From ba5787323d38084b30261e84510d4a173fcb493a Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Mon, 22 Nov 2010 11:37:21 -0800 Subject: [PATCH 0001/5560] ide: fix use after free in ide-acpi out_obj points to kfreed memory and we dereference that pointer in DEBPRINT/printk. Signed-off-by: Mariusz Kozlowski Signed-off-by: David S. Miller --- drivers/ide/ide-acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index c26c11905ffe..2af8cb460a3b 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -416,21 +416,21 @@ void ide_acpi_get_timing(ide_hwif_t *hwif) out_obj = output.pointer; if (out_obj->type != ACPI_TYPE_BUFFER) { - kfree(output.pointer); DEBPRINT("Run _GTM: error: " "expected object type of ACPI_TYPE_BUFFER, " "got 0x%x\n", out_obj->type); + kfree(output.pointer); return; } if (!out_obj->buffer.length || !out_obj->buffer.pointer || out_obj->buffer.length != sizeof(struct GTM_buffer)) { - kfree(output.pointer); printk(KERN_ERR "%s: unexpected _GTM length (0x%x)[should be 0x%zx] or " "addr (0x%p)\n", __func__, out_obj->buffer.length, sizeof(struct GTM_buffer), out_obj->buffer.pointer); + kfree(output.pointer); return; } -- GitLab From f2ba70a22c31a179226fa0517729104497a7853f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 22 Nov 2010 11:38:08 -0800 Subject: [PATCH 0002/5560] drivers/ide/pmac.c: Remove unnecessary casts of pci_get_drvdata Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/ide/pmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index ebcf8e470a97..1db7c4368dbf 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1334,7 +1334,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) static int pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) { - pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev); + pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev); int rc = 0; if (mesg.event != pdev->dev.power.power_state.event @@ -1350,7 +1350,7 @@ pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) static int pmac_ide_pci_resume(struct pci_dev *pdev) { - pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev); + pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev); int rc = 0; if (pdev->dev.power.power_state.event != PM_EVENT_ON) { -- GitLab From f17bfe79e6aa34aecbd579258a5c55a790807aca Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 22 Nov 2010 11:39:30 -0800 Subject: [PATCH 0003/5560] IDE: ide-floppy, remove unnecessary NULL check Stanse found that rq in ide_floppy_callback cannot be NULL, because it is dereferenced all around. So remove the superfluous check. This appeared after blk_* macros removal. Signed-off-by: Jiri Slaby Signed-off-by: David S. Miller --- drivers/ide/ide-floppy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 5406b6ea3ad1..536ff68062ab 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -73,7 +73,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) drive->failed_pc = NULL; if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || - (rq && rq->cmd_type == REQ_TYPE_BLOCK_PC)) + rq->cmd_type == REQ_TYPE_BLOCK_PC) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { -- GitLab From 78b7280cce23293f7570ad52c1ffe1485c6d9669 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Mar 2011 17:57:23 +0000 Subject: [PATCH 0004/5560] KEYS: Improve /proc/keys Improve /proc/keys by: (1) Don't attempt to summarise the payload of a negated key. It won't have one. To this end, a helper function - key_is_instantiated() has been added that allows the caller to find out whether the key is positively instantiated (as opposed to being uninstantiated or negatively instantiated). (2) Do show keys that are negative, expired or revoked rather than hiding them. This requires an override flag (no_state_check) to be passed to search_my_process_keyrings() and keyring_search_aux() to suppress this check. Without this, keys that are possessed by the caller, but only grant permissions to the caller if possessed are skipped as the possession check fails. Keys that are visible due to user, group or other checks are visible with or without this patch. Signed-off-by: David Howells Signed-off-by: James Morris --- include/linux/key.h | 13 +++++++++++ net/dns_resolver/dns_key.c | 10 +++++---- security/keys/internal.h | 4 +++- security/keys/keyring.c | 37 +++++++++++++++++++++----------- security/keys/proc.c | 2 +- security/keys/process_keys.c | 12 ++++++----- security/keys/request_key.c | 3 +-- security/keys/request_key_auth.c | 3 ++- security/keys/user_defined.c | 4 ++-- 9 files changed, 59 insertions(+), 29 deletions(-) diff --git a/include/linux/key.h b/include/linux/key.h index b2bb01719561..ef19b99aff98 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -276,6 +276,19 @@ static inline key_serial_t key_serial(struct key *key) return key ? key->serial : 0; } +/** + * key_is_instantiated - Determine if a key has been positively instantiated + * @key: The key to check. + * + * Return true if the specified key has been positively instantiated, false + * otherwise. + */ +static inline bool key_is_instantiated(const struct key *key) +{ + return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && + !test_bit(KEY_FLAG_NEGATIVE, &key->flags); +} + #define rcu_dereference_key(KEY) \ (rcu_dereference_protected((KEY)->payload.rcudata, \ rwsem_is_locked(&((struct key *)(KEY))->sem))) diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index cfa7a5e1c5c9..fa000d26dc60 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c @@ -212,10 +212,12 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m) int err = key->type_data.x[0]; seq_puts(m, key->description); - if (err) - seq_printf(m, ": %d", err); - else - seq_printf(m, ": %u", key->datalen); + if (key_is_instantiated(key)) { + if (err) + seq_printf(m, ": %d", err); + else + seq_printf(m, ": %u", key->datalen); + } } /* diff --git a/security/keys/internal.h b/security/keys/internal.h index 07a025f81902..f375152a2500 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -109,11 +109,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, const struct cred *cred, struct key_type *type, const void *description, - key_match_func_t match); + key_match_func_t match, + bool no_state_check); extern key_ref_t search_my_process_keyrings(struct key_type *type, const void *description, key_match_func_t match, + bool no_state_check, const struct cred *cred); extern key_ref_t search_process_keyrings(struct key_type *type, const void *description, diff --git a/security/keys/keyring.c b/security/keys/keyring.c index cdd2f3f88c88..a06ffab38568 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -176,13 +176,15 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) else seq_puts(m, "[anon]"); - rcu_read_lock(); - klist = rcu_dereference(keyring->payload.subscriptions); - if (klist) - seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); - else - seq_puts(m, ": empty"); - rcu_read_unlock(); + if (key_is_instantiated(keyring)) { + rcu_read_lock(); + klist = rcu_dereference(keyring->payload.subscriptions); + if (klist) + seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); + else + seq_puts(m, ": empty"); + rcu_read_unlock(); + } } /* @@ -271,6 +273,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, * @type: The type of key to search for. * @description: Parameter for @match. * @match: Function to rule on whether or not a key is the one required. + * @no_state_check: Don't check if a matching key is bad * * Search the supplied keyring tree for a key that matches the criteria given. * The root keyring and any linked keyrings must grant Search permission to the @@ -303,7 +306,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, const struct cred *cred, struct key_type *type, const void *description, - key_match_func_t match) + key_match_func_t match, + bool no_state_check) { struct { struct keyring_list *keylist; @@ -345,6 +349,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, kflags = keyring->flags; if (keyring->type == type && match(keyring, description)) { key = keyring; + if (no_state_check) + goto found; /* check it isn't negative and hasn't expired or been * revoked */ @@ -384,11 +390,13 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, continue; /* skip revoked keys and expired keys */ - if (kflags & (1 << KEY_FLAG_REVOKED)) - continue; + if (!no_state_check) { + if (kflags & (1 << KEY_FLAG_REVOKED)) + continue; - if (key->expiry && now.tv_sec >= key->expiry) - continue; + if (key->expiry && now.tv_sec >= key->expiry) + continue; + } /* keys that don't match */ if (!match(key, description)) @@ -399,6 +407,9 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, cred, KEY_SEARCH) < 0) continue; + if (no_state_check) + goto found; + /* we set a different error code if we pass a negative key */ if (kflags & (1 << KEY_FLAG_NEGATIVE)) { err = key->type_data.reject_error; @@ -478,7 +489,7 @@ key_ref_t keyring_search(key_ref_t keyring, return ERR_PTR(-ENOKEY); return keyring_search_aux(keyring, current->cred, - type, description, type->match); + type, description, type->match, false); } EXPORT_SYMBOL(keyring_search); diff --git a/security/keys/proc.c b/security/keys/proc.c index 525cf8a29cdd..49bbc97943ad 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -199,7 +199,7 @@ static int proc_keys_show(struct seq_file *m, void *v) if (key->perm & KEY_POS_VIEW) { skey_ref = search_my_process_keyrings(key->type, key, lookup_user_key_possessed, - cred); + true, cred); if (!IS_ERR(skey_ref)) { key_ref_put(skey_ref); key_ref = make_key_ref(key, 1); diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 930634e45149..6c0480db8885 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -331,6 +331,7 @@ void key_fsgid_changed(struct task_struct *tsk) key_ref_t search_my_process_keyrings(struct key_type *type, const void *description, key_match_func_t match, + bool no_state_check, const struct cred *cred) { key_ref_t key_ref, ret, err; @@ -350,7 +351,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, if (cred->thread_keyring) { key_ref = keyring_search_aux( make_key_ref(cred->thread_keyring, 1), - cred, type, description, match); + cred, type, description, match, no_state_check); if (!IS_ERR(key_ref)) goto found; @@ -371,7 +372,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, if (cred->tgcred->process_keyring) { key_ref = keyring_search_aux( make_key_ref(cred->tgcred->process_keyring, 1), - cred, type, description, match); + cred, type, description, match, no_state_check); if (!IS_ERR(key_ref)) goto found; @@ -395,7 +396,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, make_key_ref(rcu_dereference( cred->tgcred->session_keyring), 1), - cred, type, description, match); + cred, type, description, match, no_state_check); rcu_read_unlock(); if (!IS_ERR(key_ref)) @@ -417,7 +418,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type, else if (cred->user->session_keyring) { key_ref = keyring_search_aux( make_key_ref(cred->user->session_keyring, 1), - cred, type, description, match); + cred, type, description, match, no_state_check); if (!IS_ERR(key_ref)) goto found; @@ -459,7 +460,8 @@ key_ref_t search_process_keyrings(struct key_type *type, might_sleep(); - key_ref = search_my_process_keyrings(type, description, match, cred); + key_ref = search_my_process_keyrings(type, description, match, + false, cred); if (!IS_ERR(key_ref)) goto found; err = key_ref; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index df3c0417ee40..b18a71745901 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -530,8 +530,7 @@ struct key *request_key_and_link(struct key_type *type, dest_keyring, flags); /* search all the process keyrings for a key */ - key_ref = search_process_keyrings(type, description, type->match, - cred); + key_ref = search_process_keyrings(type, description, type->match, cred); if (!IS_ERR(key_ref)) { key = key_ref_to_ptr(key_ref); diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 68164031a74e..f6337c9082eb 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -59,7 +59,8 @@ static void request_key_auth_describe(const struct key *key, seq_puts(m, "key:"); seq_puts(m, key->description); - seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); + if (key_is_instantiated(key)) + seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); } /* diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index c6ca8662a468..63bb1aaffc0a 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -169,8 +169,8 @@ EXPORT_SYMBOL_GPL(user_destroy); void user_describe(const struct key *key, struct seq_file *m) { seq_puts(m, key->description); - - seq_printf(m, ": %u", key->datalen); + if (key_is_instantiated(key)) + seq_printf(m, ": %u", key->datalen); } EXPORT_SYMBOL_GPL(user_describe); -- GitLab From 4aab1e896a0a9d57420ff2867caa5a369123d8cb Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Mar 2011 17:57:33 +0000 Subject: [PATCH 0005/5560] KEYS: Make request_key() and co. return an error for a negative key Make request_key() and co. return an error for a negative or rejected key. If the key was simply negated, then return ENOKEY, otherwise return the error with which it was rejected. Without this patch, the following command returns a key number (with the latest keyutils): [root@andromeda ~]# keyctl request2 user debug:foo rejected @s 586569904 Trying to print the key merely gets you a permission denied error: [root@andromeda ~]# keyctl print 586569904 keyctl_read_alloc: Permission denied Doing another request_key() call does get you the error, as long as it hasn't expired yet: [root@andromeda ~]# keyctl request user debug:foo request_key: Key was rejected by service Signed-off-by: David Howells Signed-off-by: James Morris --- security/keys/keyctl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 427fddcaeb19..eca51918c951 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -206,8 +206,14 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, goto error5; } + /* wait for the key to finish being constructed */ + ret = wait_for_key_construction(key, 1); + if (ret < 0) + goto error6; + ret = key->serial; +error6: key_put(key); error5: key_type_put(ktype); -- GitLab From 780e2806986f9cc980808687da95160c65baa78a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 11 Mar 2011 18:00:19 +0000 Subject: [PATCH 0006/5560] ASoC: Treat WM8958 revision A as WM8994 revision D The first WM8958 revision requires similar treatment. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 3dc64c8b6a5c..9458289bb563 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3327,14 +3327,23 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) case WM8958: snd_soc_add_controls(codec, wm8958_snd_controls, ARRAY_SIZE(wm8958_snd_controls)); - snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, - ARRAY_SIZE(wm8994_lateclk_widgets)); - snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, - ARRAY_SIZE(wm8994_adc_widgets)); - snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, - ARRAY_SIZE(wm8994_dac_widgets)); snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, ARRAY_SIZE(wm8958_dapm_widgets)); + if (wm8994->revision < 1) { + snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, + ARRAY_SIZE(wm8994_lateclk_revd_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, + ARRAY_SIZE(wm8994_adc_revd_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets, + ARRAY_SIZE(wm8994_dac_revd_widgets)); + } else { + snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, + ARRAY_SIZE(wm8994_lateclk_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, + ARRAY_SIZE(wm8994_adc_widgets)); + snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, + ARRAY_SIZE(wm8994_dac_widgets)); + } break; } @@ -3358,10 +3367,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) } break; case WM8958: - snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, - ARRAY_SIZE(wm8994_lateclk_intercon)); - snd_soc_dapm_add_routes(dapm, wm8958_intercon, - ARRAY_SIZE(wm8958_intercon)); + if (wm8994->revision < 1) { + snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, + ARRAY_SIZE(wm8994_revd_intercon)); + snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, + ARRAY_SIZE(wm8994_lateclk_revd_intercon)); + } else { + snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, + ARRAY_SIZE(wm8994_lateclk_intercon)); + snd_soc_dapm_add_routes(dapm, wm8958_intercon, + ARRAY_SIZE(wm8958_intercon)); + } break; } -- GitLab From f701a2e594e62b35d895ad5ec1db8d2d0714c158 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 9 Mar 2011 19:31:01 +0000 Subject: [PATCH 0007/5560] ASoC: Factor WM8958 DSP2 handling into separate file DSP2 on the WM8958 has a default ROM which provides a multi-band compressor for enhanced performance on mobile devices but can also support runtime download of alternative firmware. In preparation for more exploiting this functionality refactor the code to split the handling of DSP2 into a separate file. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/Makefile | 2 +- sound/soc/codecs/wm8958-dsp2.c | 289 +++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.c | 305 +-------------------------------- sound/soc/codecs/wm8994.h | 71 ++++++++ 4 files changed, 364 insertions(+), 303 deletions(-) create mode 100644 sound/soc/codecs/wm8958-dsp2.c diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 379bc55f0723..49121ad0e172 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -69,7 +69,7 @@ snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o snd-soc-wm8991-objs := wm8991.o snd-soc-wm8993-objs := wm8993.o -snd-soc-wm8994-objs := wm8994.o wm8994-tables.o +snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o snd-soc-wm8995-objs := wm8995.o snd-soc-wm9081-objs := wm9081.o snd-soc-wm9705-objs := wm9705.o diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c new file mode 100644 index 000000000000..4b4c93c20331 --- /dev/null +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -0,0 +1,289 @@ +/* + * wm8958-dsp2.c -- WM8958 DSP2 support + * + * Copyright 2011 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "wm8994.h" + +static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5); + int ena, reg, aif, i; + + switch (mbc) { + case 0: + pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA); + aif = 0; + break; + case 1: + pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA); + aif = 0; + break; + case 2: + pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA); + aif = 1; + break; + default: + BUG(); + return; + } + + /* We can only enable the MBC if the AIF is enabled and we + * want it to be enabled. */ + ena = pwr_reg && wm8994->mbc_ena[mbc]; + + reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM); + + dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n", + mbc, start, pwr_reg, reg); + + if (start && ena) { + /* If the DSP is already running then noop */ + if (reg & WM8958_DSP2_ENA) + return; + + /* Switch the clock over to the appropriate AIF */ + snd_soc_update_bits(codec, WM8994_CLOCKING_1, + WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, + aif << WM8958_DSP2CLK_SRC_SHIFT | + WM8958_DSP2CLK_ENA); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* If we've got user supplied MBC settings use them */ + if (pdata && pdata->num_mbc_cfgs) { + struct wm8958_mbc_cfg *cfg + = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) + snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, + cfg->coeff_regs[i]); + + for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++) + snd_soc_write(codec, + i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1, + cfg->cutoff_regs[i]); + } + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* And we're off! */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_ENA | WM8958_MBC_SEL_MASK, + mbc << WM8958_MBC_SEL_SHIFT | + WM8958_MBC_ENA); + } else { + /* If the DSP is already stopped then noop */ + if (!(reg & WM8958_DSP2_ENA)) + return; + + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_ENA, 0); + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, 0); + snd_soc_update_bits(codec, WM8994_CLOCKING_1, + WM8958_DSP2CLK_ENA, 0); + } +} + +int wm8958_aif_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + int mbc; + + switch (w->shift) { + case 13: + case 12: + mbc = 2; + break; + case 11: + case 10: + mbc = 1; + break; + case 9: + case 8: + mbc = 0; + break; + default: + BUG(); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + wm8958_mbc_apply(codec, mbc, 1); + break; + case SND_SOC_DAPM_POST_PMD: + wm8958_mbc_apply(codec, mbc, 0); + break; + } + + return 0; +} + +static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_mbc_cfgs) + return -EINVAL; + + wm8994->mbc_cfg = value; + + return 0; +} + +static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; + + return 0; +} + +static int wm8958_mbc_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_mbc_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mbc = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; + + return 0; +} + +static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mbc = kcontrol->private_value; + int i; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { + if (mbc != i && wm8994->mbc_ena[i]) { + dev_dbg(codec->dev, "MBC %d active already\n", mbc); + return -EBUSY; + } + } + + wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; + + wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]); + + return 0; +} + +#define WM8958_MBC_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_mbc_info, \ + .get = wm8958_mbc_get, .put = wm8958_mbc_put, \ + .private_value = xval } + +static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = { +WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), +WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), +WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), +}; + +void wm8958_dsp2_init(struct snd_soc_codec *codec) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int ret, i; + + snd_soc_add_controls(codec, wm8958_mbc_snd_controls, + ARRAY_SIZE(wm8958_mbc_snd_controls)); + + if (!pdata) + return; + + if (pdata->num_mbc_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum, + wm8958_get_mbc_enum, wm8958_put_mbc_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->mbc_texts = kmalloc(sizeof(char *) + * pdata->num_mbc_cfgs, GFP_KERNEL); + if (!wm8994->mbc_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d MBC config texts\n", + pdata->num_mbc_cfgs); + return; + } + + for (i = 0; i < pdata->num_mbc_cfgs; i++) + wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; + + wm8994->mbc_enum.max = pdata->num_mbc_cfgs; + wm8994->mbc_enum.texts = wm8994->mbc_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add MBC mode controls: %d\n", ret); + } + + +} diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9458289bb563..96e1379f4fad 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -38,12 +38,6 @@ #include "wm8994.h" #include "wm_hubs.h" -struct fll_config { - int src; - int in; - int out; -}; - #define WM8994_NUM_DRC 3 #define WM8994_NUM_EQ 3 @@ -59,61 +53,6 @@ static int wm8994_retune_mobile_base[] = { WM8994_AIF2_EQ_GAINS_1, }; -struct wm8994_micdet { - struct snd_soc_jack *jack; - int det; - int shrt; -}; - -/* codec private data */ -struct wm8994_priv { - struct wm_hubs_data hubs; - enum snd_soc_control_type control_type; - void *control_data; - struct snd_soc_codec *codec; - int sysclk[2]; - int sysclk_rate[2]; - int mclk[2]; - int aifclk[2]; - struct fll_config fll[2], fll_suspend[2]; - - int dac_rates[2]; - int lrclk_shared[2]; - - int mbc_ena[3]; - - /* Platform dependant DRC configuration */ - const char **drc_texts; - int drc_cfg[WM8994_NUM_DRC]; - struct soc_enum drc_enum; - - /* Platform dependant ReTune mobile configuration */ - int num_retune_mobile_texts; - const char **retune_mobile_texts; - int retune_mobile_cfg[WM8994_NUM_EQ]; - struct soc_enum retune_mobile_enum; - - /* Platform dependant MBC configuration */ - int mbc_cfg; - const char **mbc_texts; - struct soc_enum mbc_enum; - - struct wm8994_micdet micdet[2]; - - wm8958_micdet_cb jack_cb; - void *jack_cb_data; - int micdet_irq; - - int revision; - struct wm8994_pdata *pdata; - - unsigned int aif1clk_enable:1; - unsigned int aif2clk_enable:1; - - unsigned int aif1clk_disable:1; - unsigned int aif2clk_disable:1; -}; - static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) { switch (reg) { @@ -574,215 +513,6 @@ static const struct soc_enum dac_osr = static const struct soc_enum adc_osr = SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); -static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) -{ - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; - int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5); - int ena, reg, aif, i; - - switch (mbc) { - case 0: - pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA); - aif = 0; - break; - case 1: - pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA); - aif = 0; - break; - case 2: - pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA); - aif = 1; - break; - default: - BUG(); - return; - } - - /* We can only enable the MBC if the AIF is enabled and we - * want it to be enabled. */ - ena = pwr_reg && wm8994->mbc_ena[mbc]; - - reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM); - - dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n", - mbc, start, pwr_reg, reg); - - if (start && ena) { - /* If the DSP is already running then noop */ - if (reg & WM8958_DSP2_ENA) - return; - - /* Switch the clock over to the appropriate AIF */ - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, - aif << WM8958_DSP2CLK_SRC_SHIFT | - WM8958_DSP2CLK_ENA); - - snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, - WM8958_DSP2_ENA, WM8958_DSP2_ENA); - - /* If we've got user supplied MBC settings use them */ - if (pdata && pdata->num_mbc_cfgs) { - struct wm8958_mbc_cfg *cfg - = &pdata->mbc_cfgs[wm8994->mbc_cfg]; - - for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) - snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, - cfg->coeff_regs[i]); - - for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++) - snd_soc_write(codec, - i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1, - cfg->cutoff_regs[i]); - } - - /* Run the DSP */ - snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, - WM8958_DSP2_RUNR); - - /* And we're off! */ - snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, - WM8958_MBC_ENA | WM8958_MBC_SEL_MASK, - mbc << WM8958_MBC_SEL_SHIFT | - WM8958_MBC_ENA); - } else { - /* If the DSP is already stopped then noop */ - if (!(reg & WM8958_DSP2_ENA)) - return; - - snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, - WM8958_MBC_ENA, 0); - snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, - WM8958_DSP2_ENA, 0); - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8958_DSP2CLK_ENA, 0); - } -} - -static int wm8958_aif_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - int mbc; - - switch (w->shift) { - case 13: - case 12: - mbc = 2; - break; - case 11: - case 10: - mbc = 1; - break; - case 9: - case 8: - mbc = 0; - break; - default: - BUG(); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - wm8958_mbc_apply(codec, mbc, 1); - break; - case SND_SOC_DAPM_POST_PMD: - wm8958_mbc_apply(codec, mbc, 0); - break; - } - - return 0; -} - -static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994_pdata *pdata = wm8994->pdata; - int value = ucontrol->value.integer.value[0]; - int reg; - - /* Don't allow on the fly reconfiguration */ - reg = snd_soc_read(codec, WM8994_CLOCKING_1); - if (reg < 0 || reg & WM8958_DSP2CLK_ENA) - return -EBUSY; - - if (value >= pdata->num_mbc_cfgs) - return -EINVAL; - - wm8994->mbc_cfg = value; - - return 0; -} - -static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; - - return 0; -} - -static int wm8958_mbc_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int wm8958_mbc_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int mbc = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; - - return 0; -} - -static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int mbc = kcontrol->private_value; - int i; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - if (ucontrol->value.integer.value[0] > 1) - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { - if (mbc != i && wm8994->mbc_ena[i]) { - dev_dbg(codec->dev, "MBC %d active already\n", mbc); - return -EBUSY; - } - } - - wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; - - wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]); - - return 0; -} - -#define WM8958_MBC_SWITCH(xname, xval) {\ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .info = wm8958_mbc_info, \ - .get = wm8958_mbc_get, .put = wm8958_mbc_put, \ - .private_value = xval } - static const struct snd_kcontrol_new wm8994_snd_controls[] = { SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1_ADC1_RIGHT_VOLUME, @@ -924,9 +654,6 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, static const struct snd_kcontrol_new wm8958_snd_controls[] = { SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), -WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), -WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), -WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), }; static int clk_sys_event(struct snd_soc_dapm_widget *w, @@ -2676,7 +2403,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], - sizeof(struct fll_config)); + sizeof(struct wm8994_fll_config)); ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0); if (ret < 0) dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", @@ -2862,34 +2589,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", pdata->num_retune_mobile_cfgs); - if (pdata->num_mbc_cfgs) { - struct snd_kcontrol_new control[] = { - SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum, - wm8958_get_mbc_enum, wm8958_put_mbc_enum), - }; - - /* We need an array of texts for the enum API */ - wm8994->mbc_texts = kmalloc(sizeof(char *) - * pdata->num_mbc_cfgs, GFP_KERNEL); - if (!wm8994->mbc_texts) { - dev_err(wm8994->codec->dev, - "Failed to allocate %d MBC config texts\n", - pdata->num_mbc_cfgs); - return; - } - - for (i = 0; i < pdata->num_mbc_cfgs; i++) - wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; - - wm8994->mbc_enum.max = pdata->num_mbc_cfgs; - wm8994->mbc_enum.texts = wm8994->mbc_texts; - - ret = snd_soc_add_controls(wm8994->codec, control, 1); - if (ret != 0) - dev_err(wm8994->codec->dev, - "Failed to add MBC mode controls: %d\n", ret); - } - if (pdata->num_retune_mobile_cfgs) wm8994_handle_retune_mobile_pdata(wm8994); else @@ -3378,6 +3077,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(dapm, wm8958_intercon, ARRAY_SIZE(wm8958_intercon)); } + + wm8958_dsp2_init(codec); break; } diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 999b8851226b..93a6cf1e1308 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -11,6 +11,8 @@ #include +#include "wm_hubs.h" + /* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ #define WM8994_SYSCLK_MCLK1 1 #define WM8994_SYSCLK_MCLK2 2 @@ -45,4 +47,73 @@ struct wm8994_access_mask { extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; +int wm8958_aif_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +void wm8958_dsp2_init(struct snd_soc_codec *codec); + +struct wm8994_micdet { + struct snd_soc_jack *jack; + int det; + int shrt; +}; + +/* codec private data */ +struct wm8994_fll_config { + int src; + int in; + int out; +}; + +#define WM8994_NUM_DRC 3 +#define WM8994_NUM_EQ 3 + +struct wm8994_priv { + struct wm_hubs_data hubs; + enum snd_soc_control_type control_type; + void *control_data; + struct snd_soc_codec *codec; + int sysclk[2]; + int sysclk_rate[2]; + int mclk[2]; + int aifclk[2]; + struct wm8994_fll_config fll[2], fll_suspend[2]; + + int dac_rates[2]; + int lrclk_shared[2]; + + int mbc_ena[3]; + + /* Platform dependant DRC configuration */ + const char **drc_texts; + int drc_cfg[WM8994_NUM_DRC]; + struct soc_enum drc_enum; + + /* Platform dependant ReTune mobile configuration */ + int num_retune_mobile_texts; + const char **retune_mobile_texts; + int retune_mobile_cfg[WM8994_NUM_EQ]; + struct soc_enum retune_mobile_enum; + + /* Platform dependant MBC configuration */ + int mbc_cfg; + const char **mbc_texts; + struct soc_enum mbc_enum; + + struct wm8994_micdet micdet[2]; + + wm8958_micdet_cb jack_cb; + void *jack_cb_data; + int micdet_irq; + + int revision; + struct wm8994_pdata *pdata; + + unsigned int aif1clk_enable:1; + unsigned int aif2clk_enable:1; + + unsigned int aif1clk_disable:1; + unsigned int aif2clk_disable:1; +}; + #endif -- GitLab From c6b7b57012c8307b936025ad41fcbef6b1b6b52f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 11 Mar 2011 18:13:12 +0000 Subject: [PATCH 0008/5560] ASoC: Handle startup sequencing of WM8958 DSP2 with deferred clocking The DSP2 startup requires that the clock be enable so if we've deferred clock startup we need to defer DSP2 startup Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8958-dsp2.c | 35 ++++++++++++++-------------------- sound/soc/codecs/wm8994.c | 3 +++ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 4b4c93c20331..f07775ebec04 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -69,6 +69,13 @@ static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) if (reg & WM8958_DSP2_ENA) return; + /* If neither AIFnCLK is not yet enabled postpone */ + if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) + & WM8994_AIF1CLK_ENA_MASK) && + !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1) + & WM8994_AIF2CLK_ENA_MASK)) + return; + /* Switch the clock over to the appropriate AIF */ snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, @@ -120,32 +127,18 @@ int wm8958_aif_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - int mbc; - - switch (w->shift) { - case 13: - case 12: - mbc = 2; - break; - case 11: - case 10: - mbc = 1; - break; - case 9: - case 8: - mbc = 0; - break; - default: - BUG(); - return -EINVAL; - } + int i; switch (event) { case SND_SOC_DAPM_POST_PMU: - wm8958_mbc_apply(codec, mbc, 1); + case SND_SOC_DAPM_PRE_PMU: + for (i = 0; i < 3; i++) + wm8958_mbc_apply(codec, i, 1); break; case SND_SOC_DAPM_POST_PMD: - wm8958_mbc_apply(codec, mbc, 0); + case SND_SOC_DAPM_PRE_PMD: + for (i = 0; i < 3; i++) + wm8958_mbc_apply(codec, i, 0); break; } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 96e1379f4fad..328f32831946 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -759,6 +759,9 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w, break; } + /* We may also have postponed startup of DSP, handle that. */ + wm8958_aif_ev(w, kcontrol, event); + return 0; } -- GitLab From af9af866020ea341aca32123b3109b6a9408dd8c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Mar 2011 21:05:06 +0000 Subject: [PATCH 0009/5560] ASoC: Mark WM8958 DSP2 registers readable Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 328f32831946..bdd1ac75178a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -55,6 +55,9 @@ static int wm8994_retune_mobile_base[] = { static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) { + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->control_data; + switch (reg) { case WM8994_GPIO_1: case WM8994_GPIO_2: @@ -71,6 +74,15 @@ static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) case WM8994_INTERRUPT_STATUS_2: case WM8994_INTERRUPT_RAW_STATUS_2: return 1; + + case WM8958_DSP2_PROGRAM: + case WM8958_DSP2_CONFIG: + case WM8958_DSP2_EXECCONTROL: + if (control->type == WM8958) + return 1; + else + return 0; + default: break; } -- GitLab From 375d135818f32bbe7b3f071bd54d977c4ff8d84a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 19 Mar 2011 16:32:53 +0100 Subject: [PATCH 0010/5560] ALSA: tea575x-tuner: various improvements Improve tea575x-tuner with various good things from radio-maestro: - extend frequency range to 50-150MHz - fix querycap(): card name, CAP_RADIO - improve g_tuner(): CAP_STEREO, stereo and tuned indication - improve g_frequency(): tuner index checking and reading frequency from HW - improve s_frequency(): tuner index and type checking Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai --- include/sound/tea575x-tuner.h | 6 ++-- sound/i2c/other/tea575x-tuner.c | 52 ++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index 5718a02d3afb..3d6cdd80df59 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h @@ -38,8 +38,10 @@ struct snd_tea575x { struct snd_card *card; struct video_device *vd; /* video device */ int dev_nr; /* requested device number + 1 */ - int tea5759; /* 5759 chip is present */ - int mute; /* Device is muted? */ + bool tea5759; /* 5759 chip is present */ + bool mute; /* Device is muted? */ + bool stereo; /* receiving stereo */ + bool tuned; /* tuned to a station */ unsigned int freq_fixup; /* crystal onboard */ unsigned int val; /* hw value */ unsigned long freq; /* frequency */ diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index ee538f1ae846..9f35f378a17d 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -37,8 +37,8 @@ static int radio_nr = -1; module_param(radio_nr, int, 0); #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) -#define FREQ_LO (87 * 16000) -#define FREQ_HI (108 * 16000) +#define FREQ_LO (50UL * 16000) +#define FREQ_HI (150UL * 16000) /* * definitions @@ -77,15 +77,29 @@ static struct v4l2_queryctrl radio_qctrl[] = { * lowlevel part */ +static void snd_tea575x_get_freq(struct snd_tea575x *tea) +{ + unsigned long freq; + + freq = tea->ops->read(tea) & TEA575X_BIT_FREQ_MASK; + /* freq *= 12.5 */ + freq *= 125; + freq /= 10; + /* crystal fixup */ + if (tea->tea5759) + freq += tea->freq_fixup; + else + freq -= tea->freq_fixup; + + tea->freq = freq * 16; /* from kHz */ +} + static void snd_tea575x_set_freq(struct snd_tea575x *tea) { unsigned long freq; - freq = tea->freq / 16; /* to kHz */ - if (freq > 108000) - freq = 108000; - if (freq < 87000) - freq = 87000; + freq = clamp(tea->freq, FREQ_LO, FREQ_HI); + freq /= 16; /* to kHz */ /* crystal fixup */ if (tea->tea5759) freq -= tea->freq_fixup; @@ -109,29 +123,33 @@ static int vidioc_querycap(struct file *file, void *priv, { struct snd_tea575x *tea = video_drvdata(file); - strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757"); strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); - strlcpy(v->card, "Maestro Radio", sizeof(v->card)); + strlcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757", sizeof(v->card)); sprintf(v->bus_info, "PCI"); v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER; + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; return 0; } static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { + struct snd_tea575x *tea = video_drvdata(file); + if (v->index > 0) return -EINVAL; + tea->ops->read(tea); + strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; v->rangelow = FREQ_LO; v->rangehigh = FREQ_HI; - v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; - v->capability = V4L2_TUNER_CAP_LOW; - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xffff; + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; + v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; + v->signal = tea->tuned ? 0xffff : 0; + return 0; } @@ -148,7 +166,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, { struct snd_tea575x *tea = video_drvdata(file); + if (f->tuner != 0) + return -EINVAL; f->type = V4L2_TUNER_RADIO; + snd_tea575x_get_freq(tea); f->frequency = tea->freq; return 0; } @@ -158,6 +179,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, { struct snd_tea575x *tea = video_drvdata(file); + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) + return -EINVAL; + if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) return -EINVAL; -- GitLab From f8960d61bc8ba945b07a4de1288aac5d52f8607b Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 19 Mar 2011 16:33:01 +0100 Subject: [PATCH 0011/5560] ALSA: tea575x-tuner: remove dev_nr Remove unused dev_nr from struct tea575x_tuner. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai --- include/sound/tea575x-tuner.h | 1 - sound/pci/fm801.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index 3d6cdd80df59..5aade569439b 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h @@ -37,7 +37,6 @@ struct snd_tea575x_ops { struct snd_tea575x { struct snd_card *card; struct video_device *vd; /* video device */ - int dev_nr; /* requested device number + 1 */ bool tea5759; /* 5759 chip is present */ bool mute; /* Device is muted? */ bool stereo; /* receiving stereo */ diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index e1baad74ea4b..f4dc1c77202b 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1453,7 +1453,6 @@ static int __devinit snd_fm801_create(struct snd_card *card, #ifdef TEA575X_RADIO if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && (tea575x_tuner & TUNER_TYPE_MASK) < 4) { - chip->tea.dev_nr = tea575x_tuner >> 16; chip->tea.card = card; chip->tea.freq_fixup = 10700; chip->tea.private_data = chip; -- GitLab From 1872f589951caee1afd7cd2ea6729ac892de9ddf Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 19 Mar 2011 16:33:14 +0100 Subject: [PATCH 0012/5560] ALSA: es1968: add radio (tea575x tuner) support Add TEA5757 radio tuner support to es1968 driver. This is found at least on MediaForte SF64-PCE2 sound cards. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai --- sound/i2c/other/Makefile | 2 +- sound/pci/Kconfig | 14 ++++- sound/pci/es1968.c | 125 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 4 deletions(-) diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile index 2dad40f3f622..c95d8f1aae87 100644 --- a/sound/i2c/other/Makefile +++ b/sound/i2c/other/Makefile @@ -14,4 +14,4 @@ snd-tea575x-tuner-objs := tea575x-tuner.o obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o -obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o +obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 389cd7931668..f9f533fccccf 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -534,6 +534,14 @@ config SND_ES1968_INPUT If you say N the buttons will directly control the master volume. It is recommended to say Y. +config SND_ES1968_RADIO + bool "Enable TEA5757 radio tuner support for es1968" + depends on SND_ES1968 + depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968 + help + Say Y here to include support for TEA5757 radio tuner integrated on + some MediaForte cards (e.g. SF64-PCE2). + config SND_FM801 tristate "ForteMedia FM801" select SND_OPL3_LIB @@ -555,10 +563,10 @@ config SND_FM801_TEA575X_BOOL FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media Forte SF256-PCS-02) into the snd-fm801 driver. -config SND_FM801_TEA575X +config SND_TEA575X tristate - depends on SND_FM801_TEA575X_BOOL - default SND_FM801 + depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO + default SND_FM801 || SND_ES1968 source "sound/pci/hda/Kconfig" diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 7c17f45d876d..faf9138970ae 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -112,6 +112,10 @@ #include #include +#ifdef CONFIG_SND_ES1968_RADIO +#include +#endif + #define CARD_NAME "ESS Maestro1/2" #define DRIVER_NAME "ES1968" @@ -553,6 +557,10 @@ struct es1968 { spinlock_t ac97_lock; struct tasklet_struct hwvol_tq; #endif + +#ifdef CONFIG_SND_ES1968_RADIO + struct snd_tea575x tea; +#endif }; static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); @@ -2571,6 +2579,111 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip) } #endif /* CONFIG_SND_ES1968_INPUT */ +#ifdef CONFIG_SND_ES1968_RADIO +#define GPIO_DATA 0x60 +#define IO_MASK 4 /* mask register offset from GPIO_DATA + bits 1=unmask write to given bit */ +#define IO_DIR 8 /* direction register offset from GPIO_DATA + bits 0/1=read/write direction */ +/* mask bits for GPIO lines */ +#define STR_DATA 0x0040 /* GPIO6 */ +#define STR_CLK 0x0080 /* GPIO7 */ +#define STR_WREN 0x0100 /* GPIO8 */ +#define STR_MOST 0x0200 /* GPIO9 */ + +static void snd_es1968_tea575x_write(struct snd_tea575x *tea, unsigned int val) +{ + struct es1968 *chip = tea->private_data; + unsigned long io = chip->io_port + GPIO_DATA; + u16 l, bits; + u16 omask, odir; + + omask = inw(io + IO_MASK); + odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); + outw(odir | STR_DATA, io + IO_DIR); + outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK); + udelay(16); + + for (l = 25; l; l--) { + bits = ((val >> 18) & STR_DATA) | STR_WREN; + val <<= 1; /* shift data */ + outw(bits, io); /* start strobe */ + udelay(2); + outw(bits | STR_CLK, io); /* HI level */ + udelay(2); + outw(bits, io); /* LO level */ + udelay(4); + } + + if (!tea->mute) + outw(0, io); + + udelay(4); + outw(omask, io + IO_MASK); + outw(odir, io + IO_DIR); + msleep(125); +} + +static unsigned int snd_es1968_tea575x_read(struct snd_tea575x *tea) +{ + struct es1968 *chip = tea->private_data; + unsigned long io = chip->io_port + GPIO_DATA; + u16 l, rdata; + u32 data = 0; + u16 omask; + + omask = inw(io + IO_MASK); + outw(~(STR_CLK | STR_WREN), io + IO_MASK); + outw(0, io); + udelay(16); + + for (l = 24; l--;) { + outw(STR_CLK, io); /* HI state */ + udelay(2); + if (!l) + tea->tuned = inw(io) & STR_MOST ? 0 : 1; + outw(0, io); /* LO state */ + udelay(2); + data <<= 1; /* shift data */ + rdata = inw(io); + if (!l) + tea->stereo = (rdata & STR_MOST) ? 0 : 1; + else if (l && rdata & STR_DATA) + data++; + udelay(2); + } + + if (tea->mute) + outw(STR_WREN, io); + + udelay(4); + outw(omask, io + IO_MASK); + + return data & 0x3ffe; +} + +static void snd_es1968_tea575x_mute(struct snd_tea575x *tea, unsigned int mute) +{ + struct es1968 *chip = tea->private_data; + unsigned long io = chip->io_port + GPIO_DATA; + u16 omask; + + omask = inw(io + IO_MASK); + outw(~STR_WREN, io + IO_MASK); + tea->mute = mute; + outw(tea->mute ? STR_WREN : 0, io); + udelay(4); + outw(omask, io + IO_MASK); + msleep(125); +} + +static struct snd_tea575x_ops snd_es1968_tea_ops = { + .write = snd_es1968_tea575x_write, + .read = snd_es1968_tea575x_read, + .mute = snd_es1968_tea575x_mute, +}; +#endif + static int snd_es1968_free(struct es1968 *chip) { #ifdef CONFIG_SND_ES1968_INPUT @@ -2585,6 +2698,10 @@ static int snd_es1968_free(struct es1968 *chip) outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ } +#ifdef CONFIG_SND_ES1968_RADIO + snd_tea575x_exit(&chip->tea); +#endif + if (chip->irq >= 0) free_irq(chip->irq, chip); snd_es1968_free_gameport(chip); @@ -2723,6 +2840,14 @@ static int __devinit snd_es1968_create(struct snd_card *card, snd_card_set_dev(card, &pci->dev); +#ifdef CONFIG_SND_ES1968_RADIO + chip->tea.card = card; + chip->tea.freq_fixup = 10700; + chip->tea.private_data = chip; + chip->tea.ops = &snd_es1968_tea_ops; + snd_tea575x_init(&chip->tea); +#endif + *chip_ret = chip; return 0; -- GitLab From 9498f954a4ec389806333041a1018909c6fe0518 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:52 +0100 Subject: [PATCH 0013/5560] HID: hid-multitouch: Auto detection of maxcontacts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enables support of autodetection of maxcontacts. When adding support for a new device, one is now able to let the device tell how many contacts it supports, or to manually set the value if the device happens to provide wrong information. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 52 +++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ee01e65e22d6..b9f9eeceaa98 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -60,8 +60,9 @@ struct mt_device { __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ __u8 num_received; /* how many contacts we received */ __u8 num_expected; /* expected last contact index */ + __u8 maxcontacts; bool curvalid; /* is the current contact valid? */ - struct mt_slot slots[0]; /* first slot */ + struct mt_slot *slots; }; struct mt_class { @@ -79,6 +80,8 @@ struct mt_class { #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 +#define MT_DEFAULT_MAXCONTACT 10 + /* * these device-dependent functions determine what slot corresponds * to a valid contact that was just read. @@ -95,12 +98,12 @@ static int cypress_compute_slot(struct mt_device *td) static int find_slot_from_contactid(struct mt_device *td) { int i; - for (i = 0; i < td->mtclass->maxcontacts; ++i) { + for (i = 0; i < td->maxcontacts; ++i) { if (td->slots[i].contactid == td->curdata.contactid && td->slots[i].touch_state) return i; } - for (i = 0; i < td->mtclass->maxcontacts; ++i) { + for (i = 0; i < td->maxcontacts; ++i) { if (!td->slots[i].seen_in_this_frame && !td->slots[i].touch_state) return i; @@ -113,8 +116,7 @@ static int find_slot_from_contactid(struct mt_device *td) struct mt_class mt_classes[] = { { .name = MT_CLS_DEFAULT, - .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, - .maxcontacts = 10 }, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, { .name = MT_CLS_DUAL_INRANGE_CONTACTID, .quirks = MT_QUIRK_VALID_IS_INRANGE | MT_QUIRK_SLOT_IS_CONTACTID, @@ -142,9 +144,19 @@ struct mt_class mt_classes[] = { static void mt_feature_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { - if (usage->hid == HID_DG_INPUTMODE) { - struct mt_device *td = hid_get_drvdata(hdev); + struct mt_device *td = hid_get_drvdata(hdev); + + switch (usage->hid) { + case HID_DG_INPUTMODE: td->inputmode = field->report->id; + break; + case HID_DG_CONTACTMAX: + td->maxcontacts = field->value[0]; + if (td->mtclass->maxcontacts) + /* check if the maxcontacts is given by the class */ + td->maxcontacts = td->mtclass->maxcontacts; + + break; } } @@ -208,8 +220,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->last_slot_field = usage->hid; return 1; case HID_DG_CONTACTID: - input_mt_init_slots(hi->input, - td->mtclass->maxcontacts); + input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; return 1; case HID_DG_WIDTH: @@ -292,7 +303,7 @@ static void mt_complete_slot(struct mt_device *td) if (td->curvalid) { int slotnum = mt_compute_slot(td); - if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) + if (slotnum >= 0 && slotnum < td->maxcontacts) td->slots[slotnum] = td->curdata; } td->num_received++; @@ -307,7 +318,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) { int i; - for (i = 0; i < td->mtclass->maxcontacts; ++i) { + for (i = 0; i < td->maxcontacts; ++i) { struct mt_slot *s = &(td->slots[i]); if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && !s->seen_in_this_frame) { @@ -341,7 +352,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, struct mt_device *td = hid_get_drvdata(hid); __s32 quirks = td->mtclass->quirks; - if (hid->claimed & HID_CLAIMED_INPUT) { + if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { switch (usage->hid) { case HID_DG_INRANGE: if (quirks & MT_QUIRK_VALID_IS_INRANGE) @@ -442,9 +453,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) */ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; - td = kzalloc(sizeof(struct mt_device) + - mtclass->maxcontacts * sizeof(struct mt_slot), - GFP_KERNEL); + td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); if (!td) { dev_err(&hdev->dev, "cannot allocate multitouch data\n"); return -ENOMEM; @@ -461,6 +470,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto fail; + if (!td->maxcontacts) + td->maxcontacts = MT_DEFAULT_MAXCONTACT; + + td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), + GFP_KERNEL); + if (!td->slots) { + dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); + hid_hw_stop(hdev); + ret = -ENOMEM; + goto fail; + } + mt_set_input_mode(hdev); return 0; @@ -482,6 +503,7 @@ static void mt_remove(struct hid_device *hdev) { struct mt_device *td = hid_get_drvdata(hdev); hid_hw_stop(hdev); + kfree(td->slots); kfree(td); hid_set_drvdata(hdev, NULL); } -- GitLab From 043b403aede4a528ed99ceaf050f567f1283a23e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:53 +0100 Subject: [PATCH 0014/5560] HID: hid-multitouch: migrate support for Stantum panels to the unified driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges hid-stantum to the generic multitouch driver. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 7 +- drivers/hid/Makefile | 1 - drivers/hid/hid-multitouch.c | 15 ++ drivers/hid/hid-stantum.c | 286 ----------------------------------- 4 files changed, 16 insertions(+), 293 deletions(-) delete mode 100644 drivers/hid/hid-stantum.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b7ec4057841d..3c72f16e725f 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -327,6 +327,7 @@ config HID_MULTITOUCH - 'Sensing Win7-TwoFinger' panel by GeneralTouch - eGalax dual-touch panels, including the Joojoo and Wetab tablets + - Stantum multitouch panels If unsure, say N. @@ -493,12 +494,6 @@ config HID_SONY ---help--- Support for Sony PS3 controller. -config HID_STANTUM - tristate "Stantum multitouch panel" - depends on USB_HID - ---help--- - Support for Stantum multitouch panel. - config HID_SUNPLUS tristate "Sunplus wireless desktop" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 06c68ae3abee..a13cb4e99fff 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -66,7 +66,6 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o obj-$(CONFIG_HID_SONY) += hid-sony.o -obj-$(CONFIG_HID_STANTUM) += hid-stantum.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index b9f9eeceaa98..5983e5559e81 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -79,6 +79,7 @@ struct mt_class { #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 +#define MT_CLS_STANTUM 6 #define MT_DEFAULT_MAXCONTACT 10 @@ -138,6 +139,9 @@ struct mt_class mt_classes[] = { .sn_move = 4096, .sn_pressure = 32, }, + { .name = MT_CLS_STANTUM, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { } }; @@ -552,6 +556,17 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, + /* Stantum panels */ + { .driver_data = MT_CLS_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + USB_DEVICE_ID_MTP)}, + { .driver_data = MT_CLS_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + USB_DEVICE_ID_MTP_STM)}, + { .driver_data = MT_CLS_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + USB_DEVICE_ID_MTP_SITRONIX)}, + { } }; MODULE_DEVICE_TABLE(hid, mt_devices); diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c deleted file mode 100644 index b2be1d11916b..000000000000 --- a/drivers/hid/hid-stantum.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * HID driver for Stantum multitouch panels - * - * Copyright (c) 2009 Stephane Chatty - * - */ - -/* - * 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. - */ - -#include -#include -#include -#include - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("Stantum HID multitouch panels"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -struct stantum_data { - __s32 x, y, z, w, h; /* x, y, pressure, width, height */ - __u16 id; /* touch id */ - bool valid; /* valid finger data, or just placeholder? */ - bool first; /* first finger in the HID packet? */ - bool activity; /* at least one active finger so far? */ -}; - -static int stantum_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - case HID_DG_INRANGE: - case HID_DG_CONFIDENCE: - case HID_DG_INPUTMODE: - case HID_DG_DEVICEINDEX: - case HID_DG_CONTACTCOUNT: - case HID_DG_CONTACTMAX: - return -1; - - case HID_DG_TIPSWITCH: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - return 1; - - case HID_DG_WIDTH: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MAJOR); - return 1; - case HID_DG_HEIGHT: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MINOR); - input_set_abs_params(hi->input, ABS_MT_ORIENTATION, - 1, 1, 0, 0); - return 1; - case HID_DG_TIPPRESSURE: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_PRESSURE); - return 1; - - case HID_DG_CONTACTID: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TRACKING_ID); - return 1; - - } - return 0; - - case 0xff000000: - /* no input-oriented meaning */ - return -1; - } - - return 0; -} - -static int stantum_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if (usage->type == EV_KEY || usage->type == EV_ABS) - clear_bit(usage->code, *bit); - - return 0; -} - -/* - * this function is called when a whole finger has been parsed, - * so that it can decide what to send to the input layer. - */ -static void stantum_filter_event(struct stantum_data *sd, - struct input_dev *input) -{ - bool wide; - - if (!sd->valid) { - /* - * touchscreen emulation: if the first finger is not valid and - * there previously was finger activity, this is a release - */ - if (sd->first && sd->activity) { - input_event(input, EV_KEY, BTN_TOUCH, 0); - sd->activity = false; - } - return; - } - - input_event(input, EV_ABS, ABS_MT_TRACKING_ID, sd->id); - input_event(input, EV_ABS, ABS_MT_POSITION_X, sd->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, sd->y); - - wide = (sd->w > sd->h); - input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, wide ? sd->w : sd->h); - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? sd->h : sd->w); - - input_event(input, EV_ABS, ABS_MT_PRESSURE, sd->z); - - input_mt_sync(input); - sd->valid = false; - - /* touchscreen emulation */ - if (sd->first) { - if (!sd->activity) { - input_event(input, EV_KEY, BTN_TOUCH, 1); - sd->activity = true; - } - input_event(input, EV_ABS, ABS_X, sd->x); - input_event(input, EV_ABS, ABS_Y, sd->y); - } - sd->first = false; -} - - -static int stantum_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct stantum_data *sd = hid_get_drvdata(hid); - - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - - switch (usage->hid) { - case HID_DG_INRANGE: - /* this is the last field in a finger */ - stantum_filter_event(sd, input); - break; - case HID_DG_WIDTH: - sd->w = value; - break; - case HID_DG_HEIGHT: - sd->h = value; - break; - case HID_GD_X: - sd->x = value; - break; - case HID_GD_Y: - sd->y = value; - break; - case HID_DG_TIPPRESSURE: - sd->z = value; - break; - case HID_DG_CONTACTID: - sd->id = value; - break; - case HID_DG_CONFIDENCE: - sd->valid = !!value; - break; - case 0xff000002: - /* this comes only before the first finger */ - sd->first = true; - break; - - default: - /* ignore the others */ - return 1; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int stantum_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - struct stantum_data *sd; - - sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL); - if (!sd) { - hid_err(hdev, "cannot allocate Stantum data\n"); - return -ENOMEM; - } - sd->valid = false; - sd->first = false; - sd->activity = false; - hid_set_drvdata(hdev, sd); - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret) - kfree(sd); - - return ret; -} - -static void stantum_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id stantum_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, - { } -}; -MODULE_DEVICE_TABLE(hid, stantum_devices); - -static const struct hid_usage_id stantum_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver stantum_driver = { - .name = "stantum", - .id_table = stantum_devices, - .probe = stantum_probe, - .remove = stantum_remove, - .input_mapping = stantum_input_mapping, - .input_mapped = stantum_input_mapped, - .usage_table = stantum_grabbed_usages, - .event = stantum_event, -}; - -static int __init stantum_init(void) -{ - return hid_register_driver(&stantum_driver); -} - -static void __exit stantum_exit(void) -{ - hid_unregister_driver(&stantum_driver); -} - -module_init(stantum_init); -module_exit(stantum_exit); - -- GitLab From a841b62c5d5f75ce3676fde755696d30cc8de99a Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:54 +0100 Subject: [PATCH 0015/5560] HID: hid-multitouch: migrate Cando dual touch panels to hid-multitouch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges hid-cando into the unified multitouch driver. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 7 +- drivers/hid/Makefile | 1 - drivers/hid/hid-cando.c | 276 ----------------------------------- drivers/hid/hid-multitouch.c | 14 ++ 4 files changed, 15 insertions(+), 283 deletions(-) delete mode 100644 drivers/hid/hid-cando.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3c72f16e725f..1edb0bd72a60 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -100,12 +100,6 @@ config HID_BELKIN ---help--- Support for Belkin Flip KVM and Wireless keyboard. -config HID_CANDO - tristate "Cando dual touch panel" - depends on USB_HID - ---help--- - Support for Cando dual touch panel. - config HID_CHERRY tristate "Cherry Cymotion keyboard" if EXPERT depends on USB_HID @@ -320,6 +314,7 @@ config HID_MULTITOUCH Generic support for HID multitouch panels. Say Y here if you have one of the following devices: + - Cando dual touch panel - Cypress TrueTouch panels - Hanvon dual touch panels - IrTouch Infrared USB panels diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index a13cb4e99fff..f8b90e4e4841 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_BELKIN) += hid-belkin.o -obj-$(CONFIG_HID_CANDO) += hid-cando.o obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CHICONY) += hid-chicony.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c deleted file mode 100644 index 1ea066c55201..000000000000 --- a/drivers/hid/hid-cando.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * HID driver for Cando dual-touch panels - * - * Copyright (c) 2010 Stephane Chatty - * - */ - -/* - * 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. - */ - -#include -#include -#include -#include - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("Cando dual-touch panel"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -struct cando_data { - __u16 x, y; - __u8 id; - __s8 oldest; /* id of the oldest finger in previous frame */ - bool valid; /* valid finger data, or just placeholder? */ - bool first; /* is this the first finger in this frame? */ - __s8 firstid; /* id of the first finger in the frame */ - __u16 firstx, firsty; /* (x, y) of the first finger in the frame */ -}; - -static int cando_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - case HID_DG_TIPSWITCH: - case HID_DG_CONTACTMAX: - return -1; - case HID_DG_INRANGE: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - return 1; - case HID_DG_CONTACTID: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TRACKING_ID); - return 1; - } - return 0; - } - - return 0; -} - -static int cando_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if (usage->type == EV_KEY || usage->type == EV_ABS) - clear_bit(usage->code, *bit); - - return 0; -} - -/* - * this function is called when a whole finger has been parsed, - * so that it can decide what to send to the input layer. - */ -static void cando_filter_event(struct cando_data *td, struct input_dev *input) -{ - td->first = !td->first; /* touchscreen emulation */ - - if (!td->valid) { - /* - * touchscreen emulation: if this is the second finger and - * the first was valid, the first was the oldest; if the - * first was not valid and there was a valid finger in the - * previous frame, this is a release. - */ - if (td->first) { - td->firstid = -1; - } else if (td->firstid >= 0) { - input_event(input, EV_ABS, ABS_X, td->firstx); - input_event(input, EV_ABS, ABS_Y, td->firsty); - td->oldest = td->firstid; - } else if (td->oldest >= 0) { - input_event(input, EV_KEY, BTN_TOUCH, 0); - td->oldest = -1; - } - - return; - } - - input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); - input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); - - input_mt_sync(input); - - /* - * touchscreen emulation: if there was no touching finger previously, - * emit touch event - */ - if (td->oldest < 0) { - input_event(input, EV_KEY, BTN_TOUCH, 1); - td->oldest = td->id; - } - - /* - * touchscreen emulation: if this is the first finger, wait for the - * second; the oldest is then the second if it was the oldest already - * or if there was no first, the first otherwise. - */ - if (td->first) { - td->firstx = td->x; - td->firsty = td->y; - td->firstid = td->id; - } else { - int x, y, oldest; - if (td->id == td->oldest || td->firstid < 0) { - x = td->x; - y = td->y; - oldest = td->id; - } else { - x = td->firstx; - y = td->firsty; - oldest = td->firstid; - } - input_event(input, EV_ABS, ABS_X, x); - input_event(input, EV_ABS, ABS_Y, y); - td->oldest = oldest; - } -} - - -static int cando_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct cando_data *td = hid_get_drvdata(hid); - - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - - switch (usage->hid) { - case HID_DG_INRANGE: - td->valid = value; - break; - case HID_DG_CONTACTID: - td->id = value; - break; - case HID_GD_X: - td->x = value; - break; - case HID_GD_Y: - td->y = value; - cando_filter_event(td, input); - break; - case HID_DG_TIPSWITCH: - /* avoid interference from generic hidinput handling */ - break; - - default: - /* fallback to the generic hidinput handling */ - return 0; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - struct cando_data *td; - - td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); - if (!td) { - hid_err(hdev, "cannot allocate Cando Touch data\n"); - return -ENOMEM; - } - hid_set_drvdata(hdev, td); - td->first = false; - td->oldest = -1; - td->valid = false; - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret) - kfree(td); - - return ret; -} - -static void cando_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id cando_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, - { } -}; -MODULE_DEVICE_TABLE(hid, cando_devices); - -static const struct hid_usage_id cando_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver cando_driver = { - .name = "cando-touch", - .id_table = cando_devices, - .probe = cando_probe, - .remove = cando_remove, - .input_mapping = cando_input_mapping, - .input_mapped = cando_input_mapped, - .usage_table = cando_grabbed_usages, - .event = cando_event, -}; - -static int __init cando_init(void) -{ - return hid_register_driver(&cando_driver); -} - -static void __exit cando_exit(void) -{ - hid_unregister_driver(&cando_driver); -} - -module_init(cando_init); -module_exit(cando_exit); - diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 5983e5559e81..e6e1ea251490 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -514,6 +514,20 @@ static void mt_remove(struct hid_device *hdev) static const struct hid_device_id mt_devices[] = { + /* Cando panels */ + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, + /* Cypress panel */ { .driver_data = MT_CLS_CYPRESS, HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, -- GitLab From 1e648a13720ef5de51f132501acf3e443d1a36d4 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:55 +0100 Subject: [PATCH 0016/5560] HID: hid-multitouch: refactor initialization of ABS_MT_ORIENTATION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way the input_set_abs_params was called for the new composite field ABS_MT_ORIENTATION was not very clear at second reading. We can remove the non-necessary call to set_abs and use the simple call to input_set_abs_params. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e6e1ea251490..d31301e85c56 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -235,9 +235,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); - field->logical_maximum = 1; - field->logical_minimum = 0; - set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); + input_set_abs_params(hi->input, + ABS_MT_ORIENTATION, 0, 1, 0, 0); td->last_slot_field = usage->hid; return 1; case HID_DG_TIPPRESSURE: -- GitLab From 0f8132b7431e241c29e61ac14f22549a6fca9632 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 16 Mar 2011 13:11:17 +0000 Subject: [PATCH 0017/5560] viafb: move initialization code This moves some mode independend initialization code to the function where the other parts of the initialization are. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index dc4c778877ce..a982718f3998 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1162,6 +1162,8 @@ void via_odev_to_seq(struct seq_file *m, u32 odev) static void load_fix_bit_crtc_reg(void) { + viafb_unlock_crt(); + /* always set to 1 */ viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); /* line compare should set all bits = 1 (extend modes) */ @@ -1169,8 +1171,6 @@ static void load_fix_bit_crtc_reg(void) /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4); /* line compare should set all bits = 1 (extend modes) */ - viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6); - /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); @@ -1181,6 +1181,10 @@ static void load_fix_bit_crtc_reg(void) viafb_write_reg(CR08, VIACR, 0x00); /* extend mode always set to 0h */ viafb_write_reg(CR14, VIACR, 0x00); + viafb_write_reg_mask(CR09, VIACR, 0x40, 0xDF); + viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6); + + viafb_lock_crt(); /* If K8M800, enable Prefetch Mode. */ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) @@ -2033,8 +2037,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, v_addr = crt_reg.ver_addr; if (set_iga == IGA1) { viafb_unlock_crt(); - viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */ - viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6); viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); } @@ -2047,7 +2049,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, break; } - load_fix_bit_crtc_reg(); viafb_lock_crt(); viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); @@ -2432,6 +2433,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, } } + load_fix_bit_crtc_reg(); via_set_primary_pitch(viafbinfo->fix.line_length); via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length : viafbinfo->fix.line_length); -- GitLab From 486d4c08dd2eb29b26b4a27f8056155a7a639861 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 16 Mar 2011 13:46:36 +0000 Subject: [PATCH 0018/5560] viafb: no need to write CRTC values twice Later the correct values will be written so there is no need to write early some values which might be wrong. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index a982718f3998..c4d2136ae338 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2401,9 +2401,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); - /* Write CRTC */ - viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); - /* Write Graphic Controller */ for (i = 0; i < StdGR; i++) via_write_reg(VIAGR, i, VPIT.GR[i]); -- GitLab From 0523656eed6941a1a0e6b8de36ca73f44d2142c0 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Mon, 21 Mar 2011 01:46:24 +0000 Subject: [PATCH 0019/5560] viafb: kill crt_setting_information As the iga path is the only remaining information which is also handled by the active devices there is no reason to keep it. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/chip.h | 4 ---- drivers/video/via/hw.c | 28 +++++++++++++--------------- drivers/video/via/viafbdev.c | 7 ++----- drivers/video/via/viafbdev.h | 2 -- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index 29d70244a21f..1aa0fb3c343e 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -137,10 +137,6 @@ struct chip_information { struct lvds_chip_information lvds_chip_info2; }; -struct crt_setting_information { - int iga_path; -}; - struct tmds_setting_information { int iga_path; int h_active; diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index c4d2136ae338..0098270ac425 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -770,13 +770,14 @@ static u32 get_lcd_devices(int output_interface) /*Set IGA path for each device*/ void viafb_set_iga_path(void) { + int crt_iga_path = 0; if (viafb_SAMM_ON == 1) { if (viafb_CRT_ON) { if (viafb_primary_dev == CRT_Device) - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; else - viaparinfo->crt_setting_info->iga_path = IGA2; + crt_iga_path = IGA2; } if (viafb_DVI_ON) { @@ -793,8 +794,7 @@ void viafb_set_iga_path(void) UNICHROME_CLE266)) { viaparinfo-> lvds_setting_info->iga_path = IGA2; - viaparinfo-> - crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; viaparinfo-> tmds_setting_info->iga_path = IGA1; } else @@ -814,10 +814,10 @@ void viafb_set_iga_path(void) viafb_SAMM_ON = 0; if (viafb_CRT_ON && viafb_LCD_ON) { - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; viaparinfo->lvds_setting_info->iga_path = IGA2; } else if (viafb_CRT_ON && viafb_DVI_ON) { - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; viaparinfo->tmds_setting_info->iga_path = IGA2; } else if (viafb_LCD_ON && viafb_DVI_ON) { viaparinfo->tmds_setting_info->iga_path = IGA1; @@ -826,7 +826,7 @@ void viafb_set_iga_path(void) viaparinfo->lvds_setting_info->iga_path = IGA2; viaparinfo->lvds_setting_info2->iga_path = IGA2; } else if (viafb_CRT_ON) { - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; } else if (viafb_LCD_ON) { viaparinfo->lvds_setting_info->iga_path = IGA2; } else if (viafb_DVI_ON) { @@ -837,7 +837,7 @@ void viafb_set_iga_path(void) viaparinfo->shared->iga1_devices = 0; viaparinfo->shared->iga2_devices = 0; if (viafb_CRT_ON) { - if (viaparinfo->crt_setting_info->iga_path == IGA1) + if (crt_iga_path == IGA1) viaparinfo->shared->iga1_devices |= VIA_CRT; else viaparinfo->shared->iga2_devices |= VIA_CRT; @@ -2072,8 +2072,6 @@ void __devinit viafb_init_chip_info(int chip_type) init_tmds_chip_info(); init_lvds_chip_info(); - viaparinfo->crt_setting_info->iga_path = IGA1; - /*Set IGA path for each device */ viafb_set_iga_path(); @@ -2450,15 +2448,15 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, /* CRT set mode */ if (viafb_CRT_ON) { - if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == - IGA2)) { + if (viafb_SAMM_ON && + viaparinfo->shared->iga2_devices & VIA_CRT) { viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, - video_bpp1 / 8, - viaparinfo->crt_setting_info->iga_path); + video_bpp1 / 8, IGA2); } else { viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, - viaparinfo->crt_setting_info->iga_path); + (viaparinfo->shared->iga1_devices & VIA_CRT) + ? IGA1 : IGA2); } /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 9d9bb9b4ed3f..ed9bd7978cc0 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -930,10 +930,8 @@ static int get_primary_device(void) /* Rule: device on iga1 path are the primary device. */ if (viafb_SAMM_ON) { if (viafb_CRT_ON) { - if (viaparinfo->crt_setting_info->iga_path == IGA1) { - DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", - viaparinfo-> - crt_setting_info->iga_path); + if (viaparinfo->shared->iga1_devices & VIA_CRT) { + DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", IGA1); primary_device = CRT_Device; } } @@ -1746,7 +1744,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; viaparinfo->lvds_setting_info2 = &viaparinfo->shared->lvds_setting_info2; - viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; viaparinfo->chip_info = &viaparinfo->shared->chip_info; if (viafb_dual_fb) diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index d66f963e930e..ff60e1ddcffc 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -50,7 +50,6 @@ struct viafb_shared { /* All the information will be needed to set engine */ struct tmds_setting_information tmds_setting_info; - struct crt_setting_information crt_setting_info; struct lvds_setting_information lvds_setting_info; struct lvds_setting_information lvds_setting_info2; struct chip_information chip_info; @@ -79,7 +78,6 @@ struct viafb_par { /* All the information will be needed to set engine */ /* depreciated, use the ones in shared directly */ struct tmds_setting_information *tmds_setting_info; - struct crt_setting_information *crt_setting_info; struct lvds_setting_information *lvds_setting_info; struct lvds_setting_information *lvds_setting_info2; struct chip_information *chip_info; -- GitLab From 5806896019ceaa0a1e808182afb4bba33c948ad6 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 14 Mar 2011 19:32:21 -0400 Subject: [PATCH 0020/5560] security: select correct default LSM_MMAP_MIN_ADDR on ARM. The default for this is universally set to 64k, but the help says: For most ia64, ppc64 and x86 users with lots of address space a value of 65536 is reasonable and should cause no problems. On arm and other archs it should not be higher than 32768. The text is right, in that we are seeing selinux-enabled ARM targets that fail to launch /sbin/init because selinux blocks a memory map. So select the right value if we know we are building ARM. Signed-off-by: Paul Gortmaker Signed-off-by: James Morris --- security/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/security/Kconfig b/security/Kconfig index 95accd442d55..e0f08b52e4ab 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -167,6 +167,7 @@ config INTEL_TXT config LSM_MMAP_MIN_ADDR int "Low address space for LSM to protect from user allocation" depends on SECURITY && SECURITY_SELINUX + default 32768 if ARM default 65536 help This is the portion of low virtual memory which should be protected -- GitLab From c54ea4918c2b7722d7242ea53271356501988a9b Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Sat, 19 Mar 2011 20:29:44 -0400 Subject: [PATCH 0021/5560] HID: Documentation for hidraw Documenation for the hidraw driver, with sample program. Signed-off-by: Alan Ott Signed-off-by: Jiri Kosina --- Documentation/hid/hidraw.txt | 119 +++++++++++++++++++++++++ samples/Kconfig | 6 ++ samples/Makefile | 2 +- samples/hidraw/Makefile | 8 ++ samples/hidraw/hid-example.c | 167 +++++++++++++++++++++++++++++++++++ 5 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 Documentation/hid/hidraw.txt create mode 100644 samples/hidraw/Makefile create mode 100644 samples/hidraw/hid-example.c diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt new file mode 100644 index 000000000000..029e6cb9a7e8 --- /dev/null +++ b/Documentation/hid/hidraw.txt @@ -0,0 +1,119 @@ + HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices + ================================================================== + +The hidraw driver provides a raw interface to USB and Bluetooth Human +Interface Devices (HIDs). It differs from hiddev in that reports sent and +received are not parsed by the HID parser, but are sent to and received from +the device unmodified. + +Hidraw should be used if the userspace application knows exactly how to +communicate with the hardware device, and is able to construct the HID +reports manually. This is often the case when making userspace drivers for +custom HID devices. + +Hidraw is also useful for communicating with non-conformant HID devices +which send and receive data in a way that is inconsistent with their report +descriptors. Because hiddev parses reports which are sent and received +through it, checking them against the device's report descriptor, such +communication with these non-conformant devices is impossible using hiddev. +Hidraw is the only alternative, short of writing a custom kernel driver, for +these non-conformant devices. + +A benefit of hidraw is that its use by userspace applications is independent +of the underlying hardware type. Currently, Hidraw is implemented for USB +and Bluetooth. In the future, as new hardware bus types are developed which +use the HID specification, hidraw will be expanded to add support for these +new bus types. + +Hidraw uses a dynamic major number, meaning that udev should be relied on to +create hidraw device nodes. Udev will typically create the device nodes +directly under /dev (eg: /dev/hidraw0). As this location is distribution- +and udev rule-dependent, applications should use libudev to locate hidraw +devices attached to the system. There is a tutorial on libudev with a +working example at: + http://www.signal11.us/oss/udev/ + +The HIDRAW API +--------------- + +read() +------- +read() will read a queued report received from the HID device. On USB +devices, the reports read using read() are the reports sent from the device +on the INTERRUPT IN endpoint. By default, read() will block until there is +a report available to be read. read() can be made non-blocking, by passing +the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using +fcntl(). + +On a device which uses numbered reports, the first byte of the returned data +will be the report number; the report data follows, beginning in the second +byte. For devices which do not use numbered reports, the report data +will begin at the first byte. + +write() +-------- +The write() function will write a report to the device. For USB devices, if +the device has an INTERRUPT OUT endpoint, the report will be sent on that +endpoint. If it does not, the report will be sent over the control endpoint, +using a SET_REPORT transfer. + +The first byte of the buffer passed to write() should be set to the report +number. If the device does not use numbered reports, the first byte should +be set to 0. The report data itself should begin at the second byte. + +ioctl() +-------- +Hidraw supports the following ioctls: + +HIDIOCGRDESCSIZE: Get Report Descriptor Size +This ioctl will get the size of the device's report descriptor. + +HIDIOCGRDESC: Get Report Descriptor +This ioctl returns the device's report descriptor using a +hidraw_report_descriptor struct. Make sure to set the size field of the +hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE. + +HIDIOCGRAWINFO: Get Raw Info +This ioctl will return a hidraw_devinfo struct containing the bus type, the +vendor ID (VID), and product ID (PID) of the device. The bus type can be one +of: + BUS_USB + BUS_HIL + BUS_BLUETOOTH + BUS_VIRTUAL +which are defined in linux/input.h. + +HIDIOCGRAWNAME(len): Get Raw Name +This ioctl returns a string containing the vendor and product strings of +the device. The returned string is Unicode, UTF-8 encoded. + +HIDIOCGRAWPHYS(len): Get Physical Address +This ioctl returns a string representing the physical address of the device. +For USB devices, the string contains the physical path to the device (the +USB controller, hubs, ports, etc). For Bluetooth devices, the string +contains the hardware (MAC) address of the device. + +HIDIOCSFEATURE(len): Send a Feature Report +This ioctl will send a feature report to the device. Per the HID +specification, feature reports are always sent using the control endpoint. +Set the first byte of the supplied buffer to the report number. For devices +which do not use numbered reports, set the first byte to 0. The report data +begins in the second byte. Make sure to set len accordingly, to one more +than the length of the report (to account for the report number). + +HIDIOCGFEATURE(len): Get a Feature Report +This ioctl will request a feature report from the device using the control +endpoint. The first byte of the supplied buffer should be set to the report +number of the requested report. For devices which do not use numbered +reports, set the first byte to 0. The report will be returned starting at +the first byte of the buffer (ie: the report number is not returned). + +Example +--------- +In samples/, find hid-example.c, which shows examples of read(), write(), +and all the ioctls for hidraw. The code may be used by anyone for any +purpose, and can serve as a starting point for developing applications using +hidraw. + +Document by: + Alan Ott , Signal 11 Software diff --git a/samples/Kconfig b/samples/Kconfig index e03cf0e374d7..52f4264b3006 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -61,4 +61,10 @@ config SAMPLE_KDB Build an example of how to dynamically add the hello command to the kdb shell. +config SAMPLE_HIDRAW + tristate "Build simple hidraw example" + depends on HIDRAW + help + Build an example of how to use hidraw from userspace. + endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index f26c0959fd86..6280817c2b7e 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,4 +1,4 @@ # Makefile for Linux samples code obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ - hw_breakpoint/ kfifo/ kdb/ + hw_breakpoint/ kfifo/ kdb/ hidraw/ diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile new file mode 100644 index 000000000000..7811cb0289aa --- /dev/null +++ b/samples/hidraw/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := hid-example + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c new file mode 100644 index 000000000000..40e3d6200582 --- /dev/null +++ b/samples/hidraw/hid-example.c @@ -0,0 +1,167 @@ +/* + * Hidraw Userspace Example + * + * Copyright (c) 2010 Alan Ott + * Copyright (c) 2010 Signal 11 Software + * + * The code may be used by anyone for any purpose, + * and can serve as a starting point for developing + * applications using hidraw. + */ + +/* Linux */ +#include +#include +#include + +/* Unix */ +#include +#include +#include +#include +#include + +/* C */ +#include +#include +#include +#include + +const char *bus_str(int bus); + +int main(int argc, char **argv) +{ + int fd; + int i, res, desc_size = 0; + char buf[256]; + struct hidraw_report_descriptor rpt_desc; + struct hidraw_devinfo info; + + /* Open the Device with non-blocking reads. In real life, + don't use a hard coded path; use libudev instead. */ + fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK); + + if (fd < 0) { + perror("Unable to open device"); + return 1; + } + + memset(&rpt_desc, 0x0, sizeof(rpt_desc)); + memset(&info, 0x0, sizeof(info)); + memset(buf, 0x0, sizeof(buf)); + + /* Get Report Descriptor Size */ + res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); + if (res < 0) + perror("HIDIOCGRDESCSIZE"); + else + printf("Report Descriptor Size: %d\n", desc_size); + + /* Get Report Descriptor */ + rpt_desc.size = desc_size; + res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); + if (res < 0) { + perror("HIDIOCGRDESC"); + } else { + printf("Report Descriptor:\n"); + for (i = 0; i < rpt_desc.size; i++) + printf("%hhx ", rpt_desc.value[i]); + puts("\n"); + } + + /* Get Raw Name */ + res = ioctl(fd, HIDIOCGRAWNAME(256), buf); + if (res < 0) + perror("HIDIOCGRAWNAME"); + else + printf("Raw Name: %s\n", buf); + + /* Get Physical Location */ + res = ioctl(fd, HIDIOCGRAWPHYS(256), buf); + if (res < 0) + perror("HIDIOCGRAWPHYS"); + else + printf("Raw Phys: %s\n", buf); + + /* Get Raw Info */ + res = ioctl(fd, HIDIOCGRAWINFO, &info); + if (res < 0) { + perror("HIDIOCGRAWINFO"); + } else { + printf("Raw Info:\n"); + printf("\tbustype: %d (%s)\n", + info.bustype, bus_str(info.bustype)); + printf("\tvendor: 0x%04hx\n", info.vendor); + printf("\tproduct: 0x%04hx\n", info.product); + } + + /* Set Feature */ + buf[0] = 0x9; /* Report Number */ + buf[1] = 0xff; + buf[2] = 0xff; + buf[3] = 0xff; + res = ioctl(fd, HIDIOCSFEATURE(4), buf); + if (res < 0) + perror("HIDIOCSFEATURE"); + else + printf("ioctl HIDIOCGFEATURE returned: %d\n", res); + + /* Get Feature */ + buf[0] = 0x9; /* Report Number */ + res = ioctl(fd, HIDIOCGFEATURE(256), buf); + if (res < 0) { + perror("HIDIOCGFEATURE"); + } else { + printf("ioctl HIDIOCGFEATURE returned: %d\n", res); + printf("Report data (not containing the report number):\n\t"); + for (i = 0; i < res; i++) + printf("%hhx ", buf[i]); + puts("\n"); + } + + /* Send a Report to the Device */ + buf[0] = 0x1; /* Report Number */ + buf[1] = 0x77; + res = write(fd, buf, 2); + if (res < 0) { + printf("Error: %d\n", errno); + perror("write"); + } else { + printf("write() wrote %d bytes\n", res); + } + + /* Get a report from the device */ + res = read(fd, buf, 16); + if (res < 0) { + perror("read"); + } else { + printf("read() read %d bytes:\n\t", res); + for (i = 0; i < res; i++) + printf("%hhx ", buf[i]); + puts("\n"); + } + close(fd); + return 0; +} + +const char * +bus_str(int bus) +{ + switch (bus) { + case BUS_USB: + return "USB"; + break; + case BUS_HIL: + return "HIL"; + break; + case BUS_BLUETOOTH: + return "Bluetooth"; + break; + case BUS_VIRTUAL: + return "Virtual"; + break; + default: + return "Other"; + break; + } +} -- GitLab From 1a978c50c6cff743c3516ffa6d2ce44382e7b70b Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Sat, 19 Mar 2011 20:29:45 -0400 Subject: [PATCH 0022/5560] HID: Move hiddev.txt to the new Documentation/hid directory With the new Documentation/hid directory, it makes sense to have hiddev.txt here as well. Signed-off-by: Alan Ott Signed-off-by: Jiri Kosina --- Documentation/{usb => hid}/hiddev.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/{usb => hid}/hiddev.txt (100%) diff --git a/Documentation/usb/hiddev.txt b/Documentation/hid/hiddev.txt similarity index 100% rename from Documentation/usb/hiddev.txt rename to Documentation/hid/hiddev.txt -- GitLab From 66b5b9722b8743f83d4c3f11f39665f5f2c40b12 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Wed, 16 Mar 2011 12:16:39 +0000 Subject: [PATCH 0023/5560] ALSA: Add snd_ctl_replace() to dynamically replace a control Add a function to dynamically replace a given control. If the control does not already exist, a third parameter is used to determine whether to actually add that control. This is useful in cases where downloadable firmware at runtime can add or replace existing controls. A separate patch needs to be made to allow ALSA Mixer to render the replaced controls on the fly. Signed-off-by: Dimitris Papastamos Signed-off-by: Takashi Iwai --- include/sound/control.h | 1 + sound/core/control.c | 64 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/include/sound/control.h b/include/sound/control.h index e67db2869360..40423810985a 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -113,6 +113,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, v void snd_ctl_free_one(struct snd_kcontrol * kcontrol); int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol); int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol); +int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace); int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, diff --git a/sound/core/control.c b/sound/core/control.c index a08ad57c49b6..5d98194bcad5 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -365,6 +365,70 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) EXPORT_SYMBOL(snd_ctl_add); +/** + * snd_ctl_replace - replace the control instance of the card + * @card: the card instance + * @kcontrol: the control instance to replace + * @add_on_replace: add the control if not already added + * + * Replaces the given control. If the given control does not exist + * and the add_on_replace flag is set, the control is added. If the + * control exists, it is destroyed first. + * + * Returns zero if successful, or a negative error code on failure. + * + * It frees automatically the control which cannot be added or replaced. + */ +int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, + bool add_on_replace) +{ + struct snd_ctl_elem_id id; + unsigned int idx; + struct snd_kcontrol *old; + int ret; + + if (!kcontrol) + return -EINVAL; + if (snd_BUG_ON(!card || !kcontrol->info)) { + ret = -EINVAL; + goto error; + } + id = kcontrol->id; + down_write(&card->controls_rwsem); + old = snd_ctl_find_id(card, &id); + if (!old) { + if (add_on_replace) + goto add; + up_write(&card->controls_rwsem); + ret = -EINVAL; + goto error; + } + ret = snd_ctl_remove(card, old); + if (ret < 0) { + up_write(&card->controls_rwsem); + goto error; + } +add: + if (snd_ctl_find_hole(card, kcontrol->count) < 0) { + up_write(&card->controls_rwsem); + ret = -ENOMEM; + goto error; + } + list_add_tail(&kcontrol->list, &card->controls); + card->controls_count += kcontrol->count; + kcontrol->id.numid = card->last_numid + 1; + card->last_numid += kcontrol->count; + up_write(&card->controls_rwsem); + for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + return 0; + +error: + snd_ctl_free_one(kcontrol); + return ret; +} +EXPORT_SYMBOL(snd_ctl_replace); + /** * snd_ctl_remove - remove the control from the card and release it * @card: the card instance -- GitLab From fbbf592002ee46ed14d5bd88f1150c604b34e705 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 11 Mar 2011 18:09:04 +0000 Subject: [PATCH 0024/5560] ASoC: Support download of WM8958 MBC firmware Allow userspace to supply an update to the ROM firmware. The firmware request is non-blocking so userspace can load the firmware at its leisure without delaying startup, the driver will begin using the firmware the next time MBC is started after it has been supplied. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8958-dsp2.c | 223 +++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.c | 4 + sound/soc/codecs/wm8994.h | 4 + 3 files changed, 231 insertions(+) diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index f07775ebec04..58fe40416709 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -30,10 +30,212 @@ #include "wm8994.h" +#define WM_FW_BLOCK_INFO 0xff +#define WM_FW_BLOCK_PM 0x00 +#define WM_FW_BLOCK_X 0x01 +#define WM_FW_BLOCK_Y 0x02 +#define WM_FW_BLOCK_Z 0x03 +#define WM_FW_BLOCK_I 0x06 +#define WM_FW_BLOCK_A 0x08 +#define WM_FW_BLOCK_C 0x0c + +static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, + const struct firmware *fw, bool check) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + u64 data64; + u32 data32; + const u8 *data; + char *str; + size_t block_len, len; + int ret = 0; + + /* Suppress unneeded downloads */ + if (wm8994->cur_fw == fw) + return 0; + + if (fw->size < 32) { + dev_err(codec->dev, "%s: firmware too short\n", name); + goto err; + } + + if (memcmp(fw->data, "WMFW", 4) != 0) { + dev_err(codec->dev, "%s: firmware has bad file magic %08x\n", + name, data32); + goto err; + } + + memcpy(&data32, fw->data + 4, sizeof(data32)); + len = be32_to_cpu(data32); + + memcpy(&data32, fw->data + 8, sizeof(data32)); + data32 = be32_to_cpu(data32); + if ((data32 >> 24) & 0xff) { + dev_err(codec->dev, "%s: unsupported firmware version %d\n", + name, (data32 >> 24) & 0xff); + goto err; + } + if ((data32 & 0xffff) != 8958) { + dev_err(codec->dev, "%s: unsupported target device %d\n", + name, data32 & 0xffff); + goto err; + } + if (((data32 >> 16) & 0xff) != 0xc) { + dev_err(codec->dev, "%s: unsupported target core %d\n", + name, (data32 >> 16) & 0xff); + goto err; + } + + if (check) { + memcpy(&data64, fw->data + 24, sizeof(u64)); + dev_info(codec->dev, "%s timestamp %llx\n", + name, be64_to_cpu(data64)); + } else { + snd_soc_write(codec, 0x102, 0x2); + snd_soc_write(codec, 0x900, 0x2); + } + + data = fw->data + len; + len = fw->size - len; + while (len) { + if (len < 12) { + dev_err(codec->dev, "%s short data block of %d\n", + name, len); + goto err; + } + + memcpy(&data32, data + 4, sizeof(data32)); + block_len = be32_to_cpu(data32); + if (block_len + 8 > len) { + dev_err(codec->dev, "%d byte block longer than file\n", + block_len); + goto err; + } + if (block_len == 0) { + dev_err(codec->dev, "Zero length block\n"); + goto err; + } + + memcpy(&data32, data, sizeof(data32)); + data32 = be32_to_cpu(data32); + + switch ((data32 >> 24) & 0xff) { + case WM_FW_BLOCK_INFO: + /* Informational text */ + if (!check) + break; + + str = kzalloc(block_len + 1, GFP_KERNEL); + if (str) { + memcpy(str, data + 8, block_len); + dev_info(codec->dev, "%s: %s\n", name, str); + kfree(str); + } else { + dev_err(codec->dev, "Out of memory\n"); + } + break; + case WM_FW_BLOCK_PM: + case WM_FW_BLOCK_X: + case WM_FW_BLOCK_Y: + case WM_FW_BLOCK_Z: + case WM_FW_BLOCK_I: + case WM_FW_BLOCK_A: + case WM_FW_BLOCK_C: + dev_dbg(codec->dev, "%s: %d bytes of %x@%x\n", name, + block_len, (data32 >> 24) & 0xff, + data32 & 0xffffff); + + if (check) + break; + + data32 &= 0xffffff; + + wm8994_bulk_write(codec->control_data, + data32 & 0xffffff, + block_len / 2, + (void *)(data + 8)); + + break; + default: + dev_warn(codec->dev, "%s: unknown block type %d\n", + name, (data32 >> 24) & 0xff); + break; + } + + /* Round up to the next 32 bit word */ + block_len += block_len % 4; + + data += block_len + 8; + len -= block_len + 8; + } + + if (!check) { + dev_dbg(codec->dev, "%s: download done\n", name); + wm8994->cur_fw = fw; + } else { + dev_info(codec->dev, "%s: got firmware\n", name); + } + + goto ok; + +err: + ret = -EINVAL; +ok: + if (!check) { + snd_soc_write(codec, 0x900, 0x0); + snd_soc_write(codec, 0x102, 0x0); + } + + return ret; +} + static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; + int i; + + /* If the DSP is already running then noop */ + if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA) + return; + + /* If we have MBC firmware download it */ + if (wm8994->mbc) + wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* If we've got user supplied MBC settings use them */ + if (pdata && pdata->num_mbc_cfgs) { + struct wm8958_mbc_cfg *cfg + = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) + snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, + cfg->coeff_regs[i]); + + for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++) + snd_soc_write(codec, + i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1, + cfg->cutoff_regs[i]); + } + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* And we're off! */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_ENA | + WM8958_MBC_SEL_MASK, + path << WM8958_MBC_SEL_SHIFT | + WM8958_MBC_ENA); +} + +static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5); int ena, reg, aif, i; @@ -76,6 +278,10 @@ static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) & WM8994_AIF2CLK_ENA_MASK)) return; + /* If we have MBC firmware download it */ + if (wm8994->mbc && wm8994->mbc_ena[mbc]) + wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false); + /* Switch the clock over to the appropriate AIF */ snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, @@ -238,6 +444,18 @@ WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), }; +static void wm8958_mbc_loaded(const struct firmware *fw, void *context) +{ + struct snd_soc_codec *codec = context; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (fw && wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) { + mutex_lock(&codec->mutex); + wm8994->mbc = fw; + mutex_unlock(&codec->mutex); + } +} + void wm8958_dsp2_init(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -247,6 +465,11 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8958_mbc_snd_controls, ARRAY_SIZE(wm8958_mbc_snd_controls)); + /* We don't require firmware and don't want to delay boot */ + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_mbc_loaded); + if (!pdata) return; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bdd1ac75178a..f622ff691b41 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1922,6 +1922,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, WM8994_VMID_BUF_ENA | WM8994_VMID_RAMP_MASK, 0); + wm8994->cur_fw = NULL; + pm_runtime_put(codec->dev); } break; @@ -3136,6 +3138,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) free_irq(wm8994->micdet_irq, wm8994); break; } + if (wm8994->mbc) + release_firmware(wm8994->mbc); kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); kfree(wm8994); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 93a6cf1e1308..1aa365b31b08 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -10,6 +10,7 @@ #define _WM8994_H #include +#include #include "wm_hubs.h" @@ -114,6 +115,9 @@ struct wm8994_priv { unsigned int aif1clk_disable:1; unsigned int aif2clk_disable:1; + + const struct firmware *cur_fw; + const struct firmware *mbc; }; #endif -- GitLab From f20d77ce2663b31c2994462d9ab9143726b67f3e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Mar 2011 20:55:37 +0000 Subject: [PATCH 0025/5560] ASoC: Refactor WM8958 DSP to support additional algorithms In preparation for the addition of additional WM8958 algorithms reorganise the code to make it easier to add such support later. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8958-dsp2.c | 96 +++++++++++++++------------------- sound/soc/codecs/wm8994.h | 1 + 2 files changed, 44 insertions(+), 53 deletions(-) diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 58fe40416709..9c1cbe5b61ae 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -189,7 +189,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, return ret; } -static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) +static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_pdata *pdata = wm8994->pdata; @@ -237,9 +237,9 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5); - int ena, reg, aif, i; + int ena, reg, aif; - switch (mbc) { + switch (path) { case 0: pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA); aif = 0; @@ -257,64 +257,34 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) return; } - /* We can only enable the MBC if the AIF is enabled and we - * want it to be enabled. */ - ena = pwr_reg && wm8994->mbc_ena[mbc]; + /* Do we have both an active AIF and an active algorithm? */ + ena = wm8994->mbc_ena[path]; + if (!pwr_reg) + ena = 0; reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM); - dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n", - mbc, start, pwr_reg, reg); + dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n", + path, wm8994->dsp_active, start, pwr_reg, reg); if (start && ena) { - /* If the DSP is already running then noop */ - if (reg & WM8958_DSP2_ENA) - return; - - /* If neither AIFnCLK is not yet enabled postpone */ + /* If either AIFnCLK is not yet enabled postpone */ if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) & WM8994_AIF1CLK_ENA_MASK) && !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1) & WM8994_AIF2CLK_ENA_MASK)) return; - /* If we have MBC firmware download it */ - if (wm8994->mbc && wm8994->mbc_ena[mbc]) - wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false); - /* Switch the clock over to the appropriate AIF */ snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, aif << WM8958_DSP2CLK_SRC_SHIFT | WM8958_DSP2CLK_ENA); - snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, - WM8958_DSP2_ENA, WM8958_DSP2_ENA); - - /* If we've got user supplied MBC settings use them */ - if (pdata && pdata->num_mbc_cfgs) { - struct wm8958_mbc_cfg *cfg - = &pdata->mbc_cfgs[wm8994->mbc_cfg]; - - for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) - snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, - cfg->coeff_regs[i]); - - for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++) - snd_soc_write(codec, - i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1, - cfg->cutoff_regs[i]); - } - - /* Run the DSP */ - snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, - WM8958_DSP2_RUNR); + if (wm8994->mbc_ena[path]) + wm8958_dsp_start_mbc(codec, path); - /* And we're off! */ - snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, - WM8958_MBC_ENA | WM8958_MBC_SEL_MASK, - mbc << WM8958_MBC_SEL_SHIFT | - WM8958_MBC_ENA); + dev_dbg(codec->dev, "DSP running\n"); } else { /* If the DSP is already stopped then noop */ if (!(reg & WM8958_DSP2_ENA)) @@ -322,10 +292,16 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, WM8958_MBC_ENA, 0); + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_STOP); snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, WM8958_DSP2_ENA, 0); snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8958_DSP2CLK_ENA, 0); + + wm8994->dsp_active = -1; + + dev_dbg(codec->dev, "DSP stopped\n"); } } @@ -339,18 +315,33 @@ int wm8958_aif_ev(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_PRE_PMU: for (i = 0; i < 3; i++) - wm8958_mbc_apply(codec, i, 1); + wm8958_dsp_apply(codec, i, 1); break; case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_PRE_PMD: for (i = 0; i < 3; i++) - wm8958_mbc_apply(codec, i, 0); + wm8958_dsp_apply(codec, i, 0); break; } return 0; } +/* Check if DSP2 is in use on another AIF */ +static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { + if (i == aif) + continue; + if (wm8994->mbc_ena[i]) + return 1; + } + + return 0; +} + static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -410,23 +401,20 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int mbc = kcontrol->private_value; - int i; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (ucontrol->value.integer.value[0] > 1) return -EINVAL; - for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { - if (mbc != i && wm8994->mbc_ena[i]) { - dev_dbg(codec->dev, "MBC %d active already\n", mbc); - return -EBUSY; - } + if (wm8958_dsp2_busy(wm8994, mbc)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc); + return -EBUSY; } wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; - wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]); + wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]); return 0; } @@ -462,10 +450,12 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) struct wm8994_pdata *pdata = wm8994->pdata; int ret, i; + wm8994->dsp_active = -1; + snd_soc_add_controls(codec, wm8958_mbc_snd_controls, ARRAY_SIZE(wm8958_mbc_snd_controls)); - /* We don't require firmware and don't want to delay boot */ + /* We don't *require* firmware and don't want to delay boot */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "wm8958_mbc.wfw", codec->dev, GFP_KERNEL, codec, wm8958_mbc_loaded); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 1aa365b31b08..a4bfde83065f 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -116,6 +116,7 @@ struct wm8994_priv { unsigned int aif1clk_disable:1; unsigned int aif2clk_disable:1; + int dsp_active; const struct firmware *cur_fw; const struct firmware *mbc; }; -- GitLab From 09e10d7fe509408d15818db6a0299f563668a7ba Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Mar 2011 22:57:47 +0000 Subject: [PATCH 0026/5560] ASoC: Add WM8958 VSS support With appropriate firmware the WM8958 can support Virtual Surround Sound or VSS, widening the stereo audio image for improved user experience. Enable support for this mode of operation when the appropriate firmware can be loaded at runtime. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/pdata.h | 34 +++ sound/soc/codecs/wm8958-dsp2.c | 363 ++++++++++++++++++++++++++++++- sound/soc/codecs/wm8994.c | 2 + sound/soc/codecs/wm8994.h | 14 ++ 4 files changed, 405 insertions(+), 8 deletions(-) diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 466b1c777aff..c72174aff1fe 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -32,6 +32,9 @@ struct wm8994_ldo_pdata { #define WM8994_EQ_REGS 20 #define WM8958_MBC_CUTOFF_REGS 20 #define WM8958_MBC_COEFF_REGS 48 +#define WM8958_MBC_COMBINED_REGS 56 +#define WM8958_VSS_HPF_REGS 2 +#define WM8958_VSS_REGS 148 /** * DRC configurations are specified with a label and a set of register @@ -71,6 +74,31 @@ struct wm8958_mbc_cfg { const char *name; u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS]; u16 coeff_regs[WM8958_MBC_COEFF_REGS]; + + /* Coefficient layout when using MBC+VSS firmware */ + u16 combined_regs[WM8958_MBC_COMBINED_REGS]; +}; + +/** + * VSS HPF configurations are specified with a label and two values to + * write. Configurations are expected to be generated using the + * multiband compressor configuration panel in WISCE - see + * http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_vss_hpf_cfg { + const char *name; + u16 regs[WM8958_VSS_HPF_REGS]; +}; + +/** + * VSS configurations are specified with a label and array of values + * to write. Configurations are expected to be generated using the + * multiband compressor configuration panel in WISCE - see + * http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_vss_cfg { + const char *name; + u16 regs[WM8958_VSS_REGS]; }; struct wm8994_pdata { @@ -95,6 +123,12 @@ struct wm8994_pdata { int num_mbc_cfgs; struct wm8958_mbc_cfg *mbc_cfgs; + int num_vss_cfgs; + struct wm8958_vss_cfg *vss_cfgs; + + int num_vss_hpf_cfgs; + struct wm8958_vss_hpf_cfg *vss_hpf_cfgs; + /* LINEOUT can be differential or single ended */ unsigned int lineout1_diff:1; unsigned int lineout2_diff:1; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 9c1cbe5b61ae..d0e257315d97 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -233,6 +233,68 @@ static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path) WM8958_MBC_ENA); } +static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int i, ena; + + if (wm8994->mbc_vss) + wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* If we've got user supplied settings use them */ + if (pdata && pdata->num_mbc_cfgs) { + struct wm8958_mbc_cfg *cfg + = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++) + snd_soc_write(codec, i + 0x2800, + cfg->combined_regs[i]); + } + + if (pdata && pdata->num_vss_cfgs) { + struct wm8958_vss_cfg *cfg + = &pdata->vss_cfgs[wm8994->vss_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) + snd_soc_write(codec, i + 0x2600, cfg->regs[i]); + } + + if (pdata && pdata->num_vss_hpf_cfgs) { + struct wm8958_vss_hpf_cfg *cfg + = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) + snd_soc_write(codec, i + 0x2400, cfg->regs[i]); + } + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* Enable the algorithms we've selected */ + ena = 0; + if (wm8994->mbc_ena[path]) + ena |= 0x8; + if (wm8994->hpf2_ena[path]) + ena |= 0x4; + if (wm8994->hpf1_ena[path]) + ena |= 0x2; + if (wm8994->vss_ena[path]) + ena |= 0x1; + + snd_soc_write(codec, 0x2201, ena); + + /* Switch the DSP into the data path */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_SEL_MASK | WM8958_MBC_ENA, + path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); +} + + static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -258,7 +320,8 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) } /* Do we have both an active AIF and an active algorithm? */ - ena = wm8994->mbc_ena[path]; + ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] || + wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path]; if (!pwr_reg) ena = 0; @@ -281,11 +344,18 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) aif << WM8958_DSP2CLK_SRC_SHIFT | WM8958_DSP2CLK_ENA); - if (wm8994->mbc_ena[path]) + if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || + wm8994->hpf2_ena[path]) + wm8958_dsp_start_vss(codec, path); + else if (wm8994->mbc_ena[path]) wm8958_dsp_start_mbc(codec, path); - dev_dbg(codec->dev, "DSP running\n"); - } else { + wm8994->dsp_active = path; + + dev_dbg(codec->dev, "DSP running in path %d\n", path); + } + + if (!start && wm8994->dsp_active == path) { /* If the DSP is already stopped then noop */ if (!(reg & WM8958_DSP2_ENA)) return; @@ -335,7 +405,8 @@ static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { if (i == aif) continue; - if (wm8994->mbc_ena[i]) + if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] || + wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i]) return 1; } @@ -426,22 +497,239 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, .get = wm8958_mbc_get, .put = wm8958_mbc_put, \ .private_value = xval } +static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_vss_cfgs) + return -EINVAL; + + wm8994->vss_cfg = value; + + return 0; +} + +static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; + + return 0; +} + +static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_vss_hpf_cfgs) + return -EINVAL; + + wm8994->vss_hpf_cfg = value; + + return 0; +} + +static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; + + return 0; +} + +static int wm8958_vss_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_vss_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int vss = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; + + return 0; +} + +static int wm8958_vss_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int vss = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (!wm8994->mbc_vss) + return -ENODEV; + + if (wm8958_dsp2_busy(wm8994, vss)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", vss); + return -EBUSY; + } + + wm8994->vss_ena[vss] = ucontrol->value.integer.value[0]; + + wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]); + + return 0; +} + + +#define WM8958_VSS_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_vss_info, \ + .get = wm8958_vss_get, .put = wm8958_vss_put, \ + .private_value = xval } + +static int wm8958_hpf_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_hpf_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int hpf = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (hpf < 3) + ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3]; + else + ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3]; + + return 0; +} + +static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int hpf = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (!wm8994->mbc_vss) + return -ENODEV; + + if (wm8958_dsp2_busy(wm8994, hpf % 3)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf); + return -EBUSY; + } + + if (wm8994->eq[hpf % 3]) + return -EBUSY; + + if (hpf < 3) + wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0]; + else + wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0]; + + wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]); + + return 0; +} + +#define WM8958_HPF_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_hpf_info, \ + .get = wm8958_hpf_get, .put = wm8958_hpf_put, \ + .private_value = xval } + static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = { WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), }; -static void wm8958_mbc_loaded(const struct firmware *fw, void *context) +static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = { +WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0), +WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1), +WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2), +WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0), +WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1), +WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2), +WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3), +WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4), +WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5), +}; + +static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) { struct snd_soc_codec *codec = context; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - if (fw && wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) { + if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) { mutex_lock(&codec->mutex); - wm8994->mbc = fw; + wm8994->mbc_vss = fw; mutex_unlock(&codec->mutex); } + +} + +static void wm8958_mbc_loaded(const struct firmware *fw, void *context) +{ + struct snd_soc_codec *codec = context; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0) + return; + + mutex_lock(&codec->mutex); + wm8994->mbc = fw; + mutex_unlock(&codec->mutex); + + /* We can't have more than one request outstanding at once so + * we daisy chain. + */ + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_mbc_vss_loaded); } void wm8958_dsp2_init(struct snd_soc_codec *codec) @@ -454,6 +742,9 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8958_mbc_snd_controls, ARRAY_SIZE(wm8958_mbc_snd_controls)); + snd_soc_add_controls(codec, wm8958_vss_snd_controls, + ARRAY_SIZE(wm8958_vss_snd_controls)); + /* We don't *require* firmware and don't want to delay boot */ request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, @@ -491,5 +782,61 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) "Failed to add MBC mode controls: %d\n", ret); } + if (pdata->num_vss_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum, + wm8958_get_vss_enum, wm8958_put_vss_enum), + }; + /* We need an array of texts for the enum API */ + wm8994->vss_texts = kmalloc(sizeof(char *) + * pdata->num_vss_cfgs, GFP_KERNEL); + if (!wm8994->vss_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d VSS config texts\n", + pdata->num_vss_cfgs); + return; + } + + for (i = 0; i < pdata->num_vss_cfgs; i++) + wm8994->vss_texts[i] = pdata->vss_cfgs[i].name; + + wm8994->vss_enum.max = pdata->num_vss_cfgs; + wm8994->vss_enum.texts = wm8994->vss_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add VSS mode controls: %d\n", ret); + } + + if (pdata->num_vss_hpf_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum, + wm8958_get_vss_hpf_enum, + wm8958_put_vss_hpf_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->vss_hpf_texts = kmalloc(sizeof(char *) + * pdata->num_vss_hpf_cfgs, GFP_KERNEL); + if (!wm8994->vss_hpf_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d VSS HPF config texts\n", + pdata->num_vss_hpf_cfgs); + return; + } + + for (i = 0; i < pdata->num_vss_hpf_cfgs; i++) + wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name; + + wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; + wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add VSS HPFmode controls: %d\n", + ret); + } } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f622ff691b41..01ef5704091e 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3140,6 +3140,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) } if (wm8994->mbc) release_firmware(wm8994->mbc); + if (wm8994->mbc_vss) + release_firmware(wm8994->mbc_vss); kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); kfree(wm8994); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index a4bfde83065f..f337f3d50590 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -84,6 +84,9 @@ struct wm8994_priv { int lrclk_shared[2]; int mbc_ena[3]; + int hpf1_ena[3]; + int hpf2_ena[3]; + int vss_ena[3]; /* Platform dependant DRC configuration */ const char **drc_texts; @@ -101,6 +104,16 @@ struct wm8994_priv { const char **mbc_texts; struct soc_enum mbc_enum; + /* Platform dependant VSS configuration */ + int vss_cfg; + const char **vss_texts; + struct soc_enum vss_enum; + + /* Platform dependant VSS HPF configuration */ + int vss_hpf_cfg; + const char **vss_hpf_texts; + struct soc_enum vss_hpf_enum; + struct wm8994_micdet micdet[2]; wm8958_micdet_cb jack_cb; @@ -119,6 +132,7 @@ struct wm8994_priv { int dsp_active; const struct firmware *cur_fw; const struct firmware *mbc; + const struct firmware *mbc_vss; }; #endif -- GitLab From 312158718fe2056703b2744801165a9574560495 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 17 Mar 2011 20:23:43 +0000 Subject: [PATCH 0027/5560] ASoC: Add WM8958 enhanced EQ support DSP2 in the WM8958 can be used to support an upgraded EQ for use in demanding applications. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/pdata.h | 15 +++ sound/soc/codecs/wm8958-dsp2.c | 192 ++++++++++++++++++++++++++++++- sound/soc/codecs/wm8994.c | 2 + sound/soc/codecs/wm8994.h | 7 ++ 4 files changed, 213 insertions(+), 3 deletions(-) diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index c72174aff1fe..d12f8d635a81 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -35,6 +35,7 @@ struct wm8994_ldo_pdata { #define WM8958_MBC_COMBINED_REGS 56 #define WM8958_VSS_HPF_REGS 2 #define WM8958_VSS_REGS 148 +#define WM8958_ENH_EQ_REGS 32 /** * DRC configurations are specified with a label and a set of register @@ -101,6 +102,17 @@ struct wm8958_vss_cfg { u16 regs[WM8958_VSS_REGS]; }; +/** + * Enhanced EQ configurations are specified with a label and array of + * values to write. Configurations are expected to be generated using + * the multiband compressor configuration panel in WISCE - see + * http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_enh_eq_cfg { + const char *name; + u16 regs[WM8958_ENH_EQ_REGS]; +}; + struct wm8994_pdata { int gpio_base; @@ -129,6 +141,9 @@ struct wm8994_pdata { int num_vss_hpf_cfgs; struct wm8958_vss_hpf_cfg *vss_hpf_cfgs; + int num_enh_eq_cfgs; + struct wm8958_enh_eq_cfg *enh_eq_cfgs; + /* LINEOUT can be differential or single ended */ unsigned int lineout1_diff:1; unsigned int lineout2_diff:1; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index d0e257315d97..74983ee2b87f 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -294,6 +294,36 @@ static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path) path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); } +static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int i; + + wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* If we've got user supplied settings use them */ + if (pdata && pdata->num_enh_eq_cfgs) { + struct wm8958_enh_eq_cfg *cfg + = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->regs); i++) + snd_soc_write(codec, i + 0x2200, + cfg->regs[i]); + } + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* Switch the DSP into the data path */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_SEL_MASK | WM8958_MBC_ENA, + path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA); +} static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) { @@ -321,7 +351,8 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) /* Do we have both an active AIF and an active algorithm? */ ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] || - wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path]; + wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] || + wm8994->enh_eq_ena[path]; if (!pwr_reg) ena = 0; @@ -344,7 +375,9 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start) aif << WM8958_DSP2CLK_SRC_SHIFT | WM8958_DSP2CLK_ENA); - if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || + if (wm8994->enh_eq_ena[path]) + wm8958_dsp_start_enh_eq(codec, path); + else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path]) wm8958_dsp_start_vss(codec, path); else if (wm8994->mbc_ena[path]) @@ -483,6 +516,9 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, return -EBUSY; } + if (wm8994->enh_eq_ena[mbc]) + return -EBUSY; + wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]); @@ -603,6 +639,9 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol, return -EBUSY; } + if (wm8994->enh_eq_ena[vss]) + return -EBUSY; + wm8994->vss_ena[vss] = ucontrol->value.integer.value[0]; wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]); @@ -661,7 +700,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, return -EBUSY; } - if (wm8994->eq[hpf % 3]) + if (wm8994->enh_eq_ena[hpf % 3]) return -EBUSY; if (hpf < 3) @@ -681,6 +720,97 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, .get = wm8958_hpf_get, .put = wm8958_hpf_put, \ .private_value = xval } +static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_enh_eq_cfgs) + return -EINVAL; + + wm8994->enh_eq_cfg = value; + + return 0; +} + +static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; + + return 0; +} + +static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; + + return 0; +} + +static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int eq = kcontrol->private_value; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + if (!wm8994->enh_eq) + return -ENODEV; + + if (wm8958_dsp2_busy(wm8994, eq)) { + dev_dbg(codec->dev, "DSP2 active on %d already\n", eq); + return -EBUSY; + } + + if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] || + wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq]) + return -EBUSY; + + wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0]; + + wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]); + + return 0; +} + +#define WM8958_ENH_EQ_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_enh_eq_info, \ + .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \ + .private_value = xval } + static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = { WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), @@ -699,6 +829,24 @@ WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4), WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5), }; +static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = { +WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0), +WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1), +WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2), +}; + +static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context) +{ + struct snd_soc_codec *codec = context; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) { + mutex_lock(&codec->mutex); + wm8994->enh_eq = fw; + mutex_unlock(&codec->mutex); + } +} + static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) { struct snd_soc_codec *codec = context; @@ -710,6 +858,12 @@ static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context) mutex_unlock(&codec->mutex); } + /* We can't have more than one request outstanding at once so + * we daisy chain. + */ + request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL, + codec, wm8958_enh_eq_loaded); } static void wm8958_mbc_loaded(const struct firmware *fw, void *context) @@ -744,6 +898,8 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) ARRAY_SIZE(wm8958_mbc_snd_controls)); snd_soc_add_controls(codec, wm8958_vss_snd_controls, ARRAY_SIZE(wm8958_vss_snd_controls)); + snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls, + ARRAY_SIZE(wm8958_enh_eq_snd_controls)); /* We don't *require* firmware and don't want to delay boot */ @@ -839,4 +995,34 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) "Failed to add VSS HPFmode controls: %d\n", ret); } + + if (pdata->num_enh_eq_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum, + wm8958_get_enh_eq_enum, + wm8958_put_enh_eq_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->enh_eq_texts = kmalloc(sizeof(char *) + * pdata->num_enh_eq_cfgs, GFP_KERNEL); + if (!wm8994->enh_eq_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d enhanced EQ config texts\n", + pdata->num_enh_eq_cfgs); + return; + } + + for (i = 0; i < pdata->num_enh_eq_cfgs; i++) + wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name; + + wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; + wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add enhanced EQ controls: %d\n", + ret); + } } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 01ef5704091e..03ef62462bab 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3142,6 +3142,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) release_firmware(wm8994->mbc); if (wm8994->mbc_vss) release_firmware(wm8994->mbc_vss); + if (wm8994->enh_eq) + release_firmware(wm8994->enh_eq); kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); kfree(wm8994); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index f337f3d50590..0a1db04b73bd 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -87,6 +87,7 @@ struct wm8994_priv { int hpf1_ena[3]; int hpf2_ena[3]; int vss_ena[3]; + int enh_eq_ena[3]; /* Platform dependant DRC configuration */ const char **drc_texts; @@ -114,6 +115,11 @@ struct wm8994_priv { const char **vss_hpf_texts; struct soc_enum vss_hpf_enum; + /* Platform dependant enhanced EQ configuration */ + int enh_eq_cfg; + const char **enh_eq_texts; + struct soc_enum enh_eq_enum; + struct wm8994_micdet micdet[2]; wm8958_micdet_cb jack_cb; @@ -133,6 +139,7 @@ struct wm8994_priv { const struct firmware *cur_fw; const struct firmware *mbc; const struct firmware *mbc_vss; + const struct firmware *enh_eq; }; #endif -- GitLab From b21a8ee67013372f439fbd1591e91d09de49bb9c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 19 Mar 2011 17:23:47 +0100 Subject: [PATCH 0028/5560] [media] remove radio-maestro Remove broken radio-maestro driver as the radio functionality is now integrated in the es1968 driver. Signed-off-by: Ondrej Zary Acked-by: Mauro Carvalho Chehab Acked-by: Hans Verkuil Signed-off-by: Takashi Iwai --- drivers/media/radio/Kconfig | 15 - drivers/media/radio/Makefile | 1 - drivers/media/radio/radio-maestro.c | 452 ---------------------------- 3 files changed, 468 deletions(-) delete mode 100644 drivers/media/radio/radio-maestro.c diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index ecdffa6aac66..851716a7da0e 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -166,21 +166,6 @@ config RADIO_MAXIRADIO To compile this driver as a module, choose M here: the module will be called radio-maxiradio. -config RADIO_MAESTRO - tristate "Maestro on board radio" - depends on VIDEO_V4L2 && PCI - ---help--- - Say Y here to directly support the on-board radio tuner on the - Maestro 2 or 2E sound card. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called radio-maestro. - config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" depends on ISA && VIDEO_V4L2 && SND diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 717656d2f749..d68907fc7925 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o -obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_RADIO_SI470X) += si470x/ diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c deleted file mode 100644 index 6af61bfeb178..000000000000 --- a/drivers/media/radio/radio-maestro.c +++ /dev/null @@ -1,452 +0,0 @@ -/* Maestro PCI sound card radio driver for Linux support - * (c) 2000 A. Tlalka, atlka@pg.gda.pl - * Notes on the hardware - * - * + Frequency control is done digitally - * + No volume control - only mute/unmute - you have to use Aux line volume - * control on Maestro card to set the volume - * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after - * frequency setting (>100ms) and only when the radio is unmuted. - * version 0.02 - * + io port is automatically detected - only the first radio is used - * version 0.03 - * + thread access locking additions - * version 0.04 - * + code improvements - * + VIDEO_TUNER_LOW is permanent - * - * Converted to V4L2 API by Mauro Carvalho Chehab - */ - -#include -#include -#include -#include -#include /* for KERNEL_VERSION MACRO */ -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); -MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); -MODULE_LICENSE("GPL"); - -static int radio_nr = -1; -module_param(radio_nr, int, 0); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 6) -#define DRIVER_VERSION "0.06" - -#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ - -#define IO_MASK 4 /* mask register offset from GPIO_DATA - bits 1=unmask write to given bit */ -#define IO_DIR 8 /* direction register offset from GPIO_DATA - bits 0/1=read/write direction */ - -#define GPIO6 0x0040 /* mask bits for GPIO lines */ -#define GPIO7 0x0080 -#define GPIO8 0x0100 -#define GPIO9 0x0200 - -#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */ -#define STR_CLK GPIO7 -#define STR_WREN GPIO8 -#define STR_MOST GPIO9 - -#define FREQ_LO 50*16000 -#define FREQ_HI 150*16000 - -#define FREQ_IF 171200 /* 10.7*16000 */ -#define FREQ_STEP 200 /* 12.5*16 */ - -#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\ - /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */ - -#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) - -struct maestro { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct pci_dev *pdev; - struct mutex lock; - - u16 io; /* base of Maestro card radio io (GPIO_DATA)*/ - u16 muted; /* VIDEO_AUDIO_MUTE */ - u16 stereo; /* VIDEO_TUNER_STEREO_ON */ - u16 tuned; /* signal strength (0 or 0xffff) */ -}; - -static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct maestro, v4l2_dev); -} - -static u32 radio_bits_get(struct maestro *dev) -{ - u16 io = dev->io, l, rdata; - u32 data = 0; - u16 omask; - - omask = inw(io + IO_MASK); - outw(~(STR_CLK | STR_WREN), io + IO_MASK); - outw(0, io); - udelay(16); - - for (l = 24; l--;) { - outw(STR_CLK, io); /* HI state */ - udelay(2); - if (!l) - dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff; - outw(0, io); /* LO state */ - udelay(2); - data <<= 1; /* shift data */ - rdata = inw(io); - if (!l) - dev->stereo = (rdata & STR_MOST) ? 0 : 1; - else if (rdata & STR_DATA) - data++; - udelay(2); - } - - if (dev->muted) - outw(STR_WREN, io); - - udelay(4); - outw(omask, io + IO_MASK); - - return data & 0x3ffe; -} - -static void radio_bits_set(struct maestro *dev, u32 data) -{ - u16 io = dev->io, l, bits; - u16 omask, odir; - - omask = inw(io + IO_MASK); - odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); - outw(odir | STR_DATA, io + IO_DIR); - outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK); - udelay(16); - for (l = 25; l; l--) { - bits = ((data >> 18) & STR_DATA) | STR_WREN; - data <<= 1; /* shift data */ - outw(bits, io); /* start strobe */ - udelay(2); - outw(bits | STR_CLK, io); /* HI level */ - udelay(2); - outw(bits, io); /* LO level */ - udelay(4); - } - - if (!dev->muted) - outw(0, io); - - udelay(4); - outw(omask, io + IO_MASK); - outw(odir, io + IO_DIR); - msleep(125); -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *v) -{ - struct maestro *dev = video_drvdata(file); - - strlcpy(v->driver, "radio-maestro", sizeof(v->driver)); - strlcpy(v->card, "Maestro Radio", sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev)); - v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - struct maestro *dev = video_drvdata(file); - - if (v->index > 0) - return -EINVAL; - - mutex_lock(&dev->lock); - radio_bits_get(dev); - - strlcpy(v->name, "FM", sizeof(v->name)); - v->type = V4L2_TUNER_RADIO; - v->rangelow = FREQ_LO; - v->rangehigh = FREQ_HI; - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - v->capability = V4L2_TUNER_CAP_LOW; - if (dev->stereo) - v->audmode = V4L2_TUNER_MODE_STEREO; - else - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = dev->tuned; - mutex_unlock(&dev->lock); - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - return v->index ? -EINVAL : 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct maestro *dev = video_drvdata(file); - - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) - return -EINVAL; - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) - return -EINVAL; - mutex_lock(&dev->lock); - radio_bits_set(dev, FREQ2BITS(f->frequency)); - mutex_unlock(&dev->lock); - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct maestro *dev = video_drvdata(file); - - if (f->tuner != 0) - return -EINVAL; - f->type = V4L2_TUNER_RADIO; - mutex_lock(&dev->lock); - f->frequency = BITS2FREQ(radio_bits_get(dev)); - mutex_unlock(&dev->lock); - return 0; -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - } - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct maestro *dev = video_drvdata(file); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = dev->muted; - return 0; - } - return -EINVAL; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct maestro *dev = video_drvdata(file); - u16 io = dev->io; - u16 omask; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - mutex_lock(&dev->lock); - omask = inw(io + IO_MASK); - outw(~STR_WREN, io + IO_MASK); - dev->muted = ctrl->value; - outw(dev->muted ? STR_WREN : 0, io); - udelay(4); - outw(omask, io + IO_MASK); - msleep(125); - mutex_unlock(&dev->lock); - return 0; - } - return -EINVAL; -} - -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) -{ - return i ? -EINVAL : 0; -} - -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; - return 0; -} - -static int vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - return a->index ? -EINVAL : 0; -} - -static const struct v4l2_file_operations maestro_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops maestro_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, -}; - -static u16 __devinit radio_power_on(struct maestro *dev) -{ - register u16 io = dev->io; - register u32 ofreq; - u16 omask, odir; - - omask = inw(io + IO_MASK); - odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); - outw(odir & ~STR_WREN, io + IO_DIR); - dev->muted = inw(io) & STR_WREN ? 0 : 1; - outw(odir, io + IO_DIR); - outw(~(STR_WREN | STR_CLK), io + IO_MASK); - outw(dev->muted ? 0 : STR_WREN, io); - udelay(16); - outw(omask, io + IO_MASK); - ofreq = radio_bits_get(dev); - - if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI))) - ofreq = FREQ2BITS(FREQ_LO); - radio_bits_set(dev, ofreq); - - return (ofreq == radio_bits_get(dev)); -} - -static int __devinit maestro_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct maestro *dev; - struct v4l2_device *v4l2_dev; - int retval; - - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "enabling pci device failed!\n"); - goto err; - } - - retval = -ENOMEM; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&pdev->dev, "not enough memory\n"); - goto err; - } - - v4l2_dev = &dev->v4l2_dev; - mutex_init(&dev->lock); - dev->pdev = pdev; - - strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name)); - - retval = v4l2_device_register(&pdev->dev, v4l2_dev); - if (retval < 0) { - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - goto errfr; - } - - dev->io = pci_resource_start(pdev, 0) + GPIO_DATA; - - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); - dev->vdev.v4l2_dev = v4l2_dev; - dev->vdev.fops = &maestro_fops; - dev->vdev.ioctl_ops = &maestro_ioctl_ops; - dev->vdev.release = video_device_release_empty; - video_set_drvdata(&dev->vdev, dev); - - if (!radio_power_on(dev)) { - retval = -EIO; - goto errfr1; - } - - retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); - if (retval) { - v4l2_err(v4l2_dev, "can't register video device!\n"); - goto errfr1; - } - - v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); - - return 0; -errfr1: - v4l2_device_unregister(v4l2_dev); -errfr: - kfree(dev); -err: - return retval; - -} - -static void __devexit maestro_remove(struct pci_dev *pdev) -{ - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct maestro *dev = to_maestro(v4l2_dev); - - video_unregister_device(&dev->vdev); - v4l2_device_unregister(&dev->v4l2_dev); -} - -static struct pci_device_id maestro_r_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968), - .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, - .class_mask = 0xffff00 }, - { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978), - .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, - .class_mask = 0xffff00 }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl); - -static struct pci_driver maestro_r_driver = { - .name = "maestro_radio", - .id_table = maestro_r_pci_tbl, - .probe = maestro_probe, - .remove = __devexit_p(maestro_remove), -}; - -static int __init maestro_radio_init(void) -{ - int retval = pci_register_driver(&maestro_r_driver); - - if (retval) - printk(KERN_ERR "error during registration pci driver\n"); - - return retval; -} - -static void __exit maestro_radio_exit(void) -{ - pci_unregister_driver(&maestro_r_driver); -} - -module_init(maestro_radio_init); -module_exit(maestro_radio_exit); -- GitLab From 3e95b9aba50deeee69afce87d2bcd94c4cd1d95e Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Wed, 23 Mar 2011 15:13:28 +0800 Subject: [PATCH 0029/5560] ALSA: hda - VIA: Add new power management function. Use set_widgets_power_state() function to seperately control different codecs' power management actions and to replace the original large function. Also fix some wrong widgets power up sequence which caused no sound issue under Smart5.1 mode and Independent HP mode. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 938 ++++++++++++++++++-------------------- 1 file changed, 453 insertions(+), 485 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 1371b57c11e8..23cb44086b27 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -154,6 +154,9 @@ struct via_spec { struct delayed_work vt1708_hp_work; int vt1708_jack_detectect; int vt1708_hp_present; + + void (*set_widgets_power_state)(struct hda_codec *codec); + #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; #endif @@ -245,7 +248,6 @@ enum { }; static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); -static void set_jack_power_state(struct hda_codec *codec); static int is_aa_path_mute(struct hda_codec *codec); static void vt1708_start_hp_work(struct via_spec *spec) @@ -271,6 +273,12 @@ static void vt1708_stop_hp_work(struct via_spec *spec) cancel_delayed_work_sync(&spec->vt1708_hp_work); } +static void set_widgets_power_state(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + if (spec->set_widgets_power_state) + spec->set_widgets_power_state(codec); +} static int analog_input_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -278,7 +286,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - set_jack_power_state(codec); + set_widgets_power_state(codec); analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { if (is_aa_path_mute(codec)) @@ -602,482 +610,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); } -static void set_jack_power_state(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int imux_is_smixer; - unsigned int parm; - - if (spec->codec_type == VT1702) { - imux_is_smixer = snd_hda_codec_read( - codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; - /* inputs */ - /* PW 1/2/5 (14h/15h/18h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x14, &parm); - set_pin_power_state(codec, 0x15, &parm); - set_pin_power_state(codec, 0x18, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */ - /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ - snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW 3/4 (16h/17h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x16, &parm); - set_pin_power_state(codec, 0x17, &parm); - /* MW0 (1ah), AOW 0/1 (10h/1dh) */ - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, - parm); - } else if (spec->codec_type == VT1708B_8CH - || spec->codec_type == VT1708B_4CH - || spec->codec_type == VT1708S) { - /* SW0 (17h) = stereo mixer */ - int is_8ch = spec->codec_type != VT1708B_4CH; - imux_is_smixer = snd_hda_codec_read( - codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) - == ((spec->codec_type == VT1708S) ? 5 : 0); - /* inputs */ - /* PW 1/2/5 (1ah/1bh/1eh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1a, &parm); - set_pin_power_state(codec, 0x1b, &parm); - set_pin_power_state(codec, 0x1e, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* SW0 (17h), AIW 0/1 (13h/14h) */ - snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW0 (19h), SW1 (18h), AOW1 (11h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x19, &parm); - if (spec->smart51_enabled) - parm = AC_PWRST_D0; - snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW6 (22h), SW2 (26h), AOW2 (24h) */ - if (is_8ch) { - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x22, &parm); - if (spec->smart51_enabled) - parm = AC_PWRST_D0; - snd_hda_codec_write(codec, 0x26, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x24, 0, - AC_VERB_SET_POWER_STATE, parm); - } - - /* PW 3/4/7 (1ch/1dh/23h) */ - parm = AC_PWRST_D3; - /* force to D0 for internal Speaker */ - set_pin_power_state(codec, 0x1c, &parm); - set_pin_power_state(codec, 0x1d, &parm); - if (is_8ch) - set_pin_power_state(codec, 0x23, &parm); - /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ - snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - parm); - if (is_8ch) { - snd_hda_codec_write(codec, 0x25, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x27, 0, - AC_VERB_SET_POWER_STATE, parm); - } - } else if (spec->codec_type == VT1718S) { - /* MUX6 (1eh) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; - /* inputs */ - /* PW 5/6/7 (29h/2ah/2bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x29, &parm); - set_pin_power_state(codec, 0x2a, &parm); - set_pin_power_state(codec, 0x2b, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ - snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x27, &parm); - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW2 (26h), AOW2 (ah) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x26, &parm); - snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW0/1 (24h/25h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x24, &parm); - set_pin_power_state(codec, 0x25, &parm); - if (!spec->hp_independent_mode) /* check for redirected HP */ - set_pin_power_state(codec, 0x28, &parm); - snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, - parm); - /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ - snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - if (spec->hp_independent_mode) { - /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x28, &parm); - snd_hda_codec_write(codec, 0x1b, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0xc, 0, - AC_VERB_SET_POWER_STATE, parm); - } - } else if (spec->codec_type == VT1716S) { - unsigned int mono_out, present; - /* SW0 (17h) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; - /* inputs */ - /* PW 1/2/5 (1ah/1bh/1eh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1a, &parm); - set_pin_power_state(codec, 0x1b, &parm); - set_pin_power_state(codec, 0x1e, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* SW0 (17h), AIW0(13h) */ - snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, - parm); - - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1e, &parm); - /* PW11 (22h) */ - if (spec->dmic_enabled) - set_pin_power_state(codec, 0x22, &parm); - else - snd_hda_codec_write( - codec, 0x22, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - - /* SW2(26h), AIW1(14h) */ - snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW0 (19h), SW1 (18h), AOW1 (11h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x19, &parm); - /* Smart 5.1 PW2(1bh) */ - if (spec->smart51_enabled) - set_pin_power_state(codec, 0x1b, &parm); - snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW7 (23h), SW3 (27h), AOW3 (25h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x23, &parm); - /* Smart 5.1 PW1(1ah) */ - if (spec->smart51_enabled) - set_pin_power_state(codec, 0x1a, &parm); - snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* Smart 5.1 PW5(1eh) */ - if (spec->smart51_enabled) - set_pin_power_state(codec, 0x1e, &parm); - snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* Mono out */ - /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ - present = snd_hda_jack_detect(codec, 0x1c); - if (present) - mono_out = 0; - else { - present = snd_hda_jack_detect(codec, 0x1d); - if (!spec->hp_independent_mode && present) - mono_out = 0; - else - mono_out = 1; - } - parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; - snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW 3/4 (1ch/1dh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1c, &parm); - set_pin_power_state(codec, 0x1d, &parm); - /* HP Independent Mode, power on AOW3 */ - if (spec->hp_independent_mode) - snd_hda_codec_write(codec, 0x25, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* force to D0 for internal Speaker */ - /* MW0 (16h), AOW0 (10h) */ - snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - mono_out ? AC_PWRST_D0 : parm); - } else if (spec->codec_type == VT2002P) { - unsigned int present; - /* MUX9 (1eh) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; - /* inputs */ - /* PW 5/6/7 (29h/2ah/2bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x29, &parm); - set_pin_power_state(codec, 0x2a, &parm); - set_pin_power_state(codec, 0x2b, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ - snd_hda_codec_write(codec, 0x1e, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x1f, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x11, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* outputs */ - /* AOW0 (8h)*/ - snd_hda_codec_write(codec, 0x8, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - - /* PW4 (26h), MW4 (1ch), MUX4(37h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x26, &parm); - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x37, - 0, AC_VERB_SET_POWER_STATE, parm); - - /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x25, &parm); - snd_hda_codec_write(codec, 0x19, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x35, 0, - AC_VERB_SET_POWER_STATE, parm); - if (spec->hp_independent_mode) { - snd_hda_codec_write(codec, 0x9, 0, - AC_VERB_SET_POWER_STATE, parm); - } - - /* Class-D */ - /* PW0 (24h), MW0(18h), MUX0(34h) */ - present = snd_hda_jack_detect(codec, 0x25); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x24, &parm); - if (present) { - snd_hda_codec_write( - codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - snd_hda_codec_write( - codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } else { - snd_hda_codec_write( - codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - snd_hda_codec_write( - codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - } - - /* Mono Out */ - /* PW15 (31h), MW8(17h), MUX8(3bh) */ - present = snd_hda_jack_detect(codec, 0x26); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x31, &parm); - if (present) { - snd_hda_codec_write( - codec, 0x17, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - snd_hda_codec_write( - codec, 0x3b, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } else { - snd_hda_codec_write( - codec, 0x17, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - snd_hda_codec_write( - codec, 0x3b, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - } - - /* MW9 (21h) */ - if (imux_is_smixer || !is_aa_path_mute(codec)) - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - else - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } else if (spec->codec_type == VT1812) { - unsigned int present; - /* MUX10 (1eh) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; - /* inputs */ - /* PW 5/6/7 (29h/2ah/2bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x29, &parm); - set_pin_power_state(codec, 0x2a, &parm); - set_pin_power_state(codec, 0x2b, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ - snd_hda_codec_write(codec, 0x1e, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x1f, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x11, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* outputs */ - /* AOW0 (8h)*/ - snd_hda_codec_write(codec, 0x8, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - - /* PW4 (28h), MW4 (18h), MUX4(38h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x28, &parm); - snd_hda_codec_write(codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x38, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x25, &parm); - snd_hda_codec_write(codec, 0x15, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x35, 0, - AC_VERB_SET_POWER_STATE, parm); - if (spec->hp_independent_mode) { - snd_hda_codec_write(codec, 0x9, 0, - AC_VERB_SET_POWER_STATE, parm); - } - - /* Internal Speaker */ - /* PW0 (24h), MW0(14h), MUX0(34h) */ - present = snd_hda_jack_detect(codec, 0x25); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x24, &parm); - if (present) { - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - snd_hda_codec_write(codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - } else { - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - snd_hda_codec_write(codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - } - /* Mono Out */ - /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ - present = snd_hda_jack_detect(codec, 0x28); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x31, &parm); - if (present) { - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - snd_hda_codec_write(codec, 0x3c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - snd_hda_codec_write(codec, 0x3e, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - } else { - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - snd_hda_codec_write(codec, 0x3c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - snd_hda_codec_write(codec, 0x3e, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - } - - /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x33, &parm); - snd_hda_codec_write(codec, 0x1d, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x3d, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* MW9 (21h) */ - if (imux_is_smixer || !is_aa_path_mute(codec)) - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - else - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } -} - /* * input MUX handling */ @@ -1120,7 +652,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); /* update jack power state */ - set_jack_power_state(codec); + set_widgets_power_state(codec); return ret; } @@ -1225,7 +757,7 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, spec->hp_independent_mode); } /* update jack power state */ - set_jack_power_state(codec); + set_widgets_power_state(codec); return 0; } @@ -1443,7 +975,7 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, } } spec->smart51_enabled = *ucontrol->value.integer.value; - set_jack_power_state(codec); + set_widgets_power_state(codec); return 1; } @@ -1967,7 +1499,7 @@ static int via_build_controls(struct hda_codec *codec) } /* init power states */ - set_jack_power_state(codec); + set_widgets_power_state(codec); analog_low_current_mode(codec, 1); via_free_kctls(codec); /* no longer needed */ @@ -2195,7 +1727,7 @@ static void via_unsol_event(struct hda_codec *codec, if (res & VIA_GPIO_EVENT) via_gpio_control(codec); if (res & VIA_JACK_EVENT) - set_jack_power_state(codec); + set_widgets_power_state(codec); if (res & VIA_MONO_EVENT) via_mono_automute(codec); if (res & VIA_SPEAKER_EVENT) @@ -3642,6 +3174,74 @@ static struct hda_amp_list vt1708B_loopbacks[] = { { } /* end */ }; #endif + +static void set_widgets_power_state_vt1708B(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + int is_8ch = 0; + if (spec->codec_type != VT1708B_4CH) + is_8ch = 1; + + /* SW0 (17h) = stereo mixer */ + imux_is_smixer = + (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) + == ((spec->codec_type == VT1708S) ? 5 : 0)); + /* inputs */ + /* PW 1/2/5 (1ah/1bh/1eh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1a, &parm); + set_pin_power_state(codec, 0x1b, &parm); + set_pin_power_state(codec, 0x1e, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; + /* SW0 (17h), AIW 0/1 (13h/14h) */ + snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW0 (19h), SW1 (18h), AOW1 (11h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x19, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1b, &parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW6 (22h), SW2 (26h), AOW2 (24h) */ + if (is_8ch) { + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x22, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1a, &parm); + snd_hda_codec_write(codec, 0x26, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x24, 0, + AC_VERB_SET_POWER_STATE, parm); + } + + /* PW 3/4/7 (1ch/1dh/23h) */ + parm = AC_PWRST_D3; + /* force to D0 for internal Speaker */ + set_pin_power_state(codec, 0x1c, &parm); + set_pin_power_state(codec, 0x1d, &parm); + if (is_8ch) + set_pin_power_state(codec, 0x23, &parm); + + /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + if (is_8ch) { + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x27, 0, + AC_VERB_SET_POWER_STATE, parm); + } +} + static int patch_vt1708S(struct hda_codec *codec); static int patch_vt1708B_8ch(struct hda_codec *codec) { @@ -3692,6 +3292,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) spec->loopback.amplist = vt1708B_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1708B; + return 0; } @@ -3742,6 +3344,8 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) spec->loopback.amplist = vt1708B_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1708B; + return 0; } @@ -4181,6 +3785,7 @@ static int patch_vt1708S(struct hda_codec *codec) spec->stream_name_analog = "VT1818S Analog"; spec->stream_name_digital = "VT1818S Digital"; } + spec->set_widgets_power_state = set_widgets_power_state_vt1708B; return 0; } @@ -4438,6 +4043,37 @@ static struct hda_amp_list vt1702_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1702(struct hda_codec *codec) +{ + int imux_is_smixer = + snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; + unsigned int parm; + /* inputs */ + /* PW 1/2/5 (14h/15h/18h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x14, &parm); + set_pin_power_state(codec, 0x15, &parm); + set_pin_power_state(codec, 0x18, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ + /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW 3/4 (16h/17h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x17, &parm); + set_pin_power_state(codec, 0x16, &parm); + /* MW0 (1ah), AOW 0/1 (10h/1dh) */ + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); +} + static int patch_vt1702(struct hda_codec *codec) { struct via_spec *spec; @@ -4484,6 +4120,7 @@ static int patch_vt1702(struct hda_codec *codec) spec->loopback.amplist = vt1702_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1702; return 0; } @@ -4825,6 +4462,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1718S(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + /* MUX6 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; + /* inputs */ + /* PW 5/6/7 (29h/2ah/2bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x29, &parm); + set_pin_power_state(codec, 0x2a, &parm); + set_pin_power_state(codec, 0x2b, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; + /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x27, &parm); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW2 (26h), AOW2 (ah) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x26, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x2b, &parm); + snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW0 (24h), AOW0 (8h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x24, &parm); + if (!spec->hp_independent_mode) /* check for redirected HP */ + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); + /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ + snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + + /* PW1 (25h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x2a, &parm); + snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); + + if (spec->hp_independent_mode) { + /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x1b, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0xc, 0, + AC_VERB_SET_POWER_STATE, parm); + } +} + static int patch_vt1718S(struct hda_codec *codec) { struct via_spec *spec; @@ -4886,6 +4589,8 @@ static int patch_vt1718S(struct hda_codec *codec) spec->loopback.amplist = vt1718S_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1718S; + return 0; } @@ -4925,8 +4630,7 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol, snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_CONNECT_SEL, index); spec->dmic_enabled = index; - set_jack_power_state(codec); - + set_widgets_power_state(codec); return 1; } @@ -5285,6 +4989,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1716S(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + unsigned int mono_out, present; + /* SW0 (17h) = stereo mixer */ + imux_is_smixer = + (snd_hda_codec_read(codec, 0x17, 0, + AC_VERB_GET_CONNECT_SEL, 0x00) == 5); + /* inputs */ + /* PW 1/2/5 (1ah/1bh/1eh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1a, &parm); + set_pin_power_state(codec, 0x1b, &parm); + set_pin_power_state(codec, 0x1e, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; + /* SW0 (17h), AIW0(13h) */ + snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1e, &parm); + /* PW11 (22h) */ + if (spec->dmic_enabled) + set_pin_power_state(codec, 0x22, &parm); + else + snd_hda_codec_write(codec, 0x22, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + + /* SW2(26h), AIW1(14h) */ + snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW0 (19h), SW1 (18h), AOW1 (11h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x19, &parm); + /* Smart 5.1 PW2(1bh) */ + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1b, &parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW7 (23h), SW3 (27h), AOW3 (25h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x23, &parm); + /* Smart 5.1 PW1(1ah) */ + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1a, &parm); + snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); + + /* Smart 5.1 PW5(1eh) */ + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1e, &parm); + snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); + + /* Mono out */ + /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ + present = snd_hda_jack_detect(codec, 0x1c); + + if (present) + mono_out = 0; + else { + present = snd_hda_jack_detect(codec, 0x1d); + if (!spec->hp_independent_mode && present) + mono_out = 0; + else + mono_out = 1; + } + parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; + snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW 3/4 (1ch/1dh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1c, &parm); + set_pin_power_state(codec, 0x1d, &parm); + /* HP Independent Mode, power on AOW3 */ + if (spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); + + /* force to D0 for internal Speaker */ + /* MW0 (16h), AOW0 (10h) */ + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, + mono_out ? AC_PWRST_D0 : parm); +} + static int patch_vt1716S(struct hda_codec *codec) { struct via_spec *spec; @@ -5339,6 +5136,7 @@ static int patch_vt1716S(struct hda_codec *codec) spec->loopback.amplist = vt1716S_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1716S; return 0; } @@ -5609,6 +5407,83 @@ static struct hda_amp_list vt2002P_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt2002P(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + unsigned int present; + /* MUX9 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; + /* inputs */ + /* PW 5/6/7 (29h/2ah/2bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x29, &parm); + set_pin_power_state(codec, 0x2a, &parm); + set_pin_power_state(codec, 0x2b, &parm); + parm = AC_PWRST_D0; + /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* AOW0 (8h)*/ + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW4 (26h), MW4 (1ch), MUX4(37h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x26, &parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x37, 0, + AC_VERB_SET_POWER_STATE, parm); + + /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x19, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); + + if (spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x9, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + + /* Class-D */ + /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ + present = snd_hda_jack_detect(codec, 0x25); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x24, &parm); + parm = present ? AC_PWRST_D3 : AC_PWRST_D0; + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); + + /* Mono Out */ + present = snd_hda_jack_detect(codec, 0x26); + + parm = present ? AC_PWRST_D3 : AC_PWRST_D0; + /* PW15 (31h), MW8(17h), MUX8(3bh) */ + snd_hda_codec_write(codec, 0x31, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x17, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3b, 0, + AC_VERB_SET_POWER_STATE, parm); + + /* MW9 (21h) */ + if (imux_is_smixer || !is_aa_path_mute(codec)) + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + else + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); +} /* patch for vt2002P */ static int patch_vt2002P(struct hda_codec *codec) @@ -5660,6 +5535,7 @@ static int patch_vt2002P(struct hda_codec *codec) spec->loopback.amplist = vt2002P_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt2002P; return 0; } @@ -5931,6 +5807,97 @@ static struct hda_amp_list vt1812_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1812(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer = + snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; + unsigned int parm; + unsigned int present; + /* MUX10 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; + /* inputs */ + /* PW 5/6/7 (29h/2ah/2bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x29, &parm); + set_pin_power_state(codec, 0x2a, &parm); + set_pin_power_state(codec, 0x2b, &parm); + parm = AC_PWRST_D0; + /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* AOW0 (8h)*/ + snd_hda_codec_write(codec, 0x8, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + + /* PW4 (28h), MW4 (18h), MUX4(38h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); + if (spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x9, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + + /* Internal Speaker */ + /* PW0 (24h), MW0(14h), MUX0(34h) */ + present = snd_hda_jack_detect(codec, 0x25); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x24, &parm); + if (present) { + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } else { + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + } + + + /* Mono Out */ + /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ + present = snd_hda_jack_detect(codec, 0x28); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x31, &parm); + if (present) { + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x3e, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } else { + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x3e, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + } + + /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x33, &parm); + snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); + +} /* patch for vt1812 */ static int patch_vt1812(struct hda_codec *codec) @@ -5984,6 +5951,7 @@ static int patch_vt1812(struct hda_codec *codec) spec->loopback.amplist = vt1812_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1812; return 0; } -- GitLab From c672af35d54992b88d3c48133bd62cc3386fb2f9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:36:59 +0100 Subject: [PATCH 0030/5560] signal: Fix SIGCONT notification code After a task receives SIGCONT, its parent is notified via SIGCHLD with its siginfo describing what the notified event is. If SIGCONT is received while the child process is stopped, the code should be CLD_CONTINUED. If SIGCONT is recieved while the child process is in the process of being stopped, it should be CLD_STOPPED. Which code to use is determined in prepare_signal() and recorded in signal->flags using SIGNAL_CLD_CONTINUED|STOP flags. get_signal_deliver() should test these flags and then notify accoringly; however, it incorrectly tested SIGNAL_STOP_CONTINUED instead of SIGNAL_CLD_CONTINUED, thus incorrectly notifying CLD_CONTINUED if the signal is delivered before the task is wait(2)ed and CLD_STOPPED if the state was fetched already. Fix it by testing SIGNAL_CLD_CONTINUED. While at it, uncompress the ?: test into if/else clause for better readability. Signed-off-by: Tejun Heo Reviewed-by: Oleg Nesterov Acked-by: Roland McGrath --- kernel/signal.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 31751868de88..e26274abf3a9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1853,8 +1853,13 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, * the CLD_ si_code into SIGNAL_CLD_MASK bits. */ if (unlikely(signal->flags & SIGNAL_CLD_MASK)) { - int why = (signal->flags & SIGNAL_STOP_CONTINUED) - ? CLD_CONTINUED : CLD_STOPPED; + int why; + + if (signal->flags & SIGNAL_CLD_CONTINUED) + why = CLD_CONTINUED; + else + why = CLD_STOPPED; + signal->flags &= ~SIGNAL_CLD_MASK; why = tracehook_notify_jctl(why, CLD_CONTINUED); -- GitLab From 9f2bf6513a6cca0b00cbbf67ba6197017cfba548 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0031/5560] ptrace: Remove the extra wake_up_state() from ptrace_detach() This wake_up_state() has a turbulent history. This is a remnant from ancient ptrace implementation and patently wrong. Commit 95a3540d (ptrace_detach: the wrong wakeup breaks the ERESTARTxxx logic) removed it but the change was reverted later by commit edaba2c5 (ptrace: revert "ptrace_detach: the wrong wakeup breaks the ERESTARTxxx logic") citing compatibility breakage and general brokeness of the whole group stop / ptrace interaction. Then, recently, it got converted from wake_up_process() to wake_up_state() to make it less dangerous. Digging through the mailing archives, the compatibility breakage doesn't seem to be critical in the sense that the behavior isn't well defined or reliable to begin with and it seems to have been agreed to remove the wakeup with proper cleanup of the whole thing. Now that the group stop and its interaction with ptrace are being cleaned up, it's high time to finally kill this silliness. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath --- kernel/ptrace.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index e2302e40b360..6acf8954017c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -312,8 +312,6 @@ static int ptrace_detach(struct task_struct *child, unsigned int data) if (child->ptrace) { child->exit_code = data; dead = __ptrace_detach(current, child); - if (!child->exit_state) - wake_up_state(child, TASK_TRACED | TASK_STOPPED); } write_unlock_irq(&tasklist_lock); -- GitLab From 71db5eb99c960e9c30e4b3ed04103c513b6251b5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0032/5560] signal: Remove superflous try_to_freeze() loop in do_signal_stop() do_signal_stop() is used only by get_signal_to_deliver() and after a successful signal stop, it always calls try_to_freeze(), so the try_to_freeze() loop around schedule() in do_signal_stop() is superflous and confusing. Remove it. Signed-off-by: Tejun Heo Acked-by: Rafael J. Wysocki Acked-by: Oleg Nesterov Acked-by: Roland McGrath --- kernel/signal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index e26274abf3a9..f4db76986ec1 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1781,9 +1781,7 @@ static int do_signal_stop(int signr) } /* Now we don't run again until woken by SIGCONT or SIGKILL */ - do { - schedule(); - } while (try_to_freeze()); + schedule(); tracehook_finish_jctl(); current->exit_code = 0; -- GitLab From edf2ed153bcae52de70db00a98b0e81a5668e563 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0033/5560] ptrace: Kill tracehook_notify_jctl() tracehook_notify_jctl() aids in determining whether and what to report to the parent when a task is stopped or continued. The function also adds an extra requirement that siglock may be released across it, which is currently unused and quite difficult to satisfy in well-defined manner. As job control and the notifications are about to receive major overhaul, remove the tracehook and open code it. If ever necessary, let's factor it out after the overhaul. * Oleg spotted incorrect CLD_CONTINUED/STOPPED selection when ptraced. Fixed. Signed-off-by: Tejun Heo Cc: Oleg Nesterov Cc: Roland McGrath --- include/linux/tracehook.h | 27 --------------------------- kernel/signal.c | 34 ++++++++++++++-------------------- 2 files changed, 14 insertions(+), 47 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 3a2e66d88a32..b073f3c8adc3 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -468,33 +468,6 @@ static inline int tracehook_get_signal(struct task_struct *task, return 0; } -/** - * tracehook_notify_jctl - report about job control stop/continue - * @notify: zero, %CLD_STOPPED or %CLD_CONTINUED - * @why: %CLD_STOPPED or %CLD_CONTINUED - * - * This is called when we might call do_notify_parent_cldstop(). - * - * @notify is zero if we would not ordinarily send a %SIGCHLD, - * or is the %CLD_STOPPED or %CLD_CONTINUED .si_code for %SIGCHLD. - * - * @why is %CLD_STOPPED when about to stop for job control; - * we are already in %TASK_STOPPED state, about to call schedule(). - * It might also be that we have just exited (check %PF_EXITING), - * but need to report that a group-wide stop is complete. - * - * @why is %CLD_CONTINUED when waking up after job control stop and - * ready to make a delayed @notify report. - * - * Return the %CLD_* value for %SIGCHLD, or zero to generate no signal. - * - * Called with the siglock held. - */ -static inline int tracehook_notify_jctl(int notify, int why) -{ - return notify ?: (current->ptrace & PT_PTRACED) ? why : 0; -} - /** * tracehook_finish_jctl - report about return from job control stop * diff --git a/kernel/signal.c b/kernel/signal.c index f4db76986ec1..03d874e1058f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1727,7 +1727,7 @@ void ptrace_notify(int exit_code) static int do_signal_stop(int signr) { struct signal_struct *sig = current->signal; - int notify; + int notify = 0; if (!sig->group_stop_count) { struct task_struct *t; @@ -1759,19 +1759,16 @@ static int do_signal_stop(int signr) * a group stop in progress and we are the last to stop, report * to the parent. When ptraced, every thread reports itself. */ - notify = sig->group_stop_count == 1 ? CLD_STOPPED : 0; - notify = tracehook_notify_jctl(notify, CLD_STOPPED); - /* - * tracehook_notify_jctl() can drop and reacquire siglock, so - * we keep ->group_stop_count != 0 before the call. If SIGCONT - * or SIGKILL comes in between ->group_stop_count == 0. - */ - if (sig->group_stop_count) { - if (!--sig->group_stop_count) - sig->flags = SIGNAL_STOP_STOPPED; - current->exit_code = sig->group_exit_code; - __set_current_state(TASK_STOPPED); + if (!--sig->group_stop_count) { + sig->flags = SIGNAL_STOP_STOPPED; + notify = CLD_STOPPED; } + if (task_ptrace(current)) + notify = CLD_STOPPED; + + current->exit_code = sig->group_exit_code; + __set_current_state(TASK_STOPPED); + spin_unlock_irq(¤t->sighand->siglock); if (notify) { @@ -1860,14 +1857,11 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, signal->flags &= ~SIGNAL_CLD_MASK; - why = tracehook_notify_jctl(why, CLD_CONTINUED); spin_unlock_irq(&sighand->siglock); - if (why) { - read_lock(&tasklist_lock); - do_notify_parent_cldstop(current->group_leader, why); - read_unlock(&tasklist_lock); - } + read_lock(&tasklist_lock); + do_notify_parent_cldstop(current->group_leader, why); + read_unlock(&tasklist_lock); goto relock; } @@ -2034,7 +2028,7 @@ void exit_signals(struct task_struct *tsk) if (unlikely(tsk->signal->group_stop_count) && !--tsk->signal->group_stop_count) { tsk->signal->flags = SIGNAL_STOP_STOPPED; - group_stop = tracehook_notify_jctl(CLD_STOPPED, CLD_STOPPED); + group_stop = CLD_STOPPED; } out: spin_unlock_irq(&tsk->sighand->siglock); -- GitLab From fe1bc6a0954611b806f9e158eb0817cf8ba21660 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0034/5560] ptrace: Add @why to ptrace_stop() To prepare for cleanup of the interaction between group stop and ptrace, add @why to ptrace_stop(). Existing users are updated such that there is no behavior change. Signed-off-by: Tejun Heo Acked-by: Roland McGrath --- kernel/signal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 03d874e1058f..95ac42dc3bcb 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1617,7 +1617,7 @@ static int sigkill_pending(struct task_struct *tsk) * If we actually decide not to stop at all because the tracer * is gone, we keep current->exit_code unless clear_code. */ -static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) +static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) __releases(¤t->sighand->siglock) __acquires(¤t->sighand->siglock) { @@ -1655,7 +1655,7 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) spin_unlock_irq(¤t->sighand->siglock); read_lock(&tasklist_lock); if (may_ptrace_stop()) { - do_notify_parent_cldstop(current, CLD_TRAPPED); + do_notify_parent_cldstop(current, why); /* * Don't want to allow preemption here, because * sys_ptrace() needs this task to be inactive. @@ -1714,7 +1714,7 @@ void ptrace_notify(int exit_code) /* Let the debugger run. */ spin_lock_irq(¤t->sighand->siglock); - ptrace_stop(exit_code, 1, &info); + ptrace_stop(exit_code, CLD_TRAPPED, 1, &info); spin_unlock_irq(¤t->sighand->siglock); } @@ -1795,7 +1795,7 @@ static int ptrace_signal(int signr, siginfo_t *info, ptrace_signal_deliver(regs, cookie); /* Let the debugger run. */ - ptrace_stop(signr, 0, info); + ptrace_stop(signr, CLD_TRAPPED, 0, info); /* We're back. Did the debugger cancel the sig? */ signr = current->exit_code; -- GitLab From e5c1902e9260a0075ea52cb5ef627a8d9aaede89 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0035/5560] signal: Fix premature completion of group stop when interfered by ptrace task->signal->group_stop_count is used to track the progress of group stop. It's initialized to the number of tasks which need to stop for group stop to finish and each stopping or trapping task decrements. However, each task doesn't keep track of whether it decremented the counter or not and if woken up before the group stop is complete and stops again, it can decrement the counter multiple times. Please consider the following example code. static void *worker(void *arg) { while (1) ; return NULL; } int main(void) { pthread_t thread; pid_t pid; int i; pid = fork(); if (!pid) { for (i = 0; i < 5; i++) pthread_create(&thread, NULL, worker, NULL); while (1) ; return 0; } ptrace(PTRACE_ATTACH, pid, NULL, NULL); while (1) { waitid(P_PID, pid, NULL, WSTOPPED); ptrace(PTRACE_SINGLESTEP, pid, NULL, (void *)(long)SIGSTOP); } return 0; } The child creates five threads and the parent continuously traps the first thread and whenever the child gets a signal, SIGSTOP is delivered. If an external process sends SIGSTOP to the child, all other threads in the process should reliably stop. However, due to the above bug, the first thread will often end up consuming group_stop_count multiple times and SIGSTOP often ends up stopping none or part of the other four threads. This patch adds a new field task->group_stop which is protected by siglock and uses GROUP_STOP_CONSUME flag to track which task is still to consume group_stop_count to fix this bug. task_clear_group_stop_pending() and task_participate_group_stop() are added to help manipulating group stop states. As ptrace_stop() now also uses task_participate_group_stop(), it will set SIGNAL_STOP_STOPPED if it completes a group stop. There still are many issues regarding the interaction between group stop and ptrace. Patches to address them will follow. - Oleg spotted duplicate GROUP_STOP_CONSUME. Dropped. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath --- include/linux/sched.h | 6 +++++ kernel/signal.c | 62 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 4b601be3dace..85f51042c2b8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1260,6 +1260,7 @@ struct task_struct { int exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ + unsigned int group_stop; /* GROUP_STOP_*, siglock protected */ /* ??? */ unsigned int personality; unsigned did_exec:1; @@ -1771,6 +1772,11 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) #define used_math() tsk_used_math(current) +/* + * task->group_stop flags + */ +#define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ + #ifdef CONFIG_PREEMPT_RCU #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */ diff --git a/kernel/signal.c b/kernel/signal.c index 95ac42dc3bcb..ecb20089eaff 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -223,6 +223,52 @@ static inline void print_dropped_signal(int sig) current->comm, current->pid, sig); } +/** + * task_clear_group_stop_pending - clear pending group stop + * @task: target task + * + * Clear group stop states for @task. + * + * CONTEXT: + * Must be called with @task->sighand->siglock held. + */ +static void task_clear_group_stop_pending(struct task_struct *task) +{ + task->group_stop &= ~GROUP_STOP_CONSUME; +} + +/** + * task_participate_group_stop - participate in a group stop + * @task: task participating in a group stop + * + * @task is participating in a group stop. Group stop states are cleared + * and the group stop count is consumed if %GROUP_STOP_CONSUME was set. If + * the consumption completes the group stop, the appropriate %SIGNAL_* + * flags are set. + * + * CONTEXT: + * Must be called with @task->sighand->siglock held. + */ +static bool task_participate_group_stop(struct task_struct *task) +{ + struct signal_struct *sig = task->signal; + bool consume = task->group_stop & GROUP_STOP_CONSUME; + + task_clear_group_stop_pending(task); + + if (!consume) + return false; + + if (!WARN_ON_ONCE(sig->group_stop_count == 0)) + sig->group_stop_count--; + + if (!sig->group_stop_count) { + sig->flags = SIGNAL_STOP_STOPPED; + return true; + } + return false; +} + /* * allocate a new signal queue record * - this may be called without locks if and only if t == current, otherwise an @@ -1645,7 +1691,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) * we must participate in the bookkeeping. */ if (current->signal->group_stop_count > 0) - --current->signal->group_stop_count; + task_participate_group_stop(current); current->last_siginfo = info; current->exit_code = exit_code; @@ -1730,6 +1776,7 @@ static int do_signal_stop(int signr) int notify = 0; if (!sig->group_stop_count) { + unsigned int gstop = GROUP_STOP_CONSUME; struct task_struct *t; if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || @@ -1741,6 +1788,7 @@ static int do_signal_stop(int signr) */ sig->group_exit_code = signr; + current->group_stop = gstop; sig->group_stop_count = 1; for (t = next_thread(current); t != current; t = next_thread(t)) /* @@ -1750,19 +1798,19 @@ static int do_signal_stop(int signr) */ if (!(t->flags & PF_EXITING) && !task_is_stopped_or_traced(t)) { + t->group_stop = gstop; sig->group_stop_count++; signal_wake_up(t, 0); - } + } else + task_clear_group_stop_pending(t); } /* * If there are no other threads in the group, or if there is * a group stop in progress and we are the last to stop, report * to the parent. When ptraced, every thread reports itself. */ - if (!--sig->group_stop_count) { - sig->flags = SIGNAL_STOP_STOPPED; + if (task_participate_group_stop(current)) notify = CLD_STOPPED; - } if (task_ptrace(current)) notify = CLD_STOPPED; @@ -2026,10 +2074,8 @@ void exit_signals(struct task_struct *tsk) recalc_sigpending_and_wake(t); if (unlikely(tsk->signal->group_stop_count) && - !--tsk->signal->group_stop_count) { - tsk->signal->flags = SIGNAL_STOP_STOPPED; + task_participate_group_stop(tsk)) group_stop = CLD_STOPPED; - } out: spin_unlock_irq(&tsk->sighand->siglock); -- GitLab From 39efa3ef3a376a4e53de2f82fc91182459d34200 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0036/5560] signal: Use GROUP_STOP_PENDING to stop once for a single group stop Currently task->signal->group_stop_count is used to decide whether to stop for group stop. However, if there is a task in the group which is taking a long time to stop, other tasks which are continued by ptrace would repeatedly stop for the same group stop until the group stop is complete. Conversely, if a ptraced task is in TASK_TRACED state, the debugger won't get notified of group stops which is inconsistent compared to the ptraced task in any other state. This patch introduces GROUP_STOP_PENDING which tracks whether a task is yet to stop for the group stop in progress. The flag is set when a group stop starts and cleared when the task stops the first time for the group stop, and consulted whenever whether the task should participate in a group stop needs to be determined. Note that now tasks in TASK_TRACED also participate in group stop. This results in the following behavior changes. * For a single group stop, a ptracer would see at most one stop reported. * A ptracee in TASK_TRACED now also participates in group stop and the tracer would get the notification. However, as a ptraced task could be in TASK_STOPPED state or any ptrace trap could consume group stop, the notification may still be missing. These will be addressed with further patches. * A ptracee may start a group stop while one is still in progress if the tracer let it continue with stop signal delivery. Group stop code handles this correctly. Oleg: * Spotted that a task might skip signal check even when its GROUP_STOP_PENDING is set. Fixed by updating recalc_sigpending_tsk() to check GROUP_STOP_PENDING instead of group_stop_count. * Pointed out that task->group_stop should be cleared whenever task->signal->group_stop_count is cleared. Fixed accordingly. * Pointed out the behavior inconsistency between TASK_TRACED and RUNNING and the last behavior change. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath --- fs/exec.c | 1 + include/linux/sched.h | 3 +++ kernel/signal.c | 36 +++++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 5e62d26a4fec..8328beb9016f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1659,6 +1659,7 @@ static int zap_process(struct task_struct *start, int exit_code) t = start; do { + task_clear_group_stop_pending(t); if (t != current && t->mm) { sigaddset(&t->pending.signal, SIGKILL); signal_wake_up(t, 1); diff --git a/include/linux/sched.h b/include/linux/sched.h index 85f51042c2b8..b2a17dfbdbad 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1775,8 +1775,11 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * /* * task->group_stop flags */ +#define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ +extern void task_clear_group_stop_pending(struct task_struct *task); + #ifdef CONFIG_PREEMPT_RCU #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */ diff --git a/kernel/signal.c b/kernel/signal.c index ecb20089eaff..a2e7a6527d24 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -124,7 +124,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) static int recalc_sigpending_tsk(struct task_struct *t) { - if (t->signal->group_stop_count > 0 || + if ((t->group_stop & GROUP_STOP_PENDING) || PENDING(&t->pending, &t->blocked) || PENDING(&t->signal->shared_pending, &t->blocked)) { set_tsk_thread_flag(t, TIF_SIGPENDING); @@ -232,19 +232,19 @@ static inline void print_dropped_signal(int sig) * CONTEXT: * Must be called with @task->sighand->siglock held. */ -static void task_clear_group_stop_pending(struct task_struct *task) +void task_clear_group_stop_pending(struct task_struct *task) { - task->group_stop &= ~GROUP_STOP_CONSUME; + task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME); } /** * task_participate_group_stop - participate in a group stop * @task: task participating in a group stop * - * @task is participating in a group stop. Group stop states are cleared - * and the group stop count is consumed if %GROUP_STOP_CONSUME was set. If - * the consumption completes the group stop, the appropriate %SIGNAL_* - * flags are set. + * @task has GROUP_STOP_PENDING set and is participating in a group stop. + * Group stop states are cleared and the group stop count is consumed if + * %GROUP_STOP_CONSUME was set. If the consumption completes the group + * stop, the appropriate %SIGNAL_* flags are set. * * CONTEXT: * Must be called with @task->sighand->siglock held. @@ -254,6 +254,8 @@ static bool task_participate_group_stop(struct task_struct *task) struct signal_struct *sig = task->signal; bool consume = task->group_stop & GROUP_STOP_CONSUME; + WARN_ON_ONCE(!(task->group_stop & GROUP_STOP_PENDING)); + task_clear_group_stop_pending(task); if (!consume) @@ -765,6 +767,9 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) t = p; do { unsigned int state; + + task_clear_group_stop_pending(t); + rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); /* * If there is a handler for SIGCONT, we must make @@ -906,6 +911,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) signal->group_stop_count = 0; t = p; do { + task_clear_group_stop_pending(t); sigaddset(&t->pending.signal, SIGKILL); signal_wake_up(t, 1); } while_each_thread(p, t); @@ -1139,6 +1145,7 @@ int zap_other_threads(struct task_struct *p) p->signal->group_stop_count = 0; while_each_thread(p, t) { + task_clear_group_stop_pending(t); count++; /* Don't bother with already dead threads */ @@ -1690,7 +1697,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) * If there is a group stop in progress, * we must participate in the bookkeeping. */ - if (current->signal->group_stop_count > 0) + if (current->group_stop & GROUP_STOP_PENDING) task_participate_group_stop(current); current->last_siginfo = info; @@ -1775,8 +1782,8 @@ static int do_signal_stop(int signr) struct signal_struct *sig = current->signal; int notify = 0; - if (!sig->group_stop_count) { - unsigned int gstop = GROUP_STOP_CONSUME; + if (!(current->group_stop & GROUP_STOP_PENDING)) { + unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME; struct task_struct *t; if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || @@ -1796,8 +1803,7 @@ static int do_signal_stop(int signr) * stop is always done with the siglock held, * so this check has no races. */ - if (!(t->flags & PF_EXITING) && - !task_is_stopped_or_traced(t)) { + if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) { t->group_stop = gstop; sig->group_stop_count++; signal_wake_up(t, 0); @@ -1926,8 +1932,8 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, if (unlikely(signr != 0)) ka = return_ka; else { - if (unlikely(signal->group_stop_count > 0) && - do_signal_stop(0)) + if (unlikely(current->group_stop & + GROUP_STOP_PENDING) && do_signal_stop(0)) goto relock; signr = dequeue_signal(current, ¤t->blocked, @@ -2073,7 +2079,7 @@ void exit_signals(struct task_struct *tsk) if (!signal_pending(t) && !(t->flags & PF_EXITING)) recalc_sigpending_and_wake(t); - if (unlikely(tsk->signal->group_stop_count) && + if (unlikely(tsk->group_stop & GROUP_STOP_PENDING) && task_participate_group_stop(tsk)) group_stop = CLD_STOPPED; out: -- GitLab From 0ae8ce1c8c5b9007ce6bfc83ec2aa0dfce5bbed3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0037/5560] ptrace: Participate in group stop from ptrace_stop() iff the task is trapping for group stop Currently, ptrace_stop() unconditionally participates in group stop bookkeeping. This is unnecessary and inaccurate. Make it only participate if the task is trapping for group stop - ie. if @why is CLD_STOPPED. As ptrace_stop() currently is not used when trapping for group stop, this equals to disabling group stop participation from ptrace_stop(). A visible behavior change is increased likelihood of delayed group stop completion if the thread group contains one or more ptraced tasks. This is to preapre for further cleanup of the interaction between group stop and ptrace. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath --- kernel/signal.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index a2e7a6527d24..9f36dd2e8d5a 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1694,10 +1694,13 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) } /* - * If there is a group stop in progress, - * we must participate in the bookkeeping. + * If @why is CLD_STOPPED, we're trapping to participate in a group + * stop. Do the bookkeeping. Note that if SIGCONT was delievered + * while siglock was released for the arch hook, PENDING could be + * clear now. We act as if SIGCONT is received after TASK_TRACED + * is entered - ignore it. */ - if (current->group_stop & GROUP_STOP_PENDING) + if (why == CLD_STOPPED && (current->group_stop & GROUP_STOP_PENDING)) task_participate_group_stop(current); current->last_siginfo = info; -- GitLab From 5224fa3660ad3881d2f2ad726d22614117963f10 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0038/5560] ptrace: Make do_signal_stop() use ptrace_stop() if the task is being ptraced A ptraced task would still stop at do_signal_stop() when it's stopping for stop signals and do_signal_stop() behaves the same whether the task is ptraced or not. However, in addition to stopping, ptrace_stop() also does ptrace specific stuff like calling architecture specific callbacks, so this behavior makes the code more fragile and difficult to understand. This patch makes do_signal_stop() test whether the task is ptraced and use ptrace_stop() if so. This renders tracehook_notify_jctl() rather pointless as the ptrace notification is now handled by ptrace_stop() regardless of the return value from the tracehook. It probably is a good idea to update it. This doesn't solve the whole problem as tasks already in stopped state would stay in the regular stop when ptrace attached. That part will be handled by the next patch. Oleg pointed out that this makes a userland-visible change. Before, SIGCONT would be able to wake up a task in group stop even if the task is ptraced if the tracer hasn't issued another ptrace command afterwards (as the next ptrace commands transitions the state into TASK_TRACED which ignores SIGCONT wakeups). With this and the next patch, SIGCONT may race with the transition into TASK_TRACED and is ignored if the tracee already entered TASK_TRACED. Another userland visible change of this and the next patch is that the ptracee's state would now be TASK_TRACED where it used to be TASK_STOPPED, which is visible via fs/proc. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath Cc: Jan Kratochvil --- kernel/signal.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 9f36dd2e8d5a..418776c41d24 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1783,7 +1783,6 @@ void ptrace_notify(int exit_code) static int do_signal_stop(int signr) { struct signal_struct *sig = current->signal; - int notify = 0; if (!(current->group_stop & GROUP_STOP_PENDING)) { unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME; @@ -1813,29 +1812,37 @@ static int do_signal_stop(int signr) } else task_clear_group_stop_pending(t); } - /* - * If there are no other threads in the group, or if there is - * a group stop in progress and we are the last to stop, report - * to the parent. When ptraced, every thread reports itself. - */ - if (task_participate_group_stop(current)) - notify = CLD_STOPPED; - if (task_ptrace(current)) - notify = CLD_STOPPED; current->exit_code = sig->group_exit_code; __set_current_state(TASK_STOPPED); - spin_unlock_irq(¤t->sighand->siglock); + if (likely(!task_ptrace(current))) { + int notify = 0; - if (notify) { - read_lock(&tasklist_lock); - do_notify_parent_cldstop(current, notify); - read_unlock(&tasklist_lock); - } + /* + * If there are no other threads in the group, or if there + * is a group stop in progress and we are the last to stop, + * report to the parent. + */ + if (task_participate_group_stop(current)) + notify = CLD_STOPPED; - /* Now we don't run again until woken by SIGCONT or SIGKILL */ - schedule(); + spin_unlock_irq(¤t->sighand->siglock); + + if (notify) { + read_lock(&tasklist_lock); + do_notify_parent_cldstop(current, notify); + read_unlock(&tasklist_lock); + } + + /* Now we don't run again until woken by SIGCONT or SIGKILL */ + schedule(); + + spin_lock_irq(¤t->sighand->siglock); + } else + ptrace_stop(current->exit_code, CLD_STOPPED, 0, NULL); + + spin_unlock_irq(¤t->sighand->siglock); tracehook_finish_jctl(); current->exit_code = 0; -- GitLab From d79fdd6d96f46fabb779d86332e3677c6f5c2a4f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:00 +0100 Subject: [PATCH 0039/5560] ptrace: Clean transitions between TASK_STOPPED and TRACED Currently, if the task is STOPPED on ptrace attach, it's left alone and the state is silently changed to TRACED on the next ptrace call. The behavior breaks the assumption that arch_ptrace_stop() is called before any task is poked by ptrace and is ugly in that a task manipulates the state of another task directly. With GROUP_STOP_PENDING, the transitions between TASK_STOPPED and TRACED can be made clean. The tracer can use the flag to tell the tracee to retry stop on attach and detach. On retry, the tracee will enter the desired state in the correct way. The lower 16bits of task->group_stop is used to remember the signal number which caused the last group stop. This is used while retrying for ptrace attach as the original group_exit_code could have been consumed with wait(2) by then. As the real parent may wait(2) and consume the group_exit_code anytime, the group_exit_code needs to be saved separately so that it can be used when switching from regular sleep to ptrace_stop(). This is recorded in the lower 16bits of task->group_stop. If a task is already stopped and there's no intervening SIGCONT, a ptrace request immediately following a successful PTRACE_ATTACH should always succeed even if the tracer doesn't wait(2) for attach completion; however, with this change, the tracee might still be TASK_RUNNING trying to enter TASK_TRACED which would cause the following request to fail with -ESRCH. This intermediate state is hidden from the ptracer by setting GROUP_STOP_TRAPPING on attach and making ptrace_check_attach() wait for it to clear on its signal->wait_chldexit. Completing the transition or getting killed clears TRAPPING and wakes up the tracer. Note that the STOPPED -> RUNNING -> TRACED transition is still visible to other threads which are in the same group as the ptracer and the reverse transition is visible to all. Please read the comments for details. Oleg: * Spotted a race condition where a task may retry group stop without proper bookkeeping. Fixed by redoing bookkeeping on retry. * Spotted that the transition is visible to userland in several different ways. Most are fixed with GROUP_STOP_TRAPPING. Unhandled corner case is documented. * Pointed out not setting GROUP_STOP_SIGMASK on an already stopped task would result in more consistent behavior. * Pointed out that calling ptrace_stop() from do_signal_stop() in TASK_STOPPED can race with group stop start logic and then confuse the TRAPPING wait in ptrace_check_attach(). ptrace_stop() is now called with TASK_RUNNING. * Suggested using signal->wait_chldexit instead of bit wait. * Spotted a race condition between TRACED transition and clearing of TRAPPING. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov Cc: Roland McGrath Cc: Jan Kratochvil --- include/linux/sched.h | 2 ++ kernel/ptrace.c | 49 ++++++++++++++++++++++++--- kernel/signal.c | 79 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 112 insertions(+), 18 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index b2a17dfbdbad..456d80ed3b78 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1775,8 +1775,10 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * /* * task->group_stop flags */ +#define GROUP_STOP_SIGMASK 0xffff /* signr of the last group stop */ #define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ +#define GROUP_STOP_TRAPPING (1 << 18) /* switching from STOPPED to TRACED */ extern void task_clear_group_stop_pending(struct task_struct *task); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 6acf8954017c..745fc2dd00c5 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -49,14 +49,22 @@ static void ptrace_untrace(struct task_struct *child) spin_lock(&child->sighand->siglock); if (task_is_traced(child)) { /* - * If the group stop is completed or in progress, - * this thread was already counted as stopped. + * If group stop is completed or in progress, it should + * participate in the group stop. Set GROUP_STOP_PENDING + * before kicking it. + * + * This involves TRACED -> RUNNING -> STOPPED transition + * which is similar to but in the opposite direction of + * what happens while attaching to a stopped task. + * However, in this direction, the intermediate RUNNING + * state is not hidden even from the current ptracer and if + * it immediately re-attaches and performs a WNOHANG + * wait(2), it may fail. */ if (child->signal->flags & SIGNAL_STOP_STOPPED || child->signal->group_stop_count) - __set_task_state(child, TASK_STOPPED); - else - signal_wake_up(child, 1); + child->group_stop |= GROUP_STOP_PENDING; + signal_wake_up(child, 1); } spin_unlock(&child->sighand->siglock); } @@ -165,6 +173,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) static int ptrace_attach(struct task_struct *task) { + bool wait_trap = false; int retval; audit_ptrace(task); @@ -204,12 +213,42 @@ static int ptrace_attach(struct task_struct *task) __ptrace_link(task, current); send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); + spin_lock(&task->sighand->siglock); + + /* + * If the task is already STOPPED, set GROUP_STOP_PENDING and + * TRAPPING, and kick it so that it transits to TRACED. TRAPPING + * will be cleared if the child completes the transition or any + * event which clears the group stop states happens. We'll wait + * for the transition to complete before returning from this + * function. + * + * This hides STOPPED -> RUNNING -> TRACED transition from the + * attaching thread but a different thread in the same group can + * still observe the transient RUNNING state. IOW, if another + * thread's WNOHANG wait(2) on the stopped tracee races against + * ATTACH, the wait(2) may fail due to the transient RUNNING. + * + * The following task_is_stopped() test is safe as both transitions + * in and out of STOPPED are protected by siglock. + */ + if (task_is_stopped(task)) { + task->group_stop |= GROUP_STOP_PENDING | GROUP_STOP_TRAPPING; + signal_wake_up(task, 1); + wait_trap = true; + } + + spin_unlock(&task->sighand->siglock); + retval = 0; unlock_tasklist: write_unlock_irq(&tasklist_lock); unlock_creds: mutex_unlock(&task->signal->cred_guard_mutex); out: + if (wait_trap) + wait_event(current->signal->wait_chldexit, + !(task->group_stop & GROUP_STOP_TRAPPING)); return retval; } diff --git a/kernel/signal.c b/kernel/signal.c index 418776c41d24..1e199919ae09 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -223,6 +223,26 @@ static inline void print_dropped_signal(int sig) current->comm, current->pid, sig); } +/** + * task_clear_group_stop_trapping - clear group stop trapping bit + * @task: target task + * + * If GROUP_STOP_TRAPPING is set, a ptracer is waiting for us. Clear it + * and wake up the ptracer. Note that we don't need any further locking. + * @task->siglock guarantees that @task->parent points to the ptracer. + * + * CONTEXT: + * Must be called with @task->sighand->siglock held. + */ +static void task_clear_group_stop_trapping(struct task_struct *task) +{ + if (unlikely(task->group_stop & GROUP_STOP_TRAPPING)) { + task->group_stop &= ~GROUP_STOP_TRAPPING; + __wake_up_sync(&task->parent->signal->wait_chldexit, + TASK_UNINTERRUPTIBLE, 1); + } +} + /** * task_clear_group_stop_pending - clear pending group stop * @task: target task @@ -1706,8 +1726,20 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) current->last_siginfo = info; current->exit_code = exit_code; - /* Let the debugger run. */ - __set_current_state(TASK_TRACED); + /* + * TRACED should be visible before TRAPPING is cleared; otherwise, + * the tracer might fail do_wait(). + */ + set_current_state(TASK_TRACED); + + /* + * We're committing to trapping. Clearing GROUP_STOP_TRAPPING and + * transition to TASK_TRACED should be atomic with respect to + * siglock. This hsould be done after the arch hook as siglock is + * released and regrabbed across it. + */ + task_clear_group_stop_trapping(current); + spin_unlock_irq(¤t->sighand->siglock); read_lock(&tasklist_lock); if (may_ptrace_stop()) { @@ -1788,6 +1820,9 @@ static int do_signal_stop(int signr) unsigned int gstop = GROUP_STOP_PENDING | GROUP_STOP_CONSUME; struct task_struct *t; + /* signr will be recorded in task->group_stop for retries */ + WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK); + if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || unlikely(signal_group_exit(sig))) return 0; @@ -1797,25 +1832,27 @@ static int do_signal_stop(int signr) */ sig->group_exit_code = signr; - current->group_stop = gstop; + current->group_stop &= ~GROUP_STOP_SIGMASK; + current->group_stop |= signr | gstop; sig->group_stop_count = 1; - for (t = next_thread(current); t != current; t = next_thread(t)) + for (t = next_thread(current); t != current; + t = next_thread(t)) { + t->group_stop &= ~GROUP_STOP_SIGMASK; /* * Setting state to TASK_STOPPED for a group * stop is always done with the siglock held, * so this check has no races. */ if (!(t->flags & PF_EXITING) && !task_is_stopped(t)) { - t->group_stop = gstop; + t->group_stop |= signr | gstop; sig->group_stop_count++; signal_wake_up(t, 0); - } else + } else { task_clear_group_stop_pending(t); + } + } } - - current->exit_code = sig->group_exit_code; - __set_current_state(TASK_STOPPED); - +retry: if (likely(!task_ptrace(current))) { int notify = 0; @@ -1827,6 +1864,7 @@ static int do_signal_stop(int signr) if (task_participate_group_stop(current)) notify = CLD_STOPPED; + __set_current_state(TASK_STOPPED); spin_unlock_irq(¤t->sighand->siglock); if (notify) { @@ -1839,13 +1877,28 @@ static int do_signal_stop(int signr) schedule(); spin_lock_irq(¤t->sighand->siglock); - } else - ptrace_stop(current->exit_code, CLD_STOPPED, 0, NULL); + } else { + ptrace_stop(current->group_stop & GROUP_STOP_SIGMASK, + CLD_STOPPED, 0, NULL); + current->exit_code = 0; + } + + /* + * GROUP_STOP_PENDING could be set if another group stop has + * started since being woken up or ptrace wants us to transit + * between TASK_STOPPED and TRACED. Retry group stop. + */ + if (current->group_stop & GROUP_STOP_PENDING) { + WARN_ON_ONCE(!(current->group_stop & GROUP_STOP_SIGMASK)); + goto retry; + } + + /* PTRACE_ATTACH might have raced with task killing, clear trapping */ + task_clear_group_stop_trapping(current); spin_unlock_irq(¤t->sighand->siglock); tracehook_finish_jctl(); - current->exit_code = 0; return 1; } -- GitLab From e3bd058f62896ec7a2c605ed62a0a811e9147947 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0040/5560] ptrace: Collapse ptrace_untrace() into __ptrace_unlink() Remove the extra task_is_traced() check in __ptrace_unlink() and collapse ptrace_untrace() into __ptrace_unlink(). This is to prepare for further changes. While at it, drop the comment on top of ptrace_untrace() and convert __ptrace_unlink() comment to docbook format. Detailed comment will be added by the next patch. This patch doesn't cause any visible behavior changes. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/ptrace.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 745fc2dd00c5..e6098434b533 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -37,15 +37,23 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) child->parent = new_parent; } -/* - * Turn a tracing stop into a normal stop now, since with no tracer there - * would be no way to wake it up with SIGCONT or SIGKILL. If there was a - * signal sent that would resume the child, but didn't because it was in - * TASK_TRACED, resume it now. - * Requires that irqs be disabled. +/** + * __ptrace_unlink - unlink ptracee and restore its execution state + * @child: ptracee to be unlinked + * + * Remove @child from the ptrace list, move it back to the original parent. + * + * CONTEXT: + * write_lock_irq(tasklist_lock) */ -static void ptrace_untrace(struct task_struct *child) +void __ptrace_unlink(struct task_struct *child) { + BUG_ON(!child->ptrace); + + child->ptrace = 0; + child->parent = child->real_parent; + list_del_init(&child->ptrace_entry); + spin_lock(&child->sighand->siglock); if (task_is_traced(child)) { /* @@ -69,24 +77,6 @@ static void ptrace_untrace(struct task_struct *child) spin_unlock(&child->sighand->siglock); } -/* - * unptrace a task: move it back to its original parent and - * remove it from the ptrace list. - * - * Must be called with the tasklist lock write-held. - */ -void __ptrace_unlink(struct task_struct *child) -{ - BUG_ON(!child->ptrace); - - child->ptrace = 0; - child->parent = child->real_parent; - list_del_init(&child->ptrace_entry); - - if (task_is_traced(child)) - ptrace_untrace(child); -} - /* * Check that we have indeed attached to the thing.. */ -- GitLab From 0e9f0a4abfd80f8adca624538d479d95159b16d8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0041/5560] ptrace: Always put ptracee into appropriate execution state Currently, __ptrace_unlink() wakes up the tracee iff it's in TASK_TRACED. For unlinking from PTRACE_DETACH, this is correct as the tracee is guaranteed to be in TASK_TRACED or dead; however, unlinking also happens when the ptracer exits and in this case the ptracee can be in any state and ptrace might be left running even if the group it belongs to is stopped. This patch updates __ptrace_unlink() such that GROUP_STOP_PENDING is reinstated regardless of the ptracee's current state as long as it's alive and makes sure that signal_wake_up() is called if execution state transition is necessary. Test case follows. #include #include #include #include #include static const struct timespec ts1s = { .tv_sec = 1 }; int main(void) { pid_t tracee; siginfo_t si; tracee = fork(); if (tracee == 0) { while (1) { nanosleep(&ts1s, NULL); write(1, ".", 1); } } ptrace(PTRACE_ATTACH, tracee, NULL, NULL); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); write(1, "exiting", 7); return 0; } Before the patch, after the parent process exits, the child is left running and prints out "." every second. exiting..... (continues) After the patch, the group stop initiated by the implied SIGSTOP from PTRACE_ATTACH is re-established when the parent exits. exiting Signed-off-by: Tejun Heo Reported-by: Oleg Nesterov Acked-by: Oleg Nesterov --- kernel/ptrace.c | 59 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index e6098434b533..43485866749a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -41,7 +41,26 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) * __ptrace_unlink - unlink ptracee and restore its execution state * @child: ptracee to be unlinked * - * Remove @child from the ptrace list, move it back to the original parent. + * Remove @child from the ptrace list, move it back to the original parent, + * and restore the execution state so that it conforms to the group stop + * state. + * + * Unlinking can happen via two paths - explicit PTRACE_DETACH or ptracer + * exiting. For PTRACE_DETACH, unless the ptracee has been killed between + * ptrace_check_attach() and here, it's guaranteed to be in TASK_TRACED. + * If the ptracer is exiting, the ptracee can be in any state. + * + * After detach, the ptracee should be in a state which conforms to the + * group stop. If the group is stopped or in the process of stopping, the + * ptracee should be put into TASK_STOPPED; otherwise, it should be woken + * up from TASK_TRACED. + * + * If the ptracee is in TASK_TRACED and needs to be moved to TASK_STOPPED, + * it goes through TRACED -> RUNNING -> STOPPED transition which is similar + * to but in the opposite direction of what happens while attaching to a + * stopped task. However, in this direction, the intermediate RUNNING + * state is not hidden even from the current ptracer and if it immediately + * re-attaches and performs a WNOHANG wait(2), it may fail. * * CONTEXT: * write_lock_irq(tasklist_lock) @@ -55,25 +74,25 @@ void __ptrace_unlink(struct task_struct *child) list_del_init(&child->ptrace_entry); spin_lock(&child->sighand->siglock); - if (task_is_traced(child)) { - /* - * If group stop is completed or in progress, it should - * participate in the group stop. Set GROUP_STOP_PENDING - * before kicking it. - * - * This involves TRACED -> RUNNING -> STOPPED transition - * which is similar to but in the opposite direction of - * what happens while attaching to a stopped task. - * However, in this direction, the intermediate RUNNING - * state is not hidden even from the current ptracer and if - * it immediately re-attaches and performs a WNOHANG - * wait(2), it may fail. - */ - if (child->signal->flags & SIGNAL_STOP_STOPPED || - child->signal->group_stop_count) - child->group_stop |= GROUP_STOP_PENDING; - signal_wake_up(child, 1); - } + + /* + * Reinstate GROUP_STOP_PENDING if group stop is in effect and + * @child isn't dead. + */ + if (!(child->flags & PF_EXITING) && + (child->signal->flags & SIGNAL_STOP_STOPPED || + child->signal->group_stop_count)) + child->group_stop |= GROUP_STOP_PENDING; + + /* + * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick + * @child in the butt. Note that @resume should be used iff @child + * is in TASK_TRACED; otherwise, we might unduly disrupt + * TASK_KILLABLE sleeps. + */ + if (child->group_stop & GROUP_STOP_PENDING || task_is_traced(child)) + signal_wake_up(child, task_is_traced(child)); + spin_unlock(&child->sighand->siglock); } -- GitLab From 408a37de6c95832a4880a88a742f89f0cc554d06 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0042/5560] job control: Don't set group_stop exit_code if re-entering job control stop While ptraced, a task may be resumed while the containing process is still job control stopped. If the task receives another stop signal in this state, it will still initiate group stop, which generates group_exit_code, which the real parent would be able to see once the ptracer detaches. In this scenario, the real parent may see two consecutive CLD_STOPPED events from two stop signals without intervening SIGCONT, which normally is impossible. Test case follows. #include #include #include #include int main(void) { pid_t tracee; siginfo_t si; tracee = fork(); if (!tracee) while (1) pause(); kill(tracee, SIGSTOP); waitid(P_PID, tracee, &si, WSTOPPED); if (!fork()) { ptrace(PTRACE_ATTACH, tracee, NULL, NULL); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_DETACH, tracee, NULL, NULL); return 0; } while (1) { si.si_pid = 0; waitid(P_PID, tracee, &si, WSTOPPED | WNOHANG); if (si.si_pid) printf("st=%02d c=%02d\n", si.si_status, si.si_code); } return 0; } Before the patch, the latter waitid() in polling mode reports the second stopped event generated by the implied SIGSTOP of PTRACE_ATTACH. st=19 c=05 ^C After the patch, the second event is not reported. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/signal.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 1e199919ae09..2f2c8f6ee01f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1827,10 +1827,27 @@ static int do_signal_stop(int signr) unlikely(signal_group_exit(sig))) return 0; /* - * There is no group stop already in progress. - * We must initiate one now. + * There is no group stop already in progress. We must + * initiate one now. + * + * While ptraced, a task may be resumed while group stop is + * still in effect and then receive a stop signal and + * initiate another group stop. This deviates from the + * usual behavior as two consecutive stop signals can't + * cause two group stops when !ptraced. + * + * The condition can be distinguished by testing whether + * SIGNAL_STOP_STOPPED is already set. Don't generate + * group_exit_code in such case. + * + * This is not necessary for SIGNAL_STOP_CONTINUED because + * an intervening stop signal is required to cause two + * continued events regardless of ptrace. */ - sig->group_exit_code = signr; + if (!(sig->flags & SIGNAL_STOP_STOPPED)) + sig->group_exit_code = signr; + else + WARN_ON_ONCE(!task_ptrace(current)); current->group_stop &= ~GROUP_STOP_SIGMASK; current->group_stop |= signr | gstop; -- GitLab From 823b018e5b1196d810790559357447948f644548 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0043/5560] job control: Small reorganization of wait_consider_task() Move EXIT_DEAD test in wait_consider_task() above ptrace check. As ptraced tasks can't be EXIT_DEAD, this change doesn't cause any behavior change. This is to prepare for further changes. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/exit.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index f9a45ebcc7b1..b4a935c72159 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1537,6 +1537,10 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, return 0; } + /* dead body doesn't have much to contribute */ + if (p->exit_state == EXIT_DEAD) + return 0; + if (likely(!ptrace) && unlikely(task_ptrace(p))) { /* * This child is hidden by ptrace. @@ -1546,9 +1550,6 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, return 0; } - if (p->exit_state == EXIT_DEAD) - return 0; - /* * We don't reap group leaders with subthreads. */ -- GitLab From 9b84cca2564b9a5b2d064fb44d2a55a5b44473a0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0044/5560] job control: Fix ptracer wait(2) hang and explain notask_error clearing wait(2) and friends allow access to stopped/continued states through zombies, which is required as the states are process-wide and should be accessible whether the leader task is alive or undead. wait_consider_task() implements this by always clearing notask_error and going through wait_task_stopped/continued() for unreaped zombies. However, while ptraced, the stopped state is per-task and as such if the ptracee became a zombie, there's no further stopped event to listen to and wait(2) and friends should return -ECHILD on the tracee. Fix it by clearing notask_error only if WCONTINUED | WEXITED is set for ptraced zombies. While at it, document why clearing notask_error is safe for each case. Test case follows. #include #include #include #include #include #include #include static void *nooper(void *arg) { pause(); return NULL; } int main(void) { const struct timespec ts1s = { .tv_sec = 1 }; pid_t tracee, tracer; siginfo_t si; tracee = fork(); if (tracee == 0) { pthread_t thr; pthread_create(&thr, NULL, nooper, NULL); nanosleep(&ts1s, NULL); printf("tracee exiting\n"); pthread_exit(NULL); /* let subthread run */ } tracer = fork(); if (tracer == 0) { ptrace(PTRACE_ATTACH, tracee, NULL, NULL); while (1) { if (waitid(P_PID, tracee, &si, WSTOPPED) < 0) { perror("waitid"); break; } ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); } return 0; } waitid(P_PID, tracer, &si, WEXITED); kill(tracee, SIGKILL); return 0; } Before the patch, after the tracee becomes a zombie, the tracer's waitid(WSTOPPED) never returns and the program doesn't terminate. tracee exiting ^C After the patch, tracee exiting triggers waitid() to fail. tracee exiting waitid: No child processes -v2: Oleg pointed out that exited in addition to continued can happen for ptraced dead group leader. Clear notask_error for ptraced child on WEXITED too. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/exit.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index b4a935c72159..84d13d6bb30b 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1550,17 +1550,41 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, return 0; } - /* - * We don't reap group leaders with subthreads. - */ - if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p)) - return wait_task_zombie(wo, p); + /* slay zombie? */ + if (p->exit_state == EXIT_ZOMBIE) { + /* we don't reap group leaders with subthreads */ + if (!delay_group_leader(p)) + return wait_task_zombie(wo, p); - /* - * It's stopped or running now, so it might - * later continue, exit, or stop again. - */ - wo->notask_error = 0; + /* + * Allow access to stopped/continued state via zombie by + * falling through. Clearing of notask_error is complex. + * + * When !@ptrace: + * + * If WEXITED is set, notask_error should naturally be + * cleared. If not, subset of WSTOPPED|WCONTINUED is set, + * so, if there are live subthreads, there are events to + * wait for. If all subthreads are dead, it's still safe + * to clear - this function will be called again in finite + * amount time once all the subthreads are released and + * will then return without clearing. + * + * When @ptrace: + * + * Stopped state is per-task and thus can't change once the + * target task dies. Only continued and exited can happen. + * Clear notask_error if WCONTINUED | WEXITED. + */ + if (likely(!ptrace) || (wo->wo_flags & (WCONTINUED | WEXITED))) + wo->notask_error = 0; + } else { + /* + * @p is alive and it's gonna stop, continue or exit, so + * there always is something to wait for. + */ + wo->notask_error = 0; + } if (task_stopped_code(p, ptrace)) return wait_task_stopped(wo, ptrace, p); -- GitLab From 45cb24a1da53beb70f09efccc0373f6a47a9efe0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0045/5560] job control: Allow access to job control events through ptracees Currently a real parent can't access job control stopped/continued events through a ptraced child. This utterly breaks job control when the children are ptraced. For example, if a program is run from an interactive shell and then strace(1) attaches to it, pressing ^Z would send SIGTSTP and strace(1) would notice it but the shell has no way to tell whether the child entered job control stop and thus can't tell when to take over the terminal - leading to awkward lone ^Z on the terminal. Because the job control and ptrace stopped states are independent, there is no reason to prevent real parents from accessing the stopped state regardless of ptrace. The continued state isn't separate but ptracers don't have any use for them as ptracees can never resume without explicit command from their ptracers, so as long as ptracers don't consume it, it should be fine. Although this is a behavior change, because the previous behavior is utterly broken when viewed from real parents and the change is only visible to real parents, I don't think it's necessary to make this behavior optional. One situation to be careful about is when a task from the real parent's group is ptracing. The parent group is the recipient of both ptrace and job control stop events and one stop can be reported as both job control and ptrace stops. As this can break the current ptrace users, suppress job control stopped events for these cases. If a real parent ptracer wants to know about both job control and ptrace stops, it can create a separate process to serve the role of real parent. Note that this only updates wait(2) side of things. The real parent can access the states via wait(2) but still is not properly notified (woken up and delivered signal). Test case polls wait(2) with WNOHANG to work around. Notification will be updated by future patches. Test case follows. #include #include #include #include #include #include #include int main(void) { const struct timespec ts100ms = { .tv_nsec = 100000000 }; pid_t tracee, tracer; siginfo_t si; int i; tracee = fork(); if (tracee == 0) { while (1) { printf("tracee: SIGSTOP\n"); raise(SIGSTOP); nanosleep(&ts100ms, NULL); printf("tracee: SIGCONT\n"); raise(SIGCONT); nanosleep(&ts100ms, NULL); } } waitid(P_PID, tracee, &si, WSTOPPED | WNOHANG | WNOWAIT); tracer = fork(); if (tracer == 0) { nanosleep(&ts100ms, NULL); ptrace(PTRACE_ATTACH, tracee, NULL, NULL); for (i = 0; i < 11; i++) { si.si_pid = 0; waitid(P_PID, tracee, &si, WSTOPPED); if (si.si_pid && si.si_code == CLD_TRAPPED) ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); } printf("tracer: EXITING\n"); return 0; } while (1) { si.si_pid = 0; waitid(P_PID, tracee, &si, WSTOPPED | WCONTINUED | WEXITED | WNOHANG); if (si.si_pid) printf("mommy : WAIT status=%02d code=%02d\n", si.si_status, si.si_code); nanosleep(&ts100ms, NULL); } return 0; } Before the patch, while ptraced, the parent can't see any job control events. tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT tracee: SIGSTOP tracee: SIGCONT tracee: SIGSTOP tracee: SIGCONT tracee: SIGSTOP tracer: EXITING mommy : WAIT status=19 code=05 ^C After the patch, tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT mommy : WAIT status=18 code=06 tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT mommy : WAIT status=18 code=06 tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT mommy : WAIT status=18 code=06 tracee: SIGSTOP tracer: EXITING mommy : WAIT status=19 code=05 ^C -v2: Oleg pointed out that wait(2) should be suppressed for the real parent's group instead of only the real parent task itself. Updated accordingly. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/exit.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 84d13d6bb30b..1a0f10f0a4db 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1541,17 +1541,19 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, if (p->exit_state == EXIT_DEAD) return 0; - if (likely(!ptrace) && unlikely(task_ptrace(p))) { + /* slay zombie? */ + if (p->exit_state == EXIT_ZOMBIE) { /* - * This child is hidden by ptrace. - * We aren't allowed to see it now, but eventually we will. + * A zombie ptracee is only visible to its ptracer. + * Notification and reaping will be cascaded to the real + * parent when the ptracer detaches. */ - wo->notask_error = 0; - return 0; - } + if (likely(!ptrace) && unlikely(task_ptrace(p))) { + /* it will become visible, clear notask_error */ + wo->notask_error = 0; + return 0; + } - /* slay zombie? */ - if (p->exit_state == EXIT_ZOMBIE) { /* we don't reap group leaders with subthreads */ if (!delay_group_leader(p)) return wait_task_zombie(wo, p); @@ -1579,6 +1581,20 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, if (likely(!ptrace) || (wo->wo_flags & (WCONTINUED | WEXITED))) wo->notask_error = 0; } else { + /* + * If @p is ptraced by a task in its real parent's group, + * hide group stop/continued state when looking at @p as + * the real parent; otherwise, a single stop can be + * reported twice as group and ptrace stops. + * + * If a ptracer wants to distinguish the two events for its + * own children, it should create a separate process which + * takes the role of real parent. + */ + if (likely(!ptrace) && task_ptrace(p) && + same_thread_group(p->parent, p->real_parent)) + return 0; + /* * @p is alive and it's gonna stop, continue or exit, so * there always is something to wait for. @@ -1586,9 +1602,18 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, wo->notask_error = 0; } + /* + * Wait for stopped. Depending on @ptrace, different stopped state + * is used and the two don't interact with each other. + */ if (task_stopped_code(p, ptrace)) return wait_task_stopped(wo, ptrace, p); + /* + * Wait for continued. There's only one continued state and the + * ptracer can consume it which can confuse the real parent. Don't + * use WCONTINUED from ptracer. You don't need or want it. + */ return wait_task_continued(wo, p); } -- GitLab From 75b95953a56969a990e6ce154b260be83818fe71 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0046/5560] job control: Add @for_ptrace to do_notify_parent_cldstop() Currently, do_notify_parent_cldstop() determines whether the notification is for the real parent or ptracer. Move the decision to the caller by adding @for_ptrace parameter to do_notify_parent_cldstop(). All the callers are updated to pass task_ptrace(target_task), so this patch doesn't cause any behavior difference. While at it, add function comment to do_notify_parent_cldstop(). Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/signal.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 2f2c8f6ee01f..69d60540a680 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1595,16 +1595,30 @@ int do_notify_parent(struct task_struct *tsk, int sig) return ret; } -static void do_notify_parent_cldstop(struct task_struct *tsk, int why) +/** + * do_notify_parent_cldstop - notify parent of stopped/continued state change + * @tsk: task reporting the state change + * @for_ptracer: the notification is for ptracer + * @why: CLD_{CONTINUED|STOPPED|TRAPPED} to report + * + * Notify @tsk's parent that the stopped/continued state has changed. If + * @for_ptracer is %false, @tsk's group leader notifies to its real parent. + * If %true, @tsk reports to @tsk->parent which should be the ptracer. + * + * CONTEXT: + * Must be called with tasklist_lock at least read locked. + */ +static void do_notify_parent_cldstop(struct task_struct *tsk, + bool for_ptracer, int why) { struct siginfo info; unsigned long flags; struct task_struct *parent; struct sighand_struct *sighand; - if (task_ptrace(tsk)) + if (for_ptracer) { parent = tsk->parent; - else { + } else { tsk = tsk->group_leader; parent = tsk->real_parent; } @@ -1743,7 +1757,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) spin_unlock_irq(¤t->sighand->siglock); read_lock(&tasklist_lock); if (may_ptrace_stop()) { - do_notify_parent_cldstop(current, why); + do_notify_parent_cldstop(current, task_ptrace(current), why); /* * Don't want to allow preemption here, because * sys_ptrace() needs this task to be inactive. @@ -1886,7 +1900,8 @@ static int do_signal_stop(int signr) if (notify) { read_lock(&tasklist_lock); - do_notify_parent_cldstop(current, notify); + do_notify_parent_cldstop(current, task_ptrace(current), + notify); read_unlock(&tasklist_lock); } @@ -1982,6 +1997,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, * the CLD_ si_code into SIGNAL_CLD_MASK bits. */ if (unlikely(signal->flags & SIGNAL_CLD_MASK)) { + struct task_struct *leader; int why; if (signal->flags & SIGNAL_CLD_CONTINUED) @@ -1994,7 +2010,8 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, spin_unlock_irq(&sighand->siglock); read_lock(&tasklist_lock); - do_notify_parent_cldstop(current->group_leader, why); + leader = current->group_leader; + do_notify_parent_cldstop(leader, task_ptrace(leader), why); read_unlock(&tasklist_lock); goto relock; } @@ -2167,7 +2184,7 @@ void exit_signals(struct task_struct *tsk) if (unlikely(group_stop)) { read_lock(&tasklist_lock); - do_notify_parent_cldstop(tsk, group_stop); + do_notify_parent_cldstop(tsk, task_ptrace(tsk), group_stop); read_unlock(&tasklist_lock); } } -- GitLab From 62bcf9d992ecc19ea4f37ff57ee0b3333e3e843e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0047/5560] job control: Job control stop notifications should always go to the real parent The stopped notifications in do_signal_stop() and exit_signals() are always for the completion of job control. The one in do_signal_stop() may be delivered to the ptracer if PTRACE_ATTACH races with notification and the one in exit_signals() if task exits while ptraced. In both cases, the notifications are meaningless and confusing to the ptracer as it never accesses the group stop state while the real parent would miss notifications for the events it is watching. Make sure these notifications always go to the real parent by calling do_notify_parent_cld_stop() with %false @for_ptrace. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/signal.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 69d60540a680..9f10b246fd46 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1898,10 +1898,18 @@ static int do_signal_stop(int signr) __set_current_state(TASK_STOPPED); spin_unlock_irq(¤t->sighand->siglock); + /* + * Notify the parent of the group stop completion. Because + * we're not holding either the siglock or tasklist_lock + * here, ptracer may attach inbetween; however, this is for + * group stop and should always be delivered to the real + * parent of the group leader. The new ptracer will get + * its notification when this task transitions into + * TASK_TRACED. + */ if (notify) { read_lock(&tasklist_lock); - do_notify_parent_cldstop(current, task_ptrace(current), - notify); + do_notify_parent_cldstop(current, false, notify); read_unlock(&tasklist_lock); } @@ -2182,9 +2190,13 @@ void exit_signals(struct task_struct *tsk) out: spin_unlock_irq(&tsk->sighand->siglock); + /* + * If group stop has completed, deliver the notification. This + * should always go to the real parent of the group leader. + */ if (unlikely(group_stop)) { read_lock(&tasklist_lock); - do_notify_parent_cldstop(tsk, task_ptrace(tsk), group_stop); + do_notify_parent_cldstop(tsk, false, group_stop); read_unlock(&tasklist_lock); } } -- GitLab From ceb6bd67f9b9db765e1c29405f26e8460391badd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0048/5560] job control: Notify the real parent of job control events regardless of ptrace With recent changes, job control and ptrace stopped states are properly separated and accessible to the real parent and the ptracer respectively; however, notifications of job control stopped/continued events to the real parent while ptraced are still missing. A ptracee participates in group stop in ptrace_stop() but the completion isn't notified. If participation results in completion of group stop, notify the real parent of the event. The ptrace and group stops are separate and can be handled as such. However, when the real parent and the ptracer are in the same thread group, only the ptrace stop event is visible through wait(2) and the duplicate notifications are different from the current behavior and are confusing. Suppress group stop notification in such cases. The continued state is shared between the real parent and the ptracer but is only meaningful to the real parent. Always notify the real parent and notify the ptracer too for backward compatibility. Similar to stop notification, if the real parent is the ptracer, suppress a duplicate notification. Test case follows. #include #include #include #include #include #include #include int main(void) { const struct timespec ts100ms = { .tv_nsec = 100000000 }; pid_t tracee, tracer; siginfo_t si; int i; tracee = fork(); if (tracee == 0) { while (1) { printf("tracee: SIGSTOP\n"); raise(SIGSTOP); nanosleep(&ts100ms, NULL); printf("tracee: SIGCONT\n"); raise(SIGCONT); nanosleep(&ts100ms, NULL); } } waitid(P_PID, tracee, &si, WSTOPPED | WNOHANG | WNOWAIT); tracer = fork(); if (tracer == 0) { nanosleep(&ts100ms, NULL); ptrace(PTRACE_ATTACH, tracee, NULL, NULL); for (i = 0; i < 11; i++) { si.si_pid = 0; waitid(P_PID, tracee, &si, WSTOPPED); if (si.si_pid && si.si_code == CLD_TRAPPED) ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); } printf("tracer: EXITING\n"); return 0; } while (1) { si.si_pid = 0; waitid(P_PID, tracee, &si, WSTOPPED | WCONTINUED | WEXITED); if (si.si_pid) printf("mommy : WAIT status=%02d code=%02d\n", si.si_status, si.si_code); } return 0; } Before this patch, while ptraced, the real parent doesn't get notifications for job control events, so although it can access those events, the later waitid(2) call never wakes up. tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT tracee: SIGSTOP tracee: SIGCONT tracee: SIGSTOP tracee: SIGCONT tracee: SIGSTOP tracer: EXITING mommy : WAIT status=19 code=05 ^C After this patch, it works as expected. tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT mommy : WAIT status=18 code=06 tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT mommy : WAIT status=18 code=06 tracee: SIGSTOP mommy : WAIT status=19 code=05 tracee: SIGCONT mommy : WAIT status=18 code=06 tracee: SIGSTOP tracer: EXITING mommy : WAIT status=19 code=05 ^C -v2: Oleg pointed out that * Group stop notification to the real parent should also happen when ptracer detach races with ptrace_stop(). * real_parent_is_ptracer() should be testing thread group equality not the task itself as wait(2) and stop/cont notifications are normally thread-group wide. Both issues are fixed accordingly. -v3: real_parent_is_ptracer() updated to test child->real_parent instead of child->group_leader->real_parent per Oleg's suggestion. Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/signal.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 9f10b246fd46..f65403da4101 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1693,6 +1693,15 @@ static int sigkill_pending(struct task_struct *tsk) sigismember(&tsk->signal->shared_pending.signal, SIGKILL); } +/* + * Test whether the target task of the usual cldstop notification - the + * real_parent of @child - is in the same group as the ptracer. + */ +static bool real_parent_is_ptracer(struct task_struct *child) +{ + return same_thread_group(child->parent, child->real_parent); +} + /* * This must be called with current->sighand->siglock held. * @@ -1708,6 +1717,8 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) __releases(¤t->sighand->siglock) __acquires(¤t->sighand->siglock) { + bool gstop_done = false; + if (arch_ptrace_stop_needed(exit_code, info)) { /* * The arch code has something special to do before a @@ -1735,7 +1746,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) * is entered - ignore it. */ if (why == CLD_STOPPED && (current->group_stop & GROUP_STOP_PENDING)) - task_participate_group_stop(current); + gstop_done = task_participate_group_stop(current); current->last_siginfo = info; current->exit_code = exit_code; @@ -1757,7 +1768,20 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) spin_unlock_irq(¤t->sighand->siglock); read_lock(&tasklist_lock); if (may_ptrace_stop()) { - do_notify_parent_cldstop(current, task_ptrace(current), why); + /* + * Notify parents of the stop. + * + * While ptraced, there are two parents - the ptracer and + * the real_parent of the group_leader. The ptracer should + * know about every stop while the real parent is only + * interested in the completion of group stop. The states + * for the two don't interact with each other. Notify + * separately unless they're gonna be duplicates. + */ + do_notify_parent_cldstop(current, true, why); + if (gstop_done && !real_parent_is_ptracer(current)) + do_notify_parent_cldstop(current, false, why); + /* * Don't want to allow preemption here, because * sys_ptrace() needs this task to be inactive. @@ -1772,7 +1796,16 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) /* * By the time we got the lock, our tracer went away. * Don't drop the lock yet, another tracer may come. + * + * If @gstop_done, the ptracer went away between group stop + * completion and here. During detach, it would have set + * GROUP_STOP_PENDING on us and we'll re-enter TASK_STOPPED + * in do_signal_stop() on return, so notifying the real + * parent of the group stop completion is enough. */ + if (gstop_done) + do_notify_parent_cldstop(current, false, why); + __set_current_state(TASK_RUNNING); if (clear_code) current->exit_code = 0; @@ -2017,10 +2050,24 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, spin_unlock_irq(&sighand->siglock); + /* + * Notify the parent that we're continuing. This event is + * always per-process and doesn't make whole lot of sense + * for ptracers, who shouldn't consume the state via + * wait(2) either, but, for backward compatibility, notify + * the ptracer of the group leader too unless it's gonna be + * a duplicate. + */ read_lock(&tasklist_lock); + + do_notify_parent_cldstop(current, false, why); + leader = current->group_leader; - do_notify_parent_cldstop(leader, task_ptrace(leader), why); + if (task_ptrace(leader) && !real_parent_is_ptracer(leader)) + do_notify_parent_cldstop(leader, true, why); + read_unlock(&tasklist_lock); + goto relock; } -- GitLab From 244056f9dbbc6dc4126a301c745fa3dd67d8af3c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 23 Mar 2011 10:37:01 +0100 Subject: [PATCH 0049/5560] job control: Don't send duplicate job control stop notification while ptraced Just as group_exit_code shouldn't be generated when a PTRACE_CONT'd task re-enters job control stop, notifiction for the event should be suppressed too. The logic is the same as the group_exit_code generation suppression in do_signal_stop(), if SIGNAL_STOP_STOPPED is already set, the task is re-entering job control stop without intervening SIGCONT and the notifications should be suppressed. Test case follows. #include #include #include #include #include #include static const struct timespec ts100ms = { .tv_nsec = 100000000 }; static pid_t tracee, tracer; static const char *pid_who(pid_t pid) { return pid == tracee ? "tracee" : (pid == tracer ? "tracer" : "mommy "); } static void sigchld_sigaction(int signo, siginfo_t *si, void *ucxt) { printf("%s: SIG status=%02d code=%02d (%s)\n", pid_who(getpid()), si->si_status, si->si_code, pid_who(si->si_pid)); } int main(void) { const struct sigaction chld_sa = { .sa_sigaction = sigchld_sigaction, .sa_flags = SA_SIGINFO|SA_RESTART }; siginfo_t si; sigaction(SIGCHLD, &chld_sa, NULL); tracee = fork(); if (!tracee) { tracee = getpid(); while (1) pause(); } kill(tracee, SIGSTOP); waitid(P_PID, tracee, &si, WSTOPPED); tracer = fork(); if (!tracer) { tracer = getpid(); ptrace(PTRACE_ATTACH, tracee, NULL, NULL); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); waitid(P_PID, tracee, &si, WSTOPPED); ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status); waitid(P_PID, tracee, &si, WSTOPPED); printf("tracer: detaching\n"); ptrace(PTRACE_DETACH, tracee, NULL, NULL); return 0; } while (1) pause(); return 0; } Before the patch, the parent gets the second notification for the tracee after the tracer detaches. si_status is zero because group_exit_code is not set by the group stop completion which triggered this notification. mommy : SIG status=19 code=05 (tracee) tracer: SIG status=00 code=05 (tracee) tracer: SIG status=19 code=04 (tracee) tracer: SIG status=00 code=05 (tracee) tracer: detaching mommy : SIG status=00 code=05 (tracee) mommy : SIG status=00 code=01 (tracer) ^C After the patch, the duplicate notification is gone. mommy : SIG status=19 code=05 (tracee) tracer: SIG status=00 code=05 (tracee) tracer: SIG status=19 code=04 (tracee) tracer: SIG status=00 code=05 (tracee) tracer: detaching mommy : SIG status=00 code=01 (tracer) ^C Signed-off-by: Tejun Heo Acked-by: Oleg Nesterov --- kernel/signal.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/signal.c b/kernel/signal.c index f65403da4101..f799a054f292 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -268,6 +268,10 @@ void task_clear_group_stop_pending(struct task_struct *task) * * CONTEXT: * Must be called with @task->sighand->siglock held. + * + * RETURNS: + * %true if group stop completion should be notified to the parent, %false + * otherwise. */ static bool task_participate_group_stop(struct task_struct *task) { @@ -284,7 +288,11 @@ static bool task_participate_group_stop(struct task_struct *task) if (!WARN_ON_ONCE(sig->group_stop_count == 0)) sig->group_stop_count--; - if (!sig->group_stop_count) { + /* + * Tell the caller to notify completion iff we are entering into a + * fresh group stop. Read comment in do_signal_stop() for details. + */ + if (!sig->group_stop_count && !(sig->flags & SIGNAL_STOP_STOPPED)) { sig->flags = SIGNAL_STOP_STOPPED; return true; } -- GitLab From bc92df7fe55e49c616a003b0b77e7badf2736429 Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Wed, 23 Mar 2011 17:56:05 +0800 Subject: [PATCH 0050/5560] ALSA: hda - VIA: Add support for VT1705 Add support for VT1705 codec, which is similiar with VT1708S except it has 6 channels output. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 100 +++++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 23cb44086b27..b7650a3dea03 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -3181,7 +3181,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) int imux_is_smixer; unsigned int parm; int is_8ch = 0; - if (spec->codec_type != VT1708B_4CH) + if ((spec->codec_type != VT1708B_4CH) && + (codec->vendor_id != 0x11064397)) is_8ch = 1; /* SW0 (17h) = stereo mixer */ @@ -3220,6 +3221,16 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) AC_VERB_SET_POWER_STATE, parm); snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_POWER_STATE, parm); + } else if (codec->vendor_id == 0x11064397) { + /* PW7(23h), SW2(27h), AOW2(25h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x23, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1a, &parm); + snd_hda_codec_write(codec, 0x27, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); } /* PW 3/4/7 (1ch/1dh/23h) */ @@ -3239,7 +3250,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) AC_VERB_SET_POWER_STATE, parm); snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); - } + } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); } static int patch_vt1708S(struct hda_codec *codec); @@ -3414,6 +3427,18 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = { { } }; +static struct hda_verb vt1705_uniwill_init_verbs[] = { + {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, + {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + { } +}; + static struct hda_pcm_stream vt1708S_pcm_analog_playback = { .substreams = 2, .channels_min = 2, @@ -3427,6 +3452,19 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = { }, }; +static struct hda_pcm_stream vt1705_pcm_analog_playback = { + .substreams = 2, + .channels_min = 2, + .channels_max = 6, + .nid = 0x10, /* NID to query formats and rates */ + .ops = { + .open = via_playback_pcm_open, + .prepare = via_playback_multi_pcm_prepare, + .cleanup = via_playback_multi_pcm_cleanup, + .close = via_pcm_open_close + }, +}; + static struct hda_pcm_stream vt1708S_pcm_analog_capture = { .substreams = 2, .channels_min = 2, @@ -3473,7 +3511,10 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, spec->multiout.dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0x24; + if (spec->codec->vendor_id == 0x11064397) + spec->multiout.dac_nids[i] = 0x25; + else + spec->multiout.dac_nids[i] = 0x24; break; case AUTO_SEQ_SURROUND: spec->multiout.dac_nids[i] = 0x11; @@ -3489,22 +3530,28 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, if (cfg->line_outs == 1) { spec->multiout.num_dacs = 3; spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; - spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; + if (spec->codec->vendor_id == 0x11064397) + spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x25; + else + spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; } return 0; } /* add playback controls from the parsed DAC table */ -static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, +static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { + struct via_spec *spec = codec->spec; char name[32]; static const char * const chname[4] = { "Front", "Surround", "C/LFE", "Side" }; - hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; - hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; + hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25}, + {0x10, 0x11, 0x25, 0} }; + hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27}, + {0x1C, 0x18, 0x27, 0} }; hda_nid_t nid, nid_vol, nid_mute; int i, err; @@ -3515,8 +3562,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, if (!nid && i > AUTO_SEQ_CENLFE) continue; - nid_vol = nid_vols[i]; - nid_mute = nid_mutes[i]; + if (codec->vendor_id == 0x11064397) { + nid_vol = nid_vols[1][i]; + nid_mute = nid_mutes[1][i]; + } else { + nid_vol = nid_vols[0][i]; + nid_mute = nid_mutes[0][i]; + } + if (!nid_vol && !nid_mute) + continue; if (i == AUTO_SEQ_CENLFE) { /* Center/LFE */ @@ -3670,7 +3724,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) return 0; /* can't find valid BIOS pin config */ - err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); + err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg); if (err < 0) return err; err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); @@ -3737,17 +3791,29 @@ static int patch_vt1708S(struct hda_codec *codec) } spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; - spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; + if (codec->vendor_id == 0x11064397) + spec->init_verbs[spec->num_iverbs++] = + vt1705_uniwill_init_verbs; + else + spec->init_verbs[spec->num_iverbs++] = + vt1708S_uniwill_init_verbs; if (codec->vendor_id == 0x11060440) spec->stream_name_analog = "VT1818S Analog"; + else if (codec->vendor_id == 0x11064397) + spec->stream_name_analog = "VT1705 Analog"; else spec->stream_name_analog = "VT1708S Analog"; - spec->stream_analog_playback = &vt1708S_pcm_analog_playback; + if (codec->vendor_id == 0x11064397) + spec->stream_analog_playback = &vt1705_pcm_analog_playback; + else + spec->stream_analog_playback = &vt1708S_pcm_analog_playback; spec->stream_analog_capture = &vt1708S_pcm_analog_capture; if (codec->vendor_id == 0x11060440) spec->stream_name_digital = "VT1818S Digital"; + else if (codec->vendor_id == 0x11064397) + spec->stream_name_digital = "VT1705 Digital"; else spec->stream_name_digital = "VT1708S Digital"; spec->stream_digital_playback = &vt1708S_pcm_digital_playback; @@ -3785,6 +3851,14 @@ static int patch_vt1708S(struct hda_codec *codec) spec->stream_name_analog = "VT1818S Analog"; spec->stream_name_digital = "VT1818S Digital"; } + /* correct names for VT1705 */ + if (codec->vendor_id == 0x11064397) { + kfree(codec->chip_name); + codec->chip_name = kstrdup("VT1705", GFP_KERNEL); + snprintf(codec->bus->card->mixername, + sizeof(codec->bus->card->mixername), + "%s %s", codec->vendor_name, codec->chip_name); + } spec->set_widgets_power_state = set_widgets_power_state_vt1708B; return 0; } @@ -6003,7 +6077,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = { .patch = patch_vt1708S}, { .id = 0x11063397, .name = "VT1708S", .patch = patch_vt1708S}, - { .id = 0x11064397, .name = "VT1708S", + { .id = 0x11064397, .name = "VT1705", .patch = patch_vt1708S}, { .id = 0x11065397, .name = "VT1708S", .patch = patch_vt1708S}, -- GitLab From 11890956e948e6ed1b3e4acc11b6879db6ace01b Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Wed, 23 Mar 2011 17:57:34 +0800 Subject: [PATCH 0051/5560] ALSA: hda - VIA: Add support for VT1802 Add support for VT1802 codec, which is similiar with VT2002P except VT1802 has no Class-D and has some different pin widget id. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 195 +++++++++++++++++++++++++++++++------- 1 file changed, 163 insertions(+), 32 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index b7650a3dea03..74e2a2482815 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -98,9 +98,15 @@ enum VIA_HDA_CODEC { VT1716S, VT2002P, VT1812, + VT1802, CODEC_TYPES, }; +#define VT2002P_COMPATIBLE(spec) \ + ((spec)->codec_type == VT2002P ||\ + (spec)->codec_type == VT1812 ||\ + (spec)->codec_type == VT1802) + struct via_spec { /* codec parameterization */ struct snd_kcontrol_new *mixers[6]; @@ -221,6 +227,8 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) codec_type = VT1812; else if (dev_id == 0x0440) codec_type = VT1708S; + else if ((dev_id & 0xfff) == 0x446) + codec_type = VT1802; else codec_type = UNKNOWN; return codec_type; @@ -749,8 +757,7 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, || spec->codec_type == VT1702 || spec->codec_type == VT1718S || spec->codec_type == VT1716S - || spec->codec_type == VT2002P - || spec->codec_type == VT1812) { + || VT2002P_COMPATIBLE(spec)) { activate_ctl(codec, "Headphone Playback Volume", spec->hp_independent_mode); activate_ctl(codec, "Headphone Playback Switch", @@ -788,6 +795,7 @@ static int via_hp_build(struct hda_codec *codec) nid = 0x34; break; case VT2002P: + case VT1802: nid = 0x35; break; case VT1812: @@ -1071,6 +1079,7 @@ static int is_aa_path_mute(struct hda_codec *codec) break; case VT2002P: case VT1812: + case VT1802: nid_mixer = 0x21; start_idx = 0; end_idx = 2; @@ -1135,6 +1144,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) break; case VT2002P: case VT1812: + case VT1802: verb = 0xf93; parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ break; @@ -2151,7 +2161,8 @@ static int via_auto_init(struct hda_codec *codec) via_auto_init_multi_out(codec); via_auto_init_hp_out(codec); via_auto_init_analog_input(codec); - if (spec->codec_type == VT2002P || spec->codec_type == VT1812) { + + if (VT2002P_COMPATIBLE(spec)) { via_hp_bind_automute(codec); } else { via_hp_automute(codec); @@ -5291,6 +5302,57 @@ static struct hda_verb vt2002P_volume_init_verbs[] = { {0x1, 0xfb8, 0x88}, { } }; +static struct hda_verb vt1802_volume_init_verbs[] = { + /* + * Unmute ADC0-1 and set the default input to mic-in + */ + {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + + + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + * mixer widget + */ + /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + + /* MUX Indices: Mic = 0 */ + {0x1e, AC_VERB_SET_CONNECT_SEL, 0}, + {0x1f, AC_VERB_SET_CONNECT_SEL, 0}, + + /* PW9 Output enable */ + {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, + + /* Enable Boost Volume backdoor */ + {0x1, 0xfb9, 0x24}, + + /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */ + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* set MUX0/1/4/8 = 0 (AOW0) */ + {0x34, AC_VERB_SET_CONNECT_SEL, 0}, + {0x35, AC_VERB_SET_CONNECT_SEL, 0}, + {0x38, AC_VERB_SET_CONNECT_SEL, 0}, + {0x3c, AC_VERB_SET_CONNECT_SEL, 0}, + + /* set PW0 index=0 (MW0) */ + {0x24, AC_VERB_SET_CONNECT_SEL, 0}, + + /* Enable AOW0 to MW9 */ + {0x1, 0xfb8, 0x88}, + { } +}; static struct hda_verb vt2002P_uniwill_init_verbs[] = { @@ -5303,6 +5365,16 @@ static struct hda_verb vt2002P_uniwill_init_verbs[] = { {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, { } }; +static struct hda_verb vt1802_uniwill_init_verbs[] = { + {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, + {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, + {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + { } +}; static struct hda_pcm_stream vt2002P_pcm_analog_playback = { .substreams = 2, @@ -5359,10 +5431,15 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { int err; + hda_nid_t sw_nid; if (!cfg->line_out_pins[0]) return -1; + if (spec->codec_type == VT1802) + sw_nid = 0x28; + else + sw_nid = 0x26; /* Line-Out: PortE */ err = via_add_control(spec, VIA_CTL_WIDGET_VOL, @@ -5372,7 +5449,7 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, return err; err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, "Master Front Playback Switch", - HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT)); + HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT)); if (err < 0) return err; @@ -5507,21 +5584,41 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) /* AOW0 (8h)*/ snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); - /* PW4 (26h), MW4 (1ch), MUX4(37h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x26, &parm); - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x37, 0, - AC_VERB_SET_POWER_STATE, parm); + if (spec->codec_type == VT1802) { + /* PW4 (28h), MW4 (18h), MUX4(38h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x38, 0, + AC_VERB_SET_POWER_STATE, parm); + } else { + /* PW4 (26h), MW4 (1ch), MUX4(37h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x26, &parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x37, 0, + AC_VERB_SET_POWER_STATE, parm); + } - /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x25, &parm); - snd_hda_codec_write(codec, 0x19, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x35, 0, - AC_VERB_SET_POWER_STATE, parm); + if (spec->codec_type == VT1802) { + /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); + } else { + /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x19, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); + } if (spec->hp_independent_mode) snd_hda_codec_write(codec, 0x9, 0, @@ -5534,22 +5631,35 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) parm = AC_PWRST_D3; set_pin_power_state(codec, 0x24, &parm); parm = present ? AC_PWRST_D3 : AC_PWRST_D0; - snd_hda_codec_write(codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, parm); + if (spec->codec_type == VT1802) + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, parm); + else + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); /* Mono Out */ present = snd_hda_jack_detect(codec, 0x26); parm = present ? AC_PWRST_D3 : AC_PWRST_D0; - /* PW15 (31h), MW8(17h), MUX8(3bh) */ - snd_hda_codec_write(codec, 0x31, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x17, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x3b, 0, - AC_VERB_SET_POWER_STATE, parm); - + if (spec->codec_type == VT1802) { + /* PW15 (33h), MW8(1ch), MUX8(3ch) */ + snd_hda_codec_write(codec, 0x33, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, parm); + } else { + /* PW15 (31h), MW8(17h), MUX8(3bh) */ + snd_hda_codec_write(codec, 0x31, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x17, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3b, 0, + AC_VERB_SET_POWER_STATE, parm); + } /* MW9 (21h) */ if (imux_is_smixer || !is_aa_path_mute(codec)) snd_hda_codec_write(codec, 0x21, 0, @@ -5580,14 +5690,31 @@ static int patch_vt2002P(struct hda_codec *codec) "from BIOS. Using genenic mode...\n"); } - spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs; - spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs; + if (spec->codec_type == VT1802) + spec->init_verbs[spec->num_iverbs++] = + vt1802_volume_init_verbs; + else + spec->init_verbs[spec->num_iverbs++] = + vt2002P_volume_init_verbs; - spec->stream_name_analog = "VT2002P Analog"; + if (spec->codec_type == VT1802) + spec->init_verbs[spec->num_iverbs++] = + vt1802_uniwill_init_verbs; + else + spec->init_verbs[spec->num_iverbs++] = + vt2002P_uniwill_init_verbs; + + if (spec->codec_type == VT1802) + spec->stream_name_analog = "VT1802 Analog"; + else + spec->stream_name_analog = "VT2002P Analog"; spec->stream_analog_playback = &vt2002P_pcm_analog_playback; spec->stream_analog_capture = &vt2002P_pcm_analog_capture; - spec->stream_name_digital = "VT2002P Digital"; + if (spec->codec_type == VT1802) + spec->stream_name_digital = "VT1802 Digital"; + else + spec->stream_name_digital = "VT2002P Digital"; spec->stream_digital_playback = &vt2002P_pcm_digital_playback; if (!spec->adc_nids && spec->input_mux) { @@ -6118,6 +6245,10 @@ static struct hda_codec_preset snd_hda_preset_via[] = { { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, { .id = 0x11060440, .name = "VT1818S", .patch = patch_vt1708S}, + { .id = 0x11060446, .name = "VT1802", + .patch = patch_vt2002P}, + { .id = 0x11068446, .name = "VT1802", + .patch = patch_vt2002P}, {} /* terminator */ }; -- GitLab From eb0536c5e2815e3e38ed2b2f31401e114faec016 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Mon, 21 Mar 2011 13:28:26 +0000 Subject: [PATCH 0052/5560] viafb: allow some pll calculations This patch allows calculating the pll multiplier within limits based on the previous table. All available information supports that it should be possible/sane to choose the multiplier free within some ranges. Storing the multiplier ranges instead of lots of pll configurations reduces the memory needed and may as well improve the performance. It is also expected to provide better pll values resulting in better frequencies for the connected devices. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 377 +++++++++++------------------------------ drivers/video/via/hw.h | 11 +- 2 files changed, 106 insertions(+), 282 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index dc4c778877ce..063ff65fbea6 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -22,272 +22,80 @@ #include #include "global.h" -static struct pll_config cle266_pll_config[] = { - {19, 4, 0}, - {26, 5, 0}, - {28, 5, 0}, - {31, 5, 0}, - {33, 5, 0}, - {55, 5, 0}, - {102, 5, 0}, - {53, 6, 0}, - {92, 6, 0}, - {98, 6, 0}, - {112, 6, 0}, - {41, 7, 0}, - {60, 7, 0}, - {99, 7, 0}, - {100, 7, 0}, - {83, 8, 0}, - {86, 8, 0}, - {108, 8, 0}, - {87, 9, 0}, - {118, 9, 0}, - {95, 12, 0}, - {115, 12, 0}, - {108, 13, 0}, - {83, 17, 0}, - {67, 20, 0}, - {86, 20, 0}, - {98, 20, 0}, - {121, 24, 0}, - {99, 29, 0}, - {33, 3, 1}, - {15, 4, 1}, - {23, 4, 1}, - {37, 5, 1}, - {83, 5, 1}, - {85, 5, 1}, - {94, 5, 1}, - {103, 5, 1}, - {109, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {82, 6, 1}, - {31, 7, 1}, - {55, 7, 1}, - {84, 7, 1}, - {83, 8, 1}, - {76, 9, 1}, - {127, 9, 1}, - {33, 4, 2}, - {75, 4, 2}, - {119, 4, 2}, - {121, 4, 2}, - {91, 5, 2}, - {118, 5, 2}, - {83, 6, 2}, - {109, 6, 2}, - {90, 7, 2}, - {93, 2, 3}, - {53, 3, 3}, - {73, 4, 3}, - {89, 4, 3}, - {105, 4, 3}, - {117, 4, 3}, - {101, 5, 3}, - {121, 5, 3}, - {127, 5, 3}, - {99, 7, 3} +static struct pll_limit cle266_pll_limits[] = { + {19, 19, 4, 0}, + {26, 102, 5, 0}, + {53, 112, 6, 0}, + {41, 100, 7, 0}, + {83, 108, 8, 0}, + {87, 118, 9, 0}, + {95, 115, 12, 0}, + {108, 108, 13, 0}, + {83, 83, 17, 0}, + {67, 98, 20, 0}, + {121, 121, 24, 0}, + {99, 99, 29, 0}, + {33, 33, 3, 1}, + {15, 23, 4, 1}, + {37, 121, 5, 1}, + {82, 82, 6, 1}, + {31, 84, 7, 1}, + {83, 83, 8, 1}, + {76, 127, 9, 1}, + {33, 121, 4, 2}, + {91, 118, 5, 2}, + {83, 109, 6, 2}, + {90, 90, 7, 2}, + {93, 93, 2, 3}, + {53, 53, 3, 3}, + {73, 117, 4, 3}, + {101, 127, 5, 3}, + {99, 99, 7, 3} }; -static struct pll_config k800_pll_config[] = { - {22, 2, 0}, - {28, 3, 0}, - {81, 3, 1}, - {85, 3, 1}, - {98, 3, 1}, - {112, 3, 1}, - {86, 4, 1}, - {166, 4, 1}, - {109, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {131, 5, 1}, - {143, 5, 1}, - {153, 5, 1}, - {66, 3, 2}, - {68, 3, 2}, - {95, 3, 2}, - {106, 3, 2}, - {116, 3, 2}, - {93, 4, 2}, - {119, 4, 2}, - {121, 4, 2}, - {133, 4, 2}, - {137, 4, 2}, - {117, 5, 2}, - {118, 5, 2}, - {120, 5, 2}, - {124, 5, 2}, - {132, 5, 2}, - {137, 5, 2}, - {141, 5, 2}, - {166, 5, 2}, - {170, 5, 2}, - {191, 5, 2}, - {206, 5, 2}, - {208, 5, 2}, - {30, 2, 3}, - {69, 3, 3}, - {82, 3, 3}, - {83, 3, 3}, - {109, 3, 3}, - {114, 3, 3}, - {125, 3, 3}, - {89, 4, 3}, - {103, 4, 3}, - {117, 4, 3}, - {126, 4, 3}, - {150, 4, 3}, - {161, 4, 3}, - {121, 5, 3}, - {127, 5, 3}, - {131, 5, 3}, - {134, 5, 3}, - {148, 5, 3}, - {169, 5, 3}, - {172, 5, 3}, - {182, 5, 3}, - {195, 5, 3}, - {196, 5, 3}, - {208, 5, 3}, - {66, 2, 4}, - {85, 3, 4}, - {141, 4, 4}, - {146, 4, 4}, - {161, 4, 4}, - {177, 5, 4} +static struct pll_limit k800_pll_limits[] = { + {22, 22, 2, 0}, + {28, 28, 3, 0}, + {81, 112, 3, 1}, + {86, 166, 4, 1}, + {109, 153, 5, 1}, + {66, 116, 3, 2}, + {93, 137, 4, 2}, + {117, 208, 5, 2}, + {30, 30, 2, 3}, + {69, 125, 3, 3}, + {89, 161, 4, 3}, + {121, 208, 5, 3}, + {66, 66, 2, 4}, + {85, 85, 3, 4}, + {141, 161, 4, 4}, + {177, 177, 5, 4} }; -static struct pll_config cx700_pll_config[] = { - {98, 3, 1}, - {86, 4, 1}, - {109, 5, 1}, - {110, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {131, 5, 1}, - {135, 5, 1}, - {142, 5, 1}, - {143, 5, 1}, - {153, 5, 1}, - {187, 5, 1}, - {208, 5, 1}, - {68, 2, 2}, - {95, 3, 2}, - {116, 3, 2}, - {93, 4, 2}, - {119, 4, 2}, - {133, 4, 2}, - {137, 4, 2}, - {151, 4, 2}, - {166, 4, 2}, - {110, 5, 2}, - {112, 5, 2}, - {117, 5, 2}, - {118, 5, 2}, - {120, 5, 2}, - {132, 5, 2}, - {137, 5, 2}, - {141, 5, 2}, - {151, 5, 2}, - {166, 5, 2}, - {175, 5, 2}, - {191, 5, 2}, - {206, 5, 2}, - {174, 7, 2}, - {82, 3, 3}, - {109, 3, 3}, - {117, 4, 3}, - {150, 4, 3}, - {161, 4, 3}, - {112, 5, 3}, - {115, 5, 3}, - {121, 5, 3}, - {127, 5, 3}, - {129, 5, 3}, - {131, 5, 3}, - {134, 5, 3}, - {138, 5, 3}, - {148, 5, 3}, - {157, 5, 3}, - {169, 5, 3}, - {172, 5, 3}, - {190, 5, 3}, - {195, 5, 3}, - {196, 5, 3}, - {208, 5, 3}, - {141, 5, 4}, - {150, 5, 4}, - {166, 5, 4}, - {176, 5, 4}, - {177, 5, 4}, - {183, 5, 4}, - {202, 5, 4} +static struct pll_limit cx700_pll_limits[] = { + {98, 98, 3, 1}, + {86, 86, 4, 1}, + {109, 208, 5, 1}, + {68, 68, 2, 2}, + {95, 116, 3, 2}, + {93, 166, 4, 2}, + {110, 206, 5, 2}, + {174, 174, 7, 2}, + {82, 109, 3, 3}, + {117, 161, 4, 3}, + {112, 208, 5, 3}, + {141, 202, 5, 4} }; -static struct pll_config vx855_pll_config[] = { - {86, 4, 1}, - {108, 5, 1}, - {110, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {131, 5, 1}, - {135, 5, 1}, - {142, 5, 1}, - {143, 5, 1}, - {153, 5, 1}, - {164, 5, 1}, - {187, 5, 1}, - {208, 5, 1}, - {110, 5, 2}, - {112, 5, 2}, - {117, 5, 2}, - {118, 5, 2}, - {124, 5, 2}, - {132, 5, 2}, - {137, 5, 2}, - {141, 5, 2}, - {149, 5, 2}, - {151, 5, 2}, - {159, 5, 2}, - {166, 5, 2}, - {167, 5, 2}, - {172, 5, 2}, - {189, 5, 2}, - {191, 5, 2}, - {194, 5, 2}, - {206, 5, 2}, - {208, 5, 2}, - {83, 3, 3}, - {88, 3, 3}, - {109, 3, 3}, - {112, 3, 3}, - {103, 4, 3}, - {105, 4, 3}, - {161, 4, 3}, - {112, 5, 3}, - {115, 5, 3}, - {121, 5, 3}, - {127, 5, 3}, - {134, 5, 3}, - {137, 5, 3}, - {148, 5, 3}, - {157, 5, 3}, - {169, 5, 3}, - {172, 5, 3}, - {182, 5, 3}, - {191, 5, 3}, - {195, 5, 3}, - {209, 5, 3}, - {142, 4, 4}, - {146, 4, 4}, - {161, 4, 4}, - {141, 5, 4}, - {150, 5, 4}, - {165, 5, 4}, - {176, 5, 4} +static struct pll_limit vx855_pll_limits[] = { + {86, 86, 4, 1}, + {108, 208, 5, 1}, + {110, 208, 5, 2}, + {83, 112, 3, 3}, + {103, 161, 4, 3}, + {112, 209, 5, 3}, + {142, 161, 4, 4}, + {141, 176, 5, 4} }; /* according to VIA Technologies these values are based on experiment */ @@ -1633,17 +1441,34 @@ static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; } -static struct pll_config get_pll_config(struct pll_config *config, int size, +static struct pll_config get_pll_config(struct pll_limit *limits, int size, int clk) { - struct pll_config best = config[0]; + struct pll_config cur, up, down, best = {0, 1, 0}; const u32 f0 = 14318180; /* X1 frequency */ - int i; - - for (i = 1; i < size; i++) { - if (abs(get_pll_output_frequency(f0, config[i]) - clk) - < abs(get_pll_output_frequency(f0, best) - clk)) - best = config[i]; + int i, f; + + for (i = 0; i < size; i++) { + cur.rshift = limits[i].rshift; + cur.divisor = limits[i].divisor; + cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); + f = abs(get_pll_output_frequency(f0, cur) - clk); + up = down = cur; + up.multiplier++; + down.multiplier--; + if (abs(get_pll_output_frequency(f0, up) - clk) < f) + cur = up; + else if (abs(get_pll_output_frequency(f0, down) - clk) < f) + cur = down; + + if (cur.multiplier < limits[i].multiplier_min) + cur.multiplier = limits[i].multiplier_min; + else if (cur.multiplier > limits[i].multiplier_max) + cur.multiplier = limits[i].multiplier_max; + + f = abs(get_pll_output_frequency(f0, cur) - clk); + if (f < abs(get_pll_output_frequency(f0, best) - clk)) + best = cur; } return best; @@ -1656,14 +1481,14 @@ u32 viafb_get_clk_value(int clk) switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - value = cle266_encode_pll(get_pll_config(cle266_pll_config, - ARRAY_SIZE(cle266_pll_config), clk)); + value = cle266_encode_pll(get_pll_config(cle266_pll_limits, + ARRAY_SIZE(cle266_pll_limits), clk)); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: - value = k800_encode_pll(get_pll_config(k800_pll_config, - ARRAY_SIZE(k800_pll_config), clk)); + value = k800_encode_pll(get_pll_config(k800_pll_limits, + ARRAY_SIZE(k800_pll_limits), clk)); break; case UNICHROME_CX700: case UNICHROME_CN750: @@ -1671,13 +1496,13 @@ u32 viafb_get_clk_value(int clk) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: - value = k800_encode_pll(get_pll_config(cx700_pll_config, - ARRAY_SIZE(cx700_pll_config), clk)); + value = k800_encode_pll(get_pll_config(cx700_pll_limits, + ARRAY_SIZE(cx700_pll_limits), clk)); break; case UNICHROME_VX855: case UNICHROME_VX900: - value = vx855_encode_pll(get_pll_config(vx855_pll_config, - ARRAY_SIZE(vx855_pll_config), clk)); + value = vx855_encode_pll(get_pll_config(vx855_pll_limits, + ARRAY_SIZE(vx855_pll_limits), clk)); break; } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 8858593405aa..63d8d37e157c 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -738,12 +738,11 @@ struct pll_config { u8 rshift; }; -struct pll_map { - u32 clk; - struct pll_config cle266_pll; - struct pll_config k800_pll; - struct pll_config cx700_pll; - struct pll_config vx855_pll; +struct pll_limit { + u16 multiplier_min; + u16 multiplier_max; + u8 divisor; + u8 rshift; }; struct rgbLUT { -- GitLab From c91faa61697a60ee5cc653db9b6fd3c7049890a6 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Tue, 22 Mar 2011 20:33:20 +0000 Subject: [PATCH 0053/5560] viafb: remove unused max_hres/vres This patch removes the max_hres and max_vres which are not used at the moment. In general they could be useful but it would be better to get them via any standard EDID implementation and not the buggy incomplete one currently used which is also removed as far as possible. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/chip.h | 2 - drivers/video/via/dvi.c | 138 +-------------------------------------- 2 files changed, 3 insertions(+), 137 deletions(-) diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index 1aa0fb3c343e..3ebf20c06eef 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -142,8 +142,6 @@ struct tmds_setting_information { int h_active; int v_active; int max_pixel_clock; - int max_hres; - int max_vres; }; struct lvds_setting_information { diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 41ca198b5098..3dbcd7743f14 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -28,9 +28,6 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); static void __devinit dvi_get_panel_size_from_DDCv1( struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting); -static void __devinit dvi_get_panel_size_from_DDCv2( - struct tmds_chip_information *tmds_chip, - struct tmds_setting_information *tmds_setting); static int viafb_dvi_query_EDID(void); static int check_tmds_chip(int device_id_subaddr, int device_id) @@ -47,17 +44,8 @@ void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); viafb_dvi_sense(); - switch (viafb_dvi_query_EDID()) { - case 1: + if (viafb_dvi_query_EDID() == 1) dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); - break; - case 2: - dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting); - break; - default: - printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n"); - break; - } return; } @@ -306,12 +294,7 @@ static int viafb_dvi_query_EDID(void) return EDID_VERSION_1; /* Found EDID1 Table */ } - data0 = (u8) tmds_register_read(0x00); - viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; - if (data0 == 0x20) - return EDID_VERSION_2; /* Found EDID2 Table */ - else - return false; + return false; } /* Get Panel Size Using EDID1 Table */ @@ -319,50 +302,15 @@ static void __devinit dvi_get_panel_size_from_DDCv1( struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting) { - int i, max_h = 0, tmp, restore; - unsigned char rData; + int i, restore; unsigned char EDID_DATA[18]; DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); restore = tmds_chip->tmds_chip_slave_addr; tmds_chip->tmds_chip_slave_addr = 0xA0; - - rData = tmds_register_read(0x23); - if (rData & 0x3C) - max_h = 640; - if (rData & 0xC0) - max_h = 720; - if (rData & 0x03) - max_h = 800; - - rData = tmds_register_read(0x24); - if (rData & 0xC0) - max_h = 800; - if (rData & 0x1E) - max_h = 1024; - if (rData & 0x01) - max_h = 1280; - for (i = 0x25; i < 0x6D; i++) { switch (i) { - case 0x26: - case 0x28: - case 0x2A: - case 0x2C: - case 0x2E: - case 0x30: - case 0x32: - case 0x34: - rData = tmds_register_read(i); - if (rData == 1) - break; - /* data = (data + 31) * 8 */ - tmp = (rData + 31) << 3; - if (tmp > max_h) - max_h = tmp; - break; - case 0x36: case 0x48: case 0x5A: @@ -383,91 +331,11 @@ static void __devinit dvi_get_panel_size_from_DDCv1( } } - tmds_setting->max_hres = max_h; - switch (max_h) { - case 640: - tmds_setting->max_vres = 480; - break; - case 800: - tmds_setting->max_vres = 600; - break; - case 1024: - tmds_setting->max_vres = 768; - break; - case 1280: - tmds_setting->max_vres = 1024; - break; - case 1400: - tmds_setting->max_vres = 1050; - break; - case 1440: - tmds_setting->max_vres = 1050; - break; - case 1600: - tmds_setting->max_vres = 1200; - break; - case 1920: - tmds_setting->max_vres = 1080; - break; - default: - DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! " - "set default panel size.\n", max_h); - break; - } - DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", tmds_setting->max_pixel_clock); tmds_chip->tmds_chip_slave_addr = restore; } -/* Get Panel Size Using EDID2 Table */ -static void __devinit dvi_get_panel_size_from_DDCv2( - struct tmds_chip_information *tmds_chip, - struct tmds_setting_information *tmds_setting) -{ - int restore; - unsigned char R_Buffer[2]; - - DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); - - restore = tmds_chip->tmds_chip_slave_addr; - tmds_chip->tmds_chip_slave_addr = 0xA2; - - /* Horizontal: 0x76, 0x77 */ - tmds_register_read_bytes(0x76, R_Buffer, 2); - tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8); - - switch (tmds_setting->max_hres) { - case 640: - tmds_setting->max_vres = 480; - break; - case 800: - tmds_setting->max_vres = 600; - break; - case 1024: - tmds_setting->max_vres = 768; - break; - case 1280: - tmds_setting->max_vres = 1024; - break; - case 1400: - tmds_setting->max_vres = 1050; - break; - case 1440: - tmds_setting->max_vres = 1050; - break; - case 1600: - tmds_setting->max_vres = 1200; - break; - default: - DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! " - "set default panel size.\n", tmds_setting->max_hres); - break; - } - - tmds_chip->tmds_chip_slave_addr = restore; -} - /* If Disable DVI, turn off pad */ void viafb_dvi_disable(void) { -- GitLab From 1606f87e98f83512762da6dbc992103ae690ff11 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 23 Mar 2011 13:49:32 +0000 Subject: [PATCH 0054/5560] viafb: call viafb_get_clk_value only in viafb_set_vclock As no caller is interested in the result call viafb_get_clk_value directly from viafb_set_vclock to encapsulate the hardware dependend stuff there. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 32 +++++++++++++++++--------------- drivers/video/via/hw.h | 1 - drivers/video/via/lcd.c | 7 ++----- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 063ff65fbea6..c28ae2e85ef6 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1474,7 +1474,7 @@ static struct pll_config get_pll_config(struct pll_limit *limits, int size, return best; } -u32 viafb_get_clk_value(int clk) +static u32 viafb_get_clk_value(int clk) { u32 value = 0; @@ -1512,6 +1512,10 @@ u32 viafb_get_clk_value(int clk) /* Set VCLK*/ void viafb_set_vclock(u32 clk, int set_iga) { + u32 value = viafb_get_clk_value(clk); + + DEBUG_MSG(KERN_INFO "PLL=0x%x", value); + /* H.W. Reset : ON */ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); @@ -1520,8 +1524,8 @@ void viafb_set_vclock(u32 clk, int set_iga) switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - via_write_reg(VIASR, SR46, (clk & 0x00FF)); - via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); + via_write_reg(VIASR, SR46, (value & 0x00FF)); + via_write_reg(VIASR, SR47, (value & 0xFF00) >> 8); break; case UNICHROME_K800: @@ -1535,9 +1539,9 @@ void viafb_set_vclock(u32 clk, int set_iga) case UNICHROME_VX800: case UNICHROME_VX855: case UNICHROME_VX900: - via_write_reg(VIASR, SR44, (clk & 0x0000FF)); - via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); - via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); + via_write_reg(VIASR, SR44, (value & 0x0000FF)); + via_write_reg(VIASR, SR45, (value & 0x00FF00) >> 8); + via_write_reg(VIASR, SR46, (value & 0xFF0000) >> 16); break; } } @@ -1547,8 +1551,8 @@ void viafb_set_vclock(u32 clk, int set_iga) switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - via_write_reg(VIASR, SR44, (clk & 0x00FF)); - via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); + via_write_reg(VIASR, SR44, (value & 0x00FF)); + via_write_reg(VIASR, SR45, (value & 0xFF00) >> 8); break; case UNICHROME_K800: @@ -1562,9 +1566,9 @@ void viafb_set_vclock(u32 clk, int set_iga) case UNICHROME_VX800: case UNICHROME_VX855: case UNICHROME_VX900: - via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); - via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); - via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); + via_write_reg(VIASR, SR4A, (value & 0x0000FF)); + via_write_reg(VIASR, SR4B, (value & 0x00FF00) >> 8); + via_write_reg(VIASR, SR4C, (value & 0xFF0000) >> 16); break; } } @@ -1827,7 +1831,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, int i; int index = 0; int h_addr, v_addr; - u32 pll_D_N, clock, refresh = viafb_refresh; + u32 clock, refresh = viafb_refresh; if (viafb_SAMM_ON && set_iga == IGA2) refresh = viafb_refresh1; @@ -1884,9 +1888,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, clock = crt_reg.hor_total * crt_reg.ver_total * crt_table[index].refresh_rate; - pll_D_N = viafb_get_clk_value(clock); - DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); - viafb_set_vclock(pll_D_N, set_iga); + viafb_set_vclock(clock, set_iga); } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 63d8d37e157c..2cdce9b7eb8e 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -935,7 +935,6 @@ void viafb_lock_crt(void); void viafb_unlock_crt(void); void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); void viafb_write_regx(struct io_reg RegTable[], int ItemNum); -u32 viafb_get_clk_value(int clk); void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting); diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 64bc7e763103..284e681cc22c 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -562,7 +562,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, int set_vres = plvds_setting_info->v_active; int panel_hres = plvds_setting_info->lcd_panel_hres; int panel_vres = plvds_setting_info->lcd_panel_vres; - u32 pll_D_N, clock; + u32 clock; struct display_timing mode_crt_reg, panel_crt_reg; struct crt_mode_table *panel_crt_table = NULL; struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, @@ -613,10 +613,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, viafb_load_FIFO_reg(set_iga, set_hres, set_vres); fill_lcd_format(); - - pll_D_N = viafb_get_clk_value(clock); - DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); - viafb_set_vclock(pll_D_N, set_iga); + viafb_set_vclock(clock, set_iga); lcd_patch_skew(plvds_setting_info, plvds_chip_info); /* If K8M800, enable LCD Prefetch Mode. */ -- GitLab From 0f77d4a052aec7392dbfd3d8942a519d013d66d9 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 23 Mar 2011 17:14:26 +0000 Subject: [PATCH 0055/5560] viafb: prepare for PLL separation This patch splits some functionality to extra functions. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 127 +++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 43 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index c28ae2e85ef6..bd28e13f83d4 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1430,6 +1430,70 @@ static u32 vx855_encode_pll(struct pll_config pll) | pll.multiplier; } +static inline void cle266_set_primary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ + via_write_reg(VIASR, 0x46, data & 0xFF); + via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void k800_set_primary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ + via_write_reg(VIASR, 0x44, data & 0xFF); + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void cle266_set_secondary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ + via_write_reg(VIASR, 0x44, data & 0xFF); + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static inline void k800_set_secondary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ + via_write_reg(VIASR, 0x4A, data & 0xFF); + via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static void cle266_set_primary_pll(struct pll_config config) +{ + cle266_set_primary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_primary_pll(struct pll_config config) +{ + k800_set_primary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_primary_pll(struct pll_config config) +{ + k800_set_primary_pll_encoded(vx855_encode_pll(config)); +} + +static void cle266_set_secondary_pll(struct pll_config config) +{ + cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_secondary_pll(struct pll_config config) +{ + k800_set_secondary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_secondary_pll(struct pll_config config) +{ + k800_set_secondary_pll_encoded(vx855_encode_pll(config)); +} + static inline u32 get_pll_internal_frequency(u32 ref_freq, struct pll_config pll) { @@ -1474,21 +1538,21 @@ static struct pll_config get_pll_config(struct pll_limit *limits, int size, return best; } -static u32 viafb_get_clk_value(int clk) +static struct pll_config get_best_pll_config(int clk) { - u32 value = 0; + struct pll_config config; switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - value = cle266_encode_pll(get_pll_config(cle266_pll_limits, - ARRAY_SIZE(cle266_pll_limits), clk)); + config = get_pll_config(cle266_pll_limits, + ARRAY_SIZE(cle266_pll_limits), clk); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: - value = k800_encode_pll(get_pll_config(k800_pll_limits, - ARRAY_SIZE(k800_pll_limits), clk)); + config = get_pll_config(k800_pll_limits, + ARRAY_SIZE(k800_pll_limits), clk); break; case UNICHROME_CX700: case UNICHROME_CN750: @@ -1496,38 +1560,31 @@ static u32 viafb_get_clk_value(int clk) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: - value = k800_encode_pll(get_pll_config(cx700_pll_limits, - ARRAY_SIZE(cx700_pll_limits), clk)); + config = get_pll_config(cx700_pll_limits, + ARRAY_SIZE(cx700_pll_limits), clk); break; case UNICHROME_VX855: case UNICHROME_VX900: - value = vx855_encode_pll(get_pll_config(vx855_pll_limits, - ARRAY_SIZE(vx855_pll_limits), clk)); + config = get_pll_config(vx855_pll_limits, + ARRAY_SIZE(vx855_pll_limits), clk); break; } - return value; + return config; } /* Set VCLK*/ void viafb_set_vclock(u32 clk, int set_iga) { - u32 value = viafb_get_clk_value(clk); - - DEBUG_MSG(KERN_INFO "PLL=0x%x", value); - - /* H.W. Reset : ON */ - viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); + struct pll_config config = get_best_pll_config(clk); if (set_iga == IGA1) { /* Change D,N FOR VCLK */ switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - via_write_reg(VIASR, SR46, (value & 0x00FF)); - via_write_reg(VIASR, SR47, (value & 0xFF00) >> 8); + cle266_set_primary_pll(config); break; - case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: @@ -1537,11 +1594,11 @@ void viafb_set_vclock(u32 clk, int set_iga) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: + k800_set_primary_pll(config); + break; case UNICHROME_VX855: case UNICHROME_VX900: - via_write_reg(VIASR, SR44, (value & 0x0000FF)); - via_write_reg(VIASR, SR45, (value & 0x00FF00) >> 8); - via_write_reg(VIASR, SR46, (value & 0xFF0000) >> 16); + vx855_set_primary_pll(config); break; } } @@ -1551,10 +1608,8 @@ void viafb_set_vclock(u32 clk, int set_iga) switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - via_write_reg(VIASR, SR44, (value & 0x00FF)); - via_write_reg(VIASR, SR45, (value & 0xFF00) >> 8); + cle266_set_secondary_pll(config); break; - case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: @@ -1564,29 +1619,15 @@ void viafb_set_vclock(u32 clk, int set_iga) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: + k800_set_secondary_pll(config); + break; case UNICHROME_VX855: case UNICHROME_VX900: - via_write_reg(VIASR, SR4A, (value & 0x0000FF)); - via_write_reg(VIASR, SR4B, (value & 0x00FF00) >> 8); - via_write_reg(VIASR, SR4C, (value & 0xFF0000) >> 16); + vx855_set_secondary_pll(config); break; } } - /* H.W. Reset : OFF */ - viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); - - /* Reset PLL */ - if (set_iga == IGA1) { - viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); - } - - if (set_iga == IGA2) { - viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); - } - /* Fire! */ via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ } -- GitLab From 6c1093af5833d4c69634711d9453287ab9e0cb77 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 23 Mar 2011 21:04:01 +0000 Subject: [PATCH 0056/5560] viafb: add clock source selection and PLL power management support This patch adds some support for clock source selection as well as PLL power management. The code is unused at the moment but was successfully tested as far as possible. The implementation is according to the documentation for VX700, VX800, VX855, VX900. Probably the source selection works like this starting with K800 and the power managemennt at least since VX700. (guessed based on the initialization in viamode.c) Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index bd28e13f83d4..b38d3b40de95 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1409,6 +1409,42 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) } +static void set_primary_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x30); +} + +static void set_secondary_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x08; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x08); +} + static u32 cle266_encode_pll(struct pll_config pll) { return (pll.multiplier << 8) @@ -1494,6 +1530,58 @@ static void vx855_set_secondary_pll(struct pll_config config) k800_set_secondary_pll_encoded(vx855_encode_pll(config)); } +enum via_clksrc { + VIA_CLKSRC_X1 = 0, + VIA_CLKSRC_TVX1, + VIA_CLKSRC_TVPLL, + VIA_CLKSRC_DVP1TVCLKR, + VIA_CLKSRC_CAP0, + VIA_CLKSRC_CAP1, +}; + +static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) +{ + u8 data = 0; + + switch (source) { + case VIA_CLKSRC_X1: + data = 0x00; + break; + case VIA_CLKSRC_TVX1: + data = 0x02; + break; + case VIA_CLKSRC_TVPLL: + data = 0x04; /* 0x06 should be the same */ + break; + case VIA_CLKSRC_DVP1TVCLKR: + data = 0x0A; + break; + case VIA_CLKSRC_CAP0: + data = 0xC; + break; + case VIA_CLKSRC_CAP1: + data = 0x0E; + break; + } + + if (!use_pll) + data |= 1; + + return data; +} + +static void set_primary_clock_source(enum via_clksrc source, bool use_pll) +{ + u8 data = set_clock_source_common(source, use_pll) << 4; + via_write_reg_mask(VIACR, 0x6C, data, 0xF0); +} + +static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) +{ + u8 data = set_clock_source_common(source, use_pll); + via_write_reg_mask(VIACR, 0x6C, data, 0x0F); +} + static inline u32 get_pll_internal_frequency(u32 ref_freq, struct pll_config pll) { -- GitLab From c5593d26aea3aba2a7703a0b5d74b4ea8b726889 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Thu, 24 Mar 2011 02:03:42 +0000 Subject: [PATCH 0057/5560] viafb: add primary/secondary clock on/off switches This patch adds functions to enable/disable the display clocks. It also fixes a tiny bug that slipped in with a previous commit but could not yet have caused any problems. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index b38d3b40de95..712348df0f84 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1409,6 +1409,42 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) } +static void set_primary_clock_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1B, value, 0x30); +} + +static void set_secondary_clock_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x80; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1B, value, 0xC0); +} + static void set_primary_pll_state(u8 state) { u8 value; @@ -1442,7 +1478,7 @@ static void set_secondary_pll_state(u8 state) return; } - via_write_reg_mask(VIASR, 0x2D, value, 0x08); + via_write_reg_mask(VIASR, 0x2D, value, 0x0C); } static u32 cle266_encode_pll(struct pll_config pll) -- GitLab From e87885fea58ef49e08f2b4218587397586dc155d Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Thu, 24 Mar 2011 12:39:05 +0800 Subject: [PATCH 0058/5560] ALSA: hda - VIA: Fix side channel mute invalid issue Modify side_mute_channel() and update_side_mute_status() functions to fix invalid side channel mute issue of VT2002P, VT1812 and VT1802 codecs. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 74e2a2482815..c90b23b5cf7c 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -708,6 +708,9 @@ static hda_nid_t side_mute_channel(struct via_spec *spec) case VT1709_10CH: return 0x29; case VT1708B_8CH: /* fall thru */ case VT1708S: return 0x27; + case VT2002P: return 0x19; + case VT1802: return 0x15; + case VT1812: return 0x15; default: return 0; } } @@ -716,13 +719,22 @@ static int update_side_mute_status(struct hda_codec *codec) { /* mute side channel */ struct via_spec *spec = codec->spec; - unsigned int parm = spec->hp_independent_mode - ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; + unsigned int parm; hda_nid_t sw3 = side_mute_channel(spec); - if (sw3) - snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, - parm); + if (sw3) { + if (VT2002P_COMPATIBLE(spec)) + parm = spec->hp_independent_mode ? + AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); + else + parm = spec->hp_independent_mode ? + AMP_OUT_MUTE : AMP_OUT_UNMUTE; + snd_hda_codec_write(codec, sw3, 0, + AC_VERB_SET_AMP_GAIN_MUTE, parm); + if (spec->codec_type == VT1812) + snd_hda_codec_write(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, parm); + } return 0; } -- GitLab From 27439ce717fea649ed77d256bb6efee7d1eb8e56 Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Thu, 24 Mar 2011 12:40:10 +0800 Subject: [PATCH 0059/5560] ALSA: hda - VIA: Add VT1802 check in via_speaker_automute function Add VT1802 check in via_speaker_automute() function. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index c90b23b5cf7c..ec6f32929ced 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1685,7 +1685,7 @@ static void via_speaker_automute(struct hda_codec *codec) unsigned int hp_present; struct via_spec *spec = codec->spec; - if (spec->codec_type != VT2002P && spec->codec_type != VT1812) + if (!VT2002P_COMPATIBLE(spec)) return; hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); -- GitLab From aa266fccf569c6ed675f15b1654a5b2c08d9dde5 Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Thu, 24 Mar 2011 12:41:01 +0800 Subject: [PATCH 0060/5560] ALSA: hda - VIA: Update VT1708 initial verbs Add a verb of power down jack detect in VT1708 initial verbs. This verb is used to avoid noise caused by hardware issue. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index ec6f32929ced..1d0afdbb52b6 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1200,6 +1200,8 @@ static struct hda_verb vt1708_volume_init_verbs[] = { {0x20, AC_VERB_SET_CONNECT_SEL, 0}, /* PW9 Output enable */ {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + /* power down jack detect function */ + {0x1, 0xf81, 0x1}, { } }; -- GitLab From 4ab2d53a99b6dcee86837d2a9739bfb9f468db45 Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Thu, 24 Mar 2011 12:42:03 +0800 Subject: [PATCH 0061/5560] ALSA: hda - VIA: Update VT1718S initial verbs Add a verb to enable control amplifier of stereo mixer in VT1718S initial verbs. Set stereo mixer default amplifier value as un-mute. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 1d0afdbb52b6..ac8e8c757f69 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -4255,7 +4255,8 @@ static struct hda_verb vt1718S_volume_init_verbs[] = { {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - + /* Enable MW0 adjust Gain 5 */ + {0x1, 0xfb2, 0x10}, /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget */ @@ -4264,7 +4265,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = { {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, /* Setup default input of Front HP to MW9 */ {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, -- GitLab From eadb9a804de223ef899ebb64aa037fa0da7bdee9 Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Thu, 24 Mar 2011 12:43:02 +0800 Subject: [PATCH 0062/5560] ALSA: hda - VIA: Update VT2002P initial verbs Add some hardware related verbs in VT2002P initial verbs. These verbs are used to fix Class-D speaker no sound issue. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index ac8e8c757f69..ae9fdaa955f0 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -5267,6 +5267,10 @@ static struct snd_kcontrol_new vt2002P_capture_mixer[] = { }; static struct hda_verb vt2002P_volume_init_verbs[] = { + /* Class-D speaker related verbs */ + {0x1, 0xfe0, 0x4}, + {0x1, 0xfe9, 0x80}, + {0x1, 0xfe2, 0x22}, /* * Unmute ADC0-1 and set the default input to mic-in */ -- GitLab From ec7e7e42da0b33c77f1baafeac93e5128c4eea7a Mon Sep 17 00:00:00 2001 From: Lydia Wang Date: Thu, 24 Mar 2011 12:43:44 +0800 Subject: [PATCH 0063/5560] ALSA: hda - VIA: Update unsolicited event function Update unsolicited event process function via_unsol_event() to make it can process more unsolicited events. Signed-off-by: Lydia Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index ae9fdaa955f0..15b57a101aa0 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -234,12 +234,12 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) return codec_type; }; +#define VIA_JACK_EVENT 0x20 #define VIA_HP_EVENT 0x01 #define VIA_GPIO_EVENT 0x02 -#define VIA_JACK_EVENT 0x04 -#define VIA_MONO_EVENT 0x08 -#define VIA_SPEAKER_EVENT 0x10 -#define VIA_BIND_HP_EVENT 0x20 +#define VIA_MONO_EVENT 0x03 +#define VIA_SPEAKER_EVENT 0x04 +#define VIA_BIND_HP_EVENT 0x05 enum { VIA_CTL_WIDGET_VOL, @@ -1746,17 +1746,21 @@ static void via_unsol_event(struct hda_codec *codec, unsigned int res) { res >>= 26; - if (res & VIA_HP_EVENT) - via_hp_automute(codec); - if (res & VIA_GPIO_EVENT) - via_gpio_control(codec); + if (res & VIA_JACK_EVENT) set_widgets_power_state(codec); - if (res & VIA_MONO_EVENT) + + res &= ~VIA_JACK_EVENT; + + if (res == VIA_HP_EVENT) + via_hp_automute(codec); + else if (res == VIA_GPIO_EVENT) + via_gpio_control(codec); + else if (res == VIA_MONO_EVENT) via_mono_automute(codec); - if (res & VIA_SPEAKER_EVENT) + else if (res == VIA_SPEAKER_EVENT) via_speaker_automute(codec); - if (res & VIA_BIND_HP_EVENT) + else if (res == VIA_BIND_HP_EVENT) via_hp_bind_automute(codec); } -- GitLab From f786bba4499cf3de20da345ce090457ebcef03b0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 22 Mar 2011 17:34:01 +0100 Subject: [PATCH 0064/5560] HID: hid-multitouch: migrate 3M PCT touch screens to hid-multitouch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges the hid-3m-pct driver into hid-multitouch. To keep devices working the same way they used to with hid-3m-pct, we need to add two signal/noise ratios for width and height. We also need to work on width/height to send proper ABS_MT_ORIENTATION flag. Importing 3M into hid-multitouch also solved the bug in which devices handling width and height in their report descriptors did not show ABS_MT_TOUCH_MAJOR and ABS_MT_TOUCH_MINOR. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-and-tested-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 7 +- drivers/hid/Makefile | 1 - drivers/hid/hid-3m-pct.c | 305 ----------------------------------- drivers/hid/hid-multitouch.c | 47 +++++- 4 files changed, 46 insertions(+), 314 deletions(-) delete mode 100644 drivers/hid/hid-3m-pct.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1edb0bd72a60..996ae3ac3244 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -55,12 +55,6 @@ source "drivers/hid/usbhid/Kconfig" menu "Special HID drivers" depends on HID -config HID_3M_PCT - tristate "3M PCT touchscreen" - depends on USB_HID - ---help--- - Support for 3M PCT touch screens. - config HID_A4TECH tristate "A4 tech mice" if EXPERT depends on USB_HID @@ -314,6 +308,7 @@ config HID_MULTITOUCH Generic support for HID multitouch panels. Say Y here if you have one of the following devices: + - 3M PCT touch screens - Cando dual touch panel - Cypress TrueTouch panels - Hanvon dual touch panels diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index f8b90e4e4841..11c9f0b127e1 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -25,7 +25,6 @@ ifdef CONFIG_LOGIWII_FF hid-logitech-y += hid-lg4ff.o endif -obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c deleted file mode 100644 index 5243ae2d3730..000000000000 --- a/drivers/hid/hid-3m-pct.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * HID driver for 3M PCT multitouch panels - * - * Copyright (c) 2009-2010 Stephane Chatty - * Copyright (c) 2010 Henrik Rydberg - * Copyright (c) 2010 Canonical, 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 the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("3M PCT multitouch panels"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -#define MAX_SLOTS 60 - -/* estimated signal-to-noise ratios */ -#define SN_MOVE 2048 -#define SN_WIDTH 128 - -struct mmm_finger { - __s32 x, y, w, h; - bool touch, valid; -}; - -struct mmm_data { - struct mmm_finger f[MAX_SLOTS]; - __u8 curid; - __u8 nexp, nreal; - bool touch, valid; -}; - -static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - int f1 = field->logical_minimum; - int f2 = field->logical_maximum; - int df = f2 - f1; - - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_BUTTON: - return -1; - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - input_set_abs_params(hi->input, ABS_MT_POSITION_X, - f1, f2, df / SN_MOVE, 0); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - f1, f2, df / SN_MOVE, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - input_set_abs_params(hi->input, ABS_MT_POSITION_Y, - f1, f2, df / SN_MOVE, 0); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - f1, f2, df / SN_MOVE, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - /* we do not want to map these: no input-oriented meaning */ - case 0x14: - case 0x23: - case HID_DG_INPUTMODE: - case HID_DG_DEVICEINDEX: - case HID_DG_CONTACTCOUNT: - case HID_DG_CONTACTMAX: - case HID_DG_INRANGE: - case HID_DG_CONFIDENCE: - return -1; - case HID_DG_TIPSWITCH: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - input_set_capability(hi->input, EV_KEY, BTN_TOUCH); - return 1; - case HID_DG_WIDTH: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MAJOR); - input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, - f1, f2, df / SN_WIDTH, 0); - return 1; - case HID_DG_HEIGHT: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MINOR); - input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, - f1, f2, df / SN_WIDTH, 0); - input_set_abs_params(hi->input, ABS_MT_ORIENTATION, - 0, 1, 0, 0); - return 1; - case HID_DG_CONTACTID: - input_mt_init_slots(hi->input, MAX_SLOTS); - return 1; - } - /* let hid-input decide for the others */ - return 0; - - case 0xff000000: - /* we do not want to map these: no input-oriented meaning */ - return -1; - } - - return 0; -} - -static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - /* tell hid-input to skip setup of these event types */ - if (usage->type == EV_KEY || usage->type == EV_ABS) - set_bit(usage->type, hi->input->evbit); - return -1; -} - -/* - * this function is called when a whole packet has been received and processed, - * so that it can decide what to send to the input layer. - */ -static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) -{ - int i; - for (i = 0; i < MAX_SLOTS; ++i) { - struct mmm_finger *f = &md->f[i]; - if (!f->valid) { - /* this finger is just placeholder data, ignore */ - continue; - } - input_mt_slot(input, i); - input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch); - if (f->touch) { - /* this finger is on the screen */ - int wide = (f->w > f->h); - /* divided by two to match visual scale of touch */ - int major = max(f->w, f->h) >> 1; - int minor = min(f->w, f->h) >> 1; - - input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); - input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); - } - f->valid = 0; - } - - input_mt_report_pointer_emulation(input, true); - input_sync(input); -} - -/* - * this function is called upon all reports - * so that we can accumulate contact point information, - * and call input_mt_sync after each point. - */ -static int mmm_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct mmm_data *md = hid_get_drvdata(hid); - /* - * strangely, this function can be called before - * field->hidinput is initialized! - */ - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - switch (usage->hid) { - case HID_DG_TIPSWITCH: - md->touch = value; - break; - case HID_DG_CONFIDENCE: - md->valid = value; - break; - case HID_DG_WIDTH: - if (md->valid) - md->f[md->curid].w = value; - break; - case HID_DG_HEIGHT: - if (md->valid) - md->f[md->curid].h = value; - break; - case HID_DG_CONTACTID: - value = clamp_val(value, 0, MAX_SLOTS - 1); - if (md->valid) { - md->curid = value; - md->f[value].touch = md->touch; - md->f[value].valid = 1; - md->nreal++; - } - break; - case HID_GD_X: - if (md->valid) - md->f[md->curid].x = value; - break; - case HID_GD_Y: - if (md->valid) - md->f[md->curid].y = value; - break; - case HID_DG_CONTACTCOUNT: - if (value) - md->nexp = value; - if (md->nreal >= md->nexp) { - mmm_filter_event(md, input); - md->nreal = 0; - } - break; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - struct mmm_data *md; - - hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; - - md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); - if (!md) { - hid_err(hdev, "cannot allocate 3M data\n"); - return -ENOMEM; - } - hid_set_drvdata(hdev, md); - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret) - kfree(md); - return ret; -} - -static void mmm_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id mmm_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, - { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, - { } -}; -MODULE_DEVICE_TABLE(hid, mmm_devices); - -static const struct hid_usage_id mmm_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver mmm_driver = { - .name = "3m-pct", - .id_table = mmm_devices, - .probe = mmm_probe, - .remove = mmm_remove, - .input_mapping = mmm_input_mapping, - .input_mapped = mmm_input_mapped, - .usage_table = mmm_grabbed_usages, - .event = mmm_event, -}; - -static int __init mmm_init(void) -{ - return hid_register_driver(&mmm_driver); -} - -static void __exit mmm_exit(void) -{ - hid_unregister_driver(&mmm_driver); -} - -module_init(mmm_init); -module_exit(mmm_exit); - diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index d31301e85c56..0175f8583095 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -11,6 +11,12 @@ * Copyright (c) 2010 Henrik Rydberg * Copyright (c) 2010 Canonical, Ltd. * + * This code is partly based on hid-3m-pct.c: + * + * Copyright (c) 2009-2010 Stephane Chatty + * Copyright (c) 2010 Henrik Rydberg + * Copyright (c) 2010 Canonical, Ltd. + * */ /* @@ -69,6 +75,8 @@ struct mt_class { __s32 name; /* MT_CLS */ __s32 quirks; __s32 sn_move; /* Signal/noise ratio for move events */ + __s32 sn_width; /* Signal/noise ratio for width events */ + __s32 sn_height; /* Signal/noise ratio for height events */ __s32 sn_pressure; /* Signal/noise ratio for pressure events */ __u8 maxcontacts; }; @@ -80,6 +88,7 @@ struct mt_class { #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 #define MT_CLS_STANTUM 6 +#define MT_CLS_3M 7 #define MT_DEFAULT_MAXCONTACT 10 @@ -141,6 +150,12 @@ struct mt_class mt_classes[] = { }, { .name = MT_CLS_STANTUM, .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { .name = MT_CLS_3M, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | + MT_QUIRK_SLOT_IS_CONTACTID, + .sn_move = 2048, + .sn_width = 128, + .sn_height = 128 }, { } }; @@ -230,11 +245,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MAJOR); + set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, + cls->sn_width); td->last_slot_field = usage->hid; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); + set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, + cls->sn_height); input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 0, 1, 0, 0); td->last_slot_field = usage->hid; @@ -332,11 +351,18 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) input_mt_report_slot_state(input, MT_TOOL_FINGER, s->touch_state); if (s->touch_state) { + /* this finger is on the screen */ + int wide = (s->w > s->h); + /* divided by two to match visual scale of touch */ + int major = max(s->w, s->h) >> 1; + int minor = min(s->w, s->h) >> 1; + input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); + input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); + input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); + input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); } s->seen_in_this_frame = false; @@ -398,6 +424,15 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, break; default: + if (td->last_field_index + && field->index == td->last_field_index) + /* we reach here when the last field in the + * report is not related to multitouch. + * This is not good. As a temporary solution, + * we trigger our mt event completion and + * ignore the field. + */ + break; /* fallback to the generic hidinput handling */ return 0; } @@ -513,6 +548,14 @@ static void mt_remove(struct hid_device *hdev) static const struct hid_device_id mt_devices[] = { + /* 3M panels */ + { .driver_data = MT_CLS_3M, + HID_USB_DEVICE(USB_VENDOR_ID_3M, + USB_DEVICE_ID_3M1968) }, + { .driver_data = MT_CLS_3M, + HID_USB_DEVICE(USB_VENDOR_ID_3M, + USB_DEVICE_ID_3M2256) }, + /* Cando panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, HID_USB_DEVICE(USB_VENDOR_ID_CANDO, -- GitLab From 2c536f84c19c73ab1e3411bf1596ff85c4a23783 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Thu, 24 Mar 2011 13:30:09 +0000 Subject: [PATCH 0065/5560] viafb: split clock and PLL code to an extra file This patch is a huge move operation with some rename and introduces an interface to still use the functions. This should be a step in the right direction to reuse the code whenever possible but cleanly separate code that differs on different platform and keeping the complexity as low as possible. pll_config was renamed to via_pll_config to keep the naming scheme. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/Makefile | 2 +- drivers/video/via/hw.c | 288 ++-------------------------------- drivers/video/via/hw.h | 6 - drivers/video/via/via_clock.c | 280 +++++++++++++++++++++++++++++++++ drivers/video/via/via_clock.h | 73 +++++++++ 5 files changed, 368 insertions(+), 281 deletions(-) create mode 100644 drivers/video/via/via_clock.c create mode 100644 drivers/video/via/via_clock.h diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index 96f01ee2a412..5108136e8776 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -6,4 +6,4 @@ obj-$(CONFIG_FB_VIA) += viafb.o viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ - via-core.o via-gpio.o via_modesetting.o + via-core.o via-gpio.o via_modesetting.o via_clock.o diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 712348df0f84..f1eff0b4831f 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -21,6 +21,7 @@ #include #include "global.h" +#include "via_clock.h" static struct pll_limit cle266_pll_limits[] = { {19, 19, 4, 0}, @@ -484,6 +485,9 @@ static struct via_device_mapping device_mapping[] = { {VIA_LVDS2, "LVDS2"} }; +/* structure with function pointers to support clock control */ +static struct via_clock clock; + static void load_fix_bit_crtc_reg(void); static void __devinit init_gfx_chip_info(int chip_type); static void __devinit init_tmds_chip_info(void); @@ -1409,230 +1413,10 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) } -static void set_primary_clock_state(u8 state) -{ - u8 value; - - switch (state) { - case VIA_STATE_ON: - value = 0x20; - break; - case VIA_STATE_OFF: - value = 0x00; - break; - default: - return; - } - - via_write_reg_mask(VIASR, 0x1B, value, 0x30); -} - -static void set_secondary_clock_state(u8 state) -{ - u8 value; - - switch (state) { - case VIA_STATE_ON: - value = 0x80; - break; - case VIA_STATE_OFF: - value = 0x00; - break; - default: - return; - } - - via_write_reg_mask(VIASR, 0x1B, value, 0xC0); -} - -static void set_primary_pll_state(u8 state) -{ - u8 value; - - switch (state) { - case VIA_STATE_ON: - value = 0x20; - break; - case VIA_STATE_OFF: - value = 0x00; - break; - default: - return; - } - - via_write_reg_mask(VIASR, 0x2D, value, 0x30); -} - -static void set_secondary_pll_state(u8 state) -{ - u8 value; - - switch (state) { - case VIA_STATE_ON: - value = 0x08; - break; - case VIA_STATE_OFF: - value = 0x00; - break; - default: - return; - } - - via_write_reg_mask(VIASR, 0x2D, value, 0x0C); -} - -static u32 cle266_encode_pll(struct pll_config pll) -{ - return (pll.multiplier << 8) - | (pll.rshift << 6) - | pll.divisor; -} - -static u32 k800_encode_pll(struct pll_config pll) -{ - return ((pll.divisor - 2) << 16) - | (pll.rshift << 10) - | (pll.multiplier - 2); -} - -static u32 vx855_encode_pll(struct pll_config pll) -{ - return (pll.divisor << 16) - | (pll.rshift << 10) - | pll.multiplier; -} - -static inline void cle266_set_primary_pll_encoded(u32 data) -{ - via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ - via_write_reg(VIASR, 0x46, data & 0xFF); - via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); - via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ -} - -static inline void k800_set_primary_pll_encoded(u32 data) -{ - via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ - via_write_reg(VIASR, 0x44, data & 0xFF); - via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); - via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); - via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ -} - -static inline void cle266_set_secondary_pll_encoded(u32 data) -{ - via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ - via_write_reg(VIASR, 0x44, data & 0xFF); - via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); - via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ -} - -static inline void k800_set_secondary_pll_encoded(u32 data) -{ - via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ - via_write_reg(VIASR, 0x4A, data & 0xFF); - via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); - via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); - via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ -} - -static void cle266_set_primary_pll(struct pll_config config) -{ - cle266_set_primary_pll_encoded(cle266_encode_pll(config)); -} - -static void k800_set_primary_pll(struct pll_config config) -{ - k800_set_primary_pll_encoded(k800_encode_pll(config)); -} - -static void vx855_set_primary_pll(struct pll_config config) -{ - k800_set_primary_pll_encoded(vx855_encode_pll(config)); -} - -static void cle266_set_secondary_pll(struct pll_config config) -{ - cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); -} - -static void k800_set_secondary_pll(struct pll_config config) -{ - k800_set_secondary_pll_encoded(k800_encode_pll(config)); -} - -static void vx855_set_secondary_pll(struct pll_config config) -{ - k800_set_secondary_pll_encoded(vx855_encode_pll(config)); -} - -enum via_clksrc { - VIA_CLKSRC_X1 = 0, - VIA_CLKSRC_TVX1, - VIA_CLKSRC_TVPLL, - VIA_CLKSRC_DVP1TVCLKR, - VIA_CLKSRC_CAP0, - VIA_CLKSRC_CAP1, -}; - -static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) -{ - u8 data = 0; - - switch (source) { - case VIA_CLKSRC_X1: - data = 0x00; - break; - case VIA_CLKSRC_TVX1: - data = 0x02; - break; - case VIA_CLKSRC_TVPLL: - data = 0x04; /* 0x06 should be the same */ - break; - case VIA_CLKSRC_DVP1TVCLKR: - data = 0x0A; - break; - case VIA_CLKSRC_CAP0: - data = 0xC; - break; - case VIA_CLKSRC_CAP1: - data = 0x0E; - break; - } - - if (!use_pll) - data |= 1; - - return data; -} - -static void set_primary_clock_source(enum via_clksrc source, bool use_pll) -{ - u8 data = set_clock_source_common(source, use_pll) << 4; - via_write_reg_mask(VIACR, 0x6C, data, 0xF0); -} - -static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) -{ - u8 data = set_clock_source_common(source, use_pll); - via_write_reg_mask(VIACR, 0x6C, data, 0x0F); -} - -static inline u32 get_pll_internal_frequency(u32 ref_freq, - struct pll_config pll) -{ - return ref_freq / pll.divisor * pll.multiplier; -} - -static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) -{ - return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; -} - -static struct pll_config get_pll_config(struct pll_limit *limits, int size, +static struct via_pll_config get_pll_config(struct pll_limit *limits, int size, int clk) { - struct pll_config cur, up, down, best = {0, 1, 0}; + struct via_pll_config cur, up, down, best = {0, 1, 0}; const u32 f0 = 14318180; /* X1 frequency */ int i, f; @@ -1662,9 +1446,9 @@ static struct pll_config get_pll_config(struct pll_limit *limits, int size, return best; } -static struct pll_config get_best_pll_config(int clk) +static struct via_pll_config get_best_pll_config(int clk) { - struct pll_config config; + struct via_pll_config config; switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: @@ -1700,57 +1484,12 @@ static struct pll_config get_best_pll_config(int clk) /* Set VCLK*/ void viafb_set_vclock(u32 clk, int set_iga) { - struct pll_config config = get_best_pll_config(clk); + struct via_pll_config config = get_best_pll_config(clk); - if (set_iga == IGA1) { - /* Change D,N FOR VCLK */ - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_CLE266: - case UNICHROME_K400: - cle266_set_primary_pll(config); - break; - case UNICHROME_K800: - case UNICHROME_PM800: - case UNICHROME_CN700: - case UNICHROME_CX700: - case UNICHROME_CN750: - case UNICHROME_K8M890: - case UNICHROME_P4M890: - case UNICHROME_P4M900: - case UNICHROME_VX800: - k800_set_primary_pll(config); - break; - case UNICHROME_VX855: - case UNICHROME_VX900: - vx855_set_primary_pll(config); - break; - } - } - - if (set_iga == IGA2) { - /* Change D,N FOR LCK */ - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_CLE266: - case UNICHROME_K400: - cle266_set_secondary_pll(config); - break; - case UNICHROME_K800: - case UNICHROME_PM800: - case UNICHROME_CN700: - case UNICHROME_CX700: - case UNICHROME_CN750: - case UNICHROME_K8M890: - case UNICHROME_P4M890: - case UNICHROME_P4M900: - case UNICHROME_VX800: - k800_set_secondary_pll(config); - break; - case UNICHROME_VX855: - case UNICHROME_VX900: - vx855_set_secondary_pll(config); - break; - } - } + if (set_iga == IGA1) + clock.set_primary_pll(config); + if (set_iga == IGA2) + clock.set_secondary_pll(config); /* Fire! */ via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ @@ -2059,6 +1798,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, void __devinit viafb_init_chip_info(int chip_type) { + via_clock_init(&clock, chip_type); init_gfx_chip_info(chip_type); init_tmds_chip_info(); init_lvds_chip_info(); diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 2cdce9b7eb8e..7e9f51a83126 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -732,12 +732,6 @@ struct _lcd_scaling_factor { struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; }; -struct pll_config { - u16 multiplier; - u8 divisor; - u8 rshift; -}; - struct pll_limit { u16 multiplier_min; u16 multiplier_max; diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c new file mode 100644 index 000000000000..29afe4ce3492 --- /dev/null +++ b/drivers/video/via/via_clock.c @@ -0,0 +1,280 @@ +/* + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2011 Florian Tobias Schandinat + * + * 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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. + */ +/* + * clock and PLL management functions + */ + +#include +#include +#include "via_clock.h" +#include "global.h" +#include "debug.h" + +static inline u32 cle266_encode_pll(struct via_pll_config pll) +{ + return (pll.multiplier << 8) + | (pll.rshift << 6) + | pll.divisor; +} + +static inline u32 k800_encode_pll(struct via_pll_config pll) +{ + return ((pll.divisor - 2) << 16) + | (pll.rshift << 10) + | (pll.multiplier - 2); +} + +static inline u32 vx855_encode_pll(struct via_pll_config pll) +{ + return (pll.divisor << 16) + | (pll.rshift << 10) + | pll.multiplier; +} + +static inline void cle266_set_primary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ + via_write_reg(VIASR, 0x46, data & 0xFF); + via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void k800_set_primary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ + via_write_reg(VIASR, 0x44, data & 0xFF); + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void cle266_set_secondary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ + via_write_reg(VIASR, 0x44, data & 0xFF); + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static inline void k800_set_secondary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ + via_write_reg(VIASR, 0x4A, data & 0xFF); + via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static void cle266_set_primary_pll(struct via_pll_config config) +{ + cle266_set_primary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_primary_pll(struct via_pll_config config) +{ + k800_set_primary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_primary_pll(struct via_pll_config config) +{ + k800_set_primary_pll_encoded(vx855_encode_pll(config)); +} + +static void cle266_set_secondary_pll(struct via_pll_config config) +{ + cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_secondary_pll(struct via_pll_config config) +{ + k800_set_secondary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_secondary_pll(struct via_pll_config config) +{ + k800_set_secondary_pll_encoded(vx855_encode_pll(config)); +} + +static void set_primary_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x30); +} + +static void set_secondary_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x08; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x0C); +} + +static void set_primary_clock_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1B, value, 0x30); +} + +static void set_secondary_clock_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x80; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1B, value, 0xC0); +} + +static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) +{ + u8 data = 0; + + switch (source) { + case VIA_CLKSRC_X1: + data = 0x00; + break; + case VIA_CLKSRC_TVX1: + data = 0x02; + break; + case VIA_CLKSRC_TVPLL: + data = 0x04; /* 0x06 should be the same */ + break; + case VIA_CLKSRC_DVP1TVCLKR: + data = 0x0A; + break; + case VIA_CLKSRC_CAP0: + data = 0xC; + break; + case VIA_CLKSRC_CAP1: + data = 0x0E; + break; + } + + if (!use_pll) + data |= 1; + + return data; +} + +static void set_primary_clock_source(enum via_clksrc source, bool use_pll) +{ + u8 data = set_clock_source_common(source, use_pll) << 4; + via_write_reg_mask(VIACR, 0x6C, data, 0xF0); +} + +static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) +{ + u8 data = set_clock_source_common(source, use_pll); + via_write_reg_mask(VIACR, 0x6C, data, 0x0F); +} + +void via_clock_init(struct via_clock *clock, int gfx_chip) +{ + switch (gfx_chip) { + case UNICHROME_CLE266: + case UNICHROME_K400: + clock->set_primary_clock_state = NULL; + clock->set_primary_clock_source = NULL; + clock->set_primary_pll_state = NULL; + clock->set_primary_pll = cle266_set_primary_pll; + + clock->set_secondary_clock_state = NULL; + clock->set_secondary_clock_source = NULL; + clock->set_secondary_pll_state = NULL; + clock->set_secondary_pll = cle266_set_secondary_pll; + break; + case UNICHROME_K800: + case UNICHROME_PM800: + case UNICHROME_CN700: + case UNICHROME_CX700: + case UNICHROME_CN750: + case UNICHROME_K8M890: + case UNICHROME_P4M890: + case UNICHROME_P4M900: + case UNICHROME_VX800: + clock->set_primary_clock_state = set_primary_clock_state; + clock->set_primary_clock_source = set_primary_clock_source; + clock->set_primary_pll_state = set_primary_pll_state; + clock->set_primary_pll = k800_set_primary_pll; + + clock->set_secondary_clock_state = set_secondary_clock_state; + clock->set_secondary_clock_source = set_secondary_clock_source; + clock->set_secondary_pll_state = set_secondary_pll_state; + clock->set_secondary_pll = k800_set_secondary_pll; + break; + case UNICHROME_VX855: + case UNICHROME_VX900: + clock->set_primary_clock_state = set_primary_clock_state; + clock->set_primary_clock_source = set_primary_clock_source; + clock->set_primary_pll_state = set_primary_pll_state; + clock->set_primary_pll = vx855_set_primary_pll; + + clock->set_secondary_clock_state = set_secondary_clock_state; + clock->set_secondary_clock_source = set_secondary_clock_source; + clock->set_secondary_pll_state = set_secondary_pll_state; + clock->set_secondary_pll = vx855_set_secondary_pll; + break; + + } +} diff --git a/drivers/video/via/via_clock.h b/drivers/video/via/via_clock.h new file mode 100644 index 000000000000..f213a7a8fc79 --- /dev/null +++ b/drivers/video/via/via_clock.h @@ -0,0 +1,73 @@ +/* + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2011 Florian Tobias Schandinat + * + * 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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. + */ +/* + * clock and PLL management functions + */ + +#ifndef __VIA_CLOCK_H__ +#define __VIA_CLOCK_H__ + +#include + +enum via_clksrc { + VIA_CLKSRC_X1 = 0, + VIA_CLKSRC_TVX1, + VIA_CLKSRC_TVPLL, + VIA_CLKSRC_DVP1TVCLKR, + VIA_CLKSRC_CAP0, + VIA_CLKSRC_CAP1, +}; + +struct via_pll_config { + u16 multiplier; + u8 divisor; + u8 rshift; +}; + +struct via_clock { + void (*set_primary_clock_state)(u8 state); + void (*set_primary_clock_source)(enum via_clksrc src, bool use_pll); + void (*set_primary_pll_state)(u8 state); + void (*set_primary_pll)(struct via_pll_config config); + + void (*set_secondary_clock_state)(u8 state); + void (*set_secondary_clock_source)(enum via_clksrc src, bool use_pll); + void (*set_secondary_pll_state)(u8 state); + void (*set_secondary_pll)(struct via_pll_config config); +}; + + +static inline u32 get_pll_internal_frequency(u32 ref_freq, + struct via_pll_config pll) +{ + return ref_freq / pll.divisor * pll.multiplier; +} + +static inline u32 get_pll_output_frequency(u32 ref_freq, + struct via_pll_config pll) +{ + return get_pll_internal_frequency(ref_freq, pll) >> pll.rshift; +} + +void via_clock_init(struct via_clock *clock, int gfx_chip); + +#endif /* __VIA_CLOCK_H__ */ -- GitLab From 0415b00d175e0d8945e6785aad21b5f157976ce0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 24 Mar 2011 18:50:09 +0100 Subject: [PATCH 0066/5560] percpu: Always align percpu output section to PAGE_SIZE Percpu allocator honors alignment request upto PAGE_SIZE and both the percpu addresses in the percpu address space and the translated kernel addresses should be aligned accordingly. The calculation of the former depends on the alignment of percpu output section in the kernel image. The linker script macros PERCPU_VADDR() and PERCPU() are used to define this output section and the latter takes @align parameter. Several architectures are using @align smaller than PAGE_SIZE breaking percpu memory alignment. This patch removes @align parameter from PERCPU(), renames it to PERCPU_SECTION() and makes it always align to PAGE_SIZE. While at it, add PCPU_SETUP_BUG_ON() checks such that alignment problems are reliably detected and remove percpu alignment comment recently added in workqueue.c as the condition would trigger BUG way before reaching there. For um, this patch raises the alignment of percpu area. As the area is in .init, there shouldn't be any noticeable difference. This problem was discovered by David Howells while debugging boot failure on mn10300. Signed-off-by: Tejun Heo Acked-by: Mike Frysinger Cc: uclinux-dist-devel@blackfin.uclinux.org Cc: David Howells Cc: Jeff Dike Cc: user-mode-linux-devel@lists.sourceforge.net --- arch/alpha/kernel/vmlinux.lds.S | 2 +- arch/arm/kernel/vmlinux.lds.S | 2 +- arch/blackfin/kernel/vmlinux.lds.S | 2 +- arch/cris/kernel/vmlinux.lds.S | 2 +- arch/frv/kernel/vmlinux.lds.S | 2 +- arch/m32r/kernel/vmlinux.lds.S | 2 +- arch/mips/kernel/vmlinux.lds.S | 2 +- arch/mn10300/kernel/vmlinux.lds.S | 2 +- arch/parisc/kernel/vmlinux.lds.S | 2 +- arch/powerpc/kernel/vmlinux.lds.S | 2 +- arch/s390/kernel/vmlinux.lds.S | 2 +- arch/sh/kernel/vmlinux.lds.S | 2 +- arch/sparc/kernel/vmlinux.lds.S | 2 +- arch/tile/kernel/vmlinux.lds.S | 2 +- arch/um/include/asm/common.lds.S | 2 +- arch/x86/kernel/vmlinux.lds.S | 2 +- arch/xtensa/kernel/vmlinux.lds.S | 2 +- include/asm-generic/vmlinux.lds.h | 17 ++++++++--------- kernel/workqueue.c | 4 +--- mm/percpu.c | 2 ++ 20 files changed, 28 insertions(+), 29 deletions(-) diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 433be2a24f31..8d57948c0aef 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -39,7 +39,7 @@ SECTIONS __init_begin = ALIGN(PAGE_SIZE); INIT_TEXT_SECTION(PAGE_SIZE) INIT_DATA_SECTION(16) - PERCPU(L1_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(L1_CACHE_BYTES) /* Align to THREAD_SIZE rather than PAGE_SIZE here so any padding page needed for the THREAD_SIZE aligned init_task gets freed after init */ . = ALIGN(THREAD_SIZE); diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index b4348e62ef06..e5287f21badc 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -82,7 +82,7 @@ SECTIONS #endif } - PERCPU(32, PAGE_SIZE) + PERCPU_SECTION(32) #ifndef CONFIG_XIP_KERNEL . = ALIGN(PAGE_SIZE); diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 854fa49f1c3e..8d85c8c6f857 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -136,7 +136,7 @@ SECTIONS . = ALIGN(16); INIT_DATA_SECTION(16) - PERCPU(32, PAGE_SIZE) + PERCPU_SECTION(32) .exit.data : { diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S index 728bbd9e7d4c..a6990cb0f098 100644 --- a/arch/cris/kernel/vmlinux.lds.S +++ b/arch/cris/kernel/vmlinux.lds.S @@ -102,7 +102,7 @@ SECTIONS #endif __vmlinux_end = .; /* Last address of the physical file. */ #ifdef CONFIG_ETRAX_ARCH_V32 - PERCPU(32, PAGE_SIZE) + PERCPU_SECTION(32) .init.ramfs : { INIT_RAM_FS diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index 0daae8af5787..7e958d829ec9 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -37,7 +37,7 @@ SECTIONS _einittext = .; INIT_DATA_SECTION(8) - PERCPU(L1_CACHE_BYTES, 4096) + PERCPU_SECTION(L1_CACHE_BYTES) . = ALIGN(PAGE_SIZE); __init_end = .; diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S index c194d64cdbb9..2e7ccf7299a0 100644 --- a/arch/m32r/kernel/vmlinux.lds.S +++ b/arch/m32r/kernel/vmlinux.lds.S @@ -53,7 +53,7 @@ SECTIONS __init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) INIT_DATA_SECTION(16) - PERCPU(32, PAGE_SIZE) + PERCPU_SECTION(32) . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 832afbb87588..8616709452b1 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -115,7 +115,7 @@ SECTIONS EXIT_DATA } - PERCPU(1 << CONFIG_MIPS_L1_CACHE_SHIFT, PAGE_SIZE) + PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT) . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S index 968bcd2cb022..6f702a6ab395 100644 --- a/arch/mn10300/kernel/vmlinux.lds.S +++ b/arch/mn10300/kernel/vmlinux.lds.S @@ -70,7 +70,7 @@ SECTIONS .exit.text : { EXIT_TEXT; } .exit.data : { EXIT_DATA; } - PERCPU(32, PAGE_SIZE) + PERCPU_SECTION(32) . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 8f1e4efd143e..85b86617fe0b 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -145,7 +145,7 @@ SECTIONS EXIT_DATA } - PERCPU(L1_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(L1_CACHE_BYTES) . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index b9150f07d266..920276c0f6a1 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -160,7 +160,7 @@ SECTIONS INIT_RAM_FS } - PERCPU(L1_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(L1_CACHE_BYTES) . = ALIGN(8); .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 1bc18cdb525b..56fe6bc81fee 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -77,7 +77,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); INIT_DATA_SECTION(0x100) - PERCPU(0x100, PAGE_SIZE) + PERCPU_SECTION(0x100) . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index af4d46187a79..731c10ce67b5 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -66,7 +66,7 @@ SECTIONS __machvec_end = .; } - PERCPU(L1_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(L1_CACHE_BYTES) /* * .exit.text is discarded at runtime, not link time, to deal with diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 92b557afe535..c0220759003e 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -108,7 +108,7 @@ SECTIONS __sun4v_2insn_patch_end = .; } - PERCPU(SMP_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); __init_end = .; diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S index 38f64fafdc10..631f10de12fe 100644 --- a/arch/tile/kernel/vmlinux.lds.S +++ b/arch/tile/kernel/vmlinux.lds.S @@ -60,7 +60,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); VMLINUX_SYMBOL(_sinitdata) = .; INIT_DATA_SECTION(16) :data =0 - PERCPU(L2_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(L2_CACHE_BYTES) . = ALIGN(PAGE_SIZE); VMLINUX_SYMBOL(_einitdata) = .; diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S index 34bede8aad4a..4938de5512d2 100644 --- a/arch/um/include/asm/common.lds.S +++ b/arch/um/include/asm/common.lds.S @@ -42,7 +42,7 @@ INIT_SETUP(0) } - PERCPU(32, 32) + PERCPU_SECTION(32) .initcall.init : { INIT_CALLS diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 624a2016198e..3e9fb5d54f96 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -319,7 +319,7 @@ SECTIONS } #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP) - PERCPU(INTERNODE_CACHE_BYTES, PAGE_SIZE) + PERCPU_SECTION(INTERNODE_CACHE_BYTES) #endif . = ALIGN(PAGE_SIZE); diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index a2820065927e..88ecea3facb4 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -155,7 +155,7 @@ SECTIONS INIT_RAM_FS } - PERCPU(XCHAL_ICACHE_LINESIZE, PAGE_SIZE) + PERCPU_SECTION(XCHAL_ICACHE_LINESIZE) /* We need this dummy segment here */ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 32c45e5fe0ab..f301cea5ca2d 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -15,7 +15,7 @@ * HEAD_TEXT_SECTION * INIT_TEXT_SECTION(PAGE_SIZE) * INIT_DATA_SECTION(...) - * PERCPU(CACHELINE_SIZE, PAGE_SIZE) + * PERCPU_SECTION(CACHELINE_SIZE) * __init_end = .; * * _stext = .; @@ -709,7 +709,7 @@ * * Note that this macros defines __per_cpu_load as an absolute symbol. * If there is no need to put the percpu section at a predetermined - * address, use PERCPU(). + * address, use PERCPU_SECTION. */ #define PERCPU_VADDR(cacheline, vaddr, phdr) \ VMLINUX_SYMBOL(__per_cpu_load) = .; \ @@ -729,20 +729,19 @@ . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu); /** - * PERCPU - define output section for percpu area, simple version + * PERCPU_SECTION - define output section for percpu area, simple version * @cacheline: cacheline size - * @align: required alignment * - * Align to @align and outputs output section for percpu area. This macro - * doesn't manipulate @vaddr or @phdr and __per_cpu_load and + * Align to PAGE_SIZE and outputs output section for percpu area. This + * macro doesn't manipulate @vaddr or @phdr and __per_cpu_load and * __per_cpu_start will be identical. * - * This macro is equivalent to ALIGN(@align); PERCPU_VADDR(@cacheline,,) + * This macro is equivalent to ALIGN(PAGE_SIZE); PERCPU_VADDR(@cacheline,,) * except that __per_cpu_load is defined as a relative symbol against * .data..percpu which is required for relocatable x86_32 configuration. */ -#define PERCPU(cacheline, align) \ - . = ALIGN(align); \ +#define PERCPU_SECTION(cacheline) \ + . = ALIGN(PAGE_SIZE); \ .data..percpu : AT(ADDR(.data..percpu) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__per_cpu_load) = .; \ VMLINUX_SYMBOL(__per_cpu_start) = .; \ diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 04ef830690ec..d30a502e8c6d 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2860,9 +2860,7 @@ static int alloc_cwqs(struct workqueue_struct *wq) } } - /* just in case, make sure it's actually aligned - * - this is affected by PERCPU() alignment in vmlinux.lds.S - */ + /* just in case, make sure it's actually aligned */ BUG_ON(!IS_ALIGNED(wq->cpu_wq.v, align)); return wq->cpu_wq.v ? 0 : -ENOMEM; } diff --git a/mm/percpu.c b/mm/percpu.c index 3f930018aa60..c5feb79f5995 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1216,8 +1216,10 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, PCPU_SETUP_BUG_ON(ai->nr_groups <= 0); #ifdef CONFIG_SMP PCPU_SETUP_BUG_ON(!ai->static_size); + PCPU_SETUP_BUG_ON((unsigned long)__per_cpu_start & ~PAGE_MASK); #endif PCPU_SETUP_BUG_ON(!base_addr); + PCPU_SETUP_BUG_ON((unsigned long)base_addr & ~PAGE_MASK); PCPU_SETUP_BUG_ON(ai->unit_size < size_sum); PCPU_SETUP_BUG_ON(ai->unit_size & ~PAGE_MASK); PCPU_SETUP_BUG_ON(ai->unit_size < PCPU_MIN_UNIT_SIZE); -- GitLab From b692a63af8b63a7a7e84702a713d0072e336b326 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Thu, 24 Mar 2011 14:25:51 +0000 Subject: [PATCH 0067/5560] viafb: add VIA slapping capability This patch introduces dummy functions to execute when we don't know what we should do (due to missing documentation). They do nothing but print a nice message in the log explaining the situation. To trigger this message initial power management support is activated which might save a bit energy by disabling PLL and clock if no device is configured to use them. Note: The message is only shown for the oldest IGPs CLE266 and K400 as for the other platforms there are reasonable assumptions how it does (hopefully) work. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 19 +++++++++++++++++++ drivers/video/via/via_clock.c | 30 ++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index f1eff0b4831f..df84251b8f93 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2289,6 +2289,25 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, get_sync(viafbinfo1)); } + clock.set_primary_clock_source(VIA_CLKSRC_X1, true); + clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); + + if (viaparinfo->shared->iga1_devices) { + clock.set_primary_pll_state(VIA_STATE_ON); + clock.set_primary_clock_state(VIA_STATE_ON); + } else { + clock.set_primary_pll_state(VIA_STATE_OFF); + clock.set_primary_clock_state(VIA_STATE_OFF); + } + + if (viaparinfo->shared->iga2_devices) { + clock.set_secondary_pll_state(VIA_STATE_ON); + clock.set_secondary_clock_state(VIA_STATE_ON); + } else { + clock.set_secondary_pll_state(VIA_STATE_OFF); + clock.set_secondary_clock_state(VIA_STATE_OFF); + } + via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c index 29afe4ce3492..a829a246881c 100644 --- a/drivers/video/via/via_clock.c +++ b/drivers/video/via/via_clock.c @@ -29,6 +29,9 @@ #include "global.h" #include "debug.h" +const char *via_slap = "Please slap VIA Technologies to motivate them " + "releasing full documentation for your platform!\n"; + static inline u32 cle266_encode_pll(struct via_pll_config pll) { return (pll.multiplier << 8) @@ -229,19 +232,34 @@ static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) via_write_reg_mask(VIACR, 0x6C, data, 0x0F); } +static void dummy_set_clock_state(u8 state) +{ + printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap); +} + +static void dummy_set_clock_source(enum via_clksrc source, bool use_pll) +{ + printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap); +} + +static void dummy_set_pll_state(u8 state) +{ + printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap); +} + void via_clock_init(struct via_clock *clock, int gfx_chip) { switch (gfx_chip) { case UNICHROME_CLE266: case UNICHROME_K400: - clock->set_primary_clock_state = NULL; - clock->set_primary_clock_source = NULL; - clock->set_primary_pll_state = NULL; + clock->set_primary_clock_state = dummy_set_clock_state; + clock->set_primary_clock_source = dummy_set_clock_source; + clock->set_primary_pll_state = dummy_set_pll_state; clock->set_primary_pll = cle266_set_primary_pll; - clock->set_secondary_clock_state = NULL; - clock->set_secondary_clock_source = NULL; - clock->set_secondary_pll_state = NULL; + clock->set_secondary_clock_state = dummy_set_clock_state; + clock->set_secondary_clock_source = dummy_set_clock_source; + clock->set_secondary_pll_state = dummy_set_pll_state; clock->set_secondary_pll = cle266_set_secondary_pll; break; case UNICHROME_K800: -- GitLab From efa3144e7cb2a7a58961e5b881b1b9ef73f39cd5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Feb 2011 16:43:05 -0800 Subject: [PATCH 0068/5560] iwlegacy: MAINTAINERS Add iwlegacy driver to MAINTAINERS file and mark as 'Orphan' Signed-off-by: Wey-Yi Guy --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 95482e9e5ba5..12698b3e3caa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3322,6 +3322,16 @@ F: Documentation/wimax/README.i2400m F: drivers/net/wimax/i2400m/ F: include/linux/wimax/i2400m.h +INTEL PRO/WIRELESS 3945ABG/BG NETWORK CONNECTION SUPPORT +L: linux-wireless@vger.kernel.org +S: Orphan +F: drivers/net/wireless/iwlegacy/ + +INTEL WIRELESS WIFI 4965AGN NETWORK CONNECTION SUPPORT +L: linux-wireless@vger.kernel.org +S: Orphan +F: drivers/net/wireless/iwlegacy/ + INTEL WIRELESS WIFI LINK (iwlwifi) M: Wey-Yi Guy M: Intel Linux Wireless -- GitLab From d103e3448a3ecb9f81babd1f6d7f5a678e213c82 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 10 Mar 2011 03:17:16 -0800 Subject: [PATCH 0069/5560] iwlagn: use 6030 configuration for 6035 series 6035 series of devices should use the same uCode as 6030 series, change it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 31 ------------------------- drivers/net/wireless/iwlwifi/iwl-6000.c | 16 +++++++++++++ 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index d7b6126408c9..b1dbe93a88b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -471,37 +471,6 @@ struct iwl_cfg iwl2030_2bg_cfg = { IWL_DEVICE_2030, }; -#define IWL_DEVICE_6035 \ - .fw_name_pre = IWL2030_FW_PRE, \ - .ucode_api_max = IWL2030_UCODE_API_MAX, \ - .ucode_api_min = IWL2030_UCODE_API_MIN, \ - .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \ - .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \ - .ops = &iwl2030_ops, \ - .mod_params = &iwlagn_mod_params, \ - .base_params = &iwl2030_base_params, \ - .bt_params = &iwl2030_bt_params, \ - .need_dc_calib = true, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ - -struct iwl_cfg iwl6035_2agn_cfg = { - .name = "2000 Series 2x2 AGN/BT", - IWL_DEVICE_6035, - .ht_params = &iwl2000_ht_params, -}; - -struct iwl_cfg iwl6035_2abg_cfg = { - .name = "2000 Series 2x2 ABG/BT", - IWL_DEVICE_6035, -}; - -struct iwl_cfg iwl6035_2bg_cfg = { - .name = "2000 Series 2x2 BG/BT", - IWL_DEVICE_6035, -}; - #define IWL_DEVICE_200 \ .fw_name_pre = IWL200_FW_PRE, \ .ucode_api_max = IWL200_UCODE_API_MAX, \ diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a745b01c0ec1..40e022617527 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -613,6 +613,22 @@ struct iwl_cfg iwl6030_2bg_cfg = { IWL_DEVICE_6030, }; +struct iwl_cfg iwl6035_2agn_cfg = { + .name = "6035 Series 2x2 AGN/BT", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +struct iwl_cfg iwl6035_2abg_cfg = { + .name = "6035 Series 2x2 ABG/BT", + IWL_DEVICE_6030, +}; + +struct iwl_cfg iwl6035_2bg_cfg = { + .name = "6035 Series 2x2 BG/BT", + IWL_DEVICE_6030, +}; + struct iwl_cfg iwl1030_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", IWL_DEVICE_6030, -- GitLab From 7ffef13d7a24654292c4641450f2794224b9eb5d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 15 Mar 2011 04:59:10 -0700 Subject: [PATCH 0070/5560] iwlagn: clean up TX aggregation code Since the driver split, there's no need for function pointers any more for aggregation queue setup and teardown as all devices now share the same code. Simplify this. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 17 +++++++---------- drivers/net/wireless/iwlwifi/iwl-agn.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-core.h | 5 ----- 7 files changed, 7 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e8e1c2dc8659..9631d8fa802a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -179,8 +179,6 @@ static struct iwl_lib_ops iwl1000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index b1dbe93a88b0..55274a14af01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -259,8 +259,6 @@ static struct iwl_lib_ops iwl2000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 90e727b1b4c1..4064490e3b96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -348,8 +348,6 @@ static struct iwl_lib_ops iwl5000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, @@ -416,8 +414,6 @@ static struct iwl_lib_ops iwl5150_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 40e022617527..7ecfbbc9457a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -288,8 +288,6 @@ static struct iwl_lib_ops iwl6000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, @@ -357,8 +355,6 @@ static struct iwl_lib_ops iwl6030_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a709d05c5868..23e5667108e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -222,8 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv, scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); } -int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) +static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, + int tx_fifo, int sta_id, int tid, u16 ssn_idx) { unsigned long flags; u16 ra_tid; @@ -288,8 +288,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, return 0; } -int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo) +static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, + u16 ssn_idx, u8 tx_fifo) { if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || (IWLAGN_FIRST_AMPDU_QUEUE + @@ -1037,8 +1037,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, 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, - sta_id, tid, *ssn); + ret = iwlagn_txq_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, *ssn); if (ret) return ret; @@ -1125,8 +1124,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, * to deactivate the uCode queue, just return "success" to allow * mac80211 to clean up it own data. */ - priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, - tx_fifo_id); + iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id); spin_unlock_irqrestore(&priv->lock, flags); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -1155,8 +1153,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, u16 ssn = SEQ_TO_SN(tid_data->seq_number); int tx_fifo = get_fifo_from_tid(ctx, tid); IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); - priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, - ssn, tx_fifo); + iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo); tid_data->agg.state = IWL_AGG_OFF; ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 20f8e4188994..8d918ea36c61 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -133,10 +133,6 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv, u16 byte_cnt); void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, struct iwl_tx_queue *txq); -int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx); -int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo); void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); void iwl_free_tfds_in_queue(struct iwl_priv *priv, int sta_id, int tid, int freed); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b316d833d9a2..1f4f6dd18009 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -171,11 +171,6 @@ struct iwl_lib_ops { struct iwl_tx_queue *txq); int (*txq_init)(struct iwl_priv *priv, struct iwl_tx_queue *txq); - /* aggregations */ - int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo, - int sta_id, int tid, u16 ssn_idx); - int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, - u8 tx_fifo); /* setup Rx handler */ void (*rx_handler_setup)(struct iwl_priv *priv); /* setup deferred work */ -- GitLab From c8823ec1337017e23b99fb0814e2f3d62537f811 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 15 Mar 2011 11:33:03 -0700 Subject: [PATCH 0071/5560] iwlagn: fix aggregation queue scheduler setup iwlagn's hardware scheduler needs to be set up with the right aggregation frame limit and buffer sizes. To achieve this, we need to move the hardware queue setup to when the session becomes operational. Tested-by: Daniel Halperin Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 47 +++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++ drivers/net/wireless/iwlwifi/iwl-agn.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 23e5667108e2..fb63a03a395e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -222,13 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv, scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); } -static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) +static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid) { - unsigned long flags; - u16 ra_tid; - int ret; - if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { @@ -240,12 +235,33 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, return -EINVAL; } - ra_tid = BUILD_RAxTID(sta_id, tid); - /* Modify device's station table to Tx this TID */ - ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); - if (ret) - return ret; + return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); +} + +void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv, + struct ieee80211_sta *sta, + int tid, int frame_limit) +{ + int sta_id, tx_fifo, txq_id, ssn_idx; + u16 ra_tid; + unsigned long flags; + struct iwl_tid_data *tid_data; + + sta_id = iwl_sta_id(sta); + if (WARN_ON(sta_id == IWL_INVALID_STATION)) + return; + if (WARN_ON(tid >= MAX_TID_COUNT)) + return; + + spin_lock_irqsave(&priv->sta_lock, flags); + tid_data = &priv->stations[sta_id].tid[tid]; + ssn_idx = SEQ_TO_SN(tid_data->seq_number); + txq_id = tid_data->agg.txq_id; + tx_fifo = tid_data->agg.tx_fifo; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + ra_tid = BUILD_RAxTID(sta_id, tid); spin_lock_irqsave(&priv->lock, flags); @@ -271,10 +287,10 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, iwl_write_targ_mem(priv, priv->scd_base_addr + IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), - ((SCD_WIN_SIZE << + ((frame_limit << IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | - ((SCD_FRAME_LIMIT << + ((frame_limit << IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); @@ -284,8 +300,6 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); spin_unlock_irqrestore(&priv->lock, flags); - - return 0; } static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, @@ -1034,10 +1048,11 @@ 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; + tid_data->agg.tx_fifo = tx_fifo; iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); spin_unlock_irqrestore(&priv->sta_lock, flags); - ret = iwlagn_txq_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, *ssn); + ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b57fbbf3fb64..8fdd1746c102 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3345,6 +3345,10 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, } break; case IEEE80211_AMPDU_TX_OPERATIONAL: + buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); + + iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size); + /* * If the limit is 0, then it wasn't initialised yet, * use the default. We can do that since we take the diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 8d918ea36c61..4f7c9ce9d8bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -202,6 +202,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn); int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); +void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv, + struct ieee80211_sta *sta, + int tid, int frame_limit); int iwlagn_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 68b953f2bdc7..a5d438d91821 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -416,6 +416,7 @@ struct iwl_ht_agg { #define IWL_EMPTYING_HW_QUEUE_ADDBA 2 #define IWL_EMPTYING_HW_QUEUE_DELBA 3 u8 state; + u8 tx_fifo; }; -- GitLab From 374920cb0512f5938fdf1f5af4f9afa7502dd0f9 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Wed, 16 Mar 2011 19:16:36 -0700 Subject: [PATCH 0072/5560] iwlwifi: limit number of attempts for highest HT rate When filling out its rate scale table, iwlwifi repeats the first HT rate IWL_HT_NUMBER_TRY times. The hardware scheduler will stop using aggregation for any frame that fails LINK_QUAL_AGG_DISABLE_START_DEF times. Currently, both these constants equal 3. If iwlwifi probes a faster rate than the link supports, all frames in a (potentially tens of frames large) batch will fail IWL_HT_NUMBER_TRY times. Because this happens to be as large as LINK_QUAL_AGG_DISABLE_START_DEF, all frames will then be sent individually. This leads to a short, but performance-degrading window where the legacy stop-and-wait MAC takes over. Bounding the initial rate by (LINK_QUAL_AGG_DISABLE_START_DEF-1) attempts makes the third try use a lower rate and hence more be likely to succeed. This somewhat mitigates the above described behavior. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index d03b4734c892..63b58ecb0dc6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2912,7 +2912,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ant_toggle_cnt = 1; repeat_rate = IWL_NUMBER_TRY; } else { - repeat_rate = IWL_HT_NUMBER_TRY; + repeat_rate = min(IWL_HT_NUMBER_TRY, + LINK_QUAL_AGG_DISABLE_START_DEF - 1); } lq_cmd->general_params.mimo_delimiter = -- GitLab From d0eb633431ec922f8f9b2040f46d9b42a4cec193 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Wed, 16 Mar 2011 17:17:36 -0700 Subject: [PATCH 0073/5560] iwlwifi: cleanup and bugfix tx aggregation code Since the driver split, there's no need for no_agg_framecnt_info since all devices have this set to false. Secondly, the compressed block ack handling code was broken. Fix this. (1) A shift less than zero simply implies that the buffer wrapped, this is expected. Remove the incorrect comment. (2) The (agg->frame_count > (64-sh)) condition can happen if the last frame is dropped. E.g., if I send 7 frames and the 6th is received but the 7th is lost, the other side may only shift the window 6, not 7 frames since the last bit is a 0. This is perfectly fine behavior and doesn't invalidate the feedback. (3) Store the feedback from a Compressed BA in the first newly received frame, rather than the start of the window. This way it will get processed by the rate selection code. Feedback stored in a non-received frame is likely to get overwritten by the retransmission. This is based on the approach taken by minstrel_ht. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 82 ++++++++--------------- drivers/net/wireless/iwlwifi/iwl-core.h | 3 - 2 files changed, 27 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index fb63a03a395e..cb8eacd5fdb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1263,11 +1263,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, struct iwl_compressed_ba_resp *ba_resp) { - int i, sh, ack; + int sh; u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); - int successes = 0; struct ieee80211_tx_info *info; + u64 bitmap, sent_bitmap; if (unlikely(!agg->wait_for_ba)) { if (unlikely(ba_resp->bitmap)) @@ -1281,70 +1281,42 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, /* Calculate shift to align block-ack bits with our Tx window bits */ sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4); - if (sh < 0) /* tbw something is wrong with indices */ + if (sh < 0) sh += 0x100; - if (agg->frame_count > (64 - sh)) { - IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); - return -1; - } - if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { + /* + * Check for success or failure according to the + * transmitted bitmap and block-ack bitmap + */ + bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; + sent_bitmap = bitmap & agg->bitmap; + + /* Sanity check values reported by uCode */ + 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); /* - * sent and ack information provided by uCode - * use it instead of figure out ourself + * set txed_2_done = txed, + * so it won't impact rate scale */ - 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 { - u64 bitmap, sent_bitmap; - - /* 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; - } + 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); - IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", - (unsigned long long)bitmap); + /* Find the first ACKed frame to store the TX status */ + while (sent_bitmap && !(sent_bitmap & 1)) { + agg->start_idx = (agg->start_idx + 1) & 0xff; + sent_bitmap >>= 1; } 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; - 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; - } + info->status.ampdu_ack_len = ba_resp->txed_2_done; + info->status.ampdu_len = ba_resp->txed; iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1f4f6dd18009..3e680af7ff70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -281,8 +281,6 @@ 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; @@ -312,7 +310,6 @@ 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 -- GitLab From 2520546aecc969372080448a2422b39eedb2a528 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Fri, 18 Mar 2011 18:48:55 -0700 Subject: [PATCH 0074/5560] iwlwifi: add RATE_MCS_RATE_MSK Throughout the code we use rate_n_flags & 0xff to extract the lower byte of the rate_n_flags u32 that contains the information about the rate. Add a #define and remove the use of the magic number. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 15 ++++++++------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 ++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 63b58ecb0dc6..e394e49228ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -115,13 +115,18 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { /* FIXME:RS: ^^ should be INV (legacy) */ }; +static inline u8 rs_extract_rate(u32 rate_n_flags) +{ + return (u8)(rate_n_flags & RATE_MCS_RATE_MSK); +} + static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) { int idx = 0; /* HT rate format */ if (rate_n_flags & RATE_MCS_HT_MSK) { - idx = (rate_n_flags & 0xff); + idx = rs_extract_rate(rate_n_flags); if (idx >= IWL_RATE_MIMO3_6M_PLCP) idx = idx - IWL_RATE_MIMO3_6M_PLCP; @@ -138,7 +143,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) /* legacy rate format, search for match in table */ } else { for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) - if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + if (iwl_rates[idx].plcp == + rs_extract_rate(rate_n_flags)) return idx; } @@ -239,11 +245,6 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { #define MCS_INDEX_PER_STREAM (8) -static inline u8 rs_extract_rate(u32 rate_n_flags) -{ - return (u8)(rate_n_flags & 0xFF); -} - static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) { window->data = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 4f7c9ce9d8bd..39313acb9cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -310,7 +310,7 @@ static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) { - return le32_to_cpu(rate_n_flags) & 0xFF; + return le32_to_cpu(rate_n_flags) & RATE_MCS_RATE_MSK; } static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index ca42ffa63ed7..288391558afd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -324,6 +324,8 @@ struct iwl3945_power_per_rate { #define RATE_MCS_SPATIAL_MSK 0x18 #define RATE_MCS_HT_DUP_POS 5 #define RATE_MCS_HT_DUP_MSK 0x20 +/* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */ +#define RATE_MCS_RATE_MSK 0xff /* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ #define RATE_MCS_FLAGS_POS 8 -- GitLab From 4263108c2a9028544cf4037fa4e72000ee456c33 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Mon, 21 Mar 2011 15:27:34 -0700 Subject: [PATCH 0075/5560] iwlwifi: set default aggregation frame limit to 63 This gives much better performance at fast 3x3 rates (up to ~160 Mbps). The scheduler will still make most decisions about batch size based on available packets and RX parameters. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 288391558afd..cc2151482f31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2132,7 +2132,7 @@ struct iwl_link_qual_general_params { #define LINK_QUAL_AGG_DISABLE_START_MAX (255) #define LINK_QUAL_AGG_DISABLE_START_MIN (0) -#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31) +#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) -- GitLab From d6b8061824a03fbe915c6cf5be2b290ae44c4ec4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 21 Mar 2011 16:53:38 -0700 Subject: [PATCH 0076/5560] iwlwifi: remove legacy isr tasklet After driver split, no need for support legacy isr, remove it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 2 - drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 193 +-------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 4 files changed, 3 insertions(+), 196 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index b5cb3be0eb4b..47e1fa4bacfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -59,8 +59,6 @@ void iwl_free_isr_ict(struct iwl_priv *priv) int iwl_alloc_isr_ict(struct iwl_priv *priv) { - if (priv->cfg->base_params->use_isr_legacy) - return 0; /* allocate shrared data table */ priv->_agn.ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 2003c1d4295f..8163a0efdc83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -652,8 +652,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ - if (!priv->cfg->base_params->use_isr_legacy) - rb_timeout = RX_RB_TIMEOUT; + rb_timeout = RX_RB_TIMEOUT; if (priv->cfg->mod_params->amsdu_size_8K) rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8fdd1746c102..bd980a2da413 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -845,191 +845,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) tasklet_kill(&priv->irq_tasklet); } -static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) -{ - u32 inta, handled = 0; - u32 inta_fh; - unsigned long flags; - u32 i; -#ifdef CONFIG_IWLWIFI_DEBUG - u32 inta_mask; -#endif - - spin_lock_irqsave(&priv->lock, flags); - - /* Ack/clear/reset pending uCode interrupts. - * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, - * and will clear only when CSR_FH_INT_STATUS gets cleared. */ - inta = iwl_read32(priv, CSR_INT); - iwl_write32(priv, CSR_INT, inta); - - /* Ack/clear/reset pending flow-handler (DMA) interrupts. - * Any new interrupts that happen after this, either while we're - * in this tasklet, or later, will show up in next ISR/tasklet. */ - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & IWL_DL_ISR) { - /* just for debug */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); - IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - } -#endif - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not - * atomic, make sure that inta covers all the interrupts that - * we've discovered, even if FH interrupt came in just after - * reading CSR_INT. */ - if (inta_fh & CSR49_FH_INT_RX_MASK) - inta |= CSR_INT_BIT_FH_RX; - if (inta_fh & CSR49_FH_INT_TX_MASK) - inta |= CSR_INT_BIT_FH_TX; - - /* Now service all interrupt bits discovered above. */ - if (inta & CSR_INT_BIT_HW_ERR) { - IWL_ERR(priv, "Hardware error detected. Restarting.\n"); - - /* Tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); - - priv->isr_stats.hw++; - iwl_irq_handle_error(priv); - - handled |= CSR_INT_BIT_HW_ERR; - - return; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_SCD) { - IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " - "the frame/frames.\n"); - priv->isr_stats.sch++; - } - - /* Alive notification via Rx interrupt will do the real work */ - if (inta & CSR_INT_BIT_ALIVE) { - IWL_DEBUG_ISR(priv, "Alive interrupt\n"); - priv->isr_stats.alive++; - } - } -#endif - /* Safely ignore these bits for debug checks below */ - inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); - - /* HW RF KILL switch toggled */ - if (inta & CSR_INT_BIT_RF_KILL) { - int hw_rf_kill = 0; - if (!(iwl_read32(priv, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) - hw_rf_kill = 1; - - IWL_WARN(priv, "RF_KILL bit toggled to %s.\n", - hw_rf_kill ? "disable radio" : "enable radio"); - - priv->isr_stats.rfkill++; - - /* driver only loads ucode once setting the interface up. - * the driver allows loading the ucode even if the radio - * is killed. Hence update the killswitch state here. The - * rfkill handler will care about restarting if needed. - */ - if (!test_bit(STATUS_ALIVE, &priv->status)) { - if (hw_rf_kill) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); - } - - handled |= CSR_INT_BIT_RF_KILL; - } - - /* Chip got too hot and stopped itself */ - if (inta & CSR_INT_BIT_CT_KILL) { - IWL_ERR(priv, "Microcode CT kill error detected.\n"); - priv->isr_stats.ctkill++; - handled |= CSR_INT_BIT_CT_KILL; - } - - /* Error detected by uCode */ - if (inta & CSR_INT_BIT_SW_ERR) { - IWL_ERR(priv, "Microcode SW error detected. " - " Restarting 0x%X.\n", inta); - priv->isr_stats.sw++; - iwl_irq_handle_error(priv); - handled |= CSR_INT_BIT_SW_ERR; - } - - /* - * uCode wakes up after power-down sleep. - * Tell device about any new tx or host commands enqueued, - * and about any Rx buffers made available while asleep. - */ - if (inta & CSR_INT_BIT_WAKEUP) { - IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); - iwl_rx_queue_update_write_ptr(priv, &priv->rxq); - for (i = 0; i < priv->hw_params.max_txq_num; i++) - iwl_txq_update_write_ptr(priv, &priv->txq[i]); - priv->isr_stats.wakeup++; - handled |= CSR_INT_BIT_WAKEUP; - } - - /* All uCode command responses, including Tx command responses, - * Rx "responses" (frame-received notification), and other - * notifications from uCode come through here*/ - if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl_rx_handle(priv); - priv->isr_stats.rx++; - handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - } - - /* This "Tx" DMA channel is used only for loading uCode */ - if (inta & CSR_INT_BIT_FH_TX) { - IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); - priv->isr_stats.tx++; - handled |= CSR_INT_BIT_FH_TX; - /* Wake up uCode load routine, now that load is complete */ - priv->ucode_write_complete = 1; - wake_up_interruptible(&priv->wait_command_queue); - } - - if (inta & ~handled) { - IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); - priv->isr_stats.unhandled++; - } - - if (inta & ~(priv->inta_mask)) { - IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", - inta & ~priv->inta_mask); - IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); - } - - /* Re-enable all interrupts */ - /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - /* Re-enable RF_KILL if it occurred */ - else if (handled & CSR_INT_BIT_RF_KILL) - iwl_enable_rfkill_int(priv); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - inta = iwl_read32(priv, CSR_INT); - inta_mask = iwl_read32(priv, CSR_INT_MASK); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " - "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); - } -#endif -} - /* tasklet for iwlagn interrupt */ static void iwl_irq_tasklet(struct iwl_priv *priv) { @@ -3751,12 +3566,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) 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)) - iwl_irq_tasklet, (unsigned long)priv); - else - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet_legacy, (unsigned long)priv); + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)priv); } static void iwl_cancel_deferred_work(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3e680af7ff70..3a4e9b4d0973 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -291,7 +291,6 @@ struct iwl_base_params { bool set_l0s; bool use_bsm; - bool use_isr_legacy; const u16 max_ll_items; const bool shadow_ram_support; u16 led_compensation; -- GitLab From 2a226ab67f2f9c46e534f37f867d3bf3af335d02 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Mar 2011 08:05:36 -0700 Subject: [PATCH 0077/5560] iwlagn: remove 3945 only station code After driver split, no more 3945 only station support needed. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-sta.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index bc90a12408a3..b0dcca07ff45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -306,12 +306,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, */ iwl_set_ht_add_station(priv, sta_id, sta, ctx); - /* 3945 only */ - rate = (priv->band == IEEE80211_BAND_5GHZ) ? - IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP; - /* Turn on both antennas for the station... */ - station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); - return sta_id; } -- GitLab From f7d046f91bd165e747b9a95d089a4168b6f9796a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Mar 2011 08:05:37 -0700 Subject: [PATCH 0078/5560] iwlagn: remove reference to 3945 and 4965 After driver split, remove the unused reference to 3945 and 4965 Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 39 +++++++++-------------- drivers/net/wireless/iwlwifi/iwl-csr.h | 39 +++++------------------ drivers/net/wireless/iwlwifi/iwl-eeprom.c | 2 -- 3 files changed, 23 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bd980a2da413..9251c68934dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -409,7 +409,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, * Tell nic where to find circular buffer of Tx Frame Descriptors for * given Tx queue, and enable the DMA channel used for that queue. * - * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA + * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA * channels supported in hardware. */ int iwl_hw_tx_queue_init(struct iwl_priv *priv, @@ -986,7 +986,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); iwl_write32(priv, CSR_FH_INT_STATUS, - CSR49_FH_INT_RX_MASK); + CSR_FH_INT_RX_MASK); } if (inta & CSR_INT_BIT_RX_PERIODIC) { handled |= CSR_INT_BIT_RX_PERIODIC; @@ -1024,7 +1024,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* This "Tx" DMA channel is used only for loading uCode */ if (inta & CSR_INT_BIT_FH_TX) { - iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK); + iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); priv->isr_stats.tx++; handled |= CSR_INT_BIT_FH_TX; @@ -1259,28 +1259,19 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, switch (api_ver) { default: - /* - * 4965 doesn't revision the firmware file format - * along with the API version, it always uses v1 - * file format. - */ - if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != - CSR_HW_REV_TYPE_4965) { - hdr_size = 28; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size); - src = ucode->u.v2.data; - break; + hdr_size = 28; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; } - /* fall through for 4965 */ + pieces->build = le32_to_cpu(ucode->u.v2.build); + pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); + pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); + pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size); + src = ucode->u.v2.data; + break; case 0: case 1: case 2: diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index f52bc040bcbf..1123319f2e2b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -155,18 +155,10 @@ #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) /* Bits for CSR_HW_IF_CONFIG_REG */ -#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) -#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100) -#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200) -#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400) -#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800) -#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) -#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) - #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) #define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */ @@ -186,7 +178,7 @@ #define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ #define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ #define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ -#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */ +#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses */ #define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */ #define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */ @@ -202,29 +194,17 @@ /* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ #define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ #define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */ -#define CSR39_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */ #define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */ #define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */ -#define CSR39_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */ #define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */ #define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */ -#define CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ - CSR39_FH_INT_BIT_RX_CHNL2 | \ - CSR_FH_INT_BIT_RX_CHNL1 | \ - CSR_FH_INT_BIT_RX_CHNL0) - - -#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \ - CSR_FH_INT_BIT_TX_CHNL1 | \ - CSR_FH_INT_BIT_TX_CHNL0) - -#define CSR49_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ - CSR_FH_INT_BIT_RX_CHNL1 | \ - CSR_FH_INT_BIT_RX_CHNL0) +#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ + CSR_FH_INT_BIT_RX_CHNL1 | \ + CSR_FH_INT_BIT_RX_CHNL0) -#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ - CSR_FH_INT_BIT_TX_CHNL0) +#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ + CSR_FH_INT_BIT_TX_CHNL0) /* GPIO */ #define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) @@ -268,7 +248,7 @@ * Indicates MAC (ucode processor, etc.) is powered up and can run. * Internal resources are accessible. * NOTE: This does not indicate that the processor is actually running. - * NOTE: This does not indicate that 4965 or 3945 has completed + * NOTE: This does not indicate that device has completed * init or post-power-down restore of internal SRAM memory. * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that * SRAM is restored and uCode is in normal operation mode. @@ -291,8 +271,6 @@ /* HW REV */ #define CSR_HW_REV_TYPE_MSK (0x00001F0) -#define CSR_HW_REV_TYPE_3945 (0x00000D0) -#define CSR_HW_REV_TYPE_4965 (0x0000000) #define CSR_HW_REV_TYPE_5300 (0x0000020) #define CSR_HW_REV_TYPE_5350 (0x0000030) #define CSR_HW_REV_TYPE_5100 (0x0000050) @@ -363,7 +341,7 @@ * 0: MAC_SLEEP * uCode sets this when preparing a power-saving power-down. * uCode resets this when power-up is complete and SRAM is sane. - * NOTE: 3945/4965 saves internal SRAM data to host when powering down, + * NOTE: device saves internal SRAM data to host when powering down, * and must restore this data after powering back up. * MAC_SLEEP is the best indication that restore is complete. * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and @@ -394,7 +372,6 @@ #define CSR_LED_REG_TRUN_OFF (0x38) /* ANA_PLL */ -#define CSR39_ANA_PLL_CFG_VAL (0x01000000) #define CSR50_ANA_PLL_CFG_VAL (0x00880300) /* HPET MEM debug */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 833194a2c639..c831a0f24613 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -198,8 +198,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv) case CSR_HW_REV_TYPE_NONE: IWL_ERR(priv, "Unknown hardware type\n"); return -ENOENT; - case CSR_HW_REV_TYPE_3945: - case CSR_HW_REV_TYPE_4965: case CSR_HW_REV_TYPE_5300: case CSR_HW_REV_TYPE_5350: case CSR_HW_REV_TYPE_5100: -- GitLab From 7eaa6a5e964f1ab02d849bda36950c0d30be8ce2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Mar 2011 08:05:38 -0700 Subject: [PATCH 0079/5560] iwlagn: remove deprecated module parameters Number of deprecated module parameters need to be remove for 2.6.40 kernel Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 30 ------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 2 files changed, 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9251c68934dd..39a05e32c34f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3771,14 +3771,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 1. Allocating HW data ************************/ - /* Disabling hardware scan means that mac80211 will perform scans - * "the hard way", rather than using device's scan. */ - if (cfg->mod_params->disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); - iwlagn_hw_ops.hw_scan = NULL; - } - hw = iwl_alloc_all(cfg); if (!hw) { err = -ENOMEM; @@ -4388,43 +4380,21 @@ module_exit(iwl_exit); module_init(iwl_init); #ifdef CONFIG_IWLWIFI_DEBUG -module_param_named(debug50, iwl_debug_level, uint, S_IRUGO); -MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)"); module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "debug output mask"); #endif -module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO); -MODULE_PARM_DESC(swcrypto50, - "using crypto in software (default 0 [hardware]) (deprecated)"); module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); -module_param_named(queues_num50, - iwlagn_mod_params.num_of_queues, int, S_IRUGO); -MODULE_PARM_DESC(queues_num50, - "number of hw queues in 50xx series (deprecated)"); module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); MODULE_PARM_DESC(queues_num, "number of hw queues."); -module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO); -MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)"); module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO); MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); -module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K, - int, S_IRUGO); -MODULE_PARM_DESC(amsdu_size_8K50, - "enable 8K amsdu size in 50XX series (deprecated)"); module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K, int, S_IRUGO); MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); -module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO); -MODULE_PARM_DESC(fw_restart50, - "restart firmware in case of error (deprecated)"); module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); -module_param_named( - disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, - "disable hardware scanning (default 0) (deprecated)"); module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3a4e9b4d0973..967b4c008bc0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -247,7 +247,6 @@ struct iwl_ops { struct iwl_mod_params { int sw_crypto; /* def: 0 = using hardware encryption */ - int disable_hw_scan; /* def: 0 = use h/w scan */ int num_of_queues; /* def: HW dependent */ int disable_11n; /* def: 0 = 11n capabilities enabled */ int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ -- GitLab From bea02e45874a5d18127b0779740c4fd5b3e7e44a Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 26 Mar 2011 02:29:18 +0000 Subject: [PATCH 0080/5560] viafb: add engine clock support This patch adds support for enabling and configuring the engine on VIAs IGPs. This is the main clock used for everything but pixel output. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 1 + drivers/video/via/via_clock.c | 51 +++++++++++++++++++++++++++++++++++ drivers/video/via/via_clock.h | 3 +++ 3 files changed, 55 insertions(+) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index df84251b8f93..e5311474219f 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2289,6 +2289,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, get_sync(viafbinfo1)); } + clock.set_engine_pll_state(VIA_STATE_ON); clock.set_primary_clock_source(VIA_CLKSRC_X1, true); clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c index a829a246881c..af8f26b643c1 100644 --- a/drivers/video/via/via_clock.c +++ b/drivers/video/via/via_clock.c @@ -87,6 +87,15 @@ static inline void k800_set_secondary_pll_encoded(u32 data) via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ } +static inline void set_engine_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */ + via_write_reg(VIASR, 0x47, data & 0xFF); + via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */ +} + static void cle266_set_primary_pll(struct via_pll_config config) { cle266_set_primary_pll_encoded(cle266_encode_pll(config)); @@ -117,6 +126,16 @@ static void vx855_set_secondary_pll(struct via_pll_config config) k800_set_secondary_pll_encoded(vx855_encode_pll(config)); } +static void k800_set_engine_pll(struct via_pll_config config) +{ + set_engine_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_engine_pll(struct via_pll_config config) +{ + set_engine_pll_encoded(vx855_encode_pll(config)); +} + static void set_primary_pll_state(u8 state) { u8 value; @@ -153,6 +172,24 @@ static void set_secondary_pll_state(u8 state) via_write_reg_mask(VIASR, 0x2D, value, 0x0C); } +static void set_engine_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x02; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x03); +} + static void set_primary_clock_state(u8 state) { u8 value; @@ -247,6 +284,11 @@ static void dummy_set_pll_state(u8 state) printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap); } +static void dummy_set_pll(struct via_pll_config config) +{ + printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); +} + void via_clock_init(struct via_clock *clock, int gfx_chip) { switch (gfx_chip) { @@ -261,6 +303,9 @@ void via_clock_init(struct via_clock *clock, int gfx_chip) clock->set_secondary_clock_source = dummy_set_clock_source; clock->set_secondary_pll_state = dummy_set_pll_state; clock->set_secondary_pll = cle266_set_secondary_pll; + + clock->set_engine_pll_state = dummy_set_pll_state; + clock->set_engine_pll = dummy_set_pll; break; case UNICHROME_K800: case UNICHROME_PM800: @@ -280,6 +325,9 @@ void via_clock_init(struct via_clock *clock, int gfx_chip) clock->set_secondary_clock_source = set_secondary_clock_source; clock->set_secondary_pll_state = set_secondary_pll_state; clock->set_secondary_pll = k800_set_secondary_pll; + + clock->set_engine_pll_state = set_engine_pll_state; + clock->set_engine_pll = k800_set_engine_pll; break; case UNICHROME_VX855: case UNICHROME_VX900: @@ -292,6 +340,9 @@ void via_clock_init(struct via_clock *clock, int gfx_chip) clock->set_secondary_clock_source = set_secondary_clock_source; clock->set_secondary_pll_state = set_secondary_pll_state; clock->set_secondary_pll = vx855_set_secondary_pll; + + clock->set_engine_pll_state = set_engine_pll_state; + clock->set_engine_pll = vx855_set_engine_pll; break; } diff --git a/drivers/video/via/via_clock.h b/drivers/video/via/via_clock.h index f213a7a8fc79..88714ae0d157 100644 --- a/drivers/video/via/via_clock.h +++ b/drivers/video/via/via_clock.h @@ -53,6 +53,9 @@ struct via_clock { void (*set_secondary_clock_source)(enum via_clksrc src, bool use_pll); void (*set_secondary_pll_state)(u8 state); void (*set_secondary_pll)(struct via_pll_config config); + + void (*set_engine_pll_state)(u8 state); + void (*set_engine_pll)(struct via_pll_config config); }; -- GitLab From 4b8ffdb959c35f5e271fb7e08635dbdb2593018f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 24 Mar 2011 09:11:49 +0200 Subject: [PATCH 0081/5560] ASoC: tlv320dac33: Move codec power up to DAPM Move the codec power on (in reg 0x01, bit 4) from set_bias_level:SND_SOC_BIAS_ON to a DAPM supply. In this way we can be sure, that all the things within the codec is powered before the external amp is going to be enabled. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 00b6d87e7bdb..4857f2ae0666 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -583,6 +583,9 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("Right DAC Power", DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Codec Power", + DAC33_PWR_CTRL, 4, 0, NULL, 0), + SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event), SND_SOC_DAPM_POST("Post Playback", dac33_playback_event), }; @@ -615,6 +618,9 @@ static const struct snd_soc_dapm_route audio_map[] = { /* output */ {"LEFT_LO", NULL, "Output Left Amplifier"}, {"RIGHT_LO", NULL, "Output Right Amplifier"}, + + {"LEFT_LO", NULL, "Codec Power"}, + {"RIGHT_LO", NULL, "Codec Power"}, }; static int dac33_add_widgets(struct snd_soc_codec *codec) @@ -632,13 +638,10 @@ static int dac33_add_widgets(struct snd_soc_codec *codec) static int dac33_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); int ret; switch (level) { case SND_SOC_BIAS_ON: - if (!dac33->substream) - dac33_soft_power(codec, 1); break; case SND_SOC_BIAS_PREPARE: break; -- GitLab From 8b573c95d7bd1cf28c69ab4e0255cd272d214482 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 25 Mar 2011 16:51:46 +0100 Subject: [PATCH 0082/5560] ASoC: imx: remove superfluous code in imx-ssi.c Checking if IMX_SSI_DMA is set and then set it again is useless. Signed-off-by: Wolfram Sang Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-ssi.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index bc92ec620004..c331d65587d8 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -667,12 +667,6 @@ static int imx_ssi_probe(struct platform_device *pdev) if (res) ssi->dma_params_rx.dma = res->start; - if ((cpu_is_mx27() || cpu_is_mx21()) && - !(ssi->flags & IMX_SSI_USE_AC97) && - (ssi->flags & IMX_SSI_DMA)) { - ssi->flags |= IMX_SSI_DMA; - } - platform_set_drvdata(pdev, ssi); ret = snd_soc_register_dai(&pdev->dev, dai); -- GitLab From f3594f5c5c489d159f6d487a889d9d68ca4c0123 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:37:01 +0000 Subject: [PATCH 0083/5560] ASoC: soc-cache: Factor-out the I2C read code The handling of all snd_soc_x_y_read_i2c() functions is similar. Make a generic I2C read function and update all callers to use it. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 100 ++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 68 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 5d76da43b14c..9f6737413a6e 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -351,33 +351,48 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data, #endif #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) -static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, - unsigned int r) +static unsigned int do_i2c_read(struct snd_soc_codec *codec, + void *reg, int reglen, + void *data, int datalen) { struct i2c_msg xfer[2]; - u8 reg = r; - u8 data; int ret; struct i2c_client *client = codec->control_data; /* Write register */ xfer[0].addr = client->addr; xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® + xfer[0].len = reglen; + xfer[0].buf = reg; /* Read data */ xfer[1].addr = client->addr; xfer[1].flags = I2C_M_RD; - xfer[1].len = 1; - xfer[1].buf = &data; + xfer[1].len = datalen; + xfer[1].buf = data; ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); + dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); + if (ret == 2) return 0; - } + else if (ret < 0) + return ret; + else + return -EIO; +} +#endif + +#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) +static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, + unsigned int r) +{ + u8 reg = r; + u8 data; + int ret; + ret = do_i2c_read(codec, ®, 1, &data, 1); + if (ret < 0) + return 0; return data; } #else @@ -388,30 +403,13 @@ static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, unsigned int r) { - struct i2c_msg xfer[2]; u8 reg = r; u16 data; int ret; - struct i2c_client *client = codec->control_data; - - /* Write register */ - xfer[0].addr = client->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - - /* Read data */ - xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 2; - xfer[1].buf = (u8 *)&data; - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); + ret = do_i2c_read(codec, ®, 1, &data, 2); + if (ret < 0) return 0; - } - return (data >> 8) | ((data & 0xff) << 8); } #else @@ -422,30 +420,13 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, unsigned int r) { - struct i2c_msg xfer[2]; u16 reg = r; u8 data; int ret; - struct i2c_client *client = codec->control_data; - - /* Write register */ - xfer[0].addr = client->addr; - xfer[0].flags = 0; - xfer[0].len = 2; - xfer[0].buf = (u8 *)® - - /* Read data */ - xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 1; - xfer[1].buf = &data; - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); + ret = do_i2c_read(codec, ®, 2, &data, 1); + if (ret < 0) return 0; - } - return data; } #else @@ -543,30 +524,13 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data, static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, unsigned int r) { - struct i2c_msg xfer[2]; u16 reg = cpu_to_be16(r); u16 data; int ret; - struct i2c_client *client = codec->control_data; - - /* Write register */ - xfer[0].addr = client->addr; - xfer[0].flags = 0; - xfer[0].len = 2; - xfer[0].buf = (u8 *)® - /* Read data */ - xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 2; - xfer[1].buf = (u8 *)&data; - - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); + ret = do_i2c_read(codec, ®, 2, &data, 2); + if (ret < 0) return 0; - } - return be16_to_cpu(data); } #else -- GitLab From 5fb609d435f0679ed322ddeb1fdafe6142463fdf Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:37:03 +0000 Subject: [PATCH 0084/5560] ASoC: soc-cache: Introduce raw bulk write support As it has become more common to have to write firmware or similar large chunks of data to the hardware, add a function to perform raw bulk writes that bypass the cache. This only handles volatile registers as we should avoid getting out of sync with the actual cache. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 3 +++ sound/soc/soc-cache.c | 39 +++++++++++++++++++++++++++++++++++++++ sound/soc/soc-core.c | 7 +++++++ 3 files changed, 49 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index bfa4836ea107..2f2a51fe78e9 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -543,6 +543,7 @@ struct snd_soc_codec { unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); + int (*bulk_write_raw)(struct snd_soc_codec *, unsigned int, const void *, size_t); void *reg_cache; const void *reg_def_copy; const struct snd_soc_cache_ops *cache_ops; @@ -814,6 +815,8 @@ struct soc_enum { unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); unsigned int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val); +unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec, + unsigned int reg, const void *data, size_t len); /* device driver data */ diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9f6737413a6e..8bcd4e1cee91 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -625,6 +625,44 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data, #define snd_soc_16_16_spi_write NULL #endif +/* Primitive bulk write support for soc-cache. The data pointed to by `data' needs + * to already be in the form the hardware expects including any leading register specific + * data. Any data written through this function will not go through the cache as it + * only handles writing to volatile or out of bounds registers. + */ +static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, + const void *data, size_t len) +{ + int ret; + + /* Ensure that the base register is volatile. Subsequently + * any other register that is touched by this routine should be + * volatile as well to ensure that we don't get out of sync with + * the cache. + */ + if (!snd_soc_codec_volatile_register(codec, reg) + && reg < codec->driver->reg_cache_size) + return -EINVAL; + + switch (codec->control_type) { + case SND_SOC_I2C: + ret = i2c_master_send(codec->control_data, data, len); + break; + case SND_SOC_SPI: + ret = do_spi_write(codec->control_data, data, len); + break; + default: + BUG(); + } + + if (ret == len) + return 0; + if (ret < 0) + return ret; + else + return -EIO; +} + static struct { int addr_bits; int data_bits; @@ -708,6 +746,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, codec->write = io_types[i].write; codec->read = io_types[i].read; + codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; switch (control) { case SND_SOC_CUSTOM: diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4dda58926bc5..636328e868e8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2228,6 +2228,13 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_write); +unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec, + unsigned int reg, const void *data, size_t len) +{ + return codec->bulk_write_raw(codec, reg, data, len); +} +EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw); + /** * snd_soc_update_bits - update codec register bits * @codec: audio codec -- GitLab From 67850a892bf627e1c627bc8d0bcd84b90ecc9d7f Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:36:57 +0000 Subject: [PATCH 0085/5560] ASoC: Add control_type in snd_soc_codec This is mainly used by the soc-cache code to easily determine the currently used underlying serial bus. Set SND_SOC_CUSTOM to 1 so we can distinguish it if it is not initialized or set. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 2f2a51fe78e9..4a11795aaee3 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -248,7 +248,7 @@ typedef int (*hw_write_t)(void *,const char* ,int); extern struct snd_ac97_bus_ops soc_ac97_ops; enum snd_soc_control_type { - SND_SOC_CUSTOM, + SND_SOC_CUSTOM = 1, SND_SOC_I2C, SND_SOC_SPI, }; @@ -539,6 +539,7 @@ struct snd_soc_codec { /* codec IO */ void *control_data; /* codec control (i2c/3wire) data */ + enum snd_soc_control_type control_type; hw_write_t hw_write; unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); unsigned int (*read)(struct snd_soc_codec *, unsigned int); -- GitLab From 26e9984cbcdde100e5af15382f2297fef1ce7804 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:36:58 +0000 Subject: [PATCH 0086/5560] ASoC: soc-cache: Factor-out the hw_write() specific code The handling of all snd_soc_x_y_write() functions is similar. Factor it out into a separate function and update all functions to use it. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 153 +++++++++--------------------------------- 1 file changed, 33 insertions(+), 120 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 8bcd4e1cee91..4ee473d6057a 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -20,6 +20,33 @@ #include +static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value, const void *data, int len) +{ + int ret; + + if (!snd_soc_codec_volatile_register(codec, reg) && + reg < codec->driver->reg_cache_size && + !codec->cache_bypass) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } + + if (codec->cache_only) { + codec->cache_sync = 1; + return 0; + } + + ret = codec->hw_write(codec->control_data, data, len); + if (ret == len) + return 0; + if (ret < 0) + return ret; + else + return -EIO; +} + static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) { @@ -46,31 +73,11 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[2]; - int ret; data[0] = (reg << 4) | ((value >> 8) & 0x000f); data[1] = value & 0x00ff; - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - - ret = codec->hw_write(codec->control_data, data, 2); - if (ret == 2) - return 0; - if (ret < 0) - return ret; - else - return -EIO; + return do_hw_write(codec, reg, value, data, 2); } #if defined(CONFIG_SPI_MASTER) @@ -129,31 +136,11 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[2]; - int ret; data[0] = (reg << 1) | ((value >> 8) & 0x0001); data[1] = value & 0x00ff; - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - - ret = codec->hw_write(codec->control_data, data, 2); - if (ret == 2) - return 0; - if (ret < 0) - return ret; - else - return -EIO; + return do_hw_write(codec, reg, value, data, 2); } #if defined(CONFIG_SPI_MASTER) @@ -190,29 +177,12 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[2]; - int ret; reg &= 0xff; data[0] = reg; data[1] = value & 0xff; - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; + return do_hw_write(codec, reg, value, data, 2); } static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, @@ -272,29 +242,12 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[3]; - int ret; data[0] = reg; data[1] = (value >> 8) & 0xff; data[2] = value & 0xff; - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - - if (codec->hw_write(codec->control_data, data, 3) == 3) - return 0; - else - return -EIO; + return do_hw_write(codec, reg, value, data, 3); } static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, @@ -460,33 +413,13 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[3]; - int ret; data[0] = (reg >> 8) & 0xff; data[1] = reg & 0xff; data[2] = value; - reg &= 0xff; - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - ret = codec->hw_write(codec->control_data, data, 3); - if (ret == 3) - return 0; - if (ret < 0) - return ret; - else - return -EIO; + return do_hw_write(codec, reg, value, data, 3); } #if defined(CONFIG_SPI_MASTER) @@ -564,33 +497,13 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { u8 data[4]; - int ret; data[0] = (reg >> 8) & 0xff; data[1] = reg & 0xff; data[2] = (value >> 8) & 0xff; data[3] = value & 0xff; - if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size && - !codec->cache_bypass) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret < 0) - return -1; - } - - if (codec->cache_only) { - codec->cache_sync = 1; - return 0; - } - - ret = codec->hw_write(codec->control_data, data, 4); - if (ret == 4) - return 0; - if (ret < 0) - return ret; - else - return -EIO; + return do_hw_write(codec, reg, value, data, 4); } #if defined(CONFIG_SPI_MASTER) -- GitLab From b8cbc195202d05efcda6af81c669577e3cb793e5 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:36:59 +0000 Subject: [PATCH 0087/5560] ASoC: soc-cache: Factor-out the hw_read() specific code The handling of all snd_soc_x_y_read() functions is similar. Factor it out into a separate function and update all callers. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 114 +++++++----------------------------------- 1 file changed, 18 insertions(+), 96 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 4ee473d6057a..abb0243f3adf 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -47,20 +47,19 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, return -EIO; } -static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, - unsigned int reg) +static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg) { int ret; unsigned int val; if (reg >= codec->driver->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg) || - codec->cache_bypass) { - if (codec->cache_only) - return -1; + snd_soc_codec_volatile_register(codec, reg) || + codec->cache_bypass) { + if (codec->cache_only) + return -1; - BUG_ON(!codec->hw_read); - return codec->hw_read(codec, reg); + BUG_ON(!codec->hw_read); + return codec->hw_read(codec, reg); } ret = snd_soc_cache_read(codec, reg, &val); @@ -69,6 +68,12 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, return val; } +static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + return do_hw_read(codec, reg); +} + static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { @@ -113,23 +118,7 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data, static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, unsigned int reg) { - int ret; - unsigned int val; - - if (reg >= codec->driver->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg) || - codec->cache_bypass) { - if (codec->cache_only) - return -1; - - BUG_ON(!codec->hw_read); - return codec->hw_read(codec, reg); - } - - ret = snd_soc_cache_read(codec, reg, &val); - if (ret < 0) - return -1; - return val; + return do_hw_read(codec, reg); } static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, @@ -188,24 +177,7 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, unsigned int reg) { - int ret; - unsigned int val; - - reg &= 0xff; - if (reg >= codec->driver->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg) || - codec->cache_bypass) { - if (codec->cache_only) - return -1; - - BUG_ON(!codec->hw_read); - return codec->hw_read(codec, reg); - } - - ret = snd_soc_cache_read(codec, reg, &val); - if (ret < 0) - return -1; - return val; + return do_hw_read(codec, reg); } #if defined(CONFIG_SPI_MASTER) @@ -253,23 +225,7 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, unsigned int reg) { - int ret; - unsigned int val; - - if (reg >= codec->driver->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg) || - codec->cache_bypass) { - if (codec->cache_only) - return -1; - - BUG_ON(!codec->hw_read); - return codec->hw_read(codec, reg); - } - - ret = snd_soc_cache_read(codec, reg, &val); - if (ret < 0) - return -1; - return val; + return do_hw_read(codec, reg); } #if defined(CONFIG_SPI_MASTER) @@ -389,24 +345,7 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, unsigned int reg) { - int ret; - unsigned int val; - - reg &= 0xff; - if (reg >= codec->driver->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg) || - codec->cache_bypass) { - if (codec->cache_only) - return -1; - - BUG_ON(!codec->hw_read); - return codec->hw_read(codec, reg); - } - - ret = snd_soc_cache_read(codec, reg, &val); - if (ret < 0) - return -1; - return val; + return do_hw_read(codec, reg); } static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, @@ -473,24 +412,7 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, unsigned int reg) { - int ret; - unsigned int val; - - if (reg >= codec->driver->reg_cache_size || - snd_soc_codec_volatile_register(codec, reg) || - codec->cache_bypass) { - if (codec->cache_only) - return -1; - - BUG_ON(!codec->hw_read); - return codec->hw_read(codec, reg); - } - - ret = snd_soc_cache_read(codec, reg, &val); - if (ret < 0) - return -1; - - return val; + return do_hw_read(codec, reg); } static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, -- GitLab From 30539a18d366cff6b21f66a81e4d9dccc4a90c89 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:37:00 +0000 Subject: [PATCH 0088/5560] ASoC: soc-cache: Factor-out the SPI write code The handling of all snd_soc_x_y_spi_write() functions is similar. Create a separate function and update all callers to use it. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 126 ++++++++++-------------------------------- 1 file changed, 30 insertions(+), 96 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index abb0243f3adf..d7bffdd033b0 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -20,6 +20,30 @@ #include +#if defined(CONFIG_SPI_MASTER) +static int do_spi_write(void *control_data, const void *msg, + int len) +{ + struct spi_device *spi = control_data; + struct spi_transfer t; + struct spi_message m; + + if (len <= 0) + return 0; + + spi_message_init(&m); + memset(&t, 0, sizeof t); + + t.tx_buf = msg; + t.len = len; + + spi_message_add_tail(&t, &m); + spi_sync(spi, &m); + + return len; +} +#endif + static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value, const void *data, int len) { @@ -89,27 +113,12 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, static int snd_soc_4_12_spi_write(void *control_data, const char *data, int len) { - struct spi_device *spi = control_data; - struct spi_transfer t; - struct spi_message m; u8 msg[2]; - if (len <= 0) - return 0; - msg[0] = data[1]; msg[1] = data[0]; - spi_message_init(&m); - memset(&t, 0, sizeof t); - - t.tx_buf = &msg[0]; - t.len = len; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return do_spi_write(control_data, msg, len); } #else #define snd_soc_4_12_spi_write NULL @@ -136,27 +145,12 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, static int snd_soc_7_9_spi_write(void *control_data, const char *data, int len) { - struct spi_device *spi = control_data; - struct spi_transfer t; - struct spi_message m; u8 msg[2]; - if (len <= 0) - return 0; - msg[0] = data[0]; msg[1] = data[1]; - spi_message_init(&m); - memset(&t, 0, sizeof t); - - t.tx_buf = &msg[0]; - t.len = len; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return do_spi_write(control_data, msg, len); } #else #define snd_soc_7_9_spi_write NULL @@ -184,27 +178,12 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, static int snd_soc_8_8_spi_write(void *control_data, const char *data, int len) { - struct spi_device *spi = control_data; - struct spi_transfer t; - struct spi_message m; u8 msg[2]; - if (len <= 0) - return 0; - msg[0] = data[0]; msg[1] = data[1]; - spi_message_init(&m); - memset(&t, 0, sizeof t); - - t.tx_buf = &msg[0]; - t.len = len; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return do_spi_write(control_data, msg, len); } #else #define snd_soc_8_8_spi_write NULL @@ -232,28 +211,13 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, static int snd_soc_8_16_spi_write(void *control_data, const char *data, int len) { - struct spi_device *spi = control_data; - struct spi_transfer t; - struct spi_message m; u8 msg[3]; - if (len <= 0) - return 0; - msg[0] = data[0]; msg[1] = data[1]; msg[2] = data[2]; - spi_message_init(&m); - memset(&t, 0, sizeof t); - - t.tx_buf = &msg[0]; - t.len = len; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return do_spi_write(control_data, msg, len); } #else #define snd_soc_8_16_spi_write NULL @@ -365,28 +329,13 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, static int snd_soc_16_8_spi_write(void *control_data, const char *data, int len) { - struct spi_device *spi = control_data; - struct spi_transfer t; - struct spi_message m; u8 msg[3]; - if (len <= 0) - return 0; - msg[0] = data[0]; msg[1] = data[1]; msg[2] = data[2]; - spi_message_init(&m); - memset(&t, 0, sizeof t); - - t.tx_buf = &msg[0]; - t.len = len; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return do_spi_write(control_data, msg, len); } #else #define snd_soc_16_8_spi_write NULL @@ -432,29 +381,14 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, static int snd_soc_16_16_spi_write(void *control_data, const char *data, int len) { - struct spi_device *spi = control_data; - struct spi_transfer t; - struct spi_message m; u8 msg[4]; - if (len <= 0) - return 0; - msg[0] = data[0]; msg[1] = data[1]; msg[2] = data[2]; msg[3] = data[3]; - spi_message_init(&m); - memset(&t, 0, sizeof t); - - t.tx_buf = &msg[0]; - t.len = len; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return do_spi_write(control_data, msg, len); } #else #define snd_soc_16_16_spi_write NULL -- GitLab From acd61451e55ea5848a6ab50d39a103e146fcf7ba Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 22 Mar 2011 10:48:49 +0000 Subject: [PATCH 0089/5560] ASoC: soc-cache: Return -ENOSYS instead of -EINVAL These functions fail with -EINVAL if the corresponding callbacks are not implemented. Change them to return -ENOSYS as it is more appropriate for unimplemented callbacks. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index d7bffdd033b0..258c3b2098b5 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1295,7 +1295,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) codec->cache_ops->name, codec->name); return codec->cache_ops->init(codec); } - return -EINVAL; + return -ENOSYS; } /* @@ -1310,7 +1310,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec) codec->cache_ops->name, codec->name); return codec->cache_ops->exit(codec); } - return -EINVAL; + return -ENOSYS; } /** @@ -1334,7 +1334,7 @@ int snd_soc_cache_read(struct snd_soc_codec *codec, } mutex_unlock(&codec->cache_rw_mutex); - return -EINVAL; + return -ENOSYS; } EXPORT_SYMBOL_GPL(snd_soc_cache_read); @@ -1359,7 +1359,7 @@ int snd_soc_cache_write(struct snd_soc_codec *codec, } mutex_unlock(&codec->cache_rw_mutex); - return -EINVAL; + return -ENOSYS; } EXPORT_SYMBOL_GPL(snd_soc_cache_write); @@ -1382,7 +1382,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) } if (!codec->cache_ops || !codec->cache_ops->sync) - return -EINVAL; + return -ENOSYS; if (codec->cache_ops->name) name = codec->cache_ops->name; -- GitLab From 8020454c9a1ec5ac5801805896b5f69d0c573e17 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 24 Mar 2011 13:45:17 +0000 Subject: [PATCH 0090/5560] ASoC: Add default snd_soc_default_writable_register() callback By using struct snd_soc_reg_access for the read/write/vol attributes of the registers, we provide callbacks that automatically determine whether a given register is readable/writable or volatile. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 4 ++++ sound/soc/soc-cache.c | 14 ++++++++++++++ sound/soc/soc-core.c | 3 +++ 3 files changed, 21 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 4a11795aaee3..e20835753c6b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -292,6 +292,8 @@ int snd_soc_default_volatile_register(struct snd_soc_codec *codec, unsigned int reg); int snd_soc_default_readable_register(struct snd_soc_codec *codec, unsigned int reg); +int snd_soc_default_writable_register(struct snd_soc_codec *codec, + unsigned int reg); /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); @@ -523,6 +525,7 @@ struct snd_soc_codec { size_t reg_size; /* reg_cache_size * reg_word_size */ int (*volatile_register)(struct snd_soc_codec *, unsigned int); int (*readable_register)(struct snd_soc_codec *, unsigned int); + int (*writable_register)(struct snd_soc_codec *, unsigned int); /* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ @@ -589,6 +592,7 @@ struct snd_soc_codec_driver { size_t, unsigned int); int (*volatile_register)(struct snd_soc_codec *, unsigned int); int (*readable_register)(struct snd_soc_codec *, unsigned int); + int (*writable_register)(struct snd_soc_codec *, unsigned int); short reg_cache_size; short reg_cache_step; short reg_word_size; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 258c3b2098b5..1210a6f70a90 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1449,3 +1449,17 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec, return codec->driver->reg_access_default[index].read; } EXPORT_SYMBOL_GPL(snd_soc_default_readable_register); + +int snd_soc_default_writable_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + int index; + + if (reg >= codec->driver->reg_cache_size) + return 1; + index = snd_soc_get_reg_access_index(codec, reg); + if (index < 0) + return 0; + return codec->driver->reg_access_default[index].write; +} +EXPORT_SYMBOL_GPL(snd_soc_default_writable_register); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 636328e868e8..074a0c6e99f4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3673,6 +3673,7 @@ int snd_soc_register_codec(struct device *dev, codec->read = codec_drv->read; codec->volatile_register = codec_drv->volatile_register; codec->readable_register = codec_drv->readable_register; + codec->writable_register = codec_drv->writable_register; codec->dapm.bias_level = SND_SOC_BIAS_OFF; codec->dapm.dev = dev; codec->dapm.codec = codec; @@ -3707,6 +3708,8 @@ int snd_soc_register_codec(struct device *dev, codec->volatile_register = snd_soc_default_volatile_register; if (!codec->readable_register) codec->readable_register = snd_soc_default_readable_register; + if (!codec->writable_register) + codec->writable_register = snd_soc_default_writable_register; } for (i = 0; i < num_dai; i++) { -- GitLab From 239c970626b9d9c7449de751d91f9a9da1018b85 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 24 Mar 2011 13:45:18 +0000 Subject: [PATCH 0091/5560] ASoC: Add snd_soc_codec_{readable,writable}_register() Provide the top level ASoC core functions for indicating whether a given register is readable or writable. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 4 ++++ sound/soc/soc-core.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index e20835753c6b..2720a9f3780b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -278,6 +278,10 @@ int snd_soc_register_codec(struct device *dev, void snd_soc_unregister_codec(struct device *dev); int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, unsigned int reg); +int snd_soc_codec_readable_register(struct snd_soc_codec *codec, + unsigned int reg); +int snd_soc_codec_writable_register(struct snd_soc_codec *codec, + unsigned int reg); int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, int addr_bits, int data_bits, enum snd_soc_control_type control); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 074a0c6e99f4..5ae70a107f1f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2146,6 +2146,42 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); +/** + * snd_soc_codec_readable_register: Report if a register is readable. + * + * @codec: CODEC to query. + * @reg: Register to query. + * + * Boolean function indicating if a CODEC register is readable. + */ +int snd_soc_codec_readable_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + if (codec->readable_register) + return codec->readable_register(codec, reg); + else + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register); + +/** + * snd_soc_codec_writable_register: Report if a register is writable. + * + * @codec: CODEC to query. + * @reg: Register to query. + * + * Boolean function indicating if a CODEC register is writable. + */ +int snd_soc_codec_writable_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + if (codec->writable_register) + return codec->writable_register(codec, reg); + else + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register); + /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec -- GitLab From 4b2ffc205cb9964e7270abc7c8bcbd6127dfcf5e Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Sat, 26 Mar 2011 03:05:08 -0400 Subject: [PATCH 0092/5560] ASoC: Blackfin I2S: add 8-bit sample support Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-i2s.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index d453b1e9d607..37d9d3c2f2b1 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -140,6 +140,10 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, bf5xx_i2s.tcr2 &= ~0x1f; bf5xx_i2s.rcr2 &= ~0x1f; switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + bf5xx_i2s->tcr2 |= 7; + bf5xx_i2s->rcr2 |= 7; + sport_handle->wdsize = 1; case SNDRV_PCM_FORMAT_S16_LE: bf5xx_i2s.tcr2 |= 15; bf5xx_i2s.rcr2 |= 15; @@ -266,8 +270,11 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai) SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ SNDRV_PCM_RATE_96000) -#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) +#define BF5XX_I2S_FORMATS \ + (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { .shutdown = bf5xx_i2s_shutdown, -- GitLab From 119bfef2f954bfca74a960bff7be7d49f97e5daf Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Sat, 26 Mar 2011 03:52:20 -0400 Subject: [PATCH 0093/5560] ASoC: ad193x: tweak style to match other codecs Rename the snd_soc_control_type field from "bus_type" to "control_type", and drop the now unused "control_data" field. Signed-off-by: Scott Jiang Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ad193x.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index da46479bfcfa..824529d5c776 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -23,8 +23,7 @@ /* codec private data */ struct ad193x_priv { - enum snd_soc_control_type bus_type; - void *control_data; + enum snd_soc_control_type control_type; int sysclk; }; @@ -354,14 +353,12 @@ static int ad193x_probe(struct snd_soc_codec *codec) struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - codec->control_data = ad193x->control_data; - if (ad193x->bus_type == SND_SOC_I2C) - ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type); + if (ad193x->control_type == SND_SOC_I2C) + ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type); else - ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type); + ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type); if (ret < 0) { - dev_err(codec->dev, "failed to set cache I/O: %d\n", - ret); + dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); return ret; } @@ -408,8 +405,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi) return -ENOMEM; spi_set_drvdata(spi, ad193x); - ad193x->control_data = spi; - ad193x->bus_type = SND_SOC_SPI; + ad193x->control_type = SND_SOC_SPI; ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x, &ad193x_dai, 1); @@ -454,8 +450,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client, return -ENOMEM; i2c_set_clientdata(client, ad193x); - ad193x->control_data = client; - ad193x->bus_type = SND_SOC_I2C; + ad193x->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x, &ad193x_dai, 1); -- GitLab From 5683dc7ae86987e392d5616731eec636abd6c7ad Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Sat, 26 Mar 2011 04:38:30 -0400 Subject: [PATCH 0094/5560] ASoC: ad73311: drop I2C requirement The AD73311 codec does not use I2C, so don't require it in Kconfig. Signed-off-by: Scott Jiang Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index d63c1754e05f..a9defd534456 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -17,7 +17,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI select SND_SOC_AD1980 if SND_SOC_AC97_BUS select SND_SOC_ADS117X - select SND_SOC_AD73311 if I2C + select SND_SOC_AD73311 select SND_SOC_AK4104 if SPI_MASTER select SND_SOC_AK4535 if I2C select SND_SOC_AK4642 if I2C -- GitLab From 95d517cfce023eb24c5363ab82377146bd659816 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 26 Mar 2011 23:39:07 +0000 Subject: [PATCH 0095/5560] viafb: gather common good, old VGA initialization in one place This patch moves all unprotected VGA initialization in one table and provides some documentation for those values. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 49 ++++++++++++++++++++++++++++--------- drivers/video/via/viamode.c | 19 -------------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 0098270ac425..5b9c096654be 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -308,6 +308,42 @@ static struct io_reg scaling_parameters[] = { {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ }; +static struct io_reg common_vga[] = { + {VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8) + [1] vertical display end (bit 8) + [2] vertical retrace start (bit 8) + [3] start vertical blanking (bit 8) + [4] line compare (bit 8) + [5] vertical total (bit 9) + [6] vertical display end (bit 9) + [7] vertical retrace start (bit 9) */ + {VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan + [5-6] byte panning */ + {VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line + [5] start vertical blanking (bit 9) + [6] line compare (bit 9) + [7] scan doubling */ + {VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start + [5] cursor disable */ + {VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end + [5-6] cursor skew */ + {VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */ + {VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */ + {VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end + [6] memory refresh bandwidth + [7] CRTC register protect enable */ + {VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location + [5] divide memory address clock by 4 + [6] double word addressing */ + {VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14 + [2] divide scan line clock by 2 + [3] divide memory address clock by 2 + [5] address wrap + [6] byte mode select + [7] sync enable */ + {VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */ +}; + static struct fifo_depth_select display_fifo_depth_reg = { /* IGA1 FIFO Depth_Select */ {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } }, @@ -1167,22 +1203,10 @@ static void load_fix_bit_crtc_reg(void) /* always set to 1 */ viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); /* line compare should set all bits = 1 (extend modes) */ - viafb_write_reg(CR18, VIACR, 0xff); - /* line compare should set all bits = 1 (extend modes) */ - viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4); - /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ - /* extend mode always set to e3h */ - viafb_write_reg(CR17, VIACR, 0xe3); - /* extend mode always set to 0h */ - viafb_write_reg(CR08, VIACR, 0x00); - /* extend mode always set to 0h */ - viafb_write_reg(CR14, VIACR, 0x00); - viafb_write_reg_mask(CR09, VIACR, 0x40, 0xDF); - viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6); viafb_lock_crt(); @@ -2353,6 +2377,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, outb(0x00, VIAAR); /* Write Common Setting for Video Mode */ + viafb_write_regx(common_vga, ARRAY_SIZE(common_vga)); switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 8c5bc41ff6a4..036ad3ab6b9d 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c @@ -30,10 +30,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIASR, SR1A, 0xFB, 0x08}, {VIASR, SR1E, 0x0F, 0x01}, {VIASR, SR2A, 0xFF, 0x00}, -{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ -{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ -{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ -{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ {VIACR, CR32, 0xFF, 0x00}, {VIACR, CR33, 0xFF, 0x00}, {VIACR, CR35, 0xFF, 0x00}, @@ -125,10 +121,6 @@ struct io_reg KM400_ModeXregs[] = { {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */ {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */ {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */ - {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ - {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ - {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ - {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ {VIACR, CR33, 0xFF, 0x00}, {VIACR, CR55, 0x80, 0x00}, {VIACR, CR5D, 0x80, 0x00}, @@ -162,10 +154,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIASR, SR1E, 0xFF, 0x01}, {VIASR, SR2A, 0xFF, 0x00}, {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ -{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ -{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ -{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ -{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ {VIACR, CR32, 0xFF, 0x00}, {VIACR, CR33, 0xFF, 0x00}, {VIACR, CR35, 0xFF, 0x00}, @@ -205,13 +193,6 @@ struct io_reg VX855_ModeXregs[] = { {VIASR, SR58, 0xFF, 0x00}, {VIASR, SR59, 0xFF, 0x00}, {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ -{VIACR, CR09, 0xFF, 0x00}, /* Initial CR09=0*/ -{VIACR, CR11, 0x8F, 0x00}, /* IGA1 initial Vertical end */ -{VIACR, CR17, 0x7F, 0x00}, /* IGA1 CRT Mode control init */ -{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ -{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ -{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ -{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ {VIACR, CR32, 0xFF, 0x00}, {VIACR, CR33, 0x7F, 0x00}, {VIACR, CR35, 0xFF, 0x00}, -- GitLab From 8e8ec596e6c0144e2dd500a57ee23dde9684df46 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Sun, 13 Mar 2011 16:54:26 +0800 Subject: [PATCH 0096/5560] crypto: caam - Add support for the Freescale SEC4/CAAM The SEC4 supercedes the SEC2.x/3.x as Freescale's Integrated Security Engine. Its programming model is incompatible with all prior versions of the SEC (talitos). The SEC4 is also known as the Cryptographic Accelerator and Assurance Module (CAAM); this driver is named caam. This initial submission does not include support for Data Path mode operation - AEAD descriptors are submitted via the job ring interface, while the Queue Interface (QI) is enabled for use by others. Only AEAD algorithms are implemented at this time, for use with IPsec. Many thanks to the Freescale STC team for their contributions to this driver. Signed-off-by: Steve Cornelius Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- .../devicetree/bindings/crypto/fsl-sec4.txt | 409 +++++ arch/powerpc/boot/dts/p4080ds.dts | 95 +- drivers/crypto/Kconfig | 2 + drivers/crypto/Makefile | 1 + drivers/crypto/caam/Kconfig | 72 + drivers/crypto/caam/Makefile | 8 + drivers/crypto/caam/caamalg.c | 1163 ++++++++++++ drivers/crypto/caam/compat.h | 35 + drivers/crypto/caam/ctrl.c | 270 +++ drivers/crypto/caam/desc.h | 1605 +++++++++++++++++ drivers/crypto/caam/desc_constr.h | 204 +++ drivers/crypto/caam/error.c | 248 +++ drivers/crypto/caam/error.h | 10 + drivers/crypto/caam/intern.h | 113 ++ drivers/crypto/caam/jr.c | 523 ++++++ drivers/crypto/caam/jr.h | 21 + drivers/crypto/caam/regs.h | 663 +++++++ 17 files changed, 5441 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/crypto/fsl-sec4.txt create mode 100644 drivers/crypto/caam/Kconfig create mode 100644 drivers/crypto/caam/Makefile create mode 100644 drivers/crypto/caam/caamalg.c create mode 100644 drivers/crypto/caam/compat.h create mode 100644 drivers/crypto/caam/ctrl.c create mode 100644 drivers/crypto/caam/desc.h create mode 100644 drivers/crypto/caam/desc_constr.h create mode 100644 drivers/crypto/caam/error.c create mode 100644 drivers/crypto/caam/error.h create mode 100644 drivers/crypto/caam/intern.h create mode 100644 drivers/crypto/caam/jr.c create mode 100644 drivers/crypto/caam/jr.h create mode 100644 drivers/crypto/caam/regs.h diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt new file mode 100644 index 000000000000..fce16a85e2c5 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt @@ -0,0 +1,409 @@ +===================================================================== +SEC 4 Device Tree Binding +Copyright (C) 2008-2011 Freescale Semiconductor Inc. + + CONTENTS + -Overview + -SEC 4 Node + -Job Ring Node + -Run Time Integrity Check (RTIC) Node + -Run Time Integrity Check (RTIC) Memory Node + -Secure Non-Volatile Storage (SNVS) Node + -Full Example + +NOTE: the SEC 4 is also known as Freescale's Cryptographic Accelerator +Accelerator and Assurance Module (CAAM). + +===================================================================== +Overview + +DESCRIPTION + +SEC 4 h/w can process requests from 2 types of sources. +1. DPAA Queue Interface (HW interface between Queue Manager & SEC 4). +2. Job Rings (HW interface between cores & SEC 4 registers). + +High Speed Data Path Configuration: + +HW interface between QM & SEC 4 and also BM & SEC 4, on DPAA-enabled parts +such as the P4080. The number of simultaneous dequeues the QI can make is +equal to the number of Descriptor Controller (DECO) engines in a particular +SEC version. E.g., the SEC 4.0 in the P4080 has 5 DECOs and can thus +dequeue from 5 subportals simultaneously. + +Job Ring Data Path Configuration: + +Each JR is located on a separate 4k page, they may (or may not) be made visible +in the memory partition devoted to a particular core. The P4080 has 4 JRs, so +up to 4 JRs can be configured; and all 4 JRs process requests in parallel. + +===================================================================== +P4080 SEC 4 Node + +Description + + Node defines the base address of the SEC 4 block. + This block specifies the address range of all global + configuration registers for the SEC 4 block. It + also receives interrupts from the Run Time Integrity Check + (RTIC) function within the SEC 4 block. + +PROPERTIES + + - compatible + Usage: required + Value type: + Definition: Must include "fsl,p4080-sec4.0","fsl,sec-4.0" + + - #address-cells + Usage: required + Value type: + Definition: A standard property. Defines the number of cells + for representing physical addresses in child nodes. + + - #size-cells + Usage: required + Value type: + Definition: A standard property. Defines the number of cells + for representing the size of physical addresses in + child nodes. + + - reg + Usage: required + Value type: + Definition: A standard property. Specifies the physical + address and length of the SEC4.0 configuration registers. + registers + + - ranges + Usage: required + Value type: + Definition: A standard property. Specifies the physical address + range of the SEC 4.0 register space (-SNVS not included). A + triplet that includes the child address, parent address, & + length. + + - interrupts + Usage: required + Value type: + Definition: Specifies the interrupts generated by this + device. The value of the interrupts property + consists of one interrupt specifier. The format + of the specifier is defined by the binding document + describing the node's interrupt parent. + + - interrupt-parent + Usage: (required if interrupt property is defined) + Value type: + Definition: A single value that points + to the interrupt parent to which the child domain + is being mapped. + + Note: All other standard properties (see the ePAPR) are allowed + but are optional. + + +EXAMPLE + crypto@300000 { + compatible = "fsl,p4080-sec4.0", "fsl,sec4.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x300000 0x10000>; + ranges = <0 0x300000 0x10000>; + interrupt-parent = <&mpic>; + interrupts = <92 2>; + }; + +===================================================================== +P4080 Job Ring (JR) Node + + Child of the crypto node defines data processing interface to SEC 4 + across the peripheral bus for purposes of processing + cryptographic descriptors. The specified address + range can be made visible to one (or more) cores. + The interrupt defined for this node is controlled within + the address range of this node. + + - compatible + Usage: required + Value type: + Definition: Must include "fsl,p4080-sec4.0-job-ring","fsl,sec4.0-job-ring" + + - reg + Usage: required + Value type: + Definition: Specifies a two JR parameters: an offset from + the parent physical address and the length the JR registers. + + - fsl,liodn + Usage: optional-but-recommended + Value type: + Definition: + Specifies the LIODN to be used in conjunction with + the ppid-to-liodn table that specifies the PPID to LIODN mapping. + Needed if the PAMU is used. Value is a 12 bit value + where value is a LIODN ID for this JR. This property is + normally set by boot firmware. + + - interrupts + Usage: required + Value type: + Definition: Specifies the interrupts generated by this + device. The value of the interrupts property + consists of one interrupt specifier. The format + of the specifier is defined by the binding document + describing the node's interrupt parent. + + - interrupt-parent + Usage: (required if interrupt property is defined) + Value type: + Definition: A single value that points + to the interrupt parent to which the child domain + is being mapped. + +EXAMPLE + jr@1000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x1000 0x1000>; + fsl,liodn = <0x081>; + interrupt-parent = <&mpic>; + interrupts = <88 2>; + }; + + +===================================================================== +P4080 Run Time Integrity Check (RTIC) Node + + Child node of the crypto node. Defines a register space that + contains up to 5 sets of addresses and their lengths (sizes) that + will be checked at run time. After an initial hash result is + calculated, these addresses are checked by HW to monitor any + change. If any memory is modified, a Security Violation is + triggered (see SNVS definition). + + + - compatible + Usage: required + Value type: + Definition: Must include "fsl,p4080-sec4.0-rtic","fsl,sec4.0-rtic". + + - #address-cells + Usage: required + Value type: + Definition: A standard property. Defines the number of cells + for representing physical addresses in child nodes. Must + have a value of 1. + + - #size-cells + Usage: required + Value type: + Definition: A standard property. Defines the number of cells + for representing the size of physical addresses in + child nodes. Must have a value of 1. + + - reg + Usage: required + Value type: + Definition: A standard property. Specifies a two parameters: + an offset from the parent physical address and the length + the SEC4 registers. + + - ranges + Usage: required + Value type: + Definition: A standard property. Specifies the physical address + range of the SEC 4 register space (-SNVS not included). A + triplet that includes the child address, parent address, & + length. + +EXAMPLE + rtic@6000 { + compatible = "fsl,p4080-sec4.0-rtic", + "fsl,sec4.0-rtic"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x6000 0x100>; + ranges = <0x0 0x6100 0xe00>; + }; + +===================================================================== +P4080 Run Time Integrity Check (RTIC) Memory Node + A child node that defines individual RTIC memory regions that are used to + perform run-time integrity check of memory areas that should not modified. + The node defines a register that contains the memory address & + length (combined) and a second register that contains the hash result + in big endian format. + + - compatible + Usage: required + Value type: + Definition: Must include "fsl,p4080-sec4.0-rtic-memory","fsl,sec4.0-rtic-memory". + + - reg + Usage: required + Value type: + Definition: A standard property. Specifies two parameters: + an offset from the parent physical address and the length: + + 1. The location of the RTIC memory address & length registers. + 2. The location RTIC hash result. + + - fsl,rtic-region + Usage: optional-but-recommended + Value type: + Definition: + Specifies the HW address (36 bit address) for this region + followed by the length of the HW partition to be checked; + the address is represented as a 64 bit quantity followed + by a 32 bit length. + + - fsl,liodn + Usage: optional-but-recommended + Value type: + Definition: + Specifies the LIODN to be used in conjunction with + the ppid-to-liodn table that specifies the PPID to LIODN + mapping. Needed if the PAMU is used. Value is a 12 bit value + where value is a LIODN ID for this RTIC memory region. This + property is normally set by boot firmware. + +EXAMPLE + rtic-a@0 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x00 0x20 0x100 0x80>; + fsl,liodn = <0x03c>; + fsl,rtic-region = <0x12345678 0x12345678 0x12345678>; + }; + +===================================================================== +P4080 Secure Non-Volatile Storage (SNVS) Node + + Node defines address range and the associated + interrupt for the SNVS function. This function + monitors security state information & reports + security violations. + + - compatible + Usage: required + Value type: + Definition: Must include "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon". + + - reg + Usage: required + Value type: + Definition: A standard property. Specifies the physical + address and length of the SEC4 configuration + registers. + + - interrupts + Usage: required + Value type: + Definition: Specifies the interrupts generated by this + device. The value of the interrupts property + consists of one interrupt specifier. The format + of the specifier is defined by the binding document + describing the node's interrupt parent. + + - interrupt-parent + Usage: (required if interrupt property is defined) + Value type: + Definition: A single value that points + to the interrupt parent to which the child domain + is being mapped. + +EXAMPLE + sec_mon@314000 { + compatible = "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon"; + reg = <0x314000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <93 2>; + }; + +===================================================================== +FULL EXAMPLE + + crypto: crypto@300000 { + compatible = "fsl,p4080-sec4.0", "fsl,sec4.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x300000 0x10000>; + ranges = <0 0x300000 0x10000>; + interrupt-parent = <&mpic>; + interrupts = <92 2>; + + sec_jr0: jr@1000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x1000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <88 2>; + }; + + sec_jr1: jr@2000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x2000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <89 2>; + }; + + sec_jr2: jr@3000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x3000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <90 2>; + }; + + sec_jr3: jr@4000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x4000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <91 2>; + }; + + rtic@6000 { + compatible = "fsl,p4080-sec4.0-rtic", + "fsl,sec4.0-rtic"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x6000 0x100>; + ranges = <0x0 0x6100 0xe00>; + + rtic_a: rtic-a@0 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x00 0x20 0x100 0x80>; + }; + + rtic_b: rtic-b@20 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x20 0x20 0x200 0x80>; + }; + + rtic_c: rtic-c@40 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x40 0x20 0x300 0x80>; + }; + + rtic_d: rtic-d@60 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x60 0x20 0x500 0x80>; + }; + }; + }; + + sec_mon: sec_mon@314000 { + compatible = "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon"; + reg = <0x314000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <93 2>; + }; + +===================================================================== diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts index 5b7fc29dd6cf..c78e80155019 100644 --- a/arch/powerpc/boot/dts/p4080ds.dts +++ b/arch/powerpc/boot/dts/p4080ds.dts @@ -1,7 +1,7 @@ /* * P4080DS Device Tree Source * - * Copyright 2009 Freescale Semiconductor Inc. + * Copyright 2009-2011 Freescale Semiconductor Inc. * * 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 @@ -33,6 +33,17 @@ dma1 = &dma1; sdhc = &sdhc; + crypto = &crypto; + sec_jr0 = &sec_jr0; + sec_jr1 = &sec_jr1; + sec_jr2 = &sec_jr2; + sec_jr3 = &sec_jr3; + rtic_a = &rtic_a; + rtic_b = &rtic_b; + rtic_c = &rtic_c; + rtic_d = &rtic_d; + sec_mon = &sec_mon; + rio0 = &rapidio0; }; @@ -410,6 +421,88 @@ dr_mode = "host"; phy_type = "ulpi"; }; + + crypto: crypto@300000 { + compatible = "fsl,p4080-sec4.0", "fsl,sec4.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x300000 0x10000>; + ranges = <0 0x300000 0x10000>; + interrupt-parent = <&mpic>; + interrupts = <92 2>; + + sec_jr0: jr@1000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x1000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <88 2>; + }; + + sec_jr1: jr@2000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x2000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <89 2>; + }; + + sec_jr2: jr@3000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x3000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <90 2>; + }; + + sec_jr3: jr@4000 { + compatible = "fsl,p4080-sec4.0-job-ring", + "fsl,sec4.0-job-ring"; + reg = <0x4000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <91 2>; + }; + + rtic@6000 { + compatible = "fsl,p4080-sec4.0-rtic", + "fsl,sec4.0-rtic"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x6000 0x100>; + ranges = <0x0 0x6100 0xe00>; + + rtic_a: rtic-a@0 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x00 0x20 0x100 0x80>; + }; + + rtic_b: rtic-b@20 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x20 0x20 0x200 0x80>; + }; + + rtic_c: rtic-c@40 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x40 0x20 0x300 0x80>; + }; + + rtic_d: rtic-d@60 { + compatible = "fsl,p4080-sec4.0-rtic-memory", + "fsl,sec4.0-rtic-memory"; + reg = <0x60 0x20 0x500 0x80>; + }; + }; + }; + + sec_mon: sec_mon@314000 { + compatible = "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon"; + reg = <0x314000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <93 2>; + }; }; rapidio0: rapidio@ffe0c0000 { diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index e54185223c8c..a27224aa883e 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -200,6 +200,8 @@ config CRYPTO_DEV_HIFN_795X_RNG Select this option if you want to enable the random number generator on the HIFN 795x crypto adapters. +source drivers/crypto/caam/Kconfig + config CRYPTO_DEV_TALITOS tristate "Talitos Freescale Security Engine (SEC)" select CRYPTO_ALGAPI diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 5203e34248d7..663c5efec13b 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -6,6 +6,7 @@ n2_crypto-y := n2_core.o n2_asm.o obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig new file mode 100644 index 000000000000..2d876bb98ff4 --- /dev/null +++ b/drivers/crypto/caam/Kconfig @@ -0,0 +1,72 @@ +config CRYPTO_DEV_FSL_CAAM + tristate "Freescale CAAM-Multicore driver backend" + depends on FSL_SOC + help + Enables the driver module for Freescale's Cryptographic Accelerator + and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). + This module adds a job ring operation interface, and configures h/w + to operate as a DPAA component automatically, depending + on h/w feature availability. + + To compile this driver as a module, choose M here: the module + will be called caam. + +config CRYPTO_DEV_FSL_CAAM_RINGSIZE + int "Job Ring size" + depends on CRYPTO_DEV_FSL_CAAM + range 2 9 + default "9" + help + Select size of Job Rings as a power of 2, within the + range 2-9 (ring size 4-512). + Examples: + 2 => 4 + 3 => 8 + 4 => 16 + 5 => 32 + 6 => 64 + 7 => 128 + 8 => 256 + 9 => 512 + +config CRYPTO_DEV_FSL_CAAM_INTC + bool "Job Ring interrupt coalescing" + depends on CRYPTO_DEV_FSL_CAAM + default y + help + Enable the Job Ring's interrupt coalescing feature. + +config CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD + int "Job Ring interrupt coalescing count threshold" + depends on CRYPTO_DEV_FSL_CAAM_INTC + range 1 255 + default 255 + help + Select number of descriptor completions to queue before + raising an interrupt, in the range 1-255. Note that a selection + of 1 functionally defeats the coalescing feature, and a selection + equal or greater than the job ring size will force timeouts. + +config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD + int "Job Ring interrupt coalescing timer threshold" + depends on CRYPTO_DEV_FSL_CAAM_INTC + range 1 65535 + default 2048 + help + Select number of bus clocks/64 to timeout in the case that one or + more descriptor completions are queued without reaching the count + threshold. Range is 1-65535. + +config CRYPTO_DEV_FSL_CAAM_CRYPTO_API + tristate "Register algorithm implementations with the Crypto API" + depends on CRYPTO_DEV_FSL_CAAM + default y + select CRYPTO_ALGAPI + select CRYPTO_AUTHENC + help + Selecting this will offload crypto for users of the + scatterlist crypto API (such as the linux native IPSec + stack) to the SEC4 via job ring. + + To compile this as a module, choose M here: the module + will be called caamalg. diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile new file mode 100644 index 000000000000..ef39011b4505 --- /dev/null +++ b/drivers/crypto/caam/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the CAAM backend and dependent components +# + +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o + +caam-objs := ctrl.o jr.o error.o diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c new file mode 100644 index 000000000000..d7fe3d3d7db9 --- /dev/null +++ b/drivers/crypto/caam/caamalg.c @@ -0,0 +1,1163 @@ +/* + * caam - Freescale FSL CAAM support for crypto API + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + * Based on talitos crypto API driver. + * + * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008): + * + * --------------- --------------- + * | JobDesc #1 |-------------------->| ShareDesc | + * | *(packet 1) | | (PDB) | + * --------------- |------------->| (hashKey) | + * . | | (cipherKey) | + * . | |-------->| (operation) | + * --------------- | | --------------- + * | JobDesc #2 |------| | + * | *(packet 2) | | + * --------------- | + * . | + * . | + * --------------- | + * | JobDesc #3 |------------ + * | *(packet 3) | + * --------------- + * + * The SharedDesc never changes for a connection unless rekeyed, but + * each packet will likely be in a different place. So all we need + * to know to process the packet is where the input is, where the + * output goes, and what context we want to process with. Context is + * in the SharedDesc, packet references in the JobDesc. + * + * So, a job desc looks like: + * + * --------------------- + * | Header | + * | ShareDesc Pointer | + * | SEQ_OUT_PTR | + * | (output buffer) | + * | SEQ_IN_PTR | + * | (input buffer) | + * | LOAD (to DECO) | + * --------------------- + */ + +#include "compat.h" + +#include "regs.h" +#include "intern.h" +#include "desc_constr.h" +#include "jr.h" +#include "error.h" + +/* + * crypto alg + */ +#define CAAM_CRA_PRIORITY 3000 +/* max key is sum of AES_MAX_KEY_SIZE, max split key size */ +#define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + \ + SHA512_DIGEST_SIZE * 2) +/* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ +#define CAAM_MAX_IV_LENGTH 16 + +#ifdef DEBUG +/* for print_hex_dumps with line references */ +#define xstr(s) str(s) +#define str(s) #s +#define debug(format, arg...) printk(format, arg) +#else +#define debug(format, arg...) +#endif + +/* + * per-session context + */ +struct caam_ctx { + struct device *jrdev; + u32 *sh_desc; + dma_addr_t shared_desc_phys; + u32 class1_alg_type; + u32 class2_alg_type; + u32 alg_op; + u8 *key; + dma_addr_t key_phys; + unsigned int keylen; + unsigned int enckeylen; + unsigned int authkeylen; + unsigned int split_key_len; + unsigned int split_key_pad_len; + unsigned int authsize; +}; + +static int aead_authenc_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) +{ + struct caam_ctx *ctx = crypto_aead_ctx(authenc); + + ctx->authsize = authsize; + + return 0; +} + +struct split_key_result { + struct completion completion; + int err; +}; + +static void split_key_done(struct device *dev, u32 *desc, u32 err, + void *context) +{ + struct split_key_result *res = context; + +#ifdef DEBUG + dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + if (err) { + char tmp[256]; + + dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + res->err = err; + + complete(&res->completion); +} + +/* +get a split ipad/opad key + +Split key generation----------------------------------------------- + +[00] 0xb0810008 jobdesc: stidx=1 share=never len=8 +[01] 0x04000014 key: class2->keyreg len=20 + @0xffe01000 +[03] 0x84410014 operation: cls2-op sha1 hmac init dec +[04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm +[05] 0xa4000001 jump: class2 local all ->1 [06] +[06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 + @0xffe04000 +*/ +static u32 gen_split_key(struct caam_ctx *ctx, const u8 *key_in, u32 authkeylen) +{ + struct device *jrdev = ctx->jrdev; + u32 *desc; + struct split_key_result result; + dma_addr_t dma_addr_in, dma_addr_out; + int ret = 0; + + desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); + + init_job_desc(desc, 0); + + dma_addr_in = dma_map_single(jrdev, (void *)key_in, authkeylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, dma_addr_in)) { + dev_err(jrdev, "unable to map key input memory\n"); + kfree(desc); + return -ENOMEM; + } + append_key(desc, dma_addr_in, authkeylen, CLASS_2 | + KEY_DEST_CLASS_REG); + + /* Sets MDHA up into an HMAC-INIT */ + append_operation(desc, ctx->alg_op | OP_ALG_DECRYPT | + OP_ALG_AS_INIT); + + /* + * do a FIFO_LOAD of zero, this will trigger the internal key expansion + into both pads inside MDHA + */ + append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); + + /* + * FIFO_STORE with the explicit split-key content store + * (0x26 output type) + */ + dma_addr_out = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len, + DMA_FROM_DEVICE); + if (dma_mapping_error(jrdev, dma_addr_out)) { + dev_err(jrdev, "unable to map key output memory\n"); + kfree(desc); + return -ENOMEM; + } + append_fifo_store(desc, dma_addr_out, ctx->split_key_len, + LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key_in, authkeylen, 1); + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); +#endif + + result.err = 0; + init_completion(&result.completion); + + ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); + if (!ret) { + /* in progress */ + wait_for_completion_interruptible(&result.completion); + ret = result.err; +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, + ctx->split_key_pad_len, 1); +#endif + } + + dma_unmap_single(jrdev, dma_addr_out, ctx->split_key_pad_len, + DMA_FROM_DEVICE); + dma_unmap_single(jrdev, dma_addr_in, authkeylen, DMA_TO_DEVICE); + + kfree(desc); + + return ret; +} + +static int build_sh_desc_ipsec(struct caam_ctx *ctx) +{ + struct device *jrdev = ctx->jrdev; + u32 *sh_desc; + u32 *jump_cmd; + + /* build shared descriptor for this session */ + sh_desc = kmalloc(CAAM_CMD_SZ * 4 + ctx->split_key_pad_len + + ctx->enckeylen, GFP_DMA | GFP_KERNEL); + if (!sh_desc) { + dev_err(jrdev, "could not allocate shared descriptor\n"); + return -ENOMEM; + } + + init_sh_desc(sh_desc, HDR_SAVECTX | HDR_SHARE_SERIAL); + + jump_cmd = append_jump(sh_desc, CLASS_BOTH | JUMP_TEST_ALL | + JUMP_COND_SHRD | JUMP_COND_SELF); + + /* process keys, starting with class 2/authentication */ + append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len, + ctx->split_key_len, + CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC); + + append_key_as_imm(sh_desc, (void *)ctx->key + ctx->split_key_pad_len, + ctx->enckeylen, ctx->enckeylen, + CLASS_1 | KEY_DEST_CLASS_REG); + + /* update jump cmd now that we are at the jump target */ + set_jump_tgt_here(sh_desc, jump_cmd); + + ctx->shared_desc_phys = dma_map_single(jrdev, sh_desc, + desc_bytes(sh_desc), + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->shared_desc_phys)) { + dev_err(jrdev, "unable to map shared descriptor\n"); + kfree(sh_desc); + return -ENOMEM; + } + + ctx->sh_desc = sh_desc; + + return 0; +} + +static int aead_authenc_setkey(struct crypto_aead *aead, + const u8 *key, unsigned int keylen) +{ + /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */ + static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + struct rtattr *rta = (void *)key; + struct crypto_authenc_key_param *param; + unsigned int authkeylen; + unsigned int enckeylen; + int ret = 0; + + param = RTA_DATA(rta); + enckeylen = be32_to_cpu(param->enckeylen); + + key += RTA_ALIGN(rta->rta_len); + keylen -= RTA_ALIGN(rta->rta_len); + + if (keylen < enckeylen) + goto badkey; + + authkeylen = keylen - enckeylen; + + if (keylen > CAAM_MAX_KEY_SIZE) + goto badkey; + + /* Pick class 2 key length from algorithm submask */ + ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> + OP_ALG_ALGSEL_SHIFT] * 2; + ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16); + +#ifdef DEBUG + printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n", + keylen, enckeylen, authkeylen); + printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n", + ctx->split_key_len, ctx->split_key_pad_len); + print_hex_dump(KERN_ERR, "key in @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); +#endif + ctx->key = kmalloc(ctx->split_key_pad_len + enckeylen, + GFP_KERNEL | GFP_DMA); + if (!ctx->key) { + dev_err(jrdev, "could not allocate key output memory\n"); + return -ENOMEM; + } + + ret = gen_split_key(ctx, key, authkeylen); + if (ret) { + kfree(ctx->key); + goto badkey; + } + + /* postpend encryption key to auth split key */ + memcpy(ctx->key + ctx->split_key_pad_len, key + authkeylen, enckeylen); + + ctx->key_phys = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len + + enckeylen, DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, ctx->key_phys)) { + dev_err(jrdev, "unable to map key i/o memory\n"); + kfree(ctx->key); + return -ENOMEM; + } +#ifdef DEBUG + print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, + ctx->split_key_pad_len + enckeylen, 1); +#endif + + ctx->keylen = keylen; + ctx->enckeylen = enckeylen; + ctx->authkeylen = authkeylen; + + ret = build_sh_desc_ipsec(ctx); + if (ret) { + dma_unmap_single(jrdev, ctx->key_phys, ctx->split_key_pad_len + + enckeylen, DMA_TO_DEVICE); + kfree(ctx->key); + } + + return ret; +badkey: + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; +} + +struct link_tbl_entry { + u64 ptr; + u32 len; + u8 reserved; + u8 buf_pool_id; + u16 offset; +}; + +/* + * ipsec_esp_edesc - s/w-extended ipsec_esp descriptor + * @src_nents: number of segments in input scatterlist + * @dst_nents: number of segments in output scatterlist + * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist + * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) + * @link_tbl_bytes: length of dma mapped link_tbl space + * @link_tbl_dma: bus physical mapped address of h/w link table + * @hw_desc: the h/w job descriptor followed by any referenced link tables + */ +struct ipsec_esp_edesc { + int assoc_nents; + int src_nents; + int dst_nents; + int link_tbl_bytes; + dma_addr_t link_tbl_dma; + struct link_tbl_entry *link_tbl; + u32 hw_desc[0]; +}; + +static void ipsec_esp_unmap(struct device *dev, + struct ipsec_esp_edesc *edesc, + struct aead_request *areq) +{ + dma_unmap_sg(dev, areq->assoc, edesc->assoc_nents, DMA_TO_DEVICE); + + if (unlikely(areq->dst != areq->src)) { + dma_unmap_sg(dev, areq->src, edesc->src_nents, + DMA_TO_DEVICE); + dma_unmap_sg(dev, areq->dst, edesc->dst_nents, + DMA_FROM_DEVICE); + } else { + dma_unmap_sg(dev, areq->src, edesc->src_nents, + DMA_BIDIRECTIONAL); + } + + if (edesc->link_tbl_bytes) + dma_unmap_single(dev, edesc->link_tbl_dma, + edesc->link_tbl_bytes, + DMA_TO_DEVICE); +} + +/* + * ipsec_esp descriptor callbacks + */ +static void ipsec_esp_encrypt_done(struct device *jrdev, u32 *desc, u32 err, + void *context) +{ + struct aead_request *areq = context; + struct ipsec_esp_edesc *edesc; +#ifdef DEBUG + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + int ivsize = crypto_aead_ivsize(aead); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + + dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + edesc = (struct ipsec_esp_edesc *)((char *)desc - + offsetof(struct ipsec_esp_edesc, hw_desc)); + + if (err) { + char tmp[256]; + + dev_err(jrdev, "%s\n", caam_jr_strstatus(tmp, err)); + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + ipsec_esp_unmap(jrdev, edesc, areq); + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "assoc @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->assoc), + areq->assoclen , 1); + print_hex_dump(KERN_ERR, "dstiv @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src) - ivsize, + edesc->src_nents ? 100 : ivsize, 1); + print_hex_dump(KERN_ERR, "dst @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src), + edesc->src_nents ? 100 : areq->cryptlen + + ctx->authsize + 4, 1); +#endif + + kfree(edesc); + + aead_request_complete(areq, err); +} + +static void ipsec_esp_decrypt_done(struct device *jrdev, u32 *desc, u32 err, + void *context) +{ + struct aead_request *areq = context; + struct ipsec_esp_edesc *edesc; +#ifdef DEBUG + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + + dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); +#endif + edesc = (struct ipsec_esp_edesc *)((char *)desc - + offsetof(struct ipsec_esp_edesc, hw_desc)); + + if (err) { + char tmp[256]; + + dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); + } + + ipsec_esp_unmap(jrdev, edesc, areq); + + /* + * verify hw auth check passed else return -EBADMSG + */ + if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK) + err = -EBADMSG; + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "iphdrout@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, + ((char *)sg_virt(areq->assoc) - sizeof(struct iphdr)), + sizeof(struct iphdr) + areq->assoclen + + ((areq->cryptlen > 1500) ? 1500 : areq->cryptlen) + + ctx->authsize + 36, 1); + if (!err && edesc->link_tbl_bytes) { + struct scatterlist *sg = sg_last(areq->src, edesc->src_nents); + print_hex_dump(KERN_ERR, "sglastout@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(sg), + sg->length + ctx->authsize + 16, 1); + } +#endif + kfree(edesc); + + aead_request_complete(areq, err); +} + +/* + * convert scatterlist to h/w link table format + * scatterlist must have been previously dma mapped + */ +static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, + struct link_tbl_entry *link_tbl_ptr, u32 offset) +{ + while (sg_count) { + link_tbl_ptr->ptr = sg_dma_address(sg); + link_tbl_ptr->len = sg_dma_len(sg); + link_tbl_ptr->reserved = 0; + link_tbl_ptr->buf_pool_id = 0; + link_tbl_ptr->offset = offset; + link_tbl_ptr++; + sg = sg_next(sg); + sg_count--; + } + + /* set Final bit (marks end of link table) */ + link_tbl_ptr--; + link_tbl_ptr->len |= 0x40000000; +} + +/* + * fill in and submit ipsec_esp job descriptor + */ +static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, + u32 encrypt, + void (*callback) (struct device *dev, u32 *desc, + u32 err, void *context)) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + u32 *desc = edesc->hw_desc, options; + int ret, sg_count, assoc_sg_count; + int ivsize = crypto_aead_ivsize(aead); + int authsize = ctx->authsize; + dma_addr_t ptr, dst_dma, src_dma; +#ifdef DEBUG + u32 *sh_desc = ctx->sh_desc; + + debug("assoclen %d cryptlen %d authsize %d\n", + areq->assoclen, areq->cryptlen, authsize); + print_hex_dump(KERN_ERR, "assoc @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->assoc), + areq->assoclen , 1); + print_hex_dump(KERN_ERR, "presciv@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src) - ivsize, + edesc->src_nents ? 100 : ivsize, 1); + print_hex_dump(KERN_ERR, "src @"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src), + edesc->src_nents ? 100 : areq->cryptlen + authsize, 1); + print_hex_dump(KERN_ERR, "shrdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, sh_desc, + desc_bytes(sh_desc), 1); +#endif + assoc_sg_count = dma_map_sg(jrdev, areq->assoc, edesc->assoc_nents ?: 1, + DMA_TO_DEVICE); + if (areq->src == areq->dst) + sg_count = dma_map_sg(jrdev, areq->src, edesc->src_nents ? : 1, + DMA_BIDIRECTIONAL); + else + sg_count = dma_map_sg(jrdev, areq->src, edesc->src_nents ? : 1, + DMA_TO_DEVICE); + + /* start auth operation */ + append_operation(desc, ctx->class2_alg_type | OP_ALG_AS_INITFINAL | + (encrypt ? : OP_ALG_ICV_ON)); + + /* Load FIFO with data for Class 2 CHA */ + options = FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG; + if (!edesc->assoc_nents) { + ptr = sg_dma_address(areq->assoc); + } else { + sg_to_link_tbl(areq->assoc, edesc->assoc_nents, + edesc->link_tbl, 0); + ptr = edesc->link_tbl_dma; + options |= LDST_SGF; + } + append_fifo_load(desc, ptr, areq->assoclen, options); + + /* copy iv from cipher/class1 input context to class2 infifo */ + append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ivsize); + + /* start class 1 (cipher) operation */ + append_operation(desc, ctx->class1_alg_type | OP_ALG_AS_INITFINAL | + encrypt); + + /* load payload & instruct to class2 to snoop class 1 if encrypting */ + options = 0; + if (!edesc->src_nents) { + src_dma = sg_dma_address(areq->src); + } else { + sg_to_link_tbl(areq->src, edesc->src_nents, edesc->link_tbl + + edesc->assoc_nents, 0); + src_dma = edesc->link_tbl_dma + edesc->assoc_nents * + sizeof(struct link_tbl_entry); + options |= LDST_SGF; + } + append_seq_in_ptr(desc, src_dma, areq->cryptlen + authsize, options); + append_seq_fifo_load(desc, areq->cryptlen, FIFOLD_CLASS_BOTH | + FIFOLD_TYPE_LASTBOTH | + (encrypt ? FIFOLD_TYPE_MSG1OUT2 + : FIFOLD_TYPE_MSG)); + + /* specify destination */ + if (areq->src == areq->dst) { + dst_dma = src_dma; + } else { + sg_count = dma_map_sg(jrdev, areq->dst, edesc->dst_nents ? : 1, + DMA_FROM_DEVICE); + if (!edesc->dst_nents) { + dst_dma = sg_dma_address(areq->dst); + options = 0; + } else { + sg_to_link_tbl(areq->dst, edesc->dst_nents, + edesc->link_tbl + edesc->assoc_nents + + edesc->src_nents, 0); + dst_dma = edesc->link_tbl_dma + (edesc->assoc_nents + + edesc->src_nents) * + sizeof(struct link_tbl_entry); + options = LDST_SGF; + } + } + append_seq_out_ptr(desc, dst_dma, areq->cryptlen + authsize, options); + append_seq_fifo_store(desc, areq->cryptlen, FIFOST_TYPE_MESSAGE_DATA); + + /* ICV */ + if (encrypt) + append_seq_store(desc, authsize, LDST_CLASS_2_CCB | + LDST_SRCDST_BYTE_CONTEXT); + else + append_seq_fifo_load(desc, authsize, FIFOLD_CLASS_CLASS2 | + FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV); + +#ifdef DEBUG + debug("job_desc_len %d\n", desc_len(desc)); + print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc) , 1); + print_hex_dump(KERN_ERR, "jdlinkt@"xstr(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, edesc->link_tbl, + edesc->link_tbl_bytes, 1); +#endif + + ret = caam_jr_enqueue(jrdev, desc, callback, areq); + if (!ret) + ret = -EINPROGRESS; + else { + ipsec_esp_unmap(jrdev, edesc, areq); + kfree(edesc); + } + + return ret; +} + +/* + * derive number of elements in scatterlist + */ +static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained) +{ + struct scatterlist *sg = sg_list; + int sg_nents = 0; + + *chained = 0; + while (nbytes > 0) { + sg_nents++; + nbytes -= sg->length; + if (!sg_is_last(sg) && (sg + 1)->length == 0) + *chained = 1; + sg = scatterwalk_sg_next(sg); + } + + return sg_nents; +} + +/* + * allocate and map the ipsec_esp extended descriptor + */ +static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, + int desc_bytes) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : + GFP_ATOMIC; + int assoc_nents, src_nents, dst_nents = 0, chained, link_tbl_bytes; + struct ipsec_esp_edesc *edesc; + + assoc_nents = sg_count(areq->assoc, areq->assoclen, &chained); + BUG_ON(chained); + if (likely(assoc_nents == 1)) + assoc_nents = 0; + + src_nents = sg_count(areq->src, areq->cryptlen + ctx->authsize, + &chained); + BUG_ON(chained); + if (src_nents == 1) + src_nents = 0; + + if (unlikely(areq->dst != areq->src)) { + dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize, + &chained); + BUG_ON(chained); + if (dst_nents == 1) + dst_nents = 0; + } + + link_tbl_bytes = (assoc_nents + src_nents + dst_nents) * + sizeof(struct link_tbl_entry); + debug("link_tbl_bytes %d\n", link_tbl_bytes); + + /* allocate space for base edesc and hw desc commands, link tables */ + edesc = kmalloc(sizeof(struct ipsec_esp_edesc) + desc_bytes + + link_tbl_bytes, GFP_DMA | flags); + if (!edesc) { + dev_err(jrdev, "could not allocate extended descriptor\n"); + return ERR_PTR(-ENOMEM); + } + + edesc->assoc_nents = assoc_nents; + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; + edesc->link_tbl = (void *)edesc + sizeof(struct ipsec_esp_edesc) + + desc_bytes; + edesc->link_tbl_dma = dma_map_single(jrdev, edesc->link_tbl, + link_tbl_bytes, DMA_TO_DEVICE); + edesc->link_tbl_bytes = link_tbl_bytes; + + return edesc; +} + +static int aead_authenc_encrypt(struct aead_request *areq) +{ + struct ipsec_esp_edesc *edesc; + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + int ivsize = crypto_aead_ivsize(aead); + u32 *desc; + dma_addr_t iv_dma; + + /* allocate extended descriptor */ + edesc = ipsec_esp_edesc_alloc(areq, 21 * sizeof(u32)); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + desc = edesc->hw_desc; + + /* insert shared descriptor pointer */ + init_job_desc_shared(desc, ctx->shared_desc_phys, + desc_len(ctx->sh_desc), HDR_SHARE_DEFER); + + iv_dma = dma_map_single(jrdev, areq->iv, ivsize, DMA_TO_DEVICE); + /* check dma error */ + + append_load(desc, iv_dma, ivsize, + LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT); + + return ipsec_esp(edesc, areq, OP_ALG_ENCRYPT, ipsec_esp_encrypt_done); +} + +static int aead_authenc_decrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + int ivsize = crypto_aead_ivsize(aead); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + struct ipsec_esp_edesc *edesc; + u32 *desc; + dma_addr_t iv_dma; + + req->cryptlen -= ctx->authsize; + + /* allocate extended descriptor */ + edesc = ipsec_esp_edesc_alloc(req, 21 * sizeof(u32)); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + desc = edesc->hw_desc; + + /* insert shared descriptor pointer */ + init_job_desc_shared(desc, ctx->shared_desc_phys, + desc_len(ctx->sh_desc), HDR_SHARE_DEFER); + + iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE); + /* check dma error */ + + append_load(desc, iv_dma, ivsize, + LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT); + + return ipsec_esp(edesc, req, !OP_ALG_ENCRYPT, ipsec_esp_decrypt_done); +} + +static int aead_authenc_givencrypt(struct aead_givcrypt_request *req) +{ + struct aead_request *areq = &req->areq; + struct ipsec_esp_edesc *edesc; + struct crypto_aead *aead = crypto_aead_reqtfm(areq); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + struct device *jrdev = ctx->jrdev; + int ivsize = crypto_aead_ivsize(aead); + dma_addr_t iv_dma; + u32 *desc; + + iv_dma = dma_map_single(jrdev, req->giv, ivsize, DMA_FROM_DEVICE); + + debug("%s: giv %p\n", __func__, req->giv); + + /* allocate extended descriptor */ + edesc = ipsec_esp_edesc_alloc(areq, 27 * sizeof(u32)); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + desc = edesc->hw_desc; + + /* insert shared descriptor pointer */ + init_job_desc_shared(desc, ctx->shared_desc_phys, + desc_len(ctx->sh_desc), HDR_SHARE_DEFER); + + /* + * LOAD IMM Info FIFO + * to DECO, Last, Padding, Random, Message, 16 bytes + */ + append_load_imm_u32(desc, NFIFOENTRY_DEST_DECO | NFIFOENTRY_LC1 | + NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DTYPE_MSG | + NFIFOENTRY_PTYPE_RND | ivsize, + LDST_SRCDST_WORD_INFO_FIFO); + + /* + * disable info fifo entries since the above serves as the entry + * this way, the MOVE command won't generate an entry. + * Note that this isn't required in more recent versions of + * SEC as a MOVE that doesn't do info FIFO entries is available. + */ + append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); + + /* MOVE DECO Alignment -> C1 Context 16 bytes */ + append_move(desc, MOVE_WAITCOMP | MOVE_SRC_INFIFO | + MOVE_DEST_CLASS1CTX | ivsize); + + /* re-enable info fifo entries */ + append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); + + /* MOVE C1 Context -> OFIFO 16 bytes */ + append_move(desc, MOVE_WAITCOMP | MOVE_SRC_CLASS1CTX | + MOVE_DEST_OUTFIFO | ivsize); + + append_fifo_store(desc, iv_dma, ivsize, FIFOST_TYPE_MESSAGE_DATA); + + return ipsec_esp(edesc, areq, OP_ALG_ENCRYPT, ipsec_esp_encrypt_done); +} + +struct caam_alg_template { + char name[CRYPTO_MAX_ALG_NAME]; + char driver_name[CRYPTO_MAX_ALG_NAME]; + unsigned int blocksize; + struct aead_alg aead; + u32 class1_alg_type; + u32 class2_alg_type; + u32 alg_op; +}; + +static struct caam_alg_template driver_algs[] = { + /* single-pass ipsec_esp descriptor */ + { + .name = "authenc(hmac(sha1),cbc(aes))", + .driver_name = "authenc-hmac-sha1-cbc-aes-caam", + .blocksize = AES_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, + }, + { + .name = "authenc(hmac(sha256),cbc(aes))", + .driver_name = "authenc-hmac-sha256-cbc-aes-caam", + .blocksize = AES_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA256 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, + }, + { + .name = "authenc(hmac(sha1),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam", + .blocksize = DES3_EDE_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, + }, + { + .name = "authenc(hmac(sha256),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam", + .blocksize = DES3_EDE_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA256 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, + }, + { + .name = "authenc(hmac(sha1),cbc(des))", + .driver_name = "authenc-hmac-sha1-cbc-des-caam", + .blocksize = DES_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, + }, + { + .name = "authenc(hmac(sha256),cbc(des))", + .driver_name = "authenc-hmac-sha256-cbc-des-caam", + .blocksize = DES_BLOCK_SIZE, + .aead = { + .setkey = aead_authenc_setkey, + .setauthsize = aead_authenc_setauthsize, + .encrypt = aead_authenc_encrypt, + .decrypt = aead_authenc_decrypt, + .givencrypt = aead_authenc_givencrypt, + .geniv = "", + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA256 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, + }, +}; + +struct caam_crypto_alg { + struct list_head entry; + struct device *ctrldev; + int class1_alg_type; + int class2_alg_type; + int alg_op; + struct crypto_alg crypto_alg; +}; + +static int caam_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + struct caam_crypto_alg *caam_alg = + container_of(alg, struct caam_crypto_alg, crypto_alg); + struct caam_ctx *ctx = crypto_tfm_ctx(tfm); + struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev); + int tgt_jr = atomic_inc_return(&priv->tfm_count); + + /* + * distribute tfms across job rings to ensure in-order + * crypto request processing per tfm + */ + ctx->jrdev = priv->algapi_jr[(tgt_jr / 2) % priv->num_jrs_for_algapi]; + + /* copy descriptor header template value */ + ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type; + ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam_alg->class2_alg_type; + ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_alg->alg_op; + + return 0; +} + +static void caam_cra_exit(struct crypto_tfm *tfm) +{ + struct caam_ctx *ctx = crypto_tfm_ctx(tfm); + + if (!dma_mapping_error(ctx->jrdev, ctx->shared_desc_phys)) + dma_unmap_single(ctx->jrdev, ctx->shared_desc_phys, + desc_bytes(ctx->sh_desc), DMA_TO_DEVICE); + kfree(ctx->sh_desc); +} + +static void __exit caam_algapi_exit(void) +{ + + struct device_node *dev_node; + struct platform_device *pdev; + struct device *ctrldev; + struct caam_drv_private *priv; + struct caam_crypto_alg *t_alg, *n; + int i, err; + + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); + if (!dev_node) + return; + + pdev = of_find_device_by_node(dev_node); + if (!pdev) + return; + + ctrldev = &pdev->dev; + of_node_put(dev_node); + priv = dev_get_drvdata(ctrldev); + + if (!priv->alg_list.next) + return; + + list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) { + crypto_unregister_alg(&t_alg->crypto_alg); + list_del(&t_alg->entry); + kfree(t_alg); + } + + for (i = 0; i < priv->total_jobrs; i++) { + err = caam_jr_deregister(priv->algapi_jr[i]); + if (err < 0) + break; + } + kfree(priv->algapi_jr); +} + +static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev, + struct caam_alg_template + *template) +{ + struct caam_crypto_alg *t_alg; + struct crypto_alg *alg; + + t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL); + if (!t_alg) { + dev_err(ctrldev, "failed to allocate t_alg\n"); + return ERR_PTR(-ENOMEM); + } + + alg = &t_alg->crypto_alg; + + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + alg->cra_module = THIS_MODULE; + alg->cra_init = caam_cra_init; + alg->cra_exit = caam_cra_exit; + alg->cra_priority = CAAM_CRA_PRIORITY; + alg->cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC; + alg->cra_blocksize = template->blocksize; + alg->cra_alignmask = 0; + alg->cra_type = &crypto_aead_type; + alg->cra_ctxsize = sizeof(struct caam_ctx); + alg->cra_u.aead = template->aead; + + t_alg->class1_alg_type = template->class1_alg_type; + t_alg->class2_alg_type = template->class2_alg_type; + t_alg->alg_op = template->alg_op; + t_alg->ctrldev = ctrldev; + + return t_alg; +} + +static int __init caam_algapi_init(void) +{ + struct device_node *dev_node; + struct platform_device *pdev; + struct device *ctrldev, **jrdev; + struct caam_drv_private *priv; + int i = 0, err = 0; + + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); + if (!dev_node) + return -ENODEV; + + pdev = of_find_device_by_node(dev_node); + if (!pdev) + return -ENODEV; + + ctrldev = &pdev->dev; + priv = dev_get_drvdata(ctrldev); + of_node_put(dev_node); + + INIT_LIST_HEAD(&priv->alg_list); + + jrdev = kmalloc(sizeof(*jrdev) * priv->total_jobrs, GFP_KERNEL); + if (!jrdev) + return -ENOMEM; + + for (i = 0; i < priv->total_jobrs; i++) { + err = caam_jr_register(ctrldev, &jrdev[i]); + if (err < 0) + break; + } + if (err < 0 && i == 0) { + dev_err(ctrldev, "algapi error in job ring registration: %d\n", + err); + return err; + } + + priv->num_jrs_for_algapi = i; + priv->algapi_jr = jrdev; + atomic_set(&priv->tfm_count, -1); + + /* register crypto algorithms the device supports */ + for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { + /* TODO: check if h/w supports alg */ + struct caam_crypto_alg *t_alg; + + t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]); + if (IS_ERR(t_alg)) { + err = PTR_ERR(t_alg); + dev_warn(ctrldev, "%s alg allocation failed\n", + t_alg->crypto_alg.cra_driver_name); + continue; + } + + err = crypto_register_alg(&t_alg->crypto_alg); + if (err) { + dev_warn(ctrldev, "%s alg registration failed\n", + t_alg->crypto_alg.cra_driver_name); + kfree(t_alg); + } else { + list_add_tail(&t_alg->entry, &priv->alg_list); + dev_info(ctrldev, "%s\n", + t_alg->crypto_alg.cra_driver_name); + } + } + + return err; +} + +module_init(caam_algapi_init); +module_exit(caam_algapi_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("FSL CAAM support for crypto API"); +MODULE_AUTHOR("Freescale Semiconductor - NMG/STC"); diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h new file mode 100644 index 000000000000..950450346f70 --- /dev/null +++ b/drivers/crypto/caam/compat.h @@ -0,0 +1,35 @@ +/* + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#ifndef CAAM_COMPAT_H +#define CAAM_COMPAT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#endif /* !defined(CAAM_COMPAT_H) */ diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c new file mode 100644 index 000000000000..aa2216160103 --- /dev/null +++ b/drivers/crypto/caam/ctrl.c @@ -0,0 +1,270 @@ +/* + * CAAM control-plane driver backend + * Controller-level driver, kernel property detection, initialization + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#include "compat.h" +#include "regs.h" +#include "intern.h" +#include "jr.h" + +static int caam_remove(struct platform_device *pdev) +{ + struct device *ctrldev; + struct caam_drv_private *ctrlpriv; + struct caam_drv_private_jr *jrpriv; + struct caam_full __iomem *topregs; + int ring, ret = 0; + + ctrldev = &pdev->dev; + ctrlpriv = dev_get_drvdata(ctrldev); + topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; + + /* shut down JobRs */ + for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { + ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]); + jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); + irq_dispose_mapping(jrpriv->irq); + } + + /* Shut down debug views */ +#ifdef CONFIG_DEBUG_FS + debugfs_remove_recursive(ctrlpriv->dfs_root); +#endif + + /* Unmap controller region */ + iounmap(&topregs->ctrl); + + kfree(ctrlpriv->jrdev); + kfree(ctrlpriv); + + return ret; +} + +/* Probe routine for CAAM top (controller) level */ +static int caam_probe(struct platform_device *pdev, + const struct of_device_id *devmatch) +{ + int d, ring, rspec; + struct device *dev; + struct device_node *nprop, *np; + struct caam_ctrl __iomem *ctrl; + struct caam_full __iomem *topregs; + struct caam_drv_private *ctrlpriv; + struct caam_perfmon *perfmon; + struct caam_deco **deco; + u32 deconum; + + ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL); + if (!ctrlpriv) + return -ENOMEM; + + dev = &pdev->dev; + dev_set_drvdata(dev, ctrlpriv); + ctrlpriv->pdev = pdev; + nprop = pdev->dev.of_node; + + /* Get configuration properties from device tree */ + /* First, get register page */ + ctrl = of_iomap(nprop, 0); + if (ctrl == NULL) { + dev_err(dev, "caam: of_iomap() failed\n"); + return -ENOMEM; + } + ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl; + + /* topregs used to derive pointers to CAAM sub-blocks only */ + topregs = (struct caam_full __iomem *)ctrl; + + /* Get the IRQ of the controller (for security violations only) */ + ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL); + + /* + * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, + * 36-bit pointers in master configuration register + */ + setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE | + (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); + + if (sizeof(dma_addr_t) == sizeof(u64)) + dma_set_mask(dev, DMA_BIT_MASK(36)); + + /* Find out how many DECOs are present */ + deconum = (rd_reg64(&topregs->ctrl.perfmon.cha_num) & + CHA_NUM_DECONUM_MASK) >> CHA_NUM_DECONUM_SHIFT; + + ctrlpriv->deco = kmalloc(deconum * sizeof(struct caam_deco *), + GFP_KERNEL); + + deco = (struct caam_deco __force **)&topregs->deco; + for (d = 0; d < deconum; d++) + ctrlpriv->deco[d] = deco[d]; + + /* + * Detect and enable JobRs + * First, find out how many ring spec'ed, allocate references + * for all, then go probe each one. + */ + rspec = 0; + for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") + rspec++; + ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL); + if (ctrlpriv->jrdev == NULL) { + iounmap(&topregs->ctrl); + return -ENOMEM; + } + + ring = 0; + ctrlpriv->total_jobrs = 0; + for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") { + caam_jr_probe(pdev, np, ring); + ctrlpriv->total_jobrs++; + ring++; + } + + /* Check to see if QI present. If so, enable */ + ctrlpriv->qi_present = !!(rd_reg64(&topregs->ctrl.perfmon.comp_parms) & + CTPR_QI_MASK); + if (ctrlpriv->qi_present) { + ctrlpriv->qi = (struct caam_queue_if __force *)&topregs->qi; + /* This is all that's required to physically enable QI */ + wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN); + } + + /* If no QI and no rings specified, quit and go home */ + if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) { + dev_err(dev, "no queues configured, terminating\n"); + caam_remove(pdev); + return -ENOMEM; + } + + /* NOTE: RTIC detection ought to go here, around Si time */ + + /* Initialize queue allocator lock */ + spin_lock_init(&ctrlpriv->jr_alloc_lock); + + /* Report "alive" for developer to see */ + dev_info(dev, "device ID = 0x%016llx\n", + rd_reg64(&topregs->ctrl.perfmon.caam_id)); + dev_info(dev, "job rings = %d, qi = %d\n", + ctrlpriv->total_jobrs, ctrlpriv->qi_present); + +#ifdef CONFIG_DEBUG_FS + /* + * FIXME: needs better naming distinction, as some amalgamation of + * "caam" and nprop->full_name. The OF name isn't distinctive, + * but does separate instances + */ + perfmon = (struct caam_perfmon __force *)&ctrl->perfmon; + + ctrlpriv->dfs_root = debugfs_create_dir("caam", NULL); + ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root); + + /* Controller-level - performance monitor counters */ + ctrlpriv->ctl_rq_dequeued = + debugfs_create_u64("rq_dequeued", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->req_dequeued); + ctrlpriv->ctl_ob_enc_req = + debugfs_create_u64("ob_rq_encrypted", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->ob_enc_req); + ctrlpriv->ctl_ib_dec_req = + debugfs_create_u64("ib_rq_decrypted", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->ib_dec_req); + ctrlpriv->ctl_ob_enc_bytes = + debugfs_create_u64("ob_bytes_encrypted", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->ob_enc_bytes); + ctrlpriv->ctl_ob_prot_bytes = + debugfs_create_u64("ob_bytes_protected", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->ob_prot_bytes); + ctrlpriv->ctl_ib_dec_bytes = + debugfs_create_u64("ib_bytes_decrypted", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->ib_dec_bytes); + ctrlpriv->ctl_ib_valid_bytes = + debugfs_create_u64("ib_bytes_validated", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->ib_valid_bytes); + + /* Controller level - global status values */ + ctrlpriv->ctl_faultaddr = + debugfs_create_u64("fault_addr", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->faultaddr); + ctrlpriv->ctl_faultdetail = + debugfs_create_u32("fault_detail", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->faultdetail); + ctrlpriv->ctl_faultstatus = + debugfs_create_u32("fault_status", + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, + ctrlpriv->ctl, &perfmon->status); + + /* Internal covering keys (useful in non-secure mode only) */ + ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0]; + ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32); + ctrlpriv->ctl_kek = debugfs_create_blob("kek", + S_IFCHR | S_IRUSR | + S_IRGRP | S_IROTH, + ctrlpriv->ctl, + &ctrlpriv->ctl_kek_wrap); + + ctrlpriv->ctl_tkek_wrap.data = &ctrlpriv->ctrl->tkek[0]; + ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32); + ctrlpriv->ctl_tkek = debugfs_create_blob("tkek", + S_IFCHR | S_IRUSR | + S_IRGRP | S_IROTH, + ctrlpriv->ctl, + &ctrlpriv->ctl_tkek_wrap); + + ctrlpriv->ctl_tdsk_wrap.data = &ctrlpriv->ctrl->tdsk[0]; + ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32); + ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk", + S_IFCHR | S_IRUSR | + S_IRGRP | S_IROTH, + ctrlpriv->ctl, + &ctrlpriv->ctl_tdsk_wrap); +#endif + return 0; +} + +static struct of_device_id caam_match[] = { + { + .compatible = "fsl,sec4.0", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, caam_match); + +static struct of_platform_driver caam_driver = { + .driver = { + .name = "caam", + .owner = THIS_MODULE, + .of_match_table = caam_match, + }, + .probe = caam_probe, + .remove = __devexit_p(caam_remove), +}; + +static int __init caam_base_init(void) +{ + return of_register_platform_driver(&caam_driver); +} + +static void __exit caam_base_exit(void) +{ + return of_unregister_platform_driver(&caam_driver); +} + +module_init(caam_base_init); +module_exit(caam_base_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("FSL CAAM request backend"); +MODULE_AUTHOR("Freescale Semiconductor - NMG/STC"); diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h new file mode 100644 index 000000000000..974a75842da9 --- /dev/null +++ b/drivers/crypto/caam/desc.h @@ -0,0 +1,1605 @@ +/* + * CAAM descriptor composition header + * Definitions to support CAAM descriptor instruction generation + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#ifndef DESC_H +#define DESC_H + +/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */ +#define MAX_CAAM_DESCSIZE 64 + +/* Block size of any entity covered/uncovered with a KEK/TKEK */ +#define KEK_BLOCKSIZE 16 + +/* + * Supported descriptor command types as they show up + * inside a descriptor command word. + */ +#define CMD_SHIFT 27 +#define CMD_MASK 0xf8000000 + +#define CMD_KEY (0x00 << CMD_SHIFT) +#define CMD_SEQ_KEY (0x01 << CMD_SHIFT) +#define CMD_LOAD (0x02 << CMD_SHIFT) +#define CMD_SEQ_LOAD (0x03 << CMD_SHIFT) +#define CMD_FIFO_LOAD (0x04 << CMD_SHIFT) +#define CMD_SEQ_FIFO_LOAD (0x05 << CMD_SHIFT) +#define CMD_STORE (0x0a << CMD_SHIFT) +#define CMD_SEQ_STORE (0x0b << CMD_SHIFT) +#define CMD_FIFO_STORE (0x0c << CMD_SHIFT) +#define CMD_SEQ_FIFO_STORE (0x0d << CMD_SHIFT) +#define CMD_MOVE_LEN (0x0e << CMD_SHIFT) +#define CMD_MOVE (0x0f << CMD_SHIFT) +#define CMD_OPERATION (0x10 << CMD_SHIFT) +#define CMD_SIGNATURE (0x12 << CMD_SHIFT) +#define CMD_JUMP (0x14 << CMD_SHIFT) +#define CMD_MATH (0x15 << CMD_SHIFT) +#define CMD_DESC_HDR (0x16 << CMD_SHIFT) +#define CMD_SHARED_DESC_HDR (0x17 << CMD_SHIFT) +#define CMD_SEQ_IN_PTR (0x1e << CMD_SHIFT) +#define CMD_SEQ_OUT_PTR (0x1f << CMD_SHIFT) + +/* General-purpose class selector for all commands */ +#define CLASS_SHIFT 25 +#define CLASS_MASK (0x03 << CLASS_SHIFT) + +#define CLASS_NONE (0x00 << CLASS_SHIFT) +#define CLASS_1 (0x01 << CLASS_SHIFT) +#define CLASS_2 (0x02 << CLASS_SHIFT) +#define CLASS_BOTH (0x03 << CLASS_SHIFT) + +/* + * Descriptor header command constructs + * Covers shared, job, and trusted descriptor headers + */ + +/* + * Do Not Run - marks a descriptor inexecutable if there was + * a preceding error somewhere + */ +#define HDR_DNR 0x01000000 + +/* + * ONE - should always be set. Combination of ONE (always + * set) and ZRO (always clear) forms an endianness sanity check + */ +#define HDR_ONE 0x00800000 +#define HDR_ZRO 0x00008000 + +/* Start Index or SharedDesc Length */ +#define HDR_START_IDX_MASK 0x3f +#define HDR_START_IDX_SHIFT 16 + +/* If shared descriptor header, 6-bit length */ +#define HDR_DESCLEN_SHR_MASK 0x3f + +/* If non-shared header, 7-bit length */ +#define HDR_DESCLEN_MASK 0x7f + +/* This is a TrustedDesc (if not SharedDesc) */ +#define HDR_TRUSTED 0x00004000 + +/* Make into TrustedDesc (if not SharedDesc) */ +#define HDR_MAKE_TRUSTED 0x00002000 + +/* Save context if self-shared (if SharedDesc) */ +#define HDR_SAVECTX 0x00001000 + +/* Next item points to SharedDesc */ +#define HDR_SHARED 0x00001000 + +/* + * Reverse Execution Order - execute JobDesc first, then + * execute SharedDesc (normally SharedDesc goes first). + */ +#define HDR_REVERSE 0x00000800 + +/* Propogate DNR property to SharedDesc */ +#define HDR_PROP_DNR 0x00000800 + +/* JobDesc/SharedDesc share property */ +#define HDR_SD_SHARE_MASK 0x03 +#define HDR_SD_SHARE_SHIFT 8 +#define HDR_JD_SHARE_MASK 0x07 +#define HDR_JD_SHARE_SHIFT 8 + +#define HDR_SHARE_NEVER (0x00 << HDR_SD_SHARE_SHIFT) +#define HDR_SHARE_WAIT (0x01 << HDR_SD_SHARE_SHIFT) +#define HDR_SHARE_SERIAL (0x02 << HDR_SD_SHARE_SHIFT) +#define HDR_SHARE_ALWAYS (0x03 << HDR_SD_SHARE_SHIFT) +#define HDR_SHARE_DEFER (0x04 << HDR_SD_SHARE_SHIFT) + +/* JobDesc/SharedDesc descriptor length */ +#define HDR_JD_LENGTH_MASK 0x7f +#define HDR_SD_LENGTH_MASK 0x3f + +/* + * KEY/SEQ_KEY Command Constructs + */ + +/* Key Destination Class: 01 = Class 1, 02 - Class 2 */ +#define KEY_DEST_CLASS_SHIFT 25 /* use CLASS_1 or CLASS_2 */ +#define KEY_DEST_CLASS_MASK (0x03 << KEY_DEST_CLASS_SHIFT) + +/* Scatter-Gather Table/Variable Length Field */ +#define KEY_SGF 0x01000000 +#define KEY_VLF 0x01000000 + +/* Immediate - Key follows command in the descriptor */ +#define KEY_IMM 0x00800000 + +/* + * Encrypted - Key is encrypted either with the KEK, or + * with the TDKEK if TK is set + */ +#define KEY_ENC 0x00400000 + +/* + * No Write Back - Do not allow key to be FIFO STOREd + */ +#define KEY_NWB 0x00200000 + +/* + * Enhanced Encryption of Key + */ +#define KEY_EKT 0x00100000 + +/* + * Encrypted with Trusted Key + */ +#define KEY_TK 0x00008000 + +/* + * KDEST - Key Destination: 0 - class key register, + * 1 - PKHA 'e', 2 - AFHA Sbox, 3 - MDHA split-key + */ +#define KEY_DEST_SHIFT 16 +#define KEY_DEST_MASK (0x03 << KEY_DEST_SHIFT) + +#define KEY_DEST_CLASS_REG (0x00 << KEY_DEST_SHIFT) +#define KEY_DEST_PKHA_E (0x01 << KEY_DEST_SHIFT) +#define KEY_DEST_AFHA_SBOX (0x02 << KEY_DEST_SHIFT) +#define KEY_DEST_MDHA_SPLIT (0x03 << KEY_DEST_SHIFT) + +/* Length in bytes */ +#define KEY_LENGTH_MASK 0x000003ff + +/* + * LOAD/SEQ_LOAD/STORE/SEQ_STORE Command Constructs + */ + +/* + * Load/Store Destination: 0 = class independent CCB, + * 1 = class 1 CCB, 2 = class 2 CCB, 3 = DECO + */ +#define LDST_CLASS_SHIFT 25 +#define LDST_CLASS_MASK (0x03 << LDST_CLASS_SHIFT) +#define LDST_CLASS_IND_CCB (0x00 << LDST_CLASS_SHIFT) +#define LDST_CLASS_1_CCB (0x01 << LDST_CLASS_SHIFT) +#define LDST_CLASS_2_CCB (0x02 << LDST_CLASS_SHIFT) +#define LDST_CLASS_DECO (0x03 << LDST_CLASS_SHIFT) + +/* Scatter-Gather Table/Variable Length Field */ +#define LDST_SGF 0x01000000 +#define LDST_VLF LDST_SGF + +/* Immediate - Key follows this command in descriptor */ +#define LDST_IMM_MASK 1 +#define LDST_IMM_SHIFT 23 +#define LDST_IMM (LDST_IMM_MASK << LDST_IMM_SHIFT) + +/* SRC/DST - Destination for LOAD, Source for STORE */ +#define LDST_SRCDST_SHIFT 16 +#define LDST_SRCDST_MASK (0x7f << LDST_SRCDST_SHIFT) + +#define LDST_SRCDST_BYTE_CONTEXT (0x20 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_BYTE_KEY (0x40 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_BYTE_INFIFO (0x7c << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_BYTE_OUTFIFO (0x7e << LDST_SRCDST_SHIFT) + +#define LDST_SRCDST_WORD_MODE_REG (0x00 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_KEYSZ_REG (0x01 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DATASZ_REG (0x02 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_ICVSZ_REG (0x03 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_CHACTRL (0x06 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECOCTRL (0x06 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_IRQCTRL (0x07 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECO_PCLOVRD (0x07 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_CLRW (0x08 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECO_MATH0 (0x08 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_STAT (0x09 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECO_MATH1 (0x09 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECO_MATH2 (0x0a << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECO_AAD_SZ (0x0b << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DECO_MATH3 (0x0b << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_CLASS1_ICV_SZ (0x0c << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_ALTDS_CLASS1 (0x0f << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_PKHA_A_SZ (0x10 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_PKHA_B_SZ (0x11 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_PKHA_N_SZ (0x12 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_PKHA_E_SZ (0x13 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_DESCBUF (0x40 << LDST_SRCDST_SHIFT) +#define LDST_SRCDST_WORD_INFO_FIFO (0x7a << LDST_SRCDST_SHIFT) + +/* Offset in source/destination */ +#define LDST_OFFSET_SHIFT 8 +#define LDST_OFFSET_MASK (0xff << LDST_OFFSET_SHIFT) + +/* LDOFF definitions used when DST = LDST_SRCDST_WORD_DECOCTRL */ +/* These could also be shifted by LDST_OFFSET_SHIFT - this reads better */ +#define LDOFF_CHG_SHARE_SHIFT 0 +#define LDOFF_CHG_SHARE_MASK (0x3 << LDOFF_CHG_SHARE_SHIFT) +#define LDOFF_CHG_SHARE_NEVER (0x1 << LDOFF_CHG_SHARE_SHIFT) +#define LDOFF_CHG_SHARE_OK_NO_PROP (0x2 << LDOFF_CHG_SHARE_SHIFT) +#define LDOFF_CHG_SHARE_OK_PROP (0x3 << LDOFF_CHG_SHARE_SHIFT) + +#define LDOFF_ENABLE_AUTO_NFIFO (1 << 2) +#define LDOFF_DISABLE_AUTO_NFIFO (1 << 3) + +#define LDOFF_CHG_NONSEQLIODN_SHIFT 4 +#define LDOFF_CHG_NONSEQLIODN_MASK (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT) +#define LDOFF_CHG_NONSEQLIODN_SEQ (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT) +#define LDOFF_CHG_NONSEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT) +#define LDOFF_CHG_NONSEQLIODN_TRUSTED (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT) + +#define LDOFF_CHG_SEQLIODN_SHIFT 6 +#define LDOFF_CHG_SEQLIODN_MASK (0x3 << LDOFF_CHG_SEQLIODN_SHIFT) +#define LDOFF_CHG_SEQLIODN_SEQ (0x1 << LDOFF_CHG_SEQLIODN_SHIFT) +#define LDOFF_CHG_SEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_SEQLIODN_SHIFT) +#define LDOFF_CHG_SEQLIODN_TRUSTED (0x3 << LDOFF_CHG_SEQLIODN_SHIFT) + +/* Data length in bytes */ +#define LDST_LEN_SHIFT 0 +#define LDST_LEN_MASK (0xff << LDST_LEN_SHIFT) + +/* Special Length definitions when dst=deco-ctrl */ +#define LDLEN_ENABLE_OSL_COUNT (1 << 7) +#define LDLEN_RST_CHA_OFIFO_PTR (1 << 6) +#define LDLEN_RST_OFIFO (1 << 5) +#define LDLEN_SET_OFIFO_OFF_VALID (1 << 4) +#define LDLEN_SET_OFIFO_OFF_RSVD (1 << 3) +#define LDLEN_SET_OFIFO_OFFSET_SHIFT 0 +#define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT) + +/* + * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE + * Command Constructs + */ + +/* + * Load Destination: 0 = skip (SEQ_FIFO_LOAD only), + * 1 = Load for Class1, 2 = Load for Class2, 3 = Load both + * Store Source: 0 = normal, 1 = Class1key, 2 = Class2key + */ +#define FIFOLD_CLASS_SHIFT 25 +#define FIFOLD_CLASS_MASK (0x03 << FIFOLD_CLASS_SHIFT) +#define FIFOLD_CLASS_SKIP (0x00 << FIFOLD_CLASS_SHIFT) +#define FIFOLD_CLASS_CLASS1 (0x01 << FIFOLD_CLASS_SHIFT) +#define FIFOLD_CLASS_CLASS2 (0x02 << FIFOLD_CLASS_SHIFT) +#define FIFOLD_CLASS_BOTH (0x03 << FIFOLD_CLASS_SHIFT) + +#define FIFOST_CLASS_SHIFT 25 +#define FIFOST_CLASS_MASK (0x03 << FIFOST_CLASS_SHIFT) +#define FIFOST_CLASS_NORMAL (0x00 << FIFOST_CLASS_SHIFT) +#define FIFOST_CLASS_CLASS1KEY (0x01 << FIFOST_CLASS_SHIFT) +#define FIFOST_CLASS_CLASS2KEY (0x02 << FIFOST_CLASS_SHIFT) + +/* + * Scatter-Gather Table/Variable Length Field + * If set for FIFO_LOAD, refers to a SG table. Within + * SEQ_FIFO_LOAD, is variable input sequence + */ +#define FIFOLDST_SGF_SHIFT 24 +#define FIFOLDST_SGF_MASK (1 << FIFOLDST_SGF_SHIFT) +#define FIFOLDST_VLF_MASK (1 << FIFOLDST_SGF_SHIFT) +#define FIFOLDST_SGF (1 << FIFOLDST_SGF_SHIFT) +#define FIFOLDST_VLF (1 << FIFOLDST_SGF_SHIFT) + +/* Immediate - Data follows command in descriptor */ +#define FIFOLD_IMM_SHIFT 23 +#define FIFOLD_IMM_MASK (1 << FIFOLD_IMM_SHIFT) +#define FIFOLD_IMM (1 << FIFOLD_IMM_SHIFT) + +/* Continue - Not the last FIFO store to come */ +#define FIFOST_CONT_SHIFT 23 +#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT) +#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT) + +/* + * Extended Length - use 32-bit extended length that + * follows the pointer field. Illegal with IMM set + */ +#define FIFOLDST_EXT_SHIFT 22 +#define FIFOLDST_EXT_MASK (1 << FIFOLDST_EXT_SHIFT) +#define FIFOLDST_EXT (1 << FIFOLDST_EXT_SHIFT) + +/* Input data type.*/ +#define FIFOLD_TYPE_SHIFT 16 +#define FIFOLD_CONT_TYPE_SHIFT 19 /* shift past last-flush bits */ +#define FIFOLD_TYPE_MASK (0x3f << FIFOLD_TYPE_SHIFT) + +/* PK types */ +#define FIFOLD_TYPE_PK (0x00 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_MASK (0x30 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_TYPEMASK (0x0f << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_A0 (0x00 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_A1 (0x01 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_A2 (0x02 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_A3 (0x03 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_B0 (0x04 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_B1 (0x05 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_B2 (0x06 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_B3 (0x07 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_N (0x08 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_A (0x0c << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_PK_B (0x0d << FIFOLD_TYPE_SHIFT) + +/* Other types. Need to OR in last/flush bits as desired */ +#define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_MSG (0x10 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_MSG1OUT2 (0x18 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_IV (0x20 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_BITDATA (0x28 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_AAD (0x30 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_ICV (0x38 << FIFOLD_TYPE_SHIFT) + +/* Last/Flush bits for use with "other" types above */ +#define FIFOLD_TYPE_ACT_MASK (0x07 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_NOACTION (0x00 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_FLUSH1 (0x01 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_LAST1 (0x02 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_LAST2FLUSH (0x03 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_LAST2 (0x04 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_LASTBOTH (0x06 << FIFOLD_TYPE_SHIFT) +#define FIFOLD_TYPE_LASTBOTHFL (0x07 << FIFOLD_TYPE_SHIFT) + +#define FIFOLDST_LEN_MASK 0xffff +#define FIFOLDST_EXT_LEN_MASK 0xffffffff + +/* Output data types */ +#define FIFOST_TYPE_SHIFT 16 +#define FIFOST_TYPE_MASK (0x3f << FIFOST_TYPE_SHIFT) + +#define FIFOST_TYPE_PKHA_A0 (0x00 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_A1 (0x01 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_A2 (0x02 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_A3 (0x03 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_B0 (0x04 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_B1 (0x05 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_B2 (0x06 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_B3 (0x07 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_AF_SBOX_JKEK (0x10 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_PKHA_E_TKEK (0x23 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_KEY_KEK (0x24 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_KEY_TKEK (0x25 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_SPLIT_KEK (0x26 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_SPLIT_TKEK (0x27 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_OUTFIFO_KEK (0x28 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_OUTFIFO_TKEK (0x29 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_RNGSTORE (0x34 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_RNGFIFO (0x35 << FIFOST_TYPE_SHIFT) +#define FIFOST_TYPE_SKIP (0x3f << FIFOST_TYPE_SHIFT) + +/* + * OPERATION Command Constructs + */ + +/* Operation type selectors - OP TYPE */ +#define OP_TYPE_SHIFT 24 +#define OP_TYPE_MASK (0x07 << OP_TYPE_SHIFT) + +#define OP_TYPE_UNI_PROTOCOL (0x00 << OP_TYPE_SHIFT) +#define OP_TYPE_PK (0x01 << OP_TYPE_SHIFT) +#define OP_TYPE_CLASS1_ALG (0x02 << OP_TYPE_SHIFT) +#define OP_TYPE_CLASS2_ALG (0x04 << OP_TYPE_SHIFT) +#define OP_TYPE_DECAP_PROTOCOL (0x06 << OP_TYPE_SHIFT) +#define OP_TYPE_ENCAP_PROTOCOL (0x07 << OP_TYPE_SHIFT) + +/* ProtocolID selectors - PROTID */ +#define OP_PCLID_SHIFT 16 +#define OP_PCLID_MASK (0xff << 16) + +/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */ +#define OP_PCLID_IKEV1_PRF (0x01 << OP_PCLID_SHIFT) +#define OP_PCLID_IKEV2_PRF (0x02 << OP_PCLID_SHIFT) +#define OP_PCLID_SSL30_PRF (0x08 << OP_PCLID_SHIFT) +#define OP_PCLID_TLS10_PRF (0x09 << OP_PCLID_SHIFT) +#define OP_PCLID_TLS11_PRF (0x0a << OP_PCLID_SHIFT) +#define OP_PCLID_DTLS10_PRF (0x0c << OP_PCLID_SHIFT) +#define OP_PCLID_PRF (0x06 << OP_PCLID_SHIFT) +#define OP_PCLID_BLOB (0x0d << OP_PCLID_SHIFT) +#define OP_PCLID_SECRETKEY (0x11 << OP_PCLID_SHIFT) +#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT) +#define OP_PCLID_DSASIGN (0x15 << OP_PCLID_SHIFT) +#define OP_PCLID_DSAVERIFY (0x16 << OP_PCLID_SHIFT) + +/* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */ +#define OP_PCLID_IPSEC (0x01 << OP_PCLID_SHIFT) +#define OP_PCLID_SRTP (0x02 << OP_PCLID_SHIFT) +#define OP_PCLID_MACSEC (0x03 << OP_PCLID_SHIFT) +#define OP_PCLID_WIFI (0x04 << OP_PCLID_SHIFT) +#define OP_PCLID_WIMAX (0x05 << OP_PCLID_SHIFT) +#define OP_PCLID_SSL30 (0x08 << OP_PCLID_SHIFT) +#define OP_PCLID_TLS10 (0x09 << OP_PCLID_SHIFT) +#define OP_PCLID_TLS11 (0x0a << OP_PCLID_SHIFT) +#define OP_PCLID_TLS12 (0x0b << OP_PCLID_SHIFT) +#define OP_PCLID_DTLS (0x0c << OP_PCLID_SHIFT) + +/* + * ProtocolInfo selectors + */ +#define OP_PCLINFO_MASK 0xffff + +/* for OP_PCLID_IPSEC */ +#define OP_PCL_IPSEC_CIPHER_MASK 0xff00 +#define OP_PCL_IPSEC_AUTH_MASK 0x00ff + +#define OP_PCL_IPSEC_DES_IV64 0x0100 +#define OP_PCL_IPSEC_DES 0x0200 +#define OP_PCL_IPSEC_3DES 0x0300 +#define OP_PCL_IPSEC_AES_CBC 0x0c00 +#define OP_PCL_IPSEC_AES_CTR 0x0d00 +#define OP_PCL_IPSEC_AES_XTS 0x1600 +#define OP_PCL_IPSEC_AES_CCM8 0x0e00 +#define OP_PCL_IPSEC_AES_CCM12 0x0f00 +#define OP_PCL_IPSEC_AES_CCM16 0x1000 +#define OP_PCL_IPSEC_AES_GCM8 0x1200 +#define OP_PCL_IPSEC_AES_GCM12 0x1300 +#define OP_PCL_IPSEC_AES_GCM16 0x1400 + +#define OP_PCL_IPSEC_HMAC_NULL 0x0000 +#define OP_PCL_IPSEC_HMAC_MD5_96 0x0001 +#define OP_PCL_IPSEC_HMAC_SHA1_96 0x0002 +#define OP_PCL_IPSEC_AES_XCBC_MAC_96 0x0005 +#define OP_PCL_IPSEC_HMAC_MD5_128 0x0006 +#define OP_PCL_IPSEC_HMAC_SHA1_160 0x0007 +#define OP_PCL_IPSEC_HMAC_SHA2_256_128 0x000c +#define OP_PCL_IPSEC_HMAC_SHA2_384_192 0x000d +#define OP_PCL_IPSEC_HMAC_SHA2_512_256 0x000e + +/* For SRTP - OP_PCLID_SRTP */ +#define OP_PCL_SRTP_CIPHER_MASK 0xff00 +#define OP_PCL_SRTP_AUTH_MASK 0x00ff + +#define OP_PCL_SRTP_AES_CTR 0x0d00 + +#define OP_PCL_SRTP_HMAC_SHA1_160 0x0007 + +/* For SSL 3.0 - OP_PCLID_SSL30 */ +#define OP_PCL_SSL30_AES_128_CBC_SHA 0x002f +#define OP_PCL_SSL30_AES_128_CBC_SHA_2 0x0030 +#define OP_PCL_SSL30_AES_128_CBC_SHA_3 0x0031 +#define OP_PCL_SSL30_AES_128_CBC_SHA_4 0x0032 +#define OP_PCL_SSL30_AES_128_CBC_SHA_5 0x0033 +#define OP_PCL_SSL30_AES_128_CBC_SHA_6 0x0034 +#define OP_PCL_SSL30_AES_128_CBC_SHA_7 0x008c +#define OP_PCL_SSL30_AES_128_CBC_SHA_8 0x0090 +#define OP_PCL_SSL30_AES_128_CBC_SHA_9 0x0094 +#define OP_PCL_SSL30_AES_128_CBC_SHA_10 0xc004 +#define OP_PCL_SSL30_AES_128_CBC_SHA_11 0xc009 +#define OP_PCL_SSL30_AES_128_CBC_SHA_12 0xc00e +#define OP_PCL_SSL30_AES_128_CBC_SHA_13 0xc013 +#define OP_PCL_SSL30_AES_128_CBC_SHA_14 0xc018 +#define OP_PCL_SSL30_AES_128_CBC_SHA_15 0xc01d +#define OP_PCL_SSL30_AES_128_CBC_SHA_16 0xc01e +#define OP_PCL_SSL30_AES_128_CBC_SHA_17 0xc01f + +#define OP_PCL_SSL30_AES_256_CBC_SHA 0x0035 +#define OP_PCL_SSL30_AES_256_CBC_SHA_2 0x0036 +#define OP_PCL_SSL30_AES_256_CBC_SHA_3 0x0037 +#define OP_PCL_SSL30_AES_256_CBC_SHA_4 0x0038 +#define OP_PCL_SSL30_AES_256_CBC_SHA_5 0x0039 +#define OP_PCL_SSL30_AES_256_CBC_SHA_6 0x003a +#define OP_PCL_SSL30_AES_256_CBC_SHA_7 0x008d +#define OP_PCL_SSL30_AES_256_CBC_SHA_8 0x0091 +#define OP_PCL_SSL30_AES_256_CBC_SHA_9 0x0095 +#define OP_PCL_SSL30_AES_256_CBC_SHA_10 0xc005 +#define OP_PCL_SSL30_AES_256_CBC_SHA_11 0xc00a +#define OP_PCL_SSL30_AES_256_CBC_SHA_12 0xc00f +#define OP_PCL_SSL30_AES_256_CBC_SHA_13 0xc014 +#define OP_PCL_SSL30_AES_256_CBC_SHA_14 0xc019 +#define OP_PCL_SSL30_AES_256_CBC_SHA_15 0xc020 +#define OP_PCL_SSL30_AES_256_CBC_SHA_16 0xc021 +#define OP_PCL_SSL30_AES_256_CBC_SHA_17 0xc022 + +#define OP_PCL_SSL30_3DES_EDE_CBC_MD5 0x0023 + +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA 0x001f +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_2 0x008b +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_3 0x008f +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_4 0x0093 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_5 0x000a +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_6 0x000d +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_7 0x0010 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_8 0x0013 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_9 0x0016 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_10 0x001b +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_11 0xc003 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_12 0xc008 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_13 0xc00d +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_14 0xc012 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_15 0xc017 +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_16 0xc01a +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_17 0xc01b +#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_18 0xc01c + +#define OP_PCL_SSL30_DES40_CBC_MD5 0x0029 + +#define OP_PCL_SSL30_DES_CBC_MD5 0x0022 + +#define OP_PCL_SSL30_DES40_CBC_SHA 0x0008 +#define OP_PCL_SSL30_DES40_CBC_SHA_2 0x000b +#define OP_PCL_SSL30_DES40_CBC_SHA_3 0x000e +#define OP_PCL_SSL30_DES40_CBC_SHA_4 0x0011 +#define OP_PCL_SSL30_DES40_CBC_SHA_5 0x0014 +#define OP_PCL_SSL30_DES40_CBC_SHA_6 0x0019 +#define OP_PCL_SSL30_DES40_CBC_SHA_7 0x0026 + +#define OP_PCL_SSL30_DES_CBC_SHA 0x001e +#define OP_PCL_SSL30_DES_CBC_SHA_2 0x0009 +#define OP_PCL_SSL30_DES_CBC_SHA_3 0x000c +#define OP_PCL_SSL30_DES_CBC_SHA_4 0x000f +#define OP_PCL_SSL30_DES_CBC_SHA_5 0x0012 +#define OP_PCL_SSL30_DES_CBC_SHA_6 0x0015 +#define OP_PCL_SSL30_DES_CBC_SHA_7 0x001a + +#define OP_PCL_SSL30_RC4_128_MD5 0x0024 +#define OP_PCL_SSL30_RC4_128_MD5_2 0x0004 +#define OP_PCL_SSL30_RC4_128_MD5_3 0x0018 + +#define OP_PCL_SSL30_RC4_40_MD5 0x002b +#define OP_PCL_SSL30_RC4_40_MD5_2 0x0003 +#define OP_PCL_SSL30_RC4_40_MD5_3 0x0017 + +#define OP_PCL_SSL30_RC4_128_SHA 0x0020 +#define OP_PCL_SSL30_RC4_128_SHA_2 0x008a +#define OP_PCL_SSL30_RC4_128_SHA_3 0x008e +#define OP_PCL_SSL30_RC4_128_SHA_4 0x0092 +#define OP_PCL_SSL30_RC4_128_SHA_5 0x0005 +#define OP_PCL_SSL30_RC4_128_SHA_6 0xc002 +#define OP_PCL_SSL30_RC4_128_SHA_7 0xc007 +#define OP_PCL_SSL30_RC4_128_SHA_8 0xc00c +#define OP_PCL_SSL30_RC4_128_SHA_9 0xc011 +#define OP_PCL_SSL30_RC4_128_SHA_10 0xc016 + +#define OP_PCL_SSL30_RC4_40_SHA 0x0028 + + +/* For TLS 1.0 - OP_PCLID_TLS10 */ +#define OP_PCL_TLS10_AES_128_CBC_SHA 0x002f +#define OP_PCL_TLS10_AES_128_CBC_SHA_2 0x0030 +#define OP_PCL_TLS10_AES_128_CBC_SHA_3 0x0031 +#define OP_PCL_TLS10_AES_128_CBC_SHA_4 0x0032 +#define OP_PCL_TLS10_AES_128_CBC_SHA_5 0x0033 +#define OP_PCL_TLS10_AES_128_CBC_SHA_6 0x0034 +#define OP_PCL_TLS10_AES_128_CBC_SHA_7 0x008c +#define OP_PCL_TLS10_AES_128_CBC_SHA_8 0x0090 +#define OP_PCL_TLS10_AES_128_CBC_SHA_9 0x0094 +#define OP_PCL_TLS10_AES_128_CBC_SHA_10 0xc004 +#define OP_PCL_TLS10_AES_128_CBC_SHA_11 0xc009 +#define OP_PCL_TLS10_AES_128_CBC_SHA_12 0xc00e +#define OP_PCL_TLS10_AES_128_CBC_SHA_13 0xc013 +#define OP_PCL_TLS10_AES_128_CBC_SHA_14 0xc018 +#define OP_PCL_TLS10_AES_128_CBC_SHA_15 0xc01d +#define OP_PCL_TLS10_AES_128_CBC_SHA_16 0xc01e +#define OP_PCL_TLS10_AES_128_CBC_SHA_17 0xc01f + +#define OP_PCL_TLS10_AES_256_CBC_SHA 0x0035 +#define OP_PCL_TLS10_AES_256_CBC_SHA_2 0x0036 +#define OP_PCL_TLS10_AES_256_CBC_SHA_3 0x0037 +#define OP_PCL_TLS10_AES_256_CBC_SHA_4 0x0038 +#define OP_PCL_TLS10_AES_256_CBC_SHA_5 0x0039 +#define OP_PCL_TLS10_AES_256_CBC_SHA_6 0x003a +#define OP_PCL_TLS10_AES_256_CBC_SHA_7 0x008d +#define OP_PCL_TLS10_AES_256_CBC_SHA_8 0x0091 +#define OP_PCL_TLS10_AES_256_CBC_SHA_9 0x0095 +#define OP_PCL_TLS10_AES_256_CBC_SHA_10 0xc005 +#define OP_PCL_TLS10_AES_256_CBC_SHA_11 0xc00a +#define OP_PCL_TLS10_AES_256_CBC_SHA_12 0xc00f +#define OP_PCL_TLS10_AES_256_CBC_SHA_13 0xc014 +#define OP_PCL_TLS10_AES_256_CBC_SHA_14 0xc019 +#define OP_PCL_TLS10_AES_256_CBC_SHA_15 0xc020 +#define OP_PCL_TLS10_AES_256_CBC_SHA_16 0xc021 +#define OP_PCL_TLS10_AES_256_CBC_SHA_17 0xc022 + +/* #define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0x0023 */ + +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA 0x001f +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_2 0x008b +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_3 0x008f +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_4 0x0093 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_5 0x000a +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_6 0x000d +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_7 0x0010 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_8 0x0013 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_9 0x0016 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_10 0x001b +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_11 0xc003 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_12 0xc008 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_13 0xc00d +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_14 0xc012 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_15 0xc017 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_16 0xc01a +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_17 0xc01b +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_18 0xc01c + +#define OP_PCL_TLS10_DES40_CBC_MD5 0x0029 + +#define OP_PCL_TLS10_DES_CBC_MD5 0x0022 + +#define OP_PCL_TLS10_DES40_CBC_SHA 0x0008 +#define OP_PCL_TLS10_DES40_CBC_SHA_2 0x000b +#define OP_PCL_TLS10_DES40_CBC_SHA_3 0x000e +#define OP_PCL_TLS10_DES40_CBC_SHA_4 0x0011 +#define OP_PCL_TLS10_DES40_CBC_SHA_5 0x0014 +#define OP_PCL_TLS10_DES40_CBC_SHA_6 0x0019 +#define OP_PCL_TLS10_DES40_CBC_SHA_7 0x0026 + + +#define OP_PCL_TLS10_DES_CBC_SHA 0x001e +#define OP_PCL_TLS10_DES_CBC_SHA_2 0x0009 +#define OP_PCL_TLS10_DES_CBC_SHA_3 0x000c +#define OP_PCL_TLS10_DES_CBC_SHA_4 0x000f +#define OP_PCL_TLS10_DES_CBC_SHA_5 0x0012 +#define OP_PCL_TLS10_DES_CBC_SHA_6 0x0015 +#define OP_PCL_TLS10_DES_CBC_SHA_7 0x001a + +#define OP_PCL_TLS10_RC4_128_MD5 0x0024 +#define OP_PCL_TLS10_RC4_128_MD5_2 0x0004 +#define OP_PCL_TLS10_RC4_128_MD5_3 0x0018 + +#define OP_PCL_TLS10_RC4_40_MD5 0x002b +#define OP_PCL_TLS10_RC4_40_MD5_2 0x0003 +#define OP_PCL_TLS10_RC4_40_MD5_3 0x0017 + +#define OP_PCL_TLS10_RC4_128_SHA 0x0020 +#define OP_PCL_TLS10_RC4_128_SHA_2 0x008a +#define OP_PCL_TLS10_RC4_128_SHA_3 0x008e +#define OP_PCL_TLS10_RC4_128_SHA_4 0x0092 +#define OP_PCL_TLS10_RC4_128_SHA_5 0x0005 +#define OP_PCL_TLS10_RC4_128_SHA_6 0xc002 +#define OP_PCL_TLS10_RC4_128_SHA_7 0xc007 +#define OP_PCL_TLS10_RC4_128_SHA_8 0xc00c +#define OP_PCL_TLS10_RC4_128_SHA_9 0xc011 +#define OP_PCL_TLS10_RC4_128_SHA_10 0xc016 + +#define OP_PCL_TLS10_RC4_40_SHA 0x0028 + +#define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0xff23 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA160 0xff30 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA224 0xff34 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA256 0xff36 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA384 0xff33 +#define OP_PCL_TLS10_3DES_EDE_CBC_SHA512 0xff35 +#define OP_PCL_TLS10_AES_128_CBC_SHA160 0xff80 +#define OP_PCL_TLS10_AES_128_CBC_SHA224 0xff84 +#define OP_PCL_TLS10_AES_128_CBC_SHA256 0xff86 +#define OP_PCL_TLS10_AES_128_CBC_SHA384 0xff83 +#define OP_PCL_TLS10_AES_128_CBC_SHA512 0xff85 +#define OP_PCL_TLS10_AES_192_CBC_SHA160 0xff20 +#define OP_PCL_TLS10_AES_192_CBC_SHA224 0xff24 +#define OP_PCL_TLS10_AES_192_CBC_SHA256 0xff26 +#define OP_PCL_TLS10_AES_192_CBC_SHA384 0xff23 +#define OP_PCL_TLS10_AES_192_CBC_SHA512 0xff25 +#define OP_PCL_TLS10_AES_256_CBC_SHA160 0xff60 +#define OP_PCL_TLS10_AES_256_CBC_SHA224 0xff64 +#define OP_PCL_TLS10_AES_256_CBC_SHA256 0xff66 +#define OP_PCL_TLS10_AES_256_CBC_SHA384 0xff63 +#define OP_PCL_TLS10_AES_256_CBC_SHA512 0xff65 + + + +/* For TLS 1.1 - OP_PCLID_TLS11 */ +#define OP_PCL_TLS11_AES_128_CBC_SHA 0x002f +#define OP_PCL_TLS11_AES_128_CBC_SHA_2 0x0030 +#define OP_PCL_TLS11_AES_128_CBC_SHA_3 0x0031 +#define OP_PCL_TLS11_AES_128_CBC_SHA_4 0x0032 +#define OP_PCL_TLS11_AES_128_CBC_SHA_5 0x0033 +#define OP_PCL_TLS11_AES_128_CBC_SHA_6 0x0034 +#define OP_PCL_TLS11_AES_128_CBC_SHA_7 0x008c +#define OP_PCL_TLS11_AES_128_CBC_SHA_8 0x0090 +#define OP_PCL_TLS11_AES_128_CBC_SHA_9 0x0094 +#define OP_PCL_TLS11_AES_128_CBC_SHA_10 0xc004 +#define OP_PCL_TLS11_AES_128_CBC_SHA_11 0xc009 +#define OP_PCL_TLS11_AES_128_CBC_SHA_12 0xc00e +#define OP_PCL_TLS11_AES_128_CBC_SHA_13 0xc013 +#define OP_PCL_TLS11_AES_128_CBC_SHA_14 0xc018 +#define OP_PCL_TLS11_AES_128_CBC_SHA_15 0xc01d +#define OP_PCL_TLS11_AES_128_CBC_SHA_16 0xc01e +#define OP_PCL_TLS11_AES_128_CBC_SHA_17 0xc01f + +#define OP_PCL_TLS11_AES_256_CBC_SHA 0x0035 +#define OP_PCL_TLS11_AES_256_CBC_SHA_2 0x0036 +#define OP_PCL_TLS11_AES_256_CBC_SHA_3 0x0037 +#define OP_PCL_TLS11_AES_256_CBC_SHA_4 0x0038 +#define OP_PCL_TLS11_AES_256_CBC_SHA_5 0x0039 +#define OP_PCL_TLS11_AES_256_CBC_SHA_6 0x003a +#define OP_PCL_TLS11_AES_256_CBC_SHA_7 0x008d +#define OP_PCL_TLS11_AES_256_CBC_SHA_8 0x0091 +#define OP_PCL_TLS11_AES_256_CBC_SHA_9 0x0095 +#define OP_PCL_TLS11_AES_256_CBC_SHA_10 0xc005 +#define OP_PCL_TLS11_AES_256_CBC_SHA_11 0xc00a +#define OP_PCL_TLS11_AES_256_CBC_SHA_12 0xc00f +#define OP_PCL_TLS11_AES_256_CBC_SHA_13 0xc014 +#define OP_PCL_TLS11_AES_256_CBC_SHA_14 0xc019 +#define OP_PCL_TLS11_AES_256_CBC_SHA_15 0xc020 +#define OP_PCL_TLS11_AES_256_CBC_SHA_16 0xc021 +#define OP_PCL_TLS11_AES_256_CBC_SHA_17 0xc022 + +/* #define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0x0023 */ + +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA 0x001f +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_2 0x008b +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_3 0x008f +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_4 0x0093 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_5 0x000a +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_6 0x000d +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_7 0x0010 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_8 0x0013 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_9 0x0016 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_10 0x001b +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_11 0xc003 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_12 0xc008 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_13 0xc00d +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_14 0xc012 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_15 0xc017 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_16 0xc01a +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_17 0xc01b +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_18 0xc01c + +#define OP_PCL_TLS11_DES40_CBC_MD5 0x0029 + +#define OP_PCL_TLS11_DES_CBC_MD5 0x0022 + +#define OP_PCL_TLS11_DES40_CBC_SHA 0x0008 +#define OP_PCL_TLS11_DES40_CBC_SHA_2 0x000b +#define OP_PCL_TLS11_DES40_CBC_SHA_3 0x000e +#define OP_PCL_TLS11_DES40_CBC_SHA_4 0x0011 +#define OP_PCL_TLS11_DES40_CBC_SHA_5 0x0014 +#define OP_PCL_TLS11_DES40_CBC_SHA_6 0x0019 +#define OP_PCL_TLS11_DES40_CBC_SHA_7 0x0026 + +#define OP_PCL_TLS11_DES_CBC_SHA 0x001e +#define OP_PCL_TLS11_DES_CBC_SHA_2 0x0009 +#define OP_PCL_TLS11_DES_CBC_SHA_3 0x000c +#define OP_PCL_TLS11_DES_CBC_SHA_4 0x000f +#define OP_PCL_TLS11_DES_CBC_SHA_5 0x0012 +#define OP_PCL_TLS11_DES_CBC_SHA_6 0x0015 +#define OP_PCL_TLS11_DES_CBC_SHA_7 0x001a + +#define OP_PCL_TLS11_RC4_128_MD5 0x0024 +#define OP_PCL_TLS11_RC4_128_MD5_2 0x0004 +#define OP_PCL_TLS11_RC4_128_MD5_3 0x0018 + +#define OP_PCL_TLS11_RC4_40_MD5 0x002b +#define OP_PCL_TLS11_RC4_40_MD5_2 0x0003 +#define OP_PCL_TLS11_RC4_40_MD5_3 0x0017 + +#define OP_PCL_TLS11_RC4_128_SHA 0x0020 +#define OP_PCL_TLS11_RC4_128_SHA_2 0x008a +#define OP_PCL_TLS11_RC4_128_SHA_3 0x008e +#define OP_PCL_TLS11_RC4_128_SHA_4 0x0092 +#define OP_PCL_TLS11_RC4_128_SHA_5 0x0005 +#define OP_PCL_TLS11_RC4_128_SHA_6 0xc002 +#define OP_PCL_TLS11_RC4_128_SHA_7 0xc007 +#define OP_PCL_TLS11_RC4_128_SHA_8 0xc00c +#define OP_PCL_TLS11_RC4_128_SHA_9 0xc011 +#define OP_PCL_TLS11_RC4_128_SHA_10 0xc016 + +#define OP_PCL_TLS11_RC4_40_SHA 0x0028 + +#define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0xff23 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA160 0xff30 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA224 0xff34 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA256 0xff36 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA384 0xff33 +#define OP_PCL_TLS11_3DES_EDE_CBC_SHA512 0xff35 +#define OP_PCL_TLS11_AES_128_CBC_SHA160 0xff80 +#define OP_PCL_TLS11_AES_128_CBC_SHA224 0xff84 +#define OP_PCL_TLS11_AES_128_CBC_SHA256 0xff86 +#define OP_PCL_TLS11_AES_128_CBC_SHA384 0xff83 +#define OP_PCL_TLS11_AES_128_CBC_SHA512 0xff85 +#define OP_PCL_TLS11_AES_192_CBC_SHA160 0xff20 +#define OP_PCL_TLS11_AES_192_CBC_SHA224 0xff24 +#define OP_PCL_TLS11_AES_192_CBC_SHA256 0xff26 +#define OP_PCL_TLS11_AES_192_CBC_SHA384 0xff23 +#define OP_PCL_TLS11_AES_192_CBC_SHA512 0xff25 +#define OP_PCL_TLS11_AES_256_CBC_SHA160 0xff60 +#define OP_PCL_TLS11_AES_256_CBC_SHA224 0xff64 +#define OP_PCL_TLS11_AES_256_CBC_SHA256 0xff66 +#define OP_PCL_TLS11_AES_256_CBC_SHA384 0xff63 +#define OP_PCL_TLS11_AES_256_CBC_SHA512 0xff65 + + +/* For TLS 1.2 - OP_PCLID_TLS12 */ +#define OP_PCL_TLS12_AES_128_CBC_SHA 0x002f +#define OP_PCL_TLS12_AES_128_CBC_SHA_2 0x0030 +#define OP_PCL_TLS12_AES_128_CBC_SHA_3 0x0031 +#define OP_PCL_TLS12_AES_128_CBC_SHA_4 0x0032 +#define OP_PCL_TLS12_AES_128_CBC_SHA_5 0x0033 +#define OP_PCL_TLS12_AES_128_CBC_SHA_6 0x0034 +#define OP_PCL_TLS12_AES_128_CBC_SHA_7 0x008c +#define OP_PCL_TLS12_AES_128_CBC_SHA_8 0x0090 +#define OP_PCL_TLS12_AES_128_CBC_SHA_9 0x0094 +#define OP_PCL_TLS12_AES_128_CBC_SHA_10 0xc004 +#define OP_PCL_TLS12_AES_128_CBC_SHA_11 0xc009 +#define OP_PCL_TLS12_AES_128_CBC_SHA_12 0xc00e +#define OP_PCL_TLS12_AES_128_CBC_SHA_13 0xc013 +#define OP_PCL_TLS12_AES_128_CBC_SHA_14 0xc018 +#define OP_PCL_TLS12_AES_128_CBC_SHA_15 0xc01d +#define OP_PCL_TLS12_AES_128_CBC_SHA_16 0xc01e +#define OP_PCL_TLS12_AES_128_CBC_SHA_17 0xc01f + +#define OP_PCL_TLS12_AES_256_CBC_SHA 0x0035 +#define OP_PCL_TLS12_AES_256_CBC_SHA_2 0x0036 +#define OP_PCL_TLS12_AES_256_CBC_SHA_3 0x0037 +#define OP_PCL_TLS12_AES_256_CBC_SHA_4 0x0038 +#define OP_PCL_TLS12_AES_256_CBC_SHA_5 0x0039 +#define OP_PCL_TLS12_AES_256_CBC_SHA_6 0x003a +#define OP_PCL_TLS12_AES_256_CBC_SHA_7 0x008d +#define OP_PCL_TLS12_AES_256_CBC_SHA_8 0x0091 +#define OP_PCL_TLS12_AES_256_CBC_SHA_9 0x0095 +#define OP_PCL_TLS12_AES_256_CBC_SHA_10 0xc005 +#define OP_PCL_TLS12_AES_256_CBC_SHA_11 0xc00a +#define OP_PCL_TLS12_AES_256_CBC_SHA_12 0xc00f +#define OP_PCL_TLS12_AES_256_CBC_SHA_13 0xc014 +#define OP_PCL_TLS12_AES_256_CBC_SHA_14 0xc019 +#define OP_PCL_TLS12_AES_256_CBC_SHA_15 0xc020 +#define OP_PCL_TLS12_AES_256_CBC_SHA_16 0xc021 +#define OP_PCL_TLS12_AES_256_CBC_SHA_17 0xc022 + +/* #define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0x0023 */ + +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA 0x001f +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_2 0x008b +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_3 0x008f +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_4 0x0093 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_5 0x000a +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_6 0x000d +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_7 0x0010 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_8 0x0013 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_9 0x0016 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_10 0x001b +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_11 0xc003 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_12 0xc008 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_13 0xc00d +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_14 0xc012 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_15 0xc017 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_16 0xc01a +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_17 0xc01b +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_18 0xc01c + +#define OP_PCL_TLS12_DES40_CBC_MD5 0x0029 + +#define OP_PCL_TLS12_DES_CBC_MD5 0x0022 + +#define OP_PCL_TLS12_DES40_CBC_SHA 0x0008 +#define OP_PCL_TLS12_DES40_CBC_SHA_2 0x000b +#define OP_PCL_TLS12_DES40_CBC_SHA_3 0x000e +#define OP_PCL_TLS12_DES40_CBC_SHA_4 0x0011 +#define OP_PCL_TLS12_DES40_CBC_SHA_5 0x0014 +#define OP_PCL_TLS12_DES40_CBC_SHA_6 0x0019 +#define OP_PCL_TLS12_DES40_CBC_SHA_7 0x0026 + +#define OP_PCL_TLS12_DES_CBC_SHA 0x001e +#define OP_PCL_TLS12_DES_CBC_SHA_2 0x0009 +#define OP_PCL_TLS12_DES_CBC_SHA_3 0x000c +#define OP_PCL_TLS12_DES_CBC_SHA_4 0x000f +#define OP_PCL_TLS12_DES_CBC_SHA_5 0x0012 +#define OP_PCL_TLS12_DES_CBC_SHA_6 0x0015 +#define OP_PCL_TLS12_DES_CBC_SHA_7 0x001a + +#define OP_PCL_TLS12_RC4_128_MD5 0x0024 +#define OP_PCL_TLS12_RC4_128_MD5_2 0x0004 +#define OP_PCL_TLS12_RC4_128_MD5_3 0x0018 + +#define OP_PCL_TLS12_RC4_40_MD5 0x002b +#define OP_PCL_TLS12_RC4_40_MD5_2 0x0003 +#define OP_PCL_TLS12_RC4_40_MD5_3 0x0017 + +#define OP_PCL_TLS12_RC4_128_SHA 0x0020 +#define OP_PCL_TLS12_RC4_128_SHA_2 0x008a +#define OP_PCL_TLS12_RC4_128_SHA_3 0x008e +#define OP_PCL_TLS12_RC4_128_SHA_4 0x0092 +#define OP_PCL_TLS12_RC4_128_SHA_5 0x0005 +#define OP_PCL_TLS12_RC4_128_SHA_6 0xc002 +#define OP_PCL_TLS12_RC4_128_SHA_7 0xc007 +#define OP_PCL_TLS12_RC4_128_SHA_8 0xc00c +#define OP_PCL_TLS12_RC4_128_SHA_9 0xc011 +#define OP_PCL_TLS12_RC4_128_SHA_10 0xc016 + +#define OP_PCL_TLS12_RC4_40_SHA 0x0028 + +/* #define OP_PCL_TLS12_AES_128_CBC_SHA256 0x003c */ +#define OP_PCL_TLS12_AES_128_CBC_SHA256_2 0x003e +#define OP_PCL_TLS12_AES_128_CBC_SHA256_3 0x003f +#define OP_PCL_TLS12_AES_128_CBC_SHA256_4 0x0040 +#define OP_PCL_TLS12_AES_128_CBC_SHA256_5 0x0067 +#define OP_PCL_TLS12_AES_128_CBC_SHA256_6 0x006c + +/* #define OP_PCL_TLS12_AES_256_CBC_SHA256 0x003d */ +#define OP_PCL_TLS12_AES_256_CBC_SHA256_2 0x0068 +#define OP_PCL_TLS12_AES_256_CBC_SHA256_3 0x0069 +#define OP_PCL_TLS12_AES_256_CBC_SHA256_4 0x006a +#define OP_PCL_TLS12_AES_256_CBC_SHA256_5 0x006b +#define OP_PCL_TLS12_AES_256_CBC_SHA256_6 0x006d + +/* AEAD_AES_xxx_CCM/GCM remain to be defined... */ + +#define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0xff23 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA160 0xff30 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA224 0xff34 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA256 0xff36 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA384 0xff33 +#define OP_PCL_TLS12_3DES_EDE_CBC_SHA512 0xff35 +#define OP_PCL_TLS12_AES_128_CBC_SHA160 0xff80 +#define OP_PCL_TLS12_AES_128_CBC_SHA224 0xff84 +#define OP_PCL_TLS12_AES_128_CBC_SHA256 0xff86 +#define OP_PCL_TLS12_AES_128_CBC_SHA384 0xff83 +#define OP_PCL_TLS12_AES_128_CBC_SHA512 0xff85 +#define OP_PCL_TLS12_AES_192_CBC_SHA160 0xff20 +#define OP_PCL_TLS12_AES_192_CBC_SHA224 0xff24 +#define OP_PCL_TLS12_AES_192_CBC_SHA256 0xff26 +#define OP_PCL_TLS12_AES_192_CBC_SHA384 0xff23 +#define OP_PCL_TLS12_AES_192_CBC_SHA512 0xff25 +#define OP_PCL_TLS12_AES_256_CBC_SHA160 0xff60 +#define OP_PCL_TLS12_AES_256_CBC_SHA224 0xff64 +#define OP_PCL_TLS12_AES_256_CBC_SHA256 0xff66 +#define OP_PCL_TLS12_AES_256_CBC_SHA384 0xff63 +#define OP_PCL_TLS12_AES_256_CBC_SHA512 0xff65 + +/* For DTLS - OP_PCLID_DTLS */ + +#define OP_PCL_DTLS_AES_128_CBC_SHA 0x002f +#define OP_PCL_DTLS_AES_128_CBC_SHA_2 0x0030 +#define OP_PCL_DTLS_AES_128_CBC_SHA_3 0x0031 +#define OP_PCL_DTLS_AES_128_CBC_SHA_4 0x0032 +#define OP_PCL_DTLS_AES_128_CBC_SHA_5 0x0033 +#define OP_PCL_DTLS_AES_128_CBC_SHA_6 0x0034 +#define OP_PCL_DTLS_AES_128_CBC_SHA_7 0x008c +#define OP_PCL_DTLS_AES_128_CBC_SHA_8 0x0090 +#define OP_PCL_DTLS_AES_128_CBC_SHA_9 0x0094 +#define OP_PCL_DTLS_AES_128_CBC_SHA_10 0xc004 +#define OP_PCL_DTLS_AES_128_CBC_SHA_11 0xc009 +#define OP_PCL_DTLS_AES_128_CBC_SHA_12 0xc00e +#define OP_PCL_DTLS_AES_128_CBC_SHA_13 0xc013 +#define OP_PCL_DTLS_AES_128_CBC_SHA_14 0xc018 +#define OP_PCL_DTLS_AES_128_CBC_SHA_15 0xc01d +#define OP_PCL_DTLS_AES_128_CBC_SHA_16 0xc01e +#define OP_PCL_DTLS_AES_128_CBC_SHA_17 0xc01f + +#define OP_PCL_DTLS_AES_256_CBC_SHA 0x0035 +#define OP_PCL_DTLS_AES_256_CBC_SHA_2 0x0036 +#define OP_PCL_DTLS_AES_256_CBC_SHA_3 0x0037 +#define OP_PCL_DTLS_AES_256_CBC_SHA_4 0x0038 +#define OP_PCL_DTLS_AES_256_CBC_SHA_5 0x0039 +#define OP_PCL_DTLS_AES_256_CBC_SHA_6 0x003a +#define OP_PCL_DTLS_AES_256_CBC_SHA_7 0x008d +#define OP_PCL_DTLS_AES_256_CBC_SHA_8 0x0091 +#define OP_PCL_DTLS_AES_256_CBC_SHA_9 0x0095 +#define OP_PCL_DTLS_AES_256_CBC_SHA_10 0xc005 +#define OP_PCL_DTLS_AES_256_CBC_SHA_11 0xc00a +#define OP_PCL_DTLS_AES_256_CBC_SHA_12 0xc00f +#define OP_PCL_DTLS_AES_256_CBC_SHA_13 0xc014 +#define OP_PCL_DTLS_AES_256_CBC_SHA_14 0xc019 +#define OP_PCL_DTLS_AES_256_CBC_SHA_15 0xc020 +#define OP_PCL_DTLS_AES_256_CBC_SHA_16 0xc021 +#define OP_PCL_DTLS_AES_256_CBC_SHA_17 0xc022 + +/* #define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0x0023 */ + +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA 0x001f +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_2 0x008b +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_3 0x008f +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_4 0x0093 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_5 0x000a +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_6 0x000d +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_7 0x0010 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_8 0x0013 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_9 0x0016 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_10 0x001b +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_11 0xc003 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_12 0xc008 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_13 0xc00d +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_14 0xc012 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_15 0xc017 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_16 0xc01a +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_17 0xc01b +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_18 0xc01c + +#define OP_PCL_DTLS_DES40_CBC_MD5 0x0029 + +#define OP_PCL_DTLS_DES_CBC_MD5 0x0022 + +#define OP_PCL_DTLS_DES40_CBC_SHA 0x0008 +#define OP_PCL_DTLS_DES40_CBC_SHA_2 0x000b +#define OP_PCL_DTLS_DES40_CBC_SHA_3 0x000e +#define OP_PCL_DTLS_DES40_CBC_SHA_4 0x0011 +#define OP_PCL_DTLS_DES40_CBC_SHA_5 0x0014 +#define OP_PCL_DTLS_DES40_CBC_SHA_6 0x0019 +#define OP_PCL_DTLS_DES40_CBC_SHA_7 0x0026 + + +#define OP_PCL_DTLS_DES_CBC_SHA 0x001e +#define OP_PCL_DTLS_DES_CBC_SHA_2 0x0009 +#define OP_PCL_DTLS_DES_CBC_SHA_3 0x000c +#define OP_PCL_DTLS_DES_CBC_SHA_4 0x000f +#define OP_PCL_DTLS_DES_CBC_SHA_5 0x0012 +#define OP_PCL_DTLS_DES_CBC_SHA_6 0x0015 +#define OP_PCL_DTLS_DES_CBC_SHA_7 0x001a + + +#define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0xff23 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA160 0xff30 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA224 0xff34 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA256 0xff36 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA384 0xff33 +#define OP_PCL_DTLS_3DES_EDE_CBC_SHA512 0xff35 +#define OP_PCL_DTLS_AES_128_CBC_SHA160 0xff80 +#define OP_PCL_DTLS_AES_128_CBC_SHA224 0xff84 +#define OP_PCL_DTLS_AES_128_CBC_SHA256 0xff86 +#define OP_PCL_DTLS_AES_128_CBC_SHA384 0xff83 +#define OP_PCL_DTLS_AES_128_CBC_SHA512 0xff85 +#define OP_PCL_DTLS_AES_192_CBC_SHA160 0xff20 +#define OP_PCL_DTLS_AES_192_CBC_SHA224 0xff24 +#define OP_PCL_DTLS_AES_192_CBC_SHA256 0xff26 +#define OP_PCL_DTLS_AES_192_CBC_SHA384 0xff23 +#define OP_PCL_DTLS_AES_192_CBC_SHA512 0xff25 +#define OP_PCL_DTLS_AES_256_CBC_SHA160 0xff60 +#define OP_PCL_DTLS_AES_256_CBC_SHA224 0xff64 +#define OP_PCL_DTLS_AES_256_CBC_SHA256 0xff66 +#define OP_PCL_DTLS_AES_256_CBC_SHA384 0xff63 +#define OP_PCL_DTLS_AES_256_CBC_SHA512 0xff65 + +/* 802.16 WiMAX protinfos */ +#define OP_PCL_WIMAX_OFDM 0x0201 +#define OP_PCL_WIMAX_OFDMA 0x0231 + +/* 802.11 WiFi protinfos */ +#define OP_PCL_WIFI 0xac04 + +/* MacSec protinfos */ +#define OP_PCL_MACSEC 0x0001 + +/* PKI unidirectional protocol protinfo bits */ +#define OP_PCL_PKPROT_TEST 0x0008 +#define OP_PCL_PKPROT_DECRYPT 0x0004 +#define OP_PCL_PKPROT_ECC 0x0002 +#define OP_PCL_PKPROT_F2M 0x0001 + +/* For non-protocol/alg-only op commands */ +#define OP_ALG_TYPE_SHIFT 24 +#define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT) +#define OP_ALG_TYPE_CLASS1 2 +#define OP_ALG_TYPE_CLASS2 4 + +#define OP_ALG_ALGSEL_SHIFT 16 +#define OP_ALG_ALGSEL_MASK (0xff << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SUBMASK (0x0f << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_AES (0x10 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_DES (0x20 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_3DES (0x21 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_ARC4 (0x30 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_MD5 (0x40 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SHA1 (0x41 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SHA224 (0x42 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SHA256 (0x43 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SHA384 (0x44 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SHA512 (0x45 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_RNG (0x50 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SNOW (0x60 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SNOW_F8 (0x60 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_KASUMI (0x70 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_CRC (0x90 << OP_ALG_ALGSEL_SHIFT) +#define OP_ALG_ALGSEL_SNOW_F9 (0xA0 << OP_ALG_ALGSEL_SHIFT) + +#define OP_ALG_AAI_SHIFT 4 +#define OP_ALG_AAI_MASK (0x1ff << OP_ALG_AAI_SHIFT) + +/* blockcipher AAI set */ +#define OP_ALG_AAI_CTR_MOD128 (0x00 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD8 (0x01 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD16 (0x02 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD24 (0x03 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD32 (0x04 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD40 (0x05 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD48 (0x06 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD56 (0x07 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD64 (0x08 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD72 (0x09 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD80 (0x0a << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD88 (0x0b << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD96 (0x0c << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD104 (0x0d << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD112 (0x0e << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_MOD120 (0x0f << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CBC (0x10 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_ECB (0x20 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CFB (0x30 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_OFB (0x40 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_XTS (0x50 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CMAC (0x60 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_XCBC_MAC (0x70 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CCM (0x80 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_GCM (0x90 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CBC_XCBCMAC (0xa0 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CTR_XCBCMAC (0xb0 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CHECKODD (0x80 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_DK (0x100 << OP_ALG_AAI_SHIFT) + +/* randomizer AAI set */ +#define OP_ALG_AAI_RNG (0x00 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_RNG_NOZERO (0x10 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_RNG_ODD (0x20 << OP_ALG_AAI_SHIFT) + +/* hmac/smac AAI set */ +#define OP_ALG_AAI_HASH (0x00 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_HMAC (0x01 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_SMAC (0x02 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_HMAC_PRECOMP (0x04 << OP_ALG_AAI_SHIFT) + +/* CRC AAI set*/ +#define OP_ALG_AAI_802 (0x01 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_3385 (0x02 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_CUST_POLY (0x04 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_DIS (0x10 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_DOS (0x20 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_DOC (0x40 << OP_ALG_AAI_SHIFT) + +/* Kasumi/SNOW AAI set */ +#define OP_ALG_AAI_F8 (0xc0 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_F9 (0xc8 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT) +#define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT) + + +#define OP_ALG_AS_SHIFT 2 +#define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT) +#define OP_ALG_AS_UPDATE (0 << OP_ALG_AS_SHIFT) +#define OP_ALG_AS_INIT (1 << OP_ALG_AS_SHIFT) +#define OP_ALG_AS_FINALIZE (2 << OP_ALG_AS_SHIFT) +#define OP_ALG_AS_INITFINAL (3 << OP_ALG_AS_SHIFT) + +#define OP_ALG_ICV_SHIFT 1 +#define OP_ALG_ICV_MASK (1 << OP_ALG_ICV_SHIFT) +#define OP_ALG_ICV_OFF (0 << OP_ALG_ICV_SHIFT) +#define OP_ALG_ICV_ON (1 << OP_ALG_ICV_SHIFT) + +#define OP_ALG_DIR_SHIFT 0 +#define OP_ALG_DIR_MASK 1 +#define OP_ALG_DECRYPT 0 +#define OP_ALG_ENCRYPT 1 + +/* PKHA algorithm type set */ +#define OP_ALG_PK 0x00800000 +#define OP_ALG_PK_FUN_MASK 0x3f /* clrmem, modmath, or cpymem */ + +/* PKHA mode clear memory functions */ +#define OP_ALG_PKMODE_A_RAM 0x80000 +#define OP_ALG_PKMODE_B_RAM 0x40000 +#define OP_ALG_PKMODE_E_RAM 0x20000 +#define OP_ALG_PKMODE_N_RAM 0x10000 +#define OP_ALG_PKMODE_CLEARMEM 0x00001 + +/* PKHA mode modular-arithmetic functions */ +#define OP_ALG_PKMODE_MOD_IN_MONTY 0x80000 +#define OP_ALG_PKMODE_MOD_OUT_MONTY 0x40000 +#define OP_ALG_PKMODE_MOD_F2M 0x20000 +#define OP_ALG_PKMODE_MOD_R2_IN 0x10000 +#define OP_ALG_PKMODE_PRJECTV 0x00800 +#define OP_ALG_PKMODE_TIME_EQ 0x400 +#define OP_ALG_PKMODE_OUT_B 0x000 +#define OP_ALG_PKMODE_OUT_A 0x100 +#define OP_ALG_PKMODE_MOD_ADD 0x002 +#define OP_ALG_PKMODE_MOD_SUB_AB 0x003 +#define OP_ALG_PKMODE_MOD_SUB_BA 0x004 +#define OP_ALG_PKMODE_MOD_MULT 0x005 +#define OP_ALG_PKMODE_MOD_EXPO 0x006 +#define OP_ALG_PKMODE_MOD_REDUCT 0x007 +#define OP_ALG_PKMODE_MOD_INV 0x008 +#define OP_ALG_PKMODE_MOD_ECC_ADD 0x009 +#define OP_ALG_PKMODE_MOD_ECC_DBL 0x00a +#define OP_ALG_PKMODE_MOD_ECC_MULT 0x00b +#define OP_ALG_PKMODE_MOD_MONT_CNST 0x00c +#define OP_ALG_PKMODE_MOD_CRT_CNST 0x00d +#define OP_ALG_PKMODE_MOD_GCD 0x00e +#define OP_ALG_PKMODE_MOD_PRIMALITY 0x00f + +/* PKHA mode copy-memory functions */ +#define OP_ALG_PKMODE_SRC_REG_SHIFT 13 +#define OP_ALG_PKMODE_SRC_REG_MASK (7 << OP_ALG_PKMODE_SRC_REG_SHIFT) +#define OP_ALG_PKMODE_DST_REG_SHIFT 10 +#define OP_ALG_PKMODE_DST_REG_MASK (7 << OP_ALG_PKMODE_DST_REG_SHIFT) +#define OP_ALG_PKMODE_SRC_SEG_SHIFT 8 +#define OP_ALG_PKMODE_SRC_SEG_MASK (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT) +#define OP_ALG_PKMODE_DST_SEG_SHIFT 6 +#define OP_ALG_PKMODE_DST_SEG_MASK (3 << OP_ALG_PKMODE_DST_SEG_SHIFT) + +#define OP_ALG_PKMODE_SRC_REG_A (0 << OP_ALG_PKMODE_SRC_REG_SHIFT) +#define OP_ALG_PKMODE_SRC_REG_B (1 << OP_ALG_PKMODE_SRC_REG_SHIFT) +#define OP_ALG_PKMODE_SRC_REG_N (3 << OP_ALG_PKMODE_SRC_REG_SHIFT) +#define OP_ALG_PKMODE_DST_REG_A (0 << OP_ALG_PKMODE_DST_REG_SHIFT) +#define OP_ALG_PKMODE_DST_REG_B (1 << OP_ALG_PKMODE_DST_REG_SHIFT) +#define OP_ALG_PKMODE_DST_REG_E (2 << OP_ALG_PKMODE_DST_REG_SHIFT) +#define OP_ALG_PKMODE_DST_REG_N (3 << OP_ALG_PKMODE_DST_REG_SHIFT) +#define OP_ALG_PKMODE_SRC_SEG_0 (0 << OP_ALG_PKMODE_SRC_SEG_SHIFT) +#define OP_ALG_PKMODE_SRC_SEG_1 (1 << OP_ALG_PKMODE_SRC_SEG_SHIFT) +#define OP_ALG_PKMODE_SRC_SEG_2 (2 << OP_ALG_PKMODE_SRC_SEG_SHIFT) +#define OP_ALG_PKMODE_SRC_SEG_3 (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT) +#define OP_ALG_PKMODE_DST_SEG_0 (0 << OP_ALG_PKMODE_DST_SEG_SHIFT) +#define OP_ALG_PKMODE_DST_SEG_1 (1 << OP_ALG_PKMODE_DST_SEG_SHIFT) +#define OP_ALG_PKMODE_DST_SEG_2 (2 << OP_ALG_PKMODE_DST_SEG_SHIFT) +#define OP_ALG_PKMODE_DST_SEG_3 (3 << OP_ALG_PKMODE_DST_SEG_SHIFT) +#define OP_ALG_PKMODE_CPYMEM_N_SZ 0x80 +#define OP_ALG_PKMODE_CPYMEM_SRC_SZ 0x81 + +/* + * SEQ_IN_PTR Command Constructs + */ + +/* Release Buffers */ +#define SQIN_RBS 0x04000000 + +/* Sequence pointer is really a descriptor */ +#define SQIN_INL 0x02000000 + +/* Sequence pointer is a scatter-gather table */ +#define SQIN_SGF 0x01000000 + +/* Appends to a previous pointer */ +#define SQIN_PRE 0x00800000 + +/* Use extended length following pointer */ +#define SQIN_EXT 0x00400000 + +/* Restore sequence with pointer/length */ +#define SQIN_RTO 0x00200000 + +/* Replace job descriptor */ +#define SQIN_RJD 0x00100000 + +#define SQIN_LEN_SHIFT 0 +#define SQIN_LEN_MASK (0xffff << SQIN_LEN_SHIFT) + +/* + * SEQ_OUT_PTR Command Constructs + */ + +/* Sequence pointer is a scatter-gather table */ +#define SQOUT_SGF 0x01000000 + +/* Appends to a previous pointer */ +#define SQOUT_PRE 0x00800000 + +/* Restore sequence with pointer/length */ +#define SQOUT_RTO 0x00200000 + +/* Use extended length following pointer */ +#define SQOUT_EXT 0x00400000 + +#define SQOUT_LEN_SHIFT 0 +#define SQOUT_LEN_MASK (0xffff << SQOUT_LEN_SHIFT) + + +/* + * SIGNATURE Command Constructs + */ + +/* TYPE field is all that's relevant */ +#define SIGN_TYPE_SHIFT 16 +#define SIGN_TYPE_MASK (0x0f << SIGN_TYPE_SHIFT) + +#define SIGN_TYPE_FINAL (0x00 << SIGN_TYPE_SHIFT) +#define SIGN_TYPE_FINAL_RESTORE (0x01 << SIGN_TYPE_SHIFT) +#define SIGN_TYPE_FINAL_NONZERO (0x02 << SIGN_TYPE_SHIFT) +#define SIGN_TYPE_IMM_2 (0x0a << SIGN_TYPE_SHIFT) +#define SIGN_TYPE_IMM_3 (0x0b << SIGN_TYPE_SHIFT) +#define SIGN_TYPE_IMM_4 (0x0c << SIGN_TYPE_SHIFT) + +/* + * MOVE Command Constructs + */ + +#define MOVE_AUX_SHIFT 25 +#define MOVE_AUX_MASK (3 << MOVE_AUX_SHIFT) +#define MOVE_AUX_MS (2 << MOVE_AUX_SHIFT) +#define MOVE_AUX_LS (1 << MOVE_AUX_SHIFT) + +#define MOVE_WAITCOMP_SHIFT 24 +#define MOVE_WAITCOMP_MASK (1 << MOVE_WAITCOMP_SHIFT) +#define MOVE_WAITCOMP (1 << MOVE_WAITCOMP_SHIFT) + +#define MOVE_SRC_SHIFT 20 +#define MOVE_SRC_MASK (0x0f << MOVE_SRC_SHIFT) +#define MOVE_SRC_CLASS1CTX (0x00 << MOVE_SRC_SHIFT) +#define MOVE_SRC_CLASS2CTX (0x01 << MOVE_SRC_SHIFT) +#define MOVE_SRC_OUTFIFO (0x02 << MOVE_SRC_SHIFT) +#define MOVE_SRC_DESCBUF (0x03 << MOVE_SRC_SHIFT) +#define MOVE_SRC_MATH0 (0x04 << MOVE_SRC_SHIFT) +#define MOVE_SRC_MATH1 (0x05 << MOVE_SRC_SHIFT) +#define MOVE_SRC_MATH2 (0x06 << MOVE_SRC_SHIFT) +#define MOVE_SRC_MATH3 (0x07 << MOVE_SRC_SHIFT) +#define MOVE_SRC_INFIFO (0x08 << MOVE_SRC_SHIFT) +#define MOVE_SRC_INFIFO_CL (0x09 << MOVE_SRC_SHIFT) + +#define MOVE_DEST_SHIFT 16 +#define MOVE_DEST_MASK (0x0f << MOVE_DEST_SHIFT) +#define MOVE_DEST_CLASS1CTX (0x00 << MOVE_DEST_SHIFT) +#define MOVE_DEST_CLASS2CTX (0x01 << MOVE_DEST_SHIFT) +#define MOVE_DEST_OUTFIFO (0x02 << MOVE_DEST_SHIFT) +#define MOVE_DEST_DESCBUF (0x03 << MOVE_DEST_SHIFT) +#define MOVE_DEST_MATH0 (0x04 << MOVE_DEST_SHIFT) +#define MOVE_DEST_MATH1 (0x05 << MOVE_DEST_SHIFT) +#define MOVE_DEST_MATH2 (0x06 << MOVE_DEST_SHIFT) +#define MOVE_DEST_MATH3 (0x07 << MOVE_DEST_SHIFT) +#define MOVE_DEST_CLASS1INFIFO (0x08 << MOVE_DEST_SHIFT) +#define MOVE_DEST_CLASS2INFIFO (0x09 << MOVE_DEST_SHIFT) +#define MOVE_DEST_PK_A (0x0c << MOVE_DEST_SHIFT) +#define MOVE_DEST_CLASS1KEY (0x0d << MOVE_DEST_SHIFT) +#define MOVE_DEST_CLASS2KEY (0x0e << MOVE_DEST_SHIFT) + +#define MOVE_OFFSET_SHIFT 8 +#define MOVE_OFFSET_MASK (0xff << MOVE_OFFSET_SHIFT) + +#define MOVE_LEN_SHIFT 0 +#define MOVE_LEN_MASK (0xff << MOVE_LEN_SHIFT) + +#define MOVELEN_MRSEL_SHIFT 0 +#define MOVELEN_MRSEL_MASK (0x3 << MOVE_LEN_SHIFT) + +/* + * MATH Command Constructs + */ + +#define MATH_IFB_SHIFT 26 +#define MATH_IFB_MASK (1 << MATH_IFB_SHIFT) +#define MATH_IFB (1 << MATH_IFB_SHIFT) + +#define MATH_NFU_SHIFT 25 +#define MATH_NFU_MASK (1 << MATH_NFU_SHIFT) +#define MATH_NFU (1 << MATH_NFU_SHIFT) + +#define MATH_STL_SHIFT 24 +#define MATH_STL_MASK (1 << MATH_STL_SHIFT) +#define MATH_STL (1 << MATH_STL_SHIFT) + +/* Function selectors */ +#define MATH_FUN_SHIFT 20 +#define MATH_FUN_MASK (0x0f << MATH_FUN_SHIFT) +#define MATH_FUN_ADD (0x00 << MATH_FUN_SHIFT) +#define MATH_FUN_ADDC (0x01 << MATH_FUN_SHIFT) +#define MATH_FUN_SUB (0x02 << MATH_FUN_SHIFT) +#define MATH_FUN_SUBB (0x03 << MATH_FUN_SHIFT) +#define MATH_FUN_OR (0x04 << MATH_FUN_SHIFT) +#define MATH_FUN_AND (0x05 << MATH_FUN_SHIFT) +#define MATH_FUN_XOR (0x06 << MATH_FUN_SHIFT) +#define MATH_FUN_LSHIFT (0x07 << MATH_FUN_SHIFT) +#define MATH_FUN_RSHIFT (0x08 << MATH_FUN_SHIFT) +#define MATH_FUN_SHLD (0x09 << MATH_FUN_SHIFT) +#define MATH_FUN_ZBYT (0x0a << MATH_FUN_SHIFT) + +/* Source 0 selectors */ +#define MATH_SRC0_SHIFT 16 +#define MATH_SRC0_MASK (0x0f << MATH_SRC0_SHIFT) +#define MATH_SRC0_REG0 (0x00 << MATH_SRC0_SHIFT) +#define MATH_SRC0_REG1 (0x01 << MATH_SRC0_SHIFT) +#define MATH_SRC0_REG2 (0x02 << MATH_SRC0_SHIFT) +#define MATH_SRC0_REG3 (0x03 << MATH_SRC0_SHIFT) +#define MATH_SRC0_IMM (0x04 << MATH_SRC0_SHIFT) +#define MATH_SRC0_SEQINLEN (0x08 << MATH_SRC0_SHIFT) +#define MATH_SRC0_SEQOUTLEN (0x09 << MATH_SRC0_SHIFT) +#define MATH_SRC0_VARSEQINLEN (0x0a << MATH_SRC0_SHIFT) +#define MATH_SRC0_VARSEQOUTLEN (0x0b << MATH_SRC0_SHIFT) +#define MATH_SRC0_ZERO (0x0c << MATH_SRC0_SHIFT) + +/* Source 1 selectors */ +#define MATH_SRC1_SHIFT 12 +#define MATH_SRC1_MASK (0x0f << MATH_SRC1_SHIFT) +#define MATH_SRC1_REG0 (0x00 << MATH_SRC1_SHIFT) +#define MATH_SRC1_REG1 (0x01 << MATH_SRC1_SHIFT) +#define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT) +#define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT) +#define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT) +#define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT) +#define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT) +#define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT) + +/* Destination selectors */ +#define MATH_DEST_SHIFT 8 +#define MATH_DEST_MASK (0x0f << MATH_DEST_SHIFT) +#define MATH_DEST_REG0 (0x00 << MATH_DEST_SHIFT) +#define MATH_DEST_REG1 (0x01 << MATH_DEST_SHIFT) +#define MATH_DEST_REG2 (0x02 << MATH_DEST_SHIFT) +#define MATH_DEST_REG3 (0x03 << MATH_DEST_SHIFT) +#define MATH_DEST_SEQINLEN (0x08 << MATH_DEST_SHIFT) +#define MATH_DEST_SEQOUTLEN (0x09 << MATH_DEST_SHIFT) +#define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT) +#define MATH_DEST_VARSEQOUTLEN (0x0b << MATH_DEST_SHIFT) +#define MATH_DEST_NONE (0x0f << MATH_DEST_SHIFT) + +/* Length selectors */ +#define MATH_LEN_SHIFT 0 +#define MATH_LEN_MASK (0x0f << MATH_LEN_SHIFT) +#define MATH_LEN_1BYTE 0x01 +#define MATH_LEN_2BYTE 0x02 +#define MATH_LEN_4BYTE 0x04 +#define MATH_LEN_8BYTE 0x08 + +/* + * JUMP Command Constructs + */ + +#define JUMP_CLASS_SHIFT 25 +#define JUMP_CLASS_MASK (3 << JUMP_CLASS_SHIFT) +#define JUMP_CLASS_NONE 0 +#define JUMP_CLASS_CLASS1 (1 << JUMP_CLASS_SHIFT) +#define JUMP_CLASS_CLASS2 (2 << JUMP_CLASS_SHIFT) +#define JUMP_CLASS_BOTH (3 << JUMP_CLASS_SHIFT) + +#define JUMP_JSL_SHIFT 24 +#define JUMP_JSL_MASK (1 << JUMP_JSL_SHIFT) +#define JUMP_JSL (1 << JUMP_JSL_SHIFT) + +#define JUMP_TYPE_SHIFT 22 +#define JUMP_TYPE_MASK (0x03 << JUMP_TYPE_SHIFT) +#define JUMP_TYPE_LOCAL (0x00 << JUMP_TYPE_SHIFT) +#define JUMP_TYPE_NONLOCAL (0x01 << JUMP_TYPE_SHIFT) +#define JUMP_TYPE_HALT (0x02 << JUMP_TYPE_SHIFT) +#define JUMP_TYPE_HALT_USER (0x03 << JUMP_TYPE_SHIFT) + +#define JUMP_TEST_SHIFT 16 +#define JUMP_TEST_MASK (0x03 << JUMP_TEST_SHIFT) +#define JUMP_TEST_ALL (0x00 << JUMP_TEST_SHIFT) +#define JUMP_TEST_INVALL (0x01 << JUMP_TEST_SHIFT) +#define JUMP_TEST_ANY (0x02 << JUMP_TEST_SHIFT) +#define JUMP_TEST_INVANY (0x03 << JUMP_TEST_SHIFT) + +/* Condition codes. JSL bit is factored in */ +#define JUMP_COND_SHIFT 8 +#define JUMP_COND_MASK (0x100ff << JUMP_COND_SHIFT) +#define JUMP_COND_PK_0 (0x80 << JUMP_COND_SHIFT) +#define JUMP_COND_PK_GCD_1 (0x40 << JUMP_COND_SHIFT) +#define JUMP_COND_PK_PRIME (0x20 << JUMP_COND_SHIFT) +#define JUMP_COND_MATH_N (0x08 << JUMP_COND_SHIFT) +#define JUMP_COND_MATH_Z (0x04 << JUMP_COND_SHIFT) +#define JUMP_COND_MATH_C (0x02 << JUMP_COND_SHIFT) +#define JUMP_COND_MATH_NV (0x01 << JUMP_COND_SHIFT) + +#define JUMP_COND_JRP ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_SHRD ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_SELF ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_CALM ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_NIP ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_NIFP ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_NOP ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL) +#define JUMP_COND_NCP ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL) + +#define JUMP_OFFSET_SHIFT 0 +#define JUMP_OFFSET_MASK (0xff << JUMP_OFFSET_SHIFT) + +/* + * NFIFO ENTRY + * Data Constructs + * + */ +#define NFIFOENTRY_DEST_SHIFT 30 +#define NFIFOENTRY_DEST_MASK (3 << NFIFOENTRY_DEST_SHIFT) +#define NFIFOENTRY_DEST_DECO (0 << NFIFOENTRY_DEST_SHIFT) +#define NFIFOENTRY_DEST_CLASS1 (1 << NFIFOENTRY_DEST_SHIFT) +#define NFIFOENTRY_DEST_CLASS2 (2 << NFIFOENTRY_DEST_SHIFT) +#define NFIFOENTRY_DEST_BOTH (3 << NFIFOENTRY_DEST_SHIFT) + +#define NFIFOENTRY_LC2_SHIFT 29 +#define NFIFOENTRY_LC2_MASK (1 << NFIFOENTRY_LC2_SHIFT) +#define NFIFOENTRY_LC2 (1 << NFIFOENTRY_LC2_SHIFT) + +#define NFIFOENTRY_LC1_SHIFT 28 +#define NFIFOENTRY_LC1_MASK (1 << NFIFOENTRY_LC1_SHIFT) +#define NFIFOENTRY_LC1 (1 << NFIFOENTRY_LC1_SHIFT) + +#define NFIFOENTRY_FC2_SHIFT 27 +#define NFIFOENTRY_FC2_MASK (1 << NFIFOENTRY_FC2_SHIFT) +#define NFIFOENTRY_FC2 (1 << NFIFOENTRY_FC2_SHIFT) + +#define NFIFOENTRY_FC1_SHIFT 26 +#define NFIFOENTRY_FC1_MASK (1 << NFIFOENTRY_FC1_SHIFT) +#define NFIFOENTRY_FC1 (1 << NFIFOENTRY_FC1_SHIFT) + +#define NFIFOENTRY_STYPE_SHIFT 24 +#define NFIFOENTRY_STYPE_MASK (3 << NFIFOENTRY_STYPE_SHIFT) +#define NFIFOENTRY_STYPE_DFIFO (0 << NFIFOENTRY_STYPE_SHIFT) +#define NFIFOENTRY_STYPE_OFIFO (1 << NFIFOENTRY_STYPE_SHIFT) +#define NFIFOENTRY_STYPE_PAD (2 << NFIFOENTRY_STYPE_SHIFT) +#define NFIFOENTRY_STYPE_SNOOP (3 << NFIFOENTRY_STYPE_SHIFT) + +#define NFIFOENTRY_DTYPE_SHIFT 20 +#define NFIFOENTRY_DTYPE_MASK (0xF << NFIFOENTRY_DTYPE_SHIFT) + +#define NFIFOENTRY_DTYPE_SBOX (0x0 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_AAD (0x1 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_IV (0x2 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_SAD (0x3 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_ICV (0xA << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_MSG (0xF << NFIFOENTRY_DTYPE_SHIFT) + +#define NFIFOENTRY_DTYPE_PK_A0 (0x0 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_A1 (0x1 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_A2 (0x2 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_A3 (0x3 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_B0 (0x4 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_B1 (0x5 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_B2 (0x6 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_B3 (0x7 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_N (0x8 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_E (0x9 << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_A (0xC << NFIFOENTRY_DTYPE_SHIFT) +#define NFIFOENTRY_DTYPE_PK_B (0xD << NFIFOENTRY_DTYPE_SHIFT) + + +#define NFIFOENTRY_BND_SHIFT 19 +#define NFIFOENTRY_BND_MASK (1 << NFIFOENTRY_BND_SHIFT) +#define NFIFOENTRY_BND (1 << NFIFOENTRY_BND_SHIFT) + +#define NFIFOENTRY_PTYPE_SHIFT 16 +#define NFIFOENTRY_PTYPE_MASK (0x7 << NFIFOENTRY_PTYPE_SHIFT) + +#define NFIFOENTRY_PTYPE_ZEROS (0x0 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_RND_NOZEROS (0x1 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_INCREMENT (0x2 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_RND (0x3 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_ZEROS_NZ (0x4 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_RND_NZ_LZ (0x5 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_N (0x6 << NFIFOENTRY_PTYPE_SHIFT) +#define NFIFOENTRY_PTYPE_RND_NZ_N (0x7 << NFIFOENTRY_PTYPE_SHIFT) + +#define NFIFOENTRY_OC_SHIFT 15 +#define NFIFOENTRY_OC_MASK (1 << NFIFOENTRY_OC_SHIFT) +#define NFIFOENTRY_OC (1 << NFIFOENTRY_OC_SHIFT) + +#define NFIFOENTRY_AST_SHIFT 14 +#define NFIFOENTRY_AST_MASK (1 << NFIFOENTRY_OC_SHIFT) +#define NFIFOENTRY_AST (1 << NFIFOENTRY_OC_SHIFT) + +#define NFIFOENTRY_BM_SHIFT 11 +#define NFIFOENTRY_BM_MASK (1 << NFIFOENTRY_BM_SHIFT) +#define NFIFOENTRY_BM (1 << NFIFOENTRY_BM_SHIFT) + +#define NFIFOENTRY_PS_SHIFT 10 +#define NFIFOENTRY_PS_MASK (1 << NFIFOENTRY_PS_SHIFT) +#define NFIFOENTRY_PS (1 << NFIFOENTRY_PS_SHIFT) + + +#define NFIFOENTRY_DLEN_SHIFT 0 +#define NFIFOENTRY_DLEN_MASK (0xFFF << NFIFOENTRY_DLEN_SHIFT) + +#define NFIFOENTRY_PLEN_SHIFT 0 +#define NFIFOENTRY_PLEN_MASK (0xFF << NFIFOENTRY_PLEN_SHIFT) + +/* + * PDB internal definitions + */ + +/* IPSec ESP CBC Encap/Decap Options */ +#define PDBOPTS_ESPCBC_ARSNONE 0x00 /* no antireplay window */ +#define PDBOPTS_ESPCBC_ARS32 0x40 /* 32-entry antireplay window */ +#define PDBOPTS_ESPCBC_ARS64 0xc0 /* 64-entry antireplay window */ +#define PDBOPTS_ESPCBC_IVSRC 0x20 /* IV comes from internal random gen */ +#define PDBOPTS_ESPCBC_ESN 0x10 /* extended sequence included */ +#define PDBOPTS_ESPCBC_OUTFMT 0x08 /* output only decapsulation (decap) */ +#define PDBOPTS_ESPCBC_IPHDRSRC 0x08 /* IP header comes from PDB (encap) */ +#define PDBOPTS_ESPCBC_INCIPHDR 0x04 /* Prepend IP header to output frame */ +#define PDBOPTS_ESPCBC_IPVSN 0x02 /* process IPv6 header */ +#define PDBOPTS_ESPCBC_TUNNEL 0x01 /* tunnel mode next-header byte */ + +#endif /* DESC_H */ diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h new file mode 100644 index 000000000000..c224f39e94a7 --- /dev/null +++ b/drivers/crypto/caam/desc_constr.h @@ -0,0 +1,204 @@ +/* + * caam descriptor construction helper functions + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#include "desc.h" + +#define IMMEDIATE (1 << 23) +#define CAAM_CMD_SZ sizeof(u32) +#define CAAM_PTR_SZ sizeof(dma_addr_t) + +#ifdef DEBUG +#define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\ + &__func__[sizeof("append")]); } while (0) +#else +#define PRINT_POS +#endif + +#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \ + LDST_SRCDST_WORD_DECOCTRL | \ + (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT)) +#define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \ + LDST_SRCDST_WORD_DECOCTRL | \ + (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT)) + +static inline int desc_len(u32 *desc) +{ + return *desc & HDR_DESCLEN_MASK; +} + +static inline int desc_bytes(void *desc) +{ + return desc_len(desc) * CAAM_CMD_SZ; +} + +static inline u32 *desc_end(u32 *desc) +{ + return desc + desc_len(desc); +} + +static inline void *sh_desc_pdb(u32 *desc) +{ + return desc + 1; +} + +static inline void init_desc(u32 *desc, u32 options) +{ + *desc = options | HDR_ONE | 1; +} + +static inline void init_sh_desc(u32 *desc, u32 options) +{ + PRINT_POS; + init_desc(desc, CMD_SHARED_DESC_HDR | options); +} + +static inline void init_sh_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes) +{ + u32 pdb_len = pdb_bytes / CAAM_CMD_SZ + 1; + + init_sh_desc(desc, ((pdb_len << HDR_START_IDX_SHIFT) + pdb_len) | + options); +} + +static inline void init_job_desc(u32 *desc, u32 options) +{ + init_desc(desc, CMD_DESC_HDR | options); +} + +static inline void append_ptr(u32 *desc, dma_addr_t ptr) +{ + dma_addr_t *offset = (dma_addr_t *)desc_end(desc); + + *offset = ptr; + + (*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ; +} + +static inline void init_job_desc_shared(u32 *desc, dma_addr_t ptr, int len, + u32 options) +{ + PRINT_POS; + init_job_desc(desc, HDR_SHARED | options | + (len << HDR_START_IDX_SHIFT)); + append_ptr(desc, ptr); +} + +static inline void append_data(u32 *desc, void *data, int len) +{ + u32 *offset = desc_end(desc); + + if (len) /* avoid sparse warning: memcpy with byte count of 0 */ + memcpy(offset, data, len); + + (*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ; +} + +static inline void append_cmd(u32 *desc, u32 command) +{ + u32 *cmd = desc_end(desc); + + *cmd = command; + + (*desc)++; +} + +static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len, + u32 command) +{ + append_cmd(desc, command | len); + append_ptr(desc, ptr); +} + +static inline void append_cmd_data(u32 *desc, void *data, int len, + u32 command) +{ + append_cmd(desc, command | IMMEDIATE | len); + append_data(desc, data, len); +} + +static inline u32 *append_jump(u32 *desc, u32 options) +{ + u32 *cmd = desc_end(desc); + + PRINT_POS; + append_cmd(desc, CMD_JUMP | options); + + return cmd; +} + +static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd) +{ + *jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc)); +} + +#define APPEND_CMD(cmd, op) \ +static inline void append_##cmd(u32 *desc, u32 options) \ +{ \ + PRINT_POS; \ + append_cmd(desc, CMD_##op | options); \ +} +APPEND_CMD(operation, OPERATION) +APPEND_CMD(move, MOVE) + +#define APPEND_CMD_LEN(cmd, op) \ +static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \ +{ \ + PRINT_POS; \ + append_cmd(desc, CMD_##op | len | options); \ +} +APPEND_CMD_LEN(seq_store, SEQ_STORE) +APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD) +APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE) + +#define APPEND_CMD_PTR(cmd, op) \ +static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \ + u32 options) \ +{ \ + PRINT_POS; \ + append_cmd_ptr(desc, ptr, len, CMD_##op | options); \ +} +APPEND_CMD_PTR(key, KEY) +APPEND_CMD_PTR(seq_in_ptr, SEQ_IN_PTR) +APPEND_CMD_PTR(seq_out_ptr, SEQ_OUT_PTR) +APPEND_CMD_PTR(load, LOAD) +APPEND_CMD_PTR(store, STORE) +APPEND_CMD_PTR(fifo_load, FIFO_LOAD) +APPEND_CMD_PTR(fifo_store, FIFO_STORE) + +#define APPEND_CMD_PTR_TO_IMM(cmd, op) \ +static inline void append_##cmd##_as_imm(u32 *desc, void *data, \ + unsigned int len, u32 options) \ +{ \ + PRINT_POS; \ + append_cmd_data(desc, data, len, CMD_##op | options); \ +} +APPEND_CMD_PTR_TO_IMM(load, LOAD); +APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD); + +/* + * 2nd variant for commands whose specified immediate length differs + * from length of immediate data provided, e.g., split keys + */ +#define APPEND_CMD_PTR_TO_IMM2(cmd, op) \ +static inline void append_##cmd##_as_imm(u32 *desc, void *data, \ + unsigned int data_len, \ + unsigned int len, u32 options) \ +{ \ + PRINT_POS; \ + append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \ + append_data(desc, data, data_len); \ +} +APPEND_CMD_PTR_TO_IMM2(key, KEY); + +#define APPEND_CMD_RAW_IMM(cmd, op, type) \ +static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \ + u32 options) \ +{ \ + PRINT_POS; \ + append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \ + append_cmd(desc, immediate); \ +} +APPEND_CMD_RAW_IMM(load, LOAD, u32); diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c new file mode 100644 index 000000000000..bd57a6825f57 --- /dev/null +++ b/drivers/crypto/caam/error.c @@ -0,0 +1,248 @@ +/* + * CAAM Error Reporting + * + * Copyright 2009-2011 Freescale Semiconductor, Inc. + */ + +#include "compat.h" +#include "regs.h" +#include "intern.h" +#include "desc.h" +#include "jr.h" +#include "error.h" + +#define SPRINTFCAT(str, format, param, max_alloc) \ +{ \ + char *tmp; \ + \ + tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ + sprintf(tmp, format, param); \ + strcat(str, tmp); \ + kfree(tmp); \ +} + +static void report_jump_idx(u32 status, char *outstr) +{ + u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> + JRSTA_DECOERR_INDEX_SHIFT; + + if (status & JRSTA_DECOERR_JUMP) + strcat(outstr, "jump tgt desc idx "); + else + strcat(outstr, "desc idx "); + + SPRINTFCAT(outstr, "%d: ", idx, sizeof("255")); +} + +static void report_ccb_status(u32 status, char *outstr) +{ + char *cha_id_list[] = { + "", + "AES", + "DES, 3DES", + "ARC4", + "MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512", + "RNG", + "SNOW f8", + "Kasumi f8, f9", + "All Public Key Algorithms", + "CRC", + "SNOW f9", + }; + char *err_id_list[] = { + "None. No error.", + "Mode error.", + "Data size error.", + "Key size error.", + "PKHA A memory size error.", + "PKHA B memory size error.", + "Data arrived out of sequence error.", + "PKHA divide-by-zero error.", + "PKHA modulus even error.", + "DES key parity error.", + "ICV check failed.", + "Hardware error.", + "Unsupported CCM AAD size.", + "Class 1 CHA is not reset", + "Invalid CHA combination was selected", + "Invalid CHA selected.", + }; + u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> + JRSTA_CCBERR_CHAID_SHIFT; + u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; + + report_jump_idx(status, outstr); + + if (cha_id < sizeof(cha_id_list)) { + SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id], + strlen(cha_id_list[cha_id])); + } else { + SPRINTFCAT(outstr, "unidentified cha_id value 0x%02x: ", + cha_id, sizeof("ff")); + } + + if (err_id < sizeof(err_id_list)) { + SPRINTFCAT(outstr, "%s", err_id_list[err_id], + strlen(err_id_list[err_id])); + } else { + SPRINTFCAT(outstr, "unidentified err_id value 0x%02x", + err_id, sizeof("ff")); + } +} + +static void report_jump_status(u32 status, char *outstr) +{ + SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); +} + +static void report_deco_status(u32 status, char *outstr) +{ + const struct { + u8 value; + char *error_text; + } desc_error_list[] = { + { 0x00, "None. No error." }, + { 0x01, "SGT Length Error. The descriptor is trying to read " + "more data than is contained in the SGT table." }, + { 0x02, "Reserved." }, + { 0x03, "Job Ring Control Error. There is a bad value in the " + "Job Ring Control register." }, + { 0x04, "Invalid Descriptor Command. The Descriptor Command " + "field is invalid." }, + { 0x05, "Reserved." }, + { 0x06, "Invalid KEY Command" }, + { 0x07, "Invalid LOAD Command" }, + { 0x08, "Invalid STORE Command" }, + { 0x09, "Invalid OPERATION Command" }, + { 0x0A, "Invalid FIFO LOAD Command" }, + { 0x0B, "Invalid FIFO STORE Command" }, + { 0x0C, "Invalid MOVE Command" }, + { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " + "invalid because the target is not a Job Header " + "Command, or the jump is from a Trusted Descriptor to " + "a Job Descriptor, or because the target Descriptor " + "contains a Shared Descriptor." }, + { 0x0E, "Invalid MATH Command" }, + { 0x0F, "Invalid SIGNATURE Command" }, + { 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR " + "Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO " + "LOAD, or SEQ FIFO STORE decremented the input or " + "output sequence length below 0. This error may result " + "if a built-in PROTOCOL Command has encountered a " + "malformed PDU." }, + { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."}, + { 0x12, "Shared Descriptor Header Error" }, + { 0x13, "Header Error. Invalid length or parity, or certain " + "other problems." }, + { 0x14, "Burster Error. Burster has gotten to an illegal " + "state" }, + { 0x15, "Context Register Length Error. The descriptor is " + "trying to read or write past the end of the Context " + "Register. A SEQ LOAD or SEQ STORE with the VLF bit " + "set was executed with too large a length in the " + "variable length register (VSOL for SEQ STORE or VSIL " + "for SEQ LOAD)." }, + { 0x16, "DMA Error" }, + { 0x17, "Reserved." }, + { 0x1A, "Job failed due to JR reset" }, + { 0x1B, "Job failed due to Fail Mode" }, + { 0x1C, "DECO Watchdog timer timeout error" }, + { 0x1D, "DECO tried to copy a key from another DECO but the " + "other DECO's Key Registers were locked" }, + { 0x1E, "DECO attempted to copy data from a DECO that had an " + "unmasked Descriptor error" }, + { 0x1F, "LIODN error. DECO was trying to share from itself or " + "from another DECO but the two Non-SEQ LIODN values " + "didn't match or the 'shared from' DECO's Descriptor " + "required that the SEQ LIODNs be the same and they " + "aren't." }, + { 0x20, "DECO has completed a reset initiated via the DRR " + "register" }, + { 0x21, "Nonce error. When using EKT (CCM) key encryption " + "option in the FIFO STORE Command, the Nonce counter " + "reached its maximum value and this encryption mode " + "can no longer be used." }, + { 0x22, "Meta data is too large (> 511 bytes) for TLS decap " + "(input frame; block ciphers) and IPsec decap (output " + "frame, when doing the next header byte update) and " + "DCRC (output frame)." }, + { 0x80, "DNR (do not run) error" }, + { 0x81, "undefined protocol command" }, + { 0x82, "invalid setting in PDB" }, + { 0x83, "Anti-replay LATE error" }, + { 0x84, "Anti-replay REPLAY error" }, + { 0x85, "Sequence number overflow" }, + { 0x86, "Sigver invalid signature" }, + { 0x87, "DSA Sign Illegal test descriptor" }, + { 0x88, "Protocol Format Error - A protocol has seen an error " + "in the format of data received. When running RSA, " + "this means that formatting with random padding was " + "used, and did not follow the form: 0x00, 0x02, 8-to-N " + "bytes of non-zero pad, 0x00, F data." }, + { 0x89, "Protocol Size Error - A protocol has seen an error in " + "size. When running RSA, pdb size N < (size of F) when " + "no formatting is used; or pdb size N < (F + 11) when " + "formatting is used." }, + { 0xC1, "Blob Command error: Undefined mode" }, + { 0xC2, "Blob Command error: Secure Memory Blob mode error" }, + { 0xC4, "Blob Command error: Black Blob key or input size " + "error" }, + { 0xC5, "Blob Command error: Invalid key destination" }, + { 0xC8, "Blob Command error: Trusted/Secure mode error" }, + { 0xF0, "IPsec TTL or hop limit field either came in as 0, " + "or was decremented to 0" }, + { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, + }; + u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK; + int i; + + report_jump_idx(status, outstr); + + for (i = 0; i < sizeof(desc_error_list); i++) + if (desc_error_list[i].value == desc_error) + break; + + if (i != sizeof(desc_error_list) && desc_error_list[i].error_text) { + SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text, + strlen(desc_error_list[i].error_text)); + } else { + SPRINTFCAT(outstr, "unidentified error value 0x%02x", + desc_error, sizeof("ff")); + } +} + +static void report_jr_status(u32 status, char *outstr) +{ + SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); +} + +static void report_cond_code_status(u32 status, char *outstr) +{ + SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); +} + +char *caam_jr_strstatus(char *outstr, u32 status) +{ + struct stat_src { + void (*report_ssed)(u32 status, char *outstr); + char *error; + } status_src[] = { + { NULL, "No error" }, + { NULL, NULL }, + { report_ccb_status, "CCB" }, + { report_jump_status, "Jump" }, + { report_deco_status, "DECO" }, + { NULL, NULL }, + { report_jr_status, "Job Ring" }, + { report_cond_code_status, "Condition Code" }, + }; + u32 ssrc = status >> JRSTA_SSRC_SHIFT; + + sprintf(outstr, "%s: ", status_src[ssrc].error); + + if (status_src[ssrc].report_ssed) + status_src[ssrc].report_ssed(status, outstr); + + return outstr; +} +EXPORT_SYMBOL(caam_jr_strstatus); diff --git a/drivers/crypto/caam/error.h b/drivers/crypto/caam/error.h new file mode 100644 index 000000000000..067afc120132 --- /dev/null +++ b/drivers/crypto/caam/error.h @@ -0,0 +1,10 @@ +/* + * CAAM Error Reporting code header + * + * Copyright 2009-2011 Freescale Semiconductor, Inc. + */ + +#ifndef CAAM_ERROR_H +#define CAAM_ERROR_H +extern char *caam_jr_strstatus(char *outstr, u32 status); +#endif /* CAAM_ERROR_H */ diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h new file mode 100644 index 000000000000..a34be01b0b29 --- /dev/null +++ b/drivers/crypto/caam/intern.h @@ -0,0 +1,113 @@ +/* + * CAAM/SEC 4.x driver backend + * Private/internal definitions between modules + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + */ + +#ifndef INTERN_H +#define INTERN_H + +#define JOBR_UNASSIGNED 0 +#define JOBR_ASSIGNED 1 + +/* Currently comes from Kconfig param as a ^2 (driver-required) */ +#define JOBR_DEPTH (1 << CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE) + +/* Kconfig params for interrupt coalescing if selected (else zero) */ +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_INTC +#define JOBR_INTC JRCFG_ICEN +#define JOBR_INTC_TIME_THLD CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD +#define JOBR_INTC_COUNT_THLD CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD +#else +#define JOBR_INTC 0 +#define JOBR_INTC_TIME_THLD 0 +#define JOBR_INTC_COUNT_THLD 0 +#endif + +/* + * Storage for tracking each in-process entry moving across a ring + * Each entry on an output ring needs one of these + */ +struct caam_jrentry_info { + void (*callbk)(struct device *dev, u32 *desc, u32 status, void *arg); + void *cbkarg; /* Argument per ring entry */ + u32 *desc_addr_virt; /* Stored virt addr for postprocessing */ + dma_addr_t desc_addr_dma; /* Stored bus addr for done matching */ + u32 desc_size; /* Stored size for postprocessing, header derived */ +}; + +/* Private sub-storage for a single JobR */ +struct caam_drv_private_jr { + struct device *parentdev; /* points back to controller dev */ + int ridx; + struct caam_job_ring __iomem *rregs; /* JobR's register space */ + struct tasklet_struct irqtask[NR_CPUS]; + int irq; /* One per queue */ + int assign; /* busy/free */ + + /* Job ring info */ + int ringsize; /* Size of rings (assume input = output) */ + struct caam_jrentry_info *entinfo; /* Alloc'ed 1 per ring entry */ + spinlock_t inplock ____cacheline_aligned; /* Input ring index lock */ + int inp_ring_write_index; /* Input index "tail" */ + int head; /* entinfo (s/w ring) head index */ + dma_addr_t *inpring; /* Base of input ring, alloc DMA-safe */ + spinlock_t outlock ____cacheline_aligned; /* Output ring index lock */ + int out_ring_read_index; /* Output index "tail" */ + int tail; /* entinfo (s/w ring) tail index */ + struct jr_outentry *outring; /* Base of output ring, DMA-safe */ +}; + +/* + * Driver-private storage for a single CAAM block instance + */ +struct caam_drv_private { + + struct device *dev; + struct device **jrdev; /* Alloc'ed array per sub-device */ + spinlock_t jr_alloc_lock; + struct platform_device *pdev; + + /* Physical-presence section */ + struct caam_ctrl *ctrl; /* controller region */ + struct caam_deco **deco; /* DECO/CCB views */ + struct caam_assurance *ac; + struct caam_queue_if *qi; /* QI control region */ + + /* + * Detected geometry block. Filled in from device tree if powerpc, + * or from register-based version detection code + */ + u8 total_jobrs; /* Total Job Rings in device */ + u8 qi_present; /* Nonzero if QI present in device */ + int secvio_irq; /* Security violation interrupt number */ + + /* which jr allocated to scatterlist crypto */ + atomic_t tfm_count ____cacheline_aligned; + int num_jrs_for_algapi; + struct device **algapi_jr; + /* list of registered crypto algorithms (mk generic context handle?) */ + struct list_head alg_list; + + /* + * debugfs entries for developer view into driver/device + * variables at runtime. + */ +#ifdef CONFIG_DEBUG_FS + struct dentry *dfs_root; + struct dentry *ctl; /* controller dir */ + struct dentry *ctl_rq_dequeued, *ctl_ob_enc_req, *ctl_ib_dec_req; + struct dentry *ctl_ob_enc_bytes, *ctl_ob_prot_bytes; + struct dentry *ctl_ib_dec_bytes, *ctl_ib_valid_bytes; + struct dentry *ctl_faultaddr, *ctl_faultdetail, *ctl_faultstatus; + + struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap; + struct dentry *ctl_kek, *ctl_tkek, *ctl_tdsk; +#endif +}; + +void caam_jr_algapi_init(struct device *dev); +void caam_jr_algapi_remove(struct device *dev); +#endif /* INTERN_H */ diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c new file mode 100644 index 000000000000..68cb9af4d1a3 --- /dev/null +++ b/drivers/crypto/caam/jr.c @@ -0,0 +1,523 @@ +/* + * CAAM/SEC 4.x transport/backend driver + * JobR backend functionality + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#include "compat.h" +#include "regs.h" +#include "jr.h" +#include "desc.h" +#include "intern.h" + +/* Main per-ring interrupt handler */ +static irqreturn_t caam_jr_interrupt(int irq, void *st_dev) +{ + struct device *dev = st_dev; + struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); + u32 irqstate; + + /* + * Check the output ring for ready responses, kick + * tasklet if jobs done. + */ + irqstate = rd_reg32(&jrp->rregs->jrintstatus); + if (!irqstate) + return IRQ_NONE; + + /* + * If JobR error, we got more development work to do + * Flag a bug now, but we really need to shut down and + * restart the queue (and fix code). + */ + if (irqstate & JRINT_JR_ERROR) { + dev_err(dev, "job ring error: irqstate: %08x\n", irqstate); + BUG(); + } + + /* mask valid interrupts */ + setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); + + /* Have valid interrupt at this point, just ACK and trigger */ + wr_reg32(&jrp->rregs->jrintstatus, irqstate); + + preempt_disable(); + tasklet_schedule(&jrp->irqtask[smp_processor_id()]); + preempt_enable(); + + return IRQ_HANDLED; +} + +/* Deferred service handler, run as interrupt-fired tasklet */ +static void caam_jr_dequeue(unsigned long devarg) +{ + int hw_idx, sw_idx, i, head, tail; + struct device *dev = (struct device *)devarg; + struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); + void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); + u32 *userdesc, userstatus; + void *userarg; + unsigned long flags; + + spin_lock_irqsave(&jrp->outlock, flags); + + head = ACCESS_ONCE(jrp->head); + sw_idx = tail = jrp->tail; + + while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 && + rd_reg32(&jrp->rregs->outring_used)) { + + hw_idx = jrp->out_ring_read_index; + for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { + sw_idx = (tail + i) & (JOBR_DEPTH - 1); + + smp_read_barrier_depends(); + + if (jrp->outring[hw_idx].desc == + jrp->entinfo[sw_idx].desc_addr_dma) + break; /* found */ + } + /* we should never fail to find a matching descriptor */ + BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0); + + /* Unmap just-run descriptor so we can post-process */ + dma_unmap_single(dev, jrp->outring[hw_idx].desc, + jrp->entinfo[sw_idx].desc_size, + DMA_TO_DEVICE); + + /* mark completed, avoid matching on a recycled desc addr */ + jrp->entinfo[sw_idx].desc_addr_dma = 0; + + /* Stash callback params for use outside of lock */ + usercall = jrp->entinfo[sw_idx].callbk; + userarg = jrp->entinfo[sw_idx].cbkarg; + userdesc = jrp->entinfo[sw_idx].desc_addr_virt; + userstatus = jrp->outring[hw_idx].jrstatus; + + smp_mb(); + + jrp->out_ring_read_index = (jrp->out_ring_read_index + 1) & + (JOBR_DEPTH - 1); + + /* + * if this job completed out-of-order, do not increment + * the tail. Otherwise, increment tail by 1 plus the + * number of subsequent jobs already completed out-of-order + */ + if (sw_idx == tail) { + do { + tail = (tail + 1) & (JOBR_DEPTH - 1); + smp_read_barrier_depends(); + } while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 && + jrp->entinfo[tail].desc_addr_dma == 0); + + jrp->tail = tail; + } + + /* set done */ + wr_reg32(&jrp->rregs->outring_rmvd, 1); + + spin_unlock_irqrestore(&jrp->outlock, flags); + + /* Finally, execute user's callback */ + usercall(dev, userdesc, userstatus, userarg); + + spin_lock_irqsave(&jrp->outlock, flags); + + head = ACCESS_ONCE(jrp->head); + sw_idx = tail = jrp->tail; + } + + spin_unlock_irqrestore(&jrp->outlock, flags); + + /* reenable / unmask IRQs */ + clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); +} + +/** + * caam_jr_register() - Alloc a ring for someone to use as needed. Returns + * an ordinal of the rings allocated, else returns -ENODEV if no rings + * are available. + * @ctrldev: points to the controller level dev (parent) that + * owns rings available for use. + * @dev: points to where a pointer to the newly allocated queue's + * dev can be written to if successful. + **/ +int caam_jr_register(struct device *ctrldev, struct device **rdev) +{ + struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); + struct caam_drv_private_jr *jrpriv = NULL; + unsigned long flags; + int ring; + + /* Lock, if free ring - assign, unlock */ + spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags); + for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { + jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); + if (jrpriv->assign == JOBR_UNASSIGNED) { + jrpriv->assign = JOBR_ASSIGNED; + *rdev = ctrlpriv->jrdev[ring]; + spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); + return ring; + } + } + + /* If assigned, write dev where caller needs it */ + spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); + *rdev = NULL; + + return -ENODEV; +} +EXPORT_SYMBOL(caam_jr_register); + +/** + * caam_jr_deregister() - Deregister an API and release the queue. + * Returns 0 if OK, -EBUSY if queue still contains pending entries + * or unprocessed results at the time of the call + * @dev - points to the dev that identifies the queue to + * be released. + **/ +int caam_jr_deregister(struct device *rdev) +{ + struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev); + struct caam_drv_private *ctrlpriv; + unsigned long flags; + + /* Get the owning controller's private space */ + ctrlpriv = dev_get_drvdata(jrpriv->parentdev); + + /* + * Make sure ring empty before release + */ + if (rd_reg32(&jrpriv->rregs->outring_used) || + (rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH)) + return -EBUSY; + + /* Release ring */ + spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags); + jrpriv->assign = JOBR_UNASSIGNED; + spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); + + return 0; +} +EXPORT_SYMBOL(caam_jr_deregister); + +/** + * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK, + * -EBUSY if the queue is full, -EIO if it cannot map the caller's + * descriptor. + * @dev: device of the job ring to be used. This device should have + * been assigned prior by caam_jr_register(). + * @desc: points to a job descriptor that execute our request. All + * descriptors (and all referenced data) must be in a DMAable + * region, and all data references must be physical addresses + * accessible to CAAM (i.e. within a PAMU window granted + * to it). + * @cbk: pointer to a callback function to be invoked upon completion + * of this request. This has the form: + * callback(struct device *dev, u32 *desc, u32 stat, void *arg) + * where: + * @dev: contains the job ring device that processed this + * response. + * @desc: descriptor that initiated the request, same as + * "desc" being argued to caam_jr_enqueue(). + * @status: untranslated status received from CAAM. See the + * reference manual for a detailed description of + * error meaning, or see the JRSTA definitions in the + * register header file + * @areq: optional pointer to an argument passed with the + * original request + * @areq: optional pointer to a user argument for use at callback + * time. + **/ +int caam_jr_enqueue(struct device *dev, u32 *desc, + void (*cbk)(struct device *dev, u32 *desc, + u32 status, void *areq), + void *areq) +{ + struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); + struct caam_jrentry_info *head_entry; + unsigned long flags; + int head, tail, desc_size; + dma_addr_t desc_dma; + + desc_size = (*desc & HDR_JD_LENGTH_MASK) * sizeof(u32); + desc_dma = dma_map_single(dev, desc, desc_size, DMA_TO_DEVICE); + if (dma_mapping_error(dev, desc_dma)) { + dev_err(dev, "caam_jr_enqueue(): can't map jobdesc\n"); + return -EIO; + } + + spin_lock_irqsave(&jrp->inplock, flags); + + head = jrp->head; + tail = ACCESS_ONCE(jrp->tail); + + if (!rd_reg32(&jrp->rregs->inpring_avail) || + CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { + spin_unlock_irqrestore(&jrp->inplock, flags); + dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); + return -EBUSY; + } + + head_entry = &jrp->entinfo[head]; + head_entry->desc_addr_virt = desc; + head_entry->desc_size = desc_size; + head_entry->callbk = (void *)cbk; + head_entry->cbkarg = areq; + head_entry->desc_addr_dma = desc_dma; + + jrp->inpring[jrp->inp_ring_write_index] = desc_dma; + + smp_wmb(); + + jrp->inp_ring_write_index = (jrp->inp_ring_write_index + 1) & + (JOBR_DEPTH - 1); + jrp->head = (head + 1) & (JOBR_DEPTH - 1); + + wmb(); + + wr_reg32(&jrp->rregs->inpring_jobadd, 1); + + spin_unlock_irqrestore(&jrp->inplock, flags); + + return 0; +} +EXPORT_SYMBOL(caam_jr_enqueue); + +static int caam_reset_hw_jr(struct device *dev) +{ + struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); + unsigned int timeout = 100000; + + /* + * FIXME: disabling IRQs here inhibits proper job completion + * and error propagation + */ + disable_irq(jrp->irq); + + /* initiate flush (required prior to reset) */ + wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); + while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) == + JRINT_ERR_HALT_INPROGRESS) && --timeout) + cpu_relax(); + + if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) != + JRINT_ERR_HALT_COMPLETE || timeout == 0) { + dev_err(dev, "failed to flush job ring %d\n", jrp->ridx); + return -EIO; + } + + /* initiate reset */ + timeout = 100000; + wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); + while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout) + cpu_relax(); + + if (timeout == 0) { + dev_err(dev, "failed to reset job ring %d\n", jrp->ridx); + return -EIO; + } + + enable_irq(jrp->irq); + + return 0; +} + +/* + * Init JobR independent of platform property detection + */ +static int caam_jr_init(struct device *dev) +{ + struct caam_drv_private_jr *jrp; + dma_addr_t inpbusaddr, outbusaddr; + int i, error; + + jrp = dev_get_drvdata(dev); + + error = caam_reset_hw_jr(dev); + if (error) + return error; + + jrp->inpring = kzalloc(sizeof(dma_addr_t) * JOBR_DEPTH, + GFP_KERNEL | GFP_DMA); + jrp->outring = kzalloc(sizeof(struct jr_outentry) * + JOBR_DEPTH, GFP_KERNEL | GFP_DMA); + + jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH, + GFP_KERNEL); + + if ((jrp->inpring == NULL) || (jrp->outring == NULL) || + (jrp->entinfo == NULL)) { + dev_err(dev, "can't allocate job rings for %d\n", + jrp->ridx); + return -ENOMEM; + } + + for (i = 0; i < JOBR_DEPTH; i++) + jrp->entinfo[i].desc_addr_dma = !0; + + /* Setup rings */ + inpbusaddr = dma_map_single(dev, jrp->inpring, + sizeof(u32 *) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, inpbusaddr)) { + dev_err(dev, "caam_jr_init(): can't map input ring\n"); + kfree(jrp->inpring); + kfree(jrp->outring); + kfree(jrp->entinfo); + return -EIO; + } + + outbusaddr = dma_map_single(dev, jrp->outring, + sizeof(struct jr_outentry) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, outbusaddr)) { + dev_err(dev, "caam_jr_init(): can't map output ring\n"); + dma_unmap_single(dev, inpbusaddr, + sizeof(u32 *) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + kfree(jrp->inpring); + kfree(jrp->outring); + kfree(jrp->entinfo); + return -EIO; + } + + jrp->inp_ring_write_index = 0; + jrp->out_ring_read_index = 0; + jrp->head = 0; + jrp->tail = 0; + + wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); + wr_reg64(&jrp->rregs->outring_base, outbusaddr); + wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); + wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); + + jrp->ringsize = JOBR_DEPTH; + + spin_lock_init(&jrp->inplock); + spin_lock_init(&jrp->outlock); + + /* Select interrupt coalescing parameters */ + setbits32(&jrp->rregs->rconfig_lo, JOBR_INTC | + (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | + (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); + + /* Connect job ring interrupt handler. */ + for_each_possible_cpu(i) + tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, + (unsigned long)dev); + + error = request_irq(jrp->irq, caam_jr_interrupt, 0, + "caam-jobr", dev); + if (error) { + dev_err(dev, "can't connect JobR %d interrupt (%d)\n", + jrp->ridx, jrp->irq); + irq_dispose_mapping(jrp->irq); + jrp->irq = 0; + dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + dma_unmap_single(dev, outbusaddr, sizeof(u32 *) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + kfree(jrp->inpring); + kfree(jrp->outring); + kfree(jrp->entinfo); + return -EINVAL; + } + + jrp->assign = JOBR_UNASSIGNED; + return 0; +} + +/* + * Shutdown JobR independent of platform property code + */ +int caam_jr_shutdown(struct device *dev) +{ + struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); + dma_addr_t inpbusaddr, outbusaddr; + int ret, i; + + ret = caam_reset_hw_jr(dev); + + for_each_possible_cpu(i) + tasklet_kill(&jrp->irqtask[i]); + + /* Release interrupt */ + free_irq(jrp->irq, dev); + + /* Free rings */ + inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); + outbusaddr = rd_reg64(&jrp->rregs->outring_base); + dma_unmap_single(dev, outbusaddr, + sizeof(struct jr_outentry) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, + DMA_BIDIRECTIONAL); + kfree(jrp->outring); + kfree(jrp->inpring); + kfree(jrp->entinfo); + + return ret; +} + +/* + * Probe routine for each detected JobR subsystem. It assumes that + * property detection was picked up externally. + */ +int caam_jr_probe(struct platform_device *pdev, struct device_node *np, + int ring) +{ + struct device *ctrldev, *jrdev; + struct platform_device *jr_pdev; + struct caam_drv_private *ctrlpriv; + struct caam_drv_private_jr *jrpriv; + u32 *jroffset; + int error; + + ctrldev = &pdev->dev; + ctrlpriv = dev_get_drvdata(ctrldev); + + jrpriv = kmalloc(sizeof(struct caam_drv_private_jr), + GFP_KERNEL); + if (jrpriv == NULL) { + dev_err(ctrldev, "can't alloc private mem for job ring %d\n", + ring); + return -ENOMEM; + } + jrpriv->parentdev = ctrldev; /* point back to parent */ + jrpriv->ridx = ring; /* save ring identity relative to detection */ + + /* + * Derive a pointer to the detected JobRs regs + * Driver has already iomapped the entire space, we just + * need to add in the offset to this JobR. Don't know if I + * like this long-term, but it'll run + */ + jroffset = (u32 *)of_get_property(np, "reg", NULL); + jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl + + *jroffset); + + /* Build a local dev for each detected queue */ + jr_pdev = of_platform_device_create(np, NULL, ctrldev); + if (jr_pdev == NULL) { + kfree(jrpriv); + return -EINVAL; + } + jrdev = &jr_pdev->dev; + dev_set_drvdata(jrdev, jrpriv); + ctrlpriv->jrdev[ring] = jrdev; + + /* Identify the interrupt */ + jrpriv->irq = of_irq_to_resource(np, 0, NULL); + + /* Now do the platform independent part */ + error = caam_jr_init(jrdev); /* now turn on hardware */ + if (error) { + kfree(jrpriv); + return error; + } + + return error; +} diff --git a/drivers/crypto/caam/jr.h b/drivers/crypto/caam/jr.h new file mode 100644 index 000000000000..c23df395b622 --- /dev/null +++ b/drivers/crypto/caam/jr.h @@ -0,0 +1,21 @@ +/* + * CAAM public-level include definitions for the JobR backend + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#ifndef JR_H +#define JR_H + +/* Prototypes for backend-level services exposed to APIs */ +int caam_jr_register(struct device *ctrldev, struct device **rdev); +int caam_jr_deregister(struct device *rdev); +int caam_jr_enqueue(struct device *dev, u32 *desc, + void (*cbk)(struct device *dev, u32 *desc, u32 status, + void *areq), + void *areq); + +extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np, + int ring); +extern int caam_jr_shutdown(struct device *dev); +#endif /* JR_H */ diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h new file mode 100644 index 000000000000..d063a260958b --- /dev/null +++ b/drivers/crypto/caam/regs.h @@ -0,0 +1,663 @@ +/* + * CAAM hardware register-level view + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + */ + +#ifndef REGS_H +#define REGS_H + +#include +#include + +/* + * Architecture-specific register access methods + * + * CAAM's bus-addressable registers are 64 bits internally. + * They have been wired to be safely accessible on 32-bit + * architectures, however. Registers were organized such + * that (a) they can be contained in 32 bits, (b) if not, then they + * can be treated as two 32-bit entities, or finally (c) if they + * must be treated as a single 64-bit value, then this can safely + * be done with two 32-bit cycles. + * + * For 32-bit operations on 64-bit values, CAAM follows the same + * 64-bit register access conventions as it's predecessors, in that + * writes are "triggered" by a write to the register at the numerically + * higher address, thus, a full 64-bit write cycle requires a write + * to the lower address, followed by a write to the higher address, + * which will latch/execute the write cycle. + * + * For example, let's assume a SW reset of CAAM through the master + * configuration register. + * - SWRST is in bit 31 of MCFG. + * - MCFG begins at base+0x0000. + * - Bits 63-32 are a 32-bit word at base+0x0000 (numerically-lower) + * - Bits 31-0 are a 32-bit word at base+0x0004 (numerically-higher) + * + * (and on Power, the convention is 0-31, 32-63, I know...) + * + * Assuming a 64-bit write to this MCFG to perform a software reset + * would then require a write of 0 to base+0x0000, followed by a + * write of 0x80000000 to base+0x0004, which would "execute" the + * reset. + * + * Of course, since MCFG 63-32 is all zero, we could cheat and simply + * write 0x8000000 to base+0x0004, and the reset would work fine. + * However, since CAAM does contain some write-and-read-intended + * 64-bit registers, this code defines 64-bit access methods for + * the sake of internal consistency and simplicity, and so that a + * clean transition to 64-bit is possible when it becomes necessary. + * + * There are limitations to this that the developer must recognize. + * 32-bit architectures cannot enforce an atomic-64 operation, + * Therefore: + * + * - On writes, since the HW is assumed to latch the cycle on the + * write of the higher-numeric-address word, then ordered + * writes work OK. + * + * - For reads, where a register contains a relevant value of more + * that 32 bits, the hardware employs logic to latch the other + * "half" of the data until read, ensuring an accurate value. + * This is of particular relevance when dealing with CAAM's + * performance counters. + * + */ + +#ifdef __BIG_ENDIAN +#define wr_reg32(reg, data) out_be32(reg, data) +#define rd_reg32(reg) in_be32(reg) +#ifdef CONFIG_64BIT +#define wr_reg64(reg, data) out_be64(reg, data) +#define rd_reg64(reg) in_be64(reg) +#endif +#else +#ifdef __LITTLE_ENDIAN +#define wr_reg32(reg, data) __raw_writel(reg, data) +#define rd_reg32(reg) __raw_readl(reg) +#ifdef CONFIG_64BIT +#define wr_reg64(reg, data) __raw_writeq(reg, data) +#define rd_reg64(reg) __raw_readq(reg) +#endif +#endif +#endif + +#ifndef CONFIG_64BIT +static inline void wr_reg64(u64 __iomem *reg, u64 data) +{ + wr_reg32((u32 __iomem *)reg, (data & 0xffffffff00000000ull) >> 32); + wr_reg32((u32 __iomem *)reg + 1, data & 0x00000000ffffffffull); +} + +static inline u64 rd_reg64(u64 __iomem *reg) +{ + return (((u64)rd_reg32((u32 __iomem *)reg)) << 32) | + ((u64)rd_reg32((u32 __iomem *)reg + 1)); +} +#endif + +/* + * jr_outentry + * Represents each entry in a JobR output ring + */ +struct jr_outentry { + dma_addr_t desc;/* Pointer to completed descriptor */ + u32 jrstatus; /* Status for completed descriptor */ +} __packed; + +/* + * caam_perfmon - Performance Monitor/Secure Memory Status/ + * CAAM Global Status/Component Version IDs + * + * Spans f00-fff wherever instantiated + */ + +/* Number of DECOs */ +#define CHA_NUM_DECONUM_SHIFT 56 +#define CHA_NUM_DECONUM_MASK (0xfull << CHA_NUM_DECONUM_SHIFT) + +struct caam_perfmon { + /* Performance Monitor Registers f00-f9f */ + u64 req_dequeued; /* PC_REQ_DEQ - Dequeued Requests */ + u64 ob_enc_req; /* PC_OB_ENC_REQ - Outbound Encrypt Requests */ + u64 ib_dec_req; /* PC_IB_DEC_REQ - Inbound Decrypt Requests */ + u64 ob_enc_bytes; /* PC_OB_ENCRYPT - Outbound Bytes Encrypted */ + u64 ob_prot_bytes; /* PC_OB_PROTECT - Outbound Bytes Protected */ + u64 ib_dec_bytes; /* PC_IB_DECRYPT - Inbound Bytes Decrypted */ + u64 ib_valid_bytes; /* PC_IB_VALIDATED Inbound Bytes Validated */ + u64 rsvd[13]; + + /* CAAM Hardware Instantiation Parameters fa0-fbf */ + u64 cha_rev; /* CRNR - CHA Revision Number */ +#define CTPR_QI_SHIFT 57 +#define CTPR_QI_MASK (0x1ull << CHA_NUM_DECONUM_SHIFT) + u64 comp_parms; /* CTPR - Compile Parameters Register */ + u64 rsvd1[2]; + + /* CAAM Global Status fc0-fdf */ + u64 faultaddr; /* FAR - Fault Address */ + u32 faultliodn; /* FALR - Fault Address LIODN */ + u32 faultdetail; /* FADR - Fault Addr Detail */ + u32 rsvd2; + u32 status; /* CSTA - CAAM Status */ + u64 rsvd3; + + /* Component Instantiation Parameters fe0-fff */ + u32 rtic_id; /* RVID - RTIC Version ID */ + u32 ccb_id; /* CCBVID - CCB Version ID */ + u64 cha_id; /* CHAVID - CHA Version ID */ + u64 cha_num; /* CHANUM - CHA Number */ + u64 caam_id; /* CAAMVID - CAAM Version ID */ +}; + +/* LIODN programming for DMA configuration */ +#define MSTRID_LOCK_LIODN 0x80000000 +#define MSTRID_LOCK_MAKETRUSTED 0x00010000 /* only for JR masterid */ + +#define MSTRID_LIODN_MASK 0x0fff +struct masterid { + u32 liodn_ms; /* lock and make-trusted control bits */ + u32 liodn_ls; /* LIODN for non-sequence and seq access */ +}; + +/* Partition ID for DMA configuration */ +struct partid { + u32 rsvd1; + u32 pidr; /* partition ID, DECO */ +}; + +/* RNG test mode (replicated twice in some configurations) */ +/* Padded out to 0x100 */ +struct rngtst { + u32 mode; /* RTSTMODEx - Test mode */ + u32 rsvd1[3]; + u32 reset; /* RTSTRESETx - Test reset control */ + u32 rsvd2[3]; + u32 status; /* RTSTSSTATUSx - Test status */ + u32 rsvd3; + u32 errstat; /* RTSTERRSTATx - Test error status */ + u32 rsvd4; + u32 errctl; /* RTSTERRCTLx - Test error control */ + u32 rsvd5; + u32 entropy; /* RTSTENTROPYx - Test entropy */ + u32 rsvd6[15]; + u32 verifctl; /* RTSTVERIFCTLx - Test verification control */ + u32 rsvd7; + u32 verifstat; /* RTSTVERIFSTATx - Test verification status */ + u32 rsvd8; + u32 verifdata; /* RTSTVERIFDx - Test verification data */ + u32 rsvd9; + u32 xkey; /* RTSTXKEYx - Test XKEY */ + u32 rsvd10; + u32 oscctctl; /* RTSTOSCCTCTLx - Test osc. counter control */ + u32 rsvd11; + u32 oscct; /* RTSTOSCCTx - Test oscillator counter */ + u32 rsvd12; + u32 oscctstat; /* RTSTODCCTSTATx - Test osc counter status */ + u32 rsvd13[2]; + u32 ofifo[4]; /* RTSTOFIFOx - Test output FIFO */ + u32 rsvd14[15]; +}; + +/* + * caam_ctrl - basic core configuration + * starts base + 0x0000 padded out to 0x1000 + */ + +#define KEK_KEY_SIZE 8 +#define TKEK_KEY_SIZE 8 +#define TDSK_KEY_SIZE 8 + +#define DECO_RESET 1 /* Use with DECO reset/availability regs */ +#define DECO_RESET_0 (DECO_RESET << 0) +#define DECO_RESET_1 (DECO_RESET << 1) +#define DECO_RESET_2 (DECO_RESET << 2) +#define DECO_RESET_3 (DECO_RESET << 3) +#define DECO_RESET_4 (DECO_RESET << 4) + +struct caam_ctrl { + /* Basic Configuration Section 000-01f */ + /* Read/Writable */ + u32 rsvd1; + u32 mcr; /* MCFG Master Config Register */ + u32 rsvd2[2]; + + /* Bus Access Configuration Section 010-11f */ + /* Read/Writable */ + struct masterid jr_mid[4]; /* JRxLIODNR - JobR LIODN setup */ + u32 rsvd3[12]; + struct masterid rtic_mid[4]; /* RTICxLIODNR - RTIC LIODN setup */ + u32 rsvd4[7]; + u32 deco_rq; /* DECORR - DECO Request */ + struct partid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */ + u32 rsvd5[22]; + + /* DECO Availability/Reset Section 120-3ff */ + u32 deco_avail; /* DAR - DECO availability */ + u32 deco_reset; /* DRR - DECO reset */ + u32 rsvd6[182]; + + /* Key Encryption/Decryption Configuration 400-5ff */ + /* Read/Writable only while in Non-secure mode */ + u32 kek[KEK_KEY_SIZE]; /* JDKEKR - Key Encryption Key */ + u32 tkek[TKEK_KEY_SIZE]; /* TDKEKR - Trusted Desc KEK */ + u32 tdsk[TDSK_KEY_SIZE]; /* TDSKR - Trusted Desc Signing Key */ + u32 rsvd7[32]; + u64 sknonce; /* SKNR - Secure Key Nonce */ + u32 rsvd8[70]; + + /* RNG Test/Verification/Debug Access 600-7ff */ + /* (Useful in Test/Debug modes only...) */ + struct rngtst rtst[2]; + + u32 rsvd9[448]; + + /* Performance Monitor f00-fff */ + struct caam_perfmon perfmon; +}; + +/* + * Controller master config register defs + */ +#define MCFGR_SWRESET 0x80000000 /* software reset */ +#define MCFGR_WDENABLE 0x40000000 /* DECO watchdog enable */ +#define MCFGR_WDFAIL 0x20000000 /* DECO watchdog force-fail */ +#define MCFGR_DMA_RESET 0x10000000 +#define MCFGR_LONG_PTR 0x00010000 /* Use >32-bit desc addressing */ + +/* AXI read cache control */ +#define MCFGR_ARCACHE_SHIFT 12 +#define MCFGR_ARCACHE_MASK (0xf << MCFGR_ARCACHE_SHIFT) + +/* AXI write cache control */ +#define MCFGR_AWCACHE_SHIFT 8 +#define MCFGR_AWCACHE_MASK (0xf << MCFGR_AWCACHE_SHIFT) + +/* AXI pipeline depth */ +#define MCFGR_AXIPIPE_SHIFT 4 +#define MCFGR_AXIPIPE_MASK (0xf << MCFGR_AXIPIPE_SHIFT) + +#define MCFGR_AXIPRI 0x00000008 /* Assert AXI priority sideband */ +#define MCFGR_BURST_64 0x00000001 /* Max burst size */ + +/* + * caam_job_ring - direct job ring setup + * 1-4 possible per instantiation, base + 1000/2000/3000/4000 + * Padded out to 0x1000 + */ +struct caam_job_ring { + /* Input ring */ + u64 inpring_base; /* IRBAx - Input desc ring baseaddr */ + u32 rsvd1; + u32 inpring_size; /* IRSx - Input ring size */ + u32 rsvd2; + u32 inpring_avail; /* IRSAx - Input ring room remaining */ + u32 rsvd3; + u32 inpring_jobadd; /* IRJAx - Input ring jobs added */ + + /* Output Ring */ + u64 outring_base; /* ORBAx - Output status ring base addr */ + u32 rsvd4; + u32 outring_size; /* ORSx - Output ring size */ + u32 rsvd5; + u32 outring_rmvd; /* ORJRx - Output ring jobs removed */ + u32 rsvd6; + u32 outring_used; /* ORSFx - Output ring slots full */ + + /* Status/Configuration */ + u32 rsvd7; + u32 jroutstatus; /* JRSTAx - JobR output status */ + u32 rsvd8; + u32 jrintstatus; /* JRINTx - JobR interrupt status */ + u32 rconfig_hi; /* JRxCFG - Ring configuration */ + u32 rconfig_lo; + + /* Indices. CAAM maintains as "heads" of each queue */ + u32 rsvd9; + u32 inp_rdidx; /* IRRIx - Input ring read index */ + u32 rsvd10; + u32 out_wtidx; /* ORWIx - Output ring write index */ + + /* Command/control */ + u32 rsvd11; + u32 jrcommand; /* JRCRx - JobR command */ + + u32 rsvd12[932]; + + /* Performance Monitor f00-fff */ + struct caam_perfmon perfmon; +}; + +#define JR_RINGSIZE_MASK 0x03ff +/* + * jrstatus - Job Ring Output Status + * All values in lo word + * Also note, same values written out as status through QI + * in the command/status field of a frame descriptor + */ +#define JRSTA_SSRC_SHIFT 28 +#define JRSTA_SSRC_MASK 0xf0000000 + +#define JRSTA_SSRC_NONE 0x00000000 +#define JRSTA_SSRC_CCB_ERROR 0x20000000 +#define JRSTA_SSRC_JUMP_HALT_USER 0x30000000 +#define JRSTA_SSRC_DECO 0x40000000 +#define JRSTA_SSRC_JRERROR 0x60000000 +#define JRSTA_SSRC_JUMP_HALT_CC 0x70000000 + +#define JRSTA_DECOERR_JUMP 0x08000000 +#define JRSTA_DECOERR_INDEX_SHIFT 8 +#define JRSTA_DECOERR_INDEX_MASK 0xff00 +#define JRSTA_DECOERR_ERROR_MASK 0x00ff + +#define JRSTA_DECOERR_NONE 0x00 +#define JRSTA_DECOERR_LINKLEN 0x01 +#define JRSTA_DECOERR_LINKPTR 0x02 +#define JRSTA_DECOERR_JRCTRL 0x03 +#define JRSTA_DECOERR_DESCCMD 0x04 +#define JRSTA_DECOERR_ORDER 0x05 +#define JRSTA_DECOERR_KEYCMD 0x06 +#define JRSTA_DECOERR_LOADCMD 0x07 +#define JRSTA_DECOERR_STORECMD 0x08 +#define JRSTA_DECOERR_OPCMD 0x09 +#define JRSTA_DECOERR_FIFOLDCMD 0x0a +#define JRSTA_DECOERR_FIFOSTCMD 0x0b +#define JRSTA_DECOERR_MOVECMD 0x0c +#define JRSTA_DECOERR_JUMPCMD 0x0d +#define JRSTA_DECOERR_MATHCMD 0x0e +#define JRSTA_DECOERR_SHASHCMD 0x0f +#define JRSTA_DECOERR_SEQCMD 0x10 +#define JRSTA_DECOERR_DECOINTERNAL 0x11 +#define JRSTA_DECOERR_SHDESCHDR 0x12 +#define JRSTA_DECOERR_HDRLEN 0x13 +#define JRSTA_DECOERR_BURSTER 0x14 +#define JRSTA_DECOERR_DESCSIGNATURE 0x15 +#define JRSTA_DECOERR_DMA 0x16 +#define JRSTA_DECOERR_BURSTFIFO 0x17 +#define JRSTA_DECOERR_JRRESET 0x1a +#define JRSTA_DECOERR_JOBFAIL 0x1b +#define JRSTA_DECOERR_DNRERR 0x80 +#define JRSTA_DECOERR_UNDEFPCL 0x81 +#define JRSTA_DECOERR_PDBERR 0x82 +#define JRSTA_DECOERR_ANRPLY_LATE 0x83 +#define JRSTA_DECOERR_ANRPLY_REPLAY 0x84 +#define JRSTA_DECOERR_SEQOVF 0x85 +#define JRSTA_DECOERR_INVSIGN 0x86 +#define JRSTA_DECOERR_DSASIGN 0x87 + +#define JRSTA_CCBERR_JUMP 0x08000000 +#define JRSTA_CCBERR_INDEX_MASK 0xff00 +#define JRSTA_CCBERR_INDEX_SHIFT 8 +#define JRSTA_CCBERR_CHAID_MASK 0x00f0 +#define JRSTA_CCBERR_CHAID_SHIFT 4 +#define JRSTA_CCBERR_ERRID_MASK 0x000f + +#define JRSTA_CCBERR_CHAID_AES (0x01 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_DES (0x02 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_ARC4 (0x03 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_MD (0x04 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_RNG (0x05 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_SNOW (0x06 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_KASUMI (0x07 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_PK (0x08 << JRSTA_CCBERR_CHAID_SHIFT) +#define JRSTA_CCBERR_CHAID_CRC (0x09 << JRSTA_CCBERR_CHAID_SHIFT) + +#define JRSTA_CCBERR_ERRID_NONE 0x00 +#define JRSTA_CCBERR_ERRID_MODE 0x01 +#define JRSTA_CCBERR_ERRID_DATASIZ 0x02 +#define JRSTA_CCBERR_ERRID_KEYSIZ 0x03 +#define JRSTA_CCBERR_ERRID_PKAMEMSZ 0x04 +#define JRSTA_CCBERR_ERRID_PKBMEMSZ 0x05 +#define JRSTA_CCBERR_ERRID_SEQUENCE 0x06 +#define JRSTA_CCBERR_ERRID_PKDIVZRO 0x07 +#define JRSTA_CCBERR_ERRID_PKMODEVN 0x08 +#define JRSTA_CCBERR_ERRID_KEYPARIT 0x09 +#define JRSTA_CCBERR_ERRID_ICVCHK 0x0a +#define JRSTA_CCBERR_ERRID_HARDWARE 0x0b +#define JRSTA_CCBERR_ERRID_CCMAAD 0x0c +#define JRSTA_CCBERR_ERRID_INVCHA 0x0f + +#define JRINT_ERR_INDEX_MASK 0x3fff0000 +#define JRINT_ERR_INDEX_SHIFT 16 +#define JRINT_ERR_TYPE_MASK 0xf00 +#define JRINT_ERR_TYPE_SHIFT 8 +#define JRINT_ERR_HALT_MASK 0xc +#define JRINT_ERR_HALT_SHIFT 2 +#define JRINT_ERR_HALT_INPROGRESS 0x4 +#define JRINT_ERR_HALT_COMPLETE 0x8 +#define JRINT_JR_ERROR 0x02 +#define JRINT_JR_INT 0x01 + +#define JRINT_ERR_TYPE_WRITE 1 +#define JRINT_ERR_TYPE_BAD_INPADDR 3 +#define JRINT_ERR_TYPE_BAD_OUTADDR 4 +#define JRINT_ERR_TYPE_INV_INPWRT 5 +#define JRINT_ERR_TYPE_INV_OUTWRT 6 +#define JRINT_ERR_TYPE_RESET 7 +#define JRINT_ERR_TYPE_REMOVE_OFL 8 +#define JRINT_ERR_TYPE_ADD_OFL 9 + +#define JRCFG_SOE 0x04 +#define JRCFG_ICEN 0x02 +#define JRCFG_IMSK 0x01 +#define JRCFG_ICDCT_SHIFT 8 +#define JRCFG_ICTT_SHIFT 16 + +#define JRCR_RESET 0x01 + +/* + * caam_assurance - Assurance Controller View + * base + 0x6000 padded out to 0x1000 + */ + +struct rtic_element { + u64 address; + u32 rsvd; + u32 length; +}; + +struct rtic_block { + struct rtic_element element[2]; +}; + +struct rtic_memhash { + u32 memhash_be[32]; + u32 memhash_le[32]; +}; + +struct caam_assurance { + /* Status/Command/Watchdog */ + u32 rsvd1; + u32 status; /* RSTA - Status */ + u32 rsvd2; + u32 cmd; /* RCMD - Command */ + u32 rsvd3; + u32 ctrl; /* RCTL - Control */ + u32 rsvd4; + u32 throttle; /* RTHR - Throttle */ + u32 rsvd5[2]; + u64 watchdog; /* RWDOG - Watchdog Timer */ + u32 rsvd6; + u32 rend; /* REND - Endian corrections */ + u32 rsvd7[50]; + + /* Block access/configuration @ 100/110/120/130 */ + struct rtic_block memblk[4]; /* Memory Blocks A-D */ + u32 rsvd8[32]; + + /* Block hashes @ 200/300/400/500 */ + struct rtic_memhash hash[4]; /* Block hash values A-D */ + u32 rsvd_3[640]; +}; + +/* + * caam_queue_if - QI configuration and control + * starts base + 0x7000, padded out to 0x1000 long + */ + +struct caam_queue_if { + u32 qi_control_hi; /* QICTL - QI Control */ + u32 qi_control_lo; + u32 rsvd1; + u32 qi_status; /* QISTA - QI Status */ + u32 qi_deq_cfg_hi; /* QIDQC - QI Dequeue Configuration */ + u32 qi_deq_cfg_lo; + u32 qi_enq_cfg_hi; /* QISEQC - QI Enqueue Command */ + u32 qi_enq_cfg_lo; + u32 rsvd2[1016]; +}; + +/* QI control bits - low word */ +#define QICTL_DQEN 0x01 /* Enable frame pop */ +#define QICTL_STOP 0x02 /* Stop dequeue/enqueue */ +#define QICTL_SOE 0x04 /* Stop on error */ + +/* QI control bits - high word */ +#define QICTL_MBSI 0x01 +#define QICTL_MHWSI 0x02 +#define QICTL_MWSI 0x04 +#define QICTL_MDWSI 0x08 +#define QICTL_CBSI 0x10 /* CtrlDataByteSwapInput */ +#define QICTL_CHWSI 0x20 /* CtrlDataHalfSwapInput */ +#define QICTL_CWSI 0x40 /* CtrlDataWordSwapInput */ +#define QICTL_CDWSI 0x80 /* CtrlDataDWordSwapInput */ +#define QICTL_MBSO 0x0100 +#define QICTL_MHWSO 0x0200 +#define QICTL_MWSO 0x0400 +#define QICTL_MDWSO 0x0800 +#define QICTL_CBSO 0x1000 /* CtrlDataByteSwapOutput */ +#define QICTL_CHWSO 0x2000 /* CtrlDataHalfSwapOutput */ +#define QICTL_CWSO 0x4000 /* CtrlDataWordSwapOutput */ +#define QICTL_CDWSO 0x8000 /* CtrlDataDWordSwapOutput */ +#define QICTL_DMBS 0x010000 +#define QICTL_EPO 0x020000 + +/* QI status bits */ +#define QISTA_PHRDERR 0x01 /* PreHeader Read Error */ +#define QISTA_CFRDERR 0x02 /* Compound Frame Read Error */ +#define QISTA_OFWRERR 0x04 /* Output Frame Read Error */ +#define QISTA_BPDERR 0x08 /* Buffer Pool Depleted */ +#define QISTA_BTSERR 0x10 /* Buffer Undersize */ +#define QISTA_CFWRERR 0x20 /* Compound Frame Write Err */ +#define QISTA_STOPD 0x80000000 /* QI Stopped (see QICTL) */ + +/* deco_sg_table - DECO view of scatter/gather table */ +struct deco_sg_table { + u64 addr; /* Segment Address */ + u32 elen; /* E, F bits + 30-bit length */ + u32 bpid_offset; /* Buffer Pool ID + 16-bit length */ +}; + +/* + * caam_deco - descriptor controller - CHA cluster block + * + * Only accessible when direct DECO access is turned on + * (done in DECORR, via MID programmed in DECOxMID + * + * 5 typical, base + 0x8000/9000/a000/b000 + * Padded out to 0x1000 long + */ +struct caam_deco { + u32 rsvd1; + u32 cls1_mode; /* CxC1MR - Class 1 Mode */ + u32 rsvd2; + u32 cls1_keysize; /* CxC1KSR - Class 1 Key Size */ + u32 cls1_datasize_hi; /* CxC1DSR - Class 1 Data Size */ + u32 cls1_datasize_lo; + u32 rsvd3; + u32 cls1_icvsize; /* CxC1ICVSR - Class 1 ICV size */ + u32 rsvd4[5]; + u32 cha_ctrl; /* CCTLR - CHA control */ + u32 rsvd5; + u32 irq_crtl; /* CxCIRQ - CCB interrupt done/error/clear */ + u32 rsvd6; + u32 clr_written; /* CxCWR - Clear-Written */ + u32 ccb_status_hi; /* CxCSTA - CCB Status/Error */ + u32 ccb_status_lo; + u32 rsvd7[3]; + u32 aad_size; /* CxAADSZR - Current AAD Size */ + u32 rsvd8; + u32 cls1_iv_size; /* CxC1IVSZR - Current Class 1 IV Size */ + u32 rsvd9[7]; + u32 pkha_a_size; /* PKASZRx - Size of PKHA A */ + u32 rsvd10; + u32 pkha_b_size; /* PKBSZRx - Size of PKHA B */ + u32 rsvd11; + u32 pkha_n_size; /* PKNSZRx - Size of PKHA N */ + u32 rsvd12; + u32 pkha_e_size; /* PKESZRx - Size of PKHA E */ + u32 rsvd13[24]; + u32 cls1_ctx[16]; /* CxC1CTXR - Class 1 Context @100 */ + u32 rsvd14[48]; + u32 cls1_key[8]; /* CxC1KEYR - Class 1 Key @200 */ + u32 rsvd15[121]; + u32 cls2_mode; /* CxC2MR - Class 2 Mode */ + u32 rsvd16; + u32 cls2_keysize; /* CxX2KSR - Class 2 Key Size */ + u32 cls2_datasize_hi; /* CxC2DSR - Class 2 Data Size */ + u32 cls2_datasize_lo; + u32 rsvd17; + u32 cls2_icvsize; /* CxC2ICVSZR - Class 2 ICV Size */ + u32 rsvd18[56]; + u32 cls2_ctx[18]; /* CxC2CTXR - Class 2 Context @500 */ + u32 rsvd19[46]; + u32 cls2_key[32]; /* CxC2KEYR - Class2 Key @600 */ + u32 rsvd20[84]; + u32 inp_infofifo_hi; /* CxIFIFO - Input Info FIFO @7d0 */ + u32 inp_infofifo_lo; + u32 rsvd21[2]; + u64 inp_datafifo; /* CxDFIFO - Input Data FIFO */ + u32 rsvd22[2]; + u64 out_datafifo; /* CxOFIFO - Output Data FIFO */ + u32 rsvd23[2]; + u32 jr_ctl_hi; /* CxJRR - JobR Control Register @800 */ + u32 jr_ctl_lo; + u64 jr_descaddr; /* CxDADR - JobR Descriptor Address */ + u32 op_status_hi; /* DxOPSTA - DECO Operation Status */ + u32 op_status_lo; + u32 rsvd24[2]; + u32 liodn; /* DxLSR - DECO LIODN Status - non-seq */ + u32 td_liodn; /* DxLSR - DECO LIODN Status - trustdesc */ + u32 rsvd26[6]; + u64 math[4]; /* DxMTH - Math register */ + u32 rsvd27[8]; + struct deco_sg_table gthr_tbl[4]; /* DxGTR - Gather Tables */ + u32 rsvd28[16]; + struct deco_sg_table sctr_tbl[4]; /* DxSTR - Scatter Tables */ + u32 rsvd29[48]; + u32 descbuf[64]; /* DxDESB - Descriptor buffer */ + u32 rsvd30[320]; +}; + +/* + * Current top-level view of memory map is: + * + * 0x0000 - 0x0fff - CAAM Top-Level Control + * 0x1000 - 0x1fff - Job Ring 0 + * 0x2000 - 0x2fff - Job Ring 1 + * 0x3000 - 0x3fff - Job Ring 2 + * 0x4000 - 0x4fff - Job Ring 3 + * 0x5000 - 0x5fff - (unused) + * 0x6000 - 0x6fff - Assurance Controller + * 0x7000 - 0x7fff - Queue Interface + * 0x8000 - 0x8fff - DECO-CCB 0 + * 0x9000 - 0x9fff - DECO-CCB 1 + * 0xa000 - 0xafff - DECO-CCB 2 + * 0xb000 - 0xbfff - DECO-CCB 3 + * 0xc000 - 0xcfff - DECO-CCB 4 + * + * caam_full describes the full register view of CAAM if useful, + * although many configurations may choose to implement parts of + * the register map separately, in differing privilege regions + */ +struct caam_full { + struct caam_ctrl __iomem ctrl; + struct caam_job_ring jr[4]; + u64 rsvd[512]; + struct caam_assurance assure; + struct caam_queue_if qi; + struct caam_deco *deco; +}; + +#endif /* REGS_H */ -- GitLab From 54e198d4c162b36ba864ecc658c829454074523f Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 23 Mar 2011 21:15:44 +0800 Subject: [PATCH 0097/5560] crypto: caam - standardize device tree naming convention to utilize '-vX.Y' Help clarify that the number trailing in compatible nomenclature is the version number of the device, i.e., change: "fsl,p4080-sec4.0", "fsl,sec4.0"; to: "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; Signed-off-by: Kim Phillips Cc: Kumar Gala Cc: Steve Cornelius Signed-off-by: Herbert Xu --- .../devicetree/bindings/crypto/fsl-sec4.txt | 68 +++++++++---------- arch/powerpc/boot/dts/p4080ds.dts | 41 +++++------ drivers/crypto/caam/caamalg.c | 4 +- drivers/crypto/caam/ctrl.c | 6 +- 4 files changed, 60 insertions(+), 59 deletions(-) diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt index fce16a85e2c5..568aa3cb5276 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt @@ -53,7 +53,7 @@ PROPERTIES - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec4.0","fsl,sec-4.0" + Definition: Must include "fsl,p4080-sec-v4.0","fsl,sec-v4.0" - #address-cells Usage: required @@ -72,7 +72,7 @@ PROPERTIES Usage: required Value type: Definition: A standard property. Specifies the physical - address and length of the SEC4.0 configuration registers. + address and length of the SEC4 configuration registers. registers - ranges @@ -105,7 +105,7 @@ PROPERTIES EXAMPLE crypto@300000 { - compatible = "fsl,p4080-sec4.0", "fsl,sec4.0"; + compatible = "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; reg = <0x300000 0x10000>; @@ -127,7 +127,7 @@ P4080 Job Ring (JR) Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec4.0-job-ring","fsl,sec4.0-job-ring" + Definition: Must include "fsl,p4080-sec-v4.0-job-ring","fsl,sec-v4.0-job-ring" - reg Usage: required @@ -163,8 +163,8 @@ P4080 Job Ring (JR) Node EXAMPLE jr@1000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; fsl,liodn = <0x081>; interrupt-parent = <&mpic>; @@ -186,7 +186,7 @@ P4080 Run Time Integrity Check (RTIC) Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec4.0-rtic","fsl,sec4.0-rtic". + Definition: Must include "fsl,p4080-sec-v4.0-rtic","fsl,sec-v4.0-rtic". - #address-cells Usage: required @@ -219,8 +219,8 @@ P4080 Run Time Integrity Check (RTIC) Node EXAMPLE rtic@6000 { - compatible = "fsl,p4080-sec4.0-rtic", - "fsl,sec4.0-rtic"; + compatible = "fsl,p4080-sec-v4.0-rtic", + "fsl,sec-v4.0-rtic"; #address-cells = <1>; #size-cells = <1>; reg = <0x6000 0x100>; @@ -238,7 +238,7 @@ P4080 Run Time Integrity Check (RTIC) Memory Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec4.0-rtic-memory","fsl,sec4.0-rtic-memory". + Definition: Must include "fsl,p4080-sec-v4.0-rtic-memory","fsl,sec-v4.0-rtic-memory". - reg Usage: required @@ -270,8 +270,8 @@ P4080 Run Time Integrity Check (RTIC) Memory Node EXAMPLE rtic-a@0 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x00 0x20 0x100 0x80>; fsl,liodn = <0x03c>; fsl,rtic-region = <0x12345678 0x12345678 0x12345678>; @@ -288,7 +288,7 @@ P4080 Secure Non-Volatile Storage (SNVS) Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon". + Definition: Must include "fsl,p4080-sec-v4.0-mon", "fsl,sec-v4.0-mon". - reg Usage: required @@ -315,7 +315,7 @@ P4080 Secure Non-Volatile Storage (SNVS) Node EXAMPLE sec_mon@314000 { - compatible = "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon"; + compatible = "fsl,p4080-sec-v4.0-mon", "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; interrupt-parent = <&mpic>; interrupts = <93 2>; @@ -325,7 +325,7 @@ EXAMPLE FULL EXAMPLE crypto: crypto@300000 { - compatible = "fsl,p4080-sec4.0", "fsl,sec4.0"; + compatible = "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; reg = <0x300000 0x10000>; @@ -334,73 +334,73 @@ FULL EXAMPLE interrupts = <92 2>; sec_jr0: jr@1000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupt-parent = <&mpic>; interrupts = <88 2>; }; sec_jr1: jr@2000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupt-parent = <&mpic>; interrupts = <89 2>; }; sec_jr2: jr@3000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupt-parent = <&mpic>; interrupts = <90 2>; }; sec_jr3: jr@4000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x4000 0x1000>; interrupt-parent = <&mpic>; interrupts = <91 2>; }; rtic@6000 { - compatible = "fsl,p4080-sec4.0-rtic", - "fsl,sec4.0-rtic"; + compatible = "fsl,p4080-sec-v4.0-rtic", + "fsl,sec-v4.0-rtic"; #address-cells = <1>; #size-cells = <1>; reg = <0x6000 0x100>; ranges = <0x0 0x6100 0xe00>; rtic_a: rtic-a@0 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x00 0x20 0x100 0x80>; }; rtic_b: rtic-b@20 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x20 0x20 0x200 0x80>; }; rtic_c: rtic-c@40 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x40 0x20 0x300 0x80>; }; rtic_d: rtic-d@60 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x60 0x20 0x500 0x80>; }; }; }; sec_mon: sec_mon@314000 { - compatible = "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon"; + compatible = "fsl,p4080-sec-v4.0-mon", "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; interrupt-parent = <&mpic>; interrupts = <93 2>; diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts index c78e80155019..0430d241fde8 100644 --- a/arch/powerpc/boot/dts/p4080ds.dts +++ b/arch/powerpc/boot/dts/p4080ds.dts @@ -423,7 +423,7 @@ }; crypto: crypto@300000 { - compatible = "fsl,p4080-sec4.0", "fsl,sec4.0"; + compatible = "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; reg = <0x300000 0x10000>; @@ -432,73 +432,74 @@ interrupts = <92 2>; sec_jr0: jr@1000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupt-parent = <&mpic>; interrupts = <88 2>; }; sec_jr1: jr@2000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupt-parent = <&mpic>; interrupts = <89 2>; }; sec_jr2: jr@3000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupt-parent = <&mpic>; interrupts = <90 2>; }; sec_jr3: jr@4000 { - compatible = "fsl,p4080-sec4.0-job-ring", - "fsl,sec4.0-job-ring"; + compatible = "fsl,p4080-sec-v4.0-job-ring", + "fsl,sec-v4.0-job-ring"; reg = <0x4000 0x1000>; interrupt-parent = <&mpic>; interrupts = <91 2>; }; rtic@6000 { - compatible = "fsl,p4080-sec4.0-rtic", - "fsl,sec4.0-rtic"; + compatible = "fsl,p4080-sec-v4.0-rtic", + "fsl,sec-v4.0-rtic"; #address-cells = <1>; #size-cells = <1>; reg = <0x6000 0x100>; ranges = <0x0 0x6100 0xe00>; rtic_a: rtic-a@0 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x00 0x20 0x100 0x80>; }; rtic_b: rtic-b@20 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x20 0x20 0x200 0x80>; }; rtic_c: rtic-c@40 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x40 0x20 0x300 0x80>; }; rtic_d: rtic-d@60 { - compatible = "fsl,p4080-sec4.0-rtic-memory", - "fsl,sec4.0-rtic-memory"; + compatible = "fsl,p4080-sec-v4.0-rtic-memory", + "fsl,sec-v4.0-rtic-memory"; reg = <0x60 0x20 0x500 0x80>; }; }; }; sec_mon: sec_mon@314000 { - compatible = "fsl,p4080-sec4.0-mon", "fsl,sec4.0-mon"; + compatible = "fsl,p4080-sec-v4.0-mon", + "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; interrupt-parent = <&mpic>; interrupts = <93 2>; diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index d7fe3d3d7db9..140343496096 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1020,7 +1020,7 @@ static void __exit caam_algapi_exit(void) struct caam_crypto_alg *t_alg, *n; int i, err; - dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); if (!dev_node) return; @@ -1094,7 +1094,7 @@ static int __init caam_algapi_init(void) struct caam_drv_private *priv; int i = 0, err = 0; - dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); if (!dev_node) return -ENODEV; diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index aa2216160103..59aae4e3b54b 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -108,7 +108,7 @@ static int caam_probe(struct platform_device *pdev, * for all, then go probe each one. */ rspec = 0; - for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") + for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") rspec++; ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL); if (ctrlpriv->jrdev == NULL) { @@ -118,7 +118,7 @@ static int caam_probe(struct platform_device *pdev, ring = 0; ctrlpriv->total_jobrs = 0; - for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") { + for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") { caam_jr_probe(pdev, np, ring); ctrlpriv->total_jobrs++; ring++; @@ -236,7 +236,7 @@ static int caam_probe(struct platform_device *pdev, static struct of_device_id caam_match[] = { { - .compatible = "fsl,sec4.0", + .compatible = "fsl,sec-v4.0", }, {}, }; -- GitLab From cdc712d884cec0354d6899e7a329eee542ca2f7d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Mar 2011 21:20:27 +0800 Subject: [PATCH 0098/5560] crypto: caam - dereferencing ERR_PTR on allocation failure t_alg is an ERR_PTR here so we can't dereference it. Signed-off-by: Dan Carpenter Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 140343496096..dce44b2d1833 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1136,7 +1136,7 @@ static int __init caam_algapi_init(void) if (IS_ERR(t_alg)) { err = PTR_ERR(t_alg); dev_warn(ctrldev, "%s alg allocation failed\n", - t_alg->crypto_alg.cra_driver_name); + driver_algs[i].driver_name); continue; } -- GitLab From 6d00376ad15a931d4b148e52d80abc54173e9bf5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Mar 2011 21:21:53 +0800 Subject: [PATCH 0099/5560] crypto: caam - ARRAY_SIZE() vs sizeof() ARRAY_SIZE() was intended here instead of sizeof(). sizeof() is four times larger than ARRAY_SIZE(). outstr is normally 256 chars so printing garbage to it could overfill the buffer and corrupt memory. Signed-off-by: Dan Carpenter Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/error.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c index bd57a6825f57..7e2d54bffad6 100644 --- a/drivers/crypto/caam/error.c +++ b/drivers/crypto/caam/error.c @@ -73,7 +73,7 @@ static void report_ccb_status(u32 status, char *outstr) report_jump_idx(status, outstr); - if (cha_id < sizeof(cha_id_list)) { + if (cha_id < ARRAY_SIZE(cha_id_list)) { SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id], strlen(cha_id_list[cha_id])); } else { @@ -81,7 +81,7 @@ static void report_ccb_status(u32 status, char *outstr) cha_id, sizeof("ff")); } - if (err_id < sizeof(err_id_list)) { + if (err_id < ARRAY_SIZE(err_id_list)) { SPRINTFCAT(outstr, "%s", err_id_list[err_id], strlen(err_id_list[err_id])); } else { @@ -198,11 +198,11 @@ static void report_deco_status(u32 status, char *outstr) report_jump_idx(status, outstr); - for (i = 0; i < sizeof(desc_error_list); i++) + for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) if (desc_error_list[i].value == desc_error) break; - if (i != sizeof(desc_error_list) && desc_error_list[i].error_text) { + if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) { SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text, strlen(desc_error_list[i].error_text)); } else { -- GitLab From 7dfc2179ec7339a180e822a5af7eb1294da245cf Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 23 Mar 2011 21:23:36 +0800 Subject: [PATCH 0100/5560] crypto: caam - de-CHIP-ify device tree compatibles - all the integration parameters have been captured by the binding. - the block name really uniquely identifies this hardware. Some advocate putting SoC names everywhere in case software needs to work around some chip-specific bug, but more precise SoC information already exists in SVR, and board information already exists in the top-level device tree node. Note that sometimes the SoC name is a worse identifier than the block version, as the block version can change between revisions of the same SoC. As a matter of historical reference, neither SEC versions 2.x nor 3.x (driven by talitos) ever needed CHIP references. Signed-off-by: Kim Phillips Cc: Kumar Gala Cc: Scott Wood Acked-off-by: Grant Likely Signed-off-by: Herbert Xu --- .../devicetree/bindings/crypto/fsl-sec4.txt | 64 ++++++++----------- arch/powerpc/boot/dts/p4080ds.dts | 32 ++++------ 2 files changed, 37 insertions(+), 59 deletions(-) diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt index 568aa3cb5276..bf57ecd5d73a 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt @@ -38,7 +38,7 @@ in the memory partition devoted to a particular core. The P4080 has 4 JRs, so up to 4 JRs can be configured; and all 4 JRs process requests in parallel. ===================================================================== -P4080 SEC 4 Node +SEC 4 Node Description @@ -53,7 +53,7 @@ PROPERTIES - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec-v4.0","fsl,sec-v4.0" + Definition: Must include "fsl,sec-v4.0" - #address-cells Usage: required @@ -105,7 +105,7 @@ PROPERTIES EXAMPLE crypto@300000 { - compatible = "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; + compatible = "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; reg = <0x300000 0x10000>; @@ -115,7 +115,7 @@ EXAMPLE }; ===================================================================== -P4080 Job Ring (JR) Node +Job Ring (JR) Node Child of the crypto node defines data processing interface to SEC 4 across the peripheral bus for purposes of processing @@ -127,7 +127,7 @@ P4080 Job Ring (JR) Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec-v4.0-job-ring","fsl,sec-v4.0-job-ring" + Definition: Must include "fsl,sec-v4.0-job-ring" - reg Usage: required @@ -163,8 +163,7 @@ P4080 Job Ring (JR) Node EXAMPLE jr@1000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; fsl,liodn = <0x081>; interrupt-parent = <&mpic>; @@ -173,7 +172,7 @@ EXAMPLE ===================================================================== -P4080 Run Time Integrity Check (RTIC) Node +Run Time Integrity Check (RTIC) Node Child node of the crypto node. Defines a register space that contains up to 5 sets of addresses and their lengths (sizes) that @@ -186,7 +185,7 @@ P4080 Run Time Integrity Check (RTIC) Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec-v4.0-rtic","fsl,sec-v4.0-rtic". + Definition: Must include "fsl,sec-v4.0-rtic". - #address-cells Usage: required @@ -219,8 +218,7 @@ P4080 Run Time Integrity Check (RTIC) Node EXAMPLE rtic@6000 { - compatible = "fsl,p4080-sec-v4.0-rtic", - "fsl,sec-v4.0-rtic"; + compatible = "fsl,sec-v4.0-rtic"; #address-cells = <1>; #size-cells = <1>; reg = <0x6000 0x100>; @@ -228,7 +226,7 @@ EXAMPLE }; ===================================================================== -P4080 Run Time Integrity Check (RTIC) Memory Node +Run Time Integrity Check (RTIC) Memory Node A child node that defines individual RTIC memory regions that are used to perform run-time integrity check of memory areas that should not modified. The node defines a register that contains the memory address & @@ -238,7 +236,7 @@ P4080 Run Time Integrity Check (RTIC) Memory Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec-v4.0-rtic-memory","fsl,sec-v4.0-rtic-memory". + Definition: Must include "fsl,sec-v4.0-rtic-memory". - reg Usage: required @@ -270,15 +268,14 @@ P4080 Run Time Integrity Check (RTIC) Memory Node EXAMPLE rtic-a@0 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x00 0x20 0x100 0x80>; fsl,liodn = <0x03c>; fsl,rtic-region = <0x12345678 0x12345678 0x12345678>; }; ===================================================================== -P4080 Secure Non-Volatile Storage (SNVS) Node +Secure Non-Volatile Storage (SNVS) Node Node defines address range and the associated interrupt for the SNVS function. This function @@ -288,7 +285,7 @@ P4080 Secure Non-Volatile Storage (SNVS) Node - compatible Usage: required Value type: - Definition: Must include "fsl,p4080-sec-v4.0-mon", "fsl,sec-v4.0-mon". + Definition: Must include "fsl,sec-v4.0-mon". - reg Usage: required @@ -315,7 +312,7 @@ P4080 Secure Non-Volatile Storage (SNVS) Node EXAMPLE sec_mon@314000 { - compatible = "fsl,p4080-sec-v4.0-mon", "fsl,sec-v4.0-mon"; + compatible = "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; interrupt-parent = <&mpic>; interrupts = <93 2>; @@ -325,7 +322,7 @@ EXAMPLE FULL EXAMPLE crypto: crypto@300000 { - compatible = "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; + compatible = "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; reg = <0x300000 0x10000>; @@ -334,73 +331,64 @@ FULL EXAMPLE interrupts = <92 2>; sec_jr0: jr@1000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupt-parent = <&mpic>; interrupts = <88 2>; }; sec_jr1: jr@2000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupt-parent = <&mpic>; interrupts = <89 2>; }; sec_jr2: jr@3000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupt-parent = <&mpic>; interrupts = <90 2>; }; sec_jr3: jr@4000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x4000 0x1000>; interrupt-parent = <&mpic>; interrupts = <91 2>; }; rtic@6000 { - compatible = "fsl,p4080-sec-v4.0-rtic", - "fsl,sec-v4.0-rtic"; + compatible = "fsl,sec-v4.0-rtic"; #address-cells = <1>; #size-cells = <1>; reg = <0x6000 0x100>; ranges = <0x0 0x6100 0xe00>; rtic_a: rtic-a@0 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x00 0x20 0x100 0x80>; }; rtic_b: rtic-b@20 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x20 0x20 0x200 0x80>; }; rtic_c: rtic-c@40 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x40 0x20 0x300 0x80>; }; rtic_d: rtic-d@60 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x60 0x20 0x500 0x80>; }; }; }; sec_mon: sec_mon@314000 { - compatible = "fsl,p4080-sec-v4.0-mon", "fsl,sec-v4.0-mon"; + compatible = "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; interrupt-parent = <&mpic>; interrupts = <93 2>; diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts index 0430d241fde8..927f94d16e9b 100644 --- a/arch/powerpc/boot/dts/p4080ds.dts +++ b/arch/powerpc/boot/dts/p4080ds.dts @@ -423,7 +423,7 @@ }; crypto: crypto@300000 { - compatible = "fsl,p4080-sec-v4.0", "fsl,sec-v4.0"; + compatible = "fsl,sec-v4.0"; #address-cells = <1>; #size-cells = <1>; reg = <0x300000 0x10000>; @@ -432,74 +432,64 @@ interrupts = <92 2>; sec_jr0: jr@1000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x1000 0x1000>; interrupt-parent = <&mpic>; interrupts = <88 2>; }; sec_jr1: jr@2000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x2000 0x1000>; interrupt-parent = <&mpic>; interrupts = <89 2>; }; sec_jr2: jr@3000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x3000 0x1000>; interrupt-parent = <&mpic>; interrupts = <90 2>; }; sec_jr3: jr@4000 { - compatible = "fsl,p4080-sec-v4.0-job-ring", - "fsl,sec-v4.0-job-ring"; + compatible = "fsl,sec-v4.0-job-ring"; reg = <0x4000 0x1000>; interrupt-parent = <&mpic>; interrupts = <91 2>; }; rtic@6000 { - compatible = "fsl,p4080-sec-v4.0-rtic", - "fsl,sec-v4.0-rtic"; + compatible = "fsl,sec-v4.0-rtic"; #address-cells = <1>; #size-cells = <1>; reg = <0x6000 0x100>; ranges = <0x0 0x6100 0xe00>; rtic_a: rtic-a@0 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x00 0x20 0x100 0x80>; }; rtic_b: rtic-b@20 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x20 0x20 0x200 0x80>; }; rtic_c: rtic-c@40 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x40 0x20 0x300 0x80>; }; rtic_d: rtic-d@60 { - compatible = "fsl,p4080-sec-v4.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; + compatible = "fsl,sec-v4.0-rtic-memory"; reg = <0x60 0x20 0x500 0x80>; }; }; }; sec_mon: sec_mon@314000 { - compatible = "fsl,p4080-sec-v4.0-mon", - "fsl,sec-v4.0-mon"; + compatible = "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; interrupt-parent = <&mpic>; interrupts = <93 2>; -- GitLab From 0475add3c27a43a6599fe6338f8fffe919a13547 Mon Sep 17 00:00:00 2001 From: Brilly Wu Date: Sun, 27 Mar 2011 10:45:00 +0800 Subject: [PATCH 0101/5560] crypto: padlock - Add SHA-1/256 module for VIA Nano Add new SHA-1/256 module that never needs any fallback and just calls the PadLock hardware instruction supported from VIA Nano processors to implement the "update" and "final" function. They are respectively named "sha1_alg_nano" and "sha256_alg_nano", and will be used on any VIA Nano processor or the later ones. On VIA C7 CPU, the "sha1_alg" and "sha256_alg" modules will still be used as before. Signed-off-by: Brilly Wu Signed-off-by: Kary Jin Signed-off-by: Herbert Xu --- drivers/crypto/padlock-sha.c | 269 ++++++++++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index adf075b6b9a8..06bdb4b2c6a6 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -288,9 +288,250 @@ static struct shash_alg sha256_alg = { } }; +/* Add two shash_alg instance for hardware-implemented * +* multiple-parts hash supported by VIA Nano Processor.*/ +static int padlock_sha1_init_nano(struct shash_desc *desc) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + + *sctx = (struct sha1_state){ + .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, + }; + + return 0; +} + +static int padlock_sha1_update_nano(struct shash_desc *desc, + const u8 *data, unsigned int len) +{ + struct sha1_state *sctx = shash_desc_ctx(desc); + unsigned int partial, done; + const u8 *src; + /*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/ + u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__ + ((aligned(STACK_ALIGN))); + u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT); + int ts_state; + + partial = sctx->count & 0x3f; + sctx->count += len; + done = 0; + src = data; + memcpy(dst, (u8 *)(sctx->state), SHA1_DIGEST_SIZE); + + if ((partial + len) >= SHA1_BLOCK_SIZE) { + + /* Append the bytes in state's buffer to a block to handle */ + if (partial) { + done = -partial; + memcpy(sctx->buffer + partial, data, + done + SHA1_BLOCK_SIZE); + src = sctx->buffer; + ts_state = irq_ts_save(); + asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" + : "+S"(src), "+D"(dst) \ + : "a"((long)-1), "c"((unsigned long)1)); + irq_ts_restore(ts_state); + done += SHA1_BLOCK_SIZE; + src = data + done; + } + + /* Process the left bytes from the input data */ + if (len - done >= SHA1_BLOCK_SIZE) { + ts_state = irq_ts_save(); + asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" + : "+S"(src), "+D"(dst) + : "a"((long)-1), + "c"((unsigned long)((len - done) / SHA1_BLOCK_SIZE))); + irq_ts_restore(ts_state); + done += ((len - done) - (len - done) % SHA1_BLOCK_SIZE); + src = data + done; + } + partial = 0; + } + memcpy((u8 *)(sctx->state), dst, SHA1_DIGEST_SIZE); + memcpy(sctx->buffer + partial, src, len - done); + + return 0; +} + +static int padlock_sha1_final_nano(struct shash_desc *desc, u8 *out) +{ + struct sha1_state *state = (struct sha1_state *)shash_desc_ctx(desc); + unsigned int partial, padlen; + __be64 bits; + static const u8 padding[64] = { 0x80, }; + + bits = cpu_to_be64(state->count << 3); + + /* Pad out to 56 mod 64 */ + partial = state->count & 0x3f; + padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial); + padlock_sha1_update_nano(desc, padding, padlen); + + /* Append length field bytes */ + padlock_sha1_update_nano(desc, (const u8 *)&bits, sizeof(bits)); + + /* Swap to output */ + padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 5); + + return 0; +} + +static int padlock_sha256_init_nano(struct shash_desc *desc) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + + *sctx = (struct sha256_state){ + .state = { SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3, \ + SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7}, + }; + + return 0; +} + +static int padlock_sha256_update_nano(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + struct sha256_state *sctx = shash_desc_ctx(desc); + unsigned int partial, done; + const u8 *src; + /*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/ + u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__ + ((aligned(STACK_ALIGN))); + u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT); + int ts_state; + + partial = sctx->count & 0x3f; + sctx->count += len; + done = 0; + src = data; + memcpy(dst, (u8 *)(sctx->state), SHA256_DIGEST_SIZE); + + if ((partial + len) >= SHA256_BLOCK_SIZE) { + + /* Append the bytes in state's buffer to a block to handle */ + if (partial) { + done = -partial; + memcpy(sctx->buf + partial, data, + done + SHA256_BLOCK_SIZE); + src = sctx->buf; + ts_state = irq_ts_save(); + asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" + : "+S"(src), "+D"(dst) + : "a"((long)-1), "c"((unsigned long)1)); + irq_ts_restore(ts_state); + done += SHA256_BLOCK_SIZE; + src = data + done; + } + + /* Process the left bytes from input data*/ + if (len - done >= SHA256_BLOCK_SIZE) { + ts_state = irq_ts_save(); + asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" + : "+S"(src), "+D"(dst) + : "a"((long)-1), + "c"((unsigned long)((len - done) / 64))); + irq_ts_restore(ts_state); + done += ((len - done) - (len - done) % 64); + src = data + done; + } + partial = 0; + } + memcpy((u8 *)(sctx->state), dst, SHA256_DIGEST_SIZE); + memcpy(sctx->buf + partial, src, len - done); + + return 0; +} + +static int padlock_sha256_final_nano(struct shash_desc *desc, u8 *out) +{ + struct sha256_state *state = + (struct sha256_state *)shash_desc_ctx(desc); + unsigned int partial, padlen; + __be64 bits; + static const u8 padding[64] = { 0x80, }; + + bits = cpu_to_be64(state->count << 3); + + /* Pad out to 56 mod 64 */ + partial = state->count & 0x3f; + padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial); + padlock_sha256_update_nano(desc, padding, padlen); + + /* Append length field bytes */ + padlock_sha256_update_nano(desc, (const u8 *)&bits, sizeof(bits)); + + /* Swap to output */ + padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 8); + + return 0; +} + +static int padlock_sha_export_nano(struct shash_desc *desc, + void *out) +{ + int statesize = crypto_shash_statesize(desc->tfm); + void *sctx = shash_desc_ctx(desc); + + memcpy(out, sctx, statesize); + return 0; +} + +static int padlock_sha_import_nano(struct shash_desc *desc, + const void *in) +{ + int statesize = crypto_shash_statesize(desc->tfm); + void *sctx = shash_desc_ctx(desc); + + memcpy(sctx, in, statesize); + return 0; +} + +static struct shash_alg sha1_alg_nano = { + .digestsize = SHA1_DIGEST_SIZE, + .init = padlock_sha1_init_nano, + .update = padlock_sha1_update_nano, + .final = padlock_sha1_final_nano, + .export = padlock_sha_export_nano, + .import = padlock_sha_import_nano, + .descsize = sizeof(struct sha1_state), + .statesize = sizeof(struct sha1_state), + .base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-padlock-nano", + .cra_priority = PADLOCK_CRA_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +}; + +static struct shash_alg sha256_alg_nano = { + .digestsize = SHA256_DIGEST_SIZE, + .init = padlock_sha256_init_nano, + .update = padlock_sha256_update_nano, + .final = padlock_sha256_final_nano, + .export = padlock_sha_export_nano, + .import = padlock_sha_import_nano, + .descsize = sizeof(struct sha256_state), + .statesize = sizeof(struct sha256_state), + .base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-padlock-nano", + .cra_priority = PADLOCK_CRA_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_SHASH, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_module = THIS_MODULE, + } +}; + static int __init padlock_init(void) { int rc = -ENODEV; + struct cpuinfo_x86 *c = &cpu_data(0); + struct shash_alg *sha1; + struct shash_alg *sha256; if (!cpu_has_phe) { printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); @@ -302,11 +543,21 @@ static int __init padlock_init(void) return -ENODEV; } - rc = crypto_register_shash(&sha1_alg); + /* Register the newly added algorithm module if on * + * VIA Nano processor, or else just do as before */ + if (c->x86_model < 0x0f) { + sha1 = &sha1_alg; + sha256 = &sha256_alg; + } else { + sha1 = &sha1_alg_nano; + sha256 = &sha256_alg_nano; + } + + rc = crypto_register_shash(sha1); if (rc) goto out; - rc = crypto_register_shash(&sha256_alg); + rc = crypto_register_shash(sha256); if (rc) goto out_unreg1; @@ -315,7 +566,8 @@ static int __init padlock_init(void) return 0; out_unreg1: - crypto_unregister_shash(&sha1_alg); + crypto_unregister_shash(sha1); + out: printk(KERN_ERR PFX "VIA PadLock SHA1/SHA256 initialization failed.\n"); return rc; @@ -323,8 +575,15 @@ static int __init padlock_init(void) static void __exit padlock_fini(void) { - crypto_unregister_shash(&sha1_alg); - crypto_unregister_shash(&sha256_alg); + struct cpuinfo_x86 *c = &cpu_data(0); + + if (c->x86_model >= 0x0f) { + crypto_unregister_shash(&sha1_alg_nano); + crypto_unregister_shash(&sha256_alg_nano); + } else { + crypto_unregister_shash(&sha1_alg); + crypto_unregister_shash(&sha256_alg); + } } module_init(padlock_init); -- GitLab From 40bfc14f3250691dca6fcb00f791727e180a7f79 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Sun, 27 Mar 2011 10:48:29 +0800 Subject: [PATCH 0102/5560] crypto: picoxcell - fix possible status FIFO overflow The SPAcc's have 2 equally sized FIFO's - a command FIFO and a status FIFO. The command FIFO takes the requests that are to be performed and the status FIFO reports the results. It is possible to get into the situation where there are more free spaces in the command FIFO than the status FIFO if we don't empty the status FIFO quickly enough resulting in a possible overflow of the status FIFO. This can result in incorrect status being reported in the status FIFO. Make sure that when we are submitting requests the number of requests that have been dispatched but not yet popped from the status FIFO does not exceed the size of a single FIFO. Signed-off-by: Jamie Iles Signed-off-by: Herbert Xu --- drivers/crypto/picoxcell_crypto.c | 64 +++++++++++++++++-------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c index b092d0a65837..230b5b8cda1f 100644 --- a/drivers/crypto/picoxcell_crypto.c +++ b/drivers/crypto/picoxcell_crypto.c @@ -176,6 +176,8 @@ struct spacc_aead_ctx { u8 salt[AES_BLOCK_SIZE]; }; +static int spacc_ablk_submit(struct spacc_req *req); + static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg) { return alg ? container_of(alg, struct spacc_alg, alg) : NULL; @@ -666,6 +668,24 @@ static int spacc_aead_submit(struct spacc_req *req) return -EINPROGRESS; } +static int spacc_req_submit(struct spacc_req *req); + +static void spacc_push(struct spacc_engine *engine) +{ + struct spacc_req *req; + + while (!list_empty(&engine->pending) && + engine->in_flight + 1 <= engine->fifo_sz) { + + ++engine->in_flight; + req = list_first_entry(&engine->pending, struct spacc_req, + list); + list_move_tail(&req->list, &engine->in_progress); + + req->result = spacc_req_submit(req); + } +} + /* * Setup an AEAD request for processing. This will configure the engine, load * the context and then start the packet processing. @@ -698,7 +718,8 @@ static int spacc_aead_setup(struct aead_request *req, u8 *giv, err = -EINPROGRESS; spin_lock_irqsave(&engine->hw_lock, flags); - if (unlikely(spacc_fifo_cmd_full(engine))) { + if (unlikely(spacc_fifo_cmd_full(engine)) || + engine->in_flight + 1 > engine->fifo_sz) { if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { err = -EBUSY; spin_unlock_irqrestore(&engine->hw_lock, flags); @@ -706,9 +727,8 @@ static int spacc_aead_setup(struct aead_request *req, u8 *giv, } list_add_tail(&dev_req->list, &engine->pending); } else { - ++engine->in_flight; - list_add_tail(&dev_req->list, &engine->in_progress); - spacc_aead_submit(dev_req); + list_add_tail(&dev_req->list, &engine->pending); + spacc_push(engine); } spin_unlock_irqrestore(&engine->hw_lock, flags); @@ -1041,7 +1061,8 @@ static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type, * we either stick it on the end of a pending list if we can backlog, * or bailout with an error if not. */ - if (unlikely(spacc_fifo_cmd_full(engine))) { + if (unlikely(spacc_fifo_cmd_full(engine)) || + engine->in_flight + 1 > engine->fifo_sz) { if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { err = -EBUSY; spin_unlock_irqrestore(&engine->hw_lock, flags); @@ -1049,9 +1070,8 @@ static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type, } list_add_tail(&dev_req->list, &engine->pending); } else { - ++engine->in_flight; - list_add_tail(&dev_req->list, &engine->in_progress); - spacc_ablk_submit(dev_req); + list_add_tail(&dev_req->list, &engine->pending); + spacc_push(engine); } spin_unlock_irqrestore(&engine->hw_lock, flags); @@ -1139,6 +1159,7 @@ static void spacc_process_done(struct spacc_engine *engine) req = list_first_entry(&engine->in_progress, struct spacc_req, list); list_move_tail(&req->list, &engine->completed); + --engine->in_flight; /* POP the status register. */ writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET); @@ -1208,36 +1229,21 @@ static void spacc_spacc_complete(unsigned long data) struct spacc_engine *engine = (struct spacc_engine *)data; struct spacc_req *req, *tmp; unsigned long flags; - int num_removed = 0; LIST_HEAD(completed); spin_lock_irqsave(&engine->hw_lock, flags); + list_splice_init(&engine->completed, &completed); + spacc_push(engine); + if (engine->in_flight) + mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); + spin_unlock_irqrestore(&engine->hw_lock, flags); list_for_each_entry_safe(req, tmp, &completed, list) { - ++num_removed; req->complete(req); + list_del(&req->list); } - - /* Try and fill the engine back up again. */ - spin_lock_irqsave(&engine->hw_lock, flags); - - engine->in_flight -= num_removed; - - list_for_each_entry_safe(req, tmp, &engine->pending, list) { - if (spacc_fifo_cmd_full(engine)) - break; - - list_move_tail(&req->list, &engine->in_progress); - ++engine->in_flight; - req->result = spacc_req_submit(req); - } - - if (engine->in_flight) - mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); - - spin_unlock_irqrestore(&engine->hw_lock, flags); } #ifdef CONFIG_PM -- GitLab From 7f980a06e4a9e3bb26db91da8f0e980b0786023a Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 27 Mar 2011 02:54:32 +0000 Subject: [PATCH 0103/5560] viafb: some small cleanup for global variables We do not need viafb_second{,_virtual}_{xres,yres} outside of viafbdev.c so move them there and eliminate the virtual ones where the only sane usage is done during initalization. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/global.c | 4 ---- drivers/video/via/global.h | 2 -- drivers/video/via/hw.h | 1 - drivers/video/via/viafbdev.c | 16 +++++++--------- drivers/video/via/viafbdev.h | 2 -- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c index 1ee511b73307..e10d8249534c 100644 --- a/drivers/video/via/global.c +++ b/drivers/video/via/global.c @@ -40,10 +40,6 @@ int viafb_hotplug_Yres = 480; int viafb_hotplug_bpp = 32; int viafb_hotplug_refresh = 60; int viafb_primary_dev = None_Device; -unsigned int viafb_second_xres = 640; -unsigned int viafb_second_yres = 480; -unsigned int viafb_second_virtual_xres; -unsigned int viafb_second_virtual_yres; int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; struct fb_info *viafbinfo; struct fb_info *viafbinfo1; diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 38ef5ac66953..ff969dc34593 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -73,8 +73,6 @@ extern int viafb_hotplug_bpp; extern int viafb_hotplug_refresh; extern int viafb_primary_dev; -extern unsigned int viafb_second_xres; -extern unsigned int viafb_second_yres; extern int viafb_lcd_panel_id; #endif /* __GLOBAL_H__ */ diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 8858593405aa..090d167863a4 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -910,7 +910,6 @@ struct via_device_mapping { const char *name; }; -extern unsigned int viafb_second_virtual_xres; extern int viafb_SAMM_ON; extern int viafb_dual_fb; extern int viafb_LCD2_ON; diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index ed9bd7978cc0..eace9a4257f4 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -37,6 +37,8 @@ static char *viafb_mode1; static int viafb_bpp = 32; static int viafb_bpp1 = 32; +static unsigned int viafb_second_xres = 640; +static unsigned int viafb_second_yres = 480; static unsigned int viafb_second_offset; static int viafb_second_size; @@ -440,8 +442,8 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (viafb_SAMM_ON == 1) { u.viamode.xres_sec = viafb_second_xres; u.viamode.yres_sec = viafb_second_yres; - u.viamode.virtual_xres_sec = viafb_second_virtual_xres; - u.viamode.virtual_yres_sec = viafb_second_virtual_yres; + u.viamode.virtual_xres_sec = viafb_dual_fb ? viafbinfo1->var.xres_virtual : viafbinfo->var.xres_virtual; + u.viamode.virtual_yres_sec = viafb_dual_fb ? viafbinfo1->var.yres_virtual : viafbinfo->var.yres_virtual; u.viamode.refresh_sec = viafb_refresh1; u.viamode.bpp_sec = viafb_bpp1; } else { @@ -1790,14 +1792,10 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) parse_mode(viafb_mode, &default_xres, &default_yres); vmode_entry = viafb_get_mode(default_xres, default_yres); - if (viafb_SAMM_ON == 1) { + if (viafb_SAMM_ON == 1) parse_mode(viafb_mode1, &viafb_second_xres, &viafb_second_yres); - viafb_second_virtual_xres = viafb_second_xres; - viafb_second_virtual_yres = viafb_second_yres; - } - default_var.xres = default_xres; default_var.yres = default_yres; default_var.xres_virtual = default_xres; @@ -1841,8 +1839,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) default_var.xres = viafb_second_xres; default_var.yres = viafb_second_yres; - default_var.xres_virtual = viafb_second_virtual_xres; - default_var.yres_virtual = viafb_second_virtual_yres; + default_var.xres_virtual = viafb_second_xres; + default_var.yres_virtual = viafb_second_yres; default_var.bits_per_pixel = viafb_bpp1; viafb_fill_var_timing_info(&default_var, viafb_get_refresh( default_var.xres, default_var.yres, viafb_refresh1), diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index ff60e1ddcffc..59e40d1bd614 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -83,8 +83,6 @@ struct viafb_par { struct chip_information *chip_info; }; -extern unsigned int viafb_second_virtual_yres; -extern unsigned int viafb_second_virtual_xres; extern int viafb_SAMM_ON; extern int viafb_dual_fb; extern int viafb_LCD2_ON; -- GitLab From cd00b1154d3c7d711e83c3c17b831aafe6377532 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 27 Mar 2011 03:36:00 +0000 Subject: [PATCH 0104/5560] viafb: replace custom return values This patch replaces OK/FAIL by true/false which is simpler and saner. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/dvi.c | 22 +++++++++------------- drivers/video/via/dvi.h | 2 +- drivers/video/via/lcd.c | 16 ++++++---------- drivers/video/via/lcd.h | 2 +- drivers/video/via/share.h | 8 -------- 5 files changed, 17 insertions(+), 33 deletions(-) diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 3dbcd7743f14..b1f364745ca0 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -30,12 +30,9 @@ static void __devinit dvi_get_panel_size_from_DDCv1( struct tmds_setting_information *tmds_setting); static int viafb_dvi_query_EDID(void); -static int check_tmds_chip(int device_id_subaddr, int device_id) +static inline bool check_tmds_chip(int device_id_subaddr, int device_id) { - if (tmds_register_read(device_id_subaddr) == device_id) - return OK; - else - return FAIL; + return tmds_register_read(device_id_subaddr) == device_id; } void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, @@ -50,7 +47,7 @@ void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, return; } -int __devinit viafb_tmds_trasmitter_identify(void) +bool __devinit viafb_tmds_trasmitter_identify(void) { unsigned char sr2a = 0, sr1e = 0, sr3e = 0; @@ -89,7 +86,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info-> tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; - if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { + if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { /* * Currently only support 12bits,dual edge,add 24bits mode later */ @@ -100,11 +97,10 @@ int __devinit viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->tmds_chip_info.i2c_port); - return OK; + return true; } else { viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C; - if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) - != FAIL) { + if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { tmds_register_write(0x08, 0x3b); DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); DEBUG_MSG(KERN_INFO "\n %2d", @@ -113,7 +109,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info-> tmds_chip_info.i2c_port); - return OK; + return true; } } @@ -123,7 +119,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) || (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) { DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); - return OK; + return true; } switch (viaparinfo->chip_info->gfx_chip_name) { @@ -147,7 +143,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; viaparinfo->chip_info->tmds_chip_info. tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; - return FAIL; + return false; } static void tmds_register_write(int index, u8 data) diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index 2c525c0c1adb..f473dd010977 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h @@ -56,7 +56,7 @@ int viafb_dvi_sense(void); void viafb_dvi_disable(void); void viafb_dvi_enable(void); -int __devinit viafb_tmds_trasmitter_identify(void); +bool __devinit viafb_tmds_trasmitter_identify(void); void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting); void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 64bc7e763103..6984046c6eed 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -48,7 +48,6 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } } }; -static int check_lvds_chip(int device_id_subaddr, int device_id); static bool lvds_identify_integratedlvds(void); static void __devinit fp_id_to_vindex(int panel_id); static int lvds_register_read(int index); @@ -84,12 +83,9 @@ static struct display_timing lcd_centering_timging(struct display_timing mode_crt_reg, struct display_timing panel_crt_reg); -static int check_lvds_chip(int device_id_subaddr, int device_id) +static inline bool check_lvds_chip(int device_id_subaddr, int device_id) { - if (lvds_register_read(device_id_subaddr) == device_id) - return OK; - else - return FAIL; + return lvds_register_read(device_id_subaddr) == device_id; } void __devinit viafb_init_lcd_size(void) @@ -150,7 +146,7 @@ static bool lvds_identify_integratedlvds(void) return true; } -int __devinit viafb_lvds_trasmitter_identify(void) +bool __devinit viafb_lvds_trasmitter_identify(void) { if (viafb_lvds_identify_vt1636(VIA_PORT_31)) { viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; @@ -175,20 +171,20 @@ int __devinit viafb_lvds_trasmitter_identify(void) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; - if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { + if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) { DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); - return OK; + return true; } viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = NON_LVDS_TRANSMITTER; viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; - return FAIL; + return false; } static void __devinit fp_id_to_vindex(int panel_id) diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h index c7909fe29550..75f60a655b0e 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/via/lcd.h @@ -79,7 +79,7 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); -int __devinit viafb_lvds_trasmitter_identify(void); +bool __devinit viafb_lvds_trasmitter_identify(void); void viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 4b7831f0d012..beb59bcdf49f 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h @@ -22,14 +22,6 @@ #ifndef __SHARE_H__ #define __SHARE_H__ -/* Define Return Value */ -#define FAIL -1 -#define OK 1 - -#ifndef NULL -#define NULL 0 -#endif - /* Define Bit Field */ #define BIT0 0x01 #define BIT1 0x02 -- GitLab From ac065bf214bb6a7fb7536f2dde686d4694342801 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Mar 2011 04:47:35 +0300 Subject: [PATCH 0105/5560] HID: hiddev: fix brace indent There was an extra tab so the close curly brace didn't match up with the right if statement. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hiddev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index af0a7c1002af..527003188bfe 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -509,7 +509,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, (uref_multi->num_values > HID_MAX_MULTI_USAGES || uref->usage_index + uref_multi->num_values > field->report_count)) goto inval; - } + } switch (cmd) { case HIDIOCGUSAGE: -- GitLab From d2a1cfebe38edc0bbac8f5cfbce062fe3d146d7a Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Sun, 27 Mar 2011 20:29:02 +0200 Subject: [PATCH 0106/5560] HID: hidraw: fix comments Adjust the comments a little bit. Signed-off-by: Jiri Kosina --- drivers/hid/hidraw.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 54409cba018c..93c72e593701 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -101,8 +101,8 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, return ret; } -/* the first byte is expected to be a report number */ -/* This function is to be called with the minors_lock mutex held */ +/* The first byte is expected to be a report number. + * This function is to be called with the minors_lock mutex held */ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type) { unsigned int minor = iminor(file->f_path.dentry->d_inode); @@ -166,11 +166,11 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t /* This function performs a Get_Report transfer over the control endpoint - per section 7.2.1 of the HID specification, version 1.1. The first byte - of buffer is the report number to request, or 0x0 if the defice does not - use numbered reports. The report_type parameter can be HID_FEATURE_REPORT - or HID_INPUT_REPORT. This function is to be called with the minors_lock - mutex held. */ + * per section 7.2.1 of the HID specification, version 1.1. The first byte + * of buffer is the report number to request, or 0x0 if the defice does not + * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT + * or HID_INPUT_REPORT. This function is to be called with the minors_lock + * mutex held. */ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type) { unsigned int minor = iminor(file->f_path.dentry->d_inode); @@ -207,7 +207,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t } /* Read the first byte from the user. This is the report number, - which is passed to dev->hid_get_raw_report(). */ + * which is passed to dev->hid_get_raw_report(). */ if (copy_from_user(&report_number, buffer, 1)) { ret = -EFAULT; goto out_free; -- GitLab From 4bcad6c1ef53a9a0224f4654ceb3b9030d0769ec Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 24 Mar 2011 13:56:47 +0000 Subject: [PATCH 0107/5560] dlm: Remove superfluous call to recalc_sigpending() recalc_sigpending() is called within sigprocmask(), so there is no need call it again after sigprocmask() has returned. Signed-off-by: Matt Fleming Signed-off-by: David Teigland --- fs/dlm/user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/dlm/user.c b/fs/dlm/user.c index d5ab3fe7c198..e96bf3e9be88 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -611,7 +611,6 @@ static ssize_t device_write(struct file *file, const char __user *buf, out_sig: sigprocmask(SIG_SETMASK, &tmpsig, NULL); - recalc_sigpending(); out_free: kfree(kbuf); return error; -- GitLab From 787e5b06a80e7fc9dc02d9b53a9d8d2ac63b7ace Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 23 Mar 2011 08:23:52 +0100 Subject: [PATCH 0108/5560] percpu: Cast away printk format warning On 32-bit systems which don't happen to implicitly define or cast VMALLOC_START and/or VMALLOC_END to long in their arch headers, the printk in the percpu code will cause a warning to be emitted: mm/percpu.c: In function 'pcpu_embed_first_chunk': mm/percpu.c:1648: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'unsigned int' So add an explicit cast to unsigned long here. Signed-off-by: Mike Frysinger Signed-off-by: Tejun Heo --- mm/percpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 3f930018aa60..8a11cd2e976d 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1646,8 +1646,8 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, /* warn if maximum distance is further than 75% of vmalloc space */ if (max_distance > (VMALLOC_END - VMALLOC_START) * 3 / 4) { pr_warning("PERCPU: max_distance=0x%zx too large for vmalloc " - "space 0x%lx\n", - max_distance, VMALLOC_END - VMALLOC_START); + "space 0x%lx\n", max_distance, + (unsigned long)(VMALLOC_END - VMALLOC_START)); #ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK /* and fail if we have fallback */ rc = -EINVAL; -- GitLab From 5f55924deaa62d6df687c131fb92aebe071ec787 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 28 Mar 2011 18:06:58 +0200 Subject: [PATCH 0109/5560] percpu: Avoid extra NOP in percpu_cmpxchg16b_double percpu_cmpxchg16b_double() uses alternative_io() and looks like : e8 .. .. .. .. call this_cpu_cmpxchg16b_emu X bytes NOPX or, once patched (if cpu supports native instruction) on SMP build : 65 48 0f c7 0e cmpxchg16b %gs:(%rsi) 0f 94 c0 sete %al on !SMP build : 48 0f c7 0e cmpxchg16b (%rsi) 0f 94 c0 sete %al Therefore, NOPX should be : P6_NOP3 on SMP P6_NOP2 on !SMP Signed-off-by: Eric Dumazet Acked-by: Christoph Lameter Cc: Ingo Molnar Cc: Pekka Enberg Signed-off-by: Tejun Heo --- arch/x86/include/asm/percpu.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index d475b4398d8b..d68fca61ad91 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -509,6 +509,11 @@ do { \ * it in software. The address used in the cmpxchg16 instruction must be * aligned to a 16 byte boundary. */ +#ifdef CONFIG_SMP +#define CMPXCHG16B_EMU_CALL "call this_cpu_cmpxchg16b_emu\n\t" P6_NOP3 +#else +#define CMPXCHG16B_EMU_CALL "call this_cpu_cmpxchg16b_emu\n\t" P6_NOP2 +#endif #define percpu_cmpxchg16b_double(pcp1, o1, o2, n1, n2) \ ({ \ char __ret; \ @@ -517,7 +522,7 @@ do { \ typeof(o2) __o2 = o2; \ typeof(o2) __n2 = n2; \ typeof(o2) __dummy; \ - alternative_io("call this_cpu_cmpxchg16b_emu\n\t" P6_NOP4, \ + alternative_io(CMPXCHG16B_EMU_CALL, \ "cmpxchg16b " __percpu_prefix "(%%rsi)\n\tsetz %0\n\t", \ X86_FEATURE_CX16, \ ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)), \ -- GitLab From 8023976cf4627d9f1d82ad468ec40e32eb87d211 Mon Sep 17 00:00:00 2001 From: Harry Ciao Date: Fri, 25 Mar 2011 13:51:56 +0800 Subject: [PATCH 0110/5560] SELinux: Add class support to the role_trans structure If kernel policy version is >= 26, then the binary representation of the role_trans structure supports specifying the class for the current subject or the newly created object. If kernel policy version is < 26, then the class field would be default to the process class. Signed-off-by: Harry Ciao Acked-by: Stephen Smalley Signed-off-by: Eric Paris --- security/selinux/include/security.h | 3 ++- security/selinux/ss/policydb.c | 14 ++++++++++++++ security/selinux/ss/policydb.h | 3 ++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 348eb00cb668..bfc5218d5840 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -30,13 +30,14 @@ #define POLICYDB_VERSION_PERMISSIVE 23 #define POLICYDB_VERSION_BOUNDARY 24 #define POLICYDB_VERSION_FILENAME_TRANS 25 +#define POLICYDB_VERSION_ROLETRANS 26 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS #endif /* Mask for just the mount related flags */ diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index e7b850ad57ee..fd62c50d6e7d 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -128,6 +128,11 @@ static struct policydb_compat_info policydb_compat[] = { .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, + { + .version = POLICYDB_VERSION_ROLETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, + }, }; static struct policydb_compat_info *policydb_lookup_compat(int version) @@ -2302,8 +2307,17 @@ int policydb_read(struct policydb *p, void *fp) tr->role = le32_to_cpu(buf[0]); tr->type = le32_to_cpu(buf[1]); tr->new_role = le32_to_cpu(buf[2]); + if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) { + rc = next_entry(buf, fp, sizeof(u32)); + if (rc) + goto bad; + tr->tclass = le32_to_cpu(buf[0]); + } else + tr->tclass = p->process_class; + if (!policydb_role_isvalid(p, tr->role) || !policydb_type_isvalid(p, tr->type) || + !policydb_class_isvalid(p, tr->tclass) || !policydb_role_isvalid(p, tr->new_role)) goto bad; ltr = tr; diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 732ea4a68682..801175f79cf9 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -72,7 +72,8 @@ struct role_datum { struct role_trans { u32 role; /* current role */ - u32 type; /* program executable type */ + u32 type; /* program executable type, or new object type */ + u32 tclass; /* process class, or new object class */ u32 new_role; /* new role */ struct role_trans *next; }; -- GitLab From 63a312ca55d09a3f6526919df495fff1073c88f4 Mon Sep 17 00:00:00 2001 From: Harry Ciao Date: Fri, 25 Mar 2011 13:51:58 +0800 Subject: [PATCH 0111/5560] SELinux: Compute role in newcontext for all classes Apply role_transition rules for all kinds of classes. Signed-off-by: Harry Ciao Acked-by: Stephen Smalley Signed-off-by: Eric Paris --- security/selinux/ss/services.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 3e7544d2a07b..03f7a4748ee8 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1484,17 +1484,15 @@ static int security_compute_sid(u32 ssid, tcontext->type, tclass, qstr); /* Check for class-specific changes. */ - if (tclass == policydb.process_class) { - if (specified & AVTAB_TRANSITION) { - /* Look for a role transition rule. */ - for (roletr = policydb.role_tr; roletr; - roletr = roletr->next) { - if (roletr->role == scontext->role && - roletr->type == tcontext->type) { - /* Use the role transition rule. */ - newcontext.role = roletr->new_role; - break; - } + if (specified & AVTAB_TRANSITION) { + /* Look for a role transition rule. */ + for (roletr = policydb.role_tr; roletr; roletr = roletr->next) { + if ((roletr->role == scontext->role) && + (roletr->type == tcontext->type) && + (roletr->tclass == tclass)) { + /* Use the role transition rule. */ + newcontext.role = roletr->new_role; + break; } } } -- GitLab From c900ff323d761753a56d8d6a67b034ceee277b6e Mon Sep 17 00:00:00 2001 From: Harry Ciao Date: Fri, 25 Mar 2011 13:52:00 +0800 Subject: [PATCH 0112/5560] SELinux: Write class field in role_trans_write. If kernel policy version is >= 26, then write the class field of the role_trans structure into the binary reprensentation. Signed-off-by: Harry Ciao Acked-by: Stephen Smalley Signed-off-by: Eric Paris --- security/selinux/ss/policydb.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index fd62c50d6e7d..a493eae24e0a 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -2535,8 +2535,9 @@ static int cat_write(void *vkey, void *datum, void *ptr) return 0; } -static int role_trans_write(struct role_trans *r, void *fp) +static int role_trans_write(struct policydb *p, void *fp) { + struct role_trans *r = p->role_tr; struct role_trans *tr; u32 buf[3]; size_t nel; @@ -2556,6 +2557,12 @@ static int role_trans_write(struct role_trans *r, void *fp) rc = put_entry(buf, sizeof(u32), 3, fp); if (rc) return rc; + if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) { + buf[0] = cpu_to_le32(tr->tclass); + rc = put_entry(buf, sizeof(u32), 1, fp); + if (rc) + return rc; + } } return 0; @@ -3267,7 +3274,7 @@ int policydb_write(struct policydb *p, void *fp) if (rc) return rc; - rc = role_trans_write(p->role_tr, fp); + rc = role_trans_write(p, fp); if (rc) return rc; -- GitLab From efb3bb4fad062f8e9b8c9c945d499597e14007e7 Mon Sep 17 00:00:00 2001 From: James Morris Date: Wed, 30 Mar 2011 08:50:41 +1100 Subject: [PATCH 0113/5560] Merge branch 'master'; commit 'v2.6.39-rc1' into next -- GitLab From ecd015127813c7893f6900cf54c6362b26d8ff90 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 27 Mar 2011 13:43:45 +0100 Subject: [PATCH 0114/5560] ASoC: Convert WM8903 to table based DAPM setup Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index ae1cadfae84c..a739e09a8309 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -926,7 +926,7 @@ SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route wm8903_intercon[] = { { "CLK_DSP", NULL, "CLK_SYS" }, { "Mic Bias", NULL, "CLK_SYS" }, @@ -1079,17 +1079,6 @@ static const struct snd_soc_dapm_route intercon[] = { { "Right Line Output PGA", NULL, "Charge Pump" }, }; -static int wm8903_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets, - ARRAY_SIZE(wm8903_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - static int wm8903_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -2020,7 +2009,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8903_snd_controls, ARRAY_SIZE(wm8903_snd_controls)); - wm8903_add_widgets(codec); wm8903_init_gpio(codec); @@ -2046,6 +2034,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { .reg_cache_default = wm8903_reg_defaults, .volatile_register = wm8903_volatile_register, .seq_notifier = wm8903_seq_notifier, + .dapm_widgets = wm8903_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), + .dapm_routes = wm8903_intercon, + .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -- GitLab From 5e251aecbd4a4bf3ff0b0ff04653afa4d01eba54 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 27 Mar 2011 14:33:03 +0100 Subject: [PATCH 0115/5560] ASoC: Convert WM8731 to table based DAPM setup Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8731.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 0a67c31b2663..44a591e82558 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -201,7 +201,7 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source, return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; } -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route wm8731_intercon[] = { {"DAC", NULL, "OSC", wm8731_check_osc}, {"ADC", NULL, "OSC", wm8731_check_osc}, @@ -227,17 +227,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"Mic Bias", NULL, "MICIN"}, }; -static int wm8731_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, - ARRAY_SIZE(wm8731_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - struct _coeff_div { u32 mclk; u32 rate; @@ -599,7 +588,6 @@ static int wm8731_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8731_snd_controls, ARRAY_SIZE(wm8731_snd_controls)); - wm8731_add_widgets(codec); /* Regulators will have been enabled by bias management */ regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); @@ -636,6 +624,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { .reg_cache_size = ARRAY_SIZE(wm8731_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8731_reg, + .dapm_widgets = wm8731_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), + .dapm_routes = wm8731_intercon, + .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), }; #if defined(CONFIG_SPI_MASTER) -- GitLab From 99b59f3ccb72c15f13169236eda16682930e47f0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 27 Mar 2011 14:35:15 +0100 Subject: [PATCH 0116/5560] ASoC: Remove -codec from WM8731 driver name Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/atmel/sam9g20_wm8731.c | 2 +- sound/soc/au1x/db1200.c | 2 +- sound/soc/codecs/wm8731.c | 4 ++-- sound/soc/pxa/corgi.c | 2 +- sound/soc/pxa/poodle.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index af3c73053ee4..28afbbf69ce0 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -184,7 +184,7 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = { .codec_dai_name = "wm8731-hifi", .init = at91sam9g20ek_wm8731_init, .platform_name = "atmel-pcm-audio", - .codec_name = "wm8731-codec.0-001b", + .codec_name = "wm8731.0-001b", .ops = &at91sam9g20ek_ops, }; diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index cb99f04abe88..1d3e258c9ea8 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -77,7 +77,7 @@ static struct snd_soc_dai_link db1200_i2s_dai = { .codec_dai_name = "wm8731-hifi", .cpu_dai_name = "au1xpsc_i2s.1", .platform_name = "au1xpsc-pcm.1", - .codec_name = "wm8731-codec.0-001b", + .codec_name = "wm8731.0-001b", .ops = &db1200_i2s_wm8731_ops, }; diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 44a591e82558..6dec7cee2cb4 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -659,7 +659,7 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi) static struct spi_driver wm8731_spi_driver = { .driver = { - .name = "wm8731-codec", + .name = "wm8731", .owner = THIS_MODULE, }, .probe = wm8731_spi_probe, @@ -703,7 +703,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); static struct i2c_driver wm8731_i2c_driver = { .driver = { - .name = "wm8731-codec", + .name = "wm8731", .owner = THIS_MODULE, }, .probe = wm8731_i2c_probe, diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 9027da466cae..28757fb9df31 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -310,7 +310,7 @@ static struct snd_soc_dai_link corgi_dai = { .cpu_dai_name = "pxa2xx-i2s", .codec_dai_name = "wm8731-hifi", .platform_name = "pxa-pcm-audio", - .codec_name = "wm8731-codec.0-001b", + .codec_name = "wm8731.0-001b", .init = corgi_wm8731_init, .ops = &corgi_ops, }; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index a7d4999f9b24..da3ae4316cf2 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -276,7 +276,7 @@ static struct snd_soc_dai_link poodle_dai = { .cpu_dai_name = "pxa2xx-i2s", .codec_dai_name = "wm8731-hifi", .platform_name = "pxa-pcm-audio", - .codec_name = "wm8731-codec.0-001b", + .codec_name = "wm8731.0-001b", .init = poodle_wm8731_init, .ops = &poodle_ops, }; -- GitLab From 754dec6b7f01efadd400f3291591627093a17988 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 27 Mar 2011 00:43:59 -0400 Subject: [PATCH 0117/5560] ASoC: fix sorting order of codecs in kconfig Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a9defd534456..3e84b528a88c 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -16,8 +16,8 @@ config SND_SOC_ALL_CODECS select SND_SOC_AD1836 if SPI_MASTER select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI select SND_SOC_AD1980 if SND_SOC_AC97_BUS - select SND_SOC_ADS117X select SND_SOC_AD73311 + select SND_SOC_ADS117X select SND_SOC_AK4104 if SPI_MASTER select SND_SOC_AK4535 if I2C select SND_SOC_AK4642 if I2C -- GitLab From 2a161018914d7f12ed73991d1aedb609fdba3fcf Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 27 Mar 2011 00:44:10 -0400 Subject: [PATCH 0118/5560] ASoC: SSM2602: fix codec name The codec name should not have a "-codec" suffix since this is not part of a MFD. This was incorrectly changed during the multi-component updated. Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ssm2602.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 2727befd158e..5a5a6b169114 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -651,7 +651,7 @@ MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); /* corgi i2c codec control layer */ static struct i2c_driver ssm2602_i2c_driver = { .driver = { - .name = "ssm2602-codec", + .name = "ssm2602", .owner = THIS_MODULE, }, .probe = ssm2602_i2c_probe, -- GitLab From 370fd17dea6056cdb2fbbca47812cf96d2a02726 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 27 Mar 2011 00:44:11 -0400 Subject: [PATCH 0119/5560] ASoC: ad73311: fix codec name The codec name should not have a "-codec" suffix since this is not part of a MFD. This was incorrectly changed during the multi-component updated. Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ad73311.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index de799cd1ba72..8d793e993e9a 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -55,7 +55,7 @@ static int __devexit ad73311_remove(struct platform_device *pdev) static struct platform_driver ad73311_codec_driver = { .driver = { - .name = "ad73311-codec", + .name = "ad73311", .owner = THIS_MODULE, }, -- GitLab From e43a7d4116c868676eca329c4211bc5cc5a93a9b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 27 Mar 2011 00:44:12 -0400 Subject: [PATCH 0120/5560] ASoC: ad193x: fix codec name The codec name should not have a "-codec" suffix since this is not part of a MFD. This was incorrectly changed during the multi-component updated. Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ad193x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 824529d5c776..2374ca5ffe68 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -423,7 +423,7 @@ static int __devexit ad193x_spi_remove(struct spi_device *spi) static struct spi_driver ad193x_spi_driver = { .driver = { - .name = "ad193x-codec", + .name = "ad193x", .owner = THIS_MODULE, }, .probe = ad193x_spi_probe, @@ -468,7 +468,7 @@ static int __devexit ad193x_i2c_remove(struct i2c_client *client) static struct i2c_driver ad193x_i2c_driver = { .driver = { - .name = "ad193x-codec", + .name = "ad193x", }, .probe = ad193x_i2c_probe, .remove = __devexit_p(ad193x_i2c_remove), -- GitLab From 1afa98b8074136c81d23e56836a59b2c8f1529c8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 27 Mar 2011 00:44:13 -0400 Subject: [PATCH 0121/5560] ASoC: ad1980: fix codec name The codec name should not have a "-codec" suffix since this is not part of a MFD. This was incorrectly changed during the multi-component updated. Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ad1980.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 34cb51ef2156..923b364a3e41 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -266,7 +266,7 @@ static int __devexit ad1980_remove(struct platform_device *pdev) static struct platform_driver ad1980_codec_driver = { .driver = { - .name = "ad1980-codec", + .name = "ad1980", .owner = THIS_MODULE, }, -- GitLab From 93547e89b6d2adeec627d2a8d8fc4d4b40b0e2c4 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Sun, 27 Mar 2011 17:22:57 -0400 Subject: [PATCH 0122/5560] ASoC: SSM2602: convert to soc-cache Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ssm2602.c | 138 ++++++++++++------------------------- 1 file changed, 43 insertions(+), 95 deletions(-) diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 5a5a6b169114..8a2b52fa4a7e 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -48,7 +48,6 @@ struct ssm2602_priv { unsigned int sysclk; enum snd_soc_control_type control_type; - void *control_data; struct snd_pcm_substream *master_substream; struct snd_pcm_substream *slave_substream; }; @@ -65,55 +64,7 @@ static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { 0x0000, 0x0000 }; -/* - * read ssm2602 register cache - */ -static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg == SSM2602_RESET) - return 0; - if (reg >= SSM2602_CACHEREGNUM) - return -1; - return cache[reg]; -} - -/* - * write ssm2602 register cache - */ -static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec, - u16 reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg >= SSM2602_CACHEREGNUM) - return; - cache[reg] = value; -} - -/* - * write to the ssm2602 register space - */ -static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - /* data is - * D15..D9 ssm2602 register offset - * D8...D0 register data - */ - data[0] = (reg << 1) | ((value >> 8) & 0x0001); - data[1] = value & 0x00ff; - - ssm2602_write_reg_cache(codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0) +#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0) /*Appending several "None"s just for OSS mixer use*/ static const char *ssm2602_input_select[] = { @@ -278,12 +229,11 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *i2c = codec->control_data; - u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; + u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3; int i = get_coeff(ssm2602->sysclk, params_rate(params)); if (substream == ssm2602->slave_substream) { - dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); + dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n"); return 0; } @@ -294,8 +244,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream, srate = (coeff_div[i].sr << 2) | (coeff_div[i].bosr << 1) | coeff_div[i].usb; - ssm2602_write(codec, SSM2602_ACTIVE, 0); - ssm2602_write(codec, SSM2602_SRATE, srate); + snd_soc_write(codec, SSM2602_ACTIVE, 0); + snd_soc_write(codec, SSM2602_SRATE, srate); /* bit size */ switch (params_format(params)) { @@ -311,8 +261,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream, iface |= 0x000c; break; } - ssm2602_write(codec, SSM2602_IFACE, iface); - ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); + snd_soc_write(codec, SSM2602_IFACE, iface); + snd_soc_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); return 0; } @@ -360,7 +310,7 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; /* set active */ - ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); + snd_soc_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); return 0; } @@ -374,7 +324,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream, /* deactivate */ if (!codec->active) - ssm2602_write(codec, SSM2602_ACTIVE, 0); + snd_soc_write(codec, SSM2602_ACTIVE, 0); if (ssm2602->master_substream == substream) ssm2602->master_substream = ssm2602->slave_substream; @@ -385,12 +335,12 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream, static int ssm2602_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; + u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; if (mute) - ssm2602_write(codec, SSM2602_APDIGI, + snd_soc_write(codec, SSM2602_APDIGI, mute_reg | APDIGI_ENABLE_DAC_MUTE); else - ssm2602_write(codec, SSM2602_APDIGI, mute_reg); + snd_soc_write(codec, SSM2602_APDIGI, mute_reg); return 0; } @@ -466,30 +416,30 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, } /* set iface */ - ssm2602_write(codec, SSM2602_IFACE, iface); + snd_soc_write(codec, SSM2602_IFACE, iface); return 0; } static int ssm2602_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f; + u16 reg = snd_soc_read(codec, SSM2602_PWR) & 0xff7f; switch (level) { case SND_SOC_BIAS_ON: /* vref/mid, osc on, dac unmute */ - ssm2602_write(codec, SSM2602_PWR, reg); + snd_soc_write(codec, SSM2602_PWR, reg); break; case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: /* everything off except vref/vmid, */ - ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); + snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); break; case SND_SOC_BIAS_OFF: /* everything off, dac mute, inactive */ - ssm2602_write(codec, SSM2602_ACTIVE, 0); - ssm2602_write(codec, SSM2602_PWR, 0xffff); + snd_soc_write(codec, SSM2602_ACTIVE, 0); + snd_soc_write(codec, SSM2602_PWR, 0xffff); break; } @@ -539,17 +489,10 @@ static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state) static int ssm2602_resume(struct snd_soc_codec *codec) { - int i; - u8 data[2]; - u16 *cache = codec->reg_cache; - - /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) { - data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); - data[1] = cache[i] & 0x00ff; - codec->hw_write(codec->control_data, data, 2); - } + snd_soc_cache_sync(codec); + ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; } @@ -560,31 +503,39 @@ static int ssm2602_probe(struct snd_soc_codec *codec) pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); - codec->control_data = ssm2602->control_data; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } - ssm2602_reset(codec); + ret = ssm2602_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); + return ret; + } /*power on device*/ - ssm2602_write(codec, SSM2602_ACTIVE, 0); + snd_soc_write(codec, SSM2602_ACTIVE, 0); /* set the update bits */ - reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL); - ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); - reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL); - ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); - reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V); - ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH); - reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V); - ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); + reg = snd_soc_read(codec, SSM2602_LINVOL); + snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); + reg = snd_soc_read(codec, SSM2602_RINVOL); + snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); + reg = snd_soc_read(codec, SSM2602_LOUT1V); + snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH); + reg = snd_soc_read(codec, SSM2602_ROUT1V); + snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); /*select Line in as default input*/ - ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC | + snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC | APANA_ENABLE_MIC_BOOST); - ssm2602_write(codec, SSM2602_PWR, 0); + snd_soc_write(codec, SSM2602_PWR, 0); snd_soc_add_controls(codec, ssm2602_snd_controls, ARRAY_SIZE(ssm2602_snd_controls)); ssm2602_add_widgets(codec); - return ret; + return 0; } /* remove everything here */ @@ -599,8 +550,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { .remove = ssm2602_remove, .suspend = ssm2602_suspend, .resume = ssm2602_resume, - .read = ssm2602_read_reg_cache, - .write = ssm2602_write, .set_bias_level = ssm2602_set_bias_level, .reg_cache_size = sizeof(ssm2602_reg), .reg_word_size = sizeof(u16), @@ -625,7 +574,6 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, ssm2602); - ssm2602->control_data = i2c; ssm2602->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, -- GitLab From f04cd9cb11469a6a9cbfdad824254143250d78d2 Mon Sep 17 00:00:00 2001 From: Scott Jiang Date: Sun, 27 Mar 2011 05:33:04 -0400 Subject: [PATCH 0123/5560] ASoC: Blackfin: add ad193x sysclk configuration Signed-off-by: Scott Jiang Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-ad193x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index d3ccb926b5e4..33678828d57e 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -60,8 +60,16 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int clk = 0; unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7}; int ret = 0; + + switch (params_rate(params)) { + case 48000: + clk = 12288000; + break; + } + /* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); @@ -74,6 +82,12 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + /* set codec DAI slots, 8 channels, all channels are enabled */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32); if (ret < 0) -- GitLab From c8ad38b8b26ad04d5125606065c87315308d6df5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 28 Mar 2011 01:45:08 -0400 Subject: [PATCH 0124/5560] ASoC: Blackfin: drop "-codec" from codec names The recent multi-component patch incorrectly added "-codec" suffixes to parts which are not MFD. Drop the suffix from the machine drivers too. Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-ad1836.c | 2 +- sound/soc/blackfin/bf5xx-ad193x.c | 2 +- sound/soc/blackfin/bf5xx-ad1980.c | 2 +- sound/soc/blackfin/bf5xx-ad73311.c | 2 +- sound/soc/blackfin/bf5xx-ssm2602.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 83012da9dfc2..826bae696d36 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -85,7 +85,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai = { .cpu_dai_name = "bf5xx-tdm", .codec_dai_name = "ad1836-hifi", .platform_name = "bf5xx-tdm-pcm-audio", - .codec_name = "ad1836-codec.0", + .codec_name = "ad1836.0", .ops = &bf5xx_ad1836_ops, }; diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index 33678828d57e..5794d094d003 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -113,7 +113,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai = { .cpu_dai_name = "bf5xx-tdm", .codec_dai_name ="ad193x-hifi", .platform_name = "bf5xx-tdm-pcm-audio", - .codec_name = "ad193x-codec.5", + .codec_name = "ad193x.5", .ops = &bf5xx_ad193x_ops, }; diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c index d57c9c9c9883..c147130a2e7e 100644 --- a/sound/soc/blackfin/bf5xx-ad1980.c +++ b/sound/soc/blackfin/bf5xx-ad1980.c @@ -73,7 +73,7 @@ static struct snd_soc_dai_link bf5xx_board_dai = { .cpu_dai_name = "bfin-ac97", .codec_dai_name = "ad1980-hifi", .platform_name = "bfin-pcm-audio", - .codec_name = "ad1980-codec", + .codec_name = "ad1980", .ops = &bf5xx_board_ops, }; diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index 732fb8bad076..1655f950dfb4 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c @@ -186,7 +186,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai = { .cpu_dai_name = "bf5xx-i2s", .codec_dai_name = "ad73311-hifi", .platform_name = "bfin-pcm-audio", - .codec_name = "ad73311-codec", + .codec_name = "ad73311", .ops = &bf5xx_ad73311_ops, }; diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index ad28663f5bbd..732a02ffe68f 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c @@ -119,7 +119,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai = { .cpu_dai_name = "bf5xx-i2s", .codec_dai_name = "ssm2602-hifi", .platform_name = "bf5xx-pcm-audio", - .codec_name = "ssm2602-codec.0-001b", + .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, }; -- GitLab From bfe4ee0a935dccf5980ecb5605c66fe50feb9056 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 28 Mar 2011 01:45:09 -0400 Subject: [PATCH 0125/5560] ASoC: Blackfin: standardize machine driver names Some machine drivers were using "bf5xx-", others were using "bf5xx_", while others were using "bfin-". Further, some were using the same name in the transport layer which makes it hard to use different codecs at the same time. So standardize all of them to "bfin-" and make sure they are name spaced according to their driver name. Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-ac97-pcm.c | 2 +- sound/soc/blackfin/bf5xx-ad1836.c | 6 +++--- sound/soc/blackfin/bf5xx-ad193x.c | 6 +++--- sound/soc/blackfin/bf5xx-ad1980.c | 4 ++-- sound/soc/blackfin/bf5xx-ad73311.c | 6 +++--- sound/soc/blackfin/bf5xx-i2s-pcm.c | 2 +- sound/soc/blackfin/bf5xx-i2s.c | 2 +- sound/soc/blackfin/bf5xx-ssm2602.c | 6 +++--- sound/soc/blackfin/bf5xx-tdm-pcm.c | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 5a2fd8abaefa..e940d26048d0 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -458,7 +458,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev) static struct platform_driver bf5xx_pcm_driver = { .driver = { - .name = "bf5xx-pcm-audio", + .name = "bfin-ac97-pcm-audio", .owner = THIS_MODULE, }, diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 826bae696d36..5d9d9e2805b8 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -82,15 +82,15 @@ static struct snd_soc_ops bf5xx_ad1836_ops = { static struct snd_soc_dai_link bf5xx_ad1836_dai = { .name = "ad1836", .stream_name = "AD1836", - .cpu_dai_name = "bf5xx-tdm", + .cpu_dai_name = "bfin-tdm", .codec_dai_name = "ad1836-hifi", - .platform_name = "bf5xx-tdm-pcm-audio", + .platform_name = "bfin-tdm-pcm-audio", .codec_name = "ad1836.0", .ops = &bf5xx_ad1836_ops, }; static struct snd_soc_card bf5xx_ad1836 = { - .name = "bf5xx_ad1836", + .name = "bfin-ad1836", .dai_link = &bf5xx_ad1836_dai, .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index 5794d094d003..355094fad18a 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -110,15 +110,15 @@ static struct snd_soc_ops bf5xx_ad193x_ops = { static struct snd_soc_dai_link bf5xx_ad193x_dai = { .name = "ad193x", .stream_name = "AD193X", - .cpu_dai_name = "bf5xx-tdm", + .cpu_dai_name = "bfin-tdm", .codec_dai_name ="ad193x-hifi", - .platform_name = "bf5xx-tdm-pcm-audio", + .platform_name = "bfin-tdm-pcm-audio", .codec_name = "ad193x.5", .ops = &bf5xx_ad193x_ops, }; static struct snd_soc_card bf5xx_ad193x = { - .name = "bf5xx_ad193x", + .name = "bfin-ad193x", .dai_link = &bf5xx_ad193x_dai, .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c index c147130a2e7e..a3812408c6a5 100644 --- a/sound/soc/blackfin/bf5xx-ad1980.c +++ b/sound/soc/blackfin/bf5xx-ad1980.c @@ -72,13 +72,13 @@ static struct snd_soc_dai_link bf5xx_board_dai = { .stream_name = "AC97 HiFi", .cpu_dai_name = "bfin-ac97", .codec_dai_name = "ad1980-hifi", - .platform_name = "bfin-pcm-audio", + .platform_name = "bfin-ac97-pcm-audio", .codec_name = "ad1980", .ops = &bf5xx_board_ops, }; static struct snd_soc_card bf5xx_board = { - .name = "bf5xx-board", + .name = "bfin-ad1980", .dai_link = &bf5xx_board_dai, .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index 1655f950dfb4..9f0d4f3c590f 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c @@ -183,15 +183,15 @@ static struct snd_soc_ops bf5xx_ad73311_ops = { static struct snd_soc_dai_link bf5xx_ad73311_dai = { .name = "ad73311", .stream_name = "AD73311", - .cpu_dai_name = "bf5xx-i2s", + .cpu_dai_name = "bfin-i2s", .codec_dai_name = "ad73311-hifi", - .platform_name = "bfin-pcm-audio", + .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ad73311", .ops = &bf5xx_ad73311_ops, }; static struct snd_soc_card bf5xx_ad73311 = { - .name = "bf5xx_ad73311", + .name = "bfin-ad73311", .probe = bf5xx_probe, .dai_link = &bf5xx_ad73311_dai, .num_links = 1, diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 890a0dccf902..50b1df8c1416 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -292,7 +292,7 @@ static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev) static struct platform_driver bfin_i2s_pcm_driver = { .driver = { - .name = "bfin-pcm-audio", + .name = "bfin-i2s-pcm-audio", .owner = THIS_MODULE, }, diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 37d9d3c2f2b1..dacd86c2ead4 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -316,7 +316,7 @@ static struct platform_driver bfin_i2s_driver = { .remove = __devexit_p(bfin_i2s_drv_remove), .driver = { - .name = "bf5xx-i2s", + .name = "bfin-i2s", .owner = THIS_MODULE, }, }; diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index 732a02ffe68f..8a7b589a6fb3 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c @@ -116,15 +116,15 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = { static struct snd_soc_dai_link bf5xx_ssm2602_dai = { .name = "ssm2602", .stream_name = "SSM2602", - .cpu_dai_name = "bf5xx-i2s", + .cpu_dai_name = "bfin-i2s", .codec_dai_name = "ssm2602-hifi", - .platform_name = "bf5xx-pcm-audio", + .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, }; static struct snd_soc_card bf5xx_ssm2602 = { - .name = "bf5xx_ssm2602", + .name = "bfin-ssm2602", .dai_link = &bf5xx_ssm2602_dai, .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c index 74cf759b78a6..d1bd745d72cf 100644 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c @@ -326,7 +326,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev) static struct platform_driver bfin_tdm_driver = { .driver = { - .name = "bf5xx-tdm-pcm-audio", + .name = "bfin-tdm-pcm-audio", .owner = THIS_MODULE, }, -- GitLab From 2c66cb99d134d787827ed1cd93cc59351ab66a95 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 28 Mar 2011 01:45:10 -0400 Subject: [PATCH 0126/5560] ASoC: Blackfin: push down SPORT settings from global variables Now that we have multi-component support, take the time to unify the SPORT implementations a bit and make the setup dynamic. This kills off the global sport_handle which was shared across all the Blackfin machine drivers. The pin management aspect is off loaded to platform resources, and now multiple SPORTs can be instantiated simultaneously. Signed-off-by: Barry Song Signed-off-by: Scott Jiang Signed-off-by: Mike Frysinger Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-ac97-pcm.c | 11 +- sound/soc/blackfin/bf5xx-ac97.c | 166 +++++++++------------------- sound/soc/blackfin/bf5xx-ad1836.c | 40 +++---- sound/soc/blackfin/bf5xx-ad193x.c | 40 +++---- sound/soc/blackfin/bf5xx-ad1980.c | 43 ++++--- sound/soc/blackfin/bf5xx-ad73311.c | 40 +++---- sound/soc/blackfin/bf5xx-i2s-pcm.c | 21 ++-- sound/soc/blackfin/bf5xx-i2s.c | 159 +++++++++++--------------- sound/soc/blackfin/bf5xx-sport.c | 159 +++++++++++++++++++------- sound/soc/blackfin/bf5xx-sport.h | 16 ++- sound/soc/blackfin/bf5xx-ssm2602.c | 40 +++---- sound/soc/blackfin/bf5xx-tdm-pcm.c | 21 ++-- sound/soc/blackfin/bf5xx-tdm.c | 110 +++++++----------- 13 files changed, 416 insertions(+), 450 deletions(-) diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index e940d26048d0..98b44b316e78 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -243,6 +243,9 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) static int bf5xx_pcm_open(struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); struct snd_pcm_runtime *runtime = substream->runtime; int ret; @@ -314,6 +317,9 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) { + struct snd_soc_pcm_runtime *rtd = pcm->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); struct snd_pcm_substream *substream = pcm->streams[stream].substream; struct snd_dma_buffer *buf = &substream->dma_buffer; size_t size = bf5xx_pcm_hardware.buffer_bytes_max @@ -377,6 +383,9 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) struct snd_dma_buffer *buf; int stream; #if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT) + struct snd_soc_pcm_runtime *rtd = pcm->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); size_t size = bf5xx_pcm_hardware.buffer_bytes_max * sizeof(struct ac97_frame) / 4; #endif @@ -405,8 +414,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) } #endif } - if (sport_handle) - sport_done(sport_handle); } static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index ffbac26b9bce..6d2162590889 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -41,48 +41,7 @@ * anomaly does not affect blackfin sound drivers. */ -static int *cmd_count; -static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; - -#define SPORT_REQ(x) \ - [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \ - P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0} -static u16 sport_req[][7] = { -#ifdef SPORT0_TCR1 - SPORT_REQ(0), -#endif -#ifdef SPORT1_TCR1 - SPORT_REQ(1), -#endif -#ifdef SPORT2_TCR1 - SPORT_REQ(2), -#endif -#ifdef SPORT3_TCR1 - SPORT_REQ(3), -#endif -}; - -#define SPORT_PARAMS(x) \ - [x] = { \ - .dma_rx_chan = CH_SPORT##x##_RX, \ - .dma_tx_chan = CH_SPORT##x##_TX, \ - .err_irq = IRQ_SPORT##x##_ERROR, \ - .regs = (struct sport_register *)SPORT##x##_TCR1, \ - } -static struct sport_param sport_params[4] = { -#ifdef SPORT0_TCR1 - SPORT_PARAMS(0), -#endif -#ifdef SPORT1_TCR1 - SPORT_PARAMS(1), -#endif -#ifdef SPORT2_TCR1 - SPORT_PARAMS(2), -#endif -#ifdef SPORT3_TCR1 - SPORT_PARAMS(3), -#endif -}; +static struct sport_device *ac97_sport_handle; void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, size_t count, unsigned int chan_mask) @@ -140,7 +99,8 @@ static unsigned int sport_tx_curr_frag(struct sport_device *sport) static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data) { - struct sport_device *sport = sport_handle; + struct sport_device *sport = ac97_sport_handle; + int *cmd_count = sport->private_data; int nextfrag = sport_tx_curr_frag(sport); struct ac97_frame *nextwrite; @@ -161,6 +121,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data) static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { + struct sport_device *sport_handle = ac97_sport_handle; struct ac97_frame out_frame[2], in_frame[2]; pr_debug("%s enter 0x%x\n", __func__, reg); @@ -185,6 +146,8 @@ static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97, void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { + struct sport_device *sport_handle = ac97_sport_handle; + pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val); if (sport_handle->tx_run) { @@ -203,28 +166,19 @@ void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97) { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \ - (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1)) - -#define CONCAT(a, b, c) a ## b ## c -#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS) - - u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM); - u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM)); + struct sport_device *sport_handle = ac97_sport_handle; + u16 gpio = P_IDENT(sport_handle->pin_req[3]); pr_debug("%s enter\n", __func__); - peripheral_free(per); + peripheral_free_list(sport_handle->pin_req); gpio_request(gpio, "bf5xx-ac97"); gpio_direction_output(gpio, 1); udelay(2); gpio_set_value(gpio, 0); udelay(1); gpio_free(gpio); - peripheral_request(per, "soc-audio"); -#else - pr_info("%s: Not implemented\n", __func__); -#endif + peripheral_request_list(sport_handle->pin_req, "soc-audio"); } static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97) @@ -306,18 +260,32 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai) #define bf5xx_ac97_resume NULL #endif -static int bf5xx_ac97_probe(struct snd_soc_dai *dai) +static struct snd_soc_dai_driver bfin_ac97_dai = { + .ac97_control = 1, + .suspend = bf5xx_ac97_suspend, + .resume = bf5xx_ac97_resume, + .playback = { + .stream_name = "AC97 Playback", + .channels_min = 2, +#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) + .channels_max = 6, +#else + .channels_max = 2, +#endif + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, + .capture = { + .stream_name = "AC97 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, +}; + +static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev) { - int ret = 0; - cmd_count = (int *)get_zeroed_page(GFP_KERNEL); - if (cmd_count == NULL) - return -ENOMEM; - - if (peripheral_request_list(sport_req[sport_num], "soc-audio")) { - pr_err("Requesting Peripherals failed\n"); - ret = -EFAULT; - goto peripheral_err; - } + struct sport_device *sport_handle; + int ret; #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET /* Request PB3 as reset pin */ @@ -329,12 +297,14 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai) } gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); #endif - sport_handle = sport_init(&sport_params[sport_num], 2, \ - sizeof(struct ac97_frame), NULL); + + sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame), + PAGE_SIZE); if (!sport_handle) { ret = -ENODEV; goto sport_err; } + /*SPORT works in TDM mode to simulate AC97 transfers*/ #if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1); @@ -361,67 +331,37 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai) goto sport_config_err; } + ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai); + if (ret) { + pr_err("Failed to register DAI: %d\n", ret); + goto sport_config_err; + } + + ac97_sport_handle = sport_handle; + return 0; sport_config_err: - kfree(sport_handle); + sport_done(sport_handle); sport_err: #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); gpio_err: #endif - peripheral_free_list(sport_req[sport_num]); -peripheral_err: - free_page((unsigned long)cmd_count); - cmd_count = NULL; return ret; } -static int bf5xx_ac97_remove(struct snd_soc_dai *dai) +static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev) { - free_page((unsigned long)cmd_count); - cmd_count = NULL; - peripheral_free_list(sport_req[sport_num]); + struct sport_device *sport_handle = platform_get_drvdata(pdev); + + snd_soc_unregister_dai(&pdev->dev); + sport_done(sport_handle); #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); #endif - return 0; -} - -struct snd_soc_dai_driver bfin_ac97_dai = { - .ac97_control = 1, - .probe = bf5xx_ac97_probe, - .remove = bf5xx_ac97_remove, - .suspend = bf5xx_ac97_suspend, - .resume = bf5xx_ac97_resume, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, -#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) - .channels_max = 6, -#else - .channels_max = 2, -#endif - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, }, -}; -EXPORT_SYMBOL_GPL(bfin_ac97_dai); - -static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev) -{ - return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai); -} -static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&pdev->dev); return 0; } diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 5d9d9e2805b8..ea4951cf5526 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -29,22 +29,12 @@ #include #include "../codecs/ad1836.h" -#include "bf5xx-sport.h" #include "bf5xx-tdm-pcm.h" #include "bf5xx-tdm.h" static struct snd_soc_card bf5xx_ad1836; -static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - snd_soc_dai_set_drvdata(cpu_dai, sport_handle); - return 0; -} - static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -75,23 +65,33 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, } static struct snd_soc_ops bf5xx_ad1836_ops = { - .startup = bf5xx_ad1836_startup, .hw_params = bf5xx_ad1836_hw_params, }; -static struct snd_soc_dai_link bf5xx_ad1836_dai = { - .name = "ad1836", - .stream_name = "AD1836", - .cpu_dai_name = "bfin-tdm", - .codec_dai_name = "ad1836-hifi", - .platform_name = "bfin-tdm-pcm-audio", - .codec_name = "ad1836.0", - .ops = &bf5xx_ad1836_ops, +static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { + { + .name = "ad1836", + .stream_name = "AD1836", + .cpu_dai_name = "bfin-tdm.0", + .codec_dai_name = "ad1836-hifi", + .platform_name = "bfin-tdm-pcm-audio", + .codec_name = "ad1836.0", + .ops = &bf5xx_ad1836_ops, + }, + { + .name = "ad1836", + .stream_name = "AD1836", + .cpu_dai_name = "bfin-tdm.1", + .codec_dai_name = "ad1836-hifi", + .platform_name = "bfin-tdm-pcm-audio", + .codec_name = "ad1836.0", + .ops = &bf5xx_ad1836_ops, + }, }; static struct snd_soc_card bf5xx_ad1836 = { .name = "bfin-ad1836", - .dai_link = &bf5xx_ad1836_dai, + .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index 355094fad18a..d6651c033cb7 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -38,22 +38,12 @@ #include #include "../codecs/ad193x.h" -#include "bf5xx-sport.h" #include "bf5xx-tdm-pcm.h" #include "bf5xx-tdm.h" static struct snd_soc_card bf5xx_ad193x; -static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - snd_soc_dai_set_drvdata(cpu_dai, sport_handle); - return 0; -} - static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -103,23 +93,33 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, } static struct snd_soc_ops bf5xx_ad193x_ops = { - .startup = bf5xx_ad193x_startup, .hw_params = bf5xx_ad193x_hw_params, }; -static struct snd_soc_dai_link bf5xx_ad193x_dai = { - .name = "ad193x", - .stream_name = "AD193X", - .cpu_dai_name = "bfin-tdm", - .codec_dai_name ="ad193x-hifi", - .platform_name = "bfin-tdm-pcm-audio", - .codec_name = "ad193x.5", - .ops = &bf5xx_ad193x_ops, +static struct snd_soc_dai_link bf5xx_ad193x_dai[] = { + { + .name = "ad193x", + .stream_name = "AD193X", + .cpu_dai_name = "bfin-tdm.0", + .codec_dai_name ="ad193x-hifi", + .platform_name = "bfin-tdm-pcm-audio", + .codec_name = "ad193x.5", + .ops = &bf5xx_ad193x_ops, + }, + { + .name = "ad193x", + .stream_name = "AD193X", + .cpu_dai_name = "bfin-tdm.1", + .codec_dai_name ="ad193x-hifi", + .platform_name = "bfin-tdm-pcm-audio", + .codec_name = "ad193x.5", + .ops = &bf5xx_ad193x_ops, + }, }; static struct snd_soc_card bf5xx_ad193x = { .name = "bfin-ad193x", - .dai_link = &bf5xx_ad193x_dai, + .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c index a3812408c6a5..06a84b211b52 100644 --- a/sound/soc/blackfin/bf5xx-ad1980.c +++ b/sound/soc/blackfin/bf5xx-ad1980.c @@ -47,39 +47,34 @@ #include #include "../codecs/ad1980.h" -#include "bf5xx-sport.h" + #include "bf5xx-ac97-pcm.h" #include "bf5xx-ac97.h" static struct snd_soc_card bf5xx_board; -static int bf5xx_board_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - pr_debug("%s enter\n", __func__); - snd_soc_dai_set_drvdata(cpu_dai, sport_handle); - return 0; -} - -static struct snd_soc_ops bf5xx_board_ops = { - .startup = bf5xx_board_startup, -}; - -static struct snd_soc_dai_link bf5xx_board_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai_name = "bfin-ac97", - .codec_dai_name = "ad1980-hifi", - .platform_name = "bfin-ac97-pcm-audio", - .codec_name = "ad1980", - .ops = &bf5xx_board_ops, +static struct snd_soc_dai_link bf5xx_board_dai[] = { + { + .name = "AC97", + .stream_name = "AC97 HiFi", + .cpu_dai_name = "bfin-ac97.0", + .codec_dai_name = "ad1980-hifi", + .platform_name = "bfin-ac97-pcm-audio", + .codec_name = "ad1980", + }, + { + .name = "AC97", + .stream_name = "AC97 HiFi", + .cpu_dai_name = "bfin-ac97.1", + .codec_dai_name = "ad1980-hifi", + .platform_name = "bfin-ac97-pcm-audio", + .codec_name = "ad1980", + }, }; static struct snd_soc_card bf5xx_board = { .name = "bfin-ad1980", - .dai_link = &bf5xx_board_dai, + .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index 9f0d4f3c590f..732a247f2527 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c @@ -145,16 +145,6 @@ static int bf5xx_probe(struct platform_device *pdev) return 0; } -static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - pr_debug("%s enter\n", __func__); - snd_soc_dai_set_drvdata(cpu_dai, sport_handle); - return 0; -} - static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -176,24 +166,34 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, static struct snd_soc_ops bf5xx_ad73311_ops = { - .startup = bf5xx_ad73311_startup, .hw_params = bf5xx_ad73311_hw_params, }; -static struct snd_soc_dai_link bf5xx_ad73311_dai = { - .name = "ad73311", - .stream_name = "AD73311", - .cpu_dai_name = "bfin-i2s", - .codec_dai_name = "ad73311-hifi", - .platform_name = "bfin-i2s-pcm-audio", - .codec_name = "ad73311", - .ops = &bf5xx_ad73311_ops, +static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { + { + .name = "ad73311", + .stream_name = "AD73311", + .cpu_dai_name = "bfin-i2s.0", + .codec_dai_name = "ad73311-hifi", + .platform_name = "bfin-i2s-pcm-audio", + .codec_name = "ad73311", + .ops = &bf5xx_ad73311_ops, + }, + { + .name = "ad73311", + .stream_name = "AD73311", + .cpu_dai_name = "bfin-i2s.1", + .codec_dai_name = "ad73311-hifi", + .platform_name = "bfin-i2s-pcm-audio", + .codec_name = "ad73311", + .ops = &bf5xx_ad73311_ops, + }, }; static struct snd_soc_card bf5xx_ad73311 = { .name = "bfin-ad73311", .probe = bf5xx_probe, - .dai_link = &bf5xx_ad73311_dai, + .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 50b1df8c1416..b5101efd1c87 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -148,10 +148,15 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) static int bf5xx_pcm_open(struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *buf = &substream->dma_buffer; int ret; pr_debug("%s enter\n", __func__); + snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); ret = snd_pcm_hw_constraint_integer(runtime, \ @@ -159,9 +164,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream) if (ret < 0) goto out; - if (sport_handle != NULL) + if (sport_handle != NULL) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sport_handle->tx_buf = buf->area; + else + sport_handle->rx_buf = buf->area; + runtime->private_data = sport_handle; - else { + } else { pr_err("sport_handle is NULL\n"); return -1; } @@ -214,11 +224,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) pr_debug("%s, area:%p, size:0x%08lx\n", __func__, buf->area, buf->bytes); - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - sport_handle->tx_buf = buf->area; - else - sport_handle->rx_buf = buf->area; - return 0; } @@ -239,8 +244,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) dma_free_coherent(NULL, buf->bytes, buf->area, 0); buf->area = NULL; } - if (sport_handle) - sport_done(sport_handle); } static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index dacd86c2ead4..00cc3e00b2fe 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -51,59 +51,24 @@ struct bf5xx_i2s_port { int configured; }; -static struct bf5xx_i2s_port bf5xx_i2s; -static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; - -static struct sport_param sport_params[2] = { - { - .dma_rx_chan = CH_SPORT0_RX, - .dma_tx_chan = CH_SPORT0_TX, - .err_irq = IRQ_SPORT0_ERROR, - .regs = (struct sport_register *)SPORT0_TCR1, - }, - { - .dma_rx_chan = CH_SPORT1_RX, - .dma_tx_chan = CH_SPORT1_TX, - .err_irq = IRQ_SPORT1_ERROR, - .regs = (struct sport_register *)SPORT1_TCR1, - } -}; - -/* - * Setting the TFS pin selector for SPORT 0 based on whether the selected - * port id F or G. If the port is F then no conflict should exist for the - * TFS. When Port G is selected and EMAC then there is a conflict between - * the PHY interrupt line and TFS. Current settings prevent the conflict - * by ignoring the TFS pin when Port G is selected. This allows both - * codecs and EMAC using Port G concurrently. - */ -#ifdef CONFIG_BF527_SPORT0_PORTG -#define LOCAL_SPORT0_TFS (0) -#else -#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) -#endif - -static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0}, - {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI, - P_SPORT1_RSCLK, P_SPORT1_TFS, 0} }; - static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); + struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data; int ret = 0; /* interface format:support I2S,slave mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - bf5xx_i2s.tcr1 |= TFSR | TCKFE; - bf5xx_i2s.rcr1 |= RFSR | RCKFE; - bf5xx_i2s.tcr2 |= TSFSE; - bf5xx_i2s.rcr2 |= RSFSE; + bf5xx_i2s->tcr1 |= TFSR | TCKFE; + bf5xx_i2s->rcr1 |= RFSR | RCKFE; + bf5xx_i2s->tcr2 |= TSFSE; + bf5xx_i2s->rcr2 |= RSFSE; break; case SND_SOC_DAIFMT_DSP_A: - bf5xx_i2s.tcr1 |= TFSR; - bf5xx_i2s.rcr1 |= RFSR; + bf5xx_i2s->tcr1 |= TFSR; + bf5xx_i2s->rcr1 |= RFSR; break; case SND_SOC_DAIFMT_LEFT_J: ret = -EINVAL; @@ -135,33 +100,35 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); + struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data; int ret = 0; - bf5xx_i2s.tcr2 &= ~0x1f; - bf5xx_i2s.rcr2 &= ~0x1f; + bf5xx_i2s->tcr2 &= ~0x1f; + bf5xx_i2s->rcr2 &= ~0x1f; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: bf5xx_i2s->tcr2 |= 7; bf5xx_i2s->rcr2 |= 7; sport_handle->wdsize = 1; case SNDRV_PCM_FORMAT_S16_LE: - bf5xx_i2s.tcr2 |= 15; - bf5xx_i2s.rcr2 |= 15; + bf5xx_i2s->tcr2 |= 15; + bf5xx_i2s->rcr2 |= 15; sport_handle->wdsize = 2; break; case SNDRV_PCM_FORMAT_S24_LE: - bf5xx_i2s.tcr2 |= 23; - bf5xx_i2s.rcr2 |= 23; + bf5xx_i2s->tcr2 |= 23; + bf5xx_i2s->rcr2 |= 23; sport_handle->wdsize = 3; break; case SNDRV_PCM_FORMAT_S32_LE: - bf5xx_i2s.tcr2 |= 31; - bf5xx_i2s.rcr2 |= 31; + bf5xx_i2s->tcr2 |= 31; + bf5xx_i2s->rcr2 |= 31; sport_handle->wdsize = 4; break; } - if (!bf5xx_i2s.configured) { + if (!bf5xx_i2s->configured) { /* * TX and RX are not independent,they are enabled at the * same time, even if only one side is running. So, we @@ -170,16 +137,16 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, * * CPU DAI:slave mode. */ - bf5xx_i2s.configured = 1; - ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, - bf5xx_i2s.rcr2, 0, 0); + bf5xx_i2s->configured = 1; + ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1, + bf5xx_i2s->rcr2, 0, 0); if (ret) { pr_err("SPORT is busy!\n"); return -EBUSY; } - ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, - bf5xx_i2s.tcr2, 0, 0); + ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1, + bf5xx_i2s->tcr2, 0, 0); if (ret) { pr_err("SPORT is busy!\n"); return -EBUSY; @@ -192,41 +159,19 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); + struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data; + pr_debug("%s enter\n", __func__); /* No active stream, SPORT is allowed to be configured again. */ if (!dai->active) - bf5xx_i2s.configured = 0; -} - -static int bf5xx_i2s_probe(struct snd_soc_dai *dai) -{ - pr_debug("%s enter\n", __func__); - if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { - pr_err("Requesting Peripherals failed\n"); - return -EFAULT; - } - - /* request DMA for SPORT */ - sport_handle = sport_init(&sport_params[sport_num], 4, \ - 2 * sizeof(u32), NULL); - if (!sport_handle) { - peripheral_free_list(&sport_req[sport_num][0]); - return -ENODEV; - } - - return 0; -} - -static int bf5xx_i2s_remove(struct snd_soc_dai *dai) -{ - pr_debug("%s enter\n", __func__); - peripheral_free_list(&sport_req[sport_num][0]); - return 0; + bf5xx_i2s->configured = 0; } #ifdef CONFIG_PM static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); pr_debug("%s : sport %d\n", __func__, dai->id); @@ -239,19 +184,21 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) static int bf5xx_i2s_resume(struct snd_soc_dai *dai) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); + struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data; int ret; pr_debug("%s : sport %d\n", __func__, dai->id); - ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, - bf5xx_i2s.rcr2, 0, 0); + ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1, + bf5xx_i2s->rcr2, 0, 0); if (ret) { pr_err("SPORT is busy!\n"); return -EBUSY; } - ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, - bf5xx_i2s.tcr2, 0, 0); + ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1, + bf5xx_i2s->tcr2, 0, 0); if (ret) { pr_err("SPORT is busy!\n"); return -EBUSY; @@ -283,8 +230,6 @@ static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { }; static struct snd_soc_dai_driver bf5xx_i2s_dai = { - .probe = bf5xx_i2s_probe, - .remove = bf5xx_i2s_remove, .suspend = bf5xx_i2s_suspend, .resume = bf5xx_i2s_resume, .playback = { @@ -300,21 +245,43 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = { .ops = &bf5xx_i2s_dai_ops, }; -static int bfin_i2s_drv_probe(struct platform_device *pdev) +static int __devinit bf5xx_i2s_probe(struct platform_device *pdev) { - return snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); + struct sport_device *sport_handle; + int ret; + + /* configure SPORT for I2S */ + sport_handle = sport_init(pdev, 4, 2 * sizeof(u32), + sizeof(struct bf5xx_i2s_port)); + if (!sport_handle) + return -ENODEV; + + /* register with the ASoC layers */ + ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); + if (ret) { + pr_err("Failed to register DAI: %d\n", ret); + sport_done(sport_handle); + return ret; + } + + return 0; } -static int __devexit bfin_i2s_drv_remove(struct platform_device *pdev) +static int __devexit bf5xx_i2s_remove(struct platform_device *pdev) { + struct sport_device *sport_handle = platform_get_drvdata(pdev); + + pr_debug("%s enter\n", __func__); + snd_soc_unregister_dai(&pdev->dev); + sport_done(sport_handle); + return 0; } static struct platform_driver bfin_i2s_driver = { - .probe = bfin_i2s_drv_probe, - .remove = __devexit_p(bfin_i2s_drv_remove), - + .probe = bf5xx_i2s_probe, + .remove = __devexit_p(bf5xx_i2s_remove), .driver = { .name = "bfin-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c index 99051ff0954e..a2d40349fcc4 100644 --- a/sound/soc/blackfin/bf5xx-sport.c +++ b/sound/soc/blackfin/bf5xx-sport.c @@ -42,8 +42,6 @@ /* delay between frame sync pulse and first data bit in multichannel mode */ #define FRAME_DELAY (1<<12) -struct sport_device *sport_handle; -EXPORT_SYMBOL(sport_handle); /* note: multichannel is in units of 8 channels, * tdm_count is # channels NOT / 8 ! */ int sport_set_multichannel(struct sport_device *sport, @@ -798,86 +796,164 @@ int sport_set_err_callback(struct sport_device *sport, } EXPORT_SYMBOL(sport_set_err_callback); -struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, - unsigned dummy_count, void *private_data) +static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param) { - int ret; + /* Extract settings from platform data */ + struct device *dev = &pdev->dev; + struct bfin_snd_platform_data *pdata = dev->platform_data; + struct resource *res; + + param->num = pdev->id; + + if (!pdata) { + dev_err(dev, "no platform_data\n"); + return -ENODEV; + } + param->pin_req = pdata->pin_req; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "no MEM resource\n"); + return -ENODEV; + } + param->regs = (struct sport_register *)res->start; + + /* first RX, then TX */ + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(dev, "no rx DMA resource\n"); + return -ENODEV; + } + param->dma_rx_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(dev, "no tx DMA resource\n"); + return -ENODEV; + } + param->dma_tx_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "no irq resource\n"); + return -ENODEV; + } + param->err_irq = res->start; + + return 0; +} + +struct sport_device *sport_init(struct platform_device *pdev, + unsigned int wdsize, unsigned int dummy_count, size_t priv_size) +{ + struct device *dev = &pdev->dev; + struct sport_param param; struct sport_device *sport; - pr_debug("%s enter\n", __func__); - BUG_ON(param == NULL); - BUG_ON(wdsize == 0 || dummy_count == 0); - sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL); - if (!sport) { - pr_err("Failed to allocate for sport device\n"); + int ret; + + dev_dbg(dev, "%s enter\n", __func__); + + param.wdsize = wdsize; + param.dummy_count = dummy_count; + BUG_ON(param.wdsize == 0 || param.dummy_count == 0); + + ret = sport_config_pdev(pdev, ¶m); + if (ret) + return NULL; + + if (peripheral_request_list(param.pin_req, "soc-audio")) { + dev_err(dev, "requesting Peripherals failed\n"); return NULL; } - memset(sport, 0, sizeof(struct sport_device)); - sport->dma_rx_chan = param->dma_rx_chan; - sport->dma_tx_chan = param->dma_tx_chan; - sport->err_irq = param->err_irq; - sport->regs = param->regs; - sport->private_data = private_data; + sport = kzalloc(sizeof(*sport), GFP_KERNEL); + if (!sport) { + dev_err(dev, "failed to allocate for sport device\n"); + goto __init_err0; + } + + sport->num = param.num; + sport->dma_rx_chan = param.dma_rx_chan; + sport->dma_tx_chan = param.dma_tx_chan; + sport->err_irq = param.err_irq; + sport->regs = param.regs; + sport->pin_req = param.pin_req; if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) { - pr_err("Failed to request RX dma %d\n", \ - sport->dma_rx_chan); + dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan); goto __init_err1; } if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) { - pr_err("Failed to request RX irq %d\n", \ - sport->dma_rx_chan); + dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan); goto __init_err2; } if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) { - pr_err("Failed to request TX dma %d\n", \ - sport->dma_tx_chan); + dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan); goto __init_err2; } if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) { - pr_err("Failed to request TX irq %d\n", \ - sport->dma_tx_chan); + dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan); goto __init_err3; } if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err", sport) < 0) { - pr_err("Failed to request err irq:%d\n", \ - sport->err_irq); + dev_err(dev, "failed to request err irq %d\n", sport->err_irq); goto __init_err3; } - pr_err("dma rx:%d tx:%d, err irq:%d, regs:%p\n", + dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n", sport->dma_rx_chan, sport->dma_tx_chan, sport->err_irq, sport->regs); - sport->wdsize = wdsize; - sport->dummy_count = dummy_count; + sport->wdsize = param.wdsize; + sport->dummy_count = param.dummy_count; + + sport->private_data = kzalloc(priv_size, GFP_KERNEL); + if (!sport->private_data) { + dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size); + goto __init_err4; + } if (L1_DATA_A_LENGTH) - sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2); + sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2); else - sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL); + sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL); if (sport->dummy_buf == NULL) { - pr_err("Failed to allocate dummy buffer\n"); - goto __error; + dev_err(dev, "failed to allocate dummy buffer\n"); + goto __error1; } ret = sport_config_rx_dummy(sport); if (ret) { - pr_err("Failed to config rx dummy ring\n"); - goto __error; + dev_err(dev, "failed to config rx dummy ring\n"); + goto __error2; } ret = sport_config_tx_dummy(sport); if (ret) { - pr_err("Failed to config tx dummy ring\n"); - goto __error; + dev_err(dev, "failed to config tx dummy ring\n"); + goto __error3; } + platform_set_drvdata(pdev, sport); + return sport; -__error: +__error3: + if (L1_DATA_A_LENGTH) + l1_data_sram_free(sport->dummy_rx_desc); + else + dma_free_coherent(NULL, 2*sizeof(struct dmasg), + sport->dummy_rx_desc, 0); +__error2: + if (L1_DATA_A_LENGTH) + l1_data_sram_free(sport->dummy_buf); + else + kfree(sport->dummy_buf); +__error1: + kfree(sport->private_data); +__init_err4: free_irq(sport->err_irq, sport); __init_err3: free_dma(sport->dma_tx_chan); @@ -885,6 +961,8 @@ struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, free_dma(sport->dma_rx_chan); __init_err1: kfree(sport); +__init_err0: + peripheral_free_list(param.pin_req); return NULL; } EXPORT_SYMBOL(sport_init); @@ -917,8 +995,9 @@ void sport_done(struct sport_device *sport) free_dma(sport->dma_tx_chan); free_irq(sport->err_irq, sport); + kfree(sport->private_data); + peripheral_free_list(sport->pin_req); kfree(sport); - sport = NULL; } EXPORT_SYMBOL(sport_done); diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h index a86e8cc0b2d3..5ab60bd613ea 100644 --- a/sound/soc/blackfin/bf5xx-sport.h +++ b/sound/soc/blackfin/bf5xx-sport.h @@ -1,5 +1,5 @@ /* - * File: bf5xx_ac97_sport.h + * File: bf5xx_sport.h * Based on: * Author: Roy Huang * @@ -33,15 +33,18 @@ #include #include #include +#include #include #include #define DESC_ELEMENT_COUNT 9 struct sport_device { + int num; int dma_rx_chan; int dma_tx_chan; int err_irq; + const unsigned short *pin_req; struct sport_register *regs; unsigned char *rx_buf; @@ -103,17 +106,20 @@ struct sport_device { void *private_data; }; -extern struct sport_device *sport_handle; - struct sport_param { + int num; int dma_rx_chan; int dma_tx_chan; int err_irq; + const unsigned short *pin_req; struct sport_register *regs; + unsigned int wdsize; + unsigned int dummy_count; + void *private_data; }; -struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, - unsigned dummy_count, void *private_data); +struct sport_device *sport_init(struct platform_device *pdev, + unsigned int wdsize, unsigned int dummy_count, size_t priv_size); void sport_done(struct sport_device *sport); diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index 8a7b589a6fb3..767e772a815d 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c @@ -44,16 +44,6 @@ static struct snd_soc_card bf5xx_ssm2602; -static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - pr_debug("%s enter\n", __func__); - snd_soc_dai_set_drvdata(cpu_dai, sport_handle); - return 0; -} - static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -109,23 +99,33 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, } static struct snd_soc_ops bf5xx_ssm2602_ops = { - .startup = bf5xx_ssm2602_startup, .hw_params = bf5xx_ssm2602_hw_params, }; -static struct snd_soc_dai_link bf5xx_ssm2602_dai = { - .name = "ssm2602", - .stream_name = "SSM2602", - .cpu_dai_name = "bfin-i2s", - .codec_dai_name = "ssm2602-hifi", - .platform_name = "bfin-i2s-pcm-audio", - .codec_name = "ssm2602.0-001b", - .ops = &bf5xx_ssm2602_ops, +static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { + { + .name = "ssm2602", + .stream_name = "SSM2602", + .cpu_dai_name = "bfin-i2s.0", + .codec_dai_name = "ssm2602-hifi", + .platform_name = "bfin-i2s-pcm-audio", + .codec_name = "ssm2602.0-001b", + .ops = &bf5xx_ssm2602_ops, + }, + { + .name = "ssm2602", + .stream_name = "SSM2602", + .cpu_dai_name = "bfin-i2s.1", + .codec_dai_name = "ssm2602-hifi", + .platform_name = "bfin-i2s-pcm-audio", + .codec_name = "ssm2602.0-001b", + .ops = &bf5xx_ssm2602_ops, + }, }; static struct snd_soc_card bf5xx_ssm2602 = { .name = "bfin-ssm2602", - .dai_link = &bf5xx_ssm2602_dai, + .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c index d1bd745d72cf..07cfc7a9e49a 100644 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c @@ -154,7 +154,12 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) static int bf5xx_pcm_open(struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai); struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_dma_buffer *buf = &substream->dma_buffer; + int ret = 0; snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); @@ -164,9 +169,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream) if (ret < 0) goto out; - if (sport_handle != NULL) + if (sport_handle != NULL) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sport_handle->tx_buf = buf->area; + else + sport_handle->rx_buf = buf->area; + runtime->private_data = sport_handle; - else { + } else { pr_err("sport_handle is NULL\n"); ret = -ENODEV; } @@ -249,11 +259,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) } buf->bytes = size; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - sport_handle->tx_buf = buf->area; - else - sport_handle->rx_buf = buf->area; - return 0; } @@ -274,8 +279,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) dma_free_coherent(NULL, buf->bytes, buf->area, 0); buf->area = NULL; } - if (sport_handle) - sport_done(sport_handle); } static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c index 5515ac9e05c7..a822d1ee1380 100644 --- a/sound/soc/blackfin/bf5xx-tdm.c +++ b/sound/soc/blackfin/bf5xx-tdm.c @@ -46,43 +46,6 @@ #include "bf5xx-sport.h" #include "bf5xx-tdm.h" -static struct bf5xx_tdm_port bf5xx_tdm; -static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; - -static struct sport_param sport_params[2] = { - { - .dma_rx_chan = CH_SPORT0_RX, - .dma_tx_chan = CH_SPORT0_TX, - .err_irq = IRQ_SPORT0_ERROR, - .regs = (struct sport_register *)SPORT0_TCR1, - }, - { - .dma_rx_chan = CH_SPORT1_RX, - .dma_tx_chan = CH_SPORT1_TX, - .err_irq = IRQ_SPORT1_ERROR, - .regs = (struct sport_register *)SPORT1_TCR1, - } -}; - -/* - * Setting the TFS pin selector for SPORT 0 based on whether the selected - * port id F or G. If the port is F then no conflict should exist for the - * TFS. When Port G is selected and EMAC then there is a conflict between - * the PHY interrupt line and TFS. Current settings prevent the conflict - * by ignoring the TFS pin when Port G is selected. This allows both - * codecs and EMAC using Port G concurrently. - */ -#ifdef CONFIG_BF527_SPORT0_PORTG -#define LOCAL_SPORT0_TFS (0) -#else -#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) -#endif - -static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0}, - {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI, - P_SPORT1_RSCLK, P_SPORT1_TFS, 0} }; - static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { @@ -119,14 +82,16 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); + struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data; int ret = 0; - bf5xx_tdm.tcr2 &= ~0x1f; - bf5xx_tdm.rcr2 &= ~0x1f; + bf5xx_tdm->tcr2 &= ~0x1f; + bf5xx_tdm->rcr2 &= ~0x1f; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S32_LE: - bf5xx_tdm.tcr2 |= 31; - bf5xx_tdm.rcr2 |= 31; + bf5xx_tdm->tcr2 |= 31; + bf5xx_tdm->rcr2 |= 31; sport_handle->wdsize = 4; break; /* at present, we only support 32bit transfer */ @@ -136,7 +101,7 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream, break; } - if (!bf5xx_tdm.configured) { + if (!bf5xx_tdm->configured) { /* * TX and RX are not independent,they are enabled at the * same time, even if only one side is running. So, we @@ -145,21 +110,21 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream, * * CPU DAI:slave mode. */ - ret = sport_config_rx(sport_handle, bf5xx_tdm.rcr1, - bf5xx_tdm.rcr2, 0, 0); + ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1, + bf5xx_tdm->rcr2, 0, 0); if (ret) { pr_err("SPORT is busy!\n"); return -EBUSY; } - ret = sport_config_tx(sport_handle, bf5xx_tdm.tcr1, - bf5xx_tdm.tcr2, 0, 0); + ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1, + bf5xx_tdm->tcr2, 0, 0); if (ret) { pr_err("SPORT is busy!\n"); return -EBUSY; } - bf5xx_tdm.configured = 1; + bf5xx_tdm->configured = 1; } return 0; @@ -168,15 +133,20 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream, static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); + struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data; + /* No active stream, SPORT is allowed to be configured again. */ if (!dai->active) - bf5xx_tdm.configured = 0; + bf5xx_tdm->configured = 0; } static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num, unsigned int *tx_slot, unsigned int rx_num, unsigned int *rx_slot) { + struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai); + struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data; int i; unsigned int slot; unsigned int tx_mapped = 0, rx_mapped = 0; @@ -189,7 +159,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, slot = tx_slot[i]; if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && (!(tx_mapped & (1 << slot)))) { - bf5xx_tdm.tx_map[i] = slot; + bf5xx_tdm->tx_map[i] = slot; tx_mapped |= 1 << slot; } else return -EINVAL; @@ -198,7 +168,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, slot = rx_slot[i]; if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && (!(rx_mapped & (1 << slot)))) { - bf5xx_tdm.rx_map[i] = slot; + bf5xx_tdm->rx_map[i] = slot; rx_mapped |= 1 << slot; } else return -EINVAL; @@ -212,12 +182,14 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) { struct sport_device *sport = snd_soc_dai_get_drvdata(dai); - if (!dai->active) - return 0; - if (dai->capture_active) - sport_rx_stop(sport); if (dai->playback_active) sport_tx_stop(sport); + if (dai->capture_active) + sport_rx_stop(sport); + + /* isolate sync/clock pins from codec while sports resume */ + peripheral_free_list(sport->pin_req); + return 0; } @@ -226,9 +198,6 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai) int ret; struct sport_device *sport = snd_soc_dai_get_drvdata(dai); - if (!dai->active) - return 0; - ret = sport_set_multichannel(sport, 8, 0xFF, 1); if (ret) { pr_err("SPORT is busy!\n"); @@ -247,6 +216,8 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai) ret = -EBUSY; } + peripheral_request_list(sport->pin_req, "soc-audio"); + return 0; } @@ -280,20 +251,14 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = { static int __devinit bfin_tdm_probe(struct platform_device *pdev) { - int ret = 0; - - if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { - pr_err("Requesting Peripherals failed\n"); - return -EFAULT; - } + struct sport_device *sport_handle; + int ret; - /* request DMA for SPORT */ - sport_handle = sport_init(&sport_params[sport_num], 4, \ - 8 * sizeof(u32), NULL); - if (!sport_handle) { - peripheral_free_list(&sport_req[sport_num][0]); + /* configure SPORT for TDM */ + sport_handle = sport_init(pdev, 4, 8 * sizeof(u32), + sizeof(struct bf5xx_tdm_port)); + if (!sport_handle) return -ENODEV; - } /* SPORT works in TDM mode */ ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1); @@ -323,18 +288,19 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev) goto sport_config_err; } - sport_handle->private_data = &bf5xx_tdm; return 0; sport_config_err: - peripheral_free_list(&sport_req[sport_num][0]); + sport_done(sport_handle); return ret; } static int __devexit bfin_tdm_remove(struct platform_device *pdev) { - peripheral_free_list(&sport_req[sport_num][0]); + struct sport_device *sport_handle = platform_get_drvdata(pdev); + snd_soc_unregister_dai(&pdev->dev); + sport_done(sport_handle); return 0; } -- GitLab From 3f8acea307abfbecf0dca8793c30195797c62dba Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 29 Mar 2011 09:29:01 -0700 Subject: [PATCH 0127/5560] doc: stable_api_nonsense.txt: fix paragraph to make more sense. Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- Documentation/stable_api_nonsense.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/stable_api_nonsense.txt b/Documentation/stable_api_nonsense.txt index 847b342b7b20..db3be892afb2 100644 --- a/Documentation/stable_api_nonsense.txt +++ b/Documentation/stable_api_nonsense.txt @@ -122,7 +122,7 @@ operating system to suffer. In both of these instances, all developers agreed that these were important changes that needed to be made, and they were made, with -relatively little pain. If Linux had to ensure that it preserve a +relatively little pain. If Linux had to ensure that it will preserve a stable source interface, a new interface would have been created, and the older, broken one would have had to be maintained over time, leading to extra work for the USB developers. Since all Linux USB developers do -- GitLab From 22dd2fd283ea96b4d45185d3e861ef46005082f4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 15 Mar 2011 10:03:24 +0300 Subject: [PATCH 0128/5560] iwlwifi: remove duplicate initialization in __iwl_down() We initialize exit_pending twice. It's the second initialization which is correct. That was added in d745d472af "iwlwifi: cancel scan when down the device". Signed-off-by: Dan Carpenter Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 321b18b59135..7adc60ea03cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2537,7 +2537,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv); static void __iwl_down(struct iwl_priv *priv) { unsigned long flags; - int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); + int exit_pending; IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); -- GitLab From 6d64ab7f9240e3201fde3fd16ce4227bd795d2ab Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 15 Mar 2011 19:55:35 +0530 Subject: [PATCH 0129/5560] ath9k_htc: Fix LED pin for AR9287 HTC device Signed-off-by: Rajkumar Manoharan 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 753a245c5ad1..ec47be94b74f 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -328,7 +328,7 @@ struct ath9k_debug { #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #define ATH_LED_PIN_DEF 1 -#define ATH_LED_PIN_9287 8 +#define ATH_LED_PIN_9287 10 #define ATH_LED_PIN_9271 15 #define ATH_LED_PIN_7010 12 #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ -- GitLab From 81544026e4cecb85a8b727d5f64cb3c8a8cb64a3 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 15 Mar 2011 19:55:36 +0530 Subject: [PATCH 0130/5560] ath9k_hw: Fix throughput drops in HT40 mode for AR9287 chips Doing adc gain calibration for AR9287 chips is causing throughput drops in HT40 mode. Remove ADC Gain from supported calibration list. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 76388c6d6692..cb611b287b35 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -26,6 +26,27 @@ enum ar9002_cal_types { IQ_MISMATCH_CAL = BIT(2), }; +static bool ar9002_hw_is_cal_supported(struct ath_hw *ah, + struct ath9k_channel *chan, + enum ar9002_cal_types cal_type) +{ + bool supported = false; + switch (ah->supp_cals & cal_type) { + case IQ_MISMATCH_CAL: + /* Run IQ Mismatch for non-CCK only */ + if (!IS_CHAN_B(chan)) + supported = true; + break; + case ADC_GAIN_CAL: + case ADC_DC_CAL: + /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ + if (!IS_CHAN_B(chan) && + !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) + supported = true; + break; + } + return supported; +} static void ar9002_hw_setup_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal) @@ -858,26 +879,32 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { ah->supp_cals = IQ_MISMATCH_CAL; - if (AR_SREV_9160_10_OR_LATER(ah) && - !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) { + if (AR_SREV_9160_10_OR_LATER(ah)) ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL; + if (AR_SREV_9287(ah)) + ah->supp_cals &= ~ADC_GAIN_CAL; + if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) { INIT_CAL(&ah->adcgain_caldata); INSERT_CAL(ah, &ah->adcgain_caldata); ath_dbg(common, ATH_DBG_CALIBRATE, - "enabling ADC Gain Calibration.\n"); + "enabling ADC Gain Calibration.\n"); + } + if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) { INIT_CAL(&ah->adcdc_caldata); INSERT_CAL(ah, &ah->adcdc_caldata); ath_dbg(common, ATH_DBG_CALIBRATE, - "enabling ADC DC Calibration.\n"); + "enabling ADC DC Calibration.\n"); } - INIT_CAL(&ah->iq_caldata); - INSERT_CAL(ah, &ah->iq_caldata); - ath_dbg(common, ATH_DBG_CALIBRATE, - "enabling IQ Calibration.\n"); + if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) { + INIT_CAL(&ah->iq_caldata); + INSERT_CAL(ah, &ah->iq_caldata); + ath_dbg(common, ATH_DBG_CALIBRATE, + "enabling IQ Calibration.\n"); + } ah->cal_list_curr = ah->cal_list; -- GitLab From b0a9ede228175c25f76314a028d305fd5b2de427 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 15 Mar 2011 19:55:38 +0530 Subject: [PATCH 0131/5560] ath: Speedup key set/reset ops for HTC driver By enabling buffered register write for ath9k_htc driver avoids unnecessary dissociation while rekeying phase under heavy traffic exchange. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/key.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 37b8e115375a..0d4f39cbdcab 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -23,6 +23,14 @@ #define REG_READ (common->ops->read) #define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) +#define ENABLE_REGWRITE_BUFFER(_ah) \ + if (common->ops->enable_write_buffer) \ + common->ops->enable_write_buffer((_ah)); + +#define REGWRITE_BUFFER_FLUSH(_ah) \ + if (common->ops->write_flush) \ + common->ops->write_flush((_ah)); + #define IEEE80211_WEP_NKID 4 /* number of key ids */ @@ -42,6 +50,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); + ENABLE_REGWRITE_BUFFER(ah); + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); @@ -66,6 +76,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) } + REGWRITE_BUFFER_FLUSH(ah); + return true; } EXPORT_SYMBOL(ath_hw_keyreset); @@ -104,9 +116,13 @@ static bool ath_hw_keysetmac(struct ath_common *common, } else { macLo = macHi = 0; } + ENABLE_REGWRITE_BUFFER(ah); + REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); + REGWRITE_BUFFER_FLUSH(ah); + return true; } @@ -223,6 +239,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; mic4 = get_unaligned_le32(k->kv_txmic + 4); + ENABLE_REGWRITE_BUFFER(ah); + /* Write RX[31:0] and TX[31:16] */ REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); @@ -236,6 +254,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), AR_KEYTABLE_TYPE_CLR); + REGWRITE_BUFFER_FLUSH(ah); + } else { /* * TKIP uses four key cache entries (two for group @@ -258,6 +278,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, mic0 = get_unaligned_le32(k->kv_mic + 0); mic2 = get_unaligned_le32(k->kv_mic + 4); + ENABLE_REGWRITE_BUFFER(ah); + /* Write MIC key[31:0] */ REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); @@ -270,8 +292,12 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), AR_KEYTABLE_TYPE_CLR); + + REGWRITE_BUFFER_FLUSH(ah); } + ENABLE_REGWRITE_BUFFER(ah); + /* MAC address registers are reserved for the MIC entry */ REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); @@ -283,7 +309,11 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, */ REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); + + REGWRITE_BUFFER_FLUSH(ah); } else { + ENABLE_REGWRITE_BUFFER(ah); + /* Write key[47:0] */ REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); @@ -296,6 +326,8 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); + REGWRITE_BUFFER_FLUSH(ah); + /* Write MAC address for the entry */ (void) ath_hw_keysetmac(common, entry, mac); } -- GitLab From e7fc63388def06d2d1bdb6916748c92c037a42c6 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 15 Mar 2011 23:11:35 +0530 Subject: [PATCH 0132/5560] ath9k_hw: Speedup register ops for HTC driver Fine-tuning register write operation and avoid unnecessay delays for ath9k_htc driver, saves hw reset time which improves scanning time and also solves one of the following scenario. Sometimes the ACK is sent by STA for assoc response is not seen at AP side. So the AP continues to send retry assoc responses. At the STA side, since the assoc response was already forwarded to mac80211, it proceeded to channel change which in turns does chip reset. In most of the cases the chip reset was completed before max retries are reached at AP side. Hence STA can able to ACK the retried frames again. But in clear environment these retries are completed within shortspan of time. Since ath9k_htc consumes more time for hw reset, this latency is causing dissociation by AP due to max reties are reached. This issue was originally reported with Cisco Aironet 1250 AP in HT40 mode in noise free environment. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 7 +++++-- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 ++++++ drivers/net/wireless/ath/ath9k/eeprom_def.c | 7 +++++++ drivers/net/wireless/ath/ath9k/hw.h | 10 +++++++--- drivers/net/wireless/ath/ath9k/phy.h | 2 ++ 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ffcf44a4058b..94acce59f51d 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -729,6 +729,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); + struct ath_common *common = ath9k_hw_common(ah); int i, regWrites = 0; struct ieee80211_channel *channel = chan->chan; u32 modesIndex, freqIndex; @@ -805,7 +806,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REG_WRITE(ah, reg, val); if (reg >= 0x7800 && reg < 0x78a0 - && ah->config.analog_shiftreg) { + && ah->config.analog_shiftreg + && (common->bus_ops->ath_bus_type != ATH_USB)) { udelay(100); } @@ -835,7 +837,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REG_WRITE(ah, reg, val); if (reg >= 0x7800 && reg < 0x78a0 - && ah->config.analog_shiftreg) { + && ah->config.analog_shiftreg + && (common->bus_ops->ath_bus_type != ATH_USB)) { udelay(100); } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 8cd8333cc086..2f0712ea49a6 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -392,6 +392,8 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, numXpdGain); } + ENABLE_REGWRITE_BUFFER(ah); + if (i == 0) { if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { @@ -442,6 +444,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, regOffset += 4; } } + REGWRITE_BUFFER_FLUSH(ah); } } @@ -757,6 +760,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; } + ENABLE_REGWRITE_BUFFER(ah); + /* OFDM power per rate */ REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, ATH9K_POW_SM(ratesArray[rate18mb], 24) @@ -840,6 +845,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); } + REGWRITE_BUFFER_FLUSH(ah); } 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 fccd87df7300..995949ddd63e 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -799,6 +799,8 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, pwr_table_offset, &diff); + ENABLE_REGWRITE_BUFFER(ah); + if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { if (OLC_FOR_AR9280_20_LATER) { REG_WRITE(ah, @@ -847,6 +849,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, regOffset += 4; } + REGWRITE_BUFFER_FLUSH(ah); } } @@ -1205,6 +1208,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, } } + ENABLE_REGWRITE_BUFFER(ah); + REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, ATH9K_POW_SM(ratesArray[rate18mb], 24) | ATH9K_POW_SM(ratesArray[rate12mb], 16) @@ -1291,6 +1296,8 @@ 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)); + + REGWRITE_BUFFER_FLUSH(ah); } static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6650fd48415c..c86eea28a88f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -99,18 +99,22 @@ #define REG_CLR_BIT(_a, _r, _f) \ REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f)) -#define DO_DELAY(x) do { \ - if ((++(x) % 64) == 0) \ - udelay(1); \ +#define DO_DELAY(x) do { \ + if (((++(x) % 64) == 0) && \ + (ath9k_hw_common(ah)->bus_ops->ath_bus_type \ + != ATH_USB)) \ + udelay(1); \ } while (0) #define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ int r; \ + ENABLE_REGWRITE_BUFFER(ah); \ for (r = 0; r < ((iniarray)->ia_rows); r++) { \ REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ INI_RA((iniarray), r, (column))); \ DO_DELAY(regWr); \ } \ + REGWRITE_BUFFER_FLUSH(ah); \ } while (0) #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 5e3d7496986e..e4029325c787 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -40,10 +40,12 @@ #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ int r; \ + ENABLE_REGWRITE_BUFFER(ah); \ for (r = 0; r < ((iniarray)->ia_rows); r++) { \ REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \ DO_DELAY(regWr); \ } \ + REGWRITE_BUFFER_FLUSH(ah); \ } while (0) #define ANTSWAP_AB 0x0001 -- GitLab From c835b21405fa551cd5af2c7bfe1c3ae129c5f8ef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 15 Mar 2011 23:17:01 +0100 Subject: [PATCH 0133/5560] mac80211: add comment about reordering Took me a minute to figure this out, maybe it's better documented... Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5c1930ba8ebe..82414a636824 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -706,6 +706,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, /* * If the current MPDU is in the right order and nothing else * is stored we can process it directly, no need to buffer it. + * If it is first but there's something stored, we may be able + * to release frames after this one. */ if (mpdu_seq_num == tid_agg_rx->head_seq_num && tid_agg_rx->stored_mpdu_num == 0) { -- GitLab From 73b46320209e9fe0d65aba1b8c21489278047574 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Thu, 17 Mar 2011 11:58:41 -0700 Subject: [PATCH 0134/5560] mwl8k: refactor in preparation for APIv2 update Specifically, APIv2 will specify a variable number of AMPDU queues in the MWL8K_CMD_GET_HW_SPEC. So init the tx queues after MWL8K_CMD_GET_HW_SPEC for ap fw. Also, we make it safe to deinit queues that have not been init'd. This happens if the mwl8k_get_hw_spec_ap routine fails, for example. Signed-off-by: Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 51 +++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 36952274950e..8fefed2342d7 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -191,6 +191,7 @@ struct mwl8k_priv { struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; + u32 txq_offset[MWL8K_TX_QUEUES]; bool radio_on; bool radio_short_preamble; @@ -1126,6 +1127,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index) struct mwl8k_rx_queue *rxq = priv->rxq + index; int i; + if (rxq->rxd == NULL) + return; + for (i = 0; i < MWL8K_RX_DESCS; i++) { if (rxq->buf[i].skb != NULL) { pci_unmap_single(priv->pdev, @@ -1560,6 +1564,9 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) struct mwl8k_priv *priv = hw->priv; struct mwl8k_tx_queue *txq = priv->txq + index; + if (txq->txd == NULL) + return; + mwl8k_txq_reclaim(hw, index, INT_MAX, 1); kfree(txq->skb); @@ -2058,23 +2065,16 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) priv->ap_macids_supported = 0x000000ff; priv->sta_macids_supported = 0x00000000; - off = le32_to_cpu(cmd->wcbbase0) & 0xffff; - iowrite32(priv->txq[0].txd_dma, priv->sram + off); - off = le32_to_cpu(cmd->rxwrptr) & 0xffff; iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); off = le32_to_cpu(cmd->rxrdptr) & 0xffff; iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); - off = le32_to_cpu(cmd->wcbbase1) & 0xffff; - iowrite32(priv->txq[1].txd_dma, priv->sram + off); - - off = le32_to_cpu(cmd->wcbbase2) & 0xffff; - iowrite32(priv->txq[2].txd_dma, priv->sram + off); - - off = le32_to_cpu(cmd->wcbbase3) & 0xffff; - iowrite32(priv->txq[3].txd_dma, priv->sram + off); + priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff; + priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff; + priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff; + priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff; } done: @@ -4600,6 +4600,23 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image, return rc; } +static int mwl8k_init_txqs(struct ieee80211_hw *hw) +{ + struct mwl8k_priv *priv = hw->priv; + int rc = 0; + int i; + + for (i = 0; i < MWL8K_TX_QUEUES; i++) { + rc = mwl8k_txq_init(hw, i); + if (rc) + break; + if (priv->ap_fw) + iowrite32(priv->txq[i].txd_dma, + priv->sram + priv->txq_offset[i]); + } + return rc; +} + /* initialize hw after successfully loading a firmware image */ static int mwl8k_probe_hw(struct ieee80211_hw *hw) { @@ -4627,8 +4644,14 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) goto err_stop_firmware; rxq_refill(hw, 0, INT_MAX); - for (i = 0; i < MWL8K_TX_QUEUES; i++) { - rc = mwl8k_txq_init(hw, i); + /* For the sta firmware, we need to know the dma addresses of tx queues + * before sending MWL8K_CMD_GET_HW_SPEC. So we must initialize them + * prior to issuing this command. But for the AP case, we learn the + * total number of queues from the result CMD_GET_HW_SPEC, so for this + * case we must initialize the tx queues after. + */ + if (!priv->ap_fw) { + rc = mwl8k_init_txqs(hw); if (rc) goto err_free_queues; } @@ -4656,6 +4679,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) /* Get config data, mac addrs etc */ if (priv->ap_fw) { rc = mwl8k_cmd_get_hw_spec_ap(hw); + if (!rc) + rc = mwl8k_init_txqs(hw); if (!rc) rc = mwl8k_cmd_set_hw_spec(hw); } else { -- GitLab From 8a7a578c2e3ac463a17fe30b11ada0509658a952 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Thu, 17 Mar 2011 11:58:42 -0700 Subject: [PATCH 0135/5560] mwl8k: update to ap firmware API version 2 Firmware APIv2 adds the following enhancements: -- capabilities are reported by the firmware -- API supports up to 8 dedicated AMPDU streams -- optional packet timestamping and expiration can be enabled. Specifically, packets that are queued in firmware for longer than 500ms will be dropped if this option is used. Based on work by "Nishant Sarmukadam" Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 41 ++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 8fefed2342d7..9db66d58f0ef 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -86,6 +86,7 @@ MODULE_PARM_DESC(ap_mode_default, #define MWL8K_RX_QUEUES 1 #define MWL8K_TX_QUEUES 4 +#define MWL8K_MAX_AMPDU_QUEUES 8 struct rxd_ops { int rxd_size; @@ -159,6 +160,9 @@ struct mwl8k_priv { u32 ap_macids_supported; u32 sta_macids_supported; + /* Ampdu stream information */ + u8 num_ampdu_queues; + /* firmware access */ struct mutex fw_mutex; struct task_struct *fw_mutex_owner; @@ -190,8 +194,8 @@ struct mwl8k_priv { int pending_tx_pkts; struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; - struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; - u32 txq_offset[MWL8K_TX_QUEUES]; + struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES + MWL8K_MAX_AMPDU_QUEUES]; + u32 txq_offset[MWL8K_TX_QUEUES + MWL8K_MAX_AMPDU_QUEUES]; bool radio_on; bool radio_short_preamble; @@ -1322,7 +1326,7 @@ struct mwl8k_tx_desc { __le16 pkt_len; __u8 dest_MAC_addr[ETH_ALEN]; __le32 next_txd_phys_addr; - __le32 reserved; + __le32 timestamp; __le16 rate_info; __u8 peer_id; __u8 tx_frag_cnt; @@ -2023,13 +2027,16 @@ struct mwl8k_cmd_get_hw_spec_ap { __le32 wcbbase2; __le32 wcbbase3; __le32 fw_api_version; + __le32 caps; + __le32 num_of_ampdu_queues; + __le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES]; } __packed; 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; + int rc, i; u32 api_version; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); @@ -2061,10 +2068,17 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); priv->fw_rev = le32_to_cpu(cmd->fw_rev); priv->hw_rev = cmd->hw_rev; - mwl8k_setup_2ghz_band(hw); + mwl8k_set_caps(hw, le32_to_cpu(cmd->caps)); priv->ap_macids_supported = 0x000000ff; priv->sta_macids_supported = 0x00000000; - + priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues); + if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) { + wiphy_warn(hw->wiphy, "fw reported %d ampdu queues" + " but we only support %d.\n", + priv->num_ampdu_queues, + MWL8K_MAX_AMPDU_QUEUES); + priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES; + } off = le32_to_cpu(cmd->rxwrptr) & 0xffff; iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); @@ -2075,6 +2089,10 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff; priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff; priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff; + + for (i = 0; i < priv->num_ampdu_queues; i++) + priv->txq_offset[i + MWL8K_TX_QUEUES] = + le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff; } done: @@ -2103,6 +2121,14 @@ struct mwl8k_cmd_set_hw_spec { __le32 total_rxd; } __packed; +/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause + * packets to expire 500 ms after the timestamp in the tx descriptor. That is, + * the packets that are queued for more than 500ms, will be dropped in the + * hardware. This helps minimizing the issues caused due to head-of-line + * blocking where a slow client can hog the bandwidth and affect traffic to a + * faster client. + */ +#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400 #define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 @@ -4434,7 +4460,7 @@ enum { MWL8366, }; -#define MWL8K_8366_AP_FW_API 1 +#define MWL8K_8366_AP_FW_API 2 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) @@ -4650,6 +4676,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) * total number of queues from the result CMD_GET_HW_SPEC, so for this * case we must initialize the tx queues after. */ + priv->num_ampdu_queues = 0; if (!priv->ap_fw) { rc = mwl8k_init_txqs(hw); if (rc) -- GitLab From 5faa1aff08ef8d82b98ac2dfd7beb62ae6eda5e5 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Mar 2011 11:58:43 -0700 Subject: [PATCH 0136/5560] mwl8k: add support for block ack commands Signed-off-by: Pradeep Nemavat Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 156 +++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 9db66d58f0ef..944ad030e4dd 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -135,6 +135,14 @@ struct mwl8k_tx_queue { struct sk_buff **skb; }; +struct mwl8k_ampdu_stream { + struct ieee80211_sta *sta; + u8 tid; + u8 state; + u8 idx; + u8 txq_idx; /* index of this stream in priv->txq */ +}; + struct mwl8k_priv { struct ieee80211_hw *hw; struct pci_dev *pdev; @@ -360,6 +368,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ #define MWL8K_CMD_UPDATE_STADB 0x1123 +#define MWL8K_CMD_BASTREAM 0x1125 static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) { @@ -399,6 +408,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) MWL8K_CMDNAME(SET_NEW_STN); MWL8K_CMDNAME(UPDATE_ENCRYPTION); MWL8K_CMDNAME(UPDATE_STADB); + MWL8K_CMDNAME(BASTREAM); default: snprintf(buf, bufsize, "0x%x", cmd); } @@ -3175,6 +3185,152 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, return rc; } +/* + * CMD_BASTREAM. + */ + +/* + * UPSTREAM is tx direction + */ +#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 +#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 + +enum { + MWL8K_BA_CREATE, + MWL8K_BA_UPDATE, + MWL8K_BA_DESTROY, + MWL8K_BA_FLUSH, + MWL8K_BA_CHECK, +} ba_stream_action_type; + + +struct mwl8k_create_ba_stream { + __le32 flags; + __le32 idle_thrs; + __le32 bar_thrs; + __le32 window_size; + u8 peer_mac_addr[6]; + u8 dialog_token; + u8 tid; + u8 queue_id; + u8 param_info; + __le32 ba_context; + u8 reset_seq_no_flag; + __le16 curr_seq_no; + u8 sta_src_mac_addr[6]; +} __packed; + +struct mwl8k_destroy_ba_stream { + __le32 flags; + __le32 ba_context; +} __packed; + +struct mwl8k_cmd_bastream { + struct mwl8k_cmd_pkt header; + __le32 action; + union { + struct mwl8k_create_ba_stream create_params; + struct mwl8k_destroy_ba_stream destroy_params; + }; +} __packed; + +static int +mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) +{ + struct mwl8k_cmd_bastream *cmd; + int rc; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + + cmd->action = cpu_to_le32(MWL8K_BA_CHECK); + + cmd->create_params.queue_id = stream->idx; + memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr, + ETH_ALEN); + cmd->create_params.tid = stream->tid; + + cmd->create_params.flags = + cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) | + cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM); + + rc = mwl8k_post_cmd(hw, &cmd->header); + + kfree(cmd); + + return rc; +} + +static int +mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, + u8 buf_size) +{ + struct mwl8k_cmd_bastream *cmd; + int rc; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + + cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + + cmd->action = cpu_to_le32(MWL8K_BA_CREATE); + + cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size); + cmd->create_params.window_size = cpu_to_le32((u32)buf_size); + cmd->create_params.queue_id = stream->idx; + + memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN); + cmd->create_params.tid = stream->tid; + cmd->create_params.curr_seq_no = cpu_to_le16(0); + cmd->create_params.reset_seq_no_flag = 1; + + cmd->create_params.param_info = + (stream->sta->ht_cap.ampdu_factor & + IEEE80211_HT_AMPDU_PARM_FACTOR) | + ((stream->sta->ht_cap.ampdu_density << 2) & + IEEE80211_HT_AMPDU_PARM_DENSITY); + + cmd->create_params.flags = + cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE | + BASTREAM_FLAG_DIRECTION_UPSTREAM); + + rc = mwl8k_post_cmd(hw, &cmd->header); + + wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", + stream->sta->addr, stream->tid); + kfree(cmd); + + return rc; +} + +static void mwl8k_destroy_ba(struct ieee80211_hw *hw, + struct mwl8k_ampdu_stream *stream) +{ + struct mwl8k_cmd_bastream *cmd; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + cmd->action = cpu_to_le32(MWL8K_BA_DESTROY); + + cmd->destroy_params.ba_context = cpu_to_le32(stream->idx); + mwl8k_post_cmd(hw, &cmd->header); + + wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx); + + kfree(cmd); +} + /* * CMD_SET_NEW_STN. */ -- GitLab From e600707b021efdc109e7becd467798da339ec26d Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Thu, 17 Mar 2011 11:58:44 -0700 Subject: [PATCH 0137/5560] mwl8k: differentiate between WMM queues and AMPDU queues We now have two different kinds of queues. And the number of AMPDU queues may vary. So we must be clear about which queues we are dealing with. Note that when we report the number of queues to mac80211, we only report the WMM queues. Based on work by Yogesh Powar . Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 52 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 944ad030e4dd..53581ee8b79f 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -85,8 +85,10 @@ MODULE_PARM_DESC(ap_mode_default, MWL8K_A2H_INT_TX_DONE) #define MWL8K_RX_QUEUES 1 -#define MWL8K_TX_QUEUES 4 +#define MWL8K_TX_WMM_QUEUES 4 #define MWL8K_MAX_AMPDU_QUEUES 8 +#define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES) +#define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues) struct rxd_ops { int rxd_size; @@ -202,8 +204,8 @@ struct mwl8k_priv { int pending_tx_pkts; struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; - struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES + MWL8K_MAX_AMPDU_QUEUES]; - u32 txq_offset[MWL8K_TX_QUEUES + MWL8K_MAX_AMPDU_QUEUES]; + struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES]; + u32 txq_offset[MWL8K_MAX_TX_QUEUES]; bool radio_on; bool radio_short_preamble; @@ -236,7 +238,7 @@ struct mwl8k_priv { * 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]; + struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES]; /* async firmware loading state */ unsigned fw_state; @@ -1400,7 +1402,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw) struct mwl8k_priv *priv = hw->priv; int i; - for (i = 0; i < MWL8K_TX_QUEUES; i++) { + for (i = 0; i < mwl8k_tx_queues(priv); i++) { struct mwl8k_tx_queue *txq = priv->txq + i; int fw_owned = 0; int drv_owned = 0; @@ -1888,7 +1890,7 @@ struct mwl8k_cmd_get_hw_spec_sta { __u8 mcs_bitmap[16]; __le32 rx_queue_ptr; __le32 num_tx_queues; - __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; + __le32 tx_queue_ptrs[MWL8K_TX_WMM_QUEUES]; __le32 caps2; __le32 num_tx_desc_per_queue; __le32 total_rxd; @@ -1994,8 +1996,8 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); - cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); - for (i = 0; i < MWL8K_TX_QUEUES; i++) + cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv)); + for (i = 0; i < mwl8k_tx_queues(priv); i++) cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); @@ -2101,7 +2103,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff; for (i = 0; i < priv->num_ampdu_queues; i++) - priv->txq_offset[i + MWL8K_TX_QUEUES] = + priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] = le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff; } @@ -2125,7 +2127,7 @@ struct mwl8k_cmd_set_hw_spec { __le32 caps; __le32 rx_queue_ptr; __le32 num_tx_queues; - __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; + __le32 tx_queue_ptrs[MWL8K_MAX_TX_QUEUES]; __le32 flags; __le32 num_tx_desc_per_queue; __le32 total_rxd; @@ -2159,7 +2161,7 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); - cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); + cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv)); /* * Mac80211 stack has Q0 as highest priority and Q3 as lowest in @@ -2167,8 +2169,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) * in that order. Map Q3 of mac80211 to Q0 of firmware so that the * priority is interpreted the right way in firmware. */ - for (i = 0; i < MWL8K_TX_QUEUES; i++) { - int j = MWL8K_TX_QUEUES - 1 - i; + for (i = 0; i < mwl8k_tx_queues(priv); i++) { + int j = mwl8k_tx_queues(priv) - 1 - i; cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma); } @@ -3880,7 +3882,7 @@ static void mwl8k_tx_poll(unsigned long data) spin_lock_bh(&priv->tx_lock); - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) limit -= mwl8k_txq_reclaim(hw, i, limit, 0); if (!priv->pending_tx_pkts && priv->tx_wait != NULL) { @@ -4012,7 +4014,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw) tasklet_disable(&priv->poll_rx_task); /* Return all skbs to mac80211 */ - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_reclaim(hw, i, INT_MAX, 1); } @@ -4510,14 +4512,14 @@ 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); + BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1); memcpy(&priv->wmm_params[queue], params, sizeof(*params)); if (!priv->wmm_enabled) rc = mwl8k_cmd_set_wmm_mode(hw, 1); if (!rc) { - int q = MWL8K_TX_QUEUES - 1 - queue; + int q = MWL8K_TX_WMM_QUEUES - 1 - queue; rc = mwl8k_cmd_set_edca_params(hw, q, params->cw_min, params->cw_max, @@ -4788,7 +4790,7 @@ static int mwl8k_init_txqs(struct ieee80211_hw *hw) int rc = 0; int i; - for (i = 0; i < MWL8K_TX_QUEUES; i++) { + for (i = 0; i < mwl8k_tx_queues(priv); i++) { rc = mwl8k_txq_init(hw, i); if (rc) break; @@ -4906,7 +4908,7 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) free_irq(priv->pdev->irq, hw); err_free_queues: - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_deinit(hw, i); mwl8k_rxq_deinit(hw, 0); @@ -4928,7 +4930,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) mwl8k_stop(hw); mwl8k_rxq_deinit(hw, 0); - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_deinit(hw, i); rc = mwl8k_init_firmware(hw, fw_image, false); @@ -4947,7 +4949,7 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) if (rc) goto fail; - for (i = 0; i < MWL8K_TX_QUEUES; i++) { + for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) { rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]); if (rc) goto fail; @@ -4981,7 +4983,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) hw->channel_change_time = 10; - hw->queues = MWL8K_TX_QUEUES; + hw->queues = MWL8K_TX_WMM_QUEUES; /* Set rssi values to dBm */ hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; @@ -5037,7 +5039,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) return 0; err_unprobe_hw: - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_deinit(hw, i); mwl8k_rxq_deinit(hw, 0); @@ -5196,10 +5198,10 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev) mwl8k_hw_reset(priv); /* Return all skbs to mac80211 */ - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_reclaim(hw, i, INT_MAX, 1); - for (i = 0; i < MWL8K_TX_QUEUES; i++) + for (i = 0; i < mwl8k_tx_queues(priv); i++) mwl8k_txq_deinit(hw, i); mwl8k_rxq_deinit(hw, 0); -- GitLab From ac109fd0427008e5b55e0e52e59c364de6d686fe Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Thu, 17 Mar 2011 11:58:45 -0700 Subject: [PATCH 0138/5560] mwl8k: add internal API for managing AMPDU streams In particular, we can now add, start, lookup, and remove streams. Based on work by Nishant Sarmukadam and Pradeep Nemavat . 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 | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 53581ee8b79f..dcd4508b1fd4 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -137,6 +137,13 @@ struct mwl8k_tx_queue { struct sk_buff **skb; }; +enum { + AMPDU_NO_STREAM, + AMPDU_STREAM_NEW, + AMPDU_STREAM_IN_PROGRESS, + AMPDU_STREAM_ACTIVE, +}; + struct mwl8k_ampdu_stream { struct ieee80211_sta *sta; u8 tid; @@ -172,6 +179,8 @@ struct mwl8k_priv { /* Ampdu stream information */ u8 num_ampdu_queues; + spinlock_t stream_lock; + struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES]; /* firmware access */ struct mutex fw_mutex; @@ -1594,6 +1603,74 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) txq->txd = NULL; } +/* caller must hold priv->stream_lock when calling the stream functions */ +struct mwl8k_ampdu_stream * +mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) +{ + struct mwl8k_ampdu_stream *stream; + struct mwl8k_priv *priv = hw->priv; + int i; + + for (i = 0; i < priv->num_ampdu_queues; i++) { + stream = &priv->ampdu[i]; + if (stream->state == AMPDU_NO_STREAM) { + stream->sta = sta; + stream->state = AMPDU_STREAM_NEW; + stream->tid = tid; + stream->idx = i; + stream->txq_idx = MWL8K_TX_WMM_QUEUES + i; + wiphy_debug(hw->wiphy, "Added a new stream for %pM %d", + sta->addr, tid); + return stream; + } + } + return NULL; +} + +static int +mwl8k_start_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) +{ + int ret; + + /* if the stream has already been started, don't start it again */ + if (stream->state != AMPDU_STREAM_NEW) + return 0; + ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0); + if (ret) + wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: " + "%d\n", stream->sta->addr, stream->tid, ret); + else + wiphy_debug(hw->wiphy, "Started stream for %pM %d\n", + stream->sta->addr, stream->tid); + return ret; +} + +static void +mwl8k_remove_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) +{ + wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr, + stream->tid); + memset(stream, 0, sizeof(*stream)); +} + +static struct mwl8k_ampdu_stream * +mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) +{ + struct mwl8k_priv *priv = hw->priv; + int i; + + for (i = 0 ; i < priv->num_ampdu_queues; i++) { + struct mwl8k_ampdu_stream *stream; + stream = &priv->ampdu[i]; + if (stream->state == AMPDU_NO_STREAM) + continue; + if (!memcmp(stream->sta->addr, addr, ETH_ALEN) && + stream->tid == tid) + return stream; + } + return NULL; +} + static void mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) { @@ -4854,6 +4931,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) goto err_free_queues; } + memset(priv->ampdu, 0, sizeof(priv->ampdu)); + /* * Temporarily enable interrupts. Initial firmware host * commands use interrupts and avoid polling. Disable @@ -5018,6 +5097,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) spin_lock_init(&priv->tx_lock); + spin_lock_init(&priv->stream_lock); + priv->tx_wait = NULL; rc = mwl8k_probe_hw(hw); -- GitLab From 65f3ddcd08fe24490359274a8c9bf526e81357a5 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Mar 2011 11:58:46 -0700 Subject: [PATCH 0139/5560] mwl8k: Initiate BA sessions Specifically, handle ampdu_action and attempt to start a BA session on receiving the first qos packet from mac80211 for transmission to a HT sta. While the BA session is being created, all the packets belonging to that stream will be dropped to prevent sequence number mismatch at the recipient. Contains contributions from: Yogesh Powar Pradeep Nemavat Brian Cavagnolo Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 194 +++++++++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index dcd4508b1fd4..ec1190ab0f8e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1577,7 +1577,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) processed++; } - if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) + if (index < MWL8K_TX_WMM_QUEUES && processed && priv->radio_on && + !mutex_is_locked(&priv->fw_mutex)) ieee80211_wake_queue(hw, index); return processed; @@ -1677,6 +1678,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) struct mwl8k_priv *priv = hw->priv; struct ieee80211_tx_info *tx_info; struct mwl8k_vif *mwl8k_vif; + struct ieee80211_sta *sta; struct ieee80211_hdr *wh; struct mwl8k_tx_queue *txq; struct mwl8k_tx_desc *tx; @@ -1684,6 +1686,10 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) u32 txstatus; u8 txdatarate; u16 qos; + int txpriority; + u8 tid = 0; + struct mwl8k_ampdu_stream *stream = NULL; + bool start_ba_session = false; wh = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(wh->frame_control)) @@ -1699,6 +1705,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) wh = &((struct mwl8k_dma_data *)skb->data)->wh; tx_info = IEEE80211_SKB_CB(skb); + sta = tx_info->control.sta; mwl8k_vif = MWL8K_VIF(tx_info->control.vif); if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { @@ -1726,12 +1733,70 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) qos |= MWL8K_QOS_ACK_POLICY_NORMAL; } + txpriority = index; + + if (ieee80211_is_data_qos(wh->frame_control) && + skb->protocol != cpu_to_be16(ETH_P_PAE) && + sta->ht_cap.ht_supported && priv->ap_fw) { + tid = qos & 0xf; + spin_lock(&priv->stream_lock); + stream = mwl8k_lookup_stream(hw, sta->addr, tid); + if (stream != NULL) { + if (stream->state == AMPDU_STREAM_ACTIVE) { + txpriority = stream->txq_idx; + index = stream->txq_idx; + } else if (stream->state == AMPDU_STREAM_NEW) { + /* We get here if the driver sends us packets + * after we've initiated a stream, but before + * our ampdu_action routine has been called + * with IEEE80211_AMPDU_TX_START to get the SSN + * for the ADDBA request. So this packet can + * go out with no risk of sequence number + * mismatch. No special handling is required. + */ + } else { + /* Drop packets that would go out after the + * ADDBA request was sent but before the ADDBA + * response is received. If we don't do this, + * the recipient would probably receive it + * after the ADDBA request with SSN 0. This + * will cause the recipient's BA receive window + * to shift, which would cause the subsequent + * packets in the BA stream to be discarded. + * mac80211 queues our packets for us in this + * case, so this is really just a safety check. + */ + wiphy_warn(hw->wiphy, + "Cannot send packet while ADDBA " + "dialog is underway.\n"); + spin_unlock(&priv->stream_lock); + dev_kfree_skb(skb); + return; + } + } else { + /* Defer calling mwl8k_start_stream so that the current + * skb can go out before the ADDBA request. This + * prevents sequence number mismatch at the recepient + * as described above. + */ + stream = mwl8k_add_stream(hw, sta, tid); + if (stream != NULL) + start_ba_session = true; + } + spin_unlock(&priv->stream_lock); + } + dma = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(priv->pdev, dma)) { wiphy_debug(hw->wiphy, "failed to dma map skb, dropping TX frame.\n"); + if (start_ba_session) { + spin_lock(&priv->stream_lock); + mwl8k_remove_stream(hw, stream); + spin_unlock(&priv->stream_lock); + } dev_kfree_skb(skb); return; } @@ -1740,12 +1805,22 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) txq = priv->txq + index; + if (index >= MWL8K_TX_WMM_QUEUES && txq->len >= MWL8K_TX_DESCS) { + /* This is the case in which the tx packet is destined for an + * AMPDU queue and that AMPDU queue is full. Because we don't + * start and stop the AMPDU queues, we must drop these packets. + */ + dev_kfree_skb(skb); + spin_unlock_bh(&priv->tx_lock); + return; + } + BUG_ON(txq->skb[txq->tail] != NULL); txq->skb[txq->tail] = skb; tx = txq->txd + txq->tail; tx->data_rate = txdatarate; - tx->tx_priority = index; + tx->tx_priority = txpriority; tx->qos_control = cpu_to_le16(qos); tx->pkt_phys_addr = cpu_to_le32(dma); tx->pkt_len = cpu_to_le16(skb->len); @@ -1764,12 +1839,20 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) if (txq->tail == MWL8K_TX_DESCS) txq->tail = 0; - if (txq->head == txq->tail) + if (txq->head == txq->tail && index < MWL8K_TX_WMM_QUEUES) ieee80211_stop_queue(hw, index); mwl8k_tx_start(priv); spin_unlock_bh(&priv->tx_lock); + + /* Initiate the ampdu session here */ + if (start_ba_session) { + spin_lock(&priv->stream_lock); + if (mwl8k_start_stream(hw, stream)) + mwl8k_remove_stream(hw, stream); + spin_unlock(&priv->stream_lock); + } } @@ -4632,21 +4715,118 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, return 0; } +#define MAX_AMPDU_ATTEMPTS 5 + static int mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { + + int i, rc = 0; + struct mwl8k_priv *priv = hw->priv; + struct mwl8k_ampdu_stream *stream; + u8 *addr = sta->addr; + + if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) + return -ENOTSUPP; + + spin_lock(&priv->stream_lock); + stream = mwl8k_lookup_stream(hw, addr, tid); + switch (action) { case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_STOP: - if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) - return -ENOTSUPP; - return 0; + break; + case IEEE80211_AMPDU_TX_START: + /* By the time we get here the hw queues may contain outgoing + * packets for this RA/TID that are not part of this BA + * session. The hw will assign sequence numbers to these + * packets as they go out. So if we query the hw for its next + * sequence number and use that for the SSN here, it may end up + * being wrong, which will lead to sequence number mismatch at + * the recipient. To avoid this, we reset the sequence number + * to O for the first MPDU in this BA stream. + */ + *ssn = 0; + if (stream == NULL) { + /* This means that somebody outside this driver called + * ieee80211_start_tx_ba_session. This is unexpected + * because we do our own rate control. Just warn and + * move on. + */ + wiphy_warn(hw->wiphy, "Unexpected call to %s. " + "Proceeding anyway.\n", __func__); + stream = mwl8k_add_stream(hw, sta, tid); + } + if (stream == NULL) { + wiphy_debug(hw->wiphy, "no free AMPDU streams\n"); + rc = -EBUSY; + break; + } + stream->state = AMPDU_STREAM_IN_PROGRESS; + + /* Release the lock before we do the time consuming stuff */ + spin_unlock(&priv->stream_lock); + for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { + rc = mwl8k_check_ba(hw, stream); + + if (!rc) + break; + /* + * HW queues take time to be flushed, give them + * sufficient time + */ + + msleep(1000); + } + spin_lock(&priv->stream_lock); + if (rc) { + wiphy_err(hw->wiphy, "Stream for tid %d busy after %d" + " attempts\n", tid, MAX_AMPDU_ATTEMPTS); + mwl8k_remove_stream(hw, stream); + rc = -EBUSY; + break; + } + ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); + break; + case IEEE80211_AMPDU_TX_STOP: + if (stream == NULL) + break; + if (stream->state == AMPDU_STREAM_ACTIVE) { + spin_unlock(&priv->stream_lock); + mwl8k_destroy_ba(hw, stream); + spin_lock(&priv->stream_lock); + } + mwl8k_remove_stream(hw, stream); + ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + BUG_ON(stream == NULL); + BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); + spin_unlock(&priv->stream_lock); + rc = mwl8k_create_ba(hw, stream, buf_size); + spin_lock(&priv->stream_lock); + if (!rc) + stream->state = AMPDU_STREAM_ACTIVE; + else { + spin_unlock(&priv->stream_lock); + mwl8k_destroy_ba(hw, stream); + spin_lock(&priv->stream_lock); + wiphy_debug(hw->wiphy, + "Failed adding stream for sta %pM tid %d\n", + addr, tid); + mwl8k_remove_stream(hw, stream); + } + break; + default: - return -ENOTSUPP; + rc = -ENOTSUPP; } + + spin_unlock(&priv->stream_lock); + return rc; } static const struct ieee80211_ops mwl8k_ops = { -- GitLab From 3aefc37ee789188f0d4488cae04ff618f4c4ddf6 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Mar 2011 11:58:47 -0700 Subject: [PATCH 0140/5560] mwl8k: Handle the watchdog event from the firmware When an ampdu stream is on, if the firmware rate adaptation logic decides that the outgoing packet rate to the station needs to go below 6.5Mbps (non HT rate), it sends an event indicating that the ampdu stream needs to be destroyed. Handle this event in the driver and destroy the ampdu stream so that the rate can go below 6.5Mbps Signed-off-by: Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 77 +++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index ec1190ab0f8e..b90178da5a27 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -63,6 +63,7 @@ MODULE_PARM_DESC(ap_mode_default, #define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38 #define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c #define MWL8K_A2H_INT_DUMMY (1 << 20) +#define MWL8K_A2H_INT_BA_WATCHDOG (1 << 14) #define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11) #define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10) #define MWL8K_A2H_INT_RADAR_DETECT (1 << 7) @@ -82,7 +83,8 @@ MODULE_PARM_DESC(ap_mode_default, MWL8K_A2H_INT_MAC_EVENT | \ MWL8K_A2H_INT_OPC_DONE | \ MWL8K_A2H_INT_RX_READY | \ - MWL8K_A2H_INT_TX_DONE) + MWL8K_A2H_INT_TX_DONE | \ + MWL8K_A2H_INT_BA_WATCHDOG) #define MWL8K_RX_QUEUES 1 #define MWL8K_TX_WMM_QUEUES 4 @@ -181,6 +183,7 @@ struct mwl8k_priv { u8 num_ampdu_queues; spinlock_t stream_lock; struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES]; + struct work_struct watchdog_ba_handle; /* firmware access */ struct mutex fw_mutex; @@ -375,6 +378,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_ENABLE_SNIFFER 0x0150 #define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */ #define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 +#define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205 #define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ @@ -420,6 +424,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) MWL8K_CMDNAME(UPDATE_ENCRYPTION); MWL8K_CMDNAME(UPDATE_STADB); MWL8K_CMDNAME(BASTREAM); + MWL8K_CMDNAME(GET_WATCHDOG_BITMAP); default: snprintf(buf, bufsize, "0x%x", cmd); } @@ -3319,6 +3324,65 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode) return rc; } +/* + * CMD_GET_WATCHDOG_BITMAP. + */ +struct mwl8k_cmd_get_watchdog_bitmap { + struct mwl8k_cmd_pkt header; + u8 bitmap; +} __packed; + +static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap) +{ + struct mwl8k_cmd_get_watchdog_bitmap *cmd; + int rc; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + + rc = mwl8k_post_cmd(hw, &cmd->header); + if (!rc) + *bitmap = cmd->bitmap; + + kfree(cmd); + + return rc; +} + +#define INVALID_BA 0xAA +static void mwl8k_watchdog_ba_events(struct work_struct *work) +{ + int rc; + u8 bitmap = 0, stream_index; + struct mwl8k_ampdu_stream *streams; + struct mwl8k_priv *priv = + container_of(work, struct mwl8k_priv, watchdog_ba_handle); + + rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap); + if (rc) + return; + + if (bitmap == INVALID_BA) + return; + + /* the bitmap is the hw queue number. Map it to the ampdu queue. */ + stream_index = bitmap - MWL8K_TX_WMM_QUEUES; + + BUG_ON(stream_index >= priv->num_ampdu_queues); + + streams = &priv->ampdu[stream_index]; + + if (streams->state == AMPDU_STREAM_ACTIVE) + ieee80211_stop_tx_ba_session(streams->sta, streams->tid); + + return; +} + + /* * CMD_BSS_START. */ @@ -4014,6 +4078,11 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id) tasklet_schedule(&priv->poll_rx_task); } + if (status & MWL8K_A2H_INT_BA_WATCHDOG) { + status &= ~MWL8K_A2H_INT_BA_WATCHDOG; + ieee80211_queue_work(hw, &priv->watchdog_ba_handle); + } + if (status) iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); @@ -4166,6 +4235,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw) /* Stop finalize join worker */ cancel_work_sync(&priv->finalize_join_worker); + cancel_work_sync(&priv->watchdog_ba_handle); if (priv->beacon_skb != NULL) dev_kfree_skb(priv->beacon_skb); @@ -5100,7 +5170,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); - iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY, + iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| + MWL8K_A2H_INT_BA_WATCHDOG, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); @@ -5258,6 +5329,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) /* Finalize join worker */ INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); + /* Handle watchdog ba events */ + INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events); /* TX reclaim and RX tasklets. */ tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); -- GitLab From 170335432ad36584a6d24fc1fd903024d221ef55 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Mar 2011 11:58:48 -0700 Subject: [PATCH 0141/5560] mwl8k: Check outgoing rate for a station to decide if ampdu can be created If the outgoing packet rate to a particular HT station is <=6.5 Mbps, do not attempt to create an ampdu. Also, if the outgoing rate is legacy rate, do not create an ampdu. Signed-off-by: Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 60 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index b90178da5a27..5473f4ca0ca0 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -291,6 +291,7 @@ struct mwl8k_vif { struct mwl8k_sta { /* Index into station database. Returned by UPDATE_STADB. */ u8 peer_id; + u8 is_ampdu_allowed; }; #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) @@ -1517,6 +1518,27 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) MWL8K_TXD_STATUS_OK_RETRY | \ MWL8K_TXD_STATUS_OK_MORE_RETRY)) +/* The firmware will fill in the rate information + * for each packet that gets queued in the hardware + * in this structure + */ + +struct rateinfo { + __le16 format:1; + __le16 short_gi:1; + __le16 band_width:1; + __le16 rate_id_mcs:6; + __le16 adv_coding:2; + __le16 antenna:2; + __le16 act_sub_chan:2; + __le16 preamble_type:1; + __le16 power_id:4; + __le16 antenna2:1; + __le16 reserved:1; + __le16 tx_bf_frame:1; + __le16 green_field:1; +} __packed; + static int mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) { @@ -1533,6 +1555,11 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) struct sk_buff *skb; struct ieee80211_tx_info *info; u32 status; + struct ieee80211_sta *sta; + struct mwl8k_sta *sta_info = NULL; + u16 rate_info; + struct rateinfo *rate; + struct ieee80211_hdr *wh; tx = txq->head; tx_desc = txq->txd + tx; @@ -1561,11 +1588,34 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) mwl8k_remove_dma_header(skb, tx_desc->qos_control); + wh = (struct ieee80211_hdr *) skb->data; + /* Mark descriptor as unused */ tx_desc->pkt_phys_addr = 0; tx_desc->pkt_len = 0; info = IEEE80211_SKB_CB(skb); + if (ieee80211_is_data(wh->frame_control)) { + sta = info->control.sta; + if (sta) { + sta_info = MWL8K_STA(sta); + BUG_ON(sta_info == NULL); + rate_info = le16_to_cpu(tx_desc->rate_info); + rate = (struct rateinfo *)&rate_info; + /* If rate is < 6.5 Mpbs for an ht station + * do not form an ampdu. If the station is a + * legacy station (format = 0), do not form an + * ampdu + */ + if (rate->rate_id_mcs < 1 || + rate->format == 0) { + sta_info->is_ampdu_allowed = false; + } else { + sta_info->is_ampdu_allowed = true; + } + } + } + ieee80211_tx_info_clear_status(info); /* Rate control is happening in the firmware. @@ -1784,9 +1834,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) * prevents sequence number mismatch at the recepient * as described above. */ - stream = mwl8k_add_stream(hw, sta, tid); - if (stream != NULL) - start_ba_session = true; + if (MWL8K_STA(sta)->is_ampdu_allowed) { + stream = mwl8k_add_stream(hw, sta, tid); + if (stream != NULL) + start_ba_session = true; + } } spin_unlock(&priv->stream_lock); } @@ -4719,6 +4771,8 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw, ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); if (ret >= 0) { MWL8K_STA(sta)->peer_id = ret; + if (sta->ht_cap.ht_supported) + MWL8K_STA(sta)->is_ampdu_allowed = true; ret = 0; } -- GitLab From a0e7c6cfe2a04af450274638845802b5c384e8df Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Mar 2011 11:58:49 -0700 Subject: [PATCH 0142/5560] mwl8k: Queue ADDBA requests in respective data queues Queue ADDBA requests in respective data queues to avoid ADDBA requests and the the related data packets (to the same ra/tid) queued in the hardware to be sent out asynchronously. Signed-off-by: Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 5473f4ca0ca0..ae56d2f32b2e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1518,6 +1518,33 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) MWL8K_TXD_STATUS_OK_RETRY | \ MWL8K_TXD_STATUS_OK_MORE_RETRY)) +static int mwl8k_tid_queue_mapping(u8 tid) +{ + BUG_ON(tid > 7); + + switch (tid) { + case 0: + case 3: + return IEEE80211_AC_BE; + break; + case 1: + case 2: + return IEEE80211_AC_BK; + break; + case 4: + case 5: + return IEEE80211_AC_VI; + break; + case 6: + case 7: + return IEEE80211_AC_VO; + break; + default: + return -1; + break; + } +} + /* The firmware will fill in the rate information * for each packet that gets queued in the hardware * in this structure @@ -1745,6 +1772,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) u8 tid = 0; struct mwl8k_ampdu_stream *stream = NULL; bool start_ba_session = false; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; wh = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(wh->frame_control)) @@ -1788,6 +1816,24 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) qos |= MWL8K_QOS_ACK_POLICY_NORMAL; } + /* Queue ADDBA request in the respective data queue. While setting up + * the ampdu stream, mac80211 queues further packets for that + * particular ra/tid pair. However, packets piled up in the hardware + * for that ra/tid pair will still go out. ADDBA request and the + * related data packets going out from different queues asynchronously + * will cause a shift in the receiver window which might result in + * ampdu packets getting dropped at the receiver after the stream has + * been setup. + */ + if (unlikely(ieee80211_is_action(wh->frame_control) && + mgmt->u.action.category == WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ && + priv->ap_fw)) { + u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); + tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; + index = mwl8k_tid_queue_mapping(tid); + } + txpriority = index; if (ieee80211_is_data_qos(wh->frame_control) && -- GitLab From 716b1bf3c5040f2303d6d1d0dfee6d8851cedc9d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 17 Mar 2011 21:53:01 -0500 Subject: [PATCH 0143/5560] rtlwifi: rtl8192c{e,u}: Remove some extraneous casts on memcpy commands Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index 803adcc80c96..b0b0b13dd0ae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -532,9 +532,9 @@ #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); \ + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ else \ - memset((void *)__pdesc, 0, _size); \ + memset(__pdesc, 0, _size); \ } while (0); #define RX_HAL_IS_CCK_RATE(_pdesc)\ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index d0b0d43b9a6d..3f0cb81c424f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -656,7 +656,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); __le16 fc = hdr->frame_control; - memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); + memset(pdesc, 0, RTL_TX_HEADER_SIZE); if (firstseg) SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); -- GitLab From c70cab1a45d56395db03957f6504c6b613bece5b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:37 +0100 Subject: [PATCH 0144/5560] ath9k: remove unnecessary debugfs return code checks Since the ath9k debugfs directory is cleaned up by debugfs_remove_recursive, there's no point in checking the return code of every single debugfs create line. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 88 +++++++++----------------- 1 file changed, 29 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 8df5a92a20f1..9fe86939d93e 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1088,67 +1088,37 @@ int ath9k_init_debug(struct ath_hw *ah) return -ENOMEM; #ifdef CONFIG_ATH_DEBUG - if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_debug)) - goto err; + debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_debug); #endif - - if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_dma)) - goto err; - - if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_interrupt)) - goto err; - - if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_wiphy)) - goto err; - - if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_xmit)) - goto err; - - if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_stations)) - goto err; - - if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_misc)) - goto err; - - if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_recv)) - goto err; - - if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_rx_chainmask)) - goto err; - - if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_tx_chainmask)) - goto err; - - if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_regidx)) - goto err; - - if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, &fops_regval)) - goto err; - - if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) - goto err; - - if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_regdump)) - goto err; + debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_dma); + debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_interrupt); + debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_wiphy); + debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_xmit); + debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_stations); + debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_misc); + debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_recv); + debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_rx_chainmask); + debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_tx_chainmask); + debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_regidx); + debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_regval); + debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, + &ah->config.cwm_ignore_extcca); + debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_regdump); sc->debug.regidx = 0; return 0; -err: - debugfs_remove_recursive(sc->debug.debugfs_phy); - sc->debug.debugfs_phy = NULL; - return -ENOMEM; } -- GitLab From 691680b8335fa8995b190676f53e3bcef6477b4a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:38 +0100 Subject: [PATCH 0145/5560] ath9k: add an interface for overriding the value of specific GPIO pins Some devices control antenna settings or other things through GPIO pins of the wireless interface. Add a debugfs interface for changing those and keeping them set across card resets. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 6 ++++++ drivers/net/wireless/ath/ath9k/hw.c | 16 ++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 2 ++ 3 files changed, 24 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 9fe86939d93e..a762cadb3ab7 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1119,6 +1119,12 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_regdump); + debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); + + debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); + sc->debug.regidx = 0; return 0; } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 338b07502f1a..b170c455a40b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1212,6 +1212,20 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, return true; } +static void ath9k_hw_apply_gpio_override(struct ath_hw *ah) +{ + u32 gpio_mask = ah->gpio_mask; + int i; + + for (i = 0; gpio_mask; i++, gpio_mask >>= 1) { + if (!(gpio_mask & 1)) + continue; + + ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i))); + } +} + bool ath9k_hw_check_alive(struct ath_hw *ah) { int count = 50; @@ -1500,6 +1514,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (AR_SREV_9300_20_OR_LATER(ah)) ar9003_hw_bb_watchdog_config(ah); + ath9k_hw_apply_gpio_override(ah); + return 0; } EXPORT_SYMBOL(ath9k_hw_reset); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c86eea28a88f..775c0eb10b95 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -799,6 +799,8 @@ struct ath_hw { int initPDADC; int PDADCdelta; u8 led_pin; + u32 gpio_mask; + u32 gpio_val; struct ar5416IniArray iniModes; struct ar5416IniArray iniCommon; -- GitLab From 6fb1b1e18fe3d141c54182c5d5b3af823bed455f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:39 +0100 Subject: [PATCH 0146/5560] ath9k: add support for overriding the MAC address through platform data On some devices the correct MAC address is not in the EEPROM data, but stored somewhere else. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 7 ++++++- include/linux/ath9k_platform.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 79aec983279f..e22e8215d941 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -15,6 +15,7 @@ */ #include +#include #include "ath9k.h" @@ -537,6 +538,7 @@ static void ath9k_init_misc(struct ath_softc *sc) static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { + struct ath9k_platform_data *pdata = sc->dev->platform_data; struct ath_hw *ah = NULL; struct ath_common *common; int ret = 0, i; @@ -551,7 +553,7 @@ 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) + if (!pdata) ah->ah_flags |= AH_USE_EEPROM; common = ath9k_hw_common(ah); @@ -587,6 +589,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (ret) goto err_hw; + if (pdata && pdata->macaddr) + memcpy(common->macaddr, pdata->macaddr, ETH_ALEN); + ret = ath9k_init_queues(sc); if (ret) goto err_queues; diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index b847fc7b93f9..b5f06583a1ba 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -23,6 +23,7 @@ struct ath9k_platform_data { u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; + u8 *macaddr; }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- GitLab From 6de66dd963ddd669667a81a2401f2fd6472ff55c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:40 +0100 Subject: [PATCH 0147/5560] ath9k: add support for overriding LED pin and GPIO settings from platform data Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/gpio.c | 14 ++++++++------ drivers/net/wireless/ath/ath9k/hw.h | 2 +- drivers/net/wireless/ath/ath9k/init.c | 8 +++++++- include/linux/ath9k_platform.h | 4 ++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 0fb8f8ac275a..44a0a886124d 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -41,12 +41,14 @@ void ath_init_leds(struct ath_softc *sc) { int ret; - if (AR_SREV_9287(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9287; - else if (AR_SREV_9485(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9485; - else - sc->sc_ah->led_pin = ATH_LED_PIN_DEF; + if (sc->sc_ah->led_pin < 0) { + if (AR_SREV_9287(sc->sc_ah)) + sc->sc_ah->led_pin = ATH_LED_PIN_9287; + else if (AR_SREV_9485(sc->sc_ah)) + sc->sc_ah->led_pin = ATH_LED_PIN_9485; + else + sc->sc_ah->led_pin = ATH_LED_PIN_DEF; + } /* Configure gpio 1 for output */ ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 775c0eb10b95..3d9fc6e391a7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -798,7 +798,7 @@ struct ath_hw { u32 originalGain[22]; int initPDADC; int PDADCdelta; - u8 led_pin; + int led_pin; u32 gpio_mask; u32 gpio_val; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e22e8215d941..cdb0f1c89a0e 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -553,8 +553,14 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; - if (!pdata) + if (!pdata) { ah->ah_flags |= AH_USE_EEPROM; + sc->sc_ah->led_pin = -1; + } else { + sc->sc_ah->gpio_mask = pdata->gpio_mask; + sc->sc_ah->gpio_val = pdata->gpio_val; + sc->sc_ah->led_pin = pdata->led_pin; + } common = ath9k_hw_common(ah); common->ops = &ath9k_common_ops; diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h index b5f06583a1ba..020387a114e3 100644 --- a/include/linux/ath9k_platform.h +++ b/include/linux/ath9k_platform.h @@ -24,6 +24,10 @@ struct ath9k_platform_data { u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; u8 *macaddr; + + int led_pin; + u32 gpio_mask; + u32 gpio_val; }; #endif /* _LINUX_ATH9K_PLATFORM_H */ -- GitLab From f171760c558946c7a2e0ee310dfb968f9d4853c6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:41 +0100 Subject: [PATCH 0148/5560] ath9k_hw: enable a BlockAck related fixup specific to AR9100 Fixes interop issues with aggregation in combination with multi-BSSID Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 ++ drivers/net/wireless/ath/ath9k/reg.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b170c455a40b..175c36f3fdac 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -410,6 +410,8 @@ 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; + if (AR_SREV_9100(ah)) + ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; ah->enable_32kHz_clock = DONT_USE_32KHZ; ah->slottime = 20; ah->globaltxtimeout = (u32) -1; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 8fa8acfde62e..693d543937b5 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1396,6 +1396,7 @@ enum { #define AR_STA_ID1_PCF 0x00100000 #define AR_STA_ID1_USE_DEFANT 0x00200000 #define AR_STA_ID1_DEFANT_UPDATE 0x00400000 +#define AR_STA_ID1_AR9100_BA_FIX 0x00400000 #define AR_STA_ID1_RTS_USE_DEF 0x00800000 #define AR_STA_ID1_ACKCTS_6MB 0x01000000 #define AR_STA_ID1_BASE_RATE_11B 0x02000000 -- GitLab From 598cdd5246ea158310942699e5008ac7f687ad62 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:42 +0100 Subject: [PATCH 0149/5560] ath9k_hw: force rx chainmask to 7 on AR9100 Most AR9100 devices already have a chainmask of 7 (three antennas), however on the ones that don't (rx and tx chainmask set to 5), problems with IQ mismatch calibration have been observed. This shows up as tx queue hangs (and subsequent hardware resets) if traffic is sent during this type of calibration. Forcing the rx chainmask to 7 fixes the calibration issues with no apparent negative side effects on throughput and stability. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 175c36f3fdac..8b8656898dfe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1869,6 +1869,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) !(AR_SREV_9271(ah))) /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */ pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; + else if (AR_SREV_9100(ah)) + pCap->rx_chainmask = 0x7; else /* Use rx_chainmask from EEPROM. */ pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); -- GitLab From a9cbe96d19861755680a712b709cccac5dc6aca8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 19 Mar 2011 13:55:43 +0100 Subject: [PATCH 0150/5560] ath9k: remove the pending frames ath_txq_schedule workaround This workaround called ath_txq_schedule whenever there were still pending frames for a queue, but the queue depth was zero. Because of its its high false positive probability (e.g. with paused TIDs) and because it is in the way of other pending work (AP powersave fixes), it is better to remove this code entirely. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 26734e53b37f..f916f088b553 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2144,33 +2144,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work) } else { txq->axq_tx_inprogress = true; } - } else { - /* If the queue has pending buffers, then it - * should be doing tx work (and have axq_depth). - * Shouldn't get to this state I think..but - * we do. - */ - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && - (txq->pending_frames > 0 || - !list_empty(&txq->axq_acq) || - txq->stopped)) { - ath_err(ath9k_hw_common(sc->sc_ah), - "txq: %p axq_qnum: %u," - " mac80211_qnum: %i" - " axq_link: %p" - " pending frames: %i" - " axq_acq empty: %i" - " stopped: %i" - " axq_depth: 0 Attempting to" - " restart tx logic.\n", - txq, txq->axq_qnum, - txq->mac80211_qnum, - txq->axq_link, - txq->pending_frames, - list_empty(&txq->axq_acq), - txq->stopped); - ath_txq_schedule(sc, txq); - } } spin_unlock_bh(&txq->axq_lock); } -- GitLab From be7974aa105dc47bb25013016d1fcad17da17783 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 21 Mar 2011 15:07:55 +0100 Subject: [PATCH 0151/5560] mac80211: Minor optimization in tx status handling ieee80211_tx_status iterates over all tx rates the driver reports back in order to 1) mark tx rates as invalid if the driver cannot have tried that rate 2) find the actually used tx rate for the final retransmission By leaving the for loop when the first invalid rate index is found we can move the rates_idx assignment after the loop and therefore save a few assignments and conditionals. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/status.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/mac80211/status.c b/net/mac80211/status.c index b936dd29e92b..3ed3c835fbbf 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -189,16 +189,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) bool acked; for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { - /* the HW cannot have attempted that rate */ - if (i >= hw->max_report_rates) { + if (info->status.rates[i].idx < 0) { + break; + } else if (i >= hw->max_report_rates) { + /* the HW cannot have attempted that rate */ info->status.rates[i].idx = -1; info->status.rates[i].count = 0; - } else if (info->status.rates[i].idx >= 0) { - rates_idx = i; + break; } retry_count += info->status.rates[i].count; } + rates_idx = i - 1; + if (retry_count < 0) retry_count = 0; -- GitLab From 903946e6e21ef4dd678acafb8881cabde9182caf Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 21 Mar 2011 17:27:35 -0700 Subject: [PATCH 0152/5560] ath9k_hw: remove AR9485 1.0 support Only AR9485 1.1 was sold. This debloats the driver by ~14 KiB. text data bss dec hex filename 300413 624 1056 302093 49c0d drivers/net/wireless/ath/ath9k/ath9k_hw.ko text data bss dec hex filename 310285 624 1056 311965 4c29d drivers/net/wireless/ath/ath9k/ath9k_hw-old.ko $ du -b ath9k_hw* 6210541 ath9k_hw.ko 6225089 ath9k_hw-old.ko Cc: Bill Wu Cc: Paul Shaw Cc: Forbes Tsai Cc: Jesmine Chen Cc: Marvian Chen Cc: Vivek Natarajan Cc: Bernadette Yetso Cc: Sarvesh Shrivastava Acked-by: Yi-Chen Su Acked-by: Jeffrey Chung Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 90 -- .../net/wireless/ath/ath9k/ar9485_initvals.h | 925 ------------------ 2 files changed, 1015 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 7f5de6e4448b..3daf3df02481 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -88,66 +88,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ar9485_1_1_pcie_phy_clkreq_disable_L1, ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 2); - } else 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_disable_L1, - ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1), - 2); } else { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -228,11 +168,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) ar9485_modes_lowest_ob_db_tx_gain_1_1, ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), 5); - else 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, @@ -245,11 +180,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) ar9485Modes_high_ob_db_tx_gain_1_1, ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), 5); - else if (AR_SREV_9485(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9485Modes_high_ob_db_tx_gain_1_0, - ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0), - 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_high_ob_db_tx_gain_table_2p2, @@ -262,11 +192,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) ar9485Modes_low_ob_db_tx_gain_1_1, ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), 5); - else if (AR_SREV_9485(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9485Modes_low_ob_db_tx_gain_1_0, - ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0), - 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_low_ob_db_tx_gain_table_2p2, @@ -279,11 +204,6 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) ar9485Modes_high_power_tx_gain_1_1, ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), 5); - else 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, @@ -303,11 +223,6 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) ar9485_common_rx_gain_1_1, ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2); - else 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, @@ -320,11 +235,6 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) ar9485Common_wo_xlna_rx_gain_1_1, ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); - else 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, diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 71cc0a3a29fb..f91f73e50d00 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -17,931 +17,6 @@ #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 */ - {0x00004090, 0x00aa10aa}, - {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}, -}; - static const u32 ar9485_1_1_mac_core[][2] = { /* Addr allmodes */ {0x00000008, 0x00000000}, -- GitLab From 5e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4e Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 21 Mar 2011 18:00:50 -0700 Subject: [PATCH 0153/5560] wireless: mwifiex: initial commit for Marvell mwifiex driver This driver adds WiFi support for Marvell 802.11n based chipsets with SDIO interface. Currently only SD8787 is supported. More chipsets will be supported later. drivers/net/wireless/mwifiex/ Signed-off-by: Nishant Sarmukadam Signed-off-by: Amitkumar Karwar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: Yogesh Ashok Powar Signed-off-by: Marc Yang Signed-off-by: Ramesh Radhakrishnan Signed-off-by: Frank Huang Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 2 + drivers/net/wireless/mwifiex/11n.c | 922 ++++++ drivers/net/wireless/mwifiex/11n.h | 178 + drivers/net/wireless/mwifiex/11n_aggr.c | 423 +++ drivers/net/wireless/mwifiex/11n_aggr.h | 32 + drivers/net/wireless/mwifiex/11n_rxreorder.c | 637 ++++ drivers/net/wireless/mwifiex/11n_rxreorder.h | 67 + drivers/net/wireless/mwifiex/Kconfig | 21 + drivers/net/wireless/mwifiex/Makefile | 41 + drivers/net/wireless/mwifiex/README | 204 ++ drivers/net/wireless/mwifiex/cfg80211.c | 1517 +++++++++ drivers/net/wireless/mwifiex/cfg80211.h | 31 + drivers/net/wireless/mwifiex/cfp.c | 368 +++ drivers/net/wireless/mwifiex/cmdevt.c | 1463 +++++++++ drivers/net/wireless/mwifiex/debugfs.c | 773 +++++ drivers/net/wireless/mwifiex/decl.h | 177 + drivers/net/wireless/mwifiex/fw.h | 1376 ++++++++ drivers/net/wireless/mwifiex/init.c | 665 ++++ drivers/net/wireless/mwifiex/ioctl.h | 433 +++ drivers/net/wireless/mwifiex/join.c | 1464 +++++++++ drivers/net/wireless/mwifiex/main.c | 1102 +++++++ drivers/net/wireless/mwifiex/main.h | 1081 ++++++ drivers/net/wireless/mwifiex/scan.c | 3098 ++++++++++++++++++ drivers/net/wireless/mwifiex/sdio.c | 1770 ++++++++++ drivers/net/wireless/mwifiex/sdio.h | 305 ++ drivers/net/wireless/mwifiex/sta_cmd.c | 1226 +++++++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 986 ++++++ drivers/net/wireless/mwifiex/sta_event.c | 405 +++ drivers/net/wireless/mwifiex/sta_ioctl.c | 2478 ++++++++++++++ drivers/net/wireless/mwifiex/sta_rx.c | 182 + drivers/net/wireless/mwifiex/sta_tx.c | 202 ++ drivers/net/wireless/mwifiex/txrx.c | 202 ++ drivers/net/wireless/mwifiex/util.c | 252 ++ drivers/net/wireless/mwifiex/util.h | 32 + drivers/net/wireless/mwifiex/wmm.c | 1237 +++++++ drivers/net/wireless/mwifiex/wmm.h | 112 + 37 files changed, 25465 insertions(+) create mode 100644 drivers/net/wireless/mwifiex/11n.c create mode 100644 drivers/net/wireless/mwifiex/11n.h create mode 100644 drivers/net/wireless/mwifiex/11n_aggr.c create mode 100644 drivers/net/wireless/mwifiex/11n_aggr.h create mode 100644 drivers/net/wireless/mwifiex/11n_rxreorder.c create mode 100644 drivers/net/wireless/mwifiex/11n_rxreorder.h create mode 100644 drivers/net/wireless/mwifiex/Kconfig create mode 100644 drivers/net/wireless/mwifiex/Makefile create mode 100644 drivers/net/wireless/mwifiex/README create mode 100644 drivers/net/wireless/mwifiex/cfg80211.c create mode 100644 drivers/net/wireless/mwifiex/cfg80211.h create mode 100644 drivers/net/wireless/mwifiex/cfp.c create mode 100644 drivers/net/wireless/mwifiex/cmdevt.c create mode 100644 drivers/net/wireless/mwifiex/debugfs.c create mode 100644 drivers/net/wireless/mwifiex/decl.h create mode 100644 drivers/net/wireless/mwifiex/fw.h create mode 100644 drivers/net/wireless/mwifiex/init.c create mode 100644 drivers/net/wireless/mwifiex/ioctl.h create mode 100644 drivers/net/wireless/mwifiex/join.c create mode 100644 drivers/net/wireless/mwifiex/main.c create mode 100644 drivers/net/wireless/mwifiex/main.h create mode 100644 drivers/net/wireless/mwifiex/scan.c create mode 100644 drivers/net/wireless/mwifiex/sdio.c create mode 100644 drivers/net/wireless/mwifiex/sdio.h create mode 100644 drivers/net/wireless/mwifiex/sta_cmd.c create mode 100644 drivers/net/wireless/mwifiex/sta_cmdresp.c create mode 100644 drivers/net/wireless/mwifiex/sta_event.c create mode 100644 drivers/net/wireless/mwifiex/sta_ioctl.c create mode 100644 drivers/net/wireless/mwifiex/sta_rx.c create mode 100644 drivers/net/wireless/mwifiex/sta_tx.c create mode 100644 drivers/net/wireless/mwifiex/txrx.c create mode 100644 drivers/net/wireless/mwifiex/util.c create mode 100644 drivers/net/wireless/mwifiex/util.h create mode 100644 drivers/net/wireless/mwifiex/wmm.c create mode 100644 drivers/net/wireless/mwifiex/wmm.h diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 7aeb113cbb90..f354bd4e121e 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -284,5 +284,6 @@ source "drivers/net/wireless/rtlwifi/Kconfig" source "drivers/net/wireless/wl1251/Kconfig" source "drivers/net/wireless/wl12xx/Kconfig" source "drivers/net/wireless/zd1211rw/Kconfig" +source "drivers/net/wireless/mwifiex/Kconfig" endif # WLAN diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index ddd3fb6ba1d3..7bba6a82b875 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -56,3 +56,5 @@ obj-$(CONFIG_WL12XX) += wl12xx/ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ obj-$(CONFIG_IWM) += iwmc3200wifi/ + +obj-$(CONFIG_MWIFIEX) += mwifiex/ diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c new file mode 100644 index 000000000000..0e04a21be0a3 --- /dev/null +++ b/drivers/net/wireless/mwifiex/11n.c @@ -0,0 +1,922 @@ +/* + * Marvell Wireless LAN device driver: 802.11n + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +/* + * Fills HT capability information field, AMPDU Parameters field, HT extended + * capability field, and supported MCS set fields. + * + * Only the following HT capability information fields are used, all other + * fields are always turned off. + * + * Bit 1 : Supported channel width (0: 20MHz, 1: Both 20 and 40 MHz) + * Bit 4 : Greenfield support (0: Not supported, 1: Supported) + * Bit 5 : Short GI for 20 MHz support (0: Not supported, 1: Supported) + * Bit 6 : Short GI for 40 MHz support (0: Not supported, 1: Supported) + * Bit 7 : Tx STBC (0: Not supported, 1: Supported) + * Bit 8-9 : Rx STBC (0: Not supported, X: Support for up to X spatial streams) + * Bit 10 : Delayed BA support (0: Not supported, 1: Supported) + * Bit 11 : Maximum AMSDU length (0: 3839 octets, 1: 7935 octets) + * Bit 14 : 40-Mhz intolerant support (0: Not supported, 1: Supported) + * + * In addition, the following AMPDU Parameters are set - + * - Maximum AMPDU length exponent (set to 3) + * - Minimum AMPDU start spacing (set to 0 - No restrictions) + * + * MCS is set for 1x1, with MSC32 for infra mode or ad-hoc mode with 40 MHz + * support. + * + * RD responder bit to set to clear in the extended capability header. + */ +void +mwifiex_fill_cap_info(struct mwifiex_private *priv, + struct mwifiex_ie_types_htcap *ht_cap) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u8 *mcs; + int rx_mcs_supp; + uint16_t ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); + uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info); + + if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap) && + ISSUPP_CHANWIDTH40(adapter->usr_dot_11n_dev_cap)) + SETHT_SUPPCHANWIDTH(ht_cap_info); + else + RESETHT_SUPPCHANWIDTH(ht_cap_info); + + if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap) && + ISSUPP_GREENFIELD(adapter->usr_dot_11n_dev_cap)) + SETHT_GREENFIELD(ht_cap_info); + else + RESETHT_GREENFIELD(ht_cap_info); + + if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap) && + ISSUPP_SHORTGI20(adapter->usr_dot_11n_dev_cap)) + SETHT_SHORTGI20(ht_cap_info); + else + RESETHT_SHORTGI20(ht_cap_info); + + if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap) && + ISSUPP_SHORTGI40(adapter->usr_dot_11n_dev_cap)) + SETHT_SHORTGI40(ht_cap_info); + else + RESETHT_SHORTGI40(ht_cap_info); + + /* No user config for RX STBC yet */ + if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap) + && ISSUPP_RXSTBC(adapter->usr_dot_11n_dev_cap)) + SETHT_RXSTBC(ht_cap_info, 1); + else + RESETHT_RXSTBC(ht_cap_info); + + /* No user config for TX STBC yet */ + if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) + SETHT_TXSTBC(ht_cap_info); + else + RESETHT_TXSTBC(ht_cap_info); + + /* No user config for Delayed BACK yet */ + if (GET_DELAYEDBACK(adapter->hw_dot_11n_dev_cap)) + SETHT_DELAYEDBACK(ht_cap_info); + else + RESETHT_DELAYEDBACK(ht_cap_info); + + if (ISENABLED_40MHZ_INTOLARENT(adapter->usr_dot_11n_dev_cap)) + SETHT_40MHZ_INTOLARANT(ht_cap_info); + else + RESETHT_40MHZ_INTOLARANT(ht_cap_info); + + SETAMPDU_SIZE(ht_cap->ht_cap.ampdu_params_info, AMPDU_FACTOR_64K); + SETAMPDU_SPACING(ht_cap->ht_cap.ampdu_params_info, 0); + + /* Need change to support 8k AMSDU receive */ + RESETHT_MAXAMSDU(ht_cap_info); + + rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); + + mcs = (u8 *)&ht_cap->ht_cap.mcs; + + /* Set MCS for 1x1 */ + memset(mcs, 0xff, rx_mcs_supp); + + /* Clear all the other values */ + memset(&mcs[rx_mcs_supp], 0, + sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); + + if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || + (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap) && + ISSUPP_CHANWIDTH40(adapter->usr_dot_11n_dev_cap))) + /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ + SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); + + /* Clear RD responder bit */ + RESETHT_EXTCAP_RDG(ht_ext_cap); + + ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info); + ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); +} + +/* + * Shows HT capability information fields. + * + * The following HT capability information fields are supported. + * - Maximum AMSDU length (3839 bytes or 7935 bytes) + * - Beam forming support + * - Greenfield preamble support + * - AMPDU support + * - MIMO Power Save support + * - Rx STBC support + * - Tx STBC support + * - Short GI for 20 MHz support + * - Short GI for 40 MHz support + * - LDPC coded packets receive support + * - Number of delayed BA streams + * - Number of immediate BA streams + * - 10 MHz channel width support + * - 20 MHz channel width support + * - 40 MHz channel width support + * - Presence of Tx antenna A/B/C/D + * - Presence of Rx antenna A/B/C/D + */ +void +mwifiex_show_dot_11n_dev_cap(struct mwifiex_adapter *adapter, u32 cap) +{ + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Max MSDU len = %s octets\n", + (ISSUPP_MAXAMSDU(cap) ? "7935" : "3839")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Beam forming %s\n", + (ISSUPP_BEAMFORMING(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Greenfield preamble %s\n", + (ISSUPP_GREENFIELD(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: AMPDU %s\n", + (ISSUPP_AMPDU(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: MIMO Power Save %s\n", + (ISSUPP_MIMOPS(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Rx STBC %s\n", + (ISSUPP_RXSTBC(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Tx STBC %s\n", + (ISSUPP_TXSTBC(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Short GI for 40 Mhz %s\n", + (ISSUPP_SHORTGI40(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Short GI for 20 Mhz %s\n", + (ISSUPP_SHORTGI20(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: LDPC coded packet receive %s\n", + (ISSUPP_RXLDPC(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, + "info: GET_HW_SPEC: Number of Delayed Block Ack streams = %d\n", + GET_DELAYEDBACK(cap)); + dev_dbg(adapter->dev, + "info: GET_HW_SPEC: Number of Immediate Block Ack streams = %d\n", + GET_IMMEDIATEBACK(cap)); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: 40 Mhz channel width %s\n", + (ISSUPP_CHANWIDTH40(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: 20 Mhz channel width %s\n", + (ISSUPP_CHANWIDTH20(cap) ? "supported" : "not supported")); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: 10 Mhz channel width %s\n", + (ISSUPP_CHANWIDTH10(cap) ? "supported" : "not supported")); + + if (ISSUPP_RXANTENNAA(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea A\n"); + + if (ISSUPP_RXANTENNAB(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea B\n"); + + if (ISSUPP_RXANTENNAC(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea C\n"); + + if (ISSUPP_RXANTENNAD(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea D\n"); + + if (ISSUPP_TXANTENNAA(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea A\n"); + + if (ISSUPP_TXANTENNAB(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea B\n"); + + if (ISSUPP_TXANTENNAC(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea C\n"); + + if (ISSUPP_TXANTENNAD(cap)) + dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea D\n"); + + return; +} + +/* + * Shows HT MCS support field. + */ +void +mwifiex_show_dev_mcs_support(struct mwifiex_adapter *adapter, u8 support) +{ + dev_dbg(adapter->dev, "info: GET_HW_SPEC: MCSs for %dx%d MIMO\n", + GET_RXMCSSUPP(support), GET_TXMCSSUPP(support)); + return; +} + +/* + * This function returns the pointer to an entry in BA Stream + * table which matches the requested BA status. + */ +static struct mwifiex_tx_ba_stream_tbl * +mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv, + enum mwifiex_ba_status ba_status) +{ + struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { + if (tx_ba_tsr_tbl->ba_status == ba_status) { + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, + flags); + return tx_ba_tsr_tbl; + } + } + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + return NULL; +} + +/* + * This function handles the command response of delete a block + * ack request. + * + * The function checks the response success status and takes action + * accordingly (send an add BA request in case of success, or recreate + * the deleted stream in case of failure, if the add BA was also + * initiated by us). + */ +int mwifiex_ret_11n_delba(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + int tid; + struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; + struct host_cmd_ds_11n_delba *del_ba = + (struct host_cmd_ds_11n_delba *) &resp->params.del_ba; + uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set); + + tid = del_ba_param_set >> DELBA_TID_POS; + if (del_ba->del_result == BA_RESULT_SUCCESS) { + mwifiex_11n_delete_ba_stream_tbl(priv, tid, + del_ba->peer_mac_addr, TYPE_DELBA_SENT, + INITIATOR_BIT(del_ba_param_set)); + + tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, + BA_STREAM_SETUP_INPROGRESS); + if (tx_ba_tbl) + mwifiex_send_addba(priv, tx_ba_tbl->tid, + tx_ba_tbl->ra); + } else { /* + * In case of failure, recreate the deleted stream in case + * we initiated the ADDBA + */ + if (INITIATOR_BIT(del_ba_param_set)) { + mwifiex_11n_create_tx_ba_stream_tbl(priv, + del_ba->peer_mac_addr, tid, + BA_STREAM_SETUP_INPROGRESS); + + tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, + BA_STREAM_SETUP_INPROGRESS); + if (tx_ba_tbl) + mwifiex_11n_delete_ba_stream_tbl(priv, + tx_ba_tbl->tid, tx_ba_tbl->ra, + TYPE_DELBA_SENT, true); + } + } + + return 0; +} + +/* + * This function handles the command response of add a block + * ack request. + * + * Handling includes changing the header fields to CPU formats, checking + * the response success status and taking actions accordingly (delete the + * BA stream table in case of failure). + */ +int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + int tid; + struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = + (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp; + struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; + + add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) + & SSN_MASK); + + tid = (le16_to_cpu(add_ba_rsp->block_ack_param_set) + & IEEE80211_ADDBA_PARAM_TID_MASK) + >> BLOCKACKPARAM_TID_POS; + if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { + tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, + add_ba_rsp->peer_mac_addr); + if (tx_ba_tbl) { + dev_dbg(priv->adapter->dev, "info: BA stream complete\n"); + tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE; + } else { + dev_err(priv->adapter->dev, "BA stream not created\n"); + } + } else { + mwifiex_11n_delete_ba_stream_tbl(priv, tid, + add_ba_rsp->peer_mac_addr, + TYPE_DELBA_SENT, true); + if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) + priv->aggr_prio_tbl[tid].ampdu_ap = + BA_STREAM_NOT_ALLOWED; + } + + return 0; +} + +/* + * This function handles the command response of 11n configuration request. + * + * Handling includes changing the header fields into CPU format. + */ +int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; + struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; + + if (data_buf) { + tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf; + tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap); + tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info); + } + return 0; +} + +/* + * This function prepares command of reconfigure Tx buffer. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting Tx buffer size (for SET only) + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, int cmd_action, + void *data_buf) +{ + struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf; + u16 action = (u16) cmd_action; + u16 buf_size = *((u16 *) data_buf); + + cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF); + cmd->size = + cpu_to_le16(sizeof(struct host_cmd_ds_txbuf_cfg) + S_DS_GEN); + tx_buf->action = cpu_to_le16(action); + switch (action) { + case HostCmd_ACT_GEN_SET: + dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size); + tx_buf->buff_size = cpu_to_le16(buf_size); + break; + case HostCmd_ACT_GEN_GET: + default: + tx_buf->buff_size = 0; + break; + } + return 0; +} + +/* + * This function prepares command of AMSDU aggregation control. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting AMSDU control parameters (for SET only) + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + int cmd_action, void *data_buf) +{ + struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = + &cmd->params.amsdu_aggr_ctrl; + u16 action = (u16) cmd_action; + struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl = + (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; + + cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl) + + S_DS_GEN); + amsdu_ctrl->action = cpu_to_le16(action); + switch (action) { + case HostCmd_ACT_GEN_SET: + amsdu_ctrl->enable = cpu_to_le16(aa_ctrl->enable); + amsdu_ctrl->curr_buf_size = 0; + break; + case HostCmd_ACT_GEN_GET: + default: + amsdu_ctrl->curr_buf_size = 0; + break; + } + return 0; +} + +/* + * This function handles the command response of AMSDU aggregation + * control request. + * + * Handling includes changing the header fields into CPU format. + */ +int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; + struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = + &resp->params.amsdu_aggr_ctrl; + + if (data_buf) { + amsdu_aggr_ctrl = + (struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf; + amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable); + amsdu_aggr_ctrl->curr_buf_size = + le16_to_cpu(amsdu_ctrl->curr_buf_size); + } + return 0; +} + +/* + * This function prepares 11n configuration command. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting HT Tx capability and HT Tx information fields + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; + struct mwifiex_ds_11n_tx_cfg *txcfg = + (struct mwifiex_ds_11n_tx_cfg *) data_buf; + + cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN); + htcfg->action = cpu_to_le16(cmd_action); + htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap); + htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo); + return 0; +} + +/* + * This function appends an 11n TLV to a buffer. + * + * Buffer allocation is responsibility of the calling + * function. No size validation is made here. + * + * The function fills up the following sections, if applicable - + * - HT capability IE + * - HT information IE (with channel list) + * - 20/40 BSS Coexistence IE + * - HT Extended Capabilities IE + */ +int +mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc, + u8 **buffer) +{ + struct mwifiex_ie_types_htcap *ht_cap; + struct mwifiex_ie_types_htinfo *ht_info; + struct mwifiex_ie_types_chan_list_param_set *chan_list; + struct mwifiex_ie_types_2040bssco *bss_co_2040; + struct mwifiex_ie_types_extcap *ext_cap; + int ret_len = 0; + + if (!buffer || !*buffer) + return ret_len; + + if (bss_desc->bcn_ht_cap) { + ht_cap = (struct mwifiex_ie_types_htcap *) *buffer; + memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); + ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); + ht_cap->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_cap)); + memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), + (u8 *) bss_desc->bcn_ht_cap + + sizeof(struct ieee_types_header), + le16_to_cpu(ht_cap->header.len)); + + mwifiex_fill_cap_info(priv, ht_cap); + + *buffer += sizeof(struct mwifiex_ie_types_htcap); + ret_len += sizeof(struct mwifiex_ie_types_htcap); + } + + if (bss_desc->bcn_ht_info) { + if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + ht_info = (struct mwifiex_ie_types_htinfo *) *buffer; + memset(ht_info, 0, + sizeof(struct mwifiex_ie_types_htinfo)); + ht_info->header.type = + cpu_to_le16(WLAN_EID_HT_INFORMATION); + ht_info->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_info)); + + memcpy((u8 *) ht_info + + sizeof(struct mwifiex_ie_types_header), + (u8 *) bss_desc->bcn_ht_info + + sizeof(struct ieee_types_header), + le16_to_cpu(ht_info->header.len)); + + if (!ISSUPP_CHANWIDTH40 + (priv->adapter->hw_dot_11n_dev_cap) + || !ISSUPP_CHANWIDTH40(priv->adapter-> + usr_dot_11n_dev_cap)) + RESET_CHANWIDTH40(ht_info->ht_info.ht_param); + + *buffer += sizeof(struct mwifiex_ie_types_htinfo); + ret_len += sizeof(struct mwifiex_ie_types_htinfo); + } + + chan_list = + (struct mwifiex_ie_types_chan_list_param_set *) *buffer; + memset(chan_list, 0, + sizeof(struct mwifiex_ie_types_chan_list_param_set)); + chan_list->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); + chan_list->header.len = cpu_to_le16( + sizeof(struct mwifiex_ie_types_chan_list_param_set) - + sizeof(struct mwifiex_ie_types_header)); + chan_list->chan_scan_param[0].chan_number = + bss_desc->bcn_ht_info->control_chan; + chan_list->chan_scan_param[0].radio_type = + mwifiex_band_to_radio_type((u8) bss_desc->bss_band); + + if ((ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) && + ISSUPP_CHANWIDTH40(priv->adapter->usr_dot_11n_dev_cap)) + && ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_info->ht_param)) + SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. + radio_type, + GET_SECONDARYCHAN(bss_desc-> + bcn_ht_info->ht_param)); + + *buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set); + ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set); + } + + if (bss_desc->bcn_bss_co_2040) { + bss_co_2040 = (struct mwifiex_ie_types_2040bssco *) *buffer; + memset(bss_co_2040, 0, + sizeof(struct mwifiex_ie_types_2040bssco)); + bss_co_2040->header.type = cpu_to_le16(WLAN_EID_BSS_COEX_2040); + bss_co_2040->header.len = + cpu_to_le16(sizeof(bss_co_2040->bss_co_2040)); + + memcpy((u8 *) bss_co_2040 + + sizeof(struct mwifiex_ie_types_header), + (u8 *) bss_desc->bcn_bss_co_2040 + + sizeof(struct ieee_types_header), + le16_to_cpu(bss_co_2040->header.len)); + + *buffer += sizeof(struct mwifiex_ie_types_2040bssco); + ret_len += sizeof(struct mwifiex_ie_types_2040bssco); + } + + if (bss_desc->bcn_ext_cap) { + ext_cap = (struct mwifiex_ie_types_extcap *) *buffer; + memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap)); + ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY); + ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap)); + + memcpy((u8 *) ext_cap + + sizeof(struct mwifiex_ie_types_header), + (u8 *) bss_desc->bcn_ext_cap + + sizeof(struct ieee_types_header), + le16_to_cpu(ext_cap->header.len)); + + *buffer += sizeof(struct mwifiex_ie_types_extcap); + ret_len += sizeof(struct mwifiex_ie_types_extcap); + } + + return ret_len; +} + +/* + * This function reconfigures the Tx buffer size in firmware. + * + * This function prepares a firmware command and issues it, if + * the current Tx buffer size is different from the one requested. + * Maximum configurable Tx buffer size is limited by the HT capability + * field value. + */ +void +mwifiex_cfg_tx_buf(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) +{ + u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K; + u16 tx_buf = 0; + u16 curr_tx_buf_size = 0; + + if (bss_desc->bcn_ht_cap) { + if (GETHT_MAXAMSDU(le16_to_cpu(bss_desc->bcn_ht_cap->cap_info))) + max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_8K; + else + max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_4K; + } + + tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu); + + dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n", + max_amsdu, priv->adapter->max_tx_buf_size); + + if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K) + curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; + else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_4K) + curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K; + else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) + curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; + if (curr_tx_buf_size != tx_buf) + mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, + NULL, &tx_buf); + + return; +} + +/* + * This function checks if the given pointer is valid entry of + * Tx BA Stream table. + */ +static int mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv, + struct mwifiex_tx_ba_stream_tbl *tx_tbl_ptr) +{ + struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; + + list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { + if (tx_ba_tsr_tbl == tx_tbl_ptr) + return true; + } + + return false; +} + +/* + * This function deletes the given entry in Tx BA Stream table. + * + * The function also performs a validity check on the supplied + * pointer before trying to delete. + */ +void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, + struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl) +{ + if (!tx_ba_tsr_tbl && + mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) + return; + + dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl); + + list_del(&tx_ba_tsr_tbl->list); + + kfree(tx_ba_tsr_tbl); + + return; +} + +/* + * This function deletes all the entries in Tx BA Stream table. + */ +void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv) +{ + int i; + struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr, *tmp_node; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + list_for_each_entry_safe(del_tbl_ptr, tmp_node, + &priv->tx_ba_stream_tbl_ptr, list) + mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr); + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + + INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); + + for (i = 0; i < MAX_NUM_TID; ++i) + priv->aggr_prio_tbl[i].ampdu_ap = + priv->aggr_prio_tbl[i].ampdu_user; +} + +/* + * This function returns the pointer to an entry in BA Stream + * table which matches the given RA/TID pair. + */ +struct mwifiex_tx_ba_stream_tbl * +mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, + int tid, u8 *ra) +{ + struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { + if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN)) + && (tx_ba_tsr_tbl->tid == tid)) { + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, + flags); + return tx_ba_tsr_tbl; + } + } + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + return NULL; +} + +/* + * This function creates an entry in Tx BA stream table for the + * given RA/TID pair. + */ +void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, + u8 *ra, int tid, + enum mwifiex_ba_status ba_status) +{ + struct mwifiex_tx_ba_stream_tbl *new_node; + unsigned long flags; + + if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) { + new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), + GFP_ATOMIC); + if (!new_node) { + dev_err(priv->adapter->dev, + "%s: failed to alloc new_node\n", __func__); + return; + } + + INIT_LIST_HEAD(&new_node->list); + + new_node->tid = tid; + new_node->ba_status = ba_status; + memcpy(new_node->ra, ra, ETH_ALEN); + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + } + + return; +} + +/* + * This function sends an add BA request to the given TID/RA pair. + */ +int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) +{ + struct host_cmd_ds_11n_addba_req add_ba_req; + static u8 dialog_tok; + int ret; + + dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid); + + add_ba_req.block_ack_param_set = cpu_to_le16( + (u16) ((tid << BLOCKACKPARAM_TID_POS) | + (priv->add_ba_param. + tx_win_size << BLOCKACKPARAM_WINSIZE_POS) | + IMMEDIATE_BLOCK_ACK)); + add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout); + + ++dialog_tok; + + if (dialog_tok == 0) + dialog_tok = 1; + + add_ba_req.dialog_token = dialog_tok; + memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); + + /* We don't wait for the response of this command */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, + 0, 0, NULL, &add_ba_req); + + return ret; +} + +/* + * This function sends a delete BA request to the given TID/RA pair. + */ +int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, + int initiator) +{ + struct host_cmd_ds_11n_delba delba; + int ret; + uint16_t del_ba_param_set; + + memset(&delba, 0, sizeof(delba)); + delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS); + + del_ba_param_set = le16_to_cpu(delba.del_ba_param_set); + if (initiator) + del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK; + else + del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK; + + memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); + + /* We don't wait for the response of this command */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, + HostCmd_ACT_GEN_SET, 0, NULL, &delba); + + return ret; +} + +/* + * This function handles the command response of a delete BA request. + */ +void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba) +{ + struct host_cmd_ds_11n_delba *cmd_del_ba = + (struct host_cmd_ds_11n_delba *) del_ba; + uint16_t del_ba_param_set = le16_to_cpu(cmd_del_ba->del_ba_param_set); + int tid; + + tid = del_ba_param_set >> DELBA_TID_POS; + + mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr, + TYPE_DELBA_RECEIVE, + INITIATOR_BIT(del_ba_param_set)); +} + +/* + * This function retrieves the Rx reordering table. + */ +int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, + struct mwifiex_ds_rx_reorder_tbl *buf) +{ + int i; + struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf; + struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr; + int count = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); + list_for_each_entry(rx_reorder_tbl_ptr, &priv->rx_reorder_tbl_ptr, + list) { + rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid; + memcpy(rx_reo_tbl->ta, rx_reorder_tbl_ptr->ta, ETH_ALEN); + rx_reo_tbl->start_win = rx_reorder_tbl_ptr->start_win; + rx_reo_tbl->win_size = rx_reorder_tbl_ptr->win_size; + for (i = 0; i < rx_reorder_tbl_ptr->win_size; ++i) { + if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) + rx_reo_tbl->buffer[i] = true; + else + rx_reo_tbl->buffer[i] = false; + } + rx_reo_tbl++; + count++; + + if (count >= MWIFIEX_MAX_RX_BASTREAM_SUPPORTED) + break; + } + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); + + return count; +} + +/* + * This function retrieves the Tx BA stream table. + */ +int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, + struct mwifiex_ds_tx_ba_stream_tbl *buf) +{ + struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; + struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf; + int count = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { + rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid; + dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", + __func__, rx_reo_tbl->tid); + memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); + rx_reo_tbl++; + count++; + if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) + break; + } + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + + return count; +} diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h new file mode 100644 index 000000000000..769a27f2b2c3 --- /dev/null +++ b/drivers/net/wireless/mwifiex/11n.h @@ -0,0 +1,178 @@ +/* + * Marvell Wireless LAN device driver: 802.11n + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_11N_H_ +#define _MWIFIEX_11N_H_ + +#include "11n_aggr.h" +#include "11n_rxreorder.h" +#include "wmm.h" + +void mwifiex_show_dot_11n_dev_cap(struct mwifiex_adapter *adapter, u32 cap); +void mwifiex_show_dev_mcs_support(struct mwifiex_adapter *adapter, u8 support); +int mwifiex_ret_11n_delba(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp); +int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp); +int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf); +int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf); + +int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf); + +int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc, + u8 **buffer); +void mwifiex_cfg_tx_buf(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc); +void mwifiex_fill_cap_info(struct mwifiex_private *, + struct mwifiex_ie_types_htcap *); +int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, + u16 action, int *htcap_cfg); +void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, + struct mwifiex_tx_ba_stream_tbl + *tx_tbl); +void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); +struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct + mwifiex_private + *priv, int tid, + u8 *ra); +void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra, + int tid, + enum mwifiex_ba_status ba_status); +int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); +int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, + int initiator); +void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba); +int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, + struct mwifiex_ds_rx_reorder_tbl *buf); +int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, + struct mwifiex_ds_tx_ba_stream_tbl *buf); +int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, + struct host_cmd_ds_command + *resp, + void *data_buf); +int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + int cmd_action, void *data_buf); +int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + int cmd_action, + void *data_buf); + +/* + * This function checks whether AMPDU is allowed or not for a particular TID. + */ +static inline u8 +mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int tid) +{ + return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) + ? true : false); +} + +/* + * This function checks whether AMSDU is allowed or not for a particular TID. + */ +static inline u8 +mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int tid) +{ + return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) + && ((priv->is_data_rate_auto) + || !((priv->bitmap_rates[2]) & 0x03))) + ? true : false); +} + +/* + * This function checks whether a BA stream is available or not. + */ +static inline u8 +mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) +{ + struct mwifiex_private *pmpriv = NULL; + u8 i = 0; + u32 ba_stream_num = 0; + + for (i = 0; i < priv->adapter->priv_num; i++) { + pmpriv = priv->adapter->priv[i]; + if (pmpriv) + ba_stream_num += + mwifiex_wmm_list_len(priv->adapter, + (struct list_head + *) &pmpriv-> + tx_ba_stream_tbl_ptr); + } + + return ((ba_stream_num < + MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) ? true : false); +} + +/* + * This function finds the correct Tx BA stream to delete. + * + * Upon successfully locating, both the TID and the RA are returned. + */ +static inline u8 +mwifiex_find_stream_to_delete(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int ptr_tid, + int *ptid, u8 *ra) +{ + int tid; + u8 ret = false; + struct mwifiex_tx_ba_stream_tbl *tx_tbl; + unsigned long flags; + + tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user; + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) { + if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) { + tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user; + *ptid = tx_tbl->tid; + memcpy(ra, tx_tbl->ra, ETH_ALEN); + ret = true; + } + } + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + + return ret; +} + +/* + * This function checks whether BA stream is set up or not. + */ +static inline int +mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int tid) +{ + struct mwifiex_tx_ba_stream_tbl *tx_tbl; + + tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra); + if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl)) + return true; + + return false; +} +#endif /* !_MWIFIEX_11N_H_ */ diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c new file mode 100644 index 000000000000..c2abced66957 --- /dev/null +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -0,0 +1,423 @@ +/* + * Marvell Wireless LAN device driver: 802.11n Aggregation + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" +#include "11n_aggr.h" + +/* + * Creates an AMSDU subframe for aggregation into one AMSDU packet. + * + * The resultant AMSDU subframe format is - + * + * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+ + * | DA | SA | Length | SNAP header | MSDU | + * | data[0..5] | data[6..11] | | | data[14..] | + * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+ + * <--6-bytes--> <--6-bytes--> <--2-bytes--><--8-bytes--> <--n-bytes--> + * + * This function also computes the amount of padding required to make the + * buffer length multiple of 4 bytes. + * + * Data => |DA|SA|SNAP-TYPE|........ .| + * MSDU => |DA|SA|Length|SNAP|...... ..| + */ +static int +mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter, + struct sk_buff *skb_aggr, + struct sk_buff *skb_src, int *pad) + +{ + int dt_offset; + struct rfc_1042_hdr snap = { + 0xaa, /* LLC DSAP */ + 0xaa, /* LLC SSAP */ + 0x03, /* LLC CTRL */ + {0x00, 0x00, 0x00}, /* SNAP OUI */ + 0x0000 /* SNAP type */ + /* + * This field will be overwritten + * later with ethertype + */ + }; + struct tx_packet_hdr *tx_header = NULL; + + skb_put(skb_aggr, sizeof(*tx_header)); + + tx_header = (struct tx_packet_hdr *) skb_aggr->data; + + /* Copy DA and SA */ + dt_offset = 2 * ETH_ALEN; + memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset); + + /* Copy SNAP header */ + snap.snap_type = *(u16 *) ((u8 *)skb_src->data + dt_offset); + dt_offset += sizeof(u16); + + memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr)); + + skb_pull(skb_src, dt_offset); + + /* Update Length field */ + tx_header->eth803_hdr.h_proto = htons(skb_src->len + LLC_SNAP_LEN); + + /* Add payload */ + skb_put(skb_aggr, skb_src->len); + memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, + skb_src->len); + *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + + LLC_SNAP_LEN)) & 3)) : 0; + skb_put(skb_aggr, *pad); + + return skb_aggr->len + *pad; +} + +/* + * Adds TxPD to AMSDU header. + * + * Each AMSDU packet will contain one TxPD at the beginning, + * followed by multiple AMSDU subframes. + */ +static void +mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, + struct sk_buff *skb) +{ + struct txpd *local_tx_pd; + + skb_push(skb, sizeof(*local_tx_pd)); + + local_tx_pd = (struct txpd *) skb->data; + memset(local_tx_pd, 0, sizeof(struct txpd)); + + /* Original priority has been overwritten */ + local_tx_pd->priority = (u8) skb->priority; + local_tx_pd->pkt_delay_2ms = + mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + local_tx_pd->bss_num = priv->bss_num; + local_tx_pd->bss_type = priv->bss_type; + /* Always zero as the data is followed by struct txpd */ + local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); + local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); + local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - + sizeof(*local_tx_pd)); + + if (local_tx_pd->tx_control == 0) + /* TxCtrl set by user or default */ + local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); + + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + (priv->adapter->pps_uapsd_mode)) { + if (true == mwifiex_check_last_packet_indication(priv)) { + priv->adapter->tx_lock_flag = true; + local_tx_pd->flags = + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET; + } + } +} + +/* + * Counts the number of subframes in an aggregate packet. + * + * This function parses an aggregate packet buffer, looking for + * subframes and counting the number of such subframe found. The + * function automatically skips the DA/SA fields at the beginning + * of each subframe and padding at the end. + */ +static int +mwifiex_11n_get_num_aggr_pkts(u8 *data, int total_pkt_len) +{ + int pkt_count = 0, pkt_len, pad; + + while (total_pkt_len > 0) { + /* Length will be in network format, change it to host */ + pkt_len = ntohs((*(__be16 *)(data + 2 * ETH_ALEN))); + pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ? + (4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0; + data += pkt_len + pad + sizeof(struct ethhdr); + total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr); + ++pkt_count; + } + + return pkt_count; +} + +/* + * De-aggregate received packets. + * + * This function parses the received aggregate buffer, extracts each subframe, + * strips off the SNAP header from them and sends the data portion for further + * processing. + * + * Each subframe body is copied onto a separate buffer, which are freed by + * upper layer after processing. The function also performs sanity tests on + * the received buffer. + */ +int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, + struct sk_buff *skb) +{ + u16 pkt_len; + int total_pkt_len; + u8 *data; + int pad; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); + struct rxpd *local_rx_pd = (struct rxpd *) skb->data; + struct sk_buff *skb_daggr; + struct mwifiex_rxinfo *rx_info_daggr = NULL; + int ret = -1; + struct rx_packet_hdr *rx_pkt_hdr; + struct mwifiex_adapter *adapter = priv->adapter; + u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; + + data = (u8 *) (local_rx_pd + local_rx_pd->rx_pkt_offset); + total_pkt_len = local_rx_pd->rx_pkt_length; + + /* Sanity test */ + if (total_pkt_len > MWIFIEX_RX_DATA_BUF_SIZE) { + dev_err(adapter->dev, "total pkt len greater than buffer" + " size %d\n", total_pkt_len); + return -1; + } + + rx_info->use_count = mwifiex_11n_get_num_aggr_pkts(data, total_pkt_len); + + while (total_pkt_len > 0) { + rx_pkt_hdr = (struct rx_packet_hdr *) data; + /* Length will be in network format, change it to host */ + pkt_len = ntohs((*(__be16 *) (data + 2 * ETH_ALEN))); + if (pkt_len > total_pkt_len) { + dev_err(adapter->dev, "pkt_len %d > total_pkt_len %d\n", + total_pkt_len, pkt_len); + break; + } + + pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ? + (4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0; + + total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr); + + if (memcmp(&rx_pkt_hdr->rfc1042_hdr, + rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) { + memmove(data + LLC_SNAP_LEN, data, 2 * ETH_ALEN); + data += LLC_SNAP_LEN; + pkt_len += sizeof(struct ethhdr) - LLC_SNAP_LEN; + } else { + *(u16 *) (data + 2 * ETH_ALEN) = (u16) 0; + pkt_len += sizeof(struct ethhdr); + } + + skb_daggr = dev_alloc_skb(pkt_len); + if (!skb_daggr) { + dev_err(adapter->dev, "%s: failed to alloc skb_daggr\n", + __func__); + return -1; + } + rx_info_daggr = MWIFIEX_SKB_RXCB(skb_daggr); + + rx_info_daggr->bss_index = rx_info->bss_index; + skb_daggr->tstamp = skb->tstamp; + rx_info_daggr->parent = skb; + skb_daggr->priority = skb->priority; + skb_put(skb_daggr, pkt_len); + memcpy(skb_daggr->data, data, pkt_len); + + ret = mwifiex_recv_packet(adapter, skb_daggr); + + switch (ret) { + case -EINPROGRESS: + break; + case -1: + dev_err(adapter->dev, "deaggr: host_to_card failed\n"); + case 0: + mwifiex_recv_packet_complete(adapter, skb_daggr, ret); + break; + default: + break; + } + + data += pkt_len + pad; + } + + return ret; +} + +/* + * Create aggregated packet. + * + * This function creates an aggregated MSDU packet, by combining buffers + * from the RA list. Each individual buffer is encapsulated as an AMSDU + * subframe and all such subframes are concatenated together to form the + * AMSDU packet. + * + * A TxPD is also added to the front of the resultant AMSDU packets for + * transmission. The resultant packets format is - + * + * +---- ~ ----+------ ~ ------+------ ~ ------+-..-+------ ~ ------+ + * | TxPD |AMSDU sub-frame|AMSDU sub-frame| .. |AMSDU sub-frame| + * | | 1 | 2 | .. | n | + * +---- ~ ----+------ ~ ------+------ ~ ------+ .. +------ ~ ------+ + */ +int +mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *pra_list, int headroom, + int ptrindex, unsigned long ra_list_flags) + __releases(&priv->wmm.ra_list_spinlock) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct sk_buff *skb_aggr, *skb_src; + struct mwifiex_txinfo *tx_info_aggr, *tx_info_src; + int pad = 0; + int ret = 0; + struct mwifiex_tx_param tx_param; + struct txpd *ptx_pd = NULL; + + if (skb_queue_empty(&pra_list->skb_head)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + return 0; + } + skb_src = skb_peek(&pra_list->skb_head); + tx_info_src = MWIFIEX_SKB_TXCB(skb_src); + skb_aggr = dev_alloc_skb(adapter->tx_buf_size); + if (!skb_aggr) { + dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + return -1; + } + skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); + tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); + + tx_info_aggr->bss_index = tx_info_src->bss_index; + skb_aggr->priority = skb_src->priority; + + while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len + + LLC_SNAP_LEN) + <= adapter->tx_buf_size)) { + + if (!skb_queue_empty(&pra_list->skb_head)) + skb_src = skb_dequeue(&pra_list->skb_head); + else + skb_src = NULL; + + pra_list->total_pkts_size -= skb_src->len; + + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad); + + mwifiex_write_data_complete(adapter, skb_src, 0); + + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + + if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + return -1; + } + + if (!skb_queue_empty(&pra_list->skb_head)) + skb_src = skb_peek(&pra_list->skb_head); + else + skb_src = NULL; + } + + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); + + /* Last AMSDU packet does not need padding */ + skb_trim(skb_aggr, skb_aggr->len - pad); + + /* Form AMSDU */ + mwifiex_11n_form_amsdu_txpd(priv, skb_aggr); + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) + ptx_pd = (struct txpd *)skb_aggr->data; + + skb_push(skb_aggr, headroom); + + tx_param.next_pkt_len = ((pra_list->total_pkts_size) ? + (((pra_list->total_pkts_size) > + adapter->tx_buf_size) ? adapter-> + tx_buf_size : pra_list->total_pkts_size + + LLC_SNAP_LEN + sizeof(struct txpd)) : 0); + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, + skb_aggr->data, + skb_aggr->len, &tx_param); + switch (ret) { + case -EBUSY: + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + mwifiex_write_data_complete(adapter, skb_aggr, -1); + return -1; + } + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + (adapter->pps_uapsd_mode) && + (adapter->tx_lock_flag)) { + priv->adapter->tx_lock_flag = false; + ptx_pd->flags = 0; + } + + skb_queue_tail(&pra_list->skb_head, skb_aggr); + + pra_list->total_pkts_size += skb_aggr->len; + + tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); + break; + case -1: + adapter->data_sent = false; + dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", + __func__, ret); + adapter->dbg.num_tx_host_to_card_failure++; + mwifiex_write_data_complete(adapter, skb_aggr, ret); + return 0; + case -EINPROGRESS: + adapter->data_sent = false; + break; + case 0: + mwifiex_write_data_complete(adapter, skb_aggr, ret); + break; + default: + break; + } + if (ret != -EBUSY) { + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { + priv->wmm.packets_out[ptrindex]++; + priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list; + } + /* Now bss_prio_cur pointer points to next node */ + adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = + list_first_entry( + &adapter->bss_prio_tbl[priv->bss_priority] + .bss_prio_cur->list, + struct mwifiex_bss_prio_node, list); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + } + + return 0; +} diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h new file mode 100644 index 000000000000..9c6dca7ab02c --- /dev/null +++ b/drivers/net/wireless/mwifiex/11n_aggr.h @@ -0,0 +1,32 @@ +/* + * Marvell Wireless LAN device driver: 802.11n Aggregation + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_11N_AGGR_H_ +#define _MWIFIEX_11N_AGGR_H_ + +#define PKT_TYPE_AMSDU 0xE6 + +int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, + struct sk_buff *skb); +int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int headroom, + int ptr_index, unsigned long flags) + __releases(&priv->wmm.ra_list_spinlock); + +#endif /* !_MWIFIEX_11N_AGGR_H_ */ diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c new file mode 100644 index 000000000000..8e94e620e6f4 --- /dev/null +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -0,0 +1,637 @@ +/* + * Marvell Wireless LAN device driver: 802.11n RX Re-ordering + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" +#include "11n_rxreorder.h" + +/* + * This function processes a received packet and forwards + * it to the kernel/upper layer. + */ +static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + + ret = mwifiex_process_rx_packet(adapter, (struct sk_buff *) payload); + return ret; +} + +/* + * This function dispatches all packets in the Rx reorder table. + * + * There could be holes in the buffer, which are skipped by the function. + * Since the buffer is linear, the function uses rotation to simulate + * circular buffer. + */ +static int +mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl + *rx_reor_tbl_ptr, int start_win) +{ + int no_pkt_to_send, i, xchg; + void *rx_tmp_ptr = NULL; + unsigned long flags; + + no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ? + min((start_win - rx_reor_tbl_ptr->start_win), + rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size; + + for (i = 0; i < no_pkt_to_send; ++i) { + spin_lock_irqsave(&priv->rx_pkt_lock, flags); + rx_tmp_ptr = NULL; + if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) { + rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; + rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + } + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + if (rx_tmp_ptr) + mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); + } + + spin_lock_irqsave(&priv->rx_pkt_lock, flags); + /* + * We don't have a circular buffer, hence use rotation to simulate + * circular buffer + */ + xchg = rx_reor_tbl_ptr->win_size - no_pkt_to_send; + for (i = 0; i < xchg; ++i) { + rx_reor_tbl_ptr->rx_reorder_ptr[i] = + rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; + rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; + } + + rx_reor_tbl_ptr->start_win = start_win; + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + + return 0; +} + +/* + * This function dispatches all packets in the Rx reorder table until + * a hole is found. + * + * The start window is adjusted automatically when a hole is located. + * Since the buffer is linear, the function uses rotation to simulate + * circular buffer. + */ +static int +mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) +{ + int i, j, xchg; + void *rx_tmp_ptr = NULL; + unsigned long flags; + + for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) { + spin_lock_irqsave(&priv->rx_pkt_lock, flags); + if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) { + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + break; + } + rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; + rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); + } + + spin_lock_irqsave(&priv->rx_pkt_lock, flags); + /* + * We don't have a circular buffer, hence use rotation to simulate + * circular buffer + */ + if (i > 0) { + xchg = rx_reor_tbl_ptr->win_size - i; + for (j = 0; j < xchg; ++j) { + rx_reor_tbl_ptr->rx_reorder_ptr[j] = + rx_reor_tbl_ptr->rx_reorder_ptr[i + j]; + rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL; + } + } + rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) + &(MAX_TID_VALUE - 1); + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + return 0; +} + +/* + * This function deletes the Rx reorder table and frees the memory. + * + * The function stops the associated timer and dispatches all the + * pending packets in the Rx reorder table before deletion. + */ +static void +mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl + *rx_reor_tbl_ptr) +{ + unsigned long flags; + + if (!rx_reor_tbl_ptr) + return; + + mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, + (rx_reor_tbl_ptr->start_win + + rx_reor_tbl_ptr->win_size) + &(MAX_TID_VALUE - 1)); + + del_timer(&rx_reor_tbl_ptr->timer_context.timer); + + spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); + list_del(&rx_reor_tbl_ptr->list); + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); + + kfree(rx_reor_tbl_ptr->rx_reorder_ptr); + kfree(rx_reor_tbl_ptr); +} + +/* + * This function returns the pointer to an entry in Rx reordering + * table which matches the given TA/TID pair. + */ +static struct mwifiex_rx_reorder_tbl * +mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) +{ + struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + unsigned long flags; + + spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); + list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) { + if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN)) + && (rx_reor_tbl_ptr->tid == tid)) { + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, + flags); + return rx_reor_tbl_ptr; + } + } + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); + + return NULL; +} + +/* + * This function finds the last sequence number used in the packets + * buffered in Rx reordering table. + */ +static int +mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr) +{ + int i; + + for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i) + if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) + return i; + + return -1; +} + +/* + * This function flushes all the packets in Rx reordering table. + * + * The function checks if any packets are currently buffered in the + * table or not. In case there are packets available, it dispatches + * them and then dumps the Rx reordering table. + */ +static void +mwifiex_flush_data(unsigned long context) +{ + struct reorder_tmr_cnxt *reorder_cnxt = + (struct reorder_tmr_cnxt *) context; + int start_win; + + start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr); + if (start_win >= 0) { + dev_dbg(reorder_cnxt->priv->adapter->dev, + "info: flush data %d\n", start_win); + mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv, + reorder_cnxt->ptr, + ((reorder_cnxt->ptr->start_win + + start_win + 1) & (MAX_TID_VALUE - 1))); + } +} + +/* + * This function creates an entry in Rx reordering table for the + * given TA/TID. + * + * The function also initializes the entry with sequence number, window + * size as well as initializes the timer. + * + * If the received TA/TID pair is already present, all the packets are + * dispatched and the window size is moved until the SSN. + */ +static void +mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, + int tid, int win_size, int seq_num) +{ + int i; + struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node; + u16 last_seq = 0; + unsigned long flags; + + /* + * If we get a TID, ta pair which is already present dispatch all the + * the packets and move the window size until the ssn + */ + rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); + if (rx_reor_tbl_ptr) { + mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, + seq_num); + return; + } + /* if !rx_reor_tbl_ptr then create one */ + new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); + if (!new_node) { + dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", + __func__); + return; + } + + INIT_LIST_HEAD(&new_node->list); + new_node->tid = tid; + memcpy(new_node->ta, ta, ETH_ALEN); + new_node->start_win = seq_num; + if (mwifiex_queuing_ra_based(priv)) + /* TODO for adhoc */ + dev_dbg(priv->adapter->dev, + "info: ADHOC:last_seq=%d start_win=%d\n", + last_seq, new_node->start_win); + else + last_seq = priv->rx_seq[tid]; + + if (last_seq >= new_node->start_win) + new_node->start_win = last_seq + 1; + + new_node->win_size = win_size; + + new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size, + GFP_KERNEL); + if (!new_node->rx_reorder_ptr) { + kfree((u8 *) new_node); + dev_err(priv->adapter->dev, + "%s: failed to alloc reorder_ptr\n", __func__); + return; + } + + new_node->timer_context.ptr = new_node; + new_node->timer_context.priv = priv; + + init_timer(&new_node->timer_context.timer); + new_node->timer_context.timer.function = mwifiex_flush_data; + new_node->timer_context.timer.data = + (unsigned long) &new_node->timer_context; + + for (i = 0; i < win_size; ++i) + new_node->rx_reorder_ptr[i] = NULL; + + spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); + list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); + + return; +} + +/* + * This function prepares command for adding a BA request. + * + * Preparation includes - + * - Setting command ID and proper size + * - Setting add BA request buffer + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, void *data_buf) +{ + struct host_cmd_ds_11n_addba_req *add_ba_req = + (struct host_cmd_ds_11n_addba_req *) + &cmd->params.add_ba_req; + + cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ); + cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN); + memcpy(add_ba_req, data_buf, sizeof(*add_ba_req)); + + return 0; +} + +/* + * This function prepares command for adding a BA response. + * + * Preparation includes - + * - Setting command ID and proper size + * - Setting add BA response buffer + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf) +{ + struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = + (struct host_cmd_ds_11n_addba_rsp *) + &cmd->params.add_ba_rsp; + struct host_cmd_ds_11n_addba_req *cmd_addba_req = + (struct host_cmd_ds_11n_addba_req *) data_buf; + u8 tid = 0; + int win_size = 0; + uint16_t block_ack_param_set; + + cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP); + cmd->size = cpu_to_le16(sizeof(*add_ba_rsp) + S_DS_GEN); + + memcpy(add_ba_rsp->peer_mac_addr, cmd_addba_req->peer_mac_addr, + ETH_ALEN); + add_ba_rsp->dialog_token = cmd_addba_req->dialog_token; + add_ba_rsp->block_ack_tmo = cmd_addba_req->block_ack_tmo; + add_ba_rsp->ssn = cmd_addba_req->ssn; + + block_ack_param_set = le16_to_cpu(cmd_addba_req->block_ack_param_set); + tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) + >> BLOCKACKPARAM_TID_POS; + add_ba_rsp->status_code = cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT); + block_ack_param_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; + /* We donot support AMSDU inside AMPDU, hence reset the bit */ + block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK; + block_ack_param_set |= (priv->add_ba_param.rx_win_size << + BLOCKACKPARAM_WINSIZE_POS); + add_ba_rsp->block_ack_param_set = cpu_to_le16(block_ack_param_set); + win_size = (le16_to_cpu(add_ba_rsp->block_ack_param_set) + & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) + >> BLOCKACKPARAM_WINSIZE_POS; + cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set); + + mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr, + tid, win_size, le16_to_cpu(cmd_addba_req->ssn)); + return 0; +} + +/* + * This function prepares command for deleting a BA request. + * + * Preparation includes - + * - Setting command ID and proper size + * - Setting del BA request buffer + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, void *data_buf) +{ + struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) + &cmd->params.del_ba; + + cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA); + cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN); + memcpy(del_ba, data_buf, sizeof(*del_ba)); + + return 0; +} + +/* + * This function identifies if Rx reordering is needed for a received packet. + * + * In case reordering is required, the function will do the reordering + * before sending it to kernel. + * + * The Rx reorder table is checked first with the received TID/TA pair. If + * not found, the received packet is dispatched immediately. But if found, + * the packet is reordered and all the packets in the updated Rx reordering + * table is dispatched until a hole is found. + * + * For sequence number less than the starting window, the packet is dropped. + */ +int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, + u16 seq_num, u16 tid, + u8 *ta, u8 pkt_type, void *payload) +{ + struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + int start_win, end_win, win_size; + int ret = 0; + u16 pkt_index = 0; + + rx_reor_tbl_ptr = + mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, + tid, ta); + if (!rx_reor_tbl_ptr) { + if (pkt_type != PKT_TYPE_BAR) + mwifiex_11n_dispatch_pkt(priv, payload); + return 0; + } + start_win = rx_reor_tbl_ptr->start_win; + win_size = rx_reor_tbl_ptr->win_size; + end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); + del_timer(&rx_reor_tbl_ptr->timer_context.timer); + mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies + + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); + + /* + * If seq_num is less then starting win then ignore and drop the + * packet + */ + if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ + if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1)) + && (seq_num < start_win)) + return -1; + } else if ((seq_num < start_win) + || (seq_num > (start_win + (TWOPOW11)))) { + return -1; + } + + /* + * If this packet is a BAR we adjust seq_num as + * WinStart = seq_num + */ + if (pkt_type == PKT_TYPE_BAR) + seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); + + if (((end_win < start_win) + && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) + && (seq_num > end_win)) || ((end_win > start_win) + && ((seq_num > end_win) || (seq_num < start_win)))) { + end_win = seq_num; + if (((seq_num - win_size) + 1) >= 0) + start_win = (end_win - win_size) + 1; + else + start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; + ret = mwifiex_11n_dispatch_pkt_until_start_win(priv, + rx_reor_tbl_ptr, start_win); + + if (ret) + return ret; + } + + if (pkt_type != PKT_TYPE_BAR) { + if (seq_num >= start_win) + pkt_index = seq_num - start_win; + else + pkt_index = (seq_num+MAX_TID_VALUE) - start_win; + + if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index]) + return -1; + + rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload; + } + + /* + * Dispatch all packets sequentially from start_win until a + * hole is found and adjust the start_win appropriately + */ + ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); + + return ret; +} + +/* + * This function deletes an entry for a given TID/TA pair. + * + * The TID/TA are taken from del BA event body. + */ +void +mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, + u8 *peer_mac, u8 type, int initiator) +{ + struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_tx_ba_stream_tbl *ptx_tbl; + u8 cleanup_rx_reorder_tbl; + unsigned long flags; + + if (type == TYPE_DELBA_RECEIVE) + cleanup_rx_reorder_tbl = (initiator) ? true : false; + else + cleanup_rx_reorder_tbl = (initiator) ? false : true; + + dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, " + "initiator=%d\n", peer_mac, tid, initiator); + + if (cleanup_rx_reorder_tbl) { + rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + peer_mac); + if (!rx_reor_tbl_ptr) { + dev_dbg(priv->adapter->dev, + "event: TID, TA not found in table\n"); + return; + } + mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr); + } else { + ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac); + if (!ptx_tbl) { + dev_dbg(priv->adapter->dev, + "event: TID, RA not found in table\n"); + return; + } + + spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); + mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl); + spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); + } +} + +/* + * This function handles the command response of an add BA response. + * + * Handling includes changing the header fields into CPU format and + * creating the stream, provided the add BA is accepted. + */ +int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = + (struct host_cmd_ds_11n_addba_rsp *) + &resp->params.add_ba_rsp; + int tid, win_size; + struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr = NULL; + uint16_t block_ack_param_set; + + block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); + + tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) + >> BLOCKACKPARAM_TID_POS; + /* + * Check if we had rejected the ADDBA, if yes then do not create + * the stream + */ + if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { + win_size = (block_ack_param_set & + IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) + >> BLOCKACKPARAM_WINSIZE_POS; + + dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM" + " tid=%d ssn=%d win_size=%d\n", + add_ba_rsp->peer_mac_addr, + tid, add_ba_rsp->ssn, win_size); + } else { + dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", + add_ba_rsp->peer_mac_addr, tid); + + rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, + tid, add_ba_rsp->peer_mac_addr); + if (rx_reor_tbl_ptr) + mwifiex_11n_delete_rx_reorder_tbl_entry(priv, + rx_reor_tbl_ptr); + } + + return 0; +} + +/* + * This function handles BA stream timeout event by preparing and sending + * a command to the firmware. + */ +void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, + struct host_cmd_ds_11n_batimeout *event) +{ + struct host_cmd_ds_11n_delba delba; + + memset(&delba, 0, sizeof(struct host_cmd_ds_11n_delba)); + memcpy(delba.peer_mac_addr, event->peer_mac_addr, ETH_ALEN); + + delba.del_ba_param_set |= + cpu_to_le16((u16) event->tid << DELBA_TID_POS); + delba.del_ba_param_set |= cpu_to_le16( + (u16) event->origninator << DELBA_INITIATOR_POS); + delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); + mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); + + return; +} + +/* + * This function cleans up the Rx reorder table by deleting all the entries + * and re-initializing. + */ +void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) +{ + struct mwifiex_rx_reorder_tbl *del_tbl_ptr, *tmp_node; + unsigned long flags; + + spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); + list_for_each_entry_safe(del_tbl_ptr, tmp_node, + &priv->rx_reorder_tbl_ptr, list) { + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); + mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr); + spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); + } + spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); + + INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); + memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); +} diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h new file mode 100644 index 000000000000..42f569035745 --- /dev/null +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -0,0 +1,67 @@ +/* + * Marvell Wireless LAN device driver: 802.11n RX Re-ordering + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_11N_RXREORDER_H_ +#define _MWIFIEX_11N_RXREORDER_H_ + +#define MIN_FLUSH_TIMER_MS 50 + +#define PKT_TYPE_BAR 0xE7 +#define MAX_TID_VALUE (2 << 11) +#define TWOPOW11 (2 << 10) + +#define BLOCKACKPARAM_TID_POS 2 +#define BLOCKACKPARAM_AMSDU_SUPP_MASK 0x1 +#define BLOCKACKPARAM_WINSIZE_POS 6 +#define DELBA_TID_POS 12 +#define DELBA_INITIATOR_POS 11 +#define TYPE_DELBA_SENT 1 +#define TYPE_DELBA_RECEIVE 2 +#define IMMEDIATE_BLOCK_ACK 0x2 + +#define ADDBA_RSP_STATUS_ACCEPT 0 + +int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, + u16 seqNum, + u16 tid, u8 *ta, + u8 pkttype, void *payload); +void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid, + u8 *PeerMACAddr, u8 type, + int initiator); +void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, + struct host_cmd_ds_11n_batimeout *event); +int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, + struct host_cmd_ds_command + *resp); +int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf); +int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, + struct host_cmd_ds_command + *cmd, void *data_buf); +int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf); +void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); +struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct + mwifiex_private + *priv, int tid, + u8 *ta); + +#endif /* _MWIFIEX_11N_RXREORDER_H_ */ diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig new file mode 100644 index 000000000000..86962920cef3 --- /dev/null +++ b/drivers/net/wireless/mwifiex/Kconfig @@ -0,0 +1,21 @@ +config MWIFIEX + tristate "Marvell WiFi-Ex Driver" + depends on CFG80211 + select LIB80211 + ---help--- + This adds support for wireless adapters based on Marvell + 802.11n chipsets. + + If you choose to build it as a module, it will be called + mwifiex. + +config MWIFIEX_SDIO + tristate "Marvell WiFi-Ex Driver for SD8787" + depends on MWIFIEX && MMC + select FW_LOADER + ---help--- + This adds support for wireless adapters based on Marvell + 8787 chipset with SDIO interface. + + If you choose to build it as a module, it will be called + mwifiex_sdio. diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile new file mode 100644 index 000000000000..42cb733ea33a --- /dev/null +++ b/drivers/net/wireless/mwifiex/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2011, Marvell International Ltd. +# +# This software file (the "File") is distributed by Marvell International +# Ltd. under the terms of the GNU General Public License Version 2, June 1991 +# (the "License"). You may use, redistribute and/or modify this File in +# accordance with the terms and conditions of the License, a copy of which +# is available by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the +# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. +# +# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE +# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE +# ARE EXPRESSLY DISCLAIMED. The License provides additional details about +# this warranty disclaimer. + + +mwifiex-y += main.o +mwifiex-y += init.o +mwifiex-y += cfp.o +mwifiex-y += cmdevt.o +mwifiex-y += util.o +mwifiex-y += txrx.o +mwifiex-y += wmm.o +mwifiex-y += 11n.o +mwifiex-y += 11n_aggr.o +mwifiex-y += 11n_rxreorder.o +mwifiex-y += scan.o +mwifiex-y += join.o +mwifiex-y += sta_ioctl.o +mwifiex-y += sta_cmd.o +mwifiex-y += sta_cmdresp.o +mwifiex-y += sta_event.o +mwifiex-y += sta_tx.o +mwifiex-y += sta_rx.o +mwifiex-y += cfg80211.o +mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o +obj-$(CONFIG_MWIFIEX) += mwifiex.o + +mwifiex_sdio-y += sdio.o +obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README new file mode 100644 index 000000000000..338377f7093b --- /dev/null +++ b/drivers/net/wireless/mwifiex/README @@ -0,0 +1,204 @@ +# Copyright (C) 2011, Marvell International Ltd. +# +# This software file (the "File") is distributed by Marvell International +# Ltd. under the terms of the GNU General Public License Version 2, June 1991 +# (the "License"). You may use, redistribute and/or modify this File in +# accordance with the terms and conditions of the License, a copy of which +# is available by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the +# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. +# +# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE +# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE +# ARE EXPRESSLY DISCLAIMED. The License provides additional details about +# this warranty disclaimer. + + +=============================================================================== + U S E R M A N U A L + +1) FOR DRIVER INSTALL + + a) Copy sd8787.bin to /lib/firmware/mrvl/ directory, + create the directory if it doesn't exist. + b) Install WLAN driver, + insmod mwifiex.ko + c) Uninstall WLAN driver, + ifconfig mlanX down + rmmod mwifiex + + +2) FOR DRIVER CONFIGURATION AND INFO + The configurations can be done either using the 'iw' user space + utility or debugfs. + + a) 'iw' utility commands + + Following are some useful iw commands:- + +iw dev mlan0 scan + + This command will trigger a scan. + The command will then display the scan table entries + +iw dev mlan0 connect -w [] [] [key 0:abcde d:1123456789a] + The above command can be used to connect to an AP with a particular SSID. + Ap's operating frequency can be specified or even the bssid. If the AP is using + WEP encryption, wep keys can be specified in the command. + Note: Every time before connecting to an AP scan command (iw dev mlan0 scan) should be used by user. + +iw dev mlan0 disconnect + This command will be used to disconnect from an AP. + + +iw dev mlan0 ibss join [fixed-freq] [fixed-bssid] [key 0:abcde] + The command will be used to join or create an ibss. Optionally, operating frequency, + bssid and the security related parameters can be specified while joining/creating + and ibss. + +iw dev mlan0 ibss leave + The command will be used to leave an ibss network. + +iw dev mlan0 link + The command will be used to get the connection status. The command will return parameters + such as SSID, operating frequency, rx/tx packets, signal strength, tx bitrate. + + Apart from the iw utility all standard configurations using the 'iwconfig' utility are also supported. + + b) Debugfs interface + + The debugfs interface can be used for configurations and for getting + some useful information from the driver. + The section below explains the configurations that can be + done. + + Mount debugfs to /debugfs mount point: + + mkdir /debugfs + mount -t debugfs debugfs /debugfs + + The information is provided in /debugfs/mwifiex/mlanX/: + +iw reg set + The command will be used to change the regulatory domain. + +iw reg get + The command will be used to get current regulatory domain. + +info + This command is used to get driver info. + + Usage: + cat info + + driver_name = "mwifiex" + driver_version = + interface_name = "mlanX" + bss_mode = "Ad-hoc" | "Managed" | "Auto" | "Unknown" + media_state = "Disconnected" | "Connected" + mac_address = <6-byte adapter MAC address> + multicase_count = + essid = + bssid = + channel = + region_code = + multicasr_address[n] = + num_tx_bytes = + num_rx_bytes = + num_tx_pkts = + num_rx_pkts = + num_tx_pkts_dropped = + num_rx_pkts_dropped = + num_tx_pkts_err = + num_rx_pkts_err = + carrier "on" | "off" + tx queue "stopped" | "started" + + The following debug info are provided in /debugfs/mwifiex/mlanX/debug: + + int_counter = + wmm_ac_vo = + wmm_ac_vi = + wmm_ac_be = + wmm_ac_bk = + max_tx_buf_size = + tx_buf_size = + curr_tx_buf_size = + ps_mode = <0/1, CAM mode/PS mode> + ps_state = <0/1/2/3, full power state/awake state/pre-sleep state/sleep state> + is_deep_sleep = <0/1, not deep sleep state/deep sleep state> + wakeup_dev_req = <0/1, wakeup device not required/required> + wakeup_tries = + hs_configured = <0/1, host sleep not configured/configured> + hs_activated = <0/1, extended host sleep not activated/activated> + num_tx_timeout = + num_cmd_timeout = + timeout_cmd_id = + timeout_cmd_act = + last_cmd_id = + last_cmd_act = + last_cmd_index = <0 based last command index> + last_cmd_resp_id = + last_cmd_resp_index = <0 based last command response index> + last_event = + last_event_index = <0 based last event index> + num_cmd_h2c_fail = + num_cmd_sleep_cfm_fail = + num_tx_h2c_fail = + num_evt_deauth = + num_evt_disassoc = + num_evt_link_lost = + num_cmd_deauth = + num_cmd_assoc_ok = + num_cmd_assoc_fail = + cmd_sent = <0/1, send command resources available/sending command to device> + data_sent = <0/1, send data resources available/sending data to device> + mp_rd_bitmap = + mp_wr_bitmap = + cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> + event_received = <0/1, no event to process/event received and yet to process> + ioctl_pending = + tx_pending = + rx_pending = + + +3) FOR DRIVER CONFIGURATION + +regrdwr + This command is used to read/write the adapter register. + + Usage: + echo " [value]" > regrdwr + cat regrdwr + + where the parameters are, + : 1:MAC/SOC, 2:BBP, 3:RF, 4:PMIC, 5:CAU + : offset of register + [value]: value to be written + + Examples: + echo "1 0xa060" > regrdwr : Read the MAC register + echo "1 0xa060 0x12" > regrdwr : Write the MAC register + echo "1 0xa794 0x80000000" > regrdwr + : Write 0x80000000 to MAC register +rdeeprom + This command is used to read the EEPROM contents of the card. + + Usage: + echo " " > rdeeprom + cat rdeeprom + + where the parameters are, + : multiples of 4 + : 4-20, multiples of 4 + + Example: + echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0 + +getlog + This command is used to get the statistics available in the station. + Usage: + + cat getlog + +=============================================================================== diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c new file mode 100644 index 000000000000..80f367f27efc --- /dev/null +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -0,0 +1,1517 @@ +/* + * Marvell Wireless LAN device driver: CFG80211 + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "cfg80211.h" +#include "main.h" + +/* + * This function maps the nl802.11 channel type into driver channel type. + * + * The mapping is as follows - + * NL80211_CHAN_NO_HT -> NO_SEC_CHANNEL + * NL80211_CHAN_HT20 -> NO_SEC_CHANNEL + * NL80211_CHAN_HT40PLUS -> SEC_CHANNEL_ABOVE + * NL80211_CHAN_HT40MINUS -> SEC_CHANNEL_BELOW + * Others -> NO_SEC_CHANNEL + */ +static int +mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type + channel_type) +{ + int channel; + switch (channel_type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + channel = NO_SEC_CHANNEL; + break; + case NL80211_CHAN_HT40PLUS: + channel = SEC_CHANNEL_ABOVE; + break; + case NL80211_CHAN_HT40MINUS: + channel = SEC_CHANNEL_BELOW; + break; + default: + channel = NO_SEC_CHANNEL; + } + return channel; +} + +/* + * This function maps the driver channel type into nl802.11 channel type. + * + * The mapping is as follows - + * NO_SEC_CHANNEL -> NL80211_CHAN_HT20 + * SEC_CHANNEL_ABOVE -> NL80211_CHAN_HT40PLUS + * SEC_CHANNEL_BELOW -> NL80211_CHAN_HT40MINUS + * Others -> NL80211_CHAN_HT20 + */ +static enum nl80211_channel_type +mwifiex_channels_to_cfg80211_channel_type(int channel_type) +{ + int channel; + switch (channel_type) { + case NO_SEC_CHANNEL: + channel = NL80211_CHAN_HT20; + break; + case SEC_CHANNEL_ABOVE: + channel = NL80211_CHAN_HT40PLUS; + break; + case SEC_CHANNEL_BELOW: + channel = NL80211_CHAN_HT40MINUS; + break; + default: + channel = NL80211_CHAN_HT20; + } + return channel; +} + +/* + * This function checks whether WEP is set. + */ +static int +mwifiex_is_alg_wep(u32 cipher) +{ + int alg = 0; + + switch (cipher) { + case MWIFIEX_ENCRYPTION_MODE_WEP40: + case MWIFIEX_ENCRYPTION_MODE_WEP104: + alg = 1; + break; + default: + alg = 0; + break; + } + return alg; +} + +/* + * This function maps the given cipher type into driver specific type. + * + * It also sets a flag to indicate whether WPA is enabled or not. + * + * The mapping table is - + * Input cipher Driver cipher type WPA enabled? + * ------------ ------------------ ------------ + * IW_AUTH_CIPHER_NONE MWIFIEX_ENCRYPTION_MODE_NONE No + * WLAN_CIPHER_SUITE_WEP40 MWIFIEX_ENCRYPTION_MODE_WEP40 No + * WLAN_CIPHER_SUITE_WEP104 MWIFIEX_ENCRYPTION_MODE_WEP104 No + * WLAN_CIPHER_SUITE_TKIP MWIFIEX_ENCRYPTION_MODE_TKIP Yes + * WLAN_CIPHER_SUITE_CCMP MWIFIEX_ENCRYPTION_MODE_CCMP Yes + * Others -1 No + */ +static int +mwifiex_get_mwifiex_cipher(u32 cipher, int *wpa_enabled) +{ + int encrypt_mode; + + if (wpa_enabled) + *wpa_enabled = 0; + switch (cipher) { + case IW_AUTH_CIPHER_NONE: + encrypt_mode = MWIFIEX_ENCRYPTION_MODE_NONE; + break; + case WLAN_CIPHER_SUITE_WEP40: + encrypt_mode = MWIFIEX_ENCRYPTION_MODE_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + encrypt_mode = MWIFIEX_ENCRYPTION_MODE_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + encrypt_mode = MWIFIEX_ENCRYPTION_MODE_TKIP; + if (wpa_enabled) + *wpa_enabled = 1; + break; + case WLAN_CIPHER_SUITE_CCMP: + encrypt_mode = MWIFIEX_ENCRYPTION_MODE_CCMP; + if (wpa_enabled) + *wpa_enabled = 1; + break; + default: + encrypt_mode = -1; + } + + return encrypt_mode; +} + +/* + * This function retrieves the private structure from kernel wiphy structure. + */ +static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy) +{ + return (void *) (*(unsigned long *) wiphy_priv(wiphy)); +} + +/* + * CFG802.11 operation handler to delete a network key. + */ +static int +mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, + u8 key_index, bool pairwise, const u8 *mac_addr) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + int ret = 0; + + ret = mwifiex_set_encode(priv, NULL, 0, key_index, 1); + if (ret) { + wiphy_err(wiphy, "deleting the crypto keys\n"); + return -EFAULT; + } + + wiphy_dbg(wiphy, "info: crypto keys deleted\n"); + return 0; +} + +/* + * CFG802.11 operation handler to set Tx power. + */ +static int +mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, + enum nl80211_tx_power_setting type, + int dbm) +{ + int ret = 0; + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + + ret = mwifiex_set_tx_power(priv, type, dbm); + + return ret; +} + +/* + * CFG802.11 operation handler to set Power Save option. + * + * The timeout value, if provided, is currently ignored. + */ +static int +mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, + bool enabled, int timeout) +{ + int ret = 0; + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + + if (timeout) + wiphy_dbg(wiphy, + "info: ignoring the timeout value" + " for IEEE power save\n"); + + ret = mwifiex_drv_set_power(priv, enabled); + + return ret; +} + +/* + * CFG802.11 operation handler to set the default network key. + */ +static int +mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, + u8 key_index, bool unicast, + bool multicast) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + int ret; + + ret = mwifiex_set_encode(priv, NULL, 0, key_index, 0); + + wiphy_dbg(wiphy, "info: set default Tx key index\n"); + + if (ret) + return -EFAULT; + + return 0; +} + +/* + * CFG802.11 operation handler to add a network key. + */ +static int +mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + int ret = 0; + int encrypt_mode; + + encrypt_mode = mwifiex_get_mwifiex_cipher(params->cipher, NULL); + + if (encrypt_mode != -1) + ret = mwifiex_set_encode(priv, params->key, params->key_len, + key_index, 0); + + wiphy_dbg(wiphy, "info: crypto keys added\n"); + + if (ret) + return -EFAULT; + + return 0; +} + +/* + * This function sends domain information to the firmware. + * + * The following information are passed to the firmware - + * - Country codes + * - Sub bands (first channel, number of channels, maximum Tx power) + */ +static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) +{ + u8 no_of_triplet = 0; + struct ieee80211_country_ie_triplet *t; + u8 no_of_parsed_chan = 0; + u8 first_chan = 0, next_chan = 0, max_pwr = 0; + u8 i, flag = 0; + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg; + int ret = 0; + + /* Set country code */ + domain_info->country_code[0] = priv->country_code[0]; + domain_info->country_code[1] = priv->country_code[1]; + domain_info->country_code[2] = ' '; + + band = mwifiex_band_to_radio_type(adapter->config_bands); + if (!wiphy->bands[band]) { + wiphy_err(wiphy, "11D: setting domain info in FW\n"); + return -1; + } + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels ; i++) { + ch = &sband->channels[i]; + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (!flag) { + flag = 1; + first_chan = (u32) ch->hw_value; + next_chan = first_chan; + max_pwr = ch->max_power; + no_of_parsed_chan = 1; + continue; + } + + if (ch->hw_value == next_chan + 1 && + ch->max_power == max_pwr) { + next_chan++; + no_of_parsed_chan++; + } else { + t = &domain_info->triplet[no_of_triplet]; + t->chans.first_channel = first_chan; + t->chans.num_channels = no_of_parsed_chan; + t->chans.max_power = max_pwr; + no_of_triplet++; + first_chan = (u32) ch->hw_value; + next_chan = first_chan; + max_pwr = ch->max_power; + no_of_parsed_chan = 1; + } + } + + if (flag) { + t = &domain_info->triplet[no_of_triplet]; + t->chans.first_channel = first_chan; + t->chans.num_channels = no_of_parsed_chan; + t->chans.max_power = max_pwr; + no_of_triplet++; + } + + domain_info->no_of_triplet = no_of_triplet; + /* Send cmd to FW to set domain info */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, + HostCmd_ACT_GEN_SET, 0, NULL, NULL); + if (ret) + wiphy_err(wiphy, "11D: setting domain info in FW\n"); + + return ret; +} + +/* + * CFG802.11 regulatory domain callback function. + * + * This function is called when the regulatory domain is changed due to the + * following reasons - + * - Set by driver + * - Set by system core + * - Set by user + * - Set bt Country IE + */ +static int mwifiex_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + + wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain" + " %c%c\n", request->alpha2[0], request->alpha2[1]); + + memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + break; + /* Todo: apply driver specific changes in channel flags based + on the request initiator if necessary. */ + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + break; + } + mwifiex_send_domain_info_cmd_fw(wiphy); + + return 0; +} + +/* + * This function sets the RF channel. + * + * This function creates multiple IOCTL requests, populates them accordingly + * and issues them to set the band/channel and frequency. + */ +static int +mwifiex_set_rf_channel(struct mwifiex_private *priv, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) +{ + struct mwifiex_chan_freq_power cfp; + int ret = 0; + int status = 0; + struct mwifiex_ds_band_cfg band_cfg; + int mode; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + u32 config_bands = 0; + struct wiphy *wiphy = priv->wdev->wiphy; + + mode = mwifiex_drv_get_mode(priv, wait_option); + + if (chan) { + memset(&band_cfg, 0, sizeof(band_cfg)); + /* Set appropriate bands */ + if (chan->band == IEEE80211_BAND_2GHZ) + config_bands = BAND_B | BAND_G | BAND_GN; + else + config_bands = BAND_AN | BAND_A; + if (mode == MWIFIEX_BSS_MODE_INFRA + || mode == MWIFIEX_BSS_MODE_AUTO) { + band_cfg.config_bands = config_bands; + } else if (mode == MWIFIEX_BSS_MODE_IBSS) { + band_cfg.config_bands = config_bands; + band_cfg.adhoc_start_band = config_bands; + } + /* Set channel offset */ + band_cfg.sec_chan_offset = + mwifiex_cfg80211_channel_type_to_mwifiex_channels + (channel_type); + status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, + &band_cfg); + + if (status) + return -EFAULT; + mwifiex_send_domain_info_cmd_fw(wiphy); + } + + wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " + "mode %d\n", config_bands, band_cfg.sec_chan_offset, mode); + if (!chan) + return ret; + + memset(&cfp, 0, sizeof(cfp)); + cfp.freq = chan->center_freq; + /* Convert frequency to channel */ + cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); + + status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); + if (status) + return -EFAULT; + + ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); + + return ret; +} + +/* + * CFG802.11 operation handler to set channel. + * + * This function can only be used when station is not connected. + */ +static int +mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + + if (priv->media_connected) { + wiphy_err(wiphy, "This setting is valid only when station " + "is not connected\n"); + return -EINVAL; + } + + return mwifiex_set_rf_channel(priv, chan, channel_type); +} + +/* + * This function sets the fragmentation threshold. + * + * This function creates an IOCTL request, populates it accordingly + * and issues an IOCTL. + * + * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE + * and MWIFIEX_FRAG_MAX_VALUE. + */ +static int +mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) +{ + int ret = 0; + int status = 0; + struct mwifiex_wait_queue *wait = NULL; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + + if (frag_thr < MWIFIEX_FRAG_MIN_VALUE + || frag_thr > MWIFIEX_FRAG_MAX_VALUE) + return -EINVAL; + + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I, + HostCmd_ACT_GEN_SET, &frag_thr); + + if (mwifiex_request_ioctl(priv, wait, status, wait_option)) + ret = -EFAULT; + + kfree(wait); + return ret; +} + +/* + * This function sets the RTS threshold. + * + * This function creates an IOCTL request, populates it accordingly + * and issues an IOCTL. + */ +static int +mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) +{ + int ret = 0; + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + + if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) + rts_thr = MWIFIEX_RTS_MAX_VALUE; + + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I, + HostCmd_ACT_GEN_SET, &rts_thr); + + if (mwifiex_request_ioctl(priv, wait, status, wait_option)) + ret = -EFAULT; + + kfree(wait); + return ret; +} + +/* + * CFG802.11 operation handler to set wiphy parameters. + * + * This function can be used to set the RTS threshold and the + * Fragmentation threshold of the driver. + */ +static int +mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + + int ret = 0; + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) + ret = mwifiex_set_rts(priv, wiphy->rts_threshold); + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) + ret = mwifiex_set_frag(priv, wiphy->frag_threshold); + + return ret; +} + +/* + * CFG802.11 operation handler to change interface type. + * + * This function creates an IOCTL request, populates it accordingly + * and issues an IOCTL. + * + * The function also maps the CFG802.11 mode type into driver mode type. + * NL80211_IFTYPE_ADHOC -> MWIFIEX_BSS_MODE_IBSS + * NL80211_IFTYPE_STATION -> MWIFIEX_BSS_MODE_INFRA + * NL80211_IFTYPE_UNSPECIFIED -> MWIFIEX_BSS_MODE_AUTO + */ +static int +mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, + struct net_device *dev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + int ret = 0; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + int mode = -1; + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + switch (type) { + case NL80211_IFTYPE_ADHOC: + mode = MWIFIEX_BSS_MODE_IBSS; + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; + wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MWIFIEX_BSS_MODE_INFRA; + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + wiphy_dbg(wiphy, "info: Setting interface type to managed\n"); + break; + case NL80211_IFTYPE_UNSPECIFIED: + mode = MWIFIEX_BSS_MODE_AUTO; + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + wiphy_dbg(wiphy, "info: setting interface type to auto\n"); + break; + default: + ret = -EINVAL; + } + if (ret) + goto done; + status = mwifiex_bss_ioctl_mode(priv, wait, HostCmd_ACT_GEN_SET, &mode); + + if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) + ret = -EFAULT; + +done: + kfree(wait); + return ret; +} + +/* + * This function dumps the station information on a buffer. + * + * The following information are shown - + * - Total bytes transmitted + * - Total bytes received + * - Total packets transmitted + * - Total packets received + * - Signal quality level + * - Transmission rate + */ +static int +mwifiex_dump_station_info(struct mwifiex_private *priv, + struct station_info *sinfo) +{ + struct mwifiex_ds_get_signal signal; + struct mwifiex_rate_cfg rate; + int ret = 0; + + sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | + STATION_INFO_RX_PACKETS | + STATION_INFO_TX_PACKETS + | STATION_INFO_SIGNAL | STATION_INFO_TX_BITRATE; + + /* Get signal information from the firmware */ + memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); + if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { + dev_err(priv->adapter->dev, "getting signal information\n"); + ret = -EFAULT; + } + + if (mwifiex_drv_get_data_rate(priv, &rate)) { + dev_err(priv->adapter->dev, "getting data rate\n"); + ret = -EFAULT; + } + + sinfo->rx_bytes = priv->stats.rx_bytes; + sinfo->tx_bytes = priv->stats.tx_bytes; + sinfo->rx_packets = priv->stats.rx_packets; + sinfo->tx_packets = priv->stats.tx_packets; + sinfo->signal = priv->w_stats.qual.level; + sinfo->txrate.legacy = rate.rate; + + return ret; +} + +/* + * CFG802.11 operation handler to get station information. + * + * This function only works in connected mode, and dumps the + * requested station information, if available. + */ +static int +mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, + u8 *mac, struct station_info *sinfo) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + int ret = 0; + + mwifiex_dump_station_info(priv, sinfo); + + if (!priv->media_connected) + return -ENOENT; + if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) + return -ENOENT; + + + ret = mwifiex_dump_station_info(priv, sinfo); + + return ret; +} + +/* Supported rates to be advertised to the cfg80211 */ + +static struct ieee80211_rate mwifiex_rates[] = { + {.bitrate = 10, .hw_value = 2, }, + {.bitrate = 20, .hw_value = 4, }, + {.bitrate = 55, .hw_value = 11, }, + {.bitrate = 110, .hw_value = 22, }, + {.bitrate = 220, .hw_value = 44, }, + {.bitrate = 60, .hw_value = 12, }, + {.bitrate = 90, .hw_value = 18, }, + {.bitrate = 120, .hw_value = 24, }, + {.bitrate = 180, .hw_value = 36, }, + {.bitrate = 240, .hw_value = 48, }, + {.bitrate = 360, .hw_value = 72, }, + {.bitrate = 480, .hw_value = 96, }, + {.bitrate = 540, .hw_value = 108, }, + {.bitrate = 720, .hw_value = 144, }, +}; + +/* Channel definitions to be advertised to cfg80211 */ + +static struct ieee80211_channel mwifiex_channels_2ghz[] = { + {.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_supported_band mwifiex_band_2ghz = { + .channels = mwifiex_channels_2ghz, + .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), + .bitrates = mwifiex_rates, + .n_bitrates = 14, +}; + +static struct ieee80211_channel mwifiex_channels_5ghz[] = { + {.center_freq = 5040, .hw_value = 8, }, + {.center_freq = 5060, .hw_value = 12, }, + {.center_freq = 5080, .hw_value = 16, }, + {.center_freq = 5170, .hw_value = 34, }, + {.center_freq = 5190, .hw_value = 38, }, + {.center_freq = 5210, .hw_value = 42, }, + {.center_freq = 5230, .hw_value = 46, }, + {.center_freq = 5180, .hw_value = 36, }, + {.center_freq = 5200, .hw_value = 40, }, + {.center_freq = 5220, .hw_value = 44, }, + {.center_freq = 5240, .hw_value = 48, }, + {.center_freq = 5260, .hw_value = 52, }, + {.center_freq = 5280, .hw_value = 56, }, + {.center_freq = 5300, .hw_value = 60, }, + {.center_freq = 5320, .hw_value = 64, }, + {.center_freq = 5500, .hw_value = 100, }, + {.center_freq = 5520, .hw_value = 104, }, + {.center_freq = 5540, .hw_value = 108, }, + {.center_freq = 5560, .hw_value = 112, }, + {.center_freq = 5580, .hw_value = 116, }, + {.center_freq = 5600, .hw_value = 120, }, + {.center_freq = 5620, .hw_value = 124, }, + {.center_freq = 5640, .hw_value = 128, }, + {.center_freq = 5660, .hw_value = 132, }, + {.center_freq = 5680, .hw_value = 136, }, + {.center_freq = 5700, .hw_value = 140, }, + {.center_freq = 5745, .hw_value = 149, }, + {.center_freq = 5765, .hw_value = 153, }, + {.center_freq = 5785, .hw_value = 157, }, + {.center_freq = 5805, .hw_value = 161, }, + {.center_freq = 5825, .hw_value = 165, }, +}; + +static struct ieee80211_supported_band mwifiex_band_5ghz = { + .channels = mwifiex_channels_5ghz, + .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), + .bitrates = mwifiex_rates - 4, + .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4, +}; + + +/* Supported crypto cipher suits to be advertised to cfg80211 */ + +static const u32 mwifiex_cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, +}; + +/* + * CFG802.11 operation handler for disconnection request. + * + * This function does not work when there is already a disconnection + * procedure going on. + */ +static int +mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, + u16 reason_code) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + + if (priv->disconnect) + return -EBUSY; + + priv->disconnect = 1; + if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) + return -EFAULT; + + wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" + " reason code %d\n", priv->cfg_bssid, reason_code); + + queue_work(priv->workqueue, &priv->cfg_workqueue); + + return 0; +} + +/* + * This function informs the CFG802.11 subsystem of a new IBSS. + * + * The following information are sent to the CFG802.11 subsystem + * to register the new IBSS. If we do not register the new IBSS, + * a kernel panic will result. + * - SSID + * - SSID length + * - BSSID + * - Channel + */ +static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) +{ + int ret = 0; + struct ieee80211_channel *chan; + struct mwifiex_bss_info bss_info; + int ie_len = 0; + u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; + + ret = mwifiex_get_bss_info(priv, &bss_info); + if (ret) + return ret; + + ie_buf[0] = WLAN_EID_SSID; + ie_buf[1] = bss_info.ssid.ssid_len; + + memcpy(&ie_buf[sizeof(struct ieee_types_header)], + &bss_info.ssid.ssid, + bss_info.ssid.ssid_len); + ie_len = ie_buf[1] + sizeof(struct ieee_types_header); + + chan = __ieee80211_get_channel(priv->wdev->wiphy, + ieee80211_channel_to_frequency(bss_info.bss_chan, + priv->curr_bss_params.band)); + + cfg80211_inform_bss(priv->wdev->wiphy, chan, + bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, + 0, ie_buf, ie_len, 0, GFP_KERNEL); + memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); + + return ret; +} + +/* + * This function informs the CFG802.11 subsystem of a new BSS connection. + * + * The following information are sent to the CFG802.11 subsystem + * to register the new BSS connection. If we do not register the new BSS, + * a kernel panic will result. + * - MAC address + * - Capabilities + * - Beacon period + * - RSSI value + * - Channel + * - Supported rates IE + * - Extended capabilities IE + * - DS parameter set IE + * - HT Capability IE + * - Vendor Specific IE (221) + * - WPA IE + * - RSN IE + */ +static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, + struct mwifiex_802_11_ssid *ssid) +{ + struct mwifiex_scan_resp scan_resp; + struct mwifiex_bssdescriptor *scan_table; + int i, j; + struct ieee80211_channel *chan; + u8 *ie, *tmp, *ie_buf; + u32 ie_len; + u64 ts = 0; + u8 *beacon; + int beacon_size; + u8 element_id, element_len; + + memset(&scan_resp, 0, sizeof(scan_resp)); + if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) + return -EFAULT; + +#define MAX_IE_BUF 2048 + ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); + if (!ie_buf) { + dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n", + __func__); + return -ENOMEM; + } + + scan_table = (struct mwifiex_bssdescriptor *) scan_resp.scan_table; + for (i = 0; i < scan_resp.num_in_scan_table; i++) { + if (ssid) { + /* Inform specific BSS only */ + if (memcmp(ssid->ssid, scan_table[i].ssid.ssid, + ssid->ssid_len)) + continue; + } + memset(ie_buf, 0, MAX_IE_BUF); + ie_buf[0] = WLAN_EID_SSID; + ie_buf[1] = scan_table[i].ssid.ssid_len; + memcpy(&ie_buf[sizeof(struct ieee_types_header)], + scan_table[i].ssid.ssid, ie_buf[1]); + + ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header); + ie_len = ie_buf[1] + sizeof(struct ieee_types_header); + + ie[0] = WLAN_EID_SUPP_RATES; + + for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) { + if (!scan_table[i].supported_rates[j]) + break; + else + ie[j + sizeof(struct ieee_types_header)] = + scan_table[i].supported_rates[j]; + } + + ie[1] = j; + ie_len += ie[1] + sizeof(struct ieee_types_header); + + beacon = scan_table[i].beacon_buf; + beacon_size = scan_table[i].beacon_buf_size; + + /* Skip time stamp, beacon interval and capability */ + + if (beacon) { + beacon += sizeof(scan_table[i].beacon_period) + + sizeof(scan_table[i].time_stamp) + + +sizeof(scan_table[i].cap_info_bitmap); + + beacon_size -= sizeof(scan_table[i].beacon_period) + + sizeof(scan_table[i].time_stamp) + + sizeof(scan_table[i].cap_info_bitmap); + } + + while (beacon_size >= sizeof(struct ieee_types_header)) { + ie = ie_buf + ie_len; + element_id = *beacon; + element_len = *(beacon + 1); + if (beacon_size < (int) element_len + + sizeof(struct ieee_types_header)) { + dev_err(priv->adapter->dev, "%s: in processing" + " IE, bytes left < IE length\n", + __func__); + break; + } + switch (element_id) { + case WLAN_EID_EXT_CAPABILITY: + case WLAN_EID_DS_PARAMS: + case WLAN_EID_HT_CAPABILITY: + case WLAN_EID_VENDOR_SPECIFIC: + case WLAN_EID_RSN: + case WLAN_EID_BSS_AC_ACCESS_DELAY: + ie[0] = element_id; + ie[1] = element_len; + tmp = (u8 *) beacon; + memcpy(&ie[sizeof(struct ieee_types_header)], + tmp + sizeof(struct ieee_types_header), + element_len); + ie_len += ie[1] + + sizeof(struct ieee_types_header); + break; + default: + break; + } + beacon += element_len + + sizeof(struct ieee_types_header); + beacon_size -= element_len + + sizeof(struct ieee_types_header); + } + chan = ieee80211_get_channel(priv->wdev->wiphy, + scan_table[i].freq); + cfg80211_inform_bss(priv->wdev->wiphy, chan, + scan_table[i].mac_address, + ts, scan_table[i].cap_info_bitmap, + scan_table[i].beacon_period, + ie_buf, ie_len, + scan_table[i].rssi, GFP_KERNEL); + } + + kfree(ie_buf); + return 0; +} + +/* + * This function connects with a BSS. + * + * This function handles both Infra and Ad-Hoc modes. It also performs + * validity checking on the provided parameters, disconnects from the + * current BSS (if any), sets up the association/scan parameters, + * including security settings, and performs specific SSID scan before + * trying to connect. + * + * For Infra mode, the function returns failure if the specified SSID + * is not found in scan table. However, for Ad-Hoc mode, it can create + * the IBSS if it does not exist. On successful completion in either case, + * the function notifies the CFG802.11 subsystem of the new BSS connection, + * otherwise the kernel will panic. + */ +static int +mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, + u8 *bssid, int mode, struct ieee80211_channel *channel, + struct cfg80211_connect_params *sme, bool privacy) +{ + struct mwifiex_802_11_ssid req_ssid; + struct mwifiex_ssid_bssid ssid_bssid; + int ret = 0; + int auth_type = 0, pairwise_encrypt_mode = 0, wpa_enabled = 0; + int group_encrypt_mode = 0; + int alg_is_wep = 0; + + memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); + memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); + + req_ssid.ssid_len = ssid_len; + if (ssid_len > IEEE80211_MAX_SSID_LEN) { + dev_err(priv->adapter->dev, "invalid SSID - aborting\n"); + return -EINVAL; + } + + memcpy(req_ssid.ssid, ssid, ssid_len); + if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) { + dev_err(priv->adapter->dev, "invalid SSID - aborting\n"); + return -EINVAL; + } + + /* disconnect before try to associate */ + mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); + + if (channel) + ret = mwifiex_set_rf_channel(priv, channel, + mwifiex_channels_to_cfg80211_channel_type + (priv->adapter->chan_offset)); + + ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ + + if (mode == MWIFIEX_BSS_MODE_IBSS) { + /* "privacy" is set only for ad-hoc mode */ + if (privacy) { + /* + * Keep MWIFIEX_ENCRYPTION_MODE_WEP104 for now so that + * the firmware can find a matching network from the + * scan. The cfg80211 does not give us the encryption + * mode at this stage so just setting it to WEP here. + */ + wpa_enabled = 0; + auth_type = MWIFIEX_AUTH_MODE_OPEN; + ret = mwifiex_set_auth(priv, + MWIFIEX_ENCRYPTION_MODE_WEP104, + auth_type, wpa_enabled); + } + + goto done; + } + + /* Now handle infra mode. "sme" is valid for infra mode only */ + if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC + || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) + auth_type = MWIFIEX_AUTH_MODE_OPEN; + else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) + auth_type = MWIFIEX_AUTH_MODE_SHARED; + + if (sme->crypto.n_ciphers_pairwise) { + pairwise_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. + ciphers_pairwise[0], &wpa_enabled); + ret = mwifiex_set_auth(priv, pairwise_encrypt_mode, auth_type, + wpa_enabled); + } + + if (sme->crypto.cipher_group) { + group_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. + cipher_group, &wpa_enabled); + ret = mwifiex_set_auth(priv, group_encrypt_mode, auth_type, + wpa_enabled); + } + if (sme->ie) + ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); + + if (sme->key) { + alg_is_wep = mwifiex_is_alg_wep(pairwise_encrypt_mode) + | mwifiex_is_alg_wep(group_encrypt_mode); + if (alg_is_wep) { + dev_dbg(priv->adapter->dev, + "info: setting wep encryption" + " with key len %d\n", sme->key_len); + ret = mwifiex_set_encode(priv, sme->key, sme->key_len, + sme->key_idx, 0); + } + } +done: + /* Do specific SSID scanning */ + if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { + dev_err(priv->adapter->dev, "scan error\n"); + return -EFAULT; + } + + + memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); + + if (mode != MWIFIEX_BSS_MODE_IBSS) { + if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, + &ssid_bssid)) + return -EFAULT; + /* Inform the BSS information to kernel, otherwise + * kernel will give a panic after successful assoc */ + if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid)) + return -EFAULT; + } + + dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", + (char *) req_ssid.ssid, ssid_bssid.bssid); + + memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6); + + /* Connect to BSS by ESSID */ + memset(&ssid_bssid.bssid, 0, ETH_ALEN); + + if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) + return -EFAULT; + + if (mode == MWIFIEX_BSS_MODE_IBSS) { + /* Inform the BSS information to kernel, otherwise + * kernel will give a panic after successful assoc */ + if (mwifiex_cfg80211_inform_ibss_bss(priv)) + return -EFAULT; + } + + return ret; +} + +/* + * CFG802.11 operation handler for association request. + * + * This function does not work when the current mode is set to Ad-Hoc, or + * when there is already an association procedure going on. The given BSS + * information is used to associate. + */ +static int +mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_connect_params *sme) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + int ret = 0; + int mode = 0; + + if (priv->assoc_request) + return -EBUSY; + + mode = mwifiex_drv_get_mode(priv, MWIFIEX_IOCTL_WAIT); + + if (mode == MWIFIEX_BSS_MODE_IBSS) { + wiphy_err(wiphy, "received infra assoc request " + "when station is in ibss mode\n"); + goto done; + } + + priv->assoc_request = 1; + + wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", + (char *) sme->ssid, sme->bssid); + + ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, + mode, sme->channel, sme, 0); + +done: + priv->assoc_result = ret; + queue_work(priv->workqueue, &priv->cfg_workqueue); + return ret; +} + +/* + * CFG802.11 operation handler to join an IBSS. + * + * This function does not work in any mode other than Ad-Hoc, or if + * a join operation is already in progress. + */ +static int +mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + int ret = 0; + int mode = 0; + + if (priv->ibss_join_request) + return -EBUSY; + + mode = mwifiex_drv_get_mode(priv, MWIFIEX_IOCTL_WAIT); + if (mode != MWIFIEX_BSS_MODE_IBSS) { + wiphy_err(wiphy, "request to join ibss received " + "when station is not in ibss mode\n"); + goto done; + } + + priv->ibss_join_request = 1; + + wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", + (char *) params->ssid, params->bssid); + + ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, + params->bssid, mode, params->channel, NULL, + params->privacy); +done: + priv->ibss_join_result = ret; + queue_work(priv->workqueue, &priv->cfg_workqueue); + return ret; +} + +/* + * CFG802.11 operation handler to leave an IBSS. + * + * This function does not work if a leave operation is + * already in progress. + */ +static int +mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +{ + struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + + if (priv->disconnect) + return -EBUSY; + + priv->disconnect = 1; + + wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", + priv->cfg_bssid); + if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) + return -EFAULT; + + queue_work(priv->workqueue, &priv->cfg_workqueue); + + return 0; +} + +/* + * CFG802.11 operation handler for scan request. + * + * This function issues a scan request to the firmware based upon + * the user specified scan configuration. On successfull completion, + * it also informs the results. + */ +static int +mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_scan_request *request) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + + wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); + + if (priv->scan_request && priv->scan_request != request) + return -EBUSY; + + priv->scan_request = request; + + queue_work(priv->workqueue, &priv->cfg_workqueue); + return 0; +} + +/* + * This function sets up the CFG802.11 specific HT capability fields + * with default values. + * + * The following default values are set - + * - HT Supported = True + * - Maximum AMPDU length factor = 0x3 + * - Minimum AMPDU spacing = 0x6 + * - HT Capabilities map = IEEE80211_HT_CAP_SUP_WIDTH_20_40 (0x0002) + * - MCS information, Rx mask = 0xff + * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01) + */ +static void +mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, + struct mwifiex_private *priv) +{ + int rx_mcs_supp; + struct ieee80211_mcs_info mcs_set; + u8 *mcs = (u8 *)&mcs_set; + struct mwifiex_adapter *adapter = priv->adapter; + + ht_info->ht_supported = true; + ht_info->ampdu_factor = 0x3; + ht_info->ampdu_density = 0x6; + + memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); + ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40; + + rx_mcs_supp = GET_RXMCSSUPP(priv->adapter->hw_dev_mcs_support); + /* Set MCS for 1x1 */ + memset(mcs, 0xff, rx_mcs_supp); + /* Clear all the other values */ + memset(&mcs[rx_mcs_supp], 0, + sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); + if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || + (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap) && + ISSUPP_CHANWIDTH40(adapter->usr_dot_11n_dev_cap))) + /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ + SETHT_MCS32(mcs_set.rx_mask); + + memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info)); + + ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; +} + +/* station cfg80211 operations */ +static struct cfg80211_ops mwifiex_cfg80211_ops = { + .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf, + .scan = mwifiex_cfg80211_scan, + .connect = mwifiex_cfg80211_connect, + .disconnect = mwifiex_cfg80211_disconnect, + .get_station = mwifiex_cfg80211_get_station, + .set_wiphy_params = mwifiex_cfg80211_set_wiphy_params, + .set_channel = mwifiex_cfg80211_set_channel, + .join_ibss = mwifiex_cfg80211_join_ibss, + .leave_ibss = mwifiex_cfg80211_leave_ibss, + .add_key = mwifiex_cfg80211_add_key, + .del_key = mwifiex_cfg80211_del_key, + .set_default_key = mwifiex_cfg80211_set_default_key, + .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, + .set_tx_power = mwifiex_cfg80211_set_tx_power, +}; + +/* + * This function registers the device with CFG802.11 subsystem. + * + * The function creates the wireless device/wiphy, populates it with + * default parameters and handler function pointers, and finally + * registers the device. + */ +int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, + struct mwifiex_private *priv) +{ + int ret = 0; + void *wdev_priv = NULL; + struct wireless_dev *wdev; + + wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + if (!wdev) { + dev_err(priv->adapter->dev, "%s: allocating wireless device\n", + __func__); + return -ENOMEM; + } + wdev->wiphy = + wiphy_new(&mwifiex_cfg80211_ops, + sizeof(struct mwifiex_private *)); + if (!wdev->wiphy) + return -ENOMEM; + wdev->iftype = NL80211_IFTYPE_STATION; + wdev->wiphy->max_scan_ssids = 10; + wdev->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; + + /* Initialize cipher suits */ + wdev->wiphy->cipher_suites = mwifiex_cipher_suites; + wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); + + /* Initialize parameters for 2GHz band */ + + mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, + priv); + mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, + priv); + + memcpy(wdev->wiphy->perm_addr, mac, 6); + wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + /* We are using custom domains */ + wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + + wdev->wiphy->reg_notifier = mwifiex_reg_notifier; + + /* Set struct mwifiex_private pointer in wiphy_priv */ + wdev_priv = wiphy_priv(wdev->wiphy); + + *(unsigned long *) wdev_priv = (unsigned long) priv; + + ret = wiphy_register(wdev->wiphy); + if (ret < 0) { + dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", + __func__); + wiphy_free(wdev->wiphy); + return ret; + } else { + dev_dbg(priv->adapter->dev, + "info: successfully registered wiphy device\n"); + } + + dev_net_set(dev, wiphy_net(wdev->wiphy)); + dev->ieee80211_ptr = wdev; + memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6); + memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6); + SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); + priv->wdev = wdev; + + dev->flags |= IFF_BROADCAST | IFF_MULTICAST; + dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; + dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; + + return ret; +} + +/* + * This function handles the result of different pending network operations. + * + * The following operations are handled and CFG802.11 subsystem is + * notified accordingly - + * - Scan request completion + * - Association request completion + * - IBSS join request completion + * - Disconnect request completion + */ +void +mwifiex_cfg80211_results(struct work_struct *work) +{ + struct mwifiex_private *priv = + container_of(work, struct mwifiex_private, cfg_workqueue); + struct mwifiex_user_scan_cfg *scan_req; + int ret = 0, i; + struct ieee80211_channel *chan; + + if (priv->scan_request) { + scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg), + GFP_KERNEL); + if (!scan_req) { + dev_err(priv->adapter->dev, "failed to alloc " + "scan_req\n"); + return; + } + for (i = 0; i < priv->scan_request->n_ssids; i++) { + memcpy(scan_req->ssid_list[i].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + scan_req->ssid_list[i].max_len = + priv->scan_request->ssids[i].ssid_len; + } + for (i = 0; i < priv->scan_request->n_channels; i++) { + chan = priv->scan_request->channels[i]; + scan_req->chan_list[i].chan_number = chan->hw_value; + scan_req->chan_list[i].radio_type = chan->band; + if (chan->flags & IEEE80211_CHAN_DISABLED) + scan_req->chan_list[i].scan_type = + MWIFIEX_SCAN_TYPE_PASSIVE; + else + scan_req->chan_list[i].scan_type = + MWIFIEX_SCAN_TYPE_ACTIVE; + scan_req->chan_list[i].scan_time = 0; + } + if (mwifiex_set_user_scan_ioctl(priv, scan_req)) { + ret = -EFAULT; + goto done; + } + if (mwifiex_inform_bss_from_scan_result(priv, NULL)) + ret = -EFAULT; +done: + priv->scan_result_status = ret; + dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n", + __func__); + cfg80211_scan_done(priv->scan_request, + (priv->scan_result_status < 0)); + priv->scan_request = NULL; + kfree(scan_req); + } + + if (priv->assoc_request) { + if (!priv->assoc_result) { + cfg80211_connect_result(priv->netdev, priv->cfg_bssid, + NULL, 0, NULL, 0, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + dev_dbg(priv->adapter->dev, + "info: associated to bssid %pM successfully\n", + priv->cfg_bssid); + } else { + dev_dbg(priv->adapter->dev, + "info: association to bssid %pM failed\n", + priv->cfg_bssid); + memset(priv->cfg_bssid, 0, ETH_ALEN); + } + priv->assoc_request = 0; + priv->assoc_result = 0; + } + + if (priv->ibss_join_request) { + if (!priv->ibss_join_result) { + cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, + GFP_KERNEL); + dev_dbg(priv->adapter->dev, + "info: joined/created adhoc network with bssid" + " %pM successfully\n", priv->cfg_bssid); + } else { + dev_dbg(priv->adapter->dev, + "info: failed creating/joining adhoc network\n"); + } + priv->ibss_join_request = 0; + priv->ibss_join_result = 0; + } + + if (priv->disconnect) { + memset(priv->cfg_bssid, 0, ETH_ALEN); + priv->disconnect = 0; + } + + return; +} diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h new file mode 100644 index 000000000000..c4db8f36aa16 --- /dev/null +++ b/drivers/net/wireless/mwifiex/cfg80211.h @@ -0,0 +1,31 @@ +/* + * Marvell Wireless LAN device driver: CFG80211 + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef __MWIFIEX_CFG80211__ +#define __MWIFIEX_CFG80211__ + +#include + +#include "main.h" + +int mwifiex_register_cfg80211(struct net_device *, u8 *, + struct mwifiex_private *); + +void mwifiex_cfg80211_results(struct work_struct *work); +#endif diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c new file mode 100644 index 000000000000..999ed81512fa --- /dev/null +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -0,0 +1,368 @@ +/* + * Marvell Wireless LAN device driver: Channel, Frequence and Power + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "cfg80211.h" + +/* 100mW */ +#define MWIFIEX_TX_PWR_DEFAULT 20 +/* 100mW */ +#define MWIFIEX_TX_PWR_US_DEFAULT 20 +/* 50mW */ +#define MWIFIEX_TX_PWR_JP_DEFAULT 16 +/* 100mW */ +#define MWIFIEX_TX_PWR_FR_100MW 20 +/* 10mW */ +#define MWIFIEX_TX_PWR_FR_10MW 10 +/* 100mW */ +#define MWIFIEX_TX_PWR_EMEA_DEFAULT 20 + +static u8 adhoc_rates_b[B_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, 0 }; + +static u8 adhoc_rates_g[G_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24, + 0xb0, 0x48, 0x60, 0x6c, 0 }; + +static u8 adhoc_rates_bg[BG_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, + 0x0c, 0x12, 0x18, 0x24, + 0x30, 0x48, 0x60, 0x6c, 0 }; + +static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24, + 0xb0, 0x48, 0x60, 0x6c, 0 }; +u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24, + 0xb0, 0x48, 0x60, 0x6c, 0 }; +static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04, + 0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18, + 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90, + 0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68, + 0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51, + 0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 }; + +u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 }; + +u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24, + 0x30, 0x48, 0x60, 0x6c, 0 }; + +u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c, + 0x12, 0x16, 0x18, 0x24, 0x30, 0x48, + 0x60, 0x6c, 0 }; + +u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30, + 0x32, 0x40, 0x41, 0xff }; + +u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; + +/* + * This function maps an index in supported rates table into + * the corresponding data rate. + */ +u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, + u8 ht_info) +{ + u16 mcs_rate[4][8] = { + {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} + , /* LG 40M */ + {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c} + , /* SG 40M */ + {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82} + , /* LG 20M */ + {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90} + }; /* SG 20M */ + + u32 rate; + + if (ht_info & BIT(0)) { + if (index == MWIFIEX_RATE_BITMAP_MCS0) { + if (ht_info & BIT(2)) + rate = 0x0D; /* MCS 32 SGI rate */ + else + rate = 0x0C; /* MCS 32 LGI rate */ + } else if (index < 8) { + if (ht_info & BIT(1)) { + if (ht_info & BIT(2)) + /* SGI, 40M */ + rate = mcs_rate[1][index]; + else + /* LGI, 40M */ + rate = mcs_rate[0][index]; + } else { + if (ht_info & BIT(2)) + /* SGI, 20M */ + rate = mcs_rate[3][index]; + else + /* LGI, 20M */ + rate = mcs_rate[2][index]; + } + } else + rate = mwifiex_data_rates[0]; + } else { + if (index >= MWIFIEX_SUPPORTED_RATES_EXT) + index = 0; + rate = mwifiex_data_rates[index]; + } + return rate; +} + +/* + * This function maps a data rate value into corresponding index in supported + * rates table. + */ +u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) +{ + u16 *ptr; + + if (rate) { + ptr = memchr(mwifiex_data_rates, rate, + sizeof(mwifiex_data_rates)); + if (ptr) + return (u8) (ptr - mwifiex_data_rates); + } + return 0; +} + +/* + * This function returns the current active data rates. + * + * The result may vary depending upon connection status. + */ +u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) +{ + u32 k; + + if (!priv->media_connected) + k = mwifiex_get_supported_rates(priv, rates); + else + k = mwifiex_copy_rates(rates, 0, + priv->curr_bss_params.data_rates, + priv->curr_bss_params.num_of_rates); + + return k; +} + +/* + * This function locates the Channel-Frequency-Power triplet based upon + * band and channel parameters. + */ +struct mwifiex_chan_freq_power * +mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private + *priv, u8 band, u16 channel) +{ + struct mwifiex_chan_freq_power *cfp = NULL; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + int i; + + if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) + sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; + else + sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; + + if (!sband) { + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" + " & channel %d\n", __func__, band, channel); + return cfp; + } + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (((ch->hw_value == channel) || + (channel == FIRST_VALID_CHANNEL)) + && !(ch->flags & IEEE80211_CHAN_DISABLED)) { + priv->cfp.channel = channel; + priv->cfp.freq = ch->center_freq; + priv->cfp.max_tx_power = ch->max_power; + cfp = &priv->cfp; + break; + } + } + if (i == sband->n_channels) + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" + " & channel %d\n", __func__, band, channel); + + return cfp; +} + +/* + * This function locates the Channel-Frequency-Power triplet based upon + * band and frequency parameters. + */ +struct mwifiex_chan_freq_power * +mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, + u8 band, u32 freq) +{ + struct mwifiex_chan_freq_power *cfp = NULL; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + int i; + + if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) + sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; + else + sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; + + if (!sband) { + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" + " & freq %d\n", __func__, band, freq); + return cfp; + } + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if ((ch->center_freq == freq) && + !(ch->flags & IEEE80211_CHAN_DISABLED)) { + priv->cfp.channel = ch->hw_value; + priv->cfp.freq = freq; + priv->cfp.max_tx_power = ch->max_power; + cfp = &priv->cfp; + break; + } + } + if (i == sband->n_channels) + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" + " & freq %d\n", __func__, band, freq); + + return cfp; +} + +/* + * This function checks if the data rate is set to auto. + */ +u8 +mwifiex_is_rate_auto(struct mwifiex_private *priv) +{ + u32 i; + int rate_num = 0; + + for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates); i++) + if (priv->bitmap_rates[i]) + rate_num++; + + if (rate_num > 1) + return true; + else + return false; +} + +/* + * This function converts rate bitmap into rate index. + */ +int +mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap, + int size) +{ + int i; + + for (i = 0; i < size * 8; i++) + if (rate_bitmap[i / 16] & (1 << (i % 16))) + return i; + + return 0; +} + +/* + * This function gets the supported data rates. + * + * The function works in both Ad-Hoc and infra mode by printing the + * band and returning the data rates. + */ +u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates) +{ + u32 k = 0; + struct mwifiex_adapter *adapter = priv->adapter; + if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) { + /* Infra. mode */ + switch (adapter->config_bands) { + case BAND_B: + dev_dbg(adapter->dev, "info: infra band=%d " + "supported_rates_b\n", adapter->config_bands); + k = mwifiex_copy_rates(rates, k, supported_rates_b, + sizeof(supported_rates_b)); + break; + case BAND_G: + case BAND_G | BAND_GN: + dev_dbg(adapter->dev, "info: infra band=%d " + "supported_rates_g\n", adapter->config_bands); + k = mwifiex_copy_rates(rates, k, supported_rates_g, + sizeof(supported_rates_g)); + break; + case BAND_B | BAND_G: + case BAND_A | BAND_B | BAND_G: + case BAND_A | BAND_B: + case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN: + case BAND_B | BAND_G | BAND_GN: + dev_dbg(adapter->dev, "info: infra band=%d " + "supported_rates_bg\n", adapter->config_bands); + k = mwifiex_copy_rates(rates, k, supported_rates_bg, + sizeof(supported_rates_bg)); + break; + case BAND_A: + case BAND_A | BAND_G: + dev_dbg(adapter->dev, "info: infra band=%d " + "supported_rates_a\n", adapter->config_bands); + k = mwifiex_copy_rates(rates, k, supported_rates_a, + sizeof(supported_rates_a)); + break; + case BAND_A | BAND_AN: + case BAND_A | BAND_G | BAND_AN | BAND_GN: + dev_dbg(adapter->dev, "info: infra band=%d " + "supported_rates_a\n", adapter->config_bands); + k = mwifiex_copy_rates(rates, k, supported_rates_a, + sizeof(supported_rates_a)); + break; + case BAND_GN: + dev_dbg(adapter->dev, "info: infra band=%d " + "supported_rates_n\n", adapter->config_bands); + k = mwifiex_copy_rates(rates, k, supported_rates_n, + sizeof(supported_rates_n)); + break; + } + } else { + /* Ad-hoc mode */ + switch (adapter->adhoc_start_band) { + case BAND_B: + dev_dbg(adapter->dev, "info: adhoc B\n"); + k = mwifiex_copy_rates(rates, k, adhoc_rates_b, + sizeof(adhoc_rates_b)); + break; + case BAND_G: + case BAND_G | BAND_GN: + dev_dbg(adapter->dev, "info: adhoc G only\n"); + k = mwifiex_copy_rates(rates, k, adhoc_rates_g, + sizeof(adhoc_rates_g)); + break; + case BAND_B | BAND_G: + case BAND_B | BAND_G | BAND_GN: + dev_dbg(adapter->dev, "info: adhoc BG\n"); + k = mwifiex_copy_rates(rates, k, adhoc_rates_bg, + sizeof(adhoc_rates_bg)); + break; + case BAND_A: + case BAND_A | BAND_AN: + dev_dbg(adapter->dev, "info: adhoc A\n"); + k = mwifiex_copy_rates(rates, k, adhoc_rates_a, + sizeof(adhoc_rates_a)); + break; + } + } + + return k; +} diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c new file mode 100644 index 000000000000..3a8fe1e122fb --- /dev/null +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -0,0 +1,1463 @@ +/* + * Marvell Wireless LAN device driver: commands and events + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +/* + * This function initializes a command node. + * + * The actual allocation of the node is not done by this function. It only + * initiates a node by filling it with default parameters. Similarly, + * allocation of the different buffers used (IOCTL buffer, data buffer) are + * not done by this function either. + */ +static void +mwifiex_init_cmd_node(struct mwifiex_private *priv, + struct cmd_ctrl_node *cmd_node, + u32 cmd_oid, void *wait_queue, void *data_buf) +{ + cmd_node->priv = priv; + cmd_node->cmd_oid = cmd_oid; + cmd_node->wq_buf = wait_queue; + cmd_node->data_buf = data_buf; + cmd_node->cmd_skb = cmd_node->skb; +} + +/* + * This function returns a command node from the free queue depending upon + * availability. + */ +static struct cmd_ctrl_node * +mwifiex_get_cmd_node(struct mwifiex_adapter *adapter) +{ + struct cmd_ctrl_node *cmd_node; + unsigned long flags; + + spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); + if (list_empty(&adapter->cmd_free_q)) { + dev_err(adapter->dev, "GET_CMD_NODE: cmd node not available\n"); + spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); + return NULL; + } + cmd_node = list_first_entry(&adapter->cmd_free_q, + struct cmd_ctrl_node, list); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); + + return cmd_node; +} + +/* + * This function cleans up a command node. + * + * The function resets the fields including the buffer pointers. + * This function does not try to free the buffers. They must be + * freed before calling this function. + * + * This function will however call the receive completion callback + * in case a response buffer is still available before resetting + * the pointer. + */ +static void +mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_node) +{ + cmd_node->cmd_oid = 0; + cmd_node->cmd_flag = 0; + cmd_node->wq_buf = NULL; + cmd_node->data_buf = NULL; + + if (cmd_node->resp_skb) { + mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); + cmd_node->resp_skb = NULL; + } + + return; +} + +/* + * This function returns a command node from the pending queue which + * matches the given IOCTL request. + */ +static struct cmd_ctrl_node * +mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait_queue) +{ + unsigned long flags; + struct cmd_ctrl_node *cmd_node; + + spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); + list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { + if (cmd_node->wq_buf == wait_queue) { + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, + flags); + return cmd_node; + } + } + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); + + return NULL; +} + +/* + * This function sends a host command to the firmware. + * + * The function copies the host command into the driver command + * buffer, which will be transferred to the firmware later by the + * main thread. + */ +static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, void *data_buf) +{ + struct mwifiex_ds_misc_cmd *pcmd_ptr = + (struct mwifiex_ds_misc_cmd *) data_buf; + + /* Copy the HOST command to command buffer */ + memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len); + dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len); + return 0; +} + +/* + * This function downloads a command to the firmware. + * + * The function performs sanity tests, sets the command sequence + * number and size, converts the header fields to CPU format before + * sending. Afterwards, it logs the command ID and action for debugging + * and sets up the command timeout timer. + */ +static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, + struct cmd_ctrl_node *cmd_node) +{ + + struct mwifiex_adapter *adapter = priv->adapter; + int ret = 0; + struct host_cmd_ds_command *host_cmd; + struct mwifiex_wait_queue *wait_queue = NULL; + uint16_t cmd_code; + uint16_t cmd_size; + struct timeval tstamp; + unsigned long flags; + + if (!adapter || !cmd_node) + return -1; + + host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); + if (cmd_node->wq_buf) + wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; + + /* Sanity test */ + if (host_cmd == NULL || host_cmd->size == 0) { + dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" + " or cmd size is 0, not sending\n"); + if (wait_queue) + wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + return -1; + } + + /* Set command sequence number */ + adapter->seq_num++; + host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO + (adapter->seq_num, cmd_node->priv->bss_num, + cmd_node->priv->bss_type)); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd = cmd_node; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + + cmd_code = le16_to_cpu(host_cmd->command); + cmd_size = le16_to_cpu(host_cmd->size); + + skb_trim(cmd_node->cmd_skb, cmd_size); + + do_gettimeofday(&tstamp); + dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," + " seqno %#x\n", + tstamp.tv_sec, tstamp.tv_usec, cmd_code, + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, + le16_to_cpu(host_cmd->seq_num)); + + skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); + + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, + cmd_node->cmd_skb->data, + cmd_node->cmd_skb->len, NULL); + + if (ret == -1) { + dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); + if (wait_queue) + wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd = NULL; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + + adapter->dbg.num_cmd_host_to_card_failure++; + return -1; + } + + /* Save the last command id and action to debug log */ + adapter->dbg.last_cmd_index = + (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; + adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code; + adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] = + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); + + /* Clear BSS_NO_BITS from HostCmd */ + cmd_code &= HostCmd_CMD_ID_MASK; + + /* Setup the timer after transmit command */ + mod_timer(&adapter->cmd_timer, + jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); + + return 0; +} + +/* + * This function downloads a sleep confirm command to the firmware. + * + * The function performs sanity tests, sets the command sequence + * number and size, converts the header fields to CPU format before + * sending. + * + * No responses are needed for sleep confirm command. + */ +static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) +{ + int ret = 0; + u16 cmd_len = 0; + struct mwifiex_private *priv; + struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf = + (struct mwifiex_opt_sleep_confirm_buffer *) + adapter->sleep_cfm->data; + cmd_len = sizeof(struct mwifiex_opt_sleep_confirm); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + + sleep_cfm_buf->ps_cfm_sleep.seq_num = + cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO + (adapter->seq_num, priv->bss_num, + priv->bss_type))); + adapter->seq_num++; + + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, + adapter->sleep_cfm->data, + adapter->sleep_cfm->len + + INTF_HEADER_LEN, NULL); + + if (ret == -1) { + dev_err(adapter->dev, "SLEEP_CFM: failed\n"); + adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++; + return -1; + } + if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) + == MWIFIEX_BSS_ROLE_STA) { + if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl) + /* Response is not needed for sleep + confirm command */ + adapter->ps_state = PS_STATE_SLEEP; + else + adapter->ps_state = PS_STATE_SLEEP_CFM; + + if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl + && (adapter->is_hs_configured + && !adapter->sleep_period.period)) { + adapter->pm_wakeup_card_req = true; + mwifiex_hs_activated_event(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_STA), true); + } + } + + return ret; +} + +/* + * This function allocates the command buffers and links them to + * the command free queue. + * + * The driver uses a pre allocated number of command buffers, which + * are created at driver initializations and freed at driver cleanup. + * Every command needs to obtain a command buffer from this pool before + * it can be issued. The command free queue lists the command buffers + * currently free to use, while the command pending queue lists the + * command buffers already in use and awaiting handling. Command buffers + * are returned to the free queue after use. + */ +int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) +{ + struct cmd_ctrl_node *cmd_array; + u32 buf_size; + u32 i; + + /* Allocate and initialize struct cmd_ctrl_node */ + buf_size = sizeof(struct cmd_ctrl_node) * MWIFIEX_NUM_OF_CMD_BUFFER; + cmd_array = kzalloc(buf_size, GFP_KERNEL); + if (!cmd_array) { + dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", + __func__); + return -1; + } + + adapter->cmd_pool = cmd_array; + memset(adapter->cmd_pool, 0, buf_size); + + /* Allocate and initialize command buffers */ + for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) { + cmd_array[i].skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); + if (!cmd_array[i].skb) { + dev_err(adapter->dev, "ALLOC_CMD_BUF: out of memory\n"); + return -1; + } + } + + for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) + mwifiex_insert_cmd_to_free_q(adapter, &cmd_array[i]); + + return 0; +} + +/* + * This function frees the command buffers. + * + * The function calls the completion callback for all the command + * buffers that still have response buffers associated with them. + */ +int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter) +{ + struct cmd_ctrl_node *cmd_array; + u32 i; + + /* Need to check if cmd pool is allocated or not */ + if (!adapter->cmd_pool) { + dev_dbg(adapter->dev, "info: FREE_CMD_BUF: cmd_pool is null\n"); + return 0; + } + + cmd_array = adapter->cmd_pool; + + /* Release shared memory buffers */ + for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) { + if (cmd_array[i].skb) { + dev_dbg(adapter->dev, "cmd: free cmd buffer %d\n", i); + dev_kfree_skb_any(cmd_array[i].skb); + } + if (!cmd_array[i].resp_skb) + continue; + mwifiex_recv_complete(adapter, cmd_array[i].resp_skb, 0); + } + /* Release struct cmd_ctrl_node */ + if (adapter->cmd_pool) { + dev_dbg(adapter->dev, "cmd: free cmd pool\n"); + kfree(adapter->cmd_pool); + adapter->cmd_pool = NULL; + } + + return 0; +} + +/* + * This function handles events generated by firmware. + * + * Event body of events received from firmware are not used (though they are + * saved), only the event ID is used. Some events are re-invoked by + * the driver, with a new event body. + * + * After processing, the function calls the completion callback + * for cleanup. + */ +int mwifiex_process_event(struct mwifiex_adapter *adapter) +{ + int ret = 0; + struct mwifiex_private *priv = + mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + struct sk_buff *skb = adapter->event_skb; + u32 eventcause = adapter->event_cause; + struct timeval tstamp; + struct mwifiex_rxinfo *rx_info = NULL; + + /* Save the last event to debug log */ + adapter->dbg.last_event_index = + (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; + adapter->dbg.last_event[adapter->dbg.last_event_index] = + (u16) eventcause; + + /* Get BSS number and corresponding priv */ + priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause), + EVENT_GET_BSS_TYPE(eventcause)); + if (!priv) + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + /* Clear BSS_NO_BITS from event */ + eventcause &= EVENT_ID_MASK; + adapter->event_cause = eventcause; + + if (skb) { + rx_info = MWIFIEX_SKB_RXCB(skb); + rx_info->bss_index = priv->bss_index; + } + + if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { + do_gettimeofday(&tstamp); + dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", + tstamp.tv_sec, tstamp.tv_usec, eventcause); + } + + ret = mwifiex_process_sta_event(priv); + + adapter->event_cause = 0; + adapter->event_skb = NULL; + + mwifiex_recv_complete(adapter, skb, 0); + + return ret; +} + +/* + * This function prepares a command before sending it to the firmware. + * + * Preparation includes - + * - Sanity tests to make sure the card is still present or the FW + * is not reset + * - Getting a new command node from the command free queue + * - Initializing the command node for default parameters + * - Fill up the non-default parameters and buffer pointers + * - Add the command to pending queue + */ +int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, + void *wait_queue, void *data_buf) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + struct cmd_ctrl_node *cmd_node = NULL; + struct host_cmd_ds_command *cmd_ptr = NULL; + + if (!adapter) { + pr_err("PREP_CMD: adapter is NULL\n"); + return -1; + } + + if (adapter->is_suspended) { + dev_err(adapter->dev, "PREP_CMD: device in suspended state\n"); + return -1; + } + + if (adapter->surprise_removed) { + dev_err(adapter->dev, "PREP_CMD: card is removed\n"); + return -1; + } + + if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) { + if (cmd_no != HostCmd_CMD_FUNC_INIT) { + dev_err(adapter->dev, "PREP_CMD: FW in reset state\n"); + return -1; + } + } + + /* Get a new command node */ + cmd_node = mwifiex_get_cmd_node(adapter); + + if (!cmd_node) { + dev_err(adapter->dev, "PREP_CMD: no free cmd node\n"); + return -1; + } + + /* Initialize the command node */ + mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf); + + if (!cmd_node->cmd_skb) { + dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); + return -1; + } + + memset(skb_put(cmd_node->cmd_skb, sizeof(struct host_cmd_ds_command)), + 0, sizeof(struct host_cmd_ds_command)); + + cmd_ptr = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); + cmd_ptr->command = cpu_to_le16(cmd_no); + cmd_ptr->result = 0; + + /* Prepare command */ + if (cmd_no) { + ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action, + cmd_oid, data_buf, cmd_ptr); + } else { + ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf); + cmd_node->cmd_flag |= CMD_F_HOSTCMD; + } + + /* Return error, since the command preparation failed */ + if (ret) { + dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n", + cmd_no); + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + return -1; + } + + /* Send command */ + if (cmd_no == HostCmd_CMD_802_11_SCAN) + mwifiex_queue_scan_cmd(priv, cmd_node); + else + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + + return ret; +} + +/* + * This function returns a command to the command free queue. + * + * The function also calls the completion callback if required, before + * cleaning the command node and re-inserting it into the free queue. + */ +void +mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_node) +{ + struct mwifiex_wait_queue *wait_queue = NULL; + unsigned long flags; + + if (cmd_node == NULL) + return; + if (cmd_node->wq_buf) { + wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; + if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR) + mwifiex_ioctl_complete(adapter, wait_queue, -1); + else + mwifiex_ioctl_complete(adapter, wait_queue, 0); + } + /* Clean the node */ + mwifiex_clean_cmd_node(adapter, cmd_node); + + /* Insert node into cmd_free_q */ + spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); + list_add_tail(&cmd_node->list, &adapter->cmd_free_q); + spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); + + return; +} + +/* + * This function queues a command to the command pending queue. + * + * This in effect adds the command to the command list to be executed. + * Exit PS command is handled specially, by placing it always to the + * front of the command queue. + */ +void +mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_node, u32 add_tail) +{ + struct host_cmd_ds_command *host_cmd = NULL; + u16 command; + unsigned long flags; + + host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); + if (!host_cmd) { + dev_err(adapter->dev, "QUEUE_CMD: host_cmd is NULL\n"); + return; + } + + command = le16_to_cpu(host_cmd->command); + + /* Exit_PS command needs to be queued in the header always. */ + if (command == HostCmd_CMD_802_11_PS_MODE_ENH) { + struct host_cmd_ds_802_11_ps_mode_enh *pm = + &host_cmd->params.psmode_enh; + if ((le16_to_cpu(pm->action) == DIS_PS) + || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { + if (adapter->ps_state != PS_STATE_AWAKE) + add_tail = false; + } + } + + spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); + if (add_tail) + list_add_tail(&cmd_node->list, &adapter->cmd_pending_q); + else + list_add(&cmd_node->list, &adapter->cmd_pending_q); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); + + dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); + + return; +} + +/* + * This function executes the next command in command pending queue. + * + * This function will fail if a command is already in processing stage, + * otherwise it will dequeue the first command from the command pending + * queue and send to the firmware. + * + * If the device is currently in host sleep mode, any commands, except the + * host sleep configuration command will de-activate the host sleep. For PS + * mode, the function will put the firmware back to sleep if applicable. + */ +int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter) +{ + struct mwifiex_private *priv = NULL; + struct cmd_ctrl_node *cmd_node = NULL; + int ret = 0; + struct host_cmd_ds_command *host_cmd; + unsigned long cmd_flags; + unsigned long cmd_pending_q_flags; + + /* Check if already in processing */ + if (adapter->curr_cmd) { + dev_err(adapter->dev, "EXEC_NEXT_CMD: cmd in processing\n"); + return -1; + } + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + /* Check if any command is pending */ + spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags); + if (list_empty(&adapter->cmd_pending_q)) { + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, + cmd_pending_q_flags); + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + return 0; + } + cmd_node = list_first_entry(&adapter->cmd_pending_q, + struct cmd_ctrl_node, list); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, + cmd_pending_q_flags); + + host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); + priv = cmd_node->priv; + + if (adapter->ps_state != PS_STATE_AWAKE) { + dev_err(adapter->dev, "%s: cannot send cmd in sleep state," + " this should not happen\n", __func__); + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + return ret; + } + + spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, + cmd_pending_q_flags); + + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + /* Any command sent to the firmware when host is in sleep + * mode should de-configure host sleep. We should skip the + * host sleep configuration command itself though + */ + if (priv && (host_cmd->command != + cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) { + if (adapter->hs_activated) { + adapter->is_hs_configured = false; + mwifiex_hs_activated_event(priv, false); + } + } + + return ret; +} + +/* + * This function handles the command response. + * + * After processing, the function cleans the command node and puts + * it back to the command free queue. + */ +int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) +{ + struct host_cmd_ds_command *resp = NULL; + struct mwifiex_private *priv = + mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + int ret = 0; + uint16_t orig_cmdresp_no; + uint16_t cmdresp_no; + uint16_t cmdresp_result; + struct mwifiex_wait_queue *wait_queue = NULL; + struct timeval tstamp; + unsigned long flags; + + /* Now we got response from FW, cancel the command timer */ + del_timer(&adapter->cmd_timer); + + if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { + resp = (struct host_cmd_ds_command *) adapter->upld_buf; + dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n", + le16_to_cpu(resp->command)); + return -1; + } + + if (adapter->curr_cmd->wq_buf) + wait_queue = (struct mwifiex_wait_queue *) + adapter->curr_cmd->wq_buf; + + adapter->num_cmd_timeout = 0; + + resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; + if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { + dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", + le16_to_cpu(resp->command)); + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd = NULL; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + return -1; + } + + if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { + /* Copy original response back to response buffer */ + struct mwifiex_ds_misc_cmd *hostcmd = NULL; + uint16_t size = le16_to_cpu(resp->size); + dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size); + size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER); + if (adapter->curr_cmd->data_buf) { + hostcmd = (struct mwifiex_ds_misc_cmd *) + adapter->curr_cmd->data_buf; + hostcmd->len = size; + memcpy(hostcmd->cmd, (void *) resp, size); + } + } + orig_cmdresp_no = le16_to_cpu(resp->command); + + /* Get BSS number and corresponding priv */ + priv = mwifiex_get_priv_by_id(adapter, + HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), + HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); + if (!priv) + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + /* Clear RET_BIT from HostCmd */ + resp->command = cpu_to_le16(orig_cmdresp_no & HostCmd_CMD_ID_MASK); + + cmdresp_no = le16_to_cpu(resp->command); + cmdresp_result = le16_to_cpu(resp->result); + + /* Save the last command response to debug log */ + adapter->dbg.last_cmd_resp_index = + (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; + adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = + orig_cmdresp_no; + + do_gettimeofday(&tstamp); + dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," + " len %d, seqno 0x%x\n", + tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result, + le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num)); + + if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { + dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); + if (wait_queue) + wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP; + + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd = NULL; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + return -1; + } + + if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { + adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD; + if ((cmdresp_result == HostCmd_RESULT_OK) + && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) + ret = mwifiex_ret_802_11_hs_cfg(priv, resp); + } else { + /* handle response */ + ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp, + wait_queue); + } + + /* Check init command response */ + if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { + if (ret == -1) { + dev_err(adapter->dev, "%s: cmd %#x failed during " + "initialization\n", __func__, cmdresp_no); + mwifiex_init_fw_complete(adapter); + return -1; + } else if (adapter->last_init_cmd == cmdresp_no) + adapter->hw_status = MWIFIEX_HW_STATUS_INIT_DONE; + } + + if (adapter->curr_cmd) { + if (wait_queue && (!ret)) + wait_queue->status = MWIFIEX_ERROR_NO_ERROR; + else if (wait_queue && (ret == -1)) + wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL; + + /* Clean up and put current command back to cmd_free_q */ + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd = NULL; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + } + + return ret; +} + +/* + * This function handles the timeout of command sending. + * + * It will re-send the same command again. + */ +void +mwifiex_cmd_timeout_func(unsigned long function_context) +{ + struct mwifiex_adapter *adapter = + (struct mwifiex_adapter *) function_context; + struct cmd_ctrl_node *cmd_node = NULL; + struct mwifiex_wait_queue *wait_queue = NULL; + struct timeval tstamp; + + adapter->num_cmd_timeout++; + adapter->dbg.num_cmd_timeout++; + if (!adapter->curr_cmd) { + dev_dbg(adapter->dev, "cmd: empty curr_cmd\n"); + return; + } + cmd_node = adapter->curr_cmd; + if (cmd_node->wq_buf) { + wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; + wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT; + } + + if (cmd_node) { + adapter->dbg.timeout_cmd_id = + adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; + adapter->dbg.timeout_cmd_act = + adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; + do_gettimeofday(&tstamp); + dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x," + " act = %#x\n", __func__, + tstamp.tv_sec, tstamp.tv_usec, + adapter->dbg.timeout_cmd_id, + adapter->dbg.timeout_cmd_act); + + dev_err(adapter->dev, "num_data_h2c_failure = %d\n", + adapter->dbg.num_tx_host_to_card_failure); + dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", + adapter->dbg.num_cmd_host_to_card_failure); + + dev_err(adapter->dev, "num_cmd_timeout = %d\n", + adapter->dbg.num_cmd_timeout); + dev_err(adapter->dev, "num_tx_timeout = %d\n", + adapter->dbg.num_tx_timeout); + + dev_err(adapter->dev, "last_cmd_index = %d\n", + adapter->dbg.last_cmd_index); + print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_cmd_id, DBG_CMD_NUM); + print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_cmd_act, DBG_CMD_NUM); + + dev_err(adapter->dev, "last_cmd_resp_index = %d\n", + adapter->dbg.last_cmd_resp_index); + print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM); + + dev_err(adapter->dev, "last_event_index = %d\n", + adapter->dbg.last_event_index); + print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_event, DBG_CMD_NUM); + + dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", + adapter->data_sent, adapter->cmd_sent); + + dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", + adapter->ps_mode, adapter->ps_state); + } + if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) + mwifiex_init_fw_complete(adapter); + + return; +} + +/* + * This function cancels all the pending commands. + * + * The current command, all commands in command pending queue and all scan + * commands in scan pending queue are cancelled. All the completion callbacks + * are called with failure status to ensure cleanup. + */ +void +mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) +{ + struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; + struct mwifiex_wait_queue *wait_queue = NULL; + unsigned long flags; + + /* Cancel current cmd */ + if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) { + wait_queue = + (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf; + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd->wq_buf = NULL; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; + mwifiex_ioctl_complete(adapter, wait_queue, -1); + } + /* Cancel all pending command */ + spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); + list_for_each_entry_safe(cmd_node, tmp_node, + &adapter->cmd_pending_q, list) { + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); + + if (cmd_node->wq_buf) { + wait_queue = + (struct mwifiex_wait_queue *) cmd_node->wq_buf; + wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; + mwifiex_ioctl_complete(adapter, wait_queue, -1); + cmd_node->wq_buf = NULL; + } + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); + } + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); + + /* Cancel all pending scan command */ + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + list_for_each_entry_safe(cmd_node, tmp_node, + &adapter->scan_pending_q, list) { + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + + cmd_node->wq_buf = NULL; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + } + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); +} + +/* + * This function cancels all pending commands that matches with + * the given IOCTL request. + * + * Both the current command buffer and the pending command queue are + * searched for matching IOCTL request. The completion callback of + * the matched command is called with failure status to ensure cleanup. + * In case of scan commands, all pending commands in scan pending queue + * are cancelled. + */ +void +mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait_queue) +{ + struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; + unsigned long cmd_flags; + unsigned long cmd_pending_q_flags; + unsigned long scan_pending_q_flags; + uint16_t cancel_scan_cmd = false; + + if ((adapter->curr_cmd) && + (adapter->curr_cmd->wq_buf == wait_queue)) { + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + cmd_node = adapter->curr_cmd; + cmd_node->wq_buf = NULL; + cmd_node->cmd_flag |= CMD_F_CANCELED; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + } + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + while (1) { + cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue); + if (!cmd_node) + break; + + spin_lock_irqsave(&adapter->cmd_pending_q_lock, + cmd_pending_q_flags); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, + cmd_pending_q_flags); + + cmd_node->wq_buf = NULL; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + } + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + /* Cancel all pending scan command */ + spin_lock_irqsave(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + list_for_each_entry_safe(cmd_node, tmp_node, + &adapter->scan_pending_q, list) { + if (cmd_node->wq_buf == wait_queue) { + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + cmd_node->wq_buf = NULL; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_lock_irqsave(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + cancel_scan_cmd = true; + } + } + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + + if (cancel_scan_cmd) { + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + } + wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; + mwifiex_ioctl_complete(adapter, wait_queue, -1); + + return; +} + +/* + * This function sends the sleep confirm command to firmware, if + * possible. + * + * The sleep confirm command cannot be issued if command response, + * data response or event response is awaiting handling, or if we + * are in the middle of sending a command, or expecting a command + * response. + */ +void +mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) +{ + if (!adapter->cmd_sent && + !adapter->curr_cmd && !IS_CARD_RX_RCVD(adapter)) + mwifiex_dnld_sleep_confirm_cmd(adapter); + else + dev_dbg(adapter->dev, + "cmd: Delay Sleep Confirm (%s%s%s)\n", + (adapter->cmd_sent) ? "D" : "", + (adapter->curr_cmd) ? "C" : "", + (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); +} + +/* + * This function sends a Host Sleep activated event to applications. + * + * This event is generated by the driver, with a blank event body. + */ +void +mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated) +{ + if (activated) { + if (priv->adapter->is_hs_configured) { + priv->adapter->hs_activated = true; + dev_dbg(priv->adapter->dev, "event: hs_activated\n"); + priv->adapter->hs_activate_wait_q_woken = true; + wake_up_interruptible( + &priv->adapter->hs_activate_wait_q); + } else { + dev_dbg(priv->adapter->dev, "event: HS not configured\n"); + } + } else { + dev_dbg(priv->adapter->dev, "event: hs_deactivated\n"); + priv->adapter->hs_activated = false; + } +} + +/* + * This function handles the command response of a Host Sleep configuration + * command. + * + * Handling includes changing the header fields into CPU format + * and setting the current host sleep activation status in driver. + * + * In case host sleep status change, the function generates an event to + * notify the applications. + */ +int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11_hs_cfg_enh *phs_cfg = + &resp->params.opt_hs_cfg; + uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); + + if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) { + mwifiex_hs_activated_event(priv, true); + return 0; + } else { + dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" + " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n", + resp->result, conditions, + phs_cfg->params.hs_config.gpio, + phs_cfg->params.hs_config.gap); + } + if (conditions != HOST_SLEEP_CFG_CANCEL) { + adapter->is_hs_configured = true; + } else { + adapter->is_hs_configured = false; + if (adapter->hs_activated) + mwifiex_hs_activated_event(priv, false); + } + + return 0; +} + +/* + * This function wakes up the adapter and generates a Host Sleep + * cancel event on receiving the power up interrupt. + */ +void +mwifiex_process_hs_config(struct mwifiex_adapter *adapter) +{ + dev_dbg(adapter->dev, "info: %s: auto cancelling host sleep" + " since there is interrupt from the firmware\n", __func__); + + adapter->if_ops.wakeup(adapter); + adapter->hs_activated = false; + adapter->is_hs_configured = false; + mwifiex_hs_activated_event(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), false); + return; +} + +/* + * This function handles the command response of a sleep confirm command. + * + * The function sets the card state to SLEEP if the response indicates success. + */ +void +mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, + u8 *pbuf, u32 upld_len) +{ + struct host_cmd_ds_command *cmd = (struct host_cmd_ds_command *) pbuf; + struct mwifiex_private *priv = + mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + uint16_t result = le16_to_cpu(cmd->result); + uint16_t command = le16_to_cpu(cmd->command); + uint16_t seq_num = le16_to_cpu(cmd->seq_num); + + if (!upld_len) { + dev_err(adapter->dev, "%s: cmd size is 0\n", __func__); + return; + } + + /* Get BSS number and corresponding priv */ + priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num), + HostCmd_GET_BSS_TYPE(seq_num)); + if (!priv) + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + + /* Update sequence number */ + seq_num = HostCmd_GET_SEQ_NO(seq_num); + /* Clear RET_BIT from HostCmd */ + command &= HostCmd_CMD_ID_MASK; + + if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { + dev_err(adapter->dev, "%s: received unexpected response for" + " cmd %x, result = %x\n", __func__, command, result); + return; + } + + if (result) { + dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", + __func__); + adapter->pm_wakeup_card_req = false; + adapter->ps_state = PS_STATE_AWAKE; + return; + } + adapter->pm_wakeup_card_req = true; + if (adapter->is_hs_configured) + mwifiex_hs_activated_event(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), true); + adapter->ps_state = PS_STATE_SLEEP; + cmd->command = cpu_to_le16(command); + cmd->seq_num = cpu_to_le16(seq_num); +} +EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp); + +/* + * This function prepares an enhanced power mode command. + * + * This function can be used to disable power save or to configure + * power save with auto PS or STA PS or auto deep sleep. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting Power Save bitmap, PS parameters TLV, PS mode TLV, + * auto deep sleep TLV (as required) + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, uint16_t ps_bitmap, + void *data_buf) +{ + struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = + &cmd->params.psmode_enh; + u8 *tlv = NULL; + u16 cmd_size = 0; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); + if (cmd_action == DIS_AUTO_PS) { + psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); + psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); + cmd->size = cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE); + } else if (cmd_action == GET_PS) { + psmode_enh->action = cpu_to_le16(GET_PS); + psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); + cmd->size = cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE); + } else if (cmd_action == EN_AUTO_PS) { + psmode_enh->action = cpu_to_le16(EN_AUTO_PS); + psmode_enh->params.auto_ps.ps_bitmap = cpu_to_le16(ps_bitmap); + cmd_size = S_DS_GEN + AUTO_PS_FIX_SIZE; + tlv = (u8 *) cmd + cmd_size; + if (ps_bitmap & BITMAP_STA_PS) { + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_ie_types_ps_param *ps_tlv = + (struct mwifiex_ie_types_ps_param *) tlv; + struct mwifiex_ps_param *ps_mode = &ps_tlv->param; + ps_tlv->header.type = cpu_to_le16(TLV_TYPE_PS_PARAM); + ps_tlv->header.len = cpu_to_le16(sizeof(*ps_tlv) - + sizeof(struct mwifiex_ie_types_header)); + cmd_size += sizeof(*ps_tlv); + tlv += sizeof(*ps_tlv); + dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); + ps_mode->null_pkt_interval = + cpu_to_le16(adapter->null_pkt_interval); + ps_mode->multiple_dtims = + cpu_to_le16(adapter->multiple_dtim); + ps_mode->bcn_miss_timeout = + cpu_to_le16(adapter->bcn_miss_time_out); + ps_mode->local_listen_interval = + cpu_to_le16(adapter->local_listen_interval); + ps_mode->adhoc_wake_period = + cpu_to_le16(adapter->adhoc_awake_period); + ps_mode->delay_to_ps = + cpu_to_le16(adapter->delay_to_ps); + ps_mode->mode = + cpu_to_le16(adapter->enhanced_ps_mode); + + } + if (ps_bitmap & BITMAP_AUTO_DS) { + struct mwifiex_ie_types_auto_ds_param *auto_ps_tlv = + (struct mwifiex_ie_types_auto_ds_param *) tlv; + struct mwifiex_auto_ds_param *auto_ds = + &auto_ps_tlv->param; + u16 idletime = 0; + auto_ps_tlv->header.type = + cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM); + auto_ps_tlv->header.len = + cpu_to_le16(sizeof(*auto_ps_tlv) - + sizeof(struct mwifiex_ie_types_header)); + cmd_size += sizeof(*auto_ps_tlv); + tlv += sizeof(*auto_ps_tlv); + if (data_buf) + idletime = ((struct mwifiex_ds_auto_ds *) + data_buf)->idle_time; + dev_dbg(priv->adapter->dev, + "cmd: PS Command: Enter Auto Deep Sleep\n"); + auto_ds->deep_sleep_timeout = cpu_to_le16(idletime); + } + cmd->size = cpu_to_le16(cmd_size); + } + return 0; +} + +/* + * This function handles the command response of an enhanced power mode + * command. + * + * Handling includes changing the header fields into CPU format + * and setting the current enhanced power mode in driver. + */ +int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11_ps_mode_enh *ps_mode = + &resp->params.psmode_enh; + uint16_t action = le16_to_cpu(ps_mode->action); + uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap); + uint16_t auto_ps_bitmap = + le16_to_cpu(ps_mode->params.auto_ps.ps_bitmap); + + dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", + __func__, resp->result, action); + if (action == EN_AUTO_PS) { + if (auto_ps_bitmap & BITMAP_AUTO_DS) { + dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); + priv->adapter->is_deep_sleep = true; + } + if (auto_ps_bitmap & BITMAP_STA_PS) { + dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); + if (adapter->sleep_period.period) + dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n"); + } + } else if (action == DIS_AUTO_PS) { + if (ps_bitmap & BITMAP_AUTO_DS) { + priv->adapter->is_deep_sleep = false; + dev_dbg(adapter->dev, "cmd: Disabled auto deep sleep\n"); + } + if (ps_bitmap & BITMAP_STA_PS) { + dev_dbg(adapter->dev, "cmd: Disabled STA power save\n"); + if (adapter->sleep_period.period) { + adapter->delay_null_pkt = false; + adapter->tx_lock_flag = false; + adapter->pps_uapsd_mode = false; + } + } + } else if (action == GET_PS) { + if (ps_bitmap & (BITMAP_STA_PS | BITMAP_UAP_INACT_PS + | BITMAP_UAP_DTIM_PS)) + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; + else + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; + + dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap); + + if (data_buf) { + /* This section is for get power save mode */ + struct mwifiex_ds_pm_cfg *pm_cfg = + (struct mwifiex_ds_pm_cfg *)data_buf; + if (ps_bitmap & BITMAP_STA_PS) + pm_cfg->param.ps_mode = 1; + else + pm_cfg->param.ps_mode = 0; + } + } + return 0; +} + +/* + * This function prepares command to get hardware specifications. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting permanent address parameter + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd) +{ + struct host_cmd_ds_get_hw_spec *hw_spec = &cmd->params.hw_spec; + + cmd->command = cpu_to_le16(HostCmd_CMD_GET_HW_SPEC); + cmd->size = + cpu_to_le16(sizeof(struct host_cmd_ds_get_hw_spec) + S_DS_GEN); + memcpy(hw_spec->permanent_addr, priv->curr_addr, ETH_ALEN); + + return 0; +} + +/* + * This function handles the command response of get hardware + * specifications. + * + * Handling includes changing the header fields into CPU format + * and saving/updating the following parameters in driver - + * - Firmware capability information + * - Firmware band settings + * - Ad-hoc start band and channel + * - Ad-hoc 11n activation status + * - Firmware release number + * - Number of antennas + * - Hardware address + * - Hardware interface version + * - Firmware version + * - Region code + * - 11n capabilities + * - MCS support fields + * - MP end port + */ +int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec; + struct mwifiex_adapter *adapter = priv->adapter; + int i; + + adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info); + + if (IS_SUPPORT_MULTI_BANDS(adapter)) + adapter->fw_bands = (u8) GET_FW_DEFAULT_BANDS(adapter); + else + adapter->fw_bands = BAND_B; + + adapter->config_bands = adapter->fw_bands; + + if (adapter->fw_bands & BAND_A) { + if (adapter->fw_bands & BAND_GN) { + adapter->config_bands |= BAND_AN; + adapter->fw_bands |= BAND_AN; + } + if (adapter->fw_bands & BAND_AN) { + adapter->adhoc_start_band = BAND_A | BAND_AN; + adapter->adhoc_11n_enabled = true; + } else { + adapter->adhoc_start_band = BAND_A; + } + priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A; + } else if (adapter->fw_bands & BAND_GN) { + adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN; + priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; + adapter->adhoc_11n_enabled = true; + } else if (adapter->fw_bands & BAND_G) { + adapter->adhoc_start_band = BAND_G | BAND_B; + priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; + } else if (adapter->fw_bands & BAND_B) { + adapter->adhoc_start_band = BAND_B; + priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; + } + + adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); + adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); + + dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", + adapter->fw_release_number); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", + hw_spec->permanent_addr); + dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", + le16_to_cpu(hw_spec->hw_if_version), + le16_to_cpu(hw_spec->version)); + + if (priv->curr_addr[0] == 0xff) + memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); + + adapter->region_code = le16_to_cpu(hw_spec->region_code); + + for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++) + /* Use the region code to search for the index */ + if (adapter->region_code == region_code_index[i]) + break; + + /* If it's unidentified region code, use the default (USA) */ + if (i >= MWIFIEX_MAX_REGION_CODE) { + adapter->region_code = 0x10; + dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n"); + } + + adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); + adapter->usr_dot_11n_dev_cap = adapter->hw_dot_11n_dev_cap & + DEFAULT_11N_CAP_MASK; + adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support; + adapter->usr_dev_mcs_support = adapter->hw_dev_mcs_support; + mwifiex_show_dot_11n_dev_cap(adapter, adapter->hw_dot_11n_dev_cap); + mwifiex_show_dev_mcs_support(adapter, adapter->hw_dev_mcs_support); + + if (adapter->if_ops.update_mp_end_port) + adapter->if_ops.update_mp_end_port(adapter, + le16_to_cpu(hw_spec->mp_end_port)); + + return 0; +} diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c new file mode 100644 index 000000000000..63b09692f27d --- /dev/null +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -0,0 +1,773 @@ +/* + * Marvell Wireless LAN device driver: debugfs + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include + +#include "main.h" +#include "11n.h" + + +static struct dentry *mwifiex_dfs_dir; + +static char *bss_modes[] = { + "Unknown", + "Managed", + "Ad-hoc", + "Auto" +}; + +/* size/addr for mwifiex_debug_info */ +#define item_size(n) (FIELD_SIZEOF(struct mwifiex_debug_info, n)) +#define item_addr(n) (offsetof(struct mwifiex_debug_info, n)) + +/* size/addr for struct mwifiex_adapter */ +#define adapter_item_size(n) (FIELD_SIZEOF(struct mwifiex_adapter, n)) +#define adapter_item_addr(n) (offsetof(struct mwifiex_adapter, n)) + +struct mwifiex_debug_data { + char name[32]; /* variable/array name */ + u32 size; /* size of the variable/array */ + size_t addr; /* address of the variable/array */ + int num; /* number of variables in an array */ +}; + +static struct mwifiex_debug_data items[] = { + {"int_counter", item_size(int_counter), + item_addr(int_counter), 1}, + {"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]), + item_addr(packets_out[WMM_AC_VO]), 1}, + {"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]), + item_addr(packets_out[WMM_AC_VI]), 1}, + {"wmm_ac_be", item_size(packets_out[WMM_AC_BE]), + item_addr(packets_out[WMM_AC_BE]), 1}, + {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]), + item_addr(packets_out[WMM_AC_BK]), 1}, + {"max_tx_buf_size", item_size(max_tx_buf_size), + item_addr(max_tx_buf_size), 1}, + {"tx_buf_size", item_size(tx_buf_size), + item_addr(tx_buf_size), 1}, + {"curr_tx_buf_size", item_size(curr_tx_buf_size), + item_addr(curr_tx_buf_size), 1}, + {"ps_mode", item_size(ps_mode), + item_addr(ps_mode), 1}, + {"ps_state", item_size(ps_state), + item_addr(ps_state), 1}, + {"is_deep_sleep", item_size(is_deep_sleep), + item_addr(is_deep_sleep), 1}, + {"wakeup_dev_req", item_size(pm_wakeup_card_req), + item_addr(pm_wakeup_card_req), 1}, + {"wakeup_tries", item_size(pm_wakeup_fw_try), + item_addr(pm_wakeup_fw_try), 1}, + {"hs_configured", item_size(is_hs_configured), + item_addr(is_hs_configured), 1}, + {"hs_activated", item_size(hs_activated), + item_addr(hs_activated), 1}, + {"num_tx_timeout", item_size(num_tx_timeout), + item_addr(num_tx_timeout), 1}, + {"num_cmd_timeout", item_size(num_cmd_timeout), + item_addr(num_cmd_timeout), 1}, + {"timeout_cmd_id", item_size(timeout_cmd_id), + item_addr(timeout_cmd_id), 1}, + {"timeout_cmd_act", item_size(timeout_cmd_act), + item_addr(timeout_cmd_act), 1}, + {"last_cmd_id", item_size(last_cmd_id), + item_addr(last_cmd_id), DBG_CMD_NUM}, + {"last_cmd_act", item_size(last_cmd_act), + item_addr(last_cmd_act), DBG_CMD_NUM}, + {"last_cmd_index", item_size(last_cmd_index), + item_addr(last_cmd_index), 1}, + {"last_cmd_resp_id", item_size(last_cmd_resp_id), + item_addr(last_cmd_resp_id), DBG_CMD_NUM}, + {"last_cmd_resp_index", item_size(last_cmd_resp_index), + item_addr(last_cmd_resp_index), 1}, + {"last_event", item_size(last_event), + item_addr(last_event), DBG_CMD_NUM}, + {"last_event_index", item_size(last_event_index), + item_addr(last_event_index), 1}, + {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure), + item_addr(num_cmd_host_to_card_failure), 1}, + {"num_cmd_sleep_cfm_fail", + item_size(num_cmd_sleep_cfm_host_to_card_failure), + item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1}, + {"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure), + item_addr(num_tx_host_to_card_failure), 1}, + {"num_evt_deauth", item_size(num_event_deauth), + item_addr(num_event_deauth), 1}, + {"num_evt_disassoc", item_size(num_event_disassoc), + item_addr(num_event_disassoc), 1}, + {"num_evt_link_lost", item_size(num_event_link_lost), + item_addr(num_event_link_lost), 1}, + {"num_cmd_deauth", item_size(num_cmd_deauth), + item_addr(num_cmd_deauth), 1}, + {"num_cmd_assoc_ok", item_size(num_cmd_assoc_success), + item_addr(num_cmd_assoc_success), 1}, + {"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure), + item_addr(num_cmd_assoc_failure), 1}, + {"cmd_sent", item_size(cmd_sent), + item_addr(cmd_sent), 1}, + {"data_sent", item_size(data_sent), + item_addr(data_sent), 1}, + {"cmd_resp_received", item_size(cmd_resp_received), + item_addr(cmd_resp_received), 1}, + {"event_received", item_size(event_received), + item_addr(event_received), 1}, + + /* variables defined in struct mwifiex_adapter */ + {"ioctl_pending", adapter_item_size(ioctl_pending), + adapter_item_addr(ioctl_pending), 1}, + {"tx_pending", adapter_item_size(tx_pending), + adapter_item_addr(tx_pending), 1}, + {"rx_pending", adapter_item_size(rx_pending), + adapter_item_addr(rx_pending), 1}, +}; + +static int num_of_items = ARRAY_SIZE(items); + +/* + * Generic proc file open handler. + * + * This function is called every time a file is accessed for read or write. + */ +static int +mwifiex_open_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +/* + * Proc info file read handler. + * + * This function is called when the 'info' file is opened for reading. + * It prints the following driver related information - + * - Driver name + * - Driver version + * - Driver extended version + * - Interface name + * - BSS mode + * - Media state (connected or disconnected) + * - MAC address + * - Total number of Tx bytes + * - Total number of Rx bytes + * - Total number of Tx packets + * - Total number of Rx packets + * - Total number of dropped Tx packets + * - Total number of dropped Rx packets + * - Total number of corrupted Tx packets + * - Total number of corrupted Rx packets + * - Carrier status (on or off) + * - Tx queue status (started or stopped) + * + * For STA mode drivers, it also prints the following extra - + * - ESSID + * - BSSID + * - Channel + * - Region code + * - Multicast count + * - Multicast addresses + */ +static ssize_t +mwifiex_info_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct mwifiex_private *priv = + (struct mwifiex_private *) file->private_data; + struct net_device *netdev = priv->netdev; + struct netdev_hw_addr *ha; + unsigned long page = get_zeroed_page(GFP_KERNEL); + char *p = (char *) page, fmt[64]; + struct mwifiex_bss_info info; + ssize_t ret = 0; + int i = 0; + + if (!p) + return -ENOMEM; + + memset(&info, 0, sizeof(info)); + ret = mwifiex_get_bss_info(priv, &info); + if (ret) + goto free_and_exit; + + mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1); + + if (!priv->version_str[0]) + mwifiex_get_ver_ext(priv); + + p += sprintf(p, "driver_name = " "\"mwifiex\"\n"); + p += sprintf(p, "driver_version = %s", fmt); + p += sprintf(p, "\nverext = %s", priv->version_str); + p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name); + p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); + p += sprintf(p, "media_state=\"%s\"\n", + (!priv->media_connected ? "Disconnected" : "Connected")); + p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", + netdev->dev_addr[0], netdev->dev_addr[1], + netdev->dev_addr[2], netdev->dev_addr[3], + netdev->dev_addr[4], netdev->dev_addr[5]); + + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) { + p += sprintf(p, "multicast_count=\"%d\"\n", + netdev_mc_count(netdev)); + p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); + p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", + info.bssid[0], info.bssid[1], + info.bssid[2], info.bssid[3], + info.bssid[4], info.bssid[5]); + p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); + p += sprintf(p, "region_code = \"%02x\"\n", info.region_code); + + netdev_for_each_mc_addr(ha, netdev) + p += sprintf(p, "multicast_address[%d]=" + "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++, + ha->addr[0], ha->addr[1], + ha->addr[2], ha->addr[3], + ha->addr[4], ha->addr[5]); + } + + p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); + p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes); + p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets); + p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets); + p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped); + p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped); + p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors); + p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); + p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) + ? "on" : "off")); + p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev)) + ? "stopped" : "started")); + + ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, + (unsigned long) p - page); + +free_and_exit: + free_page(page); + return ret; +} + +/* + * Proc getlog file read handler. + * + * This function is called when the 'getlog' file is opened for reading + * It prints the following log information - + * - Number of multicast Tx frames + * - Number of failed packets + * - Number of Tx retries + * - Number of multicast Tx retries + * - Number of duplicate frames + * - Number of RTS successes + * - Number of RTS failures + * - Number of ACK failures + * - Number of fragmented Rx frames + * - Number of multicast Rx frames + * - Number of FCS errors + * - Number of Tx frames + * - WEP ICV error counts + */ +static ssize_t +mwifiex_getlog_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct mwifiex_private *priv = + (struct mwifiex_private *) file->private_data; + unsigned long page = get_zeroed_page(GFP_KERNEL); + char *p = (char *) page; + ssize_t ret = 0; + struct mwifiex_ds_get_stats stats; + + if (!p) + return -ENOMEM; + + memset(&stats, 0, sizeof(stats)); + ret = mwifiex_get_stats_info(priv, &stats); + if (ret) + goto free_and_exit; + + p += sprintf(p, "\n" + "mcasttxframe %u\n" + "failed %u\n" + "retry %u\n" + "multiretry %u\n" + "framedup %u\n" + "rtssuccess %u\n" + "rtsfailure %u\n" + "ackfailure %u\n" + "rxfrag %u\n" + "mcastrxframe %u\n" + "fcserror %u\n" + "txframe %u\n" + "wepicverrcnt-1 %u\n" + "wepicverrcnt-2 %u\n" + "wepicverrcnt-3 %u\n" + "wepicverrcnt-4 %u\n", + stats.mcast_tx_frame, + stats.failed, + stats.retry, + stats.multi_retry, + stats.frame_dup, + stats.rts_success, + stats.rts_failure, + stats.ack_failure, + stats.rx_frag, + stats.mcast_rx_frame, + stats.fcs_error, + stats.tx_frame, + stats.wep_icv_error[0], + stats.wep_icv_error[1], + stats.wep_icv_error[2], + stats.wep_icv_error[3]); + + + ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, + (unsigned long) p - page); + +free_and_exit: + free_page(page); + return ret; +} + +static struct mwifiex_debug_info info; + +/* + * Proc debug file read handler. + * + * This function is called when the 'debug' file is opened for reading + * It prints the following log information - + * - Interrupt count + * - WMM AC VO packets count + * - WMM AC VI packets count + * - WMM AC BE packets count + * - WMM AC BK packets count + * - Maximum Tx buffer size + * - Tx buffer size + * - Current Tx buffer size + * - Power Save mode + * - Power Save state + * - Deep Sleep status + * - Device wakeup required status + * - Number of wakeup tries + * - Host Sleep configured status + * - Host Sleep activated status + * - Number of Tx timeouts + * - Number of command timeouts + * - Last timed out command ID + * - Last timed out command action + * - Last command ID + * - Last command action + * - Last command index + * - Last command response ID + * - Last command response index + * - Last event + * - Last event index + * - Number of host to card command failures + * - Number of sleep confirm command failures + * - Number of host to card data failure + * - Number of deauthentication events + * - Number of disassociation events + * - Number of link lost events + * - Number of deauthentication commands + * - Number of association success commands + * - Number of association failure commands + * - Number of commands sent + * - Number of data packets sent + * - Number of command responses received + * - Number of events received + * - Tx BA stream table (TID, RA) + * - Rx reorder table (TID, TA, Start window, Window size, Buffer) + */ +static ssize_t +mwifiex_debug_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct mwifiex_private *priv = + (struct mwifiex_private *) file->private_data; + struct mwifiex_debug_data *d = &items[0]; + unsigned long page = get_zeroed_page(GFP_KERNEL); + char *p = (char *) page; + ssize_t ret = 0; + size_t size, addr; + long val; + int i, j; + + if (!p) + return -ENOMEM; + + ret = mwifiex_get_debug_info(priv, &info); + if (ret) + goto free_and_exit; + + for (i = 0; i < num_of_items; i++) { + p += sprintf(p, "%s=", d[i].name); + + size = d[i].size / d[i].num; + + if (i < (num_of_items - 3)) + addr = d[i].addr + (size_t) &info; + else /* The last 3 items are struct mwifiex_adapter variables */ + addr = d[i].addr + (size_t) priv->adapter; + + for (j = 0; j < d[i].num; j++) { + switch (size) { + case 1: + val = *((u8 *) addr); + break; + case 2: + val = *((u16 *) addr); + break; + case 4: + val = *((u32 *) addr); + break; + case 8: + val = *((long long *) addr); + break; + default: + val = -1; + break; + } + + p += sprintf(p, "%#lx ", val); + addr += size; + } + + p += sprintf(p, "\n"); + } + + if (info.tx_tbl_num) { + p += sprintf(p, "Tx BA stream table:\n"); + for (i = 0; i < info.tx_tbl_num; i++) + p += sprintf(p, "tid = %d, " + "ra = %02x:%02x:%02x:%02x:%02x:%02x\n", + info.tx_tbl[i].tid, info.tx_tbl[i].ra[0], + info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2], + info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4], + info.tx_tbl[i].ra[5]); + } + + if (info.rx_tbl_num) { + p += sprintf(p, "Rx reorder table:\n"); + for (i = 0; i < info.rx_tbl_num; i++) { + + p += sprintf(p, "tid = %d, " + "ta = %02x:%02x:%02x:%02x:%02x:%02x, " + "start_win = %d, " + "win_size = %d, buffer: ", + info.rx_tbl[i].tid, + info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1], + info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3], + info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5], + info.rx_tbl[i].start_win, + info.rx_tbl[i].win_size); + + for (j = 0; j < info.rx_tbl[i].win_size; j++) + p += sprintf(p, "%c ", + info.rx_tbl[i].buffer[j] ? + '1' : '0'); + + p += sprintf(p, "\n"); + } + } + + ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, + (unsigned long) p - page); + +free_and_exit: + free_page(page); + return ret; +} + +static u32 saved_reg_type, saved_reg_offset, saved_reg_value; + +/* + * Proc regrdwr file write handler. + * + * This function is called when the 'regrdwr' file is opened for writing + * + * This function can be used to write to a register. + */ +static ssize_t +mwifiex_regrdwr_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + unsigned long addr = get_zeroed_page(GFP_KERNEL); + char *buf = (char *) addr; + size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); + int ret = 0; + u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX; + + if (!buf) + return -ENOMEM; + + + if (copy_from_user(buf, ubuf, buf_size)) { + ret = -EFAULT; + goto done; + } + + sscanf(buf, "%u %x %x", ®_type, ®_offset, ®_value); + + if (reg_type == 0 || reg_offset == 0) { + ret = -EINVAL; + goto done; + } else { + saved_reg_type = reg_type; + saved_reg_offset = reg_offset; + saved_reg_value = reg_value; + ret = count; + } +done: + free_page(addr); + return ret; +} + +/* + * Proc regrdwr file read handler. + * + * This function is called when the 'regrdwr' file is opened for reading + * + * This function can be used to read from a register. + */ +static ssize_t +mwifiex_regrdwr_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct mwifiex_private *priv = + (struct mwifiex_private *) file->private_data; + unsigned long addr = get_zeroed_page(GFP_KERNEL); + char *buf = (char *) addr; + int pos = 0, ret = 0; + u32 reg_value; + + if (!buf) + return -ENOMEM; + + if (!saved_reg_type) { + /* No command has been given */ + pos += snprintf(buf, PAGE_SIZE, "0"); + goto done; + } + /* Set command has been given */ + if (saved_reg_value != UINT_MAX) { + ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset, + saved_reg_value); + + pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", + saved_reg_type, saved_reg_offset, + saved_reg_value); + + ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos); + + goto done; + } + /* Get command has been given */ + ret = mwifiex_reg_read(priv, saved_reg_type, + saved_reg_offset, ®_value); + if (ret) { + ret = -EINVAL; + goto done; + } + + pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type, + saved_reg_offset, reg_value); + + ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos); + +done: + free_page(addr); + return ret; +} + +static u32 saved_offset = -1, saved_bytes = -1; + +/* + * Proc rdeeprom file write handler. + * + * This function is called when the 'rdeeprom' file is opened for writing + * + * This function can be used to write to a RDEEPROM location. + */ +static ssize_t +mwifiex_rdeeprom_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + unsigned long addr = get_zeroed_page(GFP_KERNEL); + char *buf = (char *) addr; + size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); + int ret = 0; + int offset = -1, bytes = -1; + + if (!buf) + return -ENOMEM; + + + if (copy_from_user(buf, ubuf, buf_size)) { + ret = -EFAULT; + goto done; + } + + sscanf(buf, "%d %d", &offset, &bytes); + + if (offset == -1 || bytes == -1) { + ret = -EINVAL; + goto done; + } else { + saved_offset = offset; + saved_bytes = bytes; + ret = count; + } +done: + free_page(addr); + return ret; +} + +/* + * Proc rdeeprom read write handler. + * + * This function is called when the 'rdeeprom' file is opened for reading + * + * This function can be used to read from a RDEEPROM location. + */ +static ssize_t +mwifiex_rdeeprom_read(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct mwifiex_private *priv = + (struct mwifiex_private *) file->private_data; + unsigned long addr = get_zeroed_page(GFP_KERNEL); + char *buf = (char *) addr; + int pos = 0, ret = 0, i = 0; + u8 value[MAX_EEPROM_DATA]; + + if (!buf) + return -ENOMEM; + + if (saved_offset == -1) { + /* No command has been given */ + pos += snprintf(buf, PAGE_SIZE, "0"); + goto done; + } + + /* Get command has been given */ + ret = mwifiex_eeprom_read(priv, (u16) saved_offset, + (u16) saved_bytes, value); + if (ret) { + ret = -EINVAL; + goto done; + } + + pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes); + + for (i = 0; i < saved_bytes; i++) + pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]); + + ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos); + +done: + free_page(addr); + return ret; +} + + +#define MWIFIEX_DFS_ADD_FILE(name) do { \ + if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \ + priv, &mwifiex_dfs_##name##_fops)) \ + return; \ +} while (0); + +#define MWIFIEX_DFS_FILE_OPS(name) \ +static const struct file_operations mwifiex_dfs_##name##_fops = { \ + .read = mwifiex_##name##_read, \ + .write = mwifiex_##name##_write, \ + .open = mwifiex_open_generic, \ +}; + +#define MWIFIEX_DFS_FILE_READ_OPS(name) \ +static const struct file_operations mwifiex_dfs_##name##_fops = { \ + .read = mwifiex_##name##_read, \ + .open = mwifiex_open_generic, \ +}; + +#define MWIFIEX_DFS_FILE_WRITE_OPS(name) \ +static const struct file_operations mwifiex_dfs_##name##_fops = { \ + .write = mwifiex_##name##_write, \ + .open = mwifiex_open_generic, \ +}; + + +MWIFIEX_DFS_FILE_READ_OPS(info); +MWIFIEX_DFS_FILE_READ_OPS(debug); +MWIFIEX_DFS_FILE_READ_OPS(getlog); +MWIFIEX_DFS_FILE_OPS(regrdwr); +MWIFIEX_DFS_FILE_OPS(rdeeprom); + +/* + * This function creates the debug FS directory structure and the files. + */ +void +mwifiex_dev_debugfs_init(struct mwifiex_private *priv) +{ + if (!mwifiex_dfs_dir || !priv) + return; + + priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name, + mwifiex_dfs_dir); + + if (!priv->dfs_dev_dir) + return; + + MWIFIEX_DFS_ADD_FILE(info); + MWIFIEX_DFS_ADD_FILE(debug); + MWIFIEX_DFS_ADD_FILE(getlog); + MWIFIEX_DFS_ADD_FILE(regrdwr); + MWIFIEX_DFS_ADD_FILE(rdeeprom); + + return; +} + +/* + * This function removes the debug FS directory structure and the files. + */ +void +mwifiex_dev_debugfs_remove(struct mwifiex_private *priv) +{ + if (!priv) + return; + + debugfs_remove_recursive(priv->dfs_dev_dir); + return; +} + +/* + * This function creates the top level proc directory. + */ +void +mwifiex_debugfs_init(void) +{ + if (!mwifiex_dfs_dir) + mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL); +} + +/* + * This function removes the top level proc directory. + */ +void +mwifiex_debugfs_remove(void) +{ + if (mwifiex_dfs_dir) + debugfs_remove(mwifiex_dfs_dir); +} diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h new file mode 100644 index 000000000000..4e1f115d3ec3 --- /dev/null +++ b/drivers/net/wireless/mwifiex/decl.h @@ -0,0 +1,177 @@ +/* + * Marvell Wireless LAN device driver: generic data structures and APIs + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_DECL_H_ +#define _MWIFIEX_DECL_H_ + +#undef pr_fmt +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include + + +#define MWIFIEX_MAX_BSS_NUM (1) + +#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */ + +#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 +#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 + +#define MWIFIEX_AMPDU_DEF_TXWINSIZE 32 +#define MWIFIEX_AMPDU_DEF_RXWINSIZE 16 +#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff + +#define MWIFIEX_RATE_INDEX_HRDSSS0 0 +#define MWIFIEX_RATE_INDEX_HRDSSS3 3 +#define MWIFIEX_RATE_INDEX_OFDM0 4 +#define MWIFIEX_RATE_INDEX_OFDM7 11 +#define MWIFIEX_RATE_INDEX_MCS0 12 + +#define MWIFIEX_RATE_BITMAP_OFDM0 16 +#define MWIFIEX_RATE_BITMAP_OFDM7 23 +#define MWIFIEX_RATE_BITMAP_MCS0 32 +#define MWIFIEX_RATE_BITMAP_MCS127 159 + +#define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024) +#define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024) + +#define MWIFIEX_RTS_MIN_VALUE (0) +#define MWIFIEX_RTS_MAX_VALUE (2347) +#define MWIFIEX_FRAG_MIN_VALUE (256) +#define MWIFIEX_FRAG_MAX_VALUE (2346) + +#define MWIFIEX_SDIO_BLOCK_SIZE 256 + +#define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) + +enum mwifiex_error_code { + MWIFIEX_ERROR_NO_ERROR = 0, + MWIFIEX_ERROR_FW_NOT_READY = 0x00000001, + MWIFIEX_ERROR_FW_BUSY, + MWIFIEX_ERROR_FW_CMDRESP, + MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001, + MWIFIEX_ERROR_PKT_TIMEOUT, + MWIFIEX_ERROR_CMD_INVALID, + MWIFIEX_ERROR_CMD_TIMEOUT, + MWIFIEX_ERROR_CMD_DNLD_FAIL, + MWIFIEX_ERROR_CMD_CANCEL, + MWIFIEX_ERROR_CMD_RESP_FAIL, + MWIFIEX_ERROR_ASSOC_FAIL, + MWIFIEX_ERROR_EVENT_UNKNOWN, + MWIFIEX_ERROR_INVALID_PARAMETER, +}; + +enum mwifiex_bss_type { + MWIFIEX_BSS_TYPE_STA = 0, + MWIFIEX_BSS_TYPE_UAP = 1, + MWIFIEX_BSS_TYPE_ANY = 0xff, +}; + +enum mwifiex_bss_role { + MWIFIEX_BSS_ROLE_STA = 0, + MWIFIEX_BSS_ROLE_UAP = 1, + MWIFIEX_BSS_ROLE_ANY = 0xff, +}; + +#define BSS_ROLE_BIT_MASK BIT(0) + +#define GET_BSS_ROLE(priv) ((priv)->bss_role & BSS_ROLE_BIT_MASK) + +enum mwifiex_data_frame_type { + MWIFIEX_DATA_FRAME_TYPE_ETH_II = 0, + MWIFIEX_DATA_FRAME_TYPE_802_11, +}; + +struct mwifiex_fw_image { + u8 *helper_buf; + u32 helper_len; + u8 *fw_buf; + u32 fw_len; +}; + +struct mwifiex_802_11_ssid { + u32 ssid_len; + u8 ssid[IEEE80211_MAX_SSID_LEN]; +}; + +struct mwifiex_wait_queue { + u32 bss_index; + wait_queue_head_t *wait; + u16 *condition; + u32 start_time; + int status; + u32 enabled; +}; + +struct mwifiex_rxinfo { + u8 bss_index; + struct sk_buff *parent; + u8 use_count; +}; + +struct mwifiex_txinfo { + u32 status_code; + u8 flags; + u8 bss_index; +}; + +struct mwifiex_bss_attr { + u32 bss_type; + u32 frame_type; + u32 active; + u32 bss_priority; + u32 bss_num; +}; + +enum mwifiex_cmd_result_e { + MWIFIEX_CMD_RESULT_SUCCESS = 0, + MWIFIEX_CMD_RESULT_FAILURE = 1, + MWIFIEX_CMD_RESULT_TIMEOUT = 2, + MWIFIEX_CMD_RESULT_INVALID_DATA = 3 +} __packed; + +enum mwifiex_wmm_ac_e { + WMM_AC_BK, + WMM_AC_BE, + WMM_AC_VI, + WMM_AC_VO +} __packed; + +enum mwifiex_wmm_queue_config_action_e { + MWIFIEX_WMM_QUEUE_CONFIG_ACTION_GET = 0, + MWIFIEX_WMM_QUEUE_CONFIG_ACTION_SET = 1, + MWIFIEX_WMM_QUEUE_CONFIG_ACTION_DEFAULT = 2, + MWIFIEX_WMM_QUEUE_CONFIG_ACTION_MAX +} __packed; + +enum mwifiex_wmm_queue_stats_action_e { + MWIFIEX_WMM_STATS_ACTION_START = 0, + MWIFIEX_WMM_STATS_ACTION_STOP = 1, + MWIFIEX_WMM_STATS_ACTION_GET_CLR = 2, + MWIFIEX_WMM_STATS_ACTION_SET_CFG = 3, /* Not currently used */ + MWIFIEX_WMM_STATS_ACTION_GET_CFG = 4, /* Not currently used */ + MWIFIEX_WMM_STATS_ACTION_MAX +} __packed; + +struct mwifiex_device { + struct mwifiex_bss_attr bss_attr[MWIFIEX_MAX_BSS_NUM]; +}; +#endif /* !_MWIFIEX_DECL_H_ */ diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h new file mode 100644 index 000000000000..e5dae45b11d2 --- /dev/null +++ b/drivers/net/wireless/mwifiex/fw.h @@ -0,0 +1,1376 @@ +/* + * Marvell Wireless LAN device driver: Firmware specific macros & structures + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_FW_H_ +#define _MWIFIEX_FW_H_ + +#include + + +#define INTF_HEADER_LEN 4 + +struct rfc_1042_hdr { + u8 llc_dsap; + u8 llc_ssap; + u8 llc_ctrl; + u8 snap_oui[3]; + u16 snap_type; +}; + +struct rx_packet_hdr { + struct ethhdr eth803_hdr; + struct rfc_1042_hdr rfc1042_hdr; +}; + +struct tx_packet_hdr { + struct ethhdr eth803_hdr; + struct rfc_1042_hdr rfc1042_hdr; +}; + +#define B_SUPPORTED_RATES 5 +#define G_SUPPORTED_RATES 9 +#define BG_SUPPORTED_RATES 13 +#define A_SUPPORTED_RATES 9 +#define HOSTCMD_SUPPORTED_RATES 14 +#define N_SUPPORTED_RATES 3 +#define ALL_802_11_BANDS (BAND_A | BAND_B | BAND_G | BAND_GN) + +#define FW_MULTI_BANDS_SUPPORT (BIT(8) | BIT(9) | BIT(10) | BIT(11)) +#define IS_SUPPORT_MULTI_BANDS(adapter) \ + (adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT) +#define GET_FW_DEFAULT_BANDS(adapter) \ + ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS) + +#define SHORT_SLOT_TIME_DISABLED(CapInfo) (CapInfo &= ~BIT(10)) +#define SHORT_SLOT_TIME_ENABLED(CapInfo) (CapInfo |= BIT(10)) + +extern u8 supported_rates_b[B_SUPPORTED_RATES]; +extern u8 supported_rates_g[G_SUPPORTED_RATES]; +extern u8 supported_rates_bg[BG_SUPPORTED_RATES]; +extern u8 supported_rates_a[A_SUPPORTED_RATES]; +extern u8 supported_rates_n[N_SUPPORTED_RATES]; + +#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff + +#define KEY_INFO_ENABLED 0x01 +enum KEY_TYPE_ID { + KEY_TYPE_ID_WEP = 0, + KEY_TYPE_ID_TKIP, + KEY_TYPE_ID_AES, + KEY_TYPE_ID_WAPI, +}; + +enum KEY_INFO_WEP { + KEY_INFO_WEP_MCAST = 0x01, + KEY_INFO_WEP_UNICAST = 0x02, + KEY_INFO_WEP_ENABLED = 0x04 +}; + +enum KEY_INFO_TKIP { + KEY_INFO_TKIP_MCAST = 0x01, + KEY_INFO_TKIP_UNICAST = 0x02, + KEY_INFO_TKIP_ENABLED = 0x04 +}; + +enum KEY_INFO_AES { + KEY_INFO_AES_MCAST = 0x01, + KEY_INFO_AES_UNICAST = 0x02, + KEY_INFO_AES_ENABLED = 0x04 +}; + +#define WAPI_KEY_LEN 50 + +enum KEY_INFO_WAPI { + KEY_INFO_WAPI_MCAST = 0x01, + KEY_INFO_WAPI_UNICAST = 0x02, + KEY_INFO_WAPI_ENABLED = 0x04 +}; + +#define MAX_POLL_TRIES 100 + +#define MAX_MULTI_INTERFACE_POLL_TRIES 1000 + +#define MAX_FIRMWARE_POLL_TRIES 100 + +#define FIRMWARE_READY 0xfedc + +#define FIRMWARE_TRANSFER_NBLOCK 2 + +enum MWIFIEX_802_11_PRIVACY_FILTER { + MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL, + MWIFIEX_802_11_PRIV_FILTER_8021X_WEP +}; + +enum MWIFIEX_802_11_WEP_STATUS { + MWIFIEX_802_11_WEP_ENABLED, + MWIFIEX_802_11_WEP_DISABLED, +}; + +#define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF))) + +#define PROPRIETARY_TLV_BASE_ID 0x0100 +#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) +#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1) +#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2) +#define TLV_TYPE_RSSI_LOW (PROPRIETARY_TLV_BASE_ID + 4) +#define TLV_TYPE_SNR_LOW (PROPRIETARY_TLV_BASE_ID + 5) +#define TLV_TYPE_FAILCOUNT (PROPRIETARY_TLV_BASE_ID + 6) +#define TLV_TYPE_BCNMISS (PROPRIETARY_TLV_BASE_ID + 7) +#define TLV_TYPE_LEDBEHAVIOR (PROPRIETARY_TLV_BASE_ID + 9) +#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10) +#define TLV_TYPE_POWER_TBL_2_4GHZ (PROPRIETARY_TLV_BASE_ID + 12) +#define TLV_TYPE_POWER_TBL_5GHZ (PROPRIETARY_TLV_BASE_ID + 13) +#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16) +#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18) +#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) +#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) +#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23) + +#define TLV_TYPE_STARTBGSCANLATER (PROPRIETARY_TLV_BASE_ID + 30) +#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) +#define TLV_TYPE_LINK_QUALITY (PROPRIETARY_TLV_BASE_ID + 36) +#define TLV_TYPE_RSSI_LOW_DATA (PROPRIETARY_TLV_BASE_ID + 38) +#define TLV_TYPE_SNR_LOW_DATA (PROPRIETARY_TLV_BASE_ID + 39) +#define TLV_TYPE_RSSI_HIGH_DATA (PROPRIETARY_TLV_BASE_ID + 40) +#define TLV_TYPE_SNR_HIGH_DATA (PROPRIETARY_TLV_BASE_ID + 41) + +#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) +#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) +#define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) + +#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 + +#define TLV_TYPE_HT_CAP (PROPRIETARY_TLV_BASE_ID + 74) +#define TLV_TYPE_HT_INFO (PROPRIETARY_TLV_BASE_ID + 75) +#define TLV_SECONDARY_CHANNEL_OFFSET (PROPRIETARY_TLV_BASE_ID + 76) +#define TLV_TYPE_2040BSS_COEXISTENCE (PROPRIETARY_TLV_BASE_ID + 77) +#define TLV_TYPE_OVERLAP_BSS_SCAN_PARAM (PROPRIETARY_TLV_BASE_ID + 78) +#define TLV_TYPE_EXTCAP (PROPRIETARY_TLV_BASE_ID + 79) +#define TLV_TYPE_HT_OPERATIONAL_MCS_SET (PROPRIETARY_TLV_BASE_ID + 80) + +#define ADDBA_TID_MASK (BIT(2) | BIT(3) | BIT(4) | BIT(5)) +#define DELBA_TID_MASK (BIT(12) | BIT(13) | BIT(14) | BIT(15)) +#define SSN_MASK 0xfff0 + +#define BA_RESULT_SUCCESS 0x0 +#define BA_RESULT_FAILURE 0x1 +#define BA_RESULT_TIMEOUT 0x2 +#define BA_RESULT_DATA_INVALID 0x3 + +#define IS_BASTREAM_SETUP(ptr) (ptr->ba_status) + +#define BA_STREAM_NOT_ALLOWED 0xff + +#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \ + priv->adapter->config_bands & BAND_AN) \ + && priv->curr_bss_params.bss_descriptor.bcn_ht_cap) +#define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\ + BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS) + +#define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096 +#define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 +#define MAX_RX_AMPDU_SIZE_64K 0x03 +#define NON_GREENFIELD_STAS 0x04 + +#define HWSPEC_GREENFIELD_SUPP BIT(29) +#define HWSPEC_RXSTBC_SUPP BIT(26) +#define HWSPEC_SHORTGI40_SUPP BIT(24) +#define HWSPEC_SHORTGI20_SUPP BIT(23) +#define HWSPEC_CHANBW40_SUPP BIT(17) + +#define DEFAULT_11N_CAP_MASK (HWSPEC_SHORTGI20_SUPP | HWSPEC_RXSTBC_SUPP) +#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) +#define ISSUPP_MAXAMSDU(Dot11nDevCap) (Dot11nDevCap & BIT(31)) +#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30)) +#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) +#define ISSUPP_AMPDU(Dot11nDevCap) (Dot11nDevCap & BIT(28)) +#define ISSUPP_MIMOPS(Dot11nDevCap) (Dot11nDevCap & BIT(27)) +#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) +#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) +#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24)) +#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23)) +#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) +#define GET_DELAYEDBACK(Dot11nDevCap) (((Dot11nDevCap >> 20) & 0x03)) +#define GET_IMMEDIATEBACK(Dot11nDevCap) (((Dot11nDevCap >> 18) & 0x03)) +#define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & BIT(17)) +#define ISSUPP_CHANWIDTH20(Dot11nDevCap) (Dot11nDevCap & BIT(16)) +#define ISSUPP_CHANWIDTH10(Dot11nDevCap) (Dot11nDevCap & BIT(15)) +#define ISENABLED_40MHZ_INTOLARENT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) +#define ISSUPP_RXANTENNAD(Dot11nDevCap) (Dot11nDevCap & BIT(7)) +#define ISSUPP_RXANTENNAC(Dot11nDevCap) (Dot11nDevCap & BIT(6)) +#define ISSUPP_RXANTENNAB(Dot11nDevCap) (Dot11nDevCap & BIT(5)) +#define ISSUPP_RXANTENNAA(Dot11nDevCap) (Dot11nDevCap & BIT(4)) +#define ISSUPP_TXANTENNAD(Dot11nDevCap) (Dot11nDevCap & BIT(3)) +#define ISSUPP_TXANTENNAC(Dot11nDevCap) (Dot11nDevCap & BIT(2)) +#define ISSUPP_TXANTENNAB(Dot11nDevCap) (Dot11nDevCap & BIT(1)) +#define ISSUPP_TXANTENNAA(Dot11nDevCap) (Dot11nDevCap & BIT(0)) +#define SETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap |= BIT(17)) +#define RESETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap &= ~BIT(17)) +#define GET_TXMCSSUPP(DevMCSSupported) (DevMCSSupported >> 4) +#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) +#define GETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo & BIT(1)) +#define GETHT_GREENFIELD(HTCapInfo) (HTCapInfo & BIT(4)) +#define GETHT_SHORTGI20(HTCapInfo) (HTCapInfo & BIT(5)) +#define GETHT_SHORTGI40(HTCapInfo) (HTCapInfo & BIT(6)) +#define GETHT_TXSTBC(HTCapInfo) (HTCapInfo & BIT(7)) +#define GETHT_RXSTBC(HTCapInfo) ((HTCapInfo >> 8) & 0x03) +#define GETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo & BIT(10)) +#define GETHT_MAXAMSDU(HTCapInfo) (HTCapInfo & BIT(11)) +#define SETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo |= BIT(1)) +#define SETHT_GREENFIELD(HTCapInfo) (HTCapInfo |= BIT(4)) +#define SETHT_SHORTGI20(HTCapInfo) (HTCapInfo |= BIT(5)) +#define SETHT_SHORTGI40(HTCapInfo) (HTCapInfo |= BIT(6)) +#define SETHT_TXSTBC(HTCapInfo) (HTCapInfo |= BIT(7)) +#define SETHT_RXSTBC(HTCapInfo, value) (HTCapInfo |= (value << 8)) +#define SETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo |= BIT(10)) +#define SETHT_MAXAMSDU(HTCapInfo) (HTCapInfo |= BIT(11)) +#define SETHT_DSSSCCK40(HTCapInfo) (HTCapInfo |= BIT(12)) +#define SETHT_40MHZ_INTOLARANT(HTCapInfo) (HTCapInfo |= BIT(14)) +#define RESETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo &= ~BIT(1)) +#define RESETHT_GREENFIELD(HTCapInfo) (HTCapInfo &= ~BIT(4)) +#define RESETHT_SHORTGI20(HTCapInfo) (HTCapInfo &= ~BIT(5)) +#define RESETHT_SHORTGI40(HTCapInfo) (HTCapInfo &= ~BIT(6)) +#define RESETHT_TXSTBC(HTCapInfo) (HTCapInfo &= ~BIT(7)) +#define RESETHT_RXSTBC(HTCapInfo) (HTCapInfo &= ~(0x03 << 8)) +#define RESETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo &= ~BIT(10)) +#define RESETHT_MAXAMSDU(HTCapInfo) (HTCapInfo &= ~BIT(11)) +#define RESETHT_40MHZ_INTOLARANT(HTCapInfo) (HTCapInfo &= ~BIT(14)) +#define RESETHT_EXTCAP_RDG(HTExtCap) (HTExtCap &= ~BIT(11)) +#define SETHT_MCS32(x) (x[4] |= 1) +#define SETHT_MCS_SET_DEFINED(x) (x[12] |= 1) +#define SETHT_RX_HIGHEST_DT_SUPP(x, y) ((*(u16 *) (x + 10)) = y) +#define AMPDU_FACTOR_64K 0x03 +#define SETAMPDU_SIZE(x, y) do { \ + x = x & ~0x03; \ + x |= y & 0x03; \ +} while (0) \ + +#define SETAMPDU_SPACING(x, y) do { \ + x = x & ~0x1c; \ + x |= (y & 0x07) << 2; \ +} while (0) \ + +#define ISSUPP_BANDA(FwCapInfo) (FwCapInfo & BIT(10)) +#define ISALLOWED_CHANWIDTH40(Field2) (Field2 & BIT(2)) +#define SET_CHANWIDTH40(Field2) (Field2 |= BIT(2)) +#define RESET_CHANWIDTH40(Field2) (Field2 &= ~(BIT(0) | BIT(1) | BIT(2))) +#define GET_SECONDARYCHAN(Field2) (Field2 & (BIT(0) | BIT(1))) +#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) + +#define LLC_SNAP_LEN 8 + +#define TLV_TYPE_RATE_DROP_PATTERN (PROPRIETARY_TLV_BASE_ID + 81) +#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) +#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) + +#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) + +#define MOD_CLASS_HR_DSSS 0x03 +#define MOD_CLASS_OFDM 0x07 +#define MOD_CLASS_HT 0x08 +#define HT_BW_20 0 +#define HT_BW_40 1 + +#define HostCmd_CMD_GET_HW_SPEC 0x0003 +#define HostCmd_CMD_802_11_SCAN 0x0006 +#define HostCmd_CMD_802_11_GET_LOG 0x000b +#define HostCmd_CMD_MAC_MULTICAST_ADR 0x0010 +#define HostCmd_CMD_802_11_EEPROM_ACCESS 0x0059 +#define HostCmd_CMD_802_11_ASSOCIATE 0x0012 +#define HostCmd_CMD_802_11_SNMP_MIB 0x0016 +#define HostCmd_CMD_MAC_REG_ACCESS 0x0019 +#define HostCmd_CMD_BBP_REG_ACCESS 0x001a +#define HostCmd_CMD_RF_REG_ACCESS 0x001b +#define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad +#define HostCmd_CMD_802_11_RF_CHANNEL 0x001d +#define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024 +#define HostCmd_CMD_MAC_CONTROL 0x0028 +#define HostCmd_CMD_802_11_AD_HOC_START 0x002b +#define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c +#define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040 +#define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D +#define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b +#define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e +#define HostCmd_CMD_802_11_BG_SCAN_QUERY 0x006c +#define HostCmd_CMD_WMM_GET_STATUS 0x0071 +#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f +#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083 +#define HostCmd_CMD_VERSION_EXT 0x0097 +#define HostCmd_CMD_RSSI_INFO 0x00a4 +#define HostCmd_CMD_FUNC_INIT 0x00a9 +#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa +#define HostCmd_CMD_11N_CFG 0x00cd +#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce +#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf +#define HostCmd_CMD_11N_DELBA 0x00d0 +#define HostCmd_CMD_RECONFIGURE_TX_BUFF 0x00d9 +#define HostCmd_CMD_AMSDU_AGGR_CTRL 0x00df +#define HostCmd_CMD_TXPWR_CFG 0x00d1 +#define HostCmd_CMD_TX_RATE_CFG 0x00d6 +#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4 +#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5 +#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed +#define HostCmd_CMD_SET_BSS_MODE 0x00f7 + + +enum ENH_PS_MODES { + EN_PS = 1, + DIS_PS = 2, + EN_AUTO_DS = 3, + DIS_AUTO_DS = 4, + SLEEP_CONFIRM = 5, + GET_PS = 0, + EN_AUTO_PS = 0xff, + DIS_AUTO_PS = 0xfe, +}; + +#define HostCmd_RET_BIT 0x8000 +#define HostCmd_ACT_GEN_GET 0x0000 +#define HostCmd_ACT_GEN_SET 0x0001 +#define HostCmd_ACT_GEN_REMOVE 0x0004 +#define HostCmd_ACT_SET_BOTH 0x0003 +#define HostCmd_ACT_GET_BOTH 0x000c +#define HostCmd_RESULT_OK 0x0000 +#define HostCmd_RESULT_ERROR 0x0001 +#define HostCmd_RESULT_NOT_SUPPORT 0x0002 +#define HostCmd_RESULT_PENDING 0x0003 +#define HostCmd_RESULT_BUSY 0x0004 +#define HostCmd_RESULT_PARTIAL_DATA 0x0005 + +#define HostCmd_ACT_MAC_RX_ON 0x0001 +#define HostCmd_ACT_MAC_TX_ON 0x0002 +#define HostCmd_ACT_MAC_WEP_ENABLE 0x0008 +#define HostCmd_ACT_MAC_ETHERNETII_ENABLE 0x0010 +#define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE 0x0080 +#define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100 +#define HostCmd_ACT_MAC_RTS_CTS_ENABLE 0x0200 +#define HostCmd_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400 +#define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON 0x2000 + +#define HostCmd_BSS_MODE_BSS 0x0001 +#define HostCmd_BSS_MODE_IBSS 0x0002 +#define HostCmd_BSS_MODE_ANY 0x0003 + +#define HostCmd_SCAN_RADIO_TYPE_BG 0 +#define HostCmd_SCAN_RADIO_TYPE_A 1 + +#define HOST_SLEEP_CFG_CANCEL 0xffffffff +#define HOST_SLEEP_CFG_COND_DEF 0x0000000f +#define HOST_SLEEP_CFG_GPIO_DEF 0xff +#define HOST_SLEEP_CFG_GAP_DEF 0 + +#define CMD_F_HOSTCMD (1 << 0) +#define CMD_F_CANCELED (1 << 1) + +#define HostCmd_CMD_ID_MASK 0x0fff + +#define HostCmd_SEQ_NUM_MASK 0x00ff + +#define HostCmd_BSS_NUM_MASK 0x0f00 + +#define HostCmd_BSS_TYPE_MASK 0xf000 + +#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) { \ + (((seq) & 0x00ff) | \ + (((num) & 0x000f) << 8)) | \ + (((type) & 0x000f) << 12); } + +#define HostCmd_GET_SEQ_NO(seq) \ + ((seq) & HostCmd_SEQ_NUM_MASK) + +#define HostCmd_GET_BSS_NO(seq) \ + (((seq) & HostCmd_BSS_NUM_MASK) >> 8) + +#define HostCmd_GET_BSS_TYPE(seq) \ + (((seq) & HostCmd_BSS_TYPE_MASK) >> 12) + +#define EVENT_DUMMY_HOST_WAKEUP_SIGNAL 0x00000001 +#define EVENT_LINK_LOST 0x00000003 +#define EVENT_LINK_SENSED 0x00000004 +#define EVENT_MIB_CHANGED 0x00000006 +#define EVENT_INIT_DONE 0x00000007 +#define EVENT_DEAUTHENTICATED 0x00000008 +#define EVENT_DISASSOCIATED 0x00000009 +#define EVENT_PS_AWAKE 0x0000000a +#define EVENT_PS_SLEEP 0x0000000b +#define EVENT_MIC_ERR_MULTICAST 0x0000000d +#define EVENT_MIC_ERR_UNICAST 0x0000000e +#define EVENT_DEEP_SLEEP_AWAKE 0x00000010 +#define EVENT_ADHOC_BCN_LOST 0x00000011 + +#define EVENT_WMM_STATUS_CHANGE 0x00000017 +#define EVENT_BG_SCAN_REPORT 0x00000018 +#define EVENT_RSSI_LOW 0x00000019 +#define EVENT_SNR_LOW 0x0000001a +#define EVENT_MAX_FAIL 0x0000001b +#define EVENT_RSSI_HIGH 0x0000001c +#define EVENT_SNR_HIGH 0x0000001d +#define EVENT_IBSS_COALESCED 0x0000001e +#define EVENT_DATA_RSSI_LOW 0x00000024 +#define EVENT_DATA_SNR_LOW 0x00000025 +#define EVENT_DATA_RSSI_HIGH 0x00000026 +#define EVENT_DATA_SNR_HIGH 0x00000027 +#define EVENT_LINK_QUALITY 0x00000028 +#define EVENT_PORT_RELEASE 0x0000002b +#define EVENT_PRE_BEACON_LOST 0x00000031 +#define EVENT_ADDBA 0x00000033 +#define EVENT_DELBA 0x00000034 +#define EVENT_BA_STREAM_TIEMOUT 0x00000037 +#define EVENT_AMSDU_AGGR_CTRL 0x00000042 +#define EVENT_WEP_ICV_ERR 0x00000046 +#define EVENT_HS_ACT_REQ 0x00000047 +#define EVENT_BW_CHANGE 0x00000048 + +#define EVENT_HOSTWAKE_STAIE 0x0000004d + +#define EVENT_ID_MASK 0xffff +#define BSS_NUM_MASK 0xf + +#define EVENT_GET_BSS_NUM(event_cause) \ + (((event_cause) >> 16) & BSS_NUM_MASK) + +#define EVENT_GET_BSS_TYPE(event_cause) \ + (((event_cause) >> 24) & 0x00ff) + +struct mwifiex_event_wep_icv_err { + u16 reason_code; + u8 src_mac_addr[ETH_ALEN]; + u8 wep_key_index; + u8 wep_key_length; + u8 key[WLAN_KEY_LEN_WEP104]; +}; + +struct mwifiex_802_11_fixed_ies { + u8 time_stamp[8]; + __le16 beacon_interval; + __le16 capabilities; +}; + +struct mwifiex_ie_types_header { + __le16 type; + __le16 len; +} __packed; + +struct mwifiex_ie_types_data { + struct mwifiex_ie_types_header header; + u8 data[1]; +} __packed; + +#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01 +#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08 + +struct txpd { + u8 bss_type; + u8 bss_num; + __le16 tx_pkt_length; + __le16 tx_pkt_offset; + __le16 tx_pkt_type; + __le32 tx_control; + u8 priority; + u8 flags; + u8 pkt_delay_2ms; + u8 reserved1; +} __packed; + +struct rxpd { + u8 bss_type; + u8 bss_num; + u16 rx_pkt_length; + u16 rx_pkt_offset; + u16 rx_pkt_type; + u16 seq_num; + u8 priority; + u8 rx_rate; + s8 snr; + s8 nf; + /* Ht Info [Bit 0] RxRate format: LG=0, HT=1 + * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1 + * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */ + u8 ht_info; + u8 reserved; +} __packed; + +enum mwifiex_chan_scan_mode_bitmasks { + MWIFIEX_PASSIVE_SCAN = BIT(0), + MWIFIEX_DISABLE_CHAN_FILT = BIT(1), +}; + +#define SECOND_CHANNEL_BELOW 0x30 +#define SECOND_CHANNEL_ABOVE 0x10 +struct mwifiex_chan_scan_param_set { + u8 radio_type; + u8 chan_number; + u8 chan_scan_mode_bitmap; + __le16 min_scan_time; + __le16 max_scan_time; +} __packed; + +struct mwifiex_ie_types_chan_list_param_set { + struct mwifiex_ie_types_header header; + struct mwifiex_chan_scan_param_set chan_scan_param[1]; +} __packed; + +struct chan_band_param_set { + u8 radio_type; + u8 chan_number; +}; + +struct mwifiex_ie_types_chan_band_list_param_set { + struct mwifiex_ie_types_header header; + struct chan_band_param_set chan_band_param[1]; +} __packed; + +struct mwifiex_ie_types_rates_param_set { + struct mwifiex_ie_types_header header; + u8 rates[1]; +} __packed; + +struct mwifiex_ie_types_ssid_param_set { + struct mwifiex_ie_types_header header; + u8 ssid[1]; +} __packed; + +struct mwifiex_ie_types_num_probes { + struct mwifiex_ie_types_header header; + __le16 num_probes; +} __packed; + +struct mwifiex_ie_types_wildcard_ssid_params { + struct mwifiex_ie_types_header header; + u8 max_ssid_length; + u8 ssid[1]; +} __packed; + +#define TSF_DATA_SIZE 8 +struct mwifiex_ie_types_tsf_timestamp { + struct mwifiex_ie_types_header header; + u8 tsf_data[1]; +} __packed; + +struct mwifiex_cf_param_set { + u8 cfp_cnt; + u8 cfp_period; + u16 cfp_max_duration; + u16 cfp_duration_remaining; +} __packed; + +struct mwifiex_ibss_param_set { + u16 atim_window; +} __packed; + +struct mwifiex_ie_types_ss_param_set { + struct mwifiex_ie_types_header header; + union { + struct mwifiex_cf_param_set cf_param_set[1]; + struct mwifiex_ibss_param_set ibss_param_set[1]; + } cf_ibss; +} __packed; + +struct mwifiex_fh_param_set { + u16 dwell_time; + u8 hop_set; + u8 hop_pattern; + u8 hop_index; +} __packed; + +struct mwifiex_ds_param_set { + u8 current_chan; +} __packed; + +struct mwifiex_ie_types_phy_param_set { + struct mwifiex_ie_types_header header; + union { + struct mwifiex_fh_param_set fh_param_set[1]; + struct mwifiex_ds_param_set ds_param_set[1]; + } fh_ds; +} __packed; + +struct mwifiex_ie_types_auth_type { + struct mwifiex_ie_types_header header; + __le16 auth_type; +} __packed; + +struct mwifiex_ie_types_vendor_param_set { + struct mwifiex_ie_types_header header; + u8 ie[MWIFIEX_MAX_VSIE_LEN]; +}; + +struct mwifiex_ie_types_rsn_param_set { + struct mwifiex_ie_types_header header; + u8 rsn_ie[1]; +} __packed; + +#define KEYPARAMSET_FIXED_LEN 6 + +struct mwifiex_ie_type_key_param_set { + __le16 type; + __le16 length; + __le16 key_type_id; + __le16 key_info; + __le16 key_len; + u8 key[50]; +} __packed; + +struct host_cmd_ds_802_11_key_material { + __le16 action; + struct mwifiex_ie_type_key_param_set key_param_set; +} __packed; + +struct host_cmd_ds_gen { + u16 command; + u16 size; + u16 seq_num; + u16 result; +}; + +#define S_DS_GEN sizeof(struct host_cmd_ds_gen) + +enum sleep_resp_ctrl { + RESP_NOT_NEEDED = 0, + RESP_NEEDED, +}; + +struct mwifiex_ps_param { + __le16 null_pkt_interval; + __le16 multiple_dtims; + __le16 bcn_miss_timeout; + __le16 local_listen_interval; + __le16 adhoc_wake_period; + __le16 mode; + __le16 delay_to_ps; +}; + +struct mwifiex_auto_ds_param { + __le16 deep_sleep_timeout; +}; + +struct sleep_confirm_param { + __le16 resp_ctrl; +}; + +#define BITMAP_AUTO_DS 0x01 +#define BITMAP_STA_PS 0x10 +#define BITMAP_UAP_INACT_PS 0x100 +#define BITMAP_UAP_DTIM_PS 0x200 +struct auto_ps_param { + __le16 ps_bitmap; + /* auto deep sleep parameter, + * sta power save parameter + * uap inactivity parameter + * uap DTIM parameter */ +}; + +#define AUTO_PS_FIX_SIZE 4 + +#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) +#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) + +struct mwifiex_ie_types_auto_ds_param { + struct mwifiex_ie_types_header header; + struct mwifiex_auto_ds_param param; +} __packed; + +struct mwifiex_ie_types_ps_param { + struct mwifiex_ie_types_header header; + struct mwifiex_ps_param param; +} __packed; + +struct host_cmd_ds_802_11_ps_mode_enh { + __le16 action; + + union { + struct mwifiex_ps_param opt_ps; + struct mwifiex_auto_ds_param auto_ds; + struct sleep_confirm_param sleep_cfm; + __le16 ps_bitmap; + struct auto_ps_param auto_ps; + } params; +} __packed; + +struct host_cmd_ds_get_hw_spec { + __le16 hw_if_version; + __le16 version; + __le16 reserved; + __le16 num_of_mcast_adr; + u8 permanent_addr[ETH_ALEN]; + __le16 region_code; + __le16 number_of_antenna; + __le32 fw_release_number; + __le32 reserved_1; + __le32 reserved_2; + __le32 reserved_3; + __le32 fw_cap_info; + __le32 dot_11n_dev_cap; + u8 dev_mcs_support; + __le16 mp_end_port; /* SDIO only, reserved for other interfacces */ + __le16 reserved_4; +} __packed; + +struct host_cmd_ds_802_11_rssi_info { + __le16 action; + __le16 ndata; + __le16 nbcn; + __le16 reserved[9]; + long long reserved_1; +}; + +struct host_cmd_ds_802_11_rssi_info_rsp { + __le16 action; + __le16 ndata; + __le16 nbcn; + __le16 data_rssi_last; + __le16 data_nf_last; + __le16 data_rssi_avg; + __le16 data_nf_avg; + __le16 bcn_rssi_last; + __le16 bcn_nf_last; + __le16 bcn_rssi_avg; + __le16 bcn_nf_avg; + long long tsf_bcn; +}; + +struct host_cmd_ds_802_11_mac_address { + __le16 action; + u8 mac_addr[ETH_ALEN]; +}; + +struct host_cmd_ds_mac_control { + __le16 action; + __le16 reserved; +}; + +struct host_cmd_ds_mac_multicast_adr { + __le16 action; + __le16 num_of_adrs; + u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN]; +} __packed; + +struct host_cmd_ds_802_11_deauthenticate { + u8 mac_addr[ETH_ALEN]; + __le16 reason_code; +} __packed; + +struct host_cmd_ds_802_11_associate { + u8 peer_sta_addr[ETH_ALEN]; + __le16 cap_info_bitmap; + __le16 listen_interval; + __le16 beacon_period; + u8 dtim_period; +} __packed; + +struct ieee_types_assoc_rsp { + __le16 cap_info_bitmap; + __le16 status_code; + __le16 a_id; + u8 ie_buffer[1]; +} __packed; + +struct host_cmd_ds_802_11_associate_rsp { + struct ieee_types_assoc_rsp assoc_rsp; +} __packed; + +struct ieee_types_cf_param_set { + u8 element_id; + u8 len; + u8 cfp_cnt; + u8 cfp_period; + u16 cfp_max_duration; + u16 cfp_duration_remaining; +} __packed; + +struct ieee_types_ibss_param_set { + u8 element_id; + u8 len; + __le16 atim_window; +} __packed; + +union ieee_types_ss_param_set { + struct ieee_types_cf_param_set cf_param_set; + struct ieee_types_ibss_param_set ibss_param_set; +} __packed; + +struct ieee_types_fh_param_set { + u8 element_id; + u8 len; + __le16 dwell_time; + u8 hop_set; + u8 hop_pattern; + u8 hop_index; +} __packed; + +struct ieee_types_ds_param_set { + u8 element_id; + u8 len; + u8 current_chan; +} __packed; + +union ieee_types_phy_param_set { + struct ieee_types_fh_param_set fh_param_set; + struct ieee_types_ds_param_set ds_param_set; +} __packed; + +struct host_cmd_ds_802_11_ad_hoc_start { + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 bss_mode; + __le16 beacon_period; + u8 dtim_period; + union ieee_types_ss_param_set ss_param_set; + union ieee_types_phy_param_set phy_param_set; + u16 reserved1; + __le16 cap_info_bitmap; + u8 DataRate[HOSTCMD_SUPPORTED_RATES]; +} __packed; + +struct host_cmd_ds_802_11_ad_hoc_result { + u8 pad[3]; + u8 bssid[ETH_ALEN]; +} __packed; + +struct adhoc_bss_desc { + u8 bssid[ETH_ALEN]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 bss_mode; + __le16 beacon_period; + u8 dtim_period; + u8 time_stamp[8]; + u8 local_time[8]; + union ieee_types_phy_param_set phy_param_set; + union ieee_types_ss_param_set ss_param_set; + __le16 cap_info_bitmap; + u8 data_rates[HOSTCMD_SUPPORTED_RATES]; + + /* + * DO NOT ADD ANY FIELDS TO THIS STRUCTURE. + * It is used in the Adhoc join command and will cause a + * binary layout mismatch with the firmware + */ +} __packed; + +struct host_cmd_ds_802_11_ad_hoc_join { + struct adhoc_bss_desc bss_descriptor; + u16 reserved1; + u16 reserved2; +} __packed; + +struct host_cmd_ds_802_11_get_log { + __le32 mcast_tx_frame; + __le32 failed; + __le32 retry; + __le32 multi_retry; + __le32 frame_dup; + __le32 rts_success; + __le32 rts_failure; + __le32 ack_failure; + __le32 rx_frag; + __le32 mcast_rx_frame; + __le32 fcs_error; + __le32 tx_frame; + __le32 reserved; + __le32 wep_icv_err_cnt[4]; +}; + +struct host_cmd_ds_tx_rate_query { + u8 tx_rate; + /* Ht Info [Bit 0] RxRate format: LG=0, HT=1 + * [Bit 1] HT Bandwidth: BW20 = 0, BW40 = 1 + * [Bit 2] HT Guard Interval: LGI = 0, SGI = 1 */ + u8 ht_info; +} __packed; + +enum Host_Sleep_Action { + HS_CONFIGURE = 0x0001, + HS_ACTIVATE = 0x0002, +}; + +struct mwifiex_hs_config_param { + __le32 conditions; + u8 gpio; + u8 gap; +} __packed; + +struct hs_activate_param { + u16 resp_ctrl; +} __packed; + +struct host_cmd_ds_802_11_hs_cfg_enh { + __le16 action; + + union { + struct mwifiex_hs_config_param hs_config; + struct hs_activate_param hs_activate; + } params; +} __packed; + +enum SNMP_MIB_INDEX { + OP_RATE_SET_I = 1, + DTIM_PERIOD_I = 3, + RTS_THRESH_I = 5, + SHORT_RETRY_LIM_I = 6, + LONG_RETRY_LIM_I = 7, + FRAG_THRESH_I = 8, + DOT11D_I = 9, +}; + +#define MAX_SNMP_BUF_SIZE 128 + +struct host_cmd_ds_802_11_snmp_mib { + __le16 query_type; + __le16 oid; + __le16 buf_size; + u8 value[1]; +} __packed; + +#define RADIO_ON 0x01 +#define RADIO_OFF 0x00 + +struct mwifiex_rate_scope { + __le16 type; + __le16 length; + __le16 hr_dsss_rate_bitmap; + __le16 ofdm_rate_bitmap; + __le16 ht_mcs_rate_bitmap[8]; +} __packed; + +struct mwifiex_rate_drop_pattern { + __le16 type; + __le16 length; + __le32 rate_drop_mode; +} __packed; + +struct host_cmd_ds_tx_rate_cfg { + __le16 action; + __le16 cfg_index; +} __packed; + +struct mwifiex_power_group { + u8 modulation_class; + u8 first_rate_code; + u8 last_rate_code; + s8 power_step; + s8 power_min; + s8 power_max; + u8 ht_bandwidth; + u8 reserved; +} __packed; + +struct mwifiex_types_power_group { + u16 type; + u16 length; +} __packed; + +struct host_cmd_ds_txpwr_cfg { + __le16 action; + __le16 cfg_index; + __le32 mode; +} __packed; + +#define MWIFIEX_USER_SCAN_CHAN_MAX 50 + +#define MWIFIEX_MAX_SSID_LIST_LENGTH 10 + +struct mwifiex_scan_cmd_config { + /* + * BSS Type to be sent in the firmware command + * + * Field can be used to restrict the types of networks returned in the + * scan. Valid settings are: + * + * - MWIFIEX_SCAN_MODE_BSS (infrastructure) + * - MWIFIEX_SCAN_MODE_IBSS (adhoc) + * - MWIFIEX_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure) + */ + u8 bss_mode; + + /* Specific BSSID used to filter scan results in the firmware */ + u8 specific_bssid[ETH_ALEN]; + + /* Length of TLVs sent in command starting at tlvBuffer */ + u32 tlv_buf_len; + + /* + * SSID TLV(s) and ChanList TLVs to be sent in the firmware command + * + * TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set + * WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set + */ + u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored + here */ +} __packed; + +struct mwifiex_user_scan_chan { + u8 chan_number; + u8 radio_type; + u8 scan_type; + u8 reserved; + u32 scan_time; +} __packed; + +struct mwifiex_user_scan_ssid { + u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; + u8 max_len; +} __packed; + +struct mwifiex_user_scan_cfg { + /* + * Flag set to keep the previous scan table intact + * + * If set, the scan results will accumulate, replacing any previous + * matched entries for a BSS with the new scan data + */ + u8 keep_previous_scan; + /* + * BSS mode to be sent in the firmware command + * + * Field can be used to restrict the types of networks returned in the + * scan. Valid settings are: + * + * - MWIFIEX_SCAN_MODE_BSS (infrastructure) + * - MWIFIEX_SCAN_MODE_IBSS (adhoc) + * - MWIFIEX_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure) + */ + u8 bss_mode; + /* Configure the number of probe requests for active chan scans */ + u8 num_probes; + u8 reserved; + /* BSSID filter sent in the firmware command to limit the results */ + u8 specific_bssid[ETH_ALEN]; + /* SSID filter list used in the to limit the scan results */ + struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH]; + /* Variable number (fixed maximum) of channels to scan up */ + struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; +} __packed; + +struct ie_body { + u8 grp_key_oui[4]; + u8 ptk_cnt[2]; + u8 ptk_body[4]; +} __packed; + +struct host_cmd_ds_802_11_scan { + u8 bss_mode; + u8 bssid[ETH_ALEN]; + u8 tlv_buffer[1]; +} __packed; + +struct host_cmd_ds_802_11_scan_rsp { + __le16 bss_descript_size; + u8 number_of_sets; + u8 bss_desc_and_tlv_buffer[1]; +} __packed; + +struct host_cmd_ds_802_11_bg_scan_query { + u8 flush; +} __packed; + +struct host_cmd_ds_802_11_bg_scan_query_rsp { + u32 report_condition; + struct host_cmd_ds_802_11_scan_rsp scan_resp; +} __packed; + +struct mwifiex_ietypes_domain_param_set { + struct mwifiex_ie_types_header header; + u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; + struct ieee80211_country_ie_triplet triplet[1]; +} __packed; + +struct host_cmd_ds_802_11d_domain_info { + __le16 action; + struct mwifiex_ietypes_domain_param_set domain; +} __packed; + +struct host_cmd_ds_802_11d_domain_info_rsp { + __le16 action; + struct mwifiex_ietypes_domain_param_set domain; +} __packed; + +struct host_cmd_ds_11n_addba_req { + u8 add_req_result; + u8 peer_mac_addr[ETH_ALEN]; + u8 dialog_token; + __le16 block_ack_param_set; + __le16 block_ack_tmo; + __le16 ssn; +} __packed; + +struct host_cmd_ds_11n_addba_rsp { + u8 add_rsp_result; + u8 peer_mac_addr[ETH_ALEN]; + u8 dialog_token; + __le16 status_code; + __le16 block_ack_param_set; + __le16 block_ack_tmo; + __le16 ssn; +} __packed; + +struct host_cmd_ds_11n_delba { + u8 del_result; + u8 peer_mac_addr[ETH_ALEN]; + __le16 del_ba_param_set; + __le16 reason_code; + u8 reserved; +} __packed; + +struct host_cmd_ds_11n_batimeout { + u8 tid; + u8 peer_mac_addr[ETH_ALEN]; + u8 origninator; +} __packed; + +struct host_cmd_ds_11n_cfg { + __le16 action; + __le16 ht_tx_cap; + __le16 ht_tx_info; +} __packed; + +struct host_cmd_ds_txbuf_cfg { + __le16 action; + __le16 buff_size; + __le16 mp_end_port; /* SDIO only, reserved for other interfacces */ + __le16 reserved3; +} __packed; + +struct host_cmd_ds_amsdu_aggr_ctrl { + __le16 action; + __le16 enable; + __le16 curr_buf_size; +} __packed; + +struct mwifiex_ie_types_wmm_param_set { + struct mwifiex_ie_types_header header; + u8 wmm_ie[1]; +}; + +struct mwifiex_ie_types_wmm_queue_status { + struct mwifiex_ie_types_header header; + u8 queue_index; + u8 disabled; + u16 medium_time; + u8 flow_required; + u8 flow_created; + u32 reserved; +}; + +struct ieee_types_vendor_header { + u8 element_id; + u8 len; + u8 oui[3]; + u8 oui_type; + u8 oui_subtype; + u8 version; +} __packed; + +struct ieee_types_wmm_ac_parameters { + u8 aci_aifsn_bitmap; + u8 ecw_bitmap; + __le16 tx_op_limit; +} __packed; + +struct ieee_types_wmm_parameter { + /* + * WMM Parameter IE - Vendor Specific Header: + * element_id [221/0xdd] + * Len [24] + * Oui [00:50:f2] + * OuiType [2] + * OuiSubType [1] + * Version [1] + */ + struct ieee_types_vendor_header vend_hdr; + u8 qos_info_bitmap; + u8 reserved; + struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_MAX_QUEUES]; +} __packed; + +struct ieee_types_wmm_info { + + /* + * WMM Info IE - Vendor Specific Header: + * element_id [221/0xdd] + * Len [7] + * Oui [00:50:f2] + * OuiType [2] + * OuiSubType [0] + * Version [1] + */ + struct ieee_types_vendor_header vend_hdr; + + u8 qos_info_bitmap; +} __packed; + +struct host_cmd_ds_wmm_get_status { + u8 queue_status_tlv[sizeof(struct mwifiex_ie_types_wmm_queue_status) * + IEEE80211_MAX_QUEUES]; + u8 wmm_param_tlv[sizeof(struct ieee_types_wmm_parameter) + 2]; +} __packed; + +struct mwifiex_wmm_ac_status { + u8 disabled; + u8 flow_required; + u8 flow_created; +}; + +struct mwifiex_ie_types_htcap { + struct mwifiex_ie_types_header header; + struct ieee80211_ht_cap ht_cap; +} __packed; + +struct mwifiex_ie_types_htinfo { + struct mwifiex_ie_types_header header; + struct ieee80211_ht_info ht_info; +} __packed; + +struct mwifiex_ie_types_2040bssco { + struct mwifiex_ie_types_header header; + u8 bss_co_2040; +} __packed; + +struct mwifiex_ie_types_extcap { + struct mwifiex_ie_types_header header; + u8 ext_cap; +} __packed; + +struct host_cmd_ds_mac_reg_access { + __le16 action; + __le16 offset; + __le32 value; +} __packed; + +struct host_cmd_ds_bbp_reg_access { + __le16 action; + __le16 offset; + u8 value; + u8 reserved[3]; +} __packed; + +struct host_cmd_ds_rf_reg_access { + __le16 action; + __le16 offset; + u8 value; + u8 reserved[3]; +} __packed; + +struct host_cmd_ds_pmic_reg_access { + __le16 action; + __le16 offset; + u8 value; + u8 reserved[3]; +} __packed; + +struct host_cmd_ds_802_11_eeprom_access { + __le16 action; + + __le16 offset; + __le16 byte_count; + u8 value; +} __packed; + +struct host_cmd_ds_802_11_rf_channel { + __le16 action; + __le16 current_channel; + __le16 rf_type; + __le16 reserved; + u8 reserved_1[32]; +} __packed; + +struct host_cmd_ds_version_ext { + u8 version_str_sel; + char version_str[128]; +} __packed; + +struct host_cmd_ds_802_11_ibss_status { + __le16 action; + __le16 enable; + u8 bssid[ETH_ALEN]; + __le16 beacon_interval; + __le16 atim_window; + __le16 use_g_rate_protect; +} __packed; + +#define CONNECTION_TYPE_INFRA 0 +#define CONNECTION_TYPE_ADHOC 1 + +struct host_cmd_ds_set_bss_mode { + u8 con_type; +} __packed; + +struct host_cmd_ds_command { + __le16 command; + __le16 size; + __le16 seq_num; + __le16 result; + union { + struct host_cmd_ds_get_hw_spec hw_spec; + struct host_cmd_ds_mac_control mac_ctrl; + struct host_cmd_ds_802_11_mac_address mac_addr; + struct host_cmd_ds_mac_multicast_adr mc_addr; + struct host_cmd_ds_802_11_get_log get_log; + struct host_cmd_ds_802_11_rssi_info rssi_info; + struct host_cmd_ds_802_11_rssi_info_rsp rssi_info_rsp; + struct host_cmd_ds_802_11_snmp_mib smib; + struct host_cmd_ds_802_11_rf_channel rf_channel; + struct host_cmd_ds_tx_rate_query tx_rate; + struct host_cmd_ds_tx_rate_cfg tx_rate_cfg; + struct host_cmd_ds_txpwr_cfg txp_cfg; + struct host_cmd_ds_802_11_ps_mode_enh psmode_enh; + struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg; + struct host_cmd_ds_802_11_scan scan; + struct host_cmd_ds_802_11_scan_rsp scan_resp; + struct host_cmd_ds_802_11_bg_scan_query bg_scan_query; + struct host_cmd_ds_802_11_bg_scan_query_rsp bg_scan_query_resp; + struct host_cmd_ds_802_11_associate associate; + struct host_cmd_ds_802_11_associate_rsp associate_rsp; + struct host_cmd_ds_802_11_deauthenticate deauth; + struct host_cmd_ds_802_11_ad_hoc_start adhoc_start; + struct host_cmd_ds_802_11_ad_hoc_result adhoc_result; + struct host_cmd_ds_802_11_ad_hoc_join adhoc_join; + struct host_cmd_ds_802_11d_domain_info domain_info; + struct host_cmd_ds_802_11d_domain_info_rsp domain_info_resp; + struct host_cmd_ds_11n_addba_req add_ba_req; + struct host_cmd_ds_11n_addba_rsp add_ba_rsp; + struct host_cmd_ds_11n_delba del_ba; + struct host_cmd_ds_txbuf_cfg tx_buf; + struct host_cmd_ds_amsdu_aggr_ctrl amsdu_aggr_ctrl; + struct host_cmd_ds_11n_cfg htcfg; + struct host_cmd_ds_wmm_get_status get_wmm_status; + struct host_cmd_ds_802_11_key_material key_material; + struct host_cmd_ds_version_ext verext; + struct host_cmd_ds_802_11_ibss_status ibss_coalescing; + struct host_cmd_ds_mac_reg_access mac_reg; + struct host_cmd_ds_bbp_reg_access bbp_reg; + struct host_cmd_ds_rf_reg_access rf_reg; + struct host_cmd_ds_pmic_reg_access pmic_reg; + struct host_cmd_ds_set_bss_mode bss_mode; + struct host_cmd_ds_802_11_eeprom_access eeprom; + } params; +} __packed; + +struct mwifiex_opt_sleep_confirm { + __le16 command; + __le16 size; + __le16 seq_num; + __le16 result; + __le16 action; + struct sleep_confirm_param sleep_cfm; +} __packed; + +struct mwifiex_opt_sleep_confirm_buffer { + u8 hdr[4]; + struct mwifiex_opt_sleep_confirm ps_cfm_sleep; +} __packed; +#endif /* !_MWIFIEX_FW_H_ */ diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c new file mode 100644 index 000000000000..07ebc97e19c0 --- /dev/null +++ b/drivers/net/wireless/mwifiex/init.c @@ -0,0 +1,665 @@ +/* + * Marvell Wireless LAN device driver: HW/FW Initialization + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +/* + * This function adds a BSS priority table to the table list. + * + * The function allocates a new BSS priority table node and adds it to + * the end of BSS priority table list, kept in driver memory. + */ +static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bss_prio_node *bss_prio; + int status = 0; + unsigned long flags; + + bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); + if (!bss_prio) { + dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", + __func__); + return -1; + } + + bss_prio->priv = priv; + INIT_LIST_HEAD(&bss_prio->list); + if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur) + adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = + bss_prio; + + spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority] + .bss_prio_lock, flags); + list_add_tail(&bss_prio->list, + &adapter->bss_prio_tbl[priv->bss_priority] + .bss_prio_head); + spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] + .bss_prio_lock, flags); + + return status; +} + +/* + * This function initializes the private structure and sets default + * values to the members. + * + * Additionally, it also initializes all the locks and sets up all the + * lists. + */ +static int mwifiex_init_priv(struct mwifiex_private *priv) +{ + u32 i; + int ret = 0; + + priv->media_connected = false; + memset(priv->curr_addr, 0xff, ETH_ALEN); + + priv->pkt_tx_ctrl = 0; + priv->bss_mode = MWIFIEX_BSS_MODE_INFRA; + priv->data_rate = 0; /* Initially indicate the rate as auto */ + priv->is_data_rate_auto = true; + priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR; + priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR; + + priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED; + priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN; + priv->sec_info.encryption_mode = MWIFIEX_ENCRYPTION_MODE_NONE; + for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++) + memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key)); + priv->wep_key_curr_index = 0; + priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON | + HostCmd_ACT_MAC_ETHERNETII_ENABLE; + + priv->beacon_period = 100; /* beacon interval */ ; + priv->attempted_bss_desc = NULL; + memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params)); + priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL; + + memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid)); + memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid)); + memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf)); + priv->assoc_rsp_size = 0; + priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; + priv->atim_window = 0; + priv->adhoc_state = ADHOC_IDLE; + priv->tx_power_level = 0; + priv->max_tx_power_level = 0; + priv->min_tx_power_level = 0; + priv->tx_rate = 0; + priv->rxpd_htinfo = 0; + priv->rxpd_rate = 0; + priv->rate_bitmap = 0; + priv->data_rssi_last = 0; + priv->data_rssi_avg = 0; + priv->data_nf_avg = 0; + priv->data_nf_last = 0; + priv->bcn_rssi_last = 0; + priv->bcn_rssi_avg = 0; + priv->bcn_nf_avg = 0; + priv->bcn_nf_last = 0; + memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie)); + memset(&priv->aes_key, 0, sizeof(priv->aes_key)); + priv->wpa_ie_len = 0; + priv->wpa_is_gtk_set = false; + + memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf)); + priv->assoc_tlv_buf_len = 0; + memset(&priv->wps, 0, sizeof(priv->wps)); + memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf)); + priv->gen_ie_buf_len = 0; + memset(priv->vs_ie, 0, sizeof(priv->vs_ie)); + + priv->wmm_required = true; + priv->wmm_enabled = false; + priv->wmm_qosinfo = 0; + priv->curr_bcn_buf = NULL; + priv->curr_bcn_size = 0; + + priv->scan_block = false; + + ret = mwifiex_add_bss_prio_tbl(priv); + + return ret; +} + +/* + * This function allocates buffers for members of the adapter + * structure. + * + * The memory allocated includes scan table, command buffers, and + * sleep confirm command buffer. In addition, the queues are + * also initialized. + */ +static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) +{ + int ret = 0; + u32 buf_size; + struct mwifiex_bssdescriptor *temp_scan_table; + + /* Allocate buffer to store the BSSID list */ + buf_size = sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP; + temp_scan_table = kzalloc(buf_size, GFP_KERNEL); + if (!temp_scan_table) { + dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n", + __func__); + return -1; + } + + adapter->scan_table = temp_scan_table; + + /* Allocate command buffer */ + ret = mwifiex_alloc_cmd_buffer(adapter); + if (ret) { + dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n", + __func__); + return -1; + } + + adapter->sleep_cfm = + dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm_buffer) + + INTF_HEADER_LEN); + + if (!adapter->sleep_cfm) { + dev_err(adapter->dev, "%s: failed to alloc sleep cfm" + " cmd buffer\n", __func__); + return -1; + } + skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN); + + return 0; +} + +/* + * This function initializes the adapter structure and sets default + * values to the members of adapter. + * + * This also initializes the WMM related parameters in the driver private + * structures. + */ +static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) +{ + struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf = NULL; + + skb_put(adapter->sleep_cfm, sizeof(sleep_cfm_buf->ps_cfm_sleep)); + sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm_buffer *) + (adapter->sleep_cfm->data); + + adapter->cmd_sent = false; + adapter->data_sent = true; + adapter->cmd_resp_received = false; + adapter->event_received = false; + adapter->data_received = false; + + adapter->surprise_removed = false; + + adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; + + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; + adapter->ps_state = PS_STATE_AWAKE; + adapter->need_to_wakeup = false; + + adapter->scan_mode = HostCmd_BSS_MODE_ANY; + adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME; + adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME; + adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME; + + adapter->num_in_scan_table = 0; + memset(adapter->scan_table, 0, + (sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP)); + adapter->scan_probes = 1; + + memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf)); + adapter->bcn_buf_end = adapter->bcn_buf; + + adapter->radio_on = RADIO_ON; + adapter->multiple_dtim = 1; + + adapter->local_listen_interval = 0; /* default value in firmware + will be used */ + + adapter->is_deep_sleep = false; + + adapter->delay_null_pkt = false; + adapter->delay_to_ps = 1000; + adapter->enhanced_ps_mode = PS_MODE_AUTO; + + adapter->gen_null_pkt = false; /* Disable NULL Pkg generation by + default */ + adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by + default */ + adapter->pm_wakeup_card_req = false; + + adapter->pm_wakeup_fw_try = false; + + adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; + adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; + adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; + + adapter->is_hs_configured = false; + adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF); + adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF; + adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF; + adapter->hs_activated = false; + + memset(adapter->event_body, 0, sizeof(adapter->event_body)); + adapter->hw_dot_11n_dev_cap = 0; + adapter->hw_dev_mcs_support = 0; + adapter->usr_dot_11n_dev_cap = 0; + adapter->usr_dev_mcs_support = 0; + adapter->chan_offset = 0; + adapter->adhoc_11n_enabled = false; + + mwifiex_wmm_init(adapter); + + if (adapter->sleep_cfm) { + memset(&sleep_cfm_buf->ps_cfm_sleep, 0, + adapter->sleep_cfm->len); + sleep_cfm_buf->ps_cfm_sleep.command = + cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); + sleep_cfm_buf->ps_cfm_sleep.size = + cpu_to_le16(adapter->sleep_cfm->len); + sleep_cfm_buf->ps_cfm_sleep.result = 0; + sleep_cfm_buf->ps_cfm_sleep.action = cpu_to_le16(SLEEP_CONFIRM); + sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl = + cpu_to_le16(RESP_NEEDED); + } + memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params)); + memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period)); + adapter->tx_lock_flag = false; + adapter->null_pkt_interval = 0; + adapter->fw_bands = 0; + adapter->config_bands = 0; + adapter->adhoc_start_band = 0; + adapter->scan_channels = NULL; + adapter->fw_release_number = 0; + adapter->fw_cap_info = 0; + memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf)); + adapter->event_cause = 0; + adapter->region_code = 0; + adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT; + adapter->adhoc_awake_period = 0; + memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); + adapter->arp_filter_size = 0; + + return; +} + +/* + * This function frees the adapter structure. + * + * The freeing operation is done recursively, by canceling all + * pending commands, freeing the member buffers previously + * allocated (command buffers, scan table buffer, sleep confirm + * command buffer), stopping the timers and calling the cleanup + * routines for every interface, before the actual adapter + * structure is freed. + */ +static void +mwifiex_free_adapter(struct mwifiex_adapter *adapter) +{ + if (!adapter) { + pr_err("%s: adapter is NULL\n", __func__); + return; + } + + mwifiex_cancel_all_pending_cmd(adapter); + + /* Free lock variables */ + mwifiex_free_lock_list(adapter); + + /* Free command buffer */ + dev_dbg(adapter->dev, "info: free cmd buffer\n"); + mwifiex_free_cmd_buffer(adapter); + + del_timer(&adapter->cmd_timer); + + dev_dbg(adapter->dev, "info: free scan table\n"); + kfree(adapter->scan_table); + adapter->scan_table = NULL; + + adapter->if_ops.cleanup_if(adapter); + + dev_kfree_skb_any(adapter->sleep_cfm); + + return; +} + +/* + * This function intializes the lock variables and + * the list heads. + */ +int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) +{ + struct mwifiex_private *priv = NULL; + s32 i = 0; + u32 j = 0; + + spin_lock_init(&adapter->mwifiex_lock); + spin_lock_init(&adapter->int_lock); + spin_lock_init(&adapter->main_proc_lock); + spin_lock_init(&adapter->mwifiex_cmd_lock); + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + priv = adapter->priv[i]; + spin_lock_init(&priv->rx_pkt_lock); + spin_lock_init(&priv->wmm.ra_list_spinlock); + spin_lock_init(&priv->curr_bcn_buf_lock); + } + } + + /* Initialize cmd_free_q */ + INIT_LIST_HEAD(&adapter->cmd_free_q); + /* Initialize cmd_pending_q */ + INIT_LIST_HEAD(&adapter->cmd_pending_q); + /* Initialize scan_pending_q */ + INIT_LIST_HEAD(&adapter->scan_pending_q); + + spin_lock_init(&adapter->cmd_free_q_lock); + spin_lock_init(&adapter->cmd_pending_q_lock); + spin_lock_init(&adapter->scan_pending_q_lock); + + for (i = 0; i < adapter->priv_num; ++i) { + INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); + adapter->bss_prio_tbl[i].bss_prio_cur = NULL; + spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock); + } + + for (i = 0; i < adapter->priv_num; i++) { + if (!adapter->priv[i]) + continue; + priv = adapter->priv[i]; + for (j = 0; j < MAX_NUM_TID; ++j) { + INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list); + spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock); + } + INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); + INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); + + spin_lock_init(&priv->tx_ba_stream_tbl_lock); + spin_lock_init(&priv->rx_reorder_tbl_lock); + } + + return 0; +} + +/* + * This function releases the lock variables and frees the locks and + * associated locks. + */ +void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) +{ + struct mwifiex_private *priv = NULL; + s32 i = 0; + s32 j = 0; + + /* Free lists */ + list_del(&adapter->cmd_free_q); + list_del(&adapter->cmd_pending_q); + list_del(&adapter->scan_pending_q); + + for (i = 0; i < adapter->priv_num; i++) + list_del(&adapter->bss_prio_tbl[i].bss_prio_head); + + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + priv = adapter->priv[i]; + for (j = 0; j < MAX_NUM_TID; ++j) + list_del(&priv->wmm.tid_tbl_ptr[j].ra_list); + list_del(&priv->tx_ba_stream_tbl_ptr); + list_del(&priv->rx_reorder_tbl_ptr); + } + } + + return; +} + +/* + * This function initializes the firmware. + * + * The following operations are performed sequentially - + * - Allocate adapter structure + * - Initialize the adapter structure + * - Initialize the private structure + * - Add BSS priority tables to the adapter structure + * - For each interface, send the init commands to firmware + * - Send the first command in command pending queue, if available + */ +int mwifiex_init_fw(struct mwifiex_adapter *adapter) +{ + int ret = 0; + struct mwifiex_private *priv = NULL; + u8 i = 0; + u8 first_sta = true; + int is_cmd_pend_q_empty; + unsigned long flags; + + adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; + + /* Allocate memory for member of adapter structure */ + ret = mwifiex_allocate_adapter(adapter); + if (ret) + return -1; + + /* Initialize adapter structure */ + mwifiex_init_adapter(adapter); + + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + priv = adapter->priv[i]; + + /* Initialize private structure */ + ret = mwifiex_init_priv(priv); + if (ret) + return -1; + } + } + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); + if (ret == -1) + return -1; + + first_sta = false; + } + } + + spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); + is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); + if (!is_cmd_pend_q_empty) { + /* Send the first command in queue and return */ + if (mwifiex_main_process(adapter) != -1) + ret = -EINPROGRESS; + } else { + adapter->hw_status = MWIFIEX_HW_STATUS_READY; + } + + return ret; +} + +/* + * This function deletes the BSS priority tables. + * + * The function traverses through all the allocated BSS priority nodes + * in every BSS priority table and frees them. + */ +static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) +{ + int i; + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bss_prio_node *bssprio_node = NULL, *tmp_node = NULL, + **cur = NULL; + struct list_head *head; + spinlock_t *lock; + unsigned long flags; + + for (i = 0; i < adapter->priv_num; ++i) { + head = &adapter->bss_prio_tbl[i].bss_prio_head; + cur = &adapter->bss_prio_tbl[i].bss_prio_cur; + lock = &adapter->bss_prio_tbl[i].bss_prio_lock; + dev_dbg(adapter->dev, "info: delete BSS priority table," + " index = %d, i = %d, head = %p, cur = %p\n", + priv->bss_index, i, head, *cur); + if (*cur) { + spin_lock_irqsave(lock, flags); + if (list_empty(head)) { + spin_unlock_irqrestore(lock, flags); + continue; + } + bssprio_node = list_first_entry(head, + struct mwifiex_bss_prio_node, list); + spin_unlock_irqrestore(lock, flags); + + list_for_each_entry_safe(bssprio_node, tmp_node, head, + list) { + if (bssprio_node->priv == priv) { + dev_dbg(adapter->dev, "info: Delete " + "node %p, next = %p\n", + bssprio_node, tmp_node); + spin_lock_irqsave(lock, flags); + list_del(&bssprio_node->list); + spin_unlock_irqrestore(lock, flags); + kfree(bssprio_node); + } + } + *cur = (struct mwifiex_bss_prio_node *)head; + } + } +} + +/* + * This function is used to shutdown the driver. + * + * The following operations are performed sequentially - + * - Check if already shut down + * - Make sure the main process has stopped + * - Clean up the Tx and Rx queues + * - Delete BSS priority tables + * - Free the adapter + * - Notify completion + */ +int +mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) +{ + int ret = -EINPROGRESS; + struct mwifiex_private *priv = NULL; + s32 i = 0; + unsigned long flags; + + /* mwifiex already shutdown */ + if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) + return 0; + + adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING; + /* wait for mwifiex_process to complete */ + if (adapter->mwifiex_processing) { + dev_warn(adapter->dev, "main process is still running\n"); + return ret; + } + + /* shut down mwifiex */ + dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); + + /* Clean up Tx/Rx queues and delete BSS priority table */ + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + priv = adapter->priv[i]; + + mwifiex_clean_txrx(priv); + mwifiex_delete_bss_prio_tbl(priv); + } + } + + spin_lock_irqsave(&adapter->mwifiex_lock, flags); + + /* Free adapter structure */ + mwifiex_free_adapter(adapter); + + spin_unlock_irqrestore(&adapter->mwifiex_lock, flags); + + /* Notify completion */ + ret = mwifiex_shutdown_fw_complete(adapter); + + return ret; +} + +/* + * This function downloads the firmware to the card. + * + * The actual download is preceded by two sanity checks - + * - Check if firmware is already running + * - Check if the interface is the winner to download the firmware + * + * ...and followed by another - + * - Check if the firmware is downloaded successfully + * + * After download is successfully completed, the host interrupts are enabled. + */ +int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, + struct mwifiex_fw_image *pmfw) +{ + int ret = 0; + u32 poll_num = 1; + int winner; + + /* Check if firmware is already running */ + ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner); + if (!ret) { + dev_notice(adapter->dev, + "WLAN FW already running! Skip FW download\n"); + goto done; + } + poll_num = MAX_FIRMWARE_POLL_TRIES; + + /* Check if we are the winner for downloading FW */ + if (!winner) { + dev_notice(adapter->dev, + "Other interface already running!" + " Skip FW download\n"); + poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; + goto poll_fw; + } + if (pmfw) { + /* Download firmware with helper */ + ret = adapter->if_ops.prog_fw(adapter, pmfw); + if (ret) { + dev_err(adapter->dev, "prog_fw failed ret=%#x\n", ret); + return ret; + } + } + +poll_fw: + /* Check if the firmware is downloaded successfully or not */ + ret = adapter->if_ops.check_fw_status(adapter, poll_num, NULL); + if (ret) { + dev_err(adapter->dev, "FW failed to be active in time\n"); + return -1; + } +done: + /* re-enable host interrupt for mwifiex after fw dnld is successful */ + adapter->if_ops.enable_int(adapter); + return ret; +} diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h new file mode 100644 index 000000000000..d6babfb1495c --- /dev/null +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -0,0 +1,433 @@ +/* + * Marvell Wireless LAN device driver: ioctl data structures & APIs + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_IOCTL_H_ +#define _MWIFIEX_IOCTL_H_ + +#include + +enum { + MWIFIEX_SCAN_MODE_UNCHANGED = 0, + MWIFIEX_SCAN_MODE_BSS, + MWIFIEX_SCAN_MODE_IBSS, + MWIFIEX_SCAN_MODE_ANY +}; + +enum { + MWIFIEX_SCAN_TYPE_UNCHANGED = 0, + MWIFIEX_SCAN_TYPE_ACTIVE, + MWIFIEX_SCAN_TYPE_PASSIVE +}; + +struct mwifiex_get_scan_table_fixed { + u8 bssid[ETH_ALEN]; + u8 channel; + u8 rssi; + long long network_tsf; +}; + +struct mwifiex_scan_time_params { + u32 specific_scan_time; + u32 active_scan_time; + u32 passive_scan_time; +}; + +struct mwifiex_user_scan { + u32 scan_cfg_len; + u8 scan_cfg_buf[1]; +}; + +struct mwifiex_scan_req { + u32 scan_mode; + u32 scan_type; + struct mwifiex_802_11_ssid scan_ssid; + struct mwifiex_scan_time_params scan_time; + struct mwifiex_user_scan user_scan; +}; + +struct mwifiex_scan_resp { + u32 num_in_scan_table; + u8 *scan_table; +}; + +enum { + MWIFIEX_BSS_MODE_INFRA = 1, + MWIFIEX_BSS_MODE_IBSS, + MWIFIEX_BSS_MODE_AUTO +}; + +#define MWIFIEX_PROMISC_MODE 1 +#define MWIFIEX_MULTICAST_MODE 2 +#define MWIFIEX_ALL_MULTI_MODE 4 +#define MWIFIEX_MAX_MULTICAST_LIST_SIZE 32 + +struct mwifiex_multicast_list { + u32 mode; + u32 num_multicast_addr; + u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN]; +}; + +#define MWIFIEX_MAX_CHANNEL_NUM 128 + +struct mwifiex_chan_freq { + u32 channel; + u32 freq; +}; + +struct mwifiex_chan_list { + u32 num_of_chan; + struct mwifiex_chan_freq cf[MWIFIEX_MAX_CHANNEL_NUM]; +}; + +struct mwifiex_ssid_bssid { + struct mwifiex_802_11_ssid ssid; + u8 bssid[ETH_ALEN]; +}; + +enum { + BAND_B = 1, + BAND_G = 2, + BAND_A = 4, + BAND_GN = 8, + BAND_AN = 16, +}; + +#define NO_SEC_CHANNEL 0 +#define SEC_CHANNEL_ABOVE 1 +#define SEC_CHANNEL_BELOW 3 + +struct mwifiex_ds_band_cfg { + u32 config_bands; + u32 adhoc_start_band; + u32 adhoc_channel; + u32 sec_chan_offset; +}; + +enum { + ADHOC_IDLE, + ADHOC_STARTED, + ADHOC_JOINED, + ADHOC_COALESCED +}; + +struct mwifiex_ds_get_stats { + u32 mcast_tx_frame; + u32 failed; + u32 retry; + u32 multi_retry; + u32 frame_dup; + u32 rts_success; + u32 rts_failure; + u32 ack_failure; + u32 rx_frag; + u32 mcast_rx_frame; + u32 fcs_error; + u32 tx_frame; + u32 wep_icv_error[4]; +}; + +#define BCN_RSSI_LAST_MASK 0x00000001 +#define BCN_RSSI_AVG_MASK 0x00000002 +#define DATA_RSSI_LAST_MASK 0x00000004 +#define DATA_RSSI_AVG_MASK 0x00000008 +#define BCN_SNR_LAST_MASK 0x00000010 +#define BCN_SNR_AVG_MASK 0x00000020 +#define DATA_SNR_LAST_MASK 0x00000040 +#define DATA_SNR_AVG_MASK 0x00000080 +#define BCN_NF_LAST_MASK 0x00000100 +#define BCN_NF_AVG_MASK 0x00000200 +#define DATA_NF_LAST_MASK 0x00000400 +#define DATA_NF_AVG_MASK 0x00000800 +#define ALL_RSSI_INFO_MASK 0x00000fff + +struct mwifiex_ds_get_signal { + /* + * Bit0: Last Beacon RSSI, Bit1: Average Beacon RSSI, + * Bit2: Last Data RSSI, Bit3: Average Data RSSI, + * Bit4: Last Beacon SNR, Bit5: Average Beacon SNR, + * Bit6: Last Data SNR, Bit7: Average Data SNR, + * Bit8: Last Beacon NF, Bit9: Average Beacon NF, + * Bit10: Last Data NF, Bit11: Average Data NF + */ + u16 selector; + s16 bcn_rssi_last; + s16 bcn_rssi_avg; + s16 data_rssi_last; + s16 data_rssi_avg; + s16 bcn_snr_last; + s16 bcn_snr_avg; + s16 data_snr_last; + s16 data_snr_avg; + s16 bcn_nf_last; + s16 bcn_nf_avg; + s16 data_nf_last; + s16 data_nf_avg; +}; + +struct mwifiex_fw_info { + u32 fw_ver; + u8 mac_addr[ETH_ALEN]; +}; + +#define MWIFIEX_MAX_VER_STR_LEN 128 + +struct mwifiex_ver_ext { + u32 version_str_sel; + char version_str[MWIFIEX_MAX_VER_STR_LEN]; +}; + +struct mwifiex_bss_info { + u32 bss_mode; + struct mwifiex_802_11_ssid ssid; + u32 scan_table_idx; + u32 bss_chan; + u32 region_code; + u32 media_connected; + u32 radio_on; + u32 max_power_level; + u32 min_power_level; + u32 adhoc_state; + signed int bcn_nf_last; + u32 wep_status; + u32 is_hs_configured; + u32 is_deep_sleep; + u8 bssid[ETH_ALEN]; +}; + +#define MAX_NUM_TID 8 + +#define MAX_RX_WINSIZE 64 + +struct mwifiex_ds_rx_reorder_tbl { + u16 tid; + u8 ta[ETH_ALEN]; + u32 start_win; + u32 win_size; + u32 buffer[MAX_RX_WINSIZE]; +}; + +struct mwifiex_ds_tx_ba_stream_tbl { + u16 tid; + u8 ra[ETH_ALEN]; +}; + +#define DBG_CMD_NUM 5 + +struct mwifiex_debug_info { + u32 int_counter; + u32 packets_out[MAX_NUM_TID]; + u32 max_tx_buf_size; + u32 tx_buf_size; + u32 curr_tx_buf_size; + u32 tx_tbl_num; + struct mwifiex_ds_tx_ba_stream_tbl + tx_tbl[MWIFIEX_MAX_TX_BASTREAM_SUPPORTED]; + u32 rx_tbl_num; + struct mwifiex_ds_rx_reorder_tbl rx_tbl + [MWIFIEX_MAX_RX_BASTREAM_SUPPORTED]; + u16 ps_mode; + u32 ps_state; + u8 is_deep_sleep; + u8 pm_wakeup_card_req; + u32 pm_wakeup_fw_try; + u8 is_hs_configured; + u8 hs_activated; + u32 num_cmd_host_to_card_failure; + u32 num_cmd_sleep_cfm_host_to_card_failure; + u32 num_tx_host_to_card_failure; + u32 num_event_deauth; + u32 num_event_disassoc; + u32 num_event_link_lost; + u32 num_cmd_deauth; + u32 num_cmd_assoc_success; + u32 num_cmd_assoc_failure; + u32 num_tx_timeout; + u32 num_cmd_timeout; + u16 timeout_cmd_id; + u16 timeout_cmd_act; + u16 last_cmd_id[DBG_CMD_NUM]; + u16 last_cmd_act[DBG_CMD_NUM]; + u16 last_cmd_index; + u16 last_cmd_resp_id[DBG_CMD_NUM]; + u16 last_cmd_resp_index; + u16 last_event[DBG_CMD_NUM]; + u16 last_event_index; + u8 data_sent; + u8 cmd_sent; + u8 cmd_resp_received; + u8 event_received; +}; + +enum { + MWIFIEX_AUTH_MODE_OPEN = 0x00, + MWIFIEX_AUTH_MODE_SHARED = 0x01, + MWIFIEX_AUTH_MODE_NETWORKEAP = 0x80, + MWIFIEX_AUTH_MODE_AUTO = 0xFF, +}; + +enum { + MWIFIEX_ENCRYPTION_MODE_NONE = 0, + MWIFIEX_ENCRYPTION_MODE_WEP40 = 1, + MWIFIEX_ENCRYPTION_MODE_TKIP = 2, + MWIFIEX_ENCRYPTION_MODE_CCMP = 3, + MWIFIEX_ENCRYPTION_MODE_WEP104 = 4, +}; + +#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 +#define MWIFIEX_MAX_KEY_LENGTH 32 +#define WAPI_RXPN_LEN 16 + +struct mwifiex_ds_encrypt_key { + u32 key_disable; + u32 key_index; + u32 key_len; + u8 key_material[MWIFIEX_MAX_KEY_LENGTH]; + u8 mac_addr[ETH_ALEN]; + u32 is_wapi_key; + u8 wapi_rxpn[WAPI_RXPN_LEN]; +}; + +struct mwifiex_rate_cfg { + u32 action; + u32 is_rate_auto; + u32 rate; +}; + +struct mwifiex_data_rate { + u32 tx_data_rate; + u32 rx_data_rate; +}; + +struct mwifiex_power_cfg { + u32 is_power_auto; + u32 power_level; +}; + +struct mwifiex_ds_hs_cfg { + u32 is_invoke_hostcmd; + /* Bit0: non-unicast data + * Bit1: unicast data + * Bit2: mac events + * Bit3: magic packet + */ + u32 conditions; + u32 gpio; + u32 gap; +}; + +#define DEEP_SLEEP_ON 1 +#define DEEP_SLEEP_OFF 0 + +#define DEEP_SLEEP_IDLE_TIME 100 + +struct mwifiex_ds_auto_ds { + u16 auto_ds; + u16 idle_time; +}; + +#define PS_MODE_UNCHANGED 0 +#define PS_MODE_AUTO 1 +#define PS_MODE_POLL 2 +#define PS_MODE_NULL 3 + + +struct mwifiex_ds_pm_cfg { + union { + u32 ps_mode; + struct mwifiex_ds_hs_cfg hs_cfg; + struct mwifiex_ds_auto_ds auto_deep_sleep; + u32 sleep_period; + } param; +}; + +struct mwifiex_ioctl_wmm_queue_status_ac { + u8 wmm_acm; + u8 flow_required; + u8 flow_created; + u8 disabled; +}; + +struct mwifiex_ds_wmm_queue_status { + struct mwifiex_ioctl_wmm_queue_status_ac + ac_status[IEEE80211_MAX_QUEUES]; +}; + +struct mwifiex_ds_11n_tx_cfg { + u16 tx_htcap; + u16 tx_htinfo; +}; + +struct mwifiex_ds_11n_amsdu_aggr_ctrl { + u16 enable; + u16 curr_buf_size; +}; + +#define MWIFIEX_NUM_OF_CMD_BUFFER 20 +#define MWIFIEX_SIZE_OF_CMD_BUFFER 2048 + +enum { + MWIFIEX_IE_TYPE_GEN_IE = 0, + MWIFIEX_IE_TYPE_ARP_FILTER, +}; + +enum { + MWIFIEX_REG_MAC = 1, + MWIFIEX_REG_BBP, + MWIFIEX_REG_RF, + MWIFIEX_REG_PMIC, + MWIFIEX_REG_CAU, +}; + +struct mwifiex_ds_reg_rw { + __le32 type; + __le32 offset; + __le32 value; +}; + +#define MAX_EEPROM_DATA 256 + +struct mwifiex_ds_read_eeprom { + __le16 offset; + __le16 byte_count; + u8 value[MAX_EEPROM_DATA]; +}; + +struct mwifiex_ds_misc_gen_ie { + u32 type; + u32 len; + u8 ie_data[IW_CUSTOM_MAX]; +}; + +struct mwifiex_ds_misc_cmd { + u32 len; + u8 cmd[MWIFIEX_SIZE_OF_CMD_BUFFER]; +}; + +#define MWIFIEX_MAX_VSIE_LEN (256) +#define MWIFIEX_MAX_VSIE_NUM (8) +#define MWIFIEX_VSIE_MASK_SCAN 0x01 +#define MWIFIEX_VSIE_MASK_ASSOC 0x02 +#define MWIFIEX_VSIE_MASK_ADHOC 0x04 + +enum { + MWIFIEX_FUNC_INIT = 1, + MWIFIEX_FUNC_SHUTDOWN, +}; + +#endif /* !_MWIFIEX_IOCTL_H_ */ diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c new file mode 100644 index 000000000000..d06f4c2d1d30 --- /dev/null +++ b/drivers/net/wireless/mwifiex/join.c @@ -0,0 +1,1464 @@ +/* + * Marvell Wireless LAN device driver: association and ad-hoc start/join + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9))) + +/* + * Append a generic IE as a pass through TLV to a TLV buffer. + * + * This function is called from the network join command preparation routine. + * + * If the IE buffer has been setup by the application, this routine appends + * the buffer as a pass through TLV type to the request. + */ +static int +mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer) +{ + int ret_len = 0; + struct mwifiex_ie_types_header ie_header; + + /* Null Checks */ + if (!buffer) + return 0; + if (!(*buffer)) + return 0; + + /* + * If there is a generic ie buffer setup, append it to the return + * parameter buffer pointer. + */ + if (priv->gen_ie_buf_len) { + dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n", + __func__, priv->gen_ie_buf_len, *buffer); + + /* Wrap the generic IE buffer with a pass through TLV type */ + ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); + ie_header.len = cpu_to_le16(priv->gen_ie_buf_len); + memcpy(*buffer, &ie_header, sizeof(ie_header)); + + /* Increment the return size and the return buffer pointer + param */ + *buffer += sizeof(ie_header); + ret_len += sizeof(ie_header); + + /* Copy the generic IE buffer to the output buffer, advance + pointer */ + memcpy(*buffer, priv->gen_ie_buf, priv->gen_ie_buf_len); + + /* Increment the return size and the return buffer pointer + param */ + *buffer += priv->gen_ie_buf_len; + ret_len += priv->gen_ie_buf_len; + + /* Reset the generic IE buffer */ + priv->gen_ie_buf_len = 0; + } + + /* return the length appended to the buffer */ + return ret_len; +} + +/* + * Append TSF tracking info from the scan table for the target AP. + * + * This function is called from the network join command preparation routine. + * + * The TSF table TSF sent to the firmware contains two TSF values: + * - The TSF of the target AP from its previous beacon/probe response + * - The TSF timestamp of our local MAC at the time we observed the + * beacon/probe response. + * + * The firmware uses the timestamp values to set an initial TSF value + * in the MAC for the new association after a reassociation attempt. + */ +static int +mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, + struct mwifiex_bssdescriptor *bss_desc) +{ + struct mwifiex_ie_types_tsf_timestamp tsf_tlv; + long long tsf_val; + + /* Null Checks */ + if (buffer == NULL) + return 0; + if (*buffer == NULL) + return 0; + + memset(&tsf_tlv, 0x00, sizeof(struct mwifiex_ie_types_tsf_timestamp)); + + tsf_tlv.header.type = cpu_to_le16(TLV_TYPE_TSFTIMESTAMP); + tsf_tlv.header.len = cpu_to_le16(2 * sizeof(tsf_val)); + + memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header)); + *buffer += sizeof(tsf_tlv.header); + + memcpy(*buffer, &tsf_val, sizeof(tsf_val)); + *buffer += sizeof(tsf_val); + + memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); + + dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - " + "%016llx\n", __func__, tsf_val, bss_desc->network_tsf); + + memcpy(*buffer, &tsf_val, sizeof(tsf_val)); + *buffer += sizeof(tsf_val); + + return sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val)); +} + +/* + * This function finds out the common rates between rate1 and rate2. + * + * It will fill common rates in rate1 as output if found. + * + * NOTE: Setting the MSB of the basic rates needs to be taken + * care of, either before or after calling this function. + */ +static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, + u32 rate1_size, u8 *rate2, u32 rate2_size) +{ + int ret = 0; + u8 *ptr = rate1; + u8 *tmp = NULL; + u32 i, j; + + tmp = kmalloc(rate1_size, GFP_KERNEL); + if (!tmp) { + dev_err(priv->adapter->dev, "failed to alloc tmp buf\n"); + return -ENOMEM; + } + + memcpy(tmp, rate1, rate1_size); + memset(rate1, 0, rate1_size); + + for (i = 0; rate2[i] && i < rate2_size; i++) { + for (j = 0; tmp[j] && j < rate1_size; j++) { + /* Check common rate, excluding the bit for + basic rate */ + if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) { + *rate1++ = tmp[j]; + break; + } + } + } + + dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n", + priv->data_rate); + + if (!priv->is_data_rate_auto) { + while (*ptr) { + if ((*ptr & 0x7f) == priv->data_rate) { + ret = 0; + goto done; + } + ptr++; + } + dev_err(priv->adapter->dev, "previously set fixed data rate %#x" + " is not compatible with the network\n", + priv->data_rate); + + ret = -1; + goto done; + } + + ret = 0; +done: + kfree(tmp); + return ret; +} + +/* + * This function creates the intersection of the rates supported by a + * target BSS and our adapter settings for use in an assoc/join command. + */ +static int +mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc, + u8 *out_rates, u32 *out_rates_size) +{ + u8 card_rates[MWIFIEX_SUPPORTED_RATES]; + u32 card_rates_size = 0; + + /* Copy AP supported rates */ + memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES); + /* Get the STA supported rates */ + card_rates_size = mwifiex_get_active_data_rates(priv, card_rates); + /* Get the common rates between AP and STA supported rates */ + if (mwifiex_get_common_rates(priv, out_rates, MWIFIEX_SUPPORTED_RATES, + card_rates, card_rates_size)) { + *out_rates_size = 0; + dev_err(priv->adapter->dev, "%s: cannot get common rates\n", + __func__); + return -1; + } + + *out_rates_size = + min_t(size_t, strlen(out_rates), MWIFIEX_SUPPORTED_RATES); + + return 0; +} + +/* + * This function updates the scan entry TSF timestamps to reflect + * a new association. + */ +static void +mwifiex_update_tsf_timestamps(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *new_bss_desc) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u32 table_idx; + long long new_tsf_base; + signed long long tsf_delta; + + memcpy(&new_tsf_base, new_bss_desc->time_stamp, sizeof(new_tsf_base)); + + tsf_delta = new_tsf_base - new_bss_desc->network_tsf; + + dev_dbg(adapter->dev, "info: TSF: update TSF timestamps, " + "0x%016llx -> 0x%016llx\n", + new_bss_desc->network_tsf, new_tsf_base); + + for (table_idx = 0; table_idx < adapter->num_in_scan_table; + table_idx++) + adapter->scan_table[table_idx].network_tsf += tsf_delta; +} + +/* + * This function appends a WAPI IE. + * + * This function is called from the network join command preparation routine. + * + * If the IE buffer has been setup by the application, this routine appends + * the buffer as a WAPI TLV type to the request. + */ +static int +mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer) +{ + int retLen = 0; + struct mwifiex_ie_types_header ie_header; + + /* Null Checks */ + if (buffer == NULL) + return 0; + if (*buffer == NULL) + return 0; + + /* + * If there is a wapi ie buffer setup, append it to the return + * parameter buffer pointer. + */ + if (priv->wapi_ie_len) { + dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n", + priv->wapi_ie_len, *buffer); + + /* Wrap the generic IE buffer with a pass through TLV type */ + ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE); + ie_header.len = cpu_to_le16(priv->wapi_ie_len); + memcpy(*buffer, &ie_header, sizeof(ie_header)); + + /* Increment the return size and the return buffer pointer + param */ + *buffer += sizeof(ie_header); + retLen += sizeof(ie_header); + + /* Copy the wapi IE buffer to the output buffer, advance + pointer */ + memcpy(*buffer, priv->wapi_ie, priv->wapi_ie_len); + + /* Increment the return size and the return buffer pointer + param */ + *buffer += priv->wapi_ie_len; + retLen += priv->wapi_ie_len; + + } + /* return the length appended to the buffer */ + return retLen; +} + +/* + * This function appends rsn ie tlv for wpa/wpa2 security modes. + * It is called from the network join command preparation routine. + */ +static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, + u8 **buffer) +{ + struct mwifiex_ie_types_rsn_param_set *rsn_ie_tlv; + int rsn_ie_len; + + if (!buffer || !(*buffer)) + return 0; + + rsn_ie_tlv = (struct mwifiex_ie_types_rsn_param_set *) (*buffer); + rsn_ie_tlv->header.type = cpu_to_le16((u16) priv->wpa_ie[0]); + rsn_ie_tlv->header.type = cpu_to_le16( + le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF); + rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]); + rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len) + & 0x00FF); + if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2)) + memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2], + le16_to_cpu(rsn_ie_tlv->header.len)); + else + return -1; + + rsn_ie_len = sizeof(rsn_ie_tlv->header) + + le16_to_cpu(rsn_ie_tlv->header.len); + *buffer += rsn_ie_len; + + return rsn_ie_len; +} + +/* + * This function prepares command for association. + * + * This sets the following parameters - + * - Peer MAC address + * - Listen interval + * - Beacon interval + * - Capability information + * + * ...and the following TLVs, as required - + * - SSID TLV + * - PHY TLV + * - SS TLV + * - Rates TLV + * - Authentication TLV + * - Channel TLV + * - WPA/WPA2 IE + * - 11n TLV + * - Vendor specific TLV + * - WMM TLV + * - WAPI IE + * - Generic IE + * - TSF TLV + * + * Preparation also includes - + * - Setting command ID and proper size + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf) +{ + struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate; + struct mwifiex_bssdescriptor *bss_desc; + struct mwifiex_ie_types_ssid_param_set *ssid_tlv; + struct mwifiex_ie_types_phy_param_set *phy_tlv; + struct mwifiex_ie_types_ss_param_set *ss_tlv; + struct mwifiex_ie_types_rates_param_set *rates_tlv; + struct mwifiex_ie_types_auth_type *auth_tlv; + struct mwifiex_ie_types_chan_list_param_set *chan_tlv; + u8 rates[MWIFIEX_SUPPORTED_RATES]; + u32 rates_size; + u16 tmp_cap; + u8 *pos; + int rsn_ie_len = 0; + + bss_desc = (struct mwifiex_bssdescriptor *) data_buf; + pos = (u8 *) assoc; + + mwifiex_cfg_tx_buf(priv, bss_desc); + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE); + + /* Save so we know which BSS Desc to use in the response handler */ + priv->attempted_bss_desc = bss_desc; + + memcpy(assoc->peer_sta_addr, + bss_desc->mac_address, sizeof(assoc->peer_sta_addr)); + pos += sizeof(assoc->peer_sta_addr); + + /* Set the listen interval */ + assoc->listen_interval = cpu_to_le16(priv->listen_interval); + /* Set the beacon period */ + assoc->beacon_period = cpu_to_le16(bss_desc->beacon_period); + + pos += sizeof(assoc->cap_info_bitmap); + pos += sizeof(assoc->listen_interval); + pos += sizeof(assoc->beacon_period); + pos += sizeof(assoc->dtim_period); + + ssid_tlv = (struct mwifiex_ie_types_ssid_param_set *) pos; + ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID); + ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len); + memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid, + le16_to_cpu(ssid_tlv->header.len)); + pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len); + + phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; + phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS); + phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set)); + memcpy(&phy_tlv->fh_ds.ds_param_set, + &bss_desc->phy_param_set.ds_param_set.current_chan, + sizeof(phy_tlv->fh_ds.ds_param_set)); + pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len); + + ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos; + ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS); + ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set)); + pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len); + + /* Get the common rates supported between the driver and the BSS Desc */ + if (mwifiex_setup_rates_from_bssdesc + (priv, bss_desc, rates, &rates_size)) + return -1; + + /* Save the data rates into Current BSS state structure */ + priv->curr_bss_params.num_of_rates = rates_size; + memcpy(&priv->curr_bss_params.data_rates, rates, rates_size); + + /* Setup the Rates TLV in the association command */ + rates_tlv = (struct mwifiex_ie_types_rates_param_set *) pos; + rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES); + rates_tlv->header.len = cpu_to_le16((u16) rates_size); + memcpy(rates_tlv->rates, rates, rates_size); + pos += sizeof(rates_tlv->header) + rates_size; + dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", + rates_size); + + /* Add the Authentication type to be used for Auth frames if needed */ + if (priv->sec_info.authentication_mode != MWIFIEX_AUTH_MODE_AUTO) { + auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; + auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); + auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type)); + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + auth_tlv->auth_type = cpu_to_le16((u16) priv->sec_info. + authentication_mode); + else + auth_tlv->auth_type = + cpu_to_le16(MWIFIEX_AUTH_MODE_OPEN); + pos += sizeof(auth_tlv->header) + + le16_to_cpu(auth_tlv->header.len); + } + + if (IS_SUPPORT_MULTI_BANDS(priv->adapter) + && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) + && (!bss_desc->disable_11n) + && (priv->adapter->config_bands & BAND_GN + || priv->adapter->config_bands & BAND_AN) + && (bss_desc->bcn_ht_cap) + ) + ) { + /* Append a channel TLV for the channel the attempted AP was + found on */ + chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos; + chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); + chan_tlv->header.len = + cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set)); + + memset(chan_tlv->chan_scan_param, 0x00, + sizeof(struct mwifiex_chan_scan_param_set)); + chan_tlv->chan_scan_param[0].chan_number = + (bss_desc->phy_param_set.ds_param_set.current_chan); + dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n", + chan_tlv->chan_scan_param[0].chan_number); + + chan_tlv->chan_scan_param[0].radio_type = + mwifiex_band_to_radio_type((u8) bss_desc->bss_band); + + dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n", + chan_tlv->chan_scan_param[0].radio_type); + pos += sizeof(chan_tlv->header) + + sizeof(struct mwifiex_chan_scan_param_set); + } + + if (!priv->wps.session_enable) { + if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) + rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos); + + if (rsn_ie_len == -1) + return -1; + } + + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) + && (!bss_desc->disable_11n) + && (priv->adapter->config_bands & BAND_GN + || priv->adapter->config_bands & BAND_AN)) + mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); + + /* Append vendor specific IE TLV */ + mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos); + + mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie, + bss_desc->bcn_ht_cap); + if (priv->sec_info.wapi_enabled && priv->wapi_ie_len) + mwifiex_cmd_append_wapi_ie(priv, &pos); + + + mwifiex_cmd_append_generic_ie(priv, &pos); + + mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc); + + cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN); + + /* Set the Capability info at last */ + tmp_cap = bss_desc->cap_info_bitmap; + + if (priv->adapter->config_bands == BAND_B) + SHORT_SLOT_TIME_DISABLED(tmp_cap); + + tmp_cap &= CAPINFO_MASK; + dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", + tmp_cap, CAPINFO_MASK); + assoc->cap_info_bitmap = cpu_to_le16(tmp_cap); + + return 0; +} + +/* + * Association firmware command response handler + * + * The response buffer for the association command has the following + * memory layout. + * + * For cases where an association response was not received (indicated + * by the CapInfo and AId field): + * + * .------------------------------------------------------------. + * | Header(4 * sizeof(t_u16)): Standard command response hdr | + * .------------------------------------------------------------. + * | cap_info/Error Return(t_u16): | + * | 0xFFFF(-1): Internal error | + * | 0xFFFE(-2): Authentication unhandled message | + * | 0xFFFD(-3): Authentication refused | + * | 0xFFFC(-4): Timeout waiting for AP response | + * .------------------------------------------------------------. + * | status_code(t_u16): | + * | If cap_info is -1: | + * | An internal firmware failure prevented the | + * | command from being processed. The status_code | + * | will be set to 1. | + * | | + * | If cap_info is -2: | + * | An authentication frame was received but was | + * | not handled by the firmware. IEEE Status | + * | code for the failure is returned. | + * | | + * | If cap_info is -3: | + * | An authentication frame was received and the | + * | status_code is the IEEE Status reported in the | + * | response. | + * | | + * | If cap_info is -4: | + * | (1) Association response timeout | + * | (2) Authentication response timeout | + * .------------------------------------------------------------. + * | a_id(t_u16): 0xFFFF | + * .------------------------------------------------------------. + * + * + * For cases where an association response was received, the IEEE + * standard association response frame is returned: + * + * .------------------------------------------------------------. + * | Header(4 * sizeof(t_u16)): Standard command response hdr | + * .------------------------------------------------------------. + * | cap_info(t_u16): IEEE Capability | + * .------------------------------------------------------------. + * | status_code(t_u16): IEEE Status Code | + * .------------------------------------------------------------. + * | a_id(t_u16): IEEE Association ID | + * .------------------------------------------------------------. + * | IEEE IEs(variable): Any received IEs comprising the | + * | remaining portion of a received | + * | association response frame. | + * .------------------------------------------------------------. + * + * For simplistic handling, the status_code field can be used to determine + * an association success (0) or failure (non-zero). + */ +int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, void *wq_buf) +{ + int ret = 0; + struct mwifiex_wait_queue *wait_queue = + (struct mwifiex_wait_queue *) wq_buf; + struct ieee_types_assoc_rsp *assoc_rsp; + struct mwifiex_bssdescriptor *bss_desc; + u8 enable_data = true; + + assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; + + priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, + sizeof(priv->assoc_rsp_buf)); + + memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); + + if (le16_to_cpu(assoc_rsp->status_code)) { + priv->adapter->dbg.num_cmd_assoc_failure++; + dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, " + "status code = %d, error = 0x%x, a_id = 0x%x\n", + le16_to_cpu(assoc_rsp->status_code), + le16_to_cpu(assoc_rsp->cap_info_bitmap), + le16_to_cpu(assoc_rsp->a_id)); + + ret = -1; + goto done; + } + + /* Send a Media Connected event, according to the Spec */ + priv->media_connected = true; + + priv->adapter->ps_state = PS_STATE_AWAKE; + priv->adapter->pps_uapsd_mode = false; + priv->adapter->tx_lock_flag = false; + + /* Set the attempted BSSID Index to current */ + bss_desc = priv->attempted_bss_desc; + + dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n", + bss_desc->ssid.ssid); + + /* Make a copy of current BSSID descriptor */ + memcpy(&priv->curr_bss_params.bss_descriptor, + bss_desc, sizeof(struct mwifiex_bssdescriptor)); + + /* Update curr_bss_params */ + priv->curr_bss_params.bss_descriptor.channel + = bss_desc->phy_param_set.ds_param_set.current_chan; + + priv->curr_bss_params.band = (u8) bss_desc->bss_band; + + /* + * Adjust the timestamps in the scan table to be relative to the newly + * associated AP's TSF + */ + mwifiex_update_tsf_timestamps(priv, bss_desc); + + if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) + priv->curr_bss_params.wmm_enabled = true; + else + priv->curr_bss_params.wmm_enabled = false; + + if ((priv->wmm_required || bss_desc->bcn_ht_cap) + && priv->curr_bss_params.wmm_enabled) + priv->wmm_enabled = true; + else + priv->wmm_enabled = false; + + priv->curr_bss_params.wmm_uapsd_enabled = false; + + if (priv->wmm_enabled) + priv->curr_bss_params.wmm_uapsd_enabled + = ((bss_desc->wmm_ie.qos_info_bitmap & + IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0); + + dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n", + priv->curr_pkt_filter); + if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) + priv->wpa_is_gtk_set = false; + + if (priv->wmm_enabled) { + /* Don't re-enable carrier until we get the WMM_GET_STATUS + event */ + enable_data = false; + } else { + /* Since WMM is not enabled, setup the queues with the + defaults */ + mwifiex_wmm_setup_queue_priorities(priv, NULL); + mwifiex_wmm_setup_ac_downgrade(priv); + } + + if (enable_data) + dev_dbg(priv->adapter->dev, + "info: post association, re-enabling data flow\n"); + + /* Reset SNR/NF/RSSI values */ + priv->data_rssi_last = 0; + priv->data_nf_last = 0; + priv->data_rssi_avg = 0; + priv->data_nf_avg = 0; + priv->bcn_rssi_last = 0; + priv->bcn_nf_last = 0; + priv->bcn_rssi_avg = 0; + priv->bcn_nf_avg = 0; + priv->rxpd_rate = 0; + priv->rxpd_htinfo = 0; + + mwifiex_save_curr_bcn(priv); + + priv->adapter->dbg.num_cmd_assoc_success++; + + dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: associated\n"); + + /* Add the ra_list here for infra mode as there will be only 1 ra + always */ + mwifiex_ralist_add(priv, + priv->curr_bss_params.bss_descriptor.mac_address); + + if (!netif_carrier_ok(priv->netdev)) + netif_carrier_on(priv->netdev); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); + + if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) + priv->scan_block = true; + +done: + /* Need to indicate IOCTL complete */ + if (wait_queue) { + if (ret) { + if (assoc_rsp->status_code) + wait_queue->status = + le16_to_cpu(assoc_rsp->status_code); + else + wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; + } else { + wait_queue->status = MWIFIEX_ERROR_NO_ERROR; + } + } + + return ret; +} + +/* + * This function prepares command for ad-hoc start. + * + * Driver will fill up SSID, BSS mode, IBSS parameters, physical + * parameters, probe delay, and capability information. Firmware + * will fill up beacon period, basic rates and operational rates. + * + * In addition, the following TLVs are added - + * - Channel TLV + * - Vendor specific IE + * - WPA/WPA2 IE + * - HT Capabilities IE + * - HT Information IE + * + * Preparation also includes - + * - Setting command ID and proper size + * - Ensuring correct endian-ness + */ +int +mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, void *data_buf) +{ + int ret = 0, rsn_ie_len = 0; + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start = + &cmd->params.adhoc_start; + struct mwifiex_bssdescriptor *bss_desc; + u32 cmd_append_size = 0; + u32 i; + u16 tmp_cap; + uint16_t ht_cap_info; + struct mwifiex_ie_types_chan_list_param_set *chan_tlv; + + struct mwifiex_ie_types_htcap *ht_cap; + struct mwifiex_ie_types_htinfo *ht_info; + u8 *pos = (u8 *) adhoc_start + + sizeof(struct host_cmd_ds_802_11_ad_hoc_start); + + if (!adapter) + return -1; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START); + + bss_desc = &priv->curr_bss_params.bss_descriptor; + priv->attempted_bss_desc = bss_desc; + + /* + * Fill in the parameters for 2 data structures: + * 1. struct host_cmd_ds_802_11_ad_hoc_start command + * 2. bss_desc + * Driver will fill up SSID, bss_mode,IBSS param, Physical Param, + * probe delay, and Cap info. + * Firmware will fill up beacon period, Basic rates + * and operational rates. + */ + + memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN); + + memcpy(adhoc_start->ssid, + ((struct mwifiex_802_11_ssid *) data_buf)->ssid, + ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); + + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", + adhoc_start->ssid); + + memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); + memcpy(bss_desc->ssid.ssid, + ((struct mwifiex_802_11_ssid *) data_buf)->ssid, + ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len); + + bss_desc->ssid.ssid_len = + ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len; + + /* Set the BSS mode */ + adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS; + bss_desc->bss_mode = MWIFIEX_BSS_MODE_IBSS; + adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period); + bss_desc->beacon_period = priv->beacon_period; + + /* Set Physical param set */ +/* Parameter IE Id */ +#define DS_PARA_IE_ID 3 +/* Parameter IE length */ +#define DS_PARA_IE_LEN 1 + + adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID; + adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN; + + if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, adapter->adhoc_start_band, (u16) + priv->adhoc_channel)) { + struct mwifiex_chan_freq_power *cfp; + cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, + adapter->adhoc_start_band, FIRST_VALID_CHANNEL); + if (cfp) + priv->adhoc_channel = (u8) cfp->channel; + } + + if (!priv->adhoc_channel) { + dev_err(adapter->dev, "ADHOC_S_CMD: adhoc_channel cannot be 0\n"); + return -1; + } + + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n", + priv->adhoc_channel); + + priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel; + priv->curr_bss_params.band = adapter->adhoc_start_band; + + bss_desc->channel = priv->adhoc_channel; + adhoc_start->phy_param_set.ds_param_set.current_chan = + priv->adhoc_channel; + + memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set, + sizeof(union ieee_types_phy_param_set)); + + /* Set IBSS param set */ +/* IBSS parameter IE Id */ +#define IBSS_PARA_IE_ID 6 +/* IBSS parameter IE length */ +#define IBSS_PARA_IE_LEN 2 + + adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID; + adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN; + adhoc_start->ss_param_set.ibss_param_set.atim_window + = cpu_to_le16(priv->atim_window); + memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set, + sizeof(union ieee_types_ss_param_set)); + + /* Set Capability info */ + bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS; + tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap); + tmp_cap &= ~WLAN_CAPABILITY_ESS; + tmp_cap |= WLAN_CAPABILITY_IBSS; + + /* Set up privacy in bss_desc */ + if (priv->sec_info.encryption_mode != MWIFIEX_ENCRYPTION_MODE_NONE) { + /* Ad-Hoc capability privacy on */ + dev_dbg(adapter->dev, + "info: ADHOC_S_CMD: wep_status set privacy to WEP\n"); + bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; + tmp_cap |= WLAN_CAPABILITY_PRIVACY; + } else { + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status NOT set," + " setting privacy to ACCEPT ALL\n"); + bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; + } + + memset(adhoc_start->DataRate, 0, sizeof(adhoc_start->DataRate)); + mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); + if ((adapter->adhoc_start_band & BAND_G) && + (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, + 0, NULL, &priv->curr_pkt_filter); + + if (ret) { + dev_err(adapter->dev, + "ADHOC_S_CMD: G Protection config failed\n"); + return -1; + } + } + /* Find the last non zero */ + for (i = 0; i < sizeof(adhoc_start->DataRate) && + adhoc_start->DataRate[i]; + i++) + ; + + priv->curr_bss_params.num_of_rates = i; + + /* Copy the ad-hoc creating rates into Current BSS rate structure */ + memcpy(&priv->curr_bss_params.data_rates, + &adhoc_start->DataRate, priv->curr_bss_params.num_of_rates); + + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", + adhoc_start->DataRate[0], adhoc_start->DataRate[1], + adhoc_start->DataRate[2], adhoc_start->DataRate[3]); + + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); + + if (IS_SUPPORT_MULTI_BANDS(adapter)) { + /* Append a channel TLV */ + chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos; + chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); + chan_tlv->header.len = + cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set)); + + memset(chan_tlv->chan_scan_param, 0x00, + sizeof(struct mwifiex_chan_scan_param_set)); + chan_tlv->chan_scan_param[0].chan_number = + (u8) priv->curr_bss_params.bss_descriptor.channel; + + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n", + chan_tlv->chan_scan_param[0].chan_number); + + chan_tlv->chan_scan_param[0].radio_type + = mwifiex_band_to_radio_type(priv->curr_bss_params.band); + if (adapter->adhoc_start_band & BAND_GN + || adapter->adhoc_start_band & BAND_AN) { + if (adapter->chan_offset == SEC_CHANNEL_ABOVE) + chan_tlv->chan_scan_param[0].radio_type |= + SECOND_CHANNEL_ABOVE; + else if (adapter->chan_offset == SEC_CHANNEL_BELOW) + chan_tlv->chan_scan_param[0].radio_type |= + SECOND_CHANNEL_BELOW; + } + dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", + chan_tlv->chan_scan_param[0].radio_type); + pos += sizeof(chan_tlv->header) + + sizeof(struct mwifiex_chan_scan_param_set); + cmd_append_size += + sizeof(chan_tlv->header) + + sizeof(struct mwifiex_chan_scan_param_set); + } + + /* Append vendor specific IE TLV */ + cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, + MWIFIEX_VSIE_MASK_ADHOC, &pos); + + if (priv->sec_info.wpa_enabled) { + rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos); + if (rsn_ie_len == -1) + return -1; + cmd_append_size += rsn_ie_len; + } + + if (adapter->adhoc_11n_enabled) { + { + ht_cap = (struct mwifiex_ie_types_htcap *) pos; + memset(ht_cap, 0, + sizeof(struct mwifiex_ie_types_htcap)); + ht_cap->header.type = + cpu_to_le16(WLAN_EID_HT_CAPABILITY); + ht_cap->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_cap)); + ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); + + SETHT_SHORTGI20(ht_cap_info); + if (adapter->chan_offset) { + SETHT_SHORTGI40(ht_cap_info); + SETHT_DSSSCCK40(ht_cap_info); + SETHT_SUPPCHANWIDTH(ht_cap_info); + SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); + } + + ht_cap->ht_cap.ampdu_params_info + = MAX_RX_AMPDU_SIZE_64K; + ht_cap->ht_cap.mcs.rx_mask[0] = 0xff; + pos += sizeof(struct mwifiex_ie_types_htcap); + cmd_append_size += + sizeof(struct mwifiex_ie_types_htcap); + } + { + ht_info = (struct mwifiex_ie_types_htinfo *) pos; + memset(ht_info, 0, + sizeof(struct mwifiex_ie_types_htinfo)); + ht_info->header.type = + cpu_to_le16(WLAN_EID_HT_INFORMATION); + ht_info->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_info)); + ht_info->ht_info.control_chan = + (u8) priv->curr_bss_params.bss_descriptor. + channel; + if (adapter->chan_offset) { + ht_info->ht_info.ht_param = + adapter->chan_offset; + SET_CHANWIDTH40(ht_info->ht_info.ht_param); + } + ht_info->ht_info.operation_mode = + cpu_to_le16(NON_GREENFIELD_STAS); + ht_info->ht_info.basic_set[0] = 0xff; + pos += sizeof(struct mwifiex_ie_types_htinfo); + cmd_append_size += + sizeof(struct mwifiex_ie_types_htinfo); + } + } + + cmd->size = cpu_to_le16((u16) + (sizeof(struct host_cmd_ds_802_11_ad_hoc_start) + + S_DS_GEN + cmd_append_size)); + + if (adapter->adhoc_start_band == BAND_B) + SHORT_SLOT_TIME_DISABLED(tmp_cap); + else + SHORT_SLOT_TIME_ENABLED(tmp_cap); + + adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap); + + return 0; +} + +/* + * This function prepares command for ad-hoc join. + * + * Most of the parameters are set up by copying from the target BSS descriptor + * from the scan response. + * + * In addition, the following TLVs are added - + * - Channel TLV + * - Vendor specific IE + * - WPA/WPA2 IE + * - 11n IE + * + * Preparation also includes - + * - Setting command ID and proper size + * - Ensuring correct endian-ness + */ +int +mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, void *data_buf) +{ + int ret = 0, rsn_ie_len = 0; + struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join = + &cmd->params.adhoc_join; + struct mwifiex_bssdescriptor *bss_desc = + (struct mwifiex_bssdescriptor *) data_buf; + struct mwifiex_ie_types_chan_list_param_set *chan_tlv; + u32 cmd_append_size = 0; + u16 tmp_cap; + u32 i, rates_size = 0; + u16 curr_pkt_filter; + u8 *pos = + (u8 *) adhoc_join + + sizeof(struct host_cmd_ds_802_11_ad_hoc_join); + +/* Use G protection */ +#define USE_G_PROTECTION 0x02 + if (bss_desc->erp_flags & USE_G_PROTECTION) { + curr_pkt_filter = + priv-> + curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, NULL, + &curr_pkt_filter); + if (ret) { + dev_err(priv->adapter->dev, + "ADHOC_J_CMD: G Protection config failed\n"); + return -1; + } + } + + priv->attempted_bss_desc = bss_desc; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN); + + adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS; + + adhoc_join->bss_descriptor.beacon_period + = cpu_to_le16(bss_desc->beacon_period); + + memcpy(&adhoc_join->bss_descriptor.bssid, + &bss_desc->mac_address, ETH_ALEN); + + memcpy(&adhoc_join->bss_descriptor.ssid, + &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len); + + memcpy(&adhoc_join->bss_descriptor.phy_param_set, + &bss_desc->phy_param_set, + sizeof(union ieee_types_phy_param_set)); + + memcpy(&adhoc_join->bss_descriptor.ss_param_set, + &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set)); + + tmp_cap = bss_desc->cap_info_bitmap; + + tmp_cap &= CAPINFO_MASK; + + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X" + " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK); + + /* Information on BSSID descriptor passed to FW */ + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n", + adhoc_join->bss_descriptor.bssid, + adhoc_join->bss_descriptor.ssid); + + for (i = 0; bss_desc->supported_rates[i] && + i < MWIFIEX_SUPPORTED_RATES; + i++) + ; + rates_size = i; + + /* Copy Data Rates from the Rates recorded in scan response */ + memset(adhoc_join->bss_descriptor.data_rates, 0, + sizeof(adhoc_join->bss_descriptor.data_rates)); + memcpy(adhoc_join->bss_descriptor.data_rates, + bss_desc->supported_rates, rates_size); + + /* Copy the adhoc join rates into Current BSS state structure */ + priv->curr_bss_params.num_of_rates = rates_size; + memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates, + rates_size); + + /* Copy the channel information */ + priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel; + priv->curr_bss_params.band = (u8) bss_desc->bss_band; + + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED + || priv->sec_info.wpa_enabled) + tmp_cap |= WLAN_CAPABILITY_PRIVACY; + + if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) { + /* Append a channel TLV */ + chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos; + chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); + chan_tlv->header.len = + cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set)); + + memset(chan_tlv->chan_scan_param, 0x00, + sizeof(struct mwifiex_chan_scan_param_set)); + chan_tlv->chan_scan_param[0].chan_number = + (bss_desc->phy_param_set.ds_param_set.current_chan); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n", + chan_tlv->chan_scan_param[0].chan_number); + + chan_tlv->chan_scan_param[0].radio_type = + mwifiex_band_to_radio_type((u8) bss_desc->bss_band); + + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n", + chan_tlv->chan_scan_param[0].radio_type); + pos += sizeof(chan_tlv->header) + + sizeof(struct mwifiex_chan_scan_param_set); + cmd_append_size += sizeof(chan_tlv->header) + + sizeof(struct mwifiex_chan_scan_param_set); + } + + if (priv->sec_info.wpa_enabled) + rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos); + if (rsn_ie_len == -1) + return -1; + cmd_append_size += rsn_ie_len; + + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)) + cmd_append_size += mwifiex_cmd_append_11n_tlv(priv, + bss_desc, &pos); + + /* Append vendor specific IE TLV */ + cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, + MWIFIEX_VSIE_MASK_ADHOC, &pos); + + cmd->size = cpu_to_le16((u16) + (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) + + S_DS_GEN + cmd_append_size)); + + adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); + + return ret; +} + +/* + * This function handles the command response of ad-hoc start and + * ad-hoc join. + * + * The function generates a device-connected event to notify + * the applications, in case of successful ad-hoc start/join, and + * saves the beacon buffer. + */ +int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, void *wq_buf) +{ + int ret = 0; + struct mwifiex_wait_queue *wait_queue = + (struct mwifiex_wait_queue *) wq_buf; + struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; + struct mwifiex_bssdescriptor *bss_desc; + u16 command = le16_to_cpu(resp->command); + u16 result = le16_to_cpu(resp->result); + + adhoc_result = &resp->params.adhoc_result; + + bss_desc = priv->attempted_bss_desc; + + /* Join result code 0 --> SUCCESS */ + if (result) { + dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n"); + if (priv->media_connected) + mwifiex_reset_connect_state(priv); + + memset(&priv->curr_bss_params.bss_descriptor, + 0x00, sizeof(struct mwifiex_bssdescriptor)); + + ret = -1; + goto done; + } + + /* Send a Media Connected event, according to the Spec */ + priv->media_connected = true; + + if (command == HostCmd_CMD_802_11_AD_HOC_START) { + dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", + bss_desc->ssid.ssid); + + /* Update the created network descriptor with the new BSSID */ + memcpy(bss_desc->mac_address, + adhoc_result->bssid, ETH_ALEN); + + priv->adhoc_state = ADHOC_STARTED; + } else { + /* + * Now the join cmd should be successful. + * If BSSID has changed use SSID to compare instead of BSSID + */ + dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n", + bss_desc->ssid.ssid); + + /* + * Make a copy of current BSSID descriptor, only needed for + * join since the current descriptor is already being used + * for adhoc start + */ + memcpy(&priv->curr_bss_params.bss_descriptor, + bss_desc, sizeof(struct mwifiex_bssdescriptor)); + + priv->adhoc_state = ADHOC_JOINED; + } + + dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n", + priv->adhoc_channel); + dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n", + priv->curr_bss_params.bss_descriptor.mac_address); + + if (!netif_carrier_ok(priv->netdev)) + netif_carrier_on(priv->netdev); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); + + mwifiex_save_curr_bcn(priv); + +done: + /* Need to indicate IOCTL complete */ + if (wait_queue) { + if (ret) + wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; + else + wait_queue->status = MWIFIEX_ERROR_NO_ERROR; + + } + + return ret; +} + +/* + * This function associates to a specific BSS discovered in a scan. + * + * It clears any past association response stored for application + * retrieval and calls the command preparation routine to send the + * command to firmware. + */ +int mwifiex_associate(struct mwifiex_private *priv, + void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) +{ + int ret = 0; + u8 current_bssid[ETH_ALEN]; + + /* Return error if the adapter or table entry is not marked as infra */ + if ((priv->bss_mode != MWIFIEX_BSS_MODE_INFRA) || + (bss_desc->bss_mode != MWIFIEX_BSS_MODE_INFRA)) + return -1; + + memcpy(¤t_bssid, + &priv->curr_bss_params.bss_descriptor.mac_address, + sizeof(current_bssid)); + + /* Clear any past association response stored for application + retrieval */ + priv->assoc_rsp_size = 0; + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE, + HostCmd_ACT_GEN_SET, 0, wait_queue, + bss_desc); + + return ret; +} + +/* + * This function starts an ad-hoc network. + * + * It calls the command preparation routine to send the command to firmware. + */ +int +mwifiex_adhoc_start(struct mwifiex_private *priv, + void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid) +{ + int ret = 0; + + dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", + priv->adhoc_channel); + dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", + priv->curr_bss_params.bss_descriptor.channel); + dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", + priv->curr_bss_params.band); + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START, + HostCmd_ACT_GEN_SET, 0, wait_queue, + adhoc_ssid); + + return ret; +} + +/* + * This function joins an ad-hoc network found in a previous scan. + * + * It calls the command preparation routine to send the command to firmware, + * if already not connected to the requested SSID. + */ +int mwifiex_adhoc_join(struct mwifiex_private *priv, + void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) +{ + int ret = 0; + + dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", + priv->curr_bss_params.bss_descriptor.ssid.ssid); + dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n", + bss_desc->ssid.ssid); + dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n", + bss_desc->ssid.ssid_len); + + /* Check if the requested SSID is already joined */ + if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len && + !mwifiex_ssid_cmp(&bss_desc->ssid, + &priv->curr_bss_params.bss_descriptor.ssid) && + (priv->curr_bss_params.bss_descriptor.bss_mode == + MWIFIEX_BSS_MODE_IBSS)) { + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID" + " is the same as current; not attempting to re-join\n"); + return -1; + } + + dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", + priv->curr_bss_params.bss_descriptor.channel); + dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", + priv->curr_bss_params.band); + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, + HostCmd_ACT_GEN_SET, 0, wait_queue, + bss_desc); + + return ret; +} + +/* + * This function deauthenticates/disconnects from infra network by sending + * deauthentication request. + */ +static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u8 *mac) +{ + u8 mac_address[ETH_ALEN]; + int ret = 0; + u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + if (mac) { + if (!memcmp(mac, zero_mac, sizeof(zero_mac))) + memcpy((u8 *) &mac_address, + (u8 *) &priv->curr_bss_params.bss_descriptor. + mac_address, ETH_ALEN); + else + memcpy((u8 *) &mac_address, (u8 *) mac, ETH_ALEN); + } else { + memcpy((u8 *) &mac_address, (u8 *) &priv->curr_bss_params. + bss_descriptor.mac_address, ETH_ALEN); + } + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, + HostCmd_ACT_GEN_SET, 0, wait, &mac_address); + + if (!ret && wait) + ret = -EINPROGRESS; + + return ret; +} + +/* + * This function deauthenticates/disconnects from a BSS. + * + * In case of infra made, it sends deauthentication request, and + * in case of ad-hoc mode, a stop network request is sent to the firmware. + */ +int mwifiex_deauthenticate(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, u8 *mac) +{ + int ret = 0; + + if (priv->media_connected) { + if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) { + ret = mwifiex_deauthenticate_infra(priv, wait, mac); + } else if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_AD_HOC_STOP, + HostCmd_ACT_GEN_SET, 0, wait, NULL); + + if (!ret && wait) + ret = -EINPROGRESS; + } + } + + return ret; +} + +/* + * This function converts band to radio type used in channel TLV. + */ +u8 +mwifiex_band_to_radio_type(u8 band) +{ + u8 ret_radio_type; + + switch (band) { + case BAND_A: + case BAND_AN: + case BAND_A | BAND_AN: + ret_radio_type = HostCmd_SCAN_RADIO_TYPE_A; + break; + case BAND_B: + case BAND_G: + case BAND_B | BAND_G: + default: + ret_radio_type = HostCmd_SCAN_RADIO_TYPE_BG; + break; + } + + return ret_radio_type; +} diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c new file mode 100644 index 000000000000..ed89ca41a902 --- /dev/null +++ b/drivers/net/wireless/mwifiex/main.c @@ -0,0 +1,1102 @@ +/* + * Marvell Wireless LAN device driver: major functions + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "main.h" +#include "wmm.h" +#include "cfg80211.h" +#include "11n.h" + +#define VERSION "1.0" + +const char driver_version[] = "mwifiex " VERSION " (%s) "; + +struct mwifiex_adapter *g_adapter; +EXPORT_SYMBOL_GPL(g_adapter); + +static struct mwifiex_bss_attr mwifiex_bss_sta[] = { + {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0}, +}; + +static int drv_mode = DRV_MODE_STA; + +static char fw_name[32] = DEFAULT_FW_NAME; + +/* Supported drv_mode table */ +static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { + { + /* drv_mode */ + .drv_mode = DRV_MODE_STA, + /* intf number */ + .intf_num = ARRAY_SIZE(mwifiex_bss_sta), + /* bss_attr */ + .bss_attr = mwifiex_bss_sta, + } + , +}; + +/* + * This function registers the device and performs all the necessary + * initializations. + * + * The following initialization operations are performed - + * - Allocate adapter structure + * - Save interface specific operations table in adapter + * - Call interface specific initialization routine + * - Allocate private structures + * - Set default adapter structure parameters + * - Initialize locks + * + * In case of any errors during inittialization, this function also ensures + * proper cleanup before exiting. + */ +static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, + struct mwifiex_device *mdevice, void **padapter) +{ + int ret = 0; + struct mwifiex_adapter *adapter = NULL; + u8 i = 0; + + adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL); + /* Allocate memory for adapter structure */ + if (!adapter) + return -1; + + g_adapter = adapter; + adapter->card = card; + + /* Save interface specific operations in adapter */ + memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops)); + + /* card specific initialization has been deferred until now .. */ + ret = adapter->if_ops.init_if(adapter); + if (ret) + goto error; + + adapter->priv_num = 0; + for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) { + adapter->priv[i] = NULL; + + if (!mdevice->bss_attr[i].active) + continue; + + /* For valid bss_attr, + allocate memory for private structure */ + adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private), + GFP_KERNEL); + if (!adapter->priv[i]) { + dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n", + __func__, i); + goto error; + } + + adapter->priv_num++; + memset(adapter->priv[i], 0, + sizeof(struct mwifiex_private)); + adapter->priv[i]->adapter = adapter; + /* Save bss_type, frame_type & bss_priority */ + adapter->priv[i]->bss_type = (u8) mdevice->bss_attr[i].bss_type; + adapter->priv[i]->frame_type = + (u8) mdevice->bss_attr[i].frame_type; + adapter->priv[i]->bss_priority = + (u8) mdevice->bss_attr[i].bss_priority; + if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA) + adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA; + else if (mdevice->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_UAP) + adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP; + + /* Save bss_index & bss_num */ + adapter->priv[i]->bss_index = i; + adapter->priv[i]->bss_num = mdevice->bss_attr[i].bss_num; + } + + /* Initialize lock variables */ + if (mwifiex_init_lock_list(adapter)) + goto error; + + init_timer(&adapter->cmd_timer); + adapter->cmd_timer.function = mwifiex_cmd_timeout_func; + adapter->cmd_timer.data = (unsigned long) adapter; + + /* Return pointer of struct mwifiex_adapter */ + *padapter = adapter; + return 0; + +error: + dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n"); + + /* Free lock variables */ + mwifiex_free_lock_list(adapter); + for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) + kfree(adapter->priv[i]); + kfree(adapter); + + return -1; +} + +/* + * This function unregisters the device and performs all the necessary + * cleanups. + * + * The following cleanup operations are performed - + * - Free the timers + * - Free beacon buffers + * - Free private structures + * - Free adapter structure + */ +static int mwifiex_unregister(struct mwifiex_adapter *adapter) +{ + s32 i = 0; + + del_timer(&adapter->cmd_timer); + + /* Free private structures */ + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + mwifiex_free_curr_bcn(adapter->priv[i]); + kfree(adapter->priv[i]); + } + } + + kfree(adapter); + return 0; +} + +/* + * The main process. + * + * This function is the main procedure of the driver and handles various driver + * operations. It runs in a loop and provides the core functionalities. + * + * The main responsibilities of this function are - + * - Ensure concurrency control + * - Handle pending interrupts and call interrupt handlers + * - Wake up the card if required + * - Handle command responses and call response handlers + * - Handle events and call event handlers + * - Execute pending commands + * - Transmit pending data packets + */ +int mwifiex_main_process(struct mwifiex_adapter *adapter) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&adapter->main_proc_lock, flags); + + /* Check if already processing */ + if (adapter->mwifiex_processing) { + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); + goto exit_main_proc; + } else { + adapter->mwifiex_processing = true; + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); + } +process_start: + do { + if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) || + (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) + break; + + /* Handle pending interrupt if any */ + if (adapter->int_status) { + if (adapter->hs_activated) + mwifiex_process_hs_config(adapter); + adapter->if_ops.process_int_status(adapter); + } + + /* Need to wake up the card ? */ + if ((adapter->ps_state == PS_STATE_SLEEP) && + (adapter->pm_wakeup_card_req && + !adapter->pm_wakeup_fw_try) && + (is_command_pending(adapter) + || !mwifiex_wmm_lists_empty(adapter))) { + adapter->pm_wakeup_fw_try = true; + adapter->if_ops.wakeup(adapter); + continue; + } + if (IS_CARD_RX_RCVD(adapter)) { + adapter->pm_wakeup_fw_try = false; + if (adapter->ps_state == PS_STATE_SLEEP) + adapter->ps_state = PS_STATE_AWAKE; + } else { + /* We have tried to wakeup the card already */ + if (adapter->pm_wakeup_fw_try) + break; + if (adapter->ps_state != PS_STATE_AWAKE || + adapter->tx_lock_flag) + break; + + if (adapter->scan_processing || adapter->data_sent + || mwifiex_wmm_lists_empty(adapter)) { + if (adapter->cmd_sent || adapter->curr_cmd + || (!is_command_pending(adapter))) + break; + } + } + + /* Check for Cmd Resp */ + if (adapter->cmd_resp_received) { + adapter->cmd_resp_received = false; + mwifiex_process_cmdresp(adapter); + + /* call mwifiex back when init_fw is done */ + if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) { + adapter->hw_status = MWIFIEX_HW_STATUS_READY; + mwifiex_init_fw_complete(adapter); + } + } + + /* Check for event */ + if (adapter->event_received) { + adapter->event_received = false; + mwifiex_process_event(adapter); + } + + /* Check if we need to confirm Sleep Request + received previously */ + if (adapter->ps_state == PS_STATE_PRE_SLEEP) { + if (!adapter->cmd_sent && !adapter->curr_cmd) + mwifiex_check_ps_cond(adapter); + } + + /* * The ps_state may have been changed during processing of + * Sleep Request event. + */ + if ((adapter->ps_state == PS_STATE_SLEEP) + || (adapter->ps_state == PS_STATE_PRE_SLEEP) + || (adapter->ps_state == PS_STATE_SLEEP_CFM) + || adapter->tx_lock_flag) + continue; + + if (!adapter->cmd_sent && !adapter->curr_cmd) { + if (mwifiex_exec_next_cmd(adapter) == -1) { + ret = -1; + break; + } + } + + if (!adapter->scan_processing && !adapter->data_sent && + !mwifiex_wmm_lists_empty(adapter)) { + mwifiex_wmm_process_tx(adapter); + if (adapter->hs_activated) { + adapter->is_hs_configured = false; + mwifiex_hs_activated_event + (mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_ANY), + false); + } + } + + if (adapter->delay_null_pkt && !adapter->cmd_sent && + !adapter->curr_cmd && !is_command_pending(adapter) + && mwifiex_wmm_lists_empty(adapter)) { + if (!mwifiex_send_null_packet + (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), + MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) { + adapter->delay_null_pkt = false; + adapter->ps_state = PS_STATE_SLEEP; + } + break; + } + } while (true); + + if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) + goto process_start; + + spin_lock_irqsave(&adapter->main_proc_lock, flags); + adapter->mwifiex_processing = false; + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); + +exit_main_proc: + if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) + mwifiex_shutdown_drv(adapter); + return ret; +} + +/* + * This function initializes the software. + * + * The main work includes allocating and initializing the adapter structure + * and initializing the private structures. + */ +static int +mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex) +{ + int i; + struct mwifiex_device device; + struct mwifiex_drv_mode *drv_mode_ptr; + + /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */ + drv_mode_ptr = NULL; + for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) { + if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) { + drv_mode_ptr = &mwifiex_drv_mode_tbl[i]; + break; + } + } + + if (!drv_mode_ptr) { + pr_err("invalid drv_mode=%d\n", drv_mode); + return -1; + } + + memset(&device, 0, sizeof(struct mwifiex_device)); + + for (i = 0; i < drv_mode_ptr->intf_num; i++) { + device.bss_attr[i].bss_type = + drv_mode_ptr->bss_attr[i].bss_type; + device.bss_attr[i].frame_type = + drv_mode_ptr->bss_attr[i].frame_type; + device.bss_attr[i].active = drv_mode_ptr->bss_attr[i].active; + device.bss_attr[i].bss_priority = + drv_mode_ptr->bss_attr[i].bss_priority; + device.bss_attr[i].bss_num = drv_mode_ptr->bss_attr[i].bss_num; + } + + if (mwifiex_register(card, if_ops, &device, pmwifiex)) + return -1; + + return 0; +} + +/* + * This function frees the adapter structure. + * + * Additionally, this closes the netlink socket, frees the timers + * and private structures. + */ +static void mwifiex_free_adapter(struct mwifiex_adapter *adapter) +{ + if (!adapter) { + pr_err("%s: adapter is NULL\n", __func__); + return; + } + + mwifiex_unregister(adapter); + pr_debug("info: %s: free adapter\n", __func__); +} + +/* + * This function initializes the hardware and firmware. + * + * The main initialization steps followed are - + * - Download the correct firmware to card + * - Allocate and initialize the adapter structure + * - Initialize the private structures + * - Issue the init commands to firmware + */ +static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) +{ + int ret = 0; + int err; + struct mwifiex_fw_image fw; + + memset(&fw, 0, sizeof(struct mwifiex_fw_image)); + + switch (adapter->revision_id) { + case SD8787_W0: + case SD8787_W1: + strcpy(fw_name, SD8787_W1_FW_NAME); + break; + case SD8787_A0: + case SD8787_A1: + strcpy(fw_name, SD8787_AX_FW_NAME); + break; + default: + break; + } + + err = request_firmware(&adapter->firmware, fw_name, adapter->dev); + if (err < 0) { + dev_err(adapter->dev, "request_firmware() returned" + " error code %#x\n", err); + ret = -1; + goto done; + } + fw.fw_buf = (u8 *) adapter->firmware->data; + fw.fw_len = adapter->firmware->size; + + ret = mwifiex_dnld_fw(adapter, &fw); + if (ret == -1) + goto done; + + dev_notice(adapter->dev, "WLAN FW is active\n"); + + adapter->init_wait_q_woken = false; + ret = mwifiex_init_fw(adapter); + if (ret == -1) { + goto done; + } else if (!ret) { + adapter->hw_status = MWIFIEX_HW_STATUS_READY; + goto done; + } + /* Wait for mwifiex_init to complete */ + wait_event_interruptible(adapter->init_wait_q, + adapter->init_wait_q_woken); + if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) { + ret = -1; + goto done; + } + ret = 0; + +done: + if (adapter->firmware) + release_firmware(adapter->firmware); + if (ret) + ret = -1; + return ret; +} + +/* + * This function fills a driver buffer. + * + * The function associates a given SKB with the provided driver buffer + * and also updates some of the SKB parameters, including IP header, + * priority and timestamp. + */ +static void +mwifiex_fill_buffer(struct sk_buff *skb) +{ + struct ethhdr *eth = NULL; + struct iphdr *iph; + struct timeval tv; + u8 tid = 0; + + eth = (struct ethhdr *) skb->data; + switch (eth->h_proto) { + case __constant_htons(ETH_P_IP): + iph = ip_hdr(skb); + tid = IPTOS_PREC(iph->tos); + pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", + eth->h_proto, tid, skb->priority); + break; + case __constant_htons(ETH_P_ARP): + pr_debug("data: ARP packet: %04x\n", eth->h_proto); + default: + break; + } +/* Offset for TOS field in the IP header */ +#define IPTOS_OFFSET 5 + tid = (tid >> IPTOS_OFFSET); + skb->priority = tid; + /* Record the current time the packet was queued; used to + determine the amount of time the packet was queued in + the driver before it was sent to the firmware. + The delay is then sent along with the packet to the + firmware for aggregate delay calculation for stats and + MSDU lifetime expiry. + */ + do_gettimeofday(&tv); + skb->tstamp = timeval_to_ktime(tv); + return; +} + +/* + * CFG802.11 network device handler for open. + * + * Starts the data queue. + */ +static int +mwifiex_open(struct net_device *dev) +{ + netif_start_queue(dev); + return 0; +} + +/* + * CFG802.11 network device handler for close. + */ +static int +mwifiex_close(struct net_device *dev) +{ + return 0; +} + +/* + * CFG802.11 network device handler for data transmission. + */ +static int +mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + struct sk_buff *new_skb = NULL; + struct mwifiex_txinfo *tx_info; + + dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n", + jiffies, priv->bss_index); + + if (priv->adapter->surprise_removed) { + kfree(skb); + priv->stats.tx_dropped++; + return 0; + } + if (!skb->len || (skb->len > ETH_FRAME_LEN)) { + dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len); + kfree(skb); + priv->stats.tx_dropped++; + return 0; + } + if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { + dev_dbg(priv->adapter->dev, + "data: Tx: insufficient skb headroom %d\n", + skb_headroom(skb)); + /* Insufficient skb headroom - allocate a new skb */ + new_skb = + skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); + if (unlikely(!new_skb)) { + dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n"); + kfree(skb); + priv->stats.tx_dropped++; + return 0; + } + kfree_skb(skb); + skb = new_skb; + dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n", + skb_headroom(skb)); + } + + tx_info = MWIFIEX_SKB_TXCB(skb); + tx_info->bss_index = priv->bss_index; + mwifiex_fill_buffer(skb); + + mwifiex_wmm_add_buf_txqueue(priv->adapter, skb); + atomic_inc(&priv->adapter->tx_pending); + + if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { + netif_stop_queue(priv->netdev); + dev->trans_start = jiffies; + } + + queue_work(priv->adapter->workqueue, &priv->adapter->main_work); + + return 0; +} + +/* + * CFG802.11 network device handler for setting MAC address. + */ +static int +mwifiex_set_mac_address(struct net_device *dev, void *addr) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + struct sockaddr *hw_addr = (struct sockaddr *) addr; + + memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); + + if (mwifiex_request_set_mac_address(priv)) { + dev_err(priv->adapter->dev, "set MAC address failed\n"); + return -EFAULT; + } + memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); + + return 0; +} + +/* + * CFG802.11 network device handler for setting multicast list. + */ +static void mwifiex_set_multicast_list(struct net_device *dev) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + mwifiex_request_set_multicast_list(priv, dev); +} + +/* + * CFG802.11 network device handler for transmission timeout. + */ +static void +mwifiex_tx_timeout(struct net_device *dev) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + + dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n", + jiffies, priv->bss_index); + dev->trans_start = jiffies; + priv->num_tx_timeout++; +} + +/* + * CFG802.11 network device handler for statistics retrieval. + */ +static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + + return &priv->stats; +} + +/* Network device handlers */ +static const struct net_device_ops mwifiex_netdev_ops = { + .ndo_open = mwifiex_open, + .ndo_stop = mwifiex_close, + .ndo_start_xmit = mwifiex_hard_start_xmit, + .ndo_set_mac_address = mwifiex_set_mac_address, + .ndo_tx_timeout = mwifiex_tx_timeout, + .ndo_get_stats = mwifiex_get_stats, + .ndo_set_multicast_list = mwifiex_set_multicast_list, +}; + +/* + * This function initializes the private structure parameters. + * + * The following wait queues are initialized - + * - IOCTL wait queue + * - Command wait queue + * - Statistics wait queue + * + * ...and the following default parameters are set - + * - Current key index : Set to 0 + * - Rate index : Set to auto + * - Media connected : Set to disconnected + * - Adhoc link sensed : Set to false + * - Nick name : Set to null + * - Number of Tx timeout : Set to 0 + * - Device address : Set to current address + * + * In addition, the CFG80211 work queue is also created. + */ +static void +mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) +{ + dev->netdev_ops = &mwifiex_netdev_ops; + /* Initialize private structure */ + init_waitqueue_head(&priv->ioctl_wait_q); + init_waitqueue_head(&priv->cmd_wait_q); + init_waitqueue_head(&priv->w_stats_wait_q); + priv->current_key_index = 0; + priv->media_connected = false; + memset(&priv->nick_name, 0, sizeof(priv->nick_name)); + priv->num_tx_timeout = 0; + priv->workqueue = create_singlethread_workqueue("cfg80211_wq"); + INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results); + memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); +} + +/* + * This function adds a new logical interface. + * + * It allocates, initializes and registers the interface by performing + * the following opearations - + * - Allocate a new net device structure + * - Assign device name + * - Register the new device with CFG80211 subsystem + * - Initialize semaphore and private structure + * - Register the new device with kernel + * - Create the complete debug FS structure if configured + */ +static struct mwifiex_private *mwifiex_add_interface( + struct mwifiex_adapter *adapter, + u8 bss_index, u8 bss_type) +{ + struct net_device *dev = NULL; + struct mwifiex_private *priv = NULL; + void *mdev_priv = NULL; + + dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d", + ether_setup, 1); + if (!dev) { + dev_err(adapter->dev, "no memory available for netdevice\n"); + goto error; + } + if (dev_alloc_name(dev, dev->name)) { + dev_err(adapter->dev, "unable to alloc name for netdevice\n"); + goto error; + } + + if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr, + adapter->priv[bss_index]) != 0) { + dev_err(adapter->dev, "cannot register netdevice with cfg80211\n"); + goto error; + } + /* Save the priv pointer in netdev */ + priv = adapter->priv[bss_index]; + mdev_priv = netdev_priv(dev); + *((unsigned long *) mdev_priv) = (unsigned long) priv; + + priv->netdev = dev; + + sema_init(&priv->async_sem, 1); + priv->scan_pending_on_block = false; + + mwifiex_init_priv_params(priv, dev); + + SET_NETDEV_DEV(dev, adapter->dev); + + /* Register network device */ + if (register_netdev(dev)) { + dev_err(adapter->dev, "cannot register virtual network device\n"); + goto error; + } + + dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); +#ifdef CONFIG_DEBUG_FS + mwifiex_dev_debugfs_init(priv); +#endif + return priv; +error: + if (dev) + free_netdev(dev); + return NULL; +} + +/* + * This function removes a logical interface. + * + * It deregisters, resets and frees the interface by performing + * the following operations - + * - Disconnect the device if connected, send wireless event to + * notify applications. + * - Remove the debug FS structure if configured + * - Unregister the device from kernel + * - Free the net device structure + * - Cancel all works and destroy work queue + * - Unregister and free the wireless device from CFG80211 subsystem + */ +static void +mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) +{ + struct net_device *dev = NULL; + struct mwifiex_private *priv = adapter->priv[bss_index]; + + if (!priv) + return; + dev = priv->netdev; + + if (priv->media_connected) + priv->media_connected = false; + +#ifdef CONFIG_DEBUG_FS + mwifiex_dev_debugfs_remove(priv); +#endif + /* Last reference is our one */ + dev_dbg(adapter->dev, "info: %s: refcnt = %d\n", + dev->name, netdev_refcnt_read(dev)); + + if (dev->reg_state == NETREG_REGISTERED) + unregister_netdev(dev); + + /* Clear the priv in adapter */ + priv->netdev = NULL; + if (dev) + free_netdev(dev); + + cancel_work_sync(&priv->cfg_workqueue); + flush_workqueue(priv->workqueue); + destroy_workqueue(priv->workqueue); + wiphy_unregister(priv->wdev->wiphy); + wiphy_free(priv->wdev->wiphy); + kfree(priv->wdev); + + return; +} + +/* + * Sends IOCTL request to shutdown firmware. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option) +{ + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + + /* Allocate an IOCTL request buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait, + MWIFIEX_FUNC_SHUTDOWN); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + + kfree(wait); + return status; +} +EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw); + +/* + * This function check if command is pending. + */ +int is_command_pending(struct mwifiex_adapter *adapter) +{ + unsigned long flags; + int is_cmd_pend_q_empty; + + spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); + is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q); + spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); + + return !is_cmd_pend_q_empty; +} + +/* + * This function returns the correct private structure pointer based + * upon the BSS number. + */ +struct mwifiex_private * +mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index) +{ + if (!adapter || (bss_index >= adapter->priv_num)) + return NULL; + return adapter->priv[bss_index]; +} + +/* + * This is the main work queue function. + * + * It handles the main process, which in turn handles the complete + * driver operations. + */ +static void mwifiex_main_work_queue(struct work_struct *work) +{ + struct mwifiex_adapter *adapter = + container_of(work, struct mwifiex_adapter, main_work); + + if (adapter->surprise_removed) + return; + mwifiex_main_process(adapter); +} + +/* + * This function cancels all works in the queue and destroys + * the main workqueue. + */ +static void +mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter) +{ + flush_workqueue(adapter->workqueue); + destroy_workqueue(adapter->workqueue); + adapter->workqueue = NULL; +} + +/* + * This function adds the card. + * + * This function follows the following major steps to set up the device - + * - Initialize software. This includes probing the card, registering + * the interface operations table, and allocating/initializing the + * adapter structure + * - Set up the netlink socket + * - Create and start the main work queue + * - Register the device + * - Initialize firmware and hardware + * - Add logical interfaces + */ +int +mwifiex_add_card(void *card, struct semaphore *sem, + struct mwifiex_if_ops *if_ops) +{ + int status = 0; + int i; + struct mwifiex_adapter *adapter = NULL; + struct mwifiex_drv_mode *drv_mode_info = &mwifiex_drv_mode_tbl[0]; + + if (down_interruptible(sem)) + goto exit_sem_err; + + if (mwifiex_init_sw(card, if_ops, (void **) &adapter)) { + pr_err("%s: software init failed\n", __func__); + goto err_init_sw; + } + + adapter->drv_mode = drv_mode_info; + + adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; + /* PnP and power profile */ + adapter->surprise_removed = false; + init_waitqueue_head(&adapter->init_wait_q); + adapter->is_suspended = false; + adapter->hs_activated = false; + init_waitqueue_head(&adapter->hs_activate_wait_q); + + /* Create workqueue */ + adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); + if (!adapter->workqueue) + goto err_kmalloc; + + INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); + + /* Register the device. Fill up the private data structure with relevant + information from the card and request for the required IRQ. */ + if (adapter->if_ops.register_dev(adapter)) { + pr_err("%s: failed to register mwifiex device\n", __func__); + goto err_registerdev; + } + + /* Init FW and HW */ + if (mwifiex_init_hw_fw(adapter)) { + pr_err("%s: firmware init failed\n", __func__); + goto err_init_fw; + } + /* Add interfaces */ + for (i = 0; i < drv_mode_info->intf_num; i++) { + if (!mwifiex_add_interface(adapter, i, + adapter->drv_mode->bss_attr[i].bss_type)) { + status = -1; + break; + } + } + if (status) + goto err_add_intf; + + up(sem); + + return 0; + +err_add_intf: + for (i = 0; i < adapter->priv_num; i++) + mwifiex_remove_interface(adapter, i); +err_init_fw: + /* Unregister device */ + pr_debug("info: %s: unregister device\n", __func__); + adapter->if_ops.unregister_dev(adapter); +err_registerdev: + adapter->surprise_removed = true; + mwifiex_terminate_workqueue(adapter); +err_kmalloc: + if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) || + (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) { + pr_debug("info: %s: shutdown mwifiex\n", __func__); + adapter->init_wait_q_woken = false; + status = mwifiex_shutdown_drv(adapter); + if (status == -EINPROGRESS) + wait_event_interruptible(adapter->init_wait_q, + adapter->init_wait_q_woken); + } + + mwifiex_free_adapter(adapter); + +err_init_sw: + up(sem); + +exit_sem_err: + return -1; +} +EXPORT_SYMBOL_GPL(mwifiex_add_card); + +/* + * This function removes the card. + * + * This function follows the following major steps to remove the device - + * - Stop data traffic + * - Shutdown firmware + * - Remove the logical interfaces + * - Terminate the work queue + * - Unregister the device + * - Free the adapter structure + */ +int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) +{ + struct mwifiex_private *priv = NULL; + int status; + int i; + + if (down_interruptible(sem)) + goto exit_sem_err; + + if (!adapter) + goto exit_remove; + + adapter->surprise_removed = true; + + /* Stop data */ + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (priv) { + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); + if (netif_carrier_ok(priv->netdev)) + netif_carrier_off(priv->netdev); + } + } + + dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n"); + adapter->init_wait_q_woken = false; + status = mwifiex_shutdown_drv(adapter); + if (status == -EINPROGRESS) + wait_event_interruptible(adapter->init_wait_q, + adapter->init_wait_q_woken); + dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); + if (atomic_read(&adapter->rx_pending) || + atomic_read(&adapter->tx_pending) || + atomic_read(&adapter->ioctl_pending)) { + dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " + "ioctl_pending=%d\n", + atomic_read(&adapter->rx_pending), + atomic_read(&adapter->tx_pending), + atomic_read(&adapter->ioctl_pending)); + } + + /* Remove interface */ + for (i = 0; i < adapter->priv_num; i++) + mwifiex_remove_interface(adapter, i); + + mwifiex_terminate_workqueue(adapter); + + /* Unregister device */ + dev_dbg(adapter->dev, "info: unregister device\n"); + adapter->if_ops.unregister_dev(adapter); + /* Free adapter structure */ + dev_dbg(adapter->dev, "info: free adapter\n"); + mwifiex_free_adapter(adapter); + +exit_remove: + up(sem); +exit_sem_err: + return 0; +} +EXPORT_SYMBOL_GPL(mwifiex_remove_card); + +/* + * This function initializes the module. + * + * The debug FS is also initialized if configured. + */ +static int +mwifiex_init_module(void) +{ +#ifdef CONFIG_DEBUG_FS + mwifiex_debugfs_init(); +#endif + return 0; +} + +/* + * This function cleans up the module. + * + * The debug FS is removed if available. + */ +static void +mwifiex_cleanup_module(void) +{ +#ifdef CONFIG_DEBUG_FS + mwifiex_debugfs_remove(); +#endif +} + +module_init(mwifiex_init_module); +module_exit(mwifiex_cleanup_module); + +MODULE_AUTHOR("Marvell International Ltd."); +MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h new file mode 100644 index 000000000000..2b0ad8e3d6e2 --- /dev/null +++ b/drivers/net/wireless/mwifiex/main.h @@ -0,0 +1,1081 @@ +/* + * Marvell Wireless LAN device driver: major data structures and prototypes + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_MAIN_H_ +#define _MWIFIEX_MAIN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" + +extern const char driver_version[]; +extern struct mwifiex_adapter *g_adapter; + +enum { + MWIFIEX_NO_WAIT, + MWIFIEX_IOCTL_WAIT, + MWIFIEX_CMD_WAIT, + MWIFIEX_PROC_WAIT, + MWIFIEX_WSTATS_WAIT +}; + +#define DRV_MODE_STA 0x1 +#define DRV_MODE_UAP 0x2 +#define DRV_MODE_UAP_STA 0x3 + +#define SD8787_W0 0x30 +#define SD8787_W1 0x31 +#define SD8787_A0 0x40 +#define SD8787_A1 0x41 + +#define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" +#define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin" +#define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin" + +struct mwifiex_drv_mode { + u16 drv_mode; + u16 intf_num; + struct mwifiex_bss_attr *bss_attr; +}; + + +#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ) + +#define MWIFIEX_TIMER_10S 10000 +#define MWIFIEX_TIMER_1S 1000 + +#define NL_MAX_PAYLOAD 1024 +#define NL_MULTICAST_GROUP 1 + +#define MAX_TX_PENDING 60 + +#define HEADER_ALIGNMENT 8 + +#define MWIFIEX_UPLD_SIZE (2312) + +#define MAX_EVENT_SIZE 1024 + +#define ARP_FILTER_MAX_BUF_SIZE 68 + +#define MWIFIEX_KEY_BUFFER_SIZE 16 +#define MWIFIEX_DEFAULT_LISTEN_INTERVAL 10 +#define MWIFIEX_MAX_REGION_CODE 7 + +#define DEFAULT_BCN_AVG_FACTOR 8 +#define DEFAULT_DATA_AVG_FACTOR 8 + +#define FIRST_VALID_CHANNEL 0xff +#define DEFAULT_AD_HOC_CHANNEL 6 +#define DEFAULT_AD_HOC_CHANNEL_A 36 + +#define DEFAULT_BCN_MISS_TIMEOUT 5 + +#define MAX_SCAN_BEACON_BUFFER 8000 + +#define SCAN_BEACON_ENTRY_PAD 6 + +#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 200 +#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 200 +#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 110 + +#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) + +#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) + +#define RSN_GTK_OUI_OFFSET 2 + +#define MWIFIEX_OUI_NOT_PRESENT 0 +#define MWIFIEX_OUI_PRESENT 1 + +#define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \ + adapter->event_received || \ + adapter->data_received) + +#define MWIFIEX_TYPE_CMD 1 +#define MWIFIEX_TYPE_DATA 0 +#define MWIFIEX_TYPE_EVENT 3 + +#define DBG_CMD_NUM 5 + +#define MAX_BITMAP_RATES_SIZE 10 + +#define MAX_CHANNEL_BAND_BG 14 + +#define MAX_FREQUENCY_BAND_BG 2484 + +struct mwifiex_dbg { + u32 num_cmd_host_to_card_failure; + u32 num_cmd_sleep_cfm_host_to_card_failure; + u32 num_tx_host_to_card_failure; + u32 num_event_deauth; + u32 num_event_disassoc; + u32 num_event_link_lost; + u32 num_cmd_deauth; + u32 num_cmd_assoc_success; + u32 num_cmd_assoc_failure; + u32 num_tx_timeout; + u32 num_cmd_timeout; + u16 timeout_cmd_id; + u16 timeout_cmd_act; + u16 last_cmd_id[DBG_CMD_NUM]; + u16 last_cmd_act[DBG_CMD_NUM]; + u16 last_cmd_index; + u16 last_cmd_resp_id[DBG_CMD_NUM]; + u16 last_cmd_resp_index; + u16 last_event[DBG_CMD_NUM]; + u16 last_event_index; +}; + +enum MWIFIEX_HARDWARE_STATUS { + MWIFIEX_HW_STATUS_READY, + MWIFIEX_HW_STATUS_INITIALIZING, + MWIFIEX_HW_STATUS_FW_READY, + MWIFIEX_HW_STATUS_INIT_DONE, + MWIFIEX_HW_STATUS_RESET, + MWIFIEX_HW_STATUS_CLOSING, + MWIFIEX_HW_STATUS_NOT_READY +}; + +enum MWIFIEX_802_11_POWER_MODE { + MWIFIEX_802_11_POWER_MODE_CAM, + MWIFIEX_802_11_POWER_MODE_PSP +}; + +struct mwifiex_tx_param { + u32 next_pkt_len; +}; + +enum MWIFIEX_PS_STATE { + PS_STATE_AWAKE, + PS_STATE_PRE_SLEEP, + PS_STATE_SLEEP_CFM, + PS_STATE_SLEEP +}; + +struct mwifiex_add_ba_param { + u32 tx_win_size; + u32 rx_win_size; + u32 timeout; +}; + +struct mwifiex_tx_aggr { + u8 ampdu_user; + u8 ampdu_ap; + u8 amsdu; +}; + +struct mwifiex_ra_list_tbl { + struct list_head list; + struct sk_buff_head skb_head; + u8 ra[ETH_ALEN]; + u32 total_pkts_size; + u32 is_11n_enabled; +}; + +struct mwifiex_tid_tbl { + struct list_head ra_list; + /* spin lock for tid table */ + spinlock_t tid_tbl_lock; + struct mwifiex_ra_list_tbl *ra_list_curr; +}; + +#define WMM_HIGHEST_PRIORITY 7 +#define HIGH_PRIO_TID 7 +#define LOW_PRIO_TID 0 + +struct mwifiex_wmm_desc { + struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; + u32 packets_out[MAX_NUM_TID]; + /* spin lock to protect ra_list */ + spinlock_t ra_list_spinlock; + struct mwifiex_wmm_ac_status ac_status[IEEE80211_MAX_QUEUES]; + enum mwifiex_wmm_ac_e ac_down_graded_vals[IEEE80211_MAX_QUEUES]; + u32 drv_pkt_delay_max; + u8 queue_priority[IEEE80211_MAX_QUEUES]; + u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ + +}; + +struct mwifiex_802_11_security { + u8 wpa_enabled; + u8 wpa2_enabled; + u8 wapi_enabled; + u8 wapi_key_on; + enum MWIFIEX_802_11_WEP_STATUS wep_status; + u32 authentication_mode; + u32 encryption_mode; +}; + +struct ieee_types_header { + u8 element_id; + u8 len; +} __packed; + +struct ieee_obss_scan_param { + u16 obss_scan_passive_dwell; + u16 obss_scan_active_dwell; + u16 bss_chan_width_trigger_scan_int; + u16 obss_scan_passive_total; + u16 obss_scan_active_total; + u16 bss_width_chan_trans_delay; + u16 obss_scan_active_threshold; +} __packed; + +struct ieee_types_obss_scan_param { + struct ieee_types_header ieee_hdr; + struct ieee_obss_scan_param obss_scan; +} __packed; + +#define MWIFIEX_SUPPORTED_RATES 14 + +#define MWIFIEX_SUPPORTED_RATES_EXT 32 + +#define IEEE_MAX_IE_SIZE 256 + +struct ieee_types_vendor_specific { + struct ieee_types_vendor_header vend_hdr; + u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)]; +} __packed; + +struct ieee_types_generic { + struct ieee_types_header ieee_hdr; + u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)]; +} __packed; + +struct mwifiex_bssdescriptor { + u8 mac_address[ETH_ALEN]; + struct mwifiex_802_11_ssid ssid; + u32 privacy; + s32 rssi; + u32 channel; + u32 freq; + u16 beacon_period; + u8 erp_flags; + u32 bss_mode; + u8 supported_rates[MWIFIEX_SUPPORTED_RATES]; + u8 data_rates[MWIFIEX_SUPPORTED_RATES]; + /* Network band. + * BAND_B(0x01): 'b' band + * BAND_G(0x02): 'g' band + * BAND_A(0X04): 'a' band + */ + u16 bss_band; + long long network_tsf; + u8 time_stamp[8]; + union ieee_types_phy_param_set phy_param_set; + union ieee_types_ss_param_set ss_param_set; + u16 cap_info_bitmap; + struct ieee_types_wmm_parameter wmm_ie; + u8 disable_11n; + struct ieee80211_ht_cap *bcn_ht_cap; + u16 ht_cap_offset; + struct ieee80211_ht_info *bcn_ht_info; + u16 ht_info_offset; + u8 *bcn_bss_co_2040; + u16 bss_co_2040_offset; + u8 *bcn_ext_cap; + u16 ext_cap_offset; + struct ieee_types_obss_scan_param *bcn_obss_scan; + u16 overlap_bss_offset; + struct ieee_types_vendor_specific *bcn_wpa_ie; + u16 wpa_offset; + struct ieee_types_generic *bcn_rsn_ie; + u16 rsn_offset; + struct ieee_types_generic *bcn_wapi_ie; + u16 wapi_offset; + u8 *beacon_buf; + u32 beacon_buf_size; + u32 beacon_buf_size_max; + +}; + +struct mwifiex_current_bss_params { + struct mwifiex_bssdescriptor bss_descriptor; + u8 wmm_enabled; + u8 wmm_uapsd_enabled; + u8 band; + u32 num_of_rates; + u8 data_rates[MWIFIEX_SUPPORTED_RATES]; +}; + +struct mwifiex_sleep_params { + u16 sp_error; + u16 sp_offset; + u16 sp_stable_time; + u8 sp_cal_control; + u8 sp_ext_sleep_clk; + u16 sp_reserved; +}; + +struct mwifiex_sleep_period { + u16 period; + u16 reserved; +}; + +struct mwifiex_wep_key { + u32 length; + u32 key_index; + u32 key_length; + u8 key_material[MWIFIEX_KEY_BUFFER_SIZE]; +}; + +#define MAX_REGION_CHANNEL_NUM 2 + +struct mwifiex_chan_freq_power { + u16 channel; + u32 freq; + u16 max_tx_power; + u8 unsupported; +}; + +enum state_11d_t { + DISABLE_11D = 0, + ENABLE_11D = 1, +}; + +#define MWIFIEX_MAX_TRIPLET_802_11D 83 + +struct mwifiex_802_11d_domain_reg { + u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; + u8 no_of_triplet; + struct ieee80211_country_ie_triplet + triplet[MWIFIEX_MAX_TRIPLET_802_11D]; +}; + +struct mwifiex_vendor_spec_cfg_ie { + u16 mask; + u16 flag; + u8 ie[MWIFIEX_MAX_VSIE_LEN]; +}; + +struct wps { + u8 session_enable; +}; + +struct mwifiex_adapter; +struct mwifiex_private; + +struct mwifiex_private { + struct mwifiex_adapter *adapter; + u8 bss_index; + u8 bss_type; + u8 bss_role; + u8 bss_priority; + u8 bss_num; + u8 frame_type; + u8 curr_addr[ETH_ALEN]; + u8 media_connected; + u32 num_tx_timeout; + struct net_device *netdev; + struct net_device_stats stats; + u16 curr_pkt_filter; + u32 bss_mode; + u32 pkt_tx_ctrl; + u16 tx_power_level; + u8 max_tx_power_level; + u8 min_tx_power_level; + u8 tx_rate; + u8 tx_htinfo; + u8 rxpd_htinfo; + u8 rxpd_rate; + u16 rate_bitmap; + u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; + u32 data_rate; + u8 is_data_rate_auto; + u16 bcn_avg_factor; + u16 data_avg_factor; + s16 data_rssi_last; + s16 data_nf_last; + s16 data_rssi_avg; + s16 data_nf_avg; + s16 bcn_rssi_last; + s16 bcn_nf_last; + s16 bcn_rssi_avg; + s16 bcn_nf_avg; + struct mwifiex_bssdescriptor *attempted_bss_desc; + struct mwifiex_802_11_ssid prev_ssid; + u8 prev_bssid[ETH_ALEN]; + struct mwifiex_current_bss_params curr_bss_params; + u16 beacon_period; + u16 listen_interval; + u16 atim_window; + u8 adhoc_channel; + u8 adhoc_is_link_sensed; + u8 adhoc_state; + struct mwifiex_802_11_security sec_info; + struct mwifiex_wep_key wep_key[NUM_WEP_KEYS]; + u16 wep_key_curr_index; + u8 wpa_ie[256]; + u8 wpa_ie_len; + u8 wpa_is_gtk_set; + struct host_cmd_ds_802_11_key_material aes_key; + u8 wapi_ie[256]; + u8 wapi_ie_len; + u8 wmm_required; + u8 wmm_enabled; + u8 wmm_qosinfo; + struct mwifiex_wmm_desc wmm; + struct list_head tx_ba_stream_tbl_ptr; + /* spin lock for tx_ba_stream_tbl_ptr queue */ + spinlock_t tx_ba_stream_tbl_lock; + struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID]; + struct mwifiex_add_ba_param add_ba_param; + u16 rx_seq[MAX_NUM_TID]; + struct list_head rx_reorder_tbl_ptr; + /* spin lock for rx_reorder_tbl_ptr queue */ + spinlock_t rx_reorder_tbl_lock; + /* spin lock for Rx packets */ + spinlock_t rx_pkt_lock; + +#define MWIFIEX_ASSOC_RSP_BUF_SIZE 500 + u8 assoc_rsp_buf[MWIFIEX_ASSOC_RSP_BUF_SIZE]; + u32 assoc_rsp_size; + +#define MWIFIEX_GENIE_BUF_SIZE 256 + u8 gen_ie_buf[MWIFIEX_GENIE_BUF_SIZE]; + u8 gen_ie_buf_len; + + struct mwifiex_vendor_spec_cfg_ie vs_ie[MWIFIEX_MAX_VSIE_NUM]; + +#define MWIFIEX_ASSOC_TLV_BUF_SIZE 256 + u8 assoc_tlv_buf[MWIFIEX_ASSOC_TLV_BUF_SIZE]; + u8 assoc_tlv_buf_len; + + u8 *curr_bcn_buf; + u32 curr_bcn_size; + /* spin lock for beacon buffer */ + spinlock_t curr_bcn_buf_lock; + u16 ioctl_wait_q_woken; + wait_queue_head_t ioctl_wait_q; + u16 cmd_wait_q_woken; + wait_queue_head_t cmd_wait_q; + struct wireless_dev *wdev; + struct mwifiex_chan_freq_power cfp; + char version_str[128]; +#ifdef CONFIG_DEBUG_FS + struct dentry *dfs_dev_dir; +#endif + u8 nick_name[16]; + struct iw_statistics w_stats; + u16 w_stats_wait_q_woken; + wait_queue_head_t w_stats_wait_q; + u16 current_key_index; + struct semaphore async_sem; + u8 scan_pending_on_block; + u8 report_scan_result; + struct cfg80211_scan_request *scan_request; + int scan_result_status; + bool assoc_request; + u16 assoc_result; + bool ibss_join_request; + u16 ibss_join_result; + bool disconnect; + u8 cfg_bssid[6]; + struct workqueue_struct *workqueue; + struct work_struct cfg_workqueue; + u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; + struct wps wps; + u8 scan_block; +}; + +enum mwifiex_ba_status { + BA_STREAM_NOT_SETUP = 0, + BA_STREAM_SETUP_INPROGRESS, + BA_STREAM_SETUP_COMPLETE +}; + +struct mwifiex_tx_ba_stream_tbl { + struct list_head list; + int tid; + u8 ra[ETH_ALEN]; + enum mwifiex_ba_status ba_status; +}; + +struct mwifiex_rx_reorder_tbl; + +struct reorder_tmr_cnxt { + struct timer_list timer; + struct mwifiex_rx_reorder_tbl *ptr; + struct mwifiex_private *priv; +}; + +struct mwifiex_rx_reorder_tbl { + struct list_head list; + int tid; + u8 ta[ETH_ALEN]; + int start_win; + int win_size; + void **rx_reorder_ptr; + struct reorder_tmr_cnxt timer_context; +}; + +struct mwifiex_bss_prio_node { + struct list_head list; + struct mwifiex_private *priv; +}; + +struct mwifiex_bss_prio_tbl { + struct list_head bss_prio_head; + /* spin lock for bss priority */ + spinlock_t bss_prio_lock; + struct mwifiex_bss_prio_node *bss_prio_cur; +}; + +struct cmd_ctrl_node { + struct list_head list; + struct mwifiex_private *priv; + u32 cmd_oid; + u32 cmd_flag; + struct sk_buff *cmd_skb; + struct sk_buff *resp_skb; + void *data_buf; + void *wq_buf; + struct sk_buff *skb; +}; + +struct mwifiex_if_ops { + int (*init_if) (struct mwifiex_adapter *); + void (*cleanup_if) (struct mwifiex_adapter *); + int (*check_fw_status) (struct mwifiex_adapter *, u32, int *); + int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); + int (*register_dev) (struct mwifiex_adapter *); + void (*unregister_dev) (struct mwifiex_adapter *); + int (*enable_int) (struct mwifiex_adapter *); + int (*process_int_status) (struct mwifiex_adapter *); + int (*host_to_card) (struct mwifiex_adapter *, u8, + u8 *payload, u32 pkt_len, + struct mwifiex_tx_param *); + int (*wakeup) (struct mwifiex_adapter *); + int (*wakeup_complete) (struct mwifiex_adapter *); + + void (*update_mp_end_port) (struct mwifiex_adapter *, u16); + void (*cleanup_mpa_buf) (struct mwifiex_adapter *); +}; + +struct mwifiex_adapter { + struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM]; + u8 priv_num; + struct mwifiex_drv_mode *drv_mode; + const struct firmware *firmware; + struct device *dev; + bool surprise_removed; + u32 fw_release_number; + u32 revision_id; + u16 init_wait_q_woken; + wait_queue_head_t init_wait_q; + void *card; + struct mwifiex_if_ops if_ops; + atomic_t rx_pending; + atomic_t tx_pending; + atomic_t ioctl_pending; + struct workqueue_struct *workqueue; + struct work_struct main_work; + struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; + /* spin lock for init/shutdown */ + spinlock_t mwifiex_lock; + /* spin lock for main process */ + spinlock_t main_proc_lock; + u32 mwifiex_processing; + u16 max_tx_buf_size; + u16 tx_buf_size; + u16 curr_tx_buf_size; + u32 ioport; + enum MWIFIEX_HARDWARE_STATUS hw_status; + u16 radio_on; + u16 number_of_antenna; + u32 fw_cap_info; + /* spin lock for interrupt handling */ + spinlock_t int_lock; + u8 int_status; + u32 event_cause; + struct sk_buff *event_skb; + u8 upld_buf[MWIFIEX_UPLD_SIZE]; + u8 data_sent; + u8 cmd_sent; + u8 cmd_resp_received; + u8 event_received; + u8 data_received; + u16 seq_num; + struct cmd_ctrl_node *cmd_pool; + struct cmd_ctrl_node *curr_cmd; + /* spin lock for command */ + spinlock_t mwifiex_cmd_lock; + u32 num_cmd_timeout; + u16 last_init_cmd; + struct timer_list cmd_timer; + struct list_head cmd_free_q; + /* spin lock for cmd_free_q */ + spinlock_t cmd_free_q_lock; + struct list_head cmd_pending_q; + /* spin lock for cmd_pending_q */ + spinlock_t cmd_pending_q_lock; + struct list_head scan_pending_q; + /* spin lock for scan_pending_q */ + spinlock_t scan_pending_q_lock; + u32 scan_processing; + u16 region_code; + struct mwifiex_802_11d_domain_reg domain_reg; + struct mwifiex_bssdescriptor *scan_table; + u32 num_in_scan_table; + u16 scan_probes; + u32 scan_mode; + u16 specific_scan_time; + u16 active_scan_time; + u16 passive_scan_time; + u8 bcn_buf[MAX_SCAN_BEACON_BUFFER]; + u8 *bcn_buf_end; + u8 fw_bands; + u8 adhoc_start_band; + u8 config_bands; + struct mwifiex_chan_scan_param_set *scan_channels; + u8 tx_lock_flag; + struct mwifiex_sleep_params sleep_params; + struct mwifiex_sleep_period sleep_period; + u16 ps_mode; + u32 ps_state; + u8 need_to_wakeup; + u16 multiple_dtim; + u16 local_listen_interval; + u16 null_pkt_interval; + struct sk_buff *sleep_cfm; + u16 bcn_miss_time_out; + u16 adhoc_awake_period; + u8 is_deep_sleep; + u8 delay_null_pkt; + u16 delay_to_ps; + u16 enhanced_ps_mode; + u8 pm_wakeup_card_req; + u16 gen_null_pkt; + u16 pps_uapsd_mode; + u32 pm_wakeup_fw_try; + u8 is_hs_configured; + struct mwifiex_hs_config_param hs_cfg; + u8 hs_activated; + u16 hs_activate_wait_q_woken; + wait_queue_head_t hs_activate_wait_q; + bool is_suspended; + u8 event_body[MAX_EVENT_SIZE]; + u32 hw_dot_11n_dev_cap; + u8 hw_dev_mcs_support; + u32 usr_dot_11n_dev_cap; + u8 usr_dev_mcs_support; + u8 adhoc_11n_enabled; + u8 chan_offset; + struct mwifiex_dbg dbg; + u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; + u32 arp_filter_size; +}; + +int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); +void mwifiex_free_lock_list(struct mwifiex_adapter *adapter); + +int mwifiex_init_fw(struct mwifiex_adapter *adapter); + +int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter); + +int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter); + +int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter); + +int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *); + +int mwifiex_recv_complete(struct mwifiex_adapter *, + struct sk_buff *skb, + int status); + +int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); + +int mwifiex_process_event(struct mwifiex_adapter *adapter); + +int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *ioctl_wq, + int status); + +int mwifiex_prepare_cmd(struct mwifiex_private *priv, + uint16_t cmd_no, + u16 cmd_action, + u32 cmd_oid, + void *wait_queue, void *data_buf); + +void mwifiex_cmd_timeout_func(unsigned long function_context); + +int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait_queue, + u32 func_init_shutdown); +int mwifiex_get_debug_info(struct mwifiex_private *, + struct mwifiex_debug_info *); + +int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); +int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); +void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); +void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *ioctl_wq); + +void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_node); + +void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_node, + u32 addtail); + +int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter); +int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter); +int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb); +int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, + struct mwifiex_tx_param *tx_param); +int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); +int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, + struct sk_buff *skb, int status); +int mwifiex_recv_packet_complete(struct mwifiex_adapter *, + struct sk_buff *skb, int status); +void mwifiex_clean_txrx(struct mwifiex_private *priv); +u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); +void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); +void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *, + u32); +int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, uint16_t ps_bitmap, + void *data_buf); +int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf); +void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); +void mwifiex_hs_activated_event(struct mwifiex_private *priv, + u8 activated); +int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp); +int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb); +int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, + void *data_buf, void *cmd_buf); +int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, + void *cmd_buf, void *ioctl); +int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, + struct sk_buff *skb); +int mwifiex_process_sta_event(struct mwifiex_private *); +void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); +int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); +int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue, + u16 action, + const struct mwifiex_user_scan_cfg + *user_scan_in, struct mwifiex_scan_resp *); +int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf); +void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, + struct cmd_ctrl_node *cmd_node); +int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *wait_queue); +s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, + struct mwifiex_802_11_ssid *ssid, u8 *bssid, + u32 mode); +s32 mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid, + u32 mode); +int mwifiex_find_best_network(struct mwifiex_private *priv, + struct mwifiex_ssid_bssid *req_ssid_bssid); +s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, + struct mwifiex_802_11_ssid *ssid2); +int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue, + struct mwifiex_bssdescriptor *bss_desc); +int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, + struct host_cmd_ds_command + *cmd, void *data_buf); +int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *wait_queue); +void mwifiex_reset_connect_state(struct mwifiex_private *priv); +void mwifiex_2040_coex_event(struct mwifiex_private *priv); +u8 mwifiex_band_to_radio_type(u8 band); +int mwifiex_deauthenticate(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait_queue, + u8 *mac); +int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue, + struct mwifiex_802_11_ssid *adhoc_ssid); +int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue, + struct mwifiex_bssdescriptor *bss_desc); +int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf); +int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf); +int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *wait_queue); +int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf); +struct mwifiex_chan_freq_power * + mwifiex_get_cfp_by_band_and_channel_from_cfg80211( + struct mwifiex_private *priv, + u8 band, u16 channel); +struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( + struct mwifiex_private *priv, + u8 band, u32 freq); +u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, + u8 ht_info); +u32 mwifiex_find_freq_from_band_chan(u8, u8); +int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, + u8 **buffer); +u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, + u8 ht_info); +u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, + u8 *rates); +u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); +u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate); +u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); +int mwifiex_get_rate_index(struct mwifiex_adapter *adapter, + u16 *rateBitmap, int size); +extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; +void mwifiex_save_curr_bcn(struct mwifiex_private *priv); +void mwifiex_free_curr_bcn(struct mwifiex_private *priv); +int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd); +int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp); +int is_command_pending(struct mwifiex_adapter *adapter); + +/* + * This function checks if the queuing is RA based or not. + */ +static inline u8 +mwifiex_queuing_ra_based(struct mwifiex_private *priv) +{ + /* + * Currently we assume if we are in Infra, then DA=RA. This might not be + * true in the future + */ + if ((priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) && + (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)) + return false; + + return true; +} + +/* + * This function copies rates. + */ +static inline u32 +mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len) +{ + int i; + + for (i = 0; i < len && src[i]; i++, pos++) { + if (pos >= MWIFIEX_SUPPORTED_RATES) + break; + dest[pos] = src[i]; + } + + return pos; +} + +/* + * This function returns the correct private structure pointer based + * upon the BSS type and BSS number. + */ +static inline struct mwifiex_private * +mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, + u32 bss_num, u32 bss_type) +{ + int i; + + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + if ((adapter->priv[i]->bss_num == bss_num) + && (adapter->priv[i]->bss_type == bss_type)) + break; + } + } + return ((i < adapter->priv_num) ? adapter->priv[i] : NULL); +} + +/* + * This function returns the first available private structure pointer + * based upon the BSS role. + */ +static inline struct mwifiex_private * +mwifiex_get_priv(struct mwifiex_adapter *adapter, + enum mwifiex_bss_role bss_role) +{ + int i; + + for (i = 0; i < adapter->priv_num; i++) { + if (adapter->priv[i]) { + if (bss_role == MWIFIEX_BSS_ROLE_ANY || + GET_BSS_ROLE(adapter->priv[i]) == bss_role) + break; + } + } + + return ((i < adapter->priv_num) ? adapter->priv[i] : NULL); +} + +/* + * This function returns the driver private structure of a network device. + */ +static inline struct mwifiex_private * +mwifiex_netdev_get_priv(struct net_device *dev) +{ + return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); +} + +struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue( + struct mwifiex_private *, + u8 wait_option); +struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter + *adapter, u8 bss_index); +int mwifiex_shutdown_fw(struct mwifiex_private *, u8); + +int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); +int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); + +void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, + int maxlen); +int mwifiex_request_set_mac_address(struct mwifiex_private *priv); +void mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + struct net_device *dev); +int mwifiex_request_ioctl(struct mwifiex_private *priv, + struct mwifiex_wait_queue *req, + int, u8 wait_option); +int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *); +int mwifiex_bss_start(struct mwifiex_private *priv, + u8 wait_option, + struct mwifiex_ssid_bssid *ssid_bssid); +int mwifiex_set_hs_params(struct mwifiex_private *priv, + u16 action, u8 wait_option, + struct mwifiex_ds_hs_cfg *hscfg); +int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option); +int mwifiex_enable_hs(struct mwifiex_adapter *adapter); +void mwifiex_process_ioctl_resp(struct mwifiex_private *priv, + struct mwifiex_wait_queue *req); +u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option); +int mwifiex_get_signal_info(struct mwifiex_private *priv, + u8 wait_option, + struct mwifiex_ds_get_signal *signal); +int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, + struct mwifiex_rate_cfg *rate); +int mwifiex_get_channel_list(struct mwifiex_private *priv, + u8 wait_option, + struct mwifiex_chan_list *chanlist); +int mwifiex_get_scan_table(struct mwifiex_private *priv, + u8 wait_option, + struct mwifiex_scan_resp *scanresp); +int mwifiex_get_auth_mode(struct mwifiex_private *priv, + u8 wait_option, u32 *auth_mode); +int mwifiex_get_encrypt_mode(struct mwifiex_private *priv, + u8 wait_option, + u32 *encrypt_mode); +int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option); +int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option, + struct mwifiex_ssid_bssid *ssid_bssid); +int mwifiex_request_scan(struct mwifiex_private *priv, + u8 wait_option, + struct mwifiex_802_11_ssid *req_ssid); +int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, + struct mwifiex_user_scan_cfg *scan_req); +int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); +int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); + +int mwifiex_drv_get_mode(struct mwifiex_private *priv, u8 wait_option); + +int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); + +int mwifiex_set_auth(struct mwifiex_private *priv, int encrypt_mode, + int auth_mode, int wpa_enabled); + +int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, + int key_len, u8 key_index, int disable); + +int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); + +int mwifiex_get_ver_ext(struct mwifiex_private *priv); + +int mwifiex_get_stats_info(struct mwifiex_private *priv, + struct mwifiex_ds_get_stats *log); + +int mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, + u32 reg_offset, u32 reg_value); + +int mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, + u32 reg_offset, u32 *value); + +int mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, + u8 *value); + +int mwifiex_set_11n_httx_cfg(struct mwifiex_private *priv, int data); + +int mwifiex_get_11n_httx_cfg(struct mwifiex_private *priv, int *data); + +int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index); + +int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); + +int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on); + +int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, + char *version, int max_len); + +int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); + +int mwifiex_main_process(struct mwifiex_adapter *); + +int mwifiex_bss_ioctl_mode(struct mwifiex_private *, + struct mwifiex_wait_queue *, + u16 action, int *mode); +int mwifiex_bss_ioctl_channel(struct mwifiex_private *, + u16 action, + struct mwifiex_chan_freq_power *cfp); +int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, + struct mwifiex_wait_queue *, + struct mwifiex_ssid_bssid *); +int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *, + u16 action, + struct mwifiex_ds_band_cfg *); +int mwifiex_snmp_mib_ioctl(struct mwifiex_private *, + struct mwifiex_wait_queue *, + u32 cmd_oid, u16 action, u32 *value); +int mwifiex_get_bss_info(struct mwifiex_private *, + struct mwifiex_bss_info *); + +#ifdef CONFIG_DEBUG_FS +void mwifiex_debugfs_init(void); +void mwifiex_debugfs_remove(void); + +void mwifiex_dev_debugfs_init(struct mwifiex_private *priv); +void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv); +#endif +#endif /* !_MWIFIEX_MAIN_H_ */ diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c new file mode 100644 index 000000000000..1152beb930ab --- /dev/null +++ b/drivers/net/wireless/mwifiex/scan.c @@ -0,0 +1,3098 @@ +/* + * Marvell Wireless LAN device driver: scan ioctl and command handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "11n.h" +#include "cfg80211.h" + +/* The maximum number of channels the firmware can scan per command */ +#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14 + +#define MWIFIEX_CHANNELS_PER_SCAN_CMD 4 + +/* Memory needed to store a max sized Channel List TLV for a firmware scan */ +#define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \ + + (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN \ + *sizeof(struct mwifiex_chan_scan_param_set))) + +/* Memory needed to store supported rate */ +#define RATE_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_rates_param_set) \ + + HOSTCMD_SUPPORTED_RATES) + +/* Memory needed to store a max number/size WildCard SSID TLV for a firmware + scan */ +#define WILDCARD_SSID_TLV_MAX_SIZE \ + (MWIFIEX_MAX_SSID_LIST_LENGTH * \ + (sizeof(struct mwifiex_ie_types_wildcard_ssid_params) \ + + IEEE80211_MAX_SSID_LEN)) + +/* Maximum memory needed for a mwifiex_scan_cmd_config with all TLVs at max */ +#define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config) \ + + sizeof(struct mwifiex_ie_types_num_probes) \ + + sizeof(struct mwifiex_ie_types_htcap) \ + + CHAN_TLV_MAX_SIZE \ + + RATE_TLV_MAX_SIZE \ + + WILDCARD_SSID_TLV_MAX_SIZE) + + +union mwifiex_scan_cmd_config_tlv { + /* Scan configuration (variable length) */ + struct mwifiex_scan_cmd_config config; + /* Max allocated block */ + u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC]; +}; + +enum cipher_suite { + CIPHER_SUITE_TKIP, + CIPHER_SUITE_CCMP, + CIPHER_SUITE_MAX +}; +static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = { + { 0x00, 0x50, 0xf2, 0x02 }, /* TKIP */ + { 0x00, 0x50, 0xf2, 0x04 }, /* AES */ +}; +static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = { + { 0x00, 0x0f, 0xac, 0x02 }, /* TKIP */ + { 0x00, 0x0f, 0xac, 0x04 }, /* AES */ +}; + +/* + * This function parses a given IE for a given OUI. + * + * This is used to parse a WPA/RSN IE to find if it has + * a given oui in PTK. + */ +static u8 +mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui) +{ + u8 count; + + count = iebody->ptk_cnt[0]; + + /* There could be multiple OUIs for PTK hence + 1) Take the length. + 2) Check all the OUIs for AES. + 3) If one of them is AES then pass success. */ + while (count) { + if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body))) + return MWIFIEX_OUI_PRESENT; + + --count; + if (count) + iebody = (struct ie_body *) ((u8 *) iebody + + sizeof(iebody->ptk_body)); + } + + pr_debug("info: %s: OUI is not found in PTK\n", __func__); + return MWIFIEX_OUI_NOT_PRESENT; +} + +/* + * This function checks if a given OUI is present in a RSN IE. + * + * The function first checks if a RSN IE is present or not in the + * BSS descriptor. It tries to locate the OUI only if such an IE is + * present. + */ +static u8 +mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) +{ + u8 *oui = NULL; + struct ie_body *iebody = NULL; + u8 ret = MWIFIEX_OUI_NOT_PRESENT; + + if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)). + ieee_hdr.element_id == WLAN_EID_RSN))) { + iebody = (struct ie_body *) + (((u8 *) bss_desc->bcn_rsn_ie->data) + + RSN_GTK_OUI_OFFSET); + oui = &mwifiex_rsn_oui[cipher][0]; + ret = mwifiex_search_oui_in_ie(iebody, oui); + if (ret) + return ret; + } + return ret; +} + +/* + * This function checks if a given OUI is present in a WPA IE. + * + * The function first checks if a WPA IE is present or not in the + * BSS descriptor. It tries to locate the OUI only if such an IE is + * present. + */ +static u8 +mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) +{ + u8 *oui = NULL; + struct ie_body *iebody = NULL; + u8 ret = MWIFIEX_OUI_NOT_PRESENT; + + if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)). + vend_hdr.element_id == WLAN_EID_WPA))) { + iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; + oui = &mwifiex_wpa_oui[cipher][0]; + ret = mwifiex_search_oui_in_ie(iebody, oui); + if (ret) + return ret; + } + return ret; +} + +/* + * This function compares two SSIDs and checks if they match. + */ +s32 +mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, + struct mwifiex_802_11_ssid *ssid2) +{ + if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) + return -1; + return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len); +} + +/* + * Sends IOCTL request to get the best BSS. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_find_best_bss(struct mwifiex_private *priv, + u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid) +{ + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ssid_bssid tmp_ssid_bssid; + int ret = 0; + u8 *mac = NULL; + + if (!ssid_bssid) + return -1; + + /* Allocate wait request buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + memcpy(&tmp_ssid_bssid, ssid_bssid, + sizeof(struct mwifiex_ssid_bssid)); + ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid); + + if (!ret) { + memcpy(ssid_bssid, &tmp_ssid_bssid, + sizeof(struct mwifiex_ssid_bssid)); + mac = (u8 *) &ssid_bssid->bssid; + dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s," + " %pM\n", ssid_bssid->ssid.ssid, mac); + } + + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to start a scan with user configurations. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + * + * Upon completion, it also generates a wireless event to notify + * applications. + */ +int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, + struct mwifiex_user_scan_cfg *scan_req) +{ + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + + /* Allocate an IOCTL request buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, + scan_req, NULL); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + + if (wait && (status != -EINPROGRESS)) + kfree(wait); + return status; +} + +/* + * This function checks if wapi is enabled in driver and scanned network is + * compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) +{ + if (priv->sec_info.wapi_enabled && + (bss_desc->bcn_wapi_ie && + ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id == + WLAN_EID_BSS_AC_ACCESS_DELAY))) { + return true; + } + return false; +} + +/* + * This function checks if driver is configured with no security mode and + * scanned network is compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) +{ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED + && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled + && ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != + WLAN_EID_WPA)) + && ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != + WLAN_EID_RSN)) + && priv->sec_info.encryption_mode == + MWIFIEX_ENCRYPTION_MODE_NONE && !bss_desc->privacy) { + return true; + } + return false; +} + +/* + * This function checks if static WEP is enabled in driver and scanned network + * is compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) +{ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED + && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled + && bss_desc->privacy) { + return true; + } + return false; +} + +/* + * This function checks if wpa is enabled in driver and scanned network is + * compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc, + int index) +{ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED + && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled + && ((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr. + element_id == WLAN_EID_WPA)) + /* + * Privacy bit may NOT be set in some APs like + * LinkSys WRT54G && bss_desc->privacy + */ + ) { + dev_dbg(priv->adapter->dev, "info: %s: WPA: index=%d" + " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " + "EncMode=%#x privacy=%#x\n", __func__, index, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)). + vend_hdr.element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)). + ieee_hdr.element_id : 0, + (priv->sec_info.wep_status == + MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d", + (priv->sec_info.wpa_enabled) ? "e" : "d", + (priv->sec_info.wpa2_enabled) ? "e" : "d", + priv->sec_info.encryption_mode, + bss_desc->privacy); + return true; + } + return false; +} + +/* + * This function checks if wpa2 is enabled in driver and scanned network is + * compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc, + int index) +{ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED + && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled + && ((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. + element_id == WLAN_EID_RSN)) + /* + * Privacy bit may NOT be set in some APs like + * LinkSys WRT54G && bss_desc->privacy + */ + ) { + dev_dbg(priv->adapter->dev, "info: %s: WPA2: index=%d" + " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " + "EncMode=%#x privacy=%#x\n", __func__, index, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)). + vend_hdr.element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)). + ieee_hdr.element_id : 0, + (priv->sec_info.wep_status == + MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d", + (priv->sec_info.wpa_enabled) ? "e" : "d", + (priv->sec_info.wpa2_enabled) ? "e" : "d", + priv->sec_info.encryption_mode, + bss_desc->privacy); + return true; + } + return false; +} + +/* + * This function checks if adhoc AES is enabled in driver and scanned network is + * compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) +{ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED + && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled + && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr. + element_id != WLAN_EID_WPA)) + && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. + element_id != WLAN_EID_RSN)) + && priv->sec_info.encryption_mode == + MWIFIEX_ENCRYPTION_MODE_NONE && bss_desc->privacy) { + return true; + } + return false; +} + +/* + * This function checks if dynamic WEP is enabled in driver and scanned network + * is compatible with it. + */ +static bool +mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc, + int index) +{ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED + && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled + && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr. + element_id != WLAN_EID_WPA)) + && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. + element_id != WLAN_EID_RSN)) + && priv->sec_info.encryption_mode != + MWIFIEX_ENCRYPTION_MODE_NONE && bss_desc->privacy) { + dev_dbg(priv->adapter->dev, "info: %s: dynamic " + "WEP: index=%d wpa_ie=%#x wpa2_ie=%#x " + "EncMode=%#x privacy=%#x\n", + __func__, index, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)). + vend_hdr.element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)). + ieee_hdr.element_id : 0, + priv->sec_info.encryption_mode, + bss_desc->privacy); + return true; + } + return false; +} + +/* + * This function checks if a scanned network is compatible with the driver + * settings. + * + * WEP WPA WPA2 ad-hoc encrypt Network + * enabled enabled enabled AES mode Privacy WPA WPA2 Compatible + * 0 0 0 0 NONE 0 0 0 yes No security + * 0 1 0 0 x 1x 1 x yes WPA (disable + * HT if no AES) + * 0 0 1 0 x 1x x 1 yes WPA2 (disable + * HT if no AES) + * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES + * 1 0 0 0 NONE 1 0 0 yes Static WEP + * (disable HT) + * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP + * + * Compatibility is not matched while roaming, except for mode. + */ +static s32 +mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bssdescriptor *bss_desc; + + bss_desc = &adapter->scan_table[index]; + bss_desc->disable_11n = false; + + /* Don't check for compatibility if roaming */ + if (priv->media_connected && (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) + && (bss_desc->bss_mode == MWIFIEX_BSS_MODE_INFRA)) + return index; + + if (priv->wps.session_enable) { + dev_dbg(adapter->dev, + "info: return success directly in WPS period\n"); + return index; + } + + if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { + dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); + return index; + } + + if (bss_desc->bss_mode == mode) { + if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { + /* No security */ + return index; + } else if (mwifiex_is_network_compatible_for_static_wep(priv, + bss_desc)) { + /* Static WEP enabled */ + dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); + bss_desc->disable_11n = true; + return index; + } else if (mwifiex_is_network_compatible_for_wpa(priv, bss_desc, + index)) { + /* WPA enabled */ + if (((priv->adapter->config_bands & BAND_GN + || priv->adapter->config_bands & BAND_AN) + && bss_desc->bcn_ht_cap) + && !mwifiex_is_wpa_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_wpa_oui_present(bss_desc, + CIPHER_SUITE_TKIP)) { + dev_dbg(adapter->dev, + "info: Disable 11n if AES " + "is not supported by AP\n"); + bss_desc->disable_11n = true; + } else { + return -1; + } + } + return index; + } else if (mwifiex_is_network_compatible_for_wpa2(priv, + bss_desc, index)) { + /* WPA2 enabled */ + if (((priv->adapter->config_bands & BAND_GN + || priv->adapter->config_bands & BAND_AN) + && bss_desc->bcn_ht_cap) + && !mwifiex_is_rsn_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_rsn_oui_present(bss_desc, + CIPHER_SUITE_TKIP)) { + dev_dbg(adapter->dev, + "info: Disable 11n if AES " + "is not supported by AP\n"); + bss_desc->disable_11n = true; + } else { + return -1; + } + } + return index; + } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, + bss_desc)) { + /* Ad-hoc AES enabled */ + return index; + } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, + bss_desc, index)) { + /* Dynamic WEP enabled */ + return index; + } + + /* Security doesn't match */ + dev_dbg(adapter->dev, "info: %s: failed: index=%d " + "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode" + "=%#x privacy=%#x\n", + __func__, index, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)).vend_hdr. + element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)).ieee_hdr. + element_id : 0, + (priv->sec_info.wep_status == + MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d", + (priv->sec_info.wpa_enabled) ? "e" : "d", + (priv->sec_info.wpa2_enabled) ? "e" : "d", + priv->sec_info.encryption_mode, bss_desc->privacy); + return -1; + } + + /* Mode doesn't match */ + return -1; +} + +/* + * This function finds the best SSID in the scan list. + * + * It searches the scan table for the best SSID that also matches the current + * adapter network preference (mode, security etc.). + */ +static s32 +mwifiex_find_best_network_in_list(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u32 mode = priv->bss_mode; + s32 best_net = -1; + s32 best_rssi = 0; + u32 i; + + dev_dbg(adapter->dev, "info: num of BSSIDs = %d\n", + adapter->num_in_scan_table); + + for (i = 0; i < adapter->num_in_scan_table; i++) { + switch (mode) { + case MWIFIEX_BSS_MODE_INFRA: + case MWIFIEX_BSS_MODE_IBSS: + if (mwifiex_is_network_compatible(priv, i, mode) >= 0) { + if (SCAN_RSSI(adapter->scan_table[i].rssi) > + best_rssi) { + best_rssi = SCAN_RSSI(adapter-> + scan_table[i].rssi); + best_net = i; + } + } + break; + case MWIFIEX_BSS_MODE_AUTO: + default: + if (SCAN_RSSI(adapter->scan_table[i].rssi) > + best_rssi) { + best_rssi = SCAN_RSSI(adapter->scan_table[i]. + rssi); + best_net = i; + } + break; + } + } + + return best_net; +} + +/* + * This function creates a channel list for the driver to scan, based + * on region/band information. + * + * This routine is used for any scan that is not provided with a + * specific channel list to scan. + */ +static void +mwifiex_scan_create_channel_list(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg + *user_scan_in, + struct mwifiex_chan_scan_param_set + *scan_chan_list, + u8 filtered_scan) +{ + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + struct mwifiex_adapter *adapter = priv->adapter; + int chan_idx = 0, i; + u8 scan_type; + + for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) { + + if (!priv->wdev->wiphy->bands[band]) + continue; + + sband = priv->wdev->wiphy->bands[band]; + + for (i = 0; (i < sband->n_channels) ; i++, chan_idx++) { + ch = &sband->channels[i]; + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + scan_chan_list[chan_idx].radio_type = band; + scan_type = ch->flags & IEEE80211_CHAN_PASSIVE_SCAN; + if (user_scan_in && + user_scan_in->chan_list[0].scan_time) + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16((u16) user_scan_in-> + chan_list[0].scan_time); + else if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE) + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16(adapter->passive_scan_time); + else + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16(adapter->active_scan_time); + if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE) + scan_chan_list[chan_idx].chan_scan_mode_bitmap + |= MWIFIEX_PASSIVE_SCAN; + else + scan_chan_list[chan_idx].chan_scan_mode_bitmap + &= ~MWIFIEX_PASSIVE_SCAN; + scan_chan_list[chan_idx].chan_number = + (u32) ch->hw_value; + if (filtered_scan) { + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16(adapter->specific_scan_time); + scan_chan_list[chan_idx].chan_scan_mode_bitmap + |= MWIFIEX_DISABLE_CHAN_FILT; + } + } + + } +} + +/* + * This function constructs and sends multiple scan config commands to + * the firmware. + * + * Previous routines in the code flow have created a scan command configuration + * with any requested TLVs. This function splits the channel TLV into maximum + * channels supported per scan lists and sends the portion of the channel TLV, + * along with the other TLVs, to the firmware. + */ +static int +mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, + u32 max_chan_per_scan, u8 filtered_scan, + struct mwifiex_scan_cmd_config *scan_cfg_out, + struct mwifiex_ie_types_chan_list_param_set + *chan_tlv_out, + struct mwifiex_chan_scan_param_set *scan_chan_list) +{ + int ret = 0; + struct mwifiex_chan_scan_param_set *tmp_chan_list; + struct mwifiex_chan_scan_param_set *start_chan; + + u32 tlv_idx; + u32 total_scan_time; + u32 done_early; + + if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) { + dev_dbg(priv->adapter->dev, + "info: Scan: Null detect: %p, %p, %p\n", + scan_cfg_out, chan_tlv_out, scan_chan_list); + return -1; + } + + chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); + + /* Set the temp channel struct pointer to the start of the desired + list */ + tmp_chan_list = scan_chan_list; + + /* Loop through the desired channel list, sending a new firmware scan + commands for each max_chan_per_scan channels (or for 1,6,11 + individually if configured accordingly) */ + while (tmp_chan_list->chan_number) { + + tlv_idx = 0; + total_scan_time = 0; + chan_tlv_out->header.len = 0; + start_chan = tmp_chan_list; + done_early = false; + + /* + * Construct the Channel TLV for the scan command. Continue to + * insert channel TLVs until: + * - the tlv_idx hits the maximum configured per scan command + * - the next channel to insert is 0 (end of desired channel + * list) + * - done_early is set (controlling individual scanning of + * 1,6,11) + */ + while (tlv_idx < max_chan_per_scan + && tmp_chan_list->chan_number && !done_early) { + + dev_dbg(priv->adapter->dev, + "info: Scan: Chan(%3d), Radio(%d)," + " Mode(%d, %d), Dur(%d)\n", + tmp_chan_list->chan_number, + tmp_chan_list->radio_type, + tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_PASSIVE_SCAN, + (tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_DISABLE_CHAN_FILT) >> 1, + le16_to_cpu(tmp_chan_list->max_scan_time)); + + /* Copy the current channel TLV to the command being + prepared */ + memcpy(chan_tlv_out->chan_scan_param + tlv_idx, + tmp_chan_list, + sizeof(chan_tlv_out->chan_scan_param)); + + /* Increment the TLV header length by the size + appended */ + chan_tlv_out->header.len = + cpu_to_le16(le16_to_cpu(chan_tlv_out->header.len) + + (sizeof(chan_tlv_out->chan_scan_param))); + + /* + * The tlv buffer length is set to the number of bytes + * of the between the channel tlv pointer and the start + * of the tlv buffer. This compensates for any TLVs + * that were appended before the channel list. + */ + scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out - + scan_cfg_out->tlv_buf); + + /* Add the size of the channel tlv header and the data + length */ + scan_cfg_out->tlv_buf_len += + (sizeof(chan_tlv_out->header) + + le16_to_cpu(chan_tlv_out->header.len)); + + /* Increment the index to the channel tlv we are + constructing */ + tlv_idx++; + + /* Count the total scan time per command */ + total_scan_time += + le16_to_cpu(tmp_chan_list->max_scan_time); + + done_early = false; + + /* Stop the loop if the *current* channel is in the + 1,6,11 set and we are not filtering on a BSSID + or SSID. */ + if (!filtered_scan && (tmp_chan_list->chan_number == 1 + || tmp_chan_list->chan_number == 6 + || tmp_chan_list->chan_number == 11)) + done_early = true; + + /* Increment the tmp pointer to the next channel to + be scanned */ + tmp_chan_list++; + + /* Stop the loop if the *next* channel is in the 1,6,11 + set. This will cause it to be the only channel + scanned on the next interation */ + if (!filtered_scan && (tmp_chan_list->chan_number == 1 + || tmp_chan_list->chan_number == 6 + || tmp_chan_list->chan_number == 11)) + done_early = true; + } + + /* The total scan time should be less than scan command timeout + value */ + if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) { + dev_err(priv->adapter->dev, "total scan time %dms" + " is over limit (%dms), scan skipped\n", + total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME); + ret = -1; + break; + } + + priv->adapter->scan_channels = start_chan; + + /* Send the scan command to the firmware with the specified + cfg */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN, + HostCmd_ACT_GEN_SET, + 0, wait_buf, scan_cfg_out); + if (ret) + break; + } + + if (ret) + return -1; + + return 0; +} + +/* + * This function constructs a scan command configuration structure to use + * in scan commands. + * + * Application layer or other functions can invoke network scanning + * with a scan configuration supplied in a user scan configuration structure. + * This structure is used as the basis of one or many scan command configuration + * commands that are sent to the command processing module and eventually to the + * firmware. + * + * This function creates a scan command configuration structure based on the + * following user supplied parameters (if present): + * - SSID filter + * - BSSID filter + * - Number of Probes to be sent + * - Channel list + * + * If the SSID or BSSID filter is not present, the filter is disabled/cleared. + * If the number of probes is not set, adapter default setting is used. + */ +static void +mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in, + struct mwifiex_scan_cmd_config *scan_cfg_out, + struct mwifiex_ie_types_chan_list_param_set + **chan_list_out, + struct mwifiex_chan_scan_param_set + *scan_chan_list, + u8 *max_chan_per_scan, u8 *filtered_scan, + u8 *scan_current_only) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_ie_types_num_probes *num_probes_tlv; + struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; + struct mwifiex_ie_types_rates_param_set *rates_tlv; + const u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + u8 *tlv_pos; + u32 num_probes; + u32 ssid_len; + u32 chan_idx; + u32 scan_type; + u16 scan_dur; + u8 channel; + u8 radio_type; + u32 ssid_idx; + u8 ssid_filter; + u8 rates[MWIFIEX_SUPPORTED_RATES]; + u32 rates_size; + struct mwifiex_ie_types_htcap *ht_cap; + + /* The tlv_buf_len is calculated for each scan command. The TLVs added + in this routine will be preserved since the routine that sends the + command will append channelTLVs at *chan_list_out. The difference + between the *chan_list_out and the tlv_buf start will be used to + calculate the size of anything we add in this routine. */ + scan_cfg_out->tlv_buf_len = 0; + + /* Running tlv pointer. Assigned to chan_list_out at end of function + so later routines know where channels can be added to the command + buf */ + tlv_pos = scan_cfg_out->tlv_buf; + + /* Initialize the scan as un-filtered; the flag is later set to TRUE + below if a SSID or BSSID filter is sent in the command */ + *filtered_scan = false; + + /* Initialize the scan as not being only on the current channel. If + the channel list is customized, only contains one channel, and is + the active channel, this is set true and data flow is not halted. */ + *scan_current_only = false; + + if (user_scan_in) { + + /* Default the ssid_filter flag to TRUE, set false under + certain wildcard conditions and qualified by the existence + of an SSID list before marking the scan as filtered */ + ssid_filter = true; + + /* Set the BSS type scan filter, use Adapter setting if + unset */ + scan_cfg_out->bss_mode = + (user_scan_in->bss_mode ? (u8) user_scan_in-> + bss_mode : (u8) adapter->scan_mode); + + /* Set the number of probes to send, use Adapter setting + if unset */ + num_probes = + (user_scan_in->num_probes ? user_scan_in-> + num_probes : adapter->scan_probes); + + /* + * Set the BSSID filter to the incoming configuration, + * if non-zero. If not set, it will remain disabled + * (all zeros). + */ + memcpy(scan_cfg_out->specific_bssid, + user_scan_in->specific_bssid, + sizeof(scan_cfg_out->specific_bssid)); + + for (ssid_idx = 0; + ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list)) + && (*user_scan_in->ssid_list[ssid_idx].ssid + || user_scan_in->ssid_list[ssid_idx].max_len)); + ssid_idx++) { + + ssid_len = strlen(user_scan_in->ssid_list[ssid_idx]. + ssid) + 1; + + wildcard_ssid_tlv = + (struct mwifiex_ie_types_wildcard_ssid_params *) + tlv_pos; + wildcard_ssid_tlv->header.type = + cpu_to_le16(TLV_TYPE_WILDCARDSSID); + wildcard_ssid_tlv->header.len = cpu_to_le16( + (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> + max_ssid_length))); + wildcard_ssid_tlv->max_ssid_length = + user_scan_in->ssid_list[ssid_idx].max_len; + + memcpy(wildcard_ssid_tlv->ssid, + user_scan_in->ssid_list[ssid_idx].ssid, + ssid_len); + + tlv_pos += (sizeof(wildcard_ssid_tlv->header) + + le16_to_cpu(wildcard_ssid_tlv->header.len)); + + dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n", + ssid_idx, wildcard_ssid_tlv->ssid, + wildcard_ssid_tlv->max_ssid_length); + + /* Empty wildcard ssid with a maxlen will match many or + potentially all SSIDs (maxlen == 32), therefore do + not treat the scan as + filtered. */ + if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) + ssid_filter = false; + + } + + /* + * The default number of channels sent in the command is low to + * ensure the response buffer from the firmware does not + * truncate scan results. That is not an issue with an SSID + * or BSSID filter applied to the scan results in the firmware. + */ + if ((ssid_idx && ssid_filter) + || memcmp(scan_cfg_out->specific_bssid, &zero_mac, + sizeof(zero_mac))) + *filtered_scan = true; + } else { + scan_cfg_out->bss_mode = (u8) adapter->scan_mode; + num_probes = adapter->scan_probes; + } + + /* + * If a specific BSSID or SSID is used, the number of channels in the + * scan command will be increased to the absolute maximum. + */ + if (*filtered_scan) + *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN; + else + *max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD; + + /* If the input config or adapter has the number of Probes set, + add tlv */ + if (num_probes) { + + dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", + num_probes); + + num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; + num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); + num_probes_tlv->header.len = + cpu_to_le16(sizeof(num_probes_tlv->num_probes)); + num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes); + + tlv_pos += sizeof(num_probes_tlv->header) + + le16_to_cpu(num_probes_tlv->header.len); + + } + + /* Append rates tlv */ + memset(rates, 0, sizeof(rates)); + + rates_size = mwifiex_get_supported_rates(priv, rates); + + rates_tlv = (struct mwifiex_ie_types_rates_param_set *) tlv_pos; + rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES); + rates_tlv->header.len = cpu_to_le16((u16) rates_size); + memcpy(rates_tlv->rates, rates, rates_size); + tlv_pos += sizeof(rates_tlv->header) + rates_size; + + dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size); + + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) + && (priv->adapter->config_bands & BAND_GN + || priv->adapter->config_bands & BAND_AN)) { + ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; + memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); + ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); + ht_cap->header.len = + cpu_to_le16(sizeof(struct ieee80211_ht_cap)); + mwifiex_fill_cap_info(priv, ht_cap); + tlv_pos += sizeof(struct mwifiex_ie_types_htcap); + } + + /* Append vendor specific IE TLV */ + mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos); + + /* + * Set the output for the channel TLV to the address in the tlv buffer + * past any TLVs that were added in this function (SSID, num_probes). + * Channel TLVs will be added past this for each scan command, + * preserving the TLVs that were previously added. + */ + *chan_list_out = + (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos; + + if (user_scan_in && user_scan_in->chan_list[0].chan_number) { + + dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); + + for (chan_idx = 0; + chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX + && user_scan_in->chan_list[chan_idx].chan_number; + chan_idx++) { + + channel = user_scan_in->chan_list[chan_idx].chan_number; + (scan_chan_list + chan_idx)->chan_number = channel; + + radio_type = + user_scan_in->chan_list[chan_idx].radio_type; + (scan_chan_list + chan_idx)->radio_type = radio_type; + + scan_type = user_scan_in->chan_list[chan_idx].scan_type; + + if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE) + (scan_chan_list + + chan_idx)->chan_scan_mode_bitmap + |= MWIFIEX_PASSIVE_SCAN; + else + (scan_chan_list + + chan_idx)->chan_scan_mode_bitmap + &= ~MWIFIEX_PASSIVE_SCAN; + + if (user_scan_in->chan_list[chan_idx].scan_time) { + scan_dur = (u16) user_scan_in-> + chan_list[chan_idx].scan_time; + } else { + if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE) + scan_dur = adapter->passive_scan_time; + else if (*filtered_scan) + scan_dur = adapter->specific_scan_time; + else + scan_dur = adapter->active_scan_time; + } + + (scan_chan_list + chan_idx)->min_scan_time = + cpu_to_le16(scan_dur); + (scan_chan_list + chan_idx)->max_scan_time = + cpu_to_le16(scan_dur); + } + + /* Check if we are only scanning the current channel */ + if ((chan_idx == 1) + && (user_scan_in->chan_list[0].chan_number + == priv->curr_bss_params.bss_descriptor.channel)) { + *scan_current_only = true; + dev_dbg(adapter->dev, + "info: Scan: Scanning current channel only\n"); + } + + } else { + dev_dbg(adapter->dev, + "info: Scan: Creating full region channel list\n"); + mwifiex_scan_create_channel_list(priv, user_scan_in, + scan_chan_list, + *filtered_scan); + } +} + +/* + * This function inspects the scan response buffer for pointers to + * expected TLVs. + * + * TLVs can be included at the end of the scan response BSS information. + * + * Data in the buffer is parsed pointers to TLVs that can potentially + * be passed back in the response. + */ +static void +mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, + struct mwifiex_ie_types_data *tlv, + u32 tlv_buf_size, u32 req_tlv_type, + struct mwifiex_ie_types_data **tlv_data) +{ + struct mwifiex_ie_types_data *current_tlv; + u32 tlv_buf_left; + u32 tlv_type; + u32 tlv_len; + + current_tlv = tlv; + tlv_buf_left = tlv_buf_size; + *tlv_data = NULL; + + dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n", + tlv_buf_size); + + while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { + + tlv_type = le16_to_cpu(current_tlv->header.type); + tlv_len = le16_to_cpu(current_tlv->header.len); + + if (sizeof(tlv->header) + tlv_len > tlv_buf_left) { + dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n"); + break; + } + + if (req_tlv_type == tlv_type) { + switch (tlv_type) { + case TLV_TYPE_TSFTIMESTAMP: + dev_dbg(adapter->dev, "info: SCAN_RESP: TSF " + "timestamp TLV, len = %d\n", tlv_len); + *tlv_data = (struct mwifiex_ie_types_data *) + current_tlv; + break; + case TLV_TYPE_CHANNELBANDLIST: + dev_dbg(adapter->dev, "info: SCAN_RESP: channel" + " band list TLV, len = %d\n", tlv_len); + *tlv_data = (struct mwifiex_ie_types_data *) + current_tlv; + break; + default: + dev_err(adapter->dev, + "SCAN_RESP: unhandled TLV = %d\n", + tlv_type); + /* Give up, this seems corrupted */ + return; + } + } + + if (*tlv_data) + break; + + + tlv_buf_left -= (sizeof(tlv->header) + tlv_len); + current_tlv = + (struct mwifiex_ie_types_data *) (current_tlv->data + + tlv_len); + + } /* while */ +} + +/* + * This function interprets a BSS scan response returned from the firmware. + * + * The various fixed fields and IEs are parsed and passed back for a BSS + * probe response or beacon from scan command. Information is recorded as + * needed in the scan table for that entry. + * + * The following IE types are recognized and parsed - + * - SSID + * - Supported rates + * - FH parameters set + * - DS parameters set + * - CF parameters set + * - IBSS parameters set + * - ERP information + * - Extended supported rates + * - Vendor specific (221) + * - RSN IE + * - WAPI IE + * - HT capability + * - HT operation + * - BSS Coexistence 20/40 + * - Extended capability + * - Overlapping BSS scan parameters + */ +static int +mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter, + struct mwifiex_bssdescriptor *bss_entry, + u8 **beacon_info, u32 *bytes_left) +{ + int ret = 0; + u8 element_id; + struct ieee_types_fh_param_set *fh_param_set; + struct ieee_types_ds_param_set *ds_param_set; + struct ieee_types_cf_param_set *cf_param_set; + struct ieee_types_ibss_param_set *ibss_param_set; + struct mwifiex_802_11_fixed_ies fixed_ie; + u8 *current_ptr; + u8 *rate; + u8 element_len; + u16 total_ie_len; + u8 bytes_to_copy; + u8 rate_size; + u16 beacon_size; + u8 found_data_rate_ie; + u32 bytes_left_for_current_beacon; + struct ieee_types_vendor_specific *vendor_ie; + const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 }; + const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 }; + + found_data_rate_ie = false; + rate_size = 0; + beacon_size = 0; + + if (*bytes_left >= sizeof(beacon_size)) { + /* Extract & convert beacon size from the command buffer */ + memcpy(&beacon_size, *beacon_info, sizeof(beacon_size)); + *bytes_left -= sizeof(beacon_size); + *beacon_info += sizeof(beacon_size); + } + + if (!beacon_size || beacon_size > *bytes_left) { + *beacon_info += *bytes_left; + *bytes_left = 0; + return -1; + } + + /* Initialize the current working beacon pointer for this BSS + iteration */ + current_ptr = *beacon_info; + + /* Advance the return beacon pointer past the current beacon */ + *beacon_info += beacon_size; + *bytes_left -= beacon_size; + + bytes_left_for_current_beacon = beacon_size; + + memcpy(bss_entry->mac_address, current_ptr, ETH_ALEN); + dev_dbg(adapter->dev, "info: InterpretIE: AP MAC Addr: %pM\n", + bss_entry->mac_address); + + current_ptr += ETH_ALEN; + bytes_left_for_current_beacon -= ETH_ALEN; + + if (bytes_left_for_current_beacon < 12) { + dev_err(adapter->dev, "InterpretIE: not enough bytes left\n"); + return -1; + } + + /* + * Next 4 fields are RSSI, time stamp, beacon interval, + * and capability information + */ + + /* RSSI is 1 byte long */ + bss_entry->rssi = (s32) (*current_ptr); + dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", *current_ptr); + current_ptr += 1; + bytes_left_for_current_beacon -= 1; + + /* + * The RSSI is not part of the beacon/probe response. After we have + * advanced current_ptr past the RSSI field, save the remaining + * data for use at the application layer + */ + bss_entry->beacon_buf = current_ptr; + bss_entry->beacon_buf_size = bytes_left_for_current_beacon; + + /* Time stamp is 8 bytes long */ + memcpy(fixed_ie.time_stamp, current_ptr, 8); + memcpy(bss_entry->time_stamp, current_ptr, 8); + current_ptr += 8; + bytes_left_for_current_beacon -= 8; + + /* Beacon interval is 2 bytes long */ + memcpy(&fixed_ie.beacon_interval, current_ptr, 2); + bss_entry->beacon_period = le16_to_cpu(fixed_ie.beacon_interval); + current_ptr += 2; + bytes_left_for_current_beacon -= 2; + + /* Capability information is 2 bytes long */ + memcpy(&fixed_ie.capabilities, current_ptr, 2); + dev_dbg(adapter->dev, "info: InterpretIE: fixed_ie.capabilities=0x%X\n", + fixed_ie.capabilities); + bss_entry->cap_info_bitmap = le16_to_cpu(fixed_ie.capabilities); + current_ptr += 2; + bytes_left_for_current_beacon -= 2; + + /* Rest of the current buffer are IE's */ + dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n", + bytes_left_for_current_beacon); + + if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { + dev_dbg(adapter->dev, "info: InterpretIE: AP WEP enabled\n"); + bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; + } else { + bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; + } + + if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS) + bss_entry->bss_mode = MWIFIEX_BSS_MODE_IBSS; + else + bss_entry->bss_mode = MWIFIEX_BSS_MODE_INFRA; + + + /* Process variable IE */ + while (bytes_left_for_current_beacon >= 2) { + element_id = *current_ptr; + element_len = *(current_ptr + 1); + total_ie_len = element_len + sizeof(struct ieee_types_header); + + if (bytes_left_for_current_beacon < total_ie_len) { + dev_err(adapter->dev, "err: InterpretIE: in processing" + " IE, bytes left < IE length\n"); + bytes_left_for_current_beacon = 0; + ret = -1; + continue; + } + switch (element_id) { + case WLAN_EID_SSID: + bss_entry->ssid.ssid_len = element_len; + memcpy(bss_entry->ssid.ssid, (current_ptr + 2), + element_len); + dev_dbg(adapter->dev, "info: InterpretIE: ssid: %-32s\n", + bss_entry->ssid.ssid); + break; + + case WLAN_EID_SUPP_RATES: + memcpy(bss_entry->data_rates, current_ptr + 2, + element_len); + memcpy(bss_entry->supported_rates, current_ptr + 2, + element_len); + rate_size = element_len; + found_data_rate_ie = true; + break; + + case WLAN_EID_FH_PARAMS: + fh_param_set = + (struct ieee_types_fh_param_set *) current_ptr; + memcpy(&bss_entry->phy_param_set.fh_param_set, + fh_param_set, + sizeof(struct ieee_types_fh_param_set)); + break; + + case WLAN_EID_DS_PARAMS: + ds_param_set = + (struct ieee_types_ds_param_set *) current_ptr; + + bss_entry->channel = ds_param_set->current_chan; + + memcpy(&bss_entry->phy_param_set.ds_param_set, + ds_param_set, + sizeof(struct ieee_types_ds_param_set)); + break; + + case WLAN_EID_CF_PARAMS: + cf_param_set = + (struct ieee_types_cf_param_set *) current_ptr; + memcpy(&bss_entry->ss_param_set.cf_param_set, + cf_param_set, + sizeof(struct ieee_types_cf_param_set)); + break; + + case WLAN_EID_IBSS_PARAMS: + ibss_param_set = + (struct ieee_types_ibss_param_set *) + current_ptr; + memcpy(&bss_entry->ss_param_set.ibss_param_set, + ibss_param_set, + sizeof(struct ieee_types_ibss_param_set)); + break; + + case WLAN_EID_ERP_INFO: + bss_entry->erp_flags = *(current_ptr + 2); + break; + + case WLAN_EID_EXT_SUPP_RATES: + /* + * Only process extended supported rate + * if data rate is already found. + * Data rate IE should come before + * extended supported rate IE + */ + if (found_data_rate_ie) { + if ((element_len + rate_size) > + MWIFIEX_SUPPORTED_RATES) + bytes_to_copy = + (MWIFIEX_SUPPORTED_RATES - + rate_size); + else + bytes_to_copy = element_len; + + rate = (u8 *) bss_entry->data_rates; + rate += rate_size; + memcpy(rate, current_ptr + 2, bytes_to_copy); + + rate = (u8 *) bss_entry->supported_rates; + rate += rate_size; + memcpy(rate, current_ptr + 2, bytes_to_copy); + } + break; + + case WLAN_EID_VENDOR_SPECIFIC: + vendor_ie = (struct ieee_types_vendor_specific *) + current_ptr; + + if (!memcmp + (vendor_ie->vend_hdr.oui, wpa_oui, + sizeof(wpa_oui))) { + bss_entry->bcn_wpa_ie = + (struct ieee_types_vendor_specific *) + current_ptr; + bss_entry->wpa_offset = (u16) (current_ptr - + bss_entry->beacon_buf); + } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, + sizeof(wmm_oui))) { + if (total_ie_len == + sizeof(struct ieee_types_wmm_parameter) + || total_ie_len == + sizeof(struct ieee_types_wmm_info)) + /* + * Only accept and copy the WMM IE if + * it matches the size expected for the + * WMM Info IE or the WMM Parameter IE. + */ + memcpy((u8 *) &bss_entry->wmm_ie, + current_ptr, total_ie_len); + } + break; + case WLAN_EID_RSN: + bss_entry->bcn_rsn_ie = + (struct ieee_types_generic *) current_ptr; + bss_entry->rsn_offset = (u16) (current_ptr - + bss_entry->beacon_buf); + break; + case WLAN_EID_BSS_AC_ACCESS_DELAY: + bss_entry->bcn_wapi_ie = + (struct ieee_types_generic *) current_ptr; + bss_entry->wapi_offset = (u16) (current_ptr - + bss_entry->beacon_buf); + break; + case WLAN_EID_HT_CAPABILITY: + bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *) + (current_ptr + + sizeof(struct ieee_types_header)); + bss_entry->ht_cap_offset = (u16) (current_ptr + + sizeof(struct ieee_types_header) - + bss_entry->beacon_buf); + break; + case WLAN_EID_HT_INFORMATION: + bss_entry->bcn_ht_info = (struct ieee80211_ht_info *) + (current_ptr + + sizeof(struct ieee_types_header)); + bss_entry->ht_info_offset = (u16) (current_ptr + + sizeof(struct ieee_types_header) - + bss_entry->beacon_buf); + break; + case WLAN_EID_BSS_COEX_2040: + bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr + + sizeof(struct ieee_types_header)); + bss_entry->bss_co_2040_offset = (u16) (current_ptr + + sizeof(struct ieee_types_header) - + bss_entry->beacon_buf); + break; + case WLAN_EID_EXT_CAPABILITY: + bss_entry->bcn_ext_cap = (u8 *) (current_ptr + + sizeof(struct ieee_types_header)); + bss_entry->ext_cap_offset = (u16) (current_ptr + + sizeof(struct ieee_types_header) - + bss_entry->beacon_buf); + break; + case WLAN_EID_OVERLAP_BSS_SCAN_PARAM: + bss_entry->bcn_obss_scan = + (struct ieee_types_obss_scan_param *) + current_ptr; + bss_entry->overlap_bss_offset = (u16) (current_ptr - + bss_entry->beacon_buf); + break; + default: + break; + } + + current_ptr += element_len + 2; + + /* Need to account for IE ID and IE Len */ + bytes_left_for_current_beacon -= (element_len + 2); + + } /* while (bytes_left_for_current_beacon > 2) */ + return ret; +} + +/* + * This function adjusts the pointers used in beacon buffers to reflect + * shifts. + * + * The memory allocated for beacon buffers is of fixed sizes where all the + * saved beacons must be stored. New beacons are added in the free portion + * of this memory, space permitting; while duplicate beacon buffers are + * placed at the same start location. However, since duplicate beacon + * buffers may not match the size of the old one, all the following buffers + * in the memory must be shifted to either make space, or to fill up freed + * up space. + * + * This function is used to update the beacon buffer pointers that are past + * an existing beacon buffer that is updated with a new one of different + * size. The pointers are shifted by a fixed amount, either forward or + * backward. + * + * the following pointers in every affected beacon buffers are changed, if + * present - + * - WPA IE pointer + * - RSN IE pointer + * - WAPI IE pointer + * - HT capability IE pointer + * - HT information IE pointer + * - BSS coexistence 20/40 IE pointer + * - Extended capability IE pointer + * - Overlapping BSS scan parameter IE pointer + */ +static void +mwifiex_adjust_beacon_buffer_ptrs(struct mwifiex_private *priv, u8 advance, + u8 *bcn_store, u32 rem_bcn_size, + u32 num_of_ent) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u32 adj_idx; + for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) { + if (adapter->scan_table[adj_idx].beacon_buf > bcn_store) { + + if (advance) + adapter->scan_table[adj_idx].beacon_buf += + rem_bcn_size; + else + adapter->scan_table[adj_idx].beacon_buf -= + rem_bcn_size; + + if (adapter->scan_table[adj_idx].bcn_wpa_ie) + adapter->scan_table[adj_idx].bcn_wpa_ie = + (struct ieee_types_vendor_specific *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].wpa_offset); + if (adapter->scan_table[adj_idx].bcn_rsn_ie) + adapter->scan_table[adj_idx].bcn_rsn_ie = + (struct ieee_types_generic *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].rsn_offset); + if (adapter->scan_table[adj_idx].bcn_wapi_ie) + adapter->scan_table[adj_idx].bcn_wapi_ie = + (struct ieee_types_generic *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].wapi_offset); + if (adapter->scan_table[adj_idx].bcn_ht_cap) + adapter->scan_table[adj_idx].bcn_ht_cap = + (struct ieee80211_ht_cap *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].ht_cap_offset); + + if (adapter->scan_table[adj_idx].bcn_ht_info) + adapter->scan_table[adj_idx].bcn_ht_info = + (struct ieee80211_ht_info *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].ht_info_offset); + if (adapter->scan_table[adj_idx].bcn_bss_co_2040) + adapter->scan_table[adj_idx].bcn_bss_co_2040 = + (u8 *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].bss_co_2040_offset); + if (adapter->scan_table[adj_idx].bcn_ext_cap) + adapter->scan_table[adj_idx].bcn_ext_cap = + (u8 *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].ext_cap_offset); + if (adapter->scan_table[adj_idx].bcn_obss_scan) + adapter->scan_table[adj_idx].bcn_obss_scan = + (struct ieee_types_obss_scan_param *) + (adapter->scan_table[adj_idx].beacon_buf + + adapter->scan_table[adj_idx].overlap_bss_offset); + } + } +} + +/* + * This function updates the pointers used in beacon buffer for given bss + * descriptor to reflect shifts + * + * Following pointers are updated + * - WPA IE pointer + * - RSN IE pointer + * - WAPI IE pointer + * - HT capability IE pointer + * - HT information IE pointer + * - BSS coexistence 20/40 IE pointer + * - Extended capability IE pointer + * - Overlapping BSS scan parameter IE pointer + */ +static void +mwifiex_update_beacon_buffer_ptrs(struct mwifiex_bssdescriptor *beacon) +{ + if (beacon->bcn_wpa_ie) + beacon->bcn_wpa_ie = (struct ieee_types_vendor_specific *) + (beacon->beacon_buf + beacon->wpa_offset); + if (beacon->bcn_rsn_ie) + beacon->bcn_rsn_ie = (struct ieee_types_generic *) + (beacon->beacon_buf + beacon->rsn_offset); + if (beacon->bcn_wapi_ie) + beacon->bcn_wapi_ie = (struct ieee_types_generic *) + (beacon->beacon_buf + beacon->wapi_offset); + if (beacon->bcn_ht_cap) + beacon->bcn_ht_cap = (struct ieee80211_ht_cap *) + (beacon->beacon_buf + beacon->ht_cap_offset); + if (beacon->bcn_ht_info) + beacon->bcn_ht_info = (struct ieee80211_ht_info *) + (beacon->beacon_buf + beacon->ht_info_offset); + if (beacon->bcn_bss_co_2040) + beacon->bcn_bss_co_2040 = (u8 *) (beacon->beacon_buf + + beacon->bss_co_2040_offset); + if (beacon->bcn_ext_cap) + beacon->bcn_ext_cap = (u8 *) (beacon->beacon_buf + + beacon->ext_cap_offset); + if (beacon->bcn_obss_scan) + beacon->bcn_obss_scan = (struct ieee_types_obss_scan_param *) + (beacon->beacon_buf + beacon->overlap_bss_offset); +} + +/* + * This function stores a beacon or probe response for a BSS returned + * in the scan. + * + * This stores a new scan response or an update for a previous scan response. + * New entries need to verify that they do not exceed the total amount of + * memory allocated for the table. + * + * Replacement entries need to take into consideration the amount of space + * currently allocated for the beacon/probe response and adjust the entry + * as needed. + * + * A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved + * for an entry in case it is a beacon since a probe response for the + * network will by larger per the standard. This helps to reduce the + * amount of memory copying to fit a new probe response into an entry + * already occupied by a network's previously stored beacon. + */ +static void +mwifiex_ret_802_11_scan_store_beacon(struct mwifiex_private *priv, + u32 beacon_idx, u32 num_of_ent, + struct mwifiex_bssdescriptor *new_beacon) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u8 *bcn_store; + u32 new_bcn_size; + u32 old_bcn_size; + u32 bcn_space; + + if (adapter->scan_table[beacon_idx].beacon_buf) { + + new_bcn_size = new_beacon->beacon_buf_size; + old_bcn_size = adapter->scan_table[beacon_idx].beacon_buf_size; + bcn_space = adapter->scan_table[beacon_idx].beacon_buf_size_max; + bcn_store = adapter->scan_table[beacon_idx].beacon_buf; + + /* Set the max to be the same as current entry unless changed + below */ + new_beacon->beacon_buf_size_max = bcn_space; + if (new_bcn_size == old_bcn_size) { + /* + * Beacon is the same size as the previous entry. + * Replace the previous contents with the scan result + */ + memcpy(bcn_store, new_beacon->beacon_buf, + new_beacon->beacon_buf_size); + + } else if (new_bcn_size <= bcn_space) { + /* + * New beacon size will fit in the amount of space + * we have previously allocated for it + */ + + /* Copy the new beacon buffer entry over the old one */ + memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size); + + /* + * If the old beacon size was less than the maximum + * we had alloted for the entry, and the new entry + * is even smaller, reset the max size to the old + * beacon entry and compress the storage space + * (leaving a new pad space of (old_bcn_size - + * new_bcn_size). + */ + if (old_bcn_size < bcn_space + && new_bcn_size <= old_bcn_size) { + /* + * Old Beacon size is smaller than the alloted + * storage size. Shrink the alloted storage + * space. + */ + dev_dbg(adapter->dev, "info: AppControl:" + " smaller duplicate beacon " + "(%d), old = %d, new = %d, space = %d," + "left = %d\n", + beacon_idx, old_bcn_size, new_bcn_size, + bcn_space, + (int)(sizeof(adapter->bcn_buf) - + (adapter->bcn_buf_end - + adapter->bcn_buf))); + + /* + * memmove (since the memory overlaps) the + * data after the beacon we just stored to the + * end of the current beacon. This cleans up + * any unused space the old larger beacon was + * using in the buffer + */ + memmove(bcn_store + old_bcn_size, + bcn_store + bcn_space, + adapter->bcn_buf_end - (bcn_store + + bcn_space)); + + /* + * Decrement the end pointer by the difference + * between the old larger size and the new + * smaller size since we are using less space + * due to the new beacon being smaller + */ + adapter->bcn_buf_end -= + (bcn_space - old_bcn_size); + + /* Set the maximum storage size to the old + beacon size */ + new_beacon->beacon_buf_size_max = old_bcn_size; + + /* Adjust beacon buffer pointers that are past + the current */ + mwifiex_adjust_beacon_buffer_ptrs(priv, 0, + bcn_store, (bcn_space - old_bcn_size), + num_of_ent); + } + } else if (adapter->bcn_buf_end + (new_bcn_size - bcn_space) + < (adapter->bcn_buf + sizeof(adapter->bcn_buf))) { + /* + * Beacon is larger than space previously allocated + * (bcn_space) and there is enough space left in the + * beaconBuffer to store the additional data + */ + dev_dbg(adapter->dev, "info: AppControl:" + " larger duplicate beacon (%d), " + "old = %d, new = %d, space = %d, left = %d\n", + beacon_idx, old_bcn_size, new_bcn_size, + bcn_space, + (int)(sizeof(adapter->bcn_buf) - + (adapter->bcn_buf_end - + adapter->bcn_buf))); + + /* + * memmove (since the memory overlaps) the data + * after the beacon we just stored to the end of + * the current beacon. This moves the data for + * the beacons after this further in memory to + * make space for the new larger beacon we are + * about to copy in. + */ + memmove(bcn_store + new_bcn_size, + bcn_store + bcn_space, + adapter->bcn_buf_end - (bcn_store + bcn_space)); + + /* Copy the new beacon buffer entry over the old one */ + memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size); + + /* Move the beacon end pointer by the amount of new + beacon data we are adding */ + adapter->bcn_buf_end += (new_bcn_size - bcn_space); + + /* + * This entry is bigger than the alloted max space + * previously reserved. Increase the max space to + * be equal to the new beacon size + */ + new_beacon->beacon_buf_size_max = new_bcn_size; + + /* Adjust beacon buffer pointers that are past the + current */ + mwifiex_adjust_beacon_buffer_ptrs(priv, 1, bcn_store, + (new_bcn_size - bcn_space), + num_of_ent); + } else { + /* + * Beacon is larger than the previously allocated space, + * but there is not enough free space to store the + * additional data. + */ + dev_err(adapter->dev, "AppControl: larger duplicate " + " beacon (%d), old = %d new = %d, space = %d," + " left = %d\n", beacon_idx, old_bcn_size, + new_bcn_size, bcn_space, + (int)(sizeof(adapter->bcn_buf) - + (adapter->bcn_buf_end - adapter->bcn_buf))); + + /* Storage failure, keep old beacon intact */ + new_beacon->beacon_buf_size = old_bcn_size; + if (new_beacon->bcn_wpa_ie) + new_beacon->wpa_offset = + adapter->scan_table[beacon_idx]. + wpa_offset; + if (new_beacon->bcn_rsn_ie) + new_beacon->rsn_offset = + adapter->scan_table[beacon_idx]. + rsn_offset; + if (new_beacon->bcn_wapi_ie) + new_beacon->wapi_offset = + adapter->scan_table[beacon_idx]. + wapi_offset; + if (new_beacon->bcn_ht_cap) + new_beacon->ht_cap_offset = + adapter->scan_table[beacon_idx]. + ht_cap_offset; + if (new_beacon->bcn_ht_info) + new_beacon->ht_info_offset = + adapter->scan_table[beacon_idx]. + ht_info_offset; + if (new_beacon->bcn_bss_co_2040) + new_beacon->bss_co_2040_offset = + adapter->scan_table[beacon_idx]. + bss_co_2040_offset; + if (new_beacon->bcn_ext_cap) + new_beacon->ext_cap_offset = + adapter->scan_table[beacon_idx]. + ext_cap_offset; + if (new_beacon->bcn_obss_scan) + new_beacon->overlap_bss_offset = + adapter->scan_table[beacon_idx]. + overlap_bss_offset; + } + /* Point the new entry to its permanent storage space */ + new_beacon->beacon_buf = bcn_store; + mwifiex_update_beacon_buffer_ptrs(new_beacon); + } else { + /* + * No existing beacon data exists for this entry, check to see + * if we can fit it in the remaining space + */ + if (adapter->bcn_buf_end + new_beacon->beacon_buf_size + + SCAN_BEACON_ENTRY_PAD < (adapter->bcn_buf + + sizeof(adapter->bcn_buf))) { + + /* + * Copy the beacon buffer data from the local entry to + * the adapter dev struct buffer space used to store + * the raw beacon data for each entry in the scan table + */ + memcpy(adapter->bcn_buf_end, new_beacon->beacon_buf, + new_beacon->beacon_buf_size); + + /* Update the beacon ptr to point to the table save + area */ + new_beacon->beacon_buf = adapter->bcn_buf_end; + new_beacon->beacon_buf_size_max = + (new_beacon->beacon_buf_size + + SCAN_BEACON_ENTRY_PAD); + + mwifiex_update_beacon_buffer_ptrs(new_beacon); + + /* Increment the end pointer by the size reserved */ + adapter->bcn_buf_end += new_beacon->beacon_buf_size_max; + + dev_dbg(adapter->dev, "info: AppControl: beacon[%02d]" + " sz=%03d, used = %04d, left = %04d\n", + beacon_idx, + new_beacon->beacon_buf_size, + (int)(adapter->bcn_buf_end - adapter->bcn_buf), + (int)(sizeof(adapter->bcn_buf) - + (adapter->bcn_buf_end - + adapter->bcn_buf))); + } else { + /* No space for new beacon */ + dev_dbg(adapter->dev, "info: AppControl: no space for" + " beacon (%d): %pM sz=%03d, left=%03d\n", + beacon_idx, new_beacon->mac_address, + new_beacon->beacon_buf_size, + (int)(sizeof(adapter->bcn_buf) - + (adapter->bcn_buf_end - + adapter->bcn_buf))); + + /* Storage failure; clear storage records for this + bcn */ + new_beacon->beacon_buf = NULL; + new_beacon->beacon_buf_size = 0; + new_beacon->beacon_buf_size_max = 0; + new_beacon->bcn_wpa_ie = NULL; + new_beacon->wpa_offset = 0; + new_beacon->bcn_rsn_ie = NULL; + new_beacon->rsn_offset = 0; + new_beacon->bcn_wapi_ie = NULL; + new_beacon->wapi_offset = 0; + new_beacon->bcn_ht_cap = NULL; + new_beacon->ht_cap_offset = 0; + new_beacon->bcn_ht_info = NULL; + new_beacon->ht_info_offset = 0; + new_beacon->bcn_bss_co_2040 = NULL; + new_beacon->bss_co_2040_offset = 0; + new_beacon->bcn_ext_cap = NULL; + new_beacon->ext_cap_offset = 0; + new_beacon->bcn_obss_scan = NULL; + new_beacon->overlap_bss_offset = 0; + } + } +} + +/* + * This function restores a beacon buffer of the current BSS descriptor. + */ +static void mwifiex_restore_curr_bcn(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bssdescriptor *curr_bss = + &priv->curr_bss_params.bss_descriptor; + unsigned long flags; + + if (priv->curr_bcn_buf && + ((adapter->bcn_buf_end + priv->curr_bcn_size) < + (adapter->bcn_buf + sizeof(adapter->bcn_buf)))) { + spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags); + + /* restore the current beacon buffer */ + memcpy(adapter->bcn_buf_end, priv->curr_bcn_buf, + priv->curr_bcn_size); + curr_bss->beacon_buf = adapter->bcn_buf_end; + curr_bss->beacon_buf_size = priv->curr_bcn_size; + adapter->bcn_buf_end += priv->curr_bcn_size; + + /* adjust the pointers in the current BSS descriptor */ + if (curr_bss->bcn_wpa_ie) + curr_bss->bcn_wpa_ie = + (struct ieee_types_vendor_specific *) + (curr_bss->beacon_buf + + curr_bss->wpa_offset); + + if (curr_bss->bcn_rsn_ie) + curr_bss->bcn_rsn_ie = (struct ieee_types_generic *) + (curr_bss->beacon_buf + + curr_bss->rsn_offset); + + if (curr_bss->bcn_ht_cap) + curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *) + (curr_bss->beacon_buf + + curr_bss->ht_cap_offset); + + if (curr_bss->bcn_ht_info) + curr_bss->bcn_ht_info = (struct ieee80211_ht_info *) + (curr_bss->beacon_buf + + curr_bss->ht_info_offset); + + if (curr_bss->bcn_bss_co_2040) + curr_bss->bcn_bss_co_2040 = + (u8 *) (curr_bss->beacon_buf + + curr_bss->bss_co_2040_offset); + + if (curr_bss->bcn_ext_cap) + curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf + + curr_bss->ext_cap_offset); + + if (curr_bss->bcn_obss_scan) + curr_bss->bcn_obss_scan = + (struct ieee_types_obss_scan_param *) + (curr_bss->beacon_buf + + curr_bss->overlap_bss_offset); + + spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); + + dev_dbg(adapter->dev, "info: current beacon restored %d\n", + priv->curr_bcn_size); + } else { + dev_warn(adapter->dev, + "curr_bcn_buf not saved or bcn_buf has no space\n"); + } +} + +/* + * This function post processes the scan table after a new scan command has + * completed. + * + * It inspects each entry of the scan table and tries to find an entry that + * matches with our current associated/joined network from the scan. If + * one is found, the stored copy of the BSS descriptor of our current network + * is updated. + * + * It also debug dumps the current scan table contents after processing is over. + */ +static void +mwifiex_process_scan_results(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + s32 j; + u32 i; + unsigned long flags; + + if (priv->media_connected) { + + j = mwifiex_find_ssid_in_list(priv, &priv->curr_bss_params. + bss_descriptor.ssid, + priv->curr_bss_params. + bss_descriptor.mac_address, + priv->bss_mode); + + if (j >= 0) { + spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags); + priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL; + priv->curr_bss_params.bss_descriptor.wpa_offset = 0; + priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL; + priv->curr_bss_params.bss_descriptor.rsn_offset = 0; + priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL; + priv->curr_bss_params.bss_descriptor.wapi_offset = 0; + priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL; + priv->curr_bss_params.bss_descriptor.ht_cap_offset = + 0; + priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL; + priv->curr_bss_params.bss_descriptor.ht_info_offset = + 0; + priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 = + NULL; + priv->curr_bss_params.bss_descriptor. + bss_co_2040_offset = 0; + priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL; + priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0; + priv->curr_bss_params.bss_descriptor. + bcn_obss_scan = NULL; + priv->curr_bss_params.bss_descriptor. + overlap_bss_offset = 0; + priv->curr_bss_params.bss_descriptor.beacon_buf = NULL; + priv->curr_bss_params.bss_descriptor.beacon_buf_size = + 0; + priv->curr_bss_params.bss_descriptor. + beacon_buf_size_max = 0; + + dev_dbg(adapter->dev, "info: Found current ssid/bssid" + " in list @ index #%d\n", j); + /* Make a copy of current BSSID descriptor */ + memcpy(&priv->curr_bss_params.bss_descriptor, + &adapter->scan_table[j], + sizeof(priv->curr_bss_params.bss_descriptor)); + + mwifiex_save_curr_bcn(priv); + spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); + + } else { + mwifiex_restore_curr_bcn(priv); + } + } + + for (i = 0; i < adapter->num_in_scan_table; i++) + dev_dbg(adapter->dev, "info: scan:(%02d) %pM " + "RSSI[%03d], SSID[%s]\n", + i, adapter->scan_table[i].mac_address, + (s32) adapter->scan_table[i].rssi, + adapter->scan_table[i].ssid.ssid); +} + +/* + * This function converts radio type scan parameter to a band configuration + * to be used in join command. + */ +static u8 +mwifiex_radio_type_to_band(u8 radio_type) +{ + u8 ret_band; + + switch (radio_type) { + case HostCmd_SCAN_RADIO_TYPE_A: + ret_band = BAND_A; + break; + case HostCmd_SCAN_RADIO_TYPE_BG: + default: + ret_band = BAND_G; + break; + } + + return ret_band; +} + +/* + * This function deletes a specific indexed entry from the scan table. + * + * This also compacts the remaining entries and adjusts any buffering + * of beacon/probe response data if needed. + */ +static void +mwifiex_scan_delete_table_entry(struct mwifiex_private *priv, s32 table_idx) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u32 del_idx; + u32 beacon_buf_adj; + u8 *beacon_buf; + + /* + * Shift the saved beacon buffer data for the scan table back over the + * entry being removed. Update the end of buffer pointer. Save the + * deleted buffer allocation size for pointer adjustments for entries + * compacted after the deleted index. + */ + beacon_buf_adj = adapter->scan_table[table_idx].beacon_buf_size_max; + + dev_dbg(adapter->dev, "info: Scan: Delete Entry %d, beacon buffer " + "removal = %d bytes\n", table_idx, beacon_buf_adj); + + /* Check if the table entry had storage allocated for its beacon */ + if (beacon_buf_adj) { + beacon_buf = adapter->scan_table[table_idx].beacon_buf; + + /* + * Remove the entry's buffer space, decrement the table end + * pointer by the amount we are removing + */ + adapter->bcn_buf_end -= beacon_buf_adj; + + dev_dbg(adapter->dev, "info: scan: delete entry %d," + " compact data: %p <- %p (sz = %d)\n", + table_idx, beacon_buf, + beacon_buf + beacon_buf_adj, + (int)(adapter->bcn_buf_end - beacon_buf)); + + /* + * Compact data storage. Copy all data after the deleted + * entry's end address (beacon_buf + beacon_buf_adj) back + * to the original start address (beacon_buf). + * + * Scan table entries affected by the move will have their + * entry pointer adjusted below. + * + * Use memmove since the dest/src memory regions overlap. + */ + memmove(beacon_buf, beacon_buf + beacon_buf_adj, + adapter->bcn_buf_end - beacon_buf); + } + + dev_dbg(adapter->dev, + "info: Scan: Delete Entry %d, num_in_scan_table = %d\n", + table_idx, adapter->num_in_scan_table); + + /* Shift all of the entries after the table_idx back by one, compacting + the table and removing the requested entry */ + for (del_idx = table_idx; (del_idx + 1) < adapter->num_in_scan_table; + del_idx++) { + /* Copy the next entry over this one */ + memcpy(adapter->scan_table + del_idx, + adapter->scan_table + del_idx + 1, + sizeof(struct mwifiex_bssdescriptor)); + + /* + * Adjust this entry's pointer to its beacon buffer based on + * the removed/compacted entry from the deleted index. Don't + * decrement if the buffer pointer is NULL (no data stored for + * this entry). + */ + if (adapter->scan_table[del_idx].beacon_buf) { + adapter->scan_table[del_idx].beacon_buf -= + beacon_buf_adj; + if (adapter->scan_table[del_idx].bcn_wpa_ie) + adapter->scan_table[del_idx].bcn_wpa_ie = + (struct ieee_types_vendor_specific *) + (adapter->scan_table[del_idx]. + beacon_buf + + adapter->scan_table[del_idx]. + wpa_offset); + if (adapter->scan_table[del_idx].bcn_rsn_ie) + adapter->scan_table[del_idx].bcn_rsn_ie = + (struct ieee_types_generic *) + (adapter->scan_table[del_idx]. + beacon_buf + + adapter->scan_table[del_idx]. + rsn_offset); + if (adapter->scan_table[del_idx].bcn_wapi_ie) + adapter->scan_table[del_idx].bcn_wapi_ie = + (struct ieee_types_generic *) + (adapter->scan_table[del_idx].beacon_buf + + adapter->scan_table[del_idx]. + wapi_offset); + if (adapter->scan_table[del_idx].bcn_ht_cap) + adapter->scan_table[del_idx].bcn_ht_cap = + (struct ieee80211_ht_cap *) + (adapter->scan_table[del_idx].beacon_buf + + adapter->scan_table[del_idx]. + ht_cap_offset); + + if (adapter->scan_table[del_idx].bcn_ht_info) + adapter->scan_table[del_idx].bcn_ht_info = + (struct ieee80211_ht_info *) + (adapter->scan_table[del_idx].beacon_buf + + adapter->scan_table[del_idx]. + ht_info_offset); + if (adapter->scan_table[del_idx].bcn_bss_co_2040) + adapter->scan_table[del_idx].bcn_bss_co_2040 = + (u8 *) + (adapter->scan_table[del_idx].beacon_buf + + adapter->scan_table[del_idx]. + bss_co_2040_offset); + if (adapter->scan_table[del_idx].bcn_ext_cap) + adapter->scan_table[del_idx].bcn_ext_cap = + (u8 *) + (adapter->scan_table[del_idx].beacon_buf + + adapter->scan_table[del_idx]. + ext_cap_offset); + if (adapter->scan_table[del_idx].bcn_obss_scan) + adapter->scan_table[del_idx]. + bcn_obss_scan = + (struct ieee_types_obss_scan_param *) + (adapter->scan_table[del_idx].beacon_buf + + adapter->scan_table[del_idx]. + overlap_bss_offset); + } + } + + /* The last entry is invalid now that it has been deleted or moved + back */ + memset(adapter->scan_table + adapter->num_in_scan_table - 1, + 0x00, sizeof(struct mwifiex_bssdescriptor)); + + adapter->num_in_scan_table--; +} + +/* + * This function deletes all occurrences of a given SSID from the scan table. + * + * This iterates through the scan table and deletes all entries that match + * the given SSID. It also compacts the remaining scan table entries. + */ +static int +mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, + struct mwifiex_802_11_ssid *del_ssid) +{ + int ret = -1; + s32 table_idx; + + dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n", + del_ssid->ssid); + + /* If the requested SSID is found in the table, delete it. Then keep + searching the table for multiple entires for the SSID until no + more are found */ + while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL, + MWIFIEX_BSS_MODE_AUTO)) >= + 0) { + dev_dbg(priv->adapter->dev, + "info: Scan: Delete SSID Entry: Found Idx = %d\n", + table_idx); + ret = 0; + mwifiex_scan_delete_table_entry(priv, table_idx); + } + + return ret; +} + +/* + * This is an internal function used to start a scan based on an input + * configuration. + * + * This uses the input user scan configuration information when provided in + * order to send the appropriate scan commands to firmware to populate or + * update the internal driver scan table. + */ +int mwifiex_scan_networks(struct mwifiex_private *priv, + void *wait_buf, u16 action, + const struct mwifiex_user_scan_cfg *user_scan_in, + struct mwifiex_scan_resp *scan_resp) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + struct cmd_ctrl_node *cmd_node = NULL; + union mwifiex_scan_cmd_config_tlv *scan_cfg_out = NULL; + struct mwifiex_ie_types_chan_list_param_set *chan_list_out; + u32 buf_size; + struct mwifiex_chan_scan_param_set *scan_chan_list; + u8 keep_previous_scan; + u8 filtered_scan; + u8 scan_current_chan_only; + u8 max_chan_per_scan; + unsigned long flags; + + if (action == HostCmd_ACT_GEN_GET) { + if (scan_resp) { + scan_resp->scan_table = (u8 *) adapter->scan_table; + scan_resp->num_in_scan_table = + adapter->num_in_scan_table; + } else { + ret = -1; + } + return ret; + } + + if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { + dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); + return ret; + } + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->scan_processing = true; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + + if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { + dev_dbg(adapter->dev, + "cmd: Scan is blocked during association...\n"); + return ret; + } + + scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), + GFP_KERNEL); + if (!scan_cfg_out) { + dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); + return -1; + } + + buf_size = sizeof(struct mwifiex_chan_scan_param_set) * + MWIFIEX_USER_SCAN_CHAN_MAX; + scan_chan_list = kzalloc(buf_size, GFP_KERNEL); + if (!scan_chan_list) { + dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); + kfree(scan_cfg_out); + return -1; + } + + keep_previous_scan = false; + + mwifiex_scan_setup_scan_config(priv, user_scan_in, + &scan_cfg_out->config, &chan_list_out, + scan_chan_list, &max_chan_per_scan, + &filtered_scan, &scan_current_chan_only); + + if (user_scan_in) + keep_previous_scan = user_scan_in->keep_previous_scan; + + + if (!keep_previous_scan) { + memset(adapter->scan_table, 0x00, + sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); + adapter->num_in_scan_table = 0; + adapter->bcn_buf_end = adapter->bcn_buf; + } + + ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan, + filtered_scan, &scan_cfg_out->config, + chan_list_out, scan_chan_list); + + /* Get scan command from scan_pending_q and put to cmd_pending_q */ + if (!ret) { + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + if (!list_empty(&adapter->scan_pending_q)) { + cmd_node = list_first_entry(&adapter->scan_pending_q, + struct cmd_ctrl_node, list); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, + true); + } else { + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + } + ret = -EINPROGRESS; + } else { + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->scan_processing = true; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + } + + kfree(scan_cfg_out); + kfree(scan_chan_list); + return ret; +} + +/* + * This function prepares a scan command to be sent to the firmware. + * + * This uses the scan command configuration sent to the command processing + * module in command preparation stage to configure a scan command structure + * to send to firmware. + * + * The fixed fields specifying the BSS type and BSSID filters as well as a + * variable number/length of TLVs are sent in the command to firmware. + * + * Preparation also includes - + * - Setting command ID, and proper size + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, void *data_buf) +{ + struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; + struct mwifiex_scan_cmd_config *scan_cfg; + + scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf; + + /* Set fixed field variables in scan command */ + scan_cmd->bss_mode = scan_cfg->bss_mode; + memcpy(scan_cmd->bssid, scan_cfg->specific_bssid, + sizeof(scan_cmd->bssid)); + memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len); + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN); + + /* Size is equal to the sizeof(fixed portions) + the TLV len + header */ + cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode) + + sizeof(scan_cmd->bssid) + + scan_cfg->tlv_buf_len + S_DS_GEN)); + + return 0; +} + +/* + * This function handles the command response of scan. + * + * The response buffer for the scan command has the following + * memory layout: + * + * .-------------------------------------------------------------. + * | Header (4 * sizeof(t_u16)): Standard command response hdr | + * .-------------------------------------------------------------. + * | BufSize (t_u16) : sizeof the BSS Description data | + * .-------------------------------------------------------------. + * | NumOfSet (t_u8) : Number of BSS Descs returned | + * .-------------------------------------------------------------. + * | BSSDescription data (variable, size given in BufSize) | + * .-------------------------------------------------------------. + * | TLV data (variable, size calculated using Header->Size, | + * | BufSize and sizeof the fixed fields above) | + * .-------------------------------------------------------------. + */ +int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, void *wq_buf) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_wait_queue *wait_queue = NULL; + struct cmd_ctrl_node *cmd_node = NULL; + struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; + struct mwifiex_bssdescriptor *bss_new_entry = NULL; + struct mwifiex_ie_types_data *tlv_data; + struct mwifiex_ie_types_tsf_timestamp *tsf_tlv; + u8 *bss_info; + u32 scan_resp_size; + u32 bytes_left; + u32 num_in_table; + u32 bss_idx; + u32 idx; + u32 tlv_buf_size; + long long tsf_val; + struct mwifiex_chan_freq_power *cfp; + struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv; + struct chan_band_param_set *chan_band; + u8 band; + u8 is_bgscan_resp; + unsigned long flags; + + is_bgscan_resp = (le16_to_cpu(resp->command) + == HostCmd_CMD_802_11_BG_SCAN_QUERY); + if (is_bgscan_resp) + scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; + else + scan_rsp = &resp->params.scan_resp; + + + if (scan_rsp->number_of_sets > IW_MAX_AP) { + dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", + scan_rsp->number_of_sets); + ret = -1; + goto done; + } + + bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); + dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n", + bytes_left); + + scan_resp_size = le16_to_cpu(resp->size); + + dev_dbg(adapter->dev, + "info: SCAN_RESP: returned %d APs before parsing\n", + scan_rsp->number_of_sets); + + num_in_table = adapter->num_in_scan_table; + bss_info = scan_rsp->bss_desc_and_tlv_buffer; + + /* + * The size of the TLV buffer is equal to the entire command response + * size (scan_resp_size) minus the fixed fields (sizeof()'s), the + * BSS Descriptions (bss_descript_size as bytesLef) and the command + * response header (S_DS_GEN) + */ + tlv_buf_size = scan_resp_size - (bytes_left + + sizeof(scan_rsp->bss_descript_size) + + sizeof(scan_rsp->number_of_sets) + + S_DS_GEN); + + tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp-> + bss_desc_and_tlv_buffer + + bytes_left); + + /* Search the TLV buffer space in the scan response for any valid + TLVs */ + mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size, + TLV_TYPE_TSFTIMESTAMP, + (struct mwifiex_ie_types_data **) + &tsf_tlv); + + /* Search the TLV buffer space in the scan response for any valid + TLVs */ + mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size, + TLV_TYPE_CHANNELBANDLIST, + (struct mwifiex_ie_types_data **) + &chan_band_tlv); + + /* + * Process each scan response returned (scan_rsp->number_of_sets). + * Save the information in the bss_new_entry and then insert into the + * driver scan table either as an update to an existing entry + * or as an addition at the end of the table + */ + bss_new_entry = kzalloc(sizeof(struct mwifiex_bssdescriptor), + GFP_KERNEL); + if (!bss_new_entry) { + dev_err(adapter->dev, " failed to alloc bss_new_entry\n"); + return -1; + } + + for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) { + /* Zero out the bss_new_entry we are about to store info in */ + memset(bss_new_entry, 0x00, + sizeof(struct mwifiex_bssdescriptor)); + + if (mwifiex_interpret_bss_desc_with_ie(adapter, bss_new_entry, + &bss_info, + &bytes_left)) { + /* Error parsing/interpreting scan response, skipped */ + dev_err(adapter->dev, "SCAN_RESP: " + "mwifiex_interpret_bss_desc_with_ie " + "returned ERROR\n"); + continue; + } + + /* Process the data fields and IEs returned for this BSS */ + dev_dbg(adapter->dev, "info: SCAN_RESP: BSSID = %pM\n", + bss_new_entry->mac_address); + + /* Search the scan table for the same bssid */ + for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) { + if (memcmp(bss_new_entry->mac_address, + adapter->scan_table[bss_idx].mac_address, + sizeof(bss_new_entry->mac_address))) { + continue; + } + /* + * If the SSID matches as well, it is a + * duplicate of this entry. Keep the bss_idx + * set to this entry so we replace the old + * contents in the table + */ + if ((bss_new_entry->ssid.ssid_len + == adapter->scan_table[bss_idx]. ssid.ssid_len) + && (!memcmp(bss_new_entry->ssid.ssid, + adapter->scan_table[bss_idx].ssid.ssid, + bss_new_entry->ssid.ssid_len))) { + dev_dbg(adapter->dev, "info: SCAN_RESP:" + " duplicate of index: %d\n", bss_idx); + break; + } + } + /* + * If the bss_idx is equal to the number of entries in + * the table, the new entry was not a duplicate; append + * it to the scan table + */ + if (bss_idx == num_in_table) { + /* Range check the bss_idx, keep it limited to + the last entry */ + if (bss_idx == IW_MAX_AP) + bss_idx--; + else + num_in_table++; + } + + /* + * Save the beacon/probe response returned for later application + * retrieval. Duplicate beacon/probe responses are updated if + * possible + */ + mwifiex_ret_802_11_scan_store_beacon(priv, bss_idx, + num_in_table, bss_new_entry); + /* + * If the TSF TLV was appended to the scan results, save this + * entry's TSF value in the networkTSF field.The networkTSF is + * the firmware's TSF value at the time the beacon or probe + * response was received. + */ + if (tsf_tlv) { + memcpy(&tsf_val, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE] + , sizeof(tsf_val)); + memcpy(&bss_new_entry->network_tsf, &tsf_val, + sizeof(bss_new_entry->network_tsf)); + } + band = BAND_G; + if (chan_band_tlv) { + chan_band = &chan_band_tlv->chan_band_param[idx]; + band = mwifiex_radio_type_to_band(chan_band->radio_type + & (BIT(0) | BIT(1))); + } + + /* Save the band designation for this entry for use in join */ + bss_new_entry->bss_band = band; + cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, + (u8) bss_new_entry->bss_band, + (u16)bss_new_entry->channel); + + if (cfp) + bss_new_entry->freq = cfp->freq; + else + bss_new_entry->freq = 0; + + /* Copy the locally created bss_new_entry to the scan table */ + memcpy(&adapter->scan_table[bss_idx], bss_new_entry, + sizeof(adapter->scan_table[bss_idx])); + + } + + dev_dbg(adapter->dev, + "info: SCAN_RESP: Scanned %2d APs, %d valid, %d total\n", + scan_rsp->number_of_sets, + num_in_table - adapter->num_in_scan_table, num_in_table); + + /* Update the total number of BSSIDs in the scan table */ + adapter->num_in_scan_table = num_in_table; + + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + if (list_empty(&adapter->scan_pending_q)) { + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + /* + * Process the resulting scan table: + * - Remove any bad ssids + * - Update our current BSS information from scan data + */ + mwifiex_process_scan_results(priv); + + /* Need to indicate IOCTL complete */ + wait_queue = (struct mwifiex_wait_queue *) wq_buf; + if (wait_queue) { + wait_queue->status = MWIFIEX_ERROR_NO_ERROR; + + /* Indicate ioctl complete */ + mwifiex_ioctl_complete(adapter, + (struct mwifiex_wait_queue *) wait_queue, 0); + } + if (priv->report_scan_result) + priv->report_scan_result = false; + if (priv->scan_pending_on_block) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } + + } else { + /* Get scan command from scan_pending_q and put to + cmd_pending_q */ + cmd_node = list_first_entry(&adapter->scan_pending_q, + struct cmd_ctrl_node, list); + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + } + +done: + kfree((u8 *) bss_new_entry); + return ret; +} + +/* + * This function prepares command for background scan query. + * + * Preparation includes - + * - Setting command ID and proper size + * - Setting background scan flush parameter + * - Ensuring correct endian-ness + */ +int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf) +{ + struct host_cmd_ds_802_11_bg_scan_query *bg_query = + &cmd->params.bg_scan_query; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query) + + S_DS_GEN); + + bg_query->flush = 1; + + return 0; +} + +/* + * This function finds a SSID in the scan table. + * + * A BSSID may optionally be provided to qualify the SSID. + * For non-Auto mode, further check is made to make sure the + * BSS found in the scan table is compatible with the current + * settings of the driver. + */ +s32 +mwifiex_find_ssid_in_list(struct mwifiex_private *priv, + struct mwifiex_802_11_ssid *ssid, u8 *bssid, + u32 mode) +{ + struct mwifiex_adapter *adapter = priv->adapter; + s32 net = -1, j; + u8 best_rssi = 0; + u32 i; + + dev_dbg(adapter->dev, "info: num of entries in table = %d\n", + adapter->num_in_scan_table); + + /* + * Loop through the table until the maximum is reached or until a match + * is found based on the bssid field comparison + */ + for (i = 0; + i < adapter->num_in_scan_table && (!bssid || (bssid && net < 0)); + i++) { + if (!mwifiex_ssid_cmp(&adapter->scan_table[i].ssid, ssid) && + (!bssid + || !memcmp(adapter->scan_table[i].mac_address, bssid, + ETH_ALEN)) + && + (mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, (u8) adapter->scan_table[i].bss_band, + (u16) adapter->scan_table[i].channel))) { + switch (mode) { + case MWIFIEX_BSS_MODE_INFRA: + case MWIFIEX_BSS_MODE_IBSS: + j = mwifiex_is_network_compatible(priv, i, + mode); + + if (j >= 0) { + if (SCAN_RSSI + (adapter->scan_table[i].rssi) > + best_rssi) { + best_rssi = SCAN_RSSI(adapter-> + scan_table + [i].rssi); + net = i; + } + } else { + if (net == -1) + net = j; + } + break; + case MWIFIEX_BSS_MODE_AUTO: + default: + /* + * Do not check compatibility if the mode + * requested is Auto/Unknown. Allows generic + * find to work without verifying against the + * Adapter security settings + */ + if (SCAN_RSSI(adapter->scan_table[i].rssi) > + best_rssi) { + best_rssi = SCAN_RSSI(adapter-> + scan_table[i].rssi); + net = i; + } + break; + } + } + } + + return net; +} + +/* + * This function finds a specific compatible BSSID in the scan list. + * + * This function loops through the scan table looking for a compatible + * match. If a BSSID matches, but the BSS is found to be not compatible + * the function ignores it and continues to search through the rest of + * the entries in case there is an AP with multiple SSIDs assigned to + * the same BSSID. + */ +s32 +mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid, + u32 mode) +{ + struct mwifiex_adapter *adapter = priv->adapter; + s32 net = -1; + u32 i; + + if (!bssid) + return -1; + + dev_dbg(adapter->dev, "info: FindBSSID: Num of BSSIDs = %d\n", + adapter->num_in_scan_table); + + /* + * Look through the scan table for a compatible match. The ret return + * variable will be equal to the index in the scan table (greater + * than zero) if the network is compatible. The loop will continue + * past a matched bssid that is not compatible in case there is an + * AP with multiple SSIDs assigned to the same BSSID + */ + for (i = 0; net < 0 && i < adapter->num_in_scan_table; i++) { + if (!memcmp + (adapter->scan_table[i].mac_address, bssid, ETH_ALEN) + && mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, + (u8) adapter-> + scan_table[i]. + bss_band, + (u16) adapter-> + scan_table[i]. + channel)) { + switch (mode) { + case MWIFIEX_BSS_MODE_INFRA: + case MWIFIEX_BSS_MODE_IBSS: + net = mwifiex_is_network_compatible(priv, i, + mode); + break; + default: + net = i; + break; + } + } + } + + return net; +} + +/* + * This function inserts scan command node to the scan pending queue. + */ +void +mwifiex_queue_scan_cmd(struct mwifiex_private *priv, + struct cmd_ctrl_node *cmd_node) +{ + struct mwifiex_adapter *adapter = priv->adapter; + unsigned long flags; + + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + list_add_tail(&cmd_node->list, &adapter->scan_pending_q); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); +} + +/* + * This function finds an AP with specific ssid in the scan list. + */ +int mwifiex_find_best_network(struct mwifiex_private *priv, + struct mwifiex_ssid_bssid *req_ssid_bssid) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bssdescriptor *req_bss; + s32 i; + + memset(req_ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); + + i = mwifiex_find_best_network_in_list(priv); + + if (i >= 0) { + req_bss = &adapter->scan_table[i]; + memcpy(&req_ssid_bssid->ssid, &req_bss->ssid, + sizeof(struct mwifiex_802_11_ssid)); + memcpy((u8 *) &req_ssid_bssid->bssid, + (u8 *) &req_bss->mac_address, ETH_ALEN); + + /* Make sure we are in the right mode */ + if (priv->bss_mode == MWIFIEX_BSS_MODE_AUTO) + priv->bss_mode = req_bss->bss_mode; + } + + if (!req_ssid_bssid->ssid.ssid_len) + return -1; + + dev_dbg(adapter->dev, "info: Best network found = [%s], " + "[%pM]\n", req_ssid_bssid->ssid.ssid, + req_ssid_bssid->bssid); + + return 0; +} + +/* + * This function sends a scan command for all available channels to the + * firmware, filtered on a specific SSID. + */ +static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, + void *wait_buf, u16 action, + struct mwifiex_802_11_ssid *req_ssid, + struct mwifiex_scan_resp *scan_resp) +{ + struct mwifiex_adapter *adapter = priv->adapter; + int ret = 0; + struct mwifiex_user_scan_cfg *scan_cfg; + + if (!req_ssid) + return -1; + + if (action == HostCmd_ACT_GEN_GET) { + if (scan_resp) { + scan_resp->scan_table = + (u8 *) &priv->curr_bss_params.bss_descriptor; + scan_resp->num_in_scan_table = + adapter->num_in_scan_table; + } else { + ret = -1; + } + return ret; + } + + if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { + dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); + return ret; + } + + if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { + dev_dbg(adapter->dev, + "cmd: Scan is blocked during association...\n"); + return ret; + } + + mwifiex_scan_delete_ssid_table_entry(priv, req_ssid); + + scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); + if (!scan_cfg) { + dev_err(adapter->dev, "failed to alloc scan_cfg\n"); + return -1; + } + + memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, + req_ssid->ssid_len); + scan_cfg->keep_previous_scan = true; + + ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL); + + kfree(scan_cfg); + return ret; +} + +/* + * Sends IOCTL request to start a scan. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + * + * Scan command can be issued for both normal scan and specific SSID + * scan, depending upon whether an SSID is provided or not. + */ +int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, + struct mwifiex_802_11_ssid *req_ssid) +{ + int ret = 0; + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + + if (down_interruptible(&priv->async_sem)) { + dev_err(priv->adapter->dev, "%s: acquire semaphore\n", + __func__); + return -1; + } + priv->scan_pending_on_block = true; + + /* Allocate wait request buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) { + ret = -1; + goto done; + } + + if (req_ssid && req_ssid->ssid_len != 0) + /* Specific SSID scan */ + status = mwifiex_scan_specific_ssid(priv, wait, + HostCmd_ACT_GEN_SET, + req_ssid, NULL); + else + /* Normal scan */ + status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, + NULL, NULL); + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + if (status == -1) + ret = -1; +done: + if ((wait) && (status != -EINPROGRESS)) + kfree(wait); + if (ret == -1) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } + return ret; +} + +/* + * This function appends the vendor specific IE TLV to a buffer. + */ +int +mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, + u16 vsie_mask, u8 **buffer) +{ + int id, ret_len = 0; + struct mwifiex_ie_types_vendor_param_set *vs_param_set; + + if (!buffer) + return 0; + if (!(*buffer)) + return 0; + + /* + * Traverse through the saved vendor specific IE array and append + * the selected(scan/assoc/adhoc) IE as TLV to the command + */ + for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) { + if (priv->vs_ie[id].mask & vsie_mask) { + vs_param_set = + (struct mwifiex_ie_types_vendor_param_set *) + *buffer; + vs_param_set->header.type = + cpu_to_le16(TLV_TYPE_PASSTHROUGH); + vs_param_set->header.len = + cpu_to_le16((((u16) priv->vs_ie[id].ie[1]) + & 0x00FF) + 2); + memcpy(vs_param_set->ie, priv->vs_ie[id].ie, + le16_to_cpu(vs_param_set->header.len)); + *buffer += le16_to_cpu(vs_param_set->header.len) + + sizeof(struct mwifiex_ie_types_header); + ret_len += le16_to_cpu(vs_param_set->header.len) + + sizeof(struct mwifiex_ie_types_header); + } + } + return ret_len; +} + +/* + * This function saves a beacon buffer of the current BSS descriptor. + * + * The current beacon buffer is saved so that it can be restored in the + * following cases that makes the beacon buffer not to contain the current + * ssid's beacon buffer. + * - The current ssid was not found somehow in the last scan. + * - The current ssid was the last entry of the scan table and overloaded. + */ +void +mwifiex_save_curr_bcn(struct mwifiex_private *priv) +{ + struct mwifiex_bssdescriptor *curr_bss = + &priv->curr_bss_params.bss_descriptor; + + /* save the beacon buffer if it is not saved or updated */ + if ((priv->curr_bcn_buf == NULL) || + (priv->curr_bcn_size != curr_bss->beacon_buf_size) || + (memcmp(priv->curr_bcn_buf, curr_bss->beacon_buf, + curr_bss->beacon_buf_size))) { + + kfree(priv->curr_bcn_buf); + priv->curr_bcn_buf = NULL; + + priv->curr_bcn_size = curr_bss->beacon_buf_size; + if (!priv->curr_bcn_size) + return; + + priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size, + GFP_KERNEL); + if (!priv->curr_bcn_buf) { + dev_err(priv->adapter->dev, + "failed to alloc curr_bcn_buf\n"); + } else { + memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, + curr_bss->beacon_buf_size); + dev_dbg(priv->adapter->dev, + "info: current beacon saved %d\n", + priv->curr_bcn_size); + } + } +} + +/* + * This function frees the current BSS descriptor beacon buffer. + */ +void +mwifiex_free_curr_bcn(struct mwifiex_private *priv) +{ + kfree(priv->curr_bcn_buf); + priv->curr_bcn_buf = NULL; +} diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c new file mode 100644 index 000000000000..f21e5cd19839 --- /dev/null +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -0,0 +1,1770 @@ +/* + * Marvell Wireless LAN device driver: SDIO specific handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" +#include "sdio.h" + + +#define SDIO_VERSION "1.0" + +static struct mwifiex_if_ops sdio_ops; + +static struct semaphore add_remove_card_sem; + +/* + * SDIO probe. + * + * This function probes an mwifiex device and registers it. It allocates + * the card structure, enables SDIO function number and initiates the + * device registration and initialization procedure by adding a logical + * interface. + */ +static int +mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +{ + int ret = 0; + struct sdio_mmc_card *card = NULL; + + pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", + func->vendor, func->device, func->class, func->num); + + card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); + if (!card) { + pr_err("%s: failed to alloc memory\n", __func__); + return -ENOMEM; + } + + card->func = func; + + func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; + + sdio_claim_host(func); + ret = sdio_enable_func(func); + sdio_release_host(func); + + if (ret) { + pr_err("%s: failed to enable function\n", __func__); + return -EIO; + } + + if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops)) { + pr_err("%s: add card failed\n", __func__); + kfree(card); + sdio_claim_host(func); + ret = sdio_disable_func(func); + sdio_release_host(func); + ret = -1; + } + + return ret; +} + +/* + * SDIO remove. + * + * This function removes the interface and frees up the card structure. + */ +static void +mwifiex_sdio_remove(struct sdio_func *func) +{ + struct sdio_mmc_card *card; + + pr_debug("info: SDIO func num=%d\n", func->num); + + if (func) { + card = sdio_get_drvdata(func); + if (card) { + mwifiex_remove_card(card->adapter, + &add_remove_card_sem); + kfree(card); + } + } +} + +/* + * SDIO suspend. + * + * Kernel needs to suspend all functions separately. Therefore all + * registered functions must have drivers with suspend and resume + * methods. Failing that the kernel simply removes the whole card. + * + * If already not suspended, this function allocates and sends a host + * sleep activate request to the firmware and turns off the traffic. + */ +static int mwifiex_sdio_suspend(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + struct sdio_mmc_card *card; + struct mwifiex_adapter *adapter = NULL; + mmc_pm_flag_t pm_flag = 0; + int hs_actived = 0; + int i; + int ret = 0; + + if (func) { + pm_flag = sdio_get_host_pm_caps(func); + pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", + sdio_func_id(func), pm_flag); + if (!(pm_flag & MMC_PM_KEEP_POWER)) { + pr_err("%s: cannot remain alive while host is" + " suspended\n", sdio_func_id(func)); + return -ENOSYS; + } + + card = sdio_get_drvdata(func); + if (!card || !card->adapter) { + pr_err("suspend: invalid card or adapter\n"); + return 0; + } + } else { + pr_err("suspend: sdio_func is not specified\n"); + return 0; + } + + adapter = card->adapter; + + /* Enable the Host Sleep */ + hs_actived = mwifiex_enable_hs(adapter); + if (hs_actived) { + pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + } + + /* Indicate device suspended */ + adapter->is_suspended = true; + + for (i = 0; i < adapter->priv_num; i++) + netif_carrier_off(adapter->priv[i]->netdev); + + return ret; +} + +/* + * SDIO resume. + * + * Kernel needs to suspend all functions separately. Therefore all + * registered functions must have drivers with suspend and resume + * methods. Failing that the kernel simply removes the whole card. + * + * If already not resumed, this function turns on the traffic and + * sends a host sleep cancel request to the firmware. + */ +static int mwifiex_sdio_resume(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + struct sdio_mmc_card *card; + struct mwifiex_adapter *adapter = NULL; + mmc_pm_flag_t pm_flag = 0; + int i; + + if (func) { + pm_flag = sdio_get_host_pm_caps(func); + card = sdio_get_drvdata(func); + if (!card || !card->adapter) { + pr_err("resume: invalid card or adapter\n"); + return 0; + } + } else { + pr_err("resume: sdio_func is not specified\n"); + return 0; + } + + adapter = card->adapter; + + if (!adapter->is_suspended) { + dev_warn(adapter->dev, "device already resumed\n"); + return 0; + } + + adapter->is_suspended = false; + + for (i = 0; i < adapter->priv_num; i++) + if (adapter->priv[i]->media_connected) + netif_carrier_on(adapter->priv[i]->netdev); + + /* Disable Host Sleep */ + mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), + MWIFIEX_NO_WAIT); + + return 0; +} + +/* Device ID for SD8787 */ +#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) + +/* WLAN IDs */ +static const struct sdio_device_id mwifiex_ids[] = { + {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)}, + {}, +}; + +MODULE_DEVICE_TABLE(sdio, mwifiex_ids); + +static const struct dev_pm_ops mwifiex_sdio_pm_ops = { + .suspend = mwifiex_sdio_suspend, + .resume = mwifiex_sdio_resume, +}; + +static struct sdio_driver mwifiex_sdio = { + .name = "mwifiex_sdio", + .id_table = mwifiex_ids, + .probe = mwifiex_sdio_probe, + .remove = mwifiex_sdio_remove, + .drv = { + .owner = THIS_MODULE, + .pm = &mwifiex_sdio_pm_ops, + } +}; + +/* + * This function writes data into SDIO card register. + */ +static int +mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = -1; + + sdio_claim_host(card->func); + sdio_writeb(card->func, (u8) data, reg, &ret); + sdio_release_host(card->func); + + return ret; +} + +/* + * This function reads data from SDIO card register. + */ +static int +mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = -1; + u8 val; + + sdio_claim_host(card->func); + val = sdio_readb(card->func, reg, &ret); + sdio_release_host(card->func); + + *data = val; + + return ret; +} + +/* + * This function writes multiple data into SDIO card memory. + * + * This does not work in suspended mode. + */ +static int +mwifiex_write_data_sync(struct mwifiex_adapter *adapter, + u8 *buffer, u32 pkt_len, u32 port, u32 timeout) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = -1; + u8 blk_mode = + (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; + u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; + u32 blk_cnt = + (blk_mode == + BLOCK_MODE) ? (pkt_len / + MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len; + u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); + + if (adapter->is_suspended) { + dev_err(adapter->dev, + "%s: not allowed while suspended\n", __func__); + return -1; + } + + sdio_claim_host(card->func); + + if (!sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size)) + ret = 0; + + sdio_release_host(card->func); + + return ret; +} + +/* + * This function reads multiple data from SDIO card memory. + */ +static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, + u8 *buffer, u32 len, + u32 port, u32 timeout, u8 claim) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = -1; + u8 blk_mode = + (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; + u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; + u32 blk_cnt = + (blk_mode == + BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len; + u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); + + if (claim) + sdio_claim_host(card->func); + + if (!sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size)) + ret = 0; + + if (claim) + sdio_release_host(card->func); + + return ret; +} + +/* + * This function wakes up the card. + * + * A host power up command is written to the card configuration + * register to wake up the card. + */ +static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) +{ + int ret; + + dev_dbg(adapter->dev, "event: wakeup device...\n"); + ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP); + + return ret; +} + +/* + * This function is called after the card has woken up. + * + * The card configuration register is reset. + */ +static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) +{ + int ret; + + dev_dbg(adapter->dev, "cmd: wakeup device completed\n"); + ret = mwifiex_write_reg(adapter, CONFIGURATION_REG, 0); + + return ret; +} + +/* + * This function initializes the IO ports. + * + * The following operations are performed - + * - Read the IO ports (0, 1 and 2) + * - Set host interrupt Reset-To-Read to clear + * - Set auto re-enable interrupt + */ +static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter) +{ + u32 reg; + + adapter->ioport = 0; + + /* Read the IO port */ + if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, ®)) + adapter->ioport |= (reg & 0xff); + else + return -1; + + if (!mwifiex_read_reg(adapter, IO_PORT_1_REG, ®)) + adapter->ioport |= ((reg & 0xff) << 8); + else + return -1; + + if (!mwifiex_read_reg(adapter, IO_PORT_2_REG, ®)) + adapter->ioport |= ((reg & 0xff) << 16); + else + return -1; + + pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport); + + /* Set Host interrupt reset to read to clear */ + if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, ®)) + mwifiex_write_reg(adapter, HOST_INT_RSR_REG, + reg | SDIO_INT_MASK); + else + return -1; + + /* Dnld/Upld ready set to auto reset */ + if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, ®)) + mwifiex_write_reg(adapter, CARD_MISC_CFG_REG, + reg | AUTO_RE_ENABLE_INT); + else + return -1; + + return 0; +} + +/* + * This function sends data to the card. + */ +static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, + u8 *payload, u32 pkt_len, u32 port) +{ + u32 i = 0; + int ret = 0; + + do { + ret = mwifiex_write_data_sync(adapter, payload, pkt_len, + port, 0); + if (ret) { + i++; + dev_err(adapter->dev, "host_to_card, write iomem" + " (%d) failed: %d\n", i, ret); + if (mwifiex_write_reg(adapter, + CONFIGURATION_REG, 0x04)) + dev_err(adapter->dev, "write CFG reg failed\n"); + + ret = -1; + if (i > MAX_WRITE_IOMEM_RETRY) + return ret; + } + } while (ret == -1); + + return ret; +} + +/* + * This function gets the read port. + * + * If control port bit is set in MP read bitmap, the control port + * is returned, otherwise the current read port is returned and + * the value is increased (provided it does not reach the maximum + * limit, in which case it is reset to 1) + */ +static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) +{ + struct sdio_mmc_card *card = adapter->card; + u16 rd_bitmap = card->mp_rd_bitmap; + + dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap); + + if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK))) + return -1; + + if (card->mp_rd_bitmap & CTRL_PORT_MASK) { + card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); + *port = CTRL_PORT; + dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", + *port, card->mp_rd_bitmap); + } else { + if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { + card->mp_rd_bitmap &= + (u16) (~(1 << card->curr_rd_port)); + *port = card->curr_rd_port; + + if (++card->curr_rd_port == MAX_PORT) + card->curr_rd_port = 1; + } else { + return -1; + } + + dev_dbg(adapter->dev, + "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", + *port, rd_bitmap, card->mp_rd_bitmap); + } + return 0; +} + +/* + * This function gets the write port for data. + * + * The current write port is returned if available and the value is + * increased (provided it does not reach the maximum limit, in which + * case it is reset to 1) + */ +static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) +{ + struct sdio_mmc_card *card = adapter->card; + u16 wr_bitmap = card->mp_wr_bitmap; + + dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap); + + if (!(wr_bitmap & card->mp_data_port_mask)) + return -1; + + if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { + card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port)); + *port = card->curr_wr_port; + if (++card->curr_wr_port == card->mp_end_port) + card->curr_wr_port = 1; + } else { + adapter->data_sent = true; + return -EBUSY; + } + + if (*port == CTRL_PORT) { + dev_err(adapter->dev, "invalid data port=%d cur port=%d" + " mp_wr_bitmap=0x%04x -> 0x%04x\n", + *port, card->curr_wr_port, wr_bitmap, + card->mp_wr_bitmap); + return -1; + } + + dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", + *port, wr_bitmap, card->mp_wr_bitmap); + + return 0; +} + +/* + * This function polls the card status. + */ +static int +mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) +{ + u32 tries; + u32 cs = 0; + + for (tries = 0; tries < MAX_POLL_TRIES; tries++) { + if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs)) + break; + else if ((cs & bits) == bits) + return 0; + + udelay(10); + } + + dev_err(adapter->dev, "poll card status failed, tries = %d\n", + tries); + return -1; +} + +/* + * This function reads the firmware status. + */ +static int +mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) +{ + u32 fws0 = 0, fws1 = 0; + + if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0)) + return -1; + + if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1)) + return -1; + + *dat = (u16) ((fws1 << 8) | fws0); + + return 0; +} + +/* + * This function disables the host interrupt. + * + * The host interrupt mask is read, the disable bit is reset and + * written back to the card host interrupt mask register. + */ +static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) +{ + u32 host_int_mask = 0; + + /* Read back the host_int_mask register */ + if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask)) + return -1; + + /* Update with the mask and write back to the register */ + host_int_mask &= ~HOST_INT_DISABLE; + + if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) { + dev_err(adapter->dev, "disable host interrupt failed\n"); + return -1; + } + + return 0; +} + +/* + * This function enables the host interrupt. + * + * The host interrupt enable mask is written to the card + * host interrupt mask register. + */ +static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) +{ + /* Simply write the mask to the register */ + if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) { + dev_err(adapter->dev, "enable host interrupt failed\n"); + return -1; + } + return 0; +} + +/* + * This function sends a data buffer to the card. + */ +static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, + u32 *type, u8 *buffer, + u32 npayload, u32 ioport) +{ + int ret = 0; + u32 nb; + + if (!buffer) { + dev_err(adapter->dev, "%s: buffer is NULL\n", __func__); + return -1; + } + + ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1); + + if (ret) { + dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, + ret); + return -1; + } + + nb = le16_to_cpu(*(__le16 *) (buffer)); + if (nb > npayload) { + dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n", + __func__, nb, npayload); + return -1; + } + + *type = le16_to_cpu(*(__le16 *) (buffer + 2)); + + return ret; +} + +/* + * This function downloads the firmware to the card. + * + * Firmware is downloaded to the card in blocks. Every block download + * is tested for CRC errors, and retried a number of times before + * returning failure. + */ +static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, + struct mwifiex_fw_image *fw) +{ + int ret = 0; + u8 *firmware = fw->fw_buf; + u32 firmware_len = fw->fw_len; + u32 offset = 0; + u32 base0, base1; + u8 *fwbuf; + u16 len = 0; + u32 txlen = 0, tx_blocks = 0, tries = 0; + u32 i = 0; + + if (!firmware_len) { + dev_err(adapter->dev, "firmware image not found!" + " Terminating download\n"); + return -1; + } + + dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", + firmware_len); + + /* Assume that the allocated buffer is 8-byte aligned */ + fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); + if (!fwbuf) { + dev_err(adapter->dev, "unable to alloc buffer for firmware." + " Terminating download\n"); + return -1; + } + + /* Perform firmware data transfer */ + do { + /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY + bits */ + ret = mwifiex_sdio_poll_card_status(adapter, CARD_IO_READY | + DN_LD_CARD_RDY); + if (ret) { + dev_err(adapter->dev, "FW download with helper:" + " poll status timeout @ %d\n", offset); + goto done; + } + + /* More data? */ + if (offset >= firmware_len) + break; + + for (tries = 0; tries < MAX_POLL_TRIES; tries++) { + ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, + &base0); + if (ret) { + dev_err(adapter->dev, "dev BASE0 register read" + " failed: base0=0x%04X(%d). Terminating " + "download\n", base0, base0); + goto done; + } + ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, + &base1); + if (ret) { + dev_err(adapter->dev, "dev BASE1 register read" + " failed: base1=0x%04X(%d). Terminating " + "download\n", base1, base1); + goto done; + } + len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); + + if (len) + break; + + udelay(10); + } + + if (!len) { + break; + } else if (len > MWIFIEX_UPLD_SIZE) { + dev_err(adapter->dev, "FW download failed @ %d," + " invalid length %d\n", offset, len); + ret = -1; + goto done; + } + + txlen = len; + + if (len & BIT(0)) { + i++; + if (i > MAX_WRITE_IOMEM_RETRY) { + dev_err(adapter->dev, "FW download failed @" + " %d, over max retry count\n", offset); + ret = -1; + goto done; + } + dev_err(adapter->dev, "CRC indicated by the helper:" + " len = 0x%04X, txlen = %d\n", len, txlen); + len &= ~BIT(0); + /* Setting this to 0 to resend from same offset */ + txlen = 0; + } else { + i = 0; + + /* Set blocksize to transfer - checking for last + block */ + if (firmware_len - offset < txlen) + txlen = firmware_len - offset; + + tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - + 1) / MWIFIEX_SDIO_BLOCK_SIZE; + + /* Copy payload to buffer */ + memmove(fwbuf, &firmware[offset], txlen); + } + + ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * + MWIFIEX_SDIO_BLOCK_SIZE, + adapter->ioport, 0); + if (ret) { + dev_err(adapter->dev, "FW download, write iomem (%d)" + " failed @ %d\n", i, offset); + if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) + dev_err(adapter->dev, "write CFG reg failed\n"); + + ret = -1; + goto done; + } + + offset += txlen; + } while (true); + + dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", + offset); + + ret = 0; +done: + kfree(fwbuf); + return ret; +} + +/* + * This function checks the firmware status in card. + * + * The winner interface is also determined by this function. + */ +static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, + u32 poll_num, int *winner) +{ + int ret = 0; + u16 firmware_stat; + u32 tries; + u32 winner_status; + + /* Wait for firmware initialization event */ + for (tries = 0; tries < poll_num; tries++) { + ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat); + if (ret) + continue; + if (firmware_stat == FIRMWARE_READY) { + ret = 0; + break; + } else { + mdelay(100); + ret = -1; + } + } + + if (winner && ret) { + if (mwifiex_read_reg + (adapter, CARD_FW_STATUS0_REG, &winner_status)) + winner_status = 0; + + if (winner_status) + *winner = 0; + else + *winner = 1; + } + return ret; +} + +/* + * This function reads the interrupt status from card. + */ +static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + u32 sdio_ireg = 0; + unsigned long flags; + + if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, + REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0, + 0)) { + dev_err(adapter->dev, "read mp_regs failed\n"); + return; + } + + sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG]; + if (sdio_ireg) { + /* + * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS + * Clear the interrupt status register + */ + dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg); + spin_lock_irqsave(&adapter->int_lock, flags); + adapter->int_status |= sdio_ireg; + spin_unlock_irqrestore(&adapter->int_lock, flags); + } + + return; +} + +/* + * SDIO interrupt handler. + * + * This function reads the interrupt status from firmware and assigns + * the main process in workqueue which will handle the interrupt. + */ +static void +mwifiex_sdio_interrupt(struct sdio_func *func) +{ + struct mwifiex_adapter *adapter; + struct sdio_mmc_card *card; + + card = sdio_get_drvdata(func); + if (!card || !card->adapter) { + pr_debug("int: func=%p card=%p adapter=%p\n", + func, card, card ? card->adapter : NULL); + return; + } + adapter = card->adapter; + + if (adapter->surprise_removed) + return; + + if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP) + adapter->ps_state = PS_STATE_AWAKE; + + mwifiex_interrupt_status(adapter); + queue_work(adapter->workqueue, &adapter->main_work); + + return; +} + +/* + * This function decodes a received packet. + * + * Based on the type, the packet is treated as either a data, or + * a command response, or an event, and the correct handler + * function is invoked. + */ +static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb, u32 upld_typ) +{ + u8 *cmd_buf; + + skb_pull(skb, INTF_HEADER_LEN); + + switch (upld_typ) { + case MWIFIEX_TYPE_DATA: + dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n"); + mwifiex_handle_rx_packet(adapter, skb); + break; + + case MWIFIEX_TYPE_CMD: + dev_dbg(adapter->dev, "info: --- Rx: Cmd Response ---\n"); + /* take care of curr_cmd = NULL case */ + if (!adapter->curr_cmd) { + cmd_buf = adapter->upld_buf; + + if (adapter->ps_state == PS_STATE_SLEEP_CFM) + mwifiex_process_sleep_confirm_resp(adapter, + skb->data, skb->len); + + memcpy(cmd_buf, skb->data, min_t(u32, + MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + + dev_kfree_skb_any(skb); + } else { + adapter->cmd_resp_received = true; + adapter->curr_cmd->resp_skb = skb; + } + break; + + case MWIFIEX_TYPE_EVENT: + dev_dbg(adapter->dev, "info: --- Rx: Event ---\n"); + adapter->event_cause = *(u32 *) skb->data; + + skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN); + + if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) + memcpy(adapter->event_body, skb->data, skb->len); + + /* event cause has been saved to adapter->event_cause */ + adapter->event_received = true; + adapter->event_skb = skb; + + break; + + default: + dev_err(adapter->dev, "unknown upload type %#x\n", upld_typ); + dev_kfree_skb_any(skb); + break; + } + + return 0; +} + +/* + * This function transfers received packets from card to driver, performing + * aggregation if required. + * + * For data received on control port, or if aggregation is disabled, the + * received buffers are uploaded as separate packets. However, if aggregation + * is enabled and required, the buffers are copied onto an aggregation buffer, + * provided there is space left, processed and finally uploaded. + */ +static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, + struct sk_buff *skb, u8 port) +{ + struct sdio_mmc_card *card = adapter->card; + s32 f_do_rx_aggr = 0; + s32 f_do_rx_cur = 0; + s32 f_aggr_cur = 0; + struct sk_buff *skb_deaggr; + u32 pind = 0; + u32 pkt_len, pkt_type = 0; + u8 *curr_ptr; + u32 rx_len = skb->len; + + if (port == CTRL_PORT) { + /* Read the command Resp without aggr */ + dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " + "response\n", __func__); + + f_do_rx_cur = 1; + goto rx_curr_single; + } + + if (!card->mpa_rx.enabled) { + dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", + __func__); + + f_do_rx_cur = 1; + goto rx_curr_single; + } + + if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) { + /* Some more data RX pending */ + dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); + + if (MP_RX_AGGR_IN_PROGRESS(card)) { + if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) { + f_aggr_cur = 1; + } else { + /* No room in Aggr buf, do rx aggr now */ + f_do_rx_aggr = 1; + f_do_rx_cur = 1; + } + } else { + /* Rx aggr not in progress */ + f_aggr_cur = 1; + } + + } else { + /* No more data RX pending */ + dev_dbg(adapter->dev, "info: %s: last packet\n", __func__); + + if (MP_RX_AGGR_IN_PROGRESS(card)) { + f_do_rx_aggr = 1; + if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) + f_aggr_cur = 1; + else + /* No room in Aggr buf, do rx aggr now */ + f_do_rx_cur = 1; + } else { + f_do_rx_cur = 1; + } + } + + if (f_aggr_cur) { + dev_dbg(adapter->dev, "info: current packet aggregation\n"); + /* Curr pkt can be aggregated */ + MP_RX_AGGR_SETUP(card, skb, port); + + if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || + MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { + dev_dbg(adapter->dev, "info: %s: aggregated packet " + "limit reached\n", __func__); + /* No more pkts allowed in Aggr buf, rx it */ + f_do_rx_aggr = 1; + } + } + + if (f_do_rx_aggr) { + /* do aggr RX now */ + dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", + card->mpa_rx.pkt_cnt); + + if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, + card->mpa_rx.buf_len, + (adapter->ioport | 0x1000 | + (card->mpa_rx.ports << 4)) + + card->mpa_rx.start_port, 0, 1)) + return -1; + + curr_ptr = card->mpa_rx.buf; + + for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) { + + /* get curr PKT len & type */ + pkt_len = *(u16 *) &curr_ptr[0]; + pkt_type = *(u16 *) &curr_ptr[2]; + + /* copy pkt to deaggr buf */ + skb_deaggr = card->mpa_rx.skb_arr[pind]; + + if ((pkt_type == MWIFIEX_TYPE_DATA) && (pkt_len <= + card->mpa_rx.len_arr[pind])) { + + memcpy(skb_deaggr->data, curr_ptr, pkt_len); + + skb_trim(skb_deaggr, pkt_len); + + /* Process de-aggr packet */ + mwifiex_decode_rx_packet(adapter, skb_deaggr, + pkt_type); + } else { + dev_err(adapter->dev, "wrong aggr pkt:" + " type=%d len=%d max_len=%d\n", + pkt_type, pkt_len, + card->mpa_rx.len_arr[pind]); + dev_kfree_skb_any(skb_deaggr); + } + curr_ptr += card->mpa_rx.len_arr[pind]; + } + MP_RX_AGGR_BUF_RESET(card); + } + +rx_curr_single: + if (f_do_rx_cur) { + dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n", + port, rx_len); + + if (mwifiex_sdio_card_to_host(adapter, &pkt_type, + skb->data, skb->len, + adapter->ioport + port)) + return -1; + + mwifiex_decode_rx_packet(adapter, skb, pkt_type); + } + + return 0; +} + +/* + * This function checks the current interrupt status. + * + * The following interrupts are checked and handled by this function - + * - Data sent + * - Command sent + * - Packets received + * + * Since the firmware does not generate download ready interrupt if the + * port updated is command port only, command sent interrupt checking + * should be done manually, and for every SDIO interrupt. + * + * In case of Rx packets received, the packets are uploaded from card to + * host and processed accordingly. + */ +static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = 0; + u8 sdio_ireg; + struct sk_buff *skb = NULL; + u8 port = CTRL_PORT; + u32 len_reg_l, len_reg_u; + u32 rx_blocks; + u16 rx_len; + unsigned long flags; + + spin_lock_irqsave(&adapter->int_lock, flags); + sdio_ireg = adapter->int_status; + adapter->int_status = 0; + spin_unlock_irqrestore(&adapter->int_lock, flags); + + if (!sdio_ireg) + return ret; + + if (sdio_ireg & DN_LD_HOST_INT_STATUS) { + card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; + card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; + dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", + card->mp_wr_bitmap); + if (adapter->data_sent && + (card->mp_wr_bitmap & card->mp_data_port_mask)) { + dev_dbg(adapter->dev, + "info: <--- Tx DONE Interrupt --->\n"); + adapter->data_sent = false; + } + } + + /* As firmware will not generate download ready interrupt if the port + updated is command port only, cmd_sent should be done for any SDIO + interrupt. */ + if (adapter->cmd_sent) { + /* Check if firmware has attach buffer at command port and + update just that in wr_bit_map. */ + card->mp_wr_bitmap |= + (u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK; + if (card->mp_wr_bitmap & CTRL_PORT_MASK) + adapter->cmd_sent = false; + } + + dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", + adapter->cmd_sent, adapter->data_sent); + if (sdio_ireg & UP_LD_HOST_INT_STATUS) { + card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; + card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; + dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", + card->mp_rd_bitmap); + + while (true) { + ret = mwifiex_get_rd_port(adapter, &port); + if (ret) { + dev_dbg(adapter->dev, + "info: no more rd_port available\n"); + break; + } + len_reg_l = RD_LEN_P0_L + (port << 1); + len_reg_u = RD_LEN_P0_U + (port << 1); + rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; + rx_len |= (u16) card->mp_regs[len_reg_l]; + dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", + port, rx_len); + rx_blocks = + (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - + 1) / MWIFIEX_SDIO_BLOCK_SIZE; + if (rx_len <= INTF_HEADER_LEN + || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > + MWIFIEX_RX_DATA_BUF_SIZE) { + dev_err(adapter->dev, "invalid rx_len=%d\n", + rx_len); + return -1; + } + rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); + + skb = dev_alloc_skb(rx_len); + + if (!skb) { + dev_err(adapter->dev, "%s: failed to alloc skb", + __func__); + return -1; + } + + skb_put(skb, rx_len); + + dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", + rx_len, skb->len); + + if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, + port)) { + u32 cr = 0; + + dev_err(adapter->dev, "card_to_host_mpa failed:" + " int status=%#x\n", sdio_ireg); + if (mwifiex_read_reg(adapter, + CONFIGURATION_REG, &cr)) + dev_err(adapter->dev, + "read CFG reg failed\n"); + + dev_dbg(adapter->dev, + "info: CFG reg val = %d\n", cr); + if (mwifiex_write_reg(adapter, + CONFIGURATION_REG, + (cr | 0x04))) + dev_err(adapter->dev, + "write CFG reg failed\n"); + + dev_dbg(adapter->dev, "info: write success\n"); + if (mwifiex_read_reg(adapter, + CONFIGURATION_REG, &cr)) + dev_err(adapter->dev, + "read CFG reg failed\n"); + + dev_dbg(adapter->dev, + "info: CFG reg val =%x\n", cr); + dev_kfree_skb_any(skb); + return -1; + } + } + } + + return 0; +} + +/* + * This function aggregates transmission buffers in driver and downloads + * the aggregated packet to card. + * + * The individual packets are aggregated by copying into an aggregation + * buffer and then downloaded to the card. Previous unsent packets in the + * aggregation buffer are pre-copied first before new packets are added. + * Aggregation is done till there is space left in the aggregation buffer, + * or till new packets are available. + * + * The function will only download the packet to the card when aggregation + * stops, otherwise it will just aggregate the packet in aggregation buffer + * and return. + */ +static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, + u8 *payload, u32 pkt_len, u8 port, + u32 next_pkt_len) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = 0; + s32 f_send_aggr_buf = 0; + s32 f_send_cur_buf = 0; + s32 f_precopy_cur_buf = 0; + s32 f_postcopy_cur_buf = 0; + + if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { + dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", + __func__); + + f_send_cur_buf = 1; + goto tx_curr_single; + } + + if (next_pkt_len) { + /* More pkt in TX queue */ + dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", + __func__); + + if (MP_TX_AGGR_IN_PROGRESS(card)) { + if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && + MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) { + f_precopy_cur_buf = 1; + + if (!(card->mp_wr_bitmap & + (1 << card->curr_wr_port)) + || !MP_TX_AGGR_BUF_HAS_ROOM( + card, next_pkt_len)) + f_send_aggr_buf = 1; + } else { + /* No room in Aggr buf, send it */ + f_send_aggr_buf = 1; + + if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) || + !(card->mp_wr_bitmap & + (1 << card->curr_wr_port))) + f_send_cur_buf = 1; + else + f_postcopy_cur_buf = 1; + } + } else { + if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) + && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) + f_precopy_cur_buf = 1; + else + f_send_cur_buf = 1; + } + } else { + /* Last pkt in TX queue */ + dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", + __func__); + + if (MP_TX_AGGR_IN_PROGRESS(card)) { + /* some packs in Aggr buf already */ + f_send_aggr_buf = 1; + + if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) + f_precopy_cur_buf = 1; + else + /* No room in Aggr buf, send it */ + f_send_cur_buf = 1; + } else { + f_send_cur_buf = 1; + } + } + + if (f_precopy_cur_buf) { + dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", + __func__); + MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); + + if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || + MP_TX_AGGR_PORT_LIMIT_REACHED(card)) + /* No more pkts allowed in Aggr buf, send it */ + f_send_aggr_buf = 1; + } + + if (f_send_aggr_buf) { + dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", + __func__, + card->mpa_tx.start_port, card->mpa_tx.ports); + ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, + card->mpa_tx.buf_len, + (adapter->ioport | 0x1000 | + (card->mpa_tx.ports << 4)) + + card->mpa_tx.start_port); + + MP_TX_AGGR_BUF_RESET(card); + } + +tx_curr_single: + if (f_send_cur_buf) { + dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", + __func__, port); + ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, + adapter->ioport + port); + } + + if (f_postcopy_cur_buf) { + dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", + __func__); + MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); + } + + return ret; +} + +/* + * This function downloads data from driver to card. + * + * Both commands and data packets are transferred to the card by this + * function. + * + * This function adds the SDIO specific header to the front of the buffer + * before transferring. The header contains the length of the packet and + * the type. The firmware handles the packets based upon this set type. + */ +static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, + u8 type, u8 *payload, u32 pkt_len, + struct mwifiex_tx_param *tx_param) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = 0; + u32 buf_block_len; + u32 blk_size; + u8 port = CTRL_PORT; + + /* Allocate buffer and copy payload */ + blk_size = MWIFIEX_SDIO_BLOCK_SIZE; + buf_block_len = (pkt_len + blk_size - 1) / blk_size; + *(u16 *) &payload[0] = (u16) pkt_len; + *(u16 *) &payload[2] = type; + + /* + * This is SDIO specific header + * u16 length, + * u16 type (MWIFIEX_TYPE_DATA = 0, MWIFIEX_TYPE_CMD = 1, + * MWIFIEX_TYPE_EVENT = 3) + */ + if (type == MWIFIEX_TYPE_DATA) { + ret = mwifiex_get_wr_port_data(adapter, &port); + if (ret) { + dev_err(adapter->dev, "%s: no wr_port available\n", + __func__); + return ret; + } + } else { + adapter->cmd_sent = true; + /* Type must be MWIFIEX_TYPE_CMD */ + + if (pkt_len <= INTF_HEADER_LEN || + pkt_len > MWIFIEX_UPLD_SIZE) + dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", + __func__, payload, pkt_len); + } + + /* Transfer data to card */ + pkt_len = buf_block_len * blk_size; + + if (tx_param) + ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, + port, tx_param->next_pkt_len); + else + ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, + port, 0); + + if (ret) { + if (type == MWIFIEX_TYPE_CMD) + adapter->cmd_sent = false; + if (type == MWIFIEX_TYPE_DATA) + adapter->data_sent = false; + } else { + if (type == MWIFIEX_TYPE_DATA) { + if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port))) + adapter->data_sent = true; + else + adapter->data_sent = false; + } + } + + return ret; +} + +/* + * This function allocates the MPA Tx and Rx buffers. + */ +static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter, + u32 mpa_tx_buf_size, u32 mpa_rx_buf_size) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = 0; + + card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL); + if (!card->mpa_tx.buf) { + dev_err(adapter->dev, "could not alloc buffer for MP-A TX\n"); + ret = -1; + goto error; + } + + card->mpa_tx.buf_size = mpa_tx_buf_size; + + card->mpa_rx.buf = kzalloc(mpa_rx_buf_size, GFP_KERNEL); + if (!card->mpa_rx.buf) { + dev_err(adapter->dev, "could not alloc buffer for MP-A RX\n"); + ret = -1; + goto error; + } + + card->mpa_rx.buf_size = mpa_rx_buf_size; + +error: + if (ret) { + kfree(card->mpa_tx.buf); + kfree(card->mpa_rx.buf); + } + + return ret; +} + +/* + * This function unregisters the SDIO device. + * + * The SDIO IRQ is released, the function is disabled and driver + * data is set to null. + */ +static void +mwifiex_unregister_dev(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + + if (adapter->card) { + /* Release the SDIO IRQ */ + sdio_claim_host(card->func); + sdio_release_irq(card->func); + sdio_disable_func(card->func); + sdio_release_host(card->func); + sdio_set_drvdata(card->func, NULL); + } +} + +/* + * This function registers the SDIO device. + * + * SDIO IRQ is claimed, block size is set and driver data is initialized. + */ +static int mwifiex_register_dev(struct mwifiex_adapter *adapter) +{ + int ret = 0; + struct sdio_mmc_card *card = adapter->card; + struct sdio_func *func = card->func; + + /* save adapter pointer in card */ + card->adapter = adapter; + + sdio_claim_host(func); + + /* Request the SDIO IRQ */ + ret = sdio_claim_irq(func, mwifiex_sdio_interrupt); + if (ret) { + pr_err("claim irq failed: ret=%d\n", ret); + goto disable_func; + } + + /* Set block size */ + ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); + if (ret) { + pr_err("cannot set SDIO block size\n"); + ret = -1; + goto release_irq; + } + + sdio_release_host(func); + sdio_set_drvdata(func, card); + + adapter->dev = &func->dev; + + return 0; + +release_irq: + sdio_release_irq(func); +disable_func: + sdio_disable_func(func); + sdio_release_host(func); + adapter->card = NULL; + + return -1; +} + +/* + * This function initializes the SDIO driver. + * + * The following initializations steps are followed - + * - Read the Host interrupt status register to acknowledge + * the first interrupt got from bootloader + * - Disable host interrupt mask register + * - Get SDIO port + * - Get revision ID + * - Initialize SDIO variables in card + * - Allocate MP registers + * - Allocate MPA Tx and Rx buffers + */ +static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + int ret; + u32 sdio_ireg = 0; + + /* + * Read the HOST_INT_STATUS_REG for ACK the first interrupt got + * from the bootloader. If we don't do this we get a interrupt + * as soon as we register the irq. + */ + mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg); + + /* Disable host interrupt mask register for SDIO */ + mwifiex_sdio_disable_host_int(adapter); + + /* Get SDIO ioport */ + mwifiex_init_sdio_ioport(adapter); + + /* Get revision ID */ +#define REV_ID_REG 0x5c + mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id); + + /* Initialize SDIO variables in card */ + card->mp_rd_bitmap = 0; + card->mp_wr_bitmap = 0; + card->curr_rd_port = 1; + card->curr_wr_port = 1; + + card->mp_data_port_mask = DATA_PORT_MASK; + + card->mpa_tx.buf_len = 0; + card->mpa_tx.pkt_cnt = 0; + card->mpa_tx.start_port = 0; + + card->mpa_tx.enabled = 0; + card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; + + card->mpa_rx.buf_len = 0; + card->mpa_rx.pkt_cnt = 0; + card->mpa_rx.start_port = 0; + + card->mpa_rx.enabled = 0; + card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; + + /* Allocate buffers for SDIO MP-A */ + card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL); + if (!card->mp_regs) { + dev_err(adapter->dev, "failed to alloc mp_regs\n"); + return -1; + } + + ret = mwifiex_alloc_sdio_mpa_buffers(adapter, + SDIO_MP_TX_AGGR_DEF_BUF_SIZE, + SDIO_MP_RX_AGGR_DEF_BUF_SIZE); + if (ret) { + dev_err(adapter->dev, "failed to alloc sdio mp-a buffers\n"); + kfree(card->mp_regs); + return -1; + } + + return ret; +} + +/* + * This function resets the MPA Tx and Rx buffers. + */ +static void mwifiex_cleanup_mpa_buf(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + + MP_TX_AGGR_BUF_RESET(card); + MP_RX_AGGR_BUF_RESET(card); +} + +/* + * This function cleans up the allocated card buffers. + * + * The following are freed by this function - + * - MP registers + * - MPA Tx buffer + * - MPA Rx buffer + */ +static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + + kfree(card->mp_regs); + kfree(card->mpa_tx.buf); + kfree(card->mpa_rx.buf); +} + +/* + * This function updates the MP end port in card. + */ +static void +mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) +{ + struct sdio_mmc_card *card = adapter->card; + int i; + + card->mp_end_port = port; + + card->mp_data_port_mask = DATA_PORT_MASK; + + for (i = 1; i <= MAX_PORT - card->mp_end_port; i++) + card->mp_data_port_mask &= ~(1 << (MAX_PORT - i)); + + card->curr_wr_port = 1; + + dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", + port, card->mp_data_port_mask); +} + +static struct mwifiex_if_ops sdio_ops = { + .init_if = mwifiex_init_sdio, + .cleanup_if = mwifiex_cleanup_sdio, + .check_fw_status = mwifiex_check_fw_status, + .prog_fw = mwifiex_prog_fw_w_helper, + .register_dev = mwifiex_register_dev, + .unregister_dev = mwifiex_unregister_dev, + .enable_int = mwifiex_sdio_enable_host_int, + .process_int_status = mwifiex_process_int_status, + .host_to_card = mwifiex_sdio_host_to_card, + .wakeup = mwifiex_pm_wakeup_card, + .wakeup_complete = mwifiex_pm_wakeup_card_complete, + + /* SDIO specific */ + .update_mp_end_port = mwifiex_update_mp_end_port, + .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, +}; + +/* + * This function initializes the SDIO driver. + * + * This initiates the semaphore and registers the device with + * SDIO bus. + */ +static int +mwifiex_sdio_init_module(void) +{ + int ret; + + sema_init(&add_remove_card_sem, 1); + + ret = sdio_register_driver(&mwifiex_sdio); + + return ret; +} + +/* + * This function cleans up the SDIO driver. + * + * The following major steps are followed for cleanup - + * - Resume the device if its suspended + * - Disconnect the device if connected + * - Shutdown the firmware + * - Unregister the device from SDIO bus. + */ +static void +mwifiex_sdio_cleanup_module(void) +{ + struct mwifiex_adapter *adapter = g_adapter; + int i; + + if (down_interruptible(&add_remove_card_sem)) + goto exit_sem_err; + + if (!adapter || !adapter->priv_num) + goto exit; + + if (adapter->is_suspended) + mwifiex_sdio_resume(adapter->dev); + + for (i = 0; i < adapter->priv_num; i++) + if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) + mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT, + NULL); + + if (!adapter->surprise_removed) + mwifiex_shutdown_fw(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_ANY), + MWIFIEX_CMD_WAIT); + +exit: + up(&add_remove_card_sem); + +exit_sem_err: + sdio_unregister_driver(&mwifiex_sdio); +} + +module_init(mwifiex_sdio_init_module); +module_exit(mwifiex_sdio_cleanup_module); + +MODULE_AUTHOR("Marvell International Ltd."); +MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); +MODULE_VERSION(SDIO_VERSION); +MODULE_LICENSE("GPL v2"); +MODULE_FIRMWARE("sd8787.bin"); diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h new file mode 100644 index 000000000000..a0e9bc5253e0 --- /dev/null +++ b/drivers/net/wireless/mwifiex/sdio.h @@ -0,0 +1,305 @@ +/* + * Marvell Wireless LAN device driver: SDIO specific definitions + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_SDIO_H +#define _MWIFIEX_SDIO_H + + +#include +#include +#include +#include + +#include "main.h" + +#define BLOCK_MODE 1 +#define BYTE_MODE 0 + +#define REG_PORT 0 +#define RD_BITMAP_L 0x04 +#define RD_BITMAP_U 0x05 +#define WR_BITMAP_L 0x06 +#define WR_BITMAP_U 0x07 +#define RD_LEN_P0_L 0x08 +#define RD_LEN_P0_U 0x09 + +#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff + +#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000 + +#define CTRL_PORT 0 +#define CTRL_PORT_MASK 0x0001 +#define DATA_PORT_MASK 0xfffe + +#define MAX_MP_REGS 64 +#define MAX_PORT 16 + +#define SDIO_MP_AGGR_DEF_PKT_LIMIT 8 + +#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (4096) /* 4K */ + +/* Multi port RX aggregation buffer size */ +#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (4096) /* 4K */ + +/* Misc. Config Register : Auto Re-enable interrupts */ +#define AUTO_RE_ENABLE_INT BIT(4) + +/* Host Control Registers */ +/* Host Control Registers : I/O port 0 */ +#define IO_PORT_0_REG 0x78 +/* Host Control Registers : I/O port 1 */ +#define IO_PORT_1_REG 0x79 +/* Host Control Registers : I/O port 2 */ +#define IO_PORT_2_REG 0x7A + +/* Host Control Registers : Configuration */ +#define CONFIGURATION_REG 0x00 +/* Host Control Registers : Host without Command 53 finish host*/ +#define HOST_TO_CARD_EVENT (0x1U << 3) +/* Host Control Registers : Host without Command 53 finish host */ +#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2) +/* Host Control Registers : Host power up */ +#define HOST_POWER_UP (0x1U << 1) +/* Host Control Registers : Host power down */ +#define HOST_POWER_DOWN (0x1U << 0) + +/* Host Control Registers : Host interrupt mask */ +#define HOST_INT_MASK_REG 0x02 +/* Host Control Registers : Upload host interrupt mask */ +#define UP_LD_HOST_INT_MASK (0x1U) +/* Host Control Registers : Download host interrupt mask */ +#define DN_LD_HOST_INT_MASK (0x2U) +/* Enable Host interrupt mask */ +#define HOST_INT_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK) +/* Disable Host interrupt mask */ +#define HOST_INT_DISABLE 0xff + +/* Host Control Registers : Host interrupt status */ +#define HOST_INTSTATUS_REG 0x03 +/* Host Control Registers : Upload host interrupt status */ +#define UP_LD_HOST_INT_STATUS (0x1U) +/* Host Control Registers : Download host interrupt status */ +#define DN_LD_HOST_INT_STATUS (0x2U) + +/* Host Control Registers : Host interrupt RSR */ +#define HOST_INT_RSR_REG 0x01 +/* Host Control Registers : Upload host interrupt RSR */ +#define UP_LD_HOST_INT_RSR (0x1U) +#define SDIO_INT_MASK 0x3F + +/* Host Control Registers : Host interrupt status */ +#define HOST_INT_STATUS_REG 0x28 +/* Host Control Registers : Upload CRC error */ +#define UP_LD_CRC_ERR (0x1U << 2) +/* Host Control Registers : Upload restart */ +#define UP_LD_RESTART (0x1U << 1) +/* Host Control Registers : Download restart */ +#define DN_LD_RESTART (0x1U << 0) + +/* Card Control Registers : Card status register */ +#define CARD_STATUS_REG 0x30 +/* Card Control Registers : Card I/O ready */ +#define CARD_IO_READY (0x1U << 3) +/* Card Control Registers : CIS card ready */ +#define CIS_CARD_RDY (0x1U << 2) +/* Card Control Registers : Upload card ready */ +#define UP_LD_CARD_RDY (0x1U << 1) +/* Card Control Registers : Download card ready */ +#define DN_LD_CARD_RDY (0x1U << 0) + +/* Card Control Registers : Host interrupt mask register */ +#define HOST_INTERRUPT_MASK_REG 0x34 +/* Card Control Registers : Host power interrupt mask */ +#define HOST_POWER_INT_MASK (0x1U << 3) +/* Card Control Registers : Abort card interrupt mask */ +#define ABORT_CARD_INT_MASK (0x1U << 2) +/* Card Control Registers : Upload card interrupt mask */ +#define UP_LD_CARD_INT_MASK (0x1U << 1) +/* Card Control Registers : Download card interrupt mask */ +#define DN_LD_CARD_INT_MASK (0x1U << 0) + +/* Card Control Registers : Card interrupt status register */ +#define CARD_INTERRUPT_STATUS_REG 0x38 +/* Card Control Registers : Power up interrupt */ +#define POWER_UP_INT (0x1U << 4) +/* Card Control Registers : Power down interrupt */ +#define POWER_DOWN_INT (0x1U << 3) + +/* Card Control Registers : Card interrupt RSR register */ +#define CARD_INTERRUPT_RSR_REG 0x3c +/* Card Control Registers : Power up RSR */ +#define POWER_UP_RSR (0x1U << 4) +/* Card Control Registers : Power down RSR */ +#define POWER_DOWN_RSR (0x1U << 3) + +/* Card Control Registers : Miscellaneous Configuration Register */ +#define CARD_MISC_CFG_REG 0x6C + +/* Host F1 read base 0 */ +#define HOST_F1_RD_BASE_0 0x0040 +/* Host F1 read base 1 */ +#define HOST_F1_RD_BASE_1 0x0041 +/* Host F1 card ready */ +#define HOST_F1_CARD_RDY 0x0020 + +/* Firmware status 0 register */ +#define CARD_FW_STATUS0_REG 0x60 +/* Firmware status 1 register */ +#define CARD_FW_STATUS1_REG 0x61 +/* Rx length register */ +#define CARD_RX_LEN_REG 0x62 +/* Rx unit register */ +#define CARD_RX_UNIT_REG 0x63 + +/* Event header Len*/ +#define MWIFIEX_EVENT_HEADER_LEN 8 + +/* Max retry number of CMD53 write */ +#define MAX_WRITE_IOMEM_RETRY 2 + +/* SDIO Tx aggregation in progress ? */ +#define MP_TX_AGGR_IN_PROGRESS(a) (a->mpa_tx.pkt_cnt > 0) + +/* SDIO Tx aggregation buffer room for next packet ? */ +#define MP_TX_AGGR_BUF_HAS_ROOM(a, len) ((a->mpa_tx.buf_len+len) \ + <= a->mpa_tx.buf_size) + +/* Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */ +#define MP_TX_AGGR_BUF_PUT(a, payload, pkt_len, port) do { \ + memmove(&a->mpa_tx.buf[a->mpa_tx.buf_len], \ + payload, pkt_len); \ + a->mpa_tx.buf_len += pkt_len; \ + if (!a->mpa_tx.pkt_cnt) \ + a->mpa_tx.start_port = port; \ + if (a->mpa_tx.start_port <= port) \ + a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \ + else \ + a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT - \ + a->mp_end_port))); \ + a->mpa_tx.pkt_cnt++; \ +} while (0); + +/* SDIO Tx aggregation limit ? */ +#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \ + (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit) + +/* SDIO Tx aggregation port limit ? */ +#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port < \ + a->mpa_tx.start_port) && (((MAX_PORT - \ + a->mpa_tx.start_port) + a->curr_wr_port) >= \ + SDIO_MP_AGGR_DEF_PKT_LIMIT)) + +/* Reset SDIO Tx aggregation buffer parameters */ +#define MP_TX_AGGR_BUF_RESET(a) do { \ + a->mpa_tx.pkt_cnt = 0; \ + a->mpa_tx.buf_len = 0; \ + a->mpa_tx.ports = 0; \ + a->mpa_tx.start_port = 0; \ +} while (0); + +/* SDIO Rx aggregation limit ? */ +#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \ + (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit) + +/* SDIO Tx aggregation port limit ? */ +#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port < \ + a->mpa_rx.start_port) && (((MAX_PORT - \ + a->mpa_rx.start_port) + a->curr_rd_port) >= \ + SDIO_MP_AGGR_DEF_PKT_LIMIT)) + +/* SDIO Rx aggregation in progress ? */ +#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0) + +/* SDIO Rx aggregation buffer room for next packet ? */ +#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \ + ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size) + +/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */ +#define MP_RX_AGGR_SETUP(a, skb, port) do { \ + a->mpa_rx.buf_len += skb->len; \ + if (!a->mpa_rx.pkt_cnt) \ + a->mpa_rx.start_port = port; \ + if (a->mpa_rx.start_port <= port) \ + a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt)); \ + else \ + a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1)); \ + a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb; \ + a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len; \ + a->mpa_rx.pkt_cnt++; \ +} while (0); + +/* Reset SDIO Rx aggregation buffer parameters */ +#define MP_RX_AGGR_BUF_RESET(a) do { \ + a->mpa_rx.pkt_cnt = 0; \ + a->mpa_rx.buf_len = 0; \ + a->mpa_rx.ports = 0; \ + a->mpa_rx.start_port = 0; \ +} while (0); + + +/* data structure for SDIO MPA TX */ +struct mwifiex_sdio_mpa_tx { + /* multiport tx aggregation buffer pointer */ + u8 *buf; + u32 buf_len; + u32 pkt_cnt; + u16 ports; + u16 start_port; + u8 enabled; + u32 buf_size; + u32 pkt_aggr_limit; +}; + +struct mwifiex_sdio_mpa_rx { + u8 *buf; + u32 buf_len; + u32 pkt_cnt; + u16 ports; + u16 start_port; + + struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT]; + u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT]; + + u8 enabled; + u32 buf_size; + u32 pkt_aggr_limit; +}; + +int mwifiex_bus_register(void); +void mwifiex_bus_unregister(void); + +struct sdio_mmc_card { + struct sdio_func *func; + struct mwifiex_adapter *adapter; + + u16 mp_rd_bitmap; + u16 mp_wr_bitmap; + + u16 mp_end_port; + u16 mp_data_port_mask; + + u8 curr_rd_port; + u8 curr_wr_port; + + u8 *mp_regs; + + struct mwifiex_sdio_mpa_tx mpa_tx; + struct mwifiex_sdio_mpa_rx mpa_rx; +}; +#endif /* _MWIFIEX_SDIO_H */ diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c new file mode 100644 index 000000000000..795b1eae768d --- /dev/null +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -0,0 +1,1226 @@ +/* + * Marvell Wireless LAN device driver: station command handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +/* + * This function prepares command to set/get RSSI information. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting data/beacon average factors + * - Resetting SNR/NF/RSSI values in private structure + * - Ensuring correct endian-ness + */ +static int +mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, u16 cmd_action) +{ + cmd->command = cpu_to_le16(HostCmd_CMD_RSSI_INFO); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rssi_info) + + S_DS_GEN); + cmd->params.rssi_info.action = cpu_to_le16(cmd_action); + cmd->params.rssi_info.ndata = cpu_to_le16(priv->data_avg_factor); + cmd->params.rssi_info.nbcn = cpu_to_le16(priv->bcn_avg_factor); + + /* Reset SNR/NF/RSSI values in private structure */ + priv->data_rssi_last = 0; + priv->data_nf_last = 0; + priv->data_rssi_avg = 0; + priv->data_nf_avg = 0; + priv->bcn_rssi_last = 0; + priv->bcn_nf_last = 0; + priv->bcn_rssi_avg = 0; + priv->bcn_nf_avg = 0; + + return 0; +} + +/* + * This function prepares command to set MAC control. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl; + u16 action = *((u16 *) data_buf); + + if (cmd_action != HostCmd_ACT_GEN_SET) { + dev_err(priv->adapter->dev, + "mac_control: only support set cmd\n"); + return -1; + } + + cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL); + cmd->size = + cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN); + mac_ctrl->action = cpu_to_le16(action); + + return 0; +} + +/* + * This function prepares command to set/get SNMP MIB. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting SNMP MIB OID number and value + * (as required) + * - Ensuring correct endian-ness + * + * The following SNMP MIB OIDs are supported - + * - FRAG_THRESH_I : Fragmentation threshold + * - RTS_THRESH_I : RTS threshold + * - SHORT_RETRY_LIM_I : Short retry limit + * - DOT11D_I : 11d support + */ +static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, u32 cmd_oid, + void *data_buf) +{ + struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; + u32 ul_temp; + + dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) + - 1 + S_DS_GEN); + + if (cmd_action == HostCmd_ACT_GEN_GET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET); + snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + + MAX_SNMP_BUF_SIZE); + } + + switch (cmd_oid) { + case FRAG_THRESH_I: + snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I); + if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + ul_temp = *((u32 *) data_buf); + *((__le16 *) (snmp_mib->value)) = + cpu_to_le16((u16) ul_temp); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + + sizeof(u16)); + } + break; + case RTS_THRESH_I: + snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I); + if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + ul_temp = *((u32 *) data_buf); + *(__le16 *) (snmp_mib->value) = + cpu_to_le16((u16) ul_temp); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + + sizeof(u16)); + } + break; + + case SHORT_RETRY_LIM_I: + snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I); + if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + ul_temp = (*(u32 *) data_buf); + *((__le16 *) (snmp_mib->value)) = + cpu_to_le16((u16) ul_temp); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + + sizeof(u16)); + } + break; + case DOT11D_I: + snmp_mib->oid = cpu_to_le16((u16) DOT11D_I); + if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + ul_temp = *(u32 *) data_buf; + *((__le16 *) (snmp_mib->value)) = + cpu_to_le16((u16) ul_temp); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + + sizeof(u16)); + } + break; + default: + break; + } + dev_dbg(priv->adapter->dev, + "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," + " Value=0x%x\n", + cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), + le16_to_cpu(*(__le16 *) snmp_mib->value)); + return 0; +} + +/* + * This function prepares command to get log. + * + * Preparation includes - + * - Setting command ID and proper size + * - Ensuring correct endian-ness + */ +static int +mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd) +{ + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + + S_DS_GEN); + return 0; +} + +/* + * This function prepares command to set/get Tx data rate configuration. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting configuration index, rate scope and rate drop pattern + * parameters (as required) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg; + struct mwifiex_rate_scope *rate_scope; + struct mwifiex_rate_drop_pattern *rate_drop; + u16 *pbitmap_rates = (u16 *) data_buf; + + u32 i; + + cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG); + + rate_cfg->action = cpu_to_le16(cmd_action); + rate_cfg->cfg_index = 0; + + rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg + + sizeof(struct host_cmd_ds_tx_rate_cfg)); + rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE); + rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) - + sizeof(struct mwifiex_ie_types_header)); + if (pbitmap_rates != NULL) { + rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]); + rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]); + for (i = 0; + i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16); + i++) + rate_scope->ht_mcs_rate_bitmap[i] = + cpu_to_le16(pbitmap_rates[2 + i]); + } else { + rate_scope->hr_dsss_rate_bitmap = + cpu_to_le16(priv->bitmap_rates[0]); + rate_scope->ofdm_rate_bitmap = + cpu_to_le16(priv->bitmap_rates[1]); + for (i = 0; + i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16); + i++) + rate_scope->ht_mcs_rate_bitmap[i] = + cpu_to_le16(priv->bitmap_rates[2 + i]); + } + + rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + + sizeof(struct mwifiex_rate_scope)); + rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); + rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); + rate_drop->rate_drop_mode = 0; + + cmd->size = + cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_tx_rate_cfg) + + sizeof(struct mwifiex_rate_scope) + + sizeof(struct mwifiex_rate_drop_pattern)); + + return 0; +} + +/* + * This function prepares command to set/get Tx power configuration. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting Tx power mode, power group TLV + * (as required) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct mwifiex_types_power_group *pg_tlv = NULL; + struct host_cmd_ds_txpwr_cfg *txp = NULL; + struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg; + + cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG); + cmd->size = + cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg)); + switch (cmd_action) { + case HostCmd_ACT_GEN_SET: + txp = (struct host_cmd_ds_txpwr_cfg *) data_buf; + if (txp->mode) { + pg_tlv = (struct mwifiex_types_power_group + *) ((unsigned long) data_buf + + sizeof(struct host_cmd_ds_txpwr_cfg)); + memmove(cmd_txp_cfg, data_buf, + sizeof(struct host_cmd_ds_txpwr_cfg) + + sizeof(struct mwifiex_types_power_group) + + pg_tlv->length); + + pg_tlv = (struct mwifiex_types_power_group *) ((u8 *) + cmd_txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + + sizeof(struct mwifiex_types_power_group) + + pg_tlv->length); + } else { + memmove(cmd_txp_cfg, data_buf, + sizeof(struct host_cmd_ds_txpwr_cfg)); + } + cmd_txp_cfg->action = cpu_to_le16(cmd_action); + break; + case HostCmd_ACT_GEN_GET: + cmd_txp_cfg->action = cpu_to_le16(cmd_action); + break; + } + + return 0; +} + +/* + * This function prepares command to set Host Sleep configuration. + * + * Preparation includes - + * - Setting command ID and proper size + * - Setting Host Sleep action, conditions, ARP filters + * (as required) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_hs_config_param *data_buf) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg; + u16 hs_activate = false; + + if (data_buf == NULL) + /* New Activate command */ + hs_activate = true; + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); + + if (!hs_activate && + (data_buf->conditions + != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) + && ((adapter->arp_filter_size > 0) + && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { + dev_dbg(adapter->dev, + "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n", + adapter->arp_filter_size); + memcpy(((u8 *) hs_cfg) + + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh), + adapter->arp_filter, adapter->arp_filter_size); + cmd->size = cpu_to_le16(adapter->arp_filter_size + + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) + + S_DS_GEN); + } else { + cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct + host_cmd_ds_802_11_hs_cfg_enh)); + } + if (hs_activate) { + hs_cfg->action = cpu_to_le16(HS_ACTIVATE); + hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED; + } else { + hs_cfg->action = cpu_to_le16(HS_CONFIGURE); + hs_cfg->params.hs_config.conditions = data_buf->conditions; + hs_cfg->params.hs_config.gpio = data_buf->gpio; + hs_cfg->params.hs_config.gap = data_buf->gap; + dev_dbg(adapter->dev, + "cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n", + hs_cfg->params.hs_config.conditions, + hs_cfg->params.hs_config.gpio, + hs_cfg->params.hs_config.gap); + } + + return 0; +} + +/* + * This function prepares command to set/get MAC address. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting MAC address (for SET only) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action) +{ + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_mac_address) + + S_DS_GEN); + cmd->result = 0; + + cmd->params.mac_addr.action = cpu_to_le16(cmd_action); + + if (cmd_action == HostCmd_ACT_GEN_SET) + memcpy(cmd->params.mac_addr.mac_addr, priv->curr_addr, + ETH_ALEN); + return 0; +} + +/* + * This function prepares command to set MAC multicast address. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting MAC multicast address + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct mwifiex_multicast_list *mcast_list = + (struct mwifiex_multicast_list *) data_buf; + struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr; + + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) + + S_DS_GEN); + cmd->command = cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR); + + mcast_addr->action = cpu_to_le16(cmd_action); + mcast_addr->num_of_adrs = + cpu_to_le16((u16) mcast_list->num_multicast_addr); + memcpy(mcast_addr->mac_list, mcast_list->mac_list, + mcast_list->num_multicast_addr * ETH_ALEN); + + return 0; +} + +/* + * This function prepares command to deauthenticate. + * + * Preparation includes - + * - Setting command ID and proper size + * - Setting AP MAC address and reason code + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + void *data_buf) +{ + struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_deauthenticate) + + S_DS_GEN); + + /* Set AP MAC address */ + memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN); + + dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr); + + deauth->reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING); + + return 0; +} + +/* + * This function prepares command to stop Ad-Hoc network. + * + * Preparation includes - + * - Setting command ID and proper size + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd) +{ + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); + cmd->size = cpu_to_le16(S_DS_GEN); + return 0; +} + +/* + * This function sets WEP key(s) to key parameter TLV(s). + * + * Multi-key parameter TLVs are supported, so we can send multiple + * WEP keys in a single buffer. + */ +static int +mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, + struct mwifiex_ie_type_key_param_set *key_param_set, + u16 *key_param_len) +{ + int cur_key_param_len = 0; + u8 i; + + /* Multi-key_param_set TLV is supported */ + for (i = 0; i < NUM_WEP_KEYS; i++) { + if ((priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP40) || + (priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP104)) { + key_param_set->type = + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); +/* Key_param_set WEP fixed length */ +#define KEYPARAMSET_WEP_FIXED_LEN 8 + key_param_set->length = cpu_to_le16((u16) + (priv->wep_key[i]. + key_length + + KEYPARAMSET_WEP_FIXED_LEN)); + key_param_set->key_type_id = + cpu_to_le16(KEY_TYPE_ID_WEP); + key_param_set->key_info = + cpu_to_le16(KEY_INFO_WEP_ENABLED | + KEY_INFO_WEP_UNICAST | + KEY_INFO_WEP_MCAST); + key_param_set->key_len = + cpu_to_le16(priv->wep_key[i].key_length); + /* Set WEP key index */ + key_param_set->key[0] = i; + /* Set default Tx key flag */ + if (i == + (priv-> + wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK)) + key_param_set->key[1] = 1; + else + key_param_set->key[1] = 0; + memmove(&key_param_set->key[2], + priv->wep_key[i].key_material, + priv->wep_key[i].key_length); + + cur_key_param_len = priv->wep_key[i].key_length + + KEYPARAMSET_WEP_FIXED_LEN + + sizeof(struct mwifiex_ie_types_header); + *key_param_len += (u16) cur_key_param_len; + key_param_set = + (struct mwifiex_ie_type_key_param_set *) + ((u8 *)key_param_set + + cur_key_param_len); + } else if (!priv->wep_key[i].key_length) { + continue; + } else { + dev_err(priv->adapter->dev, + "key%d Length = %d is incorrect\n", + (i + 1), priv->wep_key[i].key_length); + return -1; + } + } + + return 0; +} + +/* + * This function prepares command to set/get/reset network key(s). + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting WEP keys, WAPI keys or WPA keys along with required + * encryption (TKIP, AES) (as required) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, + u32 cmd_oid, void *data_buf) +{ + struct host_cmd_ds_802_11_key_material *key_material = + &cmd->params.key_material; + struct mwifiex_ds_encrypt_key *enc_key = + (struct mwifiex_ds_encrypt_key *) data_buf; + u16 key_param_len = 0; + int ret = 0; + const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL); + key_material->action = cpu_to_le16(cmd_action); + + if (cmd_action == HostCmd_ACT_GEN_GET) { + cmd->size = + cpu_to_le16(sizeof(key_material->action) + S_DS_GEN); + return ret; + } + + if (!enc_key) { + memset(&key_material->key_param_set, 0, + (NUM_WEP_KEYS * + sizeof(struct mwifiex_ie_type_key_param_set))); + ret = mwifiex_set_keyparamset_wep(priv, + &key_material->key_param_set, + &key_param_len); + cmd->size = cpu_to_le16(key_param_len + + sizeof(key_material->action) + S_DS_GEN); + return ret; + } else + memset(&key_material->key_param_set, 0, + sizeof(struct mwifiex_ie_type_key_param_set)); + if (enc_key->is_wapi_key) { + dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n"); + key_material->key_param_set.key_type_id = + cpu_to_le16(KEY_TYPE_ID_WAPI); + if (cmd_oid == KEY_INFO_ENABLED) + key_material->key_param_set.key_info = + cpu_to_le16(KEY_INFO_WAPI_ENABLED); + else + key_material->key_param_set.key_info = + cpu_to_le16(!KEY_INFO_WAPI_ENABLED); + + key_material->key_param_set.key[0] = enc_key->key_index; + if (!priv->sec_info.wapi_key_on) + key_material->key_param_set.key[1] = 1; + else + /* set 0 when re-key */ + key_material->key_param_set.key[1] = 0; + + if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { + /* WAPI pairwise key: unicast */ + key_material->key_param_set.key_info |= + cpu_to_le16(KEY_INFO_WAPI_UNICAST); + } else { /* WAPI group key: multicast */ + key_material->key_param_set.key_info |= + cpu_to_le16(KEY_INFO_WAPI_MCAST); + priv->sec_info.wapi_key_on = true; + } + + key_material->key_param_set.type = + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + key_material->key_param_set.key_len = + cpu_to_le16(WAPI_KEY_LEN); + memcpy(&key_material->key_param_set.key[2], + enc_key->key_material, enc_key->key_len); + memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], + enc_key->wapi_rxpn, WAPI_RXPN_LEN); + key_material->key_param_set.length = + cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN); + + key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) + + sizeof(struct mwifiex_ie_types_header); + cmd->size = cpu_to_le16(key_param_len + + sizeof(key_material->action) + S_DS_GEN); + return ret; + } + if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { + dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); + key_material->key_param_set.key_type_id = + cpu_to_le16(KEY_TYPE_ID_AES); + if (cmd_oid == KEY_INFO_ENABLED) + key_material->key_param_set.key_info = + cpu_to_le16(KEY_INFO_AES_ENABLED); + else + key_material->key_param_set.key_info = + cpu_to_le16(!KEY_INFO_AES_ENABLED); + + if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) + /* AES pairwise key: unicast */ + key_material->key_param_set.key_info |= + cpu_to_le16(KEY_INFO_AES_UNICAST); + else /* AES group key: multicast */ + key_material->key_param_set.key_info |= + cpu_to_le16(KEY_INFO_AES_MCAST); + } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { + dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); + key_material->key_param_set.key_type_id = + cpu_to_le16(KEY_TYPE_ID_TKIP); + key_material->key_param_set.key_info = + cpu_to_le16(KEY_INFO_TKIP_ENABLED); + + if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) + /* TKIP pairwise key: unicast */ + key_material->key_param_set.key_info |= + cpu_to_le16(KEY_INFO_TKIP_UNICAST); + else /* TKIP group key: multicast */ + key_material->key_param_set.key_info |= + cpu_to_le16(KEY_INFO_TKIP_MCAST); + } + + if (key_material->key_param_set.key_type_id) { + key_material->key_param_set.type = + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + key_material->key_param_set.key_len = + cpu_to_le16((u16) enc_key->key_len); + memcpy(key_material->key_param_set.key, enc_key->key_material, + enc_key->key_len); + key_material->key_param_set.length = + cpu_to_le16((u16) enc_key->key_len + + KEYPARAMSET_FIXED_LEN); + + key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) + + sizeof(struct mwifiex_ie_types_header); + + cmd->size = cpu_to_le16(key_param_len + + sizeof(key_material->action) + S_DS_GEN); + } + + return ret; +} + +/* + * This function prepares command to set/get 11d domain information. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting domain information fields (for SET only) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11d_domain_info *domain_info = + &cmd->params.domain_info; + struct mwifiex_ietypes_domain_param_set *domain = + &domain_info->domain; + u8 no_of_triplet = adapter->domain_reg.no_of_triplet; + + dev_dbg(adapter->dev, "info: 11D: no_of_triplet=0x%x\n", no_of_triplet); + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO); + domain_info->action = cpu_to_le16(cmd_action); + if (cmd_action == HostCmd_ACT_GEN_GET) { + cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); + return 0; + } + + /* Set domain info fields */ + domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY); + memcpy(domain->country_code, adapter->domain_reg.country_code, + sizeof(domain->country_code)); + + domain->header.len = cpu_to_le16((no_of_triplet * + sizeof(struct ieee80211_country_ie_triplet)) + + sizeof(domain->country_code)); + + if (no_of_triplet) { + memcpy(domain->triplet, adapter->domain_reg.triplet, + no_of_triplet * + sizeof(struct ieee80211_country_ie_triplet)); + + cmd->size = cpu_to_le16(sizeof(domain_info->action) + + le16_to_cpu(domain->header.len) + + sizeof(struct mwifiex_ie_types_header) + + S_DS_GEN); + } else { + cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); + } + + return 0; +} + +/* + * This function prepares command to set/get RF channel. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting RF type and current RF channel (for SET only) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_802_11_rf_channel *rf_chan = + &cmd->params.rf_channel; + uint16_t rf_type = le16_to_cpu(rf_chan->rf_type); + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rf_channel) + + S_DS_GEN); + + if (cmd_action == HostCmd_ACT_GEN_SET) { + if ((priv->adapter->adhoc_start_band & BAND_A) + || (priv->adapter->adhoc_start_band & BAND_AN)) + rf_chan->rf_type = + cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); + + rf_type = le16_to_cpu(rf_chan->rf_type); + SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); + rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf)); + } + rf_chan->action = cpu_to_le16(cmd_action); + return 0; +} + +/* + * This function prepares command to set/get IBSS coalescing status. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting status to enable or disable (for SET only) + * - Ensuring correct endian-ness + */ +static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct host_cmd_ds_802_11_ibss_status *ibss_coal = + &(cmd->params.ibss_coalescing); + u16 enable = 0; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS); + cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) + + S_DS_GEN); + cmd->result = 0; + ibss_coal->action = cpu_to_le16(cmd_action); + + switch (cmd_action) { + case HostCmd_ACT_GEN_SET: + if (data_buf != NULL) + enable = *(u16 *) data_buf; + ibss_coal->enable = cpu_to_le16(enable); + break; + + /* In other case.. Nothing to do */ + case HostCmd_ACT_GEN_GET: + default: + break; + } + + return 0; +} + +/* + * This function prepares command to set/get register value. + * + * Preparation includes - + * - Setting command ID, action and proper size + * - Setting register offset (for both GET and SET) and + * register value (for SET only) + * - Ensuring correct endian-ness + * + * The following type of registers can be accessed with this function - + * - MAC register + * - BBP register + * - RF register + * - PMIC register + * - CAU register + * - EEPROM + */ +static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, + u16 cmd_action, void *data_buf) +{ + struct mwifiex_ds_reg_rw *reg_rw; + + reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; + switch (le16_to_cpu(cmd->command)) { + case HostCmd_CMD_MAC_REG_ACCESS: + { + struct host_cmd_ds_mac_reg_access *mac_reg; + + cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); + mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> + params.mac_reg; + mac_reg->action = cpu_to_le16(cmd_action); + mac_reg->offset = + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + mac_reg->value = reg_rw->value; + break; + } + case HostCmd_CMD_BBP_REG_ACCESS: + { + struct host_cmd_ds_bbp_reg_access *bbp_reg; + + cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); + bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd-> + params.bbp_reg; + bbp_reg->action = cpu_to_le16(cmd_action); + bbp_reg->offset = + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + bbp_reg->value = (u8) le32_to_cpu(reg_rw->value); + break; + } + case HostCmd_CMD_RF_REG_ACCESS: + { + struct host_cmd_ds_rf_reg_access *rf_reg; + + cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); + rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> + params.rf_reg; + rf_reg->action = cpu_to_le16(cmd_action); + rf_reg->offset = + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + rf_reg->value = (u8) le32_to_cpu(reg_rw->value); + break; + } + case HostCmd_CMD_PMIC_REG_ACCESS: + { + struct host_cmd_ds_pmic_reg_access *pmic_reg; + + cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); + pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd-> + params.pmic_reg; + pmic_reg->action = cpu_to_le16(cmd_action); + pmic_reg->offset = + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); + break; + } + case HostCmd_CMD_CAU_REG_ACCESS: + { + struct host_cmd_ds_rf_reg_access *cau_reg; + + cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); + cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> + params.rf_reg; + cau_reg->action = cpu_to_le16(cmd_action); + cau_reg->offset = + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cau_reg->value = (u8) le32_to_cpu(reg_rw->value); + break; + } + case HostCmd_CMD_802_11_EEPROM_ACCESS: + { + struct mwifiex_ds_read_eeprom *rd_eeprom = + (struct mwifiex_ds_read_eeprom *) data_buf; + struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = + (struct host_cmd_ds_802_11_eeprom_access *) + &cmd->params.eeprom; + + cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); + cmd_eeprom->action = cpu_to_le16(cmd_action); + cmd_eeprom->offset = rd_eeprom->offset; + cmd_eeprom->byte_count = rd_eeprom->byte_count; + cmd_eeprom->value = 0; + break; + } + default: + return -1; + } + + return 0; +} + +/* + * This function prepares the commands before sending them to the firmware. + * + * This is a generic function which calls specific command preparation + * routines based upon the command number. + */ +int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, + void *data_buf, void *cmd_buf) +{ + struct host_cmd_ds_command *cmd_ptr = + (struct host_cmd_ds_command *) cmd_buf; + int ret = 0; + + /* Prepare command */ + switch (cmd_no) { + case HostCmd_CMD_GET_HW_SPEC: + ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr); + break; + case HostCmd_CMD_MAC_CONTROL: + ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_802_11_MAC_ADDRESS: + ret = mwifiex_cmd_802_11_mac_address(priv, cmd_ptr, + cmd_action); + break; + case HostCmd_CMD_MAC_MULTICAST_ADR: + ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_TX_RATE_CFG: + ret = mwifiex_cmd_tx_rate_cfg(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_TXPWR_CFG: + ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_802_11_PS_MODE_ENH: + ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action, + (uint16_t)cmd_oid, data_buf); + break; + case HostCmd_CMD_802_11_HS_CFG_ENH: + ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action, + (struct mwifiex_hs_config_param *) data_buf); + break; + case HostCmd_CMD_802_11_SCAN: + ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf); + break; + case HostCmd_CMD_802_11_BG_SCAN_QUERY: + ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr, + data_buf); + break; + case HostCmd_CMD_802_11_ASSOCIATE: + ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); + break; + case HostCmd_CMD_802_11_DEAUTHENTICATE: + ret = mwifiex_cmd_802_11_deauthenticate(priv, cmd_ptr, + data_buf); + break; + case HostCmd_CMD_802_11_AD_HOC_START: + ret = mwifiex_cmd_802_11_ad_hoc_start(priv, cmd_ptr, + data_buf); + break; + case HostCmd_CMD_802_11_GET_LOG: + ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr); + break; + case HostCmd_CMD_802_11_AD_HOC_JOIN: + ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, + data_buf); + break; + case HostCmd_CMD_802_11_AD_HOC_STOP: + ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr); + break; + case HostCmd_CMD_RSSI_INFO: + ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); + break; + case HostCmd_CMD_802_11_SNMP_MIB: + ret = mwifiex_cmd_802_11_snmp_mib(priv, cmd_ptr, cmd_action, + cmd_oid, data_buf); + break; + case HostCmd_CMD_802_11_TX_RATE_QUERY: + cmd_ptr->command = + cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY); + cmd_ptr->size = + cpu_to_le16(sizeof(struct host_cmd_ds_tx_rate_query) + + S_DS_GEN); + priv->tx_rate = 0; + ret = 0; + break; + case HostCmd_CMD_VERSION_EXT: + cmd_ptr->command = cpu_to_le16(cmd_no); + cmd_ptr->params.verext.version_str_sel = + (u8) (*((u32 *) data_buf)); + memcpy(&cmd_ptr->params, data_buf, + sizeof(struct host_cmd_ds_version_ext)); + cmd_ptr->size = + cpu_to_le16(sizeof(struct host_cmd_ds_version_ext) + + S_DS_GEN); + ret = 0; + break; + case HostCmd_CMD_802_11_RF_CHANNEL: + ret = mwifiex_cmd_802_11_rf_channel(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_FUNC_INIT: + if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET) + priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY; + cmd_ptr->command = cpu_to_le16(cmd_no); + cmd_ptr->size = cpu_to_le16(S_DS_GEN); + break; + case HostCmd_CMD_FUNC_SHUTDOWN: + priv->adapter->hw_status = MWIFIEX_HW_STATUS_RESET; + cmd_ptr->command = cpu_to_le16(cmd_no); + cmd_ptr->size = cpu_to_le16(S_DS_GEN); + break; + case HostCmd_CMD_11N_ADDBA_REQ: + ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf); + break; + case HostCmd_CMD_11N_DELBA: + ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf); + break; + case HostCmd_CMD_11N_ADDBA_RSP: + ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); + break; + case HostCmd_CMD_802_11_KEY_MATERIAL: + ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr, + cmd_action, cmd_oid, + data_buf); + break; + case HostCmd_CMD_802_11D_DOMAIN_INFO: + ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr, + cmd_action); + break; + case HostCmd_CMD_RECONFIGURE_TX_BUFF: + ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_AMSDU_AGGR_CTRL: + ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_11N_CFG: + ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, + data_buf); + break; + case HostCmd_CMD_WMM_GET_STATUS: + dev_dbg(priv->adapter->dev, + "cmd: WMM: WMM_GET_STATUS cmd sent\n"); + cmd_ptr->command = cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS); + cmd_ptr->size = + cpu_to_le16(sizeof(struct host_cmd_ds_wmm_get_status) + + S_DS_GEN); + ret = 0; + break; + case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: + ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr, + cmd_action, data_buf); + break; + case HostCmd_CMD_MAC_REG_ACCESS: + case HostCmd_CMD_BBP_REG_ACCESS: + case HostCmd_CMD_RF_REG_ACCESS: + case HostCmd_CMD_PMIC_REG_ACCESS: + case HostCmd_CMD_CAU_REG_ACCESS: + case HostCmd_CMD_802_11_EEPROM_ACCESS: + ret = mwifiex_cmd_reg_access(cmd_ptr, cmd_action, data_buf); + break; + case HostCmd_CMD_SET_BSS_MODE: + cmd_ptr->command = cpu_to_le16(cmd_no); + if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) + cmd_ptr->params.bss_mode.con_type = + CONNECTION_TYPE_ADHOC; + else if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) + cmd_ptr->params.bss_mode.con_type = + CONNECTION_TYPE_INFRA; + cmd_ptr->size = cpu_to_le16(sizeof(struct + host_cmd_ds_set_bss_mode) + S_DS_GEN); + ret = 0; + break; + default: + dev_err(priv->adapter->dev, + "PREP_CMD: unknown cmd- %#x\n", cmd_no); + ret = -1; + break; + } + return ret; +} + +/* + * This function issues commands to initialize firmware. + * + * This is called after firmware download to bring the card to + * working state. + * + * The following commands are issued sequentially - + * - Function init (for first interface only) + * - Read MAC address (for first interface only) + * - Reconfigure Tx buffer size (for first interface only) + * - Enable auto deep sleep (for first interface only) + * - Get Tx rate + * - Get Tx power + * - Set IBSS coalescing status + * - Set AMSDU aggregation control + * - Set 11d control + * - Set MAC control (this must be the last command to initialize firmware) + */ +int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) +{ + int ret = 0; + u16 enable = true; + struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; + struct mwifiex_ds_auto_ds auto_ds; + enum state_11d_t state_11d; + + if (first_sta) { + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, + HostCmd_ACT_GEN_SET, 0, NULL, NULL); + if (ret) + return -1; + /* Read MAC address from HW */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, + HostCmd_ACT_GEN_GET, 0, NULL, NULL); + if (ret) + return -1; + + /* Reconfigure tx buf size */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, NULL, + &priv->adapter->tx_buf_size); + if (ret) + return -1; + + /* Enable IEEE PS by default */ + priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_STA_PS, NULL, + NULL); + if (ret) + return -1; + } + + /* get tx rate */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, + HostCmd_ACT_GEN_GET, 0, NULL, NULL); + if (ret) + return -1; + priv->data_rate = 0; + + /* get tx power */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, + HostCmd_ACT_GEN_GET, 0, NULL, NULL); + if (ret) + return -1; + + /* set ibss coalescing_status */ + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, + HostCmd_ACT_GEN_SET, 0, NULL, &enable); + if (ret) + return -1; + + memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); + amsdu_aggr_ctrl.enable = true; + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, + HostCmd_ACT_GEN_SET, 0, NULL, + (void *) &amsdu_aggr_ctrl); + if (ret) + return -1; + /* MAC Control must be the last command in init_fw */ + /* set MAC Control */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, NULL, + &priv->curr_pkt_filter); + if (ret) + return -1; + + if (first_sta) { + /* Enable auto deep sleep */ + auto_ds.auto_ds = DEEP_SLEEP_ON; + auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_AUTO_DS, NULL, + &auto_ds); + if (ret) + return -1; + } + + /* Send cmd to FW to enable/disable 11D function */ + state_11d = ENABLE_11D; + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, DOT11D_I, + NULL, &state_11d); + if (ret) + dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); + + /* set last_init_cmd */ + priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB; + ret = -EINPROGRESS; + + return ret; +} diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c new file mode 100644 index 000000000000..ae960ddf2bd4 --- /dev/null +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -0,0 +1,986 @@ +/* + * Marvell Wireless LAN device driver: station command response handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + + +/* + * This function handles the command response error case. + * + * For scan response error, the function cancels all the pending + * scan commands and generates an event to inform the applications + * of the scan completion. + * + * For Power Save command failure, we do not retry enter PS + * command in case of Ad-hoc mode. + * + * For all other response errors, the current command buffer is freed + * and returned to the free command queue. + */ +static void +mwifiex_process_cmdresp_error(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + struct mwifiex_wait_queue *wq_buf) +{ + struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; + struct mwifiex_adapter *adapter = priv->adapter; + unsigned long flags; + + dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", + resp->command, resp->result); + if (wq_buf) + wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP; + + switch (le16_to_cpu(resp->command)) { + case HostCmd_CMD_802_11_PS_MODE_ENH: + { + struct host_cmd_ds_802_11_ps_mode_enh *pm = + &resp->params.psmode_enh; + dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " + "result=0x%x action=0x%X\n", + resp->result, le16_to_cpu(pm->action)); + /* We do not re-try enter-ps command in ad-hoc mode. */ + if (le16_to_cpu(pm->action) == EN_AUTO_PS && + (le16_to_cpu(pm->params.auto_ps.ps_bitmap) & + BITMAP_STA_PS) + && priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) + adapter->ps_mode = + MWIFIEX_802_11_POWER_MODE_CAM; + } + break; + case HostCmd_CMD_802_11_SCAN: + /* Cancel all pending scan command */ + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + list_for_each_entry_safe(cmd_node, tmp_node, + &adapter->scan_pending_q, list) { + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + } + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + if (priv->report_scan_result) + priv->report_scan_result = false; + if (priv->scan_pending_on_block) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } + break; + + case HostCmd_CMD_MAC_CONTROL: + break; + + default: + break; + } + /* Handling errors here */ + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + adapter->curr_cmd = NULL; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + + return; +} + +/* + * This function handles the command response of get RSSI info. + * + * Handling includes changing the header fields into CPU format + * and saving the following parameters in driver - + * - Last data and beacon RSSI value + * - Average data and beacon RSSI value + * - Last data and beacon NF value + * - Average data and beacon NF value + * + * The parameters are send to the application as well, along with + * calculated SNR values. + */ +static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = + &resp->params.rssi_info_rsp; + struct mwifiex_ds_get_signal *signal = NULL; + + priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); + priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); + + priv->data_rssi_avg = le16_to_cpu(rssi_info_rsp->data_rssi_avg); + priv->data_nf_avg = le16_to_cpu(rssi_info_rsp->data_nf_avg); + + priv->bcn_rssi_last = le16_to_cpu(rssi_info_rsp->bcn_rssi_last); + priv->bcn_nf_last = le16_to_cpu(rssi_info_rsp->bcn_nf_last); + + priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg); + priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg); + + /* Need to indicate IOCTL complete */ + if (data_buf) { + signal = (struct mwifiex_ds_get_signal *) data_buf; + memset(signal, 0, sizeof(struct mwifiex_ds_get_signal)); + + signal->selector = ALL_RSSI_INFO_MASK; + + /* RSSI */ + signal->bcn_rssi_last = priv->bcn_rssi_last; + signal->bcn_rssi_avg = priv->bcn_rssi_avg; + signal->data_rssi_last = priv->data_rssi_last; + signal->data_rssi_avg = priv->data_rssi_avg; + + /* SNR */ + signal->bcn_snr_last = + CAL_SNR(priv->bcn_rssi_last, priv->bcn_nf_last); + signal->bcn_snr_avg = + CAL_SNR(priv->bcn_rssi_avg, priv->bcn_nf_avg); + signal->data_snr_last = + CAL_SNR(priv->data_rssi_last, priv->data_nf_last); + signal->data_snr_avg = + CAL_SNR(priv->data_rssi_avg, priv->data_nf_avg); + + /* NF */ + signal->bcn_nf_last = priv->bcn_nf_last; + signal->bcn_nf_avg = priv->bcn_nf_avg; + signal->data_nf_last = priv->data_nf_last; + signal->data_nf_avg = priv->data_nf_avg; + } + + return 0; +} + +/* + * This function handles the command response of set/get SNMP + * MIB parameters. + * + * Handling includes changing the header fields into CPU format + * and saving the parameter in driver. + * + * The following parameters are supported - + * - Fragmentation threshold + * - RTS threshold + * - Short retry limit + */ +static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; + u16 oid = le16_to_cpu(smib->oid); + u16 query_type = le16_to_cpu(smib->query_type); + u32 ul_temp; + + dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," + " query_type = %#x, buf size = %#x\n", + oid, query_type, le16_to_cpu(smib->buf_size)); + if (query_type == HostCmd_ACT_GEN_GET) { + ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); + if (data_buf) + *(u32 *)data_buf = ul_temp; + switch (oid) { + case FRAG_THRESH_I: + dev_dbg(priv->adapter->dev, + "info: SNMP_RESP: FragThsd =%u\n", ul_temp); + break; + case RTS_THRESH_I: + dev_dbg(priv->adapter->dev, + "info: SNMP_RESP: RTSThsd =%u\n", ul_temp); + break; + case SHORT_RETRY_LIM_I: + dev_dbg(priv->adapter->dev, + "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); + break; + default: + break; + } + } + + return 0; +} + +/* + * This function handles the command response of get log request + * + * Handling includes changing the header fields into CPU format + * and sending the received parameters to application. + */ +static int mwifiex_ret_get_log(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct host_cmd_ds_802_11_get_log *get_log = + (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; + struct mwifiex_ds_get_stats *stats = NULL; + + if (data_buf) { + stats = (struct mwifiex_ds_get_stats *) data_buf; + stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); + stats->failed = le32_to_cpu(get_log->failed); + stats->retry = le32_to_cpu(get_log->retry); + stats->multi_retry = le32_to_cpu(get_log->multi_retry); + stats->frame_dup = le32_to_cpu(get_log->frame_dup); + stats->rts_success = le32_to_cpu(get_log->rts_success); + stats->rts_failure = le32_to_cpu(get_log->rts_failure); + stats->ack_failure = le32_to_cpu(get_log->ack_failure); + stats->rx_frag = le32_to_cpu(get_log->rx_frag); + stats->mcast_rx_frame = le32_to_cpu(get_log->mcast_rx_frame); + stats->fcs_error = le32_to_cpu(get_log->fcs_error); + stats->tx_frame = le32_to_cpu(get_log->tx_frame); + stats->wep_icv_error[0] = + le32_to_cpu(get_log->wep_icv_err_cnt[0]); + stats->wep_icv_error[1] = + le32_to_cpu(get_log->wep_icv_err_cnt[1]); + stats->wep_icv_error[2] = + le32_to_cpu(get_log->wep_icv_err_cnt[2]); + stats->wep_icv_error[3] = + le32_to_cpu(get_log->wep_icv_err_cnt[3]); + } + + return 0; +} + +/* + * This function handles the command response of set/get Tx rate + * configurations. + * + * Handling includes changing the header fields into CPU format + * and saving the following parameters in driver - + * - DSSS rate bitmap + * - OFDM rate bitmap + * - HT MCS rate bitmaps + * + * Based on the new rate bitmaps, the function re-evaluates if + * auto data rate has been activated. If not, it sends another + * query to the firmware to get the current Tx data rate and updates + * the driver value. + */ +static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_rate_cfg *ds_rate = NULL; + struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; + struct mwifiex_rate_scope *rate_scope; + struct mwifiex_ie_types_header *head = NULL; + u16 tlv, tlv_buf_len; + u8 *tlv_buf; + u32 i; + int ret = 0; + + tlv_buf = (u8 *) ((u8 *) rate_cfg) + + sizeof(struct host_cmd_ds_tx_rate_cfg); + tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16)); + + while (tlv_buf && tlv_buf_len > 0) { + tlv = (*tlv_buf); + tlv = tlv | (*(tlv_buf + 1) << 8); + + switch (tlv) { + case TLV_TYPE_RATE_SCOPE: + rate_scope = (struct mwifiex_rate_scope *) tlv_buf; + priv->bitmap_rates[0] = + le16_to_cpu(rate_scope->hr_dsss_rate_bitmap); + priv->bitmap_rates[1] = + le16_to_cpu(rate_scope->ofdm_rate_bitmap); + for (i = 0; + i < + sizeof(rate_scope->ht_mcs_rate_bitmap) / + sizeof(u16); i++) + priv->bitmap_rates[2 + i] = + le16_to_cpu(rate_scope-> + ht_mcs_rate_bitmap[i]); + break; + /* Add RATE_DROP tlv here */ + } + + head = (struct mwifiex_ie_types_header *) tlv_buf; + tlv_buf += le16_to_cpu(head->len) + sizeof(*head); + tlv_buf_len -= le16_to_cpu(head->len); + } + + priv->is_data_rate_auto = mwifiex_is_rate_auto(priv); + + if (priv->is_data_rate_auto) + priv->data_rate = 0; + else + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_TX_RATE_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL, NULL); + + if (data_buf) { + ds_rate = (struct mwifiex_rate_cfg *) data_buf; + if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { + if (priv->is_data_rate_auto) { + ds_rate->is_rate_auto = 1; + } else { + ds_rate->rate = + mwifiex_get_rate_index(adapter, + priv-> + bitmap_rates, + sizeof(priv-> + bitmap_rates)); + if (ds_rate->rate >= + MWIFIEX_RATE_BITMAP_OFDM0 + && ds_rate->rate <= + MWIFIEX_RATE_BITMAP_OFDM7) + ds_rate->rate -= + (MWIFIEX_RATE_BITMAP_OFDM0 - + MWIFIEX_RATE_INDEX_OFDM0); + if (ds_rate->rate >= + MWIFIEX_RATE_BITMAP_MCS0 + && ds_rate->rate <= + MWIFIEX_RATE_BITMAP_MCS127) + ds_rate->rate -= + (MWIFIEX_RATE_BITMAP_MCS0 - + MWIFIEX_RATE_INDEX_MCS0); + } + } + } + + return ret; +} + +/* + * This function handles the command response of get Tx power level. + * + * Handling includes saving the maximum and minimum Tx power levels + * in driver, as well as sending the values to user. + */ +static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) +{ + int length = -1, max_power = -1, min_power = -1; + struct mwifiex_types_power_group *pg_tlv_hdr = NULL; + struct mwifiex_power_group *pg = NULL; + + if (data_buf) { + pg_tlv_hdr = + (struct mwifiex_types_power_group *) ((u8 *) data_buf + + sizeof(struct host_cmd_ds_txpwr_cfg)); + pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + length = pg_tlv_hdr->length; + if (length > 0) { + max_power = pg->power_max; + min_power = pg->power_min; + length -= sizeof(struct mwifiex_power_group); + } + while (length) { + pg++; + if (max_power < pg->power_max) + max_power = pg->power_max; + + if (min_power > pg->power_min) + min_power = pg->power_min; + + length -= sizeof(struct mwifiex_power_group); + } + if (pg_tlv_hdr->length > 0) { + priv->min_tx_power_level = (u8) min_power; + priv->max_tx_power_level = (u8) max_power; + } + } else { + return -1; + } + + return 0; +} + +/* + * This function handles the command response of set/get Tx power + * configurations. + * + * Handling includes changing the header fields into CPU format + * and saving the current Tx power level in driver. + */ +static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg; + struct mwifiex_types_power_group *pg_tlv_hdr = NULL; + struct mwifiex_power_group *pg = NULL; + u16 action = le16_to_cpu(txp_cfg->action); + + switch (action) { + case HostCmd_ACT_GEN_GET: + { + pg_tlv_hdr = + (struct mwifiex_types_power_group *) ((u8 *) + txp_cfg + + sizeof + (struct + host_cmd_ds_txpwr_cfg)); + pg = (struct mwifiex_power_group *) ((u8 *) + pg_tlv_hdr + + sizeof(struct + mwifiex_types_power_group)); + if (adapter->hw_status == + MWIFIEX_HW_STATUS_INITIALIZING) + mwifiex_get_power_level(priv, txp_cfg); + priv->tx_power_level = (u16) pg->power_min; + break; + } + case HostCmd_ACT_GEN_SET: + if (le32_to_cpu(txp_cfg->mode)) { + pg_tlv_hdr = + (struct mwifiex_types_power_group *) ((u8 *) + txp_cfg + + sizeof + (struct + host_cmd_ds_txpwr_cfg)); + pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + + + sizeof(struct + mwifiex_types_power_group)); + if (pg->power_max == pg->power_min) + priv->tx_power_level = (u16) pg->power_min; + } + break; + default: + dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", + action); + return 0; + } + dev_dbg(adapter->dev, + "info: Current TxPower Level = %d, Max Power=%d, Min Power=%d\n", + priv->tx_power_level, priv->max_tx_power_level, + priv->min_tx_power_level); + + return 0; +} + +/* + * This function handles the command response of set/get MAC address. + * + * Handling includes saving the MAC address in driver. + */ +static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_802_11_mac_address *cmd_mac_addr = + &resp->params.mac_addr; + + memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN); + + dev_dbg(priv->adapter->dev, + "info: set mac address: %pM\n", priv->curr_addr); + + return 0; +} + +/* + * This function handles the command response of set/get MAC multicast + * address. + */ +static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + return 0; +} + +/* + * This function handles the command response of get Tx rate query. + * + * Handling includes changing the header fields into CPU format + * and saving the Tx rate and HT information parameters in driver. + * + * Both rate configuration and current data rate can be retrieved + * with this request. + */ +static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct mwifiex_adapter *adapter = priv->adapter; + + priv->tx_rate = resp->params.tx_rate.tx_rate; + priv->tx_htinfo = resp->params.tx_rate.ht_info; + if (!priv->is_data_rate_auto) + priv->data_rate = + mwifiex_index_to_data_rate(adapter, priv->tx_rate, + priv->tx_htinfo); + + return 0; +} + +/* + * This function handles the command response of a deauthenticate + * command. + * + * If the deauthenticated MAC matches the current BSS MAC, the connection + * state is reset. + */ +static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct mwifiex_adapter *adapter = priv->adapter; + + adapter->dbg.num_cmd_deauth++; + if (!memcmp(resp->params.deauth.mac_addr, + &priv->curr_bss_params.bss_descriptor.mac_address, + sizeof(resp->params.deauth.mac_addr))) + mwifiex_reset_connect_state(priv); + + return 0; +} + +/* + * This function handles the command response of ad-hoc stop. + * + * The function resets the connection state in driver. + */ +static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + mwifiex_reset_connect_state(priv); + return 0; +} + +/* + * This function handles the command response of set/get key material. + * + * Handling includes updating the driver parameters to reflect the + * changes. + */ +static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_802_11_key_material *key = + &resp->params.key_material; + + if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { + if ((le16_to_cpu(key->key_param_set.key_info) & + KEY_INFO_TKIP_MCAST)) { + dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); + priv->wpa_is_gtk_set = true; + priv->scan_block = false; + } + } + + memset(priv->aes_key.key_param_set.key, 0, + sizeof(key->key_param_set.key)); + priv->aes_key.key_param_set.key_len = key->key_param_set.key_len; + memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, + le16_to_cpu(priv->aes_key.key_param_set.key_len)); + + return 0; +} + +/* + * This function handles the command response of get 11d domain information. + */ +static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_802_11d_domain_info_rsp *domain_info = + &resp->params.domain_info_resp; + struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain; + u16 action = le16_to_cpu(domain_info->action); + u8 no_of_triplet = 0; + + no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) - + IEEE80211_COUNTRY_STRING_LEN) / + sizeof(struct ieee80211_country_ie_triplet)); + + dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:" + " no_of_triplet=%d\n", no_of_triplet); + + if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) { + dev_warn(priv->adapter->dev, + "11D: invalid number of triplets %d " + "returned!!\n", no_of_triplet); + return -1; + } + + switch (action) { + case HostCmd_ACT_GEN_SET: /* Proc Set Action */ + break; + case HostCmd_ACT_GEN_GET: + break; + default: + dev_err(priv->adapter->dev, + "11D: invalid action:%d\n", domain_info->action); + return -1; + } + + return 0; +} + +/* + * This function handles the command response of get RF channel. + * + * Handling includes changing the header fields into CPU format + * and saving the new channel in driver. + */ +static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct host_cmd_ds_802_11_rf_channel *rf_channel = + &resp->params.rf_channel; + u16 new_channel = le16_to_cpu(rf_channel->current_channel); + + if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { + dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", + priv->curr_bss_params.bss_descriptor.channel, + new_channel); + /* Update the channel again */ + priv->curr_bss_params.bss_descriptor.channel = new_channel; + } + if (data_buf) + *((u16 *)data_buf) = new_channel; + + return 0; +} + +/* + * This function handles the command response of get extended version. + * + * Handling includes forming the extended version string and sending it + * to application. + */ +static int mwifiex_ret_ver_ext(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext; + struct host_cmd_ds_version_ext *version_ext = NULL; + + if (data_buf) { + version_ext = (struct host_cmd_ds_version_ext *)data_buf; + version_ext->version_str_sel = ver_ext->version_str_sel; + memcpy(version_ext->version_str, ver_ext->version_str, + sizeof(char) * 128); + memcpy(priv->version_str, ver_ext->version_str, 128); + } + return 0; +} + +/* + * This function handles the command response of register access. + * + * The register value and offset are returned to the user. For EEPROM + * access, the byte count is also returned. + */ +static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, + void *data_buf) +{ + struct mwifiex_ds_reg_rw *reg_rw = NULL; + struct mwifiex_ds_read_eeprom *eeprom = NULL; + + if (data_buf) { + reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; + eeprom = (struct mwifiex_ds_read_eeprom *) data_buf; + switch (type) { + case HostCmd_CMD_MAC_REG_ACCESS: + { + struct host_cmd_ds_mac_reg_access *reg; + reg = (struct host_cmd_ds_mac_reg_access *) + &resp->params.mac_reg; + reg_rw->offset = cpu_to_le32( + (u32) le16_to_cpu(reg->offset)); + reg_rw->value = reg->value; + break; + } + case HostCmd_CMD_BBP_REG_ACCESS: + { + struct host_cmd_ds_bbp_reg_access *reg; + reg = (struct host_cmd_ds_bbp_reg_access *) + &resp->params.bbp_reg; + reg_rw->offset = cpu_to_le32( + (u32) le16_to_cpu(reg->offset)); + reg_rw->value = cpu_to_le32((u32) reg->value); + break; + } + + case HostCmd_CMD_RF_REG_ACCESS: + { + struct host_cmd_ds_rf_reg_access *reg; + reg = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32( + (u32) le16_to_cpu(reg->offset)); + reg_rw->value = cpu_to_le32((u32) reg->value); + break; + } + case HostCmd_CMD_PMIC_REG_ACCESS: + { + struct host_cmd_ds_pmic_reg_access *reg; + reg = (struct host_cmd_ds_pmic_reg_access *) + &resp->params.pmic_reg; + reg_rw->offset = cpu_to_le32( + (u32) le16_to_cpu(reg->offset)); + reg_rw->value = cpu_to_le32((u32) reg->value); + break; + } + case HostCmd_CMD_CAU_REG_ACCESS: + { + struct host_cmd_ds_rf_reg_access *reg; + reg = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32( + (u32) le16_to_cpu(reg->offset)); + reg_rw->value = cpu_to_le32((u32) reg->value); + break; + } + case HostCmd_CMD_802_11_EEPROM_ACCESS: + { + struct host_cmd_ds_802_11_eeprom_access + *cmd_eeprom = + (struct host_cmd_ds_802_11_eeprom_access + *) &resp->params.eeprom; + pr_debug("info: EEPROM read len=%x\n", + cmd_eeprom->byte_count); + if (le16_to_cpu(eeprom->byte_count) < + le16_to_cpu( + cmd_eeprom->byte_count)) { + eeprom->byte_count = cpu_to_le16(0); + pr_debug("info: EEPROM read " + "length is too big\n"); + return -1; + } + eeprom->offset = cmd_eeprom->offset; + eeprom->byte_count = cmd_eeprom->byte_count; + if (le16_to_cpu(eeprom->byte_count) > 0) + memcpy(&eeprom->value, + &cmd_eeprom->value, + le16_to_cpu(eeprom->byte_count)); + + break; + } + default: + return -1; + } + } + return 0; +} + +/* + * This function handles the command response of get IBSS coalescing status. + * + * If the received BSSID is different than the current one, the current BSSID, + * beacon interval, ATIM window and ERP information are updated, along with + * changing the ad-hoc state accordingly. + */ +static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = + &(resp->params.ibss_coalescing); + u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) + return 0; + + dev_dbg(priv->adapter->dev, + "info: new BSSID %pM\n", ibss_coal_resp->bssid); + + /* If rsp has NULL BSSID, Just return..... No Action */ + if (!memcmp(ibss_coal_resp->bssid, zero_mac, ETH_ALEN)) { + dev_warn(priv->adapter->dev, "new BSSID is NULL\n"); + return 0; + } + + /* If BSSID is diff, modify current BSS parameters */ + if (memcmp(priv->curr_bss_params.bss_descriptor.mac_address, + ibss_coal_resp->bssid, ETH_ALEN)) { + /* BSSID */ + memcpy(priv->curr_bss_params.bss_descriptor.mac_address, + ibss_coal_resp->bssid, ETH_ALEN); + + /* Beacon Interval */ + priv->curr_bss_params.bss_descriptor.beacon_period + = le16_to_cpu(ibss_coal_resp->beacon_interval); + + /* ERP Information */ + priv->curr_bss_params.bss_descriptor.erp_flags = + (u8) le16_to_cpu(ibss_coal_resp->use_g_rate_protect); + + priv->adhoc_state = ADHOC_COALESCED; + } + + return 0; +} + +/* + * This function handles the command responses. + * + * This is a generic function, which calls command specific + * response handlers based on the command ID. + */ +int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, + u16 cmdresp_no, void *cmd_buf, void *wq_buf) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_command *resp = + (struct host_cmd_ds_command *) cmd_buf; + struct mwifiex_wait_queue *wait_queue = + (struct mwifiex_wait_queue *) wq_buf; + void *data_buf = adapter->curr_cmd->data_buf; + + /* If the command is not successful, cleanup and return failure */ + if (resp->result != HostCmd_RESULT_OK) { + mwifiex_process_cmdresp_error(priv, resp, wait_queue); + return -1; + } + /* Command successful, handle response */ + switch (cmdresp_no) { + case HostCmd_CMD_GET_HW_SPEC: + ret = mwifiex_ret_get_hw_spec(priv, resp); + break; + case HostCmd_CMD_MAC_CONTROL: + break; + case HostCmd_CMD_802_11_MAC_ADDRESS: + ret = mwifiex_ret_802_11_mac_address(priv, resp); + break; + case HostCmd_CMD_MAC_MULTICAST_ADR: + ret = mwifiex_ret_mac_multicast_adr(priv, resp); + break; + case HostCmd_CMD_TX_RATE_CFG: + ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); + break; + case HostCmd_CMD_802_11_SCAN: + ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); + wait_queue = NULL; + adapter->curr_cmd->wq_buf = NULL; + break; + case HostCmd_CMD_802_11_BG_SCAN_QUERY: + ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); + dev_dbg(adapter->dev, + "info: CMD_RESP: BG_SCAN result is ready!\n"); + break; + case HostCmd_CMD_TXPWR_CFG: + ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf); + break; + case HostCmd_CMD_802_11_PS_MODE_ENH: + ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); + break; + case HostCmd_CMD_802_11_HS_CFG_ENH: + ret = mwifiex_ret_802_11_hs_cfg(priv, resp); + break; + case HostCmd_CMD_802_11_ASSOCIATE: + ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue); + break; + case HostCmd_CMD_802_11_DEAUTHENTICATE: + ret = mwifiex_ret_802_11_deauthenticate(priv, resp); + break; + case HostCmd_CMD_802_11_AD_HOC_START: + case HostCmd_CMD_802_11_AD_HOC_JOIN: + ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue); + break; + case HostCmd_CMD_802_11_AD_HOC_STOP: + ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); + break; + case HostCmd_CMD_802_11_GET_LOG: + ret = mwifiex_ret_get_log(priv, resp, data_buf); + break; + case HostCmd_CMD_RSSI_INFO: + ret = mwifiex_ret_802_11_rssi_info(priv, resp, data_buf); + break; + case HostCmd_CMD_802_11_SNMP_MIB: + ret = mwifiex_ret_802_11_snmp_mib(priv, resp, data_buf); + break; + case HostCmd_CMD_802_11_TX_RATE_QUERY: + ret = mwifiex_ret_802_11_tx_rate_query(priv, resp); + break; + case HostCmd_CMD_802_11_RF_CHANNEL: + ret = mwifiex_ret_802_11_rf_channel(priv, resp, data_buf); + break; + case HostCmd_CMD_VERSION_EXT: + ret = mwifiex_ret_ver_ext(priv, resp, data_buf); + break; + case HostCmd_CMD_FUNC_INIT: + case HostCmd_CMD_FUNC_SHUTDOWN: + break; + case HostCmd_CMD_802_11_KEY_MATERIAL: + ret = mwifiex_ret_802_11_key_material(priv, resp); + break; + case HostCmd_CMD_802_11D_DOMAIN_INFO: + ret = mwifiex_ret_802_11d_domain_info(priv, resp); + break; + case HostCmd_CMD_11N_ADDBA_REQ: + ret = mwifiex_ret_11n_addba_req(priv, resp); + break; + case HostCmd_CMD_11N_DELBA: + ret = mwifiex_ret_11n_delba(priv, resp); + break; + case HostCmd_CMD_11N_ADDBA_RSP: + ret = mwifiex_ret_11n_addba_resp(priv, resp); + break; + case HostCmd_CMD_RECONFIGURE_TX_BUFF: + adapter->tx_buf_size = (u16) le16_to_cpu(resp->params. + tx_buf.buff_size); + adapter->tx_buf_size = (adapter->tx_buf_size / + MWIFIEX_SDIO_BLOCK_SIZE) * + MWIFIEX_SDIO_BLOCK_SIZE; + adapter->curr_tx_buf_size = adapter->tx_buf_size; + dev_dbg(adapter->dev, + "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", + adapter->max_tx_buf_size, adapter->tx_buf_size); + + if (adapter->if_ops.update_mp_end_port) + adapter->if_ops.update_mp_end_port(adapter, + le16_to_cpu(resp-> + params. + tx_buf. + mp_end_port)); + break; + case HostCmd_CMD_AMSDU_AGGR_CTRL: + ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf); + break; + case HostCmd_CMD_WMM_GET_STATUS: + ret = mwifiex_ret_wmm_get_status(priv, resp); + break; + case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: + ret = mwifiex_ret_ibss_coalescing_status(priv, resp); + break; + case HostCmd_CMD_MAC_REG_ACCESS: + case HostCmd_CMD_BBP_REG_ACCESS: + case HostCmd_CMD_RF_REG_ACCESS: + case HostCmd_CMD_PMIC_REG_ACCESS: + case HostCmd_CMD_CAU_REG_ACCESS: + case HostCmd_CMD_802_11_EEPROM_ACCESS: + ret = mwifiex_ret_reg_access(cmdresp_no, resp, data_buf); + break; + case HostCmd_CMD_SET_BSS_MODE: + break; + case HostCmd_CMD_11N_CFG: + ret = mwifiex_ret_11n_cfg(priv, resp, data_buf); + break; + default: + dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", + resp->command); + break; + } + + return ret; +} diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c new file mode 100644 index 000000000000..d4a5c1fcefc2 --- /dev/null +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -0,0 +1,405 @@ +/* + * Marvell Wireless LAN device driver: station event handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +/* + * This function resets the connection state. + * + * The function is invoked after receiving a disconnect event from firmware, + * and performs the following actions - + * - Set media status to disconnected + * - Clean up Tx and Rx packets + * - Resets SNR/NF/RSSI value in driver + * - Resets security configurations in driver + * - Enables auto data rate + * - Saves the previous SSID and BSSID so that they can + * be used for re-association, if required + * - Erases current SSID and BSSID information + * - Sends a disconnect event to upper layers/applications. + */ +void +mwifiex_reset_connect_state(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + + if (!priv->media_connected) + return; + + dev_dbg(adapter->dev, "info: handles disconnect event\n"); + + priv->media_connected = false; + + priv->scan_block = false; + + /* Free Tx and Rx packets, report disconnect to upper layer */ + mwifiex_clean_txrx(priv); + + /* Reset SNR/NF/RSSI values */ + priv->data_rssi_last = 0; + priv->data_nf_last = 0; + priv->data_rssi_avg = 0; + priv->data_nf_avg = 0; + priv->bcn_rssi_last = 0; + priv->bcn_nf_last = 0; + priv->bcn_rssi_avg = 0; + priv->bcn_nf_avg = 0; + priv->rxpd_rate = 0; + priv->rxpd_htinfo = 0; + priv->sec_info.wpa_enabled = false; + priv->sec_info.wpa2_enabled = false; + priv->wpa_ie_len = 0; + + priv->sec_info.wapi_enabled = false; + priv->wapi_ie_len = 0; + priv->sec_info.wapi_key_on = false; + + priv->sec_info.encryption_mode = MWIFIEX_ENCRYPTION_MODE_NONE; + + /* Enable auto data rate */ + priv->is_data_rate_auto = true; + priv->data_rate = 0; + + if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + priv->adhoc_state = ADHOC_IDLE; + priv->adhoc_is_link_sensed = false; + } + + /* + * Memorize the previous SSID and BSSID so + * it could be used for re-assoc + */ + + dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n", + priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); + + dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n", + priv->curr_bss_params.bss_descriptor.ssid.ssid, + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + + memcpy(&priv->prev_ssid, + &priv->curr_bss_params.bss_descriptor.ssid, + sizeof(struct mwifiex_802_11_ssid)); + + memcpy(priv->prev_bssid, + priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); + + /* Need to erase the current SSID and BSSID info */ + memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params)); + + adapter->tx_lock_flag = false; + adapter->pps_uapsd_mode = false; + + if (adapter->num_cmd_timeout && adapter->curr_cmd) + return; + priv->media_connected = false; + if (!priv->disconnect) { + priv->disconnect = 1; + dev_dbg(adapter->dev, "info: successfully disconnected from" + " %pM: reason code %d\n", priv->cfg_bssid, + WLAN_REASON_DEAUTH_LEAVING); + cfg80211_disconnected(priv->netdev, + WLAN_REASON_DEAUTH_LEAVING, NULL, 0, + GFP_KERNEL); + queue_work(priv->workqueue, &priv->cfg_workqueue); + } + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); + if (netif_carrier_ok(priv->netdev)) + netif_carrier_off(priv->netdev); + /* Reset wireless stats signal info */ + priv->w_stats.qual.level = 0; + priv->w_stats.qual.noise = 0; +} + +/* + * This function handles events generated by firmware. + * + * This is a generic function and handles all events. + * + * Event specific routines are called by this function based + * upon the generated event cause. + * + * For the following events, the function just forwards them to upper + * layers, optionally recording the change - + * - EVENT_LINK_SENSED + * - EVENT_MIC_ERR_UNICAST + * - EVENT_MIC_ERR_MULTICAST + * - EVENT_PORT_RELEASE + * - EVENT_RSSI_LOW + * - EVENT_SNR_LOW + * - EVENT_MAX_FAIL + * - EVENT_RSSI_HIGH + * - EVENT_SNR_HIGH + * - EVENT_DATA_RSSI_LOW + * - EVENT_DATA_SNR_LOW + * - EVENT_DATA_RSSI_HIGH + * - EVENT_DATA_SNR_HIGH + * - EVENT_LINK_QUALITY + * - EVENT_PRE_BEACON_LOST + * - EVENT_IBSS_COALESCED + * - EVENT_WEP_ICV_ERR + * - EVENT_BW_CHANGE + * - EVENT_HOSTWAKE_STAIE + * + * For the following events, no action is taken - + * - EVENT_MIB_CHANGED + * - EVENT_INIT_DONE + * - EVENT_DUMMY_HOST_WAKEUP_SIGNAL + * + * Rest of the supported events requires driver handling - + * - EVENT_DEAUTHENTICATED + * - EVENT_DISASSOCIATED + * - EVENT_LINK_LOST + * - EVENT_PS_SLEEP + * - EVENT_PS_AWAKE + * - EVENT_DEEP_SLEEP_AWAKE + * - EVENT_HS_ACT_REQ + * - EVENT_ADHOC_BCN_LOST + * - EVENT_BG_SCAN_REPORT + * - EVENT_WMM_STATUS_CHANGE + * - EVENT_ADDBA + * - EVENT_DELBA + * - EVENT_BA_STREAM_TIEMOUT + * - EVENT_AMSDU_AGGR_CTRL + */ +int mwifiex_process_sta_event(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + int ret = 0; + u32 eventcause = adapter->event_cause; + + switch (eventcause) { + case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: + dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL," + " ignoring it\n"); + break; + case EVENT_LINK_SENSED: + dev_dbg(adapter->dev, "event: LINK_SENSED\n"); + if (!netif_carrier_ok(priv->netdev)) + netif_carrier_on(priv->netdev); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); + break; + + case EVENT_DEAUTHENTICATED: + dev_dbg(adapter->dev, "event: Deauthenticated\n"); + adapter->dbg.num_event_deauth++; + if (priv->media_connected) + mwifiex_reset_connect_state(priv); + break; + + case EVENT_DISASSOCIATED: + dev_dbg(adapter->dev, "event: Disassociated\n"); + adapter->dbg.num_event_disassoc++; + if (priv->media_connected) + mwifiex_reset_connect_state(priv); + break; + + case EVENT_LINK_LOST: + dev_dbg(adapter->dev, "event: Link lost\n"); + adapter->dbg.num_event_link_lost++; + if (priv->media_connected) + mwifiex_reset_connect_state(priv); + break; + + case EVENT_PS_SLEEP: + dev_dbg(adapter->dev, "info: EVENT: SLEEP\n"); + + adapter->ps_state = PS_STATE_PRE_SLEEP; + + mwifiex_check_ps_cond(adapter); + break; + + case EVENT_PS_AWAKE: + dev_dbg(adapter->dev, "info: EVENT: AWAKE\n"); + if (!adapter->pps_uapsd_mode && + priv->media_connected && + adapter->sleep_period.period) { + adapter->pps_uapsd_mode = true; + dev_dbg(adapter->dev, + "event: PPS/UAPSD mode activated\n"); + } + adapter->tx_lock_flag = false; + if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { + if (mwifiex_check_last_packet_indication(priv)) { + if (!adapter->data_sent) { + if (!mwifiex_send_null_packet(priv, + MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET + | + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) + adapter->ps_state = + PS_STATE_SLEEP; + return 0; + } + } + } + adapter->ps_state = PS_STATE_AWAKE; + adapter->pm_wakeup_card_req = false; + adapter->pm_wakeup_fw_try = false; + + break; + + case EVENT_DEEP_SLEEP_AWAKE: + adapter->if_ops.wakeup_complete(adapter); + dev_dbg(adapter->dev, "event: DS_AWAKE\n"); + if (adapter->is_deep_sleep) + adapter->is_deep_sleep = false; + break; + + case EVENT_HS_ACT_REQ: + dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, + 0, 0, NULL, NULL); + break; + + case EVENT_MIC_ERR_UNICAST: + dev_dbg(adapter->dev, "event: UNICAST MIC ERROR\n"); + break; + + case EVENT_MIC_ERR_MULTICAST: + dev_dbg(adapter->dev, "event: MULTICAST MIC ERROR\n"); + break; + case EVENT_MIB_CHANGED: + case EVENT_INIT_DONE: + break; + + case EVENT_ADHOC_BCN_LOST: + dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n"); + priv->adhoc_is_link_sensed = false; + mwifiex_clean_txrx(priv); + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); + if (netif_carrier_ok(priv->netdev)) + netif_carrier_off(priv->netdev); + break; + + case EVENT_BG_SCAN_REPORT: + dev_dbg(adapter->dev, "event: BGS_REPORT\n"); + /* Clear the previous scan result */ + memset(adapter->scan_table, 0x00, + sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); + adapter->num_in_scan_table = 0; + adapter->bcn_buf_end = adapter->bcn_buf; + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_BG_SCAN_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL, NULL); + break; + + case EVENT_PORT_RELEASE: + dev_dbg(adapter->dev, "event: PORT RELEASE\n"); + break; + + case EVENT_WMM_STATUS_CHANGE: + dev_dbg(adapter->dev, "event: WMM status changed\n"); + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, + 0, 0, NULL, NULL); + break; + + case EVENT_RSSI_LOW: + dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n"); + break; + case EVENT_SNR_LOW: + dev_dbg(adapter->dev, "event: Beacon SNR_LOW\n"); + break; + case EVENT_MAX_FAIL: + dev_dbg(adapter->dev, "event: MAX_FAIL\n"); + break; + case EVENT_RSSI_HIGH: + dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n"); + break; + case EVENT_SNR_HIGH: + dev_dbg(adapter->dev, "event: Beacon SNR_HIGH\n"); + break; + case EVENT_DATA_RSSI_LOW: + dev_dbg(adapter->dev, "event: Data RSSI_LOW\n"); + break; + case EVENT_DATA_SNR_LOW: + dev_dbg(adapter->dev, "event: Data SNR_LOW\n"); + break; + case EVENT_DATA_RSSI_HIGH: + dev_dbg(adapter->dev, "event: Data RSSI_HIGH\n"); + break; + case EVENT_DATA_SNR_HIGH: + dev_dbg(adapter->dev, "event: Data SNR_HIGH\n"); + break; + case EVENT_LINK_QUALITY: + dev_dbg(adapter->dev, "event: Link Quality\n"); + break; + case EVENT_PRE_BEACON_LOST: + dev_dbg(adapter->dev, "event: Pre-Beacon Lost\n"); + break; + case EVENT_IBSS_COALESCED: + dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, + HostCmd_ACT_GEN_GET, 0, NULL, NULL); + break; + case EVENT_ADDBA: + dev_dbg(adapter->dev, "event: ADDBA Request\n"); + mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, + HostCmd_ACT_GEN_SET, 0, NULL, + adapter->event_body); + break; + case EVENT_DELBA: + dev_dbg(adapter->dev, "event: DELBA Request\n"); + mwifiex_11n_delete_ba_stream(priv, adapter->event_body); + break; + case EVENT_BA_STREAM_TIEMOUT: + dev_dbg(adapter->dev, "event: BA Stream timeout\n"); + mwifiex_11n_ba_stream_timeout(priv, + (struct host_cmd_ds_11n_batimeout + *) + adapter->event_body); + break; + case EVENT_AMSDU_AGGR_CTRL: + dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", + *(u16 *) adapter->event_body); + adapter->tx_buf_size = + min(adapter->curr_tx_buf_size, + le16_to_cpu(*(__le16 *) adapter->event_body)); + dev_dbg(adapter->dev, "event: tx_buf_size %d\n", + adapter->tx_buf_size); + break; + + case EVENT_WEP_ICV_ERR: + dev_dbg(adapter->dev, "event: WEP ICV error\n"); + break; + + case EVENT_BW_CHANGE: + dev_dbg(adapter->dev, "event: BW Change\n"); + break; + + case EVENT_HOSTWAKE_STAIE: + dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause); + break; + default: + dev_dbg(adapter->dev, "event: unknown event id: %#x\n", + eventcause); + break; + } + + return ret; +} diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c new file mode 100644 index 000000000000..665a519b1403 --- /dev/null +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -0,0 +1,2478 @@ +/* + * Marvell Wireless LAN device driver: functions for station ioctl + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" +#include "cfg80211.h" + +/* + * Copies the multicast address list from device to driver. + * + * This function does not validate the destination memory for + * size, and the calling function must ensure enough memory is + * available. + */ +static int +mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, + struct net_device *dev) +{ + int i = 0; + struct netdev_hw_addr *ha; + + netdev_for_each_mc_addr(ha, dev) + memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN); + + return i; +} + +/* + * Allocate and fills a wait queue with proper parameters. + * + * This function needs to be called before an IOCTL request can be made. + * It can handle the following wait options: + * MWIFIEX_NO_WAIT - Waiting is disabled + * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue + * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue + * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue + */ +struct mwifiex_wait_queue * +mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv, + u8 wait_option) +{ + struct mwifiex_wait_queue *wait = NULL; + + wait = (struct mwifiex_wait_queue *) + kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC); + if (!wait) { + dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n", + __func__); + return wait; + } + + wait->bss_index = priv->bss_index; + + switch (wait_option) { + case MWIFIEX_NO_WAIT: + wait->enabled = 0; + break; + case MWIFIEX_IOCTL_WAIT: + priv->ioctl_wait_q_woken = false; + wait->start_time = jiffies; + wait->wait = &priv->ioctl_wait_q; + wait->condition = &priv->ioctl_wait_q_woken; + wait->enabled = 1; + break; + case MWIFIEX_CMD_WAIT: + priv->cmd_wait_q_woken = false; + wait->start_time = jiffies; + wait->wait = &priv->cmd_wait_q; + wait->condition = &priv->cmd_wait_q_woken; + wait->enabled = 1; + break; + case MWIFIEX_WSTATS_WAIT: + priv->w_stats_wait_q_woken = false; + wait->start_time = jiffies; + wait->wait = &priv->w_stats_wait_q; + wait->condition = &priv->w_stats_wait_q_woken; + wait->enabled = 1; + break; + } + + return wait; +} + +/* + * Wait queue completion handler. + * + * This function waits on a particular wait queue. + * For NO_WAIT option, it returns immediately. It also cancels the + * pending IOCTL request after waking up, in case of errors. + */ +static void +mwifiex_wait_ioctl_complete(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u8 wait_option) +{ + bool cancel_flag = false; + + switch (wait_option) { + case MWIFIEX_NO_WAIT: + break; + case MWIFIEX_IOCTL_WAIT: + wait_event_interruptible(priv->ioctl_wait_q, + priv->ioctl_wait_q_woken); + if (!priv->ioctl_wait_q_woken) + cancel_flag = true; + break; + case MWIFIEX_CMD_WAIT: + wait_event_interruptible(priv->cmd_wait_q, + priv->cmd_wait_q_woken); + if (!priv->cmd_wait_q_woken) + cancel_flag = true; + break; + case MWIFIEX_WSTATS_WAIT: + wait_event_interruptible(priv->w_stats_wait_q, + priv->w_stats_wait_q_woken); + if (!priv->w_stats_wait_q_woken) + cancel_flag = true; + break; + } + if (cancel_flag) { + mwifiex_cancel_pending_ioctl(priv->adapter, wait); + dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n", + wait, wait_option); + } + + return; +} + +/* + * The function waits for the request to complete and issues the + * completion handler, if required. + */ +int mwifiex_request_ioctl(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + int status, u8 wait_option) +{ + switch (status) { + case -EINPROGRESS: + dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n", + wait, wait_option); + atomic_inc(&priv->adapter->ioctl_pending); + /* Status pending, wake up main process */ + queue_work(priv->adapter->workqueue, &priv->adapter->main_work); + + /* Wait for completion */ + if (wait_option) { + mwifiex_wait_ioctl_complete(priv, wait, wait_option); + status = wait->status; + } + break; + case 0: + case -1: + case -EBUSY: + default: + break; + } + return status; +} +EXPORT_SYMBOL_GPL(mwifiex_request_ioctl); + +/* + * IOCTL request handler to set/get MAC address. + * + * This function prepares the correct firmware command and + * issues it to get the extended version information. + */ +static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u8 action, u8 *mac) +{ + int ret = 0; + + if ((action == HostCmd_ACT_GEN_GET) && mac) { + memcpy(mac, priv->curr_addr, ETH_ALEN); + return 0; + } + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS, + action, 0, wait, mac); + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * Sends IOCTL request to set MAC address. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_request_set_mac_address(struct mwifiex_private *priv) +{ + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + u8 wait_option = MWIFIEX_CMD_WAIT; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET, + NULL); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + if (!status) + memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); + else + dev_err(priv->adapter->dev, "set mac address failed: status=%d" + " error_code=%#x\n", status, wait->status); + + kfree(wait); + return status; +} + +/* + * IOCTL request handler to set multicast list. + * + * This function prepares the correct firmware command and + * issues it to set the multicast list. + * + * This function can be used to enable promiscuous mode, or enable all + * multicast packets, or to enable selective multicast. + */ +static int +mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u16 action, + struct mwifiex_multicast_list *mcast_list) +{ + int ret = 0; + u16 old_pkt_filter; + + old_pkt_filter = priv->curr_pkt_filter; + if (action == HostCmd_ACT_GEN_GET) + return -1; + + if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { + dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); + priv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; + priv->curr_pkt_filter &= + ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; + } else { + /* Multicast */ + priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; + if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) { + dev_dbg(priv->adapter->dev, + "info: Enabling All Multicast!\n"); + priv->curr_pkt_filter |= + HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; + } else { + priv->curr_pkt_filter &= + ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; + if (mcast_list->num_multicast_addr) { + dev_dbg(priv->adapter->dev, + "info: Set multicast list=%d\n", + mcast_list->num_multicast_addr); + /* Set multicast addresses to firmware */ + if (old_pkt_filter == priv->curr_pkt_filter) { + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_MAC_MULTICAST_ADR, + action, 0, wait, mcast_list); + if (!ret) + ret = -EINPROGRESS; + } else { + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_MAC_MULTICAST_ADR, + action, 0, NULL, + mcast_list); + } + } + } + } + dev_dbg(priv->adapter->dev, + "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", + old_pkt_filter, priv->curr_pkt_filter); + if (old_pkt_filter != priv->curr_pkt_filter) { + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action, + 0, wait, &priv->curr_pkt_filter); + if (!ret) + ret = -EINPROGRESS; + } + + return ret; +} + +/* + * Sends IOCTL request to set multicast list. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +void +mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + struct net_device *dev) +{ + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_multicast_list mcast_list; + u8 wait_option = MWIFIEX_NO_WAIT; + int status = 0; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return; + + if (dev->flags & IFF_PROMISC) { + mcast_list.mode = MWIFIEX_PROMISC_MODE; + } else if (dev->flags & IFF_ALLMULTI || + netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { + mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; + } else { + mcast_list.mode = MWIFIEX_MULTICAST_MODE; + if (netdev_mc_count(dev)) + mcast_list.num_multicast_addr = + mwifiex_copy_mcast_addr(&mcast_list, dev); + } + status = mwifiex_bss_ioctl_multicast_list(priv, wait, + HostCmd_ACT_GEN_SET, + &mcast_list); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + if (wait && status != -EINPROGRESS) + kfree(wait); + + return; +} + +/* + * IOCTL request handler to disconnect from a BSS/IBSS. + */ +static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, u8 *mac) +{ + return mwifiex_deauthenticate(priv, wait, mac); +} + +/* + * Sends IOCTL request to disconnect from a BSS. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac) +{ + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_bss_ioctl_stop(priv, wait, mac); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + + kfree(wait); + return status; +} +EXPORT_SYMBOL_GPL(mwifiex_disconnect); + +/* + * IOCTL request handler to join a BSS/IBSS. + * + * In Ad-Hoc mode, the IBSS is created if not found in scan list. + * In both Ad-Hoc and infra mode, an deauthentication is performed + * first. + */ +static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ssid_bssid *ssid_bssid) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + s32 i = -1; + + priv->scan_block = false; + if (!ssid_bssid) + return -1; + + if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) { + /* Infra mode */ + ret = mwifiex_deauthenticate(priv, NULL, NULL); + if (ret) + return ret; + + /* Search for the requested SSID in the scan table */ + if (ssid_bssid->ssid.ssid_len) + i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, + NULL, MWIFIEX_BSS_MODE_INFRA); + else + i = mwifiex_find_bssid_in_list(priv, + (u8 *) &ssid_bssid->bssid, + MWIFIEX_BSS_MODE_INFRA); + if (i < 0) + return -1; + + dev_dbg(adapter->dev, + "info: SSID found in scan list ... associating...\n"); + + /* Clear any past association response stored for + * application retrieval */ + priv->assoc_rsp_size = 0; + ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]); + if (ret) + return ret; + } else { + /* Adhoc mode */ + /* If the requested SSID matches current SSID, return */ + if (ssid_bssid->ssid.ssid_len && + (!mwifiex_ssid_cmp + (&priv->curr_bss_params.bss_descriptor.ssid, + &ssid_bssid->ssid))) + return 0; + + /* Exit Adhoc mode first */ + dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); + ret = mwifiex_deauthenticate(priv, NULL, NULL); + if (ret) + return ret; + + priv->adhoc_is_link_sensed = false; + + /* Search for the requested network in the scan table */ + if (ssid_bssid->ssid.ssid_len) + i = mwifiex_find_ssid_in_list(priv, + &ssid_bssid->ssid, NULL, + MWIFIEX_BSS_MODE_IBSS); + else + i = mwifiex_find_bssid_in_list(priv, + (u8 *)&ssid_bssid->bssid, + MWIFIEX_BSS_MODE_IBSS); + + if (i >= 0) { + dev_dbg(adapter->dev, "info: network found in scan" + " list. Joining...\n"); + ret = mwifiex_adhoc_join(priv, wait, + &adapter->scan_table[i]); + if (ret) + return ret; + } else { /* i >= 0 */ + dev_dbg(adapter->dev, "info: Network not found in " + "the list, creating adhoc with ssid = %s\n", + ssid_bssid->ssid.ssid); + ret = mwifiex_adhoc_start(priv, wait, + &ssid_bssid->ssid); + if (ret) + return ret; + } + } + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * Sends IOCTL request to connect with a BSS. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option, + struct mwifiex_ssid_bssid *ssid_bssid) +{ + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ssid_bssid tmp_ssid_bssid; + int status = 0; + + /* Stop the O.S. TX queue if needed */ + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + if (ssid_bssid) + memcpy(&tmp_ssid_bssid, ssid_bssid, + sizeof(struct mwifiex_ssid_bssid)); + status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + + kfree(wait); + return status; +} + +/* + * IOCTL request handler to set host sleep configuration. + * + * This function prepares the correct firmware command and + * issues it. + */ +static int +mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u16 action, struct mwifiex_ds_hs_cfg *hs_cfg) +{ + struct mwifiex_adapter *adapter = priv->adapter; + int status = 0; + u32 prev_cond = 0; + + switch (action) { + case HostCmd_ACT_GEN_SET: + if (adapter->pps_uapsd_mode) { + dev_dbg(adapter->dev, "info: Host Sleep IOCTL" + " is blocked in UAPSD/PPS mode\n"); + status = -1; + break; + } + if (hs_cfg->is_invoke_hostcmd) { + if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) { + if (!adapter->is_hs_configured) + /* Already cancelled */ + break; + /* Save previous condition */ + prev_cond = le32_to_cpu(adapter->hs_cfg + .conditions); + adapter->hs_cfg.conditions = + cpu_to_le32(hs_cfg->conditions); + } else if (hs_cfg->conditions) { + adapter->hs_cfg.conditions = + cpu_to_le32(hs_cfg->conditions); + adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; + if (hs_cfg->gap) + adapter->hs_cfg.gap = (u8)hs_cfg->gap; + } else if (adapter->hs_cfg.conditions == + cpu_to_le32( + HOST_SLEEP_CFG_CANCEL)) { + /* Return failure if no parameters for HS + enable */ + status = -1; + break; + } + status = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + HostCmd_ACT_GEN_SET, + 0, wait, &adapter->hs_cfg); + if (!status) + status = -EINPROGRESS; + if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) + /* Restore previous condition */ + adapter->hs_cfg.conditions = + cpu_to_le32(prev_cond); + } else { + adapter->hs_cfg.conditions = + cpu_to_le32(hs_cfg->conditions); + adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; + adapter->hs_cfg.gap = (u8)hs_cfg->gap; + } + break; + case HostCmd_ACT_GEN_GET: + hs_cfg->conditions = le32_to_cpu(adapter->hs_cfg.conditions); + hs_cfg->gpio = adapter->hs_cfg.gpio; + hs_cfg->gap = adapter->hs_cfg.gap; + break; + default: + status = -1; + break; + } + + return status; +} + +/* + * Sends IOCTL request to set Host Sleep parameters. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, + u8 wait_option, + struct mwifiex_ds_hs_cfg *hscfg) +{ + int ret = 0; + struct mwifiex_wait_queue *wait = NULL; + + if (!hscfg) + return -ENOMEM; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg); + + ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); + + if (wait && (ret != -EINPROGRESS)) + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to cancel the existing Host Sleep configuration. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) +{ + int ret = 0; + struct mwifiex_ds_hs_cfg hscfg; + + /* Cancel Host Sleep */ + hscfg.conditions = HOST_SLEEP_CFG_CANCEL; + hscfg.is_invoke_hostcmd = true; + ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, + wait_option, &hscfg); + + return ret; +} +EXPORT_SYMBOL_GPL(mwifiex_cancel_hs); + +/* + * Sends IOCTL request to cancel the existing Host Sleep configuration. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_enable_hs(struct mwifiex_adapter *adapter) +{ + struct mwifiex_ds_hs_cfg hscfg; + + if (adapter->hs_activated) { + dev_dbg(adapter->dev, "cmd: HS Already actived\n"); + return true; + } + + /* Enable Host Sleep */ + adapter->hs_activate_wait_q_woken = false; + + memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); + hscfg.is_invoke_hostcmd = true; + + if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_STA), + HostCmd_ACT_GEN_SET, + MWIFIEX_IOCTL_WAIT, &hscfg)) { + dev_err(adapter->dev, "IOCTL request HS enable failed\n"); + return false; + } + + wait_event_interruptible(adapter->hs_activate_wait_q, + adapter->hs_activate_wait_q_woken); + + return true; +} +EXPORT_SYMBOL_GPL(mwifiex_enable_hs); + +/* + * IOCTL request handler to get signal information. + * + * This function prepares the correct firmware command and + * issues it to get the signal (RSSI) information. + * + * This only works in the connected mode. + */ +static int mwifiex_get_info_signal(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_get_signal *signal) +{ + int ret = 0; + + if (!wait) { + dev_err(priv->adapter->dev, "WAIT information is not present\n"); + return -1; + } + + /* Signal info can be obtained only if connected */ + if (!priv->media_connected) { + dev_dbg(priv->adapter->dev, + "info: Can not get signal in disconnected state\n"); + return -1; + } + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO, + HostCmd_ACT_GEN_GET, 0, wait, signal); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to get statistics. + * + * This function prepares the correct firmware command and + * issues it to get the statistics (RSSI) information. + */ +static int mwifiex_get_info_stats(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_get_stats *log) +{ + int ret = 0; + + if (!wait) { + dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n"); + return -1; + } + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG, + HostCmd_ACT_GEN_GET, 0, wait, log); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to get BSS information. + * + * This function collates the information from different driver structures + * to send to the user. + */ +int mwifiex_get_bss_info(struct mwifiex_private *priv, + struct mwifiex_bss_info *info) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_bssdescriptor *bss_desc; + s32 tbl_idx = 0; + + if (!info) + return -1; + + /* Get current BSS info */ + bss_desc = &priv->curr_bss_params.bss_descriptor; + + /* BSS mode */ + info->bss_mode = priv->bss_mode; + + /* SSID */ + memcpy(&info->ssid, &bss_desc->ssid, + sizeof(struct mwifiex_802_11_ssid)); + + /* BSSID */ + memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); + + /* Channel */ + info->bss_chan = bss_desc->channel; + + /* Region code */ + info->region_code = adapter->region_code; + + /* Scan table index if connected */ + info->scan_table_idx = 0; + if (priv->media_connected) { + tbl_idx = + mwifiex_find_ssid_in_list(priv, &bss_desc->ssid, + bss_desc->mac_address, + priv->bss_mode); + if (tbl_idx >= 0) + info->scan_table_idx = tbl_idx; + } + + /* Connection status */ + info->media_connected = priv->media_connected; + + /* Radio status */ + info->radio_on = adapter->radio_on; + + /* Tx power information */ + info->max_power_level = priv->max_tx_power_level; + info->min_power_level = priv->min_tx_power_level; + + /* AdHoc state */ + info->adhoc_state = priv->adhoc_state; + + /* Last beacon NF */ + info->bcn_nf_last = priv->bcn_nf_last; + + /* wep status */ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + info->wep_status = true; + else + info->wep_status = false; + + info->is_hs_configured = adapter->is_hs_configured; + info->is_deep_sleep = adapter->is_deep_sleep; + + return 0; +} + +/* + * IOCTL request handler to get extended version information. + * + * This function prepares the correct firmware command and + * issues it to get the extended version information. + */ +static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ver_ext *ver_ext) +{ + int ret = 0; + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT, + HostCmd_ACT_GEN_GET, 0, wait, ver_ext); + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/get SNMP MIB parameters. + * + * This function prepares the correct firmware command and + * issues it. + * + * Currently the following parameters are supported - + * Set/get RTS Threshold + * Set/get fragmentation threshold + * Set/get retry count + */ +int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u32 cmd_oid, u16 action, u32 *value) +{ + int ret = 0; + + if (!value) + return -1; + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, + action, cmd_oid, wait, value); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/get band configurations. + * + * For SET operation, it performs extra checks to make sure the Ad-Hoc + * band and channel are compatible. Otherwise it returns an error. + * + * For GET operation, this function retrieves the following information - + * - Infra bands + * - Ad-hoc band + * - Ad-hoc channel + * - Secondary channel offset + */ +int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, + u16 action, + struct mwifiex_ds_band_cfg *radio_cfg) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u8 infra_band = 0; + u8 adhoc_band = 0; + u32 adhoc_channel = 0; + + if (action == HostCmd_ACT_GEN_GET) { + /* Infra Bands */ + radio_cfg->config_bands = adapter->config_bands; + /* Adhoc Band */ + radio_cfg->adhoc_start_band = adapter->adhoc_start_band; + /* Adhoc channel */ + radio_cfg->adhoc_channel = priv->adhoc_channel; + /* Secondary channel offset */ + radio_cfg->sec_chan_offset = adapter->chan_offset; + return 0; + } + + /* For action = SET */ + infra_band = (u8) radio_cfg->config_bands; + adhoc_band = (u8) radio_cfg->adhoc_start_band; + adhoc_channel = radio_cfg->adhoc_channel; + + /* SET Infra band */ + if ((infra_band | adapter->fw_bands) & ~adapter->fw_bands) + return -1; + + adapter->config_bands = infra_band; + + /* SET Ad-hoc Band */ + if ((adhoc_band | adapter->fw_bands) & ~adapter->fw_bands) + return -1; + + if (adhoc_band) + adapter->adhoc_start_band = adhoc_band; + adapter->chan_offset = (u8) radio_cfg->sec_chan_offset; + /* + * If no adhoc_channel is supplied verify if the existing adhoc + * channel compiles with new adhoc_band + */ + if (!adhoc_channel) { + if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, adapter->adhoc_start_band, + priv->adhoc_channel)) { + /* Pass back the default channel */ + radio_cfg->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; + if ((adapter->adhoc_start_band & BAND_A) + || (adapter->adhoc_start_band & BAND_AN)) + radio_cfg->adhoc_channel = + DEFAULT_AD_HOC_CHANNEL_A; + } + } else { /* Retrurn error if adhoc_band and + adhoc_channel combination is invalid */ + if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, adapter->adhoc_start_band, (u16) adhoc_channel)) + return -1; + priv->adhoc_channel = (u8) adhoc_channel; + } + if ((adhoc_band & BAND_GN) || (adhoc_band & BAND_AN)) + adapter->adhoc_11n_enabled = true; + else + adapter->adhoc_11n_enabled = false; + + return 0; +} + +/* + * IOCTL request handler to set/get active channel. + * + * This function performs validity checking on channel/frequency + * compatibility and returns failure if not valid. + */ +int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, + struct mwifiex_chan_freq_power *chan) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct mwifiex_chan_freq_power *cfp = NULL; + + if (!chan) + return -1; + + if (action == HostCmd_ACT_GEN_GET) { + cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, + priv->curr_bss_params.band, + (u16) priv->curr_bss_params.bss_descriptor. + channel); + chan->channel = cfp->channel; + chan->freq = cfp->freq; + + return 0; + } + if (!chan->channel && !chan->freq) + return -1; + if (adapter->adhoc_start_band & BAND_AN) + adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN; + else if (adapter->adhoc_start_band & BAND_A) + adapter->adhoc_start_band = BAND_G | BAND_B; + if (chan->channel) { + if (chan->channel <= MAX_CHANNEL_BAND_BG) + cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, 0, (u16) chan->channel); + if (!cfp) { + cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 + (priv, BAND_A, (u16) chan->channel); + if (cfp) { + if (adapter->adhoc_11n_enabled) + adapter->adhoc_start_band = BAND_A + | BAND_AN; + else + adapter->adhoc_start_band = BAND_A; + } + } + } else { + if (chan->freq <= MAX_FREQUENCY_BAND_BG) + cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211( + priv, 0, chan->freq); + if (!cfp) { + cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211 + (priv, BAND_A, chan->freq); + if (cfp) { + if (adapter->adhoc_11n_enabled) + adapter->adhoc_start_band = BAND_A + | BAND_AN; + else + adapter->adhoc_start_band = BAND_A; + } + } + } + if (!cfp || !cfp->channel) { + dev_err(adapter->dev, "invalid channel/freq\n"); + return -1; + } + priv->adhoc_channel = (u8) cfp->channel; + chan->channel = cfp->channel; + chan->freq = cfp->freq; + + return 0; +} + +/* + * IOCTL request handler to set/get BSS mode. + * + * This function prepares the correct firmware command and + * issues it to set or get the BSS mode. + * + * In case the mode is changed, a deauthentication is performed + * first by the function automatically. + */ +int mwifiex_bss_ioctl_mode(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u16 action, int *mode) +{ + int ret = 0; + + if (!mode) + return -1; + + if (action == HostCmd_ACT_GEN_GET) { + *mode = priv->bss_mode; + return 0; + } + + if ((priv->bss_mode == *mode) || (*mode == MWIFIEX_BSS_MODE_AUTO)) { + dev_dbg(priv->adapter->dev, + "info: Already set to required mode! No change!\n"); + priv->bss_mode = *mode; + return 0; + } + + ret = mwifiex_deauthenticate(priv, wait, NULL); + + priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN; + priv->bss_mode = *mode; + if (priv->bss_mode != MWIFIEX_BSS_MODE_AUTO) { + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, + HostCmd_ACT_GEN_SET, 0, wait, NULL); + if (!ret) + ret = -EINPROGRESS; + } + + return ret; +} + +/* + * IOCTL request handler to set/get Ad-Hoc channel. + * + * This function prepares the correct firmware command and + * issues it to set or get the ad-hoc channel. + */ +static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u16 action, u16 *channel) +{ + int ret = 0; + + if (action == HostCmd_ACT_GEN_GET) { + if (!priv->media_connected) { + *channel = priv->adhoc_channel; + return ret; + } + } else { + priv->adhoc_channel = (u8) *channel; + } + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL, + action, 0, wait, channel); + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to find a particular BSS. + * + * The BSS can be searched with either a BSSID or a SSID. If none of + * these are provided, just the best BSS (best RSSI) is returned. + */ +int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ssid_bssid *ssid_bssid) +{ + struct mwifiex_adapter *adapter = priv->adapter; + int ret = 0; + struct mwifiex_bssdescriptor *bss_desc; + u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + u8 mac[ETH_ALEN]; + int i = 0; + + if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) { + i = mwifiex_find_bssid_in_list(priv, + (u8 *) ssid_bssid->bssid, + priv->bss_mode); + if (i < 0) { + memcpy(mac, ssid_bssid->bssid, sizeof(mac)); + dev_err(adapter->dev, "cannot find bssid %pM\n", mac); + return -1; + } + bss_desc = &adapter->scan_table[i]; + memcpy(&ssid_bssid->ssid, &bss_desc->ssid, + sizeof(struct mwifiex_802_11_ssid)); + } else if (ssid_bssid->ssid.ssid_len) { + i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL, + priv->bss_mode); + if (i < 0) { + dev_err(adapter->dev, "cannot find ssid %s\n", + ssid_bssid->ssid.ssid); + return -1; + } + bss_desc = &adapter->scan_table[i]; + memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN); + } else { + ret = mwifiex_find_best_network(priv, ssid_bssid); + } + + return ret; +} + +/* + * IOCTL request handler to change Ad-Hoc channel. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + * + * The function follows the following steps to perform the change - + * - Get current IBSS information + * - Get current channel + * - If no change is required, return + * - If not connected, change channel and return + * - If connected, + * - Disconnect + * - Change channel + * - Perform specific SSID scan with same SSID + * - Start/Join the IBSS + */ +int +mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) +{ + int ret = 0; + int status = 0; + struct mwifiex_bss_info bss_info; + struct mwifiex_wait_queue *wait = NULL; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + struct mwifiex_ssid_bssid ssid_bssid; + u16 curr_chan = 0; + + memset(&bss_info, 0, sizeof(bss_info)); + + /* Get BSS information */ + if (mwifiex_get_bss_info(priv, &bss_info)) + return -1; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + /* Get current channel */ + status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET, + &curr_chan); + + if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { + ret = -1; + goto done; + } + if (curr_chan == channel) { + ret = 0; + goto done; + } + dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", + curr_chan, channel); + + if (!bss_info.media_connected) { + ret = 0; + goto done; + } + + /* Do disonnect */ + memset(&ssid_bssid, 0, ETH_ALEN); + status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid); + + if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { + ret = -1; + goto done; + } + + status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET, + (u16 *) &channel); + + if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { + ret = -1; + goto done; + } + + /* Do specific SSID scanning */ + if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) { + ret = -1; + goto done; + } + /* Start/Join Adhoc network */ + memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); + memcpy(&ssid_bssid.ssid, &bss_info.ssid, + sizeof(struct mwifiex_802_11_ssid)); + + status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid); + + if (mwifiex_request_ioctl(priv, wait, status, wait_option)) + ret = -1; + +done: + kfree(wait); + return ret; +} + +/* + * IOCTL request handler to get current driver mode. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_drv_get_mode(struct mwifiex_private *priv, u8 wait_option) +{ + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + int mode = -1; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -1; + + status = mwifiex_bss_ioctl_mode(priv, wait, HostCmd_ACT_GEN_GET, &mode); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + + if (wait && (status != -EINPROGRESS)) + kfree(wait); + return mode; +} + +/* + * IOCTL request handler to get rate. + * + * This function prepares the correct firmware command and + * issues it to get the current rate if it is connected, + * otherwise, the function returns the lowest supported rate + * for the band. + */ +static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_rate_cfg *rate_cfg) +{ + struct mwifiex_adapter *adapter = priv->adapter; + int ret = 0; + + rate_cfg->is_rate_auto = priv->is_data_rate_auto; + if (!priv->media_connected) { + switch (adapter->config_bands) { + case BAND_B: + /* Return the lowest supported rate for B band */ + rate_cfg->rate = supported_rates_b[0] & 0x7f; + break; + case BAND_G: + case BAND_G | BAND_GN: + /* Return the lowest supported rate for G band */ + rate_cfg->rate = supported_rates_g[0] & 0x7f; + break; + case BAND_B | BAND_G: + case BAND_A | BAND_B | BAND_G: + case BAND_A | BAND_B: + case BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN: + case BAND_B | BAND_G | BAND_GN: + /* Return the lowest supported rate for BG band */ + rate_cfg->rate = supported_rates_bg[0] & 0x7f; + break; + case BAND_A: + case BAND_A | BAND_G: + case BAND_A | BAND_G | BAND_AN | BAND_GN: + case BAND_A | BAND_AN: + /* Return the lowest supported rate for A band */ + rate_cfg->rate = supported_rates_a[0] & 0x7f; + break; + case BAND_GN: + /* Return the lowest supported rate for N band */ + rate_cfg->rate = supported_rates_n[0] & 0x7f; + break; + default: + dev_warn(adapter->dev, "invalid band %#x\n", + adapter->config_bands); + break; + } + } else { + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_TX_RATE_QUERY, + HostCmd_ACT_GEN_GET, 0, wait, NULL); + if (!ret) + ret = -EINPROGRESS; + } + + return ret; +} + +/* + * IOCTL request handler to set rate. + * + * This function prepares the correct firmware command and + * issues it to set the current rate. + * + * The function also performs validation checking on the supplied value. + */ +static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_rate_cfg *rate_cfg) +{ + u8 rates[MWIFIEX_SUPPORTED_RATES]; + u8 *rate = NULL; + int rate_index = 0; + u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; + u32 i = 0; + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + + if (rate_cfg->is_rate_auto) { + memset(bitmap_rates, 0, sizeof(bitmap_rates)); + /* Support all HR/DSSS rates */ + bitmap_rates[0] = 0x000F; + /* Support all OFDM rates */ + bitmap_rates[1] = 0x00FF; + /* Support all HT-MCSs rate */ + for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates) - 3; i++) + bitmap_rates[i + 2] = 0xFFFF; + bitmap_rates[9] = 0x3FFF; + } else { + memset(rates, 0, sizeof(rates)); + mwifiex_get_active_data_rates(priv, rates); + rate = rates; + for (i = 0; (rate[i] && i < MWIFIEX_SUPPORTED_RATES); i++) { + dev_dbg(adapter->dev, "info: rate=%#x wanted=%#x\n", + rate[i], rate_cfg->rate); + if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f)) + break; + } + if (!rate[i] || (i == MWIFIEX_SUPPORTED_RATES)) { + dev_err(adapter->dev, "fixed data rate %#x is out " + "of range\n", rate_cfg->rate); + return -1; + } + memset(bitmap_rates, 0, sizeof(bitmap_rates)); + + rate_index = + mwifiex_data_rate_to_index(adapter, rate_cfg->rate); + + /* Only allow b/g rates to be set */ + if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && + rate_index <= MWIFIEX_RATE_INDEX_HRDSSS3) { + bitmap_rates[0] = 1 << rate_index; + } else { + rate_index -= 1; /* There is a 0x00 in the table */ + if (rate_index >= MWIFIEX_RATE_INDEX_OFDM0 && + rate_index <= MWIFIEX_RATE_INDEX_OFDM7) + bitmap_rates[1] = 1 << (rate_index - + MWIFIEX_RATE_INDEX_OFDM0); + } + } + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, + HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates); + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/get rate. + * + * This function can be used to set/get either the rate value or the + * rate index. + */ +static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_rate_cfg *rate_cfg) +{ + int status = 0; + + if (!rate_cfg) + return -1; + + if (rate_cfg->action == HostCmd_ACT_GEN_GET) + status = mwifiex_rate_ioctl_get_rate_value( + priv, wait, rate_cfg); + else + status = mwifiex_rate_ioctl_set_rate_value( + priv, wait, rate_cfg); + + return status; +} + +/* + * Sends IOCTL request to get the data rate. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, + struct mwifiex_rate_cfg *rate) +{ + int ret = 0; + struct mwifiex_wait_queue *wait = NULL; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); + rate->action = HostCmd_ACT_GEN_GET; + ret = mwifiex_rate_ioctl_cfg(priv, wait, rate); + + ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); + if (!ret) { + if (rate && rate->is_rate_auto) + rate->rate = mwifiex_index_to_data_rate(priv->adapter, + priv->tx_rate, priv->tx_htinfo); + else if (rate) + rate->rate = priv->data_rate; + } else { + ret = -1; + } + + kfree(wait); + return ret; +} + +/* + * IOCTL request handler to set tx power configuration. + * + * This function prepares the correct firmware command and + * issues it. + * + * For non-auto power mode, all the following power groups are set - + * - Modulation class HR/DSSS + * - Modulation class OFDM + * - Modulation class HTBW20 + * - Modulation class HTBW40 + */ +static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_power_cfg *power_cfg) +{ + int ret = 0; + struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; + struct mwifiex_types_power_group *pg_tlv = NULL; + struct mwifiex_power_group *pg = NULL; + u8 *buf = NULL; + u16 dbm = 0; + + if (!power_cfg->is_power_auto) { + dbm = (u16) power_cfg->power_level; + if ((dbm < priv->min_tx_power_level) || + (dbm > priv->max_tx_power_level)) { + dev_err(priv->adapter->dev, "txpower value %d dBm" + " is out of range (%d dBm-%d dBm)\n", + dbm, priv->min_tx_power_level, + priv->max_tx_power_level); + return -1; + } + } + buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); + if (!buf) { + dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", + __func__); + return -1; + } + + txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf; + txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); + if (!power_cfg->is_power_auto) { + txp_cfg->mode = cpu_to_le32(1); + pg_tlv = (struct mwifiex_types_power_group *) (buf + + sizeof(struct host_cmd_ds_txpwr_cfg)); + pg_tlv->type = TLV_TYPE_POWER_GROUP; + pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); + pg = (struct mwifiex_power_group *) (buf + + sizeof(struct host_cmd_ds_txpwr_cfg) + + sizeof(struct mwifiex_types_power_group)); + /* Power group for modulation class HR/DSSS */ + pg->first_rate_code = 0x00; + pg->last_rate_code = 0x03; + pg->modulation_class = MOD_CLASS_HR_DSSS; + pg->power_step = 0; + pg->power_min = (s8) dbm; + pg->power_max = (s8) dbm; + pg++; + /* Power group for modulation class OFDM */ + pg->first_rate_code = 0x00; + pg->last_rate_code = 0x07; + pg->modulation_class = MOD_CLASS_OFDM; + pg->power_step = 0; + pg->power_min = (s8) dbm; + pg->power_max = (s8) dbm; + pg++; + /* Power group for modulation class HTBW20 */ + pg->first_rate_code = 0x00; + pg->last_rate_code = 0x20; + pg->modulation_class = MOD_CLASS_HT; + pg->power_step = 0; + pg->power_min = (s8) dbm; + pg->power_max = (s8) dbm; + pg->ht_bandwidth = HT_BW_20; + pg++; + /* Power group for modulation class HTBW40 */ + pg->first_rate_code = 0x00; + pg->last_rate_code = 0x20; + pg->modulation_class = MOD_CLASS_HT; + pg->power_step = 0; + pg->power_min = (s8) dbm; + pg->power_max = (s8) dbm; + pg->ht_bandwidth = HT_BW_40; + } + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, + HostCmd_ACT_GEN_SET, 0, wait, buf); + if (!ret) + ret = -EINPROGRESS; + kfree(buf); + + return ret; +} + +/* + * IOCTL request handler to get power save mode. + * + * This function prepares the correct firmware command and + * issues it. + */ +static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + u32 *ps_mode, u16 action) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + u16 sub_cmd; + + if (action == HostCmd_ACT_GEN_SET) { + if (*ps_mode) + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; + else + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; + sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, + sub_cmd, BITMAP_STA_PS, wait, NULL); + if ((!ret) && (sub_cmd == DIS_AUTO_PS)) + ret = mwifiex_prepare_cmd(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, + 0, NULL, NULL); + } else { + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, + GET_PS, 0, wait, NULL); + } + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/reset WPA IE. + * + * The supplied WPA IE is treated as a opaque buffer. Only the first field + * is checked to determine WPA version. If buffer length is zero, the existing + * WPA IE is reset. + */ +static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, + u8 *ie_data_ptr, u16 ie_len) +{ + if (ie_len) { + if (ie_len > sizeof(priv->wpa_ie)) { + dev_err(priv->adapter->dev, + "failed to copy WPA IE, too big\n"); + return -1; + } + memcpy(priv->wpa_ie, ie_data_ptr, ie_len); + priv->wpa_ie_len = (u8) ie_len; + dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", + priv->wpa_ie_len, priv->wpa_ie[0]); + + if (priv->wpa_ie[0] == WLAN_EID_WPA) { + priv->sec_info.wpa_enabled = true; + } else if (priv->wpa_ie[0] == WLAN_EID_RSN) { + priv->sec_info.wpa2_enabled = true; + } else { + priv->sec_info.wpa_enabled = false; + priv->sec_info.wpa2_enabled = false; + } + } else { + memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie)); + priv->wpa_ie_len = 0; + dev_dbg(priv->adapter->dev, "info: reset wpa_ie_len=%d IE=%#x\n", + priv->wpa_ie_len, priv->wpa_ie[0]); + priv->sec_info.wpa_enabled = false; + priv->sec_info.wpa2_enabled = false; + } + + return 0; +} + +/* + * IOCTL request handler to set/reset WAPI IE. + * + * The supplied WAPI IE is treated as a opaque buffer. Only the first field + * is checked to internally enable WAPI. If buffer length is zero, the existing + * WAPI IE is reset. + */ +static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, + u8 *ie_data_ptr, u16 ie_len) +{ + if (ie_len) { + if (ie_len > sizeof(priv->wapi_ie)) { + dev_dbg(priv->adapter->dev, + "info: failed to copy WAPI IE, too big\n"); + return -1; + } + memcpy(priv->wapi_ie, ie_data_ptr, ie_len); + priv->wapi_ie_len = ie_len; + dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", + priv->wapi_ie_len, priv->wapi_ie[0]); + + if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) + priv->sec_info.wapi_enabled = true; + } else { + memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie)); + priv->wapi_ie_len = ie_len; + dev_dbg(priv->adapter->dev, + "info: Reset wapi_ie_len=%d IE=%#x\n", + priv->wapi_ie_len, priv->wapi_ie[0]); + priv->sec_info.wapi_enabled = false; + } + return 0; +} + +/* + * IOCTL request handler to set WAPI key. + * + * This function prepares the correct firmware command and + * issues it. + */ +static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_encrypt_key *encrypt_key) +{ + int ret = 0; + struct mwifiex_private *priv = adapter->priv[wait->bss_index]; + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + wait, encrypt_key); + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/get authentication mode. + */ +static int mwifiex_set_auth_mode(struct mwifiex_private *priv, u32 auth_mode) +{ + int ret = 0; + + priv->sec_info.authentication_mode = auth_mode; + if (priv->sec_info.authentication_mode == MWIFIEX_AUTH_MODE_NETWORKEAP) + ret = mwifiex_set_wpa_ie_helper(priv, NULL, 0); + + return ret; +} + +/* + * IOCTL request handler to set WEP network key. + * + * This function prepares the correct firmware command and + * issues it, after validation checks. + */ +static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_encrypt_key *encrypt_key) +{ + int ret = 0; + struct mwifiex_private *priv = adapter->priv[wait->bss_index]; + struct mwifiex_wep_key *wep_key = NULL; + int index; + + if (priv->wep_key_curr_index >= NUM_WEP_KEYS) + priv->wep_key_curr_index = 0; + wep_key = &priv->wep_key[priv->wep_key_curr_index]; + index = encrypt_key->key_index; + if (encrypt_key->key_disable) { + priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED; + } else if (!encrypt_key->key_len) { + /* Copy the required key as the current key */ + wep_key = &priv->wep_key[index]; + if (!wep_key->key_length) { + dev_err(adapter->dev, + "key not set, so cannot enable it\n"); + return -1; + } + priv->wep_key_curr_index = (u16) index; + priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; + } else { + wep_key = &priv->wep_key[index]; + /* Cleanup */ + memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); + /* Copy the key in the driver */ + memcpy(wep_key->key_material, + encrypt_key->key_material, + encrypt_key->key_len); + wep_key->key_index = index; + wep_key->key_length = encrypt_key->key_len; + priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; + } + if (wep_key->key_length) { + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, 0, NULL, NULL); + if (ret) + return ret; + } + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; + else + priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, wait, + &priv->curr_pkt_filter); + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set WPA key. + * + * This function prepares the correct firmware command and + * issues it, after validation checks. + * + * Current driver only supports key length of up to 32 bytes. + * + * This function can also be used to disable a currently set key. + */ +static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_encrypt_key *encrypt_key) +{ + int ret = 0; + struct mwifiex_private *priv = adapter->priv[wait->bss_index]; + u8 remove_key = false; + struct host_cmd_ds_802_11_key_material *ibss_key; + + /* Current driver only supports key length of up to 32 bytes */ + if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { + dev_err(adapter->dev, "key length too long\n"); + return -1; + } + + if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + /* + * IBSS/WPA-None uses only one key (Group) for both receiving + * and sending unicast and multicast packets. + */ + /* Send the key as PTK to firmware */ + encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + NULL, encrypt_key); + if (ret) + return ret; + + ibss_key = &priv->aes_key; + memset(ibss_key, 0, + sizeof(struct host_cmd_ds_802_11_key_material)); + /* Copy the key in the driver */ + memcpy(ibss_key->key_param_set.key, encrypt_key->key_material, + encrypt_key->key_len); + memcpy(&ibss_key->key_param_set.key_len, &encrypt_key->key_len, + sizeof(ibss_key->key_param_set.key_len)); + ibss_key->key_param_set.key_type_id + = cpu_to_le16(KEY_TYPE_ID_TKIP); + ibss_key->key_param_set.key_info + = cpu_to_le16(KEY_INFO_TKIP_ENABLED); + + /* Send the key as GTK to firmware */ + encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; + } + + if (!encrypt_key->key_index) + encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; + + if (remove_key) + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + !(KEY_INFO_ENABLED), + wait, encrypt_key); + else + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + wait, encrypt_key); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/get network keys. + * + * This is a generic key handling function which supports WEP, WPA + * and WAPI. + */ +static int +mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_encrypt_key *encrypt_key) +{ + int status = 0; + struct mwifiex_adapter *adapter = priv->adapter; + + if (encrypt_key->is_wapi_key) + status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait, + encrypt_key); + else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) + status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait, + encrypt_key); + else + status = mwifiex_sec_ioctl_set_wep_key(adapter, wait, + encrypt_key); + return status; +} + +/* + * This function returns the driver version. + */ +int +mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, + int max_len) +{ + union { + u32 l; + u8 c[4]; + } ver; + char fw_ver[32]; + + ver.l = adapter->fw_release_number; + sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]); + + snprintf(version, max_len, driver_version, fw_ver); + + dev_dbg(adapter->dev, "info: MWIFIEX VERSION: %s\n", version); + + return 0; +} + +/* + * Sends IOCTL request to set Tx power. It can be set to either auto + * or a fixed value. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm) +{ + struct mwifiex_power_cfg power_cfg; + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + int ret = 0; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + if (type == NL80211_TX_POWER_FIXED) { + power_cfg.is_power_auto = 0; + power_cfg.power_level = dbm; + } else { + power_cfg.is_power_auto = 1; + } + status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg); + + ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); + + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to get scan table. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option, + struct mwifiex_scan_resp *scan_resp) +{ + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_scan_resp scan; + int status = 0; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET, + NULL, &scan); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + if (!status) { + if (scan_resp) + memcpy(scan_resp, &scan, + sizeof(struct mwifiex_scan_resp)); + } + + if (wait && (status != -EINPROGRESS)) + kfree(wait); + return status; +} + +/* + * Sends IOCTL request to get signal information. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, + struct mwifiex_ds_get_signal *signal) +{ + struct mwifiex_ds_get_signal info; + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + info.selector = ALL_RSSI_INFO_MASK; + + status = mwifiex_get_info_signal(priv, wait, &info); + + status = mwifiex_request_ioctl(priv, wait, status, wait_option); + if (!status) { + if (signal) + memcpy(signal, &info, + sizeof(struct mwifiex_ds_get_signal)); + if (info.selector & BCN_RSSI_AVG_MASK) + priv->w_stats.qual.level = info.bcn_rssi_avg; + if (info.selector & BCN_NF_AVG_MASK) + priv->w_stats.qual.noise = info.bcn_nf_avg; + } + + if (wait && (status != -EINPROGRESS)) + kfree(wait); + return status; +} + +/* + * Sends IOCTL request to set encryption mode. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +static int mwifiex_set_encrypt_mode(struct mwifiex_private *priv, + u8 wait_option, u32 encrypt_mode) +{ + priv->sec_info.encryption_mode = encrypt_mode; + return 0; +} + +/* + * This function set the authentication parameters. It sets both encryption + * mode and authentication mode, and also enables WPA if required. + */ +int +mwifiex_set_auth(struct mwifiex_private *priv, int encrypt_mode, + int auth_mode, int wpa_enabled) +{ + if (mwifiex_set_encrypt_mode(priv, MWIFIEX_IOCTL_WAIT, encrypt_mode)) + return -EFAULT; + + if (mwifiex_set_auth_mode(priv, auth_mode)) + return -EFAULT; + + return 0; +} + +/* + * Sends IOCTL request to set encoding parameters. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, + int key_len, u8 key_index, int disable) +{ + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ds_encrypt_key encrypt_key; + int status = 0; + int ret = 0; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); + encrypt_key.key_len = key_len; + if (!disable) { + encrypt_key.key_index = key_index; + if (key_len) + memcpy(encrypt_key.key_material, key, key_len); + } else { + encrypt_key.key_disable = true; + } + + status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key); + + if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) + ret = -EFAULT; + + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to set power management parameters. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on) +{ + int ret = 0; + int status = 0; + struct mwifiex_wait_queue *wait = NULL; + u32 ps_mode; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + ps_mode = power_on; + status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode, + HostCmd_ACT_GEN_SET); + + ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); + + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to get extended version. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_get_ver_ext(struct mwifiex_private *priv) +{ + struct mwifiex_ver_ext ver_ext; + struct mwifiex_wait_queue *wait = NULL; + int status = 0; + int ret = 0; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + /* get fw version */ + memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); + status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext); + + ret = mwifiex_request_ioctl(priv, wait, status, wait_option); + + if (ret) + ret = -1; + + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to get statistics information. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_get_stats_info(struct mwifiex_private *priv, + struct mwifiex_ds_get_stats *log) +{ + int ret = 0; + int status = 0; + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ds_get_stats get_log; + u8 wait_option = MWIFIEX_IOCTL_WAIT; + + /* Allocate wait buffer */ + wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); + if (!wait) + return -ENOMEM; + + memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); + status = mwifiex_get_info_stats(priv, wait, &get_log); + + /* Send IOCTL request to MWIFIEX */ + ret = mwifiex_request_ioctl(priv, wait, status, wait_option); + if (!ret) { + if (log) + memcpy(log, &get_log, sizeof(struct + mwifiex_ds_get_stats)); + priv->w_stats.discard.fragment = get_log.fcs_error; + priv->w_stats.discard.retries = get_log.retry; + priv->w_stats.discard.misc = get_log.ack_failure; + } + + kfree(wait); + return ret; +} + +/* + * IOCTL request handler to read/write register. + * + * This function prepares the correct firmware command and + * issues it. + * + * Access to the following registers are supported - + * - MAC + * - BBP + * - RF + * - PMIC + * - CAU + */ +static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_reg_rw *reg_rw, + u16 action) +{ + int ret = 0; + u16 cmd_no; + + switch (le32_to_cpu(reg_rw->type)) { + case MWIFIEX_REG_MAC: + cmd_no = HostCmd_CMD_MAC_REG_ACCESS; + break; + case MWIFIEX_REG_BBP: + cmd_no = HostCmd_CMD_BBP_REG_ACCESS; + break; + case MWIFIEX_REG_RF: + cmd_no = HostCmd_CMD_RF_REG_ACCESS; + break; + case MWIFIEX_REG_PMIC: + cmd_no = HostCmd_CMD_PMIC_REG_ACCESS; + break; + case MWIFIEX_REG_CAU: + cmd_no = HostCmd_CMD_CAU_REG_ACCESS; + break; + default: + return -1; + } + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * Sends IOCTL request to write to a register. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, + u32 reg_offset, u32 reg_value) +{ + int ret = 0; + int status = 0; + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ds_reg_rw reg_rw; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + reg_rw.type = cpu_to_le32(reg_type); + reg_rw.offset = cpu_to_le32(reg_offset); + reg_rw.value = cpu_to_le32(reg_value); + status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, + HostCmd_ACT_GEN_SET); + + ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); + + kfree(wait); + return ret; +} + +/* + * Sends IOCTL request to read from a register. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, + u32 reg_offset, u32 *value) +{ + int ret = 0; + int status = 0; + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ds_reg_rw reg_rw; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + reg_rw.type = cpu_to_le32(reg_type); + reg_rw.offset = cpu_to_le32(reg_offset); + status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, + HostCmd_ACT_GEN_GET); + + ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); + if (ret) + goto done; + + *value = le32_to_cpu(reg_rw.value); + +done: + kfree(wait); + return ret; +} + +/* + * IOCTL request handler to read EEPROM. + * + * This function prepares the correct firmware command and + * issues it. + */ +static int +mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv, + struct mwifiex_wait_queue *wait, + struct mwifiex_ds_read_eeprom *rd_eeprom) +{ + int ret = 0; + + /* Send request to firmware */ + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, + HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * Sends IOCTL request to read from EEPROM. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, + u8 *value) +{ + int ret = 0; + int status = 0; + struct mwifiex_wait_queue *wait = NULL; + struct mwifiex_ds_read_eeprom rd_eeprom; + + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + rd_eeprom.offset = cpu_to_le16((u16) offset); + rd_eeprom.byte_count = cpu_to_le16((u16) bytes); + status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom); + + ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); + if (ret) + goto done; + + memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); +done: + kfree(wait); + return ret; +} + +/* + * This function sets a generic IE. In addition to generic IE, it can + * also handle WPA, WPA2 and WAPI IEs. + */ +static int +mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, + u16 ie_len) +{ + int ret = 0; + struct ieee_types_vendor_header *pvendor_ie; + const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 }; + const u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 }; + + /* If the passed length is zero, reset the buffer */ + if (!ie_len) { + priv->gen_ie_buf_len = 0; + priv->wps.session_enable = false; + + return 0; + } else if (!ie_data_ptr) { + return -1; + } + pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; + /* Test to see if it is a WPA IE, if not, then it is a gen IE */ + if (((pvendor_ie->element_id == WLAN_EID_WPA) + && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) + || (pvendor_ie->element_id == WLAN_EID_RSN)) { + + /* IE is a WPA/WPA2 IE so call set_wpa function */ + ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); + priv->wps.session_enable = false; + + return ret; + } else if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) { + /* IE is a WAPI IE so call set_wapi function */ + ret = mwifiex_set_wapi_ie(priv, ie_data_ptr, ie_len); + + return ret; + } + /* + * Verify that the passed length is not larger than the + * available space remaining in the buffer + */ + if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) { + + /* Test to see if it is a WPS IE, if so, enable + * wps session flag + */ + pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; + if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) + && (!memcmp(pvendor_ie->oui, wps_oui, + sizeof(wps_oui)))) { + priv->wps.session_enable = true; + dev_dbg(priv->adapter->dev, + "info: WPS Session Enabled.\n"); + } + + /* Append the passed data to the end of the + genIeBuffer */ + memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, + ie_len); + /* Increment the stored buffer length by the + size passed */ + priv->gen_ie_buf_len += ie_len; + } else { + /* Passed data does not fit in the remaining + buffer space */ + ret = -1; + } + + /* Return 0, or -1 for error case */ + return ret; +} + +/* + * IOCTL request handler to set/get generic IE. + * + * In addition to various generic IEs, this function can also be + * used to set the ARP filter. + */ +static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, + struct mwifiex_ds_misc_gen_ie *gen_ie, + u16 action) +{ + struct mwifiex_adapter *adapter = priv->adapter; + + switch (gen_ie->type) { + case MWIFIEX_IE_TYPE_GEN_IE: + if (action == HostCmd_ACT_GEN_GET) { + gen_ie->len = priv->wpa_ie_len; + memcpy(gen_ie->ie_data, priv->wpa_ie, gen_ie->len); + } else { + mwifiex_set_gen_ie_helper(priv, gen_ie->ie_data, + (u16) gen_ie->len); + } + break; + case MWIFIEX_IE_TYPE_ARP_FILTER: + memset(adapter->arp_filter, 0, sizeof(adapter->arp_filter)); + if (gen_ie->len > ARP_FILTER_MAX_BUF_SIZE) { + adapter->arp_filter_size = 0; + dev_err(adapter->dev, "invalid ARP filter size\n"); + return -1; + } else { + memcpy(adapter->arp_filter, gen_ie->ie_data, + gen_ie->len); + adapter->arp_filter_size = gen_ie->len; + } + break; + default: + dev_err(adapter->dev, "invalid IE type\n"); + return -1; + } + return 0; +} + +/* + * Sends IOCTL request to set a generic IE. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + */ +int +mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len) +{ + struct mwifiex_ds_misc_gen_ie gen_ie; + int status = 0; + + if (ie_len > IW_CUSTOM_MAX) + return -EFAULT; + + gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE; + gen_ie.len = ie_len; + memcpy(gen_ie.ie_data, ie, ie_len); + status = mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET); + if (status) + return -EFAULT; + + return 0; +} diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c new file mode 100644 index 000000000000..8282679e64fd --- /dev/null +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -0,0 +1,182 @@ +/* + * Marvell Wireless LAN device driver: station RX data handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "11n_aggr.h" +#include "11n_rxreorder.h" + +/* + * This function processes the received packet and forwards it + * to kernel/upper layer. + * + * This function parses through the received packet and determines + * if it is a debug packet or normal packet. + * + * For non-debug packets, the function chops off unnecessary leading + * header bytes, reconstructs the packet as an ethernet frame or + * 802.2/llc/snap frame as required, and sends it to kernel/upper layer. + * + * The completion callback is called after processing in complete. + */ +int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb) +{ + int ret = 0; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); + struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct rx_packet_hdr *rx_pkt_hdr; + struct rxpd *local_rx_pd; + int hdr_chop; + struct ethhdr *eth_hdr; + u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; + + local_rx_pd = (struct rxpd *) (skb->data); + + rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd + + local_rx_pd->rx_pkt_offset); + + if (!memcmp(&rx_pkt_hdr->rfc1042_hdr, + rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) { + /* + * Replace the 803 header and rfc1042 header (llc/snap) with an + * EthernetII header, keep the src/dst and snap_type + * (ethertype). + * The firmware only passes up SNAP frames converting + * all RX Data from 802.11 to 802.2/LLC/SNAP frames. + * To create the Ethernet II, just move the src, dst address + * right before the snap_type. + */ + eth_hdr = (struct ethhdr *) + ((u8 *) &rx_pkt_hdr->eth803_hdr + + sizeof(rx_pkt_hdr->eth803_hdr) + + sizeof(rx_pkt_hdr->rfc1042_hdr) + - sizeof(rx_pkt_hdr->eth803_hdr.h_dest) + - sizeof(rx_pkt_hdr->eth803_hdr.h_source) + - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type)); + + memcpy(eth_hdr->h_source, rx_pkt_hdr->eth803_hdr.h_source, + sizeof(eth_hdr->h_source)); + memcpy(eth_hdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest, + sizeof(eth_hdr->h_dest)); + + /* Chop off the rxpd + the excess memory from the 802.2/llc/snap + header that was removed. */ + hdr_chop = (u8 *) eth_hdr - (u8 *) local_rx_pd; + } else { + /* Chop off the rxpd */ + hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr - + (u8 *) local_rx_pd; + } + + /* Chop off the leading header bytes so the it points to the start of + either the reconstructed EthII frame or the 802.2/llc/snap frame */ + skb_pull(skb, hdr_chop); + + priv->rxpd_rate = local_rx_pd->rx_rate; + + priv->rxpd_htinfo = local_rx_pd->ht_info; + + ret = mwifiex_recv_packet(adapter, skb); + if (ret == -1) + dev_err(adapter->dev, "recv packet failed\n"); + + return ret; +} + +/* + * This function processes the received buffer. + * + * The function looks into the RxPD and performs sanity tests on the + * received buffer to ensure its a valid packet, before processing it + * further. If the packet is determined to be aggregated, it is + * de-aggregated accordingly. Non-unicast packets are sent directly to + * the kernel/upper layers. Unicast packets are handed over to the + * Rx reordering routine if 11n is enabled. + * + * The completion callback is called after processing in complete. + */ +int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb) +{ + int ret = 0; + struct rxpd *local_rx_pd; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); + struct rx_packet_hdr *rx_pkt_hdr; + u8 ta[ETH_ALEN]; + u16 rx_pkt_type = 0; + struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + + local_rx_pd = (struct rxpd *) (skb->data); + rx_pkt_type = local_rx_pd->rx_pkt_type; + + rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd + + local_rx_pd->rx_pkt_offset); + + if ((local_rx_pd->rx_pkt_offset + local_rx_pd->rx_pkt_length) > + (u16) skb->len) { + dev_err(adapter->dev, "wrong rx packet: len=%d," + " rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len, + local_rx_pd->rx_pkt_offset, local_rx_pd->rx_pkt_length); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return ret; + } + if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) { + mwifiex_11n_deaggregate_pkt(priv, skb); + return ret; + } + /* + * If the packet is not an unicast packet then send the packet + * directly to os. Don't pass thru rx reordering + */ + if (!IS_11N_ENABLED(priv) || + memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) { + mwifiex_process_rx_packet(adapter, skb); + return ret; + } + + if (mwifiex_queuing_ra_based(priv)) { + memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN); + } else { + if (rx_pkt_type != PKT_TYPE_BAR) + priv->rx_seq[local_rx_pd->priority] = + local_rx_pd->seq_num; + memcpy(ta, priv->curr_bss_params.bss_descriptor.mac_address, + ETH_ALEN); + } + + /* Reorder and send to OS */ + ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num, + local_rx_pd->priority, ta, + (u8) local_rx_pd->rx_pkt_type, + (void *) skb); + + if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { + if (priv && (ret == -1)) + priv->stats.rx_dropped++; + + dev_kfree_skb_any(skb); + } + + return ret; +} diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c new file mode 100644 index 000000000000..e8db6bd021c6 --- /dev/null +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -0,0 +1,202 @@ +/* + * Marvell Wireless LAN device driver: station TX data handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" + +/* + * This function fills the TxPD for tx packets. + * + * The Tx buffer received by this function should already have the + * header space allocated for TxPD. + * + * This function inserts the TxPD in between interface header and actual + * data and adjusts the buffer pointers accordingly. + * + * The following TxPD fields are set by this function, as required - + * - BSS number + * - Tx packet length and offset + * - Priority + * - Packet delay + * - Priority specific Tx control + * - Flags + */ +void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, + struct sk_buff *skb) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct txpd *local_tx_pd; + struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); + + if (!skb->len) { + dev_err(adapter->dev, "Tx: bad packet length: %d\n", + skb->len); + tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID; + return skb->data; + } + + BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN)); + skb_push(skb, sizeof(*local_tx_pd)); + + local_tx_pd = (struct txpd *) skb->data; + memset(local_tx_pd, 0, sizeof(struct txpd)); + local_tx_pd->bss_num = priv->bss_num; + local_tx_pd->bss_type = priv->bss_type; + local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - + sizeof(struct txpd))); + + local_tx_pd->priority = (u8) skb->priority; + local_tx_pd->pkt_delay_2ms = + mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + + if (local_tx_pd->priority < + ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) + /* + * Set the priority specific tx_control field, setting of 0 will + * cause the default value to be used later in this function + */ + local_tx_pd->tx_control = + cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd-> + priority]); + + if (adapter->pps_uapsd_mode) { + if (mwifiex_check_last_packet_indication(priv)) { + adapter->tx_lock_flag = true; + local_tx_pd->flags = + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET; + } + } + + /* Offset of actual data */ + local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); + + /* make space for INTF_HEADER_LEN */ + skb_push(skb, INTF_HEADER_LEN); + + if (!local_tx_pd->tx_control) + /* TxCtrl set by user or default */ + local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); + + return skb->data; +} + +/* + * This function tells firmware to send a NULL data packet. + * + * The function creates a NULL data packet with TxPD and sends to the + * firmware for transmission, with highest priority setting. + */ +int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct txpd *local_tx_pd; +/* sizeof(struct txpd) + Interface specific header */ +#define NULL_PACKET_HDR 64 + u32 data_len = NULL_PACKET_HDR; + struct sk_buff *skb = NULL; + int ret = 0; + struct mwifiex_txinfo *tx_info = NULL; + + if (adapter->surprise_removed) + return -1; + + if (!priv->media_connected) + return -1; + + if (adapter->data_sent) + return -1; + + skb = dev_alloc_skb(data_len); + if (!skb) + return -1; + + tx_info = MWIFIEX_SKB_TXCB(skb); + tx_info->bss_index = priv->bss_index; + skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN); + skb_push(skb, sizeof(struct txpd)); + + local_tx_pd = (struct txpd *) skb->data; + local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); + local_tx_pd->flags = flags; + local_tx_pd->priority = WMM_HIGHEST_PRIORITY; + local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); + local_tx_pd->bss_num = priv->bss_num; + local_tx_pd->bss_type = priv->bss_type; + + skb_push(skb, INTF_HEADER_LEN); + + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, + skb->data, skb->len, NULL); + switch (ret) { + case -EBUSY: + adapter->data_sent = true; + /* Fall through FAILURE handling */ + case -1: + dev_kfree_skb_any(skb); + dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", + __func__, ret); + adapter->dbg.num_tx_host_to_card_failure++; + break; + case 0: + dev_kfree_skb_any(skb); + dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n", + __func__); + adapter->tx_lock_flag = true; + break; + case -EINPROGRESS: + break; + default: + break; + } + + return ret; +} + +/* + * This function checks if we need to send last packet indication. + */ +u8 +mwifiex_check_last_packet_indication(struct mwifiex_private *priv) +{ + struct mwifiex_adapter *adapter = priv->adapter; + u8 ret = false; + u8 prop_ps = true; + + if (!adapter->sleep_period.period) + return ret; + if (mwifiex_wmm_lists_empty(adapter)) { + if ((priv->curr_bss_params.wmm_uapsd_enabled && + priv->wmm_qosinfo) || prop_ps) + ret = true; + } + + if (ret && !adapter->cmd_sent && !adapter->curr_cmd + && !is_command_pending(adapter)) { + adapter->delay_null_pkt = false; + ret = true; + } else { + ret = false; + adapter->delay_null_pkt = true; + } + return ret; +} diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c new file mode 100644 index 000000000000..f06923cb1c4b --- /dev/null +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -0,0 +1,202 @@ +/* + * Marvell Wireless LAN device driver: generic TX/RX data handling + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" + +/* + * This function processes the received buffer. + * + * Main responsibility of this function is to parse the RxPD to + * identify the correct interface this packet is headed for and + * forwarding it to the associated handling function, where the + * packet will be further processed and sent to kernel/upper layer + * if required. + */ +int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, + struct sk_buff *skb) +{ + int ret = 0; + struct mwifiex_private *priv = + mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + struct rxpd *local_rx_pd; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); + + local_rx_pd = (struct rxpd *) (skb->data); + /* Get the BSS number from rxpd, get corresponding priv */ + priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num & + BSS_NUM_MASK, local_rx_pd->bss_type); + if (!priv) + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + + rx_info->bss_index = priv->bss_index; + ret = mwifiex_process_sta_rx_packet(adapter, skb); + + return ret; +} +EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); + +/* + * This function sends a packet to device. + * + * It processes the packet to add the TxPD, checks condition and + * sends the processed packet to firmware for transmission. + * + * On successful completion, the function calls the completion callback + * and logs the time. + */ +int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, + struct mwifiex_tx_param *tx_param) +{ + int ret = -1; + struct mwifiex_adapter *adapter = priv->adapter; + u8 *head_ptr = NULL; + struct txpd *local_tx_pd = NULL; + + head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb); + if (head_ptr) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) + local_tx_pd = + (struct txpd *) (head_ptr + INTF_HEADER_LEN); + + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, + skb->data, skb->len, tx_param); + } + + switch (ret) { + case -EBUSY: + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + (adapter->pps_uapsd_mode) && + (adapter->tx_lock_flag)) { + priv->adapter->tx_lock_flag = false; + local_tx_pd->flags = 0; + } + dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); + break; + case -1: + adapter->data_sent = false; + dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", + ret); + adapter->dbg.num_tx_host_to_card_failure++; + mwifiex_write_data_complete(adapter, skb, ret); + break; + case -EINPROGRESS: + adapter->data_sent = false; + break; + case 0: + mwifiex_write_data_complete(adapter, skb, ret); + break; + default: + break; + } + + return ret; +} + +/* + * Packet send completion callback handler. + * + * It either frees the buffer directly or forwards it to another + * completion callback which checks conditions, updates statistics, + * wakes up stalled traffic queue if required, and then frees the buffer. + */ +int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, + struct sk_buff *skb, int status) +{ + struct mwifiex_private *priv = NULL, *tpriv = NULL; + struct mwifiex_txinfo *tx_info = NULL; + int i; + + if (!skb) + return 0; + + tx_info = MWIFIEX_SKB_TXCB(skb); + priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index); + if (!priv) + goto done; + + priv->netdev->trans_start = jiffies; + if (!status) { + priv->stats.tx_packets++; + priv->stats.tx_bytes += skb->len; + } else { + priv->stats.tx_errors++; + } + atomic_dec(&adapter->tx_pending); + + for (i = 0; i < adapter->priv_num; i++) { + + tpriv = adapter->priv[i]; + + if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) + && (tpriv->media_connected)) { + if (netif_queue_stopped(tpriv->netdev)) + netif_wake_queue(tpriv->netdev); + } + } +done: + dev_kfree_skb_any(skb); + + return 0; +} + +/* + * Packet receive completion callback handler. + * + * This function calls another completion callback handler which + * updates the statistics, and optionally updates the parent buffer + * use count before freeing the received packet. + */ +int mwifiex_recv_packet_complete(struct mwifiex_adapter *adapter, + struct sk_buff *skb, int status) +{ + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); + struct mwifiex_rxinfo *rx_info_parent = NULL; + struct mwifiex_private *priv; + struct sk_buff *skb_parent = NULL; + unsigned long flags; + + priv = adapter->priv[rx_info->bss_index]; + + if (priv && (status == -1)) + priv->stats.rx_dropped++; + + if (rx_info->parent) { + skb_parent = rx_info->parent; + rx_info_parent = MWIFIEX_SKB_RXCB(skb_parent); + + spin_lock_irqsave(&priv->rx_pkt_lock, flags); + --rx_info_parent->use_count; + + if (!rx_info_parent->use_count) { + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + dev_kfree_skb_any(skb_parent); + } else { + spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); + } + } else { + dev_kfree_skb_any(skb); + } + + return 0; +} diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c new file mode 100644 index 000000000000..205022aa52f5 --- /dev/null +++ b/drivers/net/wireless/mwifiex/util.c @@ -0,0 +1,252 @@ +/* + * Marvell Wireless LAN device driver: utility functions + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + +/* + * Firmware initialization complete callback handler. + * + * This function wakes up the function waiting on the init + * wait queue for the firmware initialization to complete. + */ +int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter) +{ + + adapter->init_wait_q_woken = true; + wake_up_interruptible(&adapter->init_wait_q); + return 0; +} + +/* + * Firmware shutdown complete callback handler. + * + * This function sets the hardware status to not ready and wakes up + * the function waiting on the init wait queue for the firmware + * shutdown to complete. + */ +int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) +{ + adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY; + adapter->init_wait_q_woken = true; + wake_up_interruptible(&adapter->init_wait_q); + return 0; +} + +/* + * IOCTL request handler to send function init/shutdown command + * to firmware. + * + * This function prepares the correct firmware command and + * issues it. + */ +int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait, + u32 func_init_shutdown) +{ + struct mwifiex_private *priv = adapter->priv[wait->bss_index]; + int ret; + u16 cmd; + + if (func_init_shutdown == MWIFIEX_FUNC_INIT) { + cmd = HostCmd_CMD_FUNC_INIT; + } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { + cmd = HostCmd_CMD_FUNC_SHUTDOWN; + } else { + dev_err(adapter->dev, "unsupported parameter\n"); + return -1; + } + + /* Send command to firmware */ + ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET, + 0, wait, NULL); + + if (!ret) + ret = -EINPROGRESS; + + return ret; +} + +/* + * IOCTL request handler to set/get debug information. + * + * This function collates/sets the information from/to different driver + * structures. + */ +int mwifiex_get_debug_info(struct mwifiex_private *priv, + struct mwifiex_debug_info *info) +{ + struct mwifiex_adapter *adapter = priv->adapter; + + if (info) { + memcpy(info->packets_out, + priv->wmm.packets_out, + sizeof(priv->wmm.packets_out)); + info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; + info->tx_buf_size = (u32) adapter->tx_buf_size; + info->rx_tbl_num = mwifiex_get_rx_reorder_tbl( + priv, info->rx_tbl); + info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl( + priv, info->tx_tbl); + info->ps_mode = adapter->ps_mode; + info->ps_state = adapter->ps_state; + info->is_deep_sleep = adapter->is_deep_sleep; + info->pm_wakeup_card_req = adapter->pm_wakeup_card_req; + info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try; + info->is_hs_configured = adapter->is_hs_configured; + info->hs_activated = adapter->hs_activated; + info->num_cmd_host_to_card_failure + = adapter->dbg.num_cmd_host_to_card_failure; + info->num_cmd_sleep_cfm_host_to_card_failure + = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; + info->num_tx_host_to_card_failure + = adapter->dbg.num_tx_host_to_card_failure; + info->num_event_deauth = adapter->dbg.num_event_deauth; + info->num_event_disassoc = adapter->dbg.num_event_disassoc; + info->num_event_link_lost = adapter->dbg.num_event_link_lost; + info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; + info->num_cmd_assoc_success = + adapter->dbg.num_cmd_assoc_success; + info->num_cmd_assoc_failure = + adapter->dbg.num_cmd_assoc_failure; + info->num_tx_timeout = adapter->dbg.num_tx_timeout; + info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; + info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; + info->timeout_cmd_act = adapter->dbg.timeout_cmd_act; + memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id, + sizeof(adapter->dbg.last_cmd_id)); + memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act, + sizeof(adapter->dbg.last_cmd_act)); + info->last_cmd_index = adapter->dbg.last_cmd_index; + memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id, + sizeof(adapter->dbg.last_cmd_resp_id)); + info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index; + memcpy(info->last_event, adapter->dbg.last_event, + sizeof(adapter->dbg.last_event)); + info->last_event_index = adapter->dbg.last_event_index; + info->data_sent = adapter->data_sent; + info->cmd_sent = adapter->cmd_sent; + info->cmd_resp_received = adapter->cmd_resp_received; + } + + return 0; +} + +/* + * This function processes the received packet before sending it to the + * kernel. + * + * It extracts the SKB from the received buffer and sends it to kernel. + * In case the received buffer does not contain the data in SKB format, + * the function creates a blank SKB, fills it with the data from the + * received buffer and then sends this new SKB to the kernel. + */ +int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) +{ + struct mwifiex_rxinfo *rx_info = NULL; + struct mwifiex_private *priv = NULL; + + if (!skb) + return -1; + + rx_info = MWIFIEX_SKB_RXCB(skb); + priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); + if (!priv) + return -1; + + skb->dev = priv->netdev; + skb->protocol = eth_type_trans(skb, priv->netdev); + skb->ip_summed = CHECKSUM_NONE; + priv->stats.rx_bytes += skb->len; + priv->stats.rx_packets++; + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + + return 0; +} + +/* + * Receive packet completion callback handler. + * + * This function updates the statistics and frees the buffer SKB. + */ +int mwifiex_recv_complete(struct mwifiex_adapter *adapter, + struct sk_buff *skb, int status) +{ + struct mwifiex_private *priv = NULL; + struct mwifiex_rxinfo *rx_info = NULL; + + if (!skb) + return 0; + + rx_info = MWIFIEX_SKB_RXCB(skb); + priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); + + if (priv && (status == -1)) + priv->stats.rx_dropped++; + + dev_kfree_skb_any(skb); + + return 0; +} + +/* + * IOCTL completion callback handler. + * + * This function is called when a pending IOCTL is completed. + * + * If work queue support is enabled, the function wakes up the + * corresponding waiting function. Otherwise, it processes the + * IOCTL response and frees the response buffer. + */ +int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, + struct mwifiex_wait_queue *wait_queue, + int status) +{ + enum mwifiex_error_code status_code = + (enum mwifiex_error_code) wait_queue->status; + + atomic_dec(&adapter->ioctl_pending); + + dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d," + " status_code=%#x\n", status, status_code); + + if (wait_queue->enabled) { + *wait_queue->condition = true; + wait_queue->status = status; + if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT)) + dev_err(adapter->dev, "cmd timeout\n"); + else + wake_up_interruptible(wait_queue->wait); + } else { + if (status) + dev_err(adapter->dev, "cmd failed: status_code=%#x\n", + status_code); + kfree(wait_queue); + } + + return 0; +} diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h new file mode 100644 index 000000000000..9506afc6c0e4 --- /dev/null +++ b/drivers/net/wireless/mwifiex/util.h @@ -0,0 +1,32 @@ +/* + * Marvell Wireless LAN device driver: utility functions + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_UTIL_H_ +#define _MWIFIEX_UTIL_H_ + +static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) +{ + return (struct mwifiex_rxinfo *)skb->cb; +} + +static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) +{ + return (struct mwifiex_txinfo *)skb->cb; +} +#endif /* !_MWIFIEX_UTIL_H_ */ diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c new file mode 100644 index 000000000000..1cfbc6bed692 --- /dev/null +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -0,0 +1,1237 @@ +/* + * Marvell Wireless LAN device driver: WMM + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#include "decl.h" +#include "ioctl.h" +#include "util.h" +#include "fw.h" +#include "main.h" +#include "wmm.h" +#include "11n.h" + + +/* Maximum value FW can accept for driver delay in packet transmission */ +#define DRV_PKT_DELAY_TO_FW_MAX 512 + + +#define WMM_QUEUED_PACKET_LOWER_LIMIT 180 + +#define WMM_QUEUED_PACKET_UPPER_LIMIT 200 + +/* Offset for TOS field in the IP header */ +#define IPTOS_OFFSET 5 + +/* WMM information IE */ +static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07, + 0x00, 0x50, 0xf2, 0x02, + 0x00, 0x01, 0x00 +}; + +static const u8 wmm_aci_to_qidx_map[] = { WMM_AC_BE, + WMM_AC_BK, + WMM_AC_VI, + WMM_AC_VO +}; + +static u8 tos_to_tid[] = { + /* TID DSCP_P2 DSCP_P1 DSCP_P0 WMM_AC */ + 0x01, /* 0 1 0 AC_BK */ + 0x02, /* 0 0 0 AC_BK */ + 0x00, /* 0 0 1 AC_BE */ + 0x03, /* 0 1 1 AC_BE */ + 0x04, /* 1 0 0 AC_VI */ + 0x05, /* 1 0 1 AC_VI */ + 0x06, /* 1 1 0 AC_VO */ + 0x07 /* 1 1 1 AC_VO */ +}; + +/* + * This table inverses the tos_to_tid operation to get a priority + * which is in sequential order, and can be compared. + * Use this to compare the priority of two different TIDs. + */ +static u8 tos_to_tid_inv[] = { + 0x02, /* from tos_to_tid[2] = 0 */ + 0x00, /* from tos_to_tid[0] = 1 */ + 0x01, /* from tos_to_tid[1] = 2 */ + 0x03, + 0x04, + 0x05, + 0x06, + 0x07}; + +static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} }; + +/* + * This function debug prints the priority parameters for a WMM AC. + */ +static void +mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) +{ + const char *ac_str[] = { "BK", "BE", "VI", "VO" }; + + pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, " + "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", + ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap + & MWIFIEX_ACI) >> 5]], + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, + ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, + ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, + (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, + le16_to_cpu(ac_param->tx_op_limit)); +} + +/* + * This function allocates a route address list. + * + * The function also initializes the list with the provided RA. + */ +static struct mwifiex_ra_list_tbl * +mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) +{ + struct mwifiex_ra_list_tbl *ra_list; + + ra_list = kzalloc(sizeof(struct mwifiex_ra_list_tbl), GFP_ATOMIC); + + if (!ra_list) { + dev_err(adapter->dev, "%s: failed to alloc ra_list\n", + __func__); + return NULL; + } + INIT_LIST_HEAD(&ra_list->list); + skb_queue_head_init(&ra_list->skb_head); + + memcpy(ra_list->ra, ra, ETH_ALEN); + + ra_list->total_pkts_size = 0; + + dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); + + return ra_list; +} + +/* + * This function allocates and adds a RA list for all TIDs + * with the given RA. + */ +void +mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) +{ + int i; + struct mwifiex_ra_list_tbl *ra_list; + struct mwifiex_adapter *adapter = priv->adapter; + + for (i = 0; i < MAX_NUM_TID; ++i) { + ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra); + dev_dbg(adapter->dev, "info: created ra_list %p\n", ra_list); + + if (!ra_list) + break; + + if (!mwifiex_queuing_ra_based(priv)) + ra_list->is_11n_enabled = IS_11N_ENABLED(priv); + else + ra_list->is_11n_enabled = false; + + dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n", + ra_list, ra_list->is_11n_enabled); + + list_add_tail(&ra_list->list, + &priv->wmm.tid_tbl_ptr[i].ra_list); + + if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) + priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; + } +} + +/* + * This function sets the WMM queue priorities to their default values. + */ +static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) +{ + /* Default queue priorities: VO->VI->BE->BK */ + priv->wmm.queue_priority[0] = WMM_AC_VO; + priv->wmm.queue_priority[1] = WMM_AC_VI; + priv->wmm.queue_priority[2] = WMM_AC_BE; + priv->wmm.queue_priority[3] = WMM_AC_BK; +} + +/* + * This function map ACs to TIDs. + */ +static void +mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv, + u8 queue_priority[]) +{ + int i; + + for (i = 0; i < 4; ++i) { + tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; + tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; + } +} + +/* + * This function initializes WMM priority queues. + */ +void +mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, + struct ieee_types_wmm_parameter *wmm_ie) +{ + u16 cw_min, avg_back_off, tmp[4]; + u32 i, j, num_ac; + u8 ac_idx; + + if (!wmm_ie || !priv->wmm_enabled) { + /* WMM is not enabled, just set the defaults and return */ + mwifiex_wmm_default_queue_priorities(priv); + return; + } + + dev_dbg(priv->adapter->dev, "info: WMM Parameter IE: version=%d, " + "qos_info Parameter Set Count=%d, Reserved=%#x\n", + wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap & + IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK, + wmm_ie->reserved); + + for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) { + cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap & + MWIFIEX_ECW_MIN)) - 1; + avg_back_off = (cw_min >> 1) + + (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap & + MWIFIEX_AIFSN); + + ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac]. + aci_aifsn_bitmap & + MWIFIEX_ACI) >> 5]; + priv->wmm.queue_priority[ac_idx] = ac_idx; + tmp[ac_idx] = avg_back_off; + + dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", + (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap & + MWIFIEX_ECW_MAX) >> 4)) - 1, + cw_min, avg_back_off); + mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]); + } + + /* Bubble sort */ + for (i = 0; i < num_ac; i++) { + for (j = 1; j < num_ac - i; j++) { + if (tmp[j - 1] > tmp[j]) { + swap(tmp[j - 1], tmp[j]); + swap(priv->wmm.queue_priority[j - 1], + priv->wmm.queue_priority[j]); + } else if (tmp[j - 1] == tmp[j]) { + if (priv->wmm.queue_priority[j - 1] + < priv->wmm.queue_priority[j]) + swap(priv->wmm.queue_priority[j - 1], + priv->wmm.queue_priority[j]); + } + } + } + + mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority); +} + +/* + * This function evaluates whether or not an AC is to be downgraded. + * + * In case the AC is not enabled, the highest AC is returned that is + * enabled and does not require admission control. + */ +static enum mwifiex_wmm_ac_e +mwifiex_wmm_eval_downgrade_ac(struct mwifiex_private *priv, + enum mwifiex_wmm_ac_e eval_ac) +{ + int down_ac; + enum mwifiex_wmm_ac_e ret_ac; + struct mwifiex_wmm_ac_status *ac_status; + + ac_status = &priv->wmm.ac_status[eval_ac]; + + if (!ac_status->disabled) + /* Okay to use this AC, its enabled */ + return eval_ac; + + /* Setup a default return value of the lowest priority */ + ret_ac = WMM_AC_BK; + + /* + * Find the highest AC that is enabled and does not require + * admission control. The spec disallows downgrading to an AC, + * which is enabled due to a completed admission control. + * Unadmitted traffic is not to be sent on an AC with admitted + * traffic. + */ + for (down_ac = WMM_AC_BK; down_ac < eval_ac; down_ac++) { + ac_status = &priv->wmm.ac_status[down_ac]; + + if (!ac_status->disabled && !ac_status->flow_required) + /* AC is enabled and does not require admission + control */ + ret_ac = (enum mwifiex_wmm_ac_e) down_ac; + } + + return ret_ac; +} + +/* + * This function downgrades WMM priority queue. + */ +void +mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv) +{ + int ac_val; + + dev_dbg(priv->adapter->dev, "info: WMM: AC Priorities:" + "BK(0), BE(1), VI(2), VO(3)\n"); + + if (!priv->wmm_enabled) { + /* WMM is not enabled, default priorities */ + for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) + priv->wmm.ac_down_graded_vals[ac_val] = + (enum mwifiex_wmm_ac_e) ac_val; + } else { + for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) { + priv->wmm.ac_down_graded_vals[ac_val] + = mwifiex_wmm_eval_downgrade_ac(priv, + (enum mwifiex_wmm_ac_e) ac_val); + dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n", + ac_val, priv->wmm.ac_down_graded_vals[ac_val]); + } + } +} + +/* + * This function converts the IP TOS field to an WMM AC + * Queue assignment. + */ +static enum mwifiex_wmm_ac_e +mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos) +{ + /* Map of TOS UP values to WMM AC */ + const enum mwifiex_wmm_ac_e tos_to_ac[] = { WMM_AC_BE, + WMM_AC_BK, + WMM_AC_BK, + WMM_AC_BE, + WMM_AC_VI, + WMM_AC_VI, + WMM_AC_VO, + WMM_AC_VO + }; + + if (tos >= ARRAY_SIZE(tos_to_ac)) + return WMM_AC_BE; + + return tos_to_ac[tos]; +} + +/* + * This function evaluates a given TID and downgrades it to a lower + * TID if the WMM Parameter IE received from the AP indicates that the + * AP is disabled (due to call admission control (ACM bit). Mapping + * of TID to AC is taken care of internally. + */ +static u8 +mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid) +{ + enum mwifiex_wmm_ac_e ac, ac_down; + u8 new_tid; + + ac = mwifiex_wmm_convert_tos_to_ac(priv->adapter, tid); + ac_down = priv->wmm.ac_down_graded_vals[ac]; + + /* Send the index to tid array, picking from the array will be + * taken care by dequeuing function + */ + new_tid = ac_to_tid[ac_down][tid % 2]; + + return new_tid; +} + +/* + * This function initializes the WMM state information and the + * WMM data path queues. + */ +void +mwifiex_wmm_init(struct mwifiex_adapter *adapter) +{ + int i, j; + struct mwifiex_private *priv; + + for (j = 0; j < adapter->priv_num; ++j) { + priv = adapter->priv[j]; + if (!priv) + continue; + + for (i = 0; i < MAX_NUM_TID; ++i) { + priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i]; + priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i]; + priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i]; + priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; + } + + priv->aggr_prio_tbl[6].amsdu + = priv->aggr_prio_tbl[6].ampdu_ap + = priv->aggr_prio_tbl[6].ampdu_user + = BA_STREAM_NOT_ALLOWED; + + priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap + = priv->aggr_prio_tbl[7].ampdu_user + = BA_STREAM_NOT_ALLOWED; + + priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; + priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; + priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; + } +} + +/* + * This function checks if WMM Tx queue is empty. + */ +int +mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) +{ + int i, j; + struct mwifiex_private *priv; + + for (j = 0; j < adapter->priv_num; ++j) { + priv = adapter->priv[j]; + if (priv) { + for (i = 0; i < MAX_NUM_TID; i++) + if (!mwifiex_wmm_is_ra_list_empty(adapter, + &priv->wmm.tid_tbl_ptr[i].ra_list)) + return false; + } + } + + return true; +} + +/* + * This function deletes all packets in an RA list node. + * + * The packet sent completion callback handler are called with + * status failure, after they are dequeued to ensure proper + * cleanup. The RA list node itself is freed at the end. + */ +static void +mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ra_list) +{ + struct mwifiex_adapter *adapter = priv->adapter; + struct sk_buff *skb, *tmp; + + skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) + mwifiex_write_data_complete(adapter, skb, -1); +} + +/* + * This function deletes all packets in an RA list. + * + * Each nodes in the RA list are freed individually first, and then + * the RA list itself is freed. + */ +static void +mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv, + struct list_head *ra_list_head) +{ + struct mwifiex_ra_list_tbl *ra_list; + + list_for_each_entry(ra_list, ra_list_head, list) + mwifiex_wmm_del_pkts_in_ralist_node(priv, ra_list); +} + +/* + * This function deletes all packets in all RA lists. + */ +static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) +{ + int i; + + for (i = 0; i < MAX_NUM_TID; i++) + mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. + ra_list); +} + +/* + * This function deletes all route addresses from all RA lists. + */ +static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) +{ + struct mwifiex_ra_list_tbl *ra_list, *tmp_node; + int i; + + for (i = 0; i < MAX_NUM_TID; ++i) { + dev_dbg(priv->adapter->dev, + "info: ra_list: freeing buf for tid %d\n", i); + list_for_each_entry_safe(ra_list, tmp_node, + &priv->wmm.tid_tbl_ptr[i].ra_list, list) { + list_del(&ra_list->list); + kfree(ra_list); + } + + INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list); + + priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL; + } +} + +/* + * This function cleans up the Tx and Rx queues. + * + * Cleanup includes - + * - All packets in RA lists + * - All entries in Rx reorder table + * - All entries in Tx BA stream table + * - MPA buffer (if required) + * - All RA lists + */ +void +mwifiex_clean_txrx(struct mwifiex_private *priv) +{ + unsigned long flags; + + mwifiex_11n_cleanup_reorder_tbl(priv); + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); + + mwifiex_wmm_cleanup_queues(priv); + mwifiex_11n_delete_all_tx_ba_stream_tbl(priv); + + if (priv->adapter->if_ops.cleanup_mpa_buf) + priv->adapter->if_ops.cleanup_mpa_buf(priv->adapter); + + mwifiex_wmm_delete_all_ralist(priv); + memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); + + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); +} + +/* + * This function retrieves a particular RA list node, matching with the + * given TID and RA address. + */ +static struct mwifiex_ra_list_tbl * +mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, + u8 *ra_addr) +{ + struct mwifiex_ra_list_tbl *ra_list; + + list_for_each_entry(ra_list, &priv->wmm.tid_tbl_ptr[tid].ra_list, + list) { + if (!memcmp(ra_list->ra, ra_addr, ETH_ALEN)) + return ra_list; + } + + return NULL; +} + +/* + * This function retrieves an RA list node for a given TID and + * RA address pair. + * + * If no such node is found, a new node is added first and then + * retrieved. + */ +static struct mwifiex_ra_list_tbl * +mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr) +{ + struct mwifiex_ra_list_tbl *ra_list; + + ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra_addr); + if (ra_list) + return ra_list; + mwifiex_ralist_add(priv, ra_addr); + + return mwifiex_wmm_get_ralist_node(priv, tid, ra_addr); +} + +/* + * This function checks if a particular RA list node exists in a given TID + * table index. + */ +int +mwifiex_is_ralist_valid(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ra_list, int ptr_index) +{ + struct mwifiex_ra_list_tbl *rlist; + + list_for_each_entry(rlist, &priv->wmm.tid_tbl_ptr[ptr_index].ra_list, + list) { + if (rlist == ra_list) + return true; + } + + return false; +} + +/* + * This function adds a packet to WMM queue. + * + * In disconnected state the packet is immediately dropped and the + * packet send completion callback is called with status failure. + * + * Otherwise, the correct RA list node is located and the packet + * is queued at the list tail. + */ +void +mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, + struct sk_buff *skb) +{ + struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); + struct mwifiex_private *priv = adapter->priv[tx_info->bss_index]; + u32 tid; + struct mwifiex_ra_list_tbl *ra_list; + u8 ra[ETH_ALEN], tid_down; + unsigned long flags; + + if (!priv->media_connected) { + dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); + mwifiex_write_data_complete(adapter, skb, -1); + return; + } + + tid = skb->priority; + + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + + /* In case of infra as we have already created the list during + association we just don't have to call get_queue_raptr, we will + have only 1 raptr for a tid in case of infra */ + if (!mwifiex_queuing_ra_based(priv)) { + if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list)) + ra_list = list_first_entry( + &priv->wmm.tid_tbl_ptr[tid_down].ra_list, + struct mwifiex_ra_list_tbl, list); + else + ra_list = NULL; + } else { + memcpy(ra, skb->data, ETH_ALEN); + ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra); + } + + if (!ra_list) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); + mwifiex_write_data_complete(adapter, skb, -1); + return; + } + + skb_queue_tail(&ra_list->skb_head, skb); + + ra_list->total_pkts_size += skb->len; + + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); +} + +/* + * This function processes the get WMM status command response from firmware. + * + * The response may contain multiple TLVs - + * - AC Queue status TLVs + * - Current WMM Parameter IE TLV + * - Admission Control action frame TLVs + * + * This function parses the TLVs and then calls further specific functions + * to process any changes in the queue prioritize or state. + */ +int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, + const struct host_cmd_ds_command *resp) +{ + u8 *curr = (u8 *) &resp->params.get_wmm_status; + uint16_t resp_len = le16_to_cpu(resp->size), tlv_len; + int valid = true; + + struct mwifiex_ie_types_data *tlv_hdr; + struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus; + struct ieee_types_wmm_parameter *wmm_param_ie = NULL; + struct mwifiex_wmm_ac_status *ac_status; + + dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n", + resp_len); + + while ((resp_len >= sizeof(tlv_hdr->header)) && valid) { + tlv_hdr = (struct mwifiex_ie_types_data *) curr; + tlv_len = le16_to_cpu(tlv_hdr->header.len); + + switch (le16_to_cpu(tlv_hdr->header.type)) { + case TLV_TYPE_WMMQSTATUS: + tlv_wmm_qstatus = + (struct mwifiex_ie_types_wmm_queue_status *) + tlv_hdr; + dev_dbg(priv->adapter->dev, + "info: CMD_RESP: WMM_GET_STATUS:" + " QSTATUS TLV: %d, %d, %d\n", + tlv_wmm_qstatus->queue_index, + tlv_wmm_qstatus->flow_required, + tlv_wmm_qstatus->disabled); + + ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus-> + queue_index]; + ac_status->disabled = tlv_wmm_qstatus->disabled; + ac_status->flow_required = + tlv_wmm_qstatus->flow_required; + ac_status->flow_created = tlv_wmm_qstatus->flow_created; + break; + + case WLAN_EID_VENDOR_SPECIFIC: + /* + * Point the regular IEEE IE 2 bytes into the Marvell IE + * and setup the IEEE IE type and length byte fields + */ + + wmm_param_ie = + (struct ieee_types_wmm_parameter *) (curr + + 2); + wmm_param_ie->vend_hdr.len = (u8) tlv_len; + wmm_param_ie->vend_hdr.element_id = + WLAN_EID_VENDOR_SPECIFIC; + + dev_dbg(priv->adapter->dev, + "info: CMD_RESP: WMM_GET_STATUS:" + " WMM Parameter Set Count: %d\n", + wmm_param_ie->qos_info_bitmap & + IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK); + + memcpy((u8 *) &priv->curr_bss_params.bss_descriptor. + wmm_ie, wmm_param_ie, + wmm_param_ie->vend_hdr.len + 2); + + break; + + default: + valid = false; + break; + } + + curr += (tlv_len + sizeof(tlv_hdr->header)); + resp_len -= (tlv_len + sizeof(tlv_hdr->header)); + } + + mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie); + mwifiex_wmm_setup_ac_downgrade(priv); + + return 0; +} + +/* + * Callback handler from the command module to allow insertion of a WMM TLV. + * + * If the BSS we are associating to supports WMM, this function adds the + * required WMM Information IE to the association request command buffer in + * the form of a Marvell extended IEEE IE. + */ +u32 +mwifiex_wmm_process_association_req(struct mwifiex_private *priv, + u8 **assoc_buf, + struct ieee_types_wmm_parameter *wmm_ie, + struct ieee80211_ht_cap *ht_cap) +{ + struct mwifiex_ie_types_wmm_param_set *wmm_tlv; + u32 ret_len = 0; + + /* Null checks */ + if (!assoc_buf) + return 0; + if (!(*assoc_buf)) + return 0; + + if (!wmm_ie) + return 0; + + dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:" + "bss->wmmIe=0x%x\n", + wmm_ie->vend_hdr.element_id); + + if ((priv->wmm_required + || (ht_cap && (priv->adapter->config_bands & BAND_GN + || priv->adapter->config_bands & BAND_AN)) + ) + && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { + wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf; + wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]); + wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]); + memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2], + le16_to_cpu(wmm_tlv->header.len)); + if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) + memcpy((u8 *) (wmm_tlv->wmm_ie + + le16_to_cpu(wmm_tlv->header.len) + - sizeof(priv->wmm_qosinfo)), + &priv->wmm_qosinfo, + sizeof(priv->wmm_qosinfo)); + + ret_len = sizeof(wmm_tlv->header) + + le16_to_cpu(wmm_tlv->header.len); + + *assoc_buf += ret_len; + } + + return ret_len; +} + +/* + * This function computes the time delay in the driver queues for a + * given packet. + * + * When the packet is received at the OS/Driver interface, the current + * time is set in the packet structure. The difference between the present + * time and that received time is computed in this function and limited + * based on pre-compiled limits in the driver. + */ +u8 +mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, + const struct sk_buff *skb) +{ + u8 ret_val = 0; + struct timeval out_tstamp, in_tstamp; + u32 queue_delay; + + do_gettimeofday(&out_tstamp); + in_tstamp = ktime_to_timeval(skb->tstamp); + + queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000; + queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000; + + /* + * Queue delay is passed as a uint8 in units of 2ms (ms shifted + * by 1). Min value (other than 0) is therefore 2ms, max is 510ms. + * + * Pass max value if queue_delay is beyond the uint8 range + */ + ret_val = (u8) (min(queue_delay, priv->wmm.drv_pkt_delay_max) >> 1); + + dev_dbg(priv->adapter->dev, "data: WMM: Pkt Delay: %d ms," + " %d ms sent to FW\n", queue_delay, ret_val); + + return ret_val; +} + +/* + * This function retrieves the highest priority RA list table pointer. + */ +static struct mwifiex_ra_list_tbl * +mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, + struct mwifiex_private **priv, int *tid) +{ + struct mwifiex_private *priv_tmp; + struct mwifiex_ra_list_tbl *ptr, *head; + struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; + struct mwifiex_tid_tbl *tid_ptr; + int is_list_empty; + unsigned long flags; + int i, j; + + for (j = adapter->priv_num - 1; j >= 0; --j) { + spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, + flags); + is_list_empty = list_empty(&adapter->bss_prio_tbl[j] + .bss_prio_head); + spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, + flags); + if (is_list_empty) + continue; + + if (adapter->bss_prio_tbl[j].bss_prio_cur == + (struct mwifiex_bss_prio_node *) + &adapter->bss_prio_tbl[j].bss_prio_head) { + bssprio_node = + list_first_entry(&adapter->bss_prio_tbl[j] + .bss_prio_head, + struct mwifiex_bss_prio_node, + list); + bssprio_head = bssprio_node; + } else { + bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur; + bssprio_head = bssprio_node; + } + + do { + priv_tmp = bssprio_node->priv; + + for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) { + + tid_ptr = &(priv_tmp)->wmm. + tid_tbl_ptr[tos_to_tid[i]]; + + spin_lock_irqsave(&tid_ptr->tid_tbl_lock, + flags); + is_list_empty = + list_empty(&adapter->bss_prio_tbl[j] + .bss_prio_head); + spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock, + flags); + if (is_list_empty) + continue; + + /* + * Always choose the next ra we transmitted + * last time, this way we pick the ra's in + * round robin fashion. + */ + ptr = list_first_entry( + &tid_ptr->ra_list_curr->list, + struct mwifiex_ra_list_tbl, + list); + + head = ptr; + if (ptr == (struct mwifiex_ra_list_tbl *) + &tid_ptr->ra_list) { + /* Get next ra */ + ptr = list_first_entry(&ptr->list, + struct mwifiex_ra_list_tbl, list); + head = ptr; + } + + do { + is_list_empty = + skb_queue_empty(&ptr->skb_head); + if (!is_list_empty) { + *priv = priv_tmp; + *tid = tos_to_tid[i]; + return ptr; + } + /* Get next ra */ + ptr = list_first_entry(&ptr->list, + struct mwifiex_ra_list_tbl, + list); + if (ptr == + (struct mwifiex_ra_list_tbl *) + &tid_ptr->ra_list) + ptr = list_first_entry( + &ptr->list, + struct mwifiex_ra_list_tbl, + list); + } while (ptr != head); + } + + /* Get next bss priority node */ + bssprio_node = list_first_entry(&bssprio_node->list, + struct mwifiex_bss_prio_node, + list); + + if (bssprio_node == + (struct mwifiex_bss_prio_node *) + &adapter->bss_prio_tbl[j].bss_prio_head) + /* Get next bss priority node */ + bssprio_node = list_first_entry( + &bssprio_node->list, + struct mwifiex_bss_prio_node, + list); + } while (bssprio_node != bssprio_head); + } + return NULL; +} + +/* + * This function gets the number of packets in the Tx queue of a + * particular RA list. + */ +static int +mwifiex_num_pkts_in_txq(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int max_buf_size) +{ + int count = 0, total_size = 0; + struct sk_buff *skb, *tmp; + + skb_queue_walk_safe(&ptr->skb_head, skb, tmp) { + total_size += skb->len; + if (total_size < max_buf_size) + ++count; + else + break; + } + + return count; +} + +/* + * This function sends a single packet to firmware for transmission. + */ +static void +mwifiex_send_single_packet(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int ptr_index, + unsigned long ra_list_flags) + __releases(&priv->wmm.ra_list_spinlock) +{ + struct sk_buff *skb, *skb_next; + struct mwifiex_tx_param tx_param; + struct mwifiex_adapter *adapter = priv->adapter; + int status = 0; + struct mwifiex_txinfo *tx_info; + + if (skb_queue_empty(&ptr->skb_head)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + dev_dbg(adapter->dev, "data: nothing to send\n"); + return; + } + + skb = skb_dequeue(&ptr->skb_head); + + tx_info = MWIFIEX_SKB_TXCB(skb); + dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); + + ptr->total_pkts_size -= skb->len; + + if (!skb_queue_empty(&ptr->skb_head)) + skb_next = skb_peek(&ptr->skb_head); + else + skb_next = NULL; + + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); + + tx_param.next_pkt_len = ((skb_next) ? skb_next->len + + sizeof(struct txpd) : 0); + + status = mwifiex_process_tx(priv, skb, &tx_param); + + if (status == -EBUSY) { + /* Queue the packet back at the head */ + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + + if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + mwifiex_write_data_complete(adapter, skb, -1); + return; + } + + skb_queue_tail(&ptr->skb_head, skb); + + ptr->total_pkts_size += skb->len; + tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + } else { + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { + priv->wmm.packets_out[ptr_index]++; + priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; + } + adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = + list_first_entry( + &adapter->bss_prio_tbl[priv->bss_priority] + .bss_prio_cur->list, + struct mwifiex_bss_prio_node, + list); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + } +} + +/* + * This function checks if the first packet in the given RA list + * is already processed or not. + */ +static int +mwifiex_is_ptr_processed(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr) +{ + struct sk_buff *skb; + struct mwifiex_txinfo *tx_info; + + if (skb_queue_empty(&ptr->skb_head)) + return false; + + skb = skb_peek(&ptr->skb_head); + + tx_info = MWIFIEX_SKB_TXCB(skb); + if (tx_info->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT) + return true; + + return false; +} + +/* + * This function sends a single processed packet to firmware for + * transmission. + */ +static void +mwifiex_send_processed_packet(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ptr, int ptr_index, + unsigned long ra_list_flags) + __releases(&priv->wmm.ra_list_spinlock) +{ + struct mwifiex_tx_param tx_param; + struct mwifiex_adapter *adapter = priv->adapter; + int ret = -1; + struct sk_buff *skb, *skb_next; + struct mwifiex_txinfo *tx_info; + + if (skb_queue_empty(&ptr->skb_head)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + return; + } + + skb = skb_dequeue(&ptr->skb_head); + + if (!skb_queue_empty(&ptr->skb_head)) + skb_next = skb_peek(&ptr->skb_head); + else + skb_next = NULL; + + tx_info = MWIFIEX_SKB_TXCB(skb); + + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); + tx_param.next_pkt_len = + ((skb_next) ? skb_next->len + + sizeof(struct txpd) : 0); + ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, + skb->data, skb->len, &tx_param); + switch (ret) { + case -EBUSY: + dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + + if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + mwifiex_write_data_complete(adapter, skb, -1); + return; + } + + skb_queue_tail(&ptr->skb_head, skb); + + tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + break; + case -1: + adapter->data_sent = false; + dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); + adapter->dbg.num_tx_host_to_card_failure++; + mwifiex_write_data_complete(adapter, skb, ret); + break; + case -EINPROGRESS: + adapter->data_sent = false; + default: + break; + } + if (ret != -EBUSY) { + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); + if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { + priv->wmm.packets_out[ptr_index]++; + priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr; + } + adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = + list_first_entry( + &adapter->bss_prio_tbl[priv->bss_priority] + .bss_prio_cur->list, + struct mwifiex_bss_prio_node, + list); + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, + ra_list_flags); + } +} + +/* + * This function dequeues a packet from the highest priority list + * and transmits it. + */ +static int +mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) +{ + struct mwifiex_ra_list_tbl *ptr; + struct mwifiex_private *priv = NULL; + int ptr_index = 0; + u8 ra[ETH_ALEN]; + int tid_del = 0, tid = 0; + unsigned long flags; + + ptr = mwifiex_wmm_get_highest_priolist_ptr(adapter, &priv, &ptr_index); + if (!ptr) + return -1; + + tid = mwifiex_get_tid(priv->adapter, ptr); + + dev_dbg(adapter->dev, "data: tid=%d\n", tid); + + spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); + if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { + spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); + return -1; + } + + if (mwifiex_is_ptr_processed(priv, ptr)) { + mwifiex_send_processed_packet(priv, ptr, ptr_index, flags); + /* ra_list_spinlock has been freed in + mwifiex_send_processed_packet() */ + return 0; + } + + if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) + || ((priv->sec_info.wpa_enabled + || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set) + ) { + mwifiex_send_single_packet(priv, ptr, ptr_index, flags); + /* ra_list_spinlock has been freed in + mwifiex_send_single_packet() */ + } else { + if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) { + if (mwifiex_is_ba_stream_avail(priv)) { + mwifiex_11n_create_tx_ba_stream_tbl(priv, + ptr->ra, tid, + BA_STREAM_SETUP_INPROGRESS); + mwifiex_send_addba(priv, tid, ptr->ra); + } else if (mwifiex_find_stream_to_delete + (priv, ptr, tid, &tid_del, ra)) { + mwifiex_11n_create_tx_ba_stream_tbl(priv, + ptr->ra, tid, + BA_STREAM_SETUP_INPROGRESS); + mwifiex_send_delba(priv, tid_del, ra, 1); + } + } +/* Minimum number of AMSDU */ +#define MIN_NUM_AMSDU 2 + if (mwifiex_is_amsdu_allowed(priv, ptr, tid) && + (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= + MIN_NUM_AMSDU)) + mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, + ptr_index, flags); + /* ra_list_spinlock has been freed in + mwifiex_11n_aggregate_pkt() */ + else + mwifiex_send_single_packet(priv, ptr, ptr_index, flags); + /* ra_list_spinlock has been freed in + mwifiex_send_single_packet() */ + } + return 0; +} + +/* + * This function transmits the highest priority packet awaiting in the + * WMM Queues. + */ +void +mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) +{ + do { + /* Check if busy */ + if (adapter->data_sent || adapter->tx_lock_flag) + break; + + if (mwifiex_dequeue_tx_packet(adapter)) + break; + } while (true); + + return; +} diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h new file mode 100644 index 000000000000..241f1b0b77f9 --- /dev/null +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -0,0 +1,112 @@ +/* + * Marvell Wireless LAN device driver: WMM + * + * Copyright (C) 2011, Marvell International Ltd. + * + * This software file (the "File") is distributed by Marvell International + * Ltd. under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef _MWIFIEX_WMM_H_ +#define _MWIFIEX_WMM_H_ + +enum ieee_types_wmm_aciaifsn_bitmasks { + MWIFIEX_AIFSN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)), + MWIFIEX_ACM = BIT(4), + MWIFIEX_ACI = (BIT(5) | BIT(6)), +}; + +enum ieee_types_wmm_ecw_bitmasks { + MWIFIEX_ECW_MIN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)), + MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)), +}; + +/* + * This function retrieves the TID of the given RA list. + */ +static inline int +mwifiex_get_tid(struct mwifiex_adapter *adapter, + struct mwifiex_ra_list_tbl *ptr) +{ + struct sk_buff *skb; + + if (skb_queue_empty(&ptr->skb_head)) + return 0; + + skb = skb_peek(&ptr->skb_head); + + return skb->priority; +} + +/* + * This function gets the length of a list. + */ +static inline int +mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) +{ + struct list_head *pos; + int count = 0; + + list_for_each(pos, head) + ++count; + + return count; +} + +/* + * This function checks if a RA list is empty or not. + */ +static inline u8 +mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter, + struct list_head *ra_list_hhead) +{ + struct mwifiex_ra_list_tbl *ra_list; + int is_list_empty; + + list_for_each_entry(ra_list, ra_list_hhead, list) { + is_list_empty = skb_queue_empty(&ra_list->skb_head); + if (!is_list_empty) + return false; + } + + return true; +} + +void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, + struct sk_buff *skb); +void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); + +int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); +void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); +int mwifiex_is_ralist_valid(struct mwifiex_private *priv, + struct mwifiex_ra_list_tbl *ra_list, int tid); + +u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, + const struct sk_buff *skb); +void mwifiex_wmm_init(struct mwifiex_adapter *adapter); + +extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv, + u8 **assoc_buf, + struct ieee_types_wmm_parameter + *wmmie, + struct ieee80211_ht_cap + *htcap); + +void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, + struct ieee_types_wmm_parameter + *wmm_ie); +void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv); +extern int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, + const struct host_cmd_ds_command *resp); + +#endif /* !_MWIFIEX_WMM_H_ */ -- GitLab From f39de992540cf68cc865498242f963f70f7e97b3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 16 Mar 2011 16:41:46 +0200 Subject: [PATCH 0154/5560] libertas_spi: Add support for suspend/resume Add support for suspend/resume in if_spi. Signed-off-by: Vasily Khoruzhick Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 65 ++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index f6c2cd665f49..078ef43d957d 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -57,6 +57,7 @@ struct if_spi_card { /* Handles all SPI communication (except for FW load) */ struct workqueue_struct *workqueue; struct work_struct packet_work; + struct work_struct resume_work; u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; @@ -68,6 +69,9 @@ struct if_spi_card { /* Protects cmd_packet_list and data_packet_list */ spinlock_t buffer_lock; + + /* True is card suspended */ + u8 suspended; }; static void free_if_spi_card(struct if_spi_card *card) @@ -1057,6 +1061,28 @@ static int if_spi_init_card(struct if_spi_card *card) return err; } +static void if_spi_resume_worker(struct work_struct *work) +{ + struct if_spi_card *card; + + card = container_of(work, struct if_spi_card, resume_work); + + if (card->suspended) { + if (card->pdata->setup) + card->pdata->setup(card->spi); + + /* Init card ... */ + if_spi_init_card(card); + + enable_irq(card->spi->irq); + + /* And resume it ... */ + lbs_resume(card->priv); + + card->suspended = 0; + } +} + static int __devinit if_spi_probe(struct spi_device *spi) { struct if_spi_card *card; @@ -1107,6 +1133,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) goto free_card; } card->priv = priv; + priv->setup_fw_on_resume = 1; priv->card = card; priv->hw_host_to_card = if_spi_host_to_card; priv->enter_deep_sleep = NULL; @@ -1117,6 +1144,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) /* Initialize interrupt handling stuff. */ card->workqueue = create_workqueue("libertas_spi"); INIT_WORK(&card->packet_work, if_spi_host_to_card_worker); + INIT_WORK(&card->resume_work, if_spi_resume_worker); err = request_irq(spi->irq, if_spi_host_interrupt, IRQF_TRIGGER_FALLING, "libertas_spi", card); @@ -1161,6 +1189,8 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) lbs_deb_spi("libertas_spi_remove\n"); lbs_deb_enter(LBS_DEB_SPI); + cancel_work_sync(&card->resume_work); + lbs_stop_card(priv); lbs_remove_card(priv); /* will call free_netdev */ @@ -1174,6 +1204,40 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) return 0; } +static int if_spi_suspend(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct if_spi_card *card = spi_get_drvdata(spi); + + if (!card->suspended) { + lbs_suspend(card->priv); + flush_workqueue(card->workqueue); + disable_irq(spi->irq); + + if (card->pdata->teardown) + card->pdata->teardown(spi); + card->suspended = 1; + } + + return 0; +} + +static int if_spi_resume(struct device *dev) +{ + struct spi_device *spi = to_spi_device(dev); + struct if_spi_card *card = spi_get_drvdata(spi); + + /* Schedule delayed work */ + schedule_work(&card->resume_work); + + return 0; +} + +static const struct dev_pm_ops if_spi_pm_ops = { + .suspend = if_spi_suspend, + .resume = if_spi_resume, +}; + static struct spi_driver libertas_spi_driver = { .probe = if_spi_probe, .remove = __devexit_p(libertas_spi_remove), @@ -1181,6 +1245,7 @@ static struct spi_driver libertas_spi_driver = { .name = "libertas_spi", .bus = &spi_bus_type, .owner = THIS_MODULE, + .pm = &if_spi_pm_ops, }, }; -- GitLab From dd347f2fb2ddb20a80e9a8285252bf208ab91398 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 22 Mar 2011 21:54:17 +0100 Subject: [PATCH 0155/5560] ath9k: fix beacon timer handling issues AP mode beacon timers in ath9k are configured in milliseconds, which breaks when increasing ATH_BCBUF to 8 instead of 4 (due to rounding errors). Since the hardware timers are actually configured in microseconds, it's better to let the driver use that unit directly. To be able to do that, the beacon interval parameter abuse for passing certain flags needs to be removed. This is easy to do, because those flags are completely unnecessary anyway. ATH9K_BEACON_ENA is ignored, ATH9K_BEACON_RESET_TSF can be replaced with calling ath9k_hw_reset_tsf from the driver directly. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/beacon.c | 78 ++++++++----------- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 9 +-- drivers/net/wireless/ath/ath9k/hw.c | 36 ++++----- drivers/net/wireless/ath/ath9k/hw.h | 3 +- 5 files changed, 49 insertions(+), 79 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 099bd4183ad0..07dfb31f1749 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -386,7 +386,7 @@ struct ath_beacon { u32 beaconq; u32 bmisscnt; u32 ast_be_xmit; - u64 bc_tstamp; + u32 bc_tstamp; struct ieee80211_vif *bslot[ATH_BCBUF]; int slottime; int slotupdate; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 6d2a545fc35e..b5eab2f55824 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -57,8 +57,8 @@ int ath_beaconq_config(struct ath_softc *sc) /* * Associates the beacon frame buffer with a transmit descriptor. Will set - * up all required antenna switch parameters, rate codes, and channel flags. - * Beacons are always sent out at the lowest rate, and are not retried. + * up rate codes, and channel flags. Beacons are always sent out at the + * lowest rate, and are not retried. */ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, struct ath_buf *bf, int rateidx) @@ -68,7 +68,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, struct ath_common *common = ath9k_hw_common(ah); struct ath_desc *ds; struct ath9k_11n_rate_series series[4]; - int flags, antenna, ctsrate = 0, ctsduration = 0; + int flags, ctsrate = 0, ctsduration = 0; struct ieee80211_supported_band *sband; u8 rate = 0; @@ -76,12 +76,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, flags = ATH9K_TXDESC_NOACK; ds->ds_link = 0; - /* - * Switch antenna every beacon. - * Should only switch every beacon period, not for every SWBA - * XXX assumes two antennae - */ - antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); sband = &sc->sbands[common->hw->conf.channel->band]; rate = sband->bitrates[rateidx].hw_value; @@ -278,7 +272,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) return -ENOMEM; tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - sc->beacon.bc_tstamp = le64_to_cpu(tstamp); + sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp); /* Calculate a TSF adjustment factor required for staggered beacons. */ if (avp->av_bslot > 0) { u64 tsfadjust; @@ -294,8 +288,8 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) * adjustment. Other slots are adjusted to get the timestamp * close to the TBTT for the BSS. */ - tsfadjust = intval * avp->av_bslot / ATH_BCBUF; - avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); + tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF; + avp->tsf_adjust = cpu_to_le64(tsfadjust); ath_dbg(common, ATH_DBG_BEACON, "stagger beacons, bslot %d intval %u tsfadjust %llu\n", @@ -401,8 +395,9 @@ void ath_beacon_tasklet(unsigned long data) intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; tsf = ath9k_hw_gettsf64(ah); - tsftu = TSF_TO_TU(tsf>>32, tsf); - slot = ((tsftu % intval) * ATH_BCBUF) / intval; + tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); + tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); + slot = (tsftu % (intval * ATH_BCBUF)) / intval; /* * Reverse the slot order to get slot 0 on the TBTT offset that does * not require TSF adjustment and other slots adding @@ -415,7 +410,7 @@ void ath_beacon_tasklet(unsigned long data) ath_dbg(common, ATH_DBG_BEACON, "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", - slot, tsf, tsftu, intval, vif); + slot, tsf, tsftu / ATH_BCBUF, intval, vif); bfaddr = 0; if (vif) { @@ -463,13 +458,17 @@ static void ath9k_beacon_init(struct ath_softc *sc, u32 next_beacon, u32 beacon_period) { - if (beacon_period & ATH9K_BEACON_RESET_TSF) + if (sc->sc_flags & SC_OP_TSF_RESET) { ath9k_ps_wakeup(sc); + ath9k_hw_reset_tsf(sc->sc_ah); + } ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); - if (beacon_period & ATH9K_BEACON_RESET_TSF) + if (sc->sc_flags & SC_OP_TSF_RESET) { ath9k_ps_restore(sc); + sc->sc_flags &= ~SC_OP_TSF_RESET; + } } /* @@ -484,18 +483,14 @@ static void ath_beacon_config_ap(struct ath_softc *sc, u32 nexttbtt, intval; /* NB: the beacon interval is kept internally in TU's */ - intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; + intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); intval /= ATH_BCBUF; /* for staggered beacons */ nexttbtt = intval; - if (sc->sc_flags & SC_OP_TSF_RESET) - intval |= ATH9K_BEACON_RESET_TSF; - /* * In AP mode we enable the beacon timers and SWBA interrupts to * prepare beacon frames. */ - intval |= ATH9K_BEACON_ENA; ah->imask |= ATH9K_INT_SWBA; ath_beaconq_config(sc); @@ -505,11 +500,6 @@ static void ath_beacon_config_ap(struct ath_softc *sc, ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah, ah->imask); - - /* Clear the reset TSF flag, so that subsequent beacon updation - will not reset the HW TSF. */ - - sc->sc_flags &= ~SC_OP_TSF_RESET; } /* @@ -643,25 +633,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - u64 tsf; - u32 tsftu, intval, nexttbtt; - - intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; - - - /* Pull nexttbtt forward to reflect the current TSF */ - - nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); - if (nexttbtt == 0) - nexttbtt = intval; - else if (intval) - nexttbtt = roundup(nexttbtt, intval); - - tsf = ath9k_hw_gettsf64(ah); - tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; - do { - nexttbtt += intval; - } while (nexttbtt < tsftu); + u32 tsf, delta, intval, nexttbtt; + + tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); + intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); + + if (!sc->beacon.bc_tstamp) + nexttbtt = tsf + intval; + else { + if (tsf > sc->beacon.bc_tstamp) + delta = (tsf - sc->beacon.bc_tstamp); + else + delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); + nexttbtt = tsf + roundup(delta, intval); + } ath_dbg(common, ATH_DBG_BEACON, "IBSS nexttbtt %u intval %u (%u)\n", @@ -672,7 +657,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, * if we need to manually prepare beacon frames. Otherwise we use a * self-linked tx descriptor and let the hardware deal with things. */ - intval |= ATH9K_BEACON_ENA; ah->imask |= ATH9K_INT_SWBA; ath_beaconq_config(sc); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8d1d8792436d..8f56158e5887 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -155,7 +155,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, nexttbtt = intval; if (priv->op_flags & OP_TSF_RESET) { - intval |= ATH9K_BEACON_RESET_TSF; + ath9k_hw_reset_tsf(priv->ah); priv->op_flags &= ~OP_TSF_RESET; } else { /* @@ -168,8 +168,6 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, } while (nexttbtt < tsftu); } - intval |= ATH9K_BEACON_ENA; - if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; @@ -178,7 +176,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, bss_conf->beacon_interval, nexttbtt, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); - ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); + ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); priv->bmiss_cnt = 0; htc_imask = cpu_to_be32(imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); @@ -207,7 +205,6 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, nexttbtt += intval; } while (nexttbtt < tsftu); - intval |= ATH9K_BEACON_ENA; if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; @@ -216,7 +213,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, bss_conf->beacon_interval, nexttbtt, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); - ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); + ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); priv->bmiss_cnt = 0; htc_imask = cpu_to_be32(imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8b8656898dfe..9513ec745b93 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1697,21 +1697,15 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) case NL80211_IFTYPE_MESH_POINT: REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); - REG_WRITE(ah, AR_NEXT_NDP_TIMER, - TU_TO_USEC(next_beacon + - (ah->atim_window ? ah-> - atim_window : 1))); + REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon + + TU_TO_USEC(ah->atim_window ? ah->atim_window : 1)); flags |= AR_NDP_TIMER_EN; case NL80211_IFTYPE_AP: - REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); - REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, - TU_TO_USEC(next_beacon - - ah->config. - dma_beacon_response_time)); - REG_WRITE(ah, AR_NEXT_SWBA, - TU_TO_USEC(next_beacon - - ah->config. - sw_beacon_response_time)); + REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); + REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon - + TU_TO_USEC(ah->config.dma_beacon_response_time)); + REG_WRITE(ah, AR_NEXT_SWBA, next_beacon - + TU_TO_USEC(ah->config.sw_beacon_response_time)); flags |= AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; break; @@ -1723,18 +1717,13 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) break; } - REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); - REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period)); - REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); - REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); + REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period); + REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period); + REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period); + REG_WRITE(ah, AR_NDP_PERIOD, beacon_period); REGWRITE_BUFFER_FLUSH(ah); - beacon_period &= ~ATH9K_BEACON_ENA; - if (beacon_period & ATH9K_BEACON_RESET_TSF) { - ath9k_hw_reset_tsf(ah); - } - REG_SET_BIT(ah, AR_TIMER_MODE, flags); } EXPORT_SYMBOL(ath9k_hw_beaconinit); @@ -2395,10 +2384,11 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask) return timer_table->gen_timer_index[b]; } -static u32 ath9k_hw_gettsf32(struct ath_hw *ah) +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 3d9fc6e391a7..c819973c7c84 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -416,8 +416,6 @@ struct ath9k_beacon_state { u32 bs_nextdtim; u32 bs_intval; #define ATH9K_BEACON_PERIOD 0x0000ffff -#define ATH9K_BEACON_ENA 0x00800000 -#define ATH9K_BEACON_RESET_TSF 0x01000000 #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ u32 bs_dtimperiod; u16 bs_cfpperiod; @@ -930,6 +928,7 @@ 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); void ath9k_hw_write_associd(struct ath_hw *ah); +u32 ath9k_hw_gettsf32(struct ath_hw *ah); u64 ath9k_hw_gettsf64(struct ath_hw *ah); void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); void ath9k_hw_reset_tsf(struct ath_hw *ah); -- GitLab From 87c510fe2d4f193cd4eb518364a2dfa5059b1218 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 22 Mar 2011 21:54:18 +0100 Subject: [PATCH 0156/5560] ath9k: trigger nfcal only after multiple missed beacons in AP mode Single missed (i.e. not transmitted) beacons in AP mode are not very rare and not necessarily an indicator of strong interference, so only trigger noise floor recalibration when multiple consecutive beacons could not be transmitted. Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b5eab2f55824..6ebeafe3a92f 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -368,7 +368,8 @@ void ath_beacon_tasklet(unsigned long data) "missed %u consecutive beacons\n", sc->beacon.bmisscnt); ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); - ath9k_hw_bstuck_nfcal(ah); + if (sc->beacon.bmisscnt > 3) + ath9k_hw_bstuck_nfcal(ah); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { ath_dbg(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); -- GitLab From c944daf46a8cfa50d6c1f54d4842180d0384c594 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 22 Mar 2011 21:54:19 +0100 Subject: [PATCH 0157/5560] ath9k: fix stuck beacon detection Stuck beacon detection is supposed to trigger when 9 consecutive beacons could not be sent by the hardware. When the driver runs only one active AP mode interface, it still configures the hardware beacon timer for 4 (ATH_BCBUF) beacon slots slots, which causes stuck beacon detection to be reset if ath9k_hw_stoptxdma clears the stuck frames between SWBA intervals. Fix this by not resetting the missed beacon count for empty slots and multiplying the threshold not by the maximum number of beacon slots but by the configured number of beacon interfaces. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/beacon.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 07dfb31f1749..7c91ba4dce41 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -362,7 +362,7 @@ struct ath_vif { * number of BSSIDs) if a given beacon does not go out even after waiting this * number of beacon intervals, the game's up. */ -#define BSTUCK_THRESH (9 * ATH_BCBUF) +#define BSTUCK_THRESH 9 #define ATH_BCBUF 4 #define ATH_DEFAULT_BINTVAL 100 /* TU */ #define ATH_DEFAULT_BMISS_LIMIT 10 diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 6ebeafe3a92f..74f33bc193fe 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -363,7 +363,7 @@ void ath_beacon_tasklet(unsigned long data) if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { sc->beacon.bmisscnt++; - if (sc->beacon.bmisscnt < BSTUCK_THRESH) { + if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { ath_dbg(common, ATH_DBG_BSTUCK, "missed %u consecutive beacons\n", sc->beacon.bmisscnt); @@ -380,13 +380,6 @@ void ath_beacon_tasklet(unsigned long data) return; } - if (sc->beacon.bmisscnt != 0) { - ath_dbg(common, ATH_DBG_BSTUCK, - "resume beacon xmit after %u misses\n", - sc->beacon.bmisscnt); - sc->beacon.bmisscnt = 0; - } - /* * Generate beacon frames. we are sending frames * staggered so calculate the slot for this frame based @@ -420,6 +413,13 @@ void ath_beacon_tasklet(unsigned long data) bfaddr = bf->bf_daddr; bc = 1; } + + if (sc->beacon.bmisscnt != 0) { + ath_dbg(common, ATH_DBG_BSTUCK, + "resume beacon xmit after %u misses\n", + sc->beacon.bmisscnt); + sc->beacon.bmisscnt = 0; + } } /* -- GitLab From cfdc9a8bb8d90c6aa212a5a881862599673c443d Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 23 Mar 2011 14:52:19 +0200 Subject: [PATCH 0158/5560] ath9k: Support RSN IBSS Add support for using RSN IBSS with ath9k. For now, this uses software crypto for group addressed frames in RSN IBSS, but that may be optimized in the future by extending the key cache design to support per-STA RX GTK. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index cdb0f1c89a0e..b590a9e7943a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -690,6 +690,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) if (AR_SREV_5416(sc->sc_ah)) hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + hw->queues = 4; hw->max_rates = 4; hw->channel_change_time = 5000; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 524825720a09..3c5de73dcb4b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1845,6 +1845,20 @@ static int ath9k_set_key(struct ieee80211_hw *hw, if (ath9k_modparam_nohwcrypt) return -ENOSPC; + if (vif->type == NL80211_IFTYPE_ADHOC && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* + * For now, disable hw crypto for the RSN IBSS group keys. This + * could be optimized in the future to use a modified key cache + * design to support per-STA RX GTK, but until that gets + * implemented, use of software crypto for group addressed + * frames is a acceptable to allow RSN IBSS to be used. + */ + return -EOPNOTSUPP; + } + mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); -- GitLab From ec15e68ba6a505631016f230899bafbb7b8cd0d6 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 23 Mar 2011 15:29:52 +0200 Subject: [PATCH 0159/5560] cfg80211: Add nl80211 event for deletion of a station entry Indicate an NL80211_CMD_DEL_STATION event when a station entry in mac80211 is deleted to match with the NL80211_CMD_NEW_STATION event that is used when the entry was added. This is needed, e.g., to allow user space to remove a peer from RSN IBSS Authenticator state machine to avoid re-authentication and re-keying delays when the peer is not reachable anymore. Signed-off-by: Jouni Malinen Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 9 +++++++++ net/mac80211/sta_info.c | 2 ++ net/wireless/mlme.c | 9 +++++++++ net/wireless/nl80211.c | 34 ++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 3 +++ 5 files changed, 57 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b2b9d28cb4ab..2c4530451721 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2666,6 +2666,15 @@ void cfg80211_remain_on_channel_expired(struct net_device *dev, void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo, gfp_t gfp); +/** + * cfg80211_del_sta - notify userspace about deletion of a station + * + * @dev: the netdev + * @mac_addr: the station's address + * @gfp: allocation flags + */ +void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); + /** * cfg80211_rx_mgmt - notification of received, unprocessed management frame * @dev: network device diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d0311a322ddd..5ec0a7c51b6d 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -698,6 +698,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ cancel_work_sync(&sta->drv_unblock_wk); + cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL); + rate_control_remove_sta_debugfs(sta); ieee80211_sta_debugfs_remove(sta); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index aa5df8865ff7..16881fea4ce6 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -770,6 +770,15 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, } EXPORT_SYMBOL(cfg80211_new_sta); +void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) +{ + struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + + nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp); +} +EXPORT_SYMBOL(cfg80211_del_sta); + struct cfg80211_mgmt_registration { struct list_head list; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4ebce4284e9d..40c90fb461c4 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5966,6 +5966,40 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, nl80211_mlme_mcgrp.id, gfp); } +void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, + struct net_device *dev, const u8 *mac_addr, + gfp_t gfp) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + 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); +} + int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, struct net_device *netdev, u32 nlpid, int freq, const u8 *buf, size_t len, gfp_t gfp) diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index e3f7fa886966..dcac5cd6f017 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -79,6 +79,9 @@ void nl80211_send_remain_on_channel_cancel( void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo, gfp_t gfp); +void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, + struct net_device *dev, const u8 *mac_addr, + gfp_t gfp); int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, struct net_device *netdev, u32 nlpid, int freq, -- GitLab From f9f84e96f6d642aa7b337c22cbb7d6f936039fda Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:24 +0100 Subject: [PATCH 0160/5560] ath9k_hw: embed the ath_ops callbacks in the ath_hw struct With this change, loading the address to a register read/write function costs only one pointer dereference instead of two. On MIPS this reduces ath9k_hw binary size from 326k down to 321k. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 15 ++++++--------- drivers/net/wireless/ath/ath9k/hw.h | 16 +++++++++------- drivers/net/wireless/ath/ath9k/init.c | 9 +++------ 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index fc67c937e172..4e26946f7ab2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -430,14 +430,6 @@ static void ath9k_regwrite_flush(void *hw_priv) mutex_unlock(&priv->wmi->multi_write_mutex); } -static const struct ath_ops ath9k_common_ops = { - .read = ath9k_regread, - .multi_read = ath9k_multi_regread, - .write = ath9k_regwrite, - .enable_write_buffer = ath9k_enable_regwrite_buffer, - .write_flush = ath9k_regwrite_flush, -}; - static void ath_usb_read_cachesize(struct ath_common *common, int *csz) { *csz = L1_CACHE_BYTES >> 2; @@ -658,10 +650,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ah->hw_version.subsysid = 0; /* FIXME */ ah->hw_version.usbdev = drv_info; ah->ah_flags |= AH_USE_EEPROM; + ah->reg_ops.read = ath9k_regread; + ah->reg_ops.multi_read = ath9k_multi_regread; + ah->reg_ops.write = ath9k_regwrite; + ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer; + ah->reg_ops.write_flush = ath9k_regwrite_flush; priv->ah = ah; common = ath9k_hw_common(ah); - common->ops = &ath9k_common_ops; + common->ops = &ah->reg_ops; common->bus_ops = &ath9k_usb_bus_ops; common->ah = ah; common->hw = priv->hw; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c819973c7c84..ef387a2f54b2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -65,24 +65,24 @@ /* Register read/write primitives */ #define REG_WRITE(_ah, _reg, _val) \ - ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) + (_ah)->reg_ops.write((_ah), (_val), (_reg)) #define REG_READ(_ah, _reg) \ - ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) + (_ah)->reg_ops.read((_ah), (_reg)) #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ - ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt)) + (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt)) #define ENABLE_REGWRITE_BUFFER(_ah) \ do { \ - if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ - ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ + if ((_ah)->reg_ops.enable_write_buffer) \ + (_ah)->reg_ops.enable_write_buffer((_ah)); \ } while (0) #define REGWRITE_BUFFER_FLUSH(_ah) \ do { \ - if (ath9k_hw_common(_ah)->ops->write_flush) \ - ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ + if ((_ah)->reg_ops.write_flush) \ + (_ah)->reg_ops.write_flush((_ah)); \ } while (0) #define SM(_v, _f) (((_v) << _f##_S) & _f) @@ -657,6 +657,8 @@ struct ath_nf_limits { #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ struct ath_hw { + struct ath_ops reg_ops; + struct ieee80211_hw *hw; struct ath_common common; struct ath9k_hw_version hw_version; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index b590a9e7943a..da114c2f0dbe 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -196,11 +196,6 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) return val; } -static const struct ath_ops ath9k_common_ops = { - .read = ath9k_ioread32, - .write = ath9k_iowrite32, -}; - /**************************/ /* Initialization */ /**************************/ @@ -551,6 +546,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw = sc->hw; ah->hw_version.devid = devid; ah->hw_version.subsysid = subsysid; + ah->reg_ops.read = ath9k_ioread32; + ah->reg_ops.write = ath9k_iowrite32; sc->sc_ah = ah; if (!pdata) { @@ -563,7 +560,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, } common = ath9k_hw_common(ah); - common->ops = &ath9k_common_ops; + common->ops = &ah->reg_ops; common->bus_ops = bus_ops; common->ah = ah; common->hw = sc->hw; -- GitLab From 845e03c93dda2c00ffb5c68a1f7c8efc412d7c1a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:25 +0100 Subject: [PATCH 0161/5560] ath9k_hw: add a new register op for read-mask-write Reduces the number of calls to register ops. On MIPS this reduces the ath9k_hw binary size from 321k down to 310k Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 ++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 12 +++++----- drivers/net/wireless/ath/ath9k/init.c | 23 +++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index a6c6a466000f..6d7105b7e8f1 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -119,6 +119,7 @@ struct ath_ops { void (*write)(void *, u32 val, u32 reg_offset); void (*enable_write_buffer)(void *); void (*write_flush) (void *); + u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr); }; struct ath_common; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 4e26946f7ab2..ca69e7ccfd80 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -430,6 +430,17 @@ static void ath9k_regwrite_flush(void *hw_priv) mutex_unlock(&priv->wmi->multi_write_mutex); } +static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) +{ + u32 val; + + val = ath9k_regread(hw_priv, reg_offset); + val &= ~clr; + val |= set; + ath9k_regwrite(hw_priv, val, reg_offset); + return val; +} + static void ath_usb_read_cachesize(struct ath_common *common, int *csz) { *csz = L1_CACHE_BYTES >> 2; @@ -655,6 +666,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ah->reg_ops.write = ath9k_regwrite; ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer; ah->reg_ops.write_flush = ath9k_regwrite_flush; + ah->reg_ops.rmw = ath9k_reg_rmw; priv->ah = ah; common = ath9k_hw_common(ah); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ef387a2f54b2..e256658c740a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -73,6 +73,9 @@ #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt)) +#define REG_RMW(_ah, _reg, _set, _clr) \ + (_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr)) + #define ENABLE_REGWRITE_BUFFER(_ah) \ do { \ if ((_ah)->reg_ops.enable_write_buffer) \ @@ -87,17 +90,14 @@ #define SM(_v, _f) (((_v) << _f##_S) & _f) #define MS(_v, _f) (((_v) & _f) >> _f##_S) -#define REG_RMW(_a, _r, _set, _clr) \ - REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set)) #define REG_RMW_FIELD(_a, _r, _f, _v) \ - REG_WRITE(_a, _r, \ - (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) + REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f)) #define REG_READ_FIELD(_a, _r, _f) \ (((REG_READ(_a, _r) & _f) >> _f##_S)) #define REG_SET_BIT(_a, _r, _f) \ - REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f)) + REG_RMW(_a, _r, (_f), 0) #define REG_CLR_BIT(_a, _r, _f) \ - REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f)) + REG_RMW(_a, _r, 0, (_f)) #define DO_DELAY(x) do { \ if (((++(x) % 64) == 0) && \ diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index da114c2f0dbe..db1b7553c684 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -196,6 +196,28 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) return val; } +static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) +{ + struct ath_hw *ah = (struct ath_hw *) hw_priv; + struct ath_common *common = ath9k_hw_common(ah); + struct ath_softc *sc = (struct ath_softc *) common->priv; + unsigned long uninitialized_var(flags); + u32 val; + + if (ah->config.serialize_regmode == SER_REG_MODE_ON) + spin_lock_irqsave(&sc->sc_serial_rw, flags); + + val = ioread32(sc->mem + reg_offset); + val &= ~clr; + val |= set; + iowrite32(val, sc->mem + reg_offset); + + if (ah->config.serialize_regmode == SER_REG_MODE_ON) + spin_unlock_irqrestore(&sc->sc_serial_rw, flags); + + return val; +} + /**************************/ /* Initialization */ /**************************/ @@ -548,6 +570,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw_version.subsysid = subsysid; ah->reg_ops.read = ath9k_ioread32; ah->reg_ops.write = ath9k_iowrite32; + ah->reg_ops.rmw = ath9k_reg_rmw; sc->sc_ah = ah; if (!pdata) { -- GitLab From ca7a4deb4a1a87dbdc6e7cab0d1022a535204226 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:26 +0100 Subject: [PATCH 0162/5560] ath9k_hw: replace REG_READ+REG_WRITE with REG_RMW It's easier to read and it slightly decreases code size Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 66 ++++++++++--------------- drivers/net/wireless/ath/ath9k/mac.c | 73 ++++++++++++---------------- 2 files changed, 56 insertions(+), 83 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9513ec745b93..807d410e7645 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -675,14 +675,14 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { - REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK))); - udelay(100); - REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK)); + REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); + udelay(100); + REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) - udelay(100); + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) + udelay(100); - return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; + return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); @@ -832,8 +832,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ah->misc_mode); if (ah->misc_mode != 0) - REG_WRITE(ah, AR_PCU_MISC, - REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); + REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode); if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ) sifstime = 16; @@ -901,23 +900,19 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan) static inline void ath9k_hw_set_dma(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - u32 regval; ENABLE_REGWRITE_BUFFER(ah); /* * set AHB_MODE not to do cacheline prefetches */ - if (!AR_SREV_9300_20_OR_LATER(ah)) { - regval = REG_READ(ah, AR_AHB_MODE); - REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); - } + if (!AR_SREV_9300_20_OR_LATER(ah)) + REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); /* * let mac dma reads be in 128 byte chunks */ - regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; - REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); + REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK); REGWRITE_BUFFER_FLUSH(ah); @@ -934,8 +929,7 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) /* * let mac dma writes be in 128 byte chunks */ - regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; - REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); + REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK); /* * Setup receive FIFO threshold to hold off TX activities @@ -974,30 +968,27 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) { - u32 val; + u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC; + u32 set = AR_STA_ID1_KSRCH_MODE; - val = REG_READ(ah, AR_STA_ID1); - val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC); switch (opmode) { - case NL80211_IFTYPE_AP: - REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP - | AR_STA_ID1_KSRCH_MODE); - REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); - break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: - REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC - | AR_STA_ID1_KSRCH_MODE); + set |= AR_STA_ID1_ADHOC; REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); break; + case NL80211_IFTYPE_AP: + set |= AR_STA_ID1_STA_AP; + /* fall through */ case NL80211_IFTYPE_STATION: - REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); + REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); break; default: - if (ah->is_monitoring) - REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); + if (!ah->is_monitoring) + set = 0; break; } + REG_RMW(ah, AR_STA_ID1, set, mask); } void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, @@ -1023,10 +1014,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) u32 tmpReg; if (AR_SREV_9100(ah)) { - u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK); - val &= ~AR_RTC_DERIVED_CLK_PERIOD; - val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD); - REG_WRITE(ah, AR_RTC_DERIVED_CLK, val); + REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK, + AR_RTC_DERIVED_CLK_PERIOD, 1); (void)REG_READ(ah, AR_RTC_DERIVED_CLK); } @@ -1451,8 +1440,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ar9002_hw_enable_wep_aggregation(ah); } - REG_WRITE(ah, AR_STA_ID1, - REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); + REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); ath9k_hw_set_dma(ah); @@ -2204,11 +2192,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) REG_WRITE(ah, AR_PHY_ERR, phybits); if (phybits) - REG_WRITE(ah, AR_RXCFG, - REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); + REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA); else - REG_WRITE(ah, AR_RXCFG, - REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); + REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA); REGWRITE_BUFFER_FLUSH(ah); } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 562257ac52cf..db496f2e1f6b 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -465,10 +465,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) REG_WRITE(ah, AR_QCBRCFG(q), SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); - REG_WRITE(ah, AR_QMISC(q), - REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | - (qi->tqi_cbrOverflowLimit ? - AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); + REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR | + (qi->tqi_cbrOverflowLimit ? + AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); } if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { REG_WRITE(ah, AR_QRDYTIMECFG(q), @@ -481,40 +480,31 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); if (qi->tqi_burstTime - && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { - REG_WRITE(ah, AR_QMISC(q), - REG_READ(ah, AR_QMISC(q)) | - AR_Q_MISC_RDYTIME_EXP_POLICY); + && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) + REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY); - } - - if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) { - REG_WRITE(ah, AR_DMISC(q), - REG_READ(ah, AR_DMISC(q)) | - AR_D_MISC_POST_FR_BKOFF_DIS); - } + if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) + REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS); REGWRITE_BUFFER_FLUSH(ah); - if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { - REG_WRITE(ah, AR_DMISC(q), - REG_READ(ah, AR_DMISC(q)) | - AR_D_MISC_FRAG_BKOFF_EN); - } + if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) + REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN); + switch (qi->tqi_type) { case ATH9K_TX_QUEUE_BEACON: ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) - | AR_Q_MISC_FSP_DBA_GATED - | AR_Q_MISC_BEACON_USE - | AR_Q_MISC_CBR_INCR_DIS1); + REG_SET_BIT(ah, AR_QMISC(q), + AR_Q_MISC_FSP_DBA_GATED + | AR_Q_MISC_BEACON_USE + | AR_Q_MISC_CBR_INCR_DIS1); - REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) - | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << + REG_SET_BIT(ah, AR_DMISC(q), + (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << AR_D_MISC_ARB_LOCKOUT_CNTRL_S) - | AR_D_MISC_BEACON_USE - | AR_D_MISC_POST_FR_BKOFF_DIS); + | AR_D_MISC_BEACON_USE + | AR_D_MISC_POST_FR_BKOFF_DIS); REGWRITE_BUFFER_FLUSH(ah); @@ -533,41 +523,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) case ATH9K_TX_QUEUE_CAB: ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) - | AR_Q_MISC_FSP_DBA_GATED - | AR_Q_MISC_CBR_INCR_DIS1 - | AR_Q_MISC_CBR_INCR_DIS0); + REG_SET_BIT(ah, AR_QMISC(q), + AR_Q_MISC_FSP_DBA_GATED + | AR_Q_MISC_CBR_INCR_DIS1 + | AR_Q_MISC_CBR_INCR_DIS0); value = (qi->tqi_readyTime - (ah->config.sw_beacon_response_time - ah->config.dma_beacon_response_time) - ah->config.additional_swba_backoff) * 1024; REG_WRITE(ah, AR_QRDYTIMECFG(q), value | AR_Q_RDYTIMECFG_EN); - REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) - | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << + REG_SET_BIT(ah, AR_DMISC(q), + (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); REGWRITE_BUFFER_FLUSH(ah); break; case ATH9K_TX_QUEUE_PSPOLL: - REG_WRITE(ah, AR_QMISC(q), - REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1); + REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1); break; case ATH9K_TX_QUEUE_UAPSD: - REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | - AR_D_MISC_POST_FR_BKOFF_DIS); + REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS); break; default: break; } if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { - REG_WRITE(ah, AR_DMISC(q), - REG_READ(ah, AR_DMISC(q)) | - SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, - AR_D_MISC_ARB_LOCKOUT_CNTRL) | - AR_D_MISC_POST_FR_BKOFF_DIS); + REG_SET_BIT(ah, AR_DMISC(q), + SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, + AR_D_MISC_ARB_LOCKOUT_CNTRL) | + AR_D_MISC_POST_FR_BKOFF_DIS); } if (AR_SREV_9300_20_OR_LATER(ah)) -- GitLab From a9b6b2569cf107fe541381e82faa0a3c47a9a7fd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:27 +0100 Subject: [PATCH 0163/5560] ath9k_hw: turn a few big macros into functions RF_BANK_SETUP, REG_WRITE_RF_ARRAY and REG_WRITE_ARRAY are way too big, so they shouldn't be inlined at every single callsite, especially since they can easily be turned into real functions. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 38 ++++++++++++++++++--- drivers/net/wireless/ath/ath9k/hw.c | 14 ++++++++ drivers/net/wireless/ath/ath9k/hw.h | 14 +++----- drivers/net/wireless/ath/ath9k/phy.h | 16 --------- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 94acce59f51d..4361704fe0d0 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -44,6 +44,34 @@ static const int m1ThreshExt_off = 127; static const int m2ThreshExt_off = 127; +static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array, + int col) +{ + int i; + + for (i = 0; i < array->ia_rows; i++) + bank[i] = INI_RA(array, i, col); +} + + +#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \ + ar5008_write_rf_array(ah, iniarray, regData, &(regWr)) + +static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array, + u32 *data, unsigned int *writecnt) +{ + int r; + + ENABLE_REGWRITE_BUFFER(ah); + + for (r = 0; r < array->ia_rows; r++) { + REG_WRITE(ah, INI_RA(array, r, 0), data[r]); + DO_DELAY(*writecnt); + } + + REGWRITE_BUFFER_FLUSH(ah); +} + /** * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters * @rfbuf: @@ -530,16 +558,16 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); /* Setup Bank 0 Write */ - RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); + ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1); /* Setup Bank 1 Write */ - RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); + ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1); /* Setup Bank 2 Write */ - RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); + ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1); /* Setup Bank 6 Write */ - RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, + ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3, modesIndex); { int i; @@ -569,7 +597,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, } /* Setup Bank 7 Setup */ - RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); + ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1); /* Write Analog registers */ REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 807d410e7645..bb9a3f3c1b71 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -130,6 +130,20 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) } EXPORT_SYMBOL(ath9k_hw_wait); +void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, + int column, unsigned int *writecnt) +{ + int r; + + ENABLE_REGWRITE_BUFFER(ah); + for (r = 0; r < array->ia_rows; r++) { + REG_WRITE(ah, INI_RA(array, r, 0), + INI_RA(array, r, column)); + DO_DELAY(*writecnt); + } + REGWRITE_BUFFER_FLUSH(ah); +} + u32 ath9k_hw_reverse_bits(u32 val, u32 n) { u32 retval; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index e256658c740a..dafbe97a969c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -106,16 +106,8 @@ udelay(1); \ } while (0) -#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ - int r; \ - ENABLE_REGWRITE_BUFFER(ah); \ - for (r = 0; r < ((iniarray)->ia_rows); r++) { \ - REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ - INI_RA((iniarray), r, (column))); \ - DO_DELAY(regWr); \ - } \ - REGWRITE_BUFFER_FLUSH(ah); \ - } while (0) +#define REG_WRITE_ARRAY(iniarray, column, regWr) \ + ath9k_hw_write_array(ah, iniarray, column, &(regWr)) #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 @@ -913,6 +905,8 @@ void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, /* General Operation */ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); +void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, + int column, unsigned int *writecnt); u32 ath9k_hw_reverse_bits(u32 val, u32 n); bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high); u16 ath9k_hw_computetxtime(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index e4029325c787..f50e2c29f71e 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -38,27 +38,11 @@ #define AR_PHY_CLC_Q0 0x0000ffd0 #define AR_PHY_CLC_Q0_S 5 -#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ - int r; \ - ENABLE_REGWRITE_BUFFER(ah); \ - for (r = 0; r < ((iniarray)->ia_rows); r++) { \ - REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \ - DO_DELAY(regWr); \ - } \ - REGWRITE_BUFFER_FLUSH(ah); \ - } while (0) - #define ANTSWAP_AB 0x0001 #define REDUCE_CHAIN_0 0x00000050 #define REDUCE_CHAIN_1 0x00000051 #define AR_PHY_CHIP_ID 0x9818 -#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ - int i; \ - for (i = 0; i < (_iniarray)->ia_rows; i++) \ - (_bank)[i] = INI_RA((_iniarray), i, _col);; \ - } while (0) - #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 -- GitLab From f4c607dc53ece4ac15afed163292425efa060775 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:28 +0100 Subject: [PATCH 0164/5560] ath9k_hw: remove pCap->total_queues The EEPROM contains a field that can restrict the number of hardware queues, however this is not only useless (all the known chips contain the same number of hardware queues), but also potentially dangerous in case of a misprogrammed EEPROM (could trigger driver crashes), so let's just ignore it completely. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 8 +----- drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/mac.c | 38 ++++------------------------ 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index bb9a3f3c1b71..de0d218195da 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1437,7 +1437,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REGWRITE_BUFFER_FLUSH(ah); ah->intr_txqs = 0; - for (i = 0; i < ah->caps.total_queues; i++) + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) ath9k_hw_resettxqueue(ah, i); ath9k_hw_init_interrupt_masks(ah, ah->opmode); @@ -1885,12 +1885,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->hw_caps &= ~ATH9K_HW_CAP_HT; - if (capField & AR_EEPROM_EEPCAP_MAXQCU) - pCap->total_queues = - MS(capField, AR_EEPROM_EEPCAP_MAXQCU); - else - pCap->total_queues = ATH9K_NUM_TX_QUEUES; - if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES) pCap->keycache_size = 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dafbe97a969c..4e62ad858d8a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -191,7 +191,6 @@ enum ath9k_hw_caps { struct ath9k_hw_capabilities { u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ - u16 total_queues; u16 keycache_size; u16 low_5ghz_chan, high_5ghz_chan; u16 low_2ghz_chan, high_2ghz_chan; diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index db496f2e1f6b..05efcfbeeadc 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -209,15 +209,8 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, { u32 cw; struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath9k_tx_queue_info *qi; - if (q >= pCap->total_queues) { - 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_dbg(common, ATH_DBG_QUEUE, @@ -280,15 +273,8 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, struct ath9k_tx_queue_info *qinfo) { struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath9k_tx_queue_info *qi; - if (q >= pCap->total_queues) { - 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_dbg(common, ATH_DBG_QUEUE, @@ -320,28 +306,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_tx_queue_info *qi; - struct ath9k_hw_capabilities *pCap = &ah->caps; int q; switch (type) { case ATH9K_TX_QUEUE_BEACON: - q = pCap->total_queues - 1; + q = ATH9K_NUM_TX_QUEUES - 1; break; case ATH9K_TX_QUEUE_CAB: - q = pCap->total_queues - 2; + q = ATH9K_NUM_TX_QUEUES - 2; break; case ATH9K_TX_QUEUE_PSPOLL: q = 1; break; case ATH9K_TX_QUEUE_UAPSD: - q = pCap->total_queues - 3; + q = ATH9K_NUM_TX_QUEUES - 3; break; case ATH9K_TX_QUEUE_DATA: - for (q = 0; q < pCap->total_queues; q++) + for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++) if (ah->txq[q].tqi_type == ATH9K_TX_QUEUE_INACTIVE) break; - if (q == pCap->total_queues) { + if (q == ATH9K_NUM_TX_QUEUES) { ath_err(common, "No available TX queue\n"); return -1; } @@ -382,15 +367,9 @@ EXPORT_SYMBOL(ath9k_hw_setuptxqueue); bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) { - struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_tx_queue_info *qi; - if (q >= pCap->total_queues) { - 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_dbg(common, ATH_DBG_QUEUE, @@ -414,18 +393,11 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue); bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) { - struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; struct ath9k_tx_queue_info *qi; u32 cwMin, chanCwMin, value; - if (q >= pCap->total_queues) { - 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_dbg(common, ATH_DBG_QUEUE, -- GitLab From 0db156e9648e69c34e8e88328358a26611fd71e3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:29 +0100 Subject: [PATCH 0165/5560] ath9k_hw: remove ah->config.ht_enable It is only used in one place, and the device id check that it's based on can be moved there as well. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 7 +------ drivers/net/wireless/ath/ath9k/hw.h | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index de0d218195da..625ad0bcdc1f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -378,11 +378,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.spurchans[i][1] = AR_NO_SPUR; } - if (ah->hw_version.devid != AR2427_DEVID_PCIE) - ah->config.ht_enable = 1; - else - ah->config.ht_enable = 0; - /* PAPRD needs some more work to be enabled */ ah->config.paprd_disable = 1; @@ -1880,7 +1875,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; - if (ah->config.ht_enable) + if (ah->hw_version.devid != AR2427_DEVID_PCIE) pCap->hw_caps |= ATH9K_HW_CAP_HT; else pCap->hw_caps &= ~ATH9K_HW_CAP_HT; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 4e62ad858d8a..7bbf7015af13 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -222,7 +222,6 @@ struct ath9k_ops_config { u8 pcie_clock_req; u32 pcie_waen; u8 analog_shiftreg; - u8 ht_enable; u8 paprd_disable; u32 ofdm_trig_low; u32 ofdm_trig_high; -- GitLab From c429bdcf8fe033f04830a960e07c13a01f631499 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:30 +0100 Subject: [PATCH 0166/5560] ath9k_hw: remove pCap->reg_cap It is not used anywhere and seems pointless Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 17 ----------------- drivers/net/wireless/ath/ath9k/hw.h | 1 - 2 files changed, 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 625ad0bcdc1f..be2257469ab5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1932,23 +1932,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; - if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) { - pCap->reg_cap = - AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | - AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | - AR_EEPROM_EEREGCAP_EN_KK_U2 | - AR_EEPROM_EEREGCAP_EN_KK_MIDBAND; - } else { - pCap->reg_cap = - AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | - AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN; - } - - /* Advertise midband for AR5416 with FCC midband set in eeprom */ - if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) && - AR_SREV_5416(ah)) - pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; - 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 7bbf7015af13..a255f9a0a698 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -200,7 +200,6 @@ struct ath9k_hw_capabilities { u8 max_txchains; u8 max_rxchains; u16 tx_triglevel_max; - u16 reg_cap; u8 num_gpio_pins; u8 rx_hp_qdepth; u8 rx_lp_qdepth; -- GitLab From 6de12a1bcef0145436e815d30a3d48b9fadb199d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:31 +0100 Subject: [PATCH 0167/5560] ath9k_hw: remove pCap->keycache_size Similar to the number of tx queue, the number of keycache entries depends on the chip and shouldn't be messed with based on EEPROM data. Remove this field and stick to using AR_KEYTABLE_SIZE Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 8 +------- drivers/net/wireless/ath/ath9k/hw.c | 6 ------ drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/init.c | 8 +------- 4 files changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index ca69e7ccfd80..8303b34bdc90 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -564,13 +564,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) int i = 0; /* Get the hardware key cache size. */ - common->keymax = priv->ah->caps.keycache_size; - if (common->keymax > ATH_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; - } + common->keymax = AR_KEYTABLE_SIZE; if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index be2257469ab5..5c676da73fee 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1880,12 +1880,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->hw_caps &= ~ATH9K_HW_CAP_HT; - if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES) - pCap->keycache_size = - 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES); - else - pCap->keycache_size = AR_KEYTABLE_SIZE; - if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; else diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a255f9a0a698..296e51b6135b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -191,7 +191,6 @@ enum ath9k_hw_caps { struct ath9k_hw_capabilities { u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ - u16 keycache_size; u16 low_5ghz_chan, high_5ghz_chan; u16 low_2ghz_chan, high_2ghz_chan; u16 rts_aggr_limit; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index db1b7553c684..1ac8318d82a3 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -407,13 +407,7 @@ void ath9k_init_crypto(struct ath_softc *sc) int i = 0; /* Get the hardware key cache size. */ - common->keymax = sc->sc_ah->caps.keycache_size; - if (common->keymax > ATH_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; - } + common->keymax = AR_KEYTABLE_SIZE; /* * Reset the key cache since some parts do not -- GitLab From 340d0ea774d4ff0038a068e14340b59c5a1fce2c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:32 +0100 Subject: [PATCH 0168/5560] ath9k_hw: remove ATH9K_HW_CAP_ENHANCEDPM It is not used anywhere Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 -- drivers/net/wireless/ath/ath9k/hw.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5c676da73fee..a2509dc5e87e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1903,8 +1903,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->rts_aggr_limit = (8 * 1024); } - pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM; - #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); if (ah->rfsilent & EEP_RFSILENT_ENABLED) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 296e51b6135b..a0243b810a04 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -174,7 +174,6 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_HT = BIT(0), ATH9K_HW_CAP_RFSILENT = BIT(1), ATH9K_HW_CAP_CST = BIT(2), - ATH9K_HW_CAP_ENHANCEDPM = BIT(3), ATH9K_HW_CAP_AUTOSLEEP = BIT(4), ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5), ATH9K_HW_CAP_EDMA = BIT(6), -- GitLab From 83860c594f65945b1a2c99e84338e1145cd34890 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 23 Mar 2011 20:57:33 +0100 Subject: [PATCH 0169/5560] ath9k_hw: remove pCap->tx_triglevel_max It has the same purpose (and value) as ah->config.max_txtrig_level Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 ----- drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index a2509dc5e87e..298f4d6cbdbd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1880,11 +1880,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->hw_caps &= ~ATH9K_HW_CAP_HT; - if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) - pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; - else - pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; - if (AR_SREV_9271(ah)) pCap->num_gpio_pins = AR9271_NUM_GPIO; else if (AR_DEVID_7010(ah)) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a0243b810a04..4cc320bdf0aa 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -197,7 +197,6 @@ struct ath9k_hw_capabilities { u8 rx_chainmask; u8 max_txchains; u8 max_rxchains; - u16 tx_triglevel_max; u8 num_gpio_pins; u8 rx_hp_qdepth; u8 rx_lp_qdepth; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f916f088b553..5943bdc4c8f9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1980,7 +1980,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, 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) + ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level) tx_info->status.rates[tx_rateindex].count = hw->max_rate_tries; } -- GitLab From fbda18245beff52ec1edf096e7a77d4cdf3effb9 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 28 Mar 2011 11:39:14 +0100 Subject: [PATCH 0170/5560] ASoC: soc-cache: Fix indentation issues Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 1210a6f70a90..22c0b95fb007 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -93,13 +93,13 @@ static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg) } static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, - unsigned int reg) + unsigned int reg) { return do_hw_read(codec, reg); } static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) + unsigned int value) { u8 data[2]; @@ -111,7 +111,7 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, #if defined(CONFIG_SPI_MASTER) static int snd_soc_4_12_spi_write(void *control_data, const char *data, - int len) + int len) { u8 msg[2]; @@ -209,7 +209,7 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, #if defined(CONFIG_SPI_MASTER) static int snd_soc_8_16_spi_write(void *control_data, const char *data, - int len) + int len) { u8 msg[3]; @@ -257,7 +257,7 @@ static unsigned int do_i2c_read(struct snd_soc_codec *codec, #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, - unsigned int r) + unsigned int r) { u8 reg = r; u8 data; @@ -307,13 +307,13 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, #endif static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, - unsigned int reg) + unsigned int reg) { return do_hw_read(codec, reg); } static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) + unsigned int value) { u8 data[3]; @@ -327,7 +327,7 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, #if defined(CONFIG_SPI_MASTER) static int snd_soc_16_8_spi_write(void *control_data, const char *data, - int len) + int len) { u8 msg[3]; @@ -379,7 +379,7 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, #if defined(CONFIG_SPI_MASTER) static int snd_soc_16_16_spi_write(void *control_data, const char *data, - int len) + int len) { u8 msg[4]; -- GitLab From f20eda5d8fafe35ca3c63ec8149a700a7db228a5 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 28 Mar 2011 11:39:15 +0100 Subject: [PATCH 0171/5560] ASoC: soc-cache: Warn on syncing any non-writable registers When syncing the cache, if the driver has given us a writable_register() callback, use it to check if we are syncing a non-writable register and if so warn the user. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 22c0b95fb007..22b099076223 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -661,6 +661,8 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); if (rbnode->value == rbnode->defval) continue; + WARN_ON(codec->writable_register && + codec->writable_register(codec, rbnode->reg)); ret = snd_soc_cache_read(codec, rbnode->reg, &val); if (ret) return ret; @@ -921,6 +923,8 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) lzo_blocks = codec->reg_cache; for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { + WARN_ON(codec->writable_register && + codec->writable_register(codec, i)); ret = snd_soc_cache_read(codec, i, &val); if (ret) return ret; @@ -1179,6 +1183,8 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) codec_drv = codec->driver; for (i = 0; i < codec_drv->reg_cache_size; ++i) { + WARN_ON(codec->writable_register && + codec->writable_register(codec, i)); ret = snd_soc_cache_read(codec, i, &val); if (ret) return ret; -- GitLab From fc3b9230cc2cdbcbef37953fe8cf5af0977e7a95 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:08 +0800 Subject: [PATCH 0172/5560] ASoC: Use data based init for ak4671 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ak4671.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 2ec75abfa3e9..88b29f8c748b 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -352,7 +352,7 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route ak4671_intercon[] = { {"DAC Left", "NULL", "PMPLL"}, {"DAC Right", "NULL", "PMPLL"}, {"ADC Left", "NULL", "PMPLL"}, @@ -433,17 +433,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"}, }; -static int ak4671_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets, - ARRAY_SIZE(ak4671_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - static int ak4671_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -650,7 +639,6 @@ static int ak4671_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ak4671_snd_controls, ARRAY_SIZE(ak4671_snd_controls)); - ak4671_add_widgets(codec); ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -670,6 +658,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { .reg_cache_size = AK4671_CACHEREGNUM, .reg_word_size = sizeof(u8), .reg_cache_default = ak4671_reg, + .dapm_widgets = ak4671_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets), + .dapm_routes = ak4671_intercon, + .num_dapm_routes = ARRAY_SIZE(ak4671_intercon), }; static int __devinit ak4671_i2c_probe(struct i2c_client *client, -- GitLab From 51fb1a8704f6bccfcf5248f9edc2751c272fbdf2 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:09 +0800 Subject: [PATCH 0173/5560] ASoC: Use data based init for cx20442 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/cx20442.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 0bb424af956f..d68ea532cc7f 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -86,18 +86,6 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = { {"ADC", NULL, "Input Mixer"}, }; -static int cx20442_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets, - ARRAY_SIZE(cx20442_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, cx20442_audio_map, - ARRAY_SIZE(cx20442_audio_map)); - - return 0; -} - static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, unsigned int reg) { @@ -344,8 +332,6 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) return -ENOMEM; snd_soc_codec_set_drvdata(codec, cx20442); - cx20442_add_widgets(codec); - cx20442->control_data = NULL; codec->hw_write = NULL; codec->card->pop_time = 0; @@ -377,6 +363,10 @@ static struct snd_soc_codec_driver cx20442_codec_dev = { .reg_word_size = sizeof(u8), .read = cx20442_read_reg_cache, .write = cx20442_write, + .dapm_widgets = cx20442_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), + .dapm_routes = cx20442_audio_map, + .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map), }; static int cx20442_platform_probe(struct platform_device *pdev) -- GitLab From dc6fc49b141ed14256e1319ccb9797e9825f1734 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:10 +0800 Subject: [PATCH 0174/5560] ASoC: Use data based init for max98088 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/max98088.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index bd0517cb7980..bb58bdb49853 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1112,7 +1112,7 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = { SND_SOC_DAPM_INPUT("INB2"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route max98088_audio_map[] = { /* Left headphone output mixer */ {"Left HP Mixer", "Left DAC1 Switch", "DACL1"}, {"Left HP Mixer", "Left DAC2 Switch", "DACL2"}, @@ -1226,22 +1226,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"MIC2 Input", NULL, "MIC2"}, }; -static int max98088_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets, - ARRAY_SIZE(max98088_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - snd_soc_add_controls(codec, max98088_snd_controls, - ARRAY_SIZE(max98088_snd_controls)); - - snd_soc_dapm_new_widgets(dapm); - return 0; -} - /* codec mclk clock divider coefficients */ static const struct { u32 rate; @@ -2010,7 +1994,8 @@ static int max98088_probe(struct snd_soc_codec *codec) max98088_handle_pdata(codec); - max98088_add_widgets(codec); + snd_soc_add_controls(codec, max98088_snd_controls, + ARRAY_SIZE(max98088_snd_controls)); err_access: return ret; @@ -2036,6 +2021,10 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = { .reg_word_size = sizeof(u8), .reg_cache_default = max98088_reg, .volatile_register = max98088_volatile_register, + .dapm_widgets = max98088_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets), + .dapm_routes = max98088_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98088_audio_map), }; static int max98088_i2c_probe(struct i2c_client *i2c, -- GitLab From 7ad7dd125ae936719205672565ef48df018731c4 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:11 +0800 Subject: [PATCH 0175/5560] ASoC: Use data based init for wm9713 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 38ed98558718..7167cb6787db 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -487,7 +487,7 @@ SND_SOC_DAPM_INPUT("MIC2B"), SND_SOC_DAPM_VMID("VMID"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm9713_audio_map[] = { /* left HP mixer */ {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"}, {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, @@ -644,18 +644,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Capture Mono Mux", "Right", "Right Capture Source"}, }; -static int wm9713_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets, - ARRAY_SIZE(wm9713_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { @@ -1231,7 +1219,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm9713_snd_ac97_controls, ARRAY_SIZE(wm9713_snd_ac97_controls)); - wm9713_add_widgets(codec); return 0; @@ -1262,6 +1249,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9713_reg, + .dapm_widgets = wm9713_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets), + .dapm_routes = wm9713_audio_map, + .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map), }; static __devinit int wm9713_probe(struct platform_device *pdev) -- GitLab From 983347785bb3807c125e7c00f31790ed11c231fc Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:12 +0800 Subject: [PATCH 0176/5560] ASoC: Use data based init for wm9712 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index bf5d4ef1a2a6..90117f8156e8 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -332,7 +332,7 @@ SND_SOC_DAPM_INPUT("MIC1"), SND_SOC_DAPM_INPUT("MIC2"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm9712_audio_map[] = { /* virtual mixer - mixes left & right channels for spk and mono */ {"AC97 Mixer", NULL, "Left DAC"}, {"AC97 Mixer", NULL, "Right DAC"}, @@ -429,17 +429,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ROUT2", NULL, "Speaker PGA"}, }; -static int wm9712_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets, - ARRAY_SIZE(wm9712_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { @@ -651,7 +640,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); snd_soc_add_controls(codec, wm9712_snd_ac97_controls, ARRAY_SIZE(wm9712_snd_ac97_controls)); - wm9712_add_widgets(codec); return 0; @@ -678,6 +666,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9712_reg, + .dapm_widgets = wm9712_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets), + .dapm_routes = wm9712_audio_map, + .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map), }; static __devinit int wm9712_probe(struct platform_device *pdev) -- GitLab From 97a58d6e1ba74c6c3663b50960a521c54c2f3c90 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:13 +0800 Subject: [PATCH 0177/5560] ASoC: Use data based init for wm9705 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm9705.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 47b357adabdd..646b58dda849 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -142,7 +142,7 @@ static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = { * constantly enabled, we use the mutes on those inputs to simulate such * controls. */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm9705_audio_map[] = { /* HP mixer */ {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, {"HP Mixer", "CD Playback Switch", "CD PGA"}, @@ -200,17 +200,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Right ADC", NULL, "ADC PGA"}, }; -static int wm9705_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets, - ARRAY_SIZE(wm9705_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - /* We use a register cache to enhance read performance. */ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) { @@ -364,7 +353,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm9705_snd_ac97_controls, ARRAY_SIZE(wm9705_snd_ac97_controls)); - wm9705_add_widgets(codec); return 0; @@ -390,6 +378,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = { .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = wm9705_reg, + .dapm_widgets = wm9705_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets), + .dapm_routes = wm9705_audio_map, + .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map), }; static __devinit int wm9705_probe(struct platform_device *pdev) -- GitLab From 8428edf96ebb9e8c8a5bec257568101b6ba01dc3 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:14 +0800 Subject: [PATCH 0178/5560] ASoC: Use data based init for wm8728 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8728.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 736b0352d0a7..86d4718d3a76 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -65,22 +65,11 @@ SND_SOC_DAPM_OUTPUT("VOUTL"), SND_SOC_DAPM_OUTPUT("VOUTR"), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route wm8728_intercon[] = { {"VOUTL", NULL, "DAC"}, {"VOUTR", NULL, "DAC"}, }; -static int wm8728_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets, - ARRAY_SIZE(wm8728_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - static int wm8728_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; @@ -255,7 +244,6 @@ static int wm8728_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8728_snd_controls, ARRAY_SIZE(wm8728_snd_controls)); - wm8728_add_widgets(codec); return ret; } @@ -275,6 +263,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), .reg_word_size = sizeof(u16), .reg_cache_default = wm8728_reg_defaults, + .dapm_widgets = wm8728_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), + .dapm_routes = wm8728_intercon, + .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), }; #if defined(CONFIG_SPI_MASTER) -- GitLab From 203140006173ec1df42a05d8eb7051d82eb61c25 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:15 +0800 Subject: [PATCH 0179/5560] ASoC: Use data based init for wm8711 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8711.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 97c30382d3ff..a537e4af6ae7 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -77,7 +77,7 @@ SND_SOC_DAPM_OUTPUT("ROUT"), SND_SOC_DAPM_OUTPUT("RHPOUT"), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route wm8711_intercon[] = { /* output mixer */ {"Output Mixer", "Line Bypass Switch", "Line Input"}, {"Output Mixer", "HiFi Playback Switch", "DAC"}, @@ -89,17 +89,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"LOUT", NULL, "Output Mixer"}, }; -static int wm8711_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets, - ARRAY_SIZE(wm8711_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - struct _coeff_div { u32 mclk; u32 rate; @@ -398,7 +387,6 @@ static int wm8711_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8711_snd_controls, ARRAY_SIZE(wm8711_snd_controls)); - wm8711_add_widgets(codec); return ret; @@ -420,6 +408,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { .reg_cache_size = ARRAY_SIZE(wm8711_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8711_reg, + .dapm_widgets = wm8711_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), + .dapm_routes = wm8711_intercon, + .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), }; #if defined(CONFIG_SPI_MASTER) -- GitLab From a7dca707a73ca700124e04372fc91334d898e6a6 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:16 +0800 Subject: [PATCH 0180/5560] ASoC: Use data based init for tlv320aic23 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 54a30ef0ec8b..33bb52f3f683 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -212,7 +212,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { SND_SOC_DAPM_INPUT("MICIN"), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route tlv320aic23_intercon[] = { /* Output Mixer */ {"Output Mixer", "Line Bypass Switch", "Line Input"}, {"Output Mixer", "Playback Switch", "DAC"}, @@ -388,18 +388,6 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk, return 0; } -static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, - ARRAY_SIZE(tlv320aic23_dapm_widgets)); - /* set up audio path interconnects */ - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -676,7 +664,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, tlv320aic23_snd_controls, ARRAY_SIZE(tlv320aic23_snd_controls)); - tlv320aic23_add_widgets(codec); return 0; } @@ -698,6 +685,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { .read = tlv320aic23_read_reg_cache, .write = tlv320aic23_write, .set_bias_level = tlv320aic23_set_bias_level, + .dapm_widgets = tlv320aic23_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), + .dapm_routes = tlv320aic23_intercon, + .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon), }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -- GitLab From b63c963da21d05f40f20de0a586143922bfa19d9 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:07 +0800 Subject: [PATCH 0181/5560] ASoC: Use data based init for ak4535 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ak4535.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 8b38739c88f8..e1a214ee757f 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -230,7 +230,7 @@ static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AIN"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route ak4535_audio_map[] = { /*stereo mixer */ {"Stereo Mixer", "Playback Switch", "DAC"}, {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, @@ -287,17 +287,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Input Mixer", "Aux Capture Switch", "Aux In"}, }; -static int ak4535_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets, - ARRAY_SIZE(ak4535_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -457,8 +446,6 @@ static int ak4535_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ak4535_snd_controls, ARRAY_SIZE(ak4535_snd_controls)); - ak4535_add_widgets(codec); - return 0; } @@ -480,6 +467,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .reg_cache_size = ARRAY_SIZE(ak4535_reg), .reg_word_size = sizeof(u8), .reg_cache_default = ak4535_reg, + .dapm_widgets = ak4535_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), + .dapm_routes = ak4535_audio_map, + .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -- GitLab From e27808df97ff7b43b4927aadf410705f33313523 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 30 Mar 2011 21:53:17 +0800 Subject: [PATCH 0182/5560] ASoC: Use data based init for sn95031 DAPM Signed-off-by: Lu Guanqun Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/sn95031.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 2a30eae1881c..569555f4a92f 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -825,8 +825,6 @@ EXPORT_SYMBOL_GPL(sn95031_jack_detection); /* codec registration */ static int sn95031_codec_probe(struct snd_soc_codec *codec) { - int ret; - pr_debug("codec_probe called\n"); codec->dapm.bias_level = SND_SOC_BIAS_OFF; @@ -877,16 +875,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, sn95031_snd_controls, ARRAY_SIZE(sn95031_snd_controls)); - ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, - ARRAY_SIZE(sn95031_dapm_widgets)); - if (ret) - pr_err("soc_dapm_new_control failed %d", ret); - ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map, - ARRAY_SIZE(sn95031_audio_map)); - if (ret) - pr_err("soc_dapm_add_routes failed %d", ret); - - return ret; + return 0; } static int sn95031_codec_remove(struct snd_soc_codec *codec) @@ -903,6 +892,10 @@ struct snd_soc_codec_driver sn95031_codec = { .read = sn95031_read, .write = sn95031_write, .set_bias_level = sn95031_set_vaud_bias, + .dapm_widgets = sn95031_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), + .dapm_routes = sn95031_audio_map, + .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), }; static int __devinit sn95031_device_probe(struct platform_device *pdev) -- GitLab From 86ef925f45d384d7d255859da3962ae19b24e228 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 31 Mar 2011 00:19:19 +0200 Subject: [PATCH 0183/5560] MAINTAINERS: Add "K:" pattern for trivial Since scripts/get_maintainer.pl was updated to search content before the patch by commit 7764dcb ("get_maintainer.pl: allow "K:" pattern tests to match non-patch text") perhaps this might direct a few more patches the right place. Original-patch-by: L. Alberto Gim?nez Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Jiri Kosina --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index c7a41b1fe453..ed224e091a50 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6215,6 +6215,7 @@ TRIVIAL PATCHES M: Jiri Kosina T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git S: Maintained +K: ^Subject:.*(?i)trivial TTY LAYER M: Greg Kroah-Hartman -- GitLab From cfc64fd91fabed099a4c3df58559f4b7efe9bcce Mon Sep 17 00:00:00 2001 From: Xiaochen Wang Date: Thu, 31 Mar 2011 00:27:32 +0900 Subject: [PATCH 0184/5560] tomoyo: fix memory leak in tomoyo_commit_ok() When memory used for policy exceeds the quota, tomoyo_memory_ok() return false. In this case, tomoyo_commit_ok() must call kfree() before returning NULL. This bug exists since 2.6.35. Signed-off-by: Xiaochen Wang Acked-by: Tetsuo Handa Signed-off-by: James Morris --- security/tomoyo/memory.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c index 297612669c74..42a7b1ba8cbf 100644 --- a/security/tomoyo/memory.c +++ b/security/tomoyo/memory.c @@ -75,6 +75,7 @@ void *tomoyo_commit_ok(void *data, const unsigned int size) memset(data, 0, size); return ptr; } + kfree(ptr); return NULL; } -- GitLab From 36a0e6c2d6f3eb59b7a5ddfda63d252a42dba189 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Mon, 21 Mar 2011 01:50:30 +0000 Subject: [PATCH 0185/5560] net/r8169: add a new chip for RTL8105 Add a new chip for RTL8105 whose settings are the same with RTL_GIGA_MAC_VER_30. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/r8169.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 493b0de3848b..0111a143c992 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1574,6 +1574,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, /* 8101 family. */ + { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40900000, RTL_GIGA_MAC_VER_29 }, { 0x7c800000, 0x40800000, RTL_GIGA_MAC_VER_30 }, -- GitLab From 4804b3b3aec163b59328140d6c858c3ed1c85992 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Mon, 21 Mar 2011 01:50:29 +0000 Subject: [PATCH 0186/5560] net/r8169: add a new chip for RTL8168DP Add a new chip for RTL8168DP. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/r8169.c | 98 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0111a143c992..5c480750d8fb 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -127,6 +127,7 @@ enum mac_version { RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E + RTL_GIGA_MAC_VER_31 = 0x1f, // 8168DP }; #define _R(NAME,MAC,MASK) \ @@ -166,7 +167,8 @@ static const struct { _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E - _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880) // PCI-E + _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880), // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, 0xff7e1880) // PCI-E }; #undef _R @@ -651,12 +653,18 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) static void rtl8168_driver_start(struct rtl8169_private *tp) { int i; + u32 reg; rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START); + if (tp->mac_version == RTL_GIGA_MAC_VER_31) + reg = 0xb8; + else + reg = 0x10; + for (i = 0; i < 10; i++) { msleep(10); - if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800) + if (ocp_read(tp, 0x0f, reg) & 0x00000800) break; } } @@ -664,16 +672,36 @@ static void rtl8168_driver_start(struct rtl8169_private *tp) static void rtl8168_driver_stop(struct rtl8169_private *tp) { int i; + u32 reg; rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP); + if (tp->mac_version == RTL_GIGA_MAC_VER_31) + reg = 0xb8; + else + reg = 0x10; + for (i = 0; i < 10; i++) { msleep(10); - if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0) + if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0) break; } } +static int r8168dp_check_dash(struct rtl8169_private *tp) +{ + u32 reg; + + if (tp->mac_version == RTL_GIGA_MAC_VER_31) + reg = 0xb8; + else + reg = 0x10; + + if (ocp_read(tp, 0xF, reg) & 0x00008000) + return 1; + else + return 0; +} static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) { @@ -1555,6 +1583,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, /* 8168DP family. */ { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 }, { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 }, + { 0x7cf00000, 0x28b00000, RTL_GIGA_MAC_VER_31 }, /* 8168C family. */ { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 }, @@ -2860,6 +2889,7 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) ops->read = r8168dp_1_mdio_read; break; case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: ops->write = r8168dp_2_mdio_write; ops->read = r8168dp_2_mdio_read; break; @@ -2917,8 +2947,9 @@ 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) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) && - (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { + (tp->mac_version == RTL_GIGA_MAC_VER_28) || + (tp->mac_version == RTL_GIGA_MAC_VER_31)) && + r8168dp_check_dash(tp)) { return; } @@ -2944,6 +2975,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; } @@ -2954,8 +2986,9 @@ 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) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) && - (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { + (tp->mac_version == RTL_GIGA_MAC_VER_28) || + (tp->mac_version == RTL_GIGA_MAC_VER_31)) && + r8168dp_check_dash(tp)) { return; } @@ -2964,6 +2997,7 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; } @@ -3018,6 +3052,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -3250,7 +3285,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) { + (tp->mac_version == RTL_GIGA_MAC_VER_28) || + (tp->mac_version == RTL_GIGA_MAC_VER_31)) { rtl8168_driver_start(tp); } @@ -3283,7 +3319,8 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) struct rtl8169_private *tp = netdev_priv(dev); if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || - (tp->mac_version == RTL_GIGA_MAC_VER_28)) { + (tp->mac_version == RTL_GIGA_MAC_VER_28) || + (tp->mac_version == RTL_GIGA_MAC_VER_31)) { rtl8168_driver_stop(tp); } @@ -3383,7 +3420,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) rtl8169_irq_mask_and_ack(ioaddr); if (tp->mac_version == RTL_GIGA_MAC_VER_27 || - tp->mac_version == RTL_GIGA_MAC_VER_28) { + tp->mac_version == RTL_GIGA_MAC_VER_28 || + tp->mac_version == RTL_GIGA_MAC_VER_31) { while (RTL_R8(TxPoll) & NPQ) udelay(20); @@ -3780,6 +3818,17 @@ 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_8168dp(void __iomem *ioaddr, struct pci_dev *pdev) +{ + rtl_csi_access_enable_1(ioaddr); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + RTL_W8(MaxTxPacketSize, TxPacketMax); + + rtl_disable_clock_request(pdev); +} + static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) { static const struct ephy_info e_info_8168d_4[] = { @@ -3843,55 +3892,59 @@ static void rtl_hw_start_8168(struct net_device *dev) switch (tp->mac_version) { case RTL_GIGA_MAC_VER_11: rtl_hw_start_8168bb(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_17: rtl_hw_start_8168bef(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_18: rtl_hw_start_8168cp_1(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_19: rtl_hw_start_8168c_1(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_20: rtl_hw_start_8168c_2(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_21: rtl_hw_start_8168c_3(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_22: rtl_hw_start_8168c_4(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_23: rtl_hw_start_8168cp_2(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_24: rtl_hw_start_8168cp_3(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_25: case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_27: rtl_hw_start_8168d(ioaddr, pdev); - break; + break; case RTL_GIGA_MAC_VER_28: rtl_hw_start_8168d_4(ioaddr, pdev); - break; + break; + case RTL_GIGA_MAC_VER_31: + rtl_hw_start_8168dp(ioaddr, pdev); + break; + default: printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", dev->name, tp->mac_version); - break; + break; } RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -4756,6 +4809,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) case RTL_GIGA_MAC_VER_24: case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: /* Experimental science. Pktgen proof. */ case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_25: -- GitLab From 01dc7fec4025f6bb72b6b98ec88b375346b6dbbb Mon Sep 17 00:00:00 2001 From: hayeswang Date: Mon, 21 Mar 2011 01:50:28 +0000 Subject: [PATCH 0187/5560] net/r8169: support RTL8168E Support RTL8168E/RTL8111E. Signed-off-by: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/r8169.c | 212 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 207 insertions(+), 5 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 5c480750d8fb..caa99cdb5818 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -37,6 +37,8 @@ #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" +#define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw" +#define FIRMWARE_8168E_2 "rtl_nic/rtl8168e-2.fw" #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #ifdef RTL8169_DEBUG @@ -128,6 +130,8 @@ enum mac_version { RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E RTL_GIGA_MAC_VER_31 = 0x1f, // 8168DP + RTL_GIGA_MAC_VER_32 = 0x20, // 8168E + RTL_GIGA_MAC_VER_33 = 0x21, // 8168E }; #define _R(NAME,MAC,MASK) \ @@ -168,7 +172,9 @@ static const struct { _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880), // PCI-E - _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, 0xff7e1880) // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, 0xff7e1880), // PCI-E + _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_32, 0xff7e1880), // PCI-E + _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_33, 0xff7e1880) // PCI-E }; #undef _R @@ -317,7 +323,9 @@ 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 */ + RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ + MISC = 0xf0, /* 8168e only. */ + txpla_rst = (1 << 29) }; enum rtl_register_content { @@ -395,6 +403,7 @@ enum rtl_register_content { BWF = (1 << 6), /* Accept Broadcast wakeup frame */ MWF = (1 << 5), /* Accept Multicast wakeup frame */ UWF = (1 << 4), /* Accept Unicast wakeup frame */ + spi_en = (1 << 3), LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ @@ -579,6 +588,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); MODULE_FIRMWARE(FIRMWARE_8168D_1); MODULE_FIRMWARE(FIRMWARE_8168D_2); +MODULE_FIRMWARE(FIRMWARE_8168E_1); +MODULE_FIRMWARE(FIRMWARE_8168E_2); MODULE_FIRMWARE(FIRMWARE_8105E_1); static int rtl8169_open(struct net_device *dev); @@ -1575,6 +1586,11 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, u32 val; int mac_version; } mac_info[] = { + /* 8168E family. */ + { 0x7cf00000, 0x2c200000, RTL_GIGA_MAC_VER_33 }, + { 0x7cf00000, 0x2c100000, RTL_GIGA_MAC_VER_32 }, + { 0x7c800000, 0x2c000000, RTL_GIGA_MAC_VER_33 }, + /* 8168D family. */ { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 }, { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 }, @@ -2466,6 +2482,93 @@ static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp) rtl_patchphy(tp, 0x0d, 1 << 5); } +static void rtl8168e_hw_phy_config(struct rtl8169_private *tp) +{ + static const struct phy_reg phy_reg_init[] = { + /* Enable Delay cap */ + { 0x1f, 0x0005 }, + { 0x05, 0x8b80 }, + { 0x06, 0xc896 }, + { 0x1f, 0x0000 }, + + /* Channel estimation fine tune */ + { 0x1f, 0x0001 }, + { 0x0b, 0x6c20 }, + { 0x07, 0x2872 }, + { 0x1c, 0xefff }, + { 0x1f, 0x0003 }, + { 0x14, 0x6420 }, + { 0x1f, 0x0000 }, + + /* Update PFM & 10M TX idle timer */ + { 0x1f, 0x0007 }, + { 0x1e, 0x002f }, + { 0x15, 0x1919 }, + { 0x1f, 0x0000 }, + + { 0x1f, 0x0007 }, + { 0x1e, 0x00ac }, + { 0x18, 0x0006 }, + { 0x1f, 0x0000 } + }; + + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + /* DCO enable for 10M IDLE Power */ + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x0023); + rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + /* For impedance matching */ + rtl_writephy(tp, 0x1f, 0x0002); + rtl_w1w0_phy(tp, 0x08, 0x8000, 0x7f00); + rtl_writephy(tp, 0x1F, 0x0000); + + /* PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x002d); + rtl_w1w0_phy(tp, 0x18, 0x0050, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000); + + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b86); + rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000); + rtl_writephy(tp, 0x1f, 0x0000); + + rtl_writephy(tp, 0x1f, 0x0005); + rtl_writephy(tp, 0x05, 0x8b85); + rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); + rtl_writephy(tp, 0x1f, 0x0007); + rtl_writephy(tp, 0x1e, 0x0020); + rtl_w1w0_phy(tp, 0x15, 0x0000, 0x1100); + rtl_writephy(tp, 0x1f, 0x0006); + rtl_writephy(tp, 0x00, 0x5a00); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x0d, 0x0007); + rtl_writephy(tp, 0x0e, 0x003c); + rtl_writephy(tp, 0x0d, 0x4007); + rtl_writephy(tp, 0x0e, 0x0000); + rtl_writephy(tp, 0x0d, 0x0000); +} + +static void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp) +{ + if (rtl_apply_firmware(tp, FIRMWARE_8168E_1) < 0) + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + + rtl8168e_hw_phy_config(tp); +} + +static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) +{ + if (rtl_apply_firmware(tp, FIRMWARE_8168E_2) < 0) + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + + rtl8168e_hw_phy_config(tp); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -2581,6 +2684,12 @@ static void rtl_hw_phy_config(struct net_device *dev) case RTL_GIGA_MAC_VER_30: rtl8105e_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_32: + rtl8168e_1_hw_phy_config(tp); + break; + case RTL_GIGA_MAC_VER_33: + rtl8168e_2_hw_phy_config(tp); + break; default: break; @@ -2931,15 +3040,59 @@ static void r810x_pll_power_up(struct rtl8169_private *tp) static void r8168_phy_power_up(struct rtl8169_private *tp) { rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, 0x0e, 0x0000); + switch (tp->mac_version) { + 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: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + rtl_writephy(tp, 0x0e, 0x0000); + break; + default: + break; + } 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); + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); + 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: + case RTL_GIGA_MAC_VER_28: + case RTL_GIGA_MAC_VER_31: + rtl_writephy(tp, 0x0e, 0x0200); + default: + rtl_writephy(tp, MII_BMCR, BMCR_PDOWN); + break; + } } static void r8168_pll_power_down(struct rtl8169_private *tp) @@ -2959,6 +3112,10 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) return; } + if (tp->mac_version == RTL_GIGA_MAC_VER_32 || + tp->mac_version == RTL_GIGA_MAC_VER_33) + rtl_ephy_write(ioaddr, 0x19, 0xff64); + if (__rtl8169_get_wol(tp) & WAKE_ANY) { rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, MII_BMCR, 0x0000); @@ -2976,6 +3133,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; } @@ -2998,6 +3157,8 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; } @@ -3053,6 +3214,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_27: case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -3855,6 +4018,41 @@ static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) rtl_enable_clock_request(pdev); } +static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev) +{ + static const struct ephy_info e_info_8168e[] = { + { 0x00, 0x0200, 0x0100 }, + { 0x00, 0x0000, 0x0004 }, + { 0x06, 0x0002, 0x0001 }, + { 0x06, 0x0000, 0x0030 }, + { 0x07, 0x0000, 0x2000 }, + { 0x00, 0x0000, 0x0020 }, + { 0x03, 0x5800, 0x2000 }, + { 0x03, 0x0000, 0x0001 }, + { 0x01, 0x0800, 0x1000 }, + { 0x07, 0x0000, 0x4000 }, + { 0x1e, 0x0000, 0x2000 }, + { 0x19, 0xffff, 0xfe6c }, + { 0x0a, 0x0000, 0x0040 } + }; + + rtl_csi_access_enable_2(ioaddr); + + rtl_ephy_init(ioaddr, e_info_8168e, ARRAY_SIZE(e_info_8168e)); + + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + + RTL_W8(MaxTxPacketSize, TxPacketMax); + + rtl_disable_clock_request(pdev); + + /* Reset tx FIFO pointer */ + RTL_W32(MISC, RTL_R32(MISC) | txpla_rst); + RTL_W32(MISC, RTL_R32(MISC) & ~txpla_rst); + + RTL_W8(Config5, RTL_R8(Config5) & ~spi_en); +} + static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3940,6 +4138,10 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_hw_start_8168dp(ioaddr, pdev); break; + case RTL_GIGA_MAC_VER_32: + case RTL_GIGA_MAC_VER_33: + rtl_hw_start_8168e(ioaddr, pdev); + break; default: printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", -- GitLab From 311fddc7569d7a3340d61de262cff11685060f74 Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Wed, 16 Mar 2011 21:22:43 +0000 Subject: [PATCH 0188/5560] be2net: Support for FAT dump retrieval using ethtool --register-dump option Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 107 +++++++++++++++++++++++++++++++++ drivers/net/benet/be_cmds.h | 21 +++++++ drivers/net/benet/be_ethtool.c | 21 +++++++ drivers/net/benet/be_hw.h | 4 ++ 4 files changed, 153 insertions(+) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 5a4a87e7c5ea..2aadf88eaa0a 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1186,6 +1186,113 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter) return status; } +/* Uses synchronous mcc */ +int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_fat *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_COMMON_MANAGE_FAT); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_MANAGE_FAT, sizeof(*req)); + req->fat_operation = cpu_to_le32(QUERY_FAT); + status = be_mcc_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_get_fat *resp = embedded_payload(wrb); + if (log_size && resp->log_size) + *log_size = le32_to_cpu(resp->log_size - + sizeof(u32)); + } +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + +void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf) +{ + struct be_dma_mem get_fat_cmd; + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_fat *req; + struct be_sge *sge; + u32 offset = 0, total_size, buf_size, log_offset = sizeof(u32); + int status; + + if (buf_len == 0) + return; + + total_size = buf_len; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + while (total_size) { + buf_size = min(total_size, (u32)60*1024); + total_size -= buf_size; + + get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + buf_size; + get_fat_cmd.va = pci_alloc_consistent(adapter->pdev, + get_fat_cmd.size, + &get_fat_cmd.dma); + if (!get_fat_cmd.va) { + status = -ENOMEM; + dev_err(&adapter->pdev->dev, + "Memory allocation failure while retrieving FAT data\n"); + goto err; + } + req = get_fat_cmd.va; + sge = nonembedded_sgl(wrb); + + be_wrb_hdr_prepare(wrb, get_fat_cmd.size, false, 1, + OPCODE_COMMON_MANAGE_FAT); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_MANAGE_FAT, get_fat_cmd.size); + + sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.size)); + sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF); + sge->len = cpu_to_le32(get_fat_cmd.size); + + req->fat_operation = cpu_to_le32(RETRIEVE_FAT); + req->read_log_offset = cpu_to_le32(log_offset); + req->read_log_length = cpu_to_le32(buf_size); + req->data_buffer_size = cpu_to_le32(buf_size); + + status = be_mcc_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_get_fat *resp = get_fat_cmd.va; + memcpy(buf + offset, + resp->data_buffer, + resp->read_log_length); + } + pci_free_consistent(adapter->pdev, get_fat_cmd.size, + get_fat_cmd.va, + get_fat_cmd.dma); + if (status) + dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n"); + + offset += buf_size; + log_offset += buf_size; + } +err: + spin_unlock_bh(&adapter->mcc_lock); +} + /* Uses Mbox */ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) { diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 4f254cfaabe2..3fb6e0a3ad7a 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -186,6 +186,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_NTWK_PMAC_ADD 59 #define OPCODE_COMMON_NTWK_PMAC_DEL 60 #define OPCODE_COMMON_FUNCTION_RESET 61 +#define OPCODE_COMMON_MANAGE_FAT 68 #define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 #define OPCODE_COMMON_GET_BEACON_STATE 70 #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 @@ -380,6 +381,24 @@ struct be_cmd_resp_cq_create { u16 rsvd0; } __packed; +struct be_cmd_req_get_fat { + struct be_cmd_req_hdr hdr; + u32 fat_operation; + u32 read_log_offset; + u32 read_log_length; + u32 data_buffer_size; + u32 data_buffer[1]; +} __packed; + +struct be_cmd_resp_get_fat { + struct be_cmd_resp_hdr hdr; + u32 log_size; + u32 read_log_length; + u32 rsvd[2]; + u32 data_buffer[1]; +} __packed; + + /******************** 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 */ @@ -1148,4 +1167,6 @@ extern void be_detect_dump_ue(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); extern int be_cmd_check_native_mode(struct be_adapter *adapter); +extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); +extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index aac248fbd18b..575ac659ceb4 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -155,6 +155,25 @@ be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) drvinfo->eedump_len = 0; } +static int +be_get_reg_len(struct net_device *netdev) +{ + struct be_adapter *adapter = netdev_priv(netdev); + u32 log_size = 0; + + be_cmd_get_reg_len(adapter, &log_size); + return log_size; +} + +static void +be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf) +{ + struct be_adapter *adapter = netdev_priv(netdev); + + memset(buf, 0, regs->len); + be_cmd_get_regs(adapter, regs->len, buf); +} + static int be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) { @@ -737,6 +756,8 @@ const struct ethtool_ops be_ethtool_ops = { .phys_id = be_phys_id, .get_sset_count = be_get_sset_count, .get_ethtool_stats = be_get_ethtool_stats, + .get_regs_len = be_get_reg_len, + .get_regs = be_get_regs, .flash_device = be_do_flash, .self_test = be_self_test, }; diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index d4344a06090b..53d658afea2a 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -155,6 +155,10 @@ /********** SRIOV VF PCICFG OFFSET ********/ #define SRIOV_VF_PCICFG_OFFSET (4096) +/********** FAT TABLE ********/ +#define RETRIEVE_FAT 0 +#define QUERY_FAT 1 + /* Flashrom related descriptors */ #define IMAGE_TYPE_FIRMWARE 160 #define IMAGE_TYPE_BOOTCODE 224 -- GitLab From ac6a0c4aab16070d7d55f49a52de33f716ae1d3d Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 21 Mar 2011 20:49:25 +0000 Subject: [PATCH 0189/5560] be2net: refactor code that decides adapter->num_rx_queues The code has been refactored to not set num_rx_qs inside be_enable_msix(). num_rx_qs is now set at the time of queue creation based on the number of available msix vectors. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 8 +++-- drivers/net/benet/be_main.c | 66 +++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index f803c58b941d..3937bca3d431 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -84,7 +84,8 @@ static inline char *nic_name(struct pci_dev *pdev) #define MCC_CQ_LEN 256 #define MAX_RSS_QS 4 /* BE limit is 4 queues/port */ -#define BE_MAX_MSIX_VECTORS (MAX_RSS_QS + 1 + 1)/* RSS qs + 1 def Rx + Tx */ +#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ +#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */ #define BE_NAPI_WEIGHT 64 #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) @@ -276,7 +277,7 @@ struct be_adapter { spinlock_t mcc_cq_lock; struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS]; - bool msix_enabled; + u32 num_msix_vec; bool isr_registered; /* TX Rings */ @@ -287,7 +288,7 @@ struct be_adapter { u32 cache_line_break[8]; /* Rx rings */ - struct be_rx_obj rx_obj[MAX_RSS_QS + 1]; /* one default non-rss Q */ + struct be_rx_obj rx_obj[MAX_RX_QS]; u32 num_rx_qs; u32 big_page_size; /* Compounded page size shared by rx wrbs */ @@ -351,6 +352,7 @@ struct be_adapter { extern const struct ethtool_ops be_ethtool_ops; +#define msix_enabled(adapter) (adapter->num_msix_vec > 0) #define tx_stats(adapter) (&adapter->tx_stats) #define rx_stats(rxo) (&rxo->stats) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a71163f1e34b..7a5d6a308051 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1567,12 +1567,31 @@ static void be_rx_queues_destroy(struct be_adapter *adapter) } } +static u32 be_num_rxqs_want(struct be_adapter *adapter) +{ + if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && + !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { + return 1 + MAX_RSS_QS; /* one default non-RSS queue */ + } else { + dev_warn(&adapter->pdev->dev, + "No support for multiple RX queues\n"); + return 1; + } +} + static int be_rx_queues_create(struct be_adapter *adapter) { struct be_queue_info *eq, *q, *cq; struct be_rx_obj *rxo; int rc, i; + adapter->num_rx_qs = min(be_num_rxqs_want(adapter), + msix_enabled(adapter) ? + adapter->num_msix_vec - 1 : 1); + if (adapter->num_rx_qs != MAX_RX_QS) + dev_warn(&adapter->pdev->dev, + "Can create only %d RX queues", adapter->num_rx_qs); + adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; for_all_rx_queues(adapter, rxo, i) { rxo->adapter = adapter; @@ -1878,51 +1897,35 @@ static void be_worker(struct work_struct *work) static void be_msix_disable(struct be_adapter *adapter) { - if (adapter->msix_enabled) { + if (msix_enabled(adapter)) { pci_disable_msix(adapter->pdev); - adapter->msix_enabled = false; - } -} - -static int be_num_rxqs_get(struct be_adapter *adapter) -{ - if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && - !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { - return 1 + MAX_RSS_QS; /* one default non-RSS queue */ - } else { - dev_warn(&adapter->pdev->dev, - "No support for multiple RX queues\n"); - return 1; + adapter->num_msix_vec = 0; } } static void be_msix_enable(struct be_adapter *adapter) { #define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */ - int i, status; + int i, status, num_vec; - adapter->num_rx_qs = be_num_rxqs_get(adapter); + num_vec = be_num_rxqs_want(adapter) + 1; - for (i = 0; i < (adapter->num_rx_qs + 1); i++) + for (i = 0; i < num_vec; i++) adapter->msix_entries[i].entry = i; - status = pci_enable_msix(adapter->pdev, adapter->msix_entries, - adapter->num_rx_qs + 1); + status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); if (status == 0) { goto done; } else if (status >= BE_MIN_MSIX_VECTORS) { + num_vec = status; if (pci_enable_msix(adapter->pdev, adapter->msix_entries, - status) == 0) { - adapter->num_rx_qs = status - 1; - dev_warn(&adapter->pdev->dev, - "Could alloc only %d MSIx vectors. " - "Using %d RX Qs\n", status, adapter->num_rx_qs); + num_vec) == 0) goto done; - } } return; done: - adapter->msix_enabled = true; + adapter->num_msix_vec = num_vec; + return; } static void be_sriov_enable(struct be_adapter *adapter) @@ -2003,8 +2006,7 @@ static int be_msix_register(struct be_adapter *adapter) err: dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n", status); - pci_disable_msix(adapter->pdev); - adapter->msix_enabled = false; + be_msix_disable(adapter); return status; } @@ -2013,7 +2015,7 @@ static int be_irq_register(struct be_adapter *adapter) struct net_device *netdev = adapter->netdev; int status; - if (adapter->msix_enabled) { + if (msix_enabled(adapter)) { status = be_msix_register(adapter); if (status == 0) goto done; @@ -2046,7 +2048,7 @@ static void be_irq_unregister(struct be_adapter *adapter) return; /* INTx */ - if (!adapter->msix_enabled) { + if (!msix_enabled(adapter)) { free_irq(netdev->irq, adapter); goto done; } @@ -2088,7 +2090,7 @@ static int be_close(struct net_device *netdev) be_cq_notify(adapter, rxo->cq.id, false, 0); } - if (adapter->msix_enabled) { + if (msix_enabled(adapter)) { vec = be_msix_vec_get(adapter, tx_eq); synchronize_irq(vec); @@ -2261,7 +2263,7 @@ static int be_setup(struct be_adapter *adapter) BE_IF_FLAGS_PASS_L3L4_ERRORS; en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; - if (be_multi_rxq(adapter)) { + if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { cap_flags |= BE_IF_FLAGS_RSS; en_flags |= BE_IF_FLAGS_RSS; } -- GitLab From 15d721847f56f32fe9fd43d34db1b32b13de78dc Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 21 Mar 2011 20:49:26 +0000 Subject: [PATCH 0190/5560] be2net: parse vid and vtm fields of rx-compl only if vlanf bit is set Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 7a5d6a308051..6616300f6070 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1101,8 +1101,12 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter, AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); rxcp->pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); - rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); - rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, compl); + if (rxcp->vlanf) { + rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, + compl); + rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, + compl); + } } static void be_parse_rx_compl_v0(struct be_adapter *adapter, @@ -1127,8 +1131,12 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter, AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); rxcp->pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); - rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); - rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, compl); + if (rxcp->vlanf) { + rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, + compl); + rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, + compl); + } } static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) @@ -1150,15 +1158,19 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) else be_parse_rx_compl_v0(adapter, compl, rxcp); - /* vlanf could be wrongly set in some cards. ignore if vtm is not set */ - if ((adapter->function_mode & 0x400) && !rxcp->vtm) - rxcp->vlanf = 0; + if (rxcp->vlanf) { + /* vlanf could be wrongly set in some cards. + * ignore if vtm is not set */ + if ((adapter->function_mode & 0x400) && !rxcp->vtm) + rxcp->vlanf = 0; - if (!lancer_chip(adapter)) - rxcp->vid = swab16(rxcp->vid); + if (!lancer_chip(adapter)) + rxcp->vid = swab16(rxcp->vid); - if ((adapter->pvid == rxcp->vid) && !adapter->vlan_tag[rxcp->vid]) - rxcp->vlanf = 0; + if ((adapter->pvid == rxcp->vid) && + !adapter->vlan_tag[rxcp->vid]) + rxcp->vlanf = 0; + } /* As the compl has been parsed, reset it; we wont touch it again */ compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0; -- GitLab From 16da8250df36547269d20a3d53daa11c79f59637 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 21 Mar 2011 20:49:27 +0000 Subject: [PATCH 0191/5560] be2net: remove redundant code in be_worker() Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 6616300f6070..3bf79d148c24 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1868,6 +1868,9 @@ static void be_worker(struct work_struct *work) struct be_rx_obj *rxo; int i; + if (!adapter->ue_detected && !lancer_chip(adapter)) + be_detect_dump_ue(adapter); + /* when interrupts are not yet enabled, just reap any pending * mcc completions */ if (!netif_running(adapter->netdev)) { @@ -1880,9 +1883,6 @@ static void be_worker(struct work_struct *work) be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl); } - if (!adapter->ue_detected && !lancer_chip(adapter)) - be_detect_dump_ue(adapter); - goto reschedule; } @@ -1900,8 +1900,6 @@ static void be_worker(struct work_struct *work) be_post_rx_frags(rxo, GFP_KERNEL); } } - if (!adapter->ue_detected && !lancer_chip(adapter)) - be_detect_dump_ue(adapter); reschedule: schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); -- GitLab From 0f4a682882171d81c9e3c33c1094b87a197c09fa Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 21 Mar 2011 20:49:28 +0000 Subject: [PATCH 0192/5560] be2net: cancel be_worker in be_shutdown() even when i/f is down As the be_worker() workqueue is scheduled in be_probe() it must be canceled unconditionally in be_shutdown(). Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 3bf79d148c24..86389133dd3c 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -3155,8 +3155,7 @@ static void be_shutdown(struct pci_dev *pdev) struct be_adapter *adapter = pci_get_drvdata(pdev); struct net_device *netdev = adapter->netdev; - if (netif_running(netdev)) - cancel_delayed_work_sync(&adapter->work); + cancel_delayed_work_sync(&adapter->work); netif_device_detach(netdev); -- GitLab From e8c37c80006c99a00aa70a783023d616c166a04b Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Mon, 21 Mar 2011 20:49:29 +0000 Subject: [PATCH 0193/5560] be2net: remove one useless line Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 86389133dd3c..a24fb45c0f71 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2330,7 +2330,6 @@ static int be_setup(struct be_adapter *adapter) return 0; - be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); tx_qs_destroy: -- GitLab From dffc6b2432ea89af24a36e8100b3eeea09db67e5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 25 Mar 2011 14:21:22 +0000 Subject: [PATCH 0194/5560] smsc911x: Use pr_fmt, netdev_, and netif_ Use the more common/verbose logging styles. Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Remove smsc911x prefixes from format strings. Rename SMSC_WARNING to SMSC_WARN. Remove DPRINTK macro. Use netif_ in SMSC_ macros. Convert NETIF_MSG_ uses to lower case. Add no_printk verification in non-debug uses. Add pdata to SMSC_ uses to avoid hidden variable uses. Convert printks to netdev_ as appropriate. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 292 ++++++++++++++++++++--------------------- drivers/net/smsc911x.h | 22 ++-- 2 files changed, 155 insertions(+), 159 deletions(-) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 1566259c1f27..8b501d53063f 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -29,6 +29,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -248,8 +250,8 @@ static int smsc911x_mac_complete(struct smsc911x_data *pdata) if (!(val & MAC_CSR_CMD_CSR_BUSY_)) return 0; } - SMSC_WARNING(HW, "Timed out waiting for MAC not BUSY. " - "MAC_CSR_CMD: 0x%08X", val); + SMSC_WARN(pdata, hw, "Timed out waiting for MAC not BUSY. " + "MAC_CSR_CMD: 0x%08X", val); return -EIO; } @@ -262,7 +264,7 @@ static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset) temp = smsc911x_reg_read(pdata, MAC_CSR_CMD); if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) { - SMSC_WARNING(HW, "MAC busy at entry"); + SMSC_WARN(pdata, hw, "MAC busy at entry"); return 0xFFFFFFFF; } @@ -277,7 +279,7 @@ static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset) if (likely(smsc911x_mac_complete(pdata) == 0)) return smsc911x_reg_read(pdata, MAC_CSR_DATA); - SMSC_WARNING(HW, "MAC busy after read"); + SMSC_WARN(pdata, hw, "MAC busy after read"); return 0xFFFFFFFF; } @@ -291,8 +293,8 @@ static void smsc911x_mac_write(struct smsc911x_data *pdata, temp = smsc911x_reg_read(pdata, MAC_CSR_CMD); if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) { - SMSC_WARNING(HW, - "smsc911x_mac_write failed, MAC busy at entry"); + SMSC_WARN(pdata, hw, + "smsc911x_mac_write failed, MAC busy at entry"); return; } @@ -310,8 +312,7 @@ static void smsc911x_mac_write(struct smsc911x_data *pdata, if (likely(smsc911x_mac_complete(pdata) == 0)) return; - SMSC_WARNING(HW, - "smsc911x_mac_write failed, MAC busy after write"); + SMSC_WARN(pdata, hw, "smsc911x_mac_write failed, MAC busy after write"); } /* Get a phy register */ @@ -326,8 +327,7 @@ static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx) /* Confirm MII not busy */ if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) { - SMSC_WARNING(HW, - "MII is busy in smsc911x_mii_read???"); + SMSC_WARN(pdata, hw, "MII is busy in smsc911x_mii_read???"); reg = -EIO; goto out; } @@ -343,7 +343,7 @@ static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx) goto out; } - SMSC_WARNING(HW, "Timed out waiting for MII read to finish"); + SMSC_WARN(pdata, hw, "Timed out waiting for MII read to finish"); reg = -EIO; out: @@ -364,8 +364,7 @@ static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int regidx, /* Confirm MII not busy */ if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) { - SMSC_WARNING(HW, - "MII is busy in smsc911x_mii_write???"); + SMSC_WARN(pdata, hw, "MII is busy in smsc911x_mii_write???"); reg = -EIO; goto out; } @@ -385,7 +384,7 @@ static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int regidx, goto out; } - SMSC_WARNING(HW, "Timed out waiting for MII write to finish"); + SMSC_WARN(pdata, hw, "Timed out waiting for MII write to finish"); reg = -EIO; out: @@ -426,18 +425,20 @@ static void smsc911x_phy_initialise_external(struct smsc911x_data *pdata) unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG); if (pdata->config.flags & SMSC911X_FORCE_INTERNAL_PHY) { - SMSC_TRACE(HW, "Forcing internal PHY"); + SMSC_TRACE(pdata, hw, "Forcing internal PHY"); pdata->using_extphy = 0; } else if (pdata->config.flags & SMSC911X_FORCE_EXTERNAL_PHY) { - SMSC_TRACE(HW, "Forcing external PHY"); + SMSC_TRACE(pdata, hw, "Forcing external PHY"); smsc911x_phy_enable_external(pdata); pdata->using_extphy = 1; } else if (hwcfg & HW_CFG_EXT_PHY_DET_) { - SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET set, using external PHY"); + SMSC_TRACE(pdata, hw, + "HW_CFG EXT_PHY_DET set, using external PHY"); smsc911x_phy_enable_external(pdata); pdata->using_extphy = 1; } else { - SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET clear, using internal PHY"); + SMSC_TRACE(pdata, hw, + "HW_CFG EXT_PHY_DET clear, using internal PHY"); pdata->using_extphy = 0; } } @@ -509,13 +510,13 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) } while ((i--) && (!status)); if (!status) { - SMSC_WARNING(HW, "Failed to transmit " - "during loopback test"); + SMSC_WARN(pdata, hw, + "Failed to transmit during loopback test"); continue; } if (status & TX_STS_ES_) { - SMSC_WARNING(HW, "Transmit encountered " - "errors during loopback test"); + SMSC_WARN(pdata, hw, + "Transmit encountered errors during loopback test"); continue; } @@ -527,13 +528,13 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) } while ((i--) && (!status)); if (!status) { - SMSC_WARNING(HW, - "Failed to receive during loopback test"); + SMSC_WARN(pdata, hw, + "Failed to receive during loopback test"); continue; } if (status & RX_STS_ES_) { - SMSC_WARNING(HW, "Receive encountered " - "errors during loopback test"); + SMSC_WARN(pdata, hw, + "Receive encountered errors during loopback test"); continue; } @@ -546,9 +547,9 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz); if (pktlength != (MIN_PACKET_SIZE + 4)) { - SMSC_WARNING(HW, "Unexpected packet size " - "during loop back test, size=%d, will retry", - pktlength); + SMSC_WARN(pdata, hw, "Unexpected packet size " + "during loop back test, size=%d, will retry", + pktlength); } else { unsigned int j; int mismatch = 0; @@ -560,12 +561,12 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) } } if (!mismatch) { - SMSC_TRACE(HW, "Successfully verified " + SMSC_TRACE(pdata, hw, "Successfully verified " "loopback packet"); return 0; } else { - SMSC_WARNING(HW, "Data mismatch " - "during loop back test, will retry"); + SMSC_WARN(pdata, hw, "Data mismatch " + "during loop back test, will retry"); } } } @@ -582,7 +583,7 @@ static int smsc911x_phy_reset(struct smsc911x_data *pdata) BUG_ON(!phy_dev); BUG_ON(!phy_dev->bus); - SMSC_TRACE(HW, "Performing PHY BCR Reset"); + SMSC_TRACE(pdata, hw, "Performing PHY BCR Reset"); smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, BMCR_RESET); do { msleep(1); @@ -591,7 +592,7 @@ static int smsc911x_phy_reset(struct smsc911x_data *pdata) } while ((i--) && (temp & BMCR_RESET)); if (temp & BMCR_RESET) { - SMSC_WARNING(HW, "PHY reset failed to complete."); + SMSC_WARN(pdata, hw, "PHY reset failed to complete"); return -EIO; } /* Extra delay required because the phy may not be completed with @@ -695,11 +696,11 @@ static void smsc911x_phy_update_flowcontrol(struct smsc911x_data *pdata) else afc &= ~0xF; - SMSC_TRACE(HW, "rx pause %s, tx pause %s", - (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), - (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); + SMSC_TRACE(pdata, hw, "rx pause %s, tx pause %s", + (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), + (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); } else { - SMSC_TRACE(HW, "half duplex"); + SMSC_TRACE(pdata, hw, "half duplex"); flow = 0; afc |= 0xF; } @@ -722,17 +723,17 @@ static void smsc911x_phy_adjust_link(struct net_device *dev) if (phy_dev->duplex != pdata->last_duplex) { unsigned int mac_cr; - SMSC_TRACE(HW, "duplex state has changed"); + SMSC_TRACE(pdata, hw, "duplex state has changed"); spin_lock_irqsave(&pdata->mac_lock, flags); mac_cr = smsc911x_mac_read(pdata, MAC_CR); if (phy_dev->duplex) { - SMSC_TRACE(HW, - "configuring for full duplex mode"); + SMSC_TRACE(pdata, hw, + "configuring for full duplex mode"); mac_cr |= MAC_CR_FDPX_; } else { - SMSC_TRACE(HW, - "configuring for half duplex mode"); + SMSC_TRACE(pdata, hw, + "configuring for half duplex mode"); mac_cr &= ~MAC_CR_FDPX_; } smsc911x_mac_write(pdata, MAC_CR, mac_cr); @@ -744,9 +745,9 @@ static void smsc911x_phy_adjust_link(struct net_device *dev) carrier = netif_carrier_ok(dev); if (carrier != pdata->last_carrier) { - SMSC_TRACE(HW, "carrier state has changed"); + SMSC_TRACE(pdata, hw, "carrier state has changed"); if (carrier) { - SMSC_TRACE(HW, "configuring for carrier OK"); + SMSC_TRACE(pdata, hw, "configuring for carrier OK"); if ((pdata->gpio_orig_setting & GPIO_CFG_LED1_EN_) && (!pdata->using_extphy)) { /* Restore original GPIO configuration */ @@ -755,7 +756,7 @@ static void smsc911x_phy_adjust_link(struct net_device *dev) pdata->gpio_setting); } } else { - SMSC_TRACE(HW, "configuring for no carrier"); + SMSC_TRACE(pdata, hw, "configuring for no carrier"); /* Check global setting that LED1 * usage is 10/100 indicator */ pdata->gpio_setting = smsc911x_reg_read(pdata, @@ -787,25 +788,25 @@ static int smsc911x_mii_probe(struct net_device *dev) /* find the first phy */ phydev = phy_find_first(pdata->mii_bus); if (!phydev) { - pr_err("%s: no PHY found\n", dev->name); + netdev_err(dev, "no PHY found\n"); return -ENODEV; } - SMSC_TRACE(PROBE, "PHY: addr %d, phy_id 0x%08X", - phydev->addr, phydev->phy_id); + SMSC_TRACE(pdata, probe, "PHY: addr %d, phy_id 0x%08X", + phydev->addr, phydev->phy_id); ret = phy_connect_direct(dev, phydev, &smsc911x_phy_adjust_link, 0, pdata->config.phy_interface); if (ret) { - pr_err("%s: Could not attach to PHY\n", dev->name); + netdev_err(dev, "Could not attach to PHY\n"); return ret; } - pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", - dev->name, phydev->drv->name, - dev_name(&phydev->dev), phydev->irq); + netdev_info(dev, + "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", + phydev->drv->name, dev_name(&phydev->dev), phydev->irq); /* mask with MAC supported features */ phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause | @@ -818,13 +819,13 @@ static int smsc911x_mii_probe(struct net_device *dev) #ifdef USE_PHY_WORK_AROUND if (smsc911x_phy_loopbacktest(dev) < 0) { - SMSC_WARNING(HW, "Failed Loop Back Test"); + SMSC_WARN(pdata, hw, "Failed Loop Back Test"); return -ENODEV; } - SMSC_TRACE(HW, "Passed Loop Back Test"); + SMSC_TRACE(pdata, hw, "Passed Loop Back Test"); #endif /* USE_PHY_WORK_AROUND */ - SMSC_TRACE(HW, "phy initialised successfully"); + SMSC_TRACE(pdata, hw, "phy initialised successfully"); return 0; } @@ -860,8 +861,8 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev, smsc911x_phy_initialise_external(pdata); break; default: - SMSC_TRACE(HW, "External PHY is not supported, " - "using internal PHY"); + SMSC_TRACE(pdata, hw, "External PHY is not supported, " + "using internal PHY"); pdata->using_extphy = 0; break; } @@ -872,12 +873,12 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev, } if (mdiobus_register(pdata->mii_bus)) { - SMSC_WARNING(PROBE, "Error registering mii bus"); + SMSC_WARN(pdata, probe, "Error registering mii bus"); goto err_out_free_bus_2; } if (smsc911x_mii_probe(dev) < 0) { - SMSC_WARNING(PROBE, "Error registering mii bus"); + SMSC_WARN(pdata, probe, "Error registering mii bus"); goto err_out_unregister_bus_3; } @@ -913,8 +914,7 @@ static void smsc911x_tx_update_txcounters(struct net_device *dev) * does not reference a hardware defined reserved bit * but rather a driver defined one. */ - SMSC_WARNING(HW, - "Packet tag reserved bit is high"); + SMSC_WARN(pdata, hw, "Packet tag reserved bit is high"); } else { if (unlikely(tx_stat & TX_STS_ES_)) { dev->stats.tx_errors++; @@ -977,8 +977,8 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) } while ((val & RX_DP_CTRL_RX_FFWD_) && --timeout); if (unlikely(timeout == 0)) - SMSC_WARNING(HW, "Timed out waiting for " - "RX FFWD to finish, RX_DP_CTRL: 0x%08X", val); + SMSC_WARN(pdata, hw, "Timed out waiting for " + "RX FFWD to finish, RX_DP_CTRL: 0x%08X", val); } else { unsigned int temp; while (pktwords--) @@ -1021,8 +1021,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) smsc911x_rx_counterrors(dev, rxstat); if (unlikely(rxstat & RX_STS_ES_)) { - SMSC_WARNING(RX_ERR, - "Discarding packet with error bit set"); + SMSC_WARN(pdata, rx_err, + "Discarding packet with error bit set"); /* Packet has an error, discard it and continue with * the next */ smsc911x_rx_fastforward(pdata, pktwords); @@ -1032,8 +1032,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); if (unlikely(!skb)) { - SMSC_WARNING(RX_ERR, - "Unable to allocate skb for rx packet"); + SMSC_WARN(pdata, rx_err, + "Unable to allocate skb for rx packet"); /* Drop the packet and stop this polling iteration */ smsc911x_rx_fastforward(pdata, pktwords); dev->stats.rx_dropped++; @@ -1083,8 +1083,8 @@ static void smsc911x_rx_multicast_update(struct smsc911x_data *pdata) smsc911x_mac_write(pdata, MAC_CR, mac_cr); smsc911x_mac_write(pdata, HASHH, pdata->hashhi); smsc911x_mac_write(pdata, HASHL, pdata->hashlo); - SMSC_TRACE(HW, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X", - mac_cr, pdata->hashhi, pdata->hashlo); + SMSC_TRACE(pdata, hw, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X", + mac_cr, pdata->hashhi, pdata->hashlo); } static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata) @@ -1102,7 +1102,7 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata) /* Check Rx has stopped */ if (smsc911x_mac_read(pdata, MAC_CR) & MAC_CR_RXEN_) - SMSC_WARNING(DRV, "Rx not stopped"); + SMSC_WARN(pdata, drv, "Rx not stopped"); /* Perform the update - safe to do now Rx has stopped */ smsc911x_rx_multicast_update(pdata); @@ -1131,7 +1131,7 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata) } while ((--timeout) && (temp & HW_CFG_SRST_)); if (unlikely(temp & HW_CFG_SRST_)) { - SMSC_WARNING(DRV, "Failed to complete reset"); + SMSC_WARN(pdata, drv, "Failed to complete reset"); return -EIO; } return 0; @@ -1160,18 +1160,18 @@ static int smsc911x_open(struct net_device *dev) /* if the phy is not yet registered, retry later*/ if (!pdata->phy_dev) { - SMSC_WARNING(HW, "phy_dev is NULL"); + SMSC_WARN(pdata, hw, "phy_dev is NULL"); return -EAGAIN; } if (!is_valid_ether_addr(dev->dev_addr)) { - SMSC_WARNING(HW, "dev_addr is not a valid MAC address"); + SMSC_WARN(pdata, hw, "dev_addr is not a valid MAC address"); return -EADDRNOTAVAIL; } /* Reset the LAN911x */ if (smsc911x_soft_reset(pdata)) { - SMSC_WARNING(HW, "soft reset failed"); + SMSC_WARN(pdata, hw, "soft reset failed"); return -EIO; } @@ -1191,8 +1191,8 @@ static int smsc911x_open(struct net_device *dev) } if (unlikely(timeout == 0)) - SMSC_WARNING(IFUP, - "Timed out waiting for EEPROM busy bit to clear"); + SMSC_WARN(pdata, ifup, + "Timed out waiting for EEPROM busy bit to clear"); smsc911x_reg_write(pdata, GPIO_CFG, 0x70070000); @@ -1210,22 +1210,22 @@ static int smsc911x_open(struct net_device *dev) intcfg = ((10 << 24) | INT_CFG_IRQ_EN_); if (pdata->config.irq_polarity) { - SMSC_TRACE(IFUP, "irq polarity: active high"); + SMSC_TRACE(pdata, ifup, "irq polarity: active high"); intcfg |= INT_CFG_IRQ_POL_; } else { - SMSC_TRACE(IFUP, "irq polarity: active low"); + SMSC_TRACE(pdata, ifup, "irq polarity: active low"); } if (pdata->config.irq_type) { - SMSC_TRACE(IFUP, "irq type: push-pull"); + SMSC_TRACE(pdata, ifup, "irq type: push-pull"); intcfg |= INT_CFG_IRQ_TYPE_; } else { - SMSC_TRACE(IFUP, "irq type: open drain"); + SMSC_TRACE(pdata, ifup, "irq type: open drain"); } smsc911x_reg_write(pdata, INT_CFG, intcfg); - SMSC_TRACE(IFUP, "Testing irq handler using IRQ %d", dev->irq); + SMSC_TRACE(pdata, ifup, "Testing irq handler using IRQ %d", dev->irq); pdata->software_irq_signal = 0; smp_wmb(); @@ -1241,14 +1241,15 @@ static int smsc911x_open(struct net_device *dev) } if (!pdata->software_irq_signal) { - dev_warn(&dev->dev, "ISR failed signaling test (IRQ %d)\n", - dev->irq); + netdev_warn(dev, "ISR failed signaling test (IRQ %d)\n", + dev->irq); return -ENODEV; } - SMSC_TRACE(IFUP, "IRQ handler passed test using IRQ %d", dev->irq); + SMSC_TRACE(pdata, ifup, "IRQ handler passed test using IRQ %d", + dev->irq); - dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n", - (unsigned long)pdata->ioaddr, dev->irq); + netdev_info(dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n", + (unsigned long)pdata->ioaddr, dev->irq); /* Reset the last known duplex and carrier */ pdata->last_duplex = -1; @@ -1313,7 +1314,7 @@ static int smsc911x_stop(struct net_device *dev) if (pdata->phy_dev) phy_stop(pdata->phy_dev); - SMSC_TRACE(IFDOWN, "Interface stopped"); + SMSC_TRACE(pdata, ifdown, "Interface stopped"); return 0; } @@ -1331,8 +1332,8 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_; if (unlikely(freespace < TX_FIFO_LOW_THRESHOLD)) - SMSC_WARNING(TX_ERR, - "Tx data fifo low, space available: %d", freespace); + SMSC_WARN(pdata, tx_err, + "Tx data fifo low, space available: %d", freespace); /* Word alignment adjustment */ tx_cmd_a = (u32)((ulong)skb->data & 0x03) << 16; @@ -1432,7 +1433,7 @@ static void smsc911x_set_multicast_list(struct net_device *dev) * receiving data */ if (!pdata->multicast_update_pending) { unsigned int temp; - SMSC_TRACE(HW, "scheduling mcast update"); + SMSC_TRACE(pdata, hw, "scheduling mcast update"); pdata->multicast_update_pending = 1; /* Request the hardware to stop, then perform the @@ -1474,7 +1475,7 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) { /* Called when there is a multicast update scheduled and * it is now safe to complete the update */ - SMSC_TRACE(INTR, "RX Stop interrupt"); + SMSC_TRACE(pdata, intr, "RX Stop interrupt"); smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_); if (pdata->multicast_update_pending) smsc911x_rx_multicast_update_workaround(pdata); @@ -1491,7 +1492,7 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) } if (unlikely(intsts & inten & INT_STS_RXE_)) { - SMSC_TRACE(INTR, "RX Error interrupt"); + SMSC_TRACE(pdata, intr, "RX Error interrupt"); smsc911x_reg_write(pdata, INT_STS, INT_STS_RXE_); serviced = IRQ_HANDLED; } @@ -1505,8 +1506,7 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) /* Schedule a NAPI poll */ __napi_schedule(&pdata->napi); } else { - SMSC_WARNING(RX_ERR, - "napi_schedule_prep failed"); + SMSC_WARN(pdata, rx_err, "napi_schedule_prep failed"); } serviced = IRQ_HANDLED; } @@ -1543,7 +1543,7 @@ static int smsc911x_set_mac_address(struct net_device *dev, void *p) smsc911x_set_hw_mac_address(pdata, dev->dev_addr); spin_unlock_irq(&pdata->mac_lock); - dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr); + netdev_info(dev, "MAC Address: %pM\n", dev->dev_addr); return 0; } @@ -1649,9 +1649,9 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op) int timeout = 100; u32 e2cmd; - SMSC_TRACE(DRV, "op 0x%08x", op); + SMSC_TRACE(pdata, drv, "op 0x%08x", op); if (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) { - SMSC_WARNING(DRV, "Busy at start"); + SMSC_WARN(pdata, drv, "Busy at start"); return -EBUSY; } @@ -1664,12 +1664,12 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op) } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout)); if (!timeout) { - SMSC_TRACE(DRV, "TIMED OUT"); + SMSC_TRACE(pdata, drv, "TIMED OUT"); return -EAGAIN; } if (e2cmd & E2P_CMD_EPC_TIMEOUT_) { - SMSC_TRACE(DRV, "Error occured during eeprom operation"); + SMSC_TRACE(pdata, drv, "Error occured during eeprom operation"); return -EINVAL; } @@ -1682,7 +1682,7 @@ static int smsc911x_eeprom_read_location(struct smsc911x_data *pdata, u32 op = E2P_CMD_EPC_CMD_READ_ | address; int ret; - SMSC_TRACE(DRV, "address 0x%x", address); + SMSC_TRACE(pdata, drv, "address 0x%x", address); ret = smsc911x_eeprom_send_cmd(pdata, op); if (!ret) @@ -1698,7 +1698,7 @@ static int smsc911x_eeprom_write_location(struct smsc911x_data *pdata, u32 temp; int ret; - SMSC_TRACE(DRV, "address 0x%x, data 0x%x", address, data); + SMSC_TRACE(pdata, drv, "address 0x%x, data 0x%x", address, data); ret = smsc911x_eeprom_send_cmd(pdata, op); if (!ret) { @@ -1811,25 +1811,25 @@ static int __devinit smsc911x_init(struct net_device *dev) struct smsc911x_data *pdata = netdev_priv(dev); unsigned int byte_test; - SMSC_TRACE(PROBE, "Driver Parameters:"); - SMSC_TRACE(PROBE, "LAN base: 0x%08lX", - (unsigned long)pdata->ioaddr); - SMSC_TRACE(PROBE, "IRQ: %d", dev->irq); - SMSC_TRACE(PROBE, "PHY will be autodetected."); + SMSC_TRACE(pdata, probe, "Driver Parameters:"); + SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX", + (unsigned long)pdata->ioaddr); + SMSC_TRACE(pdata, probe, "IRQ: %d", dev->irq); + SMSC_TRACE(pdata, probe, "PHY will be autodetected."); spin_lock_init(&pdata->dev_lock); if (pdata->ioaddr == 0) { - SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000"); + SMSC_WARN(pdata, probe, "pdata->ioaddr: 0x00000000"); return -ENODEV; } /* Check byte ordering */ byte_test = smsc911x_reg_read(pdata, BYTE_TEST); - SMSC_TRACE(PROBE, "BYTE_TEST: 0x%08X", byte_test); + SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test); if (byte_test == 0x43218765) { - SMSC_TRACE(PROBE, "BYTE_TEST looks swapped, " - "applying WORD_SWAP"); + SMSC_TRACE(pdata, probe, "BYTE_TEST looks swapped, " + "applying WORD_SWAP"); smsc911x_reg_write(pdata, WORD_SWAP, 0xffffffff); /* 1 dummy read of BYTE_TEST is needed after a write to @@ -1840,12 +1840,13 @@ static int __devinit smsc911x_init(struct net_device *dev) } if (byte_test != 0x87654321) { - SMSC_WARNING(DRV, "BYTE_TEST: 0x%08X", byte_test); + SMSC_WARN(pdata, drv, "BYTE_TEST: 0x%08X", byte_test); if (((byte_test >> 16) & 0xFFFF) == (byte_test & 0xFFFF)) { - SMSC_WARNING(PROBE, - "top 16 bits equal to bottom 16 bits"); - SMSC_TRACE(PROBE, "This may mean the chip is set " - "for 32 bit while the bus is reading 16 bit"); + SMSC_WARN(pdata, probe, + "top 16 bits equal to bottom 16 bits"); + SMSC_TRACE(pdata, probe, + "This may mean the chip is set " + "for 32 bit while the bus is reading 16 bit"); } return -ENODEV; } @@ -1880,17 +1881,18 @@ static int __devinit smsc911x_init(struct net_device *dev) break; default: - SMSC_WARNING(PROBE, "LAN911x not identified, idrev: 0x%08X", - pdata->idrev); + SMSC_WARN(pdata, probe, "LAN911x not identified, idrev: 0x%08X", + pdata->idrev); return -ENODEV; } - SMSC_TRACE(PROBE, "LAN911x identified, idrev: 0x%08X, generation: %d", - pdata->idrev, pdata->generation); + SMSC_TRACE(pdata, probe, + "LAN911x identified, idrev: 0x%08X, generation: %d", + pdata->idrev, pdata->generation); if (pdata->generation == 0) - SMSC_WARNING(PROBE, - "This driver is not intended for this chip revision"); + SMSC_WARN(pdata, probe, + "This driver is not intended for this chip revision"); /* workaround for platforms without an eeprom, where the mac address * is stored elsewhere and set by the bootloader. This saves the @@ -1927,7 +1929,7 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev) BUG_ON(!pdata->ioaddr); BUG_ON(!pdata->phy_dev); - SMSC_TRACE(IFDOWN, "Stopping driver."); + SMSC_TRACE(pdata, ifdown, "Stopping driver"); phy_disconnect(pdata->phy_dev); pdata->phy_dev = NULL; @@ -1961,11 +1963,11 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) int res_size, irq_flags; int retval; - pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION); + pr_info("Driver version %s\n", SMSC_DRV_VERSION); /* platform data specifies irq & dynamic bus configuration */ if (!pdev->dev.platform_data) { - pr_warning("%s: platform_data not provided\n", SMSC_CHIPNAME); + pr_warn("platform_data not provided\n"); retval = -ENODEV; goto out_0; } @@ -1975,8 +1977,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (!res) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - pr_warning("%s: Could not allocate resource.\n", - SMSC_CHIPNAME); + pr_warn("Could not allocate resource\n"); retval = -ENODEV; goto out_0; } @@ -1984,8 +1985,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { - pr_warning("%s: Could not allocate irq resource.\n", - SMSC_CHIPNAME); + pr_warn("Could not allocate irq resource\n"); retval = -ENODEV; goto out_0; } @@ -1997,7 +1997,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof(struct smsc911x_data)); if (!dev) { - pr_warning("%s: Could not allocate device.\n", SMSC_CHIPNAME); + pr_warn("Could not allocate device\n"); retval = -ENOMEM; goto out_release_io_1; } @@ -2017,8 +2017,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) pdata->msg_enable = ((1 << debug) - 1); if (pdata->ioaddr == NULL) { - SMSC_WARNING(PROBE, - "Error smsc911x base address invalid"); + SMSC_WARN(pdata, probe, "Error smsc911x base address invalid"); retval = -ENOMEM; goto out_free_netdev_2; } @@ -2043,8 +2042,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = request_irq(dev->irq, smsc911x_irqhandler, irq_flags | IRQF_SHARED, dev->name, dev); if (retval) { - SMSC_WARNING(PROBE, - "Unable to claim requested irq: %d", dev->irq); + SMSC_WARN(pdata, probe, + "Unable to claim requested irq: %d", dev->irq); goto out_unmap_io_3; } @@ -2052,19 +2051,18 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) retval = register_netdev(dev); if (retval) { - SMSC_WARNING(PROBE, - "Error %i registering device", retval); + SMSC_WARN(pdata, probe, "Error %i registering device", retval); goto out_unset_drvdata_4; } else { - SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name); + SMSC_TRACE(pdata, probe, + "Network interface: \"%s\"", dev->name); } spin_lock_init(&pdata->mac_lock); retval = smsc911x_mii_init(pdev, dev); if (retval) { - SMSC_WARNING(PROBE, - "Error %i initialising mii", retval); + SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); goto out_unregister_netdev_5; } @@ -2073,10 +2071,12 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) /* Check if mac address has been specified when bringing interface up */ if (is_valid_ether_addr(dev->dev_addr)) { smsc911x_set_hw_mac_address(pdata, dev->dev_addr); - SMSC_TRACE(PROBE, "MAC Address is specified by configuration"); + SMSC_TRACE(pdata, probe, + "MAC Address is specified by configuration"); } else if (is_valid_ether_addr(pdata->config.mac)) { memcpy(dev->dev_addr, pdata->config.mac, 6); - SMSC_TRACE(PROBE, "MAC Address specified by platform data"); + SMSC_TRACE(pdata, probe, + "MAC Address specified by platform data"); } else { /* Try reading mac address from device. if EEPROM is present * it will already have been set */ @@ -2084,20 +2084,20 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (is_valid_ether_addr(dev->dev_addr)) { /* eeprom values are valid so use them */ - SMSC_TRACE(PROBE, - "Mac Address is read from LAN911x EEPROM"); + SMSC_TRACE(pdata, probe, + "Mac Address is read from LAN911x EEPROM"); } else { /* eeprom values are invalid, generate random MAC */ random_ether_addr(dev->dev_addr); smsc911x_set_hw_mac_address(pdata, dev->dev_addr); - SMSC_TRACE(PROBE, - "MAC Address is set to random_ether_addr"); + SMSC_TRACE(pdata, probe, + "MAC Address is set to random_ether_addr"); } } spin_unlock_irq(&pdata->mac_lock); - dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr); + netdev_info(dev, "MAC Address: %pM\n", dev->dev_addr); return 0; diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h index 50f712e99e96..8d67aacf8867 100644 --- a/drivers/net/smsc911x.h +++ b/drivers/net/smsc911x.h @@ -33,25 +33,21 @@ * can be successfully looped back */ #define USE_PHY_WORK_AROUND -#define DPRINTK(nlevel, klevel, fmt, args...) \ - ((void)((NETIF_MSG_##nlevel & pdata->msg_enable) && \ - printk(KERN_##klevel "%s: %s: " fmt "\n", \ - pdata->dev->name, __func__, ## args))) - #if USE_DEBUG >= 1 -#define SMSC_WARNING(nlevel, fmt, args...) \ - DPRINTK(nlevel, WARNING, fmt, ## args) +#define SMSC_WARN(pdata, nlevel, fmt, args...) \ + netif_warn(pdata, nlevel, (pdata)->dev, \ + "%s: " fmt "\n", __func__, ##args) #else -#define SMSC_WARNING(nlevel, fmt, args...) \ - ({ do {} while (0); 0; }) +#define SMSC_WARN(pdata, nlevel, fmt, args...) \ + no_printk(fmt "\n", ##args) #endif #if USE_DEBUG >= 2 -#define SMSC_TRACE(nlevel, fmt, args...) \ - DPRINTK(nlevel, INFO, fmt, ## args) +#define SMSC_TRACE(pdata, nlevel, fmt, args...) \ + netif_info(pdata, nlevel, pdata->dev, fmt "\n", ##args) #else -#define SMSC_TRACE(nlevel, fmt, args...) \ - ({ do {} while (0); 0; }) +#define SMSC_TRACE(pdata, nlevel, fmt, args...) \ + no_printk(fmt "\n", ##args) #endif #ifdef CONFIG_DEBUG_SPINLOCK -- GitLab From 19eccc2bc6ad3b1c81d0826a77955500be972504 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 27 Mar 2011 02:58:35 +0000 Subject: [PATCH 0195/5560] kstrtox: convert drivers/isdn/ Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- drivers/isdn/gigaset/ev-layer.c | 26 +++++++++----------------- drivers/isdn/hysdn/hysdn_proclog.c | 11 ++++------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index a14187605f5e..ba74646cf0e4 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c @@ -390,12 +390,12 @@ static const struct zsau_resp_t { */ static int cid_of_response(char *s) { - unsigned long cid; + int cid; int rc; if (s[-1] != ';') return 0; /* no CID separator */ - rc = strict_strtoul(s, 10, &cid); + rc = kstrtoint(s, 10, &cid); if (rc) return 0; /* CID not numeric */ if (cid < 1 || cid > 65535) @@ -566,27 +566,19 @@ void gigaset_handle_modem_response(struct cardstate *cs) case RT_ZCAU: event->parameter = -1; if (curarg + 1 < params) { - unsigned long type, value; - - i = strict_strtoul(argv[curarg++], 16, &type); - j = strict_strtoul(argv[curarg++], 16, &value); + u8 type, value; - if (i == 0 && type < 256 && - j == 0 && value < 256) + i = kstrtou8(argv[curarg++], 16, &type); + j = kstrtou8(argv[curarg++], 16, &value); + if (i == 0 && j == 0) event->parameter = (type << 8) | value; } else curarg = params - 1; break; case RT_NUMBER: - event->parameter = -1; - if (curarg < params) { - unsigned long res; - int rc; - - rc = strict_strtoul(argv[curarg++], 10, &res); - if (rc == 0) - event->parameter = res; - } + if (curarg >= params || + kstrtoint(argv[curarg++], 10, &event->parameter)) + event->parameter = -1; gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter); break; } diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 2ee93d04b2dd..236cc7dadfd0 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -155,7 +155,6 @@ put_log_buffer(hysdn_card * card, char *cp) static ssize_t hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off) { - unsigned long u = 0; int rc; unsigned char valbuf[128]; hysdn_card *card = file->private_data; @@ -167,12 +166,10 @@ hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t valbuf[count] = 0; /* terminating 0 */ - rc = strict_strtoul(valbuf, 0, &u); - - if (rc == 0) { - card->debug_flags = u; /* remember debug flags */ - hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags); - } + rc = kstrtoul(valbuf, 0, &card->debug_flags); + if (rc < 0) + return rc; + hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags); return (count); } /* hysdn_log_write */ -- GitLab From 4562b2fe1ebc7c547746660f735ff9af964f28ad Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Mon, 28 Mar 2011 17:08:59 +0000 Subject: [PATCH 0196/5560] via-rhine: trivial sparse annotation in vlan_tci helper Noticed by sparse: drivers/net/via-rhine.c:1706:16: warning: cast to restricted __be16 Signed-off-by: Harvey Harrison Signed-off-by: David S. Miller --- drivers/net/via-rhine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 5e7f069eab53..707f7f8beb6f 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1703,7 +1703,7 @@ static void rhine_tx(struct net_device *dev) 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); + return be16_to_cpup((__be16 *)trailer); } /* Process up to limit frames from receive ring */ -- GitLab From 9085fd09859fafbde17380b93d317a13c23c39af Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 29 Mar 2011 20:35:51 +0000 Subject: [PATCH 0197/5560] enic: Add support for new fw devcmds for port profile handling This patch introduces new fw devcmds for port profile handling. These new commands are similar to the current fw commands for port profile handling. The only difference being that the new commands split the existing port profile handling devcmds into multiple fw commands, giving the driver finer control over port profile operations. Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/vnic_dev.c | 97 +++++++++++++++++++--------------- drivers/net/enic/vnic_dev.h | 6 ++- drivers/net/enic/vnic_devcmd.h | 57 ++++++++++++++++++-- 3 files changed, 111 insertions(+), 49 deletions(-) diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index c089b362a36f..68f24ae860ae 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -786,48 +786,6 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) return r; } -int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err) -{ - u64 a0 = 0, a1 = 0; - int wait = 1000; - int ret; - - *done = 0; - - ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait); - if (ret) - return ret; - - *done = (a0 == 0); - - *err = (a0 == 0) ? (int)a1:0; - - return 0; -} - -int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len) -{ - u64 a0, a1 = len; - int wait = 1000; - dma_addr_t prov_pa; - void *prov_buf; - int ret; - - prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa); - if (!prov_buf) - return -ENOMEM; - - memcpy(prov_buf, buf, len); - - a0 = prov_pa; - - ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait); - - pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa); - - return ret; -} - int vnic_dev_deinit(struct vnic_dev *vdev) { u64 a0 = 0, a1 = 0; @@ -927,4 +885,59 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, return NULL; } +int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len) +{ + u64 a0, a1 = len; + int wait = 1000; + dma_addr_t prov_pa; + void *prov_buf; + int ret; + + prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa); + if (!prov_buf) + return -ENOMEM; + memcpy(prov_buf, buf, len); + + a0 = prov_pa; + + ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO2, &a0, &a1, wait); + + pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa); + + return ret; +} + +int vnic_dev_enable2(struct vnic_dev *vdev, int active) +{ + u64 a0, a1 = 0; + int wait = 1000; + + a0 = (active ? CMD_ENABLE2_ACTIVE : 0); + + return vnic_dev_cmd(vdev, CMD_ENABLE2, &a0, &a1, wait); +} + +static int vnic_dev_cmd_status(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, + int *status) +{ + u64 a0 = cmd, a1 = 0; + int wait = 1000; + int ret; + + ret = vnic_dev_cmd(vdev, CMD_STATUS, &a0, &a1, wait); + if (!ret) + *status = (int)a0; + + return ret; +} + +int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status) +{ + return vnic_dev_cmd_status(vdev, CMD_ENABLE2, status); +} + +int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status) +{ + return vnic_dev_cmd_status(vdev, CMD_DEINIT, status); +} diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index e837546213a8..cf482a2c9dd9 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -108,8 +108,6 @@ int vnic_dev_disable(struct vnic_dev *vdev); int vnic_dev_open(struct vnic_dev *vdev, int arg); int vnic_dev_open_done(struct vnic_dev *vdev, int *done); int vnic_dev_init(struct vnic_dev *vdev, int arg); -int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err); -int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len); int vnic_dev_deinit(struct vnic_dev *vdev); int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg); int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done); @@ -122,5 +120,9 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, unsigned int num_bars); +int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len); +int vnic_dev_enable2(struct vnic_dev *vdev, int active); +int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status); +int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status); #endif /* _VNIC_DEV_H_ */ diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h index d833a071bac5..c5569bfb47ac 100644 --- a/drivers/net/enic/vnic_devcmd.h +++ b/drivers/net/enic/vnic_devcmd.h @@ -267,17 +267,62 @@ enum vnic_devcmd_cmd { /* * As for BY_BDF except a0 is index of hvnlink subordinate vnic - * or SR-IOV virtual vnic */ + * or SR-IOV virtual vnic + */ CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43), /* - * in: (u64)a0=paddr of buffer to put latest VIC VIF-CONFIG-INFO TLV in - * (u32)a1=length of buffer in a0 - * out: (u64)a0=paddr of buffer with latest VIC VIF-CONFIG-INFO TLV - * (u32)a1=actual length of latest VIC VIF-CONFIG-INFO TLV */ + * For HPP toggle: + * adapter-info-get + * in: (u64)a0=phsical address of buffer passed in from caller. + * (u16)a1=size of buffer specified in a0. + * out: (u64)a0=phsical address of buffer passed in from caller. + * (u16)a1=actual bytes from VIF-CONFIG-INFO TLV, or + * 0 if no VIF-CONFIG-INFO TLV was ever received. */ CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44), + + /* init_prov_info2: + * Variant of CMD_INIT_PROV_INFO, where it will not try to enable + * the vnic until CMD_ENABLE2 is issued. + * (u64)a0=paddr of vnic_devcmd_provinfo + * (u32)a1=sizeof provision info */ + CMD_INIT_PROV_INFO2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 47), + + /* enable2: + * (u32)a0=0 ==> standby + * =CMD_ENABLE2_ACTIVE ==> active + */ + CMD_ENABLE2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 48), + + /* + * cmd_status: + * Returns the status of the specified command + * Input: + * a0 = command for which status is being queried. + * Possible values are: + * CMD_SOFT_RESET + * CMD_HANG_RESET + * CMD_OPEN + * CMD_INIT + * CMD_INIT_PROV_INFO + * CMD_DEINIT + * CMD_INIT_PROV_INFO2 + * CMD_ENABLE2 + * Output: + * if status == STAT_ERROR + * a0 = ERR_ENOTSUPPORTED - status for command in a0 is + * not supported + * if status == STAT_NONE + * a0 = status of the devcmd specified in a0 as follows. + * ERR_SUCCESS - command in a0 completed successfully + * ERR_EINPROGRESS - command in a0 is still in progress + */ + CMD_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 49), }; +/* CMD_ENABLE2 flags */ +#define CMD_ENABLE2_ACTIVE 0x1 + /* flags for CMD_OPEN */ #define CMD_OPENF_OPROM 0x1 /* open coming from option rom */ @@ -315,6 +360,8 @@ enum vnic_devcmd_error { ERR_ETIMEDOUT = 8, ERR_ELINKDOWN = 9, ERR_EMAXRES = 10, + ERR_ENOTSUPPORTED = 11, + ERR_EINPROGRESS = 12, }; /* -- GitLab From 18714ff8de7a000e7642561cabaf8ace8d082e9f Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 29 Mar 2011 20:35:56 +0000 Subject: [PATCH 0198/5560] enic: Add wrapper routines for new fw devcmds for port profile handling This patch adds wrapper routines to new port profile related fw devcmds and removes the old ones 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_dev.c | 62 ++++++++++++++++++++++++++++++++++--- drivers/net/enic/enic_dev.h | 7 +++-- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c index 37ad3a1c82ee..90687b14e60f 100644 --- a/drivers/net/enic/enic_dev.c +++ b/drivers/net/enic/enic_dev.c @@ -177,24 +177,24 @@ int enic_vnic_dev_deinit(struct enic *enic) return err; } -int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp) +int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp) { int err; spin_lock(&enic->devcmd_lock); - err = vnic_dev_init_prov(enic->vdev, + err = vnic_dev_init_prov2(enic->vdev, (u8 *)vp, vic_provinfo_size(vp)); spin_unlock(&enic->devcmd_lock); return err; } -int enic_dev_init_done(struct enic *enic, int *done, int *error) +int enic_dev_deinit_done(struct enic *enic, int *status) { int err; spin_lock(&enic->devcmd_lock); - err = vnic_dev_init_done(enic->vdev, done, error); + err = vnic_dev_deinit_done(enic->vdev, status); spin_unlock(&enic->devcmd_lock); return err; @@ -219,3 +219,57 @@ void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) enic_del_vlan(enic, vid); spin_unlock(&enic->devcmd_lock); } + +int enic_dev_enable2(struct enic *enic, int active) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_enable2(enic->vdev, active); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_enable2_done(struct enic *enic, int *status) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_enable2_done(enic->vdev, status); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_status_to_errno(int devcmd_status) +{ + switch (devcmd_status) { + case ERR_SUCCESS: + return 0; + case ERR_EINVAL: + return -EINVAL; + case ERR_EFAULT: + return -EFAULT; + case ERR_EPERM: + return -EPERM; + case ERR_EBUSY: + return -EBUSY; + case ERR_ECMDUNKNOWN: + case ERR_ENOTSUPPORTED: + return -EOPNOTSUPP; + case ERR_EBADSTATE: + return -EINVAL; + case ERR_ENOMEM: + return -ENOMEM; + case ERR_ETIMEDOUT: + return -ETIMEDOUT; + case ERR_ELINKDOWN: + return -ENETDOWN; + case ERR_EINPROGRESS: + return -EINPROGRESS; + case ERR_EMAXRES: + default: + return (devcmd_status < 0) ? devcmd_status : -1; + } +} diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h index 495f57fcb887..d5f681337626 100644 --- a/drivers/net/enic/enic_dev.h +++ b/drivers/net/enic/enic_dev.h @@ -35,7 +35,10 @@ int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic); int enic_dev_enable(struct enic *enic); int enic_dev_disable(struct enic *enic); int enic_vnic_dev_deinit(struct enic *enic); -int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp); -int enic_dev_init_done(struct enic *enic, int *done, int *error); +int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp); +int enic_dev_deinit_done(struct enic *enic, int *status); +int enic_dev_enable2(struct enic *enic, int arg); +int enic_dev_enable2_done(struct enic *enic, int *status); +int enic_dev_status_to_errno(int devcmd_status); #endif /* _ENIC_DEV_H_ */ -- GitLab From 756462f3434ec4807a61f884d59358092a03fc15 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 29 Mar 2011 20:36:02 +0000 Subject: [PATCH 0199/5560] enic: Cleanups in port profile helper code This patch does the following: - Introduces a new macro VIC_PROVINFO_ADD_TLV - Adds a new OS type in vic_generic_prov_os_type - Changes some vic_provinfo* helper routine args to constants Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/vnic_vic.c | 5 +++-- drivers/net/enic/vnic_vic.h | 13 +++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c index 4725b79de0ef..24ef8cd40545 100644 --- a/drivers/net/enic/vnic_vic.c +++ b/drivers/net/enic/vnic_vic.c @@ -23,7 +23,8 @@ #include "vnic_vic.h" -struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type) +struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui, + const u8 type) { struct vic_provinfo *vp; @@ -47,7 +48,7 @@ void vic_provinfo_free(struct vic_provinfo *vp) } int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, - void *value) + const void *value) { struct vic_provinfo_tlv *tlv; diff --git a/drivers/net/enic/vnic_vic.h b/drivers/net/enic/vnic_vic.h index f700f5d9e81d..9ef81f148351 100644 --- a/drivers/net/enic/vnic_vic.h +++ b/drivers/net/enic/vnic_vic.h @@ -47,6 +47,7 @@ enum vic_generic_prov_os_type { VIC_GENERIC_PROV_OS_TYPE_ESX = 1, VIC_GENERIC_PROV_OS_TYPE_LINUX = 2, VIC_GENERIC_PROV_OS_TYPE_WINDOWS = 3, + VIC_GENERIC_PROV_OS_TYPE_SOLARIS = 4, }; struct vic_provinfo { @@ -61,14 +62,22 @@ struct vic_provinfo { } tlv[0]; } __packed; +#define VIC_PROVINFO_ADD_TLV(vp, tlvtype, tlvlen, data) \ + do { \ + err = vic_provinfo_add_tlv(vp, tlvtype, tlvlen, data); \ + if (err) \ + goto add_tlv_failure; \ + } while (0) + #define VIC_PROVINFO_MAX_DATA 1385 #define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \ sizeof(struct vic_provinfo)) -struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type); +struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui, + const u8 type); void vic_provinfo_free(struct vic_provinfo *vp); int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, - void *value); + const void *value); size_t vic_provinfo_size(struct vic_provinfo *vp); #endif /* _VNIC_VIC_H_ */ -- GitLab From b3abfbd2951102f5f5b8fe251a672e5223ac972b Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 29 Mar 2011 20:36:07 +0000 Subject: [PATCH 0200/5560] enic: Add support for PORT_REQUEST_PREASSOCIATE_RR Current enic code only supports ASSOCIATE and DISASSOCIATE port profile operations. This patch adds enic support for port profile PORT_REQUEST_PREASSOCIATE_RR operation. The VIC adapter (8021qbh) is capable of handling port profile requests done in two steps namely PREASSOCIATE_RR and ASSOCIATE today. The motivation to support PREASSOCIATE_RR comes mainly from its use as an optimization during VM migration ie, to do resource reservation on destination host before resources on source host are released. PREASSOCIATE_RR is a VDP operation and according to the latest at IEEE, 8021qbh will also need to support VDP commands. In addition to handling the new PORT_REQUEST_PREASSOCIATE_RR operation this patch also does the below: - Introduces handlers for PORT_REQUEST operations - Moves most of the port profile handling code to new files enic_pp.[ch] - Uses new fw devcmds for port profile operations Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/Makefile | 2 +- drivers/net/enic/enic.h | 4 +- drivers/net/enic/enic_main.c | 196 +++++++------------------- drivers/net/enic/enic_pp.c | 264 +++++++++++++++++++++++++++++++++++ drivers/net/enic/enic_pp.h | 27 ++++ 5 files changed, 344 insertions(+), 149 deletions(-) create mode 100644 drivers/net/enic/enic_pp.c create mode 100644 drivers/net/enic/enic_pp.h diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile index 2e573be16c13..9d4974bba247 100644 --- a/drivers/net/enic/Makefile +++ b/drivers/net/enic/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_ENIC) := enic.o enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \ - enic_res.o enic_dev.o vnic_dev.o vnic_rq.o vnic_vic.o + enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 3a3c3c8a3a9b..178b94d7f89b 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 "2.1.1.12" +#define DRV_VERSION "2.1.1.13" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -120,4 +120,6 @@ static inline struct device *enic_get_dev(struct enic *enic) return &(enic->pdev->dev); } +void enic_reset_addr_lists(struct enic *enic); + #endif /* _ENIC_H_ */ diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 8b9cad5e9712..9a3a0277bf21 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -45,6 +45,7 @@ #include "enic_res.h" #include "enic.h" #include "enic_dev.h" +#include "enic_pp.h" #define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ) #define WQ_ENET_MAX_DESC_LEN (1 << WQ_ENET_LEN_BITS) @@ -874,7 +875,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev) return net_stats; } -static void enic_reset_addr_lists(struct enic *enic) +void enic_reset_addr_lists(struct enic *enic) { enic->mc_count = 0; enic->uc_count = 0; @@ -1112,157 +1113,77 @@ static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) return -EINVAL; } -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); - if (err) - return err; - - enic_reset_addr_lists(enic); - - switch (enic->pp.request) { - - case PORT_REQUEST_ASSOCIATE: - - if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name)) - return -EINVAL; - - if (!is_valid_ether_addr(mac)) - return -EADDRNOTAVAIL; - - vp = vic_provinfo_alloc(GFP_KERNEL, oui, - VIC_PROVINFO_GENERIC_TYPE); - if (!vp) - return -ENOMEM; - - vic_provinfo_add_tlv(vp, - 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)) - client_mac = enic->pp.mac_addr; - else - 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_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_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) - return err; - break; - - case PORT_REQUEST_DISASSOCIATE: - break; - - default: - return -EINVAL; - } - - /* Set flag to indicate that the port assoc/disassoc - * request has been sent out to fw - */ - enic->pp.set |= ENIC_PORT_REQUEST_APPLIED; - - return 0; -} - 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; + struct enic_port_profile prev_pp; + int err = 0, restore_pp = 1; - memset(&new_pp, 0, sizeof(new_pp)); + /* don't support VFs, yet */ + if (vf != PORT_SELF_VF) + return -EOPNOTSUPP; - if (port[IFLA_PORT_REQUEST]) { - new_pp.set |= ENIC_SET_REQUEST; - new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); - } + if (!port[IFLA_PORT_REQUEST]) + return -EOPNOTSUPP; + + memcpy(&prev_pp, &enic->pp, sizeof(enic->pp)); + memset(&enic->pp, 0, sizeof(enic->pp)); + + enic->pp.set |= ENIC_SET_REQUEST; + enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); if (port[IFLA_PORT_PROFILE]) { - new_pp.set |= ENIC_SET_NAME; - memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]), + enic->pp.set |= ENIC_SET_NAME; + memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), PORT_PROFILE_MAX); } if (port[IFLA_PORT_INSTANCE_UUID]) { - new_pp.set |= ENIC_SET_INSTANCE; - memcpy(new_pp.instance_uuid, + enic->pp.set |= ENIC_SET_INSTANCE; + memcpy(enic->pp.instance_uuid, nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); } if (port[IFLA_PORT_HOST_UUID]) { - new_pp.set |= ENIC_SET_HOST; - memcpy(new_pp.host_uuid, + enic->pp.set |= ENIC_SET_HOST; + memcpy(enic->pp.host_uuid, nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); } - /* don't support VFs, yet */ - if (vf != PORT_SELF_VF) - return -EOPNOTSUPP; - - if (!(new_pp.set & ENIC_SET_REQUEST)) - return -EOPNOTSUPP; - - 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); + /* Special case handling: mac came from IFLA_VF_MAC */ + if (!is_zero_ether_addr(prev_pp.vf_mac)) + memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN); if (is_zero_ether_addr(netdev->dev_addr)) random_ether_addr(netdev->dev_addr); - } - memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile)); + err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp); + if (err) { + if (restore_pp) { + /* Things are still the way they were: Implicit + * DISASSOCIATE failed + */ + memcpy(&enic->pp, &prev_pp, sizeof(enic->pp)); + } else { + memset(&enic->pp, 0, sizeof(enic->pp)); + memset(netdev->dev_addr, 0, ETH_ALEN); + } + } else { + /* Set flag to indicate that the port assoc/disassoc + * request has been sent out to fw + */ + enic->pp.set |= ENIC_PORT_REQUEST_APPLIED; - err = enic_set_port_profile(enic, netdev->dev_addr); - if (err) - goto set_port_profile_cleanup; + /* If DISASSOCIATE, clean up all assigned/saved macaddresses */ + if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) { + memset(enic->pp.mac_addr, 0, ETH_ALEN); + memset(netdev->dev_addr, 0, ETH_ALEN); + } + } -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; } @@ -1270,34 +1191,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf, struct sk_buff *skb) { struct enic *enic = netdev_priv(netdev); - int err, error, done; u16 response = PORT_PROFILE_RESPONSE_SUCCESS; + int err; if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED)) return -ENODATA; - err = enic_dev_init_done(enic, &done, &error); + err = enic_process_get_pp_request(enic, enic->pp.request, &response); if (err) - error = err; - - switch (error) { - case ERR_SUCCESS: - if (!done) - response = PORT_PROFILE_RESPONSE_INPROGRESS; - break; - case ERR_EINVAL: - response = PORT_PROFILE_RESPONSE_INVALID; - break; - case ERR_EBADSTATE: - response = PORT_PROFILE_RESPONSE_BADSTATE; - break; - case ERR_ENOMEM: - response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES; - break; - default: - response = PORT_PROFILE_RESPONSE_ERROR; - break; - } + return err; NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request); NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response); diff --git a/drivers/net/enic/enic_pp.c b/drivers/net/enic/enic_pp.c new file mode 100644 index 000000000000..ffaa75dd1ded --- /dev/null +++ b/drivers/net/enic/enic_pp.c @@ -0,0 +1,264 @@ +/* + * Copyright 2011 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vnic_vic.h" +#include "enic_res.h" +#include "enic.h" +#include "enic_dev.h" + +static int enic_set_port_profile(struct enic *enic) +{ + struct net_device *netdev = enic->netdev; + struct vic_provinfo *vp; + const u8 oui[3] = VIC_PROVINFO_CISCO_OUI; + const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX); + char uuid_str[38]; + char client_mac_str[18]; + u8 *client_mac; + int err; + + if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name)) + return -EINVAL; + + vp = vic_provinfo_alloc(GFP_KERNEL, oui, + VIC_PROVINFO_GENERIC_TYPE); + if (!vp) + return -ENOMEM; + + VIC_PROVINFO_ADD_TLV(vp, + 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)) + client_mac = enic->pp.mac_addr; + else + client_mac = netdev->dev_addr; + + VIC_PROVINFO_ADD_TLV(vp, + VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR, + ETH_ALEN, client_mac); + + snprintf(client_mac_str, sizeof(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_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_GENERIC_PROV_TLV_HOST_UUID_STR, + sizeof(uuid_str), uuid_str); + } + + VIC_PROVINFO_ADD_TLV(vp, + VIC_GENERIC_PROV_TLV_OS_TYPE, + sizeof(os_type), &os_type); + + err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp)); + +add_tlv_failure: + vic_provinfo_free(vp); + + return err; +} + +static int enic_unset_port_profile(struct enic *enic) +{ + int err; + + err = enic_vnic_dev_deinit(enic); + if (err) + return enic_dev_status_to_errno(err); + + enic_reset_addr_lists(enic); + + return 0; +} + +static int enic_are_pp_different(struct enic_port_profile *pp1, + struct enic_port_profile *pp2) +{ + return strcmp(pp1->name, pp2->name) | !!memcmp(pp1->instance_uuid, + pp2->instance_uuid, PORT_UUID_MAX) | + !!memcmp(pp1->host_uuid, pp2->host_uuid, PORT_UUID_MAX) | + !!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN); +} + +static int enic_pp_preassociate(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp); +static int enic_pp_disassociate(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp); +static int enic_pp_preassociate_rr(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp); +static int enic_pp_associate(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp); + +static int (*enic_pp_handlers[])(struct enic *enic, + struct enic_port_profile *prev_state, int *restore_pp) = { + [PORT_REQUEST_PREASSOCIATE] = enic_pp_preassociate, + [PORT_REQUEST_PREASSOCIATE_RR] = enic_pp_preassociate_rr, + [PORT_REQUEST_ASSOCIATE] = enic_pp_associate, + [PORT_REQUEST_DISASSOCIATE] = enic_pp_disassociate, +}; + +static const int enic_pp_handlers_count = + sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers); + +static int enic_pp_preassociate(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp) +{ + return -EOPNOTSUPP; +} + +static int enic_pp_disassociate(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp) +{ + return enic_unset_port_profile(enic); +} + +static int enic_pp_preassociate_rr(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp) +{ + int err; + int active = 0; + + if (enic->pp.request != PORT_REQUEST_ASSOCIATE) { + /* If pre-associate is not part of an associate. + We always disassociate first */ + err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic, + prev_pp, restore_pp); + if (err) + return err; + + *restore_pp = 0; + } + + *restore_pp = 0; + + err = enic_set_port_profile(enic); + if (err) + return err; + + /* If pre-associate is not part of an associate. */ + if (enic->pp.request != PORT_REQUEST_ASSOCIATE) + err = enic_dev_status_to_errno(enic_dev_enable2(enic, active)); + + return err; +} + +static int enic_pp_associate(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp) +{ + int err; + int active = 1; + + /* Check if a pre-associate was called before */ + if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR || + (prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR && + enic_are_pp_different(prev_pp, &enic->pp))) { + err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE]( + enic, prev_pp, restore_pp); + if (err) + return err; + + *restore_pp = 0; + } + + err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR]( + enic, prev_pp, restore_pp); + if (err) + return err; + + *restore_pp = 0; + + return enic_dev_status_to_errno(enic_dev_enable2(enic, active)); +} + +int enic_process_set_pp_request(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp) +{ + if (enic->pp.request < enic_pp_handlers_count + && enic_pp_handlers[enic->pp.request]) + return enic_pp_handlers[enic->pp.request](enic, + prev_pp, restore_pp); + else + return -EOPNOTSUPP; +} + +int enic_process_get_pp_request(struct enic *enic, int request, + u16 *response) +{ + int err, status = ERR_SUCCESS; + + switch (request) { + + case PORT_REQUEST_PREASSOCIATE_RR: + case PORT_REQUEST_ASSOCIATE: + err = enic_dev_enable2_done(enic, &status); + break; + + case PORT_REQUEST_DISASSOCIATE: + err = enic_dev_deinit_done(enic, &status); + break; + + default: + return -EINVAL; + } + + if (err) + status = err; + + switch (status) { + case ERR_SUCCESS: + *response = PORT_PROFILE_RESPONSE_SUCCESS; + break; + case ERR_EINVAL: + *response = PORT_PROFILE_RESPONSE_INVALID; + break; + case ERR_EBADSTATE: + *response = PORT_PROFILE_RESPONSE_BADSTATE; + break; + case ERR_ENOMEM: + *response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES; + break; + case ERR_EINPROGRESS: + *response = PORT_PROFILE_RESPONSE_INPROGRESS; + break; + default: + *response = PORT_PROFILE_RESPONSE_ERROR; + break; + } + + return 0; +} diff --git a/drivers/net/enic/enic_pp.h b/drivers/net/enic/enic_pp.h new file mode 100644 index 000000000000..699e365a944d --- /dev/null +++ b/drivers/net/enic/enic_pp.h @@ -0,0 +1,27 @@ +/* + * Copyright 2011 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef _ENIC_PP_H_ +#define _ENIC_PP_H_ + +int enic_process_set_pp_request(struct enic *enic, + struct enic_port_profile *prev_pp, int *restore_pp); +int enic_process_get_pp_request(struct enic *enic, int request, + u16 *response); + +#endif /* _ENIC_PP_H_ */ -- GitLab From ab392d2d6d4e2e50502985eead545b44ee58802c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 28 Mar 2011 16:27:31 +0000 Subject: [PATCH 0201/5560] drivers/net: Remove IRQF_SAMPLE_RANDOM flag from network drivers The IRQF_SAMPLE_RANDOM flag is marked as deprecated and will be removed. Every input point to the kernel's entropy pool have to better document the type of entropy source it is. drivers/char/random.c now implements a set of interfaces that can be used for devices to collect enviromental noise. IRQF_SAMPLE_RANDOM will be replaced with these add_*_randomness exported functions. Network drivers are not a good source of entropy. They use as a source of entropy essentially a remote host. Which means that the source of entropy can be potentially controlled by an attacker. Also, with heavy workloads the entropy decreases due to less hardware interrupts happening thanks to irq mitigation and NAPI. If a system relies in its network interface as a entropy source it has a false sense of security. Systems that don't have devices whose drivers are good sources of entropy, should either use a hardware random number generator or feed the kernel's entropy pool from userspace using other sources of entropy such as EGD, video_entropyd, timer_entropyd and audio-entropyd. Signed-off-by: Javier Martinez Canillas Signed-off-by: David S. Miller --- drivers/net/atlx/atl1.c | 2 +- drivers/net/bcm63xx_enet.c | 4 ++-- drivers/net/cris/eth_v10.c | 4 ++-- drivers/net/ibmlana.c | 3 ++- drivers/net/macb.c | 3 +-- drivers/net/netxen/netxen_nic_main.c | 2 +- drivers/net/niu.c | 3 +-- drivers/net/qla3xxx.c | 2 +- drivers/net/tg3.c | 4 ++-- drivers/net/xen-netfront.c | 3 +-- 10 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 67f40b9c16ed..e973d056dc8f 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2572,7 +2572,7 @@ static s32 atl1_up(struct atl1_adapter *adapter) { struct net_device *netdev = adapter->netdev; int err; - int irq_flags = IRQF_SAMPLE_RANDOM; + int irq_flags = 0; /* hardware has been reset, we need to reload some things */ atlx_set_multi(netdev); diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index e94a966af418..2af413fbfb0e 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -839,8 +839,8 @@ static int bcm_enet_open(struct net_device *dev) if (ret) goto out_phy_disconnect; - ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, - IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev); + ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, IRQF_DISABLED, + dev->name, dev); if (ret) goto out_freeirq; diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 80c2feeefec5..e759d74edd01 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -491,8 +491,8 @@ e100_open(struct net_device *dev) /* allocate the irq corresponding to the receiving DMA */ - if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, - IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) { + if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, 0, cardname, + (void *)dev)) { goto grace_exit0; } diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 94d9969ec0bb..f872f966927a 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -782,7 +782,8 @@ static int ibmlana_open(struct net_device *dev) /* register resources - only necessary for IRQ */ - result = request_irq(priv->realirq, irq_handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); + result = request_irq(priv->realirq, irq_handler, IRQF_SHARED, + dev->name, dev); if (result != 0) { printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq); return result; diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 79ccb54ab00c..2cb4e792f871 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1171,8 +1171,7 @@ static int __init macb_probe(struct platform_device *pdev) } dev->irq = platform_get_irq(pdev, 0); - err = request_irq(dev->irq, macb_interrupt, IRQF_SAMPLE_RANDOM, - dev->name, dev); + err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev); if (err) { printk(KERN_ERR "%s: Unable to request IRQ %d (error %d)\n", diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 83348dc4b184..933671556c15 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -905,7 +905,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter) struct nx_host_sds_ring *sds_ring; int err, ring; - unsigned long flags = IRQF_SAMPLE_RANDOM; + unsigned long flags = 0; struct net_device *netdev = adapter->netdev; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 32678b6c6b39..681a42ca5c51 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -6071,8 +6071,7 @@ static int niu_request_irq(struct niu *np) for (i = 0; i < np->num_ldg; i++) { struct niu_ldg *lp = &np->ldg[i]; - err = request_irq(lp->irq, niu_interrupt, - IRQF_SHARED | IRQF_SAMPLE_RANDOM, + err = request_irq(lp->irq, niu_interrupt, IRQF_SHARED, np->irq_name[i], lp); if (err) goto out_free_irqs; diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 348b4f1367c9..f3f737b91248 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -3468,7 +3468,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev) { struct net_device *ndev = qdev->ndev; int err; - unsigned long irq_flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED; + unsigned long irq_flags = IRQF_SHARED; unsigned long hw_flags; if (ql_alloc_mem_resources(qdev)) { diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 73c942d85f07..b7e03a6ebf25 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8839,12 +8839,12 @@ static int tg3_request_irq(struct tg3 *tp, int irq_num) fn = tg3_msi; if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) fn = tg3_msi_1shot; - flags = IRQF_SAMPLE_RANDOM; + flags = 0; } else { fn = tg3_interrupt; if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) fn = tg3_interrupt_tagged; - flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM; + flags = IRQF_SHARED; } return request_irq(tnapi->irq_vec, fn, flags, name, tnapi); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 5c8d9c385be0..c06f5a09b263 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1416,8 +1416,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) goto fail; err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt, - IRQF_SAMPLE_RANDOM, netdev->name, - netdev); + 0, netdev->name, netdev); if (err < 0) goto fail; netdev->irq = err; -- GitLab From 0a5c047507aaaf00519921336d19c0f8f5f9f363 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 31 Mar 2011 01:51:35 -0700 Subject: [PATCH 0202/5560] fib: add __rcu annotations Add __rcu annotations and lockdep checks. Add const qualifiers node_parent() and node_parent_rcu() can use rcu_dereference_index_check() Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 103 +++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b92c86f6e9b3..b9d1f33e5e04 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -126,7 +126,7 @@ struct tnode { struct work_struct work; struct tnode *tnode_free; }; - struct rt_trie_node *child[0]; + struct rt_trie_node __rcu *child[0]; }; #ifdef CONFIG_IP_FIB_TRIE_STATS @@ -151,7 +151,7 @@ struct trie_stat { }; struct trie { - struct rt_trie_node *trie; + struct rt_trie_node __rcu *trie; #ifdef CONFIG_IP_FIB_TRIE_STATS struct trie_use_stats stats; #endif @@ -177,16 +177,29 @@ static const int sync_pages = 128; static struct kmem_cache *fn_alias_kmem __read_mostly; static struct kmem_cache *trie_leaf_kmem __read_mostly; -static inline struct tnode *node_parent(struct rt_trie_node *node) +/* + * caller must hold RTNL + */ +static inline struct tnode *node_parent(const struct rt_trie_node *node) { - return (struct tnode *)(node->parent & ~NODE_TYPE_MASK); + unsigned long parent; + + parent = rcu_dereference_index_check(node->parent, lockdep_rtnl_is_held()); + + return (struct tnode *)(parent & ~NODE_TYPE_MASK); } -static inline struct tnode *node_parent_rcu(struct rt_trie_node *node) +/* + * caller must hold RCU read lock or RTNL + */ +static inline struct tnode *node_parent_rcu(const struct rt_trie_node *node) { - struct tnode *ret = node_parent(node); + unsigned long parent; + + parent = rcu_dereference_index_check(node->parent, rcu_read_lock_held() || + lockdep_rtnl_is_held()); - return rcu_dereference_rtnl(ret); + return (struct tnode *)(parent & ~NODE_TYPE_MASK); } /* Same as rcu_assign_pointer @@ -198,18 +211,24 @@ static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr) node->parent = (unsigned long)ptr | NODE_TYPE(node); } -static inline struct rt_trie_node *tnode_get_child(struct tnode *tn, unsigned int i) +/* + * caller must hold RTNL + */ +static inline struct rt_trie_node *tnode_get_child(const struct tnode *tn, unsigned int i) { BUG_ON(i >= 1U << tn->bits); - return tn->child[i]; + return rtnl_dereference(tn->child[i]); } -static inline struct rt_trie_node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) +/* + * caller must hold RCU read lock or RTNL + */ +static inline struct rt_trie_node *tnode_get_child_rcu(const struct tnode *tn, unsigned int i) { - struct rt_trie_node *ret = tnode_get_child(tn, i); + BUG_ON(i >= 1U << tn->bits); - return rcu_dereference_rtnl(ret); + return rcu_dereference_rtnl(tn->child[i]); } static inline int tnode_child_length(const struct tnode *tn) @@ -487,7 +506,7 @@ static inline void put_child(struct trie *t, struct tnode *tn, int i, static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n, int wasfull) { - struct rt_trie_node *chi = tn->child[i]; + struct rt_trie_node *chi = rtnl_dereference(tn->child[i]); int isfull; BUG_ON(i >= 1<bits); @@ -665,7 +684,7 @@ static struct rt_trie_node *resize(struct trie *t, struct tnode *tn) for (i = 0; i < tnode_child_length(tn); i++) { struct rt_trie_node *n; - n = tn->child[i]; + n = rtnl_dereference(tn->child[i]); if (!n) continue; @@ -679,6 +698,20 @@ static struct rt_trie_node *resize(struct trie *t, struct tnode *tn) return (struct rt_trie_node *) tn; } + +static void tnode_clean_free(struct tnode *tn) +{ + int i; + struct tnode *tofree; + + for (i = 0; i < tnode_child_length(tn); i++) { + tofree = (struct tnode *)rtnl_dereference(tn->child[i]); + if (tofree) + tnode_free(tofree); + } + tnode_free(tn); +} + static struct tnode *inflate(struct trie *t, struct tnode *tn) { struct tnode *oldtnode = tn; @@ -755,8 +788,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) inode = (struct tnode *) node; if (inode->bits == 1) { - put_child(t, tn, 2*i, inode->child[0]); - put_child(t, tn, 2*i+1, inode->child[1]); + put_child(t, tn, 2*i, rtnl_dereference(inode->child[0])); + put_child(t, tn, 2*i+1, rtnl_dereference(inode->child[1])); tnode_free_safe(inode); continue; @@ -797,8 +830,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) size = tnode_child_length(left); for (j = 0; j < size; j++) { - put_child(t, left, j, inode->child[j]); - put_child(t, right, j, inode->child[j + size]); + put_child(t, left, j, rtnl_dereference(inode->child[j])); + put_child(t, right, j, rtnl_dereference(inode->child[j + size])); } put_child(t, tn, 2*i, resize(t, left)); put_child(t, tn, 2*i+1, resize(t, right)); @@ -808,18 +841,8 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) tnode_free_safe(oldtnode); return tn; nomem: - { - int size = tnode_child_length(tn); - int j; - - for (j = 0; j < size; j++) - if (tn->child[j]) - tnode_free((struct tnode *)tn->child[j]); - - tnode_free(tn); - - return ERR_PTR(-ENOMEM); - } + tnode_clean_free(tn); + return ERR_PTR(-ENOMEM); } static struct tnode *halve(struct trie *t, struct tnode *tn) @@ -890,18 +913,8 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) tnode_free_safe(oldtnode); return tn; nomem: - { - int size = tnode_child_length(tn); - int j; - - for (j = 0; j < size; j++) - if (tn->child[j]) - tnode_free((struct tnode *)tn->child[j]); - - tnode_free(tn); - - return ERR_PTR(-ENOMEM); - } + tnode_clean_free(tn); + return ERR_PTR(-ENOMEM); } /* readside must use rcu_read_lock currently dump routines @@ -1033,7 +1046,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) t_key cindex; pos = 0; - n = t->trie; + n = rtnl_dereference(t->trie); /* If we point to NULL, stop. Either the tree is empty and we should * just put a new leaf in if, or we have reached an empty child slot, @@ -1756,7 +1769,7 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c) continue; if (IS_LEAF(c)) { - prefetch(p->child[idx]); + prefetch(rcu_dereference_rtnl(p->child[idx])); return (struct leaf *) c; } @@ -2272,7 +2285,7 @@ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos) /* walk rest of this hash chain */ h = tb->tb_id & (FIB_TABLE_HASHSZ - 1); - while ( (tb_node = rcu_dereference(tb->tb_hlist.next)) ) { + while ((tb_node = rcu_dereference(hlist_next_rcu(&tb->tb_hlist)))) { tb = hlist_entry(tb_node, struct fib_table, tb_hlist); n = fib_trie_get_first(iter, (struct trie *) tb->tb_data); if (n) -- GitLab From 8d1a7ed9d0ce3556a962a7472a3d09a8332d030a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 31 Mar 2011 13:35:23 +0200 Subject: [PATCH 0203/5560] CREDITS: update Johannes Berg's gpg key I've had a new key for almost two years and revoked the old one, but forgot to update it here. Signed-off-by: Johannes Berg Signed-off-by: Jiri Kosina --- CREDITS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index 1d39a6d0a510..10c180311e88 100644 --- a/CREDITS +++ b/CREDITS @@ -328,7 +328,7 @@ S: Haifa, Israel N: Johannes Berg E: johannes@sipsolutions.net W: http://johannes.sipsolutions.net/ -P: 1024D/9AB78CA5 AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5 +P: 4096R/7BF9099A C0EB C440 F6DA 091C 884D 8532 E0F3 73F3 7BF9 099A D: powerpc & 802.11 hacker N: Stephen R. van den Berg (AKA BuGless) -- GitLab From 83229aa5e2c242163599266a686483e3b91ec07e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:52:14 -0700 Subject: [PATCH 0204/5560] net: Add helper flowi4_init_output(). On-stack initialization via assignment of flow structures are expensive because GCC emits a memset() to clear the entire structure out no matter what. Add a helper for ipv4 output flow key setup which we can use to avoid the memset. Signed-off-by: David S. Miller --- include/net/flow.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/net/flow.h b/include/net/flow.h index 7fe5a0f9483a..37e77d66f78c 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -70,6 +70,27 @@ struct flowi4 { #define fl4_gre_key uli.gre_key }; +static inline void flowi4_init_output(struct flowi4 *fl4, int oif, + __u32 mark, __u8 tos, __u8 scope, + __u8 proto, __u8 flags, + __be32 daddr, __be32 saddr, + __be16 dport, __be32 sport) +{ + fl4->flowi4_oif = oif; + fl4->flowi4_iif = 0; + fl4->flowi4_mark = mark; + fl4->flowi4_tos = tos; + fl4->flowi4_scope = scope; + fl4->flowi4_proto = proto; + fl4->flowi4_flags = flags; + fl4->flowi4_secid = 0; + fl4->daddr = daddr; + fl4->saddr = saddr; + fl4->fl4_sport = sport; + fl4->fl4_dport = dport; +} + + struct flowi6 { struct flowi_common __fl_common; #define flowi6_oif __fl_common.flowic_oif -- GitLab From 94b92b88344641dbeadd2ef371549b7663a48fb1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:52:59 -0700 Subject: [PATCH 0205/5560] ipv4: Use flowi4_init_output() in net/route.h Signed-off-by: David S. Miller --- include/net/route.h | 60 ++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index f88429cad52a..b24288595e58 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -149,17 +149,12 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock __be16 dport, __be16 sport, __u8 proto, __u8 tos, int oif) { - struct flowi4 fl4 = { - .flowi4_oif = oif, - .flowi4_flags = sk ? inet_sk_flowi_flags(sk) : 0, - .flowi4_mark = sk ? sk->sk_mark : 0, - .daddr = daddr, - .saddr = saddr, - .flowi4_tos = tos, - .flowi4_proto = proto, - .fl4_dport = dport, - .fl4_sport = sport, - }; + struct flowi4 fl4; + + flowi4_init_output(&fl4, oif, sk ? sk->sk_mark : 0, tos, + RT_SCOPE_UNIVERSE, proto, + sk ? inet_sk_flowi_flags(sk) : 0, + daddr, saddr, dport, sport); if (sk) security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); return ip_route_output_flow(net, &fl4, sk); @@ -229,25 +224,21 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, __be16 sport, __be16 dport, struct sock *sk, bool can_sleep) { - struct flowi4 fl4 = { - .flowi4_oif = oif, - .flowi4_mark = sk->sk_mark, - .daddr = dst, - .saddr = src, - .flowi4_tos = tos, - .flowi4_proto = protocol, - .fl4_sport = sport, - .fl4_dport = dport, - }; struct net *net = sock_net(sk); struct rtable *rt; + struct flowi4 fl4; + __u8 flow_flags; + flow_flags = 0; if (inet_sk(sk)->transparent) - fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + flow_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS; + flow_flags |= FLOWI_FLAG_PRECOW_METRICS; if (can_sleep) - fl4.flowi4_flags |= FLOWI_FLAG_CAN_SLEEP; + flow_flags |= FLOWI_FLAG_CAN_SLEEP; + + flowi4_init_output(&fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, + protocol, flow_flags, dst, src, dport, sport); if (!dst || !src) { rt = __ip_route_output_key(net, &fl4); @@ -267,20 +258,17 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi4 fl4 = { - .flowi4_oif = rt->rt_oif, - .flowi4_mark = rt->rt_mark, - .daddr = rt->rt_dst, - .saddr = rt->rt_src, - .flowi4_tos = rt->rt_tos, - .flowi4_proto = protocol, - .fl4_sport = sport, - .fl4_dport = dport - }; + struct flowi4 fl4; + __u8 flow_flags; + + flow_flags = 0; if (inet_sk(sk)->transparent) - fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + flow_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS; + flow_flags |= FLOWI_FLAG_PRECOW_METRICS; + flowi4_init_output(&fl4, rt->rt_oif, rt->rt_mark, rt->rt_tos, + RT_SCOPE_UNIVERSE, protocol, flow_flags, + rt->rt_dst, rt->rt_src, dport, sport); ip_rt_put(rt); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); return ip_route_output_flow(sock_net(sk), &fl4, sk); -- GitLab From e79d9bc7ea76e08fc24d7adaad8b6a821d1624c3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:53:20 -0700 Subject: [PATCH 0206/5560] ipv4: Use flowi4_init_output() in inet_connection_sock.c Signed-off-by: David S. Miller --- net/ipv4/inet_connection_sock.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 6c0b7f4a3d7d..f784608a4c45 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -356,20 +356,14 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct rtable *rt; const struct inet_request_sock *ireq = inet_rsk(req); struct ip_options *opt = inet_rsk(req)->opt; - struct flowi4 fl4 = { - .flowi4_oif = sk->sk_bound_dev_if, - .flowi4_mark = sk->sk_mark, - .daddr = ((opt && opt->srr) ? - opt->faddr : ireq->rmt_addr), - .saddr = ireq->loc_addr, - .flowi4_tos = RT_CONN_FLAGS(sk), - .flowi4_proto = sk->sk_protocol, - .flowi4_flags = inet_sk_flowi_flags(sk), - .fl4_sport = inet_sk(sk)->inet_sport, - .fl4_dport = ireq->rmt_port, - }; struct net *net = sock_net(sk); + struct flowi4 fl4; + flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark, + RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, + sk->sk_protocol, inet_sk_flowi_flags(sk), + (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, + ireq->loc_addr, ireq->rmt_port, inet_sk(sk)->inet_sport); security_req_classify_flow(req, flowi4_to_flowi(&fl4)); rt = ip_route_output_flow(net, &fl4, sk); if (IS_ERR(rt)) -- GitLab From 538de0e01f1ca3568ad03877ff297c646dd8ad23 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:53:37 -0700 Subject: [PATCH 0207/5560] ipv4: Use flowi4_init_output() in ip_send_reply() Signed-off-by: David S. Miller --- net/ipv4/ip_output.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 67f241b97649..86a284308271 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1474,16 +1474,14 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar } { - struct flowi4 fl4 = { - .flowi4_oif = arg->bound_dev_if, - .daddr = daddr, - .saddr = rt->rt_spec_dst, - .flowi4_tos = RT_TOS(ip_hdr(skb)->tos), - .fl4_sport = tcp_hdr(skb)->dest, - .fl4_dport = tcp_hdr(skb)->source, - .flowi4_proto = sk->sk_protocol, - .flowi4_flags = ip_reply_arg_flowi_flags(arg), - }; + struct flowi4 fl4; + + flowi4_init_output(&fl4, arg->bound_dev_if, 0, + RT_TOS(ip_hdr(skb)->tos), + RT_SCOPE_UNIVERSE, sk->sk_protocol, + ip_reply_arg_flowi_flags(arg), + daddr, rt->rt_spec_dst, + tcp_hdr(skb)->source, tcp_hdr(skb)->dest); security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(sock_net(sk), &fl4); if (IS_ERR(rt)) -- GitLab From ef164ae3563bf4d291b6f75ca2e120b17d606963 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:53:51 -0700 Subject: [PATCH 0208/5560] ipv4: Use flowi4_init_output() in raw_sendmsg() Signed-off-by: David S. Miller --- net/ipv4/raw.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 2d3c72e5bbbf..7d32d9d57152 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -548,17 +548,13 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } { - struct flowi4 fl4 = { - .flowi4_oif = ipc.oif, - .flowi4_mark = sk->sk_mark, - .daddr = daddr, - .saddr = saddr, - .flowi4_tos = tos, - .flowi4_proto = (inet->hdrincl ? - IPPROTO_RAW : - sk->sk_protocol), - .flowi4_flags = FLOWI_FLAG_CAN_SLEEP, - }; + struct flowi4 fl4; + + flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, + RT_SCOPE_UNIVERSE, + inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, + FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); + if (!inet->hdrincl) { err = raw_probe_proto_opt(&fl4, msg); if (err) -- GitLab From 1bba6ffeeb44480ddbdda912cc85ad2cfd4725ae Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:54:08 -0700 Subject: [PATCH 0209/5560] ipv4: Use flowi4_init_output() in cookie_v4_check() Signed-off-by: David S. Miller --- net/ipv4/syncookies.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 8b44c6d2a79b..71e029691908 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -345,17 +345,13 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, * no easy way to do this. */ { - struct flowi4 fl4 = { - .flowi4_mark = sk->sk_mark, - .daddr = ((opt && opt->srr) ? - opt->faddr : ireq->rmt_addr), - .saddr = ireq->loc_addr, - .flowi4_tos = RT_CONN_FLAGS(sk), - .flowi4_proto = IPPROTO_TCP, - .flowi4_flags = inet_sk_flowi_flags(sk), - .fl4_sport = th->dest, - .fl4_dport = th->source, - }; + struct flowi4 fl4; + + flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), + RT_SCOPE_UNIVERSE, IPPROTO_TCP, + inet_sk_flowi_flags(sk), + (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, + ireq->loc_addr, th->source, th->dest); security_req_classify_flow(req, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(sock_net(sk), &fl4); if (IS_ERR(rt)) { -- GitLab From c0951cbcfd7142003bc683046ef78a53c66d3265 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:54:27 -0700 Subject: [PATCH 0210/5560] ipv4: Use flowi4_init_output() in udp_sendmsg() Signed-off-by: David S. Miller --- net/ipv4/udp.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 588f47af5faf..ac66132b8edf 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -909,20 +909,14 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, rt = (struct rtable *)sk_dst_check(sk, 0); if (rt == NULL) { - struct flowi4 fl4 = { - .flowi4_oif = ipc.oif, - .flowi4_mark = sk->sk_mark, - .daddr = faddr, - .saddr = saddr, - .flowi4_tos = tos, - .flowi4_proto = sk->sk_protocol, - .flowi4_flags = (inet_sk_flowi_flags(sk) | - FLOWI_FLAG_CAN_SLEEP), - .fl4_sport = inet->inet_sport, - .fl4_dport = dport, - }; + struct flowi4 fl4; struct net *net = sock_net(sk); + flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, + RT_SCOPE_UNIVERSE, sk->sk_protocol, + inet_sk_flowi_flags(sk)|FLOWI_FLAG_CAN_SLEEP, + faddr, saddr, dport, inet->inet_sport); + security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); rt = ip_route_output_flow(net, &fl4, sk); if (IS_ERR(rt)) { -- GitLab From f0681a68dd3a32699891cd1de93459aee5af7728 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 16 Mar 2011 21:06:52 -0300 Subject: [PATCH 0211/5560] Bluetooth: remove unnecessary function declaration hci_notify() doesn't need declaration first. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b372fb8bcdcf..c20cbe5ff6db 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -56,7 +56,6 @@ static void hci_cmd_task(unsigned long arg); static void hci_rx_task(unsigned long arg); static void hci_tx_task(unsigned long arg); -static void hci_notify(struct hci_dev *hdev, int event); static DEFINE_RWLOCK(hci_task_lock); -- GitLab From 1f6c6378c59f3ddac9ed89a68ccefe2611300c09 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 16 Mar 2011 14:29:35 +0200 Subject: [PATCH 0212/5560] Bluetooth: Add define for the maximum name length on HCI level This patch adds a clear define for the maximum device name length in HCI messages and thereby avoids magic numbers in the code. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 8 +++++--- include/net/bluetooth/hci_core.h | 2 +- net/bluetooth/hci_event.c | 4 ++-- net/bluetooth/hci_sysfs.c | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ec6acf2f1c0b..1cd031cd1c4d 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -535,15 +535,17 @@ struct hci_cp_delete_stored_link_key { __u8 delete_all; } __packed; +#define HCI_MAX_NAME_LENGTH 248 + #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 struct hci_cp_write_local_name { - __u8 name[248]; + __u8 name[HCI_MAX_NAME_LENGTH]; } __packed; #define HCI_OP_READ_LOCAL_NAME 0x0c14 struct hci_rp_read_local_name { __u8 status; - __u8 name[248]; + __u8 name[HCI_MAX_NAME_LENGTH]; } __packed; #define HCI_OP_WRITE_CA_TIMEOUT 0x0c16 @@ -745,7 +747,7 @@ struct hci_ev_auth_complete { struct hci_ev_remote_name { __u8 status; bdaddr_t bdaddr; - __u8 name[248]; + __u8 name[HCI_MAX_NAME_LENGTH]; } __packed; #define HCI_EV_ENCRYPT_CHANGE 0x08 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 441dadbf6a89..9aabb14982dd 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -94,7 +94,7 @@ struct hci_dev { __u8 bus; __u8 dev_type; bdaddr_t bdaddr; - __u8 dev_name[248]; + __u8 dev_name[HCI_MAX_NAME_LENGTH]; __u8 dev_class[3]; __u8 major_class; __u8 minor_class; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3fbfa50c2bff..91ef52673ed3 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -200,7 +200,7 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; - memcpy(hdev->dev_name, sent, 248); + memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); } static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) @@ -212,7 +212,7 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) if (rp->status) return; - memcpy(hdev->dev_name, rp->name, 248); + memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); } static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 3c838a65a75a..e54421693eb8 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -216,13 +216,13 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, char static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); - char name[249]; + char name[HCI_MAX_NAME_LENGTH + 1]; int i; - for (i = 0; i < 248; i++) + for (i = 0; i < HCI_MAX_NAME_LENGTH; i++) name[i] = hdev->dev_name[i]; - name[248] = '\0'; + name[HCI_MAX_NAME_LENGTH] = '\0'; return sprintf(buf, "%s\n", name); } -- GitLab From dc4fe30b8675033e538e2dea50be8af9c75f1b6a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 16 Mar 2011 14:29:36 +0200 Subject: [PATCH 0213/5560] Bluetooth: mgmt: Add local name information to read_info reply This patch adds the name of the adapter to the reply of the read_info management command. The management messages reserve 249 bytes for the name instead of 248 (like in the HCI spec) so that there is always a guarantee that it is nul-terminated. That way it can safely be passed onto string manipulation functions. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/mgmt.h | 5 +++++ net/bluetooth/mgmt.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 5fabfa886b3e..7d0749bed090 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -41,6 +41,10 @@ struct mgmt_rp_read_index_list { __le16 index[0]; } __packed; +/* Reserve one extra byte for names in management messages so that they + * are always guaranteed to be nul-terminated */ +#define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1) + #define MGMT_OP_READ_INFO 0x0004 struct mgmt_rp_read_info { __u8 type; @@ -55,6 +59,7 @@ struct mgmt_rp_read_info { __u16 manufacturer; __u8 hci_ver; __u16 hci_rev; + __u8 name[MGMT_MAX_NAME_LENGTH]; } __packed; struct mgmt_mode { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0054c74e27b7..ffdb2f4e8635 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -183,6 +183,8 @@ static int read_controller_info(struct sock *sk, u16 index) set_bit(HCI_MGMT, &hdev->flags); + memset(&rp, 0, sizeof(rp)); + rp.type = hdev->dev_type; rp.powered = test_bit(HCI_UP, &hdev->flags); @@ -204,6 +206,8 @@ static int read_controller_info(struct sock *sk, u16 index) rp.hci_ver = hdev->hci_ver; put_unaligned_le16(hdev->hci_rev, &rp.hci_rev); + memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name)); + hci_dev_unlock_bh(hdev); hci_dev_put(hdev); -- GitLab From b312b161ecb833b1bce5c4a97853f4a4f40c7901 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 16 Mar 2011 14:29:37 +0200 Subject: [PATCH 0214/5560] Bluetooth: mgmt: Add support for setting the local name This patch adds a new set_local_name management command as well as a local_name_changed management event. With these user space can both change the local name as well as monitor changes to it by others. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 1 + include/net/bluetooth/mgmt.h | 10 +++++ net/bluetooth/hci_event.c | 9 ++-- net/bluetooth/mgmt.c | 75 ++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 3 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 9aabb14982dd..3912c7ab717c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -767,6 +767,7 @@ int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status); +int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status); /* 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 7d0749bed090..89e7c82c4784 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -172,6 +172,11 @@ struct mgmt_rp_user_confirm_reply { #define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016 +#define MGMT_OP_SET_LOCAL_NAME 0x0017 +struct mgmt_cp_set_local_name { + __u8 name[MGMT_MAX_NAME_LENGTH]; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; @@ -239,3 +244,8 @@ struct mgmt_ev_auth_failed { bdaddr_t bdaddr; __u8 status; } __packed; + +#define MGMT_EV_LOCAL_NAME_CHANGED 0x0011 +struct mgmt_ev_local_name_changed { + __u8 name[MGMT_MAX_NAME_LENGTH]; +} __packed; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 91ef52673ed3..0def3e1fe5ef 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -193,13 +193,16 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - return; - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); if (!sent) return; + if (test_bit(HCI_MGMT, &hdev->flags)) + mgmt_set_local_name_complete(hdev->id, sent, status); + + if (status) + return; + memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); } diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index ffdb2f4e8635..f7ce78235590 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1256,6 +1256,45 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, return err; } +static int set_local_name(struct sock *sk, u16 index, unsigned char *data, + u16 len) +{ + struct mgmt_cp_set_local_name *mgmt_cp = (void *) data; + struct hci_cp_write_local_name hci_cp; + struct hci_dev *hdev; + struct pending_cmd *cmd; + int err; + + BT_DBG(""); + + if (len != sizeof(*mgmt_cp)) + return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, EINVAL); + + hdev = hci_dev_get(index); + if (!hdev) + return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV); + + hci_dev_lock_bh(hdev); + + cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); + if (!cmd) { + err = -ENOMEM; + goto failed; + } + + memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name)); + err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp), + &hci_cp); + if (err < 0) + mgmt_pending_remove(cmd); + +failed: + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + + return err; +} + int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) { unsigned char *buf; @@ -1351,6 +1390,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) case MGMT_OP_USER_CONFIRM_NEG_REPLY: err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0); break; + case MGMT_OP_SET_LOCAL_NAME: + err = set_local_name(sk, index, buf + sizeof(*hdr), len); + break; default: BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, index, opcode, 0x01); @@ -1647,3 +1689,36 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL); } + +int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) +{ + struct pending_cmd *cmd; + struct mgmt_cp_set_local_name ev; + int err; + + memset(&ev, 0, sizeof(ev)); + memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); + + cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index); + if (!cmd) + goto send_event; + + if (status) { + err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO); + goto failed; + } + + err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev, + sizeof(ev)); + if (err < 0) + goto failed; + +send_event: + err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev), + cmd ? cmd->sk : NULL); + +failed: + if (cmd) + mgmt_pending_remove(cmd); + return err; +} -- GitLab From b0d2199d6ff9f788b324fe54b1f783aff83502c4 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 22 Mar 2011 18:06:49 -0300 Subject: [PATCH 0215/5560] Bluetooth: Remove unused struct item num in struct l2cap_chan_list isn't used anywhere. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 4f4bff1eaed6..7a0262524a50 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -280,7 +280,6 @@ struct l2cap_conn_param_update_rsp { struct l2cap_chan_list { struct sock *head; rwlock_t lock; - long num; }; struct l2cap_conn { -- GitLab From 2c6d1a2eec5c49793c6760546d05515ce1b76881 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 23 Mar 2011 14:38:32 -0300 Subject: [PATCH 0216/5560] Bluetooth: Improve error message on wrong link type Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c9f9cecca527..b5a1ce06e1c0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2670,7 +2670,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, if (err) { struct l2cap_cmd_rej rej; - BT_DBG("error %d", err); + + BT_ERR("Wrong link type (%d)", err); /* FIXME: Map err to a valid reason */ rej.reason = cpu_to_le16(0); -- GitLab From a3d9bd4c00f13defd4c0fdcf8b47f8764a69e54d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:19:57 +0100 Subject: [PATCH 0217/5560] Bluetooth: Opencode macros in bnep/core.c BNEP_RX_TYPES and INCA macros have only one user each and don't provide any benefits compared to opencoding them. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/core.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 03d4d1245d58..940b4e129741 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -187,6 +187,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) n /= (ETH_ALEN * 2); if (n > 0) { + int i; + s->mc_filter = 0; /* Always send broadcast */ @@ -202,12 +204,14 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) BT_DBG("mc filter %s -> %s", batostr((void *) a1), batostr((void *) a2)); - #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); } - /* Iterate from a1 to a2 */ set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) { - INCA(a1); + /* Increment a1 */ + i = 5; + while (i >= 0 && ++a1[i--] == 0) + ; + set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); } } @@ -302,7 +306,6 @@ static u8 __bnep_rx_hlen[] = { ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */ ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */ }; -#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1) static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) { @@ -314,7 +317,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) type = *(u8 *) skb->data; skb_pull(skb, 1); - if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES) + if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) goto badframe; if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) { -- GitLab From 3aad75a128e2f2b8da31de1df4b9b9b4a8f65c66 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:19:58 +0100 Subject: [PATCH 0218/5560] Bluetooth: Fix checkpatch errors and some code style issues in bnep Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/bnep.h | 146 +++++++++++++++++++------------------- net/bluetooth/bnep/core.c | 37 +++++----- 2 files changed, 94 insertions(+), 89 deletions(-) diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 70672544db86..d768e0434ed8 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h @@ -23,88 +23,88 @@ #include #include -// Limits -#define BNEP_MAX_PROTO_FILTERS 5 -#define BNEP_MAX_MULTICAST_FILTERS 20 - -// UUIDs -#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB -#define BNEP_UUID16 0x02 -#define BNEP_UUID32 0x04 -#define BNEP_UUID128 0x16 - -#define BNEP_SVC_PANU 0x1115 -#define BNEP_SVC_NAP 0x1116 -#define BNEP_SVC_GN 0x1117 - -// Packet types -#define BNEP_GENERAL 0x00 -#define BNEP_CONTROL 0x01 -#define BNEP_COMPRESSED 0x02 -#define BNEP_COMPRESSED_SRC_ONLY 0x03 -#define BNEP_COMPRESSED_DST_ONLY 0x04 - -// Control types -#define BNEP_CMD_NOT_UNDERSTOOD 0x00 -#define BNEP_SETUP_CONN_REQ 0x01 -#define BNEP_SETUP_CONN_RSP 0x02 -#define BNEP_FILTER_NET_TYPE_SET 0x03 -#define BNEP_FILTER_NET_TYPE_RSP 0x04 -#define BNEP_FILTER_MULTI_ADDR_SET 0x05 -#define BNEP_FILTER_MULTI_ADDR_RSP 0x06 - -// Extension types -#define BNEP_EXT_CONTROL 0x00 - -// Response messages -#define BNEP_SUCCESS 0x00 - -#define BNEP_CONN_INVALID_DST 0x01 -#define BNEP_CONN_INVALID_SRC 0x02 -#define BNEP_CONN_INVALID_SVC 0x03 -#define BNEP_CONN_NOT_ALLOWED 0x04 - -#define BNEP_FILTER_UNSUPPORTED_REQ 0x01 -#define BNEP_FILTER_INVALID_RANGE 0x02 -#define BNEP_FILTER_INVALID_MCADDR 0x02 -#define BNEP_FILTER_LIMIT_REACHED 0x03 -#define BNEP_FILTER_DENIED_SECURITY 0x04 - -// L2CAP settings -#define BNEP_MTU 1691 -#define BNEP_PSM 0x0f -#define BNEP_FLUSH_TO 0xffff -#define BNEP_CONNECT_TO 15 -#define BNEP_FILTER_TO 15 - -// Headers -#define BNEP_TYPE_MASK 0x7f -#define BNEP_EXT_HEADER 0x80 +/* Limits */ +#define BNEP_MAX_PROTO_FILTERS 5 +#define BNEP_MAX_MULTICAST_FILTERS 20 + +/* UUIDs */ +#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB +#define BNEP_UUID16 0x02 +#define BNEP_UUID32 0x04 +#define BNEP_UUID128 0x16 + +#define BNEP_SVC_PANU 0x1115 +#define BNEP_SVC_NAP 0x1116 +#define BNEP_SVC_GN 0x1117 + +/* Packet types */ +#define BNEP_GENERAL 0x00 +#define BNEP_CONTROL 0x01 +#define BNEP_COMPRESSED 0x02 +#define BNEP_COMPRESSED_SRC_ONLY 0x03 +#define BNEP_COMPRESSED_DST_ONLY 0x04 + +/* Control types */ +#define BNEP_CMD_NOT_UNDERSTOOD 0x00 +#define BNEP_SETUP_CONN_REQ 0x01 +#define BNEP_SETUP_CONN_RSP 0x02 +#define BNEP_FILTER_NET_TYPE_SET 0x03 +#define BNEP_FILTER_NET_TYPE_RSP 0x04 +#define BNEP_FILTER_MULTI_ADDR_SET 0x05 +#define BNEP_FILTER_MULTI_ADDR_RSP 0x06 + +/* Extension types */ +#define BNEP_EXT_CONTROL 0x00 + +/* Response messages */ +#define BNEP_SUCCESS 0x00 + +#define BNEP_CONN_INVALID_DST 0x01 +#define BNEP_CONN_INVALID_SRC 0x02 +#define BNEP_CONN_INVALID_SVC 0x03 +#define BNEP_CONN_NOT_ALLOWED 0x04 + +#define BNEP_FILTER_UNSUPPORTED_REQ 0x01 +#define BNEP_FILTER_INVALID_RANGE 0x02 +#define BNEP_FILTER_INVALID_MCADDR 0x02 +#define BNEP_FILTER_LIMIT_REACHED 0x03 +#define BNEP_FILTER_DENIED_SECURITY 0x04 + +/* L2CAP settings */ +#define BNEP_MTU 1691 +#define BNEP_PSM 0x0f +#define BNEP_FLUSH_TO 0xffff +#define BNEP_CONNECT_TO 15 +#define BNEP_FILTER_TO 15 + +/* Headers */ +#define BNEP_TYPE_MASK 0x7f +#define BNEP_EXT_HEADER 0x80 struct bnep_setup_conn_req { - __u8 type; - __u8 ctrl; - __u8 uuid_size; - __u8 service[0]; + __u8 type; + __u8 ctrl; + __u8 uuid_size; + __u8 service[0]; } __packed; struct bnep_set_filter_req { - __u8 type; - __u8 ctrl; + __u8 type; + __u8 ctrl; __be16 len; - __u8 list[0]; + __u8 list[0]; } __packed; struct bnep_control_rsp { - __u8 type; - __u8 ctrl; + __u8 type; + __u8 ctrl; __be16 resp; } __packed; struct bnep_ext_hdr { - __u8 type; - __u8 len; - __u8 data[0]; + __u8 type; + __u8 len; + __u8 data[0]; } __packed; /* BNEP ioctl defines */ @@ -114,10 +114,10 @@ struct bnep_ext_hdr { #define BNEPGETCONNINFO _IOR('B', 211, int) struct bnep_connadd_req { - int sock; // Connected socket + int sock; /* Connected socket */ __u32 flags; __u16 role; - char device[16]; // Name of the Ethernet device + char device[16]; /* Name of the Ethernet device */ }; struct bnep_conndel_req { @@ -148,7 +148,7 @@ int bnep_del_connection(struct bnep_conndel_req *req); int bnep_get_connlist(struct bnep_connlist_req *req); int bnep_get_conninfo(struct bnep_conninfo *ci); -// BNEP sessions +/* BNEP sessions */ struct bnep_session { struct list_head list; @@ -173,7 +173,7 @@ void bnep_sock_cleanup(void); static inline int bnep_mc_hash(__u8 *addr) { - return (crc32_be(~0, addr, ETH_ALEN) >> 26); + return crc32_be(~0, addr, ETH_ALEN) >> 26; } #endif diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 940b4e129741..0a2e76bde542 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -131,7 +131,8 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len return -EILSEQ; n = get_unaligned_be16(data); - data++; len -= 2; + data++; + len -= 2; if (len < n) return -EILSEQ; @@ -176,7 +177,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) return -EILSEQ; n = get_unaligned_be16(data); - data += 2; len -= 2; + data += 2; + len -= 2; if (len < n) return -EILSEQ; @@ -198,8 +200,10 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) for (; n > 0; n--) { u8 a1[6], *a2; - memcpy(a1, data, ETH_ALEN); data += ETH_ALEN; - a2 = data; data += ETH_ALEN; + memcpy(a1, data, ETH_ALEN); + data += ETH_ALEN; + a2 = data; + data += ETH_ALEN; BT_DBG("mc filter %s -> %s", batostr((void *) a1), batostr((void *) a2)); @@ -231,7 +235,8 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len) u8 cmd = *(u8 *)data; int err = 0; - data++; len--; + data++; + len--; switch (cmd) { case BNEP_CMD_NOT_UNDERSTOOD: @@ -315,7 +320,8 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) dev->stats.rx_bytes += skb->len; - type = *(u8 *) skb->data; skb_pull(skb, 1); + type = *(u8 *) skb->data; + skb_pull(skb, 1); if ((type & BNEP_TYPE_MASK) >= sizeof(__bnep_rx_hlen)) goto badframe; @@ -370,14 +376,14 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) case BNEP_COMPRESSED_DST_ONLY: memcpy(__skb_put(nskb, ETH_ALEN), skb_mac_header(skb), - ETH_ALEN); + ETH_ALEN); memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, - ETH_ALEN + 2); + ETH_ALEN + 2); break; case BNEP_GENERAL: memcpy(__skb_put(nskb, ETH_ALEN * 2), skb_mac_header(skb), - ETH_ALEN * 2); + ETH_ALEN * 2); put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2)); break; } @@ -481,7 +487,7 @@ static int bnep_session(void *arg) while (!atomic_read(&s->killed)) { set_current_state(TASK_INTERRUPTIBLE); - // RX + /* RX */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { skb_orphan(skb); bnep_rx_frame(s, skb); @@ -490,7 +496,7 @@ static int bnep_session(void *arg) if (sk->sk_state != BT_CONNECTED) break; - // TX + /* TX */ while ((skb = skb_dequeue(&sk->sk_write_queue))) if (bnep_tx_frame(s, skb)) break; @@ -558,8 +564,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) /* session struct allocated as private part of net_device */ dev = alloc_netdev(sizeof(struct bnep_session), - (*req->device) ? req->device : "bnep%d", - bnep_net_setup); + (*req->device) ? req->device : "bnep%d", + bnep_net_setup); if (!dev) return -ENOMEM; @@ -574,7 +580,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) s = netdev_priv(dev); /* This is rx header therefore addresses are swapped. - * ie eh.h_dest is our local address. */ + * ie. eh.h_dest is our local address. */ memcpy(s->eh.h_dest, &src, ETH_ALEN); memcpy(s->eh.h_source, &dst, ETH_ALEN); memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN); @@ -600,9 +606,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) SET_NETDEV_DEVTYPE(dev, &bnep_type); err = register_netdev(dev); - if (err) { + if (err) goto failed; - } __bnep_link_session(s); -- GitLab From 8c20aa9ffc5a5ef52b6148e905671a8d12b40c87 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:19:59 +0100 Subject: [PATCH 0219/5560] Bluetooth: Use #include instead of As warned by checkpatch.pl, use #include instead of Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index d935da71ab3b..17800b1d28ea 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -39,10 +39,10 @@ #include #include #include +#include #include #include -#include #include "bnep.h" -- GitLab From 17f09a7e4ec5dd6a0d96498da6bf78762fba4468 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:20:01 +0100 Subject: [PATCH 0220/5560] Bluetooth: Fix checkpatch errors, code style issues and typos in hidp Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 37 ++++++++++++++++++++----------------- net/bluetooth/hidp/hidp.h | 4 ++-- net/bluetooth/hidp/sock.c | 7 ++++--- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 5ec12971af6b..a1472b75d628 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -55,22 +55,24 @@ static DECLARE_RWSEM(hidp_session_sem); static LIST_HEAD(hidp_session_list); static unsigned char hidp_keycode[256] = { - 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, - 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, - 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, - 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, - 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, - 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, - 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0, - 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, - 150,158,159,128,136,177,178,176,142,152,173,140 + 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, + 37, 38, 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, + 21, 44, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, + 14, 15, 57, 12, 13, 26, 27, 43, 43, 39, 40, 41, 51, 52, + 53, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 87, 88, + 99, 70, 119, 110, 102, 104, 111, 107, 109, 106, 105, 108, 103, 69, + 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, 72, 73, + 82, 83, 86, 127, 116, 117, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 134, 138, 130, 132, 128, 129, 131, 137, 133, 135, + 136, 113, 115, 114, 0, 0, 0, 121, 0, 89, 93, 124, 92, 94, + 95, 0, 0, 0, 122, 123, 90, 91, 85, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 42, 56, 125, 97, 54, 100, 126, 164, 166, 165, 163, 161, 115, + 114, 113, 150, 158, 159, 128, 136, 177, 178, 176, 142, 152, 173, 140 }; static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; @@ -721,7 +723,8 @@ static int hidp_session(void *arg) while (!atomic_read(&session->terminate)) { set_current_state(TASK_INTERRUPTIBLE); - if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED) + if (ctrl_sk->sk_state != BT_CONNECTED || + intr_sk->sk_state != BT_CONNECTED) break; while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index 13de5fa03480..b412e7152eec 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h @@ -84,8 +84,8 @@ #define HIDP_WAITING_FOR_SEND_ACK 11 struct hidp_connadd_req { - int ctrl_sock; // Connected control socket - int intr_sock; // Connteted interrupt socket + int ctrl_sock; /* Connected control socket */ + int intr_sock; /* Connected interrupt socket */ __u16 parser; __u16 rd_size; __u8 __user *rd_data; diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 250dfd46237d..178ac7f127ad 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -85,7 +85,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long return err; } - if (csock->sk->sk_state != BT_CONNECTED || isock->sk->sk_state != BT_CONNECTED) { + if (csock->sk->sk_state != BT_CONNECTED || + isock->sk->sk_state != BT_CONNECTED) { sockfd_put(csock); sockfd_put(isock); return -EBADFD; @@ -140,8 +141,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long #ifdef CONFIG_COMPAT struct compat_hidp_connadd_req { - int ctrl_sock; // Connected control socket - int intr_sock; // Connteted interrupt socket + int ctrl_sock; /* Connected control socket */ + int intr_sock; /* Connected interrupt socket */ __u16 parser; __u16 rd_size; compat_uptr_t rd_data; -- GitLab From 58aac468be411f2a9b4a28f2ed8e6e2a0db04267 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:20:03 +0100 Subject: [PATCH 0221/5560] Bluetooth: Do not use assignments in IF conditions Fix checkpatch warnings concerning assignments in if conditions. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 964ea9126f9f..16aa6bd039ba 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -235,9 +235,12 @@ static void cmtp_process_transmit(struct cmtp_session *session) size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len); - if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) { - skb_queue_head(&session->transmit, skb); - break; + if (scb->id < 0) { + scb->id = cmtp_alloc_block_id(session); + if (scb->id < 0) { + skb_queue_head(&session->transmit, skb); + break; + } } if (size < 256) { -- GitLab From ffd13320aa96e07f3048ebdcc603aaf38bed0c47 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:20:04 +0100 Subject: [PATCH 0222/5560] Bluetooth: Use #include instead of As warned by checkpatch.pl, use #include instead of Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 7ea1979a8e4f..3f2dd5c25ae5 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -34,12 +34,12 @@ #include #include #include +#include #include #include #include -#include #include "cmtp.h" -- GitLab From e0e185efbad442a659657c152a9cd9b3fdcb43f2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:20:05 +0100 Subject: [PATCH 0223/5560] Bluetooth: Fix checkpatch error in cmtp.h Do not use C99 // comments. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/cmtp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index 785e79e953c5..c6f78f89415c 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h @@ -37,7 +37,7 @@ #define CMTP_LOOPBACK 0 struct cmtp_connadd_req { - int sock; // Connected socket + int sock; /* Connected socket */ __u32 flags; }; -- GitLab From c68fb7ff29622a7db8264f939f94e37330c27080 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Mar 2011 13:12:19 +0100 Subject: [PATCH 0224/5560] Bluetooth: Rename cmd to param in pending_cmd This field holds not whole command but only command specific parameters. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f7ce78235590..d0c01230bba9 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -36,7 +36,7 @@ struct pending_cmd { struct list_head list; __u16 opcode; int index; - void *cmd; + void *param; struct sock *sk; void *user_data; }; @@ -217,7 +217,7 @@ static int read_controller_info(struct sock *sk, u16 index) static void mgmt_pending_free(struct pending_cmd *cmd) { sock_put(cmd->sk); - kfree(cmd->cmd); + kfree(cmd->param); kfree(cmd); } @@ -233,13 +233,13 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, cmd->opcode = opcode; cmd->index = index; - cmd->cmd = kmalloc(len, GFP_ATOMIC); - if (!cmd->cmd) { + cmd->param = kmalloc(len, GFP_ATOMIC); + if (!cmd->param) { kfree(cmd); return NULL; } - memcpy(cmd->cmd, data, len); + memcpy(cmd->param, data, len); cmd->sk = sk; sock_hold(sk); @@ -1426,7 +1426,7 @@ struct cmd_lookup { static void mode_rsp(struct pending_cmd *cmd, void *data) { - struct mgmt_mode *cp = cmd->cmd; + struct mgmt_mode *cp = cmd->param; struct cmd_lookup *match = data; if (cp->val != match->val) @@ -1525,7 +1525,7 @@ int mgmt_connected(u16 index, bdaddr_t *bdaddr) static void disconnect_rsp(struct pending_cmd *cmd, void *data) { - struct mgmt_cp_disconnect *cp = cmd->cmd; + struct mgmt_cp_disconnect *cp = cmd->param; struct sock **sk = data; struct mgmt_rp_disconnect rp; -- GitLab From 8fce6357a9e72c4c9c846f9951895954bfb34ad1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Mar 2011 13:12:20 +0100 Subject: [PATCH 0225/5560] Bluetooth: Allow for NULL data in mgmt_pending_add Since index is in mgmt_hdr it is possible to have mgmt command with no parameters that still needs to add itself to pending list. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d0c01230bba9..93f0f04c8bcd 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -239,7 +239,8 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, return NULL; } - memcpy(cmd->param, data, len); + if (data) + memcpy(cmd->param, data, len); cmd->sk = sk; sock_hold(sk); -- GitLab From c35938b2f56547ee77b5a038fe0db394aeac59bb Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Mar 2011 13:12:21 +0100 Subject: [PATCH 0226/5560] Bluetooth: Add read_local_oob_data management command This patch adds a command to read local OOB data to the managment interface. The command maps directly to the Read Local OOB Data HCI command. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 7 +++ include/net/bluetooth/hci_core.h | 2 + include/net/bluetooth/mgmt.h | 6 +++ net/bluetooth/hci_event.c | 15 ++++++ net/bluetooth/mgmt.c | 83 ++++++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 1cd031cd1c4d..ac4de1afe046 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -613,6 +613,13 @@ struct hci_cp_write_ssp_mode { __u8 mode; } __packed; +#define HCI_OP_READ_LOCAL_OOB_DATA 0x0c57 +struct hci_rp_read_local_oob_data { + __u8 status; + __u8 hash[16]; + __u8 randomizer[16]; +} __packed; + #define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58 #define HCI_OP_READ_LOCAL_VERSION 0x1001 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3912c7ab717c..fd9b8a31e5b0 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -768,6 +768,8 @@ int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status); +int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, + u8 status); /* 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 89e7c82c4784..6ebb1265c36e 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -177,6 +177,12 @@ struct mgmt_cp_set_local_name { __u8 name[MGMT_MAX_NAME_LENGTH]; } __packed; +#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0018 +struct mgmt_rp_read_local_oob_data { + __u8 hash[16]; + __u8 randomizer[16]; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0def3e1fe5ef..582ef60a8bc0 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -822,6 +822,17 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, rp->status); } +static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_rp_read_local_oob_data *rp = (void *) skb->data; + + BT_DBG("%s status 0x%x", hdev->name, rp->status); + + mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash, + rp->randomizer, rp->status); +} + static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%x", hdev->name, status); @@ -1752,6 +1763,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk hci_cc_pin_code_neg_reply(hdev, skb); break; + case HCI_OP_READ_LOCAL_OOB_DATA: + hci_cc_read_local_oob_data_reply(hdev, skb); + break; + case HCI_OP_LE_READ_BUFFER_SIZE: hci_cc_le_read_buffer_size(hdev, skb); break; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 93f0f04c8bcd..33b1f7400dab 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1296,6 +1296,55 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, return err; } +static int read_local_oob_data(struct sock *sk, u16 index) +{ + struct hci_dev *hdev; + struct pending_cmd *cmd; + int err; + + BT_DBG("hci%u", index); + + hdev = hci_dev_get(index); + if (!hdev) + return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, + ENODEV); + + hci_dev_lock_bh(hdev); + + if (!test_bit(HCI_UP, &hdev->flags)) { + err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, + ENETDOWN); + goto unlock; + } + + if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { + err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, + EOPNOTSUPP); + goto unlock; + } + + if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) { + err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); + goto unlock; + } + + cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0); + if (!cmd) { + err = -ENOMEM; + goto unlock; + } + + err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL); + if (err < 0) + mgmt_pending_remove(cmd); + +unlock: + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + + return err; +} + int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) { unsigned char *buf; @@ -1394,6 +1443,10 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) case MGMT_OP_SET_LOCAL_NAME: err = set_local_name(sk, index, buf + sizeof(*hdr), len); break; + case MGMT_OP_READ_LOCAL_OOB_DATA: + err = read_local_oob_data(sk, index); + break; + default: BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, index, opcode, 0x01); @@ -1723,3 +1776,33 @@ int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) mgmt_pending_remove(cmd); return err; } + +int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, + u8 status) +{ + struct pending_cmd *cmd; + int err; + + BT_DBG("hci%u status %u", index, status); + + cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index); + if (!cmd) + return -ENOENT; + + if (status) { + err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, + EIO); + } else { + struct mgmt_rp_read_local_oob_data rp; + + memcpy(rp.hash, hash, sizeof(rp.hash)); + memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); + + err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, + &rp, sizeof(rp)); + } + + mgmt_pending_remove(cmd); + + return err; +} -- GitLab From 2763eda6ccaf126633bb3180f440c8f3589f0679 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Mar 2011 13:12:22 +0100 Subject: [PATCH 0227/5560] Bluetooth: Add add/remove_remote_oob_data management commands This patch adds commands to add and remove remote OOB data to the managment interface. Remote data is stored in kernel and can be used by corresponding HCI commands and events when needed. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 17 ++++++++ include/net/bluetooth/hci_core.h | 16 +++++++ include/net/bluetooth/mgmt.h | 12 +++++ net/bluetooth/hci_core.c | 67 ++++++++++++++++++++++++++++ net/bluetooth/hci_event.c | 35 +++++++++++++++ net/bluetooth/mgmt.c | 75 ++++++++++++++++++++++++++++++++ 6 files changed, 222 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ac4de1afe046..b989a8c3e01a 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -426,6 +426,18 @@ struct hci_rp_user_confirm_reply { #define HCI_OP_USER_CONFIRM_NEG_REPLY 0x042d +#define HCI_OP_REMOTE_OOB_DATA_REPLY 0x0430 +struct hci_cp_remote_oob_data_reply { + bdaddr_t bdaddr; + __u8 hash[16]; + __u8 randomizer[16]; +} __packed; + +#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY 0x0433 +struct hci_cp_remote_oob_data_neg_reply { + bdaddr_t bdaddr; +} __packed; + #define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 struct hci_cp_io_capability_neg_reply { bdaddr_t bdaddr; @@ -962,6 +974,11 @@ struct hci_ev_user_confirm_req { __le32 passkey; } __packed; +#define HCI_EV_REMOTE_OOB_DATA_REQUEST 0x35 +struct hci_ev_remote_oob_data_request { + bdaddr_t bdaddr; +} __packed; + #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 struct hci_ev_simple_pair_complete { __u8 status; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index fd9b8a31e5b0..87bff518b54b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -82,6 +82,13 @@ struct link_key { u8 pin_len; }; +struct oob_data { + struct list_head list; + bdaddr_t bdaddr; + u8 hash[16]; + u8 randomizer[16]; +}; + #define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; @@ -169,6 +176,8 @@ struct hci_dev { struct list_head link_keys; + struct list_head remote_oob_data; + struct hci_dev_stats stat; struct sk_buff_head driver_init; @@ -505,6 +514,13 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, u8 *key, u8 type, u8 pin_len); int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); +int hci_remote_oob_data_clear(struct hci_dev *hdev); +struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, + bdaddr_t *bdaddr); +int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, + u8 *randomizer); +int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); + void hci_del_off_timer(struct hci_dev *hdev); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 6ebb1265c36e..1a6283f9fee8 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -183,6 +183,18 @@ struct mgmt_rp_read_local_oob_data { __u8 randomizer[16]; } __packed; +#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0019 +struct mgmt_cp_add_remote_oob_data { + bdaddr_t bdaddr; + __u8 hash[16]; + __u8 randomizer[16]; +} __packed; + +#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x001A +struct mgmt_cp_remove_remote_oob_data { + bdaddr_t bdaddr; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c20cbe5ff6db..675f0a1832ee 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1076,6 +1076,70 @@ static void hci_cmd_timer(unsigned long arg) tasklet_schedule(&hdev->cmd_task); } +struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, + bdaddr_t *bdaddr) +{ + struct oob_data *data; + + list_for_each_entry(data, &hdev->remote_oob_data, list) + if (bacmp(bdaddr, &data->bdaddr) == 0) + return data; + + return NULL; +} + +int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) +{ + struct oob_data *data; + + data = hci_find_remote_oob_data(hdev, bdaddr); + if (!data) + return -ENOENT; + + BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); + + list_del(&data->list); + kfree(data); + + return 0; +} + +int hci_remote_oob_data_clear(struct hci_dev *hdev) +{ + struct oob_data *data, *n; + + list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) { + list_del(&data->list); + kfree(data); + } + + return 0; +} + +int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, + u8 *randomizer) +{ + struct oob_data *data; + + data = hci_find_remote_oob_data(hdev, bdaddr); + + if (!data) { + data = kmalloc(sizeof(*data), GFP_ATOMIC); + if (!data) + return -ENOMEM; + + bacpy(&data->bdaddr, bdaddr); + list_add(&data->list, &hdev->remote_oob_data); + } + + memcpy(data->hash, hash, sizeof(data->hash)); + memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); + + BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); + + return 0; +} + /* Register HCI device */ int hci_register_dev(struct hci_dev *hdev) { @@ -1140,6 +1204,8 @@ int hci_register_dev(struct hci_dev *hdev) INIT_LIST_HEAD(&hdev->link_keys); + INIT_LIST_HEAD(&hdev->remote_oob_data); + INIT_WORK(&hdev->power_on, hci_power_on); INIT_WORK(&hdev->power_off, hci_power_off); setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); @@ -1219,6 +1285,7 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_blacklist_clear(hdev); hci_uuids_clear(hdev); hci_link_keys_clear(hdev); + hci_remote_oob_data_clear(hdev); hci_dev_unlock_bh(hdev); __hci_dev_put(hdev); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 582ef60a8bc0..e0aaf3053667 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2471,6 +2471,37 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_ hci_dev_unlock(hdev); } +static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) +{ + struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; + struct oob_data *data; + + BT_DBG("%s", hdev->name); + + hci_dev_lock(hdev); + + data = hci_find_remote_oob_data(hdev, &ev->bdaddr); + if (data) { + struct hci_cp_remote_oob_data_reply cp; + + bacpy(&cp.bdaddr, &ev->bdaddr); + memcpy(cp.hash, data->hash, sizeof(cp.hash)); + memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); + + hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), + &cp); + } else { + struct hci_cp_remote_oob_data_neg_reply cp; + + bacpy(&cp.bdaddr, &ev->bdaddr); + hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp), + &cp); + } + + hci_dev_unlock(hdev); +} + static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_conn_complete *ev = (void *) skb->data; @@ -2673,6 +2704,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_le_meta_evt(hdev, skb); break; + case HCI_EV_REMOTE_OOB_DATA_REQUEST: + hci_remote_oob_data_request_evt(hdev, skb); + break; + default: BT_DBG("%s event 0x%x", hdev->name, event); break; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 33b1f7400dab..a42dc8ca0a6f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1345,6 +1345,74 @@ static int read_local_oob_data(struct sock *sk, u16 index) return err; } +static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, + u16 len) +{ + struct hci_dev *hdev; + struct mgmt_cp_add_remote_oob_data *cp = (void *) data; + int err; + + BT_DBG("hci%u ", index); + + if (len != sizeof(*cp)) + return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, + EINVAL); + + hdev = hci_dev_get(index); + if (!hdev) + return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, + ENODEV); + + hci_dev_lock_bh(hdev); + + err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash, + cp->randomizer); + if (err < 0) + err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, -err); + else + err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL, + 0); + + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + + return err; +} + +static int remove_remote_oob_data(struct sock *sk, u16 index, + unsigned char *data, u16 len) +{ + struct hci_dev *hdev; + struct mgmt_cp_remove_remote_oob_data *cp = (void *) data; + int err; + + BT_DBG("hci%u ", index); + + if (len != sizeof(*cp)) + return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, + EINVAL); + + hdev = hci_dev_get(index); + if (!hdev) + return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, + ENODEV); + + hci_dev_lock_bh(hdev); + + err = hci_remove_remote_oob_data(hdev, &cp->bdaddr); + if (err < 0) + err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, + -err); + else + err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, + NULL, 0); + + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + + return err; +} + int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) { unsigned char *buf; @@ -1446,6 +1514,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) case MGMT_OP_READ_LOCAL_OOB_DATA: err = read_local_oob_data(sk, index); break; + case MGMT_OP_ADD_REMOTE_OOB_DATA: + err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len); + break; + case MGMT_OP_REMOVE_REMOTE_OOB_DATA: + err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr), + len); + break; default: BT_DBG("Unknown op %u", opcode); -- GitLab From ce85ee13e6b5d078f4a6c3b02ba7cd0fa140c552 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Mar 2011 13:12:23 +0100 Subject: [PATCH 0228/5560] Bluetooth: Enable support for out of band association model If remote side reports oob availability or we are pairing initiator use oob data for pairing if available. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index e0aaf3053667..da4c662dbc30 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2371,9 +2371,14 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff bacpy(&cp.bdaddr, &ev->bdaddr); cp.capability = conn->io_capability; - cp.oob_data = 0; cp.authentication = hci_get_auth_req(conn); + if ((conn->out == 0x01 || conn->remote_oob == 0x01) && + hci_find_remote_oob_data(hdev, &conn->dst)) + cp.oob_data = 0x01; + else + cp.oob_data = 0x00; + hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, sizeof(cp), &cp); } else { -- GitLab From f3dd4f0f586b3a70734820b68c69985363e2d798 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 24 Mar 2011 20:14:16 -0300 Subject: [PATCH 0229/5560] Bluetooth: Remove unused struct l2cap_conn item Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7a0262524a50..2b9ca0d5c4a0 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -301,7 +301,6 @@ struct l2cap_conn { struct sk_buff *rx_skb; __u32 rx_len; - __u8 rx_ident; __u8 tx_ident; __u8 disc_reason; -- GitLab From d1010240fa9aac93da56a683c1295e759ee69d10 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 00:39:48 -0300 Subject: [PATCH 0230/5560] Bluetooth: Move bt_accept_enqueue() to outside __l2cap_chan_add bt_accept_enqueue() is not really a channel action, so do it outside. This patch is part of a set of patches to create an struct l2cap_chan to have a clear separation between the struct sock and the L2CAP channel stuff. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b5a1ce06e1c0..bf09f6027bd2 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -169,7 +169,7 @@ static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk) __sock_put(sk); } -static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) +static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) { struct l2cap_chan_list *l = &conn->chan_list; @@ -204,9 +204,6 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so } __l2cap_chan_link(l, sk); - - if (parent) - bt_accept_enqueue(parent, sk); } /* Delete channel. @@ -652,7 +649,9 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) bacpy(&bt_sk(sk)->src, conn->src); bacpy(&bt_sk(sk)->dst, conn->dst); - __l2cap_chan_add(conn, sk, parent); + bt_accept_enqueue(parent, sk); + + __l2cap_chan_add(conn, sk); l2cap_sock_set_timer(sk, sk->sk_sndtimeo); @@ -793,11 +792,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) kfree(conn); } -static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) +static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) { struct l2cap_chan_list *l = &conn->chan_list; write_lock_bh(&l->lock); - __l2cap_chan_add(conn, sk, parent); + __l2cap_chan_add(conn, sk); write_unlock_bh(&l->lock); } @@ -876,7 +875,7 @@ int l2cap_do_connect(struct sock *sk) /* Update source addr of the socket */ bacpy(src, conn->src); - l2cap_chan_add(conn, sk, NULL); + l2cap_chan_add(conn, sk); sk->sk_state = BT_CONNECT; l2cap_sock_set_timer(sk, sk->sk_sndtimeo); @@ -2030,7 +2029,9 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd l2cap_pi(sk)->psm = psm; l2cap_pi(sk)->dcid = scid; - __l2cap_chan_add(conn, sk, parent); + bt_accept_enqueue(parent, sk); + + __l2cap_chan_add(conn, sk); dcid = l2cap_pi(sk)->scid; l2cap_sock_set_timer(sk, sk->sk_sndtimeo); -- GitLab From e90165be9a4d6a1e8fa632fcae00a5294abd3981 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 25 Mar 2011 11:31:41 +0200 Subject: [PATCH 0231/5560] Bluetooth: check L2CAP info_rsp ident and state Information requests/responses are unbound to L2CAP channel. Patch fixes issue arising when two devices connects at the same time to each other. This way we do not process out of the context messages. We are safe dropping info_rsp since info_timer is left running. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index bf09f6027bd2..033c83be3524 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2461,6 +2461,11 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm BT_DBG("type 0x%4.4x result 0x%2.2x", type, result); + /* L2CAP Info req/rsp are unbound to channels, add extra checks */ + if (cmd->ident != conn->info_ident || + conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) + return 0; + del_timer(&conn->info_timer); if (result != L2CAP_IR_SUCCESS) { -- GitLab From 80a1e1dbf62a08984d4c1bfb5a4bca38c3e1664f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 28 Mar 2011 14:07:23 +0300 Subject: [PATCH 0232/5560] Bluetooth: Add local Extended Inquiry Response (EIR) support This patch adds automated creation of the local EIR data based on what 16-bit UUIDs are registered and what the device name is. This should cover the majority use cases, however things like 32/128-bit UUIDs, TX power and Device ID will need to be added later to be on par with what bluetoothd is capable of doing (without the Management interface). Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci.h | 8 ++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/mgmt.c | 163 +++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index b989a8c3e01a..6846ec02dcb0 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -614,6 +614,14 @@ struct hci_cp_host_buffer_size { #define HCI_OP_WRITE_INQUIRY_MODE 0x0c45 +#define HCI_MAX_EIR_LENGTH 240 + +#define HCI_OP_WRITE_EIR 0x0c52 +struct hci_cp_write_eir { + uint8_t fec; + uint8_t data[HCI_MAX_EIR_LENGTH]; +} __packed; + #define HCI_OP_READ_SSP_MODE 0x0c55 struct hci_rp_read_ssp_mode { __u8 status; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 87bff518b54b..3b2f09df279a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -102,6 +102,7 @@ struct hci_dev { __u8 dev_type; bdaddr_t bdaddr; __u8 dev_name[HCI_MAX_NAME_LENGTH]; + __u8 eir[HCI_MAX_EIR_LENGTH]; __u8 dev_class[3]; __u8 major_class; __u8 minor_class; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a42dc8ca0a6f..62055c9a8084 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -544,6 +544,150 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, return err; } +#define EIR_FLAGS 0x01 /* flags */ +#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define EIR_NAME_SHORT 0x08 /* shortened local name */ +#define EIR_NAME_COMPLETE 0x09 /* complete local name */ +#define EIR_TX_POWER 0x0A /* transmit power level */ +#define EIR_DEVICE_ID 0x10 /* device ID */ + +#define PNP_INFO_SVCLASS_ID 0x1200 + +static u8 bluetooth_base_uuid[] = { + 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static u16 get_uuid16(u8 *uuid128) +{ + u32 val; + int i; + + for (i = 0; i < 12; i++) { + if (bluetooth_base_uuid[i] != uuid128[i]) + return 0; + } + + memcpy(&val, &uuid128[12], 4); + + val = le32_to_cpu(val); + if (val > 0xffff) + return 0; + + return (u16) val; +} + +static void create_eir(struct hci_dev *hdev, u8 *data) +{ + u8 *ptr = data; + u16 eir_len = 0; + u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; + int i, truncated = 0; + struct list_head *p; + size_t name_len; + + name_len = strlen(hdev->dev_name); + + if (name_len > 0) { + /* EIR Data type */ + if (name_len > 48) { + name_len = 48; + ptr[1] = EIR_NAME_SHORT; + } else + ptr[1] = EIR_NAME_COMPLETE; + + /* EIR Data length */ + ptr[0] = name_len + 1; + + memcpy(ptr + 2, hdev->dev_name, name_len); + + eir_len += (name_len + 2); + ptr += (name_len + 2); + } + + memset(uuid16_list, 0, sizeof(uuid16_list)); + + /* Group all UUID16 types */ + list_for_each(p, &hdev->uuids) { + struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list); + u16 uuid16; + + uuid16 = get_uuid16(uuid->uuid); + if (uuid16 == 0) + return; + + if (uuid16 < 0x1100) + continue; + + if (uuid16 == PNP_INFO_SVCLASS_ID) + continue; + + /* Stop if not enough space to put next UUID */ + if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { + truncated = 1; + break; + } + + /* Check for duplicates */ + for (i = 0; uuid16_list[i] != 0; i++) + if (uuid16_list[i] == uuid16) + break; + + if (uuid16_list[i] == 0) { + uuid16_list[i] = uuid16; + eir_len += sizeof(u16); + } + } + + if (uuid16_list[0] != 0) { + u8 *length = ptr; + + /* EIR Data type */ + ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; + + ptr += 2; + eir_len += 2; + + for (i = 0; uuid16_list[i] != 0; i++) { + *ptr++ = (uuid16_list[i] & 0x00ff); + *ptr++ = (uuid16_list[i] & 0xff00) >> 8; + } + + /* EIR Data length */ + *length = (i * sizeof(u16)) + 1; + } +} + +static int update_eir(struct hci_dev *hdev) +{ + struct hci_cp_write_eir cp; + + if (!(hdev->features[6] & LMP_EXT_INQ)) + return 0; + + if (hdev->ssp_mode == 0) + return 0; + + if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) + return 0; + + memset(&cp, 0, sizeof(cp)); + + create_eir(hdev, cp.data); + + if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) + return 0; + + memcpy(hdev->eir, cp.data, sizeof(cp.data)); + + return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); +} + static u8 get_service_classes(struct hci_dev *hdev) { struct list_head *p; @@ -612,6 +756,10 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) if (err < 0) goto failed; + err = update_eir(hdev); + if (err < 0) + goto failed; + err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); failed: @@ -668,6 +816,10 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) if (err < 0) goto unlock; + err = update_eir(hdev); + if (err < 0) + goto unlock; + err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); unlock: @@ -737,6 +889,8 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, } else { clear_bit(HCI_SERVICE_CACHE, &hdev->flags); err = update_class(hdev); + if (err == 0) + err = update_eir(hdev); } if (err == 0) @@ -1822,6 +1976,7 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) { struct pending_cmd *cmd; + struct hci_dev *hdev; struct mgmt_cp_set_local_name ev; int err; @@ -1837,6 +1992,14 @@ int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) goto failed; } + hdev = hci_dev_get(index); + if (hdev) { + hci_dev_lock_bh(hdev); + update_eir(hdev); + hci_dev_unlock_bh(hdev); + hci_dev_put(hdev); + } + err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev, sizeof(ev)); if (err < 0) -- GitLab From 88d377b6c3c28ee54cd4c76bfe6e60f2d9bf6ae1 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Thu, 24 Mar 2011 14:51:21 -0300 Subject: [PATCH 0233/5560] Bluetooth: add support for Apple MacBook Pro 8,2 Just adding the vendor details makes it work fine. Signed-off-by: Marc-Antoine Perennou Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 866811428e20..2af2e770f4bd 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookAir3,1, MacBookAir3,2 */ { USB_DEVICE(0x05ac, 0x821b) }, + /* Apple MacBookPro8,2 */ + { USB_DEVICE(0x05ac, 0x821a) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, -- GitLab From 23e9fde2b344c22c5176c7fd37b52c3776ef5aba Mon Sep 17 00:00:00 2001 From: Suraj Sumangala Date: Wed, 9 Mar 2011 14:44:05 +0530 Subject: [PATCH 0234/5560] Bluetooth: Increment unacked_frames count only the first transmit This patch lets 'l2cap_pinfo.unacked_frames' be incremented only the first time a frame is transmitted. Previously it was being incremented for retransmitted packets too resulting the value to cross the transmit window size. Signed-off-by: Suraj Sumangala Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c9f9cecca527..ca27f3a41536 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1116,7 +1116,9 @@ int l2cap_ertm_send(struct sock *sk) bt_cb(skb)->tx_seq = pi->next_tx_seq; pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; - pi->unacked_frames++; + if (bt_cb(skb)->retries == 1) + pi->unacked_frames++; + pi->frames_sent++; if (skb_queue_is_last(TX_QUEUE(sk), skb)) -- GitLab From 105721328f0fa53e772592eaca17ee0023f0cc87 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 16 Mar 2011 15:36:29 -0300 Subject: [PATCH 0235/5560] Bluetooth: Fix HCI_RESET command synchronization We can't send new commands before a cmd_complete for the HCI_RESET command shows up. Reported-by: Mikko Vinni Reported-by: Justin P. Mattock Reported-by: Ed Tomlinson Signed-off-by: Gustavo F. Padovan Tested-by: Justin P. Mattock Tested-by: Mikko Vinni Tested-by: Ed Tomlinson --- include/net/bluetooth/hci.h | 2 ++ net/bluetooth/hci_core.c | 6 +++++- net/bluetooth/hci_event.c | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ec6acf2f1c0b..2c0d309c7381 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -84,6 +84,8 @@ enum { HCI_SERVICE_CACHE, HCI_LINK_KEYS, HCI_DEBUG_KEYS, + + HCI_RESET, }; /* HCI ioctl defines */ diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b372fb8bcdcf..92b48e257b89 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -186,6 +186,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) BT_DBG("%s %ld", hdev->name, opt); /* Reset device */ + set_bit(HCI_RESET, &hdev->flags); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); } @@ -213,8 +214,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) /* Mandatory initialization */ /* Reset */ - if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) + if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { + set_bit(HCI_RESET, &hdev->flags); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); + } /* Read Local Supported Features */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); @@ -1074,6 +1077,7 @@ static void hci_cmd_timer(unsigned long arg) BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); + clear_bit(HCI_RESET, &hdev->flags); tasklet_schedule(&hdev->cmd_task); } diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3fbfa50c2bff..cebe7588469f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -183,6 +183,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); + clear_bit(HCI_RESET, &hdev->flags); + hci_req_complete(hdev, HCI_OP_RESET, status); } @@ -1847,7 +1849,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) if (ev->opcode != HCI_OP_NOP) del_timer(&hdev->cmd_timer); - if (ev->ncmd) { + if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { atomic_set(&hdev->cmd_cnt, 1); if (!skb_queue_empty(&hdev->cmd_q)) tasklet_schedule(&hdev->cmd_task); -- GitLab From 8693ac900e230c85d6fff428984a0f983330844d Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Mon, 14 Mar 2011 18:20:33 -0300 Subject: [PATCH 0236/5560] Bluetooth: Fix sending LE data over USB Now that we have support for LE connections, before discarding a frame we must check if there's a LE connection over that transport. Signed-off-by: Vinicius Costa Gomes Acked-by: Ville Tervo Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 2af2e770f4bd..762a5109c68a 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -693,7 +693,8 @@ static int btusb_send_frame(struct sk_buff *skb) break; case HCI_ACLDATA_PKT: - if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1) + if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 && + hdev->conn_hash.le_num < 1)) return -ENODEV; urb = usb_alloc_urb(0, GFP_ATOMIC); -- GitLab From 08ba53824a7fb224085a0ff73eab213cab0197e9 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 16 Mar 2011 14:29:34 +0200 Subject: [PATCH 0237/5560] Bluetooth: Fix missing hci_dev_lock_bh in user_confirm_reply The code was correctly calling _unlock at the end of the function but there was no actual _lock call anywhere. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0054c74e27b7..4476d8e3c0f2 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1230,6 +1230,8 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, mgmt_op, ENODEV); + hci_dev_lock_bh(hdev); + if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, mgmt_op, ENETDOWN); goto failed; -- GitLab From 34bd0273b631742e8d929c80e90cb7782105d8da Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Thu, 24 Mar 2011 17:16:08 +0200 Subject: [PATCH 0238/5560] Bluetooth: delete hanging L2CAP channel Sometimes L2CAP connection remains hanging. Make sure that L2CAP channel is deleted. Signed-off-by: Andrei Emeltchenko Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_sock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index fc85e7ae33c7..f77308e63e58 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -923,8 +923,9 @@ void __l2cap_sock_close(struct sock *sk, int reason) rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); - } else - l2cap_chan_del(sk, reason); + } + + l2cap_chan_del(sk, reason); break; case BT_CONNECT: -- GitLab From 6f5ef998b7b0b1bf1471654bf6176a5419197128 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 24 Mar 2011 20:16:42 +0100 Subject: [PATCH 0239/5560] Bluetooth: Fix warning with hci_cmd_timer After we made debugobjects working again, we got the following: WARNING: at lib/debugobjects.c:262 debug_print_object+0x8e/0xb0() Hardware name: System Product Name ODEBUG: free active (active state 0) object type: timer_list hint: hci_cmd_timer+0x0/0x60 Pid: 2125, comm: dmsetup Tainted: G W 2.6.38-06707-gc62b389 #110375 Call Trace: [] warn_slowpath_common+0x7a/0xb0 [] warn_slowpath_fmt+0x46/0x50 [] debug_print_object+0x8e/0xb0 [] ? hci_cmd_timer+0x0/0x60 [] debug_check_no_obj_freed+0x125/0x230 [] ? check_object+0xb3/0x2b0 [] kfree+0x150/0x190 [] ? bt_host_release+0x16/0x20 [] bt_host_release+0x16/0x20 [] device_release+0x27/0xa0 [] kobject_release+0x4c/0xa0 [] ? kobject_release+0x0/0xa0 [] kref_put+0x36/0x70 [] kobject_put+0x27/0x60 [] put_device+0x17/0x20 [] hci_free_dev+0x29/0x30 [] vhci_release+0x36/0x70 [] fput+0xd6/0x1f0 [] filp_close+0x66/0x90 [] sys_close+0x99/0xf0 [] system_call_fastpath+0x16/0x1b That timer was introduced with commit 6bd32326cda(Bluetooth: Use proper timer for hci command timout) Timer seems to be running when the thing is closed. Removing the timer unconditionally fixes the problem. And yes, it needs to be fixed before the HCI_UP check. Signed-off-by: Thomas Gleixner Tested-by: Ingo Molnar Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 92b48e257b89..2216620ff296 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -587,6 +587,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) hci_req_cancel(hdev, ENODEV); hci_req_lock(hdev); + /* Stop timer, it might be running */ + del_timer_sync(&hdev->cmd_timer); + if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { hci_req_unlock(hdev); return 0; @@ -626,7 +629,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) /* Drop last sent command */ if (hdev->sent_cmd) { - del_timer_sync(&hdev->cmd_timer); kfree_skb(hdev->sent_cmd); hdev->sent_cmd = NULL; } -- GitLab From 96b8e1a0e96bd30ffb07e739b29b8c4c5759b93f Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Thu, 31 Mar 2011 17:03:36 -0700 Subject: [PATCH 0240/5560] bnx2x: Update firmware to 6.2.9 To fix bugs when running offloaded FCoE/iSCSI traffic in multiple Class of Service environments. In some scenarios, traffic could stop on certain rings and eventually all traffic would stop. Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 2 +- firmware/Makefile | 6 +- firmware/WHENCE | 9 +- firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex | 9483 ------------- firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex | 9484 +++++++++++++ firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex | 13181 ------------------ firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex | 13192 ++++++++++++++++++ firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex | 15456 -------------------- firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex | 15473 +++++++++++++++++++++ 9 files changed, 38158 insertions(+), 38128 deletions(-) delete mode 100644 firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex delete mode 100644 firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex delete mode 100644 firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex create mode 100644 firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index be503cc0a50b..d9d0184b8c22 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -1929,7 +1929,7 @@ struct host_func_stats { #define BCM_5710_FW_MAJOR_VERSION 6 #define BCM_5710_FW_MINOR_VERSION 2 -#define BCM_5710_FW_REVISION_VERSION 5 +#define BCM_5710_FW_REVISION_VERSION 9 #define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 diff --git a/firmware/Makefile b/firmware/Makefile index 0384afa93de9..0d15a3d113a2 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.2.5.0.fw \ - bnx2x/bnx2x-e1h-6.2.5.0.fw \ - bnx2x/bnx2x-e2-6.2.5.0.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.9.0.fw \ + bnx2x/bnx2x-e1h-6.2.9.0.fw \ + bnx2x/bnx2x-e2-6.2.9.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \ bnx2/bnx2-rv2p-09-6.0.17.fw \ bnx2/bnx2-rv2p-09ax-6.0.17.fw \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 76404f9ce74d..182ecb6c275e 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -679,14 +679,15 @@ Found in hex form in kernel source. Driver: bnx2x: Broadcom Everest -File: bnx2x/bnx2x-e1-5.2.13.0.fw -File: bnx2x/bnx2x-e1h-5.2.13.0.fw +File: bnx2x/bnx2x-e1-6.2.9.0.fw +File: bnx2x/bnx2x-e1h-6.2.9.0.fw +File: bnx2x/bnx2x-e2-6.2.9.0.fw License: - Copyright (c) 2007-2010 Broadcom Corporation + Copyright (c) 2007-2011 Broadcom Corporation This file contains firmware data derived from proprietary unpublished - source code, Copyright (c) 2007-2009 Broadcom Corporation. + source code, Copyright (c) 2007-2011 Broadcom Corporation. Permission is hereby granted for the distribution of this firmware data in hexadecimal or equivalent format, provided this copyright notice is diff --git a/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex deleted file mode 100644 index 1b535827a742..000000000000 --- a/firmware/bnx2x/bnx2x-e1-6.2.5.0.fw.ihex +++ /dev/null @@ -1,9483 +0,0 @@ -: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-e1-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex new file mode 100644 index 000000000000..0ed7f5891184 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw.ihex @@ -0,0 +1,9484 @@ +:1000000000003BB0000000680000070C00003C202E +:1000100000001AF8000043300000007C00005E3051 +:1000200000007A2C00005EB0000000B00000D8E0B4 +:10003000000080200000D99800000088000159C00D +:100040000000398800015A5000000090000193E040 +:100050000000AC040001947800000FFC0002408016 +:100060000000000400025080020400480000000F5D +: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 +:10203000073400003305000007348000327F0CC2F3 +:10204000073500001A951962083539E058C403783D +: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 +:1032400007280400008E00000828076800130454B3 +:10325000072C000033C80000072C800038050CF351 +:10326000072D000038B61AF5072D800007762923B0 +:10327000082D8CB04E6A04560128000000000000A2 +: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 +:1054A000FFFFFFFF00090206CCCCCCC17058103CB6 +: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 +:105F3000FAFF7FEDA8A297A8971072117EAE256494 +:105F40009D4008C9EBBD5AF78916AD26B9845405A2 +:105F500055632B7DB65E0A1B8DD3E8FD4BC4D01371 +:105F600004EE8F9B432611A2C07B05844C85FF4D18 +:105F70002744CE691D1EF5D37BD2AA2CB85AE3590B +:105F8000D72A99107D2A3CDF362ED5F3E4FC09A5EB +:105F9000A75B23F873710C21F5C76F9CFF8AD5A608 +:105FA000FF8D2499B9272FA7BFCC24332F4A847C97 +:105FB00054B828ABD3483FDE070D5DBA3C9690F34A +:105FC0000D2BE6BF32B6EFF3F512A96D2FED7BFF77 +:105FD0002AA2215E8866AA9189BDEB5E4F48A72759 +:105FE0008790CD859BD87A7329B2AEA4F7DBFE45A6 +:105FF000974B7AE15C2FD37E53FBAE871013C7B566 +:10600000C649BE9FE872BCEF7E2F391E7F9FC8F441 +:10601000DF0C42B00B5DFF74217A2DDCF7142E32B9 +:1060200047D0F6FA67CA49B4343DFC497A7D42F854 +:10603000ADF7D2D291F7FB687F530BA1EF9D54E3EC +:10604000D75F45F9E8BDEF4BA14DC0477BC6CF21D7 +:10605000017A9F303EB2E8746A7FD3F054FC918E8F +:106060004E7F4FBCC87F167F5589ABB23AC927E730 +:10607000AF3B80BF326CFCD5BEB8DFF13E297FC597 +:10608000DCFCC5F171BA9DAD9FEC1EC6E8C2E9E526 +:10609000A64F5ABA7CD2F7FAF2D316C0ABA77DB19D +:1060A0003982A4E0270EAF45AF4F0BEF407C444848 +:1060B0001CE94C484482F97BEFB36B469921009F61 +:1060C000D1E6615847904D4582B7B6DC2D52380372 +:1060D00024D13AAE88B6BBD72C00B803C7E79F02DD +:1060E00079680E5568B3E97AF569C643F3E835A3D4 +:1060F0005417603D5B89084A808E576D969702BDA4 +:1061000008B69F366F099B80071226643821F7F185 +:106110003511221A326DABF0EB9854EB504927C37E +:106120008770D1D3F7FD74EB577BDF23178BE0FF2C +:10613000F71058DF40EF91287BCFA4FF00DF39AE86 +:1061400071F439B46DE3FB00B1B5E9F3A3F00BE2F0 +:10615000FBEE2F64BE6CB24F33A87E504B443D0122 +:10616000FD89912DD37646255544F03C480E528A40 +:106170000C489766422ADB811F493B5938B117BE4C +:106180005344C0F514DCBE734D0B555DE7CAFC21CA +:10619000E0F3A04EC8B09CBEEBD9D6401979BCAD97 +:1061A0001D7A0EF93F46F9680C7DDF0C317BB8B5DE +:1061B000E4653D6A93EF0C41E07CE9E60F62C83389 +:1061C00040CC8055E8B5440C7B039F9E3F64171E6E +:1061D00007CB1FFEA88D3E64E8F40A72BF61B0FCD5 +:1061E000F169E7B3E8DA57AE1A2DBA6A84D2614B87 +:1061F000F1A294FE477ABAEE23D03FA384841329F8 +:10620000DE1B25085C0E4C87BEC12BA58F9424EFA6 +:10621000BD0E7A49F93356ECED071F52AE131FD667 +:10622000B8DE7AC97897AA4422EB228CA7C2789468 +:106230004FB7041F3609958773C0DB141F527C4A81 +:1062400027B44931413EA43F9D026D7B83E1C45692 +:10625000E48304D2C582CF63880EFCCAB93E479B53 +:10626000AC30053BFCDE7A15E150D147A0E3E87481 +:10627000408A0AD94F3A816F2D7E0536B87829B405 +:10628000BFEEE08356632A4945078B5F01AD8C5F03 +:10629000BF3E38FDE29E6F8913DE41BFE7978D93C5 +:1062A000363B94FE3D999CB4E84391580503D8F8D9 +:1062B00060B3420E089309692A5C46A2F4EE667840 +:1062C00044ED580B5C0BC03F9C8A7A81B40932C004 +:1062D00069D95512CCC17ED30503C713B55AD42B47 +:1062E000923FCCEC2B7F9E1E2E36FF70231ED629AC +:1062F0007EF3493C2C52FA505D19EA24A037C304BE +:10630000F88084185F48DC4FB7DE8F717EF692A369 +:10631000F83ED5AEA68EF6CC29C77325FA908EB37B +:10632000A584243C48A7B8066DB94426B02FA0FA2E +:10633000C95F40FB6759EC2F2D0801FC59DCBE9268 +:10634000599CBF05AACF289EFDD39CF2ED73C9BF0F +:10635000CCED711F7D96663F615DDDFEDB6302F76C +:10636000DF32881FE9CDDF27FED4FEAAE5B75978D2 +:10637000CD1309E293FC54493C51C4D746DBF7BC2A +:10638000959D80759B159135CD140FE6DB42A809CC +:10639000E829877BB2E8F3934F4AB85FCA5B567F20 +:1063A00009CCB7BDC11C5B6CF307B7CBB51AE09B3A +:1063B000F28566B7173790E80B826DFFE509B68C5A +:1063C0002D1E86FCF7767709980A01F9CFEB8F0529 +:1063D0005F05B9E4F793F8B1B7A5BEEDDC7CC2ED7B +:1063E000E50DE5613A6F2BE8AE11F8D814283CAD05 +:1063F00005ACFD93C6E1E5603F5B3359FBA3C6776F +:10640000C28DC817512D42EFD5138E972E8A17A42F +:10641000BF916FB7AFEEAB7BFD3B64DD077CB6D7BA +:106420009F735D09D8CF32310468DF1B3BA2AFB147 +:10643000E1E39B9E8A37001F2349422040BF582E2C +:10644000CA8FE5CF01E341BB80CB5321398CFD4698 +:10645000477ACA15B8B5427F19AE2DC1E7B2519E31 +:10646000C81CFD24CABF245CBC7CF0F29E6EBD013A +:10647000814452F9F3F74B392857816974DD0EBD19 +:106480005EA8233FF271BF063402FD914D619A0C64 +:106490007A24BE229262BC9F0822F6D3C01E5C41C1 +:1064A000D150B8ACECDFE87A352D3CE5550A97279A +:1064B000D71F32116C66270C2E039E78A306F82591 +:1064C000472502F2AF158623B7019F924858A0F7DF +:1064D000B56038B4D5E8BB3E9530FB9043AF179913 +:1064E0007C13E87F4F9E8EFD09D80B6B5D63002EF9 +:1064F00015E1FA0CE89D2B4E1F98CE23487B3918E6 +:10650000B374F4FEACE99CEE7D377D030293AFFBE0 +:106510009BCE874D2A4F2DC7055102A5182F46BA8D +:10652000689C2EE795A8067EE396AF8A641F6D3FB0 +:106530005ADFBF9F12033FC563B39B3AA3DFC8BBBB +:10654000F4A9C042E9DEDB7597589948C14F9522FE +:10655000D3FB5BEE7A383E16E8F98A73BFA7AC0A24 +:10656000A35F4AF77D95400FEB3D6F31B34F643F1A +:106570005D0FEDAF707FE47CDEA22C92621EEBBA61 +:10658000C7057F21C5732AB9B94FE2FED54E36BE85 +:10659000E5EF9C2FE87F7C0B3F172A4572B814C9A2 +:1065A000EA23A57C3114EF8549BF3B0FDB1EFE2893 +:1065B000512BFA08D8BDC2CE72B82AA4A711F8741C +:1065C0009748AA52C1B7561211BEC230DD7A50BDEB +:1065D0005F688AA099C8BD9281F7F357D51E5428E9 +:1065E0005D5A47911098994B603CD0AB07BD683F0E +:1065F000D55C92F0523DFD5AD1574CB0CB7A21096F +:10660000032C7A2DEC39E97FD4BE1AF4B9B2316A81 +:10661000225CC108EE110E152D437AB750FFCEC390 +:1066200016E2E0A71653EC04BE8DD3F1C11F8C1BFC +:106630001528AFE782D4F2C3CFC7147E6BBF712990 +:10664000C485282901CE0932C2494762F4D4195EB3 +:1066500046EE9E453AA9DD69CDDE85F2605E495081 +:106660005E6572D814C0CEC80953A4F0C6AA983E7D +:106670005072E382DD8EED21D107ED7C23EB9DE8A6 +:10668000FFB5FE595A910AAFD522D36FF7717D78C5 +:106690005E699F8FFE4633958FA2BEFDC39C0EDFC1 +:1066A0008E2D7A703CEA336697ACE75D82E18863B1 +:1066B0008EBCA0E27ADC7ECD3CEED7B41452BF068D +:1066C000E59D2C003F2683F3470B608F3EF76493D4 +:1066D0008449E1C8007F86FA25A494F9251AFD07AC +:1066E000FA2F7F85D39FF1B8FC9674FECCD784C86F +:1066F0000F50DF515505F0EF16E2F3C701BE0BE86E +:106700007ED2E8BBEE2EBE9F9C2B6D2B6AA1703D06 +:10671000962B3AF861349797C78879E2227D1E2F2D +:10672000140D803B5E2FE23ACE19CC6F27EF7A1D15 +:1067300076A2D95CA4119BFED9C1E5695B83E69082 +:106740005BF7D5AFC6A391147A4BE7F4C99815C689 +:10675000F8873F9440FAC33A53F9E90F945668FD1D +:10676000E93FB9445D83F82BAC3825C3B5CCBD5F98 +:106770004A3DAEFB4AEC7EA694BEDF60AF5B289E2E +:10678000DE561CFE78A704FB2E93A0FFE70D5153A5 +:106790001580AB3E1CE0F786A8B8C1B5BBBC12EEB5 +:1067A0001BB3221AC891659FBDA1C856B89FF52595 +:1067B000790BD0CB5B2E8A12A59F269B24C7263748 +:1067C00053E1A68DBF33A9BAB4E3438B7EA512FC77 +:1067D00054522892B1148ECD1F3768763A75D16D18 +:1067E00008DBB73AF9265EDFBF9EFDB47CF173D1BA +:1067F0008A8738E9853FF67808A77392FE7DE21A0A +:10680000FF39E8AD71FA19947E9B0CA027D3177459 +:10681000E385FE435C33C3D08E1B8668DAF4D8C7A9 +:10682000620EE241BE20A35EDABDA6250CF4D2E9D9 +:1068300018405A7A0DA7B2DB5D828A7245F5C655BB +:10684000D27454C802C43FE74A1B91DE8F517A8349 +:106850001E7B8CD4765DCCED957F2DAAA21FDFD553 +:10686000689637160F456F52F8A85F47F630FFE578 +:1068700012CB7FF97BCA2783F057CE53A3C1EDB16A +:1068800017F84AEEA62C4DE12ADCC8EC26F86A3946 +:10689000B46D50BBD729F4F2A387CFA394260E8FF3 +:1068A000477A3BEDD363852F0B1EB06FC5CCBEA9D5 +:1068B000666718F44CA098DA2782F66735E06744DB +:1068C00049BC1CDA2377CFC3757C1BFC503FD8171B +:1068D00082F8F8A698683429CD7CE148A728C1FE43 +:1068E00099E0FECEA29F7B5E6AF5909EBE6C712FF2 +:1068F000D029507B189669B77BD5525EAF3D1C51AD +:10690000D289EAD6ED2FA4F513FE2CF1FDD8CCC622 +:10691000306D8F825FA93FB9537CBC11F663114F74 +:10692000B81EE9EEDA4724E3503CDEBDB6CC122AAD +:1069300063F96FE83C7776291400027E80648F0348 +:10694000DD097689EA9BB5DCAEDD4A2201787886DE +:1069500088185F3B438E04AEB0F1E14E4965F3B455 +:106960002A6F43FCDE8AEFDE16676D4BFFDCB1DB7E +:10697000D9BE9D2C1A0EF1DBDB772AB8FE3B5DFBFE +:10698000D698A4E3B87790DA16C043B342D04F58F4 +:10699000AB1319E2B11B7EF89D19B04FF836B72B37 +:1069A0001F50FE326CFA679D3FA1C27EF69D8E2B72 +:1069B000965D4DE0FD44CB08D89767939476F496A6 +:1069C00056277C03C1EF8697904DFDC221B7092958 +:1069D000E3874F4982236E58AF052641D0E4BC9728 +:1069E0005DCD0AA63FCCDF7A134DE0274A06EF5F64 +:1069F0003B99E5396A67C275A0F77EC6FDD1A1BE95 +:106A00007738CD7B1BB46E15F8BF46362B05B137F2 +:106A10005EA529B5E19120C707CA3B471247BFD6FB +:106A200041F6AB14FBE9E786F794AE99E2E4BE7059 +:106A3000DF40A26F81DC9D17A3D51827E0707B0093 +:106A4000CF125C65A427C64F8A605E7FAB9005714C +:106A5000940EF44FBC86ECA0778DA507A85E82B893 +:106A60004F4689F3B93BAED293A46B27CA1786442D +:106A7000E992029ABF53027FB14C3E9DEC4FE7ABC7 +:106A800086754DC64EA85FEAB87EA926C683B3A612 +:106A9000A17C61BCAE6EFE1813E0A8CB3342A60108 +:106AA0006A3414C6315C7C5573412009DBFEBB4659 +:106AB000EE51418E6AA8FEB6DFBF27C8E2C9E9F4ED +:106AC000B64234C35F027EAD88789274DAB6ADFB0D +:106AD000A3B850D9CEF655594BFAD917DF1364F144 +:106AE000E2B55BC666B1B88B535F9DE5F6E127CF93 +:106AF0003CAE76839E79FAC4F5B0CEF5FF53221AE8 +:106B00009DF7EC3399A413ED464205BBB1AE434A61 +:106B1000690F096962F9F3EF6522BDD63DE7492C9B +:106B2000A0EFAF7BE19D4984C2777653CF6B23C141 +:106B30009F7E5A607171B37BD2627A7F9D4C56A75B +:106B40008AB34C90D93EE4F48F325680FC0A6D072C +:106B50006FC671DB972B6057AD7E86AC20BFD27EAF +:106B600068B7CDA784C45821157C2C1F71FA2981E0 +:106B7000C17740C1FDDFBAB6BD6A94C251D3F621D8 +:106B8000EA8BD9DF7B360078A8392039FCB89A36F1 +:106B9000A9D33309AF27E00A71566106F009E797D8 +:106BA0008E0D185FAD6E7FE0432900EF3BF516C5F3 +:106BB0004BA813F0FAA6145A00ED1FFC63C0A0A85E +:106BC000FAE0F01301C02B1D778D9A05717C277FA9 +:106BD000C3F81772FA8E47391DF3BD35ED5BD87CCB +:106BE0002EBDF801FC52D0370E1B919D7974D23620 +:106BF000B83CEFFA67CF3D6AD2F94E3FF7FB474DFD +:106C00000AF75D7FF9F747BF0E72F9CF5E1DF47A80 +:106C1000CDD3BF0C101B1FAE9359FCE0EC28BA85F6 +:106C2000A2FDCEFECA930087E0EC4BEF8D36E87AEA +:106C3000CF7EFF4FC30DDABFEEA5B9F9B0FEBAE7BC +:106C400067E7F7E7C7009F263C76B81238BE714069 +:106C500060CEC28BFCEAA2CBA18E43A301CE33C788 +:106C60003CB83FABA1F7EAA7029D36A09D85F6464A +:106C70008ADFEA67367F08FAA12F9ECD912206BFF0 +:106C8000A81A0C029DDF9987F4223D681FDDFD6B79 +:106C90008E523A4E4E4FB773E46315F45CCD335BBE +:106CA000D87C2EBA9D815FAEEC4BB7CD2EBA9D231A +:106CB000773D560089D78E618E3C8275ED8D9F475A +:106CC000B222FDE8074BFE07C22BE659285C4BE5D4 +:106CD000F0376490A3E73292745D00747DF6DC684F +:106CE00042F9E27DA5E766B0073D2F79F47DF4FE19 +:106CF000BA97DE44B93AFBFCEBAA81768CF805EA38 +:106D0000579E25C99FC3E06756339F93D4ECCFECC1 +:106D1000F4047AE9539D58586904F0FE09BC9F6059 +:106D2000FC5E9D38B8444841AFD7E5314CFF27F2AF +:106D3000102F1BF6FF46257E271D8532A0E389799B +:106D4000703F1D1DADF5EBB0FE99367AEE6772EA25 +:106D5000EE5F4DE511EC5D92AE09E14D92422ECF12 +:106D6000EEF5C860EFCE825F95326FCAFC99A1E65E +:106D7000577E263BEBAF92F9158E87F4FCC1E47B7E +:106D8000A0F50D157F3F920D1CD78DC7D31FA7D639 +:106D9000F7EF717D514DCCCA1197F6F5436412316E +:106DA0004716F5C27B1A36A894FF4E3F2D613CA8CA +:106DB000A5FD10EA6DB79EA84E13DFBC20333FA19E +:106DC000FAC0C149A0CF4EBFFC23E4CFEA674EA86A +:106DD000102F7EADED076A7769AF3C803D48D8EC57 +:106DE000C1E9EF1E9CC4F4001D3F059D14858D5F15 +:106DF000F3A273FC9A673E748CBFDE6C47FF60A001 +:106E0000793E90C3CB61BD1F1C5608E8D10FDAA5AF +:106E1000CA547EED07DC1E5A786A797DDE6F200F3A +:106E200036ED88CF00BBD9B1299CBF1DFCB5230A24 +:106E300001BD4DE4F0EF3DB4DDF1BACF80FC74C785 +:106E400091659261DB87FED085CF9947CDD9997442 +:106E5000BC99DD9169E0A2BAF546D971BAAFB2F139 +:106E600041DDEB95F9A0EF611F6A8C87F94241D8AB +:106E7000E74A8179952C7F2DEADE94F69A8DA7F862 +:106E80002318AF5274311923837147924423C45796 +:106E900089DFEFCE4F44347B1E6AC5E183B0C5CC99 +:106EA0005DFC62018C132031FD24FA9F2474B11F14 +:106EB000FFCB9D8FB0F09994BF34F9890CFDE6E0CB +:106EC00041D277BCBE7998A806F1ED16FFDAD6223A +:106ED0005B1EA625D8270F3357A178681548CA78B6 +:106EE000ED78A562BE9287BBE368AAE737294CAE6E +:106EF000AE25DDF7AE0138232C9F33CB85AF2F7144 +:106F00007CFDF364BA70AA42CBC1B3A2F89DBD2444 +:106F10001C53E8FDB9AB7A2E7F19BBF37C8E395E2A +:106F2000BC983178FC0D356F17F12CBA5D1944DE31 +:106F30002E5DFEB8170E93EFC7731C798C436FDD7F +:106F4000AF75639EA1B6B5C816F71BDEE92561CC07 +:106F5000E319E81F0EEFBCF39BB741DC39B730E40F +:106F6000257DC7912F5C8D71232B9F2F17863B2189 +:106F7000DE2FEB46B984F32C0F437E61B3C1F205DB +:106F80009B83FDC7F56628D16605E351D7E0B8A21B +:106F9000C6EB0F06B9CE6F2C0E209E0314CF20EF48 +:106FA000B8FF81F51D1778DEBCDB94207F78221BAB +:106FB000F305019994403CE0BCE00B6DC27C823348 +:106FC0006F9E8E7FB7CB26E6CD5B8D3E79F3EF28A3 +:106FD000B67C8396266FAEF99760DE5C23367FB76A +:106FE000A8B75FAFDCB9F2E63016C665B6CF86B893 +:106FF0004C733671E4CD9B41F0AF22E439E5EAD918 +:107000005877E6E5CFCD59B3C3F63639FE32B679B7 +:10701000FCE98FCDE73641FFDC91A416EBD4E40800 +:10702000596AD383EF292C4EBB4109FF50B1D71DBC +:10703000717EB0F23F87DE7A0FF90AAE63285E9B5D +:10704000295F7990AF4E11BB5EB5AE16FF341BFDC4 +:10705000F3857A610AC6CD92EDA0897C110846C3FA +:10706000E114EF4DF230B9B7E60D94513D4AE54DCC +:107070003122988F5275BAE135060F7F3AB82C3E0F +:107080006D36C6B03A289D60FD5EFA754C63714C52 +:10709000887051B876DD787BA83F3FC75AE70C254A +:1070A0007CD28EF7DC4B52D7EF56AB6CDDCD9155D1 +:1070B0002CBF5EE5CCA742FADA1E679D2E44FF5D29 +:1070C000C13821CBA78A5A84E7474C2B3E1E4CC6B9 +:1070D000C30DA833BCCB047DA8AC6A3705B8E6B2B3 +:1070E0007C4AAE16FD58B1D90759EF6672EBCA0F4C +:1070F000CE954E0F09BF565DDCD6061DFDF42D0D55 +:10710000416C6F6E30F0DAD210C6FB6E3A361B2F30 +:10711000076FC1BA341FC665D38DFF604308C789A6 +:107120003594B1F178DE9C90CC26E02B55B4E46523 +:1071300018B6FD127F6E163481FC6D17D8F36B5AAA +:107140002E4579B3F86787D17F5C5A4ACC403E1808 +:10715000EAF87DF9F527B8CEE6597ED4AF03C951D8 +:1071600056279B77B0F328497BC1E6D9314BC379C9 +:1071700076E40E304F9CCD3330FC0C5FDB0E9EC2AC +:107180003A0485F203A828450FA7AED3E3F2D677D9 +:107190001C0FEAF9E620AB0B538BFD6150FECD06C8 +:1071A000CF3716B27CA35A32BC02EEABA1CBB04EA5 +:1071B0005C2DF5633E4F2D1E7E0BB4B71DDCA25730 +:1071C00080FD2814435E03EC76379173516C307E5A +:1071D000AB1697DC06FD7590630AC7280FDB6FA915 +:1071E000C557DD01EF1F9CF29AD144FB3717FA42D5 +:1071F0001E90B76ED9C1FF83D61385CE3C1A91A9D4 +:10720000BEA0FA6BDB94DB4B503E355B9D648A7A03 +:10721000419BDED8A0DAF4864AE6988087747A87A4 +:10722000DADFFBD4BCBEE358EF6F5022F52AEA85C3 +:107230000871D6BBA7CE675BF400370BF2917230B2 +:1072400059A7B7A060786F7EDBAAD373E7B5E3F4E4 +:107250005FAABCB6BBFEFCB3AAD3DBA926EBF446FF +:10726000419DDE8F1512EA84BCFC2FA5D03EA32FD2 +:10727000DFB9C7739FB7A0FE8F06FB9C7472F9330A +:10728000D5993F2D88BAE87EABD731DF2B202FA5CB +:1072900003EB979155CE7146D53AEB6A2FA9CF7182 +:1072A000B48BCC118EFE97B68E713C1F1BBFCCF1F8 +:1072B0007CFCEEA98EF684C4558EFE97B75538DA5D +:1072C00013DBAF73F49F7C6091A33DA573A5A3FF6F +:1072D000155D6B1DCFA71F5EE7783EF3D83D8EF698 +:1072E00095DD5F73F4AFA7EE900A729BCBEB9073C2 +:1072F000F3457B9EB6358FDA25BACFDF9147190665 +:10730000E3DFACAE4B658F937943F77BB2A1867513 +:10731000CCFB8F9B035722D7A13D958DE11506DE4F +:107320009F310FAE649AB3BE5635587D32ECE39C64 +:10733000F502CE3A6355DA86793ACFF12F77099381 +:10734000FAD2552D74CAC160EB9415C3F5DE10E571 +:10735000E2BC2517A3A85C60FCED6309CFB5CCC9DE +:1073600044FFC2B69F423C5AFBA96B34120317D3A9 +:10737000928BF2553D235FC56ED63ECA230EA52ED5 +:10738000CE92BF804DEFC37EC5D233CD6583D3AFE0 +:1073900052E20A873FE9BE3605D6A5D38F051E9B6C +:1073A0007FEFD68F339448213CD7E4B0496CF11A73 +:1073B00052AB38E01E2C9C9FD40EDC45198EA4D015 +:1073C000E32AA9C5BAAB9615610C02903AE2E0D364 +:1073D0009D8BFF47198C4BFDC219CE7532BFD0ED86 +:1073E0004F53FD86FEF40EEA4FA3BD73E947AAA7EB +:1073F0004C5EFF65303F82E943F73A3F2F3FFADFAB +:10740000C059ED875E81A25025EE0FF34402FBC305 +:10741000E6599120C4E7ACBA79EBBD56CFA5384EFA +:107420002C5715217E19EB9A8BF1FA262DAAB13C27 +:107430007114C769CA16F5547562751E962FD6EA7F +:107440001F18BBBF9FB88BA69268AA78DA4E0FCBE5 +:1074500007C5F4B55D604733F35403F6DCAD074F61 +:1074600045208E2497C93AECD70905E61D5B7E8F2F +:107470009028C699B4A0887657ABDF81F30F04EF4C +:10748000CD1E819FFBD8D22FBC5E3575DC251DBC7F +:107490005B00DE6903C3EB05788B60FE6D387F8D82 +:1074A000C748897F85842B6703DD4E7C3982E95686 +:1074B000CA36201F3BCAD8BE9C1A02077F5BFB1C42 +:1074C000CADF0F7BF2B07E15F9DA3AE770A347C73F +:1074D000792CBA92C21C8C6B04A2B1B1C594DF3274 +:1074E000A36C3FDFAB9F181F652A6102F12CD92FD7 +:1074F000627E50E5F110ABDF1F383E9B667523BD01 +:10750000365F29934D426F9D75AC90AE6B72EFBAAA +:10751000FE8F279BF1279FD7479664615D8AF44CC5 +:10752000B03FBDEDE3F872EBEFEF79B8FE2E20052A +:107530004C7F972E877C77BA71DC7E4C3D8FF30EA3 +:10754000BDBE9E9F2FF0DFD30571262BCE4782D381 +:1075500052C6E57BF1CAF295BDF45D6E7452FAC96C +:10756000D3A7629EDC3AAF40D599B35E98D3D7A239 +:10757000AB15472741163FB2E8EC4DE2734FBFF819 +:10758000F482BC5CD1179FBFF2F07CC37F317CBE1C +:10759000023E0DBD6666B2F3E9E4D05709E6A50ADE +:1075A0009D7268BD67F1BB7BFD7FFA2FCA4FD6FA8B +:1075B0002D7E48DFDF4CB9AFB1F2AB999CDF343898 +:1075C000654515CFAB656FB75E0AFBD7A01FF77D8A +:1075D0009965313CDFAB105307BD9069ED6BF879CD +:1075E00023AB5EC957EAF4CB34D7FE45E575517D30 +:1075F000CEDB72FFCD7D8E2A895F17BD266B69F2C7 +:1076000063833C7FB48BE7EB0AEAE28DB01F2EB8B0 +:1076100095D5FBEF51C86AA8AF1C51658ABE5CC8FE +:10762000DF147D3F83AEBFE0C5871A4702496E3540 +:107630008AC0CD7846331C76B8E0AE78B98F3D9FCE +:1076400002E33CA531BD5B5019C773CE4DCF8FCF40 +:10765000023FE195B796EB101FF828B718F74F6770 +:107660005EF08441FF9FC921555817F6C2CCD7C0A0 +:107670008FFF7D43578E6CE39333DF7D7D86428998 +:1076800074E6B9D767C848AC8463FE0D177F310331 +:10769000E0362B48492DE4EF7495C0B8351ACB97E6 +:1076A00059F53EBB86AB2D70FDA9379BC513F3C5BD +:1076B0001DD0AE878018F80D3C9E7FF5696339D4E4 +:1076C0005F66772902D4E33D2498A69F5ECF9F781A +:1076D00048003F4BEDAC85300BBD1F3A042837C73F +:1076E000B27DC9F922525244F5BEEF70ED78F4A78D +:1076F0005DF54E16FFCBB309E6FB7A6ED41260AF90 +:10770000B7CBC6375681FD5E25633DCE76F930CACC +:10771000859B8EC7BD639CF5B93C1E7DE8AD3BE201 +:10772000E5F4FD7BA688C8AFFE1353B2480AF9DD25 +:10773000DE5086F3070ADEAE2C07B03EA67767F46C +:10774000EE93FC3231B3A889548A4453A178F1975F +:1077500011F2B68DEF5A4412D6E9F3171A088ED3F8 +:10776000D1A0E1B5AD411F5B4C3706DF6A08E27579 +:10777000678381D7871B4AF0F9830D2187DCC37C9F +:107780006F97F0760A7FE5F3BA3ED040E7B5C1B116 +:107790006B22957A4AAF5D3C1FF540E9D4ACB5FD4C +:1077A000C4C1F634740D9B3396230BEA4DEBF4BD44 +:1077B0005BFB817F4FA3B07A11F83577CB917DA821 +:1077C0001FA3058B6CFA91FA6D0584B2E2BD2D23DF +:1077D000E6CC29407944799976388AFE7841302E72 +:1077E000401CB1E028BB6F9DB7407A5141FB61EE70 +:1077F0001C4101BD594ADA012CB5344A2A68FF9967 +:10780000794BCAE13E99E8BC3F4365F20DE356D09F +:10781000EB6C2DF2236D3A7CA763B7F92C5DCF1F7B +:107820003B3C06E4791E7CF94F2AEC0B62BF5235D3 +:10783000F0630A5E3C81750F31A15B85CAD8E35ABB +:10784000F51C99EA19DC0C627C952A16CA2731D0FE +:10785000B118FFEC89CDF1C37997E8297BFF5DBEB4 +:10786000E8DDFCE448580B523E4AE62FD6C7C27406 +:10787000D3F902CF5F1CD7D6C5CC4268D3FE53588C +:107880003B46DF7F213B3A52CC86A28BAA58D79742 +:10789000A06DF5AF8A41BDED9B5CEF107FB408E4AD +:1078A0002DD9D6693BD3D696599B68EC6AAD77C380 +:1078B000A13FBD067AAEFA45A11D40A37A8FE1FF34 +:1078C000C0435877DBD6D0A5C7144E7F8B0E542407 +:1078D000270409D6D3A909213186EA8F09FCFB14B4 +:1078E00005D3C24623E8D7841202BD19F231BF7115 +:1078F00042828E6393AB0969BE8382795FA0E336CF +:107900005637ECE6AF67BD2C3F504FCCAD90072308 +:10791000CF283AE623799CF2B465E7F87EF52E2F5E +:107920006B2A9B4CDF65A07FD6C818075B5F142FBE +:1079300057E93CEB7F5414A29615F24A58D7B03E53 +:10794000BB7DF854969772B41FE275B4C16C331BBB +:10795000CE0F541F786834D4055493F8CD5F037864 +:10796000FF95E51F4F1DBC32EB6ADADE40DB107F6E +:10797000DDD0F1BA1AA5FD8671B8AB3BA65C07EB6A +:10798000ABDE2612B188C967783CC573387E994C46 +:10799000F9E49AAD23E77A299D9F1A13D645CA07C1 +:1079A0002B7DE39A3568ABFA04909B95BE89CDC0D8 +:1079B00057EB27F2EF359089AF86655E2F45F96268 +:1079C000D8968618D427EC5F59791D98D9E122936F +:1079D0005BCA88983F94B26398B7F843333BEF0291 +:1079E00029FD8D940EC532E992E97597CAE867B60C +:1079F000C8182FA6F75B95A940977818CF57B432CF +:107A0000BD3FF6450FC69D8B6BC377A25FA097E283 +:107A10003E653449FE605EFA12F88D8E335E27E5CE +:107A2000700EE1C75E162F2C5EB16C3DBC27652E33 +:107A3000F1E1BE5C62E7A0C8B7599C7A979868D715 +:107A400040CE03C548DF5D01C617E6C3A5C817FBD6 +:107A5000C58ACBEE86B8A4B066EBBF005DB38B09D8 +:107A6000D015EEDF43EFEFE7F494B2433AD06F3F27 +:107A7000A7672C219A501F63DD7F41587B27C8DB05 +:107A80003AEFF373348AD7E19E707C18A5C39DDE6C +:107A9000E763C102A4C3188DE2FDCE2D1D316D1424 +:107AA0001DA7313C42B7B5C7FF997A23989FEC4098 +:107AB0007996B31F5E07F24E9FBFA2D1753E95C364 +:107AC000F5057F5E3C26A93FC284DA1AA9B1579F0B +:107AD00068D43E14DBFACFA1FAE0C947591DFBF583 +:107AE000743E9077BA0ECCFFF64C9013509FE5A3EE +:107AF000B080DFE29B3806EBF3E8BA09F8253D13C6 +:107B000065B4B3561CDB3341C4F812F4077EF08D24 +:107B100062FDA9A044406FCA8532EE5765694F786F +:107B20008201E16396D715F485786ED55B62CBE36D +:107B300092DE3A606C17E1676E1CEDB19EEE029129 +:107B4000FA95B9C7170AA3E9787778B9BF9D4BFDB5 +:107B50006D7A7FBD97E9A5FB23E69721C4418CEEA2 +:107B600002D44F243215AEF93715E747FBB14B7DF0 +:107B7000FDEA6EF41F76F8539FD39CEE63FBF92663 +:107B8000FF111DF8AD9E50F907B9D019BF59FAC3BE +:107B90003A9FE0AE27B6F48992CDD65837BF221F60 +:107BA000F480CCEB93643DA4437D6579E634F4FB2B +:107BB0009EF432BD271DBCF20638A7A1FE2BCB0BCD +:107BC000EDF146319ED45340DA815FE56098D8F3F9 +:107BD000BF963E6869D0F0FAC4D4711520274F4C87 +:107BE0001D5EA153193834E9C75D90673AB787C95C +:107BF000EFB9C3B7E1F9C773268B37015B615CB29C +:107C0000F3113CAFFBB81C7910EB6AA13E8282B441 +:107C10002DDB59BF55CCF16272FDD4ACB0E79B1B94 +:107C200058FC58BD7039C6B554AEC73DD15BF1DCC8 +:107C30008687DA32385FA911D364DF3B6078D00AD7 +:107C40009DDFC3502F4CC2F74D2F8B1F59F522EEED +:107C5000BA100B9E191C9EBEE7329CF4B0F65F165C +:107C60001DACF7EB8470BEDE0FDFD45C9048C2160B +:107C7000FFE8ADEF56F1FE59A88BCF823A9E68FC23 +:107C8000EA22908304EE8FBCFE3A42F8F795904FBB +:107C900083728FBD0E3DC35517DF475E0C67DB5DFA +:107CA00017B11E9883D7F1613DAB4CBE29507A9F26 +:107CB000C9F8ED0CF06B6BA87AD02040249B3ACC2D +:107CC0007F96FBFBF28B7787471A363E170CC73E31 +:107CD000A1FAC0428C23D4ECF763BD7F35E8BFC95D +:107CE000706EC0ECF238CE0B843BA13E4F39C0C65B +:107CF0007B12E0A1F7FFA85715C0BA8FC3FE270F6C +:107D0000EC495462875E0E231E62DEF031A2337DA1 +:107D100026539E88655BFAAC3A061B865D2A71F88D +:107D20004BBB7CBCEDAB8EC54A7BEB3F8E6BFF0F34 +:107D3000F59B55DF715CFB0FF48776A9F14ED07788 +:107D4000E60B1E03EC177D1FCFEF9A2B4BD00EC412 +:107D50008AC808C0C32BD92AEAB9D8F39E7DA0E708 +:107D6000666BD13735DBBEE14CF61BA361FF956234 +:107D70003CD331DEA8A18D47E7EF00BC5ACF5FC9E5 +:107D8000DE85E716E97B06E60D0B0F8F5E43DBC34E +:107D90005FF0E0B9216BBFE9E6CB7C2E5F2DAEF33F +:107DA000802AC89B1FF46D2DCA9927E8CC8359728D +:107DB000A75E98E0C8073C097696D24F95A310A21B +:107DC000A4CF4BF1B9C9F9AC85D723A49F2727CD00 +:107DD0003C57A03CA79F67069777C2E558D693DF2C +:107DE00085E9E7DCA03B4FE2D653D6D5D253DFE29C +:107DF000FC2993E8153E3ACFBA44FB3C1FBE1D9DBB +:107E0000047EF0071A3B0755D2F6D0CB609EBFE93F +:107E100009DFEF9D8EE7BEFEC99B37747958E923D1 +:107E2000BC2EB38F1E62FED5ADCC5FAD9B3F15FD62 +:107E3000BBBAED6374FB3945F7B5EA4286430F0DD3 +:107E4000F31AFC7B7B26EAA3AA0B017CFED9CDE7C3 +:107E5000759C5FE93B9F1F9F5BF3DDE5D2B38726EF +:107E6000FD74179C73AFFBBE227A6CF3D47D9FD751 +:107E7000FF7BA9DE75CA7B18E45D2E22C9FA2ED0DD +:107E80000FDB54AB1D6E9E330BFC5A9B7E2803FF09 +:107E9000ABF77DF8CEDD361FEF6F56A6EE9FE1EA19 +:107EA0003FC61A7F21F677C393D43FB01FA3FDE5E9 +:107EB0003F7B2CF8507F3D24BAC6CBB1E6BF11C73B +:107EC000B3FCEE8BDADA574D19F8345E0EFBA79E41 +:107ED000DB8801DF9F785C0EF94276BED518BF566D +:107EE0005DB8D441EF5EBC8F73DC7FAF21E8A8D7CB +:107EF000BD235A8775DA1779FCA98A7AE6F8DE9EDF +:107F0000918E3ADDBFC1F149E1B83A0D1CD77CC171 +:107F1000701439E4B3178E62C7FD4F0AC7428DE96A +:107F2000AFE5FC3A5767E766E71A42A889DE9A4B45 +:107F3000EF7B29AF7F995E357A9D2B13D38FDF4579 +:107F40004DB0FEB40DFBFB1BFE7CEFBBD762A22A3B +:107F5000E8A82B90789DB75BEFC0396F56EFA63934 +:107F6000BE0F675D7D12ABD774DFFFD0C7F0F28D17 +:107F7000CBAB09F8D3D4574F796E6D975FE0DFFB39 +:107F80000C8A8E38376F5B75BE9F155C72069BEF4F +:107F90001B975F4F20AE2BE7A6FEBEDD413F83BFA0 +:107FA000450B639D784CEFFFBB349F149EE14978ED +:107FB000AE413C4969F0546BC1A3B3BC604BF0F3D4 +:107FC00081A724C3A25BFFF8D9CAE126172E413E40 +:107FD00092389D5A60FF96A2BF95FF68D13E5FF828 +:107FE000C383A4EF73195F0C7D170D92BEC55C0EA1 +:107FF0005AF4CF179E5B0709CF7516BF05C348AF6C +:10800000CF0B9EAF0C129E6316BD8CCF173FAD49B0 +:10801000FEEF1F9EBF70B8F333581CA4A5849D27A4 +:10802000F14991078B8481E5C257ECDC676B853E93 +:10803000679DCDBBCEBAAF74EBFC355F673A795A1A +:10804000A924F2807EC71A583CE00DBE3FF9755551 +:108050005326C6E75DF3B404F765F617B7F9EF5595 +:10806000CE73B903C9F1A40C96FFB931EA7C6FF95C +:108070008A0C571D9989FD2CFCA51BEFAF056F617C +:1080800048620E026F145F5945FDEC1B3E6B7CA5E8 +:1080900093BBA1E22BA60F0D5F03C9FB5786882F68 +:1080A0004B5EFF5AF1950FF89AFE37FE1A2CBE165A +:1080B000FD4D1E8784AF5B872A8FDCAFFD6BC5D774 +:1080C00060E5D1BD6FA3FBBB507FDF17F8ACF1E7D4 +:1080D0009EFFD3E2D11A6F659A7D5E3A7C0E0487CB +:1080E00075FDD03748BCBAF79F5F345E5DF37F6A99 +:1080F000BCF2F1868CD701E0B0AEF220E5DBF2EB0A +:10810000DAD4D4DF111D97C9BEE3365EA83D321F15 +:10811000F2C77F27617EFAC89E391BECF540E33237 +:1081200099BF7DA472F606889F9E8B6460EDD9513D +:1081300031F4F36990575EC4DE738F7F84E3CB9391 +:10814000996DC57FF380AE47238BFB954752695BE2 +:1081500017E68D6CF495FAE2FB0831B64F833CC408 +:1081600082D47058744E37EF50E97B34F2F890F4B3 +:10817000CF40EBFD0FFF9841EA9F04F6CB25C9BF26 +:10818000BB7319E0B34D64F570C7E156017CD78D20 +:1081900060A7E52BF2F7029DEECE64F9C30ED5D8A9 +:1081A00000F913CFE2050F6452BA1D5D9A2DD8CFA6 +:1081B0005FCEC964FBAF19AB52EFBB16723EE87DD0 +:1081C0005F20E353F07798F75BBA8A7D7F8CC8E134 +:1081D000518B6CE74ED7BB9EF7A1476600E1389AFA +:1081E000E6DCFF02FEFEF225FDBF4F6AD9F77D28CF +:1081F000DF8DB29F7B4DF219978F33FEE8D24C7A18 +:108200007D43887EE73EE0A3097E766E4826455092 +:108210007F658D932B934E95E2FD5DC5180579CD55 +:1082200014E3DC9C393DFD38E9F06AADC79A074498 +:1082300011BED333576371C46961426641FCD013E8 +:10824000BA9BE50F191FE4F03AC499B5198946D8CD +:10825000F7CA749D36783BFEEFECFF06CF3B8E8865 +:108260003A9E6F77E16120FDD094C9F2C9B952748A +:108270009317F226AB8594DFB1DB98C9FEDED1A45B +:10828000CC64BD14CE336E675481EF5F2C9359FEDE +:108290008B90E8A885B6F927717E73BF972BB17ACA +:1082A00023F22693E7B67DEB46A5929F5F70399D3A +:1082B0009459E2A8735C12B95B01F95CB260A162E7 +:1082C000F8E1B981E32FE570B4A9D15153FCBD7831 +:1082D0004AAB87387E3A8E459BE0BB1FABEB05ACC3 +:1082E0001328DDC8F86EF5C683E2067ADDCBE56FAC +:1082F00021D0C036DE77395DDBF6F94603FC6DC967 +:10830000FC0D1D98C271F36E82F99027B79F6E81A4 +:108310007C48B74078FEE4C64AA86BE8E6F56D2FC6 +:10832000D3E78D80BF397928DFE3367E5807FAB965 +:108330004325785EE6775B3C09384F60F14B524F3E +:108340006C3CDF00F5C38FA89D13816FF29A6AEF32 +:108350004B953F7D89D3E18FFE48562A3FD0BA5ACC +:10836000FADCEAB748369454FD1757BAEC1A877B03 +:1083700098A7F30C4991C74CF261A27F3FED975C3F +:108380008FFFC295E75D722C759CF1579C7FDB12C5 +:1083900015EBD16E991E3C8762C163E12BD76478DF +:1083A0005AB64472E8DBD50B325C7E0FC3EB0D1E70 +:1083B000E35158C723FB7E3A11CF51B9EC834F8A62 +:1083C000AAF0FC0ED2A9809E785F32F0FA4683F3C1 +:1083D000EFBCBC41A2DBA783FDAC9752CAD51F39C5 +:1083E000FFBCB1E296A5087F4CD201FE13AB865DBF +:1083F0005F06FA65851282EFA69F88DD9B799B6DEB +:10840000FD49BFC605D7AFAB6EE9D76E2D5FE1A4BE +:108410005B9BCAFC02F33A268777521E9D85FCD5EA +:10842000BD7D269DFF482267CA56D69DC0DF995A5A +:10843000CC7F7F5F8CEE9849F5CD2991E549CCAF93 +:1084400030BDB16467A41952A7A7EAAF78A99BF61B +:10845000F30618DFFDB6BE7FFBE8E6A7713B9DFE85 +:10846000DE8C634485F7A375A9EDC1B7F50CFEF763 +:10847000C442A341BFDCB43175BFFF05CC4CE13928 +:10848000F517A92A557CF22A9DC1BB3A92FAFDAB99 +:10849000F44CF61CEC520A3C9F0B64703DA78F060F +:1084A0003DBD3A0DBC1F060208EF3BCDF7DF04755A +:1084B00020EFBBBE03FF4E80F1C5C100E3EF53FBCD +:1084C000562A7940A71641077E783B3B3401F86D68 +:1084D0004DEC049E7739C0F1FCA62F3225301DE407 +:1084E00065D1DC3C4A978E55242418E9F5FF9501A7 +:1084F000E637E4F2782DB57FEF82FDA3AFBE8BFEA9 +:10850000871C1E7DE34456020575E0A744731DD603 +:1085100019EEF3B1BA52129A6EF7E3BFCCE138B557 +:108520007F68F45E1A71F9417DFCBF7835CEBB3FA0 +:108530004387BA94239552E7B514C893FB33F0FBF5 +:10854000B86EB94837FF50FDC053FB87E6070EB43D +:10855000EE0D81A241F981E72A1FD9310DE4488D42 +:108560004F4AA57F2D3D7D94C7DFDDFC635DBFCA0B +:10857000F9E8FD44FF70DDB1DB09CF4DB54E782C35 +:1085800079793FD1E45B0378229D13ED7E299933FD +:108590007D003BCBF253E9E0DCEED213C07940879B +:1085A0003BB9BEF96DFD23013B1DDCEB3F25F2FD20 +:1085B000C1A3AC2E776C644D459ED1CB9FDFFA9C56 +:1085C000F8D2B233EE71FEB3F3A165E706E2C3DC85 +:1085D00034799C4970D099BEBF46D655C8D74F0A4A +:1085E00018AC4DF47970548B94F1BA51628C86F3C7 +:1085F0005FA7F6F9F0EF43995B3D89B15404DEDFE4 +:1086000077F504FB7A7EC5F974F5926CFCFCC4FB2B +:1086100062687E3ED69D49F81DB7378EE5CC83F65D +:10862000238745D0D0E4A6BA3512ACEF8D00DB77B6 +:10863000AEDEF83AFA8343E5F3D5B54EFB7F155F1E +:1086400047D2CF927BA601FFA4C3C36B1C0F4B2361 +:108650000BE7827EBE65A380FAF627300E5DC82D3B +:108660007218F5368931FB48348A0F6A424EC022AF +:10867000001FFFC0BF5B254754FB39B9DBB6DD3FA8 +:1086800017FC43B7BCACC8627C5C91C5ECC29BBE16 +:10869000E81F40DF5BFAF96DA1F6603EEDB231A054 +:1086A0005BDF094639B5D6B391C345FDB467F1FB2D +:1086B000C57C7DA4C7C56F62BCFAC780FF0A0DFDEB +:1086C000029F87EA7DA88B7EDC877554965C59FEF5 +:1086D0008EFBFD6572D4E13766661539FC77B71FEE +:1086E000F2377B91BAFF15595FACBDB836EBB3B129 +:1086F00017C3389FB9ED4652AE5BD8799013C73E89 +:108700009A9B4AAE239F100EB73CBFBFCFC7BE9BFC +:108710007C4D26EA9DDEFD547E02F6CB6EB980FDCF +:10872000147CF7E3917D3F9B0875BD27B6DF7F532F +:108730002A7ACED299DF44BAF31DF1BCB50182F595 +:10874000DF84CEF7846D7CEBBDA4BC0C10BF5CB69F +:10875000F24ADC4FBEB1F2EAD16B4AFBEE2BFAF4DF +:1087600017A2FFB014E66DE4FBE91D9EAA7DA9F6F1 +:10877000811CAF7DE3C44EFF7EE9C6F266D8526F1E +:10878000CAB8E64BD114F327F7351B53C7E31EE4F1 +:108790007A2AB9AF31E9BE86E2A37B9514289BD62D +:1087A000BBAFE9363F9F7DCDEF48CFCF67A2FCA797 +:1087B00086EF7B167FA9D11D5752F84ED1FD8F0948 +:1087C000F223D2F7805FBE957ABFF6387FEF771B32 +:1087D00087A8AF8E39F733E9E4EF7B9F91FCB5A909 +:1087E0003DA3400FFC6EEFC76FDD0FEBD9EB437C71 +:1087F000BBC789E812DF5FF8906F2DFBDCA132FD6B +:10880000FFBBBF1B817F37DB2D1F84C4AFBF8A3EF8 +:108810003FBE4F9C02DF596CDB9751956A9FB35E58 +:1088200017787CC919EF21DCBF5BCAF94DDFF774FB +:10883000AD3D1EFD26D757561CE07F67313BBB641C +:10884000C14215E23DB725E34D04372BFA65857B20 +:10885000E1FB17BFE4E7B9CCB59929CFC7FD86E3A3 +:1088600077A038C48A55CE38C19205FDDB9B938929 +:10887000D47559163FA79B6FA8F6A52D31B4BCD867 +:1088800040EB1CA10FCEBE2C25B55F8278C73212FB +:1088900052E0BA84D44EFC3145E5C9DD8B119E5FB0 +:1088A0005A7FFFF8E37B27DAFD98FF0F11FE85A1C1 +: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 +:10C7C000E52F535D223FAC724032E57370F664EEA4 +:10C7D0000C340453291E45791E95E4F913D1DBFF6F +:10C7E000D0B8443E7F20FB3314F9F79138B7810568 +:10C7F00052200BE9B1A54DF4F36E4F64FC6E82201C +:10C80000F3F166085B09FF5B00D8EECE0195DB5BB8 +:10C81000C1C3FCC495E3F2D10EDDDEA68C5C857845 +:10C82000162475A6937EE68D7E2F4942B8F229FE26 +:10C8300075726D6605C5293A1E964C81C765999E2D +:10C84000B709BE82A4D0AAD514176EB600C5859FBD +:10C850008EBEE70E88F2AB2559150769DE73923854 +:10C860002FF46FB38BBA1A74F6F746C5E35F6756B9 +:10C870001E22BDFF07C1C6F9EF2A3E47AA7609DA94 +:10C88000C3F87E4C037C6F8837AF27FDF4B37D2C53 +:10C89000205A8A3AA11F4A795FEE7FF5D417D5CD89 +:10C8A000021F3FC5632559BE08ED5760435348F04A +:10C8B0003F610FACE3B8A97E08D52FE63D69B7907C +:10C8C0001F7F0FED309D9B7ED0E8E0F643CC6FA834 +:10C8D000FD1BE637D47E84F90DB57FC7FC86DADB15 +:10C8E0004F8F402102F861A6E77F33CE8347EF7672 +:10C8F00046E0119160664FE77DA73244FE91DFF676 +:10C90000F1037124075B6437C969DE6685EB10C7E4 +:10C91000B78E0AC869D174F5C565221CF95BDE7E45 +:10C92000746C11BDA7B8249C7F7CCBC9FE9C379941 +:10C93000E0EBA2C7369BA08706EF7389A155F4FEF2 +:10C94000739BD30942B42320E490F8D9431D0D60B2 +:10C9500019F3F1F50C113F5D6BEF2C8A3EDF040AF1 +:10C9600019A85EA9F9992AF96C423857ABDB8E26D3 +:10C97000B9CE7C83F6F3EF117A887C35D4252A353D +:10C9800039D4DBBC6D362FE9D373DBDE993619E978 +:10C990003075CCA46259ED9E5F98D98FF7CD1B7D81 +:10C9A000E657AB93793E9F5BDC006BAB5C38EF26C0 +:10C9B000C78E57890437BB3EAA4AC4FE2D29D26EC2 +:10C9C0006AE7A8691392C80E4080F7B935A77C378B +:10C9D00089D81477B58DFC7239295594DDAD74C4AE +:10C9E000D1496A57BFCAD5D7D0BF2A659061FE2406 +:10C9F00035C3303E3967B8615CDF778ABBD0308F92 +:10CA0000F495E266C483F90EEB653E97C9DBFCC57D +:10CA1000FB8B18FF1B8A08FF08D2CF8681C591D2F5 +:10CA200095BF584D6663F3CE043EA735C5A735DBE9 +:10CA30009EDAED517B8F4FBF84AD3DC675B5BDC449 +:10CA400075171B9FA2FD7894EC47C10BD7F1B9FB7A +:10CA500073A3CF5CA6225EBE4C8C5BC9EE99E2D676 +:10CA60008816B79AE5A74B4E2555C8CD5E19280EF6 +:10CA7000D2E357B3FC003CA0F97FD15EAA9E4F7D64 +:10CA80004BF8AB7F90BEF78D966BAD35D5230A6C16 +:10CA9000E857A84EF85719D6D183B308874EFF8CB4 +:10CAA0006EB987DBD6BE3AB0889FFBE371CB5AAD37 +:10CAB0003EF1AB4CED9CBF66C7AB0393BBC7E1AE89 +:10CAC0008F0CF3E13E69B7A1DF9C66EC3F5CBE3B97 +:10CAD000FAFDDEECD0BC3577DA7C54977E4CD42955 +:10CAE000CDE33A3C553B633C642F95AD76CE876AE7 +:10CAF0005D1EAE9F28BDD44F74BB70830CF53DD92D +:10CB0000B7F5DABA5376C680FC2DD67D0F6585E081 +:10CB1000F1BF28FCCC7B7D3CE08DDAA73553C47D8A +:10CB2000C7125B7EFC15CE3BF612B889F4C712859E +:10CB3000BDCD6FFBD462213F112BE425DF15B62458 +:10CB4000D17D97F9717E3A4FAE5B10EFA773A38248 +:10CB5000F4CE771CC8FA2D4FFB1E75A0DCBD6FB15B +:10CB600018FC4E846C1DF67764FAA691DF99BC33ED +:10CB70002668F916F8ECC804E1D72A84BECF26B996 +:10CB8000D1CFC5D0D4D43D08867332C29FFA679EF8 +:10CB9000BEF5ADC728EEDD2BF41F879DE67CF4A61D +:10CBA000A87C14D608FD75E02FC5390B77B5D828B9 +:10CBB0004FFAAEF4BE3DD3D9ADDFC3CED5675DDF4E +:10CBC000EB0E087D3FB1F5CBB7C8AE9F407F17ADE8 +:10CBD000EF5D7E51D3F3BAC765D647FDF9F1ADF2EB +:10CBE000C4400FF47D4D930370651BCECD96949D8C +:10CBF0009A467E6DC93685CF037BF3D7752B8CE7BC +:10CC000064CF6DB7CF17E7C8028F88EE4FB77D9915 +:10CC1000549E2BDA657C5EDBA2D91D11C7A01FB51F +:10CC200026931FAD96B8FE7660DB00BE9F714082F2 +:10CC3000A03A9297B8CE817C9B2E96A3E74E8AC7E6 +:10CC4000202547A17DA669FC9CAED585666C9B918D +:10CC500045FC7AA76DEE010FA19795C1F2733DF8DF +:10CC6000391E3C90E84DA57B0A539B847C1F48EC01 +:10CC7000ECA03AD281B23889CEA370FDE6E878EF15 +:10CC800080D59B5ACF78E9E79357C8DFC45D421E31 +:10CC9000ACD943E4A75F12F91CCBBF32F06196AB6D +:10CCA0000510D8EDC17D6BDD418E4B1781C8EBCDF2 +:10CCB000F17CEDB8CF6CE417CCF967F9961D07E964 +:10CCC000DCE39C3A84495E2F547730E7BDBDD50F35 +:10CCD0004625790BB3A2EA7EE6F8BC2B0ED5E3A875 +:10CCE000F5717C2EF44AD97F1F5F84FDBBD6C7B98E +:10CCF00028CF3EFAA4DD4F76F9E83A7B40C2F1A393 +:10CD0000499DED94771CDD94E7C615609E45FDDDD9 +:10CD1000B3E4D77F6B65B90030DE6B58527637DFEE +:10CD2000FF5BB23E5EA27B389022C6F59C4F7E260A +:10CD30009EE38205CF0FE4734EDDBF907ED0B9F441 +:10CD40009127623C14E41FDD33BD0FD5FB3A2C7FE5 +:10CD5000E0F37C90EF3B44E7F58B36C48FA4F801F9 +:10CD60007281F9367FDDE57CBEF973C53783F0AF9C +:10CD70007CE69A0174AF6CC1DBFD80F0896C7D9E0E +:10CD8000CFFFBAE3F49EE3BB135B33FA406E379DEB +:10CD9000F43AE08AA7977989EFC5922ACE69A0DE96 +:10CDA0003388E4624B35D0BA2365716FB473651C68 +:10CDB000C7A566B9ABC91271608D5E6FE80B8E14A2 +:10CDC000D21F1F301D222B87AFA3F3B0E6AC24CDBA +:10CDD0004F77664F8BBA975825B7D7BE4CF2B9C676 +:10CDE000CE75908E989ECFC11AB21279FE3C87F113 +:10CDF000DCBCB6E18CB19F8BF91DBE3FB2492DBCA6 +:10CE000013DBA51AFD57A77AEFCDC2F717B63EF28E +:10CE1000C23EA6CB9A1FBE4FFBEE718AFACB3E41B3 +:10CE20003F73FC3FCF21EA1C006B797FFDF9A74FD0 +:10CE3000BCCBE7AB9F6E1E9E2DCE8D439FFC3A8DE3 +:10CE4000CF8B0FDD8BEDA63D6F315FCCF09E73EE87 +:10CE500027498C6F0DE1D197CE77BD8F109CC80804 +:10CE6000CEDBE6AECA63FAE9E76F91A33DE7273A66 +:10CE70009CFAFA3A7CFAFAFABC27B3441E335BCB2D +:10CE80000F8ED942C7F91CFD85E112D5F7BA9E274E +:10CE900085F213A3E4E5BBAAA7DFA8D5430E5A96F3 +:10CEA000FDC046F7E45A575B7DD176EF12EBE85DA3 +:10CEB00071A00754577FE14AD86F21724A7F3AEF39 +:10CEC000D3FAA40CD81FA78127113C746F506B6153 +:10CED000A12F85EBE4B49E4CD71003DC6F2A77AB0F +:10CEE000D45E29791571EF2BC0F23F01EA07131EBA +:10CEF000164798CFC5F47B2E3312975F9386FB3588 +:10CF0000F783E514C7345B855EF8E7C471FEA6D3EA +:10CF100049F733E0CA35F8976617A80AAE3353814C +:10CF200015D624316F28D2F9C09EB9AF529CF0AE0D +:10CF300052DF8FF67DCFF9589E64A1F82E104F393D +:10CF4000E2FB6FFDB6F8AF38F703F09439517EAECF +:10CF50007BCDC176DF5C8FB81D7CDC9F0761EB1752 +:10CF6000F8DEDF46FF6BFD4EE8C6EB6F63BEDA4CC2 +:10CF7000F9C14D890F14D3FBFA3D4CF37DBFA32EAD +:10CF800027DF0B34DFFBBB167C9F91DD3A65F1D5C3 +:10CF90008AFA47FD28F2BF91441B48383FD24FA37D +:10CFA000C731607A44ACDAFB9FABDC2FAA1CC9F511 +:10CFB0004838A5B23D1E6BF23745C32D220FFB4604 +:10CFC000CC2FEB540CFEA6A840ABDB7CAD725C7A98 +:10CFD000E569E5BCFEE8A16C61CF8AFA5AEA7B8A72 +:10CFE0000FD56CA13F4D1094053E224E18DB2557FE +:10CFF0001E99F857ABF56BC99FA13C45121C7EBA30 +:10D00000E83876AB90AFB14A7007B5685DA181E2B0 +:10D010008A2DE8EF7438E88C306538CBC1185D3E56 +:10D0200071AD59386FB954CF798B83E2196C574978 +:10D030002186E37BD0C9AD47F3E315E0E6763C7883 +:10D04000B945F9E47622B4707B35B4723B0542C22F +:10D05000EF5F116C627F06F7B9F8DC62D23C0BC55A +:10D060001B45D7F79C2F546874EA9D0EA87025972E +:10D070004E8709807A97D1033D06E7B0FD30D3C3D0 +:10D08000AC9F651096593FC93064509D40653DADD9 +:10D09000040FF7AB2E920EA5619FC2751A333D2A7D +:10D0A0007B968BC91A3DFE950D2C1F3A9FEECF56ED +:10D0B000F9B9CE2FD4AB14927F331FF5E745711524 +:10D0C00027E96AFA1DD9C3A7D3BDAAA2C28AA5645B +:10D0D00092EFDE30663ADDAB2A1A5BF13C1D79DE59 +:10D0E000933D4EF40B2A0AAD6ECC5AA4B2E9E3711B +:10D0F000BE4FBB970C33457C7D9716B7F896FDC0A5 +:10D10000ED423DF1A53ADD849F03837BAA7FCA19D6 +:10D11000E27C70C8C4E04E2BCE3BA4F8E664537C9E +:10D12000E00826A848F7BB9655F1BDB5876C62BEEE +:10D13000DD2EEAB03A5EF8DC1F83FD4D9B862F950D +:10D14000D27BDF1FD7ADA5757DCBB2FCA4AFBECD22 +:10D15000925B70B262C04CD4CF8E9015A81EAAEF1D +:10D16000939DEA5B9ACDE7BAD95C271BA4C5331D12 +:10D170009B860F27BEDC9FADDDC34A4E2B24BA2D04 +:10D180004BF5DE4FF323F142BEEED7F8D05BBB2167 +:10D19000DB735F76F1B9CF23FF4000F0FD9F65FBA5 +:10D1A0001EA0F5EAE2CEB27F3F3EE2EDE5E1B46ECD +:10D1B00039959049B310EF260F046CEC07B4FBEAE5 +:10D1C000DA7955E4765C07E950E4F53591491B3589 +:10D1D000ABB384EC27AEFB5FBCAE2D3C6404BEF762 +:10D1E000D8F44336216783859C697668DBF6BDF702 +:10D1F0000E125D2F44E955DDF6335F7D80F4AB3BC5 +:10D20000E174D3F46E7DFAE552CE27C169B01BBA42 +:10D210009E8DD962E7B87AECD6CB6FA779656FB7E8 +:10D2200067105E57B687F91C2CB2EDDD41020E3D4A +:10D23000DF38257D1BBF4BE7B49CC76D16E7B44BA9 +:10D24000A4FA57E2A9FF7BC9ED47F83FD5FC869EBB +:10D2500017CFD7F05ABC77FD72AA8BCC5F73EB1453 +:10D26000BEC7131079838ABFA4FF5FC23E3E1F5F13 +:10D27000B4D19C4F74DA88FF8B5B4DF781281FA6D1 +:10D280007B0FD1F6BD877C787BB6764E9B0AA98C46 +:10D29000873CAB8FAF077B67CE771F07CFAB2C9F49 +:10D2A000E09569FF62A5E77AC273DDDFD3B03ECCBB +:10D2B000D3F6263A3939DFB589FBC24F2C75BBA8A6 +:10D2C000AFE9E75A9495528AA33B7FC9F2AFBFA753 +:10D2D000EBEB8215E25E36ACE9CB3257B0C1EE2102 +:10D2E000BE166C18C0F905E6411CF7ADDD605F4164 +:10D2F000FDA60763FD7201D5933B2FA3BA4A538C59 +:10D30000F8CE89DC23DD132D4817758E33BA5DD72F +:10D31000FCBA7EDFB62BFF89CFE67BCD5DE361C52E +:10D32000906F3469F17311C1477160BD55E44F319D +:10D3300002FE1D6F7E3F8EE2D8CD8A378EEAD2275D +:10D34000F6A7F7811EE8A6B7C5E85EE03CE78CC506 +:10D35000EF4EC9381FBF8A1ED7EEA76BF2F9C7463A +:10D360000FFCDDDACD0F1DAF2AF9D94A1BD5396E76 +:10D370000317D53D96EC7DAA89BEB759B212B8A263 +:10D380007082FE50BE70C4C2E7E063F616A6903C01 +:10D39000B669F68ECE85D528B92AA1A210CE2F1E49 +:10D3A0000C01FAFE28468D05352A2F8ECB4932F422 +:10D3B000E3DD9719DEEF539A6E1807BF27945BD20F +:10D3C0001DBF267AAE30CC7F2861027F8F5316BAFC +:10D3D00083EB4A7D278E348CDB51AEE99E037C21A2 +:10D3E000E29F52FC65BF0AF532C139360CF02B942E +:10D3F000BB311DC6F8A834DCC27960CC7EC590D79D +:10D40000DB2F5067BA7C98A6578361B0B00F667A5D +:10D410001BEF432CD92B731CB7241503CFB4DEE9C3 +:10D42000ADEB9F4EF77E5E23DD07CC34D279A0CFE3 +:10D4300048E741F38D744EAD37D279688391AE6978 +:10D440007E231D33568C31CCCF6AA930F4873D7EC4 +:10D45000B561FEE5816986FEF08D371AE6E7B5CE47 +:10D46000358C176C59785EBE8F082E318C9BF95E17 +:10D47000B8E74726395498CEC5DAF7593AFFFDF890 +:10D480004BFC1F0BDE3E4189CA81FE26D2C7FF2F0F +:10D49000FE2F18A69D23E8FCBF48BB7A95E687CDF2 +:10D4A000DF794D8D13F6E6F53D27F67BB0FF865A02 +:10D4B000684DA1B8498B0FBCFA798429EFD3F39456 +:10D4C0006B4B25D3397D8CE19CFE42F7DA8A4341D0 +:10D4D000437FC47EF17DD4C883EE57A82DFED823A8 +:10D4E000477F0F35FA0B76CBE7E49DFAFD383D6FA9 +:10D4F00082E627390F9DA5C34F4A50726E7D51CFEA +:10D500004FCD79AB9EAF9EFBBD95884BEE967BCB06 +:10D510006345FEAAE7ADDF070F7F5776D560DFDAF8 +:10D520006168FF654B675F1AD7F359222C9D1B4733 +:10D5300088B0FCDDCC3BD33DB9FC3D2AD7BD174AB2 +:10D540006F4FA77BFE08BE2B5C22CA3FF4F3D2309C +:10D55000DFEF68BDC3926B7921BEFBFA98CF86D00E +:10D560007AFF334CC46F76192984FE67C02C0FD024 +:10D57000F351499EE768BEF97EB6B935DF1B6A6B89 +:10D580000C72ABB8DC7C6FC75C1F0C5B548E3BFD30 +:10D590003F92F89ECE6704DCE8EE78E5C40A2BC71C +:10D5A0002BA0E5E3376BF4D7EB16B3347C0EE31214 +:10D5B000F3D1FFDEBCE535E6CBA2940EADDE51CF54 +:10D5C000F1F5AD839D23F91E9AA7D02DEA5C7A1D53 +:10D5D00063D0257D5F7221FC17A51C35D491E0D95D +:10D5E000BE1775BEDD8DB758FFF04A518F3CBC3277 +:10D5F00095EBDFDDEB1FE77AD2CDF56F1AF4E296FB +:10D6000086F70C7A30C7FF91613C9CDC69A5FA6112 +:10D61000F88581136E42FA1DDB6CE7EFA1510E3ADB +:10D6200088AFFAFAE195C3C7F3779517C4F3338649 +:10D63000A3BD31C4FCD5F13CD47890FBE1C630B732 +:10D64000663CF53A85DEDA76420EDDCFEF9462DD98 +:10D65000541736D72FEEB6A89F901E3C9493AEC5B4 +:10D660006BF5055EE69FA857B46BDF97B66BDF9747 +:10D67000B66BDF8BB66BDF87B66BDF8146ACCE1542 +:10D6800054D76897C4BD9F5992E7C939B85FDA602B +:10D690009F3387E2FE859DF90AEE5357109E2D2198 +:10D6A0009FF3FAF9FAD07309D38581FC3D919FEF7E +:10D6B000871DB1F8F3E9FB9BC91BB3AEA33CF0484F +:10D6C000ACFF384522953969D751DE77C426F4700E +:10D6D000FAC6D8EB48EF3EC6C5083FFF4B92A82BD1 +:10D6E00039C336FA7E6A6AB26F504EB1B8F7C5DFF9 +:10D6F000CDE073924BBDCE19B18A3830A2C583E913 +:10D7000039E21C302347C4AD7A5B463CC7E7D3A956 +:10D7100065FD7C389BBF375963078A5F717FFEBE0A +:10D7200046BF6762FEFE66E49FECFC9D845E0F2DA3 +:10D73000C949E375E8BB1CD2CBE49FC4B1DD82705C +:10D7400068087DC7D305EF7EF15DE531AA2347D593 +:10D750009F4B72441D066E03C377408BF71E3E44F9 +:10D7600079D6FBC37C6388AE732D6A09F17571C2EB +:10D770000EAE774DC951795F8497F145FBD34C7C50 +:10D780005AEC08737DEC42F5F0DEF03F767BE8174B +:10D79000B95CFF55F3F93B3C6D5F84630AD15FC709 +:10D7A0005B87A37B9DF3CBBF5ED7D5FB9F3EF1503C +:10D7B000B65697BFC5DB833FBD55A34BBBB5E73A14 +:10D7C000FAFD1A7FCFE1CF3000AADBDB63D14760DF +:10D7D0005BAFD1E9D80D880FD7273C2388BF8BA733 +:10D7E00039F9FB737D7D5CC7F787F3ECB33AD5BBA2 +:10D7F00090F05F582FEAEEFA7844127CF5AF14757A +:10D80000D0C5DBDF3B44FF1F8405CFE415727EAF3C +:10D81000BD6FA633D297BF8B9A2B8B732BA4EFDDF2 +:10D82000C46773BDFDDBD235922ACE57236BCF0C74 +:10D83000A17B648BE9DE1A7D1FA6D5AFA0CD5897DA +:10D84000427AF9A95E71EE7914F0B9965DF3237608 +:10D85000FDFDC18AE1FD634EEF4F893E2F687603DF +:10D86000E7072CB87F9B9E279BEA286D2151EF6C20 +:10D870004BB1719C4CF10EF9273DDEB9EB4D51EFE8 +:10D88000BC2B4DC4D1041FF1573AB89BE3842EFF43 +:10D890002FB955A29FD3EA0BD0FEE05BCAFE4B1E08 +:10D8A0008AFCA5F38B3F5FADD503843F2CD6FC5F8C +:10D8B00031AD43014E6E1FF68B45DABE183F72DD67 +:10D8C0006D34F89A04305ADD6CE56E431DE1FF00BB +:10D8D00090CECABD504500000000000000000000CE +:10D8E0001F8B080000000000000BFB51CFC0F003AD +:10D8F0000917B1A1F26FA0F1B33851F9BF5951F92D +:10D9000097D0F884B02E1303C30A46D2F420E39DC7 +:10D9100040FD0780F838109F6322DF1C103E210C69 +:10D92000F48F1803C34220DD0DA4AF00F11F207E49 +:10D9300004E44B8B30306801F1325106864420BD3F +:10D940000688CB4520FA4E02E96651F2ECD4E3A1F9 +:10D95000CCCDA39832BC411A955FA3C2C0B05695F6 +:10D9600081E1931A84BF02499E5D9D81A15605C243 +:10D9700036956360E807AA59208DDD5C33A0FC046E +:10D98000A0BCB83A840F00134DDDCB680300000043 +:10D9900000000000000000001F8B080000000000D5 +:10D9A000000BCD3D097855D599FF5DDEBEE42679A3 +:10D9B000819705B8090183067C09612DE24D8C1819 +:10D9C0006C8A2F88364E197DA0D56859223235B61B +:10D9D000DABC4012C2A6416D8741A52F5A2D525A7A +:10D9E000A3624B67D4792C1DD1B1355AAA76A49D78 +:10D9F000C8388E5A65E242AB558739FF7FCE4DEE6F +:10DA0000BD7909A89DF98ACBE1DC7B96FFFCE7DFB5 +:10DA1000CF7FEE73CB3E80090027F1CFB900574B83 +:10DA2000009037548237D608118026CDAD6F2A0674 +:10DA3000F886123BAC57B1E763E5D8FD3A3E9F5CF0 +:10DA40000B610005DBE703C4F07FACDFFAE0BA311D +:10DA500089207BA62CCDC2D21CDF2C9B5400AD129A +:10DA6000DF6F999CE9BD5942CA35D0EF05FA73B210 +:10DA700004A0E5E86FA71E32EBECBF0208455E0F7D +:10DA8000B0BFCC8259271580F7828BB3D230F278A1 +:10DA90006FB5769FA54E02F853EBCB530F4D1AFE90 +:10DAA000FE1B0A34F7960F7F3E0BD8A433101F4994 +:10DAB000777CEAD0BA07D71964489AC3FA03A43D21 +:10DAC00039ACDCB5ED2CB56C084EE73A00921CBFC2 +:10DAD0009FB39F2752932E60B50A29318FE052D908 +:10DAE0003F3301A829DB97EB763500C1E580B723EA +:10DAF000F2978177C4FD12EDDE0BAEEB04D66FBD5D +:10DB00008BD34B7B9E1C5B07C3E9C5DC0F138FA730 +:10DB1000BB1F37818FE631E9A8495E3AEABE9F8A8A +:10DB20008EAE443A3AEBFF9E8E927FBD74D441E3B1 +:10DB3000FC95D1114037C717F4AB38FFD0735E4660 +:10DB400096F64A4867ACDA87708FE353C1B896CE31 +:10DB5000EBE5694C4C41ECE93398DC1AD7BFAC1EBD +:10DB6000E11E7B74E19B58762EA9A93B9FAD2FBF88 +:10DB7000B1F7F90B581989A7A404DBAF3B4046A1C4 +:10DB8000C2C65B91AC66EB6BC7C1E6023C905C66BB +:10DB90002471BD60008C01F83BB126005957593DF6 +:10DBA000447FCDB40E37A4393EA4939EE1FD475A7D +:10DBB0007F08FB996D8AF1FF6B00D777AA7EB0963C +:10DBC000CF9764FF20BE0B87E6A771F29B2C7540B0 +:10DBD000FCD8DFF7E15F08BFD7FFBFCC5700953E09 +:10DBE000940FA17A594B617BE8CD56593DB24285DD +:10DBF0003493110555DD924B3FF5BE7402D4F5F216 +:10DC0000FD911A4243F0FD2748443FE3BFF55ACF48 +:10DC100006467227960663441F1A406ECEF0F57CC6 +:10DC2000B71509D9525F52232568BED8D3A5AC7F5A +:10DC30007209D77B77D42FCEB6CA2B8F2409BC3973 +:10DC4000E903747526B215A70FB55E367CD3BE38CE +:10DC50007DA89F933EF2D65AFAC167DFAF88691755 +:10DC60009C267D7CD1F9CC7D1DCE576D625F4B7DAE +:10DC7000C0F8F6F6BAC519ED8C91F7B592F83D5299 +:10DC80000F462A43BFFCC1FD4C0E2FD9FE2883DB73 +:10DC90007B836DBF94B1331B7B46C18712B1AFD775 +:10DCA0001CD7D7A2E8AFE5B2AAAAC9389E1BC763A2 +:10DCB00074B6317A7B12183F9C40DA66F850BA2B62 +:10DCC000D258875288DD2F209059DD1735529B8816 +:10DCD0000E52B42F267C1E5DB6E15F8DF86D75681F +:10DCE0004C4A56F87D2D6E82C38DF3317A57343607 +:10DCF0002043851A84B42F8C2D38FC4806272762D0 +:10DD0000FDDB363AE8D22B21D33E98F48A68E5F45D +:10DD1000FAEDD3932FCEF996D8E13DED7E41557FB4 +:10DD2000DDA28746EEA7C2EBE6FE30245E8503CC7B +:10DD300018DAA70D2ED8279DCDF475D1A590604F88 +:10DD400037E0AB3944A764CF6C28AAD490AE609773 +:10DD5000A4229CA61E85680EB5AB90741A47F636B1 +:10DD600003B653820695E6FB91E112F49734F697D9 +:10DD7000B271BF22F6F72B42AF4195EBB57E136E21 +:10DD8000D2B3EA509DADE39D9BD8FF189D242BA4F0 +:10DD9000D4FDD2F0F7F5A817995CAAC7E716B9B277 +:10DDA0007D900FA2B45FF5E2DDC1C75E9A3C9DD1C4 +:10DDB000475F4C01145BEB1EF318B56CFCE7CF9189 +:10DDC000521E49C0CBE05C24E07CD6C81D8774DAC3 +:10DDD00057EB213A5E74C19F2248C6C7F7FD5ACD62 +:10DDE000442F8BE6B986E060FFADB6AE8FFDF7C37A +:10DDF000C17D29A2794CB856562A0447DF3C2985B3 +:10DE0000F31CFADD7FDDFA2506E7B35552CCA313E8 +:10DE1000BC2160F3F519EF4746F53BCCF975D010FE +:10DE20009FCEF9CDFD081702E115FE9DE195CD9736 +:10DE3000AC19E85F8F783E26C5D6B3F9B2E6B74C89 +:10DE4000C0798A6599E0DD38CF2B2B8C7EE0E531F7 +:10DE500032E23328F83CCBDDED9DC8E0EC9C24C3D6 +:10DE6000BDECD1C6D2D1E559BB439EA95ADC90582E +:10DE70007F3DA9552AA3F045CA90EB32C9BB672460 +:10DE8000AE273B928BB5525CDE21BB1D887A296E92 +:10DE9000D1ABCC5E7C4662EB7745381D67D7C6B9FF +:10DEA0009DD83786E45740EC47D6B4C55990C10E8B +:10DEB0001E711D6CA24C7673B6CCE183A37C7CD51D +:10DEC0001C3F67F4F13788F13F6C92A00FE153E3F8 +:10DED0005EDC7F302A889EFD823E616D0ED54DB995 +:10DEE000EB298B7715B37DF44465D0755C5F92F6B2 +:10DEF0007933DBE322068ABF96BD674D377FAA9050 +:10DF00005D922D9F4826191C9BF75F0B3AB353FD7A +:10DF1000D114507DEAD55EC4CF66A614F8FCBD804E +:10DF2000F30718D9A27C0D30F9AAA37CD57BD33294 +:10DF3000ABAB751033D8AB901693FC8C640E444B8E +:10DF4000DA54F6BC7D2910FD025A1116FCB6475F63 +:10DF5000301406576723905DD319A9A1F5B597D75B +:10DF6000788BD1DEA957E9397CC2F061DA214C1EE9 +:10DF7000FACBC0C0F936E7432A88BC549B47F4E883 +:10DF8000D6F8FAF5EDA5909ECEDE67CFDC8FF327AD +:10DF90006F81D8243E25C935D5A40B359194D0BFC7 +:10DFA0006BD1629B32D0DD764864C9336C744A7A97 +:10DFB000D789B72C375C88F8EDAC60F45F3C7C9C6B +:10DFC00022E41F466FA9D8E28B4A32CC532CEB4493 +:10DFD0001F665DFFD04DF08FD47EA81DB3337371E3 +:10DFE000684342BC406D84D69703837F0CACE78ABC +:10DFF000F58E81666A179DDDBD1FF9ACC0E8AD46A0 +:10E000005C7C3774E9F3B46F70B786F108066DE98C +:10E01000C9DC21396104B99C782F26937C0CC9692D +:10E02000CD6003847C7D5152D63A901F91855D1856 +:10E03000C09B5ABBA7A27F19869884EF43313569EC +:10E04000953F59C0EA36FB0F8E94CE24D2E27C0174 +:10E05000DA7E6419ADACF90C1CEF0E06908FF9C98D +:10E060005B4209D2177FF285A7E1647F92E3596989 +:10E07000DEBF0CEDEE1B157F6C13D2438CEB072F2C +:10E08000FB07E55FD66CD5268FB30D7B3DD7A13757 +:10E090001628415A6FF65740E803A37ED29821F81C +:10E0A00018640D4837DB6A55C0F982410E9709673D +:10E0B000AEF2495A0682E318C2C1D0437084CB80C5 +:10E0C000FC3D06CF31073CC71CF01CB3C2D3E2E5D0 +:10E0D000EB75FAFDCB65E1F733BF17F5E00978DBA7 +:10E0E000A8438231C6915E096BBC6DD0DB47469573 +:10E0F000061AEDBFD3EF67FBF39E4D3FCC16759D1F +:10E10000D9F525049FFD3D14119D505D8141FF759A +:10E11000F96C133FFA575F617C77ED6117205F312F +:10E12000FE55F0BD4BBCBD56F8B1CB51FF33BD7DA4 +:10E1300015C4C308DF3B2093BDFC0EBC109E6E913E +:10E140008B77C86EA1C7D9865AF9176251F4ABD53F +:10E1500060679F1226349874269DA47D8B01F9DD9B +:10E16000414E6F49F0B6917DD1C5F5A3E9F77DBD6C +:10E17000DBAEAFAFD96EAF5F0D8BC7207D5D7DA7E6 +:10E180000B526CDC6BADF607DB9F6FC91AC1770DC4 +:10E1900034776A41B2B31A711DCB3550D14F5BF958 +:10E1A000B37B662E63EBD921F4E85B4CAEEB16BD76 +:10E1B000715D24E536CA87AF6FBD145BF42569E451 +:10E1C000F56D70F52D42FB20B9D5457E1D38FDB5A6 +:10E1D000BD0AF96B967E04EF955DF6F59D6AFDCE5E +:10E1E000F5328F85D67BDDAE65A437475A8F7B9796 +:10E1F00064A432E8B7874D7D28E48B49DF265F278A +:10E200006B80DB7BBFF7A5D6B3F97E83F291F6BFB7 +:10E21000F96C1E47699E85E5A9FAFDDBE7ECF7EF8F +:10E220009FB3DF6B428E3BFBADF4F6BB713F57AB48 +:10E23000C93A491EB2A3BDAE66A390A1C2B5AF3A1A +:10E240008DA698A55DD769B63B2C959C56BB3A79AF +:10E2500094F18E0B3BE3A93DF7B9FB91FF76BFBA72 +:10E2600008F5FB37FE49012F5BD7F13D2148237D9F +:10E27000AA2937DA2BD731BA4A513D3DF3628B5D7B +:10E28000C52896C6FFC64321B20FAE7BC493AA67CA +:10E29000FDAFFBE97F4C038687E3EB06FEA510E9A3 +:10E2A00075B7C4FDBF64FFB48BD9F3EB54B8229E9D +:10E2B000814E6485F3CBDB3F0F34A2DD27EDDA7F9F +:10E2C000398DDBFB5517CA65B3DD47B28BE665EDCB +:10E2D0000C7C9F7C504A4D92387C0D5387FBDD6F40 +:10E2E0003F2871F8F6B9523E846F578F3BC1DAADC3 +:10E2F000DEF52ED1ED790FFD388C7858BD4FB1F990 +:10E30000BBAB772969CF342A5FC51235A3C4F86D3A +:10E3100095E0D7557B57921E58D5BBF95DE4D7D50C +:10E32000FB5C36B9CEF0124B235E5F5262F5587F2C +:10E33000F487619DA1EAADE8EEB0564EE32E73334B +:10E34000BABA68B6BD1F8EFF61CEF0F1000628AEE6 +:10E35000B9BA77239F0FB8BE31F9F42DFC4BFE708C +:10E36000BD3145B19F3B9C806767521C72576E461A +:10E370003FCED41726BF7EE3C7277626D9BC6F3F92 +:10E38000F2879D4906FF8AFF797FE7B7D9BAE0494E +:10E390009F867268F5EEDF84C182F75A85FB61C7FC +:10E3A0001FFCE1033B18BF1CFFAD87ECBAE34FFC39 +:10E3B000D7789DADFBF8C31F8D41BB73ED13E78F7D +:10E3C00045FA5AFBD879636114FF01E935E5B1EEEE +:10E3D0006B8AF655DF27611006E071513AF6E7E0E7 +:10E3E0005E258DA1DB775EF6A43C0C3FABD9B396DE +:10E3F0004ADCAF95A487B07E33C3F3AA3D1BDE553C +:10E40000A665C277B2508E62C9D8268AFB7DF145D7 +:10E41000E75461E98AE9481F3040F2DFD96FF5110E +:10E42000B6AF678FBC8F27E01337E27FF59E8D7CF8 +:10E430005EC73EBE837F999341FF0FDBC715DFDFC9 +:10E44000812FF7E6D2BE8FB48F2B1FBB6454FFCC55 +:10E450009407A7C26F93C4E13A5B31D628C8578F9F +:10E46000FCE8811D11BEBFF50C21C77F7C623C0614 +:10E4700097DF700D5C8E7272E0098F762FEB73DD83 +:10E48000132F119F1D7FEC79B74E72128212D37B2E +:10E49000C761F04F1FEAC15512AFACFE4128ED092C +:10E4A0000FEDD3AA54439D1EA6E7AFD2F314A7FFE6 +:10E4B00055A9FD4BA40CFBB65B29E1723995477851 +:10E4C00059A9F7B9B5A07D3FA5D9B88FAF2E40BAED +:10E4D0001B691FCDF56BB8FE5996FDFC01E7DB917A +:10E4E000F8F3788F4795B286F6F7B8B00F56A7A421 +:10E4F000972003DF02ACE3F08E70FE68964E7AF848 +:10E5000081831ECCFEE6BA4FC5D7A75ECF67C3D7BF +:10E510009D8A6EA31B136F6F7F9259DEA7859C584F +:10E5200005C9BA8289C3F5950AF16461F110BC9DF1 +:10E53000BD0AC9F1B7772964A73BE5C2AA11FCF16E +:10E540005F29DCFE58B56FFF34945F6F1FF8B9A0E8 +:10E55000434EE7ABF6BCEA4E0AF99FB2CA7F1C2FC6 +:10E56000C37EBC2CE05EFD78E6F156EF7937E378A8 +:10E570006FA9C65711FEB7FA5C906443BCD5AB6473 +:10E580008C6F1C505CB6386E6768E6CB5918DF0C90 +:10E59000FB755CF7FA75C64B49B4435E7001D981CF +:10E5A0006AEC0D0F7BBF3EE4A773EFF5E1AB41B71B +:10E5B000E8E976079ED4689CFC603512AFE2B1D7DB +:10E5C00094CD1F7569B20D6E509345184FF955F1F2 +:10E5D0007FA938EE7368FF9D31D4FE39153A72D9A0 +:10E5E00078CF1952AC0D32C4A71CE3C7E729A05B52 +:10E5F000E9CC2893ADF1D5F0819B282ED102CD69CD +:10E600008C134111F4DE6F19F7EE560DD26C7EA813 +:10E610002B93ADF1554F73B3E1617014ADD54AD072 +:10E62000341B69FE71CDB23DAE2DE65F23E209B029 +:10E630006BF7EEDD6CDC3A7C57827E0C8F573177BE +:10E640008AEC98F3841CFC6761071F90E287D0CFA7 +:10E6500032F46D2ACA39A9749B8AF6C4C24FBAD55E +:10E66000E5167A5C58DA5684F472F853A531135DD6 +:10E670002D51395DB5156F28C2FE877D371671277C +:10E68000344AEB2C10EB3C34EE9A603F1B777FF161 +:10E69000355B2633B8EAA20A60BCA52EB26C4B05E6 +:10E6A0005B7FC11125E663F582A6A49A983A7C9E09 +:10E6B0009D28EF19FEEE453C32F87FD01AA5FA03EB +:10E6C000AD3A95BB5ACBA8DCDD1AA3F77B5A67534A +:10E6D000BDB7B58ECA475AE3F43CFC2D7F02E977FB +:10E6E0006F6B233DFF696B82CA1A95F3DB42810F82 +:10E6F000CBBAE91C6C497B781DC6514CFC39F15DE5 +:10E70000CB282E87CE0D241DF13D56E572C589D745 +:10E71000969620D9A53B25B0E173A6CAEDC8B8806E +:10E72000E3903771A1CACAF7EA4ACBC9EE81780CE7 +:10E73000E5F44E297E5B05E397A7C6CD8A5AE56EC0 +:10E74000249888AB7943F5F15D3C3E334BE5F2A963 +:10E750000EDA0E6531F88C4F40473A33D779A05A1C +:10E760002F42B978A08DC1538EEF6528B3D0993967 +:10E77000DE5C011F0433CBE921BAE5FC1F9D5BB6CB +:10E780000DE3C4CCF18C4DD2C9EAB6F5DBA69A7183 +:10E790006F9DE8D8A413C63F4F8D8BD030DC5F6CE3 +:10E7A0002AE6EF7D9CCE5BFADFA5F856740CD8E222 +:10E7B0008D1D4D32F9393B8EF2B8F489A6926D93D6 +:10E7C00059FB6A8637F4DB73169666252C74BD45B3 +:10E7D000D0D30E6F3C4B1B457F758A7666FD155F67 +:10E7E000E23B88E7BF9FF0937CA4E71DAED4652889 +:10E7F0001F5B8E7AF475129E37C493B86FF122F6C0 +:10E800009C8174A26EAD879616E4E70F2D37EBDB83 +:10E81000CEB0F0792866E7EB9D2DA3C7A54DB8775C +:10E8200022DCA3C4654DB8CDFD3851B764E01A1899 +:10E830008E07E7B8390B978C3AFFDDC8771EC2C345 +:10E840004ED5229F8A9A353A6730FB9BEB75F67757 +:10E85000AE77285FE1F4CE677A5D908BFBF9F0C765 +:10E86000E31F7D0E70CBE30ACAB12BD4442FEECB4D +:10E870004C68A63AA803F9C82FBFF373FADFD1F9A1 +:10E88000403EF1919A2A46BD70BAF375403C5E8DC8 +:10E890007A2B26C7ACF2DC2C7FA19A718234C58F0B +:10E8A000E888994D29076E8E66C2F3E0F845EADBE9 +:10E8B000D6F3A42D00DC4F4F7BE99C0303221AAB57 +:10E8C000171F86CA4D6CBCDD429E54ABDC2F9C7E6C +:10E8D00058EF5178FC48690859F028E2A9661CAB4A +:10E8E000036E068D7575AB15FBB1B9C9870DEEC406 +:10E8F0008B882F7754A7F3775724417C0522FE3D60 +:10E900004EC4E9CF1771C6FB5B789CB105E2179E38 +:10E91000817C7D4401F28F13136DFCEB5CE77E413B +:10E9200057FF24F4DFCF85DC2E55F74B596CFCD014 +:10E930001BE9036156FE4CC8F1C7841C3FB0ED5F74 +:10E940008A319FA023E18E214EC355FEB4C4ECD082 +:10E950005B67BEA15FCBDA77744F6E47FC6C58CB18 +:10E96000E3F28FA2DC67FD1E16723FDCDC793D9D71 +:10E97000DB09F95264E60B08795224E4C9C16D2F12 +:10E980002EDB80EB4B78699E16483F8D717D582BAE +:10E99000939D12EEFDDE0D38CE43AD061FB77BF71B +:10E9A000DFA17D7F8F375DF9AF18FF9FE78E25517F +:10E9B0004EA526D9E454B877DF8DD82EDCFBCC4D9C +:10E9C000940F23F0E0799CAD9735C9BAFD703AC435 +:10E9D000DA15F6A7D1EC66FBDAB3700A1BAFB45EAA +:10E9E000A670F51E297E5E08E9A1819F4367552C1C +:10E9F00069C3F6DD2B5E4862FF31CF364BB8ED3987 +:10EA00007F776F35E2EFFEA2D79EAE66E5645731A1 +:10EA1000D141F0A89EFF43C0F1E3D16BF591E9F03D +:10EA2000E08A358072CC73A74CE7F4F7DFB906AE05 +:10EA3000B1E65DAC5033C6C726BB3CFC3CEBCEC553 +:10EA40007D2867CDF3ABC295B55EE2FF67C1763E28 +:10EA50006B9E6399FD2BA4C464571E9D57F0732DC4 +:10EA6000D1BF40411B8F556F90391FC4D33E6BBE41 +:10EA700049F07A399E099E592E95E0698FD5EEFAB4 +:10EA800017369F3AEB52D2CBD06D87C3D98FC131A5 +:10EA90008BC3C1E133E118C74C82209BFFF6852F61 +:10EAA000E6237C1FD60DEA1B3FFAFF1DDF95D3132B +:10EAB000D8FE6C6D97E9FCFE40D5012FE2714B55F5 +:10EAC0008D9FDB3F9CEE72041FFDA04E26BE3D5184 +:10EAD000C5CFFBE19393741EE612EF73F20E78E953 +:10EAE0000C236904AB6762FA81F9C7925FC0705367 +:10EAF00099F4DBE4A7DC9263CB371807058EBC954D +:10EB000092A1F6E87FD71D91502F85C47974A97919 +:10EB1000BEAD1C8DE1FAEF32F562AB97CA9EE603FB +:10EB20003E9DC1F58B664627B42E7B5E8AA7096899 +:10EB30005D05CDFC9C6D8BD6B7DFCDEA45DF65A8C2 +:10EB4000D7D19EEB25F902DD3C5FC03CEF98B4C203 +:10EB50009EB752E4C8B719969FF519FDCCEB5DF648 +:10EB60007CC313B0650AD1435F896D5F7AE630B725 +:10EB7000E6ECE1FEE6E0B8C29F82289773393E3E9C +:10EB8000C7ADDF529AD05E0A5F58996D3D1FED7494 +:10EB9000713BE9D0EF3C80F1F80DB55E8AE398E770 +:10EBA000E8E67E6FC5A42BCC77687FC087F4B223DC +:10EBB0005242E5C1B9CFF8FA890E793E8047AC6977 +:10EBC000DDDC67163631BCDE9327938EE9287A2187 +:10EBD0001FCF176FAFF5D2797F38D0DF7B90D58309 +:10EBE0007FEF8EE1F9F6FDD5E946ABFFFA908BDBBE +:10EBF0005BDB5D425F6DB19F3F333ED88E7CE009A9 +:10EC0000C6E9FC52F68ABC09879F63E2237C205F39 +:10EC10002E9ECACB92A943F6F9DD826E760879BFA3 +:10EC200045C87BE738C54DDA0137DAFD2BB44A25F4 +:10EC3000035F4E68B1DB09E39AED7935854D76BA0D +:10EC40000FC50A1C76459AF498A98F37F88213915C +:10EC5000EE2B99BEE4F681265BCFDB9DFA78B76A8E +:10EC6000EC7391BD7B7A764238106F467C3BEDDCCD +:10EC70004302DF1F2BC601C46F408D1F72511E68F7 +:10EC80009CE48CD36E1806273038A78E0AE72F5DD8 +:10EC90009FC17E3AD5F9C09FE4F8F6E718C8F3B3F0 +:10ECA00040E45D84480E7784B8BFD2E1E27EC27B47 +:10ECB000625DFFE15268DC01415FF303D09C399F44 +:10ECC0008CC78B3E40C304DB8DCD9CBF8B160BBD28 +:10ECD0002FCCFCFE03173F679B3F61F479FE88F35E +:10ECE000B0F257AAF1AECB728EF384CB78DF658990 +:10ECF000537CE8D2383F98FB21F2734DFB699F6A41 +:10ED00007C64ED6F96390B553ACF3D01FE98C2F009 +:10ED1000F3643EEC0526479E94043E7FE7A33C2027 +:10ED200013DF83F635CA0FD4034703298CA798FB5A +:10ED3000609EC30CCA11D1FE4C3797278C6E026EB1 +:10ED40009A3FCECF0B214DF2A140D0CD0EDFD2DBCA +:10ED50006A5979EBDCB75EC67C85771EF3E908D784 +:10ED6000D6AA6361ABDC84263BFD98CF5D1F16D22B +:10ED700039FD37A544BEDBE247BA22036EECFFA49F +:10ED8000A4933F97FC8D42F6C893526A0A192A2A27 +:10ED9000D079C693D746539B2CE71D4E3B3FC7D730 +:10EDA0007FD76A5C7713B39760F8BE9976FAA0DDD7 +:10EDB00011B5F78FBB41D8D96CB98CAF2BC4BA63EE +:10EDC000AAA1201C332041E52CD0A964FE40A59BBC +:10EDD000B59F0E03F9C847EB02E3BFC4ED8CFF33C8 +:10EDE000BC197F8D781BA25BBBDE36CF1DF2041EE3 +:10EDF00042D04CE7EFBF685CBE71129BCF5D14241C +:10EE00007B38AFB1FD7A398CD97E7D1AFA9B79E2D5 +:10EE10003C1C9670FD6C9E4FE7D4DBF5B9537F7BAD +:10EE200084BDE11941AF3BE5E6487A7D85DBAED78D +:10EE300007E3C723C83F67FCF8D4F24FBFADB6184D +:10EE4000F3348C976AD1AE9BA752BC333C11AE8889 +:10EE50005BE8E1F76E223A56F2BC994D8C5F53673E +:10EE6000703E07F413024C01E179C2383985F93656 +:10EE70001B92A93ACC3FDBA04ED2ACFB583D8EDBB7 +:10EE8000B35B6BFC4D56BBF60F7E178DFFCD40F587 +:10EE90003348C7E5C1540DB97B067304C7F0BC4BBA +:10EEA000DCB7B334E8C773580F70BDCD38C2CBF5AB +:10EEB0004AADF63AE56726E0646034BD60CFC7DC52 +:10EEC000ADA6D6F9111F111E7F096D97283947E9A4 +:10EED00035D298CB5515587CB79BEBAF329C67FF6A +:10EEE0004C66EEB2F67FDCEF263BA73754A8A23D76 +:10EEF000F9A4BCFCFB68070EFCD603789ED2FBE9A4 +:10EF00009974AFA137F4A5054807BD1230CF96AD6F +:10EF10009FF10F4FFE8100C6EDC3E7198071CB81D1 +:10EF20005F40EC5E36BF2BFA689CF276C108C8B32E +:10EF3000593F1F7461FE4AECCFFEF7CF6574F74866 +:10EF4000B0F28EB361280E60FAFFB5FEC4A3086765 +:10EF5000C7987F6B423EEB62702A6487195184BB6D +:10EF6000324F26FE83BC606A127B5E7D38528BF97D +:10EF700068D56A054A1A0607DFEF577C892710FF14 +:10EF8000B55A436D366B5F7544277B6541F4FA4390 +:10EF9000589F7994D73BDC40F620F22F58F8AFFA0F +:10EFA000C3F1B4BEC3428EB7478D3E431A653F34AA +:10EFB000D5719FC39EC762A5036DA68D0E122E2B21 +:10EFC0001DCC667430D54A0786F459E8E07B42DEF2 +:10EFD0009E9A5F389FDCA870BE194EF7CDDE9CF27A +:10EFE000E1FC61CEBBA92A2782E7AB261F68B36E7E +:10EFF000D6B0EE59E68E23DF997C61F283E21BE402 +:10F000008B8B7C6C7F9704F5F333F105FA7156FA1C +:10F01000BF78043E5904038730E77E910AC92C2645 +:10F02000427E35E78DD2F116BA77E269D13C098E7E +:10F0300059E4D1C993BC6EC1A3369807AD9C3EBEBE +:10F040005F50F58E8885EF3A99FD8C4661971C8359 +:10F05000BC62E4BBE541CF0CBCDFF07094E2FB9EE8 +:10F060007813E5ADCD7A3B7035A3C33F8E91755CC7 +:10F070007C87BEFC21E2DF97038076DBD699D74DF3 +:10F0800040FFE48FD72626609C7323C3FF31326E86 +:10F09000526365CA85EA1FCBCFCBF4282F1351FEEC +:10F0A0001CC4FB94A81BA25D3FB563FB6C9387DB7C +:10F0B000BD5C0E6EF7723B70A3BBDB8BFC3550EC76 +:10F0C000A5F354E7FACFF5707E38D70355B108CDD4 +:10F0D00046F1960EAF52D7C3E350E973D9F37327C5 +:10F0E00096DD6BD58F66BF3B5A53F1D726E17A7612 +:10F0F00051995B9F023C37F09725758CDB7BD7419C +:10F1000022937DB8C3CBE304DE03FF40E74DB9A5EE +:10F1100031F24F23F56C3CCBBE2E6228CC62728656 +:10F120002DCB407AEFD0FD64AF2D8AD4BCA94E1B05 +:10F130004E07F8E798653FBDFFA3247AB91F477EC5 +:10F14000C85AE1F7D59678897F3A5ADC3D184FBB0B +:10F15000CC934DF8FA2052336A9E2DFA5749460F48 +:10F1600029E65F6189E720C933F83908D6F11C0424 +:10F170004B3C07C112CF41F03D9E8360FD27AD0699 +:10F18000D5F13C04EB781E82753C07C13A9E836042 +:10F19000B9AFB589CA7F6C6DA6F78FB7B6509DED34 +:10F1A00013D9E350968C2E6678EEBAC96DE0F976E5 +:10F1B000B7D88F8346492EEEA32FC2FD53DFB3B7D6 +:10F1C00003AEC717E571A5CEE8ED70252BBB6684AD +:10F1D000BA30E0E57D2848A54FBD0330BEB0534AA4 +:10F1E000366124EFC60DFBCE53991E2F8D5E5F93C3 +:10F1F000C3EAB76C78723DE6F74CD6DB62CBB5A1BB +:10F20000BA1EAABCEE614B7D42798FEA67EDD779D1 +:10F21000F6AF477E4638D0C8DBB2E1E0796DA58C09 +:10F22000984A80EE790C14BB53488F57E17E4D42CB +:10F23000F8B9FDFF65581F457F7A82EEAE443E6205 +:10F24000EDD39C7E4FAF7D371E66CD18DE6FB47652 +:10F2500072D569B5036594F1F0BD34CA381DB05E4E +:10F26000C33B679B91E731EFC817207FAECBC5F951 +:10F27000B7CBC7CBFF167C7BC85B13F7B232EEE58A +:10F28000FBDAE58BD7613C7460AA4C71855E171B75 +:10F290000293775B8A7F5DC2E6FDE6332A607CFAE3 +:10F2A000871ECEFF932684B85EFDB697F4EA051359 +:10F2B0007EDC9EC3EA93EE8BC5504F6E86981FE9A5 +:10F2C00024B985F3FB8FAA26E634B0E667CD782C07 +:10F2D00007E30DAA802385F79258BDADE3EA09182C +:10F2E0000FF9E3F35C7EFD54CCD3E3EA6BA6FD9CFF +:10F2F0001124FB82618CEC87B6A84AE7F7723E2F97 +:10F30000DD2EED6FB09D9B29E82483C7FDE92C2FEE +:10F31000F9E91F7AC47DB63EB22BDCBE8496CD9E41 +:10F32000772765E2F7F59A3F8529FB9B839574BFA4 +:10F330003659AE527EF6E6721EC70B842E4DA13DA5 +:10F3400071DB7E1F970F412FE569A5CAF71EAE89B5 +:10F3500060296BC8EF2963711DE15D9335CAF762BF +:10F360007FA3F74D11CAE7DE0C625F9A64F2173B88 +:10F37000C6FCF95FCFC673F1AF6B3171C788F22558 +:10F38000C90492F1BEEFC08100C2F3B7E6FDA4FE4E +:10F390007501D6BE7DB916C37D98A6D5D4611CB1C2 +:10F3A00043ABF1225F05A6D67A97911C1ACC67A6CB +:10F3B0007B70EDE5DCAEC5F7C897D00E87F0DE4B6D +:10F3C000A1906581EC4A09EDA18E7A0A2F61BEAF4A +:10F3D0002D3FB33DE742CA7F5716E5109C1D60786C +:10F3E000B17DB25E25FD5518F4A6D1DE2B34E38B3A +:10F3F000989A6CF1377257D8F39BF39B54DBFD8FCF +:10F40000B1097B3D4FF80F798E3C68C96B9E23DABA +:10F41000F1E45C6F6EE4DE6C8437172F34EBC3D7F6 +:10F420007347A4B201D759A8F909EEA8B6AE1AE5F8 +:10F43000D758686E43BAFBCCF03AE09C56DEDE87C4 +:10F44000FB3E4D57E9BEC3D930B00EC7DD2CE8BC3A +:10F45000ABD8AE4F7FE851C43970CD1CE4478C87E0 +:10F46000252DF31727FD90B4CC37B12BC7569FD469 +:10F470005D606B7FC6F612DBFB29A9336DEFCFDA37 +:10F480005569AB4FED9D6B6B7FF6BE1A5BBD227D60 +:10F49000A1ADFDF4C38B6DF5197D7F636B3FEBE58B +:10F4A000E5B6F773FAAFB3BDFFD21B6B6CF573060D +:10F4B000BE656B6FDAD74EBD38DDFBF9EC6A0FDE47 +:10F4C00007B3C50FED76BBD3EEF6FECF7A7D1DCA2E +:10F4D000B5B09BE85B453DCEEA6B6EE27E8F777EF2 +:10F4E0004C47B93245D063246818B86FD5612FE90D +:10F4F0000335C8DBA9C10564778CDFCEE4D174B4D1 +:10F500001661F07D00E5726B325EEA1A82DBA77548 +:10F51000D3DD86EA701DC5DFCDFEAA66402284F3E6 +:10F52000E93CFF887995D8CEA7B3FE96753C29CBE8 +:10F5300074157C80F967F75AFCB391FC31A7FF750D +:10F54000BAFED67819FC58F648F1662CCB9B9FAFD3 +:10F55000C1343CE6875DE565FBB3D51D6FEA61E329 +:10F560006E2DF1F3F332E1877515F7125F0C14ABD2 +:10F57000A45F40D5CB175BE260B709BB32E0BD8B1F +:10F58000FC40B564F6611DF1DEA6527C62B3C4E3B3 +:10F590002849B60FA8D776CE7DE3DD5BD8736F8997 +:10F5A000B7D0CBE451ECA0DBC073D23B045E4BB4CC +:10F5B0008A1A667131FBA2E1009693756667B0B254 +:10F5C000AC6CDB012CDBBC2534DF99B1876B50962A +:10F5D00078E773FB4F99E64EADC3FDD3381C23D1BA +:10F5E000999AB39D9F6795AAAF23BDA1557E521EE0 +:10F5F000A2031FD2814425D18F2F1224BDE1C30362 +:10F600001FACAB522AC0DE474A0D09F333AAC3DB55 +:10F61000E97CCE97B6DBABCC2FBD0DF11AA9B7EFC5 +:10F6200077C0BB93E06B97789CB62B5B7FB686C1A7 +:10F63000DF9557928331168C633458E4CD76A14F11 +:10F64000AFF0C9A6FE2779E343DEC81BB27718FDE9 +:10F650006F9727227CDD8072CB77733720BDFB3418 +:10F66000B69B686F7F2749F46FDABB3708DEAA2D97 +:10F6700069A473B1F7239564DFFA5A7E92117FBEB5 +:10F680007E058CE923E3353C7907E97B2871EB683B +:10F6900057B4E86EA327D339A047F81F981F82F00C +:10F6A00088FC902E810FF35CEE7D336F4A9C07DF60 +:10F6B000900DB6F3C11BF22AC78E668FFB987F9818 +:10F6C000B0C0BB91CD8378E9F8A4A12E4EE784C0E9 +:10F6D000EFB37D5ADE43F7863F59AFE339E62C811D +:10F6E000EF733D1CBFE3DD407EC27918E7988E5E64 +:10F6F000E997EB902FCDB8C89BDE1CC27F2C094A3E +:10F7000033D92B2E536FC927CF269875B719CF241D +:10F710009397EB35F6EF7EBC7F31B1CB7EAF69526C +:10F72000B7BD7EC6767B7D4ACA5E6756F311B40BC1 +:10F730001A80E3E7AC5DF6F70D663CB096DFC7F0E4 +:10F74000B2994F72FD6BBBFF0A42FF9B71D771BD2F +:10F75000E96A14AF456BED7AB540E8F90287FEAC73 +:10F760000C29140FA83E1C3984F6A319A779C5A744 +:10F77000DBE29F66BCC529CFFD47B7017B437E75A1 +:10F78000C2C3E31009E6DFB41489F8C6385EBA14C0 +:10F79000FDB9A564A7359F81F2E99037F1B197E2F1 +:10F7A000CEF6FB12EFD5A9BF90743E4FC232CF8D7B +:10F7B00065C90BF8F253947F62C63B4C7F5E091A11 +:10F7C000711C6F73EC85E683186FFAAD07709CF3BC +:10F7D00095670FB7B2FA9A712AE54B6AB3567CDF88 +:10F7E0008FF1427CCFEAD5C5FA58A2FFA75DE4D7D6 +:10F7F0006F10F46CDEE331E323519FD03F3ED32EF4 +:10F800004AFA453EAC1FEDDCB37631D96CD3733C7C +:10F81000EE66C6D7A6F6DADFF78294ABB1FD3BBB46 +:10F82000312573BBCA08565BE2EF678AFD9AB6348E +:10F830007DFB5256DF03A94AFCAE4485A08BD8213C +:10F84000FBBDB13120D1FD82314794588AB59FF676 +:10F85000B8FD7DB9E35ED999CE7B668E787048811C +:10F860007797B1F9B6E8CD12CACF2D4B99CCC2F932 +:10F870007D22CF78324C46FA3B5F09C6D288DFDF63 +:10F8800028A4373CAF9EF1D232D4E7CFF33C166DBB +:10F89000A2BEAD96D5B57F55483F6901A8A8080E10 +:10F8A000C58FBF773206EDAEA178D46EB6AFA59303 +:10F8B000D0BFF602EA959FB0FDC57A2FF3C7B1FE1F +:10F8C00008F3C7B1DCCBFC717CFE53E68F637D1F70 +:10F8D000F3C7B1FC47E68FE3F3C7993F8EF56F0698 +:10F8E000AA1738E359D6F8DE503CAB5F32E359280B +:10F8F0004A3E70EBB4EF8371AD048F6B9D7A1CC3ED +:10F900001C87E286C3C611F1C3776EFAB707F09E73 +:10F91000F5CA19EBBAF0BEACD765C6CF789E84990C +:10F92000FF6CF2DFCABDD7D3B9B13BFF4833EEC796 +:10F93000DEAA207D8BC8ED4A68281F9DFE97E977D7 +:10F9400039ED5FB374EA233FDA01D3D14EEAA6B8AA +:10F95000CF261794D1FD59C91F43BE70C62B4D3E0B +:10F960007ED15792F1BED4601EAD88CF7820E5C518 +:10F97000B89A5B12EB14799E24C2D8109B919F2DEC +:10F9800079C9C1F234C539824183EC2F89D96564C4 +:10F99000A7698928C6A13A47C89BBD4FF0675BBEDF +:10F9A0009BBE37D199CFF3046A8B6251ECBF3E7F87 +:10F9B00066D49A476BE6F91E0ACDF4F65BC65B1374 +:10F9C0002A19554F294CAFEAA3E855C5C3F3DCD734 +:10F9D0001F98E3C5FCE54DC1E57D685F6D8A46E88B +:10F9E0009EFBFEFC99647F0CB68FCEA63C6725C8B3 +:10F9F000ED5625EA25BB55C5F5970FB537DBB5FAAA +:10FA0000385D31F6A3F85C20D84BED3C6A9CE21FD0 +:10FA10009E08D0B996C7CBF30A82CCBFF6DAE2AB28 +:10FA20007CDE1611F7DDA427E2D86F5354D5511CA4 +:10FA30006D2AAB243CAF17785E9F67EAFD18D91B8F +:10FA40003F137836C7592FFCF5F54D6EB2BBE22D4A +:10FA5000D9466D2EE56DEEF1E1F8C17BBD9807EF5B +:10FA6000CEAF1A75DC0338EE8CD1C67DB5A6763ADA +:10FA70008DFB331CD71D5AAEE1B8AE11F2F39F13C4 +:10FA8000707E5EFB92614EA3733130F56D2A6A3D44 +:10FA90004F76967EB413A70FEFB752EF5F80F9C190 +:10FAA0002A24EBFCCAF0FB0DABF6F1EF556D55FBCC +:10FAB000C8DED9FA8994F19EC418BF24CE6B07FD25 +:10FAC000709BBD5228F8A950BCD7D15E2946BFD241 +:10FAD0006E5F4C3F6CAFCFE8B3D767BDECB4578CCB +:10FAE000DFA0BDB244C8BB3E269F7972C5808A7232 +:10FAF000209E4C5523DC0DD0DB86E7992E85E7113F +:10FB00002C11FAEA22A1CF82FE6C82BFB0C96FF33A +:10FB100013CDEF6E1489F1C7D51EBABE1D856BDCFF +:10FB2000B47F74F22FC72D7CA49AC4A4C30E6A308C +:10FB3000ECF7562F72D8394E7BA85AEDA1BCCC02F7 +:10FB400047FCC13CCFC475E2FD5DE7FC9F755E7369 +:10FB5000BC1D4C6FA1BD627ECF80BEF7C5FA8F532E +:10FB6000D3522C48795E940F58B8168C9E0C747C36 +:10FB70008ED8F761784B9E4B783B4F3C2B08F2EFC9 +:10FB8000A514D42A29BD98E789A13C59BC82AD8728 +:10FB9000ECE593745E6DB6CFC9EEA5BCB21DF5124F +:10FBA000F71F93407688B9CF3B82FC9E4DC33952F4 +:10FBB0004AC6FECD25343FC15532B4BF0C4FC738BD +:10FBC0009E781EDAC575F6FB400D0E7BC3A4878BAD +:10FBD0001CCFFB7DDC2F32F9E09D392F4F1ECFE08B +:10FBE000582925EB02CAE9EB490B7FB84E221FE2E8 +:10FBF000DFC7D052883F0E781FD5288F20BBFF2E3D +:10FC00006024D9E08764ED3C807FF60F9C25B17AB3 +:10FC1000E3A6B33BBAC6E1B5C6811FA151E6D950F0 +:10FC2000757EDD394375FF2683EA11310F732D92FE +:10FC30007CBF2DDF3760F0EEC43C02B44B0DD8A67C +:10FC4000600EA6AC6D8B150FF5CBC17ED228FDE200 +:10FC5000B04DCDD02F68F663E8EA34BF0752822555 +:10FC60007F2F0B78ACF3AB88374D0FD27D9F05AA61 +:10FC700086E73F5F148E31A75A7702B6B9260EEF9A +:10FC8000C7C06E33E19733C39FC2F7D6F95DA3C0F7 +:10FC9000FF97C6C7A9C6738BF79F193ED67CDD9820 +:10FCA00091D78B70B9E8BB1A7A50B68C73DBFE8F94 +:10FCB000287EAD5E06749F4775195A8CD179B97646 +:10FCC00027F9E16A76AD8676C04656473B60636F9A +:10FCD00037C5A9CB4B6FEF42A22F4FFB01E5C154B3 +:10FCE000D0B2F7B071A76A2A66EC807ACE2119E308 +:10FCF000DEF015A0FB2459FBFDFCFB17C573EF4399 +:10FD0000FF283BDB4B71A040F6CCFBB8B1CBE3C185 +:10FD100026FC81EA23351827571B2086ACA84A29E0 +:10FD2000A846269B02740EE137F6DE88F73299E288 +:10FD300023FD44DF8440BD2AE2E26339C940975B7A +:10FD40006B403F21F98C4AF1F7B17864C188B2BCAD +:10FD50003C671BC2539E600348083F8F6B4D4DC8E4 +:10FD6000B1341BBFF25DDE0F7EC9EF11305FA2F12F +:10FD7000B1E0105E4DB93256C4CBA34BEDF164181F +:10FD8000606B66FD2B7FB9F87E8C278C1926BFB976 +:10FD90007F6D7E6F27EB5D883F46E79A76BDE11762 +:10FDA000DFB5F03BBE97303968BFBF37CC6FF84E38 +:10FDB0009CF48007625E37D9174BC96E30FD911DE8 +:10FDC000D810E3FFE3807FFFCAD97F26EF0F51EE03 +:10FDD0009F78FCCCCCAB64EFAFF31B9417E4617558 +:10FDE0008647C90DDE7CF6BC40E67191360954ACFD +:10FDF0000FCD97A6F3FC0D52AC2B260DF9BFEBB53A +:10FE000018E519C0DA1C9BBD6CE6ABAEB9B6786CD0 +:10FE10000E2BB386EE0D69488F6BF24AC97E0EE752 +:10FE2000F67F0DE5EB47FE5BCFF7A23CC53C87B9FB +:10FE30004C286FEEEA483279EBF9B010748B5DE62E +:10FE4000519B290EE6F970BCED79BAD57ECFD0086A +:10FE5000CAB5384F514027BC5683D68EFDAAC17E05 +:10FE60009FD0F361BECD4E1F1ABFC8F63CCDEC1932 +:10FE7000EB772C461E3F007A9975FC89238C3FD97D +:10FE800031BE9671FCA171736DE376A83C3E9A8CED +:10FE9000F869DF9DF64055A0A63890374AFC3EC071 +:10FEA000E3F71BA2CD14BFAF01C6F08C4ECEFDE42C +:10FEB00098C2EFBD01D96D50648FDFD708FA95194C +:10FEC0004520FD9EABDABF1F361F9CDF13B3DB431B +:10FED0002F21A3B079E550551FC5F13F0AEAE87F0D +:10FEE0008D642FF7B502C58FE707FA6FC073EAFA82 +:10FEF000C0F75D1DB3459E6C01C0DF04F69E8FF711 +:10FF000003FBC4BDBE8E884C7889D78CA57B3AE6AE +:10FF10003871374C42791897797E02FD61F3F7E525 +:10FF200015D8F21CCCD2790FB4C190E2A516BAE96B +:10FF300093195EADF39D57D8A358D611F7C00C9A0C +:10FF40004FD8B983F38DF97CF33D2FE24EE67C0D5B +:10FF50000BECEB6B706BB4BE06C1BFE67CCFE3FA73 +:10FF600032E0F794F3C99C6E06E7BBC0BEBE068FB5 +:10FF700046EB6B10DF031E9C6FCCE79B6F83AB39A6 +:10FF80008176DB3689F3FF77373FDE81FBFA7EFD32 +:10FF90009A28E90361175F841D58BB8B543EDFA28A +:10FFA000226FAACD32DF0E26070C910F6F78307FBB +:10FFB00043A37AAA354AE5BDCCCE36287FA38CDE92 +:10FFC0003FD01AA3FAAED6D9549AE394CDE6DFA770 +:10FFD00099324FCA686FFF32C0FDC66DF9DA6557B6 +:10FFE000A15EAAF6F37B93B3BF0486C5FE6506F156 +:10FFF000011F9EBF5C0A15A8DB266FE770476AC722 +:020000021000EC +:10000000A470FFFC1587FA5A59DDE372E9A84F196D +:100010002FC433F9A98703DC0FF7B8B9BC87B9FC43 +:100020007B878B845E01A55E72213E2ECAA6F3FEFD +:10003000C54B8C90C6F0B644927E532AF414DE6F02 +:10004000B9446C95D3CE8FA0C660E3460C2585DFFE +:1000500031BAA4E87023EAE578E862F20FE2AC6313 +:100060000E1BE712A127AB5FF500E63BC0F96E82DD +:1000700063C912BB3DBFCD97D6D03ED9561101DC26 +:100080009FC5F5F6F71E37E7C3B8E3FB068B4EF1C5 +:10009000BD03FAE656867C53677CF24040E4AB8AA7 +:1000A00038E40928BFAD165F164546FDDEC14D0197 +:1000B0002E9F4CFD369C8E393C7F10726C47EB3E78 +:1000C0008A8799F015A82909E57561D33E5B5E130F +:1000D000432C19C3661C1E943D15E88738D7B343DB +:1000E000DA933FDAF74D0A407DBDBF4C7CFF531ACF +:1000F000BEEE5703F6F8EB0998F75C2964E21F1E81 +:10010000775D745889B5E9437831F1F0FFCD475BED +:100110001166563E77DE0755DC7F2BB27D67D3FC38 +:100120007EF0C5837515540B3D5F749D9BEC1930B3 +:1001300006CA91EE8E9C13E0DF7B33ED97F46F657A +:10014000B45FBEF8F8C6385B7EA71877A4FD72E6E8 +:100150001B5AEE8B0EE5C3637E89C4CFB10A30CF44 +:100160002DCC9F1FB3DB99B63CB7F5FB1F9430CE67 +:100170007717E6E359CEAD0B993F8FF1AEA215F696 +:10018000BC3A275C665ED5E07DDB794BB43D3A7DB9 +:100190005FB11B3F58D3B53D19074B1EA5798FD0D2 +:1001A000F4A79DF7079520FFCE5E54DCCB70C68385 +:1001B0006F94935AB18479AB296F352BA7E72466E6 +:1001C000E195F61B95641D3E57C6CE6D423C2C6DE5 +:1001D000F9760CE3775A6EE6B8F452A1BF6B829CB5 +:1001E0006E8EBAD2E3308E7D4D4E4D4D302F43FB97 +:1001F00096EFD078F347F86EFDD7823C6E7297D0B9 +:10020000E7CEF74BC4FBAFAE94E93B183E08A5A47C +:10021000623C37EE9E4DF7F656ED8865BA1FF75CE7 +:100220003871B1151E5F29BFA70DD03B07F1B5F19D +:10023000E3BB7B1F62A8CCF93848723447E1E35A2C +:10024000FA7F2D386378FF273F7A91EE373F89F7A1 +:1002500059E6E2F6DDB300E3DF5BCD3A86E4B19E1A +:100260006DD6BFCDDF0FD6672CA866FDB7220D3245 +:1002700022FBFD960B3A51CF6E95407C87BC6E01F8 +:10028000FA875B5DBCFD3F89F7F32F7CFBBEDB503B +:10029000DECF74931FB855D823267CFD417E1FA95D +:1002A000FF14F8BC45EC5B10F119F94CF8BC2513B0 +:1002B0003EFB738CEF209E7C9849C140F07DEC5D45 +:1002C0008BF9C6FFD00AB1ABD81AEE8AED7DF036B5 +:1002D000A0FE1D99F019CF313AF17970E5315A5FDE +:1002E000A83488EE0D6C9C05344E06386E1D6D5F8B +:1002F0009FCAE272EC93102F7384FDA778FAA2785C +:10030000FEAF557DEF068DC991CEE2EEC64CF47D71 +:100310007788DBE5D923C4AB1F15F8FDBD16DF894F +:1003200070B76BB7D37758DD12B71B36CEEE07C95F +:10033000D2EF85106FCFE07E00E176CFE1DF470D91 +:1003400031BC638259A88AC3BF513F0298FF1D8AFE +:100350001EA1BCD050553FF13B5D6928E07485FE7D +:100360009A57D8678F6E59BA00E54C8E62D2E1F188 +:100370004EA41B65A84E74D493C3FBBFBCF578276D +:10038000FA733B99FD82DFEB4816F0BC11E7FA9E49 +:1003900014F0DE13367E8EEB1B864F4FFF7DB7B118 +:1003A000FE5B27F17B39F3E5BEC62B912E2F0C9215 +:1003B000FDC59E375ABF93F307416F7F0872FB69F3 +:1003C000EB475E7AEFDC8F91E8F5D702DF9F835E23 +:1003D0007F9D89DE18BD1E71D0EB0790995E5FC9C5 +:1003E00044678C5E8F66C28BB3AE80B11DCF67D57C +:1003F0003F2FD885E3A95F9EB7FD21562A7FBE39DE +:1004000049BB19936CF750CD792AA4C45B418B7C0E +:1004100037BFE34D391099C69D35733BCAB1D31828 +:10042000F704C2ED1CF7208E3B03E54B3091E9FB4E +:1004300046DF0FF1BCF107C5BA46E29BE74EC13774 +:100440003F0D713A607CE30A9D06DFBC2EDAB37D76 +:1004500008854E8B6FEEA4D257CAF986AE2BCF1DFE +:10046000CE3700AF74A23CEE2CE67C313EF44667FA +:10047000B2C8C247F011BD5786EA24BF4D3E7A3B51 +:10048000F411F191B37F7884EF594D1A5C47BC1495 +:10049000D76D9CA5B5F3FB38FDA4B77B6060BF8723 +:1004A000F26C795EAB3F9934B8D9D007F87DC4A916 +:1004B000821F77A20F867ECE4C116752FB60716857 +:1004C000383F87AAD255D6EF0D1C12F37F1A8A57F0 +:1004D000E1FC3DD03F05EDAF91F6698E98EF7BD9F9 +:1004E000C69C50063A3F951EBA3CC4F3372F17F30B +:1004F000E67CEC6D46FBD3C9EFF357FDE39B0F8C15 +:1005000032CED744FF8B439F9BFF2F0E65E6FF251E +:10051000213BFF57E1773A33F0FFD74299F97F69E2 +:1005200026BC7C017E6F0A65E0CBEAD3C4F78F045A +:10053000BE7FF405F1BD51F46FFBFCF86E1B01DFCB +:10054000EB108FA781EF8D23E07B5388EC95470854 +:10055000FE901EA43876D72CD82B956484E376EBD6 +:10056000385E9D8FC3F0FE81C4E87EFE9FBB62991A +:10057000BE4FC3FAFD83157EB3DF9C90B8270DFAFA +:10058000F5E89FDFF5E520C5FB997EBC27F497953C +:10059000FB0F8632C8FDF93297431F6FD9DB89FA0A +:1005A000FE0B8CFF58263A5B2DE03E955D7058D0CF +:1005B000075BF7E3A1BCE1F2AF47FC9ECA3DE1C493 +:1005C000C110F957FD0B515EEDFC568E84F1A82247 +:1005D000232DA19FF073A1C72A433ABFCF20FAED84 +:1005E00054D312E6B3EC6CD624BC6F6419EF97A118 +:1005F00019238FE78483C1D7172279673C8FFDE6E3 +:100600000CD9819FC94E6ACC367E1B22BB2DFE0AB7 +:10061000C9ED33EC72DB5C871CEFA6BC17DFECCCBA +:10062000BFF7F2F3A02AECBFF86B56F97F34A409A8 +:100630003F948FF759F50F83EF9D10D72BFF8DA5B2 +:10064000133E275E4E056711EA793EDE4799F49422 +:10065000733CD36F35F7C98D3AC912D7718707ED4F +:100660005E5718E549874CF790160979B26876B657 +:10067000B0DB353F8E7F978893DFB5E2F66A3CEFBB +:10068000EEB959AB4014143471BDA7AF184FF14FF8 +:100690002D2CD9CE93CD72B0BFBB770A7E9F9CCD57 +:1006A0001BC179CF9D0769F41BB3D06EA078844637 +:1006B000BFF795E3E98E62FC74A3D4DDB81CF5EABC +:1006C000C220BF57125D728AEFBCF1F893B96E88F1 +:1006D000569DA27D1BB5D702DDF49D8CD36EEFE94C +:1006E0006ECC945F32232C9B788D8D8AD76884E200 +:1006F0005A267E87CFC3F7AF3ADE2C21BE435592F0 +:100700008657AF428C4ED05E924BFB289FE92B550B +:100710009C5E80F925A37F67A3D3B4D7CE0BE77D7A +:1007200071B8CC7623CF27DA39EE2BE0B917C5673D +:10073000835C8E5143567FEF706EC6B8BF596E68AA +:10074000D58A549775FC148F430EE64FC7A2686F85 +:10075000B500A747887AC90EA3EFB95BF6F39A30C4 +:10076000CF73DE99155F1E26F862F4FD42D0B4D334 +:100770005A0FEB772DEE2BA8AC5FE8F4FB8D5C9A5B +:10078000BF7317D3E396EFA599FC3A369104FC1E8C +:100790008DBF1C3489ED7F24649E13723AB8336890 +:1007A000D69374481E2FEDE679F9BA49275CAE68F6 +:1007B000815E43AE00D81EAEBF203A858D579A8821 +:1007C000E2A7F759FD2995E42FAF03D43F7588F4CC +:1007D0008576A614637A4AAD7BEAF038E057A5C85F +:1007E000CFAD7B8AE4DD601DD298CFDCE31FAC1B6C +:1007F000DE28AB970CD69358DF29F4E4F670DD536E +:10080000EDC4FFF13BACFC512DE8F02F4D7F3D7A5C +:10081000BB86F70C925195ECAA8D0E7AF8E7B09B47 +:10082000F05FA525EE477A5874F3808A5757BCC508 +:100830009110F2C384E80749FCCEDE8479224DB5DD +:10084000947FCFA127BA96F8B207F705785A02C667 +:100850002787F62795797FCA52B43F7E9DBF97B10F +:100860004EFE368FBF05CA383F6B1E1EDFDB27E406 +:10087000C9536145945CBE6645DBC99FF2D6C91475 +:100880003FCEAA936D7A837E298FDAAB367AEBCF8F +:10089000491C0C5BE523A4E3656C1DFE29911C3CFF +:1008A0007FA92E53D7A2BFFD7D61FFB17DBA97E42A +:1008B0004545C49FE0FBF64CC67D137839D5BEBDD7 +:1008C000D89A88D5BA46DEB74B2FE3F9F4CEE7BF06 +:1008D000137838DEF89FDF437659E91DA0EF7E7765 +:1008E00095B6511CD68CBB7AF656A70BF5A17CC0E9 +:1008F0007581F03C2C9DF3BEF8C9DF6B744FE42387 +:100900004FC6F324258BE3F9486B23F5631B4CBFDB +:10091000D372052E85E7B1D9EEF199F7112E074E66 +:100920000C4BE2CBBE82726879A342DF77B802EC4F +:10093000F914979B795F2D667E1CCFFB4A40F60227 +:1009400064C36549C7EF4C406C01DEB71FF6FB136B +:10095000E27CEBEB8EBC89AF362E8BD58A76EFD35B +:10096000FF5384BF253A97BF4B62FC3B3F97C42F90 +:100970008BD55ACEA35FFA54C99837191FC4473C88 +:10098000563B69383E96C725B7A69F1A2FA78B8777 +:10099000656AC5823C7D381E9CEB6718DB8A78FE51 +:1009A0003AC333DA9D23E183B5A3FD78E932857E2E +:1009B00077668152EFC273902B1B243A6362F80D65 +:1009C0008BBCB8FAF32DF03AF1E8C4D7954F00DDAF +:1009D0001BB8F2BB218AB7BD60E2277D2E9D5F98D0 +:1009E000E72796751EE3F95B1AAD73F1EC8A5FE0B9 +:1009F000F71512ED4CDAF2F5DACE019733CCE3BD00 +:100A000005B6EE6323ECBBED3CD0099F137E9FD06F +:100A10002BCE733150D3E5A807CFCF12E763D32095 +:100A200026CEC7B2281DB734B3BC757E97CEA4B30B +:100A30002B5A1A06E7C5F125480CD635BCAFF5B4DC +:100A4000B2F512F6F73551FEFB87F1CB723BF0DDC4 +:100A500022307F97C8A0F3A62B04FE1A98C787BF41 +:100A600099762E134E78AEB7C8F0E941CB3ADFEB5A +:100A700096EAC43DAAAC2553B15F72BF326D38BC53 +:100A80006BA2FC770E191D7E60A543DF24FEFD5985 +:100A9000275E4C7C350DE165DA67C1CBEF5171E61D +:100AA000D1790DD9B9039297EEC39BE738ECAF49E2 +:100AB00037139DB764150B3B80AFDBFCCE1740337B +:100AC000D9F74BC57DACA32E687C38C8CF752A2DCD +:100AD00072EB3B39D5B76459FC63F35CC7FCAE9449 +:100AE00049CF977B836985D3A1EDBB5143794C09ED +:100AF000CA6352B256E8888F2E7C3587EC9EAE2CA6 +:100B0000F49F03FCBCCAF7F4A35D97E843FBB7E985 +:100B1000AAC7BA67B0BAFFEBBF4ED2A07A0EE12DDA +:100B200024F6AD5AEC9B099FBF9C3FB7EC1F8F9FEB +:100B30009589F899D8C791F484B98FE6BEA11D852F +:100B4000F4EB2B53FF9CE9F7FAE050D500F2692251 +:100B5000AA520E5D427AAD83BEC705FA4E3C7FBFF6 +:100B6000A2C565FB9DA604DED3C7F61B7DC22F89F7 +:100B700051FFE5F9BC3F9471BB7190EE93ACBF257A +:100B80000F08BCE131B86FFDAC2FE689B1F1C6A00A +:100B9000BE872ECB3C25C3E71D713C473F65F0DC8B +:100BA00024168B59E4F5BE2C6EDFBE17ADEA9533E3 +:100BB000C45FCC72B937B748B5E4871DCBF736664A +:100BC000FA7EA939DEE0F7E506EDC481A70ECD1B5C +:100BD000B2133777BC65B713936F7D213BB1FFB676 +:100BE000B79E6A67FDFFF43B0FE9ABF7EAFCB40F71 +:100BF000B92DE7C17FE07D5B157F0390EC7BFA3E6A +:100C00008EB7A590D623A90C73F83B627A4C427C30 +:100C1000BF891FF3C5B88A0EE910032E578D498886 +:100C2000AFDB853FCAE86C8AF53BAE6F66713BC3AC +:100C30009CC7E38524DE3336C76574D04679A5F5B5 +:100C4000407AC43C8735F9D91CE74496DD0F3E0D48 +:100C5000FE3D91897F9F959BFFFD16B45F9F5128B4 +:100C60001FF46FA337D1F34B5BAEA4F2B2966BF9CE +:100C7000BC62BE6F4A8993384E5FE3AFFFF64646CB +:100C8000AFABF77AE85ED9CA6FBE792BF2A7B7850A +:100C9000ED3B6BFFBFCC8E383800800000000000B9 +:100CA0001F8B080000000000000BE57D0B7C54C585 +:100CB000B9F89C3DFB4AB2BBD9DDBC96BC38E11902 +:100CC00025C44D801010EB86575109049F51026CCA +:100CD0000884008104A4BAAD1436246040ACF155F8 +:100CE000F1AA7451ACB657BD4169E5B6D16E442D39 +:100CF000540AB1BED00A06A516154DE45156ABE50F +:100D0000CEF7CD4C72CEC92E84DAFBFBF7FEFEF196 +:100D1000D77ECC9939F3F8DEF3CD37676F5C587521 +:100D2000FF986442CC430D4E8910D29C45CA5B6D3E +:100D3000B4DC209501DCA898A7EDA4B0CE5132D246 +:100D4000398690B3F0773994276399781C0652441A +:100D5000C84A2BFDB742C89943B77BE6D3FEE26D84 +:100D6000362F7D42FBC9B9CB40CB64AF4C1EA740A8 +:100D70004E20F3CAF228B43038D069242405A001EB +:100D8000611A40DAAF3542679304EDBCDE7A3ABEB1 +:100D9000D518244E8011233E374B747E79BDF31154 +:100DA00050F4678DC8848C82F1F4EF9BF139AC0B61 +:100DB000DE9793D83CC4FBB9F0FE1880621E096C24 +:100DC0001E49FA7E1CECB94CEA014FFA7934254EE3 +:100DD000CA73A6009E7C230112D2692AB31332D7AC +:100DE000F68783523E85565B58A690044CC73B73EA +:100DF00009FE9D1D04FF5FE1FC78042112E994CEF9 +:100E0000D2A1677C23850752FCC595C8A17539140A +:100E10004ACED2D1A369B3129317F0D93124D93E67 +:100E20004835FEE540453AEFD78D4E3BCCB36C8A52 +:100E30005C16CAC3EE53AE857EA654156D62C359C7 +:100E4000492A21F3D8BFC9EBCAF6E641B43E1834AB +:100E50007987523ACEB3064330BF79C418ECB462F6 +:100E600013E9AC84503116F1F7E87CE74D967D71BB +:100E70000E4D3B7296CE9334919787D0FEE74A7C15 +:100E800080202DD3F70EF3E207934F5E07CBE824C3 +:100E90004EF320DA7E6E67E574928F5536E0A785B3 +:100EA000BCDDBC80E9684FBFF47F95416D797E71F0 +:100EB000C1AB940C142FA169A381CF2E32209F5572 +:100EC000356BDB2D7CFF8A4F8803FA351EEDC13769 +:100ED000CC93DCCDF8654AA353A1781AED54B03C0D +:100EE00063F24793092DCF24E43AE877E664D919F1 +:100EF000A6AD37070CC44727BEDF278724BAB6FD47 +:100F0000B99D7B2F07BC159B94C761ADB9E4CE6B2F +:100F100092A17E9413F05C06CF06607B42A09DC731 +:100F20001A1A4A9F75F83EB255A9F86E7FF1471715 +:100F3000F929BDB61A484D347E22A401E9FAF28F90 +:100F4000E2B19F0FEE9342163AFF29F2377F1C4B16 +:100F5000E753F56393D7A2E0B20C40D7E95E268F42 +:100F600084F86C53283EE71256FE88941585E9F8FC +:100F70005505874A2CB49FAAF512CAA9C03FC5F7E8 +:100F8000876ABCF9EBCB12C30AE25DF39C76660676 +:100F90007EA678FE30069E3F54E339F0FEBB235F09 +:100FA00056B5BBDB694F063E2785A4F02C45CD69BD +:100FB00032217114E9BB6E01CFAC3D38F2E5A1845A +:100FC000DC477C5B50EF904E63D9484A2723F145BC +:100FD000D303A50E260753E4E3489F13C5B202F8D6 +:100FE000DA1FF8D446398CECFF469E0678263E4A36 +:100FF000EC71BDEF3DE334E37B5BCDC40778DE9A53 +:101000006E0D35D0AEDA7F74715A27D247796002FF +:10101000D0F10F26F2B8127BBEF6804C8650C62C5B +:101020000D480805FD0606E28871944A5F91E8F3D1 +:10103000FF1DC8319D5ACA6A6250E8B8AE20F185DA +:10104000A2F08568B7CCDA3DD548B07DD845E7B782 +:101050005C318424BADE0289F1B3D554EFCBA04DC4 +:101060008D6DB3821904E621E33C143A3F239D5F62 +:101070004E2001CB8302490807075C08870432B081 +:101080007E686030C261811C7C3E3C3002CBB981FD +:1010900051082F0A1420BC387029C2118149D82E5A +:1010A0002F50827064E02A7C9E1FB806E12581598A +:1010B00008BD81D9585F10A8425818A8C4E7A302F8 +:1010C0004BB13C3A703396C70456202C0ADC86702C +:1010D0006CA0116171A001DB8D0BDC81E5F1817BDE +:1010E000115E1AB81BE184C043580F0A08F010CFF4 +:1010F000E5F10E6581934A0A70B8027C1C4BEEFE46 +:10110000C1ED52B5D3F731F09D68673610BFBABD57 +:1011100068F735B71B2EA06B94FE4E73FDFC85F768 +:10112000C39F0E27BD746BF6349411B9975E969DDC +:1011300025E10CFACFE5BB6611D00B243759C3A7C4 +:101140007DF5035BDF5FB8FEDA6AECF0C9C0BFF57E +:10115000C41BA48F4A47BF2E413FDB14E3B4501495 +:101160007ECB7799705EA39D7E938BC2849CA32FC8 +:10117000833E991974FE7122F04B5EF21F26D2FE57 +:101180000636196004AA4A9CED13A9DE512613D431 +:101190008BDB084179DA16AFB5A7C35C0C1F84B4AA +:1011A000EE1984F234A490D99FCE2B40BECC3F1AC6 +:1011B0004436E580BC852523ED2FB89290C785CDB8 +:1011C00080F61BE6FF1CEA7BFB33337FA199BC64EE +:1011D000A513C9695126C65138788BEFA538FACACC +:1011E000D0907F623C2D0F7F32F812C08B5A431390 +:1011F00013281CB12BFC1235A76464B873A28D961A +:101200002FD94376035A0B3A9449765A1E75D0B7B4 +:101210009BB20119D3E99FE450603EA146079DCFE0 +:10122000D6C3C4DB40CBC5C75BE444A2A2BF99F8D8 +:1012300077A8E8621FDD313989FE337395B34086A4 +:10124000F78D9D71AEBCBEF4D906EB8675523BF2AC +:10125000385D57A62F2C39557C72B54B1274280275 +:101260003ACC58DD6D84756E6B72DB917EF1CE12D7 +:1012700018B27B0A713EAA001F1B114FE6F583507E +:10128000DE05DF51FC5E34CBAEC69B24F45A4D6BB9 +:101290005E6CFC5EFD6F86DF23C06D6362E3D70A80 +:1012A000BC32EEFC725CE5EA91E379AE31B1DB353C +:1012B000BB983ED5E3799B81ECA1B68A8E4BF9941D +:1012C000C91509D2A68D9CBFCF87D71FBB985DF9E2 +:1012D00077C1EB4D2EA62762E19528C9A82729BF23 +:1012E0005E4406C7D637D05F34FB758FAB8F9E3315 +:1012F00083BFD8ECA47A6E706C3D37D7C5E81D5318 +:101300007F713D63E67A5C8CF7334EB7038EB2474C +:1013100080BEB6F58620C85909B1A35C104F32E7EC +:1013200013673CF0C974D95902FA860C27E847279D +:10133000E48582B04F1918540A6568064A19F09876 +:101340009E1BDA44BBCEA17E8691D29F761506689D +:10135000559C86F974DD8942DE9C951EB5BC097BDF +:10136000DF2B8F822FDCDB36E5307E9D45FD97C37A +:101370007CDEBDFD48D86EC30FD3B76D52E9C16D99 +:101380001E0F9645FB58FCFB8DE0DFA675C40FF2DF +:101390003121BADF70D02573BEEDF6019F07BF473C +:1013A0009CE0CFB89A3E44FDE4A2FA4942FDC4C68F +:1013B000CF0CC4FF3C48CBEFB852B17FC0E3F5F689 +:1013C000FF77FCFC948B30799AE06C9769FD406A5A +:1013D000871490D30974EEA3015F66A4BB42181D65 +:1013E000950924047E2FC55BD800FAD7600F819D34 +:1013F000319B5B7C20CFC4ECC2F51F70F83F769D1B +:1014000043DF3813940220EA99BBFF3ECD46F96FC3 +:10141000438E331ECAA76879B3878EEBEE24BCDCFB +:101420006C43F9A17FE948C530DD1B807D14659FC1 +:1014300015DA0FEA2907A1BC157C92F1B47FD7D742 +:101440007B9A2862CA5DBED3301FCAD76700FA866E +:10145000D30DEAE05E7E3E9F3F20E4B3579E9C059D +:10146000429E2AF3501F4AEE94DEFE62F937BFE532 +:10147000FAD3ED6630967F23F8FE82FD1B3E5FE2D5 +:1014800056CEE9BFC4ED7D63CB765A5EE99195A354 +:10149000D4BFB3A7BFDD61A4652BF5373FA2658339 +:1014A000B5C308ED4AA984DA28BE7DD4C983FD8777 +:1014B00075342BC31FEC3F4EB448D398BE5612AFC1 +:1014C0001D792E3C86703D2B3D661C2F6EE89044A6 +:1014D000902B07E72B62944260C71DC54EE37CEC5E +:1014E000AF935C4DFBBBC4CDEC82906BD05BCFE681 +:1014F000815E721B61BF6EB192A0DDDDDB3F941394 +:101500000B7BF513E1FBB89BF99EA9659D3771082C +:10151000C8E97E16476959C3E4B2349384D6819EE4 +:10152000F011C549DBC711F1470597964DBC34FD55 +:101530006B89F8E8FCF77D2D23948690B09DEEF73B +:101540004ABD5218F68166833504B6B424DD4ACC10 +:101550005076184216908F0F255CA7B9302104CA27 +:101560006F727A7162275DC7C97DBB6DFE28F4BFBB +:10157000C15FE99D3C2A361E7BDACD79C509787CAE +:10158000486972821F19F41831EEB0119AAAF4FA60 +:101590005C37F347A83F540E7C3A6341779319E8D0 +:1015A0009D938CFE1019E246BE1DE0D9B9B1044CE2 +:1015B000562DF34FD349A841ED5709FEEA74FBE7D6 +:1015C000BBE93C1EE276848A65C73088575D94EC9F +:1015D00006BFB4A42EBD0DFCDD07D712EF0213EA3F +:1015E00083EB605C5F526B01F0EF43DE9DBFB80B95 +:1015F000F069A1FB62D0E3A30ED9144AAF8A31BBD4 +:1016000053603D7FD4CD5FC08AC01AC48B7E1FBC9F +:10161000D2CDF7C1F9241FF6C127BDD7248691B7D3 +:1016200092A2CA7745E036EC47EC87DF3785B39C5A +:1016300051E5508B6F317E85C4F6B5C42431FDC7AA +:10164000ED28D52F4DA8074204EDA6CF223D0AF67E +:10165000E6A4779417EC762C7D23E643F138B4CCDE +:101660001EA55E2265D1F4C45637F30F2A4C74BF11 +:1016700040EBA51563EA615E15769B047C27DA6D65 +:10168000E2ED043F8B78959CF8CD18A03FC407A3EA +:10169000AD7F1E319E52C7A33681ACA5307C79A3A5 +:1016A000F82BB1F075D0D4520AF33AB850260DB4E5 +:1016B0009F93FEB16924CAFB02BE077C43E9B22AAC +:1016C000898DD743CF21D1F177706D8D77B2A997EE +:1016D0009E7DEA2BE3CAC17E97031E55E31E70333D +:1016E0003B7F8C4362F12B4E5A6F9E7FBF938C04DD +:1016F0003D756A4CD00E71B1EE5F3500BD7F6CC791 +:10170000784579E5E9310D2355F82C266824E7ED75 +:101710007ED0A9D0E7E5439B5282B6D8783C0678C4 +:10172000A478BA031E8CC378CC1FDC17108F2179E4 +:101730006EE437B23BCE1B8678E45BB217FC06182A +:10174000D78FFA93C5935739D9BCE2747E5E79601E +:10175000B946BF244424124A52958DAD189F4D8836 +:1017600018F1B95EDE9ED2C99BC07F2C7A0AFCEBD1 +:101770009FFF9EF3E5C1CAC50AC40DCDF1D1FDE0BE +:10178000EC2449C3576FAFF56BC67BE75B59B35F7A +:1017900016F0EFBCFF93FE716910AF2A370787F68A +:1017A00047CE057EDEFEE60127F41BF79525AAFC51 +:1017B0009DE2F689DAD3E6EB14953DBD516E02BC8D +:1017C0002718B97ED3C99D0FEC2AC5E7E56057E914 +:1017D0001413CE6357E791603BC491F5E30B7BAAEA +:1017E000E72F615FF574137CE049A2F44BE8A59FF5 +:1017F000881BC6922F21579D5CFEF5F8D7C31BCCE2 +:101800005ABF47C0CFB99C9DF4C79120D58F379759 +:10181000C82122217FA07D3C78BF84FE66B8D28299 +:1018200076B9AA320EE3B3550532D657DD29A3FDAA +:101830000C53FD504BE7F347AE27F4F1D912227950 +:1018400027ABD63D63749CA67CE3C27BFFB816E24F +:10185000CBC52605C6DBAFB07873D027A3FF4AFB04 +:10186000F086213E7DDF655EB067821FF6FB6494E3 +:10187000B7E09BB21786EDE0F1E8FDCD052119E850 +:101880002CF97BC6510643FF550AD0E15DCF1627E0 +:10189000E8BBB86F1F282BC3FDA35F2940BB499D40 +:1018A000553AEF382EA793D28BAF073BFEC1661394 +:1018B00081B8D107AB4FA23C77AEADF74E1EDA1B15 +:1018C0005F16F1617D9C591F5FEE1357D6C59305D6 +:1018D0003FE8F9A422067F087D158B3FA81EAB4A7E +:1018E0004AB9703D26F4C77B7C9D93D2B7DCD940C2 +:1018F000F190B040463C08BE7CF79BDB1F013D1CCD +:1019000047F9631DF0F3B74FBC02FB10B2588A1AB7 +:1019100047DEDE63F7285D727BE972A37F714F19A2 +:10192000C47F76CD8A9E32AC5F6F5762EBB573EBA6 +:10193000AD61492C5EA1B73B7A79F857DB9DF2CABD +:10194000FB73E1FDF2CA8521801BD3AD35A07FF585 +:101950007A426F27C47CF4F34C88C824344A3D6F24 +:1019600005DBF5DA0933D607AC8E7C70D6CFC431EF +:1019700018042710FCD2C371A1461CAFFE92329C02 +:101980007FFD588001E2ED0CC2FA3CF1183F68C9B6 +:1019900064EDE52BE2993F3EDA8DEB9485437ECAF8 +:1019A00085E546BE86516EFF734914BF8D3E431CCC +:1019B0009C2B4CB21BF742C8A565A28158482F9EAC +:1019C00084FF4E203240D78B7512EC3B0BACE6C146 +:1019D000E89FFE16FA216BE8BE90F2FBBE7DF2CEC8 +:1019E0006D7489FBBCA312A3F9E702CEF1FC10F5DC +:1019F000C2F5812A84877EF04E36C8EB2D92FF55C2 +:101A000090838EF2AA3BE15CB86E978CE74A736EC6 +:101A1000797718DBA769CF2765873517E2288D52BC +:101A2000BC17F488C063BBDD8CFAA5F110D3838D9D +:101A300047245E66FB889779FDC9F7EDB8CF10782B +:101A4000A7EB790BC6F7DDEBC2F5887DC677584F5B +:101A500027E027F67A329DA82F80AFE4DEF9CB7617 +:101A600023AEAB8BC47B61FE011E0F22EFC7A1DF4B +:101A70002CE85BC7F94FD07739A76F57DBE99F5C3C +:101A80004ADBB7F8DC78CA2067115C6FD7FB09C85E +:101A90001F62BD940F4EC1FC76B7313BD172D8CED8 +:101AA000F0652FCA85F909FFDA99C4FC64FDBA2BE9 +:101AB000C43E9DFB19E0DF429C62917BE2D9A431D8 +:101AC00051DA73BF96E2D9904CEB4B9CE45488F406 +:101AD000E2598C23C615EF3992B57E4C058F2BBC8D +:101AE0006F22E5104F84710B55F35BE32E7124A731 +:101AF000F41DF73BD07140F239F9524BC73AA3AD10 +:101B0000594A243DFB620CA5297DE55C2F67525B99 +:101B1000FB57703EAF97FF33867A22D17E6F95FDDB +:101B200007DD1436FA49A765705F79389F1EA1F466 +:101B30002E484EE9AB4FFA4BE709C952CF3E86D348 +:101B400079427214BD27F03DDC5DF63DA887F5674C +:101B500014E23ECF0774073D611E84E3215F76BB2C +:101B600048E851DA2889C751C47C202E1147DF9BF1 +:101B7000999C83E34A461234D17252AE5702BDDFBC +:101B80000F3E98F92FE6839B92CF29CF61F44B96B5 +:101B9000717A2F1379163BCF9D67D10FBAD5C03A12 +:101BA000CE18BCDDFE9C0BA7DBCDC97DE4F3E6E4DB +:101BB00073C8E770B7FF1618AFD14C4EA11F5E5C1B +:101BC000E981F10E387C9F24D2E72F36707D924355 +:101BD000E946EB5F4996515FDD432E463DFC3D8370 +:101BE00001E7DF45F5EFA339D1F83E6874D3F7CFAD +:101BF0005C4DF03C8EAE6F3DE3CBA004CF6F9D47B4 +:101C00000CF0DCA33410C305E8A196BEFCD9722EFB +:101C1000FEA47AE85EA8A7FCB80AF8D1AA388DE736 +:101C2000D2433F4BD6DAF97EF0DFCFD478FE17F0FF +:101C3000DF2FCFCD7F17CC57CF45D307828FC5BEBF +:101C40002056BE10954792E1EE3B2E215E3C0F2BB5 +:101C5000715899DDDD21A19D6D3C52E0C7B2DD8A4E +:101C60004A41D8E1133B59BD3C31BA3FD896EC66A6 +:101C70007906AD2BBC464D1E48109FDFE53BE11CAD +:101C800042F5E254D986EB4B2A65F143B17EAA674F +:101C9000A74F49E57153BA9EA42C868724EA0FC04A +:101CA000399A83EF0F128B8D1ABF5FE0ED56B94C56 +:101CB00082B8B72B9940DA0DF5EB570F87F37B9776 +:101CC0004FDB3E856CFE52C64108CA839BDA6F88A3 +:101CD00063254DD3B5837D483EB4573DCFE9BB9FC7 +:101CE000F83899EF27CCC4037685C815E7E41BD5EF +:101CF0007EE2F3E47EC4454E261BF8798AD67EB593 +:101D0000C691A871818614BE2F38E542FF57E6764A +:101D10006B72670EE6A7ACB42B182F9065AF757A7F +:101D20004EDFF75D3E035154EB4B9A164F14D5FE30 +:101D300021A5CCAD29A795A76BDA0FF00FD2D467F8 +:101D4000D45CACA9CFAA2FD4940706C66BDAE750AF +:101D500001509707375FA9693FB4E56A4D79F89656 +:101D60009B34ED2F0ACDD7D48F787289A67E64EB91 +:101D70004A4DF9925D3FD2B46FE4715F3D5E2673C8 +:101D8000BC361A99DE69B015623CB2D1A68D4766A1 +:101D9000F37625891372210EDEF861412EE0FB6592 +:101DA000C7788C8BC7E20BBD1E8BA53FF5CF2F4BA1 +:101DB00061FAEE8B97CC069083E5BBA9BC5E42CB63 +:101DC000B6F736C09A9AF3D879AA91B0FC1E71BEC4 +:101DD00022DEEF395F317A597CD561239BA2F04531 +:101DE000768A1235FE29F82816DE1AFA89B7297C78 +:101DF0001DDF156FEF4B2C3F55ADFF774499D79AF8 +:101E00001416DFA2F6655E0AF37746C7A327EE44F1 +:101E100079BC50FD2FE641F5FF9214F443DF98732F +:101E20002BE8FF9D162FECC9BE287FA3FA0105DA27 +:101E300057B3F6066F2ED02556FC7B4D4A9FF87798 +:101E40000D8B7FC76BF0562BE45D17876B747C8D11 +:101E5000F1EF46B337B73FF1EF5AD031294007C60B +:101E60001F3DF4E5F1F358FBA000217B25D8F7D8FE +:101E70008C0A9C739D6F5F4BF7B3B9709EDA02FBBF +:101E800026D53E87EE6FF9FE260EED02B57BF7A64E +:101E9000A0DE237B15FAFC0CDDF76E52A028EC9F28 +:101EA0004FE3975B88D76A96919E0FA6E07E97AC2A +:101EB0008A93215E16DE3721E73BD9F3ED291760BF +:101EC000CFC9F9CFE5D0EE94D2F5AF8BE277E9CF69 +:101ED000E17AFC6FF0D3243C8F433CADA77611CE62 +:101EE000E3DA53987D5E7F88ED93D71F99E541B97A +:101EF00049293AE7395C7FF5CDAB297DFCD25753B0 +:101F0000CEE1978AF5AFE4FBDE29725E2BC41B4F4E +:101F100044CC883799B0FCC8BA3D2612427AB23C0C +:101F200063414753644307D86713D1E7152B89B042 +:101F30006ED31E19F5134966F541626D003F27B156 +:101F4000586BB75C3EADDD4A9AE6D6D931ADDD4A75 +:101F50002BD7DAAD017EADDDCAA829D4D931ADDDEC +:101F60001A1898A8B3635ABB35B8F96A9D1DD3DA1D +:101F7000ADE15BB476EBA290D66E8D7872A5CE8E75 +:101F800069EDD625BBD669EA0BC29B34F5A3F6DC16 +:101F9000A3298FE9F80F4DFB457B9FC3FC9BB1073D +:101FA0001FD5B41BD7F94B4D3B8AF00EC8D35E80CA +:101FB0002421E4D263CF6AEA17703FEDB2EEDF6806 +:101FC000FA212D2CDF3A48FF037AFD95F8CDE09CED +:101FD0001849F7AB1994AECB4392374C9B2DDEB525 +:101FE000A308E6F1D9E12BF6403F8BB668F3B417AE +:101FF00087B4E53A322811F4431DE58B10E593A52B +:1020000090BFADD26B4B49BD03F321FAC9678BF684 +:102010005E4330EF33E8EB80FC74B14EC16F3ECECF +:102020006F627E62BD4BA9DF17567AD7E9A3FFB175 +:102030007D64A719F8B67A9744FE43EABB9E9AB628 +:10204000BB37644459977E1D7ABF734CAA368E3DC8 +:1020500045B6615CFFC49BB297C507B572B8722FD5 +:102060008BE7AF7C5AC2F89A1E1FC22F8D85173995 +:10207000C8F60975C9241452C99FC2F161F168E517 +:10208000EF04FC03E6F3B01C82BCA038255ECF6FE2 +:102090004561D217CF09B95A39D5E3D9EE4D8FCA68 +:1020A000570AFD0FE6514DD8B9949EAFF4785FBE44 +:1020B000EB6E33E8C50BC5FB8254EDF9A0383F2821 +:1020C000A1AB3547C9831378A5FBF225A929B1F740 +:1020D000ADB7A45EF0BEF596D47FEDBEB521F51C7C +:1020E000F1B32E889751BF521F2FEB1B1FDBFD95BD +:1020F000E4C038348B7FF9BD5696AFA2B393B91EB6 +:102100008D9DECD9F77E28851A69E7F50E5F0BAC3B +:102110006F85C37737C0990EDF3DA92AFC3452BCC6 +:10212000E0FD1C6AA77644F10FF7A50ABFA80CE3EF +:1021300022EB4B587B7DBB5FA7B2FB40ED29451ED0 +:10214000F43B8F1430FB692F3AA7DF79173FCFB9E3 +:1021500003CE0B87F6E6F1DCC9CF55A8D8F9806E1F +:10216000EB4D651E759EEF83A92E1CCF31EED90E67 +:10217000C8776E741A9C9202FEB301CF459B7CB661 +:10218000693BF3D87BC99AF7D8BD2319F00DFEBC83 +:10219000CDF8B59A6FF7515C42BFB1D6B92F95F91A +:1021A000BB26E2B382DE15E7B9A60F0BACA06F8D9C +:1021B00092D7192D8FD3C4F3A426F2F35CD9C9CEDC +:1021C000777BE4FC3C7952373BFCAFA9F9549CEB9C +:1021D000CE76F8F6C1F380316801FF32608DBEFF24 +:1021E000FD13A7E35DB03EA4A70DF908C797FB1543 +:1021F0003FF9732AC6E58298AF78ABEC3D06F1B99A +:10220000FEC6AB3E4EED13AFFA58CD877AF9A3FE6A +:10221000E72789908797986EC4ED84D19B0BFCDFEC +:102220000CFF1E87F1D5CF61DD7DF24F1537CFA7AB +:1022300055CE994F2BFA2977F94EA5B2BCBFBFA551 +:10224000B2BCBF2659D58FE33CFD503CE5D6DBFA46 +:10225000853F396D0CC6358FB160C285C5351D69A6 +:102260007DFC4747DA39FCC733878627C279B288B5 +:102270005BE9DB59034999EAFB31CD2EEDF81B0AE6 +:102280005979001F777922E3FB91698C8E220F50D8 +:10229000C4ADADD3890FEE3BDCC3F3B3453F23D3CD +:1022A000ECD83ED53D71645A0A9CA749B8AFDCE032 +:1022B0009234FBCB4F524B46C27A86F3FE47A6318F +:1022C0003EDD3688C567F479902778FB13A9131192 +:1022D00052825D04F834CB72543C16A6B1F97F9259 +:1022E000C8E45BC4CFAAEE67F7BB44DC4CC4010969 +:1022F000F1BE9D40F5CA479B4D04E25A0B65DB06D3 +:10230000E0C39EFB73FC5CDD49FF037B5999578654 +:10231000F947DFF5FE16E033C1DDD75E5E99D6E3FF +:10232000A7782FF01ED7ACB40B386FEF8C677CDB2F +:102330006DB7613C5BDF6E29E787CD3C4E01FA1A31 +:10234000EC865B26F5D1ECC7528EF733872C3EF432 +:1023500063A6C5633E8738FF3052FE4C74631A781B +:1023600010A035909109F7897ACE3F1482EF25D9D4 +:102370006CF89E5121613B5C09357A25C82FEB34FE +:1023800077AE4F83F95E2679E1FE405A85B33D2D45 +:1023900019EE112A28661B7288A318EA0B0C58EF55 +:1023A000BAD6B9C10479D70A81936C62A2E3D8E99D +:1023B00038F7A6E5B07505AF694FA3ED12956E32FB +:1023C000280FF48873AA07E4B89CE5AFEBD7D7C40D +:1023D000F9D5B69EEE1B001F4AF43CF0A63483C824 +:1023E0009B6F047E2D51C84E762F8AE5A1429A3507 +:1023F000E60B7A59BE7402E41B0D667A06EA7FEAA0 +:102400009AB411DE13F225737C03DFABF3E1EFE541 +:10241000E324E9E453E0930ED000F910C6E904F98F +:102420007A6645F4F93EC3E9BCCA51F620F0CFCC38 +:10243000090D98E74EBE397B562E02A797C9097D34 +:102440009F401C222E99E9DF3845417D4C9C12E6C5 +:10245000995A156F0D94E36CE39D32D83D0B3F2FD5 +:102460005C6020462A6F93783FBE72227D9CCBE24F +:10247000AC4CBF1AC9C7422E648E9C22B09FEC8F11 +:10248000FA459B13E87A26D9F6E13962DC90FA1214 +:10249000B857F0CA3CD6C73D31F2F63FE17ACC2DB1 +:1024A000FB3D06F0E9837F79EDE50948E78BE1869E +:1024B000E61DA6CED7F65CC6E3E7982FDEF99A2F85 +:1024C000EF9FCF2F7F2DADF3B5A6BCEFC2FF5E0906 +:1024D000F4F82794B160DE7AFE17FAECA0EC3F78AE +:1024E0001BC5FF7594A90285008DA402E9CDF28772 +:1024F000AEE5780E7E4DF16CEDC5F3756D7B117F09 +:10250000074D74DE747CD344866AD38F12793E46BD +:1025100008C7BDDEDA3205FC9B2E73773E8CDBF5F7 +:10252000C23B5941AA4F0EFDF8A49D50FEFBC0D8F6 +:102530006D87E7C756BF61F751BC1F5A2DE3FD37C2 +:10254000BC97ACCA07FA9CCBCB959EB2A3C057F3FD +:10255000D67E5BA4F6B3492005EDEEE2900C777CC5 +:102560007BF4DFD2271338D3B1F2B2D6244D59D839 +:10257000E36596E8F7C40779985C2C7E6A9B19F2AC +:10258000E1AFF4F8FF06E31FE3F906C776DA717FDF +:1025900025E633FFA90233EC273F68B39030F0BD46 +:1025A000B1C344304EE59B2E51BEF5733ED4CFF3FC +:1025B000D51713B0BF85F7CB1847AAA46305285ECB +:1025C000FD6D8BD9FE56B78E858794A9A0AF166E88 +:1025D00094485061ED5753BAF903B7E3F98A7E9DE9 +:1025E0007AFB729AAC36831ED1DB9705C4DB3C01C3 +:1025F000EC568BF6F9A2B63BB0DF45E7398FF178A0 +:10260000F8FEAC888C3D3B18E2CC83305F3096BD41 +:1026100039B69609E5A76BAD088FAF75223C0ACA9B +:1026200094E279E9AEF6573350AC3B8AC00EC5ED63 +:102630009D64BD89F4FACFC66DD7841F52802FB533 +:10264000F990151CCFC27F5EC4EF199CCF7FAE807E +:10265000759E231FB2A29FF99027F68CB2C2F3F1A8 +:10266000021F63293ED0FEE61D50C8F9ED6F2CBC59 +:10267000C47A6F197CE7200A9E85DC1CE5FA7DC1CF +:10268000F6591BD2E9041A5FF86B7627F2258B43C3 +:1026900088732AD9B3A103D62F135DFC2F48DE24FB +:1026A0002AFED5F3E722E26576C7C6DEB3F2B84468 +:1026B0000F5FB6DD8978157C04370A0C1E80618FA8 +:1026C000A1B8EF7703FA7C1FA0455BFEC2D4990D39 +:1026D0007A63912E5EF085147DFF35DD3388AD5F22 +:1026E000F14D85BC8885A46C038BABB7A09E3A6680 +:1026F0006C79F53690E7ED4C9E963DFFF4AF414F77 +:102700002DF9AFFB1DA0A73E31B6A4C278B58FAF9F +:1027100077805E3F660C3AE0FD4F4272D4FBBA4FC1 +:10272000787ACE056C9017B61C590C042C3803F43B +:10273000E4DF1E3739218E5AF7A4256CA1F858BE64 +:1027400093E191968FB0F2ED88AFBA5D5A395CF2A1 +:10275000C4FDA90AEEE783191C7F19A0AA976F3759 +:1027600061FEE8F237652F0C5347BA717DFAF761C5 +:102770001E114AB7BA56B9D29CD8B79E7A3C669019 +:10278000B3BA9D8C4E753A3FB386EB653DBF3FE0D3 +:10279000E17E26E7738A178C87897C561262FAB924 +:1027A000F1170FE41FA1F33ABEFD358794D7CBEFA5 +:1027B00004B22EC12F6FAD9A077906B1F8FC0B2E2B +:1027C000173D7A9FDB1965179D18F8FE6D0CD69A98 +:1027D000C28E4B293E6AB799BC41FAB8F669D967EF +:1027E000033FE95D0B7EDF61E9D3AFBC3D9ECE6F59 +:1027F000E90E53F274B60C1BE86741A73AE0EFC24A +:102800005EBA2C79EE1533E441C2F3D5EE5EFA2CB4 +:10281000DDD16E86BC4A3D1E27B5B69B997CE9E8A2 +:10282000D47A642AD8E5C65F9C31031F7CF2A244A7 +:10283000C085D4BF5FB3ED1507E80FC013D80F41B3 +:10284000AF1EFAF5A15B78C66F46633B279CD3C4E5 +:10285000A25F00E63206F9FB99DFD0F16BDEB378B8 +:1028600061FD35CFDCEC8075FCD558CFF8FC91F5D7 +:10287000A9608F6B4CC1542742F6BC66EB0F90FFEA +:1028800016BDFE8354827AD33700E497AE7300AC52 +:102890006FE1C3D7E1FAAA891FF9AFE611B90CFCC1 +:1028A000C4D346322D9A9FAF0C60FAE9AF8F5A70AD +:1028B00053F0573361DFE1F893CCF2F8C80AF443E0 +:1028C0007EC0D74A3531964F5B199D4E79C4FD7550 +:1028D000A6C7EA78ABBAEDB7A31EFB34CB9706F2D6 +:1028E0004EF1A08DA7BE3E258DEB3FFC5E0ABE4794 +:1028F000F96E123C87F61D265F5CBEE63D9ED7CA88 +:10290000C65FC5C7A7F38E87B8DC5F53B5FB570119 +:10291000670C107A807410357FC592FBED1B91AF68 +:102920004EBDC9F4CAF2D0AC6958DF610AA7417D37 +:10293000A8FD5A09F502F52FA2C9F57613976B6D1C +:102940003D9DA75152E3F745762FAEFA3EDA4EE5AC +:1029500087F4F28DB9F7794EAF7C8AFC8A453AFF4D +:102960004C40BD5E481FA0B57FE27DF2704AD47B2B +:1029700058BDFA20887C516B0AFDFC3F408EDFB5C4 +:10298000E03DC3DAA74DF8BD9CCF9EDAFDF64D942D +:10299000DF3F6B15F2ABD5B37AF9AD79F63A124D4C +:1029A0007E3F4B2E2351E5973E8F2ABFC92C7FFFD8 +:1029B0007F5BCF2E8AA167270FD0EA59EA4F245EAA +:1029C0004A8B9FFE72E940DC67E9F02AF0A9D79BA9 +:1029D000873C0AE257AF37E9DF9B448547813FC117 +:1029E000974BFE73198ED3C3BF823F05FFF6F0A746 +:1029F0007EBD5A3CEAEBE3E0CE514A2FDD4DEBE8D9 +:102A0000FE1ACE5D5F90F1DCB54BE976B8212ECB96 +:102A1000F36EBA9CBCEC62E5EE14F306D01FE279CB +:102A2000771CCB43E82AEB76B8547EFD9136D9016A +:102A300079F59DA1E8F91298499102B74463D53719 +:102A4000F0EFD6D8B203B02F6B61E73D0B1A6E7072 +:102A5000803FDDD536786639F8F17B65F4A9BAE2B6 +:102A6000797E55D0671C40F15AC5964C8E91E04F47 +:102A7000C1CFAE6A5B3A1D368D0B366BF1516DBB23 +:102A800016CFB3AAEF33F5F205017F2764063FABFB +:102A9000E661EDF325905705F4D1F1911FF828CAAE +:102AA0003D8C3B051F159002B64FE6E7555CAF4DD8 +:102AB00091F3669643FEE21E764FE2449B4C36C08D +:102AC0007A9FE2E757C114E4CFE5948FD571CEE346 +:102AD000C067C363DBEFE3BF3A54741B6D52FBEB7B +:102AE0003FE73F44E1F15FBF3BECB7507EFE9DEC1A +:102AF0003F93BEED27BDF8D55CCCA37CD142605F8F +:102B0000D4F5E2EFB36F83F26F2C5E9867D73AB6D5 +:102B10003F0EBE6847BBDE95C5FCBFC617CEE47747 +:102B2000A27D6A427AED1AC0EEA99E68FBFB61099C +:102B3000F2E9DAE8AAC0EEF27D57DD6FE2707FDDE0 +:102B4000F5C219CDBEF2BBAE6739BFAFD46527E57C +:102B500070BFB8CBC5EE77D6FD76DC63705F71D9F8 +:102B6000CE767315AD9FF4BB6FF341DF743DCBFCA4 +:102B700009EADF6E05977AF780039B4D14CF5F80DB +:102B8000CF974EF71FE989A5700FA32F5E181EBAC5 +:102B9000281E605D142F35A02763E1E3BD01ECFE24 +:102BA000C8BF1F3EBE9C0BE3D7B68D25104FEFC5A7 +:102BB0008BE463CFED987741D7CF9EBF78261FFC7B +:102BC000A3F3AD37F2FFD97A53D3FF5DD7CBF87DAE +:102BD000EB00667FF47CDF97AF9FBF05CBCFD8BDFE +:102BE00038DF7ECA7B51FABFABBCFFEFD0FBDAFF08 +:102BF000B3F4DECBE96D77C2794AD70BDF66930B6E +:102C000058F7CDFF47D7DDE3E718BCD6D1747EEF88 +:102C100091D0752552EC3CCE50BA761F3183FB1112 +:102C20003392ABD17F98E163F1954652B807EEA994 +:102C3000057D329E3B60320DC543C7B50521CCDB17 +:102C4000320687FE14F2B8AE5FE665DFF9D2EEAF6A +:102C500066A44E9B06FEDBFE063A2FDA6EBFDDE071 +:102C60006CA44B98E993D1DFA310FDBCB7265E8519 +:102C70007921338BB5FB8C9B74FB861BCAB5F5D7CA +:102C800093475320FFEEFA1A13E60B5DA76BBF269E +:102C9000DD89EBBC81D4AF67F1990BC353473ADBB5 +:102CA0004FF6C5C3B9F1D6074F7C3F89B93C4A5F9F +:102CB000BC59FC6C7F69A115DCDFE279722BFB85C6 +:102CC0004FC2F79D163EB4C0AFC5C7BED7A9EA171D +:102CD000F122F07EA1F81674D2E35DE057E04D4F8B +:102CE00087C7E04C42E58FF7429147E227EA7CCB69 +:102CF000193D7EA30DF178603BBBAF70A0B86A733D +:102D000001949F92D05F3B3D6114B1D2F5EE3791B3 +:102D10005DECFE974F7116F5E6B348C5BFC7730566 +:102D2000C82754EF4B219F50BD2EC8275497219F91 +:102D300050DD1EF209D5F5904FA8AE877C4275197B +:102D4000F209D5ED219F505D867C42757BC82754E2 +:102D500097219F50DD1EF209D5F5904FA8AE877CD4 +:102D6000427519F209D5ED219F505D0FF984EA7A79 +:102D7000C8275497219F50DD1EF208D5F59047A82B +:102D8000AE87BC417519F205D5ED2F8FBCA42997EC +:102D900090D734ED2759DFD094A738FFAC69FF7D79 +:102DA000CF479AFA2B94CF34F582FE57E59ED43C58 +:102DB00087338B6011EC63D85FA9F7EF9A7E8CA400 +:102DC0000CE3CC66528FD00AF15B0AE3492B421B1D +:102DD000157380570EF35F9C01FCBA35B801986BF0 +:102DE000FFB833D9A0FF0F4CB886C51FF839C14CC6 +:102DF000F8A7429938E19B4CD8D78A734F474426AD +:102E0000E151940F2312426724818493281F46E2E4 +:102E100010BA2349F83C29E242981CC9C0E729911D +:102E2000010853238311A64572107A2223100E88BD +:102E30005C84303D320ADFCB881420CC8C5C8ACF96 +:102E4000B322E310664726E1F3819112844AE42A13 +:102E50008439912B100E8A5C83ED064766211C1283 +:102E6000998DCF87466E44382C52857078A41261B4 +:102E70006E6429C28B228B115E1CB919DF1B11599C +:102E800081302F721B3E1F19F921C2FC4823C24B0F +:102E9000220D08BD913BB05D416423C2C2C8BDF89C +:102EA0007C54E46E84A3230FE1F33191071116459E +:102EB0001E433836B20D6171E43F118E8BFC02E186 +:102EC000F8C873F8DEA5911D0827447E8BCF2F8BA1 +:102ED000FC37C2EF4576E3F3CB23ED087D91D7F0C5 +:102EE0007949642FC2899137F0F9A4C8EB082747C4 +:102EF000FE8CCFA744DE453835F211C2EF478E2055 +:102F00009C16F90CE115914F105E193989EF5D158A +:102F1000F912E1F4C8DFF17969E42B843DFBFD0986 +:102F2000B1EE25FA0D6721AE6573F7EB3B5F846C5C +:102F3000D19C4B3D90E0403D397335CB23D9507245 +:102F40007232FAB52B2C0AFFBEA64EAF7E6303FF8A +:102F5000613DD40C607D401EE01CCEBF078A77A780 +:102F600080BFB4A1B0B316E22177E6745600BC2F3F +:102F700083F90D776430BB784F068B97560E73B28A +:102F80007B062B86E2F91549EEDF3ADEE4F659B40A +:102F9000BF398B976DDDD9782FA09FFDF4B7DDF990 +:102FA000F2A37E98E17F2203FD22FDFDBC7EBFFFE0 +:102FB0005FA827FEF9F79F3FD7FB1F707AA564969D +:102FC000FD16E769F4E543FDC47503E464DA4FE5F3 +:102FD00066C90976B2AAA9602AD0AF90F8309E38A7 +:102FE00027465E5727A7DFFC7A1381B8E27C85600D +:102FF0003C77FE4E96E70B71D052CA17359C2F9640 +:103000006DDC610617B4A67E11CB3F0AB1389395EB +:10301000FE07FCBC64F32CCC3F5AFAA436FE540BDA +:10302000711D19CE91B5CFEB789CA9CFB9822EBE78 +:10303000F46E068F2F7959DE11913371BDA7E97AAD +:10304000219FC37F8BDD0AFA9FE201CF49C4FA4575 +:10305000BC52E081F4BDCF8079A127F60CC53CB508 +:10306000138A9206EDFC549C3A6C90FFE01F0BCF44 +:1030700029FE309FA4BB2101F3918E507DAE40E22A +:1030800093D33F16BE9FD6F95E16E1DF6FD49E1B29 +:10309000583763FE75A5890E4CDB553E9E84F71F9D +:1030A000697FF9BB201EF9B809F3818264A58714F2 +:1030B000F73D57285B6F42FE98BFCBC5F2C382BE77 +:1030C00037215F5FD0E348D3E0A9905734BF39A7D9 +:1030D00000C36EBB4CE8E789F35241A7BE79D165C6 +:1030E00089F07DC425CDAF233D29BD34F5B59BBF07 +:1030F000C4FB03945E4763D0EBE8B9E89598A9A5B3 +:1031000017C4956F80CAD54928A715EBC243EB5564 +:10311000FCA88FD3934C1BDE7714F9C4D3D2193D8E +:1031200088D19B0A743DB9790CD24B4FA769FFA88F +:10313000427A90F7ECF8BDDD3983C9BCABE9F3798D +:103140003C6E39A7F10AF49F7333991E3BB0167297 +:103150002D09797DAD95F8A8F3FCC65A2796DF5A5C +:10316000EBC1F23B6B1584EFAECD4578D4CCF27950 +:10317000843C5106C0BCBAFC4C2647F999625FB545 +:10318000CA0371E969FF78638C0155A367C6942C63 +:10319000F4BB35791AE5D76AF3303A4D3CCF6BA3CF +:1031A000E485EFA8CC2FBB54D39EE48EEA2D83FD9B +:1031B000E07923F39B5DF8FDB61BA72769DA5FDF93 +:1031C0009CA1294FCD5410BFB3A60DD63CBFA96218 +:1031D00084A65CC97F378158E30DEAF329EA19B167 +:1031E0003C6F276B7BAA7E6CDAAD74FC53FB4C58AA +:1031F000AFA7C7517310F7E3C1472D5EB043C7E0D7 +:103200001E192D1F7B4B467D77CC44824EAABA8F68 +:1032100049A409203132793A7D90C9D3B47FC804DA +:10322000F6E1E497163CBFABDA229120DCA1EAA6D6 +:1032300098A7E3AEFA8505D7BD608B4CFC785F4953 +:10324000698573EB558F0FF7C2B9E59CC1E12CB8C6 +:10325000B7D7FDAB38EFA3B4B6AA93BD7F8CEEAF62 +:103260005D90972415E2F9C1E7A52DD506C83790E2 +:10327000F7A5809C7EFEAC8CF194C52BDE2A728271 +:103280005E7BB5F5ED623ACED11619C7FDEC49CBA0 +:103290003619E5DD9706DF75ED5D7708E30CAF794C +:1032A000CAEA32291F7C5A1DCA47BDB39AC5B7FB6B +:1032B000E287AE17E80DFCAAD263BD768B9D9351D1 +:1032C000E53300F44395C98BE7A647379BF03C8F65 +:1032D000EA7F3CFF3FDA926460FAE759E4BBF946C3 +:1032E000C5AC1E77FE66D9C77E174231C37CC9DDE7 +:1032F000B29F8C8532CB5708364B7E765EA3A5EF06 +:10330000CD2BC6E2FD627DFE94805F5099F2ABCE7C +:103310008196BCC0CE67C9E84EA33A7F5CC457888B +:1033200087F52FBEE3533BE8819F4CA0F0848F7D4F +:1033300072F0F4763BEAC7E386978A6EA5F0B3D2C3 +:10334000E0C7464A977AD9FF5026E4EF18366F95C2 +:10335000F05CE4A39FC079FCA74F9BBC28863C5F30 +:103360006BC92F170F3C577E10CC809D2F8753259C +:103370000F7C959760FEC66CD2CAE3032176FE0FE0 +:1033800093A0F871D6B273AC8FC6D837C13DDC2A92 +:10339000DDBDDD8FF8BD856732258D7D3ECECB55F9 +:1033A00006269FE445F6FD45C87B19A2B2A7429FB9 +:1033B000BE90C9F2497AEC2A6945BD52CDBF0F5C77 +:1033C000FBA485DDD3518813E47131230FF90AE49E +:1033D00099CE7789F9E99F023B2F221D68E73E3598 +:1033E00085AA3B72E0FD6D4D6E7CDFE40D81FC72C1 +:1033F0003B60A58A03F4C722C2E6B7AC450A8555EF +:10340000710AF17B1C04EC824ADFF4B5075A3BB029 +:1034100090DBBB854497EFD3A2B54B6509765CD7AB +:1034200092169EF7DC332F999CA538ABF6875E9DEC +:1034300081F396BCA128F35844BAC3F01DE0654F50 +:10344000B1FB40FA79E9D7D1DF79567B674D86EF3A +:1034500009F78CAB9BB7C037810B4A2A3A08BC5797 +:1034600007193EABDB24A4D75FB85F25EED909BAB4 +:103470002F22653340AF2DBA8FEE0B737AF9A0C7B8 +:103480005EEF08A1BFF4196971D828FFD76ED97112 +:10349000FD3878EFE1D7CDC0DF15EEF050838BEE2D +:1034A00017833FFEC9B4AC28F65D67CFFF55F821FE +:1034B0003CCE84EF517C2CDC2E635E83AA1D3FDF63 +:1034C0000F327E0E12CC23AA7953F636D2A735F0EE +:1034D000733E85173E5F819FFFED79EBFD98DC2CF5 +:1034E0009E6F10C38FD1EB973E7E8CCE7EC2BD09FE +:1034F000B097DD292C0FFC94D197E846BDACD3BB27 +:103500002985F8DD51A177ABB9DD13E32C047B47A6 +:10351000CB1F6F79CE01F187BFDCF75C2AE65180C3 +:103520007DC9EBB52FB754B1F16E793E0EF3963EDF +:103530002FEDC807BFAFE291DF3BD4DF35ADF3F825 +:10354000A766C17CB93D5C266FCB76823D0C44CF2B +:10355000ABE8B3FF8AB54EFB79D669D7AE733EAC04 +:1035600053751FA48AAFF3C366B6BE8F36B3F52E6C +:10357000E8B3CE209E83DCF298C51B443F238C76B3 +:10358000FCD80E99C0FDB31E3F4367F74F9396AD2D +:10359000808F652BDF396CA47CB17818C50FE5836B +:1035A0008ABB2D68E717FF8A9D7F7E2A95A4E101DB +:1035B000FCCB61C70FE9F325D43F00FFA2771E3D86 +:1035C000767F7996DAEEF7137FCB791C6A79DBEF99 +:1035D000F1F7A2241FCB875C2EBE03B34BF71D1857 +:1035E000057400BB276F053A651285ED13B5F1D45C +:1035F000BF0DFD72EE4AE4FFEE61EAEFF5D6C58736 +:103600004D90EFDBBD4342BF68D9AA12470981FC48 +:10361000561607BB238BD92FC9E7C3BC170BA56B65 +:103620003C1DEF27590A7BAE38595EF7C304BF3BF8 +:1036300023E6AB7F0EF1712BD83F9B01ED9F7EFD02 +:103640002FF07196C906F4A76BCDCCAFEEE2DF7D0B +:1036500078288BF9D30F6531FF7A1B8F0F74811F88 +:1036600009E7D39759F0F77A08998C71722361FCB6 +:10367000671478731ABFE8916FF497BB33014F73E7 +:10368000498709E839A3789602F7060EA75AF13B55 +:103690004AF4AF0CFA99CDFBD96F62F7040EC31848 +:1036A000745DB3793CF9307C06948E7F788019FD87 +:1036B000D8E00B16F4136E8F67F13E929C68043EBF +:1036C000BF89EBA939132C3E381F983DE1F63280B3 +:1036D000B4BF20A1F8AAB076AF2FA0E33418989D0C +:1036E0006F7013BC2F499A3AC700FE2EA16E31E4C9 +:1036F000C9D3D5EF3C9B742E3ED2DE53A885B8C209 +:1037000078C218AC18F1AB29D79A59FD1B8F1C99B8 +:10371000715F26217F826C26B0338023E08BCA4400 +:10372000DCE7CE843C7E374023F2DBD546123430D2 +:10373000D86CC3EF10B1BC7E710E725D310927D217 +:10374000F585F76AEF51DC10368487C3F98E31DCDA +:103750000EF833581593938E53364D2A04BCD7AECA +:10376000EBDF7C3F7EE4F88CFB26D0327CEF0AE670 +:10377000F94309F3796653A1073E9D6B242FCB854E +:103780008C7EC087756E2588ED56303E17F737045E +:103790005D0A68F76AFCCEE6F3A3FD343BE07D7377 +:1037A000F4B8C9892CB1CF637EDA522EB74B05DF4E +:1037B0003DA595D7E46C2E37E00F52BCCDE6301610 +:1037C000DFBBB2995CB8B2599EF5B71738DE320B41 +:1037D00009E3BA5FB0201DC5B833394CCC1E84FD57 +:1037E000897908FEAD26F5987F53CDE33106AA49C5 +:1037F000304FB7E531CCEFD7E709510709F3CE9643 +:103800006CD73F57C573648D5EC238A764EE5E0007 +:10381000F393BE17E7057E9F6D6EC57880BE9DA9A8 +:103820004542393735537F4AE2E75BB46CD92CE126 +:10383000EF3BCCCEEC1E89DF2BE77E7535A72BD571 +:10384000DE53E11E5035F85378FEC5BF13B585F938 +:103850009146EEFFCEDFACF5336637A9FC4C06345B +:10386000F7EA2DBAFC7013F7373E30778F047DAF3F +:10387000BF67FF8181CD3F984A303F52DCB337723A +:103880007F52F093926DD29C8B89FB9C15A0A7D898 +:10389000F70E74F95436FCEE4A85C4BF57C9E38A63 +:1038A00027A8BF89DF95391487764BC419BB4AEC2A +:1038B0004143227CCE9295E724DE3203FCCC0A877A +:1038C000D908F08CA113C7B955EEB0E7E4F4C6717E +:1038D00037948CDA027943D7678F9869CDC2530E3B +:1038E0007EBFC87B00F2D6AFFD86CE1FCB05337DF1 +:1038F000747FD4F54AF75C2B55D1B55B0B661AA9DA +:103900003DEFBABF7B2B94D76C1D3FD348ED60D7FA +:103910009DDDD9F00DE135D997B3FA06D1DFE53356 +:10392000213FB8EB41569E4DEB83E0E7F27B40151B +:10393000E325D4B36BB8FD11F1A30AC34B0C4E645D +:10394000BFF371BE76B76797AD01FB2CDB8FE2EF5B +:1039500009DCADF8D680DFD394E9AFCEA670C92CD0 +:103960002968867BF16F868671FB15F5772FD66403 +:1039700031B9DC3890F527F045FBA9FB67FA49839C +:103980007E5234FD04FE997E8EF6EDA7E19FE9E7B5 +:10399000FB8AB61FE19F89EFCCFD31C7F708F4BB66 +:1039A000740DDB0F93A336CDFDFF93F5CF0F03BB53 +:1039B0007FF2294B12F0E1D267FE3BBB1AFC3FEECF +:1039C0000F7DD6FEAE19F2BE9747D87771EA22EC8A +:1039D0003B39CB77B69BA7E6411E6BBB79926A7EDB +:1039E000B5BDBF7365BC5AE5C73C9A2DF2B5D9EF9A +:1039F0003A2E7DE613FC9EE05243EBC790E74BC6A0 +:103A0000B3389A7E9D9BF87B87E1DC3F4ABCE0C9D6 +:103A10006CA66FFF31D8F74436851BB309F62FC764 +:103A2000F86ED797BCBF8A78A6C7AB8AEC5685E2FA +:103A30007BCC9BFE46C83BAD7E38A750A6F37822D0 +:103A400073E20EE82F767CB39BC537DB587CB3C29C +:103A5000DDB18A1A29723C7BDE5DD6CB08B9EA015A +:103A6000D273DF0FE286D32CA27CCBCCC91358BC17 +:103A70000CCA07B6D6DD05F2B387FF3EDB9CB12347 +:103A8000E341CE3B73120C4E2AFFBB322A8FC33C5C +:103A9000E68CBD6C2A3C2FB1D88755B2F838F2C7F6 +:103AA000AE8CB2DF037DA13DC43DFCE670CA0D744F +:103AB0001DFE3FC89837EDCF4FF047BBA7F20AB7BE +:103AC00057C7B3999FB6C740E759D83B0F313E75EA +:103AD000CC567540DC6ADD8002F0A353324B3ECBFE +:103AE0001ED33B7E4AA6FF2094C5F874B9F9F0BCFA +:103AF000BFF3788BD3E333A01B85651364F8524280 +:103B00008F5EBF7A7282A67CEDF424E253C74DAF7C +:103B1000CDD094CB2B066BDADFB46084A6BED4D2B2 +:103B200031BAFE02FCFD3AFB9398DF7BA8EDF4DB93 +:103B3000B3C18FDD2E7B25BA9EC52F3CFE36E45FD8 +:103B40009F809F2029647131F6BD467E1E63F41963 +:103B500035E7317B9F3383DFAE8AF3EBEEE5EDC3D0 +:103B600038BEFE3C46E48BFFB3E7310903F5BFE7FF +:103B700079FC55BA323269573BD2A7712FCB636EAD +:103B8000A47E0B7C4FECFB3B2D21F886FBE7FF7DF1 +:103B9000C4ACA8CE65EA220DF8BBBA93761DC173FA +:103BA0009BA7B89FB4BCED4B33DC93FA7EDB0A9441 +:103BB000E7A9547F2552BEE968272377423C39C7DD +:103BC0008E79384B9BAFC03875626436C2DA962B5B +:103BD000B0BF65916BB0BC9CFF9EEF9EF88EA96054 +:103BE00087F7FCDA85FBC1037278D843D08FC58E86 +:103BF000FAA13463CE3AF013F6C407F36EA6E39548 +:103C0000FED7F7310F7DF94E09E3A6A532D923413E +:103C1000FE7D240EFB2B95FF347A057D7ED5246630 +:103C2000574BC1C7A1F572917D137E4F3AC6EFA4E1 +:103C30008D1DC8FC3A53279BF794C82CEC4FD45FDA +:103C4000367090E6BB7CA694EDC6F9B6DEF5983AE0 +:103C5000258457464620ACDB39CB08F9E77FC87D81 +:103C60002C19F044DBE3F7C1FAEAE3B189248ADED8 +:103C700012D0C2F5F06CD0C370FE9EE3BB66600A42 +:103C8000FC1E61A7D10A7AD4667582FF32A3B840C0 +:103C9000A956AD4B7EE946BC076149EE3681FD9ED3 +:103CA0004DA15A6FCF8B61676E1C28F47603426179 +:103CB0008F48E407EC3BA83C3E20E469EA4083E6F9 +:103CC0007B3A1D12938BE0AFD8B940698E7FE940F3 +:103CD000DA4F4709297F16F5684736DC47FF57CD8D +:103CE0009FD2D70AF477183B09C431EAF97C843CA7 +:103CF0009F6FFE7379FB033209005F1CB8FCF20E64 +:103D00001F9D57FB6DA346815D10E3350C6479A6BA +:103D1000C4D9FD0DE61BBE98A0405CBF14CE3C4646 +:103D2000F7FAF3908F08F1C3BA172D8FC20752EB41 +:103D30001C747F6F83BCC0B830F06DFBEFE28C6009 +:103D40003F0A87F81B002F937E377C327CC7C7D78A +:103D5000663112F4837CEBE079ACF99E4F7F0979F0 +:103D6000D4F399BF99C99F9FCB6125E7DBF95C0E1E +:103D70002B8DDE44388F99B74FC67B91F3574B2379 +:103D800077427C40B1E33D7D218742DE4CC097A362 +:103D9000803F195FD6465C5CBE7378BF4C0E4A65A7 +:103DA000966F573AC285FBE7E591246C27E455C826 +:103DB000E91D39FE1DC0D7A58D54BEE938FE750337 +:103DC0004683BCF4F289D909FC44F9C453ADE283BB +:103DD000C6F6AF8CC027A60912F28985C2492A3ED1 +:103DE0002AEBF14F9C5353E93C6634E5E0F79445E8 +:103DF000FDAF7BF8A57FFCFE18978FF9B6F050F069 +:103E00006B4DF5715EF88EFC896405F5D8CA8D128C +:103E1000FE38E14A53D924F02F563E28617C0FFC2E +:103E20000ED03F4507EBCDEA73901B23F9785E7DFA +:103E30004D6408C22732FD2F03FD2B23D7733CE6C8 +:103E4000473DEF3B557F3BC6D54E852C5EF69D31F9 +:103E50006DFC6E8CCF8BE77FA67D26B24D81B89B23 +:103E60005FC6F3BD2CE2BC5762F13B88E789F89B43 +:103E700038A71371380B7C0F5765474F1B5BB26136 +:103E80001FD2271E57C2ECFEF1ED26766FABFD4F19 +:103E900045065AFF698E0FE372AF79FC87613D4B8F +:103EA000AE0E3D63A2E5A5773EE78078B9C067AB6B +:103EB000313C14F64BAD148F101F6CDD2C4F0B31C1 +:103EC0007F2761962ABF22165F2F890C46FC087B4C +:103ED00023F4F7F36B3DB829157AFC7C7648F0F7AC +:103EE000322E07CB400E88DADECC2A83DF3523B9A9 +:103EF00012DE73EDB5374C1E849EA6FC8E72533ACB +:103F0000380BE3EA426FEBEDD16EB9F5DEF1C03765 +:103F10008ADFA950FCFC0F4D62B3890080000000CD +:103F20001F8B080000000000000BB55B0B7854D518 +:103F3000B55E67CE9C994932AF3C0986C43393077E +:103F4000700D383C22E1E1C78140002138C15B455A +:103F50004D65402411131250AE51B8DF9C90808003 +:103F6000D486EA55DA824E28285AB551B0C68A302E +:103F70003CB4A15A1DABADF456E8A014791BB15660 +:103F8000FCA472D7DAFB9CCC9C4982526F874F37D6 +:103F9000EBECB5F75E7BAD7FADBDD63E8789BFFC50 +:103FA0007AFBFF0240ED8B4F4F820C8009570920AE +:103FB0000A00339747CD36A4C16E736FF5205D3A82 +:103FC0004C5E500C70917EE301C4BD5F49F210005D +:103FD000EBF24A50EC00B7625B668FF54B004A3B50 +:103FE000D20051F32C47EC79A66CC2FFD1F32680A6 +:103FF000129C57E73BBF14E01A80DBDCC07F8DC802 +:10400000D41FD7217EE49B6A85397E5C1FCC91BC8E +:10401000F8F92A3C1307CAC85A2C0B6CDEFF2FB9DB +:104020002B44B00969004E7314D28A697E5D6E9587 +:10403000AFF32D725FA1F1BF2342633B8E7F67FC1C +:10404000F8888272ED5936628428C7D61B2F5B1818 +:104050005F453A8E1D09D0F59A35B419E5069C4F97 +:1040600040FE4F5F1B1C5A8B5B3B0C5D17C83EEA42 +:10407000CE1499F655BF2B85F1D727BB4202F6D750 +:104080003BBB8AFC284FD9EEA4300CC57576279926 +:1040900001D7FD26FFF6F1A49FB2DD0327094E14D8 +:1040A0007AA7D50CC8F7409EA2D0F3BEE4D7E54B63 +:1040B0006CF5FD97570AAACB0530BDCCA19AB05D2F +:1040C000783E1F6004C05DABA7B1F6E560362A19E3 +:1040D00060F2F94A00DC5BDDF91BD8F345E75318C1 +:1040E0003DFDC14839ED075E16602BCA5F91F3C3F1 +:1040F0001580F27526C3901DB8AF4E6FAEAF9970A4 +:10410000D93A8DF157FC6ACA54DAD7A21DC84CE3DC +:104110000609A142D2D351BB09B200EEB671F13FFC +:104120006FF860A48CE33F1FE91806C8BA4F6C7F94 +:10413000788CC0ECD949F69CA8E15D3A2F8282F2D6 +:1041400058CF0BACFD400E2C964B181F401AF9436C +:10415000FF9101FB77C1D32B928C78946A3F93082F +:104160004F566CCBE2FAE7683849D4E37F5DA61F6F +:10417000CCFF8E785A43782AF9B7E2690DE9A9177E +:104180003CADFD3E78BA841D7DE089E16CFA9B1C54 +:104190001F90EFF06D0586172677A72537D48C7C06 +:1041A000B7925D095F17A181F43987EC9B1EC3EBC1 +:1041B0000E4FE0F9783B7726ABC58B8BBF8B9D6F9D +:1041C000068A1BB766348082CFE7601B1F37AC645A +:1041D000BFE29EFBDB7E99766EFB8E76DEAFD91951 +:1041E000DC68C791CC7E32D935D1EE6457B27BFD05 +:1041F0002EEBE64BD9757841E09DDEEC0AEE6413B8 +:10420000C919B38BF506C2CDE76133907FF56557C9 +:104210006903D7BB4EAF0C9BA786D87900E99543BD +:10422000185E22DF072F1565ED7FB7A5029C0DDD17 +:10423000ED378F06B8B114BBAEA0EE7B5A95028A5B +:104240002FF8F7316C46056C4C9F9C56974626E13B +:104250007EA73FDCDDAF52FFE4712E3E1EF9715B9D +:10426000DDFC67424B22EB98DCAD5CDF81A8D93FD7 +:10427000248E1E89B4238E2E4DA037727E3A47DCE1 +:104280006C9E10F74F9C5F184EB43E9FE607D055CA +:104290009E8AF69BB94370AF457BDF32EE530BD954 +:1042A000A7A22CFA460EEE57685BEEB70FC6E714CE +:1042B0000751DED4B69656B5401B8FFE53ABA9D13D +:1042C000DA2E2822DAA9B65408793D3DF598EA316C +:1042D0009E67F4331BC78365E4E58D273BB2F15E2F +:1042E000363E6CBD8CF56F1A074AA8973879A587BA +:1042F0009FFF7001697D7ED4DD0DB8BF502FFE3663 +:10430000509B376232D501EAEBEAB60DADB65CB42C +:104310002F707C0C6B7BCCAF721C8292B0DF4BC9D0 +:104320009BA9CB11B75FD9383E7C297DE5F4D097A6 +:10433000868F1A235E5C66FFFECF510E5786E056CD +:10434000D1FE8BFC49EBC045F6D7F1BDD9AF0CC00F +:10435000FD2541375E8DF8FE859FF0BD0874FEADEA +:10436000AD742EF94DDDFC1CEF3B85EEF183D0954D +:104370005DC0C74F6FDBD2AA16337BB07E469B2F42 +:1043800081F7F6047A5C827F68F866FE49711BF556 +:1043900053D84BDCA8D1F47B4680D914F72213798B +:1043A000BE17F1F276B587E7770D1A5FA36EE7E4E3 +:1043B000383D0C88D9197F611864D837D3D3CD190B +:1043C000FABEF7FB67A0DF44D26088803859E10964 +:1043D000B7B6C4E1A4C5B39FE12436DFDE08C5FD4E +:1043E0009B353DADF6EC8B683812C8EFEA1820100B +:1043F000073B0455C47DD6110E7AD9E7AC9E3852DE +:1044000013C62BD225C6CFEE395E49180F52C6E52A +:104410008CD7EC3423C18E5313EC382981AED2E90A +:1044200090219EE9716E5EC7FA955928C75DDB043D +:104430003A26285E5B8461009BDA7EEFB7F727BCE3 +:10444000CA520EC6FCB6B6772236C47225C533866C +:10445000DF48AB8278BB81FC9DD1EFFA1517E1A74D +:10446000616536F23FD5F687561BB2DED2B25EA248 +:104470009CE6976DEFB79A71DE9B47FEEA0D9ACFE7 +:10448000DCF4A7C80CCF25F0DA9AB08F8D09B49A66 +:10449000C0FFC8B7C4F79684F1CB13FAD725D01B59 +:1044A00012E8D5C6F173E70BCC4FE6A2FD4871DFE9 +:1044B000E6377B347B76FB3FEE40B0B33CC980FBF4 +:1044C000E9CD9C7EB3EDA87FB53D8EF61CF393BF7E +:1044D000EB389680FF6ECD0095CE0FA98F78F64A07 +:1044E0005F381A9478DEF1FEBFD25FFB53DE098697 +:1044F00073799F68A4F788BADC7F8FDC63A7873A5B +:10450000FDB99FF2F1E98F19F78575A1467FE69F06 +:1045100084FE3FFDC71AAD76F995B87DEAFCE5FF4C +:10452000BC28D27A473C5DFE2DB8EFAA89E1C206CD +:10453000E4AB4AE32D9E33229D63F536EE4FE5AFA3 +:10454000897E3A67AA92C3854B8AE3F609ED45B4A2 +:10455000CF3DCB44661FB599D723F3C067012C85A7 +:10456000F6B85C8D4F22FFBE6562239D6B871BD31F +:10457000B348FEE15E5EEFED735D997507D27B5245 +:10458000E65864E4DBF3C064D6EE1595555D88E328 +:104590008B6D17D939BF27C5C5F4F3B5E76B7F130A +:1045A000C6AB6F3C325B3F90E6CEEAA07C75AD04B3 +:1045B0005B6592C7F738C3CD8FACC3D6A21C739B83 +:1045C000AECAA2FC6DDEFF5496F747BE792B259F3D +:1045D000C0F86028C91D583BD942FDF35BB4569D15 +:1045E000C2DADDDF6C7F7328F277AD117D9B9179A4 +:1045F000D779AF731ECAF571128FC31F9D2E7092AB +:104600009C8F7A03C95EC2ABD3912CD0E1E1969D19 +:10461000B370DE87F395146F668C7FF737E21CCAA0 +:10462000375F3D3D2F2B8074A697E366D7F9795904 +:10463000F3E2CEFB0567CC4CCFBB2DF23D945FEE91 +:104640004ECE155481E939BD12FD65BE965F235EDD +:104650001AB7F772EE9BBC22D3EB516B237C8C20F4 +:10466000DEF360E63892531F57F27EA0D941781EE0 +:10467000200F8FCFA3B3F2267A48DE18CEB2DE2504 +:10468000DCB03C1AE9E2CD69EB553A0BF761FE4F1D +:10469000726428E5D40FCB9101F34EC86E2F8ABF08 +:1046A0008F88E5A92BB478C0F90EA90E56B71E7AEB +:1046B000362944F5CC21F52F0EB0C7F3733FA97608 +:1046C0003A543A8C3F7138CCA4D7C3E6E0B1FB70C2 +:1046D000DC824D128BA30B36652EEFA27880F62C70 +:1046E000849EEBAEF44A6C9E3EFD44CDAF34F80997 +:1046F000E457D2B9D6979F946FF6566EB1F7ED276F +:10470000D55ADE5EBE49F213CEAB4B1C66B81AEB2F +:10471000EC4DAF6F253C562F4E1A6E45C1AB375945 +:10472000997DA30E87EAC6FE80D3614EC5F6560D6D +:104730000FD1A62456A788591616F7C4552532E975 +:10474000A74C04B30DCF15D1E993FD9C6E7163DDC9 +:10475000B6D2512A937D577865B6DFEE7ED7ECEB63 +:1047600004AC6BCEE13ED271DC89C6871F1D85F299 +:104770009D84D08DA350EFE7C8D0B8CEB91D624854 +:10478000A573C2AC982B30EED500F7F7BA03DB2D3A +:1047900013F0AF350DD533A83EBA33247D14D56A56 +:1047A0009F8BF8DF17F09685F2DBBBB6199FA3C786 +:1047B00058C8AFEADA8DCFEB61DD67E2506ACD1FF2 +:1047C000450769CF71DDC60FFF3C647F1CDFDD5EEE +:1047D00047C6312CC161380C47CDE23AC5AE9B08C3 +:1047E000768D2293575C9114223D8A79FC7C980245 +:1047F00042288900E1C67DE3BA5F060F0ED98F809B +:1048000010EF1FC1F4723488781A88FA70DA18BF72 +:1048100078BF18B2E2BA65E9A0A4923E1FAD047059 +:10482000307DAA6EA4A7643498293E7579B83EE716 +:104830000AE06F677EEFCBA3FA78C1A62466BFEAD1 +:10484000C7EFFCD34F4792BD2A32E2FDE821C25D9B +:10485000099B0F6C69B1793E69FAEF3C92A7EC09AC +:10486000AC2BA9DE14038FDECCE2658A8FC52D77D1 +:10487000F447A308274D29C3D602E1A47F9EB73889 +:1048800036BE7AC5B2223E1EEB5527C5AB24B69F75 +:10489000DA1D568693B96B44859D8FB916763E7E98 +:1048A000D492C4E8DA01A5CCCFE69A2040FBC05CE4 +:1048B000309BC575AE72A8B583B2DD4E717E5D4486 +:1048C0007432FBA89ADD2C649FA7BDE96CFD39A466 +:1048D000633CB70E68389B6BE2F8815D42682B8BB6 +:1048E0004F0D32F97F954960712ED11F7F434918D2 +:1048F000C5C93CDF6D34AEEE21AB6F8587CB20EAB6 +:10490000F2209EEA4C91053FA7797F6D65F71AF575 +:10491000B88F2427AB2F941751FE7A33982D742F1C +:1049200025F378A6CB532F574E219C62FF4133F6D7 +:10493000D739783CAE4BE5F73DE0B085B6C6AF471A +:1049400032E7F371B293FC6C34C30BF9BD09FB3F42 +:1049500005DE5FE62C95A3F8BCD304ABE99E84E4A6 +:10496000193C346E5DA4FB0F253C2E367B1D6487FD +:10497000F41B67D37ACF892C2EA1333D544AF9DF3B +:1049800073E208AA63E7AED957BE81E81786B94932 +:1049900084B9CFBFC7CEA7BB349C4529EFA7F30A84 +:1049A000E917B0FDC8CBF3FB80C8EF713EF2F2FC13 +:1049B0005FD7ABDE5FB74662F6A85BC9F150D7F4AC +:1049C000019BB7CE11C9227BD4BD245D43B83EA55F +:1049D000C93DAF2977DC41C4C73CC9E516F051ADEC +:1049E0005A6121BAB65560B4BE5EDD9A3F66998AB7 +:1049F000F97CD45A351CC5E6CDCCA3F3ECD4B3E98D +:104A00007973E3EC7EAAE565A76C27BF0917BAE9BD +:104A10001E6671926F33F3536E8F532D859BE99E03 +:104A200066BE3BE210B07FFE3DF96974CE1D76870D +:104A30002DD47FB8DD63225A71BBC711AD98AF6624 +:104A4000F4290CE1EDC51A78D14E8B048E9BDA6700 +:104A5000F759BCB89E3B9FEBE7CC73EF15D17D4176 +:104A60005D5EA488CE5FC455510ED9E51981E50974 +:104A70008B9E1595A4A1315C2D225CA1FF2FD470D3 +:104A8000B568C7CBF7929F2E223C0DEF894BAC2B1C +:104A9000F7B3E72FB695031FBF9F70A79FF748B7DF +:104AA0004874AF66D1685C87E8D47C99F901F64F09 +:104AB000E2FD6A313B47206AA17CB85EE47902FAE4 +:104AC0005336E511F51D92DA1D2F695DEA2F8EF53B +:104AD000F7859BE1F926CDCE56761E0DD7F4125DF3 +:104AE000F392937071E6B97D6F8CA1FAEA45C14DDE +:104AF000F1BE871F6A7AAB273D39D93E595E544FC4 +:104B00007A71C6F4D4ED6F1A2EEA81EB41D74BBD12 +:104B100059D393DEAF8D1FA1E9A11634BDEE18C89D +:104B2000FD5DF36FFD1CD1F71748E3E3757CCDD72E +:104B3000F637219F9F9BB5881B5F31C39762B946AB +:104B4000ABFBB1EBCC0B6DECDE48B7A72EF7F27CDC +:104B5000EE0718A795D4B4989DA326A8E9ED9EFA70 +:104B6000264D7F929DC795234D39B735A2FE163E3F +:104B70002BFA98F2A8E68A5BD76A8A3A585E7ABF1F +:104B8000E8A67D95FDB2F23ADAB78E3B699B60EEFE +:104B9000184975462AD3BF2E5F593FFF75A91C7768 +:104BA00061924797F3881066F6525F10DC3CCF8D18 +:104BB0005AE8FE50F7D34479E76BF28A4E618C7065 +:104BC00035C9E393C9BF01CF41268FFDE032B69EC0 +:104BD0007A689967686C9DC3AAC34C7C8781C701BA +:104BE0001D9747B4FB88232B5F6679B0BECEFD3D91 +:104BF000D7093466F45C47E75F92CFCF01DD2F3AE7 +:104C0000D338FECB5A3E607C7A9CA51FDDC3E9FAFF +:104C1000D4F516E79706FDE8FEA5FB936ED77FD582 +:104C2000AF607926CB571FD0F6CD7C242B762E1083 +:104C30003EE9BCB35A109776C3B9C9F29A29033E2C +:104C4000B3047A79AEEB29F179AC9E72E791FEA7B5 +:104C5000D8B34D9407404BF6FE82B8BCEC63BAEF74 +:104C6000A2789A09FC7D06A057C69DE77ABEA69F4A +:104C7000D7F85BD78D4B1C5F9FA19CA0FE9A918BB0 +:104C80008B288FF847BE97E9EF24B45B26E07CB50C +:104C9000C723E54E3956AF5CFBF7B0E8A2FBC01D59 +:104CA0001E43BD507B7A3FF3EF3A88ACA2FA76EE12 +:104CB0009AF72A4691DD9FC67C1CF9E6B77AD8B9E7 +:104CC0007762CBED23A8949DBBB290D1776EBD8364 +:104CD000D36B783E377765C993741FFF7192524E3C +:104CE000F8EE5A2FB8A9DE1ABBB564F92DD83FD615 +:104CF00071652AC97D68CBC71563A86E681499BF12 +:104D0000285B1EBE91FA950ED1475B9D0FEEE5B76D +:104D100010BECD2EE66F87B573A259E2387B578B54 +:104D20001307BA5B8EC3B2E6E62213ADDB86E71348 +:104D3000EEBFCA22B787A9EE7BAD9F6F33E90BCBDD +:104D4000D46CC4D17181E7DF3516B011AE0E489135 +:104D5000A524FF81A58E614D248078E11AF20B45D0 +:104D6000ABB3B06E62EBEAFAD2D78F68FEA2CFA3E4 +:104D70008FEBA47C8ACE0F4DDE132D4FDF4879C216 +:104D8000896D856910A7F713B42FD4F79D18175FA5 +:104D9000ECA5FE3B94AFDF4784585BA3DD1B1E9060 +:104DA0005A07D0FB5BCCE38FC6E7E59FB425D90853 +:104DB0008F98C71B9F4BFC3CC13CDEF01CFDE6A856 +:104DC00031DFD7EA3BB1CA15E8250EE96D629EDFF7 +:104DD000956FCF387615F4C8F375BF4B1CAFE7F568 +:104DE000DDF72C1FDA13DEC78C72C125D63F1D44B8 +:104DF000C360EDB78D7C17E59D94F2CFED11AA2726 +:104E00005BAD6E2BEAF728F915BD077C49E479A262 +:104E10000D7C61C4C5D13F8EF0911F2EF890FBDD53 +:104E200082762144AFD8F7AF7F4024FE3B360AD0CC +:104E30004F88ABB31E597F23B9DD395F60557FE4DE +:104E40003FB74DF0A94C42C59E505FBDD15FEEBB50 +:104E5000BEFABE75957ECF94A8F72B0BB4FACA079D +:104E60003EA3DE797DBE1BE1533ABCA7DE4F0703AC +:104E7000AC8E3A1BAC61EDE8F6B6B21C94FF53E180 +:104E8000C84363C97F1C2E764F723AD8C05E029E1B +:104E9000ED18716126EAE755BBCB4D71E36CB0911B +:104EA0003DEFC68B86CF6B77EC117380F1EF1C8BD7 +:104EB000FCBBEC2E7AADD1CBFB366E5F8064FE7E00 +:104EC00054ABB7EF5E3CAA1F3DD7F77BF23E6E674F +:104ED0005DFE93DB6E77527EBAE7E7E93B47937D51 +:104EE000535C6E8251F506110223008E6DE071E86D +:104EF000B8CDF524DD971EDF784316D58377485D5E +:104F0000161FCEEB7BADD249F7027F33479D6E6A09 +:104F1000913F4C72984322C5BF315381BD071C138A +:104F20003683EC61AFE8194E469F3687C2489FA290 +:104F3000F783746E5F48E6EFE9B5F77E77BCC2EFA2 +:104F4000D3BAEF4FB47B84B1DA7E9715A4E9EF7B37 +:104F5000D8F3B252FEFC938DDB67D27C27B6486E45 +:104F600092F7EC1689CDBF10EB7813E2F038E28DA2 +:104F7000E2D7C2F7451F41FAC4365E272F44DCD280 +:104F80007D71DD6249B1B87AE2B14CE7DB29B0FA54 +:104F90005AC7E5422554CEF4AEE1D3867F2EE29186 +:104FA000910AEDAB481F8938FD57EBFE2584CBDE17 +:104FB000E241020E747DE97888E113182E75BBA7D3 +:104FC000B50F9B90C306A82C5EA8136110E505CD14 +:104FD000161864261C98927DE4E78D36E750BA6770 +:104FE000FA3289B7F79ADCAF53BDFCA54996046C39 +:104FF000FF56E061E3EF157D93899632A2EC7E4087 +:105000002C3329263AEF9AAD2C5E24C69B870A786A +:105010007EEA25B061FB4C819BE78FD0C0F207BDD3 +:10502000C50DE6527E529992F6858C2C3F2F983111 +:105030008BDEE3568E4D5B9A8F99E52F0A66CD3253 +:1050400023AE2B47A4BDE4457AEB163FA7AF4E2B0A +:1050500091906E126E983509F9F716283F2D288920 +:10506000ADA3CF8BCF37D2F3B7FA059EA0B6DE62E1 +:105070005F4DF1FE53A16B91498CF1BF2BC0E157FD +:1050800085181D95208FF2E967E89D6A49DFEDD903 +:1050900002655B412FCFE701AC243DCE537F7B906F +:1050A000F235FCF96D88B7EB35BCCDB3D9C3840BB1 +:1050B000582D9DEEC68597E292CB4CFE3D5333F7BB +:1050C000F5E6F01E1A3F185ADCC76C2C15DC783157 +:1050D000BDEF388F8E09C7F4F9707F9F4AB85FB46F +:1050E000ABA0A0ADD1A504547215C63761E76FBF60 +:1050F000A2799B558826313B54B9097F02044C178D +:10510000B1AD4B413CA09E96BC74663FC1FF4E3D85 +:105110009FCAE6DF672CD5F0787D4479AC0D85FA1F +:105120002408190568EB33B0F7AC19D73D610ABC08 +:105130005D807AAC35BD95B74426BF6D7652FE7260 +:10514000E679D13703C7D56A793B5C10C3E3F179BF +:10515000A767F0E6B57138FA40C3CF694F386F19C9 +:10516000C50F0FAF3BE1C2BEBC65C83FD53BAD84A8 +:10517000CEA54740F97301B3377FDF30D3DCFBF7AF +:10518000177FB882E73BB0859FAF5633A88E34D6E1 +:105190008213F5310D6529455A425A64EFE3438C79 +:1051A0009FF89C94A7C8B767F3F735E0277FD4ED45 +:1051B000A8DBA787DD5064CACF4D3690C85F06C311 +:1051C00046379D3BBAFD268B76166F96BCC4EFE33F +:1051D0009608D19674A29FC3F392F4A5F965CF7394 +:1051E00073AB854C51B3F176169FF4B824E31FC21C +:1051F000CFBFEB5ED252A89D9BC36018E1EADBF201 +:105200001D3D2EA17D1C8571EF7FBFD53EA422DC04 +:105210006FB5B6F664B14A36935E326D3E8ACB4BBB +:1052200036E5F7E3F1F82710CF071BD3193E57797E +:105230004466C78A8E1C90F1D19D1D02C878CECDE0 +:10524000E84867B4F37C7F46573CD56F22E5FFDD25 +:10525000EF2D9F1AC8E8134FBE3932C0EF576C3498 +:10526000BF1F74398ADB291F3A674739D00E7EFB8E +:105270006A765FE887EE3A46B828108D28217F527B +:105280002495DBC5D6C4FC5ADBD71237B7E39203AB +:10529000FCDC5D3281BFDF33AB835D8407A95384BF +:1052A00010D23F3820968491B5598BCBD66C13C859 +:1052B00071F6489293418EABDF4055225427CDD6EC +:1052C00070923228CDD0FF80109048AED9F6050CF0 +:1052D000370EDF1586F92279E59D4C1F019EDFEA26 +:1052E0007802F1B499E4FC629C00E9888B1FCCC67B +:1052F000FEB879A5719F4D12586BCC8B512F472F5B +:105300008527BF8EA7C13098E129413FE81F2CFFB8 +:105310003C87E738A54D985D3C360EE91B3B2508D8 +:10532000C92CDF64FE734E4961F7F72B353DE9B8B0 +:10533000F30F048782F3BA4A8D7A4B558C7A4B9FD0 +:105340006AD453A6DFA8977EB3BD86FEFE81FF30E8 +:10535000F4E7D40C37D0B90D630CFC57364E34D07B +:105360001EF53A037FFEEA5906BAB0F51603FFC0F0 +:105370000DF30CFD83430B0DFD576D5B62A087B4ED +:10538000DF6FE0BFBA6385A17F5878ADA17F44E7A6 +:105390004F0C7449E46706FE5107371BFA47479FD5 +:1053A00031F48F3DFEA281BEB6EB3706FEF1E7F782 +:1053B0001AE809F0A681BFCCF69E819EECFE8B8197 +:1053C0007F4AF6C786FE69F22943FFF4419F1BE836 +:1053D0000ADFD706FEB62B024F1462C89F6D5A77BC +:1053E00048058ACFF28FC7219E6FCA30FBC2C474B2 +:1053F0009975DB53855A9EA6E1F60BB0DF66F27E07 +:105400007B1C5C47794126E17A06D07DEFB9768135 +:10541000E1BAAFF3D985F9AE396E1FA98A0D0BF049 +:10542000189D3ED56DA033FDD906FE7EB365437F42 +:10543000FFC020437F4E8DCF40E736941AF8AF6C03 +:10544000540CB4479D6AE0CF5FED37D085ADB30D06 +:10545000FC0337040CFD83433586FEABB63518E8F4 +:1054600021ED8D06FEAB3B5443FFB0F06A43FF884D +:10547000CE56035D12D960E01F753064E81F1DDD54 +:1054800066E81F7BBCDD405FDBD561E01F7F3E6CC3 +:10549000A027C001037F99ED5D033DD9FD6703FFA0 +:1054A00094EC2386FE69F209437FED29841FE5CF42 +:1054B000AF0AECFDD7F4419F19FAA50CCCD3E97ED5 +:1054C0001A927DF41D7E629EAEE76F15BEAF0CEBA7 +:1054D000DC6B6A60DFC57D69E2799DA3C8CBCE37FE +:1054E000CCDF6D361667F1841AC2AE5A9A283F7522 +:1054F000A902C31DA51A55ECBE3083BD576047A352 +:105500004CDFA1617E83449AC9E3A1FA21259687E5 +:105510000EB838E2BBE7A13945C0F07F5D51C05DF0 +:105520005442F5D80BE5549FDC09EA2A9203CF5781 +:1055300017BD677A3BC9786FA4B7D36CA8BFB8F51D +:105540000E24B50E187E09BF9D663BCDF8BBE7D58E +:10555000EE9504DCDF92B8F91FC2BAC98C25646BE2 +:1055600010FD0BFDF4274137A31F096633FAD1A0C4 +:10557000CCDA0DC141ACFD59D0C7FA37064B19FD45 +:1055800078506174283895B59B837EF67C4B7036D5 +:10559000A39F0C0658BB2D58C3DA67820DACFFD908 +:1055A0006023A39F0FAAAC6D0FAE66CF5F0CB6321F +:1055B0007A477003A37F1D0CB1B623B88DB5BF0920 +:1055C000B6B3FE9DC10E46EF0A86191D0E76327ADD +:1055D0006F30C2E8FDC1838C7E2318656D67F0389B +:1055E0006B7F17EC62FD6F05CF33FAB476DF3FB502 +:1055F00088E75FBA5E741A6012C3839ED7CEA4BADE +:1056000085C0512A9D35D42D09F543A23D4E6AEB44 +:105610004813F1D8A63CE78AA2CDCD71F9FE7F16DA +:10562000F17BC10792414DC2F8D744C53C42B12934 +:105630000D42CDECFD2ACFBBAB355C4206CFB71790 +:105640006872556BFE5042F81CC4F0F9D6E5D44997 +:105650007A9DDC322030BF08DB85B92695DD13D872 +:10566000434594F73F3520504DB83DD770C71B6C6C +:105670003DB7AF8816A9B086336FA2FB9F0322BB4C +:105680002FED6BBD7AEDDF2FF4D9BFEBC4003A8765 +:10569000A67E23B2FBF4B725C76CBA1FB94FD3CB94 +:1056A0007D4526433B34D7DF48727E52D8F0E4DD97 +:1056B000C852B5B8D04579EBF5545AA3DF57822CC0 +:1056C000B1EF6341799D3E99FC01267644DF042ABF +:1056D0006B3B72024D34FE662C20880E8CB1E6F5D1 +:1056E000B69F44791ED470F16091C9D04ECFF5AF0A +:1056F00025FD1C2D540CF2A8B9B2F6BD7BD7E324CE +:10570000D73F5EFBEC98901FD3B77E2FB16A82F62D +:10571000FDD462417F4FCDF3411BE8F920EBAF5A36 +:10572000CAEF677E887519BDAFFC508B87E71A24D6 +:10573000162FAB84641FE5D3E71A960EA4FD24C68A +:10574000CD2A1C67C27155C0BF87A8FA3085E10B0E +:10575000E7037AEF5685993BD57F77E7EAF71E5145 +:105760007B269747A1F7B073765ADBA84E459C3C41 +:10577000CDE2D86851B5609DFCB6295424880C1F31 +:105780001601E5ADCE407CF49217E83858A4FDFB35 +:1057900018FD39E26B3BCD77F6955183D87B935D4D +:1057A000A365D25FB309ED41F735BF13F9771274E2 +:1057B000C54EDF71B88ADBD877FE944490BD463B76 +:1057C000D8FB903D2234BED04BFC7C5FB3DBDBD9F1 +:1057D000D2D4109BD7F89EEFF71AAE7EAFE1AD6240 +:1057E000EF81DC7B71DE459D12AB776064B4D8DF5E +:1057F000CBF74DF58D6FF62F88DB477DC711FE5D2A +:1058000014448BE3BF873AADCDABE349B438026DA6 +:10581000F678F9388E10D7EF911E10D7C728AF9FB2 +:1058200069955D37E1D028AA268C6DE00937FBAE7B +:105830004EFFBE6E3EF8595B8D70201CFBD5F5AC5B +:10584000FE5D08EDECF9A2D2DBF388AE87AE49D954 +:1058500054BFAC6E7A3D1BA5BBA175FD64BA7F9E9B +:10586000159AFB3AB5955B84635477A35F1C25BFFB +:10587000880A0D2BA924BDE5D9092BE99E77A6C876 +:10588000ED006F723B208E1431ADE7FED00F4ED18C +:1058900078F40326BFEE07552B387EF47F8FD1EDC9 +:1058A00017A577FD3587DE7D98BBD87721F5BBAC92 +:1058B0006984AF8554798AF179A17E3EF3BCE02EEC +:1058C000CC0B88EFA4C4ED7FF25012FB772F270595 +:1058D000C4C7F09EB8D7F3CC2F4DFCDEED5E11B7F8 +:1058E0002852BDFC30D3538D2D3494F484E7B33467 +:1058F0009070FD71FBAA6174DF37319447F9AAF407 +:105900008CD5D7EC31C479B89812BBC77B48E2F785 +:105910006A89F2F6C85B4ADFF88AF209AB05547A65 +:105920009F84FECFFDFE3097FF4B5320FB1A91E77B +:105930002BAC8E1EE067F53F64D97C6B859EEBB780 +:1059400068EB76FE93D7D36A2EB0EF7112E510DCC8 +:105950007CDD4479ACC95C0EFDDCE9290FB7832EF0 +:10596000CF90811E7E2EE6296CDF4DA65416BF3ED9 +:105970001503C5A437FD7E4CAF633B3D9FB0B80E09 +:10598000179A07F0EF7BC37D9DA7A7BBEB676FEC72 +:10599000BCD3EF99605CEFF7827E9B5B22BBCD02AC +:1059A0001F8BFB83E1435D3F867BC2FF035073AFD8 +:1059B00086E0390000000000000000000000000048 +:1059C0001F8B080000000000000B7BC4CEC0F0A3BA +:1059D0001E822538106C62711D0B03C30756D2F569 +:1059E000C17025507F0910E703711610A7027102DC +:1059F000104703711810BF069AFD0C881F02F11D95 +:105A000020BE0EC49780F82C109F40B277191B035C +:105A1000C35A36D2EDFF83E4E78940763910CF24AC +:105A2000231C46F1F0C0F23C0C0CDABC08FE3E5ED2 +:105A30005479051E047BB92065766D03EA0700E9F9 +:105A4000CD424A800300000000000000000000007A +:105A50001F8B080000000000000BD57D0B7854D58B +:105A6000B5F03E8F79253393C9839040C493970452 +:105A700009382421F2AA1E0842A4D406F42A5AAEF8 +:105A80000EC823869044B02DB7729B21092F411B6D +:105A9000152D5AB483458B0A36F268D106EEF028EC +:105AA000C65BB4D1A282D536D45B450B4944116F95 +:105AB000B5BF77ADB5F7C9CC393349406BFF7BC370 +:105AC000C7B7B3CFD967EFB5D75E6BEDF5DA3B76E5 +:105AD000D9C5E42B19FB027FA09CA330C60644CA9B +: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 +:108BA000BE80CA484ED56E7384D0CEF81F85B75AA2 +:108BB0003D008000000000001F8B08000000000046 +: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 +:1093E0001F8B080000000000000BFBC6C7C0F0A3E5 +:1093F0001E81C3D1F8E878022F7E7952B10C038226 +:109400005DC1C5C010CBC1C01007C42780F82410AF +:109410006B70323024027112102F00F21702712586 +:10942000101700D5363333301C6663603805C41717 +:1094300081F8061BE9F66B483030EC9241F0396454 +:109440001918D8E4A9EBC7513C78F15A0354FE5BD4 +:109450004D54FE576D06063D4304FF9D2669E627E1 +:1094600001F526033100FBB288BA68030000000052 +:1094700000000000000000001F8B0800000000003A +:10948000000BED7D0B7854D5B9E8DA8FD9F39EEC5B +:109490004942184248765E1030E01042048A9E49E4 +:1094A0000A8896D2889E165BAB4340823C035A4C96 +:1094B0008F78B2212104083050AC91224E10305ADE +:1094C00068A3A2D216DB8094A2F5F4466BABB53E3E +:1094D00002521E3E68EAA38EF7D4C359FFBFD6CE10 +:1094E000EC3D9909D89E7BEEFDBE7BD2AF2ED65EB9 +:1094F000EF7FFDEFF5AF358AE824F23F117211FEE0 +:10950000683A4C24840C8AA784C85A8F0352A25FFD +:109510002CB4E4C945E972F27F1B61CDEBBCDF7F5F +:1095200021248B90EFF032FA1782FC149E31E6630F +:10953000A424A890AE92783F5308CB6BA2402E0A89 +:10954000F0D55A6E8C53EFF08D2169847CEA64A9C2 +:109550005E458BCA69FA9633DA984F88430817B28A +:10956000F9D45D593D1AD3AB206D14C8EC4E4F921F +:10957000799035848CA7C9FE2122A988CF3FB19E5E +:1095800091363510D2658FE765998492F55B41E796 +:109590000FFD9E13C215381F0F91011E0A87878D7C +:1095A0000409A1EB3AE29F169843E7DF3A5909DA3A +:1095B000A160FB10684C7C061C67E761DEC1F39577 +:1095C00044E3F0EE6A29A4ED9C41916CA0B9A6FC9D +:1095D0002A07292564F3C4BF06C2743E4E3942549B +:1095E000483DC9E7379388BC9F7BC9E5AC3B713FD9 +:1095F00064D8A3F19815615DC67CB7D8E8BC32E9A0 +:109600007E8C17C95E9ADF543E2B0DE663ACCB917E +:10961000629C6680EB0842363638306D9A302B8D6E +:10962000403BD23B1BF677F3C42C718310AF7F64B1 +:10963000E271470F5D6F236FD7AA1D75407D639F51 +:1096400013E1B699C32744049CF7C6D1AED9D1D251 +:10965000FEF308111F966F76D246B00E2F89EECD1D +:10966000871E7ADAE6D2BC6F825AB641EB8F2F534F +:1096700046CBC12E3A4F8FC713B4D3724F80B57704 +:10968000BC2144356C1FF20CA1F55DC6FE4F10E302 +:10969000F0A4FFF7916A42283DFA727A5F8371EC79 +:1096A0006FD88321FADDFDD947AFCDA5FD92934256 +:1096B000702F8C4B965BF68BEC6170B5A9F4DFB420 +:1096C000DC3579FE0C5882FBF327AB016EEB8B5631 +:1096D000B856C35E95B0FD53E9FF2E16D0FE35C5D2 +:1096E00032BECDBCBFF9809AD6BCBB78D6D70AB5FE +:1096F000D4F8E1EEF191AE0C5A59BA05F73B55BDDD +:10970000FA37C65E73CC346E1BF1669E71D37F5CF4 +:1097100045AE423ABF44FB4F1B82D71CB3E1BA456A +:1097200033BF49557F2DC78F3E3CCBA7F8518AFBED +:1097300019B86174FCFB4B8017400F7A25F231A4F5 +:1097400045BADEE6AB49AF44F7A3A958D1D65038A5 +:10975000D855A54BF0B1317B01BFE01FB4A9BDA81E +:10976000B95B180399EF58F860CBE07F0D760D30A8 +:10977000BFC47DF8A2F0EB02F85D11879F9D54A74E +:1097800075C17E5707103E5E3E8F7557AFD4BAE85D +:109790007AD6657F3F749298E07815A3B3BEF9E45A +:1097A0004489797C83BEAE14422F027C2425F85A6A +:1097B00098C2834C52827B93AC4B16185F89C3D9F5 +:1097C0002113034E80BF87F5C00D5E9C52B5C304C4 +:1097D000677BE0F867003F399374B9C7E0F7263933 +:1097E0009DF2AF4CA2BBD3B01719F29F917CA44F4E +:1097F0005A3E452903BE302D18A6E334DBF878EA3B +:109800006ACBBE7EC6F7355EAE07FED9526EC3FE8A +:109810009ABD9C6FA88D38BF7EEDFDAC7DE27AFFCE +:10982000027C743CD45339FE340640DE3886344F13 +:109830003F02701F51D73917D6A8128483C1FFA9E0 +:109840000024508FCA87CFA09D43AB46B8DB73423C +:10985000248C70B3CAD3947C39418EF6C32795E625 +:109860008D3E0AE0BF392AD21B4994DF3C0D0DBB67 +:109870002C39D8984057B4ABA47266B4C0F82DD137 +:109880003371FDB281075C3FB019E0D8CEE859E5ED +:10989000E32A301FCA0F9D248A9DBB29A643DE4BB5 +:1098A000EA30FF49A8AC4B00BC91C97AE073F6904E +:1098B00048F4FCFEE36FE6F224D53A364F4C2E070F +:1098C00086094C0E489E3ABE1FB7A84067821E26E6 +:1098D0001781DE4884CBBF20EEF7BA867AF20E5DA0 +:1098E0008CEBE87544A3F823E7D48542B49D04B417 +:1098F000485934F194B3540E6A66FCEADB47B21A55 +:10990000FBB351B0C03A6D1EC71C320652F5064C6F +:109910004B46DD0EF4614B9B560FAA1CC59B4A01BA +:10992000C67724C72BE2A1443A11F35A75D2F1F855 +:109930007EF37A29F1AB0F3F8CF56A4AB5B73FDE6B +:10994000B8CA5501488166BB613E83F96C06879BA6 +:10995000978B6360DF22D387D3FD19DC3307E59350 +:10996000F78DEBCEC3BAD696969D00152E2DA8DEA8 +:10997000308DEEA7AB840800EFF5D0D924E8E18460 +:109980005E09721DFE994DC8B7856743BA87A18FDE +:1099900055DF1435D9E027E280FA8B70D1DEBF7D28 +:1099A0004AFE4C4CF483727CC5E5E94BB7B0F174C8 +:1099B000FA3FA03B7F823C4D0B99FA25001FEB3804 +:1099C000EB006F10BECBFF5BC653C93687067A47E4 +:1099D00091A846E9D86944F5535E4C5C536402F2A1 +:1099E00044CDE9D5617B2FB52F6B09998E7C94D23C +:1099F000AD19CF77723E10A869CA6FA6FD7E52EEF0 +:109A000009021F184CD966467AFFF56C4CD0B33763 +:109A100096EE46FED848F1A800F4FD5211F5A1F5E6 +:109A2000454FA86679F57383DFF4C30FA2C915C843 +:109A30003A08A1F0918AC49073CC3F8E1F897AD2E4 +:109A4000E5E287FB16EB7E7CD1FDFA759FFE7D7902 +:109A5000F8F18F8E67EC6B2ABE45F715F5EF166DA2 +:109A6000D680FA4BFF7DDD86FBEA2A22A1647CB812 +:109A70005B10ACF2C99C9AE507B9D3B25FB6C2AF2E +:109A800007760F000F5B49829CE4FD3AEB25ED342D +:109A9000E8B1B28AF2C8B01FD66BDB74D0E73FC919 +:109AA000214CDF8B2CEF12400F2A22A807410722FE +:109AB000CD3BB5507483C0F01FF6C5D06F6C541DFC +:109AC00033C357525D963C99AD0BE6F93BEB159CC1 +:109AD0008703C603BAF4D00E69BF520EE972A2FE24 +:109AE000C9E60F43313BFE9ECBC203035F01AC0CC2 +:109AF0005FADED9A036524D9FEF51BEF26EB7C5391 +:109B0000F2A5C4761E593B63D24752B793C9199345 +:109B10005E33B4CF7FA11BFADC2181EA858D81AF52 +:109B2000EB386FF80F95AF2D905279260DA9226171 +:109B30000DE4A4C6E8444B67F2B743B0D8E1C6F7DA +:109B4000D4F360E3C56EA7B8087C4DD62CFA7262D8 +:109B5000DAD810F8924C91D25DFFF024791C55624E +:109B600057876657D3FAEB1B3A26C177A3DE54D149 +:109B7000B0BFA9D834E9C732A1F51CF8955C1C0721 +:109B80001F55A299E4BB83746239FDCAF78FE03E8A +:109B9000A05E45BBAC1335EC572187B01E7404F5AD +:109BA00028179F2497B0EE20BFD1160AE1BCE488A5 +:109BB0006305A5BB8D4E9ED778DECFF32ACFE7F3A2 +:109BC0003C951390772B344F53A72DA262DEC5F33B +:109BD000F93C9FCEF37E9E2FE079611BE6372AACDD +:109BE000BF0D7294F5EFE2798DE7D3795EE5F90266 +:109BF0009E27BBD9F8769677D9A2AC7F37CFE7F30B +:109C00007C06CFFB79BE90E785DD984FB57FAEA28D +:109C10000E06A73EBED019CFA3F0E070EDCB77259E +:109C2000E419BE64080C0F635F35F02688FC917858 +:109C30007291DE86F0368DF3CAD877EE47317D3FDC +:109C4000A15139F749584439996ABEDFE7FC743BA2 +:109C5000E8B934DDDAA062BAA521807AEFA6068DD4 +:109C6000FB554AF0FBFA8620E6D7354CC0746D43AD +:109C700008BF37364CC7FC630DD598EF68988DE95F +:109C8000BE8630A67B1A1660BABBA10ED328D57744 +:109C900021DDD5A063BAB3A105D31D0D114CDBE6C0 +:109CA000953D5F04F35F40E73F007F183CDBEA0728 +:109CB00019546DE58BE953D22DE5EAE46CABDFA4D2 +:109CC000BCC092F7948EB2E45D456596FE1C399354 +:109CD0002CE54A6695252F7BAEB7E4AFE89865C9B9 +:109CE0008F8C7ED3D2DF88B61A4B797164A1A5BC64 +:109CF000B06585259FAFFF8BA57E5EFD1A4B799BD6 +:109D000033FCAC48F9D5B0BA0D967A43176CB3CA98 +:109D1000AB199997C5B7C8C77A96D99F91C8EFA5CF +:109D20005C120AA1DC62F2A511F016FC5EC3487455 +:109D3000AF00FEAB6B4F80DD612F6272A79F7D99F4 +:109D4000D09FE2D9F79A4EC7A9F49D08F498E88C01 +:109D5000044CED28DF3F2532BB79C3BDCCAE6EBDD0 +:109D600037B97D8D9C9DAEA3F5F3E4FEDB1E51E279 +:109D70007A906EB1535AEF15B0FE3FDABF519ED8BC +:109D80006F7C3C8A7315663D246AF845899E15B739 +:109D9000776D3DFEB960F71876AEE460DF2B4B823D +:109DA000279B28BCD7AA04FD866B3D5504F48A4F37 +:109DB000544637644F2EDAE346FDFEF333E915C807 +:109DC0007F5C563FAD6716FA3DD7660EAC972931DA +:109DD00009FD77524C205D54EE2872F5F47C4ABFA1 +:109DE000CA2B52703541F993D4BE27641BC2414A35 +:109DF000D06F9AE625F0BD29C370DD36BE8EC6CC85 +:109E00002AFCDEA40E3C2F3BCC0BE6C3E7658BB9E6 +:109E10003195624E9CEFC45806E627C4FC985E1547 +:109E20001B8A69456C08A6E363859896C7F2311DC5 +:109E300017BB02DB95C546623A36360EBF07636331 +:109E400031BD32F625FC3E263611D3D1B12FE3F7D2 +:109E5000D25825A657C4BE82DF47C5AEC37464EC92 +:109E600046FC5E12BB01D311B16F613A3C7633A65A +:109E7000C5B1B99816C5E6605A185B84ED0A6277D9 +:109E8000609A1FBB13BF6BB1E598E6C5EEC13437CE +:109E9000F65D4C87C51A31CD89ADC674686C23B6A2 +:109EA000CB8EADC77448EC7BF83D10DB8A6956EC6D +:109EB000014CFDB187B15C8DB5639A16FB217EF72D +:109EC000C51EC5D41B7B12BF7B628F63EA8EFD0C5F +:109ED000BFBB623FC1D4197B0EBF3B624730BDD4CC +:109EE0003E2939563E2E65BA2CF909A7D32DF851D3 +:109EF000F186958F97BF5260292F7BD1CAC783C740 +:109F0000CA2CF931872759EA971EACB2E447EDB75E +:109F1000F2F1923D563E3E7CA7958F176DB7F2F158 +:109F200082562B1FD79AAC7C3C7795958FE7DC65E2 +:109F3000E5E3D98BADFC3B30CFCABFB3C80EABFD58 +:109F40003D65B755AE4D7ECCD29FA7FC09ABBDC0D9 +:109F5000F98CABF4A796768EA2A349ED9A447F398B +:109F60008044A6F47D377105CDE72A469ACEF941A3 +:109F700006D01D4D3339DD0D02BAA369FA5716E339 +:109F800039D3A75F6DF95513ED2C7D28617E017DD6 +:109F90005B15F8BD9A87F03CFD22D07ACDC308FA54 +:109FA0000988FE6E2596E7B3FC0FA433953AF3DFDC +:109FB000B2727281953B59FEB1C67F5B0DE5E969CE +:109FC000A1EC20ED678F2D391F7F4262E76D17C42A +:109FD00050BB44D7FBE7CA9E95E047B33BC27B2505 +:109FE000FA7DB1239C07AEE90F6CE14764E08B2456 +:109FF000B40FBEA791D02312F26BAB5FB415146EF1 +:10A00000DACFC762F57E28CF98D9817691B1EE6616 +:10A01000EFC0F3894A4C2E35FB09DA8DFAA30ACA40 +:10A0200053FC33E4059583F7BB7D2128DFF5A8B207 +:10A03000DBCECB2D72A33E0BE586ADA37939B824D8 +:10A04000EDB09F5232BF680FE6D340E32F04FBBE52 +:10A050003757A6E9527B5733C8F5BFFABBDF122446 +:10A0600084C7AF003E2BAF0F63FD35EE9913603D03 +:10A07000141E27E03B85C7F3D2A0D4F02070B24075 +:10A08000E71F30B068BF60F13F9E13C2BF954C7EA2 +:10A09000CC403888703B20A9080F037EF4EFAE74E3 +:10A0A000C31FC3DAFD11C74DE84FE6E762BF95F85D +:10A0B000F85C1E1A789C21927032F81BE73EA423AC +:10A0C000F70BF9B39D8A98741C9B5C8DE7A9FDF88A +:10A0D0005E66825D9F1986B35E2A3FA9BC4C32AF93 +:10A0E000690AF74FC97997757E15E5FA3DD99FFB47 +:10A0F00085CEBBC0D083FA438D7D3A968BF951BC97 +:10A10000FD50D0EB283E3DF7A6FDE812CA07765178 +:10A110009E614FE20FD8D521E2F9FA503F45385AF7 +:10A120005ECFF5006A13A13E688C2B2FB6FA8F2202 +:10A13000360EC7C356380EA588FD536A72134F1EDC +:10A140009B1F3FB734FA69EF9BBF751EBBF52031EB +:10A15000DBDDF9ABA322E83572079DC798FEE31358 +:10A160007EBE60D091ECE17E13350FFB35C64D1CF1 +:10A17000874833F03C29157CFB8DF305CFEB2AE4AF +:10A18000E4E79D747F104E4529F43CE3BCCEC83F04 +:10A19000F7662D9E7F37476A50BF6B0EF073F6BF90 +:10A1A000D15EA11F921C4FF6727C7A889F8BECDDEA +:10A1B0005EE5C0769979967D2ABEEF265798E967C5 +:10A1C000E990EE6B63F5863F308F7FAFC1EF0FAD47 +:10A1D00062DFF3EEFDD8C9BE7FE88734AAB3EFDAB9 +:10A1E0006A99D717B13EA9A77FA673A0E16AB508FF +:10A1F000FAEEF0ED2404DFF2D45E01FCC89A4A4482 +:10A20000DD04D7ECED472BAFA3E5D991EA59D7C1CF +:10A21000797898048B35F8FEF2EA91B88FC401FB87 +:10A22000BD83AF3B2712DE3012EACDA6F548BCBC99 +:10A230008D8F3B2C12DE761DF8EF4A583F46F9F71A +:10A24000797B97511EB2B68FF0F2DC55A7BA46D093 +:10A2500076B991DE97AE857A1DD67A9B79BD51503D +:10A260000EF3085AC769E5F390F4DD04D0438A90F1 +:10A27000F4E9D08F6AED678381BF505E8EFFC6F22E +:10A28000870DBE90C0478C762D29F6DFE0273BC1B5 +:10A290004F3002FD5598E6B426F7BF96717E65E013 +:10A2A000572A3C270B448B7D47C22E6B7EB649FF55 +:10A2B000837C28DB5A3EA1C05A1E1C65CD97945959 +:10A2C000F3DA244BFED33E3F4BD409F460F8590C2B +:10A2D000DFCC0E95D149DC8FD7ED34DB2539BCDEE0 +:10A2E0008375CC1FD3E8E1F4C4FD322E4E97CD2503 +:10A2F000CC6E31D6FD24E75711EEF7D8D5D0C6FC89 +:10A300003063438E7CBA9F2DBF938203F9A11FE770 +:10A31000FBF1634E8F07B8FFE6877C5F1EE5FE9B6F +:10A3200047C07F03F40AFE1B3BEC3FF3DFB473FF2F +:10A33000CD43E0BFC17DADE67E98D958DE06FE9BD9 +:10A3400011E0275A80E916EEBFD9C4FD371BC17F43 +:10A350003302FC422D980EB231BB7CEBD45036F860 +:10A36000CBF64C4D6E170FB231BCC8074586A6B967 +:10A3700024F46517E02F456C3897293F167ACE4DA7 +:10A38000F323A20CAEE50743CF4179711BCB17F243 +:10A3900071409E807CA1FF60713639541B32E1EF21 +:10A3A000B817A3640EDDB7B7657E0EA051D5232B79 +:10A3B000EE2F8572D8A73785508F3C1EFA25CC8F9B +:10A3C0001F0E0B401E83EFEAD5155A4F5DDC1D8230 +:10A3D00036BE96CE2EB0B335BD0BDB6DAD0CA29F55 +:10A3E000CDD8273ABA051FE8DC902F0EE3FB4F26A5 +:10A3F0005BF12137B60BF5E1E6BA596988771A198E +:10A40000D05E2FD969D517866FB7DA49CD77CD1AC7 +:10A41000D0BF9CE82F53275BFD65CD2503B7F7958B +:10A420005BC7F79426B4F70CDCDE199B39A03D78A6 +:10A43000855893611B14CF17C6AEC1FA89FA9F0CD9 +:10A44000F16F54AF93A72821380796A7A8187A254B +:10A450004FD1781AE4DF433C5FCDF22A8B93A0FA08 +:10A46000623E8C43F727E1FC3B44E07C7AEB48C238 +:10A47000ED91DA35A11C9AFF6782F6C449F9CE2A1C +:10A480009DE677CC7088D295806F2CDE41E1FB95FC +:10A49000A144D723DD6E15C96E9ADF131998EFF525 +:10A4A0008B83F084D07F3374B15A260D40F7DB17CD +:10A4B0008BD3A349FABD86D315394612F5EA6B6CE6 +:10A4C000F4FBDAC5B354E0FFF24D41B41F88C6E691 +:10A4D0006FF0B98CF481F76F57C27C7353F87556DF +:10A4E000DB38BD9530FE68E07FC64A86E7A9FA5F93 +:10A4F000C7F959AC53B0F87F06DD545D69CB447B96 +:10A5000028E8013EFAB9C4FC688759FC9A414F8D8E +:10A51000252F23FF36C6CFCEE902B38D341F99C84D +:10A52000E22A287CD15E3C42F97829F27B02F55D73 +:10A530000B7A2A991F3D8AF10FAEBAA00E79C9C3D2 +:10A54000F005EC515E1FE7B3E1AE5921D8A7C61C58 +:10A5500012E420C6751A78D018103134E29312A68E +:10A56000F7CA2AE51330FF9132CE9FEA59172F1A06 +:10A57000F68B04E789BACEEC37167765C4E30D6D28 +:10A580001B83F8DFEC5D89E785FA58A60748A49B92 +:10A5900088F9381F5D2C077FBF1A04596FCBD4058B +:10A5A00033BE7D4D08DF0BFB1EC7AF4E8C4731E03D +:10A5B0009708FF6F71BE9A4792DB1F83B97D93A105 +:10A5C000745E077CB7E5518AE749E266FCBCDE0FA2 +:10A5D0003A66A5012919746B941F90341CC7C80FE3 +:10A5E0008D292CFEAFCB6AA7FCFFAEEF1FB459E359 +:10A5F000F3FE47DFFF1F7DFFFF117D9FCBC7A96BD8 +:10A6000060236C1E962F6F9EBA46C7F559ED7649AA +:10A610000E5AFC1FBD40FF26392F7BAC7AC9E5F3EB +:10A620000D19F527121C66E1BF19D903CB19C3CF49 +:10A63000F1E930439F0F215D90A21262D6D79A8034 +:10A64000CF5338EEA470E47187384E365F97ABA7CE +:10A650005A17317EC2CAB7772E38EA1C81FC5FC612 +:10A66000769E406708E4AD43EB46FE6BF069CA9FF7 +:10A67000C72A8380CF5720FF739544307E6D2DD736 +:10A680004313E10AFC305006E325F021A2A53BA0CC +:10A69000FCBB0C0764F0E3819FB27E603FCBE5C654 +:10A6A0007D187118B9F40FF8D04699CD8F1CB2C639 +:10A6B000B1537C7458E275CF3D8CF2D4E8C7D077A3 +:10A6C00012DB35A9556A32BEF8A610FEBA32009EDA +:10A6D00024FAB548021FA71C54007D6EE88CE9E8F7 +:10A6E000AFEAF36FC956BE2E078CB898FF5EFE5EC8 +:10A6F000A7FC9DF1EB5FD0FFB78B9FEF27D2716274 +:10A700003FA24EC49E24E3E7EB62C2B9B355EF17F4 +:10A71000648DDD13AAB39ED3C89EECE4E7093CCE5A +:10A72000B366421FFE7EE38F147FEF3861633C8C7B +:10A73000CB25C3BF7B07C47BD2FDA981F84F2ABFBD +:10A74000E7916A1F147E40448C2BFB80BCEC1B6796 +:10A75000DAA77D0AF3E79316DB29B86F64C435DE08 +:10A760001E6179633EB56DD6FC7C322B0BCE35E68F +:10A770006FB7118863BC83C8A77A8CF9533DE7FB98 +:10A780000A8BD3AE2575CDC0CFD672FF7D8D4A64BE +:10A7900088435CF2CC8315606F1E50981EF52E85A1 +:10A7A000BF668A575BE8892A703EF1CEC1715FFFB0 +:10A7B0001281F6D1E66C8847A47A2DD8BD89709FA6 +:10A7C000DB629DDFA5E69F385FE37E52AA79C81D54 +:10A7D0004228991DF133C51A3777A97B536F8391AE +:10A7E0008CE720D67B53976A775AD148B2FB5697AD +:10A7F0006A77FEEF1CEF428AF196387A14E003CBB9 +:10A80000E4F074A1201EF7A5D8AA43432928E44305 +:10A8100063BBC0176EAAD77299F54E80017219F505 +:10A82000A68B03F47781D3F1AFF63FAC007D7EF0C9 +:10A83000D8C99970EEB3E8671271C0BAF67B4917B0 +:10A84000B34F1490630B0F4AE88F237257C58DA640 +:10A85000385A8CB8A5EB5FF4632FC6692C7CC21EF6 +:10A860009D41DB2F7CFA9D3184C2E1C29ADEE34335 +:10A87000C1CE784C6071897ACF981BE9F78532B9DF +:10A88000AD3A091FF4D8199EBFFF13F76CC023A17E +:10A89000E3C8ADD86FE7376C76D3B9A064B7E1B839 +:10A8A000B45E889D6709D16281CDCF7CDFC2880705 +:10A8B0007DFF5181CDEF902DEA84F975B42B615A5B +:10A8C0006F59C75F106FBFFCE3033E80C3B2439272 +:10A8D00085BF2CEB90BAEC63303D69C7FB34218F08 +:10A8E00040F9C8526431343DB804E3C797766EFC32 +:10A8F0008BE483F656FAA1700976015C5F9582338A +:10A9000020FFE4233EB01BDFEDDEEB03B8D27EE791 +:10A910002814AFAEF9D8446784F51F4BEFDF1FD57D +:10A920007414C0AF659DEBD97809F4F92EFC634827 +:10A930007FB930CE6E950B9F90172BD05EEFC84835 +:10A940001A6FDF271738BD2E3AF0C92E9D8EFBFEF9 +:10A9500013EFEDD2E9FC17FFC747BBEE01BDECE7F3 +:10A960004E15F8CCB2C77EE72326B8CFB433BFC1AB +:10A9700085471FD9B783D2CB853FD8D1AEBDF0EC88 +:10A98000D95C8DAEFBC2E39F6569B4FE5DCF4E1D01 +:10A990000C70B8EBA92F0F1EC84F00F81AB59BF723 +:10A9A000358AFD6B870416DC7F98A709FBF3DCC1B1 +:10A9B000E772619E1FBC66C7FB8CCBE8B7FA32D842 +:10A9C000AF25C8F721BF8AC279E9FE757F91C624F9 +:10A9D00083B73E54C4C3454A3601D8EF1BBF7675D2 +:10A9E00039A4B6A006FD915EE4DB89ED96BD42F781 +:10A9F000F5CAD4FBF809F99B02F05FB67F3D1B371F +:10AA0000611F3F807F4CECBF8F8BFBEDE3E287D073 +:10AA1000E638989134FECAD8C7254FFDF3807A8076 +:10AA2000C10F2E05DF053C8E70A23DB4CA0E74F531 +:10AA3000845B0FB0FD8DCEA065170E7C924B287EF7 +:10AA40009CB3F5DE0A7CB2F759BBBA9B7E5FF8EC8B +:10AA5000AB4867179E7A49D1904F128F40F5840B0F +:10AA6000A4EFAF1BF486A5FCCC79D91E6F97DD1738 +:10AA7000DFA7A5D11BA66B3EFC7E12BF4719FE2F98 +:10AA80008D1EB94948B26F4FDB0B183F8F0E42B88D +:10AA90002C21DD8A5A6ADD4F6102ECE3C9698077B7 +:10AAA000A9F6D158BF0AEBBFCAB49F7B18DD26D6E2 +:10AAB0005F4AE913FC887DFB1A155E2549E8F442DC +:10AAC000BB5D8678E10BB64BDC03FE82FA5FA73DE7 +:10AAD000857DCFE170293ABFD4FABE28FC76817318 +:10AAE0007B507F38BEFFB7E4FCFF45CE379692F02F +:10AAF000F46CA9BFFC9248481F9A1F9F6F73A784EC +:10AB00007CFDFD0E290A4D13F9C4D2147EA7D7EDA2 +:10AB10004C1F597AE8C818E067EF1FFD09C74B863C +:10AB2000F74BF79F54742E0FA2667990C23F799A23 +:10AB3000CF7BD9E1E4FD2DDBFF97A4FDBD2B87BEC4 +:10AB400001F37FB7DB4674DAC5BB9D52523FEC6F11 +:10AB5000EC364B5C61B3B7E2B534DA4EF2B9341877 +:10AB6000BA714DE8551DF492976D78DE41E4E039F5 +:10AB70003BF813BD2E6D038557A36F3EFA2B8DFE58 +:10AB80009A12E02407AA75B04BE5CCEA72A62347D7 +:10AB90002D76B14D152DF3A6723607E4D05B63CF49 +:10ABA000DA609D6F27E8836FCBA47930EDEF6D5DA0 +:10ABB00008AED692E1B7B5FFF02A896866F967EF6B +:10ABC0007D0BE6437EE12410A722FDDCA9033F595B +:10ABD000B6CB1985B880E79EFA741FC0EDC24376E4 +:10ABE0001E27C0E2CE6B55D6C7D9A73EDDF5EFB420 +:10ABF000FC2C34A6E3D7EEA2F5410FDFEFC6E0FF51 +:10AC00003F3F91368650FE5CFB8B7B66027FA90539 +:10AC10009E4AEBD7FE7830EA756706B1FC9903C30C +:10AC2000A2B02F8B9F7C7629C891453F7213701973 +:10AC30003CF7D4ABB742FEC22FBC182779E11767A7 +:10AC4000AF013AA0FAB36696E37798DF2BA0FD2E0A +:10AC5000823C2B172E9AE26F16414AF9C6A243692D +:10AC6000780FC8540FDB2DB3F7AE0CA23F59CF16A7 +:10AC7000D1C6E9CA063A5CD4611D6FA483F949972D +:10AC800029BDF359FD4836A3D76E6C57E1E078CA69 +:10AC9000CB13DB1BF5CB1D05967A46FBA5765297A9 +:10ACA0000CFF2B79BF8B3A3E1F61ED8FE16BFF717B +:10ACB000D8F7EF08EC9E0A79DC89E76D8B95AEE159 +:10ACC000E9945E9F56C802A0DBC5BEAEE17E3ADEC7 +:10ACD000CF389F5CECA279FA3D9BCF03EA439E38C4 +:10ACE0007A7E04FBBBE41927017C5FF20B2F9ECF19 +:10ACF0002C79FAD3333FA0DFDF7FCA8D7E9325BF47 +:10AD0000B81BF77B89BDEB56F0FBF53E6E477FF332 +:10AD1000FB8F3F9F0B7AC8FBB6AEDCF401ECF3254A +:10AD20009D76EE8CB0AE83DA052575743EFA561624 +:10AD3000C7564F5CC1D5109F028E03C0E3379C2CD1 +:10AD4000DE8A9FEFAEE0FEA00FE7696938FF52E6AA +:10AD5000DF5AC1FD072BBEAA0DF69BE60171A66462 +:10AD60001C21772B752380CF4AB1AF108DE6E558B3 +:10AD700021A6463D490DE2F98394C9CECF6D994194 +:10AD8000525B0AED585C12F15CDF4767FF8B6EF196 +:10AD90008A07B4C1D0DF4207D3A7DB9CA1BB1D68E3 +:10ADA000CF78F07E29AE933204FD29B6AE4F05B6BA +:10ADB000AEC4F97E6AD3EDC0CFE3E7DEEC9CA55EBE +:10ADC000D65E85F34C7282F3A57EEB6774F6A19A8A +:10ADD0008E7466AC6363838AFC647D4300D3750D17 +:10ADE0002544C3FB0141CC4B1C1EF6529D4870DF2D +:10ADF000566373B57BAA43707E017DE2B986278CCA +:10AE0000F8650FD4A1EDEFF010B44F258F4E6A3DD9 +:10AE1000E80F4338C1B90CC049E179B96D06C29554 +:10AE2000B6C7EF2B9DE15D001747CE280B9F52322E +:10AE3000CB2CF97E7033F0E2C07F37FC08C26B7D0B +:10AE4000830353B85F017083FB1590FFBF00BFE31E +:10AE50008EF1ECBE8366A21FB8EFA059E82905FC6D +:10AE60001EA0F0CB8CD355221CEA797C9B414FA9C4 +:10AE7000E817EEA7C0E5836D0D6D981ADFD353C8B0 +:10AE8000F5E14E81C7058457DBB87F1CF7215327B6 +:10AE900039267F1209E8782F0AEF5743B987F9114D +:10AEA0008DFD9554F98C95FF69AFC27AEE7EC1266F +:10AEB00002BF92EA1F26EF6498E87846B5534338FC +:10AEC00007D17FDBC8E5EBDABEFDB4D2C7C6060DFD +:10AED000D34D9C4EB6703AD90AFB0EFEB9A0887BC2 +:10AEE000DA3A9DA0FCBC8FE6997DDF45CC7E6D7F74 +:10AEF000B0B3CB46F71F7992866917F2AFD7ECD182 +:10AF000062DACE5D4A42802FFED7BE1BC5B592CE17 +:10AF100000F843FD1C7EE47081FF66F69E828DC9B9 +:10AF20002922B1346203FB2911BE8DC1A30EB0BB2F +:10AF300053CD272BA8DB73E978596FD8917F67DE53 +:10AF4000D2F95A0D5D87A7D58DF6645690E1A327F7 +:10AF500018166A4DFB979542EFDBE7BC2ED349E903 +:10AF60007810C4F3D2745B5BA113E0BBD1D6190097 +:10AF70003EB8D1CFE48C369B8E7695A93DE78FBE47 +:10AF8000722BFD1BFC589D5C66C16383DFA64FB12D +:10AF9000E2BBC16FCF3B983ED7E6AC1EEE8478DEB5 +:10AFA000D84EA4C744FC6FB429BA40F59446D025C6 +:10AFB00041BF3B29B0B894FE7C00E3563EECC9DFAC +:10AFC0000DEF0EACE1F1D43AA517943BDCFF699C80 +:10AFD000CB1F20D52DF00E4C0BC52302EFD550FC16 +:10AFE000017AD84CF107D208C51F4627133035F037 +:10AFF0007326384FCCE7BF45C745769F4304994336 +:10B00000646A077AC0CF7464A203F442D9C6E259D5 +:10B010007ABD6227C4B3ACF5CC7284C0AFE32FC74E +:10B020007DFFABB7266FA07315785104F046F50489 +:10B03000C9A9D2F8BD5F492D23604F1EF074E3F912 +:10B04000DED54ED132AF3667F846A7C9CF3F1A4694 +:10B05000E7FBF64FB8FEE4F7876F73723F658E4EDD +:10B060008A4CF46DC499124D2725263A5F533C8DC6 +:10B07000C039687FFA4EC1C7F6FED7F0B1C6BC280A +:10B08000EE9B2D916F6452FEEEC154175538DF3B95 +:10B09000D4F42D3FE2D95D000FE2D9DDA7BFFC5308 +:10B0A00041FF7926F2ADB83CD2D05F45E5D1FD1322 +:10B0B000800FA6904747DE1CF1358596BFF3BC2470 +:10B0C00098FD750B62EB511ED4C626128DCEB7A625 +:10B0D000ED7B98CE6F6B47BC3F175DEBC3389A167C +:10B0E00066CF9D8BDAA2523EE2ED4509FCFA84F56B +:10B0F0007F6E6723D623E07D318D7B6E276B4FCA31 +:10B1000035D4A73FE46BACD9620FC139CDB936DA7B +:10B110006E0078D6803194443FC5F704E0EE00A974 +:10B120001B017CCEA0F7BB15CA97000E6FD993FA0E +:10B13000D9573AA7EE00BA5EE90CB533B8A75FD687 +:10B14000BB16EF8854EF4578877D3758FCACCC8F21 +:10B15000F90ED78B892345B98FB75793972F697D00 +:10B16000EFF8BD34D75C1AAE2626FB5A22CCBE5E61 +:10B170007AA892BF2FC2E693043F993EDB6A473E0E +:10B18000348FFB830C7C8DE34BD8C7EF975AF0E9E3 +:10B190008ED856DC6F61E3E8FB2752F87D44F10856 +:10B1A000FC72C2C6AB07031DADDEF0A52DB7D0FE05 +:10B1B0003F7E51C2EF0B624EAC7FFEDEE0FDB780FA +:10B1C000BEFE6F36027CE4E31353F13CF6BCCDEADD +:10B1D0004758E462F2FA1CA7E3F9B18D16FD787EB8 +:10B1E000CB5C05FC8FF3639BF1FB7C3894C17B2027 +:10B1F0007F3E5629C3790DC1F3D173CEF7A7AC01B9 +:10B20000381C2E433F56ED267BD27B29E79C9AE5DE +:10B21000DCB9B6A715FB25543FCACCE2FD99F84727 +:10B220006D0C2EB1C0FEE804EE2DCCE77CA46F7E41 +:10B230003B6D163E72DE99DC4F12E37AC9FCD8975B +:10B24000908EFAAFEF1A465FC6B83D8CEEE2EBB9CE +:10B250007F62B2F5C4D73119EB9FF7271F3F8FC329 +:10B26000F94CC30212A27CA8C64EEB7960FC3B9B52 +:10B2700027809DBDD39F2E98D655DBB688844CEB96 +:10B28000AADD3947A931F51BDF07E72FCDFB90B7C2 +:10B29000419EBAC60372BBDAEDA270AED978F598BA +:10B2A00030DAD98C9FBC630BE6025F3DDB766752D8 +:10B2B000FACE736916B950DBC6F787EABDE5A6FD7D +:10B2C00031F625B1FD99376BFF7A2FF8011E604AE0 +:10B2D0004D2A78F5DBB7FCE4709BE862787986CA82 +:10B2E000D930C24D7BFA35C0EB4D6E8CF74C0DBF9B +:10B2F0002B487820F8A5D05FA9BE53E61A0FE312B9 +:10B3000084436D1BC3834BC12D3E2EC783CAE4EB20 +:10B31000A9EDC3837AA253823DA55C0A0FEE21BA40 +:10B32000638075F4E1C1680B1ED4BA8AA7023D9E02 +:10B33000033D6544FFFD3FA5E8BE49700EB441C220 +:10B3400073A6532E3DEB9B2C3F16F8F3295F64E662 +:10B35000A4F278FE8EBDC5BE39A671CFB6DCE94B2E +:10B36000E667AD4D853F453A29ADF83F873FEFA4ED +:10B37000B8C7B5D259B908F6934492FB738DD4E09F +:10B38000DF529AA7CFEE04797ACA53F0D7282D3D21 +:10B39000E40CAF047ABA5BD4C6CC11E2F6673FFD89 +:10B3A000B361FAD5A78BC15F587DF5691BEA43D815 +:10B3B0001F01BD329FC745A07F6308CA83C4F3D273 +:10B3C0001FB8F2939E8FAE6DA81B07FD12874E54D7 +:10B3D000739C1C617AD4FF86F1F3E3EB516C613509 +:10B3E00008F6A540AA01CF6D72B805EE03DB0299FD +:10B3F0006375135C1F7031FF97F3D8B1967CDADE6A +:10B40000F9A7175582F7CC74F4AF3972E40FCDFE6B +:10B41000695B268B5F2445A6EF0510874CF3163B2E +:10B420009FCE77003BF567028383EEB5F37B75BA59 +:10B430000472EF662731FE50FFFE8311072237B1F9 +:10B4400072BF51DCC4CAB9FF72590DF34F26EEEB3F +:10B45000CD87D775833E73F3E12173C18F75B367D1 +:10B46000C49FE07CE167E0C3077CF733B99CD8EE6A +:10B4700030A7D36FB58BBA8DEECB315BEF5137CCA4 +:10B48000F73BEC1DC76FFEEE98CD4DD3D75F396506 +:10B4900083773B6E83001DBAAE39445398121CC5A6 +:10B4A000F67349A797E53B07CDF29AFBA3A62AF4CA +:10B4B000B79C9DF37EF377AF4C05F14FFB5B0BE937 +:10B4C0006D2F1205FA9F73506B66D7F8787F8769E6 +:10B4D0007F62BCBF381C1566E7C80E844B1C4E0E3D +:10B4E000849B012778E606CBE370467DC380731FFB +:10B4F000DCD2665F4FC6A4A6979B3DC3FF44C6C47B +:10B50000E79508E78FA188D2DB7157E88F403707AE +:10B510005CA137205DECE8CD950BF01E630FE4973E +:10B520004AE1BC2C8A671F0C0B8F1804715CDDC9C3 +:10B53000CF5713E9F42DA01788FFE67198B7F2F5FD +:10B540003DF7DDB35E8CB37CEAD55C4897483D9B04 +:10B55000BE01F4F66B09F5EF0F0F8E18302EED2DAE +:10B56000EEEFF8D425F2F303B6BEDBB81E77DB416D +:10B570007714DEE3BCAD5EB2E8BFB7D5B3380E22B8 +:10B58000778FB9C9A24736A5EC07ECCEC47E8CF5FF +:10B590001DCDCDBE02ECC387C62B1AF81F8EBCF89A +:10B5A000E11F6A69DE35CC81E7B29BFC1C7F2B452D +:10B5B000DCF787FC21F768F03B6D480FEA749D1BB0 +:10B5C0007E493A450A9FA3235746ABE8789BAF16BE +:10B5D000D167B525F670A40ADA95B2778F54AE8F8D +:10B5E0006EE93ED506F878F6353BFAFBD3BD12CEB0 +:10B5F0006383AD3A17F4F73FB52B49DFD97378650C +:10B60000ACD72EF460BCDB5C127100DF38D83D6B28 +:10B6100030CCC717242AA0FFD99D92C8F464C3CFA9 +:10B62000D125333FBB2EB37C88A7AAD3FCDEDDFA3D +:10B63000E953309E625EEB4B184FEC2B4F7ECF6987 +:10B64000829BDDD7F576A7635CB4778A886F24790F +:10B6500083BD02B4CBEBAE52B07D4418B07DDE2A80 +:10B66000F53A802BB407FE9F7799ED836E05E1B024 +:10B6700095DBC9EDB660F314DA4FFB26BF00FB6122 +:10B68000D4BBCECDF499B3530CFF4D04FD37B9456F +:10B69000AA13DE5BC90D2171136F79C401F0DA0DB5 +:10B6A000F5987F13E1D03EF2E92E383FDE00B2017B +:10B6B000F6D9C6F069C32601FD99147ED9202FFE64 +:10B6C000749FFD2BB08EBC164105DB9BA649E7BDE0 +:10B6D000DAE360F2A6F57EB403C13D0AFDE6EEFCB6 +:10B6E0002DCECB9B62BD3FF430FCF8D325F023C7B1 +:10B6F000CDFC36B9F5DDDC4EEAC2F716230027C8CB +:10B7000087CAD93B87724833C7A1C4E987D9617416 +:10B710009D18075A334189821F406C69C77785E7B6 +:10B7200046ECE45ABABE56A13B04F4A28F17F97B4B +:10B730005EA1B7004E9BB70EC678B675622817FD9E +:10B740003BFFAAE0F9D8D1D0870FC0BBBCBB2628ED +:10B7500048174743EC9EEC43AB0ADAC10EF7D657C5 +:10B76000E17BC1515541CED2584E5E8078D2C6554C +:10B77000A22AD0FA916AE33E82EA02BC182B7D74B9 +:10B780005D099C9F0D11C19744CE0AEC9D91B5AB0C +:10B79000AA54D8D7B56AA660B65B748E077FF457F3 +:10B7A000EB6EBABEC0BDDB548801DF12CBB802FC21 +:10B7B000857A8BA2B1778BD9FB24197C5F32BAC50D +:10B7C000AEF93ECC7B16501379CB64E6A7FCDEF5D0 +:10B7D00061E65F8433C90AF42FF2BF00EE6B26CF17 +:10B7E0006D18E5C2CCF635F3B13EF49345FBC9289C +:10B7F00017BB2A68BFBBFDA15D284FA63A104E4477 +:10B80000EE69033845A76607E1DDE46D1387BF04E1 +:10B810004F54659CE89D0572343ACCF57A3BF0A90B +:10B82000B58A06749EB1EACC2DF0DD1FFCFE9D901A +:10B830006634FDFE1E9007FE9EBF34E0F7E98AC520 +:10B84000BF97F1C6F9CFA13CA35AB1F8093FF3570E +:10B850003FECA6F0D9551A89D468EC7B282BBE8E14 +:10B8600003ABBBA7C3FBD9676F1083BB7939AE6B42 +:10B87000BB1ADDC0E0560E72CD80DB3A51EB84F787 +:10B880009DF5990EC48F22D28DFC6A089C2217C6A2 +:10B89000F725E38DF5CB214E22713ECFB885BE77DB +:10B8A00061E09D4A8CD7A7724C1932C50578FD78A6 +:10B8B000597700F4F84DFEE4F1099F7A587B7B8AB2 +:10B8C000FBEE1F79183E004B6C2BC334341A520F19 +:10B8D000D1D320CD7184203EF67151FB23E2F9369D +:10B8E0004983FD81FA36BA7F475E7817FD83472288 +:10B8F000BFC5F4654F097BD78F125C16BCB35B7E66 +:10B900000ACF4736AB0C476A5B18BFA80DF438E086 +:10B91000BCA2B694A8BB39BEE9069CC1DFC5E555FB +:10B92000CD4D0CAE99A504CF5BC12706EF9E6541B6 +:10B930003D0ABFCC96D5CB711F49B75E48EB6D86EB +:10B940007E617F9AD8FD14427A1C48BF1109CF1B33 +:10B9500029BDFF06CE136B5A07E3793B5C7787FE60 +:10B96000D2F9B8E9BCBF76DA0FF8FFCEB648643733 +:10B97000F2B76E78639868AB282E237EF65696D081 +:10B980007EB57255DD60E081C1C72869CCA3F202A3 +:10B99000E0364FD79703FE9D72A82FC03CDCDBED4D +:10B9A0001AAC7FDEF667EE06BDC51DE86901FE50E4 +:10B9B0003B81CD37BD957E47FD46FB0DD4AF6DB5C0 +:10B9C0006B6C3C0EBF728E671C0EB7F379DFBE93B3 +:10B9D000CDDB352C1A01FCAC5D45E10A656186F7CB +:10B9E000E0D2BC28225D9D80F57BF52CEC77D0EC75 +:10B9F00004BA48C03F635D357C5D35ABD8BA08A753 +:10BA0000273AAD2EE8B7A69CAD731E61ED45F84E02 +:10BA1000FBBF9DAFA7467F1AD3DB5BEC96FE779505 +:10BA2000ECE986F9E4972A9A807066EF6DE6F27584 +:10BA3000E536B1F1724B9F4678917AD37CD12F6A6B +:10BA4000CA53BA3AFB3C252C78CC22D781C874EA79 +:10BA5000BB0A9EA3146DB7AEEBECFA110FB782FFD1 +:10BA6000F33E05CF2B1E17836FE5A11DAA688CFF3F +:10BA7000047F3B03F8F4ED4D78BFEA402583FFD9FE +:10BA8000AF9228E043F189EA748077F189304FEB77 +:10BA9000F01C9B0244E8E37B747ED4746A11805FDF +:10BAA000C60A7FB800F800DD67D0078799E74DE741 +:10BAB00097D192550571489913D2AB147C4238A1A5 +:10BAC000FCC48E59F01E6EE6B11D77C238438869FA +:10BAD0003DB4FC4A6F21BB9F758C9642BDFA33F78B +:10BAE000C27EB4F277ED8B6166E9981E833483D20F +:10BAF000F7C67498A74CA694C5F9C1DEFB2AC60206 +:10BB00005FC1BB2565987691B2FE7CC3547F24AF9C +:10BB1000AF0B49EA5578358B5DBEF7BE6923C17E10 +:10BB2000DF0C7A621ABC0BA87E04F1317A5044B85B +:10BB30006FB675394A33E1DD719180FEB2A5E4F745 +:10BB400022D0DDE6832408F89151FD1F76F33ED61E +:10BB500079FCB86E59211B81FE8F8E3C331DF6296E +:10BB60007A84EA9DB47ED5AF3C3BE03E71FB1F5822 +:10BB7000FC49FBF37528BF57E62A49DF7D2697D09D +:10BB80001313EBA717CF423F5EDEF6ADF8BE6CEDA8 +:10BB90007439782DAD9DB9BDB212F418AD9A62D743 +:10BBA000603AEF9D635703116A33D87995369D7DCE +:10BBB000D7A6B07463C3827160B7473A6467119DBA +:10BBC000EFA8F5ECFDBE8DA51F3AC2542F2DAF7C1A +:10BBD000C2F155FAFD74399582F4FBE9C91F3AE1C7 +:10BBE0007CE6A1F2AA0C80E7C116AB5E47E0713695 +:10BBF0006A078DB647425E3AAFD6DF1184A764EF7D +:10BC00006AABA179E9190F6838FDEC9BF5ADEDB38E +:10BC1000014FE795607872FF7DE7F2626E7DEFF489 +:10BC200002A05B9DB073D4C8FDC8946FE72C235F5E +:10BC3000EF46A6E3DDCEEC93881C3A0E7C39521A0F +:10BC400056A089C1CF5A8B6BF6013F53B8DE4FEA3D +:10BC500016E0FD48A47F09F4A1DECA6476D3B7DDFF +:10BC60002EC4ABB33B6F7C15FCD3F3EA99BE9FB7F0 +:10BC7000F32301F783EA7D4368FF79E5F8E425992A +:10BC8000B72AE2180DFB5324124D83F97412B01336 +:10BC90002254FE98E160F4FBF7B6DFE1B1E33ABE6F +:10BCA0000DC6F3F8F87A3C7C3DB9C1DECA64F1B345 +:10BCB000DFE2E37EE7C18F8E4C04F8AF6226525E6E +:10BCC000E4A4E030CD234FBFBC79DC02FDD1793C48 +:10BCD000E961F7A7BDE53D78EF2891BF833A0F747E +:10BCE000BBCB7D612CB3EFADFCB45F9EE355E2F7B7 +:10BCF000DC047E35DADE793DEEEF01F6BE3A2194C2 +:10BD00006E1DF8ACA8C6DE9D8D1AEFA0D741BD51BF +:10BD10005E8F0A78D03AF2F765009F4D5C5FB8BD40 +:10BD200094A0BD7A7B4E37EA0B739BB8BE20079B6D +:10BD300081C9BA77FAC90693FE802E2C702D357111 +:10BD40007DC190FF5C6ED706BA5B50AE827E60927A +:10BD5000AB353A93AB790126D76B5BE8381A47E6E7 +:10BD60000AB35EC2E4B8B69DEB0F5C0E67F07133A8 +:10BD70005B98BCCA003DC207E1073ACA653CCBCB21 +:10BD80008AEB2D834A99BCCC687D1CE5DA1FC0E99B +:10BD90003208F8069397C35E7A45073005E8E73620 +:10BDA000CAA78FF1F2804AF5B3F4B87EB64EE4E745 +:10BDB0004C84E987185B4FE77998D737BEEFE1F3FA +:10BDC0007BFC58FA5780BFEE8D148C954C748B5EBB +:10BDD0004F9ACF2D67E7F4B9F5EC9CDA1B9CBF4F67 +:10BDE000329D3F6CF5707BD3C0ABFAAE00F48BF79D +:10BDF0001D918FB3F7AAD6537D09FD4FDCBE9AEB98 +:10BE0000E67E0D8E3FA9E489C187BC24E42BA5F012 +:10BE10003D1DDD87FC5AA7F612ACED74A4317B21E1 +:10BE2000D07BE4867298FFE6897FC5B88BBC14F698 +:10BE3000A2C3EB30E0F085F8BA77FA2BCC0EED1602 +:10BE400093DE9399CAFD0F9D3271033C9D11F6DE7E +:10BE5000A1738292B4FE042FE39B195E768F68F380 +:10BE6000C47D78BF31A57C96892E2591A786BC6DAF +:10BE7000857D9E44C8CCD65B9B75B4D3A3D512F206 +:10BE800057760F30C27F77462F51D06FD86A8B38E4 +:10BE9000603FB694F37D551DED703FFD0BEF0B85B4 +:10BEA00007ECF3FA901815F2619FA3EA68E6D7C190 +:10BEB000DFED394BED77F339C52CAFC8E1A489101C +:10BEC0009F98D7C2F06BF34405E7B1616C56BB9401 +:10BED0006FE6BF02E79F0C4E1B261E47FCBADCF93B +:10BEE000CDAFBF67D269D339E299071E290038C7A1 +:10BEF000DF6F090D787F617EFD4B93F624391FE8D3 +:10BF00002B073BCA037660F49BE67396855E6667F3 +:10BF10002DF11AEF3333FE06FCD586C645341BFCE3 +:10BF20004B07AE8EFAD07FBF989DD7DEC1CF6BDFB7 +:10BF3000DD7323BEBF301AEED426D9F7F30DD6F742 +:10BF400017CEEF7D249BF935A216FDEA8E7D3F19B1 +:10BF5000C5DE9FD1F9EF72102DB382BDA38D72FAA9 +:10BF60007850B74BF1F7D114F85D0CF0B703051713 +:10BF7000C22BA09D987A807E0BE1F7857A315541DE +:10BF80001C15829D14C4349354639A45EA300D9075 +:10BF900008A6D9A413D31CB0730B412EF462AA11C6 +:10BFA000552426BE5F4082982F22D598CAB06F19BB +:10BFB000F17309B9C381F117707E01746F9C531836 +:10BFC000E7FB377B6B1EF02639AFB8C71BDAC1BE63 +:10BFD0007721DF9ECB59F8891F8DEA84FB3D2B36F4 +:10BFE000B1FB25065F47BB86F6FFC3742607F46DD9 +:10BFF00002F2AF35EE99D7201C5B6DEF9BCF1B880B +:10C00000C35104BF3F63F43B97FB17E672F907EE99 +:10C010006D76FF2E88F77FE6829FC1544EFACAD90B +:10C02000FD6BA31FD13D79F840E77BA6F6188F5C26 +:10C0300093A0FF5F526E27E4E725B6FF1B9D505685 +:10C04000DC0FF7C36BB45C76CEC4E43645240DDB5D +:10C05000B5D84FA21D16991A32C3E5258EFF863C2E +:10C060009997E0D74F4CE7C99C2E12FAA192CF0FB7 +:10C07000F766F00D14135D1BEFE81ABFD375472860 +:10C08000AC0C61CD02B08F2A9F7784ECAC1A42D3FE +:10C09000739037F9F37FE70BBFED35D1891AAA13F7 +:10C0A000CDEF34CDE77438556AAD04FE76364C8258 +:10C0B000603FDC41EA36833E465E9190BFC13D6CF5 +:10C0C000F8FDA06170A0918E795DA1E9070DEC5E8D +:10C0D000CE1978476904BC7FCDDE517A0FDE4DA2C0 +:10C0E000E9E8B6BB67021EBC0BEF27C1FD5B4EFF44 +:10C0F000C6B8A33BDD7340EE8FEEBCBA16EA8DEEF8 +:10C10000B0E3EF45951C5C5F0D7E2178CFC545C738 +:10C11000C9A1E339D2818F1094B7EFB5BAA26BE809 +:10C120003CDF6B93902F7F522AE2BB23F06CA6C4B6 +:10C13000E797960EFDFCFBADA087BCCBF988F17E9E +:10C14000E47B951ADAC7BF3CB04E807B09EFCDD1B6 +:10C1500070DDEF0DE9CC4D07B9E463F1E545FBED8A +:10C160005D05741E0B1FFB43410DF0BF82C8C26406 +:10C17000E7CCB93E264FDE7B8A603CDC7B4EFEFB83 +:10C18000488E4E9FD9CF1AF00916BEF59E97FFCE66 +:10C1900052CE25EAF1F872E2E9F431BAEFF4C1794E +:10C1A000D4FDEE1FE1FDB5334FB1738A5F3E509B66 +:10C1B0000BFEA8229FC6CEBD0F3C8971E3B00EB026 +:10C1C000A3E9FC3498DFFDEEB7DE05FF036D87F7CA +:10C1D000338C76670ED4B2FA6DB4BE0FE14E7C6537 +:10C1E000800F0CEE643FE31386FEB8289A85BFDF0C +:10C1F000102F17B11CA6E8A4F01FBDFF063CD7AA5C +:10C20000F0A5337C563B47CDC2F94772611D07AE9E +:10C210000EE7821FEF8CF17B52722417E070B33768 +:10C220005CE133ADFFFCC96790BF9788756FDF0B8A +:10C2300078F904FB3D93BBDFD82A9AF9C7541FD382 +:10C240007BEE772FF5C179D499BE7775222CDEE786 +:10C25000307BD77511A7BD33EDD47EA2F038BFFF78 +:10C260007B587EA6EFDD9B4E8C273BBFFFB9744801 +:10C270006B783C3F89DE88F445E1D2E24822AFFA90 +:10C28000EE4545D97DB70B027FCFF441036E75CAE9 +:10C290002CCB7915A3EF9C9DF9C7505F8E26BF2745 +:10C2A0009728EF13DFA7BDD43DE0539C4E4FF377A3 +:10C2B0004DEEF1866B7C49E448CDC625B900E71AFE +:10C2C000B85387710E95D782BD8DF74DD8FBB45DFD +:10C2D0000827E3FD59FDAA6B21CEF18C9FE5BFBB7A +:10C2E000B97A9DCEE1C8EA4F63EDF359F97D504E1E +:10C2F000EBFFDE5BBD9C8D4F04F6FB48363FFCCE6A +:10C3000085C1FF52AFDFFA3B171DC093C7637FF7AC +:10C31000607F32ED6FF43FDE9FC16FFEE17E1CFF58 +:10C32000B5FD187C18E81242F6483038EABF027EA4 +:10C330007F6F7B323BCFC2CF3F7DA0B019CE813E15 +:10C3400009B077A2ECADAB09C8A5DBB76F4DFA3BDE +:10C35000797D791E4FA214523A33D1F3F39CAF3E4C +:10C36000EF8B9F07C0F9CC7042F87B175455C9C2B8 +:10C37000901BB4FF46F077E34B4804F5AB51A41390 +:10C38000D352D28DE918D28B291E931682AB2F88F7 +:10C39000E99F2B7B2A60F18B1DE1872054D7EE08A3 +:10C3A0001F077CFA6058F8117807788D7BE924988C +:10C3B000FFAF7DAAF17BA224E1F7D9E2BF2BA281D6 +:10C3C0005E332330905E4354F9FDBEF88D027C4706 +:10C3D000F8651FAE2FD5EFCD25FC8E25BF476CC06D +:10C3E0006109E9C438885FEE5CF102BCEBB370BF51 +:10C3F00017E5C1F09D4DF87B620B497716DC2F1DC8 +:10C40000CEDF93206DEC1D0FE39D88916D76CB3BC5 +:10C41000164B127ECF6811FFFDB14589BFEFC5EF06 +:10C420006F6E840F49E20812EF7FF6FA52BCE75AAA +:10C430009AFC776512EF7FEEEF1431BE6705C40BEF +:10C440000971BE37724F9DDD8A5F9DD71499DE83D7 +:10C450006A1482CC9EF6BA427B85FEE38C53197E29 +:10C460001D1084A47164DF4C33EC9B26723DEDA754 +:10C4700071B1AC82BDD91875E13968A3CAECC2A10B +:10C48000DE2A07D8E9C42FAA703F659A3419E3CB96 +:10C490009525F23838F73CB67B6137DC5F680CC80D +:10C4A000E8A71DEA67E7A0648888EF0334A94FF87E +:10C4B000E7C23E79D839E33095E0EFA11E695F29E4 +:10C4C00042BE919A2D83611C21DC8DF76E86C88453 +:10C4D0009FBFCE189B85EF98F138A556BC7F3C6571 +:10C4E000C96927C8F53CBEEF5569F9B84E99EFE721 +:10C4F000AEFA537EC0D3E7DB9B5F9E46FBB3456538 +:10C500008C6B2DF9BCF1F56974BCDE768598DFE3A0 +:10C51000CC5D255BEECFE6DC65CD2B09F788656247 +:10C520002AA7F972181FE148F544735C55668839EB +:10C530000B550FDE0F0EA5094C2FE6F90AC85390D4 +:10C5400074D822552E3ACF8E3705F43B1C6D9F9F31 +:10C550008771FA3F09E7017E1BF890B87F4A9A6617 +:10C56000BCEFE1E4F7839D705897883F4D0DA41808 +:10C57000FCD18EE831D715B08F276CF89ED45AAE17 +:10C580007FCB1E16FF6EE04B62BA3601EFD67E7E81 +:10C5900023E25D2FC5BBDD03E09DAC6AA827D872FE +:10C5A0004810C8C396D99DADD276573CA3043D141C +:10C5B00064D37E5C9A06FACC15CFDDCCDEF5A3F011 +:10C5C000C27721EB9562B0FBEDF599C57206D4F305 +:10C5D000203E7EE861E73F72BD3B08E58DED150129 +:10C5E000CD84D7CD0D6AB15C0CEFE3388AE1779644 +:10C5F0009A53FCDEF330BF580DFE2585DBFF77A68E +:10C60000B1F9DE99E6C674451AF35B3C28EBB360DA +:10C61000FE0F52FC817881237731FC5D31C481F7B4 +:10C620009E573C5F3878A038A07D0D816280DBCEBC +:10C63000BB6AD0EF51B9FC9813DE055BE175A880A9 +:10C640008F926FF8FD9301DF5FB0E1BDAF466F855C +:10C6500036D7D49FE49B807E2549D4B3C1286AD9BC +:10C66000F2D6B5F244C0177D0748A248DAF16B65EF +:10C67000CA5F3ABC7AB640CBDBD25E60E583F41D7C +:10C68000022D8FA6FD86E587E9D9F04B221D692F83 +:10C69000B37CB1BE03F29D69BF67ED41B7A07ACC10 +:10C6A000A1B4D7AF053DA7D1169C0DFE9D1FD1F9B2 +:10C6B00097D2F977F2F4A71C4E46F913F09DC2FB0E +:10C6C000204F13CB9FE6ED0EA528FF292F3F9CA2FC +:10C6D000FF9FF3765D29DA1FE5ED8EA5687F9CB795 +:10C6E0003B91A2FC055EFE628AFE7FC3DB75A768F4 +:10C6F000FF326FF74A8AF6BFE7ED5E4B51FE3A2FE5 +:10C700007F23A1FFB778FD1EFE3DC7DBF23ABC1BBD +:10C7100096D3CE5E022DF1B6A0FEBEB3AE1CF1BF25 +:10C72000713CD3330C7CCF81784D9ABF52657ECD5E +:10C730002B55C6E75FE1785DB9BC680BE0DD8A7F09 +:10C7400093509E523982BFE7AB2F67712F2B9E67A4 +:10C75000F741562C97F1F7800C7C34DA1BF3DFC5D8 +:10C76000E7D764C031AD809FB7048A6798E33D5531 +:10C770006BDE41E90942769A32997C29595EE518C7 +:10C7800001F283CA17E09B6B3D4A17DCA35FABCA7B +:10C7900058DE9459A542B9AECA287FD6665639E606 +:10C7A000A23F271DFD13793C6EAF4995F11EBFECEA +:10C7B0009F82E5D37E3C43053EDA447AFD95B0BEC8 +:10C7C00055329ED71EA9ABC2EF79FE8FFDC09F7F69 +:10C7D000E367703FE63DEE84775FE5EF88282F86BC +:10C7E00003FCE8B805ABC4A846AB1C535788907F40 +:10C7F000B889C92BFAE71D6B7A77B16365C50B1051 +:10C80000BFD3B8490EC2790EFCC9267950C47FF750 +:10C810005453D32DF2EA41EEC7D5030E8CC32B92AD +:10C8200049C0FC7B989A2AF17729D83B668511ABE1 +:10C830007CCA6FB1BE63F39FD7EF7F0B008000000F +:10C84000000000001F8B080000000000000BDD7DD1 +:10C850000D7854C5B9F09CB3677FB309BBC96EB2FC +:10C860009BDF4D801024C006420C88BA090122A229 +:10C870002E880ADAE286DF00493670A962C5B22145 +:10C880001103450DB71181825DA85AB462438B1222 +:10C8900031E88A88F8157B43AFF6A2F67A17A48AA6 +:10C8A00080B06A45FB63F9E67D6766B3E7245168AB +:10C8B000FBDC7ECF870F1EE69C397366DEFFBF99D7 +:10C8C000CD23CA89A889E09F8BF984289A764EA344 +:10C8D00069B052C4DBF4AFD16553B52DB664C787D8 +:10C8E00049F41F5EE2BDA82364D9EE65932DB439E7 +:10C8F000E917C503A2C584AC30A58C2003685FF896 +:10C90000732D21CDAB3AAE19A42764EB2A3A2EBD84 +:10C91000367F3D7A26292524966CF1ED900859B38F +:10C920008A8E3FB8A7FF681BBD3986906D4A683A6A +:10C9300071D06B58214D745EAF2C9709B497B94DE7 +:10C940006123EDB2EC8DFFBC6E08B497CA5EE2E9DC +:10C95000795F7B7D72956B307CFF2D3A2718571FCE +:10C9600090069F1C4DFFAD045CFE644206B625ACEC +:10C970009FFECD6FA5ED84F5EAF57E9BCD4A48DE9E +:10C98000B7C04DEF7CCB1E2886F1151C5F3B8F6F27 +:10C9900083EB1AA9B1880CA4573A57804FC829874E +:10C9A0009FA0EBCC5E71EFB8936984641DB2B400B4 +:10C9B0005C49DBA384A413A2836FD3752B92CF436E +:10C9C000281E5AF24BBC12BD1E7ED6C2E0946345AF +:10C9D0003819246FC6F5F46A94FD36189FFEF1C12C +:10C9E000F80FE458B6AFCB8766C00470C8DE4907BD +:10C9F000CC84F6C0B53E85E289829B8CA37F43BF81 +:10CA00006BF5D175ED94E2ED6A6877840DBC3F89D2 +:10CA1000C0FF76CB127B4EC7575C84EC9224F63C69 +:10CA2000E4ADAECAA6FD15DB30C54B48D056DAAA38 +:10CA3000CF81E7B278DF47CAE9FAE07BBC0D70F935 +:10CA4000F941F1BCB2B56A101DDF40C4F821E8BF5E +:10CA50005B9679FBAA56187F57A5787FF05A5F3608 +:10CA6000CEE77A9D9D90FBDA26B65ADD3DF37D68D0 +:10CA7000C3F5AD4D747D9F78A2297419A47EFBC9BE +:10CA80007442875A3333E007380261FB8713724AD6 +:10CA9000F220BD08FCE9F75484B2E8ADF387FE9CB0 +:10CAA000524CAF415DF45012855F7D67C0A42FA04A +:10CAB00070D6FB4259F93DEFD5EF994602946E824C +:10CAC0005D2578EDE3BDC38AFC77BD67325CC2F7B4 +:10CAD0003E89FCB6E119FAA85E1768B50EC4FE845B +:10CAE000E1BFEFF589F73F79E6B7B7C2F7CE79A294 +:10CAF000E953802E23142E7DBC27FA37745610A0DC +:10CB00007B29C9B7DEE624641E853971027F357A38 +:10CB1000A17F87A9CDE6A5CFCDFA36BF97F6A7A806 +:10CB20000CCBE53DD7876D83703CED7D2DFF749870 +:10CB300048DA544AD7A13AC5FB0481762869046DC6 +:10CB4000AFAF574637D129AD2EF9DDA862683F67F0 +:10CB50002546DA6EAE3BE82A063EF21A08152F6427 +:10CB6000FDD80E37F0714BBD61E6E340BF9165AE75 +:10CB7000F9C53DE33F64D7E33CD6BE46F96C24BD1E +:10CB8000EA3BEC12BC3F5821C087663BC5336D9B26 +:10CB9000DDA924940FFDACEB811FD7EA03D595D016 +:10CBA000CF2D9327E877CD83675457D279B89CB2BD +:10CBB000A4C379541D5B409F37DB0C20D9C87BF69A +:10CBC00039CF019C7EAE781B810F7F6EB5DA42F4BF +:10CBD00001958D3EE05B65B0230C6DA38E3476D05D +:10CBE000F96595107F87B5679EEF71F9F89ECD8046 +:10CBF000705E6FEE985641C7B12C936D21FABDB5AA +:10CC0000F51BBB27D1EFFCB8FEF9A34DF4FEBA74B7 +:10CC100085C03CAC0E256248A1747C039D239DF722 +:10CC2000AE26BF0DE467CCA9901DF4B9659081785C +:10CC300012E4A0B598B613E4539A43F199E9FB7F47 +:10CC4000B2078EC0FC47BFF99609DE778D9165600B +:10CC50009B0E85E139A5543D8E6DBC7A9CD42AF596 +:10CC600073C754F5F3F419EAE7AEEFA8DB99F3D4F0 +:10CC7000ED5B80DEC640473AE732BA0EF68858A22E +:10CC80009FAE2229089F7700FE9642D90BF031D73C +:10CC90003F7E6A017D9E05F284CE9F8C20E127288D +:10CCA0003E0FE47EDF13A57036A6367AECC5BDE1F3 +:10CCB000919563BA1EF0651DA4D808ED6FFDFDC700 +:10CCC0005FC3F85692D02F1FE0E3FBC43686B55DF4 +:10CCD000743EC9F00F0FC0BBF17FEE03BD7754E780 +:10CCE000057867D52BF8FD076778C2BA7CD69DD04A +:10CCF000FE29BC7F8A697DB76E04BDFE7EED525D64 +:10CD00004A6FB8A6934609F892D207EA0B524350ED +:10CD10005F3C20935AA01BCAAE04C6B3C10B54CECD +:10CD2000F8530D0827C5CEE887FE4B86E7E936366F +:10CD3000A6C13DCF0CFC7CFF2146FFF71BD838F184 +:10CD4000F13CF851544120276D765935CE461BEF02 +:10CD5000C3DB4E3B6BEF3E987A3DF0E5C619A9A3C5 +:10CD6000804E8C3209C07803B24DBEA1747DE63787 +:10CD70000C21890E3A402107F5A9B4BF85DCE9A74B +:10CD8000F3D87CD812D2D1FBE6F9FF6EA34026255A +:10CD90007CDEBB577BFF13E440AC4641389A9D6D67 +:10CDA000B651C56C0D213ABF54F807958F1583DB3A +:10CDB0006D804F73451BEA6F73495B1BC069F35469 +:10CDC00019ED89D47932D2B339A7E3E8207A5F3FED +:10CDD0005FB6C178A954B11BE8203FCA6EF3FB616E +:10CDE0005C0A73B98C910A8C8B2BA4DF49E37075B4 +:10CDF00038F6DC2DD171D260BC11AC3FC0C9CEE198 +:10CE000034D6EE413E75F071D306D1FE23D8382DCD +:10CE1000653DE3083C6EAE2661989FF8AE18273E4C +:10CE20003EF1492057F5BFA670A37892724D38B9EC +:10CE3000FB1793B0311FE0E36FDC8E7C6D253B80E8 +:10CE40005F1CD99540479987B74C9747C07B16FC24 +:10CE50008E7E3E09031D672AC4744D2AD82F7E8416 +:10CE6000A3965FDD07DB6EA63C12C78B967FDD0ABB +:10CE700069D5A5F6E663B7C3515938A20F7ED6F03F +:10CE80008BFB70EC7B40F45ABE7E2CE95C09C085BC +:10CE900024F6D77D7B5BA7EB383A09909541F504E2 +:10CEA000057DAEE67B84FCCD086D89C89E8B034171 +:10CEB000EEDB391D537D459975F728DB042BF0E92E +:10CEC0005282F455B977FDEDBFA6E35D186CB081D1 +:10CED0005EC939DCD60DFA91740686001EB62A8129 +:10CEE0009F24D1E75B8F651090DB6BCD6426D0B7B4 +:10CEF000C2E95CAB5F1E02BE71226B8465D7DF7F27 +:10CF000015F660C7A0F461361B8CFBFA6193F37FC2 +:10CF1000D1CE0A0D433B2BFB60779315BE6F9BDC94 +:10CF20006AA2F035BFC9FA3F48DBA14100BFBA3C55 +:10CF3000E0C303390B104ECABB4602743A5CE70BE0 +:10CF4000439BBC6726207F773EF79D5A0FC89FF40E +:10CF5000291E90433F017EA7EBD9C6F95EBB7EC573 +:10CF6000E00B803DA1BDFF685C2EF94FD5503C0E13 +:10CF7000FFA981ACA30F8BE439ADF9C0176BA9FCF5 +:10CF8000A54FE7E83C0D3F947AF0D369AED86587AA +:10CF9000EFAD32918091AEEB2B89042873E6387E99 +:10CFA0005B01F227974424D0B3B98DD4E005BA5A77 +:10CFB0006E2181047ACFFE4AC1FE9D66DF2E3B972B +:10CFC000FF262A07F4EC9FE4E7A97E52E360320AC9 +:10CFD000EC17FD3396E3203788A3CA17F7370A808A +:10CFE0007EA9DEA7DFDBC7D7ADA76A423F8AFEB5C1 +:10CFF000CA11E388DEFD5FE6FD14933502F252B1FB +:10D000001E3986F2C5A69C4DEC670A337D43EA487B +:10D0100078B0C4E082ED7FB3613B8BCA5FE328B494 +:10D02000FB434698670AF33F88CFE771A403BF101C +:10D030000472B689B49A683FA476CA6F6ED26D4600 +:10D04000BBF920F1003F5088D9C13F845B00D7ADC8 +:10D05000845427F281B88EB4313E5056E8D05F1A1E +:10D06000F6AA19E7A36F246133D84330370A6F65F6 +:10D0700039092BE06FAD3060BF91360FBE67208D50 +:10D0800068CFEEFAFAFD4C90D39643D41E1B097874 +:10D0900096514E592C6AFE23A409E1F409E7BF6DAD +:10D0A000AB6C88E7B87F16788BE339DA04FA22771D +:10D0B00079AA0ABFA25FF6575924303A71DC308E44 +:10D0C0009B3DE8A0448AE1792E3EDFB6CAF32DE30A +:10D0D00017F433BE1BE9A8FFF1B3F1F9B6C85BF64C +:10D0E0001B2928B6C60EDAFD9E1EFB5A0BE7ECE59F +:10D0F0006AB93CB253DD167031EB7D8E6914E6E6F9 +:10D10000EFC9DEED74BC2B8FA9FB55E7BF8DFE6D1B +:10D110004FFF88E366E84FFDEFED201D4EA9FBFBB6 +:10D120002B5EB3031FF7F467F3BBF62B753F2D7E21 +:10D13000B4F3A5F372DE9230AF0926A3EAF9CC9AD4 +:10D140005EF372DE9630AFC92E75FF4053DFF3BA3F +:10D15000BEC8F88DF312FD6E2ABFB47EDA75DC5CB2 +:10D160006DEC07EEACFF6D332F6DDC3B6ABFB9DFB2 +:10D170009D2BB4DF0921BD5F2FF97CA9F43A076E1E +:10D1800081BD68B5A0DDABA5975D5C7E4E067B8E4C +:10D19000F69F95EC9B9C4ADB1305DF3DF5BBDB411D +:10D1A000BE1C7EF68A0C90EB59A0E7109E2CAEB008 +:10D1B000BBCE857185EFF2FE549FB480BCD8BD9381 +:10D1C000BE97C2E695683FA5D531BFC24662C8CFBB +:10D1D000C25E4A253689F9E3CCDEE9EF3BDAF1D7C6 +:10D1E00071FF73EE8A09E403CA87CF1B6C150AF836 +:10D1F000678F49680FCCADF2E992297D8C6B953031 +:10D200006E34F79E7F1B0D7265EC494F6794DE9F6D +:10D210001BB67BE1B30DDDC417A67495A15B5A72F2 +:10D220001FBD3E7280DA3FBCBD14E8CDEAF380BF7B +:10D23000510333A2E39CD53796D8406E7ED7EA03DC +:10D24000B95933C3F70EAEF7AFD42AA1FDE6B3A5A3 +:10D2500093BDEDD30C1E6A67D47CC7530E764F4D39 +:10D2600087D9875713512C741D35D41E836B868143 +:10D270002866B85A8809AE65AB99FD9552EE37D449 +:10D28000D0EFD774FDEC0B786FA1127985D993613B +:10D29000C45B4DD71B7F027B6DBECF6F0079316CB5 +:10D2A000A781D9A49C1E8677A8DB200F12DB25114D +:10D2B000757BF46175FBC35406DF7D527818E06717 +:10D2C0001F5570E017877619515F1CD86F44FC2CEE +:10D2D0003963D90EF1A7094BAC28D7CF3C6DC6787E +:10D2E000D43EB9E35968879E4D42BFFA9577F795CA +:10D2F00049B4BDF817C9323C7FF16B1DC21996A322 +:10D30000A7F7973C3B74FB3A7A7FC9E88E321BBD86 +:10D31000FFFC158474C373253C02D6F7FCDF743818 +:10D320007EEC29637807A587332FFCECD97BE9F7DE +:10D33000CF3C95952A51BC5C05FA80F61BF75393B8 +:10D3400005FC8C71679E1908F262C94EA36A5D4F95 +:10D35000A7327B83223305E8ADBF78E289B53FC3AE +:10D36000F78B4E1D437ADBA70FC91658FF5A465F4D +:10D37000DAFEBB5399BE11F380F7F2297ECE7F6CA3 +:10D38000B913E2684336A9E13B34AC6EBF90CAF4EE +:10D39000FB1C92703F1FC62B58E3023B753B417B41 +:10D3A000A6E8D4EF6FCF073BDAC8EC07ED3C0EA43C +:10D3B00032BE7EFA693A0E930F3A663FD315537E1A +:10D3C0005CC2E9F84589D9AFF4CFF22C4AB74B409B +:10D3D000F117F4DC5FA2998718FF077C9D0EEE57CA +:10D3E000C7DED4213E4EAFAA1D7D7270EFF97CB826 +:10D3F000AA716895BEA7BD60D3D2436EFA5EDD6E9A +:10D4000027FA89E27EDD53AFA6DF41EF9FDDA978E1 +:10D41000C174AD9BF5E443E3A0DF53BA0E982F3CF3 +:10D42000F7D1F59EED782D05FA2DD86A1FA54BC0D2 +:10D43000C3C24DDF1B5A95200F2F971F04FFD671D3 +:10D44000FF766F79F7A42CA0EF4D9217BA2DE9B8AB +:10D45000E5E61BC056D9AAF30EA6CFCB14E2D78DB2 +:10D4600042D77B065CEB763F7728933E0FEE1F5347 +:10D4700006EB5A27FBAF1F0EF4FF981EE3585AB86D +:10D48000FC85E39BBE1F91E9FBEB6EB5D686AD38FC +:10D49000EE41681F28DAA183387BCA292A9FD8FD6C +:10D4A0006332E5C9535DF78F8078E23EBDB515E87C +:10D4B0007C5F32C34368970EE53C89B0758CE3719D +:10D4C000E325FFDD6E50E8F5D4A9D529158C8F50E2 +:10D4D000BE805076D0F5D5FE7438F2DDC24D6A3E7E +:10D4E00011FDC47C1785D5CFB5F4919526E20DA426 +:10D4F0002891CEB4FDD2A6860CC057752BA83C4E01 +:10D50000B07FEA4EB619C06ED27E072C4022F0AA38 +:10D5100043FA241E5CAF99AD979AAC26BADED3F0DD +:10D520002F16F796C02F5F2CE112C9922B489587D2 +:10D53000C273C974520DD77D52E4211D9767187FBD +:10D54000DF9584F2ECAC2DFAE48F81FE9EC9F18662 +:10D55000E8A34C1E973BEB89A4A4D2EB79E00BA087 +:10D560003F1B6B2FEEA2F29CF2F7994F0C28D79B32 +:10D570003A5E4D017C9D7DD62CCB142F6776A75546 +:10D58000423CE76CC7AF53605DA73BD22A212ED740 +:10D590009FBCD1CA29A1CF8FC33FC7526598E6BBB4 +:10D5A0002A0DE4564B1A18E32423ADB1A4B10FFEA3 +:10D5B00017EF390C8D251E901BDFB57A77303811A7 +:10D5C0001F6D7F76386D07E05BC8A91A898D2FDE45 +:10D5D000BF318EC76F968FD5EB86621EE833E21996 +:10D5E00000F27A1A287AFADEE1570A0780BD20EEA7 +:10D5F000373AFD33D2E87D5765B74F0771C429C468 +:10D60000DB4CBB7EA0F3DE65A3F89A47A8FE826BD5 +:10D6100069C08071971627AE6FAE42220AA5F7B98E +:10D62000A05F47601BF13577AB146EA6EB99B75E30 +:10D630000DAF05EDC61E3AA17F17112A608111B703 +:10D6400026F4A3E32F023D4AF1B0D844224974DC0A +:10D65000C58FABDF5B4222389FBA672E1AFBC2C769 +:10D66000171C1F8D4E5F7D9A4A0EEA510E2E21FE29 +:10D670006BE0BB4B84BE7E8BE12B78CF3D43E75103 +:10D68000FBE3FC8A7B87CE4B837822F1811D41DA54 +:10D6900093918E975491480E9DD7922E29323CA596 +:10D6A000675CF24B89F96744C1F57FF116C3DFED82 +:10D6B000DCEE994F6F831D7115F8EF80EFCD12CE20 +:10D6C00063DC33522899FA49F34DD4C503F9C4D722 +:10D6D0000BFD07D0F6421242F83C9C968F785B44D3 +:10D6E000BA0D8C7FC2CDE9F4BB0DA7A84C2297429E +:10D6F000076311DF9F132FE2FBDFE3745086F421F1 +:10D70000EE53FB8698537BBF0F78F325C0B976ABF9 +:10D71000BA4D1E4F6817005E683B015F0D7B2E1AE5 +:10D720007D7DE0E991B87E0B0F9D363C913F98FDE1 +:10D73000FC3EC7E323B72C70833C7A18ECC94C3EFF +:10D740004039C86F22E22311131DDF329AA8E22567 +:10D75000D44EC3F62FD2FEEBBA4DD9846CD4073029 +:10D76000EF3057E73F0429B281E9815F01DDCF95B2 +:10D770007DB90AC2D557887EF30A460F8F8E6A1C80 +:10D78000DAD887BF2CE6BF51EA88C8209F5E60F6D2 +:10D790004672694C1F48E0F737D3981D33E040F4D8 +:10D7A0005016D0DF7312C6F7374BA445A2707651DE +:10D7B0003C835EDA2C1D3F047A6CF3751ED24C9FBD +:10D7C00097EE99B6F435F4B92D5EC897D4EFA9D089 +:10D7D000D55B71FDCCEE4D6ADC2ED3E71977168D43 +:10D7E000023EA3EBBE733ABDFFDB340FC2CD6D65C5 +:10D7F000F4E35A1DCA5F06F1DD03FEA5AF01DD0D9E +:10D80000B7601C2D83C22A3915AFAD60CFBA4893DB +:10D8100004FDD63825C4C79A1A32F397C548CDCA35 +:10D820008054763D46AF92425A202E9CA150FB98E0 +:10D83000DD6F81EF3C92C2E6E59475774E03FB7C89 +:10D84000146BA7AE947C3B508F6D403864184935FB +:10D85000AC1BEE833D4FA7E1DB8DCFC338EF8C09C6 +:10D860008D25308F8C81ECEA3044B2619C23824E4E +:10D87000BADC32E88DE55CFF2FDF5D91914ADF3F36 +:10D8800072D6A4803C3FE212F668C40AF628195406 +:10D89000C4FA733DBBBC64420630B52357DDEFBC10 +:10D8A000DE376034E8ABA33ACC1BFDD1EA1B60A79E +:10D8B000FDAE32B07568F1AF7330BC06BF92483828 +:10D8C00021FE109C7901EDFCE0578AEAFED955262D +:10D8D000124E883FD4D51E9804FDEA49F71AA0C716 +:10D8E000FA8E24124EE08FAB2C7D7F57F045F02B43 +:10D8F0001D098D46B2CF8638E9117D6CCD7CA0C361 +:10D90000FD12C6B382D4AF0F25CEEBAB34124AEB77 +:10D910006B9EE9EAFB743DAA76E797D88F9447534C +:10D92000E03BE76CD1143B5F1FF413FAF77C580E11 +:10D93000E947629E92E96188335999FE9A06F85543 +:10D940006229D3937BC615CF61BCD484759E9B6935 +:10D950002011C44B0CBF0B700B0D21644BD7A706D5 +:10D960000FD8235DAF20DC04BD24C22F9498B76A82 +:10D97000EE8EC854565CDD9EB3AED84C517580CB4C +:10D980008550DE3ADF78FA5C27ABE44452695C6E7E +:10D99000A0987A04B2681857F5AC83386BBCCDFBFD +:10D9A000C7DF0FE54FA9A2E39516B3F727B717FC1A +:10D9B0009FD5A003491BD3CF4A2CD79F9CD0366953 +:10D9C000DA56DA1E9ED0B6699E3B34CF5D9A763623 +:10D9D000EB7F363992ABF31232BDBD708A42E5D689 +:10D9E00059776436F5A8C97ADDD02955B45D5FCA88 +:10D9F000F47A4397E44535C5E1D7E06576ABD51BAE +:10DA000035CC2D0638741F02B952D729D924CA073C +:10DA1000D68EDD116CC37B9E84F73A247CAFAEE3D7 +:10DA200038BED7EFF84532F2F9BAA213AC5FC74758 +:10DA3000683FAC69A9C1FCBEC85FEB88DF9725F5DC +:10DA4000E4AF857C3DE7F6BD2A33BAB625FA7341CB +:10DA50001837216E24FABF37BCEB6D304F92967F9A +:10DA6000DA04F6F47FD77F3406ECCBF7B81ED9285A +:10DA70008587C277B790C050D0A3DFAD1FFC8A4C1A +:10DA8000FBBDAF8F6E831CDD86F66B107EEF2747E4 +:10DA900073242A637EE4B88EB59DD16D00CF8F1DAF +:10DAA00053A628749CF773A239326D3FDABE9CB539 +:10DAB0000747B741FB654780F51F1ECDD1D9C0553B +:10DAC000AB9952459F3F61EB9B9F5BB91C11F333B0 +:10DAD0000FF4353BC07EAC63FA671BB57F4D545ED7 +:10DAE000CE5E7C7AD713140EB3BF9F8472EC89B3D9 +:10DAF000374F61FE41C8AF9441FC97FD41FD8872EC +:10DB00005E41FBC20D3A31B5071FC9B9DD1ED41FF6 +:10DB10005734EE06BB25637631EA8FB169BED3F088 +:10DB20005D71FD4526BB9E76D8985CD6C9980FCF0F +:10DB3000B83719EDBA87CD6C3D946F10BF568E8FF4 +:10DB40006D0E66976E7330FF7649DAC4D30E7A7D18 +:10DB500057F26D3651B8BFAB272133C8D94516B43B +:10DB600097EED84EE50695DBED7CDEED1BDC61C85B +:10DB7000E7DF21113FC815213FDAED3E776A825F6A +:10DB8000D45E42DBD61E3FB87D9ACF6D71C0355D45 +:10DB900086BC8F904BEDF9EC3DA18F329AD977324C +:10DBA0001E1EBA03D691A4B0F8D5FC99853B9AD035 +:10DBB0001E988EF3253E9F1BE220271715C810D70D +:10DBC00012F8B962A06F2FC0E5769E17107812F890 +:10DBD0003CCDD73D5747ED09BADEBF380308476A49 +:10DBE0005F8CE0F133B42F4E836E4F802F51A263D0 +:10DBF000E0FEFF4770FA3D3CFF47E154BF82CA0B8D +:10DC0000F912E40587DF4629A2CF60F202FD79B858 +:10DC10000F7AA7332D1083F1C5F767DF5B8FF6A46A +:10DC20009857D2DD7BAB6F23BDF94C6BEFFD19F03C +:10DC3000E5ECB14BBD220ECABFF3FEBB26CC7BBCCC +:10DC40006FE840B9F93EF5A39A40BEF0BC7DD9F724 +:10DC5000971C017F548C1B70EA70BCB592CF0DEB02 +:10DC60005B4BF16E82F94F33A0BF21F46ABB3DBC20 +:10DC700019EA26DA6FC9C6BA89F384D5A78456246F +:10DC800061BFABE41304E2AAB1B136CC9B533AC1F5 +:10DC9000E7EDB30AB17E85D243C80CCF293D419D43 +:10DCA0005F7B095D108C37EB0A7C0EFE3AFAD9B324 +:10DCB0004C385E1F74C2E2D443587D467B3EA7C3F6 +:10DCC00045054887E9CD2C1E4A14DF8869097A7E0C +:10DCD000BC93E139A934FADC7F01CDAF37A33D0B0A +:10DCE0003A16734A6D19381EC5FF60278B4B209D6D +:10DCF000CD7B2899D7C379CB00AE0F2433BADC6A29 +:10DD000066F9AEADD47E46B9C8E957D4E105B89DF1 +:10DD100017AD9553C05E18ED8CC73B7C107FC07863 +:10DD20003B7D3E272A1D07BF6F4E481731425CB826 +:10DD300075A22F9AE0BFC01FC817DEC9E52AD944D3 +:10DD4000D0BFBA13DE4B81F12D29901FBD13DE0722 +:10DD5000FF71E544551E7022C8F0313DF3D3CAFD72 +:10DD6000894E1EDF6C7BD497F81D31BE763CEAC726 +:10DD70004E723A11CE9101E04734E9108FDA7946BC +:10DD800037B1B87974531ED29D18AFBF79FE8F2E6C +:10DD9000F63D89EAC10513987F2FFC9EF9DCFF262A +:10DDA0002BD57E1DC479E26D5DEFB6D64F84FCBEE7 +:10DDB000BA3FB35B928A6306CCFB7824D5FC05BCE2 +:10DDC000FA83439DC0E725C24DE8BD47CD549E521E +:10DDD0007AD904759094BE36DD93847ACC61080FAD +:10DDE00005BADA02F535A84F99FFFEF91175FC4521 +:10DDF0008BBF1FC4E9EAF2FCEE26C0B9B3B7DF1D42 +:10DE0000B4C41E03F8072D8C2FCFED4F46BE2283DE +:10DE1000A2B3A1EEEDFC3E23017E6890A2852027EF +:10DE2000CE49BE1AECD794E401FEFC406671812015 +:10DE30006084AE3318FA0BD65B053BD57EF839FA11 +:10DE4000B796F2CF39395A06E308F902F204EDAC7D +:10DE50005A96876A904908FCB4ABE4398BD09E98F7 +:10DE6000954976E0FDE385E09709BD41FB1D94529D +:10DE7000191902FFD5717C34C827B05F1DD44D013C +:10DE80005EC05F83781F3C4C885337AC3F83755B23 +:10DE90000D7BD47453D74357D24509DE4BA033943E +:10DEA0000B218423DAED2047AA581E3D99B793AA87 +:10DEB000BBB18E2BC8E32FCE03D149209F924B3BA1 +:10DEC000C81C7A0D9E6276CBB8AEEDAF825F6EAFA6 +:10DED000EECE01760AF278A7A01B31CFB15D1B749C +:10DEE000E0370A7B27C16F1D3A5D15B7588DEF816A +:10DEF0001F0CDF8BC22D379015D3931BB99E4C029C +:10DF0000871AF469DB10D4A7A0EF40CE093F1AE4CA +:10DF10001ED0D5C0F4CA23C0F72FA657BEEE74B2E8 +:10DF2000EFA17F00CED7D8FEE94EC047F4037FFAB9 +:10DF30009BE3905C7E13167F5CF686F31BE9FFFD86 +:10DF40004BA6FFA11940E7CB244F06D0F9F138FDCD +:10DF50001762BE52DCFF5017C038A388772D82F8B5 +:10DF60001EBDD67139B480C7C71688B8D826755E6D +:10DF700015E2D189EDC5224EB6D3D8536F04F2A372 +:10DF80008A4492E978F51067836B87FABD061263BD +:10DF90007CD479D1A8CADBB63338DEC9E9C95E15AD +:10DFA000D681FCDA6C66F13221D7C6ADDC8E7432D4 +:10DFB00060942FFF7EE09B37F4186FF903A70301ED +:10DFC000974667E551C0A745C7E381F71B519E9F60 +:10DFD000A476C26E1EE7990EFEF1AAC050A897273C +:10DFE0008A2D37D17F16D775FBCCB5687FA7CB2A92 +:10DFF0007A7DDEC9EA9B30FE85FA2209FD012ADE20 +:10E000004600BD9615087D4D4640DCEDB89EC5CD59 +:10E010001B6EB50660BCA8CCE4A13B9DE929773A0C +:10E02000AB5714EDB8FFC9E951E443210E95988F21 +:10E03000F0C4FB6FE075C804D7BB7111AF778FF3E5 +:10E04000858CF22DA9D88F7AE12AB912E55BEC63B1 +:10E05000AB07E0527DA66E11ACE3B399160279C905 +:10E06000793C1EEE4DB7E3B8228E7DB9F1F0D1E9CF +:10E07000717A54C5C3F771B9B88FB0F9865A8C2C30 +:10E080008FC1E7BFEFD41561CE1F21909BB1DD6634 +:10E09000A68FA99D0CF27ADF9E216158CF713DB306 +:10E0A0006742FB93F9FB81CD10A7D9F74BA717EA7D +:10E0B000A0828B4F8F00FB76DFA9A77FF51BB8BF2F +:10E0C000DFE8057F741FCF63D419228568CFF3FA88 +:10E0D000CFBA944821C4A55EE4F8AAB3D036BD7F78 +:10E0E00083293035DDD9936F84F7E0FE8930F31B47 +:10E0F0004E104607A1F52C2F4CE1EB8679C4D6666D +:10E1000060BE12D60578F860FF709CF7463DEFFFC1 +:10E1100020B32F4FF0F689174AB01EF2BCDF80F50E +:10E12000CBC187993D3B57F63CB60264EF4B49188B +:10E13000079DDF7E14F347C187164E85E7C1C52BC7 +:10E140006F24DF9057013D9518C73F4762B9E8A794 +:10E15000D7167444E877CF750DF5B2F4A80B937118 +:10E160000DBC4EF624852FCC3BB65F8FF0BFD4F1AB +:10E1700031A059C6F4257C279898BF42FDA2CE67EE +:10E180007D5BFB9C3E5A780FFDFEDAD4C00FD213A4 +:10E19000ECD8E04B6E94A31F3CF8652EDA3B6D2C57 +:10E1A0006F7252EF9B0D7C62AF8A18E624C8D78D40 +:10E1B0009C8FE71AB95D4BE56022DF8BE765956AB6 +:10E1C0003E13D747D2995C4EE6F512BD9F8B7ABCC1 +:10E1D0009B8DA08F59C80BC6F5E0FD3C9EC71C77F0 +:10E1E0002AF60AD49DD57594609E346F6504F99221 +:10E1F000C23B02FEC9C9CDC94C9ED065C2380BCA0C +:10E2000009DAD50B74ACFE638191DAE9CC2EC0FE3D +:10E210001F6ECE403894AD66F669EC3909E5A2C8A8 +:10E22000E7D610F6FEDE96E3211DED5FB3532AA17B +:10E23000A295D4B454607DC8E2ADF988FF715CFE4C +:10E24000CE35FA0A3703BDED4D467AA3DF437FA0F2 +:10E250000E6AE046A15C32807EADDD29617E44AC71 +:10E260005F9B3F256175DE695C0793DFA03748A29D +:10E27000DDC9F510E80BA2B16FD57411BA247DAADF +:10E28000D50787E372F2F2F4E9AF417E8DE9AD4F35 +:10E29000A9BF70249DD10993FFBB59BEA99E34B27A +:10E2A0007C1BD767F175717DF8A18EE9DF05C60D7E +:10E2B000783D9E9E8FF35A4CA23CEF1433C0FCFA7B +:10E2C000A3AFE3FDD097A0AB139CCEEA4E91C8D587 +:10E2D000F47B752B49A47E04BB268F40FDCEF4BC95 +:10E2E00089E979B85A2E41DF6BF5BC56AF6BF579E9 +:10E2F0008681E96D414F89F907B093C6AD0CEB58A3 +:10E300009C39DB86FBEB387E97A4F92E668EE9B14B +:10E310000383C74C26CF4868FB498115E26715EB9C +:10E32000B2212F40F500F06F1285D376888B71FFF4 +:10E33000E3EE6CB67E17AF93D22B7E5262053C752E +:10E3400063BC20E624E8BF0BF86E4BA6EF8D82F786 +:10E35000185FC7DF3791164BC2FB95FBCCA8972EF1 +:10E36000BC908C753D54CFE4D9E978E9EF51BF8179 +:10E37000B6CFED4B463BE11CD71B0E1197216B101E +:10E38000BFCE0C86E710A9CC82F83691A66481A88E +:10E3900015F66CBDBDBF7C047F9EDF7D2BA33323B0 +:10E3A000EAEB0BF6E85DD0A6F3C13AECE40C36EFED +:10E3B000E09E0925F742FD85DFEA65500D9480FD5A +:10E3C00061D42DBF15E25E93742B63F7D075D4E74B +:10E3D00058B1BEBB2AEFF7BF9B45DB1FEFD113231C +:10E3E000E0FD899B0744E035C5E7EA8B4F1685F5CC +:10E3F000AAFD834B76AADBF51DEA769024EC2FA4C8 +:10E400002058F1FB926B0E26D0495946B2E3C36106 +:10E41000C096C40BF5E944F79D01813EE4AEB87E99 +:10E42000B9CA7BCD413DD6F75D9DC1F8D900F6D183 +:10E430001CA0873EDEFB23E77BA3B1F114EC133075 +:10E44000BE68F436D1B7CC198149F07E831C3B04F9 +:10E45000F834E69D1D01FAB432EFAF9827BC701F67 +:10E46000F1027C2E982BD04EBAB0D9EC017FB13D91 +:10E47000D7CAE2322F496189F91553C750F95A8B2F +:10E4800053A1EBDD74DDC76C530B31C9885FEA55CE +:10E49000B9405EF9D0CFFB709AC5B69ABE57BB891A +:10E4A000E9ED3AD29D0272E087803FA06BDD330632 +:10E4B00013FD677E8B6F68139DEF12BF05F733293D +:10E4C0005F2B7EA0AF0760C804BF644E069307F5BC +:10E4D000A6A8A102BEFFD779D5CE829E389E41CF95 +:10E4E000E2784A6749248BBEBA70C55CF4BFE2F992 +:10E4F000FACDAC8E6CE13D3578FFD5CD465CDF873B +:10E50000FB25A4F30FB7B1F52FDC64F640BDFBB5D6 +:10E5100076E6BF2FA4EFF5BDFEC91FC3BA3EDA7A77 +:10E52000B717F2101F11F69D908DC5DB3EB2B1BA40 +:10E5300002E80BE37CB46720DA43B59B164DC5FABD +:10E54000BE6D3A2FD823647F32C6B1166EFBDE6FE4 +:10E55000C6429C6CFAEDA500876BEDCBD3212E440F +:10E56000FBF9C3CCBE6675D3A9E54F021F5EFBF570 +:10E5700084EE6BC1EEDA46F9249FED4B007BFFE0A1 +:10E58000B6C968DF2E9C66B1C3BA3C5B9F98047A1B +:10E59000E8A3699932AE6797446C0007FB8A74B8A8 +:10E5A000BF5052FC7DD1537E860EE15A9167F546ED +:10E5B000E0BDB775482794AF6E053D5CBF4D8FF643 +:10E5C000F3C1E9EFFE6E96A387AF16EADA6E1D97E8 +:10E5D000603F05B7DE20E88444CAC02F6330D1F223 +:10E5E00097316F6521CC47CB670B573716B2BCDC30 +:10E5F000E5F11BD9CAF8EDF10C89C56F2E9DDF7EC0 +:10E600007E39FC46B25355FAB7B75C0B613F91D7E0 +:10E61000307989EF092BE6AF7D1295BB6F6528F83D +:10E62000FCAD0CBE8FEB4FCB76BE49E1332B23B054 +:10E630003F03EC28E22B013AF2C46C95B047CBCAF9 +:10E64000ED41B295D9DFE02700BE373AC993EB120E +:10E65000E221DD196C1F21E5FF4330CEB977FE7A48 +:10E6600008F0D3907B7604CBEBFE11F3A0D62E9668 +:10E670003FB77A635857A077F891FE845C0F7A9978 +:10E68000DED1AE2BC3C5FCC2A02386E37CE6627C50 +:10E6900028F20A5B5658301EBCC51136B37847883D +:10E6A000805E9A5AAE63F93F6EAFDDC0E3ACA6D28E +:10E6B0005709E4FDC878566FF766E9AB4A1A6DFF53 +:10E6C000A67CA217F73996FEB4B500D63D5ECF9F63 +:10E6D0000F0CC1BAFFC35781CF97B9741EE0EBA9E5 +:10E6E000A5AC6E94D4A6601CE7CDD20F1CF312E645 +:10E6F000EF27268F95D2C974EA2C25D639DE38DE6D +:10E70000ECB126D0D7676D5235B39B3D03660C67DD +:10E71000711AD4C3A56A782C7319F0BB2FA6577C45 +:10E720000A70BEF61A868FD3BB8C61907FA7F9BEA4 +:10E73000A15E74E1E2F4F39D22551D82C3D0910BDA +:10E74000FAF18CA47E6F71AB0EEB0016B54A244C27 +:10E75000BF77FAA9BDB920C73F7E626FEE9C84F9EE +:10E7600068DF13578BF81E8F776AE3D7FDC5AD4579 +:10E77000BFF39B48C034B0A7FFF9DA3F63DC7A4EA1 +:10E78000178F7BFB7C831CE04FF1FEDAF146BB194F +:10E790007D489D12C64D44DCF6C4E19F4286288E1A +:10E7A0003F7357BE9C58272AAEE338DE6E06BCD1B5 +:10E7B000A5985B59BB3F7CF5C78FFFC1F58FC0DBC8 +:10E7C00089D68103008E8606AB42D8FEBD22B0F703 +:10E7D000B7118B17F8C990E9B282FC12E71F7C6968 +:10E7E000665787855EA9BD96935984EFDD2DFBB1F1 +:10E7F0001EF14BB90DF76FDEAD6BC43AF73217FB64 +:10E800005EB6CDBF7B01FA391D58F74E5AD5F04D93 +:10E810000728809EAA31A09E1270BE6ACE5DE8EFE6 +:10E82000F6819F4D403799E5EC5ED095CFEDE52818 +:10E83000E643CCE5C4067181E6B1219C8FC04F90C0 +:10E8400075275297847632D4EF24A562DE37C4AFA1 +:10E85000C49A4AE2799024EE1F134DDE838AAD10EC +:10E86000F413F304310675400FDB3BDA0A59DE1866 +:10E87000ED4F1817EECF2956306F00FD0CA3BE9D4B +:10E88000DEE274C9EB3BA78AFBB5963EF32C5361DD +:10E890009F14ED9F43F520D87FC4AB57ED93DA4A20 +:10E8A000ED66F0EB441E5B277794B8D00FE98E42FB +:10E8B0009CC55066F2805E4DD2751401DEB4796D50 +:10E8C000DA2F9FD55364DB41AF887D500D2B26F89E +:10E8D000619F41DCCED8CFFCA3867B2AF0FE842E3C +:10E8E000962708B61A711F67B053C2BC5C83DF104D +:10E8F00036613CC4D304F80A513B0CFCCF763BABE9 +:10E90000036BBFCEE60D91C4B87AF4B17B31AE6E25 +:10E91000C57CE4DF9BA73D9F4C013032210F37C0FF +:10E92000C4EB0D59DC3D9DD393C0BFE06791D74D3B +:10E930002EF6E783C5FDE5C6D0AF2DCECBA87F214F +:10E94000B73DF88DF52FE4A31BA0FEC504D63C7F90 +:10E950000ED3A27A33BEAFD1ECC1FC5DFC399C472B +:10E9600061EA94F8FBED374C1C8475BBBC9E66D6FF +:10E970007AA8C37FD84C54DF4B9C9FA2195F4FC726 +:10E98000B77A44FF7BAF9FA8601E9BB7DFFD21D401 +:10E99000FB3CAC578F872428F6619A7ABEB72E6B62 +:10E9A000C883EBC7F7E86FAACFF7BAC6F4E8F10758 +:10E9B000DE9DDA36D203FCF539D6410B7D1C74B0EE +:10E9C0007A18ADDC3AE09284FD3B0954EC9A993513 +:10E9D000787E433C8FDD35CD07E758883C7670A5BF +:10E9E0001FEBA141FFBB50FF9FFDF01580D2F4D378 +:10E9F00068FF07BF52585C89DA1112A543535705C7 +:10EA0000C64FA13C17F4A6C0FF62AE97C05607FAE6 +:10EA10000E6EBDED091D7D9EEBF6FD078ECBFD4014 +:10EA2000ED7C4FB9D8BE816051E5669007E47189ED +:10EA300080DE5E57F419DA190D2F4C1C9358CFBFA6 +:10EA4000A8F311560FBE53DFE7FA4FB9983DDAF03D +:10EA5000C27318173D1D66DB886A95F0DA71109F46 +:10EA6000A995C1D222A5E19A59A8FF67D275D075A0 +:10EA7000FD86DB25C19D3787607F4190FE05906D47 +:10EA8000F12F407B7FCB4C9315F248C1A2394B91BB +:10EA90001F6C161FAC5F3BCF781EFC1E0BC62DD71C +:10EAA00075EAABC16E2AA376D2AFE87C7352A75445 +:10EAB0007BA95CCAD2ED2EF9372BD40FF4AD87D7E2 +:10EAC00067323DDC22F943379562BD2749AC47CA1E +:10EAD000EB64F6D84597411587BFE86276E2F850B7 +:10EAE000F704A0B997946812D8C541E2FB14FC5C06 +:10EAF000E2B77A601C380103EC2CC72A0FC6854D9B +:10EB00008EE80F47A2DDA4A09F21FC88732FB038A8 +:10EB1000DA5277C0EA86F88E2EFAA39B006E3F6425 +:10EB2000FBAB89C2E44DEECDD65110F7323BA23F8C +:10EB3000AAF6601D11C61F065CDD827878C9416C9B +:10EB4000009F09A11A454AD033426E4C88EF637288 +:10EB500060BCB5928B97C1145B1F9A90445B2EA644 +:10EB6000F5D80587FF3A43819BC25E904D01F4675B +:10EB7000AA6652FF10E8724DEC900CF17D4737DA2F +:10EB80008BF51D127EA7BEE89758E7B784D793C5CB +:10EB9000EBBA9428D6B915BA93785CAC85D103E961 +:10EBA00046FF973CC3E04FF526D6BFF5D8ED4DACF8 +:10EBB000EE888F67E079897A1EAFA180C2E7256E63 +:10EBC000116F5BCDF5AFA8D763DF258AA72C31BEC7 +:10EBD000B0711AD524382F4F0ACCB7D3EC1FE7A653 +:10EBE000EF9FA895595CBC35290C9B72374ADD3ED6 +:10EBF000885F864AFADE7F7413FFEE8003B149987E +:10EC00003778A1BF7A6056FFBB79CC1558875FDA99 +:10EC1000F9E924A00F524D901FA9BCB8A47AE019BD +:10EC2000800FE7FF43F5C05EC9B7835EE7BBEDEA3F +:10EC30007A602FC397C8AB6AEB80CFB9230AABDBEE +:10EC40008B3EF604E8DD4E23D6034EED7CFD18C462 +:10EC50002FA79A4807E69935F6C3C9B49B1B004F06 +:10EC6000E73FF9F0B1FB09D4913FEF65F5856A7B89 +:10EC7000A03FFB1F7323097E6248D0CD3FC9FE171A +:10EC8000F23AC8FDA93352ECA14258DF7E9DADAFE8 +:10EC9000FD480FBA45DEB59F7A96AEBEEB5944DC0F +:10ECA000B93A9AAFCA733D1AE783CBCB9B6D819C6F +:10ECB000761F793385D7A92912131D24C7A0CA9BB3 +:10ECC00029F6C2FEF266117CFEDC107CFE40AFBC71 +:10ECD00019AB7768D99FE101FBBECE197BF2490FD2 +:10ECE0008C67C0715A5E480A433D7F0B877FDDA564 +:10ECF000E7CD7EE5EE236FB69DDB6F1F14C91103D0 +:10ED000085EB76C2E61FEA12F93319FDD8D88339AC +:10ED100062FEF8FCFC83C3305E3457E4C55E62716A +:10ED2000B4B93CFFF5C1F442AC67EB0FCE735BD5D1 +:10ED3000F985D7389C2F982B301E7FD7BF4FC3F84B +:10ED4000D40288E30F84B8561B8FCBB3789EA79567 +:10ED50009D2BE0D929853D2C3F6392D136B4C970F3 +:10ED60007F0915A35B40F48628D55C496F4B146A74 +:10ED7000F4B9A785B6A9D1AFAC55422EDA6FFBB175 +:10ED8000248C9F3DE0F0E07C1F686179EAD07A290D +:10ED90003C988D8BE7B5855A641F8CF30737D3F306 +:10EDA0005FBB0D7D9E0FD1A2E7F910FEBD26224765 +:10EDB000E02A4BECFA804DA9EECB7E10E3B5E81BC0 +:10EDC0004D1500EF1C762ECC05836F26C697530B8E +:10EDD000F1FCA796E4C6D66AF61C79F68239E6C736 +:10EDE000E7572BCC20259E5498EF7B6E9E5FD3C0B7 +:10EDF000797E9BBAADCD1369F7BBCD258121EE811C +:10EE0000BDF783BDC7F5DF8575F91C2F5ECC97B4C0 +:10EE1000E83DBFCD077A5FCBCE776ACA6670937341 +:10EE2000D8B5C05E85E7F0113BB7E3089B7FC1D53D +:10EE30000E09F8A1C5CEE8F61F9DB776BEFACC4202 +:10EE4000065F3BE3D796B55298C18BCDFB52E322C8 +:10EE50000333FFB972F103C9FB64241FDF43B91008 +:10EE60007A508F7C778284B3587DA80DE5E61CEE3E +:10EE7000E716677AF0FB5B6A0B52209F3AF7D41AC9 +:10EE80003CA769C2CD569C7FC34B66F4E3EA574664 +:10EE900073819EB57084D92A429ED2E7731C849DEB +:10EEA000EFD3AACE0F6AF3BE6B53FDE3201FD450FD +:10EEB000192D84BCD123F207BB5F67720DF56AC3BD +:10EEC000CAD8931067FE6E6AA002FA9DBDE7DD49BD +:10EED00092075F47F9767EFF10DCD739A745BDBFA3 +:10EEE0008DAC57E71F496B2AC6D549BBFA3EECC328 +:10EEF00052BDD72B1FC9EC9A8D86C050B03BAFBD19 +:10EF000086D55B7CB2482680CF4FCC84E7F9859CC0 +:10EF1000F51626EA81D9FDE295F60338F3FA57D1C2 +:10EF2000BF1EF04AF159C7F1FAC9735716025ECFF6 +:10EF3000EEBEB210F0BA51DFE603BE18981E980379 +:10EF4000F03839D18F76A1A8F7BD547A5B9AC9F50C +:10EF5000E0BF480FFF407CFF32F530FC498C97BC86 +:10EF6000F45756971BEA62FB827BE274A7F17CB3ED +:10EF7000F35FC912C8E1FEC6B371FBCE652221B0B2 +:10EF8000BFCA2AA3F85ED99F650276A0B07FB5F309 +:10EF9000DFC0F1BA23D377C105F8E571DD5A3EB67B +:10EFA00029FC39B3B31F97306E6BF28452C6A15F50 +:10EFB000357FB40EE5CAAF70BF07E9926CE09F2CB5 +:10EFC0007ABC099F9FEB9C8BCF655324027E583DF2 +:10EFD0007D0EED35E3D5F5DBFA3D259144BF97CEA7 +:10EFE000E333F04B931C3103D06703D8D5748A0DFB +:10EFF0000A8B6F373808C6554A3BD57EA2C8DB6EF0 +:10F00000F1B3F373B67449788E56BA21909F0D7898 +:10F01000D5E46F7F91E93B96E9ECC9BF373A7DBBF8 +:10F02000810E1D06928BF57A7AB11F51BD8FB3BF49 +:10F030003AB897057F7CABFD340BEDA42F881FED0C +:10F04000A403107BC0BCFDAD685789FBBDEBE0C2DB +:10F05000AA7CFD02BEDF7601DF6F0BF23EA291F7C4 +:10F0600089EDBA843AB8485FF50C09757089EF25C7 +:10F07000D6C1455472B28DEF07598679F220E59BCF +:10F0800015A37AE8BA8EF03F9B621FE07EA09D46F2 +:10F090008CCFD5F1FADC60ED09F47B82B0BF88F14A +:10F0A00037AB63E7E755D4517F12EB943BD475BC83 +:10F0B000E7FFC9FA45F4EB2FEEFE670D7F8B7589EC +:10F0C00075D475498C1F35F3D4FAD1DAF8B9F083C9 +:10F0D0002F55CEA564FD6BE55C5696A0EF7F4CCE18 +:10F0E000F5CA430C8AA578FF0979888F3D6DE91030 +:10F0F0009A6C9518BD4ED2597D2CCFA9637510DA44 +:10F10000FCAF6712E63545DCD7F4BC2EBC3A1FFBDA +:10F11000635EB77E7F32D625D47A6AD16ED7E63B5E +:10F120001793DD9300055F9023B88FED1FAD2FA8D7 +:10F13000CC8AD717E45F667DC175599791EF7CD56E +:10F14000FA795A20814E2A8BA90350DC7F1DD96D94 +:10F150009CEE92781D8A4909117BC2FBFDBD776741 +:10F16000168B1FBECAEB9F1E4E4EC2F3175C06B62F +:10F170006FC325B33AAD5CB7BF266B0CE81586C7E5 +:10F180009FBC701B81BAC79FE83BF03C8450BDD543 +:10F190000BFA50C4ADC4F8BFE2F1D44BE59FBBFEFF +:10F1A000C9FCF36D722324BE77A9F9BA4D14060980 +:10F1B0007CA5E583FEDEEB4FAE6CC8F2AFCF42B963 +:10F1C000E51B81798F4B944749A5545E83BEDF636D +:10F1D000F480FF61E2FB8BC87AB7CA7F9FFB700E99 +:10F1E000EAC34FCCCC1F11FBA0C4FA1FEF17DE7F80 +:10F1F0009FBDF817A7FF4958CFC90A1FEE7B78209B +:10F2000099E995D853ACCE48BB1F48AB4FC47E1686 +:10F21000F1BD4E21CFFE45F2F4B57F923CA5FA1523 +:10F22000ED8D7EF3BABDDE0FE177CB2ABB7D3CDFEF +:10F2300085FB39C4BC82DDAC3EEF6D8E3F71FF595A +:10F24000AE7733B37DBF033C9C7DC764823C6A6963 +:10F2500029939F0D7E2BE6211A3A585D4EC34A82B0 +:10F260007103B1EF775646200A72EA8177AD787E56 +:10F270006C43E7F6D602AC5708A09D78EE1D76DF0A +:10F280009C113809E307574655F98EB28B9FAFA9F9 +:10F290002EC5F9A2DFEF30AAF75319B2993F2FAE6E +:10F2A000BA6CA1B7A99F43DF3B5BCBEACA830E9F31 +:10F2B000AD02EB14583C3DC9D38D71F0863DA824B6 +:10F2C0000816B9C2F37BB3916E1AF65494E0F90BA9 +:10F2D0001DE6123C47E83D2BFA6B67EFC90C433C37 +:10F2E0007BA93BF017986F7269F83AB057F3E8774B +:10F2F000209E7E76F77525185FD4F09DE0B7F83E26 +:10F30000DA3B4CE166A9871F37EA997E147AED0C47 +:10F3100018C74ECC7BB03AC3AE6964BEB5A76D7555 +:10F32000A8EB2F77644E3C03703E93A5F03C39CB9D +:10F33000CBE79BA8375BD09B0EF3795E7E1AAFA715 +:10F340002021534F1D45C1B7E7E5C5FC445BE4E50B +:10F3500093BE62767381CD807491DCCAE406A17499 +:10F3600001F6FAF858F704D8BF36A83D321EE0354A +:10F3700000C00F312E12FDE148C87FA429E321FF10 +:10F38000F1D88A51074C0E8847755F0DA8F1B4D9A2 +:10F390002AC1559D95E12F82FA4AA2341601FD57E4 +:10F3A000BEAD67758F6B9350DFB7E7D661DDE3B90C +:10F3B000778DAA7D46BDE43459ED82B85341EB7F89 +:10F3C00062FE21798FD4673DEB427022C6B0FE10F9 +:10F3D000C74A6EED0E95435CE641899DC149672F92 +:10F3E000B9209EA0C86077CCED64FBDFE7B6D92BCF +:10F3F0004D284F2596BF19EF4039A9ACBD5E067F59 +:10F400004F692278DEDDEC6C76DEEDE0769B0C78E1 +:10F410007FF96B5D9F79B91BB27BEAE8005CF5C6AA +:10F42000D821281D10F944513F27FCABB87CE5E7F3 +:10F43000C20B7DA4B5637BD9AF5C1FC5ED780D1DF4 +:10F44000F7F79EA06F41CF2FEB09DA612F4B26DC37 +:10F45000C726E8BA45EC2BF89AC585F3787DCE89A6 +:10F46000757F19C1CE8114F99830ABABD247D76400 +:10F4700021BCA2D78460DD7BEC724331C6D31A7005 +:10F480009CB5ECDCBABCD681ABCB4BE16A230082E5 +:10F4900013FB96E4015F86281D0CEE830E8AB35998 +:10F4A0001D94B23609F1A66CC013BA89624F47BCED +:10F4B000298F30FC1466333A17F96011F7CCCC0E63 +:10F4C000ACCC1E93B0FF6C8585ED3FE3FBA4935756 +:10F4D000BCBB0BF6753DC6E3CF075E1A86BF9F71B6 +:10F4E00061AD22411CEA82BD260FFCBD07385E9348 +:10F4F000956E62B326D2E701ACBF2DD8CFEA0815CE +:10F500007E0E96B2D6B11DE039362D8075C657B73E +:10F5100044F0A7275EB29DC43C1FB58B70DFF8E9AD +:10F5200017246117A9F4A1F0D7B47ED88FB3FF7761 +:10F53000FDAB27E372FA32FD2BA2F633E3FD85DF44 +:10F54000A8F52334EFF767FF105F485567F302C74C +:10F55000BBD0EF995C368AFA9BF8BE6F1236C3FEB9 +:10F560008CC9504BCBD68375489B248B17EC246DEC +:10F57000FD51BC2E88340E6175298D23D9791E8DDD +:10F5800057C255D42799A13E25B10E3699D5179962 +:10F59000A13E85DE6FEE779FB8A709BEDF7E9F4D47 +:10F5A000EC136771FB6AC2F3163B701F79EC966C23 +:10F5B000DCF733A19AC50353FD0619E8F2F9BFE958 +:10F5C0007C207763946FC1BE4A1DE47383BD65A63A +:10F5D000CFA1EE25BE4FBC86F4B94F5CD447897CE1 +:10F5E00071E6908D12E89F78DD4AB067FF387CB7EE +:10F5F0007DA907E3CDF13AAAEF125C67A590332607 +:10F6000035FE527CAC5FCA4C03DA19E972E029CCB2 +:10F610000B6EE936037FEECE2E40BC359787F11C8A +:10F62000E4D4E2368CE786D37CE7B29D3DF423E652 +:10F630004736B1F59F87FD6752CF77CF2FFA732EEC +:10F64000D853955D4646879A796C899F5343BF434B +:10F65000AFBA1C867FAFC6BE15575D8EA4AAE31352 +:10F66000DFEF6F9D821EBFCD6ED7D257A892E3E722 +:10F670007D7398D53FA9E9EBC0AAEAD127A92C3917 +:10F68000B8CA8FD7F366A94307754AE6D86C90804D +:10F690006FE6B4DD08E7999C4F8EE5C2F9276FE766 +:10F6A000DE7513B69DB1F7A17D2AE769D61E1C7BD6 +:10F6B0000CCE43F95BCE889BE0BC93F3F0AD4C429B +:10F6C000B2B615DC142A867D26D135DDA09F4A35D9 +:10F6D000F52E9A731BA02E13CF99B0327C66F0BA28 +:10F6E0005852C5ED77C854D176B3BBC40BF50C5650 +:10F6F000E2D9D30DCFB38DEC7C07C2EAB09A07E70D +:10F70000B3BA094EEF249BC7B3493404F4DB9C6FB2 +:10F71000C7F7E3F27A8F91E7B1D8F78F3EC7F6BD0E +:10F72000897A5F426C3960F7583D44D516E79E10E0 +:10F73000C59603E71C348B78216FFFC112B83A27B6 +:10F7400041FF1E9D787731FE8ECBF3F70E82F54E8A +:10F7500036A8CFC116D79772197D9CE7E7456EB3DF +:10F760000426C138C792664F82237867A65518ECE5 +:10F7700068A73DA50379E4E474619FC1E667AFF231 +:10F780004BF0FB29E2BC466740C1780009B4EB406E +:10F790007F3A4FFAB1AEB0CE14CB55287D194D81CA +:10F7A000E9399057AC397E17E615338FBE0F7520B7 +:10F7B00047F56D1352405FE4F3F333A8E317A2ED6E +:10F7C000435979E8F7C5CF771D2CA17C983A83ED92 +:10F7D000A79D423A148CBFD8D8FEAE49A5F9DE6683 +:10F7E000FABDA9BC8E64D2317F0AC40126DD16554C +:10F7F00058FE26A624D66D882B71E93D897C709D24 +:10F8000027A14DE05C6875FB06AFBA7D53F9D7437D +:10F8100012DB0388AF1EE0F8A214C5FDD6A1B1C467 +:10F82000C6D6C5EA139FE67EDB301731E541FDA45D +:10F83000430A815F306C6F26E665F696136CA7EF7E +:10F8400034ED3025AE7F83CCF2BE3C6E2E7EFF09B8 +:10F850009E815E7DFE9D748457BA5546790A117566 +:10F86000A0B7B22C9305E4BB8ECB79B13F7D628A01 +:10F8700009CFED6D5ECA7E37427B6E69B3DEF60A54 +:10F88000E0B1F96338928AFAD9C986889C02F8A255 +:10F89000BE8FA3471E0BFA81F1AE01BA1FC37E9F34 +:10F8A0008B52F9A0C473E39B9D6CAECDF7293CDF6E +:10F8B000C77E27A428FEBB2194ED687FB02909F2FA +:10F8C00009CBB7E5887512C507FDDD44B4D97EAF15 +:10F8D00074DE16E7A51252A1E0F94492E8D784ED50 +:10F8E00047793FA9EBF53F017D0C4AA1EBA1D7D7A2 +:10F8F000723C48DC3F958F6E423AB1063C4027DEB1 +:10F90000A4BEF71F75E4303B62624AB90BE2EBCD4F +:10F910006EAF0BEC2A011F715F8C2B9E8BEF79D39E +:10F92000FA1EF7352EAF3BF83E68EDF3977364F59A +:10F9300077F5745CEB377CD7A9FE6EFCBD9CBEDF0F +:10F9400013F7457FFC59AF32E03306B729BC6E96FA +:10F9500014A9EB5D48B9D7C4E4BDBABE65B2B4D250 +:10F960000DFC799DA9BE2B4ADF7F9DD3C96439F078 +:10F9700047C837BC3EBBF020F06735FC30011DE7BF +:10F980007A125903C472BE22F013FB409417C78049 +:10F990008F1A748121A9B4FD89BE6DD0D27CE4AFE9 +:10F9A0007772C6F49E9FA0C3F83C29FD01DE05FDD9 +:10F9B00069E72DE880DCD8810582DB4804AF2EC2E0 +:10F9C000EAB2A9FE62F5D79E9C9E7551E29C646ADC +:10F9D0001C04FAFDF5A610CA9FC9F61F611DDAF9CD +:10F9E000BCC03998D7CC919FE2F942C45583F61632 +:10F9F0009DEFF97FE57CA18208EE0B3B50D87BBDE3 +:10FA0000EA913F36A8EA91C5FCB47C2CE61124ECBF +:10FA1000DCA8095DDBD1BE0BCEB07A61DF4810EA0D +:10FA20006C4B319F8675CBFBB85F169258FD702FDB +:10FA30007BB1FFBA65764E41BD8D9D1F24CEA1FAE4 +:10FA40005E81385F88CD9BCA2F7EBE10B6DB6B3CD3 +:10FA5000E8FFC5EDC6F9CC0EBDB6D0D202E735F64B +:10FA60003E6788C5F7C85EA387DB89A8BFDB93D94B +:10FA7000773E31B33AF904394EA4F49EF3CF36EA17 +:10FA8000993DE8CDCD677941D95B06F8D802792B4D +:10FA90005DEF38E4C0F4C0E85CDA6F7EB12F177E0A +:10FAA0009A65AE81C519295D6DED26506ED7F8387F +:10FAB0009C0B7A1D697C4B1E88743516FACF1CF698 +:10FAC000293B2FB487AEC6E53A99DC0421F86D7C5A +:10FAD0007A322D3001C669B777BCD7500A794B23EB +:10FAE000C25FD4336AF937613E27F56C3E0E381F8A +:10FAF00099CEE7FABEE67329F49D48471984D1717F +:10FB00007F740EFB069247F5D0F90012B81DBE1B9C +:10FB1000A7F735DE56DDC03EE6ADB322DE6F9DC5EC +:10FB2000F231C12466A7425EC69D0EF127F6FD5B49 +:10FB3000D732FAB8D56C447A99D6558FF91752C591 +:10FB4000F2295EFA1FCC6726F14D849F58B9D93649 +:10FB50000DF781CE98AACEB7CC344DC6FCCE2D84FD +:10FB6000C5D36E9DA157FD7EA480C34CB2FE53A8A1 +:10FB70000F99A9F9DD482D5CB4F91A018FE6F26FEF +:10FB8000E6FBFB72E3799D219799D769C945F97422 +:10FB900069799D83FA189E23F09A73E1D6A5942F74 +:10FBA00086FCB818CF5B9F98BEE8F10DB4FDB32D6D +:10FBB0005760FBB5F43B961F85E78F1562BB4AFE85 +:10FBC0007436F04151D9AC29704EFD41331BC765E5 +:10FBD00009B4C3EF8EB846148C0297ACCA10C37E2A +:10FBE000D78FAC1F0D75355516D63E52F25FA3B0B8 +:10FBF0005DC0DBA35EBC02DA07A54F67F795171A55 +:10FC0000562445E0F7C5AA5259FFA9A39ECA8438D5 +:10FC10004155256B0FF356AC1D08CFE5CF66F7A510 +:10FC20008F7FC9ED63616FF939BFEFF51D6F81FDFE +:10FC3000667EABE4857D06FEF2E3EC5C3113AB4BF4 +:10FC4000F0FB4A143877B2D2C7E27B13AC4D6E900A +:10FC50007F37060CA510C7B559F35BE07CE701E5DB +:10FC6000156300DF13A81906FA8FF2D5F3C0CF335E +:10FC7000AFFC343705ED10355F09BA9D26F8A94A67 +:10FC8000CD37541E74313CAAF9818EFB0A8E7B95C8 +:10FC90005A2FC5E5BB866FB5F4D8AFDE276A391891 +:10FCA000D74F6B3A902EB309DB4FB40DE894F1EFC8 +:10FCB0006F617E06B9DB03F7F324EF1558A8D18FE7 +:10FCC000FD20E607660F19D57B5EF04711F6229BF3 +:10FCD00081CD960EDF65CFE97B3EF83138312FFAC2 +:10FCE000FD13089F356C3EDBA446FEFB22CC2E178D +:10FCF0007E6F83586FA77ABD6516B62FDE45A8DCE8 +:10FD0000C1D87DC915DF34EF20D7B3334CFE078D42 +:10FD100032FC4EE15CC4F36D24F41CD837EF58027A +:10FD20007F84F9E8E4D0FEA804BF0FE2C37C32C5AB +:10FD3000E3174CAE33BC887969E1D1D08F5CD5CE66 +:10FD40005B0B871EFC74A37DE6E6BF23185F9766F6 +:10FD50003DCDFC770462254655DDE9911A56572BB7 +:10FD6000E675442245A827250BE651E37127AD7CB3 +:10FD7000EB677F9CD0CF629E77F3FD595FCA4CEE54 +:10FD8000DDAD8BE03CF3AABBCD00C7F2BC02763EF2 +:10FD9000109F7F737908FB1964A9CF3C71799E2C61 +:10FDA000F260A4CF73DC3CF956E08B3B4DFCDC3AAF +:10FDB0000D5D104DFEAC3F3A11F1BB4AEEB7C4F3F6 +:10FDC000A99A73E2E698FACE9B4914BE59A9BDF1EF +:10FDD00020F2693768E374D7B1F8D50D3C4E37A1EE +:10FDE0009AE127754532FA75A9A5471532BCE73C5B +:10FDF0006B81AF0B8E40551EE635A263208EF0E678 +:10FE0000989F611E499C1BA9859F3F4F16F1C64BC9 +:10FE1000E297FEE6FF078B7F3A7CF713A91BCF839F +:10FE20001BEDE6E79192403EF093DD965F01F1070E +:10FE30002A772F5E0467141E51FCEE74066E87F756 +:10FE40006E23FE8950EB9D5A1DD0B3F83DC1F8F1E9 +:10FE500032EE474EE4FAFFB367D87EFD2ADFD04783 +:10FE6000C7837D7A584FC21EA81B67F0F96CAB0E92 +:10FE7000F5FEC23746BBC07EFF80D3E3904DB2EAA9 +:10FE8000770887862DAA733D86ED4C55B587776434 +:10FE9000AAFA8FEC2C503D2F895CA17A3EFAF0280B +:10FEA000557B4CF73855FF2B8F55AADA63A3535473 +:10FEB000FDAF3A355DD5BE3A76BBFA5C9290AFBBEA +:10FEC000281D7E3F81C1E3DAAFE6A8FA9F49997405 +:10FED00018F872DE7A56275E4196A8DE5FA2ABC3A1 +:10FEE000FA6BD2C6EC9C46FA1FDF17AF607D1AB5DD +:10FEF000EFE1A701166E52DB41B55D1BD6802CEEFB +:10FF0000751E86C6DED1DA37431C35706C3679240F +:10FF10008FFFAEF895E44AFEBB345ABCE2F9029F6B +:10FF2000BDA5433F63D91BCCFE5FB68BD5DF1592D1 +:10FF3000C10370DFD9611D094B70CE42E3C6F15297 +:10FF40008F9DA3858BD1A5C6B3D9A3C67352911A31 +:10FF5000CFC95E359E0794ABF16CF7A9F19C56AD05 +:10FF6000C6B3D3AFC673C64C359EDD01359EB36AAA +:10FF7000D578CE6954E3396F851AAFF9A1C5AAE7E0 +:10FF800042AE0E6C5DA6BADF2C759451494AE6F973 +:10FF90006BF17C89C16DDFEF933E04FE43F43FC6F5 +:10FFA000CF8D58CFBF80E21FEAF9BF20EB0F414A47 +:10FFB000564B070D9D1B30EF76B974F0761EB75F78 +:10FFC00005FE2FD17EA5FAF2BDBC3168E7BC0FF269 +:10FFD00061E610EE97F8FBB67384DC4AB42B12FD91 +:10FFE000EEFEE4592F3DCAFDF07EF5A8C60F7F074F +:10FFF000AA9FD05E5F8F71AF599CAE3F875B632134 +:020000022000DC +:10000000EEFA2CDA07EFD08994D379BD03F31E0101 +:1000100076C2308C93DC41227A3C3F1C2A4675A87C +:10002000BFB04EB386DAED709DCBED87F93C8E62A2 +:10003000340588C789F193BC74F86E7637EE33FBCC +:10004000BF17F44F2B008000000000001F8B08003A +:1000500000000000000BE57D097C94D5B5F8FDE6B5 +:100060009B2DC92499241012026126210B908449EA +:100070005804451C9660D4806193C58833498090AC +:100080008504D0D7B4A5CD40C2A28536B4A8A8A80F +:100090000302050B345804D4688745A44F5B636B97 +:1000A000AD4BCB4B0045F618B4D23EDFF37FCEB953 +:1000B000F766E6FB480AF6BDF7FBF5F7FBE3EBBB9B +:1000C000B9DFDDCF76CF3DE7DC3BECED38C612196A +:1000D000FB06FFDD717DCA988FB1DE8CFD01FF84C8 +:1000E0007A231C455607E4275A1D0F3D069F8E189C +:1000F0005879B30DFE28847E46436A2CCA9E96DD4D +:100100005D3F2BA13163AF2A1E0F1B0EBD265A5D2A +:10011000DB15C68624316B622C1427F853A64532B2 +:10012000D6C761A07AF04F61F18C0DB6D2DF6C4F6B +:10013000DFE6A531A9F8973FB628FBDB8F9BEA7075 +:10014000273B4604EBDF68BD6673F3129C6747B537 +:10015000CDB5D5C9D87B5804ED9EBFCF1250A3189A +:10016000BB62B2AD55A219FB2062DEF1DE0EC69E67 +:1001700009F764215C66CFBA6B35E69523718EA5CD +:1001800030BF2BDEB6910CE66DB17A5C585E65F53A +:100190000C8887255EEAEFC98856A1CF220E7FF82A +:1001A00023BBA8DBF9F3F94C50F8F89F847B46E3B6 +:1001B0003A8E185A935D080F63EB486CC76CBDA963 +:1001C0009F4B660E979EE0303EA27F31AEABCC6275 +:1001D00071A9D0E77885E3F54CDC83F36AE0CFF9C9 +:1001E00086A2F880AA99F79D346FBB7740620AF423 +:1001F0006F12F3B6F6167077641545F63CEF06EC11 +:10020000BF17E47EA0F8B73B392E317FD017E37FCC +:1002100014F216C3D5F7A643BE23DBE0DA0A459BEA +:10022000C3A1EB3CC6DE11F07EC604F958FABE1637 +:10023000BF2784F3F6098F1BFC0DD0BE68FCCB846E +:10024000A7E717DB683D5EE63033985F29739B7143 +:10025000FE9F8CFBCFD7DA001FF31D1E0FC2EDC12E +:100260003843F27B340FCF90A9306F36E6E6E89F33 +:10027000B175063692B16976BE84F9026ED399DB08 +:1002800084E3CC641E138EFBFBCB663703FAF83D88 +:10029000E098C17C67311F7D9FC3FC94DECF025480 +:1002A000FF01D646F9772372FAD7C1FCA63E919199 +:1002B000C60C1AB8FF1BCE17E8E5C15E9C5ECEF6F1 +:1002C00041B86FEC7D53F43B55D00BF0EB0FB11FF1 +:1002D000E0D7E1B929217C3391D30B33DAD3FE1176 +:1002E000DFB47646E5B0A19877DB1261FD770A149A +:1002F000DEE9AE2CC475E6AB36D60BE0DFEA50FD86 +:100300001618B3609CB72FAE0BFE45FA004F53DCB6 +:100310002A433CBFB902BE40BD3773553FD2C49497 +:100320004D93CE61FBC271D31BA361FD93BE6E1BC7 +:100330001E80B4A09FE9545B261FE31BF8DF976C77 +:10034000F3C41848EF4ED8676430FFBB076ACB0B85 +:10035000B3206F0DE6A73063B01CC63D8C7000FA69 +:10036000A9FB73EED86321ED186B52916FB63A2258 +:100370007B7D3A04B283D9E06F70DE6A71B4A71B4B +:10038000FE91E957F5AEB1C78026EF51DCBB1C44A6 +:10039000170E33D27F8991B9BBE3BB8B698AA01F4B +:1003A000C02EC8B37BC55C3B0BAF9AAFC07ADB1CD9 +:1003B0009EFDD8CFD2C99FCCC3F53123FBED308051 +:1003C000DBE2DF01DCA0FC543D403E03F8B3DECAB3 +:1003D000DC16C63EADB753FEB3FA044ACFD73B286E +:1003E000BD589F49E597EB5D9467CEA2D7B0DF92E9 +:1003F000B59F1B3D598CAD099378E4F35826E878F6 +:100400004DFF917F72C1786BDE3651BEBCB9695227 +:1004100004A4CBFA9F5A1901DF97ED525CF8BDB2E4 +:10042000C56DB6211F1DF3AC46F259F876DB1414E6 +:100430003BD5D714E601169A3DB0E82D1C6FC41FBA +:10044000CFC423FCCED68FA2F99CAB77D37CDC2D16 +:10045000EDC7E3A0FD85FA02CA273A8BDE45BA74E0 +:10046000B3CFCD587FF2EE76631294E7BB1537F227 +:10047000F75837F3FB017F9B4C7CBFD804FB05F298 +:10048000FBB8EC69CF3CC4509E7B3EC6F166C69675 +:10049000E6C7C1F729A3BC46AC37EB6BC6302FE9E2 +:1004A000FBC67CCDE1512DF072E97585E074E9C0A1 +:1004B000907B6F83FE5E3FA13215E6D579CD40F388 +:1004C000EAFC20DC0F3B5357BDA52FA5F661364C47 +:1004D00087F46159B83EE804D69DA9180D75C0FF90 +:1004E00017F67C2701E12FC7BD10DBFCD78F50DE4C +:1004F000FD85CB3BC69A3F7D0AE561BF04D7A3903B +:10050000BB6C62B3893F596D04EE878BCDCCC3F3CE +:100510009E2198BF10CE1E2C82FCC8BD49E3917F5E +:10052000703C4746509EA5EF7D22E5FB8EE0783B70 +:10053000F63CD9F98A03CBFDC4CFBBF63ED3F769AD +:10054000C855ED5B158EF37A15D6320AF8E3D50D52 +:100550001124B75E35B94ED6A1BC7EC6E6DA0EF5DB +:100560007EFEE3EF9E3A84E9FAEABCEF421AE38C9E +:10057000A57ECA7EBA6830B687FD9B25C23A7F71D8 +:10058000500984E53096BDF1F0CA44186FE8E6766C +:10059000435F4873B7290D980EE95F7002F7CD3EAF +:1005A0004E07C17DD86EA79A846CD7D7FFD11DB4F2 +:1005B000AF6BF7FBAC8D9F8FEFCB82FBFE60A5F995 +:1005C000FC0A27D2EBFB791E824713CDE3A596E9FF +:1005D0007FB89FE13A40A3C0797BCD2EDA6760B93E +:1005E00026C85FDA9FBAE55158E301836F0BED43EC +:1005F000255CEFB854E47B12E9A51AEAFB205F9D65 +:10060000EB8BBA15CAABFF32D00594C1FA3F7B67BA +:1006100001C263F1FEC726F5857A97C6309702536B +:100620002F7FE9EA246CC7FA3386AC7D697F43FCEF +:100630005C68F7A3ACF123904E8AD4661A87D5F094 +:10064000719E10FB176B03E0C40B92837A3F82CF3D +:10065000F83DB625E670120BE2A7A66585D308ED36 +:10066000877BAC2E15E9DFE94BACB505F743D8C75E +:10067000463B91B4CDA25FFBF4E4A26FB18F99C564 +:10068000BE24FB7BC2CC7C61D04F7FF8AEE03E6BDA +:10069000E6FBEF76900F48BF72FF8571EF728EA078 +:1006A000F66E94A749B0D9E6C23C939EB0903CBF89 +:1006B000D9F1A5DE5413CEE591D43F66C735BCD63B +:1006C00006EB3D1EEE9989E3CC17FB3733BA1C28A5 +:1006D000A7F784BBEF73D27ED8918C6B80FD712E0F +:1006E000E617ABA04FA586E853D69BDB1F3F0C77E0 +:1006F0007BB0FDCDD6D7CBCD655F1A582ED0C1B219 +:10070000C72C7E06F36E40F90AEB6A881C694539EE +:10071000C08E19AA8EC37E793B6FD9D5DFB2C83C93 +:1007200092130D8C750BAFD7819F3D203F0220EFB8 +:100730003DC0D763AF75A89CDE5B8F460F4779C974 +:10074000DC91403F775C33304FC87EA6EF07F05511 +:100750008FEB1BC7229827647F74B31833F22DB335 +:10076000C5FE73EB16F31F23F037A6F38308947FBF +:10077000CBBECC2339D8D3BA5E13EBFA35AE0BD24D +:100780004FD28A36201DDFFE85DD88EBBBDD383594 +:1007900019F51398F71338EFB15F18B4F3FE3A5C0C +:1007A00093BFD9F93FAC309F01F9F173B31FF9B191 +:1007B00005B7398063CBA22C3FF2FD0133CFFBA2FA +:1007C000CCA49FB644321FCA9196A9F17E9F13E52F +:1007D00021E3FA6B6FC6CBC344FB39F1D4BEAF053E +:1007E000408AF2E0FE70D17FED5BD958BE2289E4E9 +:1007F0004883C9BF3605FBFF81EADA0E78FBC06F7C +:10080000F099804E36C604EE57A1DF8D9FC7331C8A +:10081000E7031648AAC171CAC349EEDE66303C3808 +:10082000D586F5DC89B100EF03FFAD92DCDF980BD4 +:10083000791BC9EDD9CDF07DE354776238F63335B5 +:10084000DE40F351592D7D77F2761F9978BDB902BC +:100850005F1F0AFC005F13DF7BA64418916E4F3ABE +:100860004BDE7512BEDD890ACCF7A9B234867273ED +:100870006EC55D4EA297A627487ECD163890FD61C5 +:1008800003EB48D47FF9BF39F3B787213E679687DA +:10089000B5C30EC93E285F19E980F6333D6AC00230 +:1008A000F294CDC87777E9672938AE9BC6AD6E1E46 +:1008B000947A26849E4B2C2027A0FF43619E0F88AC +:1008C0004F0FE552F921504EBE017E3A5596B617AC +:1008D000F98A95C9F35FA014F1F07A8795F4CD9E5B +:1008E000E8A101E13F54D029E26539C73BE85D94B6 +:1008F0006F983D98CE25CF9938DDF8F685115E0BBF +:10090000A65909CF9DB3C3B758A0FC4121B71A66B9 +:1009100087BB15A8D7F092C56F70D27987EAF95EC8 +:100920008BA47EABCC3C5FF5621AD1D301B37FD7E9 +:100930000E2C7F3D8CE8A12A8A8F5BF54A92A03766 +:10094000B773158EFB9A85E8A02ADC114DE5FF1ED2 +:10095000477432D9EAF91BC20BE8AE16F5822A7346 +:10096000203D06E07B52D0D5496883F8F3D546D2C6 +:10097000BC89E521EF69E8BF15F1E931F372F63D75 +:1009800095CA4FDAF9F827D7F1F18B7F52F9360380 +:10099000BC9D2C9A94381FE671B23682F4BF3FD7C3 +:1009A000A90173149E5F3A1E4F877A97979F1EB9CD +:1009B00009E6DFB6F2E364A48FE295D585D8AEB838 +:1009C00062F914DC377BE2CBE22A60FE103E4E492E +:1009D00071C7A4C07AC6A6787A615A93D5B600F5D5 +:1009E000E0CBE6D667F11C9114E7E983DFAFBC7C6E +:1009F0007607D78F3BD2713F586CE4F421F7D51AB4 +:100A0000417FC7533CFD53709F080FCCC3FD232289 +:100A1000AB95CBBBE53727E7CFB76C3FA0C0389588 +:100A2000E12D8B2955FD39D8CF052510A5A412FC41 +:100A30003CC84F17ED812884BBC7C0F5B3CA9DDA07 +:100A400075E13F23CCAB12FF807695CDAA3B0C71AC +:100A5000CDFC669C7F253307EB3B8378827E084F75 +:100A6000CCF6E779DF07F857EC1A9487E780CA9845 +:100A7000433FBE8DEA413BC927EAF579B99EEBE7D2 +:100A8000C3D77751D0FF4549FFB3CDF25C4EE35F4A +:100A90007EB90F8D7F61AA3F1DE17F5911F576590F +:100AA000783DA00623CEF3979C9E1E37F90CE17487 +:100AB000BE6744CF9571CD23112E520EC11C7C060A +:100AC000A87F616F12D597728B153186ED2AF726B4 +:100AD0006EE5FA993897E244A17EC52F78FF9847D2 +:100AE0003E3CFF4292188FEBC77AFCE9D75B9C62D1 +:100AF000A0F53E2EE577A4E47357C254807FC62646 +:100B0000B3A6FEE548F3836EE877905FFB5DF65F82 +:100B10009EA2907E364087B7BE6AC7610BF2D3F3C0 +:100B20008CF8553FAF9A147EFE7BE1852E3CA91CC4 +:100B30006FA0064AFA70703DDC8470FEB00B1F0F88 +:100B400025815CAD4418A404E17320D79384F2FF9F +:100B500032E6715F88817C16EA411CDE322FE1ACFF +:100B6000A7B3951F2E486A83F64F09F80042FB2071 +:100B70003D76E92F26385F64E1B9B27CD899343CE0 +:100B80006FD60E82ADA06B3D0B36E55A919F166E67 +:100B9000CEB59684E0A161E7B0130E80F3C59D4603 +:100BA000178AE506A3FFC7A84F37EC549B7D8CCA74 +:100BB000AD08DF8BB623BFC37A0B36C7E4A1BE2CCA +:100BC000DB2FDCF4F0A0B210B80FD9A9C54376B37F +:100BD000363FF49036BF0D6543EF6FDF2E37A0CD63 +:100BE0000F3BA1CDB30EC016E041B5723C1D1CE514 +:100BF0003AE1003C0DF0AB2EFC34C0366DFA64D403 +:100C00002F36ABAE34281FB0BCE89E6CC87FB679D7 +:100C1000BE0BD15CAEFA167F1F7058FEF1A413B85C +:100C20001F5E60CDEF4F063C2C68D960363A70DD10 +:100C30005ABA3D6010F4FA02B7972DF26BCBAFE7CA +:100C4000EB15D25E9A194A4F7ABCC3B8F7B9614224 +:100C50005575CB869D812DB3BC10081D6036BA79C1 +:100C60008319F5B61B8FE3E3F462733B101EDE516C +:100C7000BCECD6BA09ECF430F863DDBB9370DEDE71 +:100C80001F29A437787F95710CF781F67D73EEA646 +:100C9000F4BE025ABFB4CB2D6C51029190B78F7243 +:100CA0001C6A8376F3FD8A0BE75DD26809CA33F8C4 +:100CB0005FD93ADD3C368694C3FC171E3AFC3705F3 +:100CC000FA2FDFAC6DB708E42CCAAF8A6DDF58424B +:100CD000BFCB73E3AD2D5B545CF77C397FDF588667 +:100CE000EBBA955765BD847E730633B06FD4F62E8C +:100CF0003A8BFBCAAD1B793B10975E5C6FB5CDECB0 +:100D0000C0F5565B592002E67122D2ECB6C3F7ABB0 +:100D10009B22C91EB6C002FA641EA52C2C0FDBB99B +:100D2000A2B1DDA7EF70BB58751CC777F5730A9D9C +:100D3000A3AAD18889F9E7797E110BD03A904EDCCD +:100D4000A1EBF36BF3AC899FBFAA8C81C3088F0A18 +:100D5000D6C6CF4F8047B7841FC0AB0AD6F9412C07 +:100D6000EA5BBAF6CCE5C1716B6C5C7FAA39F48D95 +:100D700025B45C9E03E53955DA699F4B2F0AC7718C +:100D80005629EE27AD30CF5542BFF66D0823FA9DA8 +:100D9000BB85EF37A0C7A6235C366E4874A19E3191 +:100DA00017F4F230E49B45E1540FF45DB2AF748068 +:100DB0005E8DF6F68D31CD01DC37363EE6243D1AE8 +:100DC000F45F824BC7FA30FF5605F560AEC76CDCA6 +:100DD00090417AF8AB729F5ACFF5AE6EF4622A67F3 +:100DE0007DB81EFF112E25440F4E8DF7A4A586ACAD +:100DF000AB6CA53B11F79DB2696603DA9D58F9CD3E +:100E0000F90DB60B3DB203D68FEB38A3141D378412 +:100E1000E8A32353F93E3272BC7B87A847FE853294 +:100E2000C3D447EFC0F11E373870BC2E78BBDDE964 +:100E3000388F331BC2F290CE468EE7F69F93B95C93 +:100E4000BE470C676E3FA477887EEF483568D28432 +:100E500070A03FE8E74C3EB73B470E2F227B1BECD0 +:100E6000D524E7F5EBB847F453662EFAF7DBBB99C8 +:100E70008F840F9BC8F585334B94AD7C5E805FC833 +:100E80008FFC6918D9E9CE88FD47C219E86604D9F4 +:100E9000DB85BCDA20E8658389D3816F113F3F058C +:100EA000E985113D6C14E7ACB902BF6C3DD76B818D +:100EB0005E389CD7270A7A61ECEF480FF90EAE67CF +:100EC000DFE47909F05E9ADAFBFA7393C43733FAF8 +:100ED00047FC23FF46F5C13D077CB07F56FCF2B1CD +:100EE0002806F5CE199BE25DD0BE6AFBAA2837A47E +:100EF0009F197D517618FF9C5F2DF077036FBF809F +:100F000037DAD715903F8BF14F07EA3B3F9A82EBD8 +:100F1000FBEB76931D4542CD4E0B9D9F16EF5F4434 +:100F20007A36E4DB797ECDE72AE60F69EDE0153FFE +:100F30007F2CDE41F0F6251912300D243148176F51 +:100F400033B902685F7E4F75C130A03777ACC6F900 +:100F5000E9DBE33CAE01BE6B9A55AF39FAFAF21AFF +:100F6000215F6AF6FFE873B4EBD5E8ECEEE5C2FF6B +:100F7000A0B7BB37A546F6FA140DCCB7B05B500F3F +:100F800002B8B802C8B7309F3422136EB76DD8F5D7 +:100F9000444E3BEA0BDBDE8A52B2827677E997E871 +:100FA0006C2E7D0EED9A3DF1E36561870DE28BCBF2 +:100FB0002DC7210565001CD0795A650A44DD06F06D +:100FC000A8DA62223953B5E7F91D4F219D7D68A14A +:100FD000FDBC72CF1BEFDF8AFAEE3E53AF42BE0C70 +:100FE0009B121FC4538D83DBC9245E2A7EF586D9EC +:100FF00091CDBF2F8F0DE2A772DF6133CBBE1E8E66 +:10100000139A0F9BDB6CDDE0A9B97D12D989767D3F +:1010100065463E38F7BAC2FA38AF6F5FBEE58D2835 +:10102000D4C7104EB82F497C75E14F571FFA9FF275 +:10103000CA70AA67C773454FF85B827B07D17724D4 +:101040008B81F1CB3FB2F80B11AF7B9745E13ACEE4 +:101050001A6B399D3FB32A1EF5BA72932FDE4E29C3 +:10106000FF5EFEECC3447F0B95DA787B16D177A246 +:101070008174065F22AE6FFEE699B4BE05CC43F4E0 +:1010800057FE8C5AE487F44B232BD8D70D9FF41DC1 +:10109000C8F9E4EC56402AACEF2CDA6D506EFC5ED9 +:1010A00015E7DC25B47F3F2CD6CAD852CA7F29F475 +:1010B000B64BA95D7E656BE879B166DB9A56C4CF05 +:1010C000F9FEEE3E384F80834FC04BF906FA55DFEC +:1010D000CDEFC3F1C31CC691A21DECA313F03BD608 +:1010E0006F35B9D1EE1DD24E9CE7F8F80F89F1614A +:1010F000DEE1785E3D1BCFF576FDFA0A062AD2DEE8 +:10110000D6CA42E9AB27BEDFF608D1D517EF71B9D1 +:10111000B2D83FB580CA5B4D813E58EE3F3C43217B +:10112000B9606181EEF87A9B49F0B5B61CE6695466 +:1011300042E1FB3AD7431780DE1508E1E320DD9852 +:1011400083DF69DD3F15EB6823BF98F4A72D14F208 +:1011500040BF6EBD7CE83550F8E3847C90EDD9E665 +:10116000EEFD3941B9E0A371AB603F413DA3EA43D5 +:101170000BED1B557B4C45089F0BBB8FBE3F17CF1C +:10118000A1CD928FB5F256CFC7E52F8EE8968F2F5F +:10119000ACCBED9E8FE17BB77CBC4E21F9F63F9541 +:1011A000B7B0D391DDA0277E5DD883BC1D3B502B0B +:1011B0006FBF6459D1B761A1DD3B80F0A383AB84DD +:1011C000A75E7EBE9FEA20F8EAE527C3D0881038E4 +:1011D0004AF849FA64CC43E374D1B1A45349C75DDA +:1011E00074AA5FAF168EFA72C34046F3297AD9C447 +:1011F000ED672D0AE9DBD0EE78D270E253376D7FD0 +:10120000ACE97852AFD0BC5F976FD6D577EBF2459B +:10121000BAFA1E5DBE5653BFEAD051333F1F0434A5 +:10122000F52C75F7D039E37A3DC2CFFD3EFB3F3751 +:10123000FB902EFA7598512E9A56325F24EABBAF76 +:10124000A9A4EF5E717444A15EB22A8CEB6D57ECD9 +:10125000221FC3F31DBDCDAB512ECAEF1D61DC4E65 +:1012600072A5A8232A26E49CDEDEA246A13DB6CDC7 +:10127000CF0ABA8F136920B8B6B19ECAB9FE96AF2D +:10128000DA92EBD01EDAA4BA804C58D98A5951149C +:10129000BFD0927AEF6CF83EFF372A85015C09E7F0 +:1012A0007605E6731B317EA094A3907DC67C8F8F5C +:1012B000817595B6F03882B2755AFC2EB0CD880E85 +:1012C0003850EE68FDFD0BF15C978AE73DEDF70ABB +:1012D000B68EE8AD42C7171E61A7D5F3C516C9176C +:1012E000B92C57D863C8CFB154C8EB7C35EBDED9E5 +:1012F00000FF2B275466817C678BCA56E37A772BD5 +:10130000E4EF418700F2DB62E04B9C8F84CF45E441 +:101310009B8C9EF5928B2FFD65E4F7914E0E7C9C85 +:10132000837ED88B073E4C7F15F307FF94FC31BBBF +:10133000BEFE84D7FF360FE5F095D72D0CE9FBCA2A +:10134000EB6F26A35DF0CA2B163A2F5F5969E1F6C1 +:10135000E6D723FDE88FBCD29FEBB90DAF7D95D3C7 +:1013600046FB6E23E1EBED8166AE37B5FCE749B491 +:101370005777B6C0AA509F783D82F8A7E69530F21D +:101380006B5F79EDAB91A1F10FFFD3F548FFF595B8 +:101390004836FB45A45BA1D7D7BC3AFA79F4E756A7 +:1013A000EF3F6C2E85F209BFFEAF1C949F575EE4A1 +:1013B0007AD26553DBB3686BFCD3C0393F3525A2C5 +:1013C0007D0E3AEB0BDC96F6E434E493EBE1C2E1FC +:1013D0007005E080EB02B894A3DCEF091E97FF656F +:1013E000E1F1F93C2ECF6E61E8FF0DC245E17E844C +:1013F0009648BF55A1F5F3EFAF7F9583F2E646EB34 +:10140000B5A59989AFFF7F59EFE0B47F55FC727A9B +:101410007F71A083C7F5E9E8FE7ABA3EF86F94DFE2 +:101420001BE9A2F9DE24BFDFFD2FBBFEFF1B7C976B +:10143000FFCBAEF746F8FE8DC077A41DFD8A575E40 +:10144000FBAF64F62DD6BDE65F96AFFFF1BAA5BE41 +:101450003E5E759DC885FA6FB1E6F75C4ED23EBA26 +:10146000D53BF6A7493B093F1F4D607C9F9E60AD71 +:10147000247D7342BFF5A41737B03CF243F8FAA9B4 +:10148000E48FA1E00B80C39B09B97EF2271903FD0D +:1014900096417E7C5235C55BE9CF8D13C22717A0DC +:1014A0003E7A7405CC0BFA391A69B0A3AF78623F63 +:1014B0003560C9A1B41DD3E3C9F79C40BD65A24DF9 +:1014C0007B7EBA47771EBACBA12D2F602FF642FF45 +:1014D00059419689F9613E93B07EC8B9F1A7697602 +:1014E00082CB5DACA9D16EFBF6703A23E0743D1C53 +:1014F000FE31DCAE839338271B457D3DDC8CB6473F +:101500005BB19D91C1B997AF97CECBF2DC7B2378CD +:1015100032719E368AA1257C8DFDB89F34A45F82EE +:101520008B84FBB785B7C4931EEE12BE126E7A3C55 +:101530001C446354EF20FCFB19738DC877B70B3D37 +:101540007EA23186E7FBB5AA45C48F7E82FB842F3D +:101550005C46D44FC6D96228EE9239FAC7E07916B4 +:1015600055CC6F92182B1915335281F5261999CF46 +:1015700002E74DF4A1911DF511A37FA513C7E1F674 +:10158000DAFE466E9706EEF685E7517DB719F2DE74 +:101590009F2D646EA8EF4D622E85D767D1B1148E52 +:1015A000C6548CCB8214DB79A379BFDE3ECCBF92CC +:1015B000E393F082C726B45F40BF6E432C6F1F9544 +:1015C00047ED7D06DEDE6D8474402AB7AF77ACB29E +:1015D000D0F9C3BBA67F3ACA8FC2F15ABB71713A28 +:1015E000B7ABC8F4CD74CEEFAAC195807A7149E348 +:1015F000203A0FA9E145D52FA1BD7F6F04D1A37774 +:10160000F5039347E0FCF6C6B9707AE7A7EC1BC96F +:10161000EBCF79F88FF0DDB3338CBE5F48F7F44938 +:10162000877ECF2B8E792FC187929947CD09308441 +:10163000A779EA25B4FF4DF1EDFB1DFA19A7CC50AF +:10164000A9FE14C6E32B596304F9A327FB3E3726F2 +:10165000407F93E1B081E5ED61F6E425307FAFB0E6 +:10166000F7A6A673BB8B1ACE3C2FDA705EFDD35360 +:10167000E0FB64D67D3CAF57D61FAF6C46FFD080F1 +:1016800009DC1E2FEB633FD8EFC274EE5FCD117003 +:101690009179802BD52F5B6B694FC573CF5A53203F +:1016A00003D26732C7E7A54379610A9BB409E1FE1B +:1016B0005D956DA5F97678C9CE1D99E9403C788095 +:1016C000A429BEB0C9E940BB57FBB8E600FA07DA67 +:1016D0009F74BA1A1C84658AC791E7ACF671818140 +:1016E0006897EFC8E57E8693F6B6483C1F96DAAC5D +:1016F000149F23E37AE6DB399F0F68685B7F0B9EBC +:101700003B1F535D5B213FFF31EE77F9C466F52B3C +:10171000785EDBC8F994ADD3C6F130BB8BEC3DA548 +:101720004DE3CC78BE2CB3B9CDB8CE8A0C4F11AEF8 +:101730008B7D0DF01B89719C8C98C1DBE4A538135F +:10174000350AF80EF9C4E888C273AF3E0EA846C445 +:10175000FDC8FCA130CF1CECAF24DAB117E9E55489 +:101760005D2AD93D3709BA2BC43846F44F18DB122D +:10177000713EE1F81DE05F186B4FB7113D87318472 +:1017800043BBC99E8EF4DDBE2ACC807EB6C2959C3A +:10179000AE81CFAC4668FF889185A3DF2043B42F8C +:1017A0005E612CDA02F97E56668C8C45BACA25BA7F +:1017B0006ECBF4E4207D7EF603360AE9A174DD06E3 +:1017C000F2AF48BA60C6D6897130CE67DB9D792802 +:1017D00037251DB5658EAF4D0FA587190AD101A418 +:1017E0008753891EA63D8CFD168E0F0C5C9A85E7EB +:1017F000D12AE6C6FD3D81B9504FE8641DE47FEC77 +:10180000B4991D68E792F244CA0DC0ABDB1A1FA45D +:10181000831DB0DF1B4D8CEDACB752FA42BD9D1954 +:1018200041C6EDAE4FA0FCDE7A07A5CDF599F4FDDB +:10183000C57A17E5F7D78FA2FC817A37E50FD51760 +:1018400050FA4A7D117D977209E0427248CA152903 +:101850008F4A6DE676F4474AB9A4A79B7900DEB1BA +:1018600079D49EE49E9477B80E435E501E49FCA640 +:101870002845BE0427CAB1B63988FF7CF5E29E83AD +:10188000782E2FB7B9E89CCEB8DCEB047A45B824A3 +:101890009BD921B4BB362C71B7AF7106E17F7FB9FC +:1018A000C28C2174F5406D183386EC1B0FD6C568C9 +:1018B000F2C5757F78A30FF45FD1CBB30BF176F24D +:1018C000879F3EF327F8FEDC0FCFA721BE611EDB0A +:1018D0009FC071978777CD2316F38D26F2470D9021 +:1018E0007610F8877829619CDF9EFBE1DF89BFDBFA +:1018F000EB2C0ED4873F423C015CFF2CF054526726 +:1019000021F879579DDE7310F97CB999E45C49A3FD +:10191000E0C3B500CF10FFEEA94446F608D0A659A3 +:101920001DC0EDD40FCC8108E8FF94C2F95701A582 +:10193000A018E3FED6BEF901F2BF527782FCE71E83 +:10194000AB8DEE35319FE962687F4ADD71AAC7DA57 +:10195000FAC5A0BD84F6B13BD0EFE8363B60DD4868 +:10196000D388B792CC232C11FD264D8A1DFD266508 +:10197000E27BD95A85FC9318773303F4BE77D355AD +:10198000C26364BA91D2CA7426F4BA26DA9F24BD1F +:1019900096AD8376C8174DB9E6052172B8447C2F01 +:1019A000CD34502ABFB78B7EFBAECD9D8DFA445F00 +:1019B0002CCFC2346F36C2B7AF6D925109C1FFC789 +:1019C00038FE089C071FBF12910AFFF768668A79E4 +:1019D0007E16E287EF5F729C92CCBCD518C759B2D5 +:1019E0006E1C4A5FD6607225F4827A67BAFAE17A91 +:1019F0001BB3F278E5AA1EF60F693FFB0CFF1C4DE6 +:101A0000EB26BB6EC5DE5FEC7D057AAEF8D842F8FA +:101A1000AD182AE2A7B2FC23A793A1516BAF9EF8A1 +:101A20008BBF4491FF613F8FAB8494DB53979773D7 +:101A3000FBAB0BF8AA1BFFCFB1BD1F47756BA7DE31 +:101A4000AFDE949DBA46F93A0AF507B99EFCD7BEB7 +:101A50008CA77928D7C8FF53F3DAAAF8EEEECFE8BF +:101A6000EDD55DF66C61B7D397EBED757D32747E85 +:101A70000123A3FB58D25EC7D4AC68B4EF7F29EE34 +:101A80006BF474AE91F6ED9A4DD0491CF0A7D111CC +:101A90008DFEAA2B3DE8D30F66F0FDFE92B0875F66 +:101AA000D9ADD239E7CAEE48E2A7C5BB7F761CFDA7 +:101AB000878BB729348D6AD64A700378326BE83E3B +:101AC00086F16671D7CFBBD39F168DFB48E52F22D9 +:101AD0006B91CE16352BEEED309F4EAB23BA77C807 +:101AE0007C6ECBE0745669691E497016F3CFCD70D9 +:101AF000D077596F51CBCFC87E0CF52E931EF4CB07 +:101B000008F4F523BC7F87F3BCB079980BFD7E8B7E +:101B10009AF72D263D6277841D8F0CE7459CB0EC2B +:101B2000E7CE0CCE9F776670BDE582F0075DD8AB3F +:101B3000923CC379227F9D57B4F1789345BBC9028B +:101B40006E9F0BFE92F51735B7470D84FA670FFDB0 +:101B500081D259625D8B6CAD39B8FF9EDD1F41FEAD +:101B6000ACB3FB9F9EF42A8C77A9795C2FE407D94C +:101B7000FFFC0C13D5BFB4592D4078313F8F7BA9A2 +:101B800046F80E0B9D67DC169F3394EF78DCCF850B +:101B9000FDBF8A326405F1596DF558F15E63CD7E63 +:101BA0006F11CA8DCF140E4FD3FE713EBC8F54D32C +:101BB00092CB909E89EF12A9FE5A43483DB3C94586 +:101BC00042D17868AA3B89E02CEE13897879BC1F52 +:101BD00087F267E9542BF927E60D75CCBA1FE5E4C7 +:101BE0005B268E977E8E27507F9BF74E1CC54D2D12 +:101BF000753A66E1FC97BDAB52BCEFBC61420E2466 +:101C0000B48DC0B8C5AAB50A73C33ADB9D5C6FA892 +:101C1000F2ABCC03F9BE400F3E00C5FA8C14214F45 +:101C200003E978AFEFA97283DB0CFBDF4933F3A93B +:101C300068377A91C73357A5F0B8E1A790EE21AD88 +:101C40008A0DA4C7417F17053EABA605D2314EA22F +:101C5000EAC5448A93B868E67E4BFC8E7ED2AA3CE5 +:101C6000680FF57A8978586C1F13423F55252E0767 +:101C7000D653635D8E5C1BCED77E99F4D89722191C +:101C8000EAB18683913CCEE9E7615B2D2178DA9257 +:101C9000C1F5E55E028F6C2E8F877C5CC4633FBE0E +:101CA0003DD18FE73759FF7193670EC201D781FA93 +:101CB000FB2273533AEAB772BE8BA29A689E17054D +:101CC0007D2F0A6FE2F1D2E29E2CD6C77CBB8951F0 +:101CD0001C77C72E0BC5939C4F6C3D80E39FDF356F +:101CE00088E1FADB9DFE0587A81CF447C05BC50BA5 +:101CF0009600AEE7DC2E6E6F3E67E2FAD8B9A9090E +:101D00000EC45BC1B44DF3C81EB3CDA220DECF29F3 +:101D1000CC9C80E5DB7BBB7CD8BEBE8EE2A42B4096 +:101D20004CE07D1C480BF05ECDB9ED83283EECDC29 +:101D30006F54BC1185DFD7E2770F6B9AF73D84C7EC +:101D40004E7E7E3AFFC27F0E0ABD5726D38A6DDAD9 +:101D500038384927B2FC4806B70F1C11703E9EC1A7 +:101D6000F7ADEA88E6C753689D1CEE80273AF7C1B5 +:101D7000C61FF9F4708C834853506E3C0574F534DB +:101D8000DA1576F2F3D5F9DD268A0BAF3818E9A615 +:101D9000B8B335B718280E42E57A788501C047A94F +:101DA00042FD564CCBA47BBB006F3AC7766C57C53F +:101DB000388CD970DD3B789C6F21EA8A549E4DE5C2 +:101DC000E744FEDC816CD2EBA07F37DE57AAF8DE59 +:101DD000F7391CA797BFCDC88E6125F95AD5E5C73D +:101DE00019138DFB5DF59ADBA2F13E1F7B4765A8B9 +:101DF0009FE8E174D5E8EA8372B577A690B3079EB1 +:101E000031A33CA814F7432A5F50B83F19F80CEFF0 +:101E10003B56AEBEED09A2CFDF99581AACE762F38C +:101E2000CFA234F81072B0ABBED945F52BA13EF667 +:101E300053B9FAAD289ACF0E13C5995CB75FDD6C24 +:101E4000FB17D49B6ADF451FCDDC8E72DDFA59EBA0 +:101E5000BF7D0CFD7FB13BCCE5A3AFCD74AFEC8271 +:101E6000A97901AEFFC29E3092471762B87C380B49 +:101E7000F2D39781F3B8E7271497F5FBE9741F6E47 +:101E8000A15FDBAF1CD79869E27416E78AC6B8BEBB +:101E9000EA77B87C03BCDC4BEDDF31517BFD3A4E79 +:101EA00067F0765DFCB92782E8E1425F8E970B7B95 +:101EB00033683F6A8FE1740EF34DC6FB7317F66407 +:101EC000E4D2BD34546E801E2AC4F9F6424C73B27B +:101ED0003DA4BCDD24CE6901A88974836D40EFABBD +:101EE000A8E37A55A5751DC587605CEDC83C4A031B +:101EF00096D8EBE363815EE9FC787FA6B053E27885 +:101F0000F1227E9BF49D6633CA6F8FD00BAB76EBCC +:101F1000E36B79F9AD998A8C0371F492F1BC48872F +:101F20003E85E24C2A1B972C423AAFACDD703FF263 +:101F3000999C7FA59115E039AC5D51691EED61EC6E +:101F4000C169B86F848E13AAB7C979E254E3495FB7 +:101F5000A57DECAE4CBEAF61BE09FAAB6A54D6D1DA +:101F6000384E799EE5EB927002709831AEAF7D9C51 +:101F700028EF61DD729EFA75CBF93C90C9E551BB43 +:101F8000D3F1933188E7DFAA743FF6EAD7C3A2639F +:101F9000BBD1CB82FBBA3918DF8AF1BE487BD04F68 +:101FA0004E26976B95183F0BF34CDFAC8DEBCEDCD8 +:101FB000A6CD0FDEADCD67EDD7E6735AB479D73134 +:101FC0006D7E1A8EDB9B9FB3F13E2E9EB331C5739F +:101FD000B6C3C2CFD998C77336A678CEC6EF78CE2F +:101FE000C63C9EB3318FE76CCC4B78E3791BF3781A +:101FF000DEC6F2A7059CAA449C24E201E99DBD1C13 +:10200000A6B9EF73E5357E8F03E880F3CD1C33F17D +:10201000CD535883CE1DDCAED477BAD581F1BE8FB7 +:10202000C47A5665A25F54695D9D887833B651DCE9 +:1020300069CD2B3CEEB42A2FCC86F68DB65567576A +:102040006338E703B19E47B1FE1553C70E846F7521 +:10205000DD51BABFDEB6C2F1CE1D1C7F646761E5FB +:10206000B1A43779719F8BED198FFAB86FB64E1BFB +:10207000E7AD8FFBD6C77BEBE940EA7BCF993A12FD +:1020800051AE9FDE655D87F33F1D26EE9FCCB6EA1D +:10209000FCFD424F5BAF6CC5FDFA1799B1DCAF7226 +:1020A00002F4F36EF65999965E1B467A78577E9D38 +:1020B00062A07B7109F1B40F2D13734A563ADAD737 +:1020C000A09C5B64A07DF32AE86538DED5F754D286 +:1020D0001F32361934EB19E40FD7D0D7909DB1BA1F +:1020E0007B0D7D35F5871E4AD1DD6B18AC8DA39F26 +:1020F000B1E2309EEFA7AF1BA6A95756749B0E8E78 +:1021000062DE427F2D83FDC30DEB7B6AF9A664C4BA +:10211000EFB2459DED6B503F7D298CEE8595E3FF39 +:1021200003B9580E7DE27DC6F2FDE23E709D761F3A +:102130002E15FB50B991F9ECB1413A2CB733770C1D +:10214000B45F34B8352780E78ADFFC61A43D05CF52 +:1021500015E3FAA03C4A36B9290EB66A5F5ACC0A92 +:10216000E8F758AAE7A34CC0CB99A6A33F2EC6FD1B +:10217000701F3FEF9D5EF7AB288A1313F4966CB285 +:102180008723DEB734F1F838B48FA9B141BAD8D279 +:1021900014173ED0165C6F900EBE263C017EB81D13 +:1021A000A7FC08F93D3A9BC57AC7293ED4A7E5FAB2 +:1021B000968A7D850DE4FD3C24F267C4F942AEF3B6 +:1021C000E2A0C3390EBC7F517F285945796ED8BD36 +:1021D0002311D2D116CF97B89EF22D697F1A03E34F +:1021E00054FC91AFE7938D13A246A3FEB9C7E42A2E +:1021F00084FC9AA6E7CD78CEAE30FACD145FB96BE9 +:102200008B19E38BEFDCB985BE2FD8E9A578CA8599 +:10221000AC96CE9F9FC97704043CCAC72B9BED3078 +:10222000EFB983B8FC280FE7FE3BD08FDEC0F73B49 +:10223000AEEE5472318E6746D13EB317BE470D12D3 +:10224000F783747CD2F9F6F4FCDE040F7E5FE38F33 +:102250000C4EF1A9D7F3C5F46B4EE28B19D786D09B +:10226000B96C6660103FFF66E9CEBF6FABDC5ED72E +:10227000C2F9A0DC1CE8351DF9E47513E9B9D5B045 +:10228000DF8CCAC37335EC8D90168D5135F45A33FB +:10229000314243CFB359ACE6DECB7D183412929F66 +:1022A0005198AAA93F6BC6101DFDE705CB498EDCEE +:1022B000AAB95F57BDDCE75048CF1CAFFDCE789C74 +:1022C0002063776BDA57B369C17A48DFDBB81E5CED +:1022D000BD3F662BDAFBCA0DFCFC34DBC3BF2F3ECF +:1022E000C4BFB3D94CC38703525D7FE2FBA289FC14 +:1022F00002D29E3E1BFFEE06FE8C8577DD0FC77B6C +:10230000F1688FD0DC9F16FE409C37E2A15AD88D31 +:10231000AA33B9DDA8DAD76AC6770700FEC6B8586F +:10232000AA678DC3F8C82685EC8A982EA778496DD0 +:102330001C16F687718C8B4FA85EE4137D7939BE2D +:10234000DF83F87D85C7952EDCA48F835C47FEC8AC +:10235000C5680F0AC1DB53831C425FF1AFEE8BF0FF +:102360002B5472E95EE4EEC3668CB39B31232617CF +:10237000F9464F5F52AE033FD3F9BBF3EDA3445F81 +:102380009DE546A2DF1BC161B19BDB51F574B780AF +:10239000B59AF19EF882FD8A0BCFA3580FE1D117B1 +:1023A000E951078FB8D8EBE120E1D305AFFDFA384A +:1023B000370EA78587147FA01B38E9E7DD13DCE41F +:1023C0007A16783C93502EC8752DC4F963FF307F80 +:1023D000EC5FFA21D8283D7FA6927D6A71118F8F1C +:1023E000D5D3C3B46BDCEE72DF3523A5330AB5FC5D +:1023F00088ED902F665E8BA7F26F4B2F8B619EFC52 +:10240000FED3CDD1895C8794BB417EE0F7066EF4A4 +:10241000BE8FDEEEB8639088131CC14668E29185DA +:102420005CD5B7D7C7234B3D40BFBF78230D1437CA +:10243000D9694B21FD42CA598FD83F3CABBEA47A23 +:102440001EA8C76713AFD96F3CC2FEB7343285DE12 +:1024500063485E11178F78F286D929FEDEBB42A54C +:10246000B8672FD47384E827AB1B539371BF38F53B +:1024700048C6B33ED0DB4F7DB757FC2818E7F42A97 +:10248000532FAB2358EFD4AAFC648CD338BDC13290 +:10249000DBDF0DBC5AC5FE50FDC30F683FBB64783F +:1024A0003B6A36B4AF5AF5521486F957AEE2FB7860 +:1024B00079AAE79D41BD713FDFB2C38EF0B36FC90A +:1024C00041BBEF49D80EB0BDD41F2A56E5F741FDF8 +:1024D000A2EABF8F3E6BC77BD62B4CF1A87F9E7BB9 +:1024E0000FF64385F633D21B3E0B832EC89F164949 +:1024F0007684CF14E646BFD245C3E1BFAEC1736157 +:102500006E737A00D2EF593C2771DCCA55CF93DE47 +:1025100052F1E88A7455C57ED3A2BBB39BC87487B9 +:10252000D8B7517FC714F5778C9341FD1DF3A8BF31 +:10253000638AFA3B7EAFD9A4D5FF2EA7713925ED6A +:10254000C9031A3A72D17FE71BCF326B69BFB565F9 +:10255000A2BEBE4C0977A13C5A86BA12E6FF1246CB +:10256000E758B62D91EFB702CF7556EE37FA4ADC31 +:10257000CFBDBD0374B210FABCE39A9585DE9B1DF6 +:10258000C76234F909D6444DFD7CBB53537E67C204 +:10259000204DF95D8E5C4DFE9ECCD19AFA935DE3A1 +:1025A00034F97B47DDA5A93FD53D55939F5E304764 +:1025B000537F669157533E6BF6224DF91CCF124D57 +:1025C000FEFEF2EF6AEA3F50BB4253FE95014EA475 +:1025D000402F2D78EEB2E0FB29564ABFA3DA8D28B2 +:1025E0003796FD36CD86F81E33C150DB9D7D3F63A7 +:1025F00030D787CA86B85306F7E6EFE0203DF617D6 +:10260000EFDC8C18CCF199C480AAE8BCDB9A88F482 +:10261000ABAFA72F1F1371E4AA0370F893C14367F0 +:102620001A410E8DB9E5C8B054C89F18BC60A611F8 +:10263000E4C698DB8EFC2A05F2AD837FC1CB871EF2 +:10264000B98AE5B38654F2F2E98C548F3FBFD07754 +:10265000A60FE77F47CA3A17B793747BCF5CA608EB +:1026600007BCAF8D70C03400F48BE911A05F4C8FB4 +:1026700001FD96817C3A0EF48BE909387FE2F77F01 +:1026800087F327A66FC3F913D3DFC1B913D3563825 +:102690007762FAFBFAD994BE57EFA176EFD797533A +:1026A000FA417D2D7DFFA8BE8ED23FD7FBE8FBD43B +:1026B000C1D28E11609AFB01E867447FE221D3C545 +:1026C000503FB0F4574AFF64432D6B8B4079D1667D +:1026D0008CF9D41AF43BF66C0730B24F43F4B1686E +:1026E000E62E1E4CFA423F3BC96FF1DDE4F0781153 +:1026F000CF7F744E4F1BA6E2BE55FB06BA65FF683E +:10270000E8FEDDC411823E460D712F20FA10FE75E1 +:10271000E9DFEE8A9B09F1BF1B42E275E85F48DC06 +:102720008DF483CB389FDBADFC9EB1F473CB781E68 +:10273000D95FFE178CE4C3D8B546D25F228D2C80BA +:10274000FDCBB89DB1D6E65C8C63185B65A37BB509 +:102750007DE0BB398FEAB95548B7FD0DEAE704FDC6 +:10276000EA7DC4FCA19CE69FFF8587ECB063455CD5 +:1027700001B6B7F2721FB61F8BB685E194927C7AD0 +:1027800006EFEDE605FDFC583F82D70F607F03FFA3 +:102790000EE34505F9A67F6C732ECAEBFE8B6D74B4 +:1027A0002F74F3B800BD6745462780CB74797EB29D +:1027B0008ABCF4E7EDEC4376A40982D7BFEFF06C56 +:1027C00042F81759EC7F89203E4BED8FF6C9A9429C +:1027D0007FFE07787B06E940C253E245E251E223DF +:1027E000247E8AF0D0135EF5F8D4E351E22FFF8BFC +:1027F000205E10AED7E32D8857B4E7FEABE06DB88E +:1028000091BF5F66A9B2D2BB6837C2E3831D6C5229 +:102810003456717A46207EBCD71CC7315FCAC64D7C +:1028200042D4CAF2B1583EE2FA72CF171DA6E810A0 +:102830007CDF2EF03DBF87FE643DF91E83ECBFB107 +:1028400087FA6F85C9B80BB72D776430FE71593E92 +:10285000877F815325F84FC85A487A32B3713DD3E8 +:1028600001FFA15C9AF47511BD4FF925DB8D9E5BCC +:1028700036A997563F2DD0F9ADEF167AE9DD3ABD6E +:1028800054AF577E3E58F8B39DCCF92DDF9DBCC6A2 +:10289000E5DACDBE3BC9DF2D9D28F82C49D059AAD9 +:1028A000436563908E9887F6C963F86E690EBEEF34 +:1028B000E9A3FC5DCC4FE93D2C40FBEB6410C498D0 +:1028C000BF174428E68F464C29C6BB7113864D18A6 +:1028D00088DF43DE658B1CD29BDE65FB0F7BC8BBAC +:1028E0006C47263AE87EE5116B2AE95FC887A61097 +:1028F0007BE06F607F1A08FBC751D8BF307D03F6BD +:10290000AF81B0DE3761FFC2FCDD992B18B69BE4C6 +:10291000D0C6EDC8F6F7D827C0C1A467F8DD93F399 +:10292000723F84EF5B311913D17EFE56CC2D1371AB +:10293000BD6FC5F431F0D462A634FBE0C0EEF443C1 +:10294000C907C1F126D1787AF84A78EAE128E1FB93 +:102950004FC0F396EEE0396230E3F649EB1FA21266 +:1029600052D07F1725DEA3FC6D8E0AF97338B5446B +:102970008C57BD8DE639B66E34330E23BF4D16C26B +:10298000B5CACAE1A5B75BB16D7D0CA1F1BB57CD4E +:102990009E8221B0EEB39B55BA377EE9C530B2476F +:1029A0007DE6E7F6B67B14CF649C5F95EA5887EF27 +:1029B00088B2B7F83B67ECEBA3C9D322BF059D6E85 +:1029C000E3F7EDABAC93BAC5A33C4F4D71BA47707A +:1029D000FAE7EF454ABDA29F85BF4B20DF2FEC49A8 +:1029E000CF1819CEE5603F0B97DB12AFD08EF249BE +:1029F000D0CF489073493F09A7F3C5CEDEEEF9B8B2 +:102A00003E6947E8EC17E147793B363084DEE52A3A +:102A100038A1523CF11111DF75E7905A5B0AE0A929 +:102A200029CD5383ED98FAB58A72E66D58671CDAA2 +:102A30001F4E0CB3D1F9F15B9E43BF3344C88B1CCE +:102A400096A3B9AF26E94EB551FC4EE77BFC3EDEBE +:102A5000D2DFF0B8CDA5BD558AFFD7C7C58D65E9D2 +:102A60003F417BE3845E2697DF11942FF21D204BBC +:102A700082813942F4EC3047387384CC27223356B4 +:102A8000938F74F5D5D48F1E95A2298F710FD6948C +:102A9000C715E469F2BD8B6ED5D4EF337BBC269F9E +:102AA000E8B95B533FA97C9A368F7C0770EF5F3B98 +:102AB00057D36E405D89A69ED357A129673E776B99 +:102AC000663CCA71FE2F75ED524DF9D351053C7E1F +:102AD000DCB680EE29A6357D4FD39FC46F521CC74C +:102AE0002F73F0FDC107FF91DF42E0393F41BB6F1B +:102AF0004CB08F3B66A7546BD748BA411CD4A17F1A +:102B0000960EAA99960E7AF1389EFCDF0C73A01EE1 +:102B1000A3C73FFA2342D789FE8850B8A03F22348A +:102B20008FFE88D0FAE88F082D477F4468F9B013EC +:102B30005AFC8F68D5E2FF960FC6FF433C8D6ED3DB +:102B4000D2831E4FB77DA6A58FB19E7082CB04D0D5 +:102B5000C790DE259E66C37FB4CFB3A268B41BDCEA +:102B6000C1DC742FE07F0B5F9775F8FA92AD1B8183 +:102B7000EF5C5EF17239DED33E7F6580FB0B94BB68 +:102B80002942CEEBED00329ED4379EE3D377328CD0 +:102B9000E4D55786B648DC3FBEA3B6915D3E91753D +:102BA000BC81EFCF0CE9E56159BDF1CA36703F94A5 +:102BB0003FB5E8BE5CDCE7E6FDDA928C7ACDBC017D +:102BC000FC3D4196D546EFB4C8F9CC4BE2F147D66F +:102BD0002C21A75D3C0E29228BDB7F225D768A8328 +:102BE000F6663111E7C992E765231DBE1D96817413 +:102BF000B691DBB9DA4C0E8A6BF1013DA29F12F55A +:102C00006DD487FB0B7DB4E143AB95D31DD3ECEFC3 +:102C100083FC564D1CEE909D764D3EBB3941537F53 +:102C2000E82187A63C3790A9291F76C2A5C98F68DD +:102C30001DA5A97FCB076E4D7E745B81A6FE6D9F9F +:102C40001569F249ACE34984E7F8AC141EDFAF081C +:102C50003B8083E365DE77E2E93E8D3C47C8B86C94 +:102C60008FA063FD796480D94371DE0D89CC45F76F +:102C700041ACE23CC8B4E7148F88AB96FA3CF369E8 +:102C8000E3AA653C75D779469C5FE47922249EDAF5 +:102C90008DF397F1D45D7817EF4BEAE9F35E817716 +:102CA000FD3A0698F9FDAF86EF9AE91E8B9C9F7E50 +:102CB0005E9B443CE0766BF7EF0F3D20E8AC2DA522 +:102CC000686616D47B16B62782E775E3B9DA7C000E +:102CD000DF861F985D2B1D371E6FDE50BE9E627C07 +:102CE00057358BDEE9A47B6B72DC6A31EEF41CA5F0 +:102CF000DBF5CD8BE6F15D2CDA4CF72E7A1E8FC317 +:102D000035C1CC1AE99D24710FE18175CDEB3154A9 +:102D1000B3D8DC64E2EFE3FB4D68272A1C0F7A602E +:102D20002EDA0DDFDF68037DEDD93A23D97D1EDA77 +:102D30003DE63ED020BBEE950C80731AD24921E2CD +:102D40001FFA3D97CDE39D1FCBE2F2215FFDBAEB69 +:102D50003E804523E7F9F9AF1BBA237A94EBF8BF1D +:102D6000BA1F20E9570F2779BE6662FF1A28E625A9 +:102D7000E1D7653F11F093F7331C4B4C455B6D7405 +:102D8000CFA300E3CA24FEBECEE674F96616C737A9 +:102D9000D64379D453BD7C352B1AEDE09DCC116D13 +:102DA000BF813DF8FFE8DE04C1BFA7FB5E3DC989D6 +:102DB000EBE4430FF7BF7AA24FFAF72DEE8185C8F7 +:102DC000091EEF23F0E11F6820BFFA9A482D1FFF6C +:102DD000358BDB5D9E96FB850FCEDD5A39C1D0AEBB +:102DE000DFB04A15726241D7EF48E0F7F9AB4CA467 +:102DF0005F3356F438C6197CB2D14471B163DD8CAF +:102E0000F49892CD8A7F8B82FBE898049CBFD7A769 +:102E1000DD8FEF60AED5E8FF285DABFDBED0C67F8D +:102E20006F62BEFEDD14715E5F7883F3FAD92CE128 +:102E300007723117E95DC2FF5F2EDAE8F5AE4E3F4B +:102E4000F79BE1795BE576278A1B93FBBB03FD3794 +:102E500021EF81003CC333711F6F34761BCFD70540 +:102E6000CF1EE2152EDA44BC828DC76774EE0FE3E5 +:102E7000FE4DE95712F52FFAAE5239D6C7DE2EE5D0 +:102E8000F2B80BE94FD2FBAB3A6D06F2B774EE8F96 +:102E900024FF3CFA71A2810ECE1BF6C58F7206E7A5 +:102EA000E76953357E107DEA59F1129D17CB533DEA +:102EB00031D918876D74595D907FC47684DE8F2A6E +:102EC00014762FFD7CBBCE5D63F8FB2E9D3EAECF0E +:102ED0007616F07738402E32E42319873095C129D1 +:102EE00015526F6034CDE7DBFA73A65FCBE57ECC7D +:102EF0006BB7517BCFDAD1941FD0B87E09DE8399AE +:102F0000D9B0D0842EECB62797E78743D3B6FEFE20 +:102F100095E188B7714AB776F9BC6C85F8A14D1771 +:102F20005F2FD3ADD99C5F7E9D2DE5B888435AA114 +:102F3000101F2C55988C4B22392EF3579B443E9FE3 +:102F4000E797ADE2F936F1BEFE0E6147C175638ABF +:102F5000EBC673FF6E6167C175638AEBC6EF28B776 +:102F6000308F720BF328B7308F720B53945BF8BD20 +:102F7000841525E7AADC0F353194EFAE59D9C4107A +:102F80007E413F54681EFD50A1F5D10F155A8E7E2B +:102F9000A8D072F44385E6D10F155A1FFD50A179D0 +:102FA00036EAAE601EE59C7BAA263F1DF4FC892113 +:102FB000FC8D7EA8D0FED10FA5E9CFB344D3FE7E11 +:102FC00056A7698F7EA8D0FA0FD6291A3FD583E27B +:102FD0009DD3D24D71443FF31D4535D980DFFF8825 +:102FE000F8EF874D2988E79645FC5C16EEE2786E8F +:102FF0002AE07837308EE78E3984E7E5669ECFE7A2 +:10300000F1C97AFA417FCF4413F7F7608AFE1E4C6C +:10301000D1DF8329FA7B26A6717F0FA6E8EFC1EFE7 +:10302000E8EFC114FD3D98A2BF0753F4F7608AFE94 +:103030001E4CD1DF83EDD0DF8329FA7BF03BFA7B96 +:1030400030457F0F7E3F897E2753705EA8C70FD41F +:103050009C1F810E35E747BB268F7A7C687DD4E3C1 +:1030600043CB518F0F2D473D3E348F7A7C687DD402 +:10307000E343F3BFCC72109FA13E1FDA0EF5F9D0E7 +:103080007C7693EF0DB49D4DDE7CF918A66D91CA48 +:10309000B30A888CE6ECF7EE433F5D5B98921C0325 +:1030A00092D3B4E2C3FB2682BEE611F17F39ACC3F2 +:1030B00080F8F688F7D43D0146F196D97F4BA4F20B +:1030C000CB78AF5FC4DB22DE73F733FA5D12E92FF2 +:1030D00096ED5DCCAE622AEB07F3DDD7D38F2FEBF5 +:1030E00091FC0C9907DE00C67895DCE5B63C8CF7C0 +:1030F000DC6150284E62C74A1E27ACA7AB33424F53 +:10310000DA61D87704EF81747815BA0F9C6E642762 +:103110004C7908A7DA3CDC7FDFCE8E11EBAABD1517 +:10312000EF9BC8794BFB26C809BA3F37A6A3754267 +:1031300034F4E3F18DA3DF49293473BD01DBE17978 +:1031400072884F716F0DA1EFF785DCF4F8F8F83F46 +:103150007F6E0A6F17CEDBFDFCB92882E3944685AB +:10316000E2A5C6EC666EBC9FFB1F429E0ED91D50A9 +:10317000713C6F231F4FF6EBDD9C4CF716BDAC6D19 +:103180006202F9481486725BC20DD6770CD707C766 +:103190008613689FBED97B3FB70F8FC9C7383AD611 +:1031A000C2E81DCBC9C3DFD5AC97D03E92FAA57D4E +:1031B0002DC3A7D07BC1537C2B56E2B63ED9B7E4D2 +:1031C0008DDE587F1B73391DB415D1BD58399FC191 +:1031D000EE7D06D81659166B358429886F76342E05 +:1031E000847E80F36720BE735D267ABF77AAD16E96 +:1031F000A2F7237A883FB96A93F1273A7D4117678E +:10320000D2B0FC8364B4272F8D3490FD77E94BFC5A +:10321000F7003C9B14926B520FF28A38B5AB8D6F5E +:10322000F49E8570DF67A2FE64FC4975AA3FD980D1 +:1032300071F57DB7E4C4AAA407C4E6A01EE0FBD5DF +:103240007DA3B0DE2AFE8EE5D5C699D101EA89FBC1 +:103250006BCA04BCCA441C93171FF45683BF8B254A +:10326000EF77B026AEEF497B8EF7B7C38E237EBDD6 +:10327000CF8877A5D77AE95EB63E8E6851A389E2FA +:103280008E16E9F4C24AA11756DE402F1C9CA3D328 +:103290000BE5EFA588364CEDF73EC6EDC97B89C539 +:1032A00026CEFFC5FB18D9618B574C30D03BC82FB9 +:1032B00071BA295EC1F59BE297DD74BF50EA8BEFCE +:1032C000083D66DAB52482FB1F84DE3213E32B014E +:1032D000BE856D61220E2B91D259D778BCE5341B87 +:1032E00097036DAFF177203A7D16AE4F1D63FC1D3D +:1032F000331D5D4E35FA0D78E1CE3506E812F293B6 +:10330000510F82FE66A35E148774EECCA7F8BD024F +:1033100085EEBDE8E9BCD054FB06C687166E672E65 +:103320001F0BA573A05FECCFA7D0FB001E71AE955D +:10333000F4ABA7F77911C21E65E3F6A62EBB04EA2B +:10334000A8F44877CE2CD41BE7A16FAF2F27188C99 +:103350003B8BCCE2E5653939B31AF190D3839D42BA +:10336000FD9E99E0E191EF20F46037407B01CAC9EE +:10337000071ECA359784C8C9E1AEF18D434704F1F1 +:103380005DD275DF2F8BDE055DFA481AFD1E4E4FAC +:10339000FA7029C015F9625E74DBC3F80B6B0D3946 +:1033A000CC3D31017F2750AE8F05308E70AEC837CF +:1033B000EFBDEF4F6B6D0417CAD7E78C998571216C +:1033C000D5D6B649487635599E02BCC718944F45A4 +:1033D000EE2405E5536E00CF849BE4FD649D3DA281 +:1033E0003987D7D7DB254AB3B8DC96BF8B72EA9111 +:1033F000837B71BF92F33FD5C3EF30ECCCE1F2F7A2 +:103400007FEB1E84FEFEC32FFB7A9ECC81753C6E43 +:10341000E0F7F9FBAA4D4CD887C82F2CE50513EF30 +:103420006004F1EEA677741B1E51ECA1F629CF5A69 +:1034300085DFA3EFC18EC3323B9EDC0EEDE6D59B4C +:10344000E9F7F89E4BE7F4F31CD00FFD5E8AB9F55F +:103450000DAB3308C78FEB7E6AA2DFA56181347C98 +:103460007F676E6D980BE5F17057D12F71DE1159A2 +:103470002E92438D18430EF9BB7A15BD88DFABD76A +:103480001D7E16DF13A86971D2EF95780FE5AEC6E1 +:10349000774E86BB3C07B1DC6BB3D37B1A8B1B63C7 +:1034A00068FF9AD747DC0B651DE46793F07F47D828 +:1034B000AFD6BA38FD5E11E70E14905335F5BAB7A2 +:1034C000E3493BA1DECEA07F5FA227FB82B427A009 +:1034D000FDC01C626794F60953E6A939A837149B0E +:1034E000B5F71265CA86F27D5F9E03E777ED5B59FB +:1034F00093FAA07EBC41B1D37B9336C7ACD1902F59 +:103500003B61C2C84E5618EB30E3FB031D805F8C55 +:103510008F2E017E4539532CE2B4CA368D267E2B80 +:10352000F343DACD3B9C32BD7FC3D1FE2F23FD0494 +:10353000DCE4B72CB3BBCDB1217C5FDAA468DE1D1F +:1035400090F98E1C95F311A8E308BF071E729AF13B +:103550006D9F62502330FE8F0D7568FCC7508FE25F +:10356000410A53D871FE0E3CCCDBC9C7CB0BE9BF77 +:10357000A489DF9B9679A84FFACFDF732209AE5E4C +:103580003BACDB89A99DE60970203875AC87FE1C31 +:10359000340EE1A334E037E179BB18E350203FD784 +:1035A000EE37E138258DFC1D13CF3A3E8E676D8CCA +:1035B000391BF523A3DDDC1FE1277E6F15E6477A73 +:1035C0006419C005EF63E17D37DC5BF4F0F18AF943 +:1035D0009635C5D03B0AC1EF1B4C888F393DBC8B5B +:1035E000903594D36D49E338BABF5E6674D33D0716 +:1035F0008F80EF274BC21E45FFC09C8D4F989C903B +:10360000EF3794D36FD6504E5F852981347AAF68F7 +:1036100049980BE739C7DE44EBEB82EF63000F05F7 +:10362000DFB92922F8025DF8306EAF6CA3169FC196 +:10363000F970F8966DF412BF2D307ACCF6D0796C13 +:103640003A9C86F7AAE6007FE3BB12CCEEA1FB9280 +:103650009F3E362B99D609F344B846BA1C93F0FD29 +:1036600021A0137E0F46AC47DEEB96E34D1CCAEF5C +:103670009D4E1CCAE567CF7CE926BDA601F08B767E +:10368000EF9EF8D28C821BC63597F1DF91D0F3A95B +:10369000E44FC997924F25FF3E6B2A0A24284139EF +:1036A00003FB6CED8BDDC0A951CC77AEC02BC0F510 +:1036B00058E83DAF6A81D7E2142DBF637FD8EF1C75 +:1036C000C1EFC5E30369F82E93AC2FC72D8EE5ED4E +:1036D00090EE91DEE688F1B0FE52AAAFBDA752DAB5 +:1036E000252F76AF8A4779B14FE17ED0F547FB7F32 +:1036F00007F5D73D5C7FBD50B57D31EE97CCE84FE7 +:103700000E7DDF7F3EE83928271688FDB92CD0BD15 +:10371000BCB890EEA9181AC2CF653FDB93EEE1F278 +:103720002680F2E6CF7B5EFDE3AD8EE07E2AD753A6 +:10373000B2F65D93D7160A3FBEFE47333BE93E5EC5 +:10374000A9CDECC078E7D2462FC95F96007AA112C6 +:10375000127FA6A30B6FA342F7C84AEB46FAD5FF28 +:1037600045395DBA6E2ABD7B20F126DF6791FBAB40 +:103770009CFF7A31FF2621DFE60AFA9E5B3ECE9C53 +:10378000D88BF46E0CB36473C4F73965DAEF5D78E7 +:10379000EBF25F67AD467EC1FB45743E5967E2F6CA +:1037A000BEDDDCFE7861E9C1DFDD07F5CE3FBE2579 +:1037B00099A95ABCA19EBA40E8AB0B85FDAF1BBCD2 +:1037C0006D19DA3B985FF81CC75BE9DEDFFE05DFA9 +:1037D000132B4E11F26E3D7F07A0A4791FE171CE2D +:1037E000DA0D2627D4DB37D44970EA92FFB5B976D3 +:1037F000B42BCF5DBBC58472629F84838E1F8A45C4 +:103800009CB08433EE4B4A887F43D647F988EFDF7C +:103810003FB4242C0AE379E4381F093A2FAD8D898F +:10382000C5F14A6BBD3FC6F390DC0FF4EB3C1DC6FF +:10383000F9A504FA43BE3D3DCE95BC342BA8CFEA92 +:10384000EBBF2BF0F8B489FF4E4D5244F32E8A6B38 +:10385000A80977A1FC1838B0CD8FE3227DE3BCCD59 +:1038600006FEBB3603ABDA3EC77980AA4D713598A8 +:10387000E2FB58A87AC7437EAB81DFDF4A5179FA71 +:103880009590D7501EC072D6AB8D7E5F23246E56A6 +:1038900043BF66B68D7E3FD1DC8BD1FB66925E6501 +:1038A0003F925E253DF7B4BE2B42AEDC687DA79DFE +:1038B0001C9E66F1BB2937BD3E0BFF1D5DB92E393D +:1038C0003FD0E1DDF4BEC7F7B3C9DE737A852B19AB +:1038D000E3267B5EEFC6FCF86ED6AB5FA7E41B1950 +:1038E0000BDFE5CF6AE27E87D30AEC6FD0EEF4926D +:1038F000308A6F93EBD2DBC3FF1FB640B5F6008072 +:10390000000000001F8B080000000000000BCD56D7 +:103910007D6C5355143FF7BE7EAFDDDEBAB1751B2B +:10392000DBBA8D8F46BAF1CA80F891681D8CF0C75A +:10393000A2DD14DD0C6C25B031C68A9360A8C6B830 +:10394000B2229211E24C3618044C876C7F18205D2D +:10395000208AB19A8689468311E11F1292A60B38FC +:10396000D16856310A44649E73DF2B9D08897FFA23 +:1039700092E6F4DE7B3E7FE7E3DE0F7A658085002A +:10398000C77B1D00468093BD4E41A3BD2EB19FA7AE +:10399000D801E6007E495B930D60AD05DA7C565C8C +:1039A000C6F1970F9008568DF4B3CC7E831DDA9A3A +:1039B0009026E4A4CDEEC67DBBBA7FADC7DC0F393F +:1039C000002D90DCE7588AB2C12A1845538981AB93 +:1039D000368E7C579F463E77466EBB3EB51E88CFDF +:1039E00066708E5600646DFFAEBE10EDB50F567852 +:1039F00018CAAD0BD6268278BE6E57A102B86EB734 +:103A00003A773BE83C54A1F4E13A6BD033358CE78C +:103A1000EDBB1629C4BF9D812F4A7E0F1C002800D4 +:103A2000E8807B9FD7B41C6013FD43BE4D56C32472 +:103A3000ABC1F3E0C43C19E53B14B387A1FD4DC312 +:103A40002C6EC4FD060E7BD81280F2B06F5511DAD1 +:103A50004B1D64CA51923D5CEF4D9A5485339500DD +:103A60005D0B7D35CA325CDC99999941FD8F20460A +:103A700020515C512FC501434C1E05F2DB67207CB1 +:103A80004E2C760A9C13839336A75BC5BB11F106B7 +:103A900047010794DF6652FD2B37A426DF46BF524D +:103AA00036AE1CC575BDE4FED649717E2581D1496F +:103AB000721ABFACF1BFF9A8C98FFAB6D92A0B01A7 +:103AC000E9C66174A216CF9A4D9C70E8D47C6E1F33 +:103AD00079AE00D08F763C77E2F921DA7C0C60F782 +:103AE000E08A8224C9BD5BBF3F540D50A6E1784DEA +:103AF000976CA4FC5C1F29B4EFC4D83606C20B0037 +:103B0000CF378EBC5D46F4FA88B939827C2BE5C686 +:103B100095B9186FC7E15C8F84FECCD0F714E64DE1 +:103B20004121C4A72BB0A21010AFEEBB13EFC955B3 +:103B3000681FB126DC7F8F664542C8D2DD7BA64C6C +:103B4000E2E88AD1DF4C786EE1B1171E433D3FB108 +:103B5000C85891E07716CAD68CDEFBE9542FC28094 +:103B6000F51C78F3B2D0F30B3FFF4C0BCA77074E2E +:103B700065939E2D439796CBB8DF59E5DFA8CC21FE +:103B8000BD2363324204C323353E8CA35D01E1674C +:103B900083DDF7420BE1FE9524707F98BDCE334C58 +:103BA000E07B2FCE488E8170F7C7C1201395C140AE +:103BB000F57D5D8260146943A5DA2FE9FD20E1827D +:103BC0007E5CCF1928A3BAD83C76A0CC89F4479B59 +:103BD000BA5E3BF6E2D7908DFCC78C06CA975F07AA +:103BE0000605E5368498374275D389FD5A94B1DFCE +:103BF000A764097D9B87D1A9BCCC3E4044C4F5A3F2 +:103C00000E56931FE5E194E715A45774F176CAEBBD +:103C1000951EB312AAA03C3905DF95016915ED8701 +:103C2000B091E6335A9FB2CD43FBAD39D043F2B6E3 +:103C3000A5D138C73C074EE72E91D49212F5B55561 +:103C40005617F5927555099E6F1B6732D5E9B68FE9 +:103C5000CFAD02750DC01E8E67D7AD27C039CBEF33 +:103C6000AED3E306EA8FEEE3182FDAEF8E8E7F51A4 +:103C70008C7AB69E595FABDA1D00AAFF80D6CF5B67 +:103C80004FABB8044E4F1A36B8337AD6BBECBB4BA9 +:103C900030B7A34AEB8B43C8BA9EF2F63840EC64C7 +:103CA00063F3CE79486B641137E852653EECC37E0E +:103CB000D74503F5516097A6CF757177A588B731C1 +:103CC0000F66D5C398A217726979C443C8C5039615 +:103CD0003DB01887CD56AB8E683860CD267AB88750 +:103CE000BB7488AB97591409F10E9AB26B684EDE1B +:103CF00034AB346651E90EEE1BEF40176FF20B66E2 +:103D0000C0BADF210D30A24FB97B18220D8BF2FD16 +:103D100031AA5F0744190820E28CFC9EFEF4875A02 +:103D2000B2FF6479F2374097F43BDB9A57627D7CAF +:103D3000AE68F1B993B554E773CEAA73FA881EF64C +:103D4000989750DC3E68AA262DF89FF27E9B476824 +:103D50000EC758FC7DD29F8EF796D6C73EA3750F2F +:103D6000433F1B9CFE6FC88F6799BEDAC32907D2F9 +:103D70007CD23FAD57CF71FE7A4D581775DAF02DD2 +:103D8000E510022C5943B1C34A75CDBC5E08A2FDB3 +:103D90003EF7D90D541F7B532630A2DDB086475D18 +:103DA000CA32C990AFB47835079CC7CC994F770C0D +:103DB0009C75F39011FDDC0BA608F18309E7B12B8C +:103DC000338F0DDCEC15FCB12F6FD37C2F917E9DD2 +:103DD000C841FE921D4C09234FEB8DA923DF225DC4 +:103DE0000B110FE1DA95EF9FA2381237564FFA31D7 +:103DF000BF7BE5A84971ABFA66FB1F7BED76B69DEC +:103E000067FC9A4E4D9DF868295193B877EA629203 +:103E1000B837EEF767DAE1D4911DE48B73E2B7F2BD +:103E20000863C43F7199FCAB3359E35236C9E97F4B +:103E30009E7DAFC085D2DCA945E22A8199129CF60D +:103E400061356F4F6A7D98CE8B85C05F4654CD4FEC +:103E50001A3FE1FCACFBE433EBD83AAA9F74BFBE37 +:103E6000ACEDDFB8559943F3E546AC2A07DC0FEF1C +:103E7000CF4B385FE99D70B8C26BF72CCBDCA76BDA +:103E8000D2B7AB76DF4A9ADE351A4E6BAC5CC5E52D +:103E9000F9FB70D1EA245D0769BFD3794EE70F5E65 +:103EA000BF702EA742E4ADFA1D10F99A4BF613B776 +:103EB000CFBF856D05C59277D25FF17FCC57DCBC53 +:103EC00090DE0D435CBC1B4A09F825827A39C6078F +:103ED0002E10F3A055B228FD0F98077E9A078B6924 +:103EE0001E0C883EBFC953E738A379D023D60E48AD +:103EF000EDD4E13AC19336F23769C6AA47EAF754DE +:103F00008A7BA0843ABA4ACD13F5F591D76C47E97C +:103F1000FD1666DE8326940FEBB57EDF6C8D8CE29A +:103F2000FE748487F4686F303772B003F707D7CC1C +:103F3000554288D334687C9D1631179EE05CAC53A3 +:103F40002D0591A315C48F7D8D710EB63C22EEF127 +:103F50000FEF4AE2BD989A0FEAB907160CD379A37E +:103F60004BE8FB243D67F6D984BEC1466F91459C62 +:103F70001770928FE4F95FA2FC164B2A1F3E0404CF +:103F8000DFA143DE22CAC7A12683E0DBCF7C2DED73 +:103F9000A4A7DAAAD0FB32D9623939A6A623CE96D5 +:103FA000D27B558D375DBFC30B64814B7968F2209E +:103FB000BD434275E0EAA1F72BD5E1E24C7E9817AC +:103FC0007361CFE4295D8F213DE62B5FCD571FFB49 +:103FD00077BEF2B57CB120D66D36E52D2AF0BFC98B +:103FE000D53CEC9020998531495C711891FE91EF98 +:103FF0007F558DF342119DB71A93CB06E85DCCA196 +:1040000033FA803E0C519F8BF739DEA258E76D5A88 +:104010009DB7A5EBF18DFBEA313937772A4BAB47DA +:1040200094FFDEE2EB237BBFB04BCB69F3FC5F5226 +:10403000F383ECECD5E6C89F467FBFE8F36385FFCA +:1040400078679EF7FC504AF70CDC99984BF7CE99AD +:104050003CDF3EE233CF4B19FC8467514A4FF124D9 +:104060005A7E2AA5F74C5BF04BD137FFD5CFB41F52 +:104070007F03DC4DE081B00C000000000000000078 +:1040800000000018000000000000000000000040D8 +:1040900000000000000000000000002800000000F8 +:1040A0000000000000000010000000000000000000 +:1040B00000000020000000000000000000000010D0 +:1040C00000000000000000000000000800000000E8 +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F00000000000000000000000000000000000C0 +:1041000000000000000000000000000000000000AF +:10411000000000000000000000000000000000009F +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000000000000000000006F +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:10417000000000000000000000000000000000003F +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A000000000000000000000000000000000000F +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000000000000EF +:1041D00000000000000000000000000000000000DF +:1041E0000000000000000000000033280010000064 +:1041F0000000000800003330001000000000000242 +:1042000000003328001000000000001000003A7881 +:104210000000000000000008800000000000000016 +:10422000000000008000000000000000000000000E +:1042300080000000000000000000000000003120AD +:1042400000000000000000080000336000010004CE +:1042500000000001000033680000000000000002C0 +:1042600000003370000000000000000800003374FC +:10427000000000000000000200003A700000000092 +:104280000000000800003A4000080000000000089C +:1042900000003D88004000000000004000003A504F +:1042A000000800000000000800003A60000800005C +:1042B0000000000800003A8800C8000000000098D4 +:1042C00000003C18009800000000002800003C5846 +:1042D00000980000000000280000337803600030E0 +:1042E0000000036000003EB0000800000000000174 +:1042F00000003EB10008000000000001000020089E +:10430000001000000000001000002000000000006D +:104310000000000880000000000000000000000015 +:10432000800000000000000000000000000000000D +:10433000000000000000000000000000000000007D +:10434000000000000000000000000000000000006D +:10435000800000000000000000000000800000005D +:1043600000000000000000008000000000000000CD +:1043700000000000800000000000000000000000BD +:10438000800000000000000000000000800000002D +:10439000000000000000000080000000000000009D +:1043A000000000008000000000000000000000008D +:1043B00080000000000000000000000080000000FD +:1043C000000000000000000080000000000000006D +:1043D000000000008000000000000000000000005D +:1043E000800000000000000000000000000000004D +:1043F00000000000000000000000000000000000BD +:1044000000000000000000000000000000000000AC +:10441000000000000000000000000000000000009C +:10442000000000000000000080000000000000000C +:1044300000000000800000000000000000000000FC +:1044400080000000000000000000000000000000EC +:1044500000000000000000008000000000000000DC +:1044600000000000800000000000000000000000CC +:1044700080000000000000000000000000000000BC +:10448000000000000000000000000000000000002C +:10449000000000000000000000000000000000001C +:1044A000000000000000000000000000000000000C +:1044B00000000000000000000000000000000000FC +:1044C00000000000000012C8008000000000008012 +:1044D000000000010000000000000000000040009B +:1044E0000490000000000490000019C800000000C3 +:1044F0000000000800004948000800000000000813 +:1045000000004928000800000000000800004938A9 +:104510000008000000000008000020080010000053 +:104520000000001000002000000000000000000853 +:104530000000401004900040000000400000499836 +:104540000008000000000001000049990008000078 +:1045500000000001800000000000000000000000DA +:10456000800000000000000000000000800000004B +:1045700000000000000000008000000000000000BB +:1045800000000000800000000000000000000000AB +:10459000800000000000000000000000800000001B +:1045A000000000000000000080000000000000008B +:1045B000000000008000000000000000000000007B +:1045C00080000000000000000000000080000000EB +:1045D000000000000000000080000000000000005B +:1045E000000000008000000000000000000000004B +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:10462000000000000000000000000000800000000A +:1046300000000000000000008000000000000000FA +:10464000000000000000000000000000000000006A +:10465000800000000000000000000000800000005A +:1046600000000000000000008000000000000000CA +:1046700000000000800000000000000000000000BA +:104680000000400000180000000000180000430077 +:104690000040000000000040000043000040000215 +:1046A0000000000100004301004000020000000083 +:1046B00000003000004000000000004080000000CA +:1046C0000000000000000000000030000008004072 +:1046D0000000000400003004000800400000000456 +:1046E00000004B00002800000000002800004B5094 +:1046F00000100000000000100000380000800000E2 +:104700000000008000003800000800800000000267 +:1047100000003900002000000000002000002008F8 +:104720000010000000000010000020000000000049 +:104730000000000800005108000800000000000808 +:104740000000512000080000000000080000513067 +:104750000008000000000008000051C00008000030 +:1047600000000001000051C100080000000000012D +:10477000000039400010000400000004000051D087 +:104780000030001800000010000051D80030001860 +:104790000000000280000000000000000000000097 +:1047A0008000000000000000000000008000000009 +:1047B0000000000000000000800000000000000079 +:1047C0000000000080000000000000000000000069 +:1047D00080000000000000000000000080000000D9 +:1047E0000000000000000000800000000000000049 +:1047F0000000000080000000000000000000000039 +:1048000000000000000000000000000000000000A8 +:104810000000000000000000000000000000000098 +:104820000000000000000000000000000000000088 +:104830008000000000000000000000008000000078 +:104840000000000000000000000000000000000068 +:1048500000000000000023E800800000000000804D +:10486000000000010000000000000000000020081F +:1048700000100000000000100000200000000000F8 +:104880000000000800002DA0000800000000000843 +:1048900000002DB80008000000000008000024E817 +:1048A00002D00028000002D000002E5800080000AE +:1048B0000000000100002E59000800000000000167 +:1048C00000002D900008000000000008800000009B +:1048D0000000000000000000800000000000000058 +:1048E0000000000080000000000000000000000048 +:1048F00080000000000000000000000080000000B8 +:104900000000000000000000800000000000000027 +:104910000000000080000000000000000000000017 +:104920000000000000000000000000000000000087 +:104930000000000000000000000000000000000077 +:104940000000000000000000000000000000000067 +:104950008000000000000000000000008000000057 +:104960000000000000000000000000000000000047 +:1049700000000000800000000000000000000000B7 +:104980008000000000000000000000008000000027 +:104990000000000000000000800000000000000097 +:1049A000000000000000250000400000000000089A +:1049B000000025080040000000000028000009C099 +:1049C000012000100000000880000000000000002E +:1049D0000000000080000000000000000000000057 +:1049E0000000402002D00028000000080000300035 +:1049F00000000000000010000000509900000000BE +:104A000000000001000050B00000000000000002A3 +:104A1000000045A000900008000000088000000091 +:104A200000000000000000000000296000080000F5 +:104A300000000001000029610008000000000001E2 +:104A4000000029700008000400000002000029781E +:104A5000000800040000000400002FB0000800005F +:104A60000000000400002FB4000800000000000453 +:104A700000002FC0000000000000000800002FC848 +:104A800000000000000000080000300000000000EE +:104A90000000001000005040000100010000000173 +:104AA0000000500000000000000000200000080886 +:104AB00000100000000000040000080C00100000BE +:104AC00000000001000008B7000000000000000125 +:104AD000000008B600000000000000010000100007 +:104AE000003000180000000400001004003000181E +:104AF0000000000400001008003000180000000250 +:104B00000000100A00300018000000020000100C25 +:104B100000300018000000010000100D00300018E7 +:104B2000000000010000100E00300018000000011D +:104B300000001010003000180000000400001014E5 +:104B40000030001800000004000030000100008068 +:104B50000008000400003004010000800008000488 +:104B60000000000A000000000000000000003068A3 +:104B70000100008000000001000030690100008099 +:104B8000000000010000306C010000800000000205 +:104B90000000306E01000080000000020000307054 +:104BA000010000800000000400003074010000805B +:104BB00000000004000030660100008000000002D8 +:104BC000000030640100008000000001000030603F +:104BD000010000800000000200003062010000803F +:104BE00000000002000030500100008000000004BE +:104BF0000000305401000080000000040000305824 +:104C000001000080000000040000305C0100008012 +:104C1000000000040000307C010000800000000162 +:104C20000000307D010000800000000100001C1821 +:104C3000001000000000000400001C300010000004 +:104C40000000000400001C380010000000000004F8 +:104C50008000000000000000000000008000000054 +:104C600000000000000000008000000000000000C4 +:104C700000000000800000000000000000000000B4 +:104C800000004C10000800000000000200004C1260 +:104C9000000800000000000200004C1400080000A2 +:104CA0000000000400004C20000800000000000884 +:104CB00000004C30004000080000000800004C00DC +:104CC000000800000000000200004C020008000084 +:104CD0000000000100004C04000800000000000279 +:104CE00000004CD0000800000000000800004CE06C +:104CF000000800000000000400004CE40008000070 +:104D00000000000100004CF000080000000000025C +:104D100000004CF4000800000000000200004D00FC +:104D20000008000000000004000050000010000017 +:104D30000000000400005004001000000000000407 +:104D400000005008001000000000000400001400E3 +:104D5000000800000000000200001402000800002B +:104D60000000000100001404000800000000000220 +:104D700000001410000800000000000200001414DD +:104D800000080000000000020000141600080000E7 +:104D900000000002000019B8000800000000000830 +:104DA000000014200008000000000002000014248D +:104DB0000008000000000002000019C80008000000 +:104DC0000000000800002C10000800000000000196 +:104DD00000002C11000800000000000100002C124F +:104DE000000800000000000100002C130008000073 +:104DF0000000000100002C0000080000000000027C +:104E000000002C02000800000000000100002C043B +:104E1000000800000000000200002C300008000024 +:104E20000000000200002C32000800000000000218 +:104E300000002C34000800000000000200002C20BC +:104E4000000800000000000100002C210008000004 +:104E50000000000100002C220008000000000001FA +:104E600000002C23000800000000000100002C249A +:104E7000000800000000000100002C2500080000D0 +:104E80000000000100002C260008000000000001C6 +:104E900000001400000800000000000200001402DE +:104EA00000080000000000010000140400080000D9 +:104EB000000000020000141200C0001800000002F0 +:104EC0000000141000C00018000000020000141CB4 +:104ED00000C00018000000080000141400C00018F2 +:104EE000000000080000142700C0001800000001A6 +:104EF0000000142400C00018000000020000142666 +:104F000000C000180000000100001590000800001B +:104F100000000008000015A00008000000000008C4 +:104F2000000015B00008000000000008800000002C +:104F300000000000000000008000000000000000F1 +:104F400000000000800000000000000000000000E1 +:104F50008000000000000000000000008000000051 +:104F600000000000000000008000000000000000C1 +:104F700000000000800000000000000000000000B1 +:104F80008000000000000000000000008000000021 +:104F90000000000000000000800000000000000091 +:104FA0000000000080000000000000000000000081 +:104FB00080000000000000000000000080000000F1 +:104FC0000000000000000000800000000000000061 +:104FD0000000000080000000000000000000000051 +:104FE00080000000000000000000000080000000C1 +:104FF0000000000000000000800000000000000031 +:105000000000000080000000000000000000000020 +:105010008000000000000000000000008000000090 +:105020000000000000000000800000000000000000 +:1050300000000000800000000000000000000000F0 +:105040008000000000000000000000008000000060 +:1050500000000000000000008000000000000000D0 +:105060000000000000000000000000000000000040 +:1050700080000000000000000000000000000000B0 +:08508000060209000000000017 +: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 deleted file mode 100644 index 5f04df69e7c3..000000000000 --- a/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw.ihex +++ /dev/null @@ -1,13181 +0,0 @@ -: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-e1h-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex new file mode 100644 index 000000000000..ba1ce53df1d8 --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw.ihex @@ -0,0 +1,13192 @@ +:1000000000004F48000000680000070C00004FB8D7 +:1000100000001ED4000056C800000094000075A027 +:1000200000009F4C00007638000000CC00011588CD +:100030000000DC5800011658000000940001F2B8DE +:100040000000400C0001F350000000A400023360E7 +:100050000000F4240002340800000FFC00032830E4 +:100060000000000400033830020400480000000FC4 +: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 +:10269000083007D8000503B207340000332B0000D0 +:1026A0000734800030A40CCB07350000351A18F52C +:1026B000073580002A8A263C0736000018D830DF0C +:1026C00008364630373A03B40130000000000000FD +: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 +:102B0000072400002AFF00000724800015090AC0DE +: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 +:1040E00002020104000000000728040000A30000F1 +:1040F000082807B8000904CA072C000034F10000A2 +:10410000072C800038A60D3D072D000037B61B6731 +:10411000072D800032632955072E00001C6835EEFC +:10412000082E48B036EA04CC012800000000000048 +: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 +:106A000010000000000028AD00010001000902068E +: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 +:1076B000D6DEEB3BFF6BCEB95634D94FF22E27E422 +: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 +:10A2200064FDD3E98BFF0778BAC08E008000000080 +: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 +:10FF7000C26B28124054C446650714A540313C9317 +:10FF800018981547F774633308AC6737337A5C5DAC +:10FF9000C1D3E0A0ECACE7102171339A300D2A8F69 +:10FFA0005947A3828266B141E4B126742428E270E5 +:10FFB0008E7BEFFDABE8AE4E02E859939373F35797 +:10FFC000FDF5FFFF7DDFFB552D3FE4720701A0BA71 +:10FFD0006C4D1E14209D221DB7215DBEFA3B30F7EB +:10FFE000C3F1EA0B602E06982ABF164C2D01387F0C +:10FFF00004DC369C3FA65D3DB3CB85FF5CFE5182A1 +:020000021000EC +:100000000100ABECF83F8ECB3AEB2AFAE2BF45E1B8 +:100010007A30D335FCF911FF8A0F34813927361E27 +:10002000F77DFDDB346FB75F05B305A0D93F876966 +:10003000D8BF18CC2300F6FA6B78FC8E7F358FF78B +:10004000F9034C0FF8D733FDABBF8EEFBFE77F9EB0 +:10005000C7EFFB434C5BFDDBF97A83DB09D01FE084 +:10006000426BC540350F8F46632F6E689F9CE94BEE +:10007000416A16740E1DC883D40E968C0CA473248A +:1000800096075E0F403AD3B08AF79767BEC5F2C0B5 +:100090001F9F1DF99D0DDA4F463F339402DC03820A +:1000A000FFD965FF7D494AA5819A23A1BCEECDEC1D +:1000B000031B2580FB2090BF00E99CCA3ACB7889BE +:1000C000EE4F719E42794881CF4C3FE6A24CE867E3 +:1000D00052778A078553BADC6480A58EB556180E10 +:1000E00080523A1141F99A40821FB3009640D80AD3 +:1000F00074FF8F96139138392F03C8826C3CFF6BC5 +:10010000169EAF5F077A3E6E5DB94286B274929BCF +:100110008BE5B60222BC9E4D7EC45DE3A0FDEAAC39 +:10012000B44EE2BE4B1DEF5871D0C3BEADFCFCB562 +:10013000F6D5F55405B080E6AFCD54EAF6E0BA2B1B +:10014000FAB43D209B7A9087D3DC79653D94C3BF98 +:100150008C127A9553A6D85507D9A9034CA8C7681D +:10016000480ED9709DC55975A9B42E1A662AE0F5B6 +:10017000252D32EB03CC8A7910EAAD52D35B3B8458 +:100180003F21BD544EA89C01A8BFC59B8CFC2C757B +:100190009C64B97F0BCD3DF25B054F7F23A776E7CB +:1001A000B76AC22DA769BD2A4D6E7C1DCFB5BA4D69 +:1001B000DAF14EDCBC95EE948C53C9E4583086E4F9 +:1001C000827CB8C3E46F8764F6B7DEECE39C1FD88B +:1001D000DE2FFA61C73B68FFE72EE3851B009E70A8 +:1001E0004F7B3E30E197D35BBF62DF0637F913DA0E +:1001F00009F991AEC775684380E75E576E0F0550E9 +:100200009E51AFD34CFB47A5503095F47209DC6B7F +:1002100050DE939BF71F213F996C7784496EC84449 +:100220007BBC5E27B58BCB134F868229387F7C5BE6 +:100230004026B71D7B480D3A703CE63D05358D7173 +:10024000E61D9F4C7ADFE96F6239D4FBEB99C6FC5F +:10025000E726F6331884D7B2AFDFCFE021BB89E2BF +:10026000DA4AED4CC134A83361C0EA724C93539022 +:100270008FAE30B8E97AD1215790CE55DCA6C8A907 +:10028000782EEF493548E75E876A506C1427037271 +:100290005FBC6E3343D88671C4966902254EAE6347 +:1002A0002F84821407F5B8D69C24EC79D2E57A998C +:1002B000E296D3AA6EDF82F2843793DCDB5CDDCF7B +:1002C000FD96DBC472FF32DDF7961B29385C237D77 +:1002D000F9643FEDAFBC48F6D390ECB6E173897199 +:1002E0005A8F8BFA3ABADC7439563BBB38EE2F5F23 +:1002F000DDC5712F71DF6A13A8F528774F85ABB87C +:1003000016D7695F03F367E1B8CE8234AFFBFC8F89 +:100310003CE5EF93BD4C9527B42A742EA7E9AA7645 +:100320005DBDFA1BDEBFD7FBDAFED52D5EE7424787 +:10033000ECBAA34812711ECCCE53F6983EAF57EFDD +:10034000133BE718F2D6A4EF5543DE9A8C9136FEA4 +:100350007E85FD11C378AAF331C3FC5B32D718EE5A +:10036000DFEADA60B87F7BCEEF0DE33BDC2F18E6E7 +:10037000DF59B6C5707F96F21F86FB33655024F4B3 +:10038000B97C2964213F9B0BF54CE7412BD307A097 +:1003900093A98A96447421B8993E043EA62B3CAAA0 +:1003A0005C847613B5740E20BFEF78E3EF796417A1 +:1003B0001DBF1AEFCC72C5F2B29EA77F6A3EEE63F4 +:1003C000453DF5600F038A84DDEAF1BE57FD24C484 +:1003D000FB6811C6133C67B43199E34C34A54F4810 +:1003E0009262F1042DD244F958F75B3DBE14CF73ED +:1003F0007FB092FCE83D1946B8BAC79BA9662C0DA0 +:100400003C74DD9D737F7E6CFFA00916939D6D4744 +:10041000FA3AF2D1775EC4EC8AE3A780F8407B9B7E +:100420003C770A44F0FA4C272821CA4376C848A2F0 +:100430005878B92B6F36068899DFA3A2D09E7F48E3 +:10044000570A49DE81A726A49DCAD5E2D28DA8BF4E +:10045000E326E6079648A111288FA60631CE5F94C1 +:10046000C6FCDD0761D6E3FD10B110FFF301384E85 +:100470002F0017D30741617DE2CAC905189F1635C1 +:10048000983D1B91CFC2F4CEE1E49FF9638FA64B58 +:10049000782E2CED14E2A7D004EBA9BED1F9A8D593 +:1004A000F8D858A454D0F90AD35B373E83FB77368B +:1004B0009A602BAE737AEC630F435C3EDEEE299FAD +:1004C0004EF37648A0505E0DB4D842DBB268FFCE42 +:1004D00001940FF4792B3C15338B70DDD945C0FAAC +:1004E00086D6BF00E9679653C81EA6F46719E07365 +:1004F000C37CF93DF967809F2B2459DE00E2421945 +:10050000EFCBE3875F7F6DCEDA3CE6274075DC7684 +:100510008F3A9FCF6FC55840E7DF6C0B6DE57AAB24 +:10052000669884E7AC7CC966A2FC7F14E333DC0CDC +:10053000F0B9DFCEF47FFC4EA65FF833991EF7BB0F +:10054000987EE9CF61BAE87B6400F577BA48A922C2 +:100550007E7AE3A3F73823F8884A30A7DED1FD7E00 +:10056000A5E60F050D279F4C263B6892DD64A7F991 +:100570008D689878EE73CD63427256BC5CD5C7899E +:10058000CF82A68FFF30BE849E333B259C7FAEA9D1 +:100590006B00F96FE2F9AEC8A3C52AE4A19D7747C5 +:1005A0005AEB467A7E47E3703A21C611107648FA34 +:1005B000947AE2630DDBC9AF8A44BEBFD3D659E259 +:1005C00074C4F8032A3130CFD46A7966AA7C39958D +:1005D000FC6216AD3B96ECFAA60F68BFC001E1873E +:1005E000A8D7F9BE387FDAA5C941A7F92D561FF95A +:1005F000D38E964FEEBA1DE53073DCAD5ED9159BF8 +:10060000FF3209C14BF67DE9DF9FC9E0F94EDA6A96 +:100610002E6C99EAC479F7D9F7BC4B22B8DF797C04 +:100620006A1A8EE7674AFB882E70654D4BA7380023 +:10063000217EFEC19CC9FBC8C466B86759A99E98B3 +:100640004C4E1517772BEC186F0C71BE9F617C4BCD +:10065000E660C3FC5B5DD986FBB7E7E41AEEEBFB13 +:10066000CE70171BE691BF52BD8D7CB0DE619B1C26 +:100670001A21911D5CF86C19F33FB784F88FA2FC26 +:10068000AC58389C29DBF0DC3314361AF7A6927F7D +:1006900026D6B5CB5B5EDEA7B87AAF6BABC0D737DB +:1006A0002CF55ECFF6560F5E6F5D8B71E40F14472D +:1006B0000ADFB8C719C473EC187BE90617F2F761B3 +:1006C00051CFF56E54AB7713EDE88ABD4A2E613FEA +:1006D0000765A07A48AF7B13ED08E049AD0E10F432 +:1006E000A7FAFBCC8F44DEFA8AFCBE5FBC7D6B347C +:1006F0005464C8338556CC2FA89FCEBFC9B0952E61 +:100700005CC673E87AC88ED93F3CB4E5DD41257CF0 +:100710003D40756D15E5055C3FD923897597EF79E7 +:10072000775046EC3EAC3A6E980F4F48FB0CE3B561 +:1007300059C6F1D393F7C53FDF5B3CAADCF488557B +:10074000C5385DF9ACC4F92AF1BE7E9EA97B93142D +:100750008A9BE6661BF753554E051407554D98477F +:100760007AC8EB7A7C982B434D4F716E80B6EE8C35 +:10077000BD4920FF8C758FA2ADD07902FF25F2CD47 +:10078000D1BE0AF8E2F6C9F288FAAF23ADEE9FBEF9 +:10079000C3791D7F063789BE234DC4DD8286D326EB +:1007A00013E5BF3EC25E0A9C11533AD2E8E2E40070 +:1007B000A03F552F4909980AF1FEF0CE4FECA8FA58 +:1007C000519E412FD8516F9F994C86FC13A5988755 +:1007D00063CFCECCB9947F6EDF9B1436FD0C7E3C8C +:1007E0005473202D2C177EFF00D98DD84701F48F2C +:1007F000EADF81BEAF427182F8A7F132CF90A3CF7A +:10080000E2BAD507451CC0DB8EC47EF6BEB87E16A4 +:100810003609FFB5E32FD53B55109AE620DC208C36 +:10082000FE0FBF9CFFCFF43832B8CE213FBFB9BB1B +:100830005FEB7E5F7D58F8FDF9E66F3FA2387F1EC3 +:10084000F35FBCDFEB72D3FDBDFA7999FD52BF7E39 +:10085000AE599E1EEA41CE65BA5F296EF6D75AA7F9 +:10086000D8B776E2C5BB28CFD5B6A086A4EEFBE804 +:10087000B47ABD0CAEB87D76ECB62D0E39627C44F0 +:10088000F5FCDAF26DFAE43C41D750FE853A2DFED4 +:1008900088BA06F3AA2583F2EA2CC9BD0DC9E196F0 +:1008A00081E524BFC312845D1E5EE21E3B9EEF6E97 +:1008B000B11C5D77507D06993966DAE72E4DAF772A +:1008C0006BF8D2EC96D92328DE7FD2B0F0B042513B +:1008D000CE93CDFBFD1A025C1F1E4EF30D5D89E722 +:1008E0009C1914767E38ADB39DF0A8C31393A5A0D0 +:1008F000C4EBAF8DAFFF0E5B7C436B982F0D97520F +:1009000046CB3F26FF847E598B8BA8CF8024FA3BB1 +:10091000F603F3A0A719675802A17D0AEE5BE50E66 +:10092000739DBA0C042E9058DF574DF8DA4AF9211E +:10093000B11F9DDCB4E78854D0038E9160B7D7C255 +:100940002D12FBE0DEF0871FD27DDB3C71F8616287 +:10095000BD7EA52ED5EBAA6DC9A1AD789EB727FEA9 +:10096000DBB965385EB52DD9497DF7D9976C018A19 +:10097000CF67B7DA4212DE3F9BDED9467DC8D99DEC +:10098000F96E5C012A4DAEFF7C8DF2FC9F2C6C173A +:10099000006EE11F57ECF4D16314EF6AB7A548402D +:1009A000F5B52AEEEB3DA0FC6A0AD7094B760D0A95 +:1009B000D9A4589E21FF706169716673924245FF08 +:1009C000D90377F725FCAADDF4FA30C6C3E4278EF5 +:1009D0003D86CF2D7B25C543F504E401EB6DF1D6B3 +:1009E000515BA83E7ED1A2EE27FE2B5EBD63601652 +:1009F000ADFF717F207EA2CDBB06507D14ABDB7BAB +:100A0000AEF7CE3767F785BC989C743C71FD1FD755 +:100A1000F848EFC9928BAF9BA146194C76D1340BA5 +:100A2000685D8F2C29E4979D1B92B94E4DB4BB6332 +:100A30001ED1A72CD7F1877E60CF24FF5181E5100E +:100A4000DD90BB7523CAE93B4FBA96AF3B47DE95B5 +:100A50001F6F9F6D556F917D6EB2312ED29E64AC2B +:100A60001B74FABF9E34DEA7D27EC1804354ADBE54 +:100A7000641CE761BF87CF7B82AEE24790AED4E4CF +:100A8000DF35DAD7E1C1E797D6FFFE8DF7582E9B09 +:100A9000FEF133DAF78043E031EF09F925F60395EB +:100AA00076817B006CE1F3EAD74F6FFEB480ECF007 +:100AB0007463EE48D2E342B9F5D48BC8E7B994D653 +:100AC000638F23DD79E023D64BE27913F19B7649DE +:100AD000627E97131F78FD1EAF4F2EEECFEECC7DBA +:100AE000DCC28DF92CBFA9725E5FD263F46C2FFD5E +:100AF0008A764E7D7DFD7CFAFAFA3C67B1D0D7FB51 +:100B00001AFEDE616D3D47FAED782357227CF0CA6C +:100B1000F5F4D682B4387BF9A570F97B357CE4888E +:100B200069CD6FAC688FEDF5CF58D4F8B8F713F1F5 +:100B3000F82BF5A0022EE700914A386F2173661C4E +:100B40004FD4C7E40C389EA01D4FA2F3A05F4ED433 +:100B5000282C5533196FA7F590264188C7C1C96E57 +:100B600017D149928F710FBD6F98063543880F9347 +:100B70003DC238E15AC227B16E999DB6EE8E2CDC8B +:100B80006F6D7F5847F5CC5A8BF08BC08264EEE7CF +:100B90007439E979069C7986FCB2D6092E33AE33D6 +:100BA000C70CEB2DE962DE8D28E7C30716BE4BB8F4 +:100BB000EBA7E69AFEB4EF51C7B3F99289EABC50AD +:100BC0000AF58C9F7DF427EFDF70EEE7A04CA4BA06 +:100BD000E29EFD768EFB89F8C42250795C0911CB28 +:100BE000057CEE8BB13F6CDB0B31BEBE18F75D238D +:100BF000F509F7A53DE9A5E703E5904379E96252D8 +:100C00006A01F1B3DA2EE8A37D52B7123DEB74040A +:100C10000897BD98342C44F9F445497D80EC199F20 +:100C2000E33E36702C3944F9EE5159AD621C3ACD91 +:100C30000A12CE8FF6D7E4D2012C97A8459BFF8DE0 +:100C40008BC725151EC629E1A28BE3F2F884BC539D +:100C5000926B12FDD98F62FEC44EB321EF94146AD9 +:100C600078CEDF5D5CA74EFADE7CD5BC74B958F453 +:100C7000BB25FD4C353DD58BCF68F783109605CE4F +:100C800023EA85F157EC4B91498F55DAB88AF21A6D +:100C9000DA5534D51E9091DFF1CDC2CEC69BC37B11 +:100CA00088629485D5545F3461DED3CF817105327B +:100CB00073D91EC6E9768A6BCDC379EBA41AEE63AD +:100CC000EC54D720DD28B5F2397E059D4C152D9FBB +:100CD00097839BE914F031453B653A1DEA98DE069F +:100CE000F54C6740ABC8FFA3C341CE6BF08493FBC8 +:100CF000C15B2B4D547794FCBAE7FEA1518B27BD05 +:100D0000CB011DAFF4A7CB611AA0FF65F7208F219F +:100D1000391C4712E591E8A7132122B39F5280C8DE +:100D200026FCC0C5FE5A010A8FA75EA71CCA22AACC +:100D300099F19B447954F46C17BB35BBA8255BEB48 +:100D40001FD35357B18BC7BABED0BF32A90E4DD4F3 +:100D5000A37EBD24B9BCCB85A1F8B35D27E79A314A +:100D60002F951497AFCCC6717BF1B773CD98CF4A4E +:100D7000C697EF1A8EE373BBBE13E3C2F2628B1BFE +:100D8000BB983517E74EC1F92AF9672151F4438A18 +:100D900067AAE88F5769758CBAE6376E27FA8B3ADF +:100DA000D4E1263EED58EC133E2A678BF78EC3A69E +:100DB00087F75A70DE498B7A98FC77853D9CEA422A +:100DC000F9AF5A33752085CEA7AC62BECD26705AD6 +:100DD0009D3FBC1E48C2F1CE9DB92BA5E1D73E0771 +:100DE000AEFF25ADAFAE191120FF551B25B7D06C56 +:100DF000F9C03928C3F6560B106EAAEFF7E468F570 +:100E00000CE747979BE3F760ADCE69DF999B4B7A80 +:100E1000EA2A163818646415931C8F8FF675D1FC76 +:100E2000688AB0B72ECAE5DEDEE9E012E51B9A9FBC +:100E3000783DFA151E009F3797A817E97E75F26571 +:100E4000CEFBE78A3E5E17C98AD9AD844A9B87FCF0 +:100E500007150859393F4C705EA95329DE2DC2751C +:100E6000501E253E3548216ECCBCCE528AABB8AE62 +:100E7000A904F7A9B6468615E173CFDE7DCC2AEC2E +:100E80006E88B03B2D2EB5EC3EF8F86031F4419CF5 +:100E90009F55EFBEF4DDE728BFEAF30E374D8FF91B +:100EA000D70B2BB9DF0487218EE87E37AEC9C6F594 +:100EB000F6F8E6518B68DEC48FDBB289AF496D115D +:100EC0007E8F166DF974B03887DE875C947E4E3E57 +:100ED0003EADE589D3769117E8BD30F77B8DE2BD55 +:100EE00070AD8673D6B648A100C71FD13F2FD6F884 +:100EF0005B71B0711FE1278B373D3883ED2824FAF1 +:100F00000A17FE525C587A44F4CDCBB61BFB8D6AAF +:100F1000EA9B693E84AD640F2BEA13EE6FAAE0BE34 +:100F2000B93A3EFEF7D0377B4B347C6C280C65BE5B +:100F3000E4797DD51EE261625F5C05CA8412AE7BF6 +:100F40007D32EDEF35F78C3FF42FD0DF9389FABD7A +:100F500052DB9BE4E460B958B99FA8DDBCD2EDA494 +:100F6000B1E6B75B4CD453E3C4773E80F8E7743FF7 +:100F70005EB25EE2BE0336F5631B2C7CC5A610BFD5 +:100F800085AF0CE43E04FB25AE0FB7BC625B4FE3BC +:100F9000E0EFFA04E442C2A13B6F201C269884F5DE +:100FA000A6C0F341F2300EC3B8C823255ADCD7EAF5 +:100FB00000081719FAF9A096FF6B53460EC4CE39F4 +:100FC00036EFC020437F12D4EAED123A27D58DDBED +:100FD0006F10F793041F7B3EFC8764AA7B1BCDBE7A +:100FE00064C2B5CF1F1ACE7D4C6F72F7621A82AB06 +:100FF000BCA7F47E3A23FB6A7A2B79DE2CE4A5D9D0 +:10100000ED9B7E05BEB4C4F4A2F337557EADC24A53 +:10101000B8C843E0249CA4F6E0CB413BF5851B8097 +:101020001188F320ECF9FC1913BF772F859C7F9D65 +:101030008063EF19B33B84CF37687191DE3FBBE229 +:10104000ECCCA6E1BF49AE3EE08AEBA39373D20D90 +:10105000E314F70D86E7FA960D37DC47796FA5F5AF +:1010600021A0B4E695C6EADE3465B4E1B9A752A77B +:101070001D60BF6F7D9871A97ED33DC6F3C8CD3288 +:10108000C503B820EAA532FC257F1B038120E96354 +:101090005CBBB18E2A8BD471DF9874C86CC0016CB4 +:1010A000D7C0A5B6907F519C1C024344DC4894B73E +:1010B000F1FB8BDA8332D77BB543B150CDEA49DE01 +:1010C0003719E4ADFBA32EF7FE3EA3DC07CE31CAF1 +:1010D0007B906A94F7E0C546790FAD31CAFBC6D55F +:1010E00046B966058C72CC5E3FCE307F445DB961F7 +:1010F0007CF3F3B719E68F0ADD6518E76EBFD730CA +:101100003FBF7EA1E17E61D3D2EBD27F51B8D63012 +:101110002F51FFC5077E7B55FD07F057E81F581F6D +:1011200065A88FB0EBFFCF0E4EE87156B783EB8CFE +:10113000B36F92CF329E302112203B284B663B99F1 +:10114000992CE2CEFB07CE1F5270FC81ABD892499E +:101150007596563FF8B438A4F733897DE39D655200 +:10116000C2FBFE24C3FBFE6B7D57E76D0D1BC6451E +:101170008780BF9BF11C71BF4DD47B5261B8ABF42B +:101180004CCDDB44C75EE0B4DDAD5FD5BFCF4BECEB +:10119000B760F9217EAF384F7F2F434E51DA1D9F44 +:1011A000D4FB31BDCF4DEC7FF5BEB77B9F26EA98CF +:1011B000EEFD863BD3CC75B4CA75F57E49659C734C +:1011C000CB2875B0D74B4D00F6C926EA93234121B1 +:1011D0004C05E83D7494FEA72224F0CCBD84C7479B +:1011E000D380F17345AABB3790C7C777464A057CC1 +:1011F000443FC55E758417F57A4272AE2B267C6239 +:10120000DCD7C3A81EC9F18A3ACF26A3A4302F0D7C +:101210009CA7005DFF215D19E5F5C6F092DEEC2686 +:10122000F1FBA4067F98A9D9E9E6EF9712F1C588EA +:10123000C9C5F569E0B7127FF7F3351D6E6CAC8E4A +:1012400039BFDEC2750C68FDFCFD9AFC75DC639E3F +:10125000C6CF095C6231E6E5FB9BF6B35E9665B6E8 +:101260006B78490DD7E30F0E7178F87B38A5D82D30 +:1012700070321D07192CFF94BAEB5AFC2FCB3C6B34 +:10128000C0A1E0B57ED7F5BE3CC6B758FFC4068105 +:10129000679ED83094F1F3D8FAE7188FBABFE643C7 +:1012A000837FCC5F7DD4E00F0B02C70DF723199D20 +:1012B00016C21F236F0C9A761FCAAFA3D1564AFAE3 +:1012C000403B7898F4AAAF1FD9903B85F6BD369F76 +:1012D0005FF339DAFCADAC5F9DCF63FE233C8EF843 +:1012E0002309DFA7093E759C43A7D6BD9063A6F7E7 +:1012F00089521F37E1CABDE11FBA9F994A87F33A65 +:10130000174DAE530227AA1943F55FDBE401E574DC +:10131000EEB6A156B3A023C57850995D8CA74D2792 +:101320001AB538D6132ED22689EF89E649CA4B0B57 +:1013300070DFC747A94F913F542FED2C20FFAB2EF4 +:101340008C3C20E1FA5DFDD58D241F09DB8B41E942 +:10135000CC077F7776C6142890D055F679BFBC9716 +:10136000FAC4337D02E7A842D9DD784C8CADC21FA8 +:10137000DFF71E60FF3B898B119F813F4B029F72FD +:1013800044ACB3709D8CFEEA73B42F7D4F46EFF7EB +:10139000E83AD9A78E97462DA24E8C6AF5E266AF41 +:1013A000A8675F4AA04D54E312FE4894E3F5D323A7 +:1013B000094F3FBFC90654DFE2FE8AA924F6FDCAE1 +:1013C00000E485EAD877ADA2CFF4FCC516A638A50F +:1013D000E3AAAF7BB378BD8C6C819766FC33C62DD6 +:1013E000F2C348EBB0592971E73D048C6377101EB6 +:1013F0001D8763BFEE15FD3A3C24E25EC786C18CB3 +:10140000B7AF3878E218C5AF7BBC6A23C975A1C9EC +:1014100055CADF67A5EE61DC6CBFD7C5FBE27999E1 +:101420005F8C436B494F2BEC11C6D9AE85ABF7C629 +:101430007FC7A2D6E7F21847761590DDE8FBE239C0 +:10144000F67BE3F06FFD1CB175AEEE073A3EAC8F54 +:101450004F6F7E6AA486EFCFF7F5905F8F69726950 +:10146000B3F48CC75FF28AF778DDF4733300E1FFE1 +:10147000B63E98FB917EED15FC77CC457E18DF508B +:101480008A48BF2BEE72B849CEFAFAB88EFAFA55EE +:10149000F6E91AEDFB8AF85F5A23F07BFD7E5412C1 +:1014A0007A0D6C1078EA8ADD478F3D8EBB2C79353A +:1014B000BF98F281FE7CA29C51BE23F9FB3B59BC34 +:1014C000FF42F99EA7F51371FB9F2BD7E850F19EC1 +:1014D00036BAE5D230FA3E6D057D0F5740F621F061 +:1014E0002F6830E25A28AF00E11BDDDF6B01BF1F20 +:1014F000B369F9C4A63F3FC46C78BE3EC597548A11 +:10150000E77F438B1B383F64A2EFB9B5F8D4A0F551 +:10151000DD89F84B43ABC04D1B32AD5C4753FD43F7 +:10152000F7F5FA67D58702375D9525EA6C3A27E922 +:10153000593AB28FEB852BB8B884F91EE5986E55F1 +:101540008794923FA92B399FC937A29EE97DC85F36 +:101550006FD37004911FBD5A3EF4D23A74AEBCBE34 +:101560009C274BB47DB1BF60FC6E2CA85AFDA0E156 +:101570006F1BF619F087FF037A5FA88030310000F7 +:1015800000000000000000001F8B080000000000A9 +:10159000000BFB51CFC0F0030947B0A3F20FA0F13D +:1015A00067B2A1F2B3B950F9875950F9FE68FAD180 +:1015B000713B13030323137E35F8B0083303830C08 +:1015C00010AB00B10E33F9E680B089280343A904BB +:1015D00003030F906604D23E405C06C4FE407E27A3 +:1015E00010CF0262197106864B405A5E8C81E1A5CC +:1015F00028449F2D90FD438C3C3BAD792973F32803 +:10160000A60C5BCAA2F285D41818BCD51918266B93 +:1016100040F80648F2AB8062C26A10F611790606FD +:101620003D205F5D16BBB94781F2FA40F9DD1AF83B +:10163000EDDFA183CA773543E5E7A1C937BAA0F248 +:1016400035DC50F9AAEE101A00B1C92A3BD80300C4 +:1016500000000000000000001F8B080000000000D8 +:10166000000BCD7D0B7C54D599F8B98FB9736732D7 +:1016700033B949263079C14D081030E02484808A7E +:10168000701322449BC204698BBB6C77C4D646148A +:1016900008EA6A7C6C33790701096A77295A3AB1FA +:1016A000A2A0B44D5DDC3FB5D69D40DCD2D6D6A01D +:1016B00058E9AE6D23F5DF5A57D9A052A9D2B2E747 +:1016C000FBCEB9997B6F2609E8EEFE363E6ECEBDA5 +:1016D000E7F19DEF7CEFF39D1345F4106D0921E7D1 +:1016E000E1873E5F25F4273BF924A48790F9F01C9D +:1016F000922373E019E3EFD933B8B64F2045581C55 +:101700002495841410F653D0D4B9599C4BC8641254 +:10171000FEF1CC425A1EBABE8E0468F9F5ABFF004A +:10172000CFCED5D5B557E984E4ACE93BB69C3E8332 +:1017300091B8102D25E4412212920BFD15C7AA7C09 +:1017400084B44367971332299663C44AA160D002D8 +:10175000217FA7F28188A8CBB4ECC75F93F3309FB9 +:1017600084282451821585F3EED1ED9DF5CDA71F78 +:10177000DA99750AE1FFB71298DF44EDC8ED6CBC49 +:1017800018FDE73CC54B5E727CEC27A7C152268052 +:101790001FFB776304EF9BFF57C6CB25E51EBD8279 +:1017A000CEB74ED4E2509FF465C8B41CBC452609A0 +:1017B000817EAFE8115CFAC4EBD249486D9F0FF10E +:1017C0002BD4FB93F07D8E08389F2977BFD9DB158A +:1017D00024E4CC5A5F18E94323242B73F47CBED64F +:1017E0004C48C26D29AFAE16A2385EF8C7C5B47DAD +:1017F0006CB518DE0BF0D4ADCA80F766BD3BF93886 +:10180000A3E983E832C5A3CCE943AE130DCFDC4F87 +:101810004F1FF227A48FECDB2DEDC8C5AF17E27D7B +:10182000FE85D3C7A71DCF5CD7D17CD582704CB9BC +:10183000BBD843E8FA3F50BB2A3D9AA2DED8EB5A08 +:101840008EFC1EAC23463C45BB2DB09E38CF984D38 +:10185000DEE093AE8F34B2BCB7D9D64B9A5CB9A652 +:10186000771C7C4841FB7CCD7E9526497F338B16C7 +:10187000654D84FE64DE5FA7B62E46806E81B62974 +:101880003EA49EB204A1FC414224BC974320D2B2A4 +:10189000A219F1FB0428C5715D4CF8D462D1369EC3 +:1018A0002BDF6B5B0FB2262658E1579A1484430650 +:1018B00036E1F22E82C28DC10D439C9F06E57B6C02 +:1018C000EB2FFB48C243E5EA96E272625D07934E56 +:1018D00005C1A4D37B2E4CAE38C75B6D87F382DB8A +:1018E000F964FD77669BA2F1DAC9E477269E28F2B7 +:1018F0005E815F2CEBDEE52287844B0969CBEF8CA0 +:10190000C1DB2EF8DF65489F20B448577EB906F446 +:1019100044F60932C0E931C9239489F57A898EF4F5 +:101920001413EE20504FF245104FE6F7B1E1E27488 +:101930001733FA8B69BF9FE5DD7E96EB3352E17A70 +:1019400073C884BB08E7912CD379BC7B17FD1FA516 +:101950008F589910DF2B8CFE5E07FA90CAA33A7855 +:101960006F91276EC12ECFEAF8B723CFBC36631E26 +:10197000A5C7C1B044405CB53EE3366A68FFC7AE58 +:1019800014E26E81C34BEBAFE070BE686415007D5E +:101990000ED6B8917E572CFF3008E47BEAD02B722C +:1019A0002A7E5DB1C8958483FEB7C93A3FFADF2429 +:1019B0001803F9B206E9C8846B43B984700C2E127F +:1019C000E230CEC0AF7E7FFF1514CE172B84B05B04 +:1019D0004778FD848E3768BC1F1C4F4E10737C9D6A +:1019E00068804FE7F823EBA186D7005F36688A7ED0 +:1019F0001F1DEF66297C14F41899CCF4438336A399 +:101A000006D64712187D2C1572B05D9BAF7512AECD +:101A1000BBB436A5BC6AA08A422B87EFDB668C0B71 +:101A200067DC353C64A1EBA6D70BEF1FB0C039478C +:101A3000F0077F97467F594016C03ABFE75B959EF7 +:101A40002063F7F776B3DA22BB08F9B059BF7FC03D +:101A500035FAFBCD1269EC2B1DFDFE1A41E5F88825 +:101A600029609F99F31E99A72F88F47D33885F4AD8 +:101A7000EA37EFF3B4C856F9E398C7087E3F613BF5 +:101A800035786B2C57077E8BAE14A01F99FE5399A7 +:101A9000E4C79B0FD433BE73C0DB11FCEF81772208 +:101AA0003E7ECFD7DA09F66A9B8BD14B7BB6186E98 +:101AB00025A3E9C55C0F138F17BA1EDB040FF2874D +:101AC00049470DE2DA71D77D223ABA03E8E892FF7E +:101AD000793A7A10E868FEFF493ADAF57F918E92FA +:101AE000E5E5682FACE47DF50FFDF62190CFBF3022 +:101AF00024947BBF58C4E4FF2FA24C2E0E92E8F62C +:101B0000F9A00F8E4B28A7068D363FC24B4D629829 +:101B100007FA5D94FE5E017B692695EBCD2A3EE9CE +:101B2000EC0B56D1EFC7AEFA301FF4D731BAB6601E +:101B30007F13326C18B4FD4B23656A8043D9C3CA46 +:101B4000C32D6763609F0F0AACFC2F2D678D188E25 +:101B5000B7AD7339C5E74AF895C2B17A9160C453FD +:101B6000D0C54F0485E1A586D8F42A5D979F0894D7 +:101B70005ED4C866B4AB098910F40F8BA99D60B11F +:101B80002F9A4081815CAE71A3FE73F6FF12B70BF2 +:101B90009D76DCEA45652ED017EEC86979883E57F8 +:101BA00046042C03FE350BDCA22118A007228BDC97 +:101BB0008F82FE8BC8C4A5A5E0D79586DB66779D8E +:101BC000E67A8CE2650DF35BB482FA39C9FAA74D67 +:101BD000FDEB98CF587461CEC32C5FBBE8F4401680 +:101BE000CCBB56084F8786AA56F045BFB5FF34D305 +:101BF000BEF103DE7EB1E6DA74460751D4AB263D72 +:101C0000FDF88DAFB860FE647516D2E5EA3AC96694 +:101C10004FAEAA49B3953FBFE8DA71ED7012B5E057 +:101C2000C142F7813C82744A7E43ED144AA7B1EA6F +:101C3000E128DA2D2705BD8D96D317374D857EEF28 +:101C40001133B1BEB0B869E610DA5BCB90FED37841 +:101C50009FE94AE3EF8B40AE4E17C9A33AD8A3E3FE +:101C6000FB051D9CCECDB22B188D09743DF5985601 +:101C70002E8D83EFB821D6A6F21BA6896CDD3A62C1 +:101C8000ABB4620068C02E37326A1AD1FE33EB5310 +:101C90003A9E2666C3B8317C3F42C7DD745EB49D70 +:101CA00097D922247DF6AA7432CE3CDA1DEB4FC5BB +:101CB000BF914ACEDECCE1238758FFA64C4ACFA481 +:101CC000FDA7A86F3EBB78FF67C322190438E588DB +:101CD0008AFC50524DACFD10A30CCB0A2FBA431115 +:101CE000B590E2D35D2AC2344847E9A386AC031E0F +:101CF00062B8DE5BE9DAE65BF872EB9F25F4F36F1E +:101D0000168B5A406E6CEDBF89E8141FDE509C6044 +:101D100079CE8D2AE0692B75B206617CB98F001CE3 +:101D200069F9F4773A4E9A46E23AED4FD6FB122221 +:101D30002DCBB5246CD04F7E2D2C78A99C381C2A35 +:101D40006A91E9FBF6B504E52301E961A19FF6D0AC +:101D5000CB8604F4B3868401E0F6E03A9C6767E939 +:101D6000BAEE42FAFE4C9D8CF103728EC26BFAF50C +:101D7000D4CFF0961003C6DB9A43E23EB4830DC481 +:101D8000AFA2B1F5D3771593C43CFA3DA3B21FC6F9 +:101D90008FFD3D617C49985C93B93C2132A53F1889 +:101DA000BF490BDF9782FE5412BD499C6F59672DC6 +:101DB000827EAC136FE90AB906F0DB5E46F9208536 +:101DC000DCBB4314910EE2E1552B8B528C738FA830 +:101DD000A37C32CBFA5905E11FAB7EB29E4C12595F +:101DE000D0B521005E482488F3CB24233F0694B36A +:101DF000F87C279146AC175AD8D30FFC966BF45554 +:101E0000012EBEE6FFFC315C37F28806762C85B6E3 +:101E1000F87C56525E80CE81F9BD1716D1EFF08B5B +:101E200009CDA01DF83D8321747E758271B9746857 +:101E30004201BEAF596D07BB2440C2027CF787E563 +:101E400098D5AE4F27B46C8BA790E3C59584897C59 +:101E5000FCAEF503EB68258D9702300F068C7F05ED +:101E6000BF699B3F8A7ED8879EC05C18EC4E6FE0AE +:101E700051787EE8991247FF2CCCFC2D95FE03F299 +:101E80002E7DA16CF36F320C7B39CBE1872D937CD7 +:101E900038CF8CCF12EE5F1975D32725E1A210D56C +:101EA00003BDECAC9109F8FF3E1F83C7842F4BBAEA +:101EB0007701EAC7B07C12E0A0684138CE90730980 +:101EC00058E24009C1F82985EBA403AE930EB84E41 +:101ED0005AE16A52D97C9DF662AC9A943452E07E03 +:101EE0002872FF83DA4D60379E21EF18B540389194 +:101EF0006B50CF0634D6C6A70E62B042231AD281E9 +:101F0000D36EA4EBF49ECDFF5AC8CB3A11601E14D9 +:101F10004EFB77928FF48265898CC485D72D34F17E +:101F2000A57FE1DF29FFDD74D44580BF281F4BF07A +:101F3000DDC5BFDEC4E3C3EBC0BFA6F8FB12890456 +:101F400000BE77898871A877C9CB81791639794A1B +:101F5000E4F6092CB1958F493804725CF6750E4A87 +:101F6000014483496FC2795CC73093F33E467731B1 +:101F7000A2B6A03EEC66FEA7194FFD728FDD1FFED4 +:101F8000CA2E7BF946B26A12C44B6F7CC845E2B4D4 +:101F9000DF9BACFE3D5DA757450DE1FB0A69EC04F4 +:101FA000BBA4CBC5EC8D751A9121FEB9E1FF7DA3D1 +:101FB000F27A3A9F33200FE683FD4EC1B7E891F5E0 +:101FC000C1B862948E9E5F9B105E718530F6FCBA3C +:101FD0005C832BC0FF8E6D77A19D499C71D08312CD +:101FE000C6412DED10DE1BBAEDF39B68FECEF91253 +:101FF000F200CE77FDBEEBD13E1F6B3ECABED4F6DB +:10200000A64F126C711F93AF4D7A77F27785A4B308 +:10201000B80E558368AFFC3A2DDE86EBDBB800D6F0 +:1020200077A2F69741FBEC4FDE7EF1A71C7FE90417 +:10203000ED37A8C3CB60BDB7047B22C09F661C6B85 +:1020400023891979F457D7739B6360BA8DD40B5DDC +:1020500060BD7C5A4FBA807AC5E3F7778ADB253FAB +:102060003AF02D05ECD4779F7C6305D80137FF400B +:10207000222AA5875307FC2481F64A5C01FB663DB2 +:10208000A5BB38961395D75AEC614AD1B80E377F65 +:10209000D78F76C4FAA7DDF13ADA7EFD3FFF762EC0 +:1020A000A17838D53AFCAF7940CF4F0A2CEE1A1BF5 +:1020B0009A7B2D7DBF5E267F1B494147D74B8C9F66 +:1020C000DEF97EDA1AB013857DFD5FC47EFBBEE0CB +:1020D000725BF4F11AC985E3D27AE847C4F60BF1D2 +:1020E000E90283CFEA0F98F1EE77F60B0CBE43AE10 +:1020F000B807E0DBD7AB4469BD4DFB4E235D2FFD38 +:10210000EEB70380874D87EC76FAA67D52C23D1765 +:102110009F6FC01334A85009F864FCBCF1E006D4EA +:102120001B1BFBB69E067EDE74C86593FF142FE171 +:1021300004E0F535295C07E57F7A22A05354BD3DC4 +:10214000B8370078A5FD5EAF50BA5AB9D0DE0EFAA6 +:102150003F9B39BA3FEA19A2DFBCA96F0B1BEFE026 +:10216000677F0FF27613617ACAE4E7B7E1979CD1F3 +:102170007A668B648F6F9D212F56E23EE0BEAC9451 +:10218000FEB3A9574CBEBEF9DB67F6C4E8F8EF3CD6 +:10219000FD1F7B62741EB7FCE5FD3DF7D0F991E7AA +:1021A0003D1AC8AB4D4FBE1A2016FC3F26B1FD802C +:1021B00053FB9F787C37E59353BF74A31D78EA8760 +:1021C000BF9FA2D3F99FFADE9F26819D7AFB0FAFB6 +:1021D0009A0CF8B8FD99A593C7B3D7816EE36EEB5F +:1021E000FAC6B17FFD90009B20843CC79F8E753A54 +:1021F00072504A4088E0DD13EEB89BE267137DD74A +:10220000540EEBB601F51594EFA5F8DE78A0EBB40B +:10221000343715DE637962089E893C128275BF7679 +:10222000E59515F0748575A013328C7AC2D96ED3FA +:1022300071BABE978EBD9ED49E5000FF9B0E6C61FE +:10224000E3F6D1F50C8C5ECF77E197CB46AFE71183 +:10225000C91E673A436EF9E66EF878300BD77FAC4B +:10226000F5DCF0CCE7C6F5EF4CF930119E1B040607 +:10227000D70EC97845027E7CFAA9C77707D93AD725 +:1022800051C49CFAF69929B0C9FB966BF88B2027AC +:10229000877FE8D6C0AE5EFFC3D790EF4E3D734C4C +:1022A000D1717F9AF804AA274F91919F41D09B1B2F +:1022B0000556D8F4983FE10E24D76B63BCBE560F89 +:1022C000E0FB37F07D9CF1C3C678FF6A21C5FAF9BF +:1022D000E422A69FE2D988970DFAA0A2F9ECEB2A96 +:1022E0002C84F57C6319D0DF58EB69CE5F83F92F1E +:1022F000B0ACEB638C8FC7E2D753BD6E59481FBD9E +:10230000CEA7B85DB1292EBC966ADD096965F1BD1D +:1023100031E2DEE6D349178A6CE773B3BD39FF8932 +:10232000F87CE2795D1CDECE707DEDC4DF3BE752C8 +:10233000EB812259E07AABA736D7A2EF3C2EAAC791 +:102340000AC1EE6C8CE51526E1EDEC9350BEBFB3EF +:102350004F427BDF2927368EE1D787CD710EF5CF2F +:102360000579F6CEE1EF737A64F4BEF1C01B4A8CB6 +:10237000EB85B8552F407F29D6E372DEDFA6E75202 +:10238000F7B7E9C0E994FDBD2D1B5F00F8DF1E74AF +:102390009118EDE2ED3E29659CA45876D9ECAC4E3F +:1023A0007FE58974DA4E0A787598775BABF15A0C41 +:1023B000EC91975D04ED4739FC969B7E6FF37B7142 +:1023C000BFA52D7023D12DFABBDD81273914413FE4 +:1023D0005A0E462AD85E68DCE6CFBA34D106379169 +:1023E00063F9B0CFF9F3C2DFCBD02FC4D3744B5C09 +:1023F000E8259974403CED254308B79014712D47AA +:10240000FF914512D1AD74664C15ADF1C5C0E1BB6D +:1024100030AED1441A13106F22F9A46FAFA5DF4775 +:102420009A7516778D4C15ADF13F7763A3E1A670D1 +:10243000E4DFAE1581FF36D6F8058DF67D5F73FCBF +:102440005B793C82EC7BF2C92769792A7C13810E87 +:102450002306C2718EED2B2FE5F2F047DC7E3E2C79 +:102460009001B0C36AEF8DCA20EF84D0F518175DD4 +:10247000967FBDBCCE428FCB42A77340AF7EF3CFD9 +:10248000D29A54747A88D355CBDF3F9E03ED777B85 +:10249000BE90CF9CD908C297C7E35D03D9CB7D100E +:1024A000DFEBBF69D98B33E87C73358940BC269755 +:1024B00054F9CA289C79C7A5B027C53A98CF3D3CA6 +:1024C000AEF768B386F2FFB1E610961FE778DDD766 +:1024D0005C82CF279BC3F8FD40F3422CF735D7E24F +:1024E000F3E9E608BE0FDCFD6CBF0278F92AE98348 +:1024F00078CDC1E635F8FD9F9BA3F8DCCBE7B30CA4 +:10250000F0E2B3CD1FE33187DA97B4423CC6C4A3EF +:1025100013EF4B486CC08DFBF9820E78BF4B66F20F +:10252000C589DF29EE3E01E44BD32D04EDD73D3CB8 +:102530006E6CCEF7EB32B3370F72787EE0897E4750 +:10254000A6CFF76A8B4BD12E229130C8EF3D4224A3 +:10255000BD8C5679217B41C82A87A7FAA30765CB92 +:10256000BEC2946E16EFD92D337935553FDD9F41AC +:10257000F1509B2FE8104E30E77BB84ACF073979EE +:10258000581070BD6BF3255262A17BB3BF6FC82298 +:10259000DFDF482DB79374CCE441E6D57209F8B576 +:1025A0006788372C517E7F3E871C24D4FE781EE836 +:1025B00012E4C2AFD2304E6CFA37DBF87A670251C0 +:1025C00040BEC4EBFE38C89FB1FC9E4E5EFF3D0E80 +:1025D000D70639F28A8CFBCA3CFE4A1218C784948B +:1025E00023A0C7DD9EB53B6AE8F3FECBDF3E01F1D9 +:1025F000C1779FF1E800D7F68A93012B1E4983FC2F +:102600008E753F7E44DE9CCDC3B8D8FF27D137649A +:10261000AB1C0A0E2BD0FE7941DF09FBD7B1572541 +:10262000E4BFE785F82C8C63C904FD82E76F0A617B +:102630007E87D9CE1FB6F377A667E8E14D30EF0667 +:10264000251C4BC117BF49D36DFB46EE90BD7D08DD +:1026500074E67C56D6297D96F1798765430238E683 +:1026600093283E17101D9F39AEE847308F79A42F6D +:1026700007CAAD6953AE60FB07FF6378535DFF0780 +:10268000F166D26BE8F2128483DC2D86A7EBE84D6D +:10269000DAE87CA54BE0F855519EE78EEC4F35FE0D +:1026A000A82088DDB0388996867230D7C3F0D73439 +:1026B000741AE3BBA129C41677EF6810910F76BF97 +:1026C000CEF6F5CE3414ED9C41EB57117D474DE12C +:1026D000E87998FCB15B8DA4A7DA9F329F265F98BA +:1026E000E59D53BF48400EFDE3D42F62DE51EEEB73 +:1026F0001E1DFC8EAA5FEF6F01B9D8F106CBAFF8B3 +:102700009537BAC8353F29673A6E6A9C0A7E50C031 +:102710001F59ECA2F889E4C7AF037977A6F676379C +:102720004EDDC7F25E9AEED577CED4C75E9F3D4DA3 +:10273000E3EFDF98F3DA03F31A67FFC29C97B95E01 +:10274000676A570FDFA8839C294E8FA66837224FF0 +:10275000AE5E3DEEF87BB85EA1F35F6BA5CF294D71 +:102760001AE6B798EDCDF93ADB3BE79BDC07BEB044 +:10277000BCA03E17C9027AFFDEC753FEE925148DBF +:102780001109F434E5CF8D004F2569C43291FB72F5 +:10279000C0BE31E97977E7E339A817E47821E67715 +:1027A0005DE0781D2412A9027E0B8B61ABBD623EF9 +:1027B000DB46E83C81715537970362DABDA1547856 +:1027C0001EE93FDFCEFFDB0861723EA1A29C87407D +:1027D000A146CB854749F97DB4BF06480AA5E35415 +:1027E000C92C1E32EFA8DE2BB1B8AA54EFB7E09186 +:1027F000EF3798F1DD0E722FD174F02BCAFAA1BA1F +:10280000C9A74794E84340A74A48C77C4F57302A96 +:10281000B0FD38B63F54C2ED92ABA4B52AD8254DD1 +:1028200024A2CE06BE3D2E119687C7F8DA6DEE8340 +:10283000713E76733EA61C8CE519FCFB739CBE0EA4 +:10284000817D82F604A3A383DC3EA9191E3EE2A784 +:10285000ED4A067BAA613A4F83BDE206FB248CDF7A +:10286000BF03F60A2D1FC9F8C76B6653BCEC33C40F +:1028700030E0FA40B3C1F8A1B901BF37919877337E +:10288000C8A547440DE0EC7AA4550AD0F27E55C0A5 +:10289000F8C523CD8D583F70CE9B007F73BF9A1033 +:1028A000C01E391326E118C04DDD2398D70C3E8F8A +:1028B000AA370771BBFCF1F87BBFDD41EB3DB8D017 +:1028C0008BFB64267FCD681AD6AE01BEDA7B52DF61 +:1028D0000CF0CFBFD580FADBC245B84FF104C51765 +:1028E000ACD3BE5DEFED1AA4DF0372D766F0836749 +:1028F00016AC427B28A0FEE36D500E684FFD1D3ED6 +:10290000D5EFDF09FA7A665CB4ED9F07D49FDE0548 +:10291000DFAB87C235E9B49F59C707BBAFA6CF8EDF +:10292000F0ED2290787AE61F705FE3B0A07DA907F2 +:10293000E26AD72B48AFC609A305D8D15561CF832A +:10294000CC7E310A690B64F200C53B01BC1B32F43A +:10295000FB96AB10E92C14C8A909D0F2E38F9DFCBB +:10296000F1D5F4FB915DB7A25C743F22A33D36F331 +:102970001BB793AF58E484FB3139655EE95B2E37B2 +:10298000E3A34756F7CCD2197902FFCDDA5BA3A2B5 +:102990009C78D19EE760EE0BF792E85B2EA4676609 +:1029A0009FC81ADB47863D2FD84F240F8B8C4F22B0 +:1029B00051AF35FFB9E4EB6224559CFBAC4BC679B3 +:1029C000B5C76B4A601DE4F377E03E19E9B18F6F3C +:1029D0008E47C73F6B956FB2C6E02A00D54FD7B37D +:1029E0005FF9F71C80FF6CA3A9A712A8A706CAC4A9 +:1029F000C4540ADF030F897148CA3C52CBF4D6761F +:102A000099E50B6EE7E5C7CE91B85098E4A3999C81 +:102A1000DF1E7B4464F65C9CA09E23E7CEA37DE191 +:102A2000E3DF33CB5E56717F2266F8AA2A312B9002 +:102A3000FF58E885E2E8D298D72667C5A64CDBFAAE +:102A400017508BC59E4F5D94AC2F811C3FAE02FD8D +:102A50009EA17E2BD0EF12BE4F5463E6614AE7E69B +:102A6000C1FC1F36F5AC9937E3C893DEDBB8CE0B5B +:102A7000F1C2174CFA696834D0FFD1DC389EB94FE7 +:102A800058724B2406FAD3956FCF9FAE72E4472F4E +:102A900071942F36BE52AE38E3A8DB66211DE801E3 +:102AA0009457C51CCF7B2FA3EE7CFAE838CB48BFE8 +:102AB0003C8E407A02B87EC59C80EEBF5B6A00BF48 +:102AC00020F040798635BF60B9C2ECEE815FB9096C +:102AD000D8F9FB6B548C679A799D2E3EEE0A45C758 +:102AE0007AFB1FBA4385F65DC1220FE0EBC8E5EB28 +:102AF000BD98FFC1F3534DB9DB7AF9FA6B6E0279D9 +:102B0000982DA2EEE9C86FCD857DF9076A54CC3FB8 +:102B10000DA40DF51DA165DF134AF851FA7D7F550F +:102B2000628D356E7387C2F4D7750ADF07DA66CF18 +:102B3000DFA07C709D02F961BE46DCB714559EC7CC +:102B4000EBF0EF4D7C040E5F2716FAD9B3C80FFEE9 +:102B500028A38F38A78F3DDC3F7D04E4BF1BE886A8 +:102B6000C9FF6DDC3F75F63BBD217258013BEC1689 +:102B7000AD1C4251CEF59DD66DB7270A6376393725 +:102B8000D549F78DB9B6FA790D45B6EFFEF06C87E9 +:102B90007D92607A8DB0F5E9F2F8A681DC2EA77AF5 +:102BA00097D9199A18B1EEAB38F47A83CB68562EC0 +:102BB000C2BE09A4451A617D9CF6F456BE3E7F2331 +:102BC0001B5B94F9E8BF6D8527B58F79BEBADDFE32 +:102BD000180527A170CE1917CE872E06CE89F6D9F3 +:102BE0009CFB6B774A915D2FD1E7E274960FD9E198 +:102BF00067FE7C07C45169F9594E874F2912F67F49 +:102C000088CF77711AAD9F82BFCDF8EA73907803B1 +:102C1000F526A7CEB3040B08BFE7A5FEFE9CC2F6BF +:102C2000B3174F1D7F9CE7611CFADCE632BEAF583C +:102C3000E278ED8AF1036B39A1B0FDE79175E17996 +:102C400094A63D7687CBE8B7D64F3EED72D3DC072E +:102C5000C9E6EBE9278CFF5E58B36ECB74CACF4A46 +:102C6000BE0FED9FEC35ED9BC500E41F0D6AE00F34 +:102C700064F37D7CB29AC951735F3DB3CE2E579DEC +:102C8000E7ADDC3C2FDEED3C67C3E5AB931EC7929E +:102C9000AFBF56ECFB1A23F1EB31E8CA19BF6E82C5 +:102CA0005F999DC9EDE048FAAA3963D3E3CF9B87CA +:102CB000B70F4C4F965F82F33329E980ED27060E5C +:102CC000FFA16E7505ECDBB178DA607362F19BD31E +:102CD00093F22BB228E305887B466A3250DEAC08BB +:102CE000FD71FB00F5C7EB8DFEC56F5AE639A851A3 +:102CF00068A78DC32786EB232B7F3D2130FAE9E0BF +:102D0000E3EDE0F874DAD15D62CC0DFD7E40860C17 +:102D100021855F6B9D773BE26DC8077436D6BCC3D7 +:102D20006EC65781858D6188D3B9CF4BC807EEA990 +:102D3000A6DD1246BB659E3B839DFBF015E13E1E62 +:102D4000F5D387FB611D7C2CBFDFD48FEF9BF15443 +:102D5000AEF76ECB60E5ADCD2C7EEC3E72D96B3A12 +:102D60006DE77FD1453CF4FD162AD7210ED84DEDF5 +:102D700078F81EA8182210476FA3F5A316BFBB2D25 +:102D80005CAD819DD05E5AAEEAF4BB34A702CB7233 +:102D900061B9564DC79CEDFEDAD26C8883178B98CB +:102DA000575B4ACB2DD4A44B776B38BF9F97BCE9B8 +:102DB00003FB2C1D9CF3F9C9F57455440D89C2E33E +:102DC0000A69D5908B31A2B7399DD1F78F42BCE407 +:102DD00009215AE9A6F3FF393F7FD5A53496DC0ACD +:102DE0007E8F1C7343FCA04965FB10400FEDF392EE +:102DF000702FE1F855F8B8237E105FCF0FE4A118CB +:102E0000A4B67689A421D5FA5CED6672AE5D33B4C2 +:102E100071E949933FB2E54F2F62FCA404293DA517 +:102E2000883F3AE5357147EADDD9C97C25BAB01A41 +:102E3000F22961F69E79BEE74DC5F89C9BCEA3D5DD +:102E4000C7E5587E26D2297DBFDCFB89E43E8BCFC7 +:102E50001C5E5471AC06FC924117C68B02D3C8DFCE +:102E6000462CF2F6A81B836EF4C9ECA4FB287DC4A3 +:102E700067B2B80401BA49A38A18F6210BC4F8A3B3 +:102E800085006F6FED34DA5F973C9D5AE6C97EAAE4 +:102E90000A98FDBFBDDADB60F503DE4D63FB2F77DB +:102EA000F9AA9E86F995FAE2D5E83E4376E62476BD +:102EB0007E0AE8F8128D0C0922C8C108617A33AC89 +:102EC00032FD5AA3C179298144C9F9B4F1F4A3FDB3 +:102ED0005CD59372BCD50BF808B278977F9780C900 +:102EE00080529F91F08298F4AD6A77337D5102E36E +:102EF000F4577A898FD6FF63BF82F6619F3F4F06F2 +:102F0000BC3E2FAEFB26C49F867FE9C6FCC6BE3FF3 +:102F1000CFC6FCFB3EFF15CB406EF709E42855F603 +:102F2000A4EA6C1E4F362469B0CF17586A10D8E750 +:102F3000187E8184213FD815FAE9E237E7E1C4D34E +:102F4000C485B49D87747B68BBF047DEF79750BAA1 +:102F50007ADA57FEE0A524195731E329CBD2A20F24 +:102F600003DE3A26FD5B03F04D37855342FBD5085F +:102F700001DCE5D922C61F49B62F3E1DE265478315 +:102F800035903F5A2597616A6C60295BEF5F79A3A2 +:102F90007B61BE355A7D0DC4D72B8EEB2867978594 +:102FA000360F40B9F27556EE5018BF40BC8858E451 +:102FB0006ED5D92938BF3E4E27ED2163D010C6E526 +:102FC0001BC7B9037BBE9C950E20CFDD42075197EE +:102FD000950E16523A9863A50343B8183AF82A2A70 +:102FE000EB4FC23FC66B3542326E379A0F36AB9904 +:102FF000A5A3F9C584E3BE8ACC20C851932FB4059C +:10300000F7A25C755FAF44C05F37F9C4E48F8F3DB2 +:10301000237C12017E5FEDD3AF4AC527E08758F9C4 +:10302000E1DA31F86605191E08D2462B64124BA767 +:10303000A2E4E797BD553CC5C2074EBCAD582490ED +:10304000933679C6CA16BC6A23E71BA50BC7FFCB0C +:10305000B2DE11B4F06127F543C058EE16C304F494 +:10306000CA02DFBA3F025DCA75DF0B813FE87247D3 +:103070001A306F76C13B693752BAFCE3245187C9D5 +:1030800077E8EBBE8BFC7C228D807DB2BD723DC6A5 +:103090007DFF7853742AE8892D14FF27512FC72705 +:1030A0008B9883393499EDB7EB21F68C86D87BC2A7 +:1030B000BFC779D9E0F586B01E5D679B7CDCE16116 +:1030C000FB5D3B3C4CDF6C517A54E0B7E142554B21 +:1030D00095EF5CA9B2FA4BDCA4221CC4D1705FB995 +:1030E00043956A7B599C2FB184BE5F32ADE451EBAE +:1030F0007E81D9EEC1E63EB453B6341FC267565D39 +:103100009C40DE95B724A6C3FEB8FA97A5820BFAB9 +:103110009DCDF671E17D8BC54ED355C69FEA5FA468 +:1031200028F0B1DA1AD3332DF2581585682A7B7B43 +:10313000A787C569D45682DFD5C35FC77DEFACE2F0 +:10314000B0F06528B7F69030EDC79360EF83C58681 +:10315000F0254BBFC1BA3E9B3E5C41972ABD1CADDA +:103160002C3C17D3A17B719F6C45B0FA0FF2DCD1D8 +:10317000F4063F272D7463C26FEED7DECEFDF49ABE +:103180002215F9B4A349E9C573302AB39F3E085606 +:103190008F7BAE00F669A98587FE303C61BF36366D +:1031A00093EDD74219F66BE109FBB5F084FD5AF8AF +:1031B0000EFBB550FE4EB38165D8B78532ECDBC649 +:1031C00066B27D5A28C33E2D3C0F3537E0F3D9E671 +:1031D00046FCFE5C731396293DA0FD474A6221B070 +:1031E000ABBBEF520CC8C7E9E2EB7EC428CA027A37 +:1031F000F104593CC1F3E203782EDA131231BED741 +:10320000197A80DC409FDDF3FDDD101F51BFEBC359 +:10321000A7477E9080DDB64788359030211BD58A40 +:103220001A99DA13C5A1CDD59961C0DBE5ED909F60 +:1032300038436F09AFD39265DD5FBEFE7B96F2D453 +:10324000D25ED94BEBDFD5BDA81DE406C0019B6B58 +:103250006DEA929A96624AB445D4A001F957A8C47F +:1032600081EEBF04EB351DE06776E067485B08E25E +:103270001F5375A51CF895D64F303EB9B0FA5DAA1C +:103280008EEF9DEDC6AB27565C503D228DD31F7C43 +:1032900017C6E9A783B4698314F6AD205BC08EF22C +:1032A000B0FDE06E179313DD1EF6FC9DC7DC0FAF7B +:1032B0005EEEA1CFE51EC687DD9E482D9C4B199E74 +:1032C00023621CA8CF45BB80430A4D85AFC0F9A13E +:1032D0003B7E2213D867D8C3F976FA543FD3E7F779 +:1032E000A8A8CF974FFD767B262D4FFF56380CFAB6 +:1032F000792B097B814E62DB985C79AA625A663D24 +:10330000AD7EC9FC6732414F7DAC32BB36CEFD92FB +:10331000968E1BA742FCEA8FC7989CFC361FA7D746 +:1033200035D888EB39DF87760D752CD06E6909C9E1 +:10333000986724E6B0A7E2D2FE0AEA29D430885181 +:1033400078943F2F50314E72D6CDEFC118447B4652 +:10335000F144B50CFABE272622BFB769DE38D8DFA4 +:103360005B7DE578FE34562AE33994ADA52CCE9AE0 +:10337000E6FF7C1CEC981DFD1E261F7C2AE699C6E4 +:103380004B0F1EAD0EC253D480DFE3C6AA5AC4BB96 +:10339000266A98AF4A7FC3EF0D413CB7B295F075EE +:1033A0006910F1DC5DC7A48F7E7A29E4EF7C590BAC +:1033B000F3BB09301F1C4D3311F68D860FA7013C5E +:1033C0007F63DE6B30D49A46EBB7AFD3C2B00E73D7 +:1033D000B5EA5AC837E8D0AAD11F4A9B53A35E8FDB +:1033E0007268E4DC06DE9FD15E2A63BE117C07BEF4 +:1033F00024ED6400CECDE771599696512E801DD6EE +:103400005187E14038D760CB3F6FCFBC06CF2B4907 +:103410002B3211CE0E62A8503F5627A39ECCF3A9A3 +:1034200009B04BF2CCB82F1CC5B0C425B26EB19F09 +:10343000E7C869906DE7C72747EDE56C1E67C8765A +:103440009CFB38CBE9C58927E77CB3828F6600BC3B +:103450005970E0571F3D9F0783E5F530CF3CCD8B7A +:103460007087B4D62A905F9349630BD0DD45C3EBD8 +:1034700080736E69FB20ACFB5C5D263A1DFF523207 +:10348000DC0AFD6EE574DE5D68D7DB7B54C9E4C7FA +:1034900030F0E3D42691C42CE343BC3266196F5A52 +:1034A00077A6AD3CBD27D7567FE6AE22DBF759F1B4 +:1034B000D9B6EF97EC2BB795E7F45D6EAB7FE9A13A +:1034C0006A5BB92C718DADFEBCA3AB6CE5F9837F53 +:1034D00065ABBFE0C43ADBF7CB86D6DBBE5FF1D687 +:1034E000ADB6F295C377DBEA9B76BD532FCEE6F6F9 +:1034F000CDC5DAF36EB84FC216BFB5FB0B4E7B5F7E +:10350000FD4B9BDE0A722DA0207DCBA0C769F9D6AA +:10351000BB98BFA52E0EEB2057742E47A9185C0050 +:10352000EB561550511FC83E564FF62D43FB63CA4C +:103530002E2A8FE681554A46BEA7815C6E8E2D2EBF +:10354000B6C4A53C5A0F9EE1AA0AD4E23E88D95ED1 +:10355000D60C12F5C3783AB37BA8370BF53C3A6D1D +:103560006F99D7F3A28847A587A95FF8A8C52F1C34 +:10357000CB0F74FA7D17EAE74D118917CF1F089119 +:10358000467896361EAB86B461EAFFFDB587F2E752 +:103590007625D2D04BFBDD5EE465FBA5DCFFEB2E90 +:1035A000EC43BE182E9451BF10592FB5C6ED3AF911 +:1035B000FAA6A94FA1FF49F18EF2D6C4FB566128A5 +:1035C000DE0672E72E2FCAC329BF71BF0CFCA516F9 +:1035D000A9792A7D1F3EA218B00FF520C76B91561E +:1035E000560DA1A7E250FD6178CED0A99D419F253F +:1035F000253B0FA35AF314E178B3C3DFAB0659A2FE +:103600002E66F69F3C5789B7D27E248DC291C2FFA9 +:10361000309F526017DBE728967F07F406D6FF79C4 +:103620003A85AA4C15F3423C4007023E917E3C414C +:103630001FEA0D0F1C8285B22CC4619F10EC53D879 +:10364000AFABCADC85EB6EDAAD60CF46993FDC09E3 +:10365000780DD6D9D73B4DFD0EE2A95D60F1F1EEB4 +:103660000CFDC56A3A6E77765126C462217E526F90 +:1036700091373BB83E8D7AD9D39437B891333F69AF +:10368000EF50FADF254E03F87A08C82DCFBD3D0470 +:10369000E8DDA3D1D544BB3EA647509F327BF73629 +:1036A0000E534DD11ACC03783F588EF6ADA7E9F9E9 +:1036B00094F8F30C49C49837365E033376A3BE27DB +:1036C000458A0E764593AE18BD29E4C15C95FB3959 +:1036D00053CC73AF2C0FA89BE3C38C9B8EC4237970 +:1036E000DCCD8C479AFDDC965D3E793C7BDC43FD6E +:1036F000D0A805DE2D741CC04BC7B9FA5AC4834C40 +:10370000D8B9DD3F97F6DE87FBB16D3AEC37CFE5F0 +:10371000F67225E087E27B8A42D04F580AF1952C59 +:10372000F07E3F530B7C69C663863CEC1C773846C1 +:1037300024167F73997A4B3C7F29C2AC2B661E19E5 +:103740009ABC4CAFD17FFBE17CD9B46EFBF9CDE9DB +:103750003DF6F2CC5DF6F2ACB8BD4CADE6E36017D9 +:10376000808D86F18D7DF6EFF5E6BE410D3B6FA6AF +:10377000D291CF33FD6BBB3F8770FD6FE6BB15F475 +:1037800025AA40BCE6DF6ED7ABB95CCFE73AF46759 +:10379000B95FC2B843D5D1E000D88F667CE8575EE8 +:1037A000DD967766C6799CF2DCFBFA4E42BFA0FF3D +:1037B0001E75B37807C4913F2CE071957C1E579914 +:1037C000C2E32A052CAEE292F497D60A9827FA3E75 +:1037D000F20569BC94C573D8B9AFF76AE517049DC3 +:1037E0008D17B58C7767496C3943433C07EA99F1EB +:1037F00015337E10F01BCB817FB7865F6E3C42E9AC +:10380000A4FA976E02FD5C25BD78B419E45B818C47 +:10381000F9DDDA825BBEE98578257CA7E5EA427DA1 +:1038200032F2C18F5D1847E8E2746D9E5734E33180 +:103830009A97F181CF6BDA47312FCFDFF782BD7BCB +:10384000C93E2AA36DFA8EC5FDCCF8DE9C3EFBF77F +:103850003E226469901FB0262E32FBCAF05559F201 +:103860001F67F3759BBB36F1C05A5A3E40E2E570C4 +:103870002F5D19A78FF080FD9CEC2422E039A94927 +:10388000C7A5709CD69FFB9CFD7BA9E31CED6CE754 +:10389000B95AC7FE915F22A7AFA7E36DD31B05906E +:1038A000A3DBD6525B9E966779F9BEFD0C3203E826 +:1038B000F02AC9174E007E5F95701FCCFDC6CCD78D +:1038C000AE07BD7E8CE52769D3F49D106FD67E2AA6 +:1038D000A19ED2D24859992FB9DFF40FE7C304F65D +:1038E0004FCCF8D793745D41AF1CA07E79B10BFC2F +:1038F0006C0DCB7DD42F87F2D3D42F87E741EA9785 +:10390000C3FB7FA67E39940F51BF1C9ECF52BF1CB4 +:10391000DE3F47FD7228DFE5ABC278F920AD0FF43A +:10392000E22D3BA84EAB0039ECD2803E9C72A8AA97 +:10393000EA36753525A92F743D85FB1CD557B17C1A +:10394000EAE5F73D85FB1CD6389C354E998CC30DB6 +:1039500009661C0E42A3BFE6FB1123F1B8288BC7F2 +:103960004DDC8F61F683F1CF51FDF038E8BB77FD78 +:10397000DBE36DF4D386F90F747B8BE07C47238FF8 +:10398000FB99F933BA2D3F7FC3C116CC9F51728E7C +:1039900037C2BA1EACF0615E89E28A6A206F9DFE72 +:1039A0009CE9C739ED69F3E9D46F7E6E5798F1D57C +:1039B000ED2E82F9D43181DA13605F34C717BFE985 +:1039C0001A3BEE7AC25BC4F3F8EC7261E41C018F1F +:1039D000FBB8C19AA5F354048E0F9EDF8EA2B18866 +:1039E000C5FFACF1576F711C0FAF7B7D06DA750216 +:1039F000B5F7D0FED3A22188A375C2B98114F3DB39 +:103A0000CBF9BD2547417BA33387E58BD4E48743BE +:103A1000D0BE2DA732643D47609E7318F057AA436D +:103A200096FE6EF5178DABFF24AAAFF571F4B5E4E1 +:103A300066E77CDA0E5FA6C2F98D6EDFBA41F0A3AD +:103A4000BB43418CD3F7E75492214BFF5268219E30 +:103A5000F3907CCC1E96422ADAC332CCBF3459DFB5 +:103A6000ACD7C2E53E65678C2F7A7C3D58CF2D4799 +:103A7000F07E09771054267D6A6CDFCE5B2C12D560 +:103A8000222FCC71EFF63279D95D1AD520CED21D16 +:103A90009275382FD2AD97239EDB389EDB0A4C7B84 +:103AA000228C76CCF7B97C35FB69E37180B60605CC +:103AB000EDB948538656938579BDDF017EEEF6B5A4 +:103AC000AAB07FA9E4548CDBEFC084FD964DAA997F +:103AD00087FD7E1FFA55FCEB34E8D735C6F9A463A1 +:103AE0009C1E3EA9DDEADCEFA3D086AC792BCEA7E5 +:103AF0009FDB9FCE761B4A871458F72D8FD9CF3383 +:103B0000BB083BDFB5F1D066E4F3EDF220DA51DB20 +:103B1000CF0929CF8985D204CE6F23FEBDCD0ECA31 +:103B2000E3FC94C7BF03A981BE284BD8ED96794723 +:103B3000EDE5F983F6F282134E3BC87815ECA0D57B +:103B40005CEE0D5279CF92668665C0472416AF02AF +:103B5000B8EB495F0BE453B8249617B29AEBBF95C4 +:103B60005C3F06D23210FEBC06AFCDFF24FC3EC047 +:103B70007CDE7F41CDC0E67610B211D3AED2D16FDC +:103B80002DB8FAE92A14970EFBAADEB09FF75FE979 +:103B9000B09F9C765695DC8B79BBB98EB886B9EF11 +:103BA0000BF3847B0F9CE35FECB8667F90AF05F26C +:103BB000CDBC0F06EF1FA6ED0BE48410A678CA6DEE +:103BC00064E775F26E27466F0A3A5EC2D77D14DE4F +:103BD000624B106F4BF9BB5C1FBBC72BB7468AEB20 +:103BE00074FCDC863EB40756DD42E78376F879CC78 +:103BF0009731EB6766F4E1B9A5DD7502CFE325687F +:103C0000D798EBBCDBC7CE19D65F29C44568DF580F +:103C100084E3235C45C9F5A5783AC9F0C4F212AF34 +:103C2000ADB59F87AC77D82F263DAC74BC3FE96516 +:103C3000FBE7261FBC7BD9891953281C1B849EDAFD +:103C4000B46917AE2F2DFCE13A0F7C08BF4F6229F3 +:103C50003298EFABFE9386E74232861E269424AF5D +:103C60004D23B19A4584FC8B77F8128196FF6A6BDD +:103C70005F4777011CF31E7E0A8C3C77D73357D5FC +:103C80005E992C7BEFEBC772908F035B906CBD2D20 +:103C9000F7C350D4C5D3187C5B0DB253821C5C5162 +:103CA000DB192E4CB6CB8476C238ED2264A79CA2D9 +:103CB0009DCF6C47D1D509F73FF17979F97791C359 +:103CC000631D5F06BC69BA0FCF3B2E9335D8BFFA90 +:103CD000B4704C9A68DE51B2D3356D743B0A768B62 +:103CE00009BF981AFE387CB78EEF1A07FEFF6E7C6C +:103CF0004CD49FC2BF5F347CB47AEBA4B1E70B70A5 +:103D0000B9F05E22DD275AFAD9D1FF278C8BCBD7A9 +:103D1000913084BC6497A1C17E5EA9F610FAF77257 +:103D2000468D0676C0165A063B604B5F0FC6BF4BEA +:103D30008B1FE806A22F4D7809C8833944CB384041 +:103D4000FB9DA3C970028BC8570E88104F279F2573 +:103D5000985F92DEEF65F708155EFE2DF0B7323200 +:103D600054DCCF48CBA8FC16337A599CD9843FAD9C +:103D7000EA7835C4DFE57A1216002E214EAA80C9F2 +:103D80006611DCDFF01A07EF84F3024466FA09EFEC +:103D9000D201BDCAE3ED9319C9906E45ABC73C97FC +:103DA0009FC818C79A0C578551A22C2DCDDC09F05D +:103DB0009446690702C0CFE26573A2623841FB2FC7 +:103DC0003FCDDA919FB17326D43759F38C2F8957A1 +:103DD00053AE4CE671F8D05A7B9C9A0CD339D3F68B +:103DE000E53F5BB517E2149346C96FE6B77B399C94 +:103DF000E9A74904FA0FD6D9F58697E7797B1DF72D +:103E0000CC54F85DF6FBA19DFEC35723A807DC2424 +:103E1000AC2A685FAC45BBC1F44B764345B0C70BD9 +:103E200008BB97D7D9BE92B52721E6A7B8BD4455A0 +:103E3000CBE9F7F55E03F312DDB44CF1282844CD4D +:103E4000A1EF7345166F6911880CE5E47809CC473A +:103E500070AB9F6907FBE5B03A0FEF4F33FDEA36D1 +:103E60002D8CF912A4A4DA66379B7961B796154DAB +:103E700086EFE99346E24E1AD0E5ADD9C56847070B +:103E8000B286FE1AE4ECB9ADE9CB5490AB90AF71B9 +:103E900039E4477B3B6354E9BBCFE611DD629FB950 +:103EA000E5468CB3B9CF4EB1BD4F34DBCF5B1B3E83 +:103EB000B106C699EA637C5845B476685745ECE785 +:103EC000AADD67736CF67AB2FF7CDBFB04B56BACE2 +:103ED000F7008DDD7F1AD14BACFD4F1BA3FF198E70 +:103EE000FEB594FD27FBCDB2F5DB21B3F86B2CE8D2 +:103EF0004D792FE5025F75311C951D6B7FA0D2C7F0 +:103F0000E29A5DA146DC1FA82694F129BD2C3977E1 +:103F10005262E77D09DA6F24DFBE3F50CDE958A435 +:103F20009481E70764FBFDC68B89F3BE63BB5DF438 +:103F30004B8839507C89FE8A41DC27F8930FCF03E8 +:103F40008E65370F36138C4F2F4E1BBA0DF6C157A7 +:103F50006ED3958E10E63DA33FFF37DBE62F033B84 +:103F6000DFBC07B32328225E22D593F13C97D94FBB +:103F70004421D3412E46449607813F74FCC1EC5C3A +:103F80005BBE86F9749E87AF3784C5C596790D42AE +:103F9000FEA175BCA579BD92651E1137998FE3719D +:103FA0007B7764BC499F6CBC633C9E658E57BFCCDD +:103FB0003EBF7A45C3F9D5733E36C73B06F34B8106 +:103FC000DF09C7E3F99523E32DB7CFAFDEADE1FC01 +:103FD000EAF97DBC23E34DFA64E399719D2EA5B106 +:103FE00011E870ACF88E19D7B9B66BBF2DAE43622D +:103FF000FB97561513B25360F223EEABEE04BA787A +:10400000BFEED612D42BDCBEC67B57A93E5E293349 +:104010007857E4FBE22D163CEEA672C49809E72916 +:10402000540207CFE07C8581E72D42F87C94DAEBDF +:1040300006E69794E0F7C79BC358DED7BC109F668F +:104040003F250BD9FD60B3160929EDF6133EE67F37 +:10405000EECCD1AEFB12E8B72A2FCB0B5E78053140 +:104060002C763435AC0F7B607FE8F3A40C74E48CC1 +:104070005D0CEE60CDA438ACBFB76C60B019E2A0A7 +:10408000B24BC7BC583DF5DF3B78C5C7FC79B79B41 +:10409000B52757B07B525770FD44A43ACC3F5AB174 +:1040A0003203F31156AD36FC1AC5DB6A4178B59878 +:1040B000EB3B381FF539BED44E7F21089A87AE57A7 +:1040C000D090E2708FDCE7F25F5C23D07E23FE6B42 +:1040D000D1CF88D08699B49FCF717D5BF5869B4008 +:1040E0003C825CA5A0FC5ABDDAEE17ECF42434B097 +:1040F00073769605490B6DB7AACEFEDDED667C158D +:1041000071DC13B362827B63CCBC5C277E9C71D371 +:104110009FF9ECF1D133A474079E0DE3F9BBCEF601 +:10412000661CB4DDC7E45B97C2E4C3683E60F0BCC4 +:104130000B7DA3FF7702E368267CB9725C00799F50 +:10414000D770C2961F4F118B46B5B94F40A4036577 +:10415000A8871DF3D92D1CC819EFDEA85C22FF6EBD +:10416000A884FF7D0361F4BCDF1935EF452F15935B +:1041700054FCC3E2C12B8E4AE1163D8917130FFF91 +:10418000DB7CB4CBC7F0F9D2D20F2A981F986FFB13 +:104190003B02E639AF6B47CA32912DF4BC72BD6267 +:1041A000307F75B814E8F2F8956961F6F730B81DFC +:1041B00094F8A50876D0A7EFDF28B0E53FF37EC7D7 +:1041C0005A2F67DEA5E55C72F29E04C87F690987F5 +:1041D000D01EC81609F0532EE4E305D8F79376BB3A +:1041E000D5968FD7D6BF5F80B8E1C3909F68398FCF +:1041F00097D7D02774807DD71267718804AD47E1C7 +:10420000CE6F4808EDA5C9BC2FA75CCFBFC59E2FB8 +:10421000D8B168B5764087BC9AEA1EB8206CCB2E20 +:1042200016E732EB8FC4BBF83955176924704E433B +:10423000F2B1787388DFDF31519EEF87624C2B2C0F +:1042400084FCDEB85A45E7BF272BBACC4FFBED0EF6 +:104250009637F6027DCA61CC075FDB744F04E284B7 +:104260005A56EA38F85A6E1FD4FB195DBDEE4A144F +:1042700040DCFCE5ACEA7A7F768AFA4D5FC5FE1633 +:104280008F712FFD7A3F8BCF3C2CA6960737F0EF2E +:104290005FD820E27D431EE2C773AC9EE29E85801C +:1042A0008F8737EE0EA73A8FB9508BAEF35BF0EEE7 +:1042B0002966F70510D27719CC73CBC78FF47D9799 +:1042C000CE3BF3631FCAD94C89F56B69BFDE3A1F39 +:1042D000B3FDF37FFA059EB37F9EDFBF4EC8F4E5C2 +:1042E0001067DF3E52263138E8BC3D839763E272A7 +:1042F000F02B93E5E796554119689412DFBBFE97C2 +:104300003AE1FE9AED02E1C43AB80CEBF3FBDE7F32 +:10431000C2BF2FBEE69D6FED007D50A9A0BFB99D25 +:10432000DB3B267CFFE967793FFFC9D7652C7C6EB4 +:10433000E3DF7D80CFE045E1735B2A7C7E26686CFD +:1043400087F71EC804A120783E566F87BCECAF37B4 +:1043500093C897E81C1E0E1FDC0F678F68FB8752FF +:10436000B5FF4196F1353FC27312E7E72FF685019D +:10437000155B1610EC27051CDF186F5DCB33989C7E +:104380004B4B67CF4C6E5F4AEEC110E42F6815FFB0 +:10439000709B46E54C67E1E09A5471E2A702CCEECF +:1043A000CF18232E7E98E3EFEACCC8B701EE76ED66 +:1043B00001F4F7148144A0FE96854344B0B47B23F6 +:1043C000C0E897C2FD0CC0AD5CC6EEB1F653BC436D +:1043D000829CBF82C1BF453F4E204FDE1F3A8E797F +:1043E000ADFE8A21E4771485B98CAEC01F54B9FDA7 +:1043F00076D8FF26DAF5999249777774011D4AC974 +:1044000032D2656F266BFFFBC01D5DE02FEE516859 +:104410001B9083B90ADA37CEF9FD2CC0E6A768C62F +:10442000518077143EDD43DF827B09B64F67F7B9D1 +:104430002C1607D7DC0074798D0FED33FA7E8DF5DD +:104440005CFE479C7F3FF233FB6AFB9F54FCEE5CB3 +:104450008FB1E8F5246FFF09E8F5642AFEA5F4FAA8 +:104460005B786FA1D70F486A7A7D7B0C7AFD0F6865 +:10447000EFC48BB32C116317EC2BCB1F2DDB07FD87 +:10448000C99F59B4EBBBF4297DB42D86AB19166CCA +:10449000E79E93F23EFA2718D7BC7FC0FC3B46CD7F +:1044A0004008F353F4BBA07217C8B10BE8570E6471 +:1044B0008FEEF7653F8377F135BE68AAFB14BE1314 +:1044C00090D9F9D800AB3716DFFC3AC0F253C6E2F8 +:1044D0009B17381F50BE0906E64FCC3767927C9376 +:1044E0001FB820BE79089F9E62C63738FFCB47F3BE +:1044F0000D89ADEB02F9DA59C8F862CEFD9B902F19 +:1045000046F82816C3EF52B28CF2DBE4A38FEF8F8C +:10451000617D67FBC018F70656707E5AA845E60114 +:10452000FE8D4BB476768E6908CFEBF692E17E373E +:10453000E609B3BC5C6F2C6630F36090C0FDB48BB1 +:10454000381EF6808F067E50258F67C98364957F5D +:10455000343FFB2B1215D67B605EE1E3FBD2234B8D +:10456000018FBD646816D86763AD532D1F4FC832E5 +:104570006A0329F87F223DB421C0F4D0063E6EE6DE +:10458000C76A23D8A74E7E5FBCF1D93F3C3E4E3F61 +:10459000EB391CEB029F585FAD0BA4D6573704ECE8 +:1045A000FAAA42284AC9FFEB0329E407E5FF9B5317 +:1045B000E1E553F0FB9D8114FC1E095C18BE9FE5EC +:1045C000F87EF653E27B176FDF13F8C4F2B62715B7 +:1045D000BE28BE7706B22F08DFBB52AD17C5F7D78E +:1045E00003B8FE4F23FC7EDD87F1F2EE05E420F4F4 +:1045F00093028E5E6B3FAACEFAA13CF58140E97E24 +:10460000F147DDE154F724D176FB52B5AB0D683CA0 +:104610000EAD6F06FFE1E1CFF8705F81EAC703815D +:10462000FF5EB97F28151D2C16991CF206167581A0 +:10463000BEFF14FD0FA492FF5FE57436915DF01A82 +:10464000A70B3AEF9F029C4EF9D7CBCF312B5AF4F0 +:10465000E500E26BE86A90577BEECE1420DE956FA2 +:104660002404F0138E723D560597FDCC4FB6DB2324 +:104670002704B867674FA326C079294B7FAF07B2DD +:10468000C7EECF090785EF3730BE2FDD188276B52C +:104690007C7E176B271DC934DE0AA0FE89BC0D4F36 +:1046A00063A65D6E9BF310233D2CCF7661EABF734A +:1046B00079D42F9BF2FF7DABFCFF8F11BA62FD5DB9 +:1046C000ACFEA1F09DE3F0FD25157C4EBC4C04E74B +:1046D000250199EBDB889A9E424F39FB33FDEC9123 +:1046E00075029D6489FB64A78FE8EF603AAC478749 +:1046F00088E7A8567079B2626106B7DB352FF4FF00 +:10470000308FC33F7CCB0355B0AFDE7BAF5606285E +:10471000C86D607A4FBF650AC657A7F27E9DF08FBD +:10472000B457FA66C1DF8FA0E34E83792C59441247 +:10473000E037A683DD80F10A0DFFCE71A6BB27040A +:10474000F1D92D42CF9A75A057AFF6B17331A1D5EB +:1047500013DC9FD96AA35B12AA98A07E0BD6D7D28E +:104760007AF09E950BAEEFEE496967D5A48B9C9EBF +:10477000A24BC6C56B2888712F13BFA3C761EB5727 +:1047800015691400DFFE0A4183D43B3FA513B0979F +:10479000C4E241CC9BFA6C05A31742FD92F1EF698C +:1047A000E934E15A0578FFB47099F5C61E8FD773C6 +:1047B0009CB718F97B643E26C7B0222DBF77342BF7 +:1047C000E5BE82F9EC6AD60CB832F93D4DC7FB1B49 +:1047D000BB46F2BEC3A155FEFFF97AC979C5597C23 +:1047E000D4517FE49E92908AF61FFE9D0FEB7D3D93 +:1047F0009C2ED48C482C1DE54A18EF89A4E5565808 +:104800000FA2D2B21FCBED58D646CA9D583FC4EA7C +:10481000134DBB20BCD376DBB11F79A49F1DD88F6D +:104820006F64DC9D580E8E941FC4FAF9ACFE858E21 +:1048300033EA9E964109E7FF816CA4C3BEE9E79B7A +:104840006EC0F8D2754D37E1B3BB59AB82389D7954 +:104850005FC9E7AFBB41037FFABA2F3F88FBFA6617 +:10486000FF2BC1EF00FED7E55AB097944231F29882 +:104870002FC97F4938DAB1BC4266F7FEAF5C787A5F +:104880007BBB257EA7C2DF4F87FC1ADD725F06491E +:10489000CAC32704E37BE91741CFA3E749C800A5B2 +:1048A000DF0F7CC5F118D273B5968A6FCCF98ED51F +:1048B000BF39DFB1E48D8937F3FD9662FEF7761DCF +:1048C000F14BCFF41ACCFF59297038FDFCFE485E3D +:1048D0006F051DE7E952A40B1DE87605F7EF9CFA7A +:1048E000C11CF709217A02E804E2C4F7968FC6EFEB +:1048F00085E2CDEC7F723446E0FE2E6F29C17DB19A +:10490000A0DFDC576772ED219F598E617249A4B810 +:1049100007E59C4737E51ED3935A5A9F2196513F8E +:10492000A887D48666411E6834047FEA87968FCABA +:10493000684FB0321DFEE800DA3FDA6CB8F1516D15 +:104940003FF7A3A35712767411F7DDCEFD08F5B734 +:1049500059860B7C4B68D93B5236D4102D178D9459 +:104960006350DEC3ED3EA1E7DC8F60CF84EAE573E0 +:1049700056795FC5E5EA44F2F4BF00B9E905CA001B +:10498000800000001F8B080000000000000BE57D88 +:104990000B7854D5B5F03E73E695642699BC270490 +:1049A000C8090F098A38090482623BE1D558790C9D +:1049B00015359628938447782620D5B1D2322180A8 +:1049C000A0D886AA156BC509C57B69AFB6A0B4E5AA +:1049D0007AD17F10B4D0521A2B55B4A25150F15154 +:1049E000938294A9D572D75A7BEFCC39273321B45F +:1049F000DEFFEFFF5DF874B3CFD967EFBD1E7BAD6F +:104A0000B5D75A7B0F6361C6721963DE1CC6C63107 +:104A1000761EFF7CB967C944BB366DAD67C268A816 +:104A200079ADBEA11A631BF15541BC5D89C74EED3E +:104A30001ECD0CA67BCA199BBEAACBEA8476CEE219 +:104A40001C77D0C55891F79370257C5F349E310D4B +:104A5000BF1D9245E3B679572A769842DB08E651A6 +:104A600018BD5BE381F6396EC6DAA164D60863230C +:104A700018BBDF25EB301F28032511D601CF533596 +:104A8000FEDE827578AE3A58D34EA8A795307F04E3 +:104A9000EA1E079B1380B2D863610CE6E5F3A834E5 +:104AA0004F1F8E06F50CEF5AA6417B6795C51F81F7 +:104AB00032034B971EFEB5E23B2B95121FD7E6043F +:104AC00047209C6D8C55EDC479B168A004E0481D69 +:104AD0009E937537D42A4BAC2B190CF9E86A1698BB +:104AE0006B63ACC21348C3F6AED29CD4E008AA8F65 +:104AF000F2403FAE75963003BC54327744298EE3C2 +:104B000005669E1A7027A7C7CBAB838149B6E474AC +:104B1000BBE12635A087439653100FF0FDC7D5EFB4 +:104B20007C1FC159EAECB2B34140CF219B034C45F5 +:104B3000783482D3B97B66B410DE2FDBB39CE17C82 +:104B4000D7A4A58F473A9AC77DF9B3073D01789F4F +:104B5000F25747606782F196083C1F5D5D4DDF416B +:104B6000F79A358FB13908CA204604ED7062C994AE +:104B7000F30E02EFE810787F0BE3CC302B503B8D27 +:104B8000015EEBAA55A616E377DDEDD979A8DFD251 +:104B9000513B958D844AC876129F3BE1EF79E83707 +:104BA000C832A778E0716D983FA7F6F0DF3CE69B2E +:104BB000920BDFD56F303D7FFD9AF7593ABEB79E15 +:104BC000EC2889F77F63756D6092687786FE1F21F8 +:104BD000786669CC8F749BE54B8B8401C4EB0337FB +:104BE000052695C4FB7BE573750EE2C58C8FFF44EB +:104BF0007CE4223E028149437BE2A32EA0D83DDA29 +:104C000085F1D2573CD45A4BA7E46A3DF160861F28 +:104C100030762FE2791EE0F9EEE2E4F88076448FF8 +:104C2000576E827600CA1475AACD0278A89FA93063 +:104C30008742F84D6783B19D7FEA64DD7CCD78348F +:104C4000E3ABFE19E68B42BFF50FB87DC0E1ECF790 +:104C5000123F5140DA189027BCA91ECEB771FE1E34 +:104C6000F88B707EADA2F4F91C984770ADE2631C1E +:104C7000DEB7F5F0D5B140465421B8DF4E42F7B764 +:104C8000F5709AE7679E7F0A0A2B907FA1D78BBFAA +:104C90007340D78E59A323029733F6538F3BE7DD3A +:104CA000CBA03E92F9CEC3BA3ACBC6678CC2F743CB +:104CB00012CBDB73ABB5EF1CB0E9D739E7B339A141 +:104CC00099DDE362FF0A0B76D73D80E7C04DEABD70 +:104CD000D7C3BF5F3E98BD0E9FADF0AADAC96CC4C2 +:104CE00017C04BF4F23326F98B6119DEA702FE667A +:104CF00032A7E6827EBE0C42EA3CC032DD9FA2B9FA +:104D000074709C6E55AA508E02F132665D1E87D774 +:104D10003CEF155E3B8D07FCF8899E1FCD7879B975 +:104D20007A7006CA9117112F69849791178397AFEC +:104D3000E0628675E3C9665105E8DCA53823DB60CF +:104D40004E35A13B039346215E58D80EA2F35D4F2A +:104D5000B190D31C6E1B937F9A18CAD31A3B0B22B7 +:104D60005CAFDB58F52E1796D101653AB9F57E7622 +:104D7000E5BB28A765BD26F46DEA1F1891F850F22F +:104D8000F32D4E5754E57CF85137DF903CABF120C2 +:104D9000DD814EEC3CC0A9662CD1106E352D7D24F2 +:104DA000CB606C033601389D9981D328FFD5B4813F +:104DB00011E4BFD49B7EB481D3F1BEAA1B74744CA2 +:104DC00099F754983AD7B20CF84F13F4AB14F44B4C +:104DD00029719AE9C7709D864B58E43145A000EAD5 +:104DE000A787F823B86E93E90D49CF9412EBA71D5E +:104DF0007ABE66AD8457494776607417AED7A0D7A0 +:104E0000CAEEA6F725849FA047E2A7CB86FA644E98 +:104E1000C8765ADF4FB0606EA419BFDBE8F0E1B38B +:104E20003A8B9687ED004F1ED4E3ACC4E7C3F5C3BD +:104E3000C2F09DE427C42B1A13BAFE3B00868232CF +:104E4000EC0FA4277EB74137CEA09EE376AF2B733D +:104E5000BFA6EF5415EC07B2237C3E9F4E7E0FCECB +:104E6000E4F6C369EFE89D9641C9F157E7CCF65BDC +:104E7000B3E3F5B70B9CD591047A40F627F5799604 +:104E80001AF45A10B6F063070FF4473DECB9142436 +:104E900019BBC71639787000431661AC1FFE2F721C +:104EA000D0EF22BB43D4813161FE6DA9DD75BFD344 +:104EB0000BF541DDF530D6B7C270EC4AB05B32235A +:104EC00007D7C27CCE1D7790FE3A5D951AC1C59377 +:104ED0001D9AC84EC0BCAD60E66400AB4111C6D29D +:104EE000192A2478142B600EF09DADF914C4F7AC88 +:104EF0004C8DE66FD558D40D93CBB6FA14C4D7F7C2 +:104F0000ECAC41C88DE13375F6CB2C01AF1CC7E189 +:104F100064E194B278BF606135A31EB14E65A457B9 +:104F2000609D93DD26D7B7EC2798C9F567F7FABCE3 +:104F3000F07A0E662658CF872D4D6F7E0BEDD95F28 +:104F4000ABEC3100E566EF1DF4FC86503D953785EE +:104F50001652B9488CF70E0B2ECA84B2BDFAA59B27 +:104F60006F07FE6DDCEDF0A15A5E7ADBFBDF29D71F +:104F7000104F4077FC6E5EFD03E5F0DE3ED442F656 +:104F8000EC8601AC1AF9C9DEAC907DB451B357ED93 +:104F900086F2A18CCA2D993A381ECA98447556A536 +:104FA0005990CF5738399F9F3B7E97B70EED4A9760 +:104FB0008BD68BBDB9F8BB16A8B343306F86F2838E +:104FC000919DA13A78797726B753EF16F85E93C989 +:104FD000ED3D670C89CCF9BA09C6775AC30CED6C64 +:104FE00067CC4ACFED0ACC2F019FCAFE9C3158A452 +:104FF000A3703CF3F7767A8E70E1F76A3633D83DCA +:10500000F7E1F7B958CA79A4F179649BFB49E7CF76 +:10501000C5FA33CFE34F9E890F227E1ECAF06FC9B7 +:10502000A475D36143797E8BEBD7C794917D91C7EB +:105030001D0ACAE3E99F29D122C05F4AA51A595324 +:105040008C7ACD336D34F001ABB4F9109FED43721F +:10505000DC8374E3FF44D0FF45ABC78DF30C4C06F3 +:10506000BB9AF89BE5CEC27E26D78FE1F20F0C2EBD +:105070009D9E7D51DBBE6110CADFB08DF64B739CE7 +:10508000E108CE4F67B729E7B95CD6AC63E2F6DF3B +:105090009C49AA3F25BDA77D07DB900364FF4959C2 +:1050A0001E863A7CF786A8BE39E9CCF5084607F398 +:1050B000D807E9ED41DC2D8D41FB86FF991332DAEB +:1050C0007D66BBB0AEA2F4052003E02552351AF987 +:1050D0006CB885F8ACAFF632639B399D27B7787012 +:1050E0005FF528CA09A84F9F746212CA8D19605AC9 +:1050F00061BF3326A99E28B4DE14B2303F4CFC8831 +:105100005F8D2800DB91928E435F46BC55D834D228 +:105110005B25ECDEEB72F0FD280FE23920EC106825 +:10512000CFF59BD719190ACFDAFD275CF53ABE3BBC +:1051300052716238EE5740EE3524E227C69A89AFA5 +:105140000F7C3395FA79F37E25E280F94F563FFBC9 +:10515000ED58B467BF65F3393402CB82749DEA63BE +:1051600062E3EA774DD6D9012758600CD995A5C7D7 +:105170002B1D68BFAE53689D4AFCCF0919EDCD6069 +:1051800013D8655A4FFB143AB3233FF7D53E35DBAE +:10519000579F650A7BB38C95E9EDAA647A4ADA5584 +:1051A00056E657B3F87AB2A2DE9D0E0F12C9819A65 +:1051B0000CBE0E26AB1F117D4E57A81AE2EB48E835 +:1051C0000317EEC78F7CA6F27DB03FD760C715648A +:1051D00071BFC0563B1864F0DDD67ECE483374B53F +:1051E000EF9B97E677107DB407C7231D7F6D2339AA +:1051F0009C6CBEEE90CA8600634E0B29544AFA1589 +:1052000085529855A71F8A58E2F95F9AC5F7A1B948 +:10521000AB9845837133C3CC9F687F2CDBC1BE78CC +:105220008A9551FB6826CC6FD9100BF1A7DC1FA71C +:10523000D8C2FE4280DFB6777918F7C945303F9C67 +:105240008706F3437D591C4AA3FAA0503695834341 +:1052500099540E0915D2FBA1A1C1545E122AA6E7EA +:10526000C3429751BD24348ACAE1A1522A2F0D5D51 +:1052700045E565A037B1DD885025959787AEA5E750 +:105280002343D7517945682695BED06C7A5F1AAA18 +:10529000A7B22C544BCF478516537D74E856AA9776 +:1052A000879653392674279563432D5456849AA9BB +:1052B000DDB8D03D54BF32741F9557853653393E03 +:1052C000F430BD97764BAA588FF768733DE8EF002E +:1052D0000ED7908F93ADBB85595C0FBC98E99F8921 +:1052E0007C27DBD92DA0C75D3DDBCD136526D235EC +:1052F000417FC12CCE971FFBDEFEFE3016A7DB469A +:105300006FEFFE0C56D237BF57208BCBAFADD676A2 +:10531000BF8AFCDBC47C6178346DF48B0ACA973693 +:10532000CD5A95C8BE7B28CB46E33E9A196CCA82FB +:10533000EFD38A4F1E40793223ECF9ED04E4971144 +:1053400039BF9E00FD15ADB5D0765F639E7DE85FE9 +:10535000D32631928BD2AF04769D419F6ECE92764A +:10536000E3CE8383683D0D29E3FAA7E31A5C5FF679 +:105370006F0EA2FDFB567B54B1A27DB38231BDFD01 +:10538000BF757DDDBFE1FB787F7C7D166D60CFA1B1 +:10539000895DDCAA4D488172F016FF7329F0C9D0EF +:1053A0004870422AD487ED083F87E5F09D9109694E +:1053B000505EB627FA1C6EE32E8F764C7041FD8A44 +:1053C000836C3F2EFFD2766DA21BEAA38EF9F70302 +:1053D0001BB0F28EE0C4740DE713694987F96C7D48 +:1053E000030C3DA8577CD4AAC276284E7FB0E3D0E8 +:1053F0007E9374718F6E9F940DFFECBFD253AAE21F +:10540000F7D68E94CC113DE9D38670239CA0471E1D +:1054100003B8FAFBA38A47C727CF08FE003AB42196 +:105420001DA45FB26D6D16F925DB523D953864D72A +:1054300064E6D9A6211F5B094FF67583C81F27F9BB +:105440000EF06BB067370B39B1B5DBDE4D8CDF6723 +:1054500010BFE5FF3AF89D9AC5D74332FC3A915701 +:10546000C65D781D1F117C08EBF8D788D764EDCE98 +:1054700008FC9BF1DC6661074157C1B8C0A77C5DA1 +:1054800031F4A37D2CD6FB85F07AEA5F0CAFCF0B0D +:1054900039910CAF4CCB213909FC3A1CFD63C9E4AE +:1054A0008D5DEC67CCEF3F17FCA69373DC6FEB01CF +:1054B000393738B99C3B7421F925E48CDDE4DF49A8 +:1054C000CDE6E3557802CEECF2047E6A1137907E89 +:1054D000EAA9AAA712E50D1BC6C88E4E1B1109E347 +:1054E0003EA528AC95A9D80C8532E2B15F09F91F19 +:1054F0008AC1CEB002FDA1AB28964ECD63A943FF71 +:10550000BB5C6F9E5AAF7EBD497D1F5F8F922FB2ED +:10551000DAEEE67E496D26D82FD764737E8BF7C30B +:10552000FD20EBEFE8D776B74E0EB679BD5497ED78 +:1055300093F1EF02F1BE6DED1AC2A7737C62BB61FD +:1055400062B62AE441971FF93CFC25E6417B2673AD +:10555000EDDB249F32413E29249FF8F8FD43A9FF4B +:105560001686FA84EC3C21CF3DA937B8FFDFF173F2 +:105570003EDA54A807C67BF6A918A7013DA4E13A74 +:105580001D0F731F8DF8B213DD35C6E9A88D6711A5 +:10559000B47B016F51DCB7872D6EF233D9EDAD7E50 +:1055A0005CCFCC9E49F057788233B37B91379E34E1 +:1055B000AD14895A97BDEB1A17F0DFFA624F2AD65D +:1055C000E7407D53058C9BD5C1447DA36BDC3FEE4A +:1055D000F7A8BBEF6787D0EFB13FCB1FCCE67C5D70 +:1055E00087A57F98C74AFEEA3EC6C1E4FA8CAF277A +:1055F0004FA95C4FB523481E2EC17E657FC9EC9B29 +:105600004BB2B99CFB56B6C5C0D73DC76D36AFFB94 +:10561000BED93762BE8BB37B5FFF2F1FBC6FCB76CB +:10562000A6F337F6FB7EBB55437F06F7D3589CEDB8 +:10563000D49F5BF81BFDE86F043E700EE175FC9390 +:10564000C85F9C1C8F119AAFF4334A7F62BAE02B7B +:10565000665522A8C7D32B3CD63AEAAF837D0DFA14 +:10566000FB81C0935CD728B79E1C817229CB8AFB33 +:1056700075F427B9B3E2FD633DA32C2E9F98D8C7DC +:10568000DD2AE6DCBAC697812EE7F011EE4769FD08 +:10569000365F97D3FAB3C81A94137EA679A07D0A11 +:1056A000937FFC067FF2D44F15E687F91FFE54A5C1 +:1056B0005219C2A26ED8EF4DF32951DC07DA2DCE74 +:1056C00008EAD2CA7E4E86F14D7BBA2582F111FBE3 +:1056D000DB0AC1692F4B8BA0F09BD4AF2203E39868 +:1056E000670EEF770513D0FFC660ADC1FF65C663D7 +:1056F00077BB9B9FF7201E1FBE409CF65076779C81 +:10570000767F36DA4373BBD6DAB5789C56C61F0B64 +:10571000BCBB3756A2CA5AC2EDD37E2CD2ACB7ABB3 +:105720007471D0DF22BF3F1C8F83B65FA28F833698 +:10573000F6DB8BF6EE43DD71D06014C7F567EF2C16 +:1057400045FE7DD8B7FBC7DF457C3A44BC62D471C7 +:1057500097867EFAF2FDB908CF6F4DF397A5F4E373 +:1057600099F7C1C7B38DF18533BEEB32A2C45BD9C3 +:1057700009D7B7F42FCAFD30FA0F3D09D7A111DFC1 +:1057800072FC1A85EF6B994DE1F24FE851902F9D15 +:105790002407228CF4A6DFA16C437D73C637CA4769 +:1057A00071CF24F246CE07F0383451FC17C64B189F +:1057B000674DC9E17AAAC6C6FDA6CAF2F2269C5771 +:1057C0008DDBA53874FEFEB342AF9BE3426AC66729 +:1057D000E541E1F74E04BF39BE7356E80BC497DECE +:1057E0004F7E217C1DB3B552FCF0D83C9535433F2C +:1057F000678263F35982EF65F91AF2CD50C6DECCA9 +:10580000E1E375D33349BCE8D8EA068A339BE36900 +:10581000DDEF6B53AA517F57231E75E35E29F077A6 +:105820009D289923A879E0BDBDEE010FC3F8D7D01C +:105830004FCAC36EF48B75FD1CE317EC5B6EF25719 +:1058400054D79E2D6FBE5C87CF0AC6E3B3FB1FF211 +:1058500068F0BC7AE8DADCB02B391ED1B78578BAAB +:10586000071F8C237F4C79CE45F863D8081E17623A +:10587000FB53287E9AF207D58776038ECBF500F787 +:1058800027AF147113731CAF3AB4CC205FD2620AF5 +:105890008BE8E21769D69DE49F4D8B59E9B979BD34 +:1058A000E5E774C73969BD49FC27A3A7C4BFF979E7 +:1058B000590EE7CB63B50B35F41BDA5313DBC11B71 +:1058C000453B5937E723248BBBCF17743D131C97F7 +:1058D0008FFEAA6A7B78685FD6B9C4CF85F21CE6D2 +:1058E000E4707DEEBEE92511C753D7626F52AFA6B3 +:1058F000597B8FC7FA4DF1D8B4D13DE279FF23F13E +:10590000D8969C7F2C1E7BADE0DB0BE5A1DC6837D5 +:10591000DA3DDD7815743C134C6161908FB756AA5F +:10592000148702FE20FD78EC0185ECCD68AD83F490 +:10593000727D6D0AF967EB4B557A5F7FAF4AFA3398 +:105940000AF26109C887DF0A3961F6CF5632C510FD +:105950003F9F3E3AC550BF69DE7DBF5D8DFEE50AC3 +:105960009B86E31DD1B8BF39EC57C97E853E7C517B +:10597000F44FDF7FB50FF599E487237E95D65BF86A +:10598000A8EAC361DB853FFAC886D208E6A93025BC +:105990001EA7D70663FFF514077ED5BB85E29C29B9 +:1059A0009F3F1808D0FE31A89592DEE4F1D314B1E0 +:1059B0004E27F6ABB801F5F89B9B6C0CFD466FAE1D +:1059C0003A43EBB9637513E54548FFB2F40F9BFD0D +:1059D000CC66FF720FBFB2C99F9C2C9FE15749F85C +:1059E00043CAAB64FC0162EB484EEEC5CB31293FA4 +:1059F0005E13704EECB7E5DE66C043DA5C95F020CE +:105A0000F9F2D5CFEE7A04E5700AF0C71A86F8FCF1 +:105A1000F7E7711FC2162A09FDC81952AE63FE448A +:105A2000499C2E37051776D771F9CF6E586EC8FB93 +:105A300030EB95E472AD77B9B53987DB5D66BD6350 +:105A40005E0F5FB4DEA9AE7DA004BFAFAE9D17C1EF +:105A500072633F6703CA5FB37C30EB896A939C8DA6 +:105A6000EB07954546E9E7AD51BBB89EB0D3FB7354 +:105A7000293CDF21E4E4E5EDA9E9DBB03C97C2F382 +:105A80001DC26814A29DFA465AA485F6E54D63919D +:105A90004F42CCD7114638BDA9E44768EDCFDBA90A +:105AA000D7A472BBFC4025C1AB4AC37C6D25AD9B1E +:105AB0001601CBD6EC60512ECCA7C56F49C1F8C2F8 +:105AC00044B7F510BA5E5A27589883C5F115CF0B25 +:105AD000611E05BEA7770AEE3F4B9DF6C164A70E77 +:105AE000CB457EF936EC0F81EF0F1F5677B701A833 +:105AF000877DA33212D9E9B234C7918F7FE39581B4 +:105B0000B86EDF61C1B25C8A1FD7DF8BF1E1C63DA1 +:105B10002AC5976EBEEDD54BC8EE36C529D574673C +:105B200009FA535A94541FCA1389C77D6E3BC99909 +:105B300096E369B49F68794B117537C94389F703B8 +:105B4000D0AE6034E62AB9496E4AFC035C13701E7D +:105B5000920E952C7A787CF13F05D734C47772B8D1 +:105B6000FA7B487E209FA9713854B795E0EB64A971 +:105B70003E9C5F48F887D8EB69B4FF93746E14FCC1 +:105B800028E9BC4CD0B973EFD9EF5C05ED5BFD594A +:105B90001475500730C243E7EB6EE21389070937EB +:105BA000F0451DCE53C2BD7FEFA86341FC3E3D953D +:105BB000E2F8D2EE9679073DE494D8BF2FCD55BADE +:105BC000ED5EF45FFC3E7BC2D2DCDC04ED85BD0BF8 +:105BD000F86EC2712B3DEC93088BEFF392E537AC76 +:105BE00012FD77F773E1FC8655B989F21BFE717AD5 +:105BF000DE7531F46CB4BA362819717CCB7D332D47 +:105C000069ADE7FA37AF3F490F65EFBEBF621CDFF2 +:105C10002C176E579B9802E3ACBF9CAF4BB68A69BA +:105C2000941F645A2F17923740FF6D085732B9D32B +:105C300057FA3FD193FE4FF446FFEF65077E86EF9C +:105C400071A8C232DA17EEC23ACA13FB201A8FF8D3 +:105C5000B62B93513E9BCC8F91F3917932514C5A94 +:105C6000CDD5E5E194F814D4137DE08FA87E7E5F56 +:105C7000007FFCA6773916A575BA54D07FA9CCCB86 +:105C8000D8DD7B5E461FE8F75A22FADDAEFABA820B +:105C9000C57DA7DF3B3DE9F74EEFF40B9EC2F72D24 +:105CA00076F609D9EF15B55EE4970A8F7F16E6A15F +:105CB0003CDB2CE44E31D00FDE3F9FA3925CFB1EF9 +:105CC000BB94E4F6972C169A6F27C8EB6D4A9FE0B9 +:105CD0008CE5D2FE2F6CCD827E6FBF8E517CCFAB18 +:105CE000352B58CFD7404F6B7D8757CDE37A5C0774 +:105CF000AF9A9740AFEBE4953D8FF3E74AE44FA7A7 +:105D0000E6B1F626AFB2F28C76421FF8312BEF8B5C +:105D1000E5C70179BDCAAB8BE6B36138BF6472A237 +:105D2000AF79A0B04E596156CFF119F3515CAD3245 +:105D3000DDC9F5F62E45E8F1D220D5DD4E12160765 +:105D4000849E3FBD9BBF572724B62B7D7959C4CF76 +:105D50004B772E0F580DF924617AFE5DFF69CF1045 +:105D600015F3B45D044FF634EE8794F0CB3CED743C +:105D7000014FF6000E77F6719ED72EF1952EF61B89 +:105D8000191556C33E42E2ED7635A0A01F3D33877C +:105D9000619A04EC134628E8E7CAF41BDB4B7CE766 +:105DA000B24D7F5631E5ABCAF83E17F73323F1BD4C +:105DB000EE7982FD2BD0A704F3C766E709FF839D28 +:105DC00079511F31B5A6573ED2ED4FEAF2FAE0679E +:105DD00069C8B3887D8351EFED4C6109FD0C7F11DB +:105DE000EB01EC15F237AB42CF4DEA28A67C9715B4 +:105DF0006E8DFC0FAAEA734E2DEEF97DA61F96B7A5 +:105E00000E1FD955A94CD3C19D1BC832D4F3ABFB8F +:105E100019DA17040719DE17365C6A783FA0A9CC97 +:105E2000502F0A5D69685F0C88D5D7076FF8AAA163 +:105E3000FDD0D6AF19EAC3B67CDDD07E78A4CEF013 +:105E4000FEB21D8B0CEF2FDFB9C250BF62CF370DF2 +:105E5000ED5B841FD98C97FFCCE372BBC5CAE550BC +:105E6000B3AB8CFC9B2D2EA37FF33E81FFCA8CF13C +:105E700025E8576F79BBB404F17D20FD4AF2B327C2 +:105E8000E30BB35C4B264FCDCF9F14E37DFC9CDD31 +:105E9000827CBD6C3FACDB2BA0EE7A6D3DC2B47151 +:105EA000048FCFDA18CF1792F11AF97D77BCC6EAC2 +:105EB000E3FEDA7417BB3B015FDC97A725F4A74A22 +:105EC0003E4A8637C98F17C2DBD302BFFF2CDE5E86 +:105ED0005778BEAB5E1FEC4A30AF337916115F0EB8 +:105EE0001E15FA66742A59F21E5A8F17AB0FE43C3E +:105EF000401FBC9997DB334FF7E3EA97E63FA86171 +:105F0000FBF9BCBDC557827449E64F3F23F0A6F3A9 +:105F1000A737707F7AAA016F6FC9F56EF2EBB5A44F +:105F20007F4AFEF416BBAFA42FFEF4B7F218E1FFD0 +:105F300069A473AE8EBEC21F9F6C1F1562EC109ECB +:105F400087602EABA6DF3725DB1F4B790EFBE312F4 +:105F50008CD3B6E2FE4B49A80753F2CB69FF4CFA4B +:105F6000A015F4A083FC04EC9006F5DB275AD8DDDD +:105F70005A1C6E69CF3B98CF695789AE19F83DFB23 +:105F8000365B99A27E21FBCC7EF917A1E7D985E388 +:105F90007D64A74D03F8D7E8F6D7123FE6F89EC414 +:105FA000CF341F8FDFAD03FD88F1BD7DB95C4FAFEE +:105FB00083FD37E2D1931DF00E447B1E9E6F43722A +:105FC000E48EA1F523F16A8EF3F555EE8CCFEF61E7 +:105FD000B78ECFEFC56E95F0AF10FBE7C9EA889D8D +:105FE000E8C73C1DB313DE54C6F32E1B0FDA5884EA +:105FF000E8C8F397251D6DB1F5EDA89F6DCC9CAF5A +:10600000AC6520FCB683FC9C18CBE1EFC3CCD98CEB +:10601000764F4685517F65FA8DFA2BBB2ACBA4CFEC +:106020008CFA2BBFDAA8BF0A8246FD55D85066D23B +:106030006746FD55149A60D26746FD3578C3D74C44 +:10604000FACCA8BF866D31EAAFE111A3FEBA6CC7E6 +:106050000A933E33EAAF2BF6AC31BC2F8DDE6D7860 +:106060003FEAE0F70CF5F2F61F18DA2F38F414E5E2 +:10607000F58C3DB6CDD06E5CC74F0CED00E1ED98D0 +:10608000FF3D9748C2D855A79E34BC9F2BECB5ABBB +:10609000BB9E36F4C35A791E7718FE22BDDE6341DB +:1060A0003B1A2956D6F54221D0755944F145A1D95C +:1060B000C23DBBC6E03C3E7CE39A83D8CF822DC66E +:1060C000FCEF851163BD910DCA40B9D0087C110168 +:1060D0003E598C79E13AF9B698358973817DE3B3FD +:1060E0000587AE63944F1AF6B763DEBB8453F29B09 +:1060F0005FF09B9C9F847731D87F512D0EA71FFEA8 +:10610000F2FD66871DF976FE1E85FD40E9094FC345 +:10611000DECDEB0B13C06586C36C87FE47BED13F57 +:106120003E597551BCE0F451D5C7FD8DC675B8E236 +:10613000108F13AC7842217F9D191FD23E4D8617D8 +:1061400035CCF70D8D392C12D1AD3F4DE0C3E13583 +:10615000AEBFD3F80F9CCF0FD508E61BA568A96684 +:106160007E1B13653DF19C56625CA7663CBB7DFDC2 +:1061700012F295067F711EF3C5F943335F99F1BEA4 +:106180006CCF663BCAC38BC5FB6BF989E312A0EDEC +:1061900046DB13E4D749BCC2BEBD03F548B2FDECF3 +:1061A00047F917BD9FFD28FF8BDDCF9EEB4DCF75C7 +:1061B000A2BF0DEC4BB39FCDAC8795BDFBFFAAA44E +:1061C000935FBBC381EB2EE873F23C18939E2C299E +:1061D00031E8C9EE7DEFDB0AED7B7F91E1B77B61B2 +:1061E0003EBFC9F03BBC00E72D197EA757076F0BD8 +:1061F000E085CEFD809EDA95C04E9CE495719700B7 +:10620000F94DD655F2F6E67623BCFC9CD1BEDC31C6 +:106210005EB23FDF2AF592FDE91ED3ABFDF95D11B9 +:1062200027BA07E39043E3F941F78A780D2C3B3F07 +:10623000D26D9D2DE0D5E70F67783369BCF4714FBF +:10624000B6631E758BC7E251342C793EF75A97B569 +:106250006ABBF82EC7F01D3FCFA422BE01AF5697F0 +:10626000F5533DDF4EF232EA37199C93BC7C3F690F +:1062700063C17BD11E92F161DBDB954E94772DCC0F +:10628000EFE172D2E7D1E77FD8188F074F10F161A5 +:10629000F95CF5FC637958ED19C189DE047958770A +:1062A00064F827E1F39035EC40BB33E44CBC2FFE9F +:1062B000AA97AF139B80170C50E22B9A877AF1F1C3 +:1062C0001FB037AFC7716F57C39427D9E21E53125F +:1062D00074F5DDCF15F4F6B08F82DE5EEC23B04F9F +:1062E00067E179327F463F2B6D3BACBE12C4F706A7 +:1062F000FCF738F2D32EC0EF7BE4BD8A73B8B08FC1 +:10630000EB358F57F6B33FCBBFCCCBF30D9BB03FF4 +:10631000FF30CF5A55D74FFA05FA917E8E3EF8AD31 +:10632000BEED4DEC1F3D85FABDAF78DCE8EDE12F09 +:10633000DCE8EDC55F78EEF8B00C8C674B7F97B961 +:106340009D3C1729EB1B328DE3AF2FE3F5FBC5B85E +:10635000AF887B3A7688BAD3745ED43995D13D1D27 +:10636000F29CA9EC6787D74DED9BB327ECC0F9AE43 +:106370002F56681FBA3E5331EC47EBBD953B900E4C +:10638000DB44FF3B907F73296F94FC39E63CCC25BE +:10639000A2FD12EF042AF15C2BCA31BBAA26C4E38A +:1063A000135E3EFF5999BC5FE977AB7F4011FB2735 +:1063B000E3BD08B0CE5F4E03F97362938DCEBDCEC0 +:1063C000535DEB911F93DD73503B2240F94FFFEC7F +:1063D000F931C4675A564FBDFABC37F1BD05C9E45F +:1063E00088CE9F76D87B11794B1DA99C4FBBDC2EA4 +:1063F000F29B9BDBBD2BE8B349F83550AEA37EC9B9 +:10640000525953223DF3AEC0FB3F7EAE99DFE79178 +:10641000ED72D177E673CD1DF68E75F938DFAB15C9 +:106420001F9E5FC8AFF1ECCBCFC1738C1AF9F8D6C1 +:1064300017B3F40A7C5F6AA1F799B33CEB6D98F748 +:10644000AD31CCDC673618C70DE3A4171473B8C29E +:10645000D7EDCB8776195A171B3482CE7B4FF1E2EA +:10646000BAADE6F9F33DF02DE49B6B1DEC2F101F48 +:106470005AE23CF4F342BF80BCF93BF26BA5C6760E +:10648000F373593C0F16D992F2157D3C5F3B0DF327 +:106490009D06737983EF95EC89D682DCF8FA520574 +:1064A000BECDE7B9D30BF8387D3DCF3DA326F17CB7 +:1064B000871770B88E67047270DC19E39BB93FECE4 +:1064C000B3F3E7D531681CF37502DF33F457A4E466 +:1064D00070399CA26924979947A13C57A7E66BC0E5 +:1064E0007A8AEB4A8F8A76B283C725D95C0BC3FBC5 +:1064F00055268A7EFCD54C79B784FB65B99CB5B22C +:106500007725FFAB02396350CFF23F603F6D4A03FE +:106510007826BA0E537C32654853259E6B787E0EE2 +:10652000EFE37B49CE0DC8F3EEDDE7FAD98F0E1B02 +:10653000CEF5AF7BE4F0C1AB75E7FAC38F1CF68FE5 +:10654000F8C7F3DBA73CF4C8E1B5AEFFB973FD5261 +:106550009E1D5383C7EE04FC5F0F4C152AC3D2CA9D +:106560006A88DE5EC2DB2C81E7F0A78067671CCFFC +:10657000D7EF3D44F83B668379C3F8B6091CD5B61E +:106580006F66445A482E4668DC1B9CAD9371DFD978 +:1065900069EF1A89E3763EF3CA8030C893E3DF3AA5 +:1065A000E366C07F6F5ABBDCF8FCD4AA97DC780F97 +:1065B000C2F1552AD96B742E5A978FD420F8EA5716 +:1065C000058139C85773567F3E466F8FB3502EE909 +:1065D000DF85119552AFA4FC5BBC234D301DAF2F5E +:1065E000DD996DA84BBDBCD491F89CFAA3059CEE37 +:1065F0000B1F6FB3176A387E70398E7F4AE4379C61 +:10660000DAEDA67D989C4FDDE3A576DC77BEB9D7A1 +:10661000C1A2E4076EB731F267F9A72A79788F1122 +:10662000FF639EE70BCFA6517FF31E50C9EF540BBB +:10663000638500AFC1BD0BF93ED804C7BCE3DA14D3 +:106640009457F3362A2CACF1F6ABF0FE8CD05D14E7 +:106650008731C369D62F0B92DC9FB360EF3DF4FD09 +:106660005CE6BF07EDD979ADE6F7D7BC874CBEE055 +:1066700002F19CFB0B84DE19C3C69E1F4CF1A38C58 +:10668000CBB50BEB9D53ABF922FD60B593CA8F568A +:106690007BA89C53C0F978F19E7D2F14D2326F1FD6 +:1066A000837AE9E583F5695FD7E276F798B65BF719 +:1066B0003F4C4D8DF9993502EF63455EE60271EE70 +:1066C000A1FC58EF799935888F913DE72BEDEC1AB5 +:1066D00093DF57DADD667C9C3E38310DF9E3970590 +:1066E000629F3B16F0A2FEF37849F6DD5295DF9BE0 +:1066F000667E2ED7D11CC1D773B7CF5CDF0FC66FB4 +:1067000079E6BD811DC4A7DC7F512EF055EE5ADF1E +:106710008EF0973393DF30CC8E321D3F033FA9A814 +:1067200077CC7C2BF9891DE5DF3B855FA39B5FF769 +:10673000DE4BF8957C85271D2C68C3B1A8D7527114 +:10674000E17BAEE6B51AEB1FDB3A06A23C5960F2DC +:10675000377CAC24DEBF1D2A1844F898ABF9A7603B +:10676000FEC53C1658CFFDF3FC7E9C53D6D617EEE3 +:10677000C475BE9DAFB3A5BF7CE21728BF16FDEC64 +:106780008174945FEF5B5BF370BC258FAD4B4779F1 +:106790007FCA1A4EC7EFDF8FA809CF115FD24FEE25 +:1067A0009FFD2ECC535B46AC06FFCD0D4F47F9F94C +:1067B00097C76C1EF4C336EE70441D808F65BB39DD +:1067C0001EA1FE16AFDF45F86ADC635C978BFEFD09 +:1067D000813C8DFC01E14281BF4214E1CBB6DB2854 +:1067E000AF75D951D587C334B22E82CFFC3DCE23AD +:1067F00006746BDCA9D6DA337ABE074BC88EEBADD4 +:106800007137A767E36E4EAF46931DDA20E4B69961 +:10681000FFF3FA097920F81EF0437E35996FCB22F9 +:106820005C7EB7FCF8C1916FC1FC3EDAFE9B7465DB +:10683000449CFF196685023D4EEFAC9F63EFE5BEB9 +:106840009E8FC53AE9D60B420F697B6062F950DD35 +:10685000CBCB25B668FA558097256D365F181E2F6D +:106860007942F5BBD08E7AD541F74F2C7EE2F9976D +:10687000AF84F92DDE65CB99CAC170A1FC96F46A8C +:10688000443E2F8BD367D153CFDB314F139FAFCA19 +:106890008AD369F1AE7D76CCFB34E373E2CE7D76AC +:1068A000BEDE4CF4DAF9D614D4DB2D3F3E67477ECA +:1068B00078FF5985E517F7FCBEA1EDF9749433888C +:1068C00027D42F926EDD74EC41BFE8F4A747533B09 +:1068D0000FC6792E44C7BFE019845CE2F79F3E0DD6 +:1068E000F36878CDE1433C34FCF4D67484E73D6B27 +:1068F00013E7FB47D6E5A1DE6EB085F33C54F2E723 +:106900000D5BBF41FCB8E0C56FF0FB9C98BF00D7A2 +:1069100033C05B8070CEFBE1F504E77C16247E6C0F +:106920007884DF6F78D6CAAA12ED07DAC4BA796F15 +:106930009B83360FEFD919BF2FE4F7AAB80F6B3935 +:10694000D92BDF10308384A6FA5927A7D7CA7EF245 +:106950009C3D976F8DA255E3F6BB48BE7D30C09F2E +:106960008FEB1FF060F4CFBE38395FC845BAD785CA +:10697000BE03FE9B88CFB17DBBCD9F32D2F09DC8B8 +:10698000BFE5E3AF14E3C3BC53D1CFF75E9E719F65 +:106990002BCBF66EB9C0DA999ECF92C981ED1B89D7 +:1069A000BF3E39CAE5CCB2C8CC2A7ADF6E8BE6E3AB +:1069B000FBC8BE590AC909B04312ADF3ED36B1CEDA +:1069C0008DEF619E56458FDF67F9F93DC92FF3EFD3 +:1069D00087F6BA751DE71F7BFC79717CBDCAFC8DFB +:1069E00005267B4E966639F1B0494EC8EFD90F7334 +:1069F000139E8F88CB8730E16F892DF26F3FC07572 +:106A0000FDAA83CE452E79C246F7FB7CF8F8FE97A7 +:106A1000BF0EFCFFE14EB99E8DF2D7BC9E1B9EBC03 +:106A20009E255ACF1FE60458C2F50CCF13AEE71CC3 +:106A30007EDEE0FF96FC5D9044FEBED0AFA7DD7128 +:106A400015543FF8C9E222DA9F99F02BF16A96A714 +:106A500037A3B190DB539EC29FA34C874F8947C990 +:106A6000A78BFE63298DD3CDCF925F253F77F3AB04 +:106A7000196E233ECDEF37E2DEA93C4E7FDB1AD8FC +:106A80009763BCF61995F2F33AB5AEF42C18779DDE +:106A9000C8EFE9F4887A26AF77E5DAD7A33C91CF3F +:106AA000BB5278BE4367A02B3D53B71F786BAF9A9C +:106AB0008EE7013A2289F332286303FD2049F2363A +:106AC000E4B9DFCE54EEEFEB4CE57EBEC9AA6B60B5 +:106AD00008F777AD3CBE34B7F9C674DCDF77EE1D3E +:106AE0003CA31AF70387549E7314F65B0B00BFF5A3 +:106AF0001C74768A85BF3F1EEDF7BD8BA7623F737E +:106B00003719F132DFB5DD8EFD9C65ABA89C7FBFE8 +:106B10002DCE27F0DF22CCD7423EFFA1E9F9DE6B74 +:106B200089AF1699F82A887C95E03C4966A158AF50 +:106B3000A5AC94EFB7457C4CC8BDC9EA8819D59877 +:106B40004F79909FF738BD5765EB11DEC745BC2CD8 +:106B50009C4BFCBA0CF85BEF37FD08F96E58723DA0 +:106B6000FFD1CF8F8FB9139A2CF9C51F473E0CE583 +:106B700047BF78F592FFC2FA2F5F19F847D6B3FDE9 +:106B8000C467FF7A0BE5753EEBA07B4D3B9FFDD5BF +:106B9000C03BB1FEB483EE17ED5CC3F7D9E167DD0E +:106BA000A4FF3B07707BB1E59973233B487FF17BE2 +:106BB00083C717F27B2A4EEFFDDB1B0AE6F3ED05D8 +:106BC000A8503E8AFD5BE3D329B44FEF7CE69C617D +:106BD0007FFACFC2B34C9CBBEA74B36A3C27DD9901 +:106BE000C9CFA936FED7B81FE1B9CBA5BBF7D9EB02 +:106BF000E1FDC4FFF3F94894439D4F72BB03ECE100 +:106C0000ADCCC7D8570A37DF6B03FA7D8C3622AC80 +:106C1000998EC217A7E179929E78E178E8043C202A +:106C20005C809706949FC9F0714B213F07F3AF87B3 +:106C30008F3FDF82E32FD93B96EE198EE345F1F3C8 +:106C4000E76ECAF700F8F9F367CF8D443BEA42F0EC +:106C5000AEFA5F06EF0FFEC5F97D5021D74766BE3D +:106C6000EFC9D7BFBC8DEA3F75FB68BE7D5CEF4FB7 +:106C7000FF2FA3F7B1FF6FE97D48D0DBEDC1B84C22 +:106C8000E7339F0F641701F7B97F593AF70E77B7CB +:106C9000DD63F13947C3FC5E6391EB2B95E4F9A307 +:106CA00043FA2B721F44FB0C790FF7F49CF96447ED +:106CB0004CF7737F4C0B2B3B88E7ECC27E95E217B9 +:106CC00094BC0378689F551AA13C316B78E8F73182 +:106CD0006FEC86A53E7E5F9971FF353DAFAA0AED48 +:106CE000B923CD302F6877C46DF1B4000833FC2A86 +:106CF000D97F5092DDF78709D7521ECA8C0AE33E2E +:106D0000E4EBA6FDC48DD5C6F737B06DB998EF7723 +:106D100043838DF293AE37B5B7F4F7105E6E644DD2 +:106D2000EBB83FE7E2F034AB3FDF8FF5C443EF78D9 +:106D3000EB8127B1DFA4DC21AD27DE1C41BEFF744F +:106D4000C00B616F89BCBC157DC22713FB5287182D +:106D50005AE2D7E1E7F78EEAFA25BC48BC5F2CBEC1 +:106D6000259DCC7897F8957833D361189EF7CC8D14 +:106D7000E33F5E1AEFD566C26E9CDE6D37BA088FB0 +:106D8000BFDBCECF4BFCAEA27E5329D61FE7F7C1A7 +:106D90009F1D3F8A3901DE2336B687E2427EBFE679 +:106DA0001913CF9F512A7E45F109CC5FD4EF57319B +:106DB0007F510F17E62FEAEB98BFA86F8FF98BFA78 +:106DC000F798BFA87F8FF98BFA3AE62FEADB63FECC +:106DD000A2BE8EF98BFAF698BFA8AF63FEA2BE3DA5 +:106DE000E62FEADF63FEA2FE3DE62FEAEB98BFA89E +:106DF0006F8FF98BFAF798BFA87F8FF98BFA3AE675 +:106E00002FEADB63DEA2FE3DE62DEADF639EA2BE33 +:106E10008EF989FAF65F8E3D67A857B2DF18DA4F10 +:106E200074BE64A84FF6FCD1D0FE2BDE1386F7D7D4 +:106E3000681F1ADE4BFA5F5B72C6F01C631FE131FC +:106E4000B88FE17FA6F9FE66E8C7CA021427B5B37A +:106E5000262A9DE8EF853295EDA4D205CB1CCBF711 +:106E600087057FDA1FF9756B783D32D79171E70698 +:106E7000A2FCFFDDF8EBB85F42C41766E03F356067 +:106E8000E2B4CFFAE33E57C64FD3632A8B8E023E5D +:106E90008C29547A62692C9A0D7C184BA1322B965E +:106EA0004DCFB3639954E6C40AE9796EAC80CABC8D +:106EB000D8602AF363C5547A63975159101B4E6505 +:106EC000BFD828FAAE30564A65FFD855F47C406CDE +:106ED0001C95036313E97951AC924A2D762D95C523 +:106EE000B16BA81C14BB8EDA0D8ECDA472486C3623 +:106EF0003D1F1ABB89CA4B62F5540E8BD5525912ED +:106F00005B4CE5F0D8422A2F8DDD4ADF5D165B4EE3 +:106F1000E588D89DF4FCF2D81D548E8CB550794587 +:106F2000AC994A5FEC1E6A571ADB486559EC3E7A09 +:106F30003E2AB699CAD1B187E97979EC212AC7C42A +:106F40007E44E5D8581B9515B1FFA0725CECC75480 +:106F50005E197B8ABEBB2AB68BCAF1B1FFA2E75786 +:106F6000C7FE93CA2FC5F6D3F32FC7F651E98FFD9D +:106F7000869E57C60E513921F6123D9F187B91CA45 +:106F800049B13FD2F3C9B157A99C123B41E55762C1 +:106F90006F515915FB90CA6B62EF53F9D5D819FAA6 +:106FA000EEDAD89FA99C1AFB1B3D9F16FB2B95DDA3 +:106FB000FBFFF1497F57C0721EF7CFAEAC3EDD57E5 +:106FC000B6392D9DE4E2F4555C2E3E98F6F101921F +:106FD00093E31C9A8384DF1643BC8B7E4402F67DC8 +:106FE000FBC6BDD71FED9DF595275EBF15F5D97280 +:106FF0000713FACC24773F73097F27C37CC49B0512 +:107000005FFFAE627F2EDA51EBCB3A96A0DFE4DE73 +:10701000E28E1A2C0B07703D9925CA8201C2CF5A05 +:10702000C2F56FCDF2A1FCF70572FA065FB5D0DBB1 +:10703000B2BD5224EAAEAE81745EAF8FFDF4B5DD11 +:1070400085F2B03EEF1FBC62406E6FE707FBDC4F7E +:10705000C517D44FE580047961E67EDE14746F1B9A +:1070600010988CED99D53F12DF4F5853A0E2EFAA4C +:10707000D46E523CC82FF56B4BA7205DCB989FFC7C +:10708000923727C9275B2CE85AD76463E89FACD3B3 +:1070900018F987EB76F33C64F4A74E037E6910FC85 +:1070A000B274E39FC9EFD4D0B480E73D45B87F4ABE +:1070B000FE8ECDE2D6B617D0AD77961DA6FCF8C5EC +:1070C0003B8CFEAB46E19F5ABAD3F4BCE92B09FDD9 +:1070D0009E66BFD4DC01C2DFE9E3794F4CED4F700F +:1070E0009F05B8319F24789BDB897A03F0417118A2 +:1070F0008907E9F794F8603DCF5D50FEEAE98343E4 +:10710000294FEEB4A6E563BB603AFF3D2BC51A1CC0 +:107110008BCF018F94CFD2D59C46F9506F811ED072 +:1071200030F1CA131C8BF7C775BC368089FB2B8DD9 +:10713000F108E726CA13AF8539605E4AED63D9745A +:107140006E13FA1BB907FD9A8FD9281F29CC5678E0 +:107150005945CF7845609D8DF8A26E4F26CF4F0BD5 +:10716000FB8FE2B9024997B7D60E9E82794D751B07 +:107170008A4BC95DB7C746F6A18CCB4A7AF5CCDFFE +:10718000E6F9028D2CB21E5397805E2713D2AB75A1 +:107190001FD115E8763209DD4EF646B7874D7443A8 +:1071A0003FF58DF8725536ADE79A35D1A14D3AFECF +:1071B00034FBFFD9DC2BE9DE1399FF5CD54FFECE03 +:1071C000982F0FE97B665339D1CD4CAFAABFD713A7 +:1071D0005DD86B6EBA77F8E6C16CCED7E0F91CE1EA +:1071E000F7BCB9E51AB2BF770B39F7BBD598FBC925 +:1071F000D88BAB9DCC0FC6F74BAB3D54FFC36A2F6A +:10720000D55F59AD51F9EAEA122A4FDA795E915CFD +:107210005FC00894DFF7B458574F0F90FBB2955EEC +:10722000F47357FDFDA5720B89BE37A64F1E40763D +:10723000BB215FA47A96311FA4C326F2CD362A3E25 +:10724000BC4FA62E7095A13D2B1915AFA3FE11F9C9 +:107250002B751B32E91EBB9BA6661BDADFB0A1D0E3 +:1072600050FFFD008DE09E5935D8F0FCEB359719A5 +:10727000EAB5E2F723985641EB46C6BF407373BAAE +:107280007878DB4F9AC6E6DF0EE37F72D846EFCD03 +:10729000F438690FD37E3EBCCDE1C3F8DE293CFF54 +:1072A00006F5537F5029BFE8948D853D20E24F2994 +:1072B0006C2D96CCCAD7D5D9637C5D55FD5D65B87C +:1072C0008F673F71507CB07E8BC2C27837431760A6 +:1072D0001EC65DF96307C13D778BCA8274BE4ADB67 +:1072E0008971F2958F0DF3617CF4E6C1D10178DEEE +:1072F000B0EBE7293E3CF755DFC1BF3F05FBF34C40 +:10730000CC8F52CA281EF1A769ADF32D986FA71E26 +:10731000CEC5F5FAA727F9EF9A2D5CFE87311EC07E +:10732000F3A21776BE5C01E39C6C5569DC0F7738DD +:10733000DA545AF7FE7CBCDF360E7784FC14D7F69D +:107340000BFC0DE5F507F3232349FEACE2FEF19EAD +:10735000F8017891DEC8AF3A7916D76F3CFE064245 +:10736000A800E544BDCD4771D9939B6C142F047DD3 +:1073700040F906275BB32D5C0E3D497C5767D5EC81 +:10738000FA71EB36A97EFEFB189A1DE7CB36AB41AE +:107390003616EB3C3F22BC4109F2F88F91BEB72E66 +:1073A0001F4BE7A2CD795CB2FC18D6545017575A40 +:1073B000F40C8FFFB2D11D567D9EBBF4CFB060851B +:1073C000E13EA325831EFCCE78284FFBF9D58B67C1 +:1073D000B7BB494E7E64796ECCED507E382DFCAE45 +:1073E00015E8F2A21A1C3610F3862C9BB62A145705 +:1073F00039F11D8CFB7FF084CD47CB50E48D2DFA05 +:10740000C9428A4F25B7179897C7AFA3798A176FD4 +:107410002766942F329BED14FE8508CF33C04900B8 +:107420007E3C4B785CEC44B9FB6E3C3F5C6F3A6F42 +:107430007C429CB3B872A062D0D7770CE472A0DE15 +:10744000C2D7277B96DF43297F2F4ECA71296FA5AC +:10745000BCFEEA409EC722E52C633B49BECC17F731 +:10746000252FD9E1E0E78B34E6413C2EE4646277D6 +:107470000DE4EB7A91FD89EF235B2F60EDA4F73EDD +:10748000B045E6B717E3F76D6BB3E87B9B2F82EB54 +:1074900038227F8FCE4A726401E3F35CDAAA44A2F9 +:1074A0003A7F87FC7D12867A4227777AE805933EF9 +:1074B0009827F4DF3C66CA376A35EAA9409A9BE010 +:1074C0005AD42AF2B0BBE7A5B2F318EF0A465E9889 +:1074D0004EF3567C9104F358C0BAA2782FF2D2C76B +:1074E000F93926F3BCCC70F4759EF37D3327E1FDAA +:1074F000CADDE39AE62DF1CDF060958E0E12EFF322 +:10750000C31C9FF3F72A44AF7784BD25CF079AE9C0 +:10751000BF8005A6A39C5B703FEC338BE3FC20F996 +:1075200060E1AE089D07FC90B5A6BB603D2CD9B2CA +:10753000EB8671F0FD821FBE68477EAFC98A0EB52B +:1075400064C2FE333CE9BB555727D0FB263DFF45BF +:10755000E18909BF157D077899B75DA53C0A5D3BB8 +:10756000914710267C3584F9EF09361C557D2DF0A6 +:10757000B4017FE6A8ECE2E72BF1F63F3D6FB35D87 +:10758000F38B81BDDB356679D3C3AE31E9533CCF94 +:1075900081FAB32B97E7A77F62F56764919C36C9A0 +:1075A000E1DC32BA8F55CAE1F9420FCA71E6A1FE99 +:1075B00083FABB5B9E4A477FC63BF73F9547F91A64 +:1075C000A86F46C4F5CD6DF57CBCDB7E9942F952BF +:1075D0007F9AD63E12EDC19A477E95AEBFEFF54F2A +:1075E00005C1A30371BE423F2E55DB06E2EF1A4AE6 +:1075F000397BC17D5B3238DD1780D36D84B30EE1FA +:10760000D49D53A91770BEBD81C377621387776E6F +:107610000F38C31457B9ED470E5F98EC8E28E9F583 +:1076200053BB5486FBAC6EBBC364079C65AD5B115A +:107630001F4B57BCF28615F862E125801FE0839A44 +:10764000CD0ED2FB0B7FCEE3A91F2895F914D03FB6 +:10765000104DBF039E2F027B01ED8DF83CBAED80EB +:10766000CF108FDD76401FF1B74CF8B596EDFD15C4 +:10767000FD8E96E2E7F998CBE4BD367B4CF7DA68ED +:107680002803F8397F27D2A9BFF93E2EEE9FFDCB04 +:10769000D03FDFB282F8BFEB12FD39B6C6D4A80DD9 +:1076A000F390BB762964272D5D59995EC9F07C1B48 +:1076B000F7AB151471FDA6F8FD945FE300BAA6C2FE +:1076C00078FD8B34FE5CF3F07CF31F32BA4747CE73 +:1076D000D7FC1CFDED4ED4872E0BE94333FCD716A7 +:1076E00071BDB954B5907DBDC4CEEDEC4E717FC572 +:1076F00070318FE145FC9CC315C2AFD0897625C699 +:10770000BBAF76D0EF18313689FCEE56C6F9CF2ADA +:10771000F1E6B17EDCBDBEC97EEEEA8F78BA85B5F2 +:10772000D3EF224EAF98A9E1798637F29C744F14BB +:10773000FC09603FB3453F476CFCFCC21B3806C0E8 +:10774000355BF8A7DFC0EB5161FC370AEC64D786E4 +:107750009F7190DD70572AF71FB29C0C2BAE87AF3C +:107760000B3975F378871FE5FAECF17705B084FEE5 +:10777000C20CF055E3EC5A570AE3345BB8BE6FCE47 +:1077800062DC2FB0B6A31CF1770598C998BF0FD063 +:10779000EF3E9FDD1B1F19CF4F2C413FC3958C330C +:1077A0005805E1D7505F62E7EF6B1FDD31E3FEF173 +:1077B000B04FC0AC29D4338823E48BDA0CDAFFCE87 +:1077C000C0F30559585A89DFBE6665610B2F37B87B +:1077D000E85E25AFE17761AFAF60D10C802F7AC84A +:1077E00078BEE3C6A8253A0CE345D6E83EC49FC55B +:1077F000A9D93C304EA04A2943BC2F59D3B7F9AE82 +:107800007CF4A919F7F7873ADEE785F3BC43A17C3E +:10781000A1D9B0E8914F6FB1B2036A19A71FF26105 +:10782000639616A676CB399FCB7325922EA5D0BD35 +:107830001EBFB3C5FCA09F0DE9F8BD3DB15F252C6F +:10784000F852DA6B8BC5BA5D2CF9EE71E37ADD265E +:10785000D70DDA8780B7D9A24CC6F78F8A75F16841 +:1078600011DF67DE5324F7997D1B6FA9834509EE6D +:10787000671C444739EE0C513E523488FA93F3901A +:10788000FC3B9F35513ECF7CE1A7B18024A1FCE0B9 +:10789000D61F71BF9029EF080C25CA6F5BB4DDFCC1 +:1078A0005CE7E7510D7289FCA68ABD6B2ECE4FF9BD +:1078B000528A0FF97DB67D27F907CCED6CF8FBA94C +:1078C0001877DB00769522E26550776C52E8772FC7 +:1078D00066F7EFBA1CF53948EB29742E54D8DBF360 +:1078E000057D1DE27EABF9685F615C0DED2BC4D7B1 +:1078F000166E575A853D5CB7C9686FCC5EABB33B1B +:107900007961B81FC061CA53B709BBE34D7BD7E5A6 +:1079100028F7CDF705BC69E17084F318BF573387AA +:10792000BFB70AFB52F2D5CF8A6C86789B3C775A58 +:1079300083F28ADFDB60CAD372D1FD31350ABFBF63 +:1079400053FA215F17E569B043E9BE9CE369140768 +:1079500037FB273B2BDD618BCE4F7973C66DD3117F +:107960003F35E9762B96AF77DF2BD641E31FF70C37 +:1079700022FB677DE5A82D989FF4DEA36766380794 +:107980005034459C9F8AFD0EF3E9677D06F050FD5B +:10799000AF33FCB08FEA7CBEEB162788EECF8B3E70 +:1079A0009D61053DDFF940D756AC67686A80EAF70C +:1079B000760DC43B9733220E5E6F96FD3902D85F79 +:1079C000E743BCFED1A38E4018ED5F716EA9E64A75 +:1079D00085E4AF0BD75779DCCF5463798E9713F8D2 +:1079E000EFA25CA89D570BB88ACAF13ED493F4FB72 +:1079F0000B8307F95D45807FCFC0E0392C17CD544C +:107A0000C2763CEF7F347289D06B097F27C425D6BC +:107A10006B617180BE977E74E88769E53DFBF96F05 +:107A20008E8B3EA000800000000000001F8B08002D +:107A300000000000000BE57D0978545596F07DF5B7 +:107A40006A4B52498A244042162A090901031490BC +:107A50004080A04512202C810A28A2A0168B10106D +:107A60004840EDA65B7AAAC226E216D4B1691B9DF6 +:107A700012D1C66EB5A3B204D92A6C823A5228DA62 +:107A8000A8A041504163774418E30CB6FF39E7DE04 +:107A900097AAFBA8B0F4F4CC37DFF7878FEFE6BCEA +:107AA0007BDF5DCE7ECEBDF7651C63AE7A1B633F88 +:107AB000E3CF0DA1D2D6D5C05821632F3ADCB6AEA4 +:107AC000504E5D9813EFC967CC9EE18972003CB7B8 +:107AD00052F199FB30C68EFA73DDB18C8DBB423FFB +:107AE000BFC8BCA49F847FA49F8F74FDDCAEC0BBC5 +:107AF00083E03F733AF0FD3BB25DBD1D1D19BBEB4A +:107B00005F9807FB6165430C6C0063775B19FD7C34 +:107B10005FB335D75A00E54B96449609ED5ED9968A +:107B2000310BFA618BE1A514C6BE69FCC8EC807EFE +:107B300016B4AACC95C85875AB42E5824D8DE611B6 +:107B4000D0AE1ACAD2B0F9CD13F365ACC93821361C +:107B5000F4BCBF83CF97B1358CE17C5E396BF440C8 +:107B6000BBBB0CF55F3E95048F072BCEE71D97AE90 +:107B70003355BCF72963E5F5F997D60F722854FF02 +:107B8000588EAB08D7D905FA405835F0F5EADB2F07 +:107B900015FD4D8D6677B8A17EC68058AB03F05DAC +:107BA00078D4B32C16E6316B5D663F15FAE89F5129 +:107BB0005282FDB19983257C9577612C88EB33B691 +:107BC0007462507EBFA3309EC1BCA62604EF617DC7 +:107BD00019FB8DBF7B9D752863637E0B6DBAD02B1F +:107BE0002E06EF965B04ECBBDE5D560CF0DF558293 +:107BF0003D8EA23A1FBC7F10E703E56D037B45B3C2 +:107C0000DE80BDCC18833D9EB192F469BF41BEB801 +:107C10006DE0D011F87C982536771AE197117F94A2 +:107C2000A4BB27633DB667B00E8F39D0F166588785 +:107C3000E72DD5E98375787AC778FC11F03649E0ED +:107C4000E1370E3B95070D30CF7EA17968E30367DE +:107C5000DE1384FE4E2F4DE9BB1AFA7B367DD81217 +:107C6000C28B18FFD974CF9CF0F161B9BDF1F9D581 +:107C7000CE639698C71241377731F099C0F5CFF0AF +:107C80007F42598C04DF383691B9F242F0A41B537D +:107C90002578F2D46CA9FDAD33AF93EA2B2CC182C9 +:107CA0001A5B88BFF5F3D14A2014F16975ECC63828 +:107CB00006533CB1E3C28753404EFEB641752A30AD +:107CC000D7393B9FFF7008B43A070B4E04BC9D7335 +:107CD0000100EB3DB749F5FB32913F5CC68A4E8C03 +:107CE000556157D07EFEA1D7CDC3E0D7AA9AD963FC +:107CF000918E73FCA6CF9BC2E679815D34B32C9044 +:107D0000878DF2F36AF6D0776A6F840266772FE880 +:107D1000A75E575F33F22B1687ED8C9F3769EB8494 +:107D2000F1171FCF7C645FD8BA9F76C4267D791D7A +:107D3000FCD28FF5FB59C5F19A0FC00A596943234C +:107D4000D169D921D5892CBA2C5D610AAC73E4269E +:107D50008B3F0A44EBDB6D27CD0EC0D70F5EC723E8 +:107D6000FB4C28FFB58C25E27B27CD4DF07CA8C3CA +:107D700041785AB0E33B3303BA8FDCB190E47A0424 +:107D8000E8B178E09F6023EBB509FAF765C63A9F42 +:107D900087FEEF5A350A848BB1F8D62954CEAB1B37 +:107DA00045FDCD6F9D48F082D618820F46074730BB +:107DB00098C7C12D1DD83298C7613590FB7BECC7A1 +:107DC000124B7AA222F5B6A5B8EE83D1BEFCBB61F8 +:107DD000BC8A3F8F2C47BC2ED8A4B890CF2A5476AB +:107DE0005049C0F946517F15EA7B050BE1F998D25D +:107DF000589F219EEA19837A7540EC6A06B06A069C +:107E00007D11813F0F09FD626AE2F31EDE5A49FDD2 +:107E100069F5871D59B47E0D3675DC609C6E0BAD1F +:107E2000C7D4A45039BAF53A2AAB37551A1D30CE0B +:107E30005B79CF25219EA0BDCD13512F0F8C6711EB +:107E4000F497565A843E9E82FA18FA3D90E5FA025B +:107E5000E572DC9226A315F5A9CD6A7F1EF8605C59 +:107E6000515FC7ACB075A97B6E610EE0234B528B9E +:107E7000C905FD4F81325C7FDFD18EBDF9A64D7FF4 +:107E8000D752A9D925E65CC218F0F9ED763E6F4DC0 +:107E9000AE8E89F6DAFB4185CB876FB3C5FF3CFC1C +:107EA000FE5996E7279C6F70189BFC1AE9D3604631 +:107EB00065EC3F6FFE405F2BD23FCED8C412E07D11 +:107EC00043A6367F2ED7579A7F8B98FF61952D4614 +:107ED000BE387CC30D4117CCABF1BEFEFDD13E6870 +:107EE000E325669AA93F666FB988FC5ABD2BC6B1D7 +:107EF0001AD65701B441B865A7C5BF3E939E332536 +:107F0000094BCB7A05EAABE35A72D1FE94EE8E0AA6 +:107F100020DF36EE8E32A21D7933C79398D9119F98 +:107F2000772F5380BF5D3B2C46E48364872B29B3B6 +:107F3000B0FDF95E498F69F2A8E733CF2A2E7F1E84 +:107F40002187D304DF4E177238CDE88CFF25CCFB98 +:107F50008E7754867A7CFA12A5D7A602D469B1CE60 +:107F60009C3039D4E4CD847CD91FF993F3E5BCD699 +:107F70000E42BE3345BF5C0E2AC040237E2AAEEBC4 +:107F8000E047F95ED09A48ED3479D5E4343DDB53CF +:107F90008AEBAE5806F20DE37896A614A0BC84F8DE +:107FA000C46C477E023E499E15C607CB1A7F342219 +:107FB0009F988A15E2130B94A5617CE46EF353EC51 +:107FC000233AC13CC62DCF34AC66A1FA72E4978E39 +:107FD00057CFEF85A2FD745B20C700FD996AA29C74 +:107FE0004B615EE7921CA4C7163D0000A06091C9DA +:107FF0005D8A7EC6A2DF294ED4BFE87FA0FE19703D +:10800000ACC6EC099BDF2DADBD9903F034B1B51BB7 +:1080100095FD333C93100FD35A27093CF6A69239AD +:108020008A0C389F7BACDCCE9CAFB9FF761CEFBCD2 +:10803000DFE2C4F1182BE2F416F32D74393BFF1282 +:10804000E7F78E893D0BEDCF44795494CB33E9CCDF +:10805000FE384C71C65AA033F47BC6C47C76A0E7C8 +:108060004C803D087760AE0EFD50EE609D6176E578 +:1080700082B12E8365037D17FDE55323A8C239B96C +:10808000C1DE011877EA306EFF9B3798C8FECF6BD0 +:108090007C6F8001EABFCE747566A07BC774F1D493 +:1080A000E07AE64EF0BF6202F8AE875F8F1BE4080D +:1080B000E1B3DE18C831C2FBF580471FCCABFE210F +:1080C000B5DCCFFD9E98CA5E57E6EBB9ADD9841FEB +:1080D000CDDE68FA7BAB37191611D2E357B2431ADB +:1080E0007FCF1772301FE58085DB9B4AF730E4C3F2 +:1080F0003CC599C3C2ED0D97074D4F03BF93DC54A8 +:1081000064A73B97B190DED6DBA3BD6AFDE3836134 +:10811000BDCBB33CEB510F94FCE9BF5EFF18AAE660 +:10812000BDF66219D269D8750A5395ABD1933F9ABF +:10813000484F2EA964A427A10CD793A676FCF43F40 +:10814000645E9B9EFF57C1F7E0DF92DF887A3CBCFC +:10815000BFCFB24AB6219D77652A5CEFFE93E6ADAC +:10816000D7EFBBDAE4F5EAF4FB4BA2FD95F4FB1183 +:10817000D4EF8597EA7306FDA13EFFDBCE1E7ED4C9 +:10818000F79F32D0FF68DF76C4389E17FA9EEC4125 +:1081900074BCFF72FAFEB19C1947103F11F4FD7BCD +:1081A000FF0C7DAFF1975E1EF472A0E7FB310F82EA +:1081B000FF8574DAAA30D4AF217F8B111F1FCCE268 +:1081C0007CACC94D98FF45761EE4C19F9379A95CAC +:1081D0007E5FF3970207C69B05B17D9912E2774D4A +:1081E0005E347ED7DB9139591E35AB302427F35EE0 +:1081F000D3DB81F6F8699B09E357D3BCEFB81D8048 +:1082000032DC0EB4E7EF58B3AE4D0EFEE32AF92987 +:1082100035EB7F9C9F52B322F3535A56C77F9C9FE6 +:108220002E4347B2331A9F8D799BF307CBE6FE3E70 +:10823000F00BCDFBA039DDBF2C13F51ED787637E75 +:10824000663588CF3B443E41E3D711D91E17CE5344 +:10825000A333FAF7E8B75FAD5F3825A986B9E0F92F +:108260001D5086EB0D0BD22F827F3FFC1AE9DC3FBD +:10827000EBEAE83C49D0F99FE8174ECB8AE0173289 +:1082800017B7FF21BA582622DF7C1F303294AFF691 +:10829000E86A5ACBF1AEC12B0246CDBE26A27D05BF +:1082A0007E99FEDFE1978AD2FAF35670FD7CEB8B64 +:1082B0002B8D83001F454CE43F86AE717543FD0254 +:1082C000BF0FA61E293F725815B0EFFA2365308FF5 +:1082D000318FB7D5FBB07E78717C5B3E054309AD2D +:1082E000BD77FD90230FD1BCEB38BE3D4D4677AF37 +:1082F00030B800E0D830B84807AFE3EDD18ED8A948 +:108300001F3F974FE85FE987B0D69F9003D632A210 +:1083100003FA8B9B143BE6436E2DFE9B19E95351E8 +:10832000DA742015D6FBF8FAE195B61EF01CF5209C +:10833000CCF7B9F5156B7C46F17E27CA8FD18FA596 +:108340005E71A940A779458A3F2BF3523C3E9725A1 +:10835000DB33FC31CAEF3373C1B5BD8FF24BEF672E +:10836000D1FB01CB358C7F733173F923E8C957B545 +:10837000761701D6FA07DC4DACE771B8BEFD3621A1 +:108380006F4183613E037C35AE9FB606F365C3192A +:10839000E78FBDEB3D95980F2342EBD67BB9F9FEF5 +:1083A000214B8EEFF0C721BF1FB81CBE5EBEE47D1F +:1083B000C11F5532BFC41BDDFBBE8779C427297698 +:1083C000F46B17B8A31E42FFBDA254E3EFBB2A5DB6 +:1083D000C5B0BE2826E5FF42FC3DAF12F97B01D3B4 +:1083E000DA2F588376C96D686BCFF97D87D2F67E18 +:1083F0001EF00FA5E2E0FD13EBE7AFF1D9881E54A4 +:108400004F70B7CBF07BBD0E2ED6C987E06F924F71 +:10841000D4DB809F9C087AE33F059DBF55D864D488 +:108420007BC112EEEF05B378D9259BFB77866CDE16 +:108430002E3A5BD0393A0C0F69213AC34F00E388DA +:10844000B075139E6E49D2D6FD70E55858573081ED +:10845000F552804F92B21F58B33C8C4F3A653F5C47 +:10846000897808F5F7E011D4FBB7083C75C97EE8B8 +:10847000888FEB3305E56E3E3104F0C126C5A7C2F7 +:108480003AE7231F4458E7E94BE5C6A77BDF65BA07 +:10849000CCFB5F5FCA872EDDFBCC94742DEF0B3ACB +:1084A0008DD5D1B15C47C7321D3C5583FD923ED37B +:1084B000F4DCF486352B3A2561BE51413381FADA7A +:1084C000ACF465ACCF734F56DA0621BF3A4CA9A085 +:1084D000F3FB3FB7F6881578B912F519F1EFEFD62F +:1084E000B8801F27A2BC13FC54A5AB0FF24FCD8A56 +:1084F00064683FE8B9DFAFB142D35B97AF31A14FBA +:1085000033F4B9A7D718817EB714FCF900F667AC2D +:10851000FDB72363332FC3AF75BA75ACD3C13E5DCE +:10852000FB27AEA0DF97EBDE5FA2AB7F4807AFD59E +:10853000C1ABE4F7A7CD54484EA601FD1071579288 +:108540009B89D96D79A4367BA6D8C84F92F87ECC8A +:10855000320EDFF6DCCB95ABF2C3E0EC3F5786F38F +:10856000B189F19F2949CC87F6C3D48E3E1B93DD98 +:108570000E1FE5E9ED1DAFFF0C7F4DA17D16C92E45 +:10858000EF5565B851D5E6BDF3C83D367CA8C13B73 +:108590002AD11F6F77DF83BD5189FB1E631E15B083 +:1085A0006F5B25EA3D6D9D5AFB113FFDACE278778C +:1085B000676FABDC80FB2A25811CCCD74F4DE025B3 +:1085C000D81915ED58B5C8778CD8A9BAD1CE4C8D2D +:1085D0000EE42CCA0F5B27ABCFC57536DEA7127D24 +:1085E0007CCB783C329D39CD98AF688C8F5FFC0294 +:1085F000B4DF7B9FBA18EDDAA78B133BE1FCF7657C +:1086000073BF6D6F7CD74E7702DC18738719F3B593 +:108610008DF70FA7728FEA5AD9027CBCE6B9836442 +:10862000E71B63E2093F0F67EFABAC05B9A8CB7658 +:10863000D0FB9E047BA706F457579B18E6ABC1916D +:108640007A86F8E6614BDFD5308F69B5D7D1FED198 +:10865000F47FAD1C9102EDA6AF30D1BE02FCF4C692 +:10866000797B560F3763FDCCE5A2F48DA472F7DF5A +:108670005F7FBB37B46F794075AE87C6BB5AB3E234 +:10868000A6C3BC4E45713DFC7973B7389C678F6EAD +:108690009E75D9C8AF71B1D10A1A0FBB236E02F40F +:1086A0009B9BE37A3ABB63A8FDEEBFABB40FB6BDAC +:1086B000797A27CC3FFD41E8EF5DADD33B4D0FB359 +:1086C000F7B3BE35129E779B1DF7A07FB93B3A5D8D +:1086D000C1BC0CE03911F3B633857F0DFCB2F8F55F +:1086E0000876FF896C95F072DAB2989D02266E7C4E +:1086F000B06331CE537B4FDB7F33A539FA85FBD195 +:108700001BBA96BC8EEB08F1D96747906FC88F06ED +:1087100078D7739FACF1A12DDC0BFE3FCE23C9357A +:1087200002EBD99244BE0F9A5C9F1B9E8F08F9A959 +:108730004B853EE0ED4EF862296E3DF152941FE309 +:108740009913BE4F62C3F3EF9A9CCC8E8BF5A13187 +:10875000FE2A36D68878FDD4E8FDF257B86FF8B413 +:1087600089F4E8ACA73B2E69417D00F4C47C907E7F +:10877000DCE46E261AB7FDFDC1E6CAB2B430396139 +:10878000CD95AEFCF6E5E4D873DF546EB0B52F2777 +:10879000B385DF3EE269931BF97C7661AC11F7E9A2 +:1087A0004A9EDEFF3CF2E3EC8551FD2C30F1D94FBF +:1087B0005B88BE4DB1B13E3BEE23C6C51A3B40F9C6 +:1087C000ADD0234DB55114A7A89DCCA4F7D4958561 +:1087D0000EC44FA9CA8C56B02B6A9CD3E1E6F07246 +:1087E000CC1BAE882D72207D3B76E3F2D0561F3F26 +:1087F00079B4D23BB46F7676F1E34F0E84F97DCD38 +:10880000FC930666FEF7F7D1AA993B1EF38FFF5340 +:10881000FB68E66EFA7DB4FCF89B91FD16AB346FF5 +:108820007569941FF1A966703B319229B48FC6EC2B +:10883000B0FE5EA17D34F5D7FD093FA7BDC057DD71 +:10884000012F71566AAFFE5AF55B60DCD2449E6F11 +:10885000559FAC64B8AF0678F5D9011E995443FB17 +:108860006B4B859E99A630773DC9BF3303E3E4592E +:108870004F47111D673F33E7C3DF1520DD2A92C242 +:10888000E52953F01FF4C7AC09A17EBEAAFD4D0631 +:10889000CEA7F4DF20BEC4B853F53C790BE9CD1860 +:1088A000DA6F63F6A6870722BFD4C6F4C53CF9EC9D +:1088B000A75332B2F243EFCF5E7A5F2E7F1FE2D62C +:1088C00038D45B51B49E799B2CC42FD31E505D6469 +:1088D00027D3CD64273F5F1E45F0BCB42292B76911 +:1088E00006BEFF063E6132E9778E7236CFC65CAFB8 +:1088F000DB50DF3F1454397D7C826E66A44F71B724 +:108900004492CB3B10C760BFA622BF75A4FE781E61 +:108910006A9742FB4D8CD538500F4C3528A4EFF4A4 +:108920007259D18DFBAFD3329CB7E37BF31FB138C3 +:108930009766F239A8DA7C206E9A6F08CEC27D481D +:10894000B6C542F98D6A5847541C3FF7F01ACCBFA0 +:10895000DAC88C66CC4F39B85ED3E653EDA81C89D3 +:10896000FC0AF5C78C503F3F96EBE5F91D78DE8792 +:10897000C55AFDCF878F8773CEE6EF39E250DE060A +:1089800011BFA0FC1BA0FE6F8CD797C615399AF2B9 +:1089900069FF7E15E64B703E3D7A878D0B704A6FFE +:1089A000E4C785C6AC58A443E2A4C938DECB2AE9A3 +:1089B0002710AA478AD00F7C59ED8FF1ECB407F647 +:1089C0008E588BF0AB7DED388569AFBC4F76EA2EC3 +:1089D000C1674DE8FFA3DD02F85528EFEDC6F5832A +:1089E00047E5F99C7BBB29D2BE9F563FFF0113D1BF +:1089F00063FE0ACE0FF36BFF42FDCE8F0D76427AF7 +:108A0000CCDF6C1A807CFD2F62DED36BD38B8F01A1 +:108A10007F4C37C5DB157834CF576146785E9D4271 +:108A2000B036DEFC073EE864C8E7FD6169117C14DE +:108A3000EAB76306DAB56F5E4ACC981646F76F96CA +:108A40006F8DC37DED5351811C3BE663164639D7CC +:108A5000939C727A7CB33C673DE66B66DA83B1B86F +:108A60001F3EF39EEC04B4779FDA0366ACFFB43E7E +:108A7000D380B0CB6E2F46D865EC43F037E29C0A2A +:108A8000FD009D16289C6FE6BDB4D79C05E33D27ED +:108A9000F8ECDB97DFCFC5BCC1FC8C602EDA61E05F +:108AA000ABDC54A4CB1F15F21716BCA4BAA27A876C +:108AB000F86A01F215C8FF5CC1570B366DFD25CA77 +:108AC000E902E4A77E97F225C497FBE8F96BCF8E05 +:108AD00060FCFD7DC8779ADD0778B909F36B660104 +:108AE000C338086F10FA1AEACB78BD2F9FEC096BD8 +:108AF00032A35F5CAD727F01E42919FD89EA069318 +:108B0000AF294C3F2EC0FAFC507D7B7CB3BF9BD875 +:108B10002FABB5905DDA2FF0D2F4C0E638E48B6F5E +:108B20005FDE7B6030C659AF2976D4FB97C8A1C001 +:108B30005B35E2298ED649FE5135E2252E84A736D3 +:108B400079137C51CD381E34BC541B059EB47AF188 +:108B5000FE01C187F398C0EBA6EE5CDE857C03C7FF +:108B6000901DD1D6E74990CF0FFC20F8FEA858E71A +:108B70003CE01B673EF197CB3C40C4FF50F5EDABAA +:108B8000CF52FE48A3A736EFF81C87A6A75D1D129B +:108B900042746E32B0AA48F9EAAF85DC996C5CAFDA +:108BA0009CAC4DBD7D31E06FEE4BAA939087B157E1 +:108BB000D8B81643532CF9A7BF56EDB8AED23F55DF +:108BC0008EC6756B7C67DAA8181B709F907520FCA9 +:108BD0006BF32BEDEC1EDD81F35D00E7A3CDF3A479 +:108BE00012207AF95E55ECDCDF6D32631E5193532F +:108BF000FD7C7F10F355E394C14A1F9C8FD381F213 +:108C0000CDC00ED27C6CC7EEA3F17C27EECBEC1D61 +:108C10001AE7535FAC11DB7DCAB81ED0F8F2A4C8C6 +:108C20004B9C5CB195FC616D9CD81CCE5761E37880 +:108C300016275D3A8ED6DE94C3E7A5C9C5C104CE1A +:108C4000FFA5CBFF42ED343D8B3F988FD3F0A9E1D8 +:108C50002D4C2E25FC68F2A5C99346D77F54AED87B +:108C6000928EE4B7DE2FD64D32D2296417903FD1D1 +:108C7000DE59CCFC1C5C98DD24BF6664DA77664F55 +:108C800084E71A9EF4CF4371953D03F13FD2964C91 +:108C9000FBE56C79F2BE6E61FED929CC7BA13E7DED +:108CA00051F5933E65209561F65CF3DB6A178EB44F +:108CB0000F43FE7A49A173479AFD869F87DAF8141D +:108CC000FAAB2A58988BFEC4EA9C2C1ABF3AC97595 +:108CD00016DF9F77263822CE118A5F869E0FA8F175 +:108CE000981FDC9429C50FF39AF7919CCF67C19523 +:108CF00018EF4E7BE0FD8A8148FF174D747E616658 +:108D00005D26D9BFB31B66F4C7D076DA8A1C82E72A +:108D10003C7F27871FE07EDDB415852F607EFE54E3 +:108D2000946B04F279CB1AC58EF1D790E70B97DCE0 +:108D30000AF54362BB76C0F99ED870AA6230C611AC +:108D40008B55921BD786C72761BDAB4175E2126771 +:108D500032FB925B91CF8DF12477DAB9C66526CECE +:108D60006F77E670BD715B0ED71BB709FE2D5DB640 +:108D70002C17CF15B43C0B760AF7D7CD8EFA00C668 +:108D8000813B3B3BD7C338D510B626033F9D51B836 +:108D90003F5E656656E4AF43A6E0BD38FF43F7C6C5 +:108DA000F6ADC509A81707A07CB844DC0571148D81 +:108DB000ABE14B1B7FA61857EB477BEF20FA5568BA +:108DC00047C47CCF2E7F7112FA0B6737E624B03090 +:108DD000BC9FC57501BEE7807E7C2D423CB8304704 +:108DE000CB4FF8A9AC1279C443A6BA34DCCF05BF87 +:108DF000FE74B87FFED5B35156E44BF0EBE5E726A1 +:108E00006E57C09F979E83FC48705BBCA74E8DF742 +:108E100044D0475AA9F7F797E7D822FAFB9AFC5DA6 +:108E2000A2D7847FDF9677E9766DE7BA9ABD4018BE +:108E300010886274CEE0FDB2989F5EC7F397B3EAE4 +:108E40002C760BE0F734CA17EE0B6E56B9BF68E507 +:108E5000F2767A675F3FE615661D67CE00C0B38E77 +:108E6000AA4E07B4DFB7E67E3ADF71E73A8575565A +:108E7000C2E2AE27D64C42713BE7F4AC4C81F6E738 +:108E800036F2F328506DD3C55B07521CEDC75BFF6C +:108E9000AC384BCB3FE9F1BF2907E2AD18F8C5C9A3 +:108EA0009C32FE79DCBE1BD8A8A8DFA5F86FF67A45 +:108EB00028AEFAABB78ACA41F5CF96A6C23AFEA64B +:108EC0009C7C6408CA516C3CE54F9ABD35B439F8B6 +:108ED000D786FE17C7019EB6DBE2EDA83FFEEA5D2E +:108EE0004CCFDBF846F0E9D04D8D6A2AA3F63B86DD +:108EF00040FB5DB678DCEE88B00FC7E9AC3F7F730E +:108F0000F7C2819DF1B9B6DEAF7FC5E9DD66C7372F +:108F1000CE88437FB5F1F7893B06219D63E2EDC81A +:108F20000AB3C5399C2FD7727D74C61AFF02E65169 +:108F3000CFAC9BD809E3C33B4D2D6627F4EBDC593E +:108F40001987F9822F8C4D71762CA17D00E761F491 +:108F5000ABA807079733DA1F1C1C303247266DDD9C +:108F600013FF0C6A36FA316EFE06F70DD18E5F8C58 +:108F7000E6FBF7623FF0CE6D3CCFD6965711F985F0 +:108F80002162BD1D7213B47D207A5E5AC49F7FB5E5 +:108F9000EEF571D8DFD90D263BCEF7AF1B4CD4FFD1 +:108FA0005C88EF0DC08F6736F2F3027377409C9CAC +:108FB000897A4421FE9D0BFC6B45FE5B687299E348 +:108FC0002FE5CBD28D3CBE9E5BAF50BCADF1E75CD4 +:108FD000977F04E15DF0A915FEFD0CA6A303AB5F2E +:108FE00089F8688F5FFFD17C803537723E40CF0FA4 +:108FF0001ADE34BE08F12923FED4E89F50DF7758EB +:109000002ABDE0237CFA4A581EFA0BCBCC2C0FCF9A +:1090100043F90CD14E94FB1FA2E27A631E6AB1950C +:1090200097BF8C8E5B8FE50F51197E9CF70F06FB67 +:109030007E8CB3BCB999C4B7BF541D26057E9D98DC +:10904000D4544666A0D4E032A01D5C66213DA2D770 +:109050004339B9220F98CBA81C96CBCF899B580DCA +:10906000F9175A09FE403AFA2F95310917F0287975 +:10907000BF173A4FC4FDDECA2109F76683E739F806 +:1090800085F48946E0F3CAFE099BB3002ECE4DE37A +:10909000709F844213C0B5B51913CBA0FD2DB92E16 +:1090A000676ED8385ABFF0BC3F3E1F99E219908BCB +:1090B000F6DF6C5B8576E06F4ACB02831A6A7F44E9 +:1090C000619F6E574270938965A0BF3DAC6DFE9164 +:1090D000CB55B9AE1B72233C9FCED80ACC4B4CF774 +:1090E000BD794C217DC6DC56A0E778C17FD3ADB6F3 +:1090F00000E9B955A6E636FEC8423D156F44BA8F61 +:1091000013641F6F0C34E2FB3DD872FB9756721547 +:10911000D7FD9CD8BEFE0741655F6AFDC1FAFE66B9 +:1091200082F5025D1517D01A444C01244F057DA726 +:10913000EC78F347EC77998F3545111DA6DA910F3E +:1091400015E631FC0CE5FC18E08B3E58023F40BBB5 +:10915000459BBFDD87623147F3B33C45E42FDE63B7 +:10916000E7EB619EC1C4AFF70A7EFDCACB6A3055FA +:10917000343E188CC3A3B0CDE302B9A81FCA554F23 +:1091800015D2E1AB75CBD21601FF7CFB9AC539161F +:10919000DA9FF1BF1E8776759EF0F7D945357003CB +:1091A000D41FCCECB17E75187F2DCCE576BF39335A +:1091B00090711FEA994C1EAFB28B7B33EE83F6E5BC +:1091C00059A30A5713165C77E786ED4F8E33463E58 +:1091D000BF31298DFBEB6C03B7C71623F3C52650AF +:1091E000C9E2004FA3602E45782E156095F6F3FD79 +:1091F000D41EDBC5A15FE39891CCF77B981BF59655 +:10920000465F8D6E97D013A68C7EBDC1CA4CB8DE6A +:109210001E6C9D1DED9346D7AF843C7E65E572388C +:109220005CB5919E5AB499E7F516295CDF2EDAA950 +:10923000F0FCE625F676F34AD4C955EB66903ED3AA +:10924000F49803FE217FCDB5BBE3038E7FC0EEAE65 +:109250002BBD2A7DB65ED3677D595FE4BF2BF94BEA +:109260009A1E03F2BC98DBF11AE885288375CF16A5 +:10927000731CAE4E7518112F1DAD4ED4E78B9ECECC +:10928000263BC92EAE65E1EDD8BA44E2DF95992AB6 +:10929000D1B5A2219539E0D19C0685CEC98E6D4805 +:1092A0002438AE3585E08A3F742EC175B7ED83FE54 +:1092B000A13BC1675F78BBC0C3F33456ECDFCDB4CC +:1092C00079E4D7A3FD39678379009EDDB65594779D +:1092D00074B3B67848F9594118B806E5CE65F2710D +:1092E000FA586B49FEC5BA1609B95A7488DBEB45C2 +:1092F000C3F87EA1D1D7231EE96F3AA8323FC03709 +:109300001D520B03D07499D0E79664037384D12D5A +:10931000CA11CD1C61F4613E5710E3ADC9825FEE06 +:109320008FE27A3F262F416A37D9368BF82798315A +:10933000E220AE37D6D945EA9779B87FACF1D5248B +:1093400091371FC75A96A39DBC6932D487F5672A07 +:10935000FE8EEC86A958F6AB012FA72FC74FCD1A6A +:109360003FF5603D889F74F801F9207B7FEE28BFB0 +:109370007F025EC96F8B019E74D0C4FC50BF42E077 +:1093800005FD568C7FCEB962496E34BE0BA2DD035B +:109390003D175F24E3AD834BC65B62B98C9F8E6E35 +:1093A000191F9D276749F5299E9E527D6A553F09E1 +:1093B0004EAF192CB5EFBAB84482337DA3A5F6D9C8 +:1093C000AB2648704EDDAD52FBEE6BA74BF53DFC76 +:1093D00073A5FAEB362E92E05EF5BF96DAF7695880 +:1093E0002AD5F70DAC96EAFB1F7C4C820B834F49C4 +:1093F000ED071E5B2FD50F6AFAA3543FE4CC6B1226 +:109400003CB4E50DA9FD0DAD7B2478187B5B6A5F4C +:109410006A7D5F8287DB3F91DA8F4C3E25D58F7264 +:109420007C23D58FC9FB5E8257083FA7C2F95FD264 +:109430007B4188D8908F73D23C43BB53DEE78C11BD +:10944000E5EFD86D0A4BC4F8E7E0443BC9FD35C6EB +:1094500081C3BB8B3844F0F10566BB1DCFB35F49B8 +:109460002F66A33F51887C3E96EE559DABE7F90EE3 +:10947000BD5DD7FCB97830CBC6B0713BB8AC10D06D +:1094800087E0C472BB047774274BED3B4F7648F5F9 +:10949000299E3CA93EB5CA29C1E9354552FBAE8B90 +:1094A0005D129CE92B97DA67AF724B704EDD64A9B1 +:1094B0007DF7B51EA9BE87BF4AAABF6E638D04F7AC +:1094C000AA5F2CB5EFD3E093EAFB065649F5FD0FF2 +:1094D000D649706170ADD47EE031BF543FA869A316 +:1094E000543FE44CBD040F6D6990DADFD01A90E070 +:1094F00061EC90D4BED47A448287DB3F92DA8F4C01 +:109500003E29D58F729C95EAE77DE30CD0BED476D8 +:109510007EDF55F3E7C6E47D27B5332581BF8FF99C +:109520006F16EDC4F3FEEDF9F99A1F58E1FC511ADC +:10953000F70703F7CF5FEA9E25FC7FEE272EF3B9EE +:10954000E97C5E021E78053989F729C47F18624DCF +:10955000A57C6412ED5B90C974E07937F083004814 +:10956000306466621C1213F263D37EEE7FF57EECEC +:109570001B10E3A05F7DB6BBE7CF289773EB5F1DA1 +:109580008171CE1CE65B89F300BB1B8FFB58EF4655 +:10959000C9F928AD1C65053C868D7728AA2EADDF5C +:1095A00065E47794B599DAB7F52BF2550AAC6F51AB +:1095B00058FF8F40FC650439ADF3829C41A0FD98B3 +:1095C000D74EF013DE64829FF43AA85CEBCDA3F291 +:1095D00029AF93EAD7798B087EC6EB22D8EF2DA767 +:1095E00072BDD74DCF37782713FC82D743E5466F3E +:1095F00015957FF4D650FD4BDEC504BFE2F55159F9 +:10960000EF5D45CF5FF3D611BCC9BB96E02D5E3F41 +:10961000950DDE8D54BEE1ADA7FA1DDE0682777989 +:10962000030407BC0709DEE30D12BCCF7B8CE0030B +:10963000DE262A0F7ACF50F996B785EADFF1B61207 +:10964000DC2CF613BEEAAE48F7183598B132E207C3 +:10965000CDFF1D87710F324791E9AF52DCA38B3FDD +:10966000F4F4F85A8C632A01F717FD9F2EB9EB9793 +:1096700085C505DF8BF1EE8F66BE2890875A03CF34 +:109680000BD42630BA1FC6847F3E5BF0254BE27EAA +:10969000F92C31AFD9420E0A913FF3883FDFB996DA +:1096A000384B8BB7ED191E350FF933DDE0A3BC83C2 +:1096B0008DDFC3EF9FE131E7811C9DABB9F3008DD6 +:1096C0006777E6E220159640C79B319F7448A53C1A +:1096D0006C7BE3558B7B12EDD6EF3A9B86F6A8FCAC +:1096E000EF2AE5EBDF35C54EC67C4B721EC74B72C9 +:1096F0009E412A7764B83BE33CBFCAA979E16E2555 +:1097000074FF7F3C86E620E795CC61A273B8CCB5A8 +:109710001FAFDEDC040E1FC237331F9525E91E077D +:10972000BE7F0B0418087B065B3222AD473F9F9E2D +:1097300079DC7FEF996790CA8F32DC3D103FA773C9 +:109740005CD27CE2BA3AC47D9C9667705EFFB1F34E +:10975000BB2F95EC10BEB5FCC6CA61E29CD6424553 +:10976000DB07E77EA295697E22D54FBD97E77B3464 +:109770007B79BCADE4FAF05C8D89F4E65425DA8996 +:10978000FEF6B99A7BFBE07EE16D10EFE1FEA9A643 +:1097900047A7026C00782AE3E72EA61E8F253ED34A +:1097A000EB57788FE17EDF54F03F317E54BAF27C84 +:1097B000CABBEEEF4CD82F4B6AA17BABC037A3716D +:1097C000FD7307A9F4FD86770DFE5C45257E312BE0 +:1097D00030FFD949C02F11FC058D2F16887B39DA4F +:1097E00073E0B71B913E7FDD36308FF669760D72E0 +:1097F000203E9719F8BD3ADF5B2A3F9781A97C3C50 +:1098000037129FFF2CDD2F40E702E9372896EE172D +:1098100034AA6CF1AB11F4E9BD828EEF269BCAFD30 +:10982000D4AFBCAFB840D075816857B1E7503ADECD +:109830001B5C70D04471112B68CA7747385755BDEF +:10984000F8C15F740BE3F3EA8693FC3C166BCA0F16 +:109850003F87F5B0E06B8DBF5473ACE7595BF8FC04 +:10986000F8F8C0E7F7083EFF12FDFE711647FCCD81 +:10987000F06A13A02600A5E7DFEC749E4F3BD737B4 +:1098800093B9A99C0DE446BE76FBD6D0BDFAB9AC1F +:109890009E9E2F289A918170356B294B86FE6E5AB9 +:1098A00055BB3F196637B16ECD70CC734FF04FDBAF +:1098B0008F65E506E54B9F83E464058EDFA4D4AC99 +:1098C000E802E3DDFAD2B01598471EA7723AB0B7A6 +:1098D000391D809F5C6AC2A5EB03B97848C805CDE5 +:1098E0005F938BA94B994B490ADD03699393A2BB04 +:1098F0003E4BC53D16630B9D43A9DE6549C0FCC9BF +:109900005CC6ED76280FC4EDB526075F9B38DDBF3A +:109910007E59A17B365F2B8CBEE7D09EDFA0F99FDE +:10992000207F5CEE3E8DE1FCAF8ABC5E8627B95F8E +:1099300076C83E7F6DF00F88CB26FBBD11D7632A1A +:10994000F13CD417CFEBBDA23897C15CBEEEE0CF9F +:10995000E0E704DAEC00FB392694277CC4C4F376F4 +:109960007A7F575B477BF3B498990FF7B394A203C0 +:109970003FA21F72E97C3DC903002FCB904498970A +:109980002C713B22CD63B918FFE04F3C1EF7A53385 +:109990003A17A4C7A762E7E3B4975FB544F3F96841 +:1099A000764A9BE7A5F3E2F47A3F2F93E8AACD0F1E +:1099B00034459E1DC6371AA39D28AF9546CF7B8898 +:1099C0004F2DFFA6C5C50733BF227BC02E2E4BE30C +:1099D000E78F03EDD9E1E6B6783C2B6427B53C165A +:1099E0002B8E9C8F745BEDA4BF263027D98B1EEC89 +:1099F000B8862FCA63A9B84348795E0FADC382FA0F +:109A00001ACA28CCA390BDF4937CC6E0BC685D4123 +:109A1000CC88B03531718487C1C718E9E9C1B8066F +:109A200058EFCE93CC8FE7A91A2F4C2A8D85FA9D3B +:109A3000DF1A290EFA6DCC2BA9F81D899D673F4CC2 +:109A4000C57C4FED852D040F681E7196E7CF8E4FB4 +:109A5000C1FEB69F373B2CE4072C243C6879CAED45 +:109A60008C39711FB4E8231BDD332E3C5A1F437819 +:109A70001379B562B1EEE2F33C1FB20B81411007DE +:109A8000B4985920CC5F36D965B88885C1993824F7 +:109A9000C061798E6B8D1F637B883CC84036303C3B +:109AA000AFC65A1322DEA7D2EF2316287CDE67F258 +:109AB000DC9D7A50FE6C82CAF1FD7715F17583CD7D +:109AC0009F82FE6DE39C1752D0DFFD6DCCDF098FC6 +:109AD0004FFD644E41BCD60DFB0FB22375F06E10E6 +:109AE000E35FA33F8A51FE6B3EE5D76E1076F6A981 +:109AF0008B9FB364C0675D1123FBC9841DD6EAEB5D +:109B00002E9EAB427A5E28B63A502FE48A7C68EDEE +:109B1000F5FF99DC14868F9DE0570780C0DBC1AF4D +:109B20000E80EFBF0DFC6A84F1DE29969BC1AFC6A3 +:109B3000D20F7E3596CF805F8DEDD0AFC6F229F083 +:109B4000ABB15C0B7E35964F825F8DED9E00BF1AE8 +:109B5000CBC7C0AFC6E77517A797D27C8E31BA5F67 +:109B6000BF3426CE80FA15E61F8D79A1C3AE7ED113 +:109B7000888FEBCF1B24FA1637474BF0E0D309212F +:109B8000FA22FD8F7791EA071CCD92EA337D3D25BD +:109B9000B8EBE27E128CF9A1F0F753AB4A2438C53A +:109BA000335A6ADF79F20409EEE8BE556A9F583EDF +:109BB0005DAA7F344E4747FF3C834C47FE7D850BB3 +:109BC000C5363A5FD91E9F3E26E8A2C18FFF4A9D47 +:109BD0001C296F7B570F83140F741173BBBB8783D2 +:109BE0009EEF3B31F0C5DC02A487816F9BBA5A62BD +:109BF000BA015D721F37303C5748270E607E76F100 +:109C0000DEE325E762902FF75698A3903EBB5D25D3 +:109C1000D1082FAD30A784F3515DA6A71FDD53F007 +:109C2000F0F569EF3F5A32E1B2FBE88F21FF75BFD3 +:109C30004CFDE8B959280F97E09155D17E6D088FFA +:109C400013E8FB4ECC5325CD5F2F170C37E953702B +:109C50005CAB8C4F57D6038887A79E30D239ACB601 +:109C6000FEC4FB5A7FC3D58B314DF997CE7FB78B9E +:109C7000B707FF370AF1026349F34B703A86217E3A +:109C80007E27E4ED5F85BCFD56D015E35884999D91 +:109C9000BFA7D1ADAEEAB151B92837457C5EEB6FB5 +:109CA0007C4C417593C89CB5F630BC3E21E6F18CE6 +:109CB00058D73AEC17E08E37BA14C45FC662B78241 +:109CC000F2D6754913C14F09F94EAB69A1E7E9F71F +:109CD00004A8EC5215A4FAE1EA4BB48E363C386580 +:109CE0003CEAE9E417EBD1FA0DBDFFDA21E4B70B4A +:109CF0002E3EFF389FCD85F622CE6777F2D2214ADD +:109D0000A713F57E9CCF25E09A7C84B78975C5F9A9 +:109D10007C04FBC5BAEAAA920EBDE0088DC71CD52B +:109D200086707BD31E3F6D15F8DF2CF0A47F6F9BF0 +:109D3000A9A6BF3D825C69A5664F8B8E1B747A27EE +:109D40005A92FB43F80BB7037FE981F2E873AB62E9 +:109D5000FF8AF038B12D5E9A4AFCB426E6F6B73198 +:109D6000DEBEF1A8CAB8BD1DB71FF5E5FBA32C6484 +:109D70004F1B478D4C0FE7BB06B18EAD02EF837CC6 +:109D8000AE13F740FB316E0BE5E3073257FABDD057 +:109D9000DFE8B1AA3300FD1D6DB327EE187EDE812A +:109DA000DB9309620D7BC64E7C10C77FFF28E80558 +:109DB00047689E5AFDE6F289637A211D839C8EEDE9 +:109DC000E1E74D41AFFD625E7B05BD1A057FEF16F1 +:109DD000F664A7B027DBD19E5890CE45623DDC9E4D +:109DE0006C16F62488F604CA77853D7907ED099448 +:109DF00005A3B2CB486FE22536B22710A0D07982F6 +:109E000005D2BAB47995A7A912BD4624C548F42A4B +:109E1000B3254AF525C65409765DCC92E0EBCFF721 +:109E2000D4D929D9AE0C3E3D5867A74A2478C0D171 +:109E3000D1D2FB95AE8952FDF8A229527D85738659 +:109E400054CFC47E18DFA283327A9D4A71AED87790 +:109E5000D2FCA9F7CB55DAB719F481EA0C97DB42AB +:109E6000D6B64F66C07D32705F1C46ADBF2CA99E32 +:109E7000FCA8A326772A9EDFABAD043E84B2F82867 +:109E8000F869947C04BE06BFB7D03D92FC40F097C1 +:109E9000FA131D5AF87E93B66F3548B7FF343A5F10 +:109EA000DE9F2ABCC2FE94AB673B7E59B7C4ABF2BF +:109EB000CB40BEC8FFFA6DCCED7B916FB67D047EC2 +:109EC0002AFAB91FFD82FC2FCD6FDBFAC52FC8BF60 +:109ED000DDDA262F1E495E0A85DC6E399AD5D0045C +:109EE000F2B63959710A5493BC1469F2D224F4665B +:109EF00079353D1F20DEDB6A72C7A0FFB7F9D85263 +:109F0000D16F981E217F3D4C8F601CC912E4FAE48A +:109F1000D4507D162756787BC67AEAFAEBA78307DA +:109F2000EBDA97E8E0D1BAF61374F0ADBAF6D3A540 +:109F3000FA0658F7E5FCEDCD423F68ED0A8D6ED587 +:109F40001941DF0E382AEB57E6AE96CE3D349E9887 +:109F5000457A73CBF195028F55127DF668E31C05A7 +:109F60003CE75FFA7E89D117D31BF8A0E498D1595A +:109F7000EB08D14FA313C37838ACBF52AB2AC95FEB +:109F8000C3314EDFF6D6B94BE8E71DC2CEBCA1F314 +:109F9000DFD49FCEBF3F1EF8674B9381E2AB2D47C6 +:109FA0002724627FBB2FCEA4F9361C33D03DB217D5 +:109FB0007B8EBFA9B65B687EDA7C0A3F581A83FBAA +:109FC000AC179A0CA4FF0A4DEE447B04BCEBF9AB32 +:109FD000BD7E35BE05072A11F1B21BEC109D1B1684 +:109FE000FA54C3CB9E134F12DEB71D5B948878BF23 +:109FF000A1D520E165688BECAF0F399320C1034FE9 +:10A00000727F10ECAE84DF2BCD5B2F17B83322C3E9 +:10A010005DE4F657E90F6C1774DA26E8B43DCA39E7 +:10A0200039D2BEC6B64FCD55E1DF5538D393E7DB05 +:10A03000CEF4E4F9AFCD4047D4B3174E1B48CF0E52 +:10A04000B1D7AB3511E851DC6CD0D909D96FB8D68E +:10A0500078F5543B7AB1BDF735BD58A27D3F2578E0 +:10A0600063C4F3B1213A8873953A7C6A7EF495E92A +:10A07000A69D47D7D1AF9DF743FDF8F4F134BB0E51 +:10A08000FB69AA247BB326E65DA1CFDF257DFEDE3A +:10A090008F429FFFD889FCA423A33AA7A31C1D6964 +:10A0A000D3E32C365C8F6BE72183CDEFC584FBF9BE +:10A0B0006EC18F3B5DEF8FE983F4ECA6FEAFFA3BF8 +:10A0C000EF0A7FE71DF477BAE33E10F7770EB96623 +:10A0D000707F2759A1EFC52C8DB9DEE889C0A7FF95 +:10A0E000D7FD9CF145B29F53E194FD1C6DFF60B715 +:10A0F0005DA1735863F264BF6737FE827926ABE2D5 +:10A10000C77B5CDB5D132FAB870342BE0F09FABC34 +:10A1100029F4F07E1137EC40FC135DCA055D78BE72 +:10A12000A2F8BCD3E674207DAA785C96574DF1F472 +:10A1300050CDBE7B6BA8FD910BD3CFE3FDFEDDF6CA +:10A1400018CAB3ECC6F9C0128E983CE7F1FB15BBF8 +:10A150005D8A636984B87E488BAC07343F41E3CBAA +:10A16000DDCD9F135FEE6ABDBC3DD5F497D6EE4DB5 +:10A17000F67A29E2E7FA66C6306EB892FED1DBC500 +:10A180002B8DA36F3FC458AF46B23BFA71DCAD01D3 +:10A1900015CF3FEF6C0926E2769D3B7048C57BE00A +:10A1A000C52D019AEF3E97625733A95D299E8B7E9C +:10A1B000F3E27B63F0F9AEF3468385F699EC24B7BE +:10A1C000C5423EDFB968B03909BF2AED73045A3E73 +:10A1D0007F10E5D56755E9BEC8EE8BFD92C2F1F65A +:10A1E000E8752AE993ED651603E697B79F378AF37A +:10A1F000D601F21F76B466D9B0DCEE02F9217D11EA +:10A2000024FCFFFE3A7E4E7527F4C7F58483E6A151 +:10A21000F141E0BCA13CD2F7767E2FC61B72F1B3B0 +:10A2200018C4CF81F37B62505FED6AE1E30C59D231 +:10A23000148371E6DBAD86589E57E99F84CF1B8758 +:10A24000DF6FEB87EB6A31F0FD1BE1D768E3ED2EA2 +:10A250009B4DF9FCDD2D3C0EDB7D9EE78FB6FBF9B7 +:10A26000B93526F498D67EFBF909637A61FEC06F92 +:10A27000A2F643987F651CB4DBDF71EB7574BEC634 +:10A28000378F85EBBD52BBECE794B4E8EC93671EC7 +:10A29000C981468723DF4DB8B192CED7733D39CA05 +:10A2A00028EB975DE797264DC0F16D7C7CE6E7EFE4 +:10A2B0006BF119FE18C3BEBB523BFCE68915D8DF13 +:10A2C000667ECE6C884DD6674786CDF8FD7C3CFF18 +:10A2D000BF2986ECEC765C3FF67F9451FE6C77F9F3 +:10A2E000E3A57198B76E664EEEC7C97ABDF4C2A6F3 +:10A2F000BD71D0FEBD0D0AE177649EBCDE9DAEEC63 +:10A3000087310EBED0CCF1ABE59334B9DCD39C7071 +:10A310001BE9A732781BF0F85EF9EB94C79EE39730 +:10A32000FB19B831469AF7FCA6045DFC26E7C7C1C5 +:10A33000DFD4F203B68A01A1F8ADB095E7D707FEE6 +:10A3400034A17F00E65B5CC6CFCFEBF3E2A38C16B3 +:10A35000D9CFD2E5C50BF57971BD3D17FED800B157 +:10A36000AF7189FF23EC9C966FD8660A4C715F83AE +:10A37000FF30C808A10B9DEBF5241600FEDF10FE90 +:10A38000E52073DDDD29202A5B55DF1016E6173046 +:10A39000BB8F250D08C5B7834FCBF140D171992FE5 +:10A3A000217EFC12E3C955B8A74972E0E379D0AB2E +:10A3B000F433D6C4F46E6802BA0E3CCAC47EC7BF7A +:10A3C000EC45BE6AF842DBCF00D7A313EECF33F2E1 +:10A3D000B71BBF3013DF6D19CEED94E6A768FB34D1 +:10A3E00037B2A6E5A50A9ECBB6AE68027C6E3A32BD +:10A3F0002B7501F4FFC1C7B4DDC9B6146ADFA7AF7E +:10A4000093E2CB815A1EEAB8C1975880FEBA4592B2 +:10A410006BADBEE1F8D218FCBEC885A081F8B4F1DE +:10A420002333C3BF0FD0B0C342FB390DC7CCB4DF59 +:10A43000B26D0797132DEFACF9F96F097D7E50F8D7 +:10A44000BD0784DFB24FF82D7B84DF12107ECB2E48 +:10A45000E1B7EC107ECB1BC26E6E3A2EE46F498CD6 +:10A460009F7FC796E765B579DED1BDE98411165C9B +:10A47000FDF180B50186F65C9693510E594E462645 +:10A48000CBFA63B83D556A5F6ACD96EA87B1EBA413 +:10A49000FA1B5AFBE9E291C1BA78A444E78F8C9188 +:10A4A000E5F26858BC4BF1B51CEFDE141EEF6622D6 +:10A4B0009D781CB8ADE931A2E3B6D359F1E17ED95C +:10A4C0001B426EB69DE6F6F98D33E76223F96D67A0 +:10A4D000043DBE16F468167ECA4D29AEDBF30B317F +:10A4E000AE3867C6731FEDF1B3F6BEF6DE19FFA9ED +:10A4F000B870FBF705058D21F8DB2D9FE452FEE4D3 +:10A500002AE563592C3FE7B65989A6FBF757BAD716 +:10A51000F29BFC2CB10F51D387EF8BD60CC4F20504 +:10A52000933B15EF3F6D56DC53508FFB7E678EF8E3 +:10A53000F72496E72B9AF037A07DE04792E1E725D4 +:10A54000C588FC1525C067996739E2C78AF13A3496 +:10A55000526D6E86EBDA64620D68E7998B39EC9D7B +:10A5600018172118E7875E9ED5F9302F25C8F78F79 +:10A57000C1BCD2F73EF068167E770B4BDC27B35890 +:10A58000F9BD83E87C4F5D7E21FF9E6D7C3FECB77B +:10A59000249BEFA306487F4F11FD1A6276A4933DDA +:10A5A0006D4FAFEAE25C364FBE8FA2E79706A16718 +:10A5B000DFC8744F89F41D8C3F0AFC6CFB6A9C8ACF +:10A5C000E31658E35CFCBB902E15EF81BDF1F5E876 +:10A5D000986911F86C7FEF697FCC0FE38382608DFF +:10A5E0002AFE4E8541CE6F190248EF0B3633C9F56E +:10A5F000605C70C2A5FD0D3923FB79839AE4F83FB6 +:10A60000B4BF5FA7E079B3367E428220FD8FF0EFC2 +:10A61000695C899FF4FBF6C7F3B5F3929E4FF01C7B +:10A62000B11A6FA3F3359B8E58D7A31FA9CFF71D7F +:10A63000FE80EB71FDFC1B3F98948AFED7E6A137A4 +:10A64000A7A21C6F41054FDFEF5938C925C1B07E65 +:10A650001BEA7B26BEB355CDEB476970CD243C3F4A +:10A66000B365186FFF49FE9127F17B605B6E13F5B0 +:10A67000BE4778BD06B3459386216C32103CA917BE +:10A68000B487FE7EEAE93A8EFC199DEF3A81E59F98 +:10A690005076A01CD1D3F519C2C791C760DD477BA6 +:10A6A000B84E86C3893D5CA7C2E1CD6DF6A5C5163F +:10A6B000BE7FACF1E1E1631384DDE1741FAFC5350A +:10A6C000C55797E7FF77C1A76F0B7D7548D88F37C0 +:10A6D00085FDD88FF683E2616E3F1AC5BEF16E61CB +:10A6E0003F768AB8371477B9857F3159C4C33C0E99 +:10A6F0002B185ACAE35EBB96E7CF30468A87C61549 +:10A70000C87EE2D87CD9AE8CEE9628F169795AAA37 +:10A710002E4ECED6C5C9B25D2931F6D7C5C98375CF +:10A7200071B21CF716378FD6C5C913A4F6C7F31D2F +:10A7300044D7A2E3B7EAE2E5E952BB101DE57D9BF1 +:10A7400010BD6644A4E396E2190FFEDFA263E4FDA8 +:10A750009AFFFFE8F80FCAA3CD20EDDFE8CB77849E +:10A76000FD7F4BD88D83C20F3820F21CFB843FB78E +:10A7700007E9D81DFD3AA7F0EBF8390E2D0FF28648 +:10A78000C8433588731C5BC4BEDB2691875A56FCD0 +:10A790003D3FC77191093ABE1B918E154ED9CF1B13 +:10A7A0009327D371942351E7F7C97EDE70BBECE7A2 +:10A7B000955A653A0E63FD757E9F4CC7A12D253ACB +:10A7C000BF6FB4CE4EC9E738C02F78B45721DE4BE7 +:10A7D00090CF731406E5F31C7AFBAEDD57D4FC86EC +:10A7E000363FC12BEF336F421B8AFB452966FEBD06 +:10A7F0000DA3A70BFA1D1ABEFCBDF839C42D9FDCB2 +:10A800004EF82C447B1EC17EFFA917B7FB7FEA657B +:10A810006FBB1F19DD0FD39B3EEEFFC48FB5F373E3 +:10A82000552C88DF9FBA8CDFF4275CAFE62F19ED3B +:10A83000350CFD08D562F0E1F777996AA573778743 +:10A84000DBF1A34EF5CAD4BEBFAA60BF9F887E9538 +:10A85000E237F9B9BC5EAECDBDF05E4FA9B305F3EA +:10A86000E29B3F323B6B919FA3F87750F4FED6E119 +:10A870005EB9D49F863F3CFFFF0BB48FF8A158FA16 +:10A88000DEDEE73AFB090B867E5E88E6F091974FA5 +:10A890004DF2A585ECF527BD2E903DCDB57599817E +:10A8A000F1B2B2D697C0F72B03245F7ABFAD5DFF3C +:10A8B00057E7A79DCC7305116FDFA35D2EA47355D9 +:10A8C0002E63BFF6DF7F21DA7D17FF1E8C4BC5712B +:10A8D000353C69F58704DD0F8BFEDAF0A2F1157EB9 +:10A8E0009F2621EC1EAC6EFE1ABE561ED91BC42339 +:10A8F0008CD7BA1E6D1D11F8C77D05BFFB7BA2AFBB +:10A900008E7FD858A7B8A71BD9EF33093F329CFEDA +:10A9100083695D7E6DFD6C783FBCFFA2DD5BE7FA6D +:10A9200050BB339360AFB367821CDD7E54A5730EBA +:10A930004CEC831BDBE859ACA09D318E505862581B +:10A94000DE55BF9FA8CF1FE8CF9515377791E0EB75 +:10A95000CFCBE7CA5C177B5ED6AE94D986E8EC52C3 +:10A96000A9CE6E8DD1D9B5893ABB27E7C58DCCA8C4 +:10A970007D6748ECD72B0EFCFE8E916328BC5E7C75 +:10A980000788E37B793BF2DB767EB69783F0DE26A1 +:10A990001FEB9883D3CF27DD33516D1EA2F3A303A2 +:10A9A000343BE6A4B8D71C1844DFF3343BE5BFCFF3 +:10A9B000E0F75A3F2ECBC17B368CCA67BCF68FCBF3 +:10A9C000E83E4E32954F791DF47CAD378FCA27BDD6 +:10A9D0004E7AFE84B788CAC7BC2E2AEBBCE5543E2B +:10A9E000E47553BBD5DEC904AFF27AA8CC02F706F2 +:10A9F000FFDE40968F3961C62C7B158C1786E74C9D +:10AA00001FCC230C8F5D17DB2538BD26596A9F5A52 +:10AA1000E590EA533C79527DE7C94E09EEE82E9263 +:10AA2000DA2796BB24B883AB5C6A1FEB744B704C7F +:10AA3000DE64A97D94C323D5EFB97E707CD365E431 +:10AA4000B9CEEB3A817858ED759FE0782A3FC1F195 +:10AA50003399CAB9BD3B107DEDC67A17DA6D7BBE5E +:10AA60009DE1F976B395DFFBEE60B42B1DC2FAEFE2 +:10AA7000E082FEA4F9427F523CE7E7E789F3DC2756 +:10AA8000E4794F96DE0319243BA9F931C3D5B458B4 +:10AA90008CC71E34D9FFBD3FCCE381E12AC37B2B99 +:10AAA00047CA26525E04AF6CB2087AF40BE19FC627 +:10AAB000F4B652BC38FE0985E23B584905E61167F9 +:10AAC0001DCD7686FF3D28AD3CFC1BFEBDA1983D0B +:10AAD000DB1C98171B5F3C2D312A2CFE1B1FF8B185 +:10AAE0002C85FAEB3B200AE6317EED34F38CFCD06A +:10AAF000FAB476B39E90FDD110FFFBADC21FA775CF +:10AB00006AFA69B57D3D3D5F9D77F97D9BB3625DD6 +:10AB10005F097FED0BE1AF9D127EF749E1777F2A58 +:10AB2000FCEEE3C2EFFE58F8DDC784DFFDA1F0D7ED +:10AB30008E0A7FED3DE177AF147EF7EABCF5F4773E +:10AB4000AD2E6C54987A99F3A57337C8EBAC5A279D +:10AB5000EF1BCE7A42F6BB673E24FB6BD397CB7ECE +:10AB6000F71D8B657FEDB61AD95F9B5225EBC75B4E +:10AB70003CA5127CF364392F77935BDE37D4E8343D +:10AB8000B15CD6939664D95F6B6FBD5B03A354FC35 +:10AB90003B2448CC5361F630EC7BF0D279C702BB42 +:10ABA000AB14F76B0A997B19EEE70C3504DFC7FD90 +:10ABB00026F6A14ADF816CC0370681BC5E1830766C +:10ABC000BC23CCEEF864BC4E3D2EE7476EBD47F685 +:10ABD000832BE7C9F18CB95CF6835D69F27EEC44A6 +:10ABE0009DDD61C21E9AF9EFACCC7D793B648899FA +:10ABF00047F795AED51E9999FEFC18B747346E9667 +:10AC0000544FF628AA0F3F273140DC53A88D1AF87D +:10AC10000EEEDFEDF988DF2F00B407BBC1FBD733A1 +:10AC20008E6FB375247D3F6EA789DF1BD89D62733D +:10AC30002E85AAEB2FF2FB01ACD548E7C73C786F15 +:10AC4000240BFB95CF8F15068DD2F932B3AE3E0D96 +:10AC50006DE265E7C3CFD1FDEFCD479CE3E8C3FAD2 +:10AC6000D0F988A6C8F70DDAFC381D9F6AFAA7202C +:10AC7000C0FDA38276FDA3A9F49D31E3878CEED9B4 +:10AC80005B0C2D679EC3FB515FF23CEC3026C76D19 +:10AC9000378E95E3B6E1F6CBC76DA31C32BF8EC9E4 +:10ACA00093F5408553D60397F8354DFC1C627B7EA7 +:10ACB000CD4D7DB2B47B3A849FA89C7D317C1F939F +:10ACC000F3CF10B1CE47CD6EBABFB23C9D119D8679 +:10ACD000D8F979C55ADCB7C1F37F1FF07B2F46E660 +:10ACE0004EEC83E5E911E2FCE25827F5D7CCE955B3 +:10ACF00004FF7ECEBAF47CA2256894BEBB61646179 +:10AD0000F485FA39C85F1D437CF47F675EE2FB0877 +:10AD10001A9FD912AEB07FE793FC40AD1C1674A900 +:10AD2000B88EFD76BE8FBA3F5813C4EF447E9FCCD9 +:10AD3000F314F7A74D30F2EFB6B86CC3812E23C4DD +:10AD4000FA8BC43ED9162F0BA23FB7C96BA552DBB5 +:10AD5000FF5C99BC2811EDE6960C4F2A9E0BDCD2C5 +:10AD6000B1C372067A7AB3A9435AA47B048DA68133 +:10AD70006467B734A618D10F1D66B41BE97B52690E +:10AD8000D355CCCF8EC4FB26490833DAA7DBE40DBC +:10AD900004CBE85CA887CE11C13A4AD18F2DB34FBE +:10ADA000A3BFF7D8F801C88503FDE30E53F1BD7DBD +:10ADB0001DF9F96B8B9D9F6F1D91349BE855E0E465 +:10ADC000DFEF2B48B339FDD85D32FF8E4F15FCE322 +:10ADD00074E17602E45EFABECF40160623BD74F03D +:10ADE000D37A3DA03B97B8F298383FD71479DFE685 +:10ADF00033E1576C117987E3C2AFF858F8154784EF +:10AE00005FB15297077A5FF815FB441EE880C8E7E8 +:10AE10001D14F9BCB7845FA19DBFD6F822791573C4 +:10AE200058E2197B771AC773CA2AC55F0EEB289DB3 +:10AE3000C9E1E4C57C7FB4ABA7CE5D5280F526E7BF +:10AE4000485847F2E4BAE1B88E94A92D744F69B21C +:10AE5000C7EC7029783FE929BA17A5DD0BBB93A38E +:10AE600086DD3E7304E9DF3B3DE2DCB1DA5C48FCA1 +:10AE7000F58489BE93A47D3F6EF24CF97B4AD3756D +:10AE8000F8BD5D079B15AE47DED1E4A23FEB1F8EF8 +:10AE9000F714D136EA4E719E172F5D459097B50293 +:10AEA000EF1A5E1AAF1F1DCBD7C1F7432DA29FA388 +:10AEB000C5B7C6623F1FA4F1FE260879D0F7B75A7E +:10AEC000EB4FDCA78916F47FB4E7E5CF9D1EF63281 +:10AED000E99CE961419FB67E4B1E34E1F7B4270738 +:10AEE0001E48477909DDAB71C5F2FB2B63FF3D13AB +:10AEF000E8B45ADC43D0F4EACD427EF5E37DE0BD10 +:10AF0000FCFD9D0F4AA698F07BE837057EC5FF1E25 +:10AF1000B0B12639FCBCEF07383FD095F7DF743766 +:10AF2000FD1DC96006E707CB8D16077E67B06B9ADB +:10AF30006B05E23139CD395CE447C99EFD3FEE81B6 +:10AF4000191B0080000000001F8B0800000000009B +:10AF5000000BED7D0B7854D5B9E8DAF34E32810958 +:10AF6000049C604227E161AC04262FF260083B108C +:10AF7000344524131221981026099068D11BAA3D4C +:10AF8000D27B68B321218418799C6B3D50090EF85F +:10AF900068CFB99E1AACD7D27EEA8D8AD6DEA312CC +:10AFA0007A430B6DC5F092F66B7B2F5ED49ED3A3D4 +:10AFB0001FF7FFFFB5D6CCDE3B93800AADF634F920 +:10AFC00074B3F65E7BAD7FFD8FF53FD78E93C18F57 +:10AFD0008F314BC25E65423263CE62858D87F6A6A5 +:10AFE0009245694333185B5EDDBC98CD64EC12FE7C +:10AFF000CC83E7CCA60D65E24BCC724981FF8799E3 +:10B00000CF361BEFE31DC37376291DFFDFCA82898C +:10B01000703F78CB6F719C6AD6EAEF87FBDD79EAE7 +:10B02000040F8CCFEAEC67875C8C65C2EFA58CE8D7 +:10B030003CF25ACD6CF45C8EB76431F497E3339AEA +:10B04000CFF07C6B17F339C742E323806E22BC2F0D +:10B050009E6DB5855D385F77F05E97EA662C23D5E7 +:10B06000D2E004782AD236AF64B06E56E9F44CC30D +:10B07000F7030BDFCECD836BE65A1F2E0FFB354354 +:10B08000BFE33776A6F96644E1DABA8D9584609E0F +:10B09000AD697FE75D9B88FD3E6C0B613F3BABE993 +:10B0A00083F1BBE7FF2E35DD1DED7F7056E94CFFC8 +:10B0B0000418B01CFE97C2D8744728C33F63F87ABF +:10B0C00019D3189B80F88F670CE038D3A0849D00BB +:10B0D000574D0FE06F0C3EBFD082F71B7A9CBE6EBF +:10B0E0000490A9EEDB609D6BF93259C3B48EFC7EEF +:10B0F000B8AEED01BA61FFDDF6D3882F17FC227ED2 +:10B10000D35A6DA723F8C2FE4CD7C6794C6D07CE33 +:10B1100001F0DEE24F4C7EF726F8772ECBBD64E5DA +:10B12000F447FCD688BE710D556319D2D30BC82CD9 +:10B130001ABEAE15FF6665FDE319310CCB8FDE3FFD +:10B14000B17A4A7C08DF43BE7109BE9A453CE97377 +:10B15000CC46FA73BEAA167C05ACF912F19566D7F7 +:10B160002270C2BAD87DF628DF6518C66308EF32B0 +:10B170007D9BDE578F4D05F8570AFE5F1968E1F891 +:10B18000BA8FF3A30B6E8A71A2FC06E3044DFC4751 +:10B19000F49A28E084716E2F2BFB1F3F059C3DBE67 +:10B1A00033E336A4D3EDDFB4322BCC5705DDB05DED +:10B1B00055A384C3D05E16B899E461997E7CB85FCC +:10B1C0005D6D3FABA7CF3B1BA7D038ABCAF9386C3E +:10B1D000A36E7E826F27E133C8D8168F8EDFDE4DD7 +:10B1E000675319E0F1A53DCDFBF0FD73BB9C0CF955 +:10B1F00088E1BBB391EE1CAFC7807791FFCF6F534F +:10B20000C20700EEB37B9C04E7BB6B943043FA3378 +:10B21000CF93FD70FF017F12CD732E2EB4EF1BF084 +:10B22000BC716B825F83F5768D6BBD2708F39E4BF7 +:10B230000AD5E3388D5B6FB268D0BF2B5E7365E0D3 +:10B24000B88D56FF019862850D703A0EAEF0EFEBA7 +:10B25000E1DAD0A5A31FFC37E85788EF975858A824 +:10B26000CF3D9C7FDCD90ACD8F0877EAE05F926101 +:10B2700021788F3FE42478C764FB689C86C2383508 +:10B280006E0CD291A9B61C8027559D8C709E55409E +:10B290003E81DFCEDCAE68881F66E374715C3F6977 +:10B2A0003FCAD33F89759E7DB06032F2F39924FE88 +:10B2B000FCB4373E8CEB3AEDE36DCDEB0E3F81B243 +:10B2C000610B652E4BE4EB50800F1A055C8D3E8BB5 +:10B2D0001A07F46D7C68F95791CE8DDE9EF5783DA6 +:10B2E00096A8252AF0FEF93D5686F8467CB872F0FD +:10B2F0007971333E37E3E5037F06C183F81B0F788E +:10B300007B77777B6208D6C13C2CE49818C543C391 +:10B31000CE1FDEAFCC2479D6B8BC733951986E3FBE +:10B3200006FE5DE17368E5300E3B3C95F876858757 +:10B33000F3ADA368CB840CDECD1DE10F1FB57B7090 +:10B340007F6F14ED06E45BC0EB0A949799888F71C8 +:10B35000B3FBE17ECD6A23DF6E49DEFC6015AC7382 +:10B360004DA19D59E1F91AAFCD2037951B8C720480 +:10B37000EB36B4C767335A77D738C19F9D9C3F815E +:10B38000D32707B3A27CD1EBB748BEF0D947C1BFE2 +:10B3900019AF5F343C9C467E057D7326CDB7AF88E0 +:10B3A000F402F00F878B5975F2D0D0E524BE67C048 +:10B3B0001E8827E04F476556945F247E1A766F22D9 +:10B3C0007E6C107CD7D803FC3346C747267CE19AB5 +:10B3D0006D729E29513EA3E731F8EC453F875BCA69 +:10B3E0005F030BD633EB70B99657A27331D0B36FAE +:10B3F0005D8D16C0513492E31D25C56389DF053D7F +:10B40000B8EAA11F17D22D51D2476383B89FBBC59D +:10B4100043CF06E54419E81BABD8671DEA40B81FC7 +:10B42000EE276DB0D27DD42F36E88FD33224F8F3D7 +:10B43000054F4F87769C68BB055DAD56770AE22BBA +:10B440009119ED9E71CCA44FFC9CAE52CFEEB4B3DB +:10B4500014DC8FE3C4FEDEBC708A82FD762A0AD932 +:10B46000078E32231F584D7A605AB685D62FF1C009 +:10B4700084BE75B8F87AE3522C24171FA482425573 +:10B48000A2F87088F58FEBF7F5F5C3F37AAFCB1F11 +:10B49000463E621ED20FA53053BF6EDEEAC509AC30 +:10B4A0005F47E7859EF186F62DDEEB0DFDBFE29B43 +:10B4B00062787E6BE64D86E7B7F9730D6D07D3E9C9 +:10B4C00075847388E3DD21F0AC7B2EF5F200D2B1F8 +:10B4D0004AAC638723E40DC23E5CE55D4BFA7953C9 +:10B4E000C95DDE215887D3CBE5CF81F6248C1B378D +:10B4F0006DB587EC08A19F0BE117E9D08E83A444BA +:10B50000F9CC61C2B359FECCF6E4DA6CB07B12A080 +:10B51000F165F665B27BDCE362DA3766FB0D7484B5 +:10B5200005F9355ED06BA1D54D7A636B35D8730ABA +:10B53000DA974BB9BD94F95F88AE41D18F6916B2E5 +:10B540005B9789F54BFBEBAD36C6FA6F007CCCE719 +:10B5500076D6B2C20BD57ABB5C5EBB453FD98E2F87 +:10B56000DCAFAA31F4694736DF371302FCF9321732 +:10B57000B3A11E92CFB764737DBC4CE8ED2520C704 +:10B58000C8B71578D5D9ADBB049FEE8AF02B1BC880 +:10B59000D1CBE9538A0DF110279AFB596857F6046D +:10B5A000C4B3469DACEE2023F9FE08B03B9BEC18DB +:10B5B000FA29CD5EDDFB75F447AA13FDE85B38D5AB +:10B5C0008627BE0DF88BAF4EF05B7C517E27BF0304 +:10B5D000DAC9999CDF6B525D7E7AACA983536747C9 +:10B5E000EDB26A61DF4D60AD2407C3FC1817E7CBED +:10B5F00091FD18BEFFC8F99C62FF67D68D7EE2BB45 +:10B6000020DFF72DF08B7C777B8D91AF968746E717 +:10B61000B31F640BFBBA8015109F85D6115F3845A8 +:10B620009F1D93815F389E883FE2257E85BD6DB763 +:10B63000B17E1BD0E908D21F8074DB5922AE734063 +:10B640007D85E4622093D9F57C100C58D5B08E8EA0 +:10B6500003452CDE03FA65C0CED27641BF31EAF253 +:10B66000451E58DF40A933B18136D5B0C16E3F02C7 +:10B67000E39E72B311ED7DB33C4C877FA01ED89A38 +:10B68000F6AE17E1D96A67B4DF3376B106E1DA2E98 +:10B69000DBDAEF6A4AB11D27DB1FEE56A1FF93F1FB +:10B6A000BCFD61F6A5DD5A2AD18BF82A41D0234191 +:10B6B000DAEF337478053AB89273689F7199F06D38 +:10B6C000B6EBA59E30EFC3E6797F27F70341A7913C +:10B6D000D63D0C5E60CD2F8F2E17EFA35CB8C05FF8 +:10B6E000D6CBC5F071FAC97EAF15EBB6243C9F16D8 +:10B6F0008AE14746F0BFCEFE7BBDBF00783EA4A0E6 +:10B70000DDABC2DBB319571D308E52F8DABFA3FE92 +:10B7100057766BE3108F56E8807ADECE42048F9422 +:10B72000D738E4032BE2BD9F9E83FE1D52A6E02086 +:10B73000751EE45F05FA5F42FC5CE93E59CEF5DA1E +:10B740000AB1FF55E094305E45172B45FF3C6E4D26 +:10B75000D3816DA8E754275A1470FF4229C207CF3E +:10B7600055275D2FA84837E06783DE79A9E44FBFEE +:10B77000790CDEEB1CB0FA9D306E67E0C70CEDEE85 +:10B780008B33981F17DD811D01BEFA9067A1C38717 +:10B7900072D37FBC631A63A7DAD840997D38BC03A3 +:10B7A0002FC7397CB0D8909634F35918A7ABD0E99D +:10B7B000417BEE9D8D5607D26960738386C83891B0 +:10B7C000A2F52970BFCB1662E8DF3B36B62F44FEE8 +:10B7D0003E61D7FCE3E0DAB559BB1BFD10D5B7B825 +:10B7E0003C1DE03FD0652B0FC7D89FD7E7707FE7A0 +:10B7F000AD97EEA4F51F4971F8E360DC218C6F0072 +:10B80000FD8ED877A6F971DC4DFF2D0DC73FB266CE +:10B81000ABFF6580EBC826277A52ECC81E570D8E09 +:10B820007B646EB377AD6E7CD7F58E56BC3F30C966 +:10B83000E19842EB792FD18BEBD9983B1E79B3334A +:10B84000C531B9099FAF6D66B85E8777A71DD7E789 +:10B85000B2B1DDB8BF7CC97BE1CD02F4977C96D94B +:10B86000B740FFFFEA0FDD9A83FEC986530B512FC5 +:10B8700039CA92B6E0B553C029F72B49DFA19446E7 +:10B8800017EE639DAB9B781CC66B69203AA6588265 +:10B89000B81F7506D6B8A6CFE0F79BC70CC74B27D5 +:10B8A000C65D66219C6BBD6BB3B0DF876D21E83749 +:10B8B00034D759130B8FCD395C8FB9DA9B333600EF +:10B8C000DC9D7B5C1EC44FA712DADD0078D5D2DD8B +:10B8D000FE277CC3DFFB81784FF207D089E4707DBF +:10B8E000CEA43D9A0DED554E47C08BCBAED39B07F2 +:10B8F0006795AECBD1ED93C3E64DE9247DD1A97018 +:10B90000B9FE414ECE1E0DC6C9F587EECB81F98E2C +:10B910007481ACCDA2754E467B7F24F91912CF3BC2 +:10B9200037C1BA63C8FFD06A2BBB612CBF5E07D793 +:10B93000E99BAD939518F8199ADB948171AA23F0CD +:10B94000DC02E30CED71F12BDCCF40FE1A813FF3FA +:10B9500072B8BECF9A19ECC6F5B2197E8AF3BD99BA +:10B960001DECA1366BF562FB0BC0BF8F7D4EF897C7 +:10B97000B149C0AFCFCCDCA3814BCA3CE30C76EB22 +:10B9800048FB67900DD9703FDE54F2A716F407BA52 +:10B99000B31C3EA72E2E28EDE825995CBF05A79D78 +:10B9A000CD839D9B55CD584BFE0DD8CB141FF4C0B5 +:10B9B0006FACF86010E3813A7DB8C4D496F6E9BF65 +:10B9C000E608FB45D8C9A9BE9DC1F9E87FBC61F571 +:10B9D00087016F69F802B42B172B61B4D73795FC38 +:10B9E00033D9F14CD8714B049CBF6C73B1B2692C44 +:10B9F000E2CFAD10F7135A4E3D8EFE7502C63F31B1 +:10BA00005EDBE2F451FC05890FF35789F549BF8EDF +:10BA1000EC4858CF8A16110765BBB8BEB106F29143 +:10BA20001F601D06BF24C84C7EC86ABBC19FAB35D2 +:10BA3000D90F66BFA1CA6437EC40DB09ED425B9FBA +:10BA40000BF9E9FD193947327CF458EB97F63DF4D0 +:10BA50000B150E6E19D2ED3F8342FFFCAC4D3D81BC +:10BA6000FA684BF03117C6E1BB6D6117EA93EEF24D +:10BA70007B1391EFBAEBACE5C86F036DE5D4EFAD86 +:10BA8000B6205D6DB95C6F54FAD58F703F91F65951 +:10BA90005579E9890E1D5D2BD5AF9CE8D0C15F516A +:10BAA0005869684BFEAAB0B2D6BE18FB4B5EAE8C8E +:10BAB000BBA8CC608F5A9FF28762EC17F21ACF6C4A +:10BAC000EFEBF1382ED768F73E3063FED8D1EC1992 +:10BAD000B94E891FB97EF97C2478FF2347FA279F46 +:10BAE0000DDECC4F08AF194E09FF48FD2B70139B9C +:10BAF00084F076ACD066201D4385B980E7AA326514 +:10BB00000BE6657E26E2953F0B24863580E7D54C13 +:10BB10001EFF8C6FE17E657C59E542DC9F3E29BDAE +:10BB2000EF2854483EAB034A58857FDE2CFCD55F96 +:10BB30006632CA3F80BCBE9908ED5FCCB5F338329F +:10BB40005317DF363BEAA7C6D7F1FCC40E07F3F75D +:10BB5000E37B37BAFD9BE1FE32297F35C63C447555 +:10BB6000B5DDB0CF5498F20EF1A67D6679AEB0BBCC +:10BB70006703DEA744F13E92FF31129F30DB853C24 +:10BB80008C8B99F1738F093F667FA7E279937C5C78 +:10BB9000A1DF73A02BEFD564B433CA14FF34A41F04 +:10BBA0003E82F7E2D583940ED921E548F87B325FD7 +:10BBB000B5636915F97B6FA13D3096F24D93315E07 +:10BBC0002DC7977E5EAE5FFD466EFEC8700C8AF78D +:10BBD000B656C6B61306D14E98C5AFD7C175FAD2C0 +:10BBE0000569B1EC84C1226127C073B40F06F794D4 +:10BBF000F36B91D14E60E5B997C1CB265A6FDCB497 +:10BC0000BCB1B1E46E7056E8E1DC09D17642662B36 +:10BC10002BD3E1FDABD9EA3FE27A2B451C42CE079C +:10BC2000FAFDB0DE0E33CF7728C7C3F15C3E9EF439 +:10BC300085BC5E8E7E364F2B433E7BC0AED6A0BD0C +:10BC4000678E27FD3097DB895D196A0B3E67EE9C96 +:10BC5000CB8CBB49C6AB33B327F2F403C57D4CFE96 +:10BC6000A0F49FF6E3C3FCA85F68F370BF303EF515 +:10BC7000C2610F3C5A971B7A1EF135F74258B380C8 +:10BC8000DC39172B643F395319D93D57EC875D6177 +:10BC9000BF2E146AE0E7AD8D3C1E5F9A6DA3767CE3 +:10BCA000C87A80F605531C275E7D8FFCB02560079F +:10BCB00088B80DD953C7853D1564ADE4EFB9ED6182 +:10BCC00017C62BCC719B9A544BFF74D0EB3585175C +:10BCD000AA7D33E97D43DCA7C69771788278EE812F +:10BCE000EB92208F032DC338108E5F1DEECAC03C2F +:10BCF0009CDFE65719F7F3D0BE58DE747FD6C3BE7B +:10BD0000AB170792F125692F4A7B06F44BD778A42D +:10BD1000CB02C547BEBF294E648E0BC9B88C397E95 +:10BD2000648E177D9C9B4EF490F6978CFF7C946BF1 +:10BD3000B4C3AC3037F6EB2E822D15E4BBDBCED28C +:10BD400076CEE0F11DB4978E94FEC483F68535CF90 +:10BD500014E7BCC2FDAD13F6A133B8AFBE126747FE +:10BD60007B3BE80D513C7189629493C9797C9FF3C8 +:10BD7000E4B9F93C228FDCD9B641BEAFA1BE09A619 +:10BD80003AC2714A741C56987F45F2949CAD4ECAD3 +:10BD9000CB277F2415AFCC0FFE4816FA231ECEDF2B +:10BDA0008513683D4C9DC0CEE8F3C602EE081C2EFC +:10BDB000F05BB23EF9FC2988E7FCE83C97C3DB8ED8 +:10BDC00092629703E31140632BE72B4F247E9F8100 +:10BDD000719D753EBD5D518F798B5CB43B795E433F +:10BDE000DED7C5CF6DC8BFF1A9213518635F5D955A +:10BDF0006731E44F23F1F74C46F922398E8D7937BC +:10BE0000911CA0AC4A78AC31E2F402DED5420E00BF +:10BE1000E12E27B04CD34E2BE375095C4E643EC235 +:10BE200056142C4F87F5366D53286FCCB49AC368DF +:10BE3000DFAF11CF1D22FE66CE23AD117918665DEE +:10BE40004776DAEA878CF9B5C61E63DB6C97CB7848 +:10BE5000BF0D8044B8DB249D40C15B47C7C37E5AF9 +:10BE6000E75F291E241F2ECEFDAA17EB5A3AE342A4 +:10BE7000BB1B30AFDDEBA27808F990282FFDF00B4B +:10BE8000EBD9B6B7F0315CCFF63C2B977B85D7B9B1 +:10BE90001C4E79D835A4E3B7ED82CF66E5F978DC9E +:10BEA00005F72550892C3599E448D6B51C49E1762B +:10BEB000A523C0EDC6A7A6BEBC94E75D797D4B6601 +:10BEC000205ADF520AF8C912F8C99CB6DADF0FD738 +:10BED000AC00AF4B9AF1ACD15FBD35D36857669AD1 +:10BEE000FD5553FB405EECBA96689E4DC4DD05FCE3 +:10BEF00066B9FA5E1BCFB7FC33F8AD787DAACD43A7 +:10BF0000D7EFB779E9DAD7E6233BED99B64CBA4AD1 +:10BF1000BC3F600FD6635E4BC621657CBC3F8FFB88 +:10BF20006F2CC0E1A8106B59684D4D443C1F0D703B +:10BF3000BB70A4FDA5AADC1807BD3D68CCEF2DAFF2 +:10BF400031E6F7EE9BA9BE9407F024CCF4DA43BAAD +:10BF50007CD41AB1FE1D0FF37C931CFFE83739DD4A +:10BF600065FB9C58FFCF045F24BC9C62F701B12A9B +:10BF70001FAABC19E3F6CC937345F6E02F855C2627 +:10BF80006CF6D8312E54D9BFC281E3ACD90DE3B8D9 +:10BF9000AF7C9CAD6913D38CF985AFDD81701C8DAE +:10BFA000E4175AEFC0FCC251915FF843DEBDDF4198 +:10BFB0003F6B569E7A1AF5862B4F3D83F8F883D057 +:10BFC0009BD03EA76FC3CFEB4913478DE3FF212FD3 +:10BFD0007F781CDFBA40698D55D7F2A19017D05BEE +:10BFE00017711EE68AC4D13EE06DAE8FE2F2397E53 +:10BFF000DA7FC95A709CF61FB3966762D8F32C5F3C +:10C000009171B98F490F7AA51E0C5E8A359ED5595C +:10C010003919F17DCECEEB62CCE3C5E53B247CCE75 +:10C020007C7C3F35025F5C7E7E74BC1D808301A4F6 +:10C0300093CD9348794D7637E53F251F25D47B6E08 +:10C04000C3BA05702C19EE2F09CF796ECBC338CE49 +:10C05000CFA7F89F6023D3F5B782BFCE0BF93A87FD +:10C06000F205727446C8D729942FB89E14F2F5EBE6 +:10C07000363FB57FD95648EDE36D2AB57FDE564E83 +:10C08000D7C1B620DDFF595B0DB53BDB42743D5A8D +:10C09000F6D8CDB8EF7CF03D85F4F148F0DCF5B88A +:10C0A000D5203F2D7B130CF2B6F6A1F186F6EA1EE1 +:10C0B00063FEBCB1638AA1BD6A83317FBEB2D598ED +:10C0C0003FAF6D9963986F456881499E6F35C97B15 +:10C0D00095A1BD309FDB8955E5B586F79CDE4643CB +:10C0E000BF84A52C148BFEB7E5F3B8C9CB25C56377 +:10C0F000874689733836DCFA36DA2791B62DC4D0F4 +:10C100009E776C5842F71F88E3FB9DF9BD26C1AFAF +:10C110009D65AB83F319DA458BAC7ABBE79E59A1D9 +:10C12000E5F93A7FD0E1E5FED8C5A9D5562FF0D183 +:10C13000D2B2F75EBD0EF82834C0C8EF51C1DCF3AF +:10C14000821D5CD8BA6BC175D0AED6D61BFCC7E2D7 +:10C150009683AF80F8B240D9D1F664783F3F3BD4A4 +:10C1600084E397782FBC82EFCF5F9C6D43367F20AE +:10C1700089913D7A2ECD113E10831FEE1770CBFCB6 +:10C18000D527DDA7CD79FA8C4C568A71E48CCC0B7F +:10C19000A5A8D7A0AD62FEEBE0ACD0FD081FDC5730 +:10C1A000514F3E90B53603F79391F2468FE41BE36F +:10C1B0000912AE1D251C9EA322BF3064CA2FE8E2DF +:10C1C00009EDF9A3C413CE89F786BE1D3B9E704EC0 +:10C1D000E41DCEC9BCC3C35531F30EE7168A7802FD +:10C1E0003CC738C2B93D35FCBA70F4BC835C1FEC67 +:10C1F000477BF20D790761E78BB8F9E02C752F3E8C +:10C20000FF6AB6DA8BD73F66A9FB108F4775F94FE7 +:10C21000CF445DFEB3EC2786FCE7A19CD093F93CAC +:10C220006FCDD0AF6AD7D850DC14CCC706EF89C524 +:10C23000C7CFE4CBF862FF67CACFEAF2A8964B37C4 +:10C24000B12BCE035C71BF425E9762B66F121023B2 +:10C25000E3A276DFD379A19F20DE3A929EF3F1FA32 +:10C260002B4B74FF40E537823D649E4F8E87FA0A60 +:10C27000F5D620480CEE33DB932ED4A19F724CD020 +:10C28000D37C3D9E2FE8C93CC948DFA7F382BF207D +:10C29000FDF36C9F8FEADAC4FD2B85E34947F06D0F +:10C2A000B4633B1BADBE03DC6EA7B8C50D81A470A3 +:10C2B000B72E1F7C11F7CB7C8C3F0E4D7500BDDB7C +:10C2C00043AFB8B11EFC9DBD36AC8861DF4DD4ECE8 +:10C2D00048FF9A4CBEBFCDF786BE34348A9C033FDC +:10C2E0008CB778090E8BA590CFCAAF9A825773FF8F +:10C2F00081BDEF4FF0C178DFEDE5F9AF1B7A57BB99 +:10C300001A75E3DF305BEC97C83379989F54C258B5 +:10C31000A85E1378EFCD02CCAFF82C14E77867E372 +:10C3200007C79663DC51B552DCF19D8D17A97DDC02 +:10C3300067C945F2BDE3FD7FC7B0FF0DDF5C3391F8 +:10C34000FB2D1C1FAB36E63ED99D4E7931C76C984C +:10C35000E7B87A3171CA8C68FE6C95C282B1EC98EC +:10C36000C9B339FF2F525BEF40B816859C0CEB9C8C +:10C370008F376C7D1BDBDF2D557C56F4EB33F93C9E +:10C38000357B6D544F0BF85987ED37FC090CE79D51 +:10C390001F3A68C3FE1F6629EC3AE52AE255BD380C +:10C3A00001E5F01DE4BF18F05F94F22BE468BA0DCC +:10C3B000E43E07F17FD8AD8F534A7ED2F2D4CCD978 +:10C3C00014F70BB504C9CE5D7A19FB7433AFD3FEF5 +:10C3D000DE051BE61EE21F6F9D84F1A561708E00D5 +:10C3E0005F91A0FB1FF3791CF3865EDB9B5F417EB0 +:10C3F000DE68A73A845979C139B3F5FED655DE37E0 +:10C4000064FDDA40213F8F00E634CD03F066DA00A8 +:10C410008E3825DEAF71B9A2F89C4BEC7FD04F1D52 +:10C420000BFD56B1BE7E8CF3319BBAD38AF1C32289 +:10C430003BF9C7CB57DA13912ED17C99DFE06F9887 +:10C44000AF67303F46751A2EBA0E809F8DF912FCE9 +:10C45000014B1C1EDA84DDEF7F449D0A722FEA4AED +:10C46000EF3F74EB2358577ACCC2DB771DBAF5FA4D +:10C47000CDB0A433935B8FDD0EEBEADEA5F837F980 +:10C48000F0BA7F77239EAFD8A0F8CBA16B7DFF8D4C +:10C49000F598626CEE72928D7F7ADBFD3723BF5E7A +:10C4A000F4320FF2F3F214CECF4D832C6C81F62DC3 +:10C4B0003DBB28EF191CB451DD9ACCCB9E4CE179E1 +:10C4C000D97F68EB27B8D1AF5D389BBBD8F833CEA6 +:10C4D0000F70601CB5CC46F9D2F1CCD389FB4BBCB4 +:10C4E0009A5ECAED698F83F23C8B19FB0EC67936D2 +:10C4F00070BFB948D445CA3C163BCBFDDB16F845A6 +:10C500007D32BEDCE81FE79BFC5FA9DFCCF916E0BB +:10C510007F0DEF77CE4E34C4EB468ADBCBEBB360B6 +:10C5200047E0FA9E1379DC4360AF633EF3C760AF28 +:10C53000E3F579B0D7F1FE8B60AFE3B51FEC75BCC6 +:10C54000BE0CF63A5E0F83BD8ED7D7C05EC7EBEB4D +:10C5500060AFE37BFF0BEC75BCBE01F63ADE7F7685 +:10C560002EDFFF3AA739C29B01DE4E3BFB35F29529 +:10C57000562AF2C2224FB62D693AEDEFAE8F80CB2C +:10C58000C19E1A504277213DB43417F51B48BCF0C8 +:10C590001FFF17DBDBD2C90F6136DFA12178AFE3C4 +:10C5A0001BE9FE6E68763918E9FB53479947017B12 +:10C5B000E6FCEDCA4C8CA39EB94DE9C3F6C06D0AEA +:10C5C000D913D351F472A2FB68F1FBBE03B89FB537 +:10C5D0002732C18F4FF6AAC07FE71136E4572DA945 +:10C5E0001EFDD2794ED91E538FCF1B3728C24F1D47 +:10C5F000B74F85356C53E4FBA9BDD8BF43BE2FDAD6 +:10C600008316F9FEBABDE8271F8BCCB7BA564D8505 +:10C6100076867CBEB60EC73F15A9AB9BB712DF1F4F +:10C62000888C3FBB17DF3F9326C7BFB396DA76D916 +:10C63000FEA795D49EC0FBCF7AE1BA47B16EE56AFA +:10C640008FD71EE2FB1FEC63AA3E9FB3A9D84AFB1B +:10C650009EAE1E9CE26E32CF6F49704FBB9278A99E +:10C660002ECF4FF15298CF8E72F6F5D2A4C9A8778B +:10C670004FA5F963FA29E5C591FA5663FC5455783C +:10C68000BDBD8785B03E3E5EDC8FEFE175F48E4C1C +:10C69000DBB03AFA2B8927CABA07194FAC593D7A51 +:10C6A0003CB1A6D4184F5C259E8F144F5C658A2739 +:10C6B000AED868CA43843E593CB18EF5DBD10F63D6 +:10C6C000AA427254E7E97B7522FAFB677D144F6436 +:10C6D000BED729DE2ACF4FE0FF2DB3F1BC196F9FE3 +:10C6E000BF5BF1A25FD17DB73211AF27EF5626A114 +:10C6F0007C9DBD5BF1A0BC7D589041F8CFFF8DFFC4 +:10C70000751FEEB75E8B9FA323F802A62A82AB9318 +:10C710007CDD30CEA9BB9571F8FECAFBD21DC80FD7 +:10C7200060770A7EB4EE45FEB426288676DE64C9BC +:10C730008FE147503EE68D176D6DF95E949F5287ED +:10C740007C7F33B5578414D1FFEB7B51BF1C9B2FEB +:10C75000FB4FACC3E7B74F91E31D20799C9720DBDB +:10C76000BB49FEBA22E37DFF11ECFF0BD490D4DE6F +:10C77000B917E5BDB452E8336D268DDF5927C7FFE1 +:10C780005A2FC6AD6A2DF2FDC524FF4D4CB6C17EB1 +:10C7900087F6AFC4FE70D70F3FAEC5B8D61DF2B94D +:10C7A000F6F123084F9D68AF2BF897BDF8FCAF7EDC +:10C7B0007D7FE6F9CCED956C60E1757951B930EF8C +:10C7C0002B0D45DCDF296C3988EA8BD5B5EEB7A295 +:10C7D0003C46F36A29D541E46F9795EAE7825E7695 +:10C7E00073AC7AFE4B057C9C8D05579A5F8B3DCED2 +:10C7F000DA22BECF75CD6731FDDC83B3E66F2DC87D +:10C800008FDA0D68223AE05A02570B5C3FCE0A3DA0 +:10C8100088CF91D618879171ED25A29E7853C9775C +:10C8200082F3F1FC5291DD2FC2E103FA7CAF4D9C03 +:10C8300073AD9DCFEBBC42DD4EF2D7AABB441D8940 +:10C84000D54DF908DBF58EFD943713F9D410D61DBC +:10C8500067505DD7A8E73B6CA63C6A97586F69F6AE +:10C86000FB94A76E7A83D70BCB3C76BD80AB09F5E2 +:10C8700032C0DDB85A095BE0BD46543C98D7CD6460 +:10C88000615F7A34AFBCA2CCD6EFC07361E27C06A4 +:10C8900013F670241F5EEDEBC3FA189B1AE757716D +:10C8A0001ED61FA4BA38CC17A5B348FE59EA91CAC0 +:10C8B000E6EBEEC63CB54E6F519E3A9E0DD31BA4DF +:10C8C0001722754D228F1EA9CF117A40E6A71BC4EF +:10C8D000BA9645F4C0E22568E7C63F20F2D422FFAD +:10C8E0002CF3D495A6736D8D810563289EEBB7F963 +:10C8F000A9AC26D5789E29DE44879B8AF9B94A9946 +:10C90000A73E5A60CC373F6067A477BB328C7CB7B8 +:10C91000A098E743FCC5320E19DF1F87F6377391E5 +:10C920001FD28DF19CB1DC1FA1C35CA6B88E6D43F4 +:10C930002DC51FF1B9027CA864BEF6EFA897B15DC2 +:10C940000CFD6D78BE05E9E1B6903F2AE33F68A68D +:10C950002CCCA138D079E467DB867A1A479E677FB2 +:10C96000323EB67C5C2C9079D63E3BF6ABF5BE767B +:10C970001CE7FBCC7120E18745EC181FAF7F995471 +:10C98000E09376899D9FF763F6A559142FF9B800B7 +:10C99000EFCFE8F3211C725FBAA3E839DAC7AE3CE7 +:10C9A0000FCEDF5BFBA3976AB5E491F3183705223E +:10C9B000790737A6C059B2CC3BA889D88EEA595816 +:10C9C00048A141CFD6B5FC27D0B351BB3FA30E9FA2 +:10C9D0007FD1E0077EBAA590EAA778FCED8B06FF31 +:10C9E0001BF96A3DF2E1B59EE7C5FCE03A9C67ABF6 +:10C9F000A2D6B8E95C0CF32BA3E70BEFC5FEE67CEF +:10CA0000E1E5E2187F8B5B8C1EB7E82D34E6F53F3D +:10CA10002F718B7F04DCE13E09F27490E429C0E5BC +:10CA2000E9AF7DFF83F51EC1F56E55FAC2F1D6ABB5 +:10CA30001F37783A2FF46B94A3E9A9AE06B4676068 +:10CA40001E1FCA5F341E0270171AE2217B5BAE41C3 +:10CA50003C04D6F97BD27F659CAE7F05747314E1EC +:10CA60007A546E47FC15F26506ADAF8FAFEF2F30ED +:10CA70007F4E11EE034F717E89E287DB493AFCD489 +:10CA8000B5FC65F07333C17788C3F705A0671DD186 +:10CA9000D3CFE1BD9CFFBDBE80FB17F05E13BD97F9 +:10CAA000C7F9E05E6157835FBEE03A5FD42F4FCE97 +:10CAB000569B8BB89D7B6791A1CE54BDAB6874BF6C +:10CAC000F99EA2D1FDE6FBF0FD2F8ADFBCBF80DB23 +:10CAD000FBD1BC4DD8C53FBED142F9E57AD1B77B79 +:10CAE00043D5A21BB1AE06F08F6D27AEC7AA5B4F30 +:10CAF0009A8DFBDBA6F36AF27B07725D366BDDD89D +:10CB00007E5F149F6F8D6975E079A86635A913CF94 +:10CB1000DD2EE8788FEA061DAAD3877EE197BCBE9A +:10CB20004ECCCB56A97CFD8E160F9DEF93E7DDE42E +:10CB30003994E6FE1B5F73E0B939F05F5260FC8AFE +:10CB400032FB69FDBA9DA6732936537BC3AFD3B7B9 +:10CB50001FD6F57FAAC8544F687DAA9CBED3D1A129 +:10CB600078449D2FD565348B313695DCB108E39739 +:10CB700060C7F9100F0B76EE1AC07C9AA3C34AB9AE +:10CB8000F33FB6F9B61F06918AEBB552BCE1830DAF +:10CB90000AFFDEC7629EC76F12797C668A33C87847 +:10CBA000B8C463DC83BCFEC35178AA8CCE37D6AD43 +:10CBB00019C8E7BC43F1061B878CC9EF6F540ABE46 +:10CBC000AA0FBCD781EF2DF35A0CF543E678848D7C +:10CBD00099EBE4791DA74DE5759CB64C5E271FCFF8 +:10CBE00054FA5E47FC962AA267A5CAEB38C14812E0 +:10CBF000DFDDE274A908ACA73A1F731CC159688C29 +:10CC00004398F9D24C8F93267A3C61E3E7933A0735 +:10CC1000AD7E0D6E773EB4BA0BE3E7DA43168A6356 +:10CC20009C95F5210024C6F397B3087EC95EEE6C8F +:10CC3000E5F502922ECB77F2BA11EA6588DBA732CE +:10CC4000FD773C968BB8C21DAC8FCE3BAC6443766F +:10CC5000948355184AB7623CC647D726A66D6184AF +:10CC6000BF50573ACCF744EB783FC6B5FB27D99372 +:10CC7000DECDE47E442CFB359AAFB5B1777571FEFD +:10CC8000BFC5B53E695CCBAAD1F952AF233C4DB9C3 +:10CC90007C5CEB88C84BC8B8D6D99DE27B1BE2BC54 +:10CCA000C580BD75F24E37F6F3919E19B377F92220 +:10CCB000E48323BD3FF188F3AF1B278EFE5D88829E +:10CCC000E218F5A43F2F60345E67FA109DA33E6919 +:10CCD00037D6E5CAEBED0159BF19528B75F631F322 +:10CCE00044EA38E717D346C0CF6BCB38D3BADCD091 +:10CCF0002D787FEE05C10F8B95B002EBAD702BAF99 +:10CD00002ABEE8FCCC5C47FFB77C18C11D87F80140 +:10CD10003C0EC4F1BADA817456F34C0CFADC389745 +:10CD2000EBD181ECD8F493CFC13EB9BF7802F79F25 +:10CD3000C6F0B8C2EF1DA3C715BE551C23AE20E92F +:10CD40007B709EAA71BAF3B62727D489FDDB4341D5 +:10CD5000AAD739DF63F56D42FCF7B7BE5508ED255C +:10CD6000DFB27A301F7EADF37C930AD289AF2E9763 +:10CD7000E7FB50E0F764A4AEFB5B944FEF8EF867DF +:10CD8000DC7EAC1DA76BC3965C3CC8FBBF585CBC8B +:10CD90000FCFD98F646FDE1758D58BFE9CB437A1A7 +:10CDA000BD12DBF27D9084C9A5A0349B5A643EB1CC +:10CDB00082F2F5D1F956EC43FBF8ACDD38BEB4573E +:10CDC000078ACBF7A1BD1A8CCC5FBE0FEDD953A655 +:10CDD000FEF47D4A18EFD7C565D4BF91C9F1CBEAFF +:10CDE000B17F24AEC8D6933F7ACC21DBF7D4A33DE4 +:10CDF000BE3D9D8F371858DFAB7D0EE1B9D6E37F7E +:10CE0000D2FE23D9FD27EDBC7E50033BED89742C67 +:10CE1000A3ECB372E1531D78C6AE5855683FFA9340 +:10CE2000888307DD16E1E76CEC45BFA7B644F2E95D +:10CE3000E354073212DFAD7FFE478F68FA756A3F11 +:10CE4000AA35C0ADB5529D8884FB04F68775D4DE43 +:10CE500073A717E1AC95F10DD6D98BEBEB4C92EFA4 +:10CE6000DDB40FDB23CDBBE6F99DBD88EFDAC83C0E +:10CE7000DFA6F76BE3E578BDD48EE2F300C54BA2E5 +:10CE800070B518E07A2D70A017E10A7AC25B707F46 +:10CE9000087A19EDC777B46CA2FAEE881C693BD208 +:10CEA0004A510EBD9136C757448EEE2739BADA7013 +:10CEB000C17E9A3E07F7BF4CEE275EFD75C33E89E3 +:10CEC000EBEEE17A48F2519D478E03F8077DD2E4FC +:10CED00093EDAFD5B7B8AFC6BCDCDF0DFE9E917D3C +:10CEE0002BE58969AB4DF27365E3B5BBBF4675149D +:10CEF000CDA0D763D563DF5B10D14FB7123E0BA532 +:10CF0000FFCCA4DD5181F72376872F627754CE8939 +:10CF1000617774629DD52CAAE722BDA9C213AFAE7A +:10CF20000E68C65C9E076C177592799BD95ABDBF77 +:10CF3000FDFD79DC9F7F6A1E874B7EDFF6CC3A854C +:10CF4000EAC4DA7BA68CC1F36EA7537DDB51AF0D2B +:10CF5000A45BE83B0527C5F73507BEE14CBB0FEEE8 +:10CF60001F4F73F9515F1D4FDA49DF513BEDB70A8F +:10CF7000FE3CF40EEEF3BAB8A2867A45C60DEF9EDB +:10CF8000B3F55194A3133EDE2E9CF7E377509E59E0 +:10CF9000A6F97C6780EC18C7CDB08DE0BBE2FB9CA6 +:10CFA000C5E279E5B61F7CBB0AC710F68BD49FE6B5 +:10CFB000F39EF863D7DB5F5D566E7F79793F2F1B59 +:10CFC000DA74C982E3F2B66B84EFC2D6C8F3CB261B +:10CFD0007BAAD2743E9989EFA04A7BBC38B9D18F25 +:10CFE0007E5CF13AA37D74BAEB959E42F46BFD56DC +:10CFF0000F6E93B7661A9F4B3B6C51D763E48F82D9 +:10D000005D689847D6DFDECAFA3AE85CB8EFF5C348 +:10D01000D68951BFA5DD5349764A7326B4603DC712 +:10D02000FEBE34311FED831E2B7E1196D7DEEBD66C +:10D0300001FDEC9664DAA7FD8AA2AF0BDAF228CAEA +:10D0400045B42E88B7A3F1F8BF7FD45047C7BEB60A +:10D05000CA10E7D46A1FA53A3E1917D3AAE9F919ED +:10D060009B8883694D8FE27E16899369BFEA35C438 +:10D07000C9B4203D0F46F6BF5DFBB0BDCC23E0D167 +:10D080004EF622BFB5AB5C9FBC34C77D52B37DF278 +:10D09000FE209FFF730EC6B7827CBF333F2F1E0C4E +:10D0A000B78F11761DD68B9BE57C5C80D7DF95A969 +:10D0B000D91D137C3C7EE504FAA82BAD2B316E10F4 +:10D0C000AD5729A2EFA4358D505FB224C0E5F7E833 +:10D0D0001CB7C12F37D7A934893A9591C6B9B38403 +:10D0E000E7D907144F35D7CB56867AB974D714379A +:10D0F000E6A664BF9B4BF83EF071967A12D76F8E0E +:10D10000A79DC5781AC9198F7B2C15BC63DBC9BFD5 +:10D11000572FBF677226C9EDDF0CF797F688784561 +:10D12000F9678B9FBD37C7784E7FA4FA87D212BEAE +:10D130009F1589F57ED6FA8727E35515F135047DCD +:10D14000313E38AC1E42D439C83A88B1810C5EB742 +:10D15000C1783D44BBD64AF8BBEAE75CC4FE0F7C0D +:10D160009A1C403EADE17A44F2D94FE7F838FFFD12 +:10D17000C64FFC27F90EFA4F0AA01EA9E6FD8B7FC9 +:10D18000C3BF7B21ED8B718133BD9BA6921EF2053F +:10D19000F4FEAF3B722E322310430F1D5DA04E0DE7 +:10D1A000E8FC23783F33901FF3FD2F13BCA6F7B3A1 +:10D1B0006606B3E8FDC8794E7566E06F7510A03D50 +:10D1C000CC75277CBF30D79D487BF0CE92DFAFC4B3 +:10D1D000BA934BF3D5651CCF1CBF11BB7288DB39EA +:10D1E000517B3287F6C36B602F36133D453DCD35FD +:10D1F00018FF5EFDF8D27E82FB7FA7BFFF79F3DFC9 +:10D2000000BE6E824FE44D3EC5FBFF40EF8B7CCDF0 +:10D210009F01DE30F191B0FB3F87F87CF6730EDFA3 +:10D22000EB44AFC59CDE657398DCB7FF35361F5CF9 +:10D2300031FFFF6F7A5FE4CD75E3FE5C3FDF48FEB0 +:10D2400039F4FB15E16DF130F93919D0E5E347798F +:10D25000FF8C7E7EDDFBEFEAF9F32AC8F9053D7D00 +:10D26000AFC13EF2118D3F958FFFBBE2C83A2EE968 +:10D27000EFFF2D4E76593E9F3617F1D5CAF9E90AD0 +:10D28000ECEB9BE6F2FA96108FCF6A927F678AFBEF +:10D2900043789E74F91C26BE8F12CCC6FB2AE3FE8F +:10D2A0006DC41FD17AF719FD1118688641CFEFD3ED +:10D2B000FB1BE5739FD88774B72EE0FDE7BE306E89 +:10D2C00015E2DFDC067B64DE5C635DA68AEDCB8D58 +:10D2D0008BF97F7ACF94FFD73D5F44CFA3F50B64E2 +:10D2E000BF82DDE672028D7F51674D6E8476B5F0A8 +:10D2F000DBC1FE8879AEBB3A1AE7AE9EABABC7186E +:10D300000C5AE97C60C44E61EE4711FF113B4AFBA9 +:10D31000FE3EE3B98D8314E72A11F46D7EE1D97ADC +:10D3200001E72AC4374B16EBB87CFF35D4DFCBFBC3 +:10D33000C7787E273D4FE57032F7EB67ADBA7C18B2 +:10D340004A9A05F3BCF82F1FC06FBF7D6E32D82BF1 +:10D350002F77293E2BB41BF74A7E7A81E44157F799 +:10D3600041F2B742F0FBD6170ED7233FAF785FC22A +:10D37000EBE4EB8FD4311DA6F59F10F188092F4205 +:10D380007FCEBFDF24F87C1CBE6B30FE36A213E3D9 +:10D39000F8A9619A7DE2287516BB04FDE1BD9D04E4 +:10D3A000978BC3551352C85E0FAE06890638EA073D +:10D3B00059CC38D3EEB90EB98FEDA679DDC28FF511 +:10D3C000C73E2FBB2FCA4FFBA8BF87CFE702FD8FF9 +:10D3D000ED40E8E802FC0E448DF8DE784D998DBEF4 +:10D3E000B750537861A98883507E53E6C14B1F9C88 +:10D3F0004AF9CDF8B238EE2FBA8C7FC722D8E4A410 +:10D40000EFC9C9EFD6CABA8C4A66FCBE5C8CFC96E2 +:10D4100021DE22E32291EFC95953C9BF753C2AFE90 +:10D42000FE93E9FB71F11B18C5B79C1DFC1CB839B4 +:10D430004FD5B0B1F5AD22ACFBB0D9292F6BCE677B +:10D440009AFF1EC63C1753C7E4503DCA6B73F3A343 +:10D450007528E7F74E71A31C9AFDE7F323F9CF7BFC +:10D460008DFEF380F49FD5ABE33F9F986BF49F1F35 +:10D47000CF0DFE8AF8CAA6D2FEF67249F1528C236D +:10D480005C147514A71E4A5E82F128AD879F573839 +:10D490002DF2FC32DF7FAA88B93D78DDE2247C9E44 +:10D4A0005A9314C62D784C47F362FCAEA0F4A31136 +:10D4B000F318FFAA10EB34FBDBF18540CF5924664B +:10D4C000E4679FF278282F50D125BE2F21EA05A4CA +:10D4D0009F5D21CEF13795F173D518B1437E90DF72 +:10D4E0000FAC107EB8F4C7FB7FCA147D1DC052E696 +:10D4F00027FEAD06C6C0EB32F13DC51A0FDB8240F8 +:10D50000FD312BC44A102F7B399FB0ED36FA3B57C3 +:10D51000A77A76D1BE3AD2390677893CC7A0517E28 +:10D52000F61AF8F9490497D83FAE60BFB98EFADB16 +:10D53000B81C6FC3F3BFF9D1EF4AC873F3DB93781C +:10D540001C654609DF6FCC57F9DD884FAA3F407F45 +:10D55000DE5082EF47FDF94C84E70AF4E74C825B2A +:10D560007CB76232E681F8FAB34B783ED73786272C +:10D5700071BB1CA3D70114968C92CF6597AF235033 +:10D5800063BDFFA1B0B3D7E5861696F07C3FF1AD41 +:10D5900039DF2FFB1DC3F8548CFD76838853950229 +:10D5A0008B5A72869FE7FF459B7A126DBC636DE5CF +:10D5B000743D6ED312B17EEB2D719E1F0C2DAA67A8 +:10D5C00092755172DC9ABAD2936775FB59C5C2C77E +:10D5D000A9CEAC3DF3C0EB0AC0795AD47B0D24FA36 +:10D5E000689FD38EF2EF4B2DABFECAC9B3BAFDC311 +:10D5F0000C2FD6456920EAEB4BF877CB5E2975F600 +:10D60000CFCBC3EF3571395CDD738ACEC3D46F687D +:10D6100060A12CAA9BB2217DDF9EC3BFBF50516881 +:10D62000659A0EAEE46CF5AE121EF759477C12AD4A +:10D630000BBC1BDBA576750CFEFD49199F94F98286 +:10D640009B5FFC3F94771B4862347FD0CBC29877B6 +:10D650005FA0AE770C61DEC5EBA3F8C8DA121FCD70 +:10D66000DBD8B59FE0890FBC47F0806DDD8FF58377 +:10D67000667C4BB9E814F8D6AD9BF03D92FC562C75 +:10D68000B425227EDF427A41BF07C53E70C476C111 +:10D69000ED8941F7C87B85A5067C3BBDE506BAB59B +:10D6A000ABF78EC1F5483A378A67E7BBAC6F221DEE +:10D6B000DF073A32A263EC3A88A348AF1B806F4C75 +:10D6C000F4AAEFE0DFBDAEEF28A5EFC5D5177EC504 +:10D6D00091427900A50FCF4B36953530B4A71D6A1E +:10D6E000127DDF4ED26F6919D04F072FC8E3632434 +:10D6F000A7C2EEFC14F1F5FF5EA2B383AF75FC1F69 +:10D70000E6FB51490CBBFCCF957F18FE3D1FBEEFD9 +:10D710009E12FC62BECA7D77C4FA662DB8AAE55394 +:10D72000C021E506E5769382F5938A1DF92C88F2EF +:10D730008BE7D70A7FBB05F3A1CD5ED6877BE13EA1 +:10D740009423C09BA33CDD81F2D3B8379DF802FD42 +:10D750007FC2A7D8A7DFC47D5AF8FF74BF85F3C581 +:10D760005F3AEF03F0FC1BC15327CE177CCEF25279 +:10D77000C9E541F73CC05B50DD4FFAE5A742DEE06A +:10D78000278D7FB7E993E5418B555E3726F3A131AD +:10D79000F29F3EE553E43FCD79D591F2A131F29F5E +:10D7A000067B7DA4FC2733E549CDF9CF455D5328A1 +:10D7B000FFBC28D342DFA99676BFCC7BBED1F50350 +:10D7C0001B7D176986C292D287E747BF2DF431438C +:10D7D000AB4EB7FEE369FCFBD7DD292EFABBABF8F5 +:10D7E00083F558129FA01F5C4E98B76321AFCBAC56 +:10D7F0004C7FC68C5787F04BAE08AF32BFEEE85275 +:10D80000C29B9135BC2C52FFE7D0D1D991F91CD1E4 +:10D8100091D9FADDF83DEE46FF78AA2733D3A1B8B7 +:10D820008BFF5DCA62CF6CFABB9492FEC5DEE175D8 +:10D830008336095F8CBAC13F3B3D7D9B5D19A3D008 +:10D8400053E6B147A2E3ACBCE0BDF32644BFDF24FE +:10D85000EF1F4FE3F83D7323137FFFD4484FC0BF42 +:10D860004AE7FA33D9FECDCA707E2816F598C599D5 +:10D87000DA7AAA838F5FECC5BC5904BFA98708BFB9 +:10D88000EDADBEEDE81F1D2DB353BD4A0C7EA0BF0C +:10D890006F7B397E1846F79E4F47BFDAA22716A442 +:10D8A000C7E08F4F4DD7CBD0D3617DAAABD0174BFC +:10D8B0004E5FE92139F55B3D4857494F49DFE1F4B7 +:10D8C000E4FB9DA4F7DBF9EABFE07E18A5B3FA34C8 +:10D8D000D2392ABF9AA19EC5FCDD9B1F8A3A161831 +:10D8E000E7391CE710FA58143F540FE138555F8AA6 +:10D8F000FDF74E9E29E5FE4E1DEB7B7522FA7D67F6 +:10D9000099A8D7F4BFEEC338CD862931EB358F3DCA +:10D91000A0F0BFD3E365FB2D627FB5E8FCDD535873 +:10D92000B709FEED09ACDB84EB5BF3D2F9F7E5B1A7 +:10D930007E732CD8E3A2BEB30EC7C679C09EC5BC09 +:10D940003CB385189E4B1FC0EFB3CCC2EFB36C2223 +:10D95000BD1BADC3F890F45534EEC9DB9501D97603 +:10D9600087A9EE46E63F993764CC7FCE0C1BF41DA9 +:10D970002B0C19F39FBC4E47EAB7CDEAFC10C6B595 +:10D98000A371C5721AFF649DECBF235C3A4397FFF5 +:10D99000D4AAC2AA5B9FDFBC2DACCF6F82BEA4B657 +:10D9A0008C433FD1FF6008EDFAAC99A10B48377961 +:10D9B0006E1E14908A7F87CEEAF61C403F1CFC0343 +:10D9C000A6E68F6C575FEBEBFF07133449A100808D +:10D9D000000000001F8B080000000000000BE53C69 +:10D9E0000D705467B5DFDD7BF727C9866C42A04B0D +:10D9F00009ED4DF879692561F909044AE06E76135D +:10DA0000B62D9405429B0AC50B64101D5E0DB5280A +:10DA10003EEBCB42421A420BC1E1F937AFBE2D05B6 +:10DA2000677CD631386AA1485DA0459496A63699A0 +:10DA3000521FD280790CD5AAB496577554DE39E7B7 +:10DA4000FBBEDD7B6F3685023A75DC4EE7E6BBF741 +:10DA50007CE73BE77CE7FF7E9745B315C66631F868 +:10DA6000F99386C6585F2DFC79338E83A651C2D8B0 +:10DA7000D2B1725C9934263236374F8EAB4D633655 +:10DA8000631D1E26E6B30403F8D7989BC69B8D5AE8 +:10DA900033318EB1F02255C0C708FF99E5127E4799 +:10DAA000320CF896B9C438B12469F819FB2893E30D +:10DAB00005345E9E1EC769FC00E3EBEF4D3D6E260C +:10DAC00060FE77A6C56F3646C0BD68B71EAFF8C703 +:10DAD000A3FF9C22E9196BE2F30F3BBD20EF9851A5 +:10DAE00085E8B9BCFF01E85D41FAB19FD3FB21A4F1 +:10DAF000EF2192E7D39CBE0F013D6D444F37D09389 +:10DB0000FFB75FEFC52A6327EECFDF808F2768DF7F +:10DB100027723EAE02FE29E23BC4F7C1F9FCE67073 +:10DB200080317C3E8DE37BDD2DF428D164A2DE9F25 +:10DB3000755BF60DC6B37AE57A1BF4B066A57F0374 +:10DB4000D9C9B2223EFFD7A9CF9A8992CC187E06B6 +:10DB5000EEBB9CFF1B7C6E9BFF199ADFE94EC3D383 +:10DB60007A1EF15C39BC89E8CDF09B20F81E077C59 +:10DB7000A3E0AFE07047326191074B3C4AF249FBAA +:10DB8000A5C4E3E497FA3C72BC8DEC667B29C73FE1 +:10DB9000EAF0E349A41FE47782E43D8ECBEF9F5D7A +:10DBA0001EBF3584BE947379483DFCCE34E377A81C +:10DBB000671F367A61FFD4F0888CFEFF1DD62BA438 +:10DBC000F5843D7DD0F9697B14719FCD4FCB77747F +:10DBD00018EE8FAAD5E979F5DA7D919BE0CFE5CDF6 +:10DBE0004FAA26E2051856CC58BC9F2537C39A7712 +:10DBF000B0A4CA2086C543260B4CB4D835FB32D11D +:10DC0000E1F1BBC4F8BFC8FF2D9B23F5FA5412F312 +:10DC10008B0CDDFE95B84F69BAD91336BA671FF67B +:10DC20003F29F80E852D7672A3F1076B412E967C65 +:10DC3000283D16F259F6E057C7A01C969549BCDF5F +:10DC400048229ED70B25DE7DB4EEB2F43ACFF171B7 +:10DC5000AE84FF29C167E8EA336D74255EA5BC4B2D +:10DC6000D2F5CDC37DB45F9E4072CBC869706D5252 +:10DC70004209D88F8FAEDDA49A56BFC0BAF530C422 +:10DC8000B7FB597A4C7A95F103DDB4EE8DA66B7D26 +:10DC900058C847D8699ACE7E164A302B7DFBF9FECC +:10DCA000DCE0F52D7EE121D4DB1B2FF794FB268BE6 +:10DCB000DCA51D2C0FA4EDDB603E90BB2EF1BC60FB +:10DCC000AEF55FFFBAA0E78F5BFDC9F5F3D153470F +:10DCD0007CBCC5F725E37F5E36EDFEE7AAE97B3223 +:10DCE0006C89E71F74FE7F87ED7666F13FDF42BEE9 +:10DCF0005BFD451ED4EF9541662481BECBF89B9B0E +:10DD0000B98EAA55C83FA5EDB39ACF5FB2833577D8 +:10DD10004F1C0C7F53AD8BE05A9F656BBB015FD8E6 +:10DD200073B1296E814B85F9F3436185AEC0DF2164 +:10DD300092FF464EDF89B04EEB8599C60CB0A9869E +:10DD400025634A500F5A7FCEF1B160882DCECFE0C7 +:10DD5000BB20F0C9750E2FCA6FB4F2F113B1CE8992 +:10DD600030E703E33FC9F311CE875AB02E88F8D5C8 +:10DD70003C595FFE9AE4DAEE16E3C43B14D7FAD2BC +:10DD80007EE877A4EF4BBD522FDF23FB97F9FA3BD8 +:10DD9000E13F2513B3917EC65C53ACF37E4B7EF01E +:10DDA0004AF3FA65BC6813FB9548EFD759A4FB4AC0 +:10DDB000F3D588D24C72F2B19402F143F50776772D +:10DDC000022B1595C69B38FFA5C9C6AFAE060FC876 +:10DDD000E922EDCBC3F67AC4F2FCDDB0AD1EB8B8D3 +:10DDE0002E8E7860652FECDB6BCBD5E25520B7BF6C +:10DDF000E2FE54517D10CBA65F7FCDECCB5FC3B666 +:10DE00007C3E925F0576C446B942E3F5C1F3FCB5AA +:10DE10008AD433B14FDA93C8477BDADEF8787B21B6 +:10DE20007F9E73C4BD52D8535E2DAEF33D215F1665 +:10DE300028C6F5D8C4E329753AC45796FE192E189A +:10DE4000AFC2BF60FDBEC85937EAC18A0EC5486679 +:10DE5000D1FB4176D221F03F96DEBF51B52308AF0A +:10DE6000C9A68BF801BFBE8F6F22BC8D4D0AD99F0A +:10DE7000D35EC6D672F98DAD4DCB692CD16F70BC17 +:10DE8000BE69F1F188174099774A06FF0A4177D8B1 +:10DE90001D3F7413E8417B9BA2A33F5AB9716547AC +:10DEA000298C99E60E8D87CB049414CC6B0F96F9D0 +:10DEB000D10FBC24D6437C1ED8478C25C122826357 +:10DEC0001A5CA7C7D61FC5E97FA930AB70DDEAF899 +:10DED000CE08B235AB71DF51BCDE036E1AF3944D40 +:10DEE00073BE16AF85FDEB99E90EA1AA4176D63334 +:10DEF0000EE86A107469C6BC37D930A8A23C2C94CD +:10DF00009A8671DD1FDA0CF71B9A3E3E9F55024C34 +:10DF1000DC3DD0EF43664C76B90CF16A03FDE55C5D +:10DF20006697C1C72DDAE8CE8C91367CEECB3C5F8C +:10DF3000722BF74FCB6A419E16BDFB91E0EF474233 +:10DF40009E3B80869E8984209FA1DDB0B52E94DF04 +:10DF50004A81ABA76DC95DB7017D97CA5908C75EF5 +:10DF6000E44FCDF077768CC6F963867FC148585769 +:10DF7000ECEBC916F075FF0268DB804FE047539762 +:10DF800017A42C7A7C7298C94298B79527B630D0DE +:10DF90009388B9D3DD0F74DCDAF4F65ACCFB5698CB +:10DFA0005E7D1E9078FFDA401DE6B54B4C2197F957 +:10DFB000EE73C8B70FFE43B978526FBEE04139CF58 +:10DFC00056D828C0BF30CA9F4BB9789976CE2A1749 +:10DFD000CD31DE78BA74FBF316F84FD5E6179FFF04 +:10DFE00008FC31954DBD0C7C82035980F45CEA50ED +:10DFF000026A2981B918F0E9F1F17DDCDBB1FE2577 +:10E00000B4D315412DE4D2913E46F26B146BBCD7CC +:10E01000A26F7F1E72D5C8C69D5DA877F7F7AACC00 +:10E020000B70EDCBF72226FCF9109F26F4C295F772 +:10E030009F3D1AC069FFA6325C4FCA11E41D980EBD +:10E04000F7CFF5C17C00BDBF1AE404EBDE63787541 +:10E050001DE07267BFDD8672CA65CDA9E130BE37AB +:10E06000E862295F862FE03B21E4E2BAACD05ABADD +:10E0700026D775D99E935C723F17610C7D77C2E8F5 +:10E080001907708BA4DE76F0FD5C64F0FD90FBCA8E +:10E09000A25C5FE5BEE43AF4D55BEDCEE867167DA1 +:10E0A00075EE43D2B10F7B356E27677B55CA8FCE95 +:10E0B000EE2ABEA71AE491D8E5223B863A6DBF52FC +:10E0C000007FA414A681FCEF13F4D20FE0F63617FC +:10E0D000263B4B33FB715FF9B13F2A958C438DCCC6 +:10E0E000F82386452C8CEF15A3FBBE9228423BFDFE +:10E0F00028EB76A35D3FC0FADDA8FF1FC352504551 +:10E10000FF18F2E0FD465FC08372DCBBEB483EFACD +:10E1100091D4CDEEC2F3E5642ACCEA279D5794C48E +:10E1200079C93700A7A4FFF49941F2CB7EB8929F3A +:10E1300036188E0BEBA23E334B1C3936D5FC31FA28 +:10E140002339D602CD0CE9D83335FE13EE77F9FC2E +:10E15000F195C64FD17FEE9F629CC0FBDFC07C0F64 +:10E16000E2C3C5DA47A82EF94B857112EF3BFDD803 +:10E1700039F4637A461F163BF441FAB153E8C7E01D +:10E18000D162B457901B8B5D9F1F3B2BF5E07676D9 +:10E190003BCA07F8F925F97F0DF801B99CC17D9FAD +:10E1A000C4B0FB966245C4A61E00FA14411FDE5798 +:10E1B000C0BF2B1B7FFC4765181FCF023845EC2BD7 +:10E1C0009691751837BE1EF2F9C6A2BF304F21DFF7 +:10E1D0004EB9406076535D163C760AF5C695F7C396 +:10E1E0003166963898DED775EEB7D27CA11D4126F0 +:10E1F0008F7C28CC745D467E0240C4A8F7D38B0484 +:10E20000E941FB0285F86B2F658DE8CFDBF0D14C3F +:10E21000D0F7054A37EAFBB722453C5F1AC7F3C27D +:10E22000CEC26430C4FB2C04CFCA436C494506EF10 +:10E23000B7222AC14F9A66E461E082BC8FF2259929 +:10E24000AF4AB84084E795C3233CCFA8A88C1751A8 +:10E25000A02B0E91DC218F1A4E637F2AE91A29FA2E +:10E2600022FCA7BB2C7944DFE824C33C24D7C89EFA +:10E2700037DC1249C7F55B22C8C72E19D78D5B1151 +:10E28000FFDCE18106F4731EA07B7769265EFF60E8 +:10E29000C1175458967D24524AF45537ED6C1D0928 +:10E2A000FB1D0E8FF563DA94AA4906318FE81C0531 +:10E2B00072C8622F1B233C0E4EBB45C00979C9B8FA +:10E2C000EF83F4DB0DEB6099EFC23CA084E7010F14 +:10E2D00044CA689ECC07003EE101B8F00493F0B454 +:10E2E0008FCFBEDE03429E99781B2A407FCD5833E4 +:10E2F000C58BB88827AFB51867064029FB5A6274EA +:10E3000005FFDF130507774A4BE487B2C86F61DD6D +:10E310001E1FC6EDD6F255BE7ECCFF8C08E16D5CAB +:10E320001E3E3360F1B79D256C0CE601F736DC79B3 +:10E3300066C0626F3DF99C5E8C33096F06EF52D464 +:10E3400013A0F768D89B9A0B02CD0DB2A457A1ABCE +:10E350005B473B88E8F43C6EAC6426D6E3D5673572 +:10E36000EA7F15B234FC26D89A483973235DF160F0 +:10E3700092E1BC5C18237C7CF6DB04BFB05A6509D3 +:10E380000B9DE07F56901E38F2A51DA86080B77DDA +:10E39000A692DC0C781B826B28FE6C9A934BF7617B +:10E3A000DDA417EEDF33BE89E296CCAFDAA3D1103D +:10E3B000C5A7EBCCA78E4D8D3F84FAE809A6FDEAF0 +:10E3C000C34467C6AF6E8870BFFA19BC4AFFB1FB81 +:10E3D000E86BE43FA00621397782BCBF9B651F37FD +:10E3E000093BE82CE47AE87CFE55A1AF7FA988B709 +:10E3F000221D06C4B4E0946BCF37DB65BE29E478F8 +:10E40000BDF201797C2962F1CB208F2F679303FC49 +:10E41000DAD05FA8D25B3CAD68A8FF3962F824333C +:10E420009338CFC79A0948F5C719C6BBC178520CB3 +:10E43000E72D13FC7D507FFC1D486FB85F339E8E27 +:10E44000505DC8F559FA65B04B1E7FAFD16FF7BA72 +:10E45000C09F023D1D786B66E6F921B1CFCF55997B +:10E4600087701F2794F856A2FC1F558CA05FC5BE6D +:10E47000A7D9887E84E9536CF306AFB389F0F4958D +:10E48000996BD1AE99BEF80AF09BC5BA824F9DF345 +:10E4900001EB7E25776C667C25BE7E10317E86F290 +:10E4A0006A35E3BF40BB7BB9DCA52714BA921D7661 +:10E4B00056E724151807A698AFF37D043F0AA83B3A +:10E4C000CBDFA1BC68E17C85F2B4853EA8E0B2F860 +:10E4D000C9F322DE2CD4F97376DA085AFB1D855174 +:10E4E00097BDEE059530ACFD8BA86B15F6E5653C48 +:10E4F000C3BE49367BBB28EC49F5BE5D827EF5651F +:10E500007776BFFD4EC443704A54F42544FC5BEA61 +:10E51000E5F5157B11E8B3C4D7E7AA6AFF8FE2627D +:10E520008225144B5CEC1B7D91FC1D3DB1DC5F280A +:10E53000FA4EACD78E47F2591465B675415F5D51FE +:10E54000DEC750A396E74B55C6FB1E3D7679013DCD +:10E55000BE28AFBB9B94E959E919C7A667A1E79408 +:10E560009D9EA228DF97E7AA8C22C407F17938D2B2 +:10E57000D1510BFA9745BEFB26D5DE84701A4B7439 +:10E580009495BE6FDE7A0BE291634BDEAA47EDFEF7 +:10E59000B534CAFD6B5994FC4AF6752B85DCAED7B1 +:10E5A0003F5CABDD6F73D8BBBC76F67F2FAF12E854 +:10E5B000F07A139F267B9D7875F6FDB15B7A462332 +:10E5C0009F87847EA26FC77CC3D0793EF26094EBB4 +:10E5D00071784292E09E1D22FF48C38160B02F37C0 +:10E5E000541E32F31AF390CED97D7988A7F5DDDD7C +:10E5F0007958C73F3B509B350F3954D245743AF395 +:10E60000900343E4216BA23C5F3DFABF1ECA2B6A14 +:10E610002EF0385F73A14BD5413FD745B93F9B39A9 +:10E62000D0A39AA027359887009E03220F41F84D6A +:10E63000A0BA9177BB54A46BE6851E9A570363CCAE +:10E6400043660E918700152AEADDFE9ACE5771DFE8 +:10E650009CFCBE58696E885AEAADEAFE1E7A4F22CB +:10E66000E775966FCE33699FED7A736C2AA73733BF +:10E670008FEBBB136E28FDAA53FDE5D81FD8CA72D5 +:10E68000432887F7728655B2025ED7605EBC15419B +:10E6900081EFADA7F39209ACAB7DFCF9677387ED11 +:10E6A000C6ABF43F3E6117EFE5DC92147590510064 +:10E6B000F33FAB1AA9B9100FB68EFB6280F3B39E7D +:10E6C000EC6883904DED4E8DEAE93B827C1F64FE41 +:10E6D000F5D25285F24340337F01C0CF10F83DD3CD +:10E6E000787D58AFFA096E5B39CF23EF485CA4FE02 +:10E6F000C5CC7E8FAEC37846FF1A5E2FAA3F3C9EE4 +:10E7000087F9FE4734A6C2FDA56DF156D2CFD31EC0 +:10E71000EA67C8FE42556F37C92D6FC063EB73E4DB +:10E7200082274B59F2168F63CCD4E505D9FC90BCF7 +:10E730003AFB10FBA2A2FEAC64932E835C2EB14781 +:10E740003A9037EFF8DAA34FB1C1F3657FE1C149E1 +:10E75000C633A81FE3DCFDDF7E06E475E02D0FF570 +:10E760002D0EECDA757725F097E8D2A8AF2BEB19D0 +:10E77000905BD122AC675106D4973EB90AF5F2609E +:10E78000BE1C834303BA0FA6DFD77F629561199F32 +:10E79000886E398771EFE00809FF269F2FC789FE31 +:10E7A00055785EE3E0283EBE14559F4AD0FEF66BD6 +:10E7B00054476FFCA53F9B7F3C5967D7D77BAAD7AF +:10E7C000737DBDC23CF0EBAF47B3CCCB59606EABB1 +:10E7D00000791C1C70D1FB21A8B352981F3C38C98A +:10E7E0007C03E11F3DC5E57AF0AD8702B84FDEE15D +:10E7F000FD0F67F3F3BF11F1285DE74DE6FE83B12E +:10E80000010DE3D68E39CF9EA884754ECE1C3F45B0 +:10E81000051640163ECC97E57C6F1DAFE332F4BD84 +:10E82000A2AE42FFF3D6B9866CF65E15357F1FB5F2 +:10E83000C1F3F7A2AD5D1AC9BFE8D8BCDD78EE27F9 +:10E8400055D3D5A3C1FE1EF88D8B619D72A042D415 +:10E85000E143D11502BA8AAE8AAE5D33B2E81BD06D +:10E86000E5A91B3198AE97EB18C9E7C54AC387CF16 +:10E870009D7432D1C79C25FC7DCE9B5FA4BEE381F5 +:10E880007E17354F2E0DEC5651F564FFBBF354192E +:10E8900066406CEEFCB32AAA94F9886AB3BB19A748 +:10E8A000726DE3079A87DBC6CBD68ECED821FCBF2C +:10E8B000383AD636F6066FB78DC36CAA6DDC30FFDA +:10E8C0000E1BBEBA40C4369E17BCDB067FA7BEC473 +:10E8D00036BEBB7C990D7E4168B5ED794D60E7167B +:10E8E0006C1FC5274ED68633D2C7C975B00F79BD08 +:10E8F00006E9E3A3A71E0AA05EA46AE26350DFFA5A +:10E90000F27B4AB07FFD923B7BBDF6489D2AE377C0 +:10E9100009C67B83F17A4DC287CBFA6D7DF9D57537 +:10E920003C3EAFA853B2F6099CF158C66119979DB9 +:10E93000EB3BE3AE33DE2EBC6DB78FF7FB79DC5FCC +:10E940002AF4A0B5FC677EACD75F6AE07D84CE92E6 +:10E9500038F50DFA447C3EBAF4BE31F85E2DB7DCD2 +:10E960001CEE2DCDC4EB487992FD12FB3C81241B9B +:10E970005B81CF936C7505F5A5B5C8447E7F82B8E1 +:10E98000BF06AF10A7EB2D7273C6DFB06FF20B0599 +:10E990002C93AF34FCC18816007D7735EDD38AE126 +:10E9A0001AF11FD6AC7EE864CDAF8A8788D39FB4B6 +:10E9B000DBC72B641F070616BF6F1C78A385F7DD26 +:10E9C0007FD0E26329E0EF744B80AE3F6F09D2FD48 +:10E9D000575A74BAB6B794D335D512A2E7AFB65426 +:10E9E000D3F5F91683AEC75A62743DDE1227B89F7D +:10E9F000B634D2F5C51693EE6F1776FA61A1C72823 +:10EA0000977D85F8519742726DC0A3BAB32E18AAAC +:10EA1000D5CF835CFF239B5CAF359EA46ABA47A326 +:10EA20009E41BCCA6A4FDD7532AF4FEF37D125F337 +:10EA300061AC5F504F649F0EE8FB26D2E7C5FE5CD9 +:10EA4000D1F5D37750E1741D2CE4FD1BC4B3281F0E +:10EA5000FDF9D7E2B5E4CF474C267F1E649ADD9FCF +:10EA6000970EF2E72BC9EED871EC93627F91DE53DB +:10EA700038FA2005F53ACD937D90397FE07D902BD3 +:10EA8000F10F7C1F47BF25FDF6D5F2EDE4F7D85412 +:10EA9000E365C423E3F3A0F861AEA3F8512D6C96AF +:10EAA00069EF529E9827F8D9716E7101FA172F12EB +:10EAB000C8EB748355E33E33791E60F7DA92C17870 +:10EAC000DFA8E9A678BE2D9DE7BC4D79CCE0F865BE +:10EAD0009703E642D6F80E7278B3AE6AB07ED6A936 +:10EAE0003FECDF0CF1F9603FE37DB269FC7D9D8C6A +:10EAF00083072FF03EC6254D4932D8BA5AD6DC35A9 +:10EB000003AEFBBFC08AE3F8BE698C2BB41740F399 +:10EB10008E1CD07D0017EE3787E7C0F3EA540ECD88 +:10EB2000AB9D3F3989E386F8DBE49F6A357B9CC463 +:10EB30000C351D77A80956E418DF9C8157717FCBEF +:10EB40003263C0BB6EAAA9D5035F8B2F36331DF08D +:10EB50007B4B989BCE870C8EEFEB144B9F4D63A1A4 +:10EB60000EE443FBDC36FE5ECFA16F524EB2DF26D1 +:10EB7000EBF0279911C0F59CF8DBC47B17E7FB96F7 +:10EB8000F72ACC20C22B8163F4BE85AD65FC7C8462 +:10EB90000BEA1394DF304F726FE960BDDB3FE5CEC7 +:10EBA00031F564DF09E5C6D4ED5D0AD5EDA26E62EC +:10EBB000FAA75CD63A46D64DCEFAE831E167655DF4 +:10EBC000F4989B51BDD5AEE486761393CD93F8FBB4 +:10EBD000B8E61978ADA9977EE90BB63AC91FA83FE8 +:10EBE0003330355B1DC7EB11777ABF4B02E7F33249 +:10EBF000FBEDF798413CDFD83E79DD5756A2BC4685 +:10EC0000F8E8FD26D3E23AFA9BC7F1443FDA7320D5 +:10EC1000C18AA767F65765DA79ECC77640F282EFCA +:10EC200077E3F53C9F70D2E5BE46BA7023E93DB567 +:10EC3000B4771617EF25791EE913F7DB746EF70C1E +:10EC4000FD96E53D799BDFF0052CFBF828CAD93B02 +:10EC5000F4BEAAA56D01EC6777F95D64A71DBAB68D +:10EC6000B514C61D7E8DE729BA2B96ED7D5247BDA2 +:10EC700022F8E67405045D6A7831E53343ADD7299F +:10EC8000F65D8E73279A06D9951E8A63BDDBEA2F3F +:10EC900056B0CF299FAFAA57C4BE77911CB68AFC45 +:10ECA00028B7BC3BE5427D19B5662A8ACD07F9CE67 +:10ECB00079B8EF9BD84DF951FB089FED7C96BC3E8F +:10ECC00026F06D75876254BFE7BB18D6EF5B4BB378 +:10ECD000C7C387C5FEB6EA53E2089F00B98C570642 +:10ECE000C3AD11705BDC5DC100ACBB75FCBD74DEF7 +:10ECF0006BEB1872356CF48F6F7B6A937FB07DC0BD +:10ED000098F6CF1D60F23DBAEDDC43ABDED0B81211 +:10ED1000D6D55E6121340B6937DB313F81AB7BD4C3 +:10ED2000E246D4DF4BD5B92184AF535F4CA01CDB46 +:10ED3000438CFA165A61930FE97EB444A3730E9282 +:10ED40005EC8BB77A3FFC80FB96CF9794175AEC334 +:10ED50008FDAE981F548EF86DA5F277D94924F7963 +:10ED60001FF842B3319E05DFAB697BB7EB97FB0A17 +:10ED7000FA75257E6C71B22413278F1CFBD7D5F84A +:10ED8000BEE371C69F3F7F6C0ED5EDCEF18DB2F321 +:10ED900056ADAB11F7A5759C87F4CF397F6B29A7CA +:10EDA000ABB57E965837A0A0FE6FAF2ECA413FED9F +:10EDB00047876B91EB0B95E6CFEB2D71B830DA4CB2 +:10EDC00071F8BBF58CE4E8D7E38171A017FE5E15FE +:10EDD000740AE4EEFAF31FCEEAD72E47D66590DE2A +:10EDE000FA59E6F76790CB30C6F5C4CF1EEBA1B851 +:10EDF000C436109C94D7F65B4F86526CE875FDD5EF +:10EE0000F63ED307ED23FDA93EBF98E49CC37250A4 +:10EE1000CE97D8230AC5E1A841761748FB557EFE58 +:10EE2000A4580E811D1C93CA2999FE12C3F71768B6 +:10EE30005F26A33C8520478A57573AED0BCD1B2D03 +:10EE4000D0DC8C076354D47FEE772FB1B7F8FA305B +:10EE50000DCF9F280917C5CB5B51AF01AE94997FA9 +:10EE60003C9BE55CCE9840D3BED5702D9E27FA62C0 +:10EE7000829F2BC943D2FDB7D25B19E79DFD50D9C4 +:10EE80002F7D06FBA5CA95FBA14CBB48729379ACBC +:10EE9000B33F0A712D0FE5FEDE048D7592DC791EFD +:10EEA00090A9D74D9FF51C9D8C97ED81C5B63EFB73 +:10EEB0000CA94B0E3EBF7785B8D8D90B7E13F3E172 +:10EEC000E066EAB3EF3FBDEA38D6E397821E9D596C +:10EED000FC7F7BBEFD3D80C4FBF979A29F3EAA9ECC +:10EEE000E17CADC76478FECE130C515C6855B2BFAF +:10EEF0003F689D27F209679C70BC67F99F1C7FD211 +:10EF000053C6D2F14315FE59C657A641141D699D3B +:10EF1000CFFDA894C77E9157761EF9049D176041D6 +:10EF20004BFFB62CCBFACEFCCF30F4C0F44C3EAA4B +:10EF3000F4F33C54AEDF2EEAE7D6D37C3F72C5B97A +:10EF4000A141FA5A617E7A1EF67FCA5D8E3E95DD3A +:10EF5000DF38F35AAF8F25722DFE0FF2DA8DF328CA +:10EF60001FB1E7A5C3638C9FEF293419F6712241C5 +:10EF700053C5BECBF4DE669501DF334EBFFF7E2C5A +:10EF80009AC7F39CF6F25571AC7F641F79C79CBB9E +:10EF9000C8BF421CDD3ACF52C7CA730B1FB4AF249F +:10EFA000F575BAD847896FD0F992D91BF8FB9FD372 +:10EFB0000F9D407DDC0FFA8871BE3D3FB1AD02F37D +:10EFC000935754B6571FDC8772F225FB49FE18D7BA +:10EFD000534FB0FDE85C97453EFDCDAA4EF2311887 +:10EFE000BEEFD1C4FB1E67FFC8EB359A317EA76A1E +:10EFF0008C466BFF58CA6D91D0E7376A9AE97DD489 +:10F000003343BCFF9570F89918D6D3B21F553AC94F +:10F01000FC3EEEEBF4D87A15DD48757C3D9DA3CC23 +:10F02000FB77467520CB55927B61A923739EA53A49 +:10F03000F1F74146FD320FD689C55817F23A51D63D +:10F040009FD24FD4A94F7794E1F98C5E8DCEDBE54A +:10F050001DF9840FF3DE70EF6AAAD50C65691EEE08 +:10F06000A33C7F24E9BCDE3AB30AEB4CCB7B928C09 +:10F07000DF88FD02F5A0B325FE8B28E8C781168343 +:10F08000C6ED2D8D74ADD29206F253554E951B9B55 +:10F090003500CF2D7454F5C46CE31D95E619D4CB1F +:10F0A000BCF2B8EDBE3708F82C7A0175EE3992EF54 +:10F0B000692E4FCF7C85CE152CEC675BB86DFFD3E6 +:10F0C000F8212D7663FC504EEC7DFD107F5FEAE960 +:10F0D00017EF4B1DF6B6679E4E7690B63B7C6F4A97 +:10F0E000712E41F3E9DDDF4CE067D827B9DFCA9C18 +:10F0F000CFA0EF12C3E27B693D366B0FE6B3EDAFF5 +:10F1000033F99DF01EC3F21CFE6AC2EF440E63B1D8 +:10F110000B79E6E65861137D4F2DBE87893416962C +:10F12000F4B1CCB945A7BCB6C45CB6733161C6FBBB +:10F1300062F2F92763A26E03765C96730FB978EEDC +:10F14000214BFEDE24F0350B397578F8B983B98E82 +:10F15000EF3C66C6785D30D4771E9F1378AEF45DC1 +:10F16000C76201773FAE5745E722C331A4372EBEB1 +:10F17000CF1274CCEA4DB60EC32431C8B2E2B93313 +:10F18000C6CFEFA562FC3CB1276868B82F80EF6E50 +:10F19000C2D7C8CF59CAE7B32EA49F2F243D69E038 +:10F1A000CF675D30A91F24BFAFBBF3F8D83D9BC626 +:10F1B00065CED7B4633FC28FDF99F0734BBB04FDBC +:10F1C000CEABFCCEE4DE8038A793B8758F81780C87 +:10F1D000FE5D65EDF10903098DD6FF18D127BEABA1 +:10F1E000992CF885FBAB882EC7BF0FF0C0F1E01E4D +:10F1F000F13DCE1A9AD7CCE9CEFC7B07A13DD6EFE4 +:10F200007B261FAF6C12F0EB087E2D87CFA20F423A +:10F210001FA7ECC15EEA55E0FB0CD1B79CD3571693 +:10F22000D3F977590EBD05B8CFD3BAE23B9FDEF8CC +:10F230006A1FFAF3CCF7FBB7D17A5721A736C2631E +:10F24000CAF59838CFC4ED42EABFD4876F08FDBC39 +:10F250003DA648BD7A8CE86DBA61FC7F89E8717C77 +:10F260005774253E2A2AE34FD0BC60FA5CF1D78957 +:10F27000AEEBA4477E07E6B48BEF0BFE61DDA7691A +:10F280009D92109D2F8275BF7D23D605BCCF101E89 +:10F290005F1AEFFE58767FF381F0B292E2AB3A1F2D +:10F2A00022C7FF0F94B0BE363046000000000000B9 +:10F2B00000000000000000001F8B0800000000009C +:10F2C000000B93E46660F8510FC181486C62F11A3B +:10F2D0007606866816068699AC0C0C15402CC74934 +:10F2E0009AFEE540FD8B80782E10CF00E2C940DC0D +:10F2F00007C49D40DC02C49240F34480981F88B943 +:10F30000809815881980F8370703C3370E8439377A +:10F3100080620F48B41B84AD7810EC3340FF6F045B +:10F32000E2AB6484C3281E1E389D9F81A15A00C190 +:10F3300017104495CFE047B0B94429B34B1AA81F22 +:10F3400000656D40B4800300000000000000000074 +:10F350001F8B080000000000000BE57D0B7854D5E2 +:10F36000B5F03A8F79666672F2204C4280134830CD +:10F370006A8A03840882F52420C696DA9152C5FE73 +:10F38000D60E34224A2051B1722BFD726002040164 +:10F390003BBC1414E9E00D8A8A362256ACE83F20C3 +:10F3A000B5B4B56D6CB9D55AED0DB5AD2F0C88520D +:10F3B000FCFBEBE5EEB51F99734E661250F1B7F703 +:10F3C0000F9FEEECB35F6BAFD75E7BEDB577DCB232 +:10F3D0000FF287029CC49F8B00EE7003C0D8743A72 +:10F3E000EAB66FCC7DA49AFCFE7FDD916D7ABA9E61 +:10F3F00048878244EB01180045001779C9AFA4DEA5 +:10F40000A49F1FFED37985007B41010FF9945227F9 +:10F41000157C8DF4B3F7238860B9FCF3406957007D +:10F42000DB99B4DD9781B54B95E9A55A156640C6C1 +:10F43000EF8697FE4EFA19BEB999B43FFE6180B6C9 +:10F4400077C22152F84886146F737218F6AB7ED0DB +:10F4500055C9F3654006070EEF64809A34BCFB5F24 +:10F460007B83C2BB4F25F0EA19C6F712F80BD3F025 +:10F47000EF856FE4421583DFA849C37FBAF0D0F966 +:10F480000F0058DEA23F5DEE0258DD024F97570095 +:10F49000AC6CF1D2FCD2168DE6E32D619A5FAE9290 +:10F4A00026040FCBDB216992F6A16A525FF447FE76 +:10F4B0000B54796D79772169EF4DE7D540D896F7F0 +:10F4C00096EAB63C01E76098CCFB1C3E9FA52D0454 +:10F4D000071E1CDF0BC65958FE6D8A171FC75B3C01 +:10F4E00038E2CA61042F6D2F2A84D2002EDD988164 +:10F4F000F09507DC7A92B0C63981D9536124193767 +:10F50000140320F5E21B00D612B8CF0E4C790B4243 +:10F5100000F793FEDB48FF4AA8ED650F295F51E62F +:10F52000D615C4CB76F52F5D640C2FF987783B6B2D +:10F5300023CBA7E745F296799E0D9672D2FE977976 +:10F5400077BE2C1138E2E56EDD23A5C7E9A14B3F5C +:10F55000FD5724EC7967FFE5BA51877C2AFAAD8024 +:10F56000E8122DF0C5EDF71C82DB82FC74BF629CB3 +:10F570007EFB25E48F92B6151B21992AEB3D4EB9EF +:10F580001EA9374979F946159265EC7B219187725E +:10F59000F62B2C2FADF3C7AA7AC303D67186A5E943 +:10F5A00052AEBB67CA842FCACBAF982B11BE8184E1 +:10F5B00085CEC31883A2BCFCB045A3FCB8BAA59203 +:10F5C000A6ED2D5A07959F8F95191D55BDE5F0AFF6 +:10F5D000A8A748BB3B5C40F9D0DC06C96D12F61702 +:10F5E0009D3193E4578D2A1A7DBB8EF91932EA05B5 +:10F5F000C1DFAB249DF2B749F81BF59F533E56BBC4 +:10F600008CAF607F2B46C9D212C47339E3F77257AF +:10F61000CA3B1CFB4D0C1B65623F91DF7561BDF25F +:10F620008A11BA42C63DBB9CF1FF2FC7DEE9453DBA +:10F63000D833FF85451DE56300721D7CA09D221F08 +:10F640006813FBE60331CE672D0F678EBF127DF284 +:10F65000D7AAC8DAB7506FB49733BDE184AB7868E6 +:10F660002A1C0DF4E6B7F272C26748A748DF7CE6B1 +:10F670004C37B424E175C243EB5AC294EFD6B4E8D8 +:10F68000345DC9F9D0853C554CF29C0FA1B09AE687 +:10F69000B3AE57B098AE4703A6272146E05C87FC7F +:10F6A00079017E5F6A18A5A479A5C8434A26BA7F66 +:10F6B0000D9697D0BC01A5C89FA2FC31D320EDF3D5 +:10F6C00079FD29D263669C20699D8FE5EBA56EC309 +:10F6D0002CB5B65F691813D3F5493E55576EED8FBB +:10F6E000F45F6585E7395A5FF4D7201D324C925F8D +:10F6F000E363FDB5492F7F2EFDDF2E25C2B8D0ACC8 +:10F7000070F473BBC89B09C3A84A8F53B6F851C3A2 +:10F71000B496C3A3B6F29AC509D32478BB0BA2C38F +:10F720002542DFE2A9D13010FAFBA2491397DA345F +:10F730007C0CDFE9F9DD49E1F597B3F22AE9F746F8 +:10F74000DC429F5AE93726C22FEC1B85F3ABFCF352 +:10F75000D29B5F20FCAAE4BA23D4CE282499F1647A +:10F76000BCE931D0091C723806A80F94B0FA77AB07 +:10F770001C08FE23708EA3704E8ECEC802A769852A +:10F7800053C0D11FDC028EEC7CCAC677F253DD6514 +:10F79000E37E3B91B0B8AFD315413BAF00F144F4E9 +:10F7A000007CB4CE7091EF05D308EE754AB71930DE +:10F7B000BC77BF85534B206959C73F6BBA0EC7FC56 +:10F7C000588AB7EF4863D3F425F999563C8EE3F590 +:10F7D0009CFC27E6E7EE35BFEFDAE6076A221C0D50 +:10F7E000F63FBF35BEC88C68A077BD5F4ACC8EAEF1 +:10F7F0009B32EEEBC0C6030FD15F7938DEE8F478B8 +:10F80000795F21E361676A32E378F993C978DE337F +:10F81000874FA73C0A787DBDE05D6783F776179137 +:10F82000DB0CF43FD3F09EAAFCF989FEA5F257D970 +:10F83000B7FC7DD6FDE5E1AF849FDE57217511C190 +:10F84000D7828BBD49534AEBB9CF1B5F055844E8BB +:10F85000B7E0D7630E5D246386F0F597D2E3CF97C8 +:10F86000740A7736FECE361F80A4AD9FFF57F3C9CA +:10F8700086D733AD874E55BF2EF9839FEEEF969610 +:10F880004312E569E9818BE93E73E90B930602E9CE +:10F89000C7D5762E18645279DCCE588A7606F63FA4 +:10F8A000F9D4EC8CDB5BA0A395185D4F84A2D42E19 +:10F8B0005A2A016DBF8AD86D4962BF54BFD8EE9DE8 +:10F8C00019A076154D97BA80DA31D52FEED726914B +:10F8D00029F82BF24721EF2FF589EF07EBD1CE5D09 +:10F8E000594EBE13D6581A64FD91EF51AC9F53C1C7 +:10F8F000BE67832BA792C063C1BBCF9D8C65D28F9F +:10F900005F96658A9F4DDCEE5A8D761751C83E7F13 +:10F91000228676B5BFC8ADDF27F56E37436676FF22 +:10F92000FA8A9F98E8D25881F61B99FFBECBEF87E1 +:10F93000AE2A5C0713868CED23CC35B0C9B1DE0747 +:10F94000D086A3EB66589A44D64CBF23BF5AD4370F +:10F95000F55AB4D74295ACBC76C985B5716B399C64 +:10F96000578BEBAE28BF66C9585A5EEC8DBE3C91F2 +:10F970008C5F4CF4679CE0A9584D48CD949E99F952 +:10F9800065FDB5DE194902C3FACBEF2CBB36039EE9 +:10F990000815299D45BEA4C12E5F9B38DE56733CD9 +:10F9A0008651C62D7ACDC7AAF6E835DF594CAFF996 +:10F9B0002B138B11CF250D10413B7B3DC15FCC320A +:10F9C000BEAFD2AEDF8A55FBBCCED47CEE02E32ABA +:10F9D0007940F6FE9DF27517C46662FD62BE8EFB2D +:10F9E0002B9352ACAAFFF93BE79B6DDE5FE5F82451 +:10F9F000E3CCCF34CEE78597E20019A7FAB31FC74F +:10FA0000DF60D793A78A77686C37705F8DA626EE84 +:10FA10009B7D303992A2FBB9DBA81FEE160E3BC4CA +:10FA2000366968D7C40132EA33B5DC9DF6A7E1FF39 +:10FA300094AB7333D145A40B5F7D2F6FBFA57E526E +:10FA40000E16FE3D87FC723E9C7F5249B707EEEFD3 +:10FA500053051C817CDBBC4EB41CCDDB4FF4C61AB5 +:10FA60006D1AD5C7D9C67B90E8D11491AF075ABC9F +:10FA700034DDD6A2418AC8D9BF1379C3FC56227F90 +:10FA800098FE88EC1731BDB72542CBEF691947F3D3 +:10FA90009B5A0C9ABFABA59EA61B5AA2F4FBBA9622 +:10FAA0001934DF83CF8FC87835946501EDAAB36729 +:10FAB000244DD463B003221504BFCBF1BB05FED5A2 +:10FAC00072EDB332FA3D67F8A87F23C8E7E987A44F +:10FAD00081FA1B0E2AB00DB2CFEB0E3EAFAF28322B +:10FAE000F39FAA957470414FB91DA85FA5A89AAC61 +:10FAF0005B44E5E65ED89A8FFC5E54CDBE07038476 +:10FB000091C877A51A52BE101D5AC5F61A6FDF3676 +:10FB10004EA6F5566B2A6DEFE48B73A193AE33605E +:10FB2000782308A777BCCAEA57B1753278FE3EA49D +:10FB300020B44D94E9FAB9BA9CC1A168767E09D681 +:10FB4000DC0768EF879561741EAB2F50370D473681 +:10FB500080CE9787937E3690AD0DAE6B0F6CDEA98D +:10FB6000CDB4D0D9AB30FBFCDCE93BA315088F4A00 +:10FB7000E49A8C5FB8D99FC47587D0434178737C71 +:10FB80006C3EE7E298048EC24590BCAF2C5D1EC867 +:10FB9000E3F3D18C5AEA9710DFB9E23957EF48C93D +:10FBA000D86E2344EE8374B94FB433ECED7CA29D40 +:10FBB0009942DC42E12A7B3BBF6807B5B6767ED12D +:10FBC0000ED61A74BC0469A7A7CB15DEAE47EE2B80 +:10FBD00035D92A674A409799DCD8E9948D7F34E07B +:10FBE00074D8674A27115FD52C2F49DEB69332AE01 +:10FBF000B3763AF951CEAD7A2660C913D245517623 +:10FC000071BFC6E9953433D36B9D1AF94539CEAF30 +:10FC10004AB5CD4FD0699D97D3D1F467A4D33A8D1F +:10FC2000D33106363A0B7AAD13F46AB4E34FD06B96 +:10FC30005D167AAD13F46ACE4CAF7559E8B54ED067 +:10FC4000ABC1DE4ED0CB490FB1EEA4E9D62C21DDFD +:10FC5000CE143D9C7AE10559A7DFE5F6A39D680F18 +:10FC6000162D50D93EA9B21350CF43697E3F76ABD3 +:10FC7000C9ED93665A7F2DFE2AFC5F28A76E96BFBA +:10FC8000267EA816EDF07C4994EFAB457F5812CB49 +:10FC900089FD7573FC382D7F528EC614DA5F1270A1 +:10FCA0003FE2C497279A848D04A40A357A6905FA3D +:10FCB0002537CB11F4DF0A783C20F004FCFCE6D4B5 +:10FCC000F81F80E10BC13B39FC94E0BC45A1F84C26 +:10FCD000323C39E124FBCB8D645F3384F3F710F3BE +:10FCE000CCC0090D6CBDE8599FB99DE482CCFD5490 +:10FCF0006E966D7C3362BDDFC637E5ABF26DE5C352 +:10FD00005A4B6C797DD1305BFD210BCEB195973686 +:10FD10008EB69597345C60CB87AFAEB3E57BF10BC5 +:10FD2000CFB72BAF2CB6F18B39A20EF76D496074AB +:10FD3000D81E1F5187FBB6FECABF7E8B6A7809FEAC +:10FD4000D542375D870805297E04BE723530DDE86F +:10FD50001F280C242F21E57ECD30A93F403300F72A +:10FD600073B216A37957D82E5F5F4301227CFAF550 +:10FD7000AD2A780BFBECDFF824FDF7372F27BF887F +:10FD8000F55D2964EBEA06B25DC2F33593E8C76D11 +:10FD9000645C97C6D67597E01FC2CFA8573455E26A +:10FDA000F27B7A72367CA31DDEB2843D3FB4CD6116 +:10FDB000079E227F7F5EF2DB1FFED641C4544E01B8 +:10FDC0007F1155E2E7D5A727FFA58D76FC9434B8BF +:10FDD0001D72E2D0E79F33FE5AC57A01D13AC44B77 +:10FDE000CE7AE64341BB2B935D21F865C3F49BFCBF +:10FDF000D6F50CACEBD4B0F43834AF64CA7FD1F88C +:10FE0000A4AB16ED8B9C8564FE65CC8EC9387F4E05 +:10FE1000EF755365BFD50EFBA2CF3F4DE71F9C5634 +:10FE2000FB700FBCA51ADDAF89BC635FD6BBBDC933 +:10FE3000F44DCC275BF524F9A954ABD135E98F20DB +:10FE40009F9DF08546422ED91F7A597AA6F76D0FED +:10FE50004C67FB12F3D59C6405E293C771AC7DF54A +:10FE60004B4984273955863BF19C79B29CAC20F9EB +:10FE70005BFDA1FB10AE6F2AB15BD50108EF9024AA +:10FE80009E1783AAE74D0B5AE6C9ED2231FF6CF6A7 +:10FE9000D192D69BEDEB194CAFB3F2E35DADCB69DC +:10FEA00039B13B5A554AAF2F8A7D9415CE4DEA178A +:10FEB000D83E12E703CEF6FF2AF6D101B57189DDEF +:10FEC0003EDACDE8008C0E2FB4EEAE3B9572611F8A +:10FED000F9036EBEAF77D82F95C43EC2F3A300B727 +:10FEE0005F2A93D45EF1552699FD5229EC19FB7ACD +:10FEF00076231AA063D3F6511FFD1B9FA4FFFEE6D5 +:10FF0000956D7DF705847D9460F611C135C69928FD +:10FF1000446DF846225FD8D7F76A5796F5FD7F8C77 +:10FF20007D94597EFBC3DF3A4830FBA81FFC4DCFC0 +:10FF300086BF7F71FB68BB0AFF9FD947D9F8E47F72 +:10FF4000B67D94A6F36763E738ED1A61479C69FBB9 +:10FF500046D827C48EA1769649EC2CB4734EC89A25 +:10FF6000EF4E32CF5B15DD877EEAB55C5E17AAD116 +:10FF7000352EBA7EEB7968676C447D3E80EB59B4D0 +:10FF800083023C3E4F8DC0B42F61FDD84697E51CDF +:10FF90004209E8793DE7365F203C103BAF522DB473 +:10FFA000CC9FE345E061972B8FD3BBF9FC289BD70F +:10FFB000E3140FA04BD4DE52751FA64FF3F58DAEA0 +:10FFC000C7D5567CB0BC52AF27511E48FBA75D0376 +:10FFD0006C78F1D9F042D621361E28CC9E336DF1D3 +:10FFE0006CFE6A4D42BF39C97622FFD2F3721D20E2 +:10FFF0000889FA11A4FF82D8B21B311E33F8EAA592 +:020000022000DC +:100000006F615C6341D74C1ADFD85A35FA401DA99D +:10001000971BD12E9FA2E3BA0AD4CFB8023BA3E725 +:10002000A110AF0DF0731C22DFBF597A9CAF9B0665 +:10003000D8ED725957853F69587679213FD2494F9B +:10004000EFF6D9E4C365956B2A9F379D9A7C4E6580 +:10005000726D927FA82FF21CFDE41A8EF304B0E4B7 +:1000600049F9879C8F8985F2B98CA7C15AAF4EF8A0 +:10007000CD552E6B181F990B5A1EF29F7FB20A297D +:10008000F4BF141E35D105DB1F5D5AB91F1D25F0C5 +:1000900072CB7E22E866F21A9ED55AB68CF47BBCEF +:1000A0009AC5DF1768E4BFD1BDE7B392CB574FBE07 +:1000B000EA3E7A6E1A27FC340CF9B84AA6F70856BD +:1000C00094333D2EEA9DE7966CF7082CFB365DAD28 +:1000D000E1F634C18F522E1B68077C5AFE503E2138 +:1000E0007FE44CB5DB05A74BAF89FC5EC5A9F2C721 +:1000F000A71D4FD0B5B75C2DE6746DF0A2DDBF2C07 +:100100003CADCF73D4DE745D4BE9EA2F072399A190 +:10011000FF5AB794317ED6B93F72DAEBCAC09A194A +:100120005BFBA25BA1D32E63FDFA162AFA5F51791D +:10013000A91A5D07BCBCBF15FA5A13D793E36833FD +:10014000107C28895129D49F500EF41C111906CF18 +:100150004D7DBA41F7E17405AA49C3E72E956DE3D9 +:10016000A9857EBB5D3DC394ACF0FB16BA291C5E2D +:100170001C0FF5B4C6CE3DD58038F774EC1F1D7644 +:10018000C3F2D2D119E30CD4CF6ABF3ADD0EEF2906 +:10019000B70BA8FADF2D7654F6762AFCDD624FAD58 +:1001A000427EB7D07F990B764B641D8E87AF8098C7 +:1001B0004EF258540CD086E978E4C3D11A5DBFB62C +:1001C0004BF47C988AB48EFFB173A2ABDC3AED4756 +:1001D000F6C6289E948001B4BE7E6AE7482706B31F +:1001E000B8A56112D8EA3FEC76D37215A2F43CFDB3 +:1001F000C46B978469BF06F9549386C3D9EF55EE53 +:10020000D8C36E6CA73178B001F5478C637E81B09E +:1002100097B53B31B3EFB8818D285F6759F23C2E1B +:100220000BDA4E2DAEEB0419B3B38AF2BF1FF7B54C +:100230009060F6D0504EB3AD8BF2E9F7ADAD7DCB0B +:10024000F9DD5CCEB770FBA81DED238BDCB7F3782E +:10025000B36D12D8EE595478587CD63B5CEEB77A21 +:100260004D1FBDAFF0DC0ADF088C7739A8447C0451 +:100270000FE5D71AF9B13EF05091B0CBDBE9C67764 +:10028000BCEACE1CDF91ADBD88EBF8B478D9C6F7D7 +:1002900031159ED971BA6F495D44E5B398F34DF1BC +:1002A0001CA076ED5013923AD6FDE82458F983FC51 +:1002B000EC433F454903190BE915930DD41F251B4A +:1002C000DC4999CABB763BB60F1F5458AC21188144 +:1002D0009935945569FBB0F2422D8ADA706E9FC150 +:1002E0002AFBBD8BD245F6FB52258E7B1261B4EF03 +:1002F00042E877B5D42BFBF4F40879083DCEFDFC39 +:10030000E9D1AE1A7ECDD2BE5C82684786FECA3D78 +:10031000CCEE285FB39EC5813504E07531DF6148BE +:1003200057231F17832D89FB16E3399BD9C0E26B36 +:100330000635826CE5E3319E1CDA8F0B0CF32C82C0 +:10034000B7A5DFBEA2EB19A4EB44B0E9B10CFA6388 +:100350008C87C88BAB90E98FF6C434967EA4D0F519 +:1003600023BC08924B08889363B1C52EA4FF1CA040 +:1003700071E8E186E6BD185F5DDC08111C86F015AA +:10038000E5AFF00C481A945FE06098F0C76036154E +:10039000188C7C81EBCF02465FC117258DF6FB36AA +:1003A000E1067BBE88DBFD45CEFB5B8E7E8A7576E3 +:1003B0000F4A5F2403DEFB83E9F6FB3661E87AF03F +:1003C00001846F7F2092427E351DE338FA572176F3 +:1003D0008587E0F389EF4FFDE559A4FE8F16D5150B +:1003E000205EB67AA3B9F45E515BE6B8B35EFC2A30 +:1003F000EC8E2CF5D37AD4B4C5353BD3651545378F +:10040000CF2270AC081A40F59A7915D5EF0A97DF1C +:10041000E78AAFF0623CE9D2C0E85CD4B37B314FED +:10042000D2A5E111346E57F4A3F0F85D918F737D7E +:10043000EA1CEF160FD3A37F07E316C4C3284F2C83 +:100440008CF376858B1E9FA9D3F3422399A1DD758A +:100450001E3FB32F75F59F56FC93055CA372087081 +:100460005AFE85599E581BF2A75947B613C8FFC3B9 +:10047000201947FA3727B8DFBDA7DE6A5ECFA47E12 +:100480004F512F9600EBBE93D45B8BF321F50C5BA1 +:10049000BD68AF7A77F17A601BD7E835EE66011F49 +:1004A00058FB8BF4EA6F2BEF8FDA833DF5F45EFD9A +:1004B000DDCFFB336CF5B45EF51E16F0D9C605FB37 +:1004C000B83DE5E7B89371AAB7593CFDBE8A2994B7 +:1004D0005FF6574CA99F45C6B9F9172EAE23AEA1BA +:1004E000EBB6E0ABBDBC5E2BF25515DEC385B64660 +:1004F000BC07CCEF09C703D3BC31CBF71EBE0A4CF7 +:10050000D3327F9F65ABAFB6F9C01843BFD3FAAD06 +:100510001F2BDCEF9D3719FD71CB0B65EE9FFB5B4D +:10052000DC50891E1BA0DAF26D61563ED2FBB7B8D3 +:1005300089778AF83D18A22B9FAEB2C877CFF89F73 +:1005400017FCFC3C230DFFFB71A3DC0A3FCB0BF82F +:1005500045DE5BCCCA47B7BD3F092F56897B00C338 +:10056000DB0A5AA9FFE20B3B3FA9D53E3F964FCF8E +:100570008FE5C5FCAADBA4C9FF5AF3CB6DB5F31F09 +:10058000CBA7E7C7F2627E356DB9A7353F673DBCA3 +:10059000AF847A7E45C5FD615C7756E0424AFA1D1C +:1005A000D7F6527C31C9DF3E40D8DB3AD5EFA3C045 +:1005B00038C73BB6FF76BFC2E037D2D61B64E7C16F +:1005C00050E1E6E7C18930FA39DFF0683C8E8EC130 +:1005D000A978EDF9A1981F90CE935FFE89EB308644 +:1005E00029B2FDA443CFF7B3AE2D2D66EBC9B2609F +:1005F00044B6AE6B220EFAB9013554FFC435A67F5E +:10060000F60EE0FAA890AC6BCC9F47EBBBB8BE5A95 +:10061000DBC2DE0B48F0FBB0F1C2D1143F09711F01 +:10062000D69C62D36FFB6AA71C40FFD5B183EC9DBB +:1006300088A7BC6CDD5BDA021DECDD032FBDD7FDA6 +:100640002CE937462AEC21F61EA63F25F61EA6BB4E +:100650005BC234FD498B4ED39D645C4C1F6D894059 +:100660008C8CBFA3651C4DEFE2FBAB0D682F92F4A1 +:10067000CB8532F55B6C6D2196B20BFDBD5E9ADECB +:10068000DBA2AD522BD0DF1BA6F963D2B4EBBC7456 +:10069000FFDA15CF25703EF1BB727A4F7C62A14A1A +:1006A000D75F50534A6E75FABBC0EB31A9AE11DB70 +:1006B0005D1096593D6F321ECA5CEF46AC372EACCA +:1006C000527820602AA1C28CF5BE87FC5513E0FD4C +:1006D00069B17830737FB7617FA303BCBF423D1E11 +:1006E000C8DC9F89FD8DD4181E20DCB5242773BD7E +:1006F000A558AF4AE3F32D4DC93999C7BD1DEBE5A8 +:10070000E727E8FD9D8BAE066A8FBA0AF5ADD46780 +:10071000C1EB25074441267C9E5F9068C67A17C6C8 +:1007200022308C8CAF872220137E7605487915DE27 +:100730002527FD9074C274528EE74258FE254B392E +:10074000B627E9F819BC7DAEBD5C8CE76A839EFBD9 +:10075000D37869DCD56ACFE7C94C3E1F6ABB6A32E1 +:10076000CA7D1E3F7FFA35E6C9B8AE4520F411AB0D +:10077000EF67E5CF88FA2156FE1ACFE7E7B379FB9A +:10078000A67869BCF0BDB78C289E55959EEFE0EF2A +:10079000559E3DCB32BF7BBF7741F1AC407A3E8363 +:1007A0006F9D78F6AC3EF63D05F572CF9B24A8B759 +:1007B000F21255547F8EF244A97D386A608D81F221 +:1007C000ACAC6270BDEB2D6B5DA252B84C7A4F930E +:1007D000C375CF3C3B5C83E6DBE1BA67BE1DAE412F +:1007E0004D7DC3F59497E9B56CF091F10DEBF85B95 +:1007F000FECD3EFE90EFDBC7DFF27DFBF8436EFBE4 +:10080000D4E3A7AC74D97CA37DFCD29BECE36FBE90 +:10081000C93E7EE9CD9F6EFCCFCA1EBFD01BFBA791 +:1008200097DBBB8AD5EE6C8ED9EC5352EF24AF67C1 +:100830002A563B3616B3D9A7A49EEAE3F6AEAD5EC0 +:10084000B4573D9F8FDBBBB6718D5EE386787F2901 +:10085000D9DA5FA4577F05BC9E295BFBD37BF517D4 +:10086000E6E31AB67A5AAF7A83057CB671C13E2E9A +:10087000F038B05B791C189577527FE1D5649F5DA5 +:1008800086FBD0A884FB7DAD0046EDC7FB26C3D90F +:10089000BB477953160EC5F55C9AB2F02C5CFFDAB3 +:1008A000F2C0B66F9BE2637E84B13E85A65A0E34D9 +:1008B00053FF9DB7B9F872CBBDD72DBC5E4F79A061 +:1008C000B9F81B96F24B78FB367E6F70B2EFB7D457 +:1008D0001ED10691FA19FC66978AFE783914463AB9 +:1008E0000D02F75D574D1B6BD5CF5B7C2E3A7F6DAC +:1008F000281FB734335C6D656CDC7B71DC007E17C0 +:10090000F6477331C5B7C652F17D4370B6F457C48C +:100910006ABB97AEEB6EBEAEE7B99B1F282370C4CF +:1009200007CB80F7229697F6EDCF696DB19F2FA880 +:100930005AD4C07D5FC91C6D348A47B67677D7CB51 +:10094000F599CE1F1AF87C5AE7D425CAC9F8B0DF4A +:10095000EEC7250C0ED6FBC857B9630DBE4C7EDC26 +:1009600056AFCDBEC92B9A960B7DCC23DE62F7E342 +:1009700012D56B64A2DB4A1F3F1F39E8B5D95B79FA +:10098000F932DD771EAF62E7066016533F610F5EF6 +:100990004BEABCD6F15738C6F3C13403D7015CA685 +:1009A000505EDCE5EC5D157F61422BD3D17FD049F1 +:1009B000CF0381DF7713FDB686A7D1FDF8717E0FD7 +:1009C000560D276A99DF91C3A7715DC5C729D9A8BC +:1009D00042AA808CED8AADF48DB5D2CDA4F74B4EF2 +:1009E000B89297D2F79ECA08FDA5DEF3BFD3C7FC25 +:1009F000C577EBD37E5B9681BEF7A0B3D8D26FC923 +:100A0000876E488DC95E3F5D8FC1D5C3B761C2AFE8 +:100A100028FF3AE75BB7F1235FA6780BA11FF839EF +:100A2000F8AC71C07FF42BFF44E671FD01177B77B2 +:100A300041DCB7E1A5D773BFE92CEE776D8068087C +:100A40000BDF05B91EE5EC5DF85D688C85FE4FFB9C +:100A5000DC0CAE3617F5778973DF6B132E9B3FECFA +:100A6000BA8DF6FC6C9856847A6BF67A17F5AF5D02 +:100A7000EFF0D33ECCE77B1D342F433B5EDCDB9EA7 +:100A8000A5818AEFF2CC7BF2DE1ABC1FB5CFC7EE90 +:100A9000EFBD4DF846B7C8DB0D81A41BEF01BCBE0E +:100AA0006BCC151300DB279795A0BECD838CEFBED2 +:100AB0007DB7CD0E5F7FF03BE10558D2271CEA766B +:100AC00029A37FABD327CE8919BDB2C57988B88B4E +:100AD000639C8F7AFC307FCEE17E18167FD15FFB5E +:100AE00013FDB49FE7ED72A3FC34A9CDF5929C3EB3 +:100AF0009FF2B862C620324FD7EEDAD420B0D56B61 +:100B0000EBBBDED12940F5657314F948D49B0FA4E3 +:100B10001ECAE59ECB4D5BBD72526F78F67ADD5CE6 +:100B2000AFFE7CC7BFBBD11FF9EE43872E43B99CF4 +:100B3000FBB4025E326EF78E20A4E83E36E9C6FDB5 +:100B4000DC0DBB948CE7B9346280F43FF7C741BA3F +:100B50005EDEB0D3939C4ADADFF093D74702C143FD +:100B6000F792A3CF0FC275F721899DAB9A5D2371D0 +:100B70005DBB4185EF4433F437C0CFF8F0F0533913 +:100B80003390CED2F6BDD7D07E3BAE74792CFA220C +:100B9000E077897ACC1FF7A044E3A37BC3C7CEC11B +:100BA0000E3F2831F876BB923E846FFB56778CC09F +:100BB000D1B4FD3DCA57937EFC4808F1D0B45BB177 +:100BC000F9899BB62B29CF489A1EC214CF57A41A75 +:100BD000C427D38FF377CDA3FEF3F91D2BDF534248 +:100BE000D8DECEDF042F9114E2F525253215F38FE0 +:100BF0003F10D209AADEEEDC1642BC927E67BA73C1 +:100C0000F11CD8EEF7C6FE3FCCEFDD1FC05137F226 +:100C10005753C70A36DEAEAFBD81FAA5C921476F6B +:100C2000E32FC5BDCF5D2EF43BCEC1B6179C927DA0 +:100C300039F791E35B4C32EEE19DEF6C3109FC8DAD +:100C4000FFF5FE96DBD00E7AD6A7A11E687AE83FA4 +:100C500042605937AFF43379EC7EF081FBEF26F236 +:100C6000D1FD470F5D3FBA9F7963884EE6DDFDD821 +:100C7000FF29D249FD05CF5C4CFD050B9E9834B091 +:100C8000AFF513F935697D978CDF3FD77793710600 +:100C900092EC1E9E3AE8F3DC2E057C04CE775FF6DC +:100CA000D07B524DE4DBC2D148AF79542F637E1123 +:100CB000C1F3FC1DCBDF534666C2B73948C64B07AC +:100CC00040C4308CF4FEC6D72FACC6D445CF579A5B +:100CD000E028D5ABCE764D07095DCFCB4EC7E3F00C +:100CE000911BE3569A76AC60E376103A867AD3F19C +:100CF0005DFC657C6F3A7ECF41C7E3D0F8233C1F93 +:100D0000845D0519CF85C5F9D9BC27BED9A7BD25F6 +:100D1000F4427F789E2331B8EAFCC6323FCAD7CE70 +:100D200087EFBFBB90D1792A414CF723C78700E1F9 +:100D300093375D47AF41FD78F4198F86EBFD0DCFFA +:100D4000BC44E5ADFB8917DD3AB5BF2120117BA37B +:100D50001B7A7E3AD1FE982FB14C537B30E509A522 +:100D6000E9353F7979BD1EA2DF0FD1EF492607F3A0 +:100D7000937BA74B19E8F7AC9FDDE786E4008A97E1 +:100D800079ED7F72D373700B5DA57148CF4353F03B +:100D90007B367A8AF96B38FFF32D746D67F29B4DC1 +:100DA0004EBBB77A548C6B70D2B9DBC5F6094D498E +:100DB000E9A54C7417EBE0E99EAB3EE5946F3EEF7E +:100DC000FEE4BBFFF99C1EBEB6FB751BDF08BC1D15 +:100DD000FE28B3DE3FE897381CCDF525C37BAF83F3 +:100DE0002A44CD416569780FD3B7C948FA9042DFEC +:100DF0003B5DD6F11CD5DF4E3D313F8B9DFD37AEBF +:100E00009FE6EFDE3B12F5D9E17D4F517E9CBFE3BB +:100E1000901BF737CF6F7FDCDD5595E67F5C17AC15 +:100E2000EF5B1C7E74EF48AABFB1FF0CF439C6FB20 +:100E30006FDA63EFBF69C77BB6FEE79A1D6EEA5FA4 +:100E4000ED679CB755E34A9CEFDB9D2EC07793DEA0 +:100E5000EE50EA33D9412FF175B127AE2658F3325F +:100E6000FA27957CB78EFAAF75B1F112BE9B68BEBA +:100E7000E862EF56AAC6CB1E229FF13CB78EFBDE7E +:100E8000D6E015A05BF478C2814FAD50ABC5FD80B4 +:100E900036395A6DDD7F09F8F30CD906FF8260FD03 +:100EA000407CEF0AF7713ABE53A14698FF3A34A549 +:100EB0009EDE7BD464CD9771DD66FDA1DF0EF9DF88 +:100EC000A5C9A05BF86BD4A42BCE45979D0ABA6D3B +:100ED0003FB066323B0F16F35F33183603D1C36B56 +:100EE000A4A307F09D08F352166728EC3BE0FBFE35 +:100EF00010EEFBCB7ADB7B60183AEA23AA8E7436BD +:100F0000BE61B9E79C8EE3055D56309E39423701DC +:100F10002AC468108617E36C87E3BEAB83A601A2E0 +:100F2000DE309D98338CF1371CA5F9B5F57FA171A2 +:100F30008F8539D1513903309F2FB179A4E83E4FC5 +:100F40005CE397734A8BFBD20730593D6CF52779E8 +:100F50006033DDCFA03BF364411A2F22DE4EF4BB99 +:100F6000C63751C2F508E73908DF69C3478E2CEF51 +:100F70007088F8C90122EF18076B6A357C09A6A2B0 +:100F800019935CC3F17C3F21E1FC4AA083A6A5D064 +:100F900049D37CAF26A914BE57A9BF4B86BFC0C991 +:100FA0001C077CA760C73BEDEF5B15FD9518A1639F +:100FB0009CEF73EECBB3C7237D3B87E9991B73642A +:100FC00011FF1CB3EEDBE2D04871E02B64CF93F548 +:100FD000C8414EECDA1C0B9F29814E165FE6D82FD4 +:100FE0005FAC2CA2E7FBCBC37DC7752DC5F8F0B372 +:100FF000B297270678676E050A3FF383495E16E7C6 +:101000006D80AE59F91163796AAC719386ED3D1D1F +:1010100017F2A182783669EA43B922690EF215A166 +:10102000C34ACE8741E8E29D1CA5FE8F2DEE581CD9 +:10103000F97060794C62C1445189F9D50CC5CA0771 +:1010400072CED5C57DC56DC174C22796B899FB38DF +:101050005D541554FF68846733A7BF933FED71B0AB +:10106000C2AE0BF09C87C7E3FDACFA77F4FD17B571 +:101070003040E35F02D5AD37E2FBAD2A346BA857B1 +:101080000322BE25C2E216C5BEDA57698F17F538AE +:10109000E2635D7CFFDE2B5E9CAFC777E0870C765A +:1010A000B3733D7E3827739C138CCB1C9728ECB40C +:1010B0004FCAFF62FFD9E8ED7C9E02A11934AE53FE +:1010C000E57E8BDAE91AF5B71FD921B1F7361CFC9A +:1010D000746467EE48D49728CFF87E790EFF2EED22 +:1010E000D8BB17EDABD6101879F954FFE90AC1FF48 +:1010F0003269945722E9BC5DEFFDE669F4E3EF51F4 +:1011000000DF753B42E6D889F3548D3C245A0EAC7F +:10111000B2D1F993CEABF7392693BF9B34217F012F +:10112000DAEED80E89BDF303E7DE85EF5D351D707D +:101130004192941F03D6EFB1CDCC6EB8EE178FD786 +:101140001049808D1C1E5CBFACEB4C41BD1F740B65 +:101150009F84C5BA601A9DF8DE7303C7CF8068BE4E +:10116000AD9E98DF3BB3EA0F50FF4F8CBDFF3C7044 +:101170004689AD7FE0FE119DFC43BEECE5679063C0 +:101180006EA0EB4A343745ED20B29FC6FD47528A28 +:1011900020DC4E7FCAFCDD125DCFAE27EB19BEC747 +:1011A000767DD2B11F75C45309FC3BF9560E703BD6 +:1011B0003200812C788EA4AAE9F92C95BB9B7EA1E4 +:1011C000507BECA647A4248DA7EE3A2B1728DE15FA +:1011D000EA977A039AEF242B4C9ABF1DF8F384ED1B +:1011E00078F7E976BCE754DAF11B8CD8F1E8C473E0 +:1011F000EEB861B6FA73954637653E8EEF4AF20F48 +:10120000F14DF4249DC77C328F94DE1B9F73F6ACA6 +:101210005986FE927EF1E8C0DF390EFC1D873D7BCA +:10122000592944BD4596F84F3545E5CA2987024FEF +:10123000A55A672DFD1609523F7598772235B0766D +:1012400025DE0E2654A323540E459C724ECFBAFAC7 +:101250003A9C24E9CD97EF3F340BB2CB5D478B37F7 +:10126000D2E0C2F371883454E079B946D3CD58FF47 +:10127000BCBED65B838EE7828886E91DFCDCE44831 +:10128000157B17A923F54111DA7F778C3E7A19DA9D +:10129000FD4DD74294BECB1464EBEF2E9E4E0EB2A2 +:1012A00038EBDBA33218E82FD8A32425F44369C612 +:1012B0002F2E42BB6D8F4BA7EB9F76F437FF8B969B +:1012C0008FD1F01CA3584E8CC271497DEAEF3FB21A +:1012D000E7F5D0772DF651F7EE7567E3FAB4498656 +:1012E0003999F6010D01367E77E55F8A902DE77911 +:1012F0008FD27DF9F22EBB9FCDBD8BF9E1E6EFBE1B +:101300009CDAA3FB67B3F7389F38CCEEA54E51AEFD +:10131000FEEA97487EFC7FF0778CC0983AB38885C8 +:1013200072203DE33E826782C7F53C7EB3E9AF326F +:101330008DDF1C7F214828AFE3FF08111351DB3CF0 +:101340009BAE574F87A61CC074F21E89FA8F9A0E67 +:10135000B3F56D6CA7DD4F74FE64A21748FF357BB3 +:10136000987FABA68B9D0F9CFFB2BDDEF82E7B7ED7 +:10137000423FFCBB24C0D7AD10149D4E7CEE1E979F +:10138000B122C0CED3E8BDB2889A79FFD515647674 +:1013900018C1079DFF91A3105942E671A4A1A4169C +:1013A000EF291DF9809D371CF948A9CFB4BFDA1287 +:1013B00060FCB2C9CDCE8F37CD0E24179379EC9B4C +:1013C0007DC350DC57FDE3DF6243B5BEEC12A222C1 +:1013D00064BA261AB9300EE5A395DD77834471A669 +:1013E000F793855C083911F2513CDB1FCBE4171DE4 +:1013F0001664FBBFBAD99512C66F773F2BD133A6BF +:10140000EE2504AE3EF068C29241084FD3EEF7A934 +:101410009FC2BB27B3BFFBD94088CEBF7B89B978B9 +:1014200002C1D7F788709B280FEE4459A6FE4D588D +:101430004FFD57DB028C9FBBBD6C1F0E6AA218DFED +:101440008DE8DE3DE9D26504CEBB89FCE1FABDC979 +:1014500015A1709BF380BEFF07FC7E61E965B0F5C6 +:1014600076CB7EED40A0F620D2FB6080C51F15C470 +:101470002212C21DF9F84408FB3FF2A187D2AF84C3 +:10148000FB8B44BB23017E0E17347E43F9654E214E +:10149000558A915828D23006E0BCDD04DF16FD9D48 +:1014A000A69B49C7C98F01BD479F1F90D97918D9FD +:1014B000A7E1FEA309C48F49F72B42FEF0D29B6A35 +:1014C00089BB97F648A920D19FD5DE400AFD32F9A5 +:1014D00073647C8387D8A35ED65FA7DD6E450D8CD1 +:1014E000FA177500D03CDB1F097D2CF4786B1ED3F6 +:1014F0007FAD6B54AA1F37AB5D3EF44B97197A9DB5 +:101500004AC6CD57751A6F31780E93F79CE1F7E60E +:10151000F5D84513001EFB58C9E81F392B28F015D4 +:10152000FB07E26BE481A3FBD0BC8AF8A000E93D95 +:1015300085DB3DE3DF65FA48DC3368EAB94760D70D +:10154000479B7CDC8E81C4EFF1DCFEA9BFAAF4FED0 +:10155000408FFE993D85AEA7A0543D87FC35E157ED +:101560007C7BC0F50FD9ED51BC9CFF422C8E7038AE +:10157000F5CD38207A49EA5FEF38E94C8CF09E7C53 +:101580002941CA980344CE2CED9D7A6A6090AFB38E +:101590005C4F1D8789032FD6D3FC347A61E4398FE1 +:1015A000857F849E4AF35392E2D5398E04DE9EBC39 +:1015B000361CF5CB0B0AFA518ED4B2BFF393E2720C +:1015C00094F741F252E487F57B2EF121DFEF3C30B6 +:1015D000C98B62755398DD3B53F74E3781B38FF556 +:1015E0005CD9055E3D5089F890291E148DE42DE3E9 +:1015F0001F4B48FCDEA59E3B3DC3FBD822BD29CC3A +:10160000EE95ED3C302C97ED475394EE3D7CCFFDAD +:1016100017422E04BF3BF95BC8439CB4922D7684DD +:101620002275F0FDA3DD8F10E776445CBC3F6316A6 +:1016300053FB7001B70FE381112BF1CF1CB4A6EA65 +:10164000343CF758101C46E3AB170C60F873E243C8 +:10165000A44D1F127BD11207DFA41EA5FEB1A60F59 +:10166000DDB6EF02BFD9F022F07B01E257FAE4F8D1 +:101670003D3FC8E8ECC4F3A79D7FE94DE332DEE7C8 +:10168000FB5799FF04883DDD45FDB1EC3E89E0370D +:10169000A13F6A6E6E8BE7E8697D21EE8308BD236A +:1016A000F4CBF98D89E77232E80FA7DE88B8B4EF82 +:1016B000AE22F88BFC2C40DFEB70EA910FF09762C2 +:1016C000EA77BB2748E07DECF9B765F49B3CF15322 +:1016D0003277521ED93B99F9053B4FEDBC4BD8AD43 +:1016E000C25E75D613F6AA5877C479D3AF83B18793 +:1016F000707C693791A710C6C7B27DF28140EC11AA +:10170000FC9E4360F6632C6065AA8CED67EDF29A4F +:101710004D3E731CF2D79152D93B3201F62E9413F1 +:101720000E317E4390BF2B40B80EED9AD21A6083E3 +:10173000CD67EF06948E8418AECF78BD14E7F92BF1 +:101740006E97BDC0D71B911E0844F723FC2E154C85 +:10175000CFE84F0EB7F02FFE3A68ECC3FEBCF5069B +:101760009DC7200D2268EF0F523BA4088123BF5173 +:10177000977A9C3D625D27FD0D9AAAD7A21C0DC2E7 +:101780003B05581FEDA30CF4F97390C535CDF376E6 +:101790003D8F267CD3D4E6FA501FE7EBE9F7102201 +:1017A000DCCF658F0339F2CC4B83F1FCF3B51FBC62 +:1017B0001FC473ADFF548F0611CE3717FD3E88F757 +:1017C000215E5BC4F61FD738EC9CE31C7FD343D16A +:1017D000C341927EA7E5E31ADB3B240BD9F9CCF594 +:1017E000490537A53DFC3E777B0EF5ED89FCBC8EA7 +:1017F000025B5EF0E93C0F8BDB72CEBF2AC4E2686D +:10180000AEDFB1D53D48C7F163FF85E3BFC9EDB891 +:10181000377705A9FF43C0336BC72837E2E13FF7AD +:1018200078F8B97FA78BE1DF988AE773314E0A27F2 +:101830009CCF3F9B43FBBB768342ED8E9964AC8586 +:1018400084BF637BAEA7FB70E73CAE7D4D9F3290BB +:10185000D0EFDA1512B557B1FE22C20FB185CBE930 +:10186000399E739E334D47FC08B72B9C7126D7EDEC +:1018700061E7EF0DA0AF9C589621EE64CFA5F4DC94 +:10188000EDBA7EF63D65216E4FD4C0F918377F1C46 +:10189000AA7E58A5F7BFEF79B3056810D9DB2D5E96 +:1018A0009A1E6ED158CAF5E7DCDD7B9FA77CA67631 +:1018B000D6A0DCEF3CF07ACEB7F4B41EFFF2D6F738 +:1018C0009FBB87E4C700F3F3087FFBD51CEF1771BC +:1018D0007D7E1DB717C67CD8B73EBF1AF131B2372F +:1018E000BC428F5F8D7F6FD08207A1D79DF838767D +:1018F00060780EF2C7E490F3BCF9D3E1255BBB79C5 +:101900004AE67846214787838CAF1BDA2F5F564221 +:10191000C68F3FF3C6902EA6270EA29E107C0AD03B +:10192000EC463976F2A3E0931EBEDBB39AE249F0AF +:101930000791AB303FE70CE3FED0C97FFDC537759B +:10194000BBBA86A05E70F259B7E35EB448AF083107 +:10195000FF7B836E4CC1FD2A596E96B1F340A68F72 +:10196000DE5413CFDF86F2DACEE465DE938FFC041B +:10197000F5D00D3FDE10423DF4969A28C2F11AB719 +:101980002D0DE1B9FA9BAA19C2F66F25958CF18F3E +:101990003B4292784FC31627016DE66528C7FFD8F2 +:1019A000E6D2F01CAC69BB879DBBEF6278237976E9 +:1019B000DEBE2B739CC40D0F6C28D259DCAD3D5E8E +:1019C000A2DD45FD17E85FC361B29D17F79C3F7725 +:1019D000F47D9EDEB48BC7D9ECBA3463BC84884BEB +:1019E00070F2F16607FF12FC50BF9F49E0A2EE764D +:1019F0007E4E1E7FF0AE9187087C87DB7F1592AA12 +:101A0000ACFE78761E7FACE3BB3FF2CAD9F9B79B38 +:101A1000F37BDA9E48668C9F6874A542B8AF6ADC97 +:101A2000EAA2FBC0C64714FA5E1DFCD143D7F3B946 +:101A30008FFCEC0F1710F8E63EE62A9CCAA641E39D +:101A40002404BD7AE258387D6E78FC67EC7C59E757 +:101A5000F12C9C4E731FDBEBC6B81C273E2775ECA0 +:101A6000757739E22028BD3A0E4DA1F7091F3CE1F8 +:101A7000C675F6AD67251858D6BBFD9CAD3F0BA1CA +:101A8000BE403CD138004EB7EC714BA9CB7E5A4DCD +:101A9000EB51BF5D7F745C84B23896F2FBA33F25A7 +:101AA00070CC79C543E3A7E63C7A338D337A436D36 +:101AB000667C7FEFD2225C7FE7B8CC228DA6ECFB60 +:101AC0009C2DB7507EBCEEC55B8AF87DA462E6EF24 +:101AD000318B719ED76EFE269DE76C88517E9C737C +:101AE000AF12453FCB7115EA1FCB2037237299DC2B +:101AF000BC719F071FD38137B89FD3FC9DC2FF5E87 +:101B0000A4F3BC8ABD1B739CEFBFFF19EA396FF4C5 +:101B10005AF7634DEDCB3B914E6F0F36066A349EFC +:101B2000403539DEE8FBEBCA8B170FE4FA8DBE7740 +:101B300023ECA049F81DEB77BAE8BB379676B67769 +:101B40006B16F0F109DC7EE93C921665F6837E3374 +:101B5000571271F02CFE46F059363DD0CEE2593E78 +:101B600038C8F40CC6E5D0F24E576AA02D1EC763E4 +:101B70007B17251D67E2E2726E2F2770D278991EBF +:101B8000FC3E2B25F11D64C12FB3D77BECF1793DD1 +:101B9000FCE37CB7C71E3F739DC32E1369AFF53FAF +:101BA000D7715EB7F9D4E2671A5D491AFFD4F847D6 +:101BB0000FDD9F343EE28A225EDED9F1DC1FBE4596 +:101BC000F8FE9D0E21C776BDEB94E3393BC7422654 +:101BD000397E2710818C724CBE6794E340FA5C43D7 +:101BE0008733AF77AFCBA277BFEAC027B11B723183 +:101BF0008EF8ED87E60EA5FE0A077E85BE75EAD152 +:101C0000D7433AC573EF783FB6EEA7E331191E0507 +:101C10007FDEF0F03C3A4E0F1F0B3E157C9C256E8C +:101C2000CC894F67792EFACEC6F6F68B9875508917 +:101C30007FA729EE06F6DE9BEC8F20FFF677DEF914 +:101C4000DBDC32F1FEDB796C5FC8CE3B23010DFF9C +:101C50006205DE9753329DB34726C919EDFF1FE495 +:101C6000323B09DDB2983E99CBF0D7AA44B923AFF5 +:101C700083DE63A067AB08675E88CA998BC7A990AB +:101C80009EE97DF4488EFCBE4EFAB8FB87FB2F51CF +:101C9000D13F3B46BE7938C9EFFCE1CB97A884DE43 +:101CA0009109F2E3C3487ED70FFFC8CACF93C7B8E4 +:101CB00008AB6E375FB96432C9CFE7F39E2FFC24BF +:101CC000AD636D7E12553E74279EE7A83F657F8FFA +:101CD0006825917BEFE8F439738E074C1FC9E7B88C +:101CE000494AF2CBCA7EBF0C3791BFF2C736E652E3 +:101CF0007CD5E988E7C39A97C6EF2C78EA621A4741 +:101D0000FA642EF3479FFBF804FA771DCF201C0FCF +:101D1000E60EC80E47AB8BF57378E7B99310CFE7A3 +:101D20000E459F5A9A1EA3559D7EF711B49BCCEE8B +:101D30000FE3FD96789E9BF6F324E7B3534D45DC05 +:101D40008B92C3F842C9959B1F23E9B39C1FFE7772 +:101D5000AE26D621BAEF3EF2CCC0FBD8BB314787C6 +:101D600020BD15E5D89FD1DE3CFAED1CFA774B5E1D +:101D7000F133BCBDE26778BB327795EB1CF27DB4E2 +:101D800077C8CDC8F4AF483B6EC174AB16FB25A332 +:101D900007A4B0DF6F5DA3B07E03CD417C374E3228 +:101DA000981D2E1166BA9AE0236E80EE1E8E226C6C +:101DB0008FFF5094D1475374FCA06D7C2825EB26EF +:101DC00091F32BC7337A11DCD275F4A5712C2FE077 +:101DD0009B911C16EFD2293C7F4278467992837101 +:101DE0003FF52D625631BEB7EFEBBBFDEC7CB31B6C +:101DF000DB8F4CC70F34FD4DA6FBD9269C03C93F92 +:101E00007E18F8DF2B64EFEB08BFC7F85FDF44FDF7 +:101E1000DFD5BBE7B23813EEEF12E7F935FBD9F99E +:101E20009CD3BF350156517D3ADEA14727ECFE2AEF +:101E3000D5AFFD9DCFFD43E8D5122839CDF3B98F3D +:101E4000734FE17CEEBF013359118B00800000001D +:101E50001F8B080000000000000BB55A0974545590 +:101E60009AFE5FBDDA92AA54AA2A450804E34B02FF +:101E700024210B45122004D42220D0314A8016811F +:101E8000F64881B298AD98B4DB699D438520D2DADB +:101E9000A319756CCE69BAE785D61125E92924D135 +:101EA000E05432C52204254E9045A01D3BED74231D +:101EB000DA64313D824BF761FEFFDEFBA82541E984 +:101EC0003E67C8E1DCBAEFDD77DF7FBFFFFBB77BA2 +:101ED000DFBA4409600CD03F1D2403D49BF1970264 +:101EE000307C3C2311F200F47A00D9096054642854 +:101EF000C1F62AFDBB0DA06D338E3385FB6F252AFD +:101F00006C9EFC53F6FBC1462DAC86828879ED7C35 +:101F1000DEDB652B4031CE7F1154533AC0B4BEECAA +:101F20009FCFC1BEA1DB002ABD979EA0FB6775AA0B +:101F30001F459B71ECD74521BCB435CE560053F1FB +:101F400095293A50CC6C5EB88AFFE3947850B2C3BE +:101F50007D4BB633AA2FC7DB764122FEF07B7A5346 +:101F6000508E227E0B12DCE3A3E679DBB6A89BE45D +:101F70002EB2AFAF20B9134B32A2E681E3FA4FFA8B +:101F8000B09F8D7F573300A643656208E52F844AD2 +:101F90008F84F2BA3F027708E59F718A8FD39E73D0 +:101FA00087FCB217712CF928FA7A2944F4719EC77C +:101FB0003EFAC27138429EE9F604D7050BFE180FAF +:101FC000E3AFCAA3E2E80E114EA76437AA01EA8F75 +:101FD000E12017B69F810A88DB3428480486AB0CC1 +:101FE0002AF6DF04EF0B73B0BDB279C871785218CE +:101FF0004F87271ACFA445D1788EA98CC673EC8A57 +:1020000068DCC679A3714ADD3825EAFE4D9B0AA338 +:10201000FA373F561A353EDD5F16D5CFDC5E1E35EA +:102020007E52D3D2A87ED68E5551E373D4B551F7E4 +:10203000737757DD90FEF303F551E362F53FB5E3A7 +:102040002751F396CAF7CA9011E6811FFF880785CA +:10205000A462D23FEA210423F53FD3E527C6FFCD92 +:10206000FA7F98F49F1BA17FF9DE44AF356C6FB106 +:10207000ADA6D79FD05AC7905E714E14EE0AE919EB +:10208000AF0D1AACDB256C1DC89D7BF1FA63667E33 +:10209000FD5181CF95B83495D6EF081EFD5AC21672 +:1020A000D5C2ECD0FFB1456D44DE3C2A2B0DC4AB4C +:1020B00017E54A09509E54549D2E1379A4838D012F +:1020C000E4F7B33ADDEACA08F99EB373BFF29C5D48 +:1020D000C7DA5F18D156F1BDA916F09B0BD973B4BE +:1020E00036FAE7015CB72D8981822F2CDF3E7F0E07 +:1020F000DE77F4652B0E0033F56F01381FCFE53D19 +:102100001FCFE55C65521AFBC87FC8EA2492A7D9A5 +:10211000EEDD69C7F79C979E30E09BC1E0F21BC8DB +:10212000EE52CDE0B7E1FB1A0DB0BA12FB0E7049CA +:10213000F5D826C24E3BE18B622857911487AA72CC +:1021400013FBF0FAFB24D138B231B70E6600ACD4E1 +:10215000FCE1C61CE60F87718DBDA450BD9208D866 +:102160000E3F90C9AE9FBB0FAD10EDE99C91E3A16E +:10217000E17051F8C9CF379B597B69B33DCA6F6E87 +:102180006C7E2141C179CE65C3A240047E5D84DFAF +:10219000746A6586DF80FAC764826770DDB7934929 +:1021A000689FD4BBCD8A439EDAF10F95807A30B612 +:1021B0002DF1A34E60A55161E3B5797CC1B94038DA +:1021C0001063E9FA3D1FC22692EF9E6FB18D785FD2 +:1021D0008FDDC0DED743EFC376393676C46D39EA7A +:1021E000C541EDD1390BC82EF07A48C2FEE26E30FF +:1021F000903D2CF1A61B489E93E03EDD8EF29CB5EF +:102200002BECF91F42A581E43A735F6D028DBB365A +:102210009F360F0AEBC078F2A1C36F4846BF3574F2 +:102220008BE4DEA5B0F799E97AE5BDA94F5A95F0A0 +:10223000FBCE80B7FF34EA7B29B8D9BCDAFC6879D9 +:10224000517EF18D8DD5BF4BCA207FA80333F9C3D2 +:102250004E13F3878355575A5FC2FBAB53FB6E3265 +:10226000E273E7ABBE9D4CB8ACDC218382FAFF245D +:10227000C1FB07FBF4301EE71EF87302DD5F6552F9 +:102280005F7909ED00F698DCAF003DB7873DA78D7B +:102290001BB0CFFD8C78072508D4ACEBDBA786FFFD +:1022A000BCD773C612CF347E3D28F855FF5AD65896 +:1022B000E2537DC2357EF1FE2B9963895F3324CED4 +:1022C000CBD879BB905F4A16AE1B79A520AFBABEBA +:1022D0002A4B223FB1EFB8B388E4D483F76AE4BA5B +:1022E000F6BDBF2A97EEC359D70DC94BB6E947399A +:1022F000EF012E678FB08F15C1A422D23BDA9DC5A6 +:1023000081E356FDC76BFDBF257C3AF7BCF2388DE3 +:1023100029BE313C34FFB4379EC7231071CE2D70D7 +:10232000C13897AD47510721DE4DF9C2F5FCD65EA5 +:10233000F20BC8AB2B3A747C99E4AF2A81FC82057E +:10234000DC0AB5E865DE9B8D7A6C3CA083A7B16B97 +:1023500023A7A6F99F12ECCB3AEE7FB06F4EC1389F +:1023600022FCD324C7BF2EDACAECC7635D3383B91E +:10237000442657F1E1AA0A7A2FF4A21F47592BF1FC +:102380008FE2C16CD874280EE59CB103F3031C37AF +:10239000F32CBFAFF9F55921DD1A63228DFBD91754 +:1023A000B28D208A8E03B30F977F4AF3CE8688E7DB +:1023B00046890FB31C7F5F7C98EFE0FE2190CDFD36 +:1023C0007B2014AFFAD3D9B44595F9C817278F1FCE +:1023D0002D8839D9B1511AC836A31F5EE468DEBE14 +:1023E0007D02D26122C785FA8DF45B29623CBE96DC +:1023F000371E9EC2FC21FC05A522BCEC42E61879E2 +:102400008AD1EE78307647E59DA123DFD8FA701D9A +:10241000AD4EE5BF485F4398D7905F88D3F7191D4D +:10242000A3ACEF4DF2AFC8FFE71C3A26AFB943F2B9 +:10243000A8F87EB3E20109D71067B74F93A5F0F86B +:1024400032078F4BB547CEA719515FFDBAE3B63CB3 +:102450009CBFA6FD0D1B2E1F7E6CF3AE73E03CD51A +:10246000E73E9841A10B199E569940386524923D4C +:10247000E5EBC1AF2F1C29876F072E06295FB72315 +:1024800089B5391D125B9F2FC4D739D0D1E88CF4A0 +:102490001BD79EFBCFCEF1A4B73D636005F9E3FCEB +:1024A00060D106E231C962405DBCFE552E9BEF094A +:1024B000473ACFAFF5A0A7EB00AA6E290EDA63C0AA +:1024C000E770DE81AF64364E9B37BF63AE6C471E4C +:1024D000E5859A0E525E18173429A4E7B89781E370 +:1024E000128C637ED1D7B510287F1D74805BC2FB30 +:1024F000ADF1431F132F863A4DCA2E89F06B022788 +:10250000CEDF6AE4F133070DE10D6BF8BAF6BEB821 +:10251000E0CF81FC15F2C3A3D27D7D13DC628DC4B4 +:102520003D81C9FF4B07E7576B7C486725BF8F9CF0 +:10253000DCC5E40ACB09ECBD9A9C39AC0E68350EBB +:102540005D78DCC5E4B2131F7280CB09C12CE515A0 +:102550007ADEEE61EB88B32B6EBF34522E5F01E65C +:10256000C56877CF6E816B764E76EF8B0FF7CD68AF +:1025700013AD1920FCC229968784FBE8B04AC2CF6C +:10258000BFF1CF67B66F9DC3EA23BF8C7CB0609B61 +:10259000E0A47572FBC2B2C933A690E3E0469C2C5E +:1025A000667EFFDA78E4BB95FA563ECE9D68B79416 +:1025B0004BCC6E80ECA64EF89987A4D085DB50B545 +:1025C0005F860E1628284BCDD1B7196FAB75C19712 +:1025D000F2F17E59BC3748FEF7AD8F7460C3F57FCA +:1025E000FE5A9C5A817864EF6F4EF65847CEF7D466 +:1025F000D92DCFA792BEF74B0A228D79E1501AC987 +:102600005717FCD4E8C17661C7EF8D149F5639BDCA +:1026100047C80E4A3A1AE6117EB3A0A9D16E657E6C +:10262000D14B3C0DA470FF317C6AF2AE8608BC2F02 +:102630003978DE0243DE9BC96E82C23EBB28FFC1F1 +:10264000B65DE461ED0756662AF9E1E7FC703015E6 +:1026500070CE2D70389570D6AE0FAAFA45C4A7DC9F +:1026600033E6D59E08BE5D10F67E41BCEF1F9DDEB1 +:102670008F0887EA039F186DB82EDF1F0269149F29 +:102680000298A7D9BFC32FFA62ECC6A71F32D2782F +:10269000DF45607E04F5BA3511F5B4E74CC79435D3 +:1026A00056263F24E2BADBCF9998DF6C4FE7F6D786 +:1026B00070FA7201F9ADCB9DD537135EEF3B0C1A62 +:1026C000CFCBE2C99EF602F3639A3DE6913DA2E8C4 +:1026D00079C4F362EAE7B0F95A8DBDE5CCFEDA754C +:1026E00040F6873C67BC479EDB29FFC8B323EFD980 +:1026F000F359CC9E5B7B31E061DF8F7E7C12EB97E0 +:102700002DA37E6BEF7C3BB3671D425B4876193A85 +:10271000C8E609604C23D549501999A796396C4CE5 +:102720005ECD3F563AB8FF0F642B896E5C8F45969D +:10273000A3EC20225EF2BE88A72B9F37FCF4C509CC +:10274000644D222E88BCAC4BE4C1E02D62FEFEC776 +:102750002296D5BF53BAB805D75BDF2373FF2F7816 +:102760007250E4C98737A7B03EC50B05F5341D5B31 +:102770000FFAD3199E4DF3D0C6A06451D3216A4BF2 +:102780002B03F3107198B3A2F790819B732EF1AFD6 +:10279000EDE00F72F5C4F77326884311DBBE19FA1A +:1027A000F875C4E1912EC47F94B884CB61FC4304D6 +:1027B000181FAFC79B41A9EFAED96E4CF99F1FFB05 +:1027C000037D1CDA0F1103F1C87B7ECC4FFD28502E +:1027D000BBD333D58938FE36C93BD589380E9EF830 +:1027E00026997C7AFBA94F6CE4EFDB8C9E5CE25966 +:1027F0005B06D60BA3F0738293F3A7D8149DA76B47 +:10280000ED5227E7FF643F3C43FCA96B93ED2AEAB6 +:10281000BBBF4DF618318FBAE0F126EB11D28BE039 +:102820005F3E9BE2BBA87FD771D8611DE52F18677B +:10283000D6BF6888AA4B6BC4BE4616F46D4B459C48 +:102840007C2F4BACAEDD18938FD450FE5240F54533 +:10285000B391D653F572CC3C94C714D0B8EFAE7395 +:10286000973AC53E472664521E833C62F5F4D06910 +:10287000D9BD8B62A01EBA4DC8DF3D3A8E13FA4D0A +:10288000668F5A3E637279E691DDCFD3E28AA85B08 +:10289000875A2595D9CF6EF4F3D82FBDA83403C736 +:1028A000E154CA0C5A0FE765A99E8F2F0DA633FB82 +:1028B0002BF1603D8FEB5E8FF5BC4AEBD6F23CD539 +:1028C000C0D68FE197E579B3406DB4E1B80DBB2573 +:1028D000B6EF53BDDB1095E7F9043E353B4E1CA126 +:1028E00072B23610735FE0E38BC1E70DFA316B24EF +:1028F0004E8F3A45BE97066991F91E743B47AD0B62 +:10290000347CB43CFB4F069E5F7C20E6D7C6FD8B33 +:1029100093D7E7751E60FB4735AAACAA3C1FB4AE3F +:1029200041BEDC2FF872BFE08B0FF8B8DADD921AE7 +:10293000A278F533AE7733FE112EEB026B16A42A84 +:1029400023795525F0D8D86260F92FC02623D9E71E +:10295000C69D31E3042E5531B8D479A518F9783ED7 +:10296000FEB7CA576DE0FB35D5C82FBFF2FF276F02 +:10297000ACFEFE5DD3DF149812A5BF454937A4BF56 +:10298000D83C79EF9129167A7EB83B83ED4368BC39 +:10299000899D6781C8B317EEE0F9687FC73C4B3E5D +:1029A000D553C7F56E09E729EAF95F5B3EE251D8D6 +:1029B0002943054E31182C7AC68FEBDCD73D71992F +:1029C00082F1A1B047CFE24B514FA14A754D614F03 +:1029D000A1253381194F12D50B380F8BCF83C72711 +:1029E0009ECC233FDB3DBF98606F385E68A13C62A0 +:1029F0001FF07D0DA9A738A92F22DE743BF9BEC6B2 +:102A0000B694FF7996F2FC857B0D6ECA47161A863E +:102A1000DE9FEDA2F7EBDD0DD8AFE959BB258EF4B3 +:102A2000FE9AE4A674FC486FBDEB47A4DFA0C16E1C +:102A300062F23E7C90EEFB5B24F7241CEFEBBC3D86 +:102A4000B715FB85CD456E82597B5FA14379A18285 +:102A5000F2C5711656C72FBCC9C0E2EEA5F1965F4C +:102A600053BE54E5695E40FEF8D2DBFB8CE40F06F2 +:102A70005B2548C1851C4939F41B3FAEF3D29B2727 +:102A80008C9494CF6B3B61ECFB8E7CA25F9521C450 +:102A9000EAF72623D541B5CD5ABFCF487AAA14F913 +:102AA00055DDCBBF67FD2AAA13F07D553B6555C1A7 +:102AB0009F873ADF3212DE752D128C4D8FB8FFB230 +:102AC000C4EE6BBC5F0B9C076B857FAA16FB90D591 +:102AD000B40F89D7613BF7371AEF1FD8BDE40885DB +:102AE000EF754DD17EE841C1F30D5497B2FADB6B1F +:102AF00024BD6ED811334EF0FCC1EFE1B93549F871 +:102B0000F31CC8219E5F9ECBE3C9E513F1963C5CA4 +:102B1000D7E563B21BE03BF9CEE2EF71912F0C8752 +:102B2000742C9E69E3063AFECCE28DEFF8B091F288 +:102B3000DB05C12F983E2A8207E613DE7782B7862F +:102B4000F0BB3368B193FD57F4717F501E34A9B4C4 +:102B50000F7E2704B6929E07BB5EDDEA24DEFC1BD7 +:102B6000E70D087FB741E0BA41E0BA011D7E12BA15 +:102B7000D8AABC032F61BA0FE5C0FD507940F8A177 +:102B80009DD13863E4B98FF4551734C1D378FF0E63 +:102B9000E18FEE68E1FE28364ED6897D80C171B99D +:102BA0008BD97E2BD6BB94C7D5B444E35F27F605FB +:102BB000EA62E2F0CD497CDFEEFBEAFF583DCD8DC5 +:102BC000D153C510E74F39C53D5C7F77684B1EED8B +:102BD000DB6978C5EAA95BC94C1CAD9ED5DAF7451F +:102BE000DEAFF517237129DF0CD89BAC9175FCABD8 +:102BF000493CFE54CD92FDA4E76BF5CEC443058A53 +:102C00002E5CEF609DB332690CAF7BA6E1D4472701 +:102C1000C8E07285EB9DA7525EA828A47CA585FB21 +:102C20009181129C2F91F27960FECBD76252A94E0E +:102C3000F1217F589D43BCC1B63228DD4EBCC1FA9C +:102C4000611DCDBF84B68E1187251D3CEF5932FF23 +:102C50000BC6B76313F97A87F5CAD8D1EA09AD8EE6 +:102C6000A8FB8AE7A9DAF53AB47B1A5F1794585D96 +:102C7000DC76F0EBB474F49F839D57D2D660FBA250 +:102C800058BF96A70E619E9A21F214CA9FD77395DA +:102C9000C1064C871F431EAE17710EA4ADCC4EEA81 +:102CA00028D925BEB54B7C1F673F5E9889FEF78308 +:102CB0007896C70C9CE1E743F4FC1398470DAC0DE4 +:102CC0001C76E2F8CBAD128B7FEB31C7BDB570A49B +:102CD000BDD70A5E36C01651976D656D79F6DE4F29 +:102CE0001E277FD46256C8BF0E74341AD9FEB21A9A +:102CF000F17CC6C87CA856F0B7F67BF6B55E4D12DF +:102D00007152F012D7C1F2DBC163B2DD2431FC7E17 +:102D1000353E122791FFB41D8C637A1E3C61552904 +:102D2000CFFF5CF0EF92D8776F2891192EBA59BC7B +:102D3000CDED7A2B83F44A7AF0D23E4AD75B533CEE +:102D40006C9F4F65F654BD5BA6C3BEB0FC010BDBA8 +:102D50000BD5FA1ABE3E812FCA35D9E80ACBD5AEBB +:102D6000EFB3B947B11B493AC8F4A693A2EB5CDFB5 +:102D70007EB9528DB0275CCF6AF26FFB053F403FB2 +:102D8000944C7EB9334961F23504B99E759DBCC53A +:102D9000F72FE7FB3606F6FE11F7CBFC3574FF7212 +:102DA000BA05184FBEF25750FF910C99F9A9473E4A +:102DB000A8CA8288F783C4EB719F612899D5C3277D +:102DC000744C3EDF89E1E48956F283CDF3ED79E47A +:102DD000DFB87F389261D948FCF6D37BC786E759C4 +:102DE00098C4E33CD07A53289B7991CF2BD6BB056E +:102DF00096321CB6089E75897C14EBA633648FB19D +:102E000075D3F5F2DD88FA8D3D7F79AE72F247C851 +:102E100083C2637A3FD5EBFBCE723FD1D0B9E17765 +:102E20005407FBCE9B80FCC4235D1BB2280E83D7C6 +:102E30003B95F2BBCB5D0F4E65FB97D21626979F55 +:102E4000E44BA1BCE97432E543B59DA793595C6F8F +:102E50009FFE02E5499817DD41D7315F61FC2BECFD +:102E60002966FCDB77BC3829930407B785E6AD3DBE +:102E7000A6AF247C6A8F15BF5741F94B4F19CB93EE +:102E8000B4BCA888EA71CA938E4D8CCA93FA057EA9 +:102E90008307E2D8FE8704199C3F30318A3F356DA5 +:102EA000EFB07CA2A643F644F2E8DA732E3DE38D40 +:102EB000C1A5B0F91A029287F1632F6F6B3AF6B190 +:102EC000F5551B024CDF0D2D067EBF95B7004DEC6E +:102ED000793F38FD84C77B7409F5506E5427D0FEC6 +:102EE000FABBE9BCBE88D5C77617DF4F78F79CF7E9 +:102EF00066E2CBBB73BD59F651E2861FCA78DD2D61 +:102F000009BCDB0C2CAF8C1DB7CDC5F77B6C491011 +:102F100075DEA8B5F52ECE9F7223DFA78ABD7FABE5 +:102F20008BD7CDF8EF191DF2E26485C1FEB4A82756 +:102F3000C6A1BFBD4BF8DB65771A58DE71529C33D2 +:102F4000DDA5F9DD121EBFB5FDFE253BE1492CFFD5 +:102F5000E14BC863E7604B3CD17EEF6E915F2D5B28 +:102F600014735DE453777F4F3E35C325FCE16498CD +:102F7000CCEB06AB85F645BFEC36D86526B73AB143 +:102F8000327FE43A357F73449C0F75A31FA4B621AA +:102F9000E743B64FF5EE8173BF71303F1A07197CD6 +:102FA000DF91EDD7D75E67BFBEE19A9DFE308A778D +:102FB0009A9EFA29CFCF1BA9A7A502EF5AF3252382 +:102FC0003BB7844DDB7572F89CD264F07A52711D68 +:102FD000868EB9213ABF6CC831B17CA9FF764925EC +:102FE0007F8F72A69922FC7DFF389E7F3DB25C6286 +:102FF000FBC207723E6471BC36D46B245E4D6E5BBF +:10300000F324B35F3F9CA27A49D3E762338F9FD703 +:10301000F4A8AD976E2AB43EA79FFB65176B693C79 +:10302000C5CBBB447C5C5C12ADBF2CE85D40FB2390 +:10303000F77824962F5D4FEF4B574C7B87DCDF8D65 +:10304000EAFF9F5CDE875D64EFBDC3CB697FF7DD80 +:103050009C4FD328BED65D87CF7E81AFCFC2CFC570 +:103060007C167E1EE6CE521AFB101FBDC3BBD9458F +:10307000FB4FBABFD8A600CDD3F7AB7A89F4030CC7 +:10308000FFEBD9D13631EF36979DDB8B8B9F0FC588 +:10309000519FECD9A04E203F01793776CED7B0FFB3 +:1030A0006801E969E0C0B10263843E2FD5A33FA067 +:1030B000F8D2792859B146F24D27F8A667AD242DEC +:1030C0001571339A7F97887FA4FFBD87EEA2BAB0AF +:1030D000BF6D994B5222E26AFB49DBA48879FB83DE +:1030E000321B8FF5D8E4BB1322E57C92C9D91FE0CF +:1030F000F301F44D5E961F79BF919F1B99FB188FCA +:103100009FCADEC4CEDD351EEB81F3B8AE6309B0D5 +:103110003825D61D30E20FAA33BA4C2A9D53D07EF3 +:10312000BB23C24E8E0A9C67627140FC9C057E994F +:10313000E69D8933DE4B7D3D84E84C6E3684647EAB +:10314000DE3D0188D73304AF67EA4307A402368E19 +:103150009D4B95422F1B772B0CB1D603763DB56561 +:10316000E0666D89397407B993BC40807D97144A35 +:10317000D63B2E98D951298CA6BFF0FAF57041E3C1 +:10318000290EC6A487EDE3C78E1B1676EFA6DA825A +:10319000F4DC0F6C1FEE16E893E925B3F5B088BE9A +:1031A00027BB450FE6789477EF611DB3E7AE3E4548 +:1031B000257FE64E12CF7D86CF617FA687DB2D85EA +:1031C00020FA6E455B6F2C0EA5381FED0BCED46335 +:1031D000E5CB700CB1F7DD4682E3BAE782A2A7FE29 +:1031E0001F5DE9623F85D769F3449DA633FB191E35 +:1031F0007F12F191CE736C384F69930467E97C2696 +:1032000093AF579BBF14B3C1C4421ACFE31B6D8564 +:103210009F75F2731E1B3B9F9B6F27BCA450B2EEA1 +:10322000AAE5C6711D4C0626B7EDFEA181C78BC36A +:10323000E75DEEE0D1B3F45D8EE4F1B0EF7ADC66E9 +:103240006B88F27364C7A5C8BCFBAA6BED5FC9DECF +:1032500025C5CEF0022F28947F8C0D7FEF02579367 +:10326000C2DFD3108C1793C3E7FBDAF735BBD5A5C4 +:103270008A0EF5B2C26576935E0ACD6945540F3663 +:10328000DBBD7F75B1EF6C5A26B1C9F4EAF4CA848C +:1032900030DF2DE02921BCB5737D49E8EF7AE7F6F0 +:1032A00064ABC4730BBA7DFA2EE819B417B373B4C8 +:1032B000EF8FF8793E5AA142DF1DC113F314FA2EA5 +:1032C000609BC3EC7E5AA2141FD76709AFAFD1CC65 +:1032D000BF276834F3EF0260EB74B67FF690388F47 +:1032E00068B4EAB2A9DE6A84783795F49ABC0F25EF +:1032F000703E3EF4DF16763E1A2BF7D7F1DE9C3196 +:10330000D3C3F23F2ABBCF62EE1385E71C0D4F5D9E +:1033100018CF156A46639FC2F09B46CF4F33A9373B +:10332000D1BEC82A13FF7E49C30D15CA486D17FACE +:10333000D0F0B393BE691D1ED4B7C6978C307ECF34 +:10334000C473DC0CF4E544267B56217F1D8BCBFF38 +:1033500001AF6B7F8EF0290000000000000000002C +:103360001F8B080000000000000BFBCACFC0F0A3B9 +:103370001E8143D1F8E8389D0F534C941182D7B386 +:10338000E0D78B0D5B3122D8FEDC0C0CCA9C0C0CF8 +:103390002A40DC07C4FD40FC1E880DB818180C81BB +:1033A000380DC84E07627B2076E386E86966676061 +:1033B000E806E2C9403C9B9D74FBCD251918CECA96 +:1033C00022F8B2720C0C510AA49B338A87267633FA +:1033D00042E5C76BA3F2BB7419184E23A949D02646 +:1033E000CD7C466306062663DCF271E6A8FC504BF2 +:1033F00054FE5D3354FE4577080D00AEA32483B818 +:1034000003000000000000001F8B08000000000007 +:10341000000BC57D0D7C54C5B5F8DCBB77EF6EF6AF +:103420002B9B0FC20642721302040CB8C480C14A1F +:10343000BB89A0A0C85B502B585F5D02242004828A +:103440005A492BFE73212104126041D4A0881B3EEF +:10345000142BD8A0A0B6B576F9D0529FCF4645A57B +:10346000ADA50115D4024DB5C8F63D7DFCE79C998C +:103470009BBDF76637E0EBFBBF7FFAABC3DC993B44 +:1034800077E67C9F33676665318564E6117211FECD +:10349000BE47C8040B21644CBC244155206309F984 +:1034A000919DE09FD6CF5C36D61312B511129B4B7F +:1034B00048A78B76946AEDA49896B7DE28922C42A2 +:1034C00052E17D859026A1F6C8E05242D44122D92E +:1034D000491FADCA999E1A72251F77371FF7B97A0F +:1034E0003B961DF55E2C9FAFF761B9AF5E21D161B0 +:1034F00084BC585F84E5CBF57E7CFE8BFA322C5F72 +:10350000A90F60F96AFD242CA3F5412C0FD6CFC07A +:10351000F2707D08DF7BBD7E1E9647EA6BF1F91BDA +:10352000F57558BE59AFE2F3B7EA9BB1ECAC0F6347 +:10353000F94E7D1B9647EB23D8EFFDFA5D581EAB85 +:10354000EFC0E77FA87F19CB0FEBA358DE4ED20860 +:10355000E947C86DB79DB7CFA2EB1DF6C47DEF4C10 +:10356000CE2464FD18D10FE01AF6C4C7BE50717C9A +:10357000DDEBBFB1CCE8480097EF1301C759EF2648 +:10358000D8BEFEC0EF893292907563BA7C2AAD4FE7 +:10359000E6DF19BEF3A87D5671BC9F799C4F8885E4 +:1035A0008D63A5EDB4DFD0CDACBFD63E19BE3326BA +:1035B000DEFE54DB3BF6D92E7D3B7BFFE92DEFD8B9 +:1035C000017F6B63128922DE554268E950BADBFA4B +:1035D000513CA71CB3115B3EC5BFD241BAE838EBE2 +:1035E000C63D12154B61DDB49B02EB7C9708140EAF +:1035F000AA9B203D2830C6D5F1EF5C4D449CC7B056 +:10360000278EB2EFDC7A1ECB57FF211342DF5B77A8 +:103610009B1071D2F1D78DFFC217007A539FB10072 +:10362000BD21B92AF09F2E5F908EBD7EFCFB3E959A +:10363000C269ED37EFCE980DF4379AF8E17B6B0F46 +:10364000FC9C28D03EB21BE1D7C0D7BD76E6AC3C8F +:103650006F7172BAA49444C432BA5C17094412C0A0 +:10366000F75F0108143E166F04D7E4A0FD12E1E1F4 +:103670005F898CFDD6BA83EF015CD4DBACFE9D7410 +:10368000DED7F9A3E4942B3E6FA87F44EBAEBF478F +:1036900089C50DF3FECC67A1EB7796C957A5D0D9A4 +:1036A000B8BABB8FC1FBAE6BAB02B0F675A3BB7CE7 +:1036B00055B4BFBDA813D74BFCC43F848EEB285232 +:1036C000C9EC62808305F16A9ECF6C80773FC0D3DE +:1036D000573EC0894687EFDDFAAEBD52D7FF698DF0 +:1036E0003E04465FA4356A9FE68EB73FA1B5A7307A +:1036F000FA217663FB66131D939C24ED560A68C479 +:103700009718D92920DCEDD347F69E776BF4B7C81C +:10371000072E7FD41E4AB02ECA2776903BA9A5A2B9 +:103720001FE0B56E3CE597E2F83A2FC577CD1C2E29 +:103730006B4BA7BB61FC4BC9AD911D2289167199DA +:1037400049FF7FE5CB0E3AF3787D7434DD50BFEA54 +:10375000C80043FF319D0586F6AB8F8D30B48FEBEB +:103760002A31D4BFF3E93586FEE3BB2B0CF5EFC558 +:103770006E34F42F27B718EAD7D97F60E83FD13BE2 +:10378000DBD07E836F81A17DB272AFA17E53D10366 +:1037900086FE37FB1B0CEDFF52D662689F1678C879 +:1037A00050BF65D2E386FEB705B71BDA6F9FF1AC59 +:1037B000A17D66E80543BDC6113A0EF8F9C1BC5FAC +:1037C0001ADEFBD7DA4386FA7B844C4A845F2230C8 +:1037D000394329C87BEA0ADE9F8A382FD01CD07172 +:1037E0003F46A745ED49E4246F7F66C73BF6B9061F +:1037F000396965749CCDDA7745DE49FCFE20CE2719 +:10380000A4D33EDDAD6F67F3BAE21F54BE42BBA442 +:103810007E2BF9EAF6FAB1BF2657297D13720D8582 +:10382000AF3A5055F17B743C2A2F2D6CC9A48E30D1 +:103830003945C8BDF85CD3FB2487442D74DC06777A +:103840004EFB1A80091D5BCA847AF136A88B4A8028 +:10385000742580ABC52B1BF064862F71A55362EED7 +:103860004BCEAA083F75222992E0FB82C3BF9CAED3 +:103870005722A101027D7E410CF960F24B2DEA6FC7 +:1038800042F9F1FECBC7D37F42FF13426405F657DE +:10389000108E0D234900F4869A2D4776E6233C6D61 +:1038A000204FB4F7E803A58BCD57BD38D85067F348 +:1038B000BD64FDEB61C6BA36EE4F8CF0A47086FA9B +:1038C0005DBCD26BDD7E394EB716E8C7EA8A289018 +:1038D0008B28078DEDDA772EA4784691548A473BE2 +:1038E0002B973A3CDBA0BC90921B211E428AC5500C +:1038F00005C04DAD60F0518F3B230D385EEDD5C155 +:103900009100DFC4F602212B187F7C3859D4AF23F5 +:1039100019DE1AC06E1BA6A3831C3FCA71BA6AD4F3 +:103920006FE6FEB70B321BDF455145C7B711466343 +:10393000A996D0EDC218586D9048384F3F0922BE65 +:103940002611B04BED1A3CC373B1EEE276E601F7F7 +:10395000D863218AE7B501D90F63550A0AC783DF07 +:10396000077AC056269235B4B65679C70EFCD19C5C +:103970002F67835CB749B5C44BEBB642CA0709F45D +:10398000C8E21E39F120B91CBBD88CA722FA3A9B99 +:103990000741386AF30F0FEAB417005D8EA776313E +:1039A0009DEAFA6BFBD62F2B397C5BC02EA6E53A3D +:1039B000657A2A41BE253381BE9BF3B344E4530E9E +:1039C000A71EB8E4BF6F073E5DCDDF5FEB7F07ED5D +:1039D000F4D59A1E37C1B179F44984CF2C81E9E33B +:1039E00096918E19910470992578B0BD19782A1393 +:1039F000ED2BC65F267AA12DBE4ADA6E57BC256B29 +:103A0000E8F813464A33812EDC6544B121FF065C99 +:103A1000D9F4FB0EDE5B524483FC706732BAB57F8B +:103A2000284414DADFE563DFB3B9482480EF2F318F +:103A3000E0C551169A4246513BE91F167C8FCE9144 +:103A4000D9114727233F5ABD6C9DA488E1C94BFF7C +:103A500077B1808EA7C806BDB1BC5CF647E9779602 +:103A60007A5C484F563D5EE9779DDFBC1084F15784 +:103A7000E5DCE3584EC7BF50DEB40AD8D2F2E1E429 +:103A8000CF80EF2CE6FE83A6FF6E70023ED04A6721 +:103A90009787443360803BFBA403CF87ED6F1CD630 +:103AA000CDF315C19D89F2F56A7235CA854BBC7F8D +:103AB000A13EF2C6E121080FF172E879A589AF9B1A +:103AC000F235BDA5FAA6E9ECB2F302D36B442D475B +:103AD000384B9C9F9BC6936EB05BD7E5CBCA0ADA86 +:103AE000452A93A3403AF0D74DBF0FB6190179ADDF +:103AF0003475B2E73F32C8CDD5FDA7FAA37DC04DDE +:103B00002A34E99B4BACBF0EE0A7EBFF31C0CF19C5 +:103B1000879F8D0453A3402FE149063F7655F9FD59 +:103B20004A94FE73D580470227880E8EDFA37CA8B7 +:103B3000E30F5B4E84E8BFAFC9C55BC44037C861C3 +:103B40008BEC4739450A64F447CCF32B1299BC89B6 +:103B5000C3D92E111D7F902911843BFD0BDAB33898 +:103B6000FCE85F8AEFF57F00FCA88E8E3A47E1F310 +:103B700046A984CE2793A8CE2BE9FB1291A03E48FC +:103B8000CC47BEA5ED13E474E0DFEBFD20079BB846 +:103B9000DF47BCED3EBD5D3E4864788DB7477CB7DE +:103BA00019DA99BDD3A4D9F5DEED06BAE8793F8DCF +:103BB00024F43FFA89CCCE1E247A39FD6C47FF6D80 +:103BC00075E69418A02125FB7A7F25F0AB97201C81 +:103BD000343DA1E905AA2F0689FDE2E3C98541220A +:103BE00060BB51FF2695D726BD9B52649403446F5A +:103BF000CF14C07F73BC482FC4ACEF7919BCF1B2AD +:103C0000F8AA97BE2489FDC5692293C344CDC4F5A3 +:103C10006B7C45B83D61D5E882307AF5F0EFCA306B +:103C20009FC180E7080EEEA46E15D4DDA416EBE765 +:103C3000CB4AA200279BD4D54CB87E54F313F8513D +:103C40003C0E936C1DEBC727D60FE5A207F16971F7 +:103C5000D59210D2F19D68070A6A885C447B30CC0B +:103C6000F5AADF07785C555F473EA28B711C9C8CE0 +:103C7000FEB9941308807F6F0122C8A6FF7795B222 +:103C800052F22B7AFAECC123598EE3592958609DE0 +:103C900056977D16E801ABCB3B0DCBA211730528DF +:103CA00053AFAF1391AD12D393361EA5AB79228CCF +:103CB0009719427E96BC412C892B13ED57DA5F0988 +:103CC000269C07A703DE2F29DDF5D08D0607458644 +:103CD000F1CCF4E428A51E8988D54E986F7F8EED2F +:103CE000FE739A960088DD24DC3C94E2AD7FD7AC6D +:103CF00029A077DCA07FE83A5716971C01932FD5AF +:103D0000EFDD70BD02710022001E56C360D7C0787F +:103D10003F585E8EF10FFA37800A8B15C172E61F8D +:103D2000044C76ABA8489A7D26F669EF08176DBD5E +:103D3000DF4FB67E1BD1F115EAF17B2ECFBEBA93D1 +:103D40007D4FA5FF037E4C33E9D9D480511FB84D78 +:103D5000DF790E6089F05EF2BFF23D2FD96857C05F +:103D60005E2914BD114ACBA9C49B067E946302F55B +:103D7000EF68DD9BD3ADC2942E859795DC8F25949B +:103D80009FF5F47F88CBD7ECAA4DB39AE8B8E74B00 +:103D90005D7EA0E7FE549C66A4F75E4F4B3D31F07C +:103DA000734BF136A4EB06AAF00AC03F2816D15E89 +:103DB0005F5DF8BC57AFC73ED1E4502FFA208A347C +:103DC00096FB93143E9642319032EA9FA70FB3FDC3 +:103DD00074B9F4E1BCD3888F6F8BAF2FBE257DFC07 +:103DE000B3DF5B992C3EC1E559765523F35794BE5A +:103DF000FD83DE78DD88787550BF26917CBED08348 +:103E00004FB57769D02BC6B880F586EFCFD8D107EC +:103E10003CAC33CCFE3F1B37A5CEA27C0CF6ADE408 +:103E200035F841AB958D2AD8F3E7C12E07FB305CFE +:103E30008EF16152C8E2B5308048EB294A20C2FCBD +:103E40009B08D1EB4139C71877B3643A8CFA7B866B +:103E50002AE8E79F5227E33CECF0BD4C8CE746E0B4 +:103E6000BB162F89A6A0FDC9F0079F62F180072E1F +:103E70008B0E347A053398D1ABF1BD553925241119 +:103E8000FE7A7DEF56E37C93CA25F37B2E4939A554 +:103E9000B35392BF2791533A7BA742DBF7E178A255 +:103EA00076DECB422A9507BEEF9310856F133465FB +:103EB000433C94A03E6BF29578519FEF124C7EBB31 +:103EC000C2E84749C7FEA29DE94DAD9E7C3EECBBD2 +:103ED000F17D2405FDDA64FD1BEACB1E9628713ABC +:103EE000EB0E6D92281E1B97076604D1BF3DB249A9 +:103EF0001A12EF5763D1FC76AA3EC7C6F7072442D1 +:103F0000FB21DC4472F12A78E825CA588026FBB3ED +:103F1000934E6CA74F391E89D0E3CFD021DB609D33 +:103F2000189F3886FD60A08B186FEA6275FA22D45C +:103F30005BAC8100CE4B0ADBEFA1F06A49E17585ED +:103F4000D7D378DDCBEBF9BC4EF505D49D32ADD39C +:103F500032C51AF662DDC1EBF9BC9ECEEB69BC5EE0 +:103F6000C0EBC246ACB7C86CBC3552848DEFE0756F +:103F700085D7D379DDCBEB05BC4EB6B1EFDB58DD91 +:103F8000618DB0F19DBC9ECFEB19BC9EC6EB8379D1 +:103F90005DD886F564F8731452F81BE44367BC8E51 +:103FA0004A84C3B5A7DE656A67F49221106E87A9BB +:103FB000D960B71D98757F36C4431F3D71B50FE8B2 +:103FC000A7E1668D9EFC283F49CE4D28C7FA737F36 +:103FD000AEE1CE1518876808C98C89787C26DE5E2C +:103FE0007204F4F6F919A21F1ADB92F82FCF723B74 +:103FF000FE191E97799AEF57EEE4FB95DBF97E6583 +:104000003BDFAF7C92EF573EC1F72B1FE7FB959B41 +:10401000F97EE526D8AFA4FD36F0FDCAF57CBF7267 +:104020002DDFAF6C81FDCA6140EF7558AEE2FB95A4 +:104030002BF97E6503DFAF7CE4CE92DF16D2F59DCF +:104040007789680F24C347F16EA3FC1CB1C3283FD6 +:104050008BB6A41BEA43370D30C8F7C256E3BE4502 +:1040600041E308435D595662A8E7DE778D61BC9C49 +:1040700085C67D8B01736E34D4FB05A71BFAA74F51 +:10408000B8C350F75E5B69A87B4AEF36D45DC5F7CD +:1040900018C67314FEC450B7E7AC30F47FDC52800E +:1040A000F42567AE31F4935C1B0DFD6A1C81CF2DA6 +:1040B00020EFA6645E967C237F57B3F4F2D2AC1F48 +:1040C0002CB92410403DC7F411C66821AE3688C50E +:1040D000AFEC1FDE7004FC175B21D353E6789579B3 +:1040E0003CD9F5D431957EA7DC73C4D7A5A35BE298 +:1040F000D3BD47979A2A3139B9E64146DFAD0F263D +:10410000A673D404741DADDF248E17BB258B418F9D +:10411000687E4DEB8302F6FF67C7D7DACDE3C6BFF3 +:1041200047713D566FB744F87CA88ED0D90BD6AEF8 +:10413000B4D904F53CF3972D9CDFCB27F84F3452CC +:1041400078AFF412BF8DD657BA2A02CC2E1115942F +:104150000FCB6E46BF5EEBAFCDABD1359DC917A27D +:104160008B5BA29C7218E20A2B33FBB6DFE4980546 +:10417000E37F969840A2542FC95270523EE55FF9F2 +:10418000A8C5BF9CA07E4A181F206423DB77F619C0 +:10419000E3A68D734CF28FE7655835F9965981CFB8 +:1041A0001BBD7DCFCB06F382F9F07959634E2C2DE0 +:1041B000B1149CEFB85806D6CB6269585E1D1B88B7 +:1041C000E5D8583696636283B12C8DE5637955EC5A +:1041D0000A7CAF24361CCBD1B1ABF0B93F361ACB39 +:1041E0002B63DFC1E7A362E3B01C19BB0E9F17C7A7 +:1041F000CAB1BC2276133E1F119B8CE5F0D82DF876 +:10420000BC28360DCB61B11F6039343613CB21B1D8 +:10421000D95816C666613938B600DF2B88CDC7324B +:104220003F762F3E57624BB0CC8B3D80656EECC71E +:10423000580E8A356099135B8EE5C0580BBE372047 +:10424000B61ACBECD843F8DC17DB8065566C339696 +:1042500069B1EDD8EE8DB563991A7B169F7B62CF5D +:1042600060E98EBD80CF5DB1BD583A63BFC4E78EB3 +:10427000D8CFB14C891DC2E7F6D8012C2F85A74BAA +:10428000D9C1651F1BF79FC77E68DC7F2E3D6A94EE +:10429000E3256F1AF79FFD878DFBCFA35E31EE3FBD +:1042A00017EF33CAF111BB8DFBCF453B8C727CE815 +:1042B000963B8C7A6493518E17B4DE6DD4238D4671 +:1042C000399EBBEC27463D72DF0AA31E59B8C6D003 +:1042D000EE9B6394DF59E431A39F3E619B518F5C59 +:1042E000FB53C378AED2E74D7E4D04E58BA3F817A0 +:1042F00086F7EC85074D725965F2C9146F0790C0B7 +:10430000FEE652E2F0835F63C6673A970719C0770B +:10431000B4CCE47CD70FF88E96E9372DF4013D64D8 +:104320004C2D9B0576CC85138202B132616ADD305B +:10433000D8EF491F48583C818CB80EE2684DD95AD5 +:104340009DA8026D6F1A4430BE40D4E5150117C612 +:104350009BB1FE5BE9C10AC88B69B2F276B292B535 +:10436000A7B0FAB1C6392BA03D3DB5231B12991E4B +:10437000B72696E75D12DBDF1B28057E27D1F5FF08 +:10438000B5BCEB7E88CBFDBB3DF4AE449F2FB4871C +:10439000F2606BEDAC35F434A88E02217014FA8D06 +:1043A0001402EF4928B78D71D629A038E9F37C298A +:1043B000F807E89731D527C0FA353834B9FB9ECFD6 +:1043C0005B5C3F35A511F437D5D57C3F18FE34BD75 +:1043D00041F5E1A34E0FCAFDC86A799B8DD9854688 +:1043E000FDA166CDC6786273D312D4C7805F4BA29D +:1043F000386B17D653C1BA1C0C7181EE5C89968B51 +:104400006CD126D0275FA5751E172C088FF3B09EA0 +:10441000FB6F0C61FF15CEA965B01E0A8FAF383C4B +:104420002EF4050FFA17F4D1F9F934AADA2D18E2AF +:104430009AA9969060EDC7F653617C5FC88F7ED9CC +:104440001F25166FD7E047FFEE4BD7E23804DF4B4E +:10445000B18EE93D9E368E000003BAE67A51A3EB99 +:10446000BA247A4A8B7713F5E66FB5EF7444E67E8B +:104470009CE93B16C98FFBB6E6F72497510E5A5DAF +:1044800021CC8790A5C4FBBBB28DEF5B6D997A59A7 +:10449000FBDC3BB47534DE7C59FDDBB5FED43184E6 +:1044A000FE391C8E64CBCD4877055C1FE770FBEEB0 +:1044B000D09F6E58D14AF939429FD912C41122CDEA +:1044C00022EE6BE6D45082CB8FC37BA0C2EC42EDD0 +:1044D000BB036B8D7198031A1C375D1EFCB5FCCEB7 +:1044E0001C4AF8BF28E93D0FB2632A5B8F9755A598 +:1044F0000D417B0A9D5701A3253290BA23FA38A0BB +:10450000793E84EF5F0CE4C30D74B1FE649771DCF7 +:104510005EDFB5BC32BA2F3DD8EB3BDF723FB0CA8D +:104520009A783F95E20BF13DD064FF69A5B61FA8CC +:10453000D50FFDA9DA0E7677D3C24ADC6F6FF23160 +:10454000FD4DBEA6A38E8DAFDB3CCE4E0EF7EDDC4F +:104550009FDCB9A902F31FC96E237D0E79F8564777 +:1045600088D96FE9503ED5C6FA0DDD3C873FAFC410 +:10457000E7DB5BD9F3C16B4BF9F3127CBE23CC9E16 +:10458000176E98E080784EA3B7221DE33A75F44F7A +:1045900027EF86784322C4E386B491003C1BECF5F8 +:1045A0008B20FF0BBD012CB5790FDAB4AD7C38ED53 +:1045B0003F6861703AE4B952C2C4FC430221153A23 +:1045C000EFC7F87A73B5F690B1BD8D7F2FAFAD729E +:1045D000F970FACFBC85A18D934BF1997F0889F7CB +:1045E0007B848F63D7DA03C6F6306F575A4FA21811 +:1045F0005016FADF9904FD9A8DDF5BC7FBB928B32B +:10460000C1BC0B16061CC3615E45ACDF131ADF9AF2 +:10461000E482146E249375DF6BE5F3B62C64715657 +:104620004D3E6CE37180AD10071816EFBF46EB6F7F +:10463000DFFEC4C7548F4B0B593EA9D6DECCE7A58D +:10464000E5E514DC678CDFFEC2CAF8B85B66F15B97 +:104650008DAE92D13799271AFC3D127218EB337444 +:104660007621D403038CED6505C676FF0863BDA8EB +:10467000C45857AE31D42FF4C4613A53F471182D95 +:10468000A6F384B712FD9078FCAF3B459F479ECBC5 +:10469000F9EDC9BA12ECD7E0E27C64CAA769522AE4 +:1046A000ECFA7DF8BD9C8FF6413C84962F40FE3697 +:1046B0002DF78F0ED8F341BFBF67F16F23C9E1B665 +:1046C00095E3710BE7C3C7009FB46CE3F87C84C724 +:1046D00075D6F3B8CE5A1ED76981B80EC667585C36 +:1046E00067158FEBFC8CE7A1EFE1719D67795CE7C3 +:1046F000191ED7799AE7A1EFE479E8DB795CA79DE9 +:10470000C7752672F9BD7F624736C4D91E9F98D8F7 +:104710004F9E28337D168480262DAF224A8315E8CC +:104720009AC206F6754AEA148B0DF262030CAE25A6 +:10473000F3148BCCF271F06F3AFF0EE815CC9F7931 +:1047400093E7F5E450AB4847EFA30F4709E47564DE +:104750004DF08E8690682AA747DAE6837E5C0D903E +:10476000ACC35E307388640978E57E303EC17EF963 +:10477000BBC307C19C1911ADAD70D2F78B5E0E564D +:10478000504F9B0C2DF21F1414C8170A8880E7FDA8 +:10479000E5FE234A691C5F741606BAA073447D9631 +:1047A000A7E9876B8D7471556C2BDACB4D753C5F27 +:1047B0004A2109FD78ADF45E2B9AE249463FAA6989 +:1047C0009931DFC35C8ED861F4C38BB698DE57FA9B +:1047D0007E7FE826D1145F33E61137B9A6F7191F9B +:1047E000CF8F4DEDD35FBCC552799D3C265E77C619 +:1047F000BE8BFDCDF6A004761EB557A5A37200ECC6 +:104800005DE9A837007113E9A8C24B3F7F1EE0F5B0 +:1048100020D6A9DD1884F1295E0C76A3850A7CD800 +:104820001BD90FC21DFD908B2B02D418DA7F1B41C0 +:10483000BF224D765EA7827114988BF891397E3233 +:10484000E4DAA7210E12A911C9365A7F7C61DFF282 +:10485000AE575E852B80FB4939B5DE124B1FFCBE7F +:10486000A9569C94689F6C31A7EB95B5D3BDA83F22 +:104870000E5F326F60B1ACCB1BE8772BCF1B38C318 +:10488000F2E20669EBBABF6F3A78D4B48EFE49EC17 +:10489000EAE735BE73B1BC138DEE330AFAA6935521 +:1048A0005C3EC62222E904792B05507EF6BB358496 +:1048B000F9F1A0A0F57CD2F4CD75C887EA83EC1C91 +:1048C0004FBF5B03449F77AFCD63504E17B875A4BD +:1048D000E9C03896C741E10FFBD74D0708FF8E8A24 +:1048E000C2C17E1FA980EFD9492DB1437CB3CEAFA1 +:1048F000C2738B8BC10BFC55DE1FE7D5BC4CC49437 +:104900008A86092C3EAAC97F8D4E1A7C3C5E3F41A7 +:10491000C278B7E4AD8D02DE9B46133C6F43EDAE2B +:104920008B1735FF06F2BC323BF1DFD6A26814E8E4 +:1049300092042621FCB4FCC026775639ECD3ABF3A5 +:1049400035FB82E7A14A7E3CB790D3368AC5C33295 +:10495000C3985771BF187A4EEEA7A7BB0E844F536A +:1049600092F3056B6596F7E44B82D7F7B91CCE90AE +:10497000A393993F4AE93F419CA093F7DBD23CFDCA +:104980007743499C7FB5F63F4A0AB66BF59C988CF5 +:10499000F3266DDFCE0FB85EF3F74CFE9B550A1A77 +:1049A000FCB05CAB82FDB4BA9C699467973F4F89B9 +:1049B000E54316DF68C073C680BEF9A689F3CD85CE +:1049C0004126BBA3B088ED1BF7D81D22F150B86E6D +:1049D00035D193A647AC45DE0DC3F27BD3C5D66572 +:1049E00095AA00FB2A7E82FB426E7F4700F6055D9A +:1049F000399172B08F291DFC15E840A38B9CB6B18C +:104A000008EF1735BD57472A0209E6AFD975E06FA1 +:104A1000F9D2616493DF43825EF0AF7296331B720A +:104A2000208F2B0C54FBF6FB2E77FF5ADB4FCEA5C5 +:104A30007FE0F7FC42C3F7A7A6B89597B2EC589D64 +:104A40007EFF3443B0E8E8B2C7CF37BD47FD0B6FF8 +:104A500022B92D594259361DBD98FD77B39F4D7A25 +:104A6000E5BD9512C89BB24C997404F21F7BFCED16 +:104A70002D5399FCE278B3727FB4B73F79A7BF2F6B +:104A80007D627599F659BEA53FE9B719F34B2F3BE7 +:104A90003FF75BC6231A789E5E2FBFC3348E180E75 +:104AA0008889CE6D0C091BE12EB98C76C79556C648 +:104AB0009F839B8D71E4BCBA0189E39D3C5FADB2DD +:104AC0004CC39372FB1F29BFCD3F62653E10F78335 +:104AD000B578D37C9E375D09796C144F7348D00349 +:104AE0008D678988F93167C93B9EAB747C536563D8 +:104AF000E7E848B3F5249CBFD0F2B3E686595D9B46 +:104B00004F759BB15E45A66741DCB56A9395403E03 +:104B1000D67C229DECD2E64FF9FDFB366607559315 +:104B2000DA26906B2B793CB1D24B24C8A7AA79E93D +:104B300089B1709EA7C6C6E4F7E714FE8A2EEFE699 +:104B40006E574406FEFE68DF55DFFF0E81F7234DEA +:104B500003406FA6253E0731BBD938BF4BCDDF3CA4 +:104B60005FED9C46B27948BB8484E7151FD0E25EB6 +:104B700097798E64BB8DE13FD939924BBDBF0BDE77 +:104B8000EFE31CCAA5DEDFF34FBEFFFC25E65F6343 +:104B9000EFBE1EE4C4AACCDA20C8552D9F651109CA +:104BA0000520566379659A3A50D1F5F35D66BF1CCE +:104BB000DACF7219FD0AFB1EEF1CD7C3BFD9BD5D4A +:104BC00006FE3DFBD31353C12E58F04B0BB1533AA5 +:104BD00038B7DBCDCF8B4564D08F77EFB360DC8007 +:104BE00048D1B1B7E8F20531B3908EBFE0676EDC13 +:104BF0005FBEFB795B640A7DFFEE173F1A45281CF8 +:104C0000CEADE87E7D20D83D3F1558FE95DA35EAD9 +:104C100016FAFC6E89DC154CA0B73A391F9CF9B91D +:104C20007306D099B0EBC00F71DC8EDBAD369D5EA4 +:104C3000F88DCD8AF0A7FDD879AC6784C81081CDF6 +:104C40004F9F2FAEE5BD9D794660F37BD91A498110 +:104C5000F9ED6A9743B4DFE25D7F43BABEEE677B4E +:104C60003C0087C52F5B0CF267F12E4BD4360ACB84 +:104C7000133694F701973016E049500F2CDA57831A +:104C800079B28B3A5AFE66F1C0FB46FEA270C17340 +:104C90001F0B3EB0F8A740FD85A73D60C77EDEB97B +:104CA000D30370A5E3CE92295D7DF7EF3A3E246CE5 +:104CB000FC587AEFF1205203F4B5B86335FBDEBE41 +:104CC0009B4F837C5B6CE2E3CFE11FD9BDF547CC02 +:104CD000668C479E276F8E857D0AB22B23617E717D +:104CE0008FFEE07CBD60CFF9AD709EF8CCF37FD92C +:104CF0000A76FDC2FFFA72EB03100F7835C50BF28E +:104D000068F14FDFF3101DFC33ECCC8E3FF7CCD3B2 +:104D10004F3D46F9E4DCEF6D68E79CFBD5E95C8527 +:104D2000AEFFDCDE7F64C1B9DBFB7E35B13FC0E3A3 +:104D3000BEFDD7F5EFCBCF00BA8DD8F4F88D207E2D +:104D400095970596CCFC0A2F4D783AB4EF502ECCAF +:104D5000F3EC311B9EBF594C9FD59500DE6A503F46 +:104D6000407D1985F7A2DDABFE66199508EEEA4095 +:104D7000113745A203C1C85EB4EF967F195F0AA53B +:104D8000D5AFC078A41BE5BBF9BDC547297EAF4CA4 +:104D90008ECFF3E46B19E0BF78F76AF6DD0E8A4F29 +:104DA0004F6F7C9E857F8CEB8DCF12BB199F0B9F25 +:104DB000C4D8E8BE8C8479241A3E6BF6DFD6A7DD12 +:104DC000A0C9874BC1791ECF9BFA2F5BA0C20E7C76 +:104DD000F6BC53F5313C47A6D0B6737BCEE7124AFA +:104DE000279F5ABB7F0872B2FB57362FF81D77FFFB +:104DF000EA03E4BB73FBDF961576FEC42550BBE2E5 +:104E00001CE9F9EB043B6311DF335BBCC31DB579CF +:104E1000E2F85A14993649F1E0F313F83CC2F8610C +:104E200051E4C0AD4202FC2DB31730FD14E9877088 +:104E3000A9A19E0E9CCFD7E35528037C9EB81EE8FF +:104E40002F193EB5F57B61FD57EBF0BA83F1B1B98F +:104E5000FF22CAAF20877BE137227C00E5B9769B31 +:104E600004F991E7AC2CFE66C67B1CFEFCFCE4B7A3 +:104E7000B417EFB727D97FE070B814BF5F6A7DDF42 +:104E8000167E73EC0A8E6B86E399AF13EB838D5C11 +:104E90007E2C22B59306E8F499CD4AF5593ED87B8D +:104EA0004175A0109F6F538705E5FC995D9608E852 +:104EB0000BB3BC584412EFDB45ECCC7E59F4F281C5 +:104EC0005120D7CE1CFC39A74B46F78B769F9055C7 +:104ED000AE1F227AFD90C4DFFE291F6FF12B89C718 +:104EE0005BBCFB6F09C7FB5C0ADC0EF3FFBCD34A5B +:104EF000543AC4E71D964989ECAD4D76AB31CFD617 +:104F00003DF6582A7DCFE27128B0EE8615810F5408 +:104F1000B04BDEB1629C9648FE4F6D78DEDAA1ACF4 +:104F2000A1706BF054613C451BAFD10427C91744F5 +:104F3000BF54CA0C96329B3A62F0A7ADD4DFD5CFEE +:104F40009BEADD1CD04BC7479FB6C23AFF6CB21F2D +:104F5000FF2C91A6FE74BC3FAB827FB992C85F3430 +:104F60008E1F5A66218A5E1FDABA8FC37CC8AF5380 +:104F700008E4AF595E4D51419E2CDE9A12817DCDE1 +:104F800043FB2F3C05703BF7A48DEF73B23CDB6A0B +:104F9000BEEF777AFF85ADFF49DB4FC3CBF4FBD57E +:104FA0005B697FB0DB773B315FF3AFCFA78E2254D5 +:104FB0004E57FFFA81A9205FAAC1C7A2FDAB7FD6D9 +:104FC0003FD240C73BD58FD54FED191401BC2C7C87 +:104FD000E1578B409F2C78CE4980240FEDFFE0876E +:104FE000503FF76B37E67B9DFBF5E9EF021F507BE7 +:104FF0005BD1EBF5F9FAF3DE74DC055067EDC245E1 +:105000002EEBC08F590025A5F7052FA7E2F9075D04 +:105010003F7C6FB1ADFB7E1688520788E8134507C9 +:10502000001F2ED865FCDE5FEDCC9E5A2C7757B161 +:10503000FEE1018C5F3BF1BDAF353AE5EDE6F7B53A +:10504000FEFF612F308DC3DE5F6423B589E8DF96F4 +:10505000C2C65DB0EB9B61C6F118BDF6FE0E7BFECD +:105060002381E5E793BD29B84FB0508E0E4D2FC672 +:1050700078C73CE0DB859EE8D034FABD5F7279B931 +:10508000D041EBF4F9003E0FE80F7562EF7A0EF0B5 +:105090005BF3520A017AAFF9B51BE3C9352F5E38CD +:1050A000F5387D7E66BF13E37A35BF5E8AF8AEB110 +:1050B000457F08F1BDEEBD36B28DF63FB3F7B7B907 +:1050C000608F9CB14673D3FB880FD574D87832B803 +:1050D000711DD42F28AAA5F35137B0BC9C3AC2EE5B +:1050E0001DA883A00ED0F18729EC1C31DF97BA8769 +:1050F000C7A3BE98A3A4E2FCAFBD893DE7F1867BC0 +:105100006E56FAA7E9E6017973E42AEA97C8B5C3AF +:1051100040CE5A62371105F6FF6283B1D4FA59E0E6 +:10512000FE8662C8DF62FB7ED64C3FA9A6E5D2743C +:1051300012C2F397AE1B7BF8EC7714C5F76C56FAE6 +:10514000C378FE14265F6A1C81F129980F69BC7729 +:1051500041DDCFD67581DFA7609EEF05AB6A03798D +:105160001EDFAF6379837592F201C47DC9112E975A +:105170007AAD9FF1D917DE74E4336D1D2DF55E9481 +:1051800027ABEB7D58AEAA2F220AE629FBB16EE1D0 +:10519000F0B015AB04EE99001E843F9B2B1880FBEA +:1051A0002C604C88B75B5C21A42F9BAF16630576FF +:1051B0007EFF8EC5A5926A17C467189C206E0C707E +:1051C00092795D6A9B8270A5EFE3F3898ED09C94FF +:1051D0003190EF3BC220A7E4CC1243BD17DC34BAB8 +:1051E000D8F3BF0D3F82F05A5D6FC772557D19C26B +:1051F0006D657D00EBFF1FE0D7CAE0770D5174FCB1 +:1052000023675618EA49E1B799C22F33CE5766385B +:10521000D4F1FC1C8D9F92F1EF23F504375F36D655 +:10522000B761A93D4F4FA2D7CFA6307BA48E8496FD +:10523000E33EA897C56148A64A7274F127E253F18C +:105240001C089E3785F69C9B307EA9E1D7E2954EDF +:1052500019E59FF201AC67E91B5611E495A56E3B79 +:10526000F92843C7C75382290AC2D98F71E006AE15 +:105270005F57F6E0D3C81F2DF50A966B399FACE750 +:105280007CB201F00EF13DBF88386D9D44507F3EE9 +:105290004CEBCCDF8F127D3C3CCDDF11B552FCA333 +:1052A0004C52B064F7701CB34586D0F79CC52400FF +:1052B000F49276ECC7115C2BE9C0F3D669DA3D3085 +:1052C000AF14A4CDC4FD1F62657A8A585819B682FE +:1052D0001F65866F83FF20DE2F916C3EE5C7E70BCD +:1052E000F0BD0B33D99E59E69D1DC7E03E0857AB74 +:1052F00013FDCA2C7F6D5E2ECA571BD2ABCB1F127B +:10530000AA7578CC4A62FF2D734CFE23D0E38790B8 +:105310009748F1BBB16D700AC0B9C5DAE10379D81D +:1053200092C6F48D3283424177BFD86B5C4E7A4A85 +:105330008D724093CBDE6B4B0CF4ACC9DDF40946A7 +:10534000BAD7E4EECF7AE46EF02CC8DD8CD816E440 +:105350004B331F34586555B812EFA361F1A7130200 +:10536000DB57EF2D0F70DFFD8BAEFC6D701E5BE326 +:105370001FF3FAA5E6C9F89D1E7BD09A381F60205E +:10538000BF97A199D21BA174D44AE90C10B18ED257 +:105390001994614A678C9FCAB0D4E8780561324499 +:1053A000DD27B279F278ADB67FB2C25E12003CAEB4 +:1053B000EC603C34C8C1F7493345CC0B90A83FE9B9 +:1053C000A28FA403E3EC605F4A56B68FDFED163B75 +:1053D000601F7FA56BBA1DF24A85B452A49FAFDC53 +:1053E00095797DEDEBC0FD6B407F5E979F9C2C8E89 +:1053F0009F9BB4784B08F8A57B5C9D98DFE472888E +:1054000086FDA71A47A8C0A1AB8F84AF73BCC3B0F9 +:105410007B929CBF1CC5D743725452A893133DF78F +:1054200025292A29D2C98B1543AEC7FB987ACB8987 +:1054300024F270E7FF8C3C6CC88B205EAD66F9935C +:1054400019C03BA068A9C2D50AD43A5FF983D148F4 +:10545000A7D739C00F716DEBB183BE57D07B9E6665 +:10546000F917D76B0AC6C1A85E7BB40CE46952BDBC +:10547000567B17D271EB4005E8F8C0BA079E84FA54 +:1054800047EB6C78EF4B556C3551E87CAB63E3B080 +:105490009CD7F61096956DED94890859BEB67ADDC5 +:1054A0004CE8BFD982F19F5391ABCED5D1FAA95622 +:1054B0001BDAEFA7B6DC9B07F6DFA956A762017BD4 +:1054C0007FCB18637B33BBFFE5549B356261F47B74 +:1054D000D102FB1184CB778802E9E64B4A15B4E38D +:1054E000BF30EDB754AEB705044F72F857B625B6C6 +:1054F00027F1FC36E45C93DA61205FCB8FFF380F35 +:10550000E84393334BD3A9DC03F81DB79144FB0266 +:10551000131D1317039E263A024B19BE2EEFDEAC65 +:105520008F446A77239E429E6986B82F8BAB7EC4D8 +:10553000ED72624FD2EEE1EF7B13B7D7B4FEE5F523 +:1055400007696D55B131AE6D8178B500FEF83496BE +:10555000EFA0ED03F5A66B664FB7DA50AECCE1F1E4 +:10556000288DCEE37416F2F07C31031DCE8F6D4092 +:10557000B927B48C7C741C85DF9794FE803E84969A +:10558000F1FD01BECBD77C67FD9D74FCBFBF69C137 +:10559000E7F36229D8FFB307FD8FDE09FEC2BF5BC8 +:1055A00009C89FBF1F9988FBC89F598D718C7227AE +:1055B0009397AF72FEAF8AB518ECF3AAE6D932C45E +:1055C00041AB62EBF079156C22611EFD1DAFC10687 +:1055D00070152CFD1A78FFF6892B509F96601CAD34 +:1055E0007AAD2D619EFFAB0EC520AFAABB5A715C90 +:1055F00042EDB3CC2C3E9E4EEE54C732903F8857BE +:105600002590F75DC5E54FCFFCB6580DF2E7B39492 +:10561000C4719AB71C6C9D55B1EF20DFF55EDF7742 +:10562000F17995F6DD2EC6A7F1F53C3A2ED17AE256 +:10563000EBB816FB7F9696F8FBE7397C4FD5CF2366 +:10564000012ABF2A6DB49F0BBE7F6F5319F8F95B17 +:10565000D2D205DDBAAADB1690806E5DD55B66C935 +:10566000FAFB29E378B8CF8087F36B16231E9639AF +:105670008227400F54B68C1F15423F7F35C2F92355 +:10568000AB3F17E4F1E9B67B3D89EE913C6FC64F25 +:105690001BC70FB5BB4B75F8D1F0627EFFD49FAA34 +:1056A000BF7A10E4D466B741AE98CB5E78CB4F0C8E +:1056B000B7544E9FA7A8FE0E21DC94178F015DAF53 +:1056C00075627E5C72F85D41427DC12F89FD4CEDB3 +:1056D0002CBB730C7C97201CAADB181D5C0A6EF196 +:1056E000EF723A284FBC9EF14E8D0EEA884A19F6A9 +:1056F000A47C293A7880A8F63ED6D143076DAF95B1 +:1057000017C6E960BC333C7105EDF729D83FC37A71 +:10571000E3FFA4AC7AAE017B678D05F7BD4E3AD4AA +:10572000AC3B587D34C8E7939EF0D46B4AE3F5F95F +:105730003B8778F4F73A9E6EA6704800BFF1CE24FE +:10574000F453A892E2B1FFEFE8E7A324E760263A1A +:10575000CACB019F249C389EAC959AFCB6A4BA7A19 +:10576000FC5ED0A3275D055F4568EB3A47E86627F6 +:105770006D6F4CBB1FF5FCC99302EAE1E57F5A3A15 +:105780000CE4702FFBB73EF6D8C743306EF9F8C76C +:1057900056B4A7705C42ED1FD003986F8E7EC04058 +:1057A0008CB324DBCFBD172EFF1D13DFD7D5F66FCB +:1057B00057D6773E04E313BB4ABCDA797D054A66C7 +:1057C0008FFD07CC43179F97AD21AF1FFC5D810470 +:1057D00081EEAD52A819F20CADBECCD1AA0ECE4BC3 +:1057E0009C2C2F27E5F0E1E67CFA7ECADCDF7921EC +:1057F000CE67A3DF81D29E237DA18F975B3359DED5 +:105800001729D43D2F8073C8B46E883BD0F9F6E1D8 +:1058100037FF52E8B9670DEF379EA95DF405A0A3E5 +:1058200074F37B2D7F456A64ED695A73236BE771CE +:10583000D4C5952C4E7A68562AC24F5BD7CC5756A2 +:10584000E17D6B335FC9C6F34C335DC33E0178FE27 +:1058500012126B80EED3987E36D3C5435CFEFCA05B +:105860005D54AD74BCC3D6EE834EE08B1F09E85780 +:10587000DFF1DE612B90FC1F8E9EB4425ED45D9002 +:105880005844D7338B283233A223F8FE6CD2E1661A +:10589000F58E7E70FF697C3CEA32C3784BD8FEF30C +:1058A0001DEF1D9D086A948EB712CABBDE24328C90 +:1058B0003F6B9FD2C48E43F1F15EA1E389F1F17A8F +:1058C000E027D9111E71F8D8115EBFEF395FA2A28F +:1058D0007DA1832FDA2B1A7C1B006E147E33536755 +:1058E000DC484625E79799AEA19F9051F1F998E1E0 +:1058F000FB7768A2FCF68433B017F8AFD119781E95 +:10590000F867A1BD3B572AC073602FC2F34596507C +:105910005E16A5ABB38342C3FAC1BD1E9D89F7795C +:10592000CD7C7A1CF8E54A28295FC03CF879951FA0 +:10593000F2751EFAF169379E47D9FF412E943596CC +:10594000AEB5B703BFFD9B05EDCF2FF60DEB33AF23 +:10595000EE388FBBBCE514F9796BB6CEBBB83D779A +:10596000D73E6704EE41BCABCED2E35F015DDF55AD +:10597000C7F24F88D439EA56833DD9C8F7437A8FA6 +:1059800003FE82791C6D9D0773075C01FEE593633E +:1059900064F4230EBCF9C5EFAB69DD31C88E7EC25D +:1059A000DA344EBFE5CC6F7D322DE01C09F1AF3506 +:1059B000E97E95AE73CD6BA443A4703A38FCFE48E3 +:1059C0004529DC0B2D62EC6C7D6C7BB802DE2B660E +:1059D000F7CE78B95DBABEF3641BD0E3E96336DC79 +:1059E00077F8CCCDCE11AEB10673C18EFFA45D4E5B +:1059F00078FFD99FDD12CEB75DE81280CE6793B0F5 +:105A00001DE4C5BECEE9FD613E1E3FF102F99FDEF9 +:105A10006211D9FD685ABC252AB178BF2AB17A80B3 +:105A200097DE14FD7D63AB274DC03C8F39AD6F63AE +:105A3000329EA734F13D3FA92E365F7767FA64BCEA +:105A40007773828879D86E7FB700EFE57556C8F80E +:105A50007E58E8F3FDBC655ECC4385F741CEE75D3B +:105A6000E6FB3617CBD3DAC0FDEC76ABBF69021D7F +:105A7000A77D6D9A00F8D0FA292E26574E4FD0E216 +:105A800048618C23E5167A53E01E8BDC00323771B7 +:105A90009786F1BEEF6DD08FC559110EEDC35F8CA7 +:105AA000C23EF61A88AF009EAD8C9ED6AC1530AEC5 +:105AB0004AE13700F4C4270FDB6E8275E4350B5ED4 +:105AC000F0DD699970DE33DC7646E7AD8FA25F08C2 +:105AD000615A183777CBBB382F7792F5AE70B37B0E +:105AE000F23FB9047D7CE964F726E6D675F2FBF156 +:105AF000A2780F5E18E004F54029BBDF440A28FABB +:105B0000FC9838FF2CE7744802B0CF56592647203E +:105B10008E2036B7CF8075CF0EDBC80D747DAD42B9 +:105B20006700F8451D23F2FB9402C7014EEB36F4E3 +:105B3000C73CBC55622017F4B0FA7F64DCA73B1861 +:105B4000F86233DC1FBFB54C46BE381860E70D9FC6 +:105B50005C56D00EFB94EEBA8AB6D974BC88574610 +:105B6000C9D2504ADE1806FB94CB44AF40FB878372 +:105B70005ADEB6D7017431DAF2E5E422D8C7CB1683 +:105B800031A6745A60F736AC5C56E105BCAEF466DB +:105B90000A7AFFE5764E07C7D383B7BB287C7C0F14 +:105BA0006EF452338EF267C6151047549B65453B21 +:105BB000B70BF73D6470BC64748AD12A0FD65DF3CD +:105BC000D2E13E5D162F7DE8C6108B73C2DEE85829 +:105BD0008C73F23F1FE23593D7D68C706065D38A01 +:105BE0002AEC0FE364D171324AC5E8583AEEB6B4F4 +:105BF000C0568CDB4DB4239C88D4D506708A4C1CCF +:105C0000E0877B6D378E1BFA369C5FC938D23D1D0D +:105C1000F4686490E30FED20A756CA0AF079C6B283 +:105C20005377C2F334FF23F74299D1F8FE0320A73C +:105C3000D3BAFE568FCF27C986F862C6879F7D03E9 +:105C4000ED1941D910A7FC3A3DF81380CBD6E2708C +:105C500018EFC5048C66C5D7B16779E724B8EFF8AB +:105C6000F434D1BF8DB7E3BA3679236B18DC4A41DF +:105C70002F68705B252A1D5158D7543BD24721E924 +:105C80004479950DBBD983E378C9F870F512C8D76C +:105C900030CF679D4BE8B97F03EE09045C417E8CF1 +:105CA0009CCDCE15EE2DE9F4813DBF362D717CF2F1 +:105CB0002D377BDF26B238ABB9FD0D37A30710892E +:105CC0006D252C5F7E24942EA2A64299630F40FE80 +:105CD000F35E51F923D2F9468B02F881FE568ABF52 +:105CE000036F7C8EF1C503E177B17CC65DA4E5DD71 +:105CF00047B3E8FBEB4AD97DC7EBBC8C46AA9B991E +:105D0000BCA8F675D961DFA4BA9878B7717A533513 +:105D10003843BC8CEBABCA5B195C338B09EEFB429E +:105D20002C08EE9BCA827E147E99CDCB97201E490B +:105D3000A73A98F65B07E3027E1A45C2C6EDB22386 +:105D4000FF862DB8EF49F9FD2D886B55B6F6C77D56 +:105D50007F38360CE3A5F3EFA6F3F1DAE938103F0C +:105D60003CDD6CC17301907E03756519A565A4CFF8 +:105D7000EEF2223AAE52EAF5AED1E84093639435A2 +:105D8000E6507D01709BA3AA4B80FE4EDABD6FC02A +:105D90003C9C9B6C0AAC7FCEA6979682FDE2F47584 +:105DA00035837CA82E63F34D6FA5CFD1CE51DE8213 +:105DB000FED5AD36857D8FC3AF94D31987C35C3EC6 +:105DC000EFB95BD8BC1D832261A0CFEA6514AED0C9 +:105DD0001662740F21D18B22F2D51158BF5BCDC250 +:105DE00071FBCD30F18589FEB47555F275552E6382 +:105DF000EB229C9FE8B4A2306E65295BE71CC2DEF3 +:105E000017E1391D7F2E5F4FA5FA2296739B6D8691 +:105E1000F1B716EDE884F9E417CB0A9E1321ECBE26 +:105E2000C35CBEAEDC46F6BDDCE217115EA44E37A5 +:105E30005F8CABEAEA94AF4EFF9632165C0A00071D +:105E4000D8E8B8277F2CE37E4EE126E3BA4EAF1E9A +:105E5000B6BD95B67FF4B08CFBDE7B45FFF13CF41C +:105E6000476585C91FFFBB53404ECF6DF4831CDFD0 +:105E700053CEE07FFA6612017A187224980EF01E53 +:105E80007224C4CB5ADC4FA700117AE41E9D1F7503 +:105E9000999A059097B1C1CFCE033950C6EE231F12 +:105EA000A49F379D5F46735605E4436596A557C882 +:105EB00078B5ABA9FDC863D345683FFCD8BDF09D5C +:105EC0006CA25B0F6D973D83D97996C3B415FAD553 +:105ED0009D7A10F0D1CACFB90E8199A5637918CAFD +:105EE0000CCADF2DE9304F894C2889CB839D0F8F59 +:105EF0001D0D7205539E4AB08C9292DE7243D77F7D +:105F000038EFAF0A09FAB93D8AC13FDFF9F0F5C3AE +:105F1000C18F5F0776622ADCC7E6FD12F27454BFB8 +:105F200088705F678DDA8B697D15B51BC17E595FFF +:105F3000F4BE087CB76E1FF1037D6404FFCBA6C7D7 +:105F4000E30D6EF6FB3C924C5A80FF0F0E3F350975 +:105F5000F0143940ED4EDABFE237AEC79C600FFD5A +:105F60009EE5C1B4FFB616F5F7FDB972C2FB78C95C +:105F700025EC4473FFF421D3319E97B76903DEEF1C +:105F8000593D49F2DF407B676E2A2F073B46095295 +:105F9000EAEA4FE7BD65F4726042650ADB2F5326DB +:105FA000B1E7CA0456B6D41F7908FCF6F02E29A52D +:105FB00090CE77C46A76AF584BF117F610B54B4BBD +:105FC000CB9FB7DF4C9F7F5C4AB5207DFEF1B55F6C +:105FD000A4C0FECE93A5151900CF7DCD46BB8EC0C3 +:105FE0006557D41F1A690B07DC745EADEF1184A7E7 +:105FF000C5166DABA475CB4B2EB0707AF939AB5B7F +:10600000DB67009DCE2992316C6F5EEFFB5C9FCC0D +:10601000AEEB9E04F7EBE7AB84C5F7C38FA2509EAF +:10602000CB4546BEDA8942C7BD89F9276129F03AD6 +:10603000C8E570714886573479D63AA4F22990673A +:106040007FE2761DA99D87E7C890FF2D600F7597A9 +:1060500027F29B4A5D0EEC7F7ACB2D1F409C7A4E37 +:106060001DB3F7F3B67C29203EA8DD974DC7CF2B93 +:10607000C5AB06C99C6561FB48C04FA1481405E645 +:10608000D341C04F0853FDA3878336EE7FF7FD252C +:106090006E1BF26129D8CEBAF5B8F87A72FD743D5C +:1060A00009F47409FFEE8F9EF8F2C03880FF32E6E3 +:1060B00022E5854F0876DD3CF2D4CB9BC755301ED8 +:1060C000D8AF6E2F8EEB2EEDC2FB5CCCF21DCC79DF +:1060D000E0DBADCE73A3997F6F94A7BDEA9CAECCF5 +:1060E000CF734DF26AA4ADE346C4EF1E76EF35647C +:1060F000C442BB404485DDFB19D1EEA7AE857E23AB +:10610000DC2E2FD041EBF0F74B003E6BB9BD30B722 +:1061100098A0BF3A37A713ED85D98DDC5E90FC4D72 +:1061200020649D5BD2C81A9DFD80A612B8D08DDC7C +:106130005ED0F43FD7DBD5BECE66D4AB8DECBC5F72 +:106140008F9DA132BD9AE7637ABDBA997E47E1C4BB +:106150003C566F97303DAE6CE2F603D7C319FCBBDB +:1061600099CD4C5F65801DE181340815F532EE61F3 +:1061700065C5ED967EC54C5F66B4EE45BDD6013F64 +:106180002E3306E406D39783DE3EAA02987CF47190 +:106190001B95D38FF3769F97DA67E971FB6C95C8EF +:1061A000F79B08B30F31E79FCEF321E8AFB31B771E +:1061B000F0F9ED3D9C7E13C8D79DE1023C57AEF14E +:1061C0002D463F693DB794E5AFE4D6B17D72B7BFC8 +:1061D000EA29FDF9B3796E76EFD03C8DAEEAA23EA6 +:1061E0001817EF8540392E637C7135B59730FEC4A2 +:1061F000FDAB6B5C3CAEC1E927993ED1E4909B04BA +:106200003CC514BE1F479E4279AD527F09D6F67138 +:10621000B861C0DDC0EFE169A530FF75E3BEC2FC27 +:106220008FBC24FEE29F353FF35BCA75F7A4A3CC75 +:106230000FED14139EEFC9F1B0F84387449C00CFD3 +:106240009430BB472EA54C4ED83FD5C3ECECCF398C +:10625000DCD68D7B0ACF6726D5CF12512D09F4A944 +:10626000A66F5B01CFD7D0FEEE379A54F4D323410B +:106270000BCA57767E314CBAD08F548B648C1BB6C8 +:106280005AC376C0C7FA528E57AFBD1DEEB7F9D6C6 +:1062900078A1F0003CAF0E8811211FF01CF18E6434 +:1062A000711D3CB77C9AFAEFFAFD8AE11E91C34951 +:1062B000C11FE6CB6B66F4B56E9C8CF358333AABDA +:1062C000DD92AF97BF02979FEC9CD89A71AF237D68 +:1062D0005DEEFCAAEA9EC57B3FB4E7A7363F5D00B2 +:1062E000708EDF7F11E8F33C4555DDDF36ED48B0B9 +:1062F0004FD0D30E7E940BFCC0C81D867D4D8EDF23 +:10630000091ED1107703F96A45E7223200E24B7B80 +:10631000C6473CF01E59C6F66DE7F37DDBCF77DC50 +:1063200082E7C94752B2B226C0FB67F5C6F3EA9FBF +:10633000ED7C7A008B6B440C79C2F39FFAF908C3A9 +:10634000FE7080289963F915ACC0EFAFFB559B2513 +:106350007EFF800CBF57007176E0E0C170AB620732 +:10636000962EE05F5A7A4837965E504783C14FF2C7 +:10637000639949825866915A2C7D248CE500D2811C +:10638000650EF8B983412F7463A910AF487472BFCA +:1063900080F8B15E4882584A80B78CF8BE84B4CB8E +:1063A0008EF91BB07F017C9FECDC99DF53B9C4836D +:1063B000FC5D7B25FB1D23B65F31DD13B8C78378F9 +:1063C00088A2FC9ECD45F991E74674C0F9A37BD61F +:1063D000B2732F9A7C47FF867EE7D974A60FD48DBF +:1063E00002CAB115CEA9DF4578B65ACFE8F71B88A7 +:1063F000DD5E08BF0FA28D3B9BC71966733D08E1A8 +:106400006E767ED08FE7936643BC41D74E7ADAD959 +:10641000BD34DA38A2F3DAA17DEDF7E9DEC7FCE896 +:106420004A931F7049FD6DAACF31BFFF359D50566D +:106430003C1EF7EC77955CA457AEBF294129F85E66 +:10644000B3ED04FA63E189013D5C9EE17CA0E9952E +:1064500039A67C0F733947E2FC611A876AC0343869 +:10646000D78B774AE8F85BBB9F54BBBF677E20247D +:1064700067B3D77C80472F9F77986CA9C8A6E5A7FC +:1064800050D7C5F78FA6865EF2E8FC116FA056D4F0 +:10649000DF77B390F3E3444B6B39C8B9D321E207FC +:1064A0003F623EA9F57C07E2F9472D28E706D2793D +:1064B000CBF07B2FB0C1918E75157EEFE56C3D3B27 +:1064C00027748ADF33FC14DC4743CBBFF07B85475E +:1064D000B62D9D0A74F039BF5FB868DFEA20C47D2D +:1064E0004676386781DE1FD931BE1ADA47EEB2B17F +:1064F000DFF1E172429B171C7377A4E33976D59ED6 +:106500000EF284A0DE3DDBEA88C0EFFF9CEDB0B068 +:106510007B558B45BCBF0CAE21B4F0F9A5A6C3F7E3 +:10652000FEF387608F7CCEE5C9194F1AC397A40A82 +:106530006A26A4A5103FD8351B9C8BF01C64952BB4 +:10654000F2D46399901F6EF7AFA0DF3FB0F7A55C60 +:1065500078FEA87311967FD9FC412EC8ADB3FB3FDE +:106560009013D16D8D1495213EB5609F20C2FE49D8 +:1065700079C72C19F647AA761FC0B8728D3784EDFB +:106580000BDBF6627DC2EEB771FF6470AA82F33A4C +:106590009B1DC2386F619B2D0ABFC7B1A7207C77B6 +:1065A000C27DFB54A66736385FC5F11F75BEFA3A47 +:1065B000C265B30DCF7F1CD8FC1B1CF7CCFE97F82F +:1065C0007C09E60B9E4DE938FE13D05F7BF9794CD0 +:1065D0007BA7471F0F965205837C3DEBE6FB5E3998 +:1065E00097E8C7F30589ABD3C3E452A707F6CDAA52 +:1065F0003A181CFE628DCA60472EE81014F83DBDA3 +:10660000F2DDED781E70C13E3B9E975800F000B859 +:106610005178215CDA0EE0FC0B002EFD601DEF626C +:106620003E7EE13E0A9751F1752F7085905FB5F57A +:106630005238B075EFB9149E42463CB5BD2D435C4F +:1066400066E13E01E1B770379B47D53E36AF09BBE7 +:106650006721FECFEC270AC45B4EEDFDE07358CFF7 +:10666000D9FD76BCCF579B17DCB7E02901FE6174DA +:106670004AF631B9AAD9DD35912CFCDD819EF6DDD3 +:10668000EC7749016429945E47EE9B86FB82A54026 +:10669000BCC0FFDE8E11ECF705C3B900D73DE3A304 +:1066A000B930EF33DAEF2349E15CC08BDF132A4DB9 +:1066B000D5E1E3B3132FA15E2C126BFFFC20F0F1A8 +:1066C000F3EC7738967EB841D4C3E33AF841AA3167 +:1066D00000B7B73C08B79EFB5BC22C5F8A84901F53 +:1066E000AB383F9E6DA77E275DFF676D2F60FBD99E +:1066F0006C637ED55FDA0EA503DC2AF9790C12B93A +:1067000005E511854BB33D819EEF39D71661E7153D +:10671000CF09FC3ECD2734B8D5CAD30DFB7C4C1E27 +:10672000E66CC93F8C7E4624F13947B39D64BE2F89 +:1067300035593EC0492ECF3EE6F774697A77BA27BD +:10674000342BB55FF2F3DE952D35B900EF4A381BD7 +:1067500089F79C1EB801E215786E88DD931A05F85A +:106760009CEAB907F5A51B20CFF4541AABD7A57640 +:10677000AE02BBF69476AFAAFA1A7B3F9FB56F8242 +:1067800076DAFF394FB03695D9F702FB7D1F6B1AC9 +:10679000FC4E83A63792C3C1F83B0D4FD3B5025CC4 +:1067A000E8783FC1F1243ADEC87F7E3C4D4EFFD3EE +:1067B000E3D8FF67C7D1F417F027A43E12BF7FC408 +:1067C000FF04FCFEBBEF93F05C035F5DD83CB809AF +:1067D000F6D1CEFBD83D30B6D6E504F4F9DC4D1B3E +:1067E00012FEFE5B4F9DE7E5C88329BFE9F8FA4832 +:1067F0002AB3CB8F70390D7FB0BF0577E5A05D4C14 +:10680000FF5AB3307509FDE761FC1EF3221246FB07 +:106810007404E9C0B2987462398A746389DBCC83EA +:106820002154EAC7F2AFE55D6361F10BEDA1275397 +:1068300044CC3B780DE4D0D941A1A7E1A2B615CE56 +:1068400045D7C0FCDF48F57278450DBFB742F4BFAD +:1068500087A1803D38C5D7973D48BCD2999EBC974B +:1068600002BCCFF6ED545C5FB2DF515B62BAF786D3 +:106870009D0BD7E050433A308FE4B52DF7BC319CE7 +:10688000C2FFEEDD6EB493876E695C02F2FC6ED2DD +:106890009905E78487F27B44481BBB0F47BB1F6405 +:1068A000789BCDF83BC2A6DFE359C07F3F6B81F9EF +:1068B000F7A9F839DC167890201FC37C8EF7AFA9B2 +:1068C00089EF7D21C5897F0FC57C8E77778788F911 +:1068D00051F740DE95CEBF18BEA3D666A42FE5DFE4 +:1068E0000AADBABAE067F108B723B053E8FD9DFFDF +:1068F0000B82D8B2B4008000000000001F8B08009B +:1069000000000000000BDD7D0B7854D5B5F03E3360 +:10691000679E99849964924CDE131E21C86B0221F4 +:1069200045A47A122246A43A3C6AC15A9C8040800F +:10693000BCA068B1C59F8144081425D488400107D4 +:1069400044C5FAE8A417E561B00344448BBDA15ADD +:106950002F522F1D901F1111466DD1F66AFDD75A87 +:106960007BEF6466480AF4FADDFFFFFEF4B3877D2F +:10697000F63EFBB1F67AAFB5F70C77288CA532F668 +:1069800082A2DCE31DC4D837F87753D773AA5DC75A +:10699000D808067F8D6C5C31630DD5AA7D15941ADD +:1069A00002564DEF84A75D1750F219CB4A2C33CF16 +:1069B000853273E8ECFDDC8C8DD58F3EEC86F6C617 +:1069C0001A75B809CAEDDBE67618F07B97CA4C3029 +:1069D000649603FA8532CBD005FA41B9D1FE1BC7C4 +:1069E0000C18BFC006EFA19F1C3B0BB8A1DFFD5BDD +:1069F000EFD761B9A19EB1741C47F175B8E93B9519 +:106A00003D85D362DAF8A234C6F2F09F308ECA56C2 +:106A10007FAA4F62ACBCE6B4256C83F7E1CAF16C87 +:106A20000863A5F67C5AA7FAFEAD1F6179CBA25385 +:106A30000E1F8CF7C6D6E57F180BFD1902302FE824 +:106A4000A2F0EB86E36361BCC85623DBC6BAE090D4 +:106A5000BB583D1536D380EC1BF82F7B616CD9C831 +:106A6000A05C28CAF9388FA87A280F17E333368537 +:106A700085D2B05ECCD7A93106F364769BF3CC40C7 +:106A8000C66EB22BEC9BDE5DE511A2BCC3D05C668A +:106A90008579EEF84FC5B314AA0F6C9D9587EBBBB3 +:106AA000B4C7976787752C32270D61BD2EDF3F83F2 +:106AB000DD2DF6CF6FD1B9F019B2305757FB01DB9E +:106AC000EB4D3EE8A77109F39CEEC79839D06E1DD7 +:106AD00088FB78D8E081227B4861538250AFDA98F6 +:106AE000168471860B7C897F3EB4C4FDBBBE86AE26 +:106AF000711FFA7AD214DCDF48A255DBA65C3E2F68 +:106B0000F99D6A77FB717F0DD9CC9300E3199C1D29 +:106B10009976F86EE02EA3C706201BFBEB41BDC2A1 +:106B200030EEC08353993B91C30BE7AB2E327A4EC4 +:106B3000A730665AE4F4A8C3B19D8DF0F1339B31C0 +:106B40006042F82FFA7933D6376C2D71B9A3F07AF9 +:106B5000F912BB4785796E5A62F6A8B0C0E5627D2E +:106B6000F1F3CB71E8BC01F8CEA8633EAC5F00FB4B +:106B700080705C604FA0E77C51DEACFA27E2FC3706 +:106B800003FE2C457C5DC8F1774186398078BEE0F4 +:106B90008D3EE9AC1BBA92CFA797B83C7D611E9B96 +:106BA000164E7731F8B4747EBBE51658FF8244B3B5 +:106BB0001DF1519F54F0F868C4F7370D0CE9AA2174 +:106BC000B1C43D23AA3F7DD24817C243AFF3673219 +:106BD0003B632BECD32AD40CC417FF46E6616C4D03 +:106BE000F3CDBC9CE8CF54A0FEF1E65B7939D5BF6C +:106BF0005181FA279ABFC7CB39FE4C1D949F699EDD +:106C0000C0CBFDFC1BB1FCEBE6EFF3F26098432632 +:106C100063BB9AA756F861FC0683678A07C67D1195 +:106C2000E63F08E61F14CF3D76BEAFB2FE37F81E32 +:106C3000E0BD533CE3EB5F16DFEDEEA17EAFA86F46 +:106C4000EBA1FF57C577A11EBE3F20BE6BEFE1FB56 +:106C500043E2BBC33DD4BF29EA8FF4D0FFEFC57731 +:106C60001D3D7CFF07F1DD3B3D7CFFAEF8EE580F8C +:106C7000F5C745FDFB71FD9F10EDC3E27D7662D344 +:106C8000713FE05D36F02DFC2B4C6C4A46BCDB546A +:106C90005F4CF8DF3002F07C5017BE672BCC8BE5E1 +:106CA000210E95FA1B82FC189E6F8BFE4BE7F75D59 +:106CB0008378B7E02DBD07F1B041F11CF341FFFE31 +:106CC000F93A0FF2DD056FE8399ECF57032C8ABEE3 +:106CD000DF8E9BFF1631BF4631DFDFD97B13DDE44A +:106CE0002D7279C64B7E89746F8F2D9B819E3418CF +:106CF000BFD1C9E54BE1FC32737F941F205F906FD9 +:106D00003E6433864C30FE437695EA1B9D6576AC37 +:106D1000F7DB55923F0F39CBCC3390AFDA80D99562 +:106D2000C07876DE77A35DAD0820FF709453FDD860 +:106D30005F8FB7231F6D64114729AE6F31C815F8F7 +:106D40007E7F7D19BDCF73FCC581FCF968325F572A +:106D50007BE2214B3EB453EFD391BC28B0AB24C7A8 +:106D60007A2FD605DCD0A4DDBE4087E5271BB9BC51 +:106D700082BFC42218BF2F1F9EEDB8BFE4CD42943E +:106D8000670FAB1EB79BBF53A3E4415F94574938CD +:106D90006E728CBCDA5CCC34ECD7EF32079E827E0C +:106DA000FBAACC9592DC05F73C879ECB17FD780FAC +:106DB000CAB53ECDB1F229BF294A3E319497B1F20E +:106DC000295E5EE5D4037F8CFADEE4B2C7942D8E93 +:106DD00044924FC0633CDFC0D00B5A17DC62655D44 +:106DE000FC3A5E1E3508F920F96EC3D7C363E4830D +:106DF000E4CBF1F2E1CAFCF5ED5BFB131E02B772C6 +:106E00005F99CFBE8D7800F867F029243F98EA7328 +:106E10007913AF0C2F83C16BB7DBAE0C3743EA3B62 +:106E2000A457187C2AF57F995CB9025C653BA3F9ED +:106E3000C9CDA741AEFDE5FD9F14322099E5001BA9 +:106E4000DAFF545DE0295877F6A2E73663FF5987E9 +:106E5000AC8D0867A36BC6E6465C4FF3E38C013E3E +:106E6000E9CD1C9F8C196576FC5ED569AEE43E5079 +:106E70007EF6DDBB14C0277D4ABD87C1BE1D7EF1F5 +:106E8000CDE4DB107E6F1988CE4D3AAF9DF5A1E9B8 +:106E900010BEADC8B16E5D4578EC33239CB27798D7 +:106EA000490E30FFF6951A2075036C071B85F553C4 +:106EB000566AB0EE1D4A67F9562C070346DE1E5887 +:106EC00034FE5FAB4E11F54C535DA4778AFADF5464 +:106ED000948F86F6AA7DA00A7267C1DA979A0C3958 +:106EE00058AF93DF6B6C24AC17C7136515F6E7B981 +:106EF0007651EF3FD8540E44D46A94E3333FB66FD3 +:106F0000D5E978D9DFD684FDBF5026BEF73FBD5204 +:106F1000CBA6F9DCA67740D1F17A93EDFAAEF9AEC3 +:106F20004D7EAB6929ACEF1377380996C16AB69EDE +:106F30004E43F9BC624ABD17E18688EF0599D84BEC +:106F4000EF263CEDDCB79D13FC59507BF1D0DF936D +:106F50000641559D3E7C2801E057B3BBDE6C80EFB7 +:106F60004D06AF3F2BBFEBBB9A9D95A4CFD4B51573 +:106F7000D1B39BEF0EABBDFFA5EFCCC6AB18EF9323 +:106F8000D01F6A9F87AA1A7D7D934D4FED19DFFFB1 +:106F9000EED727BFFFE4F93FDC89E35D7087D3C6F6 +:106FA00041EB1521804B37DFC9F6B5BB27D0F3582D +:106FB00082B6C601EF6703EF227EA5D67BB07DD0F7 +:106FC000DC6CF700A02D86662FCA0D007D4037B21D +:106FD000EBF90B475F6A1FFF3E9EBE826696321E2C +:106FE000F978B54A722A68F6270C81F26AB043969E +:106FF000C2949615BD3B6C10965FB231B44B1AAA81 +:10700000DB5D8390AE3C4686FAEEEAEB831948E7F7 +:107010008D35C629DB117F430B5C33A3F4ADB5C9B5 +:10702000069AC7CAD780EE86C2D3107428F87D3F6F +:10703000901B0AF2459F19ED1C4B4632F3E7633B68 +:10704000DB6AA4CF95065F4519B6CBD0917CB1F42D +:107050009B5C5106F370A5EA143DCDA3FCD82C949B +:107060006F76234A50762279FA6E84D373AAA71ECC +:10707000E9F0399BCDEE870AE0911AF23FB59F33D4 +:107080008065939ED5A31CCF2A02791EA5C79E10AA +:10709000FCF384C348FC6EB52538A114FAB12ED098 +:1070A000D9FD30DECA9A751D63619C5FD6BC7C74C5 +:1070B00029BC5F95A6329C87CDA9868C207F0CDFEA +:1070C0008339C2BC5F58EAB5237F8DA4AA6C1BD458 +:1070D0005BFB1A993B8A5FD90641398A4FA638551E +:1070E000CD02DF7F95ECFB77078C3BFCAD77CCF8CE +:1070F000BD6B844E87641354F93E2715C7F6631F92 +:107100001DDB4F72796CBD737C6C7DDAE4D87AD765 +:10711000DDB1E5CC7B63CB5324BE01CFB1813CB65E +:10712000F22A660D7FBA04E52DC0E73D84BFB54065 +:10713000E741F8586AB69F9D05F559C84FD01E1A09 +:10714000C248EE1EC8FDA91BF5025372BDDB31E833 +:10715000727864E5986FC3FDB2F555ED0CDADBDEAD +:10716000FFE86BECDFC6A2DAE5237CB488239597B1 +:107170005D309F44FC871BE15DFFE707512E1ED564 +:107180007B10DE59352A8DFFF0647740CFF5091763 +:10719000EA3349A27D927975871EF879D2FB2BE7F5 +:1071A000A3DD1B0FD73456AF205D027E707BBB92F0 +:1071B00091FC58A1635588376823607FA41E01BFE6 +:1071C00098946224389992156137AA3AAC4F13FA11 +:1071D0009331E35E0BD2F1438738FE3F64E4FD74E4 +:1071E000F6E7A64111E519F2C994645D4C3FEBEC5A +:1071F000A28D28A73A78B9B53DF936A4CB759393FB +:1072000087219E98D0EE82FE7A659BB501B03ECB79 +:107210001B46BF029DF65259BB01F6B2D5CAEEF12C +:10722000C23C361CB6FAF5F0DE32F31776D4D38AB8 +:10723000C5BC5B9779DE463E10A954098E96D4668C +:10724000FBB0417C0D7E981FA203CAC5D27E2DA43F +:10725000E7594A9B49BE5B8A9A9B114E1BC6EB4875 +:10726000DF48BE5747F86CC9091EED8B7E82993AFC +:107270003BF6970C82DF089D3C9ADDEC45BF090385 +:1072800098EB4A38AA60BFB442182745C0D5E9DC5C +:10729000F91305FA49C1FE86F0F608278780D3E87E +:1072A0006437C1DD29FA4DE90BED87F07E1A4BBA40 +:1072B000FA91FBB8A18205707E725CD94F67FF4CD2 +:1072C0005390AF1A7E0770837D5272CD34B987E632 +:1072D00032B28F5B9779EBB7125DDBC8CF91E9CC07 +:1072E0002E433CCA3CBC71A26E087E67A5710C336C +:1072F0005900F1385365E61B9351BFF1121CE3E9C5 +:1073000035A3BD7912EAA9725FE2E93743654DFA08 +:10731000E4CBE938C3E92C2B18D20D3DC7D14BC6BD +:10732000E1C87D88F4F174BD25E14211C28545B7FD +:10733000D75FB9ACD7078FA29F87A5839C00D0E702 +:10734000C68DC7D83F4C585698CEFD4D1FE4FB0E56 +:10735000E1BF017905C4DA3ACC3EC686743A9F1182 +:107360007E95ED5A7DD7EFA0BF4BFD8C76942B39DF +:10737000879B3B503EB2DDBEFEB80F9B54DF130926 +:1073800050BFE9583A43BEBDD2C2ED3155E079BC99 +:107390007C592BE8C68D72CEF5AF3FA57E18EC9BCD +:1073A00036D00EB4B7F617156F9853FF07F52CF6C5 +:1073B00002E959D9ED1D4B6D38FEDAC34D6680AF39 +:1073C000E52DDEBE19CA7E15E1574DFEAC0339B37B +:1073D000084EEA7113433C1DACD70258667FB230A9 +:1073E000E4BF3B5EBABBCA8DFC276D9C1BF9D0364F +:1073F00041EF01619FC5AF5F356A3ED427E2DF6F81 +:107400004CD689FDF49EAD847D1CFCA491AD82CA4E +:1074100042DDF426B4EF222B81FF42ED74BDBBF6B2 +:10742000E751F6ED23D6D26032DA254BCCCC070AF1 +:1074300073F6970AF30171E638FF508AFC279785A7 +:107440001494B3B9F5A0F0225E2DB4325F14BE6778 +:107450007FA952FB47AC5A3079047F6F063E60E04B +:10746000FF64CF257B59A593F328D45F0CCF5B4FE6 +:1074700022DF60CE72ADD31EE98DF80B721FC6DB22 +:1074800027D66D00181A86C17F365DC834E4F2F63F +:1074900007049C54B32D84FC52B51D3946FCC5AE7F +:1074A0009E8F6E87763731B16A467E59840B957F01 +:1074B0006CA77216F05FD330D2FBFD687FFB93B8E8 +:1074C0003DC234CDED4C437A6104E46C336B3243FE +:1074D0003BC276A0B70CD66121BDB99DB9911ED033 +:1074E000C3762681581643B86E62AC229A0EE453D6 +:1074F000FA25D4457AB2A7061EB4D07C0CF52C60D0 +:10750000417D08E706F05617B2809ADFE5171CE2C6 +:1075100070D37746564FFAEC0B5F9FC8443E6D3DE3 +:1075200004FAD850DC671DF129AB3596FE185B4A8A +:10753000708A08FCD8BCC44EFBDC69BFF9DE11FBC5 +:107540001C5E8AF222776172CCFECA76D95F663100 +:10755000DFF0E87E03D46F76DF7605FD32D95FE693 +:1075600052FDE625EE2BF4DFBB87FE33088F7AEE63 +:107570003F9BEA3787DE71DC0EA0D814697778DD8F +:107580005DFA753C9CB317C6F2E5A1BB63CB122E26 +:107590001683E69C0030B7DCA7F36C85FEBE732C27 +:1075A000B65D45FE1FC9FEED6A1F724EC2F6609FB2 +:1075B0006F85B7379C8D6DEF2D7DCD8174DCD59EA9 +:1075C000CFEFA62F63DBC5EF4FFC7C615EA9DF8F99 +:1075D0009AD718B329A67E4AE565F34AFD41D4BC83 +:1075E0006E71C5B6F72DED7E5EB7159AFEE9BC64E7 +:1075F000BB3B465E5DBBF8754CAA30F50077DEFEFE +:107600000753AEAEDF1F56FDF376F72C8A1FC74F28 +:10761000F8BE40A78D4981FAE9F80AF5459B95F433 +:10762000DECBEC2C219FC6A1E201DF7992B471F888 +:107630005D85A43BE16738FCE275E9C8D7B3841FD8 +:107640009D09BF426BB58BFC0A3ED11EE44923F273 +:107650008BD61DF05D129F57B4FE9452CDED0A3BC0 +:107660008B103D4B7D2999D9156E8F737DA7A7711E +:10767000E2FB7F18154098EF8C4563D80740872FB1 +:107680001BEDA52ADA675B14D20766946BFA44C037 +:107690008F514D0AF995663CF0F6A3E88FB9FEB418 +:1076A0007B7718DECF08383C386C6D07D3304E90AE +:1076B000AE9F5FF4203C1F3BC0288E86E5F9886FA3 +:1076C00036CD8DF64625CE08FA396FA82FB223DFC6 +:1076D000FC914D43BE5939597B8FD6FB156825D097 +:1076E0006E265F3ADBD532C188F18ECABBDD2351ED +:1076F000EFA90C5A347A9A996A857554823E86CFDE +:107700007423532DF8B432333E4B9671FD2B69A48C +:10771000D75809E357B63DF357FC6EB61ADACFF5E2 +:10772000C900ADBBB2ED8DBFA1BE3653F31A915F58 +:107730000CDC61E43AA9C087C1C1D832F283E87297 +:107740005128B63CFC706CF9D3140EDF51C28F7512 +:10775000609F89F8F6BC8FADA47FEE05818776B275 +:10776000FF0513C98F31F36CB45F1F9FB36E45BF24 +:10777000DEFEE3566A3FF7390B6FAF0BBE8865FF3D +:107780008B096467CF4B099624C3BC5FF95A4FF04D +:10779000C66519B0FF17076C5D85F5C383251817FB +:1077A0007BF93AC63AB05E0D0CC175BEFC0FEEB760 +:1077B0008E3C6B0A6C837E3FDEF3CC8B3FC3719FA4 +:1077C000CD4A56607F6E40B900ED463D69B6A2BD18 +:1077D00031EAE3E7FB20DF98B7C314B3BE175314B5 +:1077E000A13FB89310EF7AF23B9E5AF90C7D5F7877 +:1077F000F618E1DD5E835F87713CFF4A8E677B2D63 +:10780000DC4FBAD7921BC07DDA97C2E9EA06DDB633 +:107810005FD6A27EF916D7437AEABFD03563737973 +:10782000377EC6CE7A18371FF6F9E247D67BD01FCF +:10783000D77F7DEC3E0D08C4965F4BE17AC274168B +:10784000F53E1FE7D37BB90BE7B395D17C0ACFBEDA +:107850007F573EEAE326AE87C48FFBFB142E3F7FA3 +:10786000F52BE887F3193DD7C3016240D7F3043DF8 +:10787000BCA2703D18FE166601FECF4305A277D765 +:10788000FB7971F390FD2F1570FADC9CB40DE5B90E +:10789000D3C8F1FEDC92C38F621C53B63BB344D312 +:1078A000CAA3FCCAB3D6CF3F9401FB5FDD9A4A76E8 +:1078B000A67C5FFDECC1B41FC2FBF33B540FAABE14 +:1078C000D5539F7E6414B67B561FC47962BD06FDF6 +:1078D0009F0FBE9684ED666D720C437F89FC7EF629 +:1078E000FA9BB5F2287E7AADF424E9BF5AD8C7BB1B +:1078F00046768CCD0278CF5BAF78B0D9BCE0F72765 +:107900007D0F759D4D7A0FC6374A54E6D50F23D3A8 +:107910007D323EAB5B5F3A9409F575FB4694E0BA65 +:1079200056E9BCB70D467AD962203F58FCFE189D37 +:107930001C7FE1FB900EBE5F75A7AD0AE322D06FFE +:107940003B960F146ED3A31F3FE92CF037FEFE9831 +:107950000E78E6D9B6878680CD02786C6B42FAD86D +:107960008B8E0B1CE7053DC90916E2EB1825FCCFF1 +:10797000F3FEB3C5A8C2F3ECD96549A59CFE689F88 +:1079800090A93B617D554F0E267A9DBD3E96BE6403 +:107990003B39DF3981D8FA78BC28704A7F052B8CB7 +:1079A000C6AFF87629E3FD46A4C7EA45C0CFA3E8F1 +:1079B000A6FA74B311F5AEF871508364725FF58462 +:1079C00097CC4DEBB5F0F582CA6B86F59EC37F71FF +:1079D000BFB98276FD5C8596C8E65DC7CADD00CF7B +:1079E000791359053E253F3C3F323804DBEF35849F +:1079F0009FFE25F1C144E207E7EDA124F42B650ABF +:107A0000BFDE79772809F9DC4511B7C37A2CCF6D31 +:107A100003790074FDF12746920B4B83079370BFE7 +:107A2000CEBF68D1E9605F3E6E4D29437FD0F9E05B +:107A3000EF92705DE7822965E8D7EB894FC4F33791 +:107A4000A90F9CC47F5E0F7A8F531BEB44F86290A2 +:107A50002103E44D4A7D517D37742FBF731AEB8BA0 +:107A6000304F23F2239B671B8713C5F33E3B9CB229 +:107A70000DF75BF2D94A85F72FBF9FEABC3ABE5A91 +:107A8000B16A00C5993E63EE5EC8E7EF46DA80F959 +:107A90001DDE5FD00BF50DF9FEC134EF3D4EE8CF92 +:107AA00055D641F901AE71CCD3004D3FD07BEEB736 +:107AB00003FCEF6520FFF059EC3392DFA63195D639 +:107AC0003743652115F07D06CAE72154267D68C637 +:107AD0002625D000EBB977752CBC66B598BAF004B2 +:107AE000FE9BC380B122216E8A6A07FDCF41390C0B +:107AF000FB30D7CC4209D0EFDCEDB1DFCD63219A6A +:107B00004FF5F3DF98BADB8FBF8AFD78304D5B8489 +:107B1000FBA14C34D3BC7EFC824272D229FC9591ED +:107B2000C77A0530AE364FCAFD77F8BED53D50A9AD +:107B3000DD0BF87771D10CEDDE144A3DD1501F6199 +:107B40002D8984CFF3CA592807E637AF4D090D4E6A +:107B5000EAEA8FFD46E1761EE3F1CEBFBEC3F7F140 +:107B60002EA13FCD84D7A88FDCA0E3793D910D0AEB +:107B7000C9D751CF2BFE44E0CF33CD602A229F12CC +:107B8000EBC6F6BDA03C9BF9094EBF74E6D3FAE6FE +:107B9000B00E23A7A340431A8C5B7B167813BB1A45 +:107BA0007CB89EF6FD73E6A17DDF82734E457C288E +:107BB000213C91EF414F6296E4CBBFC7FDD3A2E0D9 +:107BC0005DB529B6CCB647957BE3FE40396ADF6ADE +:107BD000777E63D2BAD9AFC73AE55B60C084C1D1C2 +:107BE00074C2F5F013623F1FFBFEAC0CE44B6B500C +:107BF0009FCE141D8C443ECEA49F256486FEADC34B +:107C0000598CDF05F43D2ABFE2FCD1B8F5D98CAD23 +:107C100033F8287E3143EF3D84A1B6A274DF6F11A3 +:107C20004F66E8B45C95E0AA1590FDBD88E3C3E318 +:107C3000C3EA07D4776377CBF9AF5382211DF2A74C +:107C40003D5C5F492C8E187C5174FF9EE0BBBD0EDD +:107C5000840F6521DEBDA4509C6083C21A1580B3D9 +:107C60000BF619E5D306E5E42194671B6E75B306A0 +:107C7000A82FDE3961FE6B64BB5B29CFA86667A9BC +:107C8000BEC646EBE7FA7342FD561DD4A7DF533854 +:107C90000CE90DD67DCF44787FC2E9A67965D83846 +:107CA000FEB896F9F317A09FF88077FE6B8877836C +:107CB000ADE48F4B07582526D3B309F562175BAAAD +:107CC00060BBE5A90ACF83A864537E3388B059ED21 +:107CD00095CC9FC7E0A9A8AC11FDCBE92AE8D9FC57 +:107CE0007D238EF358129F57AA4E7FCF04D4F3877B +:107CF000F172F26245DB46F26C2DCD2BDDC42A70A9 +:107D0000DDF81EED029886D64AF5018253FA98FAFC +:107D1000229C477A1FFE741A43D9D8CF914E3CF16A +:107D2000E9507E2C147AC0C2AD65E9C8EF8F9C374C +:107D3000ABC8D78FB8A43E1BB2A13ECBFA16F2F661 +:107D400042DE2E2C1A938E44EDCC8D6D77D1A0F5AA +:107D50001A8E72EBA89EE24F7FB169BD1CD0EE0671 +:107D600023EB36EFAF572ADFD7BA2F151688F26309 +:107D7000D44DB944F642DD976ACCFBF34BCC2C10C2 +:107D8000E5C7A8AE3A3016DBD5B08EE5888F35C191 +:107D9000041688A28F1BACDD8F2BE9A2EE4B3DF3BE +:107DA000773BAE31F6FD9729CC9FD25DBBB4D8F7B7 +:107DB000B08E98F2EE2F3AD781EFD9C87012FA75CB +:107DC000C7A37C86F2C580CE6F00BE75C4C0E5EE49 +:107DD000057B38462E5F7087B95C46BF958DCBB367 +:107DE00009B8CF6A24696262D738B21EBF4F8E5A73 +:107DF000EF85294616A2FD89D03C107EFEFE8C6DD3 +:107E00006CFBD488F93AD56DFB097E126FA2E1E8CC +:107E10008F8E8335748474C033C6A56E5F35680059 +:107E2000A0E001C91F9E5EA58D867ABD2E865F24C7 +:107E30001477F20F62578F61548EF8CD33ABD06F49 +:107E4000DB55E6EDBBBEDF310EEB8B07F1EF27A76D +:107E50003EFBE6324A6A69E67A971AC9F5264695E4 +:107E6000CD71651B94074795ED71F5CEB87A575CD7 +:107E7000399BB73F9F18CAD57B18BB27F585712A58 +:107E8000F0CDF319A16998C7B6BAE1D7E3CA819FCB +:107E9000D51473395FDBA678485C09F8D57AB81E2B +:107EA0006BF3848D983F9750DC7108F94BF56EC5E4 +:107EB000AE003DD882AD212AE377EEA8EF820A7D9D +:107EC000571D3C49DFF5D87FA18EE87D55E129DEBD +:107ED0002EF821E9132B1AE753BE808C87EB994FBC +:107EE000CB52BAE2E192CF5EC8D00E129FDDA7D886 +:107EF000913E3BF114FB8DF243C9F67F1ADCF64745 +:107F0000545712167EBA14F5EBFFACF97004EA9BD5 +:107F10007F12F2649D121880E36E64BE01284F7FC9 +:107F200054D36FBF0EDA9D30843763CC6F4BEA6B4E +:107F300004BF1389E11CCC0B0C3CF6EFBC9C1ADE91 +:107F40008CF0BCF458C738CCFB3B9113CEC13CC07D +:107F5000EDA9FFC5CBFDC29BB17CE4B133BC3C387D +:107F60009CA387EF7BFB3F1C570EDF3F65EF9EAE68 +:107F70001F13FC44CEAFB6AFD69C8A7A5E359743CA +:107F80009BC1463303DF9C36F7DC0B4F011CA6FD7B +:107F90003481F8D953E7278DE3F682DFAB96A03F13 +:107FA00099FF919C247EAF929E9181B231B96B3F33 +:107FB00012733BDC2447AEAB6F45FD257DDA209282 +:107FC00023E54EED0B1C573EF767C113DA7F916A2C +:107FD000E7FC5BAFA3F87AFACF1249CF5B63E1EB22 +:107FE00001BAA1FDB589FDF89558CFAF52B91D7AF8 +:107FF000BFF366EAE72EA1DFB7AC0C3C6B01F81FBC +:1080000097793B6BB9BDF0C3ADC057808FB738B41B +:108010000CE4273F147978927FE0FBE4283BA9A584 +:1080200008CAB62E7BB86582966175E2334D8771BA +:1080300024C98F5AF2F977522EA537F071D3D70C95 +:10804000D886EB4850B93F6CE694826D4B492F9827 +:1080500048F3659A96A1407FA7E7F4D6A19F4CEE1E +:10806000CF9ABE5A3BAD47C419E43EC9FDFC2295E8 +:10807000DBF733F4A057C03A2DE93EEA0FF48C2128 +:10808000C21F477AC617B8C751F0656A7804BEFFA9 +:10809000FF084E1F7D1B70AA5904FC427715FC4255 +:1080A000C06F9D1232A4737E41F63DBE47B9D3EE38 +:1080B000F47D9D1A95AF33ED6735A457CA7925FC39 +:1080C0006457C50FD8E57416AFF799D2F87E49FD0D +:1080D000D423FDAA629C13C7CD144739610C12DF6B +:1080E0003C0176D552E42F220FA0E4A7F38EA07DA9 +:1080F0002AFBAD49D373FFB4DC77C5DB3A2B1FF302 +:108100006298DF8CEB9860A47D9772B7C5C1F35C71 +:108110005A1EC8A23C978B2CCCC83F3B92117F04BF +:108120003CA0FAC8D434A27F68EFB760FB39D751BE +:108130007BC00B3FF187A956B2835A306E8EF55340 +:108140000B03989783763CE1DB1C1D8DDB0DBE7025 +:10815000FF777F9EF721F126AD81FB9998AA0D99B3 +:108160001025E76F4DE3FB9C501C7EE93F50AF5D4F +:108170006D21BD16652CC5A89AD3A91FD8FF6169CA +:10818000DC4F417876EF238922BFCE5382705D9118 +:10819000C8F1729385C7CF36811E4D7C51E0AFCCBC +:1081A000EFF3097D2F5CA54B427D414B937633C89D +:1081B000F512E1BF87FAE961E524DA7FD3FDFA9091 +:1081C00009FDCC4D376BE1283B06FF30FE788FE090 +:1081D000AB6C3D233BEB1EFC2E09FBB72661BCF5C7 +:1081E0001EFC1EEDC8C537C7C41527A671FA96F345 +:1081F0008BE7FB13E5BC9A1FD7A2C791FDC7F70712 +:1082000076EDA4B4548273A817EEEF523DED5FFCF7 +:108210003CC3EBB91F3EBC3E8FF04EF6D7D33CFFBC +:10822000AC8FDCA7801C9C3586DBFBD2FE9929EC49 +:1082300071B638D6BE43BF4F67597F7939DE5EC409 +:108240007C81D8F65C6F4918143112DDBA9598F923 +:108250004B78F5048707AE116E52EE3D6E013A0081 +:108260007C598F7995805FEB1F482039E6340606EC +:10827000205E6DC47C1D92A7DC8EFFFC48AC3F26BF +:108280007EFF7E9E26FD6AD7667F3F8278D18DFD78 +:108290005D678D6C41F8D75919D1E7857D89448F89 +:1082A000AC6F781AE6D15DDC6B62480FB54AB80056 +:1082B000F9E00545ABA4764B13DC4897D2DFF1C15A +:1082C000CBDCDF51873B03EBADF3FF17E571D5ED59 +:1082D0008EB5CB2FC07F5540471774E112EC4FF29B +:1082E00017D0CB35D2B7AA787CAB56C7FC68B7DDC0 +:1082F000A09B3E87F38D4CB68DDE9F2C5810A5F7C2 +:1083000043BB762599A323D261B5D8975ADD296A54 +:10831000578DF958B83F68BFA11F102BA3FCD6B5E5 +:10832000AB3FA67CB0DA9DB1F853DD855FCA370A52 +:108330007E17856FC41FFC82BF30EE8F29E7F1F9ED +:1083400044514EA8E8A0FCB03AE18F493D101E8B85 +:108350007C2AB138C8A6C3B3EE2CD75F46B56D3DB5 +:108360008876BAA3A22307C9AA4EF84125FEC87988 +:108370005EDFB6568F76A4D47BA2ECD8011363FCE3 +:1083800018CBE83BB48B71BC30BECA40F4E2F27249 +:108390009D9097096860A35C6DEE4F7215E51EF223 +:1083A0003B695723FF43FC2A4A2F3B8EF4FF467A52 +:1083B000D91F399F04BC453B018DB4EB7BC63F09F7 +:1083C0001FD90EEDEB7FEE9F147C9C71BFE48237CA +:1083D00052FF291D9CEFE4AF57F44BA623BE2F504C +:1083E000DCE988EF17057F3CBCBF80E2A0F2FD19F5 +:1083F000BD8FFC8FD2FF3507FD7EF0AC16FC689672 +:10840000F097CD927EB2F5B1F15AF4534797E74A0F +:10841000BFD90E53571E13FAA9CA592811FAAB41F6 +:10842000BF1B3E83B1DFD5B2087D57B7FB1B534C52 +:108430003CB885C3F11E814F8EF2801EF9D8060B21 +:10844000F79F49FE366AF156C2935EC3B4FC87902B +:108450006EDE3090FFE57F0B3C90707930ADECCF55 +:10846000B8AF56BDF00F3E6422BE7E1AF48556E1C9 +:10847000F7998876F212A6E13901A6DA73A3ED68BE +:10848000F95CB5D75285F89899AE8BC1D7F634030D +:1084900095C91F46722381F402607343105F4B7AC3 +:1084A0004BB9CD86A01FEEA4B0EB6BEFB4F9B0BF13 +:1084B000B08EF3C5FEE97C9FFBA7F3BC5959EEB41F +:1084C00043053ECA382BFAA5A2E314433ADBAF15A5 +:1084D000FA2EA3F5AE9B23F2E83BE942477C2E61DE +:1084E0009097E4C30DBA32E273918F6C6E844BC5E2 +:1084F000C7D573701D9F4DB1D279C97B859FFCC6CE +:10850000749E8726FDDBD7EA272F4DEFC4C7183F9F +:10851000F95EC117F7323E5FFF592BF7F7AACC8FF0 +:108520007C726F704000E75B29FC23A87F21BF8E1F +:10853000BCC4F791A95C5FDBDB3638807474D2E091 +:10854000DB3013FD4DAD06F21B3235F0ECD3D8CF46 +:10855000AB191ECCB3BAA08B6CF93DB4DB7BF657DC +:10856000591857DB2BE21BD5C65001E9F522AFB4F1 +:108570003A2954807EAA57C47E555BA10CEF532C38 +:10858000BEBBD253BBE28FF81DBE3F15E076C329B8 +:10859000C6F1C0BF9AC79701BE193371BE2BD3294C +:1085A0007E89FB82FBF0C1BEC1B4AE7506D17E0FE1 +:1085B000F7732B130BA7919C59654A41F85FF41A86 +:1085C000292FBA6E0DD76B67E8DC5B1621EF7D357E +:1085D00081D637B3E528C595EA1E994DE74DEBE600 +:1085E0002EBE9DFD93780BCAA968FFFE0516C9250E +:1085F0007BBDAA773004F3B8D036C0C3C3A5FCFC5A +:1086000052ADC8BF3D6D601ACE3BB2CF10E8EE5CF4 +:10861000654FFD9383B384CB4B1CA72E3AAE45F236 +:108620002536CE75A5F20543B8E001187F758A6F2F +:1086300075BAD03B115E75AF66101FFDE0E12F7279 +:1086400049EF69E6F194D3066D1AD289A33C649C84 +:108650001EC55FB70B3A9E6112FA2DF0C168BA973A +:10866000F52565B174269F4F0A7A4B14791897D770 +:10867000CB3CBF492694C7DCF585FDBAF9393411E6 +:10868000DF1C7536B21FF3D9AA8345143FCD5B1C9E +:1086900022BA047887D03E39BD2191F3135826F6CB +:1086A000336B2423FD7A969EE795CC3281BECEF5BE +:1086B000026A7F66433AC1A16419D753232F29C4A4 +:1086C00017659CB792F1EF77359EF4EBA17DE50E2F +:1086D000A508582BAB6C2CA5BC93B99BF269FF473E +:1086E00009FE3BC3A4156C407CDBC5E384301ED976 +:1086F00005D5985B378CF89211E56BD50E85E22590 +:1087000072FDF1715516888D478D0A72FE8D728348 +:1087100045E993520EA1BC60717A6E2C5EF8AF4AA7 +:108720009EC6CB8377D3AF56AF8C95A7EF21FF4A78 +:10873000BD5C9E82DD701CF1B0A48CD371A495C782 +:108740009F6A583D8FC30979D6B92E210FCFE8B95A +:10875000FC9D655A4BCF8BE93C0E359785451C2A0D +:1087600062C4F9F5845F17D3657E7B2C7E49BC8A91 +:10877000209E417FD56759E8BB305EF56216AA1985 +:10878000C29F894348BE73396FE6721E9FD6AB9075 +:10879000F7F1723E5EAEC7CB73146728B7253E452E +:1087A000C723504F1AB538A0E7FEE66C3BE665CA12 +:1087B000FDBDDFA939B253BBF4C0BA6366B37B28F1 +:1087C00096BDACB70DFD68A59B73A0BE4EE5E7C393 +:1087D00013004E5BE1FD666187ACCAE174E612F9F5 +:1087E0005706D5CB8A6CB84F1DE43788A432CAA788 +:1087F00097F0DD9C08DF613E420EC78FCEEFCDAC17 +:10880000D11AF57DD95E0BC9A94B7B12E91C205307 +:108810007D790EE82FED4F603F40F9C2DE44D21360 +:108820002E08B9E194FE19B69CF6A38F8BEFB39F87 +:108830009565A19F9B29E3B2189D8FE7FA6C8DA3E4 +:10884000A7F884A8CFEFB893E39989E4F52547F812 +:108850007E2CC37C28BF3BCBC5F7BD6EE798A29F9B +:10886000615E86D7E6E150F515A1FE61D22FBCD33B +:10887000ACC77B1216471E8075D4E4D8286FBC3C69 +:10888000EFFD77A742F9A39D063A5F3AE7A949BDF4 +:1088900042F899AAB9BAA393390143CCB9C5793B37 +:1088A00062CB35C1D8725DDC3D058BDEDFFA667BBD +:1088B000547DB94B9CEB74330FE6BD33FDDDBD7CBD +:1088C000DDF05DF9FC6249E0CDF67E9437789B8B54 +:1088D000D3B311F5A3E9880FDD7CA773F17D35993A +:1088E000EACFE2F903D32B26BACF20DDE59BEC4A91 +:1088F000453B2A7208F7D394777E08CAD3B2BCAF3F +:10890000286E78E941E641F85CB294929E746983DE +:10891000C58D76634BAE8DF0A0E55525A070BB628A +:10892000FC08E0AF55341558EFFA5B3FE2876598D5 +:1089300099DF7F0056950BF9954676DE990956FB2F +:1089400032F8AE6A3D97DBD5AC2309F9C006B97F92 +:10895000FAE78D66F8677EA3366029CC779ED74A02 +:10896000E7A4D4AF55BA1F600576196597D4BB3814 +:108970003FA831878DA538FE570B2BD00528FD79F0 +:1089800026834FC3F37886DD45A12C78357BD14112 +:10899000B2BF3AE3F6FB38DF9AFDC07E7AAF4CAC4B +:1089A000A0F59E81F5225C0E6E30D17ACFE4D8C856 +:1089B000FE3DB399DBF9B3EDC68099F4962F53F0E1 +:1089C0001CF399CD06BA3FE07278DC42E7893FDCC0 +:1089D000F43AF91B3F647C5CFF4E3DE93D1FDA230E +:1089E000252184A3BB3E09F5E6AAF573E83CF2EC29 +:1089F000CD7A2FF2B3D99BEFFBFDF5E8279B785793 +:108A0000312EE926C7C234B7ADAB5EEABB6AF2C805 +:108A1000A7910E6FFA7A4CC74DA8776D063AC9E751 +:108A2000E71D50DF6FDF7C0BE9B7B327581DB82E69 +:108A3000F7A6A7C6A21CFA7042269D9F9EFD82C281 +:108A4000F0CA8CD98E4569F87EB6A27ABBC3A7A1BD +:108A50002E7EEEB934CFE609E1777FD4139E005D18 +:108A6000DD8972B866B381F4E7F689C7DF9DEAEC69 +:108A7000A22B65E2FADB4761FB670CD4BE536FDAC9 +:108A8000F43D892F2C5482F619875B3C9D99F21690 +:108A900017E0BCE2E96DF6B2FA021EA7BB36BA6374 +:108AA0009B38DDFD9B4BDCFF71F574B7D7957AF5EC +:108AB00074C7B29363E4F0E5FCCD4FF094710EB34C +:108AC00087694FD928AEAD29C07F3FC080FE087CA2 +:108AD000F27362EADF16EC780BF1D8E53B82F3C85B +:108AE000635A11CA4D77C45E8667C06C422F649B7F +:108AF0004CD29E203B615D2A7B7A55945FE4CFA2E5 +:108B00003FE0037FC47E2EBCF7D521DCA7DADCF37F +:108B100043D0BF5DF7E55F282E6A6BE371759B2735 +:108B200042F90606A797F050F2F73A0F973FF1EB9C +:108B30002AC8E0F6619D3342FDE833DD546E1171C1 +:108B4000A48D8BACE437DEE80C58B8DFC3CF503EC1 +:108B50008D1FA9E7F140A1B77D4FF85DCDC507197D +:108B6000C601D9689E8FF756F1413505CABF1F79F6 +:108B7000B387CE51163FD9D41BD73DDA20EAFBD0BC +:108B80003D27FFAE9552FD0297DE8DF43DBE98E77E +:108B9000A3B2AA24F2E7BC55FC81F3DEA8F97B99C5 +:108BA000D96D03BC9908C41A9DFF78FB688BDB164E +:108BB000853F9F352B155C7F76F79A3C98FB6B4879 +:108BC0001E17C7C26381CB48E3BE915ECA3200CE96 +:108BD00037DDC8F7E3DC0BA600F2C173E25C523C60 +:108BE000FC7A6508FC5107C4E427388DC15C949376 +:108BF0001F2BB1DFCD6DD2537EC09C26850560BC96 +:108C000073CFEECA457EFED153BB72A747CD27FE78 +:108C10003BF9CCC888F57FC6FBB37BF263CB7617F4 +:108C2000D7339FB94F57FB8B557F273FF6F436E17B +:108C300007D7B4BE4EB4AB44FBF8FECA057E28BBD2 +:108C400015F29F483FEEA9C34F62C4A873FF2C6D75 +:108C5000F9BAE83C52F91C25F66D12EE1B2CC5D270 +:108C6000C4CB3DED574FF47842C821B96FA79AFAAB +:108C7000F442381A6B6D2AE3E7030B51EFDFCCACFB +:108C80001EA4A72F443EB1D30A4FD0D38C992E1BDC +:108C9000F233791FC34FAC49DBF0F985C837765AF8 +:108CA000E109FDE46416527F5FE8BC641FFE44DF07 +:108CB0004CE7466FC9E0704867214541563BEF6578 +:108CC00085F2E49A62E19DD6C0E548A4D248F24B11 +:108CD000C2FD86E9F7931DDCCD7EAD473CCA1CC9B9 +:108CE000DFF933F2851E1DA678896524B3A39FA002 +:108CF000E17A3FCD43EE571D6FCE943685F467CCB5 +:108D0000F34948A6B8B05F3C992D9975C6491284BD +:108D1000DDCCE2E222E9A077633B394F2853BED095 +:108D20001A47B0B980C795492FC57EF1FDF4412A95 +:108D3000C515B09D71D895F1AF134F453EE878F950 +:108D4000BECADA6D1C663C9ECBC27D00F9887A21D2 +:108D5000F31862CE656D027D1AED3D19E7D6EB8200 +:108D6000452EB24F3AC2E887319698DD286F13F44A +:108D7000C142DCBFF8B837B4CBE7F916D90E94334B +:108D8000F2DC55EDA2315E8CC781FEE137E3FE4D8A +:108D9000E0FB57FB4029BD5726162E45FCAA5BCCAD +:108DA000E87E88316DAD940F5657C1F5B1BADD2715 +:108DB0008D0CF077BAF00B31E1174F13FB7A4AE8CC +:108DC000DF5D71BDF016CCB76F99934DE7ACE3F35F +:108DD00067AE35AE7B31110032342A5ED7CBCCE59D +:108DE0008CD87F49DF327E9738C89B8F9AB861BD97 +:108DF000E98875C4B5E4C7841F2ECFFE27F931FE7C +:108E0000FADB313FC68C5ABEA8C769801CED3C47CF +:108E10006971537CAFB31EEFBF30EF56C47839B7DA +:108E2000DFAC529EAF289F5A8D7EB1351616335E49 +:108E3000F4FCD4B8FE0DD0BFCD2DDBEBC6637F8F25 +:108E40000D13657FE56ACC075A6388ED8F50509EFD +:108E5000FB34778DB7393BF8F0EAD15DF21CE4FBC7 +:108E600061941752AEAF383EBE79A81BE9EB73CAC6 +:108E70009B96F2B9CEC9F365E2F9D8DB829F835E97 +:108E80003C1645EE8A29F3E9BE88CE38775BA58685 +:108E9000FAB08C73D72DF652FE34E803FF9141FAF5 +:108EA000C0F933FB19EA9DE7C82EA8FB52E5FE2660 +:108EB000D02BF0FE1F735B29F955319DB75FD4FEAF +:108EC000CF15720A7578A487BA4D3F784A0FF543DB +:108ED00033B530F56BE8FEFEAFBF65703DBEAEB09A +:108EE0006C03F203B65DA1FBB756157E467A47EDDB +:108EF0009E9B4744E7FFCFD9FD18CF1FDF61E8767F +:108F0000FD7FCBE07A6AED9E97C86F7A2EC08F2DD9 +:108F100055A98195A8875655E950F362C581CAA91C +:108F2000A40F4C8175C0BAFE9CC1E153B763921F78 +:108F3000CF23D4C17F0ABCDAE89D4576C1C6296635 +:108F40001BC697EA0AA7CF27FCB75B355C7FFC3CC2 +:108F5000BBE2E9563A37BE6AB7A102F5A812D09B28 +:108F6000FE0DE69B933CAEC2037C294BDF5AF463B3 +:108F70001BE617742F97B764713DA051F1FAEF28E3 +:108F8000267F298BCE57CADBCDF5337BA631C63F72 +:108F90006FCFE4F74C8DF6778C419C7B550D27A065 +:108FA0009E5CC7B44FD1FE655E9B9BFCC48CE713EF +:108FB0003897B8C94F6C76867F3E94F42895E2E9DD +:108FC000D2BEB8B087FBD79665FA7232D13FA80FF0 +:108FD0003F7A07C2EDE7AAF037733E933BC9360CE0 +:108FE000FD611667F8D10A37E519915FA2D7771BA3 +:108FF000691F5E75323BC2678CBF5255A2E48CE498 +:109000001B633ACF4D39C90F5BC6D91AEB07BB7545 +:10901000C64C28DAF84D4A979E70F8ABC92ABE9420 +:10902000FA83CEEC233BA77C0AD88D8897CB238785 +:1090300074E8F7777690FE581354689C9AC2DF5014 +:109040001EE03C916FD699F7A586290FEE3B990952 +:10905000C28FD9C8F19275905DCC9EE7F007FE44AF +:10906000F9715D7AFC526A27FB338A78458DF0E30B +:1090700000A0A8BE2C53FAE19689A7CCE7E3E3321F +:10908000D55D12ED775837012409CDCB9D84F37D52 +:10909000C4EABD2D13E6750AF017D779AA2981EE27 +:1090A000035BA77468E8D7F417F1BCE1783CF28958 +:1090B000717B1D888C457912D9D353DE30CF13DEF6 +:1090C00030E23ACADB2FDEFDE958C40F56C1881ED4 +:1090D0006B775F5DDEF04CB11FFFCFE40D7B146D4D +:1090E0001B3CEFCF7470FD4AE60D7BF87EC9786BB0 +:1090F0007CBEF0858C90CAF3FAC25B9E42BB7DB702 +:1091000089F261C6EF7EFD18FA35C79B5990E2CF10 +:1091100071FA43C4396909D2C9C54FCE6C798861E7 +:10912000BEF9CB1E7E1E36561FE8C91EA098499474 +:10913000DDB83653E8E7DF923D20F9759DB0AF3ECC +:1091400056228F14E0FAF6E9EDDD9D5FDA22C7EFD3 +:1091500029DFA5ADFB7C17E98FAE08E7C7C4BF7652 +:1091600074F6776DF1B4E7507676134F5345FE9A57 +:10917000AA70D6C11C3CBF49C6D3D4D6011427332C +:1091800075C5D342AC9B789A2AE2532B0C5A25F929 +:1091900069F699DCDC8EF612FF6A6C4DF5207FAB28 +:1091A0009B7BEE453C7AA13AC6BAF09C5FA3807FD8 +:1091B000F5D5C7D3DA33BB89A76D157ADB0785BA36 +:1091C0009011E0BA9571FEEB6F9371351DD9B59191 +:1091D000877368DECA4433CDFB83574DDBD03F3500 +:1091E00043C6CB5EE5FEB519222EF6C1C402F23F9E +:1091F000F504E7194DB1718777059C2F594AC94F7E +:109200007FFF2F26907F7E16FAF7FBA07FAB59F8E1 +:10921000EBB99FCFDDC4EF3170EF50E81E59441316 +:109220001DE9A476BA4F761EB0D18DC87AFD80357F +:10923000DF81D78A4E417DC8DD086550FAD595AAF1 +:10924000DF05EDB61E4B20BFE20AA75BE4E7F1F8AD +:10925000B57FB512E8C7FBA5FBE3FC8D3A0DFBB962 +:1092600094C9E57C5296B1DBFB281A0D224E22C62A +:109270005BCA60DFE1A953F87385B89F301E1EB248 +:10928000BF4643BD19FD7B911C7E0FCD25A33685BE +:10929000FCCEC90574DF5463627D5305AF279ABDC8 +:1092A000648978A9FEBB2A5748993B99F2A83345AF +:1092B0005E621C9C6736C796E3E347F1E7E36630DE +:1092C0005FFF8C3E979F1F3B8FFC16FABFB42A5F4F +:1092D000EC8B87E2288D06F71FF2290ECBEF935A0D +:1092E0009ACDE1A6CBE1CFDE8E72BA1710E885EBFE +:1092F000718CCFBFF7779D0AD24BA383E3ED7F77C5 +:10930000DEF1F34DCB2AE07A8D83D36BE34A25C09F +:10931000E1C5E77DB57E92E2AC6FD74FF281E2798D +:109320003A944FDF117FF03F6C20BADB6BE1E75ED0 +:1093300025BFA28423B43F85BD7B232AD318573D84 +:10934000BB9CEE85DA58D53B09E3AE6326D9681D90 +:10935000B5AFF273D5358BC3B988D7B565E182FA5D +:109360006EE08A03A892BF42BBE94EC6EF176A8A35 +:109370008D23C6C78757A768E3B346A0BDF441EB6A +:10938000EBB8DFAD1692AFB58B234FA3FFC097E2CA +:109390009B9405F871FE81E36315377D46FAFCC5A1 +:1093A0007DFDE93CE8F4C6D873716C756C7C923530 +:1093B0002593DF9DB5C4BEC7735B31DF5D16AFE497 +:1093C000FACD3AA36F00EA9F37DDC8F3313E99A387 +:1093D00063B8AF9F58F8FEFB1F4E14FCDA53102DF4 +:1093E0000FEA7BDC5F683708F302789EAC6C5F8322 +:1093F000FB0BFB5A2DF6F79397BE5380FB7BBEF514 +:109400003B05B8BFEB0CCD1AD24751BA6F21C2E36E +:10941000F4CD5ED20F655EF0D5E25DC3B78C77D731 +:109420002A8F9BB3FE35798C7FD17E9357BFD2FBB9 +:109430002D245FF879E22EFFDD39BA57EDE2973A35 +:1094400005F9714FFDE50B3DCF65667ED4C34ACA71 +:10945000C2F45DC9DF750CF541A907C7CFFF4931DB +:10946000FF9D599A09E5A0F4F75689BECD81CFB981 +:10947000BEBD5D217FAED9ED4F1A45F6D5CCE17A60 +:10948000E22FFF46E742589B62473B65CEF6A55464 +:109490007F61F70CAAD7994321B4C76AA01ECB2BD2 +:1094A00046C7E6791B77F27890B47F611E7AD4D7ED +:1094B000129C1123E2672DEAD730C55A95FBBD6B8C +:1094C0009DCCE367A80FC7DA8B32AEBBD1CBEFEDF3 +:1094D000D9D8A6D0FD5D69465F7E36EE6B5C7C77A1 +:1094E0007F96760EF14EC6E71F4CD30E22DD3A8DE5 +:1094F0002C97F2F90CF25C5AECB9CF9EF2E48E761E +:10950000E2C195F4A8A9A42FFD9579495F7A072FA8 +:10951000CD243DEA4ED2AFE4FBCBF3E40231F1FCC3 +:1095200059E29CEE2C714E17F97E288EEF4797ABCF +:10953000A3F2E442DDE53B44E5C9457F179D2717CB +:109540008AE18F9C9FA4EB17501CBD0EE866D1B03A +:109550002EBCAE66E26F7DE4033A37B4C3447EBAF4 +:109560006A91C75B57758AEC9F3A3C87C4E95BE315 +:10957000E7E9B97E550D7625E5330763F37D95EC74 +:109580006F57FF96ED7AF2C7DBB2A59DC8E95BAED7 +:109590004BAEA3BA4DE1F41837CF787B3ADEAF2E4D +:1095A000EDE1ABE573EE6F79DDD7CAE706C7C1E140 +:1095B0005FE57397C527FA46923CDF427CE223774A +:1095C000731ABA28659E74D33E9E273D566FD37892 +:1095D0003C54CFF325E2E3C2EEB114F7947168F383 +:1095E000CBFAC0B27C6AEFC17CB49A7D8994BF503B +:1095F000E5AE223D3E3E1E3A97B58EC5ADF82B3BFB +:1096000042E7DEFEBB7908DFCF4E74129F72B3FCD7 +:109610006BCC43B83BFB1AE2A1076D9FA7F8A2F001 +:10962000A56C101804837ACE379B2BF63F41E4AB30 +:1096300098553F73447DDFD3770BB2B93FF1A0C893 +:10964000935A939840F737B88CFC9C874BC7F3B973 +:1096500086667A17E2FCCD6EBE9F4FECF901C373AC +:109660007B4F1882749F82BFC6E641B928FD58B26D +:10967000FF76E15FBD5A3A5AF93FCC3F1E957473AD +:10968000B5F1BCF5008328FA8AA7879EBEEB89BF97 +:109690006CCFF63EC1F1421B427190ABE44B09C561 +:1096A000C0B751EEEF34B9D11E41BF0CC9DBD5199B +:1096B000D29EE7F742ACC921B9F88985DB27F2DCF5 +:1096C000945CFF2EB9FE6F496FB4A47BF764437FAF +:1096D000A74B353A27B12291CB97C8B33C1F29FE3F +:1096E000FC50BC5C91E75FE478BFFBBFCC578F7D3B +:1096F0004B7C15E42CE91D3DC67D2FFBDECFEFC171 +:1097000029EBD044FE0D9DFB90F3AAEBE0797C673A +:10971000C5FCE4FB90D07306E7681F215E9D7FCFF8 +:109720006CC6B86A7131E79FB55E1BC5256A833C7C +:109730005FA77631233F823C273CDBE5FB1CF76FBC +:10974000C5711BDD5F5BBB7B6B536FCA67F091BE5E +:1097500078E13DFE3EDDE5FB02DBD52D0EC7C43FC3 +:109760004ABEF97C794531CD97FC004E53ECF9ABFC +:109770008C1CCE6FE4332D47C217EC1DF8EE7C1520 +:10978000CF3FAF736AF652CA63E0FEF5047707F97C +:10979000956A77929060940C8BF53FCB26BCA9DD3F +:1097A000595A44F736042D45740FD19FF8BD5DE733 +:1097B0001FC80CE8B93F3E2967049E3B09DC8A7A42 +:1097C0006B1E8C832AEEF9D65B8BC8DF1847779225 +:1097D000DE3ACFDDFED01C6850BAE8719D81CB49DE +:1097E00029DFFE91EDE6F110A7C8476C9BC066DA51 +:1097F000BACA36676C9EE6CEAC9BFF81FBF38F6CDA +:1098000055C4D179DC3EDF0CD66CEFCBF1305FC4B0 +:10981000ED27887C0BE63777E559F4BE72DC5ECE27 +:10982000AF93EF8BB87DC297E27722EC46C28BC430 +:1098300026CE3718E005EAEDA3231D63F0BC5BDFFD +:1098400096D06884572F043F9EA361E19F0FC5788F +:10985000488A3A1AE3215B160D3B80715A7565C739 +:1098600077716BDCCDF632345967BBBC37E4107FBF +:10987000A92F44FC2FFBA381E747AE4C2079DF9250 +:109880005B4DF991178E9B62CE23C53FFD6C990B02 +:10989000FD50BD9BDEA67844E24EA5DBBCD79FE61B +:1098A000D844FEE43217FAB5129B3AFC23D14FF3A9 +:1098B000B0C2EF0085D92B2EF427A83AD43B66EC32 +:1098C000E6E7E567343BCACCC44F151ECF19ED243B +:1098D0003EA9AEBC4D87769FBA94D17D7BF373B819 +:1098E0005FBC5F8B5D87FBFEDBAFF5DDC6E97C39D6 +:1098F0003A19573422B86A4C914398DA29E38B32EB +:10990000CFAEA77BECA53C8AD7672FD363853CEA13 +:10991000D4E7E3F0B8A7EF247E4B7CFEAD81911E27 +:10992000F65BC54CE7DE245E37CAF3075F733F7111 +:109930009EC8DF39B5EABF86F07B02647C26C0EFA3 +:10994000713584976711BCC237FA71DD3B1DBADAF5 +:1099500041E45FABA57E56F27BF2F29AFA2C1B59DA +:109960008C4F3B53600AA7F6CECB43BAF4031EF4E8 +:10997000EB060F6ECAE17952EACA04DA37752DDDBB +:1099800010CE54471AED9BFA18DF9FEB73383C65F5 +:109990007C58FA4107E7F8D6603E70E739B545567E +:1099A0007E4E4D9CAB4E5C74FC053CFFB545F8A368 +:1099B0000FBC3A907EDFE3D24A55413DF592A39227 +:1099C0007ECF6AA3D8D744B583D96DD1F87980F218 +:1099D000747BEFE3F986AA3837AEAE746E4578969D +:1099E0003B7D948FFCDDC610FD04C6ABF6D314F7A7 +:1099F00003BD88CE079FDBA348BD28461E4ABB2D6A +:109A0000DE1E7B51F2CDFF213D694F279FBE463BB5 +:109A10008BC5DA9B9DEDA5FD186F4FC47DDF93FECE +:109A2000C3347F4CDECD11B1EF52BE670ADE28F39E +:109A3000713ACF89B38005CF714C41A21CD1959763 +:109A4000C444BED27AC5EA417DA9A7BCA4CEBC213C +:109A5000563F94FB37EBBF834F99D724F3962C984E +:109A6000BF927279FE8A05F35752F07750F87973F6 +:109A7000997FD26070533E8BFF4146714965620504 +:109A8000F9FF92BD46C2BF8B2CB0017F07C03FD902 +:109A900046E7EAF19C13E27D447151BF632A34D951 +:109AA0005E87ED3BEF93AC64549FDC57CB403DCCDD +:109AB00002F578CF75E739F399FCDEFDF8FC1599CE +:109AC0004725E3CA99FD5F56D0CF8A6104CA67F87B +:109AD000B1F82E9FF7D3F22337F18DB4069E2715E8 +:109AE000B99ED9D1CF5F26F98F39765FD729BE7C51 +:109AF000A4CF75567ECFC266E669D243B93DA7377B +:109B0000EDE346E6DEAF2386DD4CBFDBF1BC53D38D +:109B1000E7A676E1939C175BCFD77D11CFAD295D8A +:109B2000E35D9CF3F75CD4AFCADA4C1C2FE3C6DFCD +:109B3000D879CF4DC082F2C495CBF1C113A7EFCA3B +:109B4000A72B5789C9FB93E3F7B43E899F57D2E30C +:109B500025FEF5846FFE32B14F271248FF90F8764C +:109B600060C90EBA4FB27D49909E172D4A508FE7BB +:109B7000872D9169C81973F2B2EEC07B502E26462C +:109B800072F11E95016EB717EF51B9981A3981E538 +:109B9000EB9FF8BE97EAFB45B6E0BD2A77E41DBB14 +:109BA00083EA713F33192BDA72E40EBF0DCFA9841B +:109BB0009777A0DC2A8ECB8B89BBFF2141FC0E540A +:109BC000BACD48FA64BA8813B272A1D763440BCAFB +:109BD0000D19451417B431F7CE0EACCF36F17B22F8 +:109BE00018E03FD6F7CBE7F9158CAF9B650B7F37B5 +:109BF0000BFBE9771DF31DF47D271FDF6912F12EA2 +:109C00003EFED197785C52E6093366CF417DC8E6C7 +:109C1000663165797F0A53ED39785F4283F4278A8C +:109C2000F22B09BE49B95172F9E8CD3F1944BF2F53 +:109C3000F3F2CFFA22DFBCC5187B3FB77C26BB39D5 +:109C40009FBC28EEA1BC2FC17777EE08FC7D9969F7 +:109C500063F14AE12929A54607E96FCFEA914FA5AB +:109C60000AFC704CE6F373947B15FC5D17790F6466 +:109C7000AA4F253F01F3B5E851AEA69EF652FE610C +:109C8000B539928BBFBFF396D95785F3BC5479F29F +:109C90007E8A3F661E3D81F922470DCD6392508E2C +:109CA000E48B7B3830C00BE5435979640F76F2873B +:109CB0007E0AC547C74FE6E771C7B1A08AFB3CD60D +:109CC000CECF878D2DCEF734C078E345BEC9D8639B +:109CD000DE24E46F637F1056F93D2111353ABF430E +:109CE0003E99CBE08EA6875BDD516586F755C7961A +:109CF000BFE7892DDF31F2EBFED1E5C18AD680EBDB +:109D00007C4511F76D007FE1EBE2798CBF12F6DC48 +:109D1000401733E7619EA553F1A3BD30705726C5A8 +:109D20006D768D64544EDB61DE668E5EFF5A1D8F4C +:109D30006B0BBFBAFC7D2AAC4379FBF27B6904AFA5 +:109D4000341BF05B27711FC2B703826E0F083A2DD8 +:109D5000C9325B91FF1F30B837119E279ADDE8A703 +:109D6000DA9F68A4FB7F1BE6F3DFB75092CCCC08E8 +:109D7000FDEAA7F332B4633742BDBEC44CF92907EC +:109D800044DE77C3832AF9B9B01EEF41D43F622580 +:109D90007F797952E1DD58AF4F32D2B98BFD8925F9 +:109DA0003E311EFD2EC1F64473087F2723FE1ED6CA +:109DB000A3382F841BCCEB293E0FA2477D8991F459 +:109DC00070793E1FFAA1789E3ED34CE31D70D8F700 +:109DD00023DE357C449A1ED48F74633E99C4EFF21F +:109DE000A491F4BB33407D7DA3EFD9D7A779DCFCE8 +:109DF0001C30FF3D95C2CEDF578161A11DBAD51938 +:109E0000D12D8F0FE648B83355C3F6194C96F9F9A2 +:109E1000B5B4CE72A94AF72D29B2BC94CA8F8B7AF9 +:109E2000796F6C6A1EE7534ADBEB7F43BCED9B0402 +:109E300070817DF224747F7EEAB4E0EF97EF5F8952 +:109E40000BFDFE0AAE7350D7FA0F383C2E6F54B993 +:109E50009B7D0920BEC5EFCB018BC78D7EB62BF74E +:109E6000C7E12AD7A1CFE4F0EC5C474AF7EB48CD35 +:109E7000E3EB088A73E3F1F54A9EEEDB5E67B7F821 +:109E8000F72FAF332D769DDFE23CC3CAB7304F7D4D +:109E90002ECCCFD6353FFAF9B812E49B1CFFC68909 +:109EA0007C6956189BE7C4467ACC5C5F8CCD6BBA54 +:109EB00045D9D488F2F57111377F5DD0D5A184FFE3 +:109EC000D517F5ADD7A715B413BFEDB5B411894BB0 +:109ED000F267C9FF2F659C2CC132C88101792067C8 +:109EE000EEEF7D741A76DEEE78BC2FCA2BE09BD79E +:109EF000E58DB87C9E927E3BE70BF48B7424E937AA +:109F00007EFE928ED8ED414A10DDCC42F474319E33 +:109F10008F0F7A09DD73CFDC395DEB03221F6BAE47 +:109F2000E7EB58EAA779DFE27894F2106FC9F7DD22 +:109F30009407FB3D65E8A774FF147355F6273B4D66 +:109F4000D1B4FF9BF3C58C7F7C2FF5FC78BDFE4A16 +:109F500079E9729EF1FC50CE4799B883F4F83AD073 +:109F6000E379DEBA42FCBEAE4AC7F9F06E85F4FA78 +:109F70005A903328A7E4BDCC3715581BF19ECDBDB0 +:109F800006EE4FF5BF6472C7DE4B159FBF2EEC89FE +:109F9000C54CDA0BFC7E8B1A3BBF774AC89996FBFF +:109FA0007ACB7BA9B83C043915732F55A53BF65ED7 +:109FB000AA1EEC05B00B483F63BD74C22EE072BA16 +:109FC000E57AB7DDCFC8FFCC7F2774AA51E88300BC +:109FD0008BB4AE7BF3C00EA0FB001BF3F2C5BD64D7 +:109FE00001FEBB2C42FF8FF74717A5FB56209ECCE6 +:109FF0001CA4E5E24F04CD30727F33E0DBA60E8671 +:10A000006998F5DBF15ED95B59FD3BBA3E846F0F71 +:10A0100013BE0DFC94DF37DB856F8FE4A572B98426 +:10A0200042E64A741C71FA1EC7715B1CC13FE13DD8 +:10A03000F81BDB4C046F99E71A4FDF51F3396DE0E1 +:10A04000F371EAF5349F27BA9BCFD5E07D345EA546 +:10A05000338EDF3DE13F9E27491CD685FF8315DF08 +:10A060008B386E271D2CE776D765F3D6DB68BFEFFC +:10A070009CCAE3727509D24ED6C667A4A11F928FFF +:10A080007FE74A8E177756F2BCA4096D35148763B3 +:10A09000E53CAEE681FFD1EFFC08FE36D9596440BD +:10A0A000D4FB2BBBDB807ECEC9E363E36F53CCB71D +:10A0B00050BCEFCEC98698DF39957098227E477DD7 +:10A0C0004ADCEF9BC6C3253E6ED7C90FC47AB3F0F6 +:10A0D000777FE099CDF8399E0CF17B7447F33AE332 +:10A0E0007BFDAF31BE772CEF1AE27BED8608DD3BBE +:10A0F000F15AEAEC4DF3816EFAFF7210DDDB7F73EB +:10A10000DA9CED6BA1FCCCC6EBA8FC5ADA0F171E4B +:10A11000C5FA2D05542ED77D3A0DE9A0B064EA3872 +:10A12000FC9D83760BEFC765F5B5E0EFDFB886F4ED +:10A130001E86F9C8E5C608B5BB6D68CD70CCAF2AE0 +:10A14000B7F2F291A2FF1846E5DEA23CEC95EBB027 +:10A15000DCAE7C3AADBBF8E0C0422584BF73579EAD +:10A16000CCDB8F1FF66C26FA8BCACB7879A0A7744C +:10A17000651FACD77D36AD3B7DC428EC21A95F7B44 +:10A1800005BDEFD24E36E2B944AF4DF1E0F913EF21 +:10A19000C893FC3E3A33CF53F93F722300BD008091 +:10A1A000000000001F8B080000000000000BE57D90 +:10A1B00009789445D270BFF3CE9564924C0E20215D +:10A1C000102609840492300987288703048C0A38F2 +:10A1D0005C028AF08633E42011748DBBEC6620802B +:10A1E000E8A28615151574404070118302A206BEC0 +:10A1F000E1505151E3B1AEE82E7FA2ACDC1283AE48 +:10A20000B8EBAE7F55757766DE37C902FBFDDFF32D +:10A21000ECF7FCF8EC76FAEDABBAAABAAABABABA7D +:10A22000C7EBC935CFCA626CB847F1F8211DE158B8 +:10A230009268EFC7D858CDDA4F5518733A5296390D +:10A24000E3198B1E38AC3F7341B99D59582A6337C7 +:10A25000A468E1AE0E8C4DB9E6DBE4289531E62822 +:10A26000ECE98D849405181BC0D838FC13EA8FB331 +:10A270003B026A0EFC9D6F39D790C1E8DFCFD03E1C +:10A280005BF1385DFD31D725E6EBDE8C61173F5F72 +:10A290004FFD76C0EF53067D9B6CC68F09BCDF0B6C +:10A2A00016C74A253AD8FF4DA27FE661DDE33B326F +:10A2B000A688FC4D72BC0CFD78F84F817A9D98F809 +:10A2C000BBEEAD1F15ACB7A25661690005F351BADC +:10A2D0009ED528084CB6A2A5E3FCACA67A177EEF63 +:10A2E000A6B87B39119E816EBB37BB35DC12BEAE82 +:10A2F00026F890D71A2EFC67867C1293FF14A7B31A +:10A30000238ECBCBA19D87C506E182F107107E5637 +:10A310007078D62B1594624306ED1688760BE47C94 +:10A32000F7EAE73B209CF9C2008E04E65EA962BB17 +:10A33000F8DC5EFF0AEEF2F0A81CD687B18976EF52 +:10A34000833698C3A4985944E7C9CCB73B06E6FFC7 +:10A3500062845680F0A826DFBE0698D41CE6B1229F +:10A360005E808E37723A72BA48B88CF86881D388AA +:10A370001703DC463C04E9539F886922ABA07CCBE1 +:10A38000BC0CF3A9461E047E6DCAB5F937E22066FF +:10A39000F81FF0F3D1C274FF034A10AEA30ACB300A +:10A3A000433D9F12EEDE9CC2D80F61307FF81E2F16 +:10A3B000F03068E62FC6B2A8D6F056DA79BD7BC277 +:10A3C000A336627A7D7AF8325334B64FF663FDF8DD +:10A3D00070487382F0FF60629A1DE0BD47AD25FAB8 +:10A3E00075614D4BCC29413E7BD80593EE8F7C297E +:10A3F000E7E353904E569332C3EB8039E1BFEB83D2 +:10A40000E9C32E4068078E2F3BC0354370D38C06BE +:10A41000A55141785D290E5C2F33EC6AC096D39A22 +:10A420005F704676A0D3CCCBF00FAB799C61BBE1DB +:10A43000765E6F26F68FF5168FF484D69B89E3E05F +:10A44000B82BE1BB3DF85D01BC27C5B6A60FCC8F8C +:10A45000E01F5339C27B220EF06515F4BA3792E83B +:10A4600035E6DE61F45D199FA134C0FC4714B828BD +:10A470008DEDF7A1996513DDA6D46605E9A876D41C +:10A480009EC275CACC0DFDC7C1BCDFEBFF5CAE063A +:10A49000E5C74DAC08EB19F1F75C107F57B48EDAC5 +:10A4A00083FFF508EF36E4FBF34AFD002CCCEFEC1C +:10A4B000243A32A6A520FD629C29C36210DF3FC169 +:10A4C000B880EF8958047CB0A7A3B613E19DCCBC3B +:10A4D00023CD30DFD802CDA239683813C2B3D0C93A +:10A4E000E119A93A886F9BB72B7E1BD4CBF7643E4A +:10A4F0003E18F2E5472CCC0FE5CD8CF375F33AD539 +:10A50000EF037E9AF7F6CB036005B2AF041FF75C4A +:10A510006B622E490FF85FA63F9CB93282F9DE5B71 +:10A520006375F9ECDACEBAFA7DF6A6EACA7303BD12 +:10A5300074E57D8FE4E9F2FDEBAFD3D5BFE6B3E17F +:10A54000BAFCB50D37E9EA0F3A355E971FD2749B16 +:10A55000AE7E7518ACAF3E886E4F7D06E065B6A046 +:10A56000D3F59766EADA9D8D1A7504D7DDEC55F3BD +:10A5700046E3BA1BC64A74FDB01ACB97C89715F0CC +:10A580001FD2732EF34607005F2359D39B4980BF28 +:10A59000057EC58D789BB796D793EDE6EFBD7378B2 +:10A5A0000CA67EFDF712660EE6A19FCA3F6D78E706 +:10A5B000704879BEB3D084FC77DE1519FF7504228C +:10A5C000825DF3B3DA267DDD01A4DF27AADB069FD7 +:10A5D00016BEADD23A58F882E267D06F3AEB118DD1 +:10A5E000F9F2232AF303FD4FB28AC70643FA4395D3 +:10A5F000FF9DC33D82F8B125E8E91CE6D2D339229C +:10A60000434FE748B79ECED103F5748EF1E8E91CBD +:10A6100057A0A77307AF9ECE9DA6E8E99CA8E9E9DD +:10A620009C54A4A773D70A3D9DBB55EAE999E22B38 +:10A63000D6D3CF407F299FD3562ED4D56BE1036F5D +:10A64000D1684C7BD4FC52D76F895A6A65A6203FEB +:10A65000F8E03FE4879E8CB90380E705408780AB34 +:10A66000351F14D5AD5E91F46FF041760AD0BF77F7 +:10A6700008FDD569D15A1BF25CA692AEA04FFBA68D +:10A68000F4273B6800A6537A821D04728379DBB6F7 +:10A6900083A4FC0AB53BCC0382FAAA3DB9D64ACFC3 +:10A6A0008E95FAA91D3DEBEA1A94838090638CDBAA +:10A6B000018CAD32211C53055F1F0CE77C79118B97 +:10A6C000AE857A506720C0750CE186718E85F73EA5 +:10A6D0008CEBF436566BC1FEA7B17A4AA7B3264A73 +:10A6E00035E624BB622673533A9B79297DCFAE4D64 +:10A6F0004901B9596A6F188076C95F0B3F3CAE209B +:10A700003047E310D876F12AE5F5C7F827D47B3037 +:10A71000C5AB215EF3EDAEBB1E854F07514FA0FCCC +:10A720001D1D47F032B3377B7C765BFD2C25F9FE8F +:10A73000BAA26928777D8976F766985BEF24664F21 +:10A74000443D97E04F1D0FF4294FD1EB975E8227D0 +:10A750005EE85CBB10ED28C6FCB1A81FAE76DC5FDE +:10A76000A5787E8170CBFA979BAFD55A7B27C2D94B +:10A7700054E6706F04FEFC44D0E3D95B6D01352ACA +:10A78000C8479F454C7FB303D0EDEE086D19F1DB50 +:10A79000E41B57605E3918E75A08F05D28047C73A3 +:10A7A000FCAFC4F252BBD6AD234CF17C57AD67343D +:10A7B000E2DFCBF10F7F647BDB849FC33342E1E3B5 +:10A7C000BF1EA1ADC67E0E9AEA93DD880F73FD0011 +:10A7D000B24B1D1DA89FF3568E97F6F0303CA2EBAE +:10A7E000349CD76C9BCD8DFB93E10AA7EB89B819FC +:10A7F000D3CBE1CF39266FC780AA83FB1982DB59FF +:10A80000D82D11F8E6BC45C06DEF20F0EECAC27538 +:10A81000D51EDCD5D83FDA89BF56FC6827D23FC8A1 +:10A82000BFE28BF13F00799BE9E22713D07EC93666 +:10A83000B93742D1BA70E81AF8FD0381EFF516C8AE +:10A84000C7D2F795F83D219CB74F78CCE4AF86F698 +:10A85000DEE1AF129D9E5DE0A0F91432971517D985 +:10A860002C615FFF65D8DFF735003DF6A5687B7189 +:10A870001E33E24CC99F101C5A6FB477D8E02BE30B +:10A880007FB94EC73BF914E608BC4D601E5A77935A +:10A890009866C1713FFAC6EA41F9F991902760FFC5 +:10A8A000D3F7A9CC4FE9ED2C40F5EF600D94FF30C4 +:10A8B00022A76B25C037EEF19E3D50BE86E0FD7DA0 +:10A8C000BE5EB519F19C5F4E7642BCAFE97045FCA7 +:10A8D0003B4EF00BACD74FB11F58AFFD725343D670 +:10A8E0004D3EE7176676F6F857EBA6BE99EB0B10D0 +:10A8F0008C8E4498FF0D828437784A484FA09D156E +:10A900000FF8AF77A96467150C6B3423FC5BBEE5C9 +:10A9100072ECAD252CD207E56F0D5319D26BECDA32 +:10A9200051A7B1DD511688EF07F5475ED20E47C338 +:10A93000FCC7827C0789CC0ABA809E08D14B372598 +:10A94000ACCE473BE2A6EEFAEF37B31A15F1373A31 +:10A950004BAF57C6A25E91F560BC038887D8D6FA84 +:10A96000E547A95F7AB15E57A35F169A3C2C95EC38 +:10A97000549715F97EA69979DA5A6F937B2AC29E6D +:10A98000E576CB2D62ECE6D117AD1760BE0353B56B +:10A9900008EC67E198BF4C47790CFBACF7FAA21EB4 +:10A9A0007D5F650F40F99755807150AE27AAECCCBA +:10A9B0000306CED7554ECA9FAA4AA0F44C958BD217 +:10A9C00073551954FE4D959BF25353BDF1D8EFCCFE +:10A9D00095DF9AD18EBA2F4CD28FC3B148F0EF7D5C +:10A9E000617C9FB52872D1678530EE225280A0AF7E +:10A9F0006B6B46A1D955BCB7F64D4CE1BBEAC0F232 +:10AA0000D58A1BF5D39CC3DA0A649F79471BC6A27B +:10AA1000D8E9FF87131D116F659714A6C1523AD06C +:10AA2000C39386E39FAC1A48709DAEF2105C9EBA49 +:10AA3000C637E3A0FDD9AA02CA2F4CF566A6764018 +:10AA400075FBAD15DB8FD9DE684E82F2911EC58392 +:10AA5000EB7BA887F9FD40BFB516AE2FD682BE406E +:10AA6000FE19963D7EFD5D0CE5B9D617C799143BDE +:10AA70006B641CF2D5C04233D69BFC13D85C2941D1 +:10AA8000FEBEDC3A39BF5F21FC9CDF1F43F89078A3 +:10AA90002A13F43ABFA7F72D83A0DFFD6047AA0071 +:10AAA0005FF32513C1D7FC59B81F8D0463FB85BB29 +:10AAB000D33A3107CE131ADB30DFBB13033A9C7D48 +:10AAC000E19E04A44786623655825C381B5BFBD747 +:10AAD000CF51EEFD99CB3DC66ABF7E12E562970469 +:10AAE000F70390FBC602FB34DAD75444A05E5C60E7 +:10AAF000651ACF6BBD317F369CD1FE76C08EA4E146 +:10AB0000B89E703C57CFA05C4BDFF178EAAF5CC1D8 +:10AB1000F96E79E189E6D75C58EE27BEDCB6637D35 +:10AB2000E7A72057BA737938C2F53ADA19B04E5E02 +:10AB30005F1D41F2EB758BFB7825CAEDF50EF766CC +:10AB4000A8F7DC43F77EB917D307CBF2EE45FE48F2 +:10AB50008DA57E66FF6E7E2F6C0F7A9C25C2BC7E13 +:10AB6000FF8A120843FFCB9A034B1361BC3EEB1ADA +:10AB70004D9D21CDDDA45463DABB6BC111D49F156B +:10AB8000A92E6ADF777B8A8AF661AFCEFECFAF2728 +:10AB9000FDAED7FB596BBE1DDE9905F57F2FA5F6DF +:10ABA000CC12A0EF7D5D3FCDE3FBBE1AEA6777DDF7 +:10ABB000848F6F67380FB02C10EE422BF92570BAD6 +:10ABC00016C89FDF95B601FD177B4CBE0DA48F669E +:10ABD00072FBE3BCD7F704F24D19D4F741BE2CD772 +:10ABE00017751D9497FDB9BB1B3884757DFA8602D5 +:10ABF000C4C7825D8F8EEA0CF5CE0F666E05402FBE +:10AC0000DA7D7114B6635DC156C67E765577BC0D8C +:10AC1000DAFD366B787FE413AF5A4BE3B0723ECE69 +:10AC2000E3428FB1861CF20B904A817ABF85CFF840 +:10AC30003DB62EE600F76D71FA94D72D4941FF4AD3 +:10AC40003FCDEE56711DA4F8122B1C41BD08FAEC45 +:10AC500077B87E12ADA25FE78464EF55E833ABD0DE +:10AC60004FB2BFC7ADCC1716CBED6005F5AD95EB78 +:10AC7000E1CD202F905FA51E867137A6F2F664FF06 +:10AC80002681D2CD0538931EB7F949D75FE1F84642 +:10AC9000BF99B443A6C455EF6B40FF4E84B603C7BB +:10ACA000917E326676BBD0CE5916E1793195ECA80B +:10ACB000A6649C03E8C997B1DE0215ECAAB410BBE8 +:10ACC000CA7E657AF2C508CFABD8FE4AEB1BE5E831 +:10ACD000A2EF4D2C17F860D1A336DA77560BFF415F +:10ACE000B5F06755470EB0E3FA67874DA56F82FE52 +:10ACF0001CC27B68E97751641EC9876AC6DAC4DB67 +:10AD00007E58D71AC89100E8010DD6F7D04B4D2ACE +:10AD1000E7FBFA43D1FD507E324FA40BF7F526A690 +:10AD200085E847633F40B76338CF612C8269217A59 +:10AD3000D0C362ACB87E9923F6DF9AFF60413F39F9 +:10AD40008FC1C27F37B8F9B30894838BBECF237904 +:10AD5000D8DEFCF689F9FD17CE0F526F4FEF39841C +:10AD600073C8774E33CE7388795C32DA2D007F3327 +:10AD70007E1FFA9D490FFF4FE1BAFC95CEE36E8529 +:10AD8000F94CB83EBFB5FA717DD6017FE37AAE9B30 +:10AD90009FE54739B007D603FAF17DE3AD64B7D636 +:10ADA00009BF685D0727F98B5EB7F0BC6FAA681F03 +:10ADB000C6482FD44DED4CED3BDB2ADECDC6FEABB5 +:10ADC00023487ED659FC2B53B1FF5FC7B97D402F76 +:10ADD000D5FEECFA137D61FFE037F92CC82F96C041 +:10ADE000ED2AF6F7AD95E1786B620249E5507FCD2B +:10ADF000FCCE54FF33308DD01F37C8649A31CE81DA +:10AE0000E59EC458C8EFF9A74A7A604D2EE41D2488 +:10AE1000C7C9BFB7669C27313C1ED38E26824765C3 +:10AE200015F43D85B7FBDCC2EBDD26E8774CD00797 +:10AE3000D639C9016D6C8419F9F8DAB49959696485 +:10AE4000C778121580E7C9D93D18CAD1DB8A6F4C83 +:10AE500021BE117ECE298206B23F26FCA493F8675C +:10AE60003675CEE630A4E7A4A230F2837E56B43421 +:10AE7000D205ED2769C2FF3951EF17BD36CD43E347 +:10AE800096D566A69D08E1EB9936901BD0FF43E16D +:10AE90005ADF34E4C7BDB954BE178C959F615D7D00 +:10AEA00039BBC70EF253CC96FBC2C02CA4EBFE26D6 +:10AEB0003BC3FD467BFC508D74807EBB215DE2046C +:10AEC000BF22FDA784F37D8B19F805F2D5B599B49F +:10AED0006F79C6C23C0AD26BB78DE85F30DEEE21D7 +:10AEE0007FE294F00D36289F21E459F59470FA5EC4 +:10AEF000BD2FD26F52683F4479DF4E0BB52BB5FAA8 +:10AF0000B76D817E4AF76792BED96315E3BE16C15D +:10AF1000CBA33C29CBFB617927E283D72DAE682AEE +:10AF20007F5B65541E1E488F013CC6856913111F47 +:10AF30009D6D406707F6CBBF1F17FC751CBA45FA1D +:10AF4000F92A22A95F5AFA90D7AABB6E447A6A56A8 +:10AF50005ECE7EA952F971A727710EE48F57241196 +:10AF60005CD26F74DC6B25BE3F5EAA90FDF3A74AEE +:10AF700035600DF5DB8FDF7A7F3AB4FB6ABF85FC65 +:10AF800072D31E2E398ADFA72D2D23FFE2B4E2C52E +:10AF9000742EF0CDE2AF06AC85F9342CFD22590BAE +:10AFA000F1334F2B855621EBF937699E32E4832725 +:10AFB000D3B40A9C5F7956C35CB497BFB1D63F8DBA +:10AFC000F67F7ABCB608BF5F78F5E4166E4737A502 +:10AFD000A39E5860E67C22F56DB9E0C35EDDB57BCB +:10AFE000B13EE06D3AEA9588AC7A2EFF165F99FC87 +:10AFF0003F53B7798F02E39484D72DA054F5E760CF +:10B000003F67954094924678D4705D9D7306A21078 +:10B01000FF9A89DB6D255BF5F3C27F789E55827FB1 +:10B0200040BB925AD51386EB80F9AD087F09B30671 +:10B03000EBA704E905FD10BD98E34FD37F05742805 +:10B04000DE969987FB859298BD0F0DA27AD04EAE01 +:10B0500017B5755ECEA7353C7C7EE7C43A38075FEE +:10B060002CC82FDB6D72DF4EE37FF36A271ABFA374 +:10B070005827DF28825FB78571BE72C3BC10CE1718 +:10B08000395F3D26E5E436DE4F499CCF8472A9A4A2 +:10B09000CA497C25E512C042EBEBEC8E246A27E519 +:10B0A00018F33246F577246EE4F69BD8BF22C050E1 +:10B0B000BFF8F77C1CCCA33C3FF37C921C97EC6759 +:10B0C000A33E36CE7B7F9A89EC2DD0D39DFED5FE54 +:10B0D0002F2361D6FAD97D43E613691572C19D30DD +:10B0E0002E1BCF0BACBA7EBF89B4CEF038F0DC405B +:10B0F000FF5DF6F74E1ADF1F7633D0B9B3DA74C0AE +:10B1000086EBF059467AC308C787A2DDF3CFB7D0E4 +:10B110005515FE71E692FCE4E2F63CD1EF9855D26B +:10B12000EFAE2490C72588ABD4201EF7E46A49A867 +:10B1300037BE11E73D7B62209F85F614A78BCC4B71 +:10B140007A18F972E9B1B94978BEF4CF34EEB73361 +:10B15000E27B09E015CBAB2DB05FC9C27DEB914717 +:10B160004EF408CEE7EB2A8F6776487EEEDA5C3B3A +:10B17000AEC779EB72ED3343E851BDB5EF1117E07F +:10B18000FDDC56B31BC57BB5D9FF10DAE9D55BD51D +:10B190005AE42328B723BECF390EBE8FF5E6AE8B17 +:10B1A000C9433B5CB69FB776A46776081D7A6FD516 +:10B1B000D325BB569FEFB3579FB7776734BFAB6DAF +:10B1C000971BD0E7FB1ED1E75913506F00DA039CA1 +:10B1D0006EAF0C741F7101DDBAF955377EEAE618BF +:10B1E0003F610CDA11EB54770F28EFB6D87B33DAD6 +:10B1F00015A7D6CD7123D98B54DF825F014D8BBE4D +:10B20000187504F5EA5956FBE918A0CBDCBAD556F7 +:10B21000B30BE7ADE7F73D26C1BFCF737FDC7CBF43 +:10B22000BEBCB55C5822FD1819A1FC65E40318F7F3 +:10B23000560F00545AF9F12328178A4603E3A31E38 +:10B24000AF5D6D45FBEFF2E3F8B87DE9F0B8101F94 +:10B25000850379D9759523D857B0EED8AA0F472121 +:10B26000DC85BF55C8FE287CB9E761E4AFC69D53B5 +:10B270006FA2F4D6029ABFF4FBCDAB530291907744 +:10B280000E74ED6D807673FCDC7F3173992D280F81 +:10B29000199E7B19E05813520EF0CFDB7BE0473C40 +:10B2A000172E5AA76F371FE434EA9FE24D3FDB4267 +:10B2B000BFCBFDE875751B549CF71C01BFD49FCC18 +:10B2C0003794CE1DAEE34DD809FC3FD03BBFEEA86E +:10B2D0008DEEDE3FA847AF5BC3DB83D82DC47997E3 +:10B2E00039AC2E9C77999D0522009E2391560FC65E +:10B2F000955C5C1B497EB7B936B057F3286518B723 +:10B30000008298CEBFBEFE4025BBA72C8ED3BDECDD +:10B310001985F66965E82CC5FCB33C3F9F05683E7E +:10B32000C82F9ED079FAF57956C3F777A5E6C00104 +:10B33000C44B316BE0FB33A0A727E4FCBA14E6F959 +:10B34000592CDA6F86F6CCADD1B99C83DB63E57BF3 +:10B350007FB68596CB7DA6DC074B7FF033E9DE70A8 +:10B360001CC722ECE635F77BD211DEE5164F3AE238 +:10B37000C1B73A8CF6FBB76DE0FA6B4D0CD8B1F162 +:10B38000643F933D7E9BC2ED733695CBC341A69738 +:10B3900002A86F9A1E8D716F74517DD2636B1ECCA3 +:10B3A000E4F6FF3F55B2879A56F3388835B91C7FCB +:10B3B0006B1ECCE6F6BFD47B1D18F5D7DADEF6A4FB +:10B3C000A31F823DC2E1FA1CA714625FE776D21E7A +:10B3D000E81E323F6997B3A22B3B9FD82CE2329AEA +:10B3E0005687F9F17CE284E27DD31462DF3ED59D7D +:10B3F000EB8901C33D5B443D3AC7986D1AF7C0F530 +:10B4000000D7ECC74C2EF4A7B5E0DBE34947FD7944 +:10B410006275581EF2D980E1DCBF743C97CBFD8881 +:10B420007E8CE29B36897E377537E9D28470E03FA7 +:10B43000E8E7C448EEDF8EECE725BFDE661797FB32 +:10B44000C679D48A7E665BBDEF0C69031E891796A8 +:10B45000CFED8E13772A1B395C406FC80FF85D184B +:10B46000F9034F08BD24F10B7C43710C526EC5B437 +:10B47000F08B7F5B18F0CB6A0BE703B96F0BE1171A +:10B4800041FFAE44DFDB047DD98361825F4CEC6F0A +:10B4900088C7914ECE0F57B9FF027A1F417A1BF72A +:10B4A0006192DECCECEFFFAFCE51CA5E79618F0FB7 +:10B4B000EC8CE2171F8D6250EFB4B9A6A31BDA978C +:10B4C0006E5E1EE581F494D917E584F14FFBD50239 +:10B4D0007F1BF8B6F690FE688F430939F73CF3FC02 +:10B4E0006FC7E23CFFBAD9E2449150BED546FBB1EA +:10B4F00005BBE693BD0EF9469EBFEF5B3C072DDF13 +:10B50000ABF7B7173FF7684717E1DB97644AC034DA +:10B5100090C4205DB0C9D2722E0CC380FDDDB40290 +:10B52000E133B647382E01BDCB6BD5426B74EBF2DD +:10B5300072215FCA77FDF65BF41B96EFBAF124CA5D +:10B54000FB72839FBF489C7718FDFC7FEDAE3F47A1 +:10B5500006FC50DC800FE0EA41ECC2FDC4D5DB1EE6 +:10B56000CF6944FB61D3BB514A56D0DF2FCF419AFC +:10B570006B673D83FED3F6D6E537C2DF1BA41B976E +:10B580005FAEBD0A0F9AABE369A925103508F77BBA +:10B590001B2C64FF96BEF0EC962791CF8ED948BF46 +:10B5A00097BCF0C6A7D7A1FDBCD3123F9A4FC3A149 +:10B5B00084C4D994BBB83F4ED2A7F8E537ACAE6C83 +:10B5C000FE7D716C904E253B0F5831DEC788CF1140 +:10B5D000B507AC0D8E36E855DB388AFC50DB7EB003 +:10B5E000E2FA38BD5F619D525AB72FDAF04614DA9D +:10B5F000678827D44F926E2D7434D487FEC7BED689 +:10B600008FEA39719F72393A7E2AECACB2572259CF +:10B610000CC051F4B9CD3F1AE9BB635114CEE7A475 +:10B62000B982F3FDFAE51DD1DE2BB2F83A3A29E5ED +:10B63000DF8B9EBE9BF8719E52D1D19945FC9E68CE +:10B64000225BC29788F39CB36E12CD732ED3881FF2 +:10B650008BD6AB5E3FA4DF9B59C1CE36D6CD52B15F +:10B660006E4E6E04E2C23C4F8A782BDF47AAD84761 +:10B67000DF49FAFC6E3167C61652FE7B61CF4DEC96 +:10B68000D1729E6D0FDD87966FBAAF1EE974A6ABBF +:10B69000A713C20978F009BC293F43BFEA87233BBF +:10B6A000713A3117C623503BD0AB23F03BD6AFB72E +:10B6B00078D0CF1ED24EEC13F9F87789F101EE70F5 +:10B6C000DC079FECD8763CD7CE16B9C0EA43E3B985 +:10B6D000DA95039BEE27FEFAEE132E6716F8C715D0 +:10B6E0005079BD25D009CBFD07262A24276C2CD004 +:10B6F000D63ADF6411EB5C5F0E709A9550FCEEE772 +:10B70000F6A9E497B960970542EC8420FF5883DFDF +:10B7100069FEBF13F86EA0F33979AE374FC807E35F +:10B72000FC8DF262718FB6E34ED8BAB6CF938272B7 +:10B73000C247E396827E477BA4F4988DEC88D217AB +:10B740002C5EC4D3D9ED873EBD0DF7B7B5725DEB66 +:10B75000E5B0715D17BDD4BFCD757D76556EDBEB61 +:10B760001ABEB7B9AE572924EFFEBB7218341FF9C1 +:10B77000252EB77EE7B523879F33E0F57B96153DF1 +:10B78000080B9D85DD884E06FC4ABC1AE5EA1014BC +:10B79000921D5ACB5586211A21F8947894FCCA98A8 +:10B7A00046E3B4F0B5E45BC9D72D7C6B9CB71E9F14 +:10B7B000C6F2F9487B80C7FBAA85EC85D23A1E6F9A +:10B7C00008ED283EAE1CFDF354BBE6CDA4F8D0BC7A +:10B7D000DF90AF35D4F718F25E437DCD90AFD0D572 +:10B7E0002FDD7BC8CAF70F015D3D5BE5CDB41F6956 +:10B7F0006D67F8F9B9D3AE6FAD3EE48F2E4D569418 +:10B800009396A5CC1709ED9BF6A964F75C703545B6 +:10B81000A1DDB23C8CDB75179C221FC3F34D1DAC20 +:10B820002B504ECAEF4D61DC0F73C1DB141513B200 +:10B830009F6FAC53A3D0FFDBE067056DC7AB54131C +:10B840005E1B587BE5DCBEBB10CEFD0D17C2B9BF39 +:10B8500061A4EA48AE443F6C0D8F0B9CBD6472142A +:10B86000C555D4A5DD3205BECF795BE561E03E8FDD +:10B8700019E319667152B253CC47F181B3EA785C8F +:10B88000C3EC557A3ACF756CA2F8B7EFD9624AE7A4 +:10B89000AED1C72314B355C46745EB0CDFEB6EA6DE +:10B8A00075526C58279AF00F1BD789235DC43DE66B +:10B8B000B25C5DDCA390E723D5AC5BA6003D2E1CFB +:10B8C00051990DF2CD752A5BD18FC7B9E2F9136E8C +:10B8D0004870FD2D80F58A7693C4D7395C473DDBEF +:10B8E000B75FCEEDFEF3805F21DFECF92207CF8555 +:10B8F000CFED3996FE3AE65FF963F217AC75FD11AC +:10B90000FB7F9C8E72FAC27E1B437EBFB0FFAD648C +:10B91000F4475E78CD46FBEC0B4B6DDCCFBD3FD2E0 +:10B920008F2AE642576E1757EFFB21A781F4F232B8 +:10B93000A2DF35E9566E5FD5FDFD38FAD39BEB608B +:10B940005628F7F747D07A2A7F2D8CFCCC17F6FDC6 +:10B950003020D43FF7DF9D8F3C4FBF10C9A6BC8479 +:10B960007C1CC3F705E5AF5FFB2C9E2F97ED3A607B +:10B970009D05E523FEEB1F3928572FBCC4EDA96FA9 +:10B980002C0D4FA38F73F896A8472C89E8E783CE38 +:10B990003A33F6C596B1137C596DE185E3E102E0D7 +:10B9A00001E7057829427DD01E3EA6223E3AFC27BB +:10B9B000E2E3DBE95CBE5DC3F03C3A8817C5C3BF78 +:10B9C00047FAED0ACD9F7FDFFF430ECA9FCBCDF72D +:10B9D0009EFFCFE6FBE87FEC7C39BF774D77119C6B +:10B9E00046BE6FCDD7AFFC82F23B22DD04EF15AE31 +:10B9F000F7DDFFB1EBFD7F86DE1FFFC7CEF772F4E8 +:10BA00007E5BD03BD289E79917F6FD23995DC5BCD3 +:10BA10009BFF97CE5BDAF1C355F7915CA8FF2EAB85 +:10BA2000FDC49D42D6489B7648B7609C1FED9F465B +:10BA300030AEA747D84BC8FE1CD1E541B297AB59F1 +:10BA40001E9D5FF8BAA874AE4341208087B712727A +:10BA5000E95E153307BA2C82FCF0A4328AFF32EE7D +:10BA60002B47848F2940FBF4D012800BFA391469DC +:10BA700072E219757E177E4F09D2464CDF4CBE9993 +:10BA8000E2F8F31DFAFDD5CD867DD28D2E7D7901AC +:10BA90007B291ECFED0AB22C745F6214D60FD957E2 +:10BAA000FE23DD4978B991D52C733AAE1E4FB70805 +:10BAB0003CB5C6C3BFC65B2B3C897DB459D437E2C5 +:10BAC000CDEC78A01EDB9919EC8BF97C693F2DF742 +:10BAD000C597C32713FB6DB3185AE2D7DC859FCFF8 +:10BAE00086F44B789178BF5A7C4B3A19F12EF12BA2 +:10BAF000F166A4432AC6F8F50FE2BF8B39D78CEB69 +:10BB00006E88B0EBF3CD313CDFA55EF5D27AF473ED +:10BB10003EFFCE6D46BB7E982386E2428DF71166CE +:10BB20000E8C19A0C07C93CCCC67837D289EBD91E0 +:10BB3000DFF57EB37F690A8EC3FDBB5DCDDC7F0D73 +:10BB4000ABDB179E47F53D56C8173E328F79A07E76 +:10BB50006112732BBC3E8B8EA5F038A6C6F27B9B80 +:10BB6000D8AE309AF75BD889F997727A125DD0ED2A +:10BB700083FE0DE8D7638AE5EDA3F2A8BDCFC4DB51 +:10BB80007BCC90764BE3710A4DCBB95FBEF0BEAE75 +:10BB9000E9283F460FD7FB99DFEAC9FDD232ED9B7A +:10BBA000E1227CA9267702DD8F589649FB2335DCFC +:10BBB0005BB61BFDF43B789C4EE18A3BC6F447F82C +:10BBC00076C4B911BC3363770EE0F5A7DEFD07F844 +:10BBD000AE6D0DA3EF9333B4A53D311E40714DDF23 +:10BBE0000D1F664E3A644D8021B4DA71E7D14F38AB +:10BBF000D6B7F37D3C9F1C3B51A5FA63198FF764C0 +:10BC0000CB601C281FE3FBD69C00FD8D814D079661 +:10BC100037863993EF04F80B857FF8215C2F086F86 +:10BC200038D35E72205C5DD353E1FB18D676BCF14D +:10BC300051597FB8B20ECF99BA8DE0FE7B591FFBE8 +:10BC4000C17E3FEAC9FD514F8854E601AF547FF6EB +:10BC50004A5B631AEE7F565A023D2175F41ABEBE46 +:10BC600027E06F742A1BB516F17EAFCA3612BC4DA1 +:10BC70008574AE1099E1423A68C0D274BE5293E224 +:10BC800042BF58E3B0DA009E27343E91E2AE76110F +:10BC900095291E48EEB71A8705BAA31FBF29979F9B +:10BCA0004B1C773644E27E7196C3CEEF498AB8A228 +:10BCB00039E25E4CB7EA8607AFC17DE8A32A9DD77B +:10BCC000CC7994DFF7FA8BC3EE5770DFB646DCD73A +:10BCD0005CA58F23624E37F98166D50CB3E27E7383 +:10BCE000B6C363C579FE31437B1DE725EF17F642E6 +:10BCF00022409785358514AFA246C1BAC3756276D6 +:10BD000045E13ED81887542EE28E64FEA170ED30D6 +:10BD1000F2C3CC68D70EE4972F2BD3C83FAA0ABE34 +:10BD20001B8D7195789E616E484478EEEEE922BED7 +:10BD30001C1DEB4C77103F8731C443A3C5998EFC83 +:10BD4000DDB83CCC84E772A39772BE867566374334 +:10BD5000FBFBCD2C1CCF197E27DA4F5B62F66E8081 +:10BD60007C173B3347C6225FE5125FDFD24B7B0275 +:10BD7000E777EAD76C20F2C3AC55ABE93C46F20555 +:10BD800033D7E7C7C138A736A7E4A1DC6C91D3BD90 +:10BD9000867F81ED5AF861A2427C00E98134E28716 +:10BDA000F10D38CFD1C303DD1766E17EB49479502D +:10BDB000BF273037DA09CDAC89CE2B9B1D5617FA39 +:10BDC000BFA43C917203E8EAC17BB7920FB680BE74 +:10BDD000375B18DB5A65A7F4F92A2733F7606C7BC9 +:10BDE0005502E57754B928ADADCAA0EF2F55B92952 +:10BDF000BFAB6A20E5F7547928BFB7AA80D2D7AA8B +:10BE0000BCF45DCA25C00BC9212957A43C9AE5B0F2 +:10BE1000D27D5F29978C7C331DD03B348FDA93DC45 +:10BE200093F20EE761CA0BCA2349DF54C5EB4B48B6 +:10BE30004139D63015E93F523DF7C22BB82F2F724A +:10BE4000B8699FCEB8DC6B067E45BC245BD95EF436 +:10BE5000CB56DFE969BC2F2588FFDB8B14660EE12A +:10BE6000AB3B2AC29839446FCCA88CD1E5A7557E4C +:10BE7000FC4627E8FF9E0E5A7C06C071FC375FAF78 +:10BE8000FF237C7FE637677A20BD018ECD8FE3B834 +:10BE90008BC35BE088C5FC320B9D737513FE936EFC +:10BEA000C27F82FF903EF27EF333BFF91BADF3C633 +:10BEB0004A9B0BEDE2CF915E80DF3F097ACDACB4B7 +:10BEC000111E0B977FF5C22BB8DE175B49DECD5CE8 +:10BED00026D6A3E15EF397898CFC126055B34AC065 +:10BEE000DF97BFB60622A0FF2F15BE8E15300EA617 +:10BEF00061FCE1CAB73E4339A0541EA1F3770DEFB0 +:10BF0000E1217C3ECB39DD3DE9CA37A91E6BE81241 +:10BF1000837E1379CF38A29FC7EA82F9236F23FD6E +:10BF200066661C648978CE52A338D185385B7C9FC5 +:10BF3000BD92BFDB80713C13C1FE1B92A1123D2B51 +:10BF40007B9A29FD14F52DF9936B484F49BE9DBD91 +:10BF50000ADAE1FAA8C9B5CE0D91C733C5F7591968 +:10BF6000264AE5F731D82F9EFFADCC9D82764567F6 +:10BF70002CCFC2346F0AE2B7B363945909E1831B33 +:10BF800032CC020E46ED3EC54507E90319A9D63964 +:10BF90005974BF8FF4981C676646DE0A8C2F9DB9D2 +:10BFA0006A184A61566D7127C4433D6F4B3FDC7E72 +:10BFB00063761E475DDA8E1E917EB553F8E7B53481 +:10BFC0006FF2FB16EFF8FD8ED7A0E7E22F6C44DF8F +:10BFD000E23E226E2BCB3F60023920F5FEECFCDF07 +:10BFE000FF398ACE2976F1F84E48B99F757111F75D +:10BFF000CBBA617DB5715E7478C717516DFAB177B0 +:10C00000A957E4C72E577E8A423B42CE67E4BEEF73 +:10C010003B121CCA253A272ADFB7BC635B715E4618 +:10C020003F768BBF5BF8F5CA1717B4E9EF36FAEF26 +:10C03000966518CE0FCC8CEE8D49FF1D53B3A2F13F +:10C040001CE07B719FA4BD7D8EF47F97AF854EE28F +:10C0500060BD9A5DD178BE75A11DFBFA6806D7FF59 +:10C06000E785BFFCC27695F63D17B647D2BA5AB0FF +:10C07000FD9137F1DC71C12685C02863F5843FC08E +:10C080002BB387EA358C638B6B0D77B3BF4734EAEC +:10C090009592DF475620BFCDAF553C9B019E66BBB6 +:10C0A0002BBA43083C5B91DF807F4A6CB50308DF05 +:10C0B00002FEA7514EF60FD69B5FF708F997A1DE57 +:10C0C000376417BD1881B10288F7F711CEB3EBFAC8 +:10C0D000BAF1BC707EEDCE0564576C8F70A25FE143 +:10C0E0008C885B96FDEC12FCBD2B83DB3167C5F9B8 +:10C0F000D1D91DFC5E3FC289EBEC8CC2FDD0B2DD14 +:10C100006B02CED732F8BEE48E0CBECE65FDF9B51B +:10C110008D51DDA1FEC9BD1F537A58D49FEFA8CF22 +:10C12000417D7C7257049D7F9DDCF5D4A8D761BC0E +:10C13000F3B5C3E2715DC8FE3FCAB050FDF3EBD466 +:10C1400002C417F3F3B89932C46FDF5038E336F8FE +:10C150005242D71F8F1F3ABBEBE5285356909E657E +:10C16000F60A7BA209D7D19D5EE4EF68641E80D7F2 +:10C17000BA6B9C0F7558795D2E43BEA6F59748F5AE +:10C18000579A42EAD92C6E8A33B5EC2DF48837548D +:10C19000F83D2711C73F52CDA273C5E97D5C936F6F +:10C1A0004739F9AE85E8B130D33519E5D3C57A956D +:10C1B000219C0B535800ED9345F7466E403D26E118 +:10C1C0009EDE97CB83D2950AF3C0FC4AFD2AD3208A +:10C1D000ED0CF4F7213F2534F4C738C9C6146E5767 +:10C1E000C8F8D1278B4C1E2BE8C19F3262E5FB0FAC +:10C1F0004FCCC1F3B3F119B49F3B6E653E15FD4AB8 +:10C200002FF1F8D2D2541ED7FCA488872F8D0DA40D +:10C21000C7417FE7047D4BC707D231EEA2F4A544A6 +:10C220008ABB3867E5E79EF81DCF594BF3A0BD8365 +:10C23000DECDD064FB98107E2A9DE976613D35D62F +:10C24000EDCA7520BCCE6FC8CEDD1DC9D0CE35BDC0 +:10C2500012C9E3A69E0BDB680BA19B3393F39F7C73 +:10C260008F83DDC6E38C1EB3F0B8D4C73627FAFD42 +:10C2700021F87ACCA24D453CE03CD0BE9F6FAD4941 +:10C2800047FB57C23B3FAA86E03C27F87D7E780DEE +:10C290008FE716F77BB13EE61B451C7AD3361BC5EC +:10C2A000019D49ACDF83E39FD996892FF200FCFE04 +:10C2B000B97BA91CEC4BA067F1F3B600CEE7F436CE +:10C2C000EE8F3E6DE1F6DAE971092EA46FC1F8B583 +:10C2D000D3C95FB3C9A6A09FEFB4C2AC0958BEB919 +:10C2E00003C59F17575552FC7631880DBC3F046932 +:10C2F00001DE033ABD3993E2CD4EE33B0C0A7D5F8C +:10C3000089DF355633FD97888FAD7C7F75E6F9BFA1 +:10C310006786C67BCBB478933EBE4EF2892CCFCDD8 +:10C32000E4F22D57E0B97F267F2FA42CA2F6B1545A +:10C330009A27C73BD089BF5BC31A229FEA87F114B3 +:10C340003D1494234FB240FA53E877D8CAF75F6799 +:10C35000B65B286EBDF895480FC5B1DD778D89E2D3 +:10C3600029546EA7179B007D902ABFD94AF165F129 +:10C37000CF87E5D9C83E67B4CF6DDAAC8A71C026E5 +:10C38000C6796FE171C7A3D196A4F26C2A3F2DF252 +:10C39000A7F76493DD07FD7BF07E55F12F7FC5F194 +:10C3A00038A1E828B7BBEC246F4B5BCE790647A3D6 +:10C3B0001E2CBB6F5034DE3F641FA80CED16239E6D +:10C3C0002E9ADD9D50CE2ECB147277CF7A3A9F2ACB +:10C3D00011F7084A9E57F83934AC43BC9F59B262F2 +:10C3E000D0E3C49FEF5B580F98CFB9DA47A242E978 +:10C3F000B12093CBD396FA5637D52F81FAD84FC9AF +:10C400008A77A3089E2D168A5731D2F18ADB3FAF77 +:10C410005E51FB16FEA8E57E9656F367F5BFF8025F +:10C42000FAFF6E7B98DB475F6BE91EDC594BED5CD6 +:10C430009CFFD917C2486E9D8DE1F2E124C8535F7D +:10C440004F84E3E68729BEEBA309747F6F9E5FDF0D +:10C45000AF1C77512697E36571EE688C172CFB8033 +:10C46000CB41A0CB2DD4FE030BB537CE63BC68D730 +:10C47000B23E5F88207E38DB99D3E5EC8E9EA49F88 +:10C480001A63389F03BCC978DFEFEC0B3D73E91EDC +:10C490001D1A3DC00FC562FF7B36A636D91952DE84 +:10C4A0006811FBB800D444BEC13620DF8B2BB9BD68 +:10C4B00055625F45F12518AF3B208FD2802DB675B0 +:10C4C000DC2DF02BED2FDFC9147E4C1CAFA388139D +:10C4D000273BA8D68A725B13F662E97663DC2E2FBF +:10C4E000DF26DB03B4F1324E18F9D0A7509C4AC9BD +:10C4F000B23BE753FC7DC5EADB719D49F84BCCAC00 +:10C5000000F7698D8A4A703486B119E3D1AE0C1DEB +:10C5100027C49EDB151C87E1FB5FA5F807ACD9BDDE +:10C52000992EFA8EF91AE8AF7499B28AC64991FB2E +:10C530005D3E2F8927408715E3041B8789F276E645 +:10C540002DE134CEBBC5EECAE4FEA5C614D7C38325 +:10C5500091CEEFA9749FF7E24F7DA363DBB0D38246 +:10C560007ADE1A8C9705F88F6532EA677D26B7D395 +:10C570004B301E17E04C5FA78F17CFD8A4CFF7DA48 +:10C58000AECF67EDD2E773EAF479F7617DFE8018EC +:10C5900017F7E1787F18F7E198E23EDC65E3FB707E +:10C5A000CCE33E1C53DC87E377DC87631EF7E1981E +:10C5B000C77D38E625BE713F8E79DC8F6379782F91 +:10C5C0008EA752116F8974407E67AF86E9EE235DB6 +:10C5D000D8C7EF97001FF07533D54AEBE649AC4159 +:10C5E000FB11EE77EA3CC1EEC2F8E15571DA7799BA +:10C5F000FDF11E4AFD8A44A49BB981E258CB5FE35A +:10C6000071ACA579610EF47F342C3FB902C343B5F8 +:10C6100038ED47AC7FC1D2B405F15B567988EEDFC7 +:10C62000372C717D703DA71FF96158512CD9518568 +:10C63000A8E762DBA7A3319E9CADD2C78F1BE3C9DD +:10C640008D71E4463E90F6DF3396A64494EB5F6D21 +:10C65000B3AF42F8BF0A13F761A6D80DF1000E92EE +:10C66000270B1F5436A2BEEEDC8BDB51CD47C05EDC +:10C670006F43CFCA74D6A5BE6497B7E45729268AFC +:10C680004FD73CA4871609989295A6C6FB50CECDED +:10C690003791DEBC08F61AD9839FA8643FE03B5966 +:10C6A000A1F3C177B242F90BDFC9D2DF97E8ACAB97 +:10C6B0008FEF64E9EF4BF4D2C7E74F5C7200F7FDF0 +:10C6C0001356F5D5D59BED1D64C0A3805BD8B3B3DD +:10C6D000417F78D0BE5CBC3619E9BB687E73E37DD0 +:10C6E00040DF45BBC3DC585E84FF0772B108FAC463 +:10C6F0007B9745BBC4FDE54ABD1E9E25F45091992C +:10C70000F99CB1413E2C72324F0CB49FDFAB3E0717 +:10C71000DFC39AFFF6C7039CA9B8CF18D609E55125 +:10C72000B2C54371B5A53B7BC42C817E7BF7D06E2F +:10C73000EC05EBFA44CDA187A6A13EDCC9F77F5FEB +:10C74000AD7A398AE2CB04BF255B9CE148F70D3511 +:10C750003CBE0EFD676A6C902F36D4C48577770493 +:10C76000E71BE4839F884E401FEEE7293A48E72203 +:10C77000CDB562BEC3141FDAD9727EF21D2DB68C00 +:10C78000F77397C89F10FB0D39CF739907725C78C8 +:10C79000AFA36A6FB28AF2DCB47D0BEE43FE69D3BD +:10C7A00066F7EA8FF1A03DFE88EFAA15FF81CFE77B +:10C7B0002F6B46445D8BF6E70B16F768C8DF57F31F +:10C7C000AC15F715C566BF95E233B76DB062BCF224 +:10C7D0000D5B37D0F7B95B0B291E731EABA0FDE8CC +:10C7E00029F9EE81C047D170659D13E07E47C88F5F +:10C7F000A2707EBE07F6D11BF8EEC8C5AD4A2EC6A4 +:10C80000F94CF4EEB416C2F75F8B7AC675D27C741D +:10C81000C2C80E840F7E0FE40F0C76F769ADD7C542 +:10C82000844B29B42E265EEA4DFBB449814CBE1FD1 +:10C83000CE32EC878FAADC9F57C7D7419135103F86 +:10C8400001D7C97E0BD9B96566FE6E5319FC7D1DF3 +:10C85000A4DEC1AA8E5FCBF32374FC3C85C5EAEE4F +:10C86000D3DC8A412521F989A3D374F5274FEC6DD8 +:10C87000E0FFBC6039C991EB74F7FECA16FB5CF4AB +:10C88000BE211BAEFFCE787C21BD086A0FFD3E3E67 +:10C89000580FF97B93C2F73DBB6236A21FB0C8C4E4 +:10C8A000F74F5334FE7DC15EFE9D4D61BA75D82DA4 +:10C8B000CDFD47AE172D746E20FDED53F0EF36F031 +:10C8C0000F9AA2E51E3BDEE347FF84EE7EB7382FCA +:10C8D00044B8910E65C29F5496C1FD4965BE7A2B3E +:10C8E000BE9300F837C7C5523D7B1CC655D628E419 +:10C8F0006FC47431C559EAE3B4B03F8C7F5C7044B7 +:10C900002DC475622C2FC2778790BEAFF1B8D405C5 +:10C91000E8178A6AFDDED902F413A17FCBF0BE9935 +:10C92000A3B74BF811FD2B3A231E472BB9746F7335 +:10C93000FB012BC6E74D9C18938BEBC7C86752BE13 +:10C94000C3BAA6B8C2E6A38788CF9A8BCCC4C797D0 +:10C95000C3C7020FF7B31AF96F2EABB7E2FD94B954 +:10C96000BB1437EE4BB11EE2A533F2A5012F71B116 +:10C97000ADF121F1D4823743F93CC6F1356FAFE216 +:10C9800047F9D80A4F027F46F8DBC39F9CD75C4D1E +:10C990001B857242CE6F1ECE03C78179E038F2DC70 +:10C9A000820D34AED734F25F2DF0F2385B237F8CEA +:10C9B000BFC4FD32B75E32533A71B47E7D623B5CD8 +:10C9C00027932E75A4F2ABE59F050027EA85ABE51A +:10C9D0001B391F298F83EB84DF4BB8DCBB4546FF37 +:10C9E00064426FE19FECCFFAEBE29B85BC35B63732 +:10C9F000C6374BFBC0A8770A234D146FD9EC4825E6 +:10CA0000BB43CA5F4DE8156DF9F7544F837A1C1A82 +:10CA10008F4E0F69C24FB8303295DE91485E12D703 +:10CA200011E95518E6A4B8FEC2252AC55117423DA2 +:10CA30005788DDB262595A32EA912FEFEFF9B40FFD +:10CA4000ECF92FEF8DEF3810C6F96AB925DEEE0A42 +:10CA5000D6FB72F9C8648CEFF86AB56D8ABF0D7C9D +:10CA60000DEFCDFD0A65BFF98CF4DC79D3D1A8298F +:10CA7000D0BE74F9EE28BC3E50B29CEBF7F7BA6B0F +:10CA8000C37AD3B9EF862DF49EB173430EFA89BDF4 +:10CA90001CA72D7645F1F2919DD0EE28FDE7A1A7C8 +:10CAA0009D782F7C89A523DAA5A73F013DA9909EFB +:10CAB000237BE254187441E77091F49ED92985795B +:10CAC000F03CEA9CE9C05FEFC3FD626E6D7A40C145 +:10CAD000C353CDDB1BF7F7CB9F257BA6F88125E958 +:10CAE000F8AEA0B6A447745BFE14996E11FA1CED63 +:10CAF0007A4CD1AEC7F81AB4EB318F763DA668D721 +:10CB0000E3F7F2B57ABB706A4F2EB7A4DFB95B7555 +:10CB1000532E9EFBF986B38C0AD2C30E7A07789106 +:10CB200012EE46F9B4086D28CCFF3982FC0EEC9366 +:10CB30001B757496EF04CB7780873481AD16B24EA7 +:10CB4000AEBF6467A1F77487B1185D7E843D51570D +:10CB50007FA43345577E4342A6AEFC4657AE2E7F98 +:10CB600073C6B5BAFA63DCC374F95B06DEA8AB3FE3 +:10CB7000CE334E979F503055577F92B750573E79DE +:10CB8000CA7C5DF954ED4E5DFEF6A27B75F5EFA80B +:10CB900058A22B97EF22D7E17ECC86EFBFD82995FC +:10CBA000EF23DFA3327A5F6DF00813F733DAB83E74 +:10CBB0005AF45E0F47281F3C29F8F95296E751E4D2 +:10CBC00057F9BEA57CB7722BEAA3FE788E1950F8F0 +:10CBD0007EB83E11F9D858CF583E38E2E04517D01C +:10CBE0003266FBA94966901783AF39D8370DF253E7 +:10CBF000B7E7DC4AF941075F4E857C61D6DDB79A1D +:10CC0000415E0DEE73F022969FDDDE97974F6064D4 +:10CC10009A94657D3209E365075F9FBACACDFD2806 +:10CC20006DDE779729E203EF89233E300D001F6305 +:10CC30007A10F818D3C3C0C7B32D8CBD097C8CE91A +:10CC400011D89FE2F777607F8AE951D89F62FA3E58 +:10CC5000EC4B31AD877D29A61F554DA1F4932A8D4C +:10CC6000DA7D5A5544E9675515F4FDF3AA4A4AFF9F +:10CC700054E5A3EF877B4BFF4340F77E687BEF844F +:10CC8000CA734E79AE595DC11A22506E349863BE94 +:10CC9000B607CF2BDBF71398D9D721F65AB6E2F9AE +:10CCA000A0378DDFC54971E2E2FB1D29DA2748E78D +:10CCB0003FA44CE8D157453D56F10686DAFCC1D475 +:10CCC000F67B905B7B733BF9DD2CCF31EC6F889D5D +:10CCD000DF4F1E62E7F78F8798EBAB91BFAA7F64A7 +:10CCE0002E8CFF3910C9DFFDA8BEDFEC473FA872CC +:10CCF00089AFF3A1F18CF2D53F36D07DE5214E7797 +:10CD000002EA2B996F39F7C77F21713EF21C5EC68C +:10CD1000F7E45FAA1F81F6C25087D5857224346E6E +:10CD200000CFDB0F447E2DE161389E3CDFDFF42332 +:10CD30000B987282E7F843ECF529E837187A97DD0B +:10CD40001D1AB724CFEB954B0D2AFA55657C921C22 +:10CD500047C21B6986FEF282F147439CB5B978DE73 +:10CD6000515DE6A0FE3AC1776B1ED5F3A8D4AE366E +:10CD700017FD72434B1D14072BE3043A8979433D99 +:10CD80009A67FE258DE224868A3809ECC7CECB7DD2 +:10CD9000D8CFD0F84022C6810DADE0EF90AD57F866 +:10CDA000FBF3326E01EB4784AC5B8413FBEDFE3783 +:10CDB0008017ED288F87F03B41EEEB5C222FCF1DD3 +:10CDC000EDC3C9BF3542C89A8F53B4CE59786FC5E9 +:10CDD000E6FC7304ADEFB4AEE8371D27ECFA7FC173 +:10CDE0002FDDB0DD7F9F5F3C9CDEF8807F4A6BBE0D +:10CDF000917491746E8F8F24DD43E2CC88CE2D71B7 +:10CE000063A21F237FB5C757929F86D839DD91AEA5 +:10CE100018A726F948B9C4DF751B5A6A277D27F978 +:10CE2000C8C807ADF988F365F5DD76EAAF351F05AB +:10CE3000E98FF8F8F7F9A841C5F3ABABE59F194DB9 +:10CE40006C5434143D94AA6D45395278C9F526E6E0 +:10CE500067B161A390A564F9E358DEBF75B9F65DCB +:10CE600093253A84CF86083EDBDF4E7FB29E7CF767 +:10CE700042F67FBC9DFAEF0ABBE1DD3019A7E271F3 +:10CE8000E40E08C68D2E1AC9F9AB204525BB6344B4 +:10CE9000167FCF9C39B89DED82FF501EDFC4B4C30E +:10CEA000D129F8EEA897DE1B1D156F786F54D8E7CF +:10CEB000058673FE9BB26E20FBFCA6CBBC5BBD2C33 +:10CEC0004BDCDF49612957F9AEE86FB3687F78A57D +:10CED000EF8AF2F768F3C57A4F12FC94E652D9E074 +:10CEE000587C9F5D33A372398CEFD1E6E0BBAD3E39 +:10CEF000CADFC8FC94DECC0264478C014584F95B30 +:10CF000018A37BFB8722C64EC33B8723FA8EE88E8D +:10CF1000DF43DED9F3237C0B54EDFF3843DED93BEE +:10CF200098EFA2FBAB07ED696487E27AB584F84B12 +:10CF3000DF06FDDC1DE67708F437A66F80FEEE0EF7 +:10CF40007AF42DD0DF98BF296309C376A35CFAB8C1 +:10CF500027D9FE66E708D8A8B58FBF9B735EED8220 +:10CF6000F87D37A6673EF2C5BB31D7E4E37CDF8DA1 +:10CF7000E964E2A9CD4A69F62BDDDBB293E57A08D4 +:10CF80008E378AC633E257E2D3884789DF7F039F13 +:10CF9000EFB485CFADB88FC0FB21F68FA31252F14D +:10CFA0007C93CBD9B28864F1BEE87B396A2AC6FB90 +:10CFB0000E223887565ECBCC78DE6EE7783A59C5BC +:10CFC0007C88DFD3380574781BFC7BCC3CDC141ADE +:10CFD00007FD8A4DFB13C271729D4AF7F5CFBF144E +:10CFE000467EBB537EEE975C68D21AB3D06FAFBA61 +:10CFF00056B9D1DE7C57253F30FBE950F2F8C8AB7B +:10D00000E0D74DFC9D8352FBA836E929F797CFA5C1 +:10D010007A68FD33C3EF4B74B1F1F720E4BB94970A +:10D02000FBDD962E362EAF257DD759851D00FD0CD4 +:10D0300000399BF47038EDB7F674F4FC88F3837D07 +:10D040000CBD3FD5DC2592F4D34111173734D09B6A +:10D05000DE5B2B10BF23F096789FFDA08897FB7BAB +:10D06000BA66CE0678DF721DEC82FE87EB193F07A9 +:10D07000BAD1C1DFC3BFDAFDB9235BECCF7358CEA1 +:10D0800055FDEE410795EE530C65E9740E3F02E144 +:10D090004539F7F62C33EAC990DF3DA079FD6FFBE7 +:10D0A000DD03C69A549C579253614FA65CFDEF2056 +:10D0B000A8625F257F0FA18017B5FA1D84A7A20A79 +:10D0C000785CBE636E9BBF839024DEA9662EAE376C +:10D0D000E4EF208C4CD0EB9111CE61879D94EAFD5A +:10D0E0003C4997891F1B9D2DF4C7D5D2BF8C11FDDC +:10D0F0005BE24CE379FCD350ADD7C3E89F1F116FBF +:10D1000071FB5DADF9E03FED774EDAA393F1F74F98 +:10D110008C7432FE1E4A925A6AA67720059DA6C0DC +:10D120007F48A7EBC5EF55E4E3EF55B0FF7774AB4D +:10D1300036D0ED7BB6AA3FBE5B7AA190CBF5F6F474 +:10D14000FE0D299EFBB341FE3C2AFC47D23F22E361 +:10D15000728DBF9724FD00325ED7379CD3DB773CBE +:10D1600082CEAFEE511B2251CF1C37F1DF471AD8C8 +:10D17000417B1CE5D38CAC0A05F191C0BC3BE702B6 +:10D18000FCD3FFCB968CF9E9DDF87B912C8BFFFE6D +:10D190008F846F7A128FE77A265BE17E3F378FDFCD +:10D1A000DA98CDF701916E27C599176631113FCBFB +:10D1B00092A767237F1E0DEB89FCB786FB031BF04C +:10D1C000BDCAF8E07B9568A7A35DDC55D8A5D5C797 +:10D1D000EC76CE874CA7FF33FD765D9C73EFAD4EAA +:10D1E0005D3EBB364157BFCF5E97AE3C3790A12B1B +:10D1F000EF7BC4ADCBF7AF1FA8AB7FCD671E5DFE45 +:10D20000DA86025DFD41A7BCBA7C126B7A02F17B23 +:10D210002C3B95DF9F50849FC4C5E931FD9E8E74E1 +:10D220005F49EE3F64DCBB26F8D9B8AFE966E57626 +:10D230007D7522E3FB56BBD89F32FDFE461371EB92 +:10D24000D2AE673E7DDCBA8C576FD907897D8EDC04 +:10D250004F84C4AB7B107E19AFDE4277F17EA8917C +:10D260005FBF167437CEA39B95DFAFABBED74AF72F +:10D2700084247C46B8D40CCEDF9BED6DBF07F55DF2 +:10D2800036B713F2BB7BCF21BF3E0DE28AF0D96ADD +:10D290003C7703FE9E40F5AFADEEA5AECB8F37BD1C +:10D2A0000F9FCF347C37378BDE5FA57B81725C7339 +:10D2B0000E1FF75C1FC1E786F1A647F3F838166D1D +:10D2C000A57B2DED8FC7F19A6065CBE8DD2A71CF84 +:10D2D000E38E55B50FA20B759AB5C6C21F1EF05B43 +:10D2E000D08F367A38D889B9E85F7DF85107D86988 +:10D2F0004F579AC92F1691639FECEB1EBCB7D30D05 +:10D30000F669C827A391FED0EF923E3C3E3D0B6DDF +:10D310009F0EE47F6FB96F61D3C97F46F2BF0DBE28 +:10D32000237E94F3F89FBA7F21F9D78827B92F6716 +:10D3300042AF75177049FCC97521F127EFBFB8EEF0 +:10D34000B478373AE81E4D01C6E549FAADE9C3FDA8 +:10D350009CD3053EB01ECAA3F6EA8D54B3A2F1BC1D +:10D36000A099B9A29D97F19BFF0FDD4B21FCB777E8 +:10D370009FAE3D39D14A3EB473BFAE3DFEA47F5748 +:10D3800071CF2E444EF07829410F7F7713C525DCED +:10D3900017A95FC70FE570FCE689F504FADB91ABCE +:10D3A00097130CCF3FAA97AB424ECC6DF9FD10FC02 +:10D3B0003E67B985EC6EC6BC8F619CC65FD658E8E7 +:10D3C0009DC7A11E46F6CDCC758A7F8312FCDDAECB +:10D3D000429FE19D16F527B20FBF5FA538F1F71FF9 +:10D3E00066ADD497CF73F0DF1D99637CAF469EC7BF +:10D3F0005D665F5F9523F4BB9BB9C92E137114451D +:10D40000A28ED12E6BF6F3F346DC97ABDC8F45F1A1 +:10D410007752EFBBF0BC2BE41D16C06B7806EAF127 +:10D4200065E636E3225BF0DA4EDCC7398788FB70AD +:10D43000F03897E65D61FC7C589EC389FAE77C175B +:10D44000A91CEB636FE77379FC8A3C7F339EEF3551 +:10D450003B4C743ED5BC2B92E21CF0DC2B1AF8E15D +:10D460008C6967C7812941F8B40655776E644CB55D +:10D4700025BB693FF95E776D5B0EC6E99BDD7637AC +:10D48000E4EF771CA477BC460B3F9811DE96DFF1E2 +:10D490001BCCDFD569F6717BB7B980BF7702F291FB +:10D4A000E17A92F11CE3185877901606AE2578AE13 +:10D4B000F6FC6BC2A55C7EFE7B6910B5D7565E4B51 +:10D4C000F96ECB1EBC13EF194DAA9E67C150808622 +:10D4D00027168F0C87A60D5DFD4BC3916EC3943646 +:10D4E000CF2FDEC9E17AA5C1706F41A6D7F5E17AE9 +:10D4F0007532C6E6F40F89E75AA2D07A58A83019D7 +:10D50000DF45F25CE62FD688FC489E5FB49CE71BA3 +:10D51000C4EF2A6C11FE169C37A6386FF40B6C17FB +:10D52000FE189C37A6386FFC8EF20BF328BF308FA5 +:10D53000F20BF328BF3045F985DF67326F72AECA50 +:10D54000CFEDF243D6079EDBE587D847786E179A72 +:10D55000C773BBD0FA786E175A8EE776A1E5786E5E +:10D56000179AC773BBD0FA786E179A67036F0CE6E9 +:10D5700051DE79C6E9F213C0FECF0F59DF786E177E +:10D58000DA3F9EDBE9FAD3EED4B5BF9D55EADAE384 +:10D59000B95D68FD19958AEE5C6F86788776D6DA74 +:10D5A00038E29F7D295E5B1FA0EFFF89F8E7DD165B +:10D5B000DC2FAA75F3F9BE2DDCCDE95C53C0E96E12 +:10D5C000E2F72C94A6A944E7C5569E1FC9E3BC8D7B +:10D5D000FC83E762F9167E2E86299E8B618AE762BC +:10D5E00098E2B9587E0F7E2E86299E8BE1773C17F4 +:10D5F000C314CFC530C573314CF15C0C533C17C319 +:10D6000014CFC5B01D9E8B618AE762F81DCFC5306F +:10D61000C57331FC7E1CCFE72C41B8D09EEFAEDB4A +:10D6200057021FEAF6954E5D1EEDF9D0FA68CF87D6 +:10D6300096A33D1F5A8EF67C681EEDF9D0FA68CF8E +:10D6400087E647E5B8687DA15D1FDA0EEDFAD07C6C +:10D65000768DEF0DF49D8D59F7CD614C1B2295A76A +:10D66000151019057DFC93F1FCB2214C498E01C9BE +:10D670006959B279723EE435114799C39A4CF4FB6B +:10D680007BB879C4388700A3B8D5EC1F13A97CAA4E +:10D69000BC7F87FF80EEB9BB18FD1E8D3C5F97ED08 +:10D6A000DDCCA9622AEB07F36DD7338E2FEB91FC0B +:10D6B0000C81036F5A63BC4FEE62471EC6CD6E11DC +:10D6C000BF8FBB65298FB736F2D562612F6D31ED03 +:10D6D0003C88F7699A0A15BA779D6E66472C798857 +:10D6E000A78A3CB42366F789117AA9E23AFC1D3176 +:10D6F00009B7F483829CA0FB89839BEA4744433F9C +:10D700009A6F18FD3ECE682BB71FB01DEE2B7BFB2A +:10D7100014CFC610FE5E20EC71CDC7C77FEE99B165 +:10D72000BC5D386FF7DC335184C7B1CB148A3B1B27 +:10D73000BC9D79F01EF43D429EF6DE1E5071BCC2C7 +:10D74000657C3CD96FE1BA64BA175AC81AF2F15E27 +:10D750000BEBA73094DB126F30BFC338BF74582A6D +:10D76000E8C7BED2FB5443FAC58CC4784456C7E818 +:10D770005DD131FD3ED4CD97C83E80FA25BDD6D3CC +:10D78000A7D03BCE637D4B96225B8CF1DDF946073B +:10D79000ACBF89B9535CA48AE8FEB184A79767A798 +:10D7A00009D422CB62F5A63005E9CD0EC585F00F70 +:10D7B000ACFC8948EF5CB785DE551E67765AE89D5C +:10D7C0008E76E2752E3A64BC8EC15E30C4E5542F6D +:10D7D000FE2C19FDCD0B234DE43759B83B82EC06E6 +:10D7E0006DAD42724DDA418522DEEFE2B2373A4C3E +:10D7F00046BCEFB4507F325EA72CCD9F6CC2FB09B4 +:10D800009D37E4C4AA64073C8FF2F0ACEFE55B07F8 +:10D8100062BDE5FC5DD18BCB76F3DF1915E73BF2FA +:10D82000774B678BF8AFC26C6F34C6C3C8DF4793C2 +:10D83000F764E4EF924A3F4FE17B7DDF44FA16AE96 +:10D8400017EF7EAF2CA4FBEFC6B8AB1261FFCD5F24 +:10D8500066A1B8ADF906FBB044C4655DEEF74A0FAA +:10D86000F531D887F27772441DA676F914FDC2F21D +:10D87000DEE7340B9703D376323AAF9AB664840965 +:10D88000DFAB66BB39FF4C5BC2ED9C69AF7AE8FE4B +:10D89000A6B41B3F10F6CCF84B4984FF8F85FD32B0 +:10D8A00009E35501CFA31BC2441C5B22A5932FF1B2 +:10D8B000F8D5F10E2E0F1AF6F177379A7D366E579E +:10D8C0001D66FCDD38037F8E33FB4D78A1D13D18FA +:10D8D000F813F263D01E82FEA6A07D1487FC9E3250 +:10D8E00092E2210B14BA4764E4F7D1968A3730DE0E +:10D8F00076F466E6F6B1507E073EC6FE7C0ABDC7EA +:10D90000A0897DAEE46323DF4F8F10FE2907F73F28 +:10D91000B5F829D056C547D47D7F9B8CF1C4D3D1AF +:10D9200067D899A6E1C1B8BDC82C5EFE8F17FF3637 +:10D9300079196E7ADAF15BA8BFB4123E34F9EE447D +:10D940003B7E04F41FA0BCBCE3AE5CEBCC1079F9C9 +:10D950007F018165E5A90080000000001F8B0800A1 +:10D9600000000000000BED7D0B7854D5B5F03E7340 +:10D9700066269364122621901048980422A906383E +:10D980007941401E87C82358B40349143009C33B6A +:10D99000A878236A0DBDB499908001C11B340AA2F6 +:10D9A000E880CAA5966AB4DE0A4ABD838855EB03AF +:10D9B0008354EF6F1B86A7A0B546B8D6F67E5EFDF2 +:10D9C000D75A7BEFCC9C9399006AFFFF7EF76BF8E8 +:10D9D00074679FB39F6BAFF75AFBE4ADFCD28CFC2E +:10D9E0007E0C7F2CAC3F630B5CF43B9BA2E6A50650 +:10D9F000F3185BB12E27953919FB067F26F62C17F5 +:10DA0000FEF54AE6EECB584D9FE01D8AC6D8208D24 +:10DA1000E993D3189B83838CA5A1022C97B1B9A25B +:10DA20003E5D1BF2410B8C5713CFEB69ED8ED93E57 +:10DA3000A82F7704A7AAF0E89FF2EACA065818EBC5 +:10DA4000A3BA198375C5D8BCFAC02CC66C7BF20387 +:10DA500003E1919AEBA2E7CC1A1CE04960AC7A434F +:10DA6000FBC6616E1C17FE57CC5895BDD5C67020FD +:10DA7000E6B77986C3FAF298EE77627BF8AF88B1A1 +:10DA8000E3EB9E7F6ABD125AFF711B9BDD1E617F17 +:10DA900093340BCDB3B38131F730C6763538A87CDB +:10DAA000B2C1C5DC318CED6E48A3FA530D6E2ADB92 +:10DAB0001B72E9F9B30D1AD59F6B28A1FAAF1B743D +:10DAC000AAEF6928A3F285060F3DDF3FD05BA0C116 +:10DAD0007A1FB0E8C7EE82FDA5ABAD8C0D8135B6DF +:10DAE0006E66780E8B700B6E829FEE18C598971F2E +:10DAF0000B1B6CD7ED2C85B1A6758A6B35F4F33A08 +:10DB0000EDC79444285B9440CC0868E09BA207735F +:10DB100079DB6FB2115E1C8E2CB7EBC127A05F4D75 +:10DB2000839DAD87478F5EC6741CE7D19FD8FDBE2D +:10DB30002C84DBA1838EAC101C3FACBFD7061881B0 +:10DB4000C797E3867673EB62B5F5F0FEAD7C4F19AF +:10DB5000AE3B3E4FB37B016E19F98CC6BFAE9FE75B +:10DB6000871A94CB37EC7FE47D3CC77D59762FE054 +:10DB7000CFFC3DF96BD3DCD8CFEBC17EF39D2EBB40 +:10DB800007FADDD29C6477231EA4B2BAF63C9CA7A8 +:10DB90002B73564208FEB59A42EBC82AE0E37F8613 +:10DBA000E744ED5A6D330DED2CD40EE0A63BFA8719 +:10DBB000E09461653E4B01C2CBCB7484D700A621B3 +:10DBC000BC06C2F39802FE3E3639043F33DCEC005B +:10DBD000770BBC1F08A5BD2004C70C78AFC2735BD0 +:10DBE000EEF1392C1BE1C6E67922E0CF83B87E84C2 +:10DBF000FB6C07D1D562073F4FA0ABA9A980872B4B +:10DC000036292E4003B6C8E9BE7E0CD417BD666324 +:10DC1000ABA13E23D96D1F00F52E38DF1D505F707C +:10DC20007BBEDD0DFBAEC2B380752CDA3286E86DAB +:10DC3000911FCAC2E87479C3A603197B117F02BA87 +:10DC40001DE964914BB727E785D16DAB427461AE96 +:10DC5000AFD3545A77156393117ED5B767D9173868 +:10DC6000B1FE9A6D451EEE8BC341F68376016C378B +:10DC7000239BBD8AF4D505FBDA91C5E72B081B7FF2 +:10DC8000018E1F363FB49FE781FA7D5A028D37DF40 +:10DC900005FBCEC2D245EB0438109CBA36C2786E72 +:10DCA0009A87CE6361C06FD3703D569817EA735D53 +:10DCB0007E1BCEB3A039DF8E7CCABB81CFE36D491A +:10DCC000B20F87FA7CABCB9E81F08B0358A4D0FABD +:10DCD000FC3BE06816015C929D380F9B37CBD91353 +:10DCE0003EF3C57A17B526D9171B9E6FB2E17900AE +:10DCF0007FD323F18D83E2DC17344FB233EC6FD541 +:10DD0000ED1AAE47C0F7D4ADB1EB591FE8DFB6D975 +:10DD10009605F57F13F87B50C07546762047C17D88 +:10DD2000DF1AABE13AE7B85A697FDDF0BD1FE001C9 +:10DD3000CF17BB3C045FC00B1F03382C6A339E67B0 +:10DD4000683D1CBE8BDAE613BD2DB17AEDAEF075E1 +:10DD50006CD99FA3005CE6007D2B007FE6F2662273 +:10DD6000BE9CBEFFFA4CDA27AC13E19AA0B9A7A675 +:10DD700015119E101E4B7CA929E4F42BE7FBA3662A +:10DD8000A5F9FE28F86774BAD45F4D43BA84F35DF1 +:10DD9000ED8E4E977664DC30AF7D91E26F527AD291 +:10DDA000A9A44F4997924E25FD3E62F304D29410E8 +:10DDB0009FA9E9C3EA9E8D00A78C7C7E0E73C5B92E +:10DDC000025C5F41B8CAF7F67CCE8FAAB28DF48EA2 +:10DDD000E3E1B8E704BFAA2A0DE4DC9A176A2FE74B +:10DDE000AD4AE6FD10EF11DFCE8973C7F62BA8BD53 +:10DDF000E063825F2CECE617BBD7F4477EF18CA280 +:10DE000021BF58B1F140C69D00B715BF8CD7100691 +:10DE10009FDCFCC42D03B251BEF9E9DCE4BA16FF65 +:10DE2000359FF8C412219F170522F38BEB73BD6A4F +:10DE30007E71A8BEE8BE5F5EE6E5FC2680FCE60FCC +:10DE4000BF7CF1C85877489ECAFD2C6879D736DF69 +:10DE5000190E3FBEDFF5B9E7E6E3792D74DADD2A66 +:10DE60003C5AD83C9FF82F4B635A8E123A7F335E50 +:10DE7000CC6F5674EA573FCAAF7E8F7C7AE18699A1 +:10DE80000CE5943C379898B15121F92AD77F593E37 +:10DE9000A7DB1FE4F3FE73057ECFAD9D641F908268 +:10DEA000FB9D5F886AC51CF17CCE22E3F3EE7373A1 +:10DEB00075F3F9B5482FE7DAF9B99DDB6023FE73F6 +:10DEC0006E77829FC1FE3E59F1FCDBD741BB8F1FAD +:10DED000D89E89FA4AF8B9B1427E6E582E8573638E +:10DEE0007D239EDBD8F0735BFA283FB7854FBDF5E5 +:10DEF000C717DCB45FCEEF36C6F8911F2F687F8658 +:10DF0000CE714ECB265B16B4BB3A3F8BCEAB9BFF9C +:10DF1000D7E5BB18C0776ECB761BF289AB251C4CBE +:10DF2000F400A5CEC2E80CE592921CD2C7647BE453 +:10DF30008FCFC03CB7DF1A9BC84686E6B92D9FF34A +:10DF400085857549C938DFC2BAF9F7B01121796002 +:10DF5000DEE789584E2F0B603CA4DB1393B4CC153D +:10DF6000849F968872F74681870F01B863011F0668 +:10DF7000C6B7FF1CE130F09FE234E41F438706FD83 +:10DF8000382FE237AEDB0EFCD301ED86DE1CFC1C25 +:10DF9000D73114300CFB6199904C25EB0FF51DB077 +:10DFA000EC1228B3555EB6E6733D09DE07F03D4B33 +:10DFB0000916E3FE257E9BF1D7CE1E6FC9463E961D +:10DFC000C2B42677085FE538125F253E47DB5FCB9A +:10DFD00045EEEF441687A73D0EF6977C09FB0364D8 +:10DFE0002D490EED4BAE0F7478DD82FAE33F0FDF63 +:10DFF0008EFAF389462DB3CED9DB7EDBA6F48FB043 +:10E000005FF33E25DD2C72709A06BAE98376C7B9B4 +:10E01000D6217D50EE9C5040BE41BF13B7C65A700A +:10E02000FD725FA897B318AE9763897A391BC6F55E +:10E0300072ACA35E8E25EAE5F43C3F99CB23164CE7 +:10E04000403D13F401CE0F029C4E3AEB87D0BEE464 +:10E0500073A91774BA8209C961FCFB649D909B2C5B +:10E06000B811E99BD50F614FC0549DAD27122C7993 +:10E07000889F7C7DB2DFEDB62EE2872CC1EE7E025A +:10E08000482EFEF677A7A4C27C8BDBB2F215E857C8 +:10E090005D5FD8590FEFAB9B5335E41B8B9DEEB5FD +:10E0A000281717FBB234948BF16DF9A7B7C0FBC5E5 +:10E0B000CD5768D8FE76857990BEA49DB08475FF53 +:10E0C000909DB054F0B5A5C82F015E4BEA0F0C75BA +:10E0D00041FF255A6C3ECAF7A55BB89D30C3C25AB2 +:10E0E0001494C34D9EA9C8C7BA1E5434D437D9C39B +:10E0F000C05F1D21FEFA7EAEE7B7C867D857807FA4 +:10E1000030FEE5288355DC57BB8EFB60A08F3CC1F9 +:10E1100070DD1ED2EBA70ABED1D9762CC19DC7E116 +:10E120008DFA3AF3EA16E4BB2B845C1B6CEF3A766B +:10E1300017EA3309166D07E797EFB8719FAFAB2C5D +:10E1400086E48D682FF8E9E09F953890BFAD48C808 +:10E150004E25BD6A8B4AFC51E24FAD58F3E2EDE526 +:10E16000FD116F16C37B94775BF121B0D0B56D576D +:10E17000F547BC5AB469CA033E906399028E27AD35 +:10E18000C199783E67B6A72637A25EB8BCE93206C9 +:10E19000EF176DBF2B13CB33DB636723BF9FEC9A65 +:10E1A000393909F6BBE4E1A47C354C6EFC45D0E37B +:10E1B0008DCBAF4A457BE0E6AF0F3CE2023B6E31D0 +:10E1C000C01AE1FE457BBCDF074D6E6ED893A902F5 +:10E1D0008D7D1DE3FD1CE1799365DF756390FF2B59 +:10E1E000FE9D03A8BD3BD5D58B9D7D1AED50C0E7A4 +:10E1F000E53FFB80C6F9D4F2E6B573A0FFCDCB7F37 +:10E200009588E3DC74FFE1512E78FED650EF7FA3B2 +:10E210003DFFB1B27DA70B05D396ED23506E7F8DE8 +:10E22000765A31E2B5E7BA3908F7D755827BB4F9A7 +:10E230006AF728045F59AFF6F7217DD61B60761781 +:10E24000962E46FAF21995D5A33E20F51AF93CA967 +:10E2500080C3E54C9FD64CC48B653B3767A25C39C5 +:10E260009BC0EB553BAF7F03F994F7F118AEB75B5A +:10E2700019E9C90B7D5CEF66B540AF0342F30F2C83 +:10E2800088A7F1966D2934C843D04BE8F9592B2B58 +:10E29000C3750C6EEACA47FDEB436B60319EEB879A +:10E2A000A0D7A27DFB17C1C73E6C55A7E2731F1014 +:10E2B00012EA231FB6FE2A61A833A4C72514B507A6 +:10E2C00090CF2D7F2EA940E52845F8754BB75FC448 +:10E2D0003975600AE9632EC4D3157B0F4E65BC0EF9 +:10E2E00082303A3C6F147A5877FDB967C8AEBB7973 +:10E2F00037D7276E6E7FE6D57418E7963D429F109C +:10E300007ACA7241CFB73CC7E1B2FCB963F685E186 +:10E31000F6486EF2DA81A0094E78F6F2D9F7BBD151 +:10E32000DE56C8AF52A965CE691C8AA5F4977491D0 +:10E330007EB83EB783ECF2E5CD62BCDC8EB5D9B4D5 +:10E34000DF997DC3F5A1890536EA27FB033CA8DFE9 +:10E3500097B1892390FF0596C7B5A05CD76F715A16 +:10E36000B16C5AEE2439FF709D25D70AF0D5953847 +:10E370000DF5B87A076F7F675CE20E2CF7C5F1FAEE +:10E3800097B19924A7BEB4789E5902EDEE540FC5FB +:10E39000A2FF6300EB3A60817A493FEF7505306F69 +:10E3A0002A03EA51517E04147CFFD96F3E2AC475BA +:10E3B0004C181C3CCF6069B6C6BC3993014F6A0A41 +:10E3C000C43EF3828588EFFD5EE6FC7A9B8DB5A0A6 +:10E3D000BC63560F9B05CF03C8BFF0FCFF66F1235B +:10E3E0003FDEA7041E0BD7BFEE1378EB8971B6286A +:10E3F000B0CEC7B3BC4B711D3F526CC35175616E3B +:10E400003507C7FFCCC6DF4B3DB65430E10C618FFA +:10E41000D9D3D39CB8BF26012F45D7593DAC6375DE +:10E42000DECB0B115FEEEE72B01898BFB42B8EF4FA +:10E43000DA8CF432926F4D022E8A3B05650E7B39E1 +:10E44000CFE28B81F5DECD1C7E6CCF1C26FDD71272 +:10E45000AB633F65DF6FFF86FC7EA0FAF9813ED09B +:10E460007EE09D8AD6046D6ACE9DDEF60E43FBD912 +:10E470009F8FF0BBB39FB7B100F6D779AEEC98177A +:10E48000CEFB6E57BB43CBE3E385EF63DFCABF250B +:10E49000265B42EBFBACEBF42F9F2FC2D24172A85C +:10E4A000749FCAFD4DA6F57C96E6B6D23975390241 +:10E4B000166CEFB4F81505DB1FF800D757EA7006A5 +:10E4C00054D4E31DB63F85CB19762823E9F41524EF +:10E4D0005AD837A02CF46FE2E737A18FD1BEDC59B0 +:10E4E000C0EDA49DE29C247C25DC985B67E172E68C +:10E4F00025E7CE6AEEC7E274FC4FE2F9B9BF669336 +:10E500007E716E1FE81911F44E591E463D03F487C3 +:10E510002FB3F5A7106E52CE564AA92BE4B02AC6E7 +:10E52000AD14F0AA745A387C2A4CF0117863C60BEB +:10E53000F3B9CBF3643F3974B04F169DE3F07F61BC +:10E54000747E7B111F3BFFF6E61A203796AEEAC7B2 +:10E55000BC59FF13CF2F103B0CF58AFB2DA457A0FD +:10E56000DE877AA2E41F5EE40323E939D703731937 +:10E57000F18D1A358EFC8C66BE21F985370ECA11D5 +:10E58000C8375A891FDCA9761DB428213E31B82C22 +:10E59000381CE5702798FEF83E6869A7E7DF146429 +:10E5A000137F18C40E0D203FAB35588C7AA0EA7843 +:10E5B0006CDB4910296DEB387D34D9FC0F2E41FE00 +:10E5C00050E9D450AFFBCC6FF1D9609D6D499C6F81 +:10E5D000B42D4B2779FE19137C64B69DF8C89516A7 +:10E5E0008B8FECAD39E9646F75B7CF71937FF5D739 +:10E5F0005FAB976DC1F7331D2477DB501E43BD6DB4 +:10E60000E3707AFFA2E44BCB385F6A9BA90F88C303 +:10E61000F733FB5B70BEDD29DEBFE1B9A7ABFE9F20 +:10E62000C7A23E79531C7B029EB765E90350DE3ECC +:10E63000A078E62CC6FEC3F9BA8373E29EDAC98FCE +:10E640002780FEA4CEFA841DE17E6FE9471FEC3BD4 +:10E65000F620C2CB57CA72519FEF44FC1C193A2FC7 +:10E66000B0CA597D72E8DC524CE726F1D56783F3D6 +:10E670004BE1E7B75A897E7E29E2FC947AC06FE2CB +:10E68000FFFC7CEE54397F672F696E2CD5FEDED4FB +:10E6900042585FD3AD702E2410837720BCB6AD4CAA +:10E6A000D0711F9D1656DB1E816EB30B85DF09A549 +:10E6B00031D0C33C410FF324DEAE32E16D7050D255 +:10E6C000E97881B7D0FFC578CF509CF753E5F028A3 +:10E6D0007CF8E67FABB323CD33BC90FB0BF68356BF +:10E6E0005A48F2B5D4A0AFBE99FF5106CA29F6D553 +:10E6F000814128775F49F18C2C04FE113BB48BFCDF +:10E70000E69D03BA6CB8CFCE391F67A05E34AFFE6A +:10E71000B7445F17BBCED5F135361C27A922CB16DF +:10E720008432B522EB20E2CF91E931EE98087AC825 +:10E73000FEE9C33250FFEDA81C96817CAF030EF0BA +:10E7400010AECFEA4E40FEC7F654131FAB147CAC9C +:10E75000A362087F2EF866D8F38D45A8D73A2D5AC4 +:10E76000B8BE602ECF02DF0C00DFFC08EC332C4F6C +:10E77000817D1600FDF504D867583F06F6199647C7 +:10E78000C13EC3B2A341A3F74D1543F604E19CBFBC +:10E790006851687CF4DF46D28B6F7C5C6501091F91 +:10E7A000F8AFF6E17816C80DD597B4F535D4176DE6 +:10E7B0001868A82F681E62A84B3DD2BBEA0AC3B8EE +:10E7C000E565858676ABE347D8F05C93CAF239DC21 +:10E7D000CBF209EE1DD74481FB35A309EE87A78F45 +:10E7E000CE40781E46B8A3FD66D512F01C24DC6727 +:10E7F00089390F9715F2E702EEA1E7E5BDCAA94FE7 +:10E8000010DE31087707951F21BC09EE1CDE2710AA +:10E81000DE3108F75C2A8F22BC87E1B800EFA20B3B +:10E82000C3FBE6DDAA010E373E6E8477EDC37D4D56 +:10E83000F01F6880E3A20D430C7509EF05CD467803 +:10E840007B57159ADA31B601E0508EBF001D1C2EA1 +:10E850009E467129AB83F9E281AF2421BDC1FAAD97 +:10E86000150AD78FE0A715E87016FE02F46575F259 +:10E87000F7CD73143FF225D489D0AE00B806E281FB +:10E88000CECA5D979D42BE743D723015ED7A3F95BC +:10E8900037B000D167350B527D1EEBCAB443798B7C +:10E8A0001A588BFEBBB71CDE27919EFF32FDDD4E52 +:10E8B0000589529B3F0CE99C3993C9DE8C764EC08A +:10E8C00029257F62CE51625FF05381FC1FFA75C427 +:10E8D0008FB8E30E3887CFE60747E1FC373BBC8FA4 +:10E8E000A65868BE3D38DFA736EFB0BEF0FCADE2FB +:10E8F000D11948FFCCD3CF6027459B6F136E16E02C +:10E9000030BF0CE0A4601C8EC3E5642587CBFE4DB0 +:10E910003176F4679C5C67237FE5E6F8CC4CC4DB7A +:10E92000936BA66522DE356E1A9689F83EAB65DAE2 +:10E9300059E4DF53D41935144F6DE578CFD8ADA421 +:10E9400077DD21CEEEB89B6901785F393D41F3C197 +:10E950007EBCBEAC445A2FD39DF9D06EA1D8F7C26D +:10E96000D6A533703CB9FF051B620CE7FFA3126309 +:10E97000BD92D943789685E76C0FBDC7F357ABFAC4 +:10E98000787BB1A3EBFFB0FD8D57C2C63B5E98907C +:10E99000827A0B1BCD467FA386FA4783EB970DFE49 +:10E9A000375EC909C155E2D36F0A3D9FE0F9C063E4 +:10E9B0008AB7012D913CB8A5DBAFB52F11E1B7297E +:10E9C000FEA57BAE44B8BCC7FD1C9BE36B887F7C77 +:10E9D000827C3B0BF9F4F519C130BE20FB07053FE3 +:10E9E0003DF2CBEB898F1CA84CA5784CC773DCBFDC +:10E9F0007C54D07D47C5F5D57700FFECD8AD929E0D +:10EA0000D7B1E7FC41F4D374B42B9A00B9257CDC70 +:10EA10008E3DC0CF91DF7A6CF47EFFEE5FD13ABFBE +:10EA20002F7E5EB157F0F32D7CFEC5560FF117E631 +:10EA30009D6DD8DFDF8BAF5F889F1FB1713CED38D4 +:10EA4000A292BF8DF9F443B9FDC3F0B38CE36763C1 +:10EA5000650CE3F295F39959154007A8E733773130 +:10EA6000DA949FEC29EF47F27283ED38EAD32EF85F +:10EA70008772DB0CC74A663D1E0CC3DF9B9F83F683 +:10EA800061EB9B85EFC3F0D98CAF2545467CFD82B9 +:10EA90007D9569CFE6EF0FF50FF13DFC09E72F9269 +:10EAA0006F49FC05BE55837C0DF8CA554580B73FBC +:10EAB0002EC8FA4D5009E32B17C9C736C57F4D72D2 +:10EAC0007073FCD784C7872B051E839E81CF3BAE16 +:10EAD000E1FA06F3CF267A9827F5089B2701FDA4D3 +:10EAE0004756F54DC4F7C79ACB89EE243D99E73BCD +:10EAF0002AF04FB69B67EDB26911E4A17795117FBB +:10EB0000D8AED984EF7798F02CDAF8E6F6729E79D1 +:10EB1000A678AF799EDB8A84DED95E7D51F3211918 +:10EB200076F727FD362E84972AF2812F1382A47F51 +:10EB3000CD36E86547CB46935E76B8E27C44FDEC83 +:10EB400068C5F9B74623BD95D904BDD752FF72F108 +:10EB5000DEBC8E8F84DE704AF08F1382AEE57B754B +:10EB6000FB9AFE7311EF57A91AF2AB23330A09CFB0 +:10EB7000CFF82B69FEA3152AF99BEE2F9A3217FDC9 +:10EB80004D723D72BEF26BCE27A03FED0B8017FA9F +:10EB9000C7CA6D5ABF48FA85191ED1C695F803FA3F +:10EBA000EC11DCE761E4A3F8D66B84D361EC0FEFE2 +:10EBB000676D5729DE6686D381E9C3882F1DDD2561 +:10EBC000F827C015F5F0DA878DE7BAA42DDEC46FFB +:10EBD000FA1ADECFAAE47A99E4D7727D87570DE955 +:10EBE000179E3775A1F396E35C2CBEDC28FAA3D8F8 +:10EBF000FC86E46FB2613CB0144DF3659BDE5F6E42 +:10EC00007A5F60AC5F241E1F13F823E5CFB158ADC7 +:10EC10003A521CEFE8D531B5E1F9099D45DC7FD3C7 +:10EC20005924E2DE9728B7FFA328B2DC8ED65FF224 +:10EC3000BDA70B3D41E4772C504EF1EC8BE57361A1 +:10EC400072FE4C11D27950B1637FA957DD58C6E5E9 +:10EC5000C2E6F8A7284FE3D346AE17ED6F8C213CF0 +:10EC6000FCF335FCFD9FFFED23D2A70EECDD9C18D5 +:10EC70002EE7255E9EDD332D11FDC2272B1E4B0C8A +:10EC8000B703E4FB8F2B1EBB672CD1B7AAF5762EFA +:10EC9000DFD61EE8A810F680D0176EB2B6FF3FB1DF +:10ECA00007CC76C014F5E144E47F667BE0AC5B4FB3 +:10ECB00074117C04DD09B972A380CF9F6D7A22C5DF +:10ECC000E9761572B962C24F0987D3120E1BCA7B4F +:10ECD000C59B53422EC8FA622B2378781D8CF465AD +:10ECE000D6A66818FFC234951238974315F98FA13C +:10ECF000FF4AB67FA65825FC96F31CD9A6B4A37F7D +:10ED0000E5B7CDE5D57760BEC38C78E2ABB2FD1236 +:10ED10005FEFF2EBC8C6A46B711EEF1655C3475EDA +:10ED2000DFB17EE1EB977A9AB9DF326BEB45D9D14F +:10ED30005EDFF644B46F83629DC1FDB1767742CF4A +:10ED40007E18AFC1FD2F9BA16A8DB0FE651BF8BA7E +:10ED50002A7DAA960DF5DFB63E762DD2C1897A9B23 +:10ED600085DB072E039EBFD95AF836B63F59C6E554 +:10ED7000CAB18AAB12310FCEB7C5A6E5B87BCE5764 +:10ED800053CCF3D2CEEE89B1A0FFF46CBD8D05C893 +:10ED90007FE1217BF9C88621549E45F871FB9ACE0C +:10EDA000FFC662EEE73AD1BAB03FA72737AD43E2DC +:10EDB000CBB15D6A993F02BFBA519CDBA9AF9E26D9 +:10EDC0007C7B755739C9E313157C9E53ABB44484DF +:10EDD000E7EF36A844C7277D7CFCFD7BEF4A1C0B80 +:10EDE000FB385BC1F77576CF9D6F8F817D062BA4B5 +:10EDF0003CE6724AE6F704370CA178EFA7CDDCFEBB +:10EE000096F42EE3E157AD3C9248FDA59CDB3DDB3B +:10EE1000B0FE8E5D27C80E3BBB0166E372CE998FB4 +:10EE2000F986BC3B5B32C378BEB32AE20DF5792D7F +:10EE30004679D6B897F32BB39EBB7803E8C1E89721 +:10EE400032D9790B1B0B134B907E510FC63C932785 +:10EE5000CA0FA6E23EDAABA95D85889B2D6C8B318B +:10EE6000F083CA66A35DB7C064C7F5B0EB4CF24847 +:10EE7000C2697914F924F5B90E61AF1CB579AA23DA +:10EE8000E553B41773F9330FE8370DE3444CAFBCC7 +:10EE900052C07B3DC2C7DEF5450EE8D31DAA361E23 +:10EEA000F5EA1E7460D203CBCB8CF0659A8F95483F +:10EEB0007F849BF4FBD3A8FFB7F41572DB0772289D +:10EEC00001E592FE6C31CA958BF51F5CB47E5E2322 +:10EED000F4F31A837EDE814DC2FAEFAFBC9EFC5480 +:10EEE00047AEB99EF4F523DD7E2A8FC14F25F5BAD2 +:10EEF0002333CA0DFA67D8F33EBDE58B47D3378F6E +:10EF0000213F263ECDE5D25A6147360B3BF2C80C75 +:10EF10006147A630A223AB556791F8D9A5EA6F0BDC +:10EF20009A8D72C9BBCA683F3E3FC97B16CF252662 +:10EF3000ED72C3739BABC0E83F34E1E740C6FDE729 +:10EF400077A12F00E0DE54C9F34EF139E6BF48B98E +:10EF5000C4A03DF28BCA0D97FBD7F3F73EB500D3A3 +:10EF6000E518AA74D4DECAEBBAC2EB3EA778AF8A22 +:10EF7000BC371BD48F6569B351EFC2BC9EF864FEE9 +:10EF80001E516420E075627248FEA15F3F9687D6ED +:10EF90007D89D06F5045D62B48D798EF735901DA49 +:10EFA0008C3C2F2C0D5DFA05347E00F37A824D13D4 +:10EFB000C9DF5CEE48E4F179B0A37BC7BF46AED7AA +:10EFC00095F5A5C90659F97AA2E2B36877217C0EB6 +:10EFD000D3C3068C223F9A85FC2D9BE247D8107F35 +:10EFE00067393D190807C07792AF1DBFB1131FDE07 +:10EFF0005FC9FDB01DD3476FBB1D9E8F78DA49BE38 +:10F00000F48EC5D20FDE95108EB747579DB0205FA6 +:10F01000FEFD1EA6611EE3D1DD5507DF80710EAC3B +:10F020005AB8B118E9E84D95EC06B3FF76D2D3E3B0 +:10F03000C8FEBAEE1A95F2BB0F97A90CE5DAE10DFE +:10F0400071063B24E4D755093FBED867A5F768EAA7 +:10F05000E462FE15FA37314FAB8C9FCB0B829FB524 +:10F060008B73FCB9D063760ABA69137473AFA09B33 +:10F070007566FFEEC39C6E0EEF01C301E4FA3B33ED +:10F08000169692DF7A0BA33874D674757D11ECEF67 +:10F090008A18CD86F09B34239FC3B342B160FCA68F +:10F0A000BC2CDF86F47E455FB70DF96879D94CAA90 +:10F0B0004FAEC8223B7FFF2A908F68EF2768194820 +:10F0C000974367C4042C89683716129FB8F28CC521 +:10F0D000402FF9813803DD5DFE78B2E1FDB02DE906 +:10F0E000867A3F4FB6A17DDF32233DC60D2D30F22B +:10F0F0005DC6F54209E729EA38F2731D0DC9517A58 +:10F100002FF511E9AF93ED015A06BED622E4C808E7 +:10F11000A8633EDDBA8A2607E64D7CD16ED5F8F8A5 +:10F1200055A41F38B29E73209D606815F3AB5AA496 +:10F13000FE29FCF74C67A6756D6018673D5AC60836 +:10F140009F62873205F5AF3671DEF7897981AF4E60 +:10F15000B2919F8E9F63DF191E6AC73C46FB200D4C +:10F16000E9AC00F184F7FFB9E8BF53E0CBD1B2C7F7 +:10F1700056C7213ECC66A46F4C516F5E8DF1C4A37F +:10F180003318D1497BE0E5385C3F8E83F9812F4409 +:10F190001BA7E2571FDE82EBD965A771CA1F671351 +:10F1A000104F2EFFD1B18FDF46F06D711D88653D88 +:10F1B000E5F088C7750D81937B86056C540674E471 +:10F1C0003FB9670EE9180FBCFCCFBB3E7E8AE1BC9D +:10F1D0005C2EB408FC36F3D75F3CF1EB05289F7F2B +:10F1E000B1736BC10750FE60F583E9F550FE7CF505 +:10F1F0004D5B6F7787FCA53BAF5DBAA30DEAC37E7D +:10F20000F8D3279F43BCBAF6A7FFE7395CEFB57F79 +:10F21000FBA313D67F59530243FA96EB33CF93C621 +:10F220005A148C8B221F25BE6CF5517DBECF68FF12 +:10F2300098E53EB6B702FCCAEB7F41F1E534D1FF59 +:10F24000F03577292ACCFBC17CCE573A1ABADA2698 +:10F25000DBA87D00DB039FA47CCD818380AD607F34 +:10F26000BB4FC1B83828481AC67B07C07BE4E7CC3F +:10F27000ED26FD2A53E2AFE02B78CD81913FD04AB5 +:10F2800078962BE291C87F91DFBF312A9BF8F2403C +:10F2900027D3F17CCB5EDCA0609EDAFB5EB7467ABA +:10F2A0004103BB7F32D8C997AB3CEF22B7ECFDB925 +:10F2B000782EB055ABB72034EE2EA1D795BDE8A47B +:10F2C000BCEDF77739B7939E7FE85A4BB87E58FA72 +:10F2D0008B3F3DFB3BC4AFF9B1845F66BDA543D016 +:10F2E0004777DDE6DE763BC0C7F71B07B7AB747721 +:10F2F00006D9E99A3B03F377BADBFD54C6D3B43F92 +:10F30000223F9F55154F7106195752CB3E5F83F42C +:10F3100038AFA4AE18F5F7743C87BEA138F607CB1A +:10F32000EC946FE053E2282F3D5ABCFABF843C6452 +:10F33000AC6E24AD83D58DC6F2FCECA66D767774E9 +:10F3400079D52CCE35DA7B9B9D7923C595FF6B143F +:10F35000F72336E139D8C2CEC1F9FBB9181F8E7632 +:10F360000ECCEA2FA03C4B876328E681A48AC79B7A +:10F37000E37FF616CAABCE235C5EA5D67FD980F4B8 +:10F3800027FD163569AC3B6EA6433F9BE8972AE202 +:10F390002C48C3A87FD78878516735A378516AFD78 +:10F3A00047FF8DF0D924C6AF798F8F6FB706F6234C +:10F3B000BED438DD24773AFB256A78AF897DC5F362 +:10F3C00053D219C747393E13E3E3CA59D8BA53E3B6 +:10F3D000AADEA1EB101358201EF14771D0BCE9AB97 +:10F3E0006228AF55EA57A9F577DDAA8E308CA7A021 +:10F3F0005EFD7E15B7B7D1ECEC1E37CBA057919EC2 +:10F40000655E87ECD769637BD0FE0DD3B3480F638D +:10F41000E1F30C31D4851FCD58B7A5D90D7CE2FDA1 +:10F42000AFCAFBD47139E04E19C5FD77080FA98F1B +:10F4300049BDADC7B882DEC3F44B1FF20B9947D16B +:10F44000AD27D586D94DD93DFBC97C35790E129EA5 +:10F45000D1FA3F3F499F329AF4AC008DE315C3586F +:10F46000E29D99045F13BF04B6C5F3E9851E0A5AED +:10F47000A4218F41EA95923F770ABE1BCC0A92DF06 +:10F4800050E6890F823E99D0FF86D149DD79F6A8F2 +:10F49000071D6DF88CE2EF35A887C2FCC1D59F1817 +:10F4A000EEA114954EBA81D66BCA97088BBBD27A5F +:10F4B000BD826F4E519D94B7D2C9E234E45F9D3E48 +:10F4C000A18FFD219EF431C92FCCFCE11ACDC8FFDC +:10F4D0007F5462E4FF33F5BE26BBD018A7AAF49888 +:10F4E000E2E1EF4D37F04DC97FEE44379F8AEE25BC +:10F4F0000FC575DE14FCF26DA107DA591D3D77309A +:10F500007E7F348EB553E96487A84C645D54BA9805 +:10F510008BF26B929946650AF350D99FD55199C6E3 +:10F52000783E553A6BA772103B446526EBA2D2CDCC +:10F530005C162CB39946E550E6A1D2C35C14277F34 +:10F540002F21987118E037E37A26EEFD1EBA418725 +:10F5500073EAAC64A17BC04857539840BEB7F9FB2F +:10F56000E9B2FECE0D3ABE9FC4DB6F7DFEBD87F0D3 +:10F570005E30F01BF1BE83BFEFAEBF7BC324EC6FE8 +:10F58000B3507DA7687FAA487F08CFFFE9D18CCE12 +:10F59000BBAC48DF36BA38543F53A83F1A5EEF3F42 +:10F5A0004ADF1E5E1F5DA83F16DE7F49A1FE44F8BC +:10F5B000FB7DC5FABFF2BA8BF0F23D9B4EFA2EFCF2 +:10F5C000EC5246717CC39F3EAAF769C2C3DD8A151F +:10F5D000CF3546D09B1DCF51453AD21C31587A7851 +:10F5E000DE4F30D6198CB7F462FF98E82888FC0902 +:10F5F000F070B8E2DD47F398F889E213F98329C681 +:10F60000B809E03BF95583ABB89DCE58E4F772DEFC +:10F610000BE139D3C3FCBCD9A171A3EDC38CBF8767 +:10F62000849ED721F4BCF7441CB97BDF416BD269BF +:10F6300047888EA3DB8756763A9C5FF6D8F79FAA59 +:10F640006D40D7C1FA1817CABBCE58F636DA69BE74 +:10F65000232A433DE352D7DB5638F50CE78B835C16 +:10F66000C867BAE7157CA6137F053DE78A3ED2BE80 +:10F67000D41C1CDEDCEE4812EB6A9A9C7C752EF9D9 +:10F68000F3B95E9F673B34731AAC337503F7AB264F +:10F69000227D63E8ECE93FB8308ED63AC5C2904F80 +:10F6A000AD917E5E933F6ED3E415AE707FF09A44C9 +:10F6B000BF82F1CBF4402CF743A4307F2CCAD13267 +:10F6C000AD8CF2667CAAAB0CEB55ECDA5CA82F682B +:10F6D00053DD6530EF81B65FAD403FE0A22A3BC508 +:10F6E000316CFAD4B3DCFFC7F33792059E37AF8B8A +:10F6F000D10208C77E4EF2DBE6AD2928437BB7C9AD +:10F70000999C8CB8985CB584FC864D4EED35BCDF79 +:10F71000E17359283F91B9744739E82BDB6FB796ED +:10F72000211FCF78A628510D5BF789E673B1180722 +:10F7300079D465A1F78FAE2A752C71E23D46B017DA +:10F74000A03CE03AAEA3FEBE15DAA0BFF19EDAE31C +:10F75000AD97F5728E89657603DEC66BC67A8CC965 +:10F76000DF6833E905C34A1252E89C47B15178CEAD +:10F77000239FFC8AECDF794E37F9D54B5B14CA8F97 +:10F7800009EED73251DF3CB17118E5BB34B718FD33 +:10F79000D1C10C9689F77DE6B72AA4AFAACD9F37D1 +:10F7A00062BFC1B9EE0138CE60AD6B802B8CFE1EFE +:10F7B000FDE98F6351DE35E38535C223C6E342C2DE +:10F7C0005E95F7CAE7BBCE55A3DEBFA8F55D0FC2B5 +:10F7D0003F49B710CD1CB5F9D3F0FCD74F9A45740B +:10F7E00089F7B4508FE9A18FFE15D619763F614D88 +:10F7F0004A761CCE1BC25F3D11F77BB2B590F4A3D5 +:10F800001D2DA5741FC03CCEDD0DAC1DF5D6350DEC +:10F810008EF648FAEFDD999E4CBCBF7D6AD3A4B545 +:10F820000CCEFFD4FE656978DF7D716B0C8B75F7AC +:10F830006C7F72D3689A6F31DEA3C6795B67DA5149 +:10F840006E4C6B9B6447B8DDDD30FB99F0791E2A66 +:10F85000F5569700FDC5B73E4378E264011FC2F537 +:10F86000DFC7EB99A85F9CCC6111F33997962844C8 +:10F87000B7BF1BEFA1FB29A73222B7BBA984EBE7D7 +:10F88000C11237BFB76E656F2F4D217BD085F47ADB +:10F89000A2A590E277368CBB0FC1EF567CD580F8DD +:10F8A0007FBE6AE1074BE1FD9AE9D79DC172A4BD15 +:10F8B0008EF466F67B95E801F442BA27F69F150EA2 +:10F8C0005753581E21EA8FBAC1AFE161687FD85AF9 +:10F8D000D4801DF8BB6DDF69D2C3115FF530FCA584 +:10F8E0009F51429F17F92169A3E8DE1DFDACB9FACB +:10F8F0003A7F00CAE32D0B1D91CE31FAFC61E3A2E1 +:10F900007E3B99E9B161F383540C905FDBCBE7EB6D +:10F910006E27DE8319AAD3FA845E6E7EDF4D6F5B9D +:10F920008CF4B94D9C8FD4CFA3ADF7077E63BF177E +:10F930003038818644FBB5067AB95C6D5F817115FC +:10F94000F63EE7FF60D7314F84385788CFC2DAFBE5 +:10F950000BF8013CD7A6CC22FB24DA3AECFE437A22 +:10F96000D68890FDF68334E3BA64BB17C4BE62FC4C +:10F970002C604BC43240F73962A03FCAEF2FAA6E09 +:10F98000735D1D812E6469E65BF8E30E8BFF98F9C9 +:10F9900004A2C150A98F58787F3D8CCF25DCCFF5CC +:10F9A000DF935B14D27FD76FE279145FF8A14ECA60 +:10F9B000053F27542DBE11CA8E33ECDEE192175B52 +:10F9C000EEB9DC6D80DBA2F0EF999C79F2276FE352 +:10F9D000FB8F9EFA8907977B57CAA244CEB78E2D1C +:10F9E000C0794E5D61277F0CFE38247E40C3A5FEA2 +:10F9F00018031EAEDFFBE496052877F63A344CC7B1 +:10FA00005BBCC5F83E262D6C5F8CE397CF00A760EA +:10FA1000F64CA0A3A33FFD57BA1F1E87FC13E97144 +:10FA2000550CDD0B33C3795C49F77746086F1784B3 +:10FA3000E250741F44D2D5F10D4DA7541867ED2A3A +:10FA4000BB9BBEA760B2BF8EBA67EA6961F161FB7A +:10FA50002A7E4F9385DB89D9A1FDCB718FFA163AA7 +:10FA6000DCCE9EE3F5C0BB28E3F529D5BF46BE98A2 +:10FA700056EA6163281EBD90F65DBF67D5D137A0F9 +:10FA8000CD3D715EEB987EB8FE21A314BC2F63754B +:10FA9000D3BDC1E6664B2CF2FDD6766BEC50847775 +:10FAA000B385E47C6B7B4ADC50944B4E0BC54F51C5 +:10FAB000AEA861FEFDD16338BC42F2C39318AEFF1D +:10FAC000C4097C3C952BF49FC95CFF519EDE477AAC +:10FAD00047F31A1EA792FA864BE08FAB99C721A372 +:10FAE000E93FC87870DD09C58B5CC8D7D624F2EF32 +:10FAF0006F2C9AACF9F03EE7554E467263305EAA21 +:10FB0000403DCBC9FCD3601ED5C5F51B6F2B237DB3 +:10FB100026D9E9D410D4A96D7E1FAD5BE774E680C9 +:10FB20007F08CFB85C9DE1F856935E6137E90DAA76 +:10FB3000A9AE8D11792B428F6042FF96F1E0848D42 +:10FB4000BDE70149BF6EABF04F80FEE4A37B2325E8 +:10FB5000CC8F78CB74DD9DD23F6407A489EF1EA5BE +:10FB600095B0ED4D61F127457F95FC06D22F29FD1B +:10FB70000FD2CF31A204ECB5C4307FC44B605AAA77 +:10FB8000140F9B8E789205EC80ECC93CA6F0EB1923 +:10FB9000DF524FAFBFB8B8CF432FF3FB41CD9638FC +:10FBA0006D4756CF76378DE3F8167700F6867AEDF7 +:10FBB000F50EBA873345DD4DF7EE371759785E33CA +:10FBC0003BE4427D60E118CE77B34A3D0BC6503C22 +:10FBD000D593857803F0F0D9F0FE9EF0DB66DC91DA +:10FBE0001D87FAF007034E6F42BDDCB7C642FC46E4 +:10FBF000C231ABD1722FA261587C2E602D08C5D9BD +:10FC0000D67BCEF9F0BEF0B5E3B8DF356EE6C9FDC0 +:10FC1000E8075D37D4427EF6BB12748ADB01FD38FB +:10FC2000541EAF7B0DE36D2DEEE464FCEECE534924 +:10FC3000FCBDFC7ED50309FDB787E797948EE3FAF8 +:10FC4000C8034A647DA5EF3885E759ED0540F621E4 +:10FC5000BF16B7C77D5F54E9CEB03AD21EF4FF1786 +:10FC60001FB7A75BF67E51E51B4A7692789F534DEE +:10FC7000F63AFA18E1FD89BD2F55F9A0FE4856E481 +:10FC8000797F2BE67DE475EF60D467837B017FFA93 +:10FC9000443ADF00B394D0B89918970AAE8C991DF6 +:10FCA000E93B3683C6F37D6E8677317D427AECE69A +:10FCB0002AB39EEA277E75BEF6F8414AD306FE5166 +:10FCC0000CF490C422F3CB0BEBAB5A1AEA9D4D2BEC +:10FCD00095B5C83F9A405FC5B860AACB4EFA6A7323 +:10FCE000D28F27E1B99CAF652EBCEFBA03D43EE4B6 +:10FCF0005FE857C57BACD3EA399FF1BAB89F15ECE2 +:10FD000038CF55888F03AC848F527FB55671FE7300 +:10FD1000450CCF47EE4C7292DF34A99EE71FC7FB1C +:10FD2000409FC5FD4DE6F9C33AFC433E24F55B67B1 +:10FD30009ED590476C37E5195B4D79C5FBC718ED2B +:10FD40009984E2A25EF5AA97C0FEC575EE03FE8314 +:10FD50006500EC602C5F06BB1DCB57C06EC7B8C1F9 +:10FD6000AB0DB954BED6A0D1F3371A4AA89C981946 +:10FD7000A4B822F991C97FC3020AF9F1247E7D3A21 +:10FD8000A814EA4F4DE2EFFFF3853B1FF50D82F714 +:10FD900029A2BDEFEA6AC4D7EE3AABAFC6F6356921 +:10FDA000BC5E3DF6C7D5E8FFE99AA27F88F2AD9F19 +:10FDB000C5337F0DB6FD498C16C9BEAF1D2BE47946 +:10FDC00014FB9DE127128CFE9CB3637AF1E73CA003 +:10FDD000F075F4DDF7D2C348177D665A3D88C799A0 +:10FDE000D9463FFFD563395D3C3896F39FCC3780C9 +:10FDF0003E7A81BBA48F68EF9BF6020A44A02B5980 +:10FE00006E4E6013E87E76B57D76A43CA7F3827FC4 +:10FE1000441DDFC9DC312343F4D6E434D35B90E2E4 +:10FE2000BBE7EB6FDB8FF2F2BBD31B23FB3058AD8C +:10FE300093BC0E02BD213F576B39BDA9567E3FB31F +:10FE4000E64DEE1FD981F485F970486FF0EB341F51 +:10FE5000AFA79AE8ADC94C6F4E23BD0591DE60BCDB +:10FE6000241FD72FE2ABDABF577A1B39F6BBD1DBA1 +:10FE7000BF8F0F525E436756DD0084CF66F13DBCF5 +:10FE80004BA5C337C7DAB93C18AE935FA0597CFFC6 +:10FE90001058CC06FCCECAB4418DD66480DF8C9459 +:10FEA0007CFA0EC16D63FB0B3A39E4447F4DE224CA +:10FEB0007DDA58A4AFEBCED0FDC67E164EBFB5633B +:10FEC000BBAA90FE32D674CC9C8674B75225396991 +:10FED000DED78B1338DD35297C5E38B901E171BD81 +:10FEE000B963393EBA5736290ED4C7E7332D278B6D +:10FEF000BE2B43DFBBF997E6FF74E1B82F4EE0DF7E +:10FF0000737137BE97E4E5FEB534B4DFE84A734158 +:10FF10004F7A849F765B7F033D2FC47D44A3E70B1C +:10FF2000F18FE01845C085511EB057DCDF94719108 +:10FF3000A8F46CF2E346F51F0E8FFC5DCAC9E3F925 +:10FF4000BC4DC2FF6BD6F7E4FE0F4FF2FE6C2C8C5B +:10FF5000A3385FE57EE07DCC8DEB9471B3EE3C235E +:10FF6000A91FFA98BF09F56D2BA832FDB9BA81E334 +:10FF700075E71F093D7159A9771D8EBB9DB9F7A380 +:10FF80007C736A3C5FE1F949FA7A82E7B7D4034BA4 +:10FF90004AF57B71DC6878B56C9AFE406FEFD957F3 +:10FFA00030CAA8505C6BD24C2BE70BF58AE003CE2D +:10FFB000B576A86F4E027EE646BD9DEFDB057CC39D +:10FFC0004D7686D18E988ACE48E41BC84708B8FA89 +:10FFD0000CCCAB4C14E387E475F020EAA54180ED2E +:10FFE000BDF02AD1C7E575D39B9CAFD881AF505CDB +:10FFF000BA84DB09F25E507C9E46F697AAF76E3F04 +:020000023000CC +:10000000584DF6FD9EB1C27E28604508B74C8BFB6B +:10001000BE31F0BCF0C12987C7C0E3E26D8BFBA203 +:10002000381DBD7D4D397EEF6BD913A7B6A39F74E4 +:10003000CC7FC430F15D35CA33F83BCA193A97F327 +:10004000FB58B5CF8AFC2A321EAF19CFE59F8CB37F +:10005000F682C7EF131E8B38E725E0B1F302787CF8 +:100060001CF135021E9FF88E78FC09F6BF170F01B0 +:10007000D61D3B4DFFB437BC9D3A55FFBC377E1AA9 +:10008000163FE0F943AC96EC6719BFEC015794AF0B +:1000900039BDF8A5D6ED88457BB6A976C7EBF8DD66 +:1000A000C7A67A6E677726688E12B46FDE55E97B35 +:1000B00056D1FAA3DDED0366B96A3CCF8F3EB0326C +:1000C000263011C6497772799BEED419E68B5B5DB9 +:1000D000419B3701F5350F43BDCD9E6261BE307F38 +:1000E000CC48DB2192CB9D20C7913E803E39BD2577 +:1000F000F171A47C9EB8F23E8CE4B0F15DC0FBC20D +:10010000E8E4F5BD25E4874B287E6E05F653ABED9C +:100110006EC4EF897F05B91936CF24D044C2EB579E +:10012000390618C699E2CA32BC9F96F603C3FBABE8 +:10013000015FEC14C7E6F702A55E33DD9D6F68979B +:1001400024E21C3FCC1D6318CFAA7E75EF68A47F04 +:10015000A1478C837FF45D5E93BE60D627CCFAC343 +:10016000E82B8DF75D4658451E9A95E7476C660E5D +:10017000FA2E05F041FAEE414D284F80E864843DA7 +:10018000B8E36EF4ABCC71683E78D6BCF7EAB4F94C +:100190004521FFD9E67AEEF76BDAE3D88EF4B05555 +:1001A000D0A5A4AFBC84E37318C9753B43796CA692 +:1001B0005799EF24FD05D29FA0D4723FC3D90959A6 +:1001C0003CEF48F09FCD55DCFE7D4809C42A4338FA +:1001D0005DBA9343DFA74B638A6F3AA76F3D59948B +:1001E000AAC8479579AF380EDAD9697C3EF61ACF9E +:1001F0009B6CFC67ECEF62BE41C29F91911CF25375 +:10020000607EC2CDBC9F6FBAE83758E45BF6E1EB85 +:100210000F4C11F38D8052ADD3857FDA4B650CC640 +:10022000C3A1CC56B438F47F0C513D14684914F185 +:10023000F574114F8F57029C797C4B3E3212D828AF +:10024000E625B064FE7D91D25F38994AF461DF8182 +:10025000F2E8AE63DA3BC5F0BC39E1C76F4D84E725 +:100260002DEFAA1AFA49EFCAF07D80746D0564F08B +:10027000915FCB331FCF4DAD70B8A6413FD5B7BD11 +:1002800011E3BB23EDFEFD749EAB6388DE83D00FCC +:10029000F1616B02D029E22B7ABA4685F281641CA7 +:1002A00023384673A01C0D623BEE6F36F83F23E403 +:1002B0009B90BFD42AEACDCE1DA4BFAF4DB1E317AA +:1002C0005331BF27B31EF1B25F1CBF7FCB78DC6018 +:1002D00030FE12966F6F7745F66B82BE4670083619 +:1002E0002E4DEB4DEF8A1A47715A02F6C48B8FA33D +:1002F000ACB9F13A7F206C9D72DF6B9D3B9405ECAD +:1003000052E667C6384A2DD363474488A304FD0AE2 +:10031000AE73702D8FB30C16FEFA6F1B47A99CC0ED +:10032000F5C74B8DA3C8FD5E237E9F01882DEE1976 +:10033000533C81CECB125A5F18FC1E277E44B82155 +:100340005004EA3F12F5B77677FCE949F8F5CD5D40 +:100350002FEFC652EA7133C5FB6B877DB90F73B7B8 +:1003600066AE5B21E258C6F8C33560D585FBF9F16E +:100370007B01E1F599A6F5945A8D7182C94E63FB14 +:10038000A929C6F76583627A9C1BFAE569BF4ACF43 +:10039000FDDE157F0FE3DF9B0A3B07F5C27507E61D +:1003A000CD61DCC7DD134FC2E3009EDF58597211E7 +:1003B000E28B85F4D2ADBEA5F75702FDAC0539CA74 +:1003C00079B1DB407FA1B847998EF824FDFDD1E8D3 +:1003D000E9B8339BFCFF83EBF7B74FEECBBAE300F2 +:1003E000F7C4791DE3F07B41CE730AEA2183EB5F0A +:1003F000A1F7D7CD29EE158F72EA0FB44F0EFB8E01 +:10040000608ED56341FB39A7FE557A1E559FEFC913 +:1004100047286F2D47E085CC0BDC8A798100F79C5B +:100420005AF17DE0B6DEF3DFA43C6C0ECBEFA364A3 +:1004300006B7C2C2C79772AF873F9D71BFAF9CAF6F +:100440003B2FD0346FB7FC7371F9F7FC24AF36AE95 +:1004500038EC5E86B8C701FB8E98073A5AF8B37B32 +:10046000C963E37667C56B1FE0F8976C7746197729 +:10047000626630E23DA9A9C26FD5191BCC40BF41CD +:100480006794BF9BF0D094A93F1CD78BBE8B79B3E8 +:1004900008CB68EBFCB679B37522DE24E3AD327F7E +:1004A00056E6C55E287FF6BBFAE1570A7F40E93879 +:1004B00016310E615EEF6DC23F9E55EA598178118B +:1004C0002DFE20DB7F30C01ED12F7E6442E4EF0E74 +:1004D000C8FC50586F4AB81D24FBC9BC7CF3786037 +:1004E00017AD1917E60FF436E690BF2FCCDE92F960 +:1004F000B0441F9B851FA29B0ECC7AA1888798F5DC +:1005000042191F51AAB87F02E8A30DE745BD0BF3BE +:10051000D2A59D27F34965DE28E685523CEA5BEAD1 +:1005200055DFBB3DD53885F2BA9A5CA5AF7D177B08 +:10053000EADF2718ED29AF93FB1DBC684F0DEF696B +:100540004F15957A5F447899EDAAA33FFB84F26337 +:10055000C10EDD37EEFBE01326FFD4DC311CBFA556 +:100560009C96FEB4FD432D06BFEB5475D57ECA178D +:10057000AFE5FE9674BD9DEC34BBD3EE467F8B7524 +:1005800032A7235B1EF3EB3CCE4BFE15995796EC3E +:100590005C12F1BEA9B41383D24EF4F1FBA99D6F96 +:1005A000F2B86D3CFA5BB06119976BD2DF624B1108 +:1005B000FE16533E76BCC9BF62F6B79C1E27FCB63A +:1005C000C2DFF288E2BE1B49FD575BA6FC0E41F17B +:1005D0006F0F2F8E4753FF79FF9A1F0A7FCB834EF1 +:1005E00058DFDE0F8CFE1673FC2B42DC8B9C57838E +:1005F000C6FF8EE26E12BE926EA53F2BBD9E7FBFE0 +:1006000069AABA5B41FEB2D9C9E1ABA23F2B25E48E +:10061000CF529EFE53B75F8AEEE3F68893D7BD8E26 +:10062000EBB402C3591FC9BF25E06A8E4725D68B9C +:100630007BC0DF933F2B79BC11BE050F16DE87DF31 +:10064000352EDA567E18CB51DB6FEB3B17CA92275B +:10065000EE2BC7F22FAF07B350EF34FBB114047E7B +:10066000714FF89AE128F1D45B2BF1D46927BAAD28 +:10067000E27034C32955E7789A03780A2A4237FE94 +:10068000752671FA4C9FACBD86FEB5C17956160928 +:100690008FADF5FC7B59128E5B051C936B97909F79 +:1006A000D08CA783DB2E0D3FC79AE0F7EC96C2BB38 +:1006B000116ECF3D5CFE3B2C7FEDBF2D1EE1B6E7FA +:1006C000F1FB7E28E03780BEA76B82DF03F811E9DB +:1006D0007E3DE13751E3F6F5E7A5DEB2F100DFAB91 +:1006E0008143A03F64474B81C3180732F2D3D4EF54 +:1006F000C93F15ECE6A7ECED9C4BE0A71F9BFC5314 +:10070000A93E4E37A9BE63449FE9409FB1E8AFAA16 +:10071000E57A24887D7FBC823637E7AF52AE21CBA5 +:10072000B180F0D9EAE271E7087ECA007DEFD7C454 +:1007300087D181138E772057EB107E52DE6DADE5A9 +:1007400071B4DBA678568CEF178AAB3D3F49BF6D7D +:100750003CDD5FF8D6FEC77FC6FED2FF08784AFBB5 +:100760005701DFF1FBE657813C41FBDF5A1BB4A187 +:100770005CA9A9BF55F142D9E74A4E3FA9695E86F7 +:1007800071FE9EFEBA6002EAED138776E3C37A9C9F +:1007900047E2C3C895E7EF433F57347C488F92AF99 +:1007A00074617C2835C8D7CDDDF850B7EEB2948B94 +:1007B000C787B809FCFB11DDF820E83FB536F82003 +:1007C000D2AF55E083D5057C0CE0A1221EE485E282 +:1007D0009E921E8222FFC00C9FA06F48943C8415FD +:1007E0004A492FEBBBE8FC03110F6D12F1506F3D2E +:1007F000CF97ED5C1933D5987FA0D1BAA739EB9488 +:10080000F03CFE0879B22FE3F9C938A78C6B7E5E05 +:10081000EA79059F4FCCE5E71C8C1E670AE0FD5680 +:10082000403F9709CFDF223C97F70F841E77DB14F8 +:10083000FD6D1C7784DD4F79CEA0EF1DC6765BF78A +:100840003EC9BFB72BFC90322FEF3BFBCD12ED7EA4 +:10085000BC2F29FD669B13EC3BF0BCE7B3E014FA18 +:10086000CE2FC629D0EFB43186F21A172A6078232A +:100870005FBCCAFBD1788AEB79281FD75BE170A1F6 +:100880009EDF9C34350DF946CD5A95E47A34FB460B +:10089000D25B0DF01BA2B77ACE6F5201BF08DF7C8E +:1008A0000AF19B74E0379CFFE80CF53A2BD29DB31C +:1008B00027BFD9DC0BFC2F92EF7C83708FC077941D +:1008C00009C506BE6399F01DF8CE4FC6336E1F8A68 +:1008D000FD633C80F68FF415BE7FB33EDBBD6F2316 +:1008E0007D49BAFB5F4067232744A6B3FC09DF8D2F +:1008F000CEC662FF087476E504239DE913FE67D235 +:100900005905E1DB05E8ECA3F14CD8B7D71AF48A16 +:10091000CBD5F6733938FFFFE7FCED8357723BFE0A +:1009200042F9DBF87331FE53733EF73FFCA9FF6BCE +:10093000FDA9CF4EF81EFCA9AE716EC23FB35FF5A4 +:1009400093D1FABE09BDC495259FB64A3E0DFC1849 +:10095000796F0DF033E4CFA9555D9F3ECFED4D2D5E +:10096000DE4DFE86D771BC74C1AFCD7C19F4CE3795 +:1009700026FC1DFD0D7F2FBFE14AE167BDD07DFB49 +:100980009502CED1EEDD3709FBBE09C6C07B7A5B8E +:1009900057DAFDCDB0608FD0AB47D45E773512D932 +:1009A0003BCBEC71C15EEC26F977245A1BBC2F9E21 +:1009B000CC09DF1F8B28B7BAF767D293C3ED26F7B0 +:1009C00025D84D33261AF5646B2DB773AD20EF286B +:1009D000AEAF9704905FA7FB94764C0DF6A6D42992 +:1009E0002807536B3D940F7FA9717D331E458BF310 +:1009F0007FDF717D73DEC0FF94387FD14461CF9B70 +:100A0000E2FCD2FF6A8ECB8FB0B796917CADB6E098 +:100A10005FC060CD7B3FDE71379EF71C07DDD330B2 +:100A2000E703448BDB8F48B607E3B3A3C7EFA5BF4B +:100A3000E0115BDDEB68873FD268A1F335E70DE499 +:100A400025F0FCF1B313766DA3FC1FA90F57093EE7 +:100A500053AFD8E9BB8E557EE2335E7D5723C693F4 +:100A6000539DAC1DF5ACB8896EC23F354D273E6332 +:100A7000ADF2125EC9F8444D26BF37172BF04B1D5F +:100A80005AF7168E9F7448D530BEBD119B02CF48D1 +:100A90004059897AC4180BE545B42975E4F76855BF +:100AA000DCF4F73F92F25CA41F3D95A4FD7E36AEC8 +:100AB000BF1FFF3B2507A62F49433EB8B6B1310DF6 +:100AC000EF27DE3491F3877BA79FAEA6387A2EE816 +:100AD0007F0A9586BF672BCB1DBA22FEDE929FF25E +:100AE0001161DD5BA8DF503BF9D954FD81DB900F2C +:100AF000A8974D25BC6E555C7316E079E5D8498FF3 +:100B000069CE19357B11EC6B5D3F4F59169E6BD248 +:100B100050DA677352FF44D447D70DC8A6F95B1467 +:100B20006F5916F61B6021BA56457C7E5DCE92D772 +:100B3000F0EF8034A55B18DE3B68CB39DD82EDDA5F +:100B4000C6F03F82635EAFEA32DE93C20F1F21FF21 +:100B500056D3785C5C157171D514572ED51599FF55 +:100B600048718758C1B76A7256CFA6EF2738ED2E65 +:100B700044B2A6846025E1C74A1BC3381DB3B61A28 +:100B8000F4B4BB1B8CDF7F71E619D7D3D27D3F2134 +:100B9000CB8B7C86FE062CDD5F48F2227E20BFE5F3 +:100BA000497FF1BC1E2BEA019BD717E17CFE51FE69 +:100BB000A3FC47192AFF2F0D22483C0080000000AB +:100BC0001F8B080000000000000BC55B0D701CF5BA +:100BD000757F7BBBB777279D4E7BD2C93E816C5614 +:100BE000B6446410F25AB68494D8684FDF322EBDF2 +:100BF000387C88C476CED8B8CE34932A4E49EC845B +:100C00005667EB64C95FB2A414E44C3AD3B34932DB +:100C10006DF08042661AF33967700821D028811080 +:100C200032930461885B529A310127A2434BDF7BE8 +:100C3000FF5DDDEDEAE4AFB81331CCDFFFDDFFFE91 +:100C40003FDEE7EFBDF73F00F0C00200D90F003AEA +:100C5000C0A6224F122200E7AA200D95D8F74E9782 +:100C60006941800FE9AF25DB1EE807C8F8B2FD60D7 +:100C7000AD0A660DF0DF87A271CD3B6E5AF3C29FBD +:100C800073DEE16AB5371D9C3BAF3DAED594001ACB +:100C9000F2AE03D225AD73E6673A8E4FFE4C866AFC +:100CA0007DEE7AEEEFEDEF3615AD2F86DAFFBFF170 +:100CB000F3D175A9E90128137D68C47353BB44744B +:100CC00075A48302820E039D8DE90CFE73424A0CCB +:100CD00057D2F9C21EE39B30970E762B6B73F897B1 +:100CE0009D5F16D347ECF9710BF2CE801908D12B1A +:100CF000FC0E69AFE1B63F449628110F3F076BBE6B +:100D000028C0B31FE2FE8E67F905DA82ECBCF2065A +:100D100095C72F57FB5E6C5885CF5E918D6FEAD9D2 +:100D200079793F95C00B80FD5D65F6BD62ADFB91A5 +:100D3000232A64ECF1F8FF0933CC749AD8783F2465 +:100D400090BE3FDFF089E2441E39B0DB6569E7F70A +:100D50006FE09CC07483F437F1DFA95F8C4ABCF864 +:100D600009F13CB5424BEFC7E7FBA5F4FEEB68DCAD +:100D7000DD82BE361F0A2D3EE05FB40AE9E8B5F811 +:100D8000E4759F0BFF94054C278B38397C58C27350 +:100D900054D1B907ECF974230348A703CBEB56EC05 +:100DA000D7E9FCA3FFF26DDCC791E37BDEFA36BE28 +:100DB0000ED4D68D34E17E0A0C8F21933C7FEAC499 +:100DC0000964170CD5DE334AD36E1D954C0DDFFB3D +:100DD000B5E03199CEE8974C9A4F39BC90CF13DDEE +:100DE000EA948309C958504EE71B9380F85268383B +:100DF000DFFBF49CF3E0FF4788CF2C9F39CF916E47 +:100E000048BDDEC9DAB9747FC5926705C727ED7999 +:100E1000912EE35EFD16A2F3F83E199238E5F82E06 +:100E2000548AAB007E6B4E7E7A3732FD9E412FF3A3 +:100E30006122A6A6251C3F51A4DDDE4BFD328F7139 +:100E40008C898AFFE3B946975DCBE7B2D7FB6C8B01 +:100E5000CEEB8DC51694933EE2B8F2F80D73E5CF54 +:100E6000BDFF4B95BFED668925EFA340F3C3E42D8D +:100E70001ED227BF35E63A79B27E09ADF7731984E1 +:100E8000DCF441BC682E7D06C91E7C242B27AA25D4 +:100E9000477B23EB7F4CD3CF27CF6A7ACAACACA376 +:100EA00075A08FE8BE2CEADC9F3DEE7316BF7C690F +:100EB000C87843D4664CA8A376CA94B03DB7E10B7A +:100EC000DA5A7DFE757C90336F25CD077C6E2F241A +:100ED0009858C4573387AF7B0AEBEE24BE0CDEACC8 +:100EE00002CB9F9BCE17E8AB4AE6A4142279F80800 +:100EF000CB4712E5A31AE7F1469D72187F72154C95 +:100F000007059F92FCBCDB243E255ABCB376C89FE4 +:100F1000632F41DFFD1B19E7FB6AB7AAEFC77D7E90 +:100F200035BEEDBEDB48CF5F900D89DFEB6C0FEF78 +:100F3000B1D680D109968762CBEFEC3C71EF6BCFD5 +:100F4000138FBAD5D7896EA4C7B37411F6D9F43705 +:100F500066D73BDC747A7829D221359C7FFEBB4A68 +:100F6000F5CF11FD6C3ACF37EFACFDDE7972B27D73 +:100F700065B63F529008C4F09C2341038D00BD3FED +:100F8000C5EF6115CA65F9FCFC448AB23CBC46FF5A +:100F9000C4713DEDA616C3BE7C02B7BE1CED6291C6 +:100FA0007ECB7A7CD511797D23D17F6BD0A3C939D3 +:100FB000FA3570D00B99201102D745B95B07D31BC6 +:100FC000D7E338A8F2B29CCB9115FC7C4B515CF175 +:100FD000607B6D6C09AF677FDF03FFA0ECC0E7CBE0 +:100FE000BDDA2B2427A988443BC2E74840DCFA5AE3 +:100FF00005CC10B65D7ACC4F7EADFB095A08A02512 +:101000003C1E21BF54F7D8918A04E975D29CAA41AD +:10101000FE842D765DEF9B8AB7E17C032FCAC61E46 +:10102000EC8783DBD601CA91F47090EDC400DA79C5 +:101030001FF25D0976BE45CFD79C0568CF91A79674 +:10104000193FB4E7D8BD18CE9CDB6FF3973BC6774A +:1010500068958EF732984606E9D4155DE61857D4A0 +:10106000B04AA3FDF6E82B1CCF6FAE69767C0FED7E +:10107000CAE969ECAFC6FF88EF32883EBFAF249C57 +:1010800080FD9CEF15C8E9E3FBB5B1A2C819724A0F +:1010900037C28DA447C8976307C8FEF4FAD96F0D0D +:1010A00078E184540CA4FA49A827629BECEF254B05 +:1010B0005E93B14AE693147CF67D96C327A63D84E1 +:1010C000B3E031A827FBFA8F9A7ED28343AEA629DC +:1010D000F1FB280ABA8E7C4218960CD4F37373691C +:1010E00009F93929D983FD45382E2A44119EA37167 +:1010F0007ED8FD15310E16D1380D9215D8D70C2893 +:1011000020BE56E03C9F2DE1EF923DD677D788EF89 +:1011100092C52562FEBA7AF6A3990E6C8F82013EC3 +:10112000B63F71044D6445FAB8BD867685CF1F0081 +:10113000A39EFAD530CD760AD92F517F214C6AC2B1 +:10114000C86784DD9E56C267FCC2EEE7D397ACDE6B +:101150002870C6E6070EBEBDC5FC12E9CDED773698 +:101160009C1777283B9F71E8ED23315DF8C39D5DA7 +:10117000AC27CACE67F9FD4BB1F81E9A8F48EFAF86 +:101180009F4BEF3A350364BF523130923845EAD174 +:10119000B5D1CDC8DFE4A37EA31AAE1C3F2E950FB8 +:1011A00069D00A88AE72DFE5F201D8CF074FF88F19 +:1011B000EE676134D94FFE097CF9F6E5F0C5CD0F35 +:1011C000B8B714A0F9C276F4EB5226202D657A98B0 +:1011D000D1FA2CFDB19F5C66D1ABC4E2872CDA8CCE +:1011E0006C3D574AE6E70BCD575A92E5CF85F8128A +:1011F0008DE3FBFA2C7FE43E938967FB691F9C65B6 +:101200007CBB4432985F4BE5B887FA8552C6023DF5 +:1012100069F69B21D0983F57411FB711EFF466C67E +:10122000C33B7121C2B31FA097CD89C752C1567F5E +:1012300025D9D71AC5F060BFB6C8134F231DAF56C6 +:101240002043E72B572049F61C9101CF9F7A14BD0C +:1012500015FA9914BA690F7DB7CB9F4E49D9F5EBB2 +:101260002CBBFDE3A26F69D3B5593A9F26FBB55C51 +:10127000D0C3C3F6673243DF47BBC118D0E7DA33C8 +:101280001C97942D3B45ED267AD1CC744B86B02F1C +:101290000DFFE07DC219349F82FDEFC512EF923F32 +:1012A000259C1E2C61BB345D48C07A2E2E30095718 +:1012B0006CB6D6E9BD495F1CC77D6E1EF6BD4EF308 +:1012C00041CAE7C405EEEF750972BFB7BF9B952B06 +:1012D000F7F797A907B0B3ECA27040ECE1D5C5D3FE +:1012E0007970FB2CCE243D29CDFD4EF0498D24187C +:1012F00077A8A42FA5179EC7EBC22FF63C5E145CFF +:101300009AC76BE117DB4F6D83B35E65A9B54FA438 +:10131000D716B0FF224CCF4D16FD3E4DFE2A44F4A9 +:10132000C44005CFBD15E22AC9ED5F2184261CBF4C +:1013300064DFD610E30568D7883E52E663F287D7AC +:101340005F021D2D3A6DCABCE5D5C92EED2C823742 +:1013500072E337EBFDBB1B3E21E274BFBFCA9F1394 +:101360001F169EF8A09F8CFA9EC2BF7FB105B73EA4 +:10137000F8926CC895F45EE0E60008FF5D487A8A52 +:10138000FB2E7CE2CCFFD0F84217AEA69921675E17 +:101390004FE141C6B3852155679CED92331B47C38E +:1013A000070207072DEAE5CC2B115EB6E31E9E5718 +:1013B0009ABBEE0D163EC757B10F2F02CFBB713A45 +:1013C000CCE273F13E1854859E609C9971C4C17A39 +:1013D0005E3DB3F76D7F57A6C62B8DDA3CDF5B7C95 +:1013E000A8A5401CEDC2C20A48EFC6FD0E0FEF884B +:1013F00015627FAC0C748C3061A8F38B12E18DD632 +:101400008810A57093C085B404D8713CFE85FF4355 +:10141000DF5F83EFB755040DDC192C7C1B7132CED6 +:10142000737785DF30F1410AC4FB649347C4934965 +:101430007899F0E8568B3FDE2704CE64DEA01E1EAE +:101440006C15F86AEB89CFAE23FE8E94DC6A64706B +:10145000DC56B44FA584C746BD8CE710D73970BFA2 +:10146000AF290707E2FF771FF13AFA5E174E3CD02B +:101470008A3810E5DBC681F7B702EB19ED8BFCC9A2 +:10148000955A078211B6A73728539E7CF9379B1FC0 +:1014900036FE7EB24CD0D9FB9EA00B06CC3BE8B901 +:1014A000EF3D118FA1010F362C20EF2FE8E76B40A5 +:1014B000FAD0D3F7843FC02F79DF26FE47FB76E3CF +:1014C000619F0B0FBBF76BF3E1619B3E8DD048F43E +:1014D000417CCE38C13E8FFB1C4F607CDE8E42F1DA +:1014E00054BF9FDB4CBFC6EDD3FD516E4FF5EBD023 +:1014F0008E00ECD9FE1A6E9FEB37F8F9F3FD4DDC48 +:10150000DA74984B1F91D7BCC6DAB3523B15273F0C +:101510007A55BB875561EC5E0FD3ED1CCA27295F56 +:10152000C8A0DC1B8EEFF6A429A4B7E39F8596BC68 +:101530005EEF3B7BD287E347CAC1D883DF2F6CDAEB +:10154000C672B6E6AC27AB2740714E81234F10839D +:101550005247BFCD7FB5637C87B6D4F1BE2436CD6C +:1015600076AA2B7ABD639CCDE77FA2380BF737D6DE +:101570007E5A23BAF6E82B1DE3947B91FF7514FF86 +:101580007CCC312FC8EB0CB2D3251B9C721872F1A6 +:1015900055DD7EFE38C8E6F3DBADCE78683EFEBA98 +:1015A000E5D5A66BC92C5D455C99A2B812E95AA293 +:1015B00009BADAE71DB1CE6BAFAB3489F35DE9F858 +:1015C0003244F16565BEF8F24D8BCE17882FBB9D76 +:1015D000F1A59BAE178A2F17B439EDCAC5D273D3C4 +:1015E0006291772B7941E6B845EEEE633F583A2594 +:1015F0001B5D64122D5C56443600C76D6A50D3845F +:1016000033C7603A4AFEFCB0845445792BAD35CAE5 +:10161000C9CE3C14365EE925DCD823F280CFC46EF7 +:101620008F12EE18DC7D348ACE0A9ADB3C6CEF46D2 +:101630006367387FA1E8C0F90B6CCD741E7C628FA4 +:10164000B7F38D8737AA6909C71FB6F28D877B6606 +:10165000F38D5CDF986810F9C68FB6E9569E29199C +:10166000A578E5AB1B1BCBD95929D8BF81861BAC0C +:1016700027FB035A88E2E8D4468F46E79257DDFFFE +:1016800005928F4352DFBE2A8ADFCA3C9C774D8584 +:101690001BCB37E3387913C218EA6F6C7C956CF674 +:1016A0004499BEAF8ABE0F5731FD0657DFEEA775CE +:1016B00046C20B7A283F32D2E1611EC98433423CD4 +:1016C0004FCDF9E21E771D40268B4BF15BC4935141 +:1016D000C95F11FEC8C9FBDBFCDF1F56393FBBA544 +:1016E000EDC1A3C92A7ECCF66BA15D97D9D8CA7982 +:1016F000E6738427A4F9EB327BAD7CE7ACDF893A53 +:10170000F793671DC605765D82FE743B4F8B7FA9FC +:101710005B3AD3E447C721DE4DF633193C7F1D44C5 +:10172000099EBF0E325FDD63579BC8A37E99F82EDA +:10173000EA338E7A89D26DD545ACF8F530E5C349E8 +:101740001E5C75127B1F03D67CA9593972D54D5684 +:10175000ABD67C06E4CB5FFFA9F593FBDB44BDE68B +:1017600052EB26DF6D03B15F2BDFEDB5F87F9D3CBB +:10177000B983E4F1CF9DEFFE6EDB95CD77CFAD134E +:10178000A5595FE0C4D93758AF972DB0F0CBF9EB2E +:1017900040FB09E823FFC657202EA5FA87D54FDE68 +:1017A00020E675D78502561EE5876D4B45BC45F68C +:1017B0008498AB188B89AE41E53B490DCF51101C85 +:1017C0008330B6BEC8E624B52D8B75AE0F8D2FF3D2 +:1017D000B0BF1A2F4A1C1DA4FD2F0BE6D58B572D29 +:1017E000FB376CD56F48803DA46F92AD1C90F02004 +:1017F0009F2640F0F9EDB6308F57B4D1A6BB506E9E +:10180000DE247928E3F3E4ADFF9C6913F59F9CF98E +:10181000BF41729AB226A77936E33CFF65C923908F +:10182000E35840C18E58CFAF8F36112EF85D9B26FE +:10183000DE2B2B0CD287F170FEF57E679D072815F5 +:10184000D398C5470B378879C02FBE3F2C9DED3DFF +:10185000BD8AF9CAFA44FBA0F7EEFA977BFE408DE9 +:1018600033BE512B9CE33F983D87332E3A344F7D56 +:101870006C51BB90D796C542CE483EF6E4910FB767 +:10188000BEAB94F7A478AA3D6CAD27EC4E50996A94 +:10189000A57827580B06D71495937CDEF893552727 +:1018A000A657919D0F191407297E3495F5D938D183 +:1018B0007DEE0BC5798A02496FFDDC780FE7358B29 +:1018C000EB859F49E6CC774DBB901339371EACA40E +:1018D0007044BF85EB785407A4FE2E5F6F3E3F5DDA +:1018E000DD76FEBACE9138C61114A43E7C70DF16A8 +:1018F000ECBFAB79341F8FD1F3D67534AB3F5BD7D8 +:10190000895F5C5D67B4BDA4A7EA52EA3AF3CC3BB9 +:10191000EB8FE7D675DADBF19C6341515F99ADEB54 +:10192000DC1AB9A87C0E587EB9C4B2CB453D561C12 +:10193000B153E238E2E9867F3FB09CE4ACC1CB72A0 +:1019400000072720574FD66DD0BF564A7EE6551F59 +:10195000540BBB66D27C765C6CD34FB5E66F7DF0E2 +:101960000585C68F977B1A793EC8F83C5CEC4EAA79 +:10197000562B53BB5CCDC8C5346F095875F48C44E5 +:10198000CF6348ACDCF86064E6A76DC59427098294 +:1019900041266824A6ED2EA67F501588F04EA59E00 +:1019A000267BDBE62F74D8FF911E55D8D76A715F6E +:1019B00066FCA4FEB5AD387E68678071D3A10A8F3E +:1019C000D0AFA4C4F5E40ECD19F78C4F2E1178ECEE +:1019D000A0D7A07B22C727C5F82DB1C6B4CCB8DBF1 +:1019E0001917F5E8CEB8684B79FD2B841761D0CB79 +:1019F000F978CDC2B537D738E3A4A2CABEE708A7A5 +:101A00006C1A1478786FB464C116B47FBF6AD71D9E +:101A100071E2E6C1BBB96E34A802D7534736AAAC0F +:101A20001F23DED78F6C61DC58C0749CD8A8962722 +:101A300072F4A5B4C367DD8B10F803E1656232CFA1 +:101A4000FBD20E617750B0D98FDBF2F2179F117481 +:101A50000E55405A271CD7B3234371E578059E09DC +:101A6000DF0F46AB7A4ED2FA2FCB40E774CB6165DD +:101A70004735EBE9AC3F6DF238E8E4F5C5FB687E2D +:101A8000B81974B26BEDDDD8A73CC00615283FE04D +:101A90008BFE2D9FB704FB01ECFBBB47930AF6FDC1 +:101AA000558995848B9FD975C7702C42FE4EE8B737 +:101AB0006FC3B6F82768FC2A2F04687FA04B51DA61 +:101AC0005F52DC6770EBC3DED4F7DB894F7B0D8997 +:101AD00059B4A967FD76BEB7142960DC34EA8D6F6E +:101AE000667B749B5F4BB20F9CE638C2FB151F9060 +:101AF000DC4DECFA4D19E1EF1FB58BBA664077C6A5 +:101B0000D77E1865BFBDDA9CDA40DFAD6E52A9E220 +:101B1000014F379F61BE4D34F80C1FEE63A259622E +:101B20003AFFA1C19BA6759E52A7645AF7A93FE050 +:101B3000DA95F9F43BBF5ED97AE41E3FD2B4DE4FAA +:101B400072B117A66E25FA2467449ECA3D2EDE2187 +:101B5000FCD5DED46D350AE7B354AEB72B670DB3B1 +:101B600018670FCFC4FF9972AFC97645C449E59E87 +:101B7000A484F30DF5887B194345896192E721948C +:101B80007B8E9322E23ED27879C4D89FB3DE78F37D +:101B9000ED3564CF5E6C0830BE1F38F5377711BE67 +:101BA0006F95DFFEEEC3145755A8CCCF216FDFAB86 +:101BB0001407251B02BCDF538B54F0933D88DCF5E2 +:101BC00000C5D9707C03E4CAEB44B7D0D3890AA11D +:101BD000F7D2C31B380E189764A6B359764C223C33 +:101BE000E6EBB6F34E22CF14B3CCD9C48647380FF8 +:101BF00075558FC8A3C6BAAD7C931C4CB25CDE1879 +:101C00007880F4DF54BC8EF878CD5967BC7C952B76 +:101C10005E76E7A3FEB7DDCA475879275B2E43D629 +:101C2000988926CB4EAFF2A5851CF6956BB573F55A +:101C3000FBDF2CFC3CD5EFE77B643FEDD7B81F32D0 +:101C4000DFD95D8AF3BCDC1FE5E77FB9FAA894FB16 +:101C5000DDC8AADBFC3ADB93E928CDEBB6236EB9ED +:101C6000D8DF5EE0F027F63E8B9A5BC5FDBBB36C18 +:101C700091614D70BA8D7D234C0573F17EA65FDCBA +:101C8000737BDADAE729DAA78FF264627FCFF5EBAC +:101C9000DC3EDF5FC3EDC60E10F500DB3E5C83F675 +:101CA00001E9D05E21FA640F88FF2591BB384FE629 +:101CB0008B2A1AE9BBBF623423E5D88789A2BE5FAD +:101CC000DC4D76BF2CC8F2E83ED79A0E4FDE736D1E +:101CD0006ADEC176E71CAE43F4473BB39DED10DAF4 +:101CE000055E77837A27EFC344BBC476A1EF6B7799 +:101CF000B05DF002C9B9DB0E9424857E277491BFD4 +:101D0000B3EF09CDDA055C278DEB3C8D769DFA4368 +:101D10006807689DA1E6D7FF9AD6FDC3FB057C2F17 +:101D20006A62E32B6C175E3C8736FB0ADA055B0FB1 +:101D30005F3B153B961BCF67F9BCFE8E13821E1AC4 +:101D400008BAF6C6F3C48997CA67302F0EC7A495A0 +:101D5000E93B45DD51653ACC5B774C7A0C4A0B0C7C +:101D60004C2ADD56DD11A8EE68D71F73EA8E05CE2A +:101D7000BAA39A4E31BE495B75C7DBD78ABAA35A5C +:101D8000301DCCEEC3AE370ED2A3F26C7DFEAE8E0C +:101D9000C4AE8E866C9D5197441DFCA598F9657A5A +:101DA0000E9112F6FFEE3AA55D8F4478272572EA70 +:101DB0009B75F8DC5F92AD7FB9EB99F6BD8C3A75F7 +:101DC000FAD801A4CBC09D7EC60FF6FE061EFDE824 +:101DD000AB8948F63E805DEFB4EB9976DD13F73DB5 +:101DE00096BB6F7802D8EEC063FEA3E4DFDCFBFD98 +:101DF0005E2C717F47599E7D5F647D711D58F32372 +:101E0000EE227D7ECDA2A33DEE414B1F97AB22BFBC +:101E10000D2195E39DD607832013CE2E528F915E20 +:101E20006C86E90EA2EF4058E0BCD4212FDBC9E359 +:101E30001D3AF3AF4C35F93E44D99703C66E9C2644 +:101E400075520B51FEA9A7DD3CDEC1FB18BD753DE7 +:101E5000ED03713BD9BB5F57DF17E17A3FDD7B2A8A +:101E6000A6F8CF584C7990173AF2DF576A597C762A +:101E70003DAF5BE4018ACF5201E339BE57FCA4C2F7 +:101E8000F3F5E014663DDF5F6A574B681E713F75DE +:101E900020789AF9D552ED5BC179BDA2FC71E0B30F +:101EA0001D226E5D8B73A938CF675A13DFA77D5350 +:101EB000AE34CA722CE2BB17C84E0AFB75AFA7310D +:101EC0009B072B96132FD078382E29E41F7D96DCA4 +:101ED000D871E23BADE68BC477E48749EBDBF78052 +:101EE000ECF55FB2F890EC307F4AE35EB7D6A9D349 +:101EF0009231D2C3BA04CA83C4FAE3AAC30BB9703D +:101F0000CBAB2D6FB375784B0E254DD46B51AE5EB8 +:101F1000E7FD3EA59FF448546F4F1C3D40DF5E66D1 +:101F2000BDFBEA36F32DDA77716BFC3F69DE5FEFBC +:101F3000BA83EF055FEC3D8E96C57D51AAE30F0590 +:101F4000046E7E286638ECDDA24EC19F459D022FAF +:101F50005D8F3233C5F74B0DBEF70DB09D71B46D7B +:101F60009F46FB138FBF599DFD3ED50F93540F9A8B +:101F70006F1FDE7D3B38AF3B50D1EA27FB83F6ADC8 +:101F800098FA43156634771FA92221E7C945226FC5 +:101F900041F9B464CE7DF2924E99CFD35601199295 +:101FA0001D5F50D4DD7CA8B83AFA1F9FD9C4F78BC7 +:101FB000F1F924A518AEEAD4455C1E31C0A478B36B +:101FC000220EA4DF3E2DFB3DD551DB2AFAF8BEE5FB +:101FD0007CF3C851FBFB047F7F53A7C6F3AA118F84 +:101FE000230F7021BAB9E9324874AB9E9F6EEA455F +:101FF000D34DE89D9B5E8D16BD9E097F91CF071F37 +:10200000B4B19EF9343C27B6AB3B857D9183262441 +:102010008AC846C51141529EBD0FA80E6DD359D630 +:10202000049D65AD8FBFF3551890B881E89260BAF2 +:10203000B8E9807602C84EFCF0D12311C2A72DD892 +:102040008F0AFB013E6CBFDE21F862EBE93AF849EA +:1020500050E4BF9DFEC26D4FEDF6212BFFEC7E2EAE +:10206000750584FDD0C141F722EBF70BC786EB194C +:102070001FA0FF4CD2BD98CEF2EA02EA5FE93AA275 +:10208000BB7EE8AE13BAEB8359B931FDB4CF77B557 +:10209000D3C98FE79117BB3D60E9DB60BF3FAFDE7F +:1020A0001D407D27FE0D359B49AA1BED0D4F47595D +:1020B0006E4EBEC5B858794136085F2A8AE073E78C +:1020C000A269E663579309546F3AD0DFFB9DDC7930 +:1020D000BFDE9AF84A27CA49A13669D23C41C824D2 +:1020E000C9FFAC2D35FBF2E1A621CB8EBCD31ADFA4 +:1020F0004DDFD1B575E2FF9B31730FF52FD66ECD55 +:10210000A74F8A4DBB4BD6A7D3429F9A76B03E8D40 +:1021100054F431CE1AF9894C482A8B232D7D1A6943 +:102120003EC3FA6EEB55DAB63F4D422F288F40FE84 +:102130003B5461B2DDF896A54F0AEA09E993CFD284 +:10214000A790961D4FF9F136A2333E572AA6F9BB48 +:102150005093A57FA44F41BA3F0C8C038650EF28C3 +:102160002FE2D6AF962AE1379F684D3CD449F862FA +:10217000D17ACECB0F55FCBE94F18B25FF59BC5BB9 +:10218000CFFEFCDCB0C7207DA823005D9FD503FBFC +:10219000DCAB6764C8206BD6CC48DCDE3453C86D3A +:1021A000CB4C805B73A694DBD84C98DBD699ABB94B +:1021B0006D9B29E7B67D06F56025EAC34C25B79DE2 +:1021C00033D773DB35B38CDBEE99953CAE67660590 +:1021D000B76B673EC6EDCD33CD629D1A71AE3CFA4A +:1021E0004065B02BA00F46128A480F3EF32ADB77DA +:1021F0004DE53B4AA97023D7897CCA34EBC3B1268D +:1022000061EFBB82824F6E7D78A735F1AB7CFA30EF +:102210008B6F15D088FE2A587F2EFC80F8E737F4A4 +:10222000BD8D7BD5A8C97286F8E40CF1F37271C23A +:102230002CCE5CAC321EB571E6C822C49995599C6F +:1022400039D42CE2B2D4211FC76F5B2471BFECEAF2 +:10225000B6C47FB37E82C813256EF56B849B53E1B1 +:10226000CE6890F27A7B65A07C01E2900F789F4A5D +:102270005CDC67BD487D7E3326ECBE3DBE0E4E7BEA +:10228000FA2E01C7FC9AFED93CBF5D28B95C3FEB32 +:102290006D13764113762155D137CC7569975DB0B2 +:1022A000FD2CD2C3611796765976C1D2F3920AE11A +:1022B0002F4BC82E207D9675D976C1E967151B87EF +:1022C00074DB38C4B20BDDE23BC4ED0E3F8BECF6A1 +:1022D000430E2E46395ADE950787B03FCFF1730380 +:1022E00055D531FA2D41F82CC4483C4333FA5A23D2 +:1022F0008FDF4969F5AC07279536C8CDAF5CB29E34 +:10230000856DBF63B2DF718FB3F56DE8648F38A759 +:10231000E5874EE2F9CD1C7DEBD2843F42FF73335B +:102320009DD3AD6F2D8BCD443CCF3E3FD925F0FEE4 +:102330008FD658B81771A511647C9F17377C92F817 +:10234000D7207EA7F118DA9F8EEE644AD159CF3F8D +:1023500049EBAE6E9F92290F7453D3E8CB541241D0 +:102360003DFD5457C3E5EB6953AB55EFDB592A2EBE +:102370003B5BED85E4DFC645B61EB8C73D5469F644 +:10238000E6A3C7B3163D06863D3D74E1CF968B9319 +:10239000CA52C63F79ECAD695C117B7B71F8E324CE +:1023A000FA41E2FB79F0C7817CFC9F0F7F8C77CDEF +:1023B000E28F31E2534BADC01FCF76C179E39BCBA7 +:1023C000C615B1D34CB7CBC5150F769D1F577CA74B +:1023D0004BD84D459B66FB11BA4C5CE1B613881F88 +:1023E000FE95E96308BF6BFFDE842F50E6F82FB43B +:1023F000338FD338C20D7479EC58B03529B11EC46F +:102400009FA4E7A3E61296A32BA50F88137FD09570 +:10241000D3BF905E5CF4B8C98D9C07B4EB997F0C78 +:1024200084EA283FB2D32FDA2F15848E513BD62F62 +:10243000F2D07F0C2C4E53DE6CCC0B5C3F18940A10 +:102440008C63223FBA9C7F5F037D37527BA6CBAE65 +:10245000CBFF9DA35E1AD6B63DFE6669BEFD88FB26 +:10246000BD948AFF90EF8157689C3FB7E84169208F +:10247000F6CFD5058CFF00614B538EDD4F75AC1345 +:102480007172A59FEB79322867281F3F4C6BF1FED4 +:102490007AB98E19B0FC212849FDE3BC5F9107B5DC +:1024A0007FF7B76FF5FA627109793B8FB7E57F5F08 +:1024B00070D4AFD53AF4DDF1BB6E772BAF38A5B54C +:1024C000E17EC77485EBAE078D4880EB2615227B35 +:1024D000EE5FE489A7F3E8E9B5DDB3F722785F6141 +:1024E0006B5FBE0E11AFCDB7DEFE7EE73DAB82DA8D +:1024F000B849FEC45FD91727BAF9174524CAABCE2D +:10250000D2BB5BB2EE69189916A4F7B0A587053562 +:1025100093190FD139BC6D25D1D65F938633344FD3 +:10252000ED24BC41FEA2D2DF9B6FDFD759FB1EF624 +:1025300026E38493862B15AE5F0E57E6F72F25DD35 +:10254000C2FEFA17EDE0F1B048E1FAB37B9CD22D60 +:10255000E4689FDAC7758CA145F7F37DB721FA21AE +:10256000CD47D1EEFD70E681DDF8FC50FFF6C7DF08 +:10257000F4929C26B8DD77ED7E8DEE711EAAF76889 +:1025800094870BFB337EFA7D6678B5C87396B4E307 +:10259000B8DC7855AE08909D0DADC27972E2D031AD +:1025A000D002B4EEBE906D1FA7FDC23E0A792AB2DA +:1025B000C68EAC1275A9917576FE5FF02FFB7E7CFE +:1025C000BBB82FA7EAC079685197E2D49E4EF7674F +:1025D000EBC374AE324DD4A30E59F23568E5D9DDA4 +:1025E0007439B4788AFDC9A13553BDE43F429ADFFE +:1025F000E826B93EEEDCD7DEE66907DE1869386DFD +:10260000EDDFBD3F21F7CAD36F093B69E1FE90F1D1 +:102610007BC659F63DAEAED5420F8BAD7BF4C5916E +:10262000B849F3EDBEF6B749AA131D2EB7EF167CD5 +:10263000DE790F03A6191787565B7539F96DBEFF52 +:102640000BB78A7B12F63D6F35A23AF202A5AEFBBC +:102650005921571FE40DE7BDCFB6F397479F3F952C +:10266000C3CFCF773BEF835FE8FB3FF6A79F3F8564 +:102670007E6E6CD5F9F5CFE6D3E1FE266E6D39B4EA +:10268000E5324C47AC9FFFFBB1703C6FBDE5114B91 +:102690004FDCF2EA96D3625F9CFDFEE81AE73CF756 +:1026A000597A7E9F358FBA18CA090F8D86855E8E3E +:1026B00006A0F7913CE77AAC5BE5F159B977E28285 +:1026C000A2CBC5052B5AADB8A284F56D6C55EB7342 +:1026D0002437EF915EE4D82777DEDCC6054A8FC049 +:1026E000A5CF845589FCBA169C66BC3CEBD72D1C43 +:1026F000E0F6EB7E6FB297F4CF5FA9DA7689ED470B +:102700006577E01BC920FB0329D70F1ECADCC9F37C +:10271000865D797388387F87B2B71B984E61DDB2CA +:102720002FDD8AB887356A42EE3D9A31CFDB336FB1 +:10273000E8E2DF1FD838A292DE1F9CE2DFC7C03D6F +:1027400090BBFEDE964DFC7B880BF1DDDE17DDCB0A +:10275000CAD59B4BD58B976DBD084080F4E21CDC3D +:10276000CB757418ED76F821AE282C601320FEF09E +:10277000984AA365C7A4ACBE409755DF4E883A3D42 +:102780005198BE33ACCFCAE99604C5D790E1DF1D9E +:10279000DAF6E51CFC92D74D3E2D49B3B8E96A0C38 +:1027A000DFE9F78C4B690B9A875AF7FE9780C1CF08 +:1027B000AB20CEEDB5D0C76D0D8C727B1D4C725B1E +:1027C0000B53DCD6C1596E57802ED3222BC1948176 +:1027D000AF5E26B87F2324B96D86C4FB742774B01E +:1027E0006CDB0AB257EFBBE864D3398FBE332EB42B +:1027F000E961D3FD2132D20D17E66B2A2CEC6F5B19 +:10280000D314E3D7A2A01DFF0A39B7E7990FC7BABF +:1028100071979F70D7CAB9727021DC65E3C4FF035A +:1028200008E97101B048000000000000000000004D +:102830000000001800000000000000000000004040 +:102840000000000000000000000000280000000060 +:102850000000000000000010000000000000000068 +:102860000000002000000000000000000000001038 +:102870000000000000000000000000080000000050 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000000000000000018 +:1028C0000000000000000000000000000000000008 +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:1029200000000000000000000000000000000000A7 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000000000087 +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000000000000000000057 +:102980000000000000000000000000000000000047 +:102990000000000000000000000090000010000097 +:1029A0000000000800009008001000000000000275 +:1029B00000009000001000000000001000009DA822 +:1029C000000000000000000880000000000000007F +:1029D0000000000080000000000000000000000077 +:1029E000800000000000000000000000000091A036 +:1029F0000000000000000008000093C00001000477 +:102A000000000001000093C8000000000000000268 +:102A1000000093D00000000000000008000093D4E4 +:102A20000000000000000002000094980000000078 +:102A300000000008000093D8000800000000000813 +:102A400000009B3800400000000000400000941887 +:102A50000008000000000008000094580008000072 +:102A600000000008000094A800C8000000000098C2 +:102A700000009638009800000000002800009678BA +:102A800000980000000000280000C0000540003051 +:102A9000000005400000CB200008000000000001FD +:102AA0000000CB2100080000000000010000200809 +:102AB00000100000000000100000200000000000D6 +:102AC0000000000800009D600008000000000002F7 +:102AD00000009DA0000000000000000100000000B8 +:102AE00000000000000000000000000000000000E6 +:102AF00000000000000000000000000000000000D6 +:102B000080000000000000000000000080000000C5 +:102B10000000000000000000800000000000000035 +:102B20000000000080000000000000000000000025 +:102B30008000000000000000000000008000000095 +:102B40000000000000000000800000000000000005 +:102B500000000000800000000000000000000000F5 +:102B60008000000000000000000000008000000065 +:102B700000000000000000008000000000000000D5 +:102B800000000000800000000000000000000000C5 +:102B900080000000000000000000000000000000B5 +:102BA0000000000000000000000000000000000025 +:102BB0000000000000000000000000000000000015 +:102BC0000000000000000000000000000000000005 +:102BD0000000000000000000800000000000000075 +:102BE0000000000080000000000000000000000065 +:102BF0008000000000000000000000000000000055 +:102C00000000000000000000800000000000000044 +:102C10000000000080000000000000000000000034 +:102C20008000000000000000000000000000000024 +:102C30000000000000000000000000000000000094 +:102C40000000000000000000000000000000000084 +:102C50000000000000000000000000000000000074 +:102C60000000000000000000000000000000000064 +:102C700000000000000012C800800000000000807A +:102C80000000000100000000000000000000A000A3 +:102C9000071000000000071000001EC80000000020 +:102CA000000000080000AEC000080000000000089E +:102CB0000000AE4000080000000000080000AE80E8 +:102CC00000080000000000080000200800100000BC +:102CD00000000010000020000000000000000008BC +:102CE0000000A01007100040000000400000AF40AE +:102CF00000080000000000010000AF4100080000D3 +:102D00000000000100001ED00000000000000001D3 +:102D100000001ED8000000000000000200001EDAC3 +:102D20000000000000000002000012B000080000D7 +:102D3000000000088000000000000000000000000B +:102D40008000000000000000000000008000000083 +:102D500000000000000000008000000000000000F3 +:102D600000000000800000000000000000000000E3 +:102D70008000000000000000000000008000000053 +:102D800000000000000000008000000000000000C3 +:102D900000000000800000000000000000000000B3 +:102DA0000000000000000000000000000000000023 +:102DB0000000000000000000000000000000000013 +:102DC0000000000000000000000000000000000003 +:102DD0000000000000000000000000008000000073 +:102DE0000000000000000000800000000000000063 +:102DF00000000000000000000000000000000000D3 +:102E000080000000000000000000000080000000C2 +:102E10000000000000000000800000000000000032 +:102E20000000000080000000000000000000000022 +:102E30000000B00000180000000000180000B300FF +:102E400000400000000000400000B300004000020D +:102E5000000000010000B30100400002000000007B +:102E600000008000004000000000004080000000E2 +:102E7000000000000000000000008000000800408A +:102E8000000000040000800400080040000000046E +:102E90000000BB0000280000000000280000BC402B +:102EA00000100000000000100000880000800000FA +:102EB0000000008000008800000800800000000280 +:102EC00000008C000020000000000020000020080E +:102ED00000100000000000100000200000000000B2 +:102EE00000000008000011080008000000000008B1 +:102EF000000011680008000000000008000011A890 +:102F00000008000000000008000012700008000027 +:102F10000000000100001271000800000000000124 +:102F200000008D00001000040000000400001320C9 +:102F300000300018000000100000132800300018B6 +:102F400000000002800000000000000000000000FF +:102F5000800000000000000000000000000011E8F8 +:102F600000000000000000018000000000000000E0 +:102F700000000000800000000000000000000000D1 +:102F80008000000000000000000000008000000041 +:102F900000000000000000008000000000000000B1 +:102FA00000000000800000000000000000000000A1 +:102FB0000000000000000000000000000000000011 +:102FC0000000000000000000000000000000000001 +:102FD00000000000000000000000000000000000F1 +:102FE00080000000000000000000000080000000E1 +:102FF00000000000000000000000000000000000D1 +:103000000000000000008308008000000000008035 +:103010000000000100000000000000000000200887 +:103020000010000000000010000020000000000060 +:103030000000000800008D100008000000000008DB +:1030400000008D700008000000000008000084509F +:10305000046000280000046000008EA0000800004A +:103060000000000100008EA1000800000000000127 +:1030700000008408000800000000000800008448E8 +:10308000000000000000000100008DF400080000B6 +:103090000000000200008DF60008000000000002A1 +:1030A00000008E04001000000000000480000000FA +:1030B0000000000000000000800000000000000090 +:1030C0000000000080000000000000000000000080 +:1030D00000000000000000000000000000000000F0 +:1030E00000000000000000000000000000000000E0 +:1030F00000000000000000000000000000000000D0 +:1031000080000000000000000000000080000000BF +:1031100000000000000000000000000000000000AF +:10312000000000008000000000000000000000001F +:10313000800000000000000000000000800000008F +:1031400000000000000000008000000000000000FF +:1031500000000000000030000040000000000008F7 +:1031600000003008004000000000002800003390FC +:1031700001C0001000000008000032000020000024 +:1031800000000020000037200000000000000008C0 +:103190000000102006200038000000080000A000F9 +:1031A000000000000000200000003EA90000000018 +:1031B0000000000100003EC8000000000000000206 +:1031C00000001C4000E00008000000088000000033 +:1031D00000000000000000000000400000080000A7 +:1031E0000000000100004001000800000000000194 +:1031F00000004040000800040000000200004060A1 +:103200000008000400000004000040000008000066 +:10321000000000040000400400080000000000045A +:10322000000040400000000000000008000040488E +:103230000000000000000008000080000000000006 +:1032400000000010000050400001000400000001D8 +:1032500000005000000000000000002000005008A6 +:1032600000100000000000040000500C00100000DE +:1032700000000001000052C7000000000000000133 +:10328000000052C6000000000000000100003000F5 +:103290000030001800000004000030040030001866 +:1032A0000000000400003008003000180000000298 +:1032B0000000300A00300018000000020000300C4E +:1032C00000300018000000010000300D0030001830 +:1032D000000000010000300E003000180000000166 +:1032E000000030100030001800000004000030140E +:1032F00000300018000000040000500001000080B1 +:1033000000080004000050040100008000080004D0 +:103310000000000A000000000000000000005068EB +:1033200001000080000000010000506901000080E1 +:10333000000000010000506C01000080000000024D +:103340000000506E0100008000000002000050707C +:1033500001000080000000040000507401000080A3 +:103360000000000400005066010000800000000220 +:103370000000506401000080000000010000506067 +:103380000100008000000002000050620100008087 +:103390000000000200005050010000800000000406 +:1033A000000050540100008000000004000050584C +:1033B00001000080000000040000505C010000805B +:1033C000000000040000507C0100008000000001AB +:1033D0000000507D01000080000000010000401846 +:1033E00000100000000000040000409000100000E9 +:1033F00000000004000040980010000000000004DD +:103400000000411000000000000000020000411216 +:103410000000000000000002000041140000000055 +:103420000000000200004116000000000000000241 +:103430000000604000080000000000020000604240 +:1034400000080000000000020000604400080000C6 +:103450000000000400006080000800000000000878 +:10346000000060C00040000800000008000060008C +:1034700000080000000000020000600200080000D8 +:1034800000000001000060040008000000000002CD +:103490000000634000080000000000080000638096 +:1034A0000008000000000004000063840008000021 +:1034B00000000001000063C00008000000000002DE +:1034C000000063C400080000000000020000640067 +:1034D0000008000000000004000070000010000060 +:1034E0000000000400007004001000000000000450 +:1034F00000007008001000000000000400007000D0 +:103500000008000000000002000070020008000037 +:10351000000000010000700400080000000000022C +:10352000000070400008000000000002000070442D +:1035300000080000000000020000704600080000C3 +:1035400000000002000076480008000000000008AB +:10355000000070800008000000000002000070847D +:10356000000800000000000200007688000800004B +:10357000000000080000804000080000000000017A +:1035800000008041000800000000000100008042AF +:103590000008000000000001000080430008000057 +:1035A0000000000100008000000800000000000290 +:1035B00000008002000800000000000100008004FC +:1035C0000008000000000002000080C000080000A9 +:1035D00000000002000080C200080000000000029D +:1035E000000080C40008000000000002000080808D +:1035F00000080000000000010000808100080000B9 +:1036000000000001000080820008000000000001AE +:10361000000080830008000000000001000080849A +:103620000008000000000001000080850008000084 +:10363000000000010000808600080000000000017A +:1036400000006000000800000000000200006002AE +:1036500000080000000000010000600400080000F5 +:10366000000000020000604200C0001800000002DC +:103670000000604000C00018000000020000604C24 +:1036800000C00018000000080000604400C00018DE +:10369000000000080000605700C000180000000192 +:1036A0000000605400C000180000000200006056D6 +:1036B00000C0001800000001000066400008000083 +:1036C00000000008000066800008000000000008FC +:1036D000000066C000080000000000080000D94299 +:1036E00000180000000000020000DE4000000000A2 +:1036F000000000000000E0000000000000000004E6 +:103700000000DD4000000000000000040000DD4477 +:1037100000000000000000040000DD480000000080 +:10372000000000040000DD4C000000000000000468 +:103730000000DD5000000000000000040000DD5427 +:1037400000000000000000040000DD580000000040 +:10375000000000040000DD40000000000000002028 +:103760000000DA0000000000000000040000DA00A1 +:1037700000000000000000680000BB6000000000C6 +:10378000000000000000D000000000000000000465 +:103790000000B0C000000000000000040000B0C441 +:1037A00000000000000000040000B0C8000000009D +:1037B000000000040000B0C0000000000000001085 +:1037C0000000D6B000000000000000040000D6B4E5 +:1037D00000000000000000040000D6B80000000057 +:1037E000000000040000D6BC00000000000000043F +:1037F0000000D6B000000000000000100000D34818 +:1038000000000000000000080000D3580000000085 +:103810000000008000000010000000000000000018 +:103820000000D35800000000000000080000000065 +:0838300006020900000000007F +: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 deleted file mode 100644 index aef9aa622420..000000000000 --- a/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw.ihex +++ /dev/null @@ -1,15456 +0,0 @@ -: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 diff --git a/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex new file mode 100644 index 000000000000..8405e719e7fb --- /dev/null +++ b/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw.ihex @@ -0,0 +1,15473 @@ +:1000000000005310000000680000070C000053803F +:100010000000318000005A90000000B000008C18F1 +:100020000000C13400008CD0000000D800014E0850 +:100030000000F26400014EE800000074000241502C +:1000400000005250000241C8000000B40002942099 +:10005000000121EC000294D800000FFC0003B6C898 +:10006000000000040003C6C8020400480000000F9E +: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 +:10063000071D000034A216B0071D80002E7A23D9B2 +: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 +:10254000083007D80005043207340000322B0000A1 +:1025500007348000314B0C8B0735000038C518DE7E +:10256000073580002F90271007360000268F32F5A0 +:102570000836716031D40434023000BC00000030F1 +: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 +:1029A00008200780001004CD072400002AE400005E +:1029B0000724800027670ABA0824D35063FC04CF99 +: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 +:1044000002020104000000700728040000B300004D +:10441000082807B8000908DF072C000028CB000097 +:10442000072C8000365D0A33072D0000347017CB4F +:10443000072D80003A9424E8072E000036C7338EFB +:10444000072E80001CE94140082EC5D0274608E110 +: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 +:107E3000000000060001000100090206CCCCCCC9FC +: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 +:108D500073EE39E79E73EE8DEA0BC2C7CE05388EEF +: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 +:10B650000FE26106DF863CFCF13F58523CAB0080B4 +: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 +:101A8000952AECCE292EC84C225E78F674D12C64AF +:101A90001057913E3B9CDF617F98E0DCF10E08F12E +:101AA000A34B70DFDE17E77C7093C4FED2E626916D +:101AB0002F5E9CC6EBFAAAFB883DF728C1F52F6E76 +:101AC0005286117D0F4D8FE4115D168F793B5DC2FB +:101AD000799598F7B170DAF510F5FB56EF9AEBF8B7 +:101AE0007CA8B18DE63734BD6DFD7DA45F3E6B03F0 +:101AF000F21B1E1973FB128892CB9ED249BFA27AA9 +:101B0000DB25F39DBA1DE2F70CB04576B47FEB4FB1 +:101B10007AC5F354AFD5F433C0AAE7F91EFF0C55CC +:101B2000EC014CCE327F4F32D23FD1EF0B59E75907 +:101B3000430996C2FFC8EF8A6D37FD936F0EFD60B3 +:101B40000EF917A1359247F3389224EE517B4A7D66 +:101B5000BF233E3394FCBCB48E9F09FFC091343F39 +:101B6000DF23791BF9339D1FFFA5D6C5E9BB681F8D +:101B700051FA3F681F51FA3EDA47947E88F611A564 +:101B80008BCF60A7B87F3374E36DE6AFDDACA37B8A +:101B9000FE1230F5FBC4BFD3F49609FF92A643773B +:101BA000F6203C6896393EBAF85985F5D3932DA3B3 +:101BB000627E9714E9F530ADAFA4F98F3FA17BD6D3 +:101BC000254D8A2A69742FFB7436C71FC6CD8FE056 +:101BD00040E70D911D0EF17B4AE67CB7A7B5ADA796 +:101BE000F6DB9FCDA319D2398EC0C31DCE84BF377B +:101BF0006CC5DB3D3154E85FDF7346CAA2CF1FE3FB +:101C0000E3D3D80F3C86F0B9E00F344E60AF0C033D +:101C1000182F63FD1BFD74710FC14A8B7738384E46 +:101C200079FB8EFD575F89FDFD1F8FB61B3100804C +:101C3000000000001F8B080000000000000BCD7D9D +: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 +:104E2000D7F3A3F2CBB851F99E68FC2634FDE7D145 +:104E3000E4591820B4233BAA38B158988381410E15 +:104E400088353950C5F3A1E6D6002DE807E215AC48 +:104E500084CDFA2C05748F1C03C32920DD00C4D730 +:104E6000651918D8817C216906065F204E00E2CFC3 +:104E7000320C0CB380F43B20DE2A0DD1C707143B63 +:104E800027439EFBBB85C8D3378AA9831F28A1F27D +:104E900067683330DCD66160D0D683F0AF20C9BB01 +:104EA00003C5666A43D831AA0C0C877419184E28BA +:104EB00061373716287F18281FAB87DF7E572354AA +:104EC000FE2E6B54FE4F4354FE134F547E9F372AE1 +:104ED000BFD107420300BDE0D98DD8030000000018 +:104EE00000000000000000001F8B08000000000010 +:104EF000000BCD7D0D7C15D595F8998F376FDE674A +:104F000026C90B3C20C02404891AE8000182224EE5 +:104F100042B0C14DF181546997EA93B53622C81366 +:104F2000B1A6AE6D26DFE1AB8DE85656AD3E586DAD +:104F3000A9D51A2D6D6957DB04D0C52D8548A9B5B3 +:104F40002DFB6F50575B16D9E816755D5AFEF79C1E +:104F50003B93CC3C5E3EECC7CFC6ED0E77E67E9C25 +:104F60007BEE39E79EAF7B9F220640BF1CE01CFE14 +:104F7000B1E7452200CC197C462BA0542E07D8243B +:104F8000048D70117BFE415AD91566DFC08A2F9FB0 +:104F90003ED8EE5A10A8FEF3456DF13EF6BD63EA29 +:104FA00057E350C6EA4F14A8BE53CF79DE0812402B +:104FB000014049E76A35C1FAD934AE49C5FA1DFA4C +:104FC000F695C0C63B53A28084E315656FDFD6001B +:104FD000D03D0DE072D8AA16C758F998646C866C5B +:104FE000E314D1384ED91F17A1BB14E8EF1CFBDF27 +:104FF000A62F2621C1C66D9DFAD59508B7D27D335F +:10500000E811803BC6254167EF678248F3522A2C9E +:10501000305959D5ADB835FDFC713A102F65D86BB4 +:10502000677C7964F0FD32072F0C1F197801B804F2 +:10503000408359DD16960340ED33FB35EDF1B5F8AD +:10504000E8C63F7FFE7CFC19A0131E40ED8C272292 +:1050500083F06CF2F5774B0CDF5611188FB12A39BB +:105060006C9C4A573F99E30DCC53EEF4ACFF74842B +:10507000B380E621C8AEFE32E1996BD79BCB668E3A +:105080004F675E390BF83823F57F25A2B800EB7720 +:10509000C6AD888B1E65CB83F7A05D5F33BDF586FB +:1050A000C24F08F13307F163C5911E1D3A96C27ACB +:1050B000630D9B4F8105FD522E918D096300F2F126 +:1050C0005FAC89ACE99548AF634C56977D1F1BB325 +:1050D0001A25F67EDC82B420B367041ED2DE0801F6 +:1050E0004253728E1A599CEEBB6677F431BA3D0377 +:1050F00091CECDECD92CB37E116FC723E9C71848E8 +:105100008D97A51EE963E588254353398D4B7C783F +:10511000A77491B19991F4669BFE3B1A547AB63507 +:1051200068D0ED07686988D3F3FED097BE81FDD7BC +:105130005B7ECDCF9E72D7ED4F61B9192081E345DB +:1051400062BC7F9055ED310DCB6022DE2325FCF94A +:1051500012E285C1F9558649C4CB0F6D3CE9D04DAB +:10516000FCDA6C2CCF812CF8749EA1522F9F05F491 +:10517000206B3958F6C7F33C659F36DE531FA0906D +:10518000F04665262AEA042E8F22722F180827C3BC +:105190005756B960CB15499AD9DFCDE6179EA718A7 +:1051A000BB58D36D8297BFC6099C3ECA04959E31F9 +:1051B000E8DF7F0EF16288E9CD6CACE0CCE2AEEEC8 +:1051C000188EA91853D93A067D692D2F0B7F41B946 +:1051D0007CAACF81BBF8A3C78F24F5A41259C6FDC2 +:1051E000BDBD7E979F3DA222FFAB33C544BA0CE103 +:1051F000B5126CF2B05597459CF74707F7F0EB7581 +:10520000C2E6E73650A9BE8CEB553EB85E1D065B84 +:105210002FE49F72BE5E1DB2A58E66BD1E07F0E034 +:10522000253480972E8E97B28F182FCDFB5626B23D +:10523000CCA3CD5E4F190CA394F0A0E808E7D646A6 +:105240004EB716A3DB6CF277283C4839C7E3C9B2E6 +:10525000F3F17E8DC0C75964F38983A74D865893B7 +:105260000E239E3A6B506E6D2D1145944B1F159E6B +:105270001CB8360FC095E670957EB47049A1EE95C6 +:10528000D9F8B12D831FB720DC9CEE6A38DD891F69 +:1052900029DD397005901FF83A27F83ACB7F13EBD8 +:1052A000DC36B0CE49BECEF18F669D9DFD1C5463A9 +:1052B00025AE5B9DC6F890C1718B642937E0FE1A5C +:1052C00012E03183D101C23F8EE999E1A697751DA5 +:1052D000E03E21C0F50D69554ED2056F9DCC749608 +:1052E00059F87EEB05C961E601695F7F9F0327E3FB +:1052F000DFFAE38DED075C707E5188C408CE79300B +:105300000FE17C27BC3CA71B86EEEF6483DA28FB09 +:1053100000DE6BB0DA0FF8CEFF7E8B04A96CFAE5E5 +:1053200083B65C00B54BA1F9DFCD787026E2E1824F +:105330006A88B2F508378DC17940987D9CCFFAD93B +:105340001D68945DF81D6A3E037875DA3175C79F54 +:10535000777EFBA1DA7D20241F11187E5B63623506 +:10536000C2A596401AD7C0BF7B59F778181ADED667 +:10537000D85F06DE21D7CDAEF74EB8A90D58BB6673 +:105380009F71506774D252201A4D300887432FCE38 +:10539000BA38781CEDBAFC6680BEB65E01A467829E +:1053A0002ECDFCF3E9EA20D2D5C57F7DBA7AE36F32 +:1053B00097AE4E0A057FBB74A5D44BFAEBCCCE2832 +:1053C000924D2E27B5D516AD3F8ECDE492D439B38C +:1053D0001BE525C4997DC68701919515CDE47A2FEB +:1053E0001880FAAB5AE29593BE42AF9C8CAF34BBA7 +:1053F0009D7E37EB38AE42E3A27984E3CA61E80EC2 +:1054000044B1AC503F48CEE7A6303CC18335C5BC63 +:105410009D81ED869A8F8CEDD878A87E9C2BC276E4 +:105420007F9F93C862F70ECEDF3B4E7C452227114B +:10543000197D7D08CBFA1B2EBC0FDD4E86371CBCB8 +:1054400030FA2F453F49C120FECDDDB791FF220044 +:10545000A241765D619B855FDBF1FFCDC77D9FF348 +:10546000757BE12C0DF52D60FB0DBEB784CF039647 +:105470003F1074E25B673C299C00A21BBBDE48EB3B +:105480007F27F25316FE5E25727DE3BD2FA5FE1B1E +:10549000ED416BB3A03FC6F07AB8E17D788DF1E5C0 +:1054A000EAEE0B15F47B5C2F8EA17AAB1714298BD7 +:1054B0005CFDAC066E1702F4C9CB22EE711BB91E5F +:1054C000DA25EDC379BF5A21A571FF7BB5E27F488C +:1054D0003F7FD594D288E4573BAECE194EEE1C6E7A +:1054E000E0F6AC53EFB029D1FE7E58EE0B67D3E364 +:1054F00007C74FD3F8575548DE7D5AEE9371FDDF4D +:10550000FB22F8507F3EDCA00AAF4D65C62FCE933C +:10551000D1D1EA8A2205FD0E23CD6B89ED0773F008 +:10552000EBCCB3252CD23C5BC255E4B76AD1DE216B +:10553000FBF10C7B8FF26028781DBF558BB63C2B9E +:105540003E9408D7B7145F32BBBD69CFD72967FA3D +:10555000B31CF8DAC2DC2E6A0B73B8DA62621AF98D +:10556000BF2D9E7D5CE7D96CC3E7D46B8971BDB458 +:1055700085C993D1C02387BDF030B41D457FC94490 +:105580005BD6E4D7F6367E0EEDEC64D8940C7CD373 +:105590002B4C62E5097109366B6CDC9AAA8E6AC6DF +:1055A0000279AB122F3230602C7456A21F70F217A2 +:1055B00037F67C8DCD6BC27CBF86EDF26A523DCF53 +:1055C000B176E399989358BBB1C7D7AD4339FB4F38 +:1055D0006827A220B66E6A443F560B0E7109C0C3FD +:1055E000E2AA4AF4B3C9C0E502937ABA3C06FD3395 +:1055F00040CE99A1E403FB13CEF907DB0D85B788F4 +:105600002DAF68DE24AF960F2FAF36F2FE2DF61FBA +:10561000CA9B0983E351FB71758A078F6333BE1FF1 +:10562000B0E9D20FCBFEAAE38C87E501D44F222B41 +:10563000442D8DF5A12B17FD5063D6CAD08DDFCB3D +:105640003B1B99F81811EF4CEED570BF715258E61C +:1056500082F79722F7334DBAEB9820A0DFD7602A64 +:10566000FD4C2CD7CFCC46A7DB6DFA1C28D7AC1647 +:1056700092345E62C954946BB522D9BDFFB46256B0 +:10568000AEBBFDFBF63883EB0FBA3C17CB7CFDE5D8 +:1056900015A21998F1A7AFBFFC21D73F7FA3E2D98C +:1056A0004F3FECBAC8687B148CBCFE7FEE38CEBA94 +:1056B0009DCF1F5C3E4EBAAB3A80F2EFBEC4F07293 +:1056C000E5FC755B4EEB36660598E92C72252009E2 +:1056D0009E7DD579AA900283ADB3744C22F9268DB4 +:1056E0009DBB72270C3DAE145332EC37BB3FCBDC75 +:1056F0005FC2D6FF13E0FCF5CA28876A510EA15C91 +:105700002AF7BDEEF68F308C0F9619EEDFFAC2FE47 +:1057100003288F2C268FD07F9AF9BD16CB2E7AB80E +:1057200042E2FBEFBEEFFEE202818D73C4F0EB7E3E +:10573000F6EA90D0FB06F97D2B25DA8F113E752E07 +:10574000B607524E8E989259CDEAF7960BB48FFA5F +:10575000E1A5EBFE91DA8728DED1BBE0B52F5FCA69 +:10576000DA7FE2321F720EC704B68FB37FA25E7378 +:10577000B6EFCB97B2FA872ECB1F56DFAAC5F9BA80 +:10578000E8E4AA67BDE555486F08FF7FBC59FB20D8 +:105790001BEF08E424FCF8ACE0F01D41F890EEFBB0 +:1057A0007EF506EA85874D81FC51472A7E16437BAC +:1057B000BCD214485F5CBA4048FBB3CC73E982DBCF +:1057C000264F62FD258C901660DF0F55BEBDF55249 +:1057D00006EF553F90B6E1F3F45EA920593634BC8C +:1057E000CEFBAB4CEFFB01BD189216E21D341E97A9 +:1057F000F0C58CB89B5E07F418396166F3B7AD95B8 +:10580000B8FF51D00CD2EFE4B002388FA1EADF34F8 +:1058100004FDE6407FB7847038FAF7D9AB75B73C22 +:1058200074E050E44412C791340576A19E917B8DBB +:10583000EE9E7F83C4E34242DC2478148DC3A3C868 +:105840008699CDDF546FC3E3F403D069B7EF87BE09 +:10585000F0207CAD81C44AF45B58B9DC7FD812F1EA +:10586000FA03F7D8FD3CE6F4E783AC71158026EA2D +:10587000BF6A4C858AFD3757703D490783FCE32D8D +:10588000CC6E8461F4BAADB6BCD88CF10D3FC6398C +:10589000343BCE11E7FA53F819F2939D2913C9AEA0 +:1058A00019AA9F88E1D54742A55E3BC6D15F027A1F +:1058B0005E861FC8EBF7F18D914547EF437A1D09CE +:1058C000FE013DCFAED72EA7542D2B9ED2C3EA7337 +:1058D0007F3DFCF1F6215F97960DAEBF14DE1CBA3A +:1058E000CAEC5FC95752698ADB25E21E7DC09693D8 +:1058F0004ABE9AC27D01D4A1BE0779FB30FB8EF16E +:105900008C7042477F8A043C2EA4221FB8F0F3B665 +:10591000DDEED3B268EBF3298A830A7A8AFC766AD1 +:1059200021E31FE1FC76CEB3CF6EDFFE87DB5F2184 +:10593000FE2850893F049DF14F96719A24F394C438 +:105940009EB74AE65BF8F4FD514A66E393FFB2E581 +:105950008A5A9BD0D5628A2B923D92094740E6FD38 +:10596000DEE4C06FA5284E395AF8DF1F25FCCE387B +:105970000C7E592E20F87DF81C0A7EC986270FF46C +:105980004619E59ACEE52BC032DDAD97DC28737958 +:105990009167CB2780DBE26E7BEB7ABB9FD1CE2772 +:1059A0004F1EDD7C9C71D97C26C97C3D26CBC3ACC7 +:1059B000C7441B8E1B65BEDFA9D5093DCED6257712 +:1059C00008BA5A60C39192455BAFB8ED43D1D5C5D3 +:1059D000A39CC782C1759967AF4BC570F3986BCF15 +:1059E000A35382F9AFA35E3CC5F1F72CF7ACCB1DF6 +:1059F000367E3AFDCEBA6CF0ACCB2DF6BC463B9F62 +:105A0000C5767F23CDE78EC1755966CF67F970F3F0 +:105A100071D5BFD6AEBFD2AE4F76C71D726913DA4D +:105A2000194D5262955C30381EABF71977BDB79BA4 +:105A3000CF34DAF56EC0F7420DDFFF58BDD5EE7AF0 +:105A400060459BD03FD08AB602B3634A5A2EA9B2B2 +:105A5000DBD551BBDA81FE6FB6F983DA055A8426AD +:105A60002B4CF5D661BDC6457F74EADDEA85F76249 +:105A700007DE0D046FF5001CB7BBEB2D9027507FA0 +:105A8000E7C51D46E90FF2C5921D18E7CF834827E9 +:105A9000E679B4C9A947300FC0B264780CF309FCA9 +:105AA00086803EB66845EA1B582FD762F635AE5B56 +:105AB00055EA292C5B22249ACB299F80F205EA65BE +:105AC00055F31B987F61C00E56D662721AEDF356DD +:105AD0002169E1BEF85329F96599E4ABB6AA11FB37 +:105AE000CFD7B99E0E7DB46F3970DD13BA8EF21F19 +:105AF00072195CE88F6ACD80EBFED0A41EDC6FEFDC +:105B00002D50484F66065629CA973BA5A081FDF542 +:105B1000147C9EE0DDDEC8F31BB67FE2F304EF7D6C +:105B20000250DCF63E1FCF6FB8C7A76A4D1AF617B2 +:105B30001DF759CA87C8D1FCE5361C08DFDF1513ED +:105B40007CF9A055DE2890F8EA41FBB6B542217DEC +:105B5000797B6C5625F557A1929E7A5F625623E9B0 +:105B60001D1541F2D1E7870DB25BA3F314B0B01C51 +:105B7000331A51CF8CCC0D620E0CE417022617405D +:105B8000641AA4B1EC83CECE12F68C7630BB249F7F +:105B9000EC26B811EDDE0A8677B4232CF328DA253B +:105BA00061B0FFA44326CEDB374102F47B38EB1B08 +:105BB000ED1C683FACDD154D8FB25EF7E8EA453A63 +:105BC00098DD3F7B14F53A47592F3DCA7ADDBCDE9C +:105BD00088FE0E83DB7B2AFB0FEDB640A6DD1CF6AC +:105BE000DAC3BE8CEF99F1B8CC67663CE4A4EC8DC7 +:105BF000878CD4DE89838C345F744A0CC0298D5C19 +:105C0000DFD13787FAAE8CBF266EB2F6ADE33E1D0C +:105C100027B9366E157F4EB4DF4F5C69973F6D979D +:105C200057AD34B3C8F7B13E2E874BD11F329CDF3E +:105C300001B8FEF80683FD9C80C94BC3FB4F32F5CB +:105C4000DE4C79A7CA5615F2EBF604F76BFA9119F8 +:105C5000910F0B81FCB03E487596A09C0033BA783A +:105C6000CC20FFF8CC174CE4E7C3E324102A687D6E +:105C70000CF2A767D049265DF833FC397F2E9D7C56 +:105C8000CCE78DC7FEA5E844E99046C53F4AE72822 +:105C9000EBA54759AF7B74F5FC1DC2E8EA758EB2DF +:105CA0005E7A94F5BA79BDB6F90ADFCFE17B4D662D +:105CB0000983FB12D5536EBB24E8FD7E69D8536E71 +:105CC0009FA3D0FEEF94FD73554FB99DC979CFF7CF +:105CD00079612A6F6AEDAE625BD9A8F9E43FFF44AF +:105CE0003E295547F04B578819765B065FA97A0025 +:105CF000DBE7CB3A60FE547E8CEF53EC69A6B3E051 +:105D0000F7119BFF77C93C7F73BBAC07D07EFC5B70 +:105D10009F67A38FC3EBCC7724781DF9FBA664EBB8 +:105D20005B43E57D54F3BC4C1982949759526D56F0 +:105D3000994C2EC92FF2385866BFD729C9A77D2E96 +:105D40007B58D6923CBE67F7B7A44026BD44667226 +:105D50000DF51E05123545144714C9DF278747D8AE +:105D6000370A5D72AB7818B8ED3C56FAA40354FEBE +:105D7000968F1B3480E46B04FAC898CE41AD670A55 +:105D8000EA69BA00D4DE10B8FF7C8186FB5E2CF095 +:105D900097EE7715F52B98F7C0B9D087E857EE2323 +:105DA0007FE75FBCDF11E00D607EEFC5144288B96C +:105DB000F37B7DF114BD84B3E7CE49738137A1BF76 +:105DC00024C5D765D1207F288C8F925DD61ADBA0A1 +:105DD000BAD7F5FF7CC51EBF89A2B5DD2644D9B36D +:105DE00070ADD9370C9D9FC3600CFA470A6F34FB26 +:105DF00086D94F07E29918AFCFC2076D4A328DFAA4 +:105E0000BB3529CCED7939457EC676216FD6E67251 +:105E100017FD162ADD0857A4DCB4D0DE6BCF170DB2 +:105E2000D45365D8DA2BCC60EDA45A2399458F184A +:105E30006C2F9F74CF27A678F5A9E611E8BD7504ED +:105E4000BDC7A718C96CFED0690AB76B7DC1ECDF6E +:105E5000EF12AB4A9439E7E38DA9F9DCBECD850E8C +:105E6000E1639C7C28DFA1F08557100FAD0557C476 +:105E7000879B2F68DEBCCB9B4473A6323C1C73B25D +:105E8000C131DA7C10ADDA203A1CD097629CAE5159 +:105E90004F12C660BE07FFDB56BEAB1BF3407C371C +:105EA000F0B8AC64EE06F4533B7A9364064F88B4C2 +:105EB0009E0BB8FE54CAF52193FD87F3882E185E19 +:105EC000AF9632CACB14AF3ED4DCB017303EEFC031 +:105ED000EFF8F132E7758958756D767C8CCE1EBE71 +:105EE0008FD10B4CC378948A4881CE068DCA5F6EE1 +:105EF0008853796B834ECF9686527A6EC1A6F39102 +:105F0000CF531D450C6F1DF147E39F6555EE43D9F7 +:105F100041FBFE758B504FDE3C50666620837B3321 +:105F200006BC991E71BB72D522B4DF3707C0F62BB1 +:105F30002C5A647ACAD7345762D9F6336C6EBB9E3A +:105F4000EADF3711EC7310A6FA49D7BEF788E223CF +:105F5000FEC6BD85B7379BB1BF806C97E1B645DE05 +:105F60003298084F40E5E5FDCA06EA9F44001BEF62 +:105F700027CAED7CBCA9DC8F0F65CB47C023F7EBAC +:105F800083A273F9599647F92C8A61A0FB15EECBD1 +:105F9000B5E11E6D3F7292EF77C7B2EF97837C3306 +:105FA000C2BE66C331D2FA3374D87E88245838EE24 +:105FB000CF791CF1AF3DEE7DBE0F8717A5A2DFC2E2 +:105FC000F3230B94E4F791DE23665777112B476B8D +:105FD000BB2D62DF518E7BAFA2D9F34E12FF3B780F +:105FE00076F48EFFF279D7D11733290F2910E6FC0A +:105FF000375A78FB50BF9A33D80F3C51356E387DF5 +:10600000AD2021A21236202FF26B82688C0D947382 +:10601000CD3C4F39A762BCA77EC428F67CF7691730 +:1060200079BEFFA9EBF4F38C79FCBBAD373AE51FE1 +:1060300067CE7394FD3AE59EBE4562295B87976BF8 +:1060400025D2EF5EAE7DEDBED9584E4814BF3DB3AC +:10605000B2D9878C740CCCC81CF4872525DB9F6EC5 +:106060004E447CFE1CFFC9C67B09F73D269F8ED897 +:10607000E77F989C9888E79F8E5C366F22AEEB1185 +:106080001FE76FB03A493EFDCC071E79F0335BFE47 +:1060900018ED3B9AD10F794CE065A97DC7228BE2C0 +:1060A000835BDB3ECEF496AB390A6179AD90D51EA9 +:1060B00088F815C2C7074232E267F334ABF5D61849 +:1060C000E6BFE940FAAA1F12A497D5835529A2BEBC +:1060D000C3E88FE2DC727F6136BDE367F67EEE8750 +:1060E000AB49DF5F5E9BEB4363DE5F33D3877ED4D8 +:1060F000AB6B2A7D60EBCB9A0B3E3121D0F9A91511 +:10610000B5FE5D88D715B2E9CB16D7BA3AE1F7EC00 +:106110005333190E11FE63F6B90780FE4277BC694E +:10612000A69FDB3BF192E1ED05076EA7BCAC76E6DE +:10613000F38807866D3A8F026A7FE1751177BF2178 +:10614000272E1CC17E5F5EF90F7C7F6674817EC541 +:10615000174F7CCE4771D915F91EFE5B5E2D79E095 +:106160004F2C0879CAD7D45E9D33ACFE91F467C832 +:1061700033CB3E8729921CDE7C5C20F99033A93F0B +:106180008D799AF0B2045CFF73FCAF9790FF353ABB +:10619000A15F477D017E13D21E73C9CF169B2E8748 +:1061A0001AFF393FD76BE5BC1A8A6FBF7742D071AF +:1061B000BE425EFD349CAFAC984D386E4B9198C694 +:1061C000B8F79DC5DB555CEF4D251F4E0FF4C57824 +:1061D000BC5FB7B459C8FE43B54B9BFC1C41E6FB02 +:1061E000B57E1E6F69B5966B25B88C07B44A9C7F47 +:1061F000A010B29E3365F4BFD68F7EFB98053CBEDF +:106200009E20BDBA445D4D79B8F2F8E1E3B59978C6 +:1062100093ED386066BD276D7A2CA9D845FDBE7711 +:10622000E1F0FD3A7879DF10A1D7D627B0BE0A6C2D +:106230003E0CFF5B4A791E6E4BD9338467C9AC2490 +:106240007DD6A7A54CACB7A56C35D1652BAB93CF4C +:1062500086CEADEEA2739A5BFEC0E3134FB61F6805 +:1062600046FD614BCFCD807995C1781A507E6C99EF +:106270007E938A78D8B213A017E958EE22A75CC89B +:10628000F687873448334B0A426526A05CC8D3F8AA +:1062900099CA7DF12AC075DB520E06B2667E3AD5E8 +:1062A00088A19F2D711EFF0E969A354508F73891EB +:1062B000C4800EC90E2CB7D4CA348F368DE303EDDB +:1062C000AE734E7E17E6C19470BBAB04FDFBAC7F92 +:1062D000E58B7CDEFA8E12F2136DC97DD9447DD731 +:1062E000FA04185381EBB5A427C88C8EB0FF7A2D21 +:1062F000EBBA6F1593DFF2BBE2F7B2A60B48A79992 +:10630000F879CF0757E2BC5B668AB02B8BBEB1D75A +:10631000CFE3756963F955C559C679CEAF7BF204F1 +:10632000F4F715827BA8FA83F564F2EBA3E1B1845C +:10633000CDA3A086FB4B21E31C6B0C9264DF8E0582 +:10634000AB11F9D139BF3AA13AF1CB247B4A91156F +:10635000944F37D4795627CF7375852D9041BFF66A +:10636000D76CBE371FF401E2EDF2B38FBC80F95257 +:10637000BE0ABF46F955D0F902E66FDEC8D4312C0B +:10638000DF7C7CBA82F93F2F8F97303706F9278A56 +:1063900074F81688947FF6161C8DCE76D1F9297B79 +:1063A000DF41C98A72A43997CF4B0EB7F54A515CC9 +:1063B00077D9EA73F2F74861E279ED1066EF55CAD2 +:1063C0003E6A24F9D7C1F3859CFCC8CF767AF3875F +:1063D0003EB7C35BBE09968F41BEB989297469D6A1 +:1063E000EFCDEEBC2F36FE313FD70F3E07A936DC8E +:1063F0007FDAEDFC9875DF9FAE205DDF3C5B2BC242 +:106400007318CE3C7EEFE776E849C6A7BA8BFFD774 +:10641000C4D2949F9C39BFB7F62CEA4EB2F26BBA45 +:106420009CE276B6779EEDBEDEA598EF656DF3D95A +:106430007A8337CF71CDEE4A13F3C518F6F47C6F2B +:106440007B82FF1F3ABCF31D091F99F377F4C1A1AA +:10645000E6A3EC16B2E6FB85546FBE54B3CAE38DD7 +:1064600066B30C8185E79F8FB6AA5274BED96AF2D3 +:106470006BCD318A4F52FCAF9E110EC6F7CA559DA7 +:10648000FA792F30290D740E21350FF5A33FB7DFB0 +:10649000F92AE7C3BF74BF0B8780779DDAA7207FF7 +:1064A000AE973B6B84E2C1F301019F654E60F8F645 +:1064B000EF5DD63D013CF53A4659EF201E811E4561 +:1064C000BD1A7198FE4EDBFBD6BF3DF12F0AEEDF01 +:1064D0006F3D7E6229CAB95BFE550295D53BFD44EE +:1064E00004BA69DF492B2897D7EC9168FD41EE9EED +:1064F0007BB527DFBE99E67FCB5311DA1FD63CE38D +:106500004FD7B2F66BBEF7DA0C607C7BBAA9FF8579 +:106510000988BFC7059EC760F5CDB89ABD5F23C384 +:10652000F5D9F2106E50395F9DFA416825EEEFC241 +:10653000EE9EEBA8DFAE6B7D7E97FC5DA9727B9A29 +:10654000D533F1BBF54D213D55E0F065CBCB3BF5A7 +:106550004DEE4759B3D797C63CC535BB772A495648 +:106560006FFDEEB789BE173DF56414F1B07EAFF74D +:106570003CC22D4FFDA1ED92723AEFD45F8BF24FEA +:106580003A4BE533A6DACFF3E0B93FE656E2585688 +:10659000EF3B6F5EF16BF6FD645C82001329277B95 +:1065A000FF53F9572C27C32926CA58FFBE57DD7C55 +:1065B000B87EF76B74EE481399027B299E87C8F862 +:1065C0009E519FE9B90ACAC3F55D9BDE4679B97E43 +:1065D000CF5BBF42BA5B0FF2AB6E7E3E89FF18778E +:1065E0007E3C6B93EAF5D39D814373C901B03B3F79 +:1065F000ABBDE8C4B31CFEBEE5C9330FA31E71EAF0 +:1066000099FF7A18EF6758FBC7FF7918F35AE147EB +:10661000010DE5D6FAC77F1E0517FE1FB5E5C3E9D4 +:106620006F7EE3EB0F303C9CFEA59FB076FAB93746 +:1066300027E13D1DA79FFEDF31A87F6C7C6EF158DE +:10664000A4B38DDF5D3476B873A048B769BF7B7D96 +:10665000D3FC7E83BD026E8200CFDACF8C7581437E +:10666000FD0AEABDEF0AD0BF3997BDEFFA8382FA7F +:10667000CB0B26F4239EF6EF79ED85BB58F92DB6AA +:106680004EFE2CEBC4E63F41A4FD8DB10F7BDEBA7C +:10669000E7EAAB2E2BC7A7CFC0EED7433FED1BE7F2 +:1066A000ADEF31B6BEE583EB9BF9FD0C9C5510FFB9 +:1066B000EB9F60EB3903D795ADE78CF3D7F32DFC57 +:1066C000C7FCF3D773BFEAF5C79D81B58F3C801F28 +:1066D000F7E467B56F9DF55CF7DD4F0EAB973BF2C6 +:1066E00061243CD3F95E06D75754F3672AF2ED33A1 +:1066F000DFFAFA0331BECEB50C31A79F3C33090F48 +:106700006BFCD6D77F1DE2A1FF39BF867AD49AE70A +:106710007E417C77FABB2FD1B91EF61715D87E774C +:106720001A06FE8E022BDF2AF0C23ABDFF8A5FB145 +:106730007ED7B12E2C83D6EF8A5F95E3FAA9FDB4FC +:106740001EE965353ACADF7401CDFBD634E78F5BAD +:10675000D33D2BD09F9D89F748C0C9271C5C57F4B7 +:1067600097DEBAE7C415487F43ADA7337F0DE73FF7 +:106770008F7D7FD4CBBF43F2ABBDBEA777BEA7A0B2 +:106780007ED5FDAF8A26323BFFB4AF5F198FFBCDBC +:10679000D39286E78D33D77D10FF4D59CF1D673ECD +:1067A00033E9C31FC81EBF76F03412BF8F3CBF0F42 +:1067B00087BF33F63E9C89C75367B3EF075302DCAC +:1067C0009EBB153A6B50C5CCDCCF7C90B226140D25 +:1067D000C2DBD625919C3FB59BFB6932E5C5AD4335 +:1067E000D867339D71F6F6CC40B9766ADF0F6CBA84 +:1067F000E4747FEB132714CBDE1FD22EFCAE1FC236 +:10680000DF7DA9DDDFFA67B3F7B7FE89B7B3F677A7 +:106810005236AF45F84FF6FA282FE9649794D5CE53 +:106820009D1AF079F4AEB6C8DC5772583B291AA409 +:10683000BCABE626F317E827B58EFA6C3F80F15B18 +:10684000CCB76A8E04E99C7B73F426BA2FC9E9AFF2 +:1068500025034F723C41F6931C4B94F31858DA63AE +:10686000C7F81841B8E106D92A44BDFF70D19B3260 +:10687000F67B04F548975D7F4486D6FC723C172171 +:10688000188D90C5BF91D17F628104BADB4FD83D8E +:106890004EFC3D6BEF3F26A511B5F590EAA67301BE +:1068A00085D0F55896FE1E6AD0C97E2E4A5C4FFEF2 +:1068B0001F7F2A65A2BE56B8512B16F5A1C79D9819 +:1068C000F2C6AFC733CAFF3D8E73D047FA20EC7EC5 +:1068D000FCF1C7C7F02D05F5F217F0C9E4DFE57547 +:1068E0007A21961FB2E7CD7880CE314EB41232CAEB +:1068F0003921B64C46FD62712A21AF76ADE7E298A8 +:10690000301EF7D3F410F7407D3FC0F7CFC6C66BFB +:10691000288FFDC12F8A44D70F063E5E887C7620E3 +:10692000775E18FD6B3DEBE61E9AC6E09C10960064 +:106930004DCEFDE1E1CF6D3E6CFB1776D9F70F3DF3 +:106940006AE7977FDDC6DBEE86527A3EDE60D0F7DF +:10695000271A2AA8DCD55043CF671A12F43E7A577B +:106960003089F4B9A76125BD9F006F0BB8FEDF6BBE +:106970004852F9D1402EC13FF96E1093ECFD62C42C +:10698000477870DE0E3C69DBEEFE7EE0C72DC8174F +:106990000378CCC0F7E5D02BA8E8BF8A093AAE7BD4 +:1069A0007D40E779AE19F89DE4EF17302E577F3719 +:1069B000CF877858F09E77B8DF96FFDFB1F9F4DD26 +:1069C00068F2C9007BBE53B3A294F421D0CA906E82 +:1069D0001E1612478C22C2B3E7DCC9FABCE4770268 +:1069E0002EFFF0A40E6ED7EF08D8F26D2388486F03 +:1069F0001353A023BD39F3DE57A917A25CDC270887 +:106A0000B4DE486FA52E7A1BA0DF809D971CCFBEF9 +:106A10008F0FD22FE7FFF825A5F754235E3688E4C1 +:106A20000769C64FAE761FD874C4EC16D1427AAE51 +:106A300013C99F3BF9F8096112834FD7BE15C07B7C +:106A4000BBE293C0F637750590BE1EACE3FEC5AF42 +:106A50001DE7E798CE6C2C5E368DD55FCAF083C1FA +:106A6000A8BC25251EBFA5737EE16B6A22471BC605 +:106A7000BF9599F776FFE42FBD9FC3C699703CA4DC +:106A8000E379987B26FFA84761E5F17D02F993C67B +:106A90008753D3703D2BFFDF37C7F5B9D6E181753A +:106AA000A9C9A837B64DFEB6807C30FEEC8F05DC58 +:106AB000474AB4E49BB83E1364FB9CB09C9A87762B +:106AC000C1F57989DFE1FB4461FA53484F676A36C3 +:106AD000FE1BF6EFC421EBEBF5DC692EF990799EF5 +:106AE000E2A1D4F0FE4C67FE0FE1FC87A9E7CCDF02 +:106AF00059BF3335B1B5281733F199D96FDE9215E7 +:106B0000C38EFF907D8F189BBF3FE8926B85A93E97 +:106B100019DB39ED878ABB66CE77C04F34CA386D32 +:106B2000970FF2912E9EFEBF49DF3902483A0909BC +:106B3000FD53FB02C97108CF5C4851994947CA67A8 +:106B4000377239FF3E30E6EBE388EFE47411E57D00 +:106B50008C72BC5648242A719F334423DB3E303D5F +:106B6000C8E97E01A4C83F2A86EE1E3ECE5FE88DAE +:106B7000F36F059A0458DDAA1DFF0059437FD841E1 +:106B800098857EC8FC20E7F74A99DB97B30FEA3B6C +:106B900025EEB79296455CF8B3FD763EDE3583FB75 +:106BA0006ED0743CF735B34770F1EB7BA1E4C220A3 +:106BB000ABAFC4B93FD2174BD279CBC55258247F63 +:106BC0006E2797FFF590502FE47119C079EB1017DD +:106BD00071BF7F68233FDFAE6B2182FBA1984EE53A +:106BE0007A5B4FF9B14D473FB0E5FEF76D7AF92E6C +:106BF000CA7DA49B3EF3400E83EB3BB6FC7FDA9646 +:106C0000FF4FD9F27FCEB13EF86639C96303F39ED8 +:106C1000BFBC3DDE84D37CB2C1A47ABB1AEAE8B91A +:106C20003F77ACB897D57B74A3B80BF9F9516DECED +:106C30009578DF55DA140D81357EC8DABE28CAE0B2 +:106C4000DFA90A143F7BB82145ED76AA7A938AF131 +:106C500014662D5B4806F5BD14F6A8FC6DBF56C33F +:106C6000EA7DAD33EF4A8CC3DD5B23533B878FF462 +:106C7000391BB03944F3FC4164ABBC826E750ADA4F +:106C8000E91B45EAE72B81CFA88BD873E2C4A3EABE +:106C9000C7755C8C13668A7D5FC4908CF3A8E8EBA3 +:106CA000B3B05CF27A98F2B5E7BED2074FB3725137 +:106CB0005D84CA132D2F5F4CDFD367753238269E53 +:106CC000E2DFABF37E6775B1FA391BA2D45FD5EB77 +:106CD0007D02D2B3AFDC7BFE6A87EF97FB236CFCAF +:106CE000D8A1848078DB27688B3025C4FA143F7FD5 +:106CF00033F62054E1FB787409ADC3F66011D1CFAF +:106D0000D75A8EC66F463C6D8CB5A099B37FE3060B +:106D10003A9FE0DFB891EB4129EEFF9E78C701E191 +:106D2000732EF950D82267F5DB6D0FFA799C64E376 +:106D30008AC4340EDE8130EA7B25DC5F59D45AEDFB +:106D4000C96B72E2231F08C9ED41B29B789C44D6FF +:106D500052F4FE32097545F6FA4E91EB4989DE8010 +:106D6000DB0FA3DFC1EF67CB8463575026385AACE3 +:106D7000EA3A9417DBE6287200E19866DFCF62C733 +:106D80002107F63121B9CB2DD7648DC33591A132BE +:106D9000847077F77EAA8BF5F37ECAD9C7CC20E939 +:106DA00049F788C41F5BCBF939C0FDC63BDD78CFFE +:106DB00085C34FAD8648FCBB5D16D202EB677B797D +:106DC00071EE85483F31DCBD69BE2AE2B944F6F177 +:106DD0001C0E30F7A15FDC8F7E71B6DE25C743271E +:106DE00044F2FF79F3BF8B2CEFFA8BF5DE73771348 +:106DF00099D2E3CE57064634037446FB6BF5BEFFCB +:106E0000407E5819223A03CB8C568EC1F445FB4F75 +:106E1000AAA5F3CF2519E70C1EB0EDF787ED738413 +:106E200070F63640B9F5807DFEFA81B5625067781C +:106E300079DE3A4AFBE6C4FAEE4A0ACC687E4F7E17 +:106E4000B5FF6EAD09F7D7A294374FA832232FA80C +:106E5000E4CFCCB33E1EF4DAA9FB4E060DBC0F2FD7 +:106E60007D4C32509FFDF25DB349FE596BB8DE9206 +:106E7000AECB7B00CFBBE40B60E07BA75FC77E7D22 +:106E80002798477C939ECFBEE730B912E95A5287C4 +:106E9000EB05395A530CCF43DF09DFC6FEEBF8FA96 +:106EA000571602DDAF5318033AE7CC9E9B2F40FEE6 +:106EB000DF28624C1CCEA19C4739AEF6BE88EF732A +:106EC000AF14E9FE9CA216EB429CE7BE4BC68F476F +:106ED000FAD81AE6E75E9A851468086F01E7879D7D +:106EE000916ECA07DD562342135214C3A581FDAC2F +:106EF0000EEEA23C1684770ED11DE95D18A3407EEC +:106F0000B46E08F27DE7AC7521FA95A3A1BEAEFD83 +:106F1000AC9F70BB62EC62FDECACF4DE533735C461 +:106F2000F7BB404870E2FB81107B9A5B81F216D977 +:106F30005C88BF195F5940FB8246769513DF8FEE60 +:106F40005B22164DE7CF6217FFEEB2E56CDACE5B3F +:106F500078D8DE3F1C7DE301DB6ED86AEF1B45E687 +:106F6000554D0AD26D1DCC443C95ACED125667B31D +:106F7000EF3BBC7235935F2667F24BCA7B4E75427E +:106F80005DB1E77BC4B8C8F39D4231B8EE6CFF46F3 +:106F90003CB707CA24D4FB6643C274CB95A1F6FF65 +:106FA000FCA03923F421F49F68289142FD3353FF5C +:106FB000BED45E97EB0289F9B81ED14B56521ECF54 +:106FC000BA40E252EA5F4E0B284F1760BB58567822 +:106FD00029F96B14F0567F18784136E83CD79D921A +:106FE000739FADF73C1764DC5F9B793FEDC2FFBB3D +:106FF0009BEEA76D1598A287E51CFB7E5A3FBF9FAD +:10700000B635C2EDAE563B8FEA561B0FD787F87DDB +:10701000AF6B6D3A5D18CA7EFF91E3F74AA16CC071 +:107020007A63B3DF3B861A15F6B77042F6EFA91004 +:107030008F3B2E9C3CFC381B701CD6CFDCA0B92E9D +:10704000E4F2AFCC0E99EBDDE5DB43767E919C203C +:10705000BDD294F97E5814343786E6B8F06B3FF30E +:107060009694D379BE33F6793ED66E87407895B440 +:10707000D1E0DDD1FF5B05FD1E92833F677A5F960D +:10708000F5782F18B5C49CC17894A31FED0E717BC1 +:1070900092D1DB263E8F34E5418741BF07EF8198CF +:1070A00080F770EBE85738FEF0BFA0BCBDACB70668 +:1070B000F5A7753F94E87EBBF3F0B596D19D2B1FE5 +:1070C000C5793FFEFD0964074F9692F7875CF6F19C +:1070D000F8BA7E05E91DE1AFE6F0F3FC69217D21F8 +:1070E000B70780E238AD37C73DF98499F6481EDE10 +:1070F0007340724521BD2E132EC79E70CA99E711A9 +:107100000EDB74847FFA18BC271CB8322B9B12F25A +:10711000D71C48D2731EE8F464764B17CE83F19FD8 +:107120008E703685265D8AF3F82BE2ED47A1397F14 +:107130007B7873E8B82879F9001D67BBFFFAFE5029 +:1071400094E46DFDF108E9FDD17D5F20BA96185DEC +:10715000076283F932F560E7D187A10BF5DEA264FF +:10716000039D0B3DC3E818FB95347E8E55062D819B +:10717000711B29C6F9C327976AA2867159CB8F79EB +:1071800007563118286BD11FE986B73C9C7CD38DFC +:10719000C73B8FDF43F2F6BA40F224AEE79D259657 +:1071A0001F353B971C3EE596C3028475E4BF856797 +:1071B000F97E5999D465A487458CD311EF8B214969 +:1071C000E58F8345CF2590A6E7DFE19546A4C7D993 +:1071D000E716BAAF15DDE71606F2B9CB9D7C0E1E99 +:1071E000A72AB0E9106C3BF5F995CB1B17B3F1D981 +:1071F000E29B188FFAEA4A9ECFE39F27D3F9D58204 +:10720000BE1B6A314E042BB85EE6E441E4D57AF544 +:10721000B4F3EEB73AFEBBE3D82EF39C9CA3AF6564 +:10722000EE5BCE33535FCB0B673F3F39D4BE931930 +:1072300057A8C77F72FBD5B6AB1339EE7BE3339FFC +:10724000871BFA5B0EB8F2CC8FE0FD4659F7011EA2 +:10725000EF8DEEFB5DED8A72BA5FCEC094C9DE861B +:10726000EE85AF4F1DB483130B729F477F74A23A14 +:107270007796C4F0BE34FE6ECB817C806566CFC24B +:10728000D75DF3ECD518B459F48481F14CDF07EEE7 +:10729000FDF72D85CB97567BBC881D1F6B172D3FA7 +:1072A000F1ABED7FFB7D21B7D31DFB3EDB7C5B08A3 +:1072B0005F7D61A487A1E6FB0F61BE9F8E5969D0F7 +:1072C0007DF9CDF67DF9CD139DFC2D43437DF2A6CE +:1072D000702EBFAF205C42F1D5E69EF9E44F2E3808 +:1072E000E4237FFA981549C172ED8BF73670FFEBF6 +:1072F00057987E87F9205B985E87E57D957355B436 +:10730000176E8FCCA278EDE606C3932FE23CF13ED8 +:10731000BAA4CBBFD79CA8D230DEDB523B4B45BBD7 +:1073200043FA443995E50B677556317EFECCD61984 +:107330005714605CA28CDF47763D2B3796303B3A82 +:10734000CCF7D9C3C6EB61C453555877E887D6D17B +:10735000B72269FA502EC4B52ACC9571DE834D5FF1 +:10736000EC3DE9D76F29C99BC36CFE87ED7BB1DA91 +:107370009554E986323C17CF040EFA8955EE27441E +:107380003A68993D08F7061BBF97D8E33281243E3F +:10739000ED5A3F25CED7AF5D84BA6CEB737798EB8F +:1073A000372D9AA90D4B479AFC81E7FED0F218CFF2 +:1073B000CF8F313A72F1F3F9F4CEF9A93C9C680908 +:1073C00017A05C84D214CD3F4CF287DA4983F7587A +:1073D000C6C36607D63B9A6BEB2F853C0F9ABDDF81 +:1073E0009243F34B917C77F4C17699EB73A3D50765 +:1073F000F3966C247DF01DC65A649F7D6223C9ED0F +:107400008D3E95EEFFDBB740A67856740A5CEFB66A +:107410005BA4887DFF7F84FBE5F17712D2D3B8DED1 +:1074200083E73CA221A0732EFD13797E693BECAC6F +:107430009942F04DD5DCFB59E544EE67D85615ACC2 +:1074400073FB1B16E6F278D98BB995BFC3F9978504 +:10745000D355C89A176BD087F93450C5CF8F09859B +:10746000FC9C8D0F0C95F36BB586F7860A90A4F300 +:107470006743AE1F78EF177D5C4E3705116F31EE15 +:10748000D789EC1028694FEA32BBF1EC4E7BEEF263 +:107490001F223D32B967207FF7CC0D92BDF76E8F6A +:1074A00042F6E7BB37C3AFD19FF4AE2F072CB654DB +:1074B0003F12C55F3FC5E6DBCF987517E67F69FCD5 +:1074C000FBCCAD02F99B7EF4417002D2BB110511D9 +:1074D0007FCF6229D32778922084303E1B5D04DD64 +:1074E0009763FB9E30E1CF17FFC9C2D767D3FE1366 +:1074F000122BF0BC96F820CEFF9938E461FBD9FF3F +:107500005B25A1FFCAD187BEAA258F22DEE6815561 +:10751000D7C3DA6F53387F6DCB53D218A79C552051 +:10752000921E02BE507A2AFBBEF4E0EBD598DFB97A +:10753000B46226D6C4F169BD4BB4E4719C77B5B68C +:10754000AC3A97D52F3FA693FCBD227EDB012CCF12 +:107550003DCECB3E3FD7E3518F719F0F58FAFE24AB +:107560009AD79B61AECFB6C4CD5E531896AF32EEBC +:10757000E5F59E2F70E8806DEB3AE6A5D3BF75A2C6 +:107580008BA44F1CF43F4185619F3F71E8C1143EBD +:107590000C3DEC09F37DA11DF3CD6283F966EDB6D8 +:1075A000FE36DA7CB34C7ECA5B22D33ABCC3F42DE0 +:1075B000BCCFE37C3EB98DEEFFCCE42707CECDE512 +:1075C000793194C30EDF68F3EE26B9ECBF41A1FB1D +:1075D0004C1D3E72F8E7D29C013EBA0FE5C58AB059 +:1075E000BE98A76898E0E693AB47E0ABA5D07F20B4 +:1075F000C6CA4B65B07298083A3CFFB725935C7CCD +:107600009289CFA50B0478D5230779D9856F6DE0D2 +:107610001EE02C76F250EB7254E6E71E1C3EC5DFEE +:1076200063C1F3631DA201B81FB5E7AE36226CDD5E +:10763000E4DADCB5C80F5B84440AF92132EF54E880 +:107640002686F777C7302D12FD87FAEAA788DF5F15 +:1076500009915DB66DEE1A8A4BBD7B737232EE2FC7 +:107660009B18DE5FA5FD3C3D56A45CDBBEB13C6FC4 +:10767000428FF36732CEDF83FD3D6D974DBB5E1FBA +:10768000D563EBEB919B3F8D723EF86994EF539B72 +:10769000944E15E9A1BF48D5B2E52BA722BCFEE563 +:1076A0007E28C7FB18D968941FD0AA4A353BC95910 +:1076B000C2E5C4E5534A77B9CF5739EDEE6DE822FC +:1076C000BD6653C35E7AE6D7A601F3E882A5968E1F +:1076D000FA87FAC74502EEC770118FCBE3FB4697D6 +:1076E0005EF7695BBEAB785F101B4F6DB274F7FD40 +:1076F000B4AA2864BD47E84894FB89D526A0EFEAE0 +:10770000BE7FA6FC85FC1243F82C969B3AE9F765F0 +:1077100002DDFC7DACC4146E74F51BABEDF2ECA382 +:10772000AAD82793DD540F9A8546A0DC578DFEB961 +:107730008EE5C14ECC6BCEA437FC7BD54537EA1F16 +:10774000AF26FD098E72FDB5BA58253A6FAD577652 +:10775000A2FFEFF7B12ACA67EF88089EFC02E7890B +:10776000F177A611923FCDF2F338BC358DC7E1B168 +:107770008C71787C621C1E9F1887C7EF1887C7F230 +:10778000B71B4C2A633C1ECB188FC732C6E1B18CA5 +:10779000F1777CEE6DA8A3E70F1B52F4FDD9867A32 +:1077A0002A5F6ECB5728E5BF07D6F105C5C4FCA9F3 +:1077B0006E7B7DF69BCBEB7E86FE42881AB8AF07C8 +:1077C0000E35BDF2EF7699EEC98E17E7A3FF126270 +:1077D0002260DCA12DBE9DE9A283F30BC8F7824E87 +:1077E0007177AB0EF31EBFB1ADF70A99E91F25F112 +:1077F000DBAAF258F9C96D2FB7619EE9057AE3CA91 +:107800009DAEB21E99B5E6696DB03CB96CA71C641B +:10781000DF9F89FCB20DE54520C6F5C367B7FD9A29 +:10782000F4C3EE62A600A1BC2B52D248EF37E23A75 +:107830004DC579F07CEEBF83E638E6F94DD6955913 +:10784000C8A7AC7E37E78F51D6C760CD9CF3DB0D60 +:10785000574F2C1F553D3AA73B643DF65D18A69F38 +:107860005668D67A19EC5B7C7C1FB60AB89FB8C301 +:10787000C7E54347803FA7E438F90D55CDD102CC89 +:10788000FBE17CDC11E0F713F44F17E9777BA05E96 +:10789000F87BECE7F3E341C3FCC859D38BF3D14E3B +:1078A000F8854D0F532747F8FEFE8F2AEDEF1F9FF7 +:1078B000FC644B1E2B4FFD17C3C0FD7A0B1841947F +:1078C00027D6562E4FBE553E256F19AB7EF19CEF45 +:1078D000E6A17E3CCF964F69DB8E696CBD6932DADA +:1078E00011EFBEC4E5E31BB67CD9E9EB4DD17ACEEE +:1078F00009D3790B804ED25F1AE332E58989E3F828 +:1079000053F1699FA6FB335B15BAAF49F9C33C95A8 +:10791000FCAEEFFBEDFB8A7B49AF5102492D97BDD1 +:10792000EFB444F253346BC134DE9BB5253C8B7EFF +:10793000BFC12A93296EB6A58CC77F42916BE85EC2 +:10794000ACAFF404A87E6B58A57CE174D99E835536 +:10795000317C8A1AEA07697339DD636969A246795D +:10796000C7EC5FF47D6D8CFC4174FE18BFAFE5F190 +:107970000ADFD843546EFEA446FD839DDF4F2A9A4A +:1079800088BF2791E8F1DE4BDBFF938FA1BF640D29 +:107990003FBF32435BDEF31CFBDE62AA8962C60F87 +:1079A000ADDA3BFB42585E05144F0D4D7FBD298477 +:1079B000F56FD40C9EAFC5CF4B807D0F724BD98A2B +:1079C0009EFFC0FE578660AA81F5AB55E4576881DB +:1079D00017F0DEAA428288BDCF9D25A0DED65A4B85 +:1079E000D77332F8BCE70C5AF2AE54916EA4A57965 +:1079F000344E2B982AD6B76A65DA3F0BC36A37FA3A +:107A0000170A6DFF84230FF253AEF306EC7FE3D722 +:107A1000CA9EF308636FF4960B32EEE12DB7E927A7 +:107A2000136F99F3CC8F3D938BF0E4AFA59313E7DD +:107A3000C17F6F6CD6329CD7386D9FB0B39C4C1F02 +:107A40004DC77BC821D5E8CED7F873E19D51D6D27A +:107A50008BF4304397416778F918F43761FF5B6C1A +:107A6000FAEF28F2EEE3BFB0ED1FC6A76BA37330A9 +:107A7000EE2182E5EA1FE322960B9E291D799EF2F4 +:107A8000D4CEF19EFAD376147BBE5F98BEC8F3FDC8 +:107A9000E2DDB33CE5E95D9778EA7F6C6F95A73C42 +:107AA000B3FB4A4FFDD907977BCA737A3FEDA93FD5 +:107AB000EF95D59EEFF3FBD678BE5FFADB0D9EF215 +:107AC00065FD7779EA3BFA7FE6BE795394CBA30F45 +:107AD000ABF7E3EF03B9CF1D67DA15E7DDAFF3C707 +:107AE000661DE38410E5F7E9CAB8BFB3F2862F70CC +:107AF000FB4C5D68E8286F5645B97C5D9F67DE8E5C +:107B0000F2B532AAD23E2187793D397C05E923932B +:107B1000763039359BECB681EF18AFEE68B016962B +:107B2000B8FC5A01AD13304FAC325A43F70A3AED64 +:107B300065CD04CC9F5B15D5B91EC4AC5EBA2F4091 +:107B400067ED5DF36276225D31D1CFEC48D4FF075B +:107B5000EC443987E2C3CC4E243BD20872BB11CE31 +:107B60004AF4DDF88A40F7F8333B90ECC867C2CCA2 +:107B70008E9C89765BDF169443FD3F9529DEC8FE17 +:107B8000C84E2C6776E2E65CB7BFBCAF089F69D0F1 +:107B9000C6E3B347E916C71691DDF8CF48CF9FD9A2 +:107BA000F8521DF63BBD9CDFBFD731A6368EFA7466 +:107BB000475117F1497F91CCF7213951EAF6031E5D +:107BC000B0F7AB90FA2DB257D93A905C76D6618B6C +:107BD000D097C67B0EAD2F04C92F3EE937FEA3C850 +:107BE0006F6AB13A01F3048DFD8A89E3DD6BE3B975 +:107BF000589B59853F0759125FB60F9F17E84C1FD6 +:107C000061CFD2D27BF6E1F37B51327AE122E3E914 +:107C10002A9431EA42EEDF966728E92601FDD20C6C +:107C20008E2CF689F394A23BF8BD4025F21B487FC9 +:107C3000681D9C6353A8CC5329BE1C40BA10E84968 +:107C4000F4149043B4BF04F0B02A962B843486C455 +:107C5000507FC5BCD1CABC1D44078E5E8BFA6E92A4 +:107C6000DBD10790DE62B5DEF50FA9DF263CB5D883 +:107C7000E7A23B72F543556CDC8E82E23CF4EDA248 +:107C8000DF65994BFE1CB4F7DD477344474F20F97D +:107C9000B30073190A06F522C60F3BC429086F8288 +:107CA000E2F0814312D9FD81BB3BE97758039AA5E5 +:107CB00003E9FF968EFD5617AF243FE1FFC466919E +:107CC0001E1CA8FF5156BC05FA2430670F8DCFE863 +:107CD000050F903E0063823AEEB3F5B1A0B9338B45 +:107CE0007D5017B1ED9F498EDF3341E7625BD12FA5 +:107CF00017C6AD4D15319FE7F69F1678EC9ADB0B52 +:107D0000B81F73A8F103CC1E4DBAE0DBC4FA4539A5 +:107D1000DE7A76590DDDBB8ADB4C399E1B2DDB49A3 +:107D2000FEFCB3CD3AE67DD5D9784D61320FC3DF85 +:107D3000240516ED447992C7F42386D24ADBFFE28C +:107D4000F86926E6F0F8BF6181C4FD773E67DF126F +:107D5000CFE17D353AE8CA5CFB2A005281F9BEC604 +:107D6000FEAF07CF0F4EE970ED7380FB81B73C6D1E +:107D700087B77C61DA5B665AF4CBA807AC00E0FEFB +:107D80008FDDDEEF61307D186F19EFDCB39FE0E728 +:107D900009550601D2775957BAE76B6C7E09E73E61 +:107DA000CC8C7BF5A7EF4993FE7295FDBB1F99F72D +:107DB000BD8FC7DF019941F3F2ECA3B37C12F92523 +:107DC000D09F64B8FC49259AEEB1AB1CBF50A65CAD +:107DD0000F1EBF07D817B2EB937EBC37552B43FF5E +:107DE000435BE1977E73A27CD00FD326A7DE3C4194 +:107DF0007E4EA67FC5B89F04FDD7B7FFF48EFF3E29 +:107E0000E1F267BE1B4DCE46BFC7FD93797BE75EAF +:107E100055E7DCDF3B35F2F382CEE148BAE0B8B398 +:107E2000D4FA385757D2E3D08FE4F8611C7FC3F5FA +:107E30007926E9E75B8CA3A9FDACDFAA5FFA01FB19 +:107E4000592C1D3AD880F26EA24C7925DABCB58F38 +:107E500004D1EF89DF59B9AA481F4BFCF1A28FFC6E +:107E60000EED36DF3BE7571DBF4D2287F347AD6D63 +:107E70000FB09906ED731B41D4932FDECDD6D0B34E +:107E80001F72BFA1E31F9CDEE5FD7E111E0527FFCB +:107E9000E84ECA8332E6F33CA8312BD3FB709D3FFA +:107EA00066AF33C6B72AE70EC659C7AE4AEF433DA1 +:107EB00074869DCF54F6E2F3F493BF20154A485FD1 +:107EC00017611E136B671C903DE746C68040F94062 +:107ED000638E49469AF533E359EFF73270958B106C +:107EE0003E6F39337EC5D4ADB76F10F0F7535302F0 +:107EF000CAB3ADAB988DC0CAEB72EC3CA40BE002E8 +:107F0000A4DBC552D8C0FBF536FC5CA23C64FF89FB +:107F100069BFC0382ABCC4F32EB5293C2EABFD4442 +:107F2000329804042D0433678607E35D5F3D67E004 +:107F30005DFB037EB4C7D9BAE33EF404B3FB4B7CCC +:107F400068C76B54EE62763F969F61763F3EF7308E +:107F5000BB1FDF7F8FD9FD58DECBEC7E7CFE90D936 +:107F6000FDF8FE5966F763F9C5DCCA2D397330BEDA +:107F7000554AF4149CB987F21EDB559F86F4932969 +:107F8000CF2A2B6F575730FC6E0E2FA6784BD56239 +:107F90009E77BF256731D9D303FEBC0C7FE8A07F55 +:107FA000AF4F70FC7B78043A6EDBB3037ED2A44102 +:107FB000F71B8CDC8FE9F4437ED6F3FAB1FDAD6F8D +:107FC0007DE1575F6F669FD6CDD9DE112CC6733F1A +:107FD00029FEDDCE3FCCFCDDAD757B1A291F501983 +:107FE000772C85EBBAA73C4CFA06FE2E13CAED4C53 +:107FF0003BD1B10F33F571E799B91F66E6CB446CFD +:10800000BD64A4FC8D6DBE14C5B7AD46265F70BFC0 +:1080100068482F7CDD77BE7F77B29697714E99E7DF +:1080200067F90FF2BCBD0E486AEEF93BE723C8E6DC +:108030002BE67E46B77F375892A6FB1B826193F4EE +:108040004581E991A4576A498A17B60DF1FBDAA771 +:108050006C39D138EE1ADAEFDB5EF491BE556DE77C +:10806000C9358F53A9DC3C6E6E9CF22B2373D5BEB1 +:108070002CFD6C88140FBBBF4A6CFFD787D9FF2536 +:108080003F3F17D6BC6FBE8AE7A73AC2AB7BD16E23 +:10809000EF88C7284ED0336EAEE77E72295E41F777 +:1080A000594861AE674B7195F46C19E75F3658DF3C +:1080B000A9773087D30F6373F26306C29D54CF2F25 +:1080C000274CF4B7F8633C0FD9AFF1B862B0440461 +:1080D00035CB798D1EDB2FDE5196D4D0AFD31197DF +:1080E000E9DC47873E6BA8B82CBFEF42F3FA079B49 +:1080F0006DBF43739D427A61A23E57ABCEA7730B0F +:108100006790CF3BC24D2AC669FF3F82909C4F00CB +:10811000800000001F8B080000000000000BCD7DD8 +:108120000B7C14D5B9F8999DD9577637996437C91E +:10813000E6C90402060DB8818487C6380991A222D7 +:108140002E0235B4B42C0414E415D1B6ABD5B2214B +:10815000098F2025581F282DDD50B02FBD8D96DEAC +:1081600052ABFD6F04B9A8A8A97A15FDA146B43E8B +:10817000EECF6A04BDC547FFFCBFEF3B33C9CE64F9 +:108180003604B5F77FB1653833E7F19DEF7CEFF347 +:108190009DB38EBCCA60CCC758CB3FC5862E2F3C42 +:1081A0008B18EB8127934219AC9C318F2C3096CDE4 +:1081B000D869FC73317CEF76ABAC129ECB1C717727 +:1081C0000963E168454EFD44C6166685990CF51CA9 +:1081D000BEC5720CDADB1953B13FBD9DFE0C627F48 +:1081E000558C89F26F6BDEF20FFEAE3FC5F41D2C8D +:1081F0008270944A6FF7BA18B3294C386D8332F302 +:10820000CA6F9FC7E8CF6911FFEE09867DA9FBF110 +:10821000B9FEADE6AD8983DBAD2AEF75880A639BB5 +:10822000F7748419943F131482CBCE626A01CC6B2D +:10823000F5FEEB5904E6BF55EA71C900C7D62F8495 +:1082400085E1F2C1FD2FD3F003088B219CF0C776A6 +:10825000FA7CF85B618A63126305F866243EF9775D +:1082600018A5FB34F45F91807299060FFC7FE261E0 +:1082700063B9AAC7589E7CD458662C640F8F63ECF0 +:108280008575D0E9398CCD39F6DE3196CED8DC58FB +:10829000E8F147038CE5ABAE705C666C1E0B3DFEEF +:1082A0002A940B1A3C2C1182C16D6C19AE0B4CF345 +:1082B000A55280AF8111ACAC60591A63AE81FEBF8C +:1082C0002B67123E1A7A17CD64E319FBF1CD2D8C82 +:1082D000413FB13A21BE17E09F5DBF67F62878DEC7 +:1082E0005B692BBA0F1B45EC6FE1FC5CD0D9699838 +:1082F0006FA6EDFA1123A17E789A4768817A3FBE76 +:10830000E0DCCDA550EE993E3A8478077CBDD53FA0 +:108310001FC0FFBC306FAF8FFF6CE589B9A3E0B918 +:10832000B3F2A1D9F89C935C1FFA9B35A5B3D90190 +:10833000FD5DB9529980FD85EB8DED0BAA8D6580B1 +:108340009CD609E7EBCF1A0CEF99E0318FAFF777A6 +:10835000EF3A85F0CFBE007A007C86F113B40F4B64 +:108360007D5208F09C5F2DA871A09B0255503B2DBB +:10837000F8619B463F66FC8BB10C867C56374F8C70 +:10838000B743957C979DF09F3F53882B307EFEB27C +:10839000BEC469287FD3658F8BF03D2BB34BC0EFF4 +:1083A000F7AE64ACA384C04BAF4D5ADF7B5D6DF676 +:1083B00062F83E2F4F6436A003563D8AC6233846E6 +:1083C000123E8E737CB8081F052B438FFF0CC6BF6F +:1083D0007A8A5316A1FED50DFCBB0EDF5609E80CB8 +:1083E000BE6F053A8B119D49C793F133E7D8AA5563 +:1083F000488F734CEFC7CA8CE8EAEF538F8E29067B +:10840000B856091D333C008ADBDEC4182E346010D8 +:10841000E95AE7471D4FABF635133F26F199FD3476 +:10842000F233FE3B8750437CF698EBF732CA8DBFA0 +:1084300064F6EE6440C2BF9059ACBE9AB1FF93D6C9 +:10844000779E00E5DF74346CDA74117C77F7FD9663 +:108450005530E6DCF89D19338A06CA69EDCB67CC46 +:10846000B808FBE3E3C014627CBDFBC725FAE893C0 +:10847000397C5B54B65D84B26493B7874A06DA658B +:10848000613B61887661B65DB268E7D5DB019E36F7 +:10849000C0FAA569F34AD3BEDB347892C797106F50 +:1084A000B2E215603DA4E9928CF4F255E1C839D3EB +:1084B000BC236CBB7DD4E0760076B30EBFCD1AFE34 +:1084C000387E4F1EDF3E04FC5F373ECED49F43FB19 +:1084D0007ED6F041F5F539A9E78B70D9515F298A2D +:1084E000D796D4CFB6EE4F9F3A1F88579ACF426E99 +:1084F000E843B2AB7208E8BC5CBEC3859D4B99F5FE +:108500007204F86133945578BFB9ABC3A5C0FBF2D0 +:10851000D2DB3721D19727D218CA83714CCEBC1F2A +:10852000FA1D274B2C81AB76D1419B07CAEC0A166A +:108530001A0DFD6674A7913CC92CB9E017028C9BFB +:1085400099E952B1BD2773D22F18D10753A4247CC7 +:10855000786A5FA8F3205CB35908595112E2AC164F +:10856000996C2C637BA19C79C91E560FE5097FF796 +:108570002922F2B4C4F55D3BB6473DDDCA0EA17EAB +:10858000C9D3E4CF2687BC9DF4C7751243FDE1191A +:10859000778780F0DC0B5D89C097E5E559B3EBA1E7 +:1085A0005C7EC41652149C4F87508CF3098AA4B782 +:1085B000747CEA7264C24709CEF463597C2FC0DF31 +:1085C0006A8F27505EC5A65E2DEF0578F29724C905 +:1085D0006BFCAB0F7080F03E7DD5DEF612A46FE928 +:1085E000ADE4FE323E8A27509EB1DA8630B60FCC1B +:1085F000940CF23F4D936769263DD09A65273AD196 +:10860000F50153254586790BDABCD98FC2A40F9C9E +:108610002CE47290BDB280EC1081F50AA73D307F4A +:10862000AC887017F1790C6A3F89B767C1900BED80 +:108630001C675A5313D6878F59CD805CE1BA341525 +:10864000F5B3E060AEBC09306F1B8B74019D340B39 +:108650004CC2F2C0780986E3395D9E56B4BB1E73E6 +:10866000B5D8107F2D87417FC03C36DA19B7FFE4BB +:10867000902B0BDA4735FB6D6DC5C85C2C67E4E8C1 +:1086800076615846BA5C9B5D9A8BF661BABFF7DBA0 +:108690002867676EFFE30C17CAD53AA87301E89DF7 +:1086A000CC8736C540EE3A4F153025C9CE734A4DBA +:1086B0000CED29E7A962C3FBC43A98D1390365D50B +:1086C0006BABC771D6642A84D75A26B762BB5A40AF +:1086D0008692B42ECE53794C9968D57FA1E17D0264 +:1086E000EC24C5399CFE3D4C294BEE7F548AFEC7D5 +:1086F00098FA972DFB1FE8D76FE8B74D626447C71C +:10870000025E5A77B35DB031B3EEC64CB4479DAC50 +:10871000A9CBC2EEDC906923BADB186CEA51A17DCB +:108720001D03C6073AB9F88BE322237B06560AE8F5 +:1087300085154A7DFD743C12EB71FAB5C50486724D +:10874000E962C96EE0931A662C9BEDA27361AD11CC +:108750005F365F650FD2CFDAEC34C56901BFFEEC3E +:1087600059C76A4A47C37CD3C2CB18F0F1CFB71FB1 +:1087700076B505A19CCEE9E481EDAFCE88C1FC7A47 +:10878000044E7F6D011BE1255C97DB2926F51B76E6 +:10879000B0D12817C348DF5E0E0F8EDF935DB8BBE4 +:1087A000DD627C10BB06FB61B62AD49426CDAB47B4 +:1087B000B383FBC79B56D0897CD03F9E9355D1781D +:1087C00022E03F79BC9C2F37DE5F717EE503E3CD6D +:1087D0009E6E9CDF6C874CF39BADF1AF3EDE5F710C +:1087E0007E255F623C9C5FF278DF30CE6FB653A689 +:1087F000F9CD16397DF58F97F3E5C6EB59574676D7 +:10880000F04607C827A093B48A7DAE5130EE469754 +:108810005D16948176B5B537B8E6A2EEF54E9B9E0F +:108820000DE3D45D0295F3B19769D36B4B19DB2E41 +:1088300070BAE8CBFCAF4DE8479E9CB9B68CF48982 +:10884000665F5F8955411F5F29717867157AE3CDAF +:108850004978BC17E4880A70FC14F85D057EDC05D5 +:108860007C89E5F8BA203D7783BD8ECF3D002F7E11 +:10887000BF6F5D88CABF5A37859E7A3F6553B8DDA2 +:108880003EB6DADA6E3F2F8BDBEDDBF3E4F94B50CB +:10889000AFD5A685502FB229173235D9AE664D8F88 +:1088A000B9E1FBD66FB20AD48D637670B803F5399F +:1088B00064B7A7551CEC5907E58D925D41BDBC51CD +:1088C0006133ACFCE631A867603CA793B7671772C9 +:1088D0003F2C10EE3D887A6F0EDAE980D7ECB9BDF7 +:1088E00007D1FFBB0AEC72D2CBEC8D83AFC2F71776 +:1088F000C0FF6BC7B2E865329467CDC9A6F1E14FFE +:108900007A6D0EDAEFFCCF4F669E20BF22ECE67A3E +:1089100021C0663FDE8DF0861C4A9CFA6377869103 +:108920000F54BBD24EA2206C473D9D8D7A1ABED704 +:10893000BEE1643684EF1207C9B5B9738D7EC37684 +:10894000774246FB677B45803543FF57CD347E77C2 +:108950003A39BF854D7EC32C5319AC2DAE77C50572 +:108960001968EF6FC4575307E32D7AAC79E3C1243C +:108970003A55B27C81B73DB8106C0CCAB34F58F968 +:10898000B67AFC589845C68AB9FD3FD6C5361E044E +:10899000D4BF80720FE5AD83CB8DC1FCC1E1A9D1FD +:1089A000E4E3BDEB7A6ADE1A3D005FBE1417500F98 +:1089B000142C83F749F395027101FD1D26DE5F81BA +:1089C000FE8D791EF70AF7E7318BF1F4673E93DEEF +:1089D00046BCE052A23C37CFB766D07CAB9F2D653A +:1089E00056FCA46C477B6ED66131D4AC0CE0439F3F +:1089F000FFFF345FBDABE19BA90196007A7916E8D1 +:108A0000BD9DFB310CED549D5EA102D94F575E090F +:108A1000DF912E54B508F1F9ECC8BE3DD7603B900C +:108A20001D2DE8EFEA7650E2651BDA415FB6DF2BD9 +:108A3000AF7390BDC558BDFC76D9407FA9D607FB62 +:108A40007D3B497FF6DB89F8679226FA10C6E6502F +:108A500090EC819BC03E467F3F5AFF9E94CEBF1F45 +:108A60004FB253F1CFF1A4FE5ABA7F2D280057E739 +:108A7000BAAE9AB7EC03E3962C936D6D68CF35C709 +:108A8000058A4324A01ED803239729B656C0FF1297 +:108A9000EC07E9D324D747B6423FC9764AF55CF9DB +:108AA0007EA087D6F2BA8E103C37EFE0F132BD7E61 +:108AB0007FDC2C1023FFDCCE9A9800703ADC3FFA62 +:108AC000792FCC476D9198BB06CA766EEFB0577D73 +:108AD0002417446FD32FF17B3006720BE75DD7F478 +:108AE0003B2CC76C2CDC02CFBB3DBC7D5472C94E05 +:108AF00058BF76B975064E3F272F726F168CD796E2 +:108B0000934672D0F19A6F37CA2947E6846568F7B1 +:108B10002C88FE308CF148D9CF16862DE86B816603 +:108B20003FECD5E8EC983D519409704FCFABDB9BFF +:108B30005565513FFA23EAAF46B4B6C31ED5FAD9FC +:108B400069B3960BFF9EC5E39D57AF7AE8BDFB6006 +:108B50003E9E526F08C96DF3F96C9F601B5CBF3B72 +:108B60003BF287ACA478ABBB5496280ECABAA6A237 +:108B70003DB7F9F39F76FD0E509EF5B997E46C96DC +:108B8000E88B0B2586F68F26CF436FFF974F5F0C40 +:108B9000E2FAFCC5CD48BFB2D8D397AA18D7D4CB38 +:108BA000F046C072A65EFEEDA5E86F0E94AFB9B4B4 +:108BB00016CB48BB409435FEE866D4CF5B05A611C2 +:108BC000F14DBCBE9DD72FD4BED75CF6FE2FB6A10B +:108BD0003E98E4203F74AB6607E9F0A97E91F0A3CC +:108BE000FA87C6E36B1A9E5DC3C7E36B567838906D +:108BF000A7BE8EF875B32E01E9D8FDB9EB466C7FA0 +:108C0000CF3A165E02B0EF54F6FD7A9B42EDDFB626 +:108C10005A87F3F3D477B2088EE3BFD80670F8749E +:108C20003826B31B53C0F1E150EBF9A71C2EE7BE69 +:108C300015E0CF2CCDDE74387A82B3E12957DE758A +:108C4000830CF2664349578355FCF9333FF70332EF +:108C500053C4DB037E4E7FDDB9E1D30847ABFC9004 +:108C60000BC74F135818EB6F99D2CB84A47E4301E6 +:108C70008E6780DBE987766953998A74E663BE382C +:108C8000033AF35572F8B7045F600AB4F395C1D3A1 +:108C90008BEF7B89FFD1E5E0F400820ECA0E8D3E9A +:108CA00002FEAD97A29D9F25EAF457D48EF4E2B060 +:108CB00069F563459761B9338B9727DD51D41E2B36 +:108CC000043DE380362817F21D64EF98E75718E05B +:108CD000F3DB96ADE6FBB32DF0E9ECA575DA3ACE01 +:108CE000118AC1BAD6D87A1A1AF1DB655EB2D7E01A +:108CF0007D433C69FE976BF8BADCCFEDADAD9FBA12 +:108D00001AE216EB918A4E276AEDCF824E27FA2D92 +:108D1000E803E8B412F19F44A71F336B3ABDD06F4C +:108D200041E740A7D5F8DE8C0F735964EA8E450001 +:108D3000A0F4D9F45F6D436D7579F58EDFC1B3E6AC +:108D400073AFE4873AE2184676A2CDC5E5FB80DC36 +:108D50008F5C86704B7213BD17BD61DAAF792E2B15 +:108D600045BF9327ED40B9358C7EE721DCE67E4B8D +:108D7000FD8CD6A3E6326F246E81F77FFA256E1F35 +:108D80000778BD54FC322E60A3EF29F945A7FFDC1C +:108D9000F05284E34CFC523FC02FAB86C72FFB88B8 +:108DA0005F3CE59C5F3C29F80523D1289F3794F070 +:108DB000F28FFCB9C40FFDFCC3CAE87B3FFFB0B221 +:108DC000CBB0ACF3CF658132AA6F6E9F8EF3B6C085 +:108DD0004B9B5F9F47B815D7553D4F6E15C9DEE8D1 +:108DE0006528A73A595FB713F9B05A08ED85B7B3AC +:108DF000623DF52E05BFF7B0D9607F6CD5E87E17D0 +:108E0000C283FED0242D9E25F5B0AB7C83F9D857C4 +:108E100099288B24E17FA486C76F07C277E0F89D6D +:108E2000AC772CDAA5A9D6E91E6DBC9B82EA3D562B +:108E30007C7F26BDF328EA9D6C7CF27EB23E7735BE +:108E4000A11C30F379CDEA87DFBB6F887E1ED6F098 +:108E5000F6D0D9F3FD4329F8FEF726BEAF14465AE3 +:108E6000F2FDC329F8FECF567CFF15F8FC3FACF8A5 +:108E7000BCD33F3C3CBB035CBFBBB5F5FDB2787EC9 +:108E800047C3EFEBFEB3B6035EB7C213E0B9779802 +:108E9000787EC76A9D00CFEFFA69BD6D31DC17405F +:108EA0007E47FF7DD3E4581FEE875AC0D197DC8FF1 +:108EB0004BE1FD8069FFB100745EF3D9A650C48216 +:108EC0002FA1DD3F92E1D7DBDDE397B5B8B3723D6B +:108ED000DAD53B2FF7F2FD846CF5732B7EF80AEBA5 +:108EE000EF0C58C8E31A1B9743DFF6BF4576DE57F1 +:108EF000E8DF6FD5FF331A7D9D49FF8F49D2FFD838 +:108F00008F59DE75321E4FD9961D290910BE7A2F52 +:108F100045F9B4EBE62C01FDBA423521A0FD9FAF27 +:108F20008D77BB5F21FAD2DBED92128284F59B64D0 +:108F3000212618FA3B6FA8FECC70007CE30324DFE7 +:108F4000D4F3F1798FA6CFCED61EBA30A84E0E70CC +:108F5000393D15C757CF31CA697D1EB67017EB452D +:108F6000FD02EE77DC82AEF2357D09FDD4513F9AE9 +:108F7000BCBF20206BFE29EFEF6CF50DC07739F6F2 +:108F800007FD5E61059F192F6782F3960138AF0ECA +:108F900058E825737FBA7FADAF13E9D3A4B8CE12DA +:108FA0008D5E80AF1A113E579B2DC60203FCABEBC2 +:108FB0006B904C69D8FF4E078FA3EE5C797B2DE652 +:108FC0001B74DE2257204AF297713DA7AC2CA6B83D +:108FD000EA6AAD5F33FCFDED1D5D632796D3B86B88 +:108FE00071DC8BAB5902E54606DA09147F90258CBB +:108FF0002F64393B821897DD2C74342C463D7AA9B6 +:1090000097F42D0BCEB58C4FE94F3DFEA4CF9B05B9 +:109010002BCF50BF99EACB9E8E26B493865DDFD9C5 +:10902000616957FD44B3AB607E3F1E12AFC100C5FE +:10903000B774FC0E1E87AF5F6DB849407CA795C31F +:1090400090C09269E10EDA6CB595C6592FDA4F657A +:10905000402FD4DF0B9671BF81FE36E8707522FD7C +:109060007C55B8F47AA9C7E3F570FF8CE21D5E2E3B +:10907000B7E803944F1CF65BEE1FE8CF8DEB645509 +:1090800002FD73425632305EB851D383E09905AF8A +:10909000F2FDEBEB0DCC23CEE39DA6FA51C6E99E83 +:1090A000055D64DF61183E996E8E6A74B02D27FCF1 +:1090B0007480E4482884740DE567495EBAA0ECA387 +:1090C000F25FA92CF7979FA7FA415E9FC9F2B0F013 +:1090D0000CED5EA176527F3FC7A8ECED1FF7351A65 +:1090E00027D05FEEA5EF85BCFE70C7495A573EFFFB +:1090F0001E91E6FFB1A466E0FEE837A38D14279A1F +:109100001F5D4ECF4DEBE45A8CC73DB3AEAFB515E6 +:109110009EDF9CDF28A3DD3F7FE94F68FF5EEFFF06 +:109120004AF42B90DF156906D94525B6F01EEF00ED +:10913000BF0DC0D1AAE9FBDE7AA42397CAFADA2BC5 +:10914000A0FD948F5A5B0D794E1D943FE356A4CF3A +:1091500092E3EABA1CFCBB433D1D383B3A36CD973F +:10916000B18330FEC7DED2788CE8BA4EB6E2177D06 +:10917000DEA9FAD7E79D4ACEE8F8D3DF6F2E9D200F +:10918000F3FC9FB8012FEED1F594EF73A5A0C1E9D0 +:109190007369FCC6EBCD82711E2A27FA50907E6758 +:1091A000697E9C592FE8E3FEDD1119938DEDE0CD2A +:1091B0002D132CF03B4CBC1D5DB72C5C6F4779DC4C +:1091C000E5A6FD7B26539C5FAFD79062FE75D95C08 +:1091D0008F30A74AF3D9726B461CED8E2D8BFE2083 +:1091E0006370C533EEE32ACCD7F4087D9F2C46F993 +:1091F00072AB8FF2311A167D52D59CD4FFC2037F19 +:109200007261BCB761DCFA6C8CBB2C64D2C7C9F943 +:109210000EE6711BA2AB896E63CD428395BF752CA0 +:1092200087F3F5424C9111A9BFE3C9FBC88B9409A0 +:109230000E8C4F2C8A19F77340433A903E1A379997 +:10924000DF27EDE788D83FA379C770330FF55E9B22 +:109250008DE86D27E00DFDC0625097F83C9693A510 +:10926000F1410FE1F35F0DCFB11C6E0F395D2CE6BC +:10927000C91AA09BDC480743FDE4AB14687F33E0C8 +:10928000D3F323BA484FDDE1D5CBA0B700FFE1729D +:10929000CDCE29E5DF6D5846FFC7D373D0067CDC01 +:1092A0009EFDF865C1B1D05F79246893A9FCA44400 +:1092B000F6212F33F6F89307C99E95CF1542C0FFCC +:1092C00052F793878BC89FD7ECB1EE27C91EEB2FBF +:1092D000B30483F974A6F597555710CA23FBCB3115 +:1092E0002CEFD2ECF8F6ECEE275BC93E09B7652708 +:1092F000E9EF5AC6E3CB5FB77EEC0C2EE9C07CA247 +:1093000058A98DFCBD34133F3E98EDA07A637223BB +:109310007767C373D62D7D12C61B1C792F04500EA0 +:109320008C283DA18E04FA1F51CDD36458191FB764 +:10933000B3742DD90D9DDABAC0FFD6A3DE1B589F9A +:109340001ED3FAF0F50857F6D0FAF8CA7B68BD6C60 +:1093500058A6B81FDF8FBFA292DB1BB293EF2BFC86 +:10936000269BC75DFF942D6A4FEE976694DE4EF103 +:109370001DF70C1BD5CFD09E6639FEA76CC9A05730 +:109380000EE445FE909D64B7C2FB705925CAB740F4 +:1093900016EEB3D6964A37223DFF5CF34F619DEE41 +:1093A000A0752A09A445F8BA3D62B96E65C35BB7DA +:1093B00017D745485EA55AB76FCE17C35671B76722 +:1093C000353C7CD0F0B7BB902D57B9FA1CB80FB321 +:1093D000B974BB21AFDAB56F760273A1F5BCEAF5BB +:1093E0009EF46A94DBE6715FFCE23F0288DF999F9E +:1093F0003A2DE5E37F6BF2F185750DD40E16589189 +:1094000072480E309EF7D29F27269C76D2F45EC417 +:109410003CB4EF12EB333637FC06ED572F0E8A0CB7 +:10942000F7C71732635E198BEA79C13C0FF645091D +:109430005C5340E18B31210498628BA4D9BA5C3132 +:10944000E487CD9B3BFB10EEC3376AFBF0205F0C3B +:10945000DF979AF2C6AE6E5814AED7BE9FA4BFE394 +:1094600034AFB90AB71BE77ABDA45FE785E787EB9E +:1094700093F6E35EFAA76899875E97A3E3251CAE8F +:109480001F3D182F8BC3824356CE8C1F333E6A2557 +:109490008EAF451ABECCF831E3A171EE6C5A7FF362 +:1094A000FC5F7485093F2F027E305FD88C0FC62287 +:1094B0005720DDBE345F64681F4F1767DA314FA055 +:1094C00071B6C030BF68290BA5F3FC6075D625497D +:1094D000F09AF168C657E3A32C94807E1BEFF4D179 +:1094E000FA3DA7E1474C7C48F30AC3BCDAF9BC8ECD +:1094F000F3FC5599E675955AF17800BE475A41DA62 +:109500002A567A84CF6731CCA75D1EAC4F3E61D519 +:109510004D48274B4D790B66F8CCF0CF4439387560 +:10952000F03EFEE41C5F80CE2F8C67216D1F3F83D1 +:109530008E3584B287CC5B18E0734E5F0BA3B3FB10 +:10954000C7C37E0516E92FCB80DF994FF8B7CE83CE +:109550007FAF0D8A0AE609CE9E3FAA0DE71F66E19E +:109560008C4409DAFB7D76942357313063A1DDC545 +:109570003049D4B7E17A3795F57E4F747C64273D46 +:109580001E614D7B69FF5DC9983B2EB57C591B74EC +:10959000D078663B6566C5E80C9417667CE878FA77 +:1095A000568E96DF309E8D3F1BBCF4A0EC457F1697 +:1095B000E368B08E7DCB19DB5D31B07FCC0A556E90 +:1095C0004FE630DAFF5F9D93A9D91D4D147758A05F +:1095D000E9856376D6F0A097EF234F48928F0BF37F +:1095E0006A57E724C5FBF47D642FEB25FC7DD7E5A6 +:1095F0004D88E389EEDEEFA70F925F7ABE6684F2B4 +:1096000035C58C950AC5C53CE9E35906D8C58CCF4C +:109610001BFC989B7230AEE7298EA31130F3895F53 +:109620006C9AA70CACDBE6257B3B105CF7D2DFC75E +:10963000A87385E77378B475ABD5D6ADDF8E2E836E +:10964000F749F83DD1A1D961655A1C1FFF40F94483 +:10965000A91A1FCA7FD5D7D15D06FE87218FB08397 +:10966000F0A7AF2738117DC89791A04439C336E6DB +:1096700022FF387213CFC758C8945D981FB4306A60 +:109680003F91DC4F244F2238229BDD5ADC2444FDDD +:109690002CCEE3FDB032EEE7F5D37D0CDA27E53FC3 +:1096A000DA5C604A62FB4C1642FF09FACB417DCF7F +:1096B00036258D3372F0B8A9FA33B713B5FD5BD1F7 +:1096C000190A8592E4F46F72B89E3C11ACECB28D2D +:1096D0004C8DBFC52EBF2A25E5C51ECF733558C595 +:1096E000C5F4FE74FDDD6F27C6963F956C277A376B +:1096F000343E75F8A2243B31D6F814C515F5F2595D +:10970000DA89CFDFD5F8542BCCEF1FAF7E83F2C7B9 +:109710004F3481C0043CFAA3D3D89B7E940F32E926 +:10972000AFE206F0A830F95B52C622BDBBA305AA82 +:1097300094942F7B2C4721B8FDA52AED9741D32E79 +:1097400074C5FD524840BCDDAEC5CD8070C7CEF6B5 +:1097500025B7E37E883E9ED325131C0E7D3C166AFA +:10976000A6FCFA998CF4889E07A2F3B5DECFBB392C +:10977000C678DD30F8F9DD9CAAC1FC2C8A4DAFDF3C +:109780008A72E22991FCB0EF046FA2F7E678C089F3 +:109790001C6E1F8E102327502EF4343CFF9D1F405B +:1097A000BB35FB9C2154C3ABBEFFDE8FAB14C4138F +:1097B0005FFFF94B1BEFACC2798D9664DADF28E2CC +:1097C000711847B340FEABBBC411DE07CFB703B57A +:1097D000237293E07A3B504FE59133385C27A0CF5A +:1097E0007605DB6D6F207FD1C7F7BD4F280A9DEF4F +:1097F000133D8CEC09D1C99F99B9DC2ECDCCE5780D +:10980000766B4FD729811609E9BA09F72DA418E517 +:1098100041BB4E49F4DE210896F69ADE9FEB140810 +:1098200067C497C7DCDE41EF713ED85EF433837DB9 +:10983000938FEDABF0C9E9DD75CAC3E1F09BFB493D +:10984000E7EF35FE33C37163CEB462C4CBDB017581 +:10985000442E8F6F7339EC7DF2A8307E38F298E792 +:10986000EB5F9127B928AE77AB101F0DF2A9BDECC5 +:10987000441BC9AD1257139E934AB29F047EEE86D5 +:109880009FAB18B04FFB2E995389D16BA6DC1B1AE6 +:109890006C6FBD5EF9C9BC3958D0CE4F7C5797BDAF +:1098A0003128833DF79A565CA48CDC80A1FE2BAB5B +:1098B000B97DD688F65988E496C1EE32DB675ED072 +:1098C000F773802E96062519E9C26CA7B557CE23EB +:1098D000BBA61DEC1ACCD71E6CA77179735BD4C6DE +:1098E00054A8F74CB5487EC63365BD4F5C8CFA6210 +:1098F0008A5D217D51D677DB1CFA3E91C6F16AFE66 +:109900001DD4E7E71D429EF86878F76CF59BDEC62C +:10991000A4F57E66CA9B63D12FD89522BF428FD310 +:109920001CBC99E77FBD7E87107722DE6E116DD853 +:10993000EFC20A1FE5AD5E227A699CC6AD62DC49C2 +:109940003854D32FC919B01B99589DF33CE2619B41 +:109950009DE1F9C1A21B7B0D76EEC2A8D19E8B348E +:1099600081FDA39CBD1D68B6FFCC76CCDA5CCDAE84 +:109970009BC026A0FDF2CCBAFDECCDD10376CCACD9 +:1099800014FBDFBA1D7381ADEEE65C1E17A4FD83E8 +:109990005992F5FEFE559A7FCA42DC1FBC447C9F5B +:1099A000D6EB444852107FDE9B9EA4731DDE7F8A57 +:1099B00061ABF1B6E7727F7C978391BCDD35C14323 +:1099C00079D7DD379F9BDB4BEBA5DC5D8DEBFFA4EF +:1099D0009DE4602AFDE68E8AAC1426E68B0AF4D458 +:1099E000D77344D4CD92F5C38814790ABB73B9DC1C +:1099F000CEBE85D9D0CFCE8C31D5CA2FD5EB813F05 +:109A00003A1D63D4503F9109F0AD2EB551DC5FF79C +:109A10004BDD767EDED7FEC8F531F44F47007C087B +:109A20008702F0A11C2E897AA83C32EAA7E7A86831 +:109A3000263D4BA305F47D7474143DC7444BE8FDEB +:109A400039D1F3A85C169D48CFB1D10A7A9E1BBDCF +:109A5000909EE781DEC27AE5D15A7A8E8B5E4EEF18 +:109A6000C747E7D0F3FCE86C7A86A2DFA6EF15D1F2 +:109A7000467A4E882EA2F713A32BA85C19BD81CA83 +:109A800055D1EBE93929FA437A4E8EB6D0734AB4F0 +:109A900099EA4D8D6EA1F205D19FD0F3C2E8767A96 +:109AA000564777D2779D9F3D9A3DFD74708F4CF954 +:109AB000F62C518EF231151FBEA1E9856FE4AA4F35 +:109AC000A03CD5EB1DD1CE1D98EBBD9A3B74DECDED +:109AD000D15C4E9F1F848EDF85C769F575DB1C1C2A +:109AE0003A8EC0CA0367D8B7E2F33B9CCBDBEF9258 +:109AF0003AC8DED8D5C4281FCC57D923503E43508E +:109B00009A61454799417EBE6B4C6EE45D9CA737D8 +:109B1000EFAD83B81F7565AC27300DE92514489B60 +:109B200006FD8D68B5917BAD3059C0B252CFE404CB +:109B30001B88E7807D65D06BEEA04D8BFFF4CC9C3D +:109B400088F09C5B3A81EC576D3FF9C8CD2319FA38 +:109B50001DBB1C09414279B996B1643B7CD786C5CF +:109B6000F7259FD370071D9C8F36B1C7304E56D254 +:109B7000A1D4E179C2513BD4C730C573743C52972C +:109B800006E5737E157B0C9F63BBE2751E789EB75E +:109B90003FF118BA4FE312BD755E289F7F981DC034 +:109BA000F053458F32CD07E58947D503B84D52D5DF +:109BB0001B9996AE203CF196748067D76B60684124 +:109BC00079CAFB1D22B82503EB0F76DB8349EBE254 +:109BD0002EED5145F867E18D7205CAD95D52AF3B54 +:109BE000B37CF0FA74E2BC719EA057F66AFBE8728F +:109BF000D27A5405053D1E9817AC1A880776B63EF2 +:109C000047F1C0CE34B916435D7D973079B7827481 +:109C1000CCFD84B4B691A49F74BA03FC1AEC49B786 +:109C2000D6EFAE7E7BD31ABF55FFCBF07B50A3E7B8 +:109C300054F87D1AE79177663E9E1EE47615F07122 +:109C40005D303B75BD15412E4FCD78DE25C9E7123D +:109C5000BEBCCC16AB1858B76B34FA3E135E23FF6C +:109C6000CBF07A517068BCB24A3F8F336BF969A967 +:109C7000E4CD9114E744BEA7E13149CEF178A90CB7 +:109C8000726E546A39578B70650F21BF52E43BAC3A +:109C9000D7E8BB3B3B1C0B669F39AE7F9B4DAEC5E7 +:109CA0007C97D878467E02D897AD98BF3322A64CD1 +:109CB000A06D2C14CA88C709E7919F5E02F686340E +:109CC0008161AA63029F575466DA1697635E83C662 +:109CD0006FF2A26032BFE9FA7E801F75BAC8EAA4AB +:109CE000731640AF984FD8ADE169A01F1E8FD87092 +:109CF000537E677B921CEC0C155059AF9F8A7E5F98 +:109D0000D7E9B7F539DAEFBFA2DA3ADFE4CF41514C +:109D1000CB3BEA5391CE63354CA6F3CEADC7493E5B +:109D200065827C124A787808C72F8CA6DD8771DAA5 +:109D30008783399A3F2EA77DD3F7FF8F9EB781AFD8 +:109D40004E7E66B5DC8DE72A46801E52504E560385 +:109D5000EC95A8E71CB4EE0AE3EBA854B3784220D4 +:109D6000BC25D06F8ED9F8F98C238E2E95F48E23D6 +:109D700053C6FC93EEECC813C121F842F62815B87F +:109D8000A8AF0457CDF4E6615E8E9C86E597A07C73 +:109D9000DB14CC13EA655AF936EFD42F1F7F7865B0 +:109DA000C78A23B84F7561503D8AF0005DBF827449 +:109DB000AD9E234B141F1EE6FE93CE9F03FC24573B +:109DC000E8FCB4A89CE4E15BC1A4FDAC54F6CD2E44 +:109DD0004D7E7E121CDABED1E9FEACED1B0DDE37E6 +:109DE00035B9948AFF673EF1FC8E3D6C20FEE7CBCF +:109DF0007FB14752D0DE9EC6DE9C8871AF1E4EF703 +:109E00008CC7F9548CFF011DB82B5DA6B8AD30434B +:109E10008BBB0C19AFD5E3C97ABC4F8FEBA56B7424 +:109E2000851706A01E4F9F224B8BA9BF5E7615E6B5 +:109E300037E5D90C7C8D720BF7E75D6D59D2C8F20E +:109E4000817E196B2239D5D9C0E4F64CBEFF9A0148 +:109E5000F2A5633D233F2FF68C48FD9F546DEF61C3 +:109E6000CEF7C94A4020CA059529728E760E8188A0 +:109E70005C267A7532D685FE36FB51C8E5C038F7C8 +:109E800067025301EE239F89F49430C20D8DAE0812 +:109E90005584B0716D467508F703C537A10C70D6AF +:109EA00067546760F9C89189216611BFBB3AB2C88F +:109EB000105F32E3A9BFDE77DA285F61E719F63F6A +:109EC0002FCA73E876E7E43CDCFF5CD2D7EA5006A1 +:109ED000F63FF57DBDBCD2872EC57B76F25672FB70 +:109EE000339FC59B93EDA6A4FDC5DABC2ADC4FEFDA +:109EF000DF5FEC1993BCBFB826FF163CBA7F4FFF5B +:109F0000FE62A412EBABFEAE0AA44F3D1FF688839F +:109F1000EF03B0894F05140BFA5850F17836D1A3EE +:109F2000E64F0CFAAEC5CDCC7EF09C3C631CFF64C2 +:109F3000684E46023FA688E3EBF13CDD0FC6789DF4 +:109F40006CC97746FCEBE32F10B81FCBEC02C93B82 +:109F50005D6F823C598AF88666148F569D02E56BC8 +:109F60009D0C352AE417A5902FFDFB062C31DA6AEB +:109F70009F75819677627EFFA33CAE9716D8799C39 +:109F800052B87E6904C75D90E7129C4976D28A3C3C +:109F9000AEC7F5FD1747FEA92AC4B3C31151ACE6FD +:109FA0006DDE475981B66015C753C842EFA5C2D3CD +:109FB000517B07EDCB1D5D2AD279DD9391C974EFFA +:109FC000432AB9F00AD2CF68C6E6E5733D34B08EB5 +:109FD000D678D3F364CCFB55FDDF17B9E9FC8D3996 +:109FE0005FE6210D6F4F6978F957E7CB3CA5E1EFAC +:109FF000692D3EA3C7B3AE4821EF2FB0D53D90C722 +:10A00000E38C43C665CED3F37D34FCB00363E95ED5 +:10A010008E2D3DF6B85B40786CB47FD9F09F620816 +:10A02000ED2FBD9DD7242FF4FC1DBDEC3925B07854 +:10A03000D23E8247EAA238A9E79444EFCDFC775B91 +:10A040005EFFFE22F19FBE2EA9D6595F17F3FBFBE0 +:10A05000B47539BAE84F413CEFB2C5CD2CF38958FD +:10A06000BE31FE6ECE0348B5CFFD9AD6FFC9C8D427 +:10A070005C94CB0D8ED8E8E1F0BD8E9F17BFF8A39E +:10A080000BF96CCB29E70CABF57849D34FA04F37D0 +:10A0900025EF83FAE63FDF8ABD7A24E33EA8AE4F80 +:10A0A000F57D504FA5791FCD7A1F740BB3968FA9FC +:10A0B000F64107ED7F6AFAF6B3BC14FB9FE5439FB8 +:10A0C000673F90C78695F771B5839F9735BFEFD1EE +:10A0D000F8EE646473D15DC057372C7252965262A9 +:10A0E0009193F8B071919BE2B28D153CDEDB78A7BD +:10A0F000A0EDD719E3B04F83BC5809E33FABE99D0E +:10A1000037597812DAA3B32A05C33E79B8DA6D2835 +:10A11000CF5FFA93A7F1DE8467A6D8158A3F435F25 +:10A1200031B40BAA799E2253FA6EC338B71E7FD67C +:10A13000D7FF99EA37E91EB418D8F9A343187F1658 +:10A1400089BF9E796122BF974E18D80F57C04ED84D +:10A1500072C128CAF778B9FC5B14E7DD8271719887 +:10A16000E9962FFE3883E80894720CF9757C561C2A +:10A17000E563E3B80939489707C67FE6C3B8E8EB5B +:10A18000B79CCCC675EA5DD7447907E67537C799A1 +:10A19000CDF1E5B38D2757E71BE9E169533C5997AA +:10A1A0005766F991144FAECF1F463C59975BBA9C46 +:10A1B000D0E5D7CBE5EDAFEE867FBE1C71124CAF7C +:10A1C00068F3EEE74B8D2E5FD6F9F00B27D9230706 +:10A1D000C63F4CF9567ABDD6BC4CA2AF6F95C7EDC1 +:10A1E000B43F8B790A6503EB323FB2BCBF8CDD7E96 +:10A1F0007BD9F506FAE8975367946343CB29573E1A +:10A20000B7C352E56BF6A4D43FA3C94EF5FCD51EE7 +:10A2100077957C793DD4B0E80F0AB683E70E6A3FA4 +:10A22000DE11895BE827333C9E53228B4F4C7EAF77 +:10A23000F0F7FD7AC041DF6375CAFAF5016E4FB7DA +:10A24000107FC69CB8EE52B6DA8A749097ADB6E528 +:10A2500043BBDF06D40DF949F2B4C5CEF723451B45 +:10A260008B3C688197C7F235BCB07010FB6BAB3587 +:10A270009EE7D29FBFC997B4F3189382685FB7BCBB +:10A28000511144FE39E89B44F676AA75DBA6F31318 +:10A29000CAAFD103FEC4566DBD814555DCC76DB351 +:10A2A0008783C9F1C6ADF99CAED2A73ED48376733D +:10A2B0008B6CA33CC11699E75FB77AA5197BB4767E +:10A2C00001433B493F4745F765485E637EF5636858 +:10A2D000EF54A59EE763F9DC3FB4B3C41DD5C2803B +:10A2E0005EB11FAF75D1FD0F4C95797E53C8904F6D +:10A2F0006DD7F44B9D295F4394BF9CDF569C1DE9AD +:10A30000C6F534FB6D8702EA63F83E2AC59C481FF8 +:10A31000519735DF1FD6D6B5459BAFF95E55D17441 +:10A32000EF8368BAF72156D7F4CB5EA4B7F54EB9E0 +:10A330002540F73CD0BD0F51BC72099EFF70F37CE5 +:10A3400016F0FF26F3F306A15E94AF2CE8A2785432 +:10A3500047A1AA164259F4D976AF87FE5AD43A15C6 +:10A360008FAE74786D9DB8CF979317790DE731CD87 +:10A370002791DEE9B82C8DF4107C777339C26461C3 +:10A3800012F98374690AFAE078BECC1E74503CABB3 +:10A3900025C27A9DA3F8F97FA4F75A9638525D82B8 +:10A3A000F6B6AB12F17424343123622127F4A77975 +:10A3B000FFFFD5EFBD544CF9AA62E4A37CDAF76F36 +:10A3C000DC8AFBFA6BF68B21DC47F8CEF75F1EC305 +:10A3D000CF1B19F799EFF6D4F4A23E8B7A1D54AF38 +:10A3E000DB37A903F1D422F83AD0DF6D79E3FA9F85 +:10A3F000231E5B9A799CDB8CE783BEEFD3FD1A2783 +:10A400006139B1BEF97E0DD6713D5F27A78BF62D60 +:10A4100061BEF6822ABE8E141F3CE6A37BA04E1EB0 +:10A4200039E045F8BEC2BC65EC37F5BC0B65D257C8 +:10A430001AFD3029BC09E7F503D1D7D11EC07BD264 +:10A4400060BD11EE47ECE4EFDFED49A7758D027CAE +:10A45000B8AEA2AF5E4597ECC3FD22AD73546AA2BD +:10A4600079B198C4F6E2FB473EF9F18548076A16D0 +:10A47000ED6A89454D84970F012FEB2DF002F433DF +:10A48000A600FDE5476EA07E3A1C2E192D9B16DF17 +:10A49000243AAF3CDCFB452A0A847E7F4BBB5FA499 +:10A4A00002FB1D545FF3B3D0DFC6EFB532FB38CEED +:10A4B00006F09E2A7F452D30DACFC3C85F510B2CA2 +:10A4C000FCBBAFB0AE97170C49CFC6756D71FDDF01 +:10A4D000E96867A9627AC85D0C655C27C43FAE1362 +:10A4E000AE9716B72115A4201DC88902A4831BD2DC +:10A4F00043489F67921B12E3EB6E97809EC1AE7339 +:10A50000CA91A37476518BF7E8F2C4CC672D2EA3C1 +:10A51000BC6AD1EFE53B363C7905F4B202F16096B6 +:10A520005BC3A593EF0FA693EF0F45276979E12849 +:10A530007E473C154CA078C5CD583E7244DCE718E8 +:10A5400089E3F1B8595F1E937727E565E9F06CC69A +:10A55000CD6ED2CB3C6F4A6A600CF3E0FC652141C2 +:10A560002E1F161D6DFE9AE9E88EA1E48397F5D0A3 +:10A57000798D557A7ECEBEA1F373BEAAFE81F5BC5D +:10A580000FE169F17D9FE87383DD25F37BD4CE6E07 +:10A590005D1F2C10CCF70B3D988CB7C1EB1AD987F7 +:10A5A000EBA8164CA27B8CD8944564377567ABC773 +:10A5B000305F8C4921835C1CC43F9ADCFEC1390AA0 +:10A5C000E5ABFEA5599373CD4E19EDF1C70337FCEA +:10A5D0000EEBDFCE9430C6436B6C6B094F1FC2FC91 +:10A5E000768748AE96E1BE4F94A585343DFA1F08A4 +:10A5F000CF0CA559C882F781058A8DAE2155B63397 +:10A600005BF9F0F1F0DC603C3C37141E400EFEA715 +:10A6100046CF37223DEBE7ED53C9C137B4FECF42F9 +:10A620000EBE91CC5F5F03FDBE3FB47EFBDAE5CD8D +:10A63000A7389E59DE78357EFE6E8885305E3EDC1A +:10A640007C36B03715E4AFDA7417D14FCB8302E50F +:10A650004B811D1EA1B2CF45C2E6A0CFC1F37FF74B +:10A66000F1EF621DC7B3194F42213F9FB5AAEBFA24 +:10A67000B064C8938AF1F39AEA09B954C4FCFE6A3B +:10A68000A267BF66CFE879FDE99AFCEFD7F3336D97 +:10A69000349EBF88CB773FD83B681731A997A11F5D +:10A6A000FF83029EBF0FFC40F40DA384911F32A6CE +:10A6B00048A63C2DCE2FD912B77732034C205D83AC +:10A6C0007962F0FE13B027F07E824CD5D8EE076990 +:10A6D000DF15506FF52EF23609740E3EDCFD33287F +:10A6E0006761BE17F08D7F86B17E364B2A5BF8E737 +:10A6F000B13A5686798B15855ABCCDC182A41F35D7 +:10A700003F5DBF2F503C73DED7D4C261F8E9171705 +:10A71000EA79C2467DDCE56696F1B523855C1FD5F6 +:10A72000F7D6D6A15DBDD6C7C8AE5A8BBA13CB99A2 +:10A730000EBAD726D45DE9B2BAAF2253B519EEE707 +:10A74000F5CF4833DC7B9B1DCE3294731BF20DF5A5 +:10A75000F322230DDF0B969D6BF85ED434C1501E9F +:10A7600011BDC050BF04109C5C1EB5E93243FDD141 +:10A770001D5719CAE7ECF896A1FED8F862C3F7F3A3 +:10A780007E759DE1FBB8AEB586F2F9FB6F36D46FEE +:10A7900061D6F777766878057E2739D6ECAD6BA061 +:10A7A000DFD1901D8638FF755ABDEECC4965180F74 +:10A7B00069395E5146FE70FA0543FAC366B9984A94 +:10A7C0001E9BDF6F2EE4F2F383C7DE9EB412E91CFA +:10A7D000853CC8A50FBCAF6CC0396D2EE77909FA6E +:10A7E000EF6298EFE5EFDFA794549ACF822C07B37E +:10A7F0003A1F705DA162B9BFD02A845CB857940A31 +:10A800006F478689B7EDDA3CBE2ADE8E09C638105E +:10A81000EA93072DE07A42E32BD057BF453E047DF3 +:10A820005599461E06BFC7E16CF5890E07E8937F70 +:10A830002FCC1E9C1FFE41C3F3D7DCAD60FD6B78AF +:10A840007D5BA80CD725D5BED21385E67DA5AA656C +:10A8500028E716F8D284E4FB9AF76BF5F478764B88 +:10A86000FA67B4AFD4E208950D675F697F21E3F71B +:10A87000E0E2FA6627ADAB5D0DCA96FE9DD98E610A +:10A880004FE03D1831AF4479C366FF2EAAC96DDD94 +:10A890009F930ED692BFDFE21D49791F2DEA5AD24F +:10A8A000971D29FC5CD097BDB83ED37C371AFCB904 +:10A8B0008178804AE3415BB29B5A92FC7F6CA7DEB1 +:10A8C000CDEFD5FE1AFCE08F0ACFC2FF5718F783F1 +:10A8D0004F328EA793AA8DEC84936027A0FC6D93D2 +:10A8E00018ED7BC72A05C5CA2FEE58AFD987EB39BB +:10A8F000DECCFBDD663BE38AD0F584B736A0275774 +:10A9000025CE9FDBBF6D767EFFA6EC0F0751DFF6ED +:10A91000653BD86E80F660368FCFE978F9B2F228C1 +:10A92000A76890FF93533484FF738958DE85F7B688 +:10A930009E38C5E3220A1E450CE03DE47CFDD63E70 +:10A940003127B606F55489D484F9EB225332102FFF +:10A950006B0E8B2C2EA01C33E6E7DB59D35D188FD2 +:10A960006301FE3EC65CCD6827654C31EAB14CD52B +:10A97000A8C7FC33B24C7ACDA8C7721B8C7A2C2F97 +:10A9800062D46305CB2698F49A518F8D88D699F4BA +:10A990009A518F8DDA749549AF19F5D8393B8C7A75 +:10A9A0006C6CDCA8C7CEFBD55A935E33EAB1F3F7E3 +:10A9B000AF377CAF48B41BBE4F3C7CBBA15CD573AA +:10A9C000AFA1FEE4A3BB0DDFA7F6FEC6F01D10FD90 +:10A9D0001C9E67C07B6871112F7CF721E377A63A34 +:10A9E000301F7F059ECF8475BCA8EF61437FAC8389 +:10A9F0009F5B88C17FB85EEFB008DD030072EC504A +:10AA000001B45B1D17420986FAE9C1B771DF6679A7 +:10AA100050243F6E0D065B911EEEF7C5911EAEDD14 +:10AA2000613CFFB03C6E2CC7807E148C2B00FD2057 +:10AA30007DAD30FD6E04D883446F2B14A909ED4A17 +:10AA4000337DBDA3D3574C7D0ECF73E8F3D5E767B5 +:10AA5000D7CF9F6AF4A76AF4C7C44708EE1505224A +:10AA6000FDFE8E3E5F15FEE3DFDF77E03C3ED92F33 +:10AA7000303FC0710D8B1D2AB098CFEAFDDB1DC899 +:10AA80009FE67999E761B653DB8A8CFB489788DEAD +:10AA900010F1DD0B22E9239A02F2D903FCBCDEDAC5 +:10AAA00027443A17837C88FE82186B20BCAC01BC1B +:10AAB000E0BDE1BADD7A426B77E2A7229D6F3E13DB +:10AAC0003F2A1A3E9C41233FBA9534133D19F1EBBE +:10AAD0002933F2E78AD72E75A0FC3A04F816A6307F +:10AAE000E60B19F97585B892F6F9743C2BF01F8EB8 +:10AAF0002B81A98BF35E0DF34E2883F1BBEC91ED16 +:10AB00001B0A2CE8E64CF87DB0C8B8DFAEEFCFD515 +:10AB100002761C1679A53AFEBAB3D53FA27C4CE565 +:10AB20000F1F283A6B7FF840D1D7EB0F3F5334A467 +:10AB30003FDC370BFD29274B0FB55BC4FD242627CF +:10AB4000305E6B6FE271BF81F8DDD71EE7790BE1F4 +:10AB50009464AE27DD921EE7091D8DA07D92716E73 +:10AB600008F3A2861BE7F870B01EFB70283D06F6BE +:10AB7000C5313C4FA866E4D7DB9099A45019DDEFAE +:10AB80008C20F03CA4FF46F806E5EB966669F9C711 +:10AB9000CA90F9C75768FBBB1706D57F221CD0DFC8 +:10ABA00069ECAFFF3EB6CA6CEA27FD0CFDC4EAB8FB +:10ABB000BD16B3F93A5AB8BD46FB4C5F431CC35FA0 +:10ABC0008C712D2FC77F8B83C76DCF36CE565C3CE3 +:10ABD00028BE545C3C447CE91FAFE6F273AB21B065 +:10ABE0000E2A52D3B77E0E532F6FCE34FACB1B26CC +:10ABF00070B8CE2DE6EB1ED1CEE3D668653DEF12E0 +:10AC0000F316DD13A03C939F53D2CFB5EAFDD414C5 +:10AC1000FBA8FEA7C1BA1AC4C786127EFFCE864C17 +:10AC2000E33D3C278A6A6B705E53B4FE6B8A193F22 +:10AC30003731523BB7698A177CAED5FFBCA88E9ED0 +:10AC4000788E16FD1287285AE2735AB14DBBEF86F3 +:10AC5000D173BA7E7EEE4E7EBECE7CEF02F0C98B03 +:10AC6000F8FB506FDE66277F0FF4119D9F5B5AC083 +:10AC7000CF219AEF538894C98750BC7EC2CA2DEF6A +:10AC8000E51994E770EC26CABF7B662A9385BC332E +:10AC9000E73D7CBBB85F5F85BEE439BAC6E261E4DC +:10ACA0006B2DD1CED1F5A6713DD697E78AEFB6F0E0 +:10ACB000776FD5E8F236CDAFC5FD69DC27C7FBBDA0 +:10ACC000ADF6CB6F2DE6FBC3C33D577DBB231241D1 +:10ACD000BE359FAB4E759EBAD7D1DB968BF08E6595 +:10ACE00021B4DF7317C8DDB9502FAD5EA1F38F1B00 +:10ACF0004A58FA14FC5E610BE1B98ECCB9F2063BFE +:10AD000094334B599600E5DED81C1AFFB606268B05 +:10AD100000D77DC5FC3E8485B77C44E36557C3D42A +:10AD2000143A773E1DFDB35803A37B0BCDF3BC5BF8 +:10AD3000A35F571BBF2727A3D43A0FFFEE62DDBFE7 +:10AD40000EDF85F45B5BCAF6F1F3B3FC9C025E4B4D +:10AD50004FF99BA134DA17BC12D68DEF9FF7D0FACA +:10AD6000DD149CF6536CA7F39B43CB53309F27BF56 +:10AD7000AFF8ECCE93A72DB08637A1ADF735D9E16A +:10AD8000FB918ED2CA3AF8EF977E71FAB43849FB3C +:10AD9000694705DB4722A8FFDCA0FF047C2A329D1F +:10ADA000A3652E81CEC3BA9426A22BF794901F7F61 +:10ADB000178D2DB131BCC7659AD65E6D6002FE9EBF +:10ADC00004E502929C36FDBE841A6A6D86F697E011 +:10ADD000BE5908F3BE43CBB0BF7A6F9A8CF14D7762 +:10ADE00069532DAED7E30B791FB7A7382FA19FB3B7 +:10ADF0001FB87F6ACDB3867B051CCB9F35DC2BC08B +:10AE0000963FFB55EE1578AD78F9B3FF13F70AE8D6 +:10AE1000F20DD4901DEDFAA322BF47EFC347AFB6A2 +:10AE2000E33A6CA8655D88F7D8678067D7009EED28 +:10AE300075E1C777A25DB2363DC47F4F24F61D840D +:10AE4000F3350F93B1BD9E6F28B032D2D7731B0478 +:10AE5000B21F98D4B71ACBF31FF1C8E83F7CF8E8CB +:10AE60004B4531A0CF576F3DE9C3FCD4D7A53E1F5A +:10AE7000C2F5EE2DCFFBF0FEAE576F11290F85CE38 +:10AE80007D27E5890923387D2D1A113E85F4B5709B +:10AE9000DD3F2725DB672C9A4DFA7E791C204EB6C4 +:10AEA0007B7FE531FCAEE8AA2EBFA1ACEBF9554E95 +:10AEB000EB73F35347703E5C7E7FA7A340C1F12341 +:10AEC0006923A0FEBBDA39A077F7F9C88ED7E1591C +:10AED0007C7F8503EDE1D71F71B204C5057BECCC07 +:10AEE000CBF507E65D44F8D083E03CF4970207F227 +:10AEF000D95281F53989B9D921C4F7DF34FFCF3C64 +:10AF00008FA5AFCA0E5CDFA5B5AC0FCF9D2DBE518E +:10AF1000D8F003A8BF38E225BFDF3C4FB3BEB91657 +:10AF2000EFB311ACEE816B3AF467E86709F483F68E +:10AF3000E7D20EE3F713876F38B413C6DDB7DF41EE +:10AF4000F6E2B56788F78F1FA1E9A5496CF2E951D0 +:10AF5000A4FF32C629A9ED0E5D1FBDBB8E5192CA5A +:10AF60007FE1EFFBC2F3FD75323D4F152BB41E2B75 +:10AF7000F6771FA2DF16967A26A1BC9BF944A3E7B9 +:10AF80005B6C20AF685267CB819D5455CF574D50B5 +:10AF90007C6F8A76FFCBB5DAF98FAAA3E67CD5EE73 +:10AFA000C7FF8C761BCCFF6CEEED5930CC7B7B4E13 +:10AFB0001C9EE6413A993D42F37F26035EC4AF8E64 +:10AFC0009754ED56A5F8DD169D9F4E697A66C99E89 +:10AFD000D91BF261FC9647DF29C6F8718C71FAAE75 +:10AFE000FA29FFFD9F2A6F0ED19B0BE9330F9B9827 +:10AFF000EE7988B11759127D5FFB8887E82408F63F +:10B0000090730ABEE1F45A85F776227DBFC0DBBBA0 +:10B0100034FF36F2C8ADBCFE9F1DB233487C19B474 +:10B02000D13311B44DB1B867CB7CBF5887B1FC8127 +:10B03000BDB718E5CAB5263FF403C13A3FAD71C4A8 +:10B0400048C2C712459D8E79004B5978038FDFF2B5 +:10B050007B7BDE953A0EFD10F97D8FC06280A7558F +:10B060007F7CE0DF518E5DF7BB3BD3518EBD2775F2 +:10B07000E4E0782BF7B6A5A31E78578AA563FBF703 +:10B08000E25C9E0DD29723044D0EABE902C8E4D5D5 +:10B09000446AF0FF257D1B6E8671FE1BF08C7CBF21 +:10B0A0007ADFA7543EA4BAFA5810FBED9D8E702C9F +:10B0B0005FE46D6A0EA17F69E4CFEB7E79678E4213 +:10B0C000791EB1020D7F05D86EF51E3BE5F9A21F72 +:10B0D0008FC3AC617D343F73FB355D6F3A505ECBFF +:10B0E00036D65778E1E0EF60213990DFD6ECDBF21D +:10B0F00091988ECFF75EC1DF835A63B24F9769F2A2 +:10B10000DB4CFF5D26BA07FC507C210670F19F6383 +:10B11000E272BCE5D7778F7F03E07B7FCF53E9F8FE +:10B120007B133AFDEBF73C9FE86A5CE818E21EA14E +:10B130000F343EE9D70F9A7E52F60360B9507C84F3 +:10B140003F57DA13E917C27C5776DA4348F32B1FCF +:10B1500010552FDA552F3BC91E59F9C049A2DB956E +:10B1600082DA27909E63E928C7F5F55AF1C0DFA679 +:10B17000A39C5E9127B299C08AD7FDFE135E1FE89B +:10B18000DC0DF5573CF8C6F41F6219E489CB62BDAB +:10B19000A675753B7ABD16EBD5F5C6748CCFB7FC9A +:10B1A000FA1FB41EEFFD4560B92583DB2FEBFC1BB6 +:10B1B000C5C1DE8785F167727CA1BE59D3252E7289 +:10B1C0006458AD5F62D6C395F49DF2C2CFB48E1DB4 +:10B1D0002318D78F7F7CE0DF1E063896BDE20CCDAA +:10B1E000C471FFED86740674F08ED4C4E9FE676DF9 +:10B1F00039A8BF97D96339323DF9FB65BBBE47F427 +:10B2000078ED5FBF97A3ED37E4D9481EC4F2709E76 +:10B210004B7F3A8FE6790D8B103D2EFB19BF67F1FE +:10B2200013F0B3ADFC84A90AE71B27BB7EFCCD015C +:10B23000949B78670BC0E160FCBEAEE778FEBB93E1 +:10B240005D95916CE77A146ECFC558FC35B43BD749 +:10B25000805A46B9F6FF003503B31E008000000097 +:10B260001F8B080000000000000BE5BD0B7C54C5DF +:10B27000F5383E77EFBE425E4B5E8457B8791224B4 +:10B28000C485249040D485400C0AB8404494884B2F +:10B29000C010202101AD60A5CD860002C53628551D +:10B2A00014B40B8245451B31086AC08D2886EA1705 +:10B2B000438D165BA18B2008045810EAFA2DCAEFC3 +:10B2C0009C33F766EFDD243C5ABF9F4FFF9F7FFA08 +:10B2D000A9C3B93377EECC79CF9999B3E2814BF911 +:10B2E000BF8C62ECE1787DA5C9C25805D33B3D66B1 +:10B2F000867FC215814A493F189FC35F0263790761 +:10B300004675F3A4316662178CF767327611EA9FAF +:10B31000B36ADE6357E2193BB1D1D445B819CA18F4 +:10B32000565A07EDAFE0DF6DFEB25482CEA3A9F905 +:10B330005F18F43F97BE04FD6C3991BF0EFA65B1FA +:10B34000220B8FE5F073303E4B71486578367CAF49 +:10B35000E5A8B107D43BA3742C19C7DBFC0DC1CC05 +:10B360001A2D617BA5FF8A9D26E656C603FFAFD83E +:10B37000F48D91613F3AE6ED35AC7D3D6395E9880A +:10B38000870A162EAD84F284D19BFF2E7E07BEBBAA +:10B3900019BE53B206DAA7AAFAAB3FF937968EED7B +:10B3A0008DFEE7F1F8DFC58C65412116853B42181B +:10B3B0009B8938CC693FFF855F553FFE81AABF0C52 +:10B3C0002934EA7830FC63081B7245F4BFCFD603FA +:10B3D00092BAB77FFFFB2AE7E31F18F06D27E1B1B0 +:10B3E000CCE07A09F154F6A5C9EA043C96BD76C9C9 +:10B3F000A88B422A326F7257C64E6FDDF3C57D307F +:10B400009FD37586A831F4555B9810E3C77BE9B6E6 +:10B410006FF2D7417B03E03D08E839B7FE7BA30E0E +:10B42000DAC7E631AF09C67F3ACACED800C49BE17D +:10B430006B8F0A6F79F0DC1342E3E8A98BC5D2DD8C +:10B44000934139378A59DDF0FEDC16D12A21BE98A6 +:10B45000779925A4FDFB15754703E8A2AD67CC6B72 +:10B46000B4E377EB7F735E0C53E35DFFB5478577FD +:10B4700005CF81789D8A78EDEFC7EB2596160E9F54 +:10B4800061A75E99D3C791D61EBF0A5ECF563164BD +:10B4900072FFF33E12E159DA091FEA06750D72C90F +:10B4A000D8174C85C7D9AF9E21FEFD67779189C01B +:10B4B000377337FDB00CF90AD0EA3501FFCE759D20 +:10B4C0002778A9CDEC650437160AE91DCD5B8BCF33 +:10B4D000C0FA78446AB49FFE86C5CC190AFD7A7713 +:10B4E00089AE8D30B47392372C02E6B734883D6054 +:10B4F00087F29C4586BB2A307B601A8CF39C33DD37 +:10B50000E2C4F782D8E43AA0CF39BB37AC6B887F6E +:10B51000DE471AC43009DA7B5CACA02EA43D1F3292 +:10B520005643DFF7B0CEEAAB491E4689975FF7C0B6 +:10B53000F72E38F5CC04DFF3547FFFBA07CA637ADD +:10B54000B305F134A3FA9E30A683EF3724DE351914 +:10B55000DA3DB80FF047D3B319BB037EA7F3A9B305 +:10B560006F99F3E95C989F189AB9F75D78BF04105A +:10B570002B02BFCE58A5C5CF6C660F77C7A3DC1AC8 +:10B58000FC7C42FF7519DDF0DE4C4748E54AF86E59 +:10B59000E97A6DFDEC86D3C45FB303F8CB81FCD5AB +:10B5A000BD3D7FBDA2C8ED403610F96B9418A24393 +:10B5B0007E3ED724BA4CF0CE852506B60CE00B5B58 +:10B5C0000517837E2E3440238477729839A3896FC0 +:10B5D000153E57F0D68AFCD7B73D3EDBEAB71F1AB7 +:10B5E000FC1834297BEBEFE9EBA06C7DEBCB947777 +:10B5F00011DEF1D7B8BFB3F6EDF376FF3095C6B5DF +:10B60000DBC4705CE7767F14F718C2EF98ACC8B75C +:10B61000E7169B6C0CF5DDEE505732D6F7067E0030 +:10B62000BAD7ECFA3E1DF53D634B888E9F4B462AF8 +:10B630002F34FCEBB080F3683049388F8ADD80040A +:10B6400078BFE29D2017C3F7777D3FD811F2F3CD85 +:10B6500067AE9139883F43D9E46DC8BF5D990DE766 +:10B6600053F16ECE8BD5F0FDF2FA46E374A8CF7B92 +:10B67000EFC774D447E7B6351A515F9D35785E60E1 +:10B6800056E4DFFB6B0D80E7B3A1D0590FC61EDD7A +:10B69000F0BCDD19D2115E381ECE011E705E80979F +:10B6A00052575AE7F8F8FEBF161FE7A7E2F7CB1A82 +:10B6B0008630315E8D17C1C69F87BACC02CD9F3FC1 +:10B6C000DFFD7D3A0BB9F67CA3E38D24EFFF7F9974 +:10B6D0006F46FC7F2B7D39BFBF2B4934BE40BE6F08 +:10B6E000CFD73B1E21F8F5502B8DF73AE57DE27F51 +:10B6F000EDFCFF6FE83DEFBF76BED7A2F73E99DEC7 +:10B70000A11613EAAD5D3FC6B11B9877EDFF47E781 +:10B71000DDE6FFE8ACE64C18DFDF98EBEEE10279FE +:10B72000251DFA23BBE2B5EB8E71B25F51C3BE1E7D +:10B73000390DBEEB047F02FDFD9A90AFF52D003769 +:10B74000839F80FE0543E704F0D05C38D0B512ED4E +:10B75000B6BE925900367C319DE0C9C53FE833A1A1 +:10B76000FDDDE0E761FBFDD59E19D550BFBFAB4EB7 +:10B77000AA01F82EDBC4E47A802D3D440BAE636A47 +:10B780006C19664935BEBBB2B5EB91FB02D615F715 +:10B790004CD6D64F621BA3F5D0DFA4520373C194DD +:10B7A000EE0E68BF2EDE42F8BA87552EB584DC381F +:10B7B0009E4ECB78AA61839A24C48B4DB46E66EDFD +:10B7C000F1C6106F8897D80CB6D28A5FF1E85B009B +:10B7D00036C9FE15FC913CDE1D657E09F16462F3FD +:10B7E000D923D0DF25495F89ED4D0CD68D7CDCB4A3 +:10B7F000DE0CC41B93D79F26990477D91E628867F5 +:10B800007CDE2756F33ECD3B10CF378ED7C5C94FD0 +:10B81000235E0B43AD2EE40BDB8BD17AF85E0DE09B +:10B820005910FCF854F0148877F43969FD27E35B6C +:10B8300029D398772AFA9D612CCCBA12FA0F33F7E4 +:10B84000627A3E0FAFA93B161686EB357104AB5BEF +:10B8500009EB3596AD6F6D9B5702D5BB1F83F76A19 +:10B86000E6C1FB88D75E4CB213FF1759707D2330B9 +:10B8700007BB12ECF73F3FCD06FF339E4AE2DB4F9A +:10B8800037717FF352EE9BCB0682283198B3733029 +:10B89000FAB9F29FD35384EF894C67C5F52FB3D91A +:10B8A00024CB60EC97D1BA263C5BA759FF76B575DF +:10B8B000D1E02DB220420347DB7B68DA779B9CA066 +:10B8C000A9EFEEB84953DFB3749006EE5D3954D357 +:10B8D000BECFC2111A38DE7987A67DE2F2091A3886 +:10B8E000B9F63E4DFBBE6B8B35F5FD5CB335F5FD12 +:10B8F000B7CCD7C003EA7EA9697FF3CEC59AFA8197 +:10B90000EE959AFA8CA627357056F3739AF6430E85 +:10B910006ED4D4E7785ED1D40FFB769B06BEC5FB10 +:10B920008EA6FD6DBEF735F070F6B1A67D9EF9339B +:10B930000D3CCAF2774DFBDB638F06C43B2CCE87F0 +:10B9400032518D013F819C8D964E6BDA83C75C84AA +:10B950007C6390F9E1CED4EF34F563ADFFD2F467A8 +:10B960006495400464AB5A2ABBB03A2A43583395D5 +:10B97000BF1EE0B027A05CBCE05C864CB53FE7FB97 +:10B9800038B4239FE63EE444BEBB14CB2CE24018FF +:10B990000FF3EA91AF75C1977B395471A3309FC8FB +:10B9A000DC19C0873E814A8B2F98B923810F7D41D6 +:10B9B0005446F822E979A4AF2B9551BE9EF43CDAA7 +:10B9C000D79DCA185F2295DD7CF154C6FAFA53D987 +:10B9D000DDD78FCA1EBE0C7AAFA76F2095BD7CC382 +:10B9E000E8796F5F0E9571BE3C7ADEC7379C4AC915 +:10B9F000772795F1BED15426F82652BB44DF782A2A +:10BA0000937C53E879B2EF5E2A537CD3A9ECEB9B8D +:10BA10004665AA6F0E95FD7CB3A8BCC9F710BDD7CB +:10BA2000DF378FCA34DF63F47C80EF512AD37D3552 +:10BA300054DEECABA6D2EAFB0DB51BE85B41E5207A +:10BA4000DF53F43CC3B79ACA4CDF3A7A9EE57B9643 +:10BA5000CAC1BE17A91CE2DB4065B6EF552A737C4C +:10BA60002F5339D4F726BD37CCF70695B9BE77E901 +:10BA7000F92DBEB7A9BCD5B7879EDFE66BA4D2E689 +:10BA8000FB989E0FF7EDA37284EF337A9EE73B405D +:10BA9000E548DFDFE9F928DF9754E6FB8E5279BBF2 +:10BAA000EF089505BED3548EF69DA4F20EDF77F411 +:10BAB000DE9DBEF3548EF1FD8B9E8FF5FD40655BE0 +:10BAC0003C21D710A017DBF49FEE0AC67942223A38 +:10BAD0008CB7B5BD2FEBE3D5C12F308C7B8CAB146D +:10BAE000689DFE4CF0D90F484FE69824849762D3A6 +:10BAF000EEFC3B9618C6EEC77F488C35E69868FD8D +:10BB0000BEFF57FCBD65C38F7EF510DAC779268668 +:10BB1000F63150FF2ADFFD347B4F34FA61CB0679D2 +:10BB2000CA30FEF244BCA708CB860481ECC59B72E8 +:10BB3000F94E828ECA3503B8FD2E9A971C4E71AA13 +:10BB4000A8EB9BD7FFA2DD8FF6B77F2189F7C34211 +:10BB5000BC71642FAEB39FEB6DB7D4FCEB3F605C60 +:10BB6000C756A36741B702ACE7F6DEF955A86B33B9 +:10BB70004CC939A2F28F18E7712E36596AA210CF3C +:10BB8000BFFE13B65FC898DD04E51F121C9F254059 +:10BB90003FDF07C5B9C038C25FE59009A13F6BFF21 +:10BBA000FFF83FEEFF34EAB5CEFAFF87CC476312C9 +:10BBB000EDE7701C4C6F4B473A8C58DC5D8C82F77C +:10BBC000A7AD122CC847D3970CCC47FE18C46C14F1 +:10BBD00027BD3F923D60EFC02FEB96A893FD0BC9A8 +:10BBE000780F8CE70CB81CE84F144B8CF8B2B841B6 +:10BBF0007039290E6D0B1B0BF6BB54E6DBE2E5D565 +:10BC0000C605D0AEBC3B8F9731178F9799E17F283F +:10BC100047736A37ECA570A37899E26397D0EF0574 +:10BC2000D699B3A57D3C7601C699771A2D6837CA97 +:10BC3000EB02E2B90171B3C0789925518EC75A99C8 +:10BC400095C7B9434AFE8ADF63619218756DBC28B7 +:10BC5000F1598949DD108FA3C4B4705CC75C684A90 +:10BC60000E67584A52376CE7005A344329E81D439F +:10BC7000F039E0D38974F55607BB36C2B88E803DE3 +:10BC8000913270408E21468C47FEAD375B2910D52E +:10BC9000C80FABD824925FEF59FCAF6518C79E154B +:10BCA000AFA775C0348CB9E3F8DEEEEA720AD42F80 +:10BCB000E1DDFB9A407157279B1F8B71DDC07D141E +:10BCC000FBD2E871D948A7E55D079990564EDB177E +:10BCD00049312AFA2CA921BC16C74672FAEC3490D5 +:10BCE0005F0BF4A946FACC72198EA9F17C895D36F6 +:10BCF000E27E4CF1F2F344AFD97E7A69DA95D73619 +:10BD0000125D814E9AE71595279438FAB1ABD12B85 +:10BD10003F805E183FBF072B1745927E285AEC4E96 +:10BD2000AE54F169E0BE44D28CA1E1769087821EC8 +:10BD30009C1E4C6F8D417A7EB72A8BE81548A782EE +:10BD40009FA6133DD8DF42D96618CFFD89EC810943 +:10BD5000F0FC0139FE7A7FCDE8028C974F4DE4EB81 +:10BD6000934F61FD6983F5E7812A33B3816AFEACA5 +:10BD7000CA42F0E755B104FFB54AA2F2CBAA542A51 +:10BD80008F1959699D4ABE80018C38BE192857D138 +:10BD9000582AEBC3876331EE5EF0D367593A52A954 +:10BDA0006F8E1FD51BD7178004157E261706932F7D +:10BDB000ADC01E83253F16F5C70AC1BA19E96A1F2F +:10BDC000A669CF5233FC30DA2F3DE727E08B8DC8D0 +:10BDD0007FF78E89D4B49FB4BCA7065E9428D1F8AF +:10BDE000C617246A9EDF57D45F034FF3C17A1E3E05 +:10BDF000952415E89CD0FFC54F0CC4CF172B877432 +:10BE00005BC061E2BB40FC1F333A298EE0DC68B2C4 +:10BE1000A2FEFB3688F3F7B79F8BAE1A5AF73A2982 +:10BE2000EE72C96C91709DF2C874671CD63F120CFB +:10BE30002EF940C497C8307EC05E3191FE9CBE563C +:10BE4000604E94112FA3F5F2C32F9B689E33D68AC0 +:10BE5000CC91417C1287ED1F8E96A8BFFB13A53AAB +:10BE6000E467EF66937523D44EF7C8EF0B83681F22 +:10BE7000A47CFE5F0FEB511E529AD371AD5514EFA7 +:10BE80008E463DD8BAC940FB5EE5E286921020D1CD +:10BE90009C27DE0CCB9148FC08BFA70E446FC0F96D +:10BEA000FBE7EBA2B8C8377DEC1B13419F9E2A71BC +:10BEB000A5D33A79118FC7B7C70B233DE5D4854980 +:10BEC0009B71BED31D432C696A7BC8F7FDA61BACD2 +:10BED00031D634E4FECCEEA8078EAD321460DC051A +:10BEE000F4FE38C4D3B1DA48DD4A5A546D23FE2A31 +:10BEF000D64B46F5778B5789366A0FFA7D3CDAEBDD +:10BF0000D5A2830D41B896FA772E171CB8EF94C4CA +:10BF1000B2BB21DF3E346F48379CC7D44EF619CFF1 +:10BF200082CC3854FB58B3778976177E2FD3A32F52 +:10BF30001CA01E3F8F03253996F79A8F747A23C869 +:10BF4000BA5242BD9A188EEBD4932D6037E01BB3E2 +:10BF50006A1AD32560BDB28776101D4AC7D5A5B829 +:10BF6000E1F901B3E313C4E3B7DDEB9E1E8671A2D2 +:10BF70008617E39C680717F2FDB5D9AFCCEAA3F6A4 +:10BF8000E7DBFB132C56978D853B4600BC38249687 +:10BF90008FF89DC2EAE4F8858BC627A1D2057C58AC +:10BFA000CAF8FEDB749D75EA679988FE500BD2458E +:10BFB000E9EFA881C7B9FE21CBB362877B24713F2B +:10BFC0006BBA8ECB1DDB2D109F02C1BE4852D9CB60 +:10BFD0000AB68AEC656C4F91E1BEDDD9C408592FD1 +:10BFE00070FB3707ED1FEE0B5B04928FB22D269787 +:10BFF0000BF82B3589CBE76CE36B4F0FC2E6F1955D +:10C0000046FCCEAC7A813D074D4F195C25CDB82F4B +:10C0100065D9B02482DE33585DC8A7B27E3783422B +:10C0200040BD3013FF09F5E56B04979BF8C54E76CC +:10C030006806C64D70FD8F7A5EA547DAE9F700BD48 +:10C04000FE200BD8D7AFD5DA177B70A819C7397B7C +:10C050000DF76BFDE311D915C05589C3B5771C8D5C +:10C0600057A0B848E0F767E2F870BC303EB7F5C6B5 +:10C07000C75362E5725A562BB85C1D8C4FC16B7862 +:10C080002E93D03ECFD924B8901F4745CD23FCCE68 +:10C0900006FC46225E9DF6B07B002E014672517C66 +:10C0A00085E3BF623DC73FD0F92F6ABBFB4D94D7F4 +:10C0B0008878FD06ECA713F7032BBF27BAEF05FA24 +:10C0C000A2FCCE7AC365C48DC8D3AC362C04F97EED +:10C0D000ED81BDB82CF866CD9B31B87E2D8A7027D6 +:10C0E000EB406F45B2E8270B6EF1F35FA0BD6E67C2 +:10C0F0009703F0E36476B243EDF0645ED58CFBDE2B +:10C10000EDE827C7C51EC47F017E1EDC24DA82D27B +:10C1100035EDE4F3084EC25BA9D34B7E4229CCB384 +:10C12000C6824F9DF9889707AD8CF4EE8D8E3770DF +:10C130009C4C2C22FEC4B81EFA21FFEE7803FD8F22 +:10C14000494957F73F02F548A0FFF195C1A65B8C1E +:10C150007EDF01BE2F7E51EFEE8DF27B312AC10AC8 +:10C160002DFC7A347A5037D4F38A1E2D91ED96D275 +:10C17000EF8368AF003EBEF6CD30A4BB42FF9968A6 +:10C1800027D2FC76E291E9D03F7CEF911D41D4FFAC +:10C1900099B160A7A0CFA2E73F0A632AFDF7781FF5 +:10C1A000C7FC24D4278A5D1337C45980BF147D7916 +:10C1B000AD7557A7F30A099857A8765EC538AF0C36 +:10C1C0007F7FD3E5797DBD9CCFE7E82A3EBF19ED9F +:10C1D000E6C5EDFE232F9AAC4EF20BDCD12887DFAB +:10C1E000BE21B21AA22FF71B2E99819F0662FC6610 +:10C1F00015D9F593D14CC2B84EA7F67BB589FC8210 +:10C2000059DBF97EEB29617837DAF8FFC01DF62893 +:10C21000CAF53691A11DF28FA7CD6E3F9BA4B6DB68 +:10C22000D789378CB3A23D9B0BA843BE9FDBD08D33 +:10C23000E1399755C3599D48FBF01ED263C04214A3 +:10C240009F063F5C136F3031ABD98C74EA24FEFA41 +:10C25000CFE4F353E7133EBC29887FE5FB155DDC93 +:10C26000866EE8D7BC21905F53FEF0F0B0E10CBFC2 +:10C27000C3E3663B92B89D7A07F51CCC4BB0555290 +:10C280005C0C7C1ACBEF705CEB797C98BDCFEA102C +:10C29000BF0853FC58C7E7214816563488C7E5CD78 +:10C2A00068D7427464D702F17042FE4EB9A823FFEA +:10C2B000B7CCC8FDE073023FFFF1916C1F3F4AE22B +:10C2C000EBCC4F92783CE11CFA81D0EFB95B4CAEDD +:10C2D0006A01DD563DAD93F5B92617FA337A7388B6 +:10C2E0005B4C47F4EACFB6C933E06B2A6B36203D8E +:10C2F000C765CFDB82F339DC8359C4AE546DC77D8B +:10C300008429A41918DB6FF8EA438C473AA1AD08D9 +:10C310006B8529D9277A63FBF508C3FC0F07D57D08 +:10C32000887196C3F17A86FB02CE5D26B2FF861134 +:10C330009EDE14A7ECC258CD408CC7EC598A7CB461 +:10C34000373632D502ED1FD077B18A5CFF8C3C8F37 +:10C35000E32D15F8FECD124F16D2E766B6C472DC97 +:10C360004C5B0BF55722AFC63F7A765CE10318535E +:10C37000D908F8C750C6192B9BF0A98101AF045FFB +:10C38000DEF4C88435B9B869220D403A972578F5AE +:10C39000B89FE215987723E0E1EE6CAFDE86F4B249 +:10C3A000B1BABB807FDDFB9880DF4111C0EFDEE3D7 +:10C3B0004E18857860A9120B87FABBF412C1BD0A2A +:10C3C000588428EF1B601CEBE03081E8A0334B065B +:10C3D0009CB7BD401884FBA2658BAF6F9C61C9D52B +:10C3E00034CE329D8EAF671FE5EBD929CE23A3C88B +:10C3F0004FCA6502F26145449D81D6D1202F38FE97 +:10C4000081D08D1A7F53F41E3EBE52185F0ECA456E +:10C4100012F1F17D9502F99315C68EE31A3D9295BE +:10C42000759745C2F673E05FC8D7731A7624E3F7B1 +:10C4300056099C0FE6287CB6552B97B9C9ECAA7C07 +:10C440009D93CCF93A2799F37572DBF7EAC8EECEE3 +:10C4500069F8E820AE2B3BEBBFDCC4DC84975D269B +:10C460008A1F083A6F12D1051109749882FE24B808 +:10C4700088439223B89F2EF36709FA1F8958F2B8B0 +:10C48000880E9427DAC3D2DA178D88B4C0F347E058 +:10C49000F8D039A0D99B029FABE22AA246EF50DC2C +:10C4A00053307A67E078845B83ACA88FA718EB6879 +:10C4B0005D1ED8CE50CBFD2CC372EE67D1BE1AC024 +:10C4C000A655DCCF9CD2CB3B80919EB3E40BF1AC64 +:10C4D000CD2F2EE19F86E7651ABFD88471048C7B2F +:10C4E000ADE5FEA05EF65F8B5769FD85294B54FED6 +:10C4F0002275EB2DC7F11A160553DCC584FE84CADC +:10C500000FF8876EBC13F5B033414FE72F0D2CD0D9 +:10C510009FB0331ECFE4CFF5B29F383AD9A0D97F70 +:10C52000738E60A9888722D44389A86AECCB319E98 +:10C53000778185D662DC6C94B888E27F45D5FC5C57 +:10C540005A60FCEF42E587CF637BACC7E70BBAFCD0 +:10C550001487FB9BB02CB50BB782BFD1E5F0250744 +:10C56000CA07282AC3508C03EEFF06614117CE8408 +:10C570006CFCBEFB79ECDF69345B506F3D131C46ED +:10C58000FD2C5C28507C788985CBDBA1AF4237A29B +:10C590009E52E2BDCB8667ACC5734B359B1B27987B +:10C5A0007BA37A60746E8939F7FEC506F329BC0C4B +:10C5B0007243F047136CE1C0E71F7AA79A014FCF8F +:10C5C00026374DD0839C9CFBBDF705845F4D3EC054 +:10C5D000E127BC7141086FFE9CC3D54A7F9F4FC0C5 +:10C5E000FECE3DCBE1E550EF84EF17A17EC3790F7E +:10C5F0001568DDFF8AEC7F2BF19E22DDFBBC1CC1A0 +:10C60000DC683FAFD5AE3ED9FE0AFA3B62E8B150D6 +:10C61000F42FDEEE6B7B05EDF78E44FB53C948AF7C +:10C6200016574C34C6B174AC19E90276CCD6D1BEDB +:10C63000F42B493C4EF3568A9DDE57F005FDACFFC6 +:10C6400077FA1999C2C7A5EA67F3BFD34F78DF76A7 +:10C65000E3793D39FAC6FB9917D08FE2B781032CF5 +:10C66000A19EF2A6DAF6E1F8E6FCDA36A21EF5CFD4 +:10C670007E91F8F4BBCA1D2968F7BFDB6A8A44FBC8 +:10C6800037E7F5B7E34A308E20FB45A71BBF344A96 +:10C69000F0FE5C9FC86CA0A72B7C029573EB1B8DF2 +:10C6A000F96978AEB6D198A71A57993C4EE074FD57 +:10C6B00004951FB33F5927EBCDD554CE79FDA41E69 +:10C6C000E9394757771CCF1FB3A13CEE1538BF1D82 +:10C6D000B2DE3D8CE70D3A8803B4C8FAB9777FDB48 +:10C6E0006788B7B7509F030CE6CAD111BE7AA5F090 +:10C6F000711475E17A3EABC55AF219ADFBD27522C1 +:10C7000094830F561A8BE1F9C1C41187105FEDE3D2 +:10C71000905E1E876CE071C8A288E687C198B16EF2 +:10C720002F5D7CD20CEBB83B9F91E503450FF44B9A +:10C7300081499197E0892373799C0BE1FF4D363C49 +:10C7400085E7089BBA34FFE233B40F2B42D94690F9 +:10C75000B3FB8784C66D83714C77860B603BD970C1 +:10C760005368CA3468D79A30BC5B0AE92746FE6131 +:10C770006B82FD02CED7131FAC036784398C3C9EBD +:10C78000E5F8B348F12C477AB0C3D501BEBC323EC0 +:10C79000BBA5F0FD9D261D8C73108E839FEF85BF7A +:10C7A000B86D186F5ADC4740BE53BE3F2671788C77 +:10C7B000FAFB6312ED624AB4BA7D38C3F6D73B0E7A +:10C7C00096C2C71193C2E965CF05FE52E9FD092360 +:10C7D000833570E198486653AFEF0A7B6AE0C9453C +:10C7E000899AF6F7CDE8AFA91F6B6ACEACBC017F82 +:10C7F0005F0C4B0DA7F57F165F871C6AB8F4C51454 +:10C80000F46337895601E6356BD7E62F8651EF1270 +:10C81000C5B94E3589648FC0BD35AAF74FCEB06615 +:10C820003A77ACEFBA84ECDF9C587EBE7B964BBB6C +:10C83000FFA1C4E53BDA37417B5686E7623ADA3737 +:10C84000F1C7E3AFBA7F929D22AF8707B1417C3D2C +:10C85000DCBA1766CAF2763612BD6AF6895664D516 +:10C860009ADE0213609CB7D79B5C4130EE336F1F9A +:10C87000314AAAFD930A5F35062DE0BD23463C4FA1 +:10C8800075305922FACD6D386F64C017B737CC2395 +:10C89000B96E6E744445A3FD027F757B26F2575D29 +:10C8A00026DABF269DC58EFB6173968FA63873B8B6 +:10C8B0006F0A9565B5A3A9DF72DF4482E7FA8209A2 +:10C8C000FE546CAE3F80FD3C136E417B5EAE776ED6 +:10C8D00045BA944BC119B85F35B7FEC0C55FA21DFC +:10C8E000B5F07B1D63C5BF6462FDD83E165D4D5734 +:10C8F0001C6F10F5D33CE2EF9968970A705D00CF8A +:10C90000CBB6E53850EE87D7845A50EE453C4FD62B +:10C91000019FCE48E1FE9EC1C3C73BCA379EFA5372 +:10C92000EA67A72450BD021BA237E9517F28F330E4 +:10C9300080C1C7F20E5F7F2A2BEAC7EBF15CFC9F38 +:10C94000535F8C423C41FB102C93460E233DF35D1C +:10C95000E59070D681DE524A93AC87A7A01E86FE72 +:10C96000EE4DB555A11C8E5BE4D19B518F86982D61 +:10C97000B8FF312E7BA054A29A8FF8FEBDB892006A +:10C980005FC56B40BB3D054AB5DE7EA013FBB234EC +:10C9900045D1DBD54467C50EB12D4F325C874DE5DF +:10C9A00067B5DAE46ABE2CD7CAFBCD02F7079CDB79 +:10C9B000795C7F7EAA632DEA91E6E16CF236D2A71C +:10C9C000CD71E3437FBEF187E99B89CE611649872C +:10C9D000FB0A4AFDF36DF3E0F27DAD79AC94DB7FA9 +:10C9E0002AB285C8179FDE765BB30DFA6D7C2C23C7 +:10C9F0004354D9A9D753F8F94766F15E267DB13B78 +:10CA000058423D3016F71E32FD7E3F9E87C4B84621 +:10CA1000C56ED3463C0F561106EB7CF8FEF8FE8E31 +:10CA2000D7917E8DEFE55CC47B34365C98819CDBCE +:10CA30001A865CC473F63633681B2BFA41B63F91F5 +:10CA4000BEED64BCD7D2674923E744A13FF11D0C7A +:10CA500009ED2DD8FDCC160EDB115F8EE55CFE1CBA +:10CA6000B21C4E93F9B75896C3697A2E870FAC095A +:10CA7000B760BCB378913000CFCB3129D48A2AC0BB +:10CA8000807C9981FCC9F9B2CCD75596E778B91F5B +:10CA9000CEFF81F239D71749ED1439FD53AAE310BF +:10CAA000B72BCD990B615C77805CA3DE732CEE9E77 +:10CAB0008972E2E713A305F909F824B644C50735DE +:10CAC0008D3FE8914F0CB902F18909CA3C151FD975 +:10CAD000DBFC134B7E0CFA554BE2752B99BFFEEB3A +:10CAE00014659FFCFAF8FD53B97D7108F81114FF25 +:10CAF0000963185FBB1025519C74FE0A1824A060BE +:10CB0000BEC19D8C7198F9F382280E56D252B92C71 +:10CB1000546A4FAF7B7DE9B4BF3CD19744E5C14433 +:10CB20008717E5659A6F928CC7F4EBDA9FCBB2F169 +:10CB3000B89BC165B26E88C7B89B43A4FDB8DECC74 +:10CB4000F214D929653F8EC7DD309E87F1BDC0FD47 +:10CB5000358CC3E17ADA14A5D3EC13B68BC70DD7A5 +:10CB6000EEA79535FE65B00EEA4FC5DB282EF74DD2 +:10CB70001F47505F98C7EC09AED70DEA7D36198F75 +:10CB8000757A7732DAD1BA4A8E9FBA556201ED379B +:10CB900031163C5E755EF75A7C3CDB9748F851ECE9 +:10CBA0008BA2B77754D1A1CF36FD7D2DBB532EF389 +:10CBB0007B39F2BBB5BD9D51F835909F15FD6C8852 +:10CBC0006E213D7407BC82FE83A2AF0BF286E5A204 +:10CBD0009D1FF67262FD3B30FFD854470EE2E5B66A +:10CBE000577B67AE03F80EBD4B6F09B91E7DF88306 +:10CBF00081F4E1A2F18CF421946A7D68E8C40FBF4E +:10CC0000B5EF8DF1779ADC1EFC58EE1F82BE56F709 +:10CC1000373F75C4F8BED074525F6E277FAE717710 +:10CC2000A6C727F5BD313D9E278FFF5A7A7C565FF8 +:10CC3000AEC703F5366863D2DBE776F5A338D96172 +:10CC4000067A1EED5943B0B4395E75CEBD4BB84B74 +:10CC5000ADD77BF79F3E0BE97A1D7A7D36B6FB7721 +:10CC6000F57AFEF837C8AF823FFB5DB7C2FAE3370B +:10CC7000B0BE43F85358DFC5B79787403908E47B07 +:10CC8000588FD41F80F1353DDD87E20E2007C4F7B1 +:10CC9000E5C0F728078ABCCCAD1F188EFB06EC1345 +:10CCA00091A1FE0F948382BC57F518A7423D8EF8E0 +:10CCB000DA03328F7A26D04EFCD8D7F12CF28F22AD +:10CCC0000F8A1C5C9B8FDE36E0BAD450769EEB79DF +:10CCD00028D57ABE337FE6851BE4FF55D7C93F6F61 +:10CCE000FCFCFCF3C675F2CFB6FF847F9246BE4BC8 +:10CCF000FC83FA13D76F777E6C0D5FC0F987CE2562 +:10CD0000023F6462DCB969706F2BC669EEBCC2FD7C +:10CD10007AD0E9E4D707FAD55364FDF7801C2738A9 +:10CD2000986AFFBC2F9757F2DB8727060F447B7565 +:10CD3000BDFEDE94A84A6683E70F40A9D61326A459 +:10CD40005B07FEFADF6E90BE4DD749DFD37DFF63F0 +:10CD50003FEF52DFEBF0F3926CE68988CFEFDC7A9D +:10CD60008678BAD67AC0B096E3B9CD5F77EB15BBBB +:10CD700019897613F8E39FFF097F8CCDABBB68065A +:10CD8000BA466D3116EAA1FD243C6B41F10CD31A71 +:10CD90005B12EA1BA6EC0B50BCE35351869DE69652 +:10CDA00091308E3B9F62FE7D03A81F951BDE161FF0 +:10CDB0001198BF7DE41643CB2A8A3FF0F32ACCE1D9 +:10CDC000D1F37D3219CE043854056707C0EB79FBE7 +:10CDD00030BD87F1731FF27359FF8CB3F07D01FFF3 +:10CDE0007E9E37BF2BFA7FF58205F717EECB3D67A6 +:10CDF000C478CED83CCFDE9ED02E654B7861483FBC +:10CE0000785E2FD07807A7765BE34CA2235B363C95 +:10CE10006F5896CDF74D4C758DF9B60EF87070AA17 +:10CE2000D64EE19F3E86E263F467AA13983193F7EA +:10CE300093107F7DEF23FDE8FD047ADF6D8ABAFE53 +:10CE4000F7EFC9653657077C345269877161A57F52 +:10CE5000A0C9C43AC1D651DC664C2A9797669DAEEC +:10CE60009C019E0A53FBAFC1B8D728C6F96252EAAB +:10CE70004D854E1E4762B680F95E6DBC433B98AF50 +:10CE8000A47DDF7D357CD95215B957DE97E95FAABD +:10CE9000E59370BDFD83EF601CE1518205FDD4B9BF +:10CEA000F6A0552C1CE92EF335CB2AB4E5C2FC8242 +:10CEB00098268ED7C6D76C70E1C834F9DE3ED567A8 +:10CEC000AF41FADB756DED399F37086DEFA7EA19B1 +:10CED0007E82DEAF4C1DB206E37E400FAA2738E902 +:10CEE0002A7C5E1700E706C805E330C925EA65C05D +:10CEF0004F7207FBB74FC8F83D23F0F34DCD23B871 +:10CF00003FD79CC0CBADA9DC7F5B23E371BDDCBE0A +:10CF1000B98B0A0FBDFC74863F37AE0754F3263C2D +:10CF2000DD1BA5CC7B52E118985773041B20009F92 +:10CF3000BC943A61CD92DEFEF7B7A44E223EF1F7E3 +:10CF400057D88276FC5E194F5B53EF6EC17A3C7204 +:10CF500082F2569ECDF75F4DF5073A94B705EDF98D +:10CF6000C789F915CA8991F03DC166C8E4FD2474EA +:10CF7000809F5FB57FDF16F03E3344DDC8FB327D16 +:10CF8000C604D0AF20807E2303E0222DECF783A1DE +:10CF900067F09F8A77AE5E1A83F1B32D02DDB1028E +:10CFA000FD6C14E079E396070A43703D2A4A869E99 +:10CFB000D0F6C32DD35ACCA0BFC6A3FE227D5C4CB5 +:10CFC000FA7A22CA39C1D30B6D3723DF542E8D85EF +:10CFD000F61F6F99B106EFBDDEB764B50191FEE9AA +:10CFE0009692357AE8F7DECC3FEDC5FEF4D5A52D57 +:10CFF0006384ABF0696DC03CD607C0CE80F66BAEE3 +:10D00000A1CF9704BCBF28A07E5500BC36005EAE01 +:10D010007D7FDA0CBE7F390DE88788BB96BC7C9398 +:10D02000DAE617B4D92F01EDD9C75A7EBFB386C34C +:10D0300067531F295C1EA282B72C2854F3AF41B658 +:10D040001753A2ECB68EF8F75067FC931A68D79C7A +:10D050009A73898719D3D8DF3DA2166E1495F12EE5 +:10D060006D79384DB51FC89614E23E51E7FB158B1C +:10D070000B71BFE2CEDF29F58B0B6DAAF929EDF319 +:10D080007FBC22E2F7F42F57176EA2FD3F79FF2EE7 +:10D090008297B75DBE128674C9C7F3A358DFC59DDA +:10D0A0003C5F6DE7595D0ACEAFF1317EDFD05903A9 +:10D0B000F400392F6656DAFF6E0C0F5FF812B4DFFA +:10D0C000F398B810EDD7E1859174DEA8B01FF7C7CB +:10D0D000F684F7897910E0C6E0078C18576D7C7CE0 +:10D0E0001495EF8BB6655E407EFCCBB564C71B83A1 +:10D0F000C3092FBDFBAD2AC42D59A99F44787444A0 +:10D10000586276A21FBAD2C070FF8931EB0BC427D8 +:10D110004F98C84F9D56DD9FF67B8A7F3F3EBF3BB1 +:10D12000B42B5E6AA0F83FFCD17D0CC7CA5146AC57 +:10D130009FB1442E9DB753F9DE4F6F7E9C4EFB3A54 +:10D14000229DDBD9ED8B380E92CCBE760EA0FB0A69 +:10D1500047E5FC2A6FF773A4F583797CDD9A44F9DF +:10D160005298450A9B807EDB4DB601FDA2FDEDDEA7 +:10D17000FB49A4FDAA775B8B63906E43FA717ED95D +:10D18000ED2B8E2956D9F592337AC2F37B46E961AD +:10D19000D41BEF75E92D38496EEB2231CE3A43F6B8 +:10D1A0009B814F16BED9011F26F513A9DF63A68503 +:10D1B00078169635FE263A17C7A5BC97D5E2A8C1C2 +:10D1C0007C31865ED220B57F7C6BF2883C9C879F49 +:10D1D000BFFE48FA9CFC6380C7BDFCE21A27DABC9C +:10D1E0003DE0D7E338A26CF958AF9CC763B175290D +:10D1F000EAB882DF0F5D2CCB3F6F77080F07C3F7CC +:10D200000F6D0DA2735F879C7F0F55FBC78A7CCC87 +:10D210000CFBD5E1665A17874B421CF08DBEEAF82D +:10D22000A3F05EC9F306D29B25CF472FF2623DD013 +:10D2300013B70C03BFBBA51F3F0FD0B97CD407C8E1 +:10D2400047FD55E5A3F4E5370B378574241F5531A9 +:10D25000C847F9CF1BE87C755197CA4918472CD2AB +:10D26000DDCC6A607C239EFF450CEEB3CC7CDE44B3 +:10D2700074F584861EE7F3EA138FF36AB33FFDB8B3 +:10D28000BEF254E790BD1075E09D81FE16971968B7 +:10D290003D22C61849EF8961565EDF85C52F06BB62 +:10D2A000BC34345B42FA6E4679C8A27A09F92C2F55 +:10D2B0007CF21D78AEE5F0C244DA073B99C9F7C1AC +:10D2C000663DFA6218FA9F871EE6E7BB6763BE1DDC +:10D2D0005CE7FE9BFB5E1572BE9DFFAB7DAF67FA00 +:10D2E00005EE7BF173A07B16666472BC30C984784E +:10D2F0008A1B4878B9DDCCA420C08B18C15250FFDE +:10D3000028FB5EE22FB97E127502ADD38F55392905 +:10D310007F415E98993FFF25BFB7273E3D9ED13E96 +:10D32000585425ED8345C8789D26303BCACFD1207F +:10D330006BDCBC34E4BF20A2E7CC17667DF16C2621 +:10D34000D26D6C94269E80FC17ED7FFF44F52D3442 +:10D35000BE1302B3A0BDCFFB43DF91489F46D1F17E +:10D36000F4BDA4378369FF9C593C4F0C01786635A6 +:10D37000ACB319F24DF7B884347F3F33173F968230 +:10D38000F4CEFB43901BCFDFCC5812B416CF619480 +:10D3900035F07BDED3567C47E77159BCBE12E39C67 +:10D3A0005F2F09E2E7D4EB8710FF4CD3F1732E2CEB +:10D3B000CE48F1A5B21019EE954DB0EAFE9211E9F2 +:10D3C000A1DCBFF918F50A7CFFB4820FF41B51EF02 +:10D3D0002AE7E859A584F25FA4133A3CE7F5553FE4 +:10D3E000EE9F4E8BB3D279D1F2DF9AAC8BE3399DAD +:10D3F00045559EB9729D377F2DF6AB63D2760BAE45 +:10D400001F9A4B70BDCDEAFB521E820A3DD31B23EF +:10D41000E0B9C4F599329E0A69FCEDC44F7A7650A2 +:10D420001F81786CFEA219F96371A8847191F2AE24 +:10D430005607F51B6AB6703B217F17C79E887CE0B4 +:10D440003346201F7C21E84C3CFF804D07F5E71850 +:10D45000AF6FFBCE921569346FB34537A23BF2DD57 +:10D46000F9FCB5F0DEED4C4AE88EF7C456444E9A0E +:10D470008CF5AF89A49740987E9B8DFEDE6B62068B +:10D48000AE53A7ADD843F39BF3C640BC41C0A6BD85 +:10D49000FE19D9A739327F79E4736BC500BF01A5A6 +:10D4A000FE266E271C22ABAC2358D0EC572AF5E59C +:10D4B0002B0C448FF2A526A27379F55FA9DFF2D079 +:10D4C000E618A447F97603E5EF08BD49A2F6C5D5ED +:10D4D000BD730FC2B88B0DE116011E9539C71A1125 +:10D4E0002EAB150856BE57BEE2F3185D1AEF0F4B70 +:10D4F000938EEFB3FAFB8D8E437B767A6B64DC34CC +:10D5000015DD4F2FD91186FBCE4783DCC978CED7E6 +:10D510003B2FC88AE70A9578DAE925C9FC3E90A531 +:10D520003914F7AB673C9C188176EEB0C56DC4FA30 +:10D53000C375F178648ED92C965C846DFA9B093E94 +:10D540002D9F23A13FCC1F2870BE29DBBAC79800AE +:10D55000DF1B24E3E7CC6B47F70E457C001F5950D7 +:10D56000FFC435A7A01D2ED735A7F444FABC2290DE +:10D57000BF00EB531BE61F998B7C3508F4A1CC57F9 +:10D5800073EB772C40F92C7FEB643EE2F5CC5866C8 +:10D59000C4F858B93C7F583F7EA087F6E5DB36E4F7 +:10D5A00033FEFE07C8778ABD07788901E026238706 +:10D5B000336EE2FCD364F450DEBBA6498CD1FE99F5 +:10D5C0009E8DC47640797E0F4014E5FB6995B113BA +:10D5D00078DE3DA7FAFCDC5CAC4FF3D777C6378525 +:10D5E000325F14579BC82E15CA78F1ACD81E867CC2 +:10D5F00071E6B53D7B87A25C6C132C4C2D0F8A1C09 +:10D60000C679793DE0EF49C4DFB6F3F998876276D1 +:10D610006BA8843454F0A4C89B82970AC6F1A0E09A +:10D62000A5422FE349AEBF5BC64319F3527FAC75E9 +:10D6300080B419FB7FEB07DA6F3B338D09FC9C301C +:10D64000CF8BA6CCCF11A1DDDF5F26CF6FFA4DDCEB +:10D650006E9659B85D2C8B6252F540E2339B51C9EE +:10D660002F094DCEBC714433FEE7653968A337CE30 +:10D6700003C6E9D1F17B8281FAEB51197F47AAA752 +:10D68000B851AFCC76423F99280F96A9B8CFC95E62 +:10D690001765FD0D32A9FA6EDEAB47880F41774959 +:10D6A00011B066316C8171A0FFD5DA9BE28579DD1E +:10D6B0003C34EFCD632C4C07FAE488E009DD89F6B1 +:10D6C000E05191F494324E9BF363A287AD8ECB2749 +:10D6D000F20BC60715390D1CEF3279BC269DD58398 +:10D6E000E782D96281EEAF898BCF841EE4F68E2269 +:10D6F00089FEFE6FF900F7236D17C324816AAC7AA7 +:10D700006C37F7625802DAEF2372DCE1C8D21D6190 +:10D71000C52A3AACEBEC3BCB864848FFBC90838FE4 +:10D72000A11C3D759320F3BF75E442D40797C22432 +:10D730003C2FD514E14C433FAA49C796B308CE8786 +:10D74000FA183FFE405E087F502F3D65F1CBA532B1 +:10D750006EA09B1BE906ED6D5C8EACB48F31378AF1 +:10D76000EF8B5E5B9E323CA49FAA056963A6BF9DBA +:10D77000722FEF7179DE2423317E7B80FC89F6CE17 +:10D7800024E7310ACC837A7BAFAE7188BF8A10B3AD +:10D790000E977081F581B07F3D55A9473F9F2D8938 +:10D7A000DDABBE977634C849F7CFBCDD45B611E88E +:10D7B000513DEF237E9EB781DFDB52EC34FCAD6A36 +:10D7C000E33F78AF34F37C3EEAD73FE698E85E5318 +:10D7D0004C7F7EDEE514AB330E47FBFF6D737E9806 +:10D7E000E45F9FDC72D12D8693BF10AF591F94B5B3 +:10D7F0007E40F25CCE9AE93EF6B4159F8D1D82F410 +:10D800007ED940E70766D4C6939D3BB9697A06CEB8 +:10D8100077DAD26482676D7E90C32B78FEC3694B42 +:10D82000B35E42FFEB68902D1FF9D9BB5AB0E0FA06 +:10D830006AD8E6AC45F741FDB0D03E5D71DC873675 +:10D840001D1D8B743FB45024FD64DBF4D424ACB7AD +:10D85000ED14F1C618AC672C8B30AF29D3875BD0A1 +:10D860002F50CE17D618B8BE3D2FEB87936D25E706 +:10D87000D3BC9A9A14F497BC1BC01EE1BEB7D15B0F +:10D8800042E7BB058B7523F0CBB782936066B1246A +:10D8900054E7E07D96F5941FE75CB2C9827EF2FD05 +:10D8A000266645BFF6FEF77A0FC2A5824D5E578DFC +:10D8B0008DE4DF55F0A57CDF2BF33D135795D0BEEB +:10D8C00043A49480FAAD493E377E541EEFC9252FFC +:10D8D0004F42BFE0E496E408A6C2FB49394FD32C7F +:10D8E000D083DB3A58EFFD7893127770D1774AE511 +:10D8F00078E03E436D2FCCFB1978BFEBC486203314 +:10D90000E6E70DBCE775C2C0ED47BBFB5E3BB570FB +:10D91000609EDBC0F12865BBFBFFFD433AF4E315D5 +:10D92000390B7CBFDD7DF2A4EB3B5F8579C9F0BE8E +:10D9300077D34D8CC63932F8C737515F97D49A2CBC +:10D9400078FFFE589044EB2167169336A39D314B28 +:10D95000E1B89E3FB62F83CEFF957CC548AE4AEA1C +:10D960004517A62AFE6075DFDFE502FC60BDC18AAF +:10D97000EF9F5CB37A1217336D9E856CC6E57326F4 +:10D98000AC93DC16FFBA2870BD347BED1B748FF0AE +:10D99000E75A2F2971A4407CDFDA5FCE4FDAC9FD48 +:10D9A000B9F7806DB207B5C7776B9583D64567AB7E +:10D9B0004AA9CCA9DB90D753C2FB14477E3B0CE5A8 +:10D9C00026349CE221AD5595B489777667C665BC4F +:10D9D0001FFA6E48B805F5C5D9AA85F2E502994F38 +:10D9E00064BEBCA5BE51ECC9A87DC33068BF3B2452 +:10D9F0009CEEBA24D9B2C3D1CE2B740DBCDFACCC13 +:10DA0000EFD4A39CAECA784F6D991E867E67E3BAA9 +:10DA1000C8869C283C9E1B6E417F7BA67CFEE5F859 +:10DA20005AAE6FBE3587BF3406CFCFAC9F1883EB9D +:10DA3000BA070D5EA315FAB5EE1A1F8671BC6FF416 +:10DA40009E30BC6FFC0DB477A39DD0BB44D4734310 +:10DA50000B18EDE30D75EB99144F5BE6C41739AD68 +:10DA60007A17D2F5B4FBE29E2BC847AD3A8A77010C +:10DA700066F65C81F6D6D03E14277CF06DBEDE647F +:10DA80003F76E1F501F7169FE9CFFD9613EBDF1C1A +:10DA900047EBF34D060B8EF3ECA6CF63F01CCE6C78 +:10DAA000C6CFD77FBB45A079CC067E0C8A47FDC088 +:10DAB000E3A0B341EF9B85F67C98B7A59AF8703642 +:10DAC000F021E6F59E6DE3F99867633E6689B5CB74 +:10DAD000FFD155E6BB39C077787FF7E7CEFBF13B46 +:10DAE000850F03E45EA1BB821785FE7E3E649AFC2F +:10DAF0008211750387F7647E7DA0DCEF607ACF2A00 +:10DB0000BCA7B1400CADC57C55FBF5957FA0BC2DE5 +:10DB10004E3DDB4CF69CA562BEBC05E24D568C0723 +:10DB2000D6182BDBF2BA607D605E173184BF3F1ED2 +:10DB3000F313C37CBBA6C5D3F72658ACA310DD8670 +:10DB4000280FC505C43C9D8DEEE5D59868DD1CA861 +:10DB500087EA64FADE95C6F5D0FFF4E7E7B5957B72 +:10DB60007F4A099AB137F2FBF8E0884B1234D9D5D5 +:10DB7000FFD0DDB84F3B7E58C42F12E1FB7B5F3DE9 +:10DB8000CAE18C88ED090037F5FFFA6EBCC731FE9B +:10DB9000E6882C03FA01D5C7EE1E09F0F1FEB67730 +:10DBA000FBABBEA3F40BCF77E3F37FC439DEEF4FBB +:10DBB000CFBD2548EF734218CFF796E4A538A8F2F9 +:10DBC000DE01811D7E57F0C31E038BC3BC06FF839D +:10DBD000BA3BBAF3B27B9AED63FE7DED73A4D077C6 +:10DBE000B8CE94F77F7466C988FE9FDD6AB4F2FCF4 +:10DBF0008ACC6E06BFEA2E997F8BCD974792FDADFA +:10DC0000645613263059AEBD8FD5CF7F6F6FFD8D13 +:10DC1000DCDB634E9E87AF46CEC3D7D93D4AA1E138 +:10DC2000A31FD0BF0CBC3F95F149F35BC827E3802D +:10DC3000AFD05E643673F82E994FCA778CA57CCF2F +:10DC4000F30F185CE827CC92FDB12447172641BB9F +:10DC50004B20BFA8175AC7B953507F9CA862B5493B +:10DC6000A0B00ACC8E4BFD014F4DF11F515EB41395 +:10DC7000EB6BC2D0EF3903EB8931D04599ECDFB3C0 +:10DC8000CBA2FB36F483E3FB6D5CA9E2B79F643E55 +:10DC90006B8D77C7E1FAC6196FE2F91A2FEFA13C35 +:10DCA000CF0509A3B3308EB4BF6A273B9AEC7FAF90 +:10DCB000B3FB284375230C69AA7DC971FA8ECF691D +:10DCC0009C51F2696EE2F6DBA4AFA53C5A40CACA89 +:10DCD0006A82ED14578A451EC5F8B0F410C1CB66B0 +:10DCE000310BDD63F5EFD3D17D5085FE36EB959199 +:10DCF000D86E1CD01FF58DCEECD5236C2FE0E753EA +:10DD0000FA01E1509F28F41F252EFA2DD261BE7C26 +:10DD10008F6BBE50C9618399CEB906EA478C6B16EA +:10DD200091DE74EECD417F0CF424E55590F5A2040C +:10DD3000FFA3BC48D91B8CD4ECDA7991F6E6FC073A +:10DD4000FA31234D9B475CA193E25F754627454F0F +:10DD500002BD86A5455F3FBD943C65F39FE7F1CECC +:10DD6000F9CF4F8F1D44780389437F28ED4F44C47A +:10DD700099F21CD8FA48E263C308BB84FA76ECCE69 +:10DD80009E4C8247B3760A74BE75CCCE4882C37C63 +:10DD9000DD795E25D9DE8FFD63B711189F3CF9D27E +:10DDA000DF1FC6BCF7637EC3287EAC0B0EA17C13BD +:10DDB000E208398F8318F221DE63BD20F1DFA1B0C4 +:10DDC000B376F9037444FF267E4E1656794E4E27DD +:10DDD0007EEF6FFE3E6EE7E70FE7FB8217F00D6800 +:10DDE0007FA150A43C4DCF04A793FF5673B781EE9B +:10DDF0004730A7ED2FB8AE9A2CF383291616962A32 +:10DE00007A054920AF2AFA3C1EF4DB0F1DD0BF076C +:10DE1000D65D420FC682532334F57A67D037983FD8 +:10DE2000D6102B5A5C30FE506B0F4D7F76B1CC80F4 +:10DE3000F114E6E07EB4C25F4C6CD5D3BDF95C9EB4 +:10DE4000BFE2EEC9DA7B9286DCF323C9DEE46AFD29 +:10DE50006FFB35F236FD4AE1A77EAC9F9C979EECA6 +:10DE6000FF85167E3F4462F6B58ABCA0FE07EFE64A +:10DE700019C4CFA42603734984BFD7B0FE82D364EC +:10DE8000C178409B1F9E04EF45A19134139F635EB0 +:10DE900050F53C312FA81A2F9817540D635E50751A +:10DEA0007BCC0BAAAEC7BCA0EA7ACC0BAA86312FDA +:10DEB000A8BA3DE60555C3981754DD1EF382AA6142 +:10DEC000CC0BAA6E8F7941D5F59817545D8F7941A7 +:10DED000D530E60555B7C7BCA0EA7ACC0BAAAEC7C9 +:10DEE000BCA06A18F382AADB635E50753DE6055557 +:10DEF000D7635E50358C7941D5ED312FA81AC6BC59 +:10DF0000A0EAF69817540D635E50757BCC0BAAAE51 +:10DF1000C73CA0EA7ACCFBA98631EFA7BA7D335B78 +:10DF2000928C766C77BCE37FD268DFE95BE2E783B3 +:10DF3000F7033FA31C364DB450FEC21B5C277E9EE8 +:10DF400026EFF7C8FC7B89854CC573E89DBDAFF013 +:10DF5000E7EBB2BF01F66039F12F0BAD457FEE71F3 +:10DF6000BD8DEE4339EBF8FD44A6E77EC00251F6C5 +:10DF70007FE4BC100B4489FC00CC1DAC578DA7ABD3 +:10DF8000CDCCF42A3C4416583470B43D56D3BEDB95 +:10DF9000644953DFDD91AAA9EF596AD5C0BD2BB3FF +:10DFA00035EDFB2CB469E0786781A67DE272BB0693 +:10DFB0004EAE9DAC69DF77AD4353DFCF55AAA9EFD5 +:10DFC000BFA552030FA85BA8697FF34EA7A67EA04A +:10DFD0007BB9A63EA3A956036735AFD5B41F72D04F +:10DFE000A5A9CFF16CD1D40FFBB64E03DFE2DDA9BA +:10DFF000697F9BCFAD8187B37D9AF679E6031A7866 +:10E0000094E54B4DFBDB638F68EA474B2735F5659D +:10E01000A7B97FCF6A607D8071CA109E5F63AE9B97 +:10E02000D5A17F7167EA794D7B4314AC17807FCA15 +:10E03000411FA2DFF77D9738CAC7CC2AC3AC78EF5F +:10E04000DB39A2F20FEA7BDE63AD3F68BEFF4C70A6 +:10E05000983B88D61766B2B7230624907D6CCB27F1 +:10E06000A2DC67675E161B4521212FFA4702FEC21C +:10E0700012C061369E171AFC20F29F2CE017A1BF38 +:10E08000D9B62ED2C5C7A35D0EF6FBC5BDAEA8F2AC +:10E09000BC5CCB2FA66F67519EDE5103301E5EF72E +:10E0A000463EAEB36631E732DC4F54F22CEE0FD26F +:10E0B000C6B79472B419F0ABFADEBEA0DA5E83AED6 +:10E0C00022EFA3CDADD4BEAD5F39FE25C064E7AB72 +:10E0D000FAFF2DACFFF420D7B555207FE00F3D5956 +:10E0E0006521784D552CC14F574954AEAD4AA5F224 +:10E0F000B92A2BD5AFAFCA26F8852A1BC1AEAA0212 +:10E100002A3756D9E9F9A6AAC904BF54E5A0724B2B +:10E11000552995AF545552FDD6AA8504BF5EE5A496 +:10E12000B2AE6A393DDF56554B707DD55A82DFAAB3 +:10E130007251B9B36A0B95EF54D5517D03F86F084E +:10E14000EFAE7213ECAE6A22F8FDAA66823FA83ADF +:10E1500048F0DE2A0F954D55DF52F9E72A2FD57F7B +:10E1600052E523B855DE87583440D0DCC753603DB4 +:10E170003BC6FD3DCC5B817918B20D67AF961F376A +:10E18000900EA7E4FE0D23C05DC238728F948D35CA +:10E19000AA75C5F201DC5FACD6F1FC2DD53D98A582 +:10E1A00086FC761BE3E7B4B8DF3E13FF25C1D3A896 +:10E1B000AABDB8DE28A9E479CAB3901F53891F3FCE +:10E1C000B9A1759ABC2ED891687F6600AE43425CB7 +:10E1D0005FC467FAEFD11F4C743C877C7AA1F2C10F +:10E1E000BDD87AA6C59A821F196B724763FE2FEFBE +:10E1F0003ED1BA51EAFC7B15F2FD874EEB779FECDE +:10E2000085F6AAE02791E2FAFB0DA193719F7FABFF +:10E210008C8FAD03749AB228C9FE2A8EE74472E54A +:10E220004B0F09FEFBFB77E1121FE47B3C93280FA9 +:10E23000CE4466FB105DF0BBC11144F81EE6A4B2EB +:10E2400035C1518FEFDF0B0B10841D434D711DCD78 +:10E2500027703CBBE5F1EC96C7A1940B92ECBB1088 +:10E260006FC7926D9AF16C95F3338C63DE17705C17 +:10E27000FFDC75FEB890E8C7775B3C8555529E8CF5 +:10E2800022C6E3298F635E8C287F5E0C65FD50B447 +:10E290008FFFCE11FDA1FD5C104FEBDBC0BC19CB95 +:10E2A00086EFE17930603D86F77F8BE6FD82F42FC3 +:10E2B000FE1E14DEDB5DD0E530E599F1CC025EEDAB +:10E2C00049793578DE1B0720B027E5D5A07AE1260D +:10E2D000F87F771C9739554FE3EB42F94E9E09DEE4 +:10E2E0004F796930A660EA8A798F79BC66BFFD3CB8 +:10E2F000F7BBA3BC743F7547A2E3EB013C4EFE7431 +:10E3000006C689909FF03B16179D5F037E320A80F8 +:10E31000A29951C04F1DF81B0ADFCC95EFE128CF21 +:10E32000811F5B11DF67DF1E928A7C53B13B47423E +:10E330007CD7E8F87D3AE79FE57D41F9F710C4F016 +:10E34000B40D74EF009D71A46F4E28DD3B6814D9A5 +:10E35000C2373AD0AFA1E95CDEF7C7F27C92350153 +:10E36000FB93C6744E77633AE787B1EFEFA33C6443 +:10E37000739B78BC9A657AD2EC1D9CCBAA58F89B0B +:10E38000A79354F3A8D879849FE7629E34F539AEF9 +:10E3900064F9FB0AFF89C650C78610F5F878FC01BE +:10E3A000E420243D8BE4E038DEEB1E6792C2EF11DF +:10E3B000E8F7C1CE627E19C71F2C741E503917387A +:10E3C00083D9A99C099613F9DEEE5C4DF7E767B394 +:10E3D0003A7A3E377B7A1CC215CC3B3216D747CBF4 +:10E3E000AB3FC470D0C4DAD5A3BAC3BC26B8A67DEF +:10E3F00088E5F84DC271A74472D43B1DF7B785CAB2 +:10E40000A53DE07BF76D1DBE14E3D6E3444E07F651 +:10E4100031A74311F0B318D17E7E203749E95C6EF5 +:10E4200068FC8ADC142D66363C7FA0DC0F6993A360 +:10E43000EC39FFE8897B38E04F22BF56EC3645D0F7 +:10E44000FA14F3CCA0BE92E567A99EFB974E4C6DE3 +:10E450004AFA93FB1B069B9CCF8B717F648E93AF14 +:10E46000C74E19B8BC9D3A14EA42FE5ED0E5F538B5 +:10E47000920F83221F3F4DA5F33D0CFC8F5BDBFB0E +:10E480001F6D79667A31F237589C237650A2DF9E51 +:10E490009FD2B90687F1BCFCA3105F7B63F9FA79C0 +:10E4A0000EE6A1C1FAAE7609E3A5A7A2CD745F2856 +:10E4B00030CF1963569A9F419E1F8C6C32FAD32637 +:10E4C00039AE561330DFEF83E268BED27056C7D044 +:10E4D000B1D05B9CD351EE1FE2766241975F3BF077 +:10E4E000FB9E20661186D17C281EEBD4317B0D8FDC +:10E4F000CFD2FC16EACD163C97B36C9AE811C84E01 +:10E50000C038319E1765B6F2BCAA4AFEEDC0F1DAFA +:10E51000B4E333C7319C9F4D64DEA0617CBC383EC0 +:10E5200027D083E803F034D5F8A05F17E5FF0996FC +:10E530002CE88735FDF8108F2F5773FF11C6BF8564 +:10E54000E8D31DC6DFF3DAE337208BC2F817A4C780 +:10E5500013DFD5E00EA28876B62BE9DF0941F64736 +:10E56000900F931C2B7BCDC7B8468EC98AF13B76A2 +:10E57000B9A617EAA91026515EAD71369E570BBA9F +:10E580005B82FC301EF3D659C80F6855E761630102 +:10E59000F135200BC55727607C8DDF25FA00E3B3EA +:10E5A00013E5F3CDFDD8570AFE28BE26E2F8285E13 +:10E5B000EDA0719A90B25006619C87E8E0A27904C0 +:10E5C00033B71CCF6E26FF60B5CC87430F32B21332 +:10E5D0004343B89DD87D84B9F0DC57E30F93F242F2 +:10E5E000A17EF7793DE929C013E5037CE7736E57F7 +:10E5F000769F3CDE13F703AA7FD8DB13FDC4DD064C +:10E60000875881EFE7982C8BADFEB846C3C1101E2A +:10E61000D791E37CB7C8F36C60CD3515509FDD5DB5 +:10E62000641807CC6A7107A33C638EDA8EF61B73FD +:10E630002F1A35BF6B61B068E16CA682E3F1E85137 +:10E64000C0EF7FDEE03A775BBAF6F729DB7EF7B3FF +:10E6500035EABA7EF733539EC7AA74FBBBE964D789 +:10E66000268832DE05C417E88146C4F773E546FA0A +:10E670005D83C67263778F6A7CB5B3FE49F87DEF20 +:10E68000C77F92DD7A2F4BC98F531784CF8DCE5021 +:10E690008ABB3D77594771B775A55FD3FAA4369BFE +:10E6A000D1EF88D55E2E263FE05201C34D24567D22 +:10E6B000EBFF9622FCBB5BCCF4BDC0F1EF027FDE2A +:10E6C0000D847A17FC79775FC6DE067F1E61BCCFAA +:10E6D0008AE576F0E7B174813F8FE50BE0CF633BCD +:10E6E000F4E7B17C0EFC792CD7823F8FE5D3E0CFE5 +:10E6F00063BB35E0CF63F924F8F3F81CC69547E314 +:10E700003AC8E8DEFEE2E0B015E86748CE50F237DE +:10E710003EB50DEAE251D9D95B2FEA3474CE6DD5FE +:10E72000FEBECDD063119ADF3FC9FEAA87A67E70D8 +:10E730004B82A63EDEA9FD7D9B3E0BAFFEFB363D28 +:10E740004B4704FC3ECE1D01BF9FA3FD7D9B68FB94 +:10E750007D01BFBFA3FD7D9BDFC9F932153AA648F5 +:10E76000AF05215FAC2B9D10CE3AF02F94F2499962 +:10E770001E0AFCD4A3E2E48EE2C85137737BFFFE8D +:10E7800021D3BE4D80CFF758B81DE3EEEFD974A466 +:10E79000979E5B1B4271589367E849E49FF76C4C66 +:10E7A00042FE79EEF2882E389EE140467CDEB3943C +:10E7B000DBA73E374BC4CF3D4BBD22DE17BDEDB2CC +:10E7C000D78AFCF85418FF9D2DE8D7B518FA7B7F3F +:10E7D000ECE07E18C7792E04F819E5CDED0D4E0258 +:10E7E00038FC8A8EA17E045B4979FE9DCF86C8E7FE +:10E7F00051AFD07DB870D4E9A097DE2BE5DF4FF1A3 +:10E800005C0E56FB43BFFBE95A7861C4579DD6DFC7 +:10E81000313B01C7EBC73BA84628535829FB2DE2E3 +:10E82000A38CCB4F6DA98EE4E912C813E207664DA5 +:10E830007461CD5A797F12E5434D87B2841538CF84 +:10E84000E7D6E869B76C94B875DFCDF0CABA16910F +:10E85000B6D9258B37B823FF4E19F73A1B9F5F8433 +:10E8600095E9D0CE45003E5DB49F6DAD56FF9ED577 +:10E87000B3B27CFE5E96CF67647EC0F536C2A3C499 +:10E88000F5A353701CD95C5F033D05BC8F75690609 +:10E89000A3DF11FD7D6142978EF27CAF91C7F182BB +:10E8A0003CAFF5D82FC93397FB5162D170EC679D0F +:10E8B0009D911E5F67FBBA1AE376970A79BF7D16B2 +:10E8C0007904C46FAF4AAF80FDF77ED84DA54B1ECB +:10E8D000678FD266AA57FA93AC2ECEEF655FB32648 +:10E8E000982F1EB215C95EB4527ED4757A3D433B53 +:10E8F0008CFA0CE14B663D9E91603D661D63789FEE +:10E90000B936444FFB14EBE69E2278B585C361CE41 +:10E91000CA343C7FF1B63C9F30A7936057C07C520D +:10E92000A407C2D5BFE71A58EE90F1BC5DC6C7DB9D +:10E930000687EE028C63C85F45FAFD8ECEDE53EC8F +:10E940006CF657BA00FDD34523FFF81B7BB25DF888 +:10E95000F5CDB87E76DAC92E28EBB6ED63B87D5DCD +:10E960001D3CF5635CF717CA7CF44CF0B80FB1FEA0 +:10E97000B3D1FC77701A47DFDE5BAD2777CAE3DEE1 +:10E9800021E33DC7693BF430B41F6F37E1C8C08C49 +:10E99000D97AFF02FAB38F11AD6EA05B4B96220FAE +:10E9A000F66094BBF7C74C6707B1FF02BEEFB4BD7A +:10E9B00060223D9798FDCE01F0DE5F9AF5E4CFC06E +:10E9C000F3ABCAE37E19FF9FC8E3F8B38CFF269927 +:10E9D0004FF7A21DE98B7196542ADF97ED885BB63D +:10E9E00023BB653BD220DB91B7D18EF4C5794DA610 +:10E9F00072BB6C4732473F457ED225CC8B2BA01D86 +:10EA000099CB96C138F361FC6207F6EDAE6C31E04C +:10EA100077B2823574BA333552038F967A06FC4E3C +:10EA20005762C0EF78F5D7D4E79933027E076C9828 +:10EA3000A6FD6DBE1101BF23A6B523438F4DD0FAAD +:10EA4000335FDDA7A91FDC52ACA977E23F60BE5956 +:10EA5000C718CF2F1B9CFB04F24BD671BDF2FBCC29 +:10EA6000B48FA6F85B81FE4F166BDBC7D3D13E9EF9 +:10EA7000934978AE93B6961334F5E43FB518EC3D60 +:10EA8000F1FC61F578E03B3C87D8523286D13E3CC0 +:10EA9000F02FC85396FDC457946F542CCA203FE9F9 +:10EAA000A25EB39F9613B02F661FA9DD37CBBAC6FF +:10EAB000BED9B19B3BF91DF6D688EBF2C7409E4408 +:10EAC0001CF733C153F720DEDEFE92DBA9C62F1FF1 +:10EAD000E989CF3FC0A6D0CF8E6F1E21BF6B479B69 +:10EAE0007C3882D5FED6760FB7176FB524ECC47587 +:10EAF0004666B4407A30F3C8FC29C48F2D3AFA7DBB +:10EB0000CE94828A60C4CBF6838B83B5F7A754FA80 +:10EB10008108A5D20F22B232FFBDBEFF07E9D10F97 +:10EB200034008000000000001F8B0800000000007F +:10EB3000000BED7D0B7C14D5B9F8999D7D25BB812B +:10EB40000D09B08104260960AA3C36EF4D48C22465 +:10EB5000048C1AC8427804C1304978A48A9AAAB5AC +:10EB6000D86233211062A4121F55B08A2BADDAF699 +:10EB7000F6B65425A0A22CCFAA5058306844D4052C +:10EB800014ADA5F7A284D6F6CFFFE73DDF77CE24FC +:10EB90003BC32640DB7B5B7B6FF8E9E4CC3973E653 +:10EBA0009CEFFD3A134208F94AA4FF8B1F4E0269FD +:10EBB000047FBE4A81FFA7F4B6A19F5C4D02F6F028 +:10EBC0007686A19D6F185F62685F6F183FD3D0BED5 +:10EBD000D130BE56D7BF2D3473A0E2A4BFC3CFA49B +:10EBE0008BAF5B1A09095CD53B2EDBEC133D632F21 +:10EBF0001E97D369EA9D97FEB7F3FD25A6F3F1842E +:10EC000074748A7E5B32BD1E5F42D42C3A4FA7C912 +:10EC10004F04BC9A08EDDFD6C5DA36A23AC6D3FE59 +:10EC20002D9D664F9B44C80EFEDE31BE85037D31AF +:10EC3000844C329F8DF85EF982A9777F04E69B3978 +:10EC4000904418A75D77F179038D76BC6E6F74914F +:10EC500080ADB75F8CC9EEF4D17574844C1E7A9B7D +:10EC6000AEBF248ED07DEF762E76C0BC74BD840CF2 +:10EC700023E4DACD23AA9A461122D1759BE83EB649 +:10EC8000844CA48DEE33EB287B7F96458E734580B4 +:10EC90002B21263DFC2F9A8FFE009C9CA2BF8DC28B +:10ECA00065D7FB73E2C6D3F95FEA1409ACC7AAD4EF +:10ECB0003B7CE368BB8BAD4B9B77B25DD4C1A19825 +:10ECC0003874F8283C3B48D7CE3A41D7499FB74AD9 +:10ECD000157100DF4BAD939068031D0D32B487E9C9 +:10ECE000C68F9128DEC6F58D8797381EB6001EE8C0 +:10ECF000C65E8AF254F922C06BCB07D67A7FD8FD64 +:10ED0000660F054A365C4D78CD3A61F204287CCE18 +:10ED1000779A3C00BC3C57BBD810619EFC8FF4F442 +:10ED200099D319AD83171117F4CB07CB8F37ADD912 +:10ED30001336FEFB9E98F8D3D7D05F72492EEEFFB4 +:10ED400012CFFFA9515DB3C742E99892EC663A8EA3 +:10ED5000B82A0949E87B3C212B717F1A1C892B8E2C +:10ED60006EEE72F0D48ECF5D84AF3E9EEF9D472550 +:10ED700064308527052F8C5B3BDEF7B887B6496882 +:10ED80008608EF7FD0719B18A2EB7ECC71DB6EA062 +:10ED9000CF037FB64AC0D73BFFDC9108F7F7A76FD8 +:10EDA0004D04BADF4FDF1D84FD9929D668DBAADE4A +:10EDB000E400FA7AB3F308F28F4482374CC882B683 +:10EDC000C9D34687BD9A563990F403B7D7399DEC1D +:10EDD000E3FCBA87F3EBAE4637E76309AFAF35A67E +:10EDE000E1FDED8D1E6CBFDCE8C5F6B64619DB1DF6 +:10EDF0008D65783DDCE8C3FB871AABB0FDDB46854B +:10EE0000D161DA9DA5208FCE275200D07DAD744C04 +:10EE10003747C2E775929ECFAE75EBF96C0A8573E2 +:10EE2000787BB27DB8812F5375FD93BEBC5AD75FF6 +:10EE3000783643D79EF869BE6E7C5EA844D7CEED87 +:10EE4000BA5E377E6669A5AEDF57305FBF3ED189B7 +:10EE5000F265874B40B93C3DAB4ED7BF037E0139CD +:10EE60006C17FC6A32C0A5B25F791A00FCD8008E1C +:10EE70008C8F7FC3F1B317F06303BC30F8BF0AF087 +:10EE8000A7ED5700DEF49ADDADEC1E28811CA8C763 +:10EE9000B6356DA0D343E1FFAA5344F9BFB5B10124 +:10EEA0009FDB7FBEB65BC4F53A24C0CB0EBE9EFD91 +:10EEB00016A55B8C87B620AD142E5E5776979EDF25 +:10EEC000C7942D44B9B9A3F3A403E8EDB52F2F4F90 +:10EED000EF69E37E432A27037D1475525D957C69B3 +:10EEE000FDA7E9AD4BCDAF8D03BD1A495F18E7BD56 +:10EEF000FE4B4524741FAF76A90FC7403BF04D5120 +:10EF0000A2ED9C2E6532E06D4F9AE012051C375938 +:10EF100086755F387203DC7F2D6436C1BA0F5C18CA +:10EF200044601F3BA8DEB5D1716F92D4B51328BCE5 +:10EF3000035D5FEC07BE549D16CF6872F13A52D361 +:10EF400045942B5BC6DA4CC204D0776612180B7C52 +:10EF5000AE203C3BBE4C71C2754B9AC8EF0791DFA7 +:10EF6000C7A7BBF0B9572F64C443DB4482280F0204 +:10EF7000DDA6327F84FD8E87F750B9937DE143870C +:10EF80008B8EDFD75DEB00F9F25A179B3F7B45C8AC +:10EF90000170DAFFE52627DCDF919689F3EE1CB7D6 +:10EFA00014ED8B1DDD26A4EB1D63D73833B2709FA3 +:10EFB0001E80DD8EEEDAB5E940D75D666C4B4421EC +:10EFC00041A0B734A667B774D79223B4FFBC47F407 +:10EFD000039D6593F67D03E0FE90355692C2E06F87 +:10EFE0001E42C8ADEC6132D9A59703255D7A7D62DA +:10EFF0000D2D983503EC08A067DA9E668ED3F5EFE9 +:10F000007F7765FC4CC00B8537DC7BADFB8EFDE369 +:10F0100040FEF859FB0FC77F621D48AF4DE3D60C89 +:10F02000BF0DC66D71786C12F428E40BDACEED36A4 +:10F03000FBC1DEC876EAD7B1FF1B9508F72DDDCC02 +:10F04000BE3A9FC6F6B3C353471EA0CFBDCAEDAFAD +:10F05000C9274695C3FB0E50FB09EC8A573C2FC4C9 +:10F0600065823CF38A3A7AA3F0417A39DF49701E0F +:10F07000FA33601A8543011B42F9D0D77C3BEDDFA0 +:10F080009F6773ADA4A8DE7161D7EE3B683B374143 +:10F090002422DDC937FDFAF5E5FDD4A16BDFFAA91D +:10F0A000DE2EB11181EB7327CA81BEF867E259AB3E +:10F0B000EEB969669B6EDE5C12D68FF8B4F6F62761 +:10F0C0005FDA3ED9CAE59A669F6CB528F37D40D7D2 +:10F0D000C15997D0A32BB9FE6D4079B18D104F5B0C +:10F0E0003A95EBDF1065E0C3F3C7ED08C7DCC766F0 +:10F0F0004C24A8AF9589C00F488C61F680F7F8259D +:10F10000EC15974AE273F8AB085CCDA743747C2BEF +:10F1100055F35F810EE7FADC386F5F7AFF41C70075 +:10F1200094FB05A54C2F3CE638887ABEE37DAAE720 +:10F1300005F68E10C5FB6CF805F4FEFB561CFFCAE5 +:10F140007502CA11CD6EA824B285AA3832DDDB6DF6 +:10F15000FE01C59FCF5E3DEE567A7DE5DD8EE1C0B6 +:10F16000BFAF807D80F2A1C1C1EC8318358E2E71B6 +:10F170007B970DF970EB5913B183DFB0DD86744ACC +:10F18000F9F4FE71F43DDB83CC5EE838CBEDBDEDE8 +:10F190000EE4939D7F60EBE858E1607EC619AB0CEE +:10F1A000F6F8D6153108E731524CC00CF32D67F351 +:10F1B0007771BCBECDF1BA9FEBAB37B8BEFA0DD8B4 +:10F1C00013A8BF983DB11BEC097ADDC9ED891DA0DC +:10F1D000CFE8F5C5B3CFBF077C797E7B14DA9D639A +:10F1E00048DA6658D776A715D76984F33C45CF0728 +:10F1F00073ABF47643F958BDDD70FDA8E1BA7659DA +:10F2000062AAEEF9A9F1D7E8FA4B9D997A79649E42 +:10F21000A86BCB17F4764385F7063D3DC9617603AD +:10F22000CA3BBDDF383BDC6F4C063C313F676BD7D8 +:10F230001D88C7ADC753062A6176C2360EE7ADC733 +:10F2400099FEDC16FA22468960477CCAC77DC6F162 +:10F250007186E3E33F46C8BF4B1F0CFCF20593BF2A +:10F260007DD0B1F6BCF6DCA7FE5303C2F5FA4851D7 +:10F270004226D1DA7FE8786F0CF45F2E5F503A6D4A +:10F280000D513C7F478C696FA38FAC31373C056DC6 +:10F2900055359367B2101C6966ECBFDA03F2B839D2 +:10F2A000A6E139E8DFD264736D8A073EFAFEAFA0AB +:10F2B000BD9CB2828D5EFF1435C24F28AB39324CF3 +:10F2C00038FFB316DF700FE84DC137FF563A5EDDE9 +:10F2D00060F53C235DBC9ED80C4163F66DA087446D +:10F2E000CEF77F1194D80C7A5FFE8580723A4A225D +:10F2F000A8176CC41700FE21F5F27CE00F62A2FC97 +:10F3000043AF8D99CA50184F6422B9E83CC8DAF46B +:10F310007D4270DF9F05BA2E0B6950611E5B3D95E3 +:10F3200030949F1F4D5746E078F34C9CFFC569848D +:10F33000803CA3DBC176D6DDC4D5164B286B2BA64B +:10F340002F687B3EF5F7E1FD26C732D453EFFDCEA3 +:10F35000E41723D84B3D705E6639130A8B8F18E98A +:10F36000A783D3C5B6641FCA5FE3F3B900170AC702 +:10F37000AD1F4E1781BEB2EC0364B02BE806C51971 +:10F3800054BE6F3B79BDA326C273D767D5E4660C24 +:10F39000EE6D6705378B354EF4E745D8D716FA3B47 +:10F3A000ECEBE54E5300F07BDE694579D2D73EF2B7 +:10F3B00042FA38442ED80361FC46C80217F88B0283 +:10F3C0006917BEBA269CBEE4FBC3E9EBC58BE90B0B +:10F3D000E1FC9DB7D210AECD02A32F95D217F4ABAE +:10F3E000250D485FAA89F89AB390DEF0F9E566BB6F +:10F3F000CB4625E4B28C147C4F474CF97B0109DFE6 +:10F40000973A13FDB96AEECF55A39C7FE32893F397 +:10F41000C67DED3C3A677808EC89D17387039F7706 +:10F42000800218068BCA9B27EBDA248076E0140250 +:10F43000212B80C03CB03F3BAED3DA5ED62E66E3D4 +:10F440006F79FED10D2AB46FE2FDEA6CD6AFB549F3 +:10F45000FEBC62685B4CD83E09E3E9FB1EF3C8CBF7 +:10F46000006F8FA6CBB7025DE680D142AF9F4D9073 +:10F470006F87F6B20C82FBFDDE04F95B304E6B6FDA +:10F480001B2FDF19DEDED2E3A7B6733FF556B44B70 +:10F49000DFE89A89F6AC447C3780DE7923C8E251F4 +:10F4A0005B46F5EF071DE4F6FC01EEA7BE09F2E8A6 +:10F4B0002AD027CC4FDDCBFDD4DD5CAFECE47EEA77 +:10F4C0000EAE575EE57ED22BDC4F7A09FCD4ABC082 +:10F4D0000EA9E27112E6A7668D9E5C8A76844BF3D4 +:10F4E000534744F4532BBC7A7D33CDA3D73737A48D +:10F4F000C519F48B5EDF4C8DD7EB9B52E73506FDCB +:10F5000092A91B2F5FD0FBA945DD25BAF10567F451 +:10F510007E6AFE473375E39765488847EFF11B75B0 +:10F52000E3723A6B75E37AF1E6433C59D5279D6067 +:10F53000C76D1955C7F1C6EC050D6F1D97C0DB6F80 +:10F5400038DEF672BCEDE678DBC9F1B683DB03AFDB +:10F5500072BCBDC2ED819738DEB672BC6DE1F1853B +:10F56000831C6F0738DEDEE4FE6ED6E8DDE89F9D83 +:10F570003F4B38DE368A91F05696281AF0E030E09C +:10F58000418FB712F370031E520C78B85AD72E3839 +:10F590009361C043BEAEED3D5E6280FFF506BBA148 +:10F5A00052D7AFE16D9A67BE81BEEA74E32E9BDF4E +:10F5B0009CCCCEFB6BF96D1FB7E3F670BCED02BCC3 +:10F5C000619CC8C3E3115E1EF76576DCCB1C6FDB64 +:10F5D000785CA803F006F61DC75BF3A87368C79FA5 +:10F5E000BFA0E1ED6044BC5D29BF5DEBD6C785A639 +:10F5F000B8F471A1C9763DBF1513BD7D37E94B3D08 +:10F60000BF159ED5DB77133FD5F35B5E68A6AE4D85 +:10F61000ED8084CC6CD05337EA9ECB0ED6EAC6512F +:10F620003F89F92D1EAEF7FD95A88F5AA631FD48EA +:10F63000F910EDEF67BF4DED80F45E78BC68F09F88 +:10F640005EEC437F5F93C9F477C77BD508D76CD056 +:10F65000DF91F20B7C5C4EA60BAF363351A33370B7 +:10F66000997B86D1F5984731BBC71CB316820CF045 +:10F670001334E5F4DA49A2D347607E6A2FE5648645 +:10F68000E97DB3AB8180DD20DA1E5A00FB22A2C9DE +:10F69000837AD7601F917A977C07DCBF6380A78D40 +:10F6A000C2E296CC585C879B6CB6809DD198294F5E +:10F6B00002788A93193CB62451DF9DC2634B146BC8 +:10F6C000AB145ECFD0B6387001C2AF83C24B4C874B +:10F6D000F9E3C9DD745D55995606877984E953F5D8 +:10F6E00039A65F7BF421351868FBD968D6BEF18551 +:10F6F0009FCE53137BF56F5DE64BA84FC73887D578 +:10F7000091F174DEF5EA20B033C7D2F5817C34394B +:10F71000B62745B2BFFBB2C3568F97E7C17EBEC7BF +:10F72000F5EB180A117346DFCF3F1BEDBB05F09BCD +:10F7300005F0088B7BCDCC64766B15CC3318ED4B84 +:10F7400039DCBE24C14A6CB7A433FAFAF1DA99481D +:10F750006F4E0A2F3116D6CFE037FF2E465F57BACD +:10F760000F6DFDFDD0892FDC9E0EA393EF45A213F4 +:10F7700052EE71A3BFDE973DA7B2F53673FB51B3CE +:10F78000936D899ADDECC7F558287BE40FC22B995D +:10F7900042E13AC845305E53ED32F9FD14645160E0 +:10F7A000F083DC2915882B19669709C363B9142ED9 +:10F7B0007F8CF141EFF168837C1F64D0C3C374ED8B +:10F7C000A2EE14839F7875BF7ABED439D1A09F264C +:10F7D000EBC69725DE60F0632B0D7EAE5E4F9889F9 +:10F7E00059E5F83261DC421524730EDC27889FB09E +:10F7F0007EF43B7BE0FC845C85FCCAFD1A23BF36AB +:10F80000664A0867C1C5FC1A8D1FB4E735F859DD93 +:10F810000CAFEB7234FDE441BD630B7C93405C950F +:10F82000DAD0F2E6307ADBD4687FAF7434213F69F6 +:10F8300024EF9552E4F91B5D78DDD8E8C6EB138D13 +:10F84000125E1F6F4CC371EB1B3DD87EB4D18BD7BA +:10F85000471A65BCFF506319B6DB1B7DD85EDB58C9 +:10F8600085D7B64605EF8F322BAA9DEE6B542BF150 +:10F87000A8742BA3DBE9FBC2E096DA4AD71106F79E +:10F8800064D5A56B8F5CEED68D4F6A9074FDC3EB8B +:10F89000D374FD098A47D71E5AE5D58D1FEC9375A1 +:10F8A000EDB8B232DDF858D9A76BC778AA74E31D5A +:10F8B000698AAE7F5751FEC0503F7CFC506320C820 +:10F8C000E0120C3238BD1E64F0E9C2EBE75CFE0EBC +:10F8D0003207515E0CCA7251D2A1F8B2B3FC5A9CE5 +:10F8E000D923C486CD1F5746E74B0B5F2F9D4FE7AB +:10F8F0009FF9915E623C41DD7D475A97EEB929A29E +:10F90000B304F211870B448C7B1D2E888B01FBE521 +:10F910007E8B6B5A16A5C7434745CF26780E1E88A7 +:10F92000202F4F70BDE8186F47B950B14AD8242234 +:10F93000D1B2E76B3B5323C63D0FDD4BAA605F8E10 +:10F940005D2F494017150535715161FE5A45E0CFCD +:10F95000A56EB8BF2A3D278ACE56D19A6CAD1BDB67 +:10F96000BB2F6D5CED2ABD7DD94BF77E3BEC638CE4 +:10F970007AAF1DE45B5BE2266CB7A5F59F27F98C97 +:10F98000DB619F723BEC348FC37CC4EDB093DCEF42 +:10F9900009713BEC036E871DE7F6F3316E877571D5 +:10F9A000BFE76D6E3F7772FBF908B7C3DAD29E9F4F +:10F9B0008AF2F017021123F8A9DAF5969FEAEDB062 +:10F9C0006FFAF576D8D2F57A3B6C71BBDE0EAB6B75 +:10F9D000D5DB6135AADE0E5BB85C6F87DDD4A097FE +:10F9E00087F3EB27EBDAF3147D9C6D6E95DE7ED604 +:10F9F000F033DBA7978B95657AFBB9AFFDBE12B8E4 +:10FA00000EF33F80C453617AAF279F0B7A85D245AE +:10FA1000D605AA57300EEE6B86FCC9361842F56F34 +:10FA2000A129F816E47DC8DB2281B8D3AEF339E50D +:10FA30001511E82F47D5D3CD82E3FAF8C68D77E9C3 +:10FA4000E13A6399DE2FB196E9E12A27EAFD924A6D +:10FA5000A39EF1E9E1AA1285005D1AF58DC9B14CAA +:10FA600002F97DA57AC74AA85E616D9DDEB1C29D8F +:10FA7000145D3FEA9D1F64B17A831CBA0E30169A5A +:10FA8000A2720F7828DC76BD6BC63A11BAC023A3E8 +:10FA9000A8FE2982DF29FC5EB5286A03E4D9785ED6 +:10FAA00084886776DF4EC75B87B3BC08F9D2FC1148 +:10FAB000CCAFD07F80AF1C42DB617A2E3BC8FAC34B +:10FAC000D6ABEBF703CE06F7B71EF9C8A89CFFC963 +:10FAD000F5C4C49F06A137814CC07A83D0A0CB8ADD +:10FAE000AF1AEF6705981D9495C8EC206FD24C9122 +:10FAF000E79F08843CBC2662C778E608E27F06E2FE +:10FB00009CD1071CD369B319A64C003F49CFFFB362 +:10FB1000CAFBCFCF1BFDB0EBA45483DF768DC1AF02 +:10FB2000D3F3BF8D18EC971091C09E441C9874FDC0 +:10FB300008A777381D359D68990FFB7A2989E75703 +:10FB400038FD4CE4F82264F3EE1ADAEF758B04FC0E +:10FB50000D1B51E326407D51B04186BC43AED7E634 +:10FB600042BC892B3C68979E61F8F1D27F803F2F81 +:10FB700009C317E0EFB81E7F3643FFEF393D5DBC88 +:10FB80002E4647FFB87519E8CA39E8B2EA588CF72B +:10FB90008B83B21843D7B7D725601E756FB0215835 +:10FBA0004CDBE7DCAC6E684DE24C33AE97C803A685 +:10FBB000503C4CE5FBF5F2BC56472341BBE3C54640 +:10FBC0003B5E096910411EB5B8EF8803FDD831428C +:10FBD000190EF5691D836357417E7E8B25363152A0 +:10FBE0005DCB4E4B2EEAD38E9D0966893E5F6C76C7 +:10FBF00099E1B9E2C45A11FCBD6BBB08DA05C589AD +:10FC000004F3592F36060EB3F729588743F73119F5 +:10FC1000ECD35257CDE4987888CF52DB46023B377D +:10FC200016FDD73D836D88379B6B69E9B7E8FE0EFB +:10FC3000268844F052FC788827007A20D1E9F1C365 +:10FC4000746ECB4980733DFD0778D1F402E5F393E0 +:10FC5000E1F8C825616DCC2BE8DB23B3F5F891887A +:10FC60008275162D5DACBE8C8422E7593EE4768306 +:10FC700016DF3FCEED86633CEE7698DB0D2D86F8E1 +:10FC8000CD5BDC6ED8C3ED867DDC6E789DDB0D6FC1 +:10FC900072BBE100B71B7AFC05A236415E711EB152 +:10FCA00087C05F3858C3E0EC5E25F8CB201FAEB4A8 +:10FCB000FB4AE87DDB2A0BCACF91896A13C4C76D62 +:10FCC00055EA14D8877B417B135C9B8ADA12E0FEED +:10FCD0003CE5F471F0B3815EA6E5707EA7785867C5 +:10FCE00065705EBF38C6B312E85959528EE31219D7 +:10FCF000DCECF41FC03B61912A001DB8158B0EDEB1 +:10FD00003506F8CE837698FC88067AA4F09C9ECDC2 +:10FD1000EBCF32492683BB1A05708FAAE1704F8B57 +:10FD20008FC827EB39DC35B8EC2CBAD9A4D2A16F37 +:10FD300025B2BA89B70A6E361DA4EBEF9445CCBF45 +:10FD40007626F23A41FE5EE37CEF707B765D49FFFA +:10FD5000F1BA437C5C4FBB9548B68161F394DC6F8C +:10FD600091E8F35581FB92802FD60DD0F2C41EB4DA +:10FD7000AFA78805BF4DA6EB0CF23A484D5ECE21E9 +:10FD80001C3686F7BDC5F7D9D77ADE2AB9C122D18C +:10FD9000796705EE21F03E9BB9C11D5E5FDAC9D7D8 +:10FDA000B766C69D04F83238E26C3DFAF13E9B041A +:10FDB00076F7C844CF6AA00377A262F936BD3F9DAB +:10FDC000CA43C905CB6ADF190FE3E8338F13A09745 +:10FDD000AB37033DBC956447B9D3D77A2ED2237E87 +:10FDE00082F6485F7A84CA1FB4876CE59F1C07BF00 +:10FDF000B692347802F4B960966730F031A9B2A0B7 +:10FE00007E4EA3FFC2F36ADAB5D2A0BF1D5E4BBF20 +:10FE10007278E485C656F03BDE02FEC13C2889813B +:10FE2000FA9C60F99D76804F4552CA2EC00F29B6C4 +:10FE300087465338AC29587D13C06B4DF952970053 +:10FE40007455988AFDC162FB69A8C8E92A5E9324AB +:10FE500085C17BCD7DA448017827DDED5E42F79515 +:10FE600092F8C74685F24D9785F93DEF94FC3E31F7 +:10FE7000396C7C4676F1BF67435CC7CDE87C8C5516 +:10FE80004989541FACD179535134C6654ED6B07AE6 +:10FE9000057A7FF572FAA842F5559BA7978F1773DD +:10FEA0007A8A1ADD5D0FE395FB6C12FA67E282969F +:10FEB000E5B45D05F612D84F8F58902F357E4E6A07 +:10FEC000D0CB4DC5C0B75506BED6F8E9379AFCEC85 +:10FED000E5E318C06B540DE3276D7FC67DCDFB9223 +:10FEE000DA39718418FDBB7717A546333D1666DFF6 +:10FEF0004E40D92459E9FE66717A9AC5E98992E49F +:10FF00004E58CFA17B52A701BED426EA07C0DA56CD +:10FF1000587AEDDF14D82719E0A5FB9FB55C4C0794 +:10FF2000FF94DC65E9A5C714DDFBB05E604E781B6D +:10FF3000E85595DF013B02C299F0D23F9D38BCB72E +:10FF400099BEAF73581C69F2E07C1F31F928E17C3F +:10FF5000870AC4015EE8FFEEE87448E193707AA571 +:10FF6000F38754D65F7D4F6A069A9BBCFDE18AC138 +:10FF70005041467CE596DEF1F0BF5233E27FF60A4F +:10FF80006113C4FFC6889F9FDD4DC7CFAAB4799A7D +:10FF9000E9FCB31FACB580DD5FA92A7BEBE8B84A6A +:10FFA0004A177E17EE43C72747CCC402F31C9105BE +:10FFB000D24EDBB366E9F9A67A85BE6DB4478EC62C +:10FFC00028234CF4F94F041BD944AF3B372CDD08F0 +:10FFD000F37DFCA00DEB0A09BC2B07F400E1F1490D +:10FFE00079E33DB4BF76BD8D405E641EB7F7E37222 +:10FFF00092715E9363013E5FD316837EF1E90D43F8 +:020000022000DC +:10000000C703FE5B0735DC06F5D41FC72AD580D7AA +:10001000DA35D798203ED21ADD3E05C67F6222AE81 +:100020004DE9B42D3D6481F57451FB00E2ADDA3A3F +:100030006B5AC3F00FFBCA6171DCE926A26C8E60BB +:10004000D73C9A23703D4B545BD8FA37E448787F0D +:100050007ACAA09687E13D14FB2E0F870BEC7B0A32 +:100060008B8BB6267AAA07D3F6470271AD8C87AB85 +:10007000FC01F0A7FA031B7906D14F70BC75F8B0EC +:10008000A7DBC2FCFF4CFEDE53B1ACFFA43BDA0F92 +:10009000FB3C29B1B6EA76FA919ECD4ADA9C18B6B5 +:1000A0001F61089C8260EB3B1A235953101F447A4E +:1000B0009EAEABF691C710BF5B287C803FBB5C5205 +:1000C000CB4EBA8ED35459ABD0EF7E7C0AC0F3CE60 +:1000D0000C4AA80917C3A9316710AEE7F4FAE6186D +:1000E000AC337111C53AA4171E35ED5BBF238C47A5 +:1000F0003DAF32F9C1F84F2061F29DE2777ADE0F11 +:100100002DB5B0DF28D20E7831ED59658775CEABAD +:10011000B1607ECC497C65204F6B1E11B04D7FD6FF +:1001200082BEA8E5FCD52A0DDA07747C12EC71F4C6 +:10013000F79ED80BF501355C7E552DD2D3E962B719 +:1001400059C72F3396EBF987EE53D7DE98C3EA3AB7 +:10015000BBBC1FC7837E6EA5DB06B87CD222F837F6 +:10016000A17CF58D08AFAF1B9363D2E2F092250C12 +:10017000FEB594FE6A416FD8497B09D83579A3A7AB +:1001800002BD5B8F46E33A8DF0FD6787C3A924A9C2 +:100190007A305DCF294AC750FF73724333DA2FF0AC +:1001A00023EAF8DAD502F4BD84AEF27117D2A7754E +:1001B000C6B85E7AD1E053B33E791F8C73FF678C6B +:1001C000449D2752E3CE5F0AF6640F1D19E0037BBE +:1001D000366BEF49EDA533EC8F406765742CC38B0C +:1001E0008AFC5253DA93D71BD15FFD32E23B9FE288 +:1001F000B5237D3EE4A13439B7AEE84DA483732E18 +:10020000E217995FFB36C8FD18BE3695C881BA78EB +:10021000502654EFBAF01EFACB717CBFB1CB856388 +:10022000A599840C5A2E1E2BA537634B8301D0133E +:100230003637D7BBDB737F3566089C6E2018A7194D +:10024000105DEE09E06E5C09784EC1E24A00FBE702 +:100250004141A882B8FD00A2B7ABE20CF02059E6FC +:100260008FC2EDF2682EEF974E4915D0DF29D3FBF0 +:10027000A766835DF4AB1C93E65FE055825F291CA3 +:100280005BA8FF06726A50A0BD1DE8B39ADAAD7E86 +:10029000DCBF07F33AD652813C2EF4C6AFFE51F1D3 +:1002A0008B8BE2603C7ED1571C4C8B0754B25BD4E5 +:1002B000DF51DC90F7AB74533F6700D85937BBD19F +:1002C0006F729F46BBD4CAEDD2A8D18B5C2C7FC67F +:1002D000F8478B0718E9CA185732F29FD12EFDCF85 +:1002E0001C6E3F5D4DAEBE92F88016C75F93C6FC94 +:1002F0009E3569B52BA17EED3CF77B5CAA09F138F0 +:1003000067968078D4ECB539DEB3B380FFB4FA8356 +:100310004BF93D6D063F24DAFBB42C47D09F8E5C31 +:1003200046478E02D63FC74ECCF6B0FC813397E9E4 +:10033000DF39540FDAE916A7F3734415449F9F1A67 +:100340009ACBE4AC76A53FC18C1C5DBDE0D0DCB09F +:100350007CA88DE743EDBC5EB038BD7BF757705F7E +:100360006675C036B9E6C96F533844CF8AF19890A4 +:100370007E95677E087EF22C07CADBF83409EB5EB7 +:10038000AB12ED1EA47D557E1BFC32B43325D892F2 +:100390008CF2762EE5DF80AB1F7FC7DE7FDCCCA939 +:1003A000F93B058CAE7AE24B3E26BF4DF41FD0D30D +:1003B000EC2A3DBDCC55FAA79FDC5CFD39AE31A1DE +:1003C0000B3BBF42BA60FCBB6E04CB479F2FA763B9 +:1003D000207FDB873DAEF9B74E0BF58B285E82F2AE +:1003E0006EA4F7601AB184E3DB5720EAEA1B827936 +:1003F00024DA45FD9EA085243D48C70D90E75EEFB9 +:1004000002DFB7D81653837AC3AFB3EF0FD1794F5A +:1004100038FB5E8791CEEF1BBD04E3FF0F5C4741C5 +:1004200046D77F1F249CB15E6FCB7CF0DB1E8036ED +:10043000D6DFFDFBFC62684769ED6D3F92C3EA0DB4 +:10044000EEC90DFC482DA07E8D9DEA5B3A9F4322AC +:1004500098A7226433CA6711E281209FC786C1171B +:10046000FD063DBC8D76BC58C0E228A281EF8DEF21 +:10047000BD3D97F339C7535FFB363E477FAAAED6E3 +:10048000D3FF7772FBA997353EEF84FA89982BAF9B +:100490003BA08214F3D3223179C05F262504DF27E5 +:1004A000B8185D8184013D686918E041B8D17614BF +:1004B000E805BF438BABE2A2A300FF22E41303A82D +:1004C000CFE95242422A8CD7EA0F14F295E3F2E5C3 +:1004D0001E95C7388F54C6F2CBEFCA2404EF1BF326 +:1004E000F87A5F0EF8EB47A99E95408FDFAC42BCCF +:1004F000AC7B05C1FC80C3A5609BBE2AD4EC82B84E +:10050000156B575318815EB6B9F5F5AF3B8B1E2FAF +:10051000B6D2FE9652166F3DD418787715A5B596CB +:10052000827C9497AB6060D87A83BBA2AC10875171 +:10053000D46FD9C16EFE708568856B70658D0A9B1E +:100540007E3741DD2C4810775008F8F9D615CD5389 +:1005500080AFDEB5A89E414ECCAB629EB875A57A41 +:100560002BF83DB2545E964CF96853AB19CF199DE8 +:1005700028F97DA214C6879FE732BFE1E0CEA80725 +:10058000000E6B047B280AAE1665D37DF1F03EABFE +:10059000A7892EF1DDA68793E03D6B16AFF1EC82C3 +:1005A000FE261B9C40256B36D8AB60DE35494BDC04 +:1005B0004BC2E6B50FB736C0FDE0B016AC6B51CA02 +:1005C0003CD6A858D8D7E731909F6D5D911907B4F4 +:1005D000D892601D5107E396FCE9B7B98077C984CA +:1005E000795BABBBDD02FB1EE95654C88F9B72944E +:1005F0000340AFF3969F98827573A5B1ABE13AF2D1 +:10060000C2EDAD00FF77793C2694508BF9DA964520 +:100610007576586F4542CACAF0784C4BC162FB18D8 +:10062000FA5C8ADB54B374C0C5F4D102F19709B007 +:100630002EBA9F7130EE8F8D0A1D174AB256453A79 +:10064000A7F509D747F6E6A529101769D96087F4F9 +:100650000C691194F5901F50939D11EBD833BC0C8D +:10066000EED58A6B8A5542FC20BF7DBEF5D88FD46B +:1006700051605732FCD9CDC46E09D37F19D9C567F3 +:1006800072C3FCE88BDE9BD082FAA04560FC9BE144 +:10069000FDE247502FFC7CB6AF1BE0B7A655590FC3 +:1006A000F022AA9D0C28EA9B4F42F7911184CAE3DD +:1006B00096265B55A43AB4D022713AF009E5A0130E +:1006C000034684C9E5957529101F09355D85DCDD74 +:1006D000337E83FD03C04368435A2CE8C350526DF8 +:1006E0004A0AD02DA74BE3FC5BB81DF062A62FDAB7 +:1006F0000B76E55896F79C91EB73629BB4BBC1CE29 +:10070000FD1AD06D2AACF71F48B7A8E73ED9FA1FEB +:100710004857C47579F9481F0999319F5AF4178CC5 +:10072000F7B68DD3CE3FB1F8A066F7468DFE6815BB +:10073000F8ADBE3C2DDF55B017FCF5E95A3EB59C2F +:10074000C5075DF45FA4F8A0CF101F9C6E686BF620 +:10075000E60D5EBD7D9B28B5FB4A40EE1E103DE0D8 +:100760004F2411A65766940B7EB0B39B8AA2EDB8B6 +:10077000EE3C1EE7E4FED73CBEEE638D7602F92424 +:1007800093A36035AC7F7A3E5BBFA33E3D3B2081A7 +:100790007C67716E526F93306E02C84F203D7E9A17 +:1007A0000F26A1FB9957BF14EDFD5EF835B1F81087 +:1007B000D1FB133E62F01F16317B4CF3B7E61BEC06 +:1007C00003A3BD6F8C53F7E60536DB819EBAC7667F +:1007D0001C4A91B05B0D68F9003A6EA1B773752899 +:1007E0004CFE7472FD70A4513EB68AEE7FB5EFC721 +:1007F00076A0D336B3DF0EFAA4ADECCE18A0BFB608 +:10080000056219F07DB0B10CC71D6CF4E1759597C8 +:10081000C9BB60B6BCC21B1677AE2C2B3EB62ABC39 +:10082000EE41BEEED8AAB0F5577867E8DA1A9D55C2 +:1008300088A4617304F9F2BC97D9ED66AAF7B1CE2A +:1008400050FC85A7BFFA1BEAAF7687C3EF41AFDE46 +:100850009EBD7F6CC9C0FEEC166D7F1A5CB47D6BCB +:10086000FD7DADF37B7FE33A9FF5EAEDB94BADD368 +:10087000B83E6DDD7D8DAF0061350CD659BA00EA0A +:100880006283D94A07C8A3CA526135E44B8FF07816 +:10089000E29182183CE7BE378DF97BD1F58C6FA2CF +:1008A0004B6760DEEF4AF17BA397D995B30A04BF8B +:1008B0004C7F9DCACFDB1F4B63F9DCA6A29FFF16BE +:1008C000F2D0EF145A58BC97C8D3A785E5B1D659D2 +:1008D000FD01C8271DEBA9D358B6FA6EDA8ED6E40F +:1008E0004A953EEF306B963E7F5861C833441BE417 +:1008F000CA518D3E7228DC537BE1DE973FD1177DD4 +:1009000010F3D92CD04346F8DC66808FD17FA9D86C +:100910006EE087CBF46336B566ED85BC9A4AEDC9C7 +:10092000D1803FE8A2CF45CBBFC634C8803C468FBC +:10093000634267D6825EECA42A00F4CBBA9977AE04 +:1009400087F679AAF7012F7DBD47F3DF9ECF96BFCB +:10095000F446A81FE89123601F4C80BC6064FBA094 +:1009600073D1E46911ED83997529D9B0AE197AFB79 +:10097000A07343D99399701FEC03FAD39957A7B387 +:100980000F4859E625E0C3E46ED4E8AC88757AB325 +:10099000B395C17961FB71A43590F07AC6EE1C79EC +:1009A00008F4CFE07104ED7DD4FEDA638950BFA86E +:1009B000BD2FD7CBEAF049591CD30FFC7A293C6AEA +:1009C00075D4F75B64FCDE8B16F7D2C665E731FBA6 +:1009D000B03545AE877EE2CCB8C4BC4D5A9C232DC1 +:1009E0007D08AF1B96488F3FF41741C2FE08FE1EDC +:1009F00081BC6474E2D93D2E3AE433AF929F970DE7 +:100A0000E728FC2AE4436CE502DA4BB6448276CD53 +:100A1000E5FA57973BAE158A03C0DFAA65F1F2E20B +:100A20007433B6A3157113C8854917060A20377C9D +:100A30008AF834AC375AFEFCD31F83BEA67A1FE275 +:100A4000303ED280E7AC9D161FC627DACAE9CCE952 +:100A50001087596949C1787AF2AF63DCF0367F2B91 +:100A6000C4CB6D1E761EAACAABAE86EF6654148E3A +:100A70001608ED9FEE63F19B3910BF8179679DDD0C +:100A800009F19FD95E26BFC06F03BD39B7EE3BE3C6 +:100A90001E95FE9AB88DBF352E0BE34912C60B0C7E +:100AA000F1215BC1548C0F69752ABE0211CF779377 +:100AB00044277E87C218DF31C6738CF11E637CE742 +:100AC000EE3C5627ACD953DFCED3DB532BE00CC220 +:100AD00060B097A8A8A47CDD662149ED943E0F156F +:100AE0007F42EEA2EB70FED00435E0749C21CE78FC +:100AF00099722B48E5CA29D8C8EE372CE0DF2E9032 +:100B00006B30BE67A4FBC7B8FCBA2FCFA9ABEB080C +:100B1000362EE7CF47A980E705A3ACFEA8E4DE792F +:100B20002E973F9ECA911FCE637EC50F81CE894707 +:100B3000C1F30433725D3ABA250D83C9A9B0F88DAB +:100B4000F1BDDA7AB4F9AF741D0F71785F2E9FACE6 +:100B50002BCAB75BE9FBCF511C8BA82FA9411D16EF +:100B60009FD6E2E7DA73D59037C8043B52C0FC81C8 +:100B7000763F2C8E6D06BA8D4E54E448DF9B7A3B4F +:100B8000AF276E8A794CED3D4450502ED4F17C8DC8 +:100B9000369F99B89B900F80B6B5758911E2E6C46F +:100BA00063B75192A95D2B1288FF3889DC0EF1677B +:100BB0006BAB05DB44ADDA0776FA22CE17D682A9F5 +:100BC000FB20AEA6F185316F631513A7C2B475ED96 +:100BD000FAFC95313F65B4A7B5F8BA99BE04D6754D +:100BE0000EF0C1F6EB172F6FBF4FE37EBEA6FBD50D +:100BF000E8AA3CF31637D49FB44429EB6BE8BAD487 +:100C000027ED18AF70C0DA002601FA0FE4E493DE96 +:100C10001FE379F67CF65D9A1681D5A3EC49F8635B +:100C20007CF8F905533EA39B9FE549388EEACF0037 +:100C30009C972263E3912FB4FA934309CC0EAC281E +:100C40005C1CB893B6FF8DD74B5E53F88C96EF1FA4 +:100C5000509C43B0F403E0B2CECAEAD20E7DC38CFE +:100C6000F564443CB0EBCEF8DEBADD6B36EBFDCA82 +:100C70001BD2F4F6A0D1FEB31ADA43F38D75648A61 +:100C80001DEBC812781D195FBF914F7EDAC8F21AAA +:100C90003FE775FFBFE0E72F7FC9EBF736F3F39728 +:100CA000CFF373B31ADCEFB728188F3E711DB5E987 +:100CB000627BE380EB8ABEEBC6F3FBF9CCCF9A22D2 +:100CC0003A77819EEA3D67D1FF77C22ACBF479B3A8 +:100CD000D93E7DDE6C6E953E6FF6FF32E5ECFC6C26 +:100CE000388751BF12BE5330639588F9CA752DE716 +:100CF00050CF9E2F406BFBA2F71CE6E730B4731C6D +:100D0000DAFD6BF3D9F7911CBB122C508F3F635562 +:100D1000EC54889F1357C665D96F15107387FCCFA5 +:100D20004A9705BE0731239080F1D09AD62B9BE7D6 +:100D3000BED143304EDD13E757C7DE04F2F9B016DB +:100D4000E727D7DC0471FEC33CCE5FF3F2B827C1BE +:100D50003FFA599E3C17E0D1942757C1B586AF871B +:100D6000B66FCC1FDCDBA63FAFC7EABF3F5193DFB6 +:100D70004F3C5D9C2C3444AA17B939BF27CEB5141B +:100D8000E627F69E38D737613E626FC77376F7E67F +:100D900033F9D47C8CD4C33CCD2F93FAE723D8DD30 +:100DA00077E50BDA7CDFC2E7DD9A7EF3DDC9E6D7B3 +:100DB000CF27DA624780DF7F82D79719E7BB37DF1B +:100DC0008AE3E87CDFC3F9127BD6776FF8FA7ACF33 +:100DD000CFB86280691DD58AA98BD2136911B1EE93 +:100DE000C4D1E19A067549646A2AD6B11C2EADFCBD +:100DF000A7384F73B8F4857FC9F334DBF2932FEB38 +:100E00003C8D63265122C535029C2E7715640E0C4D +:100E1000F58327EBF2FD41B0337ADA668540DECF09 +:100E2000BAFC20DEBF3FCA551DD1BEE0F2ADA574AD +:100E3000910F52426B92A68AE1F6CBD92CE5CDFCFC +:100E400008E713CF8DEADE0DAA6966A96016E2D124 +:100E5000DEF608547E66AD9821BA2542BC0D0F4ED1 +:100E60001E4AFB672552FF2E6CDFF9F5BFDE4DD918 +:100E70009514941E6E8EA7E376E4286F03FD16B9D1 +:100E8000A53DD09EE54BC7BAF7FB6309DA79274643 +:100E90005BFD9B922F5EF7EF7AE5F24AF315C8E50A +:100EA00096467DFE7B4DD29895B0FE3125240412E6 +:100EB00036C57DB618F27F19D9CAEF605D296E225A +:100EC000DBC6E37D9984E56F8CF30E98C8F0342679 +:100ED00094F80388271FD2FCFDA22BF6F7FF180E0B +:100EE0006FE3F584E6EFAF8EECEF9F581417391FD0 +:100EF000D052570BF98013ABF5FEFE890DEE6A3820 +:100F0000E77782FBFB27A6507F7F6CDFF9006D9FA0 +:100F1000540E3927EAF201DC6EE771EDD9D9F2C03F +:100F200089D9E8CFBBE0DA9829C7E278D575139E56 +:100F3000472691CFC992275C32F839DAB9F65CAF0F +:100F4000320C9ED7CECB8E01D13608F2A2AEDB2278 +:100F5000D1F368BEBEBF3E4FDA93C734E139EACB66 +:100F60008CD35FEE38C9BB99D5E398599D61544243 +:100F7000891BF253E7C7DA51BFB7C2FFC2F46A6AEE +:100F8000BE3271E2E0F0790CDF57952EEFBD5A9D2D +:100F90003EE82BD02F9D849481BC7920B601E31EBE +:100FA000D771B819AFE513395E892B1EE0999AEF16 +:100FB000BB01F0415EDC2CE17760F9FDBEEAFB8D00 +:100FC000EB78D6EA7B1FCFD7978812ABCB23C81715 +:100FD00057A5B9504F6BF6D7D2894C6EDA48689452 +:100FE00095EEB359DEEDCCA4E33E7CC29C0E8F3D62 +:100FF00017432CB06E5F1A9573741F256E65647F5E +:10100000F211BE4864F2C2352098DC788D635755E2 +:1010100080FB17F1E313DD83C11E7FEE49969FBA73 +:10102000EAC945F6DAB0F99F98C8E566225B7FB554 +:101030002CF8A56458CF59CC43CD904C1E9940DE76 +:10104000F8FCD1B91027A4F6DB686C9FC376503248 +:1010500065425EFB43F7174761FC55F72E1E82F48D +:10106000CFE1B17045E6B368E7E728DF05FC070B81 +:10107000CEC5A48E453B7E3DD0FF4281F822D909E2 +:101080000F71BC5D2F37DC087476BD6C23706E2D3C +:10109000586C43B83F572848E0B75600CD433CE76B +:1010A0000933C69B293C9641FF018F03BF1B5D227C +:1010B000FFDA0CED3F8E13C8D07EF4F115C3B5E016 +:1010C000DC60E0C70F81FE22AC7F295FBFC64F14F2 +:1010D000EE25B82E99D58BF44557DD79F2934097DC +:1010E000AD294A3D7E17D135F3B2BE8B58F1533F3F +:1010F000D6EED97ED2308C44A8FF3AC4F9C478FF2A +:101100009713997D770BE78FAB9EEC3E701DF0F542 +:101110000A8B0BF0FAB33CDF66584F8FDFF57796FA +:101120002353C40588BF60395D3B7EC781C4407BC3 +:10113000FA2833E24F2DE1DFF9B89BB89A63F12921 +:101140006CDB5708C8670E677B1518CDE6BC86A315 +:10115000B3E1B96211CFF5879D73E9B78E2CC4CF87 +:101160009FB5C0F9336ACB075789DA77B7884065EE +:101170005BB0D4CCEDFBCF9E94E9AFCFF2FACC9329 +:10118000AF5A36421DCB51136BBFFDAA65C44AFA54 +:101190009ED008B68EB607054F9304D7A7D743FE57 +:1011A000B26EB9E029A3EDEAC03D5D10E25AF288C3 +:1011B0008D80ABF0F10F974E85FD9C7313FCBEEC58 +:1011C000DC04C6374A90F84DC9BDFEED0749C4AFEF +:1011D000E54BE11C9D97EB9987E01C1B5DF7B5EA99 +:1011E000B7D4EF40DE94FABD10571BE461F9CCE8A8 +:1011F000A0D9E327E0EFB2FAC8961F08E421984788 +:101200005CDB0CFEB98DD7EB46CB35E83F0EA2F484 +:101210002981060D9975E7D8EA8882F41B5746396B +:10122000231DAE7AFF38EB12E7D9E6DE343816F824 +:10123000E52F13F5E732FA8AAF6B57F8DE0DE0A71A +:1012400083E757B751BB1DF6FB32B5DBE1BA9DDA38 +:10125000ED701FBE530D5738CF06D75DD46E872B68 +:101260009C67832B9C67832B9C6783E7E03C1B5C1C +:10127000E13C1B9E3F2C540303013EC5D104F243C5 +:101280002D1646676A9215FD8D4021C1FC7D30C93F +:10129000BA6925C4EB0486273596F50763949BB19C +:1012A0009D3C96E577CD9E11708E7095305602FB71 +:1012B000A9D5AA60FDF289956602F5CBA169C2FBAA +:1012C00090772182C92352FB66C757B721FC17CB01 +:1012D000C40475E92BE1BBA1208F3F259B587C2ED0 +:1012E00028C2F7E59A6308A7C73ABF4C65F669417B +:1012F0006B1F52C09F9D043101A4DF030AF42F5ECF +:101300002EF076D02F8F82BA06DEAF1E7A0AFCD777 +:10131000558676A7497B3EE52998EF68CFFB465472 +:10132000CB40EF295A7FE242689F8AD29EFF7C2100 +:101330009EE7D2D6A37E8AF38592B4F1A9D5D01FB9 +:10134000EAA9935B82EB0D0D66E3FF6D57E7D3E0EF +:101350002FFFBDE76B56548CE3ABB3087926F662DA +:10136000FAFA7892A88F87CA822E1EAAC5DF4D8E00 +:101370000543F1FCD90336948BA79208FA217DC569 +:1013800045C3E2F51817FDD524AD9ED910FF240AF8 +:101390008179AB201EE8C1B72AE1E7D388D040A00D +:1013A0004EDD772646023BD29A1816BFE332A0BF25 +:1013B000786173038B0F06150B51937BEBFAAD0528 +:1013C000BCAE9FC70BB53A066BC1A3BABC81315EF8 +:1013D00048C465988FF62DD2C7032B942B8B172EFC +:1013E0002001CB50A07F59F080FFBEC0A57C300407 +:1013F000EDFDABD9F719A5D7316EAA9D1B833BF044 +:10140000DDA92ABEE7B65B4FBC3F848EF3AF8C925A +:10141000E030FEFC65C5F87C1EDD21C4B76A0AF128 +:10142000F02DC9FED4F3BA04F2D46DF23033CD7787 +:101430006F02D80B8B62316F72D35DE91FC03C8B9A +:1014400055073E47ED4A4EEF2F6D047A1221701971 +:10145000D6CE1AA1D15BD546E0AF49715A3BE629F9 +:10146000E08762ABF6BC17DBF3148DFFAE790AF4AC +:10147000C7D1128DBE0F54C3F3B3537BE643FA9E1C +:10148000E4D0DAD317427F6BCF7C4B36C27CEFC0FF +:10149000978DB03DF529E0E7E2195C5FA91F6D84E7 +:1014A000F95B1668F34FF0C3771EE79BB4E7A3FC24 +:1014B000B07E85686D2ACF68FB3DCEFFC70A5EA867 +:1014C000067EB9B1A7FF05DCEF02DE3E5E50F714E1 +:1014D000F4FFCBEFEF7FF87DC6F64D2438656856F4 +:1014E0002F5F18E5D56F8B981CF1D6FF1AC8952C85 +:1014F00068781ABFEF06F10096CF4A98E503796144 +:10150000173D943388CFEDC238A7719E9B0B595C71 +:10151000FD4C813E2FD662C88BF9787EAAAF798EBA +:1015200014B1795A4B22FBB119D9257F2A80FA01CF +:10153000725684F95C1460F07DB2964CE5FFC37D71 +:10154000CABAF8DD4D2AB23C709FFAC52AD899D3A1 +:101550002938210FDB54F438C6E9437916DDF7400A +:10156000B43CE73AAB8CF2F1635ED731BF449E7274 +:101570000FF0FF30916CC23A0F27E61BCCC3AD4F82 +:10158000A35CE7794FED7B1CD32F712EC2782EA57B +:101590009BC3FF5C419B05E4B34AD429A55928AFFE +:1015A00083506F6C72ACC53CB0ADC88279042DFF1E +:1015B000ACF0EF7F6B79DF49170632FD9EA6C5754B +:1015C000FBCFFF2ACB77FAD03E68178949B8381F7E +:1015D000BCD8A726413DCBF4D2183C2F5055FB0672 +:1015E000CE7F7804C1EF0447CF6AC0F341666A1F1B +:1015F000CA00179E2FD6EA63465EB81DCF8DD66906 +:10160000F5E662F941B0536D8F513F0BD997C14553 +:10161000CB17CF30C8FBC50595A86709B5E347C709 +:10162000C27BFA3FF7FCF0A458A49B8FDA593D7FA8 +:101630006121CF97F03CF0FD1616E76B4DD1D3D565 +:10164000CF27317F65FD244677BB8A7E5E85F633E2 +:101650003179202F469E60DF8583180B9EB7327E3E +:101660008F396D0EDA754F8CA45BA4B6B679F97B11 +:10167000185714D6B3E73E1D4F1AC06F319B599BC4 +:101680005E54C8FFE77A9599855097B5FC031CDF37 +:10169000ACB27AEFBEE237D5859ABE67F19BF9EE20 +:1016A0007D5D70AEEC6F8EE318CEBDFA24565FD22E +:1016B000562069F946FC2E21255C0BD88BA9F9BE72 +:1016C000FA428C6F6D96601D9ABCD957741BCA275D +:1016D0002247CE4B6B7CDF62C84BFBDCECF923AFBF +:1016E000DD530D7F17A2AF3CC4B3C53D7983E5F848 +:1016F000FE782D6F20DF03ED5E3D4A37E4D5E9D15A +:1017000085F5FF0BF4688FDDAE76A11DFB755B3FA1 +:10171000A5AB1710AF652C7EF6755BBF3C517E13F1 +:10172000F8F9BFFB3DE9137D5D00A7FB04B9CAC909 +:10173000927B1E419FE7FBA0B09F3CDFA5E20FFF1D +:10174000176FE83FDE602FD2E7E1FF59E20D0E3858 +:10175000433518F928B108F8A880F1D1BFBADCA345 +:10176000FBCD2F827CBAB0D91F9DFAF7F7F753F360 +:1017700095B222D4838A6917A59FFB8AEDCC9E0976 +:1017800030F8F6C633E8FABDBA78C653F5FF0DF166 +:101790000CBADF2AC46F297FFFD71F7F77207C65B3 +:1017A000664FFC0BD2E703B8BFCD6C7FFF80F76FAD +:1017B000447AF905A3975EF8303B290C3E0BEBFF0A +:1017C00031F0791EE1B38DADEF6B80CFD7119E1E46 +:1017D000B6DE4BF9D7270A044D2E1FC27D66313A7B +:1017E00038C5ED6BEA774F1E2AF5FADD4FE5C86F75 +:1017F00015313BF76891AEFE537E1BEEF7E3171FE2 +:1018000083FE087E7108EE7FDDFCE2D8429647EC4D +:10181000CDBBF8D9776F49D5F5DFA0EFF980C21BB2 +:10182000E26D6DCB45B42FCE2712FC1E80666F840F +:101830006259FDDEC5E7C14A099C47B4E5B1EF8CAA +:1018400068DF07308B0B0606A48BE17A7080628517 +:101850003AAF25727A0B9C6F9DBCF6733C77659509 +:101860006DF8773547BA3D96BBC08FA67EEEB510B2 +:101870004FAD77E1393AED5C9976FE634960DE3E23 +:101880003867DB46E92181BEA7A2D472327CFF46CD +:101890007BC36C681BFFAE69C2247DDE83C21FED73 +:1018A0009FF3EB597D5C9B99EC82FA8F3A55F437A4 +:1018B000D1F6336B05FC1EE7220A27F0F727B7277E +:1018C000633DB935917DEF4CFBBBA7940EDAF3C0B5 +:1018D000FE3B2A12FC3B76FC3C99F69DEFA869671B +:1018E000F17B5BA7E8FEE1FB3DDA772666703AD133 +:1018F000E019D5148770394FE142002EFCBCCDF4BD +:10190000E52C1FDCB2607110C8BBBAE0F35591EA58 +:1019100052E6B8F5DF4B37C6338CDF1B3713DF4099 +:101920003857575150AC82BD6AE3F59AD144C6EF9F +:101930005A9C5AFB63F65D8B528BEE3B22C6F746F0 +:101940001BE8D466883B18E9D4889772035E9E3101 +:10195000B3EF0CB6748A1E95DE6E7964512B9CCB66 +:10196000571F31B1BA7922E3779F5AA8C58BE7CFC9 +:10197000E962215E3F97C353C30B210D16E0B70503 +:10198000DA397453C36A384F3A8F9F43BF916CC69C +:10199000730637810541DFBB1042E4227C5746B213 +:1019A00032E7C045601D7555EC3B1926D803E409A4 +:1019B0001E3121BFB6B877E1DFFD0A0CB3C49E4EDD +:1019C00063FE44247BB627AE4021713A2C8EFF7F04 +:1019D000F1ABBF2D7E35B17010AB9B880AB8F29287 +:1019E000D9F726A09E6962A1C4CE2758941178DE4B +:1019F00061C3272AD08176DE81FEAC18A2FF6EC2B9 +:101A0000C649FDF87F258584D54727879240AE7D5E +:101A1000D0475DE5E1E29EBACAE72661FE9DDABFE6 +:101A20005920F798FD3B23D7F7B3496817B373CE16 +:101A30005A1CE933AFF24B185F087F3F270BCFE703 +:101A4000F8E1FC4E8553D82B48BDEF27C63AF6FF88 +:101A5000A579AB7BB8DF168C22F81DA46032A97A79 +:101A60003E023E9E29617644303D32BEB47E6A67B6 +:101A70001C9FC4FDA1018C28CE58F5F18193809F55 +:101A80003EFF0E1DC7E3E829F2478877DE7E385710 +:101A90002132D4F72ABEF701AFA7555102BD420249 +:101AA0000A7ECF6FFAF74557A4BFA7F8CF7EFD2F68 +:101AB000E87FAE8400800000000000001F8B08005B +:101AC00000000000000BED7D0D7854D5B5E83E73A5 +:101AD000CEFC24998409061C24E849001B6DC0E152 +:101AE000279000813393842490C0F0A741221E08E0 +:101AF000D0DC5EB44111634B9B0381102222BE8B6C +:101B0000AFBCFEE824185AEFB37DD4CB6745D48E22 +:101B1000012D5AD4E0851A2BA54110B1CF7E8F5EDE +:101B2000E5B5CFE7FB7C6BAD7DF6CC39930920C6DC +:101B30005EFADD3B7E7E877DF6DFDA6BAFFFBDF6BA +:101B4000492D8B3AAFCD628C6952A0131EB53EFD74 +:101B5000E4502CB39B59E74478A88723F224C65657 +:101B6000B2D84F7540B986FEC558DB5DA77E3F14DD +:101B7000DA4536A6A86C3A634B5607A97F11F332B3 +:101B8000199E6DD372181BC258C1B9C06115CABA6B +:101B9000DF11906898F0778741BFF08A4CB50DC689 +:101BA00059560CAF0A183BE984E714F8DF98B64C95 +:101BB000CB87FE58BE8E3A680CCA4B065BCAD9D09A +:101BC000F4186F5FA8FD35628C82F199D9DF6CFF44 +:101BD000AEC4DB9F0F66470C2F63B79BF550D6B1A1 +:101BE0002CFA33969E1354A07FBD24CAED9A629DB1 +:101BF000EFDA766D1A63679CF6F16BCDF16669AE2C +:101C0000761C2F1C9BDFD5AE41F97402FC77305E49 +:101C1000BE557350FB95B1F60E5AEF594994C7EA79 +:101C2000583EEE12FDF39769B0DEED39BC3E1C1A4A +:101C30001B31B2AF3E78BEEAF1BF303CD354A2AB09 +:101C4000C2FA5F945C0BFFAC6D6897752FD259F8A0 +:101C5000F70CE8D17844523BA14F21DB2B3399C0DC +:101C600076C94097533489B5C15CEB4212F50F7BBE +:101C70001D7C1EA328A2019D2D992EE8745904E70E +:101C8000ED8FEEFEF4D29AC70CEB3A8D354B6D70AA +:101C90001B636D702FEA82F6505E72F73FF811CE2B +:101CA00025B9627D2511A4BF964CD1EFC38BCE7BA5 +:101CB000EAA56AA2F725B179E653FB25A962BCDB48 +:101CC000A91CC7E79D767C1A372EC3F9045CA1D006 +:101CD0009D84CFB02FB219F93DEC670103F0797BF9 +:101CE000FD0659CFB7F09151A5121FF963E5889D04 +:101CF0008F0A888F061AAE9153C23FD440CEB0BC33 +:101D0000BD6A78CC57B16E9093B86E43A2750B3A0A +:101D1000AAF559E8DD03EB564539B0ACDE3B10F3CC +:101D20007697D1BC1F01BE599C9F98919BC03F974D +:101D3000375EB377B90BE15EA5495A04DA7F8EBFEF +:101D400019F1E7E9699CDE019F2F6BF0648580CF74 +:101D5000747CCF488EEF9B107E95F0ACEA8E2E807F +:101D6000CBA579581BE060DEE4F06FA83DDBE147CE +:101D7000FC0300D4BEE5285390CF80B7028EA95053 +:101D800076B29ABD49E6FD69C841F3363356B117BC +:101D9000E09BB8D1B72AEC8DD7E79671B8547CC2D6 +:101DA000B8C7D37BEF1802F3F732E6DB08E3371B43 +:101DB000C0BCF07CBF5E8A48B0E6F7B3C3738AA0AC +:101DC000DC9DE3086C84E9BB1F708F580BED7B72C0 +:101DD000BC0184AE277347BA0FC67F3F209BF8BA79 +:101DE000E73DE4EBE3E9317E3250BF749BF83DA759 +:101DF000853A908FDF5179F967A56BDF43FE6279F1 +:101E0000CCC786021EB007F0AA236D9AC70DF3BA9D +:101E1000668238C1BE3EA6BBA0DE8DF5B0C4798F08 +:101E2000EE7E74018E61D4BC32CAA2475D4C317A19 +:101E30003D34AFF2395790CC39293EAE6B67F3CBC6 +:101E4000CDA88FFD320B216FF9797B3FEBDDF0B927 +:101E500003C787721E43127CE97358BF6496F1F77B +:101E6000392CD1CBC2153908571E0BA0BE9DA73BFC +:101E7000CFC4EAF9639B32C98413E191D75714C1E7 +:101E800033B5DEDE6E761E943DF1F2AC9D7521C455 +:101E9000FB2C0DBA8D63ECC8CEBA681DC079A4D0F6 +:101EA000ED9300D3AE6CC5D67E36DBBB09F10E7662 +:101EB000C52119F0B2D49CAFD937EFF70CFAADCAEF +:101EC0008312ACFFF87782E90559C86F72C061B61A +:101ED00071087C306AE77470391D90A07DF37362DD +:101EE000DFB40EE403394DB295832E513FA903F9B7 +:101EF000E2784CAE8E598EE5452305DF0CED403D72 +:101F000039234D94072D47BEED559CA63CBBBE031F +:101F1000E559AB18CFD8457CFD3613F5691D484708 +:101F2000E198FC9BDB8EE55B7D263CC60F491E36A7 +:101F30006B5C9F4C7DE9D55EE30ADA037F16059161 +:101F40000FC35CDE25D64F391669CE30EDBAD16AA3 +:101F50005F7EDB1694898FC2DA9F65DCBFD206C034 +:101F600019EC5F498D74AC00E953612390EF5B9AE3 +:101F700080F74743F9608A4B4D47B9EE9BA925E1AD +:101F8000DF57830E1AAF2AE8CD3AFB75683F814DC3 +:101F900040BA6B696A14FD0DDC5F7D942B9292D37D +:101FA000FF38A74AB81CE8967C0BB97E9619EAE779 +:101FB000E02323BD452CDEEEC5122E0F5A26688B7A +:101FC00083F09C03E297C11E6E98FE837008E63989 +:101FD00053E40CB889CFB4B790CFE69B34F4B04B40 +:101FE000630FA0DC2872FB36A2EC96F39D8D505651 +:101FF0008603BF62B982D3B70EFF7D9E8BE32A7141 +:10200000FA0738E635DAF9416116FA86FAD5C1746D +:10201000BEFE9BD9CDB8FE079DBEA528C75A737DCD +:10202000775BE5D9FE122EC79E36D7DB35FD9F6B59 +:10203000103F1F334700E5C79ED430C9B353198CF6 +:1020400075A0CED798EA1B8A7CCDD721E5DDCAB032 +:10205000FD8F6E80250C03381ADFED2E9D00EF7783 +:10206000F17EE7C6B20686EF155E8687618CC37681 +:1020700027A9DDD6602ECDCF1E0B783C48FBD01CA7 +:10208000F7DBCBF63AF1E9487B7E849E647FC4930C +:10209000AD767E14C303F21268425CB7C474C7E71E +:1020A000B87E53FE039D6E273AADE17A64CAB9F358 +:1020B000367A2B0DAAD42E91EEA0DFA3D46FA1E81F +:1020C000C79CBAC55EDF168C443628A48F7E48EDC7 +:1020D000BCA08FB26CFAE8C7F43E411F4DAAD41ED3 +:1020E0000F16C4CBD07F3795FBF6EF0C26D167D007 +:1020F000FEA734AE47277CCD9BAC3D89E589D70B45 +:1021000079020D0B417E5C23CAE977D64FB3CA9F93 +:10211000C2C751DE2CD625B3FEEB8F237F1F0F09DC +:1021200079736429CA93983C62358FDBE4119B7301 +:1021300027D6C7E40F5BF5188E17933F6CE6E328AC +:102140003F82F3845E3BF3188EDF522BC6BF25120D +:1021500044BBC421FAA744900F7526CA763BF27798 +:10216000D3FE65A9D56F62EC5F1ED32C7EC689694C +:10217000758F931E3486B0D3820F72FBF2BB90032F +:10218000827E847D78EAE093BA01ED5654686F59F7 +:10219000F7256667F672BB276E5F9EE7F6F7C0DB32 +:1021A0008FA769FE7C4E6F5FC1F8FFCB3ABEB0A728 +:1021B000E0FDBF59DF5F6DFE1CC0E70A21BD4FE4A3 +:1021C000F05D41FF8C10AE2FC0F5D4DF00DE6C9ABD +:1021D000CFF403AE427C064243AE6AF84A09BE2AF7 +:1021E000BEDF2F6A313A2D4F4E07974DFF73695F5F +:1021F0004AF9BA2DE3CEA7F755822FD4A4FE3AB4FC +:10220000BBCDDE2ED6FF7682CB1CF722FDEFB4B716 +:102210008BF55F6EA5CF01E0F3D5D6FDFD0AE4484E +:10222000238D3F8A8FBF328EC7EF58DFFF67DCEC0C +:102230009274DE4EFBDEC0E9E932ECED9F60FBAD4F +:10224000D25E3D83E24486C0FB3F23DEE17DAF0BDF +:10225000DEBF65EEC79345E19FE17B2CFAC75BFCCF +:10226000136309AD2FEE9FC040F9567DAFB75BF504 +:10227000FDA1505D3BC22B97F0F6FBBBDE5C86EB0D +:102280004F2C835D7280D6930576C918B24B9EC7DA +:10229000F2A5C605F8BBA8DFB39C6E92D4BF42740A +:1022A000F514AF6F75713BF6EDDA8FC98ED3D6A8F2 +:1022B0000EB4E3845E3F1AE27E00D82315116F5FEF +:1022C000BBF1684812783B4AE3EEE5F83F1696D337 +:1022D000D1DE8CD92DEC55F283E276D55DEDB88F49 +:1022E00071BBAA81CAD3CD7D3E13BA779909EF0994 +:1022F0008E07733D976EFF1EC1E1E7ED93D49FA556 +:10230000F1B2399CCC7BF80CFAAD44AFFC37CA0172 +:10231000E5556621E85C549C05764BD74E4945321D +:1023200059B94BECF3FA769BDF68F2E162938E9534 +:1023300092E665185F58FC89E0FF437CFD313FB5AC +:1023400099E07FC78C4F3C8CED397C9F12FC2A872B +:10235000EF2B18DF55427619C74F0D339C689789CC +:10236000F382C4FDCD287188FD4D2F213B99C355C3 +:10237000A34B64BF87579C7222BD2F3DC6B464F443 +:1023800031A4C425E24F43A8BFD7F46F033C2E9479 +:10239000D87E78492C5E359CE0F4F1F936148547F7 +:1023A00060FF69FAD192A17C6B3C688F864BA5488F +:1023B0005B0EFA37DEB25228CF73B05EF2FB18DB49 +:1023C0008C715FF7F30A6B0B506B55B1C475804B82 +:1023D0007F8B7EE422739FE7B1587CC581F11A4B55 +:1023E000FC86FC4077C9FD793B558ABB50DCC6E5CD +:1023F00097C9AF083EB482E223A9856E9F1BE7917F +:10240000B3C9CF75FDD08C172DE4FEA503FE433B69 +:102410003AB59191FF36679B1451A1DEADD9E32FF8 +:1024200075EBCF37937FB782F934F01395427BBDBC +:102430002BC17F6D99A087104F6777D539101FC1C9 +:102440004AEE879DDD35D28BFC97E8479F453F9A42 +:10245000A4541F3FDA7800E36B163F7AED00FAD1FF +:102460008B4AC08F465964FAD1238BC2B7113D28DD +:102470001AC9B7AEE953E693BFBC4D666E687F7A62 +:10248000E7C4370AA16C6C5302186E78DFA92DC51A +:102490007A03FC69F97ADA2686F1ADB926FCA78BB6 +:1024A000CE9722FCDABDD70790DE4F3FE4263C9F53 +:1024B0005E99194983F132B6FD65530AF47F2532DE +:1024C0001C836C31FF3AD10F672C6220DD9C6623A0 +:1024D000581BEE83E26338AED290113002717F7BDD +:1024E0006E9ECFC0F1F4481AC37D8FBECAA4B379E3 +:1024F0008C8E1C908EE731D58985054C7322FE1792 +:10250000319DCAB701BF492371BE3C83E800F80E74 +:10251000E3774D13F4EF10BDFF88D307DBAEB4E3D0 +:1025200079C569E39174E4B33DA9F6788378B698E8 +:10253000FCE9413F7FCC80FAF90F5AE5C465C895A4 +:1025400047F87E727E7595301A07F4643DF279B7CC +:102550001907DE9EC9E3277BCC3849E213183E0BEE +:10256000FB7F513D01FAB29DE08DFBF11D08CF6567 +:10257000E8CB9F12DCFBF83A7721DC5CFEFCF7121B +:102580006E07A819144F01513C89EF2FFE3E95F4B8 +:102590005FE07CDA5312ED578ACA480EB95938CA3F +:1025A0008989E3117EEB87DAFB3D7BB17E6B827C10 +:1025B000FE3F16EA2FE0FCC5E78142A19DBB8AC71A +:1025C000C1E77AA5972535DEEE38C6A192ECF779FA +:1025D000538E42B3A803EC958733600FF2717F02EC +:1025E00083505EBFDDA49D441BEE7853053D7B9474 +:1025F00006921F3DBBE4C806E8FA4613EB2E1DDD2C +:1026000077DC9ADAE0C933167934B7EC090F08455C +:10261000D69CD77158C278BDE656DDD0BF3B3DBCD5 +:102620001DE3F5C651997502BCB72EAC3C79C622A4 +:102630001F12C785F998012CFB61894C701F0CBAD9 +:10264000A333308E60481194072B8C534E8C572E39 +:102650006D5CC674D82757E12905EDC29AA08FDAC0 +:10266000CF2D94996181EBF149DA7B8867A08B3398 +:10267000B4BF81981DF53E96834E2DC3971F8F439F +:102680008A7381174B9E22FBB83B93D1FC613F8B31 +:102690006C80F94BB465AE5E3C67F187296E7AB207 +:1026A00044A57957EE6C277852A7FD99E001DB39F4 +:1026B000EA18DC17DF820F8E9A786F31F1DE1F9EE9 +:1026C00095521ECF13E5B9654A3AE2F92D45A57337 +:1026D0008EFEF87B7EA97D7FDCFE0A5BB959BBD7F5 +:1026E00081F47476A71CC17D82E7EBB86F9FC0BEF2 +:1026F000B19CF838DDE9ACC6AA9FC5FECC29B5EF80 +:10270000CFD26D7C7F966E0B125E969656BA86F18E +:1027100073B5BD40DB4C2F5CC6102F2EED9482723A +:10272000ACBFFD027E1B568AFC6BDA8F57103FCF81 +:1027300029B5D8B55F757C1FE6BBA534899DFDB76B +:102740003A5F10F4740CE56A7E5CAEDE56CAE5684A +:10275000E253C8558B3D49714D0B1CCBEBAF000EBE +:10276000C127C8A728374A7648CEDE7CDC7FE0D771 +:1027700031689F7DB819F35156F919D14356A94ACA +:1027800074ED9A36CF85F278E5AE3F2BA8AF009F67 +:102790008B4B2D72B8A494093D544BEFEB395DFC83 +:1027A0007B9FEB003C77D3BED77238AFB673A7756B +:1027B000D5E18DA5740E0472C98BF1789FD04323A7 +:1027C00078DCFB8B9D6FBEBFF35E8676E0BC3FA5D9 +:1027D000AB6807DE5ED4A9E5A849CF3755C976BEF8 +:1027E000591762E45730161AC62E79BE99787EDAE8 +:1027F000F7BCD378B9392B6E77279E77269E6BB2BC +:102800007ECE3FFB9E771EAC2A02386705649FAAE6 +:10281000C6CF335DD3CE9E6063FB9E770E32F52E1E +:1028200043ED6D596FCF08756F14F3A38679021DC0 +:10283000BC399327C5F1087AC0E38679369501FC47 +:10284000682FE7743CBA80D9F0E8223C7C413CD246 +:10285000F936E265A714D988FD950603E5F94AE63D +:10286000537F1088EF676CBCBC751ACAE7EFD47948 +:102870009903F87F73D63D6C19B44F3D92C26468DA +:102880007F44BD87F6FBC847E92A9EF7BAFD967DCF +:102890003071A908F8E4BE7ED2DF601F3DC8727DAA +:1028A000F651ED28453D7BB9FBF76451F803E4632D +:1028B0000FE86B657CFC7DCF088ECFDE9B58A44370 +:1028C000EABB8F806F8DFCCE3CD6BE91EA1B18C64A +:1028D0000736498CE33B812E1C69EB0D3CD7762DE6 +:1028E000F7921FD5DCD040F83E0AF8367C9CBFF04A +:1028F0009CEA22FC25E88249432F9F2E12F7FDC84F +:10290000CE3AD67875EF6B3FFCB9BB14ED9ECBDDAC +:10291000D77953B59CB202EB3E6B23CB8658F9D6E0 +:10292000E07E0938C0E44F2E64AC33B3AF1D956F21 +:10293000E6A5C0785FC7F1C69431330EA88DC1F209 +:10294000821B5843B2BC976BCBB93F560B2622C5AE +:10295000558C54CABBACF5EDF83DE5611A37A9D6E4 +:102960003CCC3ABE0476FCE1F61EAC9F0B8B756442 +:10297000D12BCACB14F80995E5D0B845AB4FBDAE05 +:10298000527580C67781F0473FB5165F523E098B7E +:1029900074921CD0D97C90F777AC95289FB3C64829 +:1029A00063E8D7C6F32AF626E455F0F2DC6CB3DE12 +:1029B00078B1C37E8EF9DA72DB39A6D19BA0DFFE37 +:1029C00048FACF665F58F4D9072F7FB2DC50ACE7E6 +:1029D000989FD2F8276BC57CC1DDC17CEB39A66B13 +:1029E00037C223E2D4F0DB6D3DA704C8A92CE2C8AE +:1029F000A933B53A8C87ED9BA0AFC0FD914BA406DF +:102A0000B48F40C16812C56B7C1DE84F83FDBF12B7 +:102A1000EBFFDED70976485399E5FCE3EF0DFED3D3 +:102A200022BE6F1C5F8EF05DEDF002BE7F46F8AEF9 +:102A3000E0F8FE3B80F7605952FFE4AA81EF6D8217 +:102A40002F760EF1EF0ECF876596F38BAF7A3E6D42 +:102A5000AAF6BF71FD5FC13A1C33711D66FEC165E8 +:102A6000B4F7507BF3BC34B1BE69A6E93F98E7C424 +:102A7000EFC4CEF1AEADC3F17AE3E77A74EE153F61 +:102A800047CC1B89E78871F8F3687E718E189E79B0 +:102A9000731DE545F7738E391FEB4759FBDFB41BF8 +:102AA000F9AC2D613E9759BF6AE6448237BEDE0914 +:102AB000345F7742FB1A737D6B674EDD6D58F00112 +:102AC0009DA87D4C2E31AD0EE78B9F3B4EAFB39E44 +:102AD000DF7E6FA6B65B9CFFCF443A36CF69FFA37B +:102AE000E363C14C1EDF11E7E5820E474ED116228B +:102AF0009EAE367861FFEAADF4FF37986FDD4C0B80 +:102B00003F7DD1FE317E34F5BEC89F00FC1A88DFC0 +:102B1000A6723569BE84F013C3BD2C827ECB5416D9 +:102B200091F15C221CD019C641637C6D54125FBBCD +:102B300062F723E6ED46F917BF1FD1B61BED8BB840 +:102B4000FEFE559D3DCF616E9DF57CBEFD955F8976 +:102B5000753F6AE593811EFF7BE576BCC4CA267E7D +:102B600096DCFDDF46D8EF5F2CA679DE89DDBFA8B5 +:102B7000DB6DBFC7D0B0DB9EDFF15D3B5CACD50E3B +:102B8000176BB1ED574679EB6E03CA2E33EFCDB517 +:102B900042EAE77EC572920BE25C17CA36B940E59D +:102BA000EC8187EBB7828E4C3E8DC1D9273FEF9BDE +:102BB000BBEDF9790333BF452EBC8DFC30F078E7CF +:102BC000F73B04DEFBBBDFB15815E5C6BAFAFC2FB4 +:102BD0003F2FE6FF59E5C9975F07BF2FE24ABC2F99 +:102BE000C236D6D9E5CF65C3E72A4F2A7F2EAFFF7D +:102BF000A0F27EE58F0FC76DF63AE83E8AEE674990 +:102C0000EFA33495F373A9187F9AF751163C9CDC17 +:102C10009FFEAEE94F8B7877D0757E85F5BC6B74DF +:102C2000398F6FE796C7F25072697D8D1CBE00CA5E +:102C3000433CEF610AD380A7162E18918DF035FF23 +:102C40008E8FC7FCE027A7C7C7AB36E713F3BC34AA +:102C50002FBDC69AD730D69C27109F2F40F3ADE7E3 +:102C6000EB9007ADA67B5E31BFDAF831E1B5C5293F +:102C7000FCEC4EE2EF78DCB883E4CE22B7A0FF276D +:102C8000775BFD89DB7EFD14C9370C5FE0395EBCE4 +:102C90005F7BDDE5F42B2B37F5F12673BF8CD87EF7 +:102CA000CD44B82FD5DFE24747A5ACB81FBD6F8232 +:102CB0003607FB833F3DB7BCE0D2E3009E16119E72 +:102CC000D6DAFD114BFDE2725B5ED2F9D517CB4B24 +:102CD0005A61EE7B7F79492BCA6379242BCA2DE791 +:102CE0004AC17925E905182719E6487A8FE21E734B +:102CF0005FE3F95DBFA4F5B408BE33CBDB3379FDE8 +:102D0000B77EFD6C9DC9576BCA2DE717E2BC85E500 +:102D10001F8E629CC7925FA439AC719F92534EA4E0 +:102D200087A5DBA4A4F9337DF8A5D51C7F5B6C1FB8 +:102D30009BCA797C5FC7B8E36231EE3736D0B835CD +:102D40002BF8B8897CB3D5C4DFD6389EB6129EB4B2 +:102D500058BECD8358C69401F7F8F8F8E27E4FD0FC +:102D6000197E01CF755A0C4945F9AA372EA3734530 +:102D700056013C09FB141C96BB0D4587986F5C05FA +:102D80009F0FFE598AEDFCC042C630B06B2B96D126 +:102D9000B9F3248DE7AD4CAEDA200F5129AFE547EA +:102DA000B8AEA285EDCDB8BCDB6A7F2127CB67E941 +:102DB0008EE5B3B0B7460D05FE36E1C37B216B61EE +:102DC0009E7762F92C5565EBACF92CE12F97CF2259 +:102DD000E27F4B428057CBBE8D34D739B282E33588 +:102DE0007E0ECCE8FCF6465633EB268C2FE3BD2D49 +:102DF00078DD6DDE73BB90CD2278FEBF617A2AC587 +:102E0000F17A33199DABC28664544FC23C12FE4B1B +:102E1000195D4A715C37AC0BD781E7B2D1AFC1F015 +:102E200072EDA068127A7E234367012FC6FD8DCD17 +:102E30000CCFD5F447E87CEE86157FAEC77997EACC +:102E40006E15496071BDAF8CF2B856079CEB300E21 +:102E5000E9979986F1EC2AE77BFC9CC643789A5B5C +:102E6000CACB022F6EA6BC67C58B92506E3CB16177 +:102E7000CB214B7B5734251DCF05DF2E4FB7DD2BE4 +:102E800062B297E8E082DF11C173A86E85752900F0 +:102E9000479D2ED3F97BE7B635AFE3FDB1A57E257F +:102EA000E0807596344A94FFB5D8C7F1F49726634D +:102EB000CB21B0615386E5D239CC059F87A2F12D95 +:102EC000B59D14B7077AE95630AFE70199E1B9B774 +:102ED000C87F9A67D28BC063CAB28F092F17F03CA4 +:102EE0001CF1529849795073001FAA8FCEF93721EF +:102EF0009E525943F41A98F756BF83452D7168586E +:102F0000BF2D8F0CC6A6BC3385DED8EA093FA90FBA +:102F100094F07C34B92A8AFB7AA190EF2B94034871 +:102F2000EFAC94D3A9C07F6A029DBA13F2C312E931 +:102F3000B40FFE2BEC78EF5458208AF4764C26FB25 +:102F4000A277A7924179573B1D9477C55884EE31FB +:102F500075B2C18136949B5189CE096E33F126F04A +:102F6000CE58C3E6E518E76EC80860FC9F391A36EC +:102F7000637ED4E2481AE5DFDDCEF6521ED41DE8AA +:102F800021C3BC77329F0BCBCB59809E12CBA7FBC2 +:102F900025B7EA12F185CEA2D53701FEA2D7393383 +:102FA000AD7955FDE635C1CACF5ACE23465598F2C4 +:102FB000D2A3FB799EA76EDEFBD1283F28B3ACD409 +:102FC000A32791B7A545FAD72B0A2C7918BE064638 +:102FD000E7D345E1311543E2FD9F9AA08DC5F2E4A8 +:102FE00042ED166CBF07ED3CD0078B0E8F7D02F5CE +:102FF00059CB046D3CD627CAABD3FDE7DF451B8117 +:10300000EE7A505E511E613EF1E140E5DF9555F4E8 +:10301000C9BF2BA7F598F977279DFC5E19E5224FCC +:10302000657DEFA735DE46F5E27E5AE2BD34F62334 +:103030005E8605196DE3F0FE6E03AD5BE03D113F6A +:10304000CCBC97B6C4FF4A8F347600F2D67C60DCE5 +:103050000DBB187D18FCFE72F59A9E2CCA235428CD +:103060008FB02587DF5FDE844D30116814B7070706 +:10307000557239BE25B3C11F80FA2D4E9E0FC3F283 +:1030800074B6604C7CDC4195B238176A403A00BB9C +:103090008FEC2561AF8A76F7997AA1B14212F7CE0B +:1030A000EEC7F696FCEE46DA0F6F34E210E776FCD8 +:1030B00047E740C27E383EBC81F269DC5A727BA190 +:1030C000B922A6CF9B69FC9D429F6B9B70FC19D7D0 +:1030D000F816229FB94A64D6817A6CEE5D24779FF8 +:1030E000C1BC51B06926EB1B4A86C27E3F52619E2D +:1030F00037D56722BA58B7C6F349A3C50D7ED47732 +:103100005B8625BFF77DB282DBCF13AF3F2FE3B8DD +:103110005B9681A7320EF167501E9BB1086409943B +:10312000C1DD3F84E7321EB4038A502FF2F6BE7A27 +:103130006803FBD865E22B7823D00FDACFA3EDF933 +:1031400048E229DA25E65B81284FC77527E6B98969 +:103150007CAB1EC5480F24817F6ED95A0FE56B6585 +:103160002FF7A09E6CD14A68BCC4BCB72DD96C04A3 +:10317000C29598D726F2A644BE9418F7B90A4E27EE +:10318000226FCAEDE77A0B9E942713AD50CDFBBB9F +:10319000F6FC36915F83ED29BF269BF1FC1A7F0375 +:1031A000C37E6E2863FBB0997F9698570572E8201E +:1031B000D1411FFB88919DD15264E60D306DF332F1 +:1031C000B48FF0FC3690C4BE0281807AD005FA0933 +:1031D000EB15797505A6F27C593BAAB428DC83F07F +:1031E000B9FC3139FB3B82372E67DF35E5EC09ABA3 +:1031F0009C75BFBAF509B4BBB7489C0EB700DE9FFB +:103200004E421F1F98FCB6253339FD7C6ED26BCB26 +:1032100084F08738BE96C5EF777C513BB3256E6747 +:10322000723C0E909D09F8F8CC2AA7011FFF2F19B8 +:103230001EE0B709E58625CFD45959D07F9E696233 +:10324000FF2BBD277C0DC80DE43FF0077D95E40FF3 +:10325000723A16F2387EDFF6CAE4F53107C85180BB +:10326000076D026BFBDC4A2EE7C64DD5732B492F49 +:10327000F3FBBE5B83FCBE2F8B6AA4F78FA7EB35F5 +:10328000C8A72C6FFC25E6DB60E6D3EAF56192F374 +:10329000F32FD17EA339BFB9DEBCC1A43FB64ADA51 +:1032A000AE54395EBED4FAAEABD42623FCCD7A98A8 +:1032B000BE97B025CFA11AB0B47F9AAC17E3FB2D0F +:1032C000791B69FFDA80E024909B731CE71FCA9585 +:1032D000281FF85969103C3DE0B125A1EB59959C98 +:1032E000EEC18AA57A7642F35BE31C6B4DFD16CFE7 +:1032F0000778FA09EB3DA61595FB5618163D86F1A1 +:1033000092A793D0C5C24ACE3FB27B8D4D4F26B611 +:10331000BBB5D245ED56569AF10853EF2D72733F67 +:103320008A1D01F82C7A75DCD4D0EDB4AF063324B5 +:103330008B3E14FA8F6A2CEFDD7E7EFF841DB38FE7 +:1033400023D6799F49A7625EA0D755C81FA077BF33 +:1033500081F388FA4532E3F18E6E3BBE009ED59C28 +:10336000CED88A587E96051ECDC1C78DC1D1638740 +:10337000E33E733FC64DD5EEC371401FAFC3676BCD +:1033800008E82D095EC71784BE8DF50A335A73739A +:103390002E6AAF6EC076A26CB1579B2BEDF6EA2673 +:1033A0005C2FC8D1CDF87E4F6AF2797798F81AB0C1 +:1033B000EF065C269F3F88FF4CC22F6DBDFBD2C637 +:1033C000028BB9DDC6BDC497F9E32FC1579C8FEFBF +:1033D000BCBE81F4DB0BA6FDF1829329985703BC98 +:1033E000154896EF73B452D81B91E18897E7FAB16C +:1033F0003762EDFAC9ABFF1ADB9176257647DBB46D +:10340000E36964777CD29186FAFDB933A1A476C7CB +:103410000BD93B8627B33BF6F76377BC6ADAA7077D +:10342000DF77911D517C8EDB1DC5E776C8683FBCF8 +:1034300059A9D27A8ACE74CB3AC05D8C76078CB308 +:10344000DFB43BB03DD91D9FEC9011AEA273DDD42B +:10345000AF18CA687714F56377001432E2E1D9E255 +:10346000B67FC5FD4B5CEFBC897A8F956E0B7BBB3D +:1034700029BE23FAB5E56D4CD369BFEDF4535AA4C8 +:10348000DAF2E20B7B39BD27B6EB8FCECAE4AAD6BF +:103490005E58D75696BE83F2319586C7B16C180A2E +:1034A000FF3E1E7E5F039EF7CF051832B15DC34F0E +:1034B0007A51AF186E1F7ED7E02FA94BB99FB396F4 +:1034C000F99C53E37288960EA01921733C97C7D7D5 +:1034D0000C76D2F7D332088F8D3E11CFD951910B94 +:1034E000FDEFFFDA28BAF7137A040682F2D46332CA +:1034F000D58BF8CFEBC318E5E703FFCEA986F127FC +:103500009BE3839ED3EE85F68B4C3B6CA6ECA5F635 +:103510000FE6F1F6538DF3F5582EEA75A978BF8CB6 +:10352000C9EBE5BB316E8BF608B47FF0F9709907F3 +:10353000EA538F032438DE0917C52F447CA1E0D855 +:103540005EC267DA19972DAE910A122F6AB15B5CE1 +:10355000096526D70E4A269FC433310E71ED2CD350 +:103560001F1DCB6EF91CECAC0B6C7D2BAED13D3A24 +:10357000747037EBDB5FC419CE4FD446CC827D1C10 +:10358000E5D4C96FD95F01B8867DDABF73E7ECB1C6 +:1035900088F71D0AC5754F7E3B8DF6E9C0234A3B6F +:1035A000C6934E029FF2F8ADB112E9F5403A13E727 +:1035B00040518CCB1D88DD67CE5EA959CAE35E2BD6 +:1035C0007C1FF5E08121A2FD8F79BD281BFFB4127D +:1035D000F3360E0CE3E525AF3DD369101DF72AE461 +:1035E00057379EF626939F9366DBE9784EE11A4E95 +:1035F000C797E807F27EC6AC24FD52AAB97F75A032 +:1036000016401A8778D24B67015FEFEFB9A7750CA8 +:103610004C3571DAB7BB498E5ED3BB3699DC5F306F +:103620008BDB53D1E208F95BE0C3737F97298730C6 +:103630007F750E53C7A35FFFF0F4E77E3316E6797C +:10364000A368F47839095FDF3D2B97C689C37754A7 +:103650005E8E72E9A3F716269303DFAFD417DBD78C +:10366000C3CF479B772884FF0766FFDF2730EF2112 +:103670005ABC83E277FBFFE460E8AFEC1FC3ED7E4A +:10368000BCA187DFA51C00F8764E4E427700DF5DB7 +:10369000B30AFAC2377936E3F9A113B56F617D2217 +:1036A000BC2AC6B9015E30AF022847523EFC2FDD6E +:1036B00018CFDCDFEBA0A0CA85331D3292605B4FD0 +:1036C0006E299AAB33AA4EC94852C5BE4736E3D1DC +:1036D000AFBE5EB6F1DFE49E545BF98E866B6CE59F +:1036E00025F5C3E3FCC8F01ED0485BD9EDBFD95621 +:1036F0000EB209B6F2C2AAA9B6F1CA7C25B672B951 +:103700007FB6AD7DA5BAC0569E9DB7C4D6BE3A5011 +:1037100067AB0FE78F53F00A1FD0E5F771BFD38E69 +:1037200069C4E75B7AEEF1215D448BC3E44F1F4F20 +:10373000EFCEC678F5EBFD7C57EED42CAECFEEBCC9 +:103740001E4C239493A0CF3766C6DB07737B6DF1C5 +:10375000F8C3B3B87D7A7056623CBEBF7B705C3FE5 +:103760005FEEFDB7443D3CF7A67B482EB52D942374 +:10377000789FAA39EF2D2FDE1B7B7D218F23B46527 +:10378000C33ABD948F41FC7570D16D23F05C2D352B +:103790004FBF06E5BFD0DF257911761AEA537D11B8 +:1037A0003612EF9741B9CEBC675692CFDFDF68BEC5 +:1037B0005F854FD0DB332DF84AD4C741CFB897C1CE +:1037C0005D60D3FFEAA3EFF72DCCE7F19ED24F2245 +:1037D000A5789F7AB6F6D2217E6D9ACB9F378AFF65 +:1037E00098D58FDE7ED3CEAF47891FF69F997F5144 +:1037F000F9FF87261E5F7FA6C9C3A2B0BE134D3E48 +:103800007AFEAEC94FEF8F36A9F46C69CAA367B4CC +:103810002940F5FFDA5448CF434D1A3D5F69AAA00D +:10382000E7E1A630B57BADA9869E479A747AFFF191 +:103830002CCE97570B3C5A9E8827840F3A24C2EB14 +:10384000424CD59D724E93ADF21DF0FA6932BC5ECA +:10385000A91E8916EF1D1EE67A2A291F0D9D2DEE41 +:1038600085713B798E4E323F069F0BE37359F1F819 +:103870009C1B4D9AC104E7A0D9050307E701337EDD +:10388000732093D53CCDFDBA4D12E91BDF382ECF06 +:103890007F100E913C1F322EB93CCFE923CF979178 +:1038A000DE6287316E8A6945288CD7E1FCC9E32145 +:1038B000C6A09C8BE281CE2B051E2CFB15B8123CBA +:1038C00024AEBFB4489B8CE3E03D14E7E0BE7AE44D +:1038D000C6DECF348C493D9BCFE17DF8BDF983D066 +:1038E0005E7163308AEC1570F00A71BF99698FB40C +:1038F00077D667F71DE70FC57B49AF3F18B3739EB7 +:10390000203B26B11DFC0E111E506F59F090440E45 +:103910008493ADBF4C7EBE7723F43FD0CB285EA608 +:10392000A24D0DF03FA7F0EF341C38E7203C5FF0CC +:1039300048241FDD0FDCEBC1D8F6B3DFE5ED8C6A60 +:1039400089EE2FA475ED57D14E0DF6EAD7E0F7C6F4 +:103950000AA3954EFC3E6868DAB8408A850E428A12 +:103960005D4FA2A51AD33B140C1B9C50BE2EDE5EED +:10397000C6FDCF8D9773E8DEF53FCE063A9D7FBE3C +:1039800081A9F9667C35399E564B96789BC202AD6B +:103990009373C8EE3C741D9EDB8C661199E8CA20B7 +:1039A000FF5BC02B7BC3742F4FF8E99F4ADAFDB34E +:1039B00093D80FAC5EA37337E670D0B95BD304BD68 +:1039C00069369DCF279CCBF85EF93F12E8B45607C5 +:1039D0008BA27D6164B8087F89FB35B9B07213AEE4 +:1039E000CBFFA5FDFA1D92F53B0137AA33C89FBA5C +:1039F00000FE14DE436956F8FD28E3447AA4938060 +:103A0000647968B7DD2FDF1CC0FDFF7EDAF7C83FA1 +:103A10006A047F0BFDAF6DA61CBE3F35A383818278 +:103A2000DAE66CF81F58DF22B17007FA5B29D74736 +:103A300058461CAECED95C9FBBD91D8390CFBCBE6F +:103A40009927CF4C48E6EF71FFC419DBF76C1FF9DB +:103A50001B66D9EBD2FD98F7D8326EF52EBC8F6578 +:103A60000CF1F0F34E25ACCE03FC3C64DEAB653EBE +:103A7000836559EEEFCB4C398BF1D9563066F07C2B +:103A8000F79709F038AF101E174A18F447B35C11C6 +:103A9000CCAF51511E015CAD7E07F1CD2695F3FDF3 +:103AA00026AFE6F125D9B72D884777FFFB29E76CCC +:103AB000F2611C7B87D7417CD9AA2A5B73A0DCEA20 +:103AC00055F8F75A554745B27CAD8F6673BB099AD6 +:103AD000A4507E53703ED931FDCDD366EEA728A702 +:103AE000E6EB1AF18F1A08E37A9ABD5912C63745E8 +:103AF000FDAFCDF1459C78AB6917A5E6ED8D62BCB5 +:103B0000A665D8AA09882E0FD83967E1BD277F2F6F +:103B1000D9452D433C35C9CEBFCECFE671B6ADCE2B +:103B20004005E2736BBA831980BFAD39C9F5608F68 +:103B3000B97FCDEAF830D12DE063B4D4B7DD6F4C56 +:103B40007DB9D9B9C38FF7D0B68EBE95F2BCB68E0B +:103B5000E072B7F1C889CE0DF9C80FDF62FF86FCAD +:103B600090A5D0BEA92CE041FDD5E2537CE8EF4FF3 +:103B7000CC5AE7095AE497A0FFED6887C0D3396CA7 +:103B80007E0DD2E385C2D40022BD4C3E42DF0969DE +:103B900009803CCDC13CA4069FF5FE3FD8D37215E9 +:103BA000C0951E70D8ECED4185767F4165BA87E8F7 +:103BB0007318A7A3FEF62F111E2F4A9CF117699FB9 +:103BC000A9D724FB2EC9B82A8E574137CE4BD0CD6A +:103BD000A5E0B7E9BBECB8BECBA91AB10ACF2F1E3E +:103BE00062BC7EE491F39DE8AF2796BF2C7F362B15 +:103BF0003B481E378F72113D25F6DF9AC3E1F9600D +:103C0000F647341F861570DF323D3C8EB4BD7070B0 +:103C10004A32793B6BA25E5465B18B324BF7921EF0 +:103C20001D5CC5087F5E35EC1B05E3788FC940A39A +:103C3000806FC7677F3DA55E391E951D0D2CCCC7D3 +:103C4000233983BFCF40BE6598FA64CB0D6F30CC6B +:103C50009FD93E5209C89487702470313BDA5B6863 +:103C60008F137DD138504D95998F92C252781E5046 +:103C70005548A1FC1B07D79F1AFC3FD4BCC22E9904 +:103C8000FB3FD43C5A52F1158F7F65D5325A4F2CE9 +:103C90001F05BF2783E3E88CEC0CBC108BEDAE5BFB +:103CA000CDEDA86CD62BE1F9DE0D98952323BD73DD +:103CB000F97981653B281F07A6C17C12C97090BEA7 +:103CC000FBAF379C9482F0767BD1AA71B83F89EB29 +:103CD000585365C6B362EBB8381E049C034DA74227 +:103CE0002F377BB89ED54021A7A0119C10D72C93CD +:103CF000D7535CB3C570FB500F372BA077B3A877B1 +:103D000098E2A00971CDBFA4F0B8A7B48EF9A4229F +:103D10008A6BE6E13E35B2D400C61D0729BA07EB2F +:103D2000D346298CD355C3643C3F89FBDBAA97E774 +:103D3000BF35529EE0AF50AF41BBAECF2E2E8FF6B7 +:103D40005D42AFB51D1BE5A5B8B9A72E0DFDEC670B +:103D5000FCB947D06FB9E0E1F95BA25D57C2F74CFF +:103D60005A4C39D75365C6C753FE2263FF197E5597 +:103D7000C13CB990671CC9F76629F93940AF29DF02 +:103D80006E54DFE474B65A7C876C35C9FF77D34D27 +:103D9000FAADD79750BCD8B4E398A6A9BE4971FB39 +:103DA0004DE84BBFE233EEC271CCFCA93EEBECFA1E +:103DB0000786DF57617E4BDC3517E71F14CB9BC3AB +:103DC000F913EDB6FEF0D966FABDCDFE10E55D5CE7 +:103DD000409995E45C443CC1FEEC463955D06D9762 +:103DE0002F697976F9D2EA68A03C2EE366E6C33CF7 +:103DF0000F5615F05BED5FB0438F571133DBEDC904 +:103E0000FBAAB9BCEBCA54158CBF9478820CCF1BAB +:103E1000946C9DE17EB8FC818BEEC7CFABB8DE6FB2 +:103E2000C95B1E467FE5E1E9DF24BC4CACE079A527 +:103E3000A21DE8CB0FAA2C7E8BC83BB8ECEF23F970 +:103E40001C948F78B9F1A1B6692BF9F791FCCBE9F5 +:103E5000FB48CF78F8F791BAD2F534B4BFBEE8F793 +:103E600091EEAEE6F41AF27CE3E08C5C0B9E7A7481 +:103E7000CA0771F9CFD3B9CC0C337F24310EE47665 +:103E800037D0395AB4B86189350E2CF0F77393AE38 +:103E9000FF50AC539E4F7F7FDF41B4438CE1BADCCF +:103EA000669C734BF1B709FFF32B3229CEA49871AE +:103EB00026D7799DF27A3B27EAD7565BF49D3BDB08 +:103EC000207D97F63DC6EFAF7FCAEFAFA76D6421A7 +:103ED000BCAF1EFA6C3C9D3F85A229C467D33F0945 +:103EE000D0F7A7CBE4A75A73A1BEEB9842DF85EFCA +:103EF0009A9E9A857AEDE363DCBE4DEBBAE9C82D54 +:103F0000502E3E5687BE3EC81D806570DF754CFF43 +:103F1000C4F1A5FCC702F41F2DE72062DC5F361D4B +:103F200026FAD8D7D44DCFFD4D517AB635F5D0B35A +:103F300050D14A703D85DD7426C9A69C817A0B1C40 +:103F40008527A0BF851E864CD4B56AE2BF6E5BBBD9 +:103F5000B4BC1E5B3BF05F4BAB0B308F87E3D3856C +:103F6000DF0D83F1E7F6B0CD92FA1F4A5EADAA1ECF +:103F70001879F58FD505179357FC9C34D4637E27A9 +:103F80002C811F1DD52AF90D31BE34CF4B859E6E75 +:103F9000C57F823E6DCEF826976FB17C0C7EFF50B8 +:103FA0007C677EE3EB1FEDA1BCD277CC7A83FD4426 +:103FB000B3D433F6C92ABC0FF2123AAF60879E7BA6 +:103FC000BD6B15DE9BBEB52653D100BE123C58CD4D +:103FD0008CDF7F11798A8978FB9FD59CAF8FE7FAB8 +:103FE00028BEDE92CBFF5E4162BB37ABB9BC409AC4 +:103FF000B0FE1D8FD47EEEFDBC2AC635F1D6EAE2B6 +:10400000F907FDDDEF78ACFAE2F73BFE60D65FEA38 +:104010003EC72FCD795FC4790B282F720FD285F858 +:104020003B1B51F37DECEF6BF859D2717E6ECADD0C +:104030001BE7F8CCFDD414F33BD47B893ECCBF877F +:1040400020EAA79C8BD5EFA3F9627FF740A7F88FF2 +:10405000B85FF7F3EADFEED960F99E574BEC3B8986 +:104060003C6FE95313FEC4A7B85F12FB1E147B6BB1 +:104070008F66F91ED44FAADF396B7EAFEA10C16795 +:10408000DEAB79348E875FD3FB84EF0374BDFEDA39 +:104090001EF33ECE6FA8BE21F1BB5BEFEDB1DEEFAC +:1040A00079B4FAD42AB3FD515AA7F99DAE247461AC +:1040B000D2ED993D789FF032C67B97C633BFB3B53A +:1040C000D9E4A3FEE819DA9FA2F6B1EF0FD7795031 +:1040D000AFC4EFF1BFBBC7F6FDACFEF1F5475AB771 +:1040E0002EE665667E13E717911F26E8C23B87EF31 +:1040F000C776931FF0FE1FF55F316078F88CD69578 +:1041000070AFE852EBD837212CCF4138FCB1FC62BC +:1041100085CA5F121E711F2C913F86CF91445EF3BA +:10412000609A273BF61DCE6B06625E1877048D13EE +:10413000FFBEE7F57392CB9F2F342E532F2F6F4482 +:1041400094FF3F19A999BA607100000000000000B7 +:104150001F8B080000000000000BF3176060F8518F +:104160008FC09C687C5AE3BF4C0C0CFACC0C0C97AB +:10417000D818189C39191884F8C833E7229ABE7BDE +:1041800040B366F030302C636560D809C47A5CD8DF +:10419000F5D90822D847817E5F01C417E91C06A320 +:1041A00078F0E01A11068649A208BE9E18AA7CADD6 +:1041B0000882AD2345995D4E40FD008850BECB80FE +:1041C00003000000000000001F8B0800000000003A +:1041D000000BD57D0F7C54C5B5F0DCDDBB77FF2728 +:1041E00037C9029B10E24DF863D04037103058D4E5 +:1041F0004D041A90D7AE69ABB1A576A14A151156F8 +:104200006B9567D5DCFCDF841002A202455954107F +:10421000ADB6A9A2B59FE5BD0D508A7D7E9FE8533E +:10422000AB56FB62A5B45AA5F1594AFA7D086FCE88 +:1042300099B9D97B6FEE6E962A6DBFF86B87B9F38B +:10424000EFCCF93767CE9C99956C6E52760E21A70C +:10425000E1EF12421EF21242C6A4D2CAEF7DF986E5 +:1042600027AAE8BFBDCED04E9A54FE626E71B4222A +:10427000557F1611B05EED2F96FC91D07AFF4EEC73 +:104280008A937EDAE71FF486685E15EC04DA394912 +:104290004DC1BF0468F9902DD445F3C993361FA1D1 +:1042A000FD4C2776E8842844F645A6D1EFE29773C3 +:1042B00089AE7F737AF16691240B08D97F27112389 +:1042C000B45E9BFF8225033E425E6C4CFEE5C864F3 +:1042D00042C2C9A9A242FB39D07808F3FFD678F8C8 +:1042E0002F471C8444491E8E533BF72371296DB719 +:1042F000DF411AFA68BBDAB0E058AA1B2FCAE7B34D +:10430000DFCDCBE51AD1B2DC4FCBE9F7DAC0E596C9 +:10431000E5513A23AC97C7FB191AB0433D850C7A97 +:10432000719E27EB2DE7398EB7D3F255036CBEFB98 +:10433000DE3E7119D0214972234E484F96BD05F8D3 +:10434000EE77090A29A5F81D5884F84D027E6917F1 +:1043500027DE61F8DEFF892DD444F15DEB927D21EB +:104360009A2722A5072DAFF59130C225D294C271AC +:104370001987FB2A9ED6438A7451902EFD2E4A1728 +:10438000DFE8F05EB2594278B579F6C33CB368A76E +:10439000D1957EF545FCB41DB1E68391F8A1E3CD3E +:1043A0003C733835BC46E6F6FFE5888BE0DF69FAFA +:1043B000BFF9F2F37F39529ECA5F3274D890A71CBE +:1043C0004D5CB329BCF04F0552F1CF035A79292B2C +:1043D0008771E28DCA9F2751FEEB6D247F9E44F9C1 +:1043E000AFA7D185F9EE4619F35D8D41CCC745DA0B +:1043F00084D231DE4D122A6D9F17A6F575E3E5567E +:10440000D3763AF8FC21D990F796070DF5DD8A624C +:10441000288F2B37DB1294EE9D15B6845D0038A8EB +:104420008C9C0B70B830A5E0BE16A4F399C49A908A +:10443000750EE5576500CF4B76D24CF3394AD8B6A6 +:104440008CE64B82769208D1F1730609A1FDC5EF87 +:10445000246423EDAFBB72B66D19CD77CD71CA76EA +:10446000999004ED3FEEA4FD9C4A2A2DD0CF34292B +:1044700004FD905EF1B7802717FDEF741921131525 +:10448000E91D5B0E21A52AFDAE9F9F530D825CE7BF +:10449000561BBF4F5496DF4868FD8944F7BD34452D +:1044A0004F6D5C2D6F1ECF3CCE396B4CFD9BFA2DB2 +:1044B00051066AE48A54BFE790C126D9F7CFDC6F72 +:1044C000B856003A858892A83C7B70FBD67C9C77D6 +:1044D00064660ACFDD0EA607CDF236406CA83F8891 +:1044E000388684295C8A624B74D17EBA4A6DC83F93 +:1044F0004A1B4980DE5A37E1700CF25DA592D24C1E +:10450000F3A5E5071B84E984AC9D2023DF75ED75D9 +:1045100092E610832340F9B444E3D353033565C0D6 +:104520008702096DA4E5A5CAD126A82FBFE6511CB4 +:10453000D523E747D6B0F9639ECE7F10FE316B647A +:10454000BFBF9C258523C0B72A4938293C9D939A33 +:10455000EB543ACE03AA48407EBAEEEC7B1DF01C29 +:104560009FCCE035CFBB449196025F13FDF874BC3D +:10457000924957DC00F332C3A1E98BEF37CA288F89 +:104580005B1ACB317DA051EE033DB1E513BB257E17 +:104590002F13987EDEEA88D8003E758E2DB113F574 +:1045A0004F74EBF5347FFF77C7CE8075E0E6393680 +:1045B000D42F7FEE66F8BE5FE8BD8A607D49C1FA00 +:1045C00026F97F400C377F8BD6BF3F5840542ACF07 +:1045D000258EC30BCF85FED69455AAB4BFFB6FD9E9 +:1045E000F80EB42F993345B1D3F613AB8FBE4517F0 +:1045F00071B2E5D44030E2833C93EB923563FB2605 +:10460000513E19AFF4DE04E397544B4AA234C597E8 +:10461000C52484E39CD3E025497974FE2C5E9999E6 +:104620003FCF9E1EF8FBC85511C855410AEEADDCC0 +:104630003E31D37DB160437E1996AB6A26574F5EFB +:10464000C8E8ACC9D59609BDEFE5D27CCF37189F35 +:104650009AF9BCB4FA680DD0B59BCA4F7E909042CF +:10466000A7F2B140F33D4BB91C561F1596D3F67F08 +:104670007AD5A31090A725D6FA3A1D3FA752E3B8E2 +:104680000FDC62AB8DD07ABFBC76CA1F9D30DE12C4 +:10469000490139EB11CB717CE5BB92A2EAE859B232 +:1046A00084CA13E5AF925BB8FC98E46AB4F1E38D79 +:1046B00009F22E95A30D8D4112A6745BDFA8A07C94 +:1046C000ADE37206B62829A4792E67A47C06E6D34A +:1046D000D99F8434A1DCB994248952FA6CA07D93CB +:1046E00022F89E0C87E712920FBAEA42042769A3C8 +:1046F0006BFBFAE17212A64C4F7A049E57FFA88614 +:10470000E9787288E59F6BFAA3DA428570839BE5AE +:10471000F70AE535EA5C7DFB83D8BF569FE693B583 +:104720009374FD41FF157A786C35505FEBEF8DA6E1 +:10473000A21A958EBF9EE7A5E63C963FCBFD770B70 +:104740007D41CAF464ADA99F6E81E349FD8F70D8A5 +:10475000971AE73EE1BDB06A28FF4318F0A495FF21 +:10476000A0E93F5495D6FF8844B608940E33E64539 +:104770008B08A5BBB72E49C094DA60C2776A7E2F3A +:10478000E1FC7C152CFF60D32761C0B756FE8CE09E +:104790006F027C03DFF8C6121244212164F3CFBB01 +:1047A000AF7F01FE5D9E4FC81C3A8ED24B14DA8754 +:1047B0006D524C807D47708978D4200F9CEF287C07 +:1047C0004F08349D3137FA35580A2DE053F5F0691A +:1047D000E38F06AF06477AFE64E39BF9A87641F5BE +:1047E0008B73A97C790F3B424E05E6210BA0C7F3E2 +:1047F0000128AAD7F24EED473A11B12F0876B4B985 +:10480000DFFC794524A19BE7674DCF2D9067787B2E +:10481000454F579A7F4D8FC727A0DEAC917CA7CD1F +:10482000CF0DF3236007D3F955E9E7F75403CC2FF5 +:104830001DDECCF35BEFEE6D8858E8DF8B6D7CBF3F +:104840007B71F597A07F3A1E01FDE5560651FFCA20 +:10485000301EDD6AE69EDADF005BDB74E3C973E9D4 +:1048600078E5670F9FA3F1B18FEA2F85D6B3853224 +:10487000F3B1599EB5797B61DE02F011DB0F98E749 +:104880004D08E523FFFFBFF3FE5864F4BC85F6AF87 +:10489000B27931F9F807CDEBE3170A505E011E3B00 +:1048A000E3E7A0157FBD2B28867DAE99AFD3CDEB76 +:1048B0001FC5A723E79519CF675B0F65AB5F9B5FAC +:1048C000F3201E7BAE61FB849E43F3D1EFD0F3C295 +:1048D000A5E3008E9CF8F9244CEDDF29D03FEDAF25 +:1048E00047B32F36578DD23FB32FEE6B247DAD9358 +:1048F00009793A6700F7C3144E6CBF95DA9F09AA8D +:10490000E0AA5EBAC5BD948EB7F5BA8D6EF02BF5F0 +:10491000707BB1EAA587372CA0F81C776D7EA59D2A +:10492000B2428F5BFBBEE7F929F4FBE66BF877EE4A +:10493000BFA2DF5F82FA415E3F1D5C85D2403482B8 +:10494000F242E1D2E15F2B7FCAC6ECD227C1CE3A58 +:1049500017F633CCCE2AF4F42E05FAE66C959407BC +:104960008591FDFE6FAE4FEF033B8DCE77CBB5ED5E +:10497000456057EDDB317BBF0FE0BA86A03E3F3785 +:10498000B1ABDFA1C0F8AA00787ED241343B0BD78F +:10499000F9A26B34BAD60B974EC276DCCE62F9EF31 +:1049A0000FAFAB5F47BBA538CAF2CF347FB7A64580 +:1049B000D495ABDFAE0917A7CA5F6CBEB106D6DDD2 +:1049C00019AEE89B7329E96650BDD742E198212AC8 +:1049D000F618F0CBE680A5BDB8FB79574382E277A5 +:1049E000F78E2913AFB55847281591CE5A7EE62188 +:1049F000A39C3D09F873021E99DDDA4DD10BF583B6 +:104A000051A505F039F31009C17E349DBE4B47C74F +:104A1000E036A3BE9B211AE775B6E6F31191D97E65 +:104A20009BF74FD7F5976D6C3E7690A3992293FF35 +:104A30004F3B9F24E089D911BFB1EAFFEF35DF1961 +:104A40003E3A4EE0B31F27681A275DBF667DA5D6A4 +:104A50001241047F7C1109013C79F36204FCF87671 +:104A6000DFE1A04AED3D511EC0D411180CAA54EF4D +:104A70004A41A510526771A810BED3FD11978F8EC1 +:104A800026D4ABC3F9CE26D0A3EB218FF2B716CB39 +:104A9000370EE7D761FEEE094C3ECFB1DFD30F7A78 +:104AA000B80C940D856B5DFF1B0DE0072838E00BFB +:104AB00081A951E00B11D0C35A794FFF7B4117D820 +:104AC00071077CC44DF93D5F0E137DFBF5FD7F0D35 +:104AD000CAB4DCC7CB7D8188A17C63FFD4C22045EA +:104AE0009187977B82512CBFBB7F4EA10276CC0170 +:104AF0009F0CDFBDC5311CF7D25FACB4A13F76B1CE +:104B00002DE1D4E9ABF8E219A8DF9708D1A9764ADC +:104B10008F9A5F74BBC07E881FA81807DFD1E6415B +:104B20007F92F87F613F0AD9D36807F9E4A3E7735E +:104B30007AD953F4E886F30AF403B3738A383FA7AB +:104B4000506B9349185FCD6174A21C9DF23F63FBCB +:104B500043297F35E60F1BF27E3911867DB418A0FC +:104B6000FA81B6F786D530D05D2A6679BB2F9404DA +:104B7000FDB1F91B2404608B149F507FFD1C9A57D4 +:104B800080FE116CDF398BE5A56054857CBC92E515 +:104B90009DC5B124E4D74E65F9CD1A9DC9A3463E03 +:104BA000207F42BA770EE7DDCD501ED7F886789B7E +:104BB000A17CED454CCF168935FB00FF9BFB3B0BE1 +:104BC00097D3FE73811F68FFB94B42482F8D2EF794 +:104BD00029365C6F35BADCA7CCC07382CA5C8A09FF +:104BE0009C9082F4A83CE7669B0CE71DE7DB123B38 +:104BF00005389FEA760FD07A9BCB6760798968E7A2 +:104C0000FE01E60FDFC9FD0165D4BA00BB63275F73 +:104C1000AFF7DD332517DAEDDBFABF90DE17DBF3F4 +:104C2000B0DDDA72767EF32C5DA7C14FF74CA30B93 +:104C3000D31FD1FEA2545F3FD1E8C2F4078D32A644 +:104C40008F523D0E69372D4F82DF81962769BE6FE7 +:104C5000C05607F27F4F2335CD68FBBB1B5D1F8B12 +:104C600093C15F21637E7D6310F3DFB6D5AFB133AF +:104C70007F8AB782CEEBE99727A17F2FF4862D920A +:104C80008079CBA4607155EABB869F6FDB6AEF0425 +:104C90007EFDE18088E31071A0EB7CEB7ACD506F54 +:104CA000FA1B22EB2F30B0F1B28065BD0EA8F7F8E9 +:104CB00011063771253D69FAEB06782BDEE6F00523 +:104CC00093F969FADB00F51E3BC2E1F325BACEB3D6 +:104CD000AE772F8C7BDEDB1CBEE2C4C645D6E37EFE +:104CE0001FFA73E5337BE573E0CFA8C2756087A038 +:104CF00093E74D4B55C146E9EC2A188841BD6955EB +:104D000031A18C8E1FB83A26D8A6313BC346F36E2C +:104D1000E887A6E797D3725A6F1394FB75E5D09E88 +:104D2000A6532B5879E09BC6F261BDDD40343B357C +:104D300009CED6E0578CF92936A61F9FB3FFB606D9 +:104D4000F87D8AC4CAFF1BF260772D36D5F7B0FC18 +:104D50006FB5FA39ACBD4D6479573E9B77CE565747 +:104D600002ECAE0DF3DB83CB7CA9F9E62D889743EB +:104D70005E9BDF86055B83CB74F3C9FBC2B6F2652D +:104D800015E9D715B7622361DDBA3BA5B782840B5D +:104D9000FEF9F5CB5775EB06AC2BE3F8BA30AE9ABB +:104DA000AD2B146F2AB35719DED65F64C45BEEC512 +:104DB00046BCADBFD888B7DC4B32E3ED977CFC74C2 +:104DC000F8A3E387F5E36F5C681C3F7F9171FC8D6E +:104DD0008B8CE3E75FF6A9C74FEAF9A6B7C638BEE2 +:104DE0005C6B1CBFB7D638BE7CE9A71B5FA34F67BF +:104DF000FF16E3BA5E15217AFAC5FB3B8386753D43 +:104E0000C4D675AD7C6DFF4F83B0BEBB617D07FF1F +:104E10004C395BDF2BDFFD28087EFBF5171D0CC22C +:104E20003E633DAD7BB822B56EECBBE856DB63B4A8 +:104E3000DFEF4C65EB4CFF45CFB840FFAF2D67EB84 +:104E40004C9C9FE77635268FAF74A4E6E58FBB7147 +:104E5000BFA7E587ED25F2BB1AE0C378B98DDB4B20 +:104E600085CD616A8BBAA68A867C67052BBFBDB5E6 +:104E7000B059055F8AA816C23AE42D277FAEB0D894 +:104E80006F69E36BF0A41F9FED8B53E34F348D3FAD +:104E9000D130BE96774F63E5AA38A916E0D9CCF792 +:104EA000CDB788BF43FD72F6E09BD61C9EA4878FCA +:104EB000E553F0B1BC06DF5DE2F45A75D2DF13BEF4 +:104EC0000B4CF8BBC084BF0B0CF85B23569F11FE44 +:104ED000CCF5BA4DFC790309DF268E013922686FC3 +:104EE000C644999F07B1FEAA442E5F303EC4ED2C04 +:104EF0009512934B59793D5DD796887C1FC6EBD7A9 +:104F000099F29AFD0ACBD169F4C358DBAF12617AEA +:104F10009BDA1DA19DA8D743284FA97D07F363887D +:104F200062241CB1D007F78AEC7C5890430D00A78F +:104F3000E893D08F9AAE7EAF2870FB5A359CEFE491 +:104F400092C1A41DE008128C4F2227BFAC5C3E6DBD +:104F5000241C921889C2387659220FD2715AF3AEA6 +:104F600050F4714C8F6AF004C3088F2433782431D5 +:104F700014B6F2033F2832BF85D60F8590B71F24A1 +:104F800060276AF0B5B9230D4BC19ECF93104FAD8A +:104F90007EE379F96FF8BC5EE4696B9A733F02D1E6 +:104FA0001810BF34B61AEDD096EA5A17F0A542424F +:104FB0002EF0D7B7FAACE389B4D46C77C6A95D0AF2 +:104FC000F9766A9742DAEA7BB20ED69DE3C0C7163D +:104FD000E7DAC37A2E642349DDFED35BEE214983F1 +:104FE000FF348170BA957CC37767B0C8D0CE315694 +:104FF000447BBED5674B40A8D168F0B773F8B57A4B +:105000001D62CC2567B15F76068DF09E3DFCB1F642 +:105010005E479F6C05D76785378DAFCCFD4B05523A +:105020000CED623112D4F3BFDDC1F8542A70C5987B +:10503000BD9EAEDCC3DAFB6839D8C5BE8802E72F57 +:1050400054E4314ECC0572A0C3CF78DEAED5C1CFCB +:10505000A3490CFDB582126B003E72154B783E6081 +:105060006EA7A51EDEBEE393EFBC8EF231C685F2BD +:105070002128547E2CC6795C0C8F75D074B3181E11 +:1050800007A9E3943D6A2527631C4C8E5D9188E255 +:1050900062A12696F0CFE4FDF66AF0AB313CF7CA88 +:1050A00016FEB22CE19F99827FBA6316C2FF39487F +:1050B000D3C13F8DC3534042FDB06F0706857E09C3 +:1050C000B95CD19FCBF5F07E0B387C84DC8474D343 +:1050D000CA3B391EB29DCFDC2CE7D3939A4F1D9F5C +:1050E000CFC24CF3F9029F4F8F83AD57AEBA8812EF +:1050F000A47C959F862ECB79FF5B87E972D319F14B +:10510000D557B39CC7F2D43C9672BE5A96691E51CD +:105110000E4FAF9DCC3902F13313F97A43EA0D7487 +:10512000D9AEF19593AD1B84DC6CA0CB3DBC9F6CDC +:10513000E7B33ACBF96C4FCDE77B9C2E77649A8F1F +:10514000AE7E13AFDFCCE50AED96ED8EBDCD607F70 +:105150003C2E46DA1DB352E3D17A1DFA7AE3DBBA6C +:10516000B47A6BE1BBB078B85E371F9FDB450FE1C7 +:105170007EAC0D6C0C6ADF7CB1EDC55AB0C769BB63 +:105180008DD87F84AD9BB4DDDDFAFE67B6DDDBCC68 +:10519000EBDD07F59A2E3DA5F5BF59DFFF764752A7 +:1051A00083631BC25137DCDFFDFA7ACB1D7DCDEC6A +:1051B0009CB0583EEAD5D935C1ECCE7D1C81687CC7 +:1051C00000FC95C4DF0B7647BB18DB3E00FC408D2E +:1051D000BC9DF4FB6DCEB020D0F5530EC71E817A76 +:1051E000F9AA53B603DD6A633F82BC6A2311888B38 +:1051F000BCCF7BD776C8AF115DB23304F696824739 +:10520000433D0111E379DA84A80AEBE20931FAACF3 +:1052100003ED1EDA251DE7B60225D12580FF96088D +:10522000CCEE60706DF05E1D07389C142E880F6EFA +:1052300033C145C7C37D79E718166F4344522E42E8 +:105240007F764F08FAEB1F732BC21B6F72CAD03EDA +:105250003EF95684979645303ECF1143783B1C2E3D +:1052600019E2F1EEF3AEDA0CF1766BD45CAC8F7030 +:10527000C0FC279621FC6E124B2E2D05F5D51BB6D2 +:10528000013C8B258C4B8E0736E2FEB66B315DE41C +:10529000E8B85DE51B5568777CB107E3EBDCBE5EE3 +:1052A00002F15605974904E280DC815EB433F317BE +:1052B0007958BE98E038F99F67F1B20E322097D145 +:1052C000B420CEE28EBBCAEBD5A560C754B37854E8 +:1052D000A2865F86F8B63CC2FFECC5FDD0BF63BCBA +:1052E0009DD84329FA16F40EB7CF8D5AC8CB70BD9E +:1052F0004496F592D9D5CB8F8BD9D5EBCDB25E2222 +:10530000CB7A4956CF492ECFB58AF718E6FB7912EA +:10531000DA1F5A7C5B0EB5FC87ED935266B7EBED56 +:1053200015079152F60AF0997D494638D6BCD51436 +:1053300038A0B36F02923F80FB8D0BC8052897A35E +:10534000B43FD1A8060E38469F2F485852E7271F72 +:10535000ADFE5AB0F79CE9CBBDD3AF08A23E9BF699 +:10536000359E2E616925FD5E016903CF7F8DE7972C +:1053700034842DC6AB91981E2E27918C747073F8CF +:105380008FC2993F6D522ED2FA16E7E35AEAABB0BC +:1053900099EC46A3BE73896A2D9E7394B3F8412796 +:1053A0000823C84D88A07E7190A45C86E78BE19CA1 +:1053B000A56353F2E3088E45F9F93F85762254231D +:1053C0007D428047339F98F9C267E28B4FCB2757C6 +:1053D0009D253EF1C6ED59C98FB737CB7A892CEBA5 +:1053E00025B3ABE78B0BD9D5EBCDB25E22CB7A4997 +:1053F000566FEDBF48DCDF7A590BF861BC5F74195A +:10540000F26BBFE831967FC967C8772F34B6F72DA6 +:1054100032B6EF5E646CEFBB8CB57FAAFDAB9782B2 +:105420009F275B39F9DDDF2827E5AECCF5F3178F31 +:1054300022572E15F7936E5121C900AC5F749D124F +:10544000300D272CECBBE7B9FCBFE0607E9CB8A810 +:10545000E2BEF69F7D9E3F9098DF489BEF68F06A22 +:10546000FAF7F7766E6F99EDAF61BFCEC9D3A76734 +:10547000831E21102C4D64854E8DEA1B0FF1842074 +:1054800054C4539EC0F36973FF5D705EC7FC2EC1A8 +:105490007A1D1CCF3B995FE5E7A5ED413CAF9DBA76 +:1054A0002B08FBF4AE0982A59FE594C4CE05CBA2E0 +:1054B0005EB4333A1417EAC3AE09EC1E5397238146 +:1054C000FEE3AE52637B17B71F4E496CBCAE3B6325 +:1054D00004ECFFB6A9BB1A605C67F25F8942E1FE8B +:1054E000EE8418C68FB63BD93EC0195609AC0B2EB8 +:1054F00045C5F377333C712D6E882482F5BA79D790 +:105500003B19DFFC9CCE279B79BD2B49585F0E339E +:10551000FCA5C3D7DE33C4D7B54ED6AF127423BEB5 +:105520008E57135C4F8090F6D9048FC6D9DF20D1F7 +:10553000F387793D060A337E3B8D7945BC2A233FAC +:1055400099FD30CAB6AF65E4E70EBE9E3BC9D7B140 +:105550005FA7120B83BEF35624C832C42F0993B140 +:105560009CEF14F8BF56D546E5977241682B6575D8 +:10557000EF98CE50D2227E6998FE1592515ECE7081 +:105580003D9BE9A4EB9937B59E1D27DDE884EDB678 +:1055900091EBACF0AEAD674AE0AA8CF3EE6A647EA4 +:1055A0002B42EE207D309F57EC481F5B395137501E +:1055B0007A392B443CE7704E4A10A0B3AB9C24DDF3 +:1055C00039E9E7F51AE73B259879DC1E8EEF6E4E38 +:1055D000A774F5BAF9B9E76B1D0FB5C0FE2D6F1EA4 +:1055E000938361BE171306FE1C92985FA3CBAD3464 +:1055F000613C4B29F38F8C983787D32C57F134F7C4 +:105600006934B9FDABA4303DE44AA0DF41932F4596 +:10561000F957D4735D139A5DC0D471E541F4131F3B +:105620002F9708DC8331EB032DD5ECC84B48B70B23 +:10563000EE2BAD7DC51EEAB280D70D44D0F9F5CC76 +:10564000FA7A347D72DFA7D4273FD1E47EA43E41AD +:10565000FA5CDBD1BA1FE8D3E566FEEBFC3A952C89 +:10566000D5CDB79B8FBFC4C9D7856206479743AED8 +:10567000D1D3298F7EAFD1EBCD34F44947F72B211D +:105680001870560A0EF3FC763959BD7C18BF627447 +:105690003C8CA403C3438BD39A0F3EABF9343BB38A +:1056A000E3E36DBCDE368E576D5EA3C989D67F1FDE +:1056B000C757DE3C93DE175503FDED1ADEEA4CF5C5 +:1056C0005CC67A1A7E4427B357B47562B4FEDF967F +:1056D000187F98FB4F2787BF19964315FDB2DA381C +:1056E0004EF21CFA0F8E53BDDC5549F7A3BE418C18 +:1056F0002FA07B7D8C6F82F82FBDDE35EB2F4DFF09 +:10570000A7D347E67DCB68F5A58094D14ED2EC9A1D +:105710007C7E6FD2C5E381370AD6E73C435C8EA816 +:1057200062CF2AAE0FC244001F2442F8FDBF707F33 +:1057300013CD8F0D494A17F83FC4F9FD3B687ECC65 +:10574000CF9CA42B042E9779FDFD94DFD6865D11A6 +:10575000281FE72A1DBEA7D53B1BFC5ACCEE22F61C +:105760003B5E877BC063AF1409E0D549E6609CF6D9 +:10577000F13594769523E1192B12323E9FA6DC3F3A +:1057800080E787B0A5FC8A119F64B12E0F7E6097D9 +:1057900071DDCB76DE6678D2B51B159ED43EF4085B +:1057A0008CEF2499D7B5339DDFB05D9BE5BCB4FB8E +:1057B00068DAF7D2213B51E07EFB9080E939435E05 +:1057C0004C4B86DC984E182A200A255AF1501EA60A +:1057D000E387C6E3F7A2A1424C0B8726621A1C2A74 +:1057E000C5346FE87C4CE5A1A9986EE072983B3413 +:1057F00013F3DAFDB79CA14ACCFB873E8FA96F68F3 +:105800000E2BE7E7A91BEE8C12F0574BB00E51F9A7 +:10581000689BBF1CD725F3BC36B8D83ADCCEEF095D +:10582000B79BF4761F2F7FCCC5E47E03970B22C66F +:1058300088DE6F7E3FAFB7A12C8AF677BBB61E1607 +:105840002E37AC87E6FAED69EE273FA395737848CB +:1058500079FD28F461E7AFCE4014EF0D101245BD7D +:1058600044C4A841EFB66BF067798F70C3FC6790B2 +:105870008FDD549021B4D0FD856D0D0F83DE5970FE +:10588000EB7507A8DC7DE88CDEE68271BFB002997B +:10589000EEFBAB6E0F82DF77C3FC7BF17E1398DFEC +:1058A00010D7DCB1E08ED8C3C87551B4B369BBBBA7 +:1058B0005CBA73D0CEE5B737ECA2FD29AD36A2E8CD +:1058C000F8B5E40E0F51F4FAEB644121B42FBE2574 +:1058D000DFF0BD686591A19D764F22784D99A19E1C +:1058E0003CEF3C43BD9CB9338CEDF839B9AFEA428B +:1058F000433BA74FC32B3B47A4F437AC1F1D823556 +:105900001D632EA62FD3F1CD152EB6AEA5FACF4C22 +:10591000B774FD677B2F24C51F69E781E710B1F8D5 +:10592000E279604F39E528DE5339F3FA67771ED9FB +:10593000D633EBAB1CD05705A04F044C7DA0AF0A6B +:10594000408FB831D5EA9DE97DDB75A06F7C3A7D4B +:10595000338BCABD053FF8DC99F5CDF9BC7CB29B11 +:10596000E99B759CAFCC7C13E4F5D681BEA9185D8C +:10597000DF04DD99F54D251FEF1FAD6F3A67DC1B86 +:10598000FD16CDB92FD8D6F0104D3B2A6FC53CD5AA +:1059900017A29B9677CCBE23F6904E8F9093FFC9AB +:1059A000F892F3436EB5517F68FDFB43263DA2C9D3 +:1059B000C3DF28D7A738BFA6A3CF914F29D7A7CE3B +:1059C000925C9F7275CD83F3C56CE57A64FDB33B41 +:1059D0008F6CEBA9B5247909EC4BA678122DE0BFAA +:1059E000B4F586D8BDBC28C6ED743EEFE07E1EE659 +:1059F000FF9BE10A2F02FE99E18A2C76D3F63797B6 +:105A00002AE3609DA6F92FC2775D3E62CAD79BEA62 +:105A10007FC594BFC254BF415F1E57947170BE18BA +:105A20003FE4C0F3C1B862ABB3E2A7856EC62F876F +:105A30005C9128F4776EE2BC7140179A5F86FDB9DD +:105A4000597F347F8D29BF1CC74FE5AF3395AF30E9 +:105A500095AF34E557E9EB779E9A781FBEBFF14BBF +:105A600007D969E14F7A95EB898EC9B7479B995C55 +:105A7000DE06ED3BA6DC115B46902F08C06DF79962 +:105A8000F67F94CFF4FC7288F7F3F309B7E2BEA96E +:105A900083EE9F308E11FC7816F8F9B59BBFC3A535 +:105AA0005C8FF71FE28537A39FA3A3B819E3148E79 +:105AB0002B129ECFC64BADDB7736323F5347B1F545 +:105AC00039C2AF210857678F9049CCFF076270DA5F +:105AD00006EF0931FDDE56DA8EFA554A5ECFFC1B21 +:105AE0008551F46F3CC8E927F962E8577016C72C56 +:105AF000F7F51DC3F830FA35F769F8E0FB481D3EAD +:105B0000500E9B3B3F3C00EB6BDC6D2D673F7633CB +:105B1000397304B31B7FE4FCD9FAB01D2EB558ECE1 +:105B20006BE30E1627AF4E607E00918EA3F72B9885 +:105B3000C71B9EA7699FFD00C753DCCDE2ECB5FEF5 +:105B4000CCF03CC2EB3DE2667E056D5EA2CCC61990 +:105B5000ADFFE7E0B216F80164B31FC2A8E7EEE0BC +:105B6000F51D0163BD74F8B973183F2C1E4BE3DFBC +:105B7000D1F85D1BE710C085FB59EB7DB872B21AF6 +:105B8000E3378E137F6F17EC9B45F97588E3B88D6B +:105B90006E93C0CFDF22AAE85F501522EFC4F34F07 +:105BA00076FE709BFDBC10E83B178FAB20105711A1 +:105BB000D0C525829FF35C8CB37804CAD7A84E1950 +:105BC000DE3719724F6471AB27D7603C4527DDA9DA +:105BD000C3B827DC250978CFCA9EDB8DF6BCDD5E15 +:105BE00019B38A33153D8C6F2F39B91EF56CBBC2C2 +:105BF000EEDDB48B51577E05B8AA5594D74E257368 +:105C0000FCA2390ED2219BE30F8DF89AE661F48D48 +:105C1000F3F537EE0E35E8E393821E37960FB98D14 +:105C2000F075007C3E802B86F1A4F1629B0DF0762E +:105C3000B6E0D3C6954A6D11C04B8044315EC515A0 +:105C400014715C9B97E137DDB844113FD0BF1F73DF +:105C5000B6F039BCFE46193F89C483FCA4CC73D589 +:105C6000EE86FCF3CC2F6F1EE788277A8147E71773 +:105C700016E528FAB7B4FE168E6171DE6231C1FBFB +:105C80008A1289D495D2F9B714B3771645DF2871F3 +:105C900011C5667F45BA7339763E824554446BFE22 +:105CA000C0C6F5F078013F19C060D15C50E91321FE +:105CB0005E4011D83B102181C595CFC538F280FBDD +:105CC000B3EE7709F62B843790D3DE33E8571C40C8 +:105CD0003FD767DEEF28F0BAC936EC1742534F17AB +:105CE000A4FA05FD8B4EA593A74FC3B9999D687F74 +:105CF000CC0E176DEC5E1529CAC1B8C3B6C0CD2E47 +:105D00003D5D9B3C6586F55592DB6F1272E0DEE7E8 +:105D1000CAF04006BE6C0339023F62F135E181F200 +:105D2000F4F53438453A7D2B7F68BB144D3481BD82 +:105D300058E263F1AA620CCF473A84FC195D553AE8 +:105D4000FE2D96920097BF2AAC423C6347812D04FA +:105D5000715822E93E8CEF3BD9178732C9AB582CDA +:105D6000BEAF9FCF568F310EA465147E6FE3FA3A13 +:105D70005DB9430A45ADF4F0131EBE8E79ACCB3F3E +:105D8000F6D63EE6B15877F6723DD5914755E9E72C +:105D900018FB001F88C5075F073CB48D5990593F19 +:105DA000C946FDF45FDEF04F609C0C703C67050750 +:105DB00081C714B2B0FBE579188C988A070A30BE07 +:105DC000863820612C9CD2B2BF75550F26C1EE7665 +:105DD0002CF585817EF6F06E02EBA81617640F7B1A +:105DE000DEB1213DE7B2F8A072E6670DD3FF308E39 +:105DF0006C6EE6B831BB29FF2B339D1B9FC5F72284 +:105E000034F8B53875F3BC9EF2D6BEED9965858F32 +:105E1000ECF6419B28BF10CA2F1BE9FA4E91427A3B +:105E20001B65CCF7340631DFDDA860DADA588EE97D +:105E30005A683A07E23F62F152D88F041F0E5E4B58 +:105E4000AB6C029A605CCB8EF9B08FEC1ACE135516 +:105E5000807325B81F4FEDD0BF7A36CEE7E76C3C94 +:105E60006EB67D3E9EA30DE7B7B4815DD8C5E368ED +:105E7000E5B50FCE87FDE3A609DA3E39ECFAAACEE6 +:105E8000FE9AEC75B073A652AD7D4B1BF4E7167904 +:105E90009EEC996FCC9330C0E376B1FC42EFD3080F +:105EA0000FAA003ADEE5DE6730BF6932F73B54D413 +:105EB0008F8247E6C768F728CC0EAAC8473F8514EB +:105EC0000AC1F502B2298FC39D653FB0FFC1F5EE4F +:105ED00015EBF5322537A3AC6B1C8ED1E84FD18181 +:105EE000F605E86115C67DD58EF270B6C7DDE438DB +:105EF00033BC48D5832A5CFDDAE7895EE4A5EDFD75 +:105F0000E1BE6429CDE72C4EAA28BE598E5BE8E598 +:105F1000F7C9E87C41FE353C6B76C74D40C731A9D7 +:105F2000FE1C8130BE23E1E6EF09670BEF728F6C38 +:105F3000E8873C5E5B98E9DC654CC4064146C3FAE1 +:105F4000A2A0CEC38335583E2F9C6FC8E7561719C1 +:105F5000EAFB43658672877C9EA1FC6FA5D3D73D83 +:105F6000B281AF23A679CD379567DBAF7B8D5D819D +:105F7000F7204B45CD1EDD88F7928F038E413FF60B +:105F800056E23D5D3249BB8740C210AFE256C2C8FF +:105F90009F1E12C2755A2A36DAA962C068A7061B6C +:105FA000D4A4D62FC425B8D74838EEF03AE563F12B +:105FB00020DA3919EED72782AAFBDEA152D6CE32DB +:105FC0009E414B457E5E8677EF4B473F4F358F13A3 +:105FD000FC4AE63835737DE21395A33AF94BDF4E60 +:105FE000244775EF6AEC00DACF4AE13FBC7B29FA1F +:105FF0003D9C84DAD114CF2DC12B4894CEB31DAA79 +:1060000050FAC521A57CDE1E9C21631CBEC2E86A35 +:10601000733139F98E5731C473D87D4C4EB47AA39D +:10602000D1FF363B8959AD67AF7AD93EF9C45DB12E +:106030003FC1FE527D99E03BAE7D8D43F8CE655564 +:1060400072A11DFC26AF7BC7E27CAA0E84ED97EA05 +:10605000FAA922ECBD6FFA67D7FB5335FF3039E957 +:10606000C2B8E03D491617BC27F9DFFB4F43FE904D +:106070000DDF15DD7338B37DD5C7ED2BAD5EDF21A8 +:10608000B65FED1389373F939DC3EFBF55264D7122 +:106090008722B103FD4FDCA9D8C1DEE96B7409B0DA +:1060A000EECFE0F3AC4A86EDB09E8E36AF7D26FA99 +:1060B0006AF384FB8730CF561FBB0FD82AD3F9224F +:1060C0005FB3F7B2D3C13BBCEF97ADF121F9D9BBB8 +:1060D0001792232A5BCD7BB47B8A1A7CED009F004C +:1060E0002983AB3DC0E8D01ECC4C87160E9F56AF1F +:1060F00035C0E8D04AED836CE0117D4678A88D2745 +:10610000805DE823893A7CD34C252FC33E08558512 +:106110000278D897BC1FE0857B1760CFE75509D779 +:10612000C2BD8F28B30FFD55C9E4DE009A2711B810 +:10613000975130D09F7C9B961F6CF0E2634FF2B575 +:106140004792D08F280FA2FC74C160681F4D6C0766 +:106150007BA70DFE4955FAB8EEE002B03F44C2F409 +:10616000029538451CCBED130B79D79DEF0BA79DFE +:10617000A976E9F066B63B9DA43EB3BEE2E7FD2AF0 +:10618000FD0FF48D6CBA1F61B673CD71F017813EAF +:106190001F93C53D8C4F394E2E79D005EF21D8CBBA +:1061A0006D32BCC34C557A1EDCFFF1864502718D01 +:1061B000B9BE017C3A6B34BC53FD57C7E246FB883D +:1061C000FE1E69BD8FF98102F55582C0EE1128F0DF +:1061D000EE66A0FE50C88A4F35FE1CCEFB9E44FDE5 +:1061E000D8461271883B51EB6CB8AE759597E5E9CE +:1061F000F74737F904BE0FD5E84F1471768AFE745D +:106200007E61F7F4BF1FFDF3171BF17EA674B9D3AF +:10621000C7F4D268F4FFB4E368741B291F4D9C6E69 +:106220009B50FF754ECA4EAFA4E8F620CAABB79C90 +:10623000841316ED9A39BDCCF7F65D2446E0F728B5 +:10624000ECAF307BDA3E6E76C30E92812E23E2AC49 +:10625000583F761FF3A7AD133C21186A5D1AFFF271 +:1062600024BFC0F5FF008BE79B733008E7C7DDB3A1 +:106270008E06E19CA3E713EB73C8857E7E2E127E0B +:1062800003F7013DB3985F10FE40EFDCC6FE49CA3C +:10629000D4F736C33B66EBDEF21AECA1F6C6CCFEB1 +:1062A00006A9E8BA28D81927DE1114586F84A23538 +:1062B000E7025CFD7396E3BB23ED55FBF01CA63BA8 +:1062C00094992E5A9C6FBB29DE36DDB9E1092EAFB9 +:1062D00065EA0D685FF614BE8CE3ACABCA3C0EBC3D +:1062E0009795299ED7652351F4179BCE75DFE4E37C +:1062F000BDE9E3E7138EC8972696C2EF72A8E81FA0 +:106300001B5B1EE9B751BCD5FBA3AFF9285D7BE64B +:10631000DC5A0870C03B317ABA07A07F0BF8C6FA86 +:106320006D06BBE94459ECBFEEAC82DFA79882EF63 +:10633000D66BF5BAD3C4B19FA7D15971E3BEA71DDF +:10634000E2FE297CDD85D9E15FA3F325E405D7448E +:10635000680F71BE19F8D9BCDE8F8677331E7A1CA0 +:10636000031807D52358CF67A19FC95DCF9D4976F4 +:10637000AE36E7289EABF9926F60FCC477671DC606 +:1063800073B5123FA387DF378071A539D5EC3DC0C7 +:106390007472F400A79F281BEB1171C070EEB3DD7F +:1063A000C7CFCB0299FBD3E024AE0176DE33522E69 +:1063B00071FDD9D9FDF0417C378524F15CA1FD55F3 +:1063C0003BDC4D1DC6C308B98AB3DF85E9818DC7A3 +:1063D0008530CE5DEDE027E9D1CED92AD9BE49ACD2 +:1063E0004AE2399BCBAF18E3AF43DABB88D9CDD3B0 +:1063F000076B11F30F8BB0AE823F1EE06BADBC029A +:10640000FD69E9E8FA1D6F74A67F8CDEAFCFF65DFB +:10641000FF6C7C78C2A718EC43333F3AC937CE688B +:106420005F97CEBF7C82CB67002AEAF649DFF44B48 +:10643000D6F87DFBCAD1F0FB4D6BFC5EE501784FD1 +:10644000DC63FDFB445ABAC5A4EFB668F128F0231B +:106450002185D85FE9E516F3D6D6D5137EEDFD9EEE +:10646000A807D68D3275AE07C6DFD5BDCC03E3EEE7 +:10647000DA9C999EDAF8DBF9F96282DF77D1CA13E8 +:106480009C2F7798F4FC2B5CAEEFE7F2B5CB15F1BF +:10649000E0EF55ECBF6AD1548ABF32CA17E05254BC +:1064A0003A497EA6F14B55D3BEE40CEFB5F4F84D56 +:1064B000F1BD59DED3FCB478D901FC7321E0E1DFF2 +:1064C00051EEEDC95C94A7B2958C6FCAAE194CC25F +:1064D000BE76E2265B42C1389628E2A570A5A86088 +:1064E0004C1BBFF77A2E5FDF89FD0E5B0994C3BD9D +:1064F0007119DC2EF2D7301E669BF1F73F76B9C2D8 +:10650000CD12D8BF718C742465DDC6DFCB184F74F3 +:10651000BF5741C72D7CEB3DFCFD9442D3EF827CFD +:106520005ABCEFFD07E13D21128F5E1F2B028958F7 +:10653000E9FDFFE47CA9341D60EF18C47CE45DDD57 +:106540003907A55F3ED805DBD58D35804F354E42E6 +:10655000932DF4D86FFD5EED777C0EC03B0B8E6201 +:1065600076FFAC6DE915037BA9CADA7E472DB13AF7 +:106570005FA17AE1B77E5C9F985E48A8F52C3D69E3 +:10658000473E99DC4D12F03B28F336C5FA1D20EA50 +:106590002BD93BD48571559068BE8C9AAFB47B32B1 +:1065A000F13AC2EA2F218930F211792D3836F57B84 +:1065B00027250337F5C3BEF820DD17C3EFA868BF52 +:1065C00057A2F1CBF898913F26C78DF971267E31FD +:1065D000B72F53C822187F52B78DC0BE6E4C83AE02 +:1065E0003EF44706DF7B848E3FF9003CCC48D3DE87 +:1065F000CCFD8B24EAC8A1F87CFA2EDF2FCBE9046E +:106600001FEAAE2D00BCEC721176EF22E2C27717C2 +:1066100048C4FA3C6904DF6A767F9AFA297DC9EAA0 +:1066200069EB5EC75B027BE7A2447EA714FC9CAFCC +:10663000B1DFAD4BBD5B7121BE5B112431663F9272 +:1066400008A6AD9C3FE54B8B4BC11F1A7FDB2BC3CC +:10665000FD2CB9C0E84F13F3EBF03DB061BB3B9F9D +:10666000DADDB43C9E67D4A33539CC6E0DE5B07B42 +:10667000A1B297F5435C6AA15EEF6FCA118CE53E4B +:10668000B5F0CBBAF25ADE3ECEDF2DBF24675107FC +:10669000D833F2785ADF823FE7F171B57212081DE4 +:1066A00086F73F367FA37E967E3DDF94C3CE77E4A8 +:1066B00073F8B8C5D670C54BD9B877F37137E518FC +:1066C000DF8D23324BB5EFF7FA6F158E507C9F703C +:1066D000905A88576919634BC0BB69B78DD5E2C220 +:1066E00032EB098D0EC3F896593C52D175F20CBBB2 +:1066F000851C6BE9D63AE6A7327FBF9ACFA3F5BADD +:10670000DADE4914AEF0012677CE00B13C07A2F2E2 +:106710007D75CE2C8B75BFB50EF77127F232AFFBAE +:10672000E67DAEC8FD8BE67A4D9C4ECA2B417C8A35 +:10673000BB35C8FC895AFF270A995FD1DCAED3D498 +:10674000BF9BD48721CE18CE57E15C559A4412499D +:10675000DA8F27D02B972A101F705885FD91422879 +:106760001EC1CF162268D7B506D97E540CF6D6D8EE +:10677000209E84D4C97A3BAC88FFAEA29677F8A25B +:106780004D39680F8505C48BC8CEF34F38120B0105 +:106790009F2DA53662F54E7F770EB373B72AF52F7E +:1067A000965AD06F438E62B09F8B8698FD9DAE7EC9 +:1067B000AA1E836F981F832ADE3F200AE3C77A7FD1 +:1067C000F89E1CABF35B4DAF703FE4B26AAE7089CC +:1067D00072E5AFE93CAE3FE4C0D8F44B4E6E3F08E3 +:1067E000FAD74EF56F17FE8E5CEF41F0435E03F76C +:1067F0009F68FEFAB7A64925B4FCB5223B7F743EDC +:106800009203E37E486CE82FF990BC9C335347BF5A +:10681000A77224B6DEC41DA847357FDCB5BD0E8344 +:106820005EFDF666637E39A91F0B7E8AE59B1C24FC +:1068300041F17BBD49EF3E94C3CE89BE4D62EDB0C0 +:106840007EB6F1F3BF1B7F324D02B9B97EA65C6AFA +:10685000D7DDBB7A2E87D977EF533E527472B6C21A +:106860009790601FF7EE9E99577C9E403F89F622D5 +:10687000F0A7E559C7017E2B6E8473B47998E1D6F1 +:10688000CEF3D2C121EE162CFD42CFE708067F7C65 +:106890008B8BBD87146E1189FB6288C3A3020B70BA +:1068A000BFE5C7F7BBD5DA18C6D5A9CD4EB9258047 +:1068B0007176184FB786120CDE1F3ACAF94F8BABB0 +:1068C000A306C505B04FBBD13520815F79B518ABA4 +:1068D000839F4ED3CE659C8E68783C85DFF16C4DEE +:1068E000723C31D48B6759EF90509655BD3A5B8618 +:1068F000FE8E713DF98BC71F9260FDF9F0B177BE36 +:10690000087278C373760257F38E3DEE2749DC3F59 +:10691000242490F3157BEC96EF48508C61FF37FCF4 +:10692000C88F7A71C593CEC462DA7EC533EF4E2725 +:10693000549E8E350F1E1C0FF87B4C60E785EAC015 +:1069400074589F5688E49B56EF8EB97399BC7FF0BC +:10695000536F03D04FD8DD7F35F6DB77A543FF2E8D +:106960003EC965EB0FADC7E2261F1512932DF487C4 +:10697000B61FFAE0511657B2E2594702428257EC6D +:10698000DE2145291CAB777F84FC72E98F9EC8010C +:106990003CAC7ED66EB0236EF8D127ED17523ADFAD +:1069A0006027838B418EED27317F3CEC1AB4A35CCA +:1069B000B3F89455A80268BDA77EBFE0D7B4FCFD2C +:1069C000A09D4088EBFB877F273D07F9A88F5A6E73 +:1069D000D0BF91AF57EF7E57C2DF31B291C1E2CF46 +:1069E000C3F987D14E32D7276450023DB5BAAFF311 +:1069F000233BE5B7D57B3E7C13F86EB5493EDE8779 +:106A00007F148EB4CF2B734DF6F9EE82ACECA31B42 +:106A10009E38FE00F8233E78F28F0FC03DDA95A72E +:106A20003E7EE07B1017F66F6E19E47BF563AFE6F0 +:106A3000109DFEBF2C97AD9BC71E7D64D7563AFFB5 +:106A4000636F38115BC7F6FEBE04FC3FC77EFCD700 +:106A5000B1E00FBA65EF7CFCDD9A5B9EBE745CA66C +:106A60007511F835A1FF7D457E6EA43C2B80314920 +:106A7000C8CF786AA207E91D94605DFB8B4006BB16 +:106A8000F2E8F7BE4F24B0CF0E86C920E067FF9E24 +:106A9000770FDE4EF31F52FA382DE843E73FDE86CC +:106AA000FA998A0D4D57EDF9F2972EAA82D4817684 +:106AB000F86A32887A73045D5FA174AD4AD1D55CFF +:106AC0007E9C9C94E0DC60F5E3948ED3819E948E52 +:106AD000D347D2F143F8C79C91745C916B8C4B3ACD +:106AE0004E566EDF0A857B0A2CCF79B57DD68D4F49 +:106AF0007F35A3FDA4E985D1F07C9DC0E09A9D1B64 +:106B0000BE3D17E4EBC91FECDA1A60745E4C1173DA +:106B1000EC89E32584F2C91F1C8357031E06F73A4C +:106B20006558DF57ECFD15CADBB1A75F92148C6F77 +:106B30002139C26C9A27C37F2F139A5F25B0CC8D61 +:106B40000FFFBF056FD2F637C2431E32D20FF307D5 +:106B5000A9FC213D1297D729A077136370DEAB12F1 +:106B60004C2E5625FABF02717D66BC3F956BD3F45F +:106B7000FF305D216E6CD59E771600FFA5A3A7366A +:106B80007F19E67F012D7FD828B769E594D3F7D820 +:106B90008E1312D807C9E724D946EDE1638E410967 +:106BA000D7C71FDBE59DA191744FE19FC71F9DE1F2 +:106BB0003EFC876639E7F8194DCE479FD799E16DBE +:106BC0005BAEC2F65726FC7D70D25AFF3FCFF5C6AA +:106BD0002A12AB2B9A3872FD1249441D5F9A82F734 +:106BE00003881FA3F07EF0981DF787ED7DFB518F82 +:106BF0009BF5C5AA3476F49BB9CC1E58F56CFF748E +:106C0000D06B1FECFB29F2E5AAC7DF91C07F737040 +:106C1000F753D240454A0E607DD0FF0ECE073FECC1 +:106C20009F0EFA6B759A38C0DFF3F9ACFE99B1FF8D +:106C3000D58F7F64E8FF06B54F423FD928E3BC2FCC +:106C400086AF84F9BE7FD8012718E4FD3E7B9D9571 +:106C50009DF3025F1F353CB5FB67BF9E0BE75EF9F6 +:106C6000EC1DC6D6A6F0AFF0F77B5F72F0FD6DF8B5 +:106C700075B0675AF224BC8FD0EABF02FDF55A7F87 +:106C8000BD267CCA01B906F603F2BC48957E5FA515 +:106C9000C19F17B619E0BFC55F374EF1B1FD9942EC +:106CA000F71FFF03B64D466E008000000000000095 +:106CB0001F8B080000000000000BD57C0B7C54D516 +:106CC000B5F73A73CE3CC24C2627AFC9D37892F0C1 +:106CD00094804312DEB40E0491226A505AA9F5AB97 +:106CE00003F28821C9A4F8E25ABFCB8444F4029F7E +:106CF0008D95166A693B70A152217690A0B10DDC8A +:106D0000012C06056F105F78B18D5A152B24631482 +:106D1000B4575BEF5A6B9FC3CC9C4C84DEFBFBBE2D +:106D2000DFEF0BBF76BBCFD9679FB5D7FAAFD7DE02 +:106D3000EB0C28DEDCEA5400D93D6B366461AB5ABB +:106D4000D41409E02BFABB2AD6028400C603585D8E +:106D5000D5E07761AB5A407300FF7D45FFA7785BB4 +:106D60007BF0F97BE5D4D6B5348FB5F157D48726BF +:106D700005B657F2B0914A25DDBFC2BBB61860A375 +:106D8000F39F1FA7FB2B8376D58E6D73EA3DBFA5BE +:106D9000FE0609AA65EAD3F3383E6875A8DB55BC40 +:106DA0009E0E0BC265317AF25424321BA00CE9A06E +:106DB00016FFFC3001DF2B488266A8031C0129590D +:106DC000A120B5C6730FAAFE62757CAC2FBBBAC1F9 +:106DD0008FF35E2DBB2CB4FE07732D217B31B537AD +:106DE000A641D9403E18ED03ABAA213262F0FBADBB +:106DF000D98E855B80E90E5A681D9223B49D08F1F7 +:106E000081A67A8069030DFF873C74C4D18D037C11 +:106E1000B40E45BF6FC565D14D3B04B94D213960F6 +:106E2000EB84084029D2AD96B05C52A1479F240A5A +:106E3000D563006E4CF57F93D6993BB451A2EB1EFF +:106E4000A8E6B612FC12DDB738EBF2FC5FB33E5891 +:106E5000A09CE919A9CB175FB1C12AF8AF28A00CF3 +:106E600029273A36ABEF8FC679E87E268D0AB21C09 +:106E7000C6557D67740BC181888FE3F32333676444 +:106E8000126E8C71CD8EA29312F2DB27A7A8294532 +:106E9000D8579033C4A753A9CCA71F4DC399F1FE6F +:106EA0008F4FA56E95511E8F48024F41C213E10AC4 +:106EB0001A1F277CB8113F6BE9B9198DBF65BC5803 +:106EC000A0BAB952E7A487F827FE106F8CA7958A5D +:106ED00043B57B89B73E4DA1796C105A2B11BD7E0D +:106EE000E6A7035AB91D02616E5DD0CDED5DC4E722 +:106EF0006C928397FB69D0D33A149F9BA356D7AA71 +:106F000078FDC7B333245A9F0B549DBF8579D41F96 +:106F100094BF3391BF8E187FEDC44FE7407E3A4057 +:106F2000653EA47BC1BB761CCF0B115CC723D3216C +:106F30002433885450112F39FA3A33C127117D84F4 +:106F40001F5A5FF602B13EF3FB72A195C7E5439865 +:106F5000DB42E8E636C3A14A0AD3734A97EF3BF017 +:106F60009533468FD1DA09C138FFB9429CBF98B931 +:106F7000ED963CB47EE3AF9A71F887CA83BE2A1CB3 +:106F8000A7F85D3E3B2EE5FF54CE201082F572053A +:106F900048AEAE9E8573C18DC3BD36888CA4D9839F +:106FA0004C5FCA48D137EC8B1D051531E8C7E7ACFB +:106FB000A73E3C45CF59216E1CD121DF9A467C7FEC +:106FC000982E4C1EC8F795A79AB29E8B9B77AB9ACA +:106FD0009A45EB848930F12B39F63C4CCA40233377 +:106FE000F0F9CF5605B39EB3C6F8D0E2F867C6A550 +:106FF0000F019CF24DEC138EB36238465CB29D0BD0 +:10700000AEB6ABCD598C43C6E94A64901DDBCF5276 +:107010008A42BC7E689C7823DA618BC3274978BD9D +:107020004E7587883FF5AEF02CB61326BB317DBE7A +:107030001AC9C7717D8DE025BE6EDC73C369E26B32 +:107040009F07347BBAC0856F02D909C38E8026A3FF +:107050007CD748E31C12B6F5ED1FBFF47B1C9FD212 +:1070600029838CF7FB70CDDDB46EC5974E4274C298 +:10707000FA04FD6E7608FD31D669D6D77F749D2857 +:10708000799E9FE52093FD5DFF2FF47C3FA4B6D24F +:10709000F84D0ABE9AE6EFB286B6231F561C911928 +:1070A0006F2BDAA410909C152D8DFAF7BE2883C0A3 +:1070B0001FF0FD7B7F55CA789461F48FA6E1F381C0 +:1070C000CD562F5A4C48F725FAABCCD943408BC349 +:1070D00001047D2FE722BF16EBFCDAE87C780BD1A8 +:1070E000B3A949F8A7ECEA8C84F19FA55C6F5B8A91 +:1070F000F36B7948D714C24DE7F035D85F5E20AB0B +:10710000329A889C05F989FEB1D5FA0EE99F86FF6F +:1071100008DF86FD5A4AF68BEC907C3FFBBF73205C +:10712000FC9F02C2FF35A0BD8AE07CCB3689E78D8B +:10713000F96A3A1F595380ED1DA1C4EBCB4189F583 +:10714000D9CFBA47921D580943BC766920FE2DE974 +:10715000887F02890B5C420E2E2FD997FE5764AFB1 +:107160005DB082F595F84E7644EE19B1711ACE17DE +:10717000E8B24248237989FBFD9BE550B038A61F51 +:10718000FD5D7B981FCBF2901F884F7B6E22FF53D3 +:10719000B444FE3B47667CAD3C52BD267ECA739923 +:1071A000FFC86FA0F9D32695243EAFF37B24FE13CE +:1071B000FCF6319D4B3B24784C223EAF3F5CA00D4A +:1071C000E46B43C72336D2FF8BF1D5CCC7D1E9BAE4 +:1071D0001DD1F9780E3A0FE8A8AC7678D894F03A39 +:1071E00014B5753AE1B410F5967062D66B837FD60C +:1071F0002CD567C37197D1385C5FBE232C94D10B1B +:10720000CA09C2CB2261779B551FFB23C3DE3A2FED +:10721000D8ED77E12B6CB3E6553E4438BA534A6D4E +:10722000952B07EAEDBA31F7B0FD2A5C8DF698FD93 +:107230006A629C165EE5F02E467A9E5C05DEC5C34A +:10724000009E5AA5726B8EDF0C7DDF8CF19B5DF882 +:10725000679E5741FCAE55C9FE7855A2F3611BB03D +:107260009EF69541682BBE3F1CF9D4A391BD2E8F8D +:107270005E5F8DF145600954539CF1AF1922AE7BDE +:10728000466F6765D8B85D5B6D011FBEA7B7530E2B +:1072900049485FAFEA3B7215D99D4EABC6F1951ACE +:1072A0007DE97B7CBF425D8BFCCCB3B48EA3F7E25F +:1072B000F8D9219CB7AFF35DF7ED717EB9B7E3D193 +:1072C000511407FDCC0235E124F1D0F2740BC73123 +:1072D000BD23DFF1E0B2A1DE11B501E2E9C19EC636 +:1072E0006A8AA7EE746A4C97AD7D7AA480F1338FD9 +:1072F000E3E3E7960E61BCED3D0321D2BB59F2AD4D +:10730000D78EC1FEE45715AF9D95CA77FDC2093CE3 +:1073100084E5BEE1CB8A4DC4BF00F273355F6C3D9E +:1073200041F27AF6CF0A90DE55363EFDAE1FD77990 +:107330003817D1300960822F5C11C151333BD3A77C +:10734000937E074E01EBEBF86E2501B720D71D2A7F +:1073500020BBF286080F27BE61BA0F4199E2FFC930 +:107360003D89D7A75E04EFFF62D80D377808EF8F0D +:10737000ADEA8077C92FEAFE331F17988C9F06BEAF +:10738000F738673C922EE2769970EB55928F7F2703 +:1073900043C4F91BBE9425C2655F14BCAB915F7DED +:1073A0008BF379DD7D9F524086ED97F2EC709278F9 +:1073B000EBD7E93696DFCF6C02F73F5BEA0A35E19F +:1073C0007A0E2EADBDBC07DF77FE9FFC97AB5F1733 +:1073D00007A369B14C6279A511DFEF9CD722B11EDA +:1073E000426B1EF1CD3CDED013436F0C7DC95B3A7E +:1073F000C41F4AF29EE1B43EA46FC6D291928D7032 +:10740000BB5F029263EF6AA4EB6BE2C720AC2E2055 +:107410007A021D9FD8C85F3B3A255F28C9F8C3E9A7 +:107420006EE65FEFEA60D354E4D73D8BF059D20BA0 +:107430005B6B71B2F983B0A1008343684BD704EE54 +:107440001D701BE92528AD79E4B77B3BAABE4576C4 +:10745000FD31D4438A1B7E66F532DDC17A80EDC4EE +:10746000160A3CB15F783D6C591B974776A74F3F92 +:10747000958EF39D4A5779DE4CBF5722BABD7FFBEC +:10748000CC4DF3F77D6E67F9E5930EC7C56D9FA6EA +:107490000BFEACC9F0BDC678A9C96263EAF5BBBDF5 +:1074A0008B2B00AEEC407EC7E13226B720AF3BC34A +:1074B0001F647A32BA3171E2FCCBA751BC1CD08D6B +:1074C0003344245026C4EC73A5A3305220F28770B5 +:1074D0000EF237A3E6C76CAF53D00E53280EDD89EA +:1074E00079115B647C9E749FEC42B32AE2AC967483 +:1074F00061E75A1E5142CDF8DECD4A4FCA306C8B3F +:107500007DDA0C45237B5FC6F3E6DE05ACDF16476C +:1075100048223BE42CFD45FA85B86B2AC0EEBFC972 +:10752000CC7FB39C46EB7AB126C3FF05F1756C574F +:10753000F420856FDE14C824B9CE925DBCEEC96715 +:1075400085FD31DB1B39F2AB9F91BDE9D3F3A72455 +:10755000F6E676F2AF86BD01B9EC10E167EA8B7A08 +:107560009AA9DB19CC3E980F138FFA9B5D49ECCB9F +:1075700024A84E43165FD4BE98E588C1FE857E21BF +:1075800032A3A20BF528EE79B33D2AC8D0FDAF6E29 +:107590008FCEC1B49CABB5185ECA577A0FD9E3F051 +:1075A00061D8A1185E428C33F37B24705CE8ABA5F4 +:1075B000643F8ECA696477A6A3DC71FE2E5D4FD24C +:1075C0003F0D7D8BE4BFA1F39A14C2F5535D550EB8 +:1075D000529B15B9B2F6678C9F9503F383A0C385C0 +:1075E000EC9DF15E2B3834D748E28785F920ABD883 +:1075F0008F7B7F7FAB349BEC220A2D6DFE98C1ED13 +:10760000C18A5C1BBFE7A9AE9234C2910B30BF4563 +:10761000F955764A1C2798716DC67133BEC0C27980 +:107620006335C713B214D6F71D12F3D2E2E064F645 +:107630005377611E4E716B7F17FA2D6C9F423F4F3F +:10764000714AB36B16AFDB58AF41DF5DA93372A04F +:107650006CE0FA8D36F0B90CA1CCB8BE12B5118E23 +:10766000039FDB12AE1BFC1C8C0F063FA7103FA52F +:10767000FF3E3FA76608B99AF9FA3F5D7FE18A4964 +:10768000906C5FE0FF97F54F05FFEF7B44BEF55A26 +:10769000AE27664F0A57CC9697211F26503CEE8D99 +:1076A000D90707FE237C8DED68657B3309ED0DC599 +:1076B00099057561B62F137345BE64B61B5776C224 +:1076C0004D641F2747302EBD04FBF129FD471EEFF7 +:1076D000E3FC3203E91EF7FC82E5BBF0D2580D3221 +:1076E000E7E27BC6762B5EF27BD09D99745FC0EC9F +:1076F000378CB8D48847CDE38C78D4F0270D3A1F67 +:10770000FE3DC3FF64065D57D520E91BEA55F831FD +:107710002FC35EA378A13BBD7A37DF1F190E721EFF +:1077200050022AEDEBA0BE721C56E97045E4B1038D +:10773000F5D369D2C330F285F609822E4B689834AE +:10774000900E0CB78314F7E103FCFEA5BABF28C462 +:10775000312CB406E0F8BF702CF8C9EF1696638B95 +:10776000EB3CA6C7232F995AA4FB79E2AB5581A025 +:10777000BDFC1FA797482C2827FEF8FE40EB77CCCE +:10778000F631FD052A78298E2F50C29217DF9F51BE +:10779000A7491736910C3F8DF315CCD5D85F160C41 +:1077A000C53E8DA77827895C7A32ACBCCE7A47CFAC +:1077B000611BF22130B771B6DB128BD3ED56BFAF30 +:1077C00080F68F3A44BC0EB4DF379EED9244EB5105 +:1077D0006608FE0454915FB94065BB59A9CBB1D28C +:1077E0003197F777C827DA270F5CB7A4F97870FECE +:1077F0007CD082936376D5C87F701AA0F798ED6A23 +:10780000DFBED72F0BA23EBEF5BF3F4905BCFF2709 +:10781000259A4AFC387DFF89541FF2E3ADFB45FEF3 +:10782000F27D537CA4640AB92ECEACFE82F87ADBDA +:10783000AABF4D88B72FB0329BF5E28E904CC9F0AD +:1078400005FD59BEC3C97BCF46BF3E9C99D037F4D6 +:10785000A0DE0E8DC9E2EA6999222FBA63D7161B02 +:10786000E5D18B33FDA999D83FADC77FA7DB53790D +:107870003FC0A067D1AE7136E2F79F3AED106103C9 +:10788000D96D1572F65D2F4DA0CD7BF167A6F3F093 +:10789000FE021BED9F2F91202AF6B5E0F0CFB1FF3D +:1078A0005EAE0C6BBD03D7B1E42DD56641F92C99C2 +:1078B0000ED120EAD5A2BBA435F7E2F8457E1745E4 +:1078C0007003D6B9309898E72FD3E395DB1FB29AAF +:1078D000F2A4C6C3B45FB618E7A17C76496BE2FD9B +:1078E000FEAE3B0FFF9CFC40878DFDC0B28BE44F8A +:1078F000E332F57865024CFCAA94E295B21F9569D3 +:1079000083DB25235E39BD0A083CF097550E6ECF08 +:10791000AC52B9FD42B7D7CB3B0E1C665C2BDD13D6 +:10792000C8CF3ED5F5AEF3162DE637BEB9E5934385 +:107930003FC77E05ADB398EC65C44A78BC4AF71BD7 +:10794000CBF438A4E273B3DF38F087DF539E8DEBBE +:10795000DFCE19D7A5C523B782F2693C1F0C3F6261 +:10796000E6477F57A99370323F33713FF67FCA973E +:10797000C19EAB9711D749EC87A14F5F64087C2F5C +:10798000DE366F4D3EBEBF79DF07453DC22EBD06D8 +:107990009E185ED1D033DE960144D7223EFD9DFF76 +:1079A0007498F87498F03689FA97F1FDDC2AC42FA0 +:1079B000EAEDB2CE0FDF84B1AC5FB9965C6A23B951 +:1079C000945F9A7168C69F196FBDD69E22B20F66EA +:1079D0009CF54A89E76446BB34539C5F2CD67CB344 +:1079E00028DF45B7B646E5F508FB775A693DFC4305 +:1079F000D2DB6D12E787F5CFB43D4DF6A8F6B73F61 +:107A000071933DFA5069F5D0FBEAB63FE0F6915D1F +:107A100052826E7AFEC390B04BE6F775EA7C34CEA4 +:107A2000052EF8A587A26BEE437E9C477D26FD6D53 +:107A300068FFEB9AFB28CFF039A294779E567A66BE +:107A4000111D772C7435367929BF4D5C77EDE33FF6 +:107A5000F168BC7F1C2CD0F9C7F96AC336AB3782FA +:107A6000F336BC227BE9350188F2FACCCF07C2EFAE +:107A7000DAC87EAB1688164E1D781FC56823BD096F +:107A8000B4AFFB5876532BE415203EC79D33D4E8A2 +:107A900076D88CE35D99FABE888E5FE40FEFA70677 +:107AA000912EDA3F8290B0C7CDBFD938F66DA4EFE2 +:107AB000CCB617DD5259FCB9C26A96477FF8F65F1B +:107AC000392C83E3B757C77B2C6E09F1735A87248F +:107AD0000E833A455B678DB8296FABDB62F506F123 +:107AE000725D9B0C0EF25F27ED1C37D4B57DC2F89A +:107AF000AC937C51691C2FC32DC5C511CBDBDE9B1C +:107B000045F676799E0C7351A56AF79C13E37D10B8 +:107B10004DC1F1CB77BF3DEB87D447BC3B92C8AB9F +:107B20002A7CC026F4C624AFF0DBB3281E6EFECD3F +:107B3000672C8F0FF74B90533CF0F99A2DEFD9C873 +:107B40009F9C41C164A60B7E91DF0884E585B6B495 +:107B500064F28B5CFFBB4ABECFFB7F1793E37A3A9C +:107B60006B1BCF787FF2774847CD9B76EF5C7AEF3F +:107B70009377BA0171F081D22870FF8B073CE487BC +:107B80006BAC418FCAADB85EF3CBBB198FCB8EDF28 +:107B9000ED11F98D2F4FEC1705F3689D4B367F9B48 +:107BA000D7B914FC8CC79A5FC8D5B44F734E81D92E +:107BB000BB93E84D659688B7ECF083B1F789F30085 +:107BC000A0FCFC037DDF34F8B2CC719B1D6E4C9B96 +:107BD00017B7FF64CF12F62A08A13FD2B96A00DDB9 +:107BE0002B9F831C3F378BE6B9AB5869A473225C8B +:107BF0007F50E797F415EF0B80A6C4C55955C7AF62 +:107C0000CEA17D313BF4DBFE5725C7D51AC53D71AA +:107C1000CF31DF3ED86A1F225D89AD27F9BEE9ED7D +:107C20005986FEC3CB1087A7C08E0F184F80FE3B2E +:107C30002D57F41F237D5CE46A4C43BE7DFACABB1A +:107C4000363AD70AE27A8611BDDDEF711FBCD91A28 +:107C50008D37E60F74D863E781A4D7DBDE33E9758F +:107C6000E27DF4DFCCCF00A46994B77D608BCE2297 +:107C70007F1EC4F7527DC1D20DF684F3C6185E4C48 +:107C8000E78BBA7E1AFB9CCB4CF198D19AEDC2954A +:107C9000598976013667273D5F34E72175D6D0AF25 +:107CA000893F7527ED9CBFD4B509FDC3803A3A0CD6 +:107CB000F5E1A35D875EBB05D7F151D89A3597DF13 +:107CC00096686F6B9E42FDC5F132F23B85EDED6724 +:107CD0001C4F19FEE823175E1C93446FF17A52BDC6 +:107CE0007501DBB3FF577676D92076F6BB5903E2F0 +:107CF00084347C0DFCE589E597537C61E6AF615FD8 +:107D0000CD76F3934C2DA9DD04DDCF1B7CACDD7962 +:107D100096717B3E4F9C37356CFB2BFB31646BD4EB +:107D20008EB86D087DCCFD07C88F71FFC07C696C73 +:107D3000B27527F2D37CFF32922DE723D1EF139F48 +:107D4000658BDB2BF6E7543ECF6F26BF49765A533F +:107D500081E40833204C7187D4F9FC5FE97DE6BCEF +:107D60002238034636F2B92EAC8BAFCF092B7A3DC1 +:107D70004530797D4EB32D769E4BF7073BCF7D5F27 +:107D8000B7575E97CAE508D62C4D4E5657E2ADB2AE +:107D900024CD237E9225CE774AB3C5BA8F65097963 +:107DA000B4C8D5FA46A3C897680F95ED5FBA9BCFC4 +:107DB00083AD7A7D06CE9CCBE7074ECB27C812D881 +:107DC000BDA17A8E42FBC315963B4BB1DFB5E1F600 +:107DD000390AE2C73BD5B2A704FB2F6C582CFA57DF +:107DE0005A2AAC08FDC7834BE6CCA47D03CBDB3F0E +:107DF000A5F529AB15A0FA91D296F7B87F97559CB7 +:107E00005F353CBBB786DEDF20A12090FF2DEE70F2 +:107E100023D731E482BA9A368FB53D7EBABF260F9A +:107E2000F379944724CDFFDB2CF22B8E885B2BA1BA +:107E3000BCD2B7F17B785F79D94A3921AE53EC8354 +:107E40008FDE333597ECEEFF85F7FF5B56F6E0EFFC +:107E50003FF3D4B50B68FC68195419E72B57B42AC3 +:107E6000EADB31BFA6BCCD9043B922F85EE6B27121 +:107E70003ED792EECB253C1D239C665F7ADBACD7C8 +:107E80000FC94E810339CDD2B81BDB5774F9BFAA95 +:107E9000F383FE685FA06F5FCE56AE5B816811C949 +:107EA0005796B7B6113FA24D0A6CA5FDD77D8FB787 +:107EB000113E5FB73978FFE8E6B4F5D62B90E4724F +:107EC00047D19D04FE37A55D7753BB2FDBDF93259C +:107ED000E68DD0BCB77C5F16F3BA1A53C97F820F08 +:107EE000F54AECD370FC0E7ED42BA2F920EAD538EB +:107EF000320589754E663AE4B45D4CC7CD7641C70C +:107F0000825049730FD231CE1EBA8CF22B7C7F94F3 +:107F1000E4700B865B84E760217491DC5EBFEDCA80 +:107F20002D627D85ACAFACFF7CFE7EE6499A2F804A +:107F3000F3D3396A40EAE1FE1EC5A1065561DF1799 +:107F4000C6EDBB3D0BAD27CAC4FE7E33E51D53F520 +:107F5000BCD8D87F33EA0D2676F9AB5C64B0E54E29 +:107F600099ECCA398CD7C88E99F7DD269BECEFD4F3 +:107F70008E8FD82E5FEC3CD099ADDBE37CC8A77523 +:107F800084E93C90025EDD4F7AE93C3089FEC79D72 +:107F90000766660B397DED79E09DBABDD1A84E0E1E +:107FA000D7D18F1393DCFA8F2E82F24AAE476884C2 +:107FB000F4C1FD6ABBC9FE1B381FF38A7A3BD9B3F3 +:107FC00031AFC06DB4DEABF5F393FED3C0F580E303 +:107FD0007A1C5C1F68EDB28642525C3DCA490BD7E1 +:107FE000A3F48337C4F52B41BB1A647B3996EB4F5E +:107FF0005A4EEAE7BD7A3D438560D93F5C0F61AEDA +:108000007F98E29E242FACE4F31990260DAC7F9864 +:1080100022DF2A935D81A3429E17EA20E43299D69B +:10802000752E024029DA8457E2E48DFF9B9815945F +:10803000B9FCE954E2F529265C98E57F6DB61EDFB0 +:10804000E8F21FB48EE443B1AF360EC6721D89D577 +:108050005C47F286850B366375241521D2B7094D2E +:1080600062DFF862753CE63A1D731D4E9E3F914FEC +:1080700005355724DCBFACB13CA17FF9CA2909E31F +:108080008BD1A1C6F74B1F9A93307E58EB8D09FD1B +:10809000119B6E49183F2AB428E1FEE81DB549EB53 +:1080A0005E0C9C8C09AF48B8BFD1F9E4BB84AF9695 +:1080B0003C59A578FECA8EFB4C7531D31817538CEA +:1080C0007D785DFE465D1D9581119FC7A3FC1F2B2A +:1080D000A6B8E9FE2A491B88036F24C87EFC1FC589 +:1080E000C17A931D30F4FF62FB373FD6FD849C526A +:1080F00024519CE3C3B82A652AD5118B737B784B36 +:10810000D4AB7C96F2778E8B34C9ED856FD25B55FC +:1081100089E2A07BAB348E83EE1D527480F60F7A19 +:108120007EE0F64AF903EB42CD75A0190EDF64E05C +:10813000AD115107D982869EEC7F708683E38C87D0 +:108140002D96DBAAE3E87F225BD89F27B245BEF5D8 +:10815000735B7837D901C5016A539E789E8A1F8068 +:108160002A7B502EEE4C10F561F0C6DA9985E43F7B +:108170007B466AE9543F8BFD6FE06525C4FEE496BB +:108180006685F3BCD5CE27D99F942BC29F8C93854F +:10819000DF403FD241F6F14DE97EAB88B382569283 +:1081A0004F810382EE72F6AF7C4E9C0E59D28A321A +:1081B000AA4FBDE0B7B4AF104C876AA75A884FFDED +:1081C0008B653E0F7E8948427AFB6B46719D73FF3B +:1081D00085FA3F2D8DF2EBFEC58F9EBDBB32A69773 +:1081E000276DC9F3BC8BEDBBD56C793495CE514E60 +:1081F0008E8484FA8C37B3457EF866B62CEA0C423E +:10820000EF79884D7D4BBE184E4407A4EE352E1CE9 +:10821000F2E0A61F54935C6CEDF382B4AF69ECE31B +:108220005FC8033BA773FDB6912FDDFCBAD8D7BB5F +:10823000F98BC47DEB8FB2C5B9C047F43E6CCBBBA4 +:10824000FCE3496E379042F0BEB27F3CC507D52AA9 +:1082500068E4F717F817DE7D14FBF3D64B1CEFD359 +:108260007D1A7F23CA90EE9F00EFAB7B91BECFB308 +:10827000053DF3A1DA4A74BEF6FDFA54C2D3EBE928 +:10828000627C54026D6BDC7C37E8F3BDFEFDE57B60 +:10829000294FA7F7D1FB891E7AFF3C154AA8FF1A80 +:1082A000F8CFBE5A3CF0BD3781CFAAD77B59C94F12 +:1082B0009642A8ED69B2AB472CDEB5C06D2493FDA4 +:1082C000929DFD525F53F4C97B90CE3FD5FE75AFB2 +:1082D000847CFDE3C2E8AF9FC6EBDFDD248386B874 +:1082E000F838C32F7BE2EAB44F2EFE2495F889F1CB +:1082F000CAF69F92DEEDB47BA9AEE3CDDA9DC3E36F +:10830000E3FA54CF74073D07932EED3CADEA89C9DB +:108310008CBF15DB05FE56FC66440EE16C45EA0594 +:10832000DC89FEF6523E279D2041D2FC783FE24D8B +:108330001BC17535A021CEF67F2EEACAF71CCDA849 +:1083400020FA14F05F16BF9E3D2FDD329AEB79DFE5 +:10835000C8BA243A496783687F6F665389F181AE52 +:10836000270B3A332BF478729487E2B9DFFFE6ECFF +:108370007F105FF6EDDCFE43D6914BE3C3C03A5A63 +:108380007527DB27230FA3BA57CAD30E59D84F5EE0 +:108390002DDFCF7918D56970DE35A488C7A3C15108 +:1083A000ADC2BE89EF24300E6EF672BD27EBEB4AEC +:1083B00055C42D469E245BBCB98AF8C8E0C5A93CCB +:1083C0007F09D0FE989B122BC35E611CE1962DBAEB +:1083D000BD029F03F3D3D1BA3D9BE5F15EDB22CE14 +:1083E0006B12E24FEC57ED4A127756E33F8E3B3764 +:1083F000FB9B53D82F6D96CB28EEF03922E4C7CDE6 +:1084000071E75458CFFB0003E2CFE7FE7249F1E772 +:10841000F73CFF3DBFB3D4A3B1FD098F14762E1CEA +:1084200019C2790EFE55907E0DA5BD003A07CD13F9 +:10843000AD4DEA1DE940FDACF594AF7B681AC2650D +:10844000A8E00FF551A450AA7D72E82B8A03BB1552 +:10845000965FFF73577CED772495A887E4EC23871C +:10846000A770BD735F97D08FB60CEDDFA7529E81CA +:1084700071E656243145E9B1A52759CFD3647F5120 +:108480001FC21E9147393AC4B9A843F301D99714C2 +:10849000551D4789B9317EB147D8DDFAC36F16D96A +:1084A000503E672D47DD74BE52B7F729372E179A15 +:1084B00033FD0F90FE2C3FF9F20495EBDCB614511E +:1084C000FE1D8EBC3C83E3B3D9C8DA7183AF27B0FD +:1084D000A9823E4280864D99DC8EA27D15BC14880F +:1084E0008875F676346724DB1F08FCDB5B0769BD03 +:1084F0003B8FA570DCB233BB9BF520380F603BF29D +:10850000FB89CF47F37C0830A6E38A6A4D227FFFC0 +:108510000B7D3D3BF5FCB2F77399C719F38EE998D3 +:108520002EAB88ABB248EB41AEE3EAB46B24DF94E8 +:108530006D20F8D399C2756181FDD788BC335D9CED +:1085400047B70D89FE91DE13DD67D7A84E35456D1F +:10855000850C9CBFCD26FCEC2804FE53AED875E3F9 +:108560007D299D1BF92308C405D7E3A528ADF00D8F +:10857000573CFF5399DEFD1E11EFB40D89585CE4A2 +:10858000273057DACA74C5E8047EAF41E7288E8BDE +:10859000DB6CD1F769BF1DE9520917A340D0099DD3 +:1085A00023348A57525471AE9EA26ADEA03490AE34 +:1085B000C058086170000FAF860B7ACE7584436295 +:1085C0007D07EA425B891EC70417AF9B392DAE4F6A +:1085D000866C52ECF9139E65EB5A0A695DC20F2A4C +:1085E0004A98CFC7DD0B40A5F3EF14C5C77952CA2F +:1085F0007CD09A505E4E878FEF7B708EA6C9DC8F41 +:1086000010FD2ADDA77D9B34D53907E94EFB328D5D +:108610009F6BE8B672DD79DDDF6F4A2BC3F59DB144 +:108620001CBC6717B61F2D0C0FA773DA0969FEB7BC +:10863000C81E3F736AD1BA3138FE2F6D56EF5CB257 +:108640004B3DC11FD3B97DED13568DFCE2836FF412 +:1086500047BE22F93E2BB15DECB38AFBD8D79AF026 +:108660007E43E707363AD7BAA6E36D1BED7FAFCC62 +:10867000F1BF4F7A30A9A3A98AF836195A9B699F8E +:1086800013ED21D74B847385BDE87F65F8D6A638F6 +:108690003EBB72F47DEFA8FF72D29B4E5D3FF75355 +:1086A0007C84ED5E3D4EDB7BE0BBA55ADCF96910B6 +:1086B0000EF27EE06A788EEB3A8DEB7D216536E135 +:1086C00068F46B8EDB7C7138B3E5087DB7E9EFFBAE +:1086D000798EFF4BD6DB03EFD8DCB8FEC09FC345D5 +:1086E000E4AFC218CF7D5D1D69C0A42F17EA8E4E7E +:1086F00003DB919DAF7570FCBDF33E359DF41EE923 +:108700008734ECEFC5F882F4686FB1D0BBA657CFC1 +:108710008FA5FDE2F3FB965F4EFCEAF5580D7CCF8A +:1087200018427AB41BD88E197A58467A28D1F77B2A +:1087300062BFA78CF04D7A67EB9EC37AB7D702A4CD +:1087400077886FC63BE25BA538A44C45BCF3F323A6 +:10875000588FDBBA5FBE82EBD991BDC3C651DFC271 +:10876000F86A8BCC0949F87CA53572909EAFC4F7A6 +:10877000376931BDAC9412EB7A167B449DAC611F16 +:108780007FA0EB6778A496E6C5F14E594EC07F9C5A +:108790009F147DDD8FDEBBF127EB36A0BE94FA2A55 +:1087A0002C1328DE3926B31FD8AFC7C92BFE30E5FE +:1087B000865DE23AFBCF888E8B837ADCFCDCAA5C98 +:1087C000EE935FD0502EE3B1F55550BD7763156D34 +:1087D000C54D9ADD7A88DA29D5E12A3A2E9CB6A0D1 +:1087E000FB90F8C6CD379AF0D67EF05BA3B94EFA6F +:1087F000A41DE83BCEF6FF8CFEF1095CFF3DFB912A +:10880000DF90342E61BCA1C766FC0D86933EA9E7BC +:10881000FAA96897AFDBF8EB6B1574E80D04045CFC +:10882000FF9C8DDBD605D1079EC8F15D9783F8FBD1 +:1088300022D77F5D0EF2ADEFF87F7AC89FEC7DE521 +:108840001D37F9E1769B6F34E1AABD04F3882478E3 +:108850009C926365FF5A3948BD49638EC8B7860745 +:10886000611DE1A5A15D5643E4A77DDDD793DF78C7 +:108870001F5949FBDA4BA707DD942FD5EC3DC47592 +:10888000FA463EBD04F43FF9D659C4FF73B9223FFE +:108890005EBAC19A90DF8E80888DCE91037E576339 +:1088A000044552638A3BEEE8D8C2DF8DD46E4B7C20 +:1088B000AE8EE2148450DD45F2E3C61C7D9FA41405 +:1088C0004A294E41DCF03E49F455D9BB15B8BEAA41 +:1088D0008BEAAB765A049F9C0E6849CB88C52B2344 +:1088E000F27C4BC8DE2D31FC875EAF146D93F87BB4 +:1088F0008A513B44BE3CE5B4B685BF930AFAB84EF4 +:10890000AF860840BAA728415EFF94DC5208E2FA1D +:1089100027A179267D59DA2985989FFA772F0AFEB3 +:1089200013FB459B65FECE6FB30499C5346F94F974 +:1089300053ABEF1F2EDF91787E51B7E9F8610A95AE +:10894000EAC3A6F3209D3FE6F39DA7E83F929CEF84 +:10895000FC24478FE78AA028E1BBBCAE4BFB2EEF7F +:10896000238A075C74F8080971F91E1D470DFABACD +:10897000EB42B258378A82EAA36FD76112002FF315 +:10898000A91E71423880F542DE463D632D54DBA8B6 +:108990008EACBEBDE9309DBF2DD5E35A339E90A16C +:1089A000CCAF657ADD50CDE6C4FBB53A5F6A4D7C4D +:1089B00069F04B26FA44DC7DA9F4A1E5FA0EE1A0AA +:1089C000769795EBB9CFC1AD5C7F55DFBE85E95990 +:1089D000AACB6F20BD415ECF325C0FE9D3A5D26B2D +:1089E00096DF3103E757C01509F29B9D7949F22BB9 +:1089F000057539ADAFBF4BE4B5FD5D25BC2F61E01A +:108A0000C5FCFC2C3D8EBE66938837CF7654392941 +:108A10001EE83BAA7825C47DC5B14FDDF4FD4DF9B4 +:108A20003E19E89CB4AFB3625D10EDE59EAEA13790 +:108A300069E807CA8F29EC372A8E9587528AA95F81 +:108A4000EE2CE53A132D93F2009C87FD70DFD1A147 +:108A500027CA384E9F5949296AD3D17227C50B7B43 +:108A600040EC6F48C72A337BE2FCCA7B3962BF61A6 +:108A70004DEEBB0F939DBA66B795F783AFB1465FD6 +:108A8000A23C6C4F97E26DC27EDDB145AB5348DE30 +:108A9000BF91BC14761FEE5E9145E735F59D56D526 +:108AA000CEF4DE7D90EE077749DE61383EB0EFEA26 +:108AB000D16DB44FB4A5C24BEC35DE579EAE3D4AE6 +:108AC000F5AE90E7E4BCFD9ACBACEC5FCFE43BFFA6 +:108AD000752EAEABD6B76516D9E133BFDBC37515BE +:108AE0007D6D12E44AB48F7CE849AAF739F3F4713A +:108AF0001B9D0757B51FE7BA8DC1FCC1D910E28E87 +:108B0000F3F6561BE537F55B8C7E0F7F8F52ADC7B2 +:108B1000510DDBDEE67E2DE50184C7CD7248C3FF33 +:108B20003CB4EF193E1F6ED825EA3E2EDCDF26F15D +:108B30007D03EF8B74BBB51C34C6FB7203EF7A7DEB +:108B40009481F7733097EBB496EF7A84F1BD44C704 +:108B5000B7B96E0A2DB0AD2C4BE82BEDB799BFFF1E +:108B6000BB43C7F71D17C1F7A85C1DDFA36014E165 +:108B7000FBFC74514F77FEF81027CD7FFE08EFBE47 +:108B80007E1DCED9EF1ED5E382FE88C567BB323687 +:108B9000AEB7E313FE0E3170B4DF467527B33A3F2C +:108BA0006679CCED3C3093F87D1DF8EB887FD77566 +:108BB0003A558A83E7F6087B36A7D3CEE713D74129 +:108BC000B885E4DCB7FFF1960CC2CDAF056E0C3B67 +:108BD000B74CE7EBB5653F9845F97BADEE0FFBBBB6 +:108BE000EE9CC576671C1453BC3747FFCE7B4E58AE +:108BF000B7439B13F94EE7D424B7864E3BD79B5C13 +:108C00000B3D36F267D7EAFED3EC27FBF29C2CE74C +:108C100020FAAB6138BE6E97A98E52E9617AFA3BB1 +:108C20006C7CDED560F2BFD372AD09F51783E1D35A +:108C30002CAFDB72757FA2CB6B6E54D431CC7945EF +:108C4000F6D2F94357647519C50B06DFCCF2EAD2A8 +:108C50004AD3BEEEF7125ED2E37CA37F83FEFD5BB8 +:108C6000586D75C5E7EDCFE75AF473CED04F2B7032 +:108C70009D7749D04D38C4FCE6867229697EB332AF +:108C800017C73F5F78FBFA71F1F98D6FCB708AF7E8 +:108C90001E44BB5251C9F53BDD7C5EA8B4CEA57322 +:108CA000B0C02EAB97F29A4087CCF14060973D64FC +:108CB000C179AF211C215DD59DD2D58423CC1B5A0F +:108CC00072D13ECDA32D651C37AF03E3117C6EDE60 +:108CD000CC8F197F47868A75F72B5A4EB23CC2C893 +:108CE0001F1A3E17F1AA71BD01ED008D6FD0BF4B69 +:108CF0006B3FF8D7A2E2543AB7FDAC6821C5A9B9D9 +:108D0000227F31E2D528C6AB257ABC4275174B8548 +:108D1000E860E973F7D9C87E1DA61FB6A0FA49D549 +:108D2000BF86F261D50F8D3FA240436A613D6A2044 +:108D30009D221CEE95C4FECDB356AA0D81A6978741 +:108D4000705D60EF6BE21CCAACEFBD8BBAD95E9C64 +:108D50005FE86A24BC2D2FDBB206230C18BDFF751B +:108D6000B637A37F67532D6A6C5D4DF4DD1DE7694F +:108D70002D09F1726F47B38DF7A1E3BF1B2E1918B0 +:108D80001FD55F641FEB79935D41FA39DEED3B221D +:108D9000ABB42F847CFC657E3CBFF478A8FD600AF0 +:108DA000FBAFBEE3AE10C5FD7FD1F17846DF976F14 +:108DB0009A24333F2C93453B7AFF3325245F9287D7 +:108DC0001FEDFDCEFDCF5CE1E37DF490A823DE91A5 +:108DD00058875D1F4EACB336F81AD0F98A740DA7C8 +:108DE000EF950DBAF62A3D6E6F123D92A4832C2F9B +:108DF0008B9498E7069E95ABE3EB48713DB791DD08 +:108E00003B69E88B12F5901F7E2B5763DC34750AA3 +:108E1000F95AF68916DFFF1DB15F63E5F70FB83F1A +:108E2000235847F7CF173BB9BE013E0FCEA5FE3DF5 +:108E300025E2F703EE79B97644FC3E1D48221F0F68 +:108E400058A35CEF17386E61FA02C7FB3D435D64BF +:108E500017B7CCA43ADA6B757B71B8C45943380F95 +:108E6000D27B7362F32CC915E71B40EBCD8D7D5F80 +:108E700069AC7735DCC87C58ADE3EA3FF4BC1EF33F +:108E8000A8F3B949F2A8C1E2DF0B74EBF1D3F9E919 +:108E9000DA89EF210ECA8F2841CAD7F7BC91122276 +:108EA000FFDFB46FD99F281F0EBC69078A43EED934 +:108EB000BF6C04D7E1FBFD57923D39BFFF8E2BB944 +:108EC0008E5112DF970689BE5C8AA75EF5509C54CE +:108ED000BFEF55AE73ACDF3BFE518A9F305EBA9652 +:108EE000AE631CC3F82B3F56C9F8DB73B432B3949E +:108EF0000807AF93E6AD3FA270DD63FD91CA17E7A7 +:108F0000525C736C06C74F46BC5441F938C54F4795 +:108F10008626C44FA979827F7D075278FF4382124B +:108F2000811F189A809FBAF63F709C5187F62E1EBB +:108F300047C673C5790ACF332C4FC74F58F2313E1D +:108F4000768BB6AE630FAF6FB935CCF26EDA6515BE +:108F5000F7DB446BD44907212348FC78912EA11CF0 +:108F6000E6D84285946FBE502CF20DB33C9EC813D8 +:108F7000E7852F9C14DF19BF30DD3F22D9F7C641AA +:108F80009821F27049E777BB7576B2EF7977E4897B +:108F9000FD097726249C4B1AEDA379425FE6D8C4DD +:108FA0003E95F9BE3FCFF03FB08ECE634ECCB5AA12 +:108FB000C6EFB7E4A1DDBD1E8C3FEFABF3B3E89C79 +:108FC0004BE4D5003D33C91E7E9BF6F929FE9A2459 +:108FD000FCBAB1CF3F6F333C20F6F96FB5925D30EC +:108FE000EA4BE6F9CCF157F5D534CF8DE8DF699E31 +:108FF0009B6627DEFFF645E2AE0579BA1F1F0EC35A +:10900000455EE172923F38D76555655E476868B244 +:10901000EF0B0DFB737895383FEA42BB486DD3A840 +:10902000D779DFEA8503279F4C67BB9A0225C8E200 +:10903000ABBEFC9327D93C4D17F4757E02FE0C792C +:109040009DA53CA06CA0BCEECCB3E8DF259DB1F1A2 +:10905000F926343E649107FF2EA969D4672DA44FE9 +:1090600067F5EF5E90BE227B9CDD3F9BF731DFBF53 +:109070006706448378FFC0283BFBBFFA99129F1F05 +:10908000D447843FAC9F2FFCE1F0F6792C97EFA0FA +:109090005C7C5E3613AF515DAE21EFABBEEC9B69DD +:1090A000E493748ED34438673B9DC56D7DFBDB2D07 +:1090B0007C5E897E97E2C21B2625CA6D04F81FC814 +:1090C000C6FB37CF96BCE84106C8FDE65BE7B1DCDE +:1090D0006FD2BF8FB998DC7F9BE7FF691EE97D7770 +:1090E000FF77C6208B5E18F54111F9D7864170BD18 +:1090F00055E72F0C8D3E4DE765DE0BE7E97F7F3AA4 +:10910000FE3CBDC4E3DF924776D5F2A5FB0AA0F989 +:109110007A7EB942223901EBC5607AB5439F7F4719 +:109120009E2ADE9325CE8746E9FD17ACA142FE9E1E +:10913000A2ECD2CE019B9E7D7E2CD9B9DE0347C620 +:10914000DAE2E47A6605DA07F237FB0EF1F78731E7 +:10915000DC5974DC29DC4AD28DBA1F4DC4E119C236 +:1091600021D9E7DD87AEA7FCF16CFB4D599216E7DC +:1091700067F79E700F8B9BF7ACFEBB1898B70DFF7F +:10918000766A3C9D0F309D67C3623ED4FFE1378D08 +:1091900089BFDF6C7C67C7787E7064239FD31B78A0 +:1091A0005640E0D9F83D8C0BDF55DA80BF7B0CEEE2 +:1091B000B7737D459F355A941EA72F1F1A72449886 +:1091C0001566312BB9DE75226CA8E273024CDED72E +:1091D0004DA6CFEFC2B2A80F6DE4BAC5698DE025E8 +:1091E000DC4AB099FB13668BF3F229D02D135DDFB7 +:1091F0008428B73E50156A67508519B6931C61994B +:10920000C2ADB6F6834EC257C4A3A4BFEF10A5A744 +:10921000C9E4175BBF02EF1B78C5C1180425FD4EDA +:109220003F2B5FD87FAF53E863F4ACF8DD936F401A +:109230000FD33F55E9667A53352D83CE4B763FB732 +:1092400042A6FA97FDA04549CFBC998DBCFF169D5B +:109250000EE1ADE9B1F54EA2F5AAB1FE940560A10B +:10926000F54AB04BACBF1132E87C6C3244F83D5744 +:1092700011C1B8DEE9A029D4B7E517EB7C16F95B7C +:10928000959EBF591C41AEFB49CD17B8762A2139AE +:10929000AF92B7B6C38FD0F94CA958E744BCCEE71C +:1092A000388D82EE0BFE3A5FD8BB29106639430D2C +:1092B000A82FF28F2BCC54895F52C463A1DF13BB5C +:1092C00054BEF67980E977DF1EEDFD6165ECDCCBFD +:1092D000DB99C3F5D0EB254B5426BA1C85A21E3A68 +:1092E0000261FE2E3392F87B67C5F9375E9E4F7E92 +:1092F000CF2FBEC335D775EE086DE5BA9B05416427 +:109300000FCD530870DA13AB03B09684F8BE95CE38 +:10931000D955AE33ADA07C715FB6FFF2FC6CAE37B1 +:109320001DC69329A1F1D5A931BC2365FCFB3B4E99 +:10933000486D257BD4ACD7D30655B75ECF54C4EB6C +:10934000D0D0CEF38F4828A2AEFBDE2A517F7AEF31 +:1093500090FD5CE7DB23812A15D0F9FF7EAE03A6E2 +:109360001F86B3167CCDF97F96FEBB0F25FE3726F0 +:1093700096EA461E9F6B3E95CAF5AFCA0C9F46758E +:10938000BCE67AF1D296F10FF5705E6AD06BAA1343 +:1093900057BC7CFF5EDDBE363BC4EF0049ABEDAA97 +:1093A000348DBE7F5FC1BF63D54CA141257DF7BE23 +:1093B000829FA73A662A02ED4DF3DF44FC32FF2E6E +:1093C00015C2ABFF059A376D38EFF72593C73443C5 +:1093D0001E9681755228875B49BE46DDAD516F4BA5 +:1093E00080A0753B7DE277F054C409FFEE1F42C9AF +:1093F0004EB8F4997FCF43D4FFB6E8FC47BA7670F5 +:10940000DDA7437CA76D7CCF6BE69B81DFFF02B9B4 +:10941000D77EA250530000000000000000000000B2 +:109420001F8B080000000000000B9B25C3C0F0A3A9 +:109430001E8145A551F9E8F81C9A3C0B0303C34F64 +:10944000205ECC835F1F2E1CCB82607B893330185B +:109450008B32309800F12C209E0DC43F81D8508C67 +:1094600081C108888B81EC1220F6056247A0DA2FB3 +:109470001C0C0C13851918E600F1726154735F30EF +:109480004268252E060653206664C66E3FA73AD072 +:109490005E5D04FF23906D6F409E5F46F1D0C35523 +:1094A0004EA8FC7C6B54FE2C5B0606666704BFC0AE +:1094B0009A34F3ED817A1D9C71CB77BAA3F21B3DF0 +:1094C00051F97FDC50F935E1101A008D579524B819 +:1094D00003000000000000001F8B080000000000D7 +:1094E000000BED7D7D9C14D595E8A9AEEAEAEACFA4 +:1094F000A9197AA04706A8611A19E3A0050C30281B +:1095000048CDA0384693349890D1D5BC168821090F +:10951000CFD7F1ED2A1AC9F47CCFC0800DB2067DF9 +:10952000515B0C89262621899B3559B3698DC92346 +:10953000D96C168D9B47B2B86F243C379F9B79EE50 +:1095400043FABD90B0F79C7B6BA6ABA6BF00DDE4F1 +:109550008F37FCCCCDA9BA1FE79C7BEEB9E79C7B8B +:10956000EAB6EAF1437C1EC059FC5B03F0A6170083 +:10957000964D95E94E33076DACFC1C98FDECD1A5DA +:109580007AAE5362E5A2D0B84732002E8F66003C17 +:1095900000F1C38F8287D51B695461671380DFD8C0 +:1095A0005003A1A97EDD657F0F406E61E9F7F20BE4 +:1095B000A33123CCFA7B6A79B7C5FA19F9727BB764 +:1095C000D53AF5BE010765F8CD07864D3DC0E09C54 +:1095D00007C113051866632F64FF69F72521C1DAF7 +:1095E000A9B951301661BD5AAAAF3D73D4731B7B24 +:1095F0003EEC85EEC3ACD49E4DE7820CEFCB9ED300 +:1096000097C88C1EBF62797EC5607FCC934D231DA9 +:10961000B17DD4EF2946170EF576D1B314E9617404 +:10962000ACAA929E55A5E8792E9D467A2E7FD658F3 +:109630005C488FD6C8E9D11AFB689E4EC5183D4DCF +:109640001742CF3D44CFB0A067D845CFBB043D1BE8 +:109650006D7A1A86889EA1398C1EF6C8775F1A1219 +:10966000ACBE86F484B19E939E21A4A7B5083DDAD2 +:109670001F879E0F09794B213DCB2AD393427AEA6B +:10968000ABA02794019D3DF783641D6E9D8E975F6F +:10969000F071D13399589AF53BFA7B99E699ADC8A8 +:1096A000D8864553F5C6055EDF691A8A8DA37C2DE1 +:1096B000783006ACBFD13912D577F7FB10A8547FAC +:1096C00066A3D58BFDBFE34967FFA37338BE76FD64 +:1096D000DF8879FC0DC8D46E5628318AF0E882AF55 +:1096E0004112C7F166623AB66BE2ED06172CEF1E27 +:1096F0000F156BCFE919DD912679D672F710BFFEF1 +:10970000624E060C06FB9F4C02F25F8D717CECF6FC +:109710000C2F802B90ECBB2C8BE30770119BA7F4D4 +:109720005DB9341B2F9EB9434B307E8C36F46948AB +:10973000F788B1AF1BF5D6A9B80A7213E2559C0F92 +:10974000B65CAC81316D3E9BCFFE576473274CAF46 +:109750009746E1AA9F82959007722D407F6701E9A5 +:1097600049D2FC0F2E7890E85691AE4548570A0C26 +:10977000F6FC1B427E7CCFA401E54A33D2B1F4A2B1 +:10978000E9E38C20FF5BB1D74C6C4301FD3FB5E7AB +:1097900097CDAB6B7E892F0F81954B235FFCCE79E4 +:1097A000B3CBEF09BE5FDE9826FE561A7F3AFD7CEA +:1097B000FCBF0683FA012D134B84A7F019F58EF731 +:1097C000A15CB335691E62552E63E37414F0DB3D72 +:1097D000DE249D4AC621C75F137C1AF54FBC50D8C2 +:1097E0009F1B9F6F897ADF029D4A9BAECB9EE5E36C +:1097F00054EAFF47C8E27AACEF5A574ADAC1F77B1E +:1098000045FDCB9F73D62BC59F8F4FF2271D437904 +:10981000B4D723FE59330184C8D05F6839C025F816 +:109820007F5893DFDE367E172EADE3D1E4296CBF7F +:109830000D92F302CD6CBD78939FC5729D62BD49B8 +:10984000FD42487FFD52217732E9013E1EEB1E5852 +:10985000FF61D19F2275013079F6B543762743ED3C +:109860001AF9784E62FCDC0760CED20BF6F5137C59 +:109870005F5FA967D7E27E7EA5C20861E3D580EE6F +:10988000C712EBE758BDC8B290C946021FFC594D3C +:10989000A288DCF8DB20EDAF61E3B7AB8E75E1B7F2 +:1098A00092807A211C839C3F02A04BE128E1BF02F9 +:1098B0005670FC0D09FBAB538C5E858D23C73DE6CE +:1098C00041F6B46615ACDC54208786C4E5B737EEA4 +:1098D000F1205D434CFFFBD8928CCC61EB1DD7434C +:1098E0008CD91B45E47652BFE765C8CD60FDE625FF +:1098F000C82D657008562659BB8C0F569EA471C1A1 +:109900003C5844CE364A7C5EA5F8C4D9B3641740AF +:10991000F65AB20B32B48ED578C6C27D40B322A6B9 +:109920000FA7FDCCFD5CAF2960A19CD4C633B91A4A +:109930007C6F5CDC84F8CE8AA7E0B5565E9E28C0BA +:10994000570BA563643F355D2CF515EC63CF33F9F8 +:109950003951206F233BB81D30D83424F4CC8749CB +:109960007FDAEF3F20F8A48E3364902E43CDCE975C +:10997000A6CBF588545C4F6C16F4E2DFD5CB9DF294 +:10998000AACC14F2CA86F02940F235FC1464115FA7 +:10999000C6C9176E63F0A52F6AB093C9572B1CF583 +:1099A000A0FC5C0613549AA0CB582E0193CA3648EB +:1099B00050F9DB0E26F7ACDC6631799F4FF2FF3EA3 +:1099C000898DFF9B39C98511F6DC1F4F5F81FB0B29 +:1099D00093FF8DF89CC98984F2546741D1FDB2563A +:1099E000E2EB75AFA2FBB1DE5E0B483FEE97FAD318 +:1099F000B84F8C083B69C40F8E75BC47D03D22CA56 +:109A0000DA7812C6717ED9BCA05E7FBEE9765AC7ED +:109A10003E85C3436C5E48EE56F37DCC8D8786F35E +:109A2000B2E8FCE761E31F7F1E86A4FAA2F3308C44 +:109A3000F3B051E2FA53FD391FBF0C7DB44F6FEE06 +:109A40007D9CF8AF9E3CB7FA36FDCB5D7A7385D02E +:109A50007357C2C45C85E9913B7C39559108EF4747 +:109A600010EF377F72F403480F8C2717E23EC5F0E2 +:109A70007E54223D9982A36C7CE515398B7E8A2722 +:109A80007883962CE3A780CEF49926F4D97CFCDF6A +:109A900046FDF5E074FD7BF1E10F1D237B03B4E48B +:109AA0004ED44FAB531ACA457FE3060DE568B89113 +:109AB000C128373155932E676508BA50FE6CFB6399 +:109AC00028B669A4298A768FB91CBBB5C75F1B4B22 +:109AD0008244CF93337C4DCEE73FC3F5AF2763324B +:109AE000A34FCD5EAB219D83FA06ADD0EF5243C9A3 +:109AF00098CAE47018C7C3F1BDA9234D6DA83F6192 +:109B0000691FEA733D054B51BE639D84E7DAC68445 +:109B100086EF7DB125E03390C509B2AB86A24E7FBA +:109B20006EB8F14EB89DEAA7E0F5D074FBDA174A9B +:109B3000815AB04FE03872C13CFB94540EE99263F5 +:109B4000C5F5EE3F09F9F71809DA6F20F3494B63C1 +:109B500072EF1532E08DC14FA4CB0AE6295AB0EF5F +:109B6000B0791AF29BDDC5D625DB419CFD9A1268BF +:109B7000CBABEF776ABF15F39E5931324EF31ECE51 +:109B8000E0BCF733BD4FFBEAF170F61023A1777507 +:109B9000EA317CEF4D2BD017A56E5A709FBB5B7ED0 +:109BA0008789F2B707F9C6368EB11E8DCA9D3D3A38 +:109BB00095233D312A3F19FCC467C759BBED699F06 +:109BC000EE4339C8DCFD25EC8F79DD899DD86F9493 +:109BD000F58FFD2A9A7E484798EF3BDE382F6FF1CC +:109BE000703ED67802846F9B87DBE10658242F19DC +:109BF000BDBC9F5ED3EEB473C366606A3DB0FF82A6 +:109C00002D750ED86F5CE4A8EF5E2F2F79B8DEF0CB +:109C10002A09305BB12CAEC7CF4A32D593E5C513C4 +:109C2000687F28B354B20B0625A7DE7ED4C3F7BBEA +:109C3000273C1AD11983896F9F65FCF0EA1EB27B1D +:109C400022B5F30FE7903FF5AAB9801511EFB85E82 +:109C500057643C882ABF1E2F58E74F4956DCF3272C +:109C6000C0A769F4F7763AE47A9787EF7767C57A01 +:109C7000917D5637EA9918134320F9301E473E78F4 +:109C800082ABCC16C687C15AD5407F68A0D7537423 +:109C9000DF71F341AEB92586FAD1CDF76F09397A74 +:109CA0005AF07DCD99F7909ED8AD7BBAB221E4DB16 +:109CB000D12ED4F3036D1E0FCAF99F0CFF5C746C98 +:109CC0009FE4DF241DC4B78128B79BC774263FB823 +:109CD0009EA35C7E0CC875D17B93D1254DA7CBCDBF +:109CE000BFB79B3E9BEF35B59E44B615F19B481020 +:109CF0007EAB94A2F8FD47F1DDC62B3489578EE385 +:109D000065FE69E0F594943C88EB7B8F90D73DCA63 +:109D1000B8867A216ECB4D90AFA3E97A4972C83BE1 +:109D2000EBE7F3D8CFFDD80FAB7FBF32E1E8C7AE8A +:109D300017463EF07591E0EB42F9A3AE0B1BAF9DC9 +:109D4000026F03B25CAE5B8ACBF5DB8D97BD9FF6ED +:109D500005AF02D437B5A104D9DFB342891CF2ABF9 +:109D6000BF5E35D0FE618E12EDD7D4D428F093EAD1 +:109D700037C6B0FE607823D9E583DE04D9E947EA27 +:109D8000BF66DDC6E8EA3F53033E93F903C1AB8EDD +:109D900018A8178FC8E4AFF59F699E952A32CF4166 +:109DA0008C8F31FC03881FD9D5EAA4118EF8F68771 +:109DB00098E263FDBCD10A59D4A7DE901543BBBB22 +:109DC0007F9166F651AD04207FFB821F684FB64E2F +:109DD0006F1F0C0D7D4CBE6C6A1CF6279D45DB97F2 +:109DE000EDE1E8C7137D92E37D513C2AC1DE29589D +:109DF000A7FE196C68D8B5649D6D9EE23BA3A5458E +:109E0000C17D130226CE7F3CD1D5F73BE4D3F76466 +:109E1000D2836EFEFCB59C0CC8CBA6606F3449F3B0 +:109E200066F7775DBD427A546984AC4FC251135DC9 +:109E300068DFF6377A28BEA68436D494B5BB1BAB50 +:109E4000B3BB41C43D6C79E8F8391F376072FD1D22 +:109E50008671C0B84A0DF0B8462D1812507B534A8F +:109E600050B06415C553A2FEB7BADF5BA85FC9DA6C +:109E70000B6783E7D0AFC2FA6D7E1BFAAD80AF1FD0 +:109E80003E45FD32F5103D3B63AA5F6F2C450FE167 +:109E9000CCD9B3F272E04DE82F49F2AD784C5A9F1D +:109EA0007051C43CC48AC1E89D0E7FEABDF27C4774 +:109EB000DC54D5873E264558D9B8CD1A2FD00FEEA1 +:109EC000F9EDC681D0BF6CDC628D57A137D0EC2E86 +:109ED00016971A5293D95EDCBFE786288E084A8A05 +:109EE000E2C2C352DD12B49FED7A4AA39A43BCC2C8 +:109EF0006D561AF5C5F00C8F299BD8EFD851F40791 +:109F000040BEC14C96892F298DCA2F0BE9F9CF721B +:109F1000384A788A38577F05791FEA297F3EA1AAF7 +:109F200066B2983F9396B9FDA2068ABFBF5AEDDC90 +:109F3000212F9BCEB70CF28E3D1FAE652EF7E55C50 +:109F40007C500E94C6EF1E433E0C35AC8B95A31788 +:109F50007466E714F845A66AED94CBE3B1A7181E22 +:109F60001062C2B3B2CC38627EF5AB4D1EEF40A595 +:109F700088E771C23E637847A4995C4FE3DFEEB691 +:109F800083398CA3796F0B59387FB2F524C8ACFEA6 +:109F90000F1B6490DA110EBCE6A1F95C6592BE6AF3 +:109FA000E1FE9DC5FE211D9155AA63DF42FD39B931 +:109FB0006F35A1FC3BE1CFC9CE78667FCFB3F0B35C +:109FC0000553F8B34756B178B1A2761E2ECE8FBA9C +:109FD000AAF8B19FC90B3079D9C7FC46C614C8305E +:109FE000BF11E13DCC6F04F2270D2A077A5AA8DC95 +:109FF000854D57E2F9596AA4A909E3A59F8E7D9082 +:10A0000055D98FBA83CE55029D183FDF69C3EC89BD +:10A0100084B03867F941FFEF3A301EB3D3CF618087 +:10A02000890ECB01CB7D18EFDF19E6ED7F26873A4D +:10A03000F13C62BF384702C5D2DE57E0FFE7652F2B +:10A04000D18136106FFF9B5EECCFAF08383D87F0B3 +:10A050009984191F111FBFC6E1C681B9D43FA90059 +:10A06000365E7C601E1F6F01B7EFA17543053EF69B +:10A0700091FCDF84877048736B1D1E2A836A9A8067 +:10A08000DBCDFE5A817795FD8092E4FB9D882B9570 +:10A090005E3715F6358147A5F907F44B317EC1F4DB +:10A0A000701AC7FDC7E2FBF45B3DEE7EEFB9F145E8 +:10A0B0006D9F482B8CC57F29277585C161EB70AEDC +:10A0C00089C1911B72695ABE558EFB6B5917F1D02D +:10A0D00024AD7F9BCF8ACEED8EAB5DF3E88D5A74B5 +:10A0E0002EE90FF1F5572DBE2B719C827EE0E9CE53 +:10A0F0008644B874BBFA8467CADE62FFCDE80A4CB6 +:10A10000D96BECBF5AABCE01D7B45FE4A81F36E7DA +:10A110003BDE7BF57738DE9FEF3C5DE6A2A3D9E618 +:10A120009F80636E3AAB963BC510FB5C9ADB8F93C6 +:10A13000B0D88F2BC167163A61DEAF0F6EAEE1F675 +:10A140000DB763FE13883A6E3CCC02FD2B633D0EC7 +:10A150001B1E096CFB36D732BDFF7EED131487B38F +:10A16000FA15F05F353D4E97EE4C519C2DDDE7D34F +:10A17000FBA31477A338DB7666C8FB58B9CD9BDC0C +:10A180008AF27BDA3F370B11EC37B502E3D6FDAE2E +:10A1900078825B9EE29FBAA9E879995D8EF4F0F827 +:10A1A0009F0D6B8DC5F300EE55F879FD77BDC97B2A +:10A1B000110FD48D40715AA075E035F8FEF87CD3AC +:10A1C0003AF805F9FFFC7C4C85F4B166464F86F9F8 +:10A1D0006B3B0DA49BAF9391A6755A9C3DDF5BEB47 +:10A1E0001136DD04D94F998E990DB89E6A94093ABB +:10A1F000B7AB8917C7E77EC523E6EDD6B2F4B9E75A +:10A20000E3560CB4B2767BE7481EE2FF1C4FF61013 +:10A21000C6A31A3DB4AE775BEAE378D4BEBBADEE1D +:10A22000268AA75BAA47263A725AB1753828ECA647 +:10A230007E113FDDD3C8FDD6E73B5ED7F0BC668F0D +:10A24000D949F9004AE687D47E58F03BB3F804C5F3 +:10A25000C9874B9CBFF429DCCFEF0F07BAB345DFAA +:10A2600047E87DA6A9E38587900EA67F0F917F061C +:10A270000D5B181DBAA52F417EEF9D63797E81721B +:10A28000B5DA437216C1B89C8CE7A24EFF79EF6A2B +:10A290000F9DB366F49089F6FB29EB0DA08D48D194 +:10A2A0001BF07CB1E6F8953AED95CCDE6928B0F369 +:10A2B0006B56A556E07CD974F9607DD1F990E66EB5 +:10A2C0004F223FEF5E0206FA63BEB95DB94758BF41 +:10A2D000A757FA7454055787AFCE7D13E5896D2BC8 +:10A2E000E827FBA2560EED267F77100CF63E123BB8 +:10A2F0004C76941693C142BBEAFFCA345F4C671098 +:10A300005DCAFE9547D7B0F6EA6ACF2CB2CB5AF9B0 +:10A310007EA3B37FB8DF6871A75D257B73D4DFFDB3 +:10A32000E38FD3B9B2EAB2AB1428A88F76D7EA0D7F +:10A33000EF692EA20FEC521E8FD0B92EC8B794B57C +:10A34000B343C73FFC0F2F16F0FD84E2B2D385FD67 +:10A3500066F753CA7E3BDDB3F51F5E64B29CF4F230 +:10A3600038A8A25ABFC47579429C2FEE75E5DD244A +:10A37000BD7CBD9C16EB186716FD6DF48F915F03D5 +:10A38000D76CE47E16980E3F86ADF7D34A819F6D59 +:10A39000EF7719ABBC3F3195D712F2C7CBE4B5AC20 +:10A3A00057928AB74C5E8BBD5E47575B1063F33B99 +:10A3B000560BD93E9CDF35166C467995C0ECD379A7 +:10A3C000FD09FB1CA509E5F01AD882EBD7504C3CDF +:10A3D000871C6C7E3773144BE3AB449DF251691EAE +:10A3E000B7BBE671B6D769877B2151936BC23846FC +:10A3F000EC26C463775435713D7A3DB76CDD644C0F +:10A400009F4758C1F586379A8362E3DAFCBCC36B79 +:10A410002DF4629C5D358F2551FE3B55F27BDDF5B9 +:10A420006FF58A3C962650D03E4BE33AC1F5DB658A +:10A43000F1BC31494F3D6C12FA09C7B956FC4DCAFF +:10A4400067FB940CA919AB006EF436713DD3B19142 +:10A45000DB3DD78324D762FD24ED5F0D962EB1BE80 +:10A4600061D4B6CBF4DB62EB0BF4E48D423EA7DEA5 +:10A470002763EF73BCF7723CC3C26ED637C7D62FC3 +:10A480002AD2BEB6B89EBC5EC8F58D5E614FA437B9 +:10A49000535ED0A0714B02F93CB0C632B7A0D64291 +:10A4A00019C17C941038EC6326DF37223FEDF89118 +:10A4B000A227A8B4ED8152F3EFB603BC3167DE49A1 +:10A4C000B5E7B6F1FD37951DC7BD3FDBF96DA8F9BE +:10A4D0000AF9E4157C6815EB65CA5ECA88F56E5208 +:10A4E0003E90AC5A498C4BCA1238ECADBD425EE48A +:10A4F000007FEFC683F9CF77E13A952316F9D7109D +:10A500006AE3769B621AEB8BE06F9F733E21F278D1 +:10A51000E39977D3FE3756DB49FBDE805E5E7FD85A +:10A52000FBEA1AB841C3B8DD6069FD3156A83FD4D3 +:10A53000A8C7B98E857FCFE8378AF1D9E6534CC4D6 +:10A540004BFBC31B6365E382AEF31553B51E22BEFE +:10A5500094E6DB23E7C3B7319157B763F0E51744BF +:10A560001E82535F2F2EA9AFBFE0D0A7425FBF8DE1 +:10A57000FC7FEEADE07FB57118FF76D9383983A93D +:10A5800078254DF48C1AFBD2148FC1F58D7640A638 +:10A5900083F215200EA417B121EA3BBF6111DF023F +:10A5A00022CEA4363AF719391A70C0B1EE3460BE23 +:10A5B0001AF68B74FBB7AB34AECD6F66B3503E99D1 +:10A5C0006D5FE272427FA4547E9A5DDAF11B3CC655 +:10A5D000394BFBD4C78F207F4F8580F687D2F43B61 +:10A5E000C789BD37515E3FB9EA4348315E2F722EAD +:10A5F00038BD9D02AF17E8B5FFE3D227D693B775F4 +:10A60000931E058F89F1CBFED8464832BC8780EB7C +:10A6100093112C57623EC9121DFDDFEF7A0DDEDE6D +:10A62000E0FE9D4713717AA33A7FEF6EB60F15B324 +:10A630007F2E56B97D7CFA13A9DF625E427AA76449 +:10A64000E0FE76B2274FF6D3A6DC252AE6A55DA26A +:10A65000CEA47A9BF637A96B0BD6E726E0E7FE0C73 +:10A6600011B5508FDAEB4FCDF85E403A4F64785C0D +:10A67000E344E6DFE85CFFC401398B4C3D31726393 +:10A68000D9F57352E86DBBDEC903B285FDA547A4B9 +:10A69000EC02D6FEA462458AE60140969F070BF8BD +:10A6A0008319D92197A7772455D433277B34E967B9 +:10A6B0006C6E6E473A19FE9B324D2AFA6495E89A01 +:10A6C000A13AE7D3A67310F3159AA6F27706A36F03 +:10A6D00010BDA7D873B94C3C69A7D01383D1E2FA57 +:10A6E0002420CE5F03DE6CF1BC0717BDC116E7BAAC +:10A6F000B4F11B16F914C33AC76B38E6A179186E8A +:10A700002CAFC706C43CD8F50663FCBC755049683D +:10A71000D5E0E3D59DF8941A475B75B80BB7F91AE5 +:10A7200048767536117B5FC63802850E0DF49F9E04 +:10A73000923EC4D6CB0F6F0B59520C1F4EE4BEC9CC +:10A74000E898C5FC1DB44F752B2BCD6DC3BC4E19BD +:10A75000306EFCC89FBF917B15FD51E6FF205C6BFE +:10A76000A4D65F6B601E5C52C275B51B953F75FE2B +:10A77000AEFE8E56B1FE18FCD1A1CEB5188754207E +:10A7800021E2191E03F3F568E97B4AEB09D49E67C1 +:10A790007D53ED4AD2E9F28B7CB0A1BCFFBD95D7C9 +:10A7A0004FB37FA87766B9FCACDA6EA7DD5DE37ABC +:10A7B000BF57C86B29BFF2AD1A6726BCACE1B9AC74 +:10A7C000D6E6D1B3581F52B5B8DF466E5100EDF84A +:10A7D0009986DE8B21BE4A7CDF053CCF0DBF8828E1 +:10A7E0005C7F9F51B91DDB78E7A725DC9F4EA197C1 +:10A7F000BD18E1BC594C7EDD76DF887182E2894369 +:10A8000070B4AB19EDF92D1E3A4FDADDB6AFB6B024 +:10A81000FD77C43853F30F86B29C4E65C99F57DB52 +:10A820003C16EE5BE73BFF6E3FB9D2FC376C75DA46 +:10A83000C5E73A2F2F21E2CB2ACFFF858E63CFDBEE +:10A84000F4F5C1F566E39D2F521C67CC2CAF6FA6C3 +:10A85000CFDBCB346F9136B08AC5717E2CF6317761 +:10A860005E9F062930313FF115BEFFC8CDCB63078F +:10A87000CBE81F39EEF23F443FF90F021CC5FD56ED +:10A88000312A7C0F7778BFC2F6CDE0F62BF72B4B41 +:10A89000313FCBA23CAFD11E8B9E4FCEBFCF23F01A +:10A8A00095C0B35CE81583CE3FF72B646F78E02C3E +:10A8B000C6414007C3963BC07A5DFB158AC7182284 +:10A8C0008F80559D89ED80F4D2624CF6ACA7737AE7 +:10A8D000EA073BE271986E0EB386344F5ECB22BC22 +:10A8E000948C7627E3E72EBF800D01D70A581770A6 +:10A8F0009380611FC14195C11897F7667482030266 +:10A900006E12709D806B053C5FC0D23E8277A9BC01 +:10A91000BF9D4A96F71F10B021E03A01EB029E2F2F +:10A920006038C8C7F77118F7438283026E12F00CC3 +:10A9300001D70AB859C0D241824BCD5F206E117F3A +:10A94000A7E6BF8BF30D40F89B0917DC3D55BFC050 +:10A950001F1DEC31A4C2F3436F89F8D3121FD73304 +:10A96000131D09CA5362FE42FA44E1B963ACB8BC94 +:10A970005BA2DDE4B97994D52B1ABFEE2DBA2EAACD +:10A98000C56FDD79E2F7DEFF20FC6EF6D9EB9EFBAA +:10A99000E7131D26E1E9EECFDD0EED2D2838A70FD8 +:10A9A00028D934C66B988D44FE8E5773E6B3DEED1E +:10A9B000E3E79CBD3E9ECFDA2FF09BE8E0E70F83F4 +:10A9C0000B02D983D2F438E35FF8783CE1FB369E82 +:10A9D000DA61F27B8279B662C90FE27ED468BCB3D9 +:10A9E00042FEBAF2FF0AFD65771CE4DFF01D1B276B +:10A9F000102ACEA7BB27F5CD2DE913ACAEE667CF65 +:10AA0000D19FD1A3B1C6C2BC69F11E248F4CFAE517 +:10AA10000CAB67E78BC8D43F8F1737F278B12CEABD +:10AA2000D3384DFC3B066B09EE33EC798B18479A13 +:10AA3000DEAFBB5DCE57C7E74BE063E7A7C8F01CAE +:10AA4000F533898F92207EB99F631EB21EBAF0E75C +:10AA5000170A7B8D12E365F8F94BA5F69F15F232C4 +:10AA60004D3E4BCCEB7FF3D976CA610BF3816C3949 +:10AA7000B2E5EB7CE5E882E50437A4B6D2729286B3 +:10AA800014AD1B055DCEC5E72E2F45E4245758BFF6 +:10AA90005EAB15E7F926C90BC34721B9D5393EF599 +:10AAA0004BA2D49F846B7C21F62060E403A3F75271 +:10AAB000AD56F081C7290278CE58D09E1147F84A8A +:10AAC000B224F43EAFB746E3EB7C756723C71F445F +:10AAD000FF2E7C597F5A617F3234BAE49CE3FD7EBD +:10AAE0008DCF2FAB4FDFF94D1B5F91085F191269B6 +:10AAF0000F6BF75151DFADBFEC7287C06FD4035BB2 +:10AB0000F977920928FCAE32A879C4778F7C9DB979 +:10AB1000F59317E56AE9F9CB55B57ABD5E2BBEEF23 +:10AB2000303DDF82F1BE52FBCE316D723F6811F3D2 +:10AB3000764EF3FE6BD443CBA6E6B35A7C2F15E3D7 +:10AB40009E2BBE27A7E35B959CBD21F444B5F8ADD1 +:10AB5000394FFC5E76E1F756C9F519B11F558BFFE9 +:10AB6000FBCF531E7E309DBF55AD238F766EFCFD0F +:10AB7000E879E2F7CF6EFC4AAC5B55E3FC4A0397F9 +:10AB80000F459CBF548B5F4F65FC44BED8BA012B68 +:10AB90004EF61AF9E3BBB5750369650A3F0BB85E5B +:10ABA0003FD7F1EFAF7AFC770F58CAD4F88F68EF30 +:10ABB000768CAF2826095BB5E33E5AEDB8E9F73944 +:10ABC000E87E7AE47D8E71CF97EF5FAC7AFC5B1DF7 +:10ABD000743F3772AB93EE9049F9C4D58EFBCDF339 +:10ABE0005CEFBF14F80635DDB10F94B2DFCF08BBC0 +:10ABF000F6839AEE90E352F5DF10F6CABBAAAC7F5B +:10AC000052F4DF6CE353A1FE3D02FF7BAAACFF6B65 +:10AC100081CFCA2AF1F9BE5887A5F6CF80E07B1014 +:10AC20007564815F73A1794B5B7C49C98FE79CCFC9 +:10AC3000F4D077826F289A8EF14EE802B2C7FDC732 +:10AC4000C307795E495AF8FFC9B4C4F530C5B7BC2B +:10AC500051D3711E67FB5D8A92B08A9DB7D5FAB950 +:10AC6000FE9374B39BAF7715300FA954FDA0BF7846 +:10AC7000FCA5062628FF0462E21CE9CC8D46D173B0 +:10AC8000022541792DB2AEC24136CE40ED46A33009 +:10AC90006F396EE313B3081F55E7F8A88A6915CB1F +:10ACA000539EE3E7F36AF763FB87526C02F83D0EAD +:10ACB0001CBF417FA21BF3C4D3B52AF16920EC3C31 +:10ACC0001FBF49F4F34E41DF80B77C9E58E7CC7636 +:10ACD000CA57EA6FE7F94A069894DF39102A7FAF1E +:10ACE000C1580F8FFFEF14F94F23F8FD287E4F8CCA +:10ACF000DF8F2EC4F65FA1EFF04EB57ACADE8F1358 +:10AD0000369D71F6608BF37B1E3B2EEF379CDFF593 +:10AD1000F862CEEF7ABC3315CAEB1A08F1F3814A18 +:10AD2000F8DB79EF76BD6125A5E945F994759C0BB3 +:10AD3000F8624E7CDF3EFEF1F641EF61BD185E6FBA +:10AD400015DF4AC51B26E9AD515359AE371CF91919 +:10AD50003D42BE7C355A0AF532D3BB25DE0778FB6F +:10AD60005082F243B458C2A078B4D807345C0F05BF +:10AD70007CFAA4BD2E031E3BDF98F23A24C3A2F353 +:10AD8000470DD79134BDDDE4BCDA72FFFBB5315A13 +:10AD900027F51AAD13C998A0EFBADCE32CF45BFBDE +:10ADA000FC783EE6B71EC0D2FB0739596CBDECF506 +:10ADB000733DAADD9030B4F9E4AA92DDE3C6E34B1B +:10ADC00062FD856CFCD316E55F548BFFA355E26FE3 +:10ADD0008FC3F0FF1CEA5986FFE7B12C85FF534271 +:10ADE0001FD581D14B7BB6C1F52CC07AA330BE1ED6 +:10ADF00008F07EEB849E02E870E4F578055DD5D21C +:10AE0000F3ACADD72AD0638FCBE87951CCC777CAE2 +:10AE1000CDC7B7053D8100DFB7B40309832D4DB819 +:10AE2000B8C4BC9C1078CC0C88B852BAE39CE4EA55 +:10AE3000A52AE93831352FAF8A79F9E772741C17E2 +:10AE400072959161E549DC4F9BEDFC850D8E7999FA +:10AE50002DF893F1D9F3D2E99897DA739C975F555F +:10AE600049CFECA979392DE6255F4ECE0AEAFF5E7F +:10AE7000D4FF83A84F76E2ECC0EF06F0BC6CA13F94 +:10AE8000E109D44FED6FAC9E1C583655EF93A347A4 +:10AE9000EC7A3EAAD735594F0B14F407E9D706F0E0 +:10AEA000FC7B507CFFF1FDD1F035A25D84DADDC082 +:10AEB000E961ED6A0AFBFFD2E82B76FF33B05EEF63 +:10AEC000DA3FD8F5A285F56607FE60D78BE173E916 +:10AED000C0647F0D85789CF0FFEB00CFD771E57BD8 +:10AEE000E9D5E53B78A349BACFA10EC2199995439C +:10AEF0000ABF5F21CD8CEA43983FEB4BE6A00ABB2B +:10AF0000CBA3F1763E666FE1F9F10C1D9EF71BE8CD +:10AF100082987080BDDF1355C81FB8D39F6C0BD4C7 +:10AF2000733C290FE0556E8FF586DA441C85E3B536 +:10AF300037F88111EC4F677861FF9F0C469EC7FA86 +:10AF4000FBE6A894CFFBFC9CBBC84EDCDBAB00BE91 +:10AF5000DF7B9D4A76E203AF86691F1E54CC9B2897 +:10AF6000FFC1520DB41BEF0EFCE118E6298FF7D696 +:10AF7000E8D255440FE19FF640A29FFAE776E776C4 +:10AF8000863FE603D3D685FD76713F06449EF3DD0A +:10AF90006B0DCA9B3180DFDF34DCAE529ED2DEC641 +:10AFA000F91D38DE03ED1AD91D0FDC30BF97F2B959 +:10AFB000DB0394FB56173224CCEF89AC50013F04DD +:10AFC000A98B1ABD6877869707F0CE2FA86BE4E3AC +:10AFD000851702DDF3E7854C22CECAC8884AF738C8 +:10AFE0003D70C386DC66B46BDA79FE3223ECE5F89B +:10AFF0007280906025C83F00C4C73B9B9FE7DBF38E +:10B000001CC94CB62F7B8E18C956592F575DBDF001 +:10B010008842F9C915EB65AAAC97ADB25E8ED7AB85 +:10B02000787E2FF22935F60FE3707E773E76A8FC06 +:10B030007771E79AAFBB37E0CCBBAED4DECED3ADF1 +:10B04000442F1E664EE22957AE6FE7D9957AEF9DE1 +:10B0500079570CBF4B1BAEBF5794F7F1B2413C6F11 +:10B06000D81EA3FB221BC4FB86FBE8FE48773F7F6C +:10B070002BF4710B24CACE439DC0FF75863BC6B32B +:10B080005B940AF900EE7C3F97DED3947427ADDB26 +:10B090001B787ED1E4F7938DE2BB114825E214CFF3 +:10B0A000B2228B674EAD1FEFAAEFD2FAB1BF9B64FD +:10B0B000F3C3BF9774C9895B2E7CAEFC940B959348 +:10B0C0001FBF4D72E21D91AB5A3FDE4C95F5B25554 +:10B0D000D6CB55574F1D91AAD22B6AA6CA7AD92A28 +:10B0E000EBE578BDC195AAD8D7470731BEE5BD428B +:10B0F00073C08357049CEFAF0C39E0A165CEF6EA2C +:10B100007267FBA1E5CEF6EA0ADEDE0CEEBF261D75 +:10B11000AF7E9DFCAFF35C272D5AF9FAE1F60AEBFE +:10B120004AD3FDD8BE4E3100EF1762FB5556EC5B9B +:10B1300045E33FEB827CFD5F17D01DF7D3FDA9D31C +:10B14000D912E4F8DAF456C2D7D6BFFF220BBBAB54 +:10B1500044DE3D7E564079D830DE80FD3D7FCFCC49 +:10B1600006B4E7F6BEB682EEEFE87F979D376352EE +:10B170003EA472EC9764BFECDDCEEF977EB4D6ECC4 +:10B180008AA3BD12F600DACBCC8DA27B3DF6C63C7D +:10B19000648FF45F5DFEFE924FF5F03CA187D1EF26 +:10B1A00067FAFF80B877EB4171EFD6FD3D0695BB9E +:10B1B0007B5AA8DCD5635239DAD3CEF3197B2CF154 +:10B1C000DD5917955FEA49D0F32FF47453F9F99ECE +:10B1D000243D7FAA672B959FED49D1F3433DDBA921 +:10B1E0007CA2274DCF1FEF19A1F2B19E0C3D1FBAD3 +:10B1F0007A03DD9371EA3E0F7D1D520AFF392967FC +:10B20000DC61F65667DCA121E98C37CCEA76C61BF7 +:10B21000F455F31DEF236DEF70C0A1D6258EFA8192 +:10B22000F8150E586BEC74C04AE89D0ED87C6E83FE +:10B2300003BEEC999B1D70EBD39B1CF03B3EFD11B4 +:10B2400007DCF2A93B1DF0C5FBEF75E0171FEB73A0 +:10B25000C0EB83F3F97DE0033B1DCF8DFBF639E0B6 +:10B260008FCCB41E0B623C3413E1F6EC7189F6C14D +:10B270001973CDDBF03B29F8B14CF204519E0F3F1E +:10B28000637EEA72BCA70C94D48A1BC395EF91B677 +:10B29000E33D72A43D89F27AFA35C9407B578A6C46 +:10B2A0005F58E8CFD9E5D65329388C71499167A604 +:10B2B0005F0496C5DA05983EA1C34548E57650DCA3 +:10B2C000D243DF5165A424E59B309BD9FC2B1DF3B1 +:10B2D000E8DDFB6F90ECF253519ECFDED1A9350D26 +:10B2E000B0FABB17A926A6784DC3D775BFDDAF82CC +:10B2F000DC0FDEB583C72BF517FC4D1A6B1F32939D +:10B3000033D055B5DB8572DFA3EF944286B91CFDBF +:10B310009A503C039B43588F7FD7C7EA7F3558200C +:10B32000BFA164CE5259FDD89664B387D5DF2DFAFC +:10B33000DFBDECC7748F6038F713B898FC9DCFD091 +:10B34000F8E1B6A3707B18F5D338AC2BB28E77FF3B +:10B35000BEF8F748E34199DAEFEECD82C9DA05721B +:10B360005FA77B38ED7909B61E8524F6BB6A82BEDD +:10B37000A1DDBD43A27E764B2FC56282CE5E179DB6 +:10B380008817D2753BEB27D49D94D6B5F2E7CDE173 +:10B39000A97EF1FD667C7F4B4AC23CF76AF8A72282 +:10B3A0009F928C7FB8DEB664A4B2FC337216F25B57 +:10B3B0008B57E2DF839C7F8C6FB7B74EE7D764FD76 +:10B3C000F45158DE5AC06FD11EF9727B11BE4EF295 +:10B3D00089B54F52FB97606988B7433E8419DD9B5E +:10B3E0008BB5935E12E3649DE3303EDE4ECFD322F5 +:10B3F000BEC8EFF5B4F344ECFAF8D7B55CE42932F3 +:10B40000BABDE3B59BF1FBEB8ED624DD033C18F20D +:10B41000D0FD4283A1AFE4E89E7E1DE8FB5945B113 +:10B42000FA7E14E571E83EA9D83A75FA09F8654A3A +:10B43000E1F76403213B0FBF82BD24EE1596C5BD25 +:10B44000C2AA92E86AE2EBD9EC85A9F8EAF4F1F72E +:10B4500011DD72CCB9FF0E6C71EE7B71FD668A63F3 +:10B46000F747ABFB6EC897E7F6A52AF0F1E683FC39 +:10B47000BEE3BC9FF0B4F233A85C93AFA5F2AAFC84 +:10B480006C7ABF3ADF40F0AA7C33C157E69BA8BC78 +:10B49000227F293D5F99BF84E0F6FC522A57E417CA +:10B4A000D3F3E5F92B095E965F49705B7E2D954BD2 +:10B4B000F31D542EC95F4FEF17E7AF23D8CCDF48F9 +:10B4C000E525F9F554B6E4FF8CDE2FCCDF44F0C55A +:10B4D000F9CD042FC8DF46703CFF51829BF31FA6B5 +:10B4E000727EFEBF52D994FF18BD37F21F27785ED7 +:10B4F000FE1E82E7E6FB099E93EF25B831BF8BE085 +:10B50000D9F9512A2FCA3F4065437E2FBD9F957FB1 +:10B5100088CA99F927E8796DFE712AF5FCE7C57D9F +:10B52000D14F5119C97F95CA70FECBF43E94FF1BD1 +:10B530008283F9AF5319C87F9B4A2DFF3C9595E64E +:10B54000A9D2F74F6B6086432E56E72F72C0574E35 +:10B5500038F7EF953F77EEDF2BC69738E065C79C4D +:10B56000FBF7D2A39D8EF78B8FBCD3015F9273EE56 +:10B57000DF0BB3CEFD7BC1814D8EFACD998F38E0C4 +:10B58000A611E7FE3D2FEDDCBFE76CEF73DA2FA9C4 +:10B590009D0EB861AB73DF9E050FBBF2C90F3AEA8F +:10B5A000D7589F73D40FB77FC575BE92E5FADFFCFD +:10B5B00086D38E6979A1E8394C7CFF75F4DDFEA94C +:10B5C000468FB86748DCDB2AEE4773CF679DD00310 +:10B5D00033F2DC7F8A8A75578FEBAE20EF89D91959 +:10B5E000AFA17EB0ED8C19F38D2FBFC8E0D373559A +:10B5F000B397C1B69D61D7AFF8BB15AA399E6678DF +:10B600007A8FFBE8DE3929D26D615CEDEE1312DD35 +:10B610006F57371B449EC0755D3C3E01F67D3A7402 +:10B62000BFCFF01CFBFDE66B298ED1C4E123A11D29 +:10B63000EB308E3AECB5DF7FFE5A6AEFE7F0FF0899 +:10B640006D19C2F775358763681FED2A71BEF93F22 +:10B65000432AF1B33664FD30B46CEA9EE9E3D1E4E9 +:10B66000CB21F67C9B969C875776E33DF7788FF34A +:10B670003AC5FA11D65BAF58AF84685F70FA0FEF26 +:10B68000C7DCD765742FE04FF0BD1C7996F6A3BADE +:10B69000EBEFA3FBAA86C30C9F50697CFE3E244FB0 +:10B6A000EE3760EF37F3299E4AF6E05013D0BD190C +:10B6B000C3B58934DEE797FE8E06874CA43BC3935F +:10B6C00095447EE2F025862D178EFD092091C33822 +:10B6D0007E301932D05E0BC151CABF88C004953A82 +:10B6E000E892E3BE6D9BFE399C7EBCFF3F44E7F0D1 +:10B6F000D6B3E314674D81B8BFFA4D7CCEF8723AE9 +:10B70000B4AC345FAE91EF039D8DFF28B327918ECB +:10B710004781E33B86FEA98478A6F466EAD7798F51 +:10B720008472FCEB243776BC47915769CD488FB8BB +:10B73000C7A18BFD43FBB03E513EDEE3BEB7E15CEB +:10B74000E33DD1B03BDE13A2F3E453ADE5BF83B3D9 +:10B75000E33E63ADE5CF7B9F157EDFD7C479EF3342 +:10B76000E2BCF72BC2EF3B2CFCBE2FA2DFC79E3FF3 +:10B770002DFCBECFA1DFC7E027D1EF2BF8BEE4C977 +:10B7800012F7BF2CAC95849C6D27FB3E28EE2B62F4 +:10B7900023903D1F10F6FC98D93713FD8E602D6461 +:10B7A000D14FD87ADD41FA7E969162E2FD0077FCB6 +:10B7B000E2F599FF85C1F11838EE770AB4BAEE4B7D +:10B7C000A8348E92B5B0DF20F31B326669FE9C73FD +:10B7D000BF5A16FCE7D52FBFE7C7BEB78D71328DB4 +:10B7E000F21744BA7594ABBFA1714E897140FEC186 +:10B7F00011BACFF07205CAC9C1B471CE51FEB68478 +:10B800005DBF4FE1923FC0840D46EF3CF1BDA611F4 +:10B810004A37EF61EF9FB84F757C9FED96C7DED733 +:10B820007C14871D5CCCEFE579B17EDD45E80F7EA9 +:10B830007AEF9B4D889FFDDD52BFE98C5BCCBB0F3F +:10B84000A4C27C9603623FE8D7CBCBB97DAF78FF2B +:10B8500058F97A0F8A7A5F0C5A7D61D22B13741FC4 +:10B8600064FB89AE9B11DFC77668745EE36EF7C533 +:10B8700060726778D9743C0BDBA3BC9569BFAF5C81 +:10B88000FBE53FEDFA29946FFF70B8BE74FBB697E5 +:10B89000BB1EAE80FFC1E2E3A71FC376F3623CCEBE +:10B8A000D4DB3044F3BB6B07F79F5F5CB48EEE993B +:10B8B0001DA8E5F356A4DF2F54E04B7705BAFEAA86 +:10B8C000527BA93C5DDF2CC717C6D76315F8F29DE4 +:10B8D0000A7C3D5001FFBF2FC1D77988F73CFC7D22 +:10B8E00038D6AE770EE32BFA6FC85798BE1E8AF48F +:10B8F0007BAC1C5E55C8EBF805CAEBCF2BF0B592BC +:10B90000BC4E5CA0BCE64BC92BE27D01F22A47CAC3 +:10B91000F3B592BC06231726AF33CAB5AF425E67B4 +:10B9200097C3BF0A796D2E36BE0F8216DAD5A75A95 +:10B93000F939D9D60E7E3F99B785EFC3C1E39F256C +:10B940007B6980ED5733DA71DF3EF1E01D6D53FB0B +:10B95000B47B1F72F7E7DE47EFF8DF9FA17D342449 +:10B96000F67D1B1FBFE1EEA7FCFD16E73A6E007FD8 +:10B9700097A9E0F72E1A926FF578CE7D3E60F2F12E +:10B98000818DBF96CE159FA673C59AF60B1DB77C09 +:10B99000FD59DD1766177C28E2B40B666FFFEA637A +:10B9A000741F89E867B662D1EFF8297035BFFF646C +:10B9B0001BCF1F92B77FF9B1934B0BEE9982C35205 +:10B9C00061BE90BCEDF063270BF0CA63FC87C79B98 +:10B9D000298F31AE5F11A07BEBC6CA9F67FC40EC9C +:10B9E000E3DF17E71947C479C677855DFBA2B06B23 +:10B9F0005F10766D4ED8B57F2BECDAE7845DFB0DDA +:10BA0000719EF1A0388FC8F41C20784F4F56FC4E21 +:10BA1000C993E2774A0E8B7CC967F9B9454F8EDB33 +:10BA2000C78F7FAD19F93145873B8EC5E9B0EF4728 +:10BA300077D3F12ED379DFC6F52D41C7BC5D6738CA +:10BA4000E322D7C6663BEA5FA3373BDEAFD52E7550 +:10BA5000BCEF80A5CE384BFE0A679C65C21917B9AA +:10BA6000F2E7CE738D95E3CEB8C88A63373BE32CFB +:10BA7000479DE71A4B8F38E3228B73773AE0CB9FD1 +:10BA8000BDD7517FD161E7B9C6A54F3AE322B3BA1A +:10BA9000F739E05AEB61E777F5EDCEB848D874C6D0 +:10BAA00045822D5F71C0EF61FB3DEA4FBFE18C8B9A +:10BAB000F862CEB8C84F43FC1CD0F6B359BBBF8B5D +:10BAC00090BF19CA5DC9E4FD8928BFE7FD09485246 +:10BAD0009E2CC09F93DFA04CFA0D16AD7B59E81D3C +:10BAE000B5E1E48FD1AF517673BFE70E69454E2BB8 +:10BAF000F47BBCFF2215CA87ACBBFD870AFD7B4DDA +:10BB0000F277940A7EC9F47EB9BE9ABAE7BC2D8D4D +:10BB1000F954CAA45F72BDCB2FD996A1DFB39A5155 +:10BB2000DE2F9936CE39EA9FD391127E49CC43FC61 +:10BB30003314EE97EC32855F02FC7B29BB3F5BFF41 +:10BB4000A80DE5F5887D5F8BBA88FB0D4AA8F879CA +:10BB5000B67DDFA4BAB87C7FB65FF37711714F5C16 +:10BB60000D88B8FEFF978FB7523EAEAC29113779DA +:10BB70009BE5A354BD73950F057506E5837C70188E +:10BB8000F3417C2E581370CDFDDBD6E1F74DDB8100 +:10BB90009FEFC02BFCDED552FDDBF95DF155B7966A +:10BBA000CD83B0E3AC522D3FFF8CB7DF4AF993A7AA +:10BBB000D818E5EED576E75BC8D114FEE81E7ECF37 +:10BBC0005EF4DCE79FEA785C28DEFD81B2F68AFB52 +:10BBD00077C1E256F97B764705FEDF7E7516D9A957 +:10BBE000BBB6717DAC747FF37994C74FA33C9A14B4 +:10BBF00057D12E41BAB62974AF5AC8008A0FCE0D5C +:10BC000041B6B709F96AA6F13E2FF647E7CB93F2A2 +:10BC1000B9CD79BFC9EF74BE9EE389F27CADF8BBA4 +:10BC2000062B0F77D0774206A4F45A5A3FF07A9445 +:10BC3000F023391D6E37F9EFDF317C747D7A7B3765 +:10BC40005EEEF5A96CB98AE24AB3257B7D064DCC40 +:10BC5000D739150A95BDEF6D5ABFE7B81EBF306DD5 +:10BC60003DDED0F78F38EE9888236D677F05E79D1E +:10BC7000EEFEECF568C3DF7EF56EFABE6578EC4E3D +:10BC80007E6F71A3B81F6C8CEBC752781D1272B413 +:10BC90005BD88587F677F6217F07D8BA29D4470B7A +:10BCA000FEF2BD81243F5FACC3F23307F877DB17A8 +:10BCB0003FB4453CDF44CF1744F9FD470B983C6146 +:10BCC000CC3BBCEC158DBF7F59A7FAD1F1117C7F1D +:10BCD000B178BFA7BDCDC2DFAA8CD4CEEFC4521EAF +:10BCE0003B4A7A97CDB9B5C0C07115FA1D9DB923ED +:10BCF000F038D231772CB1E13AF40FD2C07FAF2DBA +:10BD00009ADC89F21AC900F597060E1BDB759ABFFB +:10BD1000F858721FD56FE5F5D97B82E7A6F8FBE0EE +:10BD200018C317C733D97B03DF73FC1BB7E814AF05 +:10BD30000B8D1D4DAC257FC46ECFE1865B787B6596 +:10BD40008CD183ED6376FBF10CBE9F15E5EDD5310B +:10BD5000BE3FEE69DF44F7EAB1F1E9DE29AF78FED4 +:10BD600084E07FBCFB5F336BA35379196966FFAE38 +:10BD70002FB29EED756FFF0E60BFF80E49D3663F80 +:10BD800072B2E05E06FB77430363CEFDF94C0D5FB4 +:10BD900097FF1DF5CCB2CAF7B3FD3B5950D3F30062 +:10BDA000800000001F8B080000000000000BC57D14 +:10BDB0000B7854D5B5F03E67CEBC3293E4E43D79C0 +:10BDC0004D4E2040944007081810DB495444458DDF +:10BDD00068DBE0B53A04E419202296A0D89C9004D0 +:10BDE000F20206EB2F111126281A2BE86041B15AF6 +:10BDF000EF80B9147B6D9B5A2FA2A28DA05114B86D +:10BE00002915C9DF5FAFFF5A6B9F43E64C2609EA4D +:10BE1000EDBDF93ED8D967BFD77BAFBDF60E6B102D +:10BE200059C8C6E8E79B61F09F1A63CC5725B2500A +:10BE30007E58BE32C3989F3BCC58FFF64B8D79D7C6 +:10BE400078633E798AA1FDF91B18EB744246F2D85B +:10BE500018A4D2D1DB6CA56318AB4D5E4EF9DEBBE6 +:10BE6000F4726F0CE6F3E418912533B6AD400C3450 +:10BE7000E532F644D5F2C3C320BF3659A43ED7BA43 +:10BE800066C6FBA0DE37F8F3A3FE69433563212BBA +:10BE900063DBABFD946EAB6EA5B43E79F0767BB5FB +:10BEA00076CF57DB58681463C16A99F2CF56BB2826 +:10BEB000BFAB5AA1F457D5F9F4BDBDDA43F927ABAE +:10BEC0008B287DA2DA4BDFDBAAA7537E6B7529E5B1 +:10BED000B7549751BEB5DA47E9C3D50B28F5575784 +:10BEE00052BAA1BA8AEAB554AB94365537D0F7C0E6 +:10BEF000B860596941FF79D6CA00871428BFDA9320 +:10BF0000510AEB79FC6A56168C5A4FA07A1B6500D1 +:10BF1000DA44C6DCCCCF1C85F07B2B633B15C6EC2A +:10BF20009D7ED50970BD74177CC37CC8AF3A209F35 +:10BF3000FF04CF6FD2C6A962CCCBB05D150BEC0469 +:10BF40007CD8143F9B0DE379B35576732C63376926 +:10BF5000E3E07784AF9AAB32C4EF098BB7544EC19C +:10BF60007EF8F8313E9F00CB63692B588D05D28453 +:10BF70008A2E668771E21F0A796D900E6BE864BEA7 +:10BF800002C4AF586282799CF38B011374AD4C6587 +:10BF9000A208E337BB383D44AED3DDBB8D852640D8 +:10BFA000BDE42E3B8EBBAE6A663C8B020F3D1DDDB1 +:10BFB0002EF6D127FCBB2410C60FF06F9D7FF0F644 +:10BFC0006965C6F609DE88F605D01EE0102806FC75 +:10BFD00045A1B7F82263FB584F447BD7E0E3C7F491 +:10BFE000DEC8424903D3F3294B790DC25DCF8FECF4 +:10BFF000FD21D57FD729131E12AF5FED4238C3CF85 +:10C00000550867298B059A04CC7AD902C89BE1B7F9 +:10C010002699E76D90374990F7403D55F1B2B198B8 +:10C020007ABC2C0E532FE50F997D1BE589982FE5DF +:10C03000DF651FD141E012E82203E58DD2E0CD8219 +:10C04000FC8FE1F7298CDD2C8F9EAE42FEBCD927F8 +:10C050005641FFCDD9626007E075A57B7C0CAEFB35 +:10C06000F196C1F9B416F974545FDEE4F43201FAC2 +:10C07000C9AC90C79BD8C0ED1EAA10A707A2F4BBFD +:10C080005BA3DFFA8A99F2085C7507CA30C6AC4E2A +:10C090001695DE60BDBB71BDE664BECE945B4B29D8 +:10C0A000CDDB35D9560AFC703E7670FC3546CCDFC8 +:10C0B0000E4306A3E1519B57DE1B2F91BC3C3F86EC +:10C0C000D3D540FD366BF2AB3720B24EC4AF544AE5 +:10C0D000F235E5561FCB83F5AC4B17034E58CFBA5C +:10C0E000AF6F69C8057E5237892407F4F9478E6B14 +:10C0F0002AE8124C50BEEEC042A6C0F8665729533B +:10C100000B30AFCBEB20C3FE1DCE90175390980C95 +:10C11000D7EFA8F2A998B7B854E2E775E917EADBB8 +:10C12000102ECD7E91E4FBDA2C31C0044A9913E63F +:10C13000736E35A37C4EFA838C24FD57309F49D013 +:10C140000FFE6E42783355C475E4325A471E3BCC1D +:10C150004CD0CE3686799AA04A7C1E3B80EDD6A57F +:10C160007F79C08AEBBB97794628D8D847F2080870 +:10C1700094A11C595B2953FDCCD6B1C417FABA7FE0 +:10C1800062F17D1ACE3716179767EBBE364595AF2D +:10C190008735F9183300FEE21378F97973F05A9471 +:10C1A0009FCD90DF11859EEC5ABD47E5997FCA5718 +:10C1B000FAF8532F7FD7A910DFEAF9CC5E0BCD3BFD +:10C1C000EFD69FC5E3BA06A287B51A9DF9E3B9FC7D +:10C1D000CD9B7A8517E17E0EE68AFC1E597F51BC05 +:10C1E00042F3D0F392D328A72E7E7E12C9E3BC532C +:10C1F000AB383F640F4EB7FA3CCF671BED04316F8D +:10C20000818A7C5DAF007E15B417D63091EC02E6D2 +:10C21000615C45B138C83FB15A935FF95DF64B2078 +:10C220006F7BCBC410BFDBAA4A4415E09E932B055D +:10C230004C00F7F82CBF97813DE2286002CE1FF03A +:10C240003D322105E96012C1337B754810A1D31E30 +:10C25000947D29B4EC3AD7243E0EFE077C3F26019C +:10C26000D6E9DD2570F9E0E2F2C10CD3B191FCAC66 +:10C27000624118CFF19689BE033F841E807C8C2CCE +:10C280007A509EB678D6A4221F3A1218E9B505D77F +:10C29000EE20B905F2D6B30556B4F46477EA32C895 +:10C2A000E7B9F87A74F8C414580CFA61C871A4801C +:10C2B00017FB7508CCE3F70CA247BE6DBFB600B301 +:10C2C0007FA77E4191A4129F683FEDAA80E3E0BA68 +:10C2D000A15F2B7B99C639A78DC34C6F1C467E8905 +:10C2E000F981C44C51F865C0714CB70FAA37AA8EBA +:10C2F0002DFC5347183DDF95109BDC3D1A7EB98C11 +:10C300005DF60D2A0E13103CCE03EC4E13AD9FAD1F +:10C31000413CE7C8DCEE509CEAF00D50FEF86A0B99 +:10C32000C90FBDDFF3D50BFED401486C29E072BF05 +:10C33000E6436B09F6533F4E0C58A15D47CAB48CD7 +:10C340002EF8FEC4A62F73717EBA7D5AEB31F245EA +:10C35000CE6A4E977ABE55E38B5A79707DB241EF23 +:10C36000AF65F07A0F6BF59E75786B918E81D20573 +:10C37000E4CFA2E3D36FC3F96E7FC0C64C51E4C2D1 +:10C38000B30E5F73C2C4FEF30C6F8FF43648FB5FCD +:10C390000ED67ED2BBD3DF6583B77F342165E0F64E +:10C3A000856F4EDF32C4FC1F8F3EBEBA1DDBE5B881 +:10C3B0002C0CF15B93BE96F0DBFC80C563057EEF31 +:10C3C0001833CD8578AB4BE0788BD2EFB383CD0BB0 +:10C3D000E05236C4BA5E18AABD30F8BA5E1D02AE8D +:10C3E000478780CBA1C1DA035C5B8798FF1FA3CF8F +:10C3F0005FCDC179E7645948CFD464035C518E2383 +:10C400005C597F7E88D2EF3B43C065287AFDF07B84 +:10C41000D2EBC9C1C6BF087AFDDBF7A4D7FF3B103A +:10C42000BDE2BCBF07BD4A89DF8F5E9D8983C375AE +:10C43000287A4D1EACFD45D06BD660F3BF087ACD8F +:10C440008B36BE9539BC2ADA45055C9F2F281649E4 +:10C45000BF9BF3B91E761C7BCA8BEBAA037D955458 +:10C46000847AFBF8C34B0BFBF474A41E8AEC2F52A6 +:10C470008F2EFDDB93A4479D9ADED7E7635722FBFF +:10C48000F99741EDBB6F3B6E8C8B85EC63FBDAA7B4 +:10C49000FBFEBBC733EAF9180F1F9FC1F85716A15F +:10C4A0007EDDE541BA8C2FFABEE30E5E3FADECFBBC +:10C4B000D9050B12C12E70F4D9059955BFDEFE5176 +:10C4C000525F3F999297C9403712BB8AEC3756C1E9 +:10C4D0003C3BB1B86ACFF68F26F4D903007F01FD4B +:10C4E00023FA38A68AE0F68FC2E6D53B9769FBB4FB +:10C4F0004ADA17E5C95362908ED7B50C6E2FBFA1EB +:10C50000E9F1DF6B7EAAC39A9FEA10FAA920ED40F9 +:10C510003F15A407D14F05E521F45341FE55CD4FFA +:10C52000F58AE6A7FA8DE6A77A58F393F9D14F4634 +:10C53000FEA880E68F6AD7FC51414A1BAAF753BA7E +:10C54000B63A44F5DADB5E188EF0E85B07B7DBF34A +:10C5500064DDBFC7D7C158298B86AF1B3C26C3FEFD +:10C56000E2FA7C87016FD72A4986FC35AE4C43FD41 +:10C57000ABE5E186F22B6DA30DE5C56C8221FFA32F +:10C58000DE2986FA57F49418F2977F7A9DA1FEE48B +:10C59000AE9986FC65476F33D49FD8596E289F703B +:10C5A0007891A17C5C68B921FF83FDF719EA8F09B6 +:10C5B000AE31948F6E6F3294A7953D18E167DA62C1 +:10C5C000A81F5FB423C28FF42B43B923FF7943FE26 +:10C5D00026D0F728FFECCA6F0CEDACAE8386FCBF0B +:10C5E000C531DAFFD89D41AF378A3DF9553CDFAF01 +:10C5F00082DD5E4CF632C8B1A671D8BAD28FFBF19B +:10C600004CF81DED63C0AEC08643EA31CA1D5385A8 +:10C61000C538FE10FC8C1E00ACEF861FE4C7AFF4DB +:10C62000FD6CBB5DFD218E9FC7E5B02AABE47F8822 +:10C630006CAFFB8BF2DA67C563799D5C2247930789 +:10C64000272CBE93E1FA2172FF9BE78D655E1CAF3C +:10C6500042F797717967E25558E6B16B0E0BE8FF28 +:10C660002A7B3501D7A3FB79D6697C5AAFF991AD06 +:10C67000EC72F2639CD3E43F334DF50C269F22E12C +:10C68000F56DE5999814B9CF9911FA18C7AF9002D2 +:10C69000D1F4A49EEA722CEFAD3B07C58F0E5F1D4F +:10C6A0008F2639E845BD6A532A59B9B33F9C4C5986 +:10C6B000400F71FFFC75E72619E5F839F64AB177A6 +:10C6C000D845ACB7EC0E5A878ECFC87AFA7EAB0548 +:10C6D000F14AF291CBDF5A0DBF6291770DC2370E4E +:10C6E000F6D1B8FF133D21D6F51DFCC08EFC4443A6 +:10C6F0005E726618EA9B3D952C88FE5B1887113D9B +:10C70000FA18FA73F11FFA4B4C3287F3C07C773971 +:10C71000F909CE45D82103F11F0EF1CDF0A1F9F5AD +:10C72000BBF277C7DC54EAFFBE78A6F95F549EAA35 +:10C73000EC4DA49FF2228D8098F2D3F760DE0B0FB0 +:10C740009B49CEFCE8ABED871E03BE341559E526A8 +:10C75000F20CF90FFD16CAE77A6DA5985F786C8C1C +:10C76000C50DE5473280085C585E1A8772E03413C5 +:10C77000A7A3DFEE347B336E42989CBB27C942F2FD +:10C780008535988F77D9707895CEB1EEF2F3BCBE2F +:10C79000AEF9ADC6FC3C3633558271E63D646601A8 +:10C7A00000D642261DEFD2E10074302789FBDFE777 +:10C7B000B3CAB5328C5B6FE6E7364B5E1C63413C17 +:10C7C0002C9C20E79AC6F5CDE3FE2491EA7F06F47F +:10C7D000A658FBBE2F72062C28974FEC9DF093CBEA +:10C7E00019F613589B81FECE04B04394FEF09DD3FE +:10C7F000609CE750EB889C37BA41069B87D42E7823 +:10C80000A3F9D51B9304031E6B6DBFD8DE05F3F4AB +:10C81000D64ACCFE43C84BFC5C493D161BD889F276 +:10C82000BBA4F2A92E8083BAC62AD742BAD9F18B0B +:10C83000E7B07E15200CFDB9CF2729348FF376772A +:10C8400000CF1940DF5C3633F6FBF7FBE23FA9DF90 +:10C8500057B0DF94FEFD2EB17559D09FB84CAA9CFD +:10C860002E88E857E4F5AC669F3713FD89FBC78532 +:10C87000321543BD868BAC7758187651F5A68B835D +:10C88000F47746936FBFDBF5B805E5D6E95F7D78B1 +:10C8900023EE8716BF6C6236A87766572C0B91BDC6 +:10C8A00017B0A0DDBA68AFC91BA07C68D22DB1E17A +:10C8B0007C5D4BFD2F7E2E96F6538B9EB706664011 +:10C8C000FB452F9C18CB401E9C59D3732813E1F7CE +:10C8D0002B81EC67A6768DBD05BE2F92D89DD1CE5B +:10C8E0003DFF9AC4ED8E532F39CA90DE84F603774C +:10C8F00050BFC19F9AAD617AEC489299F009F5C892 +:10C90000DFAD3E2D0446087C7E378F099F5F0DAF5B +:10C91000F734F7E72EDA6F0ED8717EED6D161FD45F +:10C920005BD6FE37A2EF2B9FDB1D877058B6DF6802 +:10C93000AF2E7EEEEBB55300CF8B4DAC6706E9F121 +:10C94000AF287FCE6BEB31911CF2C60920B79692CF +:10C95000C8827ABFFE64DA7B50FE99CBC4EC200A11 +:10C960003EEBFCD8F232E67DCE4AF4682FDB6FE472 +:10C97000C365ED272C382F59643D59C0E83FFC2290 +:10C980008C2F59FFFAB00FB6A09C5D166CFC9B096A +:10C99000E86DD9DED3EF22DD2D8BE0E7CFF097F401 +:10C9A000FEFAD29A1CA92FDF9884FE72D60E9B9FA6 +:10C9B000C903EB4B9DBF17EF3EB74D85F14F3DFFD0 +:10C9C000F93615505EF15F7FDF763FEE8F5EB5CBB7 +:10C9D000289796FDEA3FE25818FC872573F970E620 +:10C9E000E9A79EDC027038F38E95A076E6B79FB873 +:10C9F0001580FB993DFF3715CF9D56FCF6EA34A410 +:10CA0000B315FBAE4C1B6C5F84741BB086E33740E0 +:10CA1000F855F6C33869907D454B23F0726ACF799B +:10CA20000B9E0B7D29B01E94BF4B835F5BD03E3BBA +:10CA3000E4653D08A7D7F69E38741FE44F039EAC0B +:10CA400051F004EBCF1449AF843251BF2CDD7BCBC6 +:10CA50004D5714626AF6288827D643F2BE1F7EDF40 +:10CA600002FC16F6E137B2FC1CFBCA82F05FB60B83 +:10CA7000F03916F10AF81CDB1F9FA7F197C9FDF1E9 +:10CA8000599C6CB4FBCEB18AED5BB0706F12E17F44 +:10CA9000207C2ED9F7E341ED2C5D3E0C05E7050225 +:10CAA0009F576CB2F7E664E4DBE71DAA8BE33930ED +:10CAB00003CACEEC3EE76640279F9A7BEE4038F4EF +:10CAC000FCD62AEF80EF8B7EFB36F1DD997D7FB6B9 +:10CAD00020FEE1274E98047976E1E74D06F9A5DCC2 +:10CAE00006674B58CFB4770B31653DAA87F047F9FD +:10CAF00043C087848FC0CDD31594BF81145AF7D219 +:10CB000000E78FA58103B70A63FBC3BD3959D4F58C +:10CB1000D605BC0A4588CF0FA721FD0D844F7DFDAA +:10CB200032AEFF32287FC2C8BF91F59702BFE2FE46 +:10CB3000A81F7E0307FE88E99936AB24802D740672 +:10CB4000ED04677FBCF7C19FEBE76F6B1FD747F022 +:10CB5000BBDE5E87D350FC3ED4FABE2DFCEE4956B8 +:10CB60000C74A4C3F1D457D1F5411BCA8F8908C7EF +:10CB7000CAE919C3FBEB33132B553385BEF9AE0D50 +:10CB80009A48CE9F6A07BB5CE82F2F96E2396E94D5 +:10CB9000719ED3E4D4D2FD07C6A25C3B75F0258D0F +:10CBA0002E39DD2FDDF5A145D5F443205C3E0F7015 +:10CBB0002EFC9236EF65AF44EF6FD9AEBF45EDEF77 +:10CBC00033C9FB539CFF679D66A642179F054D51D5 +:10CBD000E3191E4FE6FAEFC2BA63271D8DC77D41E8 +:10CBE0005C8C82EBAE5DE37D1BCF45D537CD74FE0B +:10CBF000CF24CFA75628AF8D8D51D08F571B378F9D +:10CC000029617ABC2E024E92AB94CEEFA4E4D242BC +:10CC1000BEA70B18CE7FCD4010E1F306BD9B857AF1 +:10CC2000E983719F98719D7F8DB023FF2AB1B5690B +:10CC3000D0DF5F55C153A344DB1F18FBF7AD36317E +:10CC400025ACFFA5D69E0F703EEC5FED0CED32D308 +:10CC5000AB7601E5C9B26D66DA7F2D836D15C2ED45 +:10CC600093C7EC0115F29B7F5D7D07EAA5FFDC66AB +:10CC700065781EF1DABE95DDAB502E3D2A30F4A367 +:10CC8000FFE74BD55FA25E5EB8155607F264BEA300 +:10CC9000E7496C3FFFB94C560BED3F178293703359 +:10CCA000DB9D129A84FB90EEDDE91E95FA797129DD +:10CCB000F67BE63907F57BE65FDFA671CEFC6B2CD1 +:10CCC000E9357DFE606F2BE17A1CEC6DE5021F906B +:10CCD000BD1D96877116639ED717BED1641ECABF4D +:10CCE000C59802DD2FDE1FEF45FF4A583DEA6799E0 +:10CCF000B5E7E71EDA7FAB1922ED9D4219C88F8B8D +:10CD0000DB8DE37FA3C9BB65969E79BCBE3F83F3F1 +:10CD10006D27B573A668F4AA9547B6D7EBC7A40CE0 +:10CD20008BE887B75F6A6595D1F8204DEB7771FB8B +:10CD3000D7A38CFD71BAED3F0EFF7EAFC0E340D8A4 +:10CD40001E3BC5A35558422313816F5FB0B005C881 +:10CD5000BF1571A1910930DECB9ADCAC88813C7C97 +:10CD6000CFD0E681F531CF6C5D6710AF4B5EB4D3A9 +:10CD700079CA9217DEFE12F1790A610C183B95D23E +:10CD8000F9E5FD4007A71E333115ECB525D690FB1C +:10CD900051D4537BAC6C07F2F7ABAF93DE3AFDBCDA +:10CDA000551CEC9C7A4910A8C1D67F1D6A09CBAFEF +:10CDB00074621C8E576CC37DC36153A006C6AE92CD +:10CDC000BC6B9EC3F51D36D33EE3EC5C968FFBCA6D +:10CDD000B32CC3A312FE95B725285FF97BB3102DA2 +:10CDE0003EC9DC0B427D02F041EFF54C8154EA1D57 +:10CDF0004EE94A4BE52894BB26191657407E02B2ED +:10CE0000DBCDC91E361FD29589CC87F063CEEB2EC1 +:10CE1000F0D79F00A5CB1F51D2B0DD8F52CC34EF9D +:10CE200045A9DEEB53483F3A65B22F343A55F7F146 +:10CE3000799E17623C35189FD37BDF9D08DFE51F85 +:10CE40000A4A783C43643C6895A4BCAD14D27A4944 +:10CE50001EE5C9310CE17A563B773F3B57894F08B5 +:10CE600093CBCDD532C98FC66A17A5EBAAF39942E9 +:10CE7000FE350FE54DDAFAAD052AC507214FE38FE0 +:10CE8000D559EA453B0FE784714126A78FE8C8EAE8 +:10CE9000AA24DF94CDC9681F6B72AA6C3EA46627D2 +:10CEA000878FC9594AF0B16879A97506C113DAD3D9 +:10CEB000F7AB537D77233C6C59971AE4922579BCE4 +:10CEC00021DF0F5E3AFE77FF4FC18D119C1AAB6DCB +:10CED00094AEAB2E2278D5577B29FFBF00B7D694EE +:10CEE0008908B7294CB185C3ADC4901F106E8F005F +:10CEF000DF2487F30DC011F986C5787646597F6423 +:10CF00008AF11028A81FAC6EA554FF9E3880DE3E23 +:10CF10009F2268F1B0BE1A338E23737F0B4B565994 +:10CF2000D6A43EFF2673A94CC13CF22AE2E5680C68 +:10CF3000C16EF9FB76F21B9B64A93B5CAE2DBF4131 +:10CF40004943F965AA7A9C9D088B4733CD28B52BB8 +:10CF500004570F9D53D66A7AB3FE02FE8C7CD05CD8 +:10CF6000AD50BA5EE3878D1A3F6C423C631C8987E3 +:10CF70009F6BB64C67A417FF0FE4F93E3EC4C2E3B3 +:10CF800046123CC19019F04D3252A13444F1BF47D2 +:10CF9000AD8111B9143FE545FA4838BA8AFCC78C0F +:10CFA000055DE84F4BD0E0C65E1996302B9696672C +:10CFB000E67A879978EA37A33D1E09D75ACF411BF5 +:10CFC000EEAF079A4FF1070B051CEFFC2C42134BF9 +:10CFD000BE3D78B41CCF4F5B1CA457533D9539E838 +:10CFE000DF63C7AC449F4E8F4F981F86BFD401ECC0 +:10CFF000BA55A9D77E8C7CDB8DB20CE8F0C1D6E1A6 +:10D00000768473B339E84279D79CC0F587520650CD +:10D01000B8ACAFDD9F3439185768E4775DBECA53AA +:10D02000C71BE85797AB895719E95C97AB2FA570D9 +:10D030007B6D516AE9799C4F52EF56E2C348BACFF3 +:10D0400093A794F992510F304F13DA6B6833A21DF6 +:10D05000F7A110E0F4CEFD5367BB7277A09D03BB30 +:10D0600002922B2AF203E1A9E7B56F9231DE95CB4C +:10D070008735B699365C6F03D0111B85FE6C850031 +:10D08000BC01E887D179A047E38F224A75FA74A7DB +:10D09000E61AE2044D798744C4573DD811144F0C69 +:10D0A000FB3B278C271D986C437B4F327B0EA39C48 +:10D0B000EA891583A837EB9D336D5EF4DF241412E3 +:10D0C000DEBF8C2DCF192C6E09EC16F2DBCA4E0F89 +:10D0D0003B8EE330467E5B933C9EE13E71B7B333BB +:10D0E00006F72DB1A9A2615E8B527DC353C3F263D3 +:10D0F00070740D5FD8ED6EAD9FC8F17E90AAF92DCA +:10D10000B354E60D3BB7A8D2E95B51D95561FCBDDC +:10D1100066C434867117917C3DA0DCDAF9FDE456D3 +:10D120006D4E80F0658E9417C920C79D94AAA28C7D +:10D13000F3569AFF2581E8EA4A840373EEB86087C4 +:10D14000FC685814FA3A7A691AC56B5ED033B06B32 +:10D150002E203DB3B988DB239A9EE1FAE96C8B83DC +:10D16000F4D3D9B995144775B6254D41BA3BB0E112 +:10D17000F2B1088F79BD8D4C81F9CDEF9D4CE982DC +:10D18000D65F525ADEDA0644CE58CDFAF91B664114 +:10D19000BB138F98282EA83B30E14C15E4BB5BAC49 +:10D1A0000CE38EBBB7DE93837EF16E1807EDABEE1A +:10D1B000AD2388BEBA016E946F30D6C7786113E094 +:10D1C000A59C313D68D38BF5E7BD6E6A8B662795CC +:10D1D0006FB47AA39DEF5C286F8D6EB7D5E2AFE98F +:10D1E000F85FE5288457F107AB7270BD3AFFAF4C8A +:10D1F000047984F0FAC0CAA2F9E3AF4EBDBA227531 +:10D2000022A6DE159832676254FF5A1FFDF3714F54 +:10D210008860DF125E7C71371BFCACDC8F7942B317 +:10D220007F996D80F238ADBD1CBD7C49CBE7871E70 +:10D2300060787FA1B214895EDF4F9B18ECA705DCF4 +:10D24000FFDE4CF1D0FA7CC04E253A66800F942F59 +:10D2500073357F0FC0FD260B7C3FF1BA4940FAE8D9 +:10D26000A3275F1CDA2D42F30D6B7643F9DF0FF332 +:10D27000FDD9C2DE4D24EF84E6319B27C3F77B5EE8 +:10D2800037939CAF69BA7CE3ED80DF2FDE30517EAF +:10D2900041AF9DEA9D7CC0B3F976A8D7F30733D997 +:10D2A000E15F1CBE9AE21E4F9A8D7E82A9699C8F17 +:10D2B0005FD2F8795E6F33D91F7AF9BC863916854B +:10D2C000E874037D9F878736785F8195FD7B711EAB +:10D2D0009EE730BAAFF0D2C3B75EBF86F4DA78B259 +:10D2E000F7E7AFB77AA2C54FBF94AA18E4CFFCAE58 +:10D2F00016EA97815D949CAAF5172647E6F7261152 +:10D300001F30596518673C4F932717E6B7D56C90C7 +:10D310002727EDD1FD20AFA7F27DD4BCDECB89BF9E +:10D32000FAAFEF87F47D9E3E6E17E7C7BEF56C9EA1 +:10D330001C6D3D7DEB984AF54F26441FBF471BBF30 +:10D34000BB7A01F3825C2AB7423D278E7FCFDAA2F7 +:10D35000425C4742A210B6AEF9AD8B99376C5DF3D3 +:10D36000B7CEB69487F5DB8787E5FF5E2CF5E1A1A4 +:10D37000277509E161556AE931E49BF2E62BC62283 +:10D380003DCE6F6D24389F307BDC285F3F69BD2721 +:10D39000CE17759E8AC18F30BF55C30FD8BB85612C +:10D3A000F8D1F112D9BEFBFDF95F3E80F2E7116EB4 +:10D3B000DC0C04AF7E78CB8D0EB7188D3EBB41DF01 +:10D3C000FA086ECA0B4791AED73B3C48D703C36FF0 +:10D3D00034F30D06BF01EC57B0774C69785F017DDF +:10D3E000B4780ED9CAE96028B8F58DABD14171F493 +:10D3F000F514A5E97450C55460D8E396A1E8E07E21 +:10D40000A6DA0659C7053A78D84007459BD7131DB9 +:10D410007C8AF6CAA8FEF83F6E51E3A6E0B94F93A6 +:10D4200089CE958EC7A8A9B7F1FC3894C7C7E3FC8D +:10D4300037E2398D9E5FB87344DCECB0713F690010 +:10D440003844815F51DA00F493A7B28249FF3CFA75 +:10D4500039618E7EBFEFEAD4E2A969A83FFCD1FD15 +:10D46000B57AAACB6B53BCF3C23E13F5E771E7B0B4 +:10D470002F0350DA9CEA9B8E745197F0F33B511EB8 +:10D480001C3F2E90BEAD797FE528D46B917602ECDF +:10D490003F1BF0DC73A529D64F76A854B99DCE4129 +:10D4A0005589ED2CC47D4AE5968F46A0DFB08A529F +:10D4B000A6D9A12B4D977A9AC82F5BF9149E930297 +:10D4C00091C8585F6295746E0A82B014F39B1DFC7C +:10D4D000DCB54AB2C9D6B0B884E51ABFD45797FEB6 +:10D4E000F223F443DB5426A7627B2E3725C6EDAF2B +:10D4F0007FE03CC3F4BDC5EC933DB80F155829F24D +:10D500008559F2D1FD27B32B799C1A8687CA347EC0 +:10D51000DE6EEFE868C885F6F6BBFE20A31EB4C237 +:10D5200038E867B3654967C3FDD5E6E420DD6F627F +:10D530007961DFC1AE721640DEE00780F90E621736 +:10D54000BE2C785C5F223DD67078142188207D67E0 +:10D55000EEF03694CB45529D09E38E66DD3582F2BE +:10D560009BE77C33B22B0A3DCC7A655D27DA33B377 +:10D570005E499F83E707B39C233FC614B60BB618DA +:10D5800068FF9AC0824D905E657B9CE2195FD3FC78 +:10D59000631D980FD38B1D1ABD819D337D0FA4B3DE +:10D5A0006C7EF3DD057DFEB4C871376B7CDF610EE8 +:10D5B000A65C8A7400E3E03A7EF64AE0C7A0FAD996 +:10D5C000EDC1C00D63003F77B01E33C2D1C7643ACE +:10D5D000F7D0FDBAE5CCA3E519ED4FDFAB30EF4056 +:10D5E0003A89ECEFF610EFEF671DD01FA4771CEE21 +:10D5F000F93754CBBEA03CCDC1C2FADBEF39E460B1 +:10D60000FDFB8B84B347B299D430B8028AC470B89A +:10D61000F7836F7CD9756CECC07CD6076F3E8F4862 +:10D620007C7C8145C0A76D69DE5F23BFA969DEBD33 +:10D63000C8BF15B61EB70474732CD9B71FBF2F35DA +:10D64000F97252011EA7B37DA352102E9DD1CF5F58 +:10D6500023F93BAFECF463C83777D4480CF1BC76C0 +:10D66000DF278F215F9E36031FC17EE0B5559FC423 +:10D6700022DD2C01060C97271F548D20FBE9ECDEE0 +:10D680005183DE1FF940F397746A7CA2AFF34E64B6 +:10D690004018EFCEBD0EDACFDC5965BAB0CF427A72 +:10D6A000BFB38AC78730A973ECAD06BBB36EC07E2B +:10D6B000701F11D94F77B56F3BF1BDE49B8476F7AE +:10D6C00089EA05DB51BE44CE73A4CB77228DF4DB0F +:10D6D0006C43BCEDDC9685DBC3F950AF5F3B807CCF +:10D6E000F58CD2CE016D7C3CA6FCA0D83989EE6BBE +:10D6F000D28F3D64FB5008A387A1C6637957792F69 +:10D70000C805DC7FF944E64CEDDF5F643DBD7F5723 +:10D71000D595ECC4045C9FF7FFA5A50C3D7F8B8BD2 +:10D72000CFDFAEB5D3BFDB7D7E8676A1FDAB78B211 +:10D73000133CA3B8FFE11F9A5DC09CB05E6430FF4C +:10D7400066EFFFC67A61608A17B66FB5468D2BCA41 +:10D7500074491C2FC143C5B628F3EBD75F48621745 +:10D7600053CF338AAF1FDD64E4EF1A1943FB9AF2FB +:10D77000AA5ADA673782FC407D10399FE34D8F2A21 +:10D78000A807EC16BF827ED1C691A9B96BA01D482F +:10D7900035F2FBD863FC8A14FE5DF307D9D7F81580 +:10D7A000DCDF368EC8A0EF7A7F8D0297B33A5F3404 +:10D7B000C2BEEF79F28B795C3331AEF4ADC0F45870 +:10D7C00068B7632D0B99DC8C1D74678CC67DAEBF6A +:10D7D000DE42E77B8DF962FA5CC8C765DBC83FD6DD +:10D7E00096109A85F76B554122FDEA4F50AE8D4554 +:10D7F000FFEE9AB44E947F07EFB6D07A9B27F3FBE7 +:10D800006AD6291FF9AFC4FE57300FEAD51DBDBF38 +:10D810006EC57702D4A3B09F45BF21760AF268C7D0 +:10D82000F4B376DCCFB930AE0EF0B1D51CA4796D6F +:10D83000A9B152BF5BDA2C65D1F0F779BA44EB0A93 +:10D84000085D141F9CC4827684EB83D3676ECE83FD +:10D8500076B9794CC6FD7C73C1596DBFE935F1F3DA +:10D8600028DD8FC8ECDA79964D3BA7B285C7173E05 +:10D87000EADF4BFE43C78C204FA78BE47F8E9CC70B +:10D880000A17A77BC7D4CEE9A8271C852213D0BFCF +:10D8900099C7045C973C7D075DD2C8CD6703B43758 +:10D8A000517BD90BED0B797BF409C917D9BEC2C5E1 +:10D8B000E30CD7A31F0ACA03668F702DCC23708395 +:10D8C0002CA84A5FBD7A17D7AFDBA1FF10C9D100E2 +:10D8D000ADCB9D1F0C21BDB92B44C2D3FAA2E3747A +:10D8E0002EF060A1EE47F5D03CB6D61C3980F6D7B5 +:10D8F000D67B19D9495B518642BBAD37B0003F4F4B +:10D90000621928DFB62CB45C4FE7F905007F81D29D +:10D91000A8F39E9D6E237CBB573F18C2FBFB311EB4 +:10D9200020D45C4AA3D66F4CE770DA620EA4A37FC2 +:10D930006420BA287371BFAABB4AB3AB98DF85785D +:10D94000DDA0C187DD3A9EFB1724AF121EC7D5A705 +:10D950004FB81F03D64771AD497516D247E28CD038 +:10D960002C5C5762BE855D938BFCC5E1A68E117958 +:10D97000DC190BB4227FB65D924AF1A4EBC4800B94 +:10D98000FDCD6A8985CE930F1689B3F05D848D75C0 +:10D9900016F243409EF8C5EF1DD686FCE6985A5213 +:10D9A000B6A010DFB9B0C808DFDA02D98E745CEB1C +:10D9B000156501F21B4AF5FB118CDE37186732D969 +:10D9C000F3A17C7BBA883E5AB65D1088DFEBBD259B +:10D9D000FEE1F0BD5E4E16C2FD002FBBB8DD7B77C9 +:10D9E0004EE9CB2E4803DE07FDC3158E4B6912E3CB +:10D9F000572CE02796851660CC4D5BFD934771BD93 +:10DA0000EBC7D9E8FE6CF60A7F19CE37F6128B8287 +:10DA100078DDD19B349AD6576751909F3709816B37 +:10DA200091EFB7DE7D4845BFBAFD6327C60E336769 +:10DA3000D7DFAA317ECC59688938C76222CA717D86 +:10DA40005CE75B21A2A72EC1F79758F2FF1434E5DB +:10DA500027533CF32484E78629EFE6CF8B4217D087 +:10DA6000DE993A1EED653134692CCA29AEC7982477 +:10DA7000A787E3775376C63BE867DA560CF3C7F11E +:10DA8000AABA6FA779798FDC8F7695F3D8C9AFA33F +:10DA9000CFF34DD223B1C71C21712CA64B66907DCC +:10DAA000165E0FE4FEC61CEFC72EA09BDD355CEEB4 +:10DAB000B7DCC5E83D0AFCC90F836F4B014869FE1E +:10DAC000048D42F50A64F2A3AF13956008E139D6DC +:10DAD00046F494C67C24D722D7EB38D67837C61DB7 +:10DAE000393CC679F66AFC8D3F522A9D57A025CA5B +:10DAF0002CE973ED28FFF68C57D271BFFD6042749C +:10DB00003DFF5E3A6FBF5B886E9F9F4BB7737D0989 +:10DB1000B232348950C528AE0FF2622A9DDB909351 +:10DB2000DB2A72B9C0AE63A4F7E2C675D93D61E3E2 +:10DB3000ED49EF9B27C61FC46BED98DC13AA81F556 +:10DB4000B701D5E27DEEB86C0E47A7DA0747AC2FD8 +:10DB50006BEB023EA81955884094A93E2BB5D0B96D +:10DB6000084843F51BB10F0EB15AFD2D459280EFC9 +:10DB7000900C036008503F61BAC5708E22D71D51CA +:10DB8000B1FC7E1353128BFAC67F6C1C0BAC81F177 +:10DB9000E3BD4678C7AE786125DAE591748033B885 +:10DBA000D02F868ACF35B64BBDBD1F1F103C699E56 +:10DBB000009A96B7D80E0B00A5A55DD2E36349FE87 +:10DBC0004E3475AAE80FC580A47D30FF4B9F7ECBF5 +:10DBD000BB0BF22D3ECE67B1F92FAC44BA4CC8E076 +:10DBE000787A077DCB00E74799FC778CDB51AB4413 +:10DBF00005F1B12D348CF47823934A114F8D95475C +:10DC00004494EBCD7B99471090FEFFCB1A3EBFDBCF +:10DC1000D2F9390D9314927F929BDF1B6D2E101D4C +:10DC2000285F0FDEFD02E9BDC70E880CF9BFE4775F +:10DC3000C71EC1F7815ADEB152BEE5F54A921B3FBD +:10DC400087766A14FFF9507A39B27EDE921D029E01 +:10DC50004FE42C08BE3E12E5B35FF25C83F858D067 +:10DC600049EF872885FC9CCD392344EF8728A8D528 +:10DC7000C02655FC5ADAC2CBD9AD89B48F1A63EDF0 +:10DC80006AB80EE6F7E8D312437D69B206D3E743DC +:10DC9000BFA6179DA809FAED8F1E9D114A47391E90 +:10DCA000534961D0FDE677229DCB59F70CE5F72368 +:10DCB000A1DF84A91C96767FDA0194976833E3BDCF +:10DCC0000A87CAF5DC0629E0C538EF0D2B7C161C47 +:10DCD0009F69FB97C625E54F229C4F6A7A8F552E88 +:10DCE000A0774CDC1ABF38AA5871B47D56AB2B868E +:10DCF000C7B73C201E40FE707B19E90FB92A181ADD +:10DD0000A5E9659CB8BCFAF946D42FCE0A91D6B1E4 +:10DD100041EAACC1772536AC60728DD2BFBFEFDA75 +:10DD2000BE2ADD4AF36F451CA7F4AD835C7220DF89 +:10DD3000DC0BA2AFE3611C7762DF3A62F475E47733 +:10DD4000515E9FC7766FF0A2E6B1595BC7A6749982 +:10DD5000524701681A677F79BFC6F101BD2B1300D6 +:10DD60005BDD44F7D182D7615E794E64FCBE96914B +:10DD7000BFFBE535BA8AFCAEB0B0717291EE389E49 +:10DD800081EE34FB09F8CE86224054BE213F869FA7 +:10DD9000D61F498FFF74B9183E6FE83FB68109144A +:10DDA0001757C19492F4FE72916972D1C6D410CA09 +:10DDB000BFFF69B9087290E4620BAC3409762AB1EE +:10DDC0001D4D77A31ED7E5E144C4C914645FDB0D84 +:10DDD000254EDA1751FEB247FED082F191EB44EDA9 +:10DDE000BC4B830BBAA1102E5FBB14833E7D187F02 +:10DDF0008175ECE948BCBE00C6DB5C366C1CEE2FBE +:10DE0000ECFE17C93E7017F0F81577153F3F77E421 +:10DE1000CD7B32FC5E5C653AB7D32B75FAABF2BBB7 +:10DE2000709C0DD82FCAE73C0BE9CB475990EB43C8 +:10DE3000CD3EDDE6D2FC241A5D45F249A47C9AF081 +:10DE400087E41294EFE98255C6FD1CEAE783A946F0 +:10DE50007D8DF4A2EBEBD6CE3509E80FCBD5FCFDDA +:10DE6000B936639CC365195C9E99D3F93CD68995F4 +:10DE7000B4DF544B44DAC7E9F477418F47C031121D +:10DE80007E48A86B27517C0CE5E38A7B18F2EF36BD +:10DE900020597CE32D2E5DD1E2A6658273DBCFC4D1 +:10DEA000F1282FF77494DBD1BF2EB86DD7E2FE7046 +:10DEB000A3C04228373716BF4971254D55D0332CA2 +:10DEC000CA992FCEB68CED8F67E063DAAF3A546B08 +:10DED00027FAB582A11D14B7D01438348B713B9644 +:10DEE000615C4A53FE9A8C4528DFF34B0B11BF6DE2 +:10DEF000F5168A9B91F359543FC2E7B88F213AF93E +:10DF0000767ACCA1EF2F2BA2EF2B4B33F8FE3628DD +:10DF100081A882F964E58B1EE4FFAC3A4BD4795CAE +:10DF2000A9E1293383DF0F6BAB3F944EEF668995F0 +:10DF3000013618BE60FA6B52C3F03179007CB874B8 +:10DF40007C483A3E1266131F76758A5CDE925EDB71 +:10DF5000C0E4DB503FAA9516B2631BCD7C5FBEA325 +:10DF600040E30BD9D686C4F66DE93A6E8948F7705E +:10DF7000B28B44DA273A2A9EA7B8A64759CFEB2896 +:10DF8000EFD4027E7F3EB2FD1D19DC7F159414C1D3 +:10DF900043FB698E47C02BCD67EB88D4B6703E6DCE +:10DFA000D5ECE8561787E3D6FA87894F2F769EBAC5 +:10DFB000DCAED5ECE8855E9F05D5812A944E4B47B3 +:10DFC000FDF9047F878A999C64977F8A4DC2FCB2D1 +:10DFD000ABB27C951961E743B2B752C47A57E3BB41 +:10DFE00042D0FE9320BF0FFA49F0D7C5F40E978FA9 +:10DFF00011332F649D023139C8D09D907749412A51 +:10E00000772D80B924D0ED48CADB6CA0176142A7F8 +:10E01000ABF9FD8B6E7C5F92DE9FE4EF4B7EAEBD75 +:10E020002739A6755DC9A3389E22F950667C86EF14 +:10E030004BE2FDE7A277292EFA14C8DAA6048C87F2 +:10E04000E1F7B7E5FB982C4EC6FCFA128C7BBEE7D5 +:10E0500055AB764FB2730DDE7B795C8475439B665E +:10E0600009F4FD702C6A102AC3E878F7159D7178C1 +:10E07000CE773A78CBA0FE63BC3F48F3CDE078DAA8 +:10E08000E4584AF7CBE639436E6C7F60CF534F6E4E +:10E0900081F13EDF67A3F74C363B96BAB1FCF347FC +:10E0A000DE76A3BE38BDEF6D4BB4F3C92552701AAE +:10E0B000DE23AB50E3D91A987F7170B685E24F76B4 +:10E0C0001DA0FB694B649F05FBAF68DD43F9AB7690 +:10E0D000FDD98DE5EF67703D713ADDE746BF445EDF +:10E0E000AB352482FED93DCCBF28EA397B86A8CD4A +:10E0F000FB55EA7FB3E3D5438897D38F58C9EF76B2 +:10E10000E091DF51BFA7F6BD48F3FD7CF7DB77A0B8 +:10E110003D5DC19807E5F969BBE6D7B375C685EFE4 +:10E120006F5FD5E0A1E74FC76AFBE0AC21EA69E782 +:10E1300031CC09F0A7FB039D7178BFF073B3CF8298 +:10E14000F0588CF080B418E080727F7150A0792E66 +:10E150006E6DA3FB568BF772FFE0628017C1A5F5C9 +:10E1600000CDFF5806971BA7F6FDC54DEF52ECB545 +:10E17000D2FE595FF762A7CF8DF0D1D70B70E0EBDD +:10E18000DE7D71789AA7E3A9F5CF34AF8ABD7C5EB6 +:10E1900015BBF83CE6ED053C39114FB309FFA7F676 +:10E1A0003105EFC174EF79FB33B4674EEFB32968E3 +:10E1B00057E8F3CA02711B371EF988EB63B6572084 +:10E1C0007DCCA44E3ACF5922CB32BE4F70A13C60D9 +:10E1D000097079DA599209E5CF3C24D2FB964C0EAE +:10E1E0005E8AFED53319FAF946A71BFD62BBAFF074 +:10E1F000137D9E8CD5E02D75BA317E6673A6EF4CEB +:10E2000038BF9FFEF0C54B71DD2B4D95BFCBC6715E +:10E210009EE2F1A1E78755FEF5019AF770C3796395 +:10E22000640A708BC3F3EF7C91F9E85EF2DED7628B +:10E23000C2CFA14D99DCEFB6D9F101DD473C8DEF9E +:10E240003CD27C8214A735D25BEEC673BE93CCE978 +:10E25000C373D9CF9F788DE26DBAD375FF5327D59D +:10E260003BB5F7B5444CCBB5787816B885E418C003 +:10E27000B1C1363E9A7CD4EE1705F8BDB133020821 +:10E280004CD4138FE970AEB4CC349CEB70399AB592 +:10E2900035B783FC2D81E8F7CD22E56FDE4393E9A6 +:10E2A0005CF91C8B7EAECCB438B995A6188ABFD960 +:10E2B000ECF805DDBFAD52AD32DE5F39AEC9C58FBA +:10E2C000B4F716CEC7C4A922D0CD4B99BEE199139D +:10E2D000FBDFC32D6F5EE246F896E3B9076D6A7601 +:10E2E000DC807189140F3A85B46D88E067D6CB5B0A +:10E2F000797902CF4FC9DCB31EDFC344F8723BF516 +:10E30000495E9ECBCB7FA295CFCF281D9F49FA8532 +:10E31000D13B4560912574DBB80A8F068F3EB84823 +:10E32000AC5BB7ABA1F2C24CC6E336324AA7E27A85 +:10E33000A058E07CFFFDFA03BCABB6C4FF867E6C40 +:10E34000FF5DFD04492F893E7CE30ABE79B8FE7B60 +:10E35000BC84C94D09DFBFFFEFDA7EA5C92B9E44FF +:10E360003A8C1789EE75BEEE7E64D438DCFF5B1AFA +:10E37000EE0EA1DAEC8E2DB1A4C3F7730A3F3FB9BC +:10E38000EBA14D86F755F534F21D5BFD1CCF32DC59 +:10E39000783EDB92C9E5514B669FFF0DCFE546E223 +:10E3A0002F0ACFB7A452280CB7D359A588F187F903 +:10E3B0001D367AC7F712068202E63F9A8544D4DFFB +:10E3C000635817E57F802080FC38A698303F81F5A0 +:10E3D000B8A5E178FE1C5A8B76DAB1645F13D2D906 +:10E3E000978F747E2040F9CF337CBFE982EFEB3307 +:10E3F000F93EC8096621D2B38C29D0A1E898E18AF8 +:10E4000026F72FC053964E859FB7DD2C791F223AF1 +:10E41000665972B7A30FCEBA3C58A4BDBBA4B7FFD0 +:10E42000ECE9A786D17B437DEF850F7A1F785ED517 +:10E43000C2879E983048B9266777D7046E0BD7F706 +:10E44000ED1A9C9FC9D4F5805FD70764C7FDEA66C3 +:10E450006E3FEDBEC2BBE67194B7AD26DA4F9F6C3E +:10E46000FD0BBDFB78AE94915D37D0B82723F07ECD +:10E4700072E75319FCBC2360D0EF0B9F7CE9D2F00C +:10E48000784B00B3923C89BFC341783FE451AD263D +:10E49000A4D252F2C75858258F53C1F90EC777B886 +:10E4A00082943A5927A571AC875299C9E49F4E646A +:10E4B0001E4A935929A5A9AC52E0F69D9FD20C168D +:10E4C000A4340BED53F4F7B01E4A15BCF11916BF76 +:10E4D000310C4F4C87E37BBCA5FC7B447C9084785B +:10E4E0009C10459E47C40549ED5524CF312E684404 +:10E4F00072FFF71474F9BD39B3E43D94A72F657A20 +:10E500008F617AF8D9DFF3FB15EB05B2AF4FD8670F +:10E51000581440DD33895E7A07441559E94ED0EF2F +:10E520007375FF3FFEE871C208CC16F3A9F0F81D21 +:10E530006673E6E379F11CADEA1CED1C648EE60718 +:10E54000C1F7CDF83D3D0FDDB79FA39D3FCC89F0CE +:10E55000BF30BFD5E04751F11758C71CBF40E70691 +:10E56000736266BCDAC506A693B0FEE8DE5F798406 +:10E570001F6A487F56447E6E647B9BC06CA9F89DE1 +:10E58000D3D3333F54C8AED3FD5940700AB56BB0F6 +:10E590007E487E21FFD5DE70382565F17DABDD7FBD +:10E5A0004D5CB47797F4742ED867E6C4FEED6147EE +:10E5B00098807CAFCB619DCE7371638B7C946F0927 +:10E5C0000C1697AABF77DDF4809FE1BCEDA155F44E +:10E5D0004EF5BDD92AF96A6D0501BA1F10931F7057 +:10E5E000A951E6D784EF3A037F35C51ACF4D966718 +:10E5F00071FE5F9EC5CFB50F5D925A82E7D9EB14CD +:10E6000091EE0DAF53F8DF2D589735D43BE536C367 +:10E610003DF9B549DBE81D20FB57DB19DA93762974 +:10E62000FABD94DBB4F13769F537276D233F49C351 +:10E63000087EBE1F59FFC08887E9DDC7C65CD8EFDA +:10E6400062FA804AFDD78F78B80CDBDB428D86FBFF +:10E65000BCB3B3F8BEDAB697D3A329CF121886F4A9 +:10E6600020F929BE40AFD738C079D28D595C2E36FB +:10E670009903744FA649B3879667C56D407B675D64 +:10E68000D68EA3C8AFE7F2189D37DA434FD339824D +:10E690002DDFC2EC82F6770230BEA32048F8416736 +:10E6A00053C840B7317DEF6C98FAF75FF78DDF857F +:10E6B000EB6BCCF5D3F843ADF74A8D4E1B35FDDA45 +:10E6C00068379EA35568F0BE5E5B97ED1546F26411 +:10E6D00010B890BD77E3D61137A27FCAB67F48380D +:10E6E0001AEAE7B2B2F868FC1229FF9D0562C43B42 +:10E6F0004A02CDEBDC5E417B6F91BF63D1670704BB +:10E700002DD8EFBF6D2D3F782DCC6791CFE9C5F89F +:10E71000C9A7B6EEA07BFA8B5F34537CC2C8AED9D2 +:10E720005C0EB6F27712F5F78D2E69B51ADE9B5A9C +:10E73000C2C2DE5184F1161F3B798CD13D63E37771 +:10E74000FDDD8066FC10254E2DF2DD8187B222DFD3 +:10E7500023D3DE1D2888EEA7897C7760575024BD1F +:10E76000B11CE358691FB0AD04F73D55C704F21B57 +:10E77000F4E743E5B13C73585EF0103DAAB131DED9 +:10E780009D51F8E9BD6C4E2FBBF1508DECFEEA0DAA +:10E79000A12C4CEB189E37D5AE90643CD7AE0DC47F +:10E7A000D0FD925A590C60DC48766C890DFD8F2C97 +:10E7B0004194F11EDA34D354BAF764B9579A40EF52 +:10E7C000B3EE58D489F7EA6A5D12433ECE4EE0714B +:10E7D000042C5DA4F769EAE43713E6E03ECEC9EF06 +:10E7E000E9E5C82CA00868D779199E2FC366A53221 +:10E7F00004A657B6E00DE17B576CB255DEC9DF9930 +:10E80000B971DC24F203D3CF81B669A1DFE2385EAF +:10E810005B29E2FFAA7B93C91E0CB84C0CE3003FB6 +:10E82000CDE2E78296D892D0FB38BF590EF2ED06C2 +:10E83000543111F1F07ADBDA99D7C0777340A278BE +:10E8400087FCAF6B6FBB06DAF7B459E8BE850E27BD +:10E85000A54E32BCDFE05E6DCC5B22DEAB9058583B +:10E8600039E4DFC179905D55C642E171BCC95E7E75 +:10E87000E82E3B894EBA813FE9FC43CBBF8779A0A4 +:10E88000D776B39FF0DEFEBE40FED5836DF37248AF +:10E890005E3A966EC7BF635275949F630E249F9F26 +:10E8A000CE52F47712ECDA3B1576F47B45D2535D09 +:10E8B00035F3609CA12DD011331AF17BD8ECC1B097 +:10E8C000E67A4D3E4A4E2EC775BA894CEB23E8AF27 +:10E8D000DEECC9F743FDFAAF4DDABEF1F48D485FC7 +:10E8E00092ACD0BEDA9CC53C680E9B933B336498D7 +:10E8F000C7E8172D1EFC7B07D39E2B8847393FFAAC +:10E90000B55924DF104E882FA9CAE2413BD95A9548 +:10E91000EC9126603D27D1E559A785EC21A9CAE1F4 +:10E9200027FBAB6D924B09937B6BAB658F64C6BFC6 +:10E930008F63A374ED00F23E27412C45BFAB45B376 +:10E9400097D3B475A5653B284DCDE6F273BBA4CE35 +:10E95000A4F77B816E30EEE6C06A4EDFCBD36DA4A8 +:10E960003797BF3E3C6D30FFE093D52E4F1E0076AB +:10E97000DBEA72F2DB16AFFAA811E96E79AC4D460C +:10E980003A34C58DDC3C15E9FEF766BAE7591B3B06 +:10E99000499913D69F29AEC885F030896A06D2738B +:10E9A000C163C11BA5C94827EA16BCCF5F98DD7AB1 +:10E9B000A304F2A53D56CDC0F3B2A9D95B793E457B +:10E9C000DD22209F6407783E5BCD10213F23FB09A9 +:10E9D0009E1FA16EC1FCADD9ED3C3F86EBA3DBB31E +:10E9E00077DD88FAA8D6EC2943FFF4B330FF821113 +:10E9F000F87783787A870617BDFC79FC6EC6BF333B +:10EA0000C4D3C8F217B476FB0728FF8D56FECA00A0 +:10EA1000FDBFAAB50B0DD0FEA0D6AE6380F687B4BD +:10EA200076870728FFBD56FEC600FDFF516BD7391C +:10EA300040FB37B5766F0DD0FE88D6EEE800E5EFE7 +:10EA40006AE5C722FAFF40ABDFA57D77C736BC8BEE +:10EA5000F69A1BE415CA93FCD806F2776DAB2A240C +:10EA6000FAAF9DC8F5BF4EEF6EED5EC0916C7E6E45 +:10EA700073249BDB01551A9D17AFCADB3815E9F0EB +:10EA80000FFC9E22E88FA3780F575D25927F6FF9C8 +:10EA9000EBFC5D99E5AB243ADFB8A0F7B4F6FAFCDD +:10EAA00003DA3CEBB4B4329BBF9791ABBA3C33C2B0 +:10EAB000F4A35936E66DC04F18FF5F97CCF54CFEB6 +:10EAC000AA92063C37A9053D83EBAB775A42E8FF93 +:10EAD000AA97252AAF4B2EF1E379BF2A4BA487EAE8 +:10EAE000931343F84E735D5DA1E1BDCF3A59A2F790 +:10EAF00063A484AB6C739C283766C8283FEB989C52 +:10EB0000584CE76AB04F437D525522A3DCC94D48AB +:10EB10004E44B93C3787AFAB23B6DB8EF728A4074A +:10EB2000447A2B60A42C11BFE7D5890105E6D121D9 +:10EB30002F27FFEBCE16ED4C91F1F3445DCEB7FFDE +:10EB4000621AE9B15AD0630AE931163F2EB5EFFED9 +:10EB5000A6746CB405F5969C61626690CBBFCB4EF3 +:10EB6000A471773EC4F5D608D05BF8CEDAF642C67B +:10EB7000DF7973D9C8AF5B2E315752981FF377D91D +:10EB8000DC8E67A6191EDC678FC0F710C3E03BDC84 +:10EB90006FD45BB943E8AD9C2A909761F5AD2ED94F +:10EBA000900F666BEF2A799807ED9B69CF6D257DF5 +:10EBB0007216F50943FDF2C798D1A85F408F5859E6 +:10EBC0007F39A8CB63DD6ED1E574ADA6376A23F437 +:10EBD000C6D072F7EFAF8F22FA140DEFD00C247F5E +:10EBE000AB304E00E8DFEC1348AF30C947F7FB8786 +:10EBF000829BD95C2ACBCEA1E1674EF92201E5B414 +:10EC0000D927793E8A724F6A28F8EAF52CB6CCC724 +:10EC100050AF7D716C653EFABDD69A3B67EF42BA44 +:10EC200015E2E97E87A2F91DB655EF672746603CDD +:10EC3000FC7B5BEB26E0FD71AF4CFE92F41205DB32 +:10EC4000D9619F9E44761CDF6F32D9E75F84F6FC62 +:10EC50008B1605CF050E3FABBDDF90ED2478DEB3FC +:10EC60006705B5330B952E7EDECF08DEEB3212F949 +:10EC7000DF0969B76976E3998DDE3CE857EC1250FD +:10EC8000FFFC474EDB461BEA0F6D3FC058DB4DB81B +:10EC9000FF09062C5A7DBCE8CED81E51D0FDCF5EB0 +:10ECA000C9156E875A6EBA2A0BCF43E5D112F49775 +:10ECB000B1CDBED17C05968B7A7B2F5E1E42F1A52D +:10ECC000E725C0C3331D5AB99AB6F12A98CF1E8BD7 +:10ECD0003E3E18D445389EA8D193BC11FBDF5DA2FF +:10ECE000B7EFD9E89D4AF3B9DE047BB07C77E646FE +:10ECF000677ADF7C87E7E46EAC81B59F56BAE27035 +:10ED00001BB7A4EDA354D4DBEBCAF8FD616400F497 +:10ED10008FE8F7882FE06DEFCD2ABA62FFF3D03F7E +:10ED2000E20AA06899A9EB9003E0B6647FA5CD2C18 +:10ED3000E2FB5DA52ABEDFA5B75BB27736D939CB3A +:10ED40005E194769947687F1FECC776867B35CC437 +:10ED500078A7436F2EDDA5E0BD99CA06A789EA33DF +:10ED6000EEFF8ABE3EBDFDE95D6FFE04C73BA374A6 +:10ED7000A55E07B5D785002E51DAE9F5F5FBD55329 +:10ED80005CDECBDCC07FFF70733E6452A507EB07EF +:10ED90006D7EBAC76637FB4B519F002A0318A7A0A8 +:10EDA000A753DC79FC5DEC88EF91FC15B4B1A41994 +:10EDB000282F574874EE1EB4A98EB1906F817D4AFA +:10EDC0000D4C69CDB823E3315EA0659F93E47AEDE5 +:10EDD0008A0E5701F295C7C2D0EE6DB9A2331DDF7E +:10EDE000BFAFBBD752F604D26F68B9EBAE303B6C05 +:10EDF000780E8FABCF4EF097213FDA811F511F372E +:10EE00009A7D367C37454D1729AEDA0EE56F50797D +:10EE1000B656EE997E0DEDCB4419E7559F37777ABC +:10EE200009EA355722FFFB8423AE2A9B0FE501D95F +:10EE3000222379DD9D53EE43383D23792A91FF9EAD +:10EE4000713A658CC7025949FA401A914CF15956EA +:10EE5000EDBE53F638AEE7F57936B9B9FDD0E4B674 +:10EE6000101E5A623B6F2E867631F789B20AFD3743 +:10EE7000DEFB7029C6273E76EF913F637C6B53AA79 +:10EE800044EF0CECAE0979B15E8FC03A77801DB9C2 +:10EE9000BE6A6627EE47D73345417B7DB730D38FB7 +:10EEA000FAB92745623BA07E4C9E315ED559608CF5 +:10EEB00097CAAA30E637E6F8EEC7754DF8436131D8 +:10EEC0008E9322280A3E1D5CD8C9283E3F352F4F1D +:10EED000C6B8EEB8C28838D8A9C67E12AF32962717 +:10EEE000CF8888DBBAD558EEBADD98CF986BCC7F47 +:10EEF000AED3A38B9F3FE87FE7E1B17B9F64A8A7D8 +:10EF00001BBF8AA778568423DAED3123250F9E8B09 +:10EF1000645B3A67611C1CBB3486ECA583EE18A6C3 +:10EF200040DEBA94913CB526060FE07ED52ACAA5EC +:10EF30002A69A8E081F7A1DC01FB5594BF91F0CBD1 +:10EF4000CEE6FE416725FF7B7141294476847D55DD +:10EF5000BC5CE3C1AD63841FB6222CCFE3BD1F7739 +:10EF6000F3F338BA774F477284575819E26D320B72 +:10EF7000E03B94D9F77EA486601EEB95BC4AB4337F +:10EF8000D6895D348E5AEEF4E1BE3B05E3BC4D18E4 +:10EF9000EFAD521A898FE7DDDC4E52D85C3FE2D1EB +:10EFA000355BA4F891FA43317578F852AFBDD7A01C +:10EFB000C7B1E974F9B29BFBE7F67488A217FDE0CC +:10EFC000B7E7ED407CEBF9565F721BC5F58FABECF4 +:10EFD00042BA6437703B14F400DDCBD6E3C4F4B816 +:10EFE000C2EE1C1EBF763A47BC80BF901E47141667 +:10EFF000074E4777263CBAF0CB78DE933DAE5446B9 +:10F0000039F34BFDFE05E3FDE2F385746E3043F406 +:10F010005EA2F9D3D1AE4BD2C64B4A96BCF4BE3BEE +:10F02000CC4984FA0F315E3F296FEF4ABC77B507B0 +:10F030000907F9E72E0EE748BA4DEFF0978E4178B1 +:10F0400009A00FB3FAD3B1E06EA5F3C0FAFB58A242 +:10F05000755C7FBA9E68E2F64FCF4285E22C87A2AC +:10F06000F393EE04EEC74ED922A37D9B91F7500D8A +:10F07000DD83B98FC9A8EF323A3A6F46BF57243FB4 +:10F08000041C71E3799CDCB7F3C39B4C9C3F589AFA +:10F0900044788B8C2F8D8C271D9E93A0F929400FCF +:10F0A000C4E27D00F94A8C13EC59C5E89D809217A3 +:10F0B0005B6EFB77E8EFCB111619E575CE5BBEA74B +:10F0C0001C30AF2F5FF2E5A09CDE2675D913C2FC81 +:10F0D0009E92C8EF9F45CAEBE139A246AFA0375CCC +:10F0E000DF3DCD46FA06E20AE6A58E968108876FD7 +:10F0F000DFF4275BCAFFA0DDA2DAFCF8F746DD1DCE +:10F100007A3E8BECB09CB778BE685BD6465542B869 +:10F110005590BFE860F63CF21749EF727FD1189323 +:10F12000378079F69E9DE2EEDAF7DDBE00E3D5EAA0 +:10F1300053AF53503F176AFB9FF139425478491639 +:10F14000AF0FF926F27B81065FC64A3F9D0DF81B83 +:10F15000F3B885E2EEF2C5F2865CE4874613E1B3CC +:10F16000DCA42C6D0EDBA735A71697E44CA47D011B +:10F17000F3C18641E915980FDF614A3E5E8CF49A2F +:10F18000036C86F22547E506644E550CF385D1A93C +:10F19000D22B51FDE6546F498E26F7F0DCC7ACB197 +:10F1A000F43389A56C36EA65F8867AD7BC2B869F3E +:10F1B000F7241BEF479A4C3C5EE4266DDD663CD796 +:10F1C000198FEFBD8921EBD8FEF56FD5EA49366777 +:10F1D000C8148F7EB2378ED2BDCB887360DCDF520D +:10F1E0005C4E05233F28C285F2F7C8FCDDEE2A1EDF +:10F1F0000F50BB9A09781650ABDD5351EFE07F8F6B +:10F200009879BD0ABEAF425B4C05FF0B11FFBA6C8B +:10F210002C11EBA7B34E8A63641D4CE1F112C67347 +:10F22000A76D03BC03A5FB01A42A13ED5346BF66DB +:10F23000E77F17AA8AD13BE1F46613EE7F57B380CC +:10F2400024F4F9E18E642BD44E3F8FDDFDF50719D0 +:10F250002897F3C51DBE37C86E889577A07E8C3180 +:10F26000F2A17E7FAD56A3936DD532E15B2F77ABD4 +:10F27000C729DE3E87F5D4E03E2BA72AD180E70BD5 +:10F280007ED9DE4CE69B10DE6F80BFAB9B27D13B67 +:10F290005D4AAF9BCAB7552B43F43F6C80FED389C0 +:10F2A0009E06EE3F8BCAB787BE48B81140B1ADE7A6 +:10F2B000A38452A5CF6E8D84B37BB5517EFF607F52 +:10F2C000643C39878BDDEC4DBE19E0667F40F4B4B9 +:10F2D00031FC7B3CC67AD373CF25F0F372BD7E2818 +:10F2E000F916AC0FFBDE3605FFBE8FB17E69F1C7A4 +:10F2F00009FCDC5DAFCFE7F7A35E63BD48FC44CEFD +:10F3000017E695F2E3B0795D69B31ACACB66F79B4D +:10F3100057CA4FC3E6758DCB58DF57137D5ED7E7CD +:10F320005B079D975EEFA6A28BAB17B98E5BA65BC2 +:10F3300007803BAFFFD3B28BEBF75F160C5EEFCECF +:10F34000AAC871542E272CDE2328E7CA99B216DFEB +:10F350000967CE98A871C1259A1D7316FD14180F60 +:10F3600097E97D1FE55A4F368F4B39FCEC223F9EC3 +:10F37000C32CDF6751F0BC235BF35B83E0598CFC4B +:10F38000BBC72627603CA0CDAD68FBABCE5C8CE74D +:10F39000DBD37EE436927BCC68CFC07EAD18F535EA +:10F3A0008830BA97F126B64B098FA3F092FD572FFC +:10F3B0007AFE42FBAA9FF07D951EBF1F6E67B14982 +:10F3C0007D76961EBFBD491BE7BF7286D17CC0CE3D +:10F3D000A7BF7B9B9A27517CF32F6D9D9BF0FED19D +:10F3E0002F939313703F73589BB76E37EAF71AD277 +:10F3F00066E78D334581D7FF0791B1925A008000AF +:10F40000000000001F8B080000000000000BDD7DE5 +:10F410000B7C54D599F8B973EFBC9299C99D64F2ED +:10F42000E211EEE4C5044298608801AD4C12A0A838 +:10F430002C3BC147412D0E893C227921A8A1B2F570 +:10F44000864484F8206840A0A043148A56ED6011D9 +:10F4500001C11DA2A6764B6DECF661A94B47602950 +:10F4600002C2A8BB487F7F2D7BBEEFDC9B99B99978 +:10F470005150B6DDDF9FFEECCDB9E79ED777BEF7E2 +:10F48000F79D33172FD27F93087928892C0C1413FA +:10F49000FCC7951162CFCFEFE9741232BCD42B8E2A +:10F4A000A3EFDFC9D111329E9087E983D07AB9509A +:10F4B000F06FE3E8DF22212BCBE9F7D030979027DC +:10F4C000C57EBB40EB9F7408A2CC413B09DBED7CC1 +:10F4D0004BA7F3380879EA8EFC1EDE19296FF03944 +:10F4E000B64279B88EF80216E8445C44E8FB9D26E3 +:10F4F000D1DE594A8B42BFB3C64ACB3B7E7F1B67E6 +:10F500002364C40882FDD5B55693635711B2DB104E +:10F510007EF322CC673DE7DF46FB79ADBB74AA40A2 +:10F52000DBCF3B4988997E5AB7ECA6278FA71132CB +:10F53000E1B85809EFEB36DBDD3C7DDFD4DF321577 +:10F54000C6212DC45DE0262493AFE4ADB49FCC4723 +:10F55000DE73B7D329AFEB95F6846839BC9573F7A2 +:10F560004850BFB87431C0C7E2912C74BD7361AA12 +:10F57000F8DE3E550FED6E32B83B683F67F4641617 +:10F58000C0F1A20257F539F70EA982D0F9CF0D2CA0 +:10F590009B8BE38A1464D9B46C12711E26494C6D9E +:10F5A000A3E5CC2462328F23A47C85D8F7008C5F3E +:10F5B0006F157B288C6D1562DF8F605D2D3922EF12 +:10F5C00086C1FD0807B5FF791EAF81D07147EF30C6 +:10F5D000D0CED83E5EA4FF8D09C496C7EE892D9784 +:10F5E0000663CB57BD135B7E5562F09E681ABAE581 +:10F5F000388577EF012381F92E3A9DE4375278EF71 +:10F60000D31302EB975F32223E542FB278003F4E65 +:10F610009F4ADA6AA4E5838793F0FBBB7F6266DFCB +:10F62000EB022F43597E3999C0F78BD202E5A974BA +:10F63000DEAF7FC9DFE92D66CBD243FF2F176DED1B +:10F6400084FAAB02E5227DBF7B1421FD502FF84BDD +:10F65000609DBBFFC663BFE1E78DFE1EDAEFE9BD2B +:10F660003F7E19E075FAF9A1A91C9DF335BA9EAB4E +:10F670003AA1BECD2AF5D0F7134FBF98E78BDA97A2 +:10F68000453B8C31EB5C2C71B8CE56C1B3E259D8F6 +:10F690009F437AC4A725F3FC7541DA7E0997E39668 +:10F6A000A11F03C5D36228BB33ED145F27DA18DE30 +:10F6B0002E31D3729C7D579FB51B78E2BB2A523EF8 +:10F6C000BAFAC7381FD7C9F711AFF7E9655D12C09D +:10F6D0007135E7DE46E7BFCF6C2B2129F0CCF10373 +:10F6E000DEC81225BC745CD78F9A002F7EC5BB7B09 +:10F6F00048E2F15C597FDA3CF9AAAFA8A7E33A4B9C +:10F700000839F751D29D1E3A8F911B62F7BDC81F71 +:10F710005B5EA5C0A79644BD77C27C725766219DEB +:10F72000109C8FEBE407B739E97C8718490BC0457B +:10F730003BEE5A651D2FBC40FB716137FC459EF5C1 +:10F740002765D07D51E8EA758ED111FDB77428A5E3 +:10F75000B7451CE32FEAFB459A79A8FD4F94189F03 +:10F760007218DC6B42B8FF4611F6FFD483D39E3C7F +:10F77000AE1F3C9F130F7A3C93A3DECFDFB0B82FB0 +:10F780009BB66BD8993E8E8F826FC3F36F66DC4E4B +:10F79000DF9FD921B8810536CCDEFEF844F8EE793A +:10F7A0003E00F3857A0F5DEF99C0DB36F86EFE669A +:10F7B000FB385E8AB45FB0618A67B22B02CFCBA5FB +:10F7C000D3D72A189F5B14D0FB4D401781DF4D1D06 +:10F7D0000A78BA817317D071CA051F0F74672DF3A9 +:10F7E000E8E509844CFAE25FFB86D0FAE603E3CB56 +:10F7F0003B697DA7CE7BD33F01DD3DCDBBB7015D2E +:10F80000FFF69E0C5FD4FEBC03FB4BF7A5F3D606B8 +:10F81000EC47A6B85140997AAFABB61ACA138B0918 +:10F8200067A4FCD8769278FC16188FBCAF4B25E401 +:10F83000E4FE874A041DF2A3DB814E4E139B1BE8B6 +:10F840006E9FB5E5DF71BC97F438DEA4600A07FC53 +:10F8500077DF739CBB93003C62E9EFE4C915B64ABD +:10F8600046D7777A510EE88883F6B7F0D931C807C2 +:10F87000D4F7DAFDABF7C7F6A3C58B8F9475016A91 +:10F8800046E397F6BBB4E9B201E8B1A195CA8B286B +:10F89000BA6938DE652096C1E3103280BF04F09764 +:10F8A000E2259170BD66E41BF41F67A2787B0AFE17 +:10F8B000CA636542C7BF9BC3A59145A30285C0E744 +:10F8C0003841ACEAC88EF05752E1473E7F86FED9F8 +:10F8D000E906BE103802F40EB2741BC817317876F0 +:10F8E00013D4CB233CC08F860092D227F96932F221 +:10F8F000DF3352683BB67F718C5BA6AFCF01BD583A +:10F90000B09D2D358A3FB505DEB48568F9F4CEB4D7 +:10F910002ADE0678FB4B1BACF35420ADCA604BCCFF +:10F9200037B47C93CE0CE1FB21FC49F14E747A9202 +:10F930009D00EF0E2A74419EA5B594B6C4D937B583 +:10F940009DC3D0522A01FFF8BEC5DDC3E0463CB4DA +:10F95000FCE93B693DB0EFD7E8742817E672AC7F4D +:10F96000B57D913311BF9666071D117EFD84228FF0 +:10F97000557EFD8495C1E372F9B5F639ADB328051E +:10F98000E0F7299152403EA59AEA9E013D43AD7FA2 +:10F9900022811E50EA64FCE99D838529214BA4FD48 +:10F9A0009FF3BC6500B7ACAA7E0F4FE79F7503714C +:10F9B000B7D3651DE3DDF789147FEE2254BEC3B3D0 +:10F9C000CC67003E483AD211BE84B8A7C2FE2F9839 +:10F9D0004EF1A59495411ED77B0DEE4EAA37D40962 +:10F9E0000C3FEA7670FE760AB2BB1E8DDDBFF9DDF4 +:10F9F000C6081EC3FF6D8EAAA7E3D40BFE95206731 +:10FA000087514D29AD82E2EF73B1DF2F22419C5720 +:10FA1000C38B178DF1F0E2BF15BCF8739E6706AC7F +:10FA20008F9B69C2F92C7989437DC06108A0FE13C0 +:10FA30005E4CE5079D2FF92DC39BFFE4BDB8EEE6B4 +:10FA400065733D77D17D38D75AE7B98B56216B80E6 +:10FA5000FD0E307D6FD1E4401FF24122BE727B1655 +:10FA6000F4E74578501889DB101E028EF7DFBF657A +:10FA7000F8749BA2375EA39B89EB0AD713B187F278 +:10FA8000B9892F1EC432FDD772FB4478B07EE6B729 +:10FA90001011E0BA80C8064269ED01A713F7AF9EC6 +:10FAA000F41B185DFBDB3368BB26AA6F025F8BA3D8 +:10FAB0003F7C3F1A1F0F6BF0F1F015C3C709884F49 +:10FAC0009F1137E2D36D1A7C3C9C001FDB07F0B11D +:10FAD0001CF1596D4FF550624E1DFC3DE08B276ABD +:10FAE0009F176E8E2D93E7A2CAB98017B41C852F7D +:10FAF0004DBB2E1A3D71F064DD80BCF717D58C89A3 +:10FB0000E6136D38BF230A1EADBB657E36F0E935BE +:10FB100060700C513AA800F946FFC27D234113EDF5 +:10FB20003FE9AA8132D697AF6065FFD65F7B375C2D +:10FB30004BC87ABD2F5BA4F0AAE3BD7D3A902FF9A4 +:10FB4000BEE79C6057E83C3902EEABA7D03B0636D7 +:10FB500094E1E353E35A8A5AE2C04F9DFF7A2E1094 +:10FB6000D4019FDECBF4376B59581F2D5FDF703205 +:10FB70003994D21B427C0DBFCA11B02B36726BB3C5 +:10FB800001CF36664B5C3B5D53D9AEB64AC45FCA03 +:10FB9000EB0B28DE35EEFAB06F282D974DEB07F40E +:10FBA000A3EBF62E7E1BF8E5F824669724B76CD5F8 +:10FBB000D1FE32EF748D6BA7F8F6A653C27192AEE8 +:10FBC000EA3A08FD84174B620FED276B85ECBCA762 +:10FBD00018C66F6943BCAF21F83EFD7BCBDBE0BBB1 +:10FBE000478690541EBE236D1C7CB7329DC3FD58C2 +:10FBF0003997CC7AA518A84844BD7ED82C916B9B28 +:10FC000000E5964AA41749B4FF321BA9AC2385DA54 +:10FC10002DEB6C04F975BA8EBFB3863ED78D63E5C4 +:10FC2000D4E59CA70789772DCE2FD348A671A9ECE0 +:10FC3000BDBF18598E6727D6FB71BF33AB5B4A61D6 +:10FC40001E9979ECE930F874F974FC43EFE9FD2B67 +:10FC5000E83A0F29F8B2746B5566B45C3B74C6245D +:10FC6000E8A8DE7C284BB5178216B0179696566723 +:10FC700002F3C8CD9F9602FBEAC889AD3FA7F7A45F +:10FC80005C05F2FB3D9EC0FEFD97C59302F4798DA5 +:10FC900081CD5FBBEF9F29FBD97C8123FE28BA6C05 +:10FCA0009E751EEDB0E60B42CCFB330F9A08A810F0 +:10FCB000037AC5C2DEA9F05D23E95F0978D8184848 +:10FCC00026FE28BAB82629FEB82A3D345FE0891CF2 +:10FCD000775C43ECFB0B69444E8BF75D46EC7BBADB +:10FCE0008E98F29ECF07D601EF4945C8E6A576F873 +:10FCF00074D05368F99C5F27EBC7029B63FCEBACA5 +:10FD000018B201FFA2FA480BECCB592984FAC63984 +:10FD1000CA9AA01EE4780DECAF10B6CDB446C65119 +:10FD2000EBA17DF43E9E9D652041DC9F30CE03E03B +:10FD3000278F2464D3FE4F0C12E869FB0F22FC547A +:10FD40007C8986A31CC56F32DAFB833A4A5725B9F2 +:10FD5000196B8B8BE896F5AA7C216BAD87F2810C31 +:10FD60005E17C32792CB06F806B2A9753A5EE13357 +:10FD7000D96B275F1B5D66DF47DA0FA981FAB26294 +:10FD8000D6BE2277E87B2B40F6922E9C1F5D470E55 +:10FD9000C06FA06CD2942DB43C26AA2C6AEA1D9A9E +:10FDA000FA2C4D7918FBFE8C359803FE81EADC11A4 +:10FDB0003502A5D333D9C1391C2D3FDAEEAC994CAD +:10FDC000E9B4B18CE9174DFB39374722F06B723338 +:10FDD000BDDEE20E19EA8A010EFD7DC0571AF670EB +:10FDE0002247E9C112D819C432B493A2DA05386C9B +:10FDF000D710F810DB25ECDFA5433AEF741D65DF63 +:10FE000005FE827ACCC31D8BBDC0D8FAF48C6F512D +:10FE100029E7194A1B36EDA9213E4B84BF9ECDF63A +:10FE2000BC89FCF50027027D0EE029F46B89D085A2 +:10FE3000FAFD9FC6ECFF1DA849C94B3F6913E8F7BF +:10FE4000FFD1F897F1A077FF499123EB397F118C0F +:10FE5000BB89F88A408E7FBFB1E0A08E7E77441FB9 +:10FE6000DA02BCB73DF76A84DF116B683847F59258 +:10FE70008772AB6A040ABF23E9A12D00CFFFC8AD8A +:10FE800066E5E1A1E13A5A5EDDD3C4CA05A12D5071 +:10FE90007EA567362B8F090DE769FB3CF93684FF99 +:10FEA00036313E5D2FCB65FAAC3ABF87CA3C4B7307 +:10FEB000418F6E60F267CEDD876703BF9DA323226B +:10FEC000A17C7ADB99632F6DA3F0D8D69A4C7A186F +:10FED0003A7A056A6F6432D4A772A20BF97AD8C94C +:10FEE000F41BCAED42E0D74B1E6F923A9D917D51B3 +:10FEF000C7CF1CD5B213FACF9C538C72C4ECF41C40 +:10FF000081F1D5E7F451EC79245764FC9BD779F063 +:10FF1000FB07AC7EF87E8D99AD8BD20FEEB345D941 +:10FF20009735CABAD6E4323D63BA73CA91DCF1A000 +:10FF30009F28F6CEAA40FA283AAF6E8E04C06EA46F +:10FF40007A8A6C063E5C9F84F64C37CC1DEAD766F5 +:10FF5000FB653ACEED1CF1027F51F949B7DD939D67 +:10FF60001A65377697D2B225E227E8AEF1642739D1 +:10FF7000E099A1031B4AE54FDD4ED64E954F99ED12 +:10FF80006C9CCC35453DB09E6481A0BC9B37ABB02A +:10FF9000A70DF58399386FE2F16473B4BFE3F5B947 +:10FFA0003A80A3BA5FDBCB3C2FE0BA78E6F750F794 +:10FFB0004D85EF915CE6F7A8E3A97E41F1EEF17C77 +:10FFC0001FF647F58D1214EC8ABE710490767C04FE +:10FFD000CE44088D87F7FF1FC2AB1FF0E9DBC2AB31 +:10FFE000B195F211DD25F011058EEBB9A03E93F12C +:10FFF00011F44BC07B9047CF3B7DC773A3E861CE24 +:020000023000CC +:10000000038DA867AAF34ABEFFB569DF234087A71F +:1000100090EEE6FC2019FD085A3D50B503557D359C +:10002000911DF8A9420F6ED5EFADCC23B938F4D2AB +:1000300063145EA9C42A021F3D62088D71D3F6477E +:1000400074BE675F83790FE145CA4306F5F7421E28 +:100050008FE39B553C2161DB2847044F56533C31CD +:1000600041FB1A03DA25DD76FFC6F98027B70C734A +:10007000CB12CA61A467B93519EBAFD11D25E0C712 +:100080000F4F1045D033295E617DF7EC42BFCCFCA9 +:1000900031B219FDD349FE1EC0BB520A00E86FF60B +:1000A00028AC077F08FA91669BD87883F18AF92DEE +:1000B000461256EF54F0B63E17F136A39D303F90EE +:1000C000E029A989D217BE9FC7F022B92CF4EA1FF4 +:1000D00040FF7CD4EC2E20CC6405FF12E9CAC4FE9C +:1000E00028BE8CC81BCFE438F47BD7E3D6AD8CEFA9 +:1000F000B9CB01CE0F5BBBC832F40FEA71FE9BCDCA +:1001000041D4C37526C90E7EF8393C595F08FDB548 +:10011000EB45C0132DBC2BF312F91F42F746FB8BA6 +:10012000E71865630ED43F6846BB40B5FBE6A430D4 +:10013000BA52ED3ED5CFA11D47B5FBEED4D873031F +:10014000F59D7F2DA8A5FDFD59C13377EF8582B9B7 +:1001500016B66EF03FD5C25F74DCDAE5E60FC1CFAC +:100160005C2BEB83461BF091299E50949D4636B044 +:1001700075F87EA5F7039C5A05B27E3BEC8FCCD672 +:100180004FEDD8FAE8756D32B075C93FB0C6AC6BAB +:10019000938DC591BEFDBA3E1A1FBBAE93E3957514 +:1001A0001153066DA7C8B93B5BAD1F7225F409EB6F +:1001B000A24FB29CAECB1559D7B23CC64FE7287CB4 +:1001C0006C90DCCD637A7C1CBBFDFFC67ABB9EF2D3 +:1001D000C45BAF769D7FCEF3FC202F1DE9262896C9 +:1001E00045F0DAB791AEAB0CF635DDDF86FBCAF031 +:1001F00093109B1BF8D89279745DF06CCB447FE12F +:100200001CA3B407FCE6E44729CA3A09F281251B7E +:1002100087235D52BC6574FB14F3BF2C317BD17F07 +:10022000B364B1E8964558FF2B680787297F45BD21 +:10023000A43596AF7F3D1CCC39B5C5D17030E5CC27 +:100240002D8EB3EFB211F139D1BEFF990FDFCBE59F +:1002500025F69790E5B17E0AF0E70E94F9C165ADF9 +:10026000DF8390BF1963BF9713E051E8FBD1787427 +:1002700044AFE0D13233CA1F158F8E5815BF900698 +:100280008F08D5A2818ED5756BE13807E018C72F8E +:1002900044F1A900E07844B1CF283E15001C553A3E +:1002A000B8B395F1032DDCFE9498AF7DBB7568F073 +:1002B000F8DBAE43AD4FB40E55BFDDC02DDE08F800 +:1002C000B9219B88EDA80787C6809DE430F88B6034 +:1002D0005E9B0C947E91AF303FE1678762FDCEDA82 +:1002E000F95CB8647EC1FA4DC42712E1E5E5FAF97C +:1002F0006A35703BAAC06910BEE733B9A9F5F3357A +:10030000DBC24F83DED49CC4E4F7D90356A47392B6 +:100310001F9A03F6C2B97D4602F2A0890B15C27777 +:100320006739CF5CFCAE2D590239AEFA738FED669A +:10033000FE5C99507B9D961B7CCC1FDD2CFF7225AB +:10034000C0E5629ED002F672F39E587F20DD0F1B3F +:10035000ECCF591DE987EF9B787F3D98D8EB0D4C8A +:100360007F59AF23018067C48F70B410ED9A6C91F0 +:1003700080FFAA49F761E13D517E8726A5BE298706 +:10038000F9D3203F01E32E309473305C9A1E3DFD7B +:1003900025C4579B7669E93B96FE1B2265EE220732 +:1003A000FD45D53B23F48FFE03C08BC9C45FC081DC +:1003B0001F909593A7F5FB21CFA159F13FA7F78691 +:1003C000A6827E632D0B10E0FBCD2799DD3471FFF3 +:1003D000D637C13F689FD63F1C54A866251EA5B5D9 +:1003E000D726EC5FCB833F4BB5B7A2FC67453363A1 +:1003F000FCA72BB01DF8E360BC10BC82B881C0F430 +:10040000F2F58A5E4EF577E4F3F3BA46A2FE0EFAF1 +:1004100035E849AA3F0FF426D09F77E757CDC8A704 +:10042000EB9C5D50757DFE78361EFA29C04934215B +:1004300031DEAAF051BF03BFDE57C78514FD8FB070 +:1004400078D03DBF48FF4ABA5C949F307E7F7BB432 +:10045000FF7D9FC6FFBEEFCAC5833281AEEEE1A429 +:100460004CA0AB891AF9B62F811DB0247F201E94B1 +:100470000974ADB63FC1FB30FEA1C61DEA21CE8294 +:100480007226887189BB5B88BB13F3407C2BA1DC8F +:10049000B890889D14DF1B26FB58FCA38588374E37 +:1004A000607156298ADE208E195D263B6839460E1A +:1004B000F6631CA489F6B0C90D7E9AD8EF9B89BF5C +:1004C0005A003CDE73D118D34F37DBD73B15FCDE27 +:1004D0006866F18389CBB7F224CA8F9332CEE37C6E +:1004E00008E8F7177AF45FFFA7828F2A3CFE9C5733 +:1004F0007513E05512F8D5E0BB878CA8C71CD791BF +:100500008580DF6BECE4CE99F479F641E2C9D7033C +:100510001E8B39D1FE44F5D9B9CFBC10E8E219855C +:10052000EFA9EF2BA051BA120F40FD3F19F3472856 +:10053000FB2F01BA29CF55ED0E520271880F157E9F +:10054000DA74ABC507FD85748CAFBF98CFE4C08B60 +:10055000F906DC3FB53CE08F53E8828E83FD255DD4 +:100560004562E2D73F53F055F58713254EB7BE3E9F +:1005700089D92903F4A943FE9B5CEC35F890FF551B +:1005800021FF0D7F6491002ED34E37D4C33A3E9D98 +:10059000954420DFE62E254EFA6EBE1DFB55E38BFB +:1005A000FF40BA8889935E2A5DFC3E421731715242 +:1005B0000AD764900BFB74CCAEDD47110BFD8201B2 +:1005C00025EE2E100FC8AD7DBB46A21D3357F15747 +:1005D00053BE81F66B98CA37B6DFBE8DF3E0BB40E1 +:1005E00001E6237CA8F73FBF1DF49903CC4E53F7D7 +:1005F00063DFBEA17EE03B134F7F9103F0DF77F214 +:1006000085A190E7B14F89AB37188285E84F31302B +:10061000F9DE600B1602FC5E57F0A6218996E9FB15 +:10062000BC745F18F05ACD8B8176765C8F64037F43 +:10063000CE31C54E3F4AED769817A5967E88F7D302 +:10064000FDCE8672787526D3A7E9BC002F8E1D18C3 +:1006500083EB5BAF67782CEFE5D0FF73541F3ED17F +:100660004ABF3F9A7D156913413E5FD8DE07FD3FC3 +:10067000CD13A30879479F9FDF43BF3F378417C13E +:100680002F59A7F34ECD067EB19BF943B4FB00F280 +:100690003A3AAE7B968473D06FBA303700F87376EF +:1006A0007F11E6D3118748645A6EDECBEC476D7E2E +:1006B000C4717D2CFE6BFB857581FFB219FE067D32 +:1006C00024BA7D9CFEBEAE7C561F2A5C46E13145B5 +:1006D000F24905517E80E637B2518E1C7BEC73DC0B +:1006E0004FD2C5E2E8C7F59E39303FFBE4A0A13602 +:1006F0000A1FAF2E50FC5046A65F50FE6B88E637AF +:100700006A7D7915899B9F525EC0E8DCDACFE4F4FC +:10071000E07A86E7F7926779E0175743320FED6F7B +:10072000849267732FF9ECA011F4A94029E6F18CAB +:10073000581E443E40E78BF8797C630AF247F22862 +:10074000C3D7F93F3222FF984FE507F367B0BC42A9 +:10075000F228CB1F3AF19013F1B97C45B01CE9C1E6 +:100760004EDCA047BDD6F1A1CCD3FAB93BB852C8F4 +:100770009B9CDBE1443BF0EE5D4EDCDF890A5FAF22 +:10078000337A304F923CC3E29C773D518FE334265D +:10079000133B8FFAB5DF007AC4C21D1CC6C32706FF +:1007A00018FF6F108207414FD7E6FD107F6CBE0126 +:1007B000C82312A5C783FC211ABB2B76DFE54BD2D9 +:1007C00017B472667141427DE1EFA4C77F337D614A +:1007D0005981AAC7C7EA0B60FF17303C64726D27C6 +:1007E000C7F89CA22F3482BE00BAB022A75539BFE9 +:1007F0004091F32778A667CC37AEC5E79A0296E713 +:1008000070370929790E6103E87F89F0788D322FDE +:10081000158FBB008FC747F0B8E164B0CF887E0763 +:10082000F76EC8D368584E82566AB7CF175A509E93 +:100830000D118988F9AFD53E9C57E6126AAF51BCBD +:100840009C0FB1FC7197AFC70CD25B34FA8A3A6F38 +:1008500015AFB5FAF5C4E57E1EE28BBE9104DFABA1 +:100860004F91044A61BE352666DFD4982C411EFCA8 +:100870000F93F567A2EDCF1AC1F322E33BC3EC2738 +:1008800046234B23D0EF74A7E737A3D2237A7B729A +:100890005978E563B43F3D29D1015F57C7373B2BFA +:1008A0003F298638AFD08FF62BC962F92C478A19B9 +:1008B0005C93E93E6CA570D50B32C24F6F12ED6DA3 +:1008C00076D8FF7E8CD385D309FA6DD5FDDA622503 +:1008D00032E4151F2966787FA458C4276D8FF9006C +:1008E0007A176D4FFBAFDA67463E727EAFD50FFACF +:1008F00004959323ECB43EE34FD40EA4E5B3FBACD4 +:10090000A8579D55E49B43F5DF9395B8FFEF2A78F0 +:100910002393AAA160EF11EE86A174EE44B5431AA9 +:10092000ED89E2DA4ABDB3FF5686BF46D46FCEDB0F +:1009300043F74199CE0773E0FA14BC6ADE555DFABD +:1009400000C81BAFC5CDA0EE2B057DCDC82FBDD5F2 +:1009500044813D955F1E5E06783FDC221A6993C98B +:10096000233EF8FD6C5AFE68979E18017FB6DD9411 +:100970001284668227CB3B66F07CEAFDFAA3A128AD +:10098000BEB368476CB931105B6E26C2D15094BCBF +:100990006AFDA0FED76F45E1DBB902AB03F08048EA +:1009A000C47D91D2D3F107F7906320BBF93B52800D +:1009B0009FDF45D9563C7AFFFCC185BF7E8B7E27E1 +:1009C00018AA3E2F40FD5232007DD5523D279E9DF4 +:1009D000BF4DE16B4663CBC9AD143EC6D78DEE3635 +:1009E000DAAAB7C0470AD3C13E0EF7C1BE1A479C68 +:1009F0002981F846D5882F30BFE4FCBF1037C0E905 +:100A0000BCB912F1E9FC46B3047E80EE1C0BF3CBBB +:100A1000BFC1F9396617CE184FEDE9853815E0BB2F +:100A2000E1951B41AE4C308A2B445CAE4987FB4DAF +:100A3000AD63FAEC36C82BC1CFDE4D0DF43637D896 +:100A4000D1FD362086A98512CB9FE05F3498E89FC0 +:100A5000CE0E4F511BFD6E91378940DEACF0A5E004 +:100A6000053C7B18BA8AB22B8715323ED3680A1927 +:100A70002AE977CD5F2C9D96AE8BC47D8C7A9F67DB +:100A8000289DB77E4F6970287DB5A0B51AED672AFD +:100A90001F185F3CC0F8E2826595F89E9B390DD720 +:100AA0007B82AE17E0F2E64623AEF7C4700BFA3352 +:100AB0004E6CE1B0BC403460DE2DD5A7D22A1DF0CB +:100AC0005E2F1AC96078346F7878E5465AFF6E3623 +:100AD0004F388AFF7FD9FC738C4FFD85B0F1E55DFF +:100AE0003CEA697F11C3E54180A7D4628BB6D71772 +:100AF0006CE1BDC02F176CB9F7DD0900B799B79548 +:100B0000013C26D99766489648BDAA9F0AA915DBDD +:100B1000812E277D59DD3F09F4C42D946EE8BC0574 +:100B20001DF181BDF4D696EFA27DB0A026C90EEBD3 +:100B300093366F9B0AF2F82F354374B8AE9738227C +:100B4000023CECAD19F07E012778E3E1D5E1021E0D +:100B5000F1AA7284C50DF271C1EF78C4174A67B764 +:100B6000425CA9718B1EED8FB7661EFEFD6C47843B +:100B7000CEB8991B664C84EF7FACC7EF07F4BFCDAE +:100B80001F7F007E17F84735119043083F2DDD1970 +:100B9000472C2F847969E96FC18A964296EF717963 +:100BA000744836333AF41572C8A7BF011D2E2CBC09 +:100BB0000C3A24C35263F48EC17C4F46BC55E3E526 +:100BC0002637F16CB3607E9487A3FC7A6DA180F523 +:100BD0006B0B999D29FCF59E1DBFA2704A2BF4FD5D +:100BE000A010E42BF194827C96C26215B8E62D8A9F +:100BF0009E4B36B3F318600FC1FEAF4F27DB3BA30C +:100C0000FC5F8F417FE9C817DAA19FB37FFCA20F79 +:100C1000F6AB29E74C09D801CD17FE0BF36C2CFB82 +:100C2000597E96C51DC6BC35BDC38BF8A8F2FD66BE +:100C3000379343DA755D28D4333EED08633F635C38 +:100C40008C3ED5F8F4A6D6248C136E72F8CDCC8FDA +:100C500045F553DAFFF4321EF98CA9AC9D801C23B4 +:100C6000153CC6F7267DF16B02F1D077AFAD7683E8 +:100C70001E6C297B5348837556E895FA9FAECAA52A +:100C8000F5BFBE760ADA73F764F112E853D3CBF2FC +:100C900064949F1E96273FE98B14A4C319F5335023 +:100CA0000F56E7EB2526C942F1642625D6E8F30462 +:100CB00033AE354B9628FCFAB48B9BC6EC0029E585 +:100CC000E631CCEF162866F23C1A0EF7641970FC78 +:100CD000D905952F01BE4CBA8EEDC3A9978CFE1590 +:100CE00074DC53E6F8FADDFE42E647C815AE47BEAF +:100CF000B4F42523E66B9CE6E27F7FF72A1EF3CC53 +:100D0000EA5771C44FC73BF5FC6B39C0D73FDAF6E1 +:100D10005A4E6DD47C12B5FF6361227F76F0AE68C7 +:100D2000FFC074038B139171C6187FFF749B721EF2 +:100D3000E612E35FFF9430EEF38B6130DF5F0DC4AA +:100D40007DDE19161DFF1A8863BA59DC471BBFCC1C +:100D5000AFF83765BEECFC41ABA0CCD76D6471AC8D +:100D6000792C4F62C98134C4BBE986F0E318DF7C7B +:100D70008317953897C784EDB3587D8275118F27F7 +:100D8000DF518EFE319C0FB7870B5A6DDF627D8479 +:100D9000C5B5B4EBABDDCFC78DD336BB585E48725B +:100DA0007118EDC0A3EF3C0B991803F86EDEEFD479 +:100DB000459F5B19D06715FCBE09F09BAECFBC8A7E +:100DC0009513E175227EF5A822B755FC3EBA2A2F6D +:100DD00005F0ED215353A88FC2CFC3A710F3105ACB +:100DE00056F241E40FACC88778052E4491835B3EF0 +:100DF000B0A27DD6AE6F7906CED9C96D02D946DFD5 +:100E00003B929AFC6DB42CE9AD9847777FD28CADBC +:100E1000608786A882CBD1F2E74947B6829E404CD4 +:100E200029444FC791AB94F60693D84EF58BA79201 +:100E30006DC85F5AEF2228BF334990E32840DC2376 +:100E400073991F7CD16E0EF3E729C583DEE7CE8B45 +:100E5000AF8F168C64FCFB8F905045D7EBAE8EFFA6 +:100E60009D7BA4EAF7137CA128BBF461CE2D29F960 +:100E7000E404F265F5A47F36F265AAC7FF9ACA8337 +:100E8000A1FC2BE8FF3EF6A0EF9978E792D4E75D4E +:100E9000D5F1FD0A1394715D5D9C5F6F43FAD56DCA +:100EA0008DA15F25AE6BCD70530903F17C16B7CDD4 +:100EB00027EAF9940D10171952C1E668F38408E87F +:100EC00017595DD7135F1AD0D3C44C906F4BE6C54A +:100ED000DAB959B5ABB2D10F597BDF0C90DF1BF4F7 +:100EE00096555C0A3C63FD871B34FEC3AFE30B5988 +:100EF00009E9664216F8633644E2C1883FED73455E +:100F00003FCFE12A48749E4346BBD4E7033DA8D2B5 +:100F1000E4EE710FA61F52E1CE8275BDA8EE9B4292 +:100F2000CFCD0A6A72FB39B44B07F343059E8DC3DC +:100F3000109EE6AEFBD16E4A2E657EF7E4FA5A1F8C +:100F4000F09F64CA7FC08E33185A38DCFF89CC6E9C +:100F50005BC2B1F2924A5194E9F7069B923F7D033E +:100F6000ADB7039C7CBE68BFC335BA7B2AA3F3B47C +:100F70004542DB031F9EC5C69B6E5ACEF2C47D540C +:100F800047CA8EC0B14A81637E45123B6771AF0983 +:100F9000FD719BCD5D385F9DC4ECECDA4E33F2BB46 +:100FA000A1BC0BE352BD7A861FB2D584F4EAEE7D74 +:100FB0001FF305875E9D25F1CE28FC59CAEA55BC72 +:100FC000209A3C138341EA037F239D881BF2949669 +:100FD00070525F15AE4B0CCB6E58B7C2974B9298C0 +:100FE0001CA1E66616832B8B3B6AF68BE20D8B0306 +:100FF0008CB1303F17F149A87769D63B186FF6BA24 +:1010000080DFF60EE0CD1E573C7EBBC62EF5F544C4 +:10101000E30B9156821FF8111D0977C6C31F77ACE9 +:101020009DAFCD9BD4DAFB4DADD55EC5FE904DB8DE +:101030009F06B43F9A96557A99FDE16A037F59F36A +:10104000722AA9689BEAFD9C09FA6B9E6543FBBB6B +:1010500079CF4ECCA7689A46DC308D5AC59FADAE8D +:10106000F3A89EC549A9CC0A403E47B73DF4349C3D +:1010700083EDAE57F3BA589E93BC8753F2BAD43C73 +:10108000C0F011F0D7767312FA6D07CED3D2FD6798 +:10109000F95C979717682DF63AC112FF69C17FFC7A +:1010A0002629FD32F2AAE582755F9D579D742BD4E7 +:1010B0009B602F947A4003AA2FAB658F59827CAE38 +:1010C00048BD40ED4ED31E8EB597D7DC3245C07378 +:1010D000704AF9F327E1BCEB1A3389192F7A7E8223 +:1010E000A67F302D2D92FAFD1F664EC9C73C48657C +:1010F000FE154F7A86D1FEF4B1FD21CA28EDA1A0DC +:101100008EF7C2E863DD8F0E8BE8ED548FFF6CE441 +:10111000F888FEFEF0E1E95D63E958C9E26778EE20 +:1011200050D5C39B1D2CCF5A8BE77F53E414B58752 +:10113000A7826AFDF0ACC55EE877200F72FF5C0FF6 +:10114000D8C16A1E64F3722F9E3FA47ABFCE057980 +:10115000D57F3C73E220013BF314FA039A2F08CCAD +:101160004F4EED078EE28B69FF5AC41FB243EF0763 +:10117000D74EB75D26808FDD07B8F1805F84B4E479 +:10118000DC42617F9BCB9384FD25C83FC873313F10 +:1011900077B3AB6A6321C0FA398E803EDEE9FA1478 +:1011A000ED8AA6BD53C6479F97ADDFB38E9DBBDCCE +:1011B000A18FBBEE3C17CB776CDAFB2AC67B4EF9CE +:1011C00039A4B985827F35D89B0B17EAC0B2226556 +:1011D000FEB998374D661908CCDFACD821CD3B6EEF +:1011E00092E1FC6E33FD8F9200D9E49D8FFAF6A652 +:1011F00059260BE40934BB6A1723BF13933C60CA1A +:1012000069E739900FB92C09F3AA3AF7E8A7819D4D +:10121000544EE9E26716E0ABEF39B702FF4C1BC74B +:10122000B78B90771A5FFF2E1AC5E45007E795FF3A +:10123000B90CE338243ABF7DC41E667F4D74196231 +:10124000FD932E66175E2BF75703AEBD218492C126 +:101250001E6E269E4FC0EF45BC1609E3582480FE43 +:1012600040C78312DA4D2647E891B1507FAD8076B2 +:1012700093EA4738BB3713F5B1975DBEEFC23E9690 +:10128000F3A127FF19E0F688A0C4C3185FC9B9C944 +:10129000320EEC2BBD83E93366AACFC0B9A1EB5661 +:1012A0001FFF6535F0568717F50842851CDCEF50A7 +:1012B0006DE2583C48A33713D13D19DA4F55FCD2A3 +:1012C0000574B74E9810353B2EA6813FC32103BC51 +:1012D000DFA10B48A3F55388A783ED0BDBBFF50611 +:1012E000A6AFAFD799505F57F5E164473FDA898DD4 +:1012F000010EC76974BD82E7471629E71406CE0BB5 +:1013000008213C3F51EB4A56E2B01D0C3F493FFAE1 +:10131000C3C88B6C1FA8E689E72A54B8ABE70CD486 +:10132000FE0C4A7CB751F1E75280317A74A9F1DDA5 +:1013300015CA533D07C2C62582541EED775C5F4334 +:10134000483FCE4BB2C17C1FC9F0DEE7A2DF1FA52C +:10135000780C78767455B29F708047FD1E88D3C88C +:10136000A52CFEA2C5A7475C9C72CE2C3C15F3F0C1 +:10137000F6263867B627F69C19E50F8BDFA6E394AF +:10138000951D76037EAFB12BEDAF2778BE407BCEA7 +:10139000AC4BD987FF73E7CCDC9CA7873EB7BAEC90 +:1013A000B1E7CCDC6CBFD43C19EDF9B2B3D94181C3 +:1013B0009D07093DBD0DE5A511EDC2D73FEEEB0040 +:1013C0003FF3B952831BCED564DCF64E07E62B7192 +:1013D000420BC44FB5FAC0EF9CD53F01FA5977CB09 +:1013E0006E37E68F6BF481447E008CED46F9890EF2 +:1013F000B8AEAC1FC0DCF5B90DF0ED34177E1CF2B1 +:101400009AE5037CDCBCE60F5C89E2629E59D1FA66 +:1014100069879AFF674F8AC987ED4890FF9748EF21 +:101420001712E6FD5D8FFA5BC740DEDF34557F8B18 +:10143000CD6B1693BED25E56C79F1672C6E4117C62 +:1014400072C9EB54EC9804EB4B64B75D6E5E841686 +:101450000E1D09E4E85F5D03F13F4D5E8447843C67 +:10146000820EC823A04F812332FACF760EE44504C2 +:10147000D15FFCEA48F47B1913E645B0FC3EE1C0BD +:101480004809BE7B58EFF5803D23EFD42B72C0FF97 +:101490003CF84D3A0E64A39F8DB84225C01F05FB52 +:1014A000D42CD0AB3A14FC6CB8F4BC88B4A2387914 +:1014B000115BFDE31ECF65F6737F32D5CBB61226E6 +:1014C000A7E4FDCCAF49E78D7EBDF063C3515FE576 +:1014D000669A701DC7DE30F618510F77639E436D14 +:1014E000162F827CE9AE293F01F2EB18555C818E04 +:1014F000EBEE5E8EF66BA2FDA95B151B7756DF5FE8 +:10150000EA3E8D2B62FB7414EC7B14B432FA8B1719 +:10151000AEE20E62FEB626EE5D56441439119BC74C +:1015200070DE5C89F1D8FB9EA8C138EC7CD282CFFA +:1015300085A44B89CBB2788BB44A403921EDE0FCCD +:10154000929391890E6D7B5187F7F550F1B609445E +:10155000A24CA9E66AFA9AD371A0A74A1DB49C4985 +:10156000D7B55A90B3E8775BDF4F46FFEBC30E4920 +:101570003957C3EC2FF9510EF53FDA2FDACF720746 +:10158000C51BDACFCD452C2ED050C4FCC91445FC68 +:10159000381FE5D9A1E47DA8E3B5115D109E3A8E10 +:1015A0003D1F168569F1F43BB5BF0E7D8B09E22D19 +:1015B000E1E13A8C679E377866613C30B59080BD3A +:1015C000D8616D59358DD5230F3D6F0E7BB1FE3B34 +:1015D00002331488940AF3BD41D90FEDBECEEB8AD5 +:1015E0002D6BF313B4F77ED411DFC8ECBCC1F760E8 +:1015F000DC50C4E4E1F94EA7B22F6E8C9777E8A5D2 +:10160000DF38413EAE16500EB70D6370D30D67CF75 +:101610005CFBE4592887ED543FC5F9B2F9E77EC772 +:10162000C101FD75D8197E7DDB796BE7BBB4A810CD +:10163000F7AD038C063A5EC76ACECFE0C5E67DA95A +:10164000FEEA278AAEAC9C3AC6B9B70701CF2CFE9A +:101650001F81DFAFAECD28023F3BCD29F4BF9A47B3 +:101660007EB669612A968FAE2A403FD000DD9E5C2F +:10167000B918EE33B9D47C8AE714BC7857E387AB4A +:10168000ADE0DE837EB47007841254F9439B56DFCD +:10169000543C15F863938E4899A00FACD2E4B3681C +:1016A000E8798AE47BA508EC0F437F1FE353A1424E +:1016B00001F56FB31BE0B64E776CE7CF015F769A0A +:1016C000313FB26979783BF82B3325DF5E68776666 +:1016D000D9E1A99C84DDA19E74EEC048BC1FA7B6C9 +:1016E00043738FC7A3B1793464552ACBFBE88E7D51 +:1016F0000FF737C4B41B945FC3F4D6F5065F11D857 +:101700001793AE6379891FD7EB08E0C5C766863F9C +:10171000F2635645CEB80BA3F5DADF6BF1E3313354 +:10172000E2479D72EE4DBB1F8D801F74DF1A14FCC3 +:10173000F8F8D5AB0B013FCEECBCBA10F063BDBEE0 +:10174000CB03F4B53BDF7718E0717C8AB74FC7F85D +:1017500052E1E5E0ED4757186F2F55BF328D4A141F +:101760006F91EE888EB7F4EA999F4C36C79E1BEBBB +:10177000BD4CBF6A62FF58517EAC7FCC951F57BFEE +:101780003299BF52BFBAFC75103C37A8C6617AAD1A +:10179000E1C7B747C16B8999E5A32C291245B91454 +:1017A000D6579B87E710FF6872F77057749D317E9C +:1017B000C037BEC85BD905F3F030BFE51B82D477D4 +:1017C0000D1DF70DC2FC96DA75DFA8C46154BB5B32 +:1017D000B503B5E3978C627AE6A4519E52B00B260E +:1017E0007D7111FD0827E11E2C3AAEC9FF33B4E725 +:1017F000C87E4EC4738C128B8336ED9DF72CF85D3A +:10180000EBFD4AFC721787F67AFD739F60FDD93DA8 +:1018100075586FD9CF05210EDA3C4C87725BCD7FAE +:1018200050FD3FCDFB4BD1EFA3FA7FE83CC6805D76 +:1018300099EC081B906F817D49DB35092CBEDBE4F8 +:10184000206E1958ED9E58BF899A1FB5C96B407A12 +:10185000DFB49FF3833D9E61F03987213C87892760 +:1018600092237C63FA28CF4AC87352F3EEE0FE9FBE +:1018700051E3D10F9A83E710F4EA7D2FB1F7F324F7 +:10188000C2E70509E986CC89C6B790260E11BA626F +:1018900079CCB351DFFE6FE2457DDBA7C1B75002C3 +:1018A000F9D23C4ACD63BE15F57DB5FDE0FC7E3F27 +:1018B000CBEF1FC8CF6379FC0DD309E9B4B332DC99 +:1018C000EBD408F73AB999BC0F6AE47D7419F2E1D8 +:1018D00082517CBE41E8C77302EA3D4E901F17FD5E +:1018E0007D139CDBC963797231FD28FC3F93BF07F0 +:1018F000E35571E2C47744DB4B8754BBB0543D17CA +:101900001636803F6A499B230C718F4356E5BCBA5B +:1019100092AFBCC41C3E06FE9A25CF67E279A201B5 +:101920007BE425A3E2EF6774DAC0FE24CD0B8FA21F +:101930005FA219EEA5E022FB363DA11DF98B7C8844 +:101940001F1D1AB023DFC987F363AA5C687033FEDA +:10195000D6B08763E70803B1E7C85E1E7565E58406 +:10196000FA5DA2F6874625B24BBF0ECE0CDF0F25DF +:101970003A7FA7F075158E5ABCBF5CF8A9F503F045 +:10198000A37C08E583067E5ABF9FEABF231D22FA87 +:10199000F7A80E1580FC53D57F77A9F2FB43054EBF +:1019A0007F6FF94D4627E243DF6E7F12F1A3CBDD57 +:1019B0009741F21BF6A724B1FCCEAFF83765DEDA0B +:1019C000BC0965DE9ABC8943FAF00C760F0B858F53 +:1019D0007370DE4442FCFB9ABC896FB04E4DDEC48E +:1019E00057AF539B37F1CC81A76C105A84F38BE02F +:1019F00027E9DDA6C77C81A9BCC5C3F2D97896FFCB +:101A00004A3C785F6FB3C98CFE106DBE1FE5542B46 +:101A10005B401FAEA0760A9C97DAD28E7A4463367A +:101A20008FBE55C86F14A538F9A4424D4A501A9C70 +:101A3000D706E70BF05E8BCBCC6BBB66B4D581F2DF +:101A40005722CE6F985F5A3D1AFD0F5F9DD7F65C07 +:101A500001C3FF372D9FA545DFA75B552C13885386 +:101A6000253A0751339A1BC85BC6F38A824CA2E51C +:101A700071A276B34733FBEC4D43F8FD00E881B427 +:101A80001B88D36619A8F55F16B9AFE13697F7F64C +:101A9000D1E9A83FE1FE9EDDFB078C4F3C934D440E +:101AA0003897F08C5EC67D96D309E2B59A7FA18EF9 +:101AB000734E89A35D2AFF593CFAEF2B171EFFBF17 +:101AC000CE7706E569317AFC06FC06E96F809FE86F +:101AD00059FC4ABDAFE56BE5DC95E6339AFC9244D0 +:101AE000EB6A065AA4F8F3CA68EF8B8C8E3CE817B1 +:101AF000BD5CF9975C46F52180C72EA304A466520D +:101B0000EE65218F66AB7E5C769FE79AE1A82F7F1A +:101B10006C66F355EF9B51D7F3B6163FBFA5DDFDBD +:101B200078BEF7E7405FC72B3D780EFC612BD3DB17 +:101B3000C2CFB33C7DEDFD29946ED87D32CABDE0A5 +:101B4000DA7B20FE38FA1F23BF2F8CFEDFD1AFFED9 +:101B500051F2FBF2D7116B7F1FB2B23CC888FDFD7A +:101B6000BFB6AECB92D76A5E747955BF129FE008BC +:101B7000C427D4719AFBD9B9A2A1CA7916F5FD8DF3 +:101B80008A5E7867B167189C9F292B0B3E0DE76B27 +:101B90009A880D7FD7A02970FF8E5F39D8F9662CFF +:101BA000BB587C95782D785E3FADD057588CF41B90 +:101BB0005A09F439C241CA21CED1E99A49EA2C988E +:101BC00037310AEA472C0F3DFDAB32CC1B6B017A53 +:101BD00055F3A6CB2F7EB6725A19CE17FDD50E63DC +:101BE000ECBD333716337B507D4E53E64FB73D1B6C +:101BF000E67366213BEFDBECF088E0F756E3F4C9CF +:101C0000523FE63934ED62465139D88A50FFC03030 +:101C1000A4AFA65D95A510BF25017329DE07FE2799 +:101C2000760FFF996543D03FFAB2CB5709F3B696CA +:101C3000F9AF07BB7F041D07E2BC67765E5FEA8BE6 +:101C4000C33733F95419E2E0993C093C2946F816A8 +:101C5000B5F767A37F7B6518FD6EA5C5EC7DB383E3 +:101C6000C9F5E6FD35649E2552B63862CF8B4D1A14 +:101C700035A514E6515A2C2879A42C6FD549D530B6 +:101C8000F0736AF1C9A9E4ADD62879D9443645F292 +:101C9000B173BF3E6F559D9F5A56F356932F30BF79 +:101CA00043AE68C03C17EB2AC657C97282718E6B6F +:101CB000C3FDD529144EF9DDC16B014E290076BC58 +:101CC0006F39F4C858FADE91265C0BFE9BA75BC700 +:101CD000F582FE2BACEEFF0E6C89D42556814B3479 +:101CE000ADD0DB887824B4B8802F55FD4ECFCE55CB +:101CF000AD4E46BDB23BA701CF559D3D6C8C7B2FB1 +:101D000085FA94C98A2C8893E4AEFA77CC63B0EE56 +:101D1000E2E29EBF7BB7D8A29CBB5A91057117EB3C +:101D2000AA7EB982F69FFB184714333A9BCB027FF9 +:101D3000B6A003F95AB787DDCF58D765AF32A1BC3B +:101D400061FE2572AD03E588B0FA461DF009A18D4C +:101D50006AB1749D6F17B3787A41B7A80339F5AFAC +:101D60005FF271E35E4F1447CEE700B81A8DE1BE13 +:101D70002C67242F493D97A3FAA706E4CFAEB9E814 +:101D80009FBAFC3CF4F0ED98E7F86506C683A6DB45 +:101D9000983D420591723F516CFB41F713297A8BB4 +:101DA0006A176BE9409BD79D5F3104E982F2D1C08D +:101DB000263186EFC5CDEF6E1598DE4DD7615802FE +:101DC000F3A8CC72833FF152F3E9B5F6F4809EA3F9 +:101DD000E825EABCBF69FEB95ADF0079E771FC1F4C +:101DE000AA5ED3A19E33FF92DD1F3742B1278E76C4 +:101DF000FEBF12764FA79AE7E267E754F4947F227A +:101E0000FE84AE93010F76D9754DC5180F6BC27E57 +:101E100056B3DFFF18B12A6F4545193C45C25178CA +:101E20001FDDB76804C69B295D14C4A18BC5C5EC32 +:101E3000FE06617532E2B1B09660D6A660CF403C36 +:101E400016D6317C5DA4D0BD9A67A7C62DEF2CF6BF +:101E50001D2B4E8FBAA7A53589DDD3A2E4AB5B5B02 +:101E60000FBF04F79F3CADC4AD7BDF183D13E38982 +:101E7000AB050EECC3F3F6B923C07F7756E1DF560E +:101E8000A19F8896687AEDC5F38EB907D8392D41A0 +:101E9000C9AB15563BB6027E9A9D3E3CD7F99D8E46 +:101EA000208F795BE2F127A7496077840D906777EF +:101EB000AA4D08AFB0A3FE14E327D3FABD8810C023 +:101EC0003C22DD982BAB47A9DF256A2F8D49A83F1F +:101ED0007DABF322E46BFC53DF16AF13F9A72E7F23 +:101EE0001DDA7322CC3E216FB07CAC38EB8AF15FF7 +:101EF0005EF175A97E4B6D7EDD203A66FE0FD51E24 +:101F000052E325C423C7E4BFF7EAC520E83D904F5C +:101F1000FCAA1BF4EA1F9BA3F3DFAE1FA38BBDB784 +:101F200092F8CD701F429D723E9A08EE5510B7BDD3 +:101F30009FB776817DD70EE71240BF04F87251E754 +:101F4000333EB0629E46ABC0CE6F10999DFF5832B3 +:101F5000AFE5C7D07E495BA608F097AB5A7E8AE70B +:101F60003B74C4DB4E9F9F2BBF87A3CE473DAF90F2 +:101F7000487E0E3AAFF035E72DB2139CB758A0E07B +:101F8000BDEB2E82E72DC82ACF569857779B40206D +:101F90003E9D3A8D95470826FC7D2633E47DA7E1DA +:101FA000F958CCCF0E5378429EB919F2BED3E03C1B +:101FB0000CBBA7939B390DF12F95C207F482763D98 +:101FC000BB9753BEC582F8543D8DC55B53BD06E437 +:101FD0003FE7881BCF09C8707F9F03F06C05E2675D +:101FE000D89A81F1E2D47CA6479ABD069DC9897929 +:101FF000DD88AF614ECDEB667CAF7BAE84F9F60336 +:10200000F774CE23B83FAB0BA666C3EF920CB9C9E9 +:10201000C0417C499533550A7E746F55DA37B2F664 +:10202000708F27CC8F2C61ED07EEF1FC3EAB6F1566 +:102030004278AF14D561947B2459FD92D919483F59 +:10204000BC722E97DCA69C2BE0D83D644B660F61DA +:10205000F536C607C9DD498A3C57DADF9BEA57E205 +:1020600005EC7C40BD4EB9EFA08B44C79F553AD3D9 +:10207000FE3E4784CED8F9922722E704909EDBAF3C +:1020800017310F52BD87B4CA6260E7CE4CB17435C8 +:10209000694C2AC3FB0AB709C65DEBF4FC644C5CCF +:1020A0003F8D7F6E345F19A2F295BB0D1ABB2C9346 +:1020B000C1D5167E9A9D4F335E965D96380EFA7C9A +:1020C000766C1C744776741C54DDDFAA8506E42BFD +:1020D000DD76E92DC897DA44410BF73A6AD7BD6936 +:1020E000E07E76BF19F452AD3D7828415ED4E931E7 +:1020F0004C3F7427F0439C1E93C8CF9520AE5C6A7A +:10210000FC5F8A8F33FEDB9BE03CE200BC54BDC920 +:10211000A48D7BC897E5F7E935FD10F9A0A75D20F0 +:10212000E6EB6859737E8EF241E48BF20AA3D8EE97 +:10213000003EFA43E48BADD4723546F1456A8E5EBB +:102140000DFCB8F74117FEDED55B0FBAF179CECCA6 +:1021500005F8B1F00CCF018DE993970DDF83FBCD2E +:10216000CF59C33970BF794A207516DC577E2E3D92 +:102170007C04CAB69FDEC1CA05E1A7E1BEF3FC9F9D +:10218000FEF27B58061A1B42975B12FC9E5C0CF712 +:10219000EE8756F6837E5FA63977A0B97F19CEC742 +:1021A000C27A322D068C53672AE792C964C53F0470 +:1021B00099694077D9A598576821D2AE7EA81FC6E5 +:1021C000E42EAD6F83FB7DDB0B9C2C6E4E181F2025 +:1021D000C394BC131292C11FD5EEB463FB01FD6E14 +:1021E0009751C95B63E3BFF72ABB37493D6F4D8801 +:1021F000381CEC468B4462CAEA7DE6441087C3FD76 +:10220000C3ED6ABC5A291FC8F48D2A89B25FDE9BD0 +:10221000727F31ACF3E3DD0FE4833EF55DE577E2F9 +:10222000B478F5D7B14C8EAC48FEDB1CE0E3EFF39D +:102230003637F80F9666FACAA0BF798EB6F1768A5D +:102240003F93C54AFC3DAA89F26C0EF88AFD6636BA +:102250003FFB642F37AF38F23B55E93E01FDF4C434 +:10226000D7CD83BE9D7EDC2B027C1A4CE11C81F60F +:10227000F381C33709FA3D3FF7C3FB308F70C87B4A +:1022800047E05ED4F7F45DD536C027A7720F36114C +:10229000F01C50DFD0113DCAEF6DB1F340059C1228 +:1022A000870D4E06B9700361780B65A8BF51B987D9 +:1022B0006EAAC8EE8D9D5AE6C4DF4F9C41C202E073 +:1022C000C3D4F7BD3602F471B3AF2CDE3D1BEA93E5 +:1022D00064E9A568FAB95E8A2A13C8B7882DFF9306 +:1022E0003BB6FCCF155F8E8C2ED7089E3B60DDAFD2 +:1022F000734CFEC81398FC11496005C8C7175AC42F +:102300007118577770329447BF3604F3A84816CB3C +:10231000BF1865CBF53338E46D867585A99CEF71E0 +:10232000C0EFB0B1FBC532DE376C85FB2088246D71 +:10233000063ADCAD77619E6986A5F6676DA8CF5831 +:102340004901F2296933E2B5D524C1EF961CB4B234 +:10235000FC89F6B53A8C37713693CE43BFE37B04E4 +:1023600026FFAD0BABA19E2FA71B426575AF9DFD50 +:10237000AE5BFB78A25F510AFBE67E1FF522AB093C +:10238000CF274CB6B9EE807ADE66C0FB2B0E5ACB57 +:102390007DCA7804FA7FCEBA10DB038FD653FAEDEC +:1023A0003533FF3A4FEDE3156C7CFCFD46FE1EA273 +:1023B0008C6F220628D7123C6FD06B17D97CEFD5D3 +:1023C000613C04EAAFC3F999B05EBDCF3272BEB7CB +:1023D00052C0DF21E088121F6BC3F2530A1F6CD773 +:1023E0008B07014FE58F0881FD986CBB8074C0EBB3 +:1023F0006C6EBC1FC843F21D1984F92CE8F77C866B +:102400001884FC7BFE1E1BDACDA0F940FD50F813AA +:10241000E95AF09072C53583E3798E021E8FE08809 +:1024200017F6E354492EF2A36775EF6DC0FC0A8BD3 +:10243000D7E8A6E3186E23B8BFEEE4F8E77AF7967C +:10244000303A1DBC7FE55990C7C1D92A2478B65BC4 +:102450002B2438A7D46B776779A3CA71F6C50F7898 +:1024600013D91753505702FBE19640BFF8FAFE68A4 +:10247000BD05D623E1BCF8216E09ECD07C1BED87AD +:10248000F27D775AFC759C52D61150EE2DD4D6FFB2 +:10249000BE4477A5D7A9C1BF6FB9CE8CD8755EC130 +:1024A0007986B82B304F3E87CECF12991FFD13EFA0 +:1024B00051BBC1A243FCBA41BD1FCA157B4E447B30 +:1024C0002E8490E51B81CF7C57C977AD4AFE17F467 +:1024D000E35F4FF57C906B7DC93FCC877CD3A92906 +:1024E0006D1D8C385ACECC037E6CE290EFDC4882B6 +:1024F0002BE1FDB94ADF33F63CE4FB7F2B190FF7E4 +:10250000E9FA46A6D2F2C7FAAEFCC54EE48B1781B3 +:102510002F5A4818E9EE06F8BD46A0BBE9FE0E2882 +:10252000D3315AF09E304A8740B72A1D0E9E3FA5F0 +:102530004BFAFDD0161B9EDFDA428278002F8B7497 +:1025400071CCDFD282728B48C323EBA4443BD5D439 +:1025500082EBF8799B8CF2E1BBF6270528DF5CEA79 +:10256000738CA5F39A35F613FCBD0792357724D802 +:102570009D74BEE963FF81F31D7CAEFEABF3C8FE24 +:102580005EF6E884B1B1F6A823E96F9807277136A3 +:1025900037A1FAE3807DAA37615E42E41C72B80E6F +:1025A000CF3B73295E9067EA39642DDF9D741DE38C +:1025B000BB1F2FB6B957E03D923BD02E6DBED9A2BE +:1025C0009E5346FDAB79A14E39A7CCA15C6922266A +:1025D000BC2769E0F72CE93F2E23F2BB34FBE0BCBB +:1025E00072D9579D5796F03CB4BC9CC5E907ECBB2B +:1025F0004691D9AFEAEF9BDC9BABFE0E05D3531699 +:10260000934BB26FE39C6346BD91A4E814FB95E93C +:102610000BDD13245126185F657AF86C03D6AF4F93 +:10262000F2E3EF05D5F15D88240D63EDCAFD0F7E61 +:1026300033FEAE98C15D087C428DB3EECEF7358F88 +:10264000A5FB34AFD893C3D1A5D41958FC94D2C1FB +:10265000E67EDA6A1A69790E7E6FEE7AD2F25B5DF7 +:102660001ED2C1BDF0FDACD19FB0DFA18BD0C17D2A +:10267000400726C2FC01372871A2D73FDEDE01FBEE +:102680007E8E23EC3C9A4B7B1ECDFBC3B12C9EA5CA +:10269000FC9E542CDF899AC7713D9B8783E7711E8E +:1026A0002BE3CD63101D123F8E4FF7B705CFCB6BD9 +:1026B000F0483B1F6EFFFD789E6FF3ED44E42780EA +:1026C0001CEF37033C870146E4C13A7DEB609DD99E +:1026D0009062099354ECEA41F3E62DB8AFB7CE1EF1 +:1026E000C8D399915D0E712236EE53C94DEBC0EF00 +:1026F000D17CBB1EF97BCDFE31A8A7F5C94611924E +:1027000020C964965FE3A6FF8379CD229E2976DAFD +:10271000CF4D620DDE0B77F3746D5E8EFC500B6D4A +:102720007F8B92E773EBCDFAA3D1FAE639FDA37A5A +:1027300080835C6769E127427F42A4BD73305C06F9 +:10274000DD4BD5C1F813A17A0EF4DF5E1140FE9483 +:10275000884FED1D3B709FDCC86F98EF73702CE2C3 +:10276000ED57E7FB6C57EEB17A4B1FC6FB51DF4EBE +:102770005FB079315DE7C81F15E3EF1B4FC9A87F34 +:102780006E2D2DFF78D3282CBF9D71FBD2F7A0FEB4 +:10279000E9422C4FD67D3207E8C1553EFB06F85D75 +:1027A000E8B7CCAC9FAC245F770DFD2EAB24771C33 +:1027B0005C6033D910C6EF6E1CDB7815F8632627F2 +:1027C000B1F2A1D23F8CC372AE521EF7FA2828BFD5 +:1027D000C57D32271E5F1CEDE2824554DE4E4E65FC +:1027E000DF4F1FF7FC10B0E32757B1F26877E5EA37 +:1027F0003CA8D77D3A279EBE7456E1AB93BE38D72E +:1028000091E680B030FBBDE2D73C1FE2EFCB78A968 +:10281000BC85FB06BC152C0EE7F5940AF07B6655CB +:102820001E56AEB6B465031F9CE1339441DC55B42B +:10283000383B44DA2EA5A2723CEC7B3555B721CE4D +:1028400049E9EB53A4AFAB3FC9B1A15EAAD297A8A7 +:10285000477A4F7CAFE4E76CDF62E981F6F705CA9F +:10286000CF6B62E5E7207AD5E0E1FF008B7F42C5C0 +:1028700000800000000000001F8B08000000000026 +:10288000000BED7D0B785445D2769F3973CB7D429A +:102890004248088409F74BC01912205C1D02645994 +:1028A000050C171514E1041002B98DE0EEA2EB9AA5 +:1028B0000901441777E38ACA2AE88080A0C80E0A73 +:1028C000C86A644764237EBA1AAFEBED631345E52B +:1028D0004E0CA2B89FFFFAD75B7D0E99338405BFDB +:1028E000CBF3ECF7FC3F3E3E9D3ADDE77475557542 +:1028F00055757575CF55CE4EE15FE60921FC891EF1 +:10290000473E95BD6D271A7B0BFEF74357592A6941 +:10291000427410FABF9521457413A2930870B95EF2 +:10292000D42A421562B2558BF70C12C26E6970E35D +:102930007917C5D3D745CF45BEC759D41F2F764A7F +:10294000FEA29F4053F1C395429CB67D922D5285C5 +:1029500008D00375383DF489EEA9D48F82A66ED9CC +:102960009595E04CA35FA1B85C69E857D62B757FBD +:10297000E5F7D739E8FD0CEEBF93A73DF093F8AC2F +:1029800057FC5CBA84F6B8A0F155A40BD73D5EBCE9 +:10299000DCB8324CEFA5D388EFF110B8D73CDE9A03 +:1029A0007CCFA264F5427C2DCEE65961FACE3491FB +:1029B000E851E9FDF79616B5F712B2D709BF0DE356 +:1029C0007D282E31904CCF2BE724041DF47C670723 +:1029D0006D00E8A15A022F36127CB3F0D9D16EB245 +:1029E000D577059EC70BF9BD0AFADE3D289D448FB9 +:1029F0003C898723A30D7A44E1193DFE56BE346419 +:102A0000A0CC107E86D3856795DAC67884D57F778B +:102A100023BDFF0B35A1F61E2A1FB2FA2C1BA8FFFF +:102A2000C0EBB6E06685C72380CFD24F12363AB2EC +:102A3000A9B40A8685C7C1F54B6E26FCE9BD254AB7 +:102A4000962740CF6B12FC8FE17BCDD556B1311567 +:102A5000DFF76D00FC7A757781F1458F27BDF6A70A +:102A6000424BA17AC5FF04DA05AA1DAECDD4EEDB38 +:102A7000D87FCCDDC874482AB265111C3369432362 +:102A8000C18ADDE9528869E973D2595ED7DE427C9A +:102A900020FE050A42DDE603EF475551E38AA40311 +:102AA0006192DD2A9FEB3D44B4F69063831E0105DD +:102AB0007269B728B38BE28926F877656BB9DE6354 +:102AC0001182F8D43DBFA30FE35EE2151EC80FD1FB +:102AD0004101DDC55E45A703C913EA15973FE0BA7A +:102AE000904F4B1BB36F45FD7E0BE14B6501F12B06 +:102AF00005EFC7A9F27DC5D32199FA2F4812FE1020 +:102B0000954B62DCB746D275B8C532BB28477ECF3D +:102B100049F49BADCF0603CF396B55A1E50A31C609 +:102B200039F7B1C3B9C0775887A28488FA7BFAE431 +:102B3000CCA1F75FB689E9F8BE677FEF9CE21C1E67 +:102B4000872F94C37C5C1102FEA3D33D010FF06B71 +:102B50005EE1017EAA68DEEC011E014716F089C91C +:102B6000F40404F0AC15B7E545E01F43F803BF3BA0 +:102B7000C6F922C76DE07D313CA3E97D313C2139A6 +:102B8000CEC154AFCBCD1C675C933200A51A7690B2 +:102B9000888A55D4AF33525F45C9B90830DF272E34 +:102BA0001D537498E42DD54E8F20A7B725043712F6 +:102BB000FE136F1BCDCF9529E7589EDBD17C745057 +:102BC0003966BC5B69243CDAE5BD6515FD21A78447 +:102BD00017F0B1360E9A4CF43DD6557B12FAC6C0AA +:102BE000FF2F839EF06A547FC8224A4239178E6FA6 +:102BF000B72E4F2ED16887DC5538E3C3EA800BE54A +:102C0000E562F8BFD8A1E839E88D934AC36054560D +:102C1000F676F17321B46C7C2FD9953D3A197AE29E +:102C20007BEA6F30F414FDA379D0B7BBF627BC77ED +:102C3000BD281A67A5F1B61BAFD9341AD738359E0F +:102C4000E773CB7685F5D5585F8C0574A93C680B86 +:102C500006095EFCAACA745ABC5E0D62D2B608CFE1 +:102C60005ACCC39680C305B97C286EC06F4750F913 +:102C7000D97A9BC7817E03BEB77B53BFF3743EF501 +:102C80005A6B116E832FF47F9F60AC70F76E85FBDB +:102C90006D6D6782FB873A9ADA5FB1B7ABA9DE1B2D +:102CA000EE6BAACF3D38D0040F6A18666A3FE48302 +:102CB00002133CB4F12A53FBE147A698E091CD37CB +:102CC00098DA5F796E8EA9BE34B1B07E298DB73E99 +:102CD0005D150AD9C9D1A2D4D4BE542DB30B62B1AB +:102CE000A8B57D0A79F4D37FCC4F75A615743EBB89 +:102CF000571129A48F16AC95F5C67B2575F7AD84C1 +:102D00008D5B18343F2F15D65618FAF793856F1E32 +:102D100088E8AF576AB12599CABF7B1252212F624A +:102D20008818F283CA7CF540DFB4BCAB7A1C42370A +:102D3000A5042F7E5A09DE437CEC297A3C04BE119F +:102D40009F45D00DBECAFA96756A3040FD7C5B5532 +:102D5000F2E6011BC10773D7422F2F20BD0CBDE542 +:102D60004837F333C66DE6675C6F333F133C667ECE +:102D700026E59BF999EC33F33365BC999FED8BCC39 +:102D8000FCEC30DDCCCF0CCDCCCFCC12333F3BFBB9 +:102D9000CDFCECB2D4CCCFECC022537DB4FC765B3E +:102DA000B5D854FF50DCBE2F34A2436A47D5E5A006 +:102DB000A9D7A3F676D3F7843AC1BE82E8559AA97B +:102DC0000AD5D52A0701FA4FCE6B3FCFAFF92407BA +:102DD0000F131FCE8AD5F599EE0BE5A162EF7D7634 +:102DE000CCCF1F2B0FC3BD663920B94BD2DAB06BE5 +:102DF0004669F099FC91D15ED20FD3BCDA582FE925 +:102E000093E9BDBECAB292DE1045C5BD60472EC76C +:102E10004FB10EFE117ECAA410DBE38BFA29EECE71 +:102E2000ADFA8F9DBF80057AF9C3793696DF65715B +:102E300003B6432E3FA8917279064D860A71830826 +:102E4000B11FF661EC239DD15F01115C198ACADACA +:102E50009B80FF4CE04FF6EC26D168C3C7C98EDAE1 +:102E600051160B37977375FFEC66115E89C17C9222 +:102E7000AACD075D2A54AD4B1AE8D1A9218BFDD804 +:102E8000D75380F445E96AE8EB77F027B57BC45B5C +:102E90005481EF8C71BA6F7DC00D3F80EC03F1451A +:102EA0004C4861BC85B5A8FF94FE6D7D6719DB8B2E +:102EB00017144D03BD03194E0FECAD480F3DA3D0C1 +:102EC000F8FAB6730FBC27B9B5FDAFBC867D21C734 +:102ED00086DA3FB92B96E9D5AFC3867618D78FED42 +:102EE000F76EAF6F39F036DA5F6ABC76BB67D1CF69 +:102EF000A8DF6645F8371212EFEA7CC974483F3103 +:102F0000534DF4D4806F71B3EADB131D6EEDA0FD59 +:102F10000EDF9F7EFD4F570256F6A7B817137EA708 +:102F20008B1B07035FA2FF83A82F7312FD6968271D +:102F30003B6BBD9220144592FEF447FFA236F197F9 +:102F4000F81CD0E9FF6207ED31C8F57E4B439607C8 +:102F50007CB4360C663EBAE4B84EDA255D2E468760 +:102F600082B8CE3341FF790E8747257A1628F2BB07 +:102F7000879366CFAA24BC6FB614A5855513DE4F80 +:102F8000A3BFB2F8E22E19C0DBA6E3ED6CAFD3DD30 +:102F90009D13E99F45E35D83EFC31FFE15F997D9A4 +:102FA000781EDE06F839E1E2F58BC322ED7273B5C7 +:102FB00012DC48F56FEA745E6FA37698974ED1AE37 +:102FC0009AF0BB66E48A0D68F76BCDC9786F169EE0 +:102FD000BE6BB2C10FC1FA3EF32E2558930DBFCA86 +:102FE000C3723F4F1465EDA276AF79B57AE0FFB7B3 +:102FF000B87F0CCAB6F0341EF42E7D67CFB20E9E99 +:103000007B008DB83CF9EF4D9A03FD4F9928EDCE2A +:10301000CD3ADDA689229EA7C6BA8926FCC90A6ACE +:10302000379DFEE2F59870F7077E33007B5BE7F58E +:103030004CD1C0E52CE1E2F5D4DBD51D7E761BB585 +:10304000996269CEB2AB98A7346FB399FEFF0EB9FF +:10305000F966DC5B8714D0FD0ED263E0F79AF69731 +:1030600025C79315494F9AB79FEBF3360F53EBFCE7 +:10307000FC19DB5ECA9FD5D5E39FCD1F528C891901 +:10308000E4AFFF44AA42F1D09944914AE36CE8AA24 +:1030900006B19E1AA7DE61DD45E36C207FC2817117 +:1030A000FB8A3B9EA6FAF1646FEF91FA352140F05E +:1030B000249F2AEE6139685CBE909EBF9E4FF5D476 +:1030C000FE956A919047F02B5E9BA786E470DC39F1 +:1030D000ED4012959348EF87A9F555E9F78D857F67 +:1030E00030BE13D991083B715577334C13A113F8B7 +:1030F00074B54EEF093966BB330976C768DF86DDE4 +:1031000021FDAA82BE710375FBD357F485FD79B901 +:103110006AAFF88CEC8B6187C608B9DEB8981DB22F +:10312000DA0B5206B23FEBB6637ECCC1FA04F476FA +:10313000691D2747CC97D2210AF3C94D86C742E3C0 +:103140007FF3A01A047DACBEF070D06FF18B0ACB78 +:10315000E9D503B5AC81C48753B6C6F9909B8611F7 +:10316000B94982FAFFB48A10E945F3B7CA297C3419 +:1031700017BEA872317CA42A9DCB63556E2E4F5486 +:10318000F5E6FA53551E86CB0716F5027E73567D7B +:1031900065859FEF167EF68F96D07A17FC5A92B00F +:1031A00058C236A70B4AF8AECEF5963882EF0A2AF7 +:1031B0001ED8C585BB822BE308AFD23A9F3D9EE067 +:1031C000259DDB8D8947FB071496FAF907FDF51855 +:1031D000EEA9773FBD6EA2681D6FF93985D7C9EF9B +:1031E0000FF20D46FF5F56E5335E47AB7C8C97AF21 +:1031F000AEA93E85BE77BC6A3CC3770D2C1A81719F +:10320000FBC457EC474CDCDE64859F31CEA7F8C089 +:10321000E7513E110C12BDD6DAA45D594B76057A02 +:103220006074FF29EB6F15D0FB5A21DEBFB6DDDCE1 +:1032300071F05727E517B3FF7AFDF782FD5743FE7C +:103240002F358FDCA2E15426F5773220E9D3B2EB9B +:103250001D865BAC441F1AF1BE5DA5A582FC83965A +:10326000736FCBE7D48EFDD4DDB2DD629B6CB77893 +:10327000F7AFDBF9002BA25944ACB78E131F85239F +:10328000027EFA17E95A847C1D6F17FAE623E8C913 +:103290007FB77836B29C6A9F3D0F3DBADCC57AE6AF +:1032A000942DF4C5C3D0B39DC9AE72BD3F6E0AC99B +:1032B00059855D682C7742EB07F878ACE0F800FAA6 +:1032C00073F792CF218F3D773CD4F597EED6FEB6BB +:1032D0003CFDFB96E7DDA80FF2FCDFB6637DC74738 +:1032E000082ADBB92216787D76EF7399185F2F557F +:1032F000F8559A67737FF3C7CC3F52FF4F906E41EA +:103300001CE3059BE7D45EE0B39EF0A1EF3C716F38 +:10331000F940E8B779BF5BD817EF07065A98AE4F68 +:103320003DB793ED3FC998670CE9A9FE6B5E5A96CD +:1033300041EDAF58D764E948A577935283B274FB47 +:10334000CEB7ABA9BF5C97C50F7F74C54037BF3FF1 +:1033500030B461A302BDFEFDE31D31CF72D67C55B2 +:10336000D0515CDC6F782AEB8396621E572D8F6BF1 +:1033700077DDD4776E14F04BC82301BEC5760FDB22 +:10338000291AB60DFCDED56D03DEDF6309B0FD0939 +:10339000CC917ECBC9A2C0EF31FE726A1F20B8DC8F +:1033A000DBD0741BD597277715883B1C092E998194 +:1033B0007A9ADE2ED0A762D703851D093E3942785E +:1033C00014EABF64F79942B66F9DC9F7C6F776D580 +:1033D000A4DD00FB96533048A5FA2235C4FD894A86 +:1033E000D95F65DD4EA7E0F5BC68A792224CAE1B05 +:1033F000FD7266047F2C8DBFC9B6D2F7DA937D04C7 +:10340000BE6BB30319FEF8567BFA9AB7680BEB2331 +:10341000D7FDC5F8CEE78417FCADCBB57F768B7FA3 +:1034200021E3932E5C81A1ADDFED6C092FC43848F8 +:10343000DA5D01FACE6657C30C6E47F06FB95F6D67 +:103440000FE65FA64A544F95F6BA06FDBAA6668106 +:103450005F97DBFF4371FF60BFABD292E871E4B5C9 +:10346000FA2DD3536A5E6C247E6DE8A0EDC7F88C0C +:10347000B8A4B07ADCD0E3810EBE97F1BCCC49761B +:10348000D5C2F6F415C0861F7CDE0F735E9E3DDD4F +:10349000D9C1F717A6E365B677EB7186F37AF5EC39 +:1034A00040935EAD49B00B2F3DAF59E3E0B884388F +:1034B0006029ABA7F5C7487CC2D2FABD2509033BFA +:1034C00040DFD708D126BDF6D17CD688B661B203DD +:1034D0001ACDEB51E79A558DE77DC3CB4979D09F43 +:1034E000C297E0461CC022B4087B17FD1DE2D70935 +:1034F000F06BB488135A84DDF489643BE6AD886FC1 +:103500007799E30E3F6EB627FB1F8F1CF788960F47 +:10351000E2E052113D3AA0BCD8B85ED4C7F5278C82 +:103520008BCA79438AFE01FC467EEDB2627C23ADF4 +:1035300093B3BC5D196F6B2EF53BEA6B8B19EFEF04 +:10354000634DF0E5E2FF3385166A90E3AFEC1C179C +:10355000AC83EDA771D42DCC0962BEEFB18B801383 +:10356000EB982976F66BEB1202097D51AFB84288D1 +:1035700027BD606B9821D739C2B5D90BF97DE3110E +:10358000C8FF0D2D7605F1A98E0EF105FC25A126AB +:1035900089CDA911DF6FEFE2B885EACC5C8FB86204 +:1035A000DD50FDF90C3B3FAFB109B67B8119B18C01 +:1035B000D79A64FF6BFDA97E4DB58C677E2082ABE8 +:1035C000BAA2FE0E95EDC070CBC6CD0F621D333989 +:1035D0009DEDC69AE4706625DA2FECEB09903CEC81 +:1035E000F987CAF6608DD797D12E1E7A50C605D7B7 +:1035F0004CF665C4A6A24CB360BC1D49CFF3F36C76 +:103600006A47E54736D9EE439D6F44E90CE8DB870E +:10361000E7F510D03F57E7168CCC65FF47C63BAFA8 +:10362000952C10336E7E80E3AD0F6B6A50CD065D36 +:103630007E736F4F826F98A3BA1077BBB62486E370 +:10364000A1D76A7A3C749A390E7B75AE6F642EF1FD +:10365000BF3CD4A7DBE108399E71738F9F433F7C49 +:103660002A645CFAD769DA38B4137BBDDC6E2F3973 +:103670002B3FC04E38DD03D87F9E67AC1BC3734120 +:10368000DF7DCD4EF64B2F260F42789C7DE9FB0F58 +:103690005A4408F2DC05FC4961B90DC06F0B846225 +:1036A000580EC64F71727CBD25DEC2FB0C8F11BF58 +:1036B00060DF02BBE53E03294AE6DF83FB3AB35DE8 +:1036C0009AADEBB19AE9B1FC5ECD4E5BD0023E2BD8 +:1036D000C16D5BF0DE8B316C3FCBF4386FD9F3FDFD +:1036E000580EF6D87DD92BD0EF3E07F3B92CD19DDB +:1036F000C4F5FF962250FF821E772E8B0DF7443CB7 +:10370000BB5B7B6D3EE84172C771F932BB7C7E28A2 +:1037100058C0FB1A82FC95B851040B1FEF4F04C828 +:10372000AFD9EC91FC035E5A4DE78DC057233CC0E6 +:103730006771BB8C971FA2B98CF11DF27766BC94A0 +:1037400029E3336EA6FACF16C7711CF55051FD5907 +:10375000F80187D2559EF7A4A1EE1D42F564731BB4 +:10376000EE21B872E1A76F0CA1A715351F66ED75A4 +:10377000B7D27DE6B2F20982E460E6A23B2689C4B4 +:103780008BCFD799650EAC115BE7B7B063B12661FB +:10379000D2EB6B727D3590C350AEB612E3AFCC2145 +:1037A000FF99E4E894BDE151C4498EBAB5BB517F9D +:1037B000FA8F5F6EC173616DEEC9F2E16C2C449CAF +:1037C000A5CC22E344A3F3B4DFE6B29D4D64FE55DD +:1037D000861CCCBFB89C06A917EFB83C7B70AC6EBA +:1037E000F31E85FA298DADABE0520D0E80BD3AAEC9 +:1037F0008413956E4C5F0DF3EA842B9C08FE6816CB +:10380000E9BF956E8D1EA7DC4F2CC51FBCEE0CD9F1 +:1038100087135E8B48F53EECC2737B6BFBEC563E28 +:10382000D277988F22FE9359BF44FB6D7D06DE430D +:10383000742F4DDEFB9BE1D917D22F1A36C67321A8 +:103840003EFA3C290A27629E1C57E43C3921A4FE1B +:103850000A6C8DD1D7FF128F537FECC078A4E9F3A7 +:10386000E894A2B7DBE690ED48F6E0CF94FE41CABB +:10387000DD8336CF5AB9AF66657D599A22E152474A +:10388000BA0BFE5647356089855C56099E2F841B0E +:10389000CFCBE33B32F97D43AF892221A0D74A77D2 +:1038A000646C947E9DBE0EC600A8FDA2A7647F80B6 +:1038B000A1FF8F3D99A9F72FE753345FA3E9F07E6D +:1038C000AE8C5BD5240CEEF0CFE295BDD33F5E0706 +:1038D00015F4A04DCEEB4082B423E4B7A44FEE8F95 +:1038E000FD06BBE9BBA712ECB37DF1D877303F37BB +:1038F000BEF769AE5C477689E27B47B5F925F84BA0 +:10390000E271C17A221A8FA3788FF07DF2C9F37C1D +:103910005625DF49900CF97233FD840DFCF9D06E09 +:10392000F0F1D64CD2EBA5A055D7563AEEF16A99F4 +:10393000B023A7F47DA33DC904E7C0DF92F6C3809E +:103940000D7E44CBE9B20FE767629F2A2D4FAE0F81 +:103950006A6212078824945941E8816AA22BEAC955 +:103960000EF27EDCB1AAF1F71FB6B58EE78B2A9F67 +:103970008F4CD07978FE5AAF13F373C13AAF734EC0 +:10398000043F6AB6E61E7413DD4F6CB562274BD454 +:103990005883BF19968AE76A2820B8DE097A9F887B +:1039A000DFFF06DACD5F973C508DD04F0BD68EF3FC +:1039B000CD8BE043BFAD66BEF40F99E12BF69A6163 +:1039C000377832E8C7BFE70D9BE1DC8366F8B9FCC6 +:1039D00066F507D8A7784BD0A9A06C517F807E0FE1 +:1039E000AA41AC33BADC51347522C147D6CDF5803B +:1039F000CD0BDE5B3618FC3BB9FBAE3DE5F4DE914A +:103A000076160FD657C745E8FD89C48FF975F7D9E3 +:103A1000AD6E8CD72CE77B2CBADC3E29E37A0B8386 +:103A2000E6FA0BF543B51E4712BD23E52A9AFFD4EB +:103A3000EF753E42AC6CE9D4FBE1FF944C2081274A +:103A4000FC8686EEB38BF8CBE927C072634D14E198 +:103A500074C2AFE9AE048EA70C5B3A467C46DF2BFE +:103A6000B7BA0663BF7D8E5371617FDB889337EDF4 +:103A7000CCA8803DDDECB278904CE1CAF7D767E680 +:103A8000613D21422E0FE2F477AEC43ABEC49FC816 +:103A9000F45928821C679FB3DCD1AA1FE9FF79ABD8 +:103AA000A3F05913514FE32859676EBF68D30F8EA7 +:103AB00048D858970EABDBA062BC37EB78AB0199C6 +:103AC00037304C8F3F1C4653B2377FEB56549C87A0 +:103AD000F66B46CB7AAB53B7B33E5EE795C7DBDDFB +:103AE000ACCFAC6FADE4FD1A9A87B00F0713E6FFB9 +:103AF0001CFAEE8C53B81C9C47A231FC458A5C171B +:103B0000F23E04B53FB34E61BB5E9E22E1F2C79523 +:103B10002062BAE508C2027E42C65DCB747A404E8E +:103B20007C11E301BF2261516BC4BBC3BCFEADF08D +:103B30000B0FFC00417CF499F6BDC3F623B0B30132 +:103B400025F4B017FE9EF93B957B7F7044C2E7E3F6 +:103B5000C5C4BA6AFE7E90E9A8DA850F7A5CBD33E7 +:103B600096FD763200B1B0EF36DDBF16AB82ED6167 +:103B7000AFD6C05E51B942F7C303F7497BB526D92A +:103B8000D7D385FAFB323CA0C30D8ABEBE855F9FAA +:103B90000CFF7A3FF7DBACB85C1B93D15E0462523A +:103BA000D9BF96EB847FA86CEF9AC97FC7FEFC1A39 +:103BB0006F280C7CD63C90CDFEFA0B86DDBB3746D9 +:103BC000FAF317FADDEC5F89FBA5FFF891E0BEC5BB +:103BD0009EEEDA863C92F3B96A116F2ECD5BE6CB8E +:103BE000C077E74DB15BC00F517279FB1C9BF53C70 +:103BF00098661A2FE2EF8795A27A4B841FFC4C9EA1 +:103C0000B40F830B7C5BF4761EB49B67798BE93031 +:103C1000CF225C58CF6F3EA70A2BC19B6B1DC1659D +:103C2000F4CABCAEBE9E8B73F09E8C371DF24A7DEB +:103C30001F97277C41E87FFDBB2FE4594CA5182B2B +:103C4000E32C8763A41CCE1445851CEF770B53FE31 +:103C50008551BE9227EDDE3C7B83199F4F5E66BE89 +:103C600090CD732D837C8F957EC7E15B14B6E734CE +:103C70009E9E2E8207FF2E86E38587757B64D097F4 +:103C8000E487F3220CBD95ACCBCB9ABB83DB628877 +:103C9000DEF7D9486EC037921BE4F910DFD92F5CEC +:103CA00033238DF97E83CE57716F02F36DB8C52231 +:103CB000E97C6F06D399DA8BBFE3BD716EE9CF5F04 +:103CC000E63A8CF8FE37F03D7A3D66F05B58838328 +:103CD000FED97E4CF9734FEF0990FC2FFAC303898C +:103CE00082DA1DB5D6A679E8FDB2CD2B127D541E21 +:103CF000B106125DD4FFD1A03A3ED806BD3B0F52AB +:103D0000F4F5902F11797415BA1E3FF6E47FACBC20 +:103D10009DF0FC4611CDD08F15BBBE5B793B8DAFBE +:103D2000DEE76C863E3D626D2C84DE5D581CEFAF95 +:103D3000F660FE9AE3F28B9E7820CDCDF40E645AA5 +:103D4000D279FE67E2BD8A4D360FD67515EFAA1EF1 +:103D500037E6BD685E09FCA2DFAF0C7D6607FD5D3E +:103D600016D1DC69781BF5A291F57CE5AE5F7FA5E5 +:103D700026A23CFA11D6179551FB0125FA7E49F48B +:103D8000BE40C2A084D42F10F0D6F7A3893E9C97E2 +:103D90001020BC7AB0B8C83872CDB6870634C16F6F +:103DA000D8F45AA292D3BA1F60ECA3B484E63E863C +:103DB000B8EAC5E6E5A9A838B0A1C7DC7B1599B477 +:103DC0005827CB325B3811FE7ED9061BEB91B2A788 +:103DD0001FDFF230E4ED4387A7871BF0193BF44166 +:103DE00099E26B5658BF8B4465702BBF4A9FFEBC4F +:103DF000F011F8D719AA9840FC5AF4EC59D9DE27EB +:103E00009A63A87DE9CEA642AC0FCAB478BFB30DC1 +:103E10007E8D09BD646F8C6F835FA1A6428E536D4A +:103E2000FB96F971749F223A645FF87EC986CFEDE4 +:103E300042AE0F9A539225BD60EF2A436AB13DE925 +:103E4000C2F6F4FD49CFE771BD0BEB954BF1F124C0 +:103E500068C1F29E2090C758F291233801FCDDB171 +:103E60002411F94F5F5AFD52EED7AF48839F576236 +:103E70000BA4B9B894CF4B1EFD19CBE302C59FE646 +:103E8000E2BC2DD2AFF93CDE0C8CF3E675D7F238EC +:103E9000E70B8DE5B164BD5A14A4F2AC558CDFD9A3 +:103EA000C6BC796890D4770E71CB00CC93B3F4255F +:103EB000D8F12FF5757DE06DB99E7688294991FB83 +:103EC000432583A45E0C88E021D881CA061BC7293C +:103ED000D4B7CE16E23BB7665BFDC8DFA0F107742E +:103EE0007A293FC8F58B1B790C95F88BECE998B7CC +:103EF000C67568CCC1F75BEC3751BF5F639DE83195 +:103F0000BDC774FB72A32356B982CAB4B6F3BEEA26 +:103F1000CFCF7FF1B68890A7CAAD5FB23C89745508 +:103F200024A54B18FB11AE39F1FE24A2DBD7EF7E9E +:103F30006647FC3B906A113D806FC3E70C0B4F7BDB +:103F400037DA1BDFAFDCEB10E1C879BBE9F3A87906 +:103F50006DAE17C2CFF4AC14496ED8EF2FEDCD85FE +:103F60002FA01FEA7733F5339FFCAFB0C9BF6A2E8D +:103F70007C04FA64AFDDC5F107F23FC31172737EB2 +:103F8000BF53DFE75BA0EB83683A44EB87FBA2F407 +:103F900083F1BE58D7F6FE52AB5E08303DCB6C22A3 +:103FA000003FA3EC4307DB8FB2A7E57C14A44F7B53 +:103FB000D0FC38BEFDE5F76FC07A36644B9DC0BDBE +:103FC0009AF56FC9339FF3B8E612FD633CD0BFDFAB +:103FD000DAB1FE4D1F239A1D84FFF1D55E3BE4FE4E +:103FE00082794CCFDB9CC7AB15D66FFF55BD4BF428 +:103FF000E6FCC04BCDD70517D1BB7551743D2B7274 +:1040000092905E2D5CC55D78FF208ABE065DA3F5AB +:10401000E8B441EE36F528FD7B5F44D051884696E2 +:10402000E36F482F625FAD62D3776CD788ACCDC8A1 +:1040300027AF087EC5F00AD835865F9A8678E58571 +:10404000E336D333BAFE4EC818FD5FF4471BFB05B9 +:104050006575326F91DEE3754725E2F5DCBAB63E51 +:104060003335120E46C1A1A8F6BE28B828AABD163F +:1040700005FB4DEDCBF6BECCEB2CC2DBD4CEB1F4C0 +:104080006A5E875CE85704791C95BBBEB207201FA7 +:104090009D9AEDD08BB665229040EF37BFA8B2DF76 +:1040A0007BDADD9C083F65458CF4E34EBB7438D960 +:1040B00080C5EC62C2E37460800B7902CD3132DEE0 +:1040C00072BAA839313962DDDE54A726BAA97D63F8 +:1040D000508C6F3BCFA586E753A3B858BDF4E7C615 +:1040E000A9DFEF90F99F5681FCD8C6EA6F77209E32 +:1040F0007498D64FF05FE6555F9F88FD97D375DDC6 +:10410000AE998E75E0ABAA9069D63E3BF220E64AA6 +:10411000568A2322F0E0081A9F9A9057FF02D6573A +:104120002428D8FF9CB73ACABF11454961ACA7D72C +:1041300044E72B04EDF06F16909D853E2A5967AE3B +:104140005F54779CE7CBA2A8F9A2E971E3E8F9D222 +:1041500075B09EB7E0155E3D7F92F3F44E1F545943 +:10416000BE5A96DBC4CA5499278BFC92963A997F23 +:10417000D3B257C222A0E7F5E8F3D6A0DB09CCA75B +:104180005E17F75B4EECFEF7C1BF84FCECF97800DC +:10419000F6894FECF9B0E70B809FFB6BD6C7E2C204 +:1041A000F663F67D378BF1DAE710C0EBF4BE57B259 +:1041B000E06F9C7EDEC1F905A79739D85F0FEC4B05 +:1041C000E0B8C5E9CED21FAE79F1DB018D6C8F97D7 +:1041D000331F270EB64BBFAAEE3FD83EB6D439DC0C +:1041E0001847E5BE389E5795CFC7F0BEDAE917BF2E +:1041F0001D1C198FFBAF8EC7D8573F9D20A63F03CC +:10420000F9D5FDFFCA17863E5E8DF5F2AE97EC73C9 +:104210009127F2A7FF3300FAF5F4332FB1FE3D6585 +:104220006B7C14B1CDE97B321EB10D455C8F3ED65F +:104230005188AFF6CCB811F3E742BA483A9C263A17 +:10424000605C449712F8E517A347E5BF2C3DBE9A82 +:1042500025F5DC10817D9F56BA283EF93C81E35557 +:10426000347EF97CDFB703A0872E35DE7BFF1F1B72 +:10427000EF53186FFB7FC5F14A79CF1DEC66FCA2A6 +:10428000E5FE42B97EEEE70CEF48F030BE9739DF2D +:104290005FFB971DFFFF0CBF8FFECB8EF752FC7E9E +:1042A00055E777820BFBA0A75FFC3F59E2478CDB09 +:1042B00039E45F755EFFF3711BFE7C81EA39E8A586 +:1042C000F6AF89D0BB9E6CF64ADAF447060D518CE6 +:1042D000B838AFA7C6E02F37DA0F5C8E734C01F207 +:1042E00027B08EA9891F78E02D825F213F41E57DAF +:1042F00059194F7A25DD1B94F15DBF403CABE0AF0F +:1043000073197EDDFB9303C82B2954653CE6E56AEF +:10431000CFA6061AC7CBC91637CE958DED34F7F068 +:104320004EAA7775545D589FD574CA75BA23F01B91 +:104330001B6F5E675D1DB54EFAA9DB5C3F5E3C936B +:104340008AFDBAF1393681F33685681FB1AE4C1952 +:1043500022CFF7FC54D42E77C5FF783ACDD5E94467 +:1043600074E17D9B402755CF7333D34D806EA9A058 +:104370004B2EFBEF01E139F016C156DDBF12FAFEFC +:1043800063A133610BD6D10E51100E127CD66DE5B0 +:10439000F3935641EB61394E5E4747D34DE8EB6AE4 +:1043A000ABCE82B19DC68441673CEF926E7A9FC7C7 +:1043B0001D4DE71F4FD7FD9D9680AEE9099E20E475 +:1043C000A2D3B3A988B3D6109D15A5959E069DA22C +:1043D000E99E8FCDF541ADF4EE64F55A31CF46EA52 +:1043E000FEFC586BB2843B35A8F25C5E90DB8FF923 +:1043F000DA63853F323A3E99F343857E6E42D5F7C4 +:10440000C39161C778D0FA1479B693ADDA92219C42 +:104410005FEF120558B7168810E2B74ADD2BDF614F +:104420007D84F32245BCAF59FF01E05E382F86FC46 +:104430008E75D613A6F36E51E72526E5EF1C0D7E8B +:10444000CD594ACF10C772B9EB311F8BEF77B8C186 +:10445000BF4ED606AEA7B596AB7A2876AB430CC74F +:10446000CE234F3F03ED5E19CDED970897928C74E4 +:10447000BB109F778C77C97C355ABC7E03D8BE3C75 +:10448000C15D23E32602F2D41D65577C5FB64F1F42 +:104490004BDF43BE9BD0D85F8EEDCE9120D1552906 +:1044A000E2FDF72EDD645E44F30A07AF778AEFEA98 +:1044B000DC137A694281396EFDC510B9AF69945336 +:1044C000F3DD729FC2E249C777E62CEFC3EB2F35CD +:1044D000B6A87C37E8B8238EE5BC78E54D1307D144 +:1044E000F78B77A47880E6B1493B07CBF6337EF6AD +:1044F0001E3DD7B6C6F0F39FE76B8F0F419E81E25A +:104500009EB59B1ECCB9F6657B3A75A185269F4466 +:10451000DC715260E71BD8E79C344DE5F69384CC00 +:104520002B15CBE378DF7C62E02B6B3A7D6F222D7D +:104530006A50DF14E3CABA85F02FD6E3CD7FD0E707 +:10454000A11A2BB467E28157E79E5DE9F94421F394 +:104550009BA3E7ED71BD7D97311E772AE8A3C4B810 +:10456000701ED6688FEFE0BB5FE9F4785E2F0D9880 +:10457000E8CA71F179AB1C4DDD1251DAC2BDA8EC6D +:1045800033AC601FE46D425751B816DFBD4D151BAB +:1045900019DFE6628EB327F476830F9AD0CF77AE19 +:1045A000E9C1FB394DA305CB4FD37DD906BF393FB8 +:1045B000C958CF358DF6D4237FAB79B4D3B3D1832B +:1045C000FC9650187194436BE57E4D979A7077E88E +:1045D000D966AFDC07F97C69AE1B7272F303531323 +:1045E000A13FE7AE51C30EC8FB6A73DE9270793803 +:1045F0000F7C6EED683BD6AFF3E27D768CEB4CBE64 +:10460000F611F8659C73EC0B9C708EA7B6F875AC30 +:10461000FBD4449ACF987F567722D6D5D1794F953F +:104620007A7E9301FF3A4DFB0CDF9B93E4DE01F9A8 +:10463000F87469378EAB76CBD7CF575AC3DD419F1D +:1046400047692E607E3E3844CADF8476AE9EF12CE8 +:10465000BF3102E36AB2B97A429E9B56C45840A762 +:1046600009CBA41CDF6D95F32BE8735B02F4FEB35A +:10467000789FBE3BB3DA5AB481FAE9E414D6847663 +:10468000B4CE1DA63D0FFE4C0C541FC2FA7AAE6E7E +:10469000AFE6AE96E7C1BA8C917C15D686B129F407 +:1046A000FCC8E6EC81C87337E466FEB082BF0F89B0 +:1046B000E0FF84025F617BFACE048BBB057A78DE73 +:1046C00034E5A56E520E7E18C2EBF93A9EE72DA492 +:1046D000271CC93807D82061E4AB426FD43EE4738D +:1046E00046ACDBED6217D7DBE7C97CD42EF670351C +:1046F000E75FDD225CCB08DE427E84D526C4D62A65 +:1047000027974F5691BEEB21C4F6AA74867754B909 +:10471000B90C55F5E6E7CF547918DE5595CFF09EE4 +:104720002A1FC37BABC673F97C55113F8FD63F73ED +:10473000E3E7B33E71F5245E0FBD506E66B9092FF5 +:10474000E81FA770DD85F34742EABBE4DE52FF08AD +:104750005D1F75ED23EF03E8962FF9615B35DAC233 +:10476000E737AD8D1990BB71EA89A79F43BCA3249D +:104770009EF3B25A4423CF931661E173D9D03F0E12 +:1047800092BB2E778ECF8ECC3BBFB14411D608F9A9 +:10479000BAC91F23AC11F669F6D264133C73E93B26 +:1047A0007FEE40DFBFB1AB96974F781CBAF38BF525 +:1047B0007FA5E78FDD79AC873CA7FBFD86C8B84BAA +:1047C0008B6896B0D5C9FBF18FDD9E9196A2DFD3A1 +:1047D000007E19E7A4BBD89B8F3E8179B842F52CA7 +:1047E00023F823F087E8F989CE9FE215DD56FE0213 +:1047F000F3DAE7F428F49D43B7F72BCCA7F68FE95B +:10480000FB51179CAB4E97F6EB53D8AF6469CF0AB8 +:10481000A047C3D26E7DFAABB4C05DA8BF25D183DB +:10482000130DDAAA0E810504AFF6DA3D2AE27A7595 +:1048300082EF5D201A4BBF226033DBB1C64EC988C0 +:104840005B1AE79EE3F2824E3E77451D613F664E5E +:10485000EFFD22037AA9567161BF06E7349DEDA0F2 +:10486000DF14DE1F451ED034B29737E5AB3C3F7FE7 +:104870003FC4CAE559D873A26B8CF0707C66DE6ABF +:104880006A0FFD58EBB5CF8FD0BF73F4E7737B5B36 +:10489000B8349E97E17BD83F5CE59D0EF9E888FA35 +:1048A0001C9403A703BF8EF185562562FF777EBE59 +:1048B00055EF5FF67B169392E07B7A77B5DF9CC36A +:1048C000E7ADD86E19FDCCE93D706557D8EBD5A39F +:1048D000411D5163F3A4A752BBCAF3DF71497FC4E2 +:1048E00029F3B3CB2E62378C38DD11FC29CF3DF292 +:1048F0007817ED786A07CE3D2CFAD8C1F66BD11542 +:10490000D22E899CE0E0A91CD034C7C5C73E75B241 +:10491000FE2EC2E724CE2521DEBFEB333BF24369F6 +:10492000DAF8933200AB4DC8338D8ECF1ED8F171BB +:10493000629B71F15DEAE5C5C595EF1361178CF1D6 +:104940008C7BF16C1AFCAC4AE51CEF3355BEB822E7 +:10495000ADADFCB0E8B8F8F9F8B958FD15CED757A9 +:10496000DE71A4CDF879741CF0F1FCE8FD88F80242 +:10497000E889B307D520F6D35B823D92441BFD1B2B +:10498000F1F3CAB5F4520AE6A53B09FB61A72FE291 +:10499000971FC997F6FDA41E6F3FBD5DE5F5D2E9EF +:1049A000ED0941F8A715DBEFAFC73E65C52685DDEC +:1049B000F372D1C0F4223A0A67A41D43BE5B0A9C7D +:1049C0006B7712F495815FE953097EC8D5C290E2F6 +:1049D000DB4C78B438DD49ED23F03800B96A8F3C00 +:1049E000C0D060A6AB8EF7F3BA1E34DA2DACBB9FF5 +:1049F000E3D2D4EE14FB3B7F88139C27289ADF0078 +:104A00007EC7D7E57AB0AFB830B4B382F33BB6C750 +:104A1000B9108738A6E7391BDF69D0FB6BC897FE52 +:104A2000C9717DFFEEF80E79DE1C78623E1D53CC15 +:104A3000F982EFEBEFBD9F2FF7CFEEC05EE2A0D67D +:104A4000F60B434D89DDA9FD977BDFE1B2516FBFC6 +:104A500030BE6100ECEE97BBE2783FFECB5D8F1479 +:104A600022CE7C32343A15F26F7CFF54BE8DDB9F30 +:104A70005CA78E07BD4450E6D99483AEB99178A661 +:104A80006C086447CE33996F747CD7B389969C5673 +:104A90003E963BFD4E9CF7ACDC754B11E4B8DE2630 +:104AA000E969DF35398063CC95755E01F9E5799662 +:104AB000C1ED575922DA396C1EF68B6D7B8B7D6800 +:104AC0006FC4A117EFB6F179C15957B8AFBF11F351 +:104AD000F0351BF361711FF7F59C8FD4A072FEF2C5 +:104AE000E26C1186FFB1E4B6840DD80F33F09D95CA +:104AF0002BE77BD92A45F8685C6541790F4747E287 +:104B00007B00394AE98D83903FD9941DBCBB672A4D +:104B10009FDF0DE3FE1623CF94E6714F9C73EC30BC +:104B2000B41D8FFBC119856CEF0ED945007A21F0B9 +:104B30008CCCC329EB2AF3A31F86DCA3BF76E19EAE +:104B40002934DE133A5FCBA6847B222FA3EC990C89 +:104B5000CECB386197FBA5788EFDE2B281F47E3C26 +:104B6000DFCFA119EF2747C851D91C8F1BEDD47691 +:104B70001EB7371EF8BA4EB1DFBA3B41C06FB53C25 +:104B800097A0E757C5701EB9F15EBFA152EE8C7BAE +:104B90003FC40D321FF3419BCC577D707306DF7706 +:104BA00061B47FD0A6CD80FF8471C05F5F68AFED38 +:104BB000897D1703DF8589B58CE7095DCE17C6D6D9 +:104BC000CABC70FD1C31DA036ED2F3D89BB73938FA +:104BD0007FE55846C337C0F7D8B63EC88101BDE768 +:104BE000EFE57AF21F899F8B9E7484517F749B8CB2 +:104BF0005B1FB505BF811E3EBA3E85CF471D6D1FA9 +:104C00001CCCF9018ACB02FFECA8A2C33617FB9596 +:104C10005DEC0453FBD4586141FECEF8296B67214B +:104C2000BFA1659303E2298E6D79288DD735C29D8A +:104C3000C47936075501BE1D7BF23FFA44FA2F4670 +:104C4000B9689339EFAE295B98EEC9B97AA89C97F9 +:104C500057EBF4BD66A8B453E571A107BBF2F82485 +:104C6000BD893FBCBEA3199AC0F9134FF750A037B6 +:104C70001E16C19F7F9CC7AB6C37F2E6CB9ED9F660 +:104C800006F66B8F594403FC0FE5CEAD3FC77D1B85 +:104C9000A9BF49623B24C4261EDF51973CA74A1393 +:104CA00096C7BFB08384174DDDDA13703DD91C85DC +:104CB000E6D7228BC2FD2FDAD39FF3ED881F16DED5 +:104CC00027DBA9EAF8904F09FA6D91F9CA13DA05C2 +:104CD000B7C0DF6B5EDF4DE0FCFA3875DD00F0EF4A +:104CE000CCA6380BE4A9FCAEE149C341B737550166 +:104CF000FFE38CD5D321328E104DAFE83CF0E0506D +:104D0000A99FCA700F0ECDABD23DEBF9BE9052C831 +:104D100025E8F2A4C2FBD8A52B873FC472FA864DC2 +:104D2000F4A07E4F84EE4F8CE4CF3D43A55F70FE30 +:104D30003B760FB72FA5F6F2FDD71219CF2D36CE41 +:104D40006B89E6EB65BFFFA47A59EF9F1F7F88FC54 +:104D5000820117D2E18C68F8F9C7F4FDAFB7C7F04C +:104D60007A9056007C8EEDB82D341FE33EFE740C15 +:104D7000EBAFE3C9524F7C49FA34D00B785CFD5B52 +:104D800096D3B7A7F279BF0541F3778D7E7F3B5469 +:104D9000EAF1F2144F12D69DE56F4A7D48FCBA86BF +:104DA000DF7FD3C6EF478FA3427FEFFC3C7D3A8E77 +:104DB000E5E27847C98FE33B7AB17D6A4A76099686 +:104DC0009B6D36596F0B65C10F3EFE742F6F4DC43E +:104DD000778F2787B25C11CF9B6CC19543A43E6D42 +:104DE000C6BA588449D50E467E91603D6FBC57EADD +:104DF0005CDD003F05F9BD8307721976B4BB304F07 +:104E000077423BB99EFC529F779CB39AA6E793B337 +:104E1000DF13B2438F6BBA7F58B63D3ACF57D6D720 +:104E20001BEFD3BC4B35F28A2DC037644FE7788334 +:104E3000703F43F8962EBF6521F2C74BFDF7DD08A2 +:104E4000FFA9D42AC6DB09AF2645653C9A62C4ECAB +:104E500029F02323FB89F0DFDE6AED47E0DEB6327E +:104E6000FC41F3E0BDA16E293FB0A4F4BDB2E5CA98 +:104E70006A7CDFD02F1C284C6BA513F25A91DFD32C +:104E8000345AAFBFC8B89B6CB23E7ADC063E478747 +:104E9000CABCA0A66CF76F47802F7F51F97CD799C9 +:104EA000EF7393DAB5E1A7B5DA7B7B6B9E2DE1FF5B +:104EB0000D7C6BFACEF3BABE2B25FC8067CF75E66E +:104EC000BCF2DE9BCC70DFED66386797191E506729 +:104ED000863D07CCF021BD5FACB3710E19EB6C942D +:104EE0005867BB1D729D0D18EB6C945867E339D65B +:104EF000D980B1CE068C75366083DE586F03C67AD2 +:104F00001BF5BD86497D2E7CE134E46B5658649ECA +:104F10002FF1C3C7E79866D84DE7524EBF28CFA5FB +:104F2000903C487DBF309EE7C9C36831147649CEB6 +:104F3000A7D4E71DC165F4DE38B7963C0C7662ED68 +:104F400057F32177155D1B39EFB569C52B3DEFA7E9 +:104F5000768D4A82805F51B1F6AB59F0A33AB8B56D +:104F60000EC3089FCAD8869543386E1F66FDD15878 +:104F7000ED7EF34AC9478EBF14ABB8F982EA4BDA2B +:104F8000B5993F149D772E569BF3CC2F95771E2D08 +:104F900007861FF898AD39C3C5EBF4118F22CEBB3D +:104FA000584970619DFE598C5886FB8002AFCA3CFF +:104FB000B59683369937B05AD92822FC93413ABD29 +:104FC0000D78EEB95CF6C7CFC3AB158BB84288EE4F +:104FD0005A7313D6D7674A2CEC779F2929286C0F70 +:104FE000FF8FD6659813B86F2B125FDCB715293F7A +:104FF000B86FCB7C6EA2A3A93DEEDB329F9BE86B22 +:10500000AA9FBA3AD7543FAF68B8A9BEBB90F82D53 +:105010005928F19B47F6C197027819E72D2E01EF29 +:10502000C84FC952022B592F6F50F8DCB87BE9AA40 +:1050300042D0E5048933E20886DCCCD5ED8BB0069E +:10504000EC90BBB3A9B2FEA8D2F0C55DF4DE496F07 +:10505000ED165C8572D2B2EEC1116EE4D76FC872E4 +:10506000D13CBC5509A541F5140CD234C8D9616BAB +:10507000E364DE4FDCD9BE5D35FCCE8383DEC847FA +:105080007FDB55CE9B30E425CB26E3741B689D0166 +:10509000FF6A43ADCCE7DD509B12DB3D62FFC518D4 +:1050A000670BF820502E4B4BE5B89068C038C86F9E +:1050B0005F06BFEDCC41E9B71BE3E9BE3CDC690903 +:1050C000D5DFBA3386E973585F379CE8F3D20037EF +:1050D000CE6F54EDCD52E10F58B66FC13A22215533 +:1050E0005B0AB92FD9D0E3AFB8AF6BD17BAAC07937 +:1050F0009ACFD78C491C4ADF39F6B4CD3381E0BB57 +:105100006A1FB7639DBCC81AB4731EE6B60D76E479 +:1051100025FF64EB067E3E7F6B31E75D2E107E5EE1 +:10512000471ED1CF6519E32E2950D6B948BE3E1A85 +:1051300026F56349ACDCCF2379FE33C67566ABE256 +:1051400085FF38AD68A7BD989EDFA7B7734F9F3E18 +:105150000EF2D71292F76DB4BCAECA7BC4A6A932C8 +:105160002FE622F7F34C3D97CDF23DED5C3F5E67B5 +:105170005D1BEE23D7B139527FB4D4A9BC1FD7F23F +:10518000FACBA953F1BD3A1BEFDE95D81BE4F97FAA +:105190008BF0E31C817B7A8394AB6CE187FFB7E4EF +:1051A0002FEFD463DE2DC976BA311F8A46A826F9BF +:1051B000AC1C1B6792DFE9A29DE91CCD75482A89CA +:1051C00080A74DE8666A7FFDB47E51FA60606B3D52 +:1051D000EB836151E7000B4C70399577403F89AB09 +:1051E0004CEF958B29ADEDB01EDE24FDD6F25DC9E6 +:1051F0001BB12F5E6291EBA1E99A7C5EB1573E171D +:1052000022F6FCB9749CC7477CC0746E5BDFE74331 +:10521000BF1C0FECD6C0719DE60CD29744D1F2DED4 +:105220008D76C4D3C85D6E469CB43C4030FAF58997 +:10523000E61A9C1FB14AFAC67B5C5D9765B4CA4505 +:10524000C52E73BE55C5C177B89D91CF185D4F9ED1 +:10525000EFCA8EC07B82E2E57393DB9BEC88074D3F +:10526000D33AF1BD14D1F79F95859A18CF6BF7A665 +:10527000B9B06F5B1175EF59A7E16E699FF4F83F04 +:10528000EE0D927E42835DC66DE3F75B78FEC97BCF +:1052900076CECB658945DE1710459709DEF7B8BF96 +:1052A0008E19320F0D74B146D0255A8E40276B04EB +:1052B0009DE60B49A7F9A44D820477849C45D2E76B +:1052C00047D26B01FEA0FA057B9520F2DFA2E933FD +:1052D0005F6B64FACDD7E2FD41D785E3A9B8E383DC +:1052E0007AE8A71D19F29EC268FA2D100D2BB1EEB7 +:1052F0005D4076239CCC726177F23A4DF1C06EBB73 +:10530000F31BED36A9CF38CEDBF2FA3B3CEF5A3C2B +:1053100034AB211782EAA97DBCCFDDBCAC8D3CDF6C +:1053200029E764FCE4BA73562EA74D30CFBB6BCF90 +:10533000A5F1F31F4B970AD019728EB85E621BF766 +:10534000E621CE9778E1788DFD10430FB7FA75E628 +:10535000BCE58BF97FD171C2DEC3F538E12031C8DD +:1053600094B77C11BF233A6FD9B0E32DF1D24E8EA2 +:105370005373DEC4D9C6E257555EA7BBA78FB7F0FB +:10538000F9F157E57D77DA8AB34D904F2DC1C27A96 +:1053900070714257BED742D3E376463F59D529694B +:1053A00088FF15C7B8381FBFB85A2D82FD2AA676C8 +:1053B000EE88762B9777CB825DF8F4EE5E8F0668E9 +:1053C000BE7C7A5B6A1AE2FE9FADB0A592E63CDF36 +:1053D000EED315E3B2909FF1D97D8EE9C136E85343 +:1053E000345CDA81F23B3F60BB75D2F27AE2747AC8 +:1053F000BF6CC5EE4484EA4A57BC33D8452EC5E19C +:105400003CED9AE1BCBFBA610BDF07EDDAC0F709EA +:1054100068484A6E8F7D8815CCF7458ADCAFBE554B +:10542000097F7125B53B11735FE2F46CDC6E2A389D +:105430004FE3ECA604FD3C5A35E70D9D88257F809F +:10544000DA1F8991F43CB233C1C37762780259BC48 +:105450007E6B2FF7774A2D75D7019F6B52356DF80C +:1054600020E011DC92AE723B3EB7AE55F7486A2B96 +:10547000FE61945B743B0D7F1B25FC6DE4CBC0DFAC +:10548000060C7F1B25FC6D3CAF5C6BF6DF6ED7F71F +:10549000FB8C7870979A662FFCDD4081E8ED673BC6 +:1054A0003BA1E0F7B05BAF4A7F6189E259D5C8FE06 +:1054B00052422DD69D3556E967073E91E7A22082DC +:1054C000D04FBF50FB7AB09FFF50DC9D8FA1FD52A3 +:1054D000EC0FE5E11E53F2BD22E4F5CA734E1179DB +:1054E000EE7634396191F0186786A9FD3857B6A970 +:1054F000FE27E97D4CF53F757B4DF0D5BD879ADAE7 +:105500004FF48C36C1D7E4FFD4D47EB26FB2099E7B +:105510003A7E86A9FDB545C5A6FAEBA72F34D5CFAF +:10552000D06E31C13796DC666A7F93BFDA542F8420 +:10553000FF09D0C71790F7AAD561FDE4C0FD2F4E33 +:105540002EA9FE0FC8631E4D22CDF7AEFCE5677C89 +:105550008FF57EE435D38C1B31C6E26F2B8EFF07AF +:105560005DFE6347FAB60DE7756E03DF8B89D82DB4 +:10557000E46E1FECD4A0D6E79DAC46DCAA2143DE46 +:10558000876E6E7FB17623E2F69F7193C8F5AC3BD0 +:10559000739395F4D78821FB73BB21EF79C4E0594D +:1055A00056D2372386EF7FB62BC1FEBA3B6771FD1B +:1055B00015FBCFA0FE1F75C3243C55B06B72FB8852 +:1055C000BFDD84FC941157765DED91719136CFB7B4 +:1055D0001B25E88473E1A013CA30C93DCAFD24F736 +:1055E000280F90DCCF23BD564F728FF220AD33F1E0 +:1055F000FCDF689D89F2755A67A27C83D697281BC9 +:10560000687D89F2EDAAE95CBE5BA5F17BEF579559 +:1056100070F941959F9F7F54B594CB4FAA02FCFC33 +:10562000C3E1328E108F7B9313FEC9BDC97E17DF95 +:105630007F50A3DB2D51A7E7D5ECA7F52BE8D96860 +:105640004DFEC2D9BABF78F1F5BE557C11E1B74D18 +:10565000B6FA3E97FCEDE462BDAF3F2FF56AC7A0F6 +:105660004FDECB9EDA235785BDF3FF3989EADEB3DF +:10567000B47D9FE43E5D5E3E1EE13B8DEF8D741E6A +:10568000E2FD74770679ABC31956C07F65A08C5FC5 +:105690008EB436D4A0BEE63BE1C6BAF9A584F7794C +:1056A0001FBC86DC659C3F56CEC9F5CA287DFFBE6F +:1056B000E63BB97F3F0AB853FD4897ACAFB9992C88 +:1056C0009D17F521FEFE289C7696E7DB4C793B631F +:1056D000CF358CE1FA78BB1BF9A6A39C61F93DA7F5 +:1056E0007021BEFC52C21ED9FF38D9FFA6EFC2FC02 +:1056F0007DAC3E91973DD2D98ACF32C6AF41DE37DD +:105700009723DBD7E8ED4769D47F32F0F34BFC8A6F +:10571000A9BDC49FF5DC287C3319AB6D591F9B2EA6 +:10572000CF278F3DA7D77BE4783B58258C3325A81E +:10573000CF4CD1848FFACBCC141EC4DF46A536647F +:10574000707B3D9F21C12ABF97E491F77175FFBB24 +:1057500026F7038800C0DFC84B32E66DE776E10C20 +:10576000F8799D17DBF97B99EA4E2FF4F5A75EAD2A +:10577000EF08AAB73A2D3CBE1A9F3C2FFFD68BEEFE +:10578000CEB85F74B2EEAFFF13FE5F81F7473AF712 +:1057900049FEE392B7CC5658994FFF0F6D93FF9295 +:1057A0005E242F183FF19FF9017EEAFC570CFAE8BE +:1057B000FC3FCFAF6591F5BA7C5CC8FF90E4B72E93 +:1057C0004FA39C326F02EDC1FF9156290F35313244 +:1057D000DFE3A584C287714F16D1A608F1F991863F +:1057E000BCF8E5F9E1FFADFCCFB3CA7BE41C654E24 +:1057F000BEA7EE52F230BB5914E2DECD8D03B57D6B +:1058000098D7C5E7DCF580E78AD18570CF8DFAA7F8 +:105810002E52AF7DDD6C036C3C7F1BED06B5D65B75 +:105820009D6FC741EF19DF31DA7DA57FAFB5DD4050 +:10583000FE9D8D25E342EB60BFC6575B396E4D9EE2 +:1058400009C307C99EC97C4E5FA2372D32FFD373AF +:1058500060711EEE0B95E7B744BCF4ABDDF41FF4AA +:105860006AE1F745CBD19F50B75BB1EE388B7C5ADC +:10587000FA4E61AAD93F1F1FB5BF7E55CE97EC8F58 +:105880005F75897BAB7F3742F7A7B345F67FF2DEC2 +:10589000D08747B07EBEBC7B437B8B3A9683B1C535 +:1058A000329F8BC66F1988B88D4FF801170ABF1544 +:1058B00072305ED45AE5BAD277A2228F57ED4C9F50 +:1058C000AB45989F4F24830263720D890FE097E3E5 +:1058D00026CDC47DC06372C774C7F388FBF3FE0096 +:1058E000FC2A54ED6FAE88FBF3F68F95F36DF1B59E +:1058F00032DEB4DFD9AD4D3FF455B2B7DD7B802E3B +:1059000082CB3F933DEE4EE37E85EC31E0AB7A57A0 +:105910000BBC57E836E71D19EF5FED1A23AC2917CA +:10592000B777570FF86327D0F9B5E45E63C1AFD7F7 +:1059300092878C453CFEB5E40E16593AEC5CF67F36 +:10594000AE7B5BF819F3A3B5BF42EECFB8FF776C1F +:105950007B79FF6F345DAF1221137D27E8F4FD11D1 +:1059600074FD087A349AAEFBF475C57EE73B7B8CF8 +:10597000BC29C493BB2F6F60F8569B9C07E5CF4DA5 +:105980002C405EF4E2F7647EC751A002BBBB7438C2 +:10599000E33F6AE95061CDE5FDA800E85DE6947457 +:1059A0003C19786900EE29AF4FD18E83AF5FAE53BB +:1059B000F9BCFDC96762381E7724F86C22E869C813 +:1059C0007199EA5ECDBFA7F19A2AEF59FAFEE52C4C +:1059D000DC2B7A31B92679FE7AC4A036E4399EE40C +:1059E000B9FF85F22C36C97B0CCA9C856DF2D9585B +:1059F00077BE30D0C7FAC225C2B740FE2B845C1FE9 +:105A000055385F97F754128C73AFD17ED5E0586A42 +:105A10004FF576A7CC1736F89DE990F75866C6097A +:105A200017E22042CBED0B7CFB76F7C58DE4FCC280 +:105A30009CED91796BA3C2FD78DF79FC4195F3DD94 +:105A40005F8995F7B837123F14F24F7FD2CF1FDF2F +:105A500095F8983C444B1B8971A9DFABE8F7F51E1C +:105A60008A48E1F8796E3CAFB37FE47A3D6BA4AE2F +:105A70005F068801FFF4F711DACB7B8417BF9A1B0E +:105A800004DE8BABC9AAA5F2EF5CF03D7135589FDF +:105A900067B7EA9D51A227FFFEC598541BE799FFFF +:105AA0006FFB7D844CA1F1FCFBCFFE4EC278F9E880 +:105AB00082DF49C84C5C75404B6DFD9D8CE8DF4929 +:105AC000C8D4EFA7166E693F8CDF47B852F8382F5D +:105AD0007F5CBAD9AE8C718D3EE0E2D21CEFC9BCBE +:105AE000443ED74D23F5739D97E27BB9D0F92ECF75 +:105AF00075420EF4DF3B09423E8DDF3B31F86EFC10 +:105B0000EE494D7BF9BB27FF6ABF7312CD9FE8DFDB +:105B10003D89E64FF4EFA08CD262994E63CAE259F8 +:105B2000AE0D3E4DA7FFD81FC0B95CE5BF9F5FF724 +:105B300047CDD3B362F520DC537ABA58EAF58BD956 +:105B4000FF695EDFEFA16FB6E97ABFC629E321BE28 +:105B50001AAB881925703F21E7CBFEA246DE03551C +:105B60006395F18000F115F7E27D1BFB0F799F2310 +:105B7000F947B68E88CBF8F9FD80DDE9AAF144FC3F +:105B80000ED652791EF89045FE9ED4EC1CBF82FDC5 +:105B9000CB4E5DB5A7A0AFD245D1CEF91C97F70F7C +:105BA000817E9FF5274716EA677591F7478A1CF9AA +:105BB000BB4106FEB332655ED6B323753DEE9179E7 +:105BC000587B46CAFDC0048F8BCF3514E7083DBF14 +:105BD0005564CDEA0F39FE84FDF816B7F4AB1B6DA2 +:105BE000F21ECBC0AB329F679DFF6DF6FB37935F14 +:105BF000AB4AFF66EDBD1C674814D8C77D2CA6399B +:105C000019F8F75A2B4CFE429FA0D39497DC6FAB48 +:105C1000CB04F70FA59BDA5FB1D76DAAF7867B9B04 +:105C2000EA730F7A4CF0A0867C53FB211FF84CF0EE +:105C3000D0C6F1A6F6C38F1499E05323BB4A3A416C +:105C400026693CB396B882F25E7C1927E96297FE1A +:105C500054CD6D723D61E4AF6BFA3C88CE5FEF6C62 +:105C600095F9EB76BFB46B5ABC5CDFBADA0997CA18 +:105C7000E7621A18C6DD109C371E30E7997772CAA2 +:105C8000F59565AC5C7FD8F53CF3D8DEF2DC8B9102 +:105C9000574EEB0A1FE8DD5D34CEE0DF2FD0EF1367 +:105CA0008D96E7BF8FD4EF738AC2BB8B5D9EA7AB87 +:105CB000B9CDCEFBE75ABCBD4949BC109F6E7A7E78 +:105CC000E46667DBF73E39474939BB21AF488CA210 +:105CD000768F92D962FFEB82FE3C8DD07735BFB2D2 +:105CE00073DEF8A5FA9B75851CCF4C8B65F6E41C1A +:105CF0005E0FF23940A3DF74F44BEDFAF874398F7C +:105D0000EA6F565233DFBB2692EC6EC8AF16BF92D5 +:105D10006157AC4856DBA07BEBB90C99A77FD3EA5F +:105D2000D0BDBD08CF99F65A9BBC702068833C4C0F +:105D300028203FD28BF8EB43EBE3891F8FE207EC7F +:105D4000C8CFE8B2AFDDEC4077F899CD2C0F4844CE +:105D5000C17E22FC4F75602BDE6BAE9479DFBE51A5 +:105D6000C2B8FF80F16AD1E3232D2274FEFC44A067 +:105D70000D79D3E2EBF91C826BB194A7CE11E7AC9D +:105D8000B0FEFC9F3A2F21B0434AFDD86A853CE71C +:105D90007809FA19E754DCB7D88A36C6E3BC881804 +:105DA000AF44D0E1892BA55C2E061DDACB76D04717 +:105DB000176B477E5F12F6175A843BC97589B8FA8C +:105DC000FFC4F833AD32CE90E594E7453A5B35D663 +:105DD00017F6DEFA3D7717C8BBAE37F4385927AB54 +:105DE0009CF79D3C725E5FA8170EF0F7ED9ABC37EA +:105DF0002D9ABEFC2F22AE629C5F891D2BF588A1D7 +:105E000017CE9F43E921D7A1365D3F04BB5B38EF36 +:105E1000E0AE04F33C7E7C94A46FA13E8FC9CE27F4 +:105E20007A079BF484C0BE5ECD0A95F504E9C97A71 +:105E30008DF02CC6BD2CAED6DF7BBBF90169C74601 +:105E4000F98A1EC4BEC99C3536B181F715E4FDB090 +:105E50000BF438797120EA7E16DD1F3FBB5A71E1E1 +:105E60007720E6AE32D72F88FFE213AC1F6F8EBECD +:105E7000A7C6D8AFBB441CE0FE51BAFDF7088F9E01 +:105E80007FBF0CF89D0DCA7BAFCF9F57D2E33F2D4C +:105E9000C167257C87E07851B45F60C06EEC9345A4 +:105EA000DCC342F48DED0DFBBEDCDA667EA341DF80 +:105EB000F3791EFA3E1D95CB56F07A46E637903EB2 +:105EC000E07DB913540F3FF044E00CB73FB12B868F +:105ED000F34A4E7A1B0660FFD6D8A7EBAEC97DAC5D +:105EE000965D0932BF21DE22E1ADF21EFB457F0F38 +:105EF0000EC03AB631F0ACE99C83D668DEE78B2E53 +:105F0000B5EADDBCDE3C9CA7D58D427EBDD5E3F471 +:105F1000107C77FC7EBEA76B02AD1FA1D79097B215 +:105F20002255E2CFFA2B7046D2CF2FE9770D397A7E +:105F30009C9F27487B228E2968554B65717828F7EE +:105F4000FF63F7C1A69EF3CAFDDF73C3F97D6DD56C +:105F500050867B079B477F40FD5EA7C5BB1147BAB4 +:105F6000B6E617E362E9D38DBF8F5FC16567F3F9CA +:105F700001A3FC58B7238DB6B6EB27E8FA67E19585 +:105F800086BE96F2BEB85AE17DB5C59071C0F7CA1B +:105F9000FB390DF84CAD0E8F93F092151286698285 +:105FA0001F3C47FFDDB32D7AFC05E34789F1232E23 +:105FB000B05D8FCF60FC28317E3C87BE020C7D0532 +:105FC00018FA0A30F4154AE82B3CFF3C790CEF6BC9 +:105FD00063DF6E6CC47CC2BEDDD888F9817DBB48AE +:105FE00018FB7691EDB16F17598F7DBBC87AECDB4A +:105FF00045C2D8B78B6C8F7DBB4858E4FFB415867B +:106000005EF34D36C153693D3036623E63DF2EF29A +:10601000FBD8B7337D4FBBC5F4FE8D62A9E97DEC9B +:10602000DB45B69FBD5431EDEB09D1CC767DEEDA80 +:106030001496A3D7BC451957B6E7DFA9FA99AD2B3B +:10604000EB078E632C2E8FF5487ED78E97FCB7C852 +:10605000F3114A33FFBEC0993BEC121E67CEDF3608 +:106060004AEC7B8DB5C97D2F94D8F742897D2F945A +:10607000D8F71ADB43EE7BA1C4BE179E63DF0B2566 +:10608000F6BD5062DF0B25F6BD5062DF0B25F6BD75 +:10609000F01EF6BD5062DF0BCFB1EF8512FB5E78CC +:1060A0007E88F09817A1C7E0AF7737AD33490E4D22 +:1060B000EB4C970986BF1ED91EFE7A643DFCF5C8DD +:1060C0007AF8EB9130FCF5C8F6F0D723E11B46B91E +:1060D000799EC16F8F7C0F7E7B24DCBF36F067C456 +:1060E000D626AE3B7500656382F228CE1BDE70E5D6 +:1060F000B6D9D8BF6C8C51B29249A7DBAA77CC1E17 +:106100000B7BABE73F0E10CD16E81F0D8BC93C3E55 +:1061100067C879A5FDBFCBE0FADBF5FB11F81FF1ED +:10612000DDBB4BF0EFCE18FBEDC6FB1E32DB288D3E +:10613000F6AD70DBEDA2FB37DA716E55041E38D177 +:106140008CBC19EF1DF103B10ED9A2FF8EF096653C +:10615000322F3A5AAE7EABEBA72D969DFB710EA661 +:10616000B958F1E0DC47F75A8DCF99F59F292CAA51 +:10617000B7753CBD1E4BE4BCDA5F5C29ED9181BF75 +:10618000111F257DC1E7074734378C49A2F65A60B5 +:1061900034FF0ECE04BBD07F2FD83F0CEBC97E015D +:1061A000C5B73142CEABF5EF690189C7138F4D9268 +:1061B000EFC5CAF79E782C91FB9FB45CE13CB3110C +:1061C000DB850FE794EFD1F1EFB73DACA2BFE2E57D +:1061D000B23FE3BBC5EBB2EC38CF6DD0AB58348ED9 +:1061E000C57DD2224FC19DB2A2A75563BFB4C34C97 +:1061F00097057ED0E59E831A99973C0E7988A24E2A +:10620000F0BDA113F3DE328D97C93518BF6B2A7824 +:106210006DA8056EB1A0DF49448014C49309C67807 +:10622000344DF8B389BED74D2F667AF79E2914D026 +:10623000BBCFCC0D96547AAF9FF69205FE5AFFDA8B +:10624000462E8D71784624AB8027D85CE380FF848E +:10625000710AEB8FE83C1EF8070C2FB7B13D37FCF5 +:1062600087C509E7F37CFE8A3C9F33076D9CE77383 +:1062700066F959AE2FDE1DC3793DDA5A85F59AE1EC +:106280003718793B65B7BC3718F439961DDC92DCBA +:106290008DEDFC1FAF441E4BD79D89381A7762F9EC +:1062A000EEEBE0529E59BE5BFEFEACBEBF63FC8EC1 +:1062B000A9C8F1713E98E1070AB5CE1EB98F63FCFB +:1062C0001E1AE94F6E7766AFDDC5BF47A7FF7EA9EF +:1062D00011F729FE4B6E3DE85ABC5EFE9ED99C55D7 +:1062E000F7154E2778BECF19C6EFA147E7632D8C6F +:1062F000F2032FF5FBA5C267F6FF2EE6EFFCFFF2D7 +:10630000BFB7FCBF73A5703700800000000000001D +:106310001F8B080000000000000BED7D0B58556539 +:10632000BAF0B7F6DA37606F5C080AA8E002454DAC +:10633000C936225EBA2EB9282AE206C4B441DC204E +:106340002676AC21B3911ACA8D7B4348D6C04469E6 +:106350008ED5D6D433534DD1654A27EB6CB59A2EE2 +:106360009A263975A682ED25B53BE9F1D49CC799EB +:10637000CEFBBEDF5AB2D776836633E73FFFFFFC22 +:106380007B9E66F1ADEFFE7EEFFD7DBF25136D06B2 +:10639000369EB1337B459F98C258C5BE3DA52C8E15 +:1063A000B1533526C6A05C562F322CB367992F4DBA +:1063B000C0728E2102CA657F501C82CCD877ABAAEE +:1063C000F7BF064DF7AF823616C68ABF1FCC5826D8 +:1063D000631DAB642A977E3F86B158C60A0211F44A +:1063E0007EEEF789F4BCFEFBCBE87DB10DFAC1FC73 +:1063F000811DCCB71AE63BE5B650F9D44EE6C3F999 +:10640000F1173781B111F8070C99C1A43C368CB152 +:10641000D18AB007BAB359DF5F45E3CDFB3E83C6EF +:10642000BB667C45C300E80FBD1D69D07ED6F8F77A +:1064300072FAC17A5DEE295922948B8DFE39387E2D +:10644000B1C3C4DC29F8FE564302D417325613EB0D +:1064500080F650C6FDBA5CAC468861ECCE89D06946 +:10646000009459CDEB03100E5B98632BBC9AE7AAFE +:10647000C8C67663CA9820C2D4E551ACA61DF7629F +:106480000B64155DCED80FF8BB0EDEE322AFC4C59A +:1064900027BA14A82FEF077F0EA26D29CCCA983D0A +:1064A0009DD75FA924BABCC3E1EF96758A7520CE4B +:1064B000C77F43CDD00EE611EF34FB5603FC5D36AB +:1064C000EB61612C54B8F394C028DEE68754C6868D +:1064D0004D823FB2E05C0C86854E9867C18A0C7392 +:1064E000657ACF3ACCD9D9F3A6C03EF2F0BC61BCF4 +:1064F000E56B4C3E4B0A3ED3E299ADA75DE87311C4 +:10650000C0578EC575076E17003EF314A6E4C25C33 +:10651000F399B62FE667B08E1BD4B2D7AF049A6C4E +:10652000040F2ACFF18F70B9611D375B03530193BC +:10653000D8CFD36BF2130D8CBD61E270B5985CCAF5 +:10654000605887697B867FB08CFB90E83D330612EC +:106550009D76D8C7DAF6FB46C27BAF22F3FD995B86 +:106560004C0C07623E9313E0BC289D293E84BB91EE +:10657000E3D191352F3DDD2CF4ACFF8889CD6B0F35 +:10658000B3BF3AC540F36C03BC954732F6DB5556B2 +:106590007A3EB14A6232A0E053AB12A8FC34E0313B +:1065A0003EDB578DA2F7CFAD7250F9855593A8FC0D +:1065B000E22A85CADB57E5D3F38FAB9CF4BE60B407 +:1065C000EB1605D6FB9041397C0FEC6F90D8C210CA +:1065D0006FF1DCAD137ACE37A2E5BB0A3C8F2A9B64 +:1065E00059C6755701685CB08F4AC5EAA8075000C4 +:1065F0006C1B13A05C2EB2EE6647B873E7707C6C20 +:10660000FE7F2D3540BBC7EE8A24BAD5E057663EE3 +:10661000F0BA35A5077E1FD5FEDAC40C746C69325A +:10662000CC7B434D84A33905F1C3E9C1F546A53BB5 +:10663000CC2E80D7BC298CC6BD32D5D988EF6F5EF1 +:10664000BBEBD10FF0FC76A6985D709E15DB331A7C +:106650001364ECE7BA5781761536C98C78778B3797 +:10666000C62CE3F9C7033D206EB3EEE4627B0FDC7A +:10667000B728028D7B7D361FFF1B3C1F6AD7622A1D +:10668000D2B5E3E7733E3D1C9882F0F200FB581D43 +:1066900083F4F0E2143C77E94EA091C9B01EF63EB7 +:1066A000D59B1398E489391F5E83D90101EB13014F +:1066B00096EEC93DF06B1E55497CCE043428C604C5 +:1066C000C38F113D85E2CFFBB80F804BE50A6175A2 +:1066D00003CC5FD526FA0401E9ABE00DA2AF564129 +:1066E00026FA7A70983991E84D90907F15F497A723 +:1066F000C643FBEEFB0469B38CF40A738DEB19B748 +:106700006AFD64A2B72A1F3C337BA7CB9FB5EE4935 +:10671000DA21E3312A665C6795A498FB07D1FBA2D6 +:106720001681E822B4FC9A22723A626F9A106E6562 +:10673000C365C19381FBE1F8B160458AB9D286F5A2 +:10674000CC6F807515A4B237B05D772BAC3785CF91 +:10675000332E68DC4A1C37685E68BFD009E57715C0 +:106760003BC1B54292CD8928572489D657B9629743 +:1067700009E1B308E02C64203C1C661B8EBF14C6E4 +:1067800007F8DD20F9F3B0FE867499D5C339547A41 +:1067900033CCC89F5C6BF93CAEA618F3E550AE3025 +:1067A0004AE624289745323A37589F0FFB57013C59 +:1067B000FADB705CB610654B285C2AD4F556B5C47C +:1067C0009817EBDEB79AE474E26B4A387E214EE10B +:1067D000785BE92D4A5E87E7EDB64B44B746C5ECDA +:1067E000C075A9F09DDFB6CE9412D4FF5B158FC59E +:1067F000291CCF0A52FD6902EEF7D60807AE77BE14 +:10680000D46242789E83F3831C0E8B257F1A8EBF41 +:10681000D8CAE1700E3FDAF4E7DAB33E0EEFAAB65B +:106820000AA2BF1B8DCEE475D0FF4658A71B9EF36E +:10683000D7EF4A13F009F42E207F905CC9CE207A5E +:106840003BFEE0F5C9B47F583FC2DBEE90A722DFE4 +:1068500001BC21B9ABE14F7926A76BADDFE029463A +:106860009A77F0944BA3D7AAB5EF51FD22A0579485 +:10687000B766F68280F5666084E1E837094786F6F8 +:1068800036C01F77620FFDCE6781F9C85F17AD2D47 +:1068900062AE20FE03F2B6E6B930F09A87EBCD2265 +:1068A000B945E70D74F81AEBDF539FAD9E7759AAEF +:1068B0009EFE713C1CD7A1D567FBD36E4DEF69AF2F +:1068C000CD5BD69FF7437A403C74A8F0C1F6CBA9C4 +:1068D0003D2F833C5EDD80FCE13ED16711F0F9780D +:1068E000C3402C3F0BD216B6F6C5F297DE9D0BCFF8 +:1068F000CF1FDA548EFBD3D6B118F41DE41337AA98 +:10690000F2B9CA1F9E5FFC6292EBBA295941F8F3B3 +:10691000C0EF4720FFFEE2E977D210CE1FDB39BF80 +:10692000FBD9EF1F37B1D49EF55736BD67AAB00526 +:10693000C38BF3BBE65107E9FC168DE2FD1679BF68 +:1069400025F9C5407EA5A59C7FFE15DE6779FB5A1B +:1069500007B577D9FECCCF7F1093C4C40B9FB77611 +:10696000BEA1E7FEA8C9E94F407D34B54547FFA168 +:10697000FBAF50D75D3585F3B71B543CBEA1BA952C +:10698000FA5536553C8E7AEF7C8D7EABF4EFB5F33D +:1069900039B5D644E7736A6D5A23EA8BA7DAF9F959 +:1069A000FC8BD83E7625B4FB62D9D65B1253492FB7 +:1069B0004946BD04CF07F5D21B55FD74099C0FEA6B +:1069C000A761CEE736D4CBB4F292C7F8F92C7A7A25 +:1069D000DF277F9409FFF8FEEEB3F890FF56B63F2D +:1069E0007BE84A783FBFA9D59402ED3C5352083E5C +:1069F000E7F87C4D86C4A2617F4D9B4CC8073CDA0A +:106A0000BE43F05C832B33723EF328E8F0CD315C5B +:106A10001E09FD7BDACF674A3CF211E61EC2B6C6FC +:106A20009DBFFEA7553A2A48759849AE3544B1CD69 +:106A300012AEA3E27E36B677F9753482D305485D8F +:106A400005E9F3E8144732D285A6BF86B6DFAAD29D +:106A5000D7E0A8F6F9B8DEC1B120DF01C4BF895480 +:106A6000B251EFF9CD9556C9E3C0FE2E19EB2D5664 +:106A700026A17CDF6C90C7117E827E7F4F22C232BE +:106A800090857C6FF8B2C0B7B83E44A78871FC69A6 +:106A9000877DBFA3C20B55F181FCBD1F9F49C67600 +:106AA000E25391B51CFF42F50CAD5FA87E11AA57C9 +:106AB000F4B6BF3D17B9BFA3292E1FC98908266D9B +:106AC0008EA1FD2DC7F2B9FD8D628A01FA97FFF202 +:106AD000F24DA84F1EAD57769BA1FEE81D36EAFF8A +:106AE0008FDA6FE83EE75755E8F6798E6E5A44B272 +:106AF000334EB56426935D07360F83FAA3B7461865 +:106B000010FE4753B8BE0016A01DF5C46DAA1D891E +:106B1000FA383E511F6723B93E8EE5A755BB12F5E3 +:106B2000717C7F5CC5BFB248251AE57277BD5DDA1E +:106B30008CF0F073BAE9AC1D4670003D81F36355EB +:106B40002FE89402F6FE417C1AE4C77D28EF58ED49 +:106B50003086F65D67CB51BB211DF192AF4F6BBF05 +:106B6000C2D4C2EEC0760F0BBEAD306ED48AF7F23F +:106B7000E2514EB7A56408D06F41ED69E2870B6C16 +:106B800003658672DCE66A9C88F5EB53A4D5D02DAC +:106B9000AA2DA3B316FA2FF68E24FB798520937EB7 +:106BA000CFEA05B22B996A1F2CC1BFA0BCC4F6C6A0 +:106BB00070955F1A905F2EBAFF8EC644281F36B0BC +:106BC0006E11405360289A8AE5820D310E0FCA5B20 +:106BD0000FDF0FDB087CD4DAC3474F4F72B26CA4CF +:106BE000F7B3806F30FE68581BDA512B4CED0AAEBC +:106BF0009F81DEB195E17A9DA4C7AF52F1A2B3EDBA +:106C0000B05D56CF07F5F3E1AEEEC3F7E0B9DA0CAD +:106C10008E6619E5BBBC5F46B8BF2532D4678733A3 +:106C20005EBFDCCEEBE149FAF1F24DA28F917E5CC2 +:106C3000363080FAD77A91F8E2E24D250351DF58D9 +:106C40000C65945F1B702AC0A7C6B61CDEAE35EF7C +:106C50002137F0D3648139911F1D33068A101E2716 +:106C600037C5F7AF477DEF66CF0806F5559BEE4970 +:106C7000C6E7C94D11F3908FE74A45B931A8FF6CBB +:106C80008CC940BB5FA3B3F46C2E0F6EBA39271EBC +:106C9000E5DDB2BFEF795402B9BA187054423F48EB +:106CA0007B94CF0D4D96ADDA9E2C026AD9E35C231E +:106CB000116EFF62D8397732CA61C1B72D91DACB34 +:106CC000F1521F76F371B42B014F6FBEFB431AE7ED +:106CD0002BC3DEC2F9D07FD9CDCF47E338FFF260B6 +:106CE000C70409DE1F1BEFCAC4F13F17366D93D0EE +:106CF000AE5DBF692CCA8FF1AA7D54D0DF39773ED3 +:106D000087AF63B3DCFB7CD5DB0582A7565EE0EB87 +:106D10006766A897FA9959C2A7C4480F3E29B25A84 +:106D200094EF9A5EA2BD9F96CDF9CFC97E2DC9780A +:106D3000FE4BB7AD4B46F9F1999D975D5BFEB4F8FC +:106D40004E5887ABCD2031C03B979191DEBBC8CD6B +:106D5000F569560DCC24B167FEA2EC2882F3D2F57A +:106D6000993AB9878E197CFF9991E5E33A867ABA08 +:106D700033507FFAC8E85F8CE7FA11E8A7E8974933 +:106D8000CFE6F8F7518B3815DFBB57080CFD4F1FC6 +:106D9000B53C6F1FCEFD28E4C7602F9B7C5BA1BD77 +:106DA0007D7CBB1FF9DECD2FC48C4330E689E9F131 +:106DB000883FCB7798A60EE6FA145AD36C99D16F18 +:106DC0000E776E37A97AD4B9F20BCF9A11EF973DAF +:106DD000D54A7E0550537CA8DF2C6B7FF68D413061 +:106DE000DE2DDB2B32711EADFD2D2F703844B080AF +:106DF000B92448AFAE18D5BF7130F0C8E5D9F9AEA7 +:106E000007511FC273BA12D424655245BD119F1297 +:106E1000ED9319BB491F07FD8AECEB9BBD7CBC9B26 +:106E2000471D6C4CA57D15C5B2A0F3BF2DDB44E713 +:106E3000A5F5877D533F8FF5EEC702B05EC563644D +:106E400011D742D9C83EDE86F063D1D256DC879195 +:106E50001D7B039E2BC57EAC199E1B6B96FF2BB52D +:106E6000AFB748223C3D37D73D1380F964913919BB +:106E7000F47767D7D0786E33973FEBA29E7EF846C3 +:106E800028D7CEB13900BDA11C4DF0D9F90B03F1C3 +:106E9000F944D6BDC700CF78065404001A92EA6AB6 +:106EA00021BEC3383F5E799BEC437E0C1C5C403CAA +:106EB000FFE6951399B8EE6B87064E235E99EAA715 +:106EC00057E402FDAFCF56E1921EC8C4760376ABFD +:106ED0007CCD7880E4A32941EE8FFA8A1FC7C2F5E2 +:106EE000FDD54078B053F03F8EF36A70DAA7D2FB3D +:106EF0007319AE4DD9F05404D3ED7E683F5B8876AC +:106F0000E07E0FF417D3C60D433FC4C72938AE1B2C +:106F1000D0561CDCA3C766AB4B370F9AB41EE132C8 +:106F20000500CAAE065B26BD3F3342F95E66E8B691 +:106F3000C03AB2BBFFB2A91ECAD2AFFB3111449511 +:106F400027229965C3F8C26ED828EC6777FAEE4518 +:106F5000B8CE7BBBAD0CE1C4AC7A3DD76C48F4FF36 +:106F600012F1B926DAC112500EB567203F62B7D8C8 +:106F7000C83FB3E06C20EDE72897FEBA97F4F49F82 +:106F8000A5BA5E46B80E1295C32EA8BF57F20FFBE6 +:106F9000158E5F1BE5A8E7728405AF7FE71D7F8D27 +:106FA0008E857EDF748F303E03EDBE51AC0EF4E76C +:106FB00075DE39E6B5ABA07CB52A4F42D7F54D82D8 +:106FC0006C44BBE39B6EAB1FF5906F6C06F2736471 +:106FD000EFDCF321FA21B3AD36BF188DFD4C5F060F +:106FE000CB1B762029E6F8181231EC0780E74055D4 +:106FF0002E5DDB4F6F3F7666733BA853E53F46D966 +:1070000041703EE536B266C44306659CD768959AE2 +:10701000617DAFDAB62D40FFD5A9EF53FBA1DC3877 +:10702000B573583F96DE3B5FEC407D02F484884C9C +:10703000E5533C7F4DBE96AA708968B9DE84F0F0B6 +:10704000003CD0BF566A33F82DE85F9DA38703ABA1 +:10705000ED2E47BC61866807D20D9E2F9EBF2C186F +:10706000BAD955E79FF7756725FF2FA1BC00CE134E +:10707000E15A7EEAF8E5BF62746EDFE23AE01C1B7B +:10708000AE603DE7F7BFEDBC98D1D184E7B052B414 +:10709000B7E039788C5CDF73036E6D8DA16EDBF029 +:1070A0005C567A86D3390DF4009F403B0598DAE6AA +:1070B00038E42B07A9FD56CD9F36AA86F84CB9C7F0 +:1070C0002221FCBE8B8CA6FE0CCED534281C9FE161 +:1070D0007CA5B68A115F59985E23E0B927E00CB011 +:1070E0009F4E43C08EFB0C44801609CF6B725255E5 +:1070F000FD1B3882EA67C5FE8FDC61DF8CFC46B47D +:107100000E7EE4188822D6D41D3D1AD6D526B07638 +:10711000DA9749E51F4B6DA4CFB5C5F888BFB59583 +:107120000E71E05EBF616A7D7524F197AB0C062A93 +:1071300077CF1F48F6585B0CB0561C6FFE68D21B09 +:107140005EFC3B8F9774A7315E9FC146ACC7FAA225 +:107150005134DECB1ABFBACF4EE3B515298991540D +:107160003FD080FD5B535C137388AE793B503CA8E5 +:10717000DD860D4A229EE7866233B57B4870CE5F7E +:107180008CE35C6E23BD31303FF2E96DFC38FDE8E5 +:107190005FEAACE5FBD6E840F3AB0F751F7E18F94C +:1071A000873B1B4E04ED43EBD70B10AF1531DA01D3 +:1071B000287CDE397F770ECF59370097C545769208 +:1071C000BD2EA73104369C9FC4B2114FF6003CA1DE +:1071D000BDDB04E71CC7CF79751C9E73E1A6E07385 +:1071E00086F1DC2BE1BDB03CDA214CA2731E85E3B5 +:1071F000D7B24807DAD7E7CEEF555F063E4583237F +:10720000C102B0F83CD5353F27AB478E3CF209ECC4 +:107210000FE0526E0964B5A07E6E60D5ED61F8C0D6 +:10722000A21C6E1F48ACDB84F275A186FF7521F8A5 +:107230001F1812733C4AC57FE8F74ABC73319EC3DE +:107240005742C7047CB9F76FE2BC70E3DF9CC3F917 +:10725000D68138E7325CDF70E3EE21B7A1BE7187DB +:1072600085F45F7676CF109CF77729CE9FE378116F +:10727000C3BBC9BFDE99D86DC2FD75CEFF3C09F511 +:10728000AC85B57F22FABCD8F5AD8E1A6B42B91920 +:10729000939F610A40FFF8FC8CD7F15C0ECEB2C818 +:1072A00096307E905DB32626A13ED4317D6212F2E7 +:1072B000CB8E245833C953871DF9A869FBE5765C4A +:1072C00067477E26956526ABE5923EF9EB17C05FD2 +:1072D000FDA0087C06F61A3E4F80BDE6077EFB291E +:1072E000D86BF83C0AF61ABE3F0CF61A3EBB56396C +:1072F000E87D47FEB0ED8817675AB81F6591D11138 +:10730000562F5BF694C8FC1A7F83FF6EDA12A52B0A +:10731000576F8CD5956F6C030CB2F694ABD60ED329 +:107320009535FDB3D23B46F7DE5597A92BFF3F03BA +:10733000DF260E5FF497FF6F822FFED682BC2BC133 +:107340003F00BFF7654D233EDA21B09A5878C64812 +:107350009CFF199D02F9DDF0D70272BB18FF00BA3D +:1073600031DAE406ACF742FB5F435BB47DD1FE60EB +:10737000CC61AA80F7A5F91112CAF3B9AC86E86C02 +:107380001E6BA1E70DAC9D9E65EC003DCB19A7C31C +:107390006F2A0213F0F9719CEB53A4D36556D7639F +:1073A0007168B725B946C6223FB2F527BBB4B7739B +:1073B000420D9BA97AAE6D82BA2FF8CDC1B543BFFD +:1073C0008351636FBF5DEE99471B1FE63B8D7CE3E6 +:1073D0002B139F675FD6C424E40FCC3940674FF569 +:1073E000365FAB2A272BF2399CD0678BE563A50269 +:1073F000C58B77B55ACCE85F38B6C6A4EAEB77936D +:107400009D7BF810F7CB1C6B98968CF857DF3A32BF +:1074100019F1FC98496EA805F81F9B0CFCDB417E16 +:107420001C07CA8723F976EA0F92223A03CE6D91A0 +:10743000BABF23B2C37C07B42F4D1499DB81F1F49A +:1074400094685CBFB6EFD07557AEB5E8F060F6242F +:107450007DB994997BF02D05CFDBDC538F7A925860 +:10746000D6CFD587DD5DFBF1D2FDAF05E16B72AE06 +:107470003D0EF51A36914DFC41ECE9DF1B7CB57CE5 +:10748000060DBE1A5E7D9FE31C999B45AF29DE86E3 +:10749000717494C71DDB391C5BA3AEBDEF2A80431A +:1074A000F1FB22E3702E777F84F8BC83FBF543E782 +:1074B00009205D8F447AE5745DE17D8FECB78575B9 +:1074C00045265C5FB1AD3B09FD4EBBEE1A9984E7E2 +:1074D0007270D6C824E41B7BA68F7C64058CDB55B8 +:1074E000203A2C804FBB0A4EDF87E58E3A51C27995 +:1074F000BBB69F56F94BF7BE89B0BEAFF34D24879C +:10750000BAB6FF73F84CF10EE03330FF191FE733C2 +:107510004B8C4ED608F32E01B8A01DFFCFE63717CF +:10752000E233074DCE3CCCDBE8AA171CE87FAB9FCB +:107530006E21FDE120D08785E353C30AE49393C015 +:10754000FE9510DF9C596853766C1F3600E1C5DC50 +:10755000CAC151137AF07D51DD9202F4AFB3B5A6E2 +:1075600023A877A33304E57331331E0904E1A9EBA3 +:1075700005534F99F0DA78241084D7A1787A1BE26A +:1075800069540F9E9E616793CDA9BCFEC0C01EBE0C +:1075900087BF60FE728BE86FC478BF86B7FF39FD86 +:1075A000BD72541280AFDC9D0BF8FB8B7129AF04C8 +:1075B0008420BE72917CAC35EAEF24F7D645FD9D60 +:1075C000E4DEA1E95CEEED9A7EFDEEBF20DEDFC5D4 +:1075D000F1BEA37422E1658709E419C0EB605D6622 +:1075E00034968FAE2D213AD3E827749E2E15FFB521 +:1075F000760B8DDD264718FC74D589BAF34C7B6178 +:10760000413FE7E5BDAF5F1B576BA78DBB3024AE95 +:107610001B3AEE13B9DC0E4DDB52D6E7F86000F6EC +:10762000F4A33C94C81E7C15510FB89EB9013E5D71 +:10763000F91C3E5D05D7133D1ECAD7E8D2C5301EE2 +:107640007B708EE843FDB52BFF34D1E919A0531AA6 +:10765000A397794FAAF4795CA5CF632A7D6AF5E2F6 +:10766000D607E7DE80E3D689C4A70FCEC91C80F316 +:107670007DB6258DE685F550DED15BAF2DACAC1F18 +:107680004EFCC18EFCEB10C001ED8492D212B2A769 +:107690004B4C8E01E1F484D07D878EB76B9685F2DA +:1076A000C8603CE277C57795B046E40B0007C4CFCD +:1076B00043D81EEA8BB7723FF01E6C1F170CA791C0 +:1076C000A4AF1CFAADE040D161DAFE373B9EC35255 +:1076D0009F9E5F2C591FA53BB7C52DB1BA72F1749F +:1076E000BE8F4375C30684CB6BBAD0F969FD2FF604 +:1076F000FC6F52FBE39A7F203DA5BF6E3C04927E57 +:10770000BED490FAD121F5E374E50BE1E361152FC6 +:1077100034397238425E102EBED45568A90ECED3CD +:1077200088CEE3764B749E1AB7FF917235224FCF05 +:10773000AF2ED45FE34F9FE738A53C94A3FE12CA57 +:10774000DFBA587E14248713F270BD01C18CFD5B33 +:1077500055395BDDCEF16E5DD4FD947FF395AAA71C +:10776000035E12BFFF5AE5F75FFF412DFF5E20BCAD +:10777000DCB3636534EAED27B68F8C463BEC48BB3F +:10778000271AF9BECCDCD157023E7EE904F909D3B1 +:107790009D6CEF5B7E7EA6F29D13780E2437253A12 +:1077A0008FA3AAFC3C8CF293E4FD287A1E44F909CD +:1077B000F5739E55F5F4DF0A44FF4B8D2DE1FDD3A3 +:1077C0005BF4FCAA7A6354889CD4CBCDAAB58375AC +:1077D000E54AEF305DD955A7979B796219F1F5130A +:1077E0003E0EC792FC4C5DFB13B21C2D117C381C65 +:1077F000BE36C9D18867477CB1D1C1F4A2F1DF831D +:10780000217038867040FCF496F4892747D5FE5ADB +:1078100019EC4213CE5B6275BC1E877E84B5820371 +:10782000E35498EF3709CEF1C09C8CC79B83F48C4E +:10783000F7F344C297C3DE3DE5987775060C30F444 +:10784000F3FEA96E4F32FA572B9E8A22BD2974DEB1 +:10785000AA023D9FF9B2A128FB23E857F2BEE8B384 +:10786000223C0A62887FCD7956F48950EEAACB89F2 +:107870000EDEC709950E35B9B3C45813F61CAB37E5 +:10788000EACFB1A4A09EC6E978506817FAC173D7B1 +:107890006490A4E7F72B31F2FD2F794A24FFEE1212 +:1078A000EFB7FB30AEB804F4405413FED4E42944DF +:1078B000BC3EEC3419889FB6C716227CDC7344CAE0 +:1078C00083DDDB348CF0FC4853CE409CAF4985D33C +:1078D00089ED168370053C9D26E6277BD54FE7F999 +:1078E000A5B784E4C609840BEA414689E8E2813CF5 +:1078F000EE973F0CE360BD01E804F5E12E9F98EFA1 +:107900000B431F0FA8F31C3DFB2BC29F377C7BA2B0 +:1079100051AF38DCCEC73F5A2745637CEA1D6FA6BE +:107920009DD65700E3A2DEBBE37A929327BC1C1FCF +:10793000719D641F3671F9D1E15D74FF6480C75792 +:107940006B45D23BBF6A2A299C8CE7BDD644E59C97 +:10795000A2528A6F74F8B87C39E43B5A8EE777C23A +:107960000BA70FE5FA1D13F78D8FC37336113E5425 +:107970003DA53F97D2B57AFA825F74C604CACFA4F8 +:10798000B82CA81353D14EAA4C00F909947BB8A087 +:1079900084F22A8BDD7A7964614526C43BD42FB109 +:1079A0005DE52325597EA43FB740F272E10B3CEF21 +:1079B000DAB4E56A9277152D16DDBCC5757AFBA899 +:1079C00032C41E0AB5977EB4BC30D5948793171D78 +:1079D0009A5C60D25484FB1130AC9B33E0FD0B22E7 +:1079E000E5239FF14610FFAC5878EA1A552FBD16D3 +:1079F000F18039DC6C9266A707D159A5570CD1D319 +:107A0000F5F005FDF938EAC74DB1AA1C759790BF8E +:107A1000EEF31CE510F1FB8BB5BF2F5ABF2D57F5C8 +:107A2000DB72D26F3B4A2D94AF79109B04F5DF5582 +:107A30007A3DF9750ECDBA9EF4DC43E7FC3A4ED59B +:107A4000AF730D9DDBA102C067921B0EADDCA71EBC +:107A5000A1F18B4FD57338AAF2C9C32A9FEC52ED1E +:107A6000AD46555E78557971A840B5B7E218C90B97 +:107A7000A3516117C3676E6C8B0A910FB12176D445 +:107A8000E090F3D1CB8B6545AEC8A940F79684D181 +:107A9000BAF726699CAE9CB66527F98FCFC83C9F84 +:107AA000E81EC4098C9794F2FC2C666D27FF71A91F +:107AB00043A6FAC1182784F66852611E89869FDAA8 +:107AC0007B298EBFD7CAFD61D7F5D82EA59DCA9E4A +:107AD00052C6300F66B8360E80A31EF484C1E8C7C4 +:107AE000867912C040C3F61ABE0F99D34AEDB2ABE5 +:107AF000992440BBF4A929C4CF129842FC65E03216 +:107B0000A660BE0BF33D4FED1EBF1BF601781FF0C4 +:107B10005C47767989359AC7BB413EF68D67F53C5F +:107B20007E991F4B7ACB102347CD5EF1566D77219E +:107B3000BC0DD283264F25FA34903FA2356AAC099A +:107B4000F1B4D8E624BF01E0F582DBD15FF98A9970 +:107B5000FB094AB97FF2E0F4898FA0BD3BF6191BFF +:107B6000F9920F2E067C26FEDECDED84BA1237CABE +:107B7000BD3FE7733937E6992FE97E44D776E6C0F3 +:107B8000F29EBAE74FBD8DF43247203BA3A32E8768 +:107B9000F365C69C98BFD9919FB39ACA93C030CE63 +:107BA000407A50561B711D00D766AA5F745FD67865 +:107BB000BA6F42F89BA0E6194978AE893DE5384591 +:107BC0002DB3ED544E28E0F9817F54F58376F53CD2 +:107BD0007FA7DA41DB54BA6953E9E6D72ADDAC095D +:107BE000F5876EE47433C2E8B82F0ACA23DC7692B4 +:107BF00033FB0B8ED2BA81FE258CE7A64C179BC7B0 +:107C000003DCC65802C4A74B40ECAD86FD4C29A846 +:107C1000A7FCC51217A37845F19C7A5A5F00634B05 +:107C200057A1DE542F886A3DF2C731B17E6A5F6C7E +:107C30006512F62FC97F7617E6E196BA003450CE6A +:107C40009D532F107C2A603C68BFABEE011AEF50A9 +:107C5000355FC7413BEFDF51C1243794D358FEEE67 +:107C6000157C9D4E8C871EAA7B7E17C17B0E87F7E5 +:107C700055270D3A7ACCF047EAE87AF496FEBAFA3C +:107C800091EB07E9CA039CA9BAF6B1F97A7A8F1C7D +:107C90003E4E57DF915F6240397B668E96DFC3FDB3 +:107CA000629A5D37E5199B01E1317796A8F9710D6C +:107CB0006C205A5D8CFCBE4DAA9EC85A8631CCDF22 +:107CC00078FC4E03E507AC99E3B162DEC3997623F5 +:107CD0009D178C4B7CE4D04E238D6B4DF10AE8C789 +:107CE000BC17E02C06E97F4D9A7C53FDEAB81E6371 +:107CF000D07AFACB0C33C6CEB56F53F1E901751DBE +:107D0000C0B7A798705E27C793D802663041FF01BD +:107D100073B89C0EA5CB76B5FFEFD4FEDB547CEC9C +:107D2000CA7F7C7524C2651E237D244F5CB63A024F +:107D3000D751C0881EDBFDBB2383F5C73FF636CE87 +:107D40009CCC3C1AC7CDF9E8E8D9822702CF7563ED +:107D5000E0F377E1F9F2578DABA361BD4F08AC1D9D +:107D6000294AE39F9AFE7DD5D74D543F7A1C9868E7 +:107D700050FFF2D7CDBCFD0426A3BFEB8FAADC6970 +:107D800052E9276D4B3AF917CFAC3793DDB3AD709D +:107D9000C9E63658EFC899773DF102E24BE15D7FC5 +:107DA0007941EED1F34B0A133B317F7FC42A3B4329 +:107DB000FEA0CD9BB6E5CB6C5AB7646488A74F6E26 +:107DC0007DB112C7FBDDB6488302E33FB9D948FC59 +:107DD000E5B27B1FD9BC9E9DEF8F29C9D7DBF9BFC8 +:107DE0005BB3EE89EDF8BEF6F9C78E05E5E974CC14 +:107DF000BA2709FDA6075755B7E5A6F5CE3F4BCCE8 +:107E0000CC85F1BBFC97BF7CEE1D98FF03D765E3E3 +:107E100082ED80CFA7727DE7E0AADAB65CB0534767 +:107E20008BEAFD15A37B35C263F44B0365D4DF8079 +:107E3000148C2E8065FE8C088302FBFBC067DC443B +:107E40007C60C69A343CCFEC270B769FC4733EA46B +:107E5000E27B2FFAC841F59CCE954D32C1DDFD8AFB +:107E600095DB378A9C44F6B1434E2A0ED2E70EDEEC +:107E7000A5C5971C9F201F2F2E8BA2B8B216771175 +:107E8000F3BF6D403EBF70524D9644EBD7C7F1072C +:107E900021FC3231CECBE3F56EB791515E106C0D03 +:107EA000E964A5389AF24D3E5CFA0B8AD7BBEB2DFC +:107EB000525A1CC50D9EC1722DF01DCB788AE3FA73 +:107EC0005068274DE37E84D3F33C8F98E5DEE1EFE5 +:107ED000BDC0F998D4F3097D9F348D9F8B07CF25C2 +:107EE0004D772EBBF19ED479E7126D25FCD2CE459D +:107EF0008C6EA2736156DB28CCFB88E72885FBD902 +:107F00008772A8F310F7977D50765BFD4A289F3A59 +:107F1000DB8F215D687195F2049E7F4047027CCB28 +:107F2000A4F68F57F56EE463A87797AB7197CE05EB +:107F30008CE22EDA78676AFB497CBC5B486F2EAF17 +:107F400001FA475912F52AE9170DC3787E44B9ADF5 +:107F50007B01E5AB0A0607C6CDE343F47A37ABA154 +:107F6000F5C6BF2F923FDF10B596FAC70378F0FE33 +:107F70002166E8B260BF1218AD984F42570DE52058 +:107F80003D4BCDD78DAF7D89EB4739D03351379FEE +:107F9000F003ADDFF3A9887CA0D62223DFC3DC2C5D +:107FA000E4DB04BF14C4A375D45FBA8949788F8316 +:107FB000294CC67B9A823A5FE8FA613CAE17827E12 +:107FC00086FB15EAF8FC1B67F27B206C279383ED98 +:107FD0001616BC9E61BAB2EA27D3974D09669D9CDE +:107FE000FAE06C49BF9A3EFC35A1FD0DB2B36FBFFC +:107FF0006F7590DD95DAD35ECB13D3E03CA8D672D3 +:108000005888EEBDDFB222E5E7D3804E6DCC99FDF6 +:1080100036C0C3F5BE48F2CE10B597E01188E0F047 +:1080200039A7CFCEE3FA2E68E7F5946F0DF20ECFA5 +:108030000FF3B44700BE33B73E4F409B578B2F75AD +:10804000AAFC38901258E00C038F46A4DF2CE4E71A +:10805000DF50BCBB1CF55BC0E5C0EA2F74F73F4E98 +:10806000164D69C47587E621687AA976AFB4D3CD79 +:10807000E56CA73B93F8CE19666F21FD3F94DF189E +:1080800019E57DAC14231DCDE4B7BB9BF2466ADD38 +:1080900016C902CF590EBD3F66F624BD3C28526278 +:1080A00043E485DEDF55EAD4C78986B7DD41FCEBC2 +:1080B0000CEA4DC4EFF87A8C6A5E9909EF978868EC +:1080C000AFBBE9B957E5CFEFAA7A6604F257781F3C +:1080D0008589E5808F7616A0723F44F96198D22E8B +:1080E00053BE632C53A83C80B9A8ACE54126321F8F +:1080F0003DB5FC962416A0F250D487442429999EBD +:10810000C3D00E19867A9EE35CBC87F22673522890 +:108110005E50C4944FB05D41E65724F70AAE67EA5B +:108120003DDC138B14287796B29E7BB9986792C773 +:1081300054E4FC7411DE3FEE9CAE958FF3F214DE36 +:10814000FECD3F7DF138DED305FEA5D67FC6EBCF51 +:10815000954F2E9A82659381CAEF637B280FC8538F +:10816000DE9A06E7FFC9344678E4C955DE092E0FCA +:10817000CF55F621DE68E5095395FDC1E59539CA6D +:108180007BC1E5C773948EE0FE5D79CA215ECFF3B3 +:1081900097DE37294968EFC2EFB7C2048E87F87BB4 +:1081A000C3E4FA04DB294F09042F0BF0ED66E2DB90 +:1081B0004E86740A6463C53C22E033E6DBA19E8DE3 +:1081C0003353BE9F21CA96DC973F3294BE0226B637 +:1081D0001DFD744546D717440F217C4F70FFE9AF52 +:1081E00098C703F4908D7A7E408D8704EAB83F40AB +:1081F000A313ED7DE87C17C27BA604F979537BC6F7 +:10820000ED6DFDA1787C40D5F70EAAFADEFBAA5FE2 +:10821000FADC7E03C698E3D61EFAEE9D7F1AD9F1EA +:1082200020FE79FE7E8F2E3071F921A1BCE88C08EA +:108230007F0FBBB7F5EDCF991A974FF95E43248AAC +:1082400033308DEF737ED3897F021F1CD34FB35F12 +:108250001D5684431A4B98310AE66DCD67A4BF7A48 +:10826000727717D3F70DCA4082C1BA8EAE38861422 +:10827000C78467B83DD192C468BDF6142902F5A53C +:1082800006956F5A58CCF4E1B8FE214692B7A1EB9F +:108290006E88F60918571CE48FE0FE8D38E68B8057 +:1082A0007106E53BF2296FC52D4AF9582E6385A367 +:1082B000A05CD926CAF930CE9EB6125605E3564DBB +:1082C000023E4719E93C9FA2BF8AC7632C8CF22D5E +:1082D000D60DB051BCDABB66E4AEC5C837134596BF +:1082E00006EDD31BC6E5A3DFD363EBDF9F624EEA47 +:1082F0007A3C36C79B780FC32D19F83D1249B162FD +:108300001EFAA615C67CE4E749CF8E8F1683E07F60 +:10831000D47B2A02F3DB1F930C54FF585DB6F5465D +:108320001BDE23F42B9467201D516C30EF0668137D +:108330000FE3DD5F7DA46504EB1D1FA2F3CD3A3C86 +:108340008D729843FCA07ABFA529443F28C957F3F2 +:108350003426B00978CE573C71D6847AEE429B4CD5 +:108360007EF4EC2681F25302BB1CC9784E47EF1B0A +:10837000497E736F93A8FAAD1DE4B70E24B164BCB7 +:108380005F53D122905E2C7ABFADC77E4347C98927 +:1083900038CED0F1DD89C1FEB2C7EEFA4504F25104 +:1083A0006F9941F573331A4796156B0AECFF53AF7B +:1083B000C0F3274C9280F798ED0F8A11B8AE2E13B8 +:1083C000F75334033FC5FBB9CD538AFBA443D3F71E +:1083D000B0CE20BBA5212E3512E7EDC15F85FCEBA9 +:1083E000C75A32293EB2B9299BF24142C7B9771523 +:1083F0006B47FBA46195959EE7D5273B931DD0FF66 +:10840000D3D6298D20A4D8A7BB9626E0FDA0C52DE4 +:10841000161611068F8FB54EA4F916E33D669CB76C +:10842000A5C88C72645ADB1433C2EDDE55CAB3C1E1 +:10843000F31416BBD6205D46B53C4B7862637E379D +:10844000C2F3DFAE519251BF3896C6C2E6493E90A4 +:10845000CFED8477AE71D27D924F93C2B75B97CF49 +:10846000F335A3A7CBFCFEB891BDBB04E05C01F4DF +:10847000540FAF8E36654623DE9AD83262521F946F +:1084800095B8D19E3B8D7A3BF0F3C6BBE6AEAF828A +:10849000760D778FD88FECE30A33D79BD99F45A20F +:1084A0000BD00B2B903EFF638E55F204F15FD41F6F +:1084B000155D7E1A971BA626D16F067E6EDA79FCB3 +:1084C0006F68EF20DE2A41784CBF09AA5DA0E66BF9 +:1084D000244C206D9C7E0D33E6FAFC0CE32E8BAC15 +:1084E000789EA17AFA797872DE3A82C6473D37974C +:1084F000291141EB0096E0277FB98BCF7BAE9D5AC7 +:108500006F0406F34390FE1E5AAFED63E47A3DBD5F +:10851000BE93CFF542806F9FF1BACB7CFA7E9FE588 +:10852000333AB7D1A2B2FB38CAD97522E5558F5973 +:10853000C7E3FF678630F213F5369EC67FF1671CEE +:10854000A8C211E0DA18574CE7D95B3FB3EF80922D +:1085500032B6C73EBC2C41BF2EADDD67E7F6751BBA +:108560008BE4FA603BDA67161FF0BDB1F83CA0A0BF +:10857000FC1EB56985D4D7BE43F919FE6458EF6275 +:10858000F5C864C035E40F9FAE17543D84250C9F99 +:1085900040571749FE607F2588FF015FE1797B3EE8 +:1085A00081E0D3DC7A74F3BDE487B13B782B7E5E47 +:1085B00063992607791E90764F9061686A604F7CB8 +:1085C0004A83E3C9DFAE7EFA097875E2A9E55FE385 +:1085D000D332A0321AE1794FDC9C6B13A1DD58B382 +:1085E0002F01F9E9129FE53CBCB36AF89282F7F3D8 +:1085F000F4F59684A0F5C37FCD3B9E585F89726ADF +:1086000087D581A9E1885F6E1D7C02A9F85D9CAECB +:10861000BBFE95EEE7474AA716507E7B9D85EE751B +:1086200085C27789CA07987A5F43A3A78896910C79 +:10863000FD8B4754BBE9C85AB053A1DC586796F18B +:10864000BB065D8E222521CC78E63A33FF6E4EB014 +:108650009D98DAB34F6DFC2E37F74336C2F84218B7 +:108660007FDF85C6DB53A48C990EF8BFB7C879F9B4 +:10867000F42CCC6F5A44FBADDD5ED7F536B4B97738 +:10868000A02B03EB8FAC1D36414047A451A6FB7EC7 +:108690005EEF73244F5AF03B3E60CFB7B41B2350BC +:1086A000FF707B0D14BF6D698F8B1C8E72CA6608BC +:1086B0001B675D349DC3AB479E38A383F5A1E65C81 +:1086C000AE0F09CF94DD9F0AF0F21EE2798A9AFE7E +:1086D00021A97833C622117F96BC3CCFAD471FE25B +:1086E0007AF519D4AB515FCAAA9282E5534334FF9D +:1086F0000E4655AEC38DF730736C8CE4C750BCACDE +:10870000807E0B1BF34D4BC1EF643818E6E7F6078C +:10871000FD4706CC8E6FE3FA4EA4CDE650108F15C0 +:108720004E5756F81FC2337294C2701E63887E6122 +:108730000ED11FC490F282E97A7D42668E6884B3BE +:10874000FDBEBEF338347F2EE84D74CFCCCD00FE95 +:1087500088A756379D4F34181244CF8A22C70DEC94 +:10876000D1FBF13E1BF7AF48142F129446F2DB6F9A +:10877000CCE4FE8D44C6E35E83146ECF8F9DE4A6E9 +:1087800032D80F148762AFB248E4CBCB8A5CB723F0 +:108790007EA4001B40FBAF7F3A1388DC2F512F676C +:1087A000B5171757FACD6EEEFFF31A221D9BC3E0E3 +:1087B000FDAF0BB81F2E720FEC0DF5DBEBAD74BFE8 +:1087C000254F7CAA89F069BC81FCDA5E7640427E46 +:1087D000F2ABE95CDE1F2A72DE3F9DE2B2CE14846A +:1087E0007F82112C2A5076CDAA1F37E9F6D448D4BF +:1087F0008B3F4C7C91E0E106D8A5C17F9B6AE3FAF0 +:108800008F82F78FD6AE26B8CA03B89F4CBB771EAF +:108810002BF1FBFDCDCE536EBCDFBBA22095AFAFDD +:10882000C8382315CA43EB0202D2DD3D76651EEA45 +:10883000254DF273741E2919B201FD65838DEC4D2F +:10884000CB38C69E8EE1F5DAF7A31EB20FDC149C7E +:108850004F52ADEEFB2121BCBE725501DF67E70E22 +:1088600000643FB48F996A7FDB16933D7EAE0C7037 +:1088700043B8B8B9FDFCC274DB62F770B28B78BD47 +:10888000FB2ADE1EE3A5502FBDFD7E15DAE38FA681 +:10889000849FF74B75DE47DFEA7E04E358FF59CF2C +:1088A000E358BD9FB39F1980B76CB0B3647605F0F1 +:1088B000B9A5E679E1BE2373CD2CCE473A6DED0420 +:1088C0002F06F23CFA2ABA471FAAAF5A918E4E4B96 +:1088D0009BEB27CA9C8F644DA0ABFD1CF742C6BD25 +:1088E000B0DEEA4840FDD3B3B4BB01F98767D7D205 +:1088F0000FF15E7A799999F4D67263CDBFA31D64A6 +:10890000DCCBF35FF01B13880783801FE17DD36905 +:10891000D5FCFC164ADC5F2B3CF3B13307FDB18973 +:1089200046C24B4D8F1D6351DCE897DDA0E6B7339F +:1089300071483DDEF7320E16C9EF1B55077A2DEE52 +:108940002F97E7EB2AF03FE4439A9E6B4B37EAF20E +:108950007ACD2179BDC6903CE0AFA7AB79722A1FD2 +:10896000B2678DEF539F7A15EC605CE74EE043F8F9 +:10897000F4833D8CCFDD60AFE3F335B0D7D10FFE8C +:10898000C6AA51F47C739583DEBFBD6A123DAF4B1E +:108990000E98109FC91FCDBF33E717C8AFA7E19945 +:1089A00098966DC3EF76F0FA21331BFFD57D35D451 +:1089B000C7A9EDDDAEC5F49D3AADCCD62ECE4E277F +:1089C0003F38959B67342F46BFCFE652C53A03F038 +:1089D0006480C15981DF7960775A286E11BA9F0788 +:1089E0006768723CBC1DCFF013067A3FCEC0197D7C +:1089F000F8711E12F83AAEDAFBFE16A48F7E4546D9 +:108A000027E27172AA3E7EB07206D7F35E579FC905 +:108A10006FBB86F6755F5FA38FDEEA3D3B0005FA0C +:108A2000F55EEFB5B36BB1DE13139EAE06AA74D537 +:108A3000EBF8366E4FB219406F83B11C6A1F0628DF +:108A4000BFE4746D8E9FC8ED27D35B7712D25B575E +:108A50008CAF1EEDC4AE5D4BD7E3774244A4372400 +:108A60000BA4378C7F68F456CBCF6321D21BFC3923 +:108A7000ADEE3D670ED26302A72FE1999DCB291F72 +:108A8000E32E9E47A3D15B8C9A2F1F25B593BD483B +:108A90001FE6C07E407B1B04BCC773FC634AFE100C +:108AA0000B1CAE7074F723E9AD6CC64FA3B77FBB48 +:108AB0002640F9139D294A02EA335EF5FB813F9671 +:108AC0000ECFCC3073B970B92F11C7D9A08E336DCA +:108AD000C861F2FF15581D22CAB37C99C3356F7C5B +:108AE000267D6FC8A7F6DBED5456CC80E780B9270A +:108AF000C9CF3BC0C0E9F7C1B7CD8B11EF931A0EB8 +:108B0000164D437CB943247D3B745F1F14AA713317 +:108B100081CF0B9A5762701CF11E952EE53B3A38B7 +:108B20009F8F61521AAC27C12D15E7635CE86A0379 +:108B30007D4FA45FD1C11894CFDA78707009986F17 +:108B400082AAAF75DCF9F408BF76D3401D3DB7E0CB +:108B50003E7AA3E70BF10FFB0C41E31394EFEB52CA +:108B6000EF49FE58BF6DAF7EC4CBC3FB25AB66712A +:108B7000BEE131F1FC0F682DE177019A8A5C4FE28A +:108B80007ECED3FF764A7E17EE637934F995138C47 +:108B90005CDFC36F24F2EFE5B809CE5AFC4DD31762 +:108BA0006585E7172517BBFE80E36E62F22E94679A +:108BB00036079B47F13590678817CB8A9417675023 +:108BC000FCE5D2F4C02F8B9457895FF7824F03AE38 +:108BD0005776F7856F538AFE63CF0F48FF65DC5FDA +:108BE000BAB0AC8672B306819D84EB9DAAE6677825 +:108BF00086F07ACDBFEA1DA0C54F9542CC9F8C561A +:108C0000E135C6E26415D0BF0BE530DEDFDB1BF0DB +:108C1000E3BD600BDE2393D08FCAA87F4CADE093F9 +:108C2000B1BFF8E5EB182F32E5D0E744189BC4ED4F +:108C300001EDFE8D94FBE3FC8D87353E318E8D4733 +:108C4000F8241BE40726C3FBCC87F33AF078B21E66 +:108C5000591C8BE272E2A68612FCDED6D2AD9F6E64 +:108C6000427FE8E47FB7303C0FD01FFDC6B0F95C0F +:108C7000FF303942743570563CD71353C2E3E9E3F1 +:108C8000B354FD13F1344E87A76C66783C25FDE79D +:108C900027E069E44C3D9E1684E06914CD7BE978B9 +:108CA0001A3B13F0F4559083B8AF17E72A0366F622 +:108CB0008197DF952A897DD507C507C8EE1BC12698 +:108CC0005983BF7BA83D5B515EF6919FD07FCD114C +:108CD000CA8FF3D49EA63CE52EDB917D6807FD4745 +:108CE000AD450EF66781FEAED3D75B40AEB8C19EF0 +:108CF000DC304B247EB2E70E8BFF3AD46BEBF87D71 +:108D000084F2BA4D02E67B0FAAAE115CC0DFE21519 +:108D1000301DA17F8C62E8F19FC07F57980E903E76 +:108D2000BB0EE4B19BD817BF97A6C9FF31969AB77F +:108D3000D04EF5FCCDE8588DE7CCA45DC88FA603D6 +:108D40003D617CF39A6E906F41E3BDB56312F9D536 +:108D5000AEFB1EE45F901F670A8C185CCEB126EA5A +:108D6000FAE54929BAFA690997E9EA35BAEF8C5167 +:108D7000E32A595B72117FC40A9EA7305DCED0B53D +:108D80005F57964DDF03B86232BF7F3773D464DD1F +:108D9000F8A17AC1D5F03FA47731440F08D513422A +:108DA000F5828533F5F740D71803D9C49F18CFABA8 +:108DB0001B7AF6DF880ED6C91CCFBD65A7281FC356 +:108DC00003F63FFA9B0607E597225D8C3507C83FFF +:108DD000B761BE95CE63C38E27E8BB119AFF0BE83F +:108DE00086E8686CB64479AEE9F65F537FB694CBFB +:108DF000D950BA14EA5E22FD6FE36CD81B7E6F6D0A +:108E0000760A977B3B03E48760779A19CA4DAF6473 +:108E1000A0BCB1DF08FE086118D2AF42F28925304C +:108E2000C94BF992EFF1EF2932E6589388A6BF4279 +:108E3000798D80F6DD6FA979B488B711F9CCB17A54 +:108E4000327EEF97D377FFF1FC7C6C0E5E96AEE638 +:108E500065CDDE8E49602D98173B18C783B671B576 +:108E60004CF2905FC34FF543F2D9010FCDCFFBC752 +:108E70005731671394C51A45F537BBD4F87A37C50F +:108E8000BD53054724FA3786894E8A7B473389E2EA +:108E9000E283580D3DA3043F671E97C847AE00000C +:108EA000A0BC603799E9FB19D94FDA187DDF68A9B2 +:108EB0007933E5650564F223DE7388DFC3DB60FF89 +:108EC00005C5099AF6F1FB04F724B93FC478E6A07A +:108ED0003A81BE132E56F33882F8A6E89806F5625A +:108EE0005D2B7D072EBEDA407EAD2BCC35BBE81C5A +:108EF000EEB6D0F7E3BAA03FFAB9D6D90D8CE81593 +:108F000098C7397F2AFCBAAE7152DCA2EB6FFD48DC +:108F1000DEB1103FA7C7C5F56F4F9C99E397EDD41D +:108F200027C8B71BE322E97EDCBC6B6BF6211FD997 +:108F3000F09EE858ADFA9FD1FF3F14FFC0FC03B389 +:108F40003305F54E7375783FA59939F767A1BFF4DE +:108F5000AE25097DE951BDC6456C06BF39FAE2E38D +:108F6000220DE53C0EA2AD53DB67A36DB95029E39A +:108F70005F3F312E52D64B5C24502320BF1F8AF511 +:108F800063113EDC6F7DA971919AC24B8B8B68FB9C +:108F90009EA5FE5D0088ADE677505C80CECDD0B357 +:108FA000BE20386EC1F595E35F327F8F7186D96A36 +:108FB00079DF5307BF44BFFEDEDFEE7E0A9FD79DF9 +:108FC0007DAC6C39E045D1243BF97BF7FF32E641BB +:108FD0003E9C3E7E30CB61D1F9EFF187F849EB1032 +:108FE000F8BDFCE0FAA29075651BF5F1805C9BBEB4 +:108FF000FDD4387D7DFE107DD9CC6A084F43F7BB88 +:109000003AEA6ECA936BBC8D39788678D079881726 +:109010002E9B8798C3EE4BC337E64821BA5FF73ED5 +:10902000A77BE72B2BDE5A4976AC81EECF9F9ED7EC +:1090300070CF3B32E28799B9699C7C05F1E8BBDFD0 +:10904000A7BF4B311DC9E5BE11DA57E6F0EF459DCC +:10905000174F50FDF9436B77B5E706C57BEF1DE869 +:10906000721400DE0CB59D12500F195AFB1AD5CFA1 +:109070009D9FD5271EA5D5EE69CF0DFAAE5F9AD17B +:1090800069403F465AED1BF4BE37BDC720BB79FE91 +:109090005E9959267B4BCD534B53F126AD8CFB5B30 +:1090A000A5542E6F3698B87C7343B57815FC5F5B7A +:1090B00068BE1BE7EB6726F17B1D0CB810F22B6D29 +:1090C000BC5079A6C9019BC2F5C8B4B287B85CD1BF +:1090D000F205DB42F3E25C73113E427523B5DB9887 +:1090E000A3B6DBC9F5533683492897619F61F344E2 +:1090F00017A87EDADEF2D398663FCE79F343CCCF61 +:10910000FBD1F6632FE35E971C087BDFF636D56E46 +:10911000ED8C082439B81F38ACFE3EA374EAAD05C7 +:109120007DE8AF98578B30EDD55EB8C4BCDA8D6A58 +:10913000BC488B976AF9B5CCE81B87DFF91C65FB47 +:10914000F30D1407ED25AFF61EBB2380F7DCBD152C +:10915000118ECDECD2FDEB5BA7737E5A5DC0E81992 +:109160001A5F085DF78602DEFE5091F3E1823EE26F +:109170000A5AFB0F13C3FBE3BE2DE4FB3F775F29C5 +:109180009FEB7D8A4961E1F240B57CF7D0F7600F33 +:109190003D89EBD0CAAEFA34F2DB794C1C6FDD327C +:1091A000FF9EA0A63FDA507F243DAA85EAA3ABB973 +:1091B0003EA9E959921AD708A527A08F3FE23C8221 +:1091C0008DD3ADA6279EA38FB9401F409743188F1C +:1091D0002B19D4BCD121569E827EA97AD4F9F6D31C +:1091E000F7F64BB29FEAB74690FD54BDF92DD4ABCC +:1091F000D6D5723F61A7BDE62DFCFE81FB3D91F403 +:10920000A6DEFA6B76D447857A3B0AE38A888FF12B +:10921000369F205F8E7654C0E482F595A31D65C30A +:10922000BC555700E1166A4F75DDFD05E5BB82BDF3 +:1092300079B820EB1FC01F42FC4B8DD3393EEF1A8B +:109240007E8AFC26622DB7F7C45A1E0F3596F1B8F8 +:109250008551E17E1433C82374056A7E940D0EBDDA +:109260001FA52B89FB51E2736BFCA8079A26592492 +:1092700085E423F7AB6879ED632CBEB7F03E862713 +:10928000C3C8300F1D1455B2032D6A7C03FF410B78 +:1092900094579ADF24346FDA16E22709F5A358674A +:1092A000E9FD268F0AF2BD93619EE7D7E7BD83688B +:1092B000FB878D8BA3D06FF292AF61A6EA37791846 +:1092C000D7B3E343EE37E9DAC1ED22172A305785E9 +:1092D000C3BFF3E254E407B966DFE12AF483687E92 +:1092E000A8F86A151E6ADC07E18BF014F3393C63B9 +:1092F00042E0E91DA2C58554780EE0F02D2F709252 +:10930000DF4942784A3DF0D4FC54DEBDEDF47D6D7A +:10931000CB1D16D94DF0FC92EC5513C213E1FF138F +:10932000FD50E342E039EEE1CC07F03BC1E31F29F9 +:10933000E9C0E7844DB7C5DE00CF495B1F28C127D0 +:109340007B93C709FE7316E75798D91D4C8F636747 +:10935000C8BA3883064F0D0F7BFC778CFCB1E51241 +:10936000F7E797AB789886700BF6E739F470DBA0D7 +:10937000E64B1A736BDC68EF0E0D819B86871E84AB +:109380001BF2BB18B3EC26FF5D9D80F6506F78385A +:10939000B4EDC7E1E1FC59AA3DAFC2EDB9F599F7CB +:1093A00022BC5ED858F20E3E5FF4DD1685F0DABEC0 +:1093B000E58199BDC02D3198CFEF991E1E6E5B8B54 +:1093C0005DD5B3E0FD750E9F91F82CE01BDABD9BD7 +:1093D0009BC659F5F1198D3FE65BC3C98F0BFB970F +:1093E00096535EA1A76C39F1C7AE73FCB1DB8E79E1 +:1093F0008817CB1F2D85FCBE7D79ED77AF5F077099 +:10940000CDA93D4CF46704FAA373AB3B6C50F33128 +:109410005804C88BF832E6C7F8F12066F545099480 +:109420009F407CD38B79CEF881D2503F85F4C65FC4 +:1094300005220E261812808F63EED4152407EF9FA5 +:109440001586CFAE2B3390FF67B3EA1F944B9D2D4B +:10945000D84E8B6F2D2B525A67FD347FE1C3D85FF6 +:10946000F31776C6B073FE35FC3E784EED2601F359 +:109470005006D5DD4AF221BE4C61281FB266CAFCF7 +:109480007BB3B912EDF77C7F5B770EDA099D78A389 +:109490003D83F0E077384F67EDE38407572CE5FE16 +:1094A00091CEDAD3B1E1F1A036E2D2FC8C9B757299 +:1094B000D25BCBBF63D26957DE4CFB11783042C51B +:1094C000034D4EA2BC417C3296051E463FF620C09D +:1094D00087881494979C1F8BA0FF44C17EC45EFCB8 +:1094E0008F1A3D74C1DA2CFDF09E70683E400DADC0 +:1094F000FB7459B67F621FEBBBE83C00352EE95187 +:10950000E3920B6B79FE6AE71DDFE5E17A4F978105 +:109510007D0070D95CE660787ED340B10AD882E7DE +:10952000392F6F358074ACC521B578FED662E7114E +:109530003CD7EB00A712FA635EAF1AEF19A27E07C1 +:109540003A04FF01CF3FC77130DE837240F3A3338B +:10955000D41BED88DFCA17583FD65C9328117EBB19 +:10956000BA71FC753BEEA4FC851EFF20CF87FBC9BA +:10957000FEAD6833E5576AFE2DAF9DFBB72A5880D4 +:10958000FE9D3C8A2320DF6EB5D0F71AAA04D98C41 +:10959000EFF717BB8C85A4F738291FD635C72A915A +:1095A0001F6CE9B644E417E58D22C9EBDEEC92F3BB +:1095B000E9EC47F21995EE2E81CF0C2EBC383E9384 +:1095C00054A8E733C9853F217EB67E969EBFA0DEB4 +:1095D000590FF3E4A8F4746EDF6A1C1FE3571119E6 +:1095E00041FAA8BADF503A3A4F2FFDBF8FAE66223C +:1095F0009CC3D0D5ACC21F4757A58503FAA4ABB90D +:10960000857ABAFA1996FF17D2D5CF691F17A02B02 +:109610006321D3E749C7F2EF3C8F8935F03CCBFF9C +:10962000C379D25FCDE4FE8BD03C69C66AA85C00EA +:109630006743E7A3960BC73319E34C964DAFAD1DB7 +:109640002DF3F182FD9D2CC4CFC942FC9AA1FA5D95 +:10965000183FA8CEEFB9F789BFEC1D0D7F3EF9F496 +:109660007F915EBB6FAA40F7C90B477EB71375D0D9 +:10967000A23595EA3C7DFB3DFFD97E4EFC05FB55AE +:1096800043F7D51875B77A6FE0C7F93999E356FAF9 +:10969000BEF9BA1AE640B85FC8EFB9AE8EE74D6BB7 +:1096A00079CDCE57AA1E2C1DCFF3E9D0EF19EAEFE2 +:1096B000D4F2953DB64AD2F38F2856EE8F0DF1774E +:1096C00056C6CAB7D03DC6F3FD9DEF16FE03FC9DFE +:1096D000930A64FE5DC610BF677CBEF261611F7EA7 +:1096E000B3CE1807437E9763F30918AF656733C994 +:1096F000AF33C816A0EF6B95D74E213DF06491EBC8 +:10970000535CA731B7FBAB97C653BE8103870AE50D +:10971000CBA0671E2FFC27FA09FE597E3E5F01F79A +:10972000735DECFD791FC23BAB8F7BF472E0912837 +:1097300078FF68BD9DBEAFB552D5A33B4DDD492D29 +:1097400050BFFFAE13BBD13FE16B3330BCDF76B10E +:10975000FEA3860BE8C5E610FB68C339BDD8F7D673 +:10976000C420BDB86155FE8E6361C6D1F4E29B662C +:10977000EBF5E2721BD78BCB6DDD26B40FCAE3BECF +:109780007F1DF34E8DD5AC1DE5E220A586F4E17872 +:1097900089513EF1FF8FCBB37F685CBE78B63E2E19 +:1097A0003F56CD47411E8FDFFFE9D2FCA893B8DEBC +:1097B000B0C6C8ED15AF02EFC2C4D143E3F243CF48 +:1097C0003E4371F975DBAD748F6FC38E663EDE1458 +:1097D00026619E792253F5B502EE2F0DD53F1E3539 +:1097E00029D694F188EF06BA4F88F704C92FB2DD65 +:1097F000BA09FD4DE9769ECF6DDEFFF256B73148CE +:109800003F043D94F4E2B2007D97A95C7230E23BE4 +:109810007193FC141FAF1308BF46CCE6F4B330D7E6 +:1098200047FAE1A03249E0F7C4DCDC8E4FE671E78D +:1098300048C42F682A8EE2715FE980E8C0B8F37DE2 +:10984000D87432DE5F65FC7B15930DF4EF50AC13DA +:10985000BA13902FB70A4A223E4167A27B8F4FC7A7 +:109860002803F1DF93F22419E8DF93DA93D7988085 +:10987000EB6BAA6F4D40BD70CD6C1E4769CD3B4E62 +:10988000F90FA674D00753E819F6DF1D9DEB14D429 +:10989000BCC0F604FA1E026BF990F06A9499F17F4D +:1098A000E7C7E15F84F474CC46FAC2AF041FBF2758 +:1098B00064B7D27DBC96CBCC8955B09E66BB99B4BB +:1098C00009EF65530FA4C0FBE6015234C601BC2961 +:1098D000A912FA8FBC318D6FA21FA439259561BEE4 +:1098E0007F53D9048A9F379D0506033D3DA347EC6E +:1098F000CF82F76B84007D37C83DD9C0309FB0ED73 +:10990000B2A989C1F7324529544E3A482E88B2810E +:10991000EEF9896A3C5B3C2F9EAD8F4F7F3F9BEFFA +:109920005B662DF3E81E689C59C2FD965F56FC21CC +:10993000DD738B33535E50B989F1EF7E5CC6E85C12 +:1099400042E1E759A58F2B186DFAF5ADC1C034E59A +:10995000619F5D82F8D18030A53CEEAF96205F6AB2 +:1099600038577F92D747F0F2CED94797A01C941969 +:10997000FFF7491A46F1BCCBF201C5C487CB4D8134 +:10998000B0DFF9BDD07A64E653D4F1D8FFE4786B48 +:109990002E33CFF3A55F78BC9E7301F5F912C6D5BF +:1099A000DA858E1BDAEF7FAA7D6FFBFC68F6B9FBC8 +:1099B000719407412AA27A9F0DF564A3CA0F3DD97D +:1099C000137C7E19F9819BD3458C419767FBDFA6F9 +:1099D000F2D6B800800000001F8B080000000000D5 +:1099E000000BCD3B0D545CD599DF9BF7E6CD10669F +:1099F000E00D0CC910093E082831045F1288A04907 +:109A000079046240A94EF809B825E944A346DBB3BE +:109A10009DBAD6923DD932094320989009A9256E66 +:109A20006D8BA9D9B5B547A9DBEDAA47BB9398F5CE +:109A3000F81FDA5AAB7B3C16539BDDF6B83DF42792 +:109A4000969ED336FB7DDF7D0F6626432069F69C0C +:109A50009D1C72E7BE77EF77EFFDFE7FEE9C3B87A4 +:109A60009F5A8073562B6B2A9865C09F73607DD672 +:109A7000E0736AF93FD0FD0B0114FAE6C047DD4DF3 +:109A8000F1A24AF1BC25404370BE1B4003889F935E +:109A9000F0A9050F5FBD74AE182014C4877902AC1D +:109AA000B67006EE4FBB56C7EFF4039C4538B9C6F7 +:109AB0000C1CDE47113040B0C763FF5A35FCEE9DE9 +:109AC000B4EE35601CD367C62BD6BA571F51216E32 +:109AD000CFC7BFCF5AEBFEB4AB353BE499396F6AC1 +:109AE000BB6C3479DE8774065C27E283D163F83D72 +:109AF000FA6E4CE24D3C837FB8DFE84A6D74109FEC +:109B00003F688FF3E2B822315FC7FD66C0CC47598A +:109B1000C878B05E428903E7EFBBBAE2519AFFF022 +:109B2000E3C3DFFA363E3EF29D3DBFA4764149C510 +:109B30005035C2CB341C86403B044A900E4EFA8608 +:109B400078F47CEAC814A21FFBC978DA5B7E678CC4 +:109B5000C99748471C7FC77EC9D4703D97C77354C7 +:109B6000A6FDB92593F62B1F5EC4FB0F6C4FA6FB19 +:109B70008864BE1DC0F19103121CC37E8691B00E95 +:109B8000FEA905C9E39B09BF55D44B18871B3F2885 +:109B900041E7581A7C3F1874303D886E9184FD1F50 +:109BA00072EAB7105E0FED932182200FED74012C45 +:109BB00006F846F0DFEFDE5D02F0853E27E37D64C8 +:109BC0009D3A2AE1FB11AFB6B993FA4B1CC6511D61 +:109BD0000463E2B90EAEB88ACF65AF3778ABCEEB8F +:109BE000C5D6A9F9E0A1719381A097F9E88D2AE281 +:109BF000A3B765E6A3D4FDA7F2DD5C7C5618CCB113 +:109C0000F0300AC115C89EB279E20CEE0FAE763084 +:109C1000FF2CBFDAC1FB3B5B8003A4D9F9B0AF07CF +:109C200017B87A866F548BEE7BFD2DA708FC6CF37A +:109C3000D4D171B3A882D685F05839F27320797FD8 +:109C4000F6B8926979F83B5850C9723726E3595DE6 +:109C5000A371132AA81D37256CCB1EBD5FBB90BC1A +:109C6000B820017E11C1053E7FAAFC3A21C448DC20 +:109C70009359781B9DBF6FA30AB29406DF73F40F4C +:109C8000EDBCDB24FA473E0F4629EA096720992FED +:109C9000832F9430FFC80332B8A444FE6A34895E2F +:109CA0005FBAD539AD7FDCB61E23BA1B45E0C07D57 +:109CB0001D7E4B66BE391CDCFB0B99E4BB51D525E0 +:109CC000DC7F46ECEE87DAF1FDA1D765631087777C +:109CD0003FB3EB67AF627BBABA788D544C44322302 +:109CE000DB71FCE9F56E63D010F2378D97626E4C34 +:109CF000F79A99F50E5517F37A515C4FBA001F2861 +:109D00008DEA0744875478D3FABAFBF858C3EA04BB +:109D1000B95A187A2188E71BF2E0263CF4FE24BFEA +:109D2000874AE4CBFCD9D7418C325E7E465F71DC3A +:109D30005F5ACD9304A7A9B42A9249E7826C207C8C +:109D40007CE8356EF4E190F79D86DB289F99DF1B58 +:109D50007342BC9CF080EB62DB0C135B5A88EF4BC8 +:109D60009CAC3F64FF4A7EBEDD1B541CB8AFFF0CA9 +:109D700016F37AF6FC26F8B2721FBEBFD639DA4067 +:109D8000FC11DD0E5A04A76CF3C614EA6FA00DE2B5 +:109D9000C21BF53A7711C26D7C9E1602A8F50DFB29 +:109DA000C90E553C77A42044EB47CC1F95219E7DDE +:109DB0000255B0DC351EACC7F9BD6FC8C61E7EA209 +:109DC0001D0FE17C252003D1497A6A6D6002F7A35B +:109DD00078CEBC075900EB26011A12F8A976CA0DF5 +:109DE0000D097AAE0E2127F6EBDDF949E337684518 +:109DF00049EF65308D38D277636059D2386F55A5F9 +:109E000046FB6DD257263DBFB9AC26693E3428A724 +:109E100027B0BF16FF11DD65107D5BAE3CE5D84F66 +:109E200098AF40421FDFFF25E8F59FC9C4CE75708B +:109E30001DC94F33189D241F68BC8D63889785CF3B +:109E4000B92732C9909826DB75C9E2CFAA4D454C97 +:109E50001FC973C641F87F0461C8C81715DA848327 +:109E6000E804DA98C4CF516F0C22B2038AC9E3D058 +:109E7000C069511C77056A6F0DFBDE00C4A8BF04E2 +:109E8000623C1E3FB1C335C8166E313FAB058C83B3 +:109E9000F83EB33C2249D8CF69044346781E635C40 +:109EA000A27D6A385F5E492C19E77E41238CF73228 +:109EB0007C730FCDCFEF06AD2F9FF997DF8F7641E3 +:109EC00084F6F32818E092091FA890969216097359 +:109ED0007B25E839A487BE09C62AEA97C204EB2588 +:109EE00034EF12F517C19826947D9CF5374C28BEA7 +:109EF000336EA1FFD3C9CD8CFC2870C6A60B0EBE55 +:109F0000FF56B37C13EAC1CDB7555DD0DF50BA5FC1 +:109F10004C92DFBB37E98C77A57B23CB8BD2FD122C +:109F2000BF1FD814BC6E133E2755E05E75F1F8AF25 +:109F300050053EA31218E8CB40F4D99B02DBC85F62 +:109F400079D66D94B2C8233E892FAADD93AFD48809 +:109F5000F9440F3FD283F09D530E12E16009D10105 +:109F60009FAB48877D4CC718C32D0C83B1DB5A9734 +:109F7000FAF94807A2CB28680B08AF72F8E2E8C0EC +:109F80001F84B3E81937FB470AD165E965A1CBA760 +:109F9000098F174B97547AC0AE5C809AB9F5E95790 +:109FA000A57886B494C882F4C1F348481FC26700FC +:109FB000043DD0AE1B84A774F8A77E4625E87BB885 +:109FC0002FC6133D233533FC9F8DFC2FFA42BE7CF8 +:109FD0004807D11774F293BC603F101CE3F939DBDA +:109FE0002178209FE86132F26CBBEC8249F66B8BE2 +:109FF0002583E9B55446070DFB9952DC727E46D99C +:10A00000AE6781C6F4590C616EFDCEC9E3E7485FC7 +:10A010007B1CA391226A9FAEA3757A9B51C390CA01 +:10A02000F70ED7315FDE035A29F25DA16AB2FE2E28 +:10A03000BC4631227A22BEF608BF49378F90BD292F +:10A04000747861B07266DDA8D308C4905EA7BC675F +:10A050004E84F0F9827CB4EFC60C9E4F3BC5F908E4 +:10A06000A67C05C983908F4035EEC577BE7E0B2850 +:10A07000826F3D3B107F888FADF402F1240DFC1BF5 +:10A080003F7FA45EE8BBCF6E0A3D4EFC42FA89F1E9 +:10A09000678246FA493380F5A6438FB09F7076C039 +:10A0A000A5139F426CC424BF629BB5CEB601D707EF +:10A0B0005256C239A3AE243BEED083D9CCCF86040E +:10A0C000E41FCC77DEA5F23F74E7CDCB0FA87B6A07 +:10A0D0006DF644F9ECE354928FDCC479824EAA3FCA +:10A0E000C47E874A72923B371C678AFF62C371063F +:10A0F000820CC769FB2F64B7909E77A1DD1A447C60 +:10A100007FDA448788F972F23FC89EDF1ECE62BFB5 +:10A110008B5184E3EE8849A383C88F774258253E4C +:10A1200095A02442F4DB1A91D87F2BDEB73D8BFD3E +:10A130000568D0083F52FC06F9DCF28BC0A385A766 +:10A14000ADF15F3A752FE1D50B3F4F88B7ECF7BF04 +:10A15000EB5A7AAA4A27A5ED2923FA665AF445B59F +:10A160001D790DF7E9FC53360C6AE4177FE98D5A27 +:10A17000DC5FDF8F6583E2B34C10F1D50210763CD3 +:10A1800093E47429F1CB58FC33C46FDDD91A9DD701 +:10A190001E07D6B80884D83FCE443D40701D99FBB9 +:10A1A000993F33B354DDF6B721F11C6E89FD608F02 +:10A1B000A572F3D4789CE42B0FFDD8DDC9F02511EE +:10A1C000CF03C7437C0EE9FCF55758FE3ABEAA3BC5 +:10A1D000370FFF3ED57F87C47890C663DC194FC028 +:10A1E000EBB4BC587266EFDBE35193E525659E4DF9 +:10A1F0008F72A7E08FC5187FEDC6FD0E0C1CAD2336 +:10A200007D3392073A469AD0BFF59F248AB3D693FE +:10A210002E26FBD300A3144778401F2CC3BEB3C027 +:10A22000C3FCB3E8BF83F1CF209CBBAB5D9A8E38F3 +:10A2300059FC91A9D5E1FBBB0ADC8689F48D5AE370 +:10A24000230DE86789E5DF26BFF44E6BBF4C0B9406 +:10A2500043B3A588F95DF1B5ED7D8DE2DEC532C869 +:10A26000A4D7E42E83ECD39D1830E4A2EB0E5F76E6 +:10A27000B2DF87FE1D9FC7D590ECF7DDF58833A9C7 +:10A28000EF4CF1136B5B92FDC0A616E075693FB908 +:10A29000ABFE7AF8E0F1B3FE5CA18C3BB43476D52A +:10A2A000C6BFF49487F1FF421EE295F32441F37395 +:10A2B000D877211E895F11235955882793BEEAE478 +:10A2C000277FEF3E1AEF3A8BFC4BE3654FC3E788DD +:10A2D0000E57587802B12F13FFD1BE53FD61578A34 +:10A2E0003F9CBA6F9B0E77D8F859036B083FE89FE5 +:10A2F000B37F609F2BF53CCF637CDE80BCF4831E74 +:10A3000037B7F11E8DDB133D016E4FF6E8D0808E1E +:10A31000D54B3D65DCBEDC63F0F3577BAAB9B5F1E4 +:10A32000319BBEF1E639D85F38B4CBC17902A55C68 +:10A330007BE56AE2DBB764561F1AE819CA52B643D6 +:10A34000A0E0B82B1B955193CE62C53F8B2C3E5B92 +:10A35000EE9A3CEEC279B17C30F6D044B4DBDB2B14 +:10A3600067E29F75938E1939018A771624E50BEA07 +:10A370002037A95FEFBE2269FC066D69D27B9BBEC8 +:10A38000DFA81372B331B03C69FCA186F5F1BBC9FB +:10A39000AFAF7169946F68D25727BDBFB9EC8624FF +:10A3A0007820371BA4A773BA12E8C6E74FA6ABBA4A +:10A3B000E3C271904DE7D11439988DBEA97C6BE34F +:10A3C00035671AAF22AE8C525CA9D3B9CBA56D0804 +:10A3D0006A68DA2F3181F24BF6BA4A35C69715977B +:10A3E0003FBECCA2F8B2285D7CF921E76DE68C2F48 +:10A3F0001B93E3CBAC14BCCD155FBE7A89F8DC5A55 +:10A4000028F26E39AFCBEC07CA8D61B67FB9E3B2E3 +:10A41000B191424FCB1FF392CCE3B8AD552AFB97D5 +:10A420008760220022AF984FF630B7DCC8277DF353 +:10A43000A4CF5C781BC5F94D0EE3284E79B1EE2B05 +:10A4400001F23BF6ED7E34804609FEA7C5C1FA2E27 +:10A450005677660BC995A2A31F27716B8EA6F14F85 +:10A46000ECF176BEF1E016916F3C68E51B0F5AEBFC +:10A470002042D8DE8E54897CE3AF5B742BFF17E15A +:10A48000FCE2E12D6BAC7C23F657D07083EDF8A095 +:10A49000D730EF20FEF9850722F8E880A4654964EB +:10A4A0002FB63834CA1F8F34AE7A97F249FB3CAAD4 +:10A4B00041021FF5ADC927FE92B7A2DB83FDE1C6BD +:10A4C000E19769BE52EAE07E74CB559C171CC9D354 +:10A4D0009A8A29CEDB504C9806F9993FF5505E23B5 +:10A4E000EA3B13A0F9BDD78BF9B3D12735FF2F93E2 +:10A4F00026A6F8ADC41157118EFCFC993F13BCF38E +:10A50000F2F3297EC5A04FE5BC6DFE8FF77E2B527E +:10A5100042AADCE47CF308CA3CE169EB96966C8ABB +:10A52000A7B63A27F2D2D90B3BFF39ED6FFA93FD6C +:10A530008454F8FCB1F36B0ED1D5EDBC2D7EA2B7DF +:10A54000DC381A27BC41ACB198E25E8FB0CBB3E1E6 +:10A5500041F15CB80E22776798190978B0EB1DD7E6 +:10A56000B68A3CB8D1AADB79C6A47A89D2E8E07968 +:10A57000B67EB0F3E3A975127B1F35AD224F7BFD8C +:10A580000CBCA4BA89BC56B5E0191C17A7E6B3E702 +:10A59000AAA3CC95CF6EB6CE73B175937B5B81E7E2 +:10A5A000FD7FCD7FDFDBFA7F93FF3EBF5E34CAF2D3 +:10A5B00003CF4CFE9CE43BBA6CA13E28EA4349F52C +:10A5C0009CD43ACE60868033BC52F8A9C3563FB2C1 +:10A5D00042C04DADEF6458799548EB521187812107 +:10A5E00088AC9885C4171EE5BB110DF96181E71091 +:10A5F000F8B075F9B745A8AD2DD487AA715FC3CB64 +:10A600001C6CC786BDA147FB480F2DF3A4958F8313 +:10A61000AD422F0E10DF72FC04A683E44EB2850417 +:10A62000420EA4D708733EC0D1569FC86769B1EAED +:10A63000DB118F5F25BEC8E3F3F0FC54F85F3B1FCE +:10A64000FE63C4AF510B38C1D98670BED93A5D479D +:10A650008CD07BB7B59E5B8F5593BFF058AB26F47B +:10A66000B0B2D2A0F30FFBD2AFF798B59EE9084B7A +:10A67000346E5197980F6E31EFA034D9795AD09338 +:10A68000E589D6A7F79946B27E48859B5176E17A4F +:10A69000D9D3D3FB4F8E870E48E9F7F9634B0E6B86 +:10A6A0000B81ED11F1C59E347C912AEF2AE53F1113 +:10A6B000EE098B0EB6DEF128E3EB332BC9BE83D156 +:10A6C000CB883DCEE7DD93790BC7C97D378B3C87BF +:10A6D000AA08BD5DD089606AA8BED210E1BAE1FDCA +:10A6E000A0B97CE7E3E162E33DB2379184F93FB181 +:10A6F000F823B52E18A3BA20F9B15417A4FE4E576B +:10A70000673ABBFD6E8BD3B2BFE9EB3B47A8BE8374 +:10A71000F38F545BF59DA0A8EFD43DF508ECC4F78A +:10A72000BF331DECB74ED7771A8AD7480E9623A0B1 +:10A73000FAF47CEB3BB18679D67782175DDFF9635B +:10A740002BE2E79047D459A6EB3B6DFE79E5757493 +:10A7500088C5BB49AF7401E3C1DB340C3B299F10B2 +:10A760001071C6892A97E0AF9D92159F4103D87A50 +:10A770000A3FCD5DFAC3B9645FDE714129BE5FFF58 +:10A78000C4EB0AF587F31D6B287EBE569D78F05A00 +:10A790007ABFC6C9FAA30E29194FE28FB8CBC145BB +:10A7A000F0886AB5B268E312B5F5EECC247DBD4100 +:10A7B0004B8E3F86A64EC8D9C49F1A1812E279A8BC +:10A7C000CE30B349F71813BDF47C68836E0CEAE40D +:10A7D0000F27C729434DAAD0A745C2EE0C1FD71F8C +:10A7E00026FFAABF3B83FDCF03050E71EE1218258D +:10A7F0007E68D293E39AE1B1E27D2524673127E7B1 +:10A80000CBBF3326C66FDFBD7294E252CDF257B78D +:10A81000E7AF673F14FAC4B89BCB96A79C7F5C2335 +:10A82000BE88ED7402E1BFBFE0F601CA877E1075F5 +:10A83000AE2671196AD3997F6DBA6DEBBB93EB4469 +:10A840007D2A70DD74688BCAFC3F94F7C1913B4848 +:10A850004FE72D603C8F6C51F34309F270A2CDC5D8 +:10A86000F41ED922FC8B3C0784C6D2BC3FD126F40F +:10A87000D027EF013E4F16DA651D1FE94A38EE2258 +:10A880007C1400FC231D27F0E1437CFE460794E284 +:10A890001687FD5DECBFA5F2D9785B69525CEBAA27 +:10A8A0007624E1D1E90A8639CF7D33E8A4AF1A1ABC +:10A8B000B14FF17D970AC46FAEC0FD7CCE1CEC6732 +:10A8C00060DFDD188B28D87797845693DFFAE2CEC5 +:10A8D0008E01CAB3B8FC0E8DF8CDD57557B095C6AC +:10A8E000573A2103DFF7812E05689F1109485FEB76 +:10A8F000106A247F7D38E0D0286FD31C6DDF41EBD8 +:10A9000037FB1700D1796B9383D73B6BAA9CB4CAF2 +:10A91000234783F25F0B3D6C77DF77861FEEC0F134 +:10A92000EF23BD223073AE5D6DC54CA70C3D397E63 +:10A9300076438CEDF05A73BC8BD6595BAD52450310 +:10A940004ED49C3942FEFA4895CB70E1BE466A244B +:10A95000C6F7C755CE51BAE7F003755CA6757FF010 +:10A9600031F246513AF9BDB0DCA48E1FAA6E7113C4 +:10A970003FEC458A107E22530EB65FA9E3FE6CD1F0 +:10A980007F2FE285F01CC1FD96525C34897285D020 +:10A990007D53C1C7EFC076559BC2E3BE90EF885090 +:10A9A0005DA8BF496539E9F78606E8FE4F3FF23BEF +:10A9B000C743FE10F3F370BE9FE5D05E67B86673C1 +:10A9C00019F1CB1B5519ECB757B535DE4B7EFB7A29 +:10A9D000F9A37F798AE2A70295E9D9EF0CC65F2532 +:10A9E000BE6E12FEE2C9250FB0DCF575DD0E8437B0 +:10A9F0008884DFA1BA555F650DC3B7F30DC34B441F +:10AA00003EA9CF7F5F84F21BF16A915F30F38E72B3 +:10AA10003ECFCE2BD5597A6CB92BFC4A29CDBB47FA +:10AA2000117561B9204AFAC04579259AA724E7BB78 +:10AA3000D64D26C7C18B53E2E0D43C13B8C74B5A5E +:10AA4000D19E3ED986F1F17298CE2BD111588E2B22 +:10AA50005D1C2F8E548B3828E60CE76BE5E7CBF1B5 +:10AA60009B961F3CDEE3460E00F8518FC6FD2CF38B +:10AA700037BB7311D45B3D017E7EEBDA47A5C47909 +:10AA80004395ED6E9DF5C64480E0A6EA8B543E5892 +:10AA9000DBB6C0B20F26107D872681F1EBAD5915CC +:10AAA000273E3DFB7BE038F4130DE31E283E7F7EFE +:10AAB0009CF6E9A2FC97D8E749DAA78BF25F627FA0 +:10AAC0002FF7E8DCBEDA53C6ED827610797E5B1F85 +:10AAD0005C89FA00F1D65020FA24FF648773FCB732 +:10AAE0000789BF5C014523F97617C4E252823E18FC +:10AAF000F186DF25BBDC9FE761FE4BDDD7AFDA1CBB +:10AB0000D6B9C2B711DC21844B787F71E77F3DB4A1 +:10AB100094D6794B66BECAE9DABC83F50EEA850C99 +:10AB2000F637843E8CE57938EF30B2B354A2FB504F +:10AB30005B770B47774EB9C7754671DE09D4D7D41A +:10AB4000EF4739A7F3F4D77CF0195AE7E33F2EE03B +:10AB5000FB4D235BDE66B97F030390DCCB28F7B6A1 +:10AB60009CC5DE5AFC6D117F073B9E11E7673D389F +:10AB7000E21D8FD1F9FB7F22433ABC5D2A5DC19C67 +:10AB80009F1F32AA4C1E3FE74F53373445DDB07745 +:10AB9000EC7BDC8F34039462FFEB4ED34D7CF0F5FD +:10ABA000DD8E0BD60DBFBEFBC275C3D12F3BC0A53A +:10ABB000CDECE30A98E03C2B85F05407ECA357D882 +:10ABC00066B787AE6E673F52D415F51ACA39505F23 +:10ABD0005B40FEF3C026B38CDFFB73D8EE0794B165 +:10ABE00038D9F500D5CB75BABF10E1BA27E567E9CA +:10ABF000FE42EAF97B9D13EBF97C3884EA95A9F5CE +:10AC000049C9F37D51DF5F2AEA90767DB2429D38D3 +:10AC1000FA20E1E93637E3A1F7D9EBDFA1FA975D36 +:10AC2000C70F5875606D0768BBC539CC76F2FB9FBE +:10AC300017F550B81ECFB192169928DEB482EB9B5F +:10AC40001BE81C73ED7FBE75C3664BBF2173F33DDC +:10AC5000C89F59F8B4C7FD4DBB90C76B5591B786D7 +:10AC60002C95F5FCFA273C2093BFEC558F929C6CF9 +:10AC700083890D244FBD3EE1B7450F39D96FFB5491 +:10AC8000BBCE74CD534DBEBF90F7F719C66E0413FB +:10AC90003DAE65511EE92FADE6A7DA791FB1B616B4 +:10ACA000DAC780CCFAEEFDD20D7C8FA949CA66794D +:10ACB0005434B330515FEE6A4F7F1FA9B670B2852E +:10ACC000D7F73A80E2AD6886F1B24EF87E4161B8BE +:10ACD0004D20EE2BC1764D1AC073F67A4E337D6A45 +:10ACE0004B5D2B493FED6A17715BD49B3EAE7BA059 +:10ACF0005DC49F852DA12F101D6E82C97AD26F2849 +:10AD0000DA4684EFB588786D17E94B11EFEE72AC37 +:10AD100099C96BBDE40CEDA2F39ADF11FE842B20E0 +:10AD2000FC7A8CD4381F74ACC5FC0782DB4C7C5E8B +:10AD3000C98A0A8EAD3C7F1F519B2EED662FC13B09 +:10AD40006CE9E70ACDE4BA6B05388C5E7F425D5D45 +:10AD50009F5F5D5DD2BE2FEAE937083E86E723821A +:10AD60000FD78346F284FC7798D6B3EF97543CB75D +:10AD7000A388EB2E9758DF3ED5627E95E0BDB829BB +:10AD8000F8353AF7FB3B3B80E1CDF3BE466D6138C9 +:10AD900010443AF56708BFF9C93AA3339890FF7990 +:10ADA000D3A2D79B165D97233B8D8B7B6F6CC7AF70 +:10ADB000826A37D12B157E5F0F8C511D68B6F5D591 +:10ADC0007DF7B9294FDC5BB0DE4DF7D1A29EF5D9F6 +:10ADD000D4EF2F3003B47E5F4FE3B31F96121F09E9 +:10ADE000BE8F2C11F98818EAE748429EF4C576997F +:10ADF000F7555F0071CAA7BB3CC22F7261BCA8AFF8 +:10AE000020BFB99AED393E1FA3D4C16B963CC9A6A9 +:10AE10000126DD172C0089F0853A727A3E99BCFA3A +:10AE20008230D0BE66832337E07C8A470B34F643FA +:10AE30007EDDAE313E7DA663268E87F9E3EBD01C26 +:10AE4000F8CA99035FD37C6DC95D2A9ECE109E8897 +:10AE50004F7C0FF0B9E04FF52C672E547854CFFF9C +:10AE6000C8C68BC7849097C37F89F013A50B36E5BE +:10AE700033F8455F91F12B6B619EE72A3020B48255 +:10AE8000F0A149848FD4F3573CF77803E1ED956D39 +:10AE900042AFD62A96FE08E359903F6FB2D605CB53 +:10AEA0002E356508BBD30C3FF488BCB6E0D30A74DA +:10AEB000C7DD39E7EB57BB7D72967BD74F6ECE105F +:10AEC000FE903EC6FABDB751C0F77A851F7A74600E +:10AED00015FB0F37E6972E48D48F97BB4E985A171D +:10AEE0009CAB0E38C337A69BF6F93BEDBE085D95CB +:10AEF0009B8D3F1E24FE7192DCB8B93DEF7D613021 +:10AF000060905C2D31238074DBEB0B07887FFA8E19 +:10AF1000EF7C87EA24CAEBB241FEA6A20481C6DD1B +:10AF2000981766F9D8586002D5951EEC31BF9B087A +:10AF3000F7969650F966A45BA63666121C0FC423DA +:10AF4000648F6ECA35C3C13474A8DE2CF4C7B196C1 +:10AF5000E02A9A574BBA7315C0C39BCCD5D49FAF88 +:10AF6000BE3A5F9E1ADDA4F72F5D9E5ADC74BEFECA +:10AF70008220DFD3EAFFA14C1ED6F4B87E4B9EFAA6 +:10AF8000973C00A104B90A6E4ED13B7E4BEFF84DC1 +:10AF9000968BCD9B752B0F1C64F970923C9527E81E +:10AFA00019BFAD674C9647C56FCB93257F244F1EC5 +:10AFB000BA1F3C594F7E4A1F887B8CA9F2156E0937 +:10AFC0006DD94C762CEFB7AD45FACCFD4F5D17F23D +:10AFD000D45F60F1FB92A799FFCF22FFD365E15EBA +:10AFE0004F7112BFDBEDDA2919E2488A755312B7A7 +:10AFF0009F98CAE4B6762A835B732A97DBBA291F27 +:10B00000B7EBA7AEE0B67E2A9FDB8629E4FBD5C866 +:10B01000FF5345DCDE38B59CDB8D53CBB86D9C5AB5 +:10B02000CDE39AA656727BD3D40DDCDE3C5523D6F5 +:10B03000A19A504E5AFEA772D665E07F2342F5D101 +:10B04000BEE3F7BC43F8716A2AE751A2BE355CEF54 +:10B05000712A61E6FFA30542BF6FF408FAA4F2FF6C +:10B06000B196D0FE74FC0F4E716F4BA17B5B95ECDB +:10B07000E70C337F9FE7EFBEF447CA83A2FF7198C6 +:10B08000DF5FA2FD9FF62B1726FB95FD79C97E6534 +:10B09000DF12DBAF748D521D6CBBA4F33DB1532D99 +:10B0A000A17FE6F521B88DDE87DADC1AF95351DF8E +:10B0B0008D010FF6B7EE9581F27DE85F7C8BF80C81 +:10B0C000503F90DD98AFBC3EBCC9D2EFD6F80A38ED +:10B0D000ED085F847FF23E7DAD395FEE679B67CB05 +:10B0E000FD55509691CECEE638EB85DC6B42EEA353 +:10B0F00005C101CAB74453E4DEB6A3888724B93F2B +:10B1000065CBBD25C7397E71EF2387E41EF9EA2799 +:10B110009BC579D1DF4EB2A38A35DED928EA5BF52B +:10B120007EA1579546A12F142DD98E22DFBC4B74DA +:10B130004995F78822FCE3A6D27F9DB667645773D2 +:10B14000FC3E291B97D67E3F11A13CD6716529CBC9 +:10B1500077AA1C45B555CCE7C7957A4827FFF396E3 +:10B16000239F6D474CB623A9E36C79EA3BDEC47894 +:10B17000B1EDCA713CB799604F366A020F684F3E15 +:10B1800026FE4A95A7DA4233144CB34FB543F8A5CF +:10B19000AFAD0B0A7F11FD44F253A2CEF47E80DAEC +:10B1A00021FC9F9C46EBF7153A8473510F3636C647 +:10B1B000EBA98681F2AC7620BC75E6442FC960AF5E +:10B1C00067D84FFB47F97475FC15F2F9D126E117E2 +:10B1D00042772EFB2D763B17DFDBFE8ECDFFA9E3FA +:10B1E0009E2C323BD3E1E5F3165E8E0E3C9DC41FD0 +:10B1F00043CAD29B0C3DAD5E358DCBA257E7E757D6 +:10B200001C473BC77A7576BFE2BA8E347C309B5FB1 +:10B21000F1890E91CF45BF621DCDAB2D177EC5E7DD +:10B220003BE0F2FA0B35F731BE2ED55FD86CF1DF7B +:10B230006CFE425787AD37C2AC375C96DEB8587F9C +:10B24000218D7F703BF32F4CCA54FF43541B221FA8 +:10B2500022F408EA99BBE83DC6F1EC2F1CF5087E04 +:10B26000312D3D736D7B7007E175A85AF80B974B34 +:10B270000ED0EFBBAF236FFEF230DF71A58FAD1D97 +:10B2800098203F07BC31BA37DD4BF795287E7CCF3D +:10B290002BEE11009451DEFF8BF23506D9B991CC1B +:10B2A0002F7D83C6774714A07B83433D22FFF7C5DC +:10B2B000055947017967C8197E6AC2CFBF770D1E4D +:10B2C000C5F60F1985A39070EFF6B0256F2ED8C282 +:10B2D000F774B3B45B9EFD3037DDFEC4FD5CBABAD3 +:10B2E000728E7FD751A0F13D320B3F596A10227EFA +:10B2F000922307D747D0DB83EA84BC475F4D5727AB +:10B30000C7C1F922EF25837286F2EF03B49638178E +:10B310009FB37FB1FB513A970E218677D0EFE0BC07 +:10B320007BFF5A11EFF47BC26E2D8DDED8D7937C54 +:10B33000FF28B595973D16A33BC287038A4169CF85 +:10B34000C1B2CA26CA4F4635AE0083EA7304D3D5CC +:10B35000A7C72DF9D4C1607BAC7CB2253B9DBDB0A5 +:10B36000DB010BFF76DF5D326612DFA94566907F59 +:10B3700087E3F34B9184BCF11316FCBD9211AF45EA +:10B3800064EDF50AFDEFD66326FDDEB82FEF2EAE95 +:10B3900033BAF5089CA1E72531F839E9A77C77E7AE +:10B3A000689A7DBCD521E294BDCE10AFB7375FE17E +:10B3B000FAE3DEA2F4F9ACE73B441E49F5AD0F72A7 +:10B3C0005EDFA7709D3875DC53169FF4AB6640E3D3 +:10B3D000B8FA81323A577409708E72EC9D379FD853 +:10B3E0008DFDFD3D41CE7B0C51FE0385B5BFF05E6A +:10B3F000C6FBFE6B1C1A9D6383FC11DF47385C0D96 +:10B4000006E98FEC6A1C9710471E86D101BA0F77A8 +:10B41000782D70BED46B0493DEF723038E93FFA5C3 +:10B420004CB03E734237D7010EF855BEA73354795E +:10B430009AFD231DC6394F315429E865D793FC1670 +:10B440003FFAFD773527CAC1018B6E0F52DE9CEFA4 +:10B45000318D41A2FF75A0709CEDF38175E39D5481 +:10B4600017CCF2BB0D0A45F6D70481E474A8CA9143 +:10B47000F67ED450D569DE67EA7E9C277EC9FA2F16 +:10B480004B99E0FC4456D96FD9AE3C64ED63E35A66 +:10B49000E0CD66570B3D9BDD1606FA7D58DE5BF26C +:10B4A000A88EFDDD85BF8A38493E6E0358A4D37E41 +:10B4B0002778BF879B9F8EF3FEACFBBA203FCFF768 +:10B4C000712128E4D7BE77BDB04D4D8ADFB352EE6F +:10B4D0004565A6F441EEBAE07DB2EEF7EE3975327D +:10B4E00001DEA2CEE4FBD973CDFF43CF8E5327916B +:10B4F0005F0E575E58BE0E59758D584F35D3C9E64D +:10B50000339BEFB2E88839B3CF1FF28D75A6B3C372 +:10B510001D9D420E52F93195FF34D718DBF143EBF4 +:10B5200092E1DCD029E4F8060B4E4EA19E4FEFEDE0 +:10B530007B4C747FEAE934EB7EBA53E5F1337C6DE2 +:10B54000DBF9772ECDCE2F6B1176DEBF2A83EC3C54 +:10B55000E2F365BAC7F67B940F4890EB3E6FB29F5B +:10B5600069DBF9C73B457CF062DE5512D9E91CCF97 +:10B5700004FBBF59D5C97980543BAD3A431C37AA67 +:10B58000F9AAAD6FB89EF55AC7FB4F4410CEFEF82E +:10B590003EAE0F6522FF66484CA7483A3A4179F221 +:10B5A000BD9AF24E10BF63D3855EC85AAB70BD63BF +:10B5B000C8F15EF587D82AB130042DB883CCB7FB2B +:10B5C000C7F97E8EC5F773D1933E7F5A63FD2E85F2 +:10B5D000EA88F56F56A78B2BEC96EE4F25DF77BFE9 +:10B5E00038B9F8FB4EABBE9C0119422E9A1D7D6402 +:10B5F000EF9B1D7C2F85AEEF2A6BACD201D5F56990 +:10B6000067F8DE4FF77F24AB5EB474465EE0567198 +:10B61000AFE5EC0E714F867F47B8947EF739C1BF16 +:10B620000FBC926EB1CAEC07B3DC9C850207D583D0 +:10B6300023272469DA0FBA82AE341A0E9A570241D0 +:10B640006E53F77D1584F97919C4B8BD06C6B82DB7 +:10B6500087716E2B60925B9326E07E8D93A2AEB1D4 +:10B660000A0C999E574290DB3510E6B61A62DC7ED2 +:10B67000A5FE6F7F733B4EF9DA797811784D23DFA1 +:10B6800071043A7D7E1BCFAD9D3AF3C95CF4EEF3B5 +:10B690004DB01F5F5F3DCE7EA8D71364FE76FA05DE +:10B6A0007FDB709CB3E4836D3F49253F69751AFECB +:10B6B0009DC34F4AFD1DC9FF0229F7D0B3D04500F5 +:10B6C0000000000000000000000000180000000062 +:10B6D000000000000000004000000000000000002A +:10B6E0000000002800000000000000000000001022 +:10B6F000000000000000000000000020000000002A +:10B700000000000000000010000000000000000029 +:10B710000000000800000000000000000000000021 +:10B7200000000000000000000000003900000000E0 +:10B7300000000000000000380000000000000000D1 +:10B7400000000000000000000000000000000008F1 +:10B7500000000000000000000000000000000000E9 +:10B76000000000000000000C0000000000000000CD +:10B770000000000E000000000000000000000004B7 +:10B7800000000000000000000000001800000000A1 +:10B79000000000000000001C00000000000000008D +:10B7A0000000001C0000000000000000000000136A +:10B7B00000000000000000000000003A000000004F +:10B7C0000000000000000001000000000000000078 +:10B7D0000000000200000000000000000000000166 +:10B7E0000000000000000000000000100000000049 +:10B7F00000000000000000500000000000000000F9 +:10B800000000000000000000000000000000000335 +:10B810000000000000000000000000AB000000007D +:10B820000000000000000008000000000000000010 +:10B830000000C00000100000000000080000C00868 +:10B8400000100000000000020000C0000010000016 +:10B850000000001000009FB0000000000000000881 +:10B860000000C08000100000000000040000C0883C +:10B8700000100000000000020000C0800010000066 +:10B8800000000010000091200000000000000008EF +:10B8900000009340000100040000000100009348F4 +:10B8A00000000000000000020000935000000000B3 +:10B8B0000000000800009354000000000000000297 +:10B8C00000009418000000000000000800009358D9 +:10B8D000000800000000000800009AB000400000CE +:10B8E00000000040000093980008000000000008DD +:10B8F000000093D800080000000000080000942019 +:10B9000000C8000000000098000095B000980000FA +:10B9100000000028000095F00098000000000028BA +:10B920000000C480054000300000054000009D205C +:10B93000000800000000000100009D210008000038 +:10B9400000000001000020080010000000000010AE +:10B9500000002000000000000000000800009CD84B +:10B96000000800000000000200009D180000000018 +:10B9700000000001000000010000000000000000C5 +:10B9800000000009000000000000000000000002AC +:10B9900000000000000000000000CF2000000000B8 +:10B9A000000000200000CF46000000000000000161 +:10B9B0000000600000200000000000200000730074 +:10B9C000000800000000000800009FA00000000028 +:10B9D0000000000100009FA800000000000000011E +:10B9E00000009F60000000000000001000009F6346 +:10B9F000000000000000000100009F610000000046 +:10BA00000000000100009F6600000000000000012F +:10BA100000009F67000000000000000000009F6819 +:10BA2000000000000000000400009F6C0000000007 +:10BA300000000004000000520000000000000000B0 +:10BA400000000003000000000000000000000003F0 +:10BA500000000000000000000000000500000000E1 +:10BA600000000000000000020000000000000000D4 +:10BA700000060000000000000000002000009F7091 +:10BA8000000000000000000100009F900000000086 +:10BA9000000000080000005300000000000000004B +:10BAA00000009F98000000000000000200009F9C22 +:10BAB000000000000000000100009F9D0000000049 +:10BAC000000000010000000900000000000000006C +:10BAD0000000000100000000000000000000004421 +:10BAE0000000000000000000000000010000000055 +:10BAF00000000000000000500000000000000000F6 +:10BB0000000000890000000000000000000012C8D2 +:10BB10000080000000000080000000010000000024 +:10BB2000000000000000A000071000000000071047 +:10BB300000001AC800000000000000080000AEC0AD +:10BB400000080000000000080000AE4000080000EF +:10BB5000000000080000AE8000080000000000089F +:10BB6000000020080010000000000010000020006D +:10BB700000000000000000080000A01007100040B6 +:10BB80000000004000001BF8000800000000000159 +:10BB900000001BF9000800000000000100001AD09E +:10BBA000000000000000000100001AD800000000A2 +:10BBB0000000000200001ADA00000000000000028D +:10BBC0008000000000000000000000000000AF0046 +:10BBD000000000000000002000001B78002800008A +:10BBE000000000040000E000002000000000002031 +:10BBF0000000F300000800000000000800001AF038 +:10BC0000000000000000010800001B3700000000D9 +:10BC10000000000100001B0F0000000000000001F8 +:10BC200000001B70000000000000000400001B74F6 +:10BC300000000000000000040000005000000000B0 +:10BC400000000000000000030000000000000000F1 +:10BC500000000005000000000000000000000006D9 +:10BC600000000000000000000000000700000000CD +:10BC70000000000000001BC80000000000000001E0 +:10BC800000001BE800000000000000080000005158 +:10BC9000000000000000000000001BD000000000B9 +:10BCA0000000000400001BD400000000000000049D +:10BCB00000001BD8000000000000000400001BDC96 +:10BCC00000000000000000080000B00000180000A4 +:10BCD000000000180000C00000400000000000400C +:10BCE0000000C00000400002000000010000C00190 +:10BCF00000400002000000000000E2000020000000 +:10BD0000000000200000E204000200080020000201 +:10BD10008000000000000000000000000000E200C1 +:10BD200000080020000000040000F40000280000CB +:10BD3000000000280000F540001000000000001086 +:10BD40000000F5C000200000000000200000F5C049 +:10BD500000020020000000020000F30000200000AC +:10BD6000000000200000200800100000000000106B +:10BD70000000200000000000000000080000110882 +:10BD80000008000000000008000011680008000022 +:10BD900000000008000011A80008000000000008D2 +:10BDA00000001240000800000000000100001241E5 +:10BDB0000008000000000001000040000020000416 +:10BDC00000000010000059000030001800000010B2 +:10BDD0000000590800300018000000020000570061 +:10BDE00000080000000000010000570100080000EA +:10BDF00000000001000011E8000000000000000148 +:10BE0000000011F00000000000000001000011F827 +:10BE100000000000000000100000124400080000B4 +:10BE2000000000040000400000200000000000208E +:10BE30000000530000100000000000100000153842 +:10BE400000000000000000010000000300000000EE +:10BE500000000000000000000000000000000000E2 +:10BE600000000001000000000000000000000004CD +:10BE700000000000000000000000150800000000A5 +:10BE8000000000010000152800000000000000086C +:10BE900000000050000000000000000000008308C7 +:10BEA0000080000000000080000000010000000091 +:10BEB000000000000000200800100000000000103A +:10BEC00000002000000000000000000800008410B6 +:10BED0000008000000000008000084700008000056 +:10BEE0000000000800060000046000280000046054 +:10BEF00000008520000800000000000100008521EE +:10BF000000080000000000018000000000000000A8 +:10BF10000000000000008408000000000000000194 +:10BF2000000084F40008000000000002000084F615 +:10BF3000000800000000000200008504001000005E +:10BF400000000004000087600000000000000020E6 +:10BF500000006000002000000000002000007300CE +:10BF600000080000000000080000000300000000BE +:10BF700000000000000000050000000000000000BC +:10BF800000000006000000000000000000000007A4 +:10BF90000000000000000000000088080000000011 +:10BFA00000000001000088280000000000000008D8 +:10BFB0000000005000000000000000000000881099 +:10BFC00000000000000000040000881400000000D1 +:10BFD00000000004000088180000000000000004B9 +:10BFE0000000881C00000000000000080000300075 +:10BFF0000040000000000008000030080040000081 +:10C00000000000280000339001C00010000000086C +:10C010000000320000200000000000200000372057 +:10C02000000000000000000800001020062000387A +:10C03000000000080000A000000000000000200038 +:10C0400000003EA9000000000000000100003EC802 +:10C05000000000000000000280000000000000005E +:10C060000000000000006000002000000000000848 +:10C070000000400000080000000000010000400136 +:10C08000000800000000000100004040000800041B +:10C0900000000002000040600008000400000004EE +:10C0A0000000400000080000000000040000400400 +:10C0B00000080000000000040000404000000000F4 +:10C0C00000000008000040480000000000000008D8 +:10C0D0000000800000000000000000100000504040 +:10C0E00000010004000000010000500000000000FA +:10C0F00000000020000050080010000000000004B4 +:10C100000000500C0010000000000001000052C7A9 +:10C110000000000000000001000052C60000000006 +:10C120000000000100003000003000180000000492 +:10C130000000300400300018000000040000300847 +:10C1400000300018000000020000300A0030001823 +:10C15000000000020000300C003000180000000158 +:10C160000000300D00300018000000010000300E0B +:10C1700000300018000000010000301000300018EE +:10C18000000000040000301400300018000000041B +:10C19000000050000100008000080004000050046E +:10C1A00001000080000800040000000A00000000F8 +:10C1B0000000000000005068010000800000000145 +:10C1C0000000506901000080000000010000506C78 +:10C1D00001000080000000020000506E010000809D +:10C1E0000000000200005070010000800000000408 +:10C1F0000000507401000080000000040000506640 +:10C200000100008000000002000050640100008076 +:10C2100000000001000050600100008000000002EA +:10C220000000506201000080000000020000505039 +:10C230000100008000000004000050540100008054 +:10C2400000000004000050580100008000000004BD +:10C250000000505C01000080000000040000507CE1 +:10C2600001000080000000010000507D01000080FE +:10C270000000000100004018001000000000000451 +:10C2800000004090001000000000000400004098F2 +:10C290000010000000000004000041100000000039 +:10C2A0000000000200004112000000000000000237 +:10C2B00000004114000000000000000200004116D0 +:10C2C00000000000000000020000604000080000C4 +:10C2D00000000002000060420008000000000002B0 +:10C2E00000006044000800000000000400006080BE +:10C2F0000008000000000008000060C000400008C6 +:10C3000000000008000060000008000000000002BB +:10C31000000060020008000000000001000060044E +:10C320000008000000000002000063400008000058 +:10C330000000000800006380000800000000000406 +:10C34000000063840008000000000001000063C0DA +:10C350000008000000000002000063C400080000A4 +:10C36000000000020000640000080000000000045B +:10C3700000007000001000000000000400007004C5 +:10C380000010000000000004000070080010000011 +:10C3900000000004000090000008000000000002FF +:10C3A000000090020008000000000001000090045E +:10C3B000000800000000000200009040000800009B +:10C3C000000000020000904400080000000000028D +:10C3D000000090460008000000000002000096489F +:10C3E0000008000000000008000090800008000025 +:10C3F000000000020000908400080000000000021D +:10C40000000096880008000000000008000080403E +:10C41000000800000000000100008041000800004A +:10C420000000000100008042000800000000000140 +:10C4300000008043000800000000000100008000B0 +:10C440000008000000000002000080020008000058 +:10C45000000000010000800400080000000000024D +:10C46000000080C00008000000000002000080C240 +:10C470000008000000000002000080C40008000066 +:10C4800000000002000080800008000000000001A1 +:10C490000000808100080000000000010000808290 +:10C4A0000008000000000001000080830008000078 +:10C4B000000000010000808400080000000000016E +:10C4C0000000808500080000000000010000808658 +:10C4D00000080000000000010000600000080000EB +:10C4E00000000002000060020008000000000001DF +:10C4F000000060040008000000000002000060422C +:10C5000000C00018000000020000604000C00018D9 +:10C51000000000020000604C00C00018000000088D +:10C520000000604400C000180000000800006057D0 +:10C5300000C00018000000010000605400C0001896 +:10C54000000000020000605600C00018000000015A +:10C55000000066400008000000000008000066803F +:10C560000008000000000008000066C0000800008D +:10C57000000000080000DA4200180000000000027D +:10C580000000DE4000000000000000000000E000AD +:10C5900000000000000000040000D0C00000000007 +:10C5A000000000040000D0C40000000000000004EF +:10C5B0000000D0C800000000000000040000D0CC43 +:10C5C00000000000000000040000D0D000000000C7 +:10C5D000000000040000D0D40000000000000004AF +:10C5E0000000D0D800000000000000040000D0C00F +:10C5F00000000000000000200000DB000000000040 +:10C60000000000040000DB000000000000000068E3 +:10C610000000B94800000000000000000000D00049 +:10C6200000000000000000040000B0C00000000096 +:10C63000000000040000B0C400000000000000047E +:10C640000000B0C800000000000000040000B0C0FE +:10C6500000000000000000100000D6B00000000044 +:10C66000000000040000D6B4000000000000000438 +:10C670000000D6B800000000000000040000D6BC96 +:10C6800000000000000000040000D6B00000000020 +:10C69000000000100000D348000000000000000867 +:10C6A0000000D358000000000000008000000010CF +:10C6B00000000000000000000000D358000000004F +:10C6C0000000000800000000060209000000000051 +:00000001FF -- GitLab From 3b7f817e47bb66ae4d82ed73689a521af70a5410 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Thu, 31 Mar 2011 17:04:01 -0700 Subject: [PATCH 0241/5560] bnx2x: don't write dcb/llfc fields in STORM memory We could get hardware attention during DCB/FCoE traffic without this fix. Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index ef37b98d6146..775fef031ad8 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1041,12 +1041,23 @@ static inline void storm_memset_cmng(struct bnx2x *bp, struct cmng_struct_per_port *cmng, u8 port) { - size_t size = sizeof(struct cmng_struct_per_port); + size_t size = + sizeof(struct rate_shaping_vars_per_port) + + sizeof(struct fairness_vars_per_port) + + sizeof(struct safc_struct_per_port) + + sizeof(struct pfc_struct_per_port); u32 addr = BAR_XSTRORM_INTMEM + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port); __storm_memset_struct(bp, addr, size, (u32 *)cmng); + + addr += size + 4 /* SKIP DCB+LLFC */; + size = sizeof(struct cmng_struct_per_port) - + size /* written */ - 4 /*skipped*/; + + __storm_memset_struct(bp, addr, size, + (u32 *)(cmng->traffic_type_to_priority_cos)); } /* HW Lock for shared dual port PHYs */ -- GitLab From fab0dc89f0d98459c6ce7fa27422949ac15837fa Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Thu, 31 Mar 2011 17:04:22 -0700 Subject: [PATCH 0242/5560] bnx2x, cnic: Disable iSCSI if DCBX negotiation is successful With current bnx2x firmware 6.2.9, iSCSI is not supported in DCB network, so we need to disable it. Add cnic command to disconnect iSCSI connections and prevent future connections when DCBX negotiation succeeds. Signed-off-by: Dmitry Kravkov Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_dcb.c | 22 ++++++++++++ drivers/net/bnx2x/bnx2x_dcb.h | 8 +++-- drivers/net/bnx2x/bnx2x_main.c | 5 +++ drivers/net/cnic.c | 64 ++++++++++++++++++++++++---------- drivers/net/cnic.h | 1 + drivers/net/cnic_if.h | 6 ++-- 6 files changed, 83 insertions(+), 23 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 9a24d79c71d9..1214907d00d9 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -571,6 +571,28 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) { switch (state) { case BNX2X_DCBX_STATE_NEG_RECEIVED: +#ifdef BCM_CNIC + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { + struct cnic_ops *c_ops; + struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO; + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI; + + rcu_read_lock(); + c_ops = rcu_dereference(bp->cnic_ops); + if (c_ops) { + bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD); + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + } + + /* fall through if no CNIC initialized */ + case BNX2X_DCBX_STATE_ISCSI_STOPPED: +#endif + { DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n"); #ifdef BCM_DCBNL diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index 71b8eda43bd0..1e14775a18cb 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -183,9 +183,13 @@ void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled); enum { BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1, - BNX2X_DCBX_STATE_TX_PAUSED = 0x2, - BNX2X_DCBX_STATE_TX_RELEASED = 0x4 +#ifdef BCM_CNIC + BNX2X_DCBX_STATE_ISCSI_STOPPED, +#endif + BNX2X_DCBX_STATE_TX_PAUSED, + BNX2X_DCBX_STATE_TX_RELEASED }; + void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state); /* DCB netlink */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 32e64cc85d2c..f3cf88918a9e 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -10342,6 +10342,11 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) break; } + case DRV_CTL_ISCSI_STOPPED_CMD: { + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED); + break; + } + default: BNX2X_ERR("unknown command %x\n", ctl->cmd); rc = -EINVAL; diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 8cca60e43444..5dfbff06631c 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2966,31 +2966,36 @@ static int cnic_service_bnx2x(void *data, void *status_blk) return 0; } -static void cnic_ulp_stop(struct cnic_dev *dev) +static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type) { - struct cnic_local *cp = dev->cnic_priv; - int if_type; - - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + struct cnic_ulp_ops *ulp_ops; - for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { - struct cnic_ulp_ops *ulp_ops; + if (if_type == CNIC_ULP_ISCSI) + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); - mutex_lock(&cnic_lock); - ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], - lockdep_is_held(&cnic_lock)); - if (!ulp_ops) { - mutex_unlock(&cnic_lock); - continue; - } - set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); + mutex_lock(&cnic_lock); + ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], + lockdep_is_held(&cnic_lock)); + if (!ulp_ops) { mutex_unlock(&cnic_lock); + return; + } + set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); + mutex_unlock(&cnic_lock); - if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) - ulp_ops->cnic_stop(cp->ulp_handle[if_type]); + if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type])) + ulp_ops->cnic_stop(cp->ulp_handle[if_type]); - clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); - } + clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]); +} + +static void cnic_ulp_stop(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + int if_type; + + for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) + cnic_ulp_stop_one(cp, if_type); } static void cnic_ulp_start(struct cnic_dev *dev) @@ -3039,6 +3044,12 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info) cnic_put(dev); break; + case CNIC_CTL_STOP_ISCSI_CMD: { + struct cnic_local *cp = dev->cnic_priv; + set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags); + queue_delayed_work(cnic_wq, &cp->delete_task, 0); + break; + } case CNIC_CTL_COMPLETION_CMD: { u32 cid = BNX2X_SW_CID(info->data.comp.cid); u32 l5_cid; @@ -3562,8 +3573,12 @@ static void cnic_init_csk_state(struct cnic_sock *csk) static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr) { + struct cnic_local *cp = csk->dev->cnic_priv; int err = 0; + if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI) + return -EOPNOTSUPP; + if (!cnic_in_use(csk)) return -EINVAL; @@ -3965,6 +3980,17 @@ static void cnic_delete_task(struct work_struct *work) cp = container_of(work, struct cnic_local, delete_task.work); dev = cp->dev; + if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) { + struct drv_ctl_info info; + + rtnl_lock(); + cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI); + rtnl_unlock(); + + info.cmd = DRV_CTL_ISCSI_STOPPED_CMD; + cp->ethdev->drv_ctl(dev->netdev, &info); + } + for (i = 0; i < cp->max_cid_space; i++) { struct cnic_context *ctx = &cp->ctx_tbl[i]; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 4456260c653c..3367a6d3a774 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -226,6 +226,7 @@ struct cnic_local { #define CNIC_LCL_FL_KWQ_INIT 0x0 #define CNIC_LCL_FL_L2_WAIT 0x1 #define CNIC_LCL_FL_RINGS_INITED 0x2 +#define CNIC_LCL_FL_STOP_ISCSI 0x4 struct cnic_dev *dev; diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index e01b49ee3591..fdd8e46a9050 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.2.13" -#define CNIC_MODULE_RELDATE "Jan 31, 2011" +#define CNIC_MODULE_VERSION "2.2.14" +#define CNIC_MODULE_RELDATE "Mar 30, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -85,6 +85,7 @@ struct kcqe { #define CNIC_CTL_STOP_CMD 1 #define CNIC_CTL_START_CMD 2 #define CNIC_CTL_COMPLETION_CMD 3 +#define CNIC_CTL_STOP_ISCSI_CMD 4 #define DRV_CTL_IO_WR_CMD 0x101 #define DRV_CTL_IO_RD_CMD 0x102 @@ -94,6 +95,7 @@ struct kcqe { #define DRV_CTL_START_L2_CMD 0x106 #define DRV_CTL_STOP_L2_CMD 0x107 #define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c +#define DRV_CTL_ISCSI_STOPPED_CMD 0x10d struct cnic_ctl_completion { u32 cid; -- GitLab From 9b12c75bf4d58dd85c987ee7b6a4356fdc7c1222 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 18:03:35 -0700 Subject: [PATCH 0243/5560] net: Order ports in same order as addresses in flow objects. For consistency. Signed-off-by: David S. Miller --- include/net/flow.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/flow.h b/include/net/flow.h index 37e77d66f78c..c6d5fe5ec1bf 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -26,8 +26,8 @@ struct flowi_common { union flowi_uli { struct { - __be16 sport; __be16 dport; + __be16 sport; } ports; struct { @@ -36,8 +36,8 @@ union flowi_uli { } icmpt; struct { - __le16 sport; __le16 dport; + __le16 sport; } dnports; __be32 spi; @@ -86,8 +86,8 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif, fl4->flowi4_secid = 0; fl4->daddr = daddr; fl4->saddr = saddr; - fl4->fl4_sport = sport; fl4->fl4_dport = dport; + fl4->fl4_sport = sport; } -- GitLab From 4d9fd0b72cd80624f9f5c6a4c69c503615bec370 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 26 Mar 2011 03:17:42 +0000 Subject: [PATCH 0244/5560] viafb: delete clock and PLL initialization We do this also in the real program code so there is no reason to do it here too (and here it's hardly readable). Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/viamode.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 8c5bc41ff6a4..e550063b89b1 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c @@ -41,7 +41,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFF, 0x40}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ @@ -87,7 +86,6 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFD, 0x40}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */ {VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ {VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ @@ -161,7 +159,7 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIASR, SR1B, 0xFF, 0xF0}, {VIASR, SR1E, 0xFF, 0x01}, {VIASR, SR2A, 0xFF, 0x00}, -{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ +{VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */ {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ @@ -174,7 +172,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFF, 0x40}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ @@ -204,7 +201,7 @@ struct io_reg VX855_ModeXregs[] = { {VIASR, SR2A, 0xF0, 0x00}, {VIASR, SR58, 0xFF, 0x00}, {VIASR, SR59, 0xFF, 0x00}, -{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ +{VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */ {VIACR, CR09, 0xFF, 0x00}, /* Initial CR09=0*/ {VIACR, CR11, 0x8F, 0x00}, /* IGA1 initial Vertical end */ {VIACR, CR17, 0x7F, 0x00}, /* IGA1 CRT Mode control init */ @@ -219,7 +216,6 @@ struct io_reg VX855_ModeXregs[] = { {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFD, 0x60}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ -- GitLab From c6ff669bac5c409f4cb74366248f51b73f7d6feb Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 28 Mar 2011 14:17:26 -0500 Subject: [PATCH 0245/5560] dlm: delayed reply message warning Add an option (disabled by default) to print a warning message when a lock has been waiting a configurable amount of time for a reply message from another node. This is mainly for debugging. Signed-off-by: David Teigland --- fs/dlm/config.c | 9 +++- fs/dlm/config.h | 1 + fs/dlm/dlm_internal.h | 2 + fs/dlm/lock.c | 100 +++++++++++++++++++++++++++++++++++++++--- fs/dlm/lock.h | 1 + fs/dlm/lockspace.c | 6 +-- 6 files changed, 108 insertions(+), 11 deletions(-) diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 0d329ff8ed4c..9b026ea8baa9 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -100,6 +100,7 @@ struct dlm_cluster { unsigned int cl_log_debug; unsigned int cl_protocol; unsigned int cl_timewarn_cs; + unsigned int cl_waitwarn_us; }; enum { @@ -114,6 +115,7 @@ enum { CLUSTER_ATTR_LOG_DEBUG, CLUSTER_ATTR_PROTOCOL, CLUSTER_ATTR_TIMEWARN_CS, + CLUSTER_ATTR_WAITWARN_US, }; struct cluster_attribute { @@ -166,6 +168,7 @@ CLUSTER_ATTR(scan_secs, 1); CLUSTER_ATTR(log_debug, 0); CLUSTER_ATTR(protocol, 0); CLUSTER_ATTR(timewarn_cs, 1); +CLUSTER_ATTR(waitwarn_us, 0); static struct configfs_attribute *cluster_attrs[] = { [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, @@ -179,6 +182,7 @@ static struct configfs_attribute *cluster_attrs[] = { [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr, [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr, [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr, + [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr, NULL, }; @@ -439,6 +443,7 @@ static struct config_group *make_cluster(struct config_group *g, cl->cl_log_debug = dlm_config.ci_log_debug; cl->cl_protocol = dlm_config.ci_protocol; cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs; + cl->cl_waitwarn_us = dlm_config.ci_waitwarn_us; space_list = &sps->ss_group; comm_list = &cms->cs_group; @@ -986,6 +991,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num) #define DEFAULT_LOG_DEBUG 0 #define DEFAULT_PROTOCOL 0 #define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */ +#define DEFAULT_WAITWARN_US 0 struct dlm_config_info dlm_config = { .ci_tcp_port = DEFAULT_TCP_PORT, @@ -998,6 +1004,7 @@ struct dlm_config_info dlm_config = { .ci_scan_secs = DEFAULT_SCAN_SECS, .ci_log_debug = DEFAULT_LOG_DEBUG, .ci_protocol = DEFAULT_PROTOCOL, - .ci_timewarn_cs = DEFAULT_TIMEWARN_CS + .ci_timewarn_cs = DEFAULT_TIMEWARN_CS, + .ci_waitwarn_us = DEFAULT_WAITWARN_US }; diff --git a/fs/dlm/config.h b/fs/dlm/config.h index 4f1d6fce58c5..dd0ce24d5a80 100644 --- a/fs/dlm/config.h +++ b/fs/dlm/config.h @@ -28,6 +28,7 @@ struct dlm_config_info { int ci_log_debug; int ci_protocol; int ci_timewarn_cs; + int ci_waitwarn_us; }; extern struct dlm_config_info dlm_config; diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index b94204913011..6a92478fe1f1 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -245,6 +245,7 @@ struct dlm_lkb { int8_t lkb_wait_type; /* type of reply waiting for */ int8_t lkb_wait_count; + int lkb_wait_nodeid; /* for debugging */ struct list_head lkb_idtbl_list; /* lockspace lkbtbl */ struct list_head lkb_statequeue; /* rsb g/c/w list */ @@ -254,6 +255,7 @@ struct dlm_lkb { struct list_head lkb_ownqueue; /* list of locks for a process */ struct list_head lkb_time_list; ktime_t lkb_timestamp; + ktime_t lkb_wait_time; unsigned long lkb_timeout_cs; struct dlm_callback lkb_callbacks[DLM_CALLBACKS_SIZE]; diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 04b8c449303f..e3c864120371 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -799,10 +799,84 @@ static int msg_reply_type(int mstype) return -1; } +static int nodeid_warned(int nodeid, int num_nodes, int *warned) +{ + int i; + + for (i = 0; i < num_nodes; i++) { + if (!warned[i]) { + warned[i] = nodeid; + return 0; + } + if (warned[i] == nodeid) + return 1; + } + return 0; +} + +void dlm_scan_waiters(struct dlm_ls *ls) +{ + struct dlm_lkb *lkb; + ktime_t zero = ktime_set(0, 0); + s64 us; + s64 debug_maxus = 0; + u32 debug_scanned = 0; + u32 debug_expired = 0; + int num_nodes = 0; + int *warned = NULL; + + if (!dlm_config.ci_waitwarn_us) + return; + + mutex_lock(&ls->ls_waiters_mutex); + + list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) { + if (ktime_equal(lkb->lkb_wait_time, zero)) + continue; + + debug_scanned++; + + us = ktime_to_us(ktime_sub(ktime_get(), lkb->lkb_wait_time)); + + if (us < dlm_config.ci_waitwarn_us) + continue; + + lkb->lkb_wait_time = zero; + + debug_expired++; + if (us > debug_maxus) + debug_maxus = us; + + if (!num_nodes) { + num_nodes = ls->ls_num_nodes; + warned = kmalloc(GFP_KERNEL, num_nodes * sizeof(int)); + if (warned) + memset(warned, 0, num_nodes * sizeof(int)); + } + if (!warned) + continue; + if (nodeid_warned(lkb->lkb_wait_nodeid, num_nodes, warned)) + continue; + + log_error(ls, "waitwarn %x %lld %d us check connection to " + "node %d", lkb->lkb_id, (long long)us, + dlm_config.ci_waitwarn_us, lkb->lkb_wait_nodeid); + } + mutex_unlock(&ls->ls_waiters_mutex); + + if (warned) + kfree(warned); + + if (debug_expired) + log_debug(ls, "scan_waiters %u warn %u over %d us max %lld us", + debug_scanned, debug_expired, + dlm_config.ci_waitwarn_us, (long long)debug_maxus); +} + /* add/remove lkb from global waiters list of lkb's waiting for a reply from a remote node */ -static int add_to_waiters(struct dlm_lkb *lkb, int mstype) +static int add_to_waiters(struct dlm_lkb *lkb, int mstype, int to_nodeid) { struct dlm_ls *ls = lkb->lkb_resource->res_ls; int error = 0; @@ -842,6 +916,8 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) lkb->lkb_wait_count++; lkb->lkb_wait_type = mstype; + lkb->lkb_wait_time = ktime_get(); + lkb->lkb_wait_nodeid = to_nodeid; /* for debugging */ hold_lkb(lkb); list_add(&lkb->lkb_wait_reply, &ls->ls_waiters); out: @@ -1157,6 +1233,16 @@ void dlm_adjust_timeouts(struct dlm_ls *ls) list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) lkb->lkb_timestamp = ktime_add_us(lkb->lkb_timestamp, adj_us); mutex_unlock(&ls->ls_timeout_mutex); + + if (!dlm_config.ci_waitwarn_us) + return; + + mutex_lock(&ls->ls_waiters_mutex); + list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) { + if (ktime_to_us(lkb->lkb_wait_time)) + lkb->lkb_wait_time = ktime_get(); + } + mutex_unlock(&ls->ls_waiters_mutex); } /* lkb is master or local copy */ @@ -2844,12 +2930,12 @@ static int send_common(struct dlm_rsb *r, struct dlm_lkb *lkb, int mstype) struct dlm_mhandle *mh; int to_nodeid, error; - error = add_to_waiters(lkb, mstype); + to_nodeid = r->res_nodeid; + + error = add_to_waiters(lkb, mstype, to_nodeid); if (error) return error; - to_nodeid = r->res_nodeid; - error = create_message(r, lkb, to_nodeid, mstype, &ms, &mh); if (error) goto fail; @@ -2951,12 +3037,12 @@ static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb) struct dlm_mhandle *mh; int to_nodeid, error; - error = add_to_waiters(lkb, DLM_MSG_LOOKUP); + to_nodeid = dlm_dir_nodeid(r); + + error = add_to_waiters(lkb, DLM_MSG_LOOKUP, to_nodeid); if (error) return error; - to_nodeid = dlm_dir_nodeid(r); - error = create_message(r, NULL, to_nodeid, DLM_MSG_LOOKUP, &ms, &mh); if (error) goto fail; diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 88e93c80cc22..265017a7c3e7 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -24,6 +24,7 @@ int dlm_put_lkb(struct dlm_lkb *lkb); void dlm_scan_rsbs(struct dlm_ls *ls); int dlm_lock_recovery_try(struct dlm_ls *ls); void dlm_unlock_recovery(struct dlm_ls *ls); +void dlm_scan_waiters(struct dlm_ls *ls); void dlm_scan_timeout(struct dlm_ls *ls); void dlm_adjust_timeouts(struct dlm_ls *ls); diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index f994a7dfda85..14cbf4099753 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -243,7 +243,6 @@ static struct dlm_ls *find_ls_to_scan(void) static int dlm_scand(void *data) { struct dlm_ls *ls; - int timeout_jiffies = dlm_config.ci_scan_secs * HZ; while (!kthread_should_stop()) { ls = find_ls_to_scan(); @@ -252,13 +251,14 @@ static int dlm_scand(void *data) ls->ls_scan_time = jiffies; dlm_scan_rsbs(ls); dlm_scan_timeout(ls); + dlm_scan_waiters(ls); dlm_unlock_recovery(ls); } else { ls->ls_scan_time += HZ; } - } else { - schedule_timeout_interruptible(timeout_jiffies); + continue; } + schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); } return 0; } -- GitLab From 6bde95ce33e1c2ac9b5cb3d814722105131090ec Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:09:41 -0400 Subject: [PATCH 0246/5560] SELinux: update git tree in MAINTAINERS update the git tree in MAINTAINERS Signed-off-by: Eric Paris --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 560ecce38ff5..3297b8f76640 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5542,10 +5542,11 @@ M: James Morris M: Eric Paris L: selinux@tycho.nsa.gov (subscribers-only, general discussion) W: http://selinuxproject.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git +T: git git://git.infradead.org/users/eparis/selinux.git S: Supported F: include/linux/selinux* F: security/selinux/ +F: scripts/selinux/ APPARMOR SECURITY MODULE M: John Johansen -- GitLab From f50a3ec961f90e38c0311411179d5dfee1412192 Mon Sep 17 00:00:00 2001 From: Kohei Kaigai Date: Fri, 1 Apr 2011 15:39:26 +0100 Subject: [PATCH 0247/5560] selinux: add type_transition with name extension support for selinuxfs The attached patch allows /selinux/create takes optional 4th argument to support TYPE_TRANSITION with name extension for userspace object managers. If 4th argument is not supplied, it shall perform as existing kernel. In fact, the regression test of SE-PostgreSQL works well on the patched kernel. Thanks, Signed-off-by: KaiGai Kohei [manually verify fuzz was not an issue, and it wasn't: eparis] Signed-off-by: Eric Paris --- security/selinux/include/security.h | 4 ++-- security/selinux/selinuxfs.c | 16 ++++++++++++++-- security/selinux/ss/services.c | 17 +++++++++-------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index bfc5218d5840..2cf670864147 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -112,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid, int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, const struct qstr *qstr, u32 *out_sid); -int security_transition_sid_user(u32 ssid, u32 tsid, - u16 tclass, u32 *out_sid); +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, + const char *objname, u32 *out_sid); int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index ea39cb742ae5..973f5a4a6fce 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -753,11 +753,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) static ssize_t sel_write_create(struct file *file, char *buf, size_t size) { char *scon = NULL, *tcon = NULL; + char *namebuf = NULL, *objname = NULL; u32 ssid, tsid, newsid; u16 tclass; ssize_t length; char *newcon = NULL; u32 len; + int nargs; length = task_has_security(current, SECURITY__COMPUTE_CREATE); if (length) @@ -773,9 +775,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) if (!tcon) goto out; + length = -ENOMEM; + namebuf = kzalloc(size + 1, GFP_KERNEL); + if (!namebuf) + goto out; + length = -EINVAL; - if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) + nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf); + if (nargs < 3 || nargs > 4) goto out; + if (nargs == 4) + objname = namebuf; length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); if (length) @@ -785,7 +795,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) if (length) goto out; - length = security_transition_sid_user(ssid, tsid, tclass, &newsid); + length = security_transition_sid_user(ssid, tsid, tclass, + objname, &newsid); if (length) goto out; @@ -804,6 +815,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) length = len; out: kfree(newcon); + kfree(namebuf); kfree(tcon); kfree(scon); return length; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 03f7a4748ee8..39d732145abe 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1360,14 +1360,14 @@ static int compute_sid_handle_invalid_context( static void filename_compute_type(struct policydb *p, struct context *newcontext, u32 scon, u32 tcon, u16 tclass, - const struct qstr *qstr) + const char *objname) { struct filename_trans *ft; for (ft = p->filename_trans; ft; ft = ft->next) { if (ft->stype == scon && ft->ttype == tcon && ft->tclass == tclass && - !strcmp(ft->name, qstr->name)) { + !strcmp(ft->name, objname)) { newcontext->type = ft->otype; return; } @@ -1378,7 +1378,7 @@ static int security_compute_sid(u32 ssid, u32 tsid, u16 orig_tclass, u32 specified, - const struct qstr *qstr, + const char *objname, u32 *out_sid, bool kern) { @@ -1479,9 +1479,9 @@ static int security_compute_sid(u32 ssid, } /* if we have a qstr this is a file trans check so check those rules */ - if (qstr) + if (objname) filename_compute_type(&policydb, &newcontext, scontext->type, - tcontext->type, tclass, qstr); + tcontext->type, tclass, objname); /* Check for class-specific changes. */ if (specified & AVTAB_TRANSITION) { @@ -1539,13 +1539,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, const struct qstr *qstr, u32 *out_sid) { return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, - qstr, out_sid, true); + qstr ? qstr->name : NULL, out_sid, true); } -int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, + const char *objname, u32 *out_sid) { return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, - NULL, out_sid, false); + objname, out_sid, false); } /** -- GitLab From ab3cf6d0f3d2daeef2101a2a97b6c0beee6b70cf Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 1 Apr 2011 22:20:06 +0100 Subject: [PATCH 0248/5560] sfc: Move test of rx_checksum_enabled from nic.c to rx.c This is preparation for using the generic netdev features interface, and should have no effect in itself. Signed-off-by: Ben Hutchings --- drivers/net/sfc/nic.c | 6 ++---- drivers/net/sfc/rx.c | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index e8396614daf3..2594f39c3ba4 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -850,7 +850,6 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) unsigned expected_ptr; bool rx_ev_pkt_ok, discard = false, checksummed; struct efx_rx_queue *rx_queue; - struct efx_nic *efx = channel->efx; /* Basic packet information */ rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT); @@ -873,9 +872,8 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) * UDP/IP, then we can rely on the hardware checksum. */ checksummed = - likely(efx->rx_checksum_enabled) && - (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || - rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP); + rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || + rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP; } else { efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); checksummed = false; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index c0fdb59030fb..fb402c52aaff 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -605,6 +605,9 @@ void __efx_rx_packet(struct efx_channel *channel, skb_record_rx_queue(skb, channel->channel); } + if (unlikely(!efx->rx_checksum_enabled)) + checksummed = false; + if (likely(checksummed || rx_buf->is_page)) { efx_rx_packet_gro(channel, rx_buf, eh, checksummed); return; -- GitLab From 98e778c9aa4f4f75550fa3a31358304e4ce67b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 31 Mar 2011 01:01:35 +0000 Subject: [PATCH 0249/5560] virtio_net: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 46 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 82dba5aaf423..0cb0b0632672 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -710,17 +710,6 @@ static int virtnet_close(struct net_device *dev) return 0; } -static int virtnet_set_tx_csum(struct net_device *dev, u32 data) -{ - struct virtnet_info *vi = netdev_priv(dev); - struct virtio_device *vdev = vi->vdev; - - if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) - return -ENOSYS; - - return ethtool_op_set_tx_hw_csum(dev, data); -} - static void virtnet_set_rx_mode(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -822,10 +811,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) } static const struct ethtool_ops virtnet_ethtool_ops = { - .set_tx_csum = virtnet_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = ethtool_op_set_tso, - .set_ufo = ethtool_op_set_ufo, .get_link = ethtool_op_get_link, }; @@ -912,22 +897,29 @@ static int virtnet_probe(struct virtio_device *vdev) SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ - if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { + if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { /* This opens up the world of extra features. */ - dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { - dev->features |= NETIF_F_TSO | NETIF_F_UFO + dev->hw_features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; + if (csum) + dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { + dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO | NETIF_F_TSO_ECN | NETIF_F_TSO6; } /* Individual feature bits: what can host handle? */ - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) - dev->features |= NETIF_F_TSO; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) - dev->features |= NETIF_F_TSO6; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) - dev->features |= NETIF_F_TSO_ECN; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) - dev->features |= NETIF_F_UFO; + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) + dev->hw_features |= NETIF_F_TSO; + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) + dev->hw_features |= NETIF_F_TSO6; + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) + dev->hw_features |= NETIF_F_TSO_ECN; + if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) + dev->hw_features |= NETIF_F_UFO; + + if (gso) + dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO); + /* (!csum && gso) case will be fixed by register_netdev() */ } /* Configuration may specify what MAC to use. Otherwise random. */ -- GitLab From 78e47fe4194ca7fac2cc29d25f1327db86922724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 1 Apr 2011 20:56:23 -0700 Subject: [PATCH 0250/5560] net: convert SMSC USB net drivers to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a race (not fixed here) in smsc75xx in setting RFE_CTL that's not properly handled via rfe_ctl_lock. Spinlock is not a good tool here, as this has to wait for URB completion (or maybe just submission) after issuing register write request. Otherwise, the rfe_ctl might be changed just after spin_unlock() and device left programmed with other value. smsc95xx has increased hard_header_len for the case of TX checksumming. smsc75xx is fixed to advertise IP+IPV6_CSUM instead of HW_CSUM as it does not use csum_start/csum_offset. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/usb/smsc75xx.c | 124 +++++++++++++------------------------ drivers/net/usb/smsc95xx.c | 83 ++++++------------------- 2 files changed, 63 insertions(+), 144 deletions(-) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 753ee6eb7edd..860a20c938b4 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -65,7 +65,6 @@ struct smsc75xx_priv { struct usbnet *dev; u32 rfe_ctl; u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN]; - bool use_rx_csum; struct mutex dataport_mutex; spinlock_t rfe_ctl_lock; struct work_struct set_multicast; @@ -548,28 +547,6 @@ static void smsc75xx_status(struct usbnet *dev, struct urb *urb) "unexpected interrupt, intdata=0x%08X", intdata); } -/* Enable or disable Rx checksum offload engine */ -static int smsc75xx_set_rx_csum_offload(struct usbnet *dev) -{ - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - unsigned long flags; - int ret; - - spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); - - if (pdata->use_rx_csum) - pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM; - else - pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM); - - spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); - - ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); - check_warn_return(ret, "Error writing RFE_CTL"); - - return 0; -} - static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net) { return MAX_EEPROM_SIZE; @@ -599,34 +576,6 @@ static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev, return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data); } -static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - - return pdata->use_rx_csum; -} - -static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - - pdata->use_rx_csum = !!val; - - return smsc75xx_set_rx_csum_offload(dev); -} - -static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data) -{ - if (data) - netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; - else - netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} - static const struct ethtool_ops smsc75xx_ethtool_ops = { .get_link = usbnet_get_link, .nway_reset = usbnet_nway_reset, @@ -638,12 +587,6 @@ static const struct ethtool_ops smsc75xx_ethtool_ops = { .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len, .get_eeprom = smsc75xx_ethtool_get_eeprom, .set_eeprom = smsc75xx_ethtool_set_eeprom, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .get_rx_csum = smsc75xx_ethtool_get_rx_csum, - .set_rx_csum = smsc75xx_ethtool_set_rx_csum, - .get_tso = ethtool_op_get_tso, - .set_tso = smsc75xx_ethtool_set_tso, }; static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) @@ -782,6 +725,30 @@ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) return usbnet_change_mtu(netdev, new_mtu); } +/* Enable or disable Rx checksum offload engine */ +static int smsc75xx_set_features(struct net_device *netdev, u32 features) +{ + struct usbnet *dev = netdev_priv(netdev); + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + unsigned long flags; + int ret; + + spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); + + if (features & NETIF_F_RXCSUM) + pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM; + else + pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM); + + spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); + /* it's racing here! */ + + ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + check_warn_return(ret, "Error writing RFE_CTL"); + + return 0; +} + static int smsc75xx_reset(struct usbnet *dev) { struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); @@ -960,11 +927,7 @@ static int smsc75xx_reset(struct usbnet *dev) netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl); /* Enable or disable checksum offload engines */ - ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE); - ret = smsc75xx_set_rx_csum_offload(dev); - check_warn_return(ret, "Failed to set rx csum offload: %d", ret); - - smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE); + smsc75xx_set_features(dev->net, dev->net->features); smsc75xx_set_multicast(dev->net); @@ -1037,6 +1000,7 @@ static const struct net_device_ops smsc75xx_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = smsc75xx_ioctl, .ndo_set_multicast_list = smsc75xx_set_multicast, + .ndo_set_features = smsc75xx_set_features, }; static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) @@ -1065,10 +1029,17 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); - pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; + if (DEFAULT_TX_CSUM_ENABLE) { + dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + if (DEFAULT_TSO_ENABLE) + dev->net->features |= NETIF_F_SG | + NETIF_F_TSO | NETIF_F_TSO6; + } + if (DEFAULT_RX_CSUM_ENABLE) + dev->net->features |= NETIF_F_RXCSUM; - /* We have to advertise SG otherwise TSO cannot be enabled */ - dev->net->features |= NETIF_F_SG; + dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM; /* Init all registers */ ret = smsc75xx_reset(dev); @@ -1091,10 +1062,11 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) } } -static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a, - u32 rx_cmd_b) +static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, + u32 rx_cmd_a, u32 rx_cmd_b) { - if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) { + if (!(dev->net->features & NETIF_F_RXCSUM) || + unlikely(rx_cmd_a & RX_CMD_A_LCSM)) { skb->ip_summed = CHECKSUM_NONE; } else { skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT)); @@ -1104,8 +1076,6 @@ static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a, static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) { - struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); - while (skb->len > 0) { u32 rx_cmd_a, rx_cmd_b, align_count, size; struct sk_buff *ax_skb; @@ -1145,11 +1115,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) /* last frame in this batch */ if (skb->len == size) { - if (pdata->use_rx_csum) - smsc75xx_rx_csum_offload(skb, rx_cmd_a, - rx_cmd_b); - else - skb->ip_summed = CHECKSUM_NONE; + smsc75xx_rx_csum_offload(dev, skb, rx_cmd_a, + rx_cmd_b); skb_trim(skb, skb->len - 4); /* remove fcs */ skb->truesize = size + sizeof(struct sk_buff); @@ -1167,11 +1134,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ax_skb->data = packet; skb_set_tail_pointer(ax_skb, size); - if (pdata->use_rx_csum) - smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a, - rx_cmd_b); - else - ax_skb->ip_summed = CHECKSUM_NONE; + smsc75xx_rx_csum_offload(dev, ax_skb, rx_cmd_a, + rx_cmd_b); skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ ax_skb->truesize = size + sizeof(struct sk_buff); diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 727874d9deb6..708f2083898b 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -52,8 +52,6 @@ struct smsc95xx_priv { u32 hash_hi; u32 hash_lo; spinlock_t mac_cr_lock; - bool use_tx_csum; - bool use_rx_csum; }; struct usb_context { @@ -517,22 +515,24 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) } /* Enable or disable Tx & Rx checksum offload engines */ -static int smsc95xx_set_csums(struct usbnet *dev) +static int smsc95xx_set_features(struct net_device *netdev, u32 features) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct usbnet *dev = netdev_priv(netdev); u32 read_buf; - int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf); + int ret; + + ret = smsc95xx_read_reg(dev, COE_CR, &read_buf); if (ret < 0) { netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret); return ret; } - if (pdata->use_tx_csum) + if (features & NETIF_F_HW_CSUM) read_buf |= Tx_COE_EN_; else read_buf &= ~Tx_COE_EN_; - if (pdata->use_rx_csum) + if (features & NETIF_F_RXCSUM) read_buf |= Rx_COE_EN_; else read_buf &= ~Rx_COE_EN_; @@ -576,43 +576,6 @@ static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev, return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data); } -static u32 smsc95xx_ethtool_get_rx_csum(struct net_device *netdev) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - - return pdata->use_rx_csum; -} - -static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - - pdata->use_rx_csum = !!val; - - return smsc95xx_set_csums(dev); -} - -static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - - return pdata->use_tx_csum; -} - -static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val) -{ - struct usbnet *dev = netdev_priv(netdev); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - - pdata->use_tx_csum = !!val; - - ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum); - return smsc95xx_set_csums(dev); -} - static const struct ethtool_ops smsc95xx_ethtool_ops = { .get_link = usbnet_get_link, .nway_reset = usbnet_nway_reset, @@ -624,10 +587,6 @@ static const struct ethtool_ops smsc95xx_ethtool_ops = { .get_eeprom_len = smsc95xx_ethtool_get_eeprom_len, .get_eeprom = smsc95xx_ethtool_get_eeprom, .set_eeprom = smsc95xx_ethtool_set_eeprom, - .get_tx_csum = smsc95xx_ethtool_get_tx_csum, - .set_tx_csum = smsc95xx_ethtool_set_tx_csum, - .get_rx_csum = smsc95xx_ethtool_get_rx_csum, - .set_rx_csum = smsc95xx_ethtool_set_rx_csum, }; static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) @@ -755,7 +714,6 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) static int smsc95xx_reset(struct usbnet *dev) { struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - struct net_device *netdev = dev->net; u32 read_buf, write_buf, burst_cap; int ret = 0, timeout; @@ -975,12 +933,7 @@ static int smsc95xx_reset(struct usbnet *dev) } /* Enable or disable checksum offload engines */ - ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum); - ret = smsc95xx_set_csums(dev); - if (ret < 0) { - netdev_warn(dev->net, "Failed to set csum offload: %d\n", ret); - return ret; - } + smsc95xx_set_features(dev->net, dev->net->features); smsc95xx_set_multicast(dev->net); @@ -1019,6 +972,7 @@ static const struct net_device_ops smsc95xx_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = smsc95xx_ioctl, .ndo_set_multicast_list = smsc95xx_set_multicast, + .ndo_set_features = smsc95xx_set_features, }; static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) @@ -1045,8 +999,12 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) spin_lock_init(&pdata->mac_cr_lock); - pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE; - pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; + if (DEFAULT_TX_CSUM_ENABLE) + dev->net->features |= NETIF_F_HW_CSUM; + if (DEFAULT_RX_CSUM_ENABLE) + dev->net->features |= NETIF_F_RXCSUM; + + dev->net->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM; smsc95xx_init_mac_address(dev); @@ -1056,7 +1014,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->netdev_ops = &smsc95xx_netdev_ops; dev->net->ethtool_ops = &smsc95xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; - dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD; + dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; return 0; } @@ -1080,8 +1038,6 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - while (skb->len > 0) { u32 header, align_count; struct sk_buff *ax_skb; @@ -1123,7 +1079,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) /* last frame in this batch */ if (skb->len == size) { - if (pdata->use_rx_csum) + if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(skb); skb_trim(skb, skb->len - 4); /* remove fcs */ skb->truesize = size + sizeof(struct sk_buff); @@ -1141,7 +1097,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ax_skb->data = packet; skb_set_tail_pointer(ax_skb, size); - if (pdata->use_rx_csum) + if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(ax_skb); skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ ax_skb->truesize = size + sizeof(struct sk_buff); @@ -1174,8 +1130,7 @@ static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb) static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL); + bool csum = skb->ip_summed == CHECKSUM_PARTIAL; int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD; u32 tx_cmd_a, tx_cmd_b; -- GitLab From fb507934fd6faa00b3d833facb53b90c71ddc307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 31 Mar 2011 01:01:35 +0000 Subject: [PATCH 0251/5560] net: convert xen-netfront to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not tested in any way. The original code for offload setting seems broken as it resets the features on every netback reconnect. This will set GSO_ROBUST at device creation time (earlier than connect time). RX checksum offload is forced on - so advertise as it is. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 57 +++++++++++++++----------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index c06f5a09b263..f6e7e2726f6b 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1148,6 +1148,8 @@ static const struct net_device_ops xennet_netdev_ops = { .ndo_change_mtu = xennet_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, + .ndo_fix_features = xennet_fix_features, + .ndo_set_features = xennet_set_features, }; static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) @@ -1209,7 +1211,9 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev netdev->netdev_ops = &xennet_netdev_ops; netif_napi_add(netdev, &np->napi, xennet_poll, 64); - netdev->features = NETIF_F_IP_CSUM; + netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | + NETIF_F_GSO_ROBUST; + netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); SET_NETDEV_DEV(netdev, &dev->dev); @@ -1509,52 +1513,40 @@ static int talk_to_netback(struct xenbus_device *dev, return err; } -static int xennet_set_sg(struct net_device *dev, u32 data) +static u32 xennet_fix_features(struct net_device *dev, u32 features) { - if (data) { - struct netfront_info *np = netdev_priv(dev); - int val; + struct netfront_info *np = netdev_priv(dev); + int val; + if (features & NETIF_F_SG) { if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg", "%d", &val) < 0) val = 0; - if (!val) - return -ENOSYS; - } else if (dev->mtu > ETH_DATA_LEN) - dev->mtu = ETH_DATA_LEN; - return ethtool_op_set_sg(dev, data); -} - -static int xennet_set_tso(struct net_device *dev, u32 data) -{ - if (data) { - struct netfront_info *np = netdev_priv(dev); - int val; + if (!val) + features &= ~NETIF_F_SG; + } + if (features & NETIF_F_TSO) { if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-gso-tcpv4", "%d", &val) < 0) val = 0; + if (!val) - return -ENOSYS; + features &= ~NETIF_F_TSO; } - return ethtool_op_set_tso(dev, data); + return features; } -static void xennet_set_features(struct net_device *dev) +static int xennet_set_features(struct net_device *dev, u32 features) { - /* Turn off all GSO bits except ROBUST. */ - dev->features &= ~NETIF_F_GSO_MASK; - dev->features |= NETIF_F_GSO_ROBUST; - xennet_set_sg(dev, 0); - - /* We need checksum offload to enable scatter/gather and TSO. */ - if (!(dev->features & NETIF_F_IP_CSUM)) - return; + if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) { + netdev_info(dev, "Reducing MTU because no SG offload"); + dev->mtu = ETH_DATA_LEN; + } - if (!xennet_set_sg(dev, 1)) - xennet_set_tso(dev, 1); + return 0; } static int xennet_connect(struct net_device *dev) @@ -1581,7 +1573,7 @@ static int xennet_connect(struct net_device *dev) if (err) return err; - xennet_set_features(dev); + netdev_update_features(dev); spin_lock_bh(&np->rx_lock); spin_lock_irq(&np->tx_lock); @@ -1709,9 +1701,6 @@ static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data) static const struct ethtool_ops xennet_ethtool_ops = { - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = xennet_set_sg, - .set_tso = xennet_set_tso, .get_link = ethtool_op_get_link, .get_sset_count = xennet_get_sset_count, -- GitLab From d7b576545648e487b2958c220542e111f5ac46f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 31 Mar 2011 01:01:35 +0000 Subject: [PATCH 0252/5560] jme: convert offload constraints to ndo_fix_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/jme.c | 77 ++++++++++++----------------------------------- drivers/net/jme.h | 2 -- 2 files changed, 19 insertions(+), 60 deletions(-) diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 994c80939c7a..be4773f54a24 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2230,17 +2230,9 @@ jme_change_mtu(struct net_device *netdev, int new_mtu) jme_restart_rx_engine(jme); } - if (new_mtu > 1900) { - 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_IP_CSUM | NETIF_F_IPV6_CSUM; - if (test_bit(JME_FLAG_TSO, &jme->flags)) - netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; - } - netdev->mtu = new_mtu; + netdev_update_features(netdev); + jme_reset_link(jme); return 0; @@ -2640,19 +2632,20 @@ jme_set_msglevel(struct net_device *netdev, u32 value) } static u32 -jme_get_rx_csum(struct net_device *netdev) +jme_fix_features(struct net_device *netdev, u32 features) { - struct jme_adapter *jme = netdev_priv(netdev); - return jme->reg_rxmcs & RXMCS_CHECKSUM; + if (netdev->mtu > 1900) + features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM); + return features; } static int -jme_set_rx_csum(struct net_device *netdev, u32 on) +jme_set_features(struct net_device *netdev, u32 features) { struct jme_adapter *jme = netdev_priv(netdev); spin_lock_bh(&jme->rxmcs_lock); - if (on) + if (features & NETIF_F_RXCSUM) jme->reg_rxmcs |= RXMCS_CHECKSUM; else jme->reg_rxmcs &= ~RXMCS_CHECKSUM; @@ -2662,42 +2655,6 @@ jme_set_rx_csum(struct net_device *netdev, u32 on) return 0; } -static int -jme_set_tx_csum(struct net_device *netdev, u32 on) -{ - struct jme_adapter *jme = netdev_priv(netdev); - - if (on) { - set_bit(JME_FLAG_TXCSUM, &jme->flags); - if (netdev->mtu <= 1900) - netdev->features |= - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - } else { - clear_bit(JME_FLAG_TXCSUM, &jme->flags); - netdev->features &= - ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - } - - return 0; -} - -static int -jme_set_tso(struct net_device *netdev, u32 on) -{ - struct jme_adapter *jme = netdev_priv(netdev); - - if (on) { - set_bit(JME_FLAG_TSO, &jme->flags); - if (netdev->mtu <= 1900) - netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; - } else { - clear_bit(JME_FLAG_TSO, &jme->flags); - netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - } - - return 0; -} - static int jme_nway_reset(struct net_device *netdev) { @@ -2839,11 +2796,6 @@ static const struct ethtool_ops jme_ethtool_ops = { .get_link = jme_get_link, .get_msglevel = jme_get_msglevel, .set_msglevel = jme_set_msglevel, - .get_rx_csum = jme_get_rx_csum, - .set_rx_csum = jme_set_rx_csum, - .set_tx_csum = jme_set_tx_csum, - .set_tso = jme_set_tso, - .set_sg = ethtool_op_set_sg, .nway_reset = jme_nway_reset, .get_eeprom_len = jme_get_eeprom_len, .get_eeprom = jme_get_eeprom, @@ -2903,6 +2855,8 @@ static const struct net_device_ops jme_netdev_ops = { .ndo_change_mtu = jme_change_mtu, .ndo_tx_timeout = jme_tx_timeout, .ndo_vlan_rx_register = jme_vlan_rx_register, + .ndo_fix_features = jme_fix_features, + .ndo_set_features = jme_set_features, }; static int __devinit @@ -2957,6 +2911,12 @@ 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->hw_features = NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | + NETIF_F_SG | + NETIF_F_TSO | + NETIF_F_TSO6 | + NETIF_F_RXCSUM; netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | @@ -3040,8 +3000,9 @@ jme_init_one(struct pci_dev *pdev, jme->reg_txpfc = 0; jme->reg_pmcs = PMCS_MFEN; jme->reg_gpreg1 = GPREG1_DEFAULT; - set_bit(JME_FLAG_TXCSUM, &jme->flags); - set_bit(JME_FLAG_TSO, &jme->flags); + + if (jme->reg_rxmcs & RXMCS_CHECKSUM) + netdev->features |= NETIF_F_RXCSUM; /* * Get Max Read Req Size from PCI Config Space diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 8bf30451e821..e9aaeca96abc 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -468,8 +468,6 @@ struct jme_adapter { enum jme_flags_bits { JME_FLAG_MSI = 1, JME_FLAG_SSET = 2, - JME_FLAG_TXCSUM = 3, - JME_FLAG_TSO = 4, JME_FLAG_POLL = 5, JME_FLAG_SHUTDOWN = 6, }; -- GitLab From a2c725fa39b79fcc3f09151e847cc006ff0d4389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 31 Mar 2011 01:01:35 +0000 Subject: [PATCH 0253/5560] veth: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should probably get TSO available as it's basically a loopback device. Offloads are left disabled by default - as before. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/veth.c | 45 +++++---------------------------------------- 1 file changed, 5 insertions(+), 40 deletions(-) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 2de9b90c5f8f..654228849951 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -36,7 +36,6 @@ struct veth_net_stats { struct veth_priv { struct net_device *peer; struct veth_net_stats __percpu *stats; - unsigned ip_summed; }; /* @@ -99,47 +98,10 @@ static void veth_get_ethtool_stats(struct net_device *dev, data[0] = priv->peer->ifindex; } -static u32 veth_get_rx_csum(struct net_device *dev) -{ - struct veth_priv *priv; - - priv = netdev_priv(dev); - return priv->ip_summed == CHECKSUM_UNNECESSARY; -} - -static int veth_set_rx_csum(struct net_device *dev, u32 data) -{ - struct veth_priv *priv; - - priv = netdev_priv(dev); - priv->ip_summed = data ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE; - return 0; -} - -static u32 veth_get_tx_csum(struct net_device *dev) -{ - return (dev->features & NETIF_F_NO_CSUM) != 0; -} - -static int veth_set_tx_csum(struct net_device *dev, u32 data) -{ - if (data) - dev->features |= NETIF_F_NO_CSUM; - else - dev->features &= ~NETIF_F_NO_CSUM; - return 0; -} - static const struct ethtool_ops veth_ethtool_ops = { .get_settings = veth_get_settings, .get_drvinfo = veth_get_drvinfo, .get_link = ethtool_op_get_link, - .get_rx_csum = veth_get_rx_csum, - .set_rx_csum = veth_set_rx_csum, - .get_tx_csum = veth_get_tx_csum, - .set_tx_csum = veth_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, .get_strings = veth_get_strings, .get_sset_count = veth_get_sset_count, .get_ethtool_stats = veth_get_ethtool_stats, @@ -168,8 +130,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) /* don't change ip_summed == CHECKSUM_PARTIAL, as that will cause bad checksum on forwarded packets */ - if (skb->ip_summed == CHECKSUM_NONE) - skb->ip_summed = rcv_priv->ip_summed; + if (skb->ip_summed == CHECKSUM_NONE && + rcv->features & NETIF_F_RXCSUM) + skb->ip_summed = CHECKSUM_UNNECESSARY; length = skb->len; if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS) @@ -304,6 +267,8 @@ static void veth_setup(struct net_device *dev) dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; dev->destructor = veth_dev_free; + + dev->hw_features = NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; } /* -- GitLab From e9403c8437cf3721e7901c1a8fcb06bb642a7e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 1 Apr 2011 20:58:37 -0700 Subject: [PATCH 0254/5560] net: convert sunhme/sungem network drivers to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Side effects: - TX offloads (HW csum, scatter-gather) can be toggled now - RX checksum is reported correctly now (it's always active) Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/sungem.c | 3 ++- drivers/net/sunhme.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index c1a344829b54..a935426cbe63 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -3146,7 +3146,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gp->phy_mii.def ? gp->phy_mii.def->name : "no"); /* GEM can do it all... */ - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX; + dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; + dev->features |= dev->hw_features | NETIF_F_RXCSUM | NETIF_F_LLTX; if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index eb4f59fb01e9..80e907df36b4 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2788,7 +2788,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i dev->ethtool_ops = &hme_ethtool_ops; /* Happy Meal can do it all... */ - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; + dev->features |= dev->hw_features | NETIF_F_RXCSUM; dev->irq = op->archdata.irqs[0]; @@ -3113,7 +3114,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, dev->dma = 0; /* Happy Meal can do it all... */ - dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; + dev->features |= dev->hw_features | NETIF_F_RXCSUM; #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) /* Hook up PCI register/descriptor accessors. */ -- GitLab From 6cb6a27c45cec9184302c2e350b3593c64bc7f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sat, 2 Apr 2011 22:48:47 -0700 Subject: [PATCH 0255/5560] net: Call netdev_features_change() from netdev_update_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue FEAT_CHANGE notification when features are changed by netdev_update_features(). This will allow changes made by extra constraints on e.g. MTU change to be properly propagated like changes via ethtool. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 + net/core/dev.c | 23 +++++++++++++++++------ net/core/ethtool.c | 6 +++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5eeb2cd3631c..423a5447d2ed 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2550,6 +2550,7 @@ static inline u32 netdev_get_wanted_features(struct net_device *dev) } u32 netdev_increment_features(u32 all, u32 one, u32 mask); u32 netdev_fix_features(struct net_device *dev, u32 features); +int __netdev_update_features(struct net_device *dev); void netdev_update_features(struct net_device *dev); void netif_stacked_transfer_operstate(const struct net_device *rootdev, diff --git a/net/core/dev.c b/net/core/dev.c index 3da9fb06d47a..02f56376fe99 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5236,7 +5236,7 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) } EXPORT_SYMBOL(netdev_fix_features); -void netdev_update_features(struct net_device *dev) +int __netdev_update_features(struct net_device *dev) { u32 features; int err = 0; @@ -5250,7 +5250,7 @@ void netdev_update_features(struct net_device *dev) features = netdev_fix_features(dev, features); if (dev->features == features) - return; + return 0; netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n", dev->features, features); @@ -5258,12 +5258,23 @@ void netdev_update_features(struct net_device *dev) if (dev->netdev_ops->ndo_set_features) err = dev->netdev_ops->ndo_set_features(dev, features); - if (!err) - dev->features = features; - else if (err < 0) + if (unlikely(err < 0)) { netdev_err(dev, "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", err, features, dev->features); + return -1; + } + + if (!err) + dev->features = features; + + return 1; +} + +void netdev_update_features(struct net_device *dev) +{ + if (__netdev_update_features(dev)) + netdev_features_change(dev); } EXPORT_SYMBOL(netdev_update_features); @@ -5430,7 +5441,7 @@ int register_netdevice(struct net_device *dev) goto err_uninit; dev->reg_state = NETREG_REGISTERED; - netdev_update_features(dev); + __netdev_update_features(dev); /* * Default initial state at registry is that the diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 74ead9eca126..439e4b0e1312 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -317,7 +317,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr) dev->wanted_features &= ~features[0].valid; dev->wanted_features |= features[0].valid & features[0].requested; - netdev_update_features(dev); + __netdev_update_features(dev); if ((dev->wanted_features ^ dev->features) & features[0].valid) ret |= ETHTOOL_F_WISH; @@ -499,7 +499,7 @@ static int ethtool_set_one_feature(struct net_device *dev, else dev->wanted_features &= ~mask; - netdev_update_features(dev); + __netdev_update_features(dev); return 0; } @@ -551,7 +551,7 @@ int __ethtool_set_flags(struct net_device *dev, u32 data) dev->wanted_features = (dev->wanted_features & ~changed) | data; - netdev_update_features(dev); + __netdev_update_features(dev); return 0; } -- GitLab From 8a0427bb688eae86a8bb939b6a74e5aa00aa035a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sat, 2 Apr 2011 22:49:12 -0700 Subject: [PATCH 0256/5560] vlan: convert VLAN devices to use ndo_fix_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: get_flags was actually broken, because it should return the flags capped with vlan_features. This is now done implicitly by limiting netdev->hw_features. RX checksumming offload control is (and was) broken, as there was no way before to say whether it's done for tagged packets. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- net/8021q/vlan.c | 8 ++----- net/8021q/vlan_dev.c | 50 +++++++++++++------------------------------- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 7850412f52b7..e47600b4e2e3 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -327,10 +327,6 @@ static void vlan_sync_address(struct net_device *dev, static void vlan_transfer_features(struct net_device *dev, struct net_device *vlandev) { - u32 old_features = vlandev->features; - - 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) @@ -341,8 +337,8 @@ 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 - if (old_features != vlandev->features) - netdev_features_change(vlandev); + + netdev_update_features(vlandev); } static void __vlan_device_event(struct net_device *dev, unsigned long event) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index e34ea9e5e28b..b84a46b30c0c 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -704,8 +704,8 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_DORMANT))) | (1<<__LINK_STATE_PRESENT); - dev->features |= real_dev->features & real_dev->vlan_features; - dev->features |= NETIF_F_LLTX; + dev->hw_features = real_dev->vlan_features & NETIF_F_ALL_TX_OFFLOADS; + dev->features |= real_dev->vlan_features | NETIF_F_LLTX; dev->gso_max_size = real_dev->gso_max_size; /* ipv6 shared card related stuff */ @@ -759,6 +759,17 @@ static void vlan_dev_uninit(struct net_device *dev) } } +static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) +{ + struct net_device *real_dev = vlan_dev_info(dev)->real_dev; + + features &= (real_dev->features | NETIF_F_LLTX); + if (dev_ethtool_get_rx_csum(real_dev)) + features |= NETIF_F_RXCSUM; + + return features; +} + static int vlan_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -774,18 +785,6 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev, strcpy(info->fw_version, "N/A"); } -static u32 vlan_ethtool_get_rx_csum(struct net_device *dev) -{ - const struct vlan_dev_info *vlan = vlan_dev_info(dev); - return dev_ethtool_get_rx_csum(vlan->real_dev); -} - -static u32 vlan_ethtool_get_flags(struct net_device *dev) -{ - const struct vlan_dev_info *vlan = vlan_dev_info(dev); - return dev_ethtool_get_flags(vlan->real_dev); -} - static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { @@ -823,32 +822,10 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st return stats; } -static int vlan_ethtool_set_tso(struct net_device *dev, u32 data) -{ - if (data) { - struct net_device *real_dev = vlan_dev_info(dev)->real_dev; - - /* Underlying device must support TSO for VLAN-tagged packets - * and must have TSO enabled now. - */ - if (!(real_dev->vlan_features & NETIF_F_TSO)) - return -EOPNOTSUPP; - if (!(real_dev->features & NETIF_F_TSO)) - return -EINVAL; - dev->features |= NETIF_F_TSO; - } else { - dev->features &= ~NETIF_F_TSO; - } - return 0; -} - static const struct ethtool_ops vlan_ethtool_ops = { .get_settings = vlan_ethtool_get_settings, .get_drvinfo = vlan_ethtool_get_drvinfo, .get_link = ethtool_op_get_link, - .get_rx_csum = vlan_ethtool_get_rx_csum, - .get_flags = vlan_ethtool_get_flags, - .set_tso = vlan_ethtool_set_tso, }; static const struct net_device_ops vlan_netdev_ops = { @@ -874,6 +851,7 @@ static const struct net_device_ops vlan_netdev_ops = { .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, .ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target, #endif + .ndo_fix_features = vlan_dev_fix_features, }; void vlan_setup(struct net_device *dev) -- GitLab From 363618f013f2f11a1089b610748beb5de93b8630 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 1 Apr 2011 14:50:43 -0600 Subject: [PATCH 0257/5560] ASoC: Name jack GPIOs based on jack not codec snd_soc_jack_gpio has a name field. Use that name when registering the IRQ, since this is far more informative than the codec driver name. This shows up in /proc/interrupts. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-jack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index fcab80b36a37..6203a72d57af 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -325,7 +325,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, gpio_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - jack->codec->dev->driver->name, + gpios[i].name, &gpios[i]); if (ret) goto err; -- GitLab From 04368d051a6aa90c14a3ca5a48f60aca2f6ecdd1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 2 Apr 2011 03:43:15 +0200 Subject: [PATCH 0258/5560] ASoC: Properly handle spitz MIC GPIO This patch firstly restructurizes the code a bit by getting rid of continuous checking for machine type in spitz_mic_bias(). Then the patch properly requests the MIC GPIO in the spitz_init() and frees it in spitz_exit(). Signed-off-by: Marek Vasut Signed-off-by: Mark Brown --- sound/soc/pxa/spitz.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 8e1571350630..b253d864868a 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -42,6 +42,7 @@ static int spitz_jack_func; static int spitz_spk_func; +static int spitz_mic_gpio; static void spitz_ext_control(struct snd_soc_codec *codec) { @@ -217,14 +218,7 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, static int spitz_mic_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - if (machine_is_borzoi() || machine_is_spitz()) - gpio_set_value(SPITZ_GPIO_MIC_BIAS, - SND_SOC_DAPM_EVENT_ON(event)); - - if (machine_is_akita()) - gpio_set_value(AKITA_GPIO_MIC_BIAS, - SND_SOC_DAPM_EVENT_ON(event)); - + gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -339,22 +333,45 @@ static int __init spitz_init(void) if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) return -ENODEV; + if (machine_is_borzoi() || machine_is_spitz()) + spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS; + else + spitz_mic_gpio = AKITA_GPIO_MIC_BIAS; + + ret = gpio_request(spitz_mic_gpio, "MIC GPIO"); + if (ret) + goto err1; + + ret = gpio_direction_output(spitz_mic_gpio, 0); + if (ret) + goto err2; + spitz_snd_device = platform_device_alloc("soc-audio", -1); - if (!spitz_snd_device) - return -ENOMEM; + if (!spitz_snd_device) { + ret = -ENOMEM; + goto err2; + } platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); - ret = platform_device_add(spitz_snd_device); + ret = platform_device_add(spitz_snd_device); if (ret) - platform_device_put(spitz_snd_device); + goto err3; + + return 0; +err3: + platform_device_put(spitz_snd_device); +err2: + gpio_free(spitz_mic_gpio); +err1: return ret; } static void __exit spitz_exit(void) { platform_device_unregister(spitz_snd_device); + gpio_free(spitz_mic_gpio); } module_init(spitz_init); -- GitLab From 6ea0c34dac89611126455537552cffe6c7e832ad Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Apr 2011 01:41:32 +0200 Subject: [PATCH 0259/5560] percpu: Unify input section names The two percpu helper macros have the section names duplicated. So create a new define to merge the two. This also allows arches who need to link things more directly themselves to avoid duplicating the input sections in their linker script. Signed-off-by: Mike Frysinger Signed-off-by: Tejun Heo --- include/asm-generic/vmlinux.lds.h | 44 +++++++++++++++++-------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 32c45e5fe0ab..bf90fbc6688b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -687,6 +687,28 @@ *(.discard.*) \ } +/** + * PERCPU_INPUT - the percpu input sections + * @cacheline: cacheline size + * + * The core percpu section names and core symbols which do not rely + * directly upon load addresses. + * + * @cacheline is used to align subsections to avoid false cacheline + * sharing between subsections for different purposes. + */ +#define PERCPU_INPUT(cacheline) \ + VMLINUX_SYMBOL(__per_cpu_start) = .; \ + *(.data..percpu..first) \ + . = ALIGN(PAGE_SIZE); \ + *(.data..percpu..page_aligned) \ + . = ALIGN(cacheline); \ + *(.data..percpu..readmostly) \ + . = ALIGN(cacheline); \ + *(.data..percpu) \ + *(.data..percpu..shared_aligned) \ + VMLINUX_SYMBOL(__per_cpu_end) = .; + /** * PERCPU_VADDR - define output section for percpu area * @cacheline: cacheline size @@ -715,16 +737,7 @@ VMLINUX_SYMBOL(__per_cpu_load) = .; \ .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__per_cpu_start) = .; \ - *(.data..percpu..first) \ - . = ALIGN(PAGE_SIZE); \ - *(.data..percpu..page_aligned) \ - . = ALIGN(cacheline); \ - *(.data..percpu..readmostly) \ - . = ALIGN(cacheline); \ - *(.data..percpu) \ - *(.data..percpu..shared_aligned) \ - VMLINUX_SYMBOL(__per_cpu_end) = .; \ + PERCPU_INPUT(cacheline) \ } phdr \ . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu); @@ -745,16 +758,7 @@ . = ALIGN(align); \ .data..percpu : AT(ADDR(.data..percpu) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__per_cpu_load) = .; \ - VMLINUX_SYMBOL(__per_cpu_start) = .; \ - *(.data..percpu..first) \ - . = ALIGN(PAGE_SIZE); \ - *(.data..percpu..page_aligned) \ - . = ALIGN(cacheline); \ - *(.data..percpu..readmostly) \ - . = ALIGN(cacheline); \ - *(.data..percpu) \ - *(.data..percpu..shared_aligned) \ - VMLINUX_SYMBOL(__per_cpu_end) = .; \ + PERCPU_INPUT(cacheline) \ } -- GitLab From 1deac632fc3dcff33a6df3e82ef10c738ac13fe6 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 1 Apr 2011 20:11:50 +0200 Subject: [PATCH 0260/5560] signal: prepare_signal(SIGCONT) shouldn't play with TIF_SIGPENDING prepare_signal(SIGCONT) should never set TIF_SIGPENDING or wake up the TASK_INTERRUPTIBLE threads. We are going to call complete_signal() which should pick the right thread correctly. All we need is to wake up the TASK_STOPPED threads. If the task was stopped, it can't return to usermode without taking ->siglock. Otherwise we don't care, and the spurious TIF_SIGPENDING can't be useful. The comment says: * If there is a handler for SIGCONT, we must make * sure that no thread returns to user mode before * we post the signal It is not clear what this means. Probably, "when there's only a single thread" and this continues to be true. Otherwise, even if this SIGCONT is not private, with or without this change only one thread can dequeue SIGCONT, other threads can happily return to user mode before before that thread handles this signal. Note also that wake_up_state(t, __TASK_STOPPED) can't race with the task which changes its state, TASK_STOPPED state is protected by ->siglock as well. In short: when it comes to signal delivery, SIGCONT is the normal signal and does not need any special support. Signed-off-by: Oleg Nesterov Signed-off-by: Tejun Heo --- kernel/signal.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index f799a054f292..38ea9e2f1831 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -788,37 +788,14 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) } else if (sig == SIGCONT) { unsigned int why; /* - * Remove all stop signals from all queues, - * and wake all threads. + * Remove all stop signals from all queues, wake all threads. */ rm_from_queue(SIG_KERNEL_STOP_MASK, &signal->shared_pending); t = p; do { - unsigned int state; - task_clear_group_stop_pending(t); - rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); - /* - * If there is a handler for SIGCONT, we must make - * sure that no thread returns to user mode before - * we post the signal, in case it was the only - * thread eligible to run the signal handler--then - * it must not do anything between resuming and - * running the handler. With the TIF_SIGPENDING - * flag set, the thread will pause and acquire the - * siglock that we hold now and until we've queued - * the pending signal. - * - * Wake up the stopped thread _after_ setting - * TIF_SIGPENDING - */ - state = __TASK_STOPPED; - if (sig_user_defined(t, SIGCONT) && !sigismember(&t->blocked, SIGCONT)) { - set_tsk_thread_flag(t, TIF_SIGPENDING); - state |= TASK_INTERRUPTIBLE; - } - wake_up_state(t, state); + wake_up_state(t, __TASK_STOPPED); } while_each_thread(p, t); /* -- GitLab From 780006eac2fe7f4d2582da16a096e5a44c4767ff Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 1 Apr 2011 20:12:16 +0200 Subject: [PATCH 0261/5560] signal: do_signal_stop: Remove the unneeded task_clear_group_stop_pending() PF_EXITING or TASK_STOPPED has already called task_participate_group_stop() and cleared its ->group_stop. No need to do task_clear_group_stop_pending() when we start the new group stop. Add a small comment to explain the !task_is_stopped() check. Note that this check is not exactly right and it can lead to unnecessary stop later if the thread is TASK_PTRACED. What we need is task_participated_in_group_stop(), this will be solved later. Signed-off-by: Oleg Nesterov Signed-off-by: Tejun Heo --- kernel/signal.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 38ea9e2f1831..e9abc69dc0d8 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1866,7 +1866,8 @@ static int do_signal_stop(int signr) * still in effect and then receive a stop signal and * initiate another group stop. This deviates from the * usual behavior as two consecutive stop signals can't - * cause two group stops when !ptraced. + * cause two group stops when !ptraced. That is why we + * also check !task_is_stopped(t) below. * * The condition can be distinguished by testing whether * SIGNAL_STOP_STOPPED is already set. Don't generate @@ -1896,8 +1897,6 @@ static int do_signal_stop(int signr) t->group_stop |= signr | gstop; sig->group_stop_count++; signal_wake_up(t, 0); - } else { - task_clear_group_stop_pending(t); } } } -- GitLab From ee77f075921730b2b465880f9fd4367003bdab39 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 1 Apr 2011 20:12:38 +0200 Subject: [PATCH 0262/5560] signal: Turn SIGNAL_STOP_DEQUEUED into GROUP_STOP_DEQUEUED This patch moves SIGNAL_STOP_DEQUEUED from signal_struct->flags to task_struct->group_stop, and thus makes it per-thread. Like SIGNAL_STOP_DEQUEUED, GROUP_STOP_DEQUEUED can be false-positive after return from get_signal_to_deliver(), this is fine. The only purpose of this bit is: we can drop ->siglock after __dequeue_signal() returns the sig_kernel_stop() signal and before we call do_signal_stop(), in this case we must not miss SIGCONT if it comes in between. But, unlike SIGNAL_STOP_DEQUEUED, GROUP_STOP_DEQUEUED can not be false-positive in do_signal_stop() if multiple threads dequeue the sig_kernel_stop() signal at the same time. Consider two threads T1 and T2, SIGTTIN has a hanlder. - T1 dequeues SIGTSTP and sets SIGNAL_STOP_DEQUEUED, then it drops ->siglock - SIGCONT comes and clears SIGNAL_STOP_DEQUEUED, SIGTSTP should be cancelled. - T2 dequeues SIGTTIN and sets SIGNAL_STOP_DEQUEUED again. Since we have a handler we should not stop, T2 returns to usermode to run the handler. - T1 continues, calls do_signal_stop() and wrongly starts the group stop because SIGNAL_STOP_DEQUEUED was restored in between. With or without this change: - we need to do something with ptrace_signal() which can return SIGSTOP, but this needs another discussion - SIGSTOP can be lost if it races with the mt exec, will be fixed later. Signed-off-by: Oleg Nesterov Signed-off-by: Tejun Heo --- include/linux/sched.h | 6 +++--- kernel/signal.c | 14 ++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 456d80ed3b78..8cef82d4cf77 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -652,9 +652,8 @@ struct signal_struct { * Bits in flags field of signal_struct. */ #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ -#define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */ -#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ -#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ +#define SIGNAL_STOP_CONTINUED 0x00000002 /* SIGCONT since WCONTINUED reap */ +#define SIGNAL_GROUP_EXIT 0x00000004 /* group exit in progress */ /* * Pending notifications to parent. */ @@ -1779,6 +1778,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define GROUP_STOP_PENDING (1 << 16) /* task should stop for group stop */ #define GROUP_STOP_CONSUME (1 << 17) /* consume group stop count */ #define GROUP_STOP_TRAPPING (1 << 18) /* switching from STOPPED to TRACED */ +#define GROUP_STOP_DEQUEUED (1 << 19) /* stop signal dequeued */ extern void task_clear_group_stop_pending(struct task_struct *task); diff --git a/kernel/signal.c b/kernel/signal.c index e9abc69dc0d8..4f7312b49b2d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -254,7 +254,8 @@ static void task_clear_group_stop_trapping(struct task_struct *task) */ void task_clear_group_stop_pending(struct task_struct *task) { - task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME); + task->group_stop &= ~(GROUP_STOP_PENDING | GROUP_STOP_CONSUME | + GROUP_STOP_DEQUEUED); } /** @@ -602,7 +603,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) * is to alert stop-signal processing code when another * processor has come along and cleared the flag. */ - tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; + current->group_stop |= GROUP_STOP_DEQUEUED; } if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) { /* @@ -821,13 +822,6 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) signal->flags = why | SIGNAL_STOP_CONTINUED; signal->group_stop_count = 0; signal->group_exit_code = 0; - } else { - /* - * We are not stopped, but there could be a stop - * signal in the middle of being processed after - * being removed from the queue. Clear that too. - */ - signal->flags &= ~SIGNAL_STOP_DEQUEUED; } } @@ -1855,7 +1849,7 @@ static int do_signal_stop(int signr) /* signr will be recorded in task->group_stop for retries */ WARN_ON_ONCE(signr & ~GROUP_STOP_SIGMASK); - if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || + if (!likely(current->group_stop & GROUP_STOP_DEQUEUED) || unlikely(signal_group_exit(sig))) return 0; /* -- GitLab From 321fb561971ba0f10ce18c0f8a4b9fbfc7cef4b9 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 1 Apr 2011 20:13:01 +0200 Subject: [PATCH 0263/5560] ptrace: ptrace_check_attach() should not do s/STOPPED/TRACED/ After "ptrace: Clean transitions between TASK_STOPPED and TRACED" d79fdd6d96f46fabb779d86332e3677c6f5c2a4f, ptrace_check_attach() should never see a TASK_STOPPED tracee and s/STOPPED/TRACED/ is no longer legal. Add the warning. Note: ptrace_check_attach() can be greatly simplified, in particular it doesn't need tasklist. But I'd prefer another patch for that. Signed-off-by: Oleg Nesterov Signed-off-by: Tejun Heo --- kernel/ptrace.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 43485866749a..20d5efdeee02 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -112,16 +112,14 @@ int ptrace_check_attach(struct task_struct *child, int kill) */ read_lock(&tasklist_lock); if ((child->ptrace & PT_PTRACED) && child->parent == current) { - ret = 0; /* * child->sighand can't be NULL, release_task() * does ptrace_unlink() before __exit_signal(). */ spin_lock_irq(&child->sighand->siglock); - if (task_is_stopped(child)) - child->state = TASK_TRACED; - else if (!task_is_traced(child) && !kill) - ret = -ESRCH; + WARN_ON_ONCE(task_is_stopped(child)); + if (task_is_traced(child) || kill) + ret = 0; spin_unlock_irq(&child->sighand->siglock); } read_unlock(&tasklist_lock); -- GitLab From 8f7b01a178b8e6a7b663a1bbaa1710756d67b69b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 3 Apr 2011 17:21:00 -0700 Subject: [PATCH 0264/5560] xen: netfront: fix declaration order Must declare xennet_fix_features() and xennet_set_features() before using them. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 72 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index f6e7e2726f6b..0cfe4ccf92d2 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1140,6 +1140,42 @@ static void xennet_uninit(struct net_device *dev) gnttab_free_grant_references(np->gref_rx_head); } +static u32 xennet_fix_features(struct net_device *dev, u32 features) +{ + struct netfront_info *np = netdev_priv(dev); + int val; + + if (features & NETIF_F_SG) { + if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg", + "%d", &val) < 0) + val = 0; + + if (!val) + features &= ~NETIF_F_SG; + } + + if (features & NETIF_F_TSO) { + if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, + "feature-gso-tcpv4", "%d", &val) < 0) + val = 0; + + if (!val) + features &= ~NETIF_F_TSO; + } + + return features; +} + +static int xennet_set_features(struct net_device *dev, u32 features) +{ + if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) { + netdev_info(dev, "Reducing MTU because no SG offload"); + dev->mtu = ETH_DATA_LEN; + } + + return 0; +} + static const struct net_device_ops xennet_netdev_ops = { .ndo_open = xennet_open, .ndo_uninit = xennet_uninit, @@ -1513,42 +1549,6 @@ static int talk_to_netback(struct xenbus_device *dev, return err; } -static u32 xennet_fix_features(struct net_device *dev, u32 features) -{ - struct netfront_info *np = netdev_priv(dev); - int val; - - if (features & NETIF_F_SG) { - if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg", - "%d", &val) < 0) - val = 0; - - if (!val) - features &= ~NETIF_F_SG; - } - - if (features & NETIF_F_TSO) { - if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, - "feature-gso-tcpv4", "%d", &val) < 0) - val = 0; - - if (!val) - features &= ~NETIF_F_TSO; - } - - return features; -} - -static int xennet_set_features(struct net_device *dev, u32 features) -{ - if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) { - netdev_info(dev, "Reducing MTU because no SG offload"); - dev->mtu = ETH_DATA_LEN; - } - - return 0; -} - static int xennet_connect(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); -- GitLab From 17f60a7da150fdd0cfb9756f86a262daa72c835f Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:07:50 -0400 Subject: [PATCH 0265/5560] capabilites: allow the application of capability limits to usermode helpers There is no way to limit the capabilities of usermodehelpers. This problem reared its head recently when someone complained that any user with cap_net_admin was able to load arbitrary kernel modules, even though the user didn't have cap_sys_module. The reason is because the actual load is done by a usermode helper and those always have the full cap set. This patch addes new sysctls which allow us to bound the permissions of usermode helpers. /proc/sys/kernel/usermodehelper/bset /proc/sys/kernel/usermodehelper/inheritable You must have CAP_SYS_MODULE and CAP_SETPCAP to change these (changes are &= ONLY). When the kernel launches a usermodehelper it will do so with these as the bset and pI. -v2: make globals static create spinlock to protect globals -v3: require both CAP_SETPCAP and CAP_SYS_MODULE -v4: fix the typo s/CAP_SET_PCAP/CAP_SETPCAP/ because I didn't commit Signed-off-by: Eric Paris No-objection-from: Serge E. Hallyn Acked-by: David Howells Acked-by: Serge E. Hallyn Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- include/linux/kmod.h | 3 ++ kernel/kmod.c | 100 +++++++++++++++++++++++++++++++++++++++++++ kernel/sysctl.c | 6 +++ 3 files changed, 109 insertions(+) diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 6efd7a78de6a..79bb98d71858 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -24,6 +24,7 @@ #include #include #include +#include #define KMOD_PATH_LEN 256 @@ -109,6 +110,8 @@ call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) NULL, NULL, NULL); } +extern struct ctl_table usermodehelper_table[]; + extern void usermodehelper_init(void); extern int usermodehelper_disable(void); diff --git a/kernel/kmod.c b/kernel/kmod.c index 9cd0591c96a2..06fdea2819b6 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,13 @@ extern int max_threads; static struct workqueue_struct *khelper_wq; +#define CAP_BSET (void *)1 +#define CAP_PI (void *)2 + +static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; +static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; +static DEFINE_SPINLOCK(umh_sysctl_lock); + #ifdef CONFIG_MODULES /* @@ -132,6 +140,7 @@ EXPORT_SYMBOL(__request_module); static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; + struct cred *new; int retval; spin_lock_irq(¤t->sighand->siglock); @@ -153,6 +162,19 @@ static int ____call_usermodehelper(void *data) goto fail; } + retval = -ENOMEM; + new = prepare_kernel_cred(current); + if (!new) + goto fail; + + spin_lock(&umh_sysctl_lock); + new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset); + new->cap_inheritable = cap_intersect(usermodehelper_inheritable, + new->cap_inheritable); + spin_unlock(&umh_sysctl_lock); + + commit_creds(new); + retval = kernel_execve(sub_info->path, (const char *const *)sub_info->argv, (const char *const *)sub_info->envp); @@ -418,6 +440,84 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, } EXPORT_SYMBOL(call_usermodehelper_exec); +static int proc_cap_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct ctl_table t; + unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; + kernel_cap_t new_cap; + int err, i; + + if (write && (!capable(CAP_SETPCAP) || + !capable(CAP_SYS_MODULE))) + return -EPERM; + + /* + * convert from the global kernel_cap_t to the ulong array to print to + * userspace if this is a read. + */ + spin_lock(&umh_sysctl_lock); + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) { + if (table->data == CAP_BSET) + cap_array[i] = usermodehelper_bset.cap[i]; + else if (table->data == CAP_PI) + cap_array[i] = usermodehelper_inheritable.cap[i]; + else + BUG(); + } + spin_unlock(&umh_sysctl_lock); + + t = *table; + t.data = &cap_array; + + /* + * actually read or write and array of ulongs from userspace. Remember + * these are least significant 32 bits first + */ + err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos); + if (err < 0) + return err; + + /* + * convert from the sysctl array of ulongs to the kernel_cap_t + * internal representation + */ + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) + new_cap.cap[i] = cap_array[i]; + + /* + * Drop everything not in the new_cap (but don't add things) + */ + spin_lock(&umh_sysctl_lock); + if (write) { + if (table->data == CAP_BSET) + usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); + if (table->data == CAP_PI) + usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); + } + spin_unlock(&umh_sysctl_lock); + + return 0; +} + +struct ctl_table usermodehelper_table[] = { + { + .procname = "bset", + .data = CAP_BSET, + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), + .mode = 0600, + .proc_handler = proc_cap_handler, + }, + { + .procname = "inheritable", + .data = CAP_PI, + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), + .mode = 0600, + .proc_handler = proc_cap_handler, + }, + { } +}; + void __init usermodehelper_init(void) { khelper_wq = create_singlethread_workqueue("khelper"); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c0bb32414b17..965134bed6cd 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -615,6 +616,11 @@ static struct ctl_table kern_table[] = { .mode = 0555, .child = random_table, }, + { + .procname = "usermodehelper", + .mode = 0555, + .child = usermodehelper_table, + }, { .procname = "overflowuid", .data = &overflowuid, -- GitLab From 4bf2ea77dba76a22f49db3c10773896aaeeb8f66 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:28 -0400 Subject: [PATCH 0266/5560] capabilities: do not special case exec of init When the global init task is exec'd we have special case logic to make sure the pE is not reduced. There is no reason for this. If init wants to drop it's pE is should be allowed to do so. Remove this special logic. Signed-off-by: Eric Paris Acked-by: Serge Hallyn Acked-by: David Howells Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- security/commoncap.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/security/commoncap.c b/security/commoncap.c index f20e984ccfb4..a93b3b733079 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -529,15 +529,10 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) new->suid = new->fsuid = new->euid; new->sgid = new->fsgid = new->egid; - /* For init, we want to retain the capabilities set in the initial - * task. Thus we skip the usual capability rules - */ - if (!is_global_init(current)) { - if (effective) - new->cap_effective = new->cap_permitted; - else - cap_clear(new->cap_effective); - } + if (effective) + new->cap_effective = new->cap_permitted; + else + cap_clear(new->cap_effective); bprm->cap_effective = effective; /* -- GitLab From ffa8e59df047d57e812a04f7d6baf6a25c652c0c Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:34 -0400 Subject: [PATCH 0267/5560] capabilities: do not drop CAP_SETPCAP from the initial task In olden' days of yore CAP_SETPCAP had special meaning for the init task. We actually have code to make sure that CAP_SETPCAP wasn't in pE of things using the init_cred. But CAP_SETPCAP isn't so special any more and we don't have a reason to special case dropping it for init or kthreads.... Signed-off-by: Eric Paris Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- include/linux/capability.h | 6 ++++-- kernel/capability.c | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index 16ee8b49a200..11d562863e49 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -412,7 +412,6 @@ extern const kernel_cap_t __cap_init_eff_set; # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) -# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ CAP_FS_MASK_B1 } }) @@ -423,10 +422,10 @@ extern const kernel_cap_t __cap_init_eff_set; #endif /* _KERNEL_CAPABILITY_U32S != 2 */ #define CAP_INIT_INH_SET CAP_EMPTY_SET +#define CAP_INIT_EFF_SET CAP_FULL_SET # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) # define cap_set_full(c) do { (c) = __cap_full_set; } while (0) -# define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0) #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) @@ -547,6 +546,9 @@ extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); extern bool task_ns_capable(struct task_struct *t, int cap); +extern const kernel_cap_t __cap_empty_set; +extern const kernel_cap_t __cap_full_set; + /** * nsown_capable - Check superior capability to one's own user_ns * @cap: The capability in question diff --git a/kernel/capability.c b/kernel/capability.c index bf0c734d0c12..2a374d512ead 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -23,11 +23,9 @@ const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; const kernel_cap_t __cap_full_set = CAP_FULL_SET; -const kernel_cap_t __cap_init_eff_set = CAP_INIT_EFF_SET; EXPORT_SYMBOL(__cap_empty_set); EXPORT_SYMBOL(__cap_full_set); -EXPORT_SYMBOL(__cap_init_eff_set); int file_caps_enabled = 1; -- GitLab From 5163b583a036b103c3cec7171d6731c125773ed6 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:39 -0400 Subject: [PATCH 0268/5560] capabilities: delete unused cap_set_full unused code. Clean it up. Signed-off-by: Eric Paris Acked-by: David Howells Acked-by: Andrew G. Morgan Signed-off-by: James Morris --- include/linux/capability.h | 2 -- kernel/capability.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index 11d562863e49..8d0da30dad23 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -425,7 +425,6 @@ extern const kernel_cap_t __cap_init_eff_set; #define CAP_INIT_EFF_SET CAP_FULL_SET # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) -# define cap_set_full(c) do { (c) = __cap_full_set; } while (0) #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) @@ -547,7 +546,6 @@ extern bool ns_capable(struct user_namespace *ns, int cap); extern bool task_ns_capable(struct task_struct *t, int cap); extern const kernel_cap_t __cap_empty_set; -extern const kernel_cap_t __cap_full_set; /** * nsown_capable - Check superior capability to one's own user_ns diff --git a/kernel/capability.c b/kernel/capability.c index 2a374d512ead..14ea4210a530 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -22,10 +22,8 @@ */ const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; -const kernel_cap_t __cap_full_set = CAP_FULL_SET; EXPORT_SYMBOL(__cap_empty_set); -EXPORT_SYMBOL(__cap_full_set); int file_caps_enabled = 1; -- GitLab From a3232d2fa2e3cbab3e76d91cdae5890fee8a4034 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 1 Apr 2011 17:08:45 -0400 Subject: [PATCH 0269/5560] capabilities: delete all CAP_INIT macros The CAP_INIT macros of INH, BSET, and EFF made sense at one point in time, but now days they aren't helping. Just open code the logic in the init_cred. Signed-off-by: Eric Paris Acked-by: David Howells Signed-off-by: James Morris --- include/linux/capability.h | 3 --- include/linux/init_task.h | 7 ------- kernel/cred.c | 6 +++--- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index 8d0da30dad23..04fed72809de 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -421,9 +421,6 @@ extern const kernel_cap_t __cap_init_eff_set; #endif /* _KERNEL_CAPABILITY_U32S != 2 */ -#define CAP_INIT_INH_SET CAP_EMPTY_SET -#define CAP_INIT_EFF_SET CAP_FULL_SET - # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index caa151fbebb7..1f277204de34 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -83,13 +83,6 @@ extern struct group_info init_groups; #define INIT_IDS #endif -/* - * Because of the reduced scope of CAP_SETPCAP when filesystem - * capabilities are in effect, it is safe to allow CAP_SETPCAP to - * be available in the default configuration. - */ -# define CAP_INIT_BSET CAP_FULL_SET - #ifdef CONFIG_RCU_BOOST #define INIT_TASK_RCU_BOOST() \ .rcu_boost_mutex = NULL, diff --git a/kernel/cred.c b/kernel/cred.c index 5557b55048df..b982f0863ae9 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -49,10 +49,10 @@ struct cred init_cred = { .magic = CRED_MAGIC, #endif .securebits = SECUREBITS_DEFAULT, - .cap_inheritable = CAP_INIT_INH_SET, + .cap_inheritable = CAP_EMPTY_SET, .cap_permitted = CAP_FULL_SET, - .cap_effective = CAP_INIT_EFF_SET, - .cap_bset = CAP_INIT_BSET, + .cap_effective = CAP_FULL_SET, + .cap_bset = CAP_FULL_SET, .user = INIT_USER, .group_info = &init_groups, #ifdef CONFIG_KEYS -- GitLab From 95b8fbada76d978ce13a26785f8b85ff54478bb2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 3 Apr 2011 13:31:06 +0000 Subject: [PATCH 0270/5560] mISDN: fix "persistant" typo Signed-off-by: Jan Engelhardt Signed-off-by: David S. Miller --- drivers/isdn/mISDN/layer2.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index 4ae75053c9d2..9e1610f40e16 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c @@ -1640,7 +1640,7 @@ l2_tei_remove(struct FsmInst *fi, int event, void *arg) } static void -l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) { struct layer2 *l2 = fi->userdata; struct sk_buff *skb = arg; @@ -1654,7 +1654,7 @@ l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) } static void -l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) { struct layer2 *l2 = fi->userdata; struct sk_buff *skb = arg; @@ -1671,7 +1671,7 @@ l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) } static void -l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) { struct layer2 *l2 = fi->userdata; struct sk_buff *skb = arg; @@ -1685,7 +1685,7 @@ l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) } static void -l2_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_persistent_da(struct FsmInst *fi, int event, void *arg) { struct layer2 *l2 = fi->userdata; struct sk_buff *skb = arg; @@ -1829,14 +1829,14 @@ static struct FsmNode L2FnList[] = {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, - {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da}, + {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da}, {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, - {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da}, - {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da}, - {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da}, - {ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da}, + {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da}, + {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da}, + {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da}, + {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da}, + {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, }; static int -- GitLab From 43b3e1898206a1e385c9cb06f6040ea83a58b638 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 4 Apr 2011 09:32:46 +0100 Subject: [PATCH 0271/5560] ARM: 6860/1: OMAP4: Move the privately used SMP boot functions to OMAP specific header. Header files in arch/arm/*/include/mach included from arch/arm/include/asm/*.h are there to provide necessary definitions for either the rest of the kernel or the ARM specific parts. They shouldn't be polluted with *any* platform private stuff which is not absolutely necessary to satisfy the rest of the kernel. Hence move the OMAP specific SMP boot functions to different header instead of keeping them in 'plat/smp.h' which gets included indirectly by linux/smp.h The patch is outcome of the discussion in below thread: http://www.spinics.net/lists/arm-kernel/msg120363.html Cc: Tony Lindgren Signed-off-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/mach-omap2/include/mach/omap4-common.h | 7 +++++++ arch/arm/plat-omap/include/plat/smp.h | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h index de441c05a6a6..e4bd87619734 100644 --- a/arch/arm/mach-omap2/include/mach/omap4-common.h +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h @@ -33,4 +33,11 @@ extern void __iomem *gic_dist_base_addr; extern void __init gic_init_irq(void); extern void omap_smc1(u32 fn, u32 arg); +#ifdef CONFIG_SMP +/* Needed for secondary core boot */ +extern void omap_secondary_startup(void); +extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); +extern void omap_auxcoreboot_addr(u32 cpu_addr); +extern u32 omap_read_auxcoreboot0(void); +#endif #endif diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index 7a10257909ef..416e9d579fde 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h @@ -19,12 +19,6 @@ #include -/* Needed for secondary core boot */ -extern void omap_secondary_startup(void); -extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); -extern void omap_auxcoreboot_addr(u32 cpu_addr); -extern u32 omap_read_auxcoreboot0(void); - /* * We use Soft IRQ1 as the IPI */ -- GitLab From 78caf66cb568f2b0c63bf8f87cff2fe1583dd9d0 Mon Sep 17 00:00:00 2001 From: Torsten Schenk Date: Mon, 4 Apr 2011 11:45:28 +0200 Subject: [PATCH 0272/5560] ALSA: 6fire - Update kernel configuration Kernel configuration updated: - experimental dependency removed - description updated Signed-off-by: Torsten Schenk Signed-off-by: Takashi Iwai --- sound/usb/Kconfig | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 97724d8fa9f6..cc47a9caec9d 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -100,7 +100,6 @@ config SND_USB_US122L config SND_USB_6FIRE tristate "TerraTec DMX 6Fire USB" - depends on EXPERIMENTAL select FW_LOADER select SND_RAWMIDI select SND_PCM @@ -108,11 +107,9 @@ config SND_USB_6FIRE Say Y here to include support for TerraTec 6fire DMX USB interface. You will need firmware files in order to be able to use the device - after it has been coldstarted. This driver currently does not support - firmware loading for all devices. If you own such a device, - you could start windows and let the windows driver upload - the firmware. As long as you do not unplug your device from power, - it should be usable. + after it has been coldstarted. An install script for the firmware + and further help can be found at + http://sixfireusb.sourceforge.net endif # SND_USB -- GitLab From e220fa3bf503d63039fa8e0398a1c252d24663f9 Mon Sep 17 00:00:00 2001 From: Torsten Schenk Date: Mon, 4 Apr 2011 11:47:50 +0200 Subject: [PATCH 0273/5560] ALSA: 6fire - Fix pcm rate assignment Completion of signedness bug for pcm_runtime.rate: variable will never get assigned a negative value now. Signed-off-by: Torsten Schenk Signed-off-by: Takashi Iwai --- sound/usb/6fire/pcm.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index ba62c7468ba8..2110cbf35474 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -456,7 +456,7 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub) /* all substreams closed? if so, stop streaming */ if (!rt->playback.instance && !rt->capture.instance) { usb6fire_pcm_stream_stop(rt); - rt->rate = -1; + rt->rate = ARRAY_SIZE(rates); } } mutex_unlock(&rt->stream_mutex); @@ -480,7 +480,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; - int i; int ret; if (rt->panic) @@ -493,12 +492,10 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) sub->period_off = 0; if (rt->stream_state == STREAM_DISABLED) { - for (i = 0; i < ARRAY_SIZE(rates); i++) - if (alsa_rt->rate == rates[i]) { - rt->rate = i; + for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++) + if (alsa_rt->rate == rates[rt->rate]) break; - } - if (i == ARRAY_SIZE(rates)) { + if (rt->rate == ARRAY_SIZE(rates)) { mutex_unlock(&rt->stream_mutex); snd_printk("invalid rate %d in prepare.\n", alsa_rt->rate); @@ -613,7 +610,7 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip) rt->chip = chip; rt->stream_state = STREAM_DISABLED; - rt->rate = -1; + rt->rate = ARRAY_SIZE(rates); init_waitqueue_head(&rt->stream_wait_queue); mutex_init(&rt->stream_mutex); -- GitLab From 58c54fa47f5de976959767fa8d9bb857eee4c4e5 Mon Sep 17 00:00:00 2001 From: Torsten Schenk Date: Mon, 4 Apr 2011 11:49:00 +0200 Subject: [PATCH 0274/5560] ALSA: 6fire - Add support for S32_LE format Added support for sample format s32_le. Signed-off-by: Torsten Schenk Signed-off-by: Takashi Iwai --- sound/usb/6fire/pcm.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 2110cbf35474..7ea698793d43 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -64,7 +64,7 @@ static const struct snd_pcm_hardware pcm_hw = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH, - .formats = SNDRV_PCM_FMTBIT_S24_LE, + .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | @@ -228,7 +228,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) unsigned int total_length = 0; struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; - u32 *src = (u32 *) urb->buffer; + u32 *src = NULL; u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off * (alsa_rt->frame_bits >> 3)); u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size @@ -244,7 +244,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) else frame_count = 0; - src = (u32 *) (urb->buffer + total_length); + if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) + src = (u32 *) (urb->buffer + total_length); + else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) + src = (u32 *) (urb->buffer - 1 + total_length); + else + return; src++; /* skip leading 4 bytes of every packet */ total_length += urb->packets[i].length; for (frame = 0; frame < frame_count; frame++) { @@ -274,9 +279,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub, * (alsa_rt->frame_bits >> 3)); u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size * (alsa_rt->frame_bits >> 3)); - u32 *dest = (u32 *) urb->buffer; + u32 *dest; int bytes_per_frame = alsa_rt->channels << 2; + if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) + dest = (u32 *) (urb->buffer - 1); + else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) + dest = (u32 *) (urb->buffer); + else { + snd_printk(KERN_ERR PREFIX "Unknown sample format."); + return; + } + for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { /* at least 4 header bytes for valid packet. * after that: 32 bits per sample for analog channels */ -- GitLab From b84610b95f7e7bcd1cd9ecf3e8506a59e9f557fd Mon Sep 17 00:00:00 2001 From: Torsten Schenk Date: Mon, 4 Apr 2011 11:49:57 +0200 Subject: [PATCH 0275/5560] ALSA: 6fire - Improve firmware loader Firmware loader: magical device bytes check updated (accepts all device versions now and accepts possibly loaded firmware, if it is knowing to be working) Signed-off-by: Torsten Schenk Signed-off-by: Takashi Iwai --- sound/usb/6fire/firmware.c | 44 +++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 9081a54a9c6c..e720035fbd1e 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -3,12 +3,6 @@ * * Firmware loader * - * Currently not working for all devices. To be able to use the device - * in linux, it is also possible to let the windows driver upload the firmware. - * For that, start the computer in windows and reboot. - * As long as the device is connected to the power supply, no firmware reload - * needs to be performed. - * * Author: Torsten Schenk * Created: Jan 01, 2011 * Version: 0.3.0 @@ -72,6 +66,10 @@ static const u8 ep_w_max_packet_size[] = { 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ }; +static const u8 known_fw_versions[][4] = { + { 0x03, 0x01, 0x0b, 0x00 } +}; + struct ihex_record { u16 address; u8 len; @@ -363,6 +361,25 @@ static int usb6fire_fw_fpga_upload( return 0; } +/* check, if the firmware version the devices has currently loaded + * is known by this driver. 'version' needs to have 4 bytes version + * info data. */ +static int usb6fire_fw_check(u8 *version) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++) + if (!memcmp(version, known_fw_versions + i, 4)) + return 0; + + snd_printk(KERN_ERR PREFIX "invalid fimware version in device: " + "%02x %02x %02x %02x. " + "please reconnect to power. if this failure " + "still happens, check your firmware installation.", + version[0], version[1], version[2], version[3]); + return -EINVAL; +} + int usb6fire_fw_init(struct usb_interface *intf) { int i; @@ -378,9 +395,7 @@ int usb6fire_fw_init(struct usb_interface *intf) "firmware state.\n"); return ret; } - if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 - || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7] - != 0x00) { + if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) { snd_printk(KERN_ERR PREFIX "unknown device firmware state " "received from device: "); for (i = 0; i < 8; i++) @@ -389,7 +404,7 @@ int usb6fire_fw_init(struct usb_interface *intf) return -EIO; } /* do we need fpga loader ezusb firmware? */ - if (buffer[3] == 0x01 && buffer[6] == 0x19) { + if (buffer[3] == 0x01) { ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6firel2.ihx", 0, NULL, 0); if (ret < 0) @@ -397,7 +412,10 @@ int usb6fire_fw_init(struct usb_interface *intf) return FW_NOT_READY; } /* do we need fpga firmware and application ezusb firmware? */ - else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { + else if (buffer[3] == 0x02) { + ret = usb6fire_fw_check(buffer + 4); + if (ret < 0) + return ret; ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); if (ret < 0) return ret; @@ -410,8 +428,8 @@ int usb6fire_fw_init(struct usb_interface *intf) return FW_NOT_READY; } /* all fw loaded? */ - else if (buffer[3] == 0x03 && buffer[6] == 0x0b) - return 0; + else if (buffer[3] == 0x03) + return usb6fire_fw_check(buffer + 4); /* unknown data? */ else { snd_printk(KERN_ERR PREFIX "unknown device firmware state " -- GitLab From 2475b0d407614ea5a41b8325d45c614d94087088 Mon Sep 17 00:00:00 2001 From: Torsten Schenk Date: Mon, 4 Apr 2011 11:50:53 +0200 Subject: [PATCH 0276/5560] ALSA: 6fire - Add support of digital-thru mixer Digital Thru mixer element added (device can act as converter optical<->coax) Signed-off-by: Torsten Schenk Signed-off-by: Takashi Iwai --- sound/usb/6fire/control.c | 105 ++++++++++++++++++++++++++++++++++++++ sound/usb/6fire/control.h | 17 ++++++ sound/usb/6fire/pcm.c | 62 ++++++---------------- 3 files changed, 137 insertions(+), 47 deletions(-) diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index 248463511186..ac828eff1a63 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c @@ -65,6 +65,15 @@ init_data[] = { { 0 } /* TERMINATING ENTRY */ }; +static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; +/* values to write to soundcard register for all samplerates */ +static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; +static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; + +enum { + DIGITAL_THRU_ONLY_SAMPLERATE = 3 +}; + static void usb6fire_control_master_vol_update(struct control_runtime *rt) { struct comm_runtime *comm_rt = rt->chip->comm; @@ -95,6 +104,67 @@ static void usb6fire_control_opt_coax_update(struct control_runtime *rt) } } +static int usb6fire_control_set_rate(struct control_runtime *rt, int rate) +{ + int ret; + struct usb_device *device = rt->chip->dev; + struct comm_runtime *comm_rt = rt->chip->comm; + + if (rate < 0 || rate >= CONTROL_N_RATES) + return -EINVAL; + + ret = usb_set_interface(device, 1, rates_altsetting[rate]); + if (ret < 0) + return ret; + + /* set soundcard clock */ + ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate], + rates_6fire_vh[rate]); + if (ret < 0) + return ret; + + return 0; +} + +static int usb6fire_control_set_channels( + struct control_runtime *rt, int n_analog_out, + int n_analog_in, bool spdif_out, bool spdif_in) +{ + int ret; + struct comm_runtime *comm_rt = rt->chip->comm; + + /* enable analog inputs and outputs + * (one bit per stereo-channel) */ + ret = comm_rt->write16(comm_rt, 0x02, 0x02, + (1 << (n_analog_out / 2)) - 1, + (1 << (n_analog_in / 2)) - 1); + if (ret < 0) + return ret; + + /* disable digital inputs and outputs */ + /* TODO: use spdif_x to enable/disable digital channels */ + ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00); + if (ret < 0) + return ret; + + return 0; +} + +static int usb6fire_control_streaming_update(struct control_runtime *rt) +{ + struct comm_runtime *comm_rt = rt->chip->comm; + + if (comm_rt) { + if (!rt->usb_streaming && rt->digital_thru_switch) + usb6fire_control_set_rate(rt, + DIGITAL_THRU_ONLY_SAMPLERATE); + return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, + (rt->usb_streaming ? 0x01 : 0x00) | + (rt->digital_thru_switch ? 0x08 : 0x00)); + } + return -EINVAL; +} + static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -195,6 +265,28 @@ static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol, return 0; } +static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct control_runtime *rt = snd_kcontrol_chip(kcontrol); + int changed = 0; + + if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) { + rt->digital_thru_switch = ucontrol->value.integer.value[0]; + usb6fire_control_streaming_update(rt); + changed = 1; + } + return changed; +} + +static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct control_runtime *rt = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = rt->digital_thru_switch; + return 0; +} + static struct __devinitdata snd_kcontrol_new elements[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -223,6 +315,15 @@ static struct __devinitdata snd_kcontrol_new elements[] = { .get = usb6fire_control_opt_coax_get, .put = usb6fire_control_opt_coax_put }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Digital Thru Playback Route", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_ctl_boolean_mono_info, + .get = usb6fire_control_digital_thru_get, + .put = usb6fire_control_digital_thru_put + }, {} }; @@ -238,6 +339,9 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip) return -ENOMEM; rt->chip = chip; + rt->update_streaming = usb6fire_control_streaming_update; + rt->set_rate = usb6fire_control_set_rate; + rt->set_channels = usb6fire_control_set_channels; i = 0; while (init_data[i].type) { @@ -249,6 +353,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip) usb6fire_control_opt_coax_update(rt); usb6fire_control_line_phono_update(rt); usb6fire_control_master_vol_update(rt); + usb6fire_control_streaming_update(rt); i = 0; while (elements[i].name) { diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h index b534c777ab02..8f5aeead2e3d 100644 --- a/sound/usb/6fire/control.h +++ b/sound/usb/6fire/control.h @@ -21,12 +21,29 @@ enum { CONTROL_MAX_ELEMENTS = 32 }; +enum { + CONTROL_RATE_44KHZ, + CONTROL_RATE_48KHZ, + CONTROL_RATE_88KHZ, + CONTROL_RATE_96KHZ, + CONTROL_RATE_176KHZ, + CONTROL_RATE_192KHZ, + CONTROL_N_RATES +}; + struct control_runtime { + int (*update_streaming)(struct control_runtime *rt); + int (*set_rate)(struct control_runtime *rt, int rate); + int (*set_channels)(struct control_runtime *rt, int n_analog_out, + int n_analog_in, bool spdif_out, bool spdif_in); + struct sfire_chip *chip; struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; bool opt_coax_switch; bool line_phono_switch; + bool digital_thru_switch; + bool usb_streaming; u8 master_vol; }; diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 7ea698793d43..b137b25865cc 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -17,26 +17,23 @@ #include "pcm.h" #include "chip.h" #include "comm.h" +#include "control.h" enum { OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 }; /* keep next two synced with - * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */ + * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE + * and CONTROL_RATE_XXX in control.h */ static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; -static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; static const int rates_alsaid[] = { SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; -/* values to write to soundcard register for all samplerates */ -static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; -static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; - enum { /* settings for pcm */ OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 }; @@ -48,15 +45,6 @@ enum { /* pcm streaming states */ STREAM_STOPPING }; -enum { /* pcm sample rates (also index into RATES_XXX[]) */ - RATE_44KHZ, - RATE_48KHZ, - RATE_88KHZ, - RATE_96KHZ, - RATE_176KHZ, - RATE_192KHZ -}; - static const struct snd_pcm_hardware pcm_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -87,57 +75,34 @@ static const struct snd_pcm_hardware pcm_hw = { static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) { int ret; - struct usb_device *device = rt->chip->dev; - struct comm_runtime *comm_rt = rt->chip->comm; + struct control_runtime *ctrl_rt = rt->chip->control; - if (rt->rate >= ARRAY_SIZE(rates)) - return -EINVAL; - /* disable streaming */ - ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00); + ctrl_rt->usb_streaming = false; + ret = ctrl_rt->update_streaming(ctrl_rt); if (ret < 0) { snd_printk(KERN_ERR PREFIX "error stopping streaming while " "setting samplerate %d.\n", rates[rt->rate]); return ret; } - ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]); - if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error setting interface " - "altsetting %d for samplerate %d.\n", - rates_altsetting[rt->rate], rates[rt->rate]); - return ret; - } - - /* set soundcard clock */ - ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate], - rates_6fire_vh[rt->rate]); + ret = ctrl_rt->set_rate(ctrl_rt, rt->rate); if (ret < 0) { snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", rates[rt->rate]); return ret; } - /* enable analog inputs and outputs - * (one bit per stereo-channel) */ - ret = comm_rt->write16(comm_rt, 0x02, 0x02, - (1 << (OUT_N_CHANNELS / 2)) - 1, - (1 << (IN_N_CHANNELS / 2)) - 1); + ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS, + false, false); if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error initializing analog channels " + snd_printk(KERN_ERR PREFIX "error initializing channels " "while setting samplerate %d.\n", rates[rt->rate]); return ret; } - /* disable digital inputs and outputs */ - ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00); - if (ret < 0) { - snd_printk(KERN_ERR PREFIX "error initializing digital " - "channels while setting samplerate %d.\n", - rates[rt->rate]); - return ret; - } - ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01); + ctrl_rt->usb_streaming = true; + ret = ctrl_rt->update_streaming(ctrl_rt); if (ret < 0) { snd_printk(KERN_ERR PREFIX "error starting streaming while " "setting samplerate %d.\n", rates[rt->rate]); @@ -168,12 +133,15 @@ static struct pcm_substream *usb6fire_pcm_get_substream( static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) { int i; + struct control_runtime *ctrl_rt = rt->chip->control; if (rt->stream_state != STREAM_DISABLED) { for (i = 0; i < PCM_N_URBS; i++) { usb_kill_urb(&rt->in_urbs[i].instance); usb_kill_urb(&rt->out_urbs[i].instance); } + ctrl_rt->usb_streaming = false; + ctrl_rt->update_streaming(ctrl_rt); rt->stream_state = STREAM_DISABLED; } } -- GitLab From d8e4f9aed82c68b60f81b2e7977c46868d51062f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 4 Apr 2011 12:43:23 +0200 Subject: [PATCH 0277/5560] ALSA: core - Don't use "default' for default The card-id parser assigns the string "default" when no appropriate word is found in the card name. But this string may confuse the alsa-lib, so better to avoid. Use "Default" now instead. Signed-off-by: Takashi Iwai --- sound/core/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/init.c b/sound/core/init.c index a0080aa45ae9..30ecad41403c 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -514,7 +514,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) id = card->id; if (*id == '\0') - strcpy(id, "default"); + strcpy(id, "Default"); while (1) { if (loops-- == 0) { -- GitLab From 177525d26e31806d71653f74bbec13574b97892c Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Sun, 3 Apr 2011 20:58:28 +0200 Subject: [PATCH 0278/5560] eradicate bashisms in scripts/patch-kernel Silence a remaining annoying (or worse, irritating - "is my entire patched tree broken now!?") bashism-related message that occurs when /bin/sh is configured to instead deploy dash, a POSIX-compliant shell, as is the pretty much standard case on e.g. Debian. Current kernel version is 2.6.38 ( Flesh-Eating Bats with Fangs) ===> linux-2.6.38.patch-kernel_test/scripts/patch-kernel: line 253: [: =: unary operator expected <=== cannot find patch file: patch-2.6.39 Signed-off-by: Andreas Mohr Signed-off-by: Michal Marek --- scripts/patch-kernel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/patch-kernel b/scripts/patch-kernel index 46a59cae3a0a..20fb25c23382 100755 --- a/scripts/patch-kernel +++ b/scripts/patch-kernel @@ -250,7 +250,7 @@ while : # incrementing SUBLEVEL (s in v.p.s) do CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" EXTRAVER= - if [ $STOPFULLVERSION = $CURRENTFULLVERSION ]; then + if [ x$STOPFULLVERSION = x$CURRENTFULLVERSION ]; then echo "Stopping at $CURRENTFULLVERSION base as requested." break fi -- GitLab From 7f5c6d4f665bb57a19a34ce1fb16cc708c04f219 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 4 Apr 2011 17:04:03 +0200 Subject: [PATCH 0279/5560] netfilter: get rid of atomic ops in fast path We currently use a percpu spinlock to 'protect' rule bytes/packets counters, after various attempts to use RCU instead. Lately we added a seqlock so that get_counters() can run without blocking BH or 'writers'. But we really only need the seqcount in it. Spinlock itself is only locked by the current/owner cpu, so we can remove it completely. This cleanups api, using correct 'writer' vs 'reader' semantic. At replace time, the get_counters() call makes sure all cpus are done using the old table. Signed-off-by: Eric Dumazet Cc: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 96 +++++++++++++----------------- net/ipv4/netfilter/arp_tables.c | 18 +++--- net/ipv4/netfilter/ip_tables.c | 28 ++++----- net/ipv6/netfilter/ip6_tables.c | 19 +++--- net/netfilter/x_tables.c | 9 +-- 5 files changed, 80 insertions(+), 90 deletions(-) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 37219525ff6f..32cddf78b13e 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -456,72 +456,60 @@ extern void xt_proto_fini(struct net *net, u_int8_t af); extern struct xt_table_info *xt_alloc_table_info(unsigned int size); extern void xt_free_table_info(struct xt_table_info *info); -/* - * Per-CPU spinlock associated with per-cpu table entries, and - * with a counter for the "reading" side that allows a recursive - * reader to avoid taking the lock and deadlocking. - * - * "reading" is used by ip/arp/ip6 tables rule processing which runs per-cpu. - * It needs to ensure that the rules are not being changed while the packet - * is being processed. In some cases, the read lock will be acquired - * twice on the same CPU; this is okay because of the count. - * - * "writing" is used when reading counters. - * During replace any readers that are using the old tables have to complete - * before freeing the old table. This is handled by the write locking - * necessary for reading the counters. +/** + * xt_recseq - recursive seqcount for netfilter use + * + * Packet processing changes the seqcount only if no recursion happened + * get_counters() can use read_seqcount_begin()/read_seqcount_retry(), + * because we use the normal seqcount convention : + * Low order bit set to 1 if a writer is active. */ -struct xt_info_lock { - seqlock_t lock; - unsigned char readers; -}; -DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks); +DECLARE_PER_CPU(seqcount_t, xt_recseq); -/* - * Note: we need to ensure that preemption is disabled before acquiring - * the per-cpu-variable, so we do it as a two step process rather than - * using "spin_lock_bh()". - * - * We _also_ need to disable bottom half processing before updating our - * nesting count, to make sure that the only kind of re-entrancy is this - * code being called by itself: since the count+lock is not an atomic - * operation, we can allow no races. +/** + * xt_write_recseq_begin - start of a write section * - * _Only_ that special combination of being per-cpu and never getting - * re-entered asynchronously means that the count is safe. + * Begin packet processing : all readers must wait the end + * 1) Must be called with preemption disabled + * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add()) + * Returns : + * 1 if no recursion on this cpu + * 0 if recursion detected */ -static inline void xt_info_rdlock_bh(void) +static inline unsigned int xt_write_recseq_begin(void) { - struct xt_info_lock *lock; + unsigned int addend; - local_bh_disable(); - lock = &__get_cpu_var(xt_info_locks); - if (likely(!lock->readers++)) - write_seqlock(&lock->lock); -} + /* + * Low order bit of sequence is set if we already + * called xt_write_recseq_begin(). + */ + addend = (__this_cpu_read(xt_recseq.sequence) + 1) & 1; -static inline void xt_info_rdunlock_bh(void) -{ - struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks); + /* + * This is kind of a write_seqcount_begin(), but addend is 0 or 1 + * We dont check addend value to avoid a test and conditional jump, + * since addend is most likely 1 + */ + __this_cpu_add(xt_recseq.sequence, addend); + smp_wmb(); - if (likely(!--lock->readers)) - write_sequnlock(&lock->lock); - local_bh_enable(); + return addend; } -/* - * The "writer" side needs to get exclusive access to the lock, - * regardless of readers. This must be called with bottom half - * processing (and thus also preemption) disabled. +/** + * xt_write_recseq_end - end of a write section + * @addend: return value from previous xt_write_recseq_begin() + * + * End packet processing : all readers can proceed + * 1) Must be called with preemption disabled + * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add()) */ -static inline void xt_info_wrlock(unsigned int cpu) -{ - write_seqlock(&per_cpu(xt_info_locks, cpu).lock); -} - -static inline void xt_info_wrunlock(unsigned int cpu) +static inline void xt_write_recseq_end(unsigned int addend) { - write_sequnlock(&per_cpu(xt_info_locks, cpu).lock); + /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */ + smp_wmb(); + __this_cpu_add(xt_recseq.sequence, addend); } /* diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 4b5d457c2d76..2ea743336836 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -260,6 +260,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, void *table_base; const struct xt_table_info *private; struct xt_action_param acpar; + unsigned int addend; if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) return NF_DROP; @@ -267,7 +268,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, indev = in ? in->name : nulldevname; outdev = out ? out->name : nulldevname; - xt_info_rdlock_bh(); + local_bh_disable(); + addend = xt_write_recseq_begin(); private = table->private; table_base = private->entries[smp_processor_id()]; @@ -338,7 +340,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, /* Verdict */ break; } while (!acpar.hotdrop); - xt_info_rdunlock_bh(); + xt_write_recseq_end(addend); + local_bh_enable(); if (acpar.hotdrop) return NF_DROP; @@ -712,7 +715,7 @@ static void get_counters(const struct xt_table_info *t, unsigned int i; for_each_possible_cpu(cpu) { - seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; + seqcount_t *s = &per_cpu(xt_recseq, cpu); i = 0; xt_entry_foreach(iter, t->entries[cpu], t->size) { @@ -720,10 +723,10 @@ static void get_counters(const struct xt_table_info *t, unsigned int start; do { - start = read_seqbegin(lock); + start = read_seqcount_begin(s); bcnt = iter->counters.bcnt; pcnt = iter->counters.pcnt; - } while (read_seqretry(lock, start)); + } while (read_seqcount_retry(s, start)); ADD_COUNTER(counters[i], bcnt, pcnt); ++i; @@ -1115,6 +1118,7 @@ static int do_add_counters(struct net *net, const void __user *user, int ret = 0; void *loc_cpu_entry; struct arpt_entry *iter; + unsigned int addend; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1171,12 +1175,12 @@ static int do_add_counters(struct net *net, const void __user *user, /* Choose the copy that is on our node */ curcpu = smp_processor_id(); loc_cpu_entry = private->entries[curcpu]; - xt_info_wrlock(curcpu); + addend = xt_write_recseq_begin(); xt_entry_foreach(iter, loc_cpu_entry, private->size) { ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); ++i; } - xt_info_wrunlock(curcpu); + xt_write_recseq_end(addend); unlock_up_free: local_bh_enable(); xt_table_unlock(t); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index ffcea0d1678e..2b6b700949eb 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -68,15 +68,6 @@ void *ipt_alloc_initial_table(const struct xt_table *info) } EXPORT_SYMBOL_GPL(ipt_alloc_initial_table); -/* - We keep a set of rules for each CPU, so we can avoid write-locking - them in the softirq when updating the counters and therefore - only need to read-lock in the softirq; doing a write_lock_bh() in user - context stops packets coming through and allows user context to read - the counters or update the rules. - - Hence the start of any table is given by get_table() below. */ - /* Returns whether matches rule or not. */ /* Performance critical - called for every packet */ static inline bool @@ -311,6 +302,7 @@ ipt_do_table(struct sk_buff *skb, unsigned int *stackptr, origptr, cpu; const struct xt_table_info *private; struct xt_action_param acpar; + unsigned int addend; /* Initialization */ ip = ip_hdr(skb); @@ -331,7 +323,8 @@ ipt_do_table(struct sk_buff *skb, acpar.hooknum = hook; IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - xt_info_rdlock_bh(); + local_bh_disable(); + addend = xt_write_recseq_begin(); private = table->private; cpu = smp_processor_id(); table_base = private->entries[cpu]; @@ -430,7 +423,9 @@ ipt_do_table(struct sk_buff *skb, pr_debug("Exiting %s; resetting sp from %u to %u\n", __func__, *stackptr, origptr); *stackptr = origptr; - xt_info_rdunlock_bh(); + xt_write_recseq_end(addend); + local_bh_enable(); + #ifdef DEBUG_ALLOW_ALL return NF_ACCEPT; #else @@ -886,7 +881,7 @@ get_counters(const struct xt_table_info *t, unsigned int i; for_each_possible_cpu(cpu) { - seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; + seqcount_t *s = &per_cpu(xt_recseq, cpu); i = 0; xt_entry_foreach(iter, t->entries[cpu], t->size) { @@ -894,10 +889,10 @@ get_counters(const struct xt_table_info *t, unsigned int start; do { - start = read_seqbegin(lock); + start = read_seqcount_begin(s); bcnt = iter->counters.bcnt; pcnt = iter->counters.pcnt; - } while (read_seqretry(lock, start)); + } while (read_seqcount_retry(s, start)); ADD_COUNTER(counters[i], bcnt, pcnt); ++i; /* macro does multi eval of i */ @@ -1312,6 +1307,7 @@ do_add_counters(struct net *net, const void __user *user, int ret = 0; void *loc_cpu_entry; struct ipt_entry *iter; + unsigned int addend; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1368,12 +1364,12 @@ do_add_counters(struct net *net, const void __user *user, /* Choose the copy that is on our node */ curcpu = smp_processor_id(); loc_cpu_entry = private->entries[curcpu]; - xt_info_wrlock(curcpu); + addend = xt_write_recseq_begin(); xt_entry_foreach(iter, loc_cpu_entry, private->size) { ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); ++i; } - xt_info_wrunlock(curcpu); + xt_write_recseq_end(addend); unlock_up_free: local_bh_enable(); xt_table_unlock(t); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 0b2af9b85cec..ec7cf579cdd4 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -340,6 +340,7 @@ ip6t_do_table(struct sk_buff *skb, unsigned int *stackptr, origptr, cpu; const struct xt_table_info *private; struct xt_action_param acpar; + unsigned int addend; /* Initialization */ indev = in ? in->name : nulldevname; @@ -358,7 +359,8 @@ ip6t_do_table(struct sk_buff *skb, IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - xt_info_rdlock_bh(); + local_bh_disable(); + addend = xt_write_recseq_begin(); private = table->private; cpu = smp_processor_id(); table_base = private->entries[cpu]; @@ -442,7 +444,9 @@ ip6t_do_table(struct sk_buff *skb, } while (!acpar.hotdrop); *stackptr = origptr; - xt_info_rdunlock_bh(); + + xt_write_recseq_end(addend); + local_bh_enable(); #ifdef DEBUG_ALLOW_ALL return NF_ACCEPT; @@ -899,7 +903,7 @@ get_counters(const struct xt_table_info *t, unsigned int i; for_each_possible_cpu(cpu) { - seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; + seqcount_t *s = &per_cpu(xt_recseq, cpu); i = 0; xt_entry_foreach(iter, t->entries[cpu], t->size) { @@ -907,10 +911,10 @@ get_counters(const struct xt_table_info *t, unsigned int start; do { - start = read_seqbegin(lock); + start = read_seqcount_begin(s); bcnt = iter->counters.bcnt; pcnt = iter->counters.pcnt; - } while (read_seqretry(lock, start)); + } while (read_seqcount_retry(s, start)); ADD_COUNTER(counters[i], bcnt, pcnt); ++i; @@ -1325,6 +1329,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, int ret = 0; const void *loc_cpu_entry; struct ip6t_entry *iter; + unsigned int addend; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; @@ -1381,13 +1386,13 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, i = 0; /* Choose the copy that is on our node */ curcpu = smp_processor_id(); - xt_info_wrlock(curcpu); + addend = xt_write_recseq_begin(); loc_cpu_entry = private->entries[curcpu]; xt_entry_foreach(iter, loc_cpu_entry, private->size) { ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); ++i; } - xt_info_wrunlock(curcpu); + xt_write_recseq_end(addend); unlock_up_free: local_bh_enable(); diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index a9adf4c6b299..52959efca858 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -762,8 +762,8 @@ void xt_compat_unlock(u_int8_t af) EXPORT_SYMBOL_GPL(xt_compat_unlock); #endif -DEFINE_PER_CPU(struct xt_info_lock, xt_info_locks); -EXPORT_PER_CPU_SYMBOL_GPL(xt_info_locks); +DEFINE_PER_CPU(seqcount_t, xt_recseq); +EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq); static int xt_jumpstack_alloc(struct xt_table_info *i) { @@ -1362,10 +1362,7 @@ static int __init xt_init(void) int rv; for_each_possible_cpu(i) { - struct xt_info_lock *lock = &per_cpu(xt_info_locks, i); - - seqlock_init(&lock->lock); - lock->readers = 0; + seqcount_init(&per_cpu(xt_recseq, i)); } xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL); -- GitLab From fc3e5941248be00996150965a469d38c92913ac2 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 4 Apr 2011 11:07:57 -0700 Subject: [PATCH 0280/5560] xen: netfront: assume all hw features are available until backend connection setup We need to assume that all features will be available when registering the netdev otherwise they are ommitted from the initial set of dev->wanted_features. When we connect to the backed we reduce the set as necessary due to the call to netdev_update_features() in xennet_connect(). Signed-off-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 0cfe4ccf92d2..db9a763aaa7f 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1251,6 +1251,14 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev NETIF_F_GSO_ROBUST; netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; + /* + * Assume that all hw features are available for now. This set + * will be adjusted by the call to netdev_update_features() in + * xennet_connect() which is the earliest point where we can + * negotiate with the backend regarding supported features. + */ + netdev->features |= netdev->hw_features; + SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); SET_NETDEV_DEV(netdev, &dev->dev); -- GitLab From 0545a3037773512d3448557ba048cebb73b3e4af Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 05:30:58 +0000 Subject: [PATCH 0281/5560] pkt_sched: QFQ - quick fair queue scheduler This is an implementation of the Quick Fair Queue scheduler developed by Fabio Checconi. The same algorithm is already implemented in ipfw in FreeBSD. Fabio had an earlier version developed on Linux, I just cleaned it up. Thanks to Eric Dumazet for testing this under load. Signed-off-by: Stephen Hemminger Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/pkt_sched.h | 15 + net/sched/Kconfig | 11 + net/sched/Makefile | 1 + net/sched/sch_qfq.c | 1137 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1164 insertions(+) create mode 100644 net/sched/sch_qfq.c diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index b1032a3fafdc..8062e0a68dda 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -588,4 +588,19 @@ struct tc_sfb_xstats { #define SFB_MAX_PROB 0xFFFF +/* QFQ */ +enum { + TCA_QFQ_UNSPEC, + TCA_QFQ_WEIGHT, + TCA_QFQ_LMAX, + __TCA_QFQ_MAX +}; + +#define TCA_QFQ_MAX (__TCA_QFQ_MAX - 1) + +struct tc_qfq_stats { + __u32 weight; + __u32 lmax; +}; + #endif diff --git a/net/sched/Kconfig b/net/sched/Kconfig index a7a5583d4f68..aeaa2110b699 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -239,6 +239,17 @@ config NET_SCH_CHOKE To compile this code as a module, choose M here: the module will be called sch_choke. +config NET_SCH_QFQ + tristate "Quick Fair Queueing scheduler (QFQ)" + help + Say Y here if you want to use the Quick Fair Queueing Scheduler (QFQ) + packet scheduling algorithm. + + To compile this driver as a module, choose M here: the module + will be called sch_qfq. + + If unsure, say N. + config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_CLS_ACT diff --git a/net/sched/Makefile b/net/sched/Makefile index 2e77b8dba22e..dc5889c0a15a 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o obj-$(CONFIG_NET_SCH_DRR) += sch_drr.o obj-$(CONFIG_NET_SCH_MQPRIO) += sch_mqprio.o obj-$(CONFIG_NET_SCH_CHOKE) += sch_choke.o +obj-$(CONFIG_NET_SCH_QFQ) += sch_qfq.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c new file mode 100644 index 000000000000..103343408593 --- /dev/null +++ b/net/sched/sch_qfq.c @@ -0,0 +1,1137 @@ +/* + * net/sched/sch_qfq.c Quick Fair Queueing Scheduler. + * + * Copyright (c) 2009 Fabio Checconi, Luigi Rizzo, and Paolo Valente. + * + * 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 +#include + + +/* Quick Fair Queueing + =================== + + Sources: + + Fabio Checconi, Luigi Rizzo, and Paolo Valente: "QFQ: Efficient + Packet Scheduling with Tight Bandwidth Distribution Guarantees." + + See also: + http://retis.sssup.it/~fabio/linux/qfq/ + */ + +/* + + Virtual time computations. + + S, F and V are all computed in fixed point arithmetic with + FRAC_BITS decimal bits. + + QFQ_MAX_INDEX is the maximum index allowed for a group. We need + one bit per index. + QFQ_MAX_WSHIFT is the maximum power of two supported as a weight. + + The layout of the bits is as below: + + [ MTU_SHIFT ][ FRAC_BITS ] + [ MAX_INDEX ][ MIN_SLOT_SHIFT ] + ^.__grp->index = 0 + *.__grp->slot_shift + + where MIN_SLOT_SHIFT is derived by difference from the others. + + The max group index corresponds to Lmax/w_min, where + Lmax=1<group mapping. We allow class weights that are + * in the range [1, 2^MAX_WSHIFT], and we try to map each class i to the + * group with the smallest index that can support the L_i / r_i configured + * for the class. + * + * grp->index is the index of the group; and grp->slot_shift + * is the shift for the corresponding (scaled) sigma_i. + */ +#define QFQ_MAX_INDEX 19 +#define QFQ_MAX_WSHIFT 16 + +#define QFQ_MAX_WEIGHT (1<clhash, classid); + if (clc == NULL) + return NULL; + return container_of(clc, struct qfq_class, common); +} + +static void qfq_purge_queue(struct qfq_class *cl) +{ + unsigned int len = cl->qdisc->q.qlen; + + qdisc_reset(cl->qdisc); + qdisc_tree_decrease_qlen(cl->qdisc, len); +} + +static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = { + [TCA_QFQ_WEIGHT] = { .type = NLA_U32 }, + [TCA_QFQ_LMAX] = { .type = NLA_U32 }, +}; + +/* + * Calculate a flow index, given its weight and maximum packet length. + * index = log_2(maxlen/weight) but we need to apply the scaling. + * This is used only once at flow creation. + */ +static int qfq_calc_index(u32 inv_w, unsigned int maxlen) +{ + u64 slot_size = (u64)maxlen * inv_w; + unsigned long size_map; + int index = 0; + + size_map = slot_size >> QFQ_MIN_SLOT_SHIFT; + if (!size_map) + goto out; + + index = __fls(size_map) + 1; /* basically a log_2 */ + index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1))); + + if (index < 0) + index = 0; +out: + pr_debug("qfq calc_index: W = %lu, L = %u, I = %d\n", + (unsigned long) ONE_FP/inv_w, maxlen, index); + + return index; +} + +static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + struct nlattr **tca, unsigned long *arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)*arg; + struct nlattr *tb[TCA_QFQ_MAX + 1]; + u32 weight, lmax, inv_w; + int i, err; + + if (tca[TCA_OPTIONS] == NULL) { + pr_notice("qfq: no options\n"); + return -EINVAL; + } + + err = nla_parse_nested(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], qfq_policy); + if (err < 0) + return err; + + if (tb[TCA_QFQ_WEIGHT]) { + weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]); + if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) { + pr_notice("qfq: invalid weight %u\n", weight); + return -EINVAL; + } + } else + weight = 1; + + inv_w = ONE_FP / weight; + weight = ONE_FP / inv_w; + if (q->wsum + weight > QFQ_MAX_WSUM) { + pr_notice("qfq: total weight out of range (%u + %u)\n", + weight, q->wsum); + return -EINVAL; + } + + if (tb[TCA_QFQ_LMAX]) { + lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); + if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { + pr_notice("qfq: invalid max length %u\n", lmax); + return -EINVAL; + } + } else + lmax = 1UL << QFQ_MTU_SHIFT; + + if (cl != NULL) { + if (tca[TCA_RATE]) { + err = gen_replace_estimator(&cl->bstats, &cl->rate_est, + qdisc_root_sleeping_lock(sch), + tca[TCA_RATE]); + if (err) + return err; + } + + sch_tree_lock(sch); + if (tb[TCA_QFQ_WEIGHT]) { + q->wsum = weight - ONE_FP / cl->inv_w; + cl->inv_w = inv_w; + } + sch_tree_unlock(sch); + + return 0; + } + + cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL); + if (cl == NULL) + return -ENOBUFS; + + cl->refcnt = 1; + cl->common.classid = classid; + cl->lmax = lmax; + cl->inv_w = inv_w; + i = qfq_calc_index(cl->inv_w, cl->lmax); + + cl->grp = &q->groups[i]; + q->wsum += weight; + + cl->qdisc = qdisc_create_dflt(sch->dev_queue, + &pfifo_qdisc_ops, classid); + if (cl->qdisc == NULL) + cl->qdisc = &noop_qdisc; + + if (tca[TCA_RATE]) { + err = gen_new_estimator(&cl->bstats, &cl->rate_est, + qdisc_root_sleeping_lock(sch), + tca[TCA_RATE]); + if (err) { + qdisc_destroy(cl->qdisc); + kfree(cl); + return err; + } + } + + sch_tree_lock(sch); + qdisc_class_hash_insert(&q->clhash, &cl->common); + sch_tree_unlock(sch); + + qdisc_class_hash_grow(sch, &q->clhash); + + *arg = (unsigned long)cl; + return 0; +} + +static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl) +{ + struct qfq_sched *q = qdisc_priv(sch); + + if (cl->inv_w) { + q->wsum -= ONE_FP / cl->inv_w; + cl->inv_w = 0; + } + + gen_kill_estimator(&cl->bstats, &cl->rate_est); + qdisc_destroy(cl->qdisc); + kfree(cl); +} + +static int qfq_delete_class(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)arg; + + if (cl->filter_cnt > 0) + return -EBUSY; + + sch_tree_lock(sch); + + qfq_purge_queue(cl); + qdisc_class_hash_remove(&q->clhash, &cl->common); + + BUG_ON(--cl->refcnt == 0); + /* + * This shouldn't happen: we "hold" one cops->get() when called + * from tc_ctl_tclass; the destroy method is done from cops->put(). + */ + + sch_tree_unlock(sch); + return 0; +} + +static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid) +{ + struct qfq_class *cl = qfq_find_class(sch, classid); + + if (cl != NULL) + cl->refcnt++; + + return (unsigned long)cl; +} + +static void qfq_put_class(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + if (--cl->refcnt == 0) + qfq_destroy_class(sch, cl); +} + +static struct tcf_proto **qfq_tcf_chain(struct Qdisc *sch, unsigned long cl) +{ + struct qfq_sched *q = qdisc_priv(sch); + + if (cl) + return NULL; + + return &q->filter_list; +} + +static unsigned long qfq_bind_tcf(struct Qdisc *sch, unsigned long parent, + u32 classid) +{ + struct qfq_class *cl = qfq_find_class(sch, classid); + + if (cl != NULL) + cl->filter_cnt++; + + return (unsigned long)cl; +} + +static void qfq_unbind_tcf(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + cl->filter_cnt--; +} + +static int qfq_graft_class(struct Qdisc *sch, unsigned long arg, + struct Qdisc *new, struct Qdisc **old) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + if (new == NULL) { + new = qdisc_create_dflt(sch->dev_queue, + &pfifo_qdisc_ops, cl->common.classid); + if (new == NULL) + new = &noop_qdisc; + } + + sch_tree_lock(sch); + qfq_purge_queue(cl); + *old = cl->qdisc; + cl->qdisc = new; + sch_tree_unlock(sch); + return 0; +} + +static struct Qdisc *qfq_class_leaf(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + + return cl->qdisc; +} + +static int qfq_dump_class(struct Qdisc *sch, unsigned long arg, + struct sk_buff *skb, struct tcmsg *tcm) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + struct nlattr *nest; + + tcm->tcm_parent = TC_H_ROOT; + tcm->tcm_handle = cl->common.classid; + tcm->tcm_info = cl->qdisc->handle; + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (nest == NULL) + goto nla_put_failure; + NLA_PUT_U32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w); + NLA_PUT_U32(skb, TCA_QFQ_LMAX, cl->lmax); + return nla_nest_end(skb, nest); + +nla_put_failure: + nla_nest_cancel(skb, nest); + return -EMSGSIZE; +} + +static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg, + struct gnet_dump *d) +{ + struct qfq_class *cl = (struct qfq_class *)arg; + struct tc_qfq_stats xstats; + + memset(&xstats, 0, sizeof(xstats)); + cl->qdisc->qstats.qlen = cl->qdisc->q.qlen; + + xstats.weight = ONE_FP/cl->inv_w; + xstats.lmax = cl->lmax; + + if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || + gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 || + gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0) + return -1; + + return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); +} + +static void qfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl; + struct hlist_node *n; + unsigned int i; + + if (arg->stop) + return; + + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) { + if (arg->count < arg->skip) { + arg->count++; + continue; + } + if (arg->fn(sch, (unsigned long)cl, arg) < 0) { + arg->stop = 1; + return; + } + arg->count++; + } + } +} + +static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch, + int *qerr) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl; + struct tcf_result res; + int result; + + if (TC_H_MAJ(skb->priority ^ sch->handle) == 0) { + pr_debug("qfq_classify: found %d\n", skb->priority); + cl = qfq_find_class(sch, skb->priority); + if (cl != NULL) + return cl; + } + + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; + result = tc_classify(skb, q->filter_list, &res); + if (result >= 0) { +#ifdef CONFIG_NET_CLS_ACT + switch (result) { + case TC_ACT_QUEUED: + case TC_ACT_STOLEN: + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; + case TC_ACT_SHOT: + return NULL; + } +#endif + cl = (struct qfq_class *)res.class; + if (cl == NULL) + cl = qfq_find_class(sch, res.classid); + return cl; + } + + return NULL; +} + +/* Generic comparison function, handling wraparound. */ +static inline int qfq_gt(u64 a, u64 b) +{ + return (s64)(a - b) > 0; +} + +/* Round a precise timestamp to its slotted value. */ +static inline u64 qfq_round_down(u64 ts, unsigned int shift) +{ + return ts & ~((1ULL << shift) - 1); +} + +/* return the pointer to the group with lowest index in the bitmap */ +static inline struct qfq_group *qfq_ffs(struct qfq_sched *q, + unsigned long bitmap) +{ + int index = __ffs(bitmap); + return &q->groups[index]; +} +/* Calculate a mask to mimic what would be ffs_from(). */ +static inline unsigned long mask_from(unsigned long bitmap, int from) +{ + return bitmap & ~((1UL << from) - 1); +} + +/* + * The state computation relies on ER=0, IR=1, EB=2, IB=3 + * First compute eligibility comparing grp->S, q->V, + * then check if someone is blocking us and possibly add EB + */ +static int qfq_calc_state(struct qfq_sched *q, const struct qfq_group *grp) +{ + /* if S > V we are not eligible */ + unsigned int state = qfq_gt(grp->S, q->V); + unsigned long mask = mask_from(q->bitmaps[ER], grp->index); + struct qfq_group *next; + + if (mask) { + next = qfq_ffs(q, mask); + if (qfq_gt(grp->F, next->F)) + state |= EB; + } + + return state; +} + + +/* + * In principle + * q->bitmaps[dst] |= q->bitmaps[src] & mask; + * q->bitmaps[src] &= ~mask; + * but we should make sure that src != dst + */ +static inline void qfq_move_groups(struct qfq_sched *q, unsigned long mask, + int src, int dst) +{ + q->bitmaps[dst] |= q->bitmaps[src] & mask; + q->bitmaps[src] &= ~mask; +} + +static void qfq_unblock_groups(struct qfq_sched *q, int index, u64 old_F) +{ + unsigned long mask = mask_from(q->bitmaps[ER], index + 1); + struct qfq_group *next; + + if (mask) { + next = qfq_ffs(q, mask); + if (!qfq_gt(next->F, old_F)) + return; + } + + mask = (1UL << index) - 1; + qfq_move_groups(q, mask, EB, ER); + qfq_move_groups(q, mask, IB, IR); +} + +/* + * perhaps + * + old_V ^= q->V; + old_V >>= QFQ_MIN_SLOT_SHIFT; + if (old_V) { + ... + } + * + */ +static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) +{ + unsigned long vslot = q->V >> QFQ_MIN_SLOT_SHIFT; + unsigned long old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT; + + if (vslot != old_vslot) { + unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1; + qfq_move_groups(q, mask, IR, ER); + qfq_move_groups(q, mask, IB, EB); + } +} + + +/* + * XXX we should make sure that slot becomes less than 32. + * This is guaranteed by the input values. + * roundedS is always cl->S rounded on grp->slot_shift bits. + */ +static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, + u64 roundedS) +{ + u64 slot = (roundedS - grp->S) >> grp->slot_shift; + unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; + + hlist_add_head(&cl->next, &grp->slots[i]); + __set_bit(slot, &grp->full_slots); +} + +/* Maybe introduce hlist_first_entry?? */ +static struct qfq_class *qfq_slot_head(struct qfq_group *grp) +{ + return hlist_entry(grp->slots[grp->front].first, + struct qfq_class, next); +} + +/* + * remove the entry from the slot + */ +static void qfq_front_slot_remove(struct qfq_group *grp) +{ + struct qfq_class *cl = qfq_slot_head(grp); + + BUG_ON(!cl); + hlist_del(&cl->next); + if (hlist_empty(&grp->slots[grp->front])) + __clear_bit(0, &grp->full_slots); +} + +/* + * Returns the first full queue in a group. As a side effect, + * adjust the bucket list so the first non-empty bucket is at + * position 0 in full_slots. + */ +static struct qfq_class *qfq_slot_scan(struct qfq_group *grp) +{ + unsigned int i; + + pr_debug("qfq slot_scan: grp %u full %#lx\n", + grp->index, grp->full_slots); + + if (grp->full_slots == 0) + return NULL; + + i = __ffs(grp->full_slots); /* zero based */ + if (i > 0) { + grp->front = (grp->front + i) % QFQ_MAX_SLOTS; + grp->full_slots >>= i; + } + + return qfq_slot_head(grp); +} + +/* + * adjust the bucket list. When the start time of a group decreases, + * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to + * move the objects. The mask of occupied slots must be shifted + * because we use ffs() to find the first non-empty slot. + * This covers decreases in the group's start time, but what about + * increases of the start time ? + * Here too we should make sure that i is less than 32 + */ +static void qfq_slot_rotate(struct qfq_group *grp, u64 roundedS) +{ + unsigned int i = (grp->S - roundedS) >> grp->slot_shift; + + grp->full_slots <<= i; + grp->front = (grp->front - i) % QFQ_MAX_SLOTS; +} + +static void qfq_update_eligible(struct qfq_sched *q, u64 old_V) +{ + struct qfq_group *grp; + unsigned long ineligible; + + ineligible = q->bitmaps[IR] | q->bitmaps[IB]; + if (ineligible) { + if (!q->bitmaps[ER]) { + grp = qfq_ffs(q, ineligible); + if (qfq_gt(grp->S, q->V)) + q->V = grp->S; + } + qfq_make_eligible(q, old_V); + } +} + +/* What is length of next packet in queue (0 if queue is empty) */ +static unsigned int qdisc_peek_len(struct Qdisc *sch) +{ + struct sk_buff *skb; + + skb = sch->ops->peek(sch); + return skb ? qdisc_pkt_len(skb) : 0; +} + +/* + * Updates the class, returns true if also the group needs to be updated. + */ +static bool qfq_update_class(struct qfq_group *grp, struct qfq_class *cl) +{ + unsigned int len = qdisc_peek_len(cl->qdisc); + + cl->S = cl->F; + if (!len) + qfq_front_slot_remove(grp); /* queue is empty */ + else { + u64 roundedS; + + cl->F = cl->S + (u64)len * cl->inv_w; + roundedS = qfq_round_down(cl->S, grp->slot_shift); + if (roundedS == grp->S) + return false; + + qfq_front_slot_remove(grp); + qfq_slot_insert(grp, cl, roundedS); + } + + return true; +} + +static struct sk_buff *qfq_dequeue(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + struct qfq_class *cl; + struct sk_buff *skb; + unsigned int len; + u64 old_V; + + if (!q->bitmaps[ER]) + return NULL; + + grp = qfq_ffs(q, q->bitmaps[ER]); + + cl = qfq_slot_head(grp); + skb = qdisc_dequeue_peeked(cl->qdisc); + if (!skb) { + WARN_ONCE(1, "qfq_dequeue: non-workconserving leaf\n"); + return NULL; + } + + sch->q.qlen--; + qdisc_bstats_update(sch, skb); + + old_V = q->V; + len = qdisc_pkt_len(skb); + q->V += (u64)len * IWSUM; + pr_debug("qfq dequeue: len %u F %lld now %lld\n", + len, (unsigned long long) cl->F, (unsigned long long) q->V); + + if (qfq_update_class(grp, cl)) { + u64 old_F = grp->F; + + cl = qfq_slot_scan(grp); + if (!cl) + __clear_bit(grp->index, &q->bitmaps[ER]); + else { + u64 roundedS = qfq_round_down(cl->S, grp->slot_shift); + unsigned int s; + + if (grp->S == roundedS) + goto skip_unblock; + grp->S = roundedS; + grp->F = roundedS + (2ULL << grp->slot_shift); + __clear_bit(grp->index, &q->bitmaps[ER]); + s = qfq_calc_state(q, grp); + __set_bit(grp->index, &q->bitmaps[s]); + } + + qfq_unblock_groups(q, grp->index, old_F); + } + +skip_unblock: + qfq_update_eligible(q, old_V); + + return skb; +} + +/* + * Assign a reasonable start time for a new flow k in group i. + * Admissible values for \hat(F) are multiples of \sigma_i + * no greater than V+\sigma_i . Larger values mean that + * we had a wraparound so we consider the timestamp to be stale. + * + * If F is not stale and F >= V then we set S = F. + * Otherwise we should assign S = V, but this may violate + * the ordering in ER. So, if we have groups in ER, set S to + * the F_j of the first group j which would be blocking us. + * We are guaranteed not to move S backward because + * otherwise our group i would still be blocked. + */ +static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl) +{ + unsigned long mask; + uint32_t limit, roundedF; + int slot_shift = cl->grp->slot_shift; + + roundedF = qfq_round_down(cl->F, slot_shift); + limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift); + + if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) { + /* timestamp was stale */ + mask = mask_from(q->bitmaps[ER], cl->grp->index); + if (mask) { + struct qfq_group *next = qfq_ffs(q, mask); + if (qfq_gt(roundedF, next->F)) { + cl->S = next->F; + return; + } + } + cl->S = q->V; + } else /* timestamp is not stale */ + cl->S = cl->F; +} + +static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + struct qfq_class *cl; + int err; + u64 roundedS; + int s; + + cl = qfq_classify(skb, sch, &err); + if (cl == NULL) { + if (err & __NET_XMIT_BYPASS) + sch->qstats.drops++; + kfree_skb(skb); + return err; + } + pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); + + err = qdisc_enqueue(skb, cl->qdisc); + if (unlikely(err != NET_XMIT_SUCCESS)) { + pr_debug("qfq_enqueue: enqueue failed %d\n", err); + if (net_xmit_drop_count(err)) { + cl->qstats.drops++; + sch->qstats.drops++; + } + return err; + } + + bstats_update(&cl->bstats, skb); + ++sch->q.qlen; + + /* If the new skb is not the head of queue, then done here. */ + if (cl->qdisc->q.qlen != 1) + return err; + + /* If reach this point, queue q was idle */ + grp = cl->grp; + qfq_update_start(q, cl); + + /* compute new finish time and rounded start. */ + cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w; + roundedS = qfq_round_down(cl->S, grp->slot_shift); + + /* + * insert cl in the correct bucket. + * If cl->S >= grp->S we don't need to adjust the + * bucket list and simply go to the insertion phase. + * Otherwise grp->S is decreasing, we must make room + * in the bucket list, and also recompute the group state. + * Finally, if there were no flows in this group and nobody + * was in ER make sure to adjust V. + */ + if (grp->full_slots) { + if (!qfq_gt(grp->S, cl->S)) + goto skip_update; + + /* create a slot for this cl->S */ + qfq_slot_rotate(grp, roundedS); + /* group was surely ineligible, remove */ + __clear_bit(grp->index, &q->bitmaps[IR]); + __clear_bit(grp->index, &q->bitmaps[IB]); + } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V)) + q->V = roundedS; + + grp->S = roundedS; + grp->F = roundedS + (2ULL << grp->slot_shift); + s = qfq_calc_state(q, grp); + __set_bit(grp->index, &q->bitmaps[s]); + + pr_debug("qfq enqueue: new state %d %#lx S %lld F %lld V %lld\n", + s, q->bitmaps[s], + (unsigned long long) cl->S, + (unsigned long long) cl->F, + (unsigned long long) q->V); + +skip_update: + qfq_slot_insert(grp, cl, roundedS); + + return err; +} + + +static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp, + struct qfq_class *cl) +{ + unsigned int i, offset; + u64 roundedS; + + roundedS = qfq_round_down(cl->S, grp->slot_shift); + offset = (roundedS - grp->S) >> grp->slot_shift; + i = (grp->front + offset) % QFQ_MAX_SLOTS; + + hlist_del(&cl->next); + if (hlist_empty(&grp->slots[i])) + __clear_bit(offset, &grp->full_slots); +} + +/* + * called to forcibly destroy a queue. + * If the queue is not in the front bucket, or if it has + * other queues in the front bucket, we can simply remove + * the queue with no other side effects. + * Otherwise we must propagate the event up. + */ +static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl) +{ + struct qfq_group *grp = cl->grp; + unsigned long mask; + u64 roundedS; + int s; + + cl->F = cl->S; + qfq_slot_remove(q, grp, cl); + + if (!grp->full_slots) { + __clear_bit(grp->index, &q->bitmaps[IR]); + __clear_bit(grp->index, &q->bitmaps[EB]); + __clear_bit(grp->index, &q->bitmaps[IB]); + + if (test_bit(grp->index, &q->bitmaps[ER]) && + !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) { + mask = q->bitmaps[ER] & ((1UL << grp->index) - 1); + if (mask) + mask = ~((1UL << __fls(mask)) - 1); + else + mask = ~0UL; + qfq_move_groups(q, mask, EB, ER); + qfq_move_groups(q, mask, IB, IR); + } + __clear_bit(grp->index, &q->bitmaps[ER]); + } else if (hlist_empty(&grp->slots[grp->front])) { + cl = qfq_slot_scan(grp); + roundedS = qfq_round_down(cl->S, grp->slot_shift); + if (grp->S != roundedS) { + __clear_bit(grp->index, &q->bitmaps[ER]); + __clear_bit(grp->index, &q->bitmaps[IR]); + __clear_bit(grp->index, &q->bitmaps[EB]); + __clear_bit(grp->index, &q->bitmaps[IB]); + grp->S = roundedS; + grp->F = roundedS + (2ULL << grp->slot_shift); + s = qfq_calc_state(q, grp); + __set_bit(grp->index, &q->bitmaps[s]); + } + } + + qfq_update_eligible(q, q->V); +} + +static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl = (struct qfq_class *)arg; + + if (cl->qdisc->q.qlen == 0) + qfq_deactivate_class(q, cl); +} + +static unsigned int qfq_drop(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + unsigned int i, j, len; + + for (i = 0; i <= QFQ_MAX_INDEX; i++) { + grp = &q->groups[i]; + for (j = 0; j < QFQ_MAX_SLOTS; j++) { + struct qfq_class *cl; + struct hlist_node *n; + + hlist_for_each_entry(cl, n, &grp->slots[j], next) { + + if (!cl->qdisc->ops->drop) + continue; + + len = cl->qdisc->ops->drop(cl->qdisc); + if (len > 0) { + sch->q.qlen--; + if (!cl->qdisc->q.qlen) + qfq_deactivate_class(q, cl); + + return len; + } + } + } + } + + return 0; +} + +static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + int i, j, err; + + err = qdisc_class_hash_init(&q->clhash); + if (err < 0) + return err; + + for (i = 0; i <= QFQ_MAX_INDEX; i++) { + grp = &q->groups[i]; + grp->index = i; + grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS + - (QFQ_MAX_INDEX - i); + for (j = 0; j < QFQ_MAX_SLOTS; j++) + INIT_HLIST_HEAD(&grp->slots[j]); + } + + return 0; +} + +static void qfq_reset_qdisc(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_group *grp; + struct qfq_class *cl; + struct hlist_node *n, *tmp; + unsigned int i, j; + + for (i = 0; i <= QFQ_MAX_INDEX; i++) { + grp = &q->groups[i]; + for (j = 0; j < QFQ_MAX_SLOTS; j++) { + hlist_for_each_entry_safe(cl, n, tmp, + &grp->slots[j], next) { + qfq_deactivate_class(q, cl); + } + } + } + + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) + qdisc_reset(cl->qdisc); + } + sch->q.qlen = 0; +} + +static void qfq_destroy_qdisc(struct Qdisc *sch) +{ + struct qfq_sched *q = qdisc_priv(sch); + struct qfq_class *cl; + struct hlist_node *n, *next; + unsigned int i; + + tcf_destroy_chain(&q->filter_list); + + for (i = 0; i < q->clhash.hashsize; i++) { + hlist_for_each_entry_safe(cl, n, next, &q->clhash.hash[i], + common.hnode) { + qfq_destroy_class(sch, cl); + } + } + qdisc_class_hash_destroy(&q->clhash); +} + +static const struct Qdisc_class_ops qfq_class_ops = { + .change = qfq_change_class, + .delete = qfq_delete_class, + .get = qfq_get_class, + .put = qfq_put_class, + .tcf_chain = qfq_tcf_chain, + .bind_tcf = qfq_bind_tcf, + .unbind_tcf = qfq_unbind_tcf, + .graft = qfq_graft_class, + .leaf = qfq_class_leaf, + .qlen_notify = qfq_qlen_notify, + .dump = qfq_dump_class, + .dump_stats = qfq_dump_class_stats, + .walk = qfq_walk, +}; + +static struct Qdisc_ops qfq_qdisc_ops __read_mostly = { + .cl_ops = &qfq_class_ops, + .id = "qfq", + .priv_size = sizeof(struct qfq_sched), + .enqueue = qfq_enqueue, + .dequeue = qfq_dequeue, + .peek = qdisc_peek_dequeued, + .drop = qfq_drop, + .init = qfq_init_qdisc, + .reset = qfq_reset_qdisc, + .destroy = qfq_destroy_qdisc, + .owner = THIS_MODULE, +}; + +static int __init qfq_init(void) +{ + return register_qdisc(&qfq_qdisc_ops); +} + +static void __exit qfq_exit(void) +{ + unregister_qdisc(&qfq_qdisc_ops); +} + +module_init(qfq_init); +module_exit(qfq_exit); +MODULE_LICENSE("GPL"); -- GitLab From 1c0ce89c87b310e8022f50bb75c1b693ee9d7158 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 25 Mar 2011 17:59:39 +0100 Subject: [PATCH 0282/5560] iwlegacy: MAINTAINERS Add iwlegacy driver to MAINTAINERS. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- MAINTAINERS | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 09d3fc0fbbeb..5dd948b5bc6e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3355,14 +3355,10 @@ F: Documentation/wimax/README.i2400m F: drivers/net/wimax/i2400m/ F: include/linux/wimax/i2400m.h -INTEL PRO/WIRELESS 3945ABG/BG NETWORK CONNECTION SUPPORT +INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy) +M: Stanislaw Gruszka L: linux-wireless@vger.kernel.org -S: Orphan -F: drivers/net/wireless/iwlegacy/ - -INTEL WIRELESS WIFI 4965AGN NETWORK CONNECTION SUPPORT -L: linux-wireless@vger.kernel.org -S: Orphan +S: Supported F: drivers/net/wireless/iwlegacy/ INTEL WIRELESS WIFI LINK (iwlwifi) -- GitLab From 279daf64c01e391379060a6d30e9827cc0c56612 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 23 Mar 2011 14:04:31 -0700 Subject: [PATCH 0283/5560] wifi: Add hwflags to debugfs. Aids debugging wifi behaviour. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- net/mac80211/debugfs.c | 89 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 51f0d780dafa..0a602dbfdb2b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -37,7 +37,7 @@ int mac80211_format_buffer(char __user *userbuf, size_t count, return simple_read_from_buffer(userbuf, count, ppos, buf, res); } -#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ +#define DEBUGFS_READONLY_FILE_FN(name, fmt, value...) \ static ssize_t name## _read(struct file *file, char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ @@ -45,14 +45,19 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ \ return mac80211_format_buffer(userbuf, count, ppos, \ fmt "\n", ##value); \ -} \ - \ +} + +#define DEBUGFS_READONLY_FILE_OPS(name) \ static const struct file_operations name## _ops = { \ .read = name## _read, \ .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ }; +#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ + DEBUGFS_READONLY_FILE_FN(name, fmt, value) \ + DEBUGFS_READONLY_FILE_OPS(name) + #define DEBUGFS_ADD(name) \ debugfs_create_file(#name, 0400, phyd, local, &name## _ops); @@ -291,11 +296,70 @@ static ssize_t channel_type_read(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); } -static const struct file_operations channel_type_ops = { - .read = channel_type_read, - .open = mac80211_open_file_generic, - .llseek = default_llseek, -}; +static ssize_t hwflags_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ieee80211_local *local = file->private_data; + int mxln = 500; + ssize_t rv; + char *buf = kzalloc(mxln, GFP_KERNEL); + int sf = 0; /* how many written so far */ + + sf += snprintf(buf, mxln - sf, "0x%x\n", local->hw.flags); + if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) + sf += snprintf(buf + sf, mxln - sf, "HAS_RATE_CONTROL\n"); + if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) + sf += snprintf(buf + sf, mxln - sf, "RX_INCLUDES_FCS\n"); + if (local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) + sf += snprintf(buf + sf, mxln - sf, + "HOST_BCAST_PS_BUFFERING\n"); + if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE) + sf += snprintf(buf + sf, mxln - sf, + "2GHZ_SHORT_SLOT_INCAPABLE\n"); + if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE) + sf += snprintf(buf + sf, mxln - sf, + "2GHZ_SHORT_PREAMBLE_INCAPABLE\n"); + if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) + sf += snprintf(buf + sf, mxln - sf, "SIGNAL_UNSPEC\n"); + if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) + sf += snprintf(buf + sf, mxln - sf, "SIGNAL_DBM\n"); + if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) + sf += snprintf(buf + sf, mxln - sf, "NEED_DTIM_PERIOD\n"); + if (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT) + sf += snprintf(buf + sf, mxln - sf, "SPECTRUM_MGMT\n"); + if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) + sf += snprintf(buf + sf, mxln - sf, "AMPDU_AGGREGATION\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PS\n"); + if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) + sf += snprintf(buf + sf, mxln - sf, "PS_NULLFUNC_STACK\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); + if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) + sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); + if (local->hw.flags & IEEE80211_HW_BEACON_FILTER) + sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_SMPS\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n"); + if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) + sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n"); + if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) + sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n"); + if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK) + sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n"); + if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) + sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n"); + + rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); + kfree(buf); + return rv; +} static ssize_t queues_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -315,11 +379,9 @@ static ssize_t queues_read(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, res); } -static const struct file_operations queues_ops = { - .read = queues_read, - .open = mac80211_open_file_generic, - .llseek = default_llseek, -}; +DEBUGFS_READONLY_FILE_OPS(hwflags); +DEBUGFS_READONLY_FILE_OPS(channel_type); +DEBUGFS_READONLY_FILE_OPS(queues); /* statistics stuff */ @@ -395,6 +457,7 @@ void debugfs_hw_add(struct ieee80211_local *local) DEBUGFS_ADD(uapsd_queues); DEBUGFS_ADD(uapsd_max_sp_len); DEBUGFS_ADD(channel_type); + DEBUGFS_ADD(hwflags); DEBUGFS_ADD(user_power); DEBUGFS_ADD(power); -- GitLab From b64c6a3d1ab1bab9396e6efd2fd03479be4d0a63 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 24 Mar 2011 14:36:16 +0530 Subject: [PATCH 0284/5560] ath9k: cleanup few redundant macros Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ---- drivers/net/wireless/ath/ath9k/common.c | 2 +- drivers/net/wireless/ath/ath9k/mac.c | 2 -- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 7c91ba4dce41..a43f05993687 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -120,13 +120,11 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, /* RX / TX */ /***********/ -#define ATH_MAX_ANTENNA 3 #define ATH_RXBUF 512 #define ATH_TXBUF 512 #define ATH_TXBUF_RESERVE 5 #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) #define ATH_TXMAXTRY 13 -#define ATH_MGT_TXMAXTRY 4 #define TID_TO_WME_AC(_tid) \ ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ @@ -688,8 +686,6 @@ 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); - void ath_start_rfkill_poll(struct ath_softc *sc); extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); void ath9k_calculate_iter_data(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 615e68276e72..16ba8c67fbd5 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -116,7 +116,7 @@ void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, if (chan->band == IEEE80211_BAND_2GHZ) { ichan->chanmode = CHANNEL_G; - ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G; + ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; } else { ichan->chanmode = CHANNEL_A; ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 05efcfbeeadc..6f431cbff38a 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -713,7 +713,6 @@ EXPORT_SYMBOL(ath9k_hw_abortpcurecv); bool ath9k_hw_stopdmarecv(struct ath_hw *ah) { #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ -#define AH_RX_TIME_QUANTUM 100 /* usec */ struct ath_common *common = ath9k_hw_common(ah); int i; @@ -737,7 +736,6 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah) return true; } -#undef AH_RX_TIME_QUANTUM #undef AH_RX_STOP_DMA_TIMEOUT } EXPORT_SYMBOL(ath9k_hw_stopdmarecv); -- GitLab From 468b0d4482cadd174298e2fe9bde6a20044f90f5 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 24 Mar 2011 15:49:54 +0530 Subject: [PATCH 0285/5560] ath9k: remove set11n_virtualmorefrag This does not seems to be used anywhere so remove it. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 12 ------------ drivers/net/wireless/ath/ath9k/ar9003_mac.c | 12 ------------ drivers/net/wireless/ath/ath9k/hw-ops.h | 6 ------ drivers/net/wireless/ath/ath9k/hw.h | 2 -- 4 files changed, 32 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 399ab3bb299b..8dd8f6308502 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -415,17 +415,6 @@ static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds, ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); } -static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, - u32 vmf) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - if (vmf) - ads->ds_ctl0 |= AR_VirtMoreFrag; - else - ads->ds_ctl0 &= ~AR_VirtMoreFrag; -} - void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { @@ -459,5 +448,4 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; ops->clr11n_aggr = ar9002_hw_clr11n_aggr; ops->set11n_burstduration = ar9002_hw_set11n_burstduration; - ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 038a0cbfc6e7..724ac2464ad5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -485,17 +485,6 @@ static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds, } -static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, - u32 vmf) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - - if (vmf) - ads->ctl11 |= AR_VirtMoreFrag; - else - ads->ctl11 &= ~AR_VirtMoreFrag; -} - void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) { struct ar9003_txc *ads = ds; @@ -521,7 +510,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; ops->clr11n_aggr = ar9003_hw_clr11n_aggr; ops->set11n_burstduration = ar9003_hw_set11n_burstduration; - ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag; } void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index c8f254fe0f0b..22ee888b0baf 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -122,12 +122,6 @@ static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); } -static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, - u32 vmf) -{ - ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); -} - /* Private hardware call ops */ /* PHY ops */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 4cc320bdf0aa..031b1bf0d370 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -628,8 +628,6 @@ struct ath_hw_ops { void (*clr11n_aggr)(struct ath_hw *ah, void *ds); void (*set11n_burstduration)(struct ath_hw *ah, void *ds, u32 burstDuration); - void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, - u32 vmf); }; struct ath_nf_limits { -- GitLab From 2638126a7c7cce87d51ae5d3bfaca9350503c0b4 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Thu, 24 Mar 2011 19:06:40 +0530 Subject: [PATCH 0286/5560] ath9k_hw: remove ath9k_get_channel_edges This function is nowhere used. Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 25 ------------------------- drivers/net/wireless/ath/ath9k/hw.h | 3 --- 2 files changed, 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 298f4d6cbdbd..be7baf09eb00 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -156,25 +156,6 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n) return retval; } -bool ath9k_get_channel_edges(struct ath_hw *ah, - u16 flags, u16 *low, - u16 *high) -{ - struct ath9k_hw_capabilities *pCap = &ah->caps; - - if (flags & CHANNEL_5GHZ) { - *low = pCap->low_5ghz_chan; - *high = pCap->high_5ghz_chan; - return true; - } - if ((flags & CHANNEL_2GHZ)) { - *low = pCap->low_2ghz_chan; - *high = pCap->high_2ghz_chan; - return true; - } - return false; -} - u16 ath9k_hw_computetxtime(struct ath_hw *ah, u8 phy, int kbps, u32 frameLen, u16 rateix, @@ -1867,12 +1848,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) 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; - - pCap->low_5ghz_chan = 4920; - pCap->high_5ghz_chan = 6100; - common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; if (ah->hw_version.devid != AR2427_DEVID_PCIE) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 031b1bf0d370..a778b66f4438 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -190,8 +190,6 @@ enum ath9k_hw_caps { struct ath9k_hw_capabilities { u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ - u16 low_5ghz_chan, high_5ghz_chan; - u16 low_2ghz_chan, high_2ghz_chan; u16 rts_aggr_limit; u8 tx_chainmask; u8 rx_chainmask; @@ -900,7 +898,6 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, int column, unsigned int *writecnt); u32 ath9k_hw_reverse_bits(u32 val, u32 n); -bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high); u16 ath9k_hw_computetxtime(struct ath_hw *ah, u8 phy, int kbps, u32 frameLen, u16 rateix, bool shortPreamble); -- GitLab From 1ed76487ce115110171480deabd3cd4656f9803e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 24 Mar 2011 19:46:18 +0100 Subject: [PATCH 0287/5560] mac80211: fix suppressing probe responses in ad-hoc mode The commit "mac80211: reply to directed probes in IBSS" changed ad-hoc specific code to respond to unicast probe requests, even if drv_tx_last_beacon returns false, however due to confusion over the meaning of the IEEE80211_RX_RA_MATCH flag, it also unconditionally enabled responding to multicast probe requests. Fix this by explicitly checking for a multicast destination address instead. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/ibss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 3e81af1fce58..14883966374e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -661,7 +661,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, struct sk_buff *req) { - struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req); struct ieee80211_mgmt *mgmt = (void *)req->data; struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; @@ -685,7 +684,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, mgmt->bssid, tx_last_beacon); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH)) + if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && -- GitLab From 0022801c893e953ebff8e0ad00cc22716055babf Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Thu, 24 Mar 2011 20:49:38 -0700 Subject: [PATCH 0288/5560] mwifiex: remove helper functions for displaying 11n capabilities 'iw list' is sufficient to retrieve the information which was displayed by these functions. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 96 --------------------------- drivers/net/wireless/mwifiex/11n.h | 2 - drivers/net/wireless/mwifiex/cmdevt.c | 2 - drivers/net/wireless/mwifiex/fw.h | 16 ----- 4 files changed, 116 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 0e04a21be0a3..7b7b86d1ea3e 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -139,102 +139,6 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); } -/* - * Shows HT capability information fields. - * - * The following HT capability information fields are supported. - * - Maximum AMSDU length (3839 bytes or 7935 bytes) - * - Beam forming support - * - Greenfield preamble support - * - AMPDU support - * - MIMO Power Save support - * - Rx STBC support - * - Tx STBC support - * - Short GI for 20 MHz support - * - Short GI for 40 MHz support - * - LDPC coded packets receive support - * - Number of delayed BA streams - * - Number of immediate BA streams - * - 10 MHz channel width support - * - 20 MHz channel width support - * - 40 MHz channel width support - * - Presence of Tx antenna A/B/C/D - * - Presence of Rx antenna A/B/C/D - */ -void -mwifiex_show_dot_11n_dev_cap(struct mwifiex_adapter *adapter, u32 cap) -{ - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Max MSDU len = %s octets\n", - (ISSUPP_MAXAMSDU(cap) ? "7935" : "3839")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Beam forming %s\n", - (ISSUPP_BEAMFORMING(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Greenfield preamble %s\n", - (ISSUPP_GREENFIELD(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: AMPDU %s\n", - (ISSUPP_AMPDU(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: MIMO Power Save %s\n", - (ISSUPP_MIMOPS(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Rx STBC %s\n", - (ISSUPP_RXSTBC(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Tx STBC %s\n", - (ISSUPP_TXSTBC(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Short GI for 40 Mhz %s\n", - (ISSUPP_SHORTGI40(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Short GI for 20 Mhz %s\n", - (ISSUPP_SHORTGI20(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: LDPC coded packet receive %s\n", - (ISSUPP_RXLDPC(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, - "info: GET_HW_SPEC: Number of Delayed Block Ack streams = %d\n", - GET_DELAYEDBACK(cap)); - dev_dbg(adapter->dev, - "info: GET_HW_SPEC: Number of Immediate Block Ack streams = %d\n", - GET_IMMEDIATEBACK(cap)); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: 40 Mhz channel width %s\n", - (ISSUPP_CHANWIDTH40(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: 20 Mhz channel width %s\n", - (ISSUPP_CHANWIDTH20(cap) ? "supported" : "not supported")); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: 10 Mhz channel width %s\n", - (ISSUPP_CHANWIDTH10(cap) ? "supported" : "not supported")); - - if (ISSUPP_RXANTENNAA(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea A\n"); - - if (ISSUPP_RXANTENNAB(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea B\n"); - - if (ISSUPP_RXANTENNAC(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea C\n"); - - if (ISSUPP_RXANTENNAD(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Rx antennea D\n"); - - if (ISSUPP_TXANTENNAA(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea A\n"); - - if (ISSUPP_TXANTENNAB(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea B\n"); - - if (ISSUPP_TXANTENNAC(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea C\n"); - - if (ISSUPP_TXANTENNAD(cap)) - dev_dbg(adapter->dev, "info: GET_HW_SPEC: Prescence of Tx antennea D\n"); - - return; -} - -/* - * Shows HT MCS support field. - */ -void -mwifiex_show_dev_mcs_support(struct mwifiex_adapter *adapter, u8 support) -{ - dev_dbg(adapter->dev, "info: GET_HW_SPEC: MCSs for %dx%d MIMO\n", - GET_RXMCSSUPP(support), GET_TXMCSSUPP(support)); - return; -} - /* * This function returns the pointer to an entry in BA Stream * table which matches the requested BA status. diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 769a27f2b2c3..71a853e61b61 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -24,8 +24,6 @@ #include "11n_rxreorder.h" #include "wmm.h" -void mwifiex_show_dot_11n_dev_cap(struct mwifiex_adapter *adapter, u32 cap); -void mwifiex_show_dev_mcs_support(struct mwifiex_adapter *adapter, u8 support); int mwifiex_ret_11n_delba(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 3a8fe1e122fb..24a3b6b69f64 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1452,8 +1452,6 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, DEFAULT_11N_CAP_MASK; adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support; adapter->usr_dev_mcs_support = adapter->hw_dev_mcs_support; - mwifiex_show_dot_11n_dev_cap(adapter, adapter->hw_dot_11n_dev_cap); - mwifiex_show_dev_mcs_support(adapter, adapter->hw_dev_mcs_support); if (adapter->if_ops.update_mp_end_port) adapter->if_ops.update_mp_end_port(adapter, diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index e5dae45b11d2..d1a5a10c2a8e 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -196,30 +196,14 @@ enum MWIFIEX_802_11_WEP_STATUS { #define DEFAULT_11N_CAP_MASK (HWSPEC_SHORTGI20_SUPP | HWSPEC_RXSTBC_SUPP) #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) -#define ISSUPP_MAXAMSDU(Dot11nDevCap) (Dot11nDevCap & BIT(31)) -#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30)) #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) -#define ISSUPP_AMPDU(Dot11nDevCap) (Dot11nDevCap & BIT(28)) -#define ISSUPP_MIMOPS(Dot11nDevCap) (Dot11nDevCap & BIT(27)) #define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) #define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) #define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24)) #define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23)) -#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) #define GET_DELAYEDBACK(Dot11nDevCap) (((Dot11nDevCap >> 20) & 0x03)) -#define GET_IMMEDIATEBACK(Dot11nDevCap) (((Dot11nDevCap >> 18) & 0x03)) #define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & BIT(17)) -#define ISSUPP_CHANWIDTH20(Dot11nDevCap) (Dot11nDevCap & BIT(16)) -#define ISSUPP_CHANWIDTH10(Dot11nDevCap) (Dot11nDevCap & BIT(15)) #define ISENABLED_40MHZ_INTOLARENT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) -#define ISSUPP_RXANTENNAD(Dot11nDevCap) (Dot11nDevCap & BIT(7)) -#define ISSUPP_RXANTENNAC(Dot11nDevCap) (Dot11nDevCap & BIT(6)) -#define ISSUPP_RXANTENNAB(Dot11nDevCap) (Dot11nDevCap & BIT(5)) -#define ISSUPP_RXANTENNAA(Dot11nDevCap) (Dot11nDevCap & BIT(4)) -#define ISSUPP_TXANTENNAD(Dot11nDevCap) (Dot11nDevCap & BIT(3)) -#define ISSUPP_TXANTENNAC(Dot11nDevCap) (Dot11nDevCap & BIT(2)) -#define ISSUPP_TXANTENNAB(Dot11nDevCap) (Dot11nDevCap & BIT(1)) -#define ISSUPP_TXANTENNAA(Dot11nDevCap) (Dot11nDevCap & BIT(0)) #define SETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap |= BIT(17)) #define RESETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap &= ~BIT(17)) #define GET_TXMCSSUPP(DevMCSSupported) (DevMCSSupported >> 4) -- GitLab From 203afecaa320fa8c541ce130aed449ff53f5b4aa Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Thu, 24 Mar 2011 20:49:39 -0700 Subject: [PATCH 0289/5560] mwifiex: remove unnecessary _set_auth functions mwifiex_set_encrypt_mode() mwifiex_set_auth_mode() mwifiex_set_auth() These functions are confusing and misleading. And they are really not needed at all. Some unused definitions are also removed. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 17 +++++---- drivers/net/wireless/mwifiex/ioctl.h | 2 -- drivers/net/wireless/mwifiex/join.c | 25 ++++++-------- drivers/net/wireless/mwifiex/main.h | 8 ----- drivers/net/wireless/mwifiex/sta_ioctl.c | 44 ------------------------ 5 files changed, 19 insertions(+), 77 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 80f367f27efc..84e33f1f0ffe 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1055,11 +1055,10 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, * scan. The cfg80211 does not give us the encryption * mode at this stage so just setting it to WEP here. */ - wpa_enabled = 0; - auth_type = MWIFIEX_AUTH_MODE_OPEN; - ret = mwifiex_set_auth(priv, - MWIFIEX_ENCRYPTION_MODE_WEP104, - auth_type, wpa_enabled); + priv->sec_info.encryption_mode = + MWIFIEX_ENCRYPTION_MODE_WEP104; + priv->sec_info.authentication_mode = + MWIFIEX_AUTH_MODE_OPEN; } goto done; @@ -1075,15 +1074,15 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, if (sme->crypto.n_ciphers_pairwise) { pairwise_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. ciphers_pairwise[0], &wpa_enabled); - ret = mwifiex_set_auth(priv, pairwise_encrypt_mode, auth_type, - wpa_enabled); + priv->sec_info.encryption_mode = pairwise_encrypt_mode; + priv->sec_info.authentication_mode = auth_type; } if (sme->crypto.cipher_group) { group_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. cipher_group, &wpa_enabled); - ret = mwifiex_set_auth(priv, group_encrypt_mode, auth_type, - wpa_enabled); + priv->sec_info.encryption_mode = group_encrypt_mode; + priv->sec_info.authentication_mode = auth_type; } if (sme->ie) ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len); diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d6babfb1495c..b7e457110b4f 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -277,8 +277,6 @@ struct mwifiex_debug_info { enum { MWIFIEX_AUTH_MODE_OPEN = 0x00, MWIFIEX_AUTH_MODE_SHARED = 0x01, - MWIFIEX_AUTH_MODE_NETWORKEAP = 0x80, - MWIFIEX_AUTH_MODE_AUTO = 0xFF, }; enum { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index d06f4c2d1d30..98d76d8c2656 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -441,20 +441,17 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", rates_size); - /* Add the Authentication type to be used for Auth frames if needed */ - if (priv->sec_info.authentication_mode != MWIFIEX_AUTH_MODE_AUTO) { - auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; - auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); - auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type)); - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) - auth_tlv->auth_type = cpu_to_le16((u16) priv->sec_info. - authentication_mode); - else - auth_tlv->auth_type = - cpu_to_le16(MWIFIEX_AUTH_MODE_OPEN); - pos += sizeof(auth_tlv->header) + - le16_to_cpu(auth_tlv->header.len); - } + /* Add the Authentication type to be used for Auth frames */ + auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; + auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); + auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type)); + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + auth_tlv->auth_type = cpu_to_le16( + (u16) priv->sec_info.authentication_mode); + else + auth_tlv->auth_type = cpu_to_le16(MWIFIEX_AUTH_MODE_OPEN); + + pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); if (IS_SUPPORT_MULTI_BANDS(priv->adapter) && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 2b0ad8e3d6e2..f6fe1054a65c 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -994,11 +994,6 @@ int mwifiex_get_channel_list(struct mwifiex_private *priv, int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option, struct mwifiex_scan_resp *scanresp); -int mwifiex_get_auth_mode(struct mwifiex_private *priv, - u8 wait_option, u32 *auth_mode); -int mwifiex_get_encrypt_mode(struct mwifiex_private *priv, - u8 wait_option, - u32 *encrypt_mode); int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option); int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid); @@ -1014,9 +1009,6 @@ int mwifiex_drv_get_mode(struct mwifiex_private *priv, u8 wait_option); int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); -int mwifiex_set_auth(struct mwifiex_private *priv, int encrypt_mode, - int auth_mode, int wpa_enabled); - int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int key_len, u8 key_index, int disable); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 665a519b1403..362301f417a4 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -1690,20 +1690,6 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, return ret; } -/* - * IOCTL request handler to set/get authentication mode. - */ -static int mwifiex_set_auth_mode(struct mwifiex_private *priv, u32 auth_mode) -{ - int ret = 0; - - priv->sec_info.authentication_mode = auth_mode; - if (priv->sec_info.authentication_mode == MWIFIEX_AUTH_MODE_NETWORKEAP) - ret = mwifiex_set_wpa_ie_helper(priv, NULL, 0); - - return ret; -} - /* * IOCTL request handler to set WEP network key. * @@ -1998,36 +1984,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, return status; } -/* - * Sends IOCTL request to set encryption mode. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -static int mwifiex_set_encrypt_mode(struct mwifiex_private *priv, - u8 wait_option, u32 encrypt_mode) -{ - priv->sec_info.encryption_mode = encrypt_mode; - return 0; -} - -/* - * This function set the authentication parameters. It sets both encryption - * mode and authentication mode, and also enables WPA if required. - */ -int -mwifiex_set_auth(struct mwifiex_private *priv, int encrypt_mode, - int auth_mode, int wpa_enabled) -{ - if (mwifiex_set_encrypt_mode(priv, MWIFIEX_IOCTL_WAIT, encrypt_mode)) - return -EFAULT; - - if (mwifiex_set_auth_mode(priv, auth_mode)) - return -EFAULT; - - return 0; -} - /* * Sends IOCTL request to set encoding parameters. * -- GitLab From 5f9f1812b68a2979bc97399cd4954f1c191986af Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 25 Mar 2011 21:39:19 +0100 Subject: [PATCH 0290/5560] mac80211: remove the dependency on crypto_blkcipher The only thing that using crypto_blkcipher with ecb does over just using arc4 directly is wrapping the encrypt/decrypt function into a for loop, looping over each individual character. To be able to do this, it pulls in around 40 kb worth of unnecessary kernel modules (at least on a MIPS embedded device). Using arc4 directly not only eliminates those dependencies, it also makes the code smaller. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/Kconfig | 1 - net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/tkip.c | 4 ++-- net/mac80211/tkip.h | 4 ++-- net/mac80211/wep.c | 34 +++++++++++++++------------------- net/mac80211/wep.h | 4 ++-- 6 files changed, 23 insertions(+), 28 deletions(-) diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 513f85cc2ae1..f5fdfcbf552a 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -2,7 +2,6 @@ config MAC80211 tristate "Generic IEEE 802.11 Networking Stack (mac80211)" depends on CFG80211 select CRYPTO - select CRYPTO_ECB select CRYPTO_ARC4 select CRYPTO_AES select CRC32 diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a40401701424..6eb2c8523eeb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -809,8 +809,8 @@ struct ieee80211_local { struct rate_control_ref *rate_ctrl; - struct crypto_blkcipher *wep_tx_tfm; - struct crypto_blkcipher *wep_rx_tfm; + struct crypto_cipher *wep_tx_tfm; + struct crypto_cipher *wep_rx_tfm; u32 wep_iv; /* see iface.c */ diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index e840c9cd46db..757e4eb2baf7 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -202,7 +202,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key); * @payload_len is the length of payload (_not_ including IV/ICV length). * @ta is the transmitter addresses. */ -int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, +int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, struct ieee80211_key *key, u8 *pos, size_t payload_len, u8 *ta) { @@ -223,7 +223,7 @@ int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, * beginning of the buffer containing IEEE 802.11 header payload, i.e., * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the * length of payload, including IV, Ext. IV, MIC, ICV. */ -int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, +int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, struct ieee80211_key *key, u8 *payload, size_t payload_len, u8 *ta, u8 *ra, int only_iv, int queue, diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index 7e83dee976fa..1cab9c86978f 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h @@ -15,7 +15,7 @@ u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); -int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, +int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, struct ieee80211_key *key, u8 *pos, size_t payload_len, u8 *ta); enum { @@ -24,7 +24,7 @@ enum { TKIP_DECRYPT_INVALID_KEYIDX = -2, TKIP_DECRYPT_REPLAY = -3, }; -int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, +int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, struct ieee80211_key *key, u8 *payload, size_t payload_len, u8 *ta, u8 *ra, int only_iv, int queue, diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 2ff6d1e3ed21..a1c6bfd55f0f 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -30,17 +30,15 @@ int ieee80211_wep_init(struct ieee80211_local *local) /* start WEP IV from a random value */ get_random_bytes(&local->wep_iv, WEP_IV_LEN); - local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, - CRYPTO_ALG_ASYNC); + local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(local->wep_tx_tfm)) { local->wep_rx_tfm = ERR_PTR(-EINVAL); return PTR_ERR(local->wep_tx_tfm); } - local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, - CRYPTO_ALG_ASYNC); + local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(local->wep_rx_tfm)) { - crypto_free_blkcipher(local->wep_tx_tfm); + crypto_free_cipher(local->wep_tx_tfm); local->wep_tx_tfm = ERR_PTR(-EINVAL); return PTR_ERR(local->wep_rx_tfm); } @@ -51,9 +49,9 @@ int ieee80211_wep_init(struct ieee80211_local *local) void ieee80211_wep_free(struct ieee80211_local *local) { if (!IS_ERR(local->wep_tx_tfm)) - crypto_free_blkcipher(local->wep_tx_tfm); + crypto_free_cipher(local->wep_tx_tfm); if (!IS_ERR(local->wep_rx_tfm)) - crypto_free_blkcipher(local->wep_rx_tfm); + crypto_free_cipher(local->wep_rx_tfm); } static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) @@ -127,12 +125,11 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, /* Perform WEP encryption using given key. data buffer must have tailroom * for 4-byte ICV. data_len must not include this ICV. Note: this function * does _not_ add IV. data = RC4(data | CRC32(data)) */ -int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, +int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, size_t klen, u8 *data, size_t data_len) { - struct blkcipher_desc desc = { .tfm = tfm }; - struct scatterlist sg; __le32 icv; + int i; if (IS_ERR(tfm)) return -1; @@ -140,9 +137,9 @@ int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, icv = cpu_to_le32(~crc32_le(~0, data, data_len)); put_unaligned(icv, (__le32 *)(data + data_len)); - crypto_blkcipher_setkey(tfm, rc4key, klen); - sg_init_one(&sg, data, data_len + WEP_ICV_LEN); - crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); + crypto_cipher_setkey(tfm, rc4key, klen); + for (i = 0; i < data_len + WEP_ICV_LEN; i++) + crypto_cipher_encrypt_one(tfm, data + i, data + i); return 0; } @@ -186,19 +183,18 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, /* Perform WEP decryption using given key. data buffer includes encrypted * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. * Return 0 on success and -1 on ICV mismatch. */ -int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, +int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, size_t klen, u8 *data, size_t data_len) { - struct blkcipher_desc desc = { .tfm = tfm }; - struct scatterlist sg; __le32 crc; + int i; if (IS_ERR(tfm)) return -1; - crypto_blkcipher_setkey(tfm, rc4key, klen); - sg_init_one(&sg, data, data_len + WEP_ICV_LEN); - crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); + crypto_cipher_setkey(tfm, rc4key, klen); + for (i = 0; i < data_len + WEP_ICV_LEN; i++) + crypto_cipher_decrypt_one(tfm, data + i, data + i); crc = cpu_to_le32(~crc32_le(~0, data, data_len)); if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0) diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 58654ee33518..01e54840a628 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h @@ -18,12 +18,12 @@ int ieee80211_wep_init(struct ieee80211_local *local); void ieee80211_wep_free(struct ieee80211_local *local); -int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, +int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, size_t klen, u8 *data, size_t data_len); int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, const u8 *key, int keylen, int keyidx); -int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, +int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, size_t klen, u8 *data, size_t data_len); bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); -- GitLab From b93f85f0fb019f527b68569aafb836c94b89a47e Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Fri, 25 Mar 2011 19:47:01 -0700 Subject: [PATCH 0291/5560] mwifiex: remove macro SHORT_SLOT_TIME_DISABLED and SHORT_SLOT_TIME_ENABLED. Use WLAN_CAPABILITY_SHORT_SLOT_TIME instead. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 3 --- drivers/net/wireless/mwifiex/join.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index d1a5a10c2a8e..410be694e36b 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -57,9 +57,6 @@ struct tx_packet_hdr { #define GET_FW_DEFAULT_BANDS(adapter) \ ((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS) -#define SHORT_SLOT_TIME_DISABLED(CapInfo) (CapInfo &= ~BIT(10)) -#define SHORT_SLOT_TIME_ENABLED(CapInfo) (CapInfo |= BIT(10)) - extern u8 supported_rates_b[B_SUPPORTED_RATES]; extern u8 supported_rates_g[G_SUPPORTED_RATES]; extern u8 supported_rates_bg[BG_SUPPORTED_RATES]; diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 98d76d8c2656..8ffb6a8d1036 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -517,7 +517,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, tmp_cap = bss_desc->cap_info_bitmap; if (priv->adapter->config_bands == BAND_B) - SHORT_SLOT_TIME_DISABLED(tmp_cap); + tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; tmp_cap &= CAPINFO_MASK; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", @@ -1015,9 +1015,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, + S_DS_GEN + cmd_append_size)); if (adapter->adhoc_start_band == BAND_B) - SHORT_SLOT_TIME_DISABLED(tmp_cap); + tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; else - SHORT_SLOT_TIME_ENABLED(tmp_cap); + tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME; adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap); -- GitLab From 6d2bd916afe6950b50f750cd82bbb9c6ff58611f Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Fri, 25 Mar 2011 19:47:02 -0700 Subject: [PATCH 0292/5560] mwifiex: use IEEE80211_HT_CAP_ macros for 11n cap_info The hw_dot_11n_dev_cap reported by firmware hw_spec has different format than the 11n capabilities. Hence a lot of SET_ and RESET_ bit operation macros were used to convert the dev_cap format to 11n capability format. However the locally defined 11n ht_cap macros are not necessary as we can use IEEE80211_HT_CAP_ macros directly. The 32-bit dev_cap bitmap is added as comment to explain the mapping between firmware and 11n spec. Some unused macros and unnecessary adapter variables are also removed. Signed-off-by: Marc Yang Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 85 ++++++++++--------------- drivers/net/wireless/mwifiex/cfg80211.c | 3 +- drivers/net/wireless/mwifiex/cmdevt.c | 3 - drivers/net/wireless/mwifiex/fw.h | 84 ++++++------------------ drivers/net/wireless/mwifiex/init.c | 2 - drivers/net/wireless/mwifiex/join.c | 13 ++-- drivers/net/wireless/mwifiex/main.h | 2 - 7 files changed, 63 insertions(+), 129 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 7b7b86d1ea3e..ce6421f3230b 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -61,59 +61,42 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, uint16_t ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info); - if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap) && - ISSUPP_CHANWIDTH40(adapter->usr_dot_11n_dev_cap)) - SETHT_SUPPCHANWIDTH(ht_cap_info); + /* Convert dev_cap to IEEE80211_HT_CAP */ + if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) + ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; else - RESETHT_SUPPCHANWIDTH(ht_cap_info); + ht_cap_info &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap) && - ISSUPP_GREENFIELD(adapter->usr_dot_11n_dev_cap)) - SETHT_GREENFIELD(ht_cap_info); + if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap)) + ht_cap_info |= IEEE80211_HT_CAP_SGI_20; else - RESETHT_GREENFIELD(ht_cap_info); + ht_cap_info &= ~IEEE80211_HT_CAP_SGI_20; - if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap) && - ISSUPP_SHORTGI20(adapter->usr_dot_11n_dev_cap)) - SETHT_SHORTGI20(ht_cap_info); + if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap)) + ht_cap_info |= IEEE80211_HT_CAP_SGI_40; else - RESETHT_SHORTGI20(ht_cap_info); + ht_cap_info &= ~IEEE80211_HT_CAP_SGI_40; - if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap) && - ISSUPP_SHORTGI40(adapter->usr_dot_11n_dev_cap)) - SETHT_SHORTGI40(ht_cap_info); - else - RESETHT_SHORTGI40(ht_cap_info); - - /* No user config for RX STBC yet */ - if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap) - && ISSUPP_RXSTBC(adapter->usr_dot_11n_dev_cap)) - SETHT_RXSTBC(ht_cap_info, 1); - else - RESETHT_RXSTBC(ht_cap_info); - - /* No user config for TX STBC yet */ if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) - SETHT_TXSTBC(ht_cap_info); + ht_cap_info |= IEEE80211_HT_CAP_TX_STBC; else - RESETHT_TXSTBC(ht_cap_info); + ht_cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - /* No user config for Delayed BACK yet */ - if (GET_DELAYEDBACK(adapter->hw_dot_11n_dev_cap)) - SETHT_DELAYEDBACK(ht_cap_info); + if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) + ht_cap_info |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; else - RESETHT_DELAYEDBACK(ht_cap_info); + ht_cap_info &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); - if (ISENABLED_40MHZ_INTOLARENT(adapter->usr_dot_11n_dev_cap)) - SETHT_40MHZ_INTOLARANT(ht_cap_info); + if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap)) + ht_cap_info |= IEEE80211_HT_CAP_GRN_FLD; else - RESETHT_40MHZ_INTOLARANT(ht_cap_info); + ht_cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; - SETAMPDU_SIZE(ht_cap->ht_cap.ampdu_params_info, AMPDU_FACTOR_64K); - SETAMPDU_SPACING(ht_cap->ht_cap.ampdu_params_info, 0); + ht_cap_info &= ~IEEE80211_HT_CAP_MAX_AMSDU; + ht_cap_info |= IEEE80211_HT_CAP_SM_PS; - /* Need change to support 8k AMSDU receive */ - RESETHT_MAXAMSDU(ht_cap_info); + ht_cap->ht_cap.ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR; + ht_cap->ht_cap.ampdu_params_info &= ~IEEE80211_HT_AMPDU_PARM_DENSITY; rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); @@ -127,8 +110,7 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || - (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap) && - ISSUPP_CHANWIDTH40(adapter->usr_dot_11n_dev_cap))) + (ht_cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); @@ -452,10 +434,10 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, le16_to_cpu(ht_info->header.len)); if (!ISSUPP_CHANWIDTH40 - (priv->adapter->hw_dot_11n_dev_cap) - || !ISSUPP_CHANWIDTH40(priv->adapter-> - usr_dot_11n_dev_cap)) - RESET_CHANWIDTH40(ht_info->ht_info.ht_param); + (priv->adapter->hw_dot_11n_dev_cap)) + ht_info->ht_info.ht_param &= + ~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY | + IEEE80211_HT_PARAM_CHA_SEC_OFFSET); *buffer += sizeof(struct mwifiex_ie_types_htinfo); ret_len += sizeof(struct mwifiex_ie_types_htinfo); @@ -474,13 +456,13 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, chan_list->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - if ((ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) && - ISSUPP_CHANWIDTH40(priv->adapter->usr_dot_11n_dev_cap)) - && ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_info->ht_param)) + if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) + && (bss_desc->bcn_ht_info->ht_param & + IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. radio_type, - GET_SECONDARYCHAN(bss_desc-> - bcn_ht_info->ht_param)); + (bss_desc->bcn_ht_info->ht_param & + IEEE80211_HT_PARAM_CHA_SEC_OFFSET)); *buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set); ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set); @@ -540,7 +522,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, u16 curr_tx_buf_size = 0; if (bss_desc->bcn_ht_cap) { - if (GETHT_MAXAMSDU(le16_to_cpu(bss_desc->bcn_ht_cap->cap_info))) + if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) & + IEEE80211_HT_CAP_MAX_AMSDU) max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_8K; else max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_4K; diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 84e33f1f0ffe..de86ef879509 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1302,8 +1302,7 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, memset(&mcs[rx_mcs_supp], 0, sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || - (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap) && - ISSUPP_CHANWIDTH40(adapter->usr_dot_11n_dev_cap))) + ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(mcs_set.rx_mask); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 24a3b6b69f64..3865dd19e4f8 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1448,10 +1448,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, } adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); - adapter->usr_dot_11n_dev_cap = adapter->hw_dot_11n_dev_cap & - DEFAULT_11N_CAP_MASK; adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support; - adapter->usr_dev_mcs_support = adapter->hw_dev_mcs_support; if (adapter->if_ops.update_mp_end_port) adapter->if_ops.update_mp_end_port(adapter, diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 410be694e36b..6593e071dea8 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -182,76 +182,34 @@ enum MWIFIEX_802_11_WEP_STATUS { #define MWIFIEX_TX_DATA_BUF_SIZE_4K 4096 #define MWIFIEX_TX_DATA_BUF_SIZE_8K 8192 -#define MAX_RX_AMPDU_SIZE_64K 0x03 #define NON_GREENFIELD_STAS 0x04 -#define HWSPEC_GREENFIELD_SUPP BIT(29) -#define HWSPEC_RXSTBC_SUPP BIT(26) -#define HWSPEC_SHORTGI40_SUPP BIT(24) -#define HWSPEC_SHORTGI20_SUPP BIT(23) -#define HWSPEC_CHANBW40_SUPP BIT(17) - -#define DEFAULT_11N_CAP_MASK (HWSPEC_SHORTGI20_SUPP | HWSPEC_RXSTBC_SUPP) #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) -#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) -#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) -#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) -#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24)) -#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23)) -#define GET_DELAYEDBACK(Dot11nDevCap) (((Dot11nDevCap >> 20) & 0x03)) + +/* dev_cap bitmap + * BIT + * 0-16 reserved + * 17 IEEE80211_HT_CAP_SUP_WIDTH_20_40 + * 18-22 reserved + * 23 IEEE80211_HT_CAP_SGI_20 + * 24 IEEE80211_HT_CAP_SGI_40 + * 25 IEEE80211_HT_CAP_TX_STBC + * 26 IEEE80211_HT_CAP_RX_STBC + * 27-28 reserved + * 29 IEEE80211_HT_CAP_GRN_FLD + * 30-31 reserved + */ #define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & BIT(17)) -#define ISENABLED_40MHZ_INTOLARENT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) -#define SETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap |= BIT(17)) -#define RESETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap &= ~BIT(17)) -#define GET_TXMCSSUPP(DevMCSSupported) (DevMCSSupported >> 4) +#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23)) +#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24)) +#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) +#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) +#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) + #define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f) -#define GETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo & BIT(1)) -#define GETHT_GREENFIELD(HTCapInfo) (HTCapInfo & BIT(4)) -#define GETHT_SHORTGI20(HTCapInfo) (HTCapInfo & BIT(5)) -#define GETHT_SHORTGI40(HTCapInfo) (HTCapInfo & BIT(6)) -#define GETHT_TXSTBC(HTCapInfo) (HTCapInfo & BIT(7)) -#define GETHT_RXSTBC(HTCapInfo) ((HTCapInfo >> 8) & 0x03) -#define GETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo & BIT(10)) -#define GETHT_MAXAMSDU(HTCapInfo) (HTCapInfo & BIT(11)) -#define SETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo |= BIT(1)) -#define SETHT_GREENFIELD(HTCapInfo) (HTCapInfo |= BIT(4)) -#define SETHT_SHORTGI20(HTCapInfo) (HTCapInfo |= BIT(5)) -#define SETHT_SHORTGI40(HTCapInfo) (HTCapInfo |= BIT(6)) -#define SETHT_TXSTBC(HTCapInfo) (HTCapInfo |= BIT(7)) -#define SETHT_RXSTBC(HTCapInfo, value) (HTCapInfo |= (value << 8)) -#define SETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo |= BIT(10)) -#define SETHT_MAXAMSDU(HTCapInfo) (HTCapInfo |= BIT(11)) -#define SETHT_DSSSCCK40(HTCapInfo) (HTCapInfo |= BIT(12)) -#define SETHT_40MHZ_INTOLARANT(HTCapInfo) (HTCapInfo |= BIT(14)) -#define RESETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo &= ~BIT(1)) -#define RESETHT_GREENFIELD(HTCapInfo) (HTCapInfo &= ~BIT(4)) -#define RESETHT_SHORTGI20(HTCapInfo) (HTCapInfo &= ~BIT(5)) -#define RESETHT_SHORTGI40(HTCapInfo) (HTCapInfo &= ~BIT(6)) -#define RESETHT_TXSTBC(HTCapInfo) (HTCapInfo &= ~BIT(7)) -#define RESETHT_RXSTBC(HTCapInfo) (HTCapInfo &= ~(0x03 << 8)) -#define RESETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo &= ~BIT(10)) -#define RESETHT_MAXAMSDU(HTCapInfo) (HTCapInfo &= ~BIT(11)) -#define RESETHT_40MHZ_INTOLARANT(HTCapInfo) (HTCapInfo &= ~BIT(14)) #define RESETHT_EXTCAP_RDG(HTExtCap) (HTExtCap &= ~BIT(11)) #define SETHT_MCS32(x) (x[4] |= 1) -#define SETHT_MCS_SET_DEFINED(x) (x[12] |= 1) -#define SETHT_RX_HIGHEST_DT_SUPP(x, y) ((*(u16 *) (x + 10)) = y) -#define AMPDU_FACTOR_64K 0x03 -#define SETAMPDU_SIZE(x, y) do { \ - x = x & ~0x03; \ - x |= y & 0x03; \ -} while (0) \ - -#define SETAMPDU_SPACING(x, y) do { \ - x = x & ~0x1c; \ - x |= (y & 0x07) << 2; \ -} while (0) \ - -#define ISSUPP_BANDA(FwCapInfo) (FwCapInfo & BIT(10)) -#define ISALLOWED_CHANWIDTH40(Field2) (Field2 & BIT(2)) -#define SET_CHANWIDTH40(Field2) (Field2 |= BIT(2)) -#define RESET_CHANWIDTH40(Field2) (Field2 &= ~(BIT(0) | BIT(1) | BIT(2))) -#define GET_SECONDARYCHAN(Field2) (Field2 & (BIT(0) | BIT(1))) + #define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4)) #define LLC_SNAP_LEN 8 diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 07ebc97e19c0..1c9315d31d9c 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -267,8 +267,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) memset(adapter->event_body, 0, sizeof(adapter->event_body)); adapter->hw_dot_11n_dev_cap = 0; adapter->hw_dev_mcs_support = 0; - adapter->usr_dot_11n_dev_cap = 0; - adapter->usr_dev_mcs_support = 0; adapter->chan_offset = 0; adapter->adhoc_11n_enabled = false; diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 8ffb6a8d1036..08fa721580cb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -970,16 +970,16 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, cpu_to_le16(sizeof(struct ieee80211_ht_cap)); ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); - SETHT_SHORTGI20(ht_cap_info); + ht_cap_info |= IEEE80211_HT_CAP_SGI_20; if (adapter->chan_offset) { - SETHT_SHORTGI40(ht_cap_info); - SETHT_DSSSCCK40(ht_cap_info); - SETHT_SUPPCHANWIDTH(ht_cap_info); + ht_cap_info |= IEEE80211_HT_CAP_SGI_40; + ht_cap_info |= IEEE80211_HT_CAP_DSSSCCK40; + ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); } ht_cap->ht_cap.ampdu_params_info - = MAX_RX_AMPDU_SIZE_64K; + = IEEE80211_HT_MAX_AMPDU_64K; ht_cap->ht_cap.mcs.rx_mask[0] = 0xff; pos += sizeof(struct mwifiex_ie_types_htcap); cmd_append_size += @@ -999,7 +999,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, if (adapter->chan_offset) { ht_info->ht_info.ht_param = adapter->chan_offset; - SET_CHANWIDTH40(ht_info->ht_info.ht_param); + ht_info->ht_info.ht_param |= + IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; } ht_info->ht_info.operation_mode = cpu_to_le16(NON_GREENFIELD_STAS); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index f6fe1054a65c..7bcb2e965aeb 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -687,8 +687,6 @@ struct mwifiex_adapter { u8 event_body[MAX_EVENT_SIZE]; u32 hw_dot_11n_dev_cap; u8 hw_dev_mcs_support; - u32 usr_dot_11n_dev_cap; - u8 usr_dev_mcs_support; u8 adhoc_11n_enabled; u8 chan_offset; struct mwifiex_dbg dbg; -- GitLab From 324732848c42bf79988479ee1b4359e15f08154b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 27 Mar 2011 16:19:57 -0500 Subject: [PATCH 0293/5560] rtlwifi: Remove unused/unneeded variables Remove some unused variables and correct spelling errors. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 5 +- drivers/net/wireless/rtlwifi/core.c | 8 +- drivers/net/wireless/rtlwifi/efuse.c | 106 +++++++++--------- drivers/net/wireless/rtlwifi/pci.c | 53 +++------ drivers/net/wireless/rtlwifi/pci.h | 4 +- drivers/net/wireless/rtlwifi/ps.c | 3 +- .../net/wireless/rtlwifi/rtl8192c/fw_common.c | 38 +++---- drivers/net/wireless/rtlwifi/wifi.h | 18 +-- 8 files changed, 98 insertions(+), 137 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index bb0c781f4a1b..dd5318ed7872 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -432,7 +432,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, } if (rtlpriv->dm.useramask) { - /* TODO we will differentiate adhoc and station futrue */ + /* TODO adhoc and station handled differently in the future */ tcb_desc->mac_id = 0; if ((mac->mode == WIRELESS_MODE_N_24G) || @@ -630,7 +630,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) const struct iphdr *ip; if (!ieee80211_is_data(fc)) - goto end; + return false; if (ieee80211_is_nullfunc(fc)) return true; @@ -686,7 +686,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return true; } -end: return false; } diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index e4f4aee8f298..8fed3c687619 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -35,7 +35,7 @@ /*mutex for start & stop is must here. */ static int rtl_op_start(struct ieee80211_hw *hw) { - int err = 0; + int err; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -45,10 +45,8 @@ static int rtl_op_start(struct ieee80211_hw *hw) return 0; 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: + if (!err) + rtl_watch_dog_timer_callback((unsigned long)hw); mutex_unlock(&rtlpriv->locks.conf_mutex); return err; } diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index f74a8701c67d..5d73c0f7012c 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -338,11 +338,11 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *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; + bool wordchanged, result = true; for (section_idx = 0; section_idx < 16; section_idx++) { Base = section_idx * 8; - bwordchanged = false; + wordchanged = false; for (i = 0; i < 8; i = i + 2) { if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] != @@ -351,11 +351,11 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i + 1])) { words_need++; - bwordchanged = true; + wordchanged = true; } } - if (bwordchanged == true) + if (wordchanged == true) hdr_num++; } @@ -364,14 +364,14 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) if ((totalbytes + efuse_used) >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) - bresult = false; + result = 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; + return result; } void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, @@ -394,7 +394,7 @@ void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, else if (type == 2) efuse_shadow_write_2byte(hw, offset, (u16) value); else if (type == 4) - efuse_shadow_write_4byte(hw, offset, (u32) value); + efuse_shadow_write_4byte(hw, offset, value); } @@ -572,7 +572,7 @@ 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; + int result; rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -592,19 +592,18 @@ static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) if (tmpidx < 100) { *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); - bresult = true; + result = true; } else { *data = 0xff; - bresult = false; + result = false; } - return bresult; + return result; } 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)); @@ -626,11 +625,9 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) } if (tmpidx < 100) - bresult = true; - else - bresult = false; + return true; - return bresult; + return false; } static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse) @@ -681,11 +678,10 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) { u8 readstate = PG_STATE_HEADER; - bool bcontinual = true; + bool continual = true; u8 efuse_data, word_cnts = 0; u16 efuse_addr = 0; - u8 hworden; u8 tmpdata[8]; if (data == NULL) @@ -696,7 +692,7 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); - while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) { + while (continual && (efuse_addr < EFUSE_MAX_SIZE)) { if (readstate & PG_STATE_HEADER) { if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) @@ -705,9 +701,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) offset, tmpdata, &readstate); else - bcontinual = false; + continual = false; } else if (readstate & PG_STATE_DATA) { - efuse_word_enable_data_read(hworden, tmpdata, data); + efuse_word_enable_data_read(0, tmpdata, data); efuse_addr = efuse_addr + (word_cnts * 2) + 1; readstate = PG_STATE_HEADER; } @@ -725,13 +721,13 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) } static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, - u8 efuse_data, u8 offset, int *bcontinual, + u8 efuse_data, u8 offset, int *continual, u8 *write_state, struct pgpkt_struct *target_pkt, - int *repeat_times, int *bresult, u8 word_en) + int *repeat_times, int *result, u8 word_en) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct pgpkt_struct tmp_pkt; - int bdataempty = true; + bool dataempty = true; u8 originaldata[8 * sizeof(u8)]; u8 badworden = 0x0F; u8 match_word_en, tmp_word_en; @@ -751,10 +747,10 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, u16 address = *efuse_addr + 1 + tmpindex; if (efuse_one_byte_read(hw, address, &efuse_data) && (efuse_data != 0xFF)) - bdataempty = false; + dataempty = false; } - if (bdataempty == false) { + if (dataempty == false) { *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; *write_state = PG_STATE_HEADER; } else { @@ -811,12 +807,12 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, target_pkt->offset = offset; target_pkt->word_en = tmp_word_en; } else - *bcontinual = false; + *continual = false; *write_state = PG_STATE_HEADER; *repeat_times += 1; if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { - *bcontinual = false; - *bresult = false; + *continual = false; + *result = false; } } else { *efuse_addr += (2 * tmp_word_cnts) + 1; @@ -830,9 +826,9 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, - int *bcontinual, u8 *write_state, + int *continual, u8 *write_state, struct pgpkt_struct target_pkt, - int *repeat_times, int *bresult) + int *repeat_times, int *result) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct pgpkt_struct tmp_pkt; @@ -852,8 +848,8 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, *write_state = PG_STATE_HEADER; *repeat_times += 1; if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { - *bcontinual = false; - *bresult = false; + *continual = false; + *result = false; } } else { tmp_pkt.offset = (tmp_header >> 4) & 0x0F; @@ -884,8 +880,8 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, *write_state = PG_STATE_HEADER; *repeat_times += 1; if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { - *bcontinual = false; - *bresult = false; + *continual = false; + *result = false; } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, @@ -899,7 +895,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, 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; + int continual = true, dataempty = true, result = true; u16 efuse_addr = 0; u8 efuse_data; u8 target_word_cnts = 0; @@ -923,11 +919,11 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n")); - while (bcontinual && (efuse_addr < + while (continual && (efuse_addr < (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { if (write_state == PG_STATE_HEADER) { - bdataempty = true; + dataempty = true; badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER\n")); @@ -936,32 +932,30 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, (efuse_data != 0xFF)) efuse_write_data_case1(hw, &efuse_addr, efuse_data, offset, - &bcontinual, + &continual, &write_state, &target_pkt, - &repeat_times, &bresult, + &repeat_times, &result, word_en); else efuse_write_data_case2(hw, &efuse_addr, - &bcontinual, + &continual, &write_state, target_pkt, &repeat_times, - &bresult); + &result); } 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; + continual = false; } else { - efuse_addr = - efuse_addr + (2 * target_word_cnts) + 1; + efuse_addr += (2 * target_word_cnts) + 1; target_pkt.offset = offset; target_pkt.word_en = badworden; @@ -971,8 +965,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, write_state = PG_STATE_HEADER; repeat_times++; if (repeat_times > EFUSE_REPEAT_THRESHOLD_) { - bcontinual = false; - bresult = false; + continual = false; + result = false; } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-3\n")); @@ -1072,13 +1066,13 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, return badworden; } -static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) +static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) { struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tempval; u16 tmpV16; - if (pwrstate == true) { + if (pwrstate) { tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL]); if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { @@ -1106,8 +1100,8 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) } } - if (pwrstate == true) { - if (bwrite == true) { + if (pwrstate) { + if (write) { tempval = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3); @@ -1119,7 +1113,7 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) } } else { - if (bwrite == true) { + if (write) { tempval = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3); @@ -1134,12 +1128,12 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) static u16 efuse_get_current_size(struct ieee80211_hw *hw) { - int bcontinual = true; + int continual = true; u16 efuse_addr = 0; u8 hoffset, hworden; u8 efuse_data, word_cnts; - while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) + while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_addr < EFUSE_MAX_SIZE)) { if (efuse_data != 0xFF) { hoffset = (efuse_data >> 4) & 0x0F; @@ -1147,7 +1141,7 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw) word_cnts = efuse_calculate_word_cnts(hworden); efuse_addr = efuse_addr + (word_cnts * 2) + 1; } else { - bcontinual = false; + continual = false; } } diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 9cd7703c2a30..efded435d596 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -113,32 +113,19 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) /*Set HW definition to determine if it supports ASPM. */ switch (rtlpci->const_support_pciaspm) { - case 0:{ - /*Not support ASPM. */ - bool support_aspm = false; - ppsc->support_aspm = support_aspm; - break; - } - case 1:{ - /*Support ASPM. */ - bool support_aspm = true; - bool support_backdoor = true; - ppsc->support_aspm = support_aspm; - - /*if(priv->oem_id == RT_CID_TOSHIBA && - !priv->ndis_adapter.amd_l1_patch) - support_backdoor = false; */ - - ppsc->support_backdoor = support_backdoor; - - break; - } + case 0: + /*Not support ASPM. */ + ppsc->support_aspm = false; + break; + case 1: + /*Support ASPM. */ + ppsc->support_aspm = true; + ppsc->support_backdoor = true; + break; case 2: /*ASPM value set by chipset. */ - if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { - bool support_aspm = true; - ppsc->support_aspm = support_aspm; - } + if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) + ppsc->support_aspm = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, @@ -152,13 +139,11 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( 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; + return false; } /*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ @@ -166,14 +151,11 @@ 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; + return true; } /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ @@ -191,6 +173,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. pcibridge_linkctrlreg; u16 aspmlevel = 0; + u8 tmp_u1b = 0; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, @@ -204,11 +187,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) _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); - } + /*for promising device will in L0 state after an I/O. */ + pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b); /*Set corresponding value. */ aspmlevel |= BIT(0) | BIT(1); @@ -224,7 +204,6 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg); udelay(50); - } /* diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 0caa81429726..12747b9c71e1 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -192,8 +192,8 @@ struct rtl_pci { u8 const_devicepci_aspm_setting; /*If it supports ASPM, Offset[560h] = 0x40, otherwise Offset[560h] = 0x00. */ - bool b_support_aspm; - bool b_support_backdoor; + bool support_aspm; + bool support_backdoor; /*QOS & EDCA */ enum acm_method acm_method; diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 6b7e217b6b89..c8395fb0c050 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -63,7 +63,6 @@ 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 */ @@ -75,7 +74,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw) /*<3> Disable Adapter */ rtlpriv->cfg->ops->hw_disable(hw); - return status; + return true; } EXPORT_SYMBOL(rtl_ps_disable_nic); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 5ef91374b230..f107660f545d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -171,7 +171,6 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, 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; @@ -184,7 +183,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", value32)); - goto exit; + return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, @@ -204,8 +203,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) ("Polling FW ready success!!" " REG_MCUFWDL:0x%08x .\n", value32)); - err = 0; - goto exit; + return 0; } mdelay(FW_8192C_POLLING_DELAY); @@ -214,9 +212,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); - -exit: - return err; + return -EIO; } int rtl92c_download_fw(struct ieee80211_hw *hw) @@ -226,16 +222,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) struct rtl92c_firmware_header *pfwheader; u8 *pfwdata; u32 fwsize; - int err; enum version_8192c version = rtlhal->version; const struct firmware *firmware; - printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", + printk(KERN_INFO "rtl8192c: Loading firmware file %s\n", rtlpriv->cfg->fw_name); - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); - if (err) { - printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); + if (request_firmware(&firmware, rtlpriv->cfg->fw_name, + rtlpriv->io.dev)) { + printk(KERN_ERR "rtl8192c: Firmware loading failed\n"); return 1; } @@ -267,8 +261,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) _rtl92c_write_fw(hw, version, pfwdata, fwsize); _rtl92c_enable_fw_download(hw, false); - err = _rtl92c_fw_free_to_go(hw); - if (err) { + if (_rtl92c_fw_free_to_go(hw)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Firmware is not ready to run!\n")); } else { @@ -303,7 +296,6 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, 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; @@ -414,7 +406,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, case 1: boxcontent[0] &= ~(BIT(7)); memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 1); + p_cmdbuffer, 1); for (idx = 0; idx < 4; idx++) { rtl_write_byte(rtlpriv, box_reg + idx, @@ -424,7 +416,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, case 2: boxcontent[0] &= ~(BIT(7)); memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 2); + p_cmdbuffer, 2); for (idx = 0; idx < 4; idx++) { rtl_write_byte(rtlpriv, box_reg + idx, @@ -434,7 +426,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, case 3: boxcontent[0] &= ~(BIT(7)); memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 3); + p_cmdbuffer, 3); for (idx = 0; idx < 4; idx++) { rtl_write_byte(rtlpriv, box_reg + idx, @@ -444,9 +436,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, case 4: boxcontent[0] |= (BIT(7)); memcpy((u8 *) (boxextcontent), - p_cmdbuffer + buf_index, 2); + p_cmdbuffer, 2); memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index + 2, 2); + p_cmdbuffer + 2, 2); for (idx = 0; idx < 2; idx++) { rtl_write_byte(rtlpriv, box_extreg + idx, @@ -461,9 +453,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, case 5: boxcontent[0] |= (BIT(7)); memcpy((u8 *) (boxextcontent), - p_cmdbuffer + buf_index, 2); + p_cmdbuffer, 2); memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index + 2, 3); + p_cmdbuffer + 2, 3); for (idx = 0; idx < 2; idx++) { rtl_write_byte(rtlpriv, box_extreg + idx, diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 01226f8e70f9..4ce4853975f1 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -766,7 +766,7 @@ struct rtl_rfkill { #define IQK_MATRIX_REG_NUM 8 #define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) struct iqk_matrix_regs { - bool b_iqk_done; + bool iqk_done; long value[1][IQK_MATRIX_REG_NUM]; }; @@ -1621,19 +1621,19 @@ struct bt_coexist_info { u32 bt_edca_ul; u32 bt_edca_dl; - bool b_init_set; - bool b_bt_busy_traffic; - bool b_bt_traffic_mode_set; - bool b_bt_non_traffic_mode_set; + bool init_set; + bool bt_busy_traffic; + bool bt_traffic_mode_set; + bool bt_non_traffic_mode_set; - bool b_fw_coexist_all_off; - bool b_sw_coexist_all_off; + bool fw_coexist_all_off; + bool sw_coexist_all_off; u32 current_state; u32 previous_state; u8 bt_pre_rssi_state; - u8 b_reg_bt_iso; - u8 b_reg_bt_sco; + u8 reg_bt_iso; + u8 reg_bt_sco; }; -- GitLab From 166389375d5a3894aa00a9c2e490ac4b9af2a891 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:29:44 +0200 Subject: [PATCH 0294/5560] rt2x00: Limit rt2x00pci rxdone processing to 16 entries at once Instead of receiving an unlimited number of frames, stop after 16 entries and reschedule the rxdone tasklet. This allows other tasklets to be run inbetween. 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/rt2800pci.c | 6 ++++-- drivers/net/wireless/rt2x00/rt2x00pci.c | 7 +++++-- drivers/net/wireless/rt2x00/rt2x00pci.h | 5 ++++- drivers/net/wireless/rt2x00/rt61pci.c | 6 ++++-- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 329f3283697b..137a24e520da 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1368,8 +1368,10 @@ static void rt2400pci_tbtt_tasklet(unsigned long data) static void rt2400pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - rt2x00pci_rxdone(rt2x00dev); - rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); + if (rt2x00pci_rxdone(rt2x00dev)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + else + rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); } static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 58277878889e..198fc0a0d77c 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1500,8 +1500,10 @@ static void rt2500pci_tbtt_tasklet(unsigned long data) static void rt2500pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - rt2x00pci_rxdone(rt2x00dev); - rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); + if (rt2x00pci_rxdone(rt2x00dev)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + else + rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); } static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 808073aa9dcc..4672dc99fe46 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -806,8 +806,10 @@ static void rt2800pci_tbtt_tasklet(unsigned long data) static void rt2800pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - rt2x00pci_rxdone(rt2x00dev); - rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); + if (rt2x00pci_rxdone(rt2x00dev)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + else + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); } static void rt2800pci_autowake_tasklet(unsigned long data) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 4dd82b0b0520..9649bd0cd718 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -60,14 +60,15 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); -void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) +bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue = rt2x00dev->rx; struct queue_entry *entry; struct queue_entry_priv_pci *entry_priv; struct skb_frame_desc *skbdesc; + int max_rx = 16; - while (1) { + while (--max_rx) { entry = rt2x00queue_get_entry(queue, Q_INDEX); entry_priv = entry->priv_data; @@ -93,6 +94,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) */ rt2x00lib_rxdone(entry); } + + return !max_rx; } EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 746ce8fe8cf4..07961b8b369a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -101,8 +101,11 @@ struct queue_entry_priv_pci { /** * rt2x00pci_rxdone - Handle RX done events * @rt2x00dev: Device pointer, see &struct rt2x00_dev. + * + * Returns true if there are still rx frames pending and false if all + * pending rx frames were processed. */ -void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); +bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); /* * Device initialization handlers. diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 77e8113b91e1..8ee1514a7943 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2313,8 +2313,10 @@ static void rt61pci_tbtt_tasklet(unsigned long data) static void rt61pci_rxdone_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - rt2x00pci_rxdone(rt2x00dev); - rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); + if (rt2x00pci_rxdone(rt2x00dev)) + rt2x00pci_rxdone(rt2x00dev); + else + rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); } static void rt61pci_autowake_tasklet(unsigned long data) -- GitLab From 2e7798b7c12bdaab4a4aee76d6d1ab7c986234ac Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:30:09 +0200 Subject: [PATCH 0295/5560] rt2x00: Limit rt2800pci txdone processing to 16 entries at once Instead of reporting an unlimited number of tx status reports to mac80211 stop after 16 frames and reschedule the tx status tasklet. This allows other tasklets to be run inbetween. 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/rt2800pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 4672dc99fe46..d3055147ddfb 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -717,12 +717,13 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } -static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) +static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; u32 status; u8 qid; + int max_tx_done = 16; while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); @@ -759,7 +760,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); rt2800_txdone_entry(entry, status); + + if (--max_tx_done == 0) + break; } + + return !max_tx_done; } static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, @@ -780,7 +786,9 @@ static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, static void rt2800pci_txstatus_tasklet(unsigned long data) { - rt2800pci_txdone((struct rt2x00_dev *)data); + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + if (rt2800pci_txdone(rt2x00dev)) + tasklet_schedule(&rt2x00dev->txstatus_tasklet); /* * No need to enable the tx status interrupt here as we always -- GitLab From f78987cf8bb740b7a3636c08e003f1976f860cfc Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:30:36 +0200 Subject: [PATCH 0296/5560] rt2x00: Calculate tx status fifo size instead of hardcoding it Instead of hardcoding the tx status fifo size as 512 calculate it based on the number of tx queues and the number of entries per queue. Also round the size up to a power of 2 as kfifo would otherwise round it down. On rt2800pci this will increase the kfifo size from 512 bytes to 1024 bytes which is then able to hold the tx status for all entries in all tx queues. Furthermore, if the number of tx queues or tx entries changes in the future (use of the MGMT queue for example) the kfifo size doesn't need to be updated. 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/rt2x00dev.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9de9dbe94399..d63b582b6875 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "rt2x00.h" #include "rt2x00lib.h" @@ -811,13 +812,18 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) */ 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 - * status reports. In the worst case (tx status for all tx - * queues gets reported before we've got a chance to handle - * them) 24*4=384 tx status reports need to be cached. + * Allocate the txstatus fifo. In the worst case the tx + * status fifo has to hold the tx status of all entries + * in all tx queues. Hence, calculate the kfifo size as + * tx_queues * entry_num and round up to the nearest + * power of 2. */ - status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512, + int kfifo_size = + roundup_pow_of_two(rt2x00dev->ops->tx_queues * + rt2x00dev->ops->tx->entry_num * + sizeof(u32)); + + status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size, GFP_KERNEL); if (status) return status; -- GitLab From aca7305be5cd9e07f042e6bf6547e7c5635f0041 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:30:59 +0200 Subject: [PATCH 0297/5560] rt2x00: Remove DRIVER_SUPPORT_WATCHDOG flag We can simply check if the driver registered the watchdog callback. There's no need to have an additional flag for that. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 1 - drivers/net/wireless/rt2x00/rt2800usb.c | 1 - drivers/net/wireless/rt2x00/rt2x00.h | 1 - drivers/net/wireless/rt2x00/rt2x00link.c | 11 +++++------ drivers/net/wireless/rt2x00/rt73usb.c | 1 - 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 979fe6596a2d..d9e6cec56cb5 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1796,7 +1796,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); } - __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); /* diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 4e368657a83c..1c99a4f449f5 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -564,7 +564,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index a3940d7300a4..60b1cb05a70d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -674,7 +674,6 @@ enum rt2x00_flags { DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, DRIVER_SUPPORT_LINK_TUNING, - DRIVER_SUPPORT_WATCHDOG, /* * Driver configuration diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index c975b0a12e95..fc8cee91b54e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -413,12 +413,11 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev) { struct link *link = &rt2x00dev->link; - if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || - !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) - return; - - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->watchdog_work, WATCHDOG_INTERVAL); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + rt2x00dev->ops->lib->watchdog) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->watchdog_work, + WATCHDOG_INTERVAL); } void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 02f1148c577e..149e4f928325 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2209,7 +2209,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); - __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); /* * Set the rssi offset. -- GitLab From 75faae8b80171b447bfc4bac448308676fb8a663 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:31:30 +0200 Subject: [PATCH 0298/5560] rt2x00: Restructure bw_comp calculation Move the HT40 check inside the calculation function to make it easier for a later cleanup. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2ee6cebb9b25..2f8af7a806ec 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1819,11 +1819,15 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, u16 eeprom; u8 comp_en; u8 comp_type; - int comp_value; + int comp_value = 0; rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); - if (eeprom == 0xffff) + /* + * HT40 compensation not required. + */ + if (eeprom == 0xffff || + !test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) return 0; if (band == IEEE80211_BAND_2GHZ) { @@ -1865,13 +1869,12 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, u8 eirp_txpower; u8 eirp_txpower_criterion; u8 reg_limit; - int bw_comp = 0; + int bw_comp; if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) return txpower; - if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) - bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band); + bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band); if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { /* -- GitLab From 2af242e19f06cfaade7ac8608c9df8af1e0fbb34 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:32:01 +0200 Subject: [PATCH 0299/5560] rt2x00: Don't recalculate HT40 compensation for each rate Previously the HT40 tx power compensation value was calculated for each rate. However, the calculation is independent of the tx rate and as such can be precalculated and just passed in for each rate. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 32 ++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2f8af7a806ec..26ac8927a7c5 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1861,7 +1861,8 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, enum ieee80211_band band, int power_level, - u8 txpower) + u8 txpower, + int delta) { u32 reg; u16 eeprom; @@ -1869,13 +1870,10 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, u8 eirp_txpower; u8 eirp_txpower_criterion; u8 reg_limit; - int bw_comp; if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) return txpower; - bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band); - if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { /* * Check if eirp txpower exceed txpower_limit. @@ -1898,14 +1896,14 @@ static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, EEPROM_EIRP_MAX_TX_POWER_5GHZ); eirp_txpower = eirp_txpower_criterion + (txpower - criterion) + - (is_rate_b ? 4 : 0) + bw_comp; + (is_rate_b ? 4 : 0) + delta; reg_limit = (eirp_txpower > power_level) ? (eirp_txpower - power_level) : 0; } else reg_limit = 0; - return txpower + bw_comp - reg_limit; + return txpower + delta - reg_limit; } static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, @@ -1919,6 +1917,12 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, u32 offset; enum ieee80211_band band = conf->channel->band; int power_level = conf->power_level; + int delta; + + /* + * Calculate HT40 compensation delta + */ + delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); /* * set to normal bbp tx power control mode: +/- 0dBm @@ -1948,7 +1952,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower); /* @@ -1959,7 +1963,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower); /* @@ -1970,7 +1974,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower); /* @@ -1981,7 +1985,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower); /* read the next four txpower values */ @@ -1997,7 +2001,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower); /* @@ -2008,7 +2012,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower); /* @@ -2019,7 +2023,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower); /* @@ -2030,7 +2034,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3); txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, - power_level, txpower); + power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower); rt2800_register_write(rt2x00dev, offset, reg); -- GitLab From fa71a160272c0eec9c04102ab2a82befb7cb107f Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:32:32 +0200 Subject: [PATCH 0300/5560] rt2x00: Indention cleanup in rt2800lib Fix the indention in rt2800_compesate_txpower and also fix a typo in the function name rt2800_compesate_txpower -> rt2800_compensate_txpower. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 26ac8927a7c5..026513349370 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1857,12 +1857,9 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, return comp_value; } -static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, - int is_rate_b, - enum ieee80211_band band, - int power_level, - u8 txpower, - int delta) +static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, + enum ieee80211_band band, int power_level, + u8 txpower, int delta) { u32 reg; u16 eeprom; @@ -1951,7 +1948,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower); @@ -1962,7 +1959,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower); @@ -1973,7 +1970,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower); @@ -1984,7 +1981,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower); @@ -2000,7 +1997,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower); @@ -2011,7 +2008,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower); @@ -2022,7 +2019,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower); @@ -2033,7 +2030,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3); - txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band, power_level, txpower, delta); rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower); -- GitLab From 2f2bb7e8bdc977c94cdaaf84328526555eba89b1 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:33:04 +0200 Subject: [PATCH 0301/5560] rt2x00: Remove obsolete rt2x00queue_align_payload Since commit d1c3a37ceeb1a5ea02991a0476355f1a1d3b3e83 ("mac80211: clarify alignment docs, fix up alignment") removed the requirement for a 4-byte aligned payload rt2x00queue_align_payload is obsolete as mac80211 will align the payload when it passes the frame to the net stack. As a result we can remove the call to rt2x00queue_align_payload in the rx path and since that's the last user we can remove rt2x00queue_align_payload altogether. One advantage is that we save some alignment operations for frames that don't need to be aligned (for example beause they are not passed to the net stack). Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 -- drivers/net/wireless/rt2x00/rt2x00lib.h | 10 ---------- drivers/net/wireless/rt2x00/rt2x00queue.c | 13 ------------- 3 files changed, 25 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index d63b582b6875..55c1d0332b2a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -512,8 +512,6 @@ void rt2x00lib_rxdone(struct queue_entry *entry) (rxdesc.size > header_length) && (rxdesc.dev_flags & RXDONE_L2PAD)) rt2x00queue_remove_l2pad(entry->skb, header_length); - else - rt2x00queue_align_payload(entry->skb, header_length); /* Trim buffer to correct size */ skb_trim(entry->skb, rxdesc.size); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 2d94cbaf5f4a..63c40d457244 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -118,16 +118,6 @@ void rt2x00queue_free_skb(struct queue_entry *entry); */ void rt2x00queue_align_frame(struct sk_buff *skb); -/** - * rt2x00queue_align_payload - Align 802.11 payload to 4-byte boundary - * @skb: The skb to align - * @header_length: Length of 802.11 header - * - * Align the 802.11 payload to a 4-byte boundary, this could - * mean the header is not aligned properly though. - */ -void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length); - /** * rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary * @skb: The skb to align diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 4b3c70eeef1f..5d8925991ffb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -148,19 +148,6 @@ void rt2x00queue_align_frame(struct sk_buff *skb) skb_trim(skb, frame_length); } -void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length) -{ - unsigned int frame_length = skb->len; - unsigned int align = ALIGN_SIZE(skb, header_length); - - if (!align) - return; - - skb_push(skb, align); - memmove(skb->data, skb->data + align, frame_length); - skb_trim(skb, frame_length); -} - void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) { unsigned int payload_length = skb->len - header_length; -- GitLab From 9e33a3553821418b2c4f53d09311476c55176b13 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:33:40 +0200 Subject: [PATCH 0302/5560] rt2x00: Implement tx power temperature compensation rt2800 devices should adjust their tx power in accordance with the eeproms temperature calibration values. Add a new driver callback gain_calibration that is called every 4 seconds. The rt2800 gain calibration routine simply runs the tx power configuration that takes care of calculating the temperature compensation delta. We don't need to synchronize the calls to rt2800_config_txpower as they should all happen from mac80211's single threaded workqueue. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 106 ++++++++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 133 ++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2800lib.h | 1 + drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 6 + drivers/net/wireless/rt2x00/rt2x00dev.c | 2 + drivers/net/wireless/rt2x00/rt2x00lib.h | 13 +++ drivers/net/wireless/rt2x00/rt2x00link.c | 38 +++++++ 9 files changed, 296 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 70b9abbdeb9e..3b3d851fe266 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2103,6 +2103,59 @@ struct mac_iveiv_entry { #define EEPROM_TXPOWER_BG_1 FIELD16(0x00ff) #define EEPROM_TXPOWER_BG_2 FIELD16(0xff00) +/* + * EEPROM temperature compensation boundaries 802.11BG + * MINUS4: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -4) + * MINUS3: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -3) + */ +#define EEPROM_TSSI_BOUND_BG1 0x0037 +#define EEPROM_TSSI_BOUND_BG1_MINUS4 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_BG1_MINUS3 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11BG + * MINUS2: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -2) + * MINUS1: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -1) + */ +#define EEPROM_TSSI_BOUND_BG2 0x0038 +#define EEPROM_TSSI_BOUND_BG2_MINUS2 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_BG2_MINUS1 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11BG + * REF: Reference TSSI value, no tx power changes needed + * PLUS1: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 1) + */ +#define EEPROM_TSSI_BOUND_BG3 0x0039 +#define EEPROM_TSSI_BOUND_BG3_REF FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_BG3_PLUS1 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11BG + * PLUS2: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 2) + * PLUS3: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 3) + */ +#define EEPROM_TSSI_BOUND_BG4 0x003a +#define EEPROM_TSSI_BOUND_BG4_PLUS2 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_BG4_PLUS3 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11BG + * PLUS4: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 4) + * AGC_STEP: Temperature compensation step. + */ +#define EEPROM_TSSI_BOUND_BG5 0x003b +#define EEPROM_TSSI_BOUND_BG5_PLUS4 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_BG5_AGC_STEP FIELD16(0xff00) + /* * EEPROM TXPOWER 802.11A */ @@ -2112,6 +2165,59 @@ struct mac_iveiv_entry { #define EEPROM_TXPOWER_A_1 FIELD16(0x00ff) #define EEPROM_TXPOWER_A_2 FIELD16(0xff00) +/* + * EEPROM temperature compensation boundaries 802.11A + * MINUS4: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -4) + * MINUS3: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -3) + */ +#define EEPROM_TSSI_BOUND_A1 0x006a +#define EEPROM_TSSI_BOUND_A1_MINUS4 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_A1_MINUS3 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11A + * MINUS2: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -2) + * MINUS1: If the actual TSSI is below this boundary, tx power needs to be + * reduced by (agc_step * -1) + */ +#define EEPROM_TSSI_BOUND_A2 0x006b +#define EEPROM_TSSI_BOUND_A2_MINUS2 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_A2_MINUS1 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11A + * REF: Reference TSSI value, no tx power changes needed + * PLUS1: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 1) + */ +#define EEPROM_TSSI_BOUND_A3 0x006c +#define EEPROM_TSSI_BOUND_A3_REF FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_A3_PLUS1 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11A + * PLUS2: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 2) + * PLUS3: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 3) + */ +#define EEPROM_TSSI_BOUND_A4 0x006d +#define EEPROM_TSSI_BOUND_A4_PLUS2 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_A4_PLUS3 FIELD16(0xff00) + +/* + * EEPROM temperature compensation boundaries 802.11A + * PLUS4: If the actual TSSI is above this boundary, tx power needs to be + * increased by (agc_step * 4) + * AGC_STEP: Temperature compensation step. + */ +#define EEPROM_TSSI_BOUND_A5 0x006e +#define EEPROM_TSSI_BOUND_A5_PLUS4 FIELD16(0x00ff) +#define EEPROM_TSSI_BOUND_A5_AGC_STEP FIELD16(0xff00) + /* * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 026513349370..59302faec395 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1813,6 +1813,116 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); } +static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) +{ + u8 tssi_bounds[9]; + u8 current_tssi; + u16 eeprom; + u8 step; + int i; + + /* + * Read TSSI boundaries for temperature compensation from + * the EEPROM. + * + * Array idx 0 1 2 3 4 5 6 7 8 + * Matching Delta value -4 -3 -2 -1 0 +1 +2 +3 +4 + * Example TSSI bounds 0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00 + */ + if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom); + tssi_bounds[0] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG1_MINUS4); + tssi_bounds[1] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG1_MINUS3); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom); + tssi_bounds[2] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG2_MINUS2); + tssi_bounds[3] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG2_MINUS1); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom); + tssi_bounds[4] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG3_REF); + tssi_bounds[5] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG3_PLUS1); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom); + tssi_bounds[6] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG4_PLUS2); + tssi_bounds[7] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG4_PLUS3); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom); + tssi_bounds[8] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG5_PLUS4); + + step = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_BG5_AGC_STEP); + } else { + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom); + tssi_bounds[0] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A1_MINUS4); + tssi_bounds[1] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A1_MINUS3); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom); + tssi_bounds[2] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A2_MINUS2); + tssi_bounds[3] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A2_MINUS1); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom); + tssi_bounds[4] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A3_REF); + tssi_bounds[5] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A3_PLUS1); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom); + tssi_bounds[6] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A4_PLUS2); + tssi_bounds[7] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A4_PLUS3); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom); + tssi_bounds[8] = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A5_PLUS4); + + step = rt2x00_get_field16(eeprom, + EEPROM_TSSI_BOUND_A5_AGC_STEP); + } + + /* + * Check if temperature compensation is supported. + */ + if (tssi_bounds[4] == 0xff) + return 0; + + /* + * Read current TSSI (BBP 49). + */ + rt2800_bbp_read(rt2x00dev, 49, ¤t_tssi); + + /* + * Compare TSSI value (BBP49) with the compensation boundaries + * from the EEPROM and increase or decrease tx power. + */ + for (i = 0; i <= 3; i++) { + if (current_tssi > tssi_bounds[i]) + break; + } + + if (i == 4) { + for (i = 8; i >= 5; i--) { + if (current_tssi < tssi_bounds[i]) + break; + } + } + + return (i - 4) * step; +} + static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, enum ieee80211_band band) { @@ -1904,7 +2014,8 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, } static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf) + enum ieee80211_band band, + int power_level) { u8 txpower; u16 eeprom; @@ -1912,8 +2023,6 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, u32 reg; u8 r1; u32 offset; - enum ieee80211_band band = conf->channel->band; - int power_level = conf->power_level; int delta; /* @@ -1921,6 +2030,11 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, */ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); + /* + * calculate temperature compensation delta + */ + delta += rt2800_get_gain_calibration_delta(rt2x00dev); + /* * set to normal bbp tx power control mode: +/- 0dBm */ @@ -2041,6 +2155,13 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, } } +void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) +{ + rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band, + rt2x00dev->tx_power); +} +EXPORT_SYMBOL_GPL(rt2800_gain_calibration); + static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf) { @@ -2094,10 +2215,12 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { rt2800_config_channel(rt2x00dev, libconf->conf, &libconf->rf, &libconf->channel); - rt2800_config_txpower(rt2x00dev, libconf->conf); + rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, + libconf->conf->power_level); } if (flags & IEEE80211_CONF_CHANGE_POWER) - rt2800_config_txpower(rt2x00dev, libconf->conf); + rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, + libconf->conf->power_level); if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) rt2800_config_retry_limit(rt2x00dev, libconf); if (flags & IEEE80211_CONF_CHANGE_PS) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 0c92d86a36f4..f2d15941c71a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -181,6 +181,7 @@ void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); +void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev); int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index d3055147ddfb..adc3534254df 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1053,6 +1053,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .link_stats = rt2800_link_stats, .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, + .gain_calibration = rt2800_gain_calibration, .start_queue = rt2800pci_start_queue, .kick_queue = rt2800pci_kick_queue, .stop_queue = rt2800pci_stop_queue, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 1c99a4f449f5..8b3ab3f17eb3 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -629,6 +629,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_stats = rt2800_link_stats, .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, + .gain_calibration = rt2800_gain_calibration, .watchdog = rt2800usb_watchdog, .start_queue = rt2800usb_start_queue, .kick_queue = rt2x00usb_kick_queue, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 60b1cb05a70d..dd0f66ade6e8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -348,6 +348,11 @@ struct link { * to bring the device/driver back into the desired state. */ struct delayed_work watchdog_work; + + /* + * Work structure for scheduling periodic AGC adjustments. + */ + struct delayed_work agc_work; }; enum rt2x00_delayed_flags { @@ -556,6 +561,7 @@ struct rt2x00lib_ops { struct link_qual *qual); void (*link_tuner) (struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); + void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); /* * Data queue handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 55c1d0332b2a..a98c43485239 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -71,6 +71,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) */ rt2x00queue_start_queues(rt2x00dev); rt2x00link_start_tuner(rt2x00dev); + rt2x00link_start_agc(rt2x00dev); /* * Start watchdog monitoring. @@ -93,6 +94,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) /* * Stop all queues */ + rt2x00link_stop_agc(rt2x00dev); rt2x00link_stop_tuner(rt2x00dev); rt2x00queue_stop_queues(rt2x00dev); rt2x00queue_flush_queues(rt2x00dev, true); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 63c40d457244..88f2f9275528 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -32,6 +32,7 @@ */ #define WATCHDOG_INTERVAL round_jiffies_relative(HZ) #define LINK_TUNE_INTERVAL round_jiffies_relative(HZ) +#define AGC_INTERVAL round_jiffies_relative(4 * HZ) /* * rt2x00_rate: Per rate device information @@ -270,6 +271,18 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev); */ void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev); +/** + * rt2x00link_start_agc - Start periodic gain calibration + * @rt2x00dev: Pointer to &struct rt2x00_dev. + */ +void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00link_stop_agc - Stop periodic gain calibration + * @rt2x00dev: Pointer to &struct rt2x00_dev. + */ +void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev); + /** * rt2x00link_register - Initialize link tuning & watchdog functionality * @rt2x00dev: Pointer to &struct rt2x00_dev. diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index fc8cee91b54e..128b3615c08c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -446,8 +446,46 @@ static void rt2x00link_watchdog(struct work_struct *work) WATCHDOG_INTERVAL); } +void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev) +{ + struct link *link = &rt2x00dev->link; + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + rt2x00dev->ops->lib->gain_calibration) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->agc_work, + AGC_INTERVAL); +} + +void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev) +{ + cancel_delayed_work_sync(&rt2x00dev->link.agc_work); +} + +static void rt2x00link_agc(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, link.agc_work.work); + struct link *link = &rt2x00dev->link; + + /* + * When the radio is shutting down we should + * immediately cease the watchdog monitoring. + */ + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + rt2x00dev->ops->lib->gain_calibration(rt2x00dev); + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->agc_work, + AGC_INTERVAL); +} + void rt2x00link_register(struct rt2x00_dev *rt2x00dev) { + INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc); INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); } -- GitLab From 351151e8ace033fe3b1977516b32a6c76e9a3f6d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:34:15 +0200 Subject: [PATCH 0303/5560] rt2x00: Fix STBC transmissions to STAs with Rx STBC > 1 For STBC transmissions rt2x00 used the number of RxSTBC streams the destination STA indicates in its HT capabilities as STBC value in the TXWI. However, the legacy drivers and our own comment in rt2800.h suggest that the STBC field in the TXWI only allows a value of 0 or 1. The values 2 and 3 are reserved (probably for future devices). And indeed, STBC transmissions to STAs indicating more then 1 RxSTBC stream fail when the STBC field is set to something >1. Fix this by only setting the STBC field to 1 when STBC should be used. 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/rt2x00ht.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index ae1219dffaae..e8c0c3e92c2f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -43,8 +43,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ - txdesc->u.ht.stbc = - (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; + /* + * Only one STBC stream is supported for now. + */ + if (tx_info->flags & IEEE80211_TX_CTL_STBC) + txdesc->u.ht.stbc = 1; /* * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the -- GitLab From b35e77cf84137bbb4b6888dc90616eb0b452ea36 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Mon, 28 Mar 2011 13:34:50 +0200 Subject: [PATCH 0304/5560] rt2x00: Add support for the ZyXEL NWD-211AN USB Add new USB ID Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 8b3ab3f17eb3..262bf669e1b1 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -877,6 +877,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zyxel */ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, #ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, -- GitLab From f16d2db704b873d34cec54f992637f3579e10e08 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:35:21 +0200 Subject: [PATCH 0305/5560] rt2x00: Fix tx aggregation problems with some clients Some clients seem to rely upon the reception of BlockAckReqs to flush their rx reorder buffer. In order to fix aggregation for these clients rt2x00 should send a BlockAckReq if the transmission of an AMPDU subframe fails. Introduce a new flag TXDONE_AMPDU to indicate that this is an AMPDU subframe and pass IEEE80211_TX_STAT_AMPDU_NO_BACK to mac80211 if an AMPDU subframe failed during transmission. This fixes aggregation problems with Intel 5100 Windows STAs (and maybe others as well). Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 +++ drivers/net/wireless/rt2x00/rt2x00dev.c | 6 +++++- drivers/net/wireless/rt2x00/rt2x00queue.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 59302faec395..769c05c0cbaa 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -687,6 +687,9 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) mcs = real_mcs; } + if (aggr == 1 || ampdu == 1) + __set_bit(TXDONE_AMPDU, &txdesc.flags); + /* * Ralink has a retry mechanism using a global fallback * table. We setup this fallback table to try the immediate diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a98c43485239..83252d94c2b7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -353,10 +353,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, * which would allow the rc algorithm to better decide on * which rates are suitable. */ - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + if (test_bit(TXDONE_AMPDU, &txdesc->flags) || + tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_info->flags |= IEEE80211_TX_STAT_AMPDU; tx_info->status.ampdu_len = 1; tx_info->status.ampdu_ack_len = success ? 1 : 0; + + if (!success) + tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; } if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 0c8b0c699679..6ae820093997 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -217,6 +217,7 @@ enum txdone_entry_desc_flags { TXDONE_FALLBACK, TXDONE_FAILURE, TXDONE_EXCESSIVE_RETRY, + TXDONE_AMPDU, }; /** -- GitLab From 6a4c499e86f54ed9316a87e7ddc6b7d33adb4976 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:35:51 +0200 Subject: [PATCH 0306/5560] rt2x00: Add an error message when trying to send on a full queue We already tell mac80211 to stop the queue when we hit a certain threshold. Hence, it shouldn't happen at all that a frame gets queued for tx on a full queue. Add an error message for this case. 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/rt2x00queue.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 5d8925991ffb..9fc4a1ec4b43 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -482,8 +482,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, struct skb_frame_desc *skbdesc; u8 rate_idx, rate_flags; - if (unlikely(rt2x00queue_full(queue))) + if (unlikely(rt2x00queue_full(queue))) { + ERROR(queue->rt2x00dev, + "Dropping frame due to full tx queue %d.\n", queue->qid); return -ENOBUFS; + } if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))) { -- GitLab From eecd8250e492ffc4e7b72953cda9c2f3ba0e6ccc Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 28 Mar 2011 17:55:41 -0700 Subject: [PATCH 0307/5560] mwifiex: remove MWIFIEX_BSS_MODE_ macros replace them with NL80211_IFTYPE_ macros Also remove redundant functions mwifiex_drv_get_mode() and mwifiex_bss_ioctl_mode(). Signed-off-by: Bing Zhao Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 4 +- drivers/net/wireless/mwifiex/cfg80211.c | 85 ++++++++++------------ drivers/net/wireless/mwifiex/cfp.c | 3 +- drivers/net/wireless/mwifiex/init.c | 2 +- drivers/net/wireless/mwifiex/ioctl.h | 6 -- drivers/net/wireless/mwifiex/join.c | 12 +-- drivers/net/wireless/mwifiex/main.h | 7 +- drivers/net/wireless/mwifiex/scan.c | 29 ++++---- drivers/net/wireless/mwifiex/sta_cmd.c | 4 +- drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 +- drivers/net/wireless/mwifiex/sta_event.c | 2 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 83 ++------------------- 12 files changed, 74 insertions(+), 165 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index ce6421f3230b..73a6e62f5680 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -109,7 +109,7 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, memset(&mcs[rx_mcs_supp], 0, sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); - if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || + if (priv->bss_mode == NL80211_IFTYPE_STATION || (ht_cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); @@ -418,7 +418,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, } if (bss_desc->bcn_ht_info) { - if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { ht_info = (struct mwifiex_ie_types_htinfo *) *buffer; memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index de86ef879509..701c17980f6d 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -398,13 +398,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, int ret = 0; int status = 0; struct mwifiex_ds_band_cfg band_cfg; - int mode; - u8 wait_option = MWIFIEX_IOCTL_WAIT; u32 config_bands = 0; struct wiphy *wiphy = priv->wdev->wiphy; - mode = mwifiex_drv_get_mode(priv, wait_option); - if (chan) { memset(&band_cfg, 0, sizeof(band_cfg)); /* Set appropriate bands */ @@ -412,10 +408,10 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, config_bands = BAND_B | BAND_G | BAND_GN; else config_bands = BAND_AN | BAND_A; - if (mode == MWIFIEX_BSS_MODE_INFRA - || mode == MWIFIEX_BSS_MODE_AUTO) { + if (priv->bss_mode == NL80211_IFTYPE_STATION + || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) { band_cfg.config_bands = config_bands; - } else if (mode == MWIFIEX_BSS_MODE_IBSS) { + } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { band_cfg.config_bands = config_bands; band_cfg.adhoc_start_band = config_bands; } @@ -432,7 +428,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, } wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " - "mode %d\n", config_bands, band_cfg.sec_chan_offset, mode); + "mode %d\n", config_bands, band_cfg.sec_chan_offset, + priv->bss_mode); if (!chan) return ret; @@ -561,14 +558,6 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) /* * CFG802.11 operation handler to change interface type. - * - * This function creates an IOCTL request, populates it accordingly - * and issues an IOCTL. - * - * The function also maps the CFG802.11 mode type into driver mode type. - * NL80211_IFTYPE_ADHOC -> MWIFIEX_BSS_MODE_IBSS - * NL80211_IFTYPE_STATION -> MWIFIEX_BSS_MODE_INFRA - * NL80211_IFTYPE_UNSPECIFIED -> MWIFIEX_BSS_MODE_AUTO */ static int mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, @@ -578,41 +567,50 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - int mode = -1; struct mwifiex_wait_queue *wait = NULL; - int status = 0; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; + if (priv->bss_mode == type) { + wiphy_warn(wiphy, "already set to required type\n"); + return 0; + } + + priv->bss_mode = type; switch (type) { case NL80211_IFTYPE_ADHOC: - mode = MWIFIEX_BSS_MODE_IBSS; dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC; wiphy_dbg(wiphy, "info: setting interface type to adhoc\n"); break; case NL80211_IFTYPE_STATION: - mode = MWIFIEX_BSS_MODE_INFRA; dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; - wiphy_dbg(wiphy, "info: Setting interface type to managed\n"); + wiphy_dbg(wiphy, "info: setting interface type to managed\n"); break; case NL80211_IFTYPE_UNSPECIFIED: - mode = MWIFIEX_BSS_MODE_AUTO; dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; wiphy_dbg(wiphy, "info: setting interface type to auto\n"); - break; + return 0; default: - ret = -EINVAL; + wiphy_err(wiphy, "unknown interface type: %d\n", type); + return -EINVAL; } - if (ret) - goto done; - status = mwifiex_bss_ioctl_mode(priv, wait, HostCmd_ACT_GEN_SET, &mode); - if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) + wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); + if (!wait) + return -ENOMEM; + + mwifiex_deauthenticate(priv, wait, NULL); + + priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN; + + ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, + HostCmd_ACT_GEN_SET, 0, wait, NULL); + if (!ret) + ret = -EINPROGRESS; + + ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT); + if (ret) ret = -EFAULT; -done: kfree(wait); return ret; } @@ -1046,7 +1044,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ - if (mode == MWIFIEX_BSS_MODE_IBSS) { + if (mode == NL80211_IFTYPE_ADHOC) { /* "privacy" is set only for ad-hoc mode */ if (privacy) { /* @@ -1108,7 +1106,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); - if (mode != MWIFIEX_BSS_MODE_IBSS) { + if (mode != NL80211_IFTYPE_ADHOC) { if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) return -EFAULT; @@ -1129,7 +1127,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) return -EFAULT; - if (mode == MWIFIEX_BSS_MODE_IBSS) { + if (mode == NL80211_IFTYPE_ADHOC) { /* Inform the BSS information to kernel, otherwise * kernel will give a panic after successful assoc */ if (mwifiex_cfg80211_inform_ibss_bss(priv)) @@ -1152,14 +1150,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int ret = 0; - int mode = 0; if (priv->assoc_request) return -EBUSY; - mode = mwifiex_drv_get_mode(priv, MWIFIEX_IOCTL_WAIT); - - if (mode == MWIFIEX_BSS_MODE_IBSS) { + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { wiphy_err(wiphy, "received infra assoc request " "when station is in ibss mode\n"); goto done; @@ -1171,7 +1166,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, (char *) sme->ssid, sme->bssid); ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, - mode, sme->channel, sme, 0); + priv->bss_mode, sme->channel, sme, 0); done: priv->assoc_result = ret; @@ -1191,13 +1186,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); int ret = 0; - int mode = 0; if (priv->ibss_join_request) return -EBUSY; - mode = mwifiex_drv_get_mode(priv, MWIFIEX_IOCTL_WAIT); - if (mode != MWIFIEX_BSS_MODE_IBSS) { + if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { wiphy_err(wiphy, "request to join ibss received " "when station is not in ibss mode\n"); goto done; @@ -1209,8 +1202,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, (char *) params->ssid, params->bssid); ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, - params->bssid, mode, params->channel, NULL, - params->privacy); + params->bssid, priv->bss_mode, + params->channel, NULL, params->privacy); done: priv->ibss_join_result = ret; queue_work(priv->workqueue, &priv->cfg_workqueue); @@ -1301,7 +1294,7 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, /* Clear all the other values */ memset(&mcs[rx_mcs_supp], 0, sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); - if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA || + if (priv->bss_mode == NL80211_IFTYPE_STATION || ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(mcs_set.rx_mask); diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 999ed81512fa..07187a405fee 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -288,8 +288,7 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates) { u32 k = 0; struct mwifiex_adapter *adapter = priv->adapter; - if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) { - /* Infra. mode */ + if (priv->bss_mode == NL80211_IFTYPE_STATION) { switch (adapter->config_bands) { case BAND_B: dev_dbg(adapter->dev, "info: infra band=%d " diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 1c9315d31d9c..00e73eac1af4 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -78,7 +78,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) memset(priv->curr_addr, 0xff, ETH_ALEN); priv->pkt_tx_ctrl = 0; - priv->bss_mode = MWIFIEX_BSS_MODE_INFRA; + priv->bss_mode = NL80211_IFTYPE_STATION; priv->data_rate = 0; /* Initially indicate the rate as auto */ priv->is_data_rate_auto = true; priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index b7e457110b4f..7fb81dfdf8f2 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -66,12 +66,6 @@ struct mwifiex_scan_resp { u8 *scan_table; }; -enum { - MWIFIEX_BSS_MODE_INFRA = 1, - MWIFIEX_BSS_MODE_IBSS, - MWIFIEX_BSS_MODE_AUTO -}; - #define MWIFIEX_PROMISC_MODE 1 #define MWIFIEX_MULTICAST_MODE 2 #define MWIFIEX_ALL_MULTI_MODE 4 diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 08fa721580cb..d8c7c5f8464e 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -808,7 +808,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, /* Set the BSS mode */ adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS; - bss_desc->bss_mode = MWIFIEX_BSS_MODE_IBSS; + bss_desc->bss_mode = NL80211_IFTYPE_ADHOC; adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period); bss_desc->beacon_period = priv->beacon_period; @@ -1289,8 +1289,8 @@ int mwifiex_associate(struct mwifiex_private *priv, u8 current_bssid[ETH_ALEN]; /* Return error if the adapter or table entry is not marked as infra */ - if ((priv->bss_mode != MWIFIEX_BSS_MODE_INFRA) || - (bss_desc->bss_mode != MWIFIEX_BSS_MODE_INFRA)) + if ((priv->bss_mode != NL80211_IFTYPE_STATION) || + (bss_desc->bss_mode != NL80211_IFTYPE_STATION)) return -1; memcpy(¤t_bssid, @@ -1358,7 +1358,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, !mwifiex_ssid_cmp(&bss_desc->ssid, &priv->curr_bss_params.bss_descriptor.ssid) && (priv->curr_bss_params.bss_descriptor.bss_mode == - MWIFIEX_BSS_MODE_IBSS)) { + NL80211_IFTYPE_ADHOC)) { dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID" " is the same as current; not attempting to re-join\n"); return -1; @@ -1421,9 +1421,9 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, int ret = 0; if (priv->media_connected) { - if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) { + if (priv->bss_mode == NL80211_IFTYPE_STATION) { ret = mwifiex_deauthenticate_infra(priv, wait, mac); - } else if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP, HostCmd_ACT_GEN_SET, 0, wait, NULL); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 7bcb2e965aeb..12b9a364d52b 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -877,7 +877,7 @@ mwifiex_queuing_ra_based(struct mwifiex_private *priv) * Currently we assume if we are in Infra, then DA=RA. This might not be * true in the future */ - if ((priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) && + if ((priv->bss_mode == NL80211_IFTYPE_STATION) && (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)) return false; @@ -1003,8 +1003,6 @@ int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); -int mwifiex_drv_get_mode(struct mwifiex_private *priv, u8 wait_option); - int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, @@ -1043,9 +1041,6 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); int mwifiex_main_process(struct mwifiex_adapter *); -int mwifiex_bss_ioctl_mode(struct mwifiex_private *, - struct mwifiex_wait_queue *, - u16 action, int *mode); int mwifiex_bss_ioctl_channel(struct mwifiex_private *, u16 action, struct mwifiex_chan_freq_power *cfp); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 1152beb930ab..69ea32fd1fbd 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -455,8 +455,8 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode) bss_desc->disable_11n = false; /* Don't check for compatibility if roaming */ - if (priv->media_connected && (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) - && (bss_desc->bss_mode == MWIFIEX_BSS_MODE_INFRA)) + if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) + && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) return index; if (priv->wps.session_enable) { @@ -573,8 +573,8 @@ mwifiex_find_best_network_in_list(struct mwifiex_private *priv) for (i = 0; i < adapter->num_in_scan_table; i++) { switch (mode) { - case MWIFIEX_BSS_MODE_INFRA: - case MWIFIEX_BSS_MODE_IBSS: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: if (mwifiex_is_network_compatible(priv, i, mode) >= 0) { if (SCAN_RSSI(adapter->scan_table[i].rssi) > best_rssi) { @@ -584,7 +584,7 @@ mwifiex_find_best_network_in_list(struct mwifiex_private *priv) } } break; - case MWIFIEX_BSS_MODE_AUTO: + case NL80211_IFTYPE_UNSPECIFIED: default: if (SCAN_RSSI(adapter->scan_table[i].rssi) > best_rssi) { @@ -1314,9 +1314,9 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter, } if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS) - bss_entry->bss_mode = MWIFIEX_BSS_MODE_IBSS; + bss_entry->bss_mode = NL80211_IFTYPE_ADHOC; else - bss_entry->bss_mode = MWIFIEX_BSS_MODE_INFRA; + bss_entry->bss_mode = NL80211_IFTYPE_STATION; /* Process variable IE */ @@ -2251,8 +2251,7 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, searching the table for multiple entires for the SSID until no more are found */ while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL, - MWIFIEX_BSS_MODE_AUTO)) >= - 0) { + NL80211_IFTYPE_UNSPECIFIED)) >= 0) { dev_dbg(priv->adapter->dev, "info: Scan: Delete SSID Entry: Found Idx = %d\n", table_idx); @@ -2746,8 +2745,8 @@ mwifiex_find_ssid_in_list(struct mwifiex_private *priv, (priv, (u8) adapter->scan_table[i].bss_band, (u16) adapter->scan_table[i].channel))) { switch (mode) { - case MWIFIEX_BSS_MODE_INFRA: - case MWIFIEX_BSS_MODE_IBSS: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: j = mwifiex_is_network_compatible(priv, i, mode); @@ -2765,7 +2764,7 @@ mwifiex_find_ssid_in_list(struct mwifiex_private *priv, net = j; } break; - case MWIFIEX_BSS_MODE_AUTO: + case NL80211_IFTYPE_UNSPECIFIED: default: /* * Do not check compatibility if the mode @@ -2829,8 +2828,8 @@ mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid, scan_table[i]. channel)) { switch (mode) { - case MWIFIEX_BSS_MODE_INFRA: - case MWIFIEX_BSS_MODE_IBSS: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: net = mwifiex_is_network_compatible(priv, i, mode); break; @@ -2881,7 +2880,7 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, (u8 *) &req_bss->mac_address, ETH_ALEN); /* Make sure we are in the right mode */ - if (priv->bss_mode == MWIFIEX_BSS_MODE_AUTO) + if (priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) priv->bss_mode = req_bss->bss_mode; } diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 795b1eae768d..6fff26153e26 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1089,10 +1089,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, break; case HostCmd_CMD_SET_BSS_MODE: cmd_ptr->command = cpu_to_le16(cmd_no); - if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_ADHOC; - else if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) + else if (priv->bss_mode == NL80211_IFTYPE_STATION) cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_INFRA; cmd_ptr->size = cpu_to_le16(sizeof(struct diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index ae960ddf2bd4..b220b8b62cfa 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -65,7 +65,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, if (le16_to_cpu(pm->action) == EN_AUTO_PS && (le16_to_cpu(pm->params.auto_ps.ps_bitmap) & BITMAP_STA_PS) - && priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) + && priv->bss_mode == NL80211_IFTYPE_ADHOC) adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; } diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index d4a5c1fcefc2..0187185a1fc6 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -82,7 +82,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) priv->is_data_rate_auto = true; priv->data_rate = 0; - if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { priv->adhoc_state = ADHOC_IDLE; priv->adhoc_is_link_sensed = false; } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 362301f417a4..abad07e012f9 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -404,7 +404,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, if (!ssid_bssid) return -1; - if (priv->bss_mode == MWIFIEX_BSS_MODE_INFRA) { + if (priv->bss_mode == NL80211_IFTYPE_STATION) { /* Infra mode */ ret = mwifiex_deauthenticate(priv, NULL, NULL); if (ret) @@ -413,11 +413,11 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, /* Search for the requested SSID in the scan table */ if (ssid_bssid->ssid.ssid_len) i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, - NULL, MWIFIEX_BSS_MODE_INFRA); + NULL, NL80211_IFTYPE_STATION); else i = mwifiex_find_bssid_in_list(priv, (u8 *) &ssid_bssid->bssid, - MWIFIEX_BSS_MODE_INFRA); + NL80211_IFTYPE_STATION); if (i < 0) return -1; @@ -451,11 +451,11 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, if (ssid_bssid->ssid.ssid_len) i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL, - MWIFIEX_BSS_MODE_IBSS); + NL80211_IFTYPE_ADHOC); else i = mwifiex_find_bssid_in_list(priv, (u8 *)&ssid_bssid->bssid, - MWIFIEX_BSS_MODE_IBSS); + NL80211_IFTYPE_ADHOC); if (i >= 0) { dev_dbg(adapter->dev, "info: network found in scan" @@ -1020,50 +1020,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, return 0; } -/* - * IOCTL request handler to set/get BSS mode. - * - * This function prepares the correct firmware command and - * issues it to set or get the BSS mode. - * - * In case the mode is changed, a deauthentication is performed - * first by the function automatically. - */ -int mwifiex_bss_ioctl_mode(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u16 action, int *mode) -{ - int ret = 0; - - if (!mode) - return -1; - - if (action == HostCmd_ACT_GEN_GET) { - *mode = priv->bss_mode; - return 0; - } - - if ((priv->bss_mode == *mode) || (*mode == MWIFIEX_BSS_MODE_AUTO)) { - dev_dbg(priv->adapter->dev, - "info: Already set to required mode! No change!\n"); - priv->bss_mode = *mode; - return 0; - } - - ret = mwifiex_deauthenticate(priv, wait, NULL); - - priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN; - priv->bss_mode = *mode; - if (priv->bss_mode != MWIFIEX_BSS_MODE_AUTO) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, - HostCmd_ACT_GEN_SET, 0, wait, NULL); - if (!ret) - ret = -EINPROGRESS; - } - - return ret; -} - /* * IOCTL request handler to set/get Ad-Hoc channel. * @@ -1236,33 +1192,6 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) return ret; } -/* - * IOCTL request handler to get current driver mode. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int -mwifiex_drv_get_mode(struct mwifiex_private *priv, u8 wait_option) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - int mode = -1; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -1; - - status = mwifiex_bss_ioctl_mode(priv, wait, HostCmd_ACT_GEN_GET, &mode); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - if (wait && (status != -EINPROGRESS)) - kfree(wait); - return mode; -} - /* * IOCTL request handler to get rate. * @@ -1780,7 +1709,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, return -1; } - if (priv->bss_mode == MWIFIEX_BSS_MODE_IBSS) { + if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { /* * IBSS/WPA-None uses only one key (Group) for both receiving * and sending unicast and multicast packets. -- GitLab From f986b6d538c9351c99108b51be9f77ac1b300b16 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 28 Mar 2011 17:55:42 -0700 Subject: [PATCH 0308/5560] mwifiex: remove MWIFIEX_AUTH_MODE_ macros replace them with NL80211_AUTHTYPE_ macros Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 8 ++++---- drivers/net/wireless/mwifiex/init.c | 2 +- drivers/net/wireless/mwifiex/ioctl.h | 5 ----- drivers/net/wireless/mwifiex/join.c | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 701c17980f6d..2d9680044c12 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -600,7 +600,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, mwifiex_deauthenticate(priv, wait, NULL); - priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN; + priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, HostCmd_ACT_GEN_SET, 0, wait, NULL); @@ -1056,7 +1056,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, priv->sec_info.encryption_mode = MWIFIEX_ENCRYPTION_MODE_WEP104; priv->sec_info.authentication_mode = - MWIFIEX_AUTH_MODE_OPEN; + NL80211_AUTHTYPE_OPEN_SYSTEM; } goto done; @@ -1065,9 +1065,9 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, /* Now handle infra mode. "sme" is valid for infra mode only */ if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) - auth_type = MWIFIEX_AUTH_MODE_OPEN; + auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) - auth_type = MWIFIEX_AUTH_MODE_SHARED; + auth_type = NL80211_AUTHTYPE_SHARED_KEY; if (sme->crypto.n_ciphers_pairwise) { pairwise_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 00e73eac1af4..bad436d60590 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -85,7 +85,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR; priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED; - priv->sec_info.authentication_mode = MWIFIEX_AUTH_MODE_OPEN; + priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; priv->sec_info.encryption_mode = MWIFIEX_ENCRYPTION_MODE_NONE; for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++) memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key)); diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 7fb81dfdf8f2..7e0d3160f610 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -268,11 +268,6 @@ struct mwifiex_debug_info { u8 event_received; }; -enum { - MWIFIEX_AUTH_MODE_OPEN = 0x00, - MWIFIEX_AUTH_MODE_SHARED = 0x01, -}; - enum { MWIFIEX_ENCRYPTION_MODE_NONE = 0, MWIFIEX_ENCRYPTION_MODE_WEP40 = 1, diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index d8c7c5f8464e..8a1eb2a9ab13 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -449,7 +449,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, auth_tlv->auth_type = cpu_to_le16( (u16) priv->sec_info.authentication_mode); else - auth_tlv->auth_type = cpu_to_le16(MWIFIEX_AUTH_MODE_OPEN); + auth_tlv->auth_type = cpu_to_le16(NL80211_AUTHTYPE_OPEN_SYSTEM); pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); -- GitLab From fd2e401a35500c9af63dc7ffbc545d2e3c478702 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 28 Mar 2011 17:55:43 -0700 Subject: [PATCH 0309/5560] mwifiex: remove unused radio_on variable and macros The radio_on variable is defined but never used. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 3 --- drivers/net/wireless/mwifiex/init.c | 1 - drivers/net/wireless/mwifiex/ioctl.h | 1 - drivers/net/wireless/mwifiex/main.h | 1 - drivers/net/wireless/mwifiex/sta_ioctl.c | 3 --- 5 files changed, 9 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6593e071dea8..2d9339145e08 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -875,9 +875,6 @@ struct host_cmd_ds_802_11_snmp_mib { u8 value[1]; } __packed; -#define RADIO_ON 0x01 -#define RADIO_OFF 0x00 - struct mwifiex_rate_scope { __le16 type; __le16 length; diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index bad436d60590..6fcdaa9b4294 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -234,7 +234,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf)); adapter->bcn_buf_end = adapter->bcn_buf; - adapter->radio_on = RADIO_ON; adapter->multiple_dtim = 1; adapter->local_listen_interval = 0; /* default value in firmware diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 7e0d3160f610..d01160aa1db8 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -193,7 +193,6 @@ struct mwifiex_bss_info { u32 bss_chan; u32 region_code; u32 media_connected; - u32 radio_on; u32 max_power_level; u32 min_power_level; u32 adhoc_state; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 12b9a364d52b..c26f70441f83 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -611,7 +611,6 @@ struct mwifiex_adapter { u16 curr_tx_buf_size; u32 ioport; enum MWIFIEX_HARDWARE_STATUS hw_status; - u16 radio_on; u16 number_of_antenna; u32 fw_cap_info; /* spin lock for interrupt handling */ diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index abad07e012f9..b163507b1fe0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -790,9 +790,6 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, /* Connection status */ info->media_connected = priv->media_connected; - /* Radio status */ - info->radio_on = adapter->radio_on; - /* Tx power information */ info->max_power_level = priv->max_tx_power_level; info->min_power_level = priv->min_tx_power_level; -- GitLab From 4f3f1ee9f373abfdc09bb3bed87969b7fe0fba06 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Mon, 28 Mar 2011 17:55:44 -0700 Subject: [PATCH 0310/5560] mwifiex: remove unused macros in fw.h These definitions are no longer used after previous cleanups. Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 42 ------------------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 2d9339145e08..b4e4991e58e8 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -107,8 +107,6 @@ enum KEY_INFO_WAPI { #define FIRMWARE_READY 0xfedc -#define FIRMWARE_TRANSFER_NBLOCK 2 - enum MWIFIEX_802_11_PRIVACY_FILTER { MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL, MWIFIEX_802_11_PRIV_FILTER_8021X_WEP @@ -125,50 +123,22 @@ enum MWIFIEX_802_11_WEP_STATUS { #define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) #define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1) #define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2) -#define TLV_TYPE_RSSI_LOW (PROPRIETARY_TLV_BASE_ID + 4) -#define TLV_TYPE_SNR_LOW (PROPRIETARY_TLV_BASE_ID + 5) -#define TLV_TYPE_FAILCOUNT (PROPRIETARY_TLV_BASE_ID + 6) -#define TLV_TYPE_BCNMISS (PROPRIETARY_TLV_BASE_ID + 7) -#define TLV_TYPE_LEDBEHAVIOR (PROPRIETARY_TLV_BASE_ID + 9) #define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10) -#define TLV_TYPE_POWER_TBL_2_4GHZ (PROPRIETARY_TLV_BASE_ID + 12) -#define TLV_TYPE_POWER_TBL_5GHZ (PROPRIETARY_TLV_BASE_ID + 13) #define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16) #define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18) #define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) -#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) -#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23) -#define TLV_TYPE_STARTBGSCANLATER (PROPRIETARY_TLV_BASE_ID + 30) #define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) -#define TLV_TYPE_LINK_QUALITY (PROPRIETARY_TLV_BASE_ID + 36) -#define TLV_TYPE_RSSI_LOW_DATA (PROPRIETARY_TLV_BASE_ID + 38) -#define TLV_TYPE_SNR_LOW_DATA (PROPRIETARY_TLV_BASE_ID + 39) -#define TLV_TYPE_RSSI_HIGH_DATA (PROPRIETARY_TLV_BASE_ID + 40) -#define TLV_TYPE_SNR_HIGH_DATA (PROPRIETARY_TLV_BASE_ID + 41) #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) #define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) -#define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 -#define TLV_TYPE_HT_CAP (PROPRIETARY_TLV_BASE_ID + 74) -#define TLV_TYPE_HT_INFO (PROPRIETARY_TLV_BASE_ID + 75) -#define TLV_SECONDARY_CHANNEL_OFFSET (PROPRIETARY_TLV_BASE_ID + 76) -#define TLV_TYPE_2040BSS_COEXISTENCE (PROPRIETARY_TLV_BASE_ID + 77) -#define TLV_TYPE_OVERLAP_BSS_SCAN_PARAM (PROPRIETARY_TLV_BASE_ID + 78) -#define TLV_TYPE_EXTCAP (PROPRIETARY_TLV_BASE_ID + 79) -#define TLV_TYPE_HT_OPERATIONAL_MCS_SET (PROPRIETARY_TLV_BASE_ID + 80) - -#define ADDBA_TID_MASK (BIT(2) | BIT(3) | BIT(4) | BIT(5)) -#define DELBA_TID_MASK (BIT(12) | BIT(13) | BIT(14) | BIT(15)) #define SSN_MASK 0xfff0 #define BA_RESULT_SUCCESS 0x0 -#define BA_RESULT_FAILURE 0x1 #define BA_RESULT_TIMEOUT 0x2 -#define BA_RESULT_DATA_INVALID 0x3 #define IS_BASTREAM_SETUP(ptr) (ptr->ba_status) @@ -214,7 +184,6 @@ enum MWIFIEX_802_11_WEP_STATUS { #define LLC_SNAP_LEN 8 -#define TLV_TYPE_RATE_DROP_PATTERN (PROPRIETARY_TLV_BASE_ID + 81) #define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) #define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) @@ -282,15 +251,7 @@ enum ENH_PS_MODES { #define HostCmd_RET_BIT 0x8000 #define HostCmd_ACT_GEN_GET 0x0000 #define HostCmd_ACT_GEN_SET 0x0001 -#define HostCmd_ACT_GEN_REMOVE 0x0004 -#define HostCmd_ACT_SET_BOTH 0x0003 -#define HostCmd_ACT_GET_BOTH 0x000c #define HostCmd_RESULT_OK 0x0000 -#define HostCmd_RESULT_ERROR 0x0001 -#define HostCmd_RESULT_NOT_SUPPORT 0x0002 -#define HostCmd_RESULT_PENDING 0x0003 -#define HostCmd_RESULT_BUSY 0x0004 -#define HostCmd_RESULT_PARTIAL_DATA 0x0005 #define HostCmd_ACT_MAC_RX_ON 0x0001 #define HostCmd_ACT_MAC_TX_ON 0x0002 @@ -298,11 +259,8 @@ enum ENH_PS_MODES { #define HostCmd_ACT_MAC_ETHERNETII_ENABLE 0x0010 #define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE 0x0080 #define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100 -#define HostCmd_ACT_MAC_RTS_CTS_ENABLE 0x0200 -#define HostCmd_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400 #define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON 0x2000 -#define HostCmd_BSS_MODE_BSS 0x0001 #define HostCmd_BSS_MODE_IBSS 0x0002 #define HostCmd_BSS_MODE_ANY 0x0003 -- GitLab From 4dd365fd55991b4e54a1d1c255081e6370b9da29 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 30 Mar 2011 18:01:15 -0700 Subject: [PATCH 0311/5560] ieee80211: add HT extended capabilities masks IEEE Std 802.11n, Oct. 29, 2009: 7.3.2.56.5 HT Extended Capabilities field Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 2d1c6117d92c..79690b710665 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -884,6 +884,15 @@ struct ieee80211_ht_cap { #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 +/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */ +#define IEEE80211_HT_EXT_CAP_PCO 0x0001 +#define IEEE80211_HT_EXT_CAP_PCO_TIME 0x0006 +#define IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT 1 +#define IEEE80211_HT_EXT_CAP_MCS_FB 0x0300 +#define IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT 8 +#define IEEE80211_HT_EXT_CAP_HTC_SUP 0x0400 +#define IEEE80211_HT_EXT_CAP_RD_RESPONDER 0x0800 + /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ #define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 #define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C -- GitLab From 2b06bdbe073f8dff93eb476f07352df43dcdba44 Mon Sep 17 00:00:00 2001 From: Marc Yang Date: Wed, 30 Mar 2011 18:12:44 -0700 Subject: [PATCH 0312/5560] mwifiex: cleanup power save related struct and macros remove redundant structures and unused macros Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 37 +++++++++---------- drivers/net/wireless/mwifiex/fw.h | 41 ++++------------------ drivers/net/wireless/mwifiex/init.c | 2 +- drivers/net/wireless/mwifiex/sta_cmdresp.c | 23 ++++++------ 4 files changed, 37 insertions(+), 66 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 3865dd19e4f8..a9aeb31af455 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -275,14 +275,14 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) } if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) == MWIFIEX_BSS_ROLE_STA) { - if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl) + if (!sleep_cfm_buf->ps_cfm_sleep.resp_ctrl) /* Response is not needed for sleep confirm command */ adapter->ps_state = PS_STATE_SLEEP; else adapter->ps_state = PS_STATE_SLEEP_CFM; - if (!sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl + if (!sleep_cfm_buf->ps_cfm_sleep.resp_ctrl && (adapter->is_hs_configured && !adapter->sleep_period.period)) { adapter->pm_wakeup_card_req = true; @@ -1211,15 +1211,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, if (cmd_action == DIS_AUTO_PS) { psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); - cmd->size = cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE); + cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == GET_PS) { psmode_enh->action = cpu_to_le16(GET_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); - cmd->size = cpu_to_le16(S_DS_GEN + AUTO_PS_FIX_SIZE); + cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == EN_AUTO_PS) { psmode_enh->action = cpu_to_le16(EN_AUTO_PS); - psmode_enh->params.auto_ps.ps_bitmap = cpu_to_le16(ps_bitmap); - cmd_size = S_DS_GEN + AUTO_PS_FIX_SIZE; + psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); + cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + + sizeof(psmode_enh->params.ps_bitmap); tlv = (u8 *) cmd + cmd_size; if (ps_bitmap & BITMAP_STA_PS) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1249,24 +1252,23 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, } if (ps_bitmap & BITMAP_AUTO_DS) { - struct mwifiex_ie_types_auto_ds_param *auto_ps_tlv = + struct mwifiex_ie_types_auto_ds_param *auto_ds_tlv = (struct mwifiex_ie_types_auto_ds_param *) tlv; - struct mwifiex_auto_ds_param *auto_ds = - &auto_ps_tlv->param; u16 idletime = 0; - auto_ps_tlv->header.type = + + auto_ds_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM); - auto_ps_tlv->header.len = - cpu_to_le16(sizeof(*auto_ps_tlv) - + auto_ds_tlv->header.len = + cpu_to_le16(sizeof(*auto_ds_tlv) - sizeof(struct mwifiex_ie_types_header)); - cmd_size += sizeof(*auto_ps_tlv); - tlv += sizeof(*auto_ps_tlv); + cmd_size += sizeof(*auto_ds_tlv); + tlv += sizeof(*auto_ds_tlv); if (data_buf) idletime = ((struct mwifiex_ds_auto_ds *) data_buf)->idle_time; dev_dbg(priv->adapter->dev, "cmd: PS Command: Enter Auto Deep Sleep\n"); - auto_ds->deep_sleep_timeout = cpu_to_le16(idletime); + auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); } cmd->size = cpu_to_le16(cmd_size); } @@ -1290,7 +1292,7 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, uint16_t action = le16_to_cpu(ps_mode->action); uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap); uint16_t auto_ps_bitmap = - le16_to_cpu(ps_mode->params.auto_ps.ps_bitmap); + le16_to_cpu(ps_mode->params.ps_bitmap); dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", __func__, resp->result, action); @@ -1318,8 +1320,7 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, } } } else if (action == GET_PS) { - if (ps_bitmap & (BITMAP_STA_PS | BITMAP_UAP_INACT_PS - | BITMAP_UAP_DTIM_PS)) + if (ps_bitmap & BITMAP_STA_PS) adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; else adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index b4e4991e58e8..d981265eb943 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -127,11 +127,14 @@ enum MWIFIEX_802_11_WEP_STATUS { #define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16) #define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18) #define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) - #define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) - #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) +#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) +#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) +#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) #define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) +#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) +#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 @@ -184,11 +187,6 @@ enum MWIFIEX_802_11_WEP_STATUS { #define LLC_SNAP_LEN 8 -#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) -#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) - -#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) - #define MOD_CLASS_HR_DSSS 0x03 #define MOD_CLASS_OFDM 0x07 #define MOD_CLASS_HT 0x08 @@ -553,34 +551,12 @@ struct mwifiex_ps_param { __le16 delay_to_ps; }; -struct mwifiex_auto_ds_param { - __le16 deep_sleep_timeout; -}; - -struct sleep_confirm_param { - __le16 resp_ctrl; -}; - #define BITMAP_AUTO_DS 0x01 #define BITMAP_STA_PS 0x10 -#define BITMAP_UAP_INACT_PS 0x100 -#define BITMAP_UAP_DTIM_PS 0x200 -struct auto_ps_param { - __le16 ps_bitmap; - /* auto deep sleep parameter, - * sta power save parameter - * uap inactivity parameter - * uap DTIM parameter */ -}; - -#define AUTO_PS_FIX_SIZE 4 - -#define TLV_TYPE_AUTO_DS_PARAM (PROPRIETARY_TLV_BASE_ID + 113) -#define TLV_TYPE_PS_PARAM (PROPRIETARY_TLV_BASE_ID + 114) struct mwifiex_ie_types_auto_ds_param { struct mwifiex_ie_types_header header; - struct mwifiex_auto_ds_param param; + __le16 deep_sleep_timeout; } __packed; struct mwifiex_ie_types_ps_param { @@ -593,10 +569,7 @@ struct host_cmd_ds_802_11_ps_mode_enh { union { struct mwifiex_ps_param opt_ps; - struct mwifiex_auto_ds_param auto_ds; - struct sleep_confirm_param sleep_cfm; __le16 ps_bitmap; - struct auto_ps_param auto_ps; } params; } __packed; @@ -1260,7 +1233,7 @@ struct mwifiex_opt_sleep_confirm { __le16 seq_num; __le16 result; __le16 action; - struct sleep_confirm_param sleep_cfm; + __le16 resp_ctrl; } __packed; struct mwifiex_opt_sleep_confirm_buffer { diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 6fcdaa9b4294..43ea87d0f348 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -280,7 +280,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) cpu_to_le16(adapter->sleep_cfm->len); sleep_cfm_buf->ps_cfm_sleep.result = 0; sleep_cfm_buf->ps_cfm_sleep.action = cpu_to_le16(SLEEP_CONFIRM); - sleep_cfm_buf->ps_cfm_sleep.sleep_cfm.resp_ctrl = + sleep_cfm_buf->ps_cfm_sleep.resp_ctrl = cpu_to_le16(RESP_NEEDED); } memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params)); diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index b220b8b62cfa..74add45b99b6 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -46,6 +46,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; struct mwifiex_adapter *adapter = priv->adapter; + struct host_cmd_ds_802_11_ps_mode_enh *pm; unsigned long flags; dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", @@ -55,20 +56,16 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, switch (le16_to_cpu(resp->command)) { case HostCmd_CMD_802_11_PS_MODE_ENH: - { - struct host_cmd_ds_802_11_ps_mode_enh *pm = - &resp->params.psmode_enh; - dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " - "result=0x%x action=0x%X\n", + pm = &resp->params.psmode_enh; + dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " + "result=0x%x action=0x%X\n", resp->result, le16_to_cpu(pm->action)); - /* We do not re-try enter-ps command in ad-hoc mode. */ - if (le16_to_cpu(pm->action) == EN_AUTO_PS && - (le16_to_cpu(pm->params.auto_ps.ps_bitmap) & - BITMAP_STA_PS) - && priv->bss_mode == NL80211_IFTYPE_ADHOC) - adapter->ps_mode = - MWIFIEX_802_11_POWER_MODE_CAM; - } + /* We do not re-try enter-ps command in ad-hoc mode. */ + if (le16_to_cpu(pm->action) == EN_AUTO_PS && + (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && + priv->bss_mode == NL80211_IFTYPE_ADHOC) + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; + break; case HostCmd_CMD_802_11_SCAN: /* Cancel all pending scan command */ -- GitLab From 7327890a1f42046c50030c8723bdbd9266d781bc Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 30 Mar 2011 18:12:45 -0700 Subject: [PATCH 0313/5560] mwifiex: remove struct mwifiex_802_11_fixed_ies struct mwifiex_802_11_fixed_ies is not necessary. struct mwifiex_event_wep_icv_err is not used any more. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 14 -------------- drivers/net/wireless/mwifiex/scan.c | 16 ++++++++-------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index d981265eb943..2b938115b26a 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -343,20 +343,6 @@ enum ENH_PS_MODES { #define EVENT_GET_BSS_TYPE(event_cause) \ (((event_cause) >> 24) & 0x00ff) -struct mwifiex_event_wep_icv_err { - u16 reason_code; - u8 src_mac_addr[ETH_ALEN]; - u8 wep_key_index; - u8 wep_key_length; - u8 key[WLAN_KEY_LEN_WEP104]; -}; - -struct mwifiex_802_11_fixed_ies { - u8 time_stamp[8]; - __le16 beacon_interval; - __le16 capabilities; -}; - struct mwifiex_ie_types_header { __le16 type; __le16 len; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 69ea32fd1fbd..64ed60a80977 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1210,7 +1210,8 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct ieee_types_ds_param_set *ds_param_set; struct ieee_types_cf_param_set *cf_param_set; struct ieee_types_ibss_param_set *ibss_param_set; - struct mwifiex_802_11_fixed_ies fixed_ie; + __le16 beacon_interval; + __le16 capabilities; u8 *current_ptr; u8 *rate; u8 element_len; @@ -1283,22 +1284,21 @@ mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->beacon_buf_size = bytes_left_for_current_beacon; /* Time stamp is 8 bytes long */ - memcpy(fixed_ie.time_stamp, current_ptr, 8); memcpy(bss_entry->time_stamp, current_ptr, 8); current_ptr += 8; bytes_left_for_current_beacon -= 8; /* Beacon interval is 2 bytes long */ - memcpy(&fixed_ie.beacon_interval, current_ptr, 2); - bss_entry->beacon_period = le16_to_cpu(fixed_ie.beacon_interval); + memcpy(&beacon_interval, current_ptr, 2); + bss_entry->beacon_period = le16_to_cpu(beacon_interval); current_ptr += 2; bytes_left_for_current_beacon -= 2; /* Capability information is 2 bytes long */ - memcpy(&fixed_ie.capabilities, current_ptr, 2); - dev_dbg(adapter->dev, "info: InterpretIE: fixed_ie.capabilities=0x%X\n", - fixed_ie.capabilities); - bss_entry->cap_info_bitmap = le16_to_cpu(fixed_ie.capabilities); + memcpy(&capabilities, current_ptr, 2); + dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", + capabilities); + bss_entry->cap_info_bitmap = le16_to_cpu(capabilities); current_ptr += 2; bytes_left_for_current_beacon -= 2; -- GitLab From 8120347de30f98982b8c75243e3b17dd1ee75740 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 31 Mar 2011 19:50:14 -0700 Subject: [PATCH 0314/5560] mwifiex: remove unused macros in decl.h and main.h These macros are leftover of previous cleanup patches. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/decl.h | 24 ------------------------ drivers/net/wireless/mwifiex/main.h | 7 ------- 2 files changed, 31 deletions(-) diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 4e1f115d3ec3..c3c15f9e757e 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -51,7 +51,6 @@ #define MWIFIEX_RATE_BITMAP_MCS127 159 #define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024) -#define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024) #define MWIFIEX_RTS_MIN_VALUE (0) #define MWIFIEX_RTS_MAX_VALUE (2347) @@ -141,13 +140,6 @@ struct mwifiex_bss_attr { u32 bss_num; }; -enum mwifiex_cmd_result_e { - MWIFIEX_CMD_RESULT_SUCCESS = 0, - MWIFIEX_CMD_RESULT_FAILURE = 1, - MWIFIEX_CMD_RESULT_TIMEOUT = 2, - MWIFIEX_CMD_RESULT_INVALID_DATA = 3 -} __packed; - enum mwifiex_wmm_ac_e { WMM_AC_BK, WMM_AC_BE, @@ -155,22 +147,6 @@ enum mwifiex_wmm_ac_e { WMM_AC_VO } __packed; -enum mwifiex_wmm_queue_config_action_e { - MWIFIEX_WMM_QUEUE_CONFIG_ACTION_GET = 0, - MWIFIEX_WMM_QUEUE_CONFIG_ACTION_SET = 1, - MWIFIEX_WMM_QUEUE_CONFIG_ACTION_DEFAULT = 2, - MWIFIEX_WMM_QUEUE_CONFIG_ACTION_MAX -} __packed; - -enum mwifiex_wmm_queue_stats_action_e { - MWIFIEX_WMM_STATS_ACTION_START = 0, - MWIFIEX_WMM_STATS_ACTION_STOP = 1, - MWIFIEX_WMM_STATS_ACTION_GET_CLR = 2, - MWIFIEX_WMM_STATS_ACTION_SET_CFG = 3, /* Not currently used */ - MWIFIEX_WMM_STATS_ACTION_GET_CFG = 4, /* Not currently used */ - MWIFIEX_WMM_STATS_ACTION_MAX -} __packed; - struct mwifiex_device { struct mwifiex_bss_attr bss_attr[MWIFIEX_MAX_BSS_NUM]; }; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index c26f70441f83..43ff149de9db 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -50,8 +50,6 @@ enum { }; #define DRV_MODE_STA 0x1 -#define DRV_MODE_UAP 0x2 -#define DRV_MODE_UAP_STA 0x3 #define SD8787_W0 0x30 #define SD8787_W1 0x31 @@ -74,13 +72,8 @@ struct mwifiex_drv_mode { #define MWIFIEX_TIMER_10S 10000 #define MWIFIEX_TIMER_1S 1000 -#define NL_MAX_PAYLOAD 1024 -#define NL_MULTICAST_GROUP 1 - #define MAX_TX_PENDING 60 -#define HEADER_ALIGNMENT 8 - #define MWIFIEX_UPLD_SIZE (2312) #define MAX_EVENT_SIZE 1024 -- GitLab From 832fd35a545ecde11082d2dab74dd0aef8e0505e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 1 Apr 2011 15:32:16 +0530 Subject: [PATCH 0315/5560] ath9k_hw: Use appropriate rx gain table for AR9485 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 3daf3df02481..aebaad97b190 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -66,8 +66,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* rx/tx gain */ INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9485_common_rx_gain_1_1, - ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2); + ar9485Common_wo_xlna_rx_gain_1_1, + ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485_modes_lowest_ob_db_tx_gain_1_1, ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), @@ -220,8 +220,8 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) default: if (AR_SREV_9485_11(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9485_common_rx_gain_1_1, - ARRAY_SIZE(ar9485_common_rx_gain_1_1), + ar9485Common_wo_xlna_rx_gain_1_1, + ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); else INIT_INI_ARRAY(&ah->iniModesRxGain, -- GitLab From ce57d9e694d98e421e329fbac5d6f5dc5e9e101e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 1 Apr 2011 12:06:48 +0200 Subject: [PATCH 0316/5560] ssb: trivial: use u8 for chip_rev (it's mask is 0xF) 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/scan.c | 2 +- include/linux/ssb/ssb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 29884c00c4d5..7dca719fbcfb 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -307,7 +307,7 @@ int ssb_bus_scan(struct ssb_bus *bus, } else { if (bus->bustype == SSB_BUSTYPE_PCI) { bus->chip_id = pcidev_to_chipid(bus->host_pci); - pci_read_config_word(bus->host_pci, PCI_REVISION_ID, + pci_read_config_byte(bus->host_pci, PCI_REVISION_ID, &bus->chip_rev); bus->chip_package = 0; } else { diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 9659eff52ca2..7e99b348834c 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -308,7 +308,7 @@ struct ssb_bus { /* ID information about the Chip. */ u16 chip_id; - u16 chip_rev; + u8 chip_rev; u16 sprom_offset; u16 sprom_size; /* number of words in sprom */ u8 chip_package; -- GitLab From 6c74608bd479bbe02ce330f83df43c3f535ed200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 1 Apr 2011 12:07:32 +0200 Subject: [PATCH 0317/5560] ssb: pci: trivial: drop useless pointer 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/driver_pcicore.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 0e8d35224614..e0cf29e57919 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -417,11 +417,9 @@ static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) void ssb_pcicore_init(struct ssb_pcicore *pc) { struct ssb_device *dev = pc->dev; - struct ssb_bus *bus; if (!dev) return; - bus = dev->bus; if (!ssb_device_is_enabled(dev)) ssb_device_enable(dev, 0); -- GitLab From 1b1c7acd9709e545399d1b6b89888f025911c0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 1 Apr 2011 12:07:33 +0200 Subject: [PATCH 0318/5560] ssb: pci: fix mdio writes on newer cores (rev 10+) 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/driver_pcicore.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index e0cf29e57919..08fa6fdfc101 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -444,11 +444,35 @@ static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data) pcicore_write32(pc, 0x134, data); } +static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy) +{ + const u16 mdio_control = 0x128; + const u16 mdio_data = 0x12C; + u32 v; + int i; + + v = (1 << 30); /* Start of Transaction */ + v |= (1 << 28); /* Write Transaction */ + v |= (1 << 17); /* Turnaround */ + v |= (0x1F << 18); + v |= (phy << 4); + pcicore_write32(pc, mdio_data, v); + + udelay(10); + for (i = 0; i < 200; i++) { + v = pcicore_read32(pc, mdio_control); + if (v & 0x100 /* Trans complete */) + break; + msleep(1); + } +} + static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, u8 address, u16 data) { const u16 mdio_control = 0x128; const u16 mdio_data = 0x12C; + int max_retries = 10; u32 v; int i; @@ -456,16 +480,22 @@ static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, v |= 0x2; /* MDIO Clock Divisor */ pcicore_write32(pc, mdio_control, v); + if (pc->dev->id.revision >= 10) { + max_retries = 200; + ssb_pcie_mdio_set_phy(pc, device); + } + v = (1 << 30); /* Start of Transaction */ v |= (1 << 28); /* Write Transaction */ v |= (1 << 17); /* Turnaround */ - v |= (u32)device << 22; + if (pc->dev->id.revision < 10) + v |= (u32)device << 22; v |= (u32)address << 18; v |= data; pcicore_write32(pc, mdio_data, v); /* Wait for the device to complete the transaction */ udelay(10); - for (i = 0; i < 10; i++) { + for (i = 0; i < max_retries; i++) { v = pcicore_read32(pc, mdio_control); if (v & 0x100 /* Trans complete */) break; -- GitLab From ba91d1a1bcccd90247b5b9703c1a236cc2e95698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 1 Apr 2011 12:07:34 +0200 Subject: [PATCH 0319/5560] ssb: pci: implement mdio reading 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/driver_pcicore.c | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 08fa6fdfc101..76cbf96001f1 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -467,6 +467,49 @@ static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy) } } +#if 0 +//done but not used yet +static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address) +{ + const u16 mdio_control = 0x128; + const u16 mdio_data = 0x12C; + int max_retries = 10; + u16 ret = 0; + u32 v; + int i; + + v = 0x80; /* Enable Preamble Sequence */ + v |= 0x2; /* MDIO Clock Divisor */ + pcicore_write32(pc, mdio_control, v); + + if (pc->dev->id.revision >= 10) { + max_retries = 200; + ssb_pcie_mdio_set_phy(pc, device); + } + + v = (1 << 30); /* Start of Transaction */ + v |= (1 << 29); /* Read Transaction */ + v |= (1 << 17); /* Turnaround */ + if (pc->dev->id.revision < 10) + v |= (u32)device << 22; + v |= (u32)address << 18; + pcicore_write32(pc, mdio_data, v); + /* Wait for the device to complete the transaction */ + udelay(10); + for (i = 0; i < 200; i++) { + v = pcicore_read32(pc, mdio_control); + if (v & 0x100 /* Trans complete */) { + udelay(10); + ret = pcicore_read32(pc, mdio_data); + break; + } + msleep(1); + } + pcicore_write32(pc, mdio_control, 0); + return ret; +} +#endif + static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, u8 address, u16 data) { -- GitLab From ccc7c28af205888798b51b6cbc0b557ac1170a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 1 Apr 2011 13:26:52 +0200 Subject: [PATCH 0320/5560] ssb: pci: implement serdes workaround 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/driver_pcicore.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 76cbf96001f1..1ba9f0ee6f94 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -15,6 +15,11 @@ #include "ssb_private.h" +static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address); +static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data); +static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address); +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, + u8 address, u16 data); static inline u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) @@ -403,6 +408,27 @@ static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) } #endif /* CONFIG_SSB_PCICORE_HOSTMODE */ +/************************************************** + * Workarounds. + **************************************************/ + +static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc) +{ + return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80; +} + +static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc) +{ + const u8 serdes_pll_device = 0x1D; + const u8 serdes_rx_device = 0x1F; + u16 tmp; + + ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */, + ssb_pcicore_polarity_workaround(pc)); + tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */); + if (tmp & 0x4000) + ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); +} /************************************************** * Generic and Clientmode operation code. @@ -430,6 +456,8 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) #endif /* CONFIG_SSB_PCICORE_HOSTMODE */ if (!pc->hostmode) ssb_pcicore_init_clientmode(pc); + + ssb_pcicore_serdes_workaround(pc); } static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) @@ -467,8 +495,6 @@ static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy) } } -#if 0 -//done but not used yet static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address) { const u16 mdio_control = 0x128; @@ -508,7 +534,6 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address) pcicore_write32(pc, mdio_control, 0); return ret; } -#endif static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, u8 address, u16 data) -- GitLab From 26d59535aa08386b97ece58a27bb16fca4f066db Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Apr 2011 13:52:48 +0200 Subject: [PATCH 0321/5560] mac80211: clean up station cleanup timer We currently run this timer exactly once when a new mac80211 device is registered, but that is completely pointless since it will have no work to do at all. Therefore, remove that and also simplify some code using the timer. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/main.c | 5 ----- net/mac80211/sta_info.c | 13 ++----------- net/mac80211/sta_info.h | 1 - net/mac80211/util.c | 2 +- 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 562d2984c482..dc50fc3153e5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -879,10 +879,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->dynamic_ps_forced_timeout = -1; - result = sta_info_start(local); - if (result < 0) - goto fail_sta_info; - result = ieee80211_wep_init(local); if (result < 0) wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", @@ -945,7 +941,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) rtnl_unlock(); ieee80211_wep_free(local); sta_info_stop(local); - fail_sta_info: destroy_workqueue(local->workqueue); fail_workqueue: wiphy_unregister(local->hw.wiphy); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 5ec0a7c51b6d..999f8fbf0b4b 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -768,9 +768,8 @@ static void sta_info_cleanup(unsigned long data) if (!timer_needed) return; - local->sta_cleanup.expires = - round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); - add_timer(&local->sta_cleanup); + mod_timer(&local->sta_cleanup, + round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL)); } void sta_info_init(struct ieee80211_local *local) @@ -783,14 +782,6 @@ void sta_info_init(struct ieee80211_local *local) setup_timer(&local->sta_cleanup, sta_info_cleanup, (unsigned long)local); - local->sta_cleanup.expires = - round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); -} - -int sta_info_start(struct ieee80211_local *local) -{ - add_timer(&local->sta_cleanup); - return 0; } void sta_info_stop(struct ieee80211_local *local) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 57681149e37f..43238e99cfb3 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -497,7 +497,6 @@ void sta_info_set_tim_bit(struct sta_info *sta); void sta_info_clear_tim_bit(struct sta_info *sta); void sta_info_init(struct ieee80211_local *local); -int sta_info_start(struct ieee80211_local *local); void sta_info_stop(struct ieee80211_local *local); int sta_info_flush(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 556647a910ac..ef0560a2346a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1290,7 +1290,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) } } - add_timer(&local->sta_cleanup); + mod_timer(&local->sta_cleanup, jiffies + 1); mutex_lock(&local->sta_mtx); list_for_each_entry(sta, &local->sta_list, list) -- GitLab From 1e429f3842b5c9b5967a250f4daf78f92436268c Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 18:25:14 -0300 Subject: [PATCH 0322/5560] Bluetooth: Remove gfp_mask param from hci_reassembly() It is unnecessary, once we are always in interrupt context. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index decd60198f31..a80bc1cdb35b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1341,7 +1341,7 @@ int hci_recv_frame(struct sk_buff *skb) EXPORT_SYMBOL(hci_recv_frame); static int hci_reassembly(struct hci_dev *hdev, int type, void *data, - int count, __u8 index, gfp_t gfp_mask) + int count, __u8 index) { int len = 0; int hlen = 0; @@ -1371,7 +1371,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data, break; } - skb = bt_skb_alloc(len, gfp_mask); + skb = bt_skb_alloc(len, GFP_ATOMIC); if (!skb) return -ENOMEM; @@ -1457,8 +1457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) return -EILSEQ; while (count) { - rem = hci_reassembly(hdev, type, data, count, - type - 1, GFP_ATOMIC); + rem = hci_reassembly(hdev, type, data, count, type - 1); if (rem < 0) return rem; @@ -1492,8 +1491,8 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) } else type = bt_cb(skb)->pkt_type; - rem = hci_reassembly(hdev, type, data, - count, STREAM_REASSEMBLY, GFP_ATOMIC); + rem = hci_reassembly(hdev, type, data, count, + STREAM_REASSEMBLY); if (rem < 0) return rem; -- GitLab From e17acd40f6006d0a0e0b1b3f7359ba4d543011c6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 30 Mar 2011 23:57:16 +0300 Subject: [PATCH 0323/5560] Bluetooth: Add mgmt_device_found event This patch adds a device_found event to the Management interface. For now the event only maps to BR/EDR inquiry result HCI events, but in the future the plan is to also use it for the LE device discovery process. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 2 ++ include/net/bluetooth/mgmt.h | 8 ++++++++ net/bluetooth/hci_event.c | 22 ++++++++++++++-------- net/bluetooth/mgmt.c | 17 +++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3b2f09df279a..2a88fc82429b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -787,6 +787,8 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status); int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, u8 status); +int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, + u8 *eir); /* 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 1a6283f9fee8..864d0cbd2d57 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -267,3 +267,11 @@ struct mgmt_ev_auth_failed { struct mgmt_ev_local_name_changed { __u8 name[MGMT_MAX_NAME_LENGTH]; } __packed; + +#define MGMT_EV_DEVICE_FOUND 0x0012 +struct mgmt_ev_device_found { + bdaddr_t bdaddr; + __u8 dev_class[3]; + __s8 rssi; + __u8 eir[HCI_MAX_EIR_LENGTH]; +} __packed; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 833797e9654b..d04011c06be0 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1228,7 +1228,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * hci_dev_lock(hdev); - for (; num_rsp; num_rsp--) { + for (; num_rsp; num_rsp--, info++) { bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; data.pscan_period_mode = info->pscan_period_mode; @@ -1237,8 +1237,9 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * data.clock_offset = info->clock_offset; data.rssi = 0x00; data.ssp_mode = 0x00; - info++; hci_inquiry_cache_update(hdev, &data); + mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0, + NULL); } hci_dev_unlock(hdev); @@ -2158,7 +2159,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct struct inquiry_info_with_rssi_and_pscan_mode *info; info = (void *) (skb->data + 1); - for (; num_rsp; num_rsp--) { + for (; num_rsp; num_rsp--, info++) { bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; data.pscan_period_mode = info->pscan_period_mode; @@ -2167,13 +2168,15 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x00; - info++; hci_inquiry_cache_update(hdev, &data); + mgmt_device_found(hdev->id, &info->bdaddr, + info->dev_class, info->rssi, + NULL); } } else { struct inquiry_info_with_rssi *info = (void *) (skb->data + 1); - for (; num_rsp; num_rsp--) { + for (; num_rsp; num_rsp--, info++) { bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; data.pscan_period_mode = info->pscan_period_mode; @@ -2182,8 +2185,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x00; - info++; hci_inquiry_cache_update(hdev, &data); + mgmt_device_found(hdev->id, &info->bdaddr, + info->dev_class, info->rssi, + NULL); } } @@ -2314,7 +2319,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct hci_dev_lock(hdev); - for (; num_rsp; num_rsp--) { + for (; num_rsp; num_rsp--, info++) { bacpy(&data.bdaddr, &info->bdaddr); data.pscan_rep_mode = info->pscan_rep_mode; data.pscan_period_mode = info->pscan_period_mode; @@ -2323,8 +2328,9 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct data.clock_offset = info->clock_offset; data.rssi = info->rssi; data.ssp_mode = 0x01; - info++; hci_inquiry_cache_update(hdev, &data); + mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, + info->rssi, info->data); } hci_dev_unlock(hdev); diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f87691e04dca..86fb50215485 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2046,3 +2046,20 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, return err; } + +int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, + u8 *eir) +{ + struct mgmt_ev_device_found ev; + + memset(&ev, 0, sizeof(ev)); + + bacpy(&ev.bdaddr, bdaddr); + memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); + ev.rssi = rssi; + + if (eir) + memcpy(ev.eir, eir, sizeof(ev.eir)); + + return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL); +} -- GitLab From a88a9652d25a63ce10b6a5fe680d0ad8f33b9c9b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 30 Mar 2011 13:18:12 +0300 Subject: [PATCH 0324/5560] Bluetooth: Add mgmt_remote_name event This patch adds a new remote_name event to the Management interface which is sent every time the name of a remote device is resolved (over BR/EDR). Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 1 + include/net/bluetooth/mgmt.h | 6 ++++++ net/bluetooth/hci_event.c | 3 +++ net/bluetooth/mgmt.c | 12 ++++++++++++ 4 files changed, 22 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 2a88fc82429b..4093133c1283 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -789,6 +789,7 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, u8 status); int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, u8 *eir); +int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name); /* 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 864d0cbd2d57..6b6ff92ab499 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -275,3 +275,9 @@ struct mgmt_ev_device_found { __s8 rssi; __u8 eir[HCI_MAX_EIR_LENGTH]; } __packed; + +#define MGMT_EV_REMOTE_NAME 0x0013 +struct mgmt_ev_remote_name { + bdaddr_t bdaddr; + __u8 name[MGMT_MAX_NAME_LENGTH]; +} __packed; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d04011c06be0..7a3398d9cd65 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1497,6 +1497,9 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb hci_dev_lock(hdev); + if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) + mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name); + 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; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 86fb50215485..9a61320c5f2e 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -2063,3 +2063,15 @@ int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL); } + +int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) +{ + struct mgmt_ev_remote_name ev; + + memset(&ev, 0, sizeof(ev)); + + bacpy(&ev.bdaddr, bdaddr); + memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); + + return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); +} -- GitLab From 898f8b0b65715843f7afd86f3867270dc9ed8b74 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Mon, 4 Apr 2011 13:43:42 +0900 Subject: [PATCH 0325/5560] ASoC: Fix to avoid compile error This patch fixes to avoid compile error when ASoC codec doesn't use I2C nor SPI on snd_soc_hw_bulk_write_raw(). Signed-off-by: Seungwhan Youn Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 22b099076223..8418b1fa1976 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -414,12 +414,16 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r return -EINVAL; switch (codec->control_type) { +#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) case SND_SOC_I2C: ret = i2c_master_send(codec->control_data, data, len); break; +#endif +#if defined(CONFIG_SPI_MASTER) case SND_SOC_SPI: ret = do_spi_write(codec->control_data, data, len); break; +#endif default: BUG(); } -- GitLab From d420d40e9c044e8fae7957ed82cd63d2afe4147f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Apr 2011 14:55:59 +0900 Subject: [PATCH 0326/5560] ASoC: Remove excessively verbose logging on I2C write We don't need to log every I2C transfer, and certainly not at error level. Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 8418b1fa1976..ed67c160724f 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -245,7 +245,6 @@ static unsigned int do_i2c_read(struct snd_soc_codec *codec, xfer[1].buf = data; ret = i2c_transfer(client->adapter, xfer, 2); - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); if (ret == 2) return 0; else if (ret < 0) -- GitLab From 34bad69cf63efc761b05f603d99e121b83635c08 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Apr 2011 17:55:42 +0900 Subject: [PATCH 0327/5560] ASoC: Fix comment width in soc-cache.c Lines should be less than 80 columns. Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index ed67c160724f..f46a198a48c0 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -393,10 +393,11 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data, #define snd_soc_16_16_spi_write NULL #endif -/* Primitive bulk write support for soc-cache. The data pointed to by `data' needs - * to already be in the form the hardware expects including any leading register specific - * data. Any data written through this function will not go through the cache as it - * only handles writing to volatile or out of bounds registers. +/* Primitive bulk write support for soc-cache. The data pointed to by + * `data' needs to already be in the form the hardware expects + * including any leading register specific data. Any data written + * through this function will not go through the cache as it only + * handles writing to volatile or out of bounds registers. */ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, const void *data, size_t len) -- GitLab From ef49e4fae3f364af8da041dcc1bb4931c749b3da Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Apr 2011 20:48:13 +0900 Subject: [PATCH 0328/5560] ASoC: Add bias level data to DAPM context debugfs This is also in the old sysfs diagnostics but it's nice to have everything in one place. Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 81c4052c127c..05da8a8f0aef 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1304,6 +1304,47 @@ static const struct file_operations dapm_widget_power_fops = { .llseek = default_llseek, }; +static int dapm_bias_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct snd_soc_dapm_context *dapm = file->private_data; + char *level; + + switch (dapm->bias_level) { + case SND_SOC_BIAS_ON: + level = "On\n"; + break; + case SND_SOC_BIAS_PREPARE: + level = "Prepare\n"; + break; + case SND_SOC_BIAS_STANDBY: + level = "Standby\n"; + break; + case SND_SOC_BIAS_OFF: + level = "Off\n"; + break; + default: + BUG(); + level = "Unknown\n"; + break; + } + + return simple_read_from_buffer(user_buf, count, ppos, level, + strlen(level)); +} + +static const struct file_operations dapm_bias_fops = { + .open = dapm_bias_open_file, + .read = dapm_bias_read_file, + .llseek = default_llseek, +}; + void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; @@ -1312,6 +1353,13 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) if (!dapm->debugfs_dapm) return; + d = debugfs_create_file("bias_level", 0444, + dapm->debugfs_dapm, dapm, + &dapm_bias_fops); + if (!d) + dev_warn(dapm->dev, + "ASoC: Failed to create bias level debugfs file\n"); + list_for_each_entry(w, &dapm->card->widgets, list) { if (!w->name || w->dapm != dapm) continue; -- GitLab From 03e9b64b89243ccc6f8f48f5955a5a78a8ca1431 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:27 +0000 Subject: [PATCH 0329/5560] bridge: change arguments to fdb_create Later patch provides ability to create non-local static entry. To make this easier move the updating of the flag values to after the code that creates entry. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_fdb.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 88485cc74dc3..70bd0bf04099 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -320,8 +320,7 @@ static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, struct net_bridge_port *source, - const unsigned char *addr, - int is_local) + const unsigned char *addr) { struct net_bridge_fdb_entry *fdb; @@ -329,10 +328,9 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, if (fdb) { memcpy(fdb->addr.addr, addr, ETH_ALEN); fdb->dst = source; - fdb->is_local = is_local; - fdb->is_static = is_local; + fdb->is_local = 0; + fdb->is_static = 0; fdb->ageing_timer = jiffies; - hlist_add_head_rcu(&fdb->hlist, head); } return fdb; @@ -360,12 +358,15 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, fdb_delete(fdb); } - if (!fdb_create(head, source, addr, 1)) + fdb = fdb_create(head, source, addr); + if (!fdb) return -ENOMEM; + fdb->is_local = fdb->is_static = 1; return 0; } +/* Add entry for local address of interface */ int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr) { @@ -407,8 +408,9 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, } } else { spin_lock(&br->hash_lock); - if (!fdb_find(head, addr)) - fdb_create(head, source, addr, 0); + if (likely(!fdb_find(head, addr))) + fdb_create(head, source, addr); + /* else we lose race and someone else inserts * it first, don't bother updating */ -- GitLab From 7cd8861ab0d907430bbea0af93bc41aee0437efc Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:28 +0000 Subject: [PATCH 0330/5560] bridge: track last used time in forwarding table Adds tracking the last used time in forwarding table. Rename ageing_timer to updated to better describe it. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_fdb.c | 10 +++++----- net/bridge/br_input.c | 5 +++-- net/bridge/br_private.h | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 70bd0bf04099..b39135285f83 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -62,7 +62,7 @@ static inline int has_expired(const struct net_bridge *br, const struct net_bridge_fdb_entry *fdb) { return !fdb->is_static && - time_before_eq(fdb->ageing_timer + hold_time(br), jiffies); + time_before_eq(fdb->updated + hold_time(br), jiffies); } static inline int br_mac_hash(const unsigned char *mac) @@ -140,7 +140,7 @@ void br_fdb_cleanup(unsigned long _data) unsigned long this_timer; if (f->is_static) continue; - this_timer = f->ageing_timer + delay; + this_timer = f->updated + delay; if (time_before_eq(this_timer, jiffies)) fdb_delete(f); else if (time_before(this_timer, next_timer)) @@ -293,7 +293,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, fe->is_local = f->is_local; if (!f->is_static) - fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->ageing_timer); + fe->ageing_timer_value = jiffies_to_clock_t(jiffies - f->updated); ++fe; ++num; } @@ -330,7 +330,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, fdb->dst = source; fdb->is_local = 0; fdb->is_static = 0; - fdb->ageing_timer = jiffies; + fdb->updated = fdb->used = jiffies; hlist_add_head_rcu(&fdb->hlist, head); } return fdb; @@ -404,7 +404,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, } else { /* fastpath: update of existing entry */ fdb->dst = source; - fdb->ageing_timer = jiffies; + fdb->updated = jiffies; } } else { spin_lock(&br->hash_lock); diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index e2160792e1bc..785932d7ad32 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -98,9 +98,10 @@ int br_handle_frame_finish(struct sk_buff *skb) } if (skb) { - if (dst) + if (dst) { + dst->used = jiffies; br_forward(dst->dst, skb, skb2); - else + } else br_flood_forward(br, skb, skb2); } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 387013d33745..a0e6b94c515b 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -64,7 +64,8 @@ struct net_bridge_fdb_entry struct net_bridge_port *dst; struct rcu_head rcu; - unsigned long ageing_timer; + unsigned long updated; + unsigned long used; mac_addr addr; unsigned char is_local; unsigned char is_static; -- GitLab From 664de48bb6c4e167fcdf92a4bddf880030fbfbb3 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:29 +0000 Subject: [PATCH 0331/5560] bridge: split rcu and no-rcu cases of fdb lookup In some cases, look up of forward database entry is done with RCU; and for others no RCU is needed because of locking. Split the two cases into two differnt loops (and take off inline). Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_fdb.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index b39135285f83..a839a5d9d2c7 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -305,8 +305,21 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, return num; } -static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, - const unsigned char *addr) +static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, + const unsigned char *addr) +{ + struct hlist_node *h; + struct net_bridge_fdb_entry *fdb; + + hlist_for_each_entry(fdb, h, head, hlist) { + if (!compare_ether_addr(fdb->addr.addr, addr)) + return fdb; + } + return NULL; +} + +static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head, + const unsigned char *addr) { struct hlist_node *h; struct net_bridge_fdb_entry *fdb; @@ -393,7 +406,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, source->state == BR_STATE_FORWARDING)) return; - fdb = fdb_find(head, addr); + fdb = fdb_find_rcu(head, addr); if (likely(fdb)) { /* attempt to update an entry for a local interface */ if (unlikely(fdb->is_local)) { -- GitLab From b078f0df676233fc7ebc1ab270bd11ef5824bb64 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:30 +0000 Subject: [PATCH 0332/5560] bridge: add netlink notification on forward entry changes This allows applications to query and monitor bridge forwarding table in the same method used for neighbor table. The forward table entries are returned in same structure format as used by the ioctl. If more information is desired in future, the netlink method is extensible. Example (using bridge extensions to iproute2) # br monitor Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_fdb.c | 125 ++++++++++++++++++++++++++++++++++++++++ net/bridge/br_netlink.c | 1 + net/bridge/br_private.h | 1 + 3 files changed, 127 insertions(+) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index a839a5d9d2c7..5e19e61396c3 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -28,6 +28,7 @@ static struct kmem_cache *br_fdb_cache __read_mostly; static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr); +static void fdb_notify(const struct net_bridge_fdb_entry *, int); static u32 fdb_salt __read_mostly; @@ -81,6 +82,7 @@ static void fdb_rcu_free(struct rcu_head *head) static inline void fdb_delete(struct net_bridge_fdb_entry *f) { + fdb_notify(f, RTM_DELNEIGH); hlist_del_rcu(&f->hlist); call_rcu(&f->rcu, fdb_rcu_free); } @@ -345,6 +347,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, fdb->is_static = 0; fdb->updated = fdb->used = jiffies; hlist_add_head_rcu(&fdb->hlist, head); + fdb_notify(fdb, RTM_NEWNEIGH); } return fdb; } @@ -430,3 +433,125 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, spin_unlock(&br->hash_lock); } } + +static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb) +{ + if (fdb->is_local) + return NUD_PERMANENT; + else if (fdb->is_static) + return NUD_NOARP; + else if (has_expired(fdb->dst->br, fdb)) + return NUD_STALE; + else + return NUD_REACHABLE; +} + +static int fdb_fill_info(struct sk_buff *skb, + const struct net_bridge_fdb_entry *fdb, + u32 pid, u32 seq, int type, unsigned int flags) +{ + unsigned long now = jiffies; + struct nda_cacheinfo ci; + struct nlmsghdr *nlh; + struct ndmsg *ndm; + + nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags); + if (nlh == NULL) + return -EMSGSIZE; + + + ndm = nlmsg_data(nlh); + ndm->ndm_family = AF_BRIDGE; + ndm->ndm_pad1 = 0; + ndm->ndm_pad2 = 0; + ndm->ndm_flags = 0; + ndm->ndm_type = 0; + ndm->ndm_ifindex = fdb->dst->dev->ifindex; + ndm->ndm_state = fdb_to_nud(fdb); + + NLA_PUT(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr); + + ci.ndm_used = jiffies_to_clock_t(now - fdb->used); + ci.ndm_confirmed = 0; + ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); + ci.ndm_refcnt = 0; + NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci); + + return nlmsg_end(skb, nlh); + +nla_put_failure: + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; +} + +static inline size_t fdb_nlmsg_size(void) +{ + return NLMSG_ALIGN(sizeof(struct ndmsg)) + + nla_total_size(ETH_ALEN) /* NDA_LLADDR */ + + nla_total_size(sizeof(struct nda_cacheinfo)); +} + +static void fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) +{ + struct net *net = dev_net(fdb->dst->dev); + struct sk_buff *skb; + int err = -ENOBUFS; + + skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC); + if (skb == NULL) + goto errout; + + err = fdb_fill_info(skb, fdb, 0, 0, type, 0); + if (err < 0) { + /* -EMSGSIZE implies BUG in fdb_nlmsg_size() */ + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); + return; +errout: + if (err < 0) + rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); +} + +/* Dump information about entries, in response to GETNEIGH */ +int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct net *net = sock_net(skb->sk); + struct net_device *dev; + int idx = 0; + + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + struct net_bridge *br = netdev_priv(dev); + int i; + + if (!(dev->priv_flags & IFF_EBRIDGE)) + continue; + + for (i = 0; i < BR_HASH_SIZE; i++) { + struct hlist_node *h; + struct net_bridge_fdb_entry *f; + + hlist_for_each_entry_rcu(f, h, &br->hash[i], hlist) { + if (idx < cb->args[0]) + goto skip; + + if (fdb_fill_info(skb, f, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, + RTM_NEWNEIGH, + NLM_F_MULTI) < 0) + break; +skip: + ++idx; + } + } + } + rcu_read_unlock(); + + cb->args[0] = idx; + + return skb->len; +} diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index f8bf4c7f842c..cedcafd115f3 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -196,6 +196,7 @@ int __init br_netlink_init(void) /* Only the first call to __rtnl_register can fail */ __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL); + __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump); return 0; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index a0e6b94c515b..884d245a205a 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -354,6 +354,7 @@ extern int br_fdb_insert(struct net_bridge *br, extern void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr); +extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb); /* br_forward.c */ extern void br_deliver(const struct net_bridge_port *to, -- GitLab From 36fd2b63e3b4336744cf3f6a6c9543ecbec334a7 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:31 +0000 Subject: [PATCH 0333/5560] bridge: allow creating/deleting fdb entries via netlink Use RTM_NEWNEIGH and RTM_DELNEIGH to allow updating of entries in bridge forwarding table. This allows manipulating static entries which is not possible with existing tools. Example (using bridge extensions to iproute2) # br fdb add 00:02:03:04:05:06 dev eth0 Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_fdb.c | 139 ++++++++++++++++++++++++++++++++++++++++ net/bridge/br_netlink.c | 3 + net/bridge/br_private.h | 2 + 3 files changed, 144 insertions(+) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 5e19e61396c3..498f47c1c453 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -555,3 +555,142 @@ int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } + +/* Create new static fdb entry */ +static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, + __u16 state) +{ + struct net_bridge *br = source->br; + struct hlist_head *head = &br->hash[br_mac_hash(addr)]; + struct net_bridge_fdb_entry *fdb; + + fdb = fdb_find(head, addr); + if (fdb) + return -EEXIST; + + fdb = fdb_create(head, source, addr); + if (!fdb) + return -ENOMEM; + + if (state & NUD_PERMANENT) + fdb->is_local = fdb->is_static = 1; + else if (state & NUD_NOARP) + fdb->is_static = 1; + return 0; +} + +/* Add new permanent fdb entry with RTM_NEWNEIGH */ +int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) +{ + struct net *net = sock_net(skb->sk); + struct ndmsg *ndm; + struct nlattr *tb[NDA_MAX+1]; + struct net_device *dev; + struct net_bridge_port *p; + const __u8 *addr; + int err; + + ASSERT_RTNL(); + err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); + if (err < 0) + return err; + + ndm = nlmsg_data(nlh); + if (ndm->ndm_ifindex == 0) { + pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n"); + return -EINVAL; + } + + dev = __dev_get_by_index(net, ndm->ndm_ifindex); + if (dev == NULL) { + pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n"); + return -ENODEV; + } + + if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { + pr_info("bridge: RTM_NEWNEIGH with invalid address\n"); + return -EINVAL; + } + + addr = nla_data(tb[NDA_LLADDR]); + if (!is_valid_ether_addr(addr)) { + pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n"); + return -EINVAL; + } + + p = br_port_get_rtnl(dev); + if (p == NULL) { + pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n", + dev->name); + return -EINVAL; + } + + spin_lock_bh(&p->br->hash_lock); + err = fdb_add_entry(p, addr, ndm->ndm_state); + spin_unlock_bh(&p->br->hash_lock); + + return err; +} + +static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr) +{ + struct net_bridge *br = p->br; + struct hlist_head *head = &br->hash[br_mac_hash(addr)]; + struct net_bridge_fdb_entry *fdb; + + fdb = fdb_find(head, addr); + if (!fdb) + return -ENOENT; + + fdb_delete(fdb); + return 0; +} + +/* Remove neighbor entry with RTM_DELNEIGH */ +int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) +{ + struct net *net = sock_net(skb->sk); + struct ndmsg *ndm; + struct net_bridge_port *p; + struct nlattr *llattr; + const __u8 *addr; + struct net_device *dev; + int err; + + ASSERT_RTNL(); + if (nlmsg_len(nlh) < sizeof(*ndm)) + return -EINVAL; + + ndm = nlmsg_data(nlh); + if (ndm->ndm_ifindex == 0) { + pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n"); + return -EINVAL; + } + + dev = __dev_get_by_index(net, ndm->ndm_ifindex); + if (dev == NULL) { + pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n"); + return -ENODEV; + } + + llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR); + if (llattr == NULL || nla_len(llattr) != ETH_ALEN) { + pr_info("bridge: RTM_DELNEIGH with invalid address\n"); + return -EINVAL; + } + + addr = nla_data(llattr); + + p = br_port_get_rtnl(dev); + if (p == NULL) { + pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n", + dev->name); + return -EINVAL; + } + + spin_lock_bh(&p->br->hash_lock); + err = fdb_delete_by_addr(p, addr); + spin_unlock_bh(&p->br->hash_lock); + + return err; +} diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index cedcafd115f3..fb7d5a7478fe 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -196,6 +196,9 @@ int __init br_netlink_init(void) /* Only the first call to __rtnl_register can fail */ __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL); + + __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL); + __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL); __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump); return 0; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 884d245a205a..4bbe0d14c9a2 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -355,6 +355,8 @@ extern void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, const unsigned char *addr); extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb); +extern int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); +extern int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); /* br_forward.c */ extern void br_deliver(const struct net_bridge_port *to, -- GitLab From bb900b27a2f49b37bc38c08e656ea13048fee13b Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:32 +0000 Subject: [PATCH 0334/5560] bridge: allow creating bridge devices with netlink Add netlink device ops to allow creating bridge device via netlink. This works in a manner similar to vlan, macvlan and bonding. Example: # ip link add link dev br0 type bridge # ip link del dev br0 The change required rearranging initializtion code to deal with being called by create link. Most of the initialization happens in br_dev_setup, but allocation of stats is done in ndo_init callback to deal with allocation failure. Sysfs setup has to wait until after the network device kobject is registered. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br.c | 1 + net/bridge/br_device.c | 41 ++++++++++++++++++++ net/bridge/br_if.c | 83 +++-------------------------------------- net/bridge/br_netlink.c | 57 +++++++++++++++++++++++----- net/bridge/br_notify.c | 6 +++ 5 files changed, 101 insertions(+), 87 deletions(-) diff --git a/net/bridge/br.c b/net/bridge/br.c index 84bbb82599b2..f20c4fd915a8 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -104,3 +104,4 @@ module_init(br_init) module_exit(br_deinit) MODULE_LICENSE("GPL"); MODULE_VERSION(BR_VERSION); +MODULE_ALIAS_RTNL_LINK("bridge"); diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 21e5901186ea..45cfd54b06d3 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -74,6 +74,17 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +static int br_dev_init(struct net_device *dev) +{ + struct net_bridge *br = netdev_priv(dev); + + br->stats = alloc_percpu(struct br_cpu_netstats); + if (!br->stats) + return -ENOMEM; + + return 0; +} + static int br_dev_open(struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); @@ -334,6 +345,7 @@ static const struct ethtool_ops br_ethtool_ops = { static const struct net_device_ops br_netdev_ops = { .ndo_open = br_dev_open, .ndo_stop = br_dev_stop, + .ndo_init = br_dev_init, .ndo_start_xmit = br_dev_xmit, .ndo_get_stats64 = br_get_stats64, .ndo_set_mac_address = br_set_mac_address, @@ -357,18 +369,47 @@ static void br_dev_free(struct net_device *dev) free_netdev(dev); } +static struct device_type br_type = { + .name = "bridge", +}; + void br_dev_setup(struct net_device *dev) { + struct net_bridge *br = netdev_priv(dev); + random_ether_addr(dev->dev_addr); ether_setup(dev); dev->netdev_ops = &br_netdev_ops; dev->destructor = br_dev_free; SET_ETHTOOL_OPS(dev, &br_ethtool_ops); + SET_NETDEV_DEVTYPE(dev, &br_type); dev->tx_queue_len = 0; dev->priv_flags = IFF_EBRIDGE; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX; + + br->dev = dev; + spin_lock_init(&br->lock); + INIT_LIST_HEAD(&br->port_list); + spin_lock_init(&br->hash_lock); + + br->bridge_id.prio[0] = 0x80; + br->bridge_id.prio[1] = 0x00; + + memcpy(br->group_addr, br_group_address, ETH_ALEN); + + br->feature_mask = dev->features; + br->stp_enabled = BR_NO_STP; + br->designated_root = br->bridge_id; + br->bridge_max_age = br->max_age = 20 * HZ; + br->bridge_hello_time = br->hello_time = 2 * HZ; + br->bridge_forward_delay = br->forward_delay = 15 * HZ; + br->ageing_time = 300 * HZ; + + br_netfilter_rtable_init(br); + br_stp_timer_init(br); + br_multicast_init(br); } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 718b60366dfe..7f5379c593d9 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -175,56 +175,6 @@ static void del_br(struct net_bridge *br, struct list_head *head) unregister_netdevice_queue(br->dev, head); } -static struct net_device *new_bridge_dev(struct net *net, const char *name) -{ - struct net_bridge *br; - struct net_device *dev; - - dev = alloc_netdev(sizeof(struct net_bridge), name, - br_dev_setup); - - if (!dev) - return NULL; - dev_net_set(dev, net); - - br = netdev_priv(dev); - br->dev = dev; - - br->stats = alloc_percpu(struct br_cpu_netstats); - if (!br->stats) { - free_netdev(dev); - return NULL; - } - - spin_lock_init(&br->lock); - INIT_LIST_HEAD(&br->port_list); - spin_lock_init(&br->hash_lock); - - br->bridge_id.prio[0] = 0x80; - br->bridge_id.prio[1] = 0x00; - - memcpy(br->group_addr, br_group_address, ETH_ALEN); - - br->feature_mask = dev->features; - br->stp_enabled = BR_NO_STP; - br->designated_root = br->bridge_id; - br->root_path_cost = 0; - br->root_port = 0; - br->bridge_max_age = br->max_age = 20 * HZ; - br->bridge_hello_time = br->hello_time = 2 * HZ; - br->bridge_forward_delay = br->forward_delay = 15 * HZ; - br->topology_change = 0; - br->topology_change_detected = 0; - br->ageing_time = 300 * HZ; - - br_netfilter_rtable_init(br); - - br_stp_timer_init(br); - br_multicast_init(br); - - return dev; -} - /* find an available port number */ static int find_portno(struct net_bridge *br) { @@ -277,42 +227,19 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, return p; } -static struct device_type br_type = { - .name = "bridge", -}; - int br_add_bridge(struct net *net, const char *name) { struct net_device *dev; - int ret; - dev = new_bridge_dev(net, name); + dev = alloc_netdev(sizeof(struct net_bridge), name, + br_dev_setup); + if (!dev) return -ENOMEM; - rtnl_lock(); - if (strchr(dev->name, '%')) { - ret = dev_alloc_name(dev, dev->name); - if (ret < 0) - goto out_free; - } - - SET_NETDEV_DEVTYPE(dev, &br_type); - - ret = register_netdevice(dev); - if (ret) - goto out_free; - - ret = br_sysfs_addbr(dev); - if (ret) - unregister_netdevice(dev); - out: - rtnl_unlock(); - return ret; + dev_net_set(dev, net); -out_free: - free_netdev(dev); - goto out; + return register_netdev(dev); } int br_del_bridge(struct net *net, const char *name) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index fb7d5a7478fe..134a2ff6b98b 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -12,9 +12,11 @@ #include #include +#include #include #include #include + #include "br_private.h" static inline size_t br_nlmsg_size(void) @@ -188,24 +190,61 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) return 0; } +static int br_validate(struct nlattr *tb[], struct nlattr *data[]) +{ + if (tb[IFLA_ADDRESS]) { + if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) + return -EINVAL; + if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) + return -EADDRNOTAVAIL; + } + + return 0; +} + +static struct rtnl_link_ops br_link_ops __read_mostly = { + .kind = "bridge", + .priv_size = sizeof(struct net_bridge), + .setup = br_dev_setup, + .validate = br_validate, +}; int __init br_netlink_init(void) { - if (__rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo)) - return -ENOBUFS; - - /* Only the first call to __rtnl_register can fail */ - __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL); + int err; - __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL); - __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL); - __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump); + err = rtnl_link_register(&br_link_ops); + if (err < 0) + goto err1; + + err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo); + if (err) + goto err2; + err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL); + if (err) + goto err3; + err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL); + if (err) + goto err3; + err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL); + if (err) + goto err3; + err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump); + if (err) + goto err3; return 0; + +err3: + rtnl_unregister_all(PF_BRIDGE); +err2: + rtnl_link_unregister(&br_link_ops); +err1: + return err; } void __exit br_netlink_fini(void) { + rtnl_link_unregister(&br_link_ops); rtnl_unregister_all(PF_BRIDGE); } - diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 7d337c9b6082..7a03bb975375 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c @@ -36,6 +36,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v struct net_bridge *br; int err; + /* register of bridge completed, add sysfs entries */ + if ((dev->priv_flags && IFF_EBRIDGE) && event == NETDEV_REGISTER) { + br_sysfs_addbr(dev); + return NOTIFY_DONE; + } + /* not a port of a bridge */ p = br_port_get_rtnl(dev); if (!p) -- GitLab From 14f98f258f1936e0dba77474bd7eda63f61a9826 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 14:03:33 +0000 Subject: [PATCH 0335/5560] bridge: range check STP parameters Apply restrictions on STP parameters based 802.1D 1998 standard. * Fixes missing locking in set path cost ioctl * Uses common code for both ioctl and sysfs This is based on an earlier patch Sasikanth V but with overhaul. Note: 1. It does NOT enforce the restriction on the relationship max_age and forward delay or hello time because in existing implementation these are set as independant operations. 2. If STP is disabled, there is no restriction on forward delay 3. No restriction on holding time because users use Linux code to act as hub or be sticky. 4. Although standard allow 0-255, Linux only allows 0-63 for port priority because more bits are reserved for port number. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_ioctl.c | 40 +++++++------------------------ net/bridge/br_private.h | 13 ++++++---- net/bridge/br_private_stp.h | 13 ++++++++++ net/bridge/br_stp.c | 48 +++++++++++++++++++++++++++++++++++++ net/bridge/br_stp_if.c | 21 ++++++++++++---- net/bridge/br_sysfs_br.c | 39 +++--------------------------- net/bridge/br_sysfs_if.c | 26 +++++++------------- 7 files changed, 107 insertions(+), 93 deletions(-) diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index cb43312b846e..0459890dba41 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -181,40 +181,19 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - spin_lock_bh(&br->lock); - br->bridge_forward_delay = clock_t_to_jiffies(args[1]); - if (br_is_root_bridge(br)) - br->forward_delay = br->bridge_forward_delay; - spin_unlock_bh(&br->lock); - return 0; + return br_set_forward_delay(br, args[1]); case BRCTL_SET_BRIDGE_HELLO_TIME: - { - unsigned long t = clock_t_to_jiffies(args[1]); if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (t < HZ) - return -EINVAL; - - spin_lock_bh(&br->lock); - br->bridge_hello_time = t; - if (br_is_root_bridge(br)) - br->hello_time = br->bridge_hello_time; - spin_unlock_bh(&br->lock); - return 0; - } + return br_set_hello_time(br, args[1]); case BRCTL_SET_BRIDGE_MAX_AGE: if (!capable(CAP_NET_ADMIN)) return -EPERM; - spin_lock_bh(&br->lock); - br->bridge_max_age = clock_t_to_jiffies(args[1]); - if (br_is_root_bridge(br)) - br->max_age = br->bridge_max_age; - spin_unlock_bh(&br->lock); - return 0; + return br_set_max_age(br, args[1]); case BRCTL_SET_AGEING_TIME: if (!capable(CAP_NET_ADMIN)) @@ -275,19 +254,16 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case BRCTL_SET_PORT_PRIORITY: { struct net_bridge_port *p; - int ret = 0; + int ret; if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (args[2] >= (1<<(16-BR_PORT_BITS))) - return -ERANGE; - spin_lock_bh(&br->lock); if ((p = br_get_port(br, args[1])) == NULL) ret = -EINVAL; else - br_stp_set_port_priority(p, args[2]); + ret = br_stp_set_port_priority(p, args[2]); spin_unlock_bh(&br->lock); return ret; } @@ -295,15 +271,17 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case BRCTL_SET_PATH_COST: { struct net_bridge_port *p; - int ret = 0; + int ret; if (!capable(CAP_NET_ADMIN)) return -EPERM; + spin_lock_bh(&br->lock); if ((p = br_get_port(br, args[1])) == NULL) ret = -EINVAL; else - br_stp_set_path_cost(p, args[2]); + ret = br_stp_set_path_cost(p, args[2]); + spin_unlock_bh(&br->lock); return ret; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 4bbe0d14c9a2..e2a40343aa09 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -495,6 +495,11 @@ extern struct net_bridge_port *br_get_port(struct net_bridge *br, extern void br_init_port(struct net_bridge_port *p); extern void br_become_designated_port(struct net_bridge_port *p); +extern int br_set_forward_delay(struct net_bridge *br, unsigned long x); +extern int br_set_hello_time(struct net_bridge *br, unsigned long x); +extern int br_set_max_age(struct net_bridge *br, unsigned long x); + + /* br_stp_if.c */ extern void br_stp_enable_bridge(struct net_bridge *br); extern void br_stp_disable_bridge(struct net_bridge *br); @@ -505,10 +510,10 @@ extern bool br_stp_recalculate_bridge_id(struct net_bridge *br); extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); extern void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio); -extern void br_stp_set_port_priority(struct net_bridge_port *p, - u8 newprio); -extern void br_stp_set_path_cost(struct net_bridge_port *p, - u32 path_cost); +extern int br_stp_set_port_priority(struct net_bridge_port *p, + unsigned long newprio); +extern int br_stp_set_path_cost(struct net_bridge_port *p, + unsigned long path_cost); extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); /* br_stp_bpdu.c */ diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h index 8b650f7fbfa0..642ef47a867e 100644 --- a/net/bridge/br_private_stp.h +++ b/net/bridge/br_private_stp.h @@ -16,6 +16,19 @@ #define BPDU_TYPE_CONFIG 0 #define BPDU_TYPE_TCN 0x80 +/* IEEE 802.1D-1998 timer values */ +#define BR_MIN_HELLO_TIME (1*HZ) +#define BR_MAX_HELLO_TIME (10*HZ) + +#define BR_MIN_FORWARD_DELAY (2*HZ) +#define BR_MAX_FORWARD_DELAY (30*HZ) + +#define BR_MIN_MAX_AGE (6*HZ) +#define BR_MAX_MAX_AGE (40*HZ) + +#define BR_MIN_PATH_COST 1 +#define BR_MAX_PATH_COST 65535 + struct br_config_bpdu { unsigned topology_change:1; diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 7370d14f634d..bb4383e84de9 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -484,3 +484,51 @@ void br_received_tcn_bpdu(struct net_bridge_port *p) br_topology_change_acknowledge(p); } } + +/* Change bridge STP parameter */ +int br_set_hello_time(struct net_bridge *br, unsigned long val) +{ + unsigned long t = clock_t_to_jiffies(val); + + if (t < BR_MIN_HELLO_TIME || t > BR_MAX_HELLO_TIME) + return -ERANGE; + + spin_lock_bh(&br->lock); + br->bridge_hello_time = t; + if (br_is_root_bridge(br)) + br->hello_time = br->bridge_hello_time; + spin_unlock_bh(&br->lock); + return 0; +} + +int br_set_max_age(struct net_bridge *br, unsigned long val) +{ + unsigned long t = clock_t_to_jiffies(val); + + if (t < BR_MIN_MAX_AGE || t > BR_MAX_MAX_AGE) + return -ERANGE; + + spin_lock_bh(&br->lock); + br->bridge_max_age = t; + if (br_is_root_bridge(br)) + br->max_age = br->bridge_max_age; + spin_unlock_bh(&br->lock); + return 0; + +} + +int br_set_forward_delay(struct net_bridge *br, unsigned long val) +{ + unsigned long t = clock_t_to_jiffies(val); + + if (br->stp_enabled != BR_NO_STP && + (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) + return -ERANGE; + + spin_lock_bh(&br->lock); + br->bridge_forward_delay = t; + if (br_is_root_bridge(br)) + br->forward_delay = br->bridge_forward_delay; + spin_unlock_bh(&br->lock); + return 0; +} diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 9b61d09de9b9..6f615b8192f4 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -20,7 +20,7 @@ /* Port id is composed of priority and port number. - * NB: least significant bits of priority are dropped to + * NB: some bits of priority are dropped to * make room for more ports. */ static inline port_id br_make_port_id(__u8 priority, __u16 port_no) @@ -29,6 +29,8 @@ static inline port_id br_make_port_id(__u8 priority, __u16 port_no) | (port_no & ((1<> BR_PORT_BITS) + /* called under bridge lock */ void br_init_port(struct net_bridge_port *p) { @@ -255,10 +257,14 @@ void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio) } /* called under bridge lock */ -void br_stp_set_port_priority(struct net_bridge_port *p, u8 newprio) +int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio) { - port_id new_port_id = br_make_port_id(newprio, p->port_no); + port_id new_port_id; + + if (newprio > BR_MAX_PORT_PRIORITY) + return -ERANGE; + new_port_id = br_make_port_id(newprio, p->port_no); if (br_is_designated_port(p)) p->designated_port = new_port_id; @@ -269,14 +275,21 @@ void br_stp_set_port_priority(struct net_bridge_port *p, u8 newprio) br_become_designated_port(p); br_port_state_selection(p->br); } + + return 0; } /* called under bridge lock */ -void br_stp_set_path_cost(struct net_bridge_port *p, u32 path_cost) +int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost) { + if (path_cost < BR_MIN_PATH_COST || + path_cost > BR_MAX_PATH_COST) + return -ERANGE; + p->path_cost = path_cost; br_configuration_update(p->br); br_port_state_selection(p->br); + return 0; } ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id) diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index 5c1e5559ebba..68b893ea8c3a 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c @@ -43,9 +43,7 @@ static ssize_t store_bridge_parm(struct device *d, if (endp == buf) return -EINVAL; - spin_lock_bh(&br->lock); err = (*set)(br, val); - spin_unlock_bh(&br->lock); return err ? err : len; } @@ -57,20 +55,11 @@ static ssize_t show_forward_delay(struct device *d, return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay)); } -static int set_forward_delay(struct net_bridge *br, unsigned long val) -{ - unsigned long delay = clock_t_to_jiffies(val); - br->forward_delay = delay; - if (br_is_root_bridge(br)) - br->bridge_forward_delay = delay; - return 0; -} - static ssize_t store_forward_delay(struct device *d, struct device_attribute *attr, const char *buf, size_t len) { - return store_bridge_parm(d, buf, len, set_forward_delay); + return store_bridge_parm(d, buf, len, br_set_forward_delay); } static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR, show_forward_delay, store_forward_delay); @@ -82,24 +71,11 @@ static ssize_t show_hello_time(struct device *d, struct device_attribute *attr, jiffies_to_clock_t(to_bridge(d)->hello_time)); } -static int set_hello_time(struct net_bridge *br, unsigned long val) -{ - unsigned long t = clock_t_to_jiffies(val); - - if (t < HZ) - return -EINVAL; - - br->hello_time = t; - if (br_is_root_bridge(br)) - br->bridge_hello_time = t; - return 0; -} - static ssize_t store_hello_time(struct device *d, struct device_attribute *attr, const char *buf, size_t len) { - return store_bridge_parm(d, buf, len, set_hello_time); + return store_bridge_parm(d, buf, len, br_set_hello_time); } static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time, store_hello_time); @@ -111,19 +87,10 @@ static ssize_t show_max_age(struct device *d, struct device_attribute *attr, jiffies_to_clock_t(to_bridge(d)->max_age)); } -static int set_max_age(struct net_bridge *br, unsigned long val) -{ - unsigned long t = clock_t_to_jiffies(val); - br->max_age = t; - if (br_is_root_bridge(br)) - br->bridge_max_age = t; - return 0; -} - static ssize_t store_max_age(struct device *d, struct device_attribute *attr, const char *buf, size_t len) { - return store_bridge_parm(d, buf, len, set_max_age); + return store_bridge_parm(d, buf, len, br_set_max_age); } static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age); diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index fd5799c9bc8d..6229b62749e8 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -23,7 +23,7 @@ struct brport_attribute { struct attribute attr; ssize_t (*show)(struct net_bridge_port *, char *); - ssize_t (*store)(struct net_bridge_port *, unsigned long); + int (*store)(struct net_bridge_port *, unsigned long); }; #define BRPORT_ATTR(_name,_mode,_show,_store) \ @@ -38,27 +38,17 @@ static ssize_t show_path_cost(struct net_bridge_port *p, char *buf) { return sprintf(buf, "%d\n", p->path_cost); } -static ssize_t store_path_cost(struct net_bridge_port *p, unsigned long v) -{ - br_stp_set_path_cost(p, v); - return 0; -} + static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR, - show_path_cost, store_path_cost); + show_path_cost, br_stp_set_path_cost); static ssize_t show_priority(struct net_bridge_port *p, char *buf) { return sprintf(buf, "%d\n", p->priority); } -static ssize_t store_priority(struct net_bridge_port *p, unsigned long v) -{ - if (v >= (1<<(16-BR_PORT_BITS))) - return -ERANGE; - br_stp_set_port_priority(p, v); - return 0; -} + static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR, - show_priority, store_priority); + show_priority, br_stp_set_port_priority); static ssize_t show_designated_root(struct net_bridge_port *p, char *buf) { @@ -136,7 +126,7 @@ static ssize_t show_hold_timer(struct net_bridge_port *p, } static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL); -static ssize_t store_flush(struct net_bridge_port *p, unsigned long v) +static int store_flush(struct net_bridge_port *p, unsigned long v) { br_fdb_delete_by_port(p->br, p, 0); // Don't delete local entry return 0; @@ -148,7 +138,7 @@ static ssize_t show_hairpin_mode(struct net_bridge_port *p, char *buf) int hairpin_mode = (p->flags & BR_HAIRPIN_MODE) ? 1 : 0; return sprintf(buf, "%d\n", hairpin_mode); } -static ssize_t store_hairpin_mode(struct net_bridge_port *p, unsigned long v) +static int store_hairpin_mode(struct net_bridge_port *p, unsigned long v) { if (v) p->flags |= BR_HAIRPIN_MODE; @@ -165,7 +155,7 @@ static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) return sprintf(buf, "%d\n", p->multicast_router); } -static ssize_t store_multicast_router(struct net_bridge_port *p, +static int store_multicast_router(struct net_bridge_port *p, unsigned long v) { return br_multicast_set_port_router(p, v); -- GitLab From e3f6a652fd0e828de586a3a87b56c07f7a32259a Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Apr 2011 11:25:03 +0900 Subject: [PATCH 0336/5560] IPVS: combine consecutive #ifdef CONFIG_PROC_FS blocks Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_ctl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 33733c8872e7..36f4495cfdbf 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1984,9 +1984,6 @@ static const struct file_operations ip_vs_info_fops = { .release = seq_release_private, }; -#endif - -#ifdef CONFIG_PROC_FS static int ip_vs_stats_show(struct seq_file *seq, void *v) { struct net *net = seq_file_single_net(seq); -- GitLab From 1168ac22314d11447976d7803facc2744a0308ad Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:32 -0700 Subject: [PATCH 0337/5560] Staging: hv: Make vmbus driver a pci driver Make vmbus driver a pci driver. This is in preparation to cleaning up the root device management as well as the irq allocation for this driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 63 +++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index b473f468dd83..1ef2f0fa73ad 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -40,6 +40,8 @@ #define VMBUS_IRQ 0x5 #define VMBUS_IRQ_VECTOR IRQ5_VECTOR +struct pci_dev *hv_pci_dev; + /* Main vmbus driver data structure */ struct vmbus_driver_context { @@ -977,36 +979,24 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) } } -static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = { - { - .ident = "Hyper-V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), - }, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table); -static int __init vmbus_init(void) + +static int __devinit hv_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { - DPRINT_INFO(VMBUS_DRV, - "Vmbus initializing.... current log level 0x%x (%x,%x)", - vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel)); - /* Todo: it is used for loglevel, to be ported to new kernel. */ + int err; - if (!dmi_check_system(microsoft_hv_dmi_table)) - return -ENODEV; + hv_pci_dev = pdev; - return vmbus_bus_init(); -} + err = pci_enable_device(pdev); + if (err) + return err; -static void __exit vmbus_exit(void) -{ - vmbus_bus_exit(); - /* Todo: it is used for loglevel, to be ported to new kernel. */ + err = vmbus_bus_init(); + if (err) + pci_disable_device(pdev); + + return err; } /* @@ -1021,10 +1011,29 @@ static const struct pci_device_id microsoft_hv_pci_table[] = { }; MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); +static struct pci_driver hv_bus_driver = { + .name = "hv_bus", + .probe = hv_pci_probe, + .id_table = microsoft_hv_pci_table, +}; + +static int __init hv_pci_init(void) +{ + return pci_register_driver(&hv_bus_driver); +} + +static void __exit hv_pci_exit(void) +{ + vmbus_bus_exit(); + pci_unregister_driver(&hv_bus_driver); +} + + + MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); module_param(vmbus_irq, int, S_IRUGO); module_param(vmbus_loglevel, int, S_IRUGO); -module_init(vmbus_init); -module_exit(vmbus_exit); +module_init(hv_pci_init); +module_exit(hv_pci_exit); -- GitLab From 800b6902fdc86f48f39c1db8fb2ec2116058a1c7 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:33 -0700 Subject: [PATCH 0338/5560] Staging: hv: Cleanup root device handling Now we can complete the cleanup of the root device management - use the pci device as the root device for all Hyper-V devices. As part of this cleanup get rid of the root device object from vmbus_driver_context. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 130 ++------------------------------- 1 file changed, 8 insertions(+), 122 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 1ef2f0fa73ad..3d2789b4c8c8 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -44,13 +44,9 @@ struct pci_dev *hv_pci_dev; /* Main vmbus driver data structure */ struct vmbus_driver_context { - struct bus_type bus; struct tasklet_struct msg_dpc; struct tasklet_struct event_dpc; - - /* The bus root device */ - struct hv_device device_ctx; }; static int vmbus_match(struct device *device, struct device_driver *driver); @@ -62,7 +58,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env); static irqreturn_t vmbus_isr(int irq, void *dev_id); static void vmbus_device_release(struct device *device); -static void vmbus_bus_release(struct device *device); static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, @@ -119,54 +114,6 @@ static struct vmbus_driver_context vmbus_drv = { static const char *driver_name = "hyperv"; -/* - * Windows vmbus does not defined this. - * We defined this to be consistent with other devices - */ -/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ -static const struct hv_guid device_type = { - .data = { - 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, - 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 - } -}; - -/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ -static const struct hv_guid device_id = { - .data = { - 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, - 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 - } -}; - -static struct hv_device *vmbus_device; /* vmbus root device */ - - -/* - * vmbus_dev_add - Callback when the root bus device is added - */ -static int vmbus_dev_add(struct hv_device *dev, void *info) -{ - u32 *irqvector = info; - int ret; - - vmbus_device = dev; - - memcpy(&vmbus_device->dev_type, &device_type, sizeof(struct hv_guid)); - memcpy(&vmbus_device->dev_instance, &device_id, - sizeof(struct hv_guid)); - - /* strcpy(dev->name, "vmbus"); */ - /* SynIC setup... */ - on_each_cpu(hv_synic_init, (void *)irqvector, 1); - - /* Connect to VMBus in the root partition */ - ret = vmbus_connect(); - - /* VmbusSendEvent(device->localPortId+1); */ - return ret; -} - struct onmessage_work_context { struct work_struct work; @@ -418,17 +365,13 @@ static ssize_t vmbus_show_device_attr(struct device *dev, * * Here, we * - initialize the vmbus driver context - * - setup various driver entry points * - invoke the vmbus hv main init routine * - get the irq resource - * - invoke the vmbus to add the vmbus root device - * - setup the vmbus root device * - retrieve the channel offers */ static int vmbus_bus_init(void) { struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; - struct hv_device *dev_ctx = &vmbus_drv.device_ctx; int ret; unsigned int vector; @@ -485,45 +428,19 @@ static int vmbus_bus_init(void) DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); - /* Add the root device */ - memset(dev_ctx, 0, sizeof(struct hv_device)); - - ret = vmbus_dev_add(dev_ctx, &vector); - if (ret != 0) { - DPRINT_ERR(VMBUS_DRV, - "ERROR - Unable to add vmbus root device"); - - free_irq(vmbus_irq, NULL); - - bus_unregister(&vmbus_drv_ctx->bus); - - ret = -1; - goto cleanup; - } - /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */ - dev_set_name(&dev_ctx->device, "vmbus_0_0"); - - /* No need to bind a driver to the root device. */ - dev_ctx->device.parent = NULL; - /* NULL; vmbus_remove() does not get invoked */ - dev_ctx->device.bus = &vmbus_drv_ctx->bus; - - /* Setup the device dispatch table */ - dev_ctx->device.release = vmbus_bus_release; - - /* register the root device */ - ret = device_register(&dev_ctx->device); + /* + * Notify the hypervisor of our irq and + * connect to the host. + */ + on_each_cpu(hv_synic_init, (void *)&vector, 1); + ret = vmbus_connect(); if (ret) { - DPRINT_ERR(VMBUS_DRV, - "ERROR - Unable to register vmbus root device"); - free_irq(vmbus_irq, NULL); bus_unregister(&vmbus_drv_ctx->bus); - - ret = -1; goto cleanup; } + vmbus_request_offers(); wait_for_completion(&hv_channel_ready); @@ -540,7 +457,6 @@ static void vmbus_bus_exit(void) { struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; - struct hv_device *dev_ctx = &vmbus_drv.device_ctx; vmbus_release_unattached_channels(); vmbus_disconnect(); @@ -548,9 +464,6 @@ static void vmbus_bus_exit(void) hv_cleanup(); - /* Unregister the root bus device */ - device_unregister(&dev_ctx->device); - bus_unregister(&vmbus_drv_ctx->bus); free_irq(vmbus_irq, NULL); @@ -674,7 +587,7 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) /* The new device belongs to this bus */ child_device_obj->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ - child_device_obj->device.parent = &vmbus_device->device; + child_device_obj->device.parent = &hv_pci_dev->dev; child_device_obj->device.release = vmbus_device_release; /* @@ -875,14 +788,6 @@ static int vmbus_remove(struct device *child_device) int ret; struct hv_driver *drv; - /* Special case root bus device */ - if (child_device->parent == NULL) { - /* - * No-op since it is statically defined and handle in - * vmbus_bus_exit() - */ - return 0; - } if (child_device->driver) { drv = drv_to_hv_drv(child_device->driver); @@ -911,14 +816,6 @@ static void vmbus_shutdown(struct device *child_device) { struct hv_driver *drv; - /* Special case root bus device */ - if (child_device->parent == NULL) { - /* - * No-op since it is statically defined and handle in - * vmbus_bus_exit() - */ - return; - } /* The device may not be attached yet */ if (!child_device->driver) @@ -933,17 +830,6 @@ static void vmbus_shutdown(struct device *child_device) return; } -/* - * vmbus_bus_release - Final callback release of the vmbus root device - */ -static void vmbus_bus_release(struct device *device) -{ - /* FIXME */ - /* Empty release functions are a bug, or a major sign - * of a problem design, this MUST BE FIXED! */ - dev_err(device, "%s needs to be fixed!\n", __func__); - WARN_ON(1); -} /* * vmbus_device_release - Final callback release of the vmbus child device -- GitLab From 52e5c1cec89879bd64eb4e681b4cb1525eabb472 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:34 -0700 Subject: [PATCH 0339/5560] Staging: hv: Cleanup irq management Now that vmbus_driver is a pci driver, cleanup the irq allocation mess by using the standard irq allocation mechanisms. Note that this patch generates an error when the checkpatch script is run because of the IRQF_SAMPLE_RANDOM flag used in request_irq() function. This interrupt may be the only external event this VM will get and consequently if this flag (IRQF_SAMPLE_RANDOM) is not specified, experimentally we have shown that the entropy in the VM will very very low. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 3d2789b4c8c8..239b91ce8d35 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -17,6 +17,8 @@ * Authors: * Haiyang Zhang * Hank Janssen + * + * 3/9/2011: K. Y. Srinivasan - Significant restructuring and cleanup */ #include #include @@ -36,10 +38,6 @@ #include "vmbus_private.h" -/* FIXME! We need to do this dynamically for PIC and APIC system */ -#define VMBUS_IRQ 0x5 -#define VMBUS_IRQ_VECTOR IRQ5_VECTOR - struct pci_dev *hv_pci_dev; /* Main vmbus driver data structure */ @@ -69,7 +67,6 @@ EXPORT_SYMBOL(vmbus_loglevel); /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ -static int vmbus_irq = VMBUS_IRQ; /* Set up per device attributes in /sys/bus/vmbus/devices/ */ static struct device_attribute vmbus_device_attrs[] = { @@ -369,7 +366,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev, * - get the irq resource * - retrieve the channel offers */ -static int vmbus_bus_init(void) +static int vmbus_bus_init(struct pci_dev *pdev) { struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; int ret; @@ -412,21 +409,23 @@ static int vmbus_bus_init(void) } /* Get the interrupt resource */ - ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM, - driver_name, NULL); + ret = request_irq(pdev->irq, vmbus_isr, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, + driver_name, pdev); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", - vmbus_irq); + pdev->irq); bus_unregister(&vmbus_drv_ctx->bus); ret = -1; goto cleanup; } - vector = VMBUS_IRQ_VECTOR; - DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); + vector = IRQ0_VECTOR + pdev->irq; + DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", pdev->irq, + vector); /* * Notify the hypervisor of our irq and @@ -435,7 +434,7 @@ static int vmbus_bus_init(void) on_each_cpu(hv_synic_init, (void *)&vector, 1); ret = vmbus_connect(); if (ret) { - free_irq(vmbus_irq, NULL); + free_irq(pdev->irq, pdev); bus_unregister(&vmbus_drv_ctx->bus); goto cleanup; } @@ -466,7 +465,7 @@ static void vmbus_bus_exit(void) bus_unregister(&vmbus_drv_ctx->bus); - free_irq(vmbus_irq, NULL); + free_irq(hv_pci_dev->irq, hv_pci_dev); tasklet_kill(&vmbus_drv_ctx->msg_dpc); tasklet_kill(&vmbus_drv_ctx->event_dpc); @@ -878,7 +877,7 @@ static int __devinit hv_pci_probe(struct pci_dev *pdev, if (err) return err; - err = vmbus_bus_init(); + err = vmbus_bus_init(pdev); if (err) pci_disable_device(pdev); @@ -918,7 +917,6 @@ static void __exit hv_pci_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); -module_param(vmbus_irq, int, S_IRUGO); module_param(vmbus_loglevel, int, S_IRUGO); module_init(hv_pci_init); -- GitLab From 04677c0862677430f8bf5bbc356bd44bcba48f1f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:35 -0700 Subject: [PATCH 0340/5560] Staging: hv: Rename vmbus_driver_context structure Now that struct vmbus_driver_context is properly cleaned up, rename this structure appropriately and cleanup the code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 239b91ce8d35..f292b030afbc 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -41,7 +41,7 @@ struct pci_dev *hv_pci_dev; /* Main vmbus driver data structure */ -struct vmbus_driver_context { +struct hv_bus { struct bus_type bus; struct tasklet_struct msg_dpc; struct tasklet_struct event_dpc; @@ -99,7 +99,7 @@ static struct device_attribute vmbus_device_attrs[] = { }; /* The one and only one */ -static struct vmbus_driver_context vmbus_drv = { +static struct hv_bus hv_bus = { .bus.name = "vmbus", .bus.match = vmbus_match, .bus.shutdown = vmbus_shutdown, @@ -368,7 +368,6 @@ static ssize_t vmbus_show_device_attr(struct device *dev, */ static int vmbus_bus_init(struct pci_dev *pdev) { - struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; int ret; unsigned int vector; @@ -393,16 +392,16 @@ static int vmbus_bus_init(struct pci_dev *pdev) } - vmbus_drv_ctx->bus.name = driver_name; + hv_bus.bus.name = driver_name; /* Initialize the bus context */ - tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_on_msg_dpc, + tasklet_init(&hv_bus.msg_dpc, vmbus_on_msg_dpc, (unsigned long)NULL); - tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_on_event, + tasklet_init(&hv_bus.event_dpc, vmbus_on_event, (unsigned long)NULL); /* Now, register the bus with LDM */ - ret = bus_register(&vmbus_drv_ctx->bus); + ret = bus_register(&hv_bus.bus); if (ret) { ret = -1; goto cleanup; @@ -417,7 +416,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", pdev->irq); - bus_unregister(&vmbus_drv_ctx->bus); + bus_unregister(&hv_bus.bus); ret = -1; goto cleanup; @@ -435,7 +434,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) ret = vmbus_connect(); if (ret) { free_irq(pdev->irq, pdev); - bus_unregister(&vmbus_drv_ctx->bus); + bus_unregister(&hv_bus.bus); goto cleanup; } @@ -454,7 +453,6 @@ static int vmbus_bus_init(struct pci_dev *pdev) */ static void vmbus_bus_exit(void) { - struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; vmbus_release_unattached_channels(); @@ -463,12 +461,12 @@ static void vmbus_bus_exit(void) hv_cleanup(); - bus_unregister(&vmbus_drv_ctx->bus); + bus_unregister(&hv_bus.bus); free_irq(hv_pci_dev->irq, hv_pci_dev); - tasklet_kill(&vmbus_drv_ctx->msg_dpc); - tasklet_kill(&vmbus_drv_ctx->event_dpc); + tasklet_kill(&hv_bus.msg_dpc); + tasklet_kill(&hv_bus.event_dpc); } @@ -491,7 +489,7 @@ int vmbus_child_driver_register(struct device_driver *drv) drv, drv->name); /* The child driver on this vmbus */ - drv->bus = &vmbus_drv.bus; + drv->bus = &hv_bus.bus; ret = driver_register(drv); @@ -585,7 +583,7 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) atomic_inc_return(&device_num)); /* The new device belongs to this bus */ - child_device_obj->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ + child_device_obj->device.bus = &hv_bus.bus; /* device->dev.bus; */ child_device_obj->device.parent = &hv_pci_dev->dev; child_device_obj->device.release = vmbus_device_release; @@ -853,10 +851,10 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) /* Schedules a dpc if necessary */ if (ret > 0) { if (test_bit(0, (unsigned long *)&ret)) - tasklet_schedule(&vmbus_drv.msg_dpc); + tasklet_schedule(&hv_bus.msg_dpc); if (test_bit(1, (unsigned long *)&ret)) - tasklet_schedule(&vmbus_drv.event_dpc); + tasklet_schedule(&hv_bus.event_dpc); return IRQ_HANDLED; } else { -- GitLab From adde2487d306a0153856cb0a777528ac1f19fa59 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:37 -0700 Subject: [PATCH 0341/5560] Staging: hv: Get rid of the forward declaration for vmbus_uevent Get rid of the forward declaration of vmbus_uevent by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 151 ++++++++++++++++----------------- 1 file changed, 75 insertions(+), 76 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index f292b030afbc..5243d9802f72 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -51,7 +51,6 @@ static int vmbus_match(struct device *device, struct device_driver *driver); static int vmbus_probe(struct device *device); static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); -static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env); static irqreturn_t vmbus_isr(int irq, void *dev_id); @@ -98,6 +97,81 @@ static struct device_attribute vmbus_device_attrs[] = { __ATTR_NULL }; +/* + * vmbus_uevent - add uevent for our device + * + * This routine is invoked when a device is added or removed on the vmbus to + * generate a uevent to udev in the userspace. The udev will then look at its + * rule and the uevent generated here to load the appropriate driver + */ +static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) +{ + struct hv_device *dev = device_to_hv_device(device); + int ret; + + DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={" + "%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x}", + dev->dev_type.data[3], dev->dev_type.data[2], + dev->dev_type.data[1], dev->dev_type.data[0], + dev->dev_type.data[5], dev->dev_type.data[4], + dev->dev_type.data[7], dev->dev_type.data[6], + dev->dev_type.data[8], dev->dev_type.data[9], + dev->dev_type.data[10], + dev->dev_type.data[11], + dev->dev_type.data[12], + dev->dev_type.data[13], + dev->dev_type.data[14], + dev->dev_type.data[15]); + + ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" + "%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x}", + dev->dev_type.data[3], + dev->dev_type.data[2], + dev->dev_type.data[1], + dev->dev_type.data[0], + dev->dev_type.data[5], + dev->dev_type.data[4], + dev->dev_type.data[7], + dev->dev_type.data[6], + dev->dev_type.data[8], + dev->dev_type.data[9], + dev->dev_type.data[10], + dev->dev_type.data[11], + dev->dev_type.data[12], + dev->dev_type.data[13], + dev->dev_type.data[14], + dev->dev_type.data[15]); + + if (ret) + return ret; + + ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={" + "%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x}", + dev->dev_instance.data[3], + dev->dev_instance.data[2], + dev->dev_instance.data[1], + dev->dev_instance.data[0], + dev->dev_instance.data[5], + dev->dev_instance.data[4], + dev->dev_instance.data[7], + dev->dev_instance.data[6], + dev->dev_instance.data[8], + dev->dev_instance.data[9], + dev->dev_instance.data[10], + dev->dev_instance.data[11], + dev->dev_instance.data[12], + dev->dev_instance.data[13], + dev->dev_instance.data[14], + dev->dev_instance.data[15]); + if (ret) + return ret; + + return 0; +} + /* The one and only one */ static struct hv_bus hv_bus = { .bus.name = "vmbus", @@ -626,81 +700,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) &device_obj->device); } -/* - * vmbus_uevent - add uevent for our device - * - * This routine is invoked when a device is added or removed on the vmbus to - * generate a uevent to udev in the userspace. The udev will then look at its - * rule and the uevent generated here to load the appropriate driver - */ -static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) -{ - struct hv_device *dev = device_to_hv_device(device); - int ret; - - DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - dev->dev_type.data[3], dev->dev_type.data[2], - dev->dev_type.data[1], dev->dev_type.data[0], - dev->dev_type.data[5], dev->dev_type.data[4], - dev->dev_type.data[7], dev->dev_type.data[6], - dev->dev_type.data[8], dev->dev_type.data[9], - dev->dev_type.data[10], - dev->dev_type.data[11], - dev->dev_type.data[12], - dev->dev_type.data[13], - dev->dev_type.data[14], - dev->dev_type.data[15]); - - ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - dev->dev_type.data[3], - dev->dev_type.data[2], - dev->dev_type.data[1], - dev->dev_type.data[0], - dev->dev_type.data[5], - dev->dev_type.data[4], - dev->dev_type.data[7], - dev->dev_type.data[6], - dev->dev_type.data[8], - dev->dev_type.data[9], - dev->dev_type.data[10], - dev->dev_type.data[11], - dev->dev_type.data[12], - dev->dev_type.data[13], - dev->dev_type.data[14], - dev->dev_type.data[15]); - - if (ret) - return ret; - - ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - dev->dev_instance.data[3], - dev->dev_instance.data[2], - dev->dev_instance.data[1], - dev->dev_instance.data[0], - dev->dev_instance.data[5], - dev->dev_instance.data[4], - dev->dev_instance.data[7], - dev->dev_instance.data[6], - dev->dev_instance.data[8], - dev->dev_instance.data[9], - dev->dev_instance.data[10], - dev->dev_instance.data[11], - dev->dev_instance.data[12], - dev->dev_instance.data[13], - dev->dev_instance.data[14], - dev->dev_instance.data[15]); - if (ret) - return ret; - - return 0; -} - /* * vmbus_match - Attempt to match the specified device to the specified driver */ -- GitLab From b7fc147bd8732b54019e52af8f923cecd023c711 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:38 -0700 Subject: [PATCH 0342/5560] Staging: hv: Get rid of the forward declaration for vmbus_match Get rid of the forward declaration of vmbus_match by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 49 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 5243d9802f72..5dcfd9854921 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -47,7 +47,6 @@ struct hv_bus { struct tasklet_struct event_dpc; }; -static int vmbus_match(struct device *device, struct device_driver *driver); static int vmbus_probe(struct device *device); static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); @@ -172,6 +171,31 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) return 0; } + +/* + * vmbus_match - Attempt to match the specified device to the specified driver + */ +static int vmbus_match(struct device *device, struct device_driver *driver) +{ + int match = 0; + struct hv_driver *drv = drv_to_hv_drv(driver); + struct hv_device *device_ctx = device_to_hv_device(device); + + /* We found our driver ? */ + if (memcmp(&device_ctx->dev_type, &drv->dev_type, + sizeof(struct hv_guid)) == 0) { + + device_ctx->drv = drv->priv; + DPRINT_INFO(VMBUS_DRV, + "device object (%p) set to driver object (%p)", + &device_ctx, + device_ctx->drv); + + match = 1; + } + return match; +} + /* The one and only one */ static struct hv_bus hv_bus = { .bus.name = "vmbus", @@ -700,29 +724,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) &device_obj->device); } -/* - * vmbus_match - Attempt to match the specified device to the specified driver - */ -static int vmbus_match(struct device *device, struct device_driver *driver) -{ - int match = 0; - struct hv_driver *drv = drv_to_hv_drv(driver); - struct hv_device *device_ctx = device_to_hv_device(device); - - /* We found our driver ? */ - if (memcmp(&device_ctx->dev_type, &drv->dev_type, - sizeof(struct hv_guid)) == 0) { - - device_ctx->drv = drv->priv; - DPRINT_INFO(VMBUS_DRV, - "device object (%p) set to driver object (%p)", - &device_ctx, - device_ctx->drv); - - match = 1; - } - return match; -} /* * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe() -- GitLab From f1f0d67b6ea022a90bfa817bf364a91740d02f4d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:39 -0700 Subject: [PATCH 0343/5560] Staging: hv: Get rid of the forward declaration for vmbus_probe Get rid of the forward declaration of vmbus_probe by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 107 ++++++++++++++++----------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 5dcfd9854921..8153a4d493d5 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -47,7 +47,6 @@ struct hv_bus { struct tasklet_struct event_dpc; }; -static int vmbus_probe(struct device *device); static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); @@ -196,6 +195,59 @@ static int vmbus_match(struct device *device, struct device_driver *driver) return match; } + +/* + * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe() + * + * We need a callback because we cannot invoked device_unregister() inside + * vmbus_probe() since vmbus_probe() may be invoked inside device_register() + * i.e. we cannot call device_unregister() inside device_register() + */ +static void vmbus_probe_failed_cb(struct work_struct *context) +{ + struct hv_device *device_ctx = (struct hv_device *)context; + + /* + * Kick off the process of unregistering the device. + * This will call vmbus_remove() and eventually vmbus_device_release() + */ + device_unregister(&device_ctx->device); + + /* put_device(&device_ctx->device); */ +} + +/* + * vmbus_probe - Add the new vmbus's child device + */ +static int vmbus_probe(struct device *child_device) +{ + int ret = 0; + struct hv_driver *drv = + drv_to_hv_drv(child_device->driver); + struct hv_device *dev = device_to_hv_device(child_device); + + /* Let the specific open-source driver handles the probe if it can */ + if (drv->driver.probe) { + ret = dev->probe_error = + drv->driver.probe(child_device); + if (ret != 0) { + DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " + "(%p) on driver %s (%d)...", + dev_name(child_device), child_device, + child_device->driver->name, ret); + + INIT_WORK(&dev->probe_failed_work_item, + vmbus_probe_failed_cb); + schedule_work(&dev->probe_failed_work_item); + } + } else { + DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", + child_device->driver->name); + ret = -1; + } + return ret; +} + /* The one and only one */ static struct hv_bus hv_bus = { .bus.name = "vmbus", @@ -724,59 +776,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) &device_obj->device); } - -/* - * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe() - * - * We need a callback because we cannot invoked device_unregister() inside - * vmbus_probe() since vmbus_probe() may be invoked inside device_register() - * i.e. we cannot call device_unregister() inside device_register() - */ -static void vmbus_probe_failed_cb(struct work_struct *context) -{ - struct hv_device *device_ctx = (struct hv_device *)context; - - /* - * Kick off the process of unregistering the device. - * This will call vmbus_remove() and eventually vmbus_device_release() - */ - device_unregister(&device_ctx->device); - - /* put_device(&device_ctx->device); */ -} - -/* - * vmbus_probe - Add the new vmbus's child device - */ -static int vmbus_probe(struct device *child_device) -{ - int ret = 0; - struct hv_driver *drv = - drv_to_hv_drv(child_device->driver); - struct hv_device *dev = device_to_hv_device(child_device); - - /* Let the specific open-source driver handles the probe if it can */ - if (drv->driver.probe) { - ret = dev->probe_error = - drv->driver.probe(child_device); - if (ret != 0) { - DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " - "(%p) on driver %s (%d)...", - dev_name(child_device), child_device, - child_device->driver->name, ret); - - INIT_WORK(&dev->probe_failed_work_item, - vmbus_probe_failed_cb); - schedule_work(&dev->probe_failed_work_item); - } - } else { - DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", - child_device->driver->name); - ret = -1; - } - return ret; -} - /* * vmbus_remove - Remove a vmbus device */ -- GitLab From c5dce3db89def8e35d30521e187a0e8127937dd0 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:40 -0700 Subject: [PATCH 0344/5560] Staging: hv: Get rid of the forward declaration for vmbus_remove Get rid of the forward declaration of vmbus_remove by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 59 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 8153a4d493d5..3feed10a19a6 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -47,7 +47,6 @@ struct hv_bus { struct tasklet_struct event_dpc; }; -static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); static irqreturn_t vmbus_isr(int irq, void *dev_id); @@ -248,6 +247,35 @@ static int vmbus_probe(struct device *child_device) return ret; } +/* + * vmbus_remove - Remove a vmbus device + */ +static int vmbus_remove(struct device *child_device) +{ + int ret; + struct hv_driver *drv; + + + if (child_device->driver) { + drv = drv_to_hv_drv(child_device->driver); + + /* + * Let the specific open-source driver handles the removal if + * it can + */ + if (drv->driver.remove) { + ret = drv->driver.remove(child_device); + } else { + DPRINT_ERR(VMBUS_DRV, + "remove() method not set for driver - %s", + child_device->driver->name); + ret = -1; + } + } + + return 0; +} + /* The one and only one */ static struct hv_bus hv_bus = { .bus.name = "vmbus", @@ -776,35 +804,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) &device_obj->device); } -/* - * vmbus_remove - Remove a vmbus device - */ -static int vmbus_remove(struct device *child_device) -{ - int ret; - struct hv_driver *drv; - - - if (child_device->driver) { - drv = drv_to_hv_drv(child_device->driver); - - /* - * Let the specific open-source driver handles the removal if - * it can - */ - if (drv->driver.remove) { - ret = drv->driver.remove(child_device); - } else { - DPRINT_ERR(VMBUS_DRV, - "remove() method not set for driver - %s", - child_device->driver->name); - ret = -1; - } - } - - return 0; -} - /* * vmbus_shutdown - Shutdown a vmbus device */ -- GitLab From eb1bb259cf216be0cd924e76e2185c7fb2c7e8ee Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:41 -0700 Subject: [PATCH 0345/5560] Staging: hv: Get rid of the forward declaration for vmbus_shutdown Get rid of the forward declaration of vmbus_shutdown by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 3feed10a19a6..671632c9a026 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -47,7 +47,6 @@ struct hv_bus { struct tasklet_struct event_dpc; }; -static void vmbus_shutdown(struct device *device); static irqreturn_t vmbus_isr(int irq, void *dev_id); @@ -276,6 +275,28 @@ static int vmbus_remove(struct device *child_device) return 0; } + +/* + * vmbus_shutdown - Shutdown a vmbus device + */ +static void vmbus_shutdown(struct device *child_device) +{ + struct hv_driver *drv; + + + /* The device may not be attached yet */ + if (!child_device->driver) + return; + + drv = drv_to_hv_drv(child_device->driver); + + /* Let the specific open-source driver handles the removal if it can */ + if (drv->driver.shutdown) + drv->driver.shutdown(child_device); + + return; +} + /* The one and only one */ static struct hv_bus hv_bus = { .bus.name = "vmbus", @@ -804,27 +825,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) &device_obj->device); } -/* - * vmbus_shutdown - Shutdown a vmbus device - */ -static void vmbus_shutdown(struct device *child_device) -{ - struct hv_driver *drv; - - - /* The device may not be attached yet */ - if (!child_device->driver) - return; - - drv = drv_to_hv_drv(child_device->driver); - - /* Let the specific open-source driver handles the removal if it can */ - if (drv->driver.shutdown) - drv->driver.shutdown(child_device); - - return; -} - /* * vmbus_device_release - Final callback release of the vmbus child device -- GitLab From 086e7a5685babba533644acd1d39a81e3f8eed54 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:42 -0700 Subject: [PATCH 0346/5560] Staging: hv: Get rid of the forward declaration for vmbus_device_release Get rid of the forward declaration of vmbus_device_release by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 671632c9a026..976175bc6c7b 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -50,8 +50,6 @@ struct hv_bus { static irqreturn_t vmbus_isr(int irq, void *dev_id); -static void vmbus_device_release(struct device *device); - static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf); @@ -297,6 +295,18 @@ static void vmbus_shutdown(struct device *child_device) return; } + +/* + * vmbus_device_release - Final callback release of the vmbus child device + */ +static void vmbus_device_release(struct device *device) +{ + struct hv_device *device_ctx = device_to_hv_device(device); + + kfree(device_ctx); + +} + /* The one and only one */ static struct hv_bus hv_bus = { .bus.name = "vmbus", @@ -826,19 +836,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) } -/* - * vmbus_device_release - Final callback release of the vmbus child device - */ -static void vmbus_device_release(struct device *device) -{ - struct hv_device *device_ctx = device_to_hv_device(device); - - kfree(device_ctx); - - /* !!DO NOT REFERENCE device_ctx anymore at this point!! */ -} - - static irqreturn_t vmbus_isr(int irq, void *dev_id) { -- GitLab From 793be9c76e7ca3841992e8bbdea46dcceb3e3118 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:43 -0700 Subject: [PATCH 0347/5560] Staging: hv: Get rid of the forward declaration for vmbus_isr Get rid of the forward declaration of vmbus_isr by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 47 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 976175bc6c7b..194926cc80ff 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -48,7 +48,6 @@ struct hv_bus { }; -static irqreturn_t vmbus_isr(int irq, void *dev_id); static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, @@ -91,6 +90,7 @@ static struct device_attribute vmbus_device_attrs[] = { __ATTR_NULL }; + /* * vmbus_uevent - add uevent for our device * @@ -417,6 +417,28 @@ static int vmbus_on_isr(void) return ret; } + +static irqreturn_t vmbus_isr(int irq, void *dev_id) +{ + int ret; + + ret = vmbus_on_isr(); + + /* Schedules a dpc if necessary */ + if (ret > 0) { + if (test_bit(0, (unsigned long *)&ret)) + tasklet_schedule(&hv_bus.msg_dpc); + + if (test_bit(1, (unsigned long *)&ret)) + tasklet_schedule(&hv_bus.event_dpc); + + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } +} + + static void get_channel_info(struct hv_device *device, struct hv_device_info *info) { @@ -836,29 +858,6 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) } - -static irqreturn_t vmbus_isr(int irq, void *dev_id) -{ - int ret; - - ret = vmbus_on_isr(); - - /* Schedules a dpc if necessary */ - if (ret > 0) { - if (test_bit(0, (unsigned long *)&ret)) - tasklet_schedule(&hv_bus.msg_dpc); - - if (test_bit(1, (unsigned long *)&ret)) - tasklet_schedule(&hv_bus.event_dpc); - - return IRQ_HANDLED; - } else { - return IRQ_NONE; - } -} - - - static int __devinit hv_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { -- GitLab From 98db4335e978dcec8d31900c58447690e6850f3b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 15 Mar 2011 15:03:44 -0700 Subject: [PATCH 0348/5560] Staging: hv: Get rid of the forward declaration for vmbus_show_device_attr Get rid of the forward declaration of vmbus_show_device_attr by moving the code around. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 302 ++++++++++++++++----------------- 1 file changed, 147 insertions(+), 155 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 194926cc80ff..3263fc85f645 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -47,18 +47,160 @@ struct hv_bus { struct tasklet_struct event_dpc; }; +unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL); +EXPORT_SYMBOL(vmbus_loglevel); + /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ + /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ + + +static void get_channel_info(struct hv_device *device, + struct hv_device_info *info) +{ + struct vmbus_channel_debug_info debug_info; + + if (!device->channel) + return; + + vmbus_get_debug_info(device->channel, &debug_info); + + info->chn_id = debug_info.relid; + info->chn_state = debug_info.state; + memcpy(&info->chn_type, &debug_info.interfacetype, + sizeof(struct hv_guid)); + memcpy(&info->chn_instance, &debug_info.interface_instance, + sizeof(struct hv_guid)); + + info->monitor_id = debug_info.monitorid; + + info->server_monitor_pending = debug_info.servermonitor_pending; + info->server_monitor_latency = debug_info.servermonitor_latency; + info->server_monitor_conn_id = debug_info.servermonitor_connectionid; + + info->client_monitor_pending = debug_info.clientmonitor_pending; + info->client_monitor_latency = debug_info.clientmonitor_latency; + info->client_monitor_conn_id = debug_info.clientmonitor_connectionid; + + info->inbound.int_mask = debug_info.inbound.current_interrupt_mask; + info->inbound.read_idx = debug_info.inbound.current_read_index; + info->inbound.write_idx = debug_info.inbound.current_write_index; + info->inbound.bytes_avail_toread = + debug_info.inbound.bytes_avail_toread; + info->inbound.bytes_avail_towrite = + debug_info.inbound.bytes_avail_towrite; + info->outbound.int_mask = + debug_info.outbound.current_interrupt_mask; + info->outbound.read_idx = debug_info.outbound.current_read_index; + info->outbound.write_idx = debug_info.outbound.current_write_index; + info->outbound.bytes_avail_toread = + debug_info.outbound.bytes_avail_toread; + info->outbound.bytes_avail_towrite = + debug_info.outbound.bytes_avail_towrite; +} +/* + * vmbus_show_device_attr - Show the device attribute in sysfs. + * + * This is invoked when user does a + * "cat /sys/bus/vmbus/devices//" + */ static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, - char *buf); + char *buf) +{ + struct hv_device *device_ctx = device_to_hv_device(dev); + struct hv_device_info device_info; + memset(&device_info, 0, sizeof(struct hv_device_info)); -unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL); -EXPORT_SYMBOL(vmbus_loglevel); - /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ - /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ + get_channel_info(device_ctx, &device_info); + if (!strcmp(dev_attr->attr.name, "class_id")) { + return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x}\n", + device_info.chn_type.data[3], + device_info.chn_type.data[2], + device_info.chn_type.data[1], + device_info.chn_type.data[0], + device_info.chn_type.data[5], + device_info.chn_type.data[4], + device_info.chn_type.data[7], + device_info.chn_type.data[6], + device_info.chn_type.data[8], + device_info.chn_type.data[9], + device_info.chn_type.data[10], + device_info.chn_type.data[11], + device_info.chn_type.data[12], + device_info.chn_type.data[13], + device_info.chn_type.data[14], + device_info.chn_type.data[15]); + } else if (!strcmp(dev_attr->attr.name, "device_id")) { + return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x}\n", + device_info.chn_instance.data[3], + device_info.chn_instance.data[2], + device_info.chn_instance.data[1], + device_info.chn_instance.data[0], + device_info.chn_instance.data[5], + device_info.chn_instance.data[4], + device_info.chn_instance.data[7], + device_info.chn_instance.data[6], + device_info.chn_instance.data[8], + device_info.chn_instance.data[9], + device_info.chn_instance.data[10], + device_info.chn_instance.data[11], + device_info.chn_instance.data[12], + device_info.chn_instance.data[13], + device_info.chn_instance.data[14], + device_info.chn_instance.data[15]); + } else if (!strcmp(dev_attr->attr.name, "state")) { + return sprintf(buf, "%d\n", device_info.chn_state); + } else if (!strcmp(dev_attr->attr.name, "id")) { + return sprintf(buf, "%d\n", device_info.chn_id); + } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) { + return sprintf(buf, "%d\n", device_info.outbound.int_mask); + } else if (!strcmp(dev_attr->attr.name, "out_read_index")) { + return sprintf(buf, "%d\n", device_info.outbound.read_idx); + } else if (!strcmp(dev_attr->attr.name, "out_write_index")) { + return sprintf(buf, "%d\n", device_info.outbound.write_idx); + } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) { + return sprintf(buf, "%d\n", + device_info.outbound.bytes_avail_toread); + } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) { + return sprintf(buf, "%d\n", + device_info.outbound.bytes_avail_towrite); + } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) { + return sprintf(buf, "%d\n", device_info.inbound.int_mask); + } else if (!strcmp(dev_attr->attr.name, "in_read_index")) { + return sprintf(buf, "%d\n", device_info.inbound.read_idx); + } else if (!strcmp(dev_attr->attr.name, "in_write_index")) { + return sprintf(buf, "%d\n", device_info.inbound.write_idx); + } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) { + return sprintf(buf, "%d\n", + device_info.inbound.bytes_avail_toread); + } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) { + return sprintf(buf, "%d\n", + device_info.inbound.bytes_avail_towrite); + } else if (!strcmp(dev_attr->attr.name, "monitor_id")) { + return sprintf(buf, "%d\n", device_info.monitor_id); + } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) { + return sprintf(buf, "%d\n", device_info.server_monitor_pending); + } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) { + return sprintf(buf, "%d\n", device_info.server_monitor_latency); + } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) { + return sprintf(buf, "%d\n", + device_info.server_monitor_conn_id); + } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) { + return sprintf(buf, "%d\n", device_info.client_monitor_pending); + } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) { + return sprintf(buf, "%d\n", device_info.client_monitor_latency); + } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) { + return sprintf(buf, "%d\n", + device_info.client_monitor_conn_id); + } else { + return 0; + } +} /* Set up per device attributes in /sys/bus/vmbus/devices/ */ static struct device_attribute vmbus_device_attrs[] = { @@ -438,156 +580,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) } } - -static void get_channel_info(struct hv_device *device, - struct hv_device_info *info) -{ - struct vmbus_channel_debug_info debug_info; - - if (!device->channel) - return; - - vmbus_get_debug_info(device->channel, &debug_info); - - info->chn_id = debug_info.relid; - info->chn_state = debug_info.state; - memcpy(&info->chn_type, &debug_info.interfacetype, - sizeof(struct hv_guid)); - memcpy(&info->chn_instance, &debug_info.interface_instance, - sizeof(struct hv_guid)); - - info->monitor_id = debug_info.monitorid; - - info->server_monitor_pending = debug_info.servermonitor_pending; - info->server_monitor_latency = debug_info.servermonitor_latency; - info->server_monitor_conn_id = debug_info.servermonitor_connectionid; - - info->client_monitor_pending = debug_info.clientmonitor_pending; - info->client_monitor_latency = debug_info.clientmonitor_latency; - info->client_monitor_conn_id = debug_info.clientmonitor_connectionid; - - info->inbound.int_mask = debug_info.inbound.current_interrupt_mask; - info->inbound.read_idx = debug_info.inbound.current_read_index; - info->inbound.write_idx = debug_info.inbound.current_write_index; - info->inbound.bytes_avail_toread = - debug_info.inbound.bytes_avail_toread; - info->inbound.bytes_avail_towrite = - debug_info.inbound.bytes_avail_towrite; - - info->outbound.int_mask = - debug_info.outbound.current_interrupt_mask; - info->outbound.read_idx = debug_info.outbound.current_read_index; - info->outbound.write_idx = debug_info.outbound.current_write_index; - info->outbound.bytes_avail_toread = - debug_info.outbound.bytes_avail_toread; - info->outbound.bytes_avail_towrite = - debug_info.outbound.bytes_avail_towrite; -} - -/* - * vmbus_show_device_attr - Show the device attribute in sysfs. - * - * This is invoked when user does a - * "cat /sys/bus/vmbus/devices//" - */ -static ssize_t vmbus_show_device_attr(struct device *dev, - struct device_attribute *dev_attr, - char *buf) -{ - struct hv_device *device_ctx = device_to_hv_device(dev); - struct hv_device_info device_info; - - memset(&device_info, 0, sizeof(struct hv_device_info)); - - get_channel_info(device_ctx, &device_info); - - if (!strcmp(dev_attr->attr.name, "class_id")) { - return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.chn_type.data[3], - device_info.chn_type.data[2], - device_info.chn_type.data[1], - device_info.chn_type.data[0], - device_info.chn_type.data[5], - device_info.chn_type.data[4], - device_info.chn_type.data[7], - device_info.chn_type.data[6], - device_info.chn_type.data[8], - device_info.chn_type.data[9], - device_info.chn_type.data[10], - device_info.chn_type.data[11], - device_info.chn_type.data[12], - device_info.chn_type.data[13], - device_info.chn_type.data[14], - device_info.chn_type.data[15]); - } else if (!strcmp(dev_attr->attr.name, "device_id")) { - return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.chn_instance.data[3], - device_info.chn_instance.data[2], - device_info.chn_instance.data[1], - device_info.chn_instance.data[0], - device_info.chn_instance.data[5], - device_info.chn_instance.data[4], - device_info.chn_instance.data[7], - device_info.chn_instance.data[6], - device_info.chn_instance.data[8], - device_info.chn_instance.data[9], - device_info.chn_instance.data[10], - device_info.chn_instance.data[11], - device_info.chn_instance.data[12], - device_info.chn_instance.data[13], - device_info.chn_instance.data[14], - device_info.chn_instance.data[15]); - } else if (!strcmp(dev_attr->attr.name, "state")) { - return sprintf(buf, "%d\n", device_info.chn_state); - } else if (!strcmp(dev_attr->attr.name, "id")) { - return sprintf(buf, "%d\n", device_info.chn_id); - } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) { - return sprintf(buf, "%d\n", device_info.outbound.int_mask); - } else if (!strcmp(dev_attr->attr.name, "out_read_index")) { - return sprintf(buf, "%d\n", device_info.outbound.read_idx); - } else if (!strcmp(dev_attr->attr.name, "out_write_index")) { - return sprintf(buf, "%d\n", device_info.outbound.write_idx); - } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) { - return sprintf(buf, "%d\n", - device_info.outbound.bytes_avail_toread); - } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) { - return sprintf(buf, "%d\n", - device_info.outbound.bytes_avail_towrite); - } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) { - return sprintf(buf, "%d\n", device_info.inbound.int_mask); - } else if (!strcmp(dev_attr->attr.name, "in_read_index")) { - return sprintf(buf, "%d\n", device_info.inbound.read_idx); - } else if (!strcmp(dev_attr->attr.name, "in_write_index")) { - return sprintf(buf, "%d\n", device_info.inbound.write_idx); - } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) { - return sprintf(buf, "%d\n", - device_info.inbound.bytes_avail_toread); - } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) { - return sprintf(buf, "%d\n", - device_info.inbound.bytes_avail_towrite); - } else if (!strcmp(dev_attr->attr.name, "monitor_id")) { - return sprintf(buf, "%d\n", device_info.monitor_id); - } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) { - return sprintf(buf, "%d\n", device_info.server_monitor_pending); - } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) { - return sprintf(buf, "%d\n", device_info.server_monitor_latency); - } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) { - return sprintf(buf, "%d\n", - device_info.server_monitor_conn_id); - } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) { - return sprintf(buf, "%d\n", device_info.client_monitor_pending); - } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) { - return sprintf(buf, "%d\n", device_info.client_monitor_latency); - } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) { - return sprintf(buf, "%d\n", - device_info.client_monitor_conn_id); - } else { - return 0; - } -} - /* * vmbus_bus_init -Main vmbus driver initialization routine. * -- GitLab From 6e1870a847c2bd40a56f3a8807bf12ad2bf28c33 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:19 -0700 Subject: [PATCH 0349/5560] Staging: hv: Add the inclusion guard for vstorage.h In preparation for getting rid of the inclusion of storvsc.c from blkvsc.c, add inclusion guard to vstorage.h Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vstorage.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/hv/vstorage.h b/drivers/staging/hv/vstorage.h index ebb4d671c424..83060cd86842 100644 --- a/drivers/staging/hv/vstorage.h +++ b/drivers/staging/hv/vstorage.h @@ -25,6 +25,9 @@ /* to alert the user that structure sizes may be mismatched even though the */ /* protocol versions match. */ +#ifndef _VSTORAGE_H_ +#define _VSTORAGE_H_ + #define REVISION_STRING(REVISION_) #REVISION_ #define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \ do { \ @@ -190,3 +193,5 @@ struct vstor_packet { /* This is the set of flags that the vsc can set in any packets it sends */ #define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG) + +#endif /* _VSTORAGE_H_ */ -- GitLab From 036bbeda8c802c438e167d35a3ce726bcb0bb42e Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:20 -0700 Subject: [PATCH 0350/5560] Staging: hv: Move the definition of struct storvsc_request_extension In preparation for getting rid of the inclusion of storvsc.c from blkvsc.c, move the definition of struct storvsc_request_extension from storvsc.c to storvsc_api.h. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 1 + drivers/staging/hv/storvsc.c | 13 ------------- drivers/staging/hv/storvsc_api.h | 12 ++++++++++++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index 7c8729bc8329..88d6e3c14df3 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -24,6 +24,7 @@ #include #include "hv_api.h" #include "storvsc.c" +#include "storvsc_api.h" static const char *g_blk_driver_name = "blkvsc"; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index e2ad72924184..56f3cc9d860b 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -33,19 +33,6 @@ #include "channel.h" -struct storvsc_request_extension { - /* LIST_ENTRY ListEntry; */ - - struct hv_storvsc_request *request; - struct hv_device *device; - - /* Synchronize the request/response if needed */ - int wait_condition; - wait_queue_head_t wait_event; - - struct vstor_packet vstor_packet; -}; - /* A storvsc device is a device object that contains a vmbus channel */ struct storvsc_device { struct hv_device *device; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index fbf57556d890..629144c43664 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -25,6 +25,7 @@ #ifndef _STORVSC_API_H_ #define _STORVSC_API_H_ +#include "vstorage.h" #include "vmbus_api.h" /* Defines */ @@ -102,6 +103,17 @@ struct storvsc_device_info { unsigned char target_id; }; +struct storvsc_request_extension { + struct hv_storvsc_request *request; + struct hv_device *device; + + /* Synchronize the request/response if needed */ + int wait_condition; + wait_queue_head_t wait_event; + + struct vstor_packet vstor_packet; +}; + /* Interface */ int stor_vsc_initialize(struct hv_driver *driver); int stor_vsc_on_host_reset(struct hv_device *device); -- GitLab From f24eeb06a430f8508d03a419ff4274d5596a5436 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:21 -0700 Subject: [PATCH 0351/5560] Staging: hv: Move the definition of struct storvsc_device In preparation for getting rid of the inclusion of storvsc.c from blkvsc.c, move the definition of struct storvsc_device from storvsc.c to storvsc_api.h. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 26 -------------------------- drivers/staging/hv/storvsc_api.h | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 56f3cc9d860b..be1c77a1d232 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -33,32 +33,6 @@ #include "channel.h" -/* A storvsc device is a device object that contains a vmbus channel */ -struct storvsc_device { - struct hv_device *device; - - /* 0 indicates the device is being destroyed */ - atomic_t ref_count; - - atomic_t num_outstanding_req; - - /* - * Each unique Port/Path/Target represents 1 channel ie scsi - * controller. In reality, the pathid, targetid is always 0 - * and the port is set by us - */ - unsigned int port_number; - unsigned char path_id; - unsigned char target_id; - - /* LIST_ENTRY OutstandingRequestList; */ - /* HANDLE OutstandingRequestLock; */ - - /* Used for vsc/vsp channel reset process */ - struct storvsc_request_extension init_request; - struct storvsc_request_extension reset_request; -}; - static const char *g_driver_name = "storvsc"; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 629144c43664..2b814bd12bca 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -114,6 +114,32 @@ struct storvsc_request_extension { struct vstor_packet vstor_packet; }; +/* A storvsc device is a device object that contains a vmbus channel */ +struct storvsc_device { + struct hv_device *device; + + /* 0 indicates the device is being destroyed */ + atomic_t ref_count; + + atomic_t num_outstanding_req; + + /* + * Each unique Port/Path/Target represents 1 channel ie scsi + * controller. In reality, the pathid, targetid is always 0 + * and the port is set by us + */ + unsigned int port_number; + unsigned char path_id; + unsigned char target_id; + + /* LIST_ENTRY OutstandingRequestList; */ + /* HANDLE OutstandingRequestLock; */ + + /* Used for vsc/vsp channel reset process */ + struct storvsc_request_extension init_request; + struct storvsc_request_extension reset_request; +}; + /* Interface */ int stor_vsc_initialize(struct hv_driver *driver); int stor_vsc_on_host_reset(struct hv_device *device); -- GitLab From 78101852f3d08134e89979b491a9fa815395c9f5 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:22 -0700 Subject: [PATCH 0352/5560] Staging: hv: Cleanup struct storvsc_device Get rid of some dated comments from struct storvsc_device. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_api.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 2b814bd12bca..7f780c58223d 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -132,9 +132,6 @@ struct storvsc_device { unsigned char path_id; unsigned char target_id; - /* LIST_ENTRY OutstandingRequestList; */ - /* HANDLE OutstandingRequestLock; */ - /* Used for vsc/vsp channel reset process */ struct storvsc_request_extension init_request; struct storvsc_request_extension reset_request; -- GitLab From afa3f3d7f57bc9adb3f7cc2c853153916f690eda Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:23 -0700 Subject: [PATCH 0353/5560] Staging: hv: Get rid of the include of storvsc.c from blkvsc.c Now that all the structure definitions have been moved to a header file, get rid of the inclusion of storvsc.c from blkvsc.c. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/blkvsc.c | 2 +- drivers/staging/hv/storvsc.c | 8 ++++---- drivers/staging/hv/storvsc_api.h | 9 +++++++++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index abeb2f7ef4e2..a733154fa7e1 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -9,6 +9,6 @@ hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o hv_storvsc-y := storvsc_drv.o storvsc.o -hv_blkvsc-y := blkvsc_drv.o blkvsc.o +hv_blkvsc-y := blkvsc_drv.o blkvsc.o storvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o hv_utils-y := hv_util.o hv_kvp.o diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index 88d6e3c14df3..ebe511a59e49 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -22,8 +22,8 @@ */ #include #include +#include "logging.h" #include "hv_api.h" -#include "storvsc.c" #include "storvsc_api.h" static const char *g_blk_driver_name = "blkvsc"; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index be1c77a1d232..c8d7ff7fc288 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -504,7 +504,7 @@ static int stor_vsc_connect_to_vsp(struct hv_device *device) * stor_vsc_on_device_add - Callback when the device belonging to this driver * is added */ -static int stor_vsc_on_device_add(struct hv_device *device, +int stor_vsc_on_device_add(struct hv_device *device, void *additional_info) { struct storvsc_device *stor_device; @@ -553,7 +553,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, /* * stor_vsc_on_device_remove - Callback when the our device is being removed */ -static int stor_vsc_on_device_remove(struct hv_device *device) +int stor_vsc_on_device_remove(struct hv_device *device) { struct storvsc_device *stor_device; @@ -646,7 +646,7 @@ int stor_vsc_on_host_reset(struct hv_device *device) /* * stor_vsc_on_io_request - Callback to initiate an I/O request */ -static int stor_vsc_on_io_request(struct hv_device *device, +int stor_vsc_on_io_request(struct hv_device *device, struct hv_storvsc_request *request) { struct storvsc_device *stor_device; @@ -739,7 +739,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, /* * stor_vsc_on_cleanup - Perform any cleanup when the driver is removed */ -static void stor_vsc_on_cleanup(struct hv_driver *driver) +void stor_vsc_on_cleanup(struct hv_driver *driver) { } diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 7f780c58223d..141b8fd33be0 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -142,4 +142,13 @@ int stor_vsc_initialize(struct hv_driver *driver); int stor_vsc_on_host_reset(struct hv_device *device); int blk_vsc_initialize(struct hv_driver *driver); +int stor_vsc_on_device_add(struct hv_device *device, + void *additional_info); +int stor_vsc_on_device_remove(struct hv_device *device); + +int stor_vsc_on_io_request(struct hv_device *device, + struct hv_storvsc_request *request); +void stor_vsc_on_cleanup(struct hv_driver *driver); + + #endif /* _STORVSC_API_H_ */ -- GitLab From 5e081c91eb515d55bdd5d121adff8d216914c0dc Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:24 -0700 Subject: [PATCH 0354/5560] Staging: hv: Get rid of dead code in storvsc.c Get rid of some "dead code" from storvsc.c Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index c8d7ff7fc288..1f05aa66e4e1 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -65,7 +65,6 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) static inline void free_stor_device(struct storvsc_device *device) { - /* ASSERT(atomic_read(&device->ref_count) == 0); */ kfree(device); } @@ -103,10 +102,8 @@ static inline void put_stor_device(struct hv_device *device) struct storvsc_device *stor_device; stor_device = (struct storvsc_device *)device->ext; - /* ASSERT(stor_device); */ atomic_dec(&stor_device->ref_count); - /* ASSERT(atomic_read(&stor_device->ref_count)); */ } /* Drop ref count to 1 to effectively disable get_stor_device() */ @@ -116,7 +113,6 @@ static inline struct storvsc_device *release_stor_device( struct storvsc_device *stor_device; stor_device = (struct storvsc_device *)device->ext; - /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 2, then set it to 1 */ while (atomic_cmpxchg(&stor_device->ref_count, 2, 1) != 2) @@ -132,7 +128,6 @@ static inline struct storvsc_device *final_release_stor_device( struct storvsc_device *stor_device; stor_device = (struct storvsc_device *)device->ext; - /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1) @@ -341,12 +336,8 @@ static void stor_vsc_on_io_completion(struct hv_device *device, "completed bytes xfer %u", request_ext, vstor_packet->vm_srb.data_transfer_length); - /* ASSERT(request_ext != NULL); */ - /* ASSERT(request_ext->request != NULL); */ - request = request_ext->request; - /* ASSERT(request->OnIOCompletion != NULL); */ /* Copy over the status...etc */ request->status = vstor_packet->vm_srb.scsi_status; @@ -366,8 +357,6 @@ static void stor_vsc_on_io_completion(struct hv_device *device, "valid - len %d\n", request_ext, vstor_packet->vm_srb.sense_info_length); - /* ASSERT(vstor_packet->vm_srb.sense_info_length <= */ - /* request->SenseBufferSize); */ memcpy(request->sense_buffer, vstor_packet->vm_srb.sense_data, vstor_packet->vm_srb.sense_info_length); @@ -418,7 +407,6 @@ static void stor_vsc_on_channel_callback(void *context) struct storvsc_request_extension *request; int ret; - /* ASSERT(device); */ stor_device = must_get_stor_device(device); if (!stor_device) { @@ -435,21 +423,12 @@ static void stor_vsc_on_channel_callback(void *context) DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", bytes_recvd, request_id); - /* ASSERT(bytes_recvd == - sizeof(struct vstor_packet)); */ request = (struct storvsc_request_extension *) (unsigned long)request_id; - /* ASSERT(request);c */ - /* if (vstor_packet.Flags & SYNTHETIC_FLAG) */ if ((request == &stor_device->init_request) || (request == &stor_device->reset_request)) { - /* DPRINT_INFO(STORVSC, - * "reset completion - operation " - * "%u status %u", - * vstor_packet.Operation, - * vstor_packet.Status); */ memcpy(&request->vstor_packet, packet, sizeof(struct vstor_packet)); @@ -461,7 +440,6 @@ static void stor_vsc_on_channel_callback(void *context) request); } } else { - /* DPRINT_DBG(STORVSC, "nothing else to read..."); */ break; } } while (1); @@ -508,7 +486,6 @@ int stor_vsc_on_device_add(struct hv_device *device, void *additional_info) { struct storvsc_device *stor_device; - /* struct vmstorage_channel_properties *props; */ struct storvsc_device_info *device_info; int ret = 0; @@ -520,8 +497,6 @@ int stor_vsc_on_device_add(struct hv_device *device, } /* Save the channel properties to our storvsc channel */ - /* props = (struct vmstorage_channel_properties *) - * channel->offerMsg.Offer.u.Standard.UserDefined; */ /* FIXME: */ /* @@ -530,15 +505,10 @@ int stor_vsc_on_device_add(struct hv_device *device, * scsi channel prior to the bus scan */ - /* storChannel->PortNumber = 0; - storChannel->PathId = props->PathId; - storChannel->TargetId = props->TargetId; */ - stor_device->port_number = device_info->port_number; /* Send it back up */ ret = stor_vsc_connect_to_vsp(device); - /* device_info->PortNumber = stor_device->PortNumber; */ device_info->path_id = stor_device->path_id; device_info->target_id = stor_device->target_id; @@ -673,8 +643,6 @@ int stor_vsc_on_io_request(struct hv_device *device, return -2; } - /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, request->Cdb, - * request->CdbLen); */ request_extension->request = request; request_extension->device = device; @@ -762,7 +730,6 @@ int stor_vsc_initialize(struct hv_driver *driver) sizeof(struct vmscsi_request)); /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ driver->name = g_driver_name; memcpy(&driver->dev_type, &gStorVscDeviceType, -- GitLab From 6dec24423803273a2619ad383d19b18264c8ce1b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:25 -0700 Subject: [PATCH 0355/5560] Staging: hv: Move the definition of stor_vsc_initialize() Since stor_vsc_initialize() is only used in storvs_drv.c, move this function to storvsc_drv.c. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 64 -------------------------------- drivers/staging/hv/storvsc_drv.c | 63 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 1f05aa66e4e1..83d012bec325 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -33,18 +33,6 @@ #include "channel.h" - -static const char *g_driver_name = "storvsc"; - -/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ -static const struct hv_guid gStorVscDeviceType = { - .data = { - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f - } -}; - - static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) { struct storvsc_device *stor_device; @@ -711,55 +699,3 @@ void stor_vsc_on_cleanup(struct hv_driver *driver) { } -/* - * stor_vsc_initialize - Main entry point - */ -int stor_vsc_initialize(struct hv_driver *driver) -{ - struct storvsc_driver_object *stor_driver; - - stor_driver = (struct storvsc_driver_object *)driver; - - DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " - "sizeof(struct storvsc_request_extension)=%zd " - "sizeof(struct vstor_packet)=%zd, " - "sizeof(struct vmscsi_request)=%zd", - sizeof(struct hv_storvsc_request), - sizeof(struct storvsc_request_extension), - sizeof(struct vstor_packet), - sizeof(struct vmscsi_request)); - - /* Make sure we are at least 2 pages since 1 page is used for control */ - - driver->name = g_driver_name; - memcpy(&driver->dev_type, &gStorVscDeviceType, - sizeof(struct hv_guid)); - - stor_driver->request_ext_size = - sizeof(struct storvsc_request_extension); - - /* - * Divide the ring buffer data size (which is 1 page less - * than the ring buffer size since that page is reserved for - * the ring buffer indices) by the max request size (which is - * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) - */ - stor_driver->max_outstanding_req_per_channel = - ((stor_driver->ring_buffer_size - PAGE_SIZE) / - ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), - sizeof(u64))); - - DPRINT_INFO(STORVSC, "max io %u, currently %u\n", - stor_driver->max_outstanding_req_per_channel, - STORVSC_MAX_IO_REQUESTS); - - /* Setup the dispatch table */ - stor_driver->base.dev_add = stor_vsc_on_device_add; - stor_driver->base.dev_rm = stor_vsc_on_device_remove; - stor_driver->base.cleanup = stor_vsc_on_cleanup; - - stor_driver->on_io_request = stor_vsc_on_io_request; - - return 0; -} diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index e6462a2fe9ab..5ea09dae35ca 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -38,6 +38,16 @@ #include "storvsc_api.h" +static const char *g_driver_name = "storvsc"; + +/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ +static const struct hv_guid gStorVscDeviceType = { + .data = { + 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, + 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f + } +}; + struct host_device_context { /* must be 1st field * FIXME this is a bug */ @@ -64,6 +74,59 @@ struct storvsc_cmd_request { }; +/* + * stor_vsc_initialize - Main entry point + */ +int stor_vsc_initialize(struct hv_driver *driver) +{ + struct storvsc_driver_object *stor_driver; + + stor_driver = (struct storvsc_driver_object *)driver; + + DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " + "sizeof(struct storvsc_request_extension)=%zd " + "sizeof(struct vstor_packet)=%zd, " + "sizeof(struct vmscsi_request)=%zd", + sizeof(struct hv_storvsc_request), + sizeof(struct storvsc_request_extension), + sizeof(struct vstor_packet), + sizeof(struct vmscsi_request)); + + /* Make sure we are at least 2 pages since 1 page is used for control */ + + driver->name = g_driver_name; + memcpy(&driver->dev_type, &gStorVscDeviceType, + sizeof(struct hv_guid)); + + stor_driver->request_ext_size = + sizeof(struct storvsc_request_extension); + + /* + * Divide the ring buffer data size (which is 1 page less + * than the ring buffer size since that page is reserved for + * the ring buffer indices) by the max request size (which is + * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) + */ + stor_driver->max_outstanding_req_per_channel = + ((stor_driver->ring_buffer_size - PAGE_SIZE) / + ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + + sizeof(struct vstor_packet) + sizeof(u64), + sizeof(u64))); + + DPRINT_INFO(STORVSC, "max io %u, currently %u\n", + stor_driver->max_outstanding_req_per_channel, + STORVSC_MAX_IO_REQUESTS); + + /* Setup the dispatch table */ + stor_driver->base.dev_add = stor_vsc_on_device_add; + stor_driver->base.dev_rm = stor_vsc_on_device_remove; + stor_driver->base.cleanup = stor_vsc_on_cleanup; + + stor_driver->on_io_request = stor_vsc_on_io_request; + + return 0; +} + /* Static decl */ static int storvsc_probe(struct device *dev); static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd); -- GitLab From 2b8b35825fb0c4b36771b9f3c5565092fff5d164 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:26 -0700 Subject: [PATCH 0356/5560] Staging: hv: Make the function stor_vsc_initialize() static Make the function stor_vsc_initialize() a static function. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 141b8fd33be0..9a452f26c4a6 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -138,7 +138,6 @@ struct storvsc_device { }; /* Interface */ -int stor_vsc_initialize(struct hv_driver *driver); int stor_vsc_on_host_reset(struct hv_device *device); int blk_vsc_initialize(struct hv_driver *driver); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 5ea09dae35ca..af6a37d4bc63 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -77,7 +77,7 @@ struct storvsc_cmd_request { /* * stor_vsc_initialize - Main entry point */ -int stor_vsc_initialize(struct hv_driver *driver) +static int stor_vsc_initialize(struct hv_driver *driver) { struct storvsc_driver_object *stor_driver; -- GitLab From db0857771be7c5fe2d235e5a00a3ded8ac48b09d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:27 -0700 Subject: [PATCH 0357/5560] Staging: hv: Cleanup the initialization of storvsc driver Cleanup the initialization sequence for the storvsc driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index af6a37d4bc63..2c51a0728cc1 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -191,7 +191,7 @@ static struct scsi_host_template scsi_driver = { /* * storvsc_drv_init - StorVsc driver initialization. */ -static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) +static int storvsc_drv_init(void) { int ret; struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv; @@ -200,7 +200,7 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) storvsc_drv_obj->ring_buffer_size = storvsc_ringbuffer_size; /* Callback to client driver to complete the initialization */ - drv_init(&storvsc_drv_obj->base); + stor_vsc_initialize(&storvsc_drv_obj->base); drv->priv = storvsc_drv_obj; @@ -986,7 +986,7 @@ static int __init storvsc_init(void) int ret; DPRINT_INFO(STORVSC_DRV, "Storvsc initializing...."); - ret = storvsc_drv_init(stor_vsc_initialize); + ret = storvsc_drv_init(); return ret; } -- GitLab From 19b5931d54695ca748ede122ed67a9f12e791f0e Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:28 -0700 Subject: [PATCH 0358/5560] Staging: hv: Move the contents of blkvsc.c to blkvsc_drv.c In preparation for getting rid of the file blkvsc.c, move its contents to the appropriate file. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/blkvsc_drv.c | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index a733154fa7e1..30046743a0b4 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -9,6 +9,6 @@ hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o hv_storvsc-y := storvsc_drv.o storvsc.o -hv_blkvsc-y := blkvsc_drv.o blkvsc.o storvsc.o +hv_blkvsc-y := blkvsc_drv.o storvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o hv_utils-y := hv_util.o hv_kvp.o diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index af789937be4e..f1bf44bb09e6 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -116,6 +116,85 @@ struct block_device_context { }; +static const char *g_blk_driver_name = "blkvsc"; + +/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ +static const struct hv_guid g_blk_device_type = { + .data = { + 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 + } +}; + +static int blk_vsc_on_device_add(struct hv_device *device, + void *additional_info) +{ + struct storvsc_device_info *device_info; + int ret = 0; + + device_info = (struct storvsc_device_info *)additional_info; + + ret = stor_vsc_on_device_add(device, additional_info); + if (ret != 0) + return ret; + + /* + * We need to use the device instance guid to set the path and target + * id. For IDE devices, the device instance id is formatted as + * * - - 8899 - 000000000000. + */ + device_info->path_id = device->dev_instance.data[3] << 24 | + device->dev_instance.data[2] << 16 | + device->dev_instance.data[1] << 8 | + device->dev_instance.data[0]; + + device_info->target_id = device->dev_instance.data[5] << 8 | + device->dev_instance.data[4]; + + return ret; +} + + +int blk_vsc_initialize(struct hv_driver *driver) +{ + struct storvsc_driver_object *stor_driver; + int ret = 0; + + stor_driver = (struct storvsc_driver_object *)driver; + + /* Make sure we are at least 2 pages since 1 page is used for control */ + /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ + + driver->name = g_blk_driver_name; + memcpy(&driver->dev_type, &g_blk_device_type, sizeof(struct hv_guid)); + + stor_driver->request_ext_size = + sizeof(struct storvsc_request_extension); + + /* + * Divide the ring buffer data size (which is 1 page less than the ring + * buffer size since that page is reserved for the ring buffer indices) + * by the max request size (which is + * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) + */ + stor_driver->max_outstanding_req_per_channel = + ((stor_driver->ring_buffer_size - PAGE_SIZE) / + ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + + sizeof(struct vstor_packet) + sizeof(u64), + sizeof(u64))); + + DPRINT_INFO(BLKVSC, "max io outstd %u", + stor_driver->max_outstanding_req_per_channel); + + /* Setup the dispatch table */ + stor_driver->base.dev_add = blk_vsc_on_device_add; + stor_driver->base.dev_rm = stor_vsc_on_device_remove; + stor_driver->base.cleanup = stor_vsc_on_cleanup; + stor_driver->on_io_request = stor_vsc_on_io_request; + + return ret; +} + /* Static decl */ static DEFINE_MUTEX(blkvsc_mutex); static int blkvsc_probe(struct device *dev); -- GitLab From 86762a5bd908499e3936c9c765184d3f4c0d069e Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:29 -0700 Subject: [PATCH 0359/5560] Staging: hv: Get rid of the file blkvsc.c Now delete the file. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 103 ------------------------------------ 1 file changed, 103 deletions(-) delete mode 100644 drivers/staging/hv/blkvsc.c diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c deleted file mode 100644 index ebe511a59e49..000000000000 --- a/drivers/staging/hv/blkvsc.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft 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. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include "logging.h" -#include "hv_api.h" -#include "storvsc_api.h" - -static const char *g_blk_driver_name = "blkvsc"; - -/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ -static const struct hv_guid g_blk_device_type = { - .data = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } -}; - -static int blk_vsc_on_device_add(struct hv_device *device, void *additional_info) -{ - struct storvsc_device_info *device_info; - int ret = 0; - - device_info = (struct storvsc_device_info *)additional_info; - - ret = stor_vsc_on_device_add(device, additional_info); - if (ret != 0) - return ret; - - /* - * We need to use the device instance guid to set the path and target - * id. For IDE devices, the device instance id is formatted as - * * - - 8899 - 000000000000. - */ - device_info->path_id = device->dev_instance.data[3] << 24 | - device->dev_instance.data[2] << 16 | - device->dev_instance.data[1] << 8 | - device->dev_instance.data[0]; - - device_info->target_id = device->dev_instance.data[5] << 8 | - device->dev_instance.data[4]; - - return ret; -} - -int blk_vsc_initialize(struct hv_driver *driver) -{ - struct storvsc_driver_object *stor_driver; - int ret = 0; - - stor_driver = (struct storvsc_driver_object *)driver; - - /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ - - driver->name = g_blk_driver_name; - memcpy(&driver->dev_type, &g_blk_device_type, sizeof(struct hv_guid)); - - stor_driver->request_ext_size = sizeof(struct storvsc_request_extension); - - /* - * Divide the ring buffer data size (which is 1 page less than the ring - * buffer size since that page is reserved for the ring buffer indices) - * by the max request size (which is - * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) - */ - stor_driver->max_outstanding_req_per_channel = - ((stor_driver->ring_buffer_size - PAGE_SIZE) / - ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), - sizeof(u64))); - - DPRINT_INFO(BLKVSC, "max io outstd %u", - stor_driver->max_outstanding_req_per_channel); - - /* Setup the dispatch table */ - stor_driver->base.dev_add = blk_vsc_on_device_add; - stor_driver->base.dev_rm = stor_vsc_on_device_remove; - stor_driver->base.cleanup = stor_vsc_on_cleanup; - stor_driver->on_io_request = stor_vsc_on_io_request; - - return ret; -} -- GitLab From 834702f82ab8fe1ea5de5e464764d5ca2d326dbd Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:30 -0700 Subject: [PATCH 0360/5560] Staging: hv: Cleanup initialization of blkvsc driver Cleanup the initialization sequence for the block driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 8 ++++---- drivers/staging/hv/storvsc_api.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index f1bf44bb09e6..a5c0ac4bc894 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -155,7 +155,7 @@ static int blk_vsc_on_device_add(struct hv_device *device, } -int blk_vsc_initialize(struct hv_driver *driver) +static int blk_vsc_initialize(struct hv_driver *driver) { struct storvsc_driver_object *stor_driver; int ret = 0; @@ -244,7 +244,7 @@ static const struct block_device_operations block_ops = { /* * blkvsc_drv_init - BlkVsc driver initialization. */ -static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) +static int blkvsc_drv_init(void) { struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv; struct hv_driver *drv = &g_blkvsc_drv.base; @@ -255,7 +255,7 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv->priv = storvsc_drv_obj; /* Callback to client driver to complete the initialization */ - drv_init(&storvsc_drv_obj->base); + blk_vsc_initialize(&storvsc_drv_obj->base); drv->driver.name = storvsc_drv_obj->base.name; @@ -1555,7 +1555,7 @@ static int __init blkvsc_init(void) DPRINT_INFO(BLKVSC_DRV, "Blkvsc initializing...."); - ret = blkvsc_drv_init(blk_vsc_initialize); + ret = blkvsc_drv_init(); return ret; } diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 9a452f26c4a6..d985bbfe7621 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -139,7 +139,6 @@ struct storvsc_device { /* Interface */ int stor_vsc_on_host_reset(struct hv_device *device); -int blk_vsc_initialize(struct hv_driver *driver); int stor_vsc_on_device_add(struct hv_device *device, void *additional_info); -- GitLab From 852c16dbdcf84d43803a4ccfa647cf2f2952afc9 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:31 -0700 Subject: [PATCH 0361/5560] Staging: hv: Move the definition of the function get_stor_device() In preparation for further cleaning up storvsc.c move the definition of the inline function get_stor_device() from storvsc.c to storvsc_api.h. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 14 -------------- drivers/staging/hv/storvsc_api.h | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 83d012bec325..357f5ddeb8a2 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -56,20 +56,6 @@ static inline void free_stor_device(struct storvsc_device *device) kfree(device); } -/* Get the stordevice object iff exists and its refcount > 1 */ -static inline struct storvsc_device *get_stor_device(struct hv_device *device) -{ - struct storvsc_device *stor_device; - - stor_device = (struct storvsc_device *)device->ext; - if (stor_device && atomic_read(&stor_device->ref_count) > 1) - atomic_inc(&stor_device->ref_count); - else - stor_device = NULL; - - return stor_device; -} - /* Get the stordevice object iff exists and its refcount > 0 */ static inline struct storvsc_device *must_get_stor_device( struct hv_device *device) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index d985bbfe7621..4e6650712ba1 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -137,6 +137,21 @@ struct storvsc_device { struct storvsc_request_extension reset_request; }; + +/* Get the stordevice object iff exists and its refcount > 1 */ +static inline struct storvsc_device *get_stor_device(struct hv_device *device) +{ + struct storvsc_device *stor_device; + + stor_device = (struct storvsc_device *)device->ext; + if (stor_device && atomic_read(&stor_device->ref_count) > 1) + atomic_inc(&stor_device->ref_count); + else + stor_device = NULL; + + return stor_device; +} + /* Interface */ int stor_vsc_on_host_reset(struct hv_device *device); -- GitLab From 1604b1bda3c20534efad534f3fc77470f455d862 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:32 -0700 Subject: [PATCH 0362/5560] Staging: hv: Move the definition of the function put_stor_device() In preparation for further cleaning up storvsc.c move the definition of the inline function put_stor_device() from storvsc.c to storvsc_api.h. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 9 --------- drivers/staging/hv/storvsc_api.h | 10 ++++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 357f5ddeb8a2..c576e7b1e250 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -71,15 +71,6 @@ static inline struct storvsc_device *must_get_stor_device( return stor_device; } -static inline void put_stor_device(struct hv_device *device) -{ - struct storvsc_device *stor_device; - - stor_device = (struct storvsc_device *)device->ext; - - atomic_dec(&stor_device->ref_count); -} - /* Drop ref count to 1 to effectively disable get_stor_device() */ static inline struct storvsc_device *release_stor_device( struct hv_device *device) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 4e6650712ba1..d46b4de255dc 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -152,6 +152,16 @@ static inline struct storvsc_device *get_stor_device(struct hv_device *device) return stor_device; } + +static inline void put_stor_device(struct hv_device *device) +{ + struct storvsc_device *stor_device; + + stor_device = (struct storvsc_device *)device->ext; + + atomic_dec(&stor_device->ref_count); +} + /* Interface */ int stor_vsc_on_host_reset(struct hv_device *device); -- GitLab From af3043c64a4a87bc0a4596f4952dc194ebc5af72 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:33 -0700 Subject: [PATCH 0363/5560] Staging: hv: Move the definition of the function stor_vsc_on_host_reset() stor_vsc_on_host_reset() function is only used in storvsc_drv.c. Move this function from storvsc.c to storvsc_drv.c Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 56 ------------------------------ drivers/staging/hv/storvsc_drv.c | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 56 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index c576e7b1e250..6801e3738766 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -522,62 +522,6 @@ int stor_vsc_on_device_remove(struct hv_device *device) return 0; } -int stor_vsc_on_host_reset(struct hv_device *device) -{ - struct storvsc_device *stor_device; - struct storvsc_request_extension *request; - struct vstor_packet *vstor_packet; - int ret; - - DPRINT_INFO(STORVSC, "resetting host adapter..."); - - stor_device = get_stor_device(device); - if (!stor_device) { - DPRINT_ERR(STORVSC, "unable to get stor device..." - "device being destroyed?"); - return -1; - } - - request = &stor_device->reset_request; - vstor_packet = &request->vstor_packet; - - init_waitqueue_head(&request->wait_event); - - vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; - vstor_packet->vm_srb.path_id = stor_device->path_id; - - request->wait_condition = 0; - ret = vmbus_sendpacket(device->channel, vstor_packet, - sizeof(struct vstor_packet), - (unsigned long)&stor_device->reset_request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", - vstor_packet, ret); - goto cleanup; - } - - wait_event_timeout(request->wait_event, request->wait_condition, - msecs_to_jiffies(1000)); - if (request->wait_condition == 0) { - ret = -ETIMEDOUT; - goto cleanup; - } - - DPRINT_INFO(STORVSC, "host adapter reset completed"); - - /* - * At this point, all outstanding requests in the adapter - * should have been flushed out and return to us - */ - -cleanup: - put_stor_device(device); - return ret; -} - /* * stor_vsc_on_io_request - Callback to initiate an I/O request */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 2c51a0728cc1..e0a11958141c 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -36,6 +36,8 @@ #include "version_info.h" #include "vmbus.h" #include "storvsc_api.h" +#include "vstorage.h" +#include "channel.h" static const char *g_driver_name = "storvsc"; @@ -230,6 +232,63 @@ static int storvsc_drv_init(void) return ret; } + +int stor_vsc_on_host_reset(struct hv_device *device) +{ + struct storvsc_device *stor_device; + struct storvsc_request_extension *request; + struct vstor_packet *vstor_packet; + int ret; + + DPRINT_INFO(STORVSC, "resetting host adapter..."); + + stor_device = get_stor_device(device); + if (!stor_device) { + DPRINT_ERR(STORVSC, "unable to get stor device..." + "device being destroyed?"); + return -1; + } + + request = &stor_device->reset_request; + vstor_packet = &request->vstor_packet; + + init_waitqueue_head(&request->wait_event); + + vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + vstor_packet->vm_srb.path_id = stor_device->path_id; + + request->wait_condition = 0; + ret = vmbus_sendpacket(device->channel, vstor_packet, + sizeof(struct vstor_packet), + (unsigned long)&stor_device->reset_request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", + vstor_packet, ret); + goto cleanup; + } + + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } + + DPRINT_INFO(STORVSC, "host adapter reset completed"); + + /* + * At this point, all outstanding requests in the adapter + * should have been flushed out and return to us + */ + +cleanup: + put_stor_device(device); + return ret; +} + static int storvsc_drv_exit_cb(struct device *dev, void *data) { struct device **curr = (struct device **)data; -- GitLab From 12cb12ef23bfe90f4e6c003a88b4500c6ff2b71b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 23 Mar 2011 10:50:34 -0700 Subject: [PATCH 0364/5560] Staging: hv: Make the function stor_vsc_on_host_reset() static Make stor_vsc_on_host_reset() a static function. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index d46b4de255dc..5f41ef6bcc54 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -163,7 +163,6 @@ static inline void put_stor_device(struct hv_device *device) } /* Interface */ -int stor_vsc_on_host_reset(struct hv_device *device); int stor_vsc_on_device_add(struct hv_device *device, void *additional_info); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index e0a11958141c..127d12250dd5 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -233,7 +233,7 @@ static int storvsc_drv_init(void) } -int stor_vsc_on_host_reset(struct hv_device *device) +static int stor_vsc_on_host_reset(struct hv_device *device) { struct storvsc_device *stor_device; struct storvsc_request_extension *request; -- GitLab From bf587a1dfd992c3f4dcc2886a36964126b5a4ade Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:26 -0700 Subject: [PATCH 0365/5560] Staging: hv: Move the definition of struct storvsc_request_extension In preperation for embedding struct storvsc_request_extension into struct hv_storvsc_request, move the definition of struct storvsc_request_extension. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_api.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 5f41ef6bcc54..800ebbfeb47d 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -53,6 +53,18 @@ enum storvsc_request_type{ UNKNOWN_TYPE, }; + +struct storvsc_request_extension { + struct hv_storvsc_request *request; + struct hv_device *device; + + /* Synchronize the request/response if needed */ + int wait_condition; + wait_queue_head_t wait_event; + + struct vstor_packet vstor_packet; +}; + struct hv_storvsc_request { enum storvsc_request_type type; u32 host; @@ -103,17 +115,6 @@ struct storvsc_device_info { unsigned char target_id; }; -struct storvsc_request_extension { - struct hv_storvsc_request *request; - struct hv_device *device; - - /* Synchronize the request/response if needed */ - int wait_condition; - wait_queue_head_t wait_event; - - struct vstor_packet vstor_packet; -}; - /* A storvsc device is a device object that contains a vmbus channel */ struct storvsc_device { struct hv_device *device; -- GitLab From 2fd0df276e4ebb411dd0f87a2c9381b466f81ed4 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:27 -0700 Subject: [PATCH 0366/5560] Staging: hv: Embed struct storvsc_request_extension into hv_storvsc_request Embed struct storvsc_request_extension into hv_storvsc_request. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 8 -------- drivers/staging/hv/storvsc.c | 3 +-- drivers/staging/hv/storvsc_api.h | 3 +-- drivers/staging/hv/storvsc_drv.c | 6 ------ 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index a5c0ac4bc894..0a3eb5c00a92 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -84,12 +84,6 @@ struct blkvsc_request { unsigned char cmnd[MAX_COMMAND_SIZE]; struct hv_storvsc_request request; - /* - * !!!DO NOT ADD ANYTHING BELOW HERE!!! Otherwise, memory can overlap, - * because - The extension buffer falls right here and is pointed to by - * request.Extension; - * Which sounds like a horrible idea, who designed this? - */ }; /* Per device structure */ @@ -944,8 +938,6 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, #endif storvsc_req = &blkvsc_req->request; - storvsc_req->extension = (void *)((unsigned long)blkvsc_req + - sizeof(struct blkvsc_request)); storvsc_req->type = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 6801e3738766..5cea33128eda 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -533,8 +533,7 @@ int stor_vsc_on_io_request(struct hv_device *device, struct vstor_packet *vstor_packet; int ret = 0; - request_extension = - (struct storvsc_request_extension *)request->extension; + request_extension = &request->extension; vstor_packet = &request_extension->vstor_packet; stor_device = get_stor_device(device); diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 800ebbfeb47d..e41b68b13110 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -83,8 +83,7 @@ struct hv_storvsc_request { void (*on_io_completion)(struct hv_storvsc_request *request); - /* This points to the memory after DataBuffer */ - void *extension; + struct storvsc_request_extension extension; struct hv_multipage_buffer data_buffer; }; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 127d12250dd5..58d12e0a88c9 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -69,10 +69,6 @@ struct storvsc_cmd_request { struct scatterlist *bounce_sgl; struct hv_storvsc_request request; - /* !!!DO NOT ADD ANYTHING BELOW HERE!!! */ - /* The extension buffer falls right here and is pointed to by - * request.Extension; - * Which sounds like a very bad design... */ }; @@ -763,8 +759,6 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, request = &cmd_request->request; - request->extension = - (void *)((unsigned long)cmd_request + request_size); DPRINT_DBG(STORVSC_DRV, "req %p size %d ext %d", request, request_size, storvsc_drv_obj->request_ext_size); -- GitLab From 1e05d88e9374036cd2d6d0f7e840a790cf4bb43a Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:28 -0700 Subject: [PATCH 0367/5560] Staging: hv: Get rid of request_ext_size from struct storvsc_driver_object Now that struct storvsc_request_extension is part of struct hv_storvsc_request get rid of the field request_ext_size from struct storvsc_driver_object. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 5 +---- drivers/staging/hv/storvsc_api.h | 3 --- drivers/staging/hv/storvsc_drv.c | 11 +++-------- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 0a3eb5c00a92..02472c69090f 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -162,8 +162,6 @@ static int blk_vsc_initialize(struct hv_driver *driver) driver->name = g_blk_driver_name; memcpy(&driver->dev_type, &g_blk_device_type, sizeof(struct hv_guid)); - stor_driver->request_ext_size = - sizeof(struct storvsc_request_extension); /* * Divide the ring buffer data size (which is 1 page less than the ring @@ -347,8 +345,7 @@ static int blkvsc_probe(struct device *device) /* sizeof(struct blkvsc_request)); */ blkdev->request_pool = kmem_cache_create(dev_name(&device_obj->device), - sizeof(struct blkvsc_request) + - storvsc_drv_obj->request_ext_size, 0, + sizeof(struct blkvsc_request), 0, SLAB_HWCACHE_ALIGN, NULL); if (!blkdev->request_pool) { ret = -ENOMEM; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index e41b68b13110..eeaeaefb8652 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -97,9 +97,6 @@ struct storvsc_driver_object { /* Set by caller (in bytes) */ u32 ring_buffer_size; - /* Allocate this much private extension for each I/O request */ - u32 request_ext_size; - /* Maximum # of requests in flight per channel/device */ u32 max_outstanding_req_per_channel; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 58d12e0a88c9..1d13f1baf800 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -96,8 +96,6 @@ static int stor_vsc_initialize(struct hv_driver *driver) memcpy(&driver->dev_type, &gStorVscDeviceType, sizeof(struct hv_guid)); - stor_driver->request_ext_size = - sizeof(struct storvsc_request_extension); /* * Divide the ring buffer data size (which is 1 page less @@ -203,8 +201,7 @@ static int storvsc_drv_init(void) drv->priv = storvsc_drv_obj; DPRINT_INFO(STORVSC_DRV, - "request extension size %u, max outstanding reqs %u", - storvsc_drv_obj->request_ext_size, + "max outstanding reqs %u", storvsc_drv_obj->max_outstanding_req_per_channel); if (storvsc_drv_obj->max_outstanding_req_per_channel < @@ -359,8 +356,7 @@ static int storvsc_probe(struct device *device) host_device_ctx->request_pool = kmem_cache_create(dev_name(&device_obj->device), - sizeof(struct storvsc_cmd_request) + - storvsc_drv_obj->request_ext_size, 0, + sizeof(struct storvsc_cmd_request), 0, SLAB_HWCACHE_ALIGN, NULL); if (!host_device_ctx->request_pool) { @@ -759,8 +755,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, request = &cmd_request->request; - DPRINT_DBG(STORVSC_DRV, "req %p size %d ext %d", request, request_size, - storvsc_drv_obj->request_ext_size); + DPRINT_DBG(STORVSC_DRV, "req %p size %d", request, request_size); /* Build the SRB */ switch (scmnd->sc_data_direction) { -- GitLab From ced01b0df71fb184744c473b934f9ea70454b750 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:29 -0700 Subject: [PATCH 0368/5560] Staging: hv: Add a function to map a hv_driver pointer to storvsc driver Get rid of the need for struct hv_device to be the first element of struct host_device_context. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc_api.h | 8 ++++++-- drivers/staging/hv/storvsc_drv.c | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 02472c69090f..5a9d20c8a37d 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -154,7 +154,7 @@ static int blk_vsc_initialize(struct hv_driver *driver) struct storvsc_driver_object *stor_driver; int ret = 0; - stor_driver = (struct storvsc_driver_object *)driver; + stor_driver = hvdr_to_stordr(driver); /* Make sure we are at least 2 pages since 1 page is used for control */ /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index eeaeaefb8652..5c80cdb5dc1a 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -25,6 +25,7 @@ #ifndef _STORVSC_API_H_ #define _STORVSC_API_H_ +#include #include "vstorage.h" #include "vmbus_api.h" @@ -90,8 +91,6 @@ struct hv_storvsc_request { /* Represents the block vsc driver */ struct storvsc_driver_object { - /* Must be the first field */ - /* Which is a bug FIXME! */ struct hv_driver base; /* Set by caller (in bytes) */ @@ -159,6 +158,11 @@ static inline void put_stor_device(struct hv_device *device) atomic_dec(&stor_device->ref_count); } +static inline struct storvsc_driver_object *hvdr_to_stordr(struct hv_driver *d) +{ + return container_of(d, struct storvsc_driver_object, base); +} + /* Interface */ int stor_vsc_on_device_add(struct hv_device *device, diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 1d13f1baf800..268c60707ebe 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -79,7 +79,7 @@ static int stor_vsc_initialize(struct hv_driver *driver) { struct storvsc_driver_object *stor_driver; - stor_driver = (struct storvsc_driver_object *)driver; + stor_driver = hvdr_to_stordr(driver); DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " "sizeof(struct storvsc_request_extension)=%zd " -- GitLab From 93958465598f22833ee21f9aa3d79749acb7d6eb Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:30 -0700 Subject: [PATCH 0369/5560] Staging: hv: Use struct completion in struct storvsc_request_extension Get rid of the wait_queue mechanism for synchronization in struct storvsc_request_extension and instead use completion mechanism. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 34 +++++++++++--------------------- drivers/staging/hv/storvsc_api.h | 3 +-- drivers/staging/hv/storvsc_drv.c | 10 ++++------ 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 5cea33128eda..8dc17b9349bf 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -20,7 +20,7 @@ */ #include #include -#include +#include #include #include #include @@ -107,7 +107,7 @@ static int stor_vsc_channel_init(struct hv_device *device) struct storvsc_device *stor_device; struct storvsc_request_extension *request; struct vstor_packet *vstor_packet; - int ret; + int ret, t; stor_device = get_stor_device(device); if (!stor_device) { @@ -124,13 +124,12 @@ static int stor_vsc_channel_init(struct hv_device *device) * channel */ memset(request, 0, sizeof(struct storvsc_request_extension)); - init_waitqueue_head(&request->wait_event); + init_completion(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); - request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -142,14 +141,12 @@ static int stor_vsc_channel_init(struct hv_device *device) goto cleanup; } - wait_event_timeout(request->wait_event, request->wait_condition, - msecs_to_jiffies(1000)); - if (request->wait_condition == 0) { + t = wait_for_completion_timeout(&request->wait_event, HZ); + if (t == 0) { ret = -ETIMEDOUT; goto cleanup; } - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " @@ -168,7 +165,6 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; FILL_VMSTOR_REVISION(vstor_packet->version.revision); - request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -180,9 +176,8 @@ static int stor_vsc_channel_init(struct hv_device *device) goto cleanup; } - wait_event_timeout(request->wait_event, request->wait_condition, - msecs_to_jiffies(1000)); - if (request->wait_condition == 0) { + t = wait_for_completion_timeout(&request->wait_event, HZ); + if (t == 0) { ret = -ETIMEDOUT; goto cleanup; } @@ -205,7 +200,6 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->storage_channel_properties.port_number = stor_device->port_number; - request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -218,9 +212,8 @@ static int stor_vsc_channel_init(struct hv_device *device) goto cleanup; } - wait_event_timeout(request->wait_event, request->wait_condition, - msecs_to_jiffies(1000)); - if (request->wait_condition == 0) { + t = wait_for_completion_timeout(&request->wait_event, HZ); + if (t == 0) { ret = -ETIMEDOUT; goto cleanup; } @@ -248,7 +241,6 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -261,9 +253,8 @@ static int stor_vsc_channel_init(struct hv_device *device) goto cleanup; } - wait_event_timeout(request->wait_event, request->wait_condition, - msecs_to_jiffies(1000)); - if (request->wait_condition == 0) { + t = wait_for_completion_timeout(&request->wait_event, HZ); + if (t == 0) { ret = -ETIMEDOUT; goto cleanup; } @@ -397,8 +388,7 @@ static void stor_vsc_on_channel_callback(void *context) memcpy(&request->vstor_packet, packet, sizeof(struct vstor_packet)); - request->wait_condition = 1; - wake_up(&request->wait_event); + complete(&request->wait_event); } else { stor_vsc_on_receive(device, (struct vstor_packet *)packet, diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 5c80cdb5dc1a..cdef1c7d650f 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -60,8 +60,7 @@ struct storvsc_request_extension { struct hv_device *device; /* Synchronize the request/response if needed */ - int wait_condition; - wait_queue_head_t wait_event; + struct completion wait_event; struct vstor_packet vstor_packet; }; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 268c60707ebe..c2a3a5b8fd0f 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -231,7 +231,7 @@ static int stor_vsc_on_host_reset(struct hv_device *device) struct storvsc_device *stor_device; struct storvsc_request_extension *request; struct vstor_packet *vstor_packet; - int ret; + int ret, t; DPRINT_INFO(STORVSC, "resetting host adapter..."); @@ -245,13 +245,12 @@ static int stor_vsc_on_host_reset(struct hv_device *device) request = &stor_device->reset_request; vstor_packet = &request->vstor_packet; - init_waitqueue_head(&request->wait_event); + init_completion(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->vm_srb.path_id = stor_device->path_id; - request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)&stor_device->reset_request, @@ -263,9 +262,8 @@ static int stor_vsc_on_host_reset(struct hv_device *device) goto cleanup; } - wait_event_timeout(request->wait_event, request->wait_condition, - msecs_to_jiffies(1000)); - if (request->wait_condition == 0) { + t = wait_for_completion_timeout(&request->wait_event, HZ); + if (t == 0) { ret = -ETIMEDOUT; goto cleanup; } -- GitLab From 12fbd4164ea1fa4a4a717d72a68e48d1cc0362a3 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:31 -0700 Subject: [PATCH 0370/5560] Staging: hv: Get rid of the type field from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the type field from struct hv_storvsc_request and instead use the equivalent state in struct vmscsi_request - data_in field. In the current code there is a call to zero out the struct vstor_packet in stor_vsc_on_io_request(). So, to be able to directly set the state in the vstor_packet in blkvsc_drv.c and storvsc_drv.c, get rid of the call to zero out the packet in stor_vsc_on_io_request() and instead allocate the request structure that has been zeroed out. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 18 +++++++++++------- drivers/staging/hv/storvsc.c | 3 --- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 8 +++++--- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 5a9d20c8a37d..6c0bc1c7b1e1 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -512,7 +512,7 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) if (blkdev->device_type != HARDDISK_TYPE) return 0; - blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL); + blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL); if (!blkvsc_req) return -ENOMEM; @@ -553,7 +553,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_inquiry()\n"); - blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL); + blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL); if (!blkvsc_req) return -ENOMEM; @@ -640,7 +640,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) blkdev->capacity = 0; blkdev->media_not_present = 0; /* assume a disk is present */ - blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL); + blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL); if (!blkvsc_req) return -ENOMEM; @@ -717,7 +717,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) blkdev->capacity = 0; blkdev->media_not_present = 0; /* assume a disk is present */ - blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL); + blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL); if (!blkvsc_req) return -ENOMEM; @@ -915,6 +915,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, struct storvsc_driver_object *storvsc_drv_obj = drv->priv; struct hv_storvsc_request *storvsc_req; + struct vmscsi_request *vm_srb; int ret; DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - " @@ -935,8 +936,9 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, #endif storvsc_req = &blkvsc_req->request; + vm_srb = &storvsc_req->extension.vstor_packet.vm_srb; - storvsc_req->type = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; + vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; storvsc_req->on_io_completion = request_completion; storvsc_req->context = blkvsc_req; @@ -985,7 +987,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, (unsigned long)blk_rq_pos(req)); /* Create a group to tie req to list of blkvsc_reqs */ - group = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC); + group = kmem_cache_zalloc(blkdev->request_pool, GFP_ATOMIC); if (!group) return -ENOMEM; @@ -1028,7 +1030,9 @@ static int blkvsc_do_request(struct block_device_context *blkdev, * Create new blkvsc_req to represent * the current bvec */ - blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC); + blkvsc_req = + kmem_cache_zalloc( + blkdev->request_pool, GFP_ATOMIC); if (!blkvsc_req) { /* free up everything */ list_for_each_entry_safe( diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 8dc17b9349bf..b580c30ade99 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -545,8 +545,6 @@ int stor_vsc_on_io_request(struct hv_device *device, request_extension->request = request; request_extension->device = device; - memset(vstor_packet, 0 , sizeof(struct vstor_packet)); - vstor_packet->flags |= REQUEST_COMPLETION_FLAG; vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); @@ -562,7 +560,6 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.cdb_length = request->cdb_len; memcpy(&vstor_packet->vm_srb.cdb, request->cdb, request->cdb_len); - vstor_packet->vm_srb.data_in = request->type; vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len; vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index cdef1c7d650f..27781f46a293 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -66,7 +66,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - enum storvsc_request_type type; u32 host; u32 bus; u32 target_id; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index c2a3a5b8fd0f..b08423bb07d2 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -709,6 +709,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, int i; struct scatterlist *sgl; unsigned int sg_count = 0; + struct vmscsi_request *vm_srb; DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d " "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction, @@ -752,19 +753,20 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, scmnd->host_scribble = (unsigned char *)cmd_request; request = &cmd_request->request; + vm_srb = &request->extension.vstor_packet.vm_srb; DPRINT_DBG(STORVSC_DRV, "req %p size %d", request, request_size); /* Build the SRB */ switch (scmnd->sc_data_direction) { case DMA_TO_DEVICE: - request->type = WRITE_TYPE; + vm_srb->data_in = WRITE_TYPE; break; case DMA_FROM_DEVICE: - request->type = READ_TYPE; + vm_srb->data_in = READ_TYPE; break; default: - request->type = UNKNOWN_TYPE; + vm_srb->data_in = UNKNOWN_TYPE; break; } -- GitLab From 124661ded38b4bbd8a95e1e66d4e03ce328d4481 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:32 -0700 Subject: [PATCH 0371/5560] Staging: hv: Get rid of the host field from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the host field from struct hv_storvsc_request and instead use the equivalent state in struct vmscsi_request - port_number field. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 1 - drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 6c0bc1c7b1e1..243eede9bbdb 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -943,7 +943,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, storvsc_req->on_io_completion = request_completion; storvsc_req->context = blkvsc_req; - storvsc_req->host = blkdev->port; + vm_srb->port_number = blkdev->port; storvsc_req->bus = blkdev->path; storvsc_req->target_id = blkdev->target; storvsc_req->lun_id = 0; /* this is not really used at all */ diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index b580c30ade99..7273f7784c97 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -549,7 +549,6 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); - vstor_packet->vm_srb.port_number = request->host; vstor_packet->vm_srb.path_id = request->bus; vstor_packet->vm_srb.target_id = request->target_id; vstor_packet->vm_srb.lun = request->lun_id; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 27781f46a293..f9dc4f1d0f9a 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -66,7 +66,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - u32 host; u32 bus; u32 target_id; u32 lun_id; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index b08423bb07d2..05bcab625281 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -774,7 +774,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, request->context = cmd_request;/* scmnd; */ /* request->PortId = scmnd->device->channel; */ - request->host = host_device_ctx->port; + vm_srb->port_number = host_device_ctx->port; request->bus = scmnd->device->channel; request->target_id = scmnd->device->id; request->lun_id = scmnd->device->lun; -- GitLab From 735625fe4d95e2a73fe41a7e4d23f05fd97b9e80 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:33 -0700 Subject: [PATCH 0372/5560] Staging: hv: Get rid of the bus field from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the bus field from struct hv_storvsc_request and instead use the equivalent state in struct vmscsi_request - path_id field. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 5 ++--- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 243eede9bbdb..29b8e408cd32 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -944,7 +944,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, storvsc_req->context = blkvsc_req; vm_srb->port_number = blkdev->port; - storvsc_req->bus = blkdev->path; + vm_srb->path_id = blkdev->path; storvsc_req->target_id = blkdev->target; storvsc_req->lun_id = 0; /* this is not really used at all */ diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 7273f7784c97..c307922a7992 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -531,8 +531,8 @@ int stor_vsc_on_io_request(struct hv_device *device, "Extension %p", device, stor_device, request, request_extension); - DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", - request, request->data_buffer.len, request->bus, + DPRINT_DBG(STORVSC, "req %p len %d target %d, lun %d cdblen %d", + request, request->data_buffer.len, request->target_id, request->lun_id, request->cdb_len); if (!stor_device) { @@ -549,7 +549,6 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); - vstor_packet->vm_srb.path_id = request->bus; vstor_packet->vm_srb.target_id = request->target_id; vstor_packet->vm_srb.lun = request->lun_id; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index f9dc4f1d0f9a..07a391befff0 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -66,7 +66,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - u32 bus; u32 target_id; u32 lun_id; u8 *cdb; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 05bcab625281..05339bf1eb0d 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -775,7 +775,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, /* request->PortId = scmnd->device->channel; */ vm_srb->port_number = host_device_ctx->port; - request->bus = scmnd->device->channel; + vm_srb->path_id = scmnd->device->channel; request->target_id = scmnd->device->id; request->lun_id = scmnd->device->lun; -- GitLab From b4dba0a3b4008c48316f712283c682f422b2c973 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:34 -0700 Subject: [PATCH 0373/5560] Staging: hv: Get rid of the target_id from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the target_id field from struct hv_storvsc_request and instead use the equivalent state in struct vmscsi_request - target_id field. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 5 ++--- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 29b8e408cd32..b0eecf8fe710 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -945,7 +945,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, vm_srb->port_number = blkdev->port; vm_srb->path_id = blkdev->path; - storvsc_req->target_id = blkdev->target; + vm_srb->target_id = blkdev->target; storvsc_req->lun_id = 0; /* this is not really used at all */ storvsc_req->cdb_len = blkvsc_req->cmd_len; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index c307922a7992..2282ba20dbab 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -531,9 +531,9 @@ int stor_vsc_on_io_request(struct hv_device *device, "Extension %p", device, stor_device, request, request_extension); - DPRINT_DBG(STORVSC, "req %p len %d target %d, lun %d cdblen %d", + DPRINT_DBG(STORVSC, "req %p len %d lun %d cdblen %d", request, request->data_buffer.len, - request->target_id, request->lun_id, request->cdb_len); + request->lun_id, request->cdb_len); if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." @@ -549,7 +549,6 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); - vstor_packet->vm_srb.target_id = request->target_id; vstor_packet->vm_srb.lun = request->lun_id; vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 07a391befff0..54690ad5f26b 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -66,7 +66,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - u32 target_id; u32 lun_id; u8 *cdb; u32 cdb_len; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 05339bf1eb0d..c77ddc1e8571 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -776,7 +776,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, /* request->PortId = scmnd->device->channel; */ vm_srb->port_number = host_device_ctx->port; vm_srb->path_id = scmnd->device->channel; - request->target_id = scmnd->device->id; + vm_srb->target_id = scmnd->device->id; request->lun_id = scmnd->device->lun; /* ASSERT(scmnd->cmd_len <= 16); */ -- GitLab From fc3967b0c3169fe8a3b33cc90e5bc8248d5b18d9 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:35 -0700 Subject: [PATCH 0374/5560] Staging: hv: Get rid of lun_id from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the lun_id field from struct hv_storvsc_request and instead use the equivalent state in struct vmscsi_request - lun field. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 5 ++--- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index b0eecf8fe710..64586232aa55 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -946,7 +946,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, vm_srb->port_number = blkdev->port; vm_srb->path_id = blkdev->path; vm_srb->target_id = blkdev->target; - storvsc_req->lun_id = 0; /* this is not really used at all */ + vm_srb->lun = 0; /* this is not really used at all */ storvsc_req->cdb_len = blkvsc_req->cmd_len; storvsc_req->cdb = blkvsc_req->cmnd; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 2282ba20dbab..849b4676c5b4 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -531,9 +531,9 @@ int stor_vsc_on_io_request(struct hv_device *device, "Extension %p", device, stor_device, request, request_extension); - DPRINT_DBG(STORVSC, "req %p len %d lun %d cdblen %d", + DPRINT_DBG(STORVSC, "req %p len %d cdblen %d", request, request->data_buffer.len, - request->lun_id, request->cdb_len); + request->cdb_len); if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." @@ -549,7 +549,6 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); - vstor_packet->vm_srb.lun = request->lun_id; vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 54690ad5f26b..940cf980a42b 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -66,7 +66,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - u32 lun_id; u8 *cdb; u32 cdb_len; u32 status; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index c77ddc1e8571..d30d74517cca 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -777,7 +777,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, vm_srb->port_number = host_device_ctx->port; vm_srb->path_id = scmnd->device->channel; vm_srb->target_id = scmnd->device->id; - request->lun_id = scmnd->device->lun; + vm_srb->lun = scmnd->device->lun; /* ASSERT(scmnd->cmd_len <= 16); */ request->cdb_len = scmnd->cmd_len; -- GitLab From 473f9409e4614880656cae2028c567831a82a03f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:36 -0700 Subject: [PATCH 0375/5560] Staging: hv: Get rid of the cdb_len from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the cdb_len field from struct hv_storvsc_request and instead use the equivalent state in struct vmscsi_request - cdb_length field. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 9 ++++----- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 64586232aa55..fb41a5bae480 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -948,7 +948,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, vm_srb->target_id = blkdev->target; vm_srb->lun = 0; /* this is not really used at all */ - storvsc_req->cdb_len = blkvsc_req->cmd_len; + vm_srb->cdb_length = blkvsc_req->cmd_len; storvsc_req->cdb = blkvsc_req->cmnd; storvsc_req->sense_buffer = blkvsc_req->sense_buffer; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 849b4676c5b4..5a5065c7a56e 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -531,9 +531,8 @@ int stor_vsc_on_io_request(struct hv_device *device, "Extension %p", device, stor_device, request, request_extension); - DPRINT_DBG(STORVSC, "req %p len %d cdblen %d", - request, request->data_buffer.len, - request->cdb_len); + DPRINT_DBG(STORVSC, "req %p len %d", + request, request->data_buffer.len); if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." @@ -553,8 +552,8 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; /* Copy over the scsi command descriptor block */ - vstor_packet->vm_srb.cdb_length = request->cdb_len; - memcpy(&vstor_packet->vm_srb.cdb, request->cdb, request->cdb_len); + memcpy(&vstor_packet->vm_srb.cdb, request->cdb, + vstor_packet->vm_srb.cdb_length); vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 940cf980a42b..fd3af2b69cda 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -67,7 +67,6 @@ struct storvsc_request_extension { struct hv_storvsc_request { u8 *cdb; - u32 cdb_len; u32 status; u32 bytes_xfer; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index d30d74517cca..c0ccae25460f 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -780,7 +780,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, vm_srb->lun = scmnd->device->lun; /* ASSERT(scmnd->cmd_len <= 16); */ - request->cdb_len = scmnd->cmd_len; + vm_srb->cdb_length = scmnd->cmd_len; request->cdb = scmnd->cmnd; request->sense_buffer = scmnd->sense_buffer; -- GitLab From 373dd8a93aab78d0074188429c350b1e457ddf23 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:37 -0700 Subject: [PATCH 0376/5560] Staging: hv: Get rid of cdb from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the cdb field from struct hv_storvsc_request and instead directly copy the command into struct vmscsi_request. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 3 ++- drivers/staging/hv/storvsc.c | 6 ++---- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 3 ++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index fb41a5bae480..daa47579f4b7 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -949,7 +949,8 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, vm_srb->lun = 0; /* this is not really used at all */ vm_srb->cdb_length = blkvsc_req->cmd_len; - storvsc_req->cdb = blkvsc_req->cmnd; + + memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length); storvsc_req->sense_buffer = blkvsc_req->sense_buffer; storvsc_req->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 5a5065c7a56e..ca41c0556a97 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -301,7 +301,8 @@ static void stor_vsc_on_io_completion(struct hv_device *device, if (request->status != 0 || vstor_packet->vm_srb.srb_status != 1) { DPRINT_WARN(STORVSC, "cmd 0x%x scsi status 0x%x srb status 0x%x\n", - request->cdb[0], vstor_packet->vm_srb.scsi_status, + vstor_packet->vm_srb.cdb[0], + vstor_packet->vm_srb.scsi_status, vstor_packet->vm_srb.srb_status); } @@ -551,9 +552,6 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; - /* Copy over the scsi command descriptor block */ - memcpy(&vstor_packet->vm_srb.cdb, request->cdb, - vstor_packet->vm_srb.cdb_length); vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index fd3af2b69cda..55c5cc6087e7 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -66,7 +66,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - u8 *cdb; u32 status; u32 bytes_xfer; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index c0ccae25460f..08c2df4d2616 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -781,7 +781,8 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, /* ASSERT(scmnd->cmd_len <= 16); */ vm_srb->cdb_length = scmnd->cmd_len; - request->cdb = scmnd->cmnd; + + memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length); request->sense_buffer = scmnd->sense_buffer; request->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; -- GitLab From 6f461cc46d2d19daf98bfe1a6502900cb80a293b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:38 -0700 Subject: [PATCH 0377/5560] Staging: hv: Get rid of sense_buffer_size from struct hv_storvsc_request In preparation for consolidating all I/O request state, get rid of the sense_buffer_size field from struct hv_storvsc_request and instead hardcode this value as is currently done. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 1 - drivers/staging/hv/storvsc.c | 2 -- drivers/staging/hv/storvsc_api.h | 1 - drivers/staging/hv/storvsc_drv.c | 3 +-- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index daa47579f4b7..838567defb98 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -953,7 +953,6 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length); storvsc_req->sense_buffer = blkvsc_req->sense_buffer; - storvsc_req->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; ret = storvsc_drv_obj->on_io_request(blkdev->device_ctx, &blkvsc_req->request); diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index ca41c0556a97..b322f863dbd2 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -318,8 +318,6 @@ static void stor_vsc_on_io_completion(struct hv_device *device, vstor_packet->vm_srb.sense_data, vstor_packet->vm_srb.sense_info_length); - request->sense_buffer_size = - vstor_packet->vm_srb.sense_info_length; } } diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 55c5cc6087e7..3eccc277ba48 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -70,7 +70,6 @@ struct hv_storvsc_request { u32 bytes_xfer; unsigned char *sense_buffer; - u32 sense_buffer_size; void *context; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 08c2df4d2616..bc435d6cc493 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -477,7 +477,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, - request->sense_buffer_size, &sense_hdr)) + SCSI_SENSE_BUFFERSIZE, &sense_hdr)) scsi_print_sense_hdr("storvsc", &sense_hdr); } @@ -785,7 +785,6 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length); request->sense_buffer = scmnd->sense_buffer; - request->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; request->data_buffer.len = scsi_bufflen(scmnd); -- GitLab From 237ecd6d58256dc95458098bc5c4b65cf4a62eee Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:39 -0700 Subject: [PATCH 0378/5560] Staging: hv: Move sense_buffer field In preparation for consolidating all I/O request state, move sense_buffer field from struct hv_storvsc_request to struct storvsc_request_extension. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 2 +- drivers/staging/hv/storvsc_api.h | 4 ++-- drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 838567defb98..54c966f31a3c 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -952,7 +952,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length); - storvsc_req->sense_buffer = blkvsc_req->sense_buffer; + storvsc_req->extension.sense_buffer = blkvsc_req->sense_buffer; ret = storvsc_drv_obj->on_io_request(blkdev->device_ctx, &blkvsc_req->request); diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index b322f863dbd2..33943ed95178 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -314,7 +314,7 @@ static void stor_vsc_on_io_completion(struct hv_device *device, "valid - len %d\n", request_ext, vstor_packet->vm_srb.sense_info_length); - memcpy(request->sense_buffer, + memcpy(request->extension.sense_buffer, vstor_packet->vm_srb.sense_data, vstor_packet->vm_srb.sense_info_length); diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 3eccc277ba48..fd9165f674da 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -62,6 +62,8 @@ struct storvsc_request_extension { /* Synchronize the request/response if needed */ struct completion wait_event; + unsigned char *sense_buffer; + struct vstor_packet vstor_packet; }; @@ -69,8 +71,6 @@ struct hv_storvsc_request { u32 status; u32 bytes_xfer; - unsigned char *sense_buffer; - void *context; void (*on_io_completion)(struct hv_storvsc_request *request); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index bc435d6cc493..3a999d057b43 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -784,7 +784,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length); - request->sense_buffer = scmnd->sense_buffer; + request->extension.sense_buffer = scmnd->sense_buffer; request->data_buffer.len = scsi_bufflen(scmnd); -- GitLab From efb5a663e460c0213cfd2a65ae4b6b35047b0e9b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:40 -0700 Subject: [PATCH 0379/5560] Staging: hv: Move the context field from struct hv_storvsc_request In preparation of consolidating all I/O request state, move the context field from struct hv_storvsc_request to struct storvsc_request_extension. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 6 +++--- drivers/staging/hv/storvsc_api.h | 3 +-- drivers/staging/hv/storvsc_drv.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 54c966f31a3c..3d061dc5609d 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -941,7 +941,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; storvsc_req->on_io_completion = request_completion; - storvsc_req->context = blkvsc_req; + storvsc_req->extension.context = blkvsc_req; vm_srb->port_number = blkdev->port; vm_srb->path_id = blkdev->path; @@ -1138,7 +1138,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, static void blkvsc_cmd_completion(struct hv_storvsc_request *request) { struct blkvsc_request *blkvsc_req = - (struct blkvsc_request *)request->context; + (struct blkvsc_request *)request->extension.context; struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; struct scsi_sense_hdr sense_hdr; @@ -1160,7 +1160,7 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) static void blkvsc_request_completion(struct hv_storvsc_request *request) { struct blkvsc_request *blkvsc_req = - (struct blkvsc_request *)request->context; + (struct blkvsc_request *)request->extension.context; struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; unsigned long flags; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index fd9165f674da..68c5036ecdad 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -63,6 +63,7 @@ struct storvsc_request_extension { struct completion wait_event; unsigned char *sense_buffer; + void *context; struct vstor_packet vstor_packet; }; @@ -71,8 +72,6 @@ struct hv_storvsc_request { u32 status; u32 bytes_xfer; - void *context; - void (*on_io_completion)(struct hv_storvsc_request *request); struct storvsc_request_extension extension; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 3a999d057b43..65e03e63da32 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -448,7 +448,7 @@ static int storvsc_remove(struct device *device) static void storvsc_commmand_completion(struct hv_storvsc_request *request) { struct storvsc_cmd_request *cmd_request = - (struct storvsc_cmd_request *)request->context; + (struct storvsc_cmd_request *)request->extension.context; struct scsi_cmnd *scmnd = cmd_request->cmd; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; @@ -771,7 +771,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, } request->on_io_completion = storvsc_commmand_completion; - request->context = cmd_request;/* scmnd; */ + request->extension.context = cmd_request;/* scmnd; */ /* request->PortId = scmnd->device->channel; */ vm_srb->port_number = host_device_ctx->port; -- GitLab From 0bb71127060b1abb76e8864d45f9be9e9fb2882d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:41 -0700 Subject: [PATCH 0380/5560] Staging: hv: Move on_io_completion() from struct hv_storvsc_request In preparation of consolidating all I/O request state, move the on_io_completion() field from struct hv_storvsc_request to struct storvsc_request_extension. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 2 +- drivers/staging/hv/storvsc_api.h | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 3d061dc5609d..4974db85b521 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -940,7 +940,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; - storvsc_req->on_io_completion = request_completion; + storvsc_req->extension.on_io_completion = request_completion; storvsc_req->extension.context = blkvsc_req; vm_srb->port_number = blkdev->port; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 33943ed95178..d444cc9dfaf4 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -324,7 +324,7 @@ static void stor_vsc_on_io_completion(struct hv_device *device, /* TODO: */ request->bytes_xfer = vstor_packet->vm_srb.data_transfer_length; - request->on_io_completion(request); + request->extension.on_io_completion(request); atomic_dec(&stor_device->num_outstanding_req); diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 68c5036ecdad..89fa15508779 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -64,6 +64,7 @@ struct storvsc_request_extension { unsigned char *sense_buffer; void *context; + void (*on_io_completion)(struct hv_storvsc_request *request); struct vstor_packet vstor_packet; }; @@ -72,7 +73,6 @@ struct hv_storvsc_request { u32 status; u32 bytes_xfer; - void (*on_io_completion)(struct hv_storvsc_request *request); struct storvsc_request_extension extension; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 65e03e63da32..e3e0486df6dc 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -770,7 +770,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, break; } - request->on_io_completion = storvsc_commmand_completion; + request->extension.on_io_completion = storvsc_commmand_completion; request->extension.context = cmd_request;/* scmnd; */ /* request->PortId = scmnd->device->channel; */ -- GitLab From 6dc3f0a7edf15fcaf90270b1ac6de501fe6a60c6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:42 -0700 Subject: [PATCH 0381/5560] Staging: hv: Get rid of the status field from struct hv_storvsc_request In preparation of consolidating all I/O request state, get rid of the status field from struct hv_storvsc_request and instead use the state in the struct vmscsi_request directly. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 23 ++++++++++++++++++----- drivers/staging/hv/storvsc.c | 8 +++----- drivers/staging/hv/storvsc_api.h | 3 --- drivers/staging/hv/storvsc_drv.c | 6 ++++-- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 4974db85b521..d0bd6fa5bc1e 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -633,6 +633,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) struct page *page_buf; unsigned char *buf; struct scsi_sense_hdr sense_hdr; + struct vmscsi_request *vm_srb; DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_read_capacity()\n"); @@ -651,6 +652,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) return -ENOMEM; } + vm_srb = &blkvsc_req->request.extension.vstor_packet.vm_srb; init_waitqueue_head(&blkvsc_req->wevent); blkvsc_req->dev = blkdev; blkvsc_req->req = NULL; @@ -677,7 +679,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); /* check error */ - if (blkvsc_req->request.status) { + if (vm_srb->scsi_status) { scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr); @@ -710,6 +712,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) struct page *page_buf; unsigned char *buf; struct scsi_sense_hdr sense_hdr; + struct vmscsi_request *vm_srb; DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_read_capacity16()\n"); @@ -722,6 +725,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) return -ENOMEM; memset(blkvsc_req, 0, sizeof(struct blkvsc_request)); + vm_srb = &blkvsc_req->request.extension.vstor_packet.vm_srb; page_buf = alloc_page(GFP_KERNEL); if (!page_buf) { kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req); @@ -754,7 +758,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); /* check error */ - if (blkvsc_req->request.status) { + if (vm_srb->scsi_status) { scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr); if (sense_hdr.asc == 0x3A) { @@ -1142,13 +1146,15 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; struct scsi_sense_hdr sense_hdr; + struct vmscsi_request *vm_srb; DPRINT_DBG(BLKVSC_DRV, "blkvsc_cmd_completion() - req %p\n", blkvsc_req); + vm_srb = &blkvsc_req->request.extension.vstor_packet.vm_srb; blkdev->num_outstanding_reqs--; - if (blkvsc_req->request.status) + if (vm_srb->scsi_status) if (scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) scsi_print_sense_hdr("blkvsc", &sense_hdr); @@ -1165,6 +1171,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) (struct block_device_context *)blkvsc_req->dev; unsigned long flags; struct blkvsc_request *comp_req, *tmp; + struct vmscsi_request *vm_srb; /* ASSERT(blkvsc_req->group); */ @@ -1201,8 +1208,10 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) list_del(&comp_req->req_entry); + vm_srb = + &comp_req->request.extension.vstor_packet.vm_srb; if (!__blk_end_request(comp_req->req, - (!comp_req->request.status ? 0 : -EIO), + (!vm_srb->scsi_status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size)) { /* * All the sectors have been xferred ie the @@ -1231,6 +1240,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) { struct blkvsc_request *pend_req, *tmp; struct blkvsc_request *comp_req, *tmp2; + struct vmscsi_request *vm_srb; int ret = 0; @@ -1259,8 +1269,11 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) list_del(&comp_req->req_entry); if (comp_req->req) { + vm_srb = + &comp_req->request.extension.vstor_packet. + vm_srb; ret = __blk_end_request(comp_req->req, - (!comp_req->request.status ? 0 : -EIO), + (!vm_srb->scsi_status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size); diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index d444cc9dfaf4..6a45d5752c08 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -296,9 +296,9 @@ static void stor_vsc_on_io_completion(struct hv_device *device, /* Copy over the status...etc */ - request->status = vstor_packet->vm_srb.scsi_status; - if (request->status != 0 || vstor_packet->vm_srb.srb_status != 1) { + if (vstor_packet->vm_srb.scsi_status != 0 || + vstor_packet->vm_srb.srb_status != 1) { DPRINT_WARN(STORVSC, "cmd 0x%x scsi status 0x%x srb status 0x%x\n", vstor_packet->vm_srb.cdb[0], @@ -306,7 +306,7 @@ static void stor_vsc_on_io_completion(struct hv_device *device, vstor_packet->vm_srb.srb_status); } - if ((request->status & 0xFF) == 0x02) { + if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) { /* CHECK_CONDITION */ if (vstor_packet->vm_srb.srb_status & 0x80) { /* autosense data available */ @@ -321,8 +321,6 @@ static void stor_vsc_on_io_completion(struct hv_device *device, } } - /* TODO: */ - request->bytes_xfer = vstor_packet->vm_srb.data_transfer_length; request->extension.on_io_completion(request); diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 89fa15508779..1705b9f2d298 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -70,9 +70,6 @@ struct storvsc_request_extension { }; struct hv_storvsc_request { - u32 status; - u32 bytes_xfer; - struct storvsc_request_extension extension; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index e3e0486df6dc..a2faaef9321d 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -454,6 +454,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) (struct host_device_context *)scmnd->device->host->hostdata; void (*scsi_done_fn)(struct scsi_cmnd *); struct scsi_sense_hdr sense_hdr; + struct vmscsi_request *vm_srb; /* ASSERT(request == &cmd_request->request); */ /* ASSERT(scmnd); */ @@ -473,7 +474,8 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) cmd_request->bounce_sgl_count); } - scmnd->result = request->status; + vm_srb = &request->extension.vstor_packet.vm_srb; + scmnd->result = vm_srb->scsi_status; if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, @@ -483,7 +485,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) /* ASSERT(request->BytesXfer <= request->data_buffer.Length); */ scsi_set_resid(scmnd, - request->data_buffer.len - request->bytes_xfer); + request->data_buffer.len - vm_srb->data_transfer_length); scsi_done_fn = scmnd->scsi_done; -- GitLab From e9e936c60dfa4ea5ead0ddf5f9ee457a1906366d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:43 -0700 Subject: [PATCH 0382/5560] Staging: hv: Move the data_buffer field from struct hv_storvsc_request In preparation of consolidating all I/O request state, move the data_buffer field from struct hv_storvsc_request struct storvsc_request_extension. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 46 +++++++++++++++++--------------- drivers/staging/hv/storvsc.c | 10 ++++--- drivers/staging/hv/storvsc_api.h | 2 +- drivers/staging/hv/storvsc_drv.c | 13 ++++----- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index d0bd6fa5bc1e..7aa0f164ede2 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -522,9 +522,9 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.pfn_array[0] = 0; - blkvsc_req->request.data_buffer.offset = 0; - blkvsc_req->request.data_buffer.len = 0; + blkvsc_req->request.extension.data_buffer.pfn_array[0] = 0; + blkvsc_req->request.extension.data_buffer.offset = 0; + blkvsc_req->request.extension.data_buffer.len = 0; blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE; blkvsc_req->cmd_len = 10; @@ -569,9 +569,10 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); - blkvsc_req->request.data_buffer.offset = 0; - blkvsc_req->request.data_buffer.len = 64; + blkvsc_req->request.extension.data_buffer.pfn_array[0] = + page_to_pfn(page_buf); + blkvsc_req->request.extension.data_buffer.offset = 0; + blkvsc_req->request.extension.data_buffer.len = 64; blkvsc_req->cmnd[0] = INQUIRY; blkvsc_req->cmnd[1] = 0x1; /* Get product data */ @@ -658,9 +659,10 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); - blkvsc_req->request.data_buffer.offset = 0; - blkvsc_req->request.data_buffer.len = 8; + blkvsc_req->request.extension.data_buffer.pfn_array[0] = + page_to_pfn(page_buf); + blkvsc_req->request.extension.data_buffer.offset = 0; + blkvsc_req->request.extension.data_buffer.len = 8; blkvsc_req->cmnd[0] = READ_CAPACITY; blkvsc_req->cmd_len = 16; @@ -737,9 +739,10 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); - blkvsc_req->request.data_buffer.offset = 0; - blkvsc_req->request.data_buffer.len = 12; + blkvsc_req->request.extension.data_buffer.pfn_array[0] = + page_to_pfn(page_buf); + blkvsc_req->request.extension.data_buffer.offset = 0; + blkvsc_req->request.extension.data_buffer.len = 12; blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */ blkvsc_req->cmd_len = 16; @@ -928,8 +931,8 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long) blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.data_buffer.offset, - blkvsc_req->request.data_buffer.len); + blkvsc_req->request.extension.data_buffer.offset, + blkvsc_req->request.extension.data_buffer.len); #if 0 for (i = 0; i < (blkvsc_req->request.data_buffer.len >> 12); i++) { DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - " @@ -1056,10 +1059,11 @@ static int blkvsc_do_request(struct block_device_context *blkdev, blkvsc_req->dev = blkdev; blkvsc_req->req = req; - blkvsc_req->request.data_buffer.offset - = bvec->bv_offset; - blkvsc_req->request.data_buffer.len - = 0; + blkvsc_req->request.extension. + data_buffer.offset + = bvec->bv_offset; + blkvsc_req->request.extension. + data_buffer.len = 0; /* Add to the group */ blkvsc_req->group = group; @@ -1073,10 +1077,10 @@ static int blkvsc_do_request(struct block_device_context *blkdev, } /* Add the curr bvec/segment to the curr blkvsc_req */ - blkvsc_req->request.data_buffer. + blkvsc_req->request.extension.data_buffer. pfn_array[databuf_idx] = page_to_pfn(bvec->bv_page); - blkvsc_req->request.data_buffer.len + blkvsc_req->request.extension.data_buffer.len += bvec->bv_len; prev_bvec = bvec; @@ -1182,7 +1186,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long)blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.data_buffer.len, + blkvsc_req->request.extension.data_buffer.len, blkvsc_req->group->outstanding, blkdev->num_outstanding_reqs); diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 6a45d5752c08..0fdbd3427995 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -529,7 +529,7 @@ int stor_vsc_on_io_request(struct hv_device *device, request_extension); DPRINT_DBG(STORVSC, "req %p len %d", - request, request->data_buffer.len); + request, request->extension.data_buffer.len); if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." @@ -549,7 +549,8 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; - vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len; + vstor_packet->vm_srb.data_transfer_length = + request->extension.data_buffer.len; vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; @@ -563,9 +564,10 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length, vstor_packet->vm_srb.cdb_length); - if (request_extension->request->data_buffer.len) { + if (request_extension->request->extension.data_buffer.len) { ret = vmbus_sendpacket_multipagebuffer(device->channel, - &request_extension->request->data_buffer, + &request_extension->request->extension. + data_buffer, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request_extension); diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 1705b9f2d298..f4b70319c67c 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -65,6 +65,7 @@ struct storvsc_request_extension { unsigned char *sense_buffer; void *context; void (*on_io_completion)(struct hv_storvsc_request *request); + struct hv_multipage_buffer data_buffer; struct vstor_packet vstor_packet; }; @@ -73,7 +74,6 @@ struct hv_storvsc_request { struct storvsc_request_extension extension; - struct hv_multipage_buffer data_buffer; }; /* Represents the block vsc driver */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index a2faaef9321d..54be899bfe77 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -485,7 +485,8 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) /* ASSERT(request->BytesXfer <= request->data_buffer.Length); */ scsi_set_resid(scmnd, - request->data_buffer.len - vm_srb->data_transfer_length); + request->extension.data_buffer.len - + vm_srb->data_transfer_length); scsi_done_fn = scmnd->scsi_done; @@ -789,7 +790,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, request->extension.sense_buffer = scmnd->sense_buffer; - request->data_buffer.len = scsi_bufflen(scmnd); + request->extension.data_buffer.len = scsi_bufflen(scmnd); if (scsi_sg_count(scmnd)) { sgl = (struct scatterlist *)scsi_sglist(scmnd); sg_count = scsi_sg_count(scmnd); @@ -830,19 +831,19 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, sg_count = cmd_request->bounce_sgl_count; } - request->data_buffer.offset = sgl[0].offset; + request->extension.data_buffer.offset = sgl[0].offset; for (i = 0; i < sg_count; i++) { DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", i, sgl[i].length, sgl[i].offset); - request->data_buffer.pfn_array[i] = + request->extension.data_buffer.pfn_array[i] = page_to_pfn(sg_page((&sgl[i]))); } } else if (scsi_sglist(scmnd)) { /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ - request->data_buffer.offset = + request->extension.data_buffer.offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); - request->data_buffer.pfn_array[0] = + request->extension.data_buffer.pfn_array[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; } -- GitLab From d7a1bdb990b9dfe93d080dc242860e33d08ec5a6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:44 -0700 Subject: [PATCH 0383/5560] Staging: hv: Rename struct storvsc_request_extension Now that all duplicate state has been eliminated from struct hv_storvsc_request and all needed state has been moved to struct storvsc_request_extension, get rid of struct hv_storvsc_request and rename struct storvsc_request_extension as struct hv_storvsc_request. Cleanup and consolidation of I/O request state is now complete. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 60 ++++++++++++++++---------------- drivers/staging/hv/storvsc.c | 49 +++++++++++--------------- drivers/staging/hv/storvsc_api.h | 11 ++---- drivers/staging/hv/storvsc_drv.c | 31 ++++++++--------- 4 files changed, 69 insertions(+), 82 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 7aa0f164ede2..8c5b1e2609a8 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -522,9 +522,9 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.extension.data_buffer.pfn_array[0] = 0; - blkvsc_req->request.extension.data_buffer.offset = 0; - blkvsc_req->request.extension.data_buffer.len = 0; + blkvsc_req->request.data_buffer.pfn_array[0] = 0; + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 0; blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE; blkvsc_req->cmd_len = 10; @@ -569,10 +569,10 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.extension.data_buffer.pfn_array[0] = + blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); - blkvsc_req->request.extension.data_buffer.offset = 0; - blkvsc_req->request.extension.data_buffer.len = 64; + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 64; blkvsc_req->cmnd[0] = INQUIRY; blkvsc_req->cmnd[1] = 0x1; /* Get product data */ @@ -653,16 +653,16 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) return -ENOMEM; } - vm_srb = &blkvsc_req->request.extension.vstor_packet.vm_srb; + vm_srb = &blkvsc_req->request.vstor_packet.vm_srb; init_waitqueue_head(&blkvsc_req->wevent); blkvsc_req->dev = blkdev; blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.extension.data_buffer.pfn_array[0] = + blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); - blkvsc_req->request.extension.data_buffer.offset = 0; - blkvsc_req->request.extension.data_buffer.len = 8; + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 8; blkvsc_req->cmnd[0] = READ_CAPACITY; blkvsc_req->cmd_len = 16; @@ -727,7 +727,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) return -ENOMEM; memset(blkvsc_req, 0, sizeof(struct blkvsc_request)); - vm_srb = &blkvsc_req->request.extension.vstor_packet.vm_srb; + vm_srb = &blkvsc_req->request.vstor_packet.vm_srb; page_buf = alloc_page(GFP_KERNEL); if (!page_buf) { kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req); @@ -739,10 +739,10 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.extension.data_buffer.pfn_array[0] = + blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); - blkvsc_req->request.extension.data_buffer.offset = 0; - blkvsc_req->request.extension.data_buffer.len = 12; + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 12; blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */ blkvsc_req->cmd_len = 16; @@ -931,8 +931,8 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long) blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.extension.data_buffer.offset, - blkvsc_req->request.extension.data_buffer.len); + blkvsc_req->request.data_buffer.offset, + blkvsc_req->request.data_buffer.len); #if 0 for (i = 0; i < (blkvsc_req->request.data_buffer.len >> 12); i++) { DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - " @@ -943,12 +943,12 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, #endif storvsc_req = &blkvsc_req->request; - vm_srb = &storvsc_req->extension.vstor_packet.vm_srb; + vm_srb = &storvsc_req->vstor_packet.vm_srb; vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; - storvsc_req->extension.on_io_completion = request_completion; - storvsc_req->extension.context = blkvsc_req; + storvsc_req->on_io_completion = request_completion; + storvsc_req->context = blkvsc_req; vm_srb->port_number = blkdev->port; vm_srb->path_id = blkdev->path; @@ -959,7 +959,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length); - storvsc_req->extension.sense_buffer = blkvsc_req->sense_buffer; + storvsc_req->sense_buffer = blkvsc_req->sense_buffer; ret = storvsc_drv_obj->on_io_request(blkdev->device_ctx, &blkvsc_req->request); @@ -1059,10 +1059,10 @@ static int blkvsc_do_request(struct block_device_context *blkdev, blkvsc_req->dev = blkdev; blkvsc_req->req = req; - blkvsc_req->request.extension. + blkvsc_req->request. data_buffer.offset = bvec->bv_offset; - blkvsc_req->request.extension. + blkvsc_req->request. data_buffer.len = 0; /* Add to the group */ @@ -1077,10 +1077,10 @@ static int blkvsc_do_request(struct block_device_context *blkdev, } /* Add the curr bvec/segment to the curr blkvsc_req */ - blkvsc_req->request.extension.data_buffer. + blkvsc_req->request.data_buffer. pfn_array[databuf_idx] = page_to_pfn(bvec->bv_page); - blkvsc_req->request.extension.data_buffer.len + blkvsc_req->request.data_buffer.len += bvec->bv_len; prev_bvec = bvec; @@ -1146,7 +1146,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, static void blkvsc_cmd_completion(struct hv_storvsc_request *request) { struct blkvsc_request *blkvsc_req = - (struct blkvsc_request *)request->extension.context; + (struct blkvsc_request *)request->context; struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; struct scsi_sense_hdr sense_hdr; @@ -1155,7 +1155,7 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) DPRINT_DBG(BLKVSC_DRV, "blkvsc_cmd_completion() - req %p\n", blkvsc_req); - vm_srb = &blkvsc_req->request.extension.vstor_packet.vm_srb; + vm_srb = &blkvsc_req->request.vstor_packet.vm_srb; blkdev->num_outstanding_reqs--; if (vm_srb->scsi_status) @@ -1170,7 +1170,7 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) static void blkvsc_request_completion(struct hv_storvsc_request *request) { struct blkvsc_request *blkvsc_req = - (struct blkvsc_request *)request->extension.context; + (struct blkvsc_request *)request->context; struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; unsigned long flags; @@ -1186,7 +1186,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long)blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.extension.data_buffer.len, + blkvsc_req->request.data_buffer.len, blkvsc_req->group->outstanding, blkdev->num_outstanding_reqs); @@ -1213,7 +1213,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) list_del(&comp_req->req_entry); vm_srb = - &comp_req->request.extension.vstor_packet.vm_srb; + &comp_req->request.vstor_packet.vm_srb; if (!__blk_end_request(comp_req->req, (!vm_srb->scsi_status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size)) { @@ -1274,7 +1274,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) if (comp_req->req) { vm_srb = - &comp_req->request.extension.vstor_packet. + &comp_req->request.vstor_packet. vm_srb; ret = __blk_end_request(comp_req->req, (!vm_srb->scsi_status ? 0 : -EIO), diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 0fdbd3427995..55865fae7145 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -105,7 +105,7 @@ static inline struct storvsc_device *final_release_stor_device( static int stor_vsc_channel_init(struct hv_device *device) { struct storvsc_device *stor_device; - struct storvsc_request_extension *request; + struct hv_storvsc_request *request; struct vstor_packet *vstor_packet; int ret, t; @@ -123,7 +123,7 @@ static int stor_vsc_channel_init(struct hv_device *device) * Now, initiate the vsc/vsp initialization protocol on the open * channel */ - memset(request, 0, sizeof(struct storvsc_request_extension)); + memset(request, 0, sizeof(struct hv_storvsc_request)); init_completion(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -276,9 +276,8 @@ static int stor_vsc_channel_init(struct hv_device *device) static void stor_vsc_on_io_completion(struct hv_device *device, struct vstor_packet *vstor_packet, - struct storvsc_request_extension *request_ext) + struct hv_storvsc_request *request) { - struct hv_storvsc_request *request; struct storvsc_device *stor_device; stor_device = must_get_stor_device(device); @@ -288,11 +287,10 @@ static void stor_vsc_on_io_completion(struct hv_device *device, return; } - DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " - "completed bytes xfer %u", request_ext, + DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request %p " + "completed bytes xfer %u", request, vstor_packet->vm_srb.data_transfer_length); - request = request_ext->request; /* Copy over the status...etc */ @@ -311,10 +309,10 @@ static void stor_vsc_on_io_completion(struct hv_device *device, if (vstor_packet->vm_srb.srb_status & 0x80) { /* autosense data available */ DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " - "valid - len %d\n", request_ext, + "valid - len %d\n", request, vstor_packet->vm_srb.sense_info_length); - memcpy(request->extension.sense_buffer, + memcpy(request->sense_buffer, vstor_packet->vm_srb.sense_data, vstor_packet->vm_srb.sense_info_length); @@ -322,7 +320,7 @@ static void stor_vsc_on_io_completion(struct hv_device *device, } - request->extension.on_io_completion(request); + request->on_io_completion(request); atomic_dec(&stor_device->num_outstanding_req); @@ -331,12 +329,12 @@ static void stor_vsc_on_io_completion(struct hv_device *device, static void stor_vsc_on_receive(struct hv_device *device, struct vstor_packet *vstor_packet, - struct storvsc_request_extension *request_ext) + struct hv_storvsc_request *request) { switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); - stor_vsc_on_io_completion(device, vstor_packet, request_ext); + stor_vsc_on_io_completion(device, vstor_packet, request); break; case VSTOR_OPERATION_REMOVE_DEVICE: DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); @@ -357,7 +355,7 @@ static void stor_vsc_on_channel_callback(void *context) u32 bytes_recvd; u64 request_id; unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)]; - struct storvsc_request_extension *request; + struct hv_storvsc_request *request; int ret; @@ -377,7 +375,7 @@ static void stor_vsc_on_channel_callback(void *context) bytes_recvd, request_id); - request = (struct storvsc_request_extension *) + request = (struct hv_storvsc_request *) (unsigned long)request_id; if ((request == &stor_device->init_request) || @@ -516,20 +514,17 @@ int stor_vsc_on_io_request(struct hv_device *device, struct hv_storvsc_request *request) { struct storvsc_device *stor_device; - struct storvsc_request_extension *request_extension; struct vstor_packet *vstor_packet; int ret = 0; - request_extension = &request->extension; - vstor_packet = &request_extension->vstor_packet; + vstor_packet = &request->vstor_packet; stor_device = get_stor_device(device); DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, " - "Extension %p", device, stor_device, request, - request_extension); + , device, stor_device, request); DPRINT_DBG(STORVSC, "req %p len %d", - request, request->extension.data_buffer.len); + request, request->data_buffer.len); if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." @@ -538,8 +533,7 @@ int stor_vsc_on_io_request(struct hv_device *device, } - request_extension->request = request; - request_extension->device = device; + request->device = device; vstor_packet->flags |= REQUEST_COMPLETION_FLAG; @@ -550,7 +544,7 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.data_transfer_length = - request->extension.data_buffer.len; + request->data_buffer.len; vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; @@ -564,17 +558,16 @@ int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length, vstor_packet->vm_srb.cdb_length); - if (request_extension->request->extension.data_buffer.len) { + if (request->data_buffer.len) { ret = vmbus_sendpacket_multipagebuffer(device->channel, - &request_extension->request->extension. - data_buffer, + &request->data_buffer, vstor_packet, sizeof(struct vstor_packet), - (unsigned long)request_extension); + (unsigned long)request); } else { ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), - (unsigned long)request_extension, + (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); } diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index f4b70319c67c..d7db94929494 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -55,7 +55,7 @@ enum storvsc_request_type{ }; -struct storvsc_request_extension { +struct hv_storvsc_request { struct hv_storvsc_request *request; struct hv_device *device; @@ -70,11 +70,6 @@ struct storvsc_request_extension { struct vstor_packet vstor_packet; }; -struct hv_storvsc_request { - - struct storvsc_request_extension extension; - -}; /* Represents the block vsc driver */ struct storvsc_driver_object { @@ -116,8 +111,8 @@ struct storvsc_device { unsigned char target_id; /* Used for vsc/vsp channel reset process */ - struct storvsc_request_extension init_request; - struct storvsc_request_extension reset_request; + struct hv_storvsc_request init_request; + struct hv_storvsc_request reset_request; }; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 54be899bfe77..6128ffd026c1 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -81,12 +81,11 @@ static int stor_vsc_initialize(struct hv_driver *driver) stor_driver = hvdr_to_stordr(driver); - DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " - "sizeof(struct storvsc_request_extension)=%zd " + DPRINT_DBG(STORVSC, + "sizeof(struct hv_storvsc_request)=%zd " "sizeof(struct vstor_packet)=%zd, " "sizeof(struct vmscsi_request)=%zd", sizeof(struct hv_storvsc_request), - sizeof(struct storvsc_request_extension), sizeof(struct vstor_packet), sizeof(struct vmscsi_request)); @@ -229,7 +228,7 @@ static int storvsc_drv_init(void) static int stor_vsc_on_host_reset(struct hv_device *device) { struct storvsc_device *stor_device; - struct storvsc_request_extension *request; + struct hv_storvsc_request *request; struct vstor_packet *vstor_packet; int ret, t; @@ -448,7 +447,7 @@ static int storvsc_remove(struct device *device) static void storvsc_commmand_completion(struct hv_storvsc_request *request) { struct storvsc_cmd_request *cmd_request = - (struct storvsc_cmd_request *)request->extension.context; + (struct storvsc_cmd_request *)request->context; struct scsi_cmnd *scmnd = cmd_request->cmd; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; @@ -474,7 +473,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) cmd_request->bounce_sgl_count); } - vm_srb = &request->extension.vstor_packet.vm_srb; + vm_srb = &request->vstor_packet.vm_srb; scmnd->result = vm_srb->scsi_status; if (scmnd->result) { @@ -485,7 +484,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) /* ASSERT(request->BytesXfer <= request->data_buffer.Length); */ scsi_set_resid(scmnd, - request->extension.data_buffer.len - + request->data_buffer.len - vm_srb->data_transfer_length); scsi_done_fn = scmnd->scsi_done; @@ -756,7 +755,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, scmnd->host_scribble = (unsigned char *)cmd_request; request = &cmd_request->request; - vm_srb = &request->extension.vstor_packet.vm_srb; + vm_srb = &request->vstor_packet.vm_srb; DPRINT_DBG(STORVSC_DRV, "req %p size %d", request, request_size); @@ -773,8 +772,8 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, break; } - request->extension.on_io_completion = storvsc_commmand_completion; - request->extension.context = cmd_request;/* scmnd; */ + request->on_io_completion = storvsc_commmand_completion; + request->context = cmd_request;/* scmnd; */ /* request->PortId = scmnd->device->channel; */ vm_srb->port_number = host_device_ctx->port; @@ -787,10 +786,10 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length); - request->extension.sense_buffer = scmnd->sense_buffer; + request->sense_buffer = scmnd->sense_buffer; - request->extension.data_buffer.len = scsi_bufflen(scmnd); + request->data_buffer.len = scsi_bufflen(scmnd); if (scsi_sg_count(scmnd)) { sgl = (struct scatterlist *)scsi_sglist(scmnd); sg_count = scsi_sg_count(scmnd); @@ -831,19 +830,19 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, sg_count = cmd_request->bounce_sgl_count; } - request->extension.data_buffer.offset = sgl[0].offset; + request->data_buffer.offset = sgl[0].offset; for (i = 0; i < sg_count; i++) { DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", i, sgl[i].length, sgl[i].offset); - request->extension.data_buffer.pfn_array[i] = + request->data_buffer.pfn_array[i] = page_to_pfn(sg_page((&sgl[i]))); } } else if (scsi_sglist(scmnd)) { /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ - request->extension.data_buffer.offset = + request->data_buffer.offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); - request->extension.data_buffer.pfn_array[0] = + request->data_buffer.pfn_array[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; } -- GitLab From f3365453a3c4a1e8ca28c0dedabf371385456d1f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 28 Mar 2011 09:33:45 -0700 Subject: [PATCH 0384/5560] Staging: hv: Get rid of synch primitive in struct blkvsc_request Get rid of synch primitive in struct blkvsc_request and instead use the synch primitive already embedded in the struct hv_storvsc_request structure. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 52 ++++++++++----------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 8c5b1e2609a8..d1ecd60b0d03 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -72,9 +72,6 @@ struct blkvsc_request { /* The group this request is part of. Maybe null */ struct blkvsc_request_group *group; - wait_queue_head_t wevent; - int cond; - int write; sector_t sector_start; unsigned long sector_count; @@ -517,7 +514,7 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) return -ENOMEM; memset(blkvsc_req, 0, sizeof(struct blkvsc_request)); - init_waitqueue_head(&blkvsc_req->wevent); + init_completion(&blkvsc_req->request.wait_event); blkvsc_req->dev = blkdev; blkvsc_req->req = NULL; blkvsc_req->write = 0; @@ -529,14 +526,9 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE; blkvsc_req->cmd_len = 10; - /* - * Set this here since the completion routine may be invoked and - * completed before we return - */ - blkvsc_req->cond = 0; blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion); - wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); + wait_for_completion_interruptible(&blkvsc_req->request.wait_event); kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req); @@ -564,7 +556,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) return -ENOMEM; } - init_waitqueue_head(&blkvsc_req->wevent); + init_completion(&blkvsc_req->request.wait_event); blkvsc_req->dev = blkdev; blkvsc_req->req = NULL; blkvsc_req->write = 0; @@ -580,18 +572,12 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkvsc_req->cmnd[4] = 64; blkvsc_req->cmd_len = 6; - /* - * Set this here since the completion routine may be invoked and - * completed before we return - */ - blkvsc_req->cond = 0; - blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion); - DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n", - blkvsc_req, blkvsc_req->cond); + DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete\n", + blkvsc_req); - wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); + wait_for_completion_interruptible(&blkvsc_req->request.wait_event); buf = kmap(page_buf); @@ -654,7 +640,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) } vm_srb = &blkvsc_req->request.vstor_packet.vm_srb; - init_waitqueue_head(&blkvsc_req->wevent); + init_completion(&blkvsc_req->request.wait_event); blkvsc_req->dev = blkdev; blkvsc_req->req = NULL; blkvsc_req->write = 0; @@ -667,18 +653,12 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) blkvsc_req->cmnd[0] = READ_CAPACITY; blkvsc_req->cmd_len = 16; - /* - * Set this here since the completion routine may be invoked - * and completed before we return - */ - blkvsc_req->cond = 0; - blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion); - DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n", - blkvsc_req, blkvsc_req->cond); + DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete\n", + blkvsc_req); - wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); + wait_for_completion_interruptible(&blkvsc_req->request.wait_event); /* check error */ if (vm_srb->scsi_status) { @@ -734,7 +714,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) return -ENOMEM; } - init_waitqueue_head(&blkvsc_req->wevent); + init_completion(&blkvsc_req->request.wait_event); blkvsc_req->dev = blkdev; blkvsc_req->req = NULL; blkvsc_req->write = 0; @@ -751,14 +731,13 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) * Set this here since the completion routine may be invoked * and completed before we return */ - blkvsc_req->cond = 0; blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion); - DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n", - blkvsc_req, blkvsc_req->cond); + DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete\n", + blkvsc_req); - wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); + wait_for_completion_interruptible(&blkvsc_req->request.wait_event); /* check error */ if (vm_srb->scsi_status) { @@ -1163,8 +1142,7 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) SCSI_SENSE_BUFFERSIZE, &sense_hdr)) scsi_print_sense_hdr("blkvsc", &sense_hdr); - blkvsc_req->cond = 1; - wake_up_interruptible(&blkvsc_req->wevent); + complete(&blkvsc_req->request.wait_event); } static void blkvsc_request_completion(struct hv_storvsc_request *request) -- GitLab From 98e087022b611c6f748c74d952193ccf69280f52 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:44 -0700 Subject: [PATCH 0385/5560] staging: hv: Remove all unneeded DPRINT from hv_vmbus Remove all un-needed DPRINT calls from hv_vmbus. Several are remaining that will be cleaned up in my next set of patches. They deal with printing out the ringbuffer debugging which is going to be implemented slightly differently. This patch deals with hv_vmbus only. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 70 ++++--------------------------- drivers/staging/hv/channel_mgmt.c | 51 ++-------------------- drivers/staging/hv/connection.c | 9 ---- drivers/staging/hv/hv.c | 54 ++++-------------------- drivers/staging/hv/ring_buffer.c | 20 --------- drivers/staging/hv/vmbus_drv.c | 69 +----------------------------- 6 files changed, 21 insertions(+), 252 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 775a52a91222..c90dbaf0c473 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -213,9 +213,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, /* Establish the gpadl for the ring buffer */ - DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", - newchannel); - newchannel->ringbuffer_gpadlhandle = 0; ret = vmbus_establish_gpadl(newchannel, @@ -229,16 +226,6 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, goto errorout; } - DPRINT_DBG(VMBUS, "channel %p ", - newchannel, newchannel->offermsg.child_relid, - newchannel->ringbuffer_gpadlhandle, - newchannel->outbound.ring_buffer, - newchannel->outbound.ring_size, - newchannel->inbound.ring_buffer, - newchannel->inbound.ring_size, - send_ringbuffer_size); - /* Create and init the channel open message */ openInfo = kmalloc(sizeof(*openInfo) + sizeof(struct vmbus_channel_open_channel), @@ -272,14 +259,11 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - DPRINT_DBG(VMBUS, "Sending channel open msg..."); - ret = vmbus_post_msg(openMsg, sizeof(struct vmbus_channel_open_channel)); - if (ret != 0) { - DPRINT_ERR(VMBUS, "unable to open channel - %d", ret); + + if (ret != 0) goto Cleanup; - } openInfo->wait_condition = 0; wait_event_timeout(openInfo->waitevent, @@ -291,11 +275,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, } - if (openInfo->response.open_result.status == 0) - DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel); - else - DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!", - newchannel, openInfo->response.open_result.status); + if (openInfo->response.open_result.status) + err = openInfo->response.open_result.status; Cleanup: spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); @@ -303,7 +284,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); kfree(openInfo); - return 0; + return err; errorout: ringbuffer_cleanup(&newchannel->outbound); @@ -326,6 +307,7 @@ static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len) pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) / sizeof(u64); + DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount); for (i = 0; i < pfncount; i++) @@ -530,19 +512,12 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d", - kbuffer, size, msgcount); - - DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", - msginfo->msgsize - sizeof(*msginfo)); msginfo->wait_condition = 0; ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - sizeof(*msginfo)); - if (ret != 0) { - DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret); + if (ret != 0) goto Cleanup; - } if (msgcount > 1) { list_for_each(curr, &msginfo->submsglist) { @@ -556,10 +531,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, CHANNELMSG_GPADL_BODY; gpadl_body->gpadl = next_gpadl_handle; - DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd", - submsginfo->msgsize - - sizeof(*submsginfo)); - dump_gpadl_body(gpadl_body, submsginfo->msgsize - sizeof(*submsginfo)); ret = vmbus_post_msg(gpadl_body, @@ -577,12 +548,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, /* At this point, we received the gpadl created msg */ - DPRINT_DBG(VMBUS, "Received GPADL created " - "(relid %d, status %d handle %x)", - channel->offermsg.child_relid, - msginfo->response.gpadl_created.creation_status, - gpadlmsg->gpadl); - *gpadl_handle = gpadlmsg->gpadl; Cleanup: @@ -730,9 +695,6 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, u64 aligned_data = 0; int ret; - DPRINT_DBG(VMBUS, "channel %p buffer %p len %d", - channel, buffer, bufferlen); - dump_vmbus_channel(channel); /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ @@ -846,10 +808,6 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, dump_vmbus_channel(channel); - DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", - multi_pagebuffer->offset, - multi_pagebuffer->len, pfncount); - if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT)) return -EINVAL; @@ -926,8 +884,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, sizeof(struct vmpacket_descriptor)); if (ret != 0) { spin_unlock_irqrestore(&channel->inbound_lock, flags); - - /* DPRINT_DBG(VMBUS, "nothing to read!!"); */ return 0; } @@ -937,11 +893,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, userlen = packetlen - (desc.offset8 << 3); /* ASSERT(userLen > 0); */ - DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - channel, channel->offermsg.child_relid, desc.type, - desc.flags, desc.trans_id, packetlen, userlen); - *buffer_actual_len = userlen; if (userlen > bufferlen) { @@ -986,8 +937,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, sizeof(struct vmpacket_descriptor)); if (ret != 0) { spin_unlock_irqrestore(&channel->inbound_lock, flags); - - /* DPRINT_DBG(VMBUS, "nothing to read!!"); */ return 0; } @@ -996,11 +945,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, packetlen = desc.len8 << 3; userlen = packetlen - (desc.offset8 << 3); - DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - channel, channel->offermsg.child_relid, desc.type, - desc.flags, desc.trans_id, packetlen, userlen); - *buffer_actual_len = packetlen; if (packetlen > bufferlen) { diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index bc0393a41d29..e82a4bb41d17 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -290,9 +290,7 @@ static void release_channel(struct work_struct *work) struct vmbus_channel, work); - DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); destroy_workqueue(channel->controlwq); - DPRINT_DBG(VMBUS, "channel released (%p)", channel); kfree(channel); } @@ -384,8 +382,6 @@ static void vmbus_process_offer(struct work_struct *work) spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); if (!fnew) { - DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)", - newchannel->offermsg.child_relid); free_channel(newchannel); return; } @@ -400,9 +396,6 @@ static void vmbus_process_offer(struct work_struct *work) &newchannel->offermsg.offer.if_instance, newchannel); - DPRINT_DBG(VMBUS, "child device object allocated - %p", - newchannel->device_obj); - /* * Add the new device to the bus. This will kick off device-driver * binding which eventually invokes the device driver's AddDevice() @@ -470,40 +463,12 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) } } - if (!fsupported) { - DPRINT_DBG(VMBUS, "Ignoring channel offer notification for " - "child relid %d", offer->child_relid); + if (!fsupported) return; - } guidtype = &offer->offer.if_type; guidinstance = &offer->offer.if_instance; - DPRINT_INFO(VMBUS, "Channel offer notification - " - "child relid %d monitor id %d allocated %d, " - "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x} " - "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - offer->child_relid, offer->monitorid, - offer->monitor_allocated, - guidtype->data[3], guidtype->data[2], - guidtype->data[1], guidtype->data[0], - guidtype->data[5], guidtype->data[4], - guidtype->data[7], guidtype->data[6], - guidtype->data[8], guidtype->data[9], - guidtype->data[10], guidtype->data[11], - guidtype->data[12], guidtype->data[13], - guidtype->data[14], guidtype->data[15], - guidinstance->data[3], guidinstance->data[2], - guidinstance->data[1], guidinstance->data[0], - guidinstance->data[5], guidinstance->data[4], - guidinstance->data[7], guidinstance->data[6], - guidinstance->data[8], guidinstance->data[9], - guidinstance->data[10], guidinstance->data[11], - guidinstance->data[12], guidinstance->data[13], - guidinstance->data[14], guidinstance->data[15]); - /* Allocate the channel object and save this offer. */ newchannel = alloc_channel(); if (!newchannel) { @@ -511,8 +476,6 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) return; } - DPRINT_DBG(VMBUS, "channel object allocated - %p", newchannel); - memcpy(&newchannel->offermsg, offer, sizeof(struct vmbus_channel_offer_channel)); newchannel->monitor_grp = (u8)offer->monitorid / 32; @@ -535,11 +498,10 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) rescind = (struct vmbus_channel_rescind_offer *)hdr; channel = relid2channel(rescind->child_relid); - if (channel == NULL) { - DPRINT_DBG(VMBUS, "channel not found for relId %d", - rescind->child_relid); + + if (channel == NULL) + /* Just return here, no channel found */ return; - } /* work is initialized for vmbus_process_rescind_offer() from * vmbus_process_offer() where the channel got created */ @@ -573,7 +535,6 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) unsigned long flags; result = (struct vmbus_channel_open_result *)hdr; - DPRINT_DBG(VMBUS, "vmbus open result - %d", result->status); /* * Find the open msg, copy the result and signal/unblock the wait event @@ -618,8 +579,6 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) unsigned long flags; gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr; - DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d", - gpadlcreated->creation_status); /* * Find the establish msg, copy the result and signal/unblock the wait @@ -770,8 +729,6 @@ void vmbus_onmessage(void *context) hdr = (struct vmbus_channel_message_header *)msg->u.payload; size = msg->header.payload_size; - DPRINT_DBG(VMBUS, "message type %d size %d", hdr->msgtype, size); - if (hdr->msgtype >= CHANNELMSG_COUNT) { DPRINT_ERR(VMBUS, "Received invalid channel message type %d size %d", diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 44b203b95a22..ed2a7a840468 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -121,11 +121,6 @@ int vmbus_connect(void) spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, " - "monitor1 pfn %llx,, monitor2 pfn %llx", - msg->interrupt_page, msg->monitor_page1, msg->monitor_page2); - - DPRINT_DBG(VMBUS, "Sending channel initiate msg..."); ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_initiate_contact)); if (ret != 0) { @@ -156,9 +151,7 @@ int vmbus_connect(void) /* Check if successful */ if (msginfo->response.version_response.version_supported) { - DPRINT_INFO(VMBUS, "Vmbus connected!!"); vmbus_connection.conn_state = CONNECTED; - } else { DPRINT_ERR(VMBUS, "Vmbus connection failed!!..." "current version (%d) not supported", @@ -300,11 +293,9 @@ void vmbus_on_event(unsigned long data) (unsigned long *) &recv_int_page[dword])) { relid = (dword << 5) + bit; - DPRINT_DBG(VMBUS, "event detected for relid - %d", relid); if (relid == 0) { /* special case - vmbus channel protocol msg */ - DPRINT_DBG(VMBUS, "invalid relid - %d", relid); continue; } else { /* QueueWorkItem(VmbusProcessEvent, (void*)relid); */ diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 2d492adb95bb..d627a83439ac 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -80,7 +80,7 @@ static int query_hypervisor_info(void) op = HVCPUID_VENDOR_MAXFUNCTION; cpuid(op, &eax, &ebx, &ecx, &edx); - DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c", +/* DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c", (ebx & 0xFF), ((ebx >> 8) & 0xFF), ((ebx >> 16) & 0xFF), @@ -93,9 +93,9 @@ static int query_hypervisor_info(void) ((edx >> 8) & 0xFF), ((edx >> 16) & 0xFF), ((edx >> 24) & 0xFF)); - +*/ max_leaf = eax; - eax = 0; +/* eax = 0; ebx = 0; ecx = 0; edx = 0; @@ -107,6 +107,7 @@ static int query_hypervisor_info(void) ((eax >> 8) & 0xFF), ((eax >> 16) & 0xFF), ((eax >> 24) & 0xFF)); +*/ if (max_leaf >= HVCPUID_VERSION) { eax = 0; @@ -137,18 +138,11 @@ static u64 do_hypercall(u64 control, void *input, void *output) u64 output_address = (output) ? virt_to_phys(output) : 0; volatile void *hypercall_page = hv_context.hypercall_page; - DPRINT_DBG(VMBUS, "Hypercall ", - control, input_address, input, - output_address, output, hypercall_page); - __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); __asm__ __volatile__("call *%3" : "=a" (hv_status) : "c" (control), "d" (input_address), "m" (hypercall_page)); - DPRINT_DBG(VMBUS, "Hypercall ", hv_status); - return hv_status; #else @@ -165,18 +159,12 @@ static u64 do_hypercall(u64 control, void *input, void *output) u32 output_address_lo = output_address & 0xFFFFFFFF; volatile void *hypercall_page = hv_context.hypercall_page; - DPRINT_DBG(VMBUS, "Hypercall ", - control, input, output); - __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), "=a"(hv_status_lo) : "d" (control_hi), "a" (control_lo), "b" (input_address_hi), "c" (input_address_lo), "D"(output_address_hi), "S"(output_address_lo), "m" (hypercall_page)); - DPRINT_DBG(VMBUS, "Hypercall ", - hv_status_lo | ((u64)hv_status_hi << 32)); - return hv_status_lo | ((u64)hv_status_hi << 32); #endif /* !x86_64 */ } @@ -197,13 +185,8 @@ int hv_init(void) memset(hv_context.synic_message_page, 0, sizeof(void *) * MAX_NUM_CPUS); - if (!query_hypervisor_presence()) { - DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!"); + if (!query_hypervisor_presence()) goto Cleanup; - } - - DPRINT_INFO(VMBUS, - "Windows hypervisor detected! Retrieving more info..."); max_leaf = query_hypervisor_info(); /* HvQueryHypervisorFeatures(maxLeaf); */ @@ -213,11 +196,8 @@ int hv_init(void) */ rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid); - if (hv_context.guestid != 0) { - DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", - hv_context.guestid); + if (hv_context.guestid != 0) goto Cleanup; - } /* Write our OS info */ wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); @@ -232,11 +212,8 @@ int hv_init(void) */ virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); - if (!virtaddr) { - DPRINT_ERR(VMBUS, - "unable to allocate hypercall page!!"); + if (!virtaddr) goto Cleanup; - } hypercall_msr.enable = 1; @@ -247,17 +224,11 @@ int hv_init(void) hypercall_msr.as_uint64 = 0; rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - if (!hypercall_msr.enable) { - DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); + if (!hypercall_msr.enable) goto Cleanup; - } hv_context.hypercall_page = virtaddr; - DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", - hv_context.hypercall_page, - (u64)hypercall_msr.guest_physical_address << PAGE_SHIFT); - /* Setup the global signal event param for the signal event hypercall */ hv_context.signal_event_buffer = kmalloc(sizeof(struct hv_input_signal_event_buffer), @@ -394,8 +365,6 @@ void hv_synic_init(void *irqarg) /* Check the version */ rdmsrl(HV_X64_MSR_SVERSION, version); - DPRINT_INFO(VMBUS, "SynIC version: %llx", version); - hv_context.synic_message_page[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); @@ -420,8 +389,6 @@ void hv_synic_init(void *irqarg) simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu]) >> PAGE_SHIFT; - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.as_uint64); - wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64); /* Setup the Synic's event page */ @@ -430,8 +397,6 @@ void hv_synic_init(void *irqarg) siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu]) >> PAGE_SHIFT; - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.as_uint64); - wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); /* Setup the interception SINT. */ @@ -446,9 +411,6 @@ void hv_synic_init(void *irqarg) shared_sint.masked = false; shared_sint.auto_eoi = true; - DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", - shared_sint.as_uint64); - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); /* Enable the global synic bit */ diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 66688fb69741..9bd5218d8de6 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -372,20 +372,12 @@ int ringbuffer_write(struct hv_ring_buffer_info *outring_info, &bytes_avail_toread, &bytes_avail_towrite); - DPRINT_DBG(VMBUS, "Writing %u bytes...", totalbytes_towrite); - /* Dumpring_info(Outring_info, "BEFORE "); */ /* If there is only room for the packet, assume it is full. */ /* Otherwise, the next time around, we think the ring buffer */ /* is empty since the read index == write index */ if (bytes_avail_towrite <= totalbytes_towrite) { - DPRINT_DBG(VMBUS, - "No more space left on outbound ring buffer " - "(needed %u, avail %u)", - totalbytes_towrite, - bytes_avail_towrite); - spin_unlock_irqrestore(&outring_info->ring_lock, flags); return -1; } @@ -499,18 +491,10 @@ int ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, &bytes_avail_toread, &bytes_avail_towrite); - DPRINT_DBG(VMBUS, "Reading %u bytes...", buflen); - /* Dumpring_info(Inring_info, "BEFORE "); */ /* Make sure there is something to read */ if (bytes_avail_toread < buflen) { - DPRINT_DBG(VMBUS, - "got callback but not enough to read " - "!!", - bytes_avail_toread, - buflen); - spin_unlock_irqrestore(&inring_info->ring_lock, flags); return -1; @@ -568,8 +552,6 @@ copyto_ringbuffer( /* wrap-around detected! */ if (srclen > ring_buffer_size - start_write_offset) { - DPRINT_DBG(VMBUS, "wrap-around detected!"); - frag_len = ring_buffer_size - start_write_offset; memcpy(ring_buffer + start_write_offset, src, frag_len); memcpy(ring_buffer, src + frag_len, srclen - frag_len); @@ -607,8 +589,6 @@ copyfrom_ringbuffer( /* wrap-around detected at the src */ if (destlen > ring_buffer_size - start_read_offset) { - DPRINT_DBG(VMBUS, "src wrap-around detected!"); - frag_len = ring_buffer_size - start_read_offset; memcpy(dest, ring_buffer + start_read_offset, frag_len); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 3263fc85f645..b320f71b1b1e 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -245,21 +245,6 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) struct hv_device *dev = device_to_hv_device(device); int ret; - DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - dev->dev_type.data[3], dev->dev_type.data[2], - dev->dev_type.data[1], dev->dev_type.data[0], - dev->dev_type.data[5], dev->dev_type.data[4], - dev->dev_type.data[7], dev->dev_type.data[6], - dev->dev_type.data[8], dev->dev_type.data[9], - dev->dev_type.data[10], - dev->dev_type.data[11], - dev->dev_type.data[12], - dev->dev_type.data[13], - dev->dev_type.data[14], - dev->dev_type.data[15]); - ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", @@ -323,10 +308,6 @@ static int vmbus_match(struct device *device, struct device_driver *driver) sizeof(struct hv_guid)) == 0) { device_ctx->drv = drv->priv; - DPRINT_INFO(VMBUS_DRV, - "device object (%p) set to driver object (%p)", - &device_ctx, - device_ctx->drv); match = 1; } @@ -539,22 +520,16 @@ static int vmbus_on_isr(void) msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; /* Check if there are actual msgs to be process */ - if (msg->header.message_type != HVMSG_NONE) { - DPRINT_DBG(VMBUS, "received msg type %d size %d", - msg->header.message_type, - msg->header.payload_size); + if (msg->header.message_type != HVMSG_NONE) ret |= 0x1; - } /* TODO: Check if there are events to be process */ page_addr = hv_context.synic_event_page[cpu]; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; /* Since we are a child, we only need to check bit 0 */ - if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { - DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]); + if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) ret |= 0x2; - } return ret; } @@ -594,18 +569,6 @@ static int vmbus_bus_init(struct pci_dev *pdev) int ret; unsigned int vector; - DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", - HV_DRV_VERSION); - DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", - VMBUS_REVISION_NUMBER); - DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", - VMBUS_MESSAGE_SINT); - DPRINT_DBG(VMBUS, "sizeof(vmbus_channel_packet_page_buffer)=%zd, " - "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", - sizeof(struct vmbus_channel_packet_page_buffer), - sizeof(struct vmbus_channel_packet_multipage_buffer)); - - /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); if (ret != 0) { @@ -646,8 +609,6 @@ static int vmbus_bus_init(struct pci_dev *pdev) } vector = IRQ0_VECTOR + pdev->irq; - DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", pdev->irq, - vector); /* * Notify the hypervisor of our irq and @@ -761,25 +722,6 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, return NULL; } - DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - " - "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}," - "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - &child_device_obj->device, - type->data[3], type->data[2], type->data[1], type->data[0], - type->data[5], type->data[4], type->data[7], type->data[6], - type->data[8], type->data[9], type->data[10], type->data[11], - type->data[12], type->data[13], type->data[14], type->data[15], - instance->data[3], instance->data[2], - instance->data[1], instance->data[0], - instance->data[5], instance->data[4], - instance->data[7], instance->data[6], - instance->data[8], instance->data[9], - instance->data[10], instance->data[11], - instance->data[12], instance->data[13], - instance->data[14], instance->data[15]); - child_device_obj->channel = channel; memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid)); memcpy(&child_device_obj->dev_instance, instance, @@ -798,9 +740,6 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) static atomic_t device_num = ATOMIC_INIT(0); - DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", - child_device_obj); - /* Set the device name. Otherwise, device_register() will fail. */ dev_set_name(&child_device_obj->device, "vmbus_0_%d", atomic_inc_return(&device_num)); @@ -835,10 +774,6 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) */ void vmbus_child_device_unregister(struct hv_device *device_obj) { - - DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)", - &device_obj->device); - /* * Kick off the process of unregistering the device. * This will call vmbus_remove() and eventually vmbus_device_release() -- GitLab From b8a3d52b2f7db637edcb62f9a332e1b35eefad13 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:45 -0700 Subject: [PATCH 0386/5560] staging: hv: Remove all unneeded DPRINT from hv_netvsc Remove all un-needed DPRINT calls from hv_netvsc. This patch deals with hv_netvsc only. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 100 +----------------------------- drivers/staging/hv/netvsc_drv.c | 10 --- drivers/staging/hv/rndis_filter.c | 13 ---- 3 files changed, 3 insertions(+), 120 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 20b159775e88..227d7d3006c0 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -178,13 +178,6 @@ int netvsc_initialize(struct hv_driver *drv) { struct netvsc_driver *driver = (struct netvsc_driver *)drv; - DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, " - "sizeof(struct nvsp_message)=%zd, " - "sizeof(struct vmtransfer_page_packet_header)=%zd", - sizeof(struct hv_netvsc_packet), - sizeof(struct nvsp_message), - sizeof(struct vmtransfer_page_packet_header)); - drv->name = driver_name; memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid)); @@ -223,8 +216,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) goto cleanup; } - DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); - /* * Establish the gpadl handle for this buffer on this * channel. Note: This call uses the vmbus connection rather @@ -241,8 +232,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) /* Notify the NetVsp of the gpadl handle */ - DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); - init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); @@ -301,14 +290,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) net_device->recv_section_cnt * sizeof(struct nvsp_1_receive_buffer_section)); - DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, " - "endoffset %d, suballoc size %d, num suballocs %d)", - net_device->recv_section_cnt, - net_device->recv_section[0].offset, - net_device->recv_section[0].end_offset, - net_device->recv_section[0].sub_alloc_size, - net_device->recv_section[0].num_sub_allocs); - /* * For 1st release, there should only be 1 section that represents the * entire receive buffer @@ -356,8 +337,6 @@ static int netvsc_init_send_buf(struct hv_device *device) goto cleanup; } - DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); - /* * Establish the gpadl handle for this buffer on this * channel. Note: This call uses the vmbus connection rather @@ -372,8 +351,6 @@ static int netvsc_init_send_buf(struct hv_device *device) } /* Notify the NetVsp of the gpadl handle */ - DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); - init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); @@ -438,9 +415,6 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) * to send a revoke msg here */ if (net_device->recv_section_cnt) { - DPRINT_INFO(NETVSC, - "Sending NvspMessage1TypeRevokeReceiveBuffer..."); - /* Send the revoke receive buffer */ revoke_packet = &net_device->revoke_packet; memset(revoke_packet, 0, sizeof(struct nvsp_message)); @@ -468,8 +442,6 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) /* Teardown the gpadl on the vsp end */ if (net_device->recv_buf_gpadl_handle) { - DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL..."); - ret = vmbus_teardown_gpadl(net_device->dev->channel, net_device->recv_buf_gpadl_handle); @@ -483,8 +455,6 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) } if (net_device->recv_buf) { - DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); - /* Free up the receive buffer */ free_pages((unsigned long)net_device->recv_buf, get_order(net_device->recv_buf_size)); @@ -512,9 +482,6 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) * to send a revoke msg here */ if (net_device->send_section_size) { - DPRINT_INFO(NETVSC, - "Sending NvspMessage1TypeRevokeSendBuffer..."); - /* Send the revoke send buffer */ revoke_packet = &net_device->revoke_packet; memset(revoke_packet, 0, sizeof(struct nvsp_message)); @@ -542,7 +509,6 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) /* Teardown the gpadl on the vsp end */ if (net_device->send_buf_gpadl_handle) { - DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL..."); ret = vmbus_teardown_gpadl(net_device->dev->channel, net_device->send_buf_gpadl_handle); @@ -559,8 +525,6 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) } if (net_device->send_buf) { - DPRINT_INFO(NETVSC, "Freeing up send buffer..."); - /* Free up the receive buffer */ free_pages((unsigned long)net_device->send_buf, get_order(net_device->send_buf_size)); @@ -594,8 +558,6 @@ static int netvsc_connect_vsp(struct hv_device *device) init_packet->msg.init_msg.init.max_protocol_ver = NVSP_MAX_PROTOCOL_VERSION; - DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); - /* Send the init request */ net_device->wait_condition = 0; ret = vmbus_sendpacket(device->channel, init_packet, @@ -604,10 +566,8 @@ static int netvsc_connect_vsp(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); + if (ret != 0) goto cleanup; - } wait_event_timeout(net_device->channel_init_wait, net_device->wait_condition, @@ -617,31 +577,17 @@ static int netvsc_connect_vsp(struct hv_device *device) goto cleanup; } - DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", - init_packet->msg.init_msg.init_complete.status, - init_packet->msg.init_msg. - init_complete.max_mdl_chain_len); - if (init_packet->msg.init_msg.init_complete.status != NVSP_STAT_SUCCESS) { - DPRINT_ERR(NETVSC, - "unable to initialize with netvsp (status 0x%x)", - init_packet->msg.init_msg.init_complete.status); ret = -1; goto cleanup; } if (init_packet->msg.init_msg.init_complete. negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) { - DPRINT_ERR(NETVSC, "unable to initialize with netvsp " - "(version expected 1 got %d)", - init_packet->msg.init_msg. - init_complete.negotiated_protocol_ver); ret = -1; goto cleanup; } - DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); - /* Send the ndis version */ memset(init_packet, 0, sizeof(struct nvsp_message)); @@ -661,8 +607,6 @@ static int netvsc_connect_vsp(struct hv_device *device) (unsigned long)init_packet, VM_PKT_DATA_INBAND, 0); if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to send NvspMessage1TypeSendNdisVersion"); ret = -1; goto cleanup; } @@ -702,8 +646,6 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) goto cleanup; } - DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device); - /* Initialize the NetVSC channel extension */ net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; spin_lock_init(&net_device->recv_pkt_list_lock); @@ -716,12 +658,9 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) packet = kzalloc(sizeof(struct hv_netvsc_packet) + (NETVSC_RECEIVE_SG_COUNT * sizeof(struct hv_page_buffer)), GFP_KERNEL); - if (!packet) { - DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts " - "for receive pool (wanted %d got %d)", - NETVSC_RECEIVE_PACKETLIST_COUNT, i); + if (!packet) break; - } + list_add_tail(&packet->list_ent, &net_device->recv_pkt_list); } @@ -749,9 +688,6 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) goto close; } - DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***", - ret); - return ret; close: @@ -785,9 +721,6 @@ static int netvsc_device_remove(struct hv_device *device) struct netvsc_device *net_device; struct hv_netvsc_packet *netvsc_packet, *pos; - DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", - device->ext); - /* Stop outbound traffic ie sends and receives completions */ net_device = release_outbound_net_device(device); if (!net_device) { @@ -802,13 +735,8 @@ static int netvsc_device_remove(struct hv_device *device) udelay(100); } - DPRINT_INFO(NETVSC, "Disconnecting from netvsp..."); - NetVscDisconnectFromVsp(net_device); - DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", - device->ext); - /* Stop inbound traffic ie receives and sends completions */ net_device = release_inbound_net_device(device); @@ -853,9 +781,6 @@ static void netvsc_send_completion(struct hv_device *device, nvsp_packet = (struct nvsp_message *)((unsigned long)packet + (packet->offset8 << 3)); - DPRINT_DBG(NETVSC, "send completion packet - type %d", - nvsp_packet->hdr.msg_type); - if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) || (nvsp_packet->hdr.msg_type == NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) || @@ -985,9 +910,6 @@ static void netvsc_receive(struct hv_device *device, return; } - DPRINT_DBG(NETVSC, "NVSP packet received - type %d", - nvsp_packet->hdr.msg_type); - vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet; if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) { @@ -998,9 +920,6 @@ static void netvsc_receive(struct hv_device *device, return; } - DPRINT_DBG(NETVSC, "xfer page - range count %d", - vmxferpage_packet->range_cnt); - /* * Grab free packets (range count + 1) to represent this xfer * page packet. +1 to represent the xfer page packet itself. @@ -1117,13 +1036,6 @@ static void netvsc_receive(struct hv_device *device, break; } } - DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " - "(pfn %llx, offset %u, len %u)", i, - vmxferpage_packet->ranges[i].byte_offset, - vmxferpage_packet->ranges[i].byte_count, - netvsc_packet->page_buf[0].pfn, - netvsc_packet->page_buf[0].offset, - netvsc_packet->page_buf[0].len); /* Pass it to the upper layer */ ((struct netvsc_driver *)device->drv)-> @@ -1143,9 +1055,6 @@ static void netvsc_send_recv_completion(struct hv_device *device, int retries = 0; int ret; - DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx", - transaction_id); - recvcompMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE; @@ -1261,9 +1170,6 @@ static void netvsc_channel_cb(void *context) &bytes_recvd, &request_id); if (ret == 0) { if (bytes_recvd > 0) { - DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx", - bytes_recvd, request_id); - desc = (struct vmpacket_descriptor *)buffer; switch (desc->type) { case VM_PKT_COMP: diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 2d40f5f86b24..1772a194ef48 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -136,9 +136,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) int ret; unsigned int i, num_pages; - DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d", - skb->len, skb->data_len); - /* Add 1 for skb->data and additional one for RNDIS */ num_pages = skb_shinfo(skb)->nr_frags + 1 + 1; if (num_pages > net_device_ctx->avail) @@ -196,10 +193,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) net->stats.tx_bytes += skb->len; net->stats.tx_packets++; - DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu", - net->stats.tx_packets, - net->stats.tx_bytes); - net_device_ctx->avail -= num_pages; if (net_device_ctx->avail < PACKET_PAGES_LOWATER) netif_stop_queue(net); @@ -297,9 +290,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj, */ netif_rx(skb); - DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu", - net->stats.rx_packets, net->stats.rx_bytes); - return 0; } diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index e7189cd324ca..d1b13dc3d4d2 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -283,14 +283,6 @@ static void rndis_filter_receive_response(struct rndis_device *dev, */ if (request->request_msg.msg.init_req.req_id == resp->msg.init_complete.req_id) { - DPRINT_DBG(NETVSC, "found rndis request for " - "this response (id 0x%x req type 0x%x res " - "type 0x%x)", - request->request_msg.msg. - init_req.req_id, - request->request_msg.ndis_msg_type, - resp->ndis_msg_type); - found = true; break; } @@ -605,9 +597,6 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, int rndis_filter_init(struct netvsc_driver *drv) { - DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", - sizeof(struct rndis_filter_packet)); - drv->req_ext_size = sizeof(struct rndis_filter_packet); /* Driver->Context = rndisDriver; */ @@ -765,8 +754,6 @@ static int rndis_filte_device_add(struct hv_device *dev, if (!rndisDevice) return -1; - DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice); - /* * Let the inner driver handle this first to create the netvsc channel * NOTE! Once the channel is created, we may get a receive callback -- GitLab From 8de61e31466a87cf77231db52ff9c94ddb1f758b Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:46 -0700 Subject: [PATCH 0387/5560] staging: hv: Remove all unneeded DPRINT from hv_utils Remove all un-needed DPRINT calls from hv_utils. This patch deals with hv_utils only. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_kvp.c | 3 --- drivers/staging/hv/hv_util.c | 12 ------------ 2 files changed, 15 deletions(-) diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c index faf692e4126e..77758204586a 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/staging/hv/hv_kvp.c @@ -259,9 +259,6 @@ void hv_kvp_onchannelcallback(void *context) vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { - DPRINT_DBG(VMBUS, "KVP packet: len=%d, requestid=%lld", - recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&recv_buffer[ sizeof(struct vmbuspipe_hdr)]; diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index 4792f2c402b2..3e74f79720b1 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -59,9 +59,6 @@ static void shutdown_onchannelcallback(void *context) PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { - DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", - recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[ sizeof(struct vmbuspipe_hdr)]; @@ -159,9 +156,6 @@ static void timesync_onchannelcallback(void *context) PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { - DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", - recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ sizeof(struct vmbuspipe_hdr)]; @@ -200,9 +194,6 @@ static void heartbeat_onchannelcallback(void *context) PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { - DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", - recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ sizeof(struct vmbuspipe_hdr)]; @@ -214,9 +205,6 @@ static void heartbeat_onchannelcallback(void *context) sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; - DPRINT_DBG(VMBUS, "heartbeat seq = %lld", - heartbeat_msg->seq_num); - heartbeat_msg->seq_num += 1; } -- GitLab From 0a46618d58c90f93e8b8e9a18062d1691b70297e Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:47 -0700 Subject: [PATCH 0388/5560] staging: hv: Replace DPRINT with natives in hv_vmbus Replace all remaining DPRINT calls (excluding the ringbuffer debug which is going to be done in a next set of patches) with their native pr_ calls. And also changed some of the printouts to be more useful. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 9 ++++--- drivers/staging/hv/channel_mgmt.c | 25 +++++++++--------- drivers/staging/hv/connection.c | 12 +++++---- drivers/staging/hv/hv.c | 10 +++---- drivers/staging/hv/ring_buffer.c | 1 + drivers/staging/hv/vmbus_drv.c | 43 +++++++++++++------------------ 6 files changed, 49 insertions(+), 51 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index c90dbaf0c473..580ce6955ea1 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -18,6 +18,8 @@ * Haiyang Zhang * Hank Janssen */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -898,7 +900,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, if (userlen > bufferlen) { spin_unlock_irqrestore(&channel->inbound_lock, flags); - DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d", + pr_err("Buffer too small - got %d needs %d\n", bufferlen, userlen); return -1; } @@ -950,8 +952,9 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, if (packetlen > bufferlen) { spin_unlock_irqrestore(&channel->inbound_lock, flags); - DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but " - "got space for only %d bytes", packetlen, bufferlen); + pr_err("Buffer too small - needed %d bytes but " + "got space for only %d bytes\n", + packetlen, bufferlen); return -2; } diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index e82a4bb41d17..d0840706b868 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -18,6 +18,8 @@ * Haiyang Zhang * Hank Janssen */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -403,8 +405,7 @@ static void vmbus_process_offer(struct work_struct *work) */ ret = vmbus_child_device_register(newchannel->device_obj); if (ret != 0) { - DPRINT_ERR(VMBUS, - "unable to add child device object (relid %d)", + pr_err("unable to add child device object (relid %d)\n", newchannel->offermsg.child_relid); spin_lock_irqsave(&vmbus_connection.channel_lock, flags); @@ -430,8 +431,9 @@ static void vmbus_process_offer(struct work_struct *work) hv_cb_utils[cnt].callback, newchannel) == 0) { hv_cb_utils[cnt].channel = newchannel; - DPRINT_INFO(VMBUS, "%s", - hv_cb_utils[cnt].log_msg); + + pr_info("%s\n", hv_cb_utils[cnt].log_msg); + count_hv_channel(); } } @@ -472,7 +474,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) /* Allocate the channel object and save this offer. */ newchannel = alloc_channel(); if (!newchannel) { - DPRINT_ERR(VMBUS, "unable to allocate channel object"); + pr_err("Unable to allocate channel object\n"); return; } @@ -730,8 +732,7 @@ void vmbus_onmessage(void *context) size = msg->header.payload_size; if (hdr->msgtype >= CHANNELMSG_COUNT) { - DPRINT_ERR(VMBUS, - "Received invalid channel message type %d size %d", + pr_err("Received invalid channel message type %d size %d\n", hdr->msgtype, size); print_hex_dump_bytes("", DUMP_PREFIX_NONE, (unsigned char *)msg->u.payload, size); @@ -741,8 +742,7 @@ void vmbus_onmessage(void *context) if (gChannelMessageTable[hdr->msgtype].messageHandler) gChannelMessageTable[hdr->msgtype].messageHandler(hdr); else - DPRINT_ERR(VMBUS, "Unhandled channel message type %d", - hdr->msgtype); + pr_err("Unhandled channel message type %d\n", hdr->msgtype); } /* @@ -770,7 +770,7 @@ int vmbus_request_offers(void) ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header)); if (ret != 0) { - DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); + pr_err("Unable to request offers - %d\n", ret); goto cleanup; } @@ -810,9 +810,8 @@ void vmbus_release_unattached_channels(void) if (!channel->device_obj->drv) { list_del(&channel->listentry); - DPRINT_INFO(VMBUS, - "Releasing unattached device object %p", - channel->device_obj); + + pr_err("Releasing unattached device object\n"); vmbus_child_device_unregister(channel->device_obj); free_channel(channel); diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index ed2a7a840468..494e166e102d 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -20,6 +20,8 @@ * Hank Janssen * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -153,9 +155,9 @@ int vmbus_connect(void) if (msginfo->response.version_response.version_supported) { vmbus_connection.conn_state = CONNECTED; } else { - DPRINT_ERR(VMBUS, "Vmbus connection failed!!..." - "current version (%d) not supported", - VMBUS_REVISION_NUMBER); + pr_err("Unable to connect, " + "Version %d not supported by Hyper-V\n", + VMBUS_REVISION_NUMBER); ret = -1; goto Cleanup; } @@ -216,7 +218,7 @@ int vmbus_disconnect(void) vmbus_connection.conn_state = DISCONNECTED; - DPRINT_INFO(VMBUS, "Vmbus disconnected!!"); + pr_info("hv_vmbus disconnected\n"); Cleanup: kfree(msg); @@ -269,7 +271,7 @@ static void process_chn_event(void *context) * (void*)channel); */ } else { - DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relid); + pr_err("channel not found for relid - %d\n", relid); } } diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index d627a83439ac..8898d7f6cbbf 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -19,6 +19,8 @@ * Hank Janssen * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -116,7 +118,7 @@ static int query_hypervisor_info(void) edx = 0; op = HVCPUID_VERSION; cpuid(op, &eax, &ebx, &ecx, &edx); - DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\ + pr_info("Hyper-V Host OS Build:%d-%d.%d-%d-%d.%d\n", eax, ebx >> 16, ebx & 0xFFFF, @@ -369,8 +371,7 @@ void hv_synic_init(void *irqarg) (void *)get_zeroed_page(GFP_ATOMIC); if (hv_context.synic_message_page[cpu] == NULL) { - DPRINT_ERR(VMBUS, - "unable to allocate SYNIC message page!!"); + pr_err("Unable to allocate SYNIC message page\n"); goto Cleanup; } @@ -378,8 +379,7 @@ void hv_synic_init(void *irqarg) (void *)get_zeroed_page(GFP_ATOMIC); if (hv_context.synic_event_page[cpu] == NULL) { - DPRINT_ERR(VMBUS, - "unable to allocate SYNIC event page!!"); + pr_err("Unable to allocate SYNIC event page\n"); goto Cleanup; } diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 9bd5218d8de6..66e1b3f16d9a 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -20,6 +20,7 @@ * Hank Janssen * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index b320f71b1b1e..501ab369abbd 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -20,6 +20,8 @@ * * 3/9/2011: K. Y. Srinivasan - Significant restructuring and cleanup */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -350,18 +352,16 @@ static int vmbus_probe(struct device *child_device) ret = dev->probe_error = drv->driver.probe(child_device); if (ret != 0) { - DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " - "(%p) on driver %s (%d)...", - dev_name(child_device), child_device, - child_device->driver->name, ret); + pr_err("probe failed for device %s (%d)\n", + dev_name(child_device), ret); INIT_WORK(&dev->probe_failed_work_item, vmbus_probe_failed_cb); schedule_work(&dev->probe_failed_work_item); } } else { - DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", - child_device->driver->name); + pr_err("probe not set for driver %s\n", + dev_name(child_device)); ret = -1; } return ret; @@ -386,9 +386,8 @@ static int vmbus_remove(struct device *child_device) if (drv->driver.remove) { ret = drv->driver.remove(child_device); } else { - DPRINT_ERR(VMBUS_DRV, - "remove() method not set for driver - %s", - child_device->driver->name); + pr_err("remove not set for driver %s\n", + dev_name(child_device)); ret = -1; } } @@ -572,12 +571,10 @@ static int vmbus_bus_init(struct pci_dev *pdev) /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); if (ret != 0) { - DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", - ret); + pr_err("Unable to initialize the hypervisor - 0x%x\n", ret); goto cleanup; } - hv_bus.bus.name = driver_name; /* Initialize the bus context */ @@ -599,7 +596,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) driver_name, pdev); if (ret != 0) { - DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", + pr_err("Unable to request IRQ %d\n", pdev->irq); bus_unregister(&hv_bus.bus); @@ -669,8 +666,7 @@ int vmbus_child_driver_register(struct device_driver *drv) { int ret; - DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", - drv, drv->name); + pr_info("child driver registering - name %s\n", drv->name); /* The child driver on this vmbus */ drv->bus = &hv_bus.bus; @@ -695,8 +691,7 @@ EXPORT_SYMBOL(vmbus_child_driver_register); */ void vmbus_child_driver_unregister(struct device_driver *drv) { - DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s", - drv, drv->name); + pr_info("child driver unregistering - name %s\n", drv->name); driver_unregister(drv); @@ -717,8 +712,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, /* Allocate the new child device */ child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL); if (!child_device_obj) { - DPRINT_ERR(VMBUS_DRV, - "unable to allocate device_context for child device"); + pr_err("Unable to allocate device object for child device\n"); return NULL; } @@ -759,11 +753,10 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) ret = child_device_obj->probe_error; if (ret) - DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)", - &child_device_obj->device); + pr_err("Unable to register child device\n"); else - DPRINT_INFO(VMBUS_DRV, "child device (%p) registered", - &child_device_obj->device); + pr_info("child device %s registered\n", + dev_name(&child_device_obj->device)); return ret; } @@ -780,8 +773,8 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) */ device_unregister(&device_obj->device); - DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered", - &device_obj->device); + pr_info("child device %s unregistered\n", + dev_name(&device_obj->device)); } -- GitLab From eb335bc42781ddc19da98a3c74add1013ba08da2 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:48 -0700 Subject: [PATCH 0389/5560] staging: hv: replace DPRINT with native primitives in hv_netvsc Replace all remaining DPRINT calls with their native dev_ and netvsc_ calls. And also change some of the verbiage to be more useful. rndis_filter has a few remaining DPRINT calls in it that will be removed in a future patch because the debug will be implemented differently. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 115 +++++++++++++++--------------- drivers/staging/hv/netvsc_drv.c | 36 +++++----- drivers/staging/hv/rndis_filter.c | 51 ++++++------- 3 files changed, 103 insertions(+), 99 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 227d7d3006c0..e8c15d2f373e 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -18,6 +18,8 @@ * Haiyang Zhang * Hank Janssen */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -200,7 +202,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) net_device = get_outbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "unable to get net device..." + dev_err(&device->device, "unable to get net device..." "device being destroyed?"); return -1; } @@ -209,9 +211,8 @@ static int netvsc_init_recv_buf(struct hv_device *device) (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, get_order(net_device->recv_buf_size)); if (!net_device->recv_buf) { - DPRINT_ERR(NETVSC, - "unable to allocate receive buffer of size %d", - net_device->recv_buf_size); + dev_err(&device->device, "unable to allocate receive " + "buffer of size %d", net_device->recv_buf_size); ret = -1; goto cleanup; } @@ -225,8 +226,8 @@ static int netvsc_init_recv_buf(struct hv_device *device) net_device->recv_buf_size, &net_device->recv_buf_gpadl_handle); if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to establish receive buffer's gpadl"); + dev_err(&device->device, + "unable to establish receive buffer's gpadl"); goto cleanup; } @@ -250,8 +251,8 @@ static int netvsc_init_recv_buf(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to send receive buffer's gpadl to netvsp"); + dev_err(&device->device, + "unable to send receive buffer's gpadl to netvsp"); goto cleanup; } @@ -264,7 +265,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) /* Check the response */ if (init_packet->msg.v1_msg. send_recv_buf_complete.status != NVSP_STAT_SUCCESS) { - DPRINT_ERR(NETVSC, "Unable to complete receive buffer " + dev_err(&device->device, "Unable to complete receive buffer " "initialzation with NetVsp - status %d", init_packet->msg.v1_msg. send_recv_buf_complete.status); @@ -318,7 +319,7 @@ static int netvsc_init_send_buf(struct hv_device *device) net_device = get_outbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "unable to get net device..." + dev_err(&device->device, "unable to get net device..." "device being destroyed?"); return -1; } @@ -331,8 +332,8 @@ static int netvsc_init_send_buf(struct hv_device *device) (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, get_order(net_device->send_buf_size)); if (!net_device->send_buf) { - DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", - net_device->send_buf_size); + dev_err(&device->device, "unable to allocate send " + "buffer of size %d", net_device->send_buf_size); ret = -1; goto cleanup; } @@ -346,7 +347,7 @@ static int netvsc_init_send_buf(struct hv_device *device) net_device->send_buf_size, &net_device->send_buf_gpadl_handle); if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); + dev_err(&device->device, "unable to establish send buffer's gpadl"); goto cleanup; } @@ -369,7 +370,7 @@ static int netvsc_init_send_buf(struct hv_device *device) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { - DPRINT_ERR(NETVSC, + dev_err(&device->device, "unable to send receive buffer's gpadl to netvsp"); goto cleanup; } @@ -382,7 +383,7 @@ static int netvsc_init_send_buf(struct hv_device *device) /* Check the response */ if (init_packet->msg.v1_msg. send_send_buf_complete.status != NVSP_STAT_SUCCESS) { - DPRINT_ERR(NETVSC, "Unable to complete send buffer " + dev_err(&device->device, "Unable to complete send buffer " "initialzation with NetVsp - status %d", init_packet->msg.v1_msg. send_send_buf_complete.status); @@ -434,8 +435,8 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) * have a leak rather than continue and a bugchk */ if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to send revoke receive " - "buffer to netvsp"); + dev_err(&net_device->dev->device, "unable to send " + "revoke receive buffer to netvsp"); return -1; } } @@ -447,7 +448,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */ if (ret != 0) { - DPRINT_ERR(NETVSC, + dev_err(&net_device->dev->device, "unable to teardown receive buffer's gpadl"); return -1; } @@ -501,8 +502,8 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) * rather than continue and a bugchk */ if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to send revoke send buffer " - "to netvsp"); + dev_err(&net_device->dev->device, "unable to send " + "revoke send buffer to netvsp"); return -1; } } @@ -517,8 +518,8 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) * rather than continue and a bugchk */ if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to teardown send buffer's " - "gpadl"); + dev_err(&net_device->dev->device, + "unable to teardown send buffer's gpadl"); return -1; } net_device->send_buf_gpadl_handle = 0; @@ -544,7 +545,7 @@ static int netvsc_connect_vsp(struct hv_device *device) net_device = get_outbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "unable to get net device..." + dev_err(&device->device, "unable to get net device..." "device being destroyed?"); return -1; } @@ -672,18 +673,19 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) netvsc_channel_cb, device); if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); + dev_err(&device->device, "unable to open channel: %d", ret); ret = -1; goto cleanup; } /* Channel is opened */ - DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***"); + pr_info("hv_netvsc channel opened successfully"); /* Connect with the NetVsp */ ret = netvsc_connect_vsp(device); if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret); + dev_err(&device->device, + "unable to connect to NetVSP - %d", ret); ret = -1; goto close; } @@ -724,14 +726,15 @@ static int netvsc_device_remove(struct hv_device *device) /* Stop outbound traffic ie sends and receives completions */ net_device = release_outbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "No net device present!!"); + dev_err(&device->device, "No net device present!!"); return -1; } /* Wait for all send completions */ while (atomic_read(&net_device->num_outstanding_sends)) { - DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", - atomic_read(&net_device->num_outstanding_sends)); + dev_err(&device->device, + "waiting for %d requests to complete...", + atomic_read(&net_device->num_outstanding_sends)); udelay(100); } @@ -741,7 +744,7 @@ static int netvsc_device_remove(struct hv_device *device) net_device = release_inbound_net_device(device); /* At this point, no one should be accessing netDevice except in here */ - DPRINT_INFO(NETVSC, "net device (%p) safe to remove", net_device); + dev_notice(&device->device, "net device safe to remove"); /* Now, we can close the channel safely */ vmbus_close(device->channel); @@ -773,7 +776,7 @@ static void netvsc_send_completion(struct hv_device *device, net_device = get_inbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "unable to get net device..." + dev_err(&device->device, "unable to get net device..." "device being destroyed?"); return; } @@ -803,7 +806,7 @@ static void netvsc_send_completion(struct hv_device *device, atomic_dec(&net_device->num_outstanding_sends); } else { - DPRINT_ERR(NETVSC, "Unknown send completion packet type - " + dev_err(&device->device, "Unknown send completion packet type- " "%d received!!", nvsp_packet->hdr.msg_type); } @@ -820,7 +823,7 @@ static int netvsc_send(struct hv_device *device, net_device = get_outbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "net device (%p) shutting down..." + dev_err(&device->device, "net device (%p) shutting down..." "ignoring outbound packets", net_device); return -2; } @@ -856,7 +859,7 @@ static int netvsc_send(struct hv_device *device, } if (ret != 0) - DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d", + dev_err(&device->device, "Unable to send packet %p ret %d", packet, ret); atomic_inc(&net_device->num_outstanding_sends); @@ -882,7 +885,7 @@ static void netvsc_receive(struct hv_device *device, net_device = get_inbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "unable to get net device..." + dev_err(&device->device, "unable to get net device..." "device being destroyed?"); return; } @@ -892,7 +895,7 @@ static void netvsc_receive(struct hv_device *device, * packet */ if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) { - DPRINT_ERR(NETVSC, "Unknown packet type received - %d", + dev_err(&device->device, "Unknown packet type received - %d", packet->type); put_net_device(device); return; @@ -904,8 +907,8 @@ static void netvsc_receive(struct hv_device *device, /* Make sure this is a valid nvsp packet */ if (nvsp_packet->hdr.msg_type != NVSP_MSG1_TYPE_SEND_RNDIS_PKT) { - DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", - nvsp_packet->hdr.msg_type); + dev_err(&device->device, "Unknown nvsp packet type received-" + " %d", nvsp_packet->hdr.msg_type); put_net_device(device); return; } @@ -913,7 +916,7 @@ static void netvsc_receive(struct hv_device *device, vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet; if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) { - DPRINT_ERR(NETVSC, "Invalid xfer page set id - " + dev_err(&device->device, "Invalid xfer page set id - " "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, vmxferpage_packet->xfer_pageset_id); put_net_device(device); @@ -940,9 +943,9 @@ static void netvsc_receive(struct hv_device *device, * some of the xfer page packet ranges... */ if (count < 2) { - DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. " - "Dropping this xfer page packet completely!", - count, vmxferpage_packet->range_cnt + 1); + dev_err(&device->device, "Got only %d netvsc pkt...needed " + "%d pkts. Dropping this xfer page packet completely!", + count, vmxferpage_packet->range_cnt + 1); /* Return it to the freelist */ spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); @@ -968,9 +971,9 @@ static void netvsc_receive(struct hv_device *device, xferpage_packet->count = count - 1; if (xferpage_packet->count != vmxferpage_packet->range_cnt) { - DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " - "page...got %d", vmxferpage_packet->range_cnt, - xferpage_packet->count); + dev_err(&device->device, "Needed %d netvsc pkts to satisy " + "this xfer page...got %d", + vmxferpage_packet->range_cnt, xferpage_packet->count); } /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ @@ -1073,20 +1076,20 @@ static void netvsc_send_recv_completion(struct hv_device *device, } else if (ret == -1) { /* no more room...wait a bit and attempt to retry 3 times */ retries++; - DPRINT_ERR(NETVSC, "unable to send receive completion pkt " - "(tid %llx)...retrying %d", transaction_id, retries); + dev_err(&device->device, "unable to send receive completion pkt" + " (tid %llx)...retrying %d", transaction_id, retries); if (retries < 4) { udelay(100); goto retry_send_cmplt; } else { - DPRINT_ERR(NETVSC, "unable to send receive completion " - "pkt (tid %llx)...give up retrying", - transaction_id); + dev_err(&device->device, "unable to send receive " + "completion pkt (tid %llx)...give up retrying", + transaction_id); } } else { - DPRINT_ERR(NETVSC, "unable to send receive completion pkt - " - "%llx", transaction_id); + dev_err(&device->device, "unable to send receive " + "completion pkt - %llx", transaction_id); } } @@ -1107,7 +1110,7 @@ static void netvsc_receive_completion(void *context) */ net_device = get_inbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "unable to get net device..." + dev_err(&device->device, "unable to get net device..." "device being destroyed?"); return; } @@ -1160,7 +1163,7 @@ static void netvsc_channel_cb(void *context) net_device = get_inbound_net_device(device); if (!net_device) { - DPRINT_ERR(NETVSC, "net device (%p) shutting down..." + dev_err(&device->device, "net device (%p) shutting down..." "ignoring inbound packets", net_device); goto out; } @@ -1181,7 +1184,7 @@ static void netvsc_channel_cb(void *context) break; default: - DPRINT_ERR(NETVSC, + dev_err(&device->device, "unhandled packet type %d, " "tid %llx len %d\n", desc->type, request_id, @@ -1210,7 +1213,7 @@ static void netvsc_channel_cb(void *context) buffer = kmalloc(bytes_recvd, GFP_ATOMIC); if (buffer == NULL) { /* Try again next time around */ - DPRINT_ERR(NETVSC, + dev_err(&device->device, "unable to allocate buffer of size " "(%d)!!", bytes_recvd); break; diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 1772a194ef48..54a203ba1de5 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -18,6 +18,8 @@ * Haiyang Zhang * Hank Janssen */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -77,14 +79,14 @@ static int netvsc_open(struct net_device *net) /* Open up the device */ ret = rndis_filter_open(device_obj); if (ret != 0) { - DPRINT_ERR(NETVSC_DRV, - "unable to open device (ret %d).", ret); + netdev_err(net, "unable to open device (ret %d).\n", + ret); return ret; } netif_start_queue(net); } else { - DPRINT_ERR(NETVSC_DRV, "unable to open device...link is down."); + netdev_err(net, "unable to open device...link is down.\n"); } return ret; @@ -100,7 +102,7 @@ static int netvsc_close(struct net_device *net) ret = rndis_filter_close(device_obj); if (ret != 0) - DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret); + netdev_err(net, "unable to close device (ret %d).\n", ret); return ret; } @@ -147,7 +149,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) net_drv_obj->req_ext_size, GFP_ATOMIC); if (!packet) { /* out of memory, silently drop packet */ - DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet"); + netdev_err(net, "unable to allocate hv_netvsc_packet\n"); dev_kfree_skb(skb); net->stats.tx_dropped++; @@ -214,8 +216,8 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, struct net_device *net = dev_get_drvdata(&device_obj->device); if (!net) { - DPRINT_ERR(NETVSC_DRV, "got link status but net device " - "not initialized yet"); + netdev_err(net, "got link status but net device " + "not initialized yet\n"); return; } @@ -243,8 +245,8 @@ static int netvsc_recv_callback(struct hv_device *device_obj, unsigned long flags; if (!net) { - DPRINT_ERR(NETVSC_DRV, "got receive callback but net device " - "not initialized yet"); + netdev_err(net, "got receive callback but net device" + " not initialized yet\n"); return 0; } @@ -350,8 +352,7 @@ static int netvsc_probe(struct device *device) free_netdev(net); dev_set_drvdata(device, NULL); - DPRINT_ERR(NETVSC_DRV, "unable to add netvsc device (ret %d)", - ret); + netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); return ret; } @@ -397,7 +398,7 @@ static int netvsc_remove(struct device *device) int ret; if (net == NULL) { - DPRINT_INFO(NETVSC, "no net device to remove"); + dev_err(device, "No net device to remove\n"); return 0; } @@ -417,7 +418,7 @@ static int netvsc_remove(struct device *device) ret = net_drv_obj->base.dev_rm(device_obj); if (ret != 0) { /* TODO: */ - DPRINT_ERR(NETVSC, "unable to remove vsc device (ret %d)", ret); + netdev_err(net, "unable to remove vsc device (ret %d)\n", ret); } free_netdev(net); @@ -446,16 +447,13 @@ static void netvsc_drv_exit(void) /* Get the device */ ret = driver_for_each_device(&drv->driver, NULL, ¤t_dev, netvsc_drv_exit_cb); - if (ret) - DPRINT_WARN(NETVSC_DRV, - "driver_for_each_device returned %d", ret); if (current_dev == NULL) break; /* Initiate removal from the top-down */ - DPRINT_INFO(NETVSC_DRV, "unregistering device (%p)...", - current_dev); + dev_err(current_dev, "unregistering device (%s)...\n", + dev_name(current_dev)); device_unregister(current_dev); } @@ -509,7 +507,7 @@ MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table); static int __init netvsc_init(void) { - DPRINT_INFO(NETVSC_DRV, "Netvsc initializing...."); + pr_info("initializing...."); if (!dmi_check_system(hv_netvsc_dmi_table)) return -ENODEV; diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index d1b13dc3d4d2..16787052a11f 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -25,7 +25,7 @@ #include #include #include - +#include #include "logging.h" #include "hv_api.h" #include "netvsc_api.h" @@ -294,10 +294,11 @@ static void rndis_filter_receive_response(struct rndis_device *dev, memcpy(&request->response_msg, resp, resp->msg_len); } else { - DPRINT_ERR(NETVSC, "rndis response buffer overflow " - "detected (size %u max %zu)", - resp->msg_len, - sizeof(struct rndis_filter_packet)); + dev_err(&dev->net_dev->dev->device, + "rndis response buffer overflow " + "detected (size %u max %zu)\n", + resp->msg_len, + sizeof(struct rndis_filter_packet)); if (resp->ndis_msg_type == REMOTE_NDIS_RESET_CMPLT) { @@ -314,10 +315,11 @@ static void rndis_filter_receive_response(struct rndis_device *dev, request->wait_condition = 1; wake_up(&request->wait_event); } else { - DPRINT_ERR(NETVSC, "no rndis request found for this response " - "(id 0x%x res type 0x%x)", - resp->msg.init_complete.req_id, - resp->ndis_msg_type); + dev_err(&dev->net_dev->dev->device, + "no rndis request found for this response " + "(id 0x%x res type 0x%x)\n", + resp->msg.init_complete.req_id, + resp->ndis_msg_type); } } @@ -380,15 +382,15 @@ static int rndis_filter_receive(struct hv_device *dev, /* Make sure the rndis device state is initialized */ if (!net_dev->extension) { - DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." - "dropping this message!"); + dev_err(&dev->device, "got rndis message but no rndis device - " + "dropping this message!\n"); return -1; } rndis_dev = (struct rndis_device *)net_dev->extension; if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) { - DPRINT_ERR(NETVSC, "got rndis message but rndis device " - "uninitialized...dropping this message!"); + dev_err(&dev->device, "got rndis message but rndis device " + "uninitialized...dropping this message!\n"); return -1; } @@ -409,8 +411,8 @@ static int rndis_filter_receive(struct hv_device *dev, kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0); - DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " - "bytes got %u)...dropping this message!", + dev_err(&dev->device, "invalid rndis message? (expected %u " + "bytes got %u)...dropping this message!\n", rndis_hdr->msg_len, pkt->total_data_buflen); return -1; @@ -419,8 +421,8 @@ static int rndis_filter_receive(struct hv_device *dev, if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) && (rndis_hdr->msg_len > sizeof(struct rndis_message))) { - DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow " - "detected (got %u, max %zu)...marking it an error!", + dev_err(&dev->device, "incoming rndis message buffer overflow " + "detected (got %u, max %zu)..marking it an error!\n", rndis_hdr->msg_len, sizeof(struct rndis_message)); } @@ -452,7 +454,8 @@ static int rndis_filter_receive(struct hv_device *dev, rndis_filter_receive_indicate_status(rndis_dev, &rndis_msg); break; default: - DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", + dev_err(&dev->device, + "unhandled rndis message (type %u len %u)\n", rndis_msg.ndis_msg_type, rndis_msg.msg_len); break; @@ -575,7 +578,8 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, msecs_to_jiffies(2000)); if (request->wait_condition == 0) { ret = -1; - DPRINT_ERR(NETVSC, "timeout before we got a set response..."); + dev_err(&dev->net_dev->dev->device, + "timeout before we got a set response...\n"); /* * We cant deallocate the request since we may still receive a * send completion for it. @@ -789,16 +793,15 @@ static int rndis_filte_device_add(struct hv_device *dev, */ } - DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", - rndisDevice, rndisDevice->hw_mac_adr); - memcpy(deviceInfo->mac_adr, rndisDevice->hw_mac_adr, ETH_ALEN); rndis_filter_query_device_link_status(rndisDevice); deviceInfo->link_state = rndisDevice->link_stat; - DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, - ((deviceInfo->link_state) ? ("down") : ("up"))); + + dev_info(&dev->device, "Device MAC %pM link state %s", + rndisDevice->hw_mac_adr, + ((deviceInfo->link_state) ? ("down\n") : ("up\n"))); return ret; } -- GitLab From af7a5b6e598c936476fe8dcfaa09d1c7d7e1b165 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:49 -0700 Subject: [PATCH 0390/5560] staging: hv: Replaced DPRINT and printk with native functions in hv_utils Replaced all DPRINT and printk calls with pr_ calls Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_kvp.c | 6 +++--- drivers/staging/hv/hv_util.c | 17 +++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c index 77758204586a..c71a1486544d 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/staging/hv/hv_kvp.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ - +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -114,7 +114,7 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) message = (struct hv_ku_msg *)msg->data; if (msg->seq == KVP_REGISTER) { - printk(KERN_INFO "KVP: user-mode registering done.\n"); + pr_info("KVP: user-mode registering done.\n"); kvp_register(); } @@ -174,7 +174,7 @@ kvp_respond_to_host(char *key, char *value, int error) /* * This is a spurious call! */ - printk(KERN_WARNING "KVP: Transaction not active\n"); + pr_warn("KVP: Transaction not active\n"); return; } /* diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index 3e74f79720b1..3af0a11d6780 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -18,6 +18,8 @@ * Haiyang Zhang * Hank Janssen */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -76,15 +78,15 @@ static void shutdown_onchannelcallback(void *context) icmsghdrp->status = HV_S_OK; execute_shutdown = true; - DPRINT_INFO(VMBUS, "Shutdown request received -" - " gracefull shutdown initiated"); + pr_info("Shutdown request received -" + " gracefull shutdown initiated\n"); break; default: icmsghdrp->status = HV_E_FAIL; execute_shutdown = false; - DPRINT_INFO(VMBUS, "Shutdown request received -" - " Invalid request"); + pr_info("Shutdown request received -" + " Invalid request\n"); break; }; } @@ -242,7 +244,7 @@ MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); static int __init init_hyperv_utils(void) { - printk(KERN_INFO "Registering HyperV Utility Driver\n"); + pr_info("Registering HyperV Utility Driver\n"); if (hv_kvp_init()) return -ENODEV; @@ -256,8 +258,7 @@ static int __init init_hyperv_utils(void) hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) { - printk(KERN_INFO - "Unable to allocate memory for receive buffer\n"); + pr_info("Unable to allocate memory for receive buffer\n"); kfree(shut_txf_buf); kfree(time_txf_buf); kfree(hbeat_txf_buf); @@ -286,7 +287,7 @@ static int __init init_hyperv_utils(void) static void exit_hyperv_utils(void) { - printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); + pr_info("De-Registered HyperV Utility Driver\n"); hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = &chn_cb_negotiate; -- GitLab From d0d6e9c8f5ae4749d8010851e4ed10b6fb759c20 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 29 Mar 2011 13:58:50 -0700 Subject: [PATCH 0391/5560] staging: hv: Replaced printk with pr_info in hv_timesource Replaced printk in hv_timesource with pr_ calls Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_timesource.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/hv/hv_timesource.c b/drivers/staging/hv/hv_timesource.c index a7ee533303b4..0efb04915255 100644 --- a/drivers/staging/hv/hv_timesource.c +++ b/drivers/staging/hv/hv_timesource.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -91,7 +92,7 @@ static int __init init_hv_clocksource(void) if (!dmi_check_system(hv_timesource_dmi_table)) return -ENODEV; - printk(KERN_INFO "Registering HyperV clock source\n"); + pr_info("Registering HyperV clock source\n"); return clocksource_register(&hyperv_cs); } -- GitLab From 94e44cb5ae624cc34a3e4d16907c088d14901c5f Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Fri, 1 Apr 2011 14:32:10 -0700 Subject: [PATCH 0392/5560] staging: hv: change camel case funct names to lower case funct in hv_mouse Change all camelcase function names to lower case in hv_mouse Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 92 +++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 50147f84741c..084ba3be28e6 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -200,7 +200,7 @@ static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); -static struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) +static struct mousevsc_dev *alloc_input_device(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -211,7 +211,7 @@ static struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) /* * Set to 2 to allow both inbound and outbound traffics - * (ie GetInputDevice() and MustGetInputDevice()) to proceed. + * (ie get_input_device() and must_get_input_device()) to proceed. */ atomic_cmpxchg(&inputDevice->RefCount, 0, 2); @@ -221,7 +221,7 @@ static struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) return inputDevice; } -static void FreeInputDevice(struct mousevsc_dev *Device) +static void free_input_device(struct mousevsc_dev *Device) { WARN_ON(atomic_read(&Device->RefCount) == 0); kfree(Device); @@ -230,7 +230,7 @@ static void FreeInputDevice(struct mousevsc_dev *Device) /* * Get the inputdevice object if exists and its refcount > 1 */ -static struct mousevsc_dev *GetInputDevice(struct hv_device *Device) +static struct mousevsc_dev *get_input_device(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -256,7 +256,7 @@ static struct mousevsc_dev *GetInputDevice(struct hv_device *Device) /* * Get the inputdevice object iff exists and its refcount > 0 */ -static struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) +static struct mousevsc_dev *must_get_input_device(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -270,7 +270,7 @@ static struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) return inputDevice; } -static void PutInputDevice(struct hv_device *Device) +static void put_input_device(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -280,9 +280,9 @@ static void PutInputDevice(struct hv_device *Device) } /* - * Drop ref count to 1 to effectively disable GetInputDevice() + * Drop ref count to 1 to effectively disable get_input_device() */ -static struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) +static struct mousevsc_dev *release_input_device(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -298,7 +298,7 @@ static struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) /* * Drop ref count to 0. No one can use InputDevice object. */ -static struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) +static struct mousevsc_dev *final_release_input_device(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -312,12 +312,13 @@ static struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) return inputDevice; } -static void MousevscOnSendCompletion(struct hv_device *Device, struct vmpacket_descriptor *Packet) +static void mousevsc_on_send_completion(struct hv_device *Device, + struct vmpacket_descriptor *Packet) { struct mousevsc_dev *inputDevice; void *request; - inputDevice = MustGetInputDevice(Device); + inputDevice = must_get_input_device(Device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); return; @@ -330,10 +331,11 @@ static void MousevscOnSendCompletion(struct hv_device *Device, struct vmpacket_d /* Shouldn't we be doing something here? */ } - PutInputDevice(Device); + put_input_device(Device); } -static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct synthhid_device_info *DeviceInfo) +static void mousevsc_on_receive_device_info(struct mousevsc_dev *InputDevice, + struct synthhid_device_info *DeviceInfo) { int ret = 0; struct hid_descriptor *desc; @@ -413,7 +415,8 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct wake_up(&InputDevice->DeviceInfoWaitEvent); } -static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struct synthhid_input_report *InputReport) +static void mousevsc_on_receive_input_report(struct mousevsc_dev *InputDevice, + struct synthhid_input_report *InputReport) { struct mousevsc_drv_obj *inputDriver; @@ -429,13 +432,14 @@ static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struc InputReport->header.size); } -static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) +static void mousevsc_on_receive(struct hv_device *Device, + struct vmpacket_descriptor *Packet) { struct pipe_prt_msg *pipeMsg; struct synthhid_msg *hidMsg; struct mousevsc_dev *inputDevice; - inputDevice = MustGetInputDevice(Device); + inputDevice = must_get_input_device(Device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); return; @@ -446,7 +450,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript if (pipeMsg->type != PipeMessageData) { pr_err("unknown pipe msg type - type %d len %d", pipeMsg->type, pipeMsg->size); - PutInputDevice(Device); + put_input_device(Device); return ; } @@ -468,11 +472,11 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript * Parse out the device info into device attr, * hid desc and report desc */ - MousevscOnReceiveDeviceInfo(inputDevice, + mousevsc_on_receive_device_info(inputDevice, (struct synthhid_device_info *)&pipeMsg->data[0]); break; case SynthHidInputReport: - MousevscOnReceiveInputReport(inputDevice, + mousevsc_on_receive_input_report(inputDevice, (struct synthhid_input_report *)&pipeMsg->data[0]); break; @@ -482,10 +486,10 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript break; } - PutInputDevice(Device); + put_input_device(Device); } -static void MousevscOnChannelCallback(void *Context) +static void mousevsc_on_channel_callback(void *Context) { const int packetSize = 0x100; int ret = 0; @@ -499,7 +503,7 @@ static void MousevscOnChannelCallback(void *Context) unsigned char *buffer = packet; int bufferlen = packetSize; - inputDevice = MustGetInputDevice(device); + inputDevice = must_get_input_device(device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); @@ -515,12 +519,13 @@ static void MousevscOnChannelCallback(void *Context) switch (desc->type) { case VM_PKT_COMP: - MousevscOnSendCompletion(device, - desc); + mousevsc_on_send_completion( + device, desc); break; case VM_PKT_DATA_INBAND: - MousevscOnReceive(device, desc); + mousevsc_on_receive( + device, desc); break; default: @@ -568,19 +573,19 @@ static void MousevscOnChannelCallback(void *Context) } } while (1); - PutInputDevice(device); + put_input_device(device); return; } -static int MousevscConnectToVsp(struct hv_device *Device) +static int mousevsc_connect_to_vsp(struct hv_device *Device) { int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_prt_msg *request; struct mousevsc_prt_msg *response; - inputDevice = GetInputDevice(Device); + inputDevice = get_input_device(Device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); @@ -651,19 +656,20 @@ static int MousevscConnectToVsp(struct hv_device *Device) ret = -1; Cleanup: - PutInputDevice(Device); + put_input_device(Device); return ret; } -static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +static int mousevsc_on_device_add(struct hv_device *Device, + void *AdditionalInfo) { int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_drv_obj *inputDriver; struct hv_input_dev_info dev_info; - inputDevice = AllocInputDevice(Device); + inputDevice = alloc_input_device(Device); if (!inputDevice) { ret = -1; @@ -678,25 +684,25 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) INPUTVSC_RECV_RING_BUFFER_SIZE, NULL, 0, - MousevscOnChannelCallback, + mousevsc_on_channel_callback, Device ); if (ret != 0) { pr_err("unable to open channel: %d", ret); - FreeInputDevice(inputDevice); + free_input_device(inputDevice); return -1; } pr_info("InputVsc channel open: %d", ret); - ret = MousevscConnectToVsp(Device); + ret = mousevsc_connect_to_vsp(Device); if (ret != 0) { pr_err("unable to connect channel: %d", ret); vmbus_close(Device->channel); - FreeInputDevice(inputDevice); + free_input_device(inputDevice); return ret; } @@ -724,7 +730,7 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) return ret; } -static int MousevscOnDeviceRemove(struct hv_device *Device) +static int mousevsc_on_device_remove(struct hv_device *Device) { struct mousevsc_dev *inputDevice; int ret = 0; @@ -732,7 +738,7 @@ static int MousevscOnDeviceRemove(struct hv_device *Device) pr_info("disabling input device (%p)...", Device->ext); - inputDevice = ReleaseInputDevice(Device); + inputDevice = release_input_device(Device); /* @@ -749,19 +755,19 @@ static int MousevscOnDeviceRemove(struct hv_device *Device) pr_info("removing input device (%p)...", Device->ext); - inputDevice = FinalReleaseInputDevice(Device); + inputDevice = final_release_input_device(Device); pr_info("input device (%p) safe to remove", inputDevice); /* Close the channel */ vmbus_close(Device->channel); - FreeInputDevice(inputDevice); + free_input_device(inputDevice); return ret; } -static void MousevscOnCleanup(struct hv_driver *drv) +static void mousevsc_on_cleanup(struct hv_driver *drv) { } @@ -984,9 +990,9 @@ static int mouse_vsc_initialize(struct hv_driver *Driver) sizeof(struct hv_guid)); /* Setup the dispatch table */ - inputDriver->Base.dev_add = MousevscOnDeviceAdd; - inputDriver->Base.dev_rm = MousevscOnDeviceRemove; - inputDriver->Base.cleanup = MousevscOnCleanup; + inputDriver->Base.dev_add = mousevsc_on_device_add; + inputDriver->Base.dev_rm = mousevsc_on_device_remove; + inputDriver->Base.cleanup = mousevsc_on_cleanup; return ret; } -- GitLab From 2ba6810baafbed19e3af436f00b3adb5d74e9131 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Fri, 1 Apr 2011 14:32:11 -0700 Subject: [PATCH 0393/5560] staging: hv: Convert camel case func params to lower case in hv_mouse Change all camelcase function params to lower case in hv_mouse Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 172 +++++++++++++++++----------------- 1 file changed, 87 insertions(+), 85 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 084ba3be28e6..3b0390de4581 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -200,7 +200,7 @@ static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); -static struct mousevsc_dev *alloc_input_device(struct hv_device *Device) +static struct mousevsc_dev *alloc_input_device(struct hv_device *device) { struct mousevsc_dev *inputDevice; @@ -215,26 +215,26 @@ static struct mousevsc_dev *alloc_input_device(struct hv_device *Device) */ atomic_cmpxchg(&inputDevice->RefCount, 0, 2); - inputDevice->Device = Device; - Device->ext = inputDevice; + inputDevice->Device = device; + device->ext = inputDevice; return inputDevice; } -static void free_input_device(struct mousevsc_dev *Device) +static void free_input_device(struct mousevsc_dev *device) { - WARN_ON(atomic_read(&Device->RefCount) == 0); - kfree(Device); + WARN_ON(atomic_read(&device->RefCount) == 0); + kfree(device); } /* * Get the inputdevice object if exists and its refcount > 1 */ -static struct mousevsc_dev *get_input_device(struct hv_device *Device) +static struct mousevsc_dev *get_input_device(struct hv_device *device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev *)Device->ext; + inputDevice = (struct mousevsc_dev *)device->ext; /* * FIXME @@ -256,11 +256,11 @@ static struct mousevsc_dev *get_input_device(struct hv_device *Device) /* * Get the inputdevice object iff exists and its refcount > 0 */ -static struct mousevsc_dev *must_get_input_device(struct hv_device *Device) +static struct mousevsc_dev *must_get_input_device(struct hv_device *device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev *)Device->ext; + inputDevice = (struct mousevsc_dev *)device->ext; if (inputDevice && atomic_read(&inputDevice->RefCount)) atomic_inc(&inputDevice->RefCount); @@ -270,11 +270,11 @@ static struct mousevsc_dev *must_get_input_device(struct hv_device *Device) return inputDevice; } -static void put_input_device(struct hv_device *Device) +static void put_input_device(struct hv_device *device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev *)Device->ext; + inputDevice = (struct mousevsc_dev *)device->ext; atomic_dec(&inputDevice->RefCount); } @@ -282,11 +282,11 @@ static void put_input_device(struct hv_device *Device) /* * Drop ref count to 1 to effectively disable get_input_device() */ -static struct mousevsc_dev *release_input_device(struct hv_device *Device) +static struct mousevsc_dev *release_input_device(struct hv_device *device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev *)Device->ext; + inputDevice = (struct mousevsc_dev *)device->ext; /* Busy wait until the ref drop to 2, then set it to 1 */ while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) @@ -296,82 +296,83 @@ static struct mousevsc_dev *release_input_device(struct hv_device *Device) } /* - * Drop ref count to 0. No one can use InputDevice object. + * Drop ref count to 0. No one can use input_device object. */ -static struct mousevsc_dev *final_release_input_device(struct hv_device *Device) +static struct mousevsc_dev *final_release_input_device(struct hv_device *device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev *)Device->ext; + inputDevice = (struct mousevsc_dev *)device->ext; /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) udelay(100); - Device->ext = NULL; + device->ext = NULL; return inputDevice; } -static void mousevsc_on_send_completion(struct hv_device *Device, - struct vmpacket_descriptor *Packet) +static void mousevsc_on_send_completion(struct hv_device *device, + struct vmpacket_descriptor *packet) { struct mousevsc_dev *inputDevice; void *request; - inputDevice = must_get_input_device(Device); + inputDevice = must_get_input_device(device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); return; } - request = (void *)(unsigned long)Packet->trans_id; + request = (void *)(unsigned long)packet->trans_id; if (request == &inputDevice->ProtocolReq) { /* FIXME */ /* Shouldn't we be doing something here? */ } - put_input_device(Device); + put_input_device(device); } -static void mousevsc_on_receive_device_info(struct mousevsc_dev *InputDevice, - struct synthhid_device_info *DeviceInfo) +static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, + struct synthhid_device_info *device_info) { int ret = 0; struct hid_descriptor *desc; struct mousevsc_prt_msg ack; /* Assume success for now */ - InputDevice->DeviceInfoStatus = 0; + input_device->DeviceInfoStatus = 0; /* Save the device attr */ - memcpy(&InputDevice->hid_dev_info, &DeviceInfo->hid_dev_info, sizeof(struct hv_input_dev_info)); + memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info, + sizeof(struct hv_input_dev_info)); /* Save the hid desc */ - desc = &DeviceInfo->hid_descriptor; + desc = &device_info->hid_descriptor; WARN_ON(desc->bLength > 0); - InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); + input_device->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); - if (!InputDevice->HidDesc) { + if (!input_device->HidDesc) { pr_err("unable to allocate hid descriptor - size %d", desc->bLength); goto Cleanup; } - memcpy(InputDevice->HidDesc, desc, desc->bLength); + memcpy(input_device->HidDesc, desc, desc->bLength); /* Save the report desc */ - InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength; - InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize, + input_device->ReportDescSize = desc->desc[0].wDescriptorLength; + input_device->ReportDesc = kzalloc(input_device->ReportDescSize, GFP_KERNEL); - if (!InputDevice->ReportDesc) { + if (!input_device->ReportDesc) { pr_err("unable to allocate report descriptor - size %d", - InputDevice->ReportDescSize); + input_device->ReportDescSize); goto Cleanup; } - memcpy(InputDevice->ReportDesc, + memcpy(input_device->ReportDesc, ((unsigned char *)desc) + desc->bLength, desc->desc[0].wDescriptorLength); @@ -385,7 +386,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *InputDevice, ack.ack.header.size = 1; ack.ack.reserved = 0; - ret = vmbus_sendpacket(InputDevice->Device->channel, + ret = vmbus_sendpacket(input_device->Device->channel, &ack, sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(struct synthhid_device_info_ack), @@ -398,59 +399,60 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *InputDevice, goto Cleanup; } - InputDevice->device_wait_condition = 1; - wake_up(&InputDevice->DeviceInfoWaitEvent); + input_device->device_wait_condition = 1; + wake_up(&input_device->DeviceInfoWaitEvent); return; Cleanup: - kfree(InputDevice->HidDesc); - InputDevice->HidDesc = NULL; + kfree(input_device->HidDesc); + input_device->HidDesc = NULL; - kfree(InputDevice->ReportDesc); - InputDevice->ReportDesc = NULL; + kfree(input_device->ReportDesc); + input_device->ReportDesc = NULL; - InputDevice->DeviceInfoStatus = -1; - InputDevice->device_wait_condition = 1; - wake_up(&InputDevice->DeviceInfoWaitEvent); + input_device->DeviceInfoStatus = -1; + input_device->device_wait_condition = 1; + wake_up(&input_device->DeviceInfoWaitEvent); } -static void mousevsc_on_receive_input_report(struct mousevsc_dev *InputDevice, - struct synthhid_input_report *InputReport) +static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, + struct synthhid_input_report *input_report) { struct mousevsc_drv_obj *inputDriver; - if (!InputDevice->bInitializeComplete) { - pr_info("Initialization incomplete...ignoring InputReport msg"); + if (!input_device->bInitializeComplete) { + pr_info("Initialization incomplete...ignoring input_report msg"); return; } - inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; + inputDriver = (struct mousevsc_drv_obj *)input_device->Device->drv; - inputreport_callback(InputDevice->Device, - InputReport->buffer, - InputReport->header.size); + inputreport_callback(input_device->Device, + input_report->buffer, + input_report->header.size); } -static void mousevsc_on_receive(struct hv_device *Device, - struct vmpacket_descriptor *Packet) +static void mousevsc_on_receive(struct hv_device *device, + struct vmpacket_descriptor *packet) { struct pipe_prt_msg *pipeMsg; struct synthhid_msg *hidMsg; struct mousevsc_dev *inputDevice; - inputDevice = must_get_input_device(Device); + inputDevice = must_get_input_device(device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); return; } - pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); + pipeMsg = (struct pipe_prt_msg *)((unsigned long)packet + + (packet->offset8 << 3)); if (pipeMsg->type != PipeMessageData) { pr_err("unknown pipe msg type - type %d len %d", pipeMsg->type, pipeMsg->size); - put_input_device(Device); + put_input_device(device); return ; } @@ -486,14 +488,14 @@ static void mousevsc_on_receive(struct hv_device *Device, break; } - put_input_device(Device); + put_input_device(device); } -static void mousevsc_on_channel_callback(void *Context) +static void mousevsc_on_channel_callback(void *context) { const int packetSize = 0x100; int ret = 0; - struct hv_device *device = (struct hv_device *)Context; + struct hv_device *device = (struct hv_device *)context; struct mousevsc_dev *inputDevice; u32 bytesRecvd; @@ -578,14 +580,14 @@ static void mousevsc_on_channel_callback(void *Context) return; } -static int mousevsc_connect_to_vsp(struct hv_device *Device) +static int mousevsc_connect_to_vsp(struct hv_device *device) { int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_prt_msg *request; struct mousevsc_prt_msg *response; - inputDevice = get_input_device(Device); + inputDevice = get_input_device(device); if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); @@ -611,7 +613,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *Device) pr_info("synthhid protocol request..."); - ret = vmbus_sendpacket(Device->channel, request, + ret = vmbus_sendpacket(device->channel, request, sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(struct synthhid_protocol_request), @@ -656,20 +658,20 @@ static int mousevsc_connect_to_vsp(struct hv_device *Device) ret = -1; Cleanup: - put_input_device(Device); + put_input_device(device); return ret; } -static int mousevsc_on_device_add(struct hv_device *Device, - void *AdditionalInfo) +static int mousevsc_on_device_add(struct hv_device *device, + void *additional_info) { int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_drv_obj *inputDriver; struct hv_input_dev_info dev_info; - inputDevice = alloc_input_device(Device); + inputDevice = alloc_input_device(device); if (!inputDevice) { ret = -1; @@ -679,13 +681,13 @@ static int mousevsc_on_device_add(struct hv_device *Device, inputDevice->bInitializeComplete = false; /* Open the channel */ - ret = vmbus_open(Device->channel, + ret = vmbus_open(device->channel, INPUTVSC_SEND_RING_BUFFER_SIZE, INPUTVSC_RECV_RING_BUFFER_SIZE, NULL, 0, mousevsc_on_channel_callback, - Device + device ); if (ret != 0) { @@ -696,12 +698,12 @@ static int mousevsc_on_device_add(struct hv_device *Device, pr_info("InputVsc channel open: %d", ret); - ret = mousevsc_connect_to_vsp(Device); + ret = mousevsc_connect_to_vsp(device); if (ret != 0) { pr_err("unable to connect channel: %d", ret); - vmbus_close(Device->channel); + vmbus_close(device->channel); free_input_device(inputDevice); return ret; } @@ -714,14 +716,14 @@ static int mousevsc_on_device_add(struct hv_device *Device, strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse"); /* Send the device info back up */ - deviceinfo_callback(Device, &dev_info); + deviceinfo_callback(device, &dev_info); /* Send the report desc back up */ /* workaround SA-167 */ if (inputDevice->ReportDesc[14] == 0x25) inputDevice->ReportDesc[14] = 0x29; - reportdesc_callback(Device, inputDevice->ReportDesc, + reportdesc_callback(device, inputDevice->ReportDesc, inputDevice->ReportDescSize); inputDevice->bInitializeComplete = true; @@ -730,15 +732,15 @@ static int mousevsc_on_device_add(struct hv_device *Device, return ret; } -static int mousevsc_on_device_remove(struct hv_device *Device) +static int mousevsc_on_device_remove(struct hv_device *device) { struct mousevsc_dev *inputDevice; int ret = 0; pr_info("disabling input device (%p)...", - Device->ext); + device->ext); - inputDevice = release_input_device(Device); + inputDevice = release_input_device(device); /* @@ -753,14 +755,14 @@ static int mousevsc_on_device_remove(struct hv_device *Device) udelay(100); } - pr_info("removing input device (%p)...", Device->ext); + pr_info("removing input device (%p)...", device->ext); - inputDevice = final_release_input_device(Device); + inputDevice = final_release_input_device(device); pr_info("input device (%p) safe to remove", inputDevice); /* Close the channel */ - vmbus_close(Device->channel); + vmbus_close(device->channel); free_input_device(inputDevice); @@ -979,14 +981,14 @@ static void mousevsc_drv_exit(void) return; } -static int mouse_vsc_initialize(struct hv_driver *Driver) +static int mouse_vsc_initialize(struct hv_driver *driver) { struct mousevsc_drv_obj *inputDriver = - (struct mousevsc_drv_obj *)Driver; + (struct mousevsc_drv_obj *)driver; int ret = 0; - Driver->name = driver_name; - memcpy(&Driver->dev_type, &mouse_guid, + driver->name = driver_name; + memcpy(&driver->dev_type, &mouse_guid, sizeof(struct hv_guid)); /* Setup the dispatch table */ -- GitLab From 4b5d5181500e294ceb1bc05efa2df90e2abad47e Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Fri, 1 Apr 2011 14:32:12 -0700 Subject: [PATCH 0394/5560] staging: hv: Convert camel case member of struct mousevsc_drv_obj to lower case Change camelcase members of mousevsc_drv_obj to lower case in hv_mouse. Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 3b0390de4581..ce8886873f91 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -46,7 +46,7 @@ struct hv_input_dev_info { /* Represents the input vsc driver */ /* FIXME - can be removed entirely */ struct mousevsc_drv_obj { - struct hv_driver Base; + struct hv_driver base; }; @@ -836,7 +836,7 @@ static int mousevsc_probe(struct device *device) dev_set_drvdata(device, input_dev_ctx); /* Call to the vsc driver to add the device */ - ret = mousevsc_drv_obj->Base.dev_add(device_obj, NULL); + ret = mousevsc_drv_obj->base.dev_add(device_obj, NULL); if (ret != 0) { DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device"); @@ -868,14 +868,14 @@ static int mousevsc_remove(struct device *device) input_dev_ctx->connected = 0; } - if (!mousevsc_drv_obj->Base.dev_rm) + if (!mousevsc_drv_obj->base.dev_rm) return -1; /* * Call to the vsc driver to let it know that the device * is being removed */ - ret = mousevsc_drv_obj->Base.dev_rm(device_obj); + ret = mousevsc_drv_obj->base.dev_rm(device_obj); if (ret != 0) { DPRINT_ERR(INPUTVSC_DRV, @@ -951,7 +951,7 @@ static int mousevsc_drv_exit_cb(struct device *dev, void *data) static void mousevsc_drv_exit(void) { struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv; - struct hv_driver *drv = &g_mousevsc_drv.Base; + struct hv_driver *drv = &g_mousevsc_drv.base; int ret; struct device *current_dev = NULL; @@ -973,8 +973,8 @@ static void mousevsc_drv_exit(void) device_unregister(current_dev); } - if (mousevsc_drv_obj->Base.cleanup) - mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base); + if (mousevsc_drv_obj->base.cleanup) + mousevsc_drv_obj->base.cleanup(&mousevsc_drv_obj->base); vmbus_child_driver_unregister(&drv->driver); @@ -992,9 +992,9 @@ static int mouse_vsc_initialize(struct hv_driver *driver) sizeof(struct hv_guid)); /* Setup the dispatch table */ - inputDriver->Base.dev_add = mousevsc_on_device_add; - inputDriver->Base.dev_rm = mousevsc_on_device_remove; - inputDriver->Base.cleanup = mousevsc_on_cleanup; + inputDriver->base.dev_add = mousevsc_on_device_add; + inputDriver->base.dev_rm = mousevsc_on_device_remove; + inputDriver->base.cleanup = mousevsc_on_cleanup; return ret; } @@ -1003,14 +1003,14 @@ static int mouse_vsc_initialize(struct hv_driver *driver) static int __init mousevsc_init(void) { struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv; - struct hv_driver *drv = &g_mousevsc_drv.Base; + struct hv_driver *drv = &g_mousevsc_drv.base; DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); /* Callback to client driver to complete the initialization */ - mouse_vsc_initialize(&input_drv_obj->Base); + mouse_vsc_initialize(&input_drv_obj->base); - drv->driver.name = input_drv_obj->Base.name; + drv->driver.name = input_drv_obj->base.name; drv->priv = input_drv_obj; drv->driver.probe = mousevsc_probe; -- GitLab From ac41d402d64aeb42568bce88663200d8b348dab2 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Fri, 1 Apr 2011 14:32:13 -0700 Subject: [PATCH 0395/5560] staging: hv: Convert camel case members of struct mousevsc_dev to lower case Change camelcase members of struct mousevsc_dev to lower case in hv_mouse Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 127 +++++++++++++++++----------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index ce8886873f91..1edcdf7924b2 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -167,23 +167,23 @@ struct mousevsc_prt_msg { * Represents an mousevsc device */ struct mousevsc_dev { - struct hv_device *Device; + struct hv_device *device; /* 0 indicates the device is being destroyed */ - atomic_t RefCount; - int NumOutstandingRequests; - unsigned char bInitializeComplete; - struct mousevsc_prt_msg ProtocolReq; - struct mousevsc_prt_msg ProtocolResp; + atomic_t ref_count; + int num_outstanding_req; + unsigned char init_complete; + struct mousevsc_prt_msg protocol_req; + struct mousevsc_prt_msg protocol_resp; /* Synchronize the request/response if needed */ - wait_queue_head_t ProtocolWaitEvent; - wait_queue_head_t DeviceInfoWaitEvent; + wait_queue_head_t protocol_wait_event; + wait_queue_head_t dev_info_wait_event; int protocol_wait_condition; int device_wait_condition; - int DeviceInfoStatus; + int dev_info_status; - struct hid_descriptor *HidDesc; - unsigned char *ReportDesc; - u32 ReportDescSize; + struct hid_descriptor *hid_desc; + unsigned char *report_desc; + u32 report_desc_size; struct hv_input_dev_info hid_dev_info; }; @@ -213,9 +213,9 @@ static struct mousevsc_dev *alloc_input_device(struct hv_device *device) * Set to 2 to allow both inbound and outbound traffics * (ie get_input_device() and must_get_input_device()) to proceed. */ - atomic_cmpxchg(&inputDevice->RefCount, 0, 2); + atomic_cmpxchg(&inputDevice->ref_count, 0, 2); - inputDevice->Device = device; + inputDevice->device = device; device->ext = inputDevice; return inputDevice; @@ -223,7 +223,7 @@ static struct mousevsc_dev *alloc_input_device(struct hv_device *device) static void free_input_device(struct mousevsc_dev *device) { - WARN_ON(atomic_read(&device->RefCount) == 0); + WARN_ON(atomic_read(&device->ref_count) == 0); kfree(device); } @@ -242,11 +242,11 @@ static struct mousevsc_dev *get_input_device(struct hv_device *device) * what the intention is... * * printk(KERN_ERR "-------------------------> REFCOUNT = %d", - * inputDevice->RefCount); + * inputDevice->ref_count); */ - if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) - atomic_inc(&inputDevice->RefCount); + if (inputDevice && atomic_read(&inputDevice->ref_count) > 1) + atomic_inc(&inputDevice->ref_count); else inputDevice = NULL; @@ -262,8 +262,8 @@ static struct mousevsc_dev *must_get_input_device(struct hv_device *device) inputDevice = (struct mousevsc_dev *)device->ext; - if (inputDevice && atomic_read(&inputDevice->RefCount)) - atomic_inc(&inputDevice->RefCount); + if (inputDevice && atomic_read(&inputDevice->ref_count)) + atomic_inc(&inputDevice->ref_count); else inputDevice = NULL; @@ -276,7 +276,7 @@ static void put_input_device(struct hv_device *device) inputDevice = (struct mousevsc_dev *)device->ext; - atomic_dec(&inputDevice->RefCount); + atomic_dec(&inputDevice->ref_count); } /* @@ -289,7 +289,7 @@ static struct mousevsc_dev *release_input_device(struct hv_device *device) inputDevice = (struct mousevsc_dev *)device->ext; /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) + while (atomic_cmpxchg(&inputDevice->ref_count, 2, 1) != 2) udelay(100); return inputDevice; @@ -305,7 +305,7 @@ static struct mousevsc_dev *final_release_input_device(struct hv_device *device) inputDevice = (struct mousevsc_dev *)device->ext; /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) + while (atomic_cmpxchg(&inputDevice->ref_count, 1, 0) != 1) udelay(100); device->ext = NULL; @@ -326,7 +326,7 @@ static void mousevsc_on_send_completion(struct hv_device *device, request = (void *)(unsigned long)packet->trans_id; - if (request == &inputDevice->ProtocolReq) { + if (request == &inputDevice->protocol_req) { /* FIXME */ /* Shouldn't we be doing something here? */ } @@ -342,7 +342,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, struct mousevsc_prt_msg ack; /* Assume success for now */ - input_device->DeviceInfoStatus = 0; + input_device->dev_info_status = 0; /* Save the device attr */ memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info, @@ -352,27 +352,27 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, desc = &device_info->hid_descriptor; WARN_ON(desc->bLength > 0); - input_device->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); + input_device->hid_desc = kzalloc(desc->bLength, GFP_KERNEL); - if (!input_device->HidDesc) { + if (!input_device->hid_desc) { pr_err("unable to allocate hid descriptor - size %d", desc->bLength); goto Cleanup; } - memcpy(input_device->HidDesc, desc, desc->bLength); + memcpy(input_device->hid_desc, desc, desc->bLength); /* Save the report desc */ - input_device->ReportDescSize = desc->desc[0].wDescriptorLength; - input_device->ReportDesc = kzalloc(input_device->ReportDescSize, + input_device->report_desc_size = desc->desc[0].wDescriptorLength; + input_device->report_desc = kzalloc(input_device->report_desc_size, GFP_KERNEL); - if (!input_device->ReportDesc) { + if (!input_device->report_desc) { pr_err("unable to allocate report descriptor - size %d", - input_device->ReportDescSize); + input_device->report_desc_size); goto Cleanup; } - memcpy(input_device->ReportDesc, + memcpy(input_device->report_desc, ((unsigned char *)desc) + desc->bLength, desc->desc[0].wDescriptorLength); @@ -386,7 +386,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, ack.ack.header.size = 1; ack.ack.reserved = 0; - ret = vmbus_sendpacket(input_device->Device->channel, + ret = vmbus_sendpacket(input_device->device->channel, &ack, sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(struct synthhid_device_info_ack), @@ -400,20 +400,20 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, } input_device->device_wait_condition = 1; - wake_up(&input_device->DeviceInfoWaitEvent); + wake_up(&input_device->dev_info_wait_event); return; Cleanup: - kfree(input_device->HidDesc); - input_device->HidDesc = NULL; + kfree(input_device->hid_desc); + input_device->hid_desc = NULL; - kfree(input_device->ReportDesc); - input_device->ReportDesc = NULL; + kfree(input_device->report_desc); + input_device->report_desc = NULL; - input_device->DeviceInfoStatus = -1; + input_device->dev_info_status = -1; input_device->device_wait_condition = 1; - wake_up(&input_device->DeviceInfoWaitEvent); + wake_up(&input_device->dev_info_wait_event); } static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, @@ -421,14 +421,14 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, { struct mousevsc_drv_obj *inputDriver; - if (!input_device->bInitializeComplete) { + if (!input_device->init_complete) { pr_info("Initialization incomplete...ignoring input_report msg"); return; } - inputDriver = (struct mousevsc_drv_obj *)input_device->Device->drv; + inputDriver = (struct mousevsc_drv_obj *)input_device->device->drv; - inputreport_callback(input_device->Device, + inputreport_callback(input_device->device, input_report->buffer, input_report->header.size); } @@ -460,11 +460,11 @@ static void mousevsc_on_receive(struct hv_device *device, switch (hidMsg->header.type) { case SynthHidProtocolResponse: - memcpy(&inputDevice->ProtocolResp, pipeMsg, + memcpy(&inputDevice->protocol_resp, pipeMsg, pipeMsg->size + sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); inputDevice->protocol_wait_condition = 1; - wake_up(&inputDevice->ProtocolWaitEvent); + wake_up(&inputDevice->protocol_wait_event); break; case SynthHidInitialDeviceInfo: @@ -594,10 +594,10 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) return -1; } - init_waitqueue_head(&inputDevice->ProtocolWaitEvent); - init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); + init_waitqueue_head(&inputDevice->protocol_wait_event); + init_waitqueue_head(&inputDevice->dev_info_wait_event); - request = &inputDevice->ProtocolReq; + request = &inputDevice->protocol_req; /* * Now, initiate the vsc/vsp initialization protocol on the open channel @@ -626,13 +626,14 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) } inputDevice->protocol_wait_condition = 0; - wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); + wait_event_timeout(inputDevice->protocol_wait_event, + inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); if (inputDevice->protocol_wait_condition == 0) { ret = -ETIMEDOUT; goto Cleanup; } - response = &inputDevice->ProtocolResp; + response = &inputDevice->protocol_resp; if (!response->response.approved) { pr_err("synthhid protocol request failed (version %d)", @@ -642,7 +643,8 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) } inputDevice->device_wait_condition = 0; - wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); + wait_event_timeout(inputDevice->dev_info_wait_event, + inputDevice->device_wait_condition, msecs_to_jiffies(1000)); if (inputDevice->device_wait_condition == 0) { ret = -ETIMEDOUT; goto Cleanup; @@ -652,7 +654,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) * We should have gotten the device attr, hid desc and report * desc at this point */ - if (!inputDevice->DeviceInfoStatus) + if (!inputDevice->dev_info_status) pr_info("**** input channel up and running!! ****"); else ret = -1; @@ -678,7 +680,7 @@ static int mousevsc_on_device_add(struct hv_device *device, goto Cleanup; } - inputDevice->bInitializeComplete = false; + inputDevice->init_complete = false; /* Open the channel */ ret = vmbus_open(device->channel, @@ -708,7 +710,7 @@ static int mousevsc_on_device_add(struct hv_device *device, return ret; } - inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; + inputDriver = (struct mousevsc_drv_obj *)inputDevice->device->drv; dev_info.vendor = inputDevice->hid_dev_info.vendor; dev_info.product = inputDevice->hid_dev_info.product; @@ -720,13 +722,13 @@ static int mousevsc_on_device_add(struct hv_device *device, /* Send the report desc back up */ /* workaround SA-167 */ - if (inputDevice->ReportDesc[14] == 0x25) - inputDevice->ReportDesc[14] = 0x29; + if (inputDevice->report_desc[14] == 0x25) + inputDevice->report_desc[14] = 0x29; - reportdesc_callback(device, inputDevice->ReportDesc, - inputDevice->ReportDescSize); + reportdesc_callback(device, inputDevice->report_desc, + inputDevice->report_desc_size); - inputDevice->bInitializeComplete = true; + inputDevice->init_complete = true; Cleanup: return ret; @@ -749,8 +751,9 @@ static int mousevsc_on_device_remove(struct hv_device *device) * * so that outstanding requests can be completed. */ - while (inputDevice->NumOutstandingRequests) { - pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); + while (inputDevice->num_outstanding_req) { + pr_info("waiting for %d requests to complete...", + inputDevice->num_outstanding_req); udelay(100); } -- GitLab From c0765e995059afc57fafe3b5f2a3a85d62300f2f Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Fri, 1 Apr 2011 14:32:14 -0700 Subject: [PATCH 0396/5560] staging: hv: Convert camel case in in all functions to lower case in hv_mouse Convert all camelcase variables inside of all remaining functions to lower case in hv_mouse. Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 225 +++++++++++++++++----------------- 1 file changed, 113 insertions(+), 112 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 1edcdf7924b2..23b69c185a07 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -202,23 +202,23 @@ static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); static struct mousevsc_dev *alloc_input_device(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); + input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); - if (!inputDevice) + if (!input_dev) return NULL; /* * Set to 2 to allow both inbound and outbound traffics * (ie get_input_device() and must_get_input_device()) to proceed. */ - atomic_cmpxchg(&inputDevice->ref_count, 0, 2); + atomic_cmpxchg(&input_dev->ref_count, 0, 2); - inputDevice->device = device; - device->ext = inputDevice; + input_dev->device = device; + device->ext = input_dev; - return inputDevice; + return input_dev; } static void free_input_device(struct mousevsc_dev *device) @@ -232,9 +232,9 @@ static void free_input_device(struct mousevsc_dev *device) */ static struct mousevsc_dev *get_input_device(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - inputDevice = (struct mousevsc_dev *)device->ext; + input_dev = (struct mousevsc_dev *)device->ext; /* * FIXME @@ -242,15 +242,15 @@ static struct mousevsc_dev *get_input_device(struct hv_device *device) * what the intention is... * * printk(KERN_ERR "-------------------------> REFCOUNT = %d", - * inputDevice->ref_count); + * input_dev->ref_count); */ - if (inputDevice && atomic_read(&inputDevice->ref_count) > 1) - atomic_inc(&inputDevice->ref_count); + if (input_dev && atomic_read(&input_dev->ref_count) > 1) + atomic_inc(&input_dev->ref_count); else - inputDevice = NULL; + input_dev = NULL; - return inputDevice; + return input_dev; } /* @@ -258,25 +258,25 @@ static struct mousevsc_dev *get_input_device(struct hv_device *device) */ static struct mousevsc_dev *must_get_input_device(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - inputDevice = (struct mousevsc_dev *)device->ext; + input_dev = (struct mousevsc_dev *)device->ext; - if (inputDevice && atomic_read(&inputDevice->ref_count)) - atomic_inc(&inputDevice->ref_count); + if (input_dev && atomic_read(&input_dev->ref_count)) + atomic_inc(&input_dev->ref_count); else - inputDevice = NULL; + input_dev = NULL; - return inputDevice; + return input_dev; } static void put_input_device(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - inputDevice = (struct mousevsc_dev *)device->ext; + input_dev = (struct mousevsc_dev *)device->ext; - atomic_dec(&inputDevice->ref_count); + atomic_dec(&input_dev->ref_count); } /* @@ -284,15 +284,15 @@ static void put_input_device(struct hv_device *device) */ static struct mousevsc_dev *release_input_device(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - inputDevice = (struct mousevsc_dev *)device->ext; + input_dev = (struct mousevsc_dev *)device->ext; /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&inputDevice->ref_count, 2, 1) != 2) + while (atomic_cmpxchg(&input_dev->ref_count, 2, 1) != 2) udelay(100); - return inputDevice; + return input_dev; } /* @@ -300,33 +300,33 @@ static struct mousevsc_dev *release_input_device(struct hv_device *device) */ static struct mousevsc_dev *final_release_input_device(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - inputDevice = (struct mousevsc_dev *)device->ext; + input_dev = (struct mousevsc_dev *)device->ext; /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&inputDevice->ref_count, 1, 0) != 1) + while (atomic_cmpxchg(&input_dev->ref_count, 1, 0) != 1) udelay(100); device->ext = NULL; - return inputDevice; + return input_dev; } static void mousevsc_on_send_completion(struct hv_device *device, struct vmpacket_descriptor *packet) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; void *request; - inputDevice = must_get_input_device(device); - if (!inputDevice) { + input_dev = must_get_input_device(device); + if (!input_dev) { pr_err("unable to get input device...device being destroyed?"); return; } request = (void *)(unsigned long)packet->trans_id; - if (request == &inputDevice->protocol_req) { + if (request == &input_dev->protocol_req) { /* FIXME */ /* Shouldn't we be doing something here? */ } @@ -419,14 +419,14 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, struct synthhid_input_report *input_report) { - struct mousevsc_drv_obj *inputDriver; + struct mousevsc_drv_obj *input_drv; if (!input_device->init_complete) { pr_info("Initialization incomplete...ignoring input_report msg"); return; } - inputDriver = (struct mousevsc_drv_obj *)input_device->device->drv; + input_drv = (struct mousevsc_drv_obj *)input_device->device->drv; inputreport_callback(input_device->device, input_report->buffer, @@ -436,55 +436,55 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, static void mousevsc_on_receive(struct hv_device *device, struct vmpacket_descriptor *packet) { - struct pipe_prt_msg *pipeMsg; - struct synthhid_msg *hidMsg; - struct mousevsc_dev *inputDevice; + struct pipe_prt_msg *pipe_msg; + struct synthhid_msg *hid_msg; + struct mousevsc_dev *input_dev; - inputDevice = must_get_input_device(device); - if (!inputDevice) { + input_dev = must_get_input_device(device); + if (!input_dev) { pr_err("unable to get input device...device being destroyed?"); return; } - pipeMsg = (struct pipe_prt_msg *)((unsigned long)packet + + pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet + (packet->offset8 << 3)); - if (pipeMsg->type != PipeMessageData) { + if (pipe_msg->type != PipeMessageData) { pr_err("unknown pipe msg type - type %d len %d", - pipeMsg->type, pipeMsg->size); + pipe_msg->type, pipe_msg->size); put_input_device(device); return ; } - hidMsg = (struct synthhid_msg *)&pipeMsg->data[0]; + hid_msg = (struct synthhid_msg *)&pipe_msg->data[0]; - switch (hidMsg->header.type) { + switch (hid_msg->header.type) { case SynthHidProtocolResponse: - memcpy(&inputDevice->protocol_resp, pipeMsg, - pipeMsg->size + sizeof(struct pipe_prt_msg) - + memcpy(&input_dev->protocol_resp, pipe_msg, + pipe_msg->size + sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); - inputDevice->protocol_wait_condition = 1; - wake_up(&inputDevice->protocol_wait_event); + input_dev->protocol_wait_condition = 1; + wake_up(&input_dev->protocol_wait_event); break; case SynthHidInitialDeviceInfo: - WARN_ON(pipeMsg->size >= sizeof(struct hv_input_dev_info)); + WARN_ON(pipe_msg->size >= sizeof(struct hv_input_dev_info)); /* * Parse out the device info into device attr, * hid desc and report desc */ - mousevsc_on_receive_device_info(inputDevice, - (struct synthhid_device_info *)&pipeMsg->data[0]); + mousevsc_on_receive_device_info(input_dev, + (struct synthhid_device_info *)&pipe_msg->data[0]); break; case SynthHidInputReport: - mousevsc_on_receive_input_report(inputDevice, - (struct synthhid_input_report *)&pipeMsg->data[0]); + mousevsc_on_receive_input_report(input_dev, + (struct synthhid_input_report *)&pipe_msg->data[0]); break; default: pr_err("unsupported hid msg type - type %d len %d", - hidMsg->header.type, hidMsg->header.size); + hid_msg->header.type, hid_msg->header.size); break; } @@ -496,27 +496,28 @@ static void mousevsc_on_channel_callback(void *context) const int packetSize = 0x100; int ret = 0; struct hv_device *device = (struct hv_device *)context; - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; - u32 bytesRecvd; - u64 requestId; + u32 bytes_recvd; + u64 req_id; unsigned char packet[packetSize]; struct vmpacket_descriptor *desc; unsigned char *buffer = packet; int bufferlen = packetSize; - inputDevice = must_get_input_device(device); + input_dev = must_get_input_device(device); - if (!inputDevice) { + if (!input_dev) { pr_err("unable to get input device...device being destroyed?"); return; } do { - ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId); + ret = vmbus_recvpacket_raw(device->channel, buffer, + bufferlen, &bytes_recvd, &req_id); if (ret == 0) { - if (bytesRecvd > 0) { + if (bytes_recvd > 0) { desc = (struct vmpacket_descriptor *)buffer; switch (desc->type) { @@ -533,8 +534,8 @@ static void mousevsc_on_channel_callback(void *context) default: pr_err("unhandled packet type %d, tid %llx len %d\n", desc->type, - requestId, - bytesRecvd); + req_id, + bytes_recvd); break; } @@ -560,8 +561,8 @@ static void mousevsc_on_channel_callback(void *context) } } else if (ret == -2) { /* Handle large packet */ - bufferlen = bytesRecvd; - buffer = kzalloc(bytesRecvd, GFP_KERNEL); + bufferlen = bytes_recvd; + buffer = kzalloc(bytes_recvd, GFP_KERNEL); if (buffer == NULL) { buffer = packet; @@ -569,7 +570,7 @@ static void mousevsc_on_channel_callback(void *context) /* Try again next time around */ pr_err("unable to allocate buffer of size %d!", - bytesRecvd); + bytes_recvd); break; } } @@ -583,21 +584,21 @@ static void mousevsc_on_channel_callback(void *context) static int mousevsc_connect_to_vsp(struct hv_device *device) { int ret = 0; - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; struct mousevsc_prt_msg *request; struct mousevsc_prt_msg *response; - inputDevice = get_input_device(device); + input_dev = get_input_device(device); - if (!inputDevice) { + if (!input_dev) { pr_err("unable to get input device...device being destroyed?"); return -1; } - init_waitqueue_head(&inputDevice->protocol_wait_event); - init_waitqueue_head(&inputDevice->dev_info_wait_event); + init_waitqueue_head(&input_dev->protocol_wait_event); + init_waitqueue_head(&input_dev->dev_info_wait_event); - request = &inputDevice->protocol_req; + request = &input_dev->protocol_req; /* * Now, initiate the vsc/vsp initialization protocol on the open channel @@ -625,15 +626,15 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) goto Cleanup; } - inputDevice->protocol_wait_condition = 0; - wait_event_timeout(inputDevice->protocol_wait_event, - inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->protocol_wait_condition == 0) { + input_dev->protocol_wait_condition = 0; + wait_event_timeout(input_dev->protocol_wait_event, + input_dev->protocol_wait_condition, msecs_to_jiffies(1000)); + if (input_dev->protocol_wait_condition == 0) { ret = -ETIMEDOUT; goto Cleanup; } - response = &inputDevice->protocol_resp; + response = &input_dev->protocol_resp; if (!response->response.approved) { pr_err("synthhid protocol request failed (version %d)", @@ -642,10 +643,10 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) goto Cleanup; } - inputDevice->device_wait_condition = 0; - wait_event_timeout(inputDevice->dev_info_wait_event, - inputDevice->device_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->device_wait_condition == 0) { + input_dev->device_wait_condition = 0; + wait_event_timeout(input_dev->dev_info_wait_event, + input_dev->device_wait_condition, msecs_to_jiffies(1000)); + if (input_dev->device_wait_condition == 0) { ret = -ETIMEDOUT; goto Cleanup; } @@ -654,7 +655,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) * We should have gotten the device attr, hid desc and report * desc at this point */ - if (!inputDevice->dev_info_status) + if (!input_dev->dev_info_status) pr_info("**** input channel up and running!! ****"); else ret = -1; @@ -669,18 +670,18 @@ static int mousevsc_on_device_add(struct hv_device *device, void *additional_info) { int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_drv_obj *inputDriver; + struct mousevsc_dev *input_dev; + struct mousevsc_drv_obj *input_drv; struct hv_input_dev_info dev_info; - inputDevice = alloc_input_device(device); + input_dev = alloc_input_device(device); - if (!inputDevice) { + if (!input_dev) { ret = -1; goto Cleanup; } - inputDevice->init_complete = false; + input_dev->init_complete = false; /* Open the channel */ ret = vmbus_open(device->channel, @@ -694,7 +695,7 @@ static int mousevsc_on_device_add(struct hv_device *device, if (ret != 0) { pr_err("unable to open channel: %d", ret); - free_input_device(inputDevice); + free_input_device(input_dev); return -1; } @@ -706,15 +707,15 @@ static int mousevsc_on_device_add(struct hv_device *device, pr_err("unable to connect channel: %d", ret); vmbus_close(device->channel); - free_input_device(inputDevice); + free_input_device(input_dev); return ret; } - inputDriver = (struct mousevsc_drv_obj *)inputDevice->device->drv; + input_drv = (struct mousevsc_drv_obj *)input_dev->device->drv; - dev_info.vendor = inputDevice->hid_dev_info.vendor; - dev_info.product = inputDevice->hid_dev_info.product; - dev_info.version = inputDevice->hid_dev_info.version; + dev_info.vendor = input_dev->hid_dev_info.vendor; + dev_info.product = input_dev->hid_dev_info.product; + dev_info.version = input_dev->hid_dev_info.version; strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse"); /* Send the device info back up */ @@ -722,13 +723,13 @@ static int mousevsc_on_device_add(struct hv_device *device, /* Send the report desc back up */ /* workaround SA-167 */ - if (inputDevice->report_desc[14] == 0x25) - inputDevice->report_desc[14] = 0x29; + if (input_dev->report_desc[14] == 0x25) + input_dev->report_desc[14] = 0x29; - reportdesc_callback(device, inputDevice->report_desc, - inputDevice->report_desc_size); + reportdesc_callback(device, input_dev->report_desc, + input_dev->report_desc_size); - inputDevice->init_complete = true; + input_dev->init_complete = true; Cleanup: return ret; @@ -736,13 +737,13 @@ static int mousevsc_on_device_add(struct hv_device *device, static int mousevsc_on_device_remove(struct hv_device *device) { - struct mousevsc_dev *inputDevice; + struct mousevsc_dev *input_dev; int ret = 0; pr_info("disabling input device (%p)...", device->ext); - inputDevice = release_input_device(device); + input_dev = release_input_device(device); /* @@ -751,23 +752,23 @@ static int mousevsc_on_device_remove(struct hv_device *device) * * so that outstanding requests can be completed. */ - while (inputDevice->num_outstanding_req) { + while (input_dev->num_outstanding_req) { pr_info("waiting for %d requests to complete...", - inputDevice->num_outstanding_req); + input_dev->num_outstanding_req); udelay(100); } pr_info("removing input device (%p)...", device->ext); - inputDevice = final_release_input_device(device); + input_dev = final_release_input_device(device); - pr_info("input device (%p) safe to remove", inputDevice); + pr_info("input device (%p) safe to remove", input_dev); /* Close the channel */ vmbus_close(device->channel); - free_input_device(inputDevice); + free_input_device(input_dev); return ret; } @@ -986,7 +987,7 @@ static void mousevsc_drv_exit(void) static int mouse_vsc_initialize(struct hv_driver *driver) { - struct mousevsc_drv_obj *inputDriver = + struct mousevsc_drv_obj *input_drv = (struct mousevsc_drv_obj *)driver; int ret = 0; @@ -995,9 +996,9 @@ static int mouse_vsc_initialize(struct hv_driver *driver) sizeof(struct hv_guid)); /* Setup the dispatch table */ - inputDriver->base.dev_add = mousevsc_on_device_add; - inputDriver->base.dev_rm = mousevsc_on_device_remove; - inputDriver->base.cleanup = mousevsc_on_cleanup; + input_drv->base.dev_add = mousevsc_on_device_add; + input_drv->base.dev_rm = mousevsc_on_device_remove; + input_drv->base.cleanup = mousevsc_on_cleanup; return ret; } -- GitLab From ea7b2805e0c5ed8cfbac2914f9807a056a1ab13e Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Mar 2011 14:51:05 +0100 Subject: [PATCH 0397/5560] staging: brcm80211: code cleanup Removed inactive code sections (BCM_DMAPAD and CHIPC_UART_ALWAYS_ON were never defined). Also replaced magic number by #define. Deleted incorrect comment. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 5 +++-- drivers/staging/brcm80211/util/hnddma.c | 3 --- drivers/staging/brcm80211/util/hndpmu.c | 6 ------ 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 774b4e916b29..182a9f5284eb 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -48,6 +48,8 @@ #include "wl_ucode.h" #include "wl_mac80211.h" +#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ + static void wl_timer(unsigned long data); static void _wl_timer(struct wl_timer *t); @@ -1070,8 +1072,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) | IEEE80211_HW_AMPDU_AGGREGATION; hw->extra_tx_headroom = wlc_get_header_len(); - /* FIXME: should get this from wlc->machwcap */ - hw->queues = 4; + hw->queues = N_TX_QUEUES; /* FIXME: this doesn't seem to be used properly in minstrel_ht. * mac80211/status.c:ieee80211_tx_status() checks this value, * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 8a81eb997f99..0e25d18f6437 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1451,9 +1451,6 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, data = p->data; len = p->len; -#ifdef BCM_DMAPAD - len += PKTDMAPAD(di->osh, p); -#endif /* BCM_DMAPAD */ next = p->next; /* return nonzero if out of tx descriptors */ diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 59e3ede89fe7..3675d1b1aa81 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -34,7 +34,6 @@ /* debug-only definitions */ /* #define BCMDBG_FORCEHT */ -/* #define CHIPC_UART_ALWAYS_ON */ #else #define PMU_MSG(args) #endif /* BCMDBG */ @@ -2511,11 +2510,6 @@ void si_pmu_chip_init(si_t *sih) ASSERT(sih->cccaps & CC_CAP_PMU); -#ifdef CHIPC_UART_ALWAYS_ON - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st), - CCS_FORCEALP, CCS_FORCEALP); -#endif /* CHIPC_UART_ALWAYS_ON */ - /* Gate off SPROM clock and chip select signals */ si_pmu_sprom_enable(sih, false); -- GitLab From 4cbdbca020bd26dde0feb2a7511ae14fd394faf6 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Mar 2011 14:51:06 +0100 Subject: [PATCH 0398/5560] staging: brcm80211: deleted inactive BCMDBG_FORCEHT code Code cleanup. Preprocessor flag BCMDBG_FORCEHT is never defined, is a debug feature, so ifdeff'ed code has been removed. The removed section would force the backplane clock on HT rate, which facilitates debug but has a negative effect on power usage. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/hndpmu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 3675d1b1aa81..621177b4c4b0 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -1543,10 +1543,6 @@ void si_pmu_pll_init(si_t *sih, uint xtalfreq) break; } -#ifdef BCMDBG_FORCEHT - OR_REG(&cc->clk_ctl_st, CCS_FORCEHT); -#endif - /* Return to original core */ si_setcoreidx(sih, origidx); } -- GitLab From d3f54f319a6145241c37663f0e21b10888ee0920 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Mar 2011 15:11:26 +0100 Subject: [PATCH 0399/5560] staging: brcm80211: changed comment on rx buffer len in wlc_ampdu.c Code cleanup. Code in wlc_ampdu.c is waiting for Mac80211 functionality to be released. Added this information to a code comment. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index c6cdcd940956..3b2b554c0dbf 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -687,7 +687,10 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", sgi, is40, mcs); - maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ + /* XXX Fix me to honor real max_rxlen */ + /* can fix this as soon as ampdu_action() in mac80211.h + * gets extra u8buf_size par */ + maxlen = 64 * 1024; if (is40) mimo_ctlchbw = -- GitLab From 8906d770d8314cf9ab5289ee971594cb250f541d Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Mar 2011 15:11:27 +0100 Subject: [PATCH 0400/5560] staging: brcm80211: Removed invalid comment in receive processing. Comment was a left over from a driver that handled AMPDU aggregation itself (instead of relying on Mac80211). Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 639b5d7c9603..6a4126f7ecf1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -6949,11 +6949,6 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) #if defined(BCMDBG) struct sk_buff *skb = p; #endif /* BCMDBG */ - /* Todo: - * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. - * Test for INTERMEDIATE like so: - * if (!(plcp[0] | plcp[1] | plcp[2])) - */ memset(&rx_status, 0, sizeof(rx_status)); prep_mac80211_status(wlc, rxh, p, &rx_status); -- GitLab From da5fa38f4ae6c565accd4e3a81e0b89561c049a4 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Mar 2011 15:11:28 +0100 Subject: [PATCH 0401/5560] staging: brcm80211: deleted unused code in hndpmu.c Code cleanup. Code is not necessary since BCMDBG does not have to be defined for a functional driver. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/hndpmu.c | 39 ------------------------- 1 file changed, 39 deletions(-) diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 621177b4c4b0..8426a279e857 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -1448,10 +1448,6 @@ static u32 si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc) { u32 tmp, m1div; -#ifdef BCMDBG - u32 ndiv_int, ndiv_frac, p2div, p1div, fvco; - u32 fref; -#endif u32 FVCO = si_pmu1_pllfvco0(sih); /* Read m1div from pllcontrol[1] */ @@ -1459,41 +1455,6 @@ si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc) tmp = R_REG(&cc->pllcontrol_data); m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; -#ifdef BCMDBG - /* Read p2div/p1div from pllcontrol[0] */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG(&cc->pllcontrol_data); - p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT; - p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT; - - /* Calculate fvco based on xtal freq and ndiv and pdiv */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG(&cc->pllcontrol_data); - ndiv_int = - (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT; - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG(&cc->pllcontrol_data); - ndiv_frac = - (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> - PMU1_PLL0_PC3_NDIV_FRAC_SHIFT; - - fref = si_pmu1_alpclk0(sih, cc) / 1000; - - fvco = (fref * ndiv_int) << 8; - fvco += (fref * (ndiv_frac >> 12)) >> 4; - fvco += (fref * (ndiv_frac & 0xfff)) >> 12; - fvco >>= 8; - fvco *= p2div; - fvco /= p1div; - fvco /= 1000; - fvco *= 1000; - - PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco)); - - FVCO = fvco; -#endif /* BCMDBG */ - /* Return ARM/SB clock */ return FVCO / m1div * 1000; } -- GitLab From dd0308742b1ba9fbf45422be968816123cc9b6aa Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 18 Mar 2011 11:09:32 +0100 Subject: [PATCH 0402/5560] staging: brcm80211: unified README files There were separate README files for softmac and fullmac. Fullmac file contents has been merged into the toplevel README file. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/README | 36 +++++++++++++++++++++++ drivers/staging/brcm80211/TODO | 1 - drivers/staging/brcm80211/brcmfmac/README | 35 ---------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index 99e67669f26b..34fce72e0b33 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -88,3 +88,39 @@ Dowan Kim dowan@broadcom.com Roland Vossen rvossen@broadcom.com Arend van Spriel arend@broadcom.com +Broadcom fullmac driver + +This is production driver. + +What's here +=========== +- Completely open source host driver, no binary object files +- Features Broadcom's OneDriver architecture (single source base for + supported chips and architectures) +- On-chip firmware loaded using standard request_firmware() +- Support for BCM4329(SDIO) + +What's done +========== +- Integration with cfg80211 stack +- Most of Mac functionality is performed in dongle +- A-MPDU single stream rates +- BCM4329: Dualband, Single stream, 20MHz channels + +Firmware installation +====================== +Firmware is available from the Linux firmware repository at: + + git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git + http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git + https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git + +For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt +to /lib/firmware/brcm (or wherever firmware is normally installed on your +system). + +Contact Info: +============= +Brett Rudley brudley@broadcom.com +Henry Ptasinski henryp@broadcom.com +Nohee Ko noheek@broadcom.com diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index 24ebadbe4241..0b58844eaddd 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -48,4 +48,3 @@ Henry Ptasinski Dowan Kim Roland Vossen Arend van Spriel - diff --git a/drivers/staging/brcm80211/brcmfmac/README b/drivers/staging/brcm80211/brcmfmac/README index be29e4236920..139597f9cb07 100644 --- a/drivers/staging/brcm80211/brcmfmac/README +++ b/drivers/staging/brcm80211/brcmfmac/README @@ -1,37 +1,2 @@ -Broadcom fullmac driver -This is production driver. - -What's here -=========== -- Completely open source host driver, no binary object files -- Features Broadcom's OneDriver architecture (single source base for - supported chips and architectures) -- On-chip firmware loaded using standard request_firmware() -- Support for BCM4329(SDIO) - -What's done -========== -- Integration with cfg80211 stack -- Most of Mac functionality is performed in dongle -- A-MPDU single stream rates -- BCM4329: Dualband, Single stream, 20MHz channels - -Firmware installation -====================== -Firmware is available from the Linux firmware repository at: - - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git - http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - -For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt -to /lib/firmware/brcm (or wherever firmware is normally installed on your -system). - -Contact Info: -============= -Brett Rudley brudley@broadcom.com -Henry Ptasinski henryp@broadcom.com -Nohee Ko noheek@broadcom.com -- GitLab From 4a266c4fc99d9b27afb2a476ea8fdd7189788115 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 18 Mar 2011 11:09:33 +0100 Subject: [PATCH 0403/5560] staging: brcm80211: moved several README items to website Intended audience for the README file are users of the driver. Information only interesting to developers has been moved out of the file and placed on the website: http://linuxwireless.org/en/users/Drivers/brcm80211 Also, resolved bugs have been removed from the README. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/README | 70 ++++---------------------------- drivers/staging/brcm80211/TODO | 2 + 2 files changed, 9 insertions(+), 63 deletions(-) diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index 34fce72e0b33..6356f80a7f39 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -1,40 +1,5 @@ Broadcom Mac80211 driver -This is a driver in progress. It has features still to be implemented well as -bugs in current code. - - -What's here and not here -======================= -- Completely open source host driver, no binary object files -- Features Broadcom's OneDriver architecture (single source base for - supported chips and architectures) -- On-chip firmware loaded using standard request_firmware() -- Support for BCM43224, BCM43225, BCM4313 (PCIe NIC) -- Framework for supporting new chips, including mac80211-aware embedded chips -- Does not support older PCI/PCIe chips with SSB backplane -- Driver includes BMAC interface for transparent dongle support -- Uses minstrel_ht rate algorithm -- HW based encryption not enabled yet - - -What's done -========== -- Integration with mac80211 stack -- A-MPDU single & dual stream rates -- BCM43224: Dualband, Dual stream, 20MHz channels - Throughput (in chamber): ~85-90 Mbits/sec (in both 2.4 & 5 GHz bands) -- BCM43225: 2.4 GHz, Dual Stream, 20MHz channels - Throughput (in chamber): ~85-90 Mbits/sec -- BCM4313: 2.4 GHz, Single Stream - Throughput (in chamber): ~40 Mbits/sec - - -Things To Be Done -================= -See the TODO file - - Firmware installation ====================== Firmware is available from the Linux firmware repository at: @@ -63,31 +28,6 @@ Bugs/Problems - Occasional crashes with BCM43224 on multicore machines. -Note on Regulatory Implementation -================================ -This generation of chips contain additional regulatory support independent of -the driver. The devices use a single worldwide regulatory domain, with channels -12-14 (2.4 GHz band) and channels 52-64 and 100-140 (5 GHz band) restricted to -passive operation. Transmission on those channels is suppressed until -appropriate other traffic is observed on those channels. - -Within the driver, we use the ficticious country code "X2" to represent this -worldwide regulatory domain. There is currently no interface to configure a -different domain. - -The driver reads the SROM country code from the chip and hands it up to -mac80211 as the regulatory hint, however this information is otherwise unused -with the driver. - - -Contact Info: -============= -Brett Rudley brudley@broadcom.com -Henry Ptasinski henryp@broadcom.com -Dowan Kim dowan@broadcom.com -Roland Vossen rvossen@broadcom.com -Arend van Spriel arend@broadcom.com - Broadcom fullmac driver This is production driver. @@ -121,6 +61,10 @@ system). Contact Info: ============= -Brett Rudley brudley@broadcom.com -Henry Ptasinski henryp@broadcom.com -Nohee Ko noheek@broadcom.com +Brett Rudley brudley@broadcom.com +Henry Ptasinski henryp@broadcom.com +Dowan Kim dowan@broadcom.com +Roland Vossen rvossen@broadcom.com +Arend van Spriel arend@broadcom.com + +For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 \ No newline at end of file diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index 0b58844eaddd..c54b2869d2b1 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -41,6 +41,8 @@ Other handling of different interfaces so that a single binary driver can be built. - Add support for new chips (obviously an ongoing item). +More info: http://linuxwireless.org/en/users/Drivers/brcm80211 + Contact ===== Brett Rudley -- GitLab From ddc332df71409fdb5f22d5273b380c91a9ffb823 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 18 Mar 2011 11:09:34 +0100 Subject: [PATCH 0404/5560] staging: brcm80211: revised README Removed duplicated text sections in README. Removed Bugs/problems that no longer occur. One brcmsmac instability remains, (to be solved with new ucode), that has been moved to the TODO file. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/README | 82 +++++++++++++++----------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index 6356f80a7f39..8ad558675bd3 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -1,64 +1,58 @@ -Broadcom Mac80211 driver +Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers. -Firmware installation -====================== -Firmware is available from the Linux firmware repository at: +Completely open source host drivers, no binary object files. - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git - http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git +Support for the following chips: +=============================== -For all chips, copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to -/lib/firmware/brcm (or wherever firmware is normally installed on your system). + brcmsmac (PCIe) + Name Device ID + BCM4313 0x4727 + BCM43224 0x4353 + BCM43225 0x4357 -Currently supported chips -============== -PCI -Name Device ID -BCM4313 0x4727 -BCM43224 0x4353 -BCM43225 0x4357 + brcmfmac (SDIO) + Name + BCM4329 +Both brcmsmac and brcmfmac drivers require firmware files that need to be +separately downloaded. -Bugs/Problems -============== -- Driver can get confused while scanning during high throughput, can cause - burping, hanging, and possible crashing. -- Occasional hangs & burps with BCM43224 on 2.4 GHz with dual stream rates. -- Occasional crashes with BCM43224 on multicore machines. - +Firmware +====================== +Firmware is available from the Linux firmware repository at: -Broadcom fullmac driver + git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git + http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git + https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git -This is production driver. -What's here -=========== -- Completely open source host driver, no binary object files -- Features Broadcom's OneDriver architecture (single source base for - supported chips and architectures) -- On-chip firmware loaded using standard request_firmware() -- Support for BCM4329(SDIO) +=============================================================== +Broadcom brcmsmac driver +=============================================================== +- Support for both 32 and 64 bit Linux kernels -What's done -========== -- Integration with cfg80211 stack -- Most of Mac functionality is performed in dongle -- A-MPDU single stream rates -- BCM4329: Dualband, Single stream, 20MHz channels Firmware installation ====================== -Firmware is available from the Linux firmware repository at: +Copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to +/lib/firmware/brcm (or wherever firmware is normally installed +on your system). + + +=============================================================== +Broadcom brcmfmac driver +=============================================================== +- Support for 32 bit Linux kernel, 64 bit untested - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git - http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git -For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt +Firmware installation +====================== +Copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt to /lib/firmware/brcm (or wherever firmware is normally installed on your system). + Contact Info: ============= Brett Rudley brudley@broadcom.com @@ -67,4 +61,4 @@ Dowan Kim dowan@broadcom.com Roland Vossen rvossen@broadcom.com Arend van Spriel arend@broadcom.com -For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 \ No newline at end of file +For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 -- GitLab From 6f27b08d5b781608e97652ae5b83c271c9d177bc Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 18 Mar 2011 11:09:35 +0100 Subject: [PATCH 0405/5560] staging: brcm80211: cleaned up TODO file Brought TODO file in line with current driver state. Moved longer term TODO items (the ones to be done once this driver hits mainline) to website. Removed the bugs that have been solved. Added new TODO items. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/TODO | 57 ++++++---------------------------- 1 file changed, 10 insertions(+), 47 deletions(-) diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index c54b2869d2b1..e9c1393a2b92 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -1,52 +1,15 @@ -To Do List for Broadcom Mac80211 driver - -Features to be added -===================== -- 40 MHz channels -- Power Save -- AP -- IBSS -- HW-based encryption -- LED support -- RFKILL -- Debugfs and debugability - -Code cleanup -============ -- Use proper kernel coding standards -- Remove overlap with system header files. (ie much of include/proto/*.h should - be removed) -- Purge unused variables/data structs/functions BUT keep code related to - features that are being added (ie AP mode, 40 Mhz channels, IBSS etc). -- Replace proprietary utility functions with public kernel versions. +To Do List for Broadcom Mac80211 driver before getting in mainline Bugs ==== -- Various occasional asserts/hangs -- Scanning during data transfer sometimes causes major slowdowns. Sometimes - revcovers when scan is done, other times not. -- Mac80211 API not completely implemented (ie ops_bss_info_changed, - ops_get_stats, etc) - -Other -===== -- wlc_mac80211.[ch], wl_mac80211.[ch] and linux_osl.c all need to be refactored - and combined. -- Merge files that are partially duplicated between the softmac and fullmac - drivers -- Replace driver's proprietary ssb interface with generic kernel ssb module - (only used when compiling for SDIO). -- PCI and SDIO support are currently #ifdef'ed exclusive of each other, which - leads to a separate wl.ko for each. This should be changed to runtime - handling of different interfaces so that a single binary driver can be built. -- Add support for new chips (obviously an ongoing item). +- Oops on AMPDU traffic, to be solved by new ucode (currently under test) -More info: http://linuxwireless.org/en/users/Drivers/brcm80211 +brcmfmac and brcmsmac +===================== +- ASSERTS not allowed in mainline, replace by warning + error handling +- Replace printk and WL_ERROR() with proper routines -Contact -===== -Brett Rudley -Henry Ptasinski -Dowan Kim -Roland Vossen -Arend van Spriel +brcmfmac +===================== +- Replace driver's proprietary ssb interface with generic kernel ssb module +- Build and test on 64 bit linux kernel -- GitLab From 6b5a5a3eb77ea69382da9d2a64d74107e49cedaa Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 18 Mar 2011 15:56:57 -0700 Subject: [PATCH 0406/5560] STAGING: brcm80211 v2 keep power on in suspend state Keep WIFI power on during suspend. Consumes 10s of milliwatts but avoids having to reload firmware on resume. Tested on tegra2_seaboard. Signed-off-by: Venkat Rao Tested-by: Grant Grundler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 7 +++++++ drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 65313fa0cf4a..0c89e854c4ce 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -68,6 +68,13 @@ DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr, int regsize, u32 *data); +void sdioh_sdio_set_host_pm_flags(int flag) +{ + if (sdio_set_host_pm_flags(gInstance->func[1], flag)) + printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\ + __func__, (unsigned int)flag); +} + static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) { int err_ret; diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 555b056b49b1..b44daf959e8f 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -39,6 +39,8 @@ #include #include +void sdioh_sdio_set_host_pm_flags(int flag); + static struct sdio_func *cfg80211_sdio_func; static struct wl_dev *wl_cfg80211_dev; static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; @@ -1988,6 +1990,8 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy) clear_bit(WL_STATUS_SCANNING, &wl->status); clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); + sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER); + return err; } -- GitLab From c6e1a0d12ca7b4f22c58e55a16beacfb7d3d8462 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Mon, 4 Apr 2011 22:30:30 -0700 Subject: [PATCH 0407/5560] net: Allow no-cache copy from user on transmit This patch uses __copy_from_user_nocache on transmit to bypass data cache for a performance improvement. skb_add_data_nocache and skb_copy_to_page_nocache can be called by sendmsg functions to use this feature, initial support is in tcp_sendmsg. This functionality is configurable per device using ethtool. Presumably, this feature would only be useful when the driver does not touch the data. The feature is turned on by default if a device indicates that it does some form of checksum offload; it is off by default for devices that do no checksum offload or indicate no checksum is necessary. For the former case copy-checksum is probably done anyway, in the latter case the device is likely loopback in which case the no cache copy is probably not beneficial. This patch was tested using 200 instances of netperf TCP_RR with 1400 byte request and one byte reply. Platform is 16 core AMD x86. No-cache copy disabled: 672703 tps, 97.13% utilization 50/90/99% latency:244.31 484.205 1028.41 No-cache copy enabled: 702113 tps, 96.16% utilization, 50/90/99% latency 238.56 467.56 956.955 Using 14000 byte request and response sizes demonstrate the effects more dramatically: No-cache copy disabled: 79571 tps, 34.34 %utlization 50/90/95% latency 1584.46 2319.59 5001.76 No-cache copy enabled: 83856 tps, 34.81% utilization 50/90/95% latency 2508.42 2622.62 2735.88 Note especially the effect on latency tail (95th percentile). This seems to provide a nice performance improvement and is consistent in the tests I ran. Presumably, this would provide the greatest benfits in the presence of an application workload stressing the cache and a lot of transmit data happening. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- include/linux/netdevice.h | 3 +- include/net/sock.h | 53 +++++++++++++++++++++++++++++++++ net/core/dev.c | 12 ++++++++ net/core/ethtool.c | 2 +- net/ipv4/tcp.c | 7 +++-- 6 files changed, 73 insertions(+), 6 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 16d6fe954695..b51e021354b5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1407,7 +1407,7 @@ static int bond_compute_features(struct bonding *bond) int i; features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); - features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM; + features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_NOCACHE_COPY; if (!bond->first_slave) goto done; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a4664cc68e2b..09d262415769 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1066,6 +1066,7 @@ struct net_device { #define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */ #define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */ #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */ +#define NETIF_F_NOCACHE_COPY (1 << 30) /* Use no-cache copyfromuser */ /* Segmentation offload features */ #define NETIF_F_GSO_SHIFT 16 @@ -1081,7 +1082,7 @@ struct net_device { /* = all defined minus driver/device-class-related */ #define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \ NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) -#define NETIF_F_ETHTOOL_BITS (0x3f3fffff & ~NETIF_F_NEVER_CHANGE) +#define NETIF_F_ETHTOOL_BITS (0x7f3fffff & ~NETIF_F_NEVER_CHANGE) /* List of features with software fallbacks. */ #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ diff --git a/include/net/sock.h b/include/net/sock.h index da0534d3401c..43bd515e92fd 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -1389,6 +1390,58 @@ static inline void sk_nocaps_add(struct sock *sk, int flags) sk->sk_route_caps &= ~flags; } +static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb, + char __user *from, char *to, + int copy) +{ + if (skb->ip_summed == CHECKSUM_NONE) { + int err = 0; + __wsum csum = csum_and_copy_from_user(from, to, copy, 0, &err); + if (err) + return err; + skb->csum = csum_block_add(skb->csum, csum, skb->len); + } else if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) { + if (!access_ok(VERIFY_READ, from, copy) || + __copy_from_user_nocache(to, from, copy)) + return -EFAULT; + } else if (copy_from_user(to, from, copy)) + return -EFAULT; + + return 0; +} + +static inline int skb_add_data_nocache(struct sock *sk, struct sk_buff *skb, + char __user *from, int copy) +{ + int err; + + err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy), copy); + if (err) + __skb_trim(skb, skb->len); + + return err; +} + +static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from, + struct sk_buff *skb, + struct page *page, + int off, int copy) +{ + int err; + + err = skb_do_copy_data_nocache(sk, skb, from, + page_address(page) + off, copy); + if (err) + return err; + + skb->len += copy; + skb->data_len += copy; + skb->truesize += copy; + sk->sk_wmem_queued += copy; + sk_mem_charge(sk, copy); + return 0; +} + static inline int skb_copy_to_page(struct sock *sk, char __user *from, struct sk_buff *skb, struct page *page, int off, int copy) diff --git a/net/core/dev.c b/net/core/dev.c index 02f56376fe99..5d0b4f6f1a72 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5425,6 +5425,14 @@ int register_netdevice(struct net_device *dev) dev->features &= ~NETIF_F_GSO; } + /* Turn on no cache copy if HW is doing checksum */ + dev->hw_features |= NETIF_F_NOCACHE_COPY; + if ((dev->features & NETIF_F_ALL_CSUM) && + !(dev->features & NETIF_F_NO_CSUM)) { + dev->wanted_features |= NETIF_F_NOCACHE_COPY; + dev->features |= NETIF_F_NOCACHE_COPY; + } + /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, * vlan_dev_init() will do the dev->features check, so these features * are enabled only if supported by underlying device. @@ -6182,6 +6190,10 @@ u32 netdev_increment_features(u32 all, u32 one, u32 mask) } } + /* If device can't no cache copy, don't do for all */ + if (!(one & NETIF_F_NOCACHE_COPY)) + all &= ~NETIF_F_NOCACHE_COPY; + one |= NETIF_F_ALL_CSUM; one |= all & NETIF_F_ONE_FOR_ALL; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 439e4b0e1312..719670ae199c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -359,7 +359,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS /* NETIF_F_NTUPLE */ "rx-ntuple-filter", /* NETIF_F_RXHASH */ "rx-hashing", /* NETIF_F_RXCSUM */ "rx-checksum", - "", + /* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy" "", }; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b22d45010545..054a59d21eb0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -999,7 +999,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* We have some space in skb head. Superb! */ if (copy > skb_tailroom(skb)) copy = skb_tailroom(skb); - if ((err = skb_add_data(skb, from, copy)) != 0) + err = skb_add_data_nocache(sk, skb, from, copy); + if (err) goto do_fault; } else { int merge = 0; @@ -1042,8 +1043,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* Time to copy data. We are close to * the end! */ - err = skb_copy_to_page(sk, from, skb, page, - off, copy); + err = skb_copy_to_page_nocache(sk, from, skb, + page, off, copy); if (err) { /* If this page was new, give it to the * socket so it does not get leaked. -- GitLab From 014cdb5f454486b20de0e6358fb3692dbe067557 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:25:54 +0100 Subject: [PATCH 0408/5560] staging: brcm80211: cleanup si_doattach function for fullmac si_doattach for the fullmac driver is selected using BCMSDIO flag. Within the function there are #ifdef BRCM_FULLMAC but this is implicitly true so these have been removed and the function itself is now between #ifdef BRCM_FULLMAC instead of BCMSDIO. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/siutils.c | 59 ++---------------------- 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index ed168ceba5f0..a77b457e28be 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -364,7 +364,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */ /* this has been customized for the bcm 4329 ONLY */ -#ifdef BCMSDIO +#ifdef BRCM_FULLMAC static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) @@ -372,7 +372,6 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct si_pub *sih = &sii->pub; u32 w, savewin; chipcregs_t *cc; - char *pvars = NULL; uint origidx; ASSERT(GOODREGS(regs)); @@ -431,69 +430,17 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, goto exit; } -#ifdef BRCM_FULLMAC - pvars = NULL; -#else - /* Init nvram from flash if it exists */ - nvram_init((void *)&(sii->pub)); - - /* Init nvram from sprom/otp if they exist */ - if (srom_var_init - (&sii->pub, bustype, regs, sii->osh, vars, varsz)) { - SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); - goto exit; - } - pvars = vars ? *vars : NULL; - si_nvram_process(sii, pvars); -#endif - - /* === NVRAM, clock is ready === */ - -#ifdef BRCM_FULLMAC - if (sii->pub.ccrev >= 20) { -#endif cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); W_REG(&cc->gpiopullup, 0); W_REG(&cc->gpiopulldown, 0); sb_setcoreidx(sih, origidx); -#ifdef BRCM_FULLMAC - } -#endif - -#ifndef BRCM_FULLMAC - /* PMU specific initializations */ - if (PMUCTL_ENAB(sih)) { - u32 xtalfreq; - si_pmu_init(sih); - si_pmu_chip_init(sih); - xtalfreq = getintvar(pvars, "xtalfreq"); - /* If xtalfreq var not available, try to measure it */ - if (xtalfreq == 0) - xtalfreq = si_pmu_measure_alpclk(sih); - si_pmu_pll_init(sih, xtalfreq); - si_pmu_res_init(sih); - si_pmu_swreg_init(sih); - } - - /* setup the GPIO based LED powersave register */ - w = getintvar(pvars, "leddc"); - if (w == 0) - w = DEFAULT_GPIOTIMERVAL; - sb_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); - -#ifdef BCMDBG - /* clear any previous epidiag-induced target abort */ - sb_taclear(sih, false); -#endif /* BCMDBG */ -#endif return sii; exit: return NULL; } - -#else /* BCMSDIO */ +#else /* BRCM_FULLMAC */ static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) @@ -685,7 +632,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, return NULL; } -#endif /* BCMSDIO */ +#endif /* BRCM_FULLMAC */ /* may be called with core in reset */ void si_detach(si_t *sih) -- GitLab From 933b720f2f4e76d307cd50ae49dcbc1e598e79a9 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:25:55 +0100 Subject: [PATCH 0409/5560] staging: brcm80211: remove duplicate prototype for si_pmu_pllupd The prototype for this function occurred twice in this header file so removed one occurrence. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/hndpmu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/brcm80211/include/hndpmu.h b/drivers/staging/brcm80211/include/hndpmu.h index 3eea1f9fbc39..b2b2095c4ced 100644 --- a/drivers/staging/brcm80211/include/hndpmu.h +++ b/drivers/staging/brcm80211/include/hndpmu.h @@ -56,7 +56,6 @@ extern u32 si_pmu_measure_alpclk(si_t *sih); extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern void si_pmu_pllupd(si_t *sih); extern void si_pmu_sprom_enable(si_t *sih, bool enable); extern void si_pmu_radio_enable(si_t *sih, bool enable); -- GitLab From 0686acf730344e0e9442649952e34fe4e1d6ccb0 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:25:57 +0100 Subject: [PATCH 0410/5560] staging: brcm80211: replace si_* calls with ai_* calls in brcmsmac driver The brcmsmac only supports chips with amba silicon interconnect so no abstraction is required. The siutils functions will be removed from the brcmsmac driver and this commit does easy replacement of siutils functions that simply delegate to the corresponding aiutils function. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- .../brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 16 ++--- .../brcm80211/brcmsmac/phy/wlc_phy_n.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 58 +++++++++---------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 8f75af2ffc58..26313828a210 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -596,7 +596,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars if (D11REV_IS(sh->corerev, 4)) sflags = SISF_2G_PHY | SISF_5G_PHY; else - sflags = si_core_sflags(sh->sih, 0, 0); + sflags = ai_core_sflags(sh->sih, 0, 0); if (BAND_5G(bandtype)) { if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) { @@ -974,7 +974,7 @@ void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) } if (D11REV_GE(pi->sh->corerev, 5)) - ASSERT(si_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA); + ASSERT(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA); phy_init = pi->pi_fptr.init; @@ -3311,12 +3311,12 @@ void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2); } - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpiocontrol), ~0x0, 0x0); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioout), 0x40, 0x40); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioouten), 0x40, 0x40); } else { @@ -3324,11 +3324,11 @@ void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioout), 0x40, 0x00); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpioouten), 0x40, 0x0); - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, gpiocontrol), ~0x0, 0x40); } diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index 7947c6028b6e..7a759bfe1a13 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -14550,7 +14550,7 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) (pi->sh->chippkg == BCM4718_PKG_ID))) { if ((pi->sh->boardflags & BFL_EXTLNA) && (CHSPEC_IS2G(pi->radio_chanspec))) { - si_corereg(pi->sh->sih, SI_CC_IDX, + ai_corereg(pi->sh->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), 0x40, 0x40); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 5a96dc3cdb36..31716785b61d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -235,7 +235,7 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); ASSERT(bandunit != wlc_hw->band->bandunit); - ASSERT(si_iscoreup(wlc_hw->sih)); + ASSERT(ai_iscoreup(wlc_hw->sih)); ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == 0); @@ -715,7 +715,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, /* set bar0 window to point at D11 core */ wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); - wlc_hw->corerev = si_corerev(wlc_hw->sih); + wlc_hw->corerev = ai_corerev(wlc_hw->sih); regs = wlc_hw->regs; @@ -1230,7 +1230,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) } else { /* Reset and disable the core */ - if (si_iscoreup(wlc_hw->sih)) { + if (ai_iscoreup(wlc_hw->sih)) { if (R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) wlc_suspend_mac_and_wait(wlc_hw->wlc); @@ -1320,7 +1320,7 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) /* check fast clock is available (if core is not in reset) */ if (wlc_hw->forcefastclk && wlc_hw->clk) - ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); + ASSERT(ai_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); /* keep the ucode wake bit on if forcefastclk is on * since we do not want ucode to put us back to slow clock @@ -1843,17 +1843,17 @@ static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) if (OFF == clk) { /* clear gmode bit, put phy into reset */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), (SICF_PRST | SICF_FGC)); udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); udelay(1); } else { /* take phy out of reset */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_FGC), 0); + ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0); udelay(1); } @@ -1864,16 +1864,16 @@ void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) { WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, + ai_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); udelay(1); } @@ -1888,18 +1888,18 @@ void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) return; if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); + ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); else - si_core_cflags(wlc_hw->sih, SICF_FGC, 0); + ai_core_cflags(wlc_hw->sih, SICF_FGC, 0); } void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) { if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); + ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); else - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); + ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); } void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) @@ -1919,7 +1919,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && NREV_LE(wlc_hw->band->phyrev, 4)) { /* Set the PHY bandwidth */ - si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); + ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); udelay(1); @@ -1927,12 +1927,12 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) wlc_bmac_core_phypll_reset(wlc_hw); /* reset the PHY */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), (SICF_PRST | SICF_PCLKE)); phy_in_reset = true; } else { - si_core_cflags(wlc_hw->sih, + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE | SICF_BWMASK), (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); } @@ -1955,9 +1955,9 @@ WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, ASSERT(bandunit != wlc_hw->band->bandunit); /* Enable the d11 core before accessing it */ - if (!si_iscoreup(wlc_hw->sih)) { - si_core_reset(wlc_hw->sih, 0, 0); - ASSERT(si_iscoreup(wlc_hw->sih)); + if (!ai_iscoreup(wlc_hw->sih)) { + ai_core_reset(wlc_hw->sih, 0, 0); + ASSERT(ai_iscoreup(wlc_hw->sih)); wlc_mctrl_reset(wlc_hw); } @@ -1999,7 +1999,7 @@ void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) /* set gmode core flag */ if (wlc_hw->sbclk && !wlc_hw->noreset) { - si_core_cflags(wlc_hw->sih, SICF_GMODE, + ai_core_cflags(wlc_hw->sih, SICF_GMODE, ((bandunit == 0) ? SICF_GMODE : 0)); } } @@ -2096,7 +2096,7 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); - si_core_reset(wlc_hw->sih, flags, resetbits); + ai_core_reset(wlc_hw->sih, flags, resetbits); wlc_mctrl_reset(wlc_hw); } @@ -2104,7 +2104,7 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) /* put core back into reset */ if (!clk) - si_core_disable(wlc_hw->sih, 0); + ai_core_disable(wlc_hw->sih, 0); if (!xtal) wlc_bmac_xtal(wlc_hw, OFF); @@ -2189,7 +2189,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) wlc_clkctl_clk(wlc_hw, CLK_FAST); /* reset the dma engines except first time thru */ - if (si_iscoreup(wlc_hw->sih)) { + if (ai_iscoreup(wlc_hw->sih)) { for (i = 0; i < NFIFO; i++) if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", @@ -2224,7 +2224,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) * with other driver like mips/arm since they may touch chipcommon as well. */ wlc_hw->clk = false; - si_core_reset(wlc_hw->sih, flags, resetbits); + ai_core_reset(wlc_hw->sih, flags, resetbits); wlc_hw->clk = true; if (wlc_hw->band && wlc_hw->band->pi) wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); @@ -2343,7 +2343,7 @@ static void wlc_coreinit(struct wlc_info *wlc) wlc_gpio_init(wlc); - sflags = si_core_sflags(wlc_hw->sih, 0, 0); + sflags = ai_core_sflags(wlc_hw->sih, 0, 0); if (D11REV_IS(wlc_hw->corerev, 23)) { if (WLCISNPHY(wlc_hw->band)) @@ -3480,7 +3480,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); wlc_hw->clk = false; - si_core_disable(wlc_hw->sih, 0); + ai_core_disable(wlc_hw->sih, 0); wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); } -- GitLab From c6042b3043f4ee1776c10572f517b25ed4f8188f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:25:58 +0100 Subject: [PATCH 0411/5560] staging: brcm80211: remove defines from bcmsrom.c Two macro definitions in the file were either not used or meaningless and have been removed. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/bcmsrom.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index eca35b94e96c..5c4acece3d79 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -44,8 +44,6 @@ #include -#define BS_ERROR(args) - #define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ @@ -64,8 +62,6 @@ typedef struct varbuf { extern char *_vars; extern uint _varsz; -#define SROM_CIS_SINGLE 1 - static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count); static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); @@ -1424,7 +1420,6 @@ srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, } if (!wait_cnt) { - BS_ERROR(("%s: Command 0x%x timed out\n", __func__, cmd)); return 0xffff; } if (cmd == SRC_OP_READ) @@ -1490,8 +1485,6 @@ sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, * is blank, regardless of the rest of the content, so declare * it bad. */ - BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", - __func__, buf[0])); return 1; } @@ -1500,7 +1493,6 @@ sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, if (hndcrc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) { /* DBG only pci always read srom4 first, then srom8/9 */ - /* BS_ERROR(("%s: bad crc\n", __func__)); */ err = 1; } /* now correct the endianness of the byte array */ @@ -1535,8 +1527,6 @@ static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) * is blank, regardless of the rest of the content, so declare * it bad. */ - BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __func__, - buf[0])); return 1; } @@ -1544,7 +1534,6 @@ static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) htol16_buf(buf, bufsz); if (hndcrc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) { - BS_ERROR(("%s: bad crc\n", __func__)); err = 1; } /* now correct the endianness of the byte array */ @@ -1884,10 +1873,6 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) sprom_read_pci(sih, sromwindow, 0, srom, SROM4_WORDS, true); sromrev = srom[SROM4_CRCREV] & 0xff; - if (err) - BS_ERROR(("%s: srom %d, bad crc\n", __func__, - sromrev)); - } else if (err == 0) { /* srom is good and is rev < 4 */ /* top word of sprom contains version and crc8 */ @@ -1921,7 +1906,6 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) u32 val; val = 0; - BS_ERROR(("Neither SPROM nor OTP has valid image\n")); value = si_getdevpathvar(sih, "sromrev"); if (value) { sromrev = (u8) simple_strtoul(value, NULL, 0); @@ -1929,8 +1913,6 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) goto varscont; } - BS_ERROR(("%s, SROM CRC Error\n", __func__)); - value = si_getnvramflvar(sih, "sromrev"); if (value) { err = 0; -- GitLab From 94da53f91df196a62727363722dd20bd616f7362 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:25:59 +0100 Subject: [PATCH 0412/5560] staging: brcm80211: remove unneccessary include from bcmsrom.c Include statement of if_ether.h turned out to be unneccessary so this is removed. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/bcmsrom.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 5c4acece3d79..de9f79929a8d 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -42,8 +42,6 @@ #include #endif -#include - #define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ -- GitLab From 72a279620facd56cf650573c8705136e25908357 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:26:00 +0100 Subject: [PATCH 0413/5560] staging: brcm80211: remove conditional BCMSDIO code from bcmsrom.c The source file is only used by the softmac driver and will never be compiled with the BCMSDIO flag enabled so there is no need to have code ifdef for this flag. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/bcmsrom.c | 106 ----------------------- 1 file changed, 106 deletions(-) diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index de9f79929a8d..b029ecd92f5a 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -28,20 +28,10 @@ #include #include #include -#ifdef BCMSDIO -#include -#include -#endif #include #include -#if defined(BCMSDIO) -#include -#include -#include -#endif - #define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ @@ -64,11 +54,6 @@ static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count); static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); static int initvars_flash_si(si_t *sih, char **vars, uint *count); -#ifdef BCMSDIO -static int initvars_cis_sdio(char **vars, uint *count); -static int sprom_cmd_sdio(u8 cmd); -static int sprom_read_sdio(u16 addr, u16 *data); -#endif /* BCMSDIO */ static int sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, u16 *buf, uint nwords, bool check_crc); #if defined(BCMNVRAMR) @@ -173,11 +158,6 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, return initvars_srom_pci(sih, curmap, vars, count); -#ifdef BCMSDIO - case SDIO_BUS: - return initvars_cis_sdio(vars, count); -#endif /* BCMSDIO */ - default: ASSERT(0); } @@ -1974,92 +1954,6 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) return err; } -#ifdef BCMSDIO -/* - * Read the SDIO cis and call parsecis to initialize the vars. - * Return 0 on success, nonzero on error. - */ -static int initvars_cis_sdio(char **vars, uint *count) -{ - u8 *cis[SBSDIO_NUM_FUNCTION + 1]; - uint fn, numfn; - int rc = 0; - - numfn = bcmsdh_query_iofnum(NULL); - ASSERT(numfn <= SDIOD_MAX_IOFUNCS); - - for (fn = 0; fn <= numfn; fn++) { - cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC); - if (cis[fn] == NULL) { - rc = -1; - break; - } - - if (bcmsdh_cis_read(NULL, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT) != - 0) { - kfree(cis[fn]); - rc = -2; - break; - } - } - - if (!rc) - rc = srom_parsecis(cis, fn, vars, count); - - while (fn-- > 0) - kfree(cis[fn]); - - return rc; -} - -/* set SDIO sprom command register */ -static int sprom_cmd_sdio(u8 cmd) -{ - u8 status = 0; - uint wait_cnt = 1000; - - /* write sprom command register */ - bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, cmd, NULL); - - /* wait status */ - while (wait_cnt--) { - status = - bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, NULL); - if (status & SBSDIO_SPROM_DONE) - return 0; - } - - return 1; -} - -/* read a word from the SDIO srom */ -static int sprom_read_sdio(u16 addr, u16 *data) -{ - u8 addr_l, addr_h, data_l, data_h; - - addr_l = (u8) ((addr * 2) & 0xff); - addr_h = (u8) (((addr * 2) >> 8) & 0xff); - - /* set address */ - bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_HIGH, addr_h, - NULL); - bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_LOW, addr_l, - NULL); - - /* do read */ - if (sprom_cmd_sdio(SBSDIO_SPROM_READ)) - return 1; - - /* read data */ - data_h = - bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_HIGH, NULL); - data_l = - bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_LOW, NULL); - - *data = (data_h << 8) | data_l; - return 0; -} -#endif /* BCMSDIO */ static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz) { -- GitLab From 28562f3cd502a97e607590586a87811c8f438e38 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Mar 2011 11:26:01 +0100 Subject: [PATCH 0414/5560] staging: brcm80211: remove support functions for older chipsets from bcmsrom The source file contained functions for both older and current chipsets but the brcmsmac driver does not support the older chipsets so those functions are removed. Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/bcmsrom.c | 1210 ---------------------- 1 file changed, 1210 deletions(-) diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index b029ecd92f5a..d93f1c0a89d7 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -164,1216 +164,6 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, return -1; } -/* support only 16-bit word read from srom */ -int -srom_read(si_t *sih, uint bustype, void *curmap, - uint byteoff, uint nbytes, u16 *buf, bool check_crc) -{ - uint off, nw; -#ifdef BCMSDIO - uint i; -#endif /* BCMSDIO */ - - ASSERT(bustype == bustype); - - /* check input - 16-bit access only */ - if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX) - return 1; - - off = byteoff / 2; - nw = nbytes / 2; - - if (bustype == PCI_BUS) { - if (!curmap) - return 1; - - if (si_is_sprom_available(sih)) { - u16 *srom; - - srom = (u16 *) SROM_OFFSET(sih); - if (srom == NULL) - return 1; - - if (sprom_read_pci - (sih, srom, off, buf, nw, check_crc)) - return 1; - } -#if defined(BCMNVRAMR) - else { - if (otp_read_pci(sih, buf, SROM_MAX)) - return 1; - } -#endif -#ifdef BCMSDIO - } else if (bustype == SDIO_BUS) { - off = byteoff / 2; - nw = nbytes / 2; - for (i = 0; i < nw; i++) { - if (sprom_read_sdio - ((u16) (off + i), (u16 *) (buf + i))) - return 1; - } -#endif /* BCMSDIO */ - } else if (bustype == SI_BUS) { - return 1; - } else { - return 1; - } - - return 0; -} - -static const char vstr_manf[] = "manf=%s"; -static const char vstr_productname[] = "productname=%s"; -static const char vstr_manfid[] = "manfid=0x%x"; -static const char vstr_prodid[] = "prodid=0x%x"; -#ifdef BCMSDIO -static const char vstr_sdmaxspeed[] = "sdmaxspeed=%d"; -static const char vstr_sdmaxblk[][13] = { -"sdmaxblk0=%d", "sdmaxblk1=%d", "sdmaxblk2=%d"}; -#endif -static const char vstr_regwindowsz[] = "regwindowsz=%d"; -static const char vstr_sromrev[] = "sromrev=%d"; -static const char vstr_chiprev[] = "chiprev=%d"; -static const char vstr_subvendid[] = "subvendid=0x%x"; -static const char vstr_subdevid[] = "subdevid=0x%x"; -static const char vstr_boardrev[] = "boardrev=0x%x"; -static const char vstr_aa2g[] = "aa2g=0x%x"; -static const char vstr_aa5g[] = "aa5g=0x%x"; -static const char vstr_ag[] = "ag%d=0x%x"; -static const char vstr_cc[] = "cc=%d"; -static const char vstr_opo[] = "opo=%d"; -static const char vstr_pa0b[][9] = { -"pa0b0=%d", "pa0b1=%d", "pa0b2=%d"}; - -static const char vstr_pa0itssit[] = "pa0itssit=%d"; -static const char vstr_pa0maxpwr[] = "pa0maxpwr=%d"; -static const char vstr_pa1b[][9] = { -"pa1b0=%d", "pa1b1=%d", "pa1b2=%d"}; - -static const char vstr_pa1lob[][11] = { -"pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d"}; - -static const char vstr_pa1hib[][11] = { -"pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d"}; - -static const char vstr_pa1itssit[] = "pa1itssit=%d"; -static const char vstr_pa1maxpwr[] = "pa1maxpwr=%d"; -static const char vstr_pa1lomaxpwr[] = "pa1lomaxpwr=%d"; -static const char vstr_pa1himaxpwr[] = "pa1himaxpwr=%d"; -static const char vstr_oem[] = - "oem=%02x%02x%02x%02x%02x%02x%02x%02x"; -static const char vstr_boardflags[] = "boardflags=0x%x"; -static const char vstr_boardflags2[] = "boardflags2=0x%x"; -static const char vstr_ledbh[] = "ledbh%d=0x%x"; -static const char vstr_noccode[] = "ccode=0x0"; -static const char vstr_ccode[] = "ccode=%c%c"; -static const char vstr_cctl[] = "cctl=0x%x"; -static const char vstr_cckpo[] = "cckpo=0x%x"; -static const char vstr_ofdmpo[] = "ofdmpo=0x%x"; -static const char vstr_rdlid[] = "rdlid=0x%x"; -static const char vstr_rdlrndis[] = "rdlrndis=%d"; -static const char vstr_rdlrwu[] = "rdlrwu=%d"; -static const char vstr_usbfs[] = "usbfs=%d"; -static const char vstr_wpsgpio[] = "wpsgpio=%d"; -static const char vstr_wpsled[] = "wpsled=%d"; -static const char vstr_rdlsn[] = "rdlsn=%d"; -static const char vstr_rssismf2g[] = "rssismf2g=%d"; -static const char vstr_rssismc2g[] = "rssismc2g=%d"; -static const char vstr_rssisav2g[] = "rssisav2g=%d"; -static const char vstr_bxa2g[] = "bxa2g=%d"; -static const char vstr_rssismf5g[] = "rssismf5g=%d"; -static const char vstr_rssismc5g[] = "rssismc5g=%d"; -static const char vstr_rssisav5g[] = "rssisav5g=%d"; -static const char vstr_bxa5g[] = "bxa5g=%d"; -static const char vstr_tri2g[] = "tri2g=%d"; -static const char vstr_tri5gl[] = "tri5gl=%d"; -static const char vstr_tri5g[] = "tri5g=%d"; -static const char vstr_tri5gh[] = "tri5gh=%d"; -static const char vstr_rxpo2g[] = "rxpo2g=%d"; -static const char vstr_rxpo5g[] = "rxpo5g=%d"; -static const char vstr_boardtype[] = "boardtype=0x%x"; -static const char vstr_leddc[] = "leddc=0x%04x"; -static const char vstr_vendid[] = "vendid=0x%x"; -static const char vstr_devid[] = "devid=0x%x"; -static const char vstr_xtalfreq[] = "xtalfreq=%d"; -static const char vstr_txchain[] = "txchain=0x%x"; -static const char vstr_rxchain[] = "rxchain=0x%x"; -static const char vstr_antswitch[] = "antswitch=0x%x"; -static const char vstr_regrev[] = "regrev=0x%x"; -static const char vstr_antswctl2g[] = "antswctl2g=0x%x"; -static const char vstr_triso2g[] = "triso2g=0x%x"; -static const char vstr_pdetrange2g[] = "pdetrange2g=0x%x"; -static const char vstr_extpagain2g[] = "extpagain2g=0x%x"; -static const char vstr_tssipos2g[] = "tssipos2g=0x%x"; -static const char vstr_antswctl5g[] = "antswctl5g=0x%x"; -static const char vstr_triso5g[] = "triso5g=0x%x"; -static const char vstr_pdetrange5g[] = "pdetrange5g=0x%x"; -static const char vstr_extpagain5g[] = "extpagain5g=0x%x"; -static const char vstr_tssipos5g[] = "tssipos5g=0x%x"; -static const char vstr_maxp2ga0[] = "maxp2ga0=0x%x"; -static const char vstr_itt2ga0[] = "itt2ga0=0x%x"; -static const char vstr_pa[] = "pa%dgw%da%d=0x%x"; -static const char vstr_pahl[] = "pa%dg%cw%da%d=0x%x"; -static const char vstr_maxp5ga0[] = "maxp5ga0=0x%x"; -static const char vstr_itt5ga0[] = "itt5ga0=0x%x"; -static const char vstr_maxp5gha0[] = "maxp5gha0=0x%x"; -static const char vstr_maxp5gla0[] = "maxp5gla0=0x%x"; -static const char vstr_maxp2ga1[] = "maxp2ga1=0x%x"; -static const char vstr_itt2ga1[] = "itt2ga1=0x%x"; -static const char vstr_maxp5ga1[] = "maxp5ga1=0x%x"; -static const char vstr_itt5ga1[] = "itt5ga1=0x%x"; -static const char vstr_maxp5gha1[] = "maxp5gha1=0x%x"; -static const char vstr_maxp5gla1[] = "maxp5gla1=0x%x"; -static const char vstr_cck2gpo[] = "cck2gpo=0x%x"; -static const char vstr_ofdm2gpo[] = "ofdm2gpo=0x%x"; -static const char vstr_ofdm5gpo[] = "ofdm5gpo=0x%x"; -static const char vstr_ofdm5glpo[] = "ofdm5glpo=0x%x"; -static const char vstr_ofdm5ghpo[] = "ofdm5ghpo=0x%x"; -static const char vstr_cddpo[] = "cddpo=0x%x"; -static const char vstr_stbcpo[] = "stbcpo=0x%x"; -static const char vstr_bw40po[] = "bw40po=0x%x"; -static const char vstr_bwduppo[] = "bwduppo=0x%x"; -static const char vstr_mcspo[] = "mcs%dgpo%d=0x%x"; -static const char vstr_mcspohl[] = "mcs%dg%cpo%d=0x%x"; -static const char vstr_custom[] = "customvar%d=0x%x"; -static const char vstr_cckdigfilttype[] = "cckdigfilttype=%d"; -static const char vstr_boardnum[] = "boardnum=%d"; -static const char vstr_macaddr[] = "macaddr=%s"; -static const char vstr_usbepnum[] = "usbepnum=0x%x"; -static const char vstr_end[] = "END\0"; - -u8 patch_pair; - -/* For dongle HW, accept partial calibration parameters */ -#define BCMDONGLECASE(n) - -int srom_parsecis(u8 *pcis[], uint ciscnt, char **vars, - uint *count) -{ - char eabuf[32]; - char *base; - varbuf_t b; - u8 *cis, tup, tlen, sromrev = 1; - int i, j; - bool ag_init = false; - u32 w32; - uint funcid; - uint cisnum; - s32 boardnum; - int err; - bool standard_cis; - - ASSERT(vars != NULL); - ASSERT(count != NULL); - - boardnum = -1; - - base = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); - ASSERT(base != NULL); - if (!base) - return -2; - - varbuf_init(&b, base, MAXSZ_NVRAM_VARS); - memset(base, 0, MAXSZ_NVRAM_VARS); - eabuf[0] = '\0'; - for (cisnum = 0; cisnum < ciscnt; cisnum++) { - cis = *pcis++; - i = 0; - funcid = 0; - standard_cis = true; - do { - if (standard_cis) { - tup = cis[i++]; - if (tup == CISTPL_NULL || tup == CISTPL_END) - tlen = 0; - else - tlen = cis[i++]; - } else { - if (cis[i] == CISTPL_NULL - || cis[i] == CISTPL_END) { - tlen = 0; - tup = cis[i]; - } else { - tlen = cis[i]; - tup = CISTPL_BRCM_HNBU; - } - ++i; - } - if ((i + tlen) >= CIS_SIZE) - break; - - switch (tup) { - case CISTPL_VERS_1: - /* assume the strings are good if the version field checks out */ - if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) { - varbuf_append(&b, vstr_manf, - &cis[i + 2]); - varbuf_append(&b, vstr_productname, - &cis[i + 3 + - strlen((char *) - &cis[i + - 2])]); - break; - } - - case CISTPL_MANFID: - varbuf_append(&b, vstr_manfid, - (cis[i + 1] << 8) + cis[i]); - varbuf_append(&b, vstr_prodid, - (cis[i + 3] << 8) + cis[i + 2]); - break; - - case CISTPL_FUNCID: - funcid = cis[i]; - break; - - case CISTPL_FUNCE: - switch (funcid) { - case CISTPL_FID_SDIO: -#ifdef BCMSDIO - if (cis[i] == 0) { - u8 spd = cis[i + 3]; - static int base[] = { - -1, 10, 12, 13, 15, 20, - 25, 30, - 35, 40, 45, 50, 55, 60, - 70, 80 - }; - static int mult[] = { - 10, 100, 1000, 10000, - -1, -1, -1, -1 - }; - ASSERT((mult[spd & 0x7] != -1) - && - (base - [(spd >> 3) & 0x0f])); - varbuf_append(&b, - vstr_sdmaxblk[0], - (cis[i + 2] << 8) - + cis[i + 1]); - varbuf_append(&b, - vstr_sdmaxspeed, - (mult[spd & 0x7] * - base[(spd >> 3) & - 0x0f])); - } else if (cis[i] == 1) { - varbuf_append(&b, - vstr_sdmaxblk - [cisnum], - (cis[i + 13] << 8) - | cis[i + 12]); - } -#endif /* BCMSDIO */ - funcid = 0; - break; - default: - /* set macaddr if HNBU_MACADDR not seen yet */ - if (eabuf[0] == '\0' && - cis[i] == LAN_NID && - !is_zero_ether_addr(&cis[i + 2]) && - !is_multicast_ether_addr(&cis[i + 2])) { - ASSERT(cis[i + 1] == - ETH_ALEN); - snprintf(eabuf, sizeof(eabuf), - "%pM", &cis[i + 2]); - - /* set boardnum if HNBU_BOARDNUM not seen yet */ - if (boardnum == -1) - boardnum = - (cis[i + 6] << 8) + - cis[i + 7]; - } - break; - } - break; - - case CISTPL_CFTABLE: - varbuf_append(&b, vstr_regwindowsz, - (cis[i + 7] << 8) | cis[i + 6]); - break; - - case CISTPL_BRCM_HNBU: - switch (cis[i]) { - case HNBU_SROMREV: - sromrev = cis[i + 1]; - varbuf_append(&b, vstr_sromrev, - sromrev); - break; - - case HNBU_XTALFREQ: - varbuf_append(&b, vstr_xtalfreq, - (cis[i + 4] << 24) | - (cis[i + 3] << 16) | - (cis[i + 2] << 8) | - cis[i + 1]); - break; - - case HNBU_CHIPID: - varbuf_append(&b, vstr_vendid, - (cis[i + 2] << 8) + - cis[i + 1]); - varbuf_append(&b, vstr_devid, - (cis[i + 4] << 8) + - cis[i + 3]); - if (tlen >= 7) { - varbuf_append(&b, vstr_chiprev, - (cis[i + 6] << 8) - + cis[i + 5]); - } - if (tlen >= 9) { - varbuf_append(&b, - vstr_subvendid, - (cis[i + 8] << 8) - + cis[i + 7]); - } - if (tlen >= 11) { - varbuf_append(&b, vstr_subdevid, - (cis[i + 10] << 8) - + cis[i + 9]); - /* subdevid doubles for boardtype */ - varbuf_append(&b, - vstr_boardtype, - (cis[i + 10] << 8) - + cis[i + 9]); - } - break; - - case HNBU_BOARDNUM: - boardnum = - (cis[i + 2] << 8) + cis[i + 1]; - break; - - case HNBU_PATCH: - { - char vstr_paddr[16]; - char vstr_pdata[16]; - - /* retrieve the patch pairs - * from tlen/6; where 6 is - * sizeof(patch addr(2)) + - * sizeof(patch data(4)). - */ - patch_pair = tlen / 6; - - for (j = 0; j < patch_pair; j++) { - snprintf(vstr_paddr, - sizeof - (vstr_paddr), - "pa%d=0x%%x", - j); - snprintf(vstr_pdata, - sizeof - (vstr_pdata), - "pd%d=0x%%x", - j); - - varbuf_append(&b, - vstr_paddr, - (cis - [i + - (j * - 6) + - 2] << 8) - | cis[i + - (j * - 6) - + - 1]); - - varbuf_append(&b, - vstr_pdata, - (cis - [i + - (j * - 6) + - 6] << - 24) | - (cis - [i + - (j * - 6) + - 5] << - 16) | - (cis - [i + - (j * - 6) + - 4] << 8) - | cis[i + - (j * - 6) - + - 3]); - } - } - break; - - case HNBU_BOARDREV: - if (tlen == 2) - varbuf_append(&b, vstr_boardrev, - cis[i + 1]); - else - varbuf_append(&b, vstr_boardrev, - (cis[i + 2] << 8) - + cis[i + 1]); - break; - - case HNBU_BOARDFLAGS: - w32 = (cis[i + 2] << 8) + cis[i + 1]; - if (tlen >= 5) - w32 |= - ((cis[i + 4] << 24) + - (cis[i + 3] << 16)); - varbuf_append(&b, vstr_boardflags, w32); - - if (tlen >= 7) { - w32 = - (cis[i + 6] << 8) + cis[i + - 5]; - if (tlen >= 9) - w32 |= - ((cis[i + 8] << 24) - + - (cis[i + 7] << - 16)); - varbuf_append(&b, - vstr_boardflags2, - w32); - } - break; - - case HNBU_USBFS: - varbuf_append(&b, vstr_usbfs, - cis[i + 1]); - break; - - case HNBU_BOARDTYPE: - varbuf_append(&b, vstr_boardtype, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_HNBUCIS: - /* - * what follows is a nonstandard HNBU CIS - * that lacks CISTPL_BRCM_HNBU tags - * - * skip 0xff (end of standard CIS) - * after this tuple - */ - tlen++; - standard_cis = false; - break; - - case HNBU_USBEPNUM: - varbuf_append(&b, vstr_usbepnum, - (cis[i + 2] << 8) | cis[i - + - 1]); - break; - - case HNBU_AA: - varbuf_append(&b, vstr_aa2g, - cis[i + 1]); - if (tlen >= 3) - varbuf_append(&b, vstr_aa5g, - cis[i + 2]); - break; - - case HNBU_AG: - varbuf_append(&b, vstr_ag, 0, - cis[i + 1]); - if (tlen >= 3) - varbuf_append(&b, vstr_ag, 1, - cis[i + 2]); - if (tlen >= 4) - varbuf_append(&b, vstr_ag, 2, - cis[i + 3]); - if (tlen >= 5) - varbuf_append(&b, vstr_ag, 3, - cis[i + 4]); - ag_init = true; - break; - - case HNBU_ANT5G: - varbuf_append(&b, vstr_aa5g, - cis[i + 1]); - varbuf_append(&b, vstr_ag, 1, - cis[i + 2]); - break; - - case HNBU_CC: - ASSERT(sromrev == 1); - varbuf_append(&b, vstr_cc, cis[i + 1]); - break; - - case HNBU_PAPARMS: - switch (tlen) { - case 2: - ASSERT(sromrev == 1); - varbuf_append(&b, - vstr_pa0maxpwr, - cis[i + 1]); - break; - case 10: - ASSERT(sromrev >= 2); - varbuf_append(&b, vstr_opo, - cis[i + 9]); - /* FALLTHROUGH */ - case 9: - varbuf_append(&b, - vstr_pa0maxpwr, - cis[i + 8]); - /* FALLTHROUGH */ - BCMDONGLECASE(8) - varbuf_append(&b, - vstr_pa0itssit, - cis[i + 7]); - /* FALLTHROUGH */ - BCMDONGLECASE(7) - for (j = 0; j < 3; j++) { - varbuf_append(&b, - vstr_pa0b - [j], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - break; - default: - ASSERT((tlen == 2) - || (tlen == 9) - || (tlen == 10)); - break; - } - break; - - case HNBU_PAPARMS5G: - ASSERT((sromrev == 2) - || (sromrev == 3)); - switch (tlen) { - case 23: - varbuf_append(&b, - vstr_pa1himaxpwr, - cis[i + 22]); - varbuf_append(&b, - vstr_pa1lomaxpwr, - cis[i + 21]); - varbuf_append(&b, - vstr_pa1maxpwr, - cis[i + 20]); - /* FALLTHROUGH */ - case 20: - varbuf_append(&b, - vstr_pa1itssit, - cis[i + 19]); - /* FALLTHROUGH */ - case 19: - for (j = 0; j < 3; j++) { - varbuf_append(&b, - vstr_pa1b - [j], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - for (j = 3; j < 6; j++) { - varbuf_append(&b, - vstr_pa1lob - [j - 3], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - for (j = 6; j < 9; j++) { - varbuf_append(&b, - vstr_pa1hib - [j - 6], - (cis - [i + - (j * - 2) + - 2] << 8) - + cis[i + - (j * - 2) - + - 1]); - } - break; - default: - ASSERT((tlen == 19) || - (tlen == 20) - || (tlen == 23)); - break; - } - break; - - case HNBU_OEM: - ASSERT(sromrev == 1); - varbuf_append(&b, vstr_oem, - cis[i + 1], cis[i + 2], - cis[i + 3], cis[i + 4], - cis[i + 5], cis[i + 6], - cis[i + 7], cis[i + 8]); - break; - - case HNBU_LEDS: - for (j = 1; j <= 4; j++) { - if (cis[i + j] != 0xff) { - varbuf_append(&b, - vstr_ledbh, - j - 1, - cis[i + - j]); - } - } - break; - - case HNBU_CCODE: - ASSERT(sromrev > 1); - if ((cis[i + 1] == 0) - || (cis[i + 2] == 0)) - varbuf_append(&b, vstr_noccode); - else - varbuf_append(&b, vstr_ccode, - cis[i + 1], - cis[i + 2]); - varbuf_append(&b, vstr_cctl, - cis[i + 3]); - break; - - case HNBU_CCKPO: - ASSERT(sromrev > 2); - varbuf_append(&b, vstr_cckpo, - (cis[i + 2] << 8) | cis[i - + - 1]); - break; - - case HNBU_OFDMPO: - ASSERT(sromrev > 2); - varbuf_append(&b, vstr_ofdmpo, - (cis[i + 4] << 24) | - (cis[i + 3] << 16) | - (cis[i + 2] << 8) | - cis[i + 1]); - break; - - case HNBU_WPS: - varbuf_append(&b, vstr_wpsgpio, - cis[i + 1]); - if (tlen >= 3) - varbuf_append(&b, vstr_wpsled, - cis[i + 2]); - break; - - case HNBU_RSSISMBXA2G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rssismf2g, - cis[i + 1] & 0xf); - varbuf_append(&b, vstr_rssismc2g, - (cis[i + 1] >> 4) & 0xf); - varbuf_append(&b, vstr_rssisav2g, - cis[i + 2] & 0x7); - varbuf_append(&b, vstr_bxa2g, - (cis[i + 2] >> 3) & 0x3); - break; - - case HNBU_RSSISMBXA5G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rssismf5g, - cis[i + 1] & 0xf); - varbuf_append(&b, vstr_rssismc5g, - (cis[i + 1] >> 4) & 0xf); - varbuf_append(&b, vstr_rssisav5g, - cis[i + 2] & 0x7); - varbuf_append(&b, vstr_bxa5g, - (cis[i + 2] >> 3) & 0x3); - break; - - case HNBU_TRI2G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_tri2g, - cis[i + 1]); - break; - - case HNBU_TRI5G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_tri5gl, - cis[i + 1]); - varbuf_append(&b, vstr_tri5g, - cis[i + 2]); - varbuf_append(&b, vstr_tri5gh, - cis[i + 3]); - break; - - case HNBU_RXPO2G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rxpo2g, - cis[i + 1]); - break; - - case HNBU_RXPO5G: - ASSERT(sromrev == 3); - varbuf_append(&b, vstr_rxpo5g, - cis[i + 1]); - break; - - case HNBU_MACADDR: - if (!is_zero_ether_addr(&cis[i + 1]) && - !is_multicast_ether_addr(&cis[i + 1])) { - snprintf(eabuf, sizeof(eabuf), - "%pM", &cis[i + 1]); - - /* set boardnum if HNBU_BOARDNUM not seen yet */ - if (boardnum == -1) - boardnum = - (cis[i + 5] << 8) + - cis[i + 6]; - } - break; - - case HNBU_LEDDC: - /* CIS leddc only has 16bits, convert it to 32bits */ - w32 = ((cis[i + 2] << 24) | /* oncount */ - (cis[i + 1] << 8)); /* offcount */ - varbuf_append(&b, vstr_leddc, w32); - break; - - case HNBU_CHAINSWITCH: - varbuf_append(&b, vstr_txchain, - cis[i + 1]); - varbuf_append(&b, vstr_rxchain, - cis[i + 2]); - varbuf_append(&b, vstr_antswitch, - (cis[i + 4] << 8) + - cis[i + 3]); - break; - - case HNBU_REGREV: - varbuf_append(&b, vstr_regrev, - cis[i + 1]); - break; - - case HNBU_FEM:{ - u16 fem = - (cis[i + 2] << 8) + cis[i + - 1]; - varbuf_append(&b, - vstr_antswctl2g, - (fem & - SROM8_FEM_ANTSWLUT_MASK) - >> - SROM8_FEM_ANTSWLUT_SHIFT); - varbuf_append(&b, vstr_triso2g, - (fem & - SROM8_FEM_TR_ISO_MASK) - >> - SROM8_FEM_TR_ISO_SHIFT); - varbuf_append(&b, - vstr_pdetrange2g, - (fem & - SROM8_FEM_PDET_RANGE_MASK) - >> - SROM8_FEM_PDET_RANGE_SHIFT); - varbuf_append(&b, - vstr_extpagain2g, - (fem & - SROM8_FEM_EXTPA_GAIN_MASK) - >> - SROM8_FEM_EXTPA_GAIN_SHIFT); - varbuf_append(&b, - vstr_tssipos2g, - (fem & - SROM8_FEM_TSSIPOS_MASK) - >> - SROM8_FEM_TSSIPOS_SHIFT); - if (tlen < 5) - break; - - fem = - (cis[i + 4] << 8) + cis[i + - 3]; - varbuf_append(&b, - vstr_antswctl5g, - (fem & - SROM8_FEM_ANTSWLUT_MASK) - >> - SROM8_FEM_ANTSWLUT_SHIFT); - varbuf_append(&b, vstr_triso5g, - (fem & - SROM8_FEM_TR_ISO_MASK) - >> - SROM8_FEM_TR_ISO_SHIFT); - varbuf_append(&b, - vstr_pdetrange5g, - (fem & - SROM8_FEM_PDET_RANGE_MASK) - >> - SROM8_FEM_PDET_RANGE_SHIFT); - varbuf_append(&b, - vstr_extpagain5g, - (fem & - SROM8_FEM_EXTPA_GAIN_MASK) - >> - SROM8_FEM_EXTPA_GAIN_SHIFT); - varbuf_append(&b, - vstr_tssipos5g, - (fem & - SROM8_FEM_TSSIPOS_MASK) - >> - SROM8_FEM_TSSIPOS_SHIFT); - break; - } - - case HNBU_PAPARMS_C0: - varbuf_append(&b, vstr_maxp2ga0, - cis[i + 1]); - varbuf_append(&b, vstr_itt2ga0, - cis[i + 2]); - varbuf_append(&b, vstr_pa, 2, 0, 0, - (cis[i + 4] << 8) + - cis[i + 3]); - varbuf_append(&b, vstr_pa, 2, 1, 0, - (cis[i + 6] << 8) + - cis[i + 5]); - varbuf_append(&b, vstr_pa, 2, 2, 0, - (cis[i + 8] << 8) + - cis[i + 7]); - if (tlen < 31) - break; - - varbuf_append(&b, vstr_maxp5ga0, - cis[i + 9]); - varbuf_append(&b, vstr_itt5ga0, - cis[i + 10]); - varbuf_append(&b, vstr_maxp5gha0, - cis[i + 11]); - varbuf_append(&b, vstr_maxp5gla0, - cis[i + 12]); - varbuf_append(&b, vstr_pa, 5, 0, 0, - (cis[i + 14] << 8) + - cis[i + 13]); - varbuf_append(&b, vstr_pa, 5, 1, 0, - (cis[i + 16] << 8) + - cis[i + 15]); - varbuf_append(&b, vstr_pa, 5, 2, 0, - (cis[i + 18] << 8) + - cis[i + 17]); - varbuf_append(&b, vstr_pahl, 5, 'l', 0, - 0, - (cis[i + 20] << 8) + - cis[i + 19]); - varbuf_append(&b, vstr_pahl, 5, 'l', 1, - 0, - (cis[i + 22] << 8) + - cis[i + 21]); - varbuf_append(&b, vstr_pahl, 5, 'l', 2, - 0, - (cis[i + 24] << 8) + - cis[i + 23]); - varbuf_append(&b, vstr_pahl, 5, 'h', 0, - 0, - (cis[i + 26] << 8) + - cis[i + 25]); - varbuf_append(&b, vstr_pahl, 5, 'h', 1, - 0, - (cis[i + 28] << 8) + - cis[i + 27]); - varbuf_append(&b, vstr_pahl, 5, 'h', 2, - 0, - (cis[i + 30] << 8) + - cis[i + 29]); - break; - - case HNBU_PAPARMS_C1: - varbuf_append(&b, vstr_maxp2ga1, - cis[i + 1]); - varbuf_append(&b, vstr_itt2ga1, - cis[i + 2]); - varbuf_append(&b, vstr_pa, 2, 0, 1, - (cis[i + 4] << 8) + - cis[i + 3]); - varbuf_append(&b, vstr_pa, 2, 1, 1, - (cis[i + 6] << 8) + - cis[i + 5]); - varbuf_append(&b, vstr_pa, 2, 2, 1, - (cis[i + 8] << 8) + - cis[i + 7]); - if (tlen < 31) - break; - - varbuf_append(&b, vstr_maxp5ga1, - cis[i + 9]); - varbuf_append(&b, vstr_itt5ga1, - cis[i + 10]); - varbuf_append(&b, vstr_maxp5gha1, - cis[i + 11]); - varbuf_append(&b, vstr_maxp5gla1, - cis[i + 12]); - varbuf_append(&b, vstr_pa, 5, 0, 1, - (cis[i + 14] << 8) + - cis[i + 13]); - varbuf_append(&b, vstr_pa, 5, 1, 1, - (cis[i + 16] << 8) + - cis[i + 15]); - varbuf_append(&b, vstr_pa, 5, 2, 1, - (cis[i + 18] << 8) + - cis[i + 17]); - varbuf_append(&b, vstr_pahl, 5, 'l', 0, - 1, - (cis[i + 20] << 8) + - cis[i + 19]); - varbuf_append(&b, vstr_pahl, 5, 'l', 1, - 1, - (cis[i + 22] << 8) + - cis[i + 21]); - varbuf_append(&b, vstr_pahl, 5, 'l', 2, - 1, - (cis[i + 24] << 8) + - cis[i + 23]); - varbuf_append(&b, vstr_pahl, 5, 'h', 0, - 1, - (cis[i + 26] << 8) + - cis[i + 25]); - varbuf_append(&b, vstr_pahl, 5, 'h', 1, - 1, - (cis[i + 28] << 8) + - cis[i + 27]); - varbuf_append(&b, vstr_pahl, 5, 'h', 2, - 1, - (cis[i + 30] << 8) + - cis[i + 29]); - break; - - case HNBU_PO_CCKOFDM: - varbuf_append(&b, vstr_cck2gpo, - (cis[i + 2] << 8) + - cis[i + 1]); - varbuf_append(&b, vstr_ofdm2gpo, - (cis[i + 6] << 24) + - (cis[i + 5] << 16) + - (cis[i + 4] << 8) + - cis[i + 3]); - if (tlen < 19) - break; - - varbuf_append(&b, vstr_ofdm5gpo, - (cis[i + 10] << 24) + - (cis[i + 9] << 16) + - (cis[i + 8] << 8) + - cis[i + 7]); - varbuf_append(&b, vstr_ofdm5glpo, - (cis[i + 14] << 24) + - (cis[i + 13] << 16) + - (cis[i + 12] << 8) + - cis[i + 11]); - varbuf_append(&b, vstr_ofdm5ghpo, - (cis[i + 18] << 24) + - (cis[i + 17] << 16) + - (cis[i + 16] << 8) + - cis[i + 15]); - break; - - case HNBU_PO_MCS2G: - for (j = 0; j <= (tlen / 2); j++) { - varbuf_append(&b, vstr_mcspo, 2, - j, - (cis - [i + 2 + - 2 * j] << 8) + - cis[i + 1 + - 2 * j]); - } - break; - - case HNBU_PO_MCS5GM: - for (j = 0; j <= (tlen / 2); j++) { - varbuf_append(&b, vstr_mcspo, 5, - j, - (cis - [i + 2 + - 2 * j] << 8) + - cis[i + 1 + - 2 * j]); - } - break; - - case HNBU_PO_MCS5GLH: - for (j = 0; j <= (tlen / 4); j++) { - varbuf_append(&b, vstr_mcspohl, - 5, 'l', j, - (cis - [i + 2 + - 2 * j] << 8) + - cis[i + 1 + - 2 * j]); - } - - for (j = 0; j <= (tlen / 4); j++) { - varbuf_append(&b, vstr_mcspohl, - 5, 'h', j, - (cis - [i + - ((tlen / 2) + - 2) + - 2 * j] << 8) + - cis[i + - ((tlen / 2) + - 1) + 2 * j]); - } - - break; - - case HNBU_PO_CDD: - varbuf_append(&b, vstr_cddpo, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_PO_STBC: - varbuf_append(&b, vstr_stbcpo, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_PO_40M: - varbuf_append(&b, vstr_bw40po, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_PO_40MDUP: - varbuf_append(&b, vstr_bwduppo, - (cis[i + 2] << 8) + - cis[i + 1]); - break; - - case HNBU_OFDMPO5G: - varbuf_append(&b, vstr_ofdm5gpo, - (cis[i + 4] << 24) + - (cis[i + 3] << 16) + - (cis[i + 2] << 8) + - cis[i + 1]); - varbuf_append(&b, vstr_ofdm5glpo, - (cis[i + 8] << 24) + - (cis[i + 7] << 16) + - (cis[i + 6] << 8) + - cis[i + 5]); - varbuf_append(&b, vstr_ofdm5ghpo, - (cis[i + 12] << 24) + - (cis[i + 11] << 16) + - (cis[i + 10] << 8) + - cis[i + 9]); - break; - - case HNBU_CUSTOM1: - varbuf_append(&b, vstr_custom, 1, - ((cis[i + 4] << 24) + - (cis[i + 3] << 16) + - (cis[i + 2] << 8) + - cis[i + 1])); - break; - -#if defined(BCMSDIO) - case HNBU_SROM3SWRGN: - if (tlen >= 73) { - u16 srom[35]; - u8 srev = cis[i + 1 + 70]; - ASSERT(srev == 3); - /* make tuple value 16-bit aligned and parse it */ - memcpy(srom, &cis[i + 1], - sizeof(srom)); - _initvars_srom_pci(srev, srom, - SROM3_SWRGN_OFF, - &b); - /* 2.4G antenna gain is included in SROM */ - ag_init = true; - /* Ethernet MAC address is included in SROM */ - eabuf[0] = 0; - boardnum = -1; - } - /* create extra variables */ - if (tlen >= 75) - varbuf_append(&b, vstr_vendid, - (cis[i + 1 + 73] - << 8) + cis[i + - 1 + - 72]); - if (tlen >= 77) - varbuf_append(&b, vstr_devid, - (cis[i + 1 + 75] - << 8) + cis[i + - 1 + - 74]); - if (tlen >= 79) - varbuf_append(&b, vstr_xtalfreq, - (cis[i + 1 + 77] - << 8) + cis[i + - 1 + - 76]); - break; -#endif /* defined(BCMSDIO) */ - - case HNBU_CCKFILTTYPE: - varbuf_append(&b, vstr_cckdigfilttype, - (cis[i + 1])); - break; - } - - break; - } - i += tlen; - } while (tup != CISTPL_END); - } - - if (boardnum != -1) { - varbuf_append(&b, vstr_boardnum, boardnum); - } - - if (eabuf[0]) { - varbuf_append(&b, vstr_macaddr, eabuf); - } - - /* if there is no antenna gain field, set default */ - if (getvar(NULL, "ag0") == NULL && ag_init == false) { - varbuf_append(&b, vstr_ag, 0, 0xff); - } - - /* final nullbyte terminator */ - ASSERT(b.size >= 1); - *b.buf++ = '\0'; - - ASSERT(b.buf - base <= MAXSZ_NVRAM_VARS); - err = initvars_table(base, b.buf, vars, count); - - kfree(base); - return err; -} - /* In chips with chipcommon rev 32 and later, the srom is in chipcommon, * not in the bus cores. */ -- GitLab From be1c09f987ff523e7299cd8322a176dc80d8f66d Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 28 Mar 2011 01:31:36 +0400 Subject: [PATCH 0415/5560] brcm80211: replace VENDOR_BROADCOM with PCI_VENDOR_ID_BROADCOM use Linux native defines Signed-off-by: Stanislav Fomichev Acked-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 3 ++- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 6 +++--- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 3 ++- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 3 ++- drivers/staging/brcm80211/include/bcmdevs.h | 3 --- drivers/staging/brcm80211/util/siutils.c | 6 +++--- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 473f57d9f00b..f15ee63e5f28 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -580,7 +581,7 @@ int bcmsdh_stop(void *sdh) int bcmsdh_query_device(void *sdh) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0; + bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0; return bcmsdh->vendevid; } diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index ac5bbc8722e5..0188417b6593 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -87,11 +87,11 @@ bool bcmsdh_chipmatch(u16 vendor, u16 device) return true; /* Check for BRCM 27XX Standard host controller */ - if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) + if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM) return true; /* Check for BRCM Standard host controller */ - if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) + if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) return true; /* Check for TI PCIxx21 Standard host controller */ @@ -111,7 +111,7 @@ bool bcmsdh_chipmatch(u16 vendor, u16 device) #endif /* BCMSDIOH_STD */ #ifdef BCMSDIOH_SPI /* This is the PciSpiHost. */ - if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { + if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) { WL_NONE("Found PCI SPI Host Controller\n"); return true; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 106627040db0..1111920b0da1 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -5089,7 +5090,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, /* Check the Vendor ID */ switch (venid) { case 0x0000: - case VENDOR_BROADCOM: + case PCI_VENDOR_ID_BROADCOM: break; default: DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid)); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 31716785b61d..f7dab5485bf4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -2034,7 +2034,7 @@ static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) goodboard = false; } - if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM) + if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM) return goodboard; return goodboard; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 6a4126f7ecf1..ccad6b8d6416 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -4871,7 +4872,7 @@ void wlc_statsupd(struct wlc_info *wlc) bool wlc_chipmatch(u16 vendor, u16 device) { - if (vendor != VENDOR_BROADCOM) { + if (vendor != PCI_VENDOR_ID_BROADCOM) { WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); return false; } diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h index 075883a93529..7ccb25247209 100644 --- a/drivers/staging/brcm80211/include/bcmdevs.h +++ b/drivers/staging/brcm80211/include/bcmdevs.h @@ -17,9 +17,6 @@ #ifndef _BCMDEVS_H #define _BCMDEVS_H -/* PCI vendor IDs */ -#define VENDOR_BROADCOM 0x14e4 - /* DONGLE VID/PIDs */ #define BCM_DNGL_VID 0x0a5c #define BCM_DNGL_BDC_PID 0x0bdc diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index a77b457e28be..65b3ef3fc3e9 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -337,14 +337,14 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) #ifdef BCMSDIO case SPI_BUS: - sii->pub.boardvendor = VENDOR_BROADCOM; + sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM; sii->pub.boardtype = SPI_BOARD; break; #endif case SI_BUS: case JTAG_BUS: - sii->pub.boardvendor = VENDOR_BROADCOM; + sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM; sii->pub.boardtype = getintvar(pvars, "prodid"); if (pvars == NULL || (sii->pub.boardtype == 0)) { sii->pub.boardtype = getintvar(NULL, "boardtype"); @@ -1865,7 +1865,7 @@ bool si_deviceremoved(si_t *sih) case PCI_BUS: ASSERT(sii->pbus != NULL); pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w); - if ((w & 0xFFFF) != VENDOR_BROADCOM) + if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) return true; break; } -- GitLab From e7c7add92cf073bb81ee11bb3e63a0e1f83d6658 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 28 Mar 2011 01:31:37 +0400 Subject: [PATCH 0416/5560] brcm80211: remove unused defines in bcmdevs.h Signed-off-by: Stanislav Fomichev Acked-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmdevs.h | 69 +-------------------- 1 file changed, 2 insertions(+), 67 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h index 7ccb25247209..26947efa83e8 100644 --- a/drivers/staging/brcm80211/include/bcmdevs.h +++ b/drivers/staging/brcm80211/include/bcmdevs.h @@ -17,14 +17,10 @@ #ifndef _BCMDEVS_H #define _BCMDEVS_H -/* DONGLE VID/PIDs */ -#define BCM_DNGL_VID 0x0a5c -#define BCM_DNGL_BDC_PID 0x0bdc - #define BCM4325_D11DUAL_ID 0x431b #define BCM4325_D11G_ID 0x431c #define BCM4325_D11A_ID 0x431d -#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */ + #define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ #define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ #define BCM4329_D11NDUAL_ID 0x432e @@ -34,22 +30,13 @@ #define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ #define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ + #define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ #define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ #define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ -#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */ -#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */ #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ -#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */ -#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */ -#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */ -#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */ -#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */ -#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ -#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */ -#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */ /* Chip IDs */ #define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ @@ -57,7 +44,6 @@ #define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ #define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ -#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */ #define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */ #define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ #define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ @@ -79,57 +65,23 @@ /* Package IDs */ #define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ #define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ -#define BCM4716_PKG_ID 8 /* 4716 package id */ #define BCM4717_PKG_ID 9 /* 4717 package id */ #define BCM4718_PKG_ID 10 /* 4718 package id */ -#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */ -#define BCM5358U_PKG_ID 8 /* 5358U package id */ -#define BCM5358_PKG_ID 9 /* 5358 package id */ -#define BCM47186_PKG_ID 10 /* 47186 package id */ -#define BCM5357_PKG_ID 11 /* 5357 package id */ -#define BCM5356U_PKG_ID 12 /* 5356U package id */ -#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ #define HDLSIM_PKG_ID 14 /* HDL simulator package id */ #define HWSIM_PKG_ID 15 /* Hardware simulator package id */ -#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */ #define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ -#define BCM4336_WLBGA_PKG_ID 0x8 /* boardflags */ -#define BFL_RESERVED1 0x00000001 #define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ -#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication */ -#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */ -#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */ #define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ -#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */ -#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */ -#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */ -#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ #define BFL_FEM 0x00000800 /* Board supports the Front End Module */ #define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -#define BFL_HGPA 0x00002000 /* Board has a high gain PA */ -#define BFL_RESERVED2 0x00004000 -#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */ #define BFL_NOPA 0x00010000 /* Board has no PA */ -#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */ -#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */ -#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */ -#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */ #define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ #define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ #define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ -#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */ #define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ -#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */ -#define BFL_FASTPWR 0x08000000 -#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ #define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ -#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ -#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ -#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field - * when this flag is set - */ /* boardflags2 */ #define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ @@ -138,16 +90,12 @@ #define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ #define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ #define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ -#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */ #define BFL2_LEGACY 0x00000080 #define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ #define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ #define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ -#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */ #define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ #define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ -#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */ -#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* using 40Mhz LPF for 20Mhz bandedge channels */ #define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ #define BFL2_IPALVLSHIFT_3P3 0x00020000 #define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ @@ -157,32 +105,19 @@ */ /* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -#define BOARD_GPIO_RESERVED1 0x010 -#define BOARD_GPIO_RESERVED2 0x020 -#define BOARD_GPIO_RESERVED3 0x080 -#define BOARD_GPIO_RESERVED4 0x100 #define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ #define BOARD_GPIO_12 0x1000 /* gpio 12 */ #define BOARD_GPIO_13 0x2000 /* gpio 13 */ -#define BOARD_GPIO_RESERVED5 0x0800 -#define BOARD_GPIO_RESERVED6 0x2000 -#define BOARD_GPIO_RESERVED7 0x4000 -#define BOARD_GPIO_RESERVED8 0x8000 #define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ #define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ #define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ /* power control defines */ #define PLL_DELAY 150 /* us pll on delay */ #define FREF_DELAY 200 /* us fref change delay */ -#define MIN_SLOW_CLK 32 /* us Slow clock period */ #define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ -/* # of GPIO pins */ -#define GPIO_NUMPINS 16 - /* Reference board types */ #define SPI_BOARD 0x0402 -- GitLab From 0997325e31737e90626baac80ab687e51500b2ef Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 28 Mar 2011 01:31:38 +0400 Subject: [PATCH 0417/5560] brcm80211: remove unused defines in pcicfg.h Signed-off-by: Stanislav Fomichev Acked-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/pcicfg.h | 345 +-------------------- 1 file changed, 1 insertion(+), 344 deletions(-) diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h index 675554a1d341..a3569e48ddf0 100644 --- a/drivers/staging/brcm80211/include/pcicfg.h +++ b/drivers/staging/brcm80211/include/pcicfg.h @@ -17,87 +17,12 @@ #ifndef _h_pcicfg_ #define _h_pcicfg_ -/* The following inside ifndef's so we don't collide with NTDDK.H */ -#ifndef PCI_MAX_BUS -#define PCI_MAX_BUS 0x100 -#endif -#ifndef PCI_MAX_DEVICES -#define PCI_MAX_DEVICES 0x20 -#endif -#ifndef PCI_MAX_FUNCTION -#define PCI_MAX_FUNCTION 0x8 -#endif - -#ifndef PCI_INVALID_VENDORID -#define PCI_INVALID_VENDORID 0xffff -#endif -#ifndef PCI_INVALID_DEVICEID -#define PCI_INVALID_DEVICEID 0xffff -#endif - -/* Convert between bus-slot-function-register and config addresses */ - -#define PCICFG_BUS_SHIFT 16 /* Bus shift */ -#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ -#define PCICFG_FUN_SHIFT 8 /* Function shift */ -#define PCICFG_OFF_SHIFT 0 /* Register shift */ - -#define PCICFG_BUS_MASK 0xff /* Bus mask */ -#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ -#define PCICFG_FUN_MASK 7 /* Function mask */ -#define PCICFG_OFF_MASK 0xff /* Bus mask */ - -#define PCI_CONFIG_ADDR(b, s, f, o) \ - ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ - | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ - | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ - | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) - -#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) -#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) -#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) -#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) - -/* PCIE Config space accessing MACROS */ - -#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ -#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ -#define PCIECFG_FUN_SHIFT 16 /* Function shift */ -#define PCIECFG_OFF_SHIFT 0 /* Register shift */ - -#define PCIECFG_BUS_MASK 0xff /* Bus mask */ -#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ -#define PCIECFG_FUN_MASK 7 /* Function mask */ -#define PCIECFG_OFF_MASK 0xfff /* Register mask */ - -#define PCIE_CONFIG_ADDR(b, s, f, o) \ - ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ - | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ - | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ - | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) - -#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) -#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) -#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) -#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) - /* The actual config space */ #define PCI_BAR_MAX 6 -#define PCI_ROM_BAR 8 - #define PCR_RSVDA_MAX 2 -/* Bits in PCI bars' flags */ - -#define PCIBAR_FLAGS 0xf -#define PCIBAR_IO 0x1 -#define PCIBAR_MEM1M 0x2 -#define PCIBAR_MEM64 0x4 -#define PCIBAR_PREFETCH 0x8 -#define PCIBAR_MEM32_MASK 0xFFFFFF80 - /* pci config status reg has a bit to indicate that capability ptr is present */ #define PCI_CAPPTR_PRESENT 0x0010 @@ -165,164 +90,9 @@ typedef struct _pci_config_regs { /* Classes and subclasses */ -typedef enum { - PCI_CLASS_OLD = 0, - PCI_CLASS_DASDI, - PCI_CLASS_NET, - PCI_CLASS_DISPLAY, - PCI_CLASS_MMEDIA, - PCI_CLASS_MEMORY, - PCI_CLASS_BRIDGE, - PCI_CLASS_COMM, - PCI_CLASS_BASE, - PCI_CLASS_INPUT, - PCI_CLASS_DOCK, - PCI_CLASS_CPU, - PCI_CLASS_SERIAL, - PCI_CLASS_INTELLIGENT = 0xe, - PCI_CLASS_SATELLITE, - PCI_CLASS_CRYPT, - PCI_CLASS_DSP, - PCI_CLASS_XOR = 0xfe -} pci_classes; - -typedef enum { - PCI_DASDI_SCSI, - PCI_DASDI_IDE, - PCI_DASDI_FLOPPY, - PCI_DASDI_IPI, - PCI_DASDI_RAID, - PCI_DASDI_OTHER = 0x80 -} pci_dasdi_subclasses; - -typedef enum { - PCI_NET_ETHER, - PCI_NET_TOKEN, - PCI_NET_FDDI, - PCI_NET_ATM, - PCI_NET_OTHER = 0x80 -} pci_net_subclasses; - -typedef enum { - PCI_DISPLAY_VGA, - PCI_DISPLAY_XGA, - PCI_DISPLAY_3D, - PCI_DISPLAY_OTHER = 0x80 -} pci_display_subclasses; - -typedef enum { - PCI_MMEDIA_VIDEO, - PCI_MMEDIA_AUDIO, - PCI_MMEDIA_PHONE, - PCI_MEDIA_OTHER = 0x80 -} pci_mmedia_subclasses; - -typedef enum { - PCI_MEMORY_RAM, - PCI_MEMORY_FLASH, - PCI_MEMORY_OTHER = 0x80 -} pci_memory_subclasses; - -typedef enum { - PCI_BRIDGE_HOST, - PCI_BRIDGE_ISA, - PCI_BRIDGE_EISA, - PCI_BRIDGE_MC, - PCI_BRIDGE_PCI, - PCI_BRIDGE_PCMCIA, - PCI_BRIDGE_NUBUS, - PCI_BRIDGE_CARDBUS, - PCI_BRIDGE_RACEWAY, - PCI_BRIDGE_OTHER = 0x80 -} pci_bridge_subclasses; - -typedef enum { - PCI_COMM_UART, - PCI_COMM_PARALLEL, - PCI_COMM_MULTIUART, - PCI_COMM_MODEM, - PCI_COMM_OTHER = 0x80 -} pci_comm_subclasses; - -typedef enum { - PCI_BASE_PIC, - PCI_BASE_DMA, - PCI_BASE_TIMER, - PCI_BASE_RTC, - PCI_BASE_PCI_HOTPLUG, - PCI_BASE_OTHER = 0x80 -} pci_base_subclasses; - -typedef enum { - PCI_INPUT_KBD, - PCI_INPUT_PEN, - PCI_INPUT_MOUSE, - PCI_INPUT_SCANNER, - PCI_INPUT_GAMEPORT, - PCI_INPUT_OTHER = 0x80 -} pci_input_subclasses; - -typedef enum { - PCI_DOCK_GENERIC, - PCI_DOCK_OTHER = 0x80 -} pci_dock_subclasses; - -typedef enum { - PCI_CPU_386, - PCI_CPU_486, - PCI_CPU_PENTIUM, - PCI_CPU_ALPHA = 0x10, - PCI_CPU_POWERPC = 0x20, - PCI_CPU_MIPS = 0x30, - PCI_CPU_COPROC = 0x40, - PCI_CPU_OTHER = 0x80 -} pci_cpu_subclasses; - -typedef enum { - PCI_SERIAL_IEEE1394, - PCI_SERIAL_ACCESS, - PCI_SERIAL_SSA, - PCI_SERIAL_USB, - PCI_SERIAL_FIBER, - PCI_SERIAL_SMBUS, - PCI_SERIAL_OTHER = 0x80 -} pci_serial_subclasses; - -typedef enum { - PCI_INTELLIGENT_I2O -} pci_intelligent_subclasses; - -typedef enum { - PCI_SATELLITE_TV, - PCI_SATELLITE_AUDIO, - PCI_SATELLITE_VOICE, - PCI_SATELLITE_DATA, - PCI_SATELLITE_OTHER = 0x80 -} pci_satellite_subclasses; - -typedef enum { - PCI_CRYPT_NETWORK, - PCI_CRYPT_ENTERTAINMENT, - PCI_CRYPT_OTHER = 0x80 -} pci_crypt_subclasses; - -typedef enum { - PCI_DSP_DPIO, - PCI_DSP_OTHER = 0x80 -} pci_dsp_subclasses; - -typedef enum { - PCI_XOR_QDMA, - PCI_XOR_OTHER = 0x80 -} pci_xor_subclasses; - /* Header types */ -#define PCI_HEADER_MULTI 0x80 -#define PCI_HEADER_MASK 0x7f typedef enum { - PCI_HEADER_NORMAL, - PCI_HEADER_BRIDGE, - PCI_HEADER_CARDBUS + PCI_HEADER_NORMAL } pci_header_types; /* Overlay for a PCI-to-PCI bridge */ @@ -374,113 +144,24 @@ typedef struct _ppb_config_regs { /* PCI CAPABILITY DEFINES */ #define PCI_CAP_POWERMGMTCAP_ID 0x01 -#define PCI_CAP_MSICAP_ID 0x05 -#define PCI_CAP_VENDSPEC_ID 0x09 #define PCI_CAP_PCIECAP_ID 0x10 -/* Data structure to define the Message Signalled Interrupt facility - * Valid for PCI and PCIE configurations - */ -typedef struct _pciconfig_cap_msi { - u8 capID; - u8 nextptr; - u16 msgctrl; - u32 msgaddr; -} pciconfig_cap_msi; - -/* Data structure to define the Power management facility - * Valid for PCI and PCIE configurations - */ -typedef struct _pciconfig_cap_pwrmgmt { - u8 capID; - u8 nextptr; - u16 pme_cap; - u16 pme_sts_ctrl; - u8 pme_bridge_ext; - u8 data; -} pciconfig_cap_pwrmgmt; - #define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */ #define PME_CSR_OFFSET 0x4 /* 4-bytes offset */ #define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */ #define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */ -/* Data structure to define the PCIE capability */ -typedef struct _pciconfig_cap_pcie { - u8 capID; - u8 nextptr; - u16 pcie_cap; - u32 dev_cap; - u16 dev_ctrl; - u16 dev_status; - u32 link_cap; - u16 link_ctrl; - u16 link_status; - u32 slot_cap; - u16 slot_ctrl; - u16 slot_status; - u16 root_ctrl; - u16 root_cap; - u32 root_status; -} pciconfig_cap_pcie; - -/* PCIE Enhanced CAPABILITY DEFINES */ -#define PCIE_EXTCFG_OFFSET 0x100 -#define PCIE_ADVERRREP_CAPID 0x0001 -#define PCIE_VC_CAPID 0x0002 -#define PCIE_DEVSNUM_CAPID 0x0003 -#define PCIE_PWRBUDGET_CAPID 0x0004 - -/* PCIE Extended configuration */ -#define PCIE_ADV_CORR_ERR_MASK 0x114 -#define CORR_ERR_RE (1 << 0) /* Receiver */ -#define CORR_ERR_BT (1 << 6) /* Bad TLP */ -#define CORR_ERR_BD (1 << 7) /* Bad DLLP */ -#define CORR_ERR_RR (1 << 8) /* REPLAY_NUM rollover */ -#define CORR_ERR_RT (1 << 12) /* Reply timer timeout */ -#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \ - CORR_ERR_RR | CORR_ERR_RT) - -/* PCIE Root Control Register bits (Host mode only) */ -#define PCIE_RC_CORR_SERR_EN 0x0001 -#define PCIE_RC_NONFATAL_SERR_EN 0x0002 -#define PCIE_RC_FATAL_SERR_EN 0x0004 -#define PCIE_RC_PME_INT_EN 0x0008 -#define PCIE_RC_CRS_EN 0x0010 - -/* PCIE Root Capability Register bits (Host mode only) */ -#define PCIE_RC_CRS_VISIBILITY 0x0001 - -/* Header to define the PCIE specific capabilities in the extended config space */ -typedef struct _pcie_enhanced_caphdr { - u16 capID; - u16 cap_ver:4; - u16 next_ptr:12; -} pcie_enhanced_caphdr; - /* Everything below is BRCM HND proprietary */ /* Brcm PCI configuration registers */ -#define cap_list rsvd_a[0] -#define bar0_window dev_dep[0x80 - 0x40] -#define bar1_window dev_dep[0x84 - 0x40] -#define sprom_control dev_dep[0x88 - 0x40] #define PCI_BAR0_WIN 0x80 /* backplane address space accessed by BAR0 */ -#define PCI_BAR1_WIN 0x84 /* backplane address space accessed by BAR1 */ #define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ -#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ #define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ -#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */ -#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */ -#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */ #define PCI_BAR0_WIN2 0xac /* backplane address space accessed by second 4KB of BAR0 */ #define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ #define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ #define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ -#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */ #define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ #define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ #define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the @@ -491,34 +172,10 @@ typedef struct _pcie_enhanced_caphdr { /* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ #define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ #define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ -#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ - -/* On AI chips we have a second window to map DMP regs are mapped: */ -#define PCI_16KB0_WIN2_OFFSET (4 * 1024) /* bar0 + 4K is "Window 2" */ -/* PCI_INT_STATUS */ #define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ /* PCI_INT_MASK */ #define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ -#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ - -/* PCI_SPROM_CONTROL */ -#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */ -#define SPROM_LOCKED 0x08 /* SPROM Locked */ -#define SPROM_BLANK 0x04 /* indicating a blank SPROM */ -#define SPROM_WRITEEN 0x10 /* SPROM write enable */ -#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ -#define SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */ -#define SPROM_OTPIN_USE 0x80 /* device OTP In use */ -/* Bits in PCI command and status regs */ -#define PCI_CMD_IO 0x00000001 /* I/O enable */ -#define PCI_CMD_MEMORY 0x00000002 /* Memory enable */ -#define PCI_CMD_MASTER 0x00000004 /* Master enable */ -#define PCI_CMD_SPECIAL 0x00000008 /* Special cycles enable */ -#define PCI_CMD_INVALIDATE 0x00000010 /* Invalidate? */ -#define PCI_CMD_VGA_PAL 0x00000040 /* VGA Palate */ -#define PCI_STAT_TA 0x08000000 /* target abort status */ #endif /* _h_pcicfg_ */ -- GitLab From b3b97f5c23c0a6944ec1f5481ceaac12528a826b Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sat, 26 Mar 2011 02:17:52 +0100 Subject: [PATCH 0418/5560] staging/brcm80211: Fix common spelling mistakes This patch fixes some very common spelling mistakes in drivers/staging/brcm80211. WRONG -> RIGHT accomodate -> accommodate occured -> occurred recieve -> receive unferflow -> underflow useable -> usable Kernel Version: staging/staging-next 20110325 (4bbba111) Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/include/bcmsrom_fmt.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 0c89e854c4ce..d76546234169 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -271,7 +271,7 @@ extern SDIOH_API_RC sdioh_disable_func_intr(void) } #endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ -/* Configure callback to client when we recieve client interrupt */ +/* Configure callback to client when we receive client interrupt */ extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 3b2b554c0dbf..e362cad558b0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -406,7 +406,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) /* compute a new dma xfer rate for max_mpdu @ max mcs. This is the minimum dma rate that - can acheive no unferflow condition for the current mpdu size. + can achieve no underflow condition for the current mpdu size. */ /* note : we divide/multiply by 100 to avoid integer overflows */ fifo->dmaxferrate = diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h index ae2bff828607..4666afd883a5 100644 --- a/drivers/staging/brcm80211/include/bcmsrom_fmt.h +++ b/drivers/staging/brcm80211/include/bcmsrom_fmt.h @@ -103,9 +103,9 @@ #define SROM_CRCREV 63 -/* SROM Rev 4: Reallocate the software part of the srom to accomodate +/* SROM Rev 4: Reallocate the software part of the srom to accommodate * MIMO features. It assumes up to two PCIE functions and 440 bytes - * of useable srom i.e. the useable storage in chips with OTP that + * of usable srom i.e. the usable storage in chips with OTP that * implements hardware redundancy. */ -- GitLab From 7441729769927b424afa762fd4284f2d5eea78f0 Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Wed, 23 Mar 2011 18:30:43 -0400 Subject: [PATCH 0419/5560] staging: winbond: fixing some code styles issues This patch fix some code style warnings found by the checkpatch.pl script, changing spaces for a tab Signed-off-by: Chihau Chau Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/phy_calibration.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 09844db64fe9..79e53e46ecca 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -27,10 +27,10 @@ #define DEG2RAD(X) 0.017453 * (X) static const s32 Angles[] = { - FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)), - FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)), - FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)), - FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977)) + FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)), + FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)), + FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)), + FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977)) }; /****************** LOCAL FUNCTION DECLARATION SECTION **********************/ -- GitLab From 1fec95c503bea25665e5d62221016255a20f2c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Mon, 21 Mar 2011 14:24:03 +0100 Subject: [PATCH 0420/5560] staging: winbond/mto.c: remove unused variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are unused since commit a22517fec0b13b5813932a3583a2b11a2ee17f5d: Staging: w35und: remove dead code from mto.c Signed-off-by: Jonathan Neuschäfer Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mto.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index c03e5010ca34..5250217156a7 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -40,14 +40,9 @@ static u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; -static int TotalTxPkt; -static int TotalTxPktRetry; /* this record the retry rate at different data rate */ static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS]; -static int PeriodTotalTxPkt; -static int PeriodTotalTxPktRetry; - static u8 boSparseTxTraffic; void MTO_Init(struct wbsoft_priv *adapter); @@ -174,9 +169,4 @@ void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 tx_rate, u8 index) MTO_HAL()->dto_tx_retry_count += index; MTO_HAL()->dto_tx_frag_count += (index + 1); } - TotalTxPkt++; - TotalTxPktRetry += (index + 1); - - PeriodTotalTxPkt++; - PeriodTotalTxPktRetry += (index + 1); } -- GitLab From ab8911150f824f496c67b3bab19c15ff62ddff27 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:55:58 -0700 Subject: [PATCH 0421/5560] ath6kl: s|A_FREE|kfree|g for i in $(find ./drivers/staging/ath6kl/ -name \*.[ch]) ; do \ sed -r -i -e "s/A_FREE/kfree/g" $i; done Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 8 +++--- .../hif/sdio/linux_sdio/src/hif_scatter.c | 10 +++---- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 2 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 2 +- drivers/staging/ath6kl/htc2/htc.c | 4 +-- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 22 +++++++-------- .../ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 22 +++++++-------- .../ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 28 +++++++++---------- .../ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 5 ---- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 10 +++---- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 2 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 4 +-- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 +-- .../ath6kl/os/linux/include/osapi_linux.h | 2 -- drivers/staging/ath6kl/os/linux/ioctl.c | 8 +++--- drivers/staging/ath6kl/reorder/rcv_aggr.c | 6 ++-- drivers/staging/ath6kl/wlan/src/wlan_node.c | 6 ++-- drivers/staging/ath6kl/wmi/wmi.c | 4 +-- 18 files changed, 71 insertions(+), 78 deletions(-) diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 9268bf3eabd9..f1f085eba9c8 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -95,12 +95,12 @@ void BMICleanup(void) { if (pBMICmdCredits) { - A_FREE(pBMICmdCredits); + kfree(pBMICmdCredits); pBMICmdCredits = NULL; } if (pBMICmdBuf) { - A_FREE(pBMICmdBuf); + kfree(pBMICmdBuf); pBMICmdBuf = NULL; } } @@ -127,12 +127,12 @@ BMIDone(struct hif_device *device) } if (pBMICmdCredits) { - A_FREE(pBMICmdCredits); + kfree(pBMICmdCredits); pBMICmdCredits = NULL; } if (pBMICmdBuf) { - A_FREE(pBMICmdBuf); + kfree(pBMICmdBuf); pBMICmdBuf = NULL; } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index a1fdcc189f7e..7516d913dab3 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -309,7 +309,7 @@ int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_ (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item))); if (NULL == pReqPriv->pHifScatterReq) { - A_FREE(pReqPriv); + kfree(pReqPriv); break; } /* just zero the main part of the scatter request */ @@ -319,8 +319,8 @@ int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_ /* allocate a bus request for this scatter request */ busrequest = hifAllocateBusRequest(device); if (NULL == busrequest) { - A_FREE(pReqPriv->pHifScatterReq); - A_FREE(pReqPriv); + kfree(pReqPriv->pHifScatterReq); + kfree(pReqPriv); break; } /* assign the scatter request to this bus request */ @@ -382,11 +382,11 @@ void CleanupHIFScatterResources(struct hif_device *device) } if (pReqPriv->pHifScatterReq != NULL) { - A_FREE(pReqPriv->pHifScatterReq); + kfree(pReqPriv->pHifScatterReq); pReqPriv->pHifScatterReq = NULL; } - A_FREE(pReqPriv); + kfree(pReqPriv); } } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index eeddf6021f6d..05f6d157d34a 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -743,7 +743,7 @@ static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev) if (NULL == pReq) { break; } - A_FREE(pReq); + kfree(pReq); } } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index c6488e0d1305..68dd816997cb 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -108,7 +108,7 @@ static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol) A_MUTEX_DELETE(&pProtocol->HCIRxLock); A_MUTEX_DELETE(&pProtocol->HCITxLock); - A_FREE(pProtocol); + kfree(pProtocol); } static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt) diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index d40bb14a2dac..f30865542f87 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -70,7 +70,7 @@ static void HTCCleanup(struct htc_target *target) for (i = 0;i < NUM_CONTROL_BUFFERS;i++) { if (target->HTCControlBuffers[i].Buffer) { - A_FREE(target->HTCControlBuffers[i].Buffer); + kfree(target->HTCControlBuffers[i].Buffer); } } @@ -86,7 +86,7 @@ static void HTCCleanup(struct htc_target *target) A_MUTEX_DELETE(&target->HTCTxLock); } /* free our instance */ - A_FREE(target); + kfree(target); } /* registered target arrival callback from the HIF layer */ diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 4f18f4306465..5125edcca90a 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -78,7 +78,7 @@ static int SendHCICommand(struct ar3k_config_info *pConfig, } while (false); if (pPacket != NULL) { - A_FREE(pPacket); + kfree(pPacket); } return status; @@ -116,7 +116,7 @@ static int RecvHCIEvent(struct ar3k_config_info *pConfig, } while (false); if (pRecvPacket != NULL) { - A_FREE(pRecvPacket); + kfree(pRecvPacket); } return status; @@ -203,7 +203,7 @@ int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, } while (false); if (pBuffer != NULL) { - A_FREE(pBuffer); + kfree(pBuffer); } return status; @@ -268,7 +268,7 @@ static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig) } while (false); if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } return status; @@ -304,7 +304,7 @@ static int AR3KExitMinBoot(struct ar3k_config_info *pConfig) } if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } return status; @@ -328,7 +328,7 @@ static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig) } if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } return status; @@ -382,7 +382,7 @@ static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) &pEvent, &pBufferToFree); if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n")); @@ -397,7 +397,7 @@ static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) &pEvent, &pBufferToFree); if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n")); @@ -412,7 +412,7 @@ static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) &pEvent, &pBufferToFree); if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n")); @@ -427,7 +427,7 @@ static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) &pEvent, &pBufferToFree); if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n")); @@ -442,7 +442,7 @@ static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) &pEvent, &pBufferToFree); if (pBufferToFree != NULL) { - A_FREE(pBufferToFree); + kfree(pBufferToFree); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n")); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 8393efe69f5b..282ceac597b8 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -222,7 +222,7 @@ int PSSendOps(void *arg) A_RELEASE_FIRMWARE(firmware); /* Parse the PS buffer to a global variable */ status = AthDoParsePS(buffer,len); - A_FREE(buffer); + kfree(buffer); } else { A_RELEASE_FIRMWARE(firmware); } @@ -256,7 +256,7 @@ int PSSendOps(void *arg) A_RELEASE_FIRMWARE(firmware); /* parse and store the Patch file contents to a global variables */ status = AthDoParsePatch(buffer,len); - A_FREE(buffer); + kfree(buffer); } else { A_RELEASE_FIRMWARE(firmware); } @@ -283,7 +283,7 @@ int PSSendOps(void *arg) &bufferToFree) == 0) { if(ReadPSEvent(event) == 0) { /* Exit if the status is success */ if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } #ifndef HCI_TRANSPORT_SDIO @@ -295,7 +295,7 @@ int PSSendOps(void *arg) goto complete; } if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } } else { status = 0; @@ -312,13 +312,13 @@ int PSSendOps(void *arg) &bufferToFree) == 0) { if(ReadPSEvent(event) != 0) { /* Exit if the status is success */ if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } status = 1; goto complete; } if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } } else { status = 0; @@ -376,10 +376,10 @@ int PSSendOps(void *arg) AthFreeCommandList(&HciCmdList,numCmds); } if(path) { - A_FREE(path); + kfree(path); } if(config_path) { - A_FREE(config_path); + kfree(config_path); } return status; } @@ -511,7 +511,7 @@ int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type) } if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } return result; @@ -527,7 +527,7 @@ int ReadVersionInfo(struct ar3k_config_info *pConfig) } if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } return result; } @@ -564,7 +564,7 @@ int getDeviceType(struct ar3k_config_info *pConfig, u32 *code) } if(bufferToFree != NULL) { - A_FREE(bufferToFree); + kfree(bufferToFree); } return result; } diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 94a0939bfbf2..c01c0cb0af4e 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -362,7 +362,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n")); if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } @@ -401,7 +401,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n")); if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } @@ -422,7 +422,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n")); if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } @@ -433,7 +433,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) if (ByteCount > LINE_SIZE_MAX/2) { if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } @@ -449,7 +449,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n")); if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } @@ -510,7 +510,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!")); if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; //Sleep (3000); @@ -524,7 +524,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) default: { if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } @@ -541,13 +541,13 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) { if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return A_ERROR; } if(Buffer != NULL) { - A_FREE(Buffer); + kfree(Buffer); } return 0; @@ -609,7 +609,7 @@ int AthDoParsePatch(u8 *patchbuffer, u32 patchlen) /* Handle case when the number of patch buffer is more than the 20K */ if(MAX_NUM_PATCH_ENTRY == Patch_Count) { for(i = 0; i < Patch_Count; i++) { - A_FREE(RamPatch[i].Data); + kfree(RamPatch[i].Data); } return A_ERROR; } @@ -812,13 +812,13 @@ int AthCreateCommandList(struct ps_cmd_packet **HciPacketList, u32 *numPackets) for(count = 0; count < Patch_Count; count++) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count)); - A_FREE(RamPatch[Patch_Count].Data); + kfree(RamPatch[Patch_Count].Data); } for(count = 0; count < Tag_Count; count++) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count)); - A_FREE(PsTagEntry[count].TagData); + kfree(PsTagEntry[count].TagData); } /* @@ -962,8 +962,8 @@ int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets) return A_ERROR; } for(i = 0; i < numPackets;i++) { - A_FREE((*HciPacketList)[i].Hcipacket); + kfree((*HciPacketList)[i].Hcipacket); } - A_FREE(*HciPacketList); + kfree(*HciPacketList); return 0; } diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index 9378efcd586e..cd0a9e827cff 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -60,11 +60,6 @@ #ifndef A_MALLOC #define A_MALLOC(size) kmalloc((size),GFP_KERNEL) #endif /* A_MALLOC */ - - -#ifndef A_FREE -#define A_FREE(addr) kfree((addr)) -#endif /* A_MALLOC */ #endif /* HCI_TRANSPORT_UART */ /* String manipulation APIs */ diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 27cb02dfad3c..6ca147f7af65 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -982,7 +982,7 @@ ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size) } source = "softmac file"; } - A_FREE(macbuf); + kfree(macbuf); } A_RELEASE_FIRMWARE(softmac_entry); } @@ -2134,7 +2134,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) #ifdef HTC_RAW_INTERFACE if (ar->arRawHtc) { - A_FREE(ar->arRawHtc); + kfree(ar->arRawHtc); ar->arRawHtc = NULL; } #endif @@ -4883,7 +4883,7 @@ ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN); wrqu.data.length = sizeof(struct iw_pmkid_cand); wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand); - A_FREE(pmkcand); + kfree(pmkcand); #else /* WIRELESS_EXT >= 18 */ snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", tag, @@ -5603,7 +5603,7 @@ void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId, A_MEMZERO(&wrqu, sizeof(wrqu)); wrqu.data.length = size; wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); - A_FREE(buf); + kfree(buf); #endif @@ -5648,7 +5648,7 @@ void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId, wrqu.data.length = size; wireless_send_event(ar->arNetDev, IWEVGENIE, &wrqu, buf); - A_FREE(buf); + kfree(buf); #endif /* (WIRELESS_EXT >= 18) */ diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 1f7179acfd70..7e6279f5f6df 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -318,7 +318,7 @@ void ar6k_cleanup_hci_pal(void *ar_p) if (pHciPalInfo != NULL) { bt_cleanup_hci_pal(pHciPalInfo); - A_FREE(pHciPalInfo); + kfree(pHciPalInfo); ar->hcipal_info = NULL; } } diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index bcca39418f90..1f799c1d002b 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -552,7 +552,7 @@ ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, ibss_channel, mgmt, le16_to_cpu(size), signal, GFP_KERNEL); - A_FREE(ieeemgmtbuf); + kfree(ieeemgmtbuf); cfg80211_put_bss(bss); } @@ -729,7 +729,7 @@ ar6k_cfg80211_scan_node(void *arg, bss_t *ni) le16_to_cpu(size), signal, GFP_KERNEL); - A_FREE (ieeemgmtbuf); + kfree (ieeemgmtbuf); } static int diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 39e5798f5e80..ac08bcbc4f26 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -582,11 +582,11 @@ void ar6000_cleanup_hci(struct ar6_softc *ar) } if (pHcidevInfo->pHTCStructAlloc != NULL) { - A_FREE(pHcidevInfo->pHTCStructAlloc); + kfree(pHcidevInfo->pHTCStructAlloc); pHcidevInfo->pHTCStructAlloc = NULL; } - A_FREE(pHcidevInfo); + kfree(pHcidevInfo); #ifndef EXPORT_HCI_BRIDGE_INTERFACE ar->hcidev_info = NULL; #endif diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index 53b500c1835f..ff9d06ef6946 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -79,7 +79,6 @@ #define A_MEMZERO(addr, len) memset(addr, 0, len) #define A_MALLOC(size) kmalloc((size), GFP_KERNEL) #define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC) -#define A_FREE(addr) kfree(addr) #if defined(ANDROID_ENV) && defined(CONFIG_ANDROID_LOGGER) extern unsigned int enablelogcat; @@ -364,7 +363,6 @@ static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) { #define A_MEMZERO(addr, len) memset((addr), 0, (len)) #define A_MALLOC(size) malloc(size) -#define A_FREE(addr) free(addr) #ifdef ANDROID #ifndef err diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 0daa201c6cca..159a64cdd215 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -2132,7 +2132,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (copy_to_user(rq->ifr_data, buffer, length)) { ret = -EFAULT; } - A_FREE(buffer); + kfree(buffer); } else { ret = -ENOMEM; } @@ -2155,7 +2155,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { ret = BMIWriteMemory(hifDevice, address, buffer, length); } - A_FREE(buffer); + kfree(buffer); } else { ret = -ENOMEM; } @@ -2308,7 +2308,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { ret = BMILZData(hifDevice, buffer, length); } - A_FREE(buffer); + kfree(buffer); } else { ret = -ENOMEM; } @@ -3822,7 +3822,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (u32 *)buffer); } } - A_FREE(buffer); + kfree(buffer); } else { ret = -ENOMEM; } diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 094b227b32c4..eec1dc6a07c0 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -123,7 +123,7 @@ aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) rxtid->hold_q_sz = 0; if(rxtid->hold_q) { - A_FREE(rxtid->hold_q); + kfree(rxtid->hold_q); rxtid->hold_q = NULL; } @@ -154,7 +154,7 @@ aggr_module_destroy(void *cntxt) A_NETBUF_FREE(rxtid->hold_q[k].osbuf); } } - A_FREE(rxtid->hold_q); + kfree(rxtid->hold_q); } /* Free the dispatch q contents*/ while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) { @@ -168,7 +168,7 @@ aggr_module_destroy(void *cntxt) while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) { A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ)); } - A_FREE(p_aggr); + kfree(p_aggr); } A_PRINTF("out aggr_module_destroy\n"); } diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index 1a3ac7dd5e34..b166dd44893c 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -72,7 +72,7 @@ wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size) { ni->ni_buf = A_MALLOC_NOWAIT(wh_size); if (ni->ni_buf == NULL) { - A_FREE(ni); + kfree(ni); ni = NULL; return ni; } @@ -104,9 +104,9 @@ void wlan_node_free(bss_t *ni) { if (ni->ni_buf != NULL) { - A_FREE(ni->ni_buf); + kfree(ni->ni_buf); } - A_FREE(ni); + kfree(ni); } void diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 0ddaee21f9d7..eccccee94fd0 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -381,7 +381,7 @@ wmi_shutdown(struct wmi_t *wmip) A_MUTEX_DELETE(&wmip->wmi_lock); #endif } - A_FREE(wmip); + kfree(wmip); } } @@ -5877,7 +5877,7 @@ wmi_scan_indication (struct wmi_t *wmip) ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size); - A_FREE(pAr6kScanIndEvent); + kfree(pAr6kScanIndEvent); } #endif -- GitLab From eb60cfa9b80a45391d25e9f90df7f3961cc59757 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:55:59 -0700 Subject: [PATCH 0422/5560] ath6kl: remove BMIENABLE_SET define Leave the code in place as this is always defined statically. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - .../staging/ath6kl/os/linux/ar6000_android.c | 2 - drivers/staging/ath6kl/os/linux/ar6000_drv.c | 66 +++++++------------ .../ath6kl/os/linux/include/ar6000_drv.h | 6 -- drivers/staging/ath6kl/os/linux/ioctl.c | 14 +--- 5 files changed, 28 insertions(+), 61 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index ab68078699f2..50c1db09cd8c 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -126,7 +126,6 @@ ccflags-y += -DWAPI_ENABLE ccflags-y += -DCHECKSUM_OFFLOAD ccflags-y += -DWLAN_HEADERS ccflags-y += -DINIT_MODE_DRV_ENABLED -ccflags-y += -DBMIENABLE_SET obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o ath6kl-y += htc2/AR6000/ar6k.o diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index c96f6e9c99c6..03352b0827f1 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -37,7 +37,6 @@ char fwpath[256] = "/system/wifi"; int wowledon; unsigned int enablelogcat; -extern int bmienable; extern struct net_device *ar6000_devices[]; extern char ifname[]; @@ -309,7 +308,6 @@ static void android_late_resume(struct early_suspend *h) void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks) { - bmienable = 1; if (ifname[0] == '\0') strcpy(ifname, def_ifname); #ifdef CONFIG_HAS_EARLYSUSPEND diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 6ca147f7af65..6248c6d6ca27 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -118,7 +118,6 @@ struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL }; #endif unsigned int processDot11Hdr = 0; -int bmienable = BMIENABLE_DEFAULT; char ifname[IFNAMSIZ] = {0,}; @@ -164,7 +163,6 @@ unsigned int eppingtest=0; module_param_string(ifname, ifname, sizeof(ifname), 0644); module_param(wlaninitmode, int, 0644); -module_param(bmienable, int, 0644); module_param(bypasswmi, bool, 0644); module_param(debuglevel, uint, 0644); module_param(tspecCompliance, int, 0644); @@ -1719,9 +1717,7 @@ ar6000_avail_ev(void *context, void *hif_handle) BMIInit(); - if (bmienable) { - ar6000_sysfs_bmi_init(ar); - } + ar6000_sysfs_bmi_init(ar); { struct bmi_target_info targ_info; @@ -1791,38 +1787,31 @@ ar6000_avail_ev(void *context, void *hif_handle) /* when the module is unloaded. */ ar6000_devices[device_index] = dev; - /* Don't install the init function if BMI is requested */ - if (!bmienable) { - ar6000_netdev_ops.ndo_init = ar6000_init; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode)); - if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || - (wlaninitmode == WLAN_INIT_MODE_DRV)) - { - int status = 0; - do { - if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); - break; - } + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode)); + if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || + (wlaninitmode == WLAN_INIT_MODE_DRV)) { + int status = 0; + do { + if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); + break; + } #ifdef HTC_RAW_INTERFACE - if (!eppingtest && bypasswmi) { - break; /* Don't call ar6000_init for ART */ - } + if (!eppingtest && bypasswmi) { + break; /* Don't call ar6000_init for ART */ + } #endif - rtnl_lock(); - status = (ar6000_init(dev)==0) ? 0 : A_ERROR; - rtnl_unlock(); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); - } - } while (false); - + rtnl_lock(); + status = (ar6000_init(dev)==0) ? 0 : A_ERROR; + rtnl_unlock(); if (status) { - init_status = status; - goto avail_ev_failed; + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); } + } while (false); + + if (status) { + init_status = status; + goto avail_ev_failed; } } @@ -1843,11 +1832,8 @@ ar6000_avail_ev(void *context, void *hif_handle) (unsigned long)ar)); avail_ev_failed : - if (init_status) { - if (bmienable) { - ar6000_sysfs_bmi_deinit(ar); - } - } + if (init_status) + ar6000_sysfs_bmi_deinit(ar); return init_status; } @@ -2120,9 +2106,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) /* cleanup any allocated AMSDU buffers */ ar6000_cleanup_amsdu_rxbufs(ar); - if (bmienable) { - ar6000_sysfs_bmi_deinit(ar); - } + ar6000_sysfs_bmi_deinit(ar); /* Cleanup BMI */ BMICleanup(); diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 89fd80a2c8ed..dc2786036fa5 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -227,12 +227,6 @@ typedef enum _AR6K_BIN_FILE { #define SETUPBTDEV_DEFAULT 0 #endif /* SETUPBTDEV_ENABLED */ -#ifdef BMIENABLE_SET -#define BMIENABLE_DEFAULT 1 -#else -#define BMIENABLE_DEFAULT 0 -#endif /* BMIENABLE_SET */ - #ifdef ENABLEUARTPRINT_SET #define ENABLEUARTPRINT_DEFAULT 1 #else diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 159a64cdd215..f2acc686f9be 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -33,7 +33,6 @@ u32 tcmdRxFreq; extern unsigned int wmitimeout; extern A_WAITQUEUE_HEAD arEvent; extern int tspecCompliance; -extern int bmienable; extern int loghci; static int @@ -2105,16 +2104,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #endif /* CONFIG_HOST_TCMD_SUPPORT */ case AR6000_XIOCTL_BMI_DONE: - if(bmienable) - { - rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */ - ret = ar6000_init(dev); - rtnl_unlock(); - } - else - { - ret = BMIDone(hifDevice); - } + rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */ + ret = ar6000_init(dev); + rtnl_unlock(); break; case AR6000_XIOCTL_BMI_READ_MEMORY: -- GitLab From c1ccd0868efcb7607d2cdf41341542928e066219 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:00 -0700 Subject: [PATCH 0423/5560] ath6kl: propagate error values on ar6000_avail_ev() When something fails we set up some generic error values, instead keep the values from the callers and make sure to pass them on. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 51 +++++++++----------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 6248c6d6ca27..846eea762454 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1601,7 +1601,7 @@ ar6000_avail_ev(void *context, void *hif_handle) #ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; #endif /* ATH6K_CONFIG_CFG80211 */ - int init_status = 0; + int r = 0; struct hif_device_os_device_info osDevInfo; memset(&osDevInfo, 0, sizeof(osDevInfo)); @@ -1722,28 +1722,25 @@ ar6000_avail_ev(void *context, void *hif_handle) { struct bmi_target_info targ_info; - if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != 0) { - init_status = A_ERROR; + r = BMIGetTargetInfo(ar->arHifDevice, &targ_info); + if (r) goto avail_ev_failed; - } ar->arVersion.target_ver = targ_info.target_ver; ar->arTargetType = targ_info.target_type; - /* do any target-specific preparation that can be done through BMI */ - if (ar6000_prepare_target(ar->arHifDevice, + /* do any target-specific preparation that can be done through BMI */ + r = ar6000_prepare_target(ar->arHifDevice, targ_info.target_type, - targ_info.target_ver) != 0) { - init_status = A_ERROR; + targ_info.target_ver); + if (r) goto avail_ev_failed; - } } - if (ar6000_configure_target(ar) != 0) { - init_status = A_ERROR; + r = ar6000_configure_target(ar); + if (r) goto avail_ev_failed; - } A_MEMZERO(&htcInfo,sizeof(htcInfo)); htcInfo.pContext = ar; @@ -1751,8 +1748,8 @@ ar6000_avail_ev(void *context, void *hif_handle) ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo); - if (ar->arHtcTarget == NULL) { - init_status = A_ERROR; + if (!ar->arHtcTarget) { + r = -ENOMEM; goto avail_ev_failed; } @@ -1771,9 +1768,10 @@ ar6000_avail_ev(void *context, void *hif_handle) #endif #ifdef ATH_AR6K_11N_SUPPORT - if((ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs)) == NULL) { + ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs); + if (!ar->aggr_cntxt) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__)); - init_status = A_ERROR; + r = -ENOMEM; goto avail_ev_failed; } @@ -1790,9 +1788,9 @@ ar6000_avail_ev(void *context, void *hif_handle) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode)); if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || (wlaninitmode == WLAN_INIT_MODE_DRV)) { - int status = 0; do { - if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0) { + r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode); + if (r) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); break; } @@ -1802,24 +1800,23 @@ ar6000_avail_ev(void *context, void *hif_handle) } #endif rtnl_lock(); - status = (ar6000_init(dev)==0) ? 0 : A_ERROR; + r = ar6000_init(dev); rtnl_unlock(); - if (status) { + if (r) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); } } while (false); - if (status) { - init_status = status; + if (r) goto avail_ev_failed; - } } /* This runs the init function if registered */ - if (register_netdev(dev)) { + r = register_netdev(dev); + if (r) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n")); ar6000_destroy(dev, 0); - return A_ERROR; + return r; } is_netdev_registered = 1; @@ -1832,10 +1829,10 @@ ar6000_avail_ev(void *context, void *hif_handle) (unsigned long)ar)); avail_ev_failed : - if (init_status) + if (r) ar6000_sysfs_bmi_deinit(ar); - return init_status; + return r; } static void ar6000_target_failure(void *Instance, int Status) -- GitLab From e4551c7bb19c2f094eaabbcd610ab3dfd2ee86a0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:01 -0700 Subject: [PATCH 0424/5560] ath6kl: replace do while loop with function helpers on ar6000_avail_ev() This unwraps the do while loops in favor for function helpers. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 68 ++++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 846eea762454..cbf2cb66608d 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1586,6 +1586,52 @@ init_netdev(struct net_device *dev, char *name) return; } +static int __ath6kl_init_netdev(struct net_device *dev) +{ + int r; + + rtnl_lock(); + r = ar6000_init(dev); + rtnl_unlock(); + + if (r) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); + return r; + } + + return 0; +} + +#ifdef HTC_RAW_INTERFACE +static int ath6kl_init_netdev_wmi(struct net_device *dev) +{ + if (!eppingtest && bypasswmi) + return 0; + + return __ath6kl_init_netdev(dev); +} +#else +static int ath6kl_init_netdev_wmi(struct net_device *dev) +{ + return __ath6kl_init_netdev(dev); +} +#endif + +static int ath6kl_init_netdev(struct ar6_softc *ar) +{ + int r; + + r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode); + if (r) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("ar6000_avail: " + "ar6000_sysfs_bmi_get_config failed\n")); + return r; + } + + return ath6kl_init_netdev_wmi(ar->arNetDev); +} + /* * HTC Event handlers */ @@ -1788,26 +1834,8 @@ ar6000_avail_ev(void *context, void *hif_handle) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode)); if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || (wlaninitmode == WLAN_INIT_MODE_DRV)) { - do { - r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode); - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); - break; - } -#ifdef HTC_RAW_INTERFACE - if (!eppingtest && bypasswmi) { - break; /* Don't call ar6000_init for ART */ - } -#endif - rtnl_lock(); - r = ar6000_init(dev); - rtnl_unlock(); - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); - } - } while (false); - - if (r) + r = ath6kl_init_netdev(ar); + if (r) goto avail_ev_failed; } -- GitLab From 8f05c5b940f3c08d30f4298ceb7cc076dd444008 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:02 -0700 Subject: [PATCH 0425/5560] ath6kl: remove SET_MODULE_OWNER usage This is not required. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index cbf2cb66608d..bb4dbb52cbc2 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1573,10 +1573,6 @@ init_netdev(struct net_device *dev, char *name) strcpy(dev->name, name); } -#ifdef SET_MODULE_OWNER - SET_MODULE_OWNER(dev); -#endif - #ifdef CONFIG_CHECKSUM_OFFLOAD if(csumOffload){ dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/ -- GitLab From 1fd8d02467606a3f69118b495f6ff5dfb9749422 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:03 -0700 Subject: [PATCH 0426/5560] ath6kl: move setting netdev for non-cf80211 case The check for SET_NETDEV_DEV is not required given that this is upstream. The setting of the SET_NETDEV_DEV with the osDevInfo.pOSDevice is redundant for the cfg80211 case as this was already being done, so just set the netdev device for the non-cfg80211 which was missing. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index bb4dbb52cbc2..94b913260349 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1685,6 +1685,7 @@ ar6000_avail_ev(void *context, void *hif_handle) } ether_setup(dev); ar_netif = ar6k_priv(dev); + SET_NETDEV_DEV(dev, osDevInfo.pOSDevice); #endif /* ATH6K_CONFIG_CFG80211 */ if (ar_netif == NULL) { @@ -1715,11 +1716,6 @@ ar6000_avail_ev(void *context, void *hif_handle) init_netdev(dev, ifname); -#ifdef SET_NETDEV_DEV - if (ar_netif) { - SET_NETDEV_DEV(dev, osDevInfo.pOSDevice); - } -#endif ar->arNetDev = dev; ar->arHifDevice = hif_handle; -- GitLab From 9d72a9e13a150124862b74c658271736297709f4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:04 -0700 Subject: [PATCH 0427/5560] ath6kl: remove Bluetooth PAL code and WMI ACL TX/RX data support ath6kl used to have an internal PAL for Bluetooth 3.0 support but this is no longer supported. The target used a WMI with an ACL header for supporting these frames. Userspace would use the ioctl AR6000_XIOCTL_ACL_DATA to send data to the target and the firmware would generate ACL frames. Remove both the parsing of the frames and the ioctl support. We leave a warning for now for if the target generates some sort of ACL data frame, later on we can remove this warning once we have proven the target is no longer generating these frames. It should be noted this also provides a fix for the processing of spurious ACL data frames from the target, previously they would not be dropped if they were generated by the target but EXPORT_HCI_PAL_INTERFACE was not compiled in. Cc: Naveen Singh Cc: Prerepa (Dham) Viswanadham Cc: Shanmugamkamatchi Balashanmugam Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - drivers/staging/ath6kl/include/common/wmi.h | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 59 +-- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 479 ------------------ .../ath6kl/os/linux/include/ar6000_drv.h | 7 - .../ath6kl/os/linux/include/athdrv_linux.h | 2 +- .../os/linux/include/wmi_filter_linux.h | 2 +- drivers/staging/ath6kl/os/linux/ioctl.c | 68 --- 8 files changed, 22 insertions(+), 598 deletions(-) delete mode 100644 drivers/staging/ath6kl/os/linux/ar6k_pal.c diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 50c1db09cd8c..025027a9371f 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -142,7 +142,6 @@ ath6kl-y += os/linux/netbuf.o ath6kl-y += os/linux/wireless_ext.o ath6kl-y += os/linux/ioctl.o ath6kl-y += os/linux/hci_bridge.o -ath6kl-y += os/linux/ar6k_pal.o ath6kl-y += miscdrv/common_drv.o ath6kl-y += miscdrv/credit_dist.o ath6kl-y += wmi/wmi.o diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index c645af373442..d3de3cca0c7f 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -118,7 +118,7 @@ typedef enum { typedef enum { WMI_DATA_HDR_DATA_TYPE_802_3 = 0, WMI_DATA_HDR_DATA_TYPE_802_11, - WMI_DATA_HDR_DATA_TYPE_ACL, + WMI_DATA_HDR_DATA_TYPE_ACL, /* used to be used for the PAL */ } WMI_DATA_HDR_DATA_TYPE; #define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 94b913260349..3dfbb0dace67 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -147,7 +147,6 @@ unsigned int panic_on_assert = 1; unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT; unsigned int setuphci = SETUPHCI_DEFAULT; -unsigned int setuphcipal = SETUPHCIPAL_DEFAULT; unsigned int loghci = 0; unsigned int setupbtdev = SETUPBTDEV_DEFAULT; #ifndef EXPORT_HCI_BRIDGE_INTERFACE @@ -190,7 +189,6 @@ module_param(irqprocmode, uint, 0644); module_param(nohifscattersupport, uint, 0644); module_param(panic_on_assert, uint, 0644); module_param(setuphci, uint, 0644); -module_param(setuphcipal, uint, 0644); module_param(loghci, uint, 0644); module_param(setupbtdev, uint, 0644); #ifndef EXPORT_HCI_BRIDGE_INTERFACE @@ -344,8 +342,6 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, static int ar6000_sysfs_bmi_init(struct ar6_softc *ar); -/* HCI PAL callback function declarations */ -int ar6k_setup_hci_pal(struct ar6_softc *ar); void ar6k_cleanup_hci_pal(struct ar6_softc *ar); static void @@ -2027,15 +2023,6 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) // END workaround if (setuphci) ar6000_cleanup_hci(ar); -#endif -#ifdef EXPORT_HCI_PAL_INTERFACE - if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.cleanupTransport)) { - ar6kHciPalCallbacks_g.cleanupTransport(ar); - } -#else - /* cleanup hci pal driver data structures */ - if(setuphcipal) - ar6k_cleanup_hci_pal(ar); #endif AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n")); /* stop HTC */ @@ -2737,13 +2724,6 @@ int ar6000_init(struct net_device *dev) status = ar6000_setup_hci(ar); } #endif -#ifdef EXPORT_HCI_PAL_INTERFACE - if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.setupTransport)) - status = ar6kHciPalCallbacks_g.setupTransport(ar); -#else - if(setuphcipal) - status = ar6k_setup_hci_pal(ar); -#endif } while (false); @@ -3705,8 +3685,23 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); bool is_amsdu; u8 tid; - bool is_acl_data_frame; - is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL; + + /* + * This check can be removed if after a while we do not + * see the warning. For now we leave it to ensure + * we drop these frames accordingly in case the + * target generates them for some reason. These + * were used for an internal PAL but that's not + * used or supported anymore. These frames should + * not come up from the target. + */ + if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == + WMI_DATA_HDR_DATA_TYPE_ACL)) { + AR6000_STAT_INC(ar, rx_errors); + A_NETBUF_FREE(skb); + return; + } + #ifdef CONFIG_PM ar6000_check_wow_status(ar, NULL, false); #endif /* CONFIG_PM */ @@ -3728,7 +3723,7 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) * ACL data frames don't follow ethernet frame bounds for * min length */ - if (ar->arNetworkType != AP_NETWORK && !is_acl_data_frame && + if (ar->arNetworkType != AP_NETWORK && ((pPacket->ActualLength < minHdrLen) || (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE))) { @@ -3863,7 +3858,7 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) /* NWF: print the 802.11 hdr bytes */ if(containsDot11Hdr) { status = wmi_dot11_hdr_remove(ar->arWmi,skb); - } else if(!is_amsdu && !is_acl_data_frame) { + } else if(!is_amsdu) { status = wmi_dot3_2_dix(skb); } @@ -3873,16 +3868,6 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) goto rx_done; } - if (is_acl_data_frame) { - A_NETBUF_PUSH(skb, sizeof(int)); - *((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID; - /* send the data packet to PAL driver */ - if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) { - if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == true) - goto rx_done; - } - } - if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) { if (ar->arNetworkType == AP_NETWORK) { struct sk_buff *skb1 = NULL; @@ -4829,12 +4814,6 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) buf += sizeof(int); memcpy(buf, cmd->buf, cmd->evt_buf_sz); - if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) - { - /* pass the cmd packet to PAL driver */ - if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == true) - return; - } ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf); if(loghci) { A_PRINTF_LOG("HCI Event From PAL <-- \n"); diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c deleted file mode 100644 index 7e6279f5f6df..000000000000 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ /dev/null @@ -1,479 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#include "ar6000_drv.h" -#ifdef AR6K_ENABLE_HCI_PAL -#include -#include -#include - -extern unsigned int setupbtdev; -#define bt_check_bit(val, bit) (val & bit) -#define bt_set_bit(val, bit) (val |= bit) -#define bt_clear_bit(val, bit) (val &= ~bit) - -/* export ATH_AR6K_DEBUG_HCI_PAL=yes in host/localmake.linux.inc - * to enable debug information */ -#ifdef HCIPAL_DEBUG -#define PRIN_LOG(format, args...) printk(KERN_ALERT "%s:%d - %s Msg:" format "\n",__FUNCTION__, __LINE__, __FILE__, ## args) -#else -#define PRIN_LOG(format, args...) -#endif - -/********************************** - * HCI PAL private info structure - *********************************/ -typedef struct ar6k_hci_pal_info_s{ - - unsigned long ulFlags; -#define HCI_NORMAL_MODE (1) -#define HCI_REGISTERED (1<<1) - struct hci_dev *hdev; /* BT Stack HCI dev */ - struct ar6_softc *ar; - -}ar6k_hci_pal_info_t; - -/*** BT Stack Entrypoints *******/ -/*************************************** - * bt_open - open a handle to the device - ***************************************/ -static int bt_open(struct hci_dev *hdev) -{ - PRIN_LOG("HCI PAL: bt_open - enter - x\n"); - set_bit(HCI_RUNNING, &hdev->flags); - set_bit(HCI_UP, &hdev->flags); - set_bit(HCI_INIT, &hdev->flags); - return 0; -} - -/*************************************** - * bt_close - close handle to the device - ***************************************/ -static int bt_close(struct hci_dev *hdev) -{ - PRIN_LOG("HCI PAL: bt_close - enter\n"); - clear_bit(HCI_RUNNING, &hdev->flags); - return 0; -} - -/***************************** - * bt_ioctl - ioctl processing - *****************************/ -static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) -{ - PRIN_LOG("HCI PAL: bt_ioctl - enter\n"); - return -ENOIOCTLCMD; -} - -/************************************** - * bt_flush - flush outstanding packets - **************************************/ -static int bt_flush(struct hci_dev *hdev) -{ - PRIN_LOG("HCI PAL: bt_flush - enter\n"); - return 0; -} - -/*************** - * bt_destruct - ***************/ -static void bt_destruct(struct hci_dev *hdev) -{ - PRIN_LOG("HCI PAL: bt_destruct - enter\n"); - /* nothing to do here */ -} - -/**************************************************** - * Invoked from bluetooth stack via hdev->send() - * to send the packet out via ar6k to PAL firmware. - * - * For HCI command packet wmi_send_hci_cmd() is invoked. - * wmi_send_hci_cmd adds WMI_CMD_HDR and sends the packet - * to PAL firmware. - * - * For HCI ACL data packet wmi_data_hdr_add is invoked - * to add WMI_DATA_HDR to the packet. ar6000_acl_data_tx - * is then invoked to send the packet to PAL firmware. - ******************************************************/ -static int btpal_send_frame(struct sk_buff *skb) -{ - struct hci_dev *hdev = (struct hci_dev *)skb->dev; - HCI_TRANSPORT_PACKET_TYPE type; - ar6k_hci_pal_info_t *pHciPalInfo; - int status = 0; - struct sk_buff *txSkb = NULL; - struct ar6_softc *ar; - - if (!hdev) { - PRIN_LOG("HCI PAL: btpal_send_frame - no device\n"); - return -ENODEV; - } - - if (!test_bit(HCI_RUNNING, &hdev->flags)) { - PRIN_LOG("HCI PAL: btpal_send_frame - not open\n"); - return -EBUSY; - } - - pHciPalInfo = (ar6k_hci_pal_info_t *)hdev->driver_data; - A_ASSERT(pHciPalInfo != NULL); - ar = pHciPalInfo->ar; - - PRIN_LOG("+btpal_send_frame type: %d \n",bt_cb(skb)->pkt_type); - type = HCI_COMMAND_TYPE; - - switch (bt_cb(skb)->pkt_type) { - case HCI_COMMAND_PKT: - type = HCI_COMMAND_TYPE; - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - type = HCI_ACL_TYPE; - hdev->stat.acl_tx++; - break; - - case HCI_SCODATA_PKT: - /* we don't support SCO over the pal */ - kfree_skb(skb); - return 0; - default: - A_ASSERT(false); - kfree_skb(skb); - return 0; - } - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) { - A_PRINTF(">>> Send HCI %s packet len: %d\n", - (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL", - skb->len); - if (type == HCI_COMMAND_TYPE) { - PRIN_LOG(" HCI Command: OGF:0x%X OCF:0x%X \r\n", - HCI_GET_OP_CODE(skb-data) >> 10, HCI_GET_OP_CODE(skb-data) & 0x3FF); - } - AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump"); - } - - do { - if(type == HCI_COMMAND_TYPE) - { - PRIN_LOG("HCI command"); - - if (ar->arWmiReady == false) - { - PRIN_LOG("WMI not ready "); - break; - } - - if (wmi_send_hci_cmd(ar->arWmi, skb->data, skb->len) != 0) - { - PRIN_LOG("send hci cmd error"); - break; - } - } - else if(type == HCI_ACL_TYPE) - { - void *osbuf; - - PRIN_LOG("ACL data"); - if (ar->arWmiReady == false) - { - PRIN_LOG("WMI not ready"); - break; - } - - /* need to add WMI header so allocate a skb with more space */ - txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ + - sizeof(WMI_DATA_HDR) + skb->len, - GFP_ATOMIC); - - if (txSkb == NULL) { - status = A_NO_MEMORY; - PRIN_LOG("No memory"); - break; - } - - bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type; - txSkb->dev = (void *)pHciPalInfo->hdev; - skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ + sizeof(WMI_DATA_HDR)); - memcpy(txSkb->data, skb->data, skb->len); - skb_put(txSkb,skb->len); - /* Add WMI packet type */ - osbuf = (void *)txSkb; - - if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) { - PRIN_LOG("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n"); - } else { - /* Send data buffer over HTC */ - PRIN_LOG("acl data tx"); - ar6000_acl_data_tx(osbuf, ar->arNetDev); - } - txSkb = NULL; - } - } while (false); - - if (txSkb != NULL) { - PRIN_LOG("Free skb"); - kfree_skb(txSkb); - } - kfree_skb(skb); - return 0; -} - - -/*********************************************** - * Unregister HCI device and free HCI device info - ***********************************************/ -static void bt_cleanup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) -{ - int err; - - if (bt_check_bit(pHciPalInfo->ulFlags, HCI_REGISTERED)) { - bt_clear_bit(pHciPalInfo->ulFlags, HCI_REGISTERED); - clear_bit(HCI_RUNNING, &pHciPalInfo->hdev->flags); - clear_bit(HCI_UP, &pHciPalInfo->hdev->flags); - clear_bit(HCI_INIT, &pHciPalInfo->hdev->flags); - A_ASSERT(pHciPalInfo->hdev != NULL); - /* unregister */ - PRIN_LOG("Unregister PAL device"); - if ((err = hci_unregister_dev(pHciPalInfo->hdev)) < 0) { - PRIN_LOG("HCI PAL: failed to unregister with bluetooth %d\n",err); - } - } - - kfree(pHciPalInfo->hdev); - pHciPalInfo->hdev = NULL; -} - -/********************************************************* - * Allocate HCI device and store in PAL private info structure. - *********************************************************/ -static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) -{ - int status = 0; - struct hci_dev *pHciDev = NULL; - - if (!setupbtdev) { - return 0; - } - - do { - /* allocate a BT HCI struct for this device */ - pHciDev = hci_alloc_dev(); - if (NULL == pHciDev) { - PRIN_LOG("HCI PAL driver - failed to allocate BT HCI struct \n"); - status = A_NO_MEMORY; - break; - } - - /* save the device, we'll register this later */ - pHciPalInfo->hdev = pHciDev; - SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_80211); - pHciDev->driver_data = pHciPalInfo; - pHciDev->open = bt_open; - pHciDev->close = bt_close; - pHciDev->send = btpal_send_frame; - pHciDev->ioctl = bt_ioctl; - pHciDev->flush = bt_flush; - pHciDev->destruct = bt_destruct; - pHciDev->owner = THIS_MODULE; - /* driver is running in normal BT mode */ - PRIN_LOG("Normal mode enabled"); - bt_set_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE); - - } while (false); - - if (status) { - bt_cleanup_hci_pal(pHciPalInfo); - } - return status; -} - -/********************************************** - * Cleanup HCI device and free HCI PAL private info - *********************************************/ -void ar6k_cleanup_hci_pal(void *ar_p) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar_p; - ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)ar->hcipal_info; - - if (pHciPalInfo != NULL) { - bt_cleanup_hci_pal(pHciPalInfo); - kfree(pHciPalInfo); - ar->hcipal_info = NULL; - } -} - -/**************************** - * Register HCI device - ****************************/ -static bool ar6k_pal_transport_ready(void *pHciPal) -{ - ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal; - - PRIN_LOG("HCI device transport ready"); - if(pHciPalInfo == NULL) - return false; - - if (hci_register_dev(pHciPalInfo->hdev) < 0) { - PRIN_LOG("Can't register HCI device"); - hci_free_dev(pHciPalInfo->hdev); - return false; - } - PRIN_LOG("HCI device registered"); - pHciPalInfo->ulFlags |= HCI_REGISTERED; - return true; -} - -/************************************************** - * Called from ar6k driver when command or ACL data - * packet is received. Pass the packet to bluetooth - * stack via hci_recv_frame. - **************************************************/ -bool ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) -{ - struct sk_buff *skb = (struct sk_buff *)osbuf; - ar6k_hci_pal_info_t *pHciPalInfo; - bool success = false; - u8 btType = 0; - pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal; - - do { - - /* if normal mode is not enabled pass on to the stack - * by returning failure */ - if(!(pHciPalInfo->ulFlags & HCI_NORMAL_MODE)) - { - PRIN_LOG("Normal mode not enabled"); - break; - } - - if (!test_bit(HCI_RUNNING, &pHciPalInfo->hdev->flags)) { - PRIN_LOG("HCI PAL: HCI - not running\n"); - break; - } - - if(*((short *)A_NETBUF_DATA(skb)) == WMI_ACL_DATA_EVENTID) - btType = HCI_ACLDATA_PKT; - else - btType = HCI_EVENT_PKT; - /* pull 4 bytes which contains WMI packet type */ - A_NETBUF_PULL(skb, sizeof(int)); - bt_cb(skb)->pkt_type = btType; - skb->dev = (void *)pHciPalInfo->hdev; - - /* pass the received event packet up the stack */ - if (hci_recv_frame(skb) != 0) { - PRIN_LOG("HCI PAL: hci_recv_frame failed \n"); - break; - } else { - PRIN_LOG("HCI PAL: Indicated RCV of type:%d, Length:%d \n",HCI_EVENT_PKT, skb->len); - } - PRIN_LOG("hci recv success"); - success = true; - }while(false); - return success; -} - -/********************************************************** - * HCI PAL init function called from ar6k when it is loaded.. - * Allocates PAL private info, stores the same in ar6k private info. - * Registers a HCI device. - * Registers packet receive callback function with ar6k - **********************************************************/ -int ar6k_setup_hci_pal(void *ar_p) -{ - int status = 0; - ar6k_hci_pal_info_t *pHciPalInfo; - ar6k_pal_config_t ar6k_pal_config; - struct ar6_softc *ar = (struct ar6_softc *)ar_p; - - do { - - pHciPalInfo = (ar6k_hci_pal_info_t *)A_MALLOC(sizeof(ar6k_hci_pal_info_t)); - - if (NULL == pHciPalInfo) { - status = A_NO_MEMORY; - break; - } - - A_MEMZERO(pHciPalInfo, sizeof(ar6k_hci_pal_info_t)); - ar->hcipal_info = pHciPalInfo; - pHciPalInfo->ar = ar; - - status = bt_setup_hci_pal(pHciPalInfo); - if (status) { - break; - } - - if(bt_check_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE)) - PRIN_LOG("HCI PAL: running in normal mode... \n"); - else - PRIN_LOG("HCI PAL: running in test mode... \n"); - - ar6k_pal_config.fpar6k_pal_recv_pkt = ar6k_pal_recv_pkt; - register_pal_cb(&ar6k_pal_config); - ar6k_pal_transport_ready(ar->hcipal_info); - } while (false); - - if (status) { - ar6k_cleanup_hci_pal(ar); - } - return status; -} -#else /* AR6K_ENABLE_HCI_PAL */ -int ar6k_setup_hci_pal(void *ar_p) -{ - return 0; -} -void ar6k_cleanup_hci_pal(void *ar_p) -{ -} -#endif /* AR6K_ENABLE_HCI_PAL */ - -#ifdef EXPORT_HCI_PAL_INTERFACE -/***************************************************** - * Register init and callback function with ar6k - * when PAL driver is a separate kernel module. - ****************************************************/ -int ar6k_register_hci_pal(struct hci_transport_callbacks *hciTransCallbacks); -static int __init pal_init_module(void) -{ - struct hci_transport_callbacks hciTransCallbacks; - - hciTransCallbacks.setupTransport = ar6k_setup_hci_pal; - hciTransCallbacks.cleanupTransport = ar6k_cleanup_hci_pal; - - if(ar6k_register_hci_pal(&hciTransCallbacks) != 0) - return -ENODEV; - - return 0; -} - -static void __exit pal_cleanup_module(void) -{ -} - -module_init(pal_init_module); -module_exit(pal_cleanup_module); -MODULE_LICENSE("Dual BSD/GPL"); -#endif diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index dc2786036fa5..781e18f5ff55 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -215,12 +215,6 @@ typedef enum _AR6K_BIN_FILE { #define SETUPHCI_DEFAULT 0 #endif /* SETUPHCI_ENABLED */ -#ifdef SETUPHCIPAL_ENABLED -#define SETUPHCIPAL_DEFAULT 1 -#else -#define SETUPHCIPAL_DEFAULT 0 -#endif /* SETUPHCIPAL_ENABLED */ - #ifdef SETUPBTDEV_ENABLED #define SETUPBTDEV_DEFAULT 1 #else @@ -571,7 +565,6 @@ struct ar6_softc { #ifndef EXPORT_HCI_BRIDGE_INTERFACE void *hcidev_info; #endif - void *hcipal_info; WMI_AP_MODE_STAT arAPStats; u8 ap_hidden_ssid; u8 ap_country_code[3]; diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 66817c2c5022..065b09be09f8 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -942,7 +942,7 @@ typedef enum { #define AR6000_XIOCTL_HCI_CMD 132 -#define AR6000_XIOCTL_ACL_DATA 133 +#define AR6000_XIOCTL_ACL_DATA 133 /* used to be used for PAL */ #define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h index d172625afa18..1eb6f822d64e 100644 --- a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h @@ -266,7 +266,7 @@ u8 xioctl_filter[] = { (0xFF), /* AR6000_XIOCTL_DELE_AGGR 130 */ (0xFF), /* AR6000_XIOCTL_FETCH_TARGET_REGS 131 */ (0xFF), /* AR6000_XIOCTL_HCI_CMD 132 */ -(0xFF), /* AR6000_XIOCTL_ACL_DATA 133 */ +(0xFF), /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133 */ (0xFF), /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 */ (AP_NETWORK), /* AR6000_XIOCTL_AP_SET_11BG_RATESET 135 */ (0xFF), diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index f2acc686f9be..711f43a37295 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -1488,57 +1488,6 @@ prof_count_rx(u32 addr, u32 count) } #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - -static int -ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbuf) -{ - void *osbuf = NULL; - u8 tmp_space[8]; - HCI_ACL_DATA_PKT *acl; - u8 hdr_size, *datap=NULL; - int ret = 0; - - /* ACL is in data path. There is a need to create pool - * mechanism for allocating and freeing NETBUFs - ToDo later. - */ - - *p_osbuf = NULL; - acl = (HCI_ACL_DATA_PKT *)tmp_space; - hdr_size = sizeof(acl->hdl_and_flags) + sizeof(acl->data_len); - - do { - if (a_copy_from_user(acl, userdata, hdr_size)) { - ret = A_EFAULT; - break; - } - - osbuf = A_NETBUF_ALLOC(hdr_size + acl->data_len); - if (osbuf == NULL) { - ret = A_NO_MEMORY; - break; - } - A_NETBUF_PUT(osbuf, hdr_size + acl->data_len); - datap = (u8 *)A_NETBUF_DATA(osbuf); - - /* Real copy to osbuf */ - acl = (HCI_ACL_DATA_PKT *)(datap); - memcpy(acl, tmp_space, hdr_size); - if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) { - ret = A_EFAULT; - break; - } - } while(false); - - if (ret == 0) { - *p_osbuf = osbuf; - } else { - A_NETBUF_FREE(osbuf); - } - return ret; -} - - - int ar6000_ioctl_ap_setparam(struct ar6_softc *ar, int param, int value) { @@ -4411,23 +4360,6 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } #endif - case AR6000_XIOCTL_ACL_DATA: - { - void *osbuf = NULL; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (ar6000_create_acl_data_osbuf(dev, (u8 *)userdata, &osbuf) != 0) { - ret = -EIO; - } else { - if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n")); - } else { - /* Send data buffer over HTC */ - ar6000_acl_data_tx(osbuf, ar->arNetDev); - } - } - break; - } case AR6000_XIOCTL_HCI_CMD: { char tmp_buf[512]; -- GitLab From 8efba264d45d0af4b7c64373262dbcc01059b602 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:05 -0700 Subject: [PATCH 0428/5560] ath6kl: kill Android specific code To get upstream we can't use out of tree defines, kill all the androidisms. ath6kl won't be usable on Android unless external patches are supported later or Android gets their shit together and gets all their crap upstream. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../staging/ath6kl/os/linux/ar6000_android.c | 386 ------------------ drivers/staging/ath6kl/os/linux/ar6000_drv.c | 16 - drivers/staging/ath6kl/os/linux/ar6000_pm.c | 18 - drivers/staging/ath6kl/os/linux/eeprom.c | 213 ---------- .../ath6kl/os/linux/include/osapi_linux.h | 43 +- .../ath6kl/os/linux/include/wlan_config.h | 4 - .../staging/ath6kl/os/linux/wireless_ext.c | 33 -- 7 files changed, 1 insertion(+), 712 deletions(-) delete mode 100644 drivers/staging/ath6kl/os/linux/ar6000_android.c diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c deleted file mode 100644 index 03352b0827f1..000000000000 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ /dev/null @@ -1,386 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ -#include "ar6000_drv.h" -#include "htc.h" -#include -#include - -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -bool enable_mmc_host_detect_change = false; -static void ar6000_enable_mmchost_detect_change(int enable); - - -char fwpath[256] = "/system/wifi"; -int wowledon; -unsigned int enablelogcat; - -extern struct net_device *ar6000_devices[]; -extern char ifname[]; - -const char def_ifname[] = "wlan0"; -module_param_string(fwpath, fwpath, sizeof(fwpath), 0644); -module_param(enablelogcat, uint, 0644); -module_param(wowledon, int, 0644); - -#ifdef CONFIG_HAS_EARLYSUSPEND -static int screen_is_off; -static struct early_suspend ar6k_early_suspend; -#endif - -static int (*ar6000_avail_ev_p)(void *, void *); - -#if defined(CONFIG_ANDROID_LOGGER) && (!defined(CONFIG_MMC_MSM)) -int logger_write(const enum logidx index, - const unsigned char prio, - const char __kernel * const tag, - const char __kernel * const fmt, - ...) -{ - int ret = 0; - va_list vargs; - struct file *filp = (struct file *)-ENOENT; - mm_segment_t oldfs; - struct iovec vec[3]; - int tag_bytes = strlen(tag) + 1, msg_bytes; - char *msg; - va_start(vargs, fmt); - msg = kvasprintf(GFP_ATOMIC, fmt, vargs); - va_end(vargs); - if (!msg) - return -ENOMEM; - if (in_interrupt()) { - /* we have no choice since aio_write may be blocked */ - printk(KERN_ALERT "%s", msg); - goto out_free_message; - } - msg_bytes = strlen(msg) + 1; - if (msg_bytes <= 1) /* empty message? */ - goto out_free_message; /* don't bother, then */ - if ((msg_bytes + tag_bytes + 1) > 2048) { - ret = -E2BIG; - goto out_free_message; - } - - vec[0].iov_base = (unsigned char *) &prio; - vec[0].iov_len = 1; - vec[1].iov_base = (void *) tag; - vec[1].iov_len = strlen(tag) + 1; - vec[2].iov_base = (void *) msg; - vec[2].iov_len = strlen(msg) + 1; - - oldfs = get_fs(); - set_fs(KERNEL_DS); - do { - filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR); - if (IS_ERR(filp) || !filp->f_op) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: filp_open /dev/log/main error\n", __FUNCTION__)); - ret = -ENOENT; - break; - } - - if (filp->f_op->aio_write) { - int nr_segs = sizeof(vec) / sizeof(vec[0]); - int len = vec[0].iov_len + vec[1].iov_len + vec[2].iov_len; - struct kiocb kiocb; - init_sync_kiocb(&kiocb, filp); - kiocb.ki_pos = 0; - kiocb.ki_left = len; - kiocb.ki_nbytes = len; - ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos); - } - - } while (0); - - if (!IS_ERR(filp)) { - filp_close(filp, NULL); - } - set_fs(oldfs); -out_free_message: - kfree(msg); - return ret; -} -#endif - -int android_logger_lv(void *module, int mask) -{ - switch (mask) { - case ATH_DEBUG_ERR: - return 6; - case ATH_DEBUG_INFO: - return 4; - case ATH_DEBUG_WARN: - return 5; - case ATH_DEBUG_TRC: - return 3; - default: -#ifdef DEBUG - if (!module) { - return 3; - } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(driver)) { - return (mask <=ATH_DEBUG_MAKE_MODULE_MASK(3)) ? 3 : 2; - } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(htc)) { - return 2; - } else { - return 3; - } -#else - return 3; /* DEBUG */ -#endif - } -} - -static int android_readwrite_file(const char *filename, char *rbuf, const char *wbuf, size_t length) -{ - int ret = 0; - struct file *filp = (struct file *)-ENOENT; - mm_segment_t oldfs; - oldfs = get_fs(); - set_fs(KERNEL_DS); - do { - int mode = (wbuf) ? O_RDWR : O_RDONLY; - filp = filp_open(filename, mode, S_IRUSR); - if (IS_ERR(filp) || !filp->f_op) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: file %s filp_open error\n", __FUNCTION__, filename)); - ret = -ENOENT; - break; - } - - if (length==0) { - /* Read the length of the file only */ - struct inode *inode; - - inode = GET_INODE_FROM_FILEP(filp); - if (!inode) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Get inode from %s failed\n", __FUNCTION__, filename)); - ret = -ENOENT; - break; - } - ret = i_size_read(inode->i_mapping->host); - break; - } - - if (wbuf) { - if ( (ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Write %u bytes to file %s error %d\n", __FUNCTION__, - length, filename, ret)); - break; - } - } else { - if ( (ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Read %u bytes from file %s error %d\n", __FUNCTION__, - length, filename, ret)); - break; - } - } - } while (0); - - if (!IS_ERR(filp)) { - filp_close(filp, NULL); - } - set_fs(oldfs); - - return ret; -} - -int android_request_firmware(const struct firmware **firmware_p, const char *name, - struct device *device) -{ - int ret = 0; - struct firmware *firmware; - char filename[256]; - const char *raw_filename = name; - *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); - if (!firmware) - return -ENOMEM; - sprintf(filename, "%s/%s", fwpath, raw_filename); - do { - size_t length, bufsize, bmisize; - - if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) { - break; - } else { - length = ret; - } - - bufsize = ALIGN(length, PAGE_SIZE); - bmisize = A_ROUND_UP(length, 4); - bufsize = max(bmisize, bufsize); - firmware->data = vmalloc(bufsize); - firmware->size = length; - if (!firmware->data) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Cannot allocate buffer for firmware\n", __FUNCTION__)); - ret = -ENOMEM; - break; - } - - if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length)); - ret = -1; - break; - } - - } while (0); - - if (ret<0) { - if (firmware) { - if (firmware->data) - vfree(firmware->data); - kfree(firmware); - } - *firmware_p = NULL; - } else { - ret = 0; - } - return ret; -} - -void android_release_firmware(const struct firmware *firmware) -{ - if (firmware) { - if (firmware->data) - vfree(firmware->data); - kfree(firmware); - } -} - -static int ar6000_android_avail_ev(void *context, void *hif_handle) -{ - int ret; - ar6000_enable_mmchost_detect_change(0); - ret = ar6000_avail_ev_p(context, hif_handle); - return ret; -} - -/* Useful for qualcom platform to detect our wlan card for mmc stack */ -static void ar6000_enable_mmchost_detect_change(int enable) -{ -#ifdef CONFIG_MMC_MSM -#define MMC_MSM_DEV "msm_sdcc.1" - char buf[3]; - int length; - - if (!enable_mmc_host_detect_change) { - return; - } - length = snprintf(buf, sizeof(buf), "%d\n", enable ? 1 : 0); - if (android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/detect_change", - NULL, buf, length) < 0) { - /* fall back to polling */ - android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length); - } -#endif -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void android_early_suspend(struct early_suspend *h) -{ - screen_is_off = 1; -} - -static void android_late_resume(struct early_suspend *h) -{ - screen_is_off = 0; -} -#endif - -void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks) -{ - if (ifname[0] == '\0') - strcpy(ifname, def_ifname); -#ifdef CONFIG_HAS_EARLYSUSPEND - ar6k_early_suspend.suspend = android_early_suspend; - ar6k_early_suspend.resume = android_late_resume; - ar6k_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; - register_early_suspend(&ar6k_early_suspend); -#endif - - ar6000_avail_ev_p = osdrvCallbacks->deviceInsertedHandler; - osdrvCallbacks->deviceInsertedHandler = ar6000_android_avail_ev; - - ar6000_enable_mmchost_detect_change(1); -} - -void android_module_exit(void) -{ -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ar6k_early_suspend); -#endif - ar6000_enable_mmchost_detect_change(1); -} - -#ifdef CONFIG_PM -void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent) -{ - if ( -#ifdef CONFIG_HAS_EARLYSUSPEND - screen_is_off && -#endif - skb && ar->arConnected) { - bool needWake = false; - if (isEvent) { - if (A_NETBUF_LEN(skb) >= sizeof(u16)) { - u16 cmd = *(const u16 *)A_NETBUF_DATA(skb); - switch (cmd) { - case WMI_CONNECT_EVENTID: - case WMI_DISCONNECT_EVENTID: - needWake = true; - break; - default: - /* dont wake lock the system for other event */ - break; - } - } - } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) { - ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb); - if (!IEEE80211_IS_MULTICAST(datap->dstMac)) { - switch (A_BE2CPU16(datap->typeOrLen)) { - case 0x0800: /* IP */ - case 0x888e: /* EAPOL */ - case 0x88c7: /* RSN_PREAUTH */ - case 0x88b4: /* WAPI */ - needWake = true; - break; - case 0x0806: /* ARP is not important to hold wake lock */ - default: - break; - } - } - } - if (needWake) { - /* keep host wake up if there is any event and packate comming in*/ - if (wowledon) { - char buf[32]; - int len = sprintf(buf, "on"); - android_readwrite_file("/sys/power/state", NULL, buf, len); - - len = sprintf(buf, "%d", 127); - android_readwrite_file("/sys/class/leds/lcd-backlight/brightness", - NULL, buf,len); - } - } - } -} -#endif /* CONFIG_PM */ diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 3dfbb0dace67..c93853785e26 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -290,14 +290,6 @@ static void disconnect_timer_handler(unsigned long ptr); void read_rssi_compensation_param(struct ar6_softc *ar); - /* for android builds we call external APIs that handle firmware download and configuration */ -#ifdef ANDROID_ENV -/* !!!! Interim android support to make it easier to patch the default driver for - * android use. You must define an external source file ar6000_android.c that handles the following - * APIs */ -extern void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks); -extern void android_module_exit(void); -#endif /* * HTC service connection handlers */ @@ -660,10 +652,6 @@ ar6000_init_module(void) ar6000_pm_init(); -#ifdef ANDROID_ENV - android_module_init(&osdrvCallbacks); -#endif - #ifdef DEBUG /* Set the debug flags if specified at load time */ if(debugflags != 0) @@ -719,10 +707,6 @@ ar6000_cleanup_module(void) ar6000_pm_exit(); -#ifdef ANDROID_ENV - android_module_exit(); -#endif - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n")); } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 1a9042446bcb..b2459097f7c7 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -36,9 +36,6 @@ extern unsigned int wmitimeout; extern wait_queue_head_t arEvent; -#ifdef ANDROID_ENV -extern void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); -#endif #undef ATH_MODULE_NAME #define ATH_MODULE_NAME pm #define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0) @@ -283,10 +280,6 @@ void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isE /* Wow resume from irq interrupt */ AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState)); ar6000_wow_resume(ar); - } else { -#ifdef ANDROID_ENV - android_ar6k_check_wow_status(ar, skb, isEvent); -#endif } } @@ -373,17 +366,6 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); if (status == A_PENDING) { -#ifdef ANDROID_ENV - /* Wait for WMI ready event */ - u32 timeleft = wait_event_interruptible_timeout(arEvent, - (ar->arWmiReady == true), wmitimeout * HZ); - if (!timeleft || signal_pending(current)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : Failed to get wmi ready \n")); - status = A_ERROR; - break; - } -#endif - status = 0; } else if (status == 0) { ar6000_restart_endpoint(ar->arNetDev); status = 0; diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index 4cff9da2f03e..96f172497dbb 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -359,216 +359,3 @@ commit_4bytes(int offset, u32 data) request_4byte_write(offset, data); wait_for_eeprom_completion(); } -/* ATHENV */ -#ifdef ANDROID_ENV -void eeprom_ar6000_transfer(struct hif_device *device, char *fake_file, char *p_mac) -{ - u32 first_word; - u32 board_data_addr; - int i; - - printk("%s: Enter\n", __FUNCTION__); - - enable_SI(device); - eeprom_type_detect(); - - if (fake_file) { - /* - * Transfer from file to Target RAM. - * Fetch source data from file. - */ - mm_segment_t oldfs; - struct file *filp; - struct inode *inode = NULL; - int length; - - /* open file */ - oldfs = get_fs(); - set_fs(KERNEL_DS); - filp = filp_open(fake_file, O_RDONLY, S_IRUSR); - - if (IS_ERR(filp)) { - printk("%s: file %s filp_open error\n", __FUNCTION__, fake_file); - set_fs(oldfs); - return; - } - - if (!filp->f_op) { - printk("%s: File Operation Method Error\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - inode = GET_INODE_FROM_FILEP(filep); - if (!inode) { - printk("%s: Get inode from filp failed\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos); - - /* file's size */ - length = i_size_read(inode->i_mapping->host); - printk("%s: length=%d\n", __FUNCTION__, length); - if (length != EEPROM_SZ) { - printk("%s: The file's size is not as expected\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - /* read data */ - if (filp->f_op->read(filp, eeprom_data, length, &filp->f_pos) != length) { - printk("%s: file read error\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - /* read data out successfully */ - filp_close(filp, NULL); - set_fs(oldfs); - } else { - /* - * Read from EEPROM to file OR transfer from EEPROM to Target RAM. - * Fetch EEPROM_SZ Bytes of Board Data, 8 bytes at a time. - */ - - fetch_8bytes(0, (u32 *)(&eeprom_data[0])); - - /* Check the first word of EEPROM for validity */ - first_word = *((u32 *)eeprom_data); - - if ((first_word == 0) || (first_word == 0xffffffff)) { - printk("Did not find EEPROM with valid Board Data.\n"); - } - - for (i=8; if_op) { - printk("%s: File Operation Method Error\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - inode = GET_INODE_FROM_FILEP(filep); - if (!inode) { - printk("%s: Get inode from filp failed\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos); - - /* file's size */ - length = i_size_read(inode->i_mapping->host); - printk("%s: length=%d\n", __FUNCTION__, length); - if (length > ATH_SOFT_MAC_TMP_BUF_LEN) { - printk("%s: MAC file's size is not as expected\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - - /* read data */ - if (filp->f_op->read(filp, soft_mac_tmp_buf, length, &filp->f_pos) != length) { - printk("%s: file read error\n", __FUNCTION__); - filp_close(filp, NULL); - set_fs(oldfs); - return; - } - -#if 0 - /* the data we just read */ - printk("%s: mac address from the file:\n", __FUNCTION__); - for (i = 0; i < length; i++) - printk("[%c(0x%x)],", soft_mac_tmp_buf[i], soft_mac_tmp_buf[i]); - printk("\n"); -#endif - - /* read data out successfully */ - filp_close(filp, NULL); - set_fs(oldfs); - - /* convert mac address */ - if (!wmic_ether_aton(soft_mac_tmp_buf, mac_addr)) { - printk("%s: convert mac value fail\n", __FUNCTION__); - return; - } - -#if 0 - /* the converted mac address */ - printk("%s: the converted mac value\n", __FUNCTION__); - for (i = 0; i < ATH_MAC_LEN; i++) - printk("[0x%x],", mac_addr[i]); - printk("\n"); -#endif - } - /* soft mac */ - - /* Determine where in Target RAM to write Board Data */ - BMI_read_mem( HOST_INTEREST_ITEM_ADDRESS(hi_board_data), &board_data_addr); - if (board_data_addr == 0) { - printk("hi_board_data is zero\n"); - } - - /* soft mac */ -#if 1 - /* Update MAC address in RAM */ - if (p_mac) { - update_mac(eeprom_data, EEPROM_SZ, mac_addr); - } -#endif -#if 0 - /* mac address in eeprom array */ - printk("%s: mac values in eeprom array\n", __FUNCTION__); - for (i = 10; i < 10 + 6; i++) - printk("[0x%x],", eeprom_data[i]); - printk("\n"); -#endif - /* soft mac */ - - /* Write EEPROM data to Target RAM */ - BMI_write_mem(board_data_addr, ((u8 *)eeprom_data), EEPROM_SZ); - - /* Record the fact that Board Data IS initialized */ - { - u32 one = 1; - BMI_write_mem(HOST_INTEREST_ITEM_ADDRESS(hi_board_data_initialized), - (u8 *)&one, sizeof(u32)); - } - - disable_SI(); -} -#endif -/* ATHENV */ - diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index ff9d06ef6946..07078b49583f 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -80,31 +80,9 @@ #define A_MALLOC(size) kmalloc((size), GFP_KERNEL) #define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC) -#if defined(ANDROID_ENV) && defined(CONFIG_ANDROID_LOGGER) -extern unsigned int enablelogcat; -extern int android_logger_lv(void* module, int mask); -enum logidx { LOG_MAIN_IDX = 0 }; -extern int logger_write(const enum logidx idx, - const unsigned char prio, - const char __kernel * const tag, - const char __kernel * const fmt, - ...); -#define A_ANDROID_PRINTF(mask, module, tags, args...) do { \ - if (enablelogcat) \ - logger_write(LOG_MAIN_IDX, android_logger_lv(module, mask), tags, args); \ - else \ - printk(KERN_ALERT args); \ -} while (0) -#ifdef DEBUG -#define A_LOGGER_MODULE_NAME(x) #x -#define A_LOGGER(mask, mod, args...) \ - A_ANDROID_PRINTF(mask, &GET_ATH_MODULE_DEBUG_VAR_NAME(mod), "ar6k_" A_LOGGER_MODULE_NAME(mod), args); -#endif -#define A_PRINTF(args...) A_ANDROID_PRINTF(ATH_DEBUG_INFO, NULL, "ar6k_driver", args) -#else #define A_LOGGER(mask, mod, args...) printk(KERN_ALERT args) #define A_PRINTF(args...) printk(KERN_ALERT args) -#endif /* ANDROID */ + #define A_PRINTF_LOG(args...) printk(args) #define A_SPRINTF(buf, args...) sprintf (buf, args) @@ -210,17 +188,8 @@ extern unsigned int panic_on_assert; #define A_ASSERT(expr) #endif /* DEBUG */ -#ifdef ANDROID_ENV -struct firmware; -int android_request_firmware(const struct firmware **firmware_p, const char *filename, - struct device *device); -void android_release_firmware(const struct firmware *firmware); -#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) android_request_firmware(_ppf, _pfile, _dev) -#define A_RELEASE_FIRMWARE(_pf) android_release_firmware(_pf) -#else #define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev) #define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf) -#endif /* * Initialization of the network buffer subsystem @@ -364,17 +333,7 @@ static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) { #define A_MEMZERO(addr, len) memset((addr), 0, (len)) #define A_MALLOC(size) malloc(size) -#ifdef ANDROID -#ifndef err -#include -#define err(_s, args...) do { \ - fprintf(stderr, "%s: line %d ", __FILE__, __LINE__); \ - fprintf(stderr, args); fprintf(stderr, ": %d\n", errno); \ - exit(_s); } while (0) -#endif -#else #include -#endif #endif /* __KERNEL__ */ diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h index 2de5cef26cce..98951bbe05a5 100644 --- a/drivers/staging/ath6kl/os/linux/include/wlan_config.h +++ b/drivers/staging/ath6kl/os/linux/include/wlan_config.h @@ -56,11 +56,7 @@ * If the firmware successly roams within the disconnect timeout * it sends a new connect event */ -#ifdef ANDROID_ENV -#define WLAN_CONFIG_DISCONNECT_TIMEOUT 3 -#else #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10 -#endif /* ANDROID_ENV */ /* * This configuration item disables 11n support. diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index 4b779434956f..5af09f1f226b 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -2499,39 +2499,6 @@ ar6000_ioctl_siwscan(struct net_device *dev, } } -#ifdef ANDROID_ENV -#if WIRELESS_EXT >= 18 - if (data->pointer && (data->length == sizeof(struct iw_scan_req))) - { - if ((data->flags & IW_SCAN_THIS_ESSID) == IW_SCAN_THIS_ESSID) - { - struct iw_scan_req req; - if (copy_from_user(&req, data->pointer, sizeof(struct iw_scan_req))) - return -EIO; - if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != 0) - return -EIO; - ar->scanSpecificSsid = true; - } - else - { - if (ar->scanSpecificSsid) { - if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != 0) - return -EIO; - ar->scanSpecificSsid = false; - } - } - } - else - { - if (ar->scanSpecificSsid) { - if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != 0) - return -EIO; - ar->scanSpecificSsid = false; - } - } -#endif -#endif /* ANDROID_ENV */ - if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, false, false, \ 0, 0, 0, NULL) != 0) { ret = -EIO; -- GitLab From 69e87c22b64b9bb03ed90fc9ed201cf41ee4f44e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:06 -0700 Subject: [PATCH 0429/5560] ath6kl: remove all the wext and super extended private ioctl crap This removes all the wext and super extended ioctl crap. The wext interfaces are already provided by cfg80211 and the "private" ioctl stuff defined here is not even using private wext, they are using netdev private ioctls! This is completely unacceptable upstream. Die. Die Die. As part of all this we end up removing the CONFIG_HOST_GPIO_SUPPORT which ended up being heavily abused by the internal ioctl work. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Kconfig | 6 - drivers/staging/ath6kl/Makefile | 8 +- drivers/staging/ath6kl/include/a_drv_api.h | 18 - drivers/staging/ath6kl/os/linux/ar6000_drv.c | 173 +- .../ath6kl/os/linux/include/ar6000_drv.h | 30 - .../ath6kl/os/linux/include/config_linux.h | 7 - drivers/staging/ath6kl/os/linux/ioctl.c | 4691 ----------------- .../staging/ath6kl/os/linux/wireless_ext.c | 2690 ---------- drivers/staging/ath6kl/wmi/wmi.c | 187 +- 9 files changed, 25 insertions(+), 7785 deletions(-) delete mode 100644 drivers/staging/ath6kl/os/linux/ioctl.c delete mode 100644 drivers/staging/ath6kl/os/linux/wireless_ext.c diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig index 8a5caa30b85f..1f15e1fb1ab2 100644 --- a/drivers/staging/ath6kl/Kconfig +++ b/drivers/staging/ath6kl/Kconfig @@ -100,12 +100,6 @@ config AR600x_BT_RESET_PIN help WLAN GPIO to be used for resetting BT -config ATH6KL_CFG80211 - bool "CFG80211 support" - depends on ATH6K_LEGACY && CFG80211 - help - Enables support for CFG80211 APIs. The default option is to use WEXT. Even with this option enabled, WEXT is not explicitly disabled and the onus of not exercising WEXT lies on the application(s) running in the user space. - config ATH6KL_HTC_RAW_INTERFACE bool "RAW HTC support" depends on ATH6K_LEGACY diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 025027a9371f..be49800431d4 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -85,11 +85,6 @@ ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y) ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET endif -ifeq ($(CONFIG_ATH6KL_CFG80211),y) -ccflags-y += -DATH6K_CONFIG_CFG80211 -ath6kl-y += os/linux/cfg80211.o -endif - ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y) ccflags-y += -DHTC_RAW_INTERFACE endif @@ -135,12 +130,11 @@ ath6kl-y += htc2/htc_recv.o ath6kl-y += htc2/htc_services.o ath6kl-y += htc2/htc.o ath6kl-y += bmi/src/bmi.o +ath6kl-y += os/linux/cfg80211.o ath6kl-y += os/linux/ar6000_drv.o ath6kl-y += os/linux/ar6000_raw_if.o ath6kl-y += os/linux/ar6000_pm.o ath6kl-y += os/linux/netbuf.o -ath6kl-y += os/linux/wireless_ext.o -ath6kl-y += os/linux/ioctl.o ath6kl-y += os/linux/hci_bridge.o ath6kl-y += miscdrv/common_drv.o ath6kl-y += miscdrv/credit_dist.o diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h index 5e098cb30f56..9814de5a7bc7 100644 --- a/drivers/staging/ath6kl/include/a_drv_api.h +++ b/drivers/staging/ath6kl/include/a_drv_api.h @@ -130,19 +130,6 @@ extern "C" { #define A_WMI_PEER_EVENT(devt, eventCode, bssid) \ ar6000_peer_event ((devt), (eventCode), (bssid)) -#ifdef CONFIG_HOST_GPIO_SUPPORT - -#define A_WMI_GPIO_INTR_RX(intr_mask, input_values) \ - ar6000_gpio_intr_rx((intr_mask), (input_values)) - -#define A_WMI_GPIO_DATA_RX(reg_id, value) \ - ar6000_gpio_data_rx((reg_id), (value)) - -#define A_WMI_GPIO_ACK_RX() \ - ar6000_gpio_ack_rx() - -#endif - #ifdef SEND_EVENT_TO_APP #define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) \ @@ -158,11 +145,6 @@ extern "C" { #endif -#ifdef CONFIG_HOST_TCMD_SUPPORT -#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \ - ar6000_tcmd_rx_report_event((devt), (results), (len)) -#endif - #define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \ ar6000_hbChallengeResp_event((devt), (cookie), (source)) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index c93853785e26..3b3eec140fa1 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -27,9 +27,7 @@ */ #include "ar6000_drv.h" -#ifdef ATH6K_CONFIG_CFG80211 #include "cfg80211.h" -#endif /* ATH6K_CONFIG_CFG80211 */ #include "htc.h" #include "wmi_filter_linux.h" #include "epping_test.h" @@ -284,7 +282,6 @@ void ar6000_destroy(struct net_device *dev, unsigned int unregister); static void ar6000_detect_error(unsigned long ptr); static void ar6000_set_multicast_list(struct net_device *dev); static struct net_device_stats *ar6000_get_stats(struct net_device *dev); -static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev); static void disconnect_timer_handler(unsigned long ptr); @@ -348,7 +345,6 @@ ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode); struct net_device *ar6000_devices[MAX_AR6000]; static int is_netdev_registered; -extern struct iw_handler_def ath_iw_handler_def; DECLARE_WAIT_QUEUE_HEAD(arEvent); static void ar6000_cookie_init(struct ar6_softc *ar); static void ar6000_cookie_cleanup(struct ar6_softc *ar); @@ -375,7 +371,6 @@ static struct net_device_ops ar6000_netdev_ops = { .ndo_open = ar6000_open, .ndo_stop = ar6000_close, .ndo_get_stats = ar6000_get_stats, - .ndo_do_ioctl = ar6000_ioctl, .ndo_start_xmit = ar6000_data_tx, .ndo_set_multicast_list = ar6000_set_multicast_list, }; @@ -669,10 +664,6 @@ ar6000_init_module(void) memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD)); #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ -#ifdef CONFIG_HOST_GPIO_SUPPORT - ar6000_gpio_init(); -#endif /* CONFIG_HOST_GPIO_SUPPORT */ - status = HIFInit(&osdrvCallbacks); if (status) return -ENODEV; @@ -1533,9 +1524,6 @@ init_netdev(struct net_device *dev, char *name) { dev->netdev_ops = &ar6000_netdev_ops; dev->watchdog_timeo = AR6000_TX_TIMEOUT; - dev->wireless_handlers = &ath_iw_handler_def; - - ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */ /* * We need the OS to provide us with more headroom in order to @@ -1620,9 +1608,7 @@ ar6000_avail_ev(void *context, void *hif_handle) struct ar6_softc *ar; int device_index = 0; struct htc_init_info htcInfo; -#ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; -#endif /* ATH6K_CONFIG_CFG80211 */ int r = 0; struct hif_device_os_device_info osDevInfo; @@ -1650,23 +1636,12 @@ ar6000_avail_ev(void *context, void *hif_handle) /* we use another local "i" variable below. */ device_index = i; -#ifdef ATH6K_CONFIG_CFG80211 wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice); if (IS_ERR(wdev)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__)); return A_ERROR; } ar_netif = wdev_priv(wdev); -#else - dev = alloc_etherdev(sizeof(struct ar6_softc)); - if (dev == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: can't alloc etherdev\n")); - return A_ERROR; - } - ether_setup(dev); - ar_netif = ar6k_priv(dev); - SET_NETDEV_DEV(dev, osDevInfo.pOSDevice); -#endif /* ATH6K_CONFIG_CFG80211 */ if (ar_netif == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__)); @@ -1676,7 +1651,6 @@ ar6000_avail_ev(void *context, void *hif_handle) A_MEMZERO(ar_netif, sizeof(struct ar6_softc)); ar = (struct ar6_softc *)ar_netif; -#ifdef ATH6K_CONFIG_CFG80211 ar->wdev = wdev; wdev->iftype = NL80211_IFTYPE_STATION; @@ -1692,7 +1666,6 @@ ar6000_avail_ev(void *context, void *hif_handle) wdev->netdev = dev; ar->arNetworkType = INFRA_NETWORK; ar->smeState = SME_DISCONNECTED; -#endif /* ATH6K_CONFIG_CFG80211 */ init_netdev(dev, ifname); @@ -2117,9 +2090,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) } free_netdev(dev); -#ifdef ATH6K_CONFIG_CFG80211 ar6k_cfg80211_deinit(ar); -#endif /* ATH6K_CONFIG_CFG80211 */ #ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT ar6000_remove_ap_interface(); @@ -2267,11 +2238,9 @@ ar6000_open(struct net_device *dev) spin_lock_irqsave(&ar->arLock, flags); -#ifdef ATH6K_CONFIG_CFG80211 if(ar->arWlanState == WLAN_DISABLED) { ar->arWlanState = WLAN_ENABLED; } -#endif /* ATH6K_CONFIG_CFG80211 */ if( ar->arConnected || bypasswmi) { netif_carrier_on(dev); @@ -2288,12 +2257,9 @@ ar6000_open(struct net_device *dev) static int ar6000_close(struct net_device *dev) { -#ifdef ATH6K_CONFIG_CFG80211 struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); -#endif /* ATH6K_CONFIG_CFG80211 */ netif_stop_queue(dev); -#ifdef ATH6K_CONFIG_CFG80211 ar6000_disconnect(ar); if(ar->arWmiReady == true) { @@ -2304,7 +2270,6 @@ ar6000_close(struct net_device *dev) ar->arWlanState = WLAN_DISABLED; } ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED); -#endif /* ATH6K_CONFIG_CFG80211 */ return 0; } @@ -4116,93 +4081,6 @@ ar6000_get_stats(struct net_device *dev) return &ar->arNetStats; } -static struct iw_statistics * -ar6000_get_iwstats(struct net_device * dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - TARGET_STATS *pStats = &ar->arTargetStats; - struct iw_statistics * pIwStats = &ar->arIwStats; - int rtnllocked; - - if (ar->bIsDestroyProgress || ar->arWmiReady == false || ar->arWlanState == WLAN_DISABLED) - { - pIwStats->status = 0; - pIwStats->qual.qual = 0; - pIwStats->qual.level =0; - pIwStats->qual.noise = 0; - pIwStats->discard.code =0; - pIwStats->discard.retries=0; - pIwStats->miss.beacon =0; - return pIwStats; - } - - /* - * The in_atomic function is used to determine if the scheduling is - * allowed in the current context or not. This was introduced in 2.6 - * From what I have read on the differences between 2.4 and 2.6, the - * 2.4 kernel did not support preemption and so this check might not - * be required for 2.4 kernels. - */ - if (in_atomic()) - { - wmi_get_stats_cmd(ar->arWmi); - - pIwStats->status = 1 ; - pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161; - pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */ - pIwStats->qual.noise = pStats->noise_floor_calibation; - pIwStats->discard.code = pStats->rx_decrypt_err; - pIwStats->discard.retries = pStats->tx_retry_cnt; - pIwStats->miss.beacon = pStats->cs_bmiss_cnt; - return pIwStats; - } - - dev_hold(dev); - rtnllocked = rtnl_is_locked(); - if (rtnllocked) { - rtnl_unlock(); - } - pIwStats->status = 0; - - if (down_interruptible(&ar->arSem)) { - goto err_exit; - } - - do { - - if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) { - break; - } - - ar->statsUpdatePending = true; - - if(wmi_get_stats_cmd(ar->arWmi) != 0) { - break; - } - - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); - if (signal_pending(current)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : WMI get stats timeout \n")); - break; - } - pIwStats->status = 1 ; - pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161; - pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */ - pIwStats->qual.noise = pStats->noise_floor_calibation; - pIwStats->discard.code = pStats->rx_decrypt_err; - pIwStats->discard.retries = pStats->tx_retry_cnt; - pIwStats->miss.beacon = pStats->cs_bmiss_cnt; - } while (0); - up(&ar->arSem); - -err_exit: - if (rtnllocked) { - rtnl_lock(); - } - dev_put(dev); - return pIwStats; -} - void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) { @@ -4224,6 +4102,29 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) wake_up(&arEvent); } +void ar6000_install_static_wep_keys(struct ar6_softc *ar) +{ + u8 index; + u8 keyUsage; + + for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { + if (ar->arWepKeyList[index].arKeyLen) { + keyUsage = GROUP_USAGE; + if (index == ar->arDefTxKeyIndex) { + keyUsage |= TX_USAGE; + } + wmi_addKey_cmd(ar->arWmi, + index, + WEP_CRYPT, + keyUsage, + ar->arWepKeyList[index].arKeyLen, + NULL, + ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL, + NO_SYNC_WMIFLAG); + } + } +} + void add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie, u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) @@ -4362,13 +4263,11 @@ ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, return; } -#ifdef ATH6K_CONFIG_CFG80211 ar6k_cfg80211_connect_event(ar, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo); -#endif /* ATH6K_CONFIG_CFG80211 */ memcpy(ar->arBssid, bssid, sizeof(ar->arBssid)); ar->arBssChannel = channel; @@ -4482,26 +4381,6 @@ ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, netif_wake_queue(ar->arNetDev); - /* For CFG80211 the key configuration and the default key comes in after connect so no point in plumbing invalid keys */ -#ifndef ATH6K_CONFIG_CFG80211 - if ((networkType & ADHOC_NETWORK) && - (OPEN_AUTH == ar->arDot11AuthMode) && - (NONE_AUTH == ar->arAuthMode) && - (WEP_CRYPT == ar->arPairwiseCrypto)) - { - if (!ar->arConnected) { - wmi_addKey_cmd(ar->arWmi, - ar->arDefTxKeyIndex, - WEP_CRYPT, - GROUP_USAGE | TX_USAGE, - ar->arWepKeyList[ar->arDefTxKeyIndex].arKeyLen, - NULL, - ar->arWepKeyList[ar->arDefTxKeyIndex].arKey, KEY_OP_INIT_VAL, NULL, - NO_SYNC_WMIFLAG); - } - } -#endif /* ATH6K_CONFIG_CFG80211 */ - /* Update connect & link status atomically */ spin_lock_irqsave(&ar->arLock, flags); ar->arConnected = true; @@ -4631,11 +4510,9 @@ ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, return; } -#ifdef ATH6K_CONFIG_CFG80211 ar6k_cfg80211_disconnect_event(ar, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus); -#endif /* ATH6K_CONFIG_CFG80211 */ /* Send disconnect event to supplicant */ A_MEMZERO(&wrqu, sizeof(wrqu)); @@ -4882,9 +4759,7 @@ ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast) tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]); } else { -#ifdef ATH6K_CONFIG_CFG80211 ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast); -#endif /* ATH6K_CONFIG_CFG80211 */ A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n", keyid & 0x3, ismcast ? "multi": "uni"); @@ -4901,9 +4776,7 @@ void ar6000_scanComplete_event(struct ar6_softc *ar, int status) { -#ifdef ATH6K_CONFIG_CFG80211 ar6k_cfg80211_scanComplete_event(ar, status); -#endif /* ATH6K_CONFIG_CFG80211 */ if (!ar->arUserBssFilter) { wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 781e18f5ff55..5b053ab2e618 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -33,9 +33,7 @@ #include #include #include -#ifdef ATH6K_CONFIG_CFG80211 #include -#endif /* ATH6K_CONFIG_CFG80211 */ #include #include @@ -373,7 +371,6 @@ struct ar_wep_key { u8 arKey[64]; } ; -#ifdef ATH6K_CONFIG_CFG80211 struct ar_key { u8 key[WLAN_MAX_KEY_LEN]; u8 key_len; @@ -387,8 +384,6 @@ enum { SME_CONNECTING, SME_CONNECTED }; -#endif /* ATH6K_CONFIG_CFG80211 */ - struct ar_node_mapping { u8 macAddress[6]; @@ -584,12 +579,10 @@ struct ar6_softc { WMI_BTCOEX_STATS_EVENT arBtcoexStats; s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */ struct hif_device_os_device_info osDevInfo; -#ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; struct cfg80211_scan_request *scan_request; struct ar_key keys[WMI_MAX_KEY_INDEX + 1]; u32 smeState; -#endif /* ATH6K_CONFIG_CFG80211 */ u16 arWlanPowerState; bool arWlanOff; #ifdef CONFIG_PM @@ -619,30 +612,10 @@ struct ar_virtual_interface { }; #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ -#ifdef ATH6K_CONFIG_CFG80211 static inline void *ar6k_priv(struct net_device *dev) { return (wdev_priv(dev->ieee80211_ptr)); } -#else -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -static inline void *ar6k_priv(struct net_device *dev) -{ - extern struct net_device *arApNetDev; - - if (arApNetDev == dev) { - /* return arDev saved in virtual interface context */ - struct ar_virtual_interface *arVirDev; - arVirDev = netdev_priv(dev); - return arVirDev->arDev; - } else { - return netdev_priv(dev); - } -} -#else -#define ar6k_priv netdev_priv -#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ -#endif /* ATH6K_CONFIG_CFG80211 */ #define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \ (pHciDev)->bus = (__bus); \ @@ -688,9 +661,6 @@ struct ar_giwscan_param { spin_unlock_bh(lock); \ } while (0) -int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -int ar6000_ioctl_dispatcher(struct net_device *dev, struct ifreq *rq, int cmd); -void ar6000_gpio_init(void); void ar6000_init_profile_info(struct ar6_softc *ar); void ar6000_install_static_wep_keys(struct ar6_softc *ar); int ar6000_init(struct net_device *dev); diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h index 50f53d361049..d4030e26b20c 100644 --- a/drivers/staging/ath6kl/os/linux/include/config_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/config_linux.h @@ -30,13 +30,6 @@ extern "C" { #include -/* - * Host-side GPIO support is optional. - * If run-time access to GPIO pins is not required, then - * this should be changed to #undef. - */ -#define CONFIG_HOST_GPIO_SUPPORT - /* * Host side Test Command support */ diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c deleted file mode 100644 index 711f43a37295..000000000000 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ /dev/null @@ -1,4691 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#include "ar6000_drv.h" -#include "ieee80211_ioctl.h" -#include "ar6kap_common.h" -#include "targaddrs.h" -#include "a_hci.h" -#include "wlan_config.h" - -extern int enablerssicompensation; -u32 tcmdRxFreq; -extern unsigned int wmitimeout; -extern A_WAITQUEUE_HEAD arEvent; -extern int tspecCompliance; -extern int loghci; - -static int -ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (ar->arWmiReady == false) { - return -EIO; - } - - if(wmi_get_roam_tbl_cmd(ar->arWmi) != 0) { - return -EIO; - } - - return 0; -} - -static int -ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (ar->arWmiReady == false) { - return -EIO; - } - - - /* currently assume only roam times are required */ - if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != 0) { - return -EIO; - } - - - return 0; -} - -static int -ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_ROAM_CTRL_CMD cmd; - u8 size = sizeof(cmd); - - if (ar->arWmiReady == false) { - return -EIO; - } - - - if (copy_from_user(&cmd, userdata, size)) { - return -EFAULT; - } - - if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) { - if (cmd.info.bssBiasInfo.numBss > 1) { - size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS); - } - } - - if (copy_from_user(&cmd, userdata, size)) { - return -EFAULT; - } - - if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != 0) { - return -EIO; - } - - return 0; -} - -static int -ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_POWERSAVE_TIMERS_POLICY_CMD cmd; - u8 size = sizeof(cmd); - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, size)) { - return -EFAULT; - } - - if (copy_from_user(&cmd, userdata, size)) { - return -EFAULT; - } - - if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != 0) { - return -EIO; - } - - return 0; -} - -static int -ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_QOS_SUPP_CMD cmd; - int ret; - - if ((dev->flags & IFF_UP) != IFF_UP) { - return -EIO; - } - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), - sizeof(cmd))) - { - return -EFAULT; - } - - ret = wmi_set_qos_supp_cmd(ar->arWmi, cmd.status); - - switch (ret) { - case 0: - return 0; - case A_EBUSY : - return -EBUSY; - case A_NO_MEMORY: - return -ENOMEM; - case A_EINVAL: - default: - return -EFAULT; - } -} - -static int -ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_WMM_CMD cmd; - int ret; - - if ((dev->flags & IFF_UP) != IFF_UP) { - return -EIO; - } - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), - sizeof(cmd))) - { - return -EFAULT; - } - - if (cmd.status == WMI_WMM_ENABLED) { - ar->arWmmEnabled = true; - } else { - ar->arWmmEnabled = false; - } - - ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status); - - switch (ret) { - case 0: - return 0; - case A_EBUSY : - return -EBUSY; - case A_NO_MEMORY: - return -ENOMEM; - case A_EINVAL: - default: - return -EFAULT; - } -} - -static int -ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_WMM_TXOP_CMD cmd; - int ret; - - if ((dev->flags & IFF_UP) != IFF_UP) { - return -EIO; - } - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), - sizeof(cmd))) - { - return -EFAULT; - } - - ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable); - - switch (ret) { - case 0: - return 0; - case A_EBUSY : - return -EBUSY; - case A_NO_MEMORY: - return -ENOMEM; - case A_EINVAL: - default: - return -EFAULT; - } -} - -static int -ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int ret = 0; - - if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == false) { - return -EIO; - } - - if(copy_to_user((char *)((unsigned int*)rq->ifr_data + 1), - &ar->arRegCode, sizeof(ar->arRegCode))) - ret = -EFAULT; - - return ret; -} - -static int -ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_AP_SET_COUNTRY_CMD cmd; - int ret; - - if ((dev->flags & IFF_UP) != IFF_UP) { - return -EIO; - } - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), - sizeof(cmd))) - { - return -EFAULT; - } - - ar->ap_profile_flag = 1; /* There is a change in profile */ - - ret = wmi_set_country(ar->arWmi, cmd.countryCode); - memcpy(ar->ap_country_code, cmd.countryCode, 3); - - switch (ret) { - case 0: - return 0; - case A_EBUSY : - return -EBUSY; - case A_NO_MEMORY: - return -ENOMEM; - case A_EINVAL: - default: - return -EFAULT; - } -} - - -/* Get power mode command */ -static int -ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_POWER_MODE_CMD power_mode; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi); - if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) { - ret = -EFAULT; - } - - return ret; -} - - -static int -ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_CHANNEL_PARAMS_CMD cmd, *cmdp; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - if( (ar->arNextMode == AP_NETWORK) && (cmd.numChannels || cmd.scanParam) ) { - A_PRINTF("ERROR: Only wmode is allowed in AP mode\n"); - return -EIO; - } - - if (cmd.numChannels > 1) { - cmdp = A_MALLOC(130); - if (copy_from_user(cmdp, rq->ifr_data, - sizeof (*cmdp) + - ((cmd.numChannels - 1) * sizeof(u16)))) - { - kfree(cmdp); - return -EFAULT; - } - } else { - cmdp = &cmd; - } - - if ((ar->arPhyCapability == WMI_11G_CAPABILITY) && - ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE))) - { - ret = -EINVAL; - } - - if (!ret && - (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode, - cmdp->numChannels, cmdp->channelList) - != 0)) - { - ret = -EIO; - } - - if (cmd.numChannels > 1) { - kfree(cmdp); - } - - ar->ap_wmode = cmdp->phyMode; - /* Set the profile change flag to allow a commit cmd */ - ar->ap_profile_flag = 1; - - return ret; -} - - -static int -ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq) -{ - - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SNR_THRESHOLD_PARAMS_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != 0 ) { - ret = -EIO; - } - - return ret; -} - -static int -ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) -{ -#define SWAP_THOLD(thold1, thold2) do { \ - USER_RSSI_THOLD tmpThold; \ - tmpThold.tag = thold1.tag; \ - tmpThold.rssi = thold1.rssi; \ - thold1.tag = thold2.tag; \ - thold1.rssi = thold2.rssi; \ - thold2.tag = tmpThold.tag; \ - thold2.rssi = tmpThold.rssi; \ -} while (0) - - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; - USER_RSSI_PARAMS rssiParams; - s32 i, j; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user((char *)&rssiParams, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(USER_RSSI_PARAMS))) { - return -EFAULT; - } - cmd.weight = rssiParams.weight; - cmd.pollTime = rssiParams.pollTime; - - memcpy(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map)); - /* - * only 6 elements, so use bubble sorting, in ascending order - */ - for (i = 5; i > 0; i--) { - for (j = 0; j < i; j++) { /* above tholds */ - if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) { - SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]); - } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) { - return -EFAULT; - } - } - } - for (i = 11; i > 6; i--) { - for (j = 6; j < i; j++) { /* below tholds */ - if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) { - SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]); - } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) { - return -EFAULT; - } - } - } - -#ifdef DEBUG - for (i = 0; i < 12; i++) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("thold[%d].tag: %d, thold[%d].rssi: %d \n", - i, ar->rssi_map[i].tag, i, ar->rssi_map[i].rssi)); - } -#endif - - if (enablerssicompensation) { - for (i = 0; i < 6; i++) - ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, true); - for (i = 6; i < 12; i++) - ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, false); - } - - cmd.thresholdAbove1_Val = ar->rssi_map[0].rssi; - cmd.thresholdAbove2_Val = ar->rssi_map[1].rssi; - cmd.thresholdAbove3_Val = ar->rssi_map[2].rssi; - cmd.thresholdAbove4_Val = ar->rssi_map[3].rssi; - cmd.thresholdAbove5_Val = ar->rssi_map[4].rssi; - cmd.thresholdAbove6_Val = ar->rssi_map[5].rssi; - cmd.thresholdBelow1_Val = ar->rssi_map[6].rssi; - cmd.thresholdBelow2_Val = ar->rssi_map[7].rssi; - cmd.thresholdBelow3_Val = ar->rssi_map[8].rssi; - cmd.thresholdBelow4_Val = ar->rssi_map[9].rssi; - cmd.thresholdBelow5_Val = ar->rssi_map[10].rssi; - cmd.thresholdBelow6_Val = ar->rssi_map[11].rssi; - - if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != 0 ) { - ret = -EIO; - } - - return ret; -} - -static int -ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq) -{ - - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_LQ_THRESHOLD_PARAMS_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(cmd))) { - return -EFAULT; - } - - if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != 0 ) { - ret = -EIO; - } - - return ret; -} - - -static int -ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_PROBED_SSID_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength, - cmd.ssid) != 0) - { - ret = -EIO; - } - - return ret; -} - -static int -ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_ADD_BAD_AP_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) { - return -EIO; - } - - if (memcmp(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) { - /* - * This is a delete badAP. - */ - if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != 0) { - ret = -EIO; - } - } else { - if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != 0) { - ret = -EIO; - } - } - - return ret; -} - -static int -ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_CREATE_PSTREAM_CMD cmd; - int ret; - - if (ar->arWmiReady == false) { - return -EIO; - } - - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - ret = wmi_verify_tspec_params(&cmd, tspecCompliance); - if (ret == 0) - ret = wmi_create_pstream_cmd(ar->arWmi, &cmd); - - switch (ret) { - case 0: - return 0; - case A_EBUSY : - return -EBUSY; - case A_NO_MEMORY: - return -ENOMEM; - case A_EINVAL: - default: - return -EFAULT; - } -} - -static int -ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_DELETE_PSTREAM_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid); - - switch (ret) { - case 0: - return 0; - case A_EBUSY : - return -EBUSY; - case A_NO_MEMORY: - return -ENOMEM; - case A_EINVAL: - default: - return -EFAULT; - } -} - -static int -ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct ar6000_queuereq qreq; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if( copy_from_user(&qreq, rq->ifr_data, - sizeof(struct ar6000_queuereq))) - return -EFAULT; - - qreq.activeTsids = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficClass); - - if (copy_to_user(rq->ifr_data, &qreq, - sizeof(struct ar6000_queuereq))) - { - ret = -EFAULT; - } - - return ret; -} - -#ifdef CONFIG_HOST_TCMD_SUPPORT -static int -ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, - struct ifreq *rq, u8 *data, u32 len) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u32 buf[4+TCMD_MAX_RATES]; - int ret = 0; - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - return -EBUSY; - } - - ar->tcmdRxReport = 0; - if (wmi_test_cmd(ar->arWmi, data, len) != 0) { - up(&ar->arSem); - return -EIO; - } - - wait_event_interruptible_timeout(arEvent, ar->tcmdRxReport != 0, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - - buf[0] = ar->tcmdRxTotalPkt; - buf[1] = ar->tcmdRxRssi; - buf[2] = ar->tcmdRxcrcErrPkt; - buf[3] = ar->tcmdRxsecErrPkt; - memcpy(((u8 *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); - memcpy(((u8 *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); - - if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) { - ret = -EFAULT; - } - - up(&ar->arSem); - - return ret; -} - -void -ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results; - - if (enablerssicompensation) { - rx_rep->u.report.rssiInDBm = rssi_compensation_calc_tcmd(tcmdRxFreq, rx_rep->u.report.rssiInDBm,rx_rep->u.report.totalPkt); - } - - - ar->tcmdRxTotalPkt = rx_rep->u.report.totalPkt; - ar->tcmdRxRssi = rx_rep->u.report.rssiInDBm; - ar->tcmdRxcrcErrPkt = rx_rep->u.report.crcErrPkt; - ar->tcmdRxsecErrPkt = rx_rep->u.report.secErrPkt; - ar->tcmdRxReport = 1; - A_MEMZERO(ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); - A_MEMZERO(ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); - memcpy(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt)); - memcpy(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); - - wake_up(&arEvent); -} -#endif /* CONFIG_HOST_TCMD_SUPPORT*/ - -static int -ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_TARGET_ERROR_REPORT_BITMASK cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask); - - return (ret==0 ? ret : -EINVAL); -} - -static int -ar6000_clear_target_stats(struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - TARGET_STATS *pStats = &ar->arTargetStats; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - AR6000_SPIN_LOCK(&ar->arLock, 0); - A_MEMZERO(pStats, sizeof(TARGET_STATS)); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - return ret; -} - -static int -ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - TARGET_STATS_CMD cmd; - TARGET_STATS *pStats = &ar->arTargetStats; - int ret = 0; - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - if (ar->arWmiReady == false) { - return -EIO; - } - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - return -EBUSY; - } - - ar->statsUpdatePending = true; - - if(wmi_get_stats_cmd(ar->arWmi) != 0) { - up(&ar->arSem); - return -EIO; - } - - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - - if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) { - ret = -EFAULT; - } - - if (cmd.clearStats == 1) { - ret = ar6000_clear_target_stats(dev); - } - - up(&ar->arSem); - - return ret; -} - -static int -ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */ - WMI_AP_MODE_STAT *pStats = &ar->arAPStats; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1), - sizeof(u32))) - { - return -EFAULT; - } - if (action == AP_CLEAR_STATS) { - u8 i; - AR6000_SPIN_LOCK(&ar->arLock, 0); - for(i = 0; i < AP_MAX_NUM_STA; i++) { - pStats->sta[i].tx_bytes = 0; - pStats->sta[i].tx_pkts = 0; - pStats->sta[i].tx_error = 0; - pStats->sta[i].tx_discard = 0; - pStats->sta[i].rx_bytes = 0; - pStats->sta[i].rx_pkts = 0; - pStats->sta[i].rx_error = 0; - pStats->sta[i].rx_discard = 0; - } - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - return ret; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - ar->statsUpdatePending = true; - - if(wmi_get_stats_cmd(ar->arWmi) != 0) { - up(&ar->arSem); - return -EIO; - } - - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - - if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) { - ret = -EFAULT; - } - - up(&ar->arSem); - - return ret; -} - -static int -ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_ACCESS_PARAMS_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_access_params_cmd(ar->arWmi, cmd.ac, cmd.txop, cmd.eCWmin, cmd.eCWmax, - cmd.aifsn) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return (ret); -} - -static int -ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_DISC_TIMEOUT_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return (ret); -} - -static int -ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_VOICE_PKT_SIZE_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - - return (ret); -} - -static int -ar6000_xioctl_set_max_sp_len(struct net_device *dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_MAX_SP_LEN_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return (ret); -} - - -static int -ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BT_STATUS_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return (ret); -} - -static int -ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BT_PARAMS_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return (ret); -} - -static int -ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_FE_ANT_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, - char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_DEBUG_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - - return(ret); -} - -static int -ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char *userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == 0) - { - ret = 0; - } else { - ret = -EINVAL; - } - return(ret); -} - -static int -ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char *userdata, - struct ifreq *rq) -{ - - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - AR6000_BTCOEX_CONFIG btcoexConfig; - WMI_BTCOEX_CONFIG_EVENT *pbtcoexConfigEv = &ar->arBtcoexConfig; - - int ret = 0; - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - if (ar->arWmiReady == false) { - return -EIO; - } - if (copy_from_user(&btcoexConfig.configCmd, userdata, sizeof(AR6000_BTCOEX_CONFIG))) { - return -EFAULT; - } - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoexConfig.configCmd) != 0) - { - up(&ar->arSem); - return -EIO; - } - - ar->statsUpdatePending = true; - - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - - if (!ret && copy_to_user(btcoexConfig.configEvent, pbtcoexConfigEv, sizeof(WMI_BTCOEX_CONFIG_EVENT))) { - ret = -EFAULT; - } - up(&ar->arSem); - return ret; -} - -static int -ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, struct ifreq *rq) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - AR6000_BTCOEX_STATS btcoexStats; - WMI_BTCOEX_STATS_EVENT *pbtcoexStats = &ar->arBtcoexStats; - int ret = 0; - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - if (ar->arWmiReady == false) { - return -EIO; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (copy_from_user(&btcoexStats.statsEvent, userdata, sizeof(AR6000_BTCOEX_CONFIG))) { - return -EFAULT; - } - - if (wmi_get_btcoex_stats_cmd(ar->arWmi) != 0) - { - up(&ar->arSem); - return -EIO; - } - - ar->statsUpdatePending = true; - - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - - if (!ret && copy_to_user(btcoexStats.statsEvent, pbtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT))) { - ret = -EFAULT; - } - - - up(&ar->arSem); - - return(ret); -} - -static int -ar6000_xioctl_set_excess_tx_retry_thres_cmd(struct net_device * dev, char * userdata) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_SET_EXCESS_TX_RETRY_THRES_CMD cmd; - int ret = 0; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - return -EFAULT; - } - - if (wmi_set_excess_tx_retry_thres_cmd(ar->arWmi, &cmd) != 0) - { - ret = -EINVAL; - } - return(ret); -} - -#ifdef CONFIG_HOST_GPIO_SUPPORT -struct ar6000_gpio_intr_wait_cmd_s gpio_intr_results; -/* gpio_reg_results and gpio_data_available are protected by arSem */ -static struct ar6000_gpio_register_cmd_s gpio_reg_results; -static bool gpio_data_available; /* Requested GPIO data available */ -static bool gpio_intr_available; /* GPIO interrupt info available */ -static bool gpio_ack_received; /* GPIO ack was received */ - -/* Host-side initialization for General Purpose I/O support */ -void ar6000_gpio_init(void) -{ - gpio_intr_available = false; - gpio_data_available = false; - gpio_ack_received = false; -} - -/* - * Called when a GPIO interrupt is received from the Target. - * intr_values shows which GPIO pins have interrupted. - * input_values shows a recent value of GPIO pins. - */ -void -ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values) -{ - gpio_intr_results.intr_mask = intr_mask; - gpio_intr_results.input_values = input_values; - *((volatile bool *)&gpio_intr_available) = true; - wake_up(&arEvent); -} - -/* - * This is called when a response is received from the Target - * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get - * call. - */ -void -ar6000_gpio_data_rx(u32 reg_id, u32 value) -{ - gpio_reg_results.gpioreg_id = reg_id; - gpio_reg_results.value = value; - *((volatile bool *)&gpio_data_available) = true; - wake_up(&arEvent); -} - -/* - * This is called when an acknowledgement is received from the Target - * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set - * call. - */ -void -ar6000_gpio_ack_rx(void) -{ - gpio_ack_received = true; - wake_up(&arEvent); -} - -int -ar6000_gpio_output_set(struct net_device *dev, - u32 set_mask, - u32 clear_mask, - u32 enable_mask, - u32 disable_mask) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - gpio_ack_received = false; - return wmi_gpio_output_set(ar->arWmi, - set_mask, clear_mask, enable_mask, disable_mask); -} - -static int -ar6000_gpio_input_get(struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - *((volatile bool *)&gpio_data_available) = false; - return wmi_gpio_input_get(ar->arWmi); -} - -static int -ar6000_gpio_register_set(struct net_device *dev, - u32 gpioreg_id, - u32 value) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - gpio_ack_received = false; - return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value); -} - -static int -ar6000_gpio_register_get(struct net_device *dev, - u32 gpioreg_id) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - *((volatile bool *)&gpio_data_available) = false; - return wmi_gpio_register_get(ar->arWmi, gpioreg_id); -} - -static int -ar6000_gpio_intr_ack(struct net_device *dev, - u32 ack_mask) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - gpio_intr_available = false; - return wmi_gpio_intr_ack(ar->arWmi, ack_mask); -} -#endif /* CONFIG_HOST_GPIO_SUPPORT */ - -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -static struct prof_count_s prof_count_results; -static bool prof_count_available; /* Requested GPIO data available */ - -static int -prof_count_get(struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - *((volatile bool *)&prof_count_available) = false; - return wmi_prof_count_get_cmd(ar->arWmi); -} - -/* - * This is called when a response is received from the Target - * for a previous prof_count_get call. - */ -void -prof_count_rx(u32 addr, u32 count) -{ - prof_count_results.addr = addr; - prof_count_results.count = count; - *((volatile bool *)&prof_count_available) = true; - wake_up(&arEvent); -} -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - -int -ar6000_ioctl_ap_setparam(struct ar6_softc *ar, int param, int value) -{ - int ret=0; - - switch(param) { - case IEEE80211_PARAM_WPA: - switch (value) { - case WPA_MODE_WPA1: - ar->arAuthMode = WPA_AUTH; - break; - case WPA_MODE_WPA2: - ar->arAuthMode = WPA2_AUTH; - break; - case WPA_MODE_AUTO: - ar->arAuthMode = WPA_AUTH | WPA2_AUTH; - break; - case WPA_MODE_NONE: - ar->arAuthMode = NONE_AUTH; - break; - } - break; - case IEEE80211_PARAM_AUTHMODE: - if(value == IEEE80211_AUTH_WPA_PSK) { - if (WPA_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA_PSK_AUTH; - } else if (WPA2_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA2_PSK_AUTH; - } else if ((WPA_AUTH | WPA2_AUTH) == ar->arAuthMode) { - ar->arAuthMode = WPA_PSK_AUTH | WPA2_PSK_AUTH; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\ - "mode when WPA param was set to %d\n", - ar->arAuthMode)); - ret = -EIO; - } - } - break; - case IEEE80211_PARAM_UCASTCIPHER: - ar->arPairwiseCrypto = 0; - if(value & (1<arPairwiseCrypto |= AES_CRYPT; - } - if(value & (1<arPairwiseCrypto |= TKIP_CRYPT; - } - if(!ar->arPairwiseCrypto) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Error - Invalid cipher in WPA \n")); - ret = -EIO; - } - break; - case IEEE80211_PARAM_PRIVACY: - if(value == 0) { - ar->arDot11AuthMode = OPEN_AUTH; - ar->arAuthMode = NONE_AUTH; - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arPairwiseCryptoLen = 0; - ar->arGroupCrypto = NONE_CRYPT; - ar->arGroupCryptoLen = 0; - } - break; -#ifdef WAPI_ENABLE - case IEEE80211_PARAM_WAPI: - A_PRINTF("WAPI Policy: %d\n", value); - ar->arDot11AuthMode = OPEN_AUTH; - ar->arAuthMode = NONE_AUTH; - if(value & 0x1) { - ar->arPairwiseCrypto = WAPI_CRYPT; - ar->arGroupCrypto = WAPI_CRYPT; - } else { - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arGroupCrypto = NONE_CRYPT; - } - break; -#endif - } - return ret; -} - -int -ar6000_ioctl_setparam(struct ar6_softc *ar, int param, int value) -{ - bool profChanged = false; - int ret=0; - - if(ar->arNextMode == AP_NETWORK) { - ar->ap_profile_flag = 1; /* There is a change in profile */ - switch (param) { - case IEEE80211_PARAM_WPA: - case IEEE80211_PARAM_AUTHMODE: - case IEEE80211_PARAM_UCASTCIPHER: - case IEEE80211_PARAM_PRIVACY: - case IEEE80211_PARAM_WAPI: - ret = ar6000_ioctl_ap_setparam(ar, param, value); - return ret; - } - } - - switch (param) { - case IEEE80211_PARAM_WPA: - switch (value) { - case WPA_MODE_WPA1: - ar->arAuthMode = WPA_AUTH; - profChanged = true; - break; - case WPA_MODE_WPA2: - ar->arAuthMode = WPA2_AUTH; - profChanged = true; - break; - case WPA_MODE_NONE: - ar->arAuthMode = NONE_AUTH; - profChanged = true; - break; - } - break; - case IEEE80211_PARAM_AUTHMODE: - switch(value) { - case IEEE80211_AUTH_WPA_PSK: - if (WPA_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA_PSK_AUTH; - profChanged = true; - } else if (WPA2_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA2_PSK_AUTH; - profChanged = true; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\ - "mode when WPA param was set to %d\n", - ar->arAuthMode)); - ret = -EIO; - } - break; - case IEEE80211_AUTH_WPA_CCKM: - if (WPA2_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA2_AUTH_CCKM; - } else { - ar->arAuthMode = WPA_AUTH_CCKM; - } - break; - default: - break; - } - break; - case IEEE80211_PARAM_UCASTCIPHER: - switch (value) { - case IEEE80211_CIPHER_AES_CCM: - ar->arPairwiseCrypto = AES_CRYPT; - profChanged = true; - break; - case IEEE80211_CIPHER_TKIP: - ar->arPairwiseCrypto = TKIP_CRYPT; - profChanged = true; - break; - case IEEE80211_CIPHER_WEP: - ar->arPairwiseCrypto = WEP_CRYPT; - profChanged = true; - break; - case IEEE80211_CIPHER_NONE: - ar->arPairwiseCrypto = NONE_CRYPT; - profChanged = true; - break; - } - break; - case IEEE80211_PARAM_UCASTKEYLEN: - if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) { - ret = -EIO; - } else { - ar->arPairwiseCryptoLen = value; - } - break; - case IEEE80211_PARAM_MCASTCIPHER: - switch (value) { - case IEEE80211_CIPHER_AES_CCM: - ar->arGroupCrypto = AES_CRYPT; - profChanged = true; - break; - case IEEE80211_CIPHER_TKIP: - ar->arGroupCrypto = TKIP_CRYPT; - profChanged = true; - break; - case IEEE80211_CIPHER_WEP: - ar->arGroupCrypto = WEP_CRYPT; - profChanged = true; - break; - case IEEE80211_CIPHER_NONE: - ar->arGroupCrypto = NONE_CRYPT; - profChanged = true; - break; - } - break; - case IEEE80211_PARAM_MCASTKEYLEN: - if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) { - ret = -EIO; - } else { - ar->arGroupCryptoLen = value; - } - break; - case IEEE80211_PARAM_COUNTERMEASURES: - if (ar->arWmiReady == false) { - return -EIO; - } - wmi_set_tkip_countermeasures_cmd(ar->arWmi, value); - break; - default: - break; - } - if ((ar->arNextMode != AP_NETWORK) && (profChanged == true)) { - /* - * profile has changed. Erase ssid to signal change - */ - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - } - - return ret; -} - -int -ar6000_ioctl_setkey(struct ar6_softc *ar, struct ieee80211req_key *ik) -{ - KEY_USAGE keyUsage; - int status; - CRYPTO_TYPE keyType = NONE_CRYPT; - -#ifdef USER_KEYS - ar->user_saved_keys.keyOk = false; -#endif - if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) || - (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) { - keyUsage = GROUP_USAGE; - if(ar->arNextMode == AP_NETWORK) { - memcpy(&ar->ap_mode_bkey, ik, - sizeof(struct ieee80211req_key)); -#ifdef WAPI_ENABLE - if(ar->arPairwiseCrypto == WAPI_CRYPT) { - return ap_set_wapi_key(ar, ik); - } -#endif - } -#ifdef USER_KEYS - memcpy(&ar->user_saved_keys.bcast_ik, ik, - sizeof(struct ieee80211req_key)); -#endif - } else { - keyUsage = PAIRWISE_USAGE; -#ifdef USER_KEYS - memcpy(&ar->user_saved_keys.ucast_ik, ik, - sizeof(struct ieee80211req_key)); -#endif -#ifdef WAPI_ENABLE - if(ar->arNextMode == AP_NETWORK) { - if(ar->arPairwiseCrypto == WAPI_CRYPT) { - return ap_set_wapi_key(ar, ik); - } - } -#endif - } - - switch (ik->ik_type) { - case IEEE80211_CIPHER_WEP: - keyType = WEP_CRYPT; - break; - case IEEE80211_CIPHER_TKIP: - keyType = TKIP_CRYPT; - break; - case IEEE80211_CIPHER_AES_CCM: - keyType = AES_CRYPT; - break; - default: - break; - } -#ifdef USER_KEYS - ar->user_saved_keys.keyType = keyType; -#endif - if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) { - if (NONE_CRYPT == keyType) { - return -EIO; - } - - if ((WEP_CRYPT == keyType)&&(!ar->arConnected)) { - int index = ik->ik_keyix; - - if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) { - return -EIO; - } - - A_MEMZERO(ar->arWepKeyList[index].arKey, - sizeof(ar->arWepKeyList[index].arKey)); - memcpy(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen); - ar->arWepKeyList[index].arKeyLen = ik->ik_keylen; - - if(ik->ik_flags & IEEE80211_KEY_DEFAULT){ - ar->arDefTxKeyIndex = index; - } - - return 0; - } - - if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) && - (GROUP_USAGE & keyUsage)) - { - A_UNTIMEOUT(&ar->disconnect_timer); - } - - status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage, - ik->ik_keylen, (u8 *)&ik->ik_keyrsc, - ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, - SYNC_BOTH_WMIFLAG); - - if (status) { - return -EIO; - } - } else { - status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata); - } - -#ifdef USER_KEYS - ar->user_saved_keys.keyOk = true; -#endif - - return 0; -} - -int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct hif_device *hifDevice = ar->arHifDevice; - int ret = 0, param; - unsigned int address = 0; - unsigned int length = 0; - unsigned char *buffer; - char *userdata; - u32 connectCtrlFlags; - - - WMI_SET_AKMP_PARAMS_CMD akmpParams; - WMI_SET_PMKID_LIST_CMD pmkidInfo; - - WMI_SET_HT_CAP_CMD htCap; - WMI_SET_HT_OP_CMD htOp; - - /* - * ioctl operations may have to wait for the Target, so we cannot hold rtnl. - * Prevent the device from disappearing under us and release the lock during - * the ioctl operation. - */ - dev_hold(dev); - rtnl_unlock(); - - if (cmd == AR6000_IOCTL_EXTENDED) { - /* - * This allows for many more wireless ioctls than would otherwise - * be available. Applications embed the actual ioctl command in - * the first word of the parameter block, and use the command - * AR6000_IOCTL_EXTENDED_CMD on the ioctl call. - */ - if (get_user(cmd, (int *)rq->ifr_data)) { - ret = -EFAULT; - goto ioctl_done; - } - userdata = (char *)(((unsigned int *)rq->ifr_data)+1); - if(is_xioctl_allowed(ar->arNextMode, cmd) != 0) { - A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd); - ret = -EOPNOTSUPP; - goto ioctl_done; - } - } else { - int ret = is_iwioctl_allowed(ar->arNextMode, cmd); - if(ret == A_ENOTSUP) { - A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd); - ret = -EOPNOTSUPP; - goto ioctl_done; - } else if (ret == A_ERROR) { - /* It is not our ioctl (out of range ioctl) */ - ret = -EOPNOTSUPP; - goto ioctl_done; - } - userdata = (char *)rq->ifr_data; - } - - if ((ar->arWlanState == WLAN_DISABLED) && - ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) && - (cmd != AR6000_XIOCTL_GET_WLAN_SLEEP_STATE) && - (cmd != AR6000_XIOCTL_DIAG_READ) && - (cmd != AR6000_XIOCTL_DIAG_WRITE) && - (cmd != AR6000_XIOCTL_SET_BT_HW_POWER_STATE) && - (cmd != AR6000_XIOCTL_GET_BT_HW_POWER_STATE) && - (cmd != AR6000_XIOCTL_ADD_AP_INTERFACE) && - (cmd != AR6000_XIOCTL_REMOVE_AP_INTERFACE) && - (cmd != AR6000_IOCTL_WMI_GETREV))) - { - ret = -EIO; - goto ioctl_done; - } - - ret = 0; - switch(cmd) - { - case IEEE80211_IOCTL_SETPARAM: - { - int param, value; - int *ptr = (int *)rq->ifr_ifru.ifru_newname; - if (ar->arWmiReady == false) { - ret = -EIO; - } else { - param = *ptr++; - value = *ptr; - ret = ar6000_ioctl_setparam(ar,param,value); - } - break; - } - case IEEE80211_IOCTL_SETKEY: - { - struct ieee80211req_key keydata; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&keydata, userdata, - sizeof(struct ieee80211req_key))) { - ret = -EFAULT; - } else { - ar6000_ioctl_setkey(ar, &keydata); - } - break; - } - case IEEE80211_IOCTL_DELKEY: - case IEEE80211_IOCTL_SETOPTIE: - { - //ret = -EIO; - break; - } - case IEEE80211_IOCTL_SETMLME: - { - struct ieee80211req_mlme mlme; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&mlme, userdata, - sizeof(struct ieee80211req_mlme))) { - ret = -EFAULT; - } else { - switch (mlme.im_op) { - case IEEE80211_MLME_AUTHORIZE: - A_PRINTF("setmlme AUTHORIZE %02X:%02X\n", - mlme.im_macaddr[4], mlme.im_macaddr[5]); - break; - case IEEE80211_MLME_UNAUTHORIZE: - A_PRINTF("setmlme UNAUTHORIZE %02X:%02X\n", - mlme.im_macaddr[4], mlme.im_macaddr[5]); - break; - case IEEE80211_MLME_DEAUTH: - A_PRINTF("setmlme DEAUTH %02X:%02X\n", - mlme.im_macaddr[4], mlme.im_macaddr[5]); - //remove_sta(ar, mlme.im_macaddr); - break; - case IEEE80211_MLME_DISASSOC: - A_PRINTF("setmlme DISASSOC %02X:%02X\n", - mlme.im_macaddr[4], mlme.im_macaddr[5]); - //remove_sta(ar, mlme.im_macaddr); - break; - default: - ret = 0; - goto ioctl_done; - } - - wmi_ap_set_mlme(ar->arWmi, mlme.im_op, mlme.im_macaddr, - mlme.im_reason); - } - break; - } - case IEEE80211_IOCTL_ADDPMKID: - { - struct ieee80211req_addpmkid req; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) { - ret = -EFAULT; - } else { - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n", - req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2], - req.pi_bssid[3], req.pi_bssid[4], req.pi_bssid[5], - req.pi_enable)); - - status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid, - req.pi_enable); - - if (status) { - ret = -EIO; - goto ioctl_done; - } - } - break; - } -#ifdef CONFIG_HOST_TCMD_SUPPORT - case AR6000_XIOCTL_TCMD_CONT_TX: - { - TCMD_CONT_TX txCmd; - - if ((ar->tcmdPm == TCMD_PM_SLEEP) || - (ar->tcmdPm == TCMD_PM_DEEPSLEEP)) - { - A_PRINTF("Can NOT send tx tcmd when target is asleep! \n"); - ret = -EFAULT; - goto ioctl_done; - } - - if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX))) { - ret = -EFAULT; - goto ioctl_done; - } else { - wmi_test_cmd(ar->arWmi,(u8 *)&txCmd, sizeof(TCMD_CONT_TX)); - } - } - break; - case AR6000_XIOCTL_TCMD_CONT_RX: - { - TCMD_CONT_RX rxCmd; - - if ((ar->tcmdPm == TCMD_PM_SLEEP) || - (ar->tcmdPm == TCMD_PM_DEEPSLEEP)) - { - A_PRINTF("Can NOT send rx tcmd when target is asleep! \n"); - ret = -EFAULT; - goto ioctl_done; - } - if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX))) { - ret = -EFAULT; - goto ioctl_done; - } - - switch(rxCmd.act) - { - case TCMD_CONT_RX_PROMIS: - case TCMD_CONT_RX_FILTER: - case TCMD_CONT_RX_SETMAC: - case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE: - wmi_test_cmd(ar->arWmi,(u8 *)&rxCmd, - sizeof(TCMD_CONT_RX)); - tcmdRxFreq = rxCmd.u.para.freq; - break; - case TCMD_CONT_RX_REPORT: - ar6000_ioctl_tcmd_get_rx_report(dev, rq, - (u8 *)&rxCmd, sizeof(TCMD_CONT_RX)); - break; - default: - A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act); - ret = -EINVAL; - goto ioctl_done; - } - } - break; - case AR6000_XIOCTL_TCMD_PM: - { - TCMD_PM pmCmd; - - if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM))) { - ret = -EFAULT; - goto ioctl_done; - } - ar->tcmdPm = pmCmd.mode; - wmi_test_cmd(ar->arWmi, (u8 *)&pmCmd, sizeof(TCMD_PM)); - } - break; -#endif /* CONFIG_HOST_TCMD_SUPPORT */ - - case AR6000_XIOCTL_BMI_DONE: - rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */ - ret = ar6000_init(dev); - rtnl_unlock(); - break; - - case AR6000_XIOCTL_BMI_READ_MEMORY: - if (get_user(address, (unsigned int *)userdata) || - get_user(length, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n", - address, length)); - if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { - A_MEMZERO(buffer, length); - ret = BMIReadMemory(hifDevice, address, buffer, length); - if (copy_to_user(rq->ifr_data, buffer, length)) { - ret = -EFAULT; - } - kfree(buffer); - } else { - ret = -ENOMEM; - } - break; - - case AR6000_XIOCTL_BMI_WRITE_MEMORY: - if (get_user(address, (unsigned int *)userdata) || - get_user(length, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length: %d)\n", - address, length)); - if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { - A_MEMZERO(buffer, length); - if (copy_from_user(buffer, &userdata[sizeof(address) + - sizeof(length)], length)) - { - ret = -EFAULT; - } else { - ret = BMIWriteMemory(hifDevice, address, buffer, length); - } - kfree(buffer); - } else { - ret = -ENOMEM; - } - break; - - case AR6000_XIOCTL_BMI_TEST: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("No longer supported\n")); - ret = -EOPNOTSUPP; - break; - - case AR6000_XIOCTL_BMI_EXECUTE: - if (get_user(address, (unsigned int *)userdata) || - get_user(param, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n", - address, param)); - ret = BMIExecute(hifDevice, address, (u32 *)¶m); - /* return value */ - if (put_user(param, (unsigned int *)rq->ifr_data)) { - ret = -EFAULT; - break; - } - break; - - case AR6000_XIOCTL_BMI_SET_APP_START: - if (get_user(address, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", address)); - ret = BMISetAppStart(hifDevice, address); - break; - - case AR6000_XIOCTL_BMI_READ_SOC_REGISTER: - if (get_user(address, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - ret = BMIReadSOCRegister(hifDevice, address, (u32 *)¶m); - /* return value */ - if (put_user(param, (unsigned int *)rq->ifr_data)) { - ret = -EFAULT; - break; - } - break; - - case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER: - if (get_user(address, (unsigned int *)userdata) || - get_user(param, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - ret = BMIWriteSOCRegister(hifDevice, address, param); - break; - -#ifdef HTC_RAW_INTERFACE - case AR6000_XIOCTL_HTC_RAW_OPEN: - ret = 0; - if (!arRawIfEnabled(ar)) { - /* make sure block size is set in case the target was reset since last - * BMI phase (i.e. flashup downloads) */ - ret = ar6000_set_htc_params(ar->arHifDevice, - ar->arTargetType, - 0, /* use default yield */ - 0 /* use default number of HTC ctrl buffers */ - ); - if (ret) { - break; - } - /* Terminate the BMI phase */ - ret = BMIDone(hifDevice); - if (ret == 0) { - ret = ar6000_htc_raw_open(ar); - } - } - break; - - case AR6000_XIOCTL_HTC_RAW_CLOSE: - if (arRawIfEnabled(ar)) { - ret = ar6000_htc_raw_close(ar); - arRawIfEnabled(ar) = false; - } else { - ret = A_ERROR; - } - break; - - case AR6000_XIOCTL_HTC_RAW_READ: - if (arRawIfEnabled(ar)) { - unsigned int streamID; - if (get_user(streamID, (unsigned int *)userdata) || - get_user(length, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - buffer = (unsigned char*)rq->ifr_data + sizeof(length); - ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID, - (char*)buffer, length); - if (put_user(ret, (unsigned int *)rq->ifr_data)) { - ret = -EFAULT; - break; - } - } else { - ret = A_ERROR; - } - break; - - case AR6000_XIOCTL_HTC_RAW_WRITE: - if (arRawIfEnabled(ar)) { - unsigned int streamID; - if (get_user(streamID, (unsigned int *)userdata) || - get_user(length, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - buffer = (unsigned char*)userdata + sizeof(streamID) + sizeof(length); - ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID, - (char*)buffer, length); - if (put_user(ret, (unsigned int *)rq->ifr_data)) { - ret = -EFAULT; - break; - } - } else { - ret = A_ERROR; - } - break; -#endif /* HTC_RAW_INTERFACE */ - - case AR6000_XIOCTL_BMI_LZ_STREAM_START: - if (get_user(address, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0x%x)\n", address)); - ret = BMILZStreamStart(hifDevice, address); - break; - - case AR6000_XIOCTL_BMI_LZ_DATA: - if (get_user(length, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n", length)); - if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { - A_MEMZERO(buffer, length); - if (copy_from_user(buffer, &userdata[sizeof(length)], length)) - { - ret = -EFAULT; - } else { - ret = BMILZData(hifDevice, buffer, length); - } - kfree(buffer); - } else { - ret = -ENOMEM; - } - break; - -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) - /* - * Optional support for Target-side profiling. - * Not needed in production. - */ - - /* Configure Target-side profiling */ - case AR6000_XIOCTL_PROF_CFG: - { - u32 period; - u32 nbins; - if (get_user(period, (unsigned int *)userdata) || - get_user(nbins, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - - if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != 0) { - ret = -EIO; - } - - break; - } - - /* Start a profiling bucket/bin at the specified address */ - case AR6000_XIOCTL_PROF_ADDR_SET: - { - u32 addr; - if (get_user(addr, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - - if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != 0) { - ret = -EIO; - } - - break; - } - - /* START Target-side profiling */ - case AR6000_XIOCTL_PROF_START: - wmi_prof_start_cmd(ar->arWmi); - break; - - /* STOP Target-side profiling */ - case AR6000_XIOCTL_PROF_STOP: - wmi_prof_stop_cmd(ar->arWmi); - break; - case AR6000_XIOCTL_PROF_COUNT_GET: - { - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - - prof_count_available = false; - ret = prof_count_get(dev); - if (ret != 0) { - up(&ar->arSem); - ret = -EIO; - goto ioctl_done; - } - - /* Wait for Target to respond. */ - wait_event_interruptible(arEvent, prof_count_available); - if (signal_pending(current)) { - ret = -EINTR; - } else { - if (copy_to_user(userdata, &prof_count_results, - sizeof(prof_count_results))) - { - ret = -EFAULT; - } - } - up(&ar->arSem); - break; - } -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - - case AR6000_IOCTL_WMI_GETREV: - { - if (copy_to_user(rq->ifr_data, &ar->arVersion, - sizeof(ar->arVersion))) - { - ret = -EFAULT; - } - break; - } - case AR6000_IOCTL_WMI_SETPWR: - { - WMI_POWER_MODE_CMD pwrModeCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&pwrModeCmd, userdata, - sizeof(pwrModeCmd))) - { - ret = -EFAULT; - } else { - if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode) - != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS: - { - WMI_IBSS_PM_CAPS_CMD ibssPmCaps; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&ibssPmCaps, userdata, - sizeof(ibssPmCaps))) - { - ret = -EFAULT; - } else { - if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl, - ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != 0) - { - ret = -EIO; - } - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arIbssPsEnable = ibssPmCaps.power_saving; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } - break; - } - case AR6000_XIOCTL_WMI_SET_AP_PS: - { - WMI_AP_PS_CMD apPsCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&apPsCmd, userdata, - sizeof(apPsCmd))) - { - ret = -EFAULT; - } else { - if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time, - apPsCmd.ps_period, apPsCmd.sleep_period) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_IOCTL_WMI_SET_PMPARAMS: - { - WMI_POWER_PARAMS_CMD pmParams; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&pmParams, userdata, - sizeof(pmParams))) - { - ret = -EFAULT; - } else { - if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period, - pmParams.pspoll_number, - pmParams.dtim_policy, - pmParams.tx_wakeup_policy, - pmParams.num_tx_to_wakeup, -#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN - IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN -#else - SEND_POWER_SAVE_FAIL_EVENT_ALWAYS -#endif - ) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_IOCTL_WMI_SETSCAN: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&ar->scParams, userdata, - sizeof(ar->scParams))) - { - ret = -EFAULT; - } else { - if (CAN_SCAN_IN_CONNECT(ar->scParams.scanCtrlFlags)) { - ar->arSkipScan = false; - } else { - ar->arSkipScan = true; - } - - if (wmi_scanparams_cmd(ar->arWmi, ar->scParams.fg_start_period, - ar->scParams.fg_end_period, - ar->scParams.bg_period, - ar->scParams.minact_chdwell_time, - ar->scParams.maxact_chdwell_time, - ar->scParams.pas_chdwell_time, - ar->scParams.shortScanRatio, - ar->scParams.scanCtrlFlags, - ar->scParams.max_dfsch_act_time, - ar->scParams.maxact_scan_per_ssid) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_IOCTL_WMI_SETLISTENINT: - { - WMI_LISTEN_INT_CMD listenCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&listenCmd, userdata, - sizeof(listenCmd))) - { - ret = -EFAULT; - } else { - if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != 0) { - ret = -EIO; - } else { - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arListenIntervalT = listenCmd.listenInterval; - ar->arListenIntervalB = listenCmd.numBeacons; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } - - } - break; - } - case AR6000_IOCTL_WMI_SET_BMISS_TIME: - { - WMI_BMISS_TIME_CMD bmissCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&bmissCmd, userdata, - sizeof(bmissCmd))) - { - ret = -EFAULT; - } else { - if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != 0) { - ret = -EIO; - } - } - break; - } - case AR6000_IOCTL_WMI_SETBSSFILTER: - { - WMI_BSS_FILTER_CMD filt; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&filt, userdata, - sizeof(filt))) - { - ret = -EFAULT; - } else { - if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask) - != 0) { - ret = -EIO; - } else { - ar->arUserBssFilter = filt.bssFilter; - } - } - break; - } - - case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD: - { - ret = ar6000_ioctl_set_snr_threshold(dev, rq); - break; - } - case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD: - { - ret = ar6000_ioctl_set_rssi_threshold(dev, rq); - break; - } - case AR6000_XIOCTL_WMI_CLR_RSSISNR: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } - ret = wmi_clr_rssi_snr(ar->arWmi); - break; - } - case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD: - { - ret = ar6000_ioctl_set_lq_threshold(dev, rq); - break; - } - case AR6000_XIOCTL_WMI_SET_LPREAMBLE: - { - WMI_SET_LPREAMBLE_CMD setLpreambleCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setLpreambleCmd, userdata, - sizeof(setLpreambleCmd))) - { - ret = -EFAULT; - } else { - if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status, -#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP - WMI_DONOT_IGNORE_BARKER_IN_ERP -#else - WMI_IGNORE_BARKER_IN_ERP -#endif - ) != 0) - { - ret = -EIO; - } - } - - break; - } - case AR6000_XIOCTL_WMI_SET_RTS: - { - WMI_SET_RTS_CMD rtsCmd; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&rtsCmd, userdata, - sizeof(rtsCmd))) - { - ret = -EFAULT; - } else { - ar->arRTS = rtsCmd.threshold; - if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold) - != 0) - { - ret = -EIO; - } - } - - break; - } - case AR6000_XIOCTL_WMI_SET_WMM: - { - ret = ar6000_ioctl_set_wmm(dev, rq); - break; - } - case AR6000_XIOCTL_WMI_SET_QOS_SUPP: - { - ret = ar6000_ioctl_set_qos_supp(dev, rq); - break; - } - case AR6000_XIOCTL_WMI_SET_TXOP: - { - ret = ar6000_ioctl_set_txop(dev, rq); - break; - } - case AR6000_XIOCTL_WMI_GET_RD: - { - ret = ar6000_ioctl_get_rd(dev, rq); - break; - } - case AR6000_IOCTL_WMI_SET_CHANNELPARAMS: - { - ret = ar6000_ioctl_set_channelParams(dev, rq); - break; - } - case AR6000_IOCTL_WMI_SET_PROBEDSSID: - { - ret = ar6000_ioctl_set_probedSsid(dev, rq); - break; - } - case AR6000_IOCTL_WMI_SET_BADAP: - { - ret = ar6000_ioctl_set_badAp(dev, rq); - break; - } - case AR6000_IOCTL_WMI_CREATE_QOS: - { - ret = ar6000_ioctl_create_qos(dev, rq); - break; - } - case AR6000_IOCTL_WMI_DELETE_QOS: - { - ret = ar6000_ioctl_delete_qos(dev, rq); - break; - } - case AR6000_IOCTL_WMI_GET_QOS_QUEUE: - { - ret = ar6000_ioctl_get_qos_queue(dev, rq); - break; - } - case AR6000_IOCTL_WMI_GET_TARGET_STATS: - { - ret = ar6000_ioctl_get_target_stats(dev, rq); - break; - } - case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK: - { - ret = ar6000_ioctl_set_error_report_bitmask(dev, rq); - break; - } - case AR6000_IOCTL_WMI_SET_ASSOC_INFO: - { - WMI_SET_ASSOC_INFO_CMD cmd; - u8 assocInfo[WMI_MAX_ASSOC_INFO_LEN]; - - if (ar->arWmiReady == false) { - ret = -EIO; - break; - } - - if (get_user(cmd.ieType, userdata)) { - ret = -EFAULT; - break; - } - if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) { - ret = -EIO; - break; - } - - if (get_user(cmd.bufferSize, userdata + 1) || - (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) || - copy_from_user(assocInfo, userdata + 2, cmd.bufferSize)) { - ret = -EFAULT; - break; - } - if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType, - cmd.bufferSize, assocInfo) != 0) { - ret = -EIO; - break; - } - break; - } - case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS: - { - ret = ar6000_ioctl_set_access_params(dev, rq); - break; - } - case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT: - { - ret = ar6000_ioctl_set_disconnect_timeout(dev, rq); - break; - } - case AR6000_XIOCTL_FORCE_TARGET_RESET: - { - if (ar->arHtcTarget) - { -// HTCForceReset(htcTarget); - } - else - { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("ar6000_ioctl cannot attempt reset.\n")); - } - break; - } - case AR6000_XIOCTL_TARGET_INFO: - case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */ - { - /* If we made it to here, then the Target exists and is ready. */ - - if (cmd == AR6000_XIOCTL_TARGET_INFO) { - if (copy_to_user((u32 *)rq->ifr_data, &ar->arVersion.target_ver, - sizeof(ar->arVersion.target_ver))) - { - ret = -EFAULT; - } - if (copy_to_user(((u32 *)rq->ifr_data)+1, &ar->arTargetType, - sizeof(ar->arTargetType))) - { - ret = -EFAULT; - } - } - break; - } - case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS: - { - WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam; - - if (copy_from_user(&hbparam, userdata, sizeof(hbparam))) - { - ret = -EFAULT; - } else { - AR6000_SPIN_LOCK(&ar->arLock, 0); - /* Start a cyclic timer with the parameters provided. */ - if (hbparam.frequency) { - ar->arHBChallengeResp.frequency = hbparam.frequency; - } - if (hbparam.threshold) { - ar->arHBChallengeResp.missThres = hbparam.threshold; - } - - /* Delete the pending timer and start a new one */ - if (timer_pending(&ar->arHBChallengeResp.timer)) { - A_UNTIMEOUT(&ar->arHBChallengeResp.timer); - } - A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } - break; - } - case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP: - { - u32 cookie; - - if (copy_from_user(&cookie, userdata, sizeof(cookie))) { - ret = -EFAULT; - goto ioctl_done; - } - - /* Send the challenge on the control channel */ - if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != 0) { - ret = -EIO; - goto ioctl_done; - } - break; - } -#ifdef USER_KEYS - case AR6000_XIOCTL_USER_SETKEYS: - { - - ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN; - - if (copy_from_user(&ar->user_key_ctrl, userdata, - sizeof(ar->user_key_ctrl))) - { - ret = -EFAULT; - goto ioctl_done; - } - - A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl); - break; - } -#endif /* USER_KEYS */ - -#ifdef CONFIG_HOST_GPIO_SUPPORT - case AR6000_XIOCTL_GPIO_OUTPUT_SET: - { - struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd; - - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - - if (copy_from_user(&gpio_output_set_cmd, userdata, - sizeof(gpio_output_set_cmd))) - { - ret = -EFAULT; - } else { - ret = ar6000_gpio_output_set(dev, - gpio_output_set_cmd.set_mask, - gpio_output_set_cmd.clear_mask, - gpio_output_set_cmd.enable_mask, - gpio_output_set_cmd.disable_mask); - if (ret != 0) { - ret = -EIO; - } - } - up(&ar->arSem); - break; - } - case AR6000_XIOCTL_GPIO_INPUT_GET: - { - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - - ret = ar6000_gpio_input_get(dev); - if (ret != 0) { - up(&ar->arSem); - ret = -EIO; - goto ioctl_done; - } - - /* Wait for Target to respond. */ - wait_event_interruptible(arEvent, gpio_data_available); - if (signal_pending(current)) { - ret = -EINTR; - } else { - A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE); - - if (copy_to_user(userdata, &gpio_reg_results.value, - sizeof(gpio_reg_results.value))) - { - ret = -EFAULT; - } - } - up(&ar->arSem); - break; - } - case AR6000_XIOCTL_GPIO_REGISTER_SET: - { - struct ar6000_gpio_register_cmd_s gpio_register_cmd; - - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - - if (copy_from_user(&gpio_register_cmd, userdata, - sizeof(gpio_register_cmd))) - { - ret = -EFAULT; - } else { - ret = ar6000_gpio_register_set(dev, - gpio_register_cmd.gpioreg_id, - gpio_register_cmd.value); - if (ret != 0) { - ret = -EIO; - } - - /* Wait for acknowledgement from Target */ - wait_event_interruptible(arEvent, gpio_ack_received); - if (signal_pending(current)) { - ret = -EINTR; - } - } - up(&ar->arSem); - break; - } - case AR6000_XIOCTL_GPIO_REGISTER_GET: - { - struct ar6000_gpio_register_cmd_s gpio_register_cmd; - - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - - if (copy_from_user(&gpio_register_cmd, userdata, - sizeof(gpio_register_cmd))) - { - ret = -EFAULT; - } else { - ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id); - if (ret != 0) { - up(&ar->arSem); - ret = -EIO; - goto ioctl_done; - } - - /* Wait for Target to respond. */ - wait_event_interruptible(arEvent, gpio_data_available); - if (signal_pending(current)) { - ret = -EINTR; - } else { - A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id); - if (copy_to_user(userdata, &gpio_reg_results, - sizeof(gpio_reg_results))) - { - ret = -EFAULT; - } - } - } - up(&ar->arSem); - break; - } - case AR6000_XIOCTL_GPIO_INTR_ACK: - { - struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd; - - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - - if (copy_from_user(&gpio_intr_ack_cmd, userdata, - sizeof(gpio_intr_ack_cmd))) - { - ret = -EFAULT; - } else { - ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask); - if (ret != 0) { - ret = -EIO; - } - } - up(&ar->arSem); - break; - } - case AR6000_XIOCTL_GPIO_INTR_WAIT: - { - /* Wait for Target to report an interrupt. */ - wait_event_interruptible(arEvent, gpio_intr_available); - - if (signal_pending(current)) { - ret = -EINTR; - } else { - if (copy_to_user(userdata, &gpio_intr_results, - sizeof(gpio_intr_results))) - { - ret = -EFAULT; - } - } - break; - } -#endif /* CONFIG_HOST_GPIO_SUPPORT */ - - case AR6000_XIOCTL_DBGLOG_CFG_MODULE: - { - struct ar6000_dbglog_module_config_s config; - - if (copy_from_user(&config, userdata, sizeof(config))) { - ret = -EFAULT; - goto ioctl_done; - } - - /* Send the challenge on the control channel */ - if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask, - config.tsr, config.rep, - config.size, config.valid) != 0) - { - ret = -EIO; - goto ioctl_done; - } - break; - } - - case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS: - { - /* Send the challenge on the control channel */ - if (ar6000_dbglog_get_debug_logs(ar) != 0) - { - ret = -EIO; - goto ioctl_done; - } - break; - } - - case AR6000_XIOCTL_SET_ADHOC_BSSID: - { - WMI_SET_ADHOC_BSSID_CMD adhocBssid; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&adhocBssid, userdata, - sizeof(adhocBssid))) - { - ret = -EFAULT; - } else if (memcmp(adhocBssid.bssid, bcast_mac, - AR6000_ETH_ADDR_LEN) == 0) - { - ret = -EFAULT; - } else { - - memcpy(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid)); - } - break; - } - - case AR6000_XIOCTL_SET_OPT_MODE: - { - WMI_SET_OPT_MODE_CMD optModeCmd; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&optModeCmd, userdata, - sizeof(optModeCmd))) - { - ret = -EFAULT; - } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) { - ret = -EFAULT; - - } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode) - != 0) - { - ret = -EIO; - } - break; - } - - case AR6000_XIOCTL_OPT_SEND_FRAME: - { - WMI_OPT_TX_FRAME_CMD optTxFrmCmd; - u8 data[MAX_OPT_DATA_LEN]; - - if (ar->arWmiReady == false) { - ret = -EIO; - break; - } - - if (copy_from_user(&optTxFrmCmd, userdata, sizeof(optTxFrmCmd))) { - ret = -EFAULT; - break; - } - - if (optTxFrmCmd.optIEDataLen > MAX_OPT_DATA_LEN) { - ret = -EINVAL; - break; - } - - if (copy_from_user(data, userdata+sizeof(WMI_OPT_TX_FRAME_CMD) - 1, - optTxFrmCmd.optIEDataLen)) { - ret = -EFAULT; - break; - } - - ret = wmi_opt_tx_frame_cmd(ar->arWmi, - optTxFrmCmd.frmType, - optTxFrmCmd.dstAddr, - optTxFrmCmd.bssid, - optTxFrmCmd.optIEDataLen, - data); - break; - } - case AR6000_XIOCTL_WMI_SETRETRYLIMITS: - { - WMI_SET_RETRY_LIMITS_CMD setRetryParams; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setRetryParams, userdata, - sizeof(setRetryParams))) - { - ret = -EFAULT; - } else { - if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType, - setRetryParams.trafficClass, - setRetryParams.maxRetries, - setRetryParams.enableNotify) != 0) - { - ret = -EIO; - } - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arMaxRetries = setRetryParams.maxRetries; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } - break; - } - - case AR6000_XIOCTL_SET_BEACON_INTVAL: - { - WMI_BEACON_INT_CMD bIntvlCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&bIntvlCmd, userdata, - sizeof(bIntvlCmd))) - { - ret = -EFAULT; - } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval) - != 0) - { - ret = -EIO; - } - if(ret == 0) { - ar->ap_beacon_interval = bIntvlCmd.beaconInterval; - ar->ap_profile_flag = 1; /* There is a change in profile */ - } - break; - } - case IEEE80211_IOCTL_SETAUTHALG: - { - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct ieee80211req_authalg req; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&req, userdata, - sizeof(struct ieee80211req_authalg))) - { - ret = -EFAULT; - } else { - if (req.auth_alg & AUTH_ALG_OPEN_SYSTEM) { - ar->arDot11AuthMode |= OPEN_AUTH; - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arGroupCrypto = NONE_CRYPT; - } - if (req.auth_alg & AUTH_ALG_SHARED_KEY) { - ar->arDot11AuthMode |= SHARED_AUTH; - ar->arPairwiseCrypto = WEP_CRYPT; - ar->arGroupCrypto = WEP_CRYPT; - ar->arAuthMode = NONE_AUTH; - } - if (req.auth_alg == AUTH_ALG_LEAP) { - ar->arDot11AuthMode = LEAP_AUTH; - } - } - break; - } - - case AR6000_XIOCTL_SET_VOICE_PKT_SIZE: - ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata); - break; - - case AR6000_XIOCTL_SET_MAX_SP: - ret = ar6000_xioctl_set_max_sp_len(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_GET_ROAM_TBL: - ret = ar6000_ioctl_get_roam_tbl(dev, rq); - break; - case AR6000_XIOCTL_WMI_SET_ROAM_CTRL: - ret = ar6000_ioctl_set_roam_ctrl(dev, userdata); - break; - case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS: - ret = ar6000_ioctl_set_powersave_timers(dev, userdata); - break; - case AR6000_XIOCTRL_WMI_GET_POWER_MODE: - ret = ar6000_ioctl_get_power_mode(dev, rq); - break; - case AR6000_XIOCTRL_WMI_SET_WLAN_STATE: - { - AR6000_WLAN_STATE state; - if (get_user(state, (unsigned int *)userdata)) - ret = -EFAULT; - else if (ar6000_set_wlan_state(ar, state) != 0) - ret = -EIO; - break; - } - case AR6000_XIOCTL_WMI_GET_ROAM_DATA: - ret = ar6000_ioctl_get_roam_data(dev, rq); - break; - - case AR6000_XIOCTL_WMI_SET_BT_STATUS: - ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BT_PARAMS: - ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT: - ret = ar6000_xioctl_set_btcoex_fe_ant_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV: - ret = ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG: - ret = ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG: - ret = ar6000_xioctl_set_btcoex_sco_config_cmd( dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG: - ret = ar6000_xioctl_set_btcoex_a2dp_config_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG: - ret = ar6000_xioctl_set_btcoex_aclcoex_config_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG: - ret = ar60000_xioctl_set_btcoex_debug_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS: - ret = ar6000_xioctl_set_btcoex_bt_operating_status_cmd(dev, userdata); - break; - - case AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG: - ret = ar6000_xioctl_get_btcoex_config_cmd(dev, userdata, rq); - break; - - case AR6000_XIOCTL_WMI_GET_BTCOEX_STATS: - ret = ar6000_xioctl_get_btcoex_stats_cmd(dev, userdata, rq); - break; - - case AR6000_XIOCTL_WMI_STARTSCAN: - { - WMI_START_SCAN_CMD setStartScanCmd, *cmdp; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setStartScanCmd, userdata, - sizeof(setStartScanCmd))) - { - ret = -EFAULT; - } else { - if (setStartScanCmd.numChannels > 1) { - cmdp = A_MALLOC(130); - if (copy_from_user(cmdp, userdata, - sizeof (*cmdp) + - ((setStartScanCmd.numChannels - 1) * - sizeof(u16)))) - { - kfree(cmdp); - ret = -EFAULT; - goto ioctl_done; - } - } else { - cmdp = &setStartScanCmd; - } - - if (wmi_startscan_cmd(ar->arWmi, cmdp->scanType, - cmdp->forceFgScan, - cmdp->isLegacy, - cmdp->homeDwellTime, - cmdp->forceScanInterval, - cmdp->numChannels, - cmdp->channelList) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_SETFIXRATES: - { - WMI_FIX_RATES_CMD setFixRatesCmd; - int returnStatus; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setFixRatesCmd, userdata, - sizeof(setFixRatesCmd))) - { - ret = -EFAULT; - } else { - returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask); - if (returnStatus == A_EINVAL) { - ret = -EINVAL; - } else if(returnStatus != 0) { - ret = -EIO; - } else { - ar->ap_profile_flag = 1; /* There is a change in profile */ - } - } - break; - } - - case AR6000_XIOCTL_WMI_GETFIXRATES: - { - WMI_FIX_RATES_CMD getFixRatesCmd; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int ret = 0; - - if (ar->bIsDestroyProgress) { - ret = -EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - /* Used copy_from_user/copy_to_user to access user space data */ - if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd))) { - ret = -EFAULT; - } else { - ar->arRateMask = 0xFFFFFFFF; - - if (wmi_get_ratemask_cmd(ar->arWmi) != 0) { - up(&ar->arSem); - ret = -EIO; - goto ioctl_done; - } - - wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFFFFFFFF, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - - if (!ret) { - getFixRatesCmd.fixRateMask = ar->arRateMask; - } - - if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd))) { - ret = -EFAULT; - } - - up(&ar->arSem); - } - break; - } - case AR6000_XIOCTL_WMI_SET_AUTHMODE: - { - WMI_SET_AUTH_MODE_CMD setAuthMode; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setAuthMode, userdata, - sizeof(setAuthMode))) - { - ret = -EFAULT; - } else { - if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_SET_REASSOCMODE: - { - WMI_SET_REASSOC_MODE_CMD setReassocMode; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setReassocMode, userdata, - sizeof(setReassocMode))) - { - ret = -EFAULT; - } else { - if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_DIAG_READ: - { - u32 addr, data; - if (get_user(addr, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - addr = TARG_VTOP(ar->arTargetType, addr); - if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != 0) { - ret = -EIO; - } - if (put_user(data, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - break; - } - case AR6000_XIOCTL_DIAG_WRITE: - { - u32 addr, data; - if (get_user(addr, (unsigned int *)userdata) || - get_user(data, (unsigned int *)userdata + 1)) { - ret = -EFAULT; - break; - } - addr = TARG_VTOP(ar->arTargetType, addr); - if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != 0) { - ret = -EIO; - } - break; - } - case AR6000_XIOCTL_WMI_SET_KEEPALIVE: - { - WMI_SET_KEEPALIVE_CMD setKeepAlive; - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } else if (copy_from_user(&setKeepAlive, userdata, - sizeof(setKeepAlive))){ - ret = -EFAULT; - } else { - if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != 0) { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_SET_PARAMS: - { - WMI_SET_PARAMS_CMD cmd; - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } else if (copy_from_user(&cmd, userdata, - sizeof(cmd))){ - ret = -EFAULT; - } else if (copy_from_user(&cmd, userdata, - sizeof(cmd) + cmd.length)) - { - ret = -EFAULT; - } else { - if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != 0) { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_SET_MCAST_FILTER: - { - WMI_SET_MCAST_FILTER_CMD cmd; - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } else if (copy_from_user(&cmd, userdata, - sizeof(cmd))){ - ret = -EFAULT; - } else { - if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0], - cmd.multicast_mac[1], - cmd.multicast_mac[2], - cmd.multicast_mac[3]) != 0) { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER: - { - WMI_SET_MCAST_FILTER_CMD cmd; - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } else if (copy_from_user(&cmd, userdata, - sizeof(cmd))){ - ret = -EFAULT; - } else { - if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0], - cmd.multicast_mac[1], - cmd.multicast_mac[2], - cmd.multicast_mac[3]) != 0) { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_MCAST_FILTER: - { - WMI_MCAST_FILTER_CMD cmd; - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } else if (copy_from_user(&cmd, userdata, - sizeof(cmd))){ - ret = -EFAULT; - } else { - if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable) != 0) { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_GET_KEEPALIVE: - { - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_GET_KEEPALIVE_CMD getKeepAlive; - int ret = 0; - if (ar->bIsDestroyProgress) { - ret =-EBUSY; - goto ioctl_done; - } - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (down_interruptible(&ar->arSem)) { - ret = -ERESTARTSYS; - goto ioctl_done; - } - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - ret = -EBUSY; - goto ioctl_done; - } - if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) { - ret = -EFAULT; - } else { - getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi); - ar->arKeepaliveConfigured = 0xFF; - if (wmi_get_keepalive_configured(ar->arWmi) != 0){ - up(&ar->arSem); - ret = -EIO; - goto ioctl_done; - } - wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ); - if (signal_pending(current)) { - ret = -EINTR; - } - - if (!ret) { - getKeepAlive.configured = ar->arKeepaliveConfigured; - } - if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) { - ret = -EFAULT; - } - up(&ar->arSem); - } - break; - } - case AR6000_XIOCTL_WMI_SET_APPIE: - { - WMI_SET_APPIE_CMD appIEcmd; - u8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN]; - u32 fType,ieLen; - - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } - if (get_user(fType, (u32 *)userdata)) { - ret = -EFAULT; - break; - } - appIEcmd.mgmtFrmType = fType; - if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) { - ret = -EIO; - } else { - if (get_user(ieLen, (u32 *)(userdata + 4))) { - ret = -EFAULT; - break; - } - appIEcmd.ieLen = ieLen; - A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEcmd.ieLen); - if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) { - ret = -EIO; - break; - } - if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) { - ret = -EFAULT; - } else { - if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType, - appIEcmd.ieLen, appIeInfo) != 0) - { - ret = -EIO; - } - } - } - break; - } - case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER: - { - WMI_BSS_FILTER_CMD cmd; - u32 filterType; - - if (copy_from_user(&filterType, userdata, sizeof(u32))) - { - ret = -EFAULT; - goto ioctl_done; - } - if (filterType & (IEEE80211_FILTER_TYPE_BEACON | - IEEE80211_FILTER_TYPE_PROBE_RESP)) - { - cmd.bssFilter = ALL_BSS_FILTER; - } else { - cmd.bssFilter = NONE_BSS_FILTER; - } - if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != 0) { - ret = -EIO; - } else { - ar->arUserBssFilter = cmd.bssFilter; - } - - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arMgmtFilter = filterType; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - break; - } - case AR6000_XIOCTL_WMI_SET_WSC_STATUS: - { - u32 wsc_status; - - if (ar->arWmiReady == false) { - ret = -EIO; - goto ioctl_done; - } else if (copy_from_user(&wsc_status, userdata, sizeof(u32))) - { - ret = -EFAULT; - goto ioctl_done; - } - if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != 0) { - ret = -EIO; - } - break; - } - case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL: - { - u32 ROM_addr; - u32 RAM_addr; - u32 nbytes; - u32 do_activate; - u32 rompatch_id; - - if (get_user(ROM_addr, (u32 *)userdata) || - get_user(RAM_addr, (u32 *)userdata + 1) || - get_user(nbytes, (u32 *)userdata + 2) || - get_user(do_activate, (u32 *)userdata + 3)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x length: %d\n", - ROM_addr, RAM_addr, nbytes)); - ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr, - nbytes, do_activate, &rompatch_id); - if (ret == 0) { - /* return value */ - if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) { - ret = -EFAULT; - break; - } - } - break; - } - - case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL: - { - u32 rompatch_id; - - if (get_user(rompatch_id, (u32 *)userdata)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompatch_id)); - ret = BMIrompatchUninstall(hifDevice, rompatch_id); - break; - } - - case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE: - case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE: - { - u32 rompatch_count; - - if (get_user(rompatch_count, (u32 *)userdata)) { - ret = -EFAULT; - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count)); - length = sizeof(u32) * rompatch_count; - if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { - A_MEMZERO(buffer, length); - if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length)) - { - ret = -EFAULT; - } else { - if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) { - ret = BMIrompatchActivate(hifDevice, rompatch_count, (u32 *)buffer); - } else { - ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (u32 *)buffer); - } - } - kfree(buffer); - } else { - ret = -ENOMEM; - } - - break; - } - case AR6000_XIOCTL_SET_IP: - { - WMI_SET_IP_CMD setIP; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setIP, userdata, - sizeof(setIP))) - { - ret = -EFAULT; - } else { - if (wmi_set_ip_cmd(ar->arWmi, - &setIP) != 0) - { - ret = -EIO; - } - } - break; - } - - case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE: - { - WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setHostSleepMode, userdata, - sizeof(setHostSleepMode))) - { - ret = -EFAULT; - } else { - if (wmi_set_host_sleep_mode_cmd(ar->arWmi, - &setHostSleepMode) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_SET_WOW_MODE: - { - WMI_SET_WOW_MODE_CMD setWowMode; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&setWowMode, userdata, - sizeof(setWowMode))) - { - ret = -EFAULT; - } else { - if (wmi_set_wow_mode_cmd(ar->arWmi, - &setWowMode) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_GET_WOW_LIST: - { - WMI_GET_WOW_LIST_CMD getWowList; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&getWowList, userdata, - sizeof(getWowList))) - { - ret = -EFAULT; - } else { - if (wmi_get_wow_list_cmd(ar->arWmi, - &getWowList) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN: - { -#define WOW_PATTERN_SIZE 64 -#define WOW_MASK_SIZE 64 - - WMI_ADD_WOW_PATTERN_CMD cmd; - u8 mask_data[WOW_PATTERN_SIZE]={0}; - u8 pattern_data[WOW_PATTERN_SIZE]={0}; - - do { - if (ar->arWmiReady == false) { - ret = -EIO; - break; - } - if(copy_from_user(&cmd, userdata, - sizeof(WMI_ADD_WOW_PATTERN_CMD))) - { - ret = -EFAULT; - break; - } - if (copy_from_user(pattern_data, - userdata + 3, - cmd.filter_size)) - { - ret = -EFAULT; - break; - } - if (copy_from_user(mask_data, - (userdata + 3 + cmd.filter_size), - cmd.filter_size)) - { - ret = -EFAULT; - break; - } - if (wmi_add_wow_pattern_cmd(ar->arWmi, - &cmd, pattern_data, mask_data, cmd.filter_size) != 0) - { - ret = -EIO; - } - } while(false); -#undef WOW_PATTERN_SIZE -#undef WOW_MASK_SIZE - break; - } - case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN: - { - WMI_DEL_WOW_PATTERN_CMD delWowPattern; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&delWowPattern, userdata, - sizeof(delWowPattern))) - { - ret = -EFAULT; - } else { - if (wmi_del_wow_pattern_cmd(ar->arWmi, - &delWowPattern) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE: - if (ar->arHtcTarget != NULL) { -#ifdef ATH_DEBUG_MODULE - HTCDumpCreditStates(ar->arHtcTarget); -#endif /* ATH_DEBUG_MODULE */ -#ifdef HTC_EP_STAT_PROFILING - { - struct htc_endpoint_stats stats; - int i; - - for (i = 0; i < 5; i++) { - if (HTCGetEndpointStatistics(ar->arHtcTarget, - i, - HTC_EP_STAT_SAMPLE_AND_CLEAR, - &stats)) { - A_PRINTF(KERN_ALERT"------- Profiling Endpoint : %d \n", i); - A_PRINTF(KERN_ALERT"TxCreditLowIndications : %d \n", stats.TxCreditLowIndications); - A_PRINTF(KERN_ALERT"TxIssued : %d \n", stats.TxIssued); - A_PRINTF(KERN_ALERT"TxDropped: %d \n", stats.TxDropped); - A_PRINTF(KERN_ALERT"TxPacketsBundled : %d \n", stats.TxPacketsBundled); - A_PRINTF(KERN_ALERT"TxBundles : %d \n", stats.TxBundles); - A_PRINTF(KERN_ALERT"TxCreditRpts : %d \n", stats.TxCreditRpts); - A_PRINTF(KERN_ALERT"TxCreditsRptsFromRx : %d \n", stats.TxCreditRptsFromRx); - A_PRINTF(KERN_ALERT"TxCreditsRptsFromOther : %d \n", stats.TxCreditRptsFromOther); - A_PRINTF(KERN_ALERT"TxCreditsRptsFromEp0 : %d \n", stats.TxCreditRptsFromEp0); - A_PRINTF(KERN_ALERT"TxCreditsFromRx : %d \n", stats.TxCreditsFromRx); - A_PRINTF(KERN_ALERT"TxCreditsFromOther : %d \n", stats.TxCreditsFromOther); - A_PRINTF(KERN_ALERT"TxCreditsFromEp0 : %d \n", stats.TxCreditsFromEp0); - A_PRINTF(KERN_ALERT"TxCreditsConsummed : %d \n", stats.TxCreditsConsummed); - A_PRINTF(KERN_ALERT"TxCreditsReturned : %d \n", stats.TxCreditsReturned); - A_PRINTF(KERN_ALERT"RxReceived : %d \n", stats.RxReceived); - A_PRINTF(KERN_ALERT"RxPacketsBundled : %d \n", stats.RxPacketsBundled); - A_PRINTF(KERN_ALERT"RxLookAheads : %d \n", stats.RxLookAheads); - A_PRINTF(KERN_ALERT"RxBundleLookAheads : %d \n", stats.RxBundleLookAheads); - A_PRINTF(KERN_ALERT"RxBundleIndFromHdr : %d \n", stats.RxBundleIndFromHdr); - A_PRINTF(KERN_ALERT"RxAllocThreshHit : %d \n", stats.RxAllocThreshHit); - A_PRINTF(KERN_ALERT"RxAllocThreshBytes : %d \n", stats.RxAllocThreshBytes); - A_PRINTF(KERN_ALERT"---- \n"); - - } - } - } -#endif - } - break; - case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE: - if (ar->arHtcTarget != NULL) { - struct ar6000_traffic_activity_change data; - - if (copy_from_user(&data, userdata, sizeof(data))) - { - ret = -EFAULT; - goto ioctl_done; - } - /* note, this is used for testing (mbox ping testing), indicate activity - * change using the stream ID as the traffic class */ - ar6000_indicate_tx_activity(ar, - (u8)data.StreamID, - data.Active ? true : false); - } - break; - case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS: - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&connectCtrlFlags, userdata, - sizeof(connectCtrlFlags))) - { - ret = -EFAULT; - } else { - ar->arConnectCtrlFlags = connectCtrlFlags; - } - break; - case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS: - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&akmpParams, userdata, - sizeof(WMI_SET_AKMP_PARAMS_CMD))) - { - ret = -EFAULT; - } else { - if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != 0) { - ret = -EIO; - } - } - break; - case AR6000_XIOCTL_WMI_SET_PMKID_LIST: - if (ar->arWmiReady == false) { - ret = -EIO; - } else { - if (copy_from_user(&pmkidInfo.numPMKID, userdata, - sizeof(pmkidInfo.numPMKID))) - { - ret = -EFAULT; - break; - } - if (copy_from_user(&pmkidInfo.pmkidList, - userdata + sizeof(pmkidInfo.numPMKID), - pmkidInfo.numPMKID * sizeof(WMI_PMKID))) - { - ret = -EFAULT; - break; - } - if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != 0) { - ret = -EIO; - } - } - break; - case AR6000_XIOCTL_WMI_GET_PMKID_LIST: - if (ar->arWmiReady == false) { - ret = -EIO; - } else { - if (wmi_get_pmkid_list_cmd(ar->arWmi) != 0) { - ret = -EIO; - } - } - break; - case AR6000_XIOCTL_WMI_ABORT_SCAN: - if (ar->arWmiReady == false) { - ret = -EIO; - } - ret = wmi_abort_scan_cmd(ar->arWmi); - break; - case AR6000_XIOCTL_AP_HIDDEN_SSID: - { - u8 hidden_ssid; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) { - ret = -EFAULT; - } else { - wmi_ap_set_hidden_ssid(ar->arWmi, hidden_ssid); - ar->ap_hidden_ssid = hidden_ssid; - ar->ap_profile_flag = 1; /* There is a change in profile */ - } - break; - } - case AR6000_XIOCTL_AP_GET_STA_LIST: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } else { - u8 i; - ap_get_sta_t temp; - A_MEMZERO(&temp, sizeof(temp)); - for(i=0;ista_list[i].mac, ATH_MAC_LEN); - temp.sta[i].aid = ar->sta_list[i].aid; - temp.sta[i].keymgmt = ar->sta_list[i].keymgmt; - temp.sta[i].ucipher = ar->sta_list[i].ucipher; - temp.sta[i].auth = ar->sta_list[i].auth; - } - if(copy_to_user((ap_get_sta_t *)rq->ifr_data, &temp, - sizeof(ar->sta_list))) { - ret = -EFAULT; - } - } - break; - } - case AR6000_XIOCTL_AP_SET_NUM_STA: - { - u8 num_sta; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) { - ret = -EFAULT; - } else if(num_sta > AP_MAX_NUM_STA) { - /* value out of range */ - ret = -EINVAL; - } else { - wmi_ap_set_num_sta(ar->arWmi, num_sta); - } - break; - } - case AR6000_XIOCTL_AP_SET_ACL_POLICY: - { - u8 policy; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&policy, userdata, sizeof(policy))) { - ret = -EFAULT; - } else if(policy == ar->g_acl.policy) { - /* No change in policy */ - } else { - if(!(policy & AP_ACL_RETAIN_LIST_MASK)) { - /* clear ACL list */ - memset(&ar->g_acl,0,sizeof(WMI_AP_ACL)); - } - ar->g_acl.policy = policy; - wmi_ap_set_acl_policy(ar->arWmi, policy); - } - break; - } - case AR6000_XIOCTL_AP_SET_ACL_MAC: - { - WMI_AP_ACL_MAC_CMD acl; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&acl, userdata, sizeof(acl))) { - ret = -EFAULT; - } else { - if(acl_add_del_mac(&ar->g_acl, &acl)) { - wmi_ap_acl_mac_list(ar->arWmi, &acl); - } else { - A_PRINTF("ACL list error\n"); - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_AP_GET_ACL_LIST: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl, - sizeof(WMI_AP_ACL))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_COMMIT_CONFIG: - { - ret = ar6000_ap_mode_profile_commit(ar); - break; - } - case IEEE80211_IOCTL_GETWPAIE: - { - struct ieee80211req_wpaie wpaie; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) { - ret = -EFAULT; - } else if (ar6000_ap_mode_get_wpa_ie(ar, &wpaie)) { - ret = -EFAULT; - } else if(copy_to_user(userdata, &wpaie, sizeof(wpaie))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_CONN_INACT_TIME: - { - u32 period; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&period, userdata, sizeof(period))) { - ret = -EFAULT; - } else { - wmi_ap_conn_inact_time(ar->arWmi, period); - } - break; - } - case AR6000_XIOCTL_AP_PROT_SCAN_TIME: - { - WMI_AP_PROT_SCAN_TIME_CMD bgscan; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) { - ret = -EFAULT; - } else { - wmi_ap_bgscan_time(ar->arWmi, bgscan.period_min, bgscan.dwell_ms); - } - break; - } - case AR6000_XIOCTL_AP_SET_COUNTRY: - { - ret = ar6000_ioctl_set_country(dev, rq); - break; - } - case AR6000_XIOCTL_AP_SET_DTIM: - { - WMI_AP_SET_DTIM_CMD d; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&d, userdata, sizeof(d))) { - ret = -EFAULT; - } else { - if(d.dtim > 0 && d.dtim < 11) { - ar->ap_dtim_period = d.dtim; - wmi_ap_set_dtim(ar->arWmi, d.dtim); - ar->ap_profile_flag = 1; /* There is a change in profile */ - } else { - A_PRINTF("DTIM out of range. Valid range is [1-10]\n"); - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT: - { - WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } - if (copy_from_user(&evtCfgCmd, userdata, - sizeof(evtCfgCmd))) { - ret = -EFAULT; - break; - } - ret = wmi_set_target_event_report_cmd(ar->arWmi, &evtCfgCmd); - break; - } - case AR6000_XIOCTL_AP_INTRA_BSS_COMM: - { - u8 intra=0; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&intra, userdata, sizeof(intra))) { - ret = -EFAULT; - } else { - ar->intra_bss = (intra?1:0); - } - break; - } - case AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO: - { - struct drv_debug_module_s moduleinfo; - - if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) { - ret = -EFAULT; - break; - } - - a_dump_module_debug_info_by_name(moduleinfo.modulename); - ret = 0; - break; - } - case AR6000_XIOCTL_MODULE_DEBUG_SET_MASK: - { - struct drv_debug_module_s moduleinfo; - - if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) { - ret = -EFAULT; - break; - } - - if (a_set_module_mask(moduleinfo.modulename, moduleinfo.mask)) { - ret = -EFAULT; - } - - break; - } - case AR6000_XIOCTL_MODULE_DEBUG_GET_MASK: - { - struct drv_debug_module_s moduleinfo; - - if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) { - ret = -EFAULT; - break; - } - - if (a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask)) { - ret = -EFAULT; - break; - } - - if (copy_to_user(userdata, &moduleinfo, sizeof(moduleinfo))) { - ret = -EFAULT; - break; - } - - break; - } -#ifdef ATH_AR6K_11N_SUPPORT - case AR6000_XIOCTL_DUMP_RCV_AGGR_STATS: - { - PACKET_LOG *copy_of_pkt_log; - - aggr_dump_stats(ar->aggr_cntxt, ©_of_pkt_log); - if (copy_to_user(rq->ifr_data, copy_of_pkt_log, sizeof(PACKET_LOG))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_SETUP_AGGR: - { - WMI_ADDBA_REQ_CMD cmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - ret = -EFAULT; - } else { - wmi_setup_aggr_cmd(ar->arWmi, cmd.tid); - } - } - break; - - case AR6000_XIOCTL_DELE_AGGR: - { - WMI_DELBA_REQ_CMD cmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - ret = -EFAULT; - } else { - wmi_delete_aggr_cmd(ar->arWmi, cmd.tid, cmd.is_sender_initiator); - } - } - break; - - case AR6000_XIOCTL_ALLOW_AGGR: - { - WMI_ALLOW_AGGR_CMD cmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - ret = -EFAULT; - } else { - wmi_allow_aggr_cmd(ar->arWmi, cmd.tx_allow_aggr, cmd.rx_allow_aggr); - } - } - break; - - case AR6000_XIOCTL_SET_HT_CAP: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&htCap, userdata, - sizeof(htCap))) - { - ret = -EFAULT; - } else { - - if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_SET_HT_OP: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&htOp, userdata, - sizeof(htOp))) - { - ret = -EFAULT; - } else { - - if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != 0) - { - ret = -EIO; - } - } - break; - } -#endif - case AR6000_XIOCTL_HCI_CMD: - { - char tmp_buf[512]; - s8 i; - WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf; - u8 size; - - size = sizeof(cmd->cmd_buf_sz); - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(cmd, userdata, size)) { - ret = -EFAULT; - } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz)) { - ret = -EFAULT; - } else { - if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != 0) { - ret = -EIO; - }else if(loghci) { - A_PRINTF_LOG("HCI Command To PAL --> \n"); - for(i = 0; i < cmd->cmd_buf_sz; i++) { - A_PRINTF_LOG("0x%02x ",cmd->buf[i]); - if((i % 10) == 0) { - A_PRINTF_LOG("\n"); - } - } - A_PRINTF_LOG("\n"); - A_PRINTF_LOG("==================================\n"); - } - } - break; - } - case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE: - { - WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { - ret = -EFAULT; - } else { - if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN || - cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) { - if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != 0) { - ret = -EIO; - } - } else { - ret = -EINVAL; - } - } - break; - } - case AR6000_XIOCTL_AP_GET_STAT: - { - ret = ar6000_ioctl_get_ap_stats(dev, rq); - break; - } - case AR6000_XIOCTL_SET_TX_SELECT_RATES: - { - WMI_SET_TX_SELECT_RATES_CMD masks; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&masks, userdata, - sizeof(masks))) - { - ret = -EFAULT; - } else { - - if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != 0) - { - ret = -EIO; - } - } - break; - } - case AR6000_XIOCTL_AP_GET_HIDDEN_SSID: - { - WMI_AP_HIDDEN_SSID_CMD ssid; - ssid.hidden_ssid = ar->ap_hidden_ssid; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data, - &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_GET_COUNTRY: - { - WMI_AP_SET_COUNTRY_CMD cty; - memcpy(cty.countryCode, ar->ap_country_code, 3); - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data, - &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_GET_WMODE: - { - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((u8 *)rq->ifr_data, - &ar->ap_wmode, sizeof(u8))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_GET_DTIM: - { - WMI_AP_SET_DTIM_CMD dtim; - dtim.dtim = ar->ap_dtim_period; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data, - &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_GET_BINTVL: - { - WMI_BEACON_INT_CMD bi; - bi.beaconInterval = ar->ap_beacon_interval; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data, - &bi, sizeof(WMI_BEACON_INT_CMD))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_AP_GET_RTS: - { - WMI_SET_RTS_CMD rts; - rts.threshold = ar->arRTS; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data, - &rts, sizeof(WMI_SET_RTS_CMD))) { - ret = -EFAULT; - } - break; - } - case AR6000_XIOCTL_FETCH_TARGET_REGS: - { - u32 targregs[AR6003_FETCH_TARG_REGS_COUNT]; - - if (ar->arTargetType == TARGET_TYPE_AR6003) { - ar6k_FetchTargetRegs(hifDevice, targregs); - if (copy_to_user((u32 *)rq->ifr_data, &targregs, sizeof(targregs))) - { - ret = -EFAULT; - } - } else { - ret = -EOPNOTSUPP; - } - break; - } - case AR6000_XIOCTL_AP_SET_11BG_RATESET: - { - WMI_AP_SET_11BG_RATESET_CMD rate; - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&rate, userdata, sizeof(rate))) { - ret = -EFAULT; - } else { - wmi_ap_set_rateset(ar->arWmi, rate.rateset); - } - break; - } - case AR6000_XIOCTL_GET_WLAN_SLEEP_STATE: - { - WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent ; - - if (ar->arWlanState == WLAN_ENABLED) { - wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE; - } else { - wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP; - } - rq->ifr_ifru.ifru_ivalue = ar->arWlanState; /* return value */ - - ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)&wmiSleepEvent, - sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); - break; - } -#ifdef CONFIG_PM - case AR6000_XIOCTL_SET_BT_HW_POWER_STATE: - { - unsigned int state; - if (get_user(state, (unsigned int *)userdata)) { - ret = -EFAULT; - break; - } - if (ar6000_set_bt_hw_state(ar, state)!= 0) { - ret = -EIO; - } - } - break; - case AR6000_XIOCTL_GET_BT_HW_POWER_STATE: - rq->ifr_ifru.ifru_ivalue = !ar->arBTOff; /* return value */ - break; -#endif - - case AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM: - { - WMI_SET_TX_SGI_PARAM_CMD SGICmd; - - if (ar->arWmiReady == false) { - ret = -EIO; - } else if (copy_from_user(&SGICmd, userdata, - sizeof(SGICmd))){ - ret = -EFAULT; - } else{ - if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != 0) { - ret = -EIO; - } - - } - break; - } - - case AR6000_XIOCTL_ADD_AP_INTERFACE: -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT - { - char ap_ifname[IFNAMSIZ] = {0,}; - if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) { - ret = -EFAULT; - } else { - if (ar6000_add_ap_interface(ar, ap_ifname) != 0) { - ret = -EIO; - } - } - } -#else - ret = -EOPNOTSUPP; -#endif - break; - case AR6000_XIOCTL_REMOVE_AP_INTERFACE: -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT - if (ar6000_remove_ap_interface(ar) != 0) { - ret = -EIO; - } -#else - ret = -EOPNOTSUPP; -#endif - break; - - case AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES: - { - ret = ar6000_xioctl_set_excess_tx_retry_thres_cmd(dev, userdata); - break; - } - - default: - ret = -EOPNOTSUPP; - } - -ioctl_done: - rtnl_lock(); /* restore rtnl state */ - dev_put(dev); - - return ret; -} - -u8 mac_cmp_wild(u8 *mac, u8 *new_mac, u8 wild, u8 new_wild) -{ - u8 i; - - for(i=0;i=0;i--) - { - if(mac_cmp_wild(a->acl_mac[i], acl->mac, a->wildcard[i], - acl->wildcard)==0) - already_avail = i; - - if(!((1 << i) & a->index)) - free_slot = i; - } - - if(acl->action == ADD_MAC_ADDR) - { - /* Dont add mac if it is already available */ - if((already_avail >= 0) || (free_slot == -1)) - return 0; - - memcpy(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN); - a->index = a->index | (1 << free_slot); - acl->index = free_slot; - a->wildcard[free_slot] = acl->wildcard; - return 1; - } - else if(acl->action == DEL_MAC_ADDR) - { - if(acl->index > AP_ACL_SIZE) - return 0; - - if(!(a->index & (1 << acl->index))) - return 0; - - A_MEMZERO(a->acl_mac[acl->index],ATH_MAC_LEN); - a->index = a->index & ~(1 << acl->index); - a->wildcard[acl->index] = 0; - return 1; - } - - return 0; -} diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c deleted file mode 100644 index 5af09f1f226b..000000000000 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ /dev/null @@ -1,2690 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#include "ar6000_drv.h" - -#define IWE_STREAM_ADD_EVENT(p1, p2, p3, p4, p5) \ - iwe_stream_add_event((p1), (p2), (p3), (p4), (p5)) - -#define IWE_STREAM_ADD_POINT(p1, p2, p3, p4, p5) \ - iwe_stream_add_point((p1), (p2), (p3), (p4), (p5)) - -#define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \ - iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6)) - -static void ar6000_set_quality(struct iw_quality *iq, s8 rssi); -extern unsigned int wmitimeout; -extern A_WAITQUEUE_HEAD arEvent; - -#if WIRELESS_EXT > 14 -/* - * Encode a WPA or RSN information element as a custom - * element using the hostap format. - */ -static u_int -encode_ie(void *buf, size_t bufsize, - const u_int8_t *ie, size_t ielen, - const char *leader, size_t leader_len) -{ - u_int8_t *p; - int i; - - if (bufsize < leader_len) - return 0; - p = buf; - memcpy(p, leader, leader_len); - bufsize -= leader_len; - p += leader_len; - for (i = 0; i < ielen && bufsize > 2; i++) - { - p += sprintf((char*)p, "%02x", ie[i]); - bufsize -= 2; - } - return (i == ielen ? p - (u_int8_t *)buf : 0); -} -#endif /* WIRELESS_EXT > 14 */ - -static u8 get_bss_phy_capability(bss_t *bss) -{ - u8 capability = 0; - struct ieee80211_common_ie *cie = &bss->ni_cie; -#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484))) - if (CHAN_IS_11A(cie->ie_chan)) { - if (cie->ie_htcap) { - capability = WMI_11NA_CAPABILITY; - } else { - capability = WMI_11A_CAPABILITY; - } - } else if ((cie->ie_erp) || (cie->ie_xrates)) { - if (cie->ie_htcap) { - capability = WMI_11NG_CAPABILITY; - } else { - capability = WMI_11G_CAPABILITY; - } - } - return capability; -} - -void -ar6000_scan_node(void *arg, bss_t *ni) -{ - struct iw_event iwe; -#if WIRELESS_EXT > 14 - char buf[256]; -#endif - struct ar_giwscan_param *param; - char *current_ev; - char *end_buf; - struct ieee80211_common_ie *cie; - char *current_val; - s32 j; - u32 rate_len, data_len = 0; - - param = (struct ar_giwscan_param *)arg; - - current_ev = param->current_ev; - end_buf = param->end_buf; - - cie = &ni->ni_cie; - - if ((end_buf - current_ev) > IW_EV_ADDR_LEN) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6); - current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf, - &iwe, IW_EV_ADDR_LEN); - } - param->bytes_needed += IW_EV_ADDR_LEN; - - data_len = cie->ie_ssid[1] + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - iwe.u.data.length = cie->ie_ssid[1]; - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf, - &iwe, (char*)&cie->ie_ssid[2]); - } - param->bytes_needed += data_len; - - if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) { - if ((end_buf - current_ev) > IW_EV_UINT_LEN) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ? - IW_MODE_MASTER : IW_MODE_ADHOC; - current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf, - &iwe, IW_EV_UINT_LEN); - } - param->bytes_needed += IW_EV_UINT_LEN; - } - - if ((end_buf - current_ev) > IW_EV_FREQ_LEN) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = cie->ie_chan * 100000; - iwe.u.freq.e = 1; - current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf, - &iwe, IW_EV_FREQ_LEN); - } - param->bytes_needed += IW_EV_FREQ_LEN; - - if ((end_buf - current_ev) > IW_EV_QUAL_LEN) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - ar6000_set_quality(&iwe.u.qual, ni->ni_snr); - current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf, - &iwe, IW_EV_QUAL_LEN); - } - param->bytes_needed += IW_EV_QUAL_LEN; - - if ((end_buf - current_ev) > IW_EV_POINT_LEN) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - if (cie->ie_capInfo & IEEE80211_CAPINFO_PRIVACY) { - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - } else { - iwe.u.data.flags = IW_ENCODE_DISABLED; - } - iwe.u.data.length = 0; - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf, - &iwe, ""); - } - param->bytes_needed += IW_EV_POINT_LEN; - - /* supported bit rate */ - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = 0; - iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = 0; - current_val = current_ev + IW_EV_LCP_LEN; - param->bytes_needed += IW_EV_LCP_LEN; - - if (cie->ie_rates != NULL) { - rate_len = cie->ie_rates[1]; - data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN)); - if ((end_buf - current_ev) > data_len) - { - for (j = 0; j < rate_len; j++) { - unsigned char val; - val = cie->ie_rates[2 + j]; - iwe.u.bitrate.value = - (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000); - current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev, - current_val, end_buf, - &iwe, IW_EV_PARAM_LEN); - } - } - param->bytes_needed += data_len; - } - - if (cie->ie_xrates != NULL) { - rate_len = cie->ie_xrates[1]; - data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN)); - if ((end_buf - current_ev) > data_len) - { - for (j = 0; j < rate_len; j++) { - unsigned char val; - val = cie->ie_xrates[2 + j]; - iwe.u.bitrate.value = - (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000); - current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev, - current_val, end_buf, - &iwe, IW_EV_PARAM_LEN); - } - } - param->bytes_needed += data_len; - } - /* remove fixed header if no rates were added */ - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - -#if WIRELESS_EXT >= 18 - /* IE */ - if (cie->ie_wpa != NULL) { - data_len = cie->ie_wpa[1] + 2 + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = cie->ie_wpa[1] + 2; - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf, - &iwe, (char*)cie->ie_wpa); - } - param->bytes_needed += data_len; - } - - if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) { - data_len = cie->ie_rsn[1] + 2 + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = cie->ie_rsn[1] + 2; - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf, - &iwe, (char*)cie->ie_rsn); - } - param->bytes_needed += data_len; - } - -#endif /* WIRELESS_EXT >= 18 */ - - if ((end_buf - current_ev) > IW_EV_CHAR_LEN) - { - /* protocol */ - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = SIOCGIWNAME; - switch (get_bss_phy_capability(ni)) { - case WMI_11A_CAPABILITY: - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a"); - break; - case WMI_11G_CAPABILITY: - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); - break; - case WMI_11NA_CAPABILITY: - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11na"); - break; - case WMI_11NG_CAPABILITY: - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11ng"); - break; - default: - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); - break; - } - current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf, - &iwe, IW_EV_CHAR_LEN); - } - param->bytes_needed += IW_EV_CHAR_LEN; - -#if WIRELESS_EXT > 14 - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt); - data_len = iwe.u.data.length + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf, - &iwe, buf); - } - param->bytes_needed += data_len; - -#if WIRELESS_EXT < 18 - if (cie->ie_wpa != NULL) { - static const char wpa_leader[] = "wpa_ie="; - data_len = (sizeof(wpa_leader) - 1) + ((cie->ie_wpa[1]+2) * 2) + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa, - cie->ie_wpa[1]+2, - wpa_leader, sizeof(wpa_leader)-1); - - if (iwe.u.data.length != 0) { - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, - end_buf, &iwe, buf); - } - } - param->bytes_needed += data_len; - } - - if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) { - static const char rsn_leader[] = "rsn_ie="; - data_len = (sizeof(rsn_leader) - 1) + ((cie->ie_rsn[1]+2) * 2) + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_rsn, - cie->ie_rsn[1]+2, - rsn_leader, sizeof(rsn_leader)-1); - - if (iwe.u.data.length != 0) { - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, - end_buf, &iwe, buf); - } - } - param->bytes_needed += data_len; - } -#endif /* WIRELESS_EXT < 18 */ - - if (cie->ie_wmm != NULL) { - static const char wmm_leader[] = "wmm_ie="; - data_len = (sizeof(wmm_leader) - 1) + ((cie->ie_wmm[1]+2) * 2) + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm, - cie->ie_wmm[1]+2, - wmm_leader, sizeof(wmm_leader)-1); - if (iwe.u.data.length != 0) { - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, - end_buf, &iwe, buf); - } - } - param->bytes_needed += data_len; - } - - if (cie->ie_ath != NULL) { - static const char ath_leader[] = "ath_ie="; - data_len = (sizeof(ath_leader) - 1) + ((cie->ie_ath[1]+2) * 2) + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath, - cie->ie_ath[1]+2, - ath_leader, sizeof(ath_leader)-1); - if (iwe.u.data.length != 0) { - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, - end_buf, &iwe, buf); - } - } - param->bytes_needed += data_len; - } - -#ifdef WAPI_ENABLE - if (cie->ie_wapi != NULL) { - static const char wapi_leader[] = "wapi_ie="; - data_len = (sizeof(wapi_leader) - 1) + ((cie->ie_wapi[1] + 2) * 2) + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wapi, - cie->ie_wapi[1] + 2, - wapi_leader, sizeof(wapi_leader) - 1); - if (iwe.u.data.length != 0) { - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, - end_buf, &iwe, buf); - } - } - param->bytes_needed += data_len; - } -#endif /* WAPI_ENABLE */ - -#endif /* WIRELESS_EXT > 14 */ - -#if WIRELESS_EXT >= 18 - if (cie->ie_wsc != NULL) { - data_len = (cie->ie_wsc[1] + 2) + IW_EV_POINT_LEN; - if ((end_buf - current_ev) > data_len) - { - A_MEMZERO(&iwe, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = cie->ie_wsc[1] + 2; - current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf, - &iwe, (char*)cie->ie_wsc); - } - param->bytes_needed += data_len; - } -#endif /* WIRELESS_EXT >= 18 */ - - param->current_ev = current_ev; -} - -int -ar6000_ioctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct ar_giwscan_param param; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - - param.current_ev = extra; - param.end_buf = extra + data->length; - param.bytes_needed = 0; - param.info = info; - - /* Translate data to WE format */ - wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, ¶m); - - /* check if bytes needed is greater than bytes consumed */ - if (param.bytes_needed > (param.current_ev - extra)) - { - /* Request one byte more than needed, because when "data->length" equals bytes_needed, - it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions - checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/ - data->length = param.bytes_needed + 1; - - return -E2BIG; - } - - return 0; -} - -extern int reconnect_flag; -/* SIOCSIWESSID */ -static int -ar6000_ioctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int status; - u8 arNetworkType; - u8 prevMode = ar->arNetworkType; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - -#if defined(WIRELESS_EXT) - if (WIRELESS_EXT >= 20) { - data->length += 1; - } -#endif - - /* - * iwconfig passes a null terminated string with length including this - * so we need to account for this - */ - if (data->flags && (!data->length || (data->length == 1) || - ((data->length - 1) > sizeof(ar->arSsid)))) - { - /* - * ssid is invalid - */ - return -EINVAL; - } - - if (ar->arNextMode == AP_NETWORK) { - /* SSID change for AP network - Will take effect on commit */ - if(memcmp(ar->arSsid,ssid,32) != 0) { - ar->arSsidLen = data->length - 1; - memcpy(ar->arSsid, ssid, ar->arSsidLen); - ar->ap_profile_flag = 1; /* There is a change in profile */ - } - return 0; - } else if(ar->arNetworkType == AP_NETWORK) { - u8 ctr; - struct sk_buff *skb; - - /* We are switching from AP to STA | IBSS mode, cleanup the AP state */ - for (ctr=0; ctr < AP_MAX_NUM_STA; ctr++) { - remove_sta(ar, ar->sta_list[ctr].mac, 0); - } - A_MUTEX_LOCK(&ar->mcastpsqLock); - while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) { - skb = A_NETBUF_DEQUEUE(&ar->mcastpsq); - A_NETBUF_FREE(skb); - } - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - } - - /* Added for bug 25178, return an IOCTL error instead of target returning - Illegal parameter error when either the BSSID or channel is missing - and we cannot scan during connect. - */ - if (data->flags) { - if (ar->arSkipScan == true && - (ar->arChannelHint == 0 || - (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] && - !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5]))) - { - return -EINVAL; - } - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) { - up(&ar->arSem); - return -EBUSY; - } - - if (ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) { - /* - * sleep until the command queue drains - */ - wait_event_interruptible_timeout(arEvent, - ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ); - if (signal_pending(current)) { - return -EINTR; - } - } - - if (!data->flags) { - arNetworkType = ar->arNetworkType; -#ifdef ATH6K_CONFIG_CFG80211 - if (ar->arConnected) { -#endif /* ATH6K_CONFIG_CFG80211 */ - ar6000_init_profile_info(ar); -#ifdef ATH6K_CONFIG_CFG80211 - } -#endif /* ATH6K_CONFIG_CFG80211 */ - ar->arNetworkType = arNetworkType; - } - - /* Update the arNetworkType */ - ar->arNetworkType = ar->arNextMode; - - if ((prevMode != AP_NETWORK) && - ((ar->arSsidLen) || - ((ar->arSsidLen == 0) && (ar->arConnected || ar->arConnectPending)) || - (!data->flags))) - { - if ((!data->flags) || - (memcmp(ar->arSsid, ssid, ar->arSsidLen) != 0) || - (ar->arSsidLen != (data->length - 1))) - { - /* - * SSID set previously or essid off has been issued. - * - * Disconnect Command is issued in two cases after wmi is ready - * (1) ssid is different from the previous setting - * (2) essid off has been issued - * - */ - if (ar->arWmiReady == true) { - reconnect_flag = 0; - status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0); - ar6000_disconnect(ar); - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - if (ar->arSkipScan == false) { - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - } - if (!data->flags) { - up(&ar->arSem); - return 0; - } - } else { - up(&ar->arSem); - } - } - else - { - /* - * SSID is same, so we assume profile hasn't changed. - * If the interface is up and wmi is ready, we issue - * a reconnect cmd. Issue a reconnect only we are already - * connected. - */ - if((ar->arConnected == true) && (ar->arWmiReady == true)) - { - reconnect_flag = true; - status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid, - ar->arChannelHint); - up(&ar->arSem); - if (status) { - return -EIO; - } - return 0; - } - else{ - /* - * Dont return if connect is pending. - */ - if(!(ar->arConnectPending)) { - up(&ar->arSem); - return 0; - } - } - } - } - - ar->arSsidLen = data->length - 1; - memcpy(ar->arSsid, ssid, ar->arSsidLen); - - if (ar6000_connect_to_ap(ar)!= 0) { - up(&ar->arSem); - return -EIO; - }else{ - up(&ar->arSem); - } - return 0; -} - -/* SIOCGIWESSID */ -static int -ar6000_ioctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *essid) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (!ar->arSsidLen) { - return -EINVAL; - } - - data->flags = 1; - data->length = ar->arSsidLen; - memcpy(essid, ar->arSsid, ar->arSsidLen); - - return 0; -} - - -void ar6000_install_static_wep_keys(struct ar6_softc *ar) -{ - u8 index; - u8 keyUsage; - - for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { - if (ar->arWepKeyList[index].arKeyLen) { - keyUsage = GROUP_USAGE; - if (index == ar->arDefTxKeyIndex) { - keyUsage |= TX_USAGE; - } - wmi_addKey_cmd(ar->arWmi, - index, - WEP_CRYPT, - keyUsage, - ar->arWepKeyList[index].arKeyLen, - NULL, - ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL, - NO_SYNC_WMIFLAG); - } - } -} - -/* - * SIOCSIWRATE - */ -int -ar6000_ioctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u32 kbps; - s8 rate_idx; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (rrq->fixed) { - kbps = rrq->value / 1000; /* rrq->value is in bps */ - } else { - kbps = -1; /* -1 indicates auto rate */ - } - if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BitRate is not Valid %d\n", kbps)); - return -EINVAL; - } - ar->arBitRate = kbps; - if(ar->arWmiReady == true) - { - if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != 0) { - return -EINVAL; - } - } - return 0; -} - -/* - * SIOCGIWRATE - */ -int -ar6000_ioctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int ret = 0; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == false) { - rrq->value = 1000 * 1000; - return 0; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) { - up(&ar->arSem); - return -EBUSY; - } - - ar->arBitRate = 0xFFFF; - if (wmi_get_bitrate_cmd(ar->arWmi) != 0) { - up(&ar->arSem); - return -EIO; - } - wait_event_interruptible_timeout(arEvent, ar->arBitRate != 0xFFFF, wmitimeout * HZ); - if (signal_pending(current)) { - ret = -EINTR; - } - /* If the interface is down or wmi is not ready or the target is not - connected - return the value stored in the device structure */ - if (!ret) { - if (ar->arBitRate == -1) { - rrq->fixed = true; - rrq->value = 0; - } else { - rrq->value = ar->arBitRate * 1000; - } - } - - up(&ar->arSem); - - return ret; -} - -/* - * SIOCSIWTXPOW - */ -static int -ar6000_ioctl_siwtxpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u8 dbM; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (rrq->disabled) { - return -EOPNOTSUPP; - } - - if (rrq->fixed) { - if (rrq->flags != IW_TXPOW_DBM) { - return -EOPNOTSUPP; - } - ar->arTxPwr= dbM = rrq->value; - ar->arTxPwrSet = true; - } else { - ar->arTxPwr = dbM = 0; - ar->arTxPwrSet = false; - } - if(ar->arWmiReady == true) - { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("Set tx pwr cmd %d dbM\n", dbM)); - wmi_set_txPwr_cmd(ar->arWmi, dbM); - } - return 0; -} - -/* - * SIOCGIWTXPOW - */ -int -ar6000_ioctl_giwtxpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int ret = 0; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - return -EBUSY; - } - - if((ar->arWmiReady == true) && (ar->arConnected == true)) - { - ar->arTxPwr = 0; - - if (wmi_get_txPwr_cmd(ar->arWmi) != 0) { - up(&ar->arSem); - return -EIO; - } - - wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, wmitimeout * HZ); - - if (signal_pending(current)) { - ret = -EINTR; - } - } - /* If the interace is down or wmi is not ready or target is not connected - then return value stored in the device structure */ - - if (!ret) { - if (ar->arTxPwrSet == true) { - rrq->fixed = true; - } - rrq->value = ar->arTxPwr; - rrq->flags = IW_TXPOW_DBM; - // - // IWLIST need this flag to get TxPower - // - rrq->disabled = 0; - } - - up(&ar->arSem); - - return ret; -} - -/* - * SIOCSIWRETRY - * since iwconfig only provides us with one max retry value, we use it - * to apply to data frames of the BE traffic class. - */ -static int -ar6000_ioctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (rrq->disabled) { - return -EOPNOTSUPP; - } - - if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) { - return -EOPNOTSUPP; - } - - if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) { - return - EINVAL; - } - if(ar->arWmiReady == true) - { - if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE, - rrq->value, 0) != 0){ - return -EINVAL; - } - } - ar->arMaxRetries = rrq->value; - return 0; -} - -/* - * SIOCGIWRETRY - */ -static int -ar6000_ioctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - rrq->disabled = 0; - switch (rrq->flags & IW_RETRY_TYPE) { - case IW_RETRY_LIFETIME: - return -EOPNOTSUPP; - break; - case IW_RETRY_LIMIT: - rrq->flags = IW_RETRY_LIMIT; - switch (rrq->flags & IW_RETRY_MODIFIER) { - case IW_RETRY_MIN: - rrq->flags |= IW_RETRY_MIN; - rrq->value = WMI_MIN_RETRIES; - break; - case IW_RETRY_MAX: - rrq->flags |= IW_RETRY_MAX; - rrq->value = ar->arMaxRetries; - break; - } - break; - } - return 0; -} - -/* - * SIOCSIWENCODE - */ -static int -ar6000_ioctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *keybuf) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int index; - s32 auth = 0; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if(ar->arNextMode != AP_NETWORK) { - /* - * Static WEP Keys should be configured before setting the SSID - */ - if (ar->arSsid[0] && erq->length) { - return -EIO; - } - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - index = erq->flags & IW_ENCODE_INDEX; - - if (index && (((index - 1) < WMI_MIN_KEY_INDEX) || - ((index - 1) > WMI_MAX_KEY_INDEX))) - { - return -EIO; - } - - if (erq->flags & IW_ENCODE_DISABLED) { - /* - * Encryption disabled - */ - if (index) { - /* - * If key index was specified then clear the specified key - */ - index--; - A_MEMZERO(ar->arWepKeyList[index].arKey, - sizeof(ar->arWepKeyList[index].arKey)); - ar->arWepKeyList[index].arKeyLen = 0; - } - ar->arDot11AuthMode = OPEN_AUTH; - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arGroupCrypto = NONE_CRYPT; - ar->arAuthMode = NONE_AUTH; - } else { - /* - * Enabling WEP encryption - */ - if (index) { - index--; /* keyindex is off base 1 in iwconfig */ - } - - if (erq->flags & IW_ENCODE_OPEN) { - auth |= OPEN_AUTH; - ar->arDefTxKeyIndex = index; - } - if (erq->flags & IW_ENCODE_RESTRICTED) { - auth |= SHARED_AUTH; - } - - if (!auth) { - auth = OPEN_AUTH; - } - - if (erq->length) { - if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) { - return -EIO; - } - - A_MEMZERO(ar->arWepKeyList[index].arKey, - sizeof(ar->arWepKeyList[index].arKey)); - memcpy(ar->arWepKeyList[index].arKey, keybuf, erq->length); - ar->arWepKeyList[index].arKeyLen = erq->length; - ar->arDot11AuthMode = auth; - } else { - if (ar->arWepKeyList[index].arKeyLen == 0) { - return -EIO; - } - ar->arDefTxKeyIndex = index; - - if(ar->arSsidLen && ar->arWepKeyList[index].arKeyLen) { - wmi_addKey_cmd(ar->arWmi, - index, - WEP_CRYPT, - GROUP_USAGE | TX_USAGE, - ar->arWepKeyList[index].arKeyLen, - NULL, - ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL, - NO_SYNC_WMIFLAG); - } - } - - ar->arPairwiseCrypto = WEP_CRYPT; - ar->arGroupCrypto = WEP_CRYPT; - ar->arAuthMode = NONE_AUTH; - } - - if(ar->arNextMode != AP_NETWORK) { - /* - * profile has changed. Erase ssid to signal change - */ - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - } - ar->ap_profile_flag = 1; /* There is a change in profile */ - return 0; -} - -static int -ar6000_ioctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *key) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u8 keyIndex; - struct ar_wep_key *wk; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arPairwiseCrypto == NONE_CRYPT) { - erq->length = 0; - erq->flags = IW_ENCODE_DISABLED; - } else { - if (ar->arPairwiseCrypto == WEP_CRYPT) { - /* get the keyIndex */ - keyIndex = erq->flags & IW_ENCODE_INDEX; - if (0 == keyIndex) { - keyIndex = ar->arDefTxKeyIndex; - } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) || - (keyIndex - 1 > WMI_MAX_KEY_INDEX)) - { - keyIndex = WMI_MIN_KEY_INDEX; - } else { - keyIndex--; - } - erq->flags = keyIndex + 1; - erq->flags &= ~IW_ENCODE_DISABLED; - wk = &ar->arWepKeyList[keyIndex]; - if (erq->length > wk->arKeyLen) { - erq->length = wk->arKeyLen; - } - if (wk->arKeyLen) { - memcpy(key, wk->arKey, erq->length); - } - } else { - erq->flags &= ~IW_ENCODE_DISABLED; - if (ar->user_saved_keys.keyOk) { - erq->length = ar->user_saved_keys.ucast_ik.ik_keylen; - if (erq->length) { - memcpy(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length); - } - } else { - erq->length = 1; // not really printing any key but let iwconfig know enc is on - } - } - - if (ar->arDot11AuthMode & OPEN_AUTH) { - erq->flags |= IW_ENCODE_OPEN; - } - if (ar->arDot11AuthMode & SHARED_AUTH) { - erq->flags |= IW_ENCODE_RESTRICTED; - } - } - - return 0; -} - -#if WIRELESS_EXT >= 18 -/* - * SIOCSIWGENIE - */ -static int -ar6000_ioctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - -#ifdef WAPI_ENABLE - u8 *ie = erq->pointer; - u8 ie_type = ie[0]; - u16 ie_length = erq->length; - u8 wapi_ie[128]; -#endif - - if (ar->arWmiReady == false) { - return -EIO; - } -#ifdef WAPI_ENABLE - if (ie_type == IEEE80211_ELEMID_WAPI) { - if (ie_length > 0) { - if (copy_from_user(wapi_ie, ie, ie_length)) { - return -EIO; - } - } - wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie); - } else if (ie_length == 0) { - wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie); - } -#endif - return 0; -} - - -/* - * SIOCGIWGENIE - */ -static int -ar6000_ioctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (ar->arWmiReady == false) { - return -EIO; - } - erq->length = 0; - erq->flags = 0; - - return 0; -} - -/* - * SIOCSIWAUTH - */ -static int -ar6000_ioctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - bool profChanged; - u16 param; - s32 ret; - s32 value; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - param = data->flags & IW_AUTH_INDEX; - value = data->value; - profChanged = true; - ret = 0; - - switch (param) { - case IW_AUTH_WPA_VERSION: - if (value & IW_AUTH_WPA_VERSION_DISABLED) { - ar->arAuthMode = NONE_AUTH; - } else if (value & IW_AUTH_WPA_VERSION_WPA) { - ar->arAuthMode = WPA_AUTH; - } else if (value & IW_AUTH_WPA_VERSION_WPA2) { - ar->arAuthMode = WPA2_AUTH; - } else { - ret = -1; - profChanged = false; - } - break; - case IW_AUTH_CIPHER_PAIRWISE: - if (value & IW_AUTH_CIPHER_NONE) { - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arPairwiseCryptoLen = 0; - } else if (value & IW_AUTH_CIPHER_WEP40) { - ar->arPairwiseCrypto = WEP_CRYPT; - ar->arPairwiseCryptoLen = 5; - } else if (value & IW_AUTH_CIPHER_TKIP) { - ar->arPairwiseCrypto = TKIP_CRYPT; - ar->arPairwiseCryptoLen = 0; - } else if (value & IW_AUTH_CIPHER_CCMP) { - ar->arPairwiseCrypto = AES_CRYPT; - ar->arPairwiseCryptoLen = 0; - } else if (value & IW_AUTH_CIPHER_WEP104) { - ar->arPairwiseCrypto = WEP_CRYPT; - ar->arPairwiseCryptoLen = 13; - } else { - ret = -1; - profChanged = false; - } - break; - case IW_AUTH_CIPHER_GROUP: - if (value & IW_AUTH_CIPHER_NONE) { - ar->arGroupCrypto = NONE_CRYPT; - ar->arGroupCryptoLen = 0; - } else if (value & IW_AUTH_CIPHER_WEP40) { - ar->arGroupCrypto = WEP_CRYPT; - ar->arGroupCryptoLen = 5; - } else if (value & IW_AUTH_CIPHER_TKIP) { - ar->arGroupCrypto = TKIP_CRYPT; - ar->arGroupCryptoLen = 0; - } else if (value & IW_AUTH_CIPHER_CCMP) { - ar->arGroupCrypto = AES_CRYPT; - ar->arGroupCryptoLen = 0; - } else if (value & IW_AUTH_CIPHER_WEP104) { - ar->arGroupCrypto = WEP_CRYPT; - ar->arGroupCryptoLen = 13; - } else { - ret = -1; - profChanged = false; - } - break; - case IW_AUTH_KEY_MGMT: - if (value & IW_AUTH_KEY_MGMT_PSK) { - if (WPA_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA_PSK_AUTH; - } else if (WPA2_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA2_PSK_AUTH; - } else { - ret = -1; - } - } else if (!(value & IW_AUTH_KEY_MGMT_802_1X)) { - ar->arAuthMode = NONE_AUTH; - } - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - wmi_set_tkip_countermeasures_cmd(ar->arWmi, value); - profChanged = false; - break; - case IW_AUTH_DROP_UNENCRYPTED: - profChanged = false; - break; - case IW_AUTH_80211_AUTH_ALG: - ar->arDot11AuthMode = 0; - if (value & IW_AUTH_ALG_OPEN_SYSTEM) { - ar->arDot11AuthMode |= OPEN_AUTH; - } - if (value & IW_AUTH_ALG_SHARED_KEY) { - ar->arDot11AuthMode |= SHARED_AUTH; - } - if (value & IW_AUTH_ALG_LEAP) { - ar->arDot11AuthMode = LEAP_AUTH; - } - if(ar->arDot11AuthMode == 0) { - ret = -1; - profChanged = false; - } - break; - case IW_AUTH_WPA_ENABLED: - if (!value) { - ar->arAuthMode = NONE_AUTH; - /* when the supplicant is stopped, it calls this - * handler with value=0. The followings need to be - * reset if the STA were to connect again - * without security - */ - ar->arDot11AuthMode = OPEN_AUTH; - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arPairwiseCryptoLen = 0; - ar->arGroupCrypto = NONE_CRYPT; - ar->arGroupCryptoLen = 0; - } - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - profChanged = false; - break; - case IW_AUTH_ROAMING_CONTROL: - profChanged = false; - break; - case IW_AUTH_PRIVACY_INVOKED: - if (!value) { - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arPairwiseCryptoLen = 0; - ar->arGroupCrypto = NONE_CRYPT; - ar->arGroupCryptoLen = 0; - } - break; -#ifdef WAPI_ENABLE - case IW_AUTH_WAPI_ENABLED: - ar->arWapiEnable = value; - break; -#endif - default: - ret = -1; - profChanged = false; - break; - } - - if (profChanged == true) { - /* - * profile has changed. Erase ssid to signal change - */ - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - } - - return ret; -} - - -/* - * SIOCGIWAUTH - */ -static int -ar6000_ioctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u16 param; - s32 ret; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - param = data->flags & IW_AUTH_INDEX; - ret = 0; - data->value = 0; - - - switch (param) { - case IW_AUTH_WPA_VERSION: - if (ar->arAuthMode == NONE_AUTH) { - data->value |= IW_AUTH_WPA_VERSION_DISABLED; - } else if (ar->arAuthMode == WPA_AUTH) { - data->value |= IW_AUTH_WPA_VERSION_WPA; - } else if (ar->arAuthMode == WPA2_AUTH) { - data->value |= IW_AUTH_WPA_VERSION_WPA2; - } else { - ret = -1; - } - break; - case IW_AUTH_CIPHER_PAIRWISE: - if (ar->arPairwiseCrypto == NONE_CRYPT) { - data->value |= IW_AUTH_CIPHER_NONE; - } else if (ar->arPairwiseCrypto == WEP_CRYPT) { - if (ar->arPairwiseCryptoLen == 13) { - data->value |= IW_AUTH_CIPHER_WEP104; - } else { - data->value |= IW_AUTH_CIPHER_WEP40; - } - } else if (ar->arPairwiseCrypto == TKIP_CRYPT) { - data->value |= IW_AUTH_CIPHER_TKIP; - } else if (ar->arPairwiseCrypto == AES_CRYPT) { - data->value |= IW_AUTH_CIPHER_CCMP; - } else { - ret = -1; - } - break; - case IW_AUTH_CIPHER_GROUP: - if (ar->arGroupCrypto == NONE_CRYPT) { - data->value |= IW_AUTH_CIPHER_NONE; - } else if (ar->arGroupCrypto == WEP_CRYPT) { - if (ar->arGroupCryptoLen == 13) { - data->value |= IW_AUTH_CIPHER_WEP104; - } else { - data->value |= IW_AUTH_CIPHER_WEP40; - } - } else if (ar->arGroupCrypto == TKIP_CRYPT) { - data->value |= IW_AUTH_CIPHER_TKIP; - } else if (ar->arGroupCrypto == AES_CRYPT) { - data->value |= IW_AUTH_CIPHER_CCMP; - } else { - ret = -1; - } - break; - case IW_AUTH_KEY_MGMT: - if ((ar->arAuthMode == WPA_PSK_AUTH) || - (ar->arAuthMode == WPA2_PSK_AUTH)) { - data->value |= IW_AUTH_KEY_MGMT_PSK; - } else if ((ar->arAuthMode == WPA_AUTH) || - (ar->arAuthMode == WPA2_AUTH)) { - data->value |= IW_AUTH_KEY_MGMT_802_1X; - } - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - // TODO. Save countermeassure enable/disable - data->value = 0; - break; - case IW_AUTH_DROP_UNENCRYPTED: - break; - case IW_AUTH_80211_AUTH_ALG: - if (ar->arDot11AuthMode == OPEN_AUTH) { - data->value |= IW_AUTH_ALG_OPEN_SYSTEM; - } else if (ar->arDot11AuthMode == SHARED_AUTH) { - data->value |= IW_AUTH_ALG_SHARED_KEY; - } else if (ar->arDot11AuthMode == LEAP_AUTH) { - data->value |= IW_AUTH_ALG_LEAP; - } else { - ret = -1; - } - break; - case IW_AUTH_WPA_ENABLED: - if (ar->arAuthMode == NONE_AUTH) { - data->value = 0; - } else { - data->value = 1; - } - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; - case IW_AUTH_ROAMING_CONTROL: - break; - case IW_AUTH_PRIVACY_INVOKED: - if (ar->arPairwiseCrypto == NONE_CRYPT) { - data->value = 0; - } else { - data->value = 1; - } - break; -#ifdef WAPI_ENABLE - case IW_AUTH_WAPI_ENABLED: - data->value = ar->arWapiEnable; - break; -#endif - default: - ret = -1; - break; - } - - return 0; -} - -/* - * SIOCSIWPMKSA - */ -static int -ar6000_ioctl_siwpmksa(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - s32 ret; - int status; - struct iw_pmksa *pmksa; - - pmksa = (struct iw_pmksa *)extra; - - if (ar->arWmiReady == false) { - return -EIO; - } - - ret = 0; - status = 0; - - switch (pmksa->cmd) { - case IW_PMKSA_ADD: - status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, true); - break; - case IW_PMKSA_REMOVE: - status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, false); - break; - case IW_PMKSA_FLUSH: - if (ar->arConnected == true) { - status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0); - } - break; - default: - ret=-1; - break; - } - if (status) { - ret = -1; - } - - return ret; -} - -#ifdef WAPI_ENABLE - -#define PN_INIT 0x5c365c36 - -static int ar6000_set_wapi_key(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - KEY_USAGE keyUsage = 0; - s32 keyLen; - u8 *keyData; - s32 index; - u32 *PN; - s32 i; - int status; - u8 wapiKeyRsc[16]; - CRYPTO_TYPE keyType = WAPI_CRYPT; - const u8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - index = erq->flags & IW_ENCODE_INDEX; - if (index && (((index - 1) < WMI_MIN_KEY_INDEX) || - ((index - 1) > WMI_MAX_KEY_INDEX))) { - return -EIO; - } - - index--; - if (index < 0 || index > 4) { - return -EIO; - } - keyData = (u8 *)(ext + 1); - keyLen = erq->length - sizeof(struct iw_encode_ext); - memcpy(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc)); - - if (memcmp(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) { - keyUsage |= GROUP_USAGE; - PN = (u32 *)wapiKeyRsc; - for (i = 0; i < 4; i++) { - PN[i] = PN_INIT; - } - } else { - keyUsage |= PAIRWISE_USAGE; - } - status = wmi_addKey_cmd(ar->arWmi, - index, - keyType, - keyUsage, - keyLen, - wapiKeyRsc, - keyData, - KEY_OP_INIT_WAPIPN, - NULL, - SYNC_BEFORE_WMIFLAG); - if (0 != status) { - return -EIO; - } - return 0; -} - -#endif - -/* - * SIOCSIWENCODEEXT - */ -static int -ar6000_ioctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - s32 index; - struct iw_encode_ext *ext; - KEY_USAGE keyUsage; - s32 keyLen; - u8 *keyData; - u8 keyRsc[8]; - int status; - CRYPTO_TYPE keyType; -#ifdef USER_KEYS - struct ieee80211req_key ik; -#endif /* USER_KEYS */ - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - -#ifdef USER_KEYS - ar->user_saved_keys.keyOk = false; -#endif /* USER_KEYS */ - - index = erq->flags & IW_ENCODE_INDEX; - - if (index && (((index - 1) < WMI_MIN_KEY_INDEX) || - ((index - 1) > WMI_MAX_KEY_INDEX))) - { - return -EIO; - } - - ext = (struct iw_encode_ext *)extra; - if (erq->flags & IW_ENCODE_DISABLED) { - /* - * Encryption disabled - */ - if (index) { - /* - * If key index was specified then clear the specified key - */ - index--; - A_MEMZERO(ar->arWepKeyList[index].arKey, - sizeof(ar->arWepKeyList[index].arKey)); - ar->arWepKeyList[index].arKeyLen = 0; - } - } else { - /* - * Enabling WEP encryption - */ - if (index) { - index--; /* keyindex is off base 1 in iwconfig */ - } - - keyUsage = 0; - keyLen = erq->length - sizeof(struct iw_encode_ext); - - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - keyUsage = TX_USAGE; - ar->arDefTxKeyIndex = index; - // Just setting the key index - if (keyLen == 0) { - return 0; - } - } - - if (keyLen <= 0) { - return -EIO; - } - - /* key follows iw_encode_ext */ - keyData = (u8 *)(ext + 1); - - switch (ext->alg) { - case IW_ENCODE_ALG_WEP: - keyType = WEP_CRYPT; -#ifdef USER_KEYS - ik.ik_type = IEEE80211_CIPHER_WEP; -#endif /* USER_KEYS */ - if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen)) { - return -EIO; - } - - /* Check whether it is static wep. */ - if (!ar->arConnected) { - A_MEMZERO(ar->arWepKeyList[index].arKey, - sizeof(ar->arWepKeyList[index].arKey)); - memcpy(ar->arWepKeyList[index].arKey, keyData, keyLen); - ar->arWepKeyList[index].arKeyLen = keyLen; - - return 0; - } - break; - case IW_ENCODE_ALG_TKIP: - keyType = TKIP_CRYPT; -#ifdef USER_KEYS - ik.ik_type = IEEE80211_CIPHER_TKIP; -#endif /* USER_KEYS */ - break; - case IW_ENCODE_ALG_CCMP: - keyType = AES_CRYPT; -#ifdef USER_KEYS - ik.ik_type = IEEE80211_CIPHER_AES_CCM; -#endif /* USER_KEYS */ - break; -#ifdef WAPI_ENABLE - case IW_ENCODE_ALG_SM4: - if (ar->arWapiEnable) { - return ar6000_set_wapi_key(dev, info, erq, extra); - } else { - return -EIO; - } -#endif - case IW_ENCODE_ALG_PMK: - ar->arConnectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD; - return wmi_set_pmk_cmd(ar->arWmi, keyData); - default: - return -EIO; - } - - - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - keyUsage |= GROUP_USAGE; - } else { - keyUsage |= PAIRWISE_USAGE; - } - - if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - memcpy(keyRsc, ext->rx_seq, sizeof(keyRsc)); - } else { - A_MEMZERO(keyRsc, sizeof(keyRsc)); - } - - if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) && - (GROUP_USAGE & keyUsage)) - { - A_UNTIMEOUT(&ar->disconnect_timer); - } - - status = wmi_addKey_cmd(ar->arWmi, index, keyType, keyUsage, - keyLen, keyRsc, - keyData, KEY_OP_INIT_VAL, - (u8 *)ext->addr.sa_data, - SYNC_BOTH_WMIFLAG); - if (status) { - return -EIO; - } - -#ifdef USER_KEYS - ik.ik_keyix = index; - ik.ik_keylen = keyLen; - memcpy(ik.ik_keydata, keyData, keyLen); - memcpy(&ik.ik_keyrsc, keyRsc, sizeof(keyRsc)); - memcpy(ik.ik_macaddr, ext->addr.sa_data, ETH_ALEN); - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - memcpy(&ar->user_saved_keys.bcast_ik, &ik, - sizeof(struct ieee80211req_key)); - } else { - memcpy(&ar->user_saved_keys.ucast_ik, &ik, - sizeof(struct ieee80211req_key)); - } - ar->user_saved_keys.keyOk = true; -#endif /* USER_KEYS */ - } - - - return 0; -} - -/* - * SIOCGIWENCODEEXT - */ -static int -ar6000_ioctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arPairwiseCrypto == NONE_CRYPT) { - erq->length = 0; - erq->flags = IW_ENCODE_DISABLED; - } else { - erq->length = 0; - } - - return 0; -} -#endif // WIRELESS_EXT >= 18 - -#if WIRELESS_EXT > 20 -static int ar6000_ioctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ -#ifndef ATH6K_CONFIG_OTA_MODE - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_POWER_MODE power_mode; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (wrqu->power.disabled) - power_mode = MAX_PERF_POWER; - else - power_mode = REC_POWER; - - if (wmi_powermode_cmd(ar->arWmi, power_mode) < 0) - return -EIO; -#endif - return 0; -} - -static int ar6000_ioctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_POWER_MODE power_mode; - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - power_mode = wmi_get_power_mode_cmd(ar->arWmi); - - if (power_mode == MAX_PERF_POWER) - wrqu->power.disabled = 1; - else - wrqu->power.disabled = 0; - - return 0; -} -#endif // WIRELESS_EXT > 20 - -/* - * SIOCGIWNAME - */ -int -ar6000_ioctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *name, char *extra) -{ - u8 capability; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - capability = ar->arPhyCapability; - if(ar->arNetworkType == INFRA_NETWORK && ar->arConnected) { - bss_t *bss = wmi_find_node(ar->arWmi, ar->arBssid); - if (bss) { - capability = get_bss_phy_capability(bss); - wmi_node_return(ar->arWmi, bss); - } - } - switch (capability) { - case (WMI_11A_CAPABILITY): - strncpy(name, "AR6000 802.11a", IFNAMSIZ); - break; - case (WMI_11G_CAPABILITY): - strncpy(name, "AR6000 802.11g", IFNAMSIZ); - break; - case (WMI_11AG_CAPABILITY): - strncpy(name, "AR6000 802.11ag", IFNAMSIZ); - break; - case (WMI_11NA_CAPABILITY): - strncpy(name, "AR6000 802.11na", IFNAMSIZ); - break; - case (WMI_11NG_CAPABILITY): - strncpy(name, "AR6000 802.11ng", IFNAMSIZ); - break; - case (WMI_11NAG_CAPABILITY): - strncpy(name, "AR6000 802.11nag", IFNAMSIZ); - break; - default: - strncpy(name, "AR6000 802.11b", IFNAMSIZ); - break; - } - - return 0; -} - -/* - * SIOCSIWFREQ - */ -int -ar6000_ioctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - /* - * We support limiting the channels via wmiconfig. - * - * We use this command to configure the channel hint for the connect cmd - * so it is possible the target will end up connecting to a different - * channel. - */ - if (freq->e > 1) { - return -EINVAL; - } else if (freq->e == 1) { - ar->arChannelHint = freq->m / 100000; - } else { - if(freq->m) { - ar->arChannelHint = wlan_ieee2freq(freq->m); - } else { - /* Auto Channel Selection */ - ar->arChannelHint = 0; - } - } - - ar->ap_profile_flag = 1; /* There is a change in profile */ - - A_PRINTF("channel hint set to %d\n", ar->arChannelHint); - return 0; -} - -/* - * SIOCGIWFREQ - */ -int -ar6000_ioctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arNetworkType == AP_NETWORK) { - if(ar->arChannelHint) { - freq->m = ar->arChannelHint * 100000; - } else if(ar->arACS) { - freq->m = ar->arACS * 100000; - } else { - return -EINVAL; - } - } else { - if (ar->arConnected != true) { - return -EINVAL; - } else { - freq->m = ar->arBssChannel * 100000; - } - } - - freq->e = 1; - - return 0; -} - -/* - * SIOCSIWMODE - */ -int -ar6000_ioctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - /* - * clear SSID during mode switch in connected state - */ - if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == true) ){ - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - } - - switch (*mode) { - case IW_MODE_INFRA: - ar->arNextMode = INFRA_NETWORK; - break; - case IW_MODE_ADHOC: - ar->arNextMode = ADHOC_NETWORK; - break; - case IW_MODE_MASTER: - ar->arNextMode = AP_NETWORK; - break; - default: - return -EINVAL; - } - - /* clear all shared parameters between AP and STA|IBSS modes when we - * switch between them. Switch between STA & IBSS modes does'nt clear - * the shared profile. This is as per the original design for switching - * between STA & IBSS. - */ - if (ar->arNetworkType == AP_NETWORK || ar->arNextMode == AP_NETWORK) { - ar->arDot11AuthMode = OPEN_AUTH; - ar->arAuthMode = NONE_AUTH; - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arPairwiseCryptoLen = 0; - ar->arGroupCrypto = NONE_CRYPT; - ar->arGroupCryptoLen = 0; - ar->arChannelHint = 0; - ar->arBssChannel = 0; - A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - } - - /* SSID has to be cleared to trigger a profile change while switching - * between STA & IBSS modes having the same SSID - */ - if (ar->arNetworkType != ar->arNextMode) { - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - } - - return 0; -} - -/* - * SIOCGIWMODE - */ -int -ar6000_ioctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - switch (ar->arNetworkType) { - case INFRA_NETWORK: - *mode = IW_MODE_INFRA; - break; - case ADHOC_NETWORK: - *mode = IW_MODE_ADHOC; - break; - case AP_NETWORK: - *mode = IW_MODE_MASTER; - break; - default: - return -EIO; - } - return 0; -} - -/* - * SIOCSIWSENS - */ -int -ar6000_ioctl_siwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *sens, char *extra) -{ - return 0; -} - -/* - * SIOCGIWSENS - */ -int -ar6000_ioctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *sens, char *extra) -{ - sens->value = 0; - sens->fixed = 1; - - return 0; -} - -/* - * SIOCGIWRANGE - */ -int -ar6000_ioctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct iw_range *range = (struct iw_range *) extra; - int i, ret = 0; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - return -EBUSY; - } - - ar->arNumChannels = -1; - A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList)); - - if (wmi_get_channelList_cmd(ar->arWmi) != 0) { - up(&ar->arSem); - return -EIO; - } - - wait_event_interruptible_timeout(arEvent, ar->arNumChannels != -1, wmitimeout * HZ); - - if (signal_pending(current)) { - up(&ar->arSem); - return -EINTR; - } - - data->length = sizeof(struct iw_range); - A_MEMZERO(range, sizeof(struct iw_range)); - - range->txpower_capa = 0; - - range->min_pmp = 1 * 1024; - range->max_pmp = 65535 * 1024; - range->min_pmt = 1 * 1024; - range->max_pmt = 1000 * 1024; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = 0; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 13; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->min_retry = 0; - range->max_retry = 255; - - range->num_frequency = range->num_channels = ar->arNumChannels; - for (i = 0; i < ar->arNumChannels; i++) { - range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]); - range->freq[i].m = ar->arChannelList[i] * 100000; - range->freq[i].e = 1; - /* - * Linux supports max of 32 channels, bail out once you - * reach the max. - */ - if (i == IW_MAX_FREQUENCIES) { - break; - } - } - - /* Max quality is max field value minus noise floor */ - range->max_qual.qual = 0xff - 161; - - /* - * In order to use dBm measurements, 'level' must be lower - * than any possible measurement (see iw_print_stats() in - * wireless tools). It's unclear how this is meant to be - * done, but setting zero in these values forces dBm and - * the actual numbers are not used. - */ - range->max_qual.level = 0; - range->max_qual.noise = 0; - - range->sensitivity = 3; - - range->max_encoding_tokens = 4; - /* XXX query driver to find out supported key sizes */ - range->num_encoding_sizes = 3; - range->encoding_size[0] = 5; /* 40-bit */ - range->encoding_size[1] = 13; /* 104-bit */ - range->encoding_size[2] = 16; /* 128-bit */ - - range->num_bitrates = 0; - - /* estimated maximum TCP throughput values (bps) */ - range->throughput = 22000000; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - up(&ar->arSem); - - return ret; -} - - -/* - * SIOCSIWAP - * This ioctl is used to set the desired bssid for the connect command. - */ -int -ar6000_ioctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ap_addr->sa_family != ARPHRD_ETHER) { - return -EIO; - } - - if (memcmp(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) { - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - } else { - memcpy(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid)); - } - - return 0; -} - -/* - * SIOCGIWAP - */ -int -ar6000_ioctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arNetworkType == AP_NETWORK) { - memcpy(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN); - ap_addr->sa_family = ARPHRD_ETHER; - return 0; - } - - if (ar->arConnected != true) { - return -EINVAL; - } - - memcpy(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid)); - ap_addr->sa_family = ARPHRD_ETHER; - - return 0; -} - -#if (WIRELESS_EXT >= 18) -/* - * SIOCSIWMLME - */ -int -ar6000_ioctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->bIsDestroyProgress) { - return -EBUSY; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (down_interruptible(&ar->arSem)) { - return -ERESTARTSYS; - } - - if (data->pointer && data->length == sizeof(struct iw_mlme)) { - - u8 arNetworkType; - struct iw_mlme mlme; - - if (copy_from_user(&mlme, data->pointer, sizeof(struct iw_mlme))) - return -EIO; - - switch (mlme.cmd) { - - case IW_MLME_DEAUTH: - /* fall through */ - case IW_MLME_DISASSOC: - if ((ar->arConnected != true) || - (memcmp(ar->arBssid, mlme.addr.sa_data, 6) != 0)) { - - up(&ar->arSem); - return -EINVAL; - } - wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0); - arNetworkType = ar->arNetworkType; - ar6000_init_profile_info(ar); - ar->arNetworkType = arNetworkType; - reconnect_flag = 0; - ar6000_disconnect(ar); - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - if (ar->arSkipScan == false) { - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - } - break; - - case IW_MLME_AUTH: - /* fall through */ - case IW_MLME_ASSOC: - /* fall through */ - default: - up(&ar->arSem); - return -EOPNOTSUPP; - } - } - - up(&ar->arSem); - return 0; -} -#endif /* WIRELESS_EXT >= 18 */ - -/* - * SIOCGIWAPLIST - */ -int -ar6000_ioctl_iwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - return -EIO; /* for now */ -} - -/* - * SIOCSIWSCAN - */ -int -ar6000_ioctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ -#define ACT_DWELLTIME_DEFAULT 105 -#define HOME_TXDRAIN_TIME 100 -#define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - int ret = 0; - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - /* If scan is issued in the middle of ongoing scan or connect, - dont issue another one */ - if ( ar->scan_triggered > 0 ) { - ++ar->scan_triggered; - if (ar->scan_triggered < 5) { - return 0; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("Scan request is triggered over 5 times. Not scan complete event\n")); - } - } - - if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) { - return -EIO; - } - } - - if (ar->arConnected) { - if (wmi_get_stats_cmd(ar->arWmi) != 0) { - return -EIO; - } - } - - if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, false, false, \ - 0, 0, 0, NULL) != 0) { - ret = -EIO; - } - - if (ret == 0) { - ar->scan_triggered = 1; - } - - return ret; -#undef ACT_DWELLTIME_DEFAULT -#undef HOME_TXDRAIN_TIME -#undef SCAN_INT -} - - -/* - * Units are in db above the noise floor. That means the - * rssi values reported in the tx/rx descriptors in the - * driver are the SNR expressed in db. - * - * If you assume that the noise floor is -95, which is an - * excellent assumption 99.5 % of the time, then you can - * derive the absolute signal level (i.e. -95 + rssi). - * There are some other slight factors to take into account - * depending on whether the rssi measurement is from 11b, - * 11g, or 11a. These differences are at most 2db and - * can be documented. - * - * NB: various calculations are based on the orinoco/wavelan - * drivers for compatibility - */ -static void -ar6000_set_quality(struct iw_quality *iq, s8 rssi) -{ - if (rssi < 0) { - iq->qual = 0; - } else { - iq->qual = rssi; - } - - /* NB: max is 94 because noise is hardcoded to 161 */ - if (iq->qual > 94) - iq->qual = 94; - - iq->noise = 161; /* -95dBm */ - iq->level = iq->noise + iq->qual; - iq->updated = 7; -} - - -int -ar6000_ioctl_siwcommit(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { - A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); - return -EOPNOTSUPP; - } - - if (ar->arWmiReady == false) { - return -EIO; - } - - if (ar->arWlanState == WLAN_DISABLED) { - return -EIO; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AP: SSID %s freq %d authmode %d dot11 auth %d"\ - " PW crypto %d GRP crypto %d\n", - ar->arSsid, ar->arChannelHint, - ar->arAuthMode, ar->arDot11AuthMode, - ar->arPairwiseCrypto, ar->arGroupCrypto)); - - ar6000_ap_mode_profile_commit(ar); - - /* if there is a profile switch from STA|IBSS mode to AP mode, - * update the host driver association state for the STA|IBSS mode. - */ - if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) { - /* Stop getting pkts from upper stack */ - netif_stop_queue(ar->arNetDev); - A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); - ar->arBssChannel = 0; - ar->arBeaconInterval = 0; - - /* Flush the Tx queues */ - ar6000_TxDataCleanup(ar); - - /* Start getting pkts from upper stack */ - netif_wake_queue(ar->arNetDev); - } - - return 0; -} - -#define W_PROTO(_x) wait_ ## _x -#define WAIT_HANDLER_IMPL(_x, type) \ -int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\ - int ret; \ - dev_hold(dev); \ - rtnl_unlock(); \ - ret = _x(dev, info, wrqu, extra); \ - rtnl_lock(); \ - dev_put(dev); \ - return ret;\ -} - -WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid, struct iw_point *) -WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate, struct iw_param *) -WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow, struct iw_param *) -WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange, struct iw_point*) - -/* Structures to export the Wireless Handlers */ -static const iw_handler ath_handlers[] = { - (iw_handler) ar6000_ioctl_siwcommit, /* SIOCSIWCOMMIT */ - (iw_handler) ar6000_ioctl_giwname, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) ar6000_ioctl_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) ar6000_ioctl_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) ar6000_ioctl_siwmode, /* SIOCSIWMODE */ - (iw_handler) ar6000_ioctl_giwmode, /* SIOCGIWMODE */ - (iw_handler) ar6000_ioctl_siwsens, /* SIOCSIWSENS */ - (iw_handler) ar6000_ioctl_giwsens, /* SIOCGIWSENS */ - (iw_handler) NULL /* not _used */, /* SIOCSIWRANGE */ - (iw_handler) W_PROTO(ar6000_ioctl_giwrange),/* SIOCGIWRANGE */ - (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ - (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ - (iw_handler) NULL, /* SIOCSIWTHRSPY */ - (iw_handler) NULL, /* SIOCGIWTHRSPY */ - (iw_handler) ar6000_ioctl_siwap, /* SIOCSIWAP */ - (iw_handler) ar6000_ioctl_giwap, /* SIOCGIWAP */ -#if (WIRELESS_EXT >= 18) - (iw_handler) ar6000_ioctl_siwmlme, /* SIOCSIWMLME */ -#else - (iw_handler) NULL, /* -- hole -- */ -#endif /* WIRELESS_EXT >= 18 */ - (iw_handler) ar6000_ioctl_iwaplist, /* SIOCGIWAPLIST */ - (iw_handler) ar6000_ioctl_siwscan, /* SIOCSIWSCAN */ - (iw_handler) ar6000_ioctl_giwscan, /* SIOCGIWSCAN */ - (iw_handler) W_PROTO(ar6000_ioctl_siwessid),/* SIOCSIWESSID */ - (iw_handler) ar6000_ioctl_giwessid, /* SIOCGIWESSID */ - (iw_handler) NULL, /* SIOCSIWNICKN */ - (iw_handler) NULL, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) ar6000_ioctl_siwrate, /* SIOCSIWRATE */ - (iw_handler) W_PROTO(ar6000_ioctl_giwrate), /* SIOCGIWRATE */ - (iw_handler) NULL, /* SIOCSIWRTS */ - (iw_handler) NULL, /* SIOCGIWRTS */ - (iw_handler) NULL, /* SIOCSIWFRAG */ - (iw_handler) NULL, /* SIOCGIWFRAG */ - (iw_handler) ar6000_ioctl_siwtxpow, /* SIOCSIWTXPOW */ - (iw_handler) W_PROTO(ar6000_ioctl_giwtxpow),/* SIOCGIWTXPOW */ - (iw_handler) ar6000_ioctl_siwretry, /* SIOCSIWRETRY */ - (iw_handler) ar6000_ioctl_giwretry, /* SIOCGIWRETRY */ - (iw_handler) ar6000_ioctl_siwencode, /* SIOCSIWENCODE */ - (iw_handler) ar6000_ioctl_giwencode, /* SIOCGIWENCODE */ -#if WIRELESS_EXT > 20 - (iw_handler) ar6000_ioctl_siwpower, /* SIOCSIWPOWER */ - (iw_handler) ar6000_ioctl_giwpower, /* SIOCGIWPOWER */ -#endif // WIRELESS_EXT > 20 -#if WIRELESS_EXT >= 18 - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) ar6000_ioctl_siwgenie, /* SIOCSIWGENIE */ - (iw_handler) ar6000_ioctl_giwgenie, /* SIOCGIWGENIE */ - (iw_handler) ar6000_ioctl_siwauth, /* SIOCSIWAUTH */ - (iw_handler) ar6000_ioctl_giwauth, /* SIOCGIWAUTH */ - (iw_handler) ar6000_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ - (iw_handler) ar6000_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */ - (iw_handler) ar6000_ioctl_siwpmksa, /* SIOCSIWPMKSA */ -#endif // WIRELESS_EXT >= 18 -}; - -struct iw_handler_def ath_iw_handler_def = { - .standard = (iw_handler *)ath_handlers, - .num_standard = ARRAY_SIZE(ath_handlers), - .private = NULL, - .num_private = 0, -}; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index eccccee94fd0..8b9ad76e7029 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -132,12 +132,6 @@ wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); static int wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); -#ifdef CONFIG_HOST_GPIO_SUPPORT -static int wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len); -#endif /* CONFIG_HOST_GPIO_SUPPORT */ - #ifdef CONFIG_HOST_TCMD_SUPPORT static int wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len); @@ -865,17 +859,6 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) status = wmi_dset_data_req_rx(wmip, datap, len); break; #endif /* CONFIG_HOST_DSET_SUPPORT */ -#ifdef CONFIG_HOST_GPIO_SUPPORT - case (WMIX_GPIO_INTR_EVENTID): - wmi_gpio_intr_rx(wmip, datap, len); - break; - case (WMIX_GPIO_DATA_EVENTID): - wmi_gpio_data_rx(wmip, datap, len); - break; - case (WMIX_GPIO_ACK_EVENTID): - wmi_gpio_ack_rx(wmip, datap, len); - break; -#endif /* CONFIG_HOST_GPIO_SUPPORT */ case (WMIX_HB_CHALLENGE_RESP_EVENTID): wmi_hbChallengeResp_rx(wmip, datap, len); break; @@ -1208,7 +1191,7 @@ wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid) /* Send a "simple" extended wmi command -- one with no arguments. Enabling this command only if GPIO or profiling support is enabled. This is to suppress warnings on some platforms */ -#if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT) +#if defined(CONFIG_TARGET_PROFILE_SUPPORT) static int wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid) { @@ -2298,46 +2281,6 @@ wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len) return 0; } -#ifdef CONFIG_HOST_GPIO_SUPPORT -static int -wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap; - - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG, - gpio_intr->intr_mask, gpio_intr->input_values)); - - A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values); - - return 0; -} - -static int -wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap; - - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, - gpio_data->reg_id, gpio_data->value)); - - A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value); - - return 0; -} - -static int -wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_GPIO_ACK_RX(); - - return 0; -} -#endif /* CONFIG_HOST_GPIO_SUPPORT */ - /* * Called to send a wmi command. Command specific data is already built * on osbuf and current osbuf->data points to it. @@ -4282,132 +4225,6 @@ wmi_set_powersave_timers_cmd(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -#ifdef CONFIG_HOST_GPIO_SUPPORT -/* Send a command to Target to change GPIO output pins. */ -int -wmi_gpio_output_set(struct wmi_t *wmip, - u32 set_mask, - u32 clear_mask, - u32 enable_mask, - u32 disable_mask) -{ - void *osbuf; - WMIX_GPIO_OUTPUT_SET_CMD *output_set; - int size; - - size = sizeof(*output_set); - - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG, - set_mask, clear_mask, enable_mask, disable_mask)); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, size); - output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf)); - - output_set->set_mask = set_mask; - output_set->clear_mask = clear_mask; - output_set->enable_mask = enable_mask; - output_set->disable_mask = disable_mask; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID, - NO_SYNC_WMIFLAG)); -} - -/* Send a command to the Target requesting state of the GPIO input pins */ -int -wmi_gpio_input_get(struct wmi_t *wmip) -{ - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID); -} - -/* Send a command to the Target that changes the value of a GPIO register. */ -int -wmi_gpio_register_set(struct wmi_t *wmip, - u32 gpioreg_id, - u32 value) -{ - void *osbuf; - WMIX_GPIO_REGISTER_SET_CMD *register_set; - int size; - - size = sizeof(*register_set); - - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value)); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, size); - register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf)); - - register_set->gpioreg_id = gpioreg_id; - register_set->value = value; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID, - NO_SYNC_WMIFLAG)); -} - -/* Send a command to the Target to fetch the value of a GPIO register. */ -int -wmi_gpio_register_get(struct wmi_t *wmip, - u32 gpioreg_id) -{ - void *osbuf; - WMIX_GPIO_REGISTER_GET_CMD *register_get; - int size; - - size = sizeof(*register_get); - - A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id)); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, size); - register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf)); - - register_get->gpioreg_id = gpioreg_id; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID, - NO_SYNC_WMIFLAG)); -} - -/* Send a command to the Target acknowledging some GPIO interrupts. */ -int -wmi_gpio_intr_ack(struct wmi_t *wmip, - u32 ack_mask) -{ - void *osbuf; - WMIX_GPIO_INTR_ACK_CMD *intr_ack; - int size; - - size = sizeof(*intr_ack); - - A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask)); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, size); - intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf)); - - intr_ack->ack_mask = ack_mask; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID, - NO_SYNC_WMIFLAG)); -} -#endif /* CONFIG_HOST_GPIO_SUPPORT */ - int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin, u8 eCWmax, u8 aifsn) @@ -4683,8 +4500,6 @@ wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len) A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len); - return 0; } -- GitLab From 1d7abecc84b29f4e0ce0290e0326500eee0c0a40 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:07 -0700 Subject: [PATCH 0430/5560] ath6kl: remove define ATH_AR6K_11N_SUPPORT This is always enabled. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - drivers/staging/ath6kl/os/linux/ar6000_drv.c | 12 ------------ drivers/staging/ath6kl/reorder/rcv_aggr.c | 4 ---- drivers/staging/ath6kl/wmi/wmi.c | 10 ---------- 4 files changed, 27 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index be49800431d4..96e4ed9d04c7 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -116,7 +116,6 @@ ccflags-y += -DSEND_EVENT_TO_APP ccflags-y += -DUSER_KEYS ccflags-y += -DNO_SYNC_FLUSH ccflags-y += -DHTC_EP_STAT_PROFILING -ccflags-y += -DATH_AR6K_11N_SUPPORT ccflags-y += -DWAPI_ENABLE ccflags-y += -DCHECKSUM_OFFLOAD ccflags-y += -DWLAN_HEADERS diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 3b3eec140fa1..d1c7b5fd7fc7 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -306,9 +306,7 @@ static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets) static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket); -#ifdef ATH_AR6K_11N_SUPPORT static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num); -#endif static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf); //static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf); @@ -738,7 +736,6 @@ aptcTimerHandler(unsigned long arg) } #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ -#ifdef ATH_AR6K_11N_SUPPORT static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num) { @@ -757,7 +754,6 @@ ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num) A_PRINTF("%s(), allocation of netbuf failed", __func__); } } -#endif static struct bin_attribute bmi_attr = { .attr = {.name = "bmi", .mode = 0600}, @@ -1758,7 +1754,6 @@ ar6000_avail_ev(void *context, void *hif_handle) } #endif -#ifdef ATH_AR6K_11N_SUPPORT ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs); if (!ar->aggr_cntxt) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__)); @@ -1767,7 +1762,6 @@ ar6000_avail_ev(void *context, void *hif_handle) } aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack); -#endif HIFClaimDevice(ar->arHifDevice, ar); @@ -2057,9 +2051,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) HIFReleaseDevice(ar->arHifDevice); HIFShutDownDevice(ar->arHifDevice); } -#ifdef ATH_AR6K_11N_SUPPORT aggr_module_destroy(ar->aggr_cntxt); -#endif /* Done with cookies */ ar6000_cookie_cleanup(ar); @@ -3850,9 +3842,7 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) } } } -#ifdef ATH_AR6K_11N_SUPPORT aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb); -#endif ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb); } } @@ -4621,7 +4611,6 @@ ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode) ar->arRegCode = regCode; } -#ifdef ATH_AR6K_11N_SUPPORT void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt) { @@ -4643,7 +4632,6 @@ ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt) { aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid); } -#endif void register_pal_cb(ar6k_pal_config_t *palConfig_p) { diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index eec1dc6a07c0..788d0884f064 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -21,8 +21,6 @@ * */ -#ifdef ATH_AR6K_11N_SUPPORT - #include #include #include @@ -662,5 +660,3 @@ aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf) A_PRINTF("================================================\n\n"); } - -#endif /* ATH_AR6K_11N_SUPPORT */ diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 8b9ad76e7029..153ca1f5bc92 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -181,13 +181,11 @@ static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap, static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap, int len); -#ifdef ATH_AR6K_11N_SUPPORT static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int); static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int); static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int); static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len); static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len); -#endif static int wmi_hci_event_rx(struct wmi_t *, u8 *, int); #ifdef WAPI_ENABLE @@ -1120,7 +1118,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG)); status = wmi_acm_reject_event_rx(wmip, datap, len); break; -#ifdef ATH_AR6K_11N_SUPPORT case (WMI_ADDBA_REQ_EVENTID): status = wmi_addba_req_event_rx(wmip, datap, len); break; @@ -1138,7 +1135,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG)); status = wmi_btcoex_stats_event_rx(wmip, datap, len); break; -#endif case (WMI_TX_COMPLETE_EVENTID): { int index; @@ -5810,7 +5806,6 @@ int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss) return 0; } -#ifdef ATH_AR6K_11N_SUPPORT static int wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) { @@ -5863,7 +5858,6 @@ wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len) return 0; } -#endif static int wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len) @@ -6187,7 +6181,6 @@ wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset) return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG)); } -#ifdef ATH_AR6K_11N_SUPPORT int wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) { @@ -6233,7 +6226,6 @@ wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width) return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID, NO_SYNC_WMIFLAG)); } -#endif int wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray) @@ -6275,7 +6267,6 @@ wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz) return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG)); } -#ifdef ATH_AR6K_11N_SUPPORT int wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask) { @@ -6335,7 +6326,6 @@ wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink) /* Delete the local aggr state, on host */ return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG)); } -#endif int wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, -- GitLab From eba67f4366521b6c761f50af859917b89eba7dbf Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:08 -0700 Subject: [PATCH 0431/5560] ath6kl: remove dependency on LINUX and KERNEL_2_6 macros Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 3 - drivers/staging/ath6kl/include/a_config.h | 22 -------- drivers/staging/ath6kl/include/a_debug.h | 28 ---------- drivers/staging/ath6kl/include/a_drv.h | 22 -------- drivers/staging/ath6kl/include/a_osapi.h | 29 ---------- drivers/staging/ath6kl/include/a_types.h | 26 --------- drivers/staging/ath6kl/include/ar6000_api.h | 22 -------- drivers/staging/ath6kl/include/athendpack.h | 52 ------------------ drivers/staging/ath6kl/include/athstartpack.h | 55 ------------------- .../staging/ath6kl/include/common/bmi_msg.h | 8 --- .../staging/ath6kl/include/common/dbglog.h | 8 --- .../ath6kl/include/common/dset_internal.h | 8 --- .../staging/ath6kl/include/common/dsetid.h | 8 --- .../ath6kl/include/common/epping_test.h | 9 --- .../staging/ath6kl/include/common/gmboxif.h | 8 --- drivers/staging/ath6kl/include/common/htc.h | 9 --- .../staging/ath6kl/include/common/regdump.h | 8 --- .../staging/ath6kl/include/common/targaddrs.h | 8 --- drivers/staging/ath6kl/include/common/wmi.h | 8 --- drivers/staging/ath6kl/include/common/wmix.h | 7 --- .../staging/ath6kl/wlan/include/ieee80211.h | 4 -- drivers/staging/ath6kl/wmi/wmi.c | 4 -- 23 files changed, 357 deletions(-) delete mode 100644 drivers/staging/ath6kl/include/athendpack.h delete mode 100644 drivers/staging/ath6kl/include/athstartpack.h diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 96e4ed9d04c7..99030345032b 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -110,7 +110,6 @@ ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK endif -ccflags-y += -DLINUX -DKERNEL_2_6 ccflags-y += -DTCMD ccflags-y += -DSEND_EVENT_TO_APP ccflags-y += -DUSER_KEYS diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 1ff221838c0f..e551dbe674dc 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -42,7 +42,6 @@ //#define MBOXHW_UNIT_TEST 1 -#include "athstartpack.h" PREPACK struct ar6k_irq_proc_registers { u8 host_int_status; u8 cpu_int_status; @@ -69,8 +68,6 @@ PREPACK struct ar6k_gmbox_ctrl_registers { u8 int_status_enable; } POSTPACK; -#include "athendpack.h" - #define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers) #define AR6K_REG_IO_BUFFER_SIZE 32 diff --git a/drivers/staging/ath6kl/include/a_config.h b/drivers/staging/ath6kl/include/a_config.h index 4a0083c65113..f7c09319433f 100644 --- a/drivers/staging/ath6kl/include/a_config.h +++ b/drivers/staging/ath6kl/include/a_config.h @@ -26,28 +26,6 @@ #ifndef _A_CONFIG_H_ #define _A_CONFIG_H_ -#ifdef UNDER_NWIFI -#include "../os/windows/include/config.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/config.h" -#endif - -#if defined(__linux__) && !defined(LINUX_EMULATION) #include "../os/linux/include/config_linux.h" -#endif - -#ifdef REXOS -#include "../os/rexos/include/common/config_rexos.h" -#endif - -#ifdef WIN_NWF -#include "../os/windows/include/win/config_win.h" -#endif - -#ifdef THREADX -#include "../os/threadx/include/common/config_threadx.h" -#endif #endif diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index d433942e2b98..51cb633ee6ce 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -187,35 +187,7 @@ void a_dump_module_debug_info_by_name(char *module_name); void a_module_debug_support_init(void); void a_module_debug_support_cleanup(void); -#ifdef UNDER_NWIFI -#include "../os/windows/include/debug.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/debug.h" -#endif - -#if defined(__linux__) && !defined(LINUX_EMULATION) #include "../os/linux/include/debug_linux.h" -#endif - -#ifdef REXOS -#include "../os/rexos/include/common/debug_rexos.h" -#endif - -#if defined ART_WIN -#include "../os/win_art/include/debug_win.h" -#endif - -#ifdef WIN_NWF -#include -#endif - -#ifdef THREADX -#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index))) -#include "../os/threadx/include/common/debug_threadx.h" -#endif - #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/a_drv.h b/drivers/staging/ath6kl/include/a_drv.h index 6db10f0f2d10..1548604e8465 100644 --- a/drivers/staging/ath6kl/include/a_drv.h +++ b/drivers/staging/ath6kl/include/a_drv.h @@ -27,28 +27,6 @@ #ifndef _A_DRV_H_ #define _A_DRV_H_ -#if defined(__linux__) && !defined(LINUX_EMULATION) #include "../os/linux/include/athdrv_linux.h" -#endif - -#ifdef UNDER_NWIFI -#include "../os/windows/include/athdrv.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/athdrv.h" -#endif - -#ifdef REXOS -#include "../os/rexos/include/common/athdrv_rexos.h" -#endif - -#ifdef WIN_NWF -#include "../os/windows/include/athdrv.h" -#endif - -#ifdef THREADX -#include "../os/threadx/include/common/athdrv_threadx.h" -#endif #endif /* _ADRV_H_ */ diff --git a/drivers/staging/ath6kl/include/a_osapi.h b/drivers/staging/ath6kl/include/a_osapi.h index 7bdeeea21503..fd7ae0d612c6 100644 --- a/drivers/staging/ath6kl/include/a_osapi.h +++ b/drivers/staging/ath6kl/include/a_osapi.h @@ -27,35 +27,6 @@ #ifndef _A_OSAPI_H_ #define _A_OSAPI_H_ -#if defined(__linux__) && !defined(LINUX_EMULATION) #include "../os/linux/include/osapi_linux.h" -#endif - -#ifdef UNDER_NWIFI -#include "../os/windows/include/osapi.h" -#include "../os/windows/include/netbuf.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/osapi.h" -#include "../os/windows/include/netbuf.h" -#endif - -#ifdef REXOS -#include "../os/rexos/include/common/osapi_rexos.h" -#endif - -#if defined ART_WIN -#include "../os/win_art/include/osapi_win.h" -#include "../os/win_art/include/netbuf.h" -#endif - -#ifdef WIN_NWF -#include -#endif - -#if defined(THREADX) -#include "../os/threadx/include/common/osapi_threadx.h" -#endif #endif /* _OSAPI_H_ */ diff --git a/drivers/staging/ath6kl/include/a_types.h b/drivers/staging/ath6kl/include/a_types.h index 18f4cfe4f97d..4b6783f6aec7 100644 --- a/drivers/staging/ath6kl/include/a_types.h +++ b/drivers/staging/ath6kl/include/a_types.h @@ -27,32 +27,6 @@ #ifndef _A_TYPES_H_ #define _A_TYPES_H_ -#if defined(__linux__) && !defined(LINUX_EMULATION) #include "../os/linux/include/athtypes_linux.h" -#endif - -#ifdef UNDER_NWIFI -#include "../os/windows/include/athtypes.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/athtypes.h" -#endif - -#ifdef REXOS -#include "../os/rexos/include/common/athtypes_rexos.h" -#endif - -#if defined ART_WIN -#include "../os/win_art/include/athtypes_win.h" -#endif - -#ifdef WIN_NWF -#include -#endif - -#ifdef THREADX -#include "../os/threadx/include/common/athtypes_threadx.h" -#endif #endif /* _ATHTYPES_H_ */ diff --git a/drivers/staging/ath6kl/include/ar6000_api.h b/drivers/staging/ath6kl/include/ar6000_api.h index 1e1d92a507e2..e9460800272c 100644 --- a/drivers/staging/ath6kl/include/ar6000_api.h +++ b/drivers/staging/ath6kl/include/ar6000_api.h @@ -26,29 +26,7 @@ #ifndef _AR6000_API_H_ #define _AR6000_API_H_ -#if defined(__linux__) && !defined(LINUX_EMULATION) #include "../os/linux/include/ar6xapi_linux.h" -#endif - -#ifdef UNDER_NWIFI -#include "../os/windows/include/ar6xapi.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/ar6xapi.h" -#endif - -#ifdef REXOS -#include "../os/rexos/include/common/ar6xapi_rexos.h" -#endif - -#if defined ART_WIN -#include "../os/win_art/include/ar6xapi_win.h" -#endif - -#ifdef WIN_NWF -#include "../os/windows/include/ar6xapi.h" -#endif #endif /* _AR6000_API_H */ diff --git a/drivers/staging/ath6kl/include/athendpack.h b/drivers/staging/ath6kl/include/athendpack.h deleted file mode 100644 index 1b940503bb21..000000000000 --- a/drivers/staging/ath6kl/include/athendpack.h +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// end compiler-specific structure packing -// -// Author(s): ="Atheros" -//============================================================================== -#ifdef VXWORKS -#endif /* VXWORKS */ - -#if defined(LINUX) || defined(__linux__) -#endif /* LINUX */ - -#ifdef QNX -#endif /* QNX */ - -#ifdef INTEGRITY -#include "integrity/athendpack_integrity.h" -#endif /* INTEGRITY */ - -#ifdef NUCLEUS -#endif /* NUCLEUS */ - - -#ifdef UNDER_NWIFI -#include "../os/windows/include/athendpack.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/athendpack.h" -#endif /* WINCE */ - -#ifdef WIN_NWF -#include -#endif diff --git a/drivers/staging/ath6kl/include/athstartpack.h b/drivers/staging/ath6kl/include/athstartpack.h deleted file mode 100644 index 1c45f666d8a2..000000000000 --- a/drivers/staging/ath6kl/include/athstartpack.h +++ /dev/null @@ -1,55 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// start compiler-specific structure packing -// -// Author(s): ="Atheros" -//============================================================================== -#ifdef VXWORKS -#endif /* VXWORKS */ - -#if defined(LINUX) || defined(__linux__) -#endif /* LINUX */ - -#ifdef QNX -#endif /* QNX */ - -#ifdef INTEGRITY -#include "integrity/athstartpack_integrity.h" -#endif /* INTEGRITY */ - -#ifdef NUCLEUS -#endif /* NUCLEUS */ - -#ifdef UNDER_NWIFI -#include "../os/windows/include/athstartpack.h" -#endif - -#ifdef ATHR_CE_LEGACY -#include "../os/windows/include/athstartpack.h" -#endif /* WINCE */ - -#ifdef WIN_NWF -#include -#endif - -#ifdef THREADX -#include "../os/threadx/include/common/osapi_threadx.h" -#endif diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h index e76624c5915c..84e8db569a9f 100644 --- a/drivers/staging/ath6kl/include/common/bmi_msg.h +++ b/drivers/staging/ath6kl/include/common/bmi_msg.h @@ -22,10 +22,6 @@ #ifndef __BMI_MSG_H__ #define __BMI_MSG_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - /* * Bootloader Messaging Interface (BMI) * @@ -234,8 +230,4 @@ PREPACK struct bmi_target_info { * Note: Not supported on all versions of ROM firmware. */ -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* __BMI_MSG_H__ */ diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h index 3a3d00da0b81..e5ef9394f004 100644 --- a/drivers/staging/ath6kl/include/common/dbglog.h +++ b/drivers/staging/ath6kl/include/common/dbglog.h @@ -24,10 +24,6 @@ #ifndef _DBGLOG_H_ #define _DBGLOG_H_ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - #ifdef __cplusplus extern "C" { #endif @@ -127,8 +123,4 @@ PREPACK struct dbglog_config_s { } #endif -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* _DBGLOG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/dset_internal.h b/drivers/staging/ath6kl/include/common/dset_internal.h index 69475331eab7..e3ecd8e1a3c3 100644 --- a/drivers/staging/ath6kl/include/common/dset_internal.h +++ b/drivers/staging/ath6kl/include/common/dset_internal.h @@ -25,10 +25,6 @@ #ifndef __DSET_INTERNAL_H__ #define __DSET_INTERNAL_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - /* * Internal dset definitions, common for DataSet layer. */ @@ -56,8 +52,4 @@ typedef PREPACK struct dset_descriptor_s { Dataset descriptor for BPatch. */ } POSTPACK dset_descriptor_t; -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* __DSET_INTERNAL_H__ */ diff --git a/drivers/staging/ath6kl/include/common/dsetid.h b/drivers/staging/ath6kl/include/common/dsetid.h index 090e30967925..cc797bab5c4c 100644 --- a/drivers/staging/ath6kl/include/common/dsetid.h +++ b/drivers/staging/ath6kl/include/common/dsetid.h @@ -25,10 +25,6 @@ #ifndef __DSETID_H__ #define __DSETID_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - /* Well-known DataSet IDs */ #define DSETID_UNUSED 0x00000000 #define DSETID_BOARD_DATA 0x00000001 /* Cal and board data */ @@ -127,8 +123,4 @@ PREPACK struct patch_s { */ #define DSETID_BPATCH_FLAG 0x80000000 -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* __DSETID_H__ */ diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h index 5c40d8a2229d..c9520edf5c3b 100644 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ b/drivers/staging/ath6kl/include/common/epping_test.h @@ -25,10 +25,6 @@ #ifndef EPPING_TEST_H_ #define EPPING_TEST_H_ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - /* alignment to 4-bytes */ #define EPPING_ALIGNMENT_PAD (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr)) @@ -112,9 +108,4 @@ typedef PREPACK struct { #define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we can use this to distinguish packets */ -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - - #endif /*EPPING_TEST_H_*/ diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h index dd9afbd78ff9..ea11c14def43 100644 --- a/drivers/staging/ath6kl/include/common/gmboxif.h +++ b/drivers/staging/ath6kl/include/common/gmboxif.h @@ -23,10 +23,6 @@ #ifndef __GMBOXIF_H__ #define __GMBOXIF_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - /* GMBOX interface definitions */ #define AR6K_GMBOX_CREDIT_COUNTER 1 /* we use credit counter 1 to track credits */ @@ -70,9 +66,5 @@ typedef PREPACK struct { #define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF 4 -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* __GMBOXIF_H__ */ diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h index b9d4495d4324..85cbfa89d670 100644 --- a/drivers/staging/ath6kl/include/common/htc.h +++ b/drivers/staging/ath6kl/include/common/htc.h @@ -24,10 +24,6 @@ #ifndef __HTC_H__ #define __HTC_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - #define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field)) #define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \ @@ -227,10 +223,5 @@ typedef PREPACK struct { u8 LookAhead[4]; /* 4 byte lookahead */ } POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT; -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - - #endif /* __HTC_H__ */ diff --git a/drivers/staging/ath6kl/include/common/regdump.h b/drivers/staging/ath6kl/include/common/regdump.h index aa64821617e8..614dfa102ea1 100644 --- a/drivers/staging/ath6kl/include/common/regdump.h +++ b/drivers/staging/ath6kl/include/common/regdump.h @@ -24,10 +24,6 @@ #ifndef __REGDUMP_H__ #define __REGDUMP_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - #if defined(AR6001) #include "AR6001/AR6001_regdump.h" #endif @@ -52,8 +48,4 @@ PREPACK struct register_dump_s { } POSTPACK; #endif /* __ASSEMBLER__ */ -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* __REGDUMP_H__ */ diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h index 794ae2182a77..e921b302c451 100644 --- a/drivers/staging/ath6kl/include/common/targaddrs.h +++ b/drivers/staging/ath6kl/include/common/targaddrs.h @@ -22,10 +22,6 @@ #ifndef __TARGADDRS_H__ #define __TARGADDRS_H__ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - #if defined(AR6002) #include "AR6002/addrs.h" #endif @@ -238,8 +234,4 @@ PREPACK struct host_interest_s { #endif /* !__ASSEMBLER__ */ -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #endif /* __TARGADDRS_H__ */ diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index d3de3cca0c7f..363e9353a6b4 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -34,10 +34,6 @@ #ifndef _WMI_H_ #define _WMI_H_ -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - #include "wmix.h" #include "wlan_defs.h" @@ -3122,10 +3118,6 @@ typedef PREPACK struct { * End of AP mode definitions */ -#ifndef ATH_TARGET -#include "athendpack.h" -#endif - #ifdef __cplusplus } #endif diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h index 5ebb8285d135..38c2970aa4da 100644 --- a/drivers/staging/ath6kl/include/common/wmix.h +++ b/drivers/staging/ath6kl/include/common/wmix.h @@ -40,10 +40,6 @@ extern "C" { #endif -#ifndef ATH_TARGET -#include "athstartpack.h" -#endif - #include "dbglog.h" /* @@ -268,9 +264,6 @@ typedef PREPACK struct { u32 count; } POSTPACK WMIX_PROF_COUNT_EVENT; -#ifndef ATH_TARGET -#include "athendpack.h" -#endif #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h index 532ab0eb20c3..cf47d0657e70 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h @@ -23,8 +23,6 @@ #ifndef _NET80211_IEEE80211_H_ #define _NET80211_IEEE80211_H_ -#include "athstartpack.h" - /* * 802.11 protocol definitions. */ @@ -396,6 +394,4 @@ enum ieee80211_authmode { #define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/ -#include "athendpack.h" - #endif /* _NET80211_IEEE80211_H_ */ diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 153ca1f5bc92..aad0c97dca00 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -265,8 +265,6 @@ const u8 up_to_ac[]= { WMM_AC_VO, }; -#include "athstartpack.h" - /* This stuff is used when we want a simple layer-3 visibility */ typedef PREPACK struct _iphdr { u8 ip_ver_hdrlen; /* version and hdr length */ @@ -284,8 +282,6 @@ typedef PREPACK struct _iphdr { u8 ip_dst[4]; } POSTPACK iphdr; -#include "athendpack.h" - static s16 rssi_event_value = 0; static s16 snr_event_value = 0; -- GitLab From 871f7105cc406fb963d1b47f0f99608f6b5037df Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:09 -0700 Subject: [PATCH 0432/5560] ath6kl: remove SEND_EVENT_TO_APP define This was enabled by default but its pretty useless for upstream given that its sendign some custom wireless event. These need to be reviewed instead and a respective cfg80211 event / call should be used later. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 2 - drivers/staging/ath6kl/include/a_drv_api.h | 16 +-- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 113 +----------------- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 2 - .../ath6kl/os/linux/include/ar6xapi_linux.h | 5 - drivers/staging/ath6kl/wmi/wmi.c | 16 --- 6 files changed, 4 insertions(+), 150 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 99030345032b..a86dd5a7229c 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -110,8 +110,6 @@ ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK endif -ccflags-y += -DTCMD -ccflags-y += -DSEND_EVENT_TO_APP ccflags-y += -DUSER_KEYS ccflags-y += -DNO_SYNC_FLUSH ccflags-y += -DHTC_EP_STAT_PROFILING diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h index 9814de5a7bc7..a40d97a84ffc 100644 --- a/drivers/staging/ath6kl/include/a_drv_api.h +++ b/drivers/staging/ath6kl/include/a_drv_api.h @@ -130,19 +130,9 @@ extern "C" { #define A_WMI_PEER_EVENT(devt, eventCode, bssid) \ ar6000_peer_event ((devt), (eventCode), (bssid)) -#ifdef SEND_EVENT_TO_APP - -#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) \ - ar6000_send_event_to_app((ar), (eventId), (datap), (len)) - -#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len) \ - ar6000_send_generic_event_to_app((ar), (eventId), (datap), (len)) - -#else - -#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) -#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len) - +#ifdef CONFIG_HOST_TCMD_SUPPORT +#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \ + ar6000_tcmd_rx_report_event((devt), (results), (len)) #endif #define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \ diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index d1c7b5fd7fc7..2a5abe0cc1c3 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -591,7 +591,6 @@ ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, send = dbglog_get_debug_fragment(&buffer[sent], length - sent, MAX_WIRELESS_EVENT_SIZE); while (send) { - ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, (u8 *)&buffer[sent], send); sent += send; send = dbglog_get_debug_fragment(&buffer[sent], length - sent, MAX_WIRELESS_EVENT_SIZE); @@ -1830,9 +1829,6 @@ static void ar6000_target_failure(void *Instance, int Status) sip = true; errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; - ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, - (u8 *)&errEvent, - sizeof(WMI_TARGET_ERROR_REPORT_EVENT)); } } } @@ -2122,9 +2118,6 @@ static void ar6000_detect_error(unsigned long ptr) ar->arHBChallengeResp.seqNum = 0; errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; AR6000_SPIN_UNLOCK(&ar->arLock, 0); - ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, - (u8 *)&errEvent, - sizeof(WMI_TARGET_ERROR_REPORT_EVENT)); return; } @@ -4922,19 +4915,13 @@ ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThre userRssiThold.rssi = rssi; A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold, userRssiThold.tag, userRssiThold.rssi); - - ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(u8 *)&userRssiThold, sizeof(USER_RSSI_THOLD)); } void ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source) { - if (source == APP_HB_CHALLENGE) { - /* Report it to the app in case it wants a positive acknowledgement */ - ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID, - (u8 *)&cookie, sizeof(cookie)); - } else { + if (source != APP_HB_CHALLENGE) { /* This would ignore the replys that come in after their due time */ if (cookie == ar->arHBChallengeResp.seqNum) { ar->arHBChallengeResp.outstanding = false; @@ -5387,100 +5374,6 @@ ar6000_alloc_cookie(struct ar6_softc *ar) return cookie; } -#ifdef SEND_EVENT_TO_APP -/* - * This function is used to send event which come from taget to - * the application. The buf which send to application is include - * the event ID and event content. - */ -#define EVENT_ID_LEN 2 -void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId, - u8 *datap, int len) -{ - -#if (WIRELESS_EXT >= 15) - -/* note: IWEVCUSTOM only exists in wireless extensions after version 15 */ - - char *buf; - u16 size; - union iwreq_data wrqu; - - size = len + EVENT_ID_LEN; - - if (size > IW_CUSTOM_MAX) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n", - eventId, size, IW_CUSTOM_MAX)); - return; - } - - buf = A_MALLOC_NOWAIT(size); - if (NULL == buf){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size)); - return; - } - - A_MEMZERO(buf, size); - memcpy(buf, &eventId, EVENT_ID_LEN); - memcpy(buf+EVENT_ID_LEN, datap, len); - - //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(u16 *)buf, size)); - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = size; - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); - kfree(buf); -#endif - - -} - -/* - * This function is used to send events larger than 256 bytes - * to the application. The buf which is sent to application - * includes the event ID and event content. - */ -void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId, - u8 *datap, int len) -{ - -#if (WIRELESS_EXT >= 18) - -/* IWEVGENIE exists in wireless extensions version 18 onwards */ - - char *buf; - u16 size; - union iwreq_data wrqu; - - size = len + EVENT_ID_LEN; - - if (size > IW_GENERIC_IE_MAX) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVGENIE (max=%d) \n", - eventId, size, IW_GENERIC_IE_MAX)); - return; - } - - buf = A_MALLOC_NOWAIT(size); - if (NULL == buf){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size)); - return; - } - - A_MEMZERO(buf, size); - memcpy(buf, &eventId, EVENT_ID_LEN); - memcpy(buf+EVENT_ID_LEN, datap, len); - - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = size; - wireless_send_event(ar->arNetDev, IWEVGENIE, &wrqu, buf); - - kfree(buf); - -#endif /* (WIRELESS_EXT >= 18) */ - -} -#endif /* SEND_EVENT_TO_APP */ - - void ar6000_tx_retry_err_event(void *devt) { @@ -5491,13 +5384,9 @@ void ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr) { WMI_SNR_THRESHOLD_EVENT event; - struct ar6_softc *ar = (struct ar6_softc *)devt; event.range = newThreshold; event.snr = snr; - - ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (u8 *)&event, - sizeof(WMI_SNR_THRESHOLD_EVENT)); } void diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index b2459097f7c7..1004f245d795 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -624,8 +624,6 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool } if (pSleepEvent) { AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState)); - ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)pSleepEvent, - sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); } } up(&ar->arSem); diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index 1acfb9cb7c73..dd6905c41b76 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -83,11 +83,6 @@ s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above); void ar6000_dbglog_init_done(struct ar6_softc *ar); -#ifdef SEND_EVENT_TO_APP -void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len); -void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len); -#endif - #ifdef CONFIG_HOST_TCMD_SUPPORT void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len); #endif diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index aad0c97dca00..e1f6acd32436 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -944,23 +944,19 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) case (WMI_READY_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG)); status = wmi_ready_event_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt); break; case (WMI_CONNECT_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG)); status = wmi_connect_event_rx(wmip, datap, len); - A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_DISCONNECT_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG)); status = wmi_disconnect_event_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_PEER_NODE_EVENTID): A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG)); status = wmi_peer_node_event_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_TKIP_MICERR_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG)); @@ -991,7 +987,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN); status = wmi_bssInfo_event_rx(wmip, datap, len); - A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); } break; case (WMI_REGDOMAIN_EVENTID): @@ -1001,13 +996,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) case (WMI_PSTREAM_TIMEOUT_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG)); status = wmi_pstream_timeout_event_rx(wmip, datap, len); - /* pstreams are fatpipe abstractions that get implicitly created. - * User apps only deal with thinstreams. creation of a thinstream - * by the user or data traffic flow in an AC triggers implicit - * pstream creation. Do we need to send this event to App..? - * no harm in sending it. - */ - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_NEIGHBOR_REPORT_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG)); @@ -1016,7 +1004,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) case (WMI_SCAN_COMPLETE_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG)); status = wmi_scanComplete_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_CMDERROR_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG)); @@ -1033,7 +1020,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) case (WMI_ERROR_REPORT_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG)); status = wmi_reportErrorEvent_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_OPT_RX_FRAME_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG)); @@ -1072,7 +1058,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) case (WMI_TX_RETRY_ERR_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG)); status = wmi_txRetryErrEvent_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_SNR_THRESHOLD_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG)); @@ -1081,7 +1066,6 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) case (WMI_LQ_THRESHOLD_EVENTID): A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG)); status = wmi_lqThresholdEvent_rx(wmip, datap, len); - A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); break; case (WMI_APLIST_EVENTID): AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n")); -- GitLab From efa5dc420a0f2f3f8dbc6b2d4037b8148b3cdb64 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:10 -0700 Subject: [PATCH 0433/5560] ath6kl: remove USER_KEYS define This is always defined so just keep the code. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - drivers/staging/ath6kl/os/linux/ar6000_drv.c | 11 ----------- drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 5 ----- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 2 -- 4 files changed, 19 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index a86dd5a7229c..d7441e75e2ac 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -110,7 +110,6 @@ ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK endif -ccflags-y += -DUSER_KEYS ccflags-y += -DNO_SYNC_FLUSH ccflags-y += -DHTC_EP_STAT_PROFILING ccflags-y += -DWAPI_ENABLE diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 2a5abe0cc1c3..abde25626a06 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -349,9 +349,7 @@ static void ar6000_cookie_cleanup(struct ar6_softc *ar); static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie); static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar); -#ifdef USER_KEYS static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl); -#endif #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT struct net_device *arApNetDev; @@ -1926,10 +1924,8 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0); } } -#ifdef USER_KEYS ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; ar->user_key_ctrl = 0; -#endif } AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__)); @@ -4347,7 +4343,6 @@ ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); } -#ifdef USER_KEYS if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN && ar->user_saved_keys.keyOk == true) { @@ -4360,7 +4355,6 @@ ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, } ar6000_reinstall_keys(ar, key_op_ctrl); } -#endif /* USER_KEYS */ netif_wake_queue(ar->arNetDev); @@ -4581,13 +4575,11 @@ ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, reconnect_flag = 0; } -#ifdef USER_KEYS if (reason != CSERV_DISCONNECT) { ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; ar->user_key_ctrl = 0; } -#endif /* USER_KEYS */ netif_stop_queue(ar->arNetDev); A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); @@ -5713,9 +5705,7 @@ void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac) } #endif -#ifdef USER_KEYS static int - ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl) { int status = 0; @@ -5760,7 +5750,6 @@ ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl) return status; } -#endif /* USER_KEYS */ void diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 5b053ab2e618..23427cfb8896 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -92,8 +92,6 @@ #endif -#ifdef USER_KEYS - #define USER_SAVEDKEYS_STAT_INIT 0 #define USER_SAVEDKEYS_STAT_RUN 1 @@ -104,7 +102,6 @@ struct USER_SAVEDKEYS { CRYPTO_TYPE keyType; bool keyOk; }; -#endif #define DBG_INFO 0x00000001 #define DBG_ERROR 0x00000002 @@ -540,11 +537,9 @@ struct ar6_softc { u32 log_cnt; u32 dbglog_init_done; u32 arConnectCtrlFlags; -#ifdef USER_KEYS s32 user_savedkeys_stat; u32 user_key_ctrl; struct USER_SAVEDKEYS user_saved_keys; -#endif USER_RSSI_THOLD rssi_map[12]; u8 arUserBssFilter; u16 ap_profile_flag; /* AP mode */ diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 065b09be09f8..3d5f01da543f 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -620,7 +620,6 @@ typedef enum { */ #define AR6000_XIOCTL_WMI_SET_TXOP 57 -#ifdef USER_KEYS /* * arguments: * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS) @@ -628,7 +627,6 @@ typedef enum { * uses struct ar6000_user_setkeys_info */ #define AR6000_XIOCTL_USER_SETKEYS 58 -#endif /* USER_KEYS */ #define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 /* -- GitLab From e53a79d977071cb3cd9bb2923693a8fe6a7b884e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:11 -0700 Subject: [PATCH 0434/5560] ath6kl: remove unused define NO_SYNC_FLUSH Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index d7441e75e2ac..50f9be3eefcb 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -110,7 +110,6 @@ ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK endif -ccflags-y += -DNO_SYNC_FLUSH ccflags-y += -DHTC_EP_STAT_PROFILING ccflags-y += -DWAPI_ENABLE ccflags-y += -DCHECKSUM_OFFLOAD -- GitLab From 382241010ce9cc231c350524695db9d822971da2 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:12 -0700 Subject: [PATCH 0435/5560] ath6kl: remove define HTC_EP_STAT_PROFILING This is always set so just keep the code it idefs around. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - drivers/staging/ath6kl/htc2/htc.c | 6 ------ drivers/staging/ath6kl/htc2/htc_internal.h | 8 -------- drivers/staging/ath6kl/htc2/htc_recv.c | 6 ------ drivers/staging/ath6kl/htc2/htc_send.c | 5 ----- 5 files changed, 26 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 50f9be3eefcb..d79f8629708b 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -110,7 +110,6 @@ ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK endif -ccflags-y += -DHTC_EP_STAT_PROFILING ccflags-y += -DWAPI_ENABLE ccflags-y += -DCHECKSUM_OFFLOAD ccflags-y += -DWLAN_HEADERS diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index f30865542f87..ae54e64b6243 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -448,9 +448,7 @@ static void ResetEndpointStates(struct htc_target *target) pEndpoint->ServiceID = 0; pEndpoint->MaxMsgLength = 0; pEndpoint->MaxTxQueueDepth = 0; -#ifdef HTC_EP_STAT_PROFILING A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats)); -#endif INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers); INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue); INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue); @@ -527,7 +525,6 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, struct htc_endpoint_stats *pStats) { -#ifdef HTC_EP_STAT_PROFILING struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); bool clearStats = false; bool sample = false; @@ -568,9 +565,6 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, UNLOCK_HTC_TX(target); return true; -#else - return false; -#endif } struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle) diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 9425ed983671..1c9aeca41143 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -27,7 +27,6 @@ * processing errors, the last frame header is dump for comparison */ //#define HTC_CAPTURE_LAST_FRAME -//#define HTC_EP_STAT_PROFILING #ifdef __cplusplus extern "C" { @@ -82,17 +81,10 @@ struct htc_endpoint { struct htc_target *target; /* back pointer to target */ u8 SeqNo; /* TX seq no (helpful) for debugging */ u32 LocalConnectionFlags; /* local connection flags */ -#ifdef HTC_EP_STAT_PROFILING struct htc_endpoint_stats EndPointStats; /* endpoint statistics */ -#endif }; -#ifdef HTC_EP_STAT_PROFILING #define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count); -#else -#define INC_HTC_EP_STAT(p,stat,count) -#endif - #define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL #define NUM_CONTROL_BUFFERS 8 diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index c2088018c51d..974cc8cd6936 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -36,7 +36,6 @@ (pP)->PktInfo.AsRx.ExpectedHdr, \ (pP)->Endpoint)) -#ifdef HTC_EP_STAT_PROFILING #define HTC_RX_STAT_PROFILE(t,ep,numLookAheads) \ { \ INC_HTC_EP_STAT((ep), RxReceived, 1); \ @@ -46,9 +45,6 @@ INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1); \ } \ } -#else -#define HTC_RX_STAT_PROFILE(t,ep,lookAhead) -#endif static void DoRecvCompletion(struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueueToIndicate) @@ -931,12 +927,10 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) } if (!status) { -#ifdef HTC_EP_STAT_PROFILING LOCK_HTC_RX(target); HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads); INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1); UNLOCK_HTC_RX(target); -#endif if (i == (pScatterReq->ValidScatterEntries - 1)) { /* last packet's more packets flag is set based on the lookahead */ SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket); diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 6f4050a98c85..9310d4d5c992 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -776,9 +776,6 @@ void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n", pRpt->EndpointID, pRpt->Credits)); - -#ifdef HTC_EP_STAT_PROFILING - INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1); INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits); @@ -797,8 +794,6 @@ void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1); } -#endif - if (ENDPOINT_0 == pRpt->EndpointID) { /* always give endpoint 0 credits back */ pEndpoint->CreditDist.TxCredits += pRpt->Credits; -- GitLab From f22ac91fae621dc6035e15b489e46b711ad22689 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:13 -0700 Subject: [PATCH 0436/5560] ath6kl: remove unused define WLAN_HEADERS All the code is used so just keep it and remove the static define. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - .../common/AR6002/hw4.0/hw/analog_intf_reg.h | 13 ------------- .../include/common/AR6002/hw4.0/hw/apb_map.h | 8 -------- .../include/common/AR6002/hw4.0/hw/gpio_reg.h | 8 -------- .../include/common/AR6002/hw4.0/hw/mbox_host_reg.h | 13 ------------- .../include/common/AR6002/hw4.0/hw/mbox_reg.h | 8 -------- .../include/common/AR6002/hw4.0/hw/rtc_reg.h | 8 -------- .../include/common/AR6002/hw4.0/hw/umbox_reg.h | 14 -------------- .../include/common/AR6002/hw4.0/hw/vmc_reg.h | 8 -------- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 14 -------------- drivers/staging/ath6kl/wmi/wmi.c | 2 -- 11 files changed, 97 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index d79f8629708b..cd04fbab486b 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -112,7 +112,6 @@ endif ccflags-y += -DWAPI_ENABLE ccflags-y += -DCHECKSUM_OFFLOAD -ccflags-y += -DWLAN_HEADERS ccflags-y += -DINIT_MODE_DRV_ENABLED obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h index 01b9eb54a43c..b8de1c9efd5c 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h @@ -21,17 +21,4 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "analog_intf_athr_wlan_reg.h" - - -#ifndef BT_HEADERS - - - -#endif -#endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h index e4d2d62f0bb4..0068ca31b051 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h @@ -21,11 +21,8 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "apb_athr_wlan_map.h" - #ifndef BT_HEADERS #define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS @@ -40,9 +37,4 @@ #define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS #define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS - -#endif #endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h index b3e7126e26a2..afef47ebf1f8 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h @@ -21,11 +21,8 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "gpio_athr_wlan_reg.h" - #ifndef BT_HEADERS #define GPIO_OUT_ADDRESS WLAN_GPIO_OUT_ADDRESS @@ -1086,9 +1083,4 @@ #define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) #define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) - -#endif #endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h index 3af562156f6e..109f24e10a65 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h @@ -21,17 +21,4 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "mbox_wlan_host_reg.h" - - -#ifndef BT_HEADERS - - - -#endif -#endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h index cc67585e2e8b..72fa483450d6 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h @@ -21,11 +21,8 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "mbox_wlan_reg.h" - #ifndef BT_HEADERS #define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS @@ -552,9 +549,4 @@ #define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x) #define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x) - -#endif #endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h index 0855de5f1400..82bd708eba35 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h @@ -21,11 +21,8 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "rtc_wlan_reg.h" - #ifndef BT_HEADERS #define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS @@ -967,9 +964,4 @@ #define GPIO_WAKEUP_CONTROL_ENABLE_GET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x) #define GPIO_WAKEUP_CONTROL_ENABLE_SET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x) - -#endif #endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h index b233cbc513bc..b18ff48171a8 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h @@ -20,18 +20,4 @@ // Author(s): ="Atheros" //=================================================================== - -#ifdef WLAN_HEADERS - #include "umbox_wlan_reg.h" - - -#ifndef BT_HEADERS - - - -#endif -#endif - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h index c3d8088a5554..990f2be2cd18 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h +++ b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h @@ -21,11 +21,8 @@ //=================================================================== -#ifdef WLAN_HEADERS - #include "vmc_wlan_reg.h" - #ifndef BT_HEADERS #define MC_BCAM_VALID_ADDRESS WLAN_MC_BCAM_VALID_ADDRESS @@ -159,9 +156,4 @@ #define CPU_RAM4_CONFLICT_CNT_GET(x) WLAN_CPU_RAM4_CONFLICT_CNT_GET(x) #define CPU_RAM4_CONFLICT_CNT_SET(x) WLAN_CPU_RAM4_CONFLICT_CNT_SET(x) - -#endif #endif - - - diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index abde25626a06..b9d04715b7aa 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -152,10 +152,8 @@ unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT; unsigned int hciuartscale = HCIUARTSCALE_DEFAULT; unsigned int hciuartstep = HCIUARTSTEP_DEFAULT; #endif -#ifdef CONFIG_CHECKSUM_OFFLOAD unsigned int csumOffload=0; unsigned int csumOffloadTest=0; -#endif unsigned int eppingtest=0; module_param_string(ifname, ifname, sizeof(ifname), 0644); @@ -177,9 +175,7 @@ module_param(reduce_credit_dribble, int, 0644); module_param(allow_trace_signal, int, 0644); module_param(enablerssicompensation, uint, 0644); module_param(processDot11Hdr, uint, 0644); -#ifdef CONFIG_CHECKSUM_OFFLOAD module_param(csumOffload, uint, 0644); -#endif #ifdef CONFIG_HOST_TCMD_SUPPORT module_param(testmode, uint, 0644); #endif @@ -1744,12 +1740,10 @@ ar6000_avail_ev(void *context, void *hif_handle) #endif -#ifdef CONFIG_CHECKSUM_OFFLOAD if(csumOffload){ /*if external frame work is also needed, change and use an extended rxMetaVerion*/ ar->rxMetaVersion=WMI_META_VERSION_2; } -#endif ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs); if (!ar->aggr_cntxt) { @@ -3006,7 +3000,6 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) } if (ar->arWmiEnabled) { -#ifdef CONFIG_CHECKSUM_OFFLOAD u8 csumStart=0; u8 csumDest=0; u8 csum=skb->ip_summed; @@ -3015,7 +3008,6 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) sizeof(ATH_LLC_SNAP_HDR)); csumDest=skb->csum_offset+csumStart; } -#endif if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) { struct sk_buff *newbuf; @@ -3046,7 +3038,6 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) break; } } -#ifdef CONFIG_CHECKSUM_OFFLOAD if(csumOffload && (csum ==CHECKSUM_PARTIAL)){ WMI_TX_META_V2 metaV2; metaV2.csumStart =csumStart; @@ -3060,7 +3051,6 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) } else -#endif { if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n")); @@ -3693,11 +3683,9 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) case WMI_META_VERSION_1: offset += sizeof(WMI_RX_META_V1); break; -#ifdef CONFIG_CHECKSUM_OFFLOAD case WMI_META_VERSION_2: offset += sizeof(WMI_RX_META_V2); break; -#endif default: break; } @@ -3767,7 +3755,6 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1)); break; } -#ifdef CONFIG_CHECKSUM_OFFLOAD case WMI_META_VERSION_2: { WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb); @@ -3778,7 +3765,6 @@ ar6000_rx(void *Context, struct htc_packet *pPacket) A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2)); break; } -#endif default: break; } diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index e1f6acd32436..3f5bbe3691f7 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -463,7 +463,6 @@ int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) *pVersion = WMI_META_VERSION_1; return (0); } -#ifdef CONFIG_CHECKSUM_OFFLOAD case WMI_META_VERSION_2: { WMI_TX_META_V2 *pV2 ; @@ -475,7 +474,6 @@ int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2)); return (0); } -#endif default: return (0); } -- GitLab From 1822d7f80e35fd605687cdf194f15f1c151cdb17 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:14 -0700 Subject: [PATCH 0437/5560] ath6kl: remove INIT_MODE_DRV_ENABLED define Since this is defined statically we just leave the code. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 1 - drivers/staging/ath6kl/os/linux/ar6000_drv.c | 14 ++++---------- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 4 ---- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index cd04fbab486b..8a46e93fd2e7 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -112,7 +112,6 @@ endif ccflags-y += -DWAPI_ENABLE ccflags-y += -DCHECKSUM_OFFLOAD -ccflags-y += -DINIT_MODE_DRV_ENABLED obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o ath6kl-y += htc2/AR6000/ar6k.o diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index b9d04715b7aa..8f9e4b2797b8 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -852,8 +852,6 @@ ar6000_sysfs_bmi_deinit(struct ar6_softc *ar) } \ } while(0) -#ifdef INIT_MODE_DRV_ENABLED - #ifdef SOFTMAC_FILE_USED #define AR6002_MAC_ADDRESS_OFFSET 0x0A #define AR6003_MAC_ADDRESS_OFFSET 0x16 @@ -1111,7 +1109,6 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, A_RELEASE_FIRMWARE(fw_entry); return 0; } -#endif /* INIT_MODE_DRV_ENABLED */ int ar6000_update_bdaddr(struct ar6_softc *ar) @@ -1158,7 +1155,6 @@ ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode) } A_RELEASE_FIRMWARE(fw_entry); -#ifdef INIT_MODE_DRV_ENABLED } else { /* The config is contained within the driver itself */ int status; @@ -1348,8 +1344,6 @@ ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode) msleep(1000); } #endif /* HTC_RAW_INTERFACE */ - -#endif /* INIT_MODE_DRV_ENABLED */ } return 0; @@ -2340,10 +2334,10 @@ u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) int ar6000_target_config_wlan_params(struct ar6_softc *ar) { int status = 0; -#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) +#if defined(ENABLE_COEXISTENCE) WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; -#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ +#endif /* ENABLE_COEXISTENCE */ #ifdef CONFIG_HOST_TCMD_SUPPORT if (ar->arTargetMode != AR6000_WLAN_MODE) { @@ -2361,7 +2355,7 @@ int ar6000_target_config_wlan_params(struct ar6_softc *ar) status = A_ERROR; } -#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) +#if defined(ENABLE_COEXISTENCE) /* Configure the type of BT collocated with WLAN */ memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); #ifdef CONFIG_AR600x_BT_QCOM @@ -2393,7 +2387,7 @@ int ar6000_target_config_wlan_params(struct ar6_softc *ar) AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n")); status = A_ERROR; } -#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ +#endif /* ENABLE_COEXISTENCE */ #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 23427cfb8896..205a7bf613fc 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -238,11 +238,7 @@ typedef enum _AR6K_BIN_FILE { #define HCIUARTSTEP_DEFAULT 0 #endif /* AR600x_BT_AR3001 */ -#ifdef INIT_MODE_DRV_ENABLED #define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_DRV -#else -#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_USR -#endif /* INIT_MODE_DRV_ENABLED */ #define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \ if ((_ver) == AR6003_REV1_VERSION) { \ -- GitLab From 492543eae4f95a746c9d10265c78a3d2853ac315 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:15 -0700 Subject: [PATCH 0438/5560] ath6kl: use CONFIG_AR600x_SD31_XXX When CONFIG_AR600x_SD31_XXX gets enabled we define another flag called AR600x_SD31_XXX, just use CONFIG_AR600x_SD31_XXX since that is already defined by the generated autoconf header file from the kernel. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 4 ---- drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 8a46e93fd2e7..888b8fccaf0c 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -29,10 +29,6 @@ ccflags-y += -I$(obj)/os ccflags-y += -I$(obj)/bmi/include ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 -ifeq ($(CONFIG_AR600x_SD31_XXX),y) -ccflags-y += -DAR600x_SD31_XXX -endif - ifeq ($(CONFIG_AR600x_WB31_XXX),y) ccflags-y += -DAR600x_WB31_XXX endif diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 205a7bf613fc..f089242c66bc 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -283,7 +283,7 @@ typedef enum _AR6K_BIN_FILE { #define AR6003_REV1_ART_FIRMWARE_FILE "ath6k/AR6003/hw1.0/device.bin" #define AR6003_REV1_PATCH_FILE "ath6k/AR6003/hw1.0/data.patch.bin" #define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin" -#ifdef AR600x_SD31_XXX +#ifdef CONFIG_AR600x_SD31_XXX #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin" #elif defined(AR600x_SD32_XXX) #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin" @@ -303,7 +303,7 @@ typedef enum _AR6K_BIN_FILE { #define AR6003_REV2_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.0/device.bin" #define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" #define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin" -#ifdef AR600x_SD31_XXX +#ifdef CONFIG_AR600x_SD31_XXX #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" #elif defined(AR600x_SD32_XXX) #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin" -- GitLab From 1e6d4562eb7f2ecef9c03639f2ca6f3e6d6fdf7e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:16 -0700 Subject: [PATCH 0439/5560] ath6kl: use CONFIG_AR600x_WB31_XXX When CONFIG_AR600x_WB31_XXX gets enabled we define another flag called AR600x_WB31_XXX, just use CONFIG_AR600x_WB31_XXX since that is already defined by the generated autoconf header file from the kernel. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 4 ---- drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 888b8fccaf0c..4dbfb65c2c83 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -29,10 +29,6 @@ ccflags-y += -I$(obj)/os ccflags-y += -I$(obj)/bmi/include ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 -ifeq ($(CONFIG_AR600x_WB31_XXX),y) -ccflags-y += -DAR600x_WB31_XXX -endif - ifeq ($(CONFIG_AR600x_SD32_XXX),y) ccflags-y += -DAR600x_SD32_XXX endif diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index f089242c66bc..1d6b26371201 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -287,7 +287,7 @@ typedef enum _AR6K_BIN_FILE { #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin" #elif defined(AR600x_SD32_XXX) #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin" -#elif defined(AR600x_WB31_XXX) +#elif defined(CONFIG_AR600x_WB31_XXX) #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin" #else #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin" @@ -307,7 +307,7 @@ typedef enum _AR6K_BIN_FILE { #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" #elif defined(AR600x_SD32_XXX) #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin" -#elif defined(AR600x_WB31_XXX) +#elif defined(CONFIG_AR600x_WB31_XXX) #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin" #else #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin" -- GitLab From 42ad85dbc1c594f34a272ddbaee6387f4f369f8a Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:17 -0700 Subject: [PATCH 0440/5560] ath6kl: use CONFIG_AR600x_SD32_XXX When CONFIG_AR600x_SD32_XXX gets enabled we define another flag called AR600x_SD32_XXX, just use CONFIG_AR600x_SD32_XXX since that is already defined by the generated autoconf header file from the kernel. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 4 ---- drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 4dbfb65c2c83..3df4c86ee671 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -29,10 +29,6 @@ ccflags-y += -I$(obj)/os ccflags-y += -I$(obj)/bmi/include ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 -ifeq ($(CONFIG_AR600x_SD32_XXX),y) -ccflags-y += -DAR600x_SD32_XXX -endif - ifeq ($(CONFIG_AR600x_CUSTOM_XXX),y) ccflags-y += -DAR600x_CUSTOM_XXX endif diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 1d6b26371201..764f8f184fe9 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -285,7 +285,7 @@ typedef enum _AR6K_BIN_FILE { #define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin" #ifdef CONFIG_AR600x_SD31_XXX #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin" -#elif defined(AR600x_SD32_XXX) +#elif defined(CONFIG_AR600x_SD32_XXX) #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin" #elif defined(CONFIG_AR600x_WB31_XXX) #define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin" @@ -305,7 +305,7 @@ typedef enum _AR6K_BIN_FILE { #define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin" #ifdef CONFIG_AR600x_SD31_XXX #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" -#elif defined(AR600x_SD32_XXX) +#elif defined(CONFIG_AR600x_SD32_XXX) #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin" #elif defined(CONFIG_AR600x_WB31_XXX) #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin" -- GitLab From 5b1978ee0053667956ef9d65e5b48d2f1f14bc05 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:18 -0700 Subject: [PATCH 0441/5560] ath6kl: remove AR600x_CUSTOM_XXX define There already is a CONFIG_AR600x_CUSTOM_XXX if this is desired to be used. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index 3df4c86ee671..b0f711ea5dd2 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -29,10 +29,6 @@ ccflags-y += -I$(obj)/os ccflags-y += -I$(obj)/bmi/include ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 -ifeq ($(CONFIG_AR600x_CUSTOM_XXX),y) -ccflags-y += -DAR600x_CUSTOM_XXX -endif - ifeq ($(CONFIG_ATH6KL_ENABLE_COEXISTENCE),y) ccflags-y += -DENABLE_COEXISTENCE endif -- GitLab From 524717f1a4624dcee164a69722bb1506d97c5d80 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:19 -0700 Subject: [PATCH 0442/5560] ath6kl: use CONFIG_ATH6KL_ENABLE_COEXISTENCE When CONFIG_ATH6KL_ENABLE_COEXISTENCE gets enabled we define another flag called ENABLE_COEXISTENCE, just use CONFIG_ATH6KL_ENABLE_COEXISTENCE since that is already defined by the generated autoconf header file from the kernel. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/Makefile | 4 ---- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile index b0f711ea5dd2..1d3f2390a172 100644 --- a/drivers/staging/ath6kl/Makefile +++ b/drivers/staging/ath6kl/Makefile @@ -29,10 +29,6 @@ ccflags-y += -I$(obj)/os ccflags-y += -I$(obj)/bmi/include ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 -ifeq ($(CONFIG_ATH6KL_ENABLE_COEXISTENCE),y) -ccflags-y += -DENABLE_COEXISTENCE -endif - ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y) ccflags-y += -DAR600x_DUAL_ANTENNA endif diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 8f9e4b2797b8..1798889657d3 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2334,10 +2334,10 @@ u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) int ar6000_target_config_wlan_params(struct ar6_softc *ar) { int status = 0; -#if defined(ENABLE_COEXISTENCE) +#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; -#endif /* ENABLE_COEXISTENCE */ +#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ #ifdef CONFIG_HOST_TCMD_SUPPORT if (ar->arTargetMode != AR6000_WLAN_MODE) { @@ -2355,7 +2355,7 @@ int ar6000_target_config_wlan_params(struct ar6_softc *ar) status = A_ERROR; } -#if defined(ENABLE_COEXISTENCE) +#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) /* Configure the type of BT collocated with WLAN */ memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); #ifdef CONFIG_AR600x_BT_QCOM @@ -2387,7 +2387,7 @@ int ar6000_target_config_wlan_params(struct ar6_softc *ar) AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n")); status = A_ERROR; } -#endif /* ENABLE_COEXISTENCE */ +#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { -- GitLab From 0e7fd280fb1eb8a870d223fdfe4821d318001af5 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:20 -0700 Subject: [PATCH 0443/5560] ath6kl: simplify btcoex parameter programming Make the code more legible by parsing the config options on the header file. While a it ensure to propagate errors and bail out if we fail to set btcoex params. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 80 ++++++++++--------- .../ath6kl/os/linux/include/ar6000_drv.h | 19 +++++ 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 1798889657d3..f08f165f4d97 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2328,16 +2328,52 @@ u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) return(arEndpoint2Ac(ar, ep )); } +#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) +static int ath6kl_config_btcoex_params(struct ar6_softc *ar) +{ + int r; + WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; + WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; + + /* Configure the type of BT collocated with WLAN */ + memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); + sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV; + + r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd); + + if (r) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Unable to set collocated BT type\n")); + return r; + } + + /* Configure the type of BT collocated with WLAN */ + memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); + + sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA; + + r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd); + if (r) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("Unable to set fornt end antenna configuration\n")); + return r; + } + + return 0; +} +#else +static int ath6kl_config_btcoex_params(struct ar6_softc *ar) +{ + return 0; +} +#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ + /* * This function applies WLAN specific configuration defined in wlan_config.h */ int ar6000_target_config_wlan_params(struct ar6_softc *ar) { int status = 0; -#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; - WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; -#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ #ifdef CONFIG_HOST_TCMD_SUPPORT if (ar->arTargetMode != AR6000_WLAN_MODE) { @@ -2355,39 +2391,9 @@ int ar6000_target_config_wlan_params(struct ar6_softc *ar) status = A_ERROR; } -#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) - /* Configure the type of BT collocated with WLAN */ - memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); -#ifdef CONFIG_AR600x_BT_QCOM - sbcb_cmd.btcoexCoLocatedBTdev = 1; -#elif defined(CONFIG_AR600x_BT_CSR) - sbcb_cmd.btcoexCoLocatedBTdev = 2; -#elif defined(CONFIG_AR600x_BT_AR3001) - sbcb_cmd.btcoexCoLocatedBTdev = 3; -#else -#error Unsupported Bluetooth Type -#endif /* Collocated Bluetooth Type */ - - if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n")); - status = A_ERROR; - } - - /* Configure the type of BT collocated with WLAN */ - memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); -#ifdef CONFIG_AR600x_DUAL_ANTENNA - sbfa_cmd.btcoexFeAntType = 2; -#elif defined(CONFIG_AR600x_SINGLE_ANTENNA) - sbfa_cmd.btcoexFeAntType = 1; -#else -#error Unsupported Front-End Antenna Configuration -#endif /* AR600x Front-End Antenna Configuration */ - - if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n")); - status = A_ERROR; - } -#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ + status = ath6kl_config_btcoex_params(ar); + if (status) + return status; #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 764f8f184fe9..e47b07807e9c 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -228,6 +228,25 @@ typedef enum _AR6K_BIN_FILE { #define NOHIFSCATTERSUPPORT_DEFAULT 0 #endif /* ATH6K_CONFIG_HIF_VIRTUAL_SCATTER */ + +#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) + +#ifdef CONFIG_AR600x_BT_QCOM +#define ATH6KL_BT_DEV 1 +#elif defined(CONFIG_AR600x_BT_CSR) +#define ATH6KL_BT_DEV 2 +#else +#define ATH6KL_BT_DEV 3 +#endif + +#ifdef CONFIG_AR600x_DUAL_ANTENNA +#define ATH6KL_BT_ANTENNA 2 +#else +#define ATH6KL_BT_ANTENNA 1 +#endif + +#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ + #ifdef AR600x_BT_AR3001 #define AR3KHCIBAUD_DEFAULT 3000000 #define HCIUARTSCALE_DEFAULT 1 -- GitLab From 711908df76bedee2df653be057465168ed626742 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:21 -0700 Subject: [PATCH 0444/5560] ath6kl: propagate errors on module setup This propagates initial platform registration failures and also HIF initialization failures. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/hif/sdio/linux_sdio/src/hif.c | 32 ++++++++----------- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 12 ++++--- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 26 ++++++++------- .../ath6kl/os/linux/include/ar6xapi_linux.h | 2 +- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index e6d9cd802dee..001f99375445 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -125,31 +125,27 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, /* ------ Functions ------ */ int HIFInit(OSDRV_CALLBACKS *callbacks) { - int status; - AR_DEBUG_ASSERT(callbacks != NULL); + int r; + AR_DEBUG_ASSERT(callbacks != NULL); + + A_REGISTER_MODULE_DEBUG_INFO(hif); - A_REGISTER_MODULE_DEBUG_INFO(hif); + /* store the callback handlers */ + osdrvCallbacks = *callbacks; - /* store the callback handlers */ - osdrvCallbacks = *callbacks; + /* Register with bus driver core */ + registered = 1; - /* Register with bus driver core */ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n")); - registered = 1; #if defined(CONFIG_PM) - if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) { - ar6k_driver.drv.pm = &ar6k_device_pm_ops; - } + if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) + ar6k_driver.drv.pm = &ar6k_device_pm_ops; #endif /* CONFIG_PM */ - status = sdio_register_driver(&ar6k_driver); - AR_DEBUG_ASSERT(status==0); - if (status != 0) { - return A_ERROR; - } - - return 0; + r = sdio_register_driver(&ar6k_driver); + if (r < 0) + return r; + return 0; } static int diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index f08f165f4d97..5f73182911ed 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -603,7 +603,7 @@ static int __init ar6000_init_module(void) { static int probed = 0; - int status; + int r; OSDRV_CALLBACKS osdrvCallbacks; a_module_debug_support_init(); @@ -636,7 +636,9 @@ ar6000_init_module(void) osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev; #endif - ar6000_pm_init(); + r = ar6000_pm_init(); + if (r) + return r; #ifdef DEBUG /* Set the debug flags if specified at load time */ @@ -655,9 +657,9 @@ ar6000_init_module(void) memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD)); #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - status = HIFInit(&osdrvCallbacks); - if (status) - return -ENODEV; + r = HIFInit(&osdrvCallbacks); + if (r) + return r; return 0; } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 1004f245d795..be401aa6dfcb 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -660,24 +660,28 @@ ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) return status; } -void ar6000_pm_init() +int ar6000_pm_init() { - A_REGISTER_MODULE_DEBUG_INFO(pm); + int r; + A_REGISTER_MODULE_DEBUG_INFO(pm); + #ifdef CONFIG_PM - /* - * Register ar6000_pm_device into system. - * We should also add platform_device into the first item of array - * of devices[] in file arch/xxx/mach-xxx/board-xxxx.c - */ - if (platform_driver_register(&ar6000_pm_device)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: fail to register the power control driver.\n")); - } + /* + * Register ar6000_pm_device into system. + * We should also add platform_device into the first item of array + * of devices[] in file arch/xxx/mach-xxx/board-xxxx.c + */ + r = platform_driver_register(&ar6000_pm_device); + if (r < 0) + return -ENODEV; #endif /* CONFIG_PM */ + + return 0; } void ar6000_pm_exit() { #ifdef CONFIG_PM - platform_driver_unregister(&ar6000_pm_device); + platform_driver_unregister(&ar6000_pm_device); #endif /* CONFIG_PM */ } diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index dd6905c41b76..a8e8e36e60ad 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -178,7 +178,7 @@ int ar6000_power_change_ev(void *context, u32 config); void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); #endif -void ar6000_pm_init(void); +int ar6000_pm_init(void); void ar6000_pm_exit(void); #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -- GitLab From 0c804c5a573867b0a0eeed957508601fb0f29a7a Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:22 -0700 Subject: [PATCH 0445/5560] ath6kl: remove useless plat_setup_power() calls These map to do nothing. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 3 --- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 6 ------ drivers/staging/ath6kl/os/linux/include/wlan_config.h | 6 ------ 3 files changed, 15 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 5f73182911ed..056acae7b211 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2017,9 +2017,6 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) { /* only stop endpoint if we are not stop it in suspend_ev */ ar6000_stop_endpoint(dev, false, true); - } else { - /* clear up the platform power state before rmmod */ - plat_setup_power(1,0); } ar->arWlanState = WLAN_DISABLED; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index be401aa6dfcb..eeb38079d3cb 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -304,13 +304,11 @@ int ar6000_power_change_ev(void *context, u32 config) static int ar6000_pm_probe(struct platform_device *pdev) { - plat_setup_power(1,1); return 0; } static int ar6000_pm_remove(struct platform_device *pdev) { - plat_setup_power(0,1); return 0; } @@ -352,8 +350,6 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) break; } - plat_setup_power(1,0); - /* Change the state to ON */ ar->arWlanPowerState = WLAN_POWER_STATE_ON; @@ -385,8 +381,6 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) &config, sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); - plat_setup_power(0,0); - ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR; } } while (0); diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h index 98951bbe05a5..c1fe0c6e4fa1 100644 --- a/drivers/staging/ath6kl/os/linux/include/wlan_config.h +++ b/drivers/staging/ath6kl/os/linux/include/wlan_config.h @@ -105,10 +105,4 @@ */ #define WLAN_CONFIG_DISABLE_TX_BURSTING 0 -/* - * Platform specific function to power ON/OFF AR6000 - * and enable/disable SDIO card detection - */ -#define plat_setup_power(on, detect) - #endif /* _HOST_WLAN_CONFIG_H_ */ -- GitLab From 4f56a12dd58ca2025b22ac4caabb89c90e1f1b7b Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:23 -0700 Subject: [PATCH 0446/5560] ath6kl: propagate errors on hifEnableFunc() failures This will be passed along to the SDIO probe routine when it fails. This will generate better error code to the user when loading the module if it fails. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 001f99375445..1752b33f8d90 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -1012,7 +1012,7 @@ static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret)); sdio_release_host(func); - return A_ERROR; + return ret; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n")); } @@ -1023,14 +1023,14 @@ static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", __FUNCTION__, ret)); sdio_release_host(func); - return A_ERROR; + return ret; } ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); sdio_release_host(func); if (ret) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); - return A_ERROR; + return ret; } device->is_disabled = false; /* create async I/O thread */ @@ -1041,7 +1041,7 @@ static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) "AR6K Async"); if (IS_ERR(device->async_task)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); - return A_ERROR; + return -ENOMEM; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); wake_up_process(device->async_task ); @@ -1056,14 +1056,14 @@ static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) } else { taskFunc = enable_task; taskName = "AR6K enable"; - ret = A_PENDING; + ret = -ENOMEM; #endif /* CONFIG_PM */ } /* create resume thread */ pTask = kthread_create(taskFunc, (void *)device, taskName); if (IS_ERR(pTask)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__)); - return A_ERROR; + return -ENOMEM; } wake_up_process(pTask); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n")); -- GitLab From 09b6b5e916afa32a4a4a4c9d7cb3ed00563d6b0e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:24 -0700 Subject: [PATCH 0447/5560] ath6kl: cleanup allocation and getting of the hif dev Removes verbose debug messages and checks that are just not needed, and renames the functions to something more sensible. While we clean this up, just move the routines above and remove the forward declarations. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/hif/sdio/linux_sdio/src/hif.c | 65 ++++++++----------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 1752b33f8d90..c862a199a73b 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -58,8 +58,6 @@ static int hifDeviceResume(struct device *dev); #endif /* CONFIG_PM */ static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id); static void hifDeviceRemoved(struct sdio_func *func); -static struct hif_device *addHifDevice(struct sdio_func *func); -static struct hif_device *getHifDevice(struct sdio_func *func); static void delHifDevice(struct hif_device * device); static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte); @@ -69,6 +67,26 @@ module_param(reset_sdio_on_unload, int, 0644); extern u32 nohifscattersupport; +static struct hif_device *ath6kl_alloc_hifdev(struct sdio_func *func) +{ + struct hif_device *hifdevice; + + hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL); + +#if HIF_USE_DMA_BOUNCE_BUFFER + hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); +#endif + hifdevice->func = func; + hifdevice->powerConfig = HIF_DEVICE_POWER_UP; + sdio_set_drvdata(func, hifdevice); + + return hifdevice; +} + +static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func) +{ + return (struct hif_device *) sdio_get_drvdata(func); +} /* ------ Static Variables ------ */ static const struct sdio_device_id ar6k_id_table[] = { @@ -774,7 +792,7 @@ hifIRQHandler(struct sdio_func *func) struct hif_device *device; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n")); - device = getHifDevice(func); + device = ath6kl_get_hifdev(func); atomic_set(&device->irqHandling, 1); /* release the host during ints so we can pick it back up when we process cmds */ sdio_release_host(device->func); @@ -829,8 +847,8 @@ static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n", func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize)); - addHifDevice(func); - device = getHifDevice(func); + ath6kl_alloc_hifdev(func); + device = ath6kl_get_hifdev(func); device->id = id; device->is_disabled = true; @@ -951,7 +969,7 @@ static int hifDisableFunc(struct hif_device *device, struct sdio_func *func) int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n")); - device = getHifDevice(func); + device = ath6kl_get_hifdev(func); if (!IS_ERR(device->async_task)) { init_completion(&device->async_completion); device->async_shutdown = 1; @@ -1000,7 +1018,7 @@ static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) int ret = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n")); - device = getHifDevice(func); + device = ath6kl_get_hifdev(func); if (device->is_disabled) { /* enable the SDIO function */ @@ -1079,7 +1097,7 @@ static int hifDeviceSuspend(struct device *dev) int status = 0; struct hif_device *device; - device = getHifDevice(func); + device = ath6kl_get_hifdev(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { device->is_suspend = true; /* set true first for PowerStateChangeNotify(..) */ @@ -1107,7 +1125,7 @@ static int hifDeviceResume(struct device *dev) int status = 0; struct hif_device *device; - device = getHifDevice(func); + device = ath6kl_get_hifdev(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks.deviceResumeHandler(device->claimedContext); @@ -1128,7 +1146,7 @@ static void hifDeviceRemoved(struct sdio_func *func) AR_DEBUG_ASSERT(func != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); - device = getHifDevice(func); + device = ath6kl_get_hifdev(func); if (device->claimedContext != NULL) { status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); } @@ -1178,33 +1196,6 @@ int hifWaitForPendingRecv(struct hif_device *device) return 0; } - -static struct hif_device * -addHifDevice(struct sdio_func *func) -{ - struct hif_device *hifdevice; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n")); - AR_DEBUG_ASSERT(func != NULL); - hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL); - AR_DEBUG_ASSERT(hifdevice != NULL); -#if HIF_USE_DMA_BOUNCE_BUFFER - hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); - AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL); -#endif - hifdevice->func = func; - hifdevice->powerConfig = HIF_DEVICE_POWER_UP; - sdio_set_drvdata(func, hifdevice); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice)); - return hifdevice; -} - -static struct hif_device * -getHifDevice(struct sdio_func *func) -{ - AR_DEBUG_ASSERT(func != NULL); - return (struct hif_device *)sdio_get_drvdata(func); -} - static void delHifDevice(struct hif_device * device) { -- GitLab From 60a9bc57804bd6a629ff1016fea43766f3f6eaf3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:25 -0700 Subject: [PATCH 0448/5560] ath6kl: style cleanup on struct sdio_driver components No functional changes except renames of the routines and id data structure. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/hif/sdio/linux_sdio/src/hif.c | 172 +++++++++--------- 1 file changed, 85 insertions(+), 87 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index c862a199a73b..9420c40f2993 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -56,12 +56,14 @@ static int hifDeviceSuspend(struct device *dev); static int hifDeviceResume(struct device *dev); #endif /* CONFIG_PM */ -static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id); -static void hifDeviceRemoved(struct sdio_func *func); static void delHifDevice(struct hif_device * device); static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte); +static int hifEnableFunc(struct hif_device *device, struct sdio_func *func); +static int hifDisableFunc(struct hif_device *device, struct sdio_func *func); +OSDRV_CALLBACKS osdrvCallbacks; + int reset_sdio_on_unload = 0; module_param(reset_sdio_on_unload, int, 0644); @@ -88,21 +90,86 @@ static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func) return (struct hif_device *) sdio_get_drvdata(func); } -/* ------ Static Variables ------ */ -static const struct sdio_device_id ar6k_id_table[] = { - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) }, - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) }, - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) }, - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) }, - { /* null */ }, +static const struct sdio_device_id ath6kl_hifdev_ids[] = { + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) }, + { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) }, + { /* null */ }, }; -MODULE_DEVICE_TABLE(sdio, ar6k_id_table); -static struct sdio_driver ar6k_driver = { - .name = "ar6k_wlan", - .id_table = ar6k_id_table, - .probe = hifDeviceInserted, - .remove = hifDeviceRemoved, +MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids); + +static int ath6kl_hifdev_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int ret; + struct hif_device *device; + int count; + + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, + ("ath6kl: Function: 0x%X, Vendor ID: 0x%X, " + "Device ID: 0x%X, block size: 0x%X/0x%X\n", + func->num, func->vendor, func->device, + func->max_blksize, func->cur_blksize)); + + ath6kl_alloc_hifdev(func); + device = ath6kl_get_hifdev(func); + + device->id = id; + device->is_disabled = true; + + spin_lock_init(&device->lock); + spin_lock_init(&device->asynclock); + + DL_LIST_INIT(&device->ScatterReqHead); + + /* Try to allow scatter unless globally overridden */ + if (!nohifscattersupport) + device->scatter_enabled = true; + + A_MEMZERO(device->busRequest, sizeof(device->busRequest)); + + for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) { + sema_init(&device->busRequest[count].sem_req, 0); + hifFreeBusRequest(device, &device->busRequest[count]); + } + + sema_init(&device->sem_async, 0); + + ret = hifEnableFunc(device, func); + + return ret; +} + +static void ath6kl_hifdev_remove(struct sdio_func *func) +{ + int status = 0; + struct hif_device *device; + AR_DEBUG_ASSERT(func != NULL); + + device = ath6kl_get_hifdev(func); + if (device->claimedContext != NULL) + status = osdrvCallbacks. + deviceRemovedHandler(device->claimedContext, device); + + if (device->is_disabled) + device->is_disabled = false; + else + status = hifDisableFunc(device, func); + + CleanupHIFScatterResources(device); + + delHifDevice(device); + AR_DEBUG_ASSERT(status == 0); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); +} + +static struct sdio_driver ath6kl_hifdev_driver = { + .name = "ath6kl_hifdev", + .id_table = ath6kl_hifdev_ids, + .probe = ath6kl_hifdev_probe, + .remove = ath6kl_hifdev_remove, }; #if defined(CONFIG_PM) @@ -119,14 +186,11 @@ static struct dev_pm_ops ar6k_device_pm_ops = { /* make sure we only unregister when registered. */ static int registered = 0; -OSDRV_CALLBACKS osdrvCallbacks; extern u32 onebitmode; extern u32 busspeedlow; extern u32 debughif; static void ResetAllCards(void); -static int hifDisableFunc(struct hif_device *device, struct sdio_func *func); -static int hifEnableFunc(struct hif_device *device, struct sdio_func *func); #ifdef DEBUG @@ -156,10 +220,10 @@ int HIFInit(OSDRV_CALLBACKS *callbacks) #if defined(CONFIG_PM) if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) - ar6k_driver.drv.pm = &ar6k_device_pm_ops; + ath6kl_hifdev_driver.drv.pm = &ar6k_device_pm_ops; #endif /* CONFIG_PM */ - r = sdio_register_driver(&ar6k_driver); + r = sdio_register_driver(&ath6kl_hifdev_driver); if (r < 0) return r; @@ -777,7 +841,7 @@ HIFShutDownDevice(struct hif_device *device) registered = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Unregistering with the bus driver\n")); - sdio_unregister_driver(&ar6k_driver); + sdio_unregister_driver(&ath6kl_hifdev_driver); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Unregistered\n")); } @@ -837,48 +901,6 @@ static int enable_task(void *param) } #endif -static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id) -{ - int ret; - struct hif_device * device; - int count; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n", - func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize)); - - ath6kl_alloc_hifdev(func); - device = ath6kl_get_hifdev(func); - - device->id = id; - device->is_disabled = true; - - spin_lock_init(&device->lock); - - spin_lock_init(&device->asynclock); - - DL_LIST_INIT(&device->ScatterReqHead); - - if (!nohifscattersupport) { - /* try to allow scatter operation on all instances, - * unless globally overridden */ - device->scatter_enabled = true; - } - - /* Initialize the bus requests to be used later */ - A_MEMZERO(device->busRequest, sizeof(device->busRequest)); - for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { - sema_init(&device->busRequest[count].sem_req, 0); - hifFreeBusRequest(device, &device->busRequest[count]); - } - sema_init(&device->sem_async, 0); - - ret = hifEnableFunc(device, func); - - return ret; -} - - void HIFAckInterrupt(struct hif_device *device) { @@ -1139,30 +1161,6 @@ static int hifDeviceResume(struct device *dev) } #endif /* CONFIG_PM */ -static void hifDeviceRemoved(struct sdio_func *func) -{ - int status = 0; - struct hif_device *device; - AR_DEBUG_ASSERT(func != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); - device = ath6kl_get_hifdev(func); - if (device->claimedContext != NULL) { - status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device); - } - - if (device->is_disabled) { - device->is_disabled = false; - } else { - status = hifDisableFunc(device, func); - } - CleanupHIFScatterResources(device); - - delHifDevice(device); - AR_DEBUG_ASSERT(status == 0); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); -} - /* * This should be moved to AR6K HTC layer. */ -- GitLab From 2df44b8b9bd9c3d9dcc8d4532d02515dd8712b6e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:26 -0700 Subject: [PATCH 0449/5560] ath6kl: remove completely pointles platform driver Perhaps there was some good intention on having some platform driver on ath6kl, but right now its pointless. Kill! Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 6 -- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 55 ------------------- .../ath6kl/os/linux/include/ar6xapi_linux.h | 3 - 3 files changed, 64 deletions(-) diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 056acae7b211..e3c1f5812b00 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -636,10 +636,6 @@ ar6000_init_module(void) osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev; #endif - r = ar6000_pm_init(); - if (r) - return r; - #ifdef DEBUG /* Set the debug flags if specified at load time */ if(debugflags != 0) @@ -689,8 +685,6 @@ ar6000_cleanup_module(void) a_module_debug_support_cleanup(); - ar6000_pm_exit(); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n")); } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index eeb38079d3cb..1e0ace8b6d13 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -302,35 +302,6 @@ int ar6000_power_change_ev(void *context, u32 config) return status; } -static int ar6000_pm_probe(struct platform_device *pdev) -{ - return 0; -} - -static int ar6000_pm_remove(struct platform_device *pdev) -{ - return 0; -} - -static int ar6000_pm_suspend(struct platform_device *pdev, pm_message_t state) -{ - return 0; -} - -static int ar6000_pm_resume(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver ar6000_pm_device = { - .probe = ar6000_pm_probe, - .remove = ar6000_pm_remove, - .suspend = ar6000_pm_suspend, - .resume = ar6000_pm_resume, - .driver = { - .name = "wlan_ar6000_pm", - }, -}; #endif /* CONFIG_PM */ int @@ -653,29 +624,3 @@ ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) status = ar6000_update_wlan_pwr_state(ar, state, false); return status; } - -int ar6000_pm_init() -{ - int r; - A_REGISTER_MODULE_DEBUG_INFO(pm); - -#ifdef CONFIG_PM - /* - * Register ar6000_pm_device into system. - * We should also add platform_device into the first item of array - * of devices[] in file arch/xxx/mach-xxx/board-xxxx.c - */ - r = platform_driver_register(&ar6000_pm_device); - if (r < 0) - return -ENODEV; -#endif /* CONFIG_PM */ - - return 0; -} - -void ar6000_pm_exit() -{ -#ifdef CONFIG_PM - platform_driver_unregister(&ar6000_pm_device); -#endif /* CONFIG_PM */ -} diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index a8e8e36e60ad..184dbdb50495 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -178,9 +178,6 @@ int ar6000_power_change_ev(void *context, u32 config); void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); #endif -int ar6000_pm_init(void); -void ar6000_pm_exit(void); - #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname); int ar6000_remove_ap_interface(struct ar6_softc *ar); -- GitLab From 0174d3c26448a132d01e6741fb80749dc81180b7 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:27 -0700 Subject: [PATCH 0450/5560] ath6kl: cleanup and move the ath6kl pm ops to be assigned statically There should be no need to assign the pm ops dynamically, so assign them statically and make them const. While we are doing this just do some simple code style cleanup on the routines and move them above prior to their assignment into the driver ops. This has no functional change other than assigning the pm ops statically. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/hif/sdio/linux_sdio/src/hif.c | 130 +++++++++--------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 9420c40f2993..359261ba3de1 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -53,8 +53,6 @@ #if defined(CONFIG_PM) #define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) #define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) -static int hifDeviceSuspend(struct device *dev); -static int hifDeviceResume(struct device *dev); #endif /* CONFIG_PM */ static void delHifDevice(struct hif_device * device); static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); @@ -165,23 +163,77 @@ static void ath6kl_hifdev_remove(struct sdio_func *func) AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); } +#if defined(CONFIG_PM) +static int hifDeviceSuspend(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + int status = 0; + struct hif_device *device; + + device = ath6kl_get_hifdev(func); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); + + if (device && device->claimedContext && + osdrvCallbacks.deviceSuspendHandler) { + /* set true first for PowerStateChangeNotify(..) */ + device->is_suspend = true; + status = osdrvCallbacks. + deviceSuspendHandler(device->claimedContext); + if (status) + device->is_suspend = false; + } + + CleanupHIFScatterResources(device); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); + + switch (status) { + case 0: + return 0; + case A_EBUSY: + /* Hack for kernel in order to support deep sleep and wow */ + return -EBUSY; + default: + return -1; + } +} + +static int hifDeviceResume(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + int status = 0; + struct hif_device *device; + + device = ath6kl_get_hifdev(func); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); + if (device && device->claimedContext && + osdrvCallbacks.deviceSuspendHandler) { + status = osdrvCallbacks. + deviceResumeHandler(device->claimedContext); + if (status == 0) + device->is_suspend = false; + } + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); + + return status; +} + +static const struct dev_pm_ops ar6k_device_pm_ops = { + .suspend = hifDeviceSuspend, + .resume = hifDeviceResume, +}; +#endif /* CONFIG_PM */ + static struct sdio_driver ath6kl_hifdev_driver = { .name = "ath6kl_hifdev", .id_table = ath6kl_hifdev_ids, .probe = ath6kl_hifdev_probe, .remove = ath6kl_hifdev_remove, -}; - #if defined(CONFIG_PM) -/* New suspend/resume based on linux-2.6.32 - * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch - * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host - */ -static struct dev_pm_ops ar6k_device_pm_ops = { - .suspend = hifDeviceSuspend, - .resume = hifDeviceResume, + .drv = { + .pm = &ar6k_device_pm_ops, + }, +#endif }; -#endif /* CONFIG_PM */ /* make sure we only unregister when registered. */ static int registered = 0; @@ -218,11 +270,6 @@ int HIFInit(OSDRV_CALLBACKS *callbacks) /* Register with bus driver core */ registered = 1; -#if defined(CONFIG_PM) - if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) - ath6kl_hifdev_driver.drv.pm = &ar6k_device_pm_ops; -#endif /* CONFIG_PM */ - r = sdio_register_driver(&ath6kl_hifdev_driver); if (r < 0) return r; @@ -1112,55 +1159,6 @@ static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) return ret; } -#if defined(CONFIG_PM) -static int hifDeviceSuspend(struct device *dev) -{ - struct sdio_func *func=dev_to_sdio_func(dev); - int status = 0; - struct hif_device *device; - - device = ath6kl_get_hifdev(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); - if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { - device->is_suspend = true; /* set true first for PowerStateChangeNotify(..) */ - status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); - if (status) { - device->is_suspend = false; - } - } - CleanupHIFScatterResources(device); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); - - switch (status) { - case 0: - return 0; - case A_EBUSY: - return -EBUSY; /* Hack for kernel in order to support deep sleep and wow */ - default: - return -1; - } -} - -static int hifDeviceResume(struct device *dev) -{ - struct sdio_func *func=dev_to_sdio_func(dev); - int status = 0; - struct hif_device *device; - - device = ath6kl_get_hifdev(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); - if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { - status = osdrvCallbacks.deviceResumeHandler(device->claimedContext); - if (status == 0) { - device->is_suspend = false; - } - } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); - - return status; -} -#endif /* CONFIG_PM */ - /* * This should be moved to AR6K HTC layer. */ -- GitLab From 437c567b1a02bdd50a9d0ce57c1310b827eb0ae4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:28 -0700 Subject: [PATCH 0451/5560] ath6kl: rename the pm ops to something more sensible This has no functional changes. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/hif/sdio/linux_sdio/src/hif.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 359261ba3de1..314c5525dbc2 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -164,14 +164,14 @@ static void ath6kl_hifdev_remove(struct sdio_func *func) } #if defined(CONFIG_PM) -static int hifDeviceSuspend(struct device *dev) +static int ath6kl_hifdev_suspend(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); int status = 0; struct hif_device *device; device = ath6kl_get_hifdev(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ath6kl_hifdev_suspend\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { @@ -184,7 +184,7 @@ static int hifDeviceSuspend(struct device *dev) } CleanupHIFScatterResources(device); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ath6kl_hifdev_suspend\n")); switch (status) { case 0: @@ -197,14 +197,14 @@ static int hifDeviceSuspend(struct device *dev) } } -static int hifDeviceResume(struct device *dev) +static int ath6kl_hifdev_resume(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); int status = 0; struct hif_device *device; device = ath6kl_get_hifdev(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ath6kl_hifdev_resume\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks. @@ -212,14 +212,14 @@ static int hifDeviceResume(struct device *dev) if (status == 0) device->is_suspend = false; } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ath6kl_hifdev_resume\n")); return status; } -static const struct dev_pm_ops ar6k_device_pm_ops = { - .suspend = hifDeviceSuspend, - .resume = hifDeviceResume, +static const struct dev_pm_ops ath6kl_hifdev_pmops = { + .suspend = ath6kl_hifdev_suspend, + .resume = ath6kl_hifdev_resume, }; #endif /* CONFIG_PM */ @@ -230,7 +230,7 @@ static struct sdio_driver ath6kl_hifdev_driver = { .remove = ath6kl_hifdev_remove, #if defined(CONFIG_PM) .drv = { - .pm = &ar6k_device_pm_ops, + .pm = &ath6kl_hifdev_pmops, }, #endif }; -- GitLab From 628a7dd85cff27db40a1759d883a76a6fef20346 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:29 -0700 Subject: [PATCH 0452/5560] ath6kl: remove chatty debug messages on ath6kl driver ops These do not help in any way. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 314c5525dbc2..c8f1a6ec37ad 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -144,7 +144,6 @@ static void ath6kl_hifdev_remove(struct sdio_func *func) { int status = 0; struct hif_device *device; - AR_DEBUG_ASSERT(func != NULL); device = ath6kl_get_hifdev(func); if (device->claimedContext != NULL) @@ -159,8 +158,6 @@ static void ath6kl_hifdev_remove(struct sdio_func *func) CleanupHIFScatterResources(device); delHifDevice(device); - AR_DEBUG_ASSERT(status == 0); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); } #if defined(CONFIG_PM) @@ -171,7 +168,6 @@ static int ath6kl_hifdev_suspend(struct device *dev) struct hif_device *device; device = ath6kl_get_hifdev(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ath6kl_hifdev_suspend\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { @@ -184,7 +180,6 @@ static int ath6kl_hifdev_suspend(struct device *dev) } CleanupHIFScatterResources(device); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ath6kl_hifdev_suspend\n")); switch (status) { case 0: @@ -204,7 +199,6 @@ static int ath6kl_hifdev_resume(struct device *dev) struct hif_device *device; device = ath6kl_get_hifdev(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ath6kl_hifdev_resume\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks. @@ -212,7 +206,6 @@ static int ath6kl_hifdev_resume(struct device *dev) if (status == 0) device->is_suspend = false; } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ath6kl_hifdev_resume\n")); return status; } -- GitLab From 427beeb21ad0b4297657d578003b2eb3803f95c9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 29 Mar 2011 17:56:30 -0700 Subject: [PATCH 0453/5560] ath6kl: remove ar6000_prepare_target() crap This was empty code, WTF^pi. Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common_drv.h | 4 --- drivers/staging/ath6kl/miscdrv/common_drv.c | 34 -------------------- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 8 ----- 3 files changed, 46 deletions(-) diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index b6063347229f..34db29958bcb 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -81,10 +81,6 @@ int ar6000_set_htc_params(struct hif_device *hifDevice, u32 MboxIsrYieldValue, u8 HtcControlBuffers); -int ar6000_prepare_target(struct hif_device *hifDevice, - u32 TargetType, - u32 TargetVersion); - int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice, u32 TargetType, u32 Flags); diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index a23a52412b3d..2be2ea494f53 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -683,40 +683,6 @@ int ar6000_set_htc_params(struct hif_device *hifDevice, return status; } - -static int prepare_ar6002(struct hif_device *hifDevice, u32 TargetVersion) -{ - int status = 0; - - /* placeholder */ - - return status; -} - -static int prepare_ar6003(struct hif_device *hifDevice, u32 TargetVersion) -{ - int status = 0; - - /* placeholder */ - - return status; -} - -/* this function assumes the caller has already initialized the BMI APIs */ -int ar6000_prepare_target(struct hif_device *hifDevice, - u32 TargetType, - u32 TargetVersion) -{ - if (TargetType == TARGET_TYPE_AR6002) { - /* do any preparations for AR6002 devices */ - return prepare_ar6002(hifDevice,TargetVersion); - } else if (TargetType == TARGET_TYPE_AR6003) { - return prepare_ar6003(hifDevice,TargetVersion); - } - - return 0; -} - #if defined(CONFIG_AR6002_REV1_FORCE_HOST) /* * Call this function just before the call to BMIInit diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index e3c1f5812b00..666d5e60b49c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1698,14 +1698,6 @@ ar6000_avail_ev(void *context, void *hif_handle) ar->arVersion.target_ver = targ_info.target_ver; ar->arTargetType = targ_info.target_type; - - /* do any target-specific preparation that can be done through BMI */ - r = ar6000_prepare_target(ar->arHifDevice, - targ_info.target_type, - targ_info.target_ver); - if (r) - goto avail_ev_failed; - } r = ar6000_configure_target(ar); -- GitLab From 550ac6ba4ef0e57f6edbadf2b018d5125d2f7e98 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:41 +1200 Subject: [PATCH 0454/5560] ALSA: snd-asihpi: Control naming Clock source is neither capture nor playback, so change 'Capture Clock' to 'Clock'. Add spaces to control name string for consistency, always 'PCM 0' , never 'PCM0' Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index f53a31e939c1..edcbe39d6033 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -1413,14 +1413,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, struct hpi_control *hpi_ctl, char *name) { - char *dir = ""; + char *dir; memset(snd_control, 0, sizeof(*snd_control)); snd_control->name = hpi_ctl->name; snd_control->private_value = hpi_ctl->h_control; snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; snd_control->index = 0; - if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) + if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE) + dir = ""; /* clock is neither capture nor playback */ + else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) dir = "Capture "; /* On or towards a PCM capture destination*/ else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && (!hpi_ctl->dst_node_type)) @@ -1433,7 +1435,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, dir = "Playback "; /* PCM Playback source, or output node */ if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) - sprintf(hpi_ctl->name, "%s%d %s%d %s%s", + sprintf(hpi_ctl->name, "%s %d %s %d %s%s", asihpi_src_names[hpi_ctl->src_node_type], hpi_ctl->src_node_index, asihpi_dst_names[hpi_ctl->dst_node_type], -- GitLab From a6477134db119a22aa30911ff18e440b8db9df65 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:42 +1200 Subject: [PATCH 0455/5560] ALSA: asihpi: Update debug printing Debug print full substream ID. Other minor debug print updates. Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 102 +++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index edcbe39d6033..434342f874ff 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -57,8 +57,25 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); */ #define snd_printddd(format, args...) \ __snd_printk(3, __FILE__, __LINE__, format, ##args) + +/* copied from pcm_lib.c, hope later patch will make that version public +and this copy can be removed */ +static void pcm_debug_name(struct snd_pcm_substream *substream, + char *name, size_t len) +{ + snprintf(name, len, "pcmC%dD%d%c:%d", + substream->pcm->card->number, + substream->pcm->device, + substream->stream ? 'c' : 'p', + substream->number); +} +#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name)) + #else -#define snd_printddd(format, args...) do { } while (0) +#define snd_printddd(format, args...) do { } while (0) +#define pcm_debug_name(s, n, l) do { } while (0) +#define DEBUG_NAME(name, substream) do { } while (0) + #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ @@ -101,13 +118,6 @@ static int adapter_fs = DEFAULT_SAMPLERATE; #define PERIOD_BYTES_MIN 2048 #define BUFFER_BYTES_MAX (512 * 1024) -/* convert stream to character */ -#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C') - -/*#define TIMER_MILLISECONDS 20 -#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000) -*/ - #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) struct clk_source { @@ -288,19 +298,26 @@ static u16 handle_error(u16 err, int line, char *filename) #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) /***************************** GENERAL PCM ****************/ -static void print_hwparams(struct snd_pcm_hw_params *p) + +static void print_hwparams(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *p) { - snd_printd("HWPARAMS \n"); - snd_printd("samplerate %d \n", params_rate(p)); - snd_printd("Channels %d \n", params_channels(p)); - snd_printd("Format %d \n", params_format(p)); - snd_printd("subformat %d \n", params_subformat(p)); - snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); - snd_printd("Period bytes %d \n", params_period_bytes(p)); - snd_printd("access %d \n", params_access(p)); - snd_printd("period_size %d \n", params_period_size(p)); - snd_printd("periods %d \n", params_periods(p)); - snd_printd("buffer_size %d \n", params_buffer_size(p)); + DEBUG_NAME(substream, name); + snd_printd("%s HWPARAMS\n", name); + snd_printd(" samplerate %d Hz\n", params_rate(p)); + snd_printd(" channels %d\n", params_channels(p)); + snd_printd(" format %d\n", params_format(p)); + snd_printd(" subformat %d\n", params_subformat(p)); + snd_printd(" buffer %d B\n", params_buffer_bytes(p)); + snd_printd(" period %d B\n", params_period_bytes(p)); + snd_printd(" access %d\n", params_access(p)); + snd_printd(" period_size %d\n", params_period_size(p)); + snd_printd(" periods %d\n", params_periods(p)); + snd_printd(" buffer_size %d\n", params_buffer_size(p)); + snd_printd(" %d B/s\n", params_rate(p) * + params_channels(p) * + snd_pcm_format_width(params_format(p)) / 8); + } static snd_pcm_format_t hpi_to_alsa_formats[] = { @@ -451,7 +468,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, int width; unsigned int bytes_per_sec; - print_hwparams(params); + print_hwparams(substream, params); err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); if (err < 0) return err; @@ -459,10 +476,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, if (err) return err; - snd_printdd("format %d, %d chans, %d_hz\n", - format, params_channels(params), - params_rate(params)); - hpi_handle_error(hpi_format_create(&dpcm->format, params_channels(params), format, params_rate(params), 0, 0)); @@ -509,8 +522,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, dpcm->bytes_per_sec = bytes_per_sec; dpcm->buffer_bytes = params_buffer_bytes(params); dpcm->period_bytes = params_period_bytes(params); - snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n", - dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); return 0; } @@ -564,9 +575,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); struct snd_pcm_substream *s; u16 e; + DEBUG_NAME(substream, name); + + snd_printdd("%s trigger\n", name); - snd_printdd("%c%d trigger\n", - SCHR(substream->stream), substream->number); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_pcm_group_for_each_entry(s, substream) { @@ -599,9 +611,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } if (card->support_grouping) { - snd_printdd("\t%c%d group\n", - SCHR(s->stream), - s->number); + snd_printdd("%d group\n", s->number); e = hpi_stream_group_add( dpcm->h_stream, ds->h_stream); @@ -636,9 +646,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, s->runtime->status->state = SNDRV_PCM_STATE_SETUP; if (card->support_grouping) { - snd_printdd("\t%c%d group\n", - SCHR(s->stream), - s->number); + snd_printdd("%d group\n", s->number); snd_pcm_trigger_done(s, substream); } else break; @@ -732,9 +740,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) int loops = 0; u16 state; u32 buffer_size, bytes_avail, samples_played, on_card_bytes; + DEBUG_NAME(substream, name); - snd_printdd("%c%d snd_card_asihpi_timer_function\n", - SCHR(substream->stream), substream->number); + snd_printdd("%s snd_card_asihpi_timer_function\n", name); /* find minimum newdata and buffer pos in group */ snd_pcm_group_for_each_entry(s, substream) { @@ -786,16 +794,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); } - snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", + snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n", (unsigned long)frames_to_bytes(runtime, runtime->status->hw_ptr), (unsigned long)frames_to_bytes(runtime, runtime->control->appl_ptr)); - snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," - " aux=x%04X space=x%04X\n", - loops, SCHR(s->stream), s->number, - state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, + snd_printdd("%d S=%d, " + "rw=0x%04X, dma=0x%04X, left=0x%04X, " + "aux=0x%04X space=0x%04X\n", + s->number, state, + ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, + (int)bytes_avail, (int)on_card_bytes, buffer_size-bytes_avail); loops++; } @@ -814,7 +824,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) next_jiffies = max(next_jiffies, 1U); dpcm->timer.expires = jiffies + next_jiffies; - snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", + snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n", next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); snd_pcm_group_for_each_entry(s, substream) { @@ -863,7 +873,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { - snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); + snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd); return snd_pcm_lib_ioctl(substream, cmd, arg); } @@ -873,7 +883,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - snd_printdd("playback prepare %d\n", substream->number); + snd_printdd("P%d prepare\n", substream->number); hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); dpcm->pcm_buf_host_rw_ofs = 0; @@ -890,7 +900,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t ptr; ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); - snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); + snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr); return ptr; } -- GitLab From 0b7ce9e2bd2d9dbc8f4797b0cd5e0d138cb529e1 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:43 +1200 Subject: [PATCH 0456/5560] ALSA: asihpi: Handle playback drained status better Use the card drained status reporting for playback, but allow it to persist for a few timer cycles before signalling XRUN, to allow card to recover by itself. Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 434342f874ff..a5226e3af3d7 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -165,6 +165,7 @@ struct snd_card_asihpi_pcm { unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ + unsigned int drained_count; struct snd_pcm_substream *substream; u32 h_stream; struct hpi_format format; @@ -592,6 +593,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, if (substream->stream != s->stream) continue; + ds->drained_count = 0; if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && (card->support_mmap)) { /* How do I know how much valid data is present @@ -771,12 +773,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { hpi_handle_error(hpi_stream_start(ds->h_stream)); snd_printdd("P%d start\n", s->number); + ds->drained_count = 0; } } else if (state == HPI_STATE_DRAINED) { snd_printd(KERN_WARNING "P%d drained\n", s->number); - /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); - continue; */ + ds->drained_count++; + if (ds->drained_count > 2) { + snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); + continue; + } + } else { + ds->drained_count = 0; } } else pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; -- GitLab From f3d145aac913b318e96e5c2763d8908805a5e30a Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:44 +1200 Subject: [PATCH 0457/5560] ALSA: asihpi: MMAP for non-busmaster cards Allow older non DMA capable cards to use MMAP by emulating the DMA using read and write functions, and getting rid of copy & silence callbacks that were used only by older cards. Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 205 +++++++++++++------------------------- 1 file changed, 70 insertions(+), 135 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index a5226e3af3d7..d5258aa738a1 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -42,6 +42,7 @@ #include #include + MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. "); MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); @@ -146,7 +147,7 @@ struct snd_card_asihpi { u32 h_mixer; struct clk_cache cc; - u16 support_mmap; + u16 can_dma; u16 support_grouping; u16 support_mrx; u16 update_interval_frames; @@ -491,8 +492,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, } dpcm->hpi_buffer_attached = 0; - if (card->support_mmap) { - + if (card->can_dma) { err = hpi_stream_host_buffer_attach(dpcm->h_stream, params_buffer_bytes(params), runtime->dma_addr); if (err == 0) { @@ -594,8 +594,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, continue; ds->drained_count = 0; - if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && - (card->support_mmap)) { + if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* How do I know how much valid data is present * in buffer? Must be at least one period! * Guessing 2 periods, but if @@ -630,7 +629,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, /* start the master stream */ snd_card_asihpi_pcm_timer_start(substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || - !card->support_mmap) + !card->can_dma) hpi_handle_error(hpi_stream_start(dpcm->h_stream)); break; @@ -766,6 +765,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) /* number of bytes in on-card buffer */ runtime->delay = on_card_bytes; + if (!card->can_dma) + on_card_bytes = bytes_avail; + if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; if (state == HPI_STATE_STOPPED) { @@ -844,30 +846,63 @@ static void snd_card_asihpi_timer_function(unsigned long data) ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; - if (xfercount && (on_card_bytes <= ds->period_bytes)) { - if (card->support_mmap) { - if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_printddd("P%d write x%04x\n", + if (xfercount && + /* Limit use of on card fifo for playback */ + ((on_card_bytes <= ds->period_bytes) || + (s->stream == SNDRV_PCM_STREAM_CAPTURE))) + + { + + unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes; + unsigned int xfer1, xfer2; + char *pd = &s->runtime->dma_area[buf_ofs]; + + if (card->can_dma) { + xfer1 = xfercount; + xfer2 = 0; + } else { + xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs); + xfer2 = xfercount - xfer1; + } + + if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { + snd_printddd("P%d write1 0x%04X 0x%04X\n", + s->number, xfer1, buf_ofs); + hpi_handle_error( + hpi_outstream_write_buf( + ds->h_stream, pd, xfer1, + &ds->format)); + + if (xfer2) { + pd = s->runtime->dma_area; + + snd_printddd("P%d write2 0x%04X 0x%04X\n", s->number, - ds->period_bytes); + xfercount - xfer1, buf_ofs); hpi_handle_error( hpi_outstream_write_buf( - ds->h_stream, - &s->runtime-> - dma_area[0], - xfercount, + ds->h_stream, pd, + xfercount - xfer1, &ds->format)); - } else { - snd_printddd("C%d read x%04x\n", - s->number, - xfercount); + } + } else { + snd_printddd("C%d read1 0x%04x\n", + s->number, xfer1); + hpi_handle_error( + hpi_instream_read_buf( + ds->h_stream, + pd, xfer1)); + if (xfer2) { + pd = s->runtime->dma_area; + snd_printddd("C%d read2 0x%04x\n", + s->number, xfer2); hpi_handle_error( hpi_instream_read_buf( ds->h_stream, - NULL, xfercount)); + pd, xfer2)); } - ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; - } /* else R/W will be handled by read/write callbacks */ + } + ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; snd_pcm_period_elapsed(s); } @@ -1004,11 +1039,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) SNDRV_PCM_INFO_DOUBLE | SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE; - - if (card->support_mmap) - snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID; + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID; if (card->support_grouping) snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; @@ -1016,7 +1049,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) /* struct is copied, so can create initializer dynamically */ runtime->hw = snd_card_asihpi_playback; - if (card->support_mmap) + if (card->can_dma) err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); if (err < 0) @@ -1046,58 +1079,6 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) return 0; } -static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, - int channel, - snd_pcm_uframes_t pos, - void __user *src, - snd_pcm_uframes_t count) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - unsigned int len; - - len = frames_to_bytes(runtime, count); - - if (copy_from_user(runtime->dma_area, src, len)) - return -EFAULT; - - snd_printddd("playback copy%d %u bytes\n", - substream->number, len); - - hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, - runtime->dma_area, len, &dpcm->format)); - - dpcm->pcm_buf_host_rw_ofs += len; - - return 0; -} - -static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * - substream, int channel, - snd_pcm_uframes_t pos, - snd_pcm_uframes_t count) -{ - /* Usually writes silence to DMA buffer, which should be overwritten - by real audio later. Our fifos cannot be overwritten, and are not - free-running DMAs. Silence is output on fifo underflow. - This callback is still required to allow the copy callback to be used. - */ - return 0; -} - -static struct snd_pcm_ops snd_card_asihpi_playback_ops = { - .open = snd_card_asihpi_playback_open, - .close = snd_card_asihpi_playback_close, - .ioctl = snd_card_asihpi_playback_ioctl, - .hw_params = snd_card_asihpi_pcm_hw_params, - .hw_free = snd_card_asihpi_hw_free, - .prepare = snd_card_asihpi_playback_prepare, - .trigger = snd_card_asihpi_trigger, - .pointer = snd_card_asihpi_playback_pointer, - .copy = snd_card_asihpi_playback_copy, - .silence = snd_card_asihpi_playback_silence, -}; - static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { .open = snd_card_asihpi_playback_open, .close = snd_card_asihpi_playback_close, @@ -1229,18 +1210,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) snd_card_asihpi_capture_format(card, dpcm->h_stream, &snd_card_asihpi_capture); snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); - snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; - - if (card->support_mmap) - snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID; + snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID; if (card->support_grouping) snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; runtime->hw = snd_card_asihpi_capture; - if (card->support_mmap) + if (card->can_dma) err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); if (err < 0) @@ -1264,28 +1243,6 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream) return 0; } -static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t pos, - void __user *dst, snd_pcm_uframes_t count) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - u32 len; - - len = frames_to_bytes(runtime, count); - - snd_printddd("capture copy%d %d bytes\n", substream->number, len); - hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, - runtime->dma_area, len)); - - dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; - - if (copy_to_user(dst, runtime->dma_area, len)) - return -EFAULT; - - return 0; -} - static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { .open = snd_card_asihpi_capture_open, .close = snd_card_asihpi_capture_close, @@ -1297,18 +1254,6 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { .pointer = snd_card_asihpi_capture_pointer, }; -static struct snd_pcm_ops snd_card_asihpi_capture_ops = { - .open = snd_card_asihpi_capture_open, - .close = snd_card_asihpi_capture_close, - .ioctl = snd_card_asihpi_capture_ioctl, - .hw_params = snd_card_asihpi_pcm_hw_params, - .hw_free = snd_card_asihpi_hw_free, - .prepare = snd_card_asihpi_capture_prepare, - .trigger = snd_card_asihpi_trigger, - .pointer = snd_card_asihpi_capture_pointer, - .copy = snd_card_asihpi_capture_copy -}; - static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, int device, int substreams) { @@ -1321,17 +1266,10 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, if (err < 0) return err; /* pointer to ops struct is stored, dont change ops afterwards! */ - if (asihpi->support_mmap) { snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_asihpi_playback_mmap_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_asihpi_capture_mmap_ops); - } else { - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_card_asihpi_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_card_asihpi_capture_ops); - } pcm->private_data = asihpi; pcm->info_flags = 0; @@ -2895,14 +2833,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, if (err) asihpi->update_interval_frames = 512; - if (!asihpi->support_mmap) + if (!asihpi->can_dma) asihpi->update_interval_frames *= 2; hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 0, &h_stream)); err = hpi_instream_host_buffer_free(h_stream); - asihpi->support_mmap = (!err); + asihpi->can_dma = (!err); hpi_handle_error(hpi_instream_close(h_stream)); @@ -2914,8 +2852,8 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->out_max_chans = 2; } - snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", - asihpi->support_mmap, + snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n", + asihpi->can_dma, asihpi->support_grouping, asihpi->support_mrx ); @@ -2945,10 +2883,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, by enable_hwdep module param*/ snd_asihpi_hpi_new(asihpi, 0, NULL); - if (asihpi->support_mmap) - strcpy(card->driver, "ASIHPI-MMAP"); - else - strcpy(card->driver, "ASIHPI"); + strcpy(card->driver, "ASIHPI"); sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); sprintf(card->longname, "%s %i", -- GitLab From 6027dfa46ea477b1223d83e74a3b3dcc572285b5 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:45 +1200 Subject: [PATCH 0458/5560] ALSA: asihpi: Remove 2 unused functions Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpifunc.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index c38fc9487560..7397b169b89f 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c @@ -105,33 +105,6 @@ u16 hpi_subsys_get_version_ex(u32 *pversion_ex) return hr.error; } -u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, - u16 *pw_adapter_index) -{ - struct hpi_message hm; - struct hpi_response hr; - - hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, - HPI_SUBSYS_CREATE_ADAPTER); - hm.u.s.resource = *p_resource; - - hpi_send_recv(&hm, &hr); - - *pw_adapter_index = hr.u.s.adapter_index; - return hr.error; -} - -u16 hpi_subsys_delete_adapter(u16 adapter_index) -{ - struct hpi_message hm; - struct hpi_response hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, - HPI_SUBSYS_DELETE_ADAPTER); - hm.obj_index = adapter_index; - hpi_send_recv(&hm, &hr); - return hr.error; -} - u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) { struct hpi_message hm; -- GitLab From b0096a65677fa8d7e50975dc7282ce313610d9e8 Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:46 +1200 Subject: [PATCH 0459/5560] ALSA: asihpi: Standardise substream name generation Define and use pcm_debug_name if CONFIG_SND_DEBUG Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/asihpi.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index d5258aa738a1..eac7b08a161d 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -47,18 +47,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. "); MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); -#if defined CONFIG_SND_DEBUG_VERBOSE -/** - * snd_printddd - very verbose debug printk - * @format: format string - * - * Works like snd_printk() for debugging purposes. - * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. - * Must set snd module debug parameter to 3 to enable at runtime. - */ -#define snd_printddd(format, args...) \ - __snd_printk(3, __FILE__, __LINE__, format, ##args) - +#if defined CONFIG_SND_DEBUG /* copied from pcm_lib.c, hope later patch will make that version public and this copy can be removed */ static void pcm_debug_name(struct snd_pcm_substream *substream, @@ -71,12 +60,24 @@ static void pcm_debug_name(struct snd_pcm_substream *substream, substream->number); } #define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name)) - #else -#define snd_printddd(format, args...) do { } while (0) #define pcm_debug_name(s, n, l) do { } while (0) #define DEBUG_NAME(name, substream) do { } while (0) +#endif +#if defined CONFIG_SND_DEBUG_VERBOSE +/** + * snd_printddd - very verbose debug printk + * @format: format string + * + * Works like snd_printk() for debugging purposes. + * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. + * Must set snd module debug parameter to 3 to enable at runtime. + */ +#define snd_printddd(format, args...) \ + __snd_printk(3, __FILE__, __LINE__, format, ##args) +#else +#define snd_printddd(format, args...) do { } while (0) #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ @@ -857,7 +858,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) unsigned int xfer1, xfer2; char *pd = &s->runtime->dma_area[buf_ofs]; - if (card->can_dma) { + if (card->can_dma) { /* buffer wrap is handled at lower level */ xfer1 = xfercount; xfer2 = 0; } else { -- GitLab From 6d0b898e9c402d6b7d0d07adacdbee2ebedafdcd Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:47 +1200 Subject: [PATCH 0460/5560] ALSA: asihpi: Simplify driver unload cleanup Replacing subsys_delete_adapter with adapter_delete allows some special-case adapter lookup code to be removed. Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpi6000.c | 39 +++++-------- sound/pci/asihpi/hpi6205.c | 97 +++++++++++++++++---------------- sound/pci/asihpi/hpi_internal.h | 17 +++--- sound/pci/asihpi/hpicmn.c | 1 - sound/pci/asihpi/hpimsgx.c | 31 +++++------ sound/pci/asihpi/hpioctl.c | 54 +++++++++--------- 6 files changed, 113 insertions(+), 126 deletions(-) diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 3e3c2ef6efd8..09befdafe09f 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c @@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, static void subsys_create_adapter(struct hpi_message *phm, struct hpi_response *phr); -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr); +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr); static void adapter_get_asserts(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr); @@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) case HPI_SUBSYS_CREATE_ADAPTER: subsys_create_adapter(phm, phr); break; - case HPI_SUBSYS_DELETE_ADAPTER: - subsys_delete_adapter(phm, phr); - break; default: phr->error = HPI_ERROR_INVALID_FUNC; break; @@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, adapter_get_asserts(pao, phm, phr); break; + case HPI_ADAPTER_DELETE: + adapter_delete(pao, phm, phr); + break; + default: hw_message(pao, phm, phr); break; @@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) { struct hpi_adapter_obj *pao = NULL; - /* subsytem messages get executed by every HPI. */ - /* All other messages are ignored unless the adapter index matches */ - /* an adapter in the HPI */ - /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */ - - /* if Dsp has crashed then do not communicate with it any more */ if (phm->object != HPI_OBJ_SUBSYSTEM) { pao = hpi_find_adapter(phm->adapter_index); if (!pao) { - HPI_DEBUG_LOG(DEBUG, - " %d,%d refused, for another HPI?\n", - phm->object, phm->function); + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_BAD_ADAPTER_NUMBER); + HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n", + phm->adapter_index); return; } + /* Don't even try to communicate with crashed DSP */ if (pao->dsp_crashed >= 10) { hpi_init_response(phr, phm->object, phm->function, HPI_ERROR_DSP_HARDWARE); - HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", - phm->object, phm->function); + HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n", + phm->adapter_index); return; } } @@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm, phr->error = 0; } -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr) +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_adapter_obj *pao = NULL; - - pao = hpi_find_adapter(phm->obj_index); - if (!pao) - return; - delete_adapter_obj(pao); hpi_delete_adapter(pao); phr->error = 0; diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 620525bdac59..53037342cd29 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, static void subsys_create_adapter(struct hpi_message *phm, struct hpi_response *phr); -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr); +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr); static u16 create_adapter_obj(struct hpi_adapter_obj *pao, u32 *pos_error_code); @@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index); /*****************************************************************************/ -static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) +static void subsys_message(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { switch (phm->function) { case HPI_SUBSYS_CREATE_ADAPTER: subsys_create_adapter(phm, phr); break; - case HPI_SUBSYS_DELETE_ADAPTER: - subsys_delete_adapter(phm, phr); - break; default: phr->error = HPI_ERROR_INVALID_FUNC; break; @@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr) { switch (phm->function) { + case HPI_ADAPTER_DELETE: + adapter_delete(pao, phm, phr); + break; + default: hw_message(pao, phm, phr); break; @@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao, /** Entry point to this HPI backend * All calls to the HPI start here */ -void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) +void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, + struct hpi_response *phr) { - struct hpi_adapter_obj *pao = NULL; - - /* subsytem messages are processed by every HPI. - * All other messages are ignored unless the adapter index matches - * an adapter in the HPI - */ - /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, - phm->wFunction); */ - - /* if Dsp has crashed then do not communicate with it any more */ - if (phm->object != HPI_OBJ_SUBSYSTEM) { - pao = hpi_find_adapter(phm->adapter_index); - if (!pao) { - HPI_DEBUG_LOG(DEBUG, - " %d,%d refused, for another HPI?\n", - phm->object, phm->function); - return; - } - - if ((pao->dsp_crashed >= 10) - && (phm->function != HPI_ADAPTER_DEBUG_READ)) { - /* allow last resort debug read even after crash */ - hpi_init_response(phr, phm->object, phm->function, - HPI_ERROR_DSP_HARDWARE); - HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", - phm->object, phm->function); - return; - } + if (pao && (pao->dsp_crashed >= 10) + && (phm->function != HPI_ADAPTER_DEBUG_READ)) { + /* allow last resort debug read even after crash */ + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_DSP_HARDWARE); + HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object, + phm->function); + return; } /* Init default response */ @@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) case HPI_TYPE_MESSAGE: switch (phm->object) { case HPI_OBJ_SUBSYSTEM: - subsys_message(phm, phr); + subsys_message(pao, phm, phr); break; case HPI_OBJ_ADAPTER: @@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) } } +void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) +{ + struct hpi_adapter_obj *pao = NULL; + + if (phm->object != HPI_OBJ_SUBSYSTEM) { + /* normal messages must have valid adapter index */ + pao = hpi_find_adapter(phm->adapter_index); + } else { + /* subsys messages don't address an adapter */ + _HPI_6205(NULL, phm, phr); + return; + } + + if (pao) + _HPI_6205(pao, phm, phr); + else + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_BAD_ADAPTER_NUMBER); +} + /*****************************************************************************/ /* SUBSYSTEM */ @@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm, } /** delete an adapter - required by WDM driver */ -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr) +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_adapter_obj *pao; struct hpi_hw_obj *phw; - pao = hpi_find_adapter(phm->obj_index); if (!pao) { phr->error = HPI_ERROR_INVALID_OBJ_INDEX; return; @@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, } err = adapter_boot_load_dsp(pao, pos_error_code); - if (err) + if (err) { + HPI_DEBUG_LOG(ERROR, "DSP code load failed\n"); /* no need to clean up as SubSysCreateAdapter */ /* calls DeleteAdapter on error. */ return err; - + } HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); /* allow boot load even if mem alloc wont work */ @@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, control_cache.number_of_controls, interface->control_cache.size_in_bytes, p_control_cache_virtual); + if (!phw->p_cache) err = HPI_ERROR_MEMORY_ALLOC; } @@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, } /** Free memory areas allocated by adapter - * this routine is called from SubSysDeleteAdapter, + * this routine is called from AdapterDelete, * and SubSysCreateAdapter if duplicate index */ static void delete_adapter_obj(struct hpi_adapter_obj *pao) { - struct hpi_hw_obj *phw; + struct hpi_hw_obj *phw = pao->priv; int i; - phw = pao->priv; - if (hpios_locked_mem_valid(&phw->h_control_cache)) { hpios_locked_mem_free(&phw->h_control_cache); hpi_free_control_cache(phw->p_cache); @@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, case HPI_ADAPTER_FAMILY_ASI(0x6300): boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); break; + case HPI_ADAPTER_FAMILY_ASI(0x5500): case HPI_ADAPTER_FAMILY_ASI(0x5600): case HPI_ADAPTER_FAMILY_ASI(0x6500): boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); @@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us) static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) { struct bus_master_interface *interface = phw->p_interface_buffer; - u32 r; interface->host_cmd = cmd; @@ -2088,7 +2089,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, phr->specific_error = sizeof(interface->u); phr->size = sizeof(struct hpi_response_header); HPI_DEBUG_LOG(ERROR, - "message len %d too big for buffer %zd \n", phm->size, + "message len %d too big for buffer %ld \n", phm->size, sizeof(interface->u)); return 0; } diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index af678be0aa15..d829a65f47d0 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES { /* These defines are used to fill in protocol information for an Ethernet packet sent using HMI on CS18102 */ -/** ID supplied by Cirrius for ASI packets. */ +/** ID supplied by Cirrus for ASI packets. */ #define HPI_ETHERNET_PACKET_ID 0x85 /** Simple packet - no special routing required */ #define HPI_ETHERNET_PACKET_V1 0x01 @@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES { /** This packet must make its way to the host across the HPI interface */ #define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 -#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ +#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */ /** Default network timeout in milli-seconds. */ #define HPI_ETHERNET_TIMEOUT_MS 500 @@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS { HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), - HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), + /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */ HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), - HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), + /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */ HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), - HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), - HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), + /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */ + /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */ HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), @@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS { HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), -#define HPI_ADAPTER_FUNCTION_COUNT 20 + HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21), +#define HPI_ADAPTER_FUNCTION_COUNT 21 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), @@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr); u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, u16 *pw_adapter_index); -u16 hpi_subsys_delete_adapter(u16 adapter_index); - u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, struct hpi_hostbuffer_status **pp_status); diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 3e9c5c289764..0428f285725d 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -667,7 +667,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) phr->u.s.num_adapters = adapters.gw_num_adapters; break; case HPI_SUBSYS_CREATE_ADAPTER: - case HPI_SUBSYS_DELETE_ADAPTER: break; default: phr->error = HPI_ERROR_INVALID_FUNC; diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index bcbdf30a6aa0..888e37966c3f 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c @@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, HPIMSGX__init(phm, phr); break; - case HPI_SUBSYS_DELETE_ADAPTER: - HPIMSGX__cleanup(phm->obj_index, h_owner); - { - struct hpi_message hm; - struct hpi_response hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, - HPI_ADAPTER_CLOSE); - hm.adapter_index = phm->obj_index; - hw_entry_point(&hm, &hr); - } - if ((phm->obj_index < HPI_MAX_ADAPTERS) - && hpi_entry_points[phm->obj_index]) { - hpi_entry_points[phm->obj_index] (phm, phr); - hpi_entry_points[phm->obj_index] = NULL; - } else - phr->error = HPI_ERROR_INVALID_OBJ_INDEX; - - break; default: /* Must explicitly handle every subsys message in this switch */ hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, @@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr, case HPI_ADAPTER_CLOSE: adapter_close(phm, phr); break; + case HPI_ADAPTER_DELETE: + HPIMSGX__cleanup(phm->adapter_index, h_owner); + { + struct hpi_message hm; + struct hpi_response hr; + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_CLOSE); + hm.adapter_index = phm->adapter_index; + hw_entry_point(&hm, &hr); + } + hw_entry_point(phm, phr); + break; + default: hw_entry_point(phm, phr); break; diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index cd624f13ff8e..484f41189867 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions #include "hpidebug.h" #include "hpimsgx.h" #include "hpioctl.h" +#include "hpicmn.h" #include #include @@ -161,26 +162,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) goto out; } - pa = &adapters[hm->h.adapter_index]; + switch (hm->h.function) { + case HPI_SUBSYS_CREATE_ADAPTER: + case HPI_ADAPTER_DELETE: + /* Application must not use these functions! */ + hr->h.size = sizeof(hr->h); + hr->h.error = HPI_ERROR_INVALID_OPERATION; + hr->h.function = hm->h.function; + uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); + if (uncopied_bytes) + err = -EFAULT; + else + err = 0; + goto out; + } + hr->h.size = res_max_size; if (hm->h.object == HPI_OBJ_SUBSYSTEM) { - switch (hm->h.function) { - case HPI_SUBSYS_CREATE_ADAPTER: - case HPI_SUBSYS_DELETE_ADAPTER: - /* Application must not use these functions! */ - hr->h.size = sizeof(hr->h); - hr->h.error = HPI_ERROR_INVALID_OPERATION; - hr->h.function = hm->h.function; - uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); - if (uncopied_bytes) - err = -EFAULT; - else - err = 0; - goto out; - - default: - hpi_send_recv_f(&hm->m0, &hr->r0, file); - } + hpi_send_recv_f(&hm->m0, &hr->r0, file); } else { u16 __user *ptr = NULL; u32 size = 0; @@ -188,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) /* -1=no data 0=read from user mem, 1=write to user mem */ int wrflag = -1; u32 adapter = hm->h.adapter_index; + pa = &adapters[adapter]; - if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { + if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) { hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER_NUMBER); @@ -395,17 +395,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, adapter.index = hr.u.s.adapter_index; adapter.type = hr.u.s.adapter_type; + + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_OPEN); hm.adapter_index = adapter.index; + hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); - err = hpi_adapter_open(adapter.index); - if (err) + if (hr.error) goto err; adapter.snd_card_asihpi = NULL; /* WARNING can't init mutex in 'adapter' * and then copy it to adapters[] ?!?! */ - adapters[hr.u.s.adapter_index] = adapter; + adapters[adapter.index] = adapter; mutex_init(&adapters[adapter.index].mutex); pci_set_drvdata(pci_dev, &adapters[adapter.index]); @@ -440,10 +443,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) struct hpi_adapter *pa; pa = pci_get_drvdata(pci_dev); - hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, - HPI_SUBSYS_DELETE_ADAPTER); - hm.obj_index = pa->index; - hm.adapter_index = HPI_ADAPTER_INDEX_INVALID; + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_DELETE); + hm.adapter_index = pa->index; hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); /* unmap PCI memory space, mapped during device init. */ -- GitLab From 42258daba22897f9859b0f3cb42700322b7c16bc Mon Sep 17 00:00:00 2001 From: Eliot Blennerhassett Date: Tue, 5 Apr 2011 20:55:48 +1200 Subject: [PATCH 0461/5560] ALSA: asihpi: Minor cleanups Remove some unneeded defintions Use %pR to print resources Make some data const Consistent braces for else Signed-off-by: Eliot Blennerhassett Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpi_internal.h | 2 -- sound/pci/asihpi/hpicmn.c | 9 +++++++-- sound/pci/asihpi/hpicmn.h | 2 ++ sound/pci/asihpi/hpioctl.c | 9 +++------ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index d829a65f47d0..4fab1595a6a2 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -1583,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR); /*////////////////////////////////////////////////////////////////////////// */ /* declarations for individual HPI entry points */ -hpi_handler_func HPI_1000; hpi_handler_func HPI_6000; hpi_handler_func HPI_6205; -hpi_handler_func HPI_COMMON; #endif /* _HPI_INTERNAL_H_ */ diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 0428f285725d..b15a02e91f82 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -227,8 +227,9 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) if (info->control_type) { pC->p_info[info->control_index] = info; cached++; - } else /* dummy cache entry */ + } else { /* dummy cache entry */ pC->p_info[info->control_index] = NULL; + } byte_count += info->size_in32bit_words * 4; @@ -298,7 +299,7 @@ struct pad_ofs_size { unsigned int field_size; }; -static struct pad_ofs_size pad_desc[] = { +static const struct pad_ofs_size pad_desc[] = { HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ @@ -617,6 +618,10 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, } } +/** Allocate control cache. + +\return Cache pointer, or NULL if allocation fails. +*/ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, const u32 size_in_bytes, u8 *p_dsp_control_buffer) { diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h index 590f0b69e655..d53cdf6e535f 100644 --- a/sound/pci/asihpi/hpicmn.h +++ b/sound/pci/asihpi/hpicmn.h @@ -60,3 +60,5 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC, struct hpi_message *phm, struct hpi_response *phr); u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); + +hpi_handler_func HPI_COMMON; diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 484f41189867..d8e7047512f8 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -317,7 +317,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { - int err, idx, nm; + int idx, nm; unsigned int memlen; struct hpi_message hm; struct hpi_response hr; @@ -351,11 +351,8 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, nm = HPI_MAX_ADAPTER_MEM_SPACES; for (idx = 0; idx < nm; idx++) { - HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", - idx, pci_dev->resource[idx].name, - (unsigned long long)pci_resource_start(pci_dev, idx), - (unsigned long long)pci_resource_end(pci_dev, idx), - (unsigned long long)pci_resource_flags(pci_dev, idx)); + HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx, + &pci_dev->resource[idx]); if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { memlen = pci_resource_len(pci_dev, idx); -- GitLab From f82d9a67fbcdfd8af6be7a7c9e381864ec9a271a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Apr 2011 13:36:09 +0100 Subject: [PATCH 0462/5560] sfc: Enable all TSO features on VLANs The TSO code already supports IPv6 on VLAN, so enable it. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index d890679e4c4d..542f32d21acf 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -2457,7 +2457,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, net_dev->features |= NETIF_F_TSO6; /* Mask for features that also apply to VLAN devices */ net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | - NETIF_F_HIGHDMA | NETIF_F_TSO); + NETIF_F_HIGHDMA | NETIF_F_ALL_TSO); efx = netdev_priv(net_dev); pci_set_drvdata(pci_dev, efx); SET_NETDEV_DEV(net_dev, &pci_dev->dev); -- GitLab From abfe903980161b11f3594e3dcbab8b5c5a67168b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Apr 2011 15:00:02 +0100 Subject: [PATCH 0463/5560] sfc: Implement generic features interface Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 20 +++++++-- drivers/net/sfc/ethtool.c | 78 ------------------------------------ drivers/net/sfc/net_driver.h | 2 - drivers/net/sfc/rx.c | 2 +- 4 files changed, 18 insertions(+), 84 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 542f32d21acf..db72a6e054e1 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1874,6 +1874,17 @@ static void efx_set_multicast_list(struct net_device *net_dev) /* Otherwise efx_start_port() will do this */ } +static int efx_set_features(struct net_device *net_dev, u32 data) +{ + struct efx_nic *efx = netdev_priv(net_dev); + + /* If disabling RX n-tuple filtering, clear existing filters */ + if (net_dev->features & ~data & NETIF_F_NTUPLE) + efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); + + return 0; +} + static const struct net_device_ops efx_netdev_ops = { .ndo_open = efx_net_open, .ndo_stop = efx_net_stop, @@ -1885,6 +1896,7 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_change_mtu = efx_change_mtu, .ndo_set_mac_address = efx_set_mac_address, .ndo_set_multicast_list = efx_set_multicast_list, + .ndo_set_features = efx_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, #endif @@ -2269,7 +2281,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); efx->net_dev = net_dev; - efx->rx_checksum_enabled = true; spin_lock_init(&efx->stats_lock); mutex_init(&efx->mac_lock); efx->mac_op = type->default_mac_ops; @@ -2452,12 +2463,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, return -ENOMEM; net_dev->features |= (type->offload_features | NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_TSO | - NETIF_F_GRO); + NETIF_F_RXCSUM); if (type->offload_features & NETIF_F_V6_CSUM) net_dev->features |= NETIF_F_TSO6; /* Mask for features that also apply to VLAN devices */ net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | - NETIF_F_HIGHDMA | NETIF_F_ALL_TSO); + NETIF_F_HIGHDMA | NETIF_F_ALL_TSO | + NETIF_F_RXCSUM); + /* All offloads can be toggled */ + net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA; efx = netdev_priv(net_dev); pci_set_drvdata(pci_dev, efx); SET_NETDEV_DEV(net_dev, &pci_dev->dev); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 807178ef65ad..0d5543972574 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -518,72 +518,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, } } -static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) -{ - struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev); - u32 features; - - features = NETIF_F_TSO; - if (efx->type->offload_features & NETIF_F_V6_CSUM) - features |= NETIF_F_TSO6; - - if (enable) - net_dev->features |= features; - else - net_dev->features &= ~features; - - return 0; -} - -static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) -{ - struct efx_nic *efx = netdev_priv(net_dev); - u32 features = efx->type->offload_features & NETIF_F_ALL_CSUM; - - if (enable) - net_dev->features |= features; - else - net_dev->features &= ~features; - - return 0; -} - -static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - /* No way to stop the hardware doing the checks; we just - * ignore the result. - */ - efx->rx_checksum_enabled = !!enable; - - return 0; -} - -static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - return efx->rx_checksum_enabled; -} - -static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) -{ - struct efx_nic *efx = netdev_priv(net_dev); - u32 supported = (efx->type->offload_features & - (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE)); - int rc; - - rc = ethtool_op_set_flags(net_dev, data, supported); - if (rc) - return rc; - - if (!(data & ETH_FLAG_NTUPLE)) - efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); - - return 0; -} - static void efx_ethtool_self_test(struct net_device *net_dev, struct ethtool_test *test, u64 *data) { @@ -1070,18 +1004,6 @@ const struct ethtool_ops efx_ethtool_ops = { .set_ringparam = efx_ethtool_set_ringparam, .get_pauseparam = efx_ethtool_get_pauseparam, .set_pauseparam = efx_ethtool_set_pauseparam, - .get_rx_csum = efx_ethtool_get_rx_csum, - .set_rx_csum = efx_ethtool_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - /* Need to enable/disable IPv6 too */ - .set_tx_csum = efx_ethtool_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - /* Need to enable/disable TSO-IPv6 too */ - .set_tso = efx_ethtool_set_tso, - .get_flags = ethtool_op_get_flags, - .set_flags = efx_ethtool_set_flags, .get_sset_count = efx_ethtool_get_sset_count, .self_test = efx_ethtool_self_test, .get_strings = efx_ethtool_get_strings, diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 215d5c51bfa0..f0f8ca535a4d 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -681,7 +681,6 @@ struct efx_filter_state; * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock - * @rx_checksum_enabled: RX checksumming enabled * @stats_buffer: DMA buffer for statistics * @mac_op: MAC interface * @phy_type: PHY type @@ -771,7 +770,6 @@ struct efx_nic { bool port_initialized; struct net_device *net_dev; - bool rx_checksum_enabled; struct efx_buffer stats_buffer; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index fb402c52aaff..b7dc891b4461 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -605,7 +605,7 @@ void __efx_rx_packet(struct efx_channel *channel, skb_record_rx_queue(skb, channel->channel); } - if (unlikely(!efx->rx_checksum_enabled)) + if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) checksummed = false; if (likely(checksummed || rx_buf->is_page)) { -- GitLab From e20b5b61a36bd5b80eea064c0f2e73285dbe0d3b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 1 Apr 2011 22:52:34 +0100 Subject: [PATCH 0464/5560] ethtool: Convert struct ethtool_ops comment to kernel-doc format Signed-off-by: Ben Hutchings --- include/linux/ethtool.h | 80 ++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c8fcbdd2b0e7..ab12f84c17bd 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -683,63 +683,53 @@ void ethtool_ntuple_flush(struct net_device *dev); bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** - * ðtool_ops - Alter and report network device settings - * get_settings: Get device-specific settings - * set_settings: Set device-specific settings - * get_drvinfo: Report driver information - * get_regs: Get device registers - * get_wol: Report whether Wake-on-Lan is enabled - * set_wol: Turn Wake-on-Lan on or off - * get_msglevel: Report driver message level - * set_msglevel: Set driver message level - * nway_reset: Restart autonegotiation - * get_link: Get link status - * get_eeprom: Read data from the device EEPROM - * set_eeprom: Write data to the device EEPROM - * get_coalesce: Get interrupt coalescing parameters - * set_coalesce: Set interrupt coalescing parameters - * get_ringparam: Report ring sizes - * set_ringparam: Set ring sizes - * get_pauseparam: Report pause parameters - * set_pauseparam: Set pause parameters - * get_rx_csum: Report whether receive checksums are turned on or off - * set_rx_csum: Turn receive checksum on or off - * get_tx_csum: Report whether transmit checksums are turned on or off - * set_tx_csum: Turn transmit checksums on or off - * get_sg: Report whether scatter-gather is enabled - * set_sg: Turn scatter-gather on or off - * get_tso: Report whether TCP segmentation offload is enabled - * set_tso: Turn TCP segmentation offload on or off - * get_ufo: Report whether UDP fragmentation offload is enabled - * set_ufo: Turn UDP fragmentation offload on or off - * self_test: Run specified self-tests - * get_strings: Return a set of strings that describe the requested objects - * phys_id: Identify the device - * get_stats: Return statistics about the device - * get_flags: get 32-bit flags bitmap - * set_flags: set 32-bit flags bitmap - * - * Description: - * - * get_settings: + * struct ethtool_ops - Alter and report network device settings + * @get_settings: Get device-specific settings. * @get_settings is passed an ðtool_cmd to fill in. It returns * an negative errno or zero. - * - * set_settings: + * @set_settings: Set device-specific settings. * @set_settings is passed an ðtool_cmd and should attempt to set * all the settings this device supports. It may return an error value * if something goes wrong (otherwise 0). - * - * get_eeprom: + * @get_drvinfo: Report driver information + * @get_regs: Get device registers + * @get_wol: Report whether Wake-on-Lan is enabled + * @set_wol: Turn Wake-on-Lan on or off + * @get_msglevel: Report driver message level + * @set_msglevel: Set driver message level + * @nway_reset: Restart autonegotiation + * @get_link: Get link status + * @get_eeprom: Read data from the device EEPROM. * Should fill in the magic field. Don't need to check len for zero * or wraparound. Fill in the data argument with the eeprom values * from offset to offset + len. Update len to the amount read. * Returns an error or zero. - * - * set_eeprom: + * @set_eeprom: Write data to the device EEPROM. * Should validate the magic field. Don't need to check len for zero * or wraparound. Update len to the amount written. Returns an error * or zero. + * @get_coalesce: Get interrupt coalescing parameters + * @set_coalesce: Set interrupt coalescing parameters + * @get_ringparam: Report ring sizes + * @set_ringparam: Set ring sizes + * @get_pauseparam: Report pause parameters + * @set_pauseparam: Set pause parameters + * @get_rx_csum: Report whether receive checksums are turned on or off + * @set_rx_csum: Turn receive checksum on or off + * @get_tx_csum: Report whether transmit checksums are turned on or off + * @set_tx_csum: Turn transmit checksums on or off + * @get_sg: Report whether scatter-gather is enabled + * @set_sg: Turn scatter-gather on or off + * @get_tso: Report whether TCP segmentation offload is enabled + * @set_tso: Turn TCP segmentation offload on or off + * @get_ufo: Report whether UDP fragmentation offload is enabled + * @set_ufo: Turn UDP fragmentation offload on or off + * @self_test: Run specified self-tests + * @get_strings: Return a set of strings that describe the requested objects + * @phys_id: Identify the device + * @get_stats: Return statistics about the device + * @get_flags: get 32-bit flags bitmap + * @set_flags: set 32-bit flags bitmap */ struct ethtool_ops { int (*get_settings)(struct net_device *, struct ethtool_cmd *); -- GitLab From 8717d07b1143e0f150921f5bd7cfe7af579a995a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 1 Apr 2011 23:57:41 +0100 Subject: [PATCH 0465/5560] ethtool: Fill out and update comment for struct ethtool_ops Briefly document all operations (except get_rx_ntuple), including whether they may return an error code and whether they are deprecated. Also mention some things that should be handled by the ethtool core rather than by drivers. Briefly document general requirements for callers. Signed-off-by: Ben Hutchings --- include/linux/ethtool.h | 124 ++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 31 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ab12f84c17bd..ead7dcb1bf1e 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -683,22 +683,28 @@ void ethtool_ntuple_flush(struct net_device *dev); bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** - * struct ethtool_ops - Alter and report network device settings - * @get_settings: Get device-specific settings. - * @get_settings is passed an ðtool_cmd to fill in. It returns - * an negative errno or zero. - * @set_settings: Set device-specific settings. - * @set_settings is passed an ðtool_cmd and should attempt to set - * all the settings this device supports. It may return an error value - * if something goes wrong (otherwise 0). - * @get_drvinfo: Report driver information + * struct ethtool_ops - optional netdev operations + * @get_settings: Get various device settings including Ethernet link + * settings. Returns a negative error code or zero. + * @set_settings: Set various device settings including Ethernet link + * settings. Returns a negative error code or zero. + * @get_drvinfo: Report driver/device information. Should only set the + * @driver, @version, @fw_version and @bus_info fields. If not + * implemented, the @driver and @bus_info fields will be filled in + * according to the netdev's parent device. + * @get_regs_len: Get buffer length required for @get_regs * @get_regs: Get device registers * @get_wol: Report whether Wake-on-Lan is enabled - * @set_wol: Turn Wake-on-Lan on or off - * @get_msglevel: Report driver message level + * @set_wol: Turn Wake-on-Lan on or off. Returns a negative error code + * or zero. + * @get_msglevel: Report driver message level. This should be the value + * of the @msg_enable field used by netif logging functions. * @set_msglevel: Set driver message level - * @nway_reset: Restart autonegotiation - * @get_link: Get link status + * @nway_reset: Restart autonegotiation. Returns a negative error code + * or zero. + * @get_link: Report whether physical link is up. Will only be called if + * the netdev is up. Should usually be set to ethtool_op_get_link(), + * which uses netif_carrier_ok(). * @get_eeprom: Read data from the device EEPROM. * Should fill in the magic field. Don't need to check len for zero * or wraparound. Fill in the data argument with the eeprom values @@ -708,28 +714,84 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * Should validate the magic field. Don't need to check len for zero * or wraparound. Update len to the amount written. Returns an error * or zero. - * @get_coalesce: Get interrupt coalescing parameters - * @set_coalesce: Set interrupt coalescing parameters + * @get_coalesce: Get interrupt coalescing parameters. Returns a negative + * error code or zero. + * @set_coalesce: Set interrupt coalescing parameters. Returns a negative + * error code or zero. * @get_ringparam: Report ring sizes - * @set_ringparam: Set ring sizes + * @set_ringparam: Set ring sizes. Returns a negative error code or zero. * @get_pauseparam: Report pause parameters - * @set_pauseparam: Set pause parameters - * @get_rx_csum: Report whether receive checksums are turned on or off - * @set_rx_csum: Turn receive checksum on or off - * @get_tx_csum: Report whether transmit checksums are turned on or off - * @set_tx_csum: Turn transmit checksums on or off - * @get_sg: Report whether scatter-gather is enabled - * @set_sg: Turn scatter-gather on or off - * @get_tso: Report whether TCP segmentation offload is enabled - * @set_tso: Turn TCP segmentation offload on or off - * @get_ufo: Report whether UDP fragmentation offload is enabled - * @set_ufo: Turn UDP fragmentation offload on or off + * @set_pauseparam: Set pause parameters. Returns a negative error code + * or zero. + * @get_rx_csum: Deprecated in favour of the netdev feature %NETIF_F_RXCSUM. + * Report whether receive checksums are turned on or off. + * @set_rx_csum: Deprecated in favour of generic netdev features. Turn + * receive checksum on or off. Returns a negative error code or zero. + * @get_tx_csum: Deprecated as redundant. Report whether transmit checksums + * are turned on or off. + * @set_tx_csum: Deprecated in favour of generic netdev features. Turn + * transmit checksums on or off. Returns a egative error code or zero. + * @get_sg: Deprecated as redundant. Report whether scatter-gather is + * enabled. + * @set_sg: Deprecated in favour of generic netdev features. Turn + * scatter-gather on or off. Returns a negative error code or zero. + * @get_tso: Deprecated as redundant. Report whether TCP segmentation + * offload is enabled. + * @set_tso: Deprecated in favour of generic netdev features. Turn TCP + * segmentation offload on or off. Returns a negative error code or zero. * @self_test: Run specified self-tests * @get_strings: Return a set of strings that describe the requested objects - * @phys_id: Identify the device - * @get_stats: Return statistics about the device - * @get_flags: get 32-bit flags bitmap - * @set_flags: set 32-bit flags bitmap + * @phys_id: Identify the physical device, e.g. by flashing an LED + * attached to it until interrupted by a signal or the given time + * (in seconds) elapses. If the given time is zero, use a default + * time limit. Returns a negative error code or zero. Being + * interrupted by a signal is not an error. + * @get_ethtool_stats: Return extended statistics about the device. + * This is only useful if the device maintains statistics not + * included in &struct rtnl_link_stats64. + * @begin: Function to be called before any other operation. Returns a + * negative error code or zero. + * @complete: Function to be called after any other operation except + * @begin. Will be called even if the other operation failed. + * @get_ufo: Deprecated as redundant. Report whether UDP fragmentation + * offload is enabled. + * @set_ufo: Deprecated in favour of generic netdev features. Turn UDP + * fragmentation offload on or off. Returns a negative error code or zero. + * @get_flags: Deprecated as redundant. Report features included in + * &enum ethtool_flags that are enabled. + * @set_flags: Deprecated in favour of generic netdev features. Turn + * features included in &enum ethtool_flags on or off. Returns a + * negative error code or zero. + * @get_priv_flags: Report driver-specific feature flags. + * @set_priv_flags: Set driver-specific feature flags. Returns a negative + * error code or zero. + * @get_sset_count: Get number of strings that @get_strings will write. + * @get_rxnfc: Get RX flow classification rules. Returns a negative + * error code or zero. + * @set_rxnfc: Set RX flow classification rules. Returns a negative + * error code or zero. + * @flash_device: Write a firmware image to device's flash memory. + * Returns a negative error code or zero. + * @reset: Reset (part of) the device, as specified by a bitmask of + * flags from &enum ethtool_reset_flags. Returns a negative + * error code or zero. + * @set_rx_ntuple: Set an RX n-tuple rule. Returns a negative error code + * or zero. + * @get_rx_ntuple: Deprecated. + * @get_rxfh_indir: Get the contents of the RX flow hash indirection table. + * Returns a negative error code or zero. + * @set_rxfh_indir: Set the contents of the RX flow hash indirection table. + * Returns a negative error code or zero. + * + * All operations are optional (i.e. the function pointer may be set + * to %NULL) and callers must take this into account. Callers must + * hold the RTNL, except that for @get_drvinfo the caller may or may + * not hold the RTNL. + * + * See the structures used by these operations for further documentation. + * + * See &struct net_device and &struct net_device_ops for documentation + * of the generic netdev features interface. */ struct ethtool_ops { int (*get_settings)(struct net_device *, struct ethtool_cmd *); -- GitLab From 68f512f21a64c9b264df6c61a9333e7890faf74b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 2 Apr 2011 00:35:15 +0100 Subject: [PATCH 0466/5560] ethtool: Change ETHTOOL_PHYS_ID implementation to allow dropping RTNL The ethtool ETHTOOL_PHYS_ID command runs for an arbitrarily long period of time, holding the RTNL lock. This blocks routing updates, device enumeration, and various important operations that one might want to keep running while hunting for the flashing LED. We need to drop the RTNL lock during this operation, but currently the core implementation is a thin wrapper around a driver operation and drivers may well depend upon holding the lock. Define a new driver operation 'set_phys_id' with an argument that sets the ID indicator on/off/inactive/active (the last optional, for any driver or firmware that prefers to handle blinking asynchronously). When this is defined, the ethtool core drops the lock while waiting and only acquires it around calls to this operation. Deprecate the 'phys_id' operation in favour of this. It can be removed once all in-tree drivers are converted. Signed-off-by: Ben Hutchings --- include/linux/ethtool.h | 30 +++++++++++++++++++++- net/core/ethtool.c | 55 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ead7dcb1bf1e..c04d1316d221 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -663,6 +663,22 @@ struct ethtool_rx_ntuple_list { unsigned int count; }; +/** + * enum ethtool_phys_id_state - indicator state for physical identification + * @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated + * @ETHTOOL_ID_ACTIVE: Physical ID indicator should be activated + * @ETHTOOL_ID_ON: LED should be turned on (used iff %ETHTOOL_ID_ACTIVE + * is not supported) + * @ETHTOOL_ID_OFF: LED should be turned off (used iff %ETHTOOL_ID_ACTIVE + * is not supported) + */ +enum ethtool_phys_id_state { + ETHTOOL_ID_INACTIVE, + ETHTOOL_ID_ACTIVE, + ETHTOOL_ID_ON, + ETHTOOL_ID_OFF +}; + struct net_device; /* Some generic methods drivers may use in their ethtool_ops */ @@ -741,7 +757,18 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * segmentation offload on or off. Returns a negative error code or zero. * @self_test: Run specified self-tests * @get_strings: Return a set of strings that describe the requested objects - * @phys_id: Identify the physical device, e.g. by flashing an LED + * @set_phys_id: Identify the physical devices, e.g. by flashing an LED + * attached to it. The implementation may update the indicator + * asynchronously or synchronously, but in either case it must return + * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE, + * and must either activate asynchronous updates or return -%EINVAL. + * If it returns -%EINVAL then it will be called again at intervals with + * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of + * the indicator accordingly. Finally, it is called with the argument + * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a + * negative error code or zero. + * @phys_id: Deprecated in favour of @set_phys_id. + * Identify the physical device, e.g. by flashing an LED * attached to it until interrupted by a signal or the given time * (in seconds) elapses. If the given time is zero, use a default * time limit. Returns a negative error code or zero. Being @@ -830,6 +857,7 @@ struct ethtool_ops { int (*set_tso)(struct net_device *, u32); void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); void (*get_strings)(struct net_device *, u32 stringset, u8 *); + int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); int (*phys_id)(struct net_device *, u32); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 74ead9eca126..1c95f0fb8b3a 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include /* * Some useful ethtool_ops methods that're device independent. @@ -1618,14 +1620,63 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) { struct ethtool_value id; + static bool busy; + int rc; - if (!dev->ethtool_ops->phys_id) + if (!dev->ethtool_ops->set_phys_id && !dev->ethtool_ops->phys_id) return -EOPNOTSUPP; + if (busy) + return -EBUSY; + if (copy_from_user(&id, useraddr, sizeof(id))) return -EFAULT; - return dev->ethtool_ops->phys_id(dev, id.data); + if (!dev->ethtool_ops->set_phys_id) + /* Do it the old way */ + return dev->ethtool_ops->phys_id(dev, id.data); + + rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE); + if (rc && rc != -EINVAL) + return rc; + + /* Drop the RTNL lock while waiting, but prevent reentry or + * removal of the device. + */ + busy = true; + dev_hold(dev); + rtnl_unlock(); + + if (rc == 0) { + /* Driver will handle this itself */ + schedule_timeout_interruptible( + id.data ? id.data : MAX_SCHEDULE_TIMEOUT); + } else { + /* Driver expects to be called periodically */ + do { + rtnl_lock(); + rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ON); + rtnl_unlock(); + if (rc) + break; + schedule_timeout_interruptible(HZ / 2); + + rtnl_lock(); + rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_OFF); + rtnl_unlock(); + if (rc) + break; + schedule_timeout_interruptible(HZ / 2); + } while (!signal_pending(current) && + (id.data == 0 || --id.data != 0)); + } + + rtnl_lock(); + dev_put(dev); + busy = false; + + (void)dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_INACTIVE); + return rc; } static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) -- GitLab From c5e129ac2fc72c119b85db79a629de66332f136d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 2 Apr 2011 00:43:46 +0100 Subject: [PATCH 0467/5560] sfc: Implement ethtool_ops::set_phys_id instead of ethtool_ops::phys_id Signed-off-by: Ben Hutchings --- drivers/net/sfc/ethtool.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 0d5543972574..644f7c1d6e7b 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -178,19 +178,27 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { */ /* Identify device by flashing LEDs */ -static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) +static int efx_ethtool_phys_id(struct net_device *net_dev, + enum ethtool_phys_id_state state) { struct efx_nic *efx = netdev_priv(net_dev); + enum efx_led_mode mode; - do { - efx->type->set_id_led(efx, EFX_LED_ON); - schedule_timeout_interruptible(HZ / 2); - - efx->type->set_id_led(efx, EFX_LED_OFF); - schedule_timeout_interruptible(HZ / 2); - } while (!signal_pending(current) && --count != 0); + switch (state) { + case ETHTOOL_ID_ON: + mode = EFX_LED_ON; + break; + case ETHTOOL_ID_OFF: + mode = EFX_LED_OFF; + break; + case ETHTOOL_ID_INACTIVE: + mode = EFX_LED_DEFAULT; + break; + default: + return -EINVAL; + } - efx->type->set_id_led(efx, EFX_LED_DEFAULT); + efx->type->set_id_led(efx, mode); return 0; } @@ -1007,7 +1015,7 @@ const struct ethtool_ops efx_ethtool_ops = { .get_sset_count = efx_ethtool_get_sset_count, .self_test = efx_ethtool_self_test, .get_strings = efx_ethtool_get_strings, - .phys_id = efx_ethtool_phys_id, + .set_phys_id = efx_ethtool_phys_id, .get_ethtool_stats = efx_ethtool_get_stats, .get_wol = efx_ethtool_get_wol, .set_wol = efx_ethtool_set_wol, -- GitLab From aabf6f897e44bdf3e237ada04aa8f88d77d75cac Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 5 Apr 2011 15:37:45 +0200 Subject: [PATCH 0468/5560] Bluetooth: Use kthread API in hidp kernel_thread() is a low-level implementation detail and EXPORT_SYMBOL(kernel_thread) is scheduled for removal. Use the API instead. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 53 ++++++++++++++++++--------------------- net/bluetooth/hidp/hidp.h | 2 +- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index a1472b75d628..ae6ebc6c3481 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -463,8 +464,7 @@ static void hidp_idle_timeout(unsigned long arg) { struct hidp_session *session = (struct hidp_session *) arg; - atomic_inc(&session->terminate); - hidp_schedule(session); + kthread_stop(session->task); } static void hidp_set_timer(struct hidp_session *session) @@ -535,9 +535,7 @@ static void hidp_process_hid_control(struct hidp_session *session, skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); - /* Kill session thread */ - atomic_inc(&session->terminate); - hidp_schedule(session); + kthread_stop(session->task); } } @@ -696,22 +694,10 @@ static int hidp_session(void *arg) struct sock *ctrl_sk = session->ctrl_sock->sk; struct sock *intr_sk = session->intr_sock->sk; struct sk_buff *skb; - int vendor = 0x0000, product = 0x0000; wait_queue_t ctrl_wait, intr_wait; BT_DBG("session %p", session); - if (session->input) { - vendor = session->input->id.vendor; - product = session->input->id.product; - } - - if (session->hid) { - vendor = session->hid->vendor; - product = session->hid->product; - } - - daemonize("khidpd_%04x%04x", vendor, product); set_user_nice(current, -15); init_waitqueue_entry(&ctrl_wait, current); @@ -720,7 +706,7 @@ static int hidp_session(void *arg) add_wait_queue(sk_sleep(intr_sk), &intr_wait); session->waiting_for_startup = 0; wake_up_interruptible(&session->startup_queue); - while (!atomic_read(&session->terminate)) { + while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); if (ctrl_sk->sk_state != BT_CONNECTED || @@ -968,6 +954,7 @@ static int hidp_setup_hid(struct hidp_session *session, int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) { struct hidp_session *session, *s; + int vendor, product; int err; BT_DBG(""); @@ -1029,9 +1016,24 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, hidp_set_timer(session); - err = kernel_thread(hidp_session, session, CLONE_KERNEL); - if (err < 0) + if (session->hid) { + vendor = session->hid->vendor; + product = session->hid->product; + } else if (session->input) { + vendor = session->input->id.vendor; + product = session->input->id.product; + } else { + vendor = 0x0000; + product = 0x0000; + } + + session->task = kthread_run(hidp_session, session, "khidpd_%04x%04x", + vendor, product); + if (IS_ERR(session->task)) { + err = PTR_ERR(session->task); goto unlink; + } + while (session->waiting_for_startup) { wait_event_interruptible(session->startup_queue, !session->waiting_for_startup); @@ -1056,8 +1058,7 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, err_add_device: hid_destroy_device(session->hid); session->hid = NULL; - atomic_inc(&session->terminate); - hidp_schedule(session); + kthread_stop(session->task); unlink: hidp_del_timer(session); @@ -1108,13 +1109,7 @@ int hidp_del_connection(struct hidp_conndel_req *req) skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); - /* Wakeup user-space polling for socket errors */ - session->intr_sock->sk->sk_err = EUNATCH; - session->ctrl_sock->sk->sk_err = EUNATCH; - - /* Kill session thread */ - atomic_inc(&session->terminate); - hidp_schedule(session); + kthread_stop(session->task); } } else err = -ENOENT; diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index b412e7152eec..12822cde4b49 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h @@ -142,7 +142,7 @@ struct hidp_session { uint ctrl_mtu; uint intr_mtu; - atomic_t terminate; + struct task_struct *task; unsigned char keys[8]; unsigned char leds; -- GitLab From f4d7cd4a4c25cb4a5c30a675d4cc0052c93b925a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:20:00 +0100 Subject: [PATCH 0469/5560] Bluetooth: Use kthread API in bnep kernel_thread() is a low-level implementation detail and EXPORT_SYMBOL(kernel_thread) is scheduled for removal. Use the API instead. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/bnep.h | 2 +- net/bluetooth/bnep/core.c | 21 ++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index d768e0434ed8..8e6c06158f8e 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h @@ -155,7 +155,7 @@ struct bnep_session { unsigned int role; unsigned long state; unsigned long flags; - atomic_t killed; + struct task_struct *task; struct ethhdr eh; struct msghdr msg; diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 0a2e76bde542..ca39fcf010ce 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -479,12 +480,11 @@ static int bnep_session(void *arg) BT_DBG(""); - daemonize("kbnepd %s", dev->name); set_user_nice(current, -15); init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); - while (!atomic_read(&s->killed)) { + while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); /* RX */ @@ -611,11 +611,12 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) __bnep_link_session(s); - err = kernel_thread(bnep_session, s, CLONE_KERNEL); - if (err < 0) { + s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name); + if (IS_ERR(s->task)) { /* Session thread start failed, gotta cleanup. */ unregister_netdev(dev); __bnep_unlink_session(s); + err = PTR_ERR(s->task); goto failed; } @@ -639,15 +640,9 @@ int bnep_del_connection(struct bnep_conndel_req *req) down_read(&bnep_session_sem); s = __bnep_get_session(req->dst); - if (s) { - /* Wakeup user-space which is polling for socket errors. - * This is temporary hack until we have shutdown in L2CAP */ - s->sock->sk->sk_err = EUNATCH; - - /* Kill session thread */ - atomic_inc(&s->killed); - wake_up_interruptible(sk_sleep(s->sock->sk)); - } else + if (s) + kthread_stop(s->task); + else err = -ENOENT; up_read(&bnep_session_sem); -- GitLab From fada4ac33992b1f953d95584e36f6ca7860aea40 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Mar 2011 14:20:06 +0100 Subject: [PATCH 0470/5560] Bluetooth: Use kthread API in cmtp kernel_thread() is a low-level implementation detail and EXPORT_SYMBOL(kernel_thread) is scheduled for removal. Use the API instead. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/capi.c | 6 +++--- net/bluetooth/cmtp/cmtp.h | 9 +-------- net/bluetooth/cmtp/core.c | 16 +++++++++------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 67cff810c77d..744233cba244 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -143,7 +144,7 @@ static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb) skb_queue_tail(&session->transmit, skb); - cmtp_schedule(session); + wake_up_interruptible(sk_sleep(session->sock->sk)); } static void cmtp_send_interopmsg(struct cmtp_session *session, @@ -386,8 +387,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) capi_ctr_down(ctrl); - atomic_inc(&session->terminate); - cmtp_schedule(session); + kthread_stop(session->task); } static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index c6f78f89415c..db43b54ac9af 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h @@ -81,7 +81,7 @@ struct cmtp_session { char name[BTNAMSIZ]; - atomic_t terminate; + struct task_struct *task; wait_queue_head_t wait; @@ -121,13 +121,6 @@ void cmtp_detach_device(struct cmtp_session *session); void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb); -static inline void cmtp_schedule(struct cmtp_session *session) -{ - struct sock *sk = session->sock->sk; - - wake_up_interruptible(sk_sleep(sk)); -} - /* CMTP init defines */ int cmtp_init_sockets(void); void cmtp_cleanup_sockets(void); diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 16aa6bd039ba..cce99b0919f5 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -287,12 +288,11 @@ static int cmtp_session(void *arg) BT_DBG("session %p", session); - daemonize("kcmtpd_ctr_%d", session->num); set_user_nice(current, -15); init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); - while (!atomic_read(&session->terminate)) { + while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); if (sk->sk_state != BT_CONNECTED) @@ -370,9 +370,12 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) __cmtp_link_session(session); - err = kernel_thread(cmtp_session, session, CLONE_KERNEL); - if (err < 0) + session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d", + session->num); + if (IS_ERR(session->task)) { + err = PTR_ERR(session->task); goto unlink; + } if (!(session->flags & (1 << CMTP_LOOPBACK))) { err = cmtp_attach_device(session); @@ -409,9 +412,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) /* Flush the transmit queue */ skb_queue_purge(&session->transmit); - /* Kill session thread */ - atomic_inc(&session->terminate); - cmtp_schedule(session); + /* Stop session thread */ + kthread_stop(session->task); } else err = -ENOENT; -- GitLab From 2a7ce0edd661b3144c7b916ecf1eba0967b6d4a5 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Mon, 4 Apr 2011 15:19:59 -0500 Subject: [PATCH 0471/5560] dlm: remove shared message stub for recovery kmalloc a stub message struct during recovery instead of sharing the struct in the lockspace. This leaves the lockspace stub_ms only for faking downconvert replies, where it is never modified and sharing is not a problem. Also improve the debug messages in the same recovery function. Signed-off-by: David Teigland --- fs/dlm/dlm_internal.h | 1 + fs/dlm/lock.c | 82 ++++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 6a92478fe1f1..0262451eb9c6 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -209,6 +209,7 @@ struct dlm_args { #define DLM_IFL_WATCH_TIMEWARN 0x00400000 #define DLM_IFL_TIMEOUT_CANCEL 0x00800000 #define DLM_IFL_DEADLOCK_CANCEL 0x01000000 +#define DLM_IFL_STUB_MS 0x02000000 /* magic number for m_flags */ #define DLM_IFL_USER 0x00000001 #define DLM_IFL_ORPHAN 0x00000002 diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index e3c864120371..81227799d47a 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1037,10 +1037,10 @@ static int remove_from_waiters_ms(struct dlm_lkb *lkb, struct dlm_message *ms) struct dlm_ls *ls = lkb->lkb_resource->res_ls; int error; - if (ms != &ls->ls_stub_ms) + if (ms->m_flags != DLM_IFL_STUB_MS) mutex_lock(&ls->ls_waiters_mutex); error = _remove_from_waiters(lkb, ms->m_type, ms); - if (ms != &ls->ls_stub_ms) + if (ms->m_flags != DLM_IFL_STUB_MS) mutex_unlock(&ls->ls_waiters_mutex); return error; } @@ -1462,14 +1462,8 @@ static void grant_lock_pending(struct dlm_rsb *r, struct dlm_lkb *lkb) ALTPR/ALTCW: our rqmode may have been changed to PR or CW to become compatible with other granted locks */ -static void munge_demoted(struct dlm_lkb *lkb, struct dlm_message *ms) +static void munge_demoted(struct dlm_lkb *lkb) { - if (ms->m_type != DLM_MSG_CONVERT_REPLY) { - log_print("munge_demoted %x invalid reply type %d", - lkb->lkb_id, ms->m_type); - return; - } - if (lkb->lkb_rqmode == DLM_LOCK_IV || lkb->lkb_grmode == DLM_LOCK_IV) { log_print("munge_demoted %x invalid modes gr %d rq %d", lkb->lkb_id, lkb->lkb_grmode, lkb->lkb_rqmode); @@ -2966,9 +2960,9 @@ static int send_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) /* down conversions go without a reply from the master */ if (!error && down_conversion(lkb)) { remove_from_waiters(lkb, DLM_MSG_CONVERT_REPLY); + r->res_ls->ls_stub_ms.m_flags = DLM_IFL_STUB_MS; r->res_ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; r->res_ls->ls_stub_ms.m_result = 0; - r->res_ls->ls_stub_ms.m_flags = lkb->lkb_flags; __receive_convert_reply(r, lkb, &r->res_ls->ls_stub_ms); } @@ -3156,6 +3150,9 @@ static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) static void receive_flags_reply(struct dlm_lkb *lkb, struct dlm_message *ms) { + if (ms->m_flags == DLM_IFL_STUB_MS) + return; + lkb->lkb_sbflags = ms->m_sbflags; lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | (ms->m_flags & 0x0000FFFF); @@ -3698,7 +3695,7 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, /* convert was queued on remote master */ receive_flags_reply(lkb, ms); if (is_demoted(lkb)) - munge_demoted(lkb, ms); + munge_demoted(lkb); del_lkb(r, lkb); add_lkb(r, lkb, DLM_LKSTS_CONVERT); add_timeout(lkb); @@ -3708,7 +3705,7 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, /* convert was granted on remote master */ receive_flags_reply(lkb, ms); if (is_demoted(lkb)) - munge_demoted(lkb, ms); + munge_demoted(lkb); grant_lock_pc(r, lkb, ms); queue_cast(r, lkb, 0); break; @@ -4082,15 +4079,17 @@ void dlm_receive_buffer(union dlm_packet *p, int nodeid) dlm_put_lockspace(ls); } -static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb) +static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb, + struct dlm_message *ms_stub) { if (middle_conversion(lkb)) { hold_lkb(lkb); - ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; - ls->ls_stub_ms.m_result = -EINPROGRESS; - ls->ls_stub_ms.m_flags = lkb->lkb_flags; - ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; - _receive_convert_reply(lkb, &ls->ls_stub_ms); + memset(ms_stub, 0, sizeof(struct dlm_message)); + ms_stub->m_flags = DLM_IFL_STUB_MS; + ms_stub->m_type = DLM_MSG_CONVERT_REPLY; + ms_stub->m_result = -EINPROGRESS; + ms_stub->m_header.h_nodeid = lkb->lkb_nodeid; + _receive_convert_reply(lkb, ms_stub); /* Same special case as in receive_rcom_lock_args() */ lkb->lkb_grmode = DLM_LOCK_IV; @@ -4131,13 +4130,27 @@ static int waiter_needs_recovery(struct dlm_ls *ls, struct dlm_lkb *lkb) void dlm_recover_waiters_pre(struct dlm_ls *ls) { struct dlm_lkb *lkb, *safe; + struct dlm_message *ms_stub; int wait_type, stub_unlock_result, stub_cancel_result; + ms_stub = kmalloc(GFP_KERNEL, sizeof(struct dlm_message)); + if (!ms_stub) { + log_error(ls, "dlm_recover_waiters_pre no mem"); + return; + } + mutex_lock(&ls->ls_waiters_mutex); list_for_each_entry_safe(lkb, safe, &ls->ls_waiters, lkb_wait_reply) { - log_debug(ls, "pre recover waiter lkid %x type %d flags %x", - lkb->lkb_id, lkb->lkb_wait_type, lkb->lkb_flags); + + /* exclude debug messages about unlocks because there can be so + many and they aren't very interesting */ + + if (lkb->lkb_wait_type != DLM_MSG_UNLOCK) { + log_debug(ls, "recover_waiter %x nodeid %d " + "msg %d to %d", lkb->lkb_id, lkb->lkb_nodeid, + lkb->lkb_wait_type, lkb->lkb_wait_nodeid); + } /* all outstanding lookups, regardless of destination will be resent after recovery is done */ @@ -4183,26 +4196,28 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) break; case DLM_MSG_CONVERT: - recover_convert_waiter(ls, lkb); + recover_convert_waiter(ls, lkb, ms_stub); break; case DLM_MSG_UNLOCK: hold_lkb(lkb); - ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY; - ls->ls_stub_ms.m_result = stub_unlock_result; - ls->ls_stub_ms.m_flags = lkb->lkb_flags; - ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; - _receive_unlock_reply(lkb, &ls->ls_stub_ms); + memset(ms_stub, 0, sizeof(struct dlm_message)); + ms_stub->m_flags = DLM_IFL_STUB_MS; + ms_stub->m_type = DLM_MSG_UNLOCK_REPLY; + ms_stub->m_result = stub_unlock_result; + ms_stub->m_header.h_nodeid = lkb->lkb_nodeid; + _receive_unlock_reply(lkb, ms_stub); dlm_put_lkb(lkb); break; case DLM_MSG_CANCEL: hold_lkb(lkb); - ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY; - ls->ls_stub_ms.m_result = stub_cancel_result; - ls->ls_stub_ms.m_flags = lkb->lkb_flags; - ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; - _receive_cancel_reply(lkb, &ls->ls_stub_ms); + memset(ms_stub, 0, sizeof(struct dlm_message)); + ms_stub->m_flags = DLM_IFL_STUB_MS; + ms_stub->m_type = DLM_MSG_CANCEL_REPLY; + ms_stub->m_result = stub_cancel_result; + ms_stub->m_header.h_nodeid = lkb->lkb_nodeid; + _receive_cancel_reply(lkb, ms_stub); dlm_put_lkb(lkb); break; @@ -4213,6 +4228,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) schedule(); } mutex_unlock(&ls->ls_waiters_mutex); + kfree(ms_stub); } static struct dlm_lkb *find_resend_waiter(struct dlm_ls *ls) @@ -4277,8 +4293,8 @@ int dlm_recover_waiters_post(struct dlm_ls *ls) ou = is_overlap_unlock(lkb); err = 0; - log_debug(ls, "recover_waiters_post %x type %d flags %x %s", - lkb->lkb_id, mstype, lkb->lkb_flags, r->res_name); + log_debug(ls, "recover_waiter %x nodeid %d msg %d r_nodeid %d", + lkb->lkb_id, lkb->lkb_nodeid, mstype, r->res_nodeid); /* At this point we assume that we won't get a reply to any previous op or overlap op on this lock. First, do a big -- GitLab From 1322901da5094cecd9826ec3aaade83f6452cc45 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 19:06:05 -0300 Subject: [PATCH 0472/5560] Bluetooth: Don't use spin_lock_bh in user context spin_lock() and spin_unlock() are more apropiated for user context. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 88 ++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 9a61320c5f2e..c32238163b72 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -179,7 +179,7 @@ static int read_controller_info(struct sock *sk, u16 index) hci_del_off_timer(hdev); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); set_bit(HCI_MGMT, &hdev->flags); @@ -208,7 +208,7 @@ static int read_controller_info(struct sock *sk, u16 index) memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name)); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp)); @@ -316,7 +316,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); up = test_bit(HCI_UP, &hdev->flags); if ((cp->val && up) || (!cp->val && !up)) { @@ -343,7 +343,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) err = 0; failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; } @@ -368,7 +368,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN); @@ -403,7 +403,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -429,7 +429,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN); @@ -463,7 +463,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -522,7 +522,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (cp->val) set_bit(HCI_PAIRABLE, &hdev->flags); @@ -538,7 +538,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -739,7 +739,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) if (!hdev) return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); if (!uuid) { @@ -763,7 +763,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -788,7 +788,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) if (!hdev) return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { err = hci_uuids_clear(hdev); @@ -823,7 +823,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); unlock: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -847,7 +847,7 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); hdev->major_class = cp->major; hdev->minor_class = cp->minor; @@ -857,7 +857,7 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data, if (err == 0) err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -879,7 +879,7 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); BT_DBG("hci%u enable %d", index, cp->enable); @@ -897,7 +897,7 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, 0); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -931,7 +931,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, key_count); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); hci_link_keys_clear(hdev); @@ -949,7 +949,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) key->pin_len); } - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return 0; @@ -971,7 +971,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) if (!hdev) return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); err = hci_remove_link_key(hdev, &cp->bdaddr); if (err < 0) { @@ -994,7 +994,7 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) } unlock: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1020,7 +1020,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) if (!hdev) return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN); @@ -1052,7 +1052,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1073,7 +1073,7 @@ static int get_connections(struct sock *sk, u16 index) if (!hdev) return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); count = 0; list_for_each(p, &hdev->conn_hash.list) { @@ -1104,7 +1104,7 @@ static int get_connections(struct sock *sk, u16 index) unlock: kfree(rp); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; } @@ -1129,7 +1129,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN); @@ -1151,7 +1151,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1178,7 +1178,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, @@ -1199,7 +1199,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1222,14 +1222,14 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); hdev->io_capability = cp->io_capability; BT_DBG("%s IO capability set to 0x%02x", hdev->name, hdev->io_capability); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0); @@ -1315,7 +1315,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) if (!hdev) return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (cp->io_cap == 0x03) { sec_level = BT_SECURITY_MEDIUM; @@ -1357,7 +1357,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) err = 0; unlock: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1389,7 +1389,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, mgmt_op, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, mgmt_op, ENETDOWN); @@ -1407,7 +1407,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1431,7 +1431,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); if (!cmd) { @@ -1446,7 +1446,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, mgmt_pending_remove(cmd); failed: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1465,7 +1465,7 @@ static int read_local_oob_data(struct sock *sk, u16 index) return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, @@ -1495,7 +1495,7 @@ static int read_local_oob_data(struct sock *sk, u16 index) mgmt_pending_remove(cmd); unlock: - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1519,7 +1519,7 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash, cp->randomizer); @@ -1529,7 +1529,7 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL, 0); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; @@ -1553,7 +1553,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, ENODEV); - hci_dev_lock_bh(hdev); + hci_dev_lock(hdev); err = hci_remove_remote_oob_data(hdev, &cp->bdaddr); if (err < 0) @@ -1563,7 +1563,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, NULL, 0); - hci_dev_unlock_bh(hdev); + hci_dev_unlock(hdev); hci_dev_put(hdev); return err; -- GitLab From e63a15ec0f25c0f97e8f6247b97ac9b30968b6b3 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 18:56:53 -0300 Subject: [PATCH 0473/5560] Bluetooth: Use GFP_KERNEL in user context The allocation in mgmt_control() code are in user context and not locked by any spinlock, so it's not recommended the use of GFP_ATOMIC there. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c32238163b72..c304688252b8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1581,7 +1581,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) if (msglen < sizeof(*hdr)) return -EINVAL; - buf = kmalloc(msglen, GFP_ATOMIC); + buf = kmalloc(msglen, GFP_KERNEL); if (!buf) return -ENOMEM; -- GitLab From db940cb0db7c69a217661ecd49e1e6b0d680a6cc Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 2 Apr 2011 14:19:41 +0300 Subject: [PATCH 0474/5560] Bluetooth: convert net/bluetooth/ to kstrtox Convert from strict_strto*() interfaces to kstrto*() interfaces. Signed-off-by: Alexey Dobriyan Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_sysfs.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index e54421693eb8..8775933ea837 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -277,10 +277,12 @@ static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *at static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hci_dev *hdev = dev_get_drvdata(dev); - unsigned long val; + unsigned int val; + int rv; - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; + rv = kstrtouint(buf, 0, &val); + if (rv < 0) + return rv; if (val != 0 && (val < 500 || val > 3600000)) return -EINVAL; @@ -299,15 +301,14 @@ static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribu static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hci_dev *hdev = dev_get_drvdata(dev); - unsigned long val; - - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; + u16 val; + int rv; - if (val < 0x0002 || val > 0xFFFE || val % 2) - return -EINVAL; + rv = kstrtou16(buf, 0, &val); + if (rv < 0) + return rv; - if (val < hdev->sniff_min_interval) + if (val == 0 || val % 2 || val < hdev->sniff_min_interval) return -EINVAL; hdev->sniff_max_interval = val; @@ -324,15 +325,14 @@ static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribu static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hci_dev *hdev = dev_get_drvdata(dev); - unsigned long val; + u16 val; + int rv; - if (strict_strtoul(buf, 0, &val) < 0) - return -EINVAL; - - if (val < 0x0002 || val > 0xFFFE || val % 2) - return -EINVAL; + rv = kstrtou16(buf, 0, &val); + if (rv < 0) + return rv; - if (val > hdev->sniff_max_interval) + if (val == 0 || val % 2 || val > hdev->sniff_max_interval) return -EINVAL; hdev->sniff_min_interval = val; -- GitLab From 2627aaa6795753e787e544bbc8be60e38e0b08e6 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 09:59:08 +0100 Subject: [PATCH 0475/5560] staging: gma500: begin adding Moorestown support The Moorestown systems have some graphics differences we care about and some we don't need to. To start with it has a single pipe and that pipe can be used for LVDS Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 6 ++++-- drivers/staging/gma500/psb_drv.h | 6 ++---- drivers/staging/gma500/psb_fb.c | 6 +++++- drivers/staging/gma500/psb_intel_display.c | 4 +++- drivers/staging/gma500/psb_intel_lvds.c | 8 ++++++-- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 44cd095d2862..a7391c5853fd 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -586,8 +586,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) return -ENOMEM; INIT_LIST_HEAD(&dev_priv->video_ctx); - dev_priv->num_pipe = 2; - + if (IS_MRST(dev)) + dev_priv->num_pipe = 1; + else + dev_priv->num_pipe = 2; dev_priv->dev = dev; bdev = &dev_priv->bdev; diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 29a36056d664..e7507b1aceb4 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -45,6 +45,8 @@ enum { CHIP_PSB_8109 = 1, }; +#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) + /* *Hardware bugfixes */ @@ -52,10 +54,6 @@ enum { #define DRIVER_NAME "pvrsrvkm" #define DRIVER_DESC "drm driver for the Intel GMA500" #define DRIVER_AUTHOR "Intel Corporation" -#define OSPM_PROC_ENTRY "ospm" -#define RTPM_PROC_ENTRY "rtpm" -#define BLC_PROC_ENTRY "mrst_blc" -#define DISPLAY_PROC_ENTRY "display_status" #define PSB_DRM_DRIVER_DATE "2009-03-10" #define PSB_DRM_DRIVER_MAJOR 8 diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index f67f53b12937..4e5d8a6b7e26 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -716,7 +716,11 @@ static void psb_setup_outputs(struct drm_device *dev) break; case INTEL_OUTPUT_LVDS: PSB_DEBUG_ENTRY("LVDS.\n"); - crtc_mask = (1 << 1); + if (IS_MRST(dev)) + crtc_mask = (1 << 0); + else + crtc_mask = (1 << 1); + clone_mask = (1 << INTEL_OUTPUT_LVDS); break; case INTEL_OUTPUT_MIPI: diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index 80b37f4ca10a..917d37ef92bc 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -569,7 +569,9 @@ static int psb_intel_panel_fitter_pipe(struct drm_device *dev) if ((pfit_control & PFIT_ENABLE) == 0) return -1; /* Must be on PIPE 1 for PSB */ - return 1; + if (!IS_MRST(dev)) + return 1; + return (pfit_control >> 29) & 3; } static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c index d3d210a1026a..2de05245ec9b 100644 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -400,11 +400,15 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) panel_fixed_mode = mode_dev->panel_fixed_mode2; - /* PSB doesn't appear to be GEN4 */ - if (psb_intel_crtc->pipe == 0) { + /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ + if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); return false; } + if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) { + printk(KERN_ERR "Must use PIPE A\n"); + return false; + } /* Should never happen!! */ list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { -- GitLab From 54edcea62dbf7c4b4a429411d216d86c2788d8e9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 09:59:17 +0100 Subject: [PATCH 0476/5560] staging: gma500: Add moorestown lvds driver code Add the new files needed for the GMA500 driver to support Moorestown LVDS displays. Don't wire them in yet. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/mrst_crtc.c | 623 +++++++++++++++++++++++++++++ drivers/staging/gma500/mrst_lvds.c | 364 +++++++++++++++++ 2 files changed, 987 insertions(+) create mode 100644 drivers/staging/gma500/mrst_crtc.c create mode 100644 drivers/staging/gma500/mrst_lvds.c diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c new file mode 100644 index 000000000000..89b9cac898aa --- /dev/null +++ b/drivers/staging/gma500/mrst_crtc.c @@ -0,0 +1,623 @@ +/* + * Copyright © 2009 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. + */ + +#include +#include + +#include +#include "psb_fb.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_display.h" +#include "psb_powermgmt.h" + +struct psb_intel_range_t { + int min, max; +}; + +struct mrst_limit_t { + struct psb_intel_range_t dot, m, p1; +}; + +struct mrst_clock_t { + /* derived values */ + int dot; + int m; + int p1; +}; + +#define MRST_LIMIT_LVDS_100L 0 +#define MRST_LIMIT_LVDS_83 1 +#define MRST_LIMIT_LVDS_100 2 + +#define MRST_DOT_MIN 19750 +#define MRST_DOT_MAX 120000 +#define MRST_M_MIN_100L 20 +#define MRST_M_MIN_100 10 +#define MRST_M_MIN_83 12 +#define MRST_M_MAX_100L 34 +#define MRST_M_MAX_100 17 +#define MRST_M_MAX_83 20 +#define MRST_P1_MIN 2 +#define MRST_P1_MAX_0 7 +#define MRST_P1_MAX_1 8 + +static const struct mrst_limit_t mrst_limits[] = { + { /* MRST_LIMIT_LVDS_100L */ + .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, + .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L}, + .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, + }, + { /* MRST_LIMIT_LVDS_83L */ + .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, + .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83}, + .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0}, + }, + { /* MRST_LIMIT_LVDS_100 */ + .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, + .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100}, + .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, + }, +}; + +#define MRST_M_MIN 10 +static const u32 mrst_m_converts[] = { + 0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C, + 0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25, + 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c, +}; + +static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc) +{ + const struct mrst_limit_t *limit = NULL; + struct drm_device *dev = crtc->dev; + DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; + + if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) + || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) { + switch (dev_priv->core_freq) { + case 100: + limit = &mrst_limits[MRST_LIMIT_LVDS_100L]; + break; + case 166: + limit = &mrst_limits[MRST_LIMIT_LVDS_83]; + break; + case 200: + limit = &mrst_limits[MRST_LIMIT_LVDS_100]; + break; + } + } else { + limit = NULL; + PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n"); + } + + return limit; +} + +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ +static void mrst_clock(int refclk, struct mrst_clock_t *clock) +{ + clock->dot = (refclk * clock->m) / (14 * clock->p1); +} + +void mrstPrintPll(char *prefix, struct mrst_clock_t *clock) +{ + PSB_DEBUG_ENTRY("%s: dotclock = %d, m = %d, p1 = %d.\n", + prefix, clock->dot, clock->m, clock->p1); +} + +/** + * Returns a set of divisors for the desired target clock with the given refclk, + * or FALSE. Divisor values are the actual divisors for + */ +static bool +mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, + struct mrst_clock_t *best_clock) +{ + struct mrst_clock_t clock; + const struct mrst_limit_t *limit = mrst_limit(crtc); + int err = target; + + memset(best_clock, 0, sizeof(*best_clock)); + + for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { + for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; + clock.p1++) { + int this_err; + + mrst_clock(refclk, &clock); + + this_err = abs(clock.dot - target); + if (this_err < err) { + *best_clock = clock; + err = this_err; + } + } + } + DRM_DEBUG("mrstFindBestPLL err = %d.\n", err); + + return err != target; +} + +/** + * Sets the power management mode of the pipe and plane. + * + * This code should probably grow support for turning the cursor off and back + * on appropriately at the same time as we're turning the pipe off/on. + */ +static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + u32 temp; + bool enabled; + + PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe); + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return; + + /* XXX: When our outputs are all unaware of DPMS modes other than off + * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. + */ + switch (mode) { + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + /* Enable the DPLL */ + temp = REG_READ(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) == 0) { + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + } + /* Enable the pipe */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) == 0) + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); + /* Enable the plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { + REG_WRITE(dspcntr_reg, + temp | DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + } + + psb_intel_crtc_load_lut(crtc); + + /* Give the overlay scaler a chance to enable + if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, true); TODO */ + break; + case DRM_MODE_DPMS_OFF: + /* Give the overlay scaler a chance to disable + * if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + /* Disable display plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(dspcntr_reg, + temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); + } + + /* Next, disable display pipes */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + REG_READ(pipeconf_reg); + } + /* Wait for for the pipe disable to take effect. */ + psb_intel_wait_for_vblank(dev); + + temp = REG_READ(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) != 0) { + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + } + + /* Wait for the clocks to turn off. */ + udelay(150); + break; + } + + enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; + + /*Set FIFO Watermarks*/ + REG_WRITE(DSPARB, 0x3FFF); + REG_WRITE(DSPFW1, 0x3F88080A); + REG_WRITE(DSPFW2, 0x0b060808); + REG_WRITE(DSPFW3, 0x0); + REG_WRITE(DSPFW4, 0x08030404); + REG_WRITE(DSPFW5, 0x04040404); + REG_WRITE(DSPFW6, 0x78); + REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000); + /* Must write Bit 14 of the Chicken Bit Register */ + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); +} + +/** + * Return the pipe currently connected to the panel fitter, + * or -1 if the panel fitter is not present or not in use + */ +static int mrst_panel_fitter_pipe(struct drm_device *dev) +{ + u32 pfit_control; + + pfit_control = REG_READ(PFIT_CONTROL); + + /* See if the panel fitter is in use */ + if ((pfit_control & PFIT_ENABLE) == 0) + return -1; + return (pfit_control >> 29) & 3; +} + +static int mrst_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; + int pipe = psb_intel_crtc->pipe; + int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0; + int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; + int refclk = 0; + struct mrst_clock_t clock; + u32 dpll = 0, fp = 0, dspcntr, pipeconf; + bool ok, is_sdvo = false; + bool is_crt = false, is_lvds = false, is_tv = false; + bool is_mipi = false; + struct drm_mode_config *mode_config = &dev->mode_config; + struct psb_intel_output *psb_intel_output = NULL; + uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; + struct drm_encoder *encoder; + + PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe); + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return 0; + + memcpy(&psb_intel_crtc->saved_mode, + mode, + sizeof(struct drm_display_mode)); + memcpy(&psb_intel_crtc->saved_adjusted_mode, + adjusted_mode, + sizeof(struct drm_display_mode)); + + list_for_each_entry(encoder, &mode_config->encoder_list, head) { + + if (encoder->crtc != crtc) + continue; + + psb_intel_output = enc_to_psb_intel_output(encoder); + switch (psb_intel_output->type) { + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; + case INTEL_OUTPUT_SDVO: + is_sdvo = true; + break; + case INTEL_OUTPUT_TVOUT: + is_tv = true; + break; + case INTEL_OUTPUT_ANALOG: + is_crt = true; + break; + case INTEL_OUTPUT_MIPI: + is_mipi = true; + break; + } + } + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* Disable the panel fitter if it was on our pipe */ + if (mrst_panel_fitter_pipe(dev) == pipe) + REG_WRITE(PFIT_CONTROL, 0); + + REG_WRITE(pipesrc_reg, + ((mode->crtc_hdisplay - 1) << 16) | + (mode->crtc_vdisplay - 1)); + + if (psb_intel_output) + drm_connector_property_get_value(&psb_intel_output->base, + dev->mode_config.scaling_mode_property, &scalingType); + + if (scalingType == DRM_MODE_SCALE_NO_SCALE) { + /* Moorestown doesn't have register support for centering so + * we need to mess with the h/vblank and h/vsync start and + * ends to get centering */ + int offsetX = 0, offsetY = 0; + + offsetX = (adjusted_mode->crtc_hdisplay - + mode->crtc_hdisplay) / 2; + offsetY = (adjusted_mode->crtc_vdisplay - + mode->crtc_vdisplay) / 2; + + REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(hblank_reg, + (adjusted_mode->crtc_hblank_start - offsetX - 1) | + ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); + REG_WRITE(hsync_reg, + (adjusted_mode->crtc_hsync_start - offsetX - 1) | + ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); + REG_WRITE(vblank_reg, + (adjusted_mode->crtc_vblank_start - offsetY - 1) | + ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); + REG_WRITE(vsync_reg, + (adjusted_mode->crtc_vsync_start - offsetY - 1) | + ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); + } else { + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | + ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | + ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | + ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); + } + + /* Flush the plane changes */ + { + struct drm_crtc_helper_funcs *crtc_funcs = + crtc->helper_private; + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + } + + /* setup pipeconf */ + pipeconf = REG_READ(pipeconf_reg); + + /* Set up the display plane register */ + dspcntr = REG_READ(dspcntr_reg); + dspcntr |= DISPPLANE_GAMMA_ENABLE; + + if (pipe == 0) + dspcntr |= DISPPLANE_SEL_PIPE_A; + else + dspcntr |= DISPPLANE_SEL_PIPE_B; + + dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE; + dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE; + + if (is_mipi) + goto mrst_crtc_mode_set_exit; + + refclk = dev_priv->core_freq * 1000; + + dpll = 0; /*BIT16 = 0 for 100MHz reference */ + + ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock); + + if (!ok) { + PSB_DEBUG_ENTRY( + "mrstFindBestPLL fail in mrst_crtc_mode_set.\n"); + } else { + PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d," + "m = %x, p1 = %x.\n", clock.dot, clock.m, + clock.p1); + } + + fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8; + + dpll |= DPLL_VGA_MODE_DIS; + + + dpll |= DPLL_VCO_ENABLE; + + if (is_lvds) + dpll |= DPLLA_MODE_LVDS; + else + dpll |= DPLLB_MODE_DAC_SERIAL; + + if (is_sdvo) { + int sdvo_pixel_multiply = + adjusted_mode->clock / mode->clock; + + dpll |= DPLL_DVO_HIGH_SPEED; + dpll |= + (sdvo_pixel_multiply - + 1) << SDVO_MULTIPLIER_SHIFT_HIRES; + } + + + /* compute bitmask from p1 value */ + dpll |= (1 << (clock.p1 - 2)) << 17; + + dpll |= DPLL_VCO_ENABLE; + + mrstPrintPll("chosen", &clock); + + if (dpll & DPLL_VCO_ENABLE) { + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Check the DPLLA lock bit PIPEACONF[29] */ + udelay(150); + } + + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + + /* write it again -- the BIOS does, after all */ + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); + psb_intel_wait_for_vblank(dev); + + REG_WRITE(dspcntr_reg, dspcntr); + psb_intel_wait_for_vblank(dev); + +mrst_crtc_mode_set_exit: + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + return 0; +} + +static bool mrst_crtc_mode_fixup(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +int mrst_pipe_set_base(struct drm_crtc *crtc, + int x, int y, struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_i915_master_private *master_priv; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev; + int pipe = psb_intel_crtc->pipe; + unsigned long Start, Offset; + /* FIXME: check if we need this surely MRST is pipe 0 only */ + int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + u32 dspcntr; + int ret = 0; + + PSB_DEBUG_ENTRY("\n"); + + /* no fb bound */ + if (!crtc->fb) { + DRM_DEBUG("No FB bound\n"); + return 0; + } + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return 0; + + Start = mode_dev->bo_offset(dev, psbfb); + Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + + REG_WRITE(dspstride, crtc->fb->pitch); + + dspcntr = REG_READ(dspcntr_reg); + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; + + switch (crtc->fb->bits_per_pixel) { + case 8: + dspcntr |= DISPPLANE_8BPP; + break; + case 16: + if (crtc->fb->depth == 15) + dspcntr |= DISPPLANE_15_16BPP; + else + dspcntr |= DISPPLANE_16BPP; + break; + case 24: + case 32: + dspcntr |= DISPPLANE_32BPP_NO_ALPHA; + break; + default: + DRM_ERROR("Unknown color depth\n"); + ret = -EINVAL; + goto pipe_set_base_exit; + } + REG_WRITE(dspcntr_reg, dspcntr); + + DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); + if (0 /* FIXMEAC - check what PSB needs */) { + REG_WRITE(dspbase, Offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, Start); + REG_READ(dspsurf); + } else { + REG_WRITE(dspbase, Start + Offset); + REG_READ(dspbase); + } + +pipe_set_base_exit: + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + return ret; +} + +static void mrst_crtc_prepare(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); +} + +static void mrst_crtc_commit(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); +} + +const struct drm_crtc_helper_funcs mrst_helper_funcs = { + .dpms = mrst_crtc_dpms, + .mode_fixup = mrst_crtc_mode_fixup, + .mode_set = mrst_crtc_mode_set, + .mode_set_base = mrst_pipe_set_base, + .prepare = mrst_crtc_prepare, + .commit = mrst_crtc_commit, +}; + diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c new file mode 100644 index 000000000000..4628b01694a9 --- /dev/null +++ b/drivers/staging/gma500/mrst_lvds.c @@ -0,0 +1,364 @@ +/* + * Copyright © 2006-2009 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. + * + * Authors: + * Eric Anholt + * Dave Airlie + * Jesse Barnes + */ + +#include +#include + +#include "psb_intel_bios.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_powermgmt.h" +#include + +/* The max/min PWM frequency in BPCR[31:17] - */ +/* The smallest number is 1 (not 0) that can fit in the + * 15-bit field of the and then*/ +/* shifts to the left by one bit to get the actual 16-bit + * value that the 15-bits correspond to.*/ +#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF +#define BRIGHTNESS_MAX_LEVEL 100 + +/** + * Sets the power state for the panel. + */ +static void mrst_lvds_set_power(struct drm_device *dev, + struct psb_intel_output *output, bool on) +{ + u32 pp_status; + DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; + PSB_DEBUG_ENTRY("\n"); + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return; + + if (on) { + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | + POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); + dev_priv->is_lvds_on = true; + } else { + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & + ~POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while (pp_status & PP_ON); + dev_priv->is_lvds_on = false; + pm_request_idle(&dev->pdev->dev); + } + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); +} + +static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + + PSB_DEBUG_ENTRY("\n"); + + if (mode == DRM_MODE_DPMS_ON) + mrst_lvds_set_power(dev, output, true); + else + mrst_lvds_set_power(dev, output, false); + + /* XXX: We never power down the LVDS pairs. */ +} + +static void mrst_lvds_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct psb_intel_mode_device *mode_dev = + enc_to_psb_intel_output(encoder)->mode_dev; + struct drm_device *dev = encoder->dev; + u32 lvds_port; + uint64_t v = DRM_MODE_SCALE_FULLSCREEN; + + PSB_DEBUG_ENTRY("\n"); + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return; + + /* + * The LVDS pin pair will already have been turned on in the + * psb_intel_crtc_mode_set since it has a large impact on the DPLL + * settings. + */ + lvds_port = (REG_READ(LVDS) & + (~LVDS_PIPEB_SELECT)) | + LVDS_PORT_EN | + LVDS_BORDER_EN; + + if (mode_dev->panel_wants_dither) + lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; + + REG_WRITE(LVDS, lvds_port); + + drm_connector_property_get_value( + &enc_to_psb_intel_output(encoder)->base, + dev->mode_config.scaling_mode_property, + &v); + + if (v == DRM_MODE_SCALE_NO_SCALE) + REG_WRITE(PFIT_CONTROL, 0); + else if (v == DRM_MODE_SCALE_ASPECT) { + if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || + (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { + if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == + (mode->hdisplay * adjusted_mode->crtc_vdisplay)) + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); + else if ((adjusted_mode->crtc_hdisplay * + mode->vdisplay) > (mode->hdisplay * + adjusted_mode->crtc_vdisplay)) + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | + PFIT_SCALING_MODE_PILLARBOX); + else + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | + PFIT_SCALING_MODE_LETTERBOX); + } else + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); + } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ + REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); +} + + +static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = { + .dpms = mrst_lvds_dpms, + .mode_fixup = psb_intel_lvds_mode_fixup, + .prepare = psb_intel_lvds_prepare, + .mode_set = mrst_lvds_mode_set, + .commit = psb_intel_lvds_commit, +}; + +static struct drm_display_mode lvds_configuration_modes[] = { + /* hard coded fixed mode for TPO LTPS LPJ040K001A */ + { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836, + 846, 1056, 0, 480, 489, 491, 525, 0, 0) }, + /* hard coded fixed mode for LVDS 800x480 */ + { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801, + 802, 1024, 0, 480, 481, 482, 525, 0, 0) }, + /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ + { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072, + 1104, 1184, 0, 600, 603, 604, 608, 0, 0) }, + /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ + { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104, + 1136, 1184, 0, 600, 603, 604, 608, 0, 0) }, + /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */ + { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124, + 1204, 1312, 0, 600, 607, 610, 621, 0, 0) }, + /* hard coded fixed mode for LVDS 1024x768 */ + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, + 1184, 1344, 0, 768, 771, 777, 806, 0, 0) }, + /* hard coded fixed mode for LVDS 1366x768 */ + { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430, + 1558, 1664, 0, 768, 769, 770, 776, 0, 0) }, +}; + +/* Returns the panel fixed mode from configuration. */ + +static struct drm_display_mode * +mrst_lvds_get_configuration_mode(struct drm_device *dev) +{ + struct drm_display_mode *mode = NULL; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; + + if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) + return NULL; + + mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; + mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; + mode->hsync_start = mode->hdisplay + \ + ((ti->hsync_offset_hi << 8) | \ + ti->hsync_offset_lo); + mode->hsync_end = mode->hsync_start + \ + ((ti->hsync_pulse_width_hi << 8) | \ + ti->hsync_pulse_width_lo); + mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ + ti->hblank_lo); + mode->vsync_start = \ + mode->vdisplay + ((ti->vsync_offset_hi << 4) | \ + ti->vsync_offset_lo); + mode->vsync_end = \ + mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \ + ti->vsync_pulse_width_lo); + mode->vtotal = mode->vdisplay + \ + ((ti->vblank_hi << 8) | ti->vblank_lo); + mode->clock = ti->pixel_clock * 10; +#if 0 + printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay); + printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay); + printk(KERN_INFO "HSS is %d\n", mode->hsync_start); + printk(KERN_INFO "HSE is %d\n", mode->hsync_end); + printk(KERN_INFO "htotal is %d\n", mode->htotal); + printk(KERN_INFO "VSS is %d\n", mode->vsync_start); + printk(KERN_INFO "VSE is %d\n", mode->vsync_end); + printk(KERN_INFO "vtotal is %d\n", mode->vtotal); + printk(KERN_INFO "clock is %d\n", mode->clock); +#endif + } else + mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]); + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + return mode; +} + +/** + * mrst_lvds_init - setup LVDS connectors on this device + * @dev: drm device + * + * Create the connector, register the LVDS DDC bus, and try to figure out what + * modes we can display on the LVDS panel (if present). + */ +void mrst_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev) +{ + struct psb_intel_output *psb_intel_output; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + struct edid *edid; + int ret = 0; + struct i2c_adapter *i2c_adap; + struct drm_display_mode *scan; /* *modes, *bios_mode; */ + + PSB_DEBUG_ENTRY("\n"); + + psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); + if (!psb_intel_output) + return; + + psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; + encoder = &psb_intel_output->enc; + dev_priv->is_lvds_on = true; + drm_connector_init(dev, &psb_intel_output->base, + &psb_intel_lvds_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + + drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs, + DRM_MODE_ENCODER_LVDS); + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + psb_intel_output->type = INTEL_OUTPUT_LVDS; + + drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs); + drm_connector_helper_add(connector, + &psb_intel_lvds_connector_helper_funcs); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + + drm_connector_attach_property(connector, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_FULLSCREEN); + drm_connector_attach_property(connector, + dev_priv->backlight_property, + BRIGHTNESS_MAX_LEVEL); + + mode_dev->panel_wants_dither = false; + if (dev_priv->vbt_data.size != 0x00) + mode_dev->panel_wants_dither = (dev_priv->gct_data. + Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); + + /* + * LVDS discovery: + * 1) check for EDID on DDC + * 2) check for VBT data + * 3) check to see if LVDS is already on + * if none of the above, no panel + * 4) make sure lid is open + * if closed, act like it's not there for now + */ + i2c_adap = i2c_get_adapter(2); + if (i2c_adap == NULL) + printk(KERN_ALERT "No ddc adapter available!\n"); + /* + * Attempt to get the fixed panel mode from DDC. Assume that the + * preferred mode is the right one. + */ + if (i2c_adap) { + edid = drm_get_edid(connector, i2c_adap); + if (edid) { + drm_mode_connector_update_edid_property(connector, + edid); + ret = drm_add_edid_modes(connector, edid); + kfree(edid); + } + + list_for_each_entry(scan, &connector->probed_modes, head) { + if (scan->type & DRM_MODE_TYPE_PREFERRED) { + mode_dev->panel_fixed_mode = + drm_mode_duplicate(dev, scan); + goto out; /* FIXME: check for quirks */ + } + } + } + + /* + * If we didn't get EDID, try geting panel timing + * from configuration data + */ + mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev); + + if (mode_dev->panel_fixed_mode) { + mode_dev->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; + goto out; /* FIXME: check for quirks */ + } + + /* If we still don't have a mode after all that, give up. */ + if (!mode_dev->panel_fixed_mode) { + DRM_DEBUG + ("Found no modes on the lvds, ignoring the LVDS\n"); + goto failed_find; + } + +out: + drm_sysfs_connector_add(connector); + return; + +failed_find: + DRM_DEBUG("No LVDS modes found, disabling.\n"); + if (psb_intel_output->ddc_bus) + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); + +/* failed_ddc: */ + + drm_encoder_cleanup(encoder); + drm_connector_cleanup(connector); + kfree(connector); +} + -- GitLab From c9981d941cfe1d5b5244ca4c5f7211153b1d0805 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 09:59:25 +0100 Subject: [PATCH 0477/5560] staging: gma500: Make some of the lvds operations non-static We need these as they are also used by the Moorestown LVDS display support. Make the various needed symbols visible in the headers Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.h | 15 +++++++++++++++ drivers/staging/gma500/psb_intel_display.c | 4 ---- drivers/staging/gma500/psb_intel_lvds.c | 8 ++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index e7507b1aceb4..6de1c8a1863f 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -948,6 +948,21 @@ int psb_set_brightness(struct backlight_device *bd); int psb_get_brightness(struct backlight_device *bd); struct backlight_device * psb_get_backlight_device(void); +/* mrst_crtc.c */ +extern const struct drm_crtc_helper_funcs mrst_helper_funcs; + +/* mrst_lvds.c */ +extern void mrst_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev); + +/* psb_intel_lvds.c */ +extern void psb_intel_lvds_prepare(struct drm_encoder *encoder); +extern void psb_intel_lvds_commit(struct drm_encoder *encoder); +extern const struct drm_connector_helper_funcs + psb_intel_lvds_connector_helper_funcs; +extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; + + /* *Debug print bits setting */ diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index 917d37ef92bc..92b423dd3d3d 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -1335,10 +1335,6 @@ static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { .commit = psb_intel_crtc_commit, }; -static const struct drm_crtc_helper_funcs mrst_helper_funcs; -static const struct drm_crtc_helper_funcs mdfld_helper_funcs; -const struct drm_crtc_funcs mdfld_intel_crtc_funcs; - const struct drm_crtc_funcs psb_intel_crtc_funcs = { .save = psb_intel_crtc_save, .restore = psb_intel_crtc_restore, diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c index 2de05245ec9b..1e07f416691c 100644 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -449,7 +449,7 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, return true; } -static void psb_intel_lvds_prepare(struct drm_encoder *encoder) +void psb_intel_lvds_prepare(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); @@ -470,7 +470,7 @@ static void psb_intel_lvds_prepare(struct drm_encoder *encoder) ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); } -static void psb_intel_lvds_commit(struct drm_encoder *encoder) +void psb_intel_lvds_commit(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); @@ -673,14 +673,14 @@ static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = { .commit = psb_intel_lvds_commit, }; -static const struct drm_connector_helper_funcs +const struct drm_connector_helper_funcs psb_intel_lvds_connector_helper_funcs = { .get_modes = psb_intel_lvds_get_modes, .mode_valid = psb_intel_lvds_mode_valid, .best_encoder = psb_intel_best_encoder, }; -static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = { +const struct drm_connector_funcs psb_intel_lvds_connector_funcs = { .dpms = drm_helper_connector_dpms, .save = psb_intel_lvds_save, .restore = psb_intel_lvds_restore, -- GitLab From a9100caeea46e345f918319048b817cd7d295518 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 09:59:37 +0100 Subject: [PATCH 0478/5560] staging: gma500: Add moorestown config structures We have a set of firmware passed descriptors and things we need to grovel through for video configuration. This differs from the setup for the PC style Poulsbo hardware. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.h | 188 +++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 6de1c8a1863f..b7b21ae83dba 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -332,6 +332,194 @@ struct psb_video_ctx { /* todo: more context specific data for multi-context support */ }; +struct mrst_vbt { + s8 signature[4]; /*4 bytes,"$GCT" */ + u8 revision; + u8 size; + u8 checksum; + void *mrst_gct; +} __attribute__ ((packed)); + +struct mrst_timing_info { + u16 pixel_clock; + u8 hactive_lo; + u8 hblank_lo; + u8 hblank_hi:4; + u8 hactive_hi:4; + u8 vactive_lo; + u8 vblank_lo; + u8 vblank_hi:4; + u8 vactive_hi:4; + u8 hsync_offset_lo; + u8 hsync_pulse_width_lo; + u8 vsync_pulse_width_lo:4; + u8 vsync_offset_lo:4; + u8 vsync_pulse_width_hi:2; + u8 vsync_offset_hi:2; + u8 hsync_pulse_width_hi:2; + u8 hsync_offset_hi:2; + u8 width_mm_lo; + u8 height_mm_lo; + u8 height_mm_hi:4; + u8 width_mm_hi:4; + u8 hborder; + u8 vborder; + u8 unknown0:1; + u8 hsync_positive:1; + u8 vsync_positive:1; + u8 separate_sync:2; + u8 stereo:1; + u8 unknown6:1; + u8 interlaced:1; +} __attribute__((packed)); + +struct gct_r10_timing_info { + u16 pixel_clock; + u32 hactive_lo:8; + u32 hactive_hi:4; + u32 hblank_lo:8; + u32 hblank_hi:4; + u32 hsync_offset_lo:8; + u16 hsync_offset_hi:2; + u16 hsync_pulse_width_lo:8; + u16 hsync_pulse_width_hi:2; + u16 hsync_positive:1; + u16 rsvd_1:3; + u8 vactive_lo:8; + u16 vactive_hi:4; + u16 vblank_lo:8; + u16 vblank_hi:4; + u16 vsync_offset_lo:4; + u16 vsync_offset_hi:2; + u16 vsync_pulse_width_lo:4; + u16 vsync_pulse_width_hi:2; + u16 vsync_positive:1; + u16 rsvd_2:3; +} __attribute__((packed)); + +struct mrst_panel_descriptor_v1 { + u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ + /* 0x61190 if MIPI */ + u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ + u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ + /* Register 0x61210 */ + struct mrst_timing_info DTD;/*18 bytes, Standard definition */ + u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ + /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ + /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ + u16 Panel_MIPI_Display_Descriptor; + /*16 bits, Defined as follows: */ + /* if MIPI, 0x0000 if LVDS */ + /* Bit 0, Type, 2 bits, */ + /* 0: Type-1, */ + /* 1: Type-2, */ + /* 2: Type-3, */ + /* 3: Type-4 */ + /* Bit 2, Pixel Format, 4 bits */ + /* Bit0: 16bpp (not supported in LNC), */ + /* Bit1: 18bpp loosely packed, */ + /* Bit2: 18bpp packed, */ + /* Bit3: 24bpp */ + /* Bit 6, Reserved, 2 bits, 00b */ + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ + /* Bit 14, Reserved, 2 bits, 00b */ +} __attribute__ ((packed)); + +struct mrst_panel_descriptor_v2 { + u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ + /* 0x61190 if MIPI */ + u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ + u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ + /* Register 0x61210 */ + struct mrst_timing_info DTD;/*18 bytes, Standard definition */ + u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ + /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ + u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */ + /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ + u16 Panel_MIPI_Display_Descriptor; + /*16 bits, Defined as follows: */ + /* if MIPI, 0x0000 if LVDS */ + /* Bit 0, Type, 2 bits, */ + /* 0: Type-1, */ + /* 1: Type-2, */ + /* 2: Type-3, */ + /* 3: Type-4 */ + /* Bit 2, Pixel Format, 4 bits */ + /* Bit0: 16bpp (not supported in LNC), */ + /* Bit1: 18bpp loosely packed, */ + /* Bit2: 18bpp packed, */ + /* Bit3: 24bpp */ + /* Bit 6, Reserved, 2 bits, 00b */ + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ + /* Bit 14, Reserved, 2 bits, 00b */ +} __attribute__ ((packed)); + +union mrst_panel_rx { + struct{ + u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ + /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ + u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ + /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ + u16 SupportedVideoTransferMode:2; /*0: Non-burst only */ + /* 1: Burst and non-burst */ + /* 2/3: Reserved */ + u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ + u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ + u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ + u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ + u16 Rsvd:5;/*5 bits,00000b */ + } panelrx; + u16 panel_receiver; +} __attribute__ ((packed)); + +struct mrst_gct_v1 { + union{ /*8 bits,Defined as follows: */ + struct { + u8 PanelType:4; /*4 bits, Bit field for panels*/ + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ + /*2 bits,Specifies which of the*/ + u8 BootPanelIndex:2; + /* 4 panels to use by default*/ + u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ + /* the 4 MIPI DSI receivers to use*/ + } PD; + u8 PanelDescriptor; + }; + struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ + union mrst_panel_rx panelrx[4]; /* panel receivers*/ +} __attribute__ ((packed)); + +struct mrst_gct_v2 { + union{ /*8 bits,Defined as follows: */ + struct { + u8 PanelType:4; /*4 bits, Bit field for panels*/ + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ + /*2 bits,Specifies which of the*/ + u8 BootPanelIndex:2; + /* 4 panels to use by default*/ + u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ + /* the 4 MIPI DSI receivers to use*/ + } PD; + u8 PanelDescriptor; + }; + struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ + union mrst_panel_rx panelrx[4]; /* panel receivers*/ +} __attribute__ ((packed)); + +struct mrst_gct_data { + u8 bpi; /* boot panel index, number of panel used during boot */ + u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ + struct mrst_timing_info DTD; /* timing info for the selected panel */ + u32 Panel_Port_Control; + u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/ + u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + u32 PP_Cycle_Delay; + u16 Panel_Backlight_Inverter_Descriptor; + u16 Panel_MIPI_Display_Descriptor; +} __attribute__ ((packed)); + #define MODE_SETTING_IN_CRTC 0x1 #define MODE_SETTING_IN_ENCODER 0x2 #define MODE_SETTING_ON_GOING 0x3 -- GitLab From d3fc13d8fb6b7d71313fe57c342ba313bad22fd4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 09:59:45 +0100 Subject: [PATCH 0479/5560] staging: gma500: Add moorestown specific data to the device structure Moorestown needs somewhere to stash various pipe config registers and the firmware and fuse configurations Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index b7b21ae83dba..b4a8f0294b24 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -644,7 +644,8 @@ struct drm_psb_private { struct drm_psb_sizes_arg sizes; - uint32_t fuse_reg_value; + u32 fuse_reg_value; + u32 video_device_fuse; /* pci revision id for B0:D2:F0 */ uint8_t platform_rev_id; @@ -669,6 +670,7 @@ struct drm_psb_private { unsigned int lvds_use_ssc:1; int lvds_ssc_freq; bool is_lvds_on; + bool is_mipi_on; unsigned int core_freq; uint32_t iLVDS_enable; @@ -676,6 +678,20 @@ struct drm_psb_private { /*runtime PM state*/ int rpm_enabled; + /* Moorestown specific */ + struct mrst_vbt vbt_data; + struct mrst_gct_data gct_data; + + /* Moorestown pipe config register value cache */ + uint32_t pipeconf; + uint32_t pipeconf1; + uint32_t pipeconf2; + + /* Moorestown plane control register value cache */ + uint32_t dspcntr; + uint32_t dspcntr1; + uint32_t dspcntr2; + /* *Register state */ -- GitLab From f4f7868bf9de98934ae026a87c66b67f1149e38c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 09:59:57 +0100 Subject: [PATCH 0480/5560] staging: gma500: Makefiles Build the new files now all the changes they need are present. They won't yet be used but the plumbing is next step. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile index a52ba48be518..383a574a5d1d 100644 --- a/drivers/staging/gma500/Makefile +++ b/drivers/staging/gma500/Makefile @@ -26,6 +26,8 @@ psb_gfx-y += psb_bl.o \ psb_ttm_fence_user.o \ psb_ttm_placement_user.o \ psb_powermgmt.o \ - psb_irq.o + psb_irq.o \ + mrst_crtc.o \ + mrst_lvds.o obj-$(CONFIG_DRM_PSB) += psb_gfx.o -- GitLab From a7cf87e64a5cd5862381c6e874e58b13d5d54c3a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:00:05 +0100 Subject: [PATCH 0481/5560] staging: gma500: Add Moorestown backlight support Which is of course different to Poulsbo. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_bl.c | 112 ++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 27 deletions(-) diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c index 70c17b352f9f..a2729fdee8fc 100644 --- a/drivers/staging/gma500/psb_bl.c +++ b/drivers/staging/gma500/psb_bl.c @@ -33,7 +33,6 @@ #define BLC_PWM_FREQ_CALC_CONSTANT 32 #define MHz 1000000 #define BRIGHTNESS_MIN_LEVEL 1 -#define BRIGHTNESS_MAX_LEVEL 100 #define BRIGHTNESS_MASK 0xFF #define BLC_POLARITY_NORMAL 0 #define BLC_POLARITY_INVERSE 1 @@ -59,15 +58,57 @@ int psb_set_brightness(struct backlight_device *bd) DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - /* Perform value bounds checking */ - if (level < BRIGHTNESS_MIN_LEVEL) - level = BRIGHTNESS_MIN_LEVEL; + /* Percentage 1-100% being valid */ + if (level < 1) + level = 1; psb_intel_lvds_set_brightness(dev, level); psb_brightness = level; return 0; } +int mrst_set_brightness(struct backlight_device *bd) +{ + struct drm_device *dev = bl_get_data(psb_backlight_device); + struct drm_psb_private *dev_priv = dev->dev_private; + int level = bd->props.brightness; + u32 blc_pwm_ctl; + u32 max_pwm_blc; + + DRM_DEBUG_DRIVER("backlight level set to %d\n", level); + + /* Percentage 1-100% being valid */ + if (level < 1) + level = 1; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) { + /* Calculate and set the brightness value */ + max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; + blc_pwm_ctl = level * max_pwm_blc / 100; + + /* Adjust the backlight level with the percent in + * dev_priv->blc_adj1; + */ + blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; + blc_pwm_ctl = blc_pwm_ctl / 100; + + /* Adjust the backlight level with the percent in + * dev_priv->blc_adj2; + */ + blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; + blc_pwm_ctl = blc_pwm_ctl / 100; + + if (blc_pol == BLC_POLARITY_INVERSE) + blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl; + /* force PWM bit on */ + REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); + REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + psb_brightness = level; + return 0; +} + int psb_get_brightness(struct backlight_device *bd) { DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness); @@ -85,24 +126,33 @@ static const struct backlight_ops psb_ops = { static int device_backlight_init(struct drm_device *dev) { + struct drm_psb_private *dev_priv = dev->dev_private; unsigned long core_clock; /* u32 bl_max_freq; */ /* unsigned long value; */ u16 bl_max_freq; uint32_t value; uint32_t blc_pwm_precision_factor; - struct drm_psb_private *dev_priv = dev->dev_private; - /* get bl_max_freq and pol from dev_priv*/ - if (!dev_priv->lvds_bl) { - DRM_ERROR("Has no valid LVDS backlight info\n"); - return 1; + if (IS_MRST(dev)) { + dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; + dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; + bl_max_freq = 256; + /* this needs to be set elsewhere */ + blc_pol = BLC_POLARITY_NORMAL; + blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR; + } else { + /* get bl_max_freq and pol from dev_priv*/ + if (!dev_priv->lvds_bl) { + DRM_ERROR("Has no valid LVDS backlight info\n"); + return 1; + } + bl_max_freq = dev_priv->lvds_bl->freq; + blc_pol = dev_priv->lvds_bl->pol; + blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; + blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd; + blc_type = dev_priv->lvds_bl->type; } - bl_max_freq = dev_priv->lvds_bl->freq; - blc_pol = dev_priv->lvds_bl->pol; - blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; - blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd; - blc_type = dev_priv->lvds_bl->type; core_clock = dev_priv->core_freq; @@ -113,16 +163,24 @@ static int device_backlight_init(struct drm_device *dev) if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) { - /* Check: may be MFLD only */ - if ( - value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || - value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) - return 2; - else { - value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (value)); + if (IS_MRST(dev)) { + if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) + return 2; + else { + REG_WRITE(BLC_PWM_CTL2, + (0x80000000 | REG_READ(BLC_PWM_CTL2))); + REG_WRITE(BLC_PWM_CTL, value | (value << 16)); + } + } else { + if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || + value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) + return 2; + else { + value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; + REG_WRITE(BLC_PWM_CTL, + (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | + (value)); + } } ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); } @@ -136,7 +194,7 @@ int psb_backlight_init(struct drm_device *dev) struct backlight_properties props; memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = BRIGHTNESS_MAX_LEVEL; + props.max_brightness = 100; psb_backlight_device = backlight_device_register("psb-bl", NULL, (void *)dev, &psb_ops, &props); @@ -147,8 +205,8 @@ int psb_backlight_init(struct drm_device *dev) if (ret < 0) return ret; - psb_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL; - psb_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL; + psb_backlight_device->props.brightness = 100; + psb_backlight_device->props.max_brightness = 100; backlight_update_status(psb_backlight_device); #endif return 0; -- GitLab From 9ba06b5fabdfe23f3fe68b04fbe5928a38349bbf Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:00:13 +0100 Subject: [PATCH 0482/5560] staging: gma500: add framebuffer setup For Moorestown we want to use the mrst LVDS setup not the Poulsbo setup Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_fb.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index 4e5d8a6b7e26..53a270e5857b 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -698,8 +698,16 @@ static void psb_setup_outputs(struct drm_device *dev) psb_create_backlight_property(dev); - psb_intel_lvds_init(dev, &dev_priv->mode_dev); - /* psb_intel_sdvo_init(dev, SDVOB); */ + if (IS_MRST(dev)) { + if (dev_priv->iLVDS_enable) + mrst_lvds_init(dev, &dev_priv->mode_dev); + else + DRM_ERROR("DSI is not supported\n"); + } else { + /* FIXME: check if SDVO init should be re-enabled */ + psb_intel_lvds_init(dev, &dev_priv->mode_dev); + /* psb_intel_sdvo_init(dev, SDVOB); */ + } list_for_each_entry(connector, &dev->mode_config.connector_list, head) { @@ -717,10 +725,9 @@ static void psb_setup_outputs(struct drm_device *dev) case INTEL_OUTPUT_LVDS: PSB_DEBUG_ENTRY("LVDS.\n"); if (IS_MRST(dev)) - crtc_mask = (1 << 0); - else - crtc_mask = (1 << 1); - + crtc_mask = (1 << 0); + else + crtc_mask = (1 << 1); clone_mask = (1 << INTEL_OUTPUT_LVDS); break; case INTEL_OUTPUT_MIPI: -- GitLab From e68e8c711b58646c129383828c4ccc49f3b3d6cf Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:00:23 +0100 Subject: [PATCH 0483/5560] staging: gma500: enable Moorestown CRTC handling Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_intel_display.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index 92b423dd3d3d..d24d0bf8be5a 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -569,9 +569,7 @@ static int psb_intel_panel_fitter_pipe(struct drm_device *dev) if ((pfit_control & PFIT_ENABLE) == 0) return -1; /* Must be on PIPE 1 for PSB */ - if (!IS_MRST(dev)) - return 1; - return (pfit_control >> 29) & 3; + return 1; } static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, @@ -1395,7 +1393,11 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, psb_intel_crtc->mode_dev = mode_dev; psb_intel_crtc->cursor_addr = 0; - drm_crtc_helper_add(&psb_intel_crtc->base, + if (IS_MRST(dev)) + drm_crtc_helper_add(&psb_intel_crtc->base, + &mrst_helper_funcs); + else + drm_crtc_helper_add(&psb_intel_crtc->base, &psb_intel_helper_funcs); /* Setup the array of drm_connector pointer array */ -- GitLab From 427096db840eb199450e6099e4f9b2731daa692c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:00:32 +0100 Subject: [PATCH 0484/5560] staging: gma500: Moorestown does its setup differently Grovel the firmware via the Moorestown interfaces and read the other bits off the fuses. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 241 +++++++++++++++++++++++++++---- 1 file changed, 213 insertions(+), 28 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index a7391c5853fd..878b603ba4d1 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -320,6 +320,210 @@ static void psb_do_takedown(struct drm_device *dev) } +void mrst_get_fuse_settings(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + uint32_t fuse_value = 0; + uint32_t fuse_value_tmp = 0; + +#define FB_REG06 0xD0810600 +#define FB_MIPI_DISABLE (1 << 11) +#define FB_REG09 0xD0810900 +#define FB_REG09 0xD0810900 +#define FB_SKU_MASK 0x7000 +#define FB_SKU_SHIFT 12 +#define FB_SKU_100 0 +#define FB_SKU_100L 1 +#define FB_SKU_83 2 + pci_write_config_dword(pci_root, 0xD0, FB_REG06); + pci_read_config_dword(pci_root, 0xD4, &fuse_value); + + dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE; + + DRM_INFO("internal display is %s\n", + dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display"); + + /*prevent Runtime suspend at start*/ + if (dev_priv->iLVDS_enable) { + dev_priv->is_lvds_on = true; + dev_priv->is_mipi_on = false; + } + else { + dev_priv->is_mipi_on = true; + dev_priv->is_lvds_on = false; + } + + dev_priv->video_device_fuse = fuse_value; + + pci_write_config_dword(pci_root, 0xD0, FB_REG09); + pci_read_config_dword(pci_root, 0xD4, &fuse_value); + + DRM_INFO("SKU values is 0x%x. \n", fuse_value); + fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT; + + dev_priv->fuse_reg_value = fuse_value; + + switch (fuse_value_tmp) { + case FB_SKU_100: + dev_priv->core_freq = 200; + break; + case FB_SKU_100L: + dev_priv->core_freq = 100; + break; + case FB_SKU_83: + dev_priv->core_freq = 166; + break; + default: + DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp); + dev_priv->core_freq = 0; + } + DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq); + pci_dev_put(pci_root); +} + +void mid_get_pci_revID (struct drm_psb_private *dev_priv) +{ + uint32_t platform_rev_id = 0; + struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); + + /*get the revison ID, B0:D2:F0;0x08 */ + pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); + dev_priv->platform_rev_id = (uint8_t) platform_rev_id; + pci_dev_put(pci_gfx_root); + PSB_DEBUG_ENTRY("platform_rev_id is %x\n", dev_priv->platform_rev_id); +} + +void mrst_get_vbt_data(struct drm_psb_private *dev_priv) +{ + struct mrst_vbt *vbt = &dev_priv->vbt_data; + u32 platform_config_address; + u16 new_size; + u8 *vbt_virtual; + u8 bpi; + u8 number_desc = 0; + struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD; + struct gct_r10_timing_info ti; + void *pGCT; + struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); + + /*get the address of the platform config vbt, B0:D2:F0;0xFC */ + pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address); + pci_dev_put(pci_gfx_root); + DRM_INFO("drm platform config address is %x\n", + platform_config_address); + + /* check for platform config address == 0. */ + /* this means fw doesn't support vbt */ + + if (platform_config_address == 0) { + vbt->size = 0; + return; + } + + /* get the virtual address of the vbt */ + vbt_virtual = ioremap(platform_config_address, sizeof(*vbt)); + + memcpy(vbt, vbt_virtual, sizeof(*vbt)); + iounmap(vbt_virtual); /* Free virtual address space */ + + printk(KERN_ALERT "GCT revision is %x\n", vbt->revision); + + switch (vbt->revision) { + case 0: + vbt->mrst_gct = NULL; + vbt->mrst_gct = \ + ioremap(platform_config_address + sizeof(*vbt) - 4, + vbt->size - sizeof(*vbt) + 4); + pGCT = vbt->mrst_gct; + bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = + ((struct mrst_gct_v1 *)pGCT)->PD.PanelType; + memcpy(&dev_priv->gct_data.DTD, + &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD, + sizeof(struct mrst_timing_info)); + dev_priv->gct_data.Panel_Port_Control = + ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; + break; + case 1: + vbt->mrst_gct = NULL; + vbt->mrst_gct = \ + ioremap(platform_config_address + sizeof(*vbt) - 4, + vbt->size - sizeof(*vbt) + 4); + pGCT = vbt->mrst_gct; + bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = + ((struct mrst_gct_v2 *)pGCT)->PD.PanelType; + memcpy(&dev_priv->gct_data.DTD, + &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD, + sizeof(struct mrst_timing_info)); + dev_priv->gct_data.Panel_Port_Control = + ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; + break; + case 0x10: + /*header definition changed from rev 01 (v2) to rev 10h. */ + /*so, some values have changed location*/ + new_size = vbt->checksum; /*checksum contains lo size byte*/ + /*LSB of mrst_gct contains hi size byte*/ + new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8; + + vbt->checksum = vbt->size; /*size contains the checksum*/ + if (new_size > 0xff) + vbt->size = 0xff; /*restrict size to 255*/ + else + vbt->size = new_size; + + /* number of descriptors defined in the GCT */ + number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8; + bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16; + vbt->mrst_gct = NULL; + vbt->mrst_gct = \ + ioremap(platform_config_address + GCT_R10_HEADER_SIZE, + GCT_R10_DISPLAY_DESC_SIZE * number_desc); + pGCT = vbt->mrst_gct; + pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE); + dev_priv->gct_data.bpi = bpi; /*save boot panel id*/ + + /*copy the GCT display timings into a temp structure*/ + memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info)); + + /*now copy the temp struct into the dev_priv->gct_data*/ + dp_ti->pixel_clock = ti.pixel_clock; + dp_ti->hactive_hi = ti.hactive_hi; + dp_ti->hactive_lo = ti.hactive_lo; + dp_ti->hblank_hi = ti.hblank_hi; + dp_ti->hblank_lo = ti.hblank_lo; + dp_ti->hsync_offset_hi = ti.hsync_offset_hi; + dp_ti->hsync_offset_lo = ti.hsync_offset_lo; + dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi; + dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo; + dp_ti->vactive_hi = ti.vactive_hi; + dp_ti->vactive_lo = ti.vactive_lo; + dp_ti->vblank_hi = ti.vblank_hi; + dp_ti->vblank_lo = ti.vblank_lo; + dp_ti->vsync_offset_hi = ti.vsync_offset_hi; + dp_ti->vsync_offset_lo = ti.vsync_offset_lo; + dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi; + dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo; + + /*mov the MIPI_Display_Descriptor data from GCT to dev priv*/ + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + *((u8 *)pGCT + 0x0d); + dev_priv->gct_data.Panel_MIPI_Display_Descriptor |= + (*((u8 *)pGCT + 0x0e)) << 8; + break; + default: + printk(KERN_ERR "Unknown revision of GCT!\n"); + vbt->size = 0; + } +} + static void psb_get_core_freq(struct drm_device *dev) { uint32_t clock; @@ -358,31 +562,6 @@ static void psb_get_core_freq(struct drm_device *dev) } } -#define FB_REG06 0xD0810600 -#define FB_TOPAZ_DISABLE BIT0 -#define FB_MIPI_DISABLE BIT11 -#define FB_REG09 0xD0810900 -#define FB_SKU_MASK (BIT12|BIT13|BIT14) -#define FB_SKU_SHIFT 12 -#define FB_SKU_100 0 -#define FB_SKU_100L 1 -#define FB_SKU_83 2 - -bool mid_get_pci_revID(struct drm_psb_private *dev_priv) -{ - uint32_t platform_rev_id = 0; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - /*get the revison ID, B0:D2:F0;0x08 */ - pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); - dev_priv->platform_rev_id = (uint8_t) platform_rev_id; - pci_dev_put(pci_gfx_root); - PSB_DEBUG_ENTRY("platform_rev_id is %x\n", - dev_priv->platform_rev_id); - - return true; -} - static int psb_do_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = @@ -634,9 +813,15 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (!dev_priv->sgx_reg) goto out_err; - psb_get_core_freq(dev); - psb_intel_opregion_init(dev); - psb_intel_init_bios(dev); + if (IS_MRST(dev)) { + mrst_get_fuse_settings(dev); + mrst_get_vbt_data(dev_priv); + mid_get_pci_revID(dev_priv); + } else { + psb_get_core_freq(dev); + psb_intel_opregion_init(dev); + psb_intel_init_bios(dev); + } PSB_DEBUG_INIT("Init TTM fence and BO driver\n"); -- GitLab From c69a20369b0f8fca522b8420991f7b214e4e737f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:00:43 +0100 Subject: [PATCH 0485/5560] staging: gma500: Add Moorestown identifiers Turn it on, turn it up, turn it loose Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 8 ++++++++ drivers/staging/gma500/psb_drv.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 878b603ba4d1..b9256e3b6107 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -62,6 +62,14 @@ module_param_named(rtpm, gfxrtdelay, int, 0600); static struct pci_device_id pciidlist[] = { { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 }, { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 }, + { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, + { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, { 0, 0, 0} }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index b4a8f0294b24..dbb3fbb294f6 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -43,6 +43,7 @@ extern struct ttm_bo_driver psb_ttm_bo_driver; enum { CHIP_PSB_8108 = 0, CHIP_PSB_8109 = 1, + CHIP_MRST_4100 = 2, }; #define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) -- GitLab From 7e2c6c433e000e2e001f1a8464ea08d053c8fb52 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:00:54 +0100 Subject: [PATCH 0486/5560] staging: gma500: delete the RAR handling RAR registers are used on MID platforms for various protected video playback activities using video playback engines we don't support. So Rasputin can keep his Rars Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_buffer.c | 16 +--------------- drivers/staging/gma500/psb_drv.c | 29 +---------------------------- drivers/staging/gma500/psb_drv.h | 6 ------ drivers/staging/gma500/psb_gtt.c | 22 ---------------------- 4 files changed, 2 insertions(+), 71 deletions(-) diff --git a/drivers/staging/gma500/psb_buffer.c b/drivers/staging/gma500/psb_buffer.c index 3077f6a7b7dc..a921f892ea5f 100644 --- a/drivers/staging/gma500/psb_buffer.c +++ b/drivers/staging/gma500/psb_buffer.c @@ -76,14 +76,6 @@ static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->available_caching = TTM_PL_FLAG_UNCACHED; man->default_caching = TTM_PL_FLAG_UNCACHED; break; - case TTM_PL_RAR: /* Unmappable RAR memory */ - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_FIXED; - man->available_caching = TTM_PL_FLAG_UNCACHED; - man->default_caching = TTM_PL_FLAG_UNCACHED; - man->gpu_offset = pg->mmu_gatt_start + (pg->rar_start); - break; case TTM_PL_TT: /* Mappable GATT memory */ man->func = &ttm_bo_manager_func; #ifdef PSB_WORKING_HOST_MMU_ACCESS @@ -95,8 +87,7 @@ static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->available_caching = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; man->default_caching = TTM_PL_FLAG_WC; - man->gpu_offset = pg->mmu_gatt_start + - (pg->rar_start + dev_priv->rar_region_size); + man->gpu_offset = pg->mmu_gatt_start; break; default: DRM_ERROR("Unsupported memory type %u\n", (unsigned) type); @@ -387,11 +378,6 @@ static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev, mem->bus.base = dev_priv->ci_region_start;; mem->bus.is_iomem = true; break; - case TTM_PL_RAR: - mem->bus.offset = mm_node->start << PAGE_SHIFT; - mem->bus.base = dev_priv->rar_region_start;; - mem->bus.is_iomem = true; - break; default: return -EINVAL; } diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index b9256e3b6107..84bcfebf3e8f 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -321,11 +321,6 @@ static void psb_do_takedown(struct drm_device *dev) ttm_bo_clean_mm(bdev, TTM_PL_CI); dev_priv->have_camera = 0; } - if (dev_priv->have_rar) { - ttm_bo_clean_mm(bdev, TTM_PL_RAR); - dev_priv->have_rar = 0; - } - } void mrst_get_fuse_settings(struct drm_device *dev) @@ -647,7 +642,7 @@ static int psb_do_init(struct drm_device *dev) if (!ttm_bo_init_mm(bdev, TTM_PL_TT, pg->gatt_pages - (pg->ci_start >> PAGE_SHIFT) - - ((dev_priv->ci_region_size + dev_priv->rar_region_size) + ((dev_priv->ci_region_size) >> PAGE_SHIFT))) { dev_priv->have_tt = 1; @@ -707,12 +702,6 @@ static int psb_driver_unload(struct drm_device *dev) (dev_priv->mmu), pg->ci_start, pg->ci_stolen_size >> PAGE_SHIFT); - if (pg->rar_stolen_size != 0) - psb_mmu_remove_pfn_sequence( - psb_mmu_get_default_pd - (dev_priv->mmu), - pg->rar_start, - pg->rar_stolen_size >> PAGE_SHIFT); up_read(&pg->sem); psb_mmu_driver_takedown(dev_priv->mmu); dev_priv->mmu = NULL; @@ -883,7 +872,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) /* CI/RAR use the lower half of TT. */ pg->ci_start = (tt_pages / 2) << PAGE_SHIFT; - pg->rar_start = pg->ci_start + pg->ci_stolen_size; /* @@ -901,21 +889,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) goto out_err; } - /* - * Make MSVDX/TOPAZ MMU aware of the rar stolen memory area. - */ - if (dev_priv->pg->rar_stolen_size != 0) { - down_read(&pg->sem); - ret = psb_mmu_insert_pfn_sequence( - psb_mmu_get_default_pd(dev_priv->mmu), - dev_priv->rar_region_start >> PAGE_SHIFT, - pg->mmu_gatt_start + pg->rar_start, - pg->rar_stolen_size >> PAGE_SHIFT, 0); - up_read(&pg->sem); - if (ret) - goto out_err; - } - dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0); if (!dev_priv->pf_pd) goto out_err; diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index dbb3fbb294f6..2aa7abc6c20d 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -605,12 +605,6 @@ struct drm_psb_private { unsigned int ci_region_start; unsigned int ci_region_size; - /* - * RAR share buffer; - */ - unsigned int rar_region_start; - unsigned int rar_region_size; - /* *Memory managers */ diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c index 53c1e1ed3bd2..0e5ee6c25d9d 100644 --- a/drivers/staging/gma500/psb_gtt.c +++ b/drivers/staging/gma500/psb_gtt.c @@ -76,7 +76,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) struct drm_psb_private *dev_priv = dev->dev_private; unsigned gtt_pages; unsigned long stolen_size, vram_stolen_size, ci_stolen_size; - unsigned long rar_stolen_size; unsigned i, num_pages; unsigned pfn_base; uint32_t ci_pages, vram_pages; @@ -118,8 +117,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) * managed by TTM to stolen_size */ stolen_size = vram_stolen_size; - rar_stolen_size = dev_priv->rar_region_size; - printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n", pg->gatt_start, pg->gatt_pages/256); printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n", @@ -136,10 +133,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M\n", dev_priv->ci_region_start, ci_stolen_size / 1024 / 1024); - if (rar_stolen_size > 0) - printk(KERN_INFO "RAR Stole memory: RAM base = 0x%08x, size = %lu M\n", - dev_priv->rar_region_start, - rar_stolen_size / 1024 / 1024); if (resume && (gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { @@ -152,7 +145,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) pg->stolen_size = stolen_size; pg->vram_stolen_size = vram_stolen_size; pg->ci_stolen_size = ci_stolen_size; - pg->rar_stolen_size = rar_stolen_size; pg->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT); if (!pg->gtt_map) { @@ -209,20 +201,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) iowrite32(pte, ttm_gtt_map + i); } - /* - * insert RAR stolen pages - */ - if (rar_stolen_size != 0) { - pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT; - num_pages = rar_stolen_size >> PAGE_SHIFT; - printk(KERN_INFO"Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n", - num_pages, pfn_base, - (ttm_gtt_map - pg->gtt_map + i) * 4); - for (; i < num_pages + ci_pages; ++i) { - pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0); - iowrite32(pte, ttm_gtt_map + i); - } - } /* * Init rest of gtt managed by TTM. */ -- GitLab From 1163a0b88c5882bef744b40133195d7231d4e409 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:01:03 +0100 Subject: [PATCH 0487/5560] staging: gma500: We don't support the CI either The camera interface is also not covered (and we won't be using TTM anyway even if it ever re-emerges) so it to can go Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_buffer.c | 13 ----------- drivers/staging/gma500/psb_drv.c | 36 +---------------------------- drivers/staging/gma500/psb_drv.h | 8 ------- drivers/staging/gma500/psb_gtt.c | 27 ++-------------------- drivers/staging/gma500/psb_gtt.h | 4 ---- 5 files changed, 3 insertions(+), 85 deletions(-) diff --git a/drivers/staging/gma500/psb_buffer.c b/drivers/staging/gma500/psb_buffer.c index a921f892ea5f..b5d79a589db1 100644 --- a/drivers/staging/gma500/psb_buffer.c +++ b/drivers/staging/gma500/psb_buffer.c @@ -68,14 +68,6 @@ static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; man->default_caching = TTM_PL_FLAG_WC; break; - case TTM_PL_CI: - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_FIXED; - man->gpu_offset = pg->mmu_gatt_start + (pg->ci_start); - man->available_caching = TTM_PL_FLAG_UNCACHED; - man->default_caching = TTM_PL_FLAG_UNCACHED; - break; case TTM_PL_TT: /* Mappable GATT memory */ man->func = &ttm_bo_manager_func; #ifdef PSB_WORKING_HOST_MMU_ACCESS @@ -373,11 +365,6 @@ static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev, mem->bus.offset = mm_node->start << PAGE_SHIFT; mem->bus.base = 0x00000000; break; - case TTM_PL_CI: - mem->bus.offset = mm_node->start << PAGE_SHIFT; - mem->bus.base = dev_priv->ci_region_start;; - mem->bus.is_iomem = true; - break; default: return -EINVAL; } diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 84bcfebf3e8f..cbb691e8617c 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -316,11 +316,6 @@ static void psb_do_takedown(struct drm_device *dev) ttm_bo_clean_mm(bdev, TTM_PL_TT); dev_priv->have_tt = 0; } - - if (dev_priv->have_camera) { - ttm_bo_clean_mm(bdev, TTM_PL_CI); - dev_priv->have_camera = 0; - } } void mrst_get_fuse_settings(struct drm_device *dev) @@ -639,12 +634,7 @@ static int psb_do_init(struct drm_device *dev) PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); /* TT region managed by TTM. */ - if (!ttm_bo_init_mm(bdev, TTM_PL_TT, - pg->gatt_pages - - (pg->ci_start >> PAGE_SHIFT) - - ((dev_priv->ci_region_size) - >> PAGE_SHIFT))) { - + if (!ttm_bo_init_mm(bdev, TTM_PL_TT, pg->gatt_pages)) { dev_priv->have_tt = 1; dev_priv->sizes.tt_size = (tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2; @@ -696,12 +686,6 @@ static int psb_driver_unload(struct drm_device *dev) (dev_priv->mmu), pg->mmu_gatt_start, pg->vram_stolen_size >> PAGE_SHIFT); - if (pg->ci_stolen_size != 0) - psb_mmu_remove_pfn_sequence( - psb_mmu_get_default_pd - (dev_priv->mmu), - pg->ci_start, - pg->ci_stolen_size >> PAGE_SHIFT); up_read(&pg->sem); psb_mmu_driver_takedown(dev_priv->mmu); dev_priv->mmu = NULL; @@ -870,24 +854,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; - /* CI/RAR use the lower half of TT. */ - pg->ci_start = (tt_pages / 2) << PAGE_SHIFT; - - - /* - * Make MSVDX/TOPAZ MMU aware of the CI stolen memory area. - */ - if (dev_priv->pg->ci_stolen_size != 0) { - down_read(&pg->sem); - ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd - (dev_priv->mmu), - dev_priv->ci_region_start >> PAGE_SHIFT, - pg->mmu_gatt_start + pg->ci_start, - pg->ci_stolen_size >> PAGE_SHIFT, 0); - up_read(&pg->sem); - if (ret) - goto out_err; - } dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0); if (!dev_priv->pf_pd) diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 2aa7abc6c20d..7c83c8de0dca 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -599,18 +599,10 @@ struct drm_psb_private { struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE]; uint32_t num_pipe; - /* - * CI share buffer - */ - unsigned int ci_region_start; - unsigned int ci_region_size; - /* *Memory managers */ - int have_camera; - int have_rar; int have_tt; int have_mem_mmu; struct mutex temp_mem; diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c index 0e5ee6c25d9d..d129b75c4e56 100644 --- a/drivers/staging/gma500/psb_gtt.c +++ b/drivers/staging/gma500/psb_gtt.c @@ -75,10 +75,10 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) struct drm_device *dev = pg->dev; struct drm_psb_private *dev_priv = dev->dev_private; unsigned gtt_pages; - unsigned long stolen_size, vram_stolen_size, ci_stolen_size; + unsigned long stolen_size, vram_stolen_size; unsigned i, num_pages; unsigned pfn_base; - uint32_t ci_pages, vram_pages; + uint32_t vram_pages; uint32_t tt_pages; uint32_t *ttm_gtt_map; uint32_t dvmt_mode = 0; @@ -111,10 +111,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base); vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE; - /* CI is not included in the stolen size since the TOPAZ MMU bug */ - ci_stolen_size = dev_priv->ci_region_size; - /* Don't add CI & RAR share buffer space - * managed by TTM to stolen_size */ stolen_size = vram_stolen_size; printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n", @@ -129,11 +125,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n", (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode); - if (ci_stolen_size > 0) - printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M\n", - dev_priv->ci_region_start, - ci_stolen_size / 1024 / 1024); - if (resume && (gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { DRM_ERROR("GTT resume error.\n"); @@ -144,7 +135,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) pg->gtt_pages = gtt_pages; pg->stolen_size = stolen_size; pg->vram_stolen_size = vram_stolen_size; - pg->ci_stolen_size = ci_stolen_size; pg->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT); if (!pg->gtt_map) { @@ -188,19 +178,6 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) for (; i < tt_pages / 2 - 1; ++i) iowrite32(pte, pg->gtt_map + i); - /* - * insert CI stolen pages - */ - - pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT; - ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT; - printk(KERN_INFO"Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n", - num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4); - for (i = 0; i < num_pages; ++i) { - pte = psb_gtt_mask_pte(pfn_base + i, 0); - iowrite32(pte, ttm_gtt_map + i); - } - /* * Init rest of gtt managed by TTM. */ diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h index 0272f83b461e..8a0ef7783abd 100644 --- a/drivers/staging/gma500/psb_gtt.h +++ b/drivers/staging/gma500/psb_gtt.h @@ -29,8 +29,6 @@ struct psb_gtt { int initialized; uint32_t gatt_start; uint32_t mmu_gatt_start; - uint32_t ci_start; - uint32_t rar_start; uint32_t gtt_start; uint32_t gtt_phys_start; unsigned gtt_pages; @@ -41,8 +39,6 @@ struct psb_gtt { u16 gmch_ctrl; unsigned long stolen_size; unsigned long vram_stolen_size; - unsigned long ci_stolen_size; - unsigned long rar_stolen_size; uint32_t *gtt_map; struct rw_semaphore sem; }; -- GitLab From 5c7d3a7aba44864547906cd326dd115c9327e19f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:01:13 +0100 Subject: [PATCH 0488/5560] staging: gma500: Clean up more unused structures and code We don't need the 3D validation stuff so it and all the related gunge can depart. While we are at it prune some unused definitions. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 16 ----- drivers/staging/gma500/psb_drv.h | 105 ------------------------------ drivers/staging/gma500/psb_sgx.c | 107 ------------------------------- 3 files changed, 228 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index cbb691e8617c..6e9954c53411 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -284,20 +284,7 @@ static void psb_set_uopt(struct drm_psb_uopt *uopt) static void psb_lastclose(struct drm_device *dev) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - return; - - if (!dev->dev_private) - return; - - mutex_lock(&dev_priv->cmdbuf_mutex); - if (dev_priv->context.buffers) { - vfree(dev_priv->context.buffers); - dev_priv->context.buffers = NULL; - } - mutex_unlock(&dev_priv->cmdbuf_mutex); } static void psb_do_takedown(struct drm_device *dev) @@ -744,7 +731,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; - INIT_LIST_HEAD(&dev_priv->video_ctx); if (IS_MRST(dev)) dev_priv->num_pipe = 1; @@ -767,8 +753,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) mutex_init(&dev_priv->temp_mem); mutex_init(&dev_priv->cmdbuf_mutex); mutex_init(&dev_priv->reset_mutex); - INIT_LIST_HEAD(&dev_priv->context.validate_list); - INIT_LIST_HEAD(&dev_priv->context.kern_validate_list); /* mutex_init(&dev_priv->dsr_mutex); */ diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 7c83c8de0dca..014035f2e2e1 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -94,23 +94,10 @@ enum { #define PSB_MEM_MMU_START 0x00000000 #define PSB_MEM_TT_START 0xE0000000 -#define PSB_GL3_CACHE_CTL 0x2100 -#define PSB_GL3_CACHE_STAT 0x2108 - /* *Flags for external memory type field. */ -#define MRST_MSVDX_OFFSET 0x90000 /*MSVDX Base offset */ -#define PSB_MSVDX_OFFSET 0x50000 /*MSVDX Base offset */ -/* MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */ -#define PSB_MSVDX_SIZE 0x10000 - -#define LNC_TOPAZ_OFFSET 0xA0000 -#define PNW_TOPAZ_OFFSET 0xC0000 -#define PNW_GL3_OFFSET 0xB0000 -#define LNC_TOPAZ_SIZE 0x10000 -#define PNW_TOPAZ_SIZE 0x30000 /* PNW VXE285 has two cores */ #define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */ #define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */ #define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */ @@ -222,20 +209,6 @@ enum { #define MDFLD_PNW_B0 0x04 #define MDFLD_PNW_C0 0x08 -#define MDFLD_DSR_2D_3D_0 BIT0 -#define MDFLD_DSR_2D_3D_2 BIT1 -#define MDFLD_DSR_CURSOR_0 BIT2 -#define MDFLD_DSR_CURSOR_2 BIT3 -#define MDFLD_DSR_OVERLAY_0 BIT4 -#define MDFLD_DSR_OVERLAY_2 BIT5 -#define MDFLD_DSR_MIPI_CONTROL BIT6 -#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) - -#define MDFLD_DSR_RR 45 -#define MDFLD_DPU_ENABLE BIT31 -#define MDFLD_DSR_FULLSCREEN BIT30 -#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR) - #define PSB_PWR_STATE_ON 1 #define PSB_PWR_STATE_OFF 2 @@ -249,9 +222,6 @@ enum { #define PSB_PCIx_MSI_ADDR_LOC 0x94 #define PSB_PCIx_MSI_DATA_LOC 0x98 -#define MDFLD_PLANE_MAX_WIDTH 2048 -#define MDFLD_PLANE_MAX_HEIGHT 2048 - struct opregion_header; struct opregion_acpi; struct opregion_swsci; @@ -273,66 +243,6 @@ struct drm_psb_uopt { int pad; /*keep it here in case we use it in future*/ }; -/** - *struct psb_context - * - *@buffers: array of pre-allocated validate buffers. - *@used_buffers: number of buffers in @buffers array currently in use. - *@validate_buffer: buffers validated from user-space. - *@kern_validate_buffers : buffers validated from kernel-space. - *@fence_flags : Fence flags to be used for fence creation. - * - *This structure is used during execbuf validation. - */ - -struct psb_context { - struct psb_validate_buffer *buffers; - uint32_t used_buffers; - struct list_head validate_list; - struct list_head kern_validate_list; - uint32_t fence_types; - uint32_t val_seq; -}; - -struct psb_validate_buffer; - -/* Currently defined profiles */ -enum VAProfile { - VAProfileMPEG2Simple = 0, - VAProfileMPEG2Main = 1, - VAProfileMPEG4Simple = 2, - VAProfileMPEG4AdvancedSimple = 3, - VAProfileMPEG4Main = 4, - VAProfileH264Baseline = 5, - VAProfileH264Main = 6, - VAProfileH264High = 7, - VAProfileVC1Simple = 8, - VAProfileVC1Main = 9, - VAProfileVC1Advanced = 10, - VAProfileH263Baseline = 11, - VAProfileJPEGBaseline = 12, - VAProfileH264ConstrainedBaseline = 13 -}; - -/* Currently defined entrypoints */ -enum VAEntrypoint { - VAEntrypointVLD = 1, - VAEntrypointIZZ = 2, - VAEntrypointIDCT = 3, - VAEntrypointMoComp = 4, - VAEntrypointDeblocking = 5, - VAEntrypointEncSlice = 6, /* slice level encode */ - VAEntrypointEncPicture = 7 /* pictuer encode, JPEG, etc */ -}; - - -struct psb_video_ctx { - struct list_head head; - struct file *filp; /* DRM device file pointer */ - int ctx_type; /* profile<<8|entrypoint */ - /* todo: more context specific data for multi-context support */ -}; - struct mrst_vbt { s8 signature[4]; /*4 bytes,"$GCT" */ u8 revision; @@ -574,10 +484,6 @@ struct drm_psb_private { uint8_t *vdc_reg; uint32_t gatt_free_offset; - /* IMG video context */ - struct list_head video_ctx; - - /* *Fencing / irq. @@ -869,12 +775,6 @@ struct drm_psb_private { int force_ta_mem_load;*/ atomic_t val_seq; - /* - *TODO: change this to be per drm-context. - */ - - struct psb_context context; - /* * LID-Switch */ @@ -1032,11 +932,6 @@ extern void psb_fence_or_sync(struct drm_file *file_priv, struct list_head *list, struct psb_ttm_fence_rep *fence_arg, struct ttm_fence_object **fence_p); -extern int psb_validate_kernel_buffer(struct psb_context *context, - struct ttm_buffer_object *bo, - uint32_t fence_class, - uint64_t set_flags, - uint64_t clr_flags); /* *psb_irq.c diff --git a/drivers/staging/gma500/psb_sgx.c b/drivers/staging/gma500/psb_sgx.c index 973134bc2345..91fbb6a11cae 100644 --- a/drivers/staging/gma500/psb_sgx.c +++ b/drivers/staging/gma500/psb_sgx.c @@ -64,113 +64,6 @@ struct psb_validate_buffer { uint32_t offset; int po_correct; }; -static int -psb_placement_fence_type(struct ttm_buffer_object *bo, - uint64_t set_val_flags, - uint64_t clr_val_flags, - uint32_t new_fence_class, - uint32_t *new_fence_type) -{ - int ret; - uint32_t n_fence_type; - /* - uint32_t set_flags = set_val_flags & 0xFFFFFFFF; - uint32_t clr_flags = clr_val_flags & 0xFFFFFFFF; - */ - struct ttm_fence_object *old_fence; - uint32_t old_fence_type; - struct ttm_placement placement; - - if (unlikely - (!(set_val_flags & - (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)))) { - DRM_ERROR - ("GPU access type (read / write) is not indicated.\n"); - return -EINVAL; - } - - /* User space driver doesn't set any TTM placement flags in - set_val_flags or clr_val_flags */ - placement.num_placement = 0;/* FIXME */ - placement.num_busy_placement = 0; - placement.fpfn = 0; - placement.lpfn = 0; - ret = psb_ttm_bo_check_placement(bo, &placement); - if (unlikely(ret != 0)) - return ret; - - switch (new_fence_class) { - default: - n_fence_type = _PSB_FENCE_TYPE_EXE; - } - - *new_fence_type = n_fence_type; - old_fence = (struct ttm_fence_object *) bo->sync_obj; - old_fence_type = (uint32_t) (unsigned long) bo->sync_obj_arg; - - if (old_fence && ((new_fence_class != old_fence->fence_class) || - ((n_fence_type ^ old_fence_type) & - old_fence_type))) { - ret = ttm_bo_wait(bo, 0, 1, 0); - if (unlikely(ret != 0)) - return ret; - } - /* - bo->proposed_flags = (bo->proposed_flags | set_flags) - & ~clr_flags & TTM_PL_MASK_MEMTYPE; - */ - return 0; -} - -int psb_validate_kernel_buffer(struct psb_context *context, - struct ttm_buffer_object *bo, - uint32_t fence_class, - uint64_t set_flags, uint64_t clr_flags) -{ - struct psb_validate_buffer *item; - uint32_t cur_fence_type; - int ret; - - if (unlikely(context->used_buffers >= PSB_NUM_VALIDATE_BUFFERS)) { - DRM_ERROR("Out of free validation buffer entries for " - "kernel buffer validation.\n"); - return -ENOMEM; - } - - item = &context->buffers[context->used_buffers]; - item->user_val_arg = NULL; - item->base.reserved = 0; - - ret = ttm_bo_reserve(bo, 1, 0, 1, context->val_seq); - if (unlikely(ret != 0)) - return ret; - - ret = psb_placement_fence_type(bo, set_flags, clr_flags, fence_class, - &cur_fence_type); - if (unlikely(ret != 0)) { - ttm_bo_unreserve(bo); - return ret; - } - - item->base.bo = ttm_bo_reference(bo); - item->base.new_sync_obj_arg = (void *) (unsigned long) cur_fence_type; - item->base.reserved = 1; - - /* Internal locking ??? FIXMEAC */ - list_add_tail(&item->base.head, &context->kern_validate_list); - context->used_buffers++; - /* - ret = ttm_bo_validate(bo, 1, 0, 0); - if (unlikely(ret != 0)) - goto out_unlock; - */ - item->offset = bo->offset; - item->flags = bo->mem.placement; - context->fence_types |= cur_fence_type; - - return ret; -} - void psb_fence_or_sync(struct drm_file *file_priv, uint32_t engine, uint32_t fence_types, -- GitLab From 0b35c063b2084258efee6f1bae583ee21bb07892 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:01:22 +0100 Subject: [PATCH 0489/5560] staging: gma500: pull mrst firmware stuff into its own header Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/mrst.h | 217 +++++++++++++++++++++++++++++++ drivers/staging/gma500/psb_drv.h | 197 +--------------------------- 2 files changed, 218 insertions(+), 196 deletions(-) create mode 100644 drivers/staging/gma500/mrst.h diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h new file mode 100644 index 000000000000..5e4aaeb3711b --- /dev/null +++ b/drivers/staging/gma500/mrst.h @@ -0,0 +1,217 @@ +/************************************************************************** + * Copyright (c) 2007-2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +/* MID device specific descriptors */ + +struct mrst_vbt { + s8 signature[4]; /*4 bytes,"$GCT" */ + u8 revision; + u8 size; + u8 checksum; + void *mrst_gct; +} __attribute__ ((packed)); + +struct mrst_timing_info { + u16 pixel_clock; + u8 hactive_lo; + u8 hblank_lo; + u8 hblank_hi:4; + u8 hactive_hi:4; + u8 vactive_lo; + u8 vblank_lo; + u8 vblank_hi:4; + u8 vactive_hi:4; + u8 hsync_offset_lo; + u8 hsync_pulse_width_lo; + u8 vsync_pulse_width_lo:4; + u8 vsync_offset_lo:4; + u8 vsync_pulse_width_hi:2; + u8 vsync_offset_hi:2; + u8 hsync_pulse_width_hi:2; + u8 hsync_offset_hi:2; + u8 width_mm_lo; + u8 height_mm_lo; + u8 height_mm_hi:4; + u8 width_mm_hi:4; + u8 hborder; + u8 vborder; + u8 unknown0:1; + u8 hsync_positive:1; + u8 vsync_positive:1; + u8 separate_sync:2; + u8 stereo:1; + u8 unknown6:1; + u8 interlaced:1; +} __attribute__((packed)); + +struct gct_r10_timing_info { + u16 pixel_clock; + u32 hactive_lo:8; + u32 hactive_hi:4; + u32 hblank_lo:8; + u32 hblank_hi:4; + u32 hsync_offset_lo:8; + u16 hsync_offset_hi:2; + u16 hsync_pulse_width_lo:8; + u16 hsync_pulse_width_hi:2; + u16 hsync_positive:1; + u16 rsvd_1:3; + u8 vactive_lo:8; + u16 vactive_hi:4; + u16 vblank_lo:8; + u16 vblank_hi:4; + u16 vsync_offset_lo:4; + u16 vsync_offset_hi:2; + u16 vsync_pulse_width_lo:4; + u16 vsync_pulse_width_hi:2; + u16 vsync_positive:1; + u16 rsvd_2:3; +} __attribute__((packed)); + +struct mrst_panel_descriptor_v1 { + u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ + /* 0x61190 if MIPI */ + u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ + u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ + /* Register 0x61210 */ + struct mrst_timing_info DTD;/*18 bytes, Standard definition */ + u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ + /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ + /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ + u16 Panel_MIPI_Display_Descriptor; + /*16 bits, Defined as follows: */ + /* if MIPI, 0x0000 if LVDS */ + /* Bit 0, Type, 2 bits, */ + /* 0: Type-1, */ + /* 1: Type-2, */ + /* 2: Type-3, */ + /* 3: Type-4 */ + /* Bit 2, Pixel Format, 4 bits */ + /* Bit0: 16bpp (not supported in LNC), */ + /* Bit1: 18bpp loosely packed, */ + /* Bit2: 18bpp packed, */ + /* Bit3: 24bpp */ + /* Bit 6, Reserved, 2 bits, 00b */ + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ + /* Bit 14, Reserved, 2 bits, 00b */ +} __attribute__ ((packed)); + +struct mrst_panel_descriptor_v2 { + u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ + /* 0x61190 if MIPI */ + u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ + u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ + /* Register 0x61210 */ + struct mrst_timing_info DTD;/*18 bytes, Standard definition */ + u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ + /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ + u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */ + /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ + u16 Panel_MIPI_Display_Descriptor; + /*16 bits, Defined as follows: */ + /* if MIPI, 0x0000 if LVDS */ + /* Bit 0, Type, 2 bits, */ + /* 0: Type-1, */ + /* 1: Type-2, */ + /* 2: Type-3, */ + /* 3: Type-4 */ + /* Bit 2, Pixel Format, 4 bits */ + /* Bit0: 16bpp (not supported in LNC), */ + /* Bit1: 18bpp loosely packed, */ + /* Bit2: 18bpp packed, */ + /* Bit3: 24bpp */ + /* Bit 6, Reserved, 2 bits, 00b */ + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ + /* Bit 14, Reserved, 2 bits, 00b */ +} __attribute__ ((packed)); + +union mrst_panel_rx { + struct{ + u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ + /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ + u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ + /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ + u16 SupportedVideoTransferMode:2; /*0: Non-burst only */ + /* 1: Burst and non-burst */ + /* 2/3: Reserved */ + u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ + u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ + u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ + u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ + u16 Rsvd:5;/*5 bits,00000b */ + } panelrx; + u16 panel_receiver; +} __attribute__ ((packed)); + +struct mrst_gct_v1 { + union{ /*8 bits,Defined as follows: */ + struct { + u8 PanelType:4; /*4 bits, Bit field for panels*/ + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ + /*2 bits,Specifies which of the*/ + u8 BootPanelIndex:2; + /* 4 panels to use by default*/ + u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ + /* the 4 MIPI DSI receivers to use*/ + } PD; + u8 PanelDescriptor; + }; + struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ + union mrst_panel_rx panelrx[4]; /* panel receivers*/ +} __attribute__ ((packed)); + +struct mrst_gct_v2 { + union{ /*8 bits,Defined as follows: */ + struct { + u8 PanelType:4; /*4 bits, Bit field for panels*/ + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ + /*2 bits,Specifies which of the*/ + u8 BootPanelIndex:2; + /* 4 panels to use by default*/ + u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ + /* the 4 MIPI DSI receivers to use*/ + } PD; + u8 PanelDescriptor; + }; + struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ + union mrst_panel_rx panelrx[4]; /* panel receivers*/ +} __attribute__ ((packed)); + +struct mrst_gct_data { + u8 bpi; /* boot panel index, number of panel used during boot */ + u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ + struct mrst_timing_info DTD; /* timing info for the selected panel */ + u32 Panel_Port_Control; + u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/ + u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + u32 PP_Cycle_Delay; + u16 Panel_Backlight_Inverter_Descriptor; + u16 Panel_MIPI_Display_Descriptor; +} __attribute__ ((packed)); + +#define MODE_SETTING_IN_CRTC 0x1 +#define MODE_SETTING_IN_ENCODER 0x2 +#define MODE_SETTING_ON_GOING 0x3 +#define MODE_SETTING_IN_DSR 0x4 +#define MODE_SETTING_ENCODER_DONE 0x8 +#define GCT_R10_HEADER_SIZE 16 +#define GCT_R10_DISPLAY_DESC_SIZE 28 + diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 014035f2e2e1..c2fd475a8637 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -29,6 +29,7 @@ #include "psb_intel_drv.h" #include "psb_gtt.h" #include "psb_powermgmt.h" +#include "mrst.h" #include "ttm/ttm_object.h" #include "psb_ttm_fence_driver.h" #include "psb_ttm_userobj_api.h" @@ -243,202 +244,6 @@ struct drm_psb_uopt { int pad; /*keep it here in case we use it in future*/ }; -struct mrst_vbt { - s8 signature[4]; /*4 bytes,"$GCT" */ - u8 revision; - u8 size; - u8 checksum; - void *mrst_gct; -} __attribute__ ((packed)); - -struct mrst_timing_info { - u16 pixel_clock; - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_offset_lo; - u8 hsync_pulse_width_lo; - u8 vsync_pulse_width_lo:4; - u8 vsync_offset_lo:4; - u8 vsync_pulse_width_hi:2; - u8 vsync_offset_hi:2; - u8 hsync_pulse_width_hi:2; - u8 hsync_offset_hi:2; - u8 width_mm_lo; - u8 height_mm_lo; - u8 height_mm_hi:4; - u8 width_mm_hi:4; - u8 hborder; - u8 vborder; - u8 unknown0:1; - u8 hsync_positive:1; - u8 vsync_positive:1; - u8 separate_sync:2; - u8 stereo:1; - u8 unknown6:1; - u8 interlaced:1; -} __attribute__((packed)); - -struct gct_r10_timing_info { - u16 pixel_clock; - u32 hactive_lo:8; - u32 hactive_hi:4; - u32 hblank_lo:8; - u32 hblank_hi:4; - u32 hsync_offset_lo:8; - u16 hsync_offset_hi:2; - u16 hsync_pulse_width_lo:8; - u16 hsync_pulse_width_hi:2; - u16 hsync_positive:1; - u16 rsvd_1:3; - u8 vactive_lo:8; - u16 vactive_hi:4; - u16 vblank_lo:8; - u16 vblank_hi:4; - u16 vsync_offset_lo:4; - u16 vsync_offset_hi:2; - u16 vsync_pulse_width_lo:4; - u16 vsync_pulse_width_hi:2; - u16 vsync_positive:1; - u16 rsvd_2:3; -} __attribute__((packed)); - -struct mrst_panel_descriptor_v1 { - u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ - /* Register 0x61210 */ - struct mrst_timing_info DTD;/*18 bytes, Standard definition */ - u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ - /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ - /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ - u16 Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); - -struct mrst_panel_descriptor_v2 { - u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ - /* Register 0x61210 */ - struct mrst_timing_info DTD;/*18 bytes, Standard definition */ - u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ - /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ - u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */ - /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ - u16 Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); - -union mrst_panel_rx { - struct{ - u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ - /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ - u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ - /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ - u16 SupportedVideoTransferMode:2; /*0: Non-burst only */ - /* 1: Burst and non-burst */ - /* 2/3: Reserved */ - u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ - u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ - u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ - u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ - u16 Rsvd:5;/*5 bits,00000b */ - } panelrx; - u16 panel_receiver; -} __attribute__ ((packed)); - -struct mrst_gct_v1 { - union{ /*8 bits,Defined as follows: */ - struct { - u8 PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - u8 BootPanelIndex:2; - /* 4 panels to use by default*/ - u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - u8 PanelDescriptor; - }; - struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ - union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); - -struct mrst_gct_v2 { - union{ /*8 bits,Defined as follows: */ - struct { - u8 PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - u8 BootPanelIndex:2; - /* 4 panels to use by default*/ - u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - u8 PanelDescriptor; - }; - struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ - union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); - -struct mrst_gct_data { - u8 bpi; /* boot panel index, number of panel used during boot */ - u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ - struct mrst_timing_info DTD; /* timing info for the selected panel */ - u32 Panel_Port_Control; - u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u32 PP_Cycle_Delay; - u16 Panel_Backlight_Inverter_Descriptor; - u16 Panel_MIPI_Display_Descriptor; -} __attribute__ ((packed)); - -#define MODE_SETTING_IN_CRTC 0x1 -#define MODE_SETTING_IN_ENCODER 0x2 -#define MODE_SETTING_ON_GOING 0x3 -#define MODE_SETTING_IN_DSR 0x4 -#define MODE_SETTING_ENCODER_DONE 0x8 -#define GCT_R10_HEADER_SIZE 16 -#define GCT_R10_DISPLAY_DESC_SIZE 28 - struct drm_psb_private { /* * DSI info. -- GitLab From aea74b6567997bbb670357caa57aff39c8c390a5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:01:31 +0100 Subject: [PATCH 0490/5560] staging: gma500: kill off TTM We are not using TTM, we are not going to use TTM either Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/Makefile | 7 - drivers/staging/gma500/psb_2d.c | 1 - drivers/staging/gma500/psb_buffer.c | 423 ------------ drivers/staging/gma500/psb_drm.h | 111 ---- drivers/staging/gma500/psb_drv.c | 227 +------ drivers/staging/gma500/psb_drv.h | 110 --- drivers/staging/gma500/psb_fb.c | 5 +- drivers/staging/gma500/psb_fence.c | 122 ---- drivers/staging/gma500/psb_gtt.c | 2 +- drivers/staging/gma500/psb_sgx.c | 131 ---- drivers/staging/gma500/psb_sgx.h | 32 - drivers/staging/gma500/psb_ttm_fence.c | 605 ----------------- drivers/staging/gma500/psb_ttm_fence_api.h | 272 -------- drivers/staging/gma500/psb_ttm_fence_driver.h | 302 --------- drivers/staging/gma500/psb_ttm_fence_user.c | 237 ------- drivers/staging/gma500/psb_ttm_fence_user.h | 140 ---- drivers/staging/gma500/psb_ttm_glue.c | 349 ---------- .../staging/gma500/psb_ttm_placement_user.c | 628 ------------------ drivers/staging/gma500/psb_ttm_userobj_api.h | 85 --- 19 files changed, 17 insertions(+), 3772 deletions(-) delete mode 100644 drivers/staging/gma500/psb_buffer.c delete mode 100644 drivers/staging/gma500/psb_fence.c delete mode 100644 drivers/staging/gma500/psb_sgx.c delete mode 100644 drivers/staging/gma500/psb_sgx.h delete mode 100644 drivers/staging/gma500/psb_ttm_fence.c delete mode 100644 drivers/staging/gma500/psb_ttm_fence_api.h delete mode 100644 drivers/staging/gma500/psb_ttm_fence_driver.h delete mode 100644 drivers/staging/gma500/psb_ttm_fence_user.c delete mode 100644 drivers/staging/gma500/psb_ttm_fence_user.h delete mode 100644 drivers/staging/gma500/psb_ttm_glue.c delete mode 100644 drivers/staging/gma500/psb_ttm_placement_user.c delete mode 100644 drivers/staging/gma500/psb_ttm_userobj_api.h diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile index 383a574a5d1d..4d7aabe7e37c 100644 --- a/drivers/staging/gma500/Makefile +++ b/drivers/staging/gma500/Makefile @@ -16,15 +16,8 @@ psb_gfx-y += psb_bl.o \ psb_intel_modes.o \ psb_intel_sdvo.o \ psb_reset.o \ - psb_sgx.o \ psb_pvr_glue.o \ - psb_buffer.o \ - psb_fence.o \ psb_mmu.o \ - psb_ttm_glue.o \ - psb_ttm_fence.o \ - psb_ttm_fence_user.o \ - psb_ttm_placement_user.o \ psb_powermgmt.o \ psb_irq.o \ mrst_crtc.o \ diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c index e4cae5d77d01..9a0691f75d15 100644 --- a/drivers/staging/gma500/psb_2d.c +++ b/drivers/staging/gma500/psb_2d.c @@ -40,7 +40,6 @@ #include "psb_reg.h" #include "psb_drv.h" #include "psb_fb.h" -#include "psb_sgx.h" void psb_spank(struct drm_psb_private *dev_priv) { diff --git a/drivers/staging/gma500/psb_buffer.c b/drivers/staging/gma500/psb_buffer.c deleted file mode 100644 index b5d79a589db1..000000000000 --- a/drivers/staging/gma500/psb_buffer.c +++ /dev/null @@ -1,423 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ -#include "ttm/ttm_placement.h" -#include "ttm/ttm_execbuf_util.h" -#include "psb_ttm_fence_api.h" -#include -#include "psb_drv.h" - -#define DRM_MEM_TTM 26 - -struct drm_psb_ttm_backend { - struct ttm_backend base; - struct page **pages; - unsigned int desired_tile_stride; - unsigned int hw_tile_stride; - int mem_type; - unsigned long offset; - unsigned long num_pages; -}; - -/* - * MSVDX/TOPAZ GPU virtual space looks like this - * (We currently use only one MMU context). - * PSB_MEM_MMU_START: from 0x00000000~0xe000000, for generic buffers - * TTM_PL_CI: from 0xe0000000+half GTT space, for camear/video buffer sharing - * TTM_PL_RAR: from TTM_PL_CI+CI size, for RAR/video buffer sharing - * TTM_PL_TT: from TTM_PL_RAR+RAR size, for buffers need to mapping into GTT - */ -static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ - - struct drm_psb_private *dev_priv = - container_of(bdev, struct drm_psb_private, bdev); - struct psb_gtt *pg = dev_priv->pg; - - switch (type) { - case TTM_PL_SYSTEM: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_CACHED | - TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case DRM_PSB_MEM_MMU: - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_CMA; - man->gpu_offset = PSB_MEM_MMU_START; - man->available_caching = TTM_PL_FLAG_CACHED | - TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - case TTM_PL_TT: /* Mappable GATT memory */ - man->func = &ttm_bo_manager_func; -#ifdef PSB_WORKING_HOST_MMU_ACCESS - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; -#else - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_CMA; -#endif - man->available_caching = TTM_PL_FLAG_CACHED | - TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - man->gpu_offset = pg->mmu_gatt_start; - break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned) type); - return -EINVAL; - } - return 0; -} - - -static void psb_evict_mask(struct ttm_buffer_object *bo, - struct ttm_placement *placement) -{ - static uint32_t cur_placement; - - cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEM; - cur_placement |= TTM_PL_FLAG_SYSTEM; - - placement->fpfn = 0; - placement->lpfn = 0; - placement->num_placement = 1; - placement->placement = &cur_placement; - placement->num_busy_placement = 0; - placement->busy_placement = NULL; - - /* all buffers evicted to system memory */ - /* return cur_placement | TTM_PL_FLAG_SYSTEM; */ -} - -static int psb_invalidate_caches(struct ttm_bo_device *bdev, - uint32_t placement) -{ - return 0; -} - -static int psb_move_blit(struct ttm_buffer_object *bo, - bool evict, bool no_wait, - struct ttm_mem_reg *new_mem) -{ - BUG(); - return 0; -} - -/* - * Flip destination ttm into GATT, - * then blit and subsequently move out again. - */ - -static int psb_move_flip(struct ttm_buffer_object *bo, - bool evict, bool interruptible, bool no_wait, - struct ttm_mem_reg *new_mem) -{ - /*struct ttm_bo_device *bdev = bo->bdev;*/ - struct ttm_mem_reg tmp_mem; - int ret; - struct ttm_placement placement; - uint32_t flags = TTM_PL_FLAG_TT; - - tmp_mem = *new_mem; - tmp_mem.mm_node = NULL; - - placement.fpfn = 0; - placement.lpfn = 0; - placement.num_placement = 1; - placement.placement = &flags; - placement.num_busy_placement = 0; /* FIXME */ - placement.busy_placement = NULL; - - ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, - false, no_wait); - if (ret) - return ret; - ret = ttm_tt_bind(bo->ttm, &tmp_mem); - if (ret) - goto out_cleanup; - ret = psb_move_blit(bo, true, no_wait, &tmp_mem); - if (ret) - goto out_cleanup; - - ret = ttm_bo_move_ttm(bo, evict, false, no_wait, new_mem); -out_cleanup: - if (tmp_mem.mm_node) { - drm_mm_put_block(tmp_mem.mm_node); - tmp_mem.mm_node = NULL; - } - return ret; -} - -static int psb_move(struct ttm_buffer_object *bo, - bool evict, bool interruptible, bool no_wait_reserve, - bool no_wait, struct ttm_mem_reg *new_mem) -{ - struct ttm_mem_reg *old_mem = &bo->mem; - - if ((old_mem->mem_type == TTM_PL_RAR) || - (new_mem->mem_type == TTM_PL_RAR)) { - if (old_mem->mm_node) { - spin_lock(&bo->glob->lru_lock); - drm_mm_put_block(old_mem->mm_node); - spin_unlock(&bo->glob->lru_lock); - } - old_mem->mm_node = NULL; - *old_mem = *new_mem; - } else if (old_mem->mem_type == TTM_PL_SYSTEM) { - return ttm_bo_move_memcpy(bo, evict, false, no_wait, new_mem); - } else if (new_mem->mem_type == TTM_PL_SYSTEM) { - int ret = psb_move_flip(bo, evict, interruptible, - no_wait, new_mem); - if (unlikely(ret != 0)) { - if (ret == -ERESTART) - return ret; - else - return ttm_bo_move_memcpy(bo, evict, false, - no_wait, new_mem); - } - } else { - if (psb_move_blit(bo, evict, no_wait, new_mem)) - return ttm_bo_move_memcpy(bo, evict, false, no_wait, - new_mem); - } - return 0; -} - -static int drm_psb_tbe_populate(struct ttm_backend *backend, - unsigned long num_pages, - struct page **pages, - struct page *dummy_read_page, - dma_addr_t *dma_addrs) -{ - struct drm_psb_ttm_backend *psb_be = - container_of(backend, struct drm_psb_ttm_backend, base); - - psb_be->pages = pages; - return 0; -} - -static int drm_psb_tbe_unbind(struct ttm_backend *backend) -{ - struct ttm_bo_device *bdev = backend->bdev; - struct drm_psb_private *dev_priv = - container_of(bdev, struct drm_psb_private, bdev); - struct drm_psb_ttm_backend *psb_be = - container_of(backend, struct drm_psb_ttm_backend, base); - struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu); - /* struct ttm_mem_type_manager *man = &bdev->man[psb_be->mem_type]; */ - - if (psb_be->mem_type == TTM_PL_TT) { - uint32_t gatt_p_offset = - (psb_be->offset - dev_priv->pg->mmu_gatt_start) - >> PAGE_SHIFT; - - (void) psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset, - psb_be->num_pages, - psb_be->desired_tile_stride, - psb_be->hw_tile_stride, 0); - } - - psb_mmu_remove_pages(pd, psb_be->offset, - psb_be->num_pages, - psb_be->desired_tile_stride, - psb_be->hw_tile_stride); - - return 0; -} - -static int drm_psb_tbe_bind(struct ttm_backend *backend, - struct ttm_mem_reg *bo_mem) -{ - struct ttm_bo_device *bdev = backend->bdev; - struct drm_psb_private *dev_priv = - container_of(bdev, struct drm_psb_private, bdev); - struct drm_psb_ttm_backend *psb_be = - container_of(backend, struct drm_psb_ttm_backend, base); - struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu); - struct ttm_mem_type_manager *man = &bdev->man[bo_mem->mem_type]; - struct drm_mm_node *mm_node = bo_mem->mm_node; - int type; - int ret = 0; - - psb_be->mem_type = bo_mem->mem_type; - psb_be->num_pages = bo_mem->num_pages; - psb_be->desired_tile_stride = 0; - psb_be->hw_tile_stride = 0; - psb_be->offset = (mm_node->start << PAGE_SHIFT) + - man->gpu_offset; - - type = - (bo_mem-> - placement & TTM_PL_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0; - - if (psb_be->mem_type == TTM_PL_TT) { - uint32_t gatt_p_offset = - (psb_be->offset - dev_priv->pg->mmu_gatt_start) - >> PAGE_SHIFT; - - ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages, - gatt_p_offset, - psb_be->num_pages, - psb_be->desired_tile_stride, - psb_be->hw_tile_stride, type); - } - - ret = psb_mmu_insert_pages(pd, psb_be->pages, - psb_be->offset, psb_be->num_pages, - psb_be->desired_tile_stride, - psb_be->hw_tile_stride, type); - if (ret) - goto out_err; - - return 0; -out_err: - drm_psb_tbe_unbind(backend); - return ret; - -} - -static void drm_psb_tbe_clear(struct ttm_backend *backend) -{ - struct drm_psb_ttm_backend *psb_be = - container_of(backend, struct drm_psb_ttm_backend, base); - - psb_be->pages = NULL; - return; -} - -static void drm_psb_tbe_destroy(struct ttm_backend *backend) -{ - struct drm_psb_ttm_backend *psb_be = - container_of(backend, struct drm_psb_ttm_backend, base); - - if (backend) - kfree(psb_be); -} - -static struct ttm_backend_func psb_ttm_backend = { - .populate = drm_psb_tbe_populate, - .clear = drm_psb_tbe_clear, - .bind = drm_psb_tbe_bind, - .unbind = drm_psb_tbe_unbind, - .destroy = drm_psb_tbe_destroy, -}; - -static struct ttm_backend *drm_psb_tbe_init(struct ttm_bo_device *bdev) -{ - struct drm_psb_ttm_backend *psb_be; - - psb_be = kzalloc(sizeof(*psb_be), GFP_KERNEL); - if (!psb_be) - return NULL; - psb_be->pages = NULL; - psb_be->base.func = &psb_ttm_backend; - psb_be->base.bdev = bdev; - return &psb_be->base; -} - -static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct drm_psb_private *dev_priv = - container_of(bdev, struct drm_psb_private, bdev); - struct psb_gtt *pg = dev_priv->pg; - struct drm_mm_node *mm_node = mem->mm_node; - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - return 0; - case TTM_PL_TT: - mem->bus.offset = mm_node->start << PAGE_SHIFT; - mem->bus.base = pg->gatt_start; - mem->bus.is_iomem = false; - /* Don't know whether it is IO_MEM, this flag - used in vm_fault handle */ - break; - case DRM_PSB_MEM_MMU: - mem->bus.offset = mm_node->start << PAGE_SHIFT; - mem->bus.base = 0x00000000; - break; - default: - return -EINVAL; - } - return 0; -} - -static void psb_ttm_io_mem_free(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ -} - -/* - * Use this memory type priority if no eviction is needed. - */ -/* -static uint32_t psb_mem_prios[] = { - TTM_PL_CI, - TTM_PL_RAR, - TTM_PL_TT, - DRM_PSB_MEM_MMU, - TTM_PL_SYSTEM -}; -*/ -/* - * Use this memory type priority if need to evict. - */ -/* -static uint32_t psb_busy_prios[] = { - TTM_PL_TT, - TTM_PL_CI, - TTM_PL_RAR, - DRM_PSB_MEM_MMU, - TTM_PL_SYSTEM -}; -*/ -struct ttm_bo_driver psb_ttm_bo_driver = { -/* - .mem_type_prio = psb_mem_prios, - .mem_busy_prio = psb_busy_prios, - .num_mem_type_prio = ARRAY_SIZE(psb_mem_prios), - .num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios), -*/ - .create_ttm_backend_entry = &drm_psb_tbe_init, - .invalidate_caches = &psb_invalidate_caches, - .init_mem_type = &psb_init_mem_type, - .evict_flags = &psb_evict_mask, - .move = &psb_move, - .verify_access = &psb_verify_access, - .sync_obj_signaled = &ttm_fence_sync_obj_signaled, - .sync_obj_wait = &ttm_fence_sync_obj_wait, - .sync_obj_flush = &ttm_fence_sync_obj_flush, - .sync_obj_unref = &ttm_fence_sync_obj_unref, - .sync_obj_ref = &ttm_fence_sync_obj_ref, - .io_mem_reserve = &psb_ttm_io_mem_reserve, - .io_mem_free = &psb_ttm_io_mem_free -}; diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h index fb9b4245bada..28862c7e0949 100644 --- a/drivers/staging/gma500/psb_drm.h +++ b/drivers/staging/gma500/psb_drm.h @@ -28,9 +28,6 @@ #include "drm_mode.h" #endif -#include "psb_ttm_fence_user.h" -#include "psb_ttm_placement_user.h" - #define DRM_PSB_SAREA_MAJOR 0 #define DRM_PSB_SAREA_MINOR 2 #define PSB_FIXED_SHIFT 16 @@ -41,15 +38,6 @@ * Public memory types. */ -#define DRM_PSB_MEM_MMU TTM_PL_PRIV1 -#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1 - -#define TTM_PL_CI TTM_PL_PRIV0 -#define TTM_PL_FLAG_CI TTM_PL_FLAG_PRIV0 - -#define TTM_PL_RAR TTM_PL_PRIV2 -#define TTM_PL_FLAG_RAR TTM_PL_FLAG_PRIV2 - typedef s32 psb_fixed; typedef u32 psb_ufixed; @@ -112,111 +100,12 @@ struct drm_psb_sarea { u32 num_active_scanouts; }; -#define PSB_RELOC_MAGIC 0x67676767 -#define PSB_RELOC_SHIFT_MASK 0x0000FFFF -#define PSB_RELOC_SHIFT_SHIFT 0 -#define PSB_RELOC_ALSHIFT_MASK 0xFFFF0000 -#define PSB_RELOC_ALSHIFT_SHIFT 16 - -#define PSB_RELOC_OP_OFFSET 0 /* Offset of the indicated - * buffer - */ - -struct drm_psb_reloc { - u32 reloc_op; - u32 where; /* offset in destination buffer */ - u32 buffer; /* Buffer reloc applies to */ - u32 mask; /* Destination format: */ - u32 shift; /* Destination format: */ - u32 pre_add; /* Destination format: */ - u32 background; /* Destination add */ - u32 dst_buffer; /* Destination buffer. Index into buffer_list */ - u32 arg0; /* Reloc-op dependant */ - u32 arg1; -}; - - #define PSB_GPU_ACCESS_READ (1ULL << 32) #define PSB_GPU_ACCESS_WRITE (1ULL << 33) #define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE) #define PSB_BO_FLAG_COMMAND (1ULL << 52) -#define PSB_ENGINE_2D 0 -#define PSB_ENGINE_VIDEO 1 -#define LNC_ENGINE_ENCODE 5 - -/* - * For this fence class we have a couple of - * fence types. - */ - -#define _PSB_FENCE_EXE_SHIFT 0 -#define _PSB_FENCE_FEEDBACK_SHIFT 4 - -#define _PSB_FENCE_TYPE_EXE (1 << _PSB_FENCE_EXE_SHIFT) -#define _PSB_FENCE_TYPE_FEEDBACK (1 << _PSB_FENCE_FEEDBACK_SHIFT) - -#define PSB_NUM_ENGINES 6 - - -#define PSB_FEEDBACK_OP_VISTEST (1 << 0) - -struct drm_psb_extension_rep { - s32 exists; - u32 driver_ioctl_offset; - u32 sarea_offset; - u32 major; - u32 minor; - u32 pl; -}; - -#define DRM_PSB_EXT_NAME_LEN 128 - -union drm_psb_extension_arg { - char extension[DRM_PSB_EXT_NAME_LEN]; - struct drm_psb_extension_rep rep; -}; - -struct psb_validate_req { - u64 set_flags; - u64 clear_flags; - u64 next; - u64 presumed_gpu_offset; - u32 buffer_handle; - u32 presumed_flags; - u32 group; - u32 pad64; -}; - -struct psb_validate_rep { - u64 gpu_offset; - u32 placement; - u32 fence_type_mask; -}; - -#define PSB_USE_PRESUMED (1 << 0) - -struct psb_validate_arg { - int handled; - int ret; - union { - struct psb_validate_req req; - struct psb_validate_rep rep; - } d; -}; - - -#define DRM_PSB_FENCE_NO_USER (1 << 0) - -struct psb_ttm_fence_rep { - u32 handle; - u32 fence_class; - u32 fence_type; - u32 signaled_types; - u32 error; -}; - /* * Feedback components: */ diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 6e9954c53411..ba08b071d662 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -111,9 +111,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #define DRM_IOCTL_PSB_GTT_UNMAP \ DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \ struct psb_gtt_mapping_arg) -#define DRM_IOCTL_PSB_GETPAGEADDRS \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\ - struct drm_psb_getpageaddrs_arg) #define DRM_IOCTL_PSB_UPDATE_GUARD \ DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \ uint32_t) @@ -130,69 +127,8 @@ MODULE_DEVICE_TABLE(pci, pciidlist); DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \ struct drm_psb_get_pipe_from_crtc_id_arg) -/* - * TTM execbuf extension. - */ - -#define DRM_PSB_CMDBUF 0x23 -#define DRM_PSB_SCENE_UNREF 0x24 #define DRM_IOCTL_PSB_KMS_OFF DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE) #define DRM_IOCTL_PSB_KMS_ON DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE) -/* - * TTM placement user extension. - */ - -#define DRM_PSB_PLACEMENT_OFFSET (DRM_PSB_SCENE_UNREF + 1) - -#define DRM_PSB_TTM_PL_CREATE (TTM_PL_CREATE + DRM_PSB_PLACEMENT_OFFSET) -#define DRM_PSB_TTM_PL_REFERENCE (TTM_PL_REFERENCE + DRM_PSB_PLACEMENT_OFFSET) -#define DRM_PSB_TTM_PL_UNREF (TTM_PL_UNREF + DRM_PSB_PLACEMENT_OFFSET) -#define DRM_PSB_TTM_PL_SYNCCPU (TTM_PL_SYNCCPU + DRM_PSB_PLACEMENT_OFFSET) -#define DRM_PSB_TTM_PL_WAITIDLE (TTM_PL_WAITIDLE + DRM_PSB_PLACEMENT_OFFSET) -#define DRM_PSB_TTM_PL_SETSTATUS (TTM_PL_SETSTATUS + DRM_PSB_PLACEMENT_OFFSET) -#define DRM_PSB_TTM_PL_CREATE_UB (TTM_PL_CREATE_UB + DRM_PSB_PLACEMENT_OFFSET) - -/* - * TTM fence extension. - */ - -#define DRM_PSB_FENCE_OFFSET (DRM_PSB_TTM_PL_CREATE_UB + 1) -#define DRM_PSB_TTM_FENCE_SIGNALED (TTM_FENCE_SIGNALED + DRM_PSB_FENCE_OFFSET) -#define DRM_PSB_TTM_FENCE_FINISH (TTM_FENCE_FINISH + DRM_PSB_FENCE_OFFSET) -#define DRM_PSB_TTM_FENCE_UNREF (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET) - -#define DRM_PSB_FLIP (DRM_PSB_TTM_FENCE_UNREF + 1) /*20*/ - -#define DRM_IOCTL_PSB_TTM_PL_CREATE \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\ - union ttm_pl_create_arg) -#define DRM_IOCTL_PSB_TTM_PL_REFERENCE \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_REFERENCE,\ - union ttm_pl_reference_arg) -#define DRM_IOCTL_PSB_TTM_PL_UNREF \ - DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_UNREF,\ - struct ttm_pl_reference_req) -#define DRM_IOCTL_PSB_TTM_PL_SYNCCPU \ - DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SYNCCPU,\ - struct ttm_pl_synccpu_arg) -#define DRM_IOCTL_PSB_TTM_PL_WAITIDLE \ - DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WAITIDLE,\ - struct ttm_pl_waitidle_arg) -#define DRM_IOCTL_PSB_TTM_PL_SETSTATUS \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SETSTATUS,\ - union ttm_pl_setstatus_arg) -#define DRM_IOCTL_PSB_TTM_PL_CREATE_UB \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE_UB,\ - union ttm_pl_create_ub_arg) -#define DRM_IOCTL_PSB_TTM_FENCE_SIGNALED \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_SIGNALED, \ - union ttm_fence_signaled_arg) -#define DRM_IOCTL_PSB_TTM_FENCE_FINISH \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_FINISH, \ - union ttm_fence_finish_arg) -#define DRM_IOCTL_PSB_TTM_FENCE_UNREF \ - DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF, \ - struct ttm_fence_unref_arg) static int psb_vt_leave_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -246,35 +182,12 @@ static struct drm_ioctl_desc psb_ioctls[] = { PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP, psb_gtt_unmap_meminfo_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_GETPAGEADDRS, - psb_getpageaddrs_ioctl, - DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, psb_intel_get_pipe_from_crtc_id, 0), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_REFERENCE, psb_pl_reference_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_UNREF, psb_pl_unref_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SYNCCPU, psb_pl_synccpu_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_WAITIDLE, psb_pl_waitidle_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SETSTATUS, psb_pl_setstatus_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE_UB, psb_pl_ub_create_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_SIGNALED, - psb_fence_signaled_ioctl, DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_FINISH, psb_fence_finish_ioctl, - DRM_AUTH), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_UNREF, psb_fence_unref_ioctl, - DRM_AUTH), }; static void psb_set_uopt(struct drm_psb_uopt *uopt) @@ -289,20 +202,7 @@ static void psb_lastclose(struct drm_device *dev) static void psb_do_takedown(struct drm_device *dev) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->bdev; - - - if (dev_priv->have_mem_mmu) { - ttm_bo_clean_mm(bdev, DRM_PSB_MEM_MMU); - dev_priv->have_mem_mmu = 0; - } - - if (dev_priv->have_tt) { - ttm_bo_clean_mm(bdev, TTM_PL_TT); - dev_priv->have_tt = 0; - } + /* FIXME: do we need to clean up the gtt here ? */ } void mrst_get_fuse_settings(struct drm_device *dev) @@ -551,7 +451,6 @@ static int psb_do_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->bdev; struct psb_gtt *pg = dev_priv->pg; uint32_t stolen_gtt; @@ -560,16 +459,6 @@ static int psb_do_init(struct drm_device *dev) int ret = -ENOMEM; - - /* - * Initialize sequence numbers for the different command - * submission mechanisms. - */ - - dev_priv->sequence[PSB_ENGINE_2D] = 0; - dev_priv->sequence[PSB_ENGINE_VIDEO] = 0; - dev_priv->sequence[LNC_ENGINE_ENCODE] = 0; - if (pg->mmu_gatt_start & 0x0FFFFFFF) { DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n"); ret = -EINVAL; @@ -620,22 +509,6 @@ static int psb_do_init(struct drm_device *dev) PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); - /* TT region managed by TTM. */ - if (!ttm_bo_init_mm(bdev, TTM_PL_TT, pg->gatt_pages)) { - dev_priv->have_tt = 1; - dev_priv->sizes.tt_size = - (tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2; - } - - if (!ttm_bo_init_mm(bdev, - DRM_PSB_MEM_MMU, - PSB_MEM_TT_START >> PAGE_SHIFT)) { - dev_priv->have_mem_mmu = 1; - dev_priv->sizes.mmu_size = - PSB_MEM_TT_START / (1024*1024); - } - - PSB_DEBUG_INIT("Init MSVDX\n"); return 0; out_err: psb_do_takedown(dev); @@ -682,14 +555,6 @@ static int psb_driver_unload(struct drm_device *dev) __free_page(dev_priv->scratch_page); dev_priv->scratch_page = NULL; } - if (dev_priv->has_bo_device) { - ttm_bo_device_release(&dev_priv->bdev); - dev_priv->has_bo_device = 0; - } - if (dev_priv->has_fence_device) { - ttm_fence_device_release(&dev_priv->fdev); - dev_priv->has_fence_device = 0; - } if (dev_priv->vdc_reg) { iounmap(dev_priv->vdc_reg); dev_priv->vdc_reg = NULL; @@ -699,12 +564,6 @@ static int psb_driver_unload(struct drm_device *dev) dev_priv->sgx_reg = NULL; } - if (dev_priv->tdev) - ttm_object_device_release(&dev_priv->tdev); - - if (dev_priv->has_global) - psb_ttm_global_release(dev_priv); - kfree(dev_priv); dev->dev_private = NULL; @@ -721,7 +580,6 @@ static int psb_driver_unload(struct drm_device *dev) static int psb_driver_load(struct drm_device *dev, unsigned long chipset) { struct drm_psb_private *dev_priv; - struct ttm_bo_device *bdev; unsigned long resource_start; struct psb_gtt *pg; unsigned long irqflags; @@ -738,24 +596,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->num_pipe = 2; dev_priv->dev = dev; - bdev = &dev_priv->bdev; - - ret = psb_ttm_global_init(dev_priv); - if (unlikely(ret != 0)) - goto out_err; - dev_priv->has_global = 1; - - dev_priv->tdev = ttm_object_device_init - (dev_priv->mem_global_ref.object, PSB_OBJECT_HASH_ORDER); - if (unlikely(dev_priv->tdev == NULL)) - goto out_err; mutex_init(&dev_priv->temp_mem); mutex_init(&dev_priv->cmdbuf_mutex); mutex_init(&dev_priv->reset_mutex); - -/* mutex_init(&dev_priv->dsr_mutex); */ - spin_lock_init(&dev_priv->reloc_lock); DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue); @@ -788,25 +632,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) psb_intel_init_bios(dev); } - PSB_DEBUG_INIT("Init TTM fence and BO driver\n"); - /* Init OSPM support */ ospm_power_init(dev); - ret = psb_ttm_fence_device_init(&dev_priv->fdev); - if (unlikely(ret != 0)) - goto out_err; - - dev_priv->has_fence_device = 1; - ret = ttm_bo_device_init(bdev, - dev_priv->bo_global_ref.ref.object, - &psb_ttm_bo_driver, - DRM_PSB_FILE_PAGE_OFFSET, false); - if (unlikely(ret != 0)) - goto out_err; - dev_priv->has_bo_device = 1; - ttm_lock_init(&dev_priv->ttm_lock); - ret = -ENOMEM; dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO); @@ -846,10 +674,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0); psb_mmu_set_pd_context(dev_priv->pf_pd, 1); - spin_lock_init(&dev_priv->sequence_lock); - - PSB_DEBUG_INIT("Begin to init MSVDX/Topaz\n"); - ret = psb_do_init(dev); if (ret) return ret; @@ -901,11 +725,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) #endif /*Intel drm driver load is done, continue doing pvr load*/ DRM_DEBUG("Pvr driver load\n"); - -/* if (PVRCore_Init() < 0) - goto out_err; */ -/* if (MRSTLFBInit(dev) < 0) - goto out_err;*/ return 0; out_err: psb_driver_unload(dev); @@ -921,40 +740,13 @@ int psb_driver_device_is_agp(struct drm_device *dev) static int psb_vt_leave_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_psb_private *dev_priv = psb_priv(dev); - struct ttm_bo_device *bdev = &dev_priv->bdev; - struct ttm_mem_type_manager *man; - int ret; - - ret = ttm_vt_lock(&dev_priv->ttm_lock, 1, - psb_fpriv(file_priv)->tfile); - if (unlikely(ret != 0)) - return ret; - - ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_TT); - if (unlikely(ret != 0)) - goto out_unlock; - - man = &bdev->man[TTM_PL_TT]; - -#if 0 /* What to do with this ? */ - if (unlikely(!drm_mm_clean(&man->manager))) - DRM_INFO("Warning: GATT was not clean after VT switch.\n"); -#endif - - ttm_bo_swapout_all(&dev_priv->bdev); - return 0; -out_unlock: - (void) ttm_vt_unlock(&dev_priv->ttm_lock); - return ret; } static int psb_vt_enter_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_psb_private *dev_priv = psb_priv(dev); - return ttm_vt_unlock(&dev_priv->ttm_lock); + return 0; } static int psb_sizes_ioctl(struct drm_device *dev, void *data, @@ -1636,8 +1428,7 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, dev_priv->rpm_enabled = 1; } /* - * The driver private ioctls and TTM ioctls should be - * thread-safe. + * The driver private ioctls should be thread-safe. */ if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) @@ -1675,6 +1466,16 @@ static void psb_remove(struct pci_dev *pdev) drm_put_dev(dev); } +static int psb_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int psb_release(struct inode *inode, struct file *filp) +{ + return 0; +} + static const struct dev_pm_ops psb_pm_ops = { .runtime_suspend = psb_runtime_suspend, @@ -1714,7 +1515,7 @@ static struct drm_driver driver = { .open = psb_open, .release = psb_release, .unlocked_ioctl = psb_unlocked_ioctl, - .mmap = psb_mmap, + /* .mmap = psb_mmap, */ .poll = psb_poll, .fasync = drm_fasync, .read = drm_read, diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index c2fd475a8637..aad09fb2a358 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -30,11 +30,6 @@ #include "psb_gtt.h" #include "psb_powermgmt.h" #include "mrst.h" -#include "ttm/ttm_object.h" -#include "psb_ttm_fence_driver.h" -#include "psb_ttm_userobj_api.h" -#include "ttm/ttm_bo_driver.h" -#include "ttm/ttm_lock.h" /*Append new drm mode definition here, align with libdrm definition*/ #define DRM_MODE_SCALE_NO_SCALE 2 @@ -92,9 +87,6 @@ enum { #define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT) #define PSB_NUM_VALIDATE_BUFFERS 2048 -#define PSB_MEM_MMU_START 0x00000000 -#define PSB_MEM_TT_START 0xE0000000 - /* *Flags for external memory type field. */ @@ -251,22 +243,8 @@ struct drm_psb_private { void * dbi_dsr_info; void * dsi_configs[2]; - /* - *TTM Glue. - */ - - struct drm_global_reference mem_global_ref; - struct ttm_bo_global_ref bo_global_ref; - int has_global; - struct drm_device *dev; - struct ttm_object_device *tdev; - struct ttm_fence_device fdev; - struct ttm_bo_device bdev; - struct ttm_lock ttm_lock; struct vm_operations_struct *ttm_vm_ops; - int has_fence_device; - int has_bo_device; unsigned long chipset; @@ -276,11 +254,7 @@ struct drm_psb_private { /*GTT Memory manager*/ struct psb_gtt_mm *gtt_mm; - struct page *scratch_page; - uint32_t sequence[PSB_NUM_ENGINES]; - uint32_t last_sequence[PSB_NUM_ENGINES]; - uint32_t last_submitted_seq[PSB_NUM_ENGINES]; struct psb_mmu_driver *mmu; struct psb_mmu_pd *pf_pd; @@ -299,7 +273,6 @@ struct drm_psb_private { bool vblanksEnabledForFlips; spinlock_t irqmask_lock; - spinlock_t sequence_lock; /* *Modesetting @@ -636,46 +609,6 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev) return (struct drm_psb_private *) dev->dev_private; } -/* - *TTM glue. psb_ttm_glue.c - */ - -extern int psb_open(struct inode *inode, struct file *filp); -extern int psb_release(struct inode *inode, struct file *filp); -extern int psb_mmap(struct file *filp, struct vm_area_struct *vma); - -extern int psb_fence_signaled_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_verify_access(struct ttm_buffer_object *bo, - struct file *filp); -extern ssize_t psb_ttm_read(struct file *filp, char __user *buf, - size_t count, loff_t *f_pos); -extern ssize_t psb_ttm_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos); -extern int psb_fence_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_fence_unref_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_unref_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_reference_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_extension_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_ttm_global_init(struct drm_psb_private *dev_priv); -extern void psb_ttm_global_release(struct drm_psb_private *dev_priv); -extern int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); /* *MMU stuff. */ @@ -718,26 +651,6 @@ extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address, uint32_t num_pages, uint32_t desired_tile_stride, uint32_t hw_tile_stride); -/* - *psb_sgx.c - */ - - - -extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psb_reg_submit(struct drm_psb_private *dev_priv, - uint32_t *regs, unsigned int cmds); - - -extern void psb_fence_or_sync(struct drm_file *file_priv, - uint32_t engine, - uint32_t fence_types, - uint32_t fence_flags, - struct list_head *list, - struct psb_ttm_fence_rep *fence_arg, - struct ttm_fence_object **fence_p); - /* *psb_irq.c */ @@ -766,29 +679,6 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); -/* - *psb_fence.c - */ - -extern void psb_fence_handler(struct drm_device *dev, uint32_t class); - -extern int psb_fence_emit_sequence(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t flags, uint32_t *sequence, - unsigned long *timeout_jiffies); -extern void psb_fence_error(struct drm_device *dev, - uint32_t class, - uint32_t sequence, uint32_t type, int error); -extern int psb_ttm_fence_device_init(struct ttm_fence_device *fdev); - -/* MSVDX/Topaz stuff */ -extern int psb_remove_videoctx(struct drm_psb_private *dev_priv, struct file *filp); - -extern int lnc_video_frameskip(struct drm_device *dev, - uint64_t user_pointer); -extern int lnc_video_getparam(struct drm_device *dev, void *data, - struct drm_file *file_priv); - /* * psb_opregion.c */ diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index 53a270e5857b..c15e2f9a244d 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -36,9 +36,7 @@ #include "psb_drv.h" #include "psb_intel_reg.h" #include "psb_intel_drv.h" -#include "psb_ttm_userobj_api.h" #include "psb_fb.h" -#include "psb_sgx.h" #include "psb_pvr_glue.h" static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); @@ -317,6 +315,8 @@ static struct drm_framebuffer *psb_user_framebuffer_create (struct drm_device *dev, struct drm_file *filp, struct drm_mode_fb_cmd *r) { + return NULL; +#if 0 struct ttm_buffer_object *bo = NULL; uint64_t size; @@ -332,7 +332,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create /* JB: TODO not drop, refcount buffer */ return psb_framebuffer_create(dev, r, bo); -#if 0 struct psb_framebuffer *psbfb; struct drm_framebuffer *fb; struct fb_info *info; diff --git a/drivers/staging/gma500/psb_fence.c b/drivers/staging/gma500/psb_fence.c deleted file mode 100644 index a70aa64f2cad..000000000000 --- a/drivers/staging/gma500/psb_fence.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * 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. - * - * - * Authors: Thomas Hellstrom - */ - -#include -#include "psb_drv.h" - - -static void psb_fence_poll(struct ttm_fence_device *fdev, - uint32_t fence_class, uint32_t waiting_types) -{ - struct drm_psb_private *dev_priv = - container_of(fdev, struct drm_psb_private, fdev); - - - if (unlikely(!dev_priv)) - return; - - if (waiting_types == 0) - return; - - /* DRM_ERROR("Polling fence sequence, got 0x%08x\n", sequence); */ - ttm_fence_handler(fdev, fence_class, 0 /* Sequence */, - _PSB_FENCE_TYPE_EXE, 0); -} - -void psb_fence_error(struct drm_device *dev, - uint32_t fence_class, - uint32_t sequence, uint32_t type, int error) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - struct ttm_fence_device *fdev = &dev_priv->fdev; - unsigned long irq_flags; - struct ttm_fence_class_manager *fc = - &fdev->fence_class[fence_class]; - - BUG_ON(fence_class >= PSB_NUM_ENGINES); - write_lock_irqsave(&fc->lock, irq_flags); - ttm_fence_handler(fdev, fence_class, sequence, type, error); - write_unlock_irqrestore(&fc->lock, irq_flags); -} - -int psb_fence_emit_sequence(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t flags, uint32_t *sequence, - unsigned long *timeout_jiffies) -{ - struct drm_psb_private *dev_priv = - container_of(fdev, struct drm_psb_private, fdev); - - if (!dev_priv) - return -EINVAL; - - if (fence_class >= PSB_NUM_ENGINES) - return -EINVAL; - - DRM_ERROR("Unexpected fence class\n"); - return -EINVAL; -} - -static void psb_fence_lockup(struct ttm_fence_object *fence, - uint32_t fence_types) -{ - DRM_ERROR("Unsupported fence class\n"); -} - -void psb_fence_handler(struct drm_device *dev, uint32_t fence_class) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - struct ttm_fence_device *fdev = &dev_priv->fdev; - struct ttm_fence_class_manager *fc = - &fdev->fence_class[fence_class]; - unsigned long irq_flags; - - write_lock_irqsave(&fc->lock, irq_flags); - psb_fence_poll(fdev, fence_class, fc->waiting_types); - write_unlock_irqrestore(&fc->lock, irq_flags); -} - - -static struct ttm_fence_driver psb_ttm_fence_driver = { - .has_irq = NULL, - .emit = psb_fence_emit_sequence, - .flush = NULL, - .poll = psb_fence_poll, - .needed_flush = NULL, - .wait = NULL, - .signaled = NULL, - .lockup = psb_fence_lockup, -}; - -int psb_ttm_fence_device_init(struct ttm_fence_device *fdev) -{ - struct drm_psb_private *dev_priv = - container_of(fdev, struct drm_psb_private, fdev); - struct ttm_fence_class_init fci = {.wrap_diff = (1 << 30), - .flush_diff = (1 << 29), - .sequence_mask = 0xFFFFFFFF - }; - - return ttm_fence_device_init(PSB_NUM_ENGINES, - dev_priv->mem_global_ref.object, - fdev, &fci, 1, - &psb_ttm_fence_driver); -} diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c index d129b75c4e56..c1283e836b23 100644 --- a/drivers/staging/gma500/psb_gtt.c +++ b/drivers/staging/gma500/psb_gtt.c @@ -101,7 +101,7 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); /* fix me: video mmu has hw bug to access 0x0D0000000, * then make gatt start at 0x0e000,0000 */ - pg->mmu_gatt_start = PSB_MEM_TT_START; + pg->mmu_gatt_start = 0xE0000000; pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; diff --git a/drivers/staging/gma500/psb_sgx.c b/drivers/staging/gma500/psb_sgx.c deleted file mode 100644 index 91fbb6a11cae..000000000000 --- a/drivers/staging/gma500/psb_sgx.c +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX. USA. - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ - -#include -#include "psb_drv.h" -#include "psb_drm.h" -#include "psb_reg.h" -#include "ttm/ttm_bo_api.h" -#include "ttm/ttm_execbuf_util.h" -#include "psb_ttm_userobj_api.h" -#include "ttm/ttm_placement.h" -#include "psb_sgx.h" -#include "psb_intel_reg.h" -#include "psb_powermgmt.h" - - -static inline int psb_same_page(unsigned long offset, - unsigned long offset2) -{ - return (offset & PAGE_MASK) == (offset2 & PAGE_MASK); -} - -static inline unsigned long psb_offset_end(unsigned long offset, - unsigned long end) -{ - offset = (offset + PAGE_SIZE) & PAGE_MASK; - return (end < offset) ? end : offset; -} - -struct psb_dstbuf_cache { - unsigned int dst; - struct ttm_buffer_object *dst_buf; - unsigned long dst_offset; - uint32_t *dst_page; - unsigned int dst_page_offset; - struct ttm_bo_kmap_obj dst_kmap; - bool dst_is_iomem; -}; - -struct psb_validate_buffer { - struct ttm_validate_buffer base; - struct psb_validate_req req; - int ret; - struct psb_validate_arg __user *user_val_arg; - uint32_t flags; - uint32_t offset; - int po_correct; -}; -void psb_fence_or_sync(struct drm_file *file_priv, - uint32_t engine, - uint32_t fence_types, - uint32_t fence_flags, - struct list_head *list, - struct psb_ttm_fence_rep *fence_arg, - struct ttm_fence_object **fence_p) -{ - struct drm_device *dev = file_priv->minor->dev; - struct drm_psb_private *dev_priv = psb_priv(dev); - struct ttm_fence_device *fdev = &dev_priv->fdev; - int ret; - struct ttm_fence_object *fence; - struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile; - uint32_t handle; - - ret = ttm_fence_user_create(fdev, tfile, - engine, fence_types, - TTM_FENCE_FLAG_EMIT, &fence, &handle); - if (ret) { - - /* - * Fence creation failed. - * Fall back to synchronous operation and idle the engine. - */ - - if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) { - - /* - * Communicate to user-space that - * fence creation has failed and that - * the engine is idle. - */ - - fence_arg->handle = ~0; - fence_arg->error = ret; - } - - ttm_eu_backoff_reservation(list); - if (fence_p) - *fence_p = NULL; - return; - } - - ttm_eu_fence_buffer_objects(list, fence); - if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) { - struct ttm_fence_info info = ttm_fence_get_info(fence); - fence_arg->handle = handle; - fence_arg->fence_class = ttm_fence_class(fence); - fence_arg->fence_type = ttm_fence_types(fence); - fence_arg->signaled_types = info.signaled_types; - fence_arg->error = 0; - } else { - ret = - ttm_ref_object_base_unref(tfile, handle, - ttm_fence_type); - BUG_ON(ret); - } - - if (fence_p) - *fence_p = fence; - else if (fence) - ttm_fence_object_unref(&fence); -} - diff --git a/drivers/staging/gma500/psb_sgx.h b/drivers/staging/gma500/psb_sgx.h deleted file mode 100644 index 9300e2da993a..000000000000 --- a/drivers/staging/gma500/psb_sgx.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2008, 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. - * - * Authors: - * Eric Anholt - * - **/ -#ifndef _PSB_SGX_H_ -#define _PSB_SGX_H_ - -extern int psb_submit_video_cmdbuf(struct drm_device *dev, - struct ttm_buffer_object *cmd_buffer, - unsigned long cmd_offset, - unsigned long cmd_size, - struct ttm_fence_object *fence); - -extern int drm_idle_check_interval; - -#endif diff --git a/drivers/staging/gma500/psb_ttm_fence.c b/drivers/staging/gma500/psb_ttm_fence.c deleted file mode 100644 index d1c359018cba..000000000000 --- a/drivers/staging/gma500/psb_ttm_fence.c +++ /dev/null @@ -1,605 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include "psb_ttm_fence_api.h" -#include "psb_ttm_fence_driver.h" -#include -#include - -#include - -/* - * Simple implementation for now. - */ - -static void ttm_fence_lockup(struct ttm_fence_object *fence, uint32_t mask) -{ - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - - printk(KERN_ERR "GPU lockup dectected on engine %u " - "fence type 0x%08x\n", - (unsigned int)fence->fence_class, (unsigned int)mask); - /* - * Give engines some time to idle? - */ - - write_lock(&fc->lock); - ttm_fence_handler(fence->fdev, fence->fence_class, - fence->sequence, mask, -EBUSY); - write_unlock(&fc->lock); -} - -/* - * Convenience function to be called by fence::wait methods that - * need polling. - */ - -int ttm_fence_wait_polling(struct ttm_fence_object *fence, bool lazy, - bool interruptible, uint32_t mask) -{ - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - const struct ttm_fence_driver *driver = ttm_fence_driver(fence); - uint32_t count = 0; - int ret; - unsigned long end_jiffies = fence->timeout_jiffies; - - DECLARE_WAITQUEUE(entry, current); - add_wait_queue(&fc->fence_queue, &entry); - - ret = 0; - - for (;;) { - __set_current_state((interruptible) ? - TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - if (ttm_fence_object_signaled(fence, mask)) - break; - if (time_after_eq(jiffies, end_jiffies)) { - if (driver->lockup) - driver->lockup(fence, mask); - else - ttm_fence_lockup(fence, mask); - continue; - } - if (lazy) - schedule_timeout(1); - else if ((++count & 0x0F) == 0) { - __set_current_state(TASK_RUNNING); - schedule(); - __set_current_state((interruptible) ? - TASK_INTERRUPTIBLE : - TASK_UNINTERRUPTIBLE); - } - if (interruptible && signal_pending(current)) { - ret = -ERESTART; - break; - } - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&fc->fence_queue, &entry); - return ret; -} - -/* - * Typically called by the IRQ handler. - */ - -void ttm_fence_handler(struct ttm_fence_device *fdev, uint32_t fence_class, - uint32_t sequence, uint32_t type, uint32_t error) -{ - int wake = 0; - uint32_t diff; - uint32_t relevant_type; - uint32_t new_type; - struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class]; - const struct ttm_fence_driver *driver = ttm_fence_driver_from_dev(fdev); - struct list_head *head; - struct ttm_fence_object *fence, *next; - bool found = false; - - if (list_empty(&fc->ring)) - return; - - list_for_each_entry(fence, &fc->ring, ring) { - diff = (sequence - fence->sequence) & fc->sequence_mask; - if (diff > fc->wrap_diff) { - found = true; - break; - } - } - - fc->waiting_types &= ~type; - head = (found) ? &fence->ring : &fc->ring; - - list_for_each_entry_safe_reverse(fence, next, head, ring) { - if (&fence->ring == &fc->ring) - break; - - DRM_DEBUG("Fence 0x%08lx, sequence 0x%08x, type 0x%08x\n", - (unsigned long)fence, fence->sequence, - fence->fence_type); - - if (error) { - fence->info.error = error; - fence->info.signaled_types = fence->fence_type; - list_del_init(&fence->ring); - wake = 1; - break; - } - - relevant_type = type & fence->fence_type; - new_type = (fence->info.signaled_types | relevant_type) ^ - fence->info.signaled_types; - - if (new_type) { - fence->info.signaled_types |= new_type; - DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n", - (unsigned long)fence, - fence->info.signaled_types); - - if (unlikely(driver->signaled)) - driver->signaled(fence); - - if (driver->needed_flush) - fc->pending_flush |= - driver->needed_flush(fence); - - if (new_type & fence->waiting_types) - wake = 1; - } - - fc->waiting_types |= - fence->waiting_types & ~fence->info.signaled_types; - - if (!(fence->fence_type & ~fence->info.signaled_types)) { - DRM_DEBUG("Fence completely signaled 0x%08lx\n", - (unsigned long)fence); - list_del_init(&fence->ring); - } - } - - /* - * Reinstate lost waiting types. - */ - - if ((fc->waiting_types & type) != type) { - head = head->prev; - list_for_each_entry(fence, head, ring) { - if (&fence->ring == &fc->ring) - break; - diff = - (fc->highest_waiting_sequence - - fence->sequence) & fc->sequence_mask; - if (diff > fc->wrap_diff) - break; - - fc->waiting_types |= - fence->waiting_types & ~fence->info.signaled_types; - } - } - - if (wake) - wake_up_all(&fc->fence_queue); -} - -static void ttm_fence_unring(struct ttm_fence_object *fence) -{ - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - unsigned long irq_flags; - - write_lock_irqsave(&fc->lock, irq_flags); - list_del_init(&fence->ring); - write_unlock_irqrestore(&fc->lock, irq_flags); -} - -bool ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask) -{ - unsigned long flags; - bool signaled; - const struct ttm_fence_driver *driver = ttm_fence_driver(fence); - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - - mask &= fence->fence_type; - read_lock_irqsave(&fc->lock, flags); - signaled = (mask & fence->info.signaled_types) == mask; - read_unlock_irqrestore(&fc->lock, flags); - if (!signaled && driver->poll) { - write_lock_irqsave(&fc->lock, flags); - driver->poll(fence->fdev, fence->fence_class, mask); - signaled = (mask & fence->info.signaled_types) == mask; - write_unlock_irqrestore(&fc->lock, flags); - } - return signaled; -} - -int ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t type) -{ - const struct ttm_fence_driver *driver = ttm_fence_driver(fence); - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - unsigned long irq_flags; - uint32_t saved_pending_flush; - uint32_t diff; - bool call_flush; - - if (type & ~fence->fence_type) { - DRM_ERROR("Flush trying to extend fence type, " - "0x%x, 0x%x\n", type, fence->fence_type); - return -EINVAL; - } - - write_lock_irqsave(&fc->lock, irq_flags); - fence->waiting_types |= type; - fc->waiting_types |= fence->waiting_types; - diff = (fence->sequence - fc->highest_waiting_sequence) & - fc->sequence_mask; - - if (diff < fc->wrap_diff) - fc->highest_waiting_sequence = fence->sequence; - - /* - * fence->waiting_types has changed. Determine whether - * we need to initiate some kind of flush as a result of this. - */ - - saved_pending_flush = fc->pending_flush; - if (driver->needed_flush) - fc->pending_flush |= driver->needed_flush(fence); - - if (driver->poll) - driver->poll(fence->fdev, fence->fence_class, - fence->waiting_types); - - call_flush = (fc->pending_flush != 0); - write_unlock_irqrestore(&fc->lock, irq_flags); - - if (call_flush && driver->flush) - driver->flush(fence->fdev, fence->fence_class); - - return 0; -} - -/* - * Make sure old fence objects are signaled before their fence sequences are - * wrapped around and reused. - */ - -void ttm_fence_flush_old(struct ttm_fence_device *fdev, - uint32_t fence_class, uint32_t sequence) -{ - struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class]; - struct ttm_fence_object *fence; - unsigned long irq_flags; - const struct ttm_fence_driver *driver = fdev->driver; - bool call_flush; - - uint32_t diff; - - write_lock_irqsave(&fc->lock, irq_flags); - - list_for_each_entry_reverse(fence, &fc->ring, ring) { - diff = (sequence - fence->sequence) & fc->sequence_mask; - if (diff <= fc->flush_diff) - break; - - fence->waiting_types = fence->fence_type; - fc->waiting_types |= fence->fence_type; - - if (driver->needed_flush) - fc->pending_flush |= driver->needed_flush(fence); - } - - if (driver->poll) - driver->poll(fdev, fence_class, fc->waiting_types); - - call_flush = (fc->pending_flush != 0); - write_unlock_irqrestore(&fc->lock, irq_flags); - - if (call_flush && driver->flush) - driver->flush(fdev, fence->fence_class); - - /* - * FIXME: Shold we implement a wait here for really old fences? - */ - -} - -int ttm_fence_object_wait(struct ttm_fence_object *fence, - bool lazy, bool interruptible, uint32_t mask) -{ - const struct ttm_fence_driver *driver = ttm_fence_driver(fence); - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - int ret = 0; - unsigned long timeout; - unsigned long cur_jiffies; - unsigned long to_jiffies; - - if (mask & ~fence->fence_type) { - DRM_ERROR("Wait trying to extend fence type" - " 0x%08x 0x%08x\n", mask, fence->fence_type); - BUG(); - return -EINVAL; - } - - if (driver->wait) - return driver->wait(fence, lazy, interruptible, mask); - - ttm_fence_object_flush(fence, mask); -retry: - if (!driver->has_irq || - driver->has_irq(fence->fdev, fence->fence_class, mask)) { - - cur_jiffies = jiffies; - to_jiffies = fence->timeout_jiffies; - - timeout = (time_after(to_jiffies, cur_jiffies)) ? - to_jiffies - cur_jiffies : 1; - - if (interruptible) - ret = wait_event_interruptible_timeout - (fc->fence_queue, - ttm_fence_object_signaled(fence, mask), timeout); - else - ret = wait_event_timeout - (fc->fence_queue, - ttm_fence_object_signaled(fence, mask), timeout); - - if (unlikely(ret == -ERESTARTSYS)) - return -ERESTART; - - if (unlikely(ret == 0)) { - if (driver->lockup) - driver->lockup(fence, mask); - else - ttm_fence_lockup(fence, mask); - goto retry; - } - - return 0; - } - - return ttm_fence_wait_polling(fence, lazy, interruptible, mask); -} - -int ttm_fence_object_emit(struct ttm_fence_object *fence, uint32_t fence_flags, - uint32_t fence_class, uint32_t type) -{ - const struct ttm_fence_driver *driver = ttm_fence_driver(fence); - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - unsigned long flags; - uint32_t sequence; - unsigned long timeout; - int ret; - - ttm_fence_unring(fence); - ret = driver->emit(fence->fdev, - fence_class, fence_flags, &sequence, &timeout); - if (ret) - return ret; - - write_lock_irqsave(&fc->lock, flags); - fence->fence_class = fence_class; - fence->fence_type = type; - fence->waiting_types = 0; - fence->info.signaled_types = 0; - fence->info.error = 0; - fence->sequence = sequence; - fence->timeout_jiffies = timeout; - if (list_empty(&fc->ring)) - fc->highest_waiting_sequence = sequence - 1; - list_add_tail(&fence->ring, &fc->ring); - fc->latest_queued_sequence = sequence; - write_unlock_irqrestore(&fc->lock, flags); - return 0; -} - -int ttm_fence_object_init(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t type, - uint32_t create_flags, - void (*destroy) (struct ttm_fence_object *), - struct ttm_fence_object *fence) -{ - int ret = 0; - - kref_init(&fence->kref); - fence->fence_class = fence_class; - fence->fence_type = type; - fence->info.signaled_types = 0; - fence->waiting_types = 0; - fence->sequence = 0; - fence->info.error = 0; - fence->fdev = fdev; - fence->destroy = destroy; - INIT_LIST_HEAD(&fence->ring); - atomic_inc(&fdev->count); - - if (create_flags & TTM_FENCE_FLAG_EMIT) { - ret = ttm_fence_object_emit(fence, create_flags, - fence->fence_class, type); - } - - return ret; -} - -int ttm_fence_object_create(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t type, - uint32_t create_flags, - struct ttm_fence_object **c_fence) -{ - struct ttm_fence_object *fence; - int ret; - - ret = ttm_mem_global_alloc(fdev->mem_glob, - sizeof(*fence), - false, - false); - if (unlikely(ret != 0)) { - printk(KERN_ERR "Out of memory creating fence object\n"); - return ret; - } - - fence = kmalloc(sizeof(*fence), GFP_KERNEL); - if (!fence) { - printk(KERN_ERR "Out of memory creating fence object\n"); - ttm_mem_global_free(fdev->mem_glob, sizeof(*fence)); - return -ENOMEM; - } - - ret = ttm_fence_object_init(fdev, fence_class, type, - create_flags, NULL, fence); - if (ret) { - ttm_fence_object_unref(&fence); - return ret; - } - *c_fence = fence; - - return 0; -} - -static void ttm_fence_object_destroy(struct kref *kref) -{ - struct ttm_fence_object *fence = - container_of(kref, struct ttm_fence_object, kref); - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - unsigned long irq_flags; - - write_lock_irqsave(&fc->lock, irq_flags); - list_del_init(&fence->ring); - write_unlock_irqrestore(&fc->lock, irq_flags); - - atomic_dec(&fence->fdev->count); - if (fence->destroy) - fence->destroy(fence); - else { - ttm_mem_global_free(fence->fdev->mem_glob, - sizeof(*fence)); - kfree(fence); - } -} - -void ttm_fence_device_release(struct ttm_fence_device *fdev) -{ - kfree(fdev->fence_class); -} - -int -ttm_fence_device_init(int num_classes, - struct ttm_mem_global *mem_glob, - struct ttm_fence_device *fdev, - const struct ttm_fence_class_init *init, - bool replicate_init, - const struct ttm_fence_driver *driver) -{ - struct ttm_fence_class_manager *fc; - const struct ttm_fence_class_init *fci; - int i; - - fdev->mem_glob = mem_glob; - fdev->fence_class = kzalloc(num_classes * - sizeof(*fdev->fence_class), GFP_KERNEL); - - if (unlikely(!fdev->fence_class)) - return -ENOMEM; - - fdev->num_classes = num_classes; - atomic_set(&fdev->count, 0); - fdev->driver = driver; - - for (i = 0; i < fdev->num_classes; ++i) { - fc = &fdev->fence_class[i]; - fci = &init[(replicate_init) ? 0 : i]; - - fc->wrap_diff = fci->wrap_diff; - fc->flush_diff = fci->flush_diff; - fc->sequence_mask = fci->sequence_mask; - - rwlock_init(&fc->lock); - INIT_LIST_HEAD(&fc->ring); - init_waitqueue_head(&fc->fence_queue); - } - - return 0; -} - -struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence) -{ - struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); - struct ttm_fence_info tmp; - unsigned long irq_flags; - - read_lock_irqsave(&fc->lock, irq_flags); - tmp = fence->info; - read_unlock_irqrestore(&fc->lock, irq_flags); - - return tmp; -} - -void ttm_fence_object_unref(struct ttm_fence_object **p_fence) -{ - struct ttm_fence_object *fence = *p_fence; - - *p_fence = NULL; - (void)kref_put(&fence->kref, &ttm_fence_object_destroy); -} - -/* - * Placement / BO sync object glue. - */ - -bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg) -{ - struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj; - uint32_t fence_types = (uint32_t) (unsigned long)sync_arg; - - return ttm_fence_object_signaled(fence, fence_types); -} - -int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg, - bool lazy, bool interruptible) -{ - struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj; - uint32_t fence_types = (uint32_t) (unsigned long)sync_arg; - - return ttm_fence_object_wait(fence, lazy, interruptible, fence_types); -} - -int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg) -{ - struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj; - uint32_t fence_types = (uint32_t) (unsigned long)sync_arg; - - return ttm_fence_object_flush(fence, fence_types); -} - -void ttm_fence_sync_obj_unref(void **sync_obj) -{ - ttm_fence_object_unref((struct ttm_fence_object **)sync_obj); -} - -void *ttm_fence_sync_obj_ref(void *sync_obj) -{ - return (void *) - ttm_fence_object_ref((struct ttm_fence_object *)sync_obj); -} diff --git a/drivers/staging/gma500/psb_ttm_fence_api.h b/drivers/staging/gma500/psb_ttm_fence_api.h deleted file mode 100644 index b14a42711d03..000000000000 --- a/drivers/staging/gma500/psb_ttm_fence_api.h +++ /dev/null @@ -1,272 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ -#ifndef _TTM_FENCE_API_H_ -#define _TTM_FENCE_API_H_ - -#include -#include - -#define TTM_FENCE_FLAG_EMIT (1 << 0) -#define TTM_FENCE_TYPE_EXE (1 << 0) - -struct ttm_fence_device; - -/** - * struct ttm_fence_info - * - * @fence_class: The fence class. - * @fence_type: Bitfield indicating types for this fence. - * @signaled_types: Bitfield indicating which types are signaled. - * @error: Last error reported from the device. - * - * Used as output from the ttm_fence_get_info - */ - -struct ttm_fence_info { - uint32_t signaled_types; - uint32_t error; -}; - -/** - * struct ttm_fence_object - * - * @fdev: Pointer to the fence device struct. - * @kref: Holds the reference count of this fence object. - * @ring: List head used for the circular list of not-completely - * signaled fences. - * @info: Data for fast retrieval using the ttm_fence_get_info() - * function. - * @timeout_jiffies: Absolute jiffies value indicating when this fence - * object times out and, if waited on, calls ttm_fence_lockup - * to check for and resolve a GPU lockup. - * @sequence: Fence sequence number. - * @waiting_types: Types currently waited on. - * @destroy: Called to free the fence object, when its refcount has - * reached zero. If NULL, kfree is used. - * - * This struct is provided in the driver interface so that drivers can - * derive from it and create their own fence implementation. All members - * are private to the fence implementation and the fence driver callbacks. - * Otherwise a driver may access the derived object using container_of(). - */ - -struct ttm_fence_object { - struct ttm_fence_device *fdev; - struct kref kref; - uint32_t fence_class; - uint32_t fence_type; - - /* - * The below fields are protected by the fence class - * manager spinlock. - */ - - struct list_head ring; - struct ttm_fence_info info; - unsigned long timeout_jiffies; - uint32_t sequence; - uint32_t waiting_types; - void (*destroy) (struct ttm_fence_object *); -}; - -/** - * ttm_fence_object_init - * - * @fdev: Pointer to a struct ttm_fence_device. - * @fence_class: Fence class for this fence. - * @type: Fence type for this fence. - * @create_flags: Flags indicating varios actions at init time. At this point - * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to - * the command stream. - * @destroy: Destroy function. If NULL, kfree() is used. - * @fence: The struct ttm_fence_object to initialize. - * - * Initialize a pre-allocated fence object. This function, together with the - * destroy function makes it possible to derive driver-specific fence objects. - */ - -extern int -ttm_fence_object_init(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t type, - uint32_t create_flags, - void (*destroy) (struct ttm_fence_object *fence), - struct ttm_fence_object *fence); - -/** - * ttm_fence_object_create - * - * @fdev: Pointer to a struct ttm_fence_device. - * @fence_class: Fence class for this fence. - * @type: Fence type for this fence. - * @create_flags: Flags indicating varios actions at init time. At this point - * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to - * the command stream. - * @c_fence: On successful termination, *(@c_fence) will point to the created - * fence object. - * - * Create and initialize a struct ttm_fence_object. The destroy function will - * be set to kfree(). - */ - -extern int -ttm_fence_object_create(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t type, - uint32_t create_flags, - struct ttm_fence_object **c_fence); - -/** - * ttm_fence_object_wait - * - * @fence: The fence object to wait on. - * @lazy: Allow sleeps to reduce the cpu-usage if polling. - * @interruptible: Sleep interruptible when waiting. - * @type_mask: Wait for the given type_mask to signal. - * - * Wait for a fence to signal the given type_mask. The function will - * perform a fence_flush using type_mask. (See ttm_fence_object_flush). - * - * Returns - * -ERESTART if interrupted by a signal. - * May return driver-specific error codes if timed-out. - */ - -extern int -ttm_fence_object_wait(struct ttm_fence_object *fence, - bool lazy, bool interruptible, uint32_t type_mask); - -/** - * ttm_fence_object_flush - * - * @fence: The fence object to flush. - * @flush_mask: Fence types to flush. - * - * Make sure that the given fence eventually signals the - * types indicated by @flush_mask. Note that this may or may not - * map to a CPU or GPU flush. - */ - -extern int -ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t flush_mask); - -/** - * ttm_fence_get_info - * - * @fence: The fence object. - * - * Copy the info block from the fence while holding relevant locks. - */ - -struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence); - -/** - * ttm_fence_object_ref - * - * @fence: The fence object. - * - * Return a ref-counted pointer to the fence object indicated by @fence. - */ - -static inline struct ttm_fence_object *ttm_fence_object_ref(struct - ttm_fence_object - *fence) -{ - kref_get(&fence->kref); - return fence; -} - -/** - * ttm_fence_object_unref - * - * @p_fence: Pointer to a ref-counted pinter to a struct ttm_fence_object. - * - * Unreference the fence object pointed to by *(@p_fence), clearing - * *(p_fence). - */ - -extern void ttm_fence_object_unref(struct ttm_fence_object **p_fence); - -/** - * ttm_fence_object_signaled - * - * @fence: Pointer to the struct ttm_fence_object. - * @mask: Type mask to check whether signaled. - * - * This function checks (without waiting) whether the fence object - * pointed to by @fence has signaled the types indicated by @mask, - * and returns 1 if true, 0 if false. This function does NOT perform - * an implicit fence flush. - */ - -extern bool -ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask); - -/** - * ttm_fence_class - * - * @fence: Pointer to the struct ttm_fence_object. - * - * Convenience function that returns the fence class of a - * struct ttm_fence_object. - */ - -static inline uint32_t ttm_fence_class(const struct ttm_fence_object *fence) -{ - return fence->fence_class; -} - -/** - * ttm_fence_types - * - * @fence: Pointer to the struct ttm_fence_object. - * - * Convenience function that returns the fence types of a - * struct ttm_fence_object. - */ - -static inline uint32_t ttm_fence_types(const struct ttm_fence_object *fence) -{ - return fence->fence_type; -} - -/* - * The functions below are wrappers to the above functions, with - * similar names but with sync_obj omitted. These wrappers are intended - * to be plugged directly into the buffer object driver's sync object - * API, if the driver chooses to use ttm_fence_objects as buffer object - * sync objects. In the prototypes below, a sync_obj is cast to a - * struct ttm_fence_object, whereas a sync_arg is cast to an - * uint32_t representing a fence_type argument. - */ - -extern bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg); -extern int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg, - bool lazy, bool interruptible); -extern int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg); -extern void ttm_fence_sync_obj_unref(void **sync_obj); -extern void *ttm_fence_sync_obj_ref(void *sync_obj); - -#endif diff --git a/drivers/staging/gma500/psb_ttm_fence_driver.h b/drivers/staging/gma500/psb_ttm_fence_driver.h deleted file mode 100644 index c35c569fa3f0..000000000000 --- a/drivers/staging/gma500/psb_ttm_fence_driver.h +++ /dev/null @@ -1,302 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ -#ifndef _TTM_FENCE_DRIVER_H_ -#define _TTM_FENCE_DRIVER_H_ - -#include -#include -#include -#include "psb_ttm_fence_api.h" -#include "ttm/ttm_memory.h" - -/** @file ttm_fence_driver.h - * - * Definitions needed for a driver implementing the - * ttm_fence subsystem. - */ - -/** - * struct ttm_fence_class_manager: - * - * @wrap_diff: Sequence difference to catch 32-bit wrapping. - * if (seqa - seqb) > @wrap_diff, then seqa < seqb. - * @flush_diff: Sequence difference to trigger fence flush. - * if (cur_seq - seqa) > @flush_diff, then consider fence object with - * seqa as old an needing a flush. - * @sequence_mask: Mask of valid bits in a fence sequence. - * @lock: Lock protecting this struct as well as fence objects - * associated with this struct. - * @ring: Circular sequence-ordered list of fence objects. - * @pending_flush: Fence types currently needing a flush. - * @waiting_types: Fence types that are currently waited for. - * @fence_queue: Queue of waiters on fences belonging to this fence class. - * @highest_waiting_sequence: Sequence number of the fence with highest - * sequence number and that is waited for. - * @latest_queued_sequence: Sequence number of the fence latest queued - * on the ring. - */ - -struct ttm_fence_class_manager { - - /* - * Unprotected constant members. - */ - - uint32_t wrap_diff; - uint32_t flush_diff; - uint32_t sequence_mask; - - /* - * The rwlock protects this structure as well as - * the data in all fence objects belonging to this - * class. This should be OK as most fence objects are - * only read from once they're created. - */ - - rwlock_t lock; - struct list_head ring; - uint32_t pending_flush; - uint32_t waiting_types; - wait_queue_head_t fence_queue; - uint32_t highest_waiting_sequence; - uint32_t latest_queued_sequence; -}; - -/** - * struct ttm_fence_device - * - * @fence_class: Array of fence class managers. - * @num_classes: Array dimension of @fence_class. - * @count: Current number of fence objects for statistics. - * @driver: Driver struct. - * - * Provided in the driver interface so that the driver can derive - * from this struct for its driver_private, and accordingly - * access the driver_private from the fence driver callbacks. - * - * All members except "count" are initialized at creation and - * never touched after that. No protection needed. - * - * This struct is private to the fence implementation and to the fence - * driver callbacks, and may otherwise be used by drivers only to - * obtain the derived device_private object using container_of(). - */ - -struct ttm_fence_device { - struct ttm_mem_global *mem_glob; - struct ttm_fence_class_manager *fence_class; - uint32_t num_classes; - atomic_t count; - const struct ttm_fence_driver *driver; -}; - -/** - * struct ttm_fence_class_init - * - * @wrap_diff: Fence sequence number wrap indicator. If - * (sequence1 - sequence2) > @wrap_diff, then sequence1 is - * considered to be older than sequence2. - * @flush_diff: Fence sequence number flush indicator. - * If a non-completely-signaled fence has a fence sequence number - * sequence1 and (sequence1 - current_emit_sequence) > @flush_diff, - * the fence is considered too old and it will be flushed upon the - * next call of ttm_fence_flush_old(), to make sure no fences with - * stale sequence numbers remains unsignaled. @flush_diff should - * be sufficiently less than @wrap_diff. - * @sequence_mask: Mask with valid bits of the fence sequence - * number set to 1. - * - * This struct is used as input to ttm_fence_device_init. - */ - -struct ttm_fence_class_init { - uint32_t wrap_diff; - uint32_t flush_diff; - uint32_t sequence_mask; -}; - -/** - * struct ttm_fence_driver - * - * @has_irq: Called by a potential waiter. Should return 1 if a - * fence object with indicated parameters is expected to signal - * automatically, and 0 if the fence implementation needs to - * repeatedly call @poll to make it signal. - * @emit: Make sure a fence with the given parameters is - * present in the indicated command stream. Return its sequence number - * in "breadcrumb". - * @poll: Check and report sequences of the given "fence_class" - * that have signaled "types" - * @flush: Make sure that the types indicated by the bitfield - * ttm_fence_class_manager::pending_flush will eventually - * signal. These bits have been put together using the - * result from the needed_flush function described below. - * @needed_flush: Given the fence_class and fence_types indicated by - * "fence", and the last received fence sequence of this - * fence class, indicate what types need a fence flush to - * signal. Return as a bitfield. - * @wait: Set to non-NULL if the driver wants to override the fence - * wait implementation. Return 0 on success, -EBUSY on failure, - * and -ERESTART if interruptible and a signal is pending. - * @signaled: Driver callback that is called whenever a - * ttm_fence_object::signaled_types has changed status. - * This function is called from atomic context, - * with the ttm_fence_class_manager::lock held in write mode. - * @lockup: Driver callback that is called whenever a wait has exceeded - * the lifetime of a fence object. - * If there is a GPU lockup, - * this function should, if possible, reset the GPU, - * call the ttm_fence_handler with an error status, and - * return. If no lockup was detected, simply extend the - * fence timeout_jiffies and return. The driver might - * want to protect the lockup check with a mutex and cache a - * non-locked-up status for a while to avoid an excessive - * amount of lockup checks from every waiting thread. - */ - -struct ttm_fence_driver { - bool (*has_irq) (struct ttm_fence_device *fdev, - uint32_t fence_class, uint32_t flags); - int (*emit) (struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t flags, - uint32_t *breadcrumb, unsigned long *timeout_jiffies); - void (*flush) (struct ttm_fence_device *fdev, uint32_t fence_class); - void (*poll) (struct ttm_fence_device *fdev, - uint32_t fence_class, uint32_t types); - uint32_t(*needed_flush) - (struct ttm_fence_object *fence); - int (*wait) (struct ttm_fence_object *fence, bool lazy, - bool interruptible, uint32_t mask); - void (*signaled) (struct ttm_fence_object *fence); - void (*lockup) (struct ttm_fence_object *fence, uint32_t fence_types); -}; - -/** - * function ttm_fence_device_init - * - * @num_classes: Number of fence classes for this fence implementation. - * @mem_global: Pointer to the global memory accounting info. - * @fdev: Pointer to an uninitialised struct ttm_fence_device. - * @init: Array of initialization info for each fence class. - * @replicate_init: Use the first @init initialization info for all classes. - * @driver: Driver callbacks. - * - * Initialize a struct ttm_fence_driver structure. Returns -ENOMEM if - * out-of-memory. Otherwise returns 0. - */ -extern int -ttm_fence_device_init(int num_classes, - struct ttm_mem_global *mem_glob, - struct ttm_fence_device *fdev, - const struct ttm_fence_class_init *init, - bool replicate_init, - const struct ttm_fence_driver *driver); - -/** - * function ttm_fence_device_release - * - * @fdev: Pointer to the fence device. - * - * Release all resources held by a fence device. Note that before - * this function is called, the caller must have made sure all fence - * objects belonging to this fence device are completely signaled. - */ - -extern void ttm_fence_device_release(struct ttm_fence_device *fdev); - -/** - * ttm_fence_handler - the fence handler. - * - * @fdev: Pointer to the fence device. - * @fence_class: Fence class that signals. - * @sequence: Signaled sequence. - * @type: Types that signal. - * @error: Error from the engine. - * - * This function signals all fences with a sequence previous to the - * @sequence argument, and belonging to @fence_class. The signaled fence - * types are provided in @type. If error is non-zero, the error member - * of the fence with sequence = @sequence is set to @error. This value - * may be reported back to user-space, indicating, for example an illegal - * 3D command or illegal mpeg data. - * - * This function is typically called from the driver::poll method when the - * command sequence preceding the fence marker has executed. It should be - * called with the ttm_fence_class_manager::lock held in write mode and - * may be called from interrupt context. - */ - -extern void -ttm_fence_handler(struct ttm_fence_device *fdev, - uint32_t fence_class, - uint32_t sequence, uint32_t type, uint32_t error); - -/** - * ttm_fence_driver_from_dev - * - * @fdev: The ttm fence device. - * - * Returns a pointer to the fence driver struct. - */ - -static inline const struct ttm_fence_driver *ttm_fence_driver_from_dev( - struct ttm_fence_device *fdev) -{ - return fdev->driver; -} - -/** - * ttm_fence_driver - * - * @fence: Pointer to a ttm fence object. - * - * Returns a pointer to the fence driver struct. - */ - -static inline const struct ttm_fence_driver *ttm_fence_driver(struct - ttm_fence_object - *fence) -{ - return ttm_fence_driver_from_dev(fence->fdev); -} - -/** - * ttm_fence_fc - * - * @fence: Pointer to a ttm fence object. - * - * Returns a pointer to the struct ttm_fence_class_manager for the - * fence class of @fence. - */ - -static inline struct ttm_fence_class_manager *ttm_fence_fc(struct - ttm_fence_object - *fence) -{ - return &fence->fdev->fence_class[fence->fence_class]; -} - -#endif diff --git a/drivers/staging/gma500/psb_ttm_fence_user.c b/drivers/staging/gma500/psb_ttm_fence_user.c deleted file mode 100644 index 36f974fc607d..000000000000 --- a/drivers/staging/gma500/psb_ttm_fence_user.c +++ /dev/null @@ -1,237 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include "psb_ttm_fence_user.h" -#include "ttm/ttm_object.h" -#include "psb_ttm_fence_driver.h" -#include "psb_ttm_userobj_api.h" - -/** - * struct ttm_fence_user_object - * - * @base: The base object used for user-space visibility and refcounting. - * - * @fence: The fence object itself. - * - */ - -struct ttm_fence_user_object { - struct ttm_base_object base; - struct ttm_fence_object fence; -}; - -static struct ttm_fence_user_object *ttm_fence_user_object_lookup( - struct ttm_object_file *tfile, - uint32_t handle) -{ - struct ttm_base_object *base; - - base = ttm_base_object_lookup(tfile, handle); - if (unlikely(base == NULL)) { - printk(KERN_ERR "Invalid fence handle 0x%08lx\n", - (unsigned long)handle); - return NULL; - } - - if (unlikely(base->object_type != ttm_fence_type)) { - ttm_base_object_unref(&base); - printk(KERN_ERR "Invalid fence handle 0x%08lx\n", - (unsigned long)handle); - return NULL; - } - - return container_of(base, struct ttm_fence_user_object, base); -} - -/* - * The fence object destructor. - */ - -static void ttm_fence_user_destroy(struct ttm_fence_object *fence) -{ - struct ttm_fence_user_object *ufence = - container_of(fence, struct ttm_fence_user_object, fence); - - ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence)); - kfree(ufence); -} - -/* - * The base object destructor. We basically unly unreference the - * attached fence object. - */ - -static void ttm_fence_user_release(struct ttm_base_object **p_base) -{ - struct ttm_fence_user_object *ufence; - struct ttm_base_object *base = *p_base; - struct ttm_fence_object *fence; - - *p_base = NULL; - - if (unlikely(base == NULL)) - return; - - ufence = container_of(base, struct ttm_fence_user_object, base); - fence = &ufence->fence; - ttm_fence_object_unref(&fence); -} - -int -ttm_fence_user_create(struct ttm_fence_device *fdev, - struct ttm_object_file *tfile, - uint32_t fence_class, - uint32_t fence_types, - uint32_t create_flags, - struct ttm_fence_object **fence, - uint32_t *user_handle) -{ - int ret; - struct ttm_fence_object *tmp; - struct ttm_fence_user_object *ufence; - - ret = ttm_mem_global_alloc(fdev->mem_glob, - sizeof(*ufence), - false, - false); - if (unlikely(ret != 0)) - return -ENOMEM; - - ufence = kmalloc(sizeof(*ufence), GFP_KERNEL); - if (unlikely(ufence == NULL)) { - ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence)); - return -ENOMEM; - } - - ret = ttm_fence_object_init(fdev, - fence_class, - fence_types, create_flags, - &ttm_fence_user_destroy, &ufence->fence); - - if (unlikely(ret != 0)) - goto out_err0; - - /* - * One fence ref is held by the fence ptr we return. - * The other one by the base object. Need to up the - * fence refcount before we publish this object to - * user-space. - */ - - tmp = ttm_fence_object_ref(&ufence->fence); - ret = ttm_base_object_init(tfile, &ufence->base, - false, ttm_fence_type, - &ttm_fence_user_release, NULL); - - if (unlikely(ret != 0)) - goto out_err1; - - *fence = &ufence->fence; - *user_handle = ufence->base.hash.key; - - return 0; -out_err1: - ttm_fence_object_unref(&tmp); - tmp = &ufence->fence; - ttm_fence_object_unref(&tmp); - return ret; -out_err0: - ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence)); - kfree(ufence); - return ret; -} - -int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data) -{ - int ret; - union ttm_fence_signaled_arg *arg = data; - struct ttm_fence_object *fence; - struct ttm_fence_info info; - struct ttm_fence_user_object *ufence; - struct ttm_base_object *base; - ret = 0; - - ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle); - if (unlikely(ufence == NULL)) - return -EINVAL; - - fence = &ufence->fence; - - if (arg->req.flush) { - ret = ttm_fence_object_flush(fence, arg->req.fence_type); - if (unlikely(ret != 0)) - goto out; - } - - info = ttm_fence_get_info(fence); - arg->rep.signaled_types = info.signaled_types; - arg->rep.fence_error = info.error; - -out: - base = &ufence->base; - ttm_base_object_unref(&base); - return ret; -} - -int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data) -{ - int ret; - union ttm_fence_finish_arg *arg = data; - struct ttm_fence_user_object *ufence; - struct ttm_base_object *base; - struct ttm_fence_object *fence; - ret = 0; - - ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle); - if (unlikely(ufence == NULL)) - return -EINVAL; - - fence = &ufence->fence; - - ret = ttm_fence_object_wait(fence, - arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY, - true, arg->req.fence_type); - if (likely(ret == 0)) { - struct ttm_fence_info info = ttm_fence_get_info(fence); - - arg->rep.signaled_types = info.signaled_types; - arg->rep.fence_error = info.error; - } - - base = &ufence->base; - ttm_base_object_unref(&base); - - return ret; -} - -int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data) -{ - struct ttm_fence_unref_arg *arg = data; - int ret = 0; - - ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type); - return ret; -} diff --git a/drivers/staging/gma500/psb_ttm_fence_user.h b/drivers/staging/gma500/psb_ttm_fence_user.h deleted file mode 100644 index fc13f89c6e12..000000000000 --- a/drivers/staging/gma500/psb_ttm_fence_user.h +++ /dev/null @@ -1,140 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors - * Thomas Hellström - */ - -#ifndef TTM_FENCE_USER_H -#define TTM_FENCE_USER_H - -#if !defined(__KERNEL__) && !defined(_KERNEL) -#include -#endif - -#define TTM_FENCE_MAJOR 0 -#define TTM_FENCE_MINOR 1 -#define TTM_FENCE_PL 0 -#define TTM_FENCE_DATE "080819" - -/** - * struct ttm_fence_signaled_req - * - * @handle: Handle to the fence object. Input. - * - * @fence_type: Fence types we want to flush. Input. - * - * @flush: Boolean. Flush the indicated fence_types. Input. - * - * Argument to the TTM_FENCE_SIGNALED ioctl. - */ - -struct ttm_fence_signaled_req { - uint32_t handle; - uint32_t fence_type; - int32_t flush; - uint32_t pad64; -}; - -/** - * struct ttm_fence_rep - * - * @signaled_types: Fence type that has signaled. - * - * @fence_error: Command execution error. - * Hardware errors that are consequences of the execution - * of the command stream preceding the fence are reported - * here. - * - * Output argument to the TTM_FENCE_SIGNALED and - * TTM_FENCE_FINISH ioctls. - */ - -struct ttm_fence_rep { - uint32_t signaled_types; - uint32_t fence_error; -}; - -union ttm_fence_signaled_arg { - struct ttm_fence_signaled_req req; - struct ttm_fence_rep rep; -}; - -/* - * Waiting mode flags for the TTM_FENCE_FINISH ioctl. - * - * TTM_FENCE_FINISH_MODE_LAZY: Allow for sleeps during polling - * wait. - * - * TTM_FENCE_FINISH_MODE_NO_BLOCK: Don't block waiting for GPU, - * but return -EBUSY if the buffer is busy. - */ - -#define TTM_FENCE_FINISH_MODE_LAZY (1 << 0) -#define TTM_FENCE_FINISH_MODE_NO_BLOCK (1 << 1) - -/** - * struct ttm_fence_finish_req - * - * @handle: Handle to the fence object. Input. - * - * @fence_type: Fence types we want to finish. - * - * @mode: Wait mode. - * - * Input to the TTM_FENCE_FINISH ioctl. - */ - -struct ttm_fence_finish_req { - uint32_t handle; - uint32_t fence_type; - uint32_t mode; - uint32_t pad64; -}; - -union ttm_fence_finish_arg { - struct ttm_fence_finish_req req; - struct ttm_fence_rep rep; -}; - -/** - * struct ttm_fence_unref_arg - * - * @handle: Handle to the fence object. - * - * Argument to the TTM_FENCE_UNREF ioctl. - */ - -struct ttm_fence_unref_arg { - uint32_t handle; - uint32_t pad64; -}; - -/* - * Ioctl offsets frome extenstion start. - */ - -#define TTM_FENCE_SIGNALED 0x01 -#define TTM_FENCE_FINISH 0x02 -#define TTM_FENCE_UNREF 0x03 - -#endif diff --git a/drivers/staging/gma500/psb_ttm_glue.c b/drivers/staging/gma500/psb_ttm_glue.c deleted file mode 100644 index d1d965e69ecd..000000000000 --- a/drivers/staging/gma500/psb_ttm_glue.c +++ /dev/null @@ -1,349 +0,0 @@ -/************************************************************************** - * Copyright (c) 2008, Intel Corporation. - * All Rights Reserved. - * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA. - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ - - -#include -#include "psb_drv.h" -#include "psb_ttm_userobj_api.h" -#include - - -static struct vm_operations_struct psb_ttm_vm_ops; - -/** - * NOTE: driver_private of drm_file is now a struct psb_file_data struct - * pPriv in struct psb_file_data contains the original psb_fpriv; - */ -int psb_open(struct inode *inode, struct file *filp) -{ - struct drm_file *file_priv; - struct drm_psb_private *dev_priv; - struct psb_fpriv *psb_fp; - struct psb_file_data *pvr_file_priv; - int ret; - - DRM_DEBUG("\n"); - - ret = drm_open(inode, filp); - if (unlikely(ret)) - return ret; - - psb_fp = kzalloc(sizeof(*psb_fp), GFP_KERNEL); - - if (unlikely(psb_fp == NULL)) - goto out_err0; - - file_priv = (struct drm_file *) filp->private_data; - dev_priv = psb_priv(file_priv->minor->dev); - - DRM_DEBUG("is_master %d\n", file_priv->is_master ? 1 : 0); - - psb_fp->tfile = ttm_object_file_init(dev_priv->tdev, - PSB_FILE_OBJECT_HASH_ORDER); - if (unlikely(psb_fp->tfile == NULL)) - goto out_err1; - - pvr_file_priv = (struct psb_file_data *)file_priv->driver_priv; - if (!pvr_file_priv) { - DRM_ERROR("drm file private is NULL\n"); - goto out_err1; - } - - pvr_file_priv->priv = psb_fp; - if (unlikely(dev_priv->bdev.dev_mapping == NULL)) - dev_priv->bdev.dev_mapping = dev_priv->dev->dev_mapping; - - return 0; - -out_err1: - kfree(psb_fp); -out_err0: - (void) drm_release(inode, filp); - return ret; -} - -int psb_release(struct inode *inode, struct file *filp) -{ - struct drm_file *file_priv; - struct psb_fpriv *psb_fp; - struct drm_psb_private *dev_priv; - int ret; - file_priv = (struct drm_file *) filp->private_data; - psb_fp = psb_fpriv(file_priv); - dev_priv = psb_priv(file_priv->minor->dev); - - ttm_object_file_release(&psb_fp->tfile); - kfree(psb_fp); - - ret = drm_release(inode, filp); - - return ret; -} - -int psb_fence_signaled_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - - return ttm_fence_signaled_ioctl(psb_fpriv(file_priv)->tfile, data); -} - -int psb_fence_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_fence_finish_ioctl(psb_fpriv(file_priv)->tfile, data); -} - -int psb_fence_unref_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_fence_unref_ioctl(psb_fpriv(file_priv)->tfile, data); -} - -int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_pl_waitidle_ioctl(psb_fpriv(file_priv)->tfile, data); -} - -int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_pl_setstatus_ioctl(psb_fpriv(file_priv)->tfile, - &psb_priv(dev)->ttm_lock, data); - -} - -int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_pl_synccpu_ioctl(psb_fpriv(file_priv)->tfile, data); -} - -int psb_pl_unref_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_pl_unref_ioctl(psb_fpriv(file_priv)->tfile, data); - -} - -int psb_pl_reference_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return ttm_pl_reference_ioctl(psb_fpriv(file_priv)->tfile, data); - -} - -int psb_pl_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - - return ttm_pl_create_ioctl(psb_fpriv(file_priv)->tfile, - &dev_priv->bdev, &dev_priv->ttm_lock, data); - -} - -int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - - return ttm_pl_ub_create_ioctl(psb_fpriv(file_priv)->tfile, - &dev_priv->bdev, &dev_priv->ttm_lock, data); - -} -/** - * psb_ttm_fault - Wrapper around the ttm fault method. - * - * @vma: The struct vm_area_struct as in the vm fault() method. - * @vmf: The struct vm_fault as in the vm fault() method. - * - * Since ttm_fault() will reserve buffers while faulting, - * we need to take the ttm read lock around it, as this driver - * relies on the ttm_lock in write mode to exclude all threads from - * reserving and thus validating buffers in aperture- and memory shortage - * situations. - */ - -static int psb_ttm_fault(struct vm_area_struct *vma, - struct vm_fault *vmf) -{ - struct ttm_buffer_object *bo = (struct ttm_buffer_object *) - vma->vm_private_data; - struct drm_psb_private *dev_priv = - container_of(bo->bdev, struct drm_psb_private, bdev); - int ret; - - ret = ttm_read_lock(&dev_priv->ttm_lock, true); - if (unlikely(ret != 0)) - return VM_FAULT_NOPAGE; - - ret = dev_priv->ttm_vm_ops->fault(vma, vmf); - - ttm_read_unlock(&dev_priv->ttm_lock); - return ret; -} - -/** - * if vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET call directly to - * PVRMMap - */ -int psb_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv; - struct drm_psb_private *dev_priv; - int ret; - - if (vma->vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET || - vma->vm_pgoff > 2 * DRM_PSB_FILE_PAGE_OFFSET) -#if 0 /* FIXMEAC */ - return PVRMMap(filp, vma); -#else - return -EINVAL; -#endif - - file_priv = (struct drm_file *) filp->private_data; - dev_priv = psb_priv(file_priv->minor->dev); - - ret = ttm_bo_mmap(filp, vma, &dev_priv->bdev); - if (unlikely(ret != 0)) - return ret; - - if (unlikely(dev_priv->ttm_vm_ops == NULL)) { - dev_priv->ttm_vm_ops = (struct vm_operations_struct *) - vma->vm_ops; - psb_ttm_vm_ops = *vma->vm_ops; - psb_ttm_vm_ops.fault = &psb_ttm_fault; - } - - vma->vm_ops = &psb_ttm_vm_ops; - - return 0; -} -/* -ssize_t psb_ttm_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - struct drm_file *file_priv = (struct drm_file *)filp->private_data; - struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev); - - return ttm_bo_io(&dev_priv->bdev, filp, buf, NULL, count, f_pos, 1); -} - -ssize_t psb_ttm_read(struct file *filp, char __user *buf, - size_t count, loff_t *f_pos) -{ - struct drm_file *file_priv = (struct drm_file *)filp->private_data; - struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev); - - return ttm_bo_io(&dev_priv->bdev, filp, NULL, buf, count, f_pos, 1); -} -*/ -int psb_verify_access(struct ttm_buffer_object *bo, - struct file *filp) -{ - struct drm_file *file_priv = (struct drm_file *)filp->private_data; - - if (capable(CAP_SYS_ADMIN)) - return 0; - - if (unlikely(!file_priv->authenticated)) - return -EPERM; - - return ttm_pl_verify_access(bo, psb_fpriv(file_priv)->tfile); -} - -static int psb_ttm_mem_global_init(struct drm_global_reference *ref) -{ - return ttm_mem_global_init(ref->object); -} - -static void psb_ttm_mem_global_release(struct drm_global_reference *ref) -{ - ttm_mem_global_release(ref->object); -} - -int psb_ttm_global_init(struct drm_psb_private *dev_priv) -{ - struct drm_global_reference *global_ref; - int ret; - - global_ref = &dev_priv->mem_global_ref; - global_ref->global_type = DRM_GLOBAL_TTM_MEM; - global_ref->size = sizeof(struct ttm_mem_global); - global_ref->init = &psb_ttm_mem_global_init; - global_ref->release = &psb_ttm_mem_global_release; - - ret = drm_global_item_ref(global_ref); - if (unlikely(ret != 0)) { - DRM_ERROR("Failed referencing a global TTM memory object.\n"); - return ret; - } - - dev_priv->bo_global_ref.mem_glob = dev_priv->mem_global_ref.object; - global_ref = &dev_priv->bo_global_ref.ref; - global_ref->global_type = DRM_GLOBAL_TTM_BO; - global_ref->size = sizeof(struct ttm_bo_global); - global_ref->init = &ttm_bo_global_init; - global_ref->release = &ttm_bo_global_release; - ret = drm_global_item_ref(global_ref); - if (ret != 0) { - DRM_ERROR("Failed setting up TTM BO subsystem.\n"); - drm_global_item_unref(global_ref); - return ret; - } - return 0; -} - -void psb_ttm_global_release(struct drm_psb_private *dev_priv) -{ - drm_global_item_unref(&dev_priv->mem_global_ref); -} - -int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_getpageaddrs_arg *arg = data; - struct ttm_buffer_object *bo; - struct ttm_tt *ttm; - struct page **tt_pages; - unsigned long i, num_pages; - unsigned long *p = arg->page_addrs; - int ret = 0; - - bo = ttm_buffer_object_lookup(psb_fpriv(file_priv)->tfile, - arg->handle); - if (unlikely(bo == NULL)) { - printk(KERN_ERR - "Could not find buffer object for getpageaddrs.\n"); - return -EINVAL; - } - - arg->gtt_offset = bo->offset; - ttm = bo->ttm; - num_pages = ttm->num_pages; - tt_pages = ttm->pages; - - for (i = 0; i < num_pages; i++) - p[i] = (unsigned long)page_to_phys(tt_pages[i]); - - return ret; -} diff --git a/drivers/staging/gma500/psb_ttm_placement_user.c b/drivers/staging/gma500/psb_ttm_placement_user.c deleted file mode 100644 index 272b397982ed..000000000000 --- a/drivers/staging/gma500/psb_ttm_placement_user.c +++ /dev/null @@ -1,628 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include "psb_ttm_placement_user.h" -#include "ttm/ttm_bo_driver.h" -#include "ttm/ttm_object.h" -#include "psb_ttm_userobj_api.h" -#include "ttm/ttm_lock.h" -#include -#include - -struct ttm_bo_user_object { - struct ttm_base_object base; - struct ttm_buffer_object bo; -}; - -static size_t pl_bo_size; - -static uint32_t psb_busy_prios[] = { - TTM_PL_TT, - TTM_PL_PRIV0, /* CI */ - TTM_PL_PRIV2, /* RAR */ - TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */ - TTM_PL_SYSTEM -}; - -static const struct ttm_placement default_placement = { - 0, 0, 0, NULL, 5, psb_busy_prios -}; - -static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages) -{ - size_t page_array_size = - (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK; - - if (unlikely(pl_bo_size == 0)) { - pl_bo_size = bdev->glob->ttm_bo_extra_size + - ttm_round_pot(sizeof(struct ttm_bo_user_object)); - } - - return bdev->glob->ttm_bo_size + 2 * page_array_size; -} - -static struct ttm_bo_user_object *ttm_bo_user_lookup(struct ttm_object_file - *tfile, uint32_t handle) -{ - struct ttm_base_object *base; - - base = ttm_base_object_lookup(tfile, handle); - if (unlikely(base == NULL)) { - printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n", - (unsigned long)handle); - return NULL; - } - - if (unlikely(base->object_type != ttm_buffer_type)) { - ttm_base_object_unref(&base); - printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n", - (unsigned long)handle); - return NULL; - } - - return container_of(base, struct ttm_bo_user_object, base); -} - -struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file - *tfile, uint32_t handle) -{ - struct ttm_bo_user_object *user_bo; - struct ttm_base_object *base; - - user_bo = ttm_bo_user_lookup(tfile, handle); - if (unlikely(user_bo == NULL)) - return NULL; - - (void)ttm_bo_reference(&user_bo->bo); - base = &user_bo->base; - ttm_base_object_unref(&base); - return &user_bo->bo; -} - -static void ttm_bo_user_destroy(struct ttm_buffer_object *bo) -{ - struct ttm_bo_user_object *user_bo = - container_of(bo, struct ttm_bo_user_object, bo); - - ttm_mem_global_free(bo->glob->mem_glob, bo->acc_size); - kfree(user_bo); -} - -static void ttm_bo_user_release(struct ttm_base_object **p_base) -{ - struct ttm_bo_user_object *user_bo; - struct ttm_base_object *base = *p_base; - struct ttm_buffer_object *bo; - - *p_base = NULL; - - if (unlikely(base == NULL)) - return; - - user_bo = container_of(base, struct ttm_bo_user_object, base); - bo = &user_bo->bo; - ttm_bo_unref(&bo); -} - -static void ttm_bo_user_ref_release(struct ttm_base_object *base, - enum ttm_ref_type ref_type) -{ - struct ttm_bo_user_object *user_bo = - container_of(base, struct ttm_bo_user_object, base); - struct ttm_buffer_object *bo = &user_bo->bo; - - switch (ref_type) { - case TTM_REF_SYNCCPU_WRITE: - ttm_bo_synccpu_write_release(bo); - break; - default: - BUG(); - } -} - -static void ttm_pl_fill_rep(struct ttm_buffer_object *bo, - struct ttm_pl_rep *rep) -{ - struct ttm_bo_user_object *user_bo = - container_of(bo, struct ttm_bo_user_object, bo); - - rep->gpu_offset = bo->offset; - rep->bo_size = bo->num_pages << PAGE_SHIFT; - rep->map_handle = bo->addr_space_offset; - rep->placement = bo->mem.placement; - rep->handle = user_bo->base.hash.key; - rep->sync_object_arg = (uint32_t) (unsigned long)bo->sync_obj_arg; -} - -/* FIXME Copy from upstream TTM */ -static inline size_t ttm_bo_size(struct ttm_bo_global *glob, - unsigned long num_pages) -{ - size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) & - PAGE_MASK; - - return glob->ttm_bo_size + 2 * page_array_size; -} - -/* FIXME Copy from upstream TTM "ttm_bo_create", upstream TTM does not - export this, so copy it here */ -static int ttm_bo_create_private(struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - struct ttm_placement *placement, - uint32_t page_alignment, - unsigned long buffer_start, - bool interruptible, - struct file *persistant_swap_storage, - struct ttm_buffer_object **p_bo) -{ - struct ttm_buffer_object *bo; - struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; - int ret; - - size_t acc_size = - ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT); - ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); - if (unlikely(ret != 0)) - return ret; - - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - - if (unlikely(bo == NULL)) { - ttm_mem_global_free(mem_glob, acc_size); - return -ENOMEM; - } - - ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, - buffer_start, interruptible, - persistant_swap_storage, acc_size, NULL); - if (likely(ret == 0)) - *p_bo = bo; - - return ret; -} - -int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo, - struct ttm_placement *placement) -{ - int i; - - for (i = 0; i < placement->num_placement; i++) { - if (!capable(CAP_SYS_ADMIN)) { - if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { - printk(KERN_ERR TTM_PFX "Need to be root to " - "modify NO_EVICT status.\n"); - return -EINVAL; - } - } - } - for (i = 0; i < placement->num_busy_placement; i++) { - if (!capable(CAP_SYS_ADMIN)) { - if (placement->busy_placement[i] - & TTM_PL_FLAG_NO_EVICT) { - printk(KERN_ERR TTM_PFX "Need to be root to modify NO_EVICT status.\n"); - return -EINVAL; - } - } - } - return 0; -} - -int ttm_buffer_object_create(struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - uint32_t flags, - uint32_t page_alignment, - unsigned long buffer_start, - bool interruptible, - struct file *persistant_swap_storage, - struct ttm_buffer_object **p_bo) -{ - struct ttm_placement placement = default_placement; - int ret; - - if ((flags & TTM_PL_MASK_CACHING) == 0) - flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; - - placement.num_placement = 1; - placement.placement = &flags; - - ret = ttm_bo_create_private(bdev, - size, - type, - &placement, - page_alignment, - buffer_start, - interruptible, - persistant_swap_storage, - p_bo); - - return ret; -} - - -int ttm_pl_create_ioctl(struct ttm_object_file *tfile, - struct ttm_bo_device *bdev, - struct ttm_lock *lock, void *data) -{ - union ttm_pl_create_arg *arg = data; - struct ttm_pl_create_req *req = &arg->req; - struct ttm_pl_rep *rep = &arg->rep; - struct ttm_buffer_object *bo; - struct ttm_buffer_object *tmp; - struct ttm_bo_user_object *user_bo; - uint32_t flags; - int ret = 0; - struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; - struct ttm_placement placement = default_placement; - size_t acc_size = - ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT); - ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); - if (unlikely(ret != 0)) - return ret; - - flags = req->placement; - user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL); - if (unlikely(user_bo == NULL)) { - ttm_mem_global_free(mem_glob, acc_size); - return -ENOMEM; - } - - bo = &user_bo->bo; - ret = ttm_read_lock(lock, true); - if (unlikely(ret != 0)) { - ttm_mem_global_free(mem_glob, acc_size); - kfree(user_bo); - return ret; - } - - placement.num_placement = 1; - placement.placement = &flags; - - if ((flags & TTM_PL_MASK_CACHING) == 0) - flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; - - ret = ttm_bo_init(bdev, bo, req->size, - ttm_bo_type_device, &placement, - req->page_alignment, 0, true, - NULL, acc_size, &ttm_bo_user_destroy); - ttm_read_unlock(lock); - - /* - * Note that the ttm_buffer_object_init function - * would've called the destroy function on failure!! - */ - - if (unlikely(ret != 0)) - goto out; - - tmp = ttm_bo_reference(bo); - ret = ttm_base_object_init(tfile, &user_bo->base, - flags & TTM_PL_FLAG_SHARED, - ttm_buffer_type, - &ttm_bo_user_release, - &ttm_bo_user_ref_release); - if (unlikely(ret != 0)) - goto out_err; - - ttm_pl_fill_rep(bo, rep); - ttm_bo_unref(&bo); -out: - return 0; -out_err: - ttm_bo_unref(&tmp); - ttm_bo_unref(&bo); - return ret; -} - -int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile, - struct ttm_bo_device *bdev, - struct ttm_lock *lock, void *data) -{ - union ttm_pl_create_ub_arg *arg = data; - struct ttm_pl_create_ub_req *req = &arg->req; - struct ttm_pl_rep *rep = &arg->rep; - struct ttm_buffer_object *bo; - struct ttm_buffer_object *tmp; - struct ttm_bo_user_object *user_bo; - uint32_t flags; - int ret = 0; - struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; - struct ttm_placement placement = default_placement; - size_t acc_size = - ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT); - ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); - if (unlikely(ret != 0)) - return ret; - - flags = req->placement; - user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL); - if (unlikely(user_bo == NULL)) { - ttm_mem_global_free(mem_glob, acc_size); - return -ENOMEM; - } - ret = ttm_read_lock(lock, true); - if (unlikely(ret != 0)) { - ttm_mem_global_free(mem_glob, acc_size); - kfree(user_bo); - return ret; - } - bo = &user_bo->bo; - - placement.num_placement = 1; - placement.placement = &flags; - - ret = ttm_bo_init(bdev, - bo, - req->size, - ttm_bo_type_user, - &placement, - req->page_alignment, - req->user_address, - true, - NULL, - acc_size, - &ttm_bo_user_destroy); - - /* - * Note that the ttm_buffer_object_init function - * would've called the destroy function on failure!! - */ - ttm_read_unlock(lock); - if (unlikely(ret != 0)) - goto out; - - tmp = ttm_bo_reference(bo); - ret = ttm_base_object_init(tfile, &user_bo->base, - flags & TTM_PL_FLAG_SHARED, - ttm_buffer_type, - &ttm_bo_user_release, - &ttm_bo_user_ref_release); - if (unlikely(ret != 0)) - goto out_err; - - ttm_pl_fill_rep(bo, rep); - ttm_bo_unref(&bo); -out: - return 0; -out_err: - ttm_bo_unref(&tmp); - ttm_bo_unref(&bo); - return ret; -} - -int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data) -{ - union ttm_pl_reference_arg *arg = data; - struct ttm_pl_rep *rep = &arg->rep; - struct ttm_bo_user_object *user_bo; - struct ttm_buffer_object *bo; - struct ttm_base_object *base; - int ret; - - user_bo = ttm_bo_user_lookup(tfile, arg->req.handle); - if (unlikely(user_bo == NULL)) { - printk(KERN_ERR "Could not reference buffer object.\n"); - return -EINVAL; - } - - bo = &user_bo->bo; - ret = ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL); - if (unlikely(ret != 0)) { - printk(KERN_ERR - "Could not add a reference to buffer object.\n"); - goto out; - } - - ttm_pl_fill_rep(bo, rep); - -out: - base = &user_bo->base; - ttm_base_object_unref(&base); - return ret; -} - -int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data) -{ - struct ttm_pl_reference_req *arg = data; - - return ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_USAGE); -} - -int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data) -{ - struct ttm_pl_synccpu_arg *arg = data; - struct ttm_bo_user_object *user_bo; - struct ttm_buffer_object *bo; - struct ttm_base_object *base; - bool existed; - int ret; - - switch (arg->op) { - case TTM_PL_SYNCCPU_OP_GRAB: - user_bo = ttm_bo_user_lookup(tfile, arg->handle); - if (unlikely(user_bo == NULL)) { - printk(KERN_ERR - "Could not find buffer object for synccpu.\n"); - return -EINVAL; - } - bo = &user_bo->bo; - base = &user_bo->base; - ret = ttm_bo_synccpu_write_grab(bo, - arg->access_mode & - TTM_PL_SYNCCPU_MODE_NO_BLOCK); - if (unlikely(ret != 0)) { - ttm_base_object_unref(&base); - goto out; - } - ret = ttm_ref_object_add(tfile, &user_bo->base, - TTM_REF_SYNCCPU_WRITE, &existed); - if (existed || ret != 0) - ttm_bo_synccpu_write_release(bo); - ttm_base_object_unref(&base); - break; - case TTM_PL_SYNCCPU_OP_RELEASE: - ret = ttm_ref_object_base_unref(tfile, arg->handle, - TTM_REF_SYNCCPU_WRITE); - break; - default: - ret = -EINVAL; - break; - } -out: - return ret; -} - -int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, - struct ttm_lock *lock, void *data) -{ - union ttm_pl_setstatus_arg *arg = data; - struct ttm_pl_setstatus_req *req = &arg->req; - struct ttm_pl_rep *rep = &arg->rep; - struct ttm_buffer_object *bo; - struct ttm_bo_device *bdev; - struct ttm_placement placement = default_placement; - uint32_t flags[2]; - int ret; - - bo = ttm_buffer_object_lookup(tfile, req->handle); - if (unlikely(bo == NULL)) { - printk(KERN_ERR - "Could not find buffer object for setstatus.\n"); - return -EINVAL; - } - - bdev = bo->bdev; - - ret = ttm_read_lock(lock, true); - if (unlikely(ret != 0)) - goto out_err0; - - ret = ttm_bo_reserve(bo, true, false, false, 0); - if (unlikely(ret != 0)) - goto out_err1; - - ret = ttm_bo_wait_cpu(bo, false); - if (unlikely(ret != 0)) - goto out_err2; - - flags[0] = req->set_placement; - flags[1] = req->clr_placement; - - placement.num_placement = 2; - placement.placement = flags; - - /* Review internal locking ? FIXMEAC */ - ret = psb_ttm_bo_check_placement(bo, &placement); - if (unlikely(ret != 0)) - goto out_err2; - - placement.num_placement = 1; - flags[0] = (req->set_placement | bo->mem.placement) - & ~req->clr_placement; - - ret = ttm_bo_validate(bo, &placement, true, false, false); - if (unlikely(ret != 0)) - goto out_err2; - - ttm_pl_fill_rep(bo, rep); -out_err2: - ttm_bo_unreserve(bo); -out_err1: - ttm_read_unlock(lock); -out_err0: - ttm_bo_unref(&bo); - return ret; -} - -static int psb_ttm_bo_block_reservation(struct ttm_buffer_object *bo, - bool interruptible, bool no_wait) -{ - int ret; - - while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { - if (no_wait) - return -EBUSY; - else if (interruptible) { - ret = wait_event_interruptible(bo->event_queue, - atomic_read(&bo->reserved) == 0); - if (unlikely(ret != 0)) - return -ERESTART; - } else { - wait_event(bo->event_queue, - atomic_read(&bo->reserved) == 0); - } - } - return 0; -} - -static void psb_ttm_bo_unblock_reservation(struct ttm_buffer_object *bo) -{ - atomic_set(&bo->reserved, 0); - wake_up_all(&bo->event_queue); -} - -int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data) -{ - struct ttm_pl_waitidle_arg *arg = data; - struct ttm_buffer_object *bo; - int ret; - - bo = ttm_buffer_object_lookup(tfile, arg->handle); - if (unlikely(bo == NULL)) { - printk(KERN_ERR "Could not find buffer object for waitidle.\n"); - return -EINVAL; - } - - ret = - psb_ttm_bo_block_reservation(bo, true, - arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK); - if (unlikely(ret != 0)) - goto out; - ret = ttm_bo_wait(bo, - arg->mode & TTM_PL_WAITIDLE_MODE_LAZY, - true, arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK); - psb_ttm_bo_unblock_reservation(bo); -out: - ttm_bo_unref(&bo); - return ret; -} - -int ttm_pl_verify_access(struct ttm_buffer_object *bo, - struct ttm_object_file *tfile) -{ - struct ttm_bo_user_object *ubo; - - /* - * Check bo subclass. - */ - - if (unlikely(bo->destroy != &ttm_bo_user_destroy)) - return -EPERM; - - ubo = container_of(bo, struct ttm_bo_user_object, bo); - if (likely(ubo->base.shareable || ubo->base.tfile == tfile)) - return 0; - - return -EPERM; -} diff --git a/drivers/staging/gma500/psb_ttm_userobj_api.h b/drivers/staging/gma500/psb_ttm_userobj_api.h deleted file mode 100644 index 6a8f7c4ddc78..000000000000 --- a/drivers/staging/gma500/psb_ttm_userobj_api.h +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#ifndef _TTM_USEROBJ_API_H_ -#define _TTM_USEROBJ_API_H_ - -#include "psb_ttm_placement_user.h" -#include "psb_ttm_fence_user.h" -#include "ttm/ttm_object.h" -#include "psb_ttm_fence_api.h" -#include "ttm/ttm_bo_api.h" - -struct ttm_lock; - -/* - * User ioctls. - */ - -extern int ttm_pl_create_ioctl(struct ttm_object_file *tfile, - struct ttm_bo_device *bdev, - struct ttm_lock *lock, void *data); -extern int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile, - struct ttm_bo_device *bdev, - struct ttm_lock *lock, void *data); -extern int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data); -extern int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data); -extern int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data); -extern int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, - struct ttm_lock *lock, void *data); -extern int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data); -extern int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data); -extern int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data); -extern int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data); - -extern int -ttm_fence_user_create(struct ttm_fence_device *fdev, - struct ttm_object_file *tfile, - uint32_t fence_class, - uint32_t fence_types, - uint32_t create_flags, - struct ttm_fence_object **fence, uint32_t * user_handle); - -extern struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file - *tfile, - uint32_t handle); - -extern int -ttm_pl_verify_access(struct ttm_buffer_object *bo, - struct ttm_object_file *tfile); - -extern int ttm_buffer_object_create(struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - uint32_t flags, - uint32_t page_alignment, - unsigned long buffer_start, - bool interruptible, - struct file *persistant_swap_storage, - struct ttm_buffer_object **p_bo); - -extern int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo, - struct ttm_placement *placement); -#endif -- GitLab From 8fc5945f8fdcd7e902b3852051c8e1d9f0714487 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 30 Mar 2011 10:01:42 +0100 Subject: [PATCH 0491/5560] staging: gma500: Remove extra semi-colon. The patch below removes an extra semi-colon from various parts of the kernel. Please have a look when you have time, and let me know if its legit or not. Signed-off-by: Justin P. Mattock Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index c15e2f9a244d..dc6f74a071ab 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -192,7 +192,7 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) struct drm_device *dev = psbfb->base.dev; struct drm_psb_private *dev_priv = dev->dev_private; struct psb_gtt *pg = dev_priv->pg; - unsigned long phys_addr = (unsigned long)pg->stolen_base;; + unsigned long phys_addr = (unsigned long)pg->stolen_base; page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; -- GitLab From c34433b19d66a7c476fdfaa04c15d8eb9ca86461 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 30 Mar 2011 10:01:54 +0100 Subject: [PATCH 0492/5560] staging: gma500: turn on psb SDVO Keep this as its own commit for bisection purposes Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_fb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index dc6f74a071ab..6c75df504c50 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -703,9 +703,8 @@ static void psb_setup_outputs(struct drm_device *dev) else DRM_ERROR("DSI is not supported\n"); } else { - /* FIXME: check if SDVO init should be re-enabled */ psb_intel_lvds_init(dev, &dev_priv->mode_dev); - /* psb_intel_sdvo_init(dev, SDVOB); */ + psb_intel_sdvo_init(dev, SDVOB); } list_for_each_entry(connector, &dev->mode_config.connector_list, -- GitLab From b0e2326ca7117d802d7af552d2bfdf10ba966ea3 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:41:04 +0100 Subject: [PATCH 0493/5560] staging: gma500: Another file we don't need Zap... bang And take out a few more variables that are now dead Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 10 +- drivers/staging/gma500/psb_drv.h | 1 - drivers/staging/gma500/psb_irq.c | 2 - .../staging/gma500/psb_ttm_placement_user.h | 252 ------------------ 4 files changed, 1 insertion(+), 264 deletions(-) delete mode 100644 drivers/staging/gma500/psb_ttm_placement_user.h diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index ba08b071d662..5f72e5adae36 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -38,25 +38,16 @@ int drm_psb_debug; static int drm_psb_trap_pagefaults; -int drm_psb_disable_vsync = 1; int drm_psb_no_fb; -int gfxrtdelay = 2 * 1000; static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); MODULE_PARM_DESC(debug, "Enable debug output"); MODULE_PARM_DESC(no_fb, "Disable FBdev"); MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults"); -MODULE_PARM_DESC(disable_vsync, "Disable vsync interrupts"); -MODULE_PARM_DESC(force_pipeb, "Forces PIPEB to become primary fb"); -MODULE_PARM_DESC(ta_mem_size, "TA memory size in kiB"); -MODULE_PARM_DESC(ospm, "switch for ospm support"); -MODULE_PARM_DESC(rtpm, "Specifies Runtime PM delay for GFX"); -MODULE_PARM_DESC(hdmi_edid, "EDID info for HDMI monitor"); module_param_named(debug, drm_psb_debug, int, 0600); module_param_named(no_fb, drm_psb_no_fb, int, 0600); module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); -module_param_named(rtpm, gfxrtdelay, int, 0600); static struct pci_device_id pciidlist[] = { @@ -498,6 +489,7 @@ static int psb_do_init(struct drm_device *dev) pg->gatt_pages : PSB_TT_PRIV0_PLIMIT; tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start; tt_pages -= tt_start >> PAGE_SHIFT; + /* FIXME: can we kill ta_mem_size ? */ dev_priv->sizes.ta_mem_size = 0; PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index aad09fb2a358..7361fbfc0682 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -769,7 +769,6 @@ extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; extern int drm_psb_debug; extern int drm_psb_no_fb; -extern int drm_psb_disable_vsync; extern int drm_idle_check_interval; #define PSB_DEBUG_GENERAL(_fmt, _arg...) \ diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index 4597c8824721..9c2dbe4ed566 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -545,7 +545,6 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - drm_psb_disable_vsync = 0; mid_enable_pipe_event(dev_priv, pipe); psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); @@ -567,7 +566,6 @@ void psb_disable_vblank(struct drm_device *dev, int pipe) spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - drm_psb_disable_vsync = 1; mid_disable_pipe_event(dev_priv, pipe); psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); diff --git a/drivers/staging/gma500/psb_ttm_placement_user.h b/drivers/staging/gma500/psb_ttm_placement_user.h deleted file mode 100644 index 8b7068b54441..000000000000 --- a/drivers/staging/gma500/psb_ttm_placement_user.h +++ /dev/null @@ -1,252 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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. - * - **************************************************************************/ -/* - * Authors - * Thomas Hellström - */ - -#ifndef _TTM_PLACEMENT_USER_H_ -#define _TTM_PLACEMENT_USER_H_ - -#if !defined(__KERNEL__) && !defined(_KERNEL) -#include -#else -#include -#endif - -#include "ttm/ttm_placement.h" - -#define TTM_PLACEMENT_MAJOR 0 -#define TTM_PLACEMENT_MINOR 1 -#define TTM_PLACEMENT_PL 0 -#define TTM_PLACEMENT_DATE "080819" - -/** - * struct ttm_pl_create_req - * - * @size: The buffer object size. - * @placement: Flags that indicate initial acceptable - * placement. - * @page_alignment: Required alignment in pages. - * - * Input to the TTM_BO_CREATE ioctl. - */ - -struct ttm_pl_create_req { - uint64_t size; - uint32_t placement; - uint32_t page_alignment; -}; - -/** - * struct ttm_pl_create_ub_req - * - * @size: The buffer object size. - * @user_address: User-space address of the memory area that - * should be used to back the buffer object cast to 64-bit. - * @placement: Flags that indicate initial acceptable - * placement. - * @page_alignment: Required alignment in pages. - * - * Input to the TTM_BO_CREATE_UB ioctl. - */ - -struct ttm_pl_create_ub_req { - uint64_t size; - uint64_t user_address; - uint32_t placement; - uint32_t page_alignment; -}; - -/** - * struct ttm_pl_rep - * - * @gpu_offset: The current offset into the memory region used. - * This can be used directly by the GPU if there are no - * additional GPU mapping procedures used by the driver. - * - * @bo_size: Actual buffer object size. - * - * @map_handle: Offset into the device address space. - * Used for map, seek, read, write. This will never change - * during the lifetime of an object. - * - * @placement: Flag indicating the placement status of - * the buffer object using the TTM_PL flags above. - * - * @sync_object_arg: Used for user-space synchronization and - * depends on the synchronization model used. If fences are - * used, this is the buffer_object::fence_type_mask - * - * Output from the TTM_PL_CREATE and TTM_PL_REFERENCE, and - * TTM_PL_SETSTATUS ioctls. - */ - -struct ttm_pl_rep { - uint64_t gpu_offset; - uint64_t bo_size; - uint64_t map_handle; - uint32_t placement; - uint32_t handle; - uint32_t sync_object_arg; - uint32_t pad64; -}; - -/** - * struct ttm_pl_setstatus_req - * - * @set_placement: Placement flags to set. - * - * @clr_placement: Placement flags to clear. - * - * @handle: The object handle - * - * Input to the TTM_PL_SETSTATUS ioctl. - */ - -struct ttm_pl_setstatus_req { - uint32_t set_placement; - uint32_t clr_placement; - uint32_t handle; - uint32_t pad64; -}; - -/** - * struct ttm_pl_reference_req - * - * @handle: The object to put a reference on. - * - * Input to the TTM_PL_REFERENCE and the TTM_PL_UNREFERENCE ioctls. - */ - -struct ttm_pl_reference_req { - uint32_t handle; - uint32_t pad64; -}; - -/* - * ACCESS mode flags for SYNCCPU. - * - * TTM_SYNCCPU_MODE_READ will guarantee that the GPU is not - * writing to the buffer. - * - * TTM_SYNCCPU_MODE_WRITE will guarantee that the GPU is not - * accessing the buffer. - * - * TTM_SYNCCPU_MODE_NO_BLOCK makes sure the call does not wait - * for GPU accesses to finish but return -EBUSY. - * - * TTM_SYNCCPU_MODE_TRYCACHED Try to place the buffer in cacheable - * memory while synchronized for CPU. - */ - -#define TTM_PL_SYNCCPU_MODE_READ TTM_ACCESS_READ -#define TTM_PL_SYNCCPU_MODE_WRITE TTM_ACCESS_WRITE -#define TTM_PL_SYNCCPU_MODE_NO_BLOCK (1 << 2) -#define TTM_PL_SYNCCPU_MODE_TRYCACHED (1 << 3) - -/** - * struct ttm_pl_synccpu_arg - * - * @handle: The object to synchronize. - * - * @access_mode: access mode indicated by the - * TTM_SYNCCPU_MODE flags. - * - * @op: indicates whether to grab or release the - * buffer for cpu usage. - * - * Input to the TTM_PL_SYNCCPU ioctl. - */ - -struct ttm_pl_synccpu_arg { - uint32_t handle; - uint32_t access_mode; - enum { - TTM_PL_SYNCCPU_OP_GRAB, - TTM_PL_SYNCCPU_OP_RELEASE - } op; - uint32_t pad64; -}; - -/* - * Waiting mode flags for the TTM_BO_WAITIDLE ioctl. - * - * TTM_WAITIDLE_MODE_LAZY: Allow for sleeps during polling - * wait. - * - * TTM_WAITIDLE_MODE_NO_BLOCK: Don't block waiting for GPU, - * but return -EBUSY if the buffer is busy. - */ - -#define TTM_PL_WAITIDLE_MODE_LAZY (1 << 0) -#define TTM_PL_WAITIDLE_MODE_NO_BLOCK (1 << 1) - -/** - * struct ttm_waitidle_arg - * - * @handle: The object to synchronize. - * - * @mode: wait mode indicated by the - * TTM_SYNCCPU_MODE flags. - * - * Argument to the TTM_BO_WAITIDLE ioctl. - */ - -struct ttm_pl_waitidle_arg { - uint32_t handle; - uint32_t mode; -}; - -union ttm_pl_create_arg { - struct ttm_pl_create_req req; - struct ttm_pl_rep rep; -}; - -union ttm_pl_reference_arg { - struct ttm_pl_reference_req req; - struct ttm_pl_rep rep; -}; - -union ttm_pl_setstatus_arg { - struct ttm_pl_setstatus_req req; - struct ttm_pl_rep rep; -}; - -union ttm_pl_create_ub_arg { - struct ttm_pl_create_ub_req req; - struct ttm_pl_rep rep; -}; - -/* - * Ioctl offsets. - */ - -#define TTM_PL_CREATE 0x00 -#define TTM_PL_REFERENCE 0x01 -#define TTM_PL_UNREF 0x02 -#define TTM_PL_SYNCCPU 0x03 -#define TTM_PL_WAITIDLE 0x04 -#define TTM_PL_SETSTATUS 0x05 -#define TTM_PL_CREATE_UB 0x06 - -#endif -- GitLab From 0c6b262753eededa3596d37e8d68ef44718c365b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:41:12 +0100 Subject: [PATCH 0494/5560] staging: gma500: kill some more #if 0 bits Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_mmu.c | 61 -------------------------------- 1 file changed, 61 deletions(-) diff --git a/drivers/staging/gma500/psb_mmu.c b/drivers/staging/gma500/psb_mmu.c index edd0d4923e0f..c904d73b1de3 100644 --- a/drivers/staging/gma500/psb_mmu.c +++ b/drivers/staging/gma500/psb_mmu.c @@ -444,67 +444,6 @@ static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt, pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte; } -#if 0 -static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd, - uint32_t mmu_offset) -{ - uint32_t *v; - uint32_t pfn; - - v = kmap_atomic(pd->p, KM_USER0); - if (!v) { - printk(KERN_INFO "Could not kmap pde page.\n"); - return 0; - } - pfn = v[psb_mmu_pd_index(mmu_offset)]; - /* printk(KERN_INFO "pde is 0x%08x\n",pfn); */ - kunmap_atomic(v, KM_USER0); - if (((pfn & 0x0F) != PSB_PTE_VALID)) { - printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n", - mmu_offset, pfn); - } - v = ioremap(pfn & 0xFFFFF000, 4096); - if (!v) { - printk(KERN_INFO "Could not kmap pte page.\n"); - return 0; - } - pfn = v[psb_mmu_pt_index(mmu_offset)]; - /* printk(KERN_INFO "pte is 0x%08x\n",pfn); */ - iounmap(v); - if (((pfn & 0x0F) != PSB_PTE_VALID)) { - printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n", - mmu_offset, pfn); - } - return pfn >> PAGE_SHIFT; -} - -static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd, - uint32_t mmu_offset, - uint32_t gtt_pages) -{ - uint32_t start; - uint32_t next; - - printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n", - mmu_offset, gtt_pages); - down_read(&pd->driver->sem); - start = psb_mmu_check_pte_locked(pd, mmu_offset); - mmu_offset += PAGE_SIZE; - gtt_pages -= 1; - while (gtt_pages--) { - next = psb_mmu_check_pte_locked(pd, mmu_offset); - if (next != start + 1) { - printk(KERN_INFO - "Ptes out of order: 0x%08x, 0x%08x.\n", - start, next); - } - start = next; - mmu_offset += PAGE_SIZE; - } - up_read(&pd->driver->sem); -} - -#endif void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset, uint32_t gtt_start, -- GitLab From ad9f792e67c0a0522bb78109bc979197c9756fcc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:41:22 +0100 Subject: [PATCH 0495/5560] staging: gma500: Fix some set up bugs found by comparing driver versions Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 5f72e5adae36..02629779d2a4 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -670,6 +670,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) return ret; + PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); + PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); + /* igd_opregion_init(&dev_priv->opregion_dev); */ acpi_video_register(); if (dev_priv->lid_state) -- GitLab From 99172946238c77160c97cc71b68bb0004c00aed2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:41:30 +0100 Subject: [PATCH 0496/5560] staging: gma500: Add a test ioctl for issuing 2D accel ops via user space Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_2d.c | 2 +- drivers/staging/gma500/psb_drv.h | 3 +++ drivers/staging/gma500/psb_fb.c | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c index 9a0691f75d15..94bce5c0648e 100644 --- a/drivers/staging/gma500/psb_2d.c +++ b/drivers/staging/gma500/psb_2d.c @@ -84,7 +84,7 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv, /* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize it with console use */ -static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, +int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, unsigned size) { int ret = 0; diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 7361fbfc0682..8c1ecebf69f1 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -709,6 +709,9 @@ extern int psbfb_sync(struct fb_info *info); extern void psb_spank(struct drm_psb_private *dev_priv); +extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, + unsigned size); + /* *psb_reset.c */ diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index 6c75df504c50..6499f28cb2af 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -270,6 +270,31 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) return 0; } +static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +{ + struct psb_fbdev *fbdev = info->par; + struct psb_framebuffer *psbfb = fbdev->pfb; + struct drm_device *dev = psbfb->base.dev; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 __user *p = (u32 __user *)arg; + u32 l; + u32 buf[32]; + switch (cmd) { + case 0x12345678: + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + if (get_user(l, p)) + return -EFAULT; + if (l > 32) + return -EMSGSIZE; + if (copy_from_user(buf, p + 1, l)) + return -EFAULT; + psbfb_2d_submit(dev_priv, buf, l); + return 0; + default: + return -ENOTTY; + } +} static struct fb_ops psbfb_ops = { .owner = THIS_MODULE, @@ -282,6 +307,7 @@ static struct fb_ops psbfb_ops = { .fb_imageblit = psbfb_imageblit, .fb_mmap = psbfb_mmap, .fb_sync = psbfb_sync, + .fb_ioctl = psbfb_ioctl, }; static struct drm_framebuffer *psb_framebuffer_create -- GitLab From a3461ee16c73f9caa4948651f9c24c284205a378 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:41:40 +0100 Subject: [PATCH 0497/5560] staging: gma500: prune more unused fields Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 13 --- drivers/staging/gma500/psb_drv.h | 134 ------------------------------- 2 files changed, 147 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 02629779d2a4..518b0fb80271 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -181,11 +181,6 @@ static struct drm_ioctl_desc psb_ioctls[] = { }; -static void psb_set_uopt(struct drm_psb_uopt *uopt) -{ - return; -} - static void psb_lastclose(struct drm_device *dev) { return; @@ -589,16 +584,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->dev = dev; - mutex_init(&dev_priv->temp_mem); - mutex_init(&dev_priv->cmdbuf_mutex); - mutex_init(&dev_priv->reset_mutex); - spin_lock_init(&dev_priv->reloc_lock); - - DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue); - dev->dev_private = (void *) dev_priv; dev_priv->chipset = chipset; - psb_set_uopt(&dev_priv->uopt); PSB_DEBUG_INIT("Mapping MMIO\n"); resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 8c1ecebf69f1..7d07c97e8044 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -228,28 +228,11 @@ struct psb_intel_opregion { int enabled; }; -/* - *User options. - */ - -struct drm_psb_uopt { - int pad; /*keep it here in case we use it in future*/ -}; - struct drm_psb_private { - /* - * DSI info. - */ - void * dbi_dsr_info; - void * dsi_configs[2]; - struct drm_device *dev; - struct vm_operations_struct *ttm_vm_ops; unsigned long chipset; - struct drm_psb_uopt uopt; - struct psb_gtt *pg; /*GTT Memory manager*/ @@ -270,7 +253,6 @@ struct drm_psb_private { uint32_t vdc_irq_mask; uint32_t pipestat[PSB_NUM_PIPE]; - bool vblanksEnabledForFlips; spinlock_t irqmask_lock; @@ -287,23 +269,6 @@ struct drm_psb_private { *Memory managers */ - int have_tt; - int have_mem_mmu; - struct mutex temp_mem; - - /* - *Relocation buffer mapping. - */ - - spinlock_t reloc_lock; - unsigned int rel_mapped_pages; - wait_queue_head_t rel_mapped_queue; - - /* - *SAREA - */ - struct drm_psb_sarea *sarea_priv; - /* *OSPM info */ @@ -468,91 +433,10 @@ struct drm_psb_private { uint32_t saveOVC_OGAMC4; uint32_t saveOVC_OGAMC5; - /* - * extra MDFLD Register state - */ - uint32_t saveHDMIPHYMISCCTL; - uint32_t saveHDMIB_CONTROL; - uint32_t saveDSPCCNTR; - uint32_t savePIPECCONF; - uint32_t savePIPECSRC; - uint32_t saveHTOTAL_C; - uint32_t saveHBLANK_C; - uint32_t saveHSYNC_C; - uint32_t saveVTOTAL_C; - uint32_t saveVBLANK_C; - uint32_t saveVSYNC_C; - uint32_t saveDSPCSTRIDE; - uint32_t saveDSPCSIZE; - uint32_t saveDSPCPOS; - uint32_t saveDSPCSURF; - uint32_t saveDSPCLINOFF; - uint32_t saveDSPCTILEOFF; - uint32_t saveDSPCCURSOR_CTRL; - uint32_t saveDSPCCURSOR_BASE; - uint32_t saveDSPCCURSOR_POS; - uint32_t save_palette_c[256]; - uint32_t saveOV_OVADD_C; - uint32_t saveOV_OGAMC0_C; - uint32_t saveOV_OGAMC1_C; - uint32_t saveOV_OGAMC2_C; - uint32_t saveOV_OGAMC3_C; - uint32_t saveOV_OGAMC4_C; - uint32_t saveOV_OGAMC5_C; - - /* DSI reg save */ - uint32_t saveDEVICE_READY_REG; - uint32_t saveINTR_EN_REG; - uint32_t saveDSI_FUNC_PRG_REG; - uint32_t saveHS_TX_TIMEOUT_REG; - uint32_t saveLP_RX_TIMEOUT_REG; - uint32_t saveTURN_AROUND_TIMEOUT_REG; - uint32_t saveDEVICE_RESET_REG; - uint32_t saveDPI_RESOLUTION_REG; - uint32_t saveHORIZ_SYNC_PAD_COUNT_REG; - uint32_t saveHORIZ_BACK_PORCH_COUNT_REG; - uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG; - uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG; - uint32_t saveVERT_SYNC_PAD_COUNT_REG; - uint32_t saveVERT_BACK_PORCH_COUNT_REG; - uint32_t saveVERT_FRONT_PORCH_COUNT_REG; - uint32_t saveHIGH_LOW_SWITCH_COUNT_REG; - uint32_t saveINIT_COUNT_REG; - uint32_t saveMAX_RET_PAK_REG; - uint32_t saveVIDEO_FMT_REG; - uint32_t saveEOT_DISABLE_REG; - uint32_t saveLP_BYTECLK_REG; - uint32_t saveHS_LS_DBI_ENABLE_REG; - uint32_t saveTXCLKESC_REG; - uint32_t saveDPHY_PARAM_REG; - uint32_t saveMIPI_CONTROL_REG; - uint32_t saveMIPI; - uint32_t saveMIPI_C; - void (*init_drvIC)(struct drm_device *dev); - void (*dsi_prePowerState)(struct drm_device *dev); - void (*dsi_postPowerState)(struct drm_device *dev); - - /* DPST Register Save */ - uint32_t saveHISTOGRAM_INT_CONTROL_REG; - uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG; - uint32_t savePWM_CONTROL_LOGIC; - /* MSI reg save */ - uint32_t msi_addr; uint32_t msi_data; - /* - *Scheduling. - */ - - struct mutex reset_mutex; - struct mutex cmdbuf_mutex; - /*uint32_t ta_mem_pages; - struct psb_ta_mem *ta_mem; - int force_ta_mem_load;*/ - atomic_t val_seq; - /* * LID-Switch */ @@ -566,8 +450,6 @@ struct drm_psb_private { *Watchdog */ - int timer_available; - uint32_t apm_reg; uint16_t apm_base; @@ -583,27 +465,11 @@ struct drm_psb_private { }; -struct psb_file_data { /* TODO: Audit this, remove the indirection and set - it up properly in open/postclose ACFIXME */ - void *priv; -}; - -struct psb_fpriv { - struct ttm_object_file *tfile; -}; - struct psb_mmu_driver; extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); extern int drm_pick_crtcs(struct drm_device *dev); -static inline struct psb_fpriv *psb_fpriv(struct drm_file *file_priv) -{ - struct psb_file_data *pvr_file_priv - = (struct psb_file_data *)file_priv->driver_priv; - return (struct psb_fpriv *) pvr_file_priv->priv; -} - static inline struct drm_psb_private *psb_priv(struct drm_device *dev) { return (struct drm_psb_private *) dev->dev_private; -- GitLab From c3460fd3ec3819c37aeb7bd68e4705ff87733872 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:42:08 +0100 Subject: [PATCH 0498/5560] staging: gma500: begin tidying up the power management Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/mrst_crtc.c | 15 +- drivers/staging/gma500/mrst_lvds.c | 10 +- drivers/staging/gma500/psb_bl.c | 9 +- drivers/staging/gma500/psb_drv.c | 53 +- drivers/staging/gma500/psb_drv.h | 11 +- drivers/staging/gma500/psb_intel_display.c | 35 +- drivers/staging/gma500/psb_intel_lvds.c | 20 +- drivers/staging/gma500/psb_irq.c | 176 ++--- drivers/staging/gma500/psb_powermgmt.c | 750 ++++++--------------- drivers/staging/gma500/psb_powermgmt.h | 55 +- 10 files changed, 363 insertions(+), 771 deletions(-) diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c index 89b9cac898aa..664d0e7bbc18 100644 --- a/drivers/staging/gma500/mrst_crtc.c +++ b/drivers/staging/gma500/mrst_crtc.c @@ -174,8 +174,7 @@ static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode) PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe); - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return; /* XXX: When our outputs are all unaware of DPMS modes other than off @@ -270,7 +269,7 @@ static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode) REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000); /* Must write Bit 14 of the Chicken Bit Register */ - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } /** @@ -323,8 +322,7 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc, PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe); - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return 0; memcpy(&psb_intel_crtc->saved_mode, @@ -514,7 +512,7 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc, psb_intel_wait_for_vblank(dev); mrst_crtc_mode_set_exit: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); return 0; } @@ -551,8 +549,7 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, return 0; } - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return 0; Start = mode_dev->bo_offset(dev, psbfb); @@ -596,7 +593,7 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, } pipe_set_base_exit: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); return ret; } diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c index 4628b01694a9..21b9056ec84a 100644 --- a/drivers/staging/gma500/mrst_lvds.c +++ b/drivers/staging/gma500/mrst_lvds.c @@ -48,8 +48,7 @@ static void mrst_lvds_set_power(struct drm_device *dev, DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; PSB_DEBUG_ENTRY("\n"); - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return; if (on) { @@ -69,7 +68,7 @@ static void mrst_lvds_set_power(struct drm_device *dev, pm_request_idle(&dev->pdev->dev); } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode) @@ -99,8 +98,7 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, PSB_DEBUG_ENTRY("\n"); - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return; /* @@ -144,7 +142,7 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c index a2729fdee8fc..57b9a5e5e7b3 100644 --- a/drivers/staging/gma500/psb_bl.c +++ b/drivers/staging/gma500/psb_bl.c @@ -81,7 +81,7 @@ int mrst_set_brightness(struct backlight_device *bd) if (level < 1) level = 1; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, 0)) { /* Calculate and set the brightness value */ max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; blc_pwm_ctl = level * max_pwm_blc / 100; @@ -103,7 +103,7 @@ int mrst_set_brightness(struct backlight_device *bd) /* force PWM bit on */ REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } psb_brightness = level; return 0; @@ -161,8 +161,7 @@ static int device_backlight_init(struct drm_device *dev) value /= bl_max_freq; value /= blc_pwm_precision_factor; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { if (IS_MRST(dev)) { if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) return 2; @@ -182,7 +181,7 @@ static int device_backlight_init(struct drm_device *dev) (value)); } } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } return 0; } diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 518b0fb80271..be8f11d19ee2 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -558,7 +558,7 @@ static int psb_driver_unload(struct drm_device *dev) psb_intel_destroy_bios(dev); } - ospm_power_uninit(); + gma_power_uninit(dev); return 0; } @@ -612,7 +612,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) } /* Init OSPM support */ - ospm_power_init(dev); + gma_power_init(dev); ret = -ENOMEM; @@ -837,13 +837,12 @@ static int psb_dpst_ioctl(struct drm_device *dev, void *data, uint32_t y; uint32_t reg; - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) + if (!gma_power_begin(dev, 0)) return 0; reg = PSB_RVDC32(PIPEASRC); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); /* horizontal is the left 16 bits */ x = reg >> 16; @@ -920,11 +919,10 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, drm_fb = obj_to_fb(obj); psb_fb = to_psb_fb(drm_fb); - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, 0)) { REG_WRITE(DSPASURF, psb_fb->offset); REG_READ(DSPASURF); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { dev_priv->saveDSPASURF = psb_fb->offset; } @@ -1010,11 +1008,10 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, { struct drm_psb_private *dev_priv = psb_priv(dev); struct drm_psb_register_rw_arg *arg = data; - UHBUsage usage = - arg->b_force_hw_on ? OSPM_UHB_FORCE_POWER_ON : OSPM_UHB_ONLY_IF_ON; + bool usage = arg->b_force_hw_on ? true : false; if (arg->display_write_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) PSB_WVDC32(arg->display.pfit_controls, PFIT_CONTROL); @@ -1039,7 +1036,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, if (arg->display_write_mask & REGRWBITS_VTOTAL_B) PSB_WVDC32(arg->display.vtotal_b, VTOTAL_B); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) dev_priv->savePFIT_CONTROL = @@ -1064,7 +1061,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, } if (arg->display_read_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { if (arg->display_read_mask & REGRWBITS_PFIT_CONTROLS) arg->display.pfit_controls = @@ -1085,7 +1082,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A); if (arg->display_read_mask & REGRWBITS_VTOTAL_B) arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { if (arg->display_read_mask & REGRWBITS_PFIT_CONTROLS) @@ -1111,7 +1108,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, } if (arg->overlay_write_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5); PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4); @@ -1162,7 +1159,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, } } } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5; @@ -1188,7 +1185,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, } if (arg->overlay_read_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5); arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4); @@ -1209,7 +1206,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, arg->overlay.OVADD = PSB_RVDC32(OV_OVADD); if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5; @@ -1235,7 +1232,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, } if (arg->sprite_enable_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { PSB_WVDC32(0x1F3E, DSPARB); PSB_WVDC32(arg->sprite.dspa_control | PSB_RVDC32(DSPACNTR), DSPACNTR); @@ -1250,22 +1247,22 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE); PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); PSB_RVDC32(DSPCSURF); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } } if (arg->sprite_disable_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { PSB_WVDC32(0x3F3E, DSPARB); PSB_WVDC32(0x0, DSPCCNTR); PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); PSB_RVDC32(DSPCSURF); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } } if (arg->subpicture_enable_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { uint32_t temp; if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) { temp = PSB_RVDC32(DSPACNTR); @@ -1309,12 +1306,12 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, PSB_WVDC32(temp, DSPCSURF); PSB_RVDC32(DSPCSURF); } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } } if (arg->subpicture_disable_mask != 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (gma_power_begin(dev, usage)) { uint32_t temp; if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) { temp = PSB_RVDC32(DSPACNTR); @@ -1355,7 +1352,7 @@ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, PSB_WVDC32(temp, DSPCSURF); PSB_RVDC32(DSPCSURF); } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } } @@ -1513,8 +1510,8 @@ static struct drm_driver driver = { static struct pci_driver psb_pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, - .resume = ospm_power_resume, - .suspend = ospm_power_suspend, + .resume = gma_power_resume, + .suspend = gma_power_suspend, .probe = psb_probe, .remove = psb_remove, #ifdef CONFIG_PM diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 7d07c97e8044..c3609e01f6c9 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -246,7 +246,6 @@ struct drm_psb_private { uint8_t *vdc_reg; uint32_t gatt_free_offset; - /* *Fencing / irq. */ @@ -256,6 +255,14 @@ struct drm_psb_private { spinlock_t irqmask_lock; + /* + * Power + */ + + bool suspended; + bool display_power; + int display_count; + /* *Modesetting */ @@ -527,8 +534,6 @@ extern int psb_irq_disable_dpst(struct drm_device *dev); extern void psb_irq_preinstall(struct drm_device *dev); extern int psb_irq_postinstall(struct drm_device *dev); extern void psb_irq_uninstall(struct drm_device *dev); -extern void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands); -extern int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands); extern void psb_irq_turn_on_dpst(struct drm_device *dev); extern void psb_irq_turn_off_dpst(struct drm_device *dev); diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index d24d0bf8be5a..b462f32670b8 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -359,8 +359,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, return 0; } - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return 0; Start = mode_dev->bo_offset(dev, psbfb); @@ -405,7 +404,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, psb_intel_pipe_set_base_exit: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); return ret; } @@ -816,8 +815,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc) return; } - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { for (i = 0; i < 256; i++) { REG_WRITE(palreg + 4 * i, ((psb_intel_crtc->lut_r[i] + @@ -827,7 +825,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc) (psb_intel_crtc->lut_b[i] + psb_intel_crtc->lut_adj[i])); } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { for (i = 0; i < 256; i++) { dev_priv->save_palette_a[i] = @@ -1046,11 +1044,10 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, temp = 0; temp |= CURSOR_MODE_DISABLE; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { REG_WRITE(control, temp); REG_WRITE(base, 0); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } /* unpin the old bo */ @@ -1104,11 +1101,10 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, temp |= (pipe << 28); temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { REG_WRITE(control, temp); REG_WRITE(base, addr); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } /* unpin the old bo */ @@ -1143,11 +1139,10 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) adder = psb_intel_crtc->cursor_addr; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } return 0; } @@ -1197,15 +1192,14 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev, bool is_lvds; struct drm_psb_private *dev_priv = dev->dev_private; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) fp = REG_READ((pipe == 0) ? FPA0 : FPB0); else fp = REG_READ((pipe == 0) ? FPA1 : FPB1); is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { dpll = (pipe == 0) ? dev_priv->saveDPLL_A : dev_priv->saveDPLL_B; @@ -1277,13 +1271,12 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, int vsync; struct drm_psb_private *dev_priv = dev->dev_private; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { htot = (pipe == 0) ? dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B; diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c index 1e07f416691c..28e04a3e7b6f 100644 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -83,13 +83,12 @@ static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; u32 retVal; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { retVal = ((REG_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else retVal = ((dev_priv->saveBLC_PWM_CTL & BACKLIGHT_MODULATION_FREQ_MASK) >> @@ -200,14 +199,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) struct drm_psb_private *dev_priv = dev->dev_private; u32 blc_pwm_ctl; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } else { blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & ~BACKLIGHT_DUTY_CYCLE_MASK; @@ -224,8 +222,7 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, { u32 pp_status; - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return; if (on) { @@ -248,7 +245,7 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, } while (pp_status & PP_ON); } - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) @@ -457,8 +454,7 @@ void psb_intel_lvds_prepare(struct drm_encoder *encoder) PSB_DEBUG_ENTRY("\n"); - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_FORCE_POWER_ON)) + if (!gma_power_begin(dev, true)) return; mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); @@ -467,7 +463,7 @@ void psb_intel_lvds_prepare(struct drm_encoder *encoder) psb_intel_lvds_set_power(dev, output, false); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } void psb_intel_lvds_commit(struct drm_encoder *encoder) diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index 9c2dbe4ed566..9ea37e588874 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -88,13 +88,12 @@ psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) u32 reg = psb_pipestat(pipe); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev_priv->dev, false)) { u32 writeVal = PSB_RVDC32(reg); writeVal |= (mask | (mask >> 16)); PSB_WVDC32(writeVal, reg); (void) PSB_RVDC32(reg); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev_priv->dev); } } } @@ -105,39 +104,36 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) if ((dev_priv->pipestat[pipe] & mask) != 0) { u32 reg = psb_pipestat(pipe); dev_priv->pipestat[pipe] &= ~mask; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev_priv->dev, false)) { u32 writeVal = PSB_RVDC32(reg); writeVal &= ~mask; PSB_WVDC32(writeVal, reg); (void) PSB_RVDC32(reg); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev_priv->dev); } } } void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev_priv->dev, false)) { u32 pipe_event = mid_pipe_event(pipe); dev_priv->vdc_irq_mask |= pipe_event; PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev_priv->dev); } } void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) { if (dev_priv->pipestat[pipe] == 0) { - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev_priv->dev, false)) { u32 pipe_event = mid_pipe_event(pipe); dev_priv->vdc_irq_mask &= ~pipe_event; PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev_priv->dev); } } } @@ -242,7 +238,7 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) vdc_stat &= dev_priv->vdc_irq_mask; spin_unlock(&dev_priv->irqmask_lock); - if (dsp_int && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + if (dsp_int && gma_power_is_on(dev)) { psb_vdc_interrupt(dev, vdc_stat); handled = 1; } @@ -270,55 +266,29 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) } void psb_irq_preinstall(struct drm_device *dev) -{ - psb_irq_preinstall_islands(dev, OSPM_ALL_ISLANDS); -} - -/** - * FIXME: should I remove display irq enable here?? - */ -void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands) { struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; unsigned long irqflags; - PSB_DEBUG_ENTRY("\n"); - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - if (hw_islands & OSPM_DISPLAY_ISLAND) { - if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (dev->vblank_enabled[0]) - dev_priv->vdc_irq_mask |= - _PSB_PIPEA_EVENT_FLAG; - if (dev->vblank_enabled[1]) - dev_priv->vdc_irq_mask |= - _MDFLD_PIPEB_EVENT_FLAG; - if (dev->vblank_enabled[2]) - dev_priv->vdc_irq_mask |= - _MDFLD_PIPEC_EVENT_FLAG; - } - } -/* NO I DONT WANT ANY IRQS GRRR FIXMEAC */ - if (hw_islands & OSPM_GRAPHICS_ISLAND) - dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG; -/* */ + if (gma_power_is_on(dev)) + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); + if (dev->vblank_enabled[0]) + dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG; + if (dev->vblank_enabled[1]) + dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; + if (dev->vblank_enabled[2]) + dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; + /*This register is safe even if display island is off*/ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } int psb_irq_postinstall(struct drm_device *dev) { - return psb_irq_postinstall_islands(dev, OSPM_ALL_ISLANDS); -} - -int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands) -{ - struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; unsigned long irqflags; @@ -327,47 +297,30 @@ int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands) spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - /*This register is safe even if display island is off*/ + /* This register is safe even if display island is off */ PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (hw_islands & OSPM_DISPLAY_ISLAND) { - if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) { - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - - if (dev->vblank_enabled[0]) - psb_enable_pipestat(dev_priv, 0, - PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 0, - PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[1]) - psb_enable_pipestat(dev_priv, 1, - PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 1, - PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[2]) - psb_enable_pipestat(dev_priv, 2, - PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 2, - PIPE_VBLANK_INTERRUPT_ENABLE); - } - } + if (dev->vblank_enabled[0]) + psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); + if (dev->vblank_enabled[1]) + psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); + if (dev->vblank_enabled[2]) + psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); return 0; } void psb_irq_uninstall(struct drm_device *dev) -{ - psb_irq_uninstall_islands(dev, OSPM_ALL_ISLANDS); -} - -void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands) { struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; @@ -377,39 +330,29 @@ void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands) spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - if (hw_islands & OSPM_DISPLAY_ISLAND) { - if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) { - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (dev->vblank_enabled[0]) - psb_disable_pipestat(dev_priv, 0, - PIPE_VBLANK_INTERRUPT_ENABLE); + if (dev->vblank_enabled[0]) + psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - if (dev->vblank_enabled[1]) - psb_disable_pipestat(dev_priv, 1, - PIPE_VBLANK_INTERRUPT_ENABLE); + if (dev->vblank_enabled[1]) + psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - if (dev->vblank_enabled[2]) - psb_disable_pipestat(dev_priv, 2, - PIPE_VBLANK_INTERRUPT_ENABLE); - } - dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | - _PSB_IRQ_MSVDX_FLAG | - _LNC_IRQ_TOPAZ_FLAG; - } - /*TODO: remove following code*/ - if (hw_islands & OSPM_GRAPHICS_ISLAND) - dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG; + if (dev->vblank_enabled[2]) + psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); + + dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | + _PSB_IRQ_MSVDX_FLAG | + _LNC_IRQ_TOPAZ_FLAG; - /*These two registers are safe even if display island is off*/ + /* These two registers are safe even if display island is off */ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); wmb(); - /*This register is safe even if display island is off*/ + /* This register is safe even if display island is off */ PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } @@ -420,8 +363,7 @@ void psb_irq_turn_on_dpst(struct drm_device *dev) u32 hist_reg; u32 pwm_reg; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL); hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL); @@ -443,7 +385,7 @@ void psb_irq_turn_on_dpst(struct drm_device *dev) PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, PWM_CONTROL_LOGIC); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } } @@ -472,8 +414,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev) u32 hist_reg; u32 pwm_reg; - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); @@ -484,7 +425,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev) PWM_CONTROL_LOGIC); pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } } @@ -526,18 +467,16 @@ static int psb_vblank_do_wait(struct drm_device *dev, */ int psb_enable_vblank(struct drm_device *dev, int pipe) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; uint32_t reg_val = 0; uint32_t pipeconf_reg = mid_pipeconf(pipe); PSB_DEBUG_ENTRY("\n"); - if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, - OSPM_UHB_ONLY_IF_ON)) { + if (gma_power_begin(dev, false)) { reg_val = REG_READ(pipeconf_reg); - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); } if (!(reg_val & PIPEACONF_ENABLE)) @@ -558,8 +497,7 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) */ void psb_disable_vblank(struct drm_device *dev, int pipe) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; PSB_DEBUG_ENTRY("\n"); @@ -601,7 +539,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) return 0; } - if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) + if (!gma_power_begin(dev, false)) return 0; reg_val = REG_READ(pipeconf_reg); @@ -630,7 +568,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) psb_get_vblank_counter_exit: - ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + gma_power_end(dev); return count; } diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c index 7deb1ba82545..fc0ed7ab1973 100644 --- a/drivers/staging/gma500/psb_powermgmt.c +++ b/drivers/staging/gma500/psb_powermgmt.c @@ -24,83 +24,73 @@ * Authors: * Benjamin Defnet * Rajesh Poornachandran - * + * Massively reworked + * Alan Cox */ #include "psb_powermgmt.h" #include "psb_drv.h" +#include "psb_reg.h" #include "psb_intel_reg.h" #include #include -#undef OSPM_GFX_DPK - -extern u32 gui32SGXDeviceID; -extern u32 gui32MRSTDisplayDeviceID; -extern u32 gui32MRSTMSVDXDeviceID; -extern u32 gui32MRSTTOPAZDeviceID; - -struct drm_device *gpDrmDevice = NULL; static struct mutex power_mutex; -static bool gbSuspendInProgress = false; -static bool gbResumeInProgress = false; -static int g_hw_power_status_mask; -static atomic_t g_display_access_count; -static atomic_t g_graphics_access_count; -static atomic_t g_videoenc_access_count; -static atomic_t g_videodec_access_count; -int allow_runtime_pm = 0; - -void ospm_power_island_up(int hw_islands); -void ospm_power_island_down(int hw_islands); -static bool gbSuspended = false; -bool gbgfxsuspended = false; -/* - * ospm_power_init +/** + * gma_power_init - initialise power manager + * @dev: our device * - * Description: Initialize this ospm power management module + * Set up for power management tracking of our hardware. */ -void ospm_power_init(struct drm_device *dev) +void gma_power_init(struct drm_device *dev) { - struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; - - gpDrmDevice = dev; + struct drm_psb_private *dev_priv = dev->dev_private; dev_priv->apm_base = dev_priv->apm_reg & 0xffff; dev_priv->ospm_base &= 0xffff; + dev_priv->display_power = true; /* We start active */ + dev_priv->display_count = 0; /* Currently no users */ + dev_priv->suspended = false; /* And not suspended */ mutex_init(&power_mutex); - g_hw_power_status_mask = OSPM_ALL_ISLANDS; - atomic_set(&g_display_access_count, 0); - atomic_set(&g_graphics_access_count, 0); - atomic_set(&g_videoenc_access_count, 0); - atomic_set(&g_videodec_access_count, 0); + + if (!IS_MRST(dev)) { + /* FIXME: wants further review */ + u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL); + /* Disable 2D clock gating */ + gating &= ~3; + gating |= 1; + PSB_WSGX32(gating, PSB_CR_CLKGATECTL); + PSB_RSGX32(PSB_CR_CLKGATECTL); + } } -/* - * ospm_power_uninit +/** + * gma_power_uninit - end power manager + * @dev: device to end for * - * Description: Uninitialize this ospm power management module + * Undo the effects of gma_power_init */ -void ospm_power_uninit(void) +void gma_power_uninit(struct drm_device *dev) { mutex_destroy(&power_mutex); - pm_runtime_disable(&gpDrmDevice->pdev->dev); - pm_runtime_set_suspended(&gpDrmDevice->pdev->dev); + pm_runtime_disable(&dev->pdev->dev); + pm_runtime_set_suspended(&dev->pdev->dev); } -/* - * save_display_registers +/** + * save_display_registers - save registers lost on suspend + * @dev: our DRM device * - * Description: We are going to suspend so save current display - * register state. + * Save the state we need in order to be able to restore the interface + * upon resume from suspend */ static int save_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc * crtc; - struct drm_connector * connector; + struct drm_crtc *crtc; + struct drm_connector *connector; /* Display arbitration control + watermarks */ dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); @@ -112,37 +102,31 @@ static int save_display_registers(struct drm_device *dev) dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); - /*save crtc and output state*/ + /* Save crtc and output state */ mutex_lock(&dev->mode_config.mutex); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if(drm_helper_crtc_in_use(crtc)) { + if (drm_helper_crtc_in_use(crtc)) crtc->funcs->save(crtc); - } } - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) connector->funcs->save(connector); - } - mutex_unlock(&dev->mode_config.mutex); - - /* Interrupt state */ - /* - * Handled in psb_irq.c - */ + mutex_unlock(&dev->mode_config.mutex); return 0; } -/* - * restore_display_registers +/** + * restore_display_registers - restore lost register state + * @dev: our DRM device * - * Description: We are going to resume so restore display register state. + * Restore register state that was lost during suspend and resume. */ static int restore_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc * crtc; - struct drm_connector * connector; + struct drm_crtc *crtc; + struct drm_connector *connector; /* Display arbitration + watermarks */ PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); @@ -158,39 +142,57 @@ static int restore_display_registers(struct drm_device *dev) PSB_WVDC32(0x80000000, VGACNTRL); mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if(drm_helper_crtc_in_use(crtc)) + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + if (drm_helper_crtc_in_use(crtc)) crtc->funcs->restore(crtc); - } - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - connector->funcs->restore(connector); - } - mutex_unlock(&dev->mode_config.mutex); - /*Interrupt state*/ - /* - * Handled in psb_irq.c - */ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + connector->funcs->restore(connector); + mutex_unlock(&dev->mode_config.mutex); return 0; } -/* - * powermgmt_suspend_display + +/** + * power_down - power down the display island + * @dev: our DRM device * - * Description: Suspend the display hardware saving state and disabling - * as necessary. + * Power down the display interface of our device */ -void ospm_suspend_display(struct drm_device *dev) +static void power_down(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - int pp_stat, ret=0; + u32 pwr_mask ; + u32 pwr_sts; - printk(KERN_ALERT "%s \n", __func__); + if (IS_MRST(dev)) { + pwr_mask = PSB_PWRGT_DISPLAY_MASK; + outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC); -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "%s \n", __func__); -#endif - if (!(g_hw_power_status_mask & OSPM_DISPLAY_ISLAND)) + while (true) { + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & pwr_mask) == pwr_mask) + break; + else + udelay(10); + } + dev_priv->display_power = false; + } +} + + +/** + * gma_suspend_display - suspend the display logic + * @dev: our DRM device + * + * Suspend the display logic of the graphics interface + */ +static void gma_suspend_display(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int pp_stat; + + if (dev_priv->suspended) return; save_display_registers(dev); @@ -225,33 +227,55 @@ void ospm_suspend_display(struct drm_device *dev) != DPI_FIFO_EMPTY); PSB_WVDC32(0, DEVICE_READY_REG); /* turn off panel power */ - ret = 0; } - ospm_power_island_down(OSPM_DISPLAY_ISLAND); + power_down(dev); } /* - * ospm_resume_display + * power_up * - * Description: Resume the display hardware restoring state and enabling - * as necessary. + * Description: Restore power to the specified island(s) (powergating) */ -void ospm_resume_display(struct pci_dev *pdev) +static void power_up(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK; + u32 pwr_sts, pwr_cnt; + + if (IS_MRST(dev)) { + pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); + pwr_cnt &= ~pwr_mask; + outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); + + while (true) { + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & pwr_mask) == 0) + break; + else + udelay(10); + } + } + dev_priv->suspended = false; + dev_priv->display_power = true; +} + +/** + * gma_resume_display - resume display side logic + * + * Resume the display hardware restoring state and enabling + * as necessary. + */ +static void gma_resume_display(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); struct drm_psb_private *dev_priv = dev->dev_private; struct psb_gtt *pg = dev_priv->pg; - printk(KERN_ALERT "%s \n", __func__); - -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "%s \n", __func__); -#endif - if (g_hw_power_status_mask & OSPM_DISPLAY_ISLAND) + if (dev_priv->suspended == false) return; /* turn on the display power island */ - ospm_power_island_up(OSPM_DISPLAY_ISLAND); + power_up(dev); PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); pci_write_config_word(pdev, PSB_GMCH_CTRL, @@ -267,26 +291,21 @@ void ospm_resume_display(struct pci_dev *pdev) restore_display_registers(dev); } -#if 1 -/* - * ospm_suspend_pci +/** + * gma_suspend_pci - suspend PCI side + * @pdev: PCI device * - * Description: Suspend the pci device saving state and disabling - * as necessary. + * Perform the suspend processing on our PCI device state */ -static void ospm_suspend_pci(struct pci_dev *pdev) +static void gma_suspend_pci(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); struct drm_psb_private *dev_priv = dev->dev_private; int bsm, vbt; - if (gbSuspended) + if (dev_priv->suspended) return; -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "ospm_suspend_pci\n"); -#endif - pci_save_state(pdev); pci_read_config_dword(pdev, 0x5C, &bsm); dev_priv->saveBSM = bsm; @@ -298,29 +317,25 @@ static void ospm_suspend_pci(struct pci_dev *pdev) pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); - gbSuspended = true; - gbgfxsuspended = true; + dev_priv->suspended = true; } -/* - * ospm_resume_pci +/** + * gma_resume_pci - resume helper + * @dev: our PCI device * - * Description: Resume the pci device restoring state and enabling - * as necessary. + * Perform the resume processing on our PCI device state - rewrite + * register state and re-enable the PCI device */ -static bool ospm_resume_pci(struct pci_dev *pdev) +static bool gma_resume_pci(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); struct drm_psb_private *dev_priv = dev->dev_private; - int ret = 0; + int ret; - if (!gbSuspended) + if (!dev_priv->suspended) return true; -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "ospm_resume_pci\n"); -#endif - pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM); @@ -331,448 +346,131 @@ static bool ospm_resume_pci(struct pci_dev *pdev) ret = pci_enable_device(pdev); if (ret != 0) - printk(KERN_ALERT "ospm_resume_pci: pci_enable_device failed: %d\n", ret); + dev_err(&pdev->dev, "pci_enable failed: %d\n", ret); else - gbSuspended = false; - - return !gbSuspended; -} -#endif -/* - * ospm_power_suspend - * - * Description: OSPM is telling our driver to suspend so save state - * and power down all hardware. - */ -int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state) -{ - int ret = 0; - int graphics_access_count; - int videoenc_access_count; - int videodec_access_count; - int display_access_count; - bool suspend_pci = true; - - if(gbSuspendInProgress || gbResumeInProgress) - { -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "OSPM_GFX_DPK: %s system BUSY \n", __func__); -#endif - return -EBUSY; - } - - mutex_lock(&power_mutex); - - if (!gbSuspended) { - graphics_access_count = atomic_read(&g_graphics_access_count); - videoenc_access_count = atomic_read(&g_videoenc_access_count); - videodec_access_count = atomic_read(&g_videodec_access_count); - display_access_count = atomic_read(&g_display_access_count); - - if (graphics_access_count || - videoenc_access_count || - videodec_access_count || - display_access_count) - ret = -EBUSY; - - if (!ret) { - gbSuspendInProgress = true; - - psb_irq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - ospm_suspend_display(gpDrmDevice); - if (suspend_pci == true) { - ospm_suspend_pci(pdev); - } - gbSuspendInProgress = false; - } else { - printk(KERN_ALERT "ospm_power_suspend: device busy: graphics %d videoenc %d videodec %d display %d\n", graphics_access_count, videoenc_access_count, videodec_access_count, display_access_count); - } - } - - - mutex_unlock(&power_mutex); - return ret; + dev_priv->suspended = false; + return !dev_priv->suspended; } -/* - * ospm_power_island_up +/** + * gma_power_suspend - bus callback for suspend + * @pdev: our PCI device + * @state: suspend type * - * Description: Restore power to the specified island(s) (powergating) + * Called back by the PCI layer during a suspend of the system. We + * perform the necessary shut down steps and save enough state that + * we can undo this when resume is called. */ -void ospm_power_island_up(int hw_islands) +int gma_power_suspend(struct pci_dev *pdev, pm_message_t state) { - u32 pwr_cnt = 0; - u32 pwr_sts = 0; - u32 pwr_mask = 0; - - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) gpDrmDevice->dev_private; - - - if (hw_islands & OSPM_DISPLAY_ISLAND) { - pwr_mask = PSB_PWRGT_DISPLAY_MASK; - - pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); - pwr_cnt &= ~pwr_mask; - outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); + struct drm_device *dev = pci_get_drvdata(pdev); + struct drm_psb_private *dev_priv = dev->dev_private; - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == 0) - break; - else - udelay(10); + mutex_lock(&power_mutex); + if (!dev_priv->suspended) { + if (dev_priv->display_count) { + mutex_unlock(&power_mutex); + return -EBUSY; } + psb_irq_uninstall(dev); + gma_suspend_display(dev); + gma_suspend_pci(pdev); } - - g_hw_power_status_mask |= hw_islands; -} - -/* - * ospm_power_resume - */ -int ospm_power_resume(struct pci_dev *pdev) -{ - if(gbSuspendInProgress || gbResumeInProgress) - { -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "OSPM_GFX_DPK: %s hw_island: Suspend || gbResumeInProgress!!!! \n", __func__); -#endif - return 0; - } - - mutex_lock(&power_mutex); - -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "OSPM_GFX_DPK: ospm_power_resume \n"); -#endif - - gbResumeInProgress = true; - - ospm_resume_pci(pdev); - - ospm_resume_display(gpDrmDevice->pdev); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - - gbResumeInProgress = false; - - mutex_unlock(&power_mutex); - + mutex_unlock(&power_mutex); return 0; } -/* - * ospm_power_island_down +/** + * gma_power_resume - resume power + * @pdev: PCI device * - * Description: Cut power to the specified island(s) (powergating) + * Resume the PCI side of the graphics and then the displays */ -void ospm_power_island_down(int islands) +int gma_power_resume(struct pci_dev *pdev) { -#if 0 - u32 pwr_cnt = 0; - u32 pwr_mask = 0; - u32 pwr_sts = 0; - - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) gpDrmDevice->dev_private; - - g_hw_power_status_mask &= ~islands; - - if (islands & OSPM_GRAPHICS_ISLAND) { - pwr_cnt |= PSB_PWRGT_GFX_MASK; - pwr_mask |= PSB_PWRGT_GFX_MASK; - if (dev_priv->graphics_state == PSB_PWR_STATE_ON) { - dev_priv->gfx_on_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ; - dev_priv->gfx_last_mode_change = jiffies; - dev_priv->graphics_state = PSB_PWR_STATE_OFF; - dev_priv->gfx_off_cnt++; - } - } - if (islands & OSPM_VIDEO_ENC_ISLAND) { - pwr_cnt |= PSB_PWRGT_VID_ENC_MASK; - pwr_mask |= PSB_PWRGT_VID_ENC_MASK; - } - if (islands & OSPM_VIDEO_DEC_ISLAND) { - pwr_cnt |= PSB_PWRGT_VID_DEC_MASK; - pwr_mask |= PSB_PWRGT_VID_DEC_MASK; - } - if (pwr_cnt) { - pwr_cnt |= inl(dev_priv->apm_base); - outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD); - while (true) { - pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS); - - if ((pwr_sts & pwr_mask) == pwr_mask) - break; - else - udelay(10); - } - } - - if (islands & OSPM_DISPLAY_ISLAND) { - pwr_mask = PSB_PWRGT_DISPLAY_MASK; - - outl(pwr_mask, (dev_priv->ospm_base + PSB_PM_SSC)); + struct drm_device *dev = pci_get_drvdata(pdev); - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == pwr_mask) - break; - else - udelay(10); - } - } -#endif + mutex_lock(&power_mutex); + gma_resume_pci(pdev); + gma_resume_display(pdev); + psb_irq_preinstall(dev); + psb_irq_postinstall(dev); + mutex_unlock(&power_mutex); + return 0; } -/* - * ospm_power_is_hw_on + +/** + * gma_power_is_on - returne true if power is on + * @dev: our DRM device * - * Description: do an instantaneous check for if the specified islands - * are on. Only use this in cases where you know the g_state_change_mutex - * is already held such as in irq install/uninstall. Otherwise, use - * ospm_power_using_hw_begin(). + * Returns true if the display island power is on at this moment */ -bool ospm_power_is_hw_on(int hw_islands) +bool gma_power_is_on(struct drm_device *dev) { - return ((g_hw_power_status_mask & hw_islands) == hw_islands) ? true:false; + struct drm_psb_private *dev_priv = dev->dev_private; + return dev_priv->display_power; } -/* - * ospm_power_using_hw_begin + +/** + * gma_power_begin - begin requiring power + * @dev: our DRM device + * @force_on: true to force power on * - * Description: Notify PowerMgmt module that you will be accessing the - * specified island's hw so don't power it off. If force_on is true, - * this will power on the specified island if it is off. - * Otherwise, this will return false and the caller is expected to not - * access the hw. + * Begin an action that requires the display power island is enabled. + * We refcount the islands. * - * NOTE *** If this is called from and interrupt handler or other atomic - * context, then it will return false if we are in the middle of a - * power state transition and the caller will be expected to handle that - * even if force_on is set to true. + * FIXME: locking */ -bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage) +bool gma_power_begin(struct drm_device *dev, bool force_on) { - return 1; /*FIXMEAC */ -#if 0 - bool ret = true; - bool island_is_off = false; - bool b_atomic = (in_interrupt() || in_atomic()); - bool locked = true; - struct pci_dev *pdev = gpDrmDevice->pdev; - u32 deviceID = 0; - bool force_on = usage ? true: false; - /*quick path, not 100% race safe, but should be enough comapre to current other code in this file */ - if (!force_on) { - if (hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask)) - return false; - else { - locked = false; -#ifdef CONFIG_PM_RUNTIME - /* increment pm_runtime_refcount */ - pm_runtime_get(&pdev->dev); -#endif - goto increase_count; - } - } - - - if (!b_atomic) - mutex_lock(&power_mutex); - - island_is_off = hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask); - - if (b_atomic && (gbSuspendInProgress || gbResumeInProgress || gbSuspended) && force_on && island_is_off) - ret = false; - - if (ret && island_is_off && !force_on) - ret = false; - - if (ret && island_is_off && force_on) { - gbResumeInProgress = true; - - ret = ospm_resume_pci(pdev); - - if (ret) { - switch(hw_island) - { - case OSPM_DISPLAY_ISLAND: - deviceID = gui32MRSTDisplayDeviceID; - ospm_resume_display(pdev); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - break; - case OSPM_GRAPHICS_ISLAND: - deviceID = gui32SGXDeviceID; - ospm_power_island_up(OSPM_GRAPHICS_ISLAND); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND); - break; -#if 1 - case OSPM_VIDEO_DEC_ISLAND: - if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { - //printk(KERN_ALERT "%s power on display for video decode use\n", __func__); - deviceID = gui32MRSTDisplayDeviceID; - ospm_resume_display(pdev); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - } - else{ - //printk(KERN_ALERT "%s display is already on for video decode use\n", __func__); - } - - if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) { - //printk(KERN_ALERT "%s power on video decode\n", __func__); - deviceID = gui32MRSTMSVDXDeviceID; - ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); - } - else{ - //printk(KERN_ALERT "%s video decode is already on\n", __func__); - } - - break; - case OSPM_VIDEO_ENC_ISLAND: - if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { - //printk(KERN_ALERT "%s power on display for video encode\n", __func__); - deviceID = gui32MRSTDisplayDeviceID; - ospm_resume_display(pdev); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); - } - else{ - //printk(KERN_ALERT "%s display is already on for video encode use\n", __func__); - } - - if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) { - //printk(KERN_ALERT "%s power on video encode\n", __func__); - deviceID = gui32MRSTTOPAZDeviceID; - ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND); - psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); - psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); - } - else{ - //printk(KERN_ALERT "%s video decode is already on\n", __func__); - } -#endif - break; - - default: - printk(KERN_ALERT "%s unknown island !!!! \n", __func__); - break; - } - - } - - if (!ret) - printk(KERN_ALERT "ospm_power_using_hw_begin: forcing on %d failed\n", hw_island); + struct drm_psb_private *dev_priv = dev->dev_private; + int ret; - gbResumeInProgress = false; + /* Power already on ? */ + if (dev_priv->display_power) { + dev_priv->display_count++; + pm_runtime_get(&dev->pdev->dev); + return true; } -increase_count: - if (ret) { - switch(hw_island) - { - case OSPM_GRAPHICS_ISLAND: - atomic_inc(&g_graphics_access_count); - break; - case OSPM_VIDEO_ENC_ISLAND: - atomic_inc(&g_videoenc_access_count); - break; - case OSPM_VIDEO_DEC_ISLAND: - atomic_inc(&g_videodec_access_count); - break; - case OSPM_DISPLAY_ISLAND: - atomic_inc(&g_display_access_count); - break; - } + if (force_on == false) + return false; + + /* Ok power up needed */ + ret = gma_resume_pci(dev->pdev); + if (ret == 0) { + psb_irq_preinstall(dev); + psb_irq_postinstall(dev); + pm_runtime_get(&dev->pdev->dev); + dev_priv->display_count++; + return true; } - - if (!b_atomic && locked) - mutex_unlock(&power_mutex); - - return ret; -#endif + return false; } -/* - * ospm_power_using_hw_end +/** + * gma_power_end - end use of power + * @dev: Our DRM device * - * Description: Notify PowerMgmt module that you are done accessing the - * specified island's hw so feel free to power it off. Note that this - * function doesn't actually power off the islands. + * Indicate that one of our gma_power_begin() requested periods when + * the diplay island power is needed has completed. */ -void ospm_power_using_hw_end(int hw_island) -{ -#if 0 /* FIXMEAC */ - switch(hw_island) - { - case OSPM_GRAPHICS_ISLAND: - atomic_dec(&g_graphics_access_count); - break; - case OSPM_VIDEO_ENC_ISLAND: - atomic_dec(&g_videoenc_access_count); - break; - case OSPM_VIDEO_DEC_ISLAND: - atomic_dec(&g_videodec_access_count); - break; - case OSPM_DISPLAY_ISLAND: - atomic_dec(&g_display_access_count); - break; - } - - //decrement runtime pm ref count - pm_runtime_put(&gpDrmDevice->pdev->dev); - - WARN_ON(atomic_read(&g_graphics_access_count) < 0); - WARN_ON(atomic_read(&g_videoenc_access_count) < 0); - WARN_ON(atomic_read(&g_videodec_access_count) < 0); - WARN_ON(atomic_read(&g_display_access_count) < 0); -#endif -} - -int ospm_runtime_pm_allow(struct drm_device * dev) +void gma_power_end(struct drm_device *dev) { - return 0; -} - -void ospm_runtime_pm_forbid(struct drm_device * dev) -{ - struct drm_psb_private * dev_priv = dev->dev_private; - - DRM_INFO("%s\n", __FUNCTION__); - - pm_runtime_forbid(&dev->pdev->dev); - dev_priv->rpm_enabled = 0; + struct drm_psb_private *dev_priv = dev->dev_private; + dev_priv->display_count--; + WARN_ON(dev_priv->display_count < 0); + pm_runtime_put(&dev->pdev->dev); } int psb_runtime_suspend(struct device *dev) { - pm_message_t state; - int ret = 0; - state.event = 0; - -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "OSPM_GFX_DPK: %s \n", __func__); -#endif - if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count) - || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)){ -#ifdef OSPM_GFX_DPK - printk(KERN_ALERT "OSPM_GFX_DPK: GFX: %d VEC: %d VED: %d DC: %d DSR: %d \n", atomic_read(&g_graphics_access_count), - atomic_read(&g_videoenc_access_count), atomic_read(&g_videodec_access_count), atomic_read(&g_display_access_count)); -#endif - return -EBUSY; - } - else - ret = ospm_power_suspend(gpDrmDevice->pdev, state); - - return ret; + static pm_message_t dummy; + return gma_power_suspend(to_pci_dev(dev), dummy); } int psb_runtime_resume(struct device *dev) @@ -782,11 +480,11 @@ int psb_runtime_resume(struct device *dev) int psb_runtime_idle(struct device *dev) { - /*printk (KERN_ALERT "lvds:%d,mipi:%d\n", dev_priv->is_lvds_on, dev_priv->is_mipi_on);*/ - if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count) - || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)) - return 1; - else + struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev)); + struct drm_psb_private *dev_priv = drmdev->dev_private; + if (dev_priv->display_count) return 0; + else + return 1; } diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/psb_powermgmt.h index bf6f27af03a8..e005229af798 100644 --- a/drivers/staging/gma500/psb_powermgmt.h +++ b/drivers/staging/gma500/psb_powermgmt.h @@ -24,7 +24,8 @@ * Authors: * Benjamin Defnet * Rajesh Poornachandran - * + * Massively reworked + * Alan Cox */ #ifndef _PSB_POWERMGMT_H_ #define _PSB_POWERMGMT_H_ @@ -32,65 +33,35 @@ #include #include -#define OSPM_GRAPHICS_ISLAND 0x1 -#define OSPM_VIDEO_ENC_ISLAND 0x2 -#define OSPM_VIDEO_DEC_ISLAND 0x4 -#define OSPM_DISPLAY_ISLAND 0x8 -#define OSPM_GL3_CACHE_ISLAND 0x10 -#define OSPM_ALL_ISLANDS 0x1f - -/* IPC message and command defines used to enable/disable mipi panel voltages */ -#define IPC_MSG_PANEL_ON_OFF 0xE9 -#define IPC_CMD_PANEL_ON 1 -#define IPC_CMD_PANEL_OFF 0 - -typedef enum _UHBUsage -{ - OSPM_UHB_ONLY_IF_ON = 0, - OSPM_UHB_FORCE_POWER_ON, -} UHBUsage; - -/* Use these functions to power down video HW for D0i3 purpose */ - -void ospm_power_init(struct drm_device *dev); -void ospm_power_uninit(void); - +void gma_power_init(struct drm_device *dev); +void gma_power_uninit(struct drm_device *dev); /* - * OSPM will call these functions + * The kernel bus power management will call these functions */ -int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state); -int ospm_power_resume(struct pci_dev *pdev); +int gma_power_suspend(struct pci_dev *pdev, pm_message_t state); +int gma_power_resume(struct pci_dev *pdev); /* * These are the functions the driver should use to wrap all hw access * (i.e. register reads and writes) */ -bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage); -void ospm_power_using_hw_end(int hw_island); +bool gma_power_begin(struct drm_device *dev, bool force); +void gma_power_end(struct drm_device *dev); /* * Use this function to do an instantaneous check for if the hw is on. - * Only use this in cases where you know the g_state_change_mutex - * is already held such as in irq install/uninstall and you need to - * prevent a deadlock situation. Otherwise use ospm_power_using_hw_begin(). + * Only use this in cases where you know the mutex is already held such + * as in irq install/uninstall and you need to + * prevent a deadlock situation. Otherwise use gma_power_begin(). */ -bool ospm_power_is_hw_on(int hw_islands); +bool gma_power_is_on(struct drm_device *dev); -/* - * Power up/down different hw component rails/islands - */ -void ospm_power_island_down(int hw_islands); -void ospm_power_island_up(int hw_islands); -void ospm_suspend_graphics(void); /* * GFX-Runtime PM callbacks */ int psb_runtime_suspend(struct device *dev); int psb_runtime_resume(struct device *dev); int psb_runtime_idle(struct device *dev); -int ospm_runtime_pm_allow(struct drm_device * dev); -void ospm_runtime_pm_forbid(struct drm_device * dev); - #endif /*_PSB_POWERMGMT_H_*/ -- GitLab From 3350dead09da181b664775027abc51540425b93d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:42:22 +0100 Subject: [PATCH 0499/5560] staging: gma500: cleanup the SDVO messages Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 3 ++- drivers/staging/gma500/psb_intel_sdvo.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index be8f11d19ee2..8978ed657857 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -493,7 +493,8 @@ static int psb_do_init(struct drm_device *dev) PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, PSB_CR_BIF_CTRL); psb_spank(dev_priv); - + + printk(KERN_INFO "TWOD base %08lX\n", (u32) pg->mmu_gatt_start); PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); return 0; diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c index 731a5a2261d3..d005227b95d2 100644 --- a/drivers/staging/gma500/psb_intel_sdvo.c +++ b/drivers/staging/gma500/psb_intel_sdvo.c @@ -204,7 +204,7 @@ static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output, struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; int i; - if (1) { + if (0) { DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); for (i = 0; i < args_len; i++) printk(KERN_INFO"%02X ", ((u8 *) args)[i]); @@ -266,7 +266,7 @@ static u8 psb_intel_sdvo_read_response( SDVO_I2C_CMD_STATUS, &status); - if (1) { + if (0) { DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv)); for (i = 0; i < response_len; i++) printk(KERN_INFO"%02X ", ((u8 *) response)[i]); -- GitLab From 9c6ac29cb08da3ac56db668b8f3e33cbf048b879 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:42:47 +0100 Subject: [PATCH 0500/5560] staging: gma500: Set the TWOD base 2D accel still doesn't work but now it doesn't crash either Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 5 +++-- drivers/staging/gma500/psb_gtt.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 8978ed657857..05c31b9b43fc 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -494,8 +494,9 @@ static int psb_do_init(struct drm_device *dev) PSB_CR_BIF_CTRL); psb_spank(dev_priv); - printk(KERN_INFO "TWOD base %08lX\n", (u32) pg->mmu_gatt_start); - PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); + /* mmu_gatt ?? */ + printk(KERN_INFO "TWOD base %08lX\n", (u32) pg->gatt_start); + PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); return 0; out_err: diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c index c1283e836b23..093d7dfee893 100644 --- a/drivers/staging/gma500/psb_gtt.c +++ b/drivers/staging/gma500/psb_gtt.c @@ -117,9 +117,9 @@ int psb_gtt_init(struct psb_gtt *pg, int resume) pg->gatt_start, pg->gatt_pages/256); printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n", pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start); - printk(KERN_INFO "Stole memory information\n"); - printk(KERN_INFO " base in RAM: 0x%x\n", pg->stolen_base); - printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", + printk(KERN_INFO "Stolen memory information\n"); + printk(KERN_INFO " base in RAM: 0x%x\n", pg->stolen_base); + printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", vram_stolen_size/1024); dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7; printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n", -- GitLab From 636fa5c78c73901022ed6c20c50543af8811e050 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 18:44:16 +0100 Subject: [PATCH 0501/5560] staging: gma500: psb_reset actually holds lid functions So rename the file something sensible Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/Makefile | 2 +- drivers/staging/gma500/{psb_reset.c => psb_lid.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/staging/gma500/{psb_reset.c => psb_lid.c} (100%) diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile index 4d7aabe7e37c..e00557e40a59 100644 --- a/drivers/staging/gma500/Makefile +++ b/drivers/staging/gma500/Makefile @@ -15,7 +15,7 @@ psb_gfx-y += psb_bl.o \ psb_intel_lvds.o \ psb_intel_modes.o \ psb_intel_sdvo.o \ - psb_reset.o \ + psb_lid.o \ psb_pvr_glue.o \ psb_mmu.o \ psb_powermgmt.o \ diff --git a/drivers/staging/gma500/psb_reset.c b/drivers/staging/gma500/psb_lid.c similarity index 100% rename from drivers/staging/gma500/psb_reset.c rename to drivers/staging/gma500/psb_lid.c -- GitLab From cb048d558690ba1468e6bb26b82594b4330fb21c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 1 Apr 2011 22:24:15 +0100 Subject: [PATCH 0502/5560] staging: gma500: enable the 2D op stuff Well one of them anyway - not yet sure why the other fails Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_2d.c | 2 +- drivers/staging/gma500/psb_fb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c index 94bce5c0648e..29959ded78fc 100644 --- a/drivers/staging/gma500/psb_2d.c +++ b/drivers/staging/gma500/psb_2d.c @@ -343,7 +343,7 @@ void psbfb_copyarea(struct fb_info *info, if (unlikely(info->state != FBINFO_STATE_RUNNING)) return; - if (1 || (info->flags & FBINFO_HWACCEL_DISABLED)) + if (info->flags & FBINFO_HWACCEL_DISABLED) return cfb_copyarea(info, region); /* psb_check_power_state(dev, PSB_DEVICE_SGX); */ diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index 6499f28cb2af..665096f6a843 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -287,7 +287,7 @@ static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg return -EFAULT; if (l > 32) return -EMSGSIZE; - if (copy_from_user(buf, p + 1, l)) + if (copy_from_user(buf, p + 1, l * sizeof(u32))) return -EFAULT; psbfb_2d_submit(dev_priv, buf, l); return 0; -- GitLab From 8a789f8c306b5e3fe6ef71bb5412055075d8c87f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 5 Apr 2011 16:55:26 +0100 Subject: [PATCH 0503/5560] staging: gma500: Add oaktrail Oaktrail needs a couple of slight plumbing tweaks Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/Kconfig | 2 +- drivers/staging/gma500/mrst_lvds.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig index 5501eb9b3355..ce8bedaeaac2 100644 --- a/drivers/staging/gma500/Kconfig +++ b/drivers/staging/gma500/Kconfig @@ -1,6 +1,6 @@ config DRM_PSB tristate "Intel GMA500 KMS Framebuffer" - depends on DRM && PCI + depends on DRM && PCI && X86 select FB_CFB_COPYAREA select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c index 21b9056ec84a..4a08b74f5ff9 100644 --- a/drivers/staging/gma500/mrst_lvds.c +++ b/drivers/staging/gma500/mrst_lvds.c @@ -22,6 +22,7 @@ #include #include +#include #include "psb_intel_bios.h" #include "psb_drv.h" @@ -300,7 +301,15 @@ void mrst_lvds_init(struct drm_device *dev, * 4) make sure lid is open * if closed, act like it's not there for now */ - i2c_adap = i2c_get_adapter(2); + + /* This ifdef can go once the cpu ident stuff is cleaned up in arch */ +#if defined(CONFIG_X86_MRST) + if (mrst_identify_cpu()) + i2c_adap = i2c_get_adapter(2); + else /* Oaktrail uses I2C 1 */ +#endif + i2c_adap = i2c_get_adapter(1); + if (i2c_adap == NULL) printk(KERN_ALERT "No ddc adapter available!\n"); /* -- GitLab From d6f087ec9c7ba029419762273a685460c93c8454 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Mar 2011 19:37:00 +0100 Subject: [PATCH 0504/5560] staging: IIO: ADC: New driver for the AD7780 / AD7781 24-bit Sigma-Delta ADC Changes since v1: IIO: ADC: AD7780: Apply review feedback Abort probe() with error in case platform_data is not present. Add comment explaining power down reset (PDRST) GPIO handling and dual function DOUT/RDY interrupt usage. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 11 ++ drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7780.c | 329 +++++++++++++++++++++++++++++++ drivers/staging/iio/adc/ad7780.h | 30 +++ 4 files changed, 371 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7780.c create mode 100644 drivers/staging/iio/adc/ad7780.h diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 6692a3d87f23..41593890ce88 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -142,6 +142,17 @@ config AD7887 To compile this driver as a module, choose M here: the module will be called ad7887. +config AD7780 + tristate "Analog Devices AD7780 AD7781 ADC driver" + depends on SPI + help + Say yes here to build support for Analog Devices + AD7780 and AD7781 SPI analog to digital convertors (ADC). + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called ad7780. + config AD7745 tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 31067defd79b..1d9b3f582eab 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7314) += ad7314.o obj-$(CONFIG_AD7745) += ad7745.o +obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_ADT75) += adt75.o obj-$(CONFIG_ADT7310) += adt7310.o diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c new file mode 100644 index 000000000000..0fd994fdee46 --- /dev/null +++ b/drivers/staging/iio/adc/ad7780.c @@ -0,0 +1,329 @@ +/* + * AD7780/AD7781 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "adc.h" + +#include "ad7780.h" + +#define AD7780_RDY (1 << 7) +#define AD7780_FILTER (1 << 6) +#define AD7780_ERR (1 << 5) +#define AD7780_ID1 (1 << 4) +#define AD7780_ID0 (1 << 3) +#define AD7780_GAIN (1 << 2) +#define AD7780_PAT1 (1 << 1) +#define AD7780_PAT0 (1 << 0) + +struct ad7780_chip_info { + u8 bits; + u8 storagebits; + u8 res_shift; +}; + +struct ad7780_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + const struct ad7780_chip_info *chip_info; + struct regulator *reg; + struct ad7780_platform_data *pdata; + wait_queue_head_t wq_data_avail; + bool done; + u16 int_vref_mv; + struct spi_transfer xfer; + struct spi_message msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned int data ____cacheline_aligned; +}; + +enum ad7780_supported_device_ids { + ID_AD7780, + ID_AD7781, +}; + +static int ad7780_read(struct ad7780_state *st, int *val) +{ + int ret; + + spi_bus_lock(st->spi->master); + + enable_irq(st->spi->irq); + st->done = false; + gpio_set_value(st->pdata->gpio_pdrst, 1); + + ret = wait_event_interruptible(st->wq_data_avail, st->done); + disable_irq_nosync(st->spi->irq); + if (ret) + goto out; + + ret = spi_sync_locked(st->spi, &st->msg); + *val = be32_to_cpu(st->data); +out: + gpio_set_value(st->pdata->gpio_pdrst, 0); + spi_bus_unlock(st->spi->master); + + return ret; +} + +static ssize_t ad7780_scan(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7780_state *st = dev_info->dev_data; + int ret, val, smpl; + + mutex_lock(&dev_info->mlock); + ret = ad7780_read(st, &smpl); + mutex_unlock(&dev_info->mlock); + + if (ret < 0) + return ret; + + if ((smpl & AD7780_ERR) || + !((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1))) + return -EIO; + + val = (smpl >> st->chip_info->res_shift) & + ((1 << (st->chip_info->bits)) - 1); + val -= (1 << (st->chip_info->bits - 1)); + + if (!(smpl & AD7780_GAIN)) + val *= 128; + + return sprintf(buf, "%d\n", val); +} +static IIO_DEV_ATTR_IN_RAW(0, ad7780_scan, 0); + +static ssize_t ad7780_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7780_state *st = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits-1) */ + unsigned int scale = (st->int_vref_mv * 100000) >> + (st->chip_info->bits - 1); + + return sprintf(buf, "%d.%05d\n", scale / 100000, scale % 100000); +} +static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7780_show_scale, NULL, 0); + +static ssize_t ad7780_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7780_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7780_show_name, NULL, 0); + +static struct attribute *ad7780_attributes[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7780_attribute_group = { + .attrs = ad7780_attributes, +}; + +static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { + [ID_AD7780] = { + .bits = 24, + .storagebits = 32, + .res_shift = 8, + }, + [ID_AD7781] = { + .bits = 20, + .storagebits = 32, + .res_shift = 12, + }, +}; + +/** + * Interrupt handler + */ +static irqreturn_t ad7780_interrupt(int irq, void *dev_id) +{ + struct ad7780_state *st = dev_id; + + st->done = true; + wake_up_interruptible(&st->wq_data_avail); + + return IRQ_HANDLED; +}; + +static int __devinit ad7780_probe(struct spi_device *spi) +{ + struct ad7780_platform_data *pdata = spi->dev.platform_data; + struct ad7780_state *st; + int ret, voltage_uv = 0; + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->chip_info = + &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + st->pdata = pdata; + + if (pdata && pdata->vref_mv) + st->int_vref_mv = pdata->vref_mv; + else if (voltage_uv) + st->int_vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); + + spi_set_drvdata(spi, st); + st->spi = spi; + + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + + /* Establish that the iio_dev is a child of the spi device */ + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &ad7780_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + init_waitqueue_head(&st->wq_data_avail); + + /* Setup default message */ + + st->xfer.rx_buf = &st->data; + st->xfer.len = st->chip_info->storagebits / 8; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, + "AD7877 /PDRST"); + if (ret) { + dev_err(&spi->dev, "failed to request GPIO PDRST\n"); + goto error_free_device; + } + + ret = request_irq(spi->irq, ad7780_interrupt, + IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st); + if (ret) + goto error_free_device; + + disable_irq(spi->irq); + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_irq; + + return 0; + +error_free_irq: + free_irq(spi->irq, st); + +error_free_device: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); +error_ret: + return ret; +} + +static int ad7780_remove(struct spi_device *spi) +{ + struct ad7780_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + free_irq(spi->irq, st); + gpio_free(st->pdata->gpio_pdrst); + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + kfree(st); + return 0; +} + +static const struct spi_device_id ad7780_id[] = { + {"ad7780", ID_AD7780}, + {"ad7781", ID_AD7781}, + {} +}; + +static struct spi_driver ad7780_driver = { + .driver = { + .name = "ad7780", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7780_probe, + .remove = __devexit_p(ad7780_remove), + .id_table = ad7780_id, +}; + +static int __init ad7780_init(void) +{ + return spi_register_driver(&ad7780_driver); +} +module_init(ad7780_init); + +static void __exit ad7780_exit(void) +{ + spi_unregister_driver(&ad7780_driver); +} +module_exit(ad7780_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7780/1 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7780.h b/drivers/staging/iio/adc/ad7780.h new file mode 100644 index 000000000000..67e511c3d6f0 --- /dev/null +++ b/drivers/staging/iio/adc/ad7780.h @@ -0,0 +1,30 @@ +/* + * AD7780/AD7781 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ +#ifndef IIO_ADC_AD7780_H_ +#define IIO_ADC_AD7780_H_ + +/* + * TODO: struct ad7780_platform_data needs to go into include/linux/iio + */ + +/* NOTE: + * The AD7780 doesn't feature a dedicated SPI chip select, in addition it + * features a dual use data out ready DOUT/RDY output. + * In order to avoid contentions on the SPI bus, it's therefore necessary + * to use spi bus locking combined with a dedicated GPIO to control the + * power down reset signal of the AD7780. + * + * The DOUT/RDY output must also be wired to an interrupt capable GPIO. + */ + +struct ad7780_platform_data { + u16 vref_mv; + int gpio_pdrst; +}; + +#endif /* IIO_ADC_AD7780_H_ */ -- GitLab From 59c23eabdae97a18cfc400339138f6d1dbde926a Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 4 Apr 2011 15:39:15 +0200 Subject: [PATCH 0505/5560] staging: IIO: DAC: New driver for the AD5504 and AD55041 High Voltage DACs Changes since V1: IIO: DAC: Apply review feedback from Jonathan Fix array size and declare const. Fix reversed dacY_powerdown read back. Use individual attribute groups instead of is_visible. Fix event naming and add the _en file. Changes since V2: IIO: DAC: AD5504 use proper event type Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/Kconfig | 10 + drivers/staging/iio/dac/Makefile | 1 + drivers/staging/iio/dac/ad5504.c | 426 +++++++++++++++++++++++++++++++ drivers/staging/iio/dac/ad5504.h | 74 ++++++ drivers/staging/iio/sysfs.h | 1 + 5 files changed, 512 insertions(+) create mode 100644 drivers/staging/iio/dac/ad5504.c create mode 100644 drivers/staging/iio/dac/ad5504.h diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index 67defcb359b1..1b0188a2c559 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -21,6 +21,16 @@ config AD5446 To compile this driver as a module, choose M here: the module will be called ad5446. +config AD5504 + tristate "Analog Devices AD5504/AD5501 DAC SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD5504, AD5501, + High Voltage Digital to Analog Converter. + + To compile this driver as a module, choose M here: the + module will be called ad5504. + config MAX517 tristate "Maxim MAX517/518/519 DAC driver" depends on I2C && EXPERIMENTAL diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile index 1197aef54abb..020df4a1130a 100644 --- a/drivers/staging/iio/dac/Makefile +++ b/drivers/staging/iio/dac/Makefile @@ -3,5 +3,6 @@ # obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o +obj-$(CONFIG_AD5504) += ad5504.o obj-$(CONFIG_AD5446) += ad5446.o obj-$(CONFIG_MAX517) += max517.o diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c new file mode 100644 index 000000000000..153c36e7f70e --- /dev/null +++ b/drivers/staging/iio/dac/ad5504.c @@ -0,0 +1,426 @@ +/* + * AD5504, AD5501 High Voltage Digital to Analog Converter + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "dac.h" +#include "ad5504.h" + +static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val) +{ + u16 tmp = cpu_to_be16(AD5504_CMD_WRITE | + AD5504_ADDR(addr) | + (val & AD5504_RES_MASK)); + + return spi_write(spi, (u8 *)&tmp, 2); +} + +static int ad5504_spi_read(struct spi_device *spi, u8 addr, u16 *val) +{ + u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr)); + int ret; + struct spi_transfer t = { + .tx_buf = &tmp, + .rx_buf = val, + .len = 2, + }; + struct spi_message m; + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + ret = spi_sync(spi, &m); + + *val = be16_to_cpu(*val) & AD5504_RES_MASK; + + return ret; +} + +static ssize_t ad5504_write_dac(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + long readin; + int ret; + + ret = strict_strtol(buf, 10, &readin); + if (ret) + return ret; + + ret = ad5504_spi_write(st->spi, this_attr->address, readin); + return ret ? ret : len; +} + +static ssize_t ad5504_read_dac(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + u16 val; + + ret = ad5504_spi_read(st->spi, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t ad5504_read_powerdown_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + + const char mode[][14] = {"20kohm_to_gnd", "three_state"}; + + return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); +} + +static ssize_t ad5504_write_powerdown_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + int ret; + + if (sysfs_streq(buf, "20kohm_to_gnd")) + st->pwr_down_mode = AD5504_DAC_PWRDN_20K; + else if (sysfs_streq(buf, "three_state")) + st->pwr_down_mode = AD5504_DAC_PWRDN_3STATE; + else + ret = -EINVAL; + + return ret ? ret : len; +} + +static ssize_t ad5504_read_dac_powerdown(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + return sprintf(buf, "%d\n", + !(st->pwr_down_mask & (1 << this_attr->address))); +} + +static ssize_t ad5504_write_dac_powerdown(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + long readin; + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = strict_strtol(buf, 10, &readin); + if (ret) + return ret; + + if (readin == 0) + st->pwr_down_mask |= (1 << this_attr->address); + else if (readin == 1) + st->pwr_down_mask &= ~(1 << this_attr->address); + else + ret = -EINVAL; + + ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL, + AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | + AD5504_DAC_PWR(st->pwr_down_mask)); + + /* writes to the CTRL register must be followed by a NOOP */ + ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0); + + return ret ? ret : len; +} + +static ssize_t ad5504_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + /* Corresponds to Vref / 2^(bits) */ + unsigned int scale_uv = (st->vref_mv * 1000) >> AD5505_BITS; + + return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); +} +static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5504_show_scale, NULL, 0); + +static ssize_t ad5504_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad5504_show_name, NULL, 0); + +#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out##_num##_raw, \ + S_IRUGO | S_IWUSR, _show, _store, _addr) + +static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5504_read_dac, + ad5504_write_dac, AD5504_ADDR_DAC0); +static IIO_DEV_ATTR_OUT_RW_RAW(1, ad5504_read_dac, + ad5504_write_dac, AD5504_ADDR_DAC1); +static IIO_DEV_ATTR_OUT_RW_RAW(2, ad5504_read_dac, + ad5504_write_dac, AD5504_ADDR_DAC2); +static IIO_DEV_ATTR_OUT_RW_RAW(3, ad5504_read_dac, + ad5504_write_dac, AD5504_ADDR_DAC3); + +static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO | + S_IWUSR, ad5504_read_powerdown_mode, + ad5504_write_powerdown_mode, 0); + +static IIO_CONST_ATTR(out_powerdown_mode_available, + "20kohm_to_gnd three_state"); + +#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out##_num##_powerdown, \ + S_IRUGO | S_IWUSR, _show, _store, _addr) + +static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5504_read_dac_powerdown, + ad5504_write_dac_powerdown, 0); +static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5504_read_dac_powerdown, + ad5504_write_dac_powerdown, 1); +static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5504_read_dac_powerdown, + ad5504_write_dac_powerdown, 2); +static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5504_read_dac_powerdown, + ad5504_write_dac_powerdown, 3); + +static struct attribute *ad5504_attributes[] = { + &iio_dev_attr_out0_raw.dev_attr.attr, + &iio_dev_attr_out1_raw.dev_attr.attr, + &iio_dev_attr_out2_raw.dev_attr.attr, + &iio_dev_attr_out3_raw.dev_attr.attr, + &iio_dev_attr_out0_powerdown.dev_attr.attr, + &iio_dev_attr_out1_powerdown.dev_attr.attr, + &iio_dev_attr_out2_powerdown.dev_attr.attr, + &iio_dev_attr_out3_powerdown.dev_attr.attr, + &iio_dev_attr_out_powerdown_mode.dev_attr.attr, + &iio_const_attr_out_powerdown_mode_available.dev_attr.attr, + &iio_dev_attr_out_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5504_attribute_group = { + .attrs = ad5504_attributes, +}; + +static struct attribute *ad5501_attributes[] = { + &iio_dev_attr_out0_raw.dev_attr.attr, + &iio_dev_attr_out0_powerdown.dev_attr.attr, + &iio_dev_attr_out_powerdown_mode.dev_attr.attr, + &iio_const_attr_out_powerdown_mode_available.dev_attr.attr, + &iio_dev_attr_out_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5501_attribute_group = { + .attrs = ad5501_attributes, +}; + +static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000"); +static IIO_CONST_ATTR(temp0_thresh_rising_en, "1"); + +static struct attribute *ad5504_ev_attributes[] = { + &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr, + &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad5504_ev_attribute_group = { + .attrs = ad5504_ev_attributes, +}; + +static void ad5504_interrupt_bh(struct work_struct *work_s) +{ + struct ad5504_state *st = container_of(work_s, + struct ad5504_state, work_alarm); + + iio_push_event(st->indio_dev, 0, + IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + st->last_timestamp); + + enable_irq(st->spi->irq); +} + +static int ad5504_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct ad5504_state *st = dev_info->dev_data; + + st->last_timestamp = timestamp; + schedule_work(&st->work_alarm); + return 0; +} + +IIO_EVENT_SH(ad5504, &ad5504_interrupt); + +static int __devinit ad5504_probe(struct spi_device *spi) +{ + struct ad5504_platform_data *pdata = spi->dev.platform_data; + struct ad5504_state *st; + int ret, voltage_uv = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + spi_set_drvdata(spi, st); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else if (pdata) + st->vref_mv = pdata->vref_mv; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); + + st->spi = spi; + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + st->indio_dev->dev.parent = &spi->dev; + + st->indio_dev->attrs = spi_get_device_id(st->spi)->driver_data + == ID_AD5501 ? &ad5501_attribute_group : + &ad5504_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &ad5504_ev_attribute_group, + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_dev; + + if (spi->irq) { + INIT_WORK(&st->work_alarm, ad5504_interrupt_bh); + + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + spi_get_device_id(st->spi)->name); + if (ret) + goto error_unreg_iio_device; + + iio_add_event_to_list(&iio_event_ad5504, + &st->indio_dev->interrupts[0]->ev_list); + } + + return 0; + +error_unreg_iio_device: + iio_device_unregister(st->indio_dev); +error_free_dev: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad5504_remove(struct spi_device *spi) +{ + struct ad5504_state *st = spi_get_drvdata(spi); + + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); + + iio_device_unregister(st->indio_dev); + + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + + kfree(st); + + return 0; +} + +static const struct spi_device_id ad5504_id[] = { + {"ad5504", ID_AD5504}, + {"ad5501", ID_AD5501}, + {} +}; + +static struct spi_driver ad5504_driver = { + .driver = { + .name = "ad5504", + .owner = THIS_MODULE, + }, + .probe = ad5504_probe, + .remove = __devexit_p(ad5504_remove), + .id_table = ad5504_id, +}; + +static __init int ad5504_spi_init(void) +{ + return spi_register_driver(&ad5504_driver); +} +module_init(ad5504_spi_init); + +static __exit void ad5504_spi_exit(void) +{ + spi_unregister_driver(&ad5504_driver); +} +module_exit(ad5504_spi_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h new file mode 100644 index 000000000000..d2fac631a43a --- /dev/null +++ b/drivers/staging/iio/dac/ad5504.h @@ -0,0 +1,74 @@ +/* + * AD5504 SPI DAC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef SPI_AD5504_H_ +#define SPI_AD5504_H_ + +#define AD5505_BITS 12 +#define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1) + +#define AD5504_CMD_READ (1 << 15) +#define AD5504_CMD_WRITE (0 << 15) +#define AD5504_ADDR(addr) ((addr) << 12) + +/* Registers */ +#define AD5504_ADDR_NOOP 0 +#define AD5504_ADDR_DAC0 1 +#define AD5504_ADDR_DAC1 2 +#define AD5504_ADDR_DAC2 3 +#define AD5504_ADDR_DAC3 4 +#define AD5504_ADDR_ALL_DAC 5 +#define AD5504_ADDR_CTRL 7 + +/* Control Register */ +#define AD5504_DAC_PWR(ch) ((ch) << 2) +#define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6) +#define AD5504_DAC_PWRDN_20K 0 +#define AD5504_DAC_PWRDN_3STATE 1 + +/* + * TODO: struct ad5504_platform_data needs to go into include/linux/iio + */ + +struct ad5504_platform_data { + u16 vref_mv; +}; + +/** + * struct ad5446_state - driver instance specific data + * @indio_dev: the industrial I/O device + * @us: spi_device + * @reg: supply regulator + * @vref_mv: actual reference voltage used + * @work_alarm: bh work structure for event handling + * @last_timestamp: timestamp of last event interrupt + * @pwr_down_mask power down mask + * @pwr_down_mode current power down mode + */ + +struct ad5504_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + struct regulator *reg; + unsigned short vref_mv; + struct work_struct work_alarm; + s64 last_timestamp; + unsigned pwr_down_mask; + unsigned pwr_down_mode; +}; + +/** + * ad5504_supported_device_ids: + */ + +enum ad5504_supported_device_ids { + ID_AD5504, + ID_AD5501, +}; + +#endif /* SPI_AD5504_H_ */ diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h index 24b74ddcd083..8f4d5474c093 100644 --- a/drivers/staging/iio/sysfs.h +++ b/drivers/staging/iio/sysfs.h @@ -266,6 +266,7 @@ struct iio_const_attr { #define IIO_EV_CLASS_MAGN 4 #define IIO_EV_CLASS_LIGHT 5 #define IIO_EV_CLASS_PROXIMITY 6 +#define IIO_EV_CLASS_TEMP 7 #define IIO_EV_MOD_X 0 #define IIO_EV_MOD_Y 1 -- GitLab From 4bf4a6c5b1b2c73cd61d46d77e7da814effc6058 Mon Sep 17 00:00:00 2001 From: Raymond Yau Date: Tue, 5 Apr 2011 22:47:15 +0800 Subject: [PATCH 0506/5560] ALSA: hda - Fix alc662_dac_nid and change "6stack-dig" to "5stack-dig" alc662 series only have 3 DAC, so it can only support 5stack-dig instead of 6stack-dig. [updated HD-Audio-Models.txt as well by tiwai] Signed-off-by: Raymond Yau Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 2 +- sound/pci/hda/patch_realtek.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 0caf77e59be4..d70c93bdcadf 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -94,7 +94,7 @@ ALC662/663/272 3stack-dig 3-stack (2-channel) with SPDIF 3stack-6ch 3-stack (6-channel) 3stack-6ch-dig 3-stack (6-channel) with SPDIF - 6stack-dig 6-stack with SPDIF + 5stack-dig 5-stack with SPDIF lenovo-101e Lenovo laptop eeepc-p701 ASUS Eeepc P701 eeepc-ep20 ASUS Eeepc EP20 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 12c6f4508c54..a0262306508f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -17432,8 +17432,8 @@ static int patch_alc861vd(struct hda_codec *codec) #define ALC662_DIGOUT_NID 0x06 #define ALC662_DIGIN_NID 0x0a -static hda_nid_t alc662_dac_nids[4] = { - /* front, rear, clfe, rear_surr */ +static hda_nid_t alc662_dac_nids[3] = { + /* front, rear, clfe */ 0x02, 0x03, 0x04 }; @@ -18691,7 +18691,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = { [ALC662_3ST_2ch_DIG] = "3stack-dig", [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", [ALC662_3ST_6ch] = "3stack-6ch", - [ALC662_5ST_DIG] = "6stack-dig", + [ALC662_5ST_DIG] = "5stack-dig", [ALC662_LENOVO_101E] = "lenovo-101e", [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", -- GitLab From e217b960e4f82610946fcad764b8af017a4811c0 Mon Sep 17 00:00:00 2001 From: Raymond Yau Date: Wed, 30 Mar 2011 20:00:39 +0800 Subject: [PATCH 0507/5560] ALSA: emu10k1 - Remove CLFE-related controls for SB Live! Platinum CT4760P SB Live! Platinum CT4760P is just a 4 channels sound card with STAC9721 and Philips UDA1334 DAC. Signed-off-by: Raymond Yau Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/emumixer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 05afe06e353a..1b50a23232b5 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -1913,6 +1913,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, for (; *c; c += 2) rename_ctl(card, c[0], c[1]); + if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */ + remove_ctl(card, "Center Playback Volume"); + remove_ctl(card, "LFE Playback Volume"); + remove_ctl(card, "Wave Center Playback Volume"); + remove_ctl(card, "Wave LFE Playback Volume"); + } if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); -- GitLab From 1bc7cf99a90b4cfbeed362f3f238bcc9fc2f2c28 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 6 Apr 2011 09:42:29 +0200 Subject: [PATCH 0508/5560] ALSA: hda - Correct initial dac_nids for some ALC272-quirks Some ALC272-quirks use alc662_dac_nids instead of alc272_dac_nids. This patch fixes these entries. No functional change since the first two elements are identical in both arrays. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a0262306508f..e62fe7f2aeff 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19059,7 +19059,7 @@ static struct alc_config_preset alc662_presets[] = { .cap_mixer = alc272_auto_capture_mixer, .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), - .dac_nids = alc662_dac_nids, + .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .adc_nids = alc272_adc_nids, .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), @@ -19074,7 +19074,7 @@ static struct alc_config_preset alc662_presets[] = { .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), - .dac_nids = alc662_dac_nids, + .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .adc_nids = alc662_adc_nids, .num_adc_nids = 1, -- GitLab From 1304ac8993e32c0530bc82bf1d3f953548a20971 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 6 Apr 2011 15:16:21 +0200 Subject: [PATCH 0509/5560] ALSA: hda - Fix mix->DAC deduction for ALC892 The current alc662 parser doesn't set the DAC for the mixer 0x0f properly for ALC892, which has 4 DACs while ALC662 has 3. Fixed by implementing alc662_mix_to_dac() more genericly with the dynamic widget list. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e62fe7f2aeff..d566eac08d6c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19105,16 +19105,17 @@ static struct alc_config_preset alc662_presets[] = { */ /* convert from MIX nid to DAC */ -static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) -{ - if (nid == 0x0f) - return 0x02; - else if (nid >= 0x0c && nid <= 0x0e) - return nid - 0x0c + 0x02; - else if (nid == 0x26) /* ALC887-VD has this DAC too */ - return 0x25; - else - return 0; +static hda_nid_t alc662_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) +{ + hda_nid_t list[4]; + int i, num; + + num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); + for (i = 0; i < num; i++) { + if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) + return list[i]; + } + return 0; } /* get MIX nid connected to the given pin targeted to DAC */ @@ -19126,7 +19127,7 @@ static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); for (i = 0; i < num; i++) { - if (alc662_mix_to_dac(mix[i]) == dac) + if (alc662_mix_to_dac(codec, mix[i]) == dac) return mix[i]; } return 0; @@ -19143,7 +19144,7 @@ static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) if (num < 0) return 0; for (i = 0; i < num; i++) { - hda_nid_t nid = alc662_mix_to_dac(srcs[i]); + hda_nid_t nid = alc662_mix_to_dac(codec, srcs[i]); if (!nid) continue; for (j = 0; j < spec->multiout.num_dacs; j++) @@ -19297,7 +19298,7 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, if (num <= 1) return; for (i = 0; i < num; i++) { - if (alc662_mix_to_dac(srcs[i]) != dac) + if (alc662_mix_to_dac(codec, srcs[i]) != dac) continue; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); return; -- GitLab From 79add6277396b91c638f16eb2f1338badc47760d Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 4 Apr 2011 14:15:29 -0700 Subject: [PATCH 0510/5560] update David Miller's old email address Signed-off-by: Justin P. Mattock Acked-by: David S. Miller Signed-off-by: Jiri Kosina --- arch/mips/fw/arc/cmdline.c | 2 +- arch/mips/fw/arc/env.c | 2 +- arch/mips/fw/arc/identify.c | 2 +- arch/mips/fw/arc/init.c | 2 +- arch/mips/fw/arc/misc.c | 2 +- arch/mips/fw/arc/salone.c | 2 +- arch/mips/fw/arc/time.c | 2 +- arch/mips/fw/arc/tree.c | 2 +- arch/mips/include/asm/asmmacro-32.h | 2 +- arch/mips/include/asm/asmmacro-64.h | 2 +- arch/mips/include/asm/cpu.h | 2 +- arch/mips/include/asm/r4kcache.h | 2 +- arch/mips/include/asm/sgialib.h | 2 +- arch/mips/include/asm/sgiarcs.h | 2 +- arch/mips/kernel/octeon_switch.S | 2 +- arch/mips/kernel/r2300_fpu.S | 2 +- arch/mips/kernel/r2300_switch.S | 2 +- arch/mips/kernel/r4k_fpu.S | 2 +- arch/mips/kernel/r4k_switch.S | 2 +- arch/mips/kernel/r6000_fpu.S | 2 +- arch/mips/mm/c-r3k.c | 2 +- arch/mips/mm/c-r4k.c | 2 +- arch/mips/mm/c-tx39.c | 2 +- arch/mips/mm/sc-ip22.c | 2 +- arch/mips/mm/sc-r5k.c | 2 +- arch/mips/mm/tlb-r3k.c | 2 +- arch/mips/mm/tlb-r4k.c | 2 +- arch/mips/mm/tlb-r8k.c | 2 +- arch/mips/sgi-ip22/ip22-hpc.c | 2 +- arch/mips/sgi-ip22/ip22-int.c | 2 +- arch/mips/sgi-ip22/ip22-mc.c | 2 +- arch/mips/sgi-ip22/ip22-setup.c | 2 +- drivers/net/sgiseeq.c | 2 +- drivers/net/sgiseeq.h | 2 +- drivers/scsi/sgiwd93.c | 2 +- drivers/video/console/newport_con.c | 2 +- include/video/newport.h | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/arch/mips/fw/arc/cmdline.c b/arch/mips/fw/arc/cmdline.c index 5c8603c85f20..9fdf07e50f1b 100644 --- a/arch/mips/fw/arc/cmdline.c +++ b/arch/mips/fw/arc/cmdline.c @@ -5,7 +5,7 @@ * * cmdline.c: Kernel command line creation using ARCS argc/argv. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include #include diff --git a/arch/mips/fw/arc/env.c b/arch/mips/fw/arc/env.c index 6f5dd42b96e2..1118a26b32ee 100644 --- a/arch/mips/fw/arc/env.c +++ b/arch/mips/fw/arc/env.c @@ -5,7 +5,7 @@ * * env.c: ARCS environment variable routines. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include #include diff --git a/arch/mips/fw/arc/identify.c b/arch/mips/fw/arc/identify.c index 0ce9acf10c39..788060a53dce 100644 --- a/arch/mips/fw/arc/identify.c +++ b/arch/mips/fw/arc/identify.c @@ -9,7 +9,7 @@ * * This code is based on arch/mips/sgi/kernel/system.c, which is * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include #include diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c index 3ad8788b6eaa..629b24db0d3a 100644 --- a/arch/mips/fw/arc/init.c +++ b/arch/mips/fw/arc/init.c @@ -5,7 +5,7 @@ * * PROM library initialisation code. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include #include diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c index e527c5fd5a32..29627fbae7ad 100644 --- a/arch/mips/fw/arc/misc.c +++ b/arch/mips/fw/arc/misc.c @@ -5,7 +5,7 @@ * * Miscellaneous ARCS PROM routines. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. */ diff --git a/arch/mips/fw/arc/salone.c b/arch/mips/fw/arc/salone.c index e6afb64723d0..9b568950d1fd 100644 --- a/arch/mips/fw/arc/salone.c +++ b/arch/mips/fw/arc/salone.c @@ -2,7 +2,7 @@ * Routines to load into memory and execute stand-along program images using * ARCS PROM firmware. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include #include diff --git a/arch/mips/fw/arc/time.c b/arch/mips/fw/arc/time.c index 42138c837d48..190cdb50b895 100644 --- a/arch/mips/fw/arc/time.c +++ b/arch/mips/fw/arc/time.c @@ -5,7 +5,7 @@ * * Extracting time information from ARCS prom. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include diff --git a/arch/mips/fw/arc/tree.c b/arch/mips/fw/arc/tree.c index d68e5a59c1f6..924a37dc2569 100644 --- a/arch/mips/fw/arc/tree.c +++ b/arch/mips/fw/arc/tree.c @@ -5,7 +5,7 @@ * * PROM component device tree code. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. */ diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h index 5de3963f511e..2413afe21b33 100644 --- a/arch/mips/include/asm/asmmacro-32.h +++ b/arch/mips/include/asm/asmmacro-32.h @@ -1,7 +1,7 @@ /* * asmmacro.h: Assembler macros to make things easier to read. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1998, 1999, 2003 Ralf Baechle */ #ifndef _ASM_ASMMACRO_32_H diff --git a/arch/mips/include/asm/asmmacro-64.h b/arch/mips/include/asm/asmmacro-64.h index 225feefcb25d..08a527dfe4a3 100644 --- a/arch/mips/include/asm/asmmacro-64.h +++ b/arch/mips/include/asm/asmmacro-64.h @@ -1,7 +1,7 @@ /* * asmmacro.h: Assembler macros to make things easier to read. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1998, 1999 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 86877539c6e8..e7af793e5368 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -2,7 +2,7 @@ * cpu.h: Values of the PRId register used to match up * various MIPS cpu types. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 2004 Maciej W. Rozycki */ #ifndef _ASM_CPU_H diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 387bf59f1e37..54ea47da59a1 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -5,7 +5,7 @@ * * Inline assembly cache operations. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org) * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org) */ diff --git a/arch/mips/include/asm/sgialib.h b/arch/mips/include/asm/sgialib.h index 2a2f1bddc276..f58115769457 100644 --- a/arch/mips/include/asm/sgialib.h +++ b/arch/mips/include/asm/sgialib.h @@ -5,7 +5,7 @@ * * SGI ARCS firmware interface library for the Linux kernel. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org) */ #ifndef _ASM_SGIALIB_H diff --git a/arch/mips/include/asm/sgiarcs.h b/arch/mips/include/asm/sgiarcs.h index 721327f88601..149342951436 100644 --- a/arch/mips/include/asm/sgiarcs.h +++ b/arch/mips/include/asm/sgiarcs.h @@ -5,7 +5,7 @@ * * ARC firmware interface defines. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. */ diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index dd18b26a358a..ce89c8061708 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1994, 1995, 1996, by Andreas Busse * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2000 MIPS Technologies, Inc. diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S index ac68e68339db..61c8a0f2a60c 100644 --- a/arch/mips/kernel/r2300_fpu.S +++ b/arch/mips/kernel/r2300_fpu.S @@ -6,7 +6,7 @@ * Copyright (C) 1996, 1998 by Ralf Baechle * * Multi-arch abstraction and asm macros for easier reading: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * Further modifications to make this work: * Copyright (c) 1998 Harald Koerfgen diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 698414b7a253..293898391e67 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -5,7 +5,7 @@ * Copyright (C) 1994, 1995, 1996 by Andreas Busse * * Multi-cpu abstraction and macros for easier reading: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * Further modifications to make this work: * Copyright (c) 1998-2000 Harald Koerfgen diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index dbd42adc52ed..55ffe149dae9 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -6,7 +6,7 @@ * Copyright (C) 1996, 98, 99, 2000, 01 Ralf Baechle * * Multi-arch abstraction and asm macros for easier reading: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 8893ee1a2368..9414f9354469 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1994, 1995, 1996, by Andreas Busse * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2000 MIPS Technologies, Inc. diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S index 43cda53f5af6..da0fbe46d83b 100644 --- a/arch/mips/kernel/r6000_fpu.S +++ b/arch/mips/kernel/r6000_fpu.S @@ -8,7 +8,7 @@ * Copyright (C) 1996 by Ralf Baechle * * Multi-arch abstraction and asm macros for easier reading: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #include #include diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 54e5f7b9f440..e6b0efd3f6a4 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -1,7 +1,7 @@ /* * r2300.c: R2000 and R3000 specific mmu/cache code. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * with a lot of changes to make this thing work for R3000s * Tx39XX R4k style caches added. HK diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index b4923a75cb4b..fd5cb57905d0 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 6515b4418714..d352fad3e451 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -1,7 +1,7 @@ /* * r2300.c: R2000 and R3000 specific mmu/cache code. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * with a lot of changes to make this thing work for R3000s * Tx39XX R4k style caches added. HK diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c index 13adb5782110..a6bd11fba7bf 100644 --- a/arch/mips/mm/sc-ip22.c +++ b/arch/mips/mm/sc-ip22.c @@ -2,7 +2,7 @@ * sc-ip22.c: Indy cache management functions. * * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + * derived from r4xx0.c by David S. Miller (davem@davemloft.net). */ #include #include diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c index f330d38e5575..ae1e533a096e 100644 --- a/arch/mips/mm/sc-r5k.c +++ b/arch/mips/mm/sc-r5k.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + * derived from r4xx0.c by David S. Miller (davem@davemloft.net). */ #include #include diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index 0f5ab236ab69..40424affef83 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c @@ -1,7 +1,7 @@ /* * r2300.c: R2000 and R3000 specific mmu/cache code. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * with a lot of changes to make this thing work for R3000s * Tx39XX R4k style caches added. HK diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index c618eed933a1..ba40325caea6 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index 2b82f23df1a1..3d95f76c106b 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. diff --git a/arch/mips/sgi-ip22/ip22-hpc.c b/arch/mips/sgi-ip22/ip22-hpc.c index 5c00cdd20d8e..bb70589b5f74 100644 --- a/arch/mips/sgi-ip22/ip22-hpc.c +++ b/arch/mips/sgi-ip22/ip22-hpc.c @@ -1,7 +1,7 @@ /* * ip22-hpc.c: Routines for generic manipulation of the HPC controllers. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1998 Ralf Baechle */ diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 383f11d7f442..13d87d2e29aa 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -2,7 +2,7 @@ * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC * found on INDY and Indigo2 workstations. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) * - Indigo2 changes diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 5268ac187bbd..d22262ee6853 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c @@ -1,7 +1,7 @@ /* * ip22-mc.c: Routines for manipulating SGI Memory Controller. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) * Copyright (C) 2004 Peter Fuerst (pf@net.alphadv.de) - IP28 diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index 5deeb68b6c9c..5e6621349471 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c @@ -1,7 +1,7 @@ /* * ip22-setup.c: SGI specific setup, including init of the feature struct. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) */ #include diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 3a0cc63428ee..f016e613a492 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -1,7 +1,7 @@ /* * sgiseeq.c: Seeq8003 ethernet driver for SGI machines. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #undef DEBUG diff --git a/drivers/net/sgiseeq.h b/drivers/net/sgiseeq.h index 523104de6830..2211e2987a8d 100644 --- a/drivers/net/sgiseeq.h +++ b/drivers/net/sgiseeq.h @@ -1,7 +1,7 @@ /* * sgiseeq.h: Defines for the Seeq8003 ethernet controller. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #ifndef _SGISEEQ_H #define _SGISEEQ_H diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index fef0e3c75b16..3a9d85ca6047 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 3772433c49d1..93317b5b8740 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -6,7 +6,7 @@ * * This driver is based on sgicons.c and cons_newport. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) */ #include diff --git a/include/video/newport.h b/include/video/newport.h index 001b935e71c4..db9d9e3d6cc0 100644 --- a/include/video/newport.h +++ b/include/video/newport.h @@ -3,7 +3,7 @@ * newport.h: Defines and register layout for NEWPORT graphics * hardware. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * * Ulf Carlsson - Compability with the IRIX structures added */ -- GitLab From 5a3016a61530ea171c1b8ab23d7f651de919e39f Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 6 Apr 2011 11:09:55 +0200 Subject: [PATCH 0511/5560] doc: fix 3 typos in sysctl/vm.txt Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- Documentation/sysctl/vm.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 30289fab86eb..96f0ee825bed 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -481,10 +481,10 @@ the DMA zone. Type(A) is called as "Node" order. Type (B) is "Zone" order. "Node order" orders the zonelists by node, then by zone within each node. -Specify "[Nn]ode" for zone order +Specify "[Nn]ode" for node order "Zone Order" orders the zonelists by zone type, then by node within each -zone. Specify "[Zz]one"for zode order. +zone. Specify "[Zz]one" for zone order. Specify "[Dd]efault" to request automatic configuration. Autoconfiguration will select "node" order in following case. -- GitLab From 82a5a936f6dea13849d93a2899a9b7294a8db336 Mon Sep 17 00:00:00 2001 From: Peter Hsiang Date: Mon, 4 Apr 2011 19:35:30 -0700 Subject: [PATCH 0512/5560] ASoC: Add max98095 CODEC driver This patch adds the MAX98095 CODEC driver. Signed-off-by: Peter Hsiang Signed-off-by: Mark Brown --- include/sound/max98095.h | 26 + sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/max98095.c | 2009 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/max98095.h | 284 +++++ 5 files changed, 2325 insertions(+) create mode 100644 include/sound/max98095.h create mode 100644 sound/soc/codecs/max98095.c create mode 100644 sound/soc/codecs/max98095.h diff --git a/include/sound/max98095.h b/include/sound/max98095.h new file mode 100644 index 000000000000..3381765b503e --- /dev/null +++ b/include/sound/max98095.h @@ -0,0 +1,26 @@ +/* + * Platform data for MAX98095 + * + * Copyright 2011 Maxim Integrated Products + * + * 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. + * + */ + +#ifndef __SOUND_MAX98095_PDATA_H__ +#define __SOUND_MAX98095_PDATA_H__ + +/* codec platform data */ +struct max98095_pdata { + /* Analog/digital microphone configuration: + * 0 = analog microphone input (normal setting) + * 1 = digital microphone input + */ + unsigned int digmic_left_mode:1; + unsigned int digmic_right_mode:1; +}; + +#endif diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b814ed0a1636..78da05b5e5eb 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -33,6 +33,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_JZ4740_CODEC if SOC_JZ4740 select SND_SOC_LM4857 if I2C select SND_SOC_MAX98088 if I2C + select SND_SOC_MAX98095 if I2C select SND_SOC_MAX9850 if I2C select SND_SOC_MAX9877 if I2C select SND_SOC_PCM3008 @@ -187,6 +188,9 @@ config SND_SOC_DMIC config SND_SOC_MAX98088 tristate +config SND_SOC_MAX98095 + tristate + config SND_SOC_MAX9850 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 49121ad0e172..f030c1826746 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -19,6 +19,7 @@ snd-soc-dfbmcs320-objs := dfbmcs320.o snd-soc-dmic-objs := dmic.o snd-soc-l3-objs := l3.o snd-soc-max98088-objs := max98088.o +snd-soc-max98095-objs := max98095.o snd-soc-max9850-objs := max9850.o snd-soc-pcm3008-objs := pcm3008.o snd-soc-sgtl5000-objs := sgtl5000.o @@ -108,6 +109,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o +obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c new file mode 100644 index 000000000000..9c77f17a6afb --- /dev/null +++ b/sound/soc/codecs/max98095.c @@ -0,0 +1,2009 @@ +/* + * max98095.c -- MAX98095 ALSA SoC Audio driver + * + * Copyright 2011 Maxim Integrated Products + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "max98095.h" + +enum max98095_type { + MAX98095, +}; + +struct max98095_cdata { + unsigned int rate; + unsigned int fmt; +}; + +struct max98095_priv { + enum max98095_type devtype; + void *control_data; + struct max98095_pdata *pdata; + unsigned int sysclk; + struct max98095_cdata dai[3]; + u8 lin_state; + unsigned int mic1pre; + unsigned int mic2pre; +}; + +static const u8 max98095_reg_def[M98095_REG_CNT] = { + 0x00, /* 00 */ + 0x00, /* 01 */ + 0x00, /* 02 */ + 0x00, /* 03 */ + 0x00, /* 04 */ + 0x00, /* 05 */ + 0x00, /* 06 */ + 0x00, /* 07 */ + 0x00, /* 08 */ + 0x00, /* 09 */ + 0x00, /* 0A */ + 0x00, /* 0B */ + 0x00, /* 0C */ + 0x00, /* 0D */ + 0x00, /* 0E */ + 0x00, /* 0F */ + 0x00, /* 10 */ + 0x00, /* 11 */ + 0x00, /* 12 */ + 0x00, /* 13 */ + 0x00, /* 14 */ + 0x00, /* 15 */ + 0x00, /* 16 */ + 0x00, /* 17 */ + 0x00, /* 18 */ + 0x00, /* 19 */ + 0x00, /* 1A */ + 0x00, /* 1B */ + 0x00, /* 1C */ + 0x00, /* 1D */ + 0x00, /* 1E */ + 0x00, /* 1F */ + 0x00, /* 20 */ + 0x00, /* 21 */ + 0x00, /* 22 */ + 0x00, /* 23 */ + 0x00, /* 24 */ + 0x00, /* 25 */ + 0x00, /* 26 */ + 0x00, /* 27 */ + 0x00, /* 28 */ + 0x00, /* 29 */ + 0x00, /* 2A */ + 0x00, /* 2B */ + 0x00, /* 2C */ + 0x00, /* 2D */ + 0x00, /* 2E */ + 0x00, /* 2F */ + 0x00, /* 30 */ + 0x00, /* 31 */ + 0x00, /* 32 */ + 0x00, /* 33 */ + 0x00, /* 34 */ + 0x00, /* 35 */ + 0x00, /* 36 */ + 0x00, /* 37 */ + 0x00, /* 38 */ + 0x00, /* 39 */ + 0x00, /* 3A */ + 0x00, /* 3B */ + 0x00, /* 3C */ + 0x00, /* 3D */ + 0x00, /* 3E */ + 0x00, /* 3F */ + 0x00, /* 40 */ + 0x00, /* 41 */ + 0x00, /* 42 */ + 0x00, /* 43 */ + 0x00, /* 44 */ + 0x00, /* 45 */ + 0x00, /* 46 */ + 0x00, /* 47 */ + 0x00, /* 48 */ + 0x00, /* 49 */ + 0x00, /* 4A */ + 0x00, /* 4B */ + 0x00, /* 4C */ + 0x00, /* 4D */ + 0x00, /* 4E */ + 0x00, /* 4F */ + 0x00, /* 50 */ + 0x00, /* 51 */ + 0x00, /* 52 */ + 0x00, /* 53 */ + 0x00, /* 54 */ + 0x00, /* 55 */ + 0x00, /* 56 */ + 0x00, /* 57 */ + 0x00, /* 58 */ + 0x00, /* 59 */ + 0x00, /* 5A */ + 0x00, /* 5B */ + 0x00, /* 5C */ + 0x00, /* 5D */ + 0x00, /* 5E */ + 0x00, /* 5F */ + 0x00, /* 60 */ + 0x00, /* 61 */ + 0x00, /* 62 */ + 0x00, /* 63 */ + 0x00, /* 64 */ + 0x00, /* 65 */ + 0x00, /* 66 */ + 0x00, /* 67 */ + 0x00, /* 68 */ + 0x00, /* 69 */ + 0x00, /* 6A */ + 0x00, /* 6B */ + 0x00, /* 6C */ + 0x00, /* 6D */ + 0x00, /* 6E */ + 0x00, /* 6F */ + 0x00, /* 70 */ + 0x00, /* 71 */ + 0x00, /* 72 */ + 0x00, /* 73 */ + 0x00, /* 74 */ + 0x00, /* 75 */ + 0x00, /* 76 */ + 0x00, /* 77 */ + 0x00, /* 78 */ + 0x00, /* 79 */ + 0x00, /* 7A */ + 0x00, /* 7B */ + 0x00, /* 7C */ + 0x00, /* 7D */ + 0x00, /* 7E */ + 0x00, /* 7F */ + 0x00, /* 80 */ + 0x00, /* 81 */ + 0x00, /* 82 */ + 0x00, /* 83 */ + 0x00, /* 84 */ + 0x00, /* 85 */ + 0x00, /* 86 */ + 0x00, /* 87 */ + 0x00, /* 88 */ + 0x00, /* 89 */ + 0x00, /* 8A */ + 0x00, /* 8B */ + 0x00, /* 8C */ + 0x00, /* 8D */ + 0x00, /* 8E */ + 0x00, /* 8F */ + 0x00, /* 90 */ + 0x00, /* 91 */ + 0x30, /* 92 */ + 0xF0, /* 93 */ + 0x00, /* 94 */ + 0x00, /* 95 */ + 0x3F, /* 96 */ + 0x00, /* 97 */ + 0x00, /* 98 */ + 0x00, /* 99 */ + 0x00, /* 9A */ + 0x00, /* 9B */ + 0x00, /* 9C */ + 0x00, /* 9D */ + 0x00, /* 9E */ + 0x00, /* 9F */ + 0x00, /* A0 */ + 0x00, /* A1 */ + 0x00, /* A2 */ + 0x00, /* A3 */ + 0x00, /* A4 */ + 0x00, /* A5 */ + 0x00, /* A6 */ + 0x00, /* A7 */ + 0x00, /* A8 */ + 0x00, /* A9 */ + 0x00, /* AA */ + 0x00, /* AB */ + 0x00, /* AC */ + 0x00, /* AD */ + 0x00, /* AE */ + 0x00, /* AF */ + 0x00, /* B0 */ + 0x00, /* B1 */ + 0x00, /* B2 */ + 0x00, /* B3 */ + 0x00, /* B4 */ + 0x00, /* B5 */ + 0x00, /* B6 */ + 0x00, /* B7 */ + 0x00, /* B8 */ + 0x00, /* B9 */ + 0x00, /* BA */ + 0x00, /* BB */ + 0x00, /* BC */ + 0x00, /* BD */ + 0x00, /* BE */ + 0x00, /* BF */ + 0x00, /* C0 */ + 0x00, /* C1 */ + 0x00, /* C2 */ + 0x00, /* C3 */ + 0x00, /* C4 */ + 0x00, /* C5 */ + 0x00, /* C6 */ + 0x00, /* C7 */ + 0x00, /* C8 */ + 0x00, /* C9 */ + 0x00, /* CA */ + 0x00, /* CB */ + 0x00, /* CC */ + 0x00, /* CD */ + 0x00, /* CE */ + 0x00, /* CF */ + 0x00, /* D0 */ + 0x00, /* D1 */ + 0x00, /* D2 */ + 0x00, /* D3 */ + 0x00, /* D4 */ + 0x00, /* D5 */ + 0x00, /* D6 */ + 0x00, /* D7 */ + 0x00, /* D8 */ + 0x00, /* D9 */ + 0x00, /* DA */ + 0x00, /* DB */ + 0x00, /* DC */ + 0x00, /* DD */ + 0x00, /* DE */ + 0x00, /* DF */ + 0x00, /* E0 */ + 0x00, /* E1 */ + 0x00, /* E2 */ + 0x00, /* E3 */ + 0x00, /* E4 */ + 0x00, /* E5 */ + 0x00, /* E6 */ + 0x00, /* E7 */ + 0x00, /* E8 */ + 0x00, /* E9 */ + 0x00, /* EA */ + 0x00, /* EB */ + 0x00, /* EC */ + 0x00, /* ED */ + 0x00, /* EE */ + 0x00, /* EF */ + 0x00, /* F0 */ + 0x00, /* F1 */ + 0x00, /* F2 */ + 0x00, /* F3 */ + 0x00, /* F4 */ + 0x00, /* F5 */ + 0x00, /* F6 */ + 0x00, /* F7 */ + 0x00, /* F8 */ + 0x00, /* F9 */ + 0x00, /* FA */ + 0x00, /* FB */ + 0x00, /* FC */ + 0x00, /* FD */ + 0x00, /* FE */ + 0x00, /* FF */ +}; + +static struct { + int readable; + int writable; +} max98095_access[M98095_REG_CNT] = { + { 0x00, 0x00 }, /* 00 */ + { 0xFF, 0x00 }, /* 01 */ + { 0xFF, 0x00 }, /* 02 */ + { 0xFF, 0x00 }, /* 03 */ + { 0xFF, 0x00 }, /* 04 */ + { 0xFF, 0x00 }, /* 05 */ + { 0xFF, 0x00 }, /* 06 */ + { 0xFF, 0x00 }, /* 07 */ + { 0xFF, 0x00 }, /* 08 */ + { 0xFF, 0x00 }, /* 09 */ + { 0xFF, 0x00 }, /* 0A */ + { 0xFF, 0x00 }, /* 0B */ + { 0xFF, 0x00 }, /* 0C */ + { 0xFF, 0x00 }, /* 0D */ + { 0xFF, 0x00 }, /* 0E */ + { 0xFF, 0x9F }, /* 0F */ + { 0xFF, 0xFF }, /* 10 */ + { 0xFF, 0xFF }, /* 11 */ + { 0xFF, 0xFF }, /* 12 */ + { 0xFF, 0xFF }, /* 13 */ + { 0xFF, 0xFF }, /* 14 */ + { 0xFF, 0xFF }, /* 15 */ + { 0xFF, 0xFF }, /* 16 */ + { 0xFF, 0xFF }, /* 17 */ + { 0xFF, 0xFF }, /* 18 */ + { 0xFF, 0xFF }, /* 19 */ + { 0xFF, 0xFF }, /* 1A */ + { 0xFF, 0xFF }, /* 1B */ + { 0xFF, 0xFF }, /* 1C */ + { 0xFF, 0xFF }, /* 1D */ + { 0xFF, 0x77 }, /* 1E */ + { 0xFF, 0x77 }, /* 1F */ + { 0xFF, 0x77 }, /* 20 */ + { 0xFF, 0x77 }, /* 21 */ + { 0xFF, 0x77 }, /* 22 */ + { 0xFF, 0x77 }, /* 23 */ + { 0xFF, 0xFF }, /* 24 */ + { 0xFF, 0x7F }, /* 25 */ + { 0xFF, 0x31 }, /* 26 */ + { 0xFF, 0xFF }, /* 27 */ + { 0xFF, 0xFF }, /* 28 */ + { 0xFF, 0xFF }, /* 29 */ + { 0xFF, 0xF7 }, /* 2A */ + { 0xFF, 0x2F }, /* 2B */ + { 0xFF, 0xEF }, /* 2C */ + { 0xFF, 0xFF }, /* 2D */ + { 0xFF, 0xFF }, /* 2E */ + { 0xFF, 0xFF }, /* 2F */ + { 0xFF, 0xFF }, /* 30 */ + { 0xFF, 0xFF }, /* 31 */ + { 0xFF, 0xFF }, /* 32 */ + { 0xFF, 0xFF }, /* 33 */ + { 0xFF, 0xF7 }, /* 34 */ + { 0xFF, 0x2F }, /* 35 */ + { 0xFF, 0xCF }, /* 36 */ + { 0xFF, 0xFF }, /* 37 */ + { 0xFF, 0xFF }, /* 38 */ + { 0xFF, 0xFF }, /* 39 */ + { 0xFF, 0xFF }, /* 3A */ + { 0xFF, 0xFF }, /* 3B */ + { 0xFF, 0xFF }, /* 3C */ + { 0xFF, 0xFF }, /* 3D */ + { 0xFF, 0xF7 }, /* 3E */ + { 0xFF, 0x2F }, /* 3F */ + { 0xFF, 0xCF }, /* 40 */ + { 0xFF, 0xFF }, /* 41 */ + { 0xFF, 0x77 }, /* 42 */ + { 0xFF, 0xFF }, /* 43 */ + { 0xFF, 0xFF }, /* 44 */ + { 0xFF, 0xFF }, /* 45 */ + { 0xFF, 0xFF }, /* 46 */ + { 0xFF, 0xFF }, /* 47 */ + { 0xFF, 0xFF }, /* 48 */ + { 0xFF, 0x0F }, /* 49 */ + { 0xFF, 0xFF }, /* 4A */ + { 0xFF, 0xFF }, /* 4B */ + { 0xFF, 0x3F }, /* 4C */ + { 0xFF, 0x3F }, /* 4D */ + { 0xFF, 0x3F }, /* 4E */ + { 0xFF, 0xFF }, /* 4F */ + { 0xFF, 0x7F }, /* 50 */ + { 0xFF, 0x7F }, /* 51 */ + { 0xFF, 0x0F }, /* 52 */ + { 0xFF, 0x3F }, /* 53 */ + { 0xFF, 0x3F }, /* 54 */ + { 0xFF, 0x3F }, /* 55 */ + { 0xFF, 0xFF }, /* 56 */ + { 0xFF, 0xFF }, /* 57 */ + { 0xFF, 0xBF }, /* 58 */ + { 0xFF, 0x1F }, /* 59 */ + { 0xFF, 0xBF }, /* 5A */ + { 0xFF, 0x1F }, /* 5B */ + { 0xFF, 0xBF }, /* 5C */ + { 0xFF, 0x3F }, /* 5D */ + { 0xFF, 0x3F }, /* 5E */ + { 0xFF, 0x7F }, /* 5F */ + { 0xFF, 0x7F }, /* 60 */ + { 0xFF, 0x47 }, /* 61 */ + { 0xFF, 0x9F }, /* 62 */ + { 0xFF, 0x9F }, /* 63 */ + { 0xFF, 0x9F }, /* 64 */ + { 0xFF, 0x9F }, /* 65 */ + { 0xFF, 0x9F }, /* 66 */ + { 0xFF, 0xBF }, /* 67 */ + { 0xFF, 0xBF }, /* 68 */ + { 0xFF, 0xFF }, /* 69 */ + { 0xFF, 0xFF }, /* 6A */ + { 0xFF, 0x7F }, /* 6B */ + { 0xFF, 0xF7 }, /* 6C */ + { 0xFF, 0xFF }, /* 6D */ + { 0xFF, 0xFF }, /* 6E */ + { 0xFF, 0x1F }, /* 6F */ + { 0xFF, 0xF7 }, /* 70 */ + { 0xFF, 0xFF }, /* 71 */ + { 0xFF, 0xFF }, /* 72 */ + { 0xFF, 0x1F }, /* 73 */ + { 0xFF, 0xF7 }, /* 74 */ + { 0xFF, 0xFF }, /* 75 */ + { 0xFF, 0xFF }, /* 76 */ + { 0xFF, 0x1F }, /* 77 */ + { 0xFF, 0xF7 }, /* 78 */ + { 0xFF, 0xFF }, /* 79 */ + { 0xFF, 0xFF }, /* 7A */ + { 0xFF, 0x1F }, /* 7B */ + { 0xFF, 0xF7 }, /* 7C */ + { 0xFF, 0xFF }, /* 7D */ + { 0xFF, 0xFF }, /* 7E */ + { 0xFF, 0x1F }, /* 7F */ + { 0xFF, 0xF7 }, /* 80 */ + { 0xFF, 0xFF }, /* 81 */ + { 0xFF, 0xFF }, /* 82 */ + { 0xFF, 0x1F }, /* 83 */ + { 0xFF, 0x7F }, /* 84 */ + { 0xFF, 0x0F }, /* 85 */ + { 0xFF, 0xD8 }, /* 86 */ + { 0xFF, 0xFF }, /* 87 */ + { 0xFF, 0xEF }, /* 88 */ + { 0xFF, 0xFE }, /* 89 */ + { 0xFF, 0xFE }, /* 8A */ + { 0xFF, 0xFF }, /* 8B */ + { 0xFF, 0xFF }, /* 8C */ + { 0xFF, 0x3F }, /* 8D */ + { 0xFF, 0xFF }, /* 8E */ + { 0xFF, 0x3F }, /* 8F */ + { 0xFF, 0x8F }, /* 90 */ + { 0xFF, 0xFF }, /* 91 */ + { 0xFF, 0x3F }, /* 92 */ + { 0xFF, 0xFF }, /* 93 */ + { 0xFF, 0xFF }, /* 94 */ + { 0xFF, 0x0F }, /* 95 */ + { 0xFF, 0x3F }, /* 96 */ + { 0xFF, 0x8C }, /* 97 */ + { 0x00, 0x00 }, /* 98 */ + { 0x00, 0x00 }, /* 99 */ + { 0x00, 0x00 }, /* 9A */ + { 0x00, 0x00 }, /* 9B */ + { 0x00, 0x00 }, /* 9C */ + { 0x00, 0x00 }, /* 9D */ + { 0x00, 0x00 }, /* 9E */ + { 0x00, 0x00 }, /* 9F */ + { 0x00, 0x00 }, /* A0 */ + { 0x00, 0x00 }, /* A1 */ + { 0x00, 0x00 }, /* A2 */ + { 0x00, 0x00 }, /* A3 */ + { 0x00, 0x00 }, /* A4 */ + { 0x00, 0x00 }, /* A5 */ + { 0x00, 0x00 }, /* A6 */ + { 0x00, 0x00 }, /* A7 */ + { 0x00, 0x00 }, /* A8 */ + { 0x00, 0x00 }, /* A9 */ + { 0x00, 0x00 }, /* AA */ + { 0x00, 0x00 }, /* AB */ + { 0x00, 0x00 }, /* AC */ + { 0x00, 0x00 }, /* AD */ + { 0x00, 0x00 }, /* AE */ + { 0x00, 0x00 }, /* AF */ + { 0x00, 0x00 }, /* B0 */ + { 0x00, 0x00 }, /* B1 */ + { 0x00, 0x00 }, /* B2 */ + { 0x00, 0x00 }, /* B3 */ + { 0x00, 0x00 }, /* B4 */ + { 0x00, 0x00 }, /* B5 */ + { 0x00, 0x00 }, /* B6 */ + { 0x00, 0x00 }, /* B7 */ + { 0x00, 0x00 }, /* B8 */ + { 0x00, 0x00 }, /* B9 */ + { 0x00, 0x00 }, /* BA */ + { 0x00, 0x00 }, /* BB */ + { 0x00, 0x00 }, /* BC */ + { 0x00, 0x00 }, /* BD */ + { 0x00, 0x00 }, /* BE */ + { 0x00, 0x00 }, /* BF */ + { 0x00, 0x00 }, /* C0 */ + { 0x00, 0x00 }, /* C1 */ + { 0x00, 0x00 }, /* C2 */ + { 0x00, 0x00 }, /* C3 */ + { 0x00, 0x00 }, /* C4 */ + { 0x00, 0x00 }, /* C5 */ + { 0x00, 0x00 }, /* C6 */ + { 0x00, 0x00 }, /* C7 */ + { 0x00, 0x00 }, /* C8 */ + { 0x00, 0x00 }, /* C9 */ + { 0x00, 0x00 }, /* CA */ + { 0x00, 0x00 }, /* CB */ + { 0x00, 0x00 }, /* CC */ + { 0x00, 0x00 }, /* CD */ + { 0x00, 0x00 }, /* CE */ + { 0x00, 0x00 }, /* CF */ + { 0x00, 0x00 }, /* D0 */ + { 0x00, 0x00 }, /* D1 */ + { 0x00, 0x00 }, /* D2 */ + { 0x00, 0x00 }, /* D3 */ + { 0x00, 0x00 }, /* D4 */ + { 0x00, 0x00 }, /* D5 */ + { 0x00, 0x00 }, /* D6 */ + { 0x00, 0x00 }, /* D7 */ + { 0x00, 0x00 }, /* D8 */ + { 0x00, 0x00 }, /* D9 */ + { 0x00, 0x00 }, /* DA */ + { 0x00, 0x00 }, /* DB */ + { 0x00, 0x00 }, /* DC */ + { 0x00, 0x00 }, /* DD */ + { 0x00, 0x00 }, /* DE */ + { 0x00, 0x00 }, /* DF */ + { 0x00, 0x00 }, /* E0 */ + { 0x00, 0x00 }, /* E1 */ + { 0x00, 0x00 }, /* E2 */ + { 0x00, 0x00 }, /* E3 */ + { 0x00, 0x00 }, /* E4 */ + { 0x00, 0x00 }, /* E5 */ + { 0x00, 0x00 }, /* E6 */ + { 0x00, 0x00 }, /* E7 */ + { 0x00, 0x00 }, /* E8 */ + { 0x00, 0x00 }, /* E9 */ + { 0x00, 0x00 }, /* EA */ + { 0x00, 0x00 }, /* EB */ + { 0x00, 0x00 }, /* EC */ + { 0x00, 0x00 }, /* ED */ + { 0x00, 0x00 }, /* EE */ + { 0x00, 0x00 }, /* EF */ + { 0x00, 0x00 }, /* F0 */ + { 0x00, 0x00 }, /* F1 */ + { 0x00, 0x00 }, /* F2 */ + { 0x00, 0x00 }, /* F3 */ + { 0x00, 0x00 }, /* F4 */ + { 0x00, 0x00 }, /* F5 */ + { 0x00, 0x00 }, /* F6 */ + { 0x00, 0x00 }, /* F7 */ + { 0x00, 0x00 }, /* F8 */ + { 0x00, 0x00 }, /* F9 */ + { 0x00, 0x00 }, /* FA */ + { 0x00, 0x00 }, /* FB */ + { 0x00, 0x00 }, /* FC */ + { 0x00, 0x00 }, /* FD */ + { 0x00, 0x00 }, /* FE */ + { 0xFF, 0x00 }, /* FF */ +}; + +static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg) +{ + if (reg >= M98095_REG_CNT) + return 0; + return max98095_access[reg].readable != 0; +} + +static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg) +{ + if (reg > M98095_REG_MAX_CACHED) + return 1; + + switch (reg) { + case M98095_000_HOST_DATA: + case M98095_001_HOST_INT_STS: + case M98095_002_HOST_RSP_STS: + case M98095_003_HOST_CMD_STS: + case M98095_004_CODEC_STS: + case M98095_005_DAI1_ALC_STS: + case M98095_006_DAI2_ALC_STS: + case M98095_007_JACK_AUTO_STS: + case M98095_008_JACK_MANUAL_STS: + case M98095_009_JACK_VBAT_STS: + case M98095_00A_ACC_ADC_STS: + case M98095_00B_MIC_NG_AGC_STS: + case M98095_00C_SPK_L_VOLT_STS: + case M98095_00D_SPK_R_VOLT_STS: + case M98095_00E_TEMP_SENSOR_STS: + return 1; + } + + return 0; +} + +static const char * const max98095_fltr_mode[] = { "Voice", "Music" }; +static const struct soc_enum max98095_dai1_filter_mode_enum[] = { + SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode), +}; +static const struct soc_enum max98095_dai2_filter_mode_enum[] = { + SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode), +}; + +static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" }; + +static const struct soc_enum max98095_extmic_enum = + SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text); + +static const struct snd_kcontrol_new max98095_extmic_mux = + SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum); + +static const char * const max98095_linein_text[] = { "INA", "INB" }; + +static const struct soc_enum max98095_linein_enum = + SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text); + +static const struct snd_kcontrol_new max98095_linein_mux = + SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum); + +static const char * const max98095_line_mode_text[] = { + "Stereo", "Differential"}; + +static const struct soc_enum max98095_linein_mode_enum = + SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text); + +static const struct soc_enum max98095_lineout_mode_enum = + SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text); + +static const char * const max98095_dai_fltr[] = { + "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k", + "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"}; +static const struct soc_enum max98095_dai1_dac_filter_enum[] = { + SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr), +}; +static const struct soc_enum max98095_dai2_dac_filter_enum[] = { + SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr), +}; +static const struct soc_enum max98095_dai3_dac_filter_enum[] = { + SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr), +}; + +static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + unsigned int sel = ucontrol->value.integer.value[0]; + + max98095->mic1pre = sel; + snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK, + (1+sel)<value.integer.value[0] = max98095->mic1pre; + return 0; +} + +static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + unsigned int sel = ucontrol->value.integer.value[0]; + + max98095->mic2pre = sel; + snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK, + (1+sel)<value.integer.value[0] = max98095->mic2pre; + return 0; +} + +static const unsigned int max98095_micboost_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), + 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), +}; + +static const DECLARE_TLV_DB_SCALE(max98095_mic_tlv, 0, 100, 0); +static const DECLARE_TLV_DB_SCALE(max98095_adc_tlv, -1200, 100, 0); +static const DECLARE_TLV_DB_SCALE(max98095_adcboost_tlv, 0, 600, 0); + +static const unsigned int max98095_hp_tlv[] = { + TLV_DB_RANGE_HEAD(5), + 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0), + 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0), + 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0), + 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0), + 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0), +}; + +static const unsigned int max98095_spk_tlv[] = { + TLV_DB_RANGE_HEAD(4), + 0, 10, TLV_DB_SCALE_ITEM(-5900, 400, 0), + 11, 18, TLV_DB_SCALE_ITEM(-1700, 200, 0), + 19, 27, TLV_DB_SCALE_ITEM(-200, 100, 0), + 28, 39, TLV_DB_SCALE_ITEM(650, 50, 0), +}; + +static const unsigned int max98095_rcv_lout_tlv[] = { + TLV_DB_RANGE_HEAD(5), + 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0), + 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0), + 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0), + 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0), + 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0), +}; + +static const unsigned int max98095_lin_tlv[] = { + TLV_DB_RANGE_HEAD(3), + 0, 2, TLV_DB_SCALE_ITEM(-600, 300, 0), + 3, 3, TLV_DB_SCALE_ITEM(300, 1100, 0), + 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0), +}; + +static const struct snd_kcontrol_new max98095_snd_controls[] = { + + SOC_DOUBLE_R_TLV("Headphone Volume", M98095_064_LVL_HP_L, + M98095_065_LVL_HP_R, 0, 31, 0, max98095_hp_tlv), + + SOC_DOUBLE_R_TLV("Speaker Volume", M98095_067_LVL_SPK_L, + M98095_068_LVL_SPK_R, 0, 39, 0, max98095_spk_tlv), + + SOC_SINGLE_TLV("Receiver Volume", M98095_066_LVL_RCV, + 0, 31, 0, max98095_rcv_lout_tlv), + + SOC_DOUBLE_R_TLV("Lineout Volume", M98095_062_LVL_LINEOUT1, + M98095_063_LVL_LINEOUT2, 0, 31, 0, max98095_rcv_lout_tlv), + + SOC_DOUBLE_R("Headphone Switch", M98095_064_LVL_HP_L, + M98095_065_LVL_HP_R, 7, 1, 1), + + SOC_DOUBLE_R("Speaker Switch", M98095_067_LVL_SPK_L, + M98095_068_LVL_SPK_R, 7, 1, 1), + + SOC_SINGLE("Receiver Switch", M98095_066_LVL_RCV, 7, 1, 1), + + SOC_DOUBLE_R("Lineout Switch", M98095_062_LVL_LINEOUT1, + M98095_063_LVL_LINEOUT2, 7, 1, 1), + + SOC_SINGLE_TLV("MIC1 Volume", M98095_05F_LVL_MIC1, 0, 20, 1, + max98095_mic_tlv), + + SOC_SINGLE_TLV("MIC2 Volume", M98095_060_LVL_MIC2, 0, 20, 1, + max98095_mic_tlv), + + SOC_SINGLE_EXT_TLV("MIC1 Boost Volume", + M98095_05F_LVL_MIC1, 5, 2, 0, + max98095_mic1pre_get, max98095_mic1pre_set, + max98095_micboost_tlv), + SOC_SINGLE_EXT_TLV("MIC2 Boost Volume", + M98095_060_LVL_MIC2, 5, 2, 0, + max98095_mic2pre_get, max98095_mic2pre_set, + max98095_micboost_tlv), + + SOC_SINGLE_TLV("Linein Volume", M98095_061_LVL_LINEIN, 0, 5, 1, + max98095_lin_tlv), + + SOC_SINGLE_TLV("ADCL Volume", M98095_05D_LVL_ADC_L, 0, 15, 1, + max98095_adc_tlv), + SOC_SINGLE_TLV("ADCR Volume", M98095_05E_LVL_ADC_R, 0, 15, 1, + max98095_adc_tlv), + + SOC_SINGLE_TLV("ADCL Boost Volume", M98095_05D_LVL_ADC_L, 4, 3, 0, + max98095_adcboost_tlv), + SOC_SINGLE_TLV("ADCR Boost Volume", M98095_05E_LVL_ADC_R, 4, 3, 0, + max98095_adcboost_tlv), + + SOC_ENUM("DAI1 Filter Mode", max98095_dai1_filter_mode_enum), + SOC_ENUM("DAI2 Filter Mode", max98095_dai2_filter_mode_enum), + SOC_ENUM("DAI1 DAC Filter", max98095_dai1_dac_filter_enum), + SOC_ENUM("DAI2 DAC Filter", max98095_dai2_dac_filter_enum), + SOC_ENUM("DAI3 DAC Filter", max98095_dai3_dac_filter_enum), + + SOC_ENUM("Linein Mode", max98095_linein_mode_enum), + SOC_ENUM("Lineout Mode", max98095_lineout_mode_enum), +}; + +/* Left speaker mixer switch */ +static const struct snd_kcontrol_new max98095_left_speaker_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_050_MIX_SPK_LEFT, 0, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_050_MIX_SPK_LEFT, 6, 1, 0), + SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0), + SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_050_MIX_SPK_LEFT, 4, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_050_MIX_SPK_LEFT, 5, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_050_MIX_SPK_LEFT, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_050_MIX_SPK_LEFT, 2, 1, 0), +}; + +/* Right speaker mixer switch */ +static const struct snd_kcontrol_new max98095_right_speaker_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 6, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 0, 1, 0), + SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0), + SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_051_MIX_SPK_RIGHT, 5, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_051_MIX_SPK_RIGHT, 4, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_051_MIX_SPK_RIGHT, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_051_MIX_SPK_RIGHT, 2, 1, 0), +}; + +/* Left headphone mixer switch */ +static const struct snd_kcontrol_new max98095_left_hp_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04C_MIX_HP_LEFT, 0, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04C_MIX_HP_LEFT, 5, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_04C_MIX_HP_LEFT, 3, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_04C_MIX_HP_LEFT, 4, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_04C_MIX_HP_LEFT, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_04C_MIX_HP_LEFT, 2, 1, 0), +}; + +/* Right headphone mixer switch */ +static const struct snd_kcontrol_new max98095_right_hp_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 5, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 0, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_04D_MIX_HP_RIGHT, 3, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_04D_MIX_HP_RIGHT, 4, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_04D_MIX_HP_RIGHT, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_04D_MIX_HP_RIGHT, 2, 1, 0), +}; + +/* Receiver earpiece mixer switch */ +static const struct snd_kcontrol_new max98095_mono_rcv_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04F_MIX_RCV, 0, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04F_MIX_RCV, 5, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_04F_MIX_RCV, 3, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_04F_MIX_RCV, 4, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_04F_MIX_RCV, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_04F_MIX_RCV, 2, 1, 0), +}; + +/* Left lineout mixer switch */ +static const struct snd_kcontrol_new max98095_left_lineout_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_053_MIX_LINEOUT1, 5, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_053_MIX_LINEOUT1, 0, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_053_MIX_LINEOUT1, 3, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_053_MIX_LINEOUT1, 4, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_053_MIX_LINEOUT1, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_053_MIX_LINEOUT1, 2, 1, 0), +}; + +/* Right lineout mixer switch */ +static const struct snd_kcontrol_new max98095_right_lineout_mixer_controls[] = { + SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_054_MIX_LINEOUT2, 0, 1, 0), + SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_054_MIX_LINEOUT2, 5, 1, 0), + SOC_DAPM_SINGLE("MIC1 Switch", M98095_054_MIX_LINEOUT2, 3, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_054_MIX_LINEOUT2, 4, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_054_MIX_LINEOUT2, 1, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_054_MIX_LINEOUT2, 2, 1, 0), +}; + +/* Left ADC mixer switch */ +static const struct snd_kcontrol_new max98095_left_ADC_mixer_controls[] = { + SOC_DAPM_SINGLE("MIC1 Switch", M98095_04A_MIX_ADC_LEFT, 7, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_04A_MIX_ADC_LEFT, 6, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_04A_MIX_ADC_LEFT, 3, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_04A_MIX_ADC_LEFT, 2, 1, 0), +}; + +/* Right ADC mixer switch */ +static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = { + SOC_DAPM_SINGLE("MIC1 Switch", M98095_04B_MIX_ADC_RIGHT, 7, 1, 0), + SOC_DAPM_SINGLE("MIC2 Switch", M98095_04B_MIX_ADC_RIGHT, 6, 1, 0), + SOC_DAPM_SINGLE("IN1 Switch", M98095_04B_MIX_ADC_RIGHT, 3, 1, 0), + SOC_DAPM_SINGLE("IN2 Switch", M98095_04B_MIX_ADC_RIGHT, 2, 1, 0), +}; + +static int max98095_mic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (w->reg == M98095_05F_LVL_MIC1) { + snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, + (1+max98095->mic1pre)<reg, M98095_MICPRE_MASK, + (1+max98095->mic2pre)<reg, M98095_MICPRE_MASK, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * The line inputs are stereo inputs with the left and right + * channels sharing a common PGA power control signal. + */ +static int max98095_line_pga(struct snd_soc_dapm_widget *w, + int event, u8 channel) +{ + struct snd_soc_codec *codec = w->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + u8 *state; + + BUG_ON(!((channel == 1) || (channel == 2))); + + state = &max98095->lin_state; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + *state |= channel; + snd_soc_update_bits(codec, w->reg, + (1 << w->shift), (1 << w->shift)); + break; + case SND_SOC_DAPM_POST_PMD: + *state &= ~channel; + if (*state == 0) { + snd_soc_update_bits(codec, w->reg, + (1 << w->shift), 0); + } + break; + default: + return -EINVAL; + } + + return 0; +} + +static int max98095_pga_in1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + return max98095_line_pga(w, event, 1); +} + +static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + return max98095_line_pga(w, event, 2); +} + +/* + * The stereo line out mixer outputs to two stereo line outs. + * The 2nd pair has a separate set of enables. + */ +static int max98095_lineout_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, w->reg, + (1 << (w->shift+2)), (1 << (w->shift+2))); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, w->reg, + (1 << (w->shift+2)), 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dapm_widget max98095_dapm_widgets[] = { + + SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98095_090_PWR_EN_IN, 0, 0), + SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98095_090_PWR_EN_IN, 1, 0), + + SND_SOC_DAPM_DAC("DACL1", "HiFi Playback", + M98095_091_PWR_EN_OUT, 0, 0), + SND_SOC_DAPM_DAC("DACR1", "HiFi Playback", + M98095_091_PWR_EN_OUT, 1, 0), + SND_SOC_DAPM_DAC("DACM2", "Aux Playback", + M98095_091_PWR_EN_OUT, 2, 0), + SND_SOC_DAPM_DAC("DACM3", "Voice Playback", + M98095_091_PWR_EN_OUT, 2, 0), + + SND_SOC_DAPM_PGA("HP Left Out", M98095_091_PWR_EN_OUT, + 6, 0, NULL, 0), + SND_SOC_DAPM_PGA("HP Right Out", M98095_091_PWR_EN_OUT, + 7, 0, NULL, 0), + + SND_SOC_DAPM_PGA("SPK Left Out", M98095_091_PWR_EN_OUT, + 4, 0, NULL, 0), + SND_SOC_DAPM_PGA("SPK Right Out", M98095_091_PWR_EN_OUT, + 5, 0, NULL, 0), + + SND_SOC_DAPM_PGA("RCV Mono Out", M98095_091_PWR_EN_OUT, + 3, 0, NULL, 0), + + SND_SOC_DAPM_PGA_E("LINE Left Out", M98095_092_PWR_EN_OUT, + 0, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_E("LINE Right Out", M98095_092_PWR_EN_OUT, + 1, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0, + &max98095_extmic_mux), + + SND_SOC_DAPM_MUX("Linein Mux", SND_SOC_NOPM, 0, 0, + &max98095_linein_mux), + + SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0, + &max98095_left_hp_mixer_controls[0], + ARRAY_SIZE(max98095_left_hp_mixer_controls)), + + SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0, + &max98095_right_hp_mixer_controls[0], + ARRAY_SIZE(max98095_right_hp_mixer_controls)), + + SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0, + &max98095_left_speaker_mixer_controls[0], + ARRAY_SIZE(max98095_left_speaker_mixer_controls)), + + SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0, + &max98095_right_speaker_mixer_controls[0], + ARRAY_SIZE(max98095_right_speaker_mixer_controls)), + + SND_SOC_DAPM_MIXER("Receiver Mixer", SND_SOC_NOPM, 0, 0, + &max98095_mono_rcv_mixer_controls[0], + ARRAY_SIZE(max98095_mono_rcv_mixer_controls)), + + SND_SOC_DAPM_MIXER("Left Lineout Mixer", SND_SOC_NOPM, 0, 0, + &max98095_left_lineout_mixer_controls[0], + ARRAY_SIZE(max98095_left_lineout_mixer_controls)), + + SND_SOC_DAPM_MIXER("Right Lineout Mixer", SND_SOC_NOPM, 0, 0, + &max98095_right_lineout_mixer_controls[0], + ARRAY_SIZE(max98095_right_lineout_mixer_controls)), + + SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0, + &max98095_left_ADC_mixer_controls[0], + ARRAY_SIZE(max98095_left_ADC_mixer_controls)), + + SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0, + &max98095_right_ADC_mixer_controls[0], + ARRAY_SIZE(max98095_right_ADC_mixer_controls)), + + SND_SOC_DAPM_PGA_E("MIC1 Input", M98095_05F_LVL_MIC1, + 5, 0, NULL, 0, max98095_mic_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("MIC2 Input", M98095_060_LVL_MIC2, + 5, 0, NULL, 0, max98095_mic_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("IN1 Input", M98095_090_PWR_EN_IN, + 7, 0, NULL, 0, max98095_pga_in1_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_PGA_E("IN2 Input", M98095_090_PWR_EN_IN, + 7, 0, NULL, 0, max98095_pga_in2_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MICBIAS("MICBIAS1", M98095_090_PWR_EN_IN, 2, 0), + SND_SOC_DAPM_MICBIAS("MICBIAS2", M98095_090_PWR_EN_IN, 3, 0), + + SND_SOC_DAPM_OUTPUT("HPL"), + SND_SOC_DAPM_OUTPUT("HPR"), + SND_SOC_DAPM_OUTPUT("SPKL"), + SND_SOC_DAPM_OUTPUT("SPKR"), + SND_SOC_DAPM_OUTPUT("RCV"), + SND_SOC_DAPM_OUTPUT("OUT1"), + SND_SOC_DAPM_OUTPUT("OUT2"), + SND_SOC_DAPM_OUTPUT("OUT3"), + SND_SOC_DAPM_OUTPUT("OUT4"), + + SND_SOC_DAPM_INPUT("MIC1"), + SND_SOC_DAPM_INPUT("MIC2"), + SND_SOC_DAPM_INPUT("INA1"), + SND_SOC_DAPM_INPUT("INA2"), + SND_SOC_DAPM_INPUT("INB1"), + SND_SOC_DAPM_INPUT("INB2"), +}; + +static const struct snd_soc_dapm_route max98095_audio_map[] = { + /* Left headphone output mixer */ + {"Left Headphone Mixer", "Left DAC1 Switch", "DACL1"}, + {"Left Headphone Mixer", "Right DAC1 Switch", "DACR1"}, + {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Left Headphone Mixer", "IN1 Switch", "IN1 Input"}, + {"Left Headphone Mixer", "IN2 Switch", "IN2 Input"}, + + /* Right headphone output mixer */ + {"Right Headphone Mixer", "Left DAC1 Switch", "DACL1"}, + {"Right Headphone Mixer", "Right DAC1 Switch", "DACR1"}, + {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Right Headphone Mixer", "IN1 Switch", "IN1 Input"}, + {"Right Headphone Mixer", "IN2 Switch", "IN2 Input"}, + + /* Left speaker output mixer */ + {"Left Speaker Mixer", "Left DAC1 Switch", "DACL1"}, + {"Left Speaker Mixer", "Right DAC1 Switch", "DACR1"}, + {"Left Speaker Mixer", "Mono DAC2 Switch", "DACM2"}, + {"Left Speaker Mixer", "Mono DAC3 Switch", "DACM3"}, + {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Left Speaker Mixer", "IN1 Switch", "IN1 Input"}, + {"Left Speaker Mixer", "IN2 Switch", "IN2 Input"}, + + /* Right speaker output mixer */ + {"Right Speaker Mixer", "Left DAC1 Switch", "DACL1"}, + {"Right Speaker Mixer", "Right DAC1 Switch", "DACR1"}, + {"Right Speaker Mixer", "Mono DAC2 Switch", "DACM2"}, + {"Right Speaker Mixer", "Mono DAC3 Switch", "DACM3"}, + {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Right Speaker Mixer", "IN1 Switch", "IN1 Input"}, + {"Right Speaker Mixer", "IN2 Switch", "IN2 Input"}, + + /* Earpiece/Receiver output mixer */ + {"Receiver Mixer", "Left DAC1 Switch", "DACL1"}, + {"Receiver Mixer", "Right DAC1 Switch", "DACR1"}, + {"Receiver Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Receiver Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Receiver Mixer", "IN1 Switch", "IN1 Input"}, + {"Receiver Mixer", "IN2 Switch", "IN2 Input"}, + + /* Left Lineout output mixer */ + {"Left Lineout Mixer", "Left DAC1 Switch", "DACL1"}, + {"Left Lineout Mixer", "Right DAC1 Switch", "DACR1"}, + {"Left Lineout Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Left Lineout Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Left Lineout Mixer", "IN1 Switch", "IN1 Input"}, + {"Left Lineout Mixer", "IN2 Switch", "IN2 Input"}, + + /* Right lineout output mixer */ + {"Right Lineout Mixer", "Left DAC1 Switch", "DACL1"}, + {"Right Lineout Mixer", "Right DAC1 Switch", "DACR1"}, + {"Right Lineout Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Right Lineout Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Right Lineout Mixer", "IN1 Switch", "IN1 Input"}, + {"Right Lineout Mixer", "IN2 Switch", "IN2 Input"}, + + {"HP Left Out", NULL, "Left Headphone Mixer"}, + {"HP Right Out", NULL, "Right Headphone Mixer"}, + {"SPK Left Out", NULL, "Left Speaker Mixer"}, + {"SPK Right Out", NULL, "Right Speaker Mixer"}, + {"RCV Mono Out", NULL, "Receiver Mixer"}, + {"LINE Left Out", NULL, "Left Lineout Mixer"}, + {"LINE Right Out", NULL, "Right Lineout Mixer"}, + + {"HPL", NULL, "HP Left Out"}, + {"HPR", NULL, "HP Right Out"}, + {"SPKL", NULL, "SPK Left Out"}, + {"SPKR", NULL, "SPK Right Out"}, + {"RCV", NULL, "RCV Mono Out"}, + {"OUT1", NULL, "LINE Left Out"}, + {"OUT2", NULL, "LINE Right Out"}, + {"OUT3", NULL, "LINE Left Out"}, + {"OUT4", NULL, "LINE Right Out"}, + + /* Left ADC input mixer */ + {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Left ADC Mixer", "IN1 Switch", "IN1 Input"}, + {"Left ADC Mixer", "IN2 Switch", "IN2 Input"}, + + /* Right ADC input mixer */ + {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"}, + {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"}, + {"Right ADC Mixer", "IN1 Switch", "IN1 Input"}, + {"Right ADC Mixer", "IN2 Switch", "IN2 Input"}, + + /* Inputs */ + {"ADCL", NULL, "Left ADC Mixer"}, + {"ADCR", NULL, "Right ADC Mixer"}, + + {"IN1 Input", NULL, "INA1"}, + {"IN2 Input", NULL, "INA2"}, + + {"MIC1 Input", NULL, "MIC1"}, + {"MIC2 Input", NULL, "MIC2"}, +}; + +static int max98095_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_add_controls(codec, max98095_snd_controls, + ARRAY_SIZE(max98095_snd_controls)); + + return 0; +} + +/* codec mclk clock divider coefficients */ +static const struct { + u32 rate; + u8 sr; +} rate_table[] = { + {8000, 0x01}, + {11025, 0x02}, + {16000, 0x03}, + {22050, 0x04}, + {24000, 0x05}, + {32000, 0x06}, + {44100, 0x07}, + {48000, 0x08}, + {88200, 0x09}, + {96000, 0x0A}, +}; + +static int rate_value(int rate, u8 *value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(rate_table); i++) { + if (rate_table[i].rate >= rate) { + *value = rate_table[i].sr; + return 0; + } + } + *value = rate_table[0].sr; + return -EINVAL; +} + +static int max98095_dai1_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + unsigned long long ni; + unsigned int rate; + u8 regval; + + cdata = &max98095->dai[0]; + + rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, + M98095_DAI_WS, 0); + break; + case SNDRV_PCM_FORMAT_S24_LE: + snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, + M98095_DAI_WS, M98095_DAI_WS); + break; + default: + return -EINVAL; + } + + if (rate_value(rate, ®val)) + return -EINVAL; + + snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE, + M98095_CLKMODE_MASK, regval); + cdata->rate = rate; + + /* Configure NI when operating as master */ + if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) { + if (max98095->sysclk == 0) { + dev_err(codec->dev, "Invalid system clock frequency\n"); + return -EINVAL; + } + ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) + * (unsigned long long int)rate; + do_div(ni, (unsigned long long int)max98095->sysclk); + snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI, + (ni >> 8) & 0x7F); + snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO, + ni & 0xFF); + } + + /* Update sample rate mode */ + if (rate < 50000) + snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS, + M98095_DAI_DHF, 0); + else + snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS, + M98095_DAI_DHF, M98095_DAI_DHF); + + return 0; +} + +static int max98095_dai2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + unsigned long long ni; + unsigned int rate; + u8 regval; + + cdata = &max98095->dai[1]; + + rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT, + M98095_DAI_WS, 0); + break; + case SNDRV_PCM_FORMAT_S24_LE: + snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT, + M98095_DAI_WS, M98095_DAI_WS); + break; + default: + return -EINVAL; + } + + if (rate_value(rate, ®val)) + return -EINVAL; + + snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE, + M98095_CLKMODE_MASK, regval); + cdata->rate = rate; + + /* Configure NI when operating as master */ + if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) { + if (max98095->sysclk == 0) { + dev_err(codec->dev, "Invalid system clock frequency\n"); + return -EINVAL; + } + ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) + * (unsigned long long int)rate; + do_div(ni, (unsigned long long int)max98095->sysclk); + snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI, + (ni >> 8) & 0x7F); + snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO, + ni & 0xFF); + } + + /* Update sample rate mode */ + if (rate < 50000) + snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS, + M98095_DAI_DHF, 0); + else + snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS, + M98095_DAI_DHF, M98095_DAI_DHF); + + return 0; +} + +static int max98095_dai3_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + unsigned long long ni; + unsigned int rate; + u8 regval; + + cdata = &max98095->dai[2]; + + rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT, + M98095_DAI_WS, 0); + break; + case SNDRV_PCM_FORMAT_S24_LE: + snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT, + M98095_DAI_WS, M98095_DAI_WS); + break; + default: + return -EINVAL; + } + + if (rate_value(rate, ®val)) + return -EINVAL; + + snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE, + M98095_CLKMODE_MASK, regval); + cdata->rate = rate; + + /* Configure NI when operating as master */ + if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) { + if (max98095->sysclk == 0) { + dev_err(codec->dev, "Invalid system clock frequency\n"); + return -EINVAL; + } + ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) + * (unsigned long long int)rate; + do_div(ni, (unsigned long long int)max98095->sysclk); + snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI, + (ni >> 8) & 0x7F); + snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO, + ni & 0xFF); + } + + /* Update sample rate mode */ + if (rate < 50000) + snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS, + M98095_DAI_DHF, 0); + else + snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS, + M98095_DAI_DHF, M98095_DAI_DHF); + + return 0; +} + +static int max98095_dai_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + + /* Requested clock frequency is already setup */ + if (freq == max98095->sysclk) + return 0; + + max98095->sysclk = freq; /* remember current sysclk */ + + /* Setup clocks for slave mode, and using the PLL + * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) + * 0x02 (when master clk is 20MHz to 40MHz).. + * 0x03 (when master clk is 40MHz to 60MHz).. + */ + if ((freq >= 10000000) && (freq < 20000000)) { + snd_soc_write(codec, M98095_026_SYS_CLK, 0x10); + } else if ((freq >= 20000000) && (freq < 40000000)) { + snd_soc_write(codec, M98095_026_SYS_CLK, 0x20); + } else if ((freq >= 40000000) && (freq < 60000000)) { + snd_soc_write(codec, M98095_026_SYS_CLK, 0x30); + } else { + dev_err(codec->dev, "Invalid master clock frequency\n"); + return -EINVAL; + } + + dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq); + + max98095->sysclk = freq; + return 0; +} + +static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + u8 regval = 0; + + cdata = &max98095->dai[0]; + + if (fmt != cdata->fmt) { + cdata->fmt = fmt; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* Slave mode PLL */ + snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI, + 0x80); + snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO, + 0x00); + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* Set to master mode */ + regval |= M98095_DAI_MAS; + break; + case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBM_CFS: + default: + dev_err(codec->dev, "Clock mode unsupported"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + regval |= M98095_DAI_DLY; + break; + case SND_SOC_DAIFMT_LEFT_J: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + regval |= M98095_DAI_WCI; + break; + case SND_SOC_DAIFMT_IB_NF: + regval |= M98095_DAI_BCI; + break; + case SND_SOC_DAIFMT_IB_IF: + regval |= M98095_DAI_BCI|M98095_DAI_WCI; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, + M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI | + M98095_DAI_WCI, regval); + + snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64); + } + + return 0; +} + +static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + u8 regval = 0; + + cdata = &max98095->dai[1]; + + if (fmt != cdata->fmt) { + cdata->fmt = fmt; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* Slave mode PLL */ + snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI, + 0x80); + snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO, + 0x00); + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* Set to master mode */ + regval |= M98095_DAI_MAS; + break; + case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBM_CFS: + default: + dev_err(codec->dev, "Clock mode unsupported"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + regval |= M98095_DAI_DLY; + break; + case SND_SOC_DAIFMT_LEFT_J: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + regval |= M98095_DAI_WCI; + break; + case SND_SOC_DAIFMT_IB_NF: + regval |= M98095_DAI_BCI; + break; + case SND_SOC_DAIFMT_IB_IF: + regval |= M98095_DAI_BCI|M98095_DAI_WCI; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT, + M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI | + M98095_DAI_WCI, regval); + + snd_soc_write(codec, M98095_035_DAI2_CLOCK, + M98095_DAI_BSEL64); + } + + return 0; +} + +static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + u8 regval = 0; + + cdata = &max98095->dai[2]; + + if (fmt != cdata->fmt) { + cdata->fmt = fmt; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* Slave mode PLL */ + snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI, + 0x80); + snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO, + 0x00); + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* Set to master mode */ + regval |= M98095_DAI_MAS; + break; + case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBM_CFS: + default: + dev_err(codec->dev, "Clock mode unsupported"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + regval |= M98095_DAI_DLY; + break; + case SND_SOC_DAIFMT_LEFT_J: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + regval |= M98095_DAI_WCI; + break; + case SND_SOC_DAIFMT_IB_NF: + regval |= M98095_DAI_BCI; + break; + case SND_SOC_DAIFMT_IB_IF: + regval |= M98095_DAI_BCI|M98095_DAI_WCI; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT, + M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI | + M98095_DAI_WCI, regval); + + snd_soc_write(codec, M98095_03F_DAI3_CLOCK, + M98095_DAI_BSEL64); + } + + return 0; +} + +static int max98095_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = snd_soc_cache_sync(codec); + + if (ret != 0) { + dev_err(codec->dev, "Failed to sync cache: %d\n", ret); + return ret; + } + } + + snd_soc_update_bits(codec, M98095_090_PWR_EN_IN, + M98095_MBEN, M98095_MBEN); + break; + + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, M98095_090_PWR_EN_IN, + M98095_MBEN, 0); + codec->cache_sync = 1; + break; + } + codec->dapm.bias_level = level; + return 0; +} + +#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000 +#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +static struct snd_soc_dai_ops max98095_dai1_ops = { + .set_sysclk = max98095_dai_set_sysclk, + .set_fmt = max98095_dai1_set_fmt, + .hw_params = max98095_dai1_hw_params, +}; + +static struct snd_soc_dai_ops max98095_dai2_ops = { + .set_sysclk = max98095_dai_set_sysclk, + .set_fmt = max98095_dai2_set_fmt, + .hw_params = max98095_dai2_hw_params, +}; + +static struct snd_soc_dai_ops max98095_dai3_ops = { + .set_sysclk = max98095_dai_set_sysclk, + .set_fmt = max98095_dai3_set_fmt, + .hw_params = max98095_dai3_hw_params, +}; + +static struct snd_soc_dai_driver max98095_dai[] = { +{ + .name = "HiFi", + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98095_RATES, + .formats = MAX98095_FORMATS, + }, + .capture = { + .stream_name = "HiFi Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MAX98095_RATES, + .formats = MAX98095_FORMATS, + }, + .ops = &max98095_dai1_ops, +}, +{ + .name = "Aux", + .playback = { + .stream_name = "Aux Playback", + .channels_min = 1, + .channels_max = 1, + .rates = MAX98095_RATES, + .formats = MAX98095_FORMATS, + }, + .ops = &max98095_dai2_ops, +}, +{ + .name = "Voice", + .playback = { + .stream_name = "Voice Playback", + .channels_min = 1, + .channels_max = 1, + .rates = MAX98095_RATES, + .formats = MAX98095_FORMATS, + }, + .ops = &max98095_dai3_ops, +} + +}; + +static void max98095_handle_pdata(struct snd_soc_codec *codec) +{ + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_pdata *pdata = max98095->pdata; + u8 regval = 0; + + if (!pdata) { + dev_dbg(codec->dev, "No platform data\n"); + return; + } + + /* Configure mic for analog/digital mic mode */ + if (pdata->digmic_left_mode) + regval |= M98095_DIGMIC_L; + + if (pdata->digmic_right_mode) + regval |= M98095_DIGMIC_R; + + snd_soc_write(codec, M98095_087_CFG_MIC, regval); +} + +#ifdef CONFIG_PM +static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state) +{ + max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int max98095_resume(struct snd_soc_codec *codec) +{ + max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + return 0; +} +#else +#define max98095_suspend NULL +#define max98095_resume NULL +#endif + +static int max98095_reset(struct snd_soc_codec *codec) +{ + int i, ret; + + /* Gracefully reset the DSP core and the codec hardware + * in a proper sequence */ + ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0); + if (ret < 0) { + dev_err(codec->dev, "Failed to reset DSP: %d\n", ret); + return ret; + } + + ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0); + if (ret < 0) { + dev_err(codec->dev, "Failed to reset codec: %d\n", ret); + return ret; + } + + /* Reset to hardware default for registers, as there is not + * a soft reset hardware control register */ + for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) { + ret = snd_soc_write(codec, i, max98095_reg_def[i]); + if (ret < 0) { + dev_err(codec->dev, "Failed to reset: %d\n", ret); + return ret; + } + } + + return ret; +} + +static int max98095_probe(struct snd_soc_codec *codec) +{ + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); + struct max98095_cdata *cdata; + int ret = 0; + + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + /* reset the codec, the DSP core, and disable all interrupts */ + max98095_reset(codec); + + /* initialize private data */ + + max98095->sysclk = (unsigned)-1; + + cdata = &max98095->dai[0]; + cdata->rate = (unsigned)-1; + cdata->fmt = (unsigned)-1; + + cdata = &max98095->dai[1]; + cdata->rate = (unsigned)-1; + cdata->fmt = (unsigned)-1; + + cdata = &max98095->dai[2]; + cdata->rate = (unsigned)-1; + cdata->fmt = (unsigned)-1; + + max98095->lin_state = 0; + max98095->mic1pre = 0; + max98095->mic2pre = 0; + + ret = snd_soc_read(codec, M98095_0FF_REV_ID); + if (ret < 0) { + dev_err(codec->dev, "Failed to read device revision: %d\n", + ret); + goto err_access; + } + dev_info(codec->dev, "revision %c\n", ret + 'A'); + + snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV); + + /* initialize registers cache to hardware default */ + max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + snd_soc_write(codec, M98095_048_MIX_DAC_LR, + M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR); + + snd_soc_write(codec, M98095_049_MIX_DAC_M, + M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM); + + snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM); + snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL); + snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL); + + snd_soc_write(codec, M98095_02C_DAI1_IOCFG, + M98095_S1NORMAL|M98095_SDATA); + + snd_soc_write(codec, M98095_036_DAI2_IOCFG, + M98095_S2NORMAL|M98095_SDATA); + + snd_soc_write(codec, M98095_040_DAI3_IOCFG, + M98095_S3NORMAL|M98095_SDATA); + + max98095_handle_pdata(codec); + + /* take the codec out of the shut down */ + snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN, + M98095_SHDNRUN); + + max98095_add_widgets(codec); + +err_access: + return ret; +} + +static int max98095_remove(struct snd_soc_codec *codec) +{ + max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_max98095 = { + .probe = max98095_probe, + .remove = max98095_remove, + .suspend = max98095_suspend, + .resume = max98095_resume, + .set_bias_level = max98095_set_bias_level, + .reg_cache_size = ARRAY_SIZE(max98095_reg_def), + .reg_word_size = sizeof(u8), + .reg_cache_default = max98095_reg_def, + .readable_register = max98095_readable, + .volatile_register = max98095_volatile, + .dapm_widgets = max98095_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets), + .dapm_routes = max98095_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98095_audio_map), +}; + +static int max98095_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct max98095_priv *max98095; + int ret; + + max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL); + if (max98095 == NULL) + return -ENOMEM; + + max98095->devtype = id->driver_data; + i2c_set_clientdata(i2c, max98095); + max98095->control_data = i2c; + max98095->pdata = i2c->dev.platform_data; + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_max98095, &max98095_dai[0], 3); + if (ret < 0) + kfree(max98095); + return ret; +} + +static int __devexit max98095_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id max98095_i2c_id[] = { + { "max98095", MAX98095 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max98095_i2c_id); + +static struct i2c_driver max98095_i2c_driver = { + .driver = { + .name = "max98095", + .owner = THIS_MODULE, + }, + .probe = max98095_i2c_probe, + .remove = __devexit_p(max98095_i2c_remove), + .id_table = max98095_i2c_id, +}; + +static int __init max98095_init(void) +{ + int ret; + + ret = i2c_add_driver(&max98095_i2c_driver); + if (ret) + pr_err("Failed to register max98095 I2C driver: %d\n", ret); + + return ret; +} +module_init(max98095_init); + +static void __exit max98095_exit(void) +{ + i2c_del_driver(&max98095_i2c_driver); +} +module_exit(max98095_exit); + +MODULE_DESCRIPTION("ALSA SoC MAX98095 driver"); +MODULE_AUTHOR("Peter Hsiang"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h new file mode 100644 index 000000000000..5b22bc8dbede --- /dev/null +++ b/sound/soc/codecs/max98095.h @@ -0,0 +1,284 @@ +/* + * max98095.h -- MAX98095 ALSA SoC Audio driver + * + * Copyright 2011 Maxim Integrated Products + * + * 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 _MAX98095_H +#define _MAX98095_H + +/* + * MAX98095 Registers Definition + */ + +#define M98095_000_HOST_DATA 0x00 +#define M98095_001_HOST_INT_STS 0x01 +#define M98095_002_HOST_RSP_STS 0x02 +#define M98095_003_HOST_CMD_STS 0x03 +#define M98095_004_CODEC_STS 0x04 +#define M98095_005_DAI1_ALC_STS 0x05 +#define M98095_006_DAI2_ALC_STS 0x06 +#define M98095_007_JACK_AUTO_STS 0x07 +#define M98095_008_JACK_MANUAL_STS 0x08 +#define M98095_009_JACK_VBAT_STS 0x09 +#define M98095_00A_ACC_ADC_STS 0x0A +#define M98095_00B_MIC_NG_AGC_STS 0x0B +#define M98095_00C_SPK_L_VOLT_STS 0x0C +#define M98095_00D_SPK_R_VOLT_STS 0x0D +#define M98095_00E_TEMP_SENSOR_STS 0x0E +#define M98095_00F_HOST_CFG 0x0F +#define M98095_010_HOST_INT_CFG 0x10 +#define M98095_011_HOST_INT_EN 0x11 +#define M98095_012_CODEC_INT_EN 0x12 +#define M98095_013_JACK_INT_EN 0x13 +#define M98095_014_JACK_INT_EN 0x14 +#define M98095_015_DEC 0x15 +#define M98095_016_RESERVED 0x16 +#define M98095_017_RESERVED 0x17 +#define M98095_018_KEYCODE3 0x18 +#define M98095_019_KEYCODE2 0x19 +#define M98095_01A_KEYCODE1 0x1A +#define M98095_01B_KEYCODE0 0x1B +#define M98095_01C_OEMCODE1 0x1C +#define M98095_01D_OEMCODE0 0x1D +#define M98095_01E_XCFG1 0x1E +#define M98095_01F_XCFG2 0x1F +#define M98095_020_XCFG3 0x20 +#define M98095_021_XCFG4 0x21 +#define M98095_022_XCFG5 0x22 +#define M98095_023_XCFG6 0x23 +#define M98095_024_XGPIO 0x24 +#define M98095_025_XCLKCFG 0x25 +#define M98095_026_SYS_CLK 0x26 +#define M98095_027_DAI1_CLKMODE 0x27 +#define M98095_028_DAI1_CLKCFG_HI 0x28 +#define M98095_029_DAI1_CLKCFG_LO 0x29 +#define M98095_02A_DAI1_FORMAT 0x2A +#define M98095_02B_DAI1_CLOCK 0x2B +#define M98095_02C_DAI1_IOCFG 0x2C +#define M98095_02D_DAI1_TDM 0x2D +#define M98095_02E_DAI1_FILTERS 0x2E +#define M98095_02F_DAI1_LVL1 0x2F +#define M98095_030_DAI1_LVL2 0x30 +#define M98095_031_DAI2_CLKMODE 0x31 +#define M98095_032_DAI2_CLKCFG_HI 0x32 +#define M98095_033_DAI2_CLKCFG_LO 0x33 +#define M98095_034_DAI2_FORMAT 0x34 +#define M98095_035_DAI2_CLOCK 0x35 +#define M98095_036_DAI2_IOCFG 0x36 +#define M98095_037_DAI2_TDM 0x37 +#define M98095_038_DAI2_FILTERS 0x38 +#define M98095_039_DAI2_LVL1 0x39 +#define M98095_03A_DAI2_LVL2 0x3A +#define M98095_03B_DAI3_CLKMODE 0x3B +#define M98095_03C_DAI3_CLKCFG_HI 0x3C +#define M98095_03D_DAI3_CLKCFG_LO 0x3D +#define M98095_03E_DAI3_FORMAT 0x3E +#define M98095_03F_DAI3_CLOCK 0x3F +#define M98095_040_DAI3_IOCFG 0x40 +#define M98095_041_DAI3_TDM 0x41 +#define M98095_042_DAI3_FILTERS 0x42 +#define M98095_043_DAI3_LVL1 0x43 +#define M98095_044_DAI3_LVL2 0x44 +#define M98095_045_CFG_DSP 0x45 +#define M98095_046_DAC_CTRL1 0x46 +#define M98095_047_DAC_CTRL2 0x47 +#define M98095_048_MIX_DAC_LR 0x48 +#define M98095_049_MIX_DAC_M 0x49 +#define M98095_04A_MIX_ADC_LEFT 0x4A +#define M98095_04B_MIX_ADC_RIGHT 0x4B +#define M98095_04C_MIX_HP_LEFT 0x4C +#define M98095_04D_MIX_HP_RIGHT 0x4D +#define M98095_04E_CFG_HP 0x4E +#define M98095_04F_MIX_RCV 0x4F +#define M98095_050_MIX_SPK_LEFT 0x50 +#define M98095_051_MIX_SPK_RIGHT 0x51 +#define M98095_052_MIX_SPK_CFG 0x52 +#define M98095_053_MIX_LINEOUT1 0x53 +#define M98095_054_MIX_LINEOUT2 0x54 +#define M98095_055_MIX_LINEOUT_CFG 0x55 +#define M98095_056_LVL_SIDETONE_DAI12 0x56 +#define M98095_057_LVL_SIDETONE_DAI3 0x57 +#define M98095_058_LVL_DAI1_PLAY 0x58 +#define M98095_059_LVL_DAI1_EQ 0x59 +#define M98095_05A_LVL_DAI2_PLAY 0x5A +#define M98095_05B_LVL_DAI2_EQ 0x5B +#define M98095_05C_LVL_DAI3_PLAY 0x5C +#define M98095_05D_LVL_ADC_L 0x5D +#define M98095_05E_LVL_ADC_R 0x5E +#define M98095_05F_LVL_MIC1 0x5F +#define M98095_060_LVL_MIC2 0x60 +#define M98095_061_LVL_LINEIN 0x61 +#define M98095_062_LVL_LINEOUT1 0x62 +#define M98095_063_LVL_LINEOUT2 0x63 +#define M98095_064_LVL_HP_L 0x64 +#define M98095_065_LVL_HP_R 0x65 +#define M98095_066_LVL_RCV 0x66 +#define M98095_067_LVL_SPK_L 0x67 +#define M98095_068_LVL_SPK_R 0x68 +#define M98095_069_MICAGC_CFG 0x69 +#define M98095_06A_MICAGC_THRESH 0x6A +#define M98095_06B_SPK_NOISEGATE 0x6B +#define M98095_06C_DAI1_ALC1_TIME 0x6C +#define M98095_06D_DAI1_ALC1_COMP 0x6D +#define M98095_06E_DAI1_ALC1_EXPN 0x6E +#define M98095_06F_DAI1_ALC1_GAIN 0x6F +#define M98095_070_DAI1_ALC2_TIME 0x70 +#define M98095_071_DAI1_ALC2_COMP 0x71 +#define M98095_072_DAI1_ALC2_EXPN 0x72 +#define M98095_073_DAI1_ALC2_GAIN 0x73 +#define M98095_074_DAI1_ALC3_TIME 0x74 +#define M98095_075_DAI1_ALC3_COMP 0x75 +#define M98095_076_DAI1_ALC3_EXPN 0x76 +#define M98095_077_DAI1_ALC3_GAIN 0x77 +#define M98095_078_DAI2_ALC1_TIME 0x78 +#define M98095_079_DAI2_ALC1_COMP 0x79 +#define M98095_07A_DAI2_ALC1_EXPN 0x7A +#define M98095_07B_DAI2_ALC1_GAIN 0x7B +#define M98095_07C_DAI2_ALC2_TIME 0x7C +#define M98095_07D_DAI2_ALC2_COMP 0x7D +#define M98095_07E_DAI2_ALC2_EXPN 0x7E +#define M98095_07F_DAI2_ALC2_GAIN 0x7F +#define M98095_080_DAI2_ALC3_TIME 0x80 +#define M98095_081_DAI2_ALC3_COMP 0x81 +#define M98095_082_DAI2_ALC3_EXPN 0x82 +#define M98095_083_DAI2_ALC3_GAIN 0x83 +#define M98095_084_HP_NOISE_GATE 0x84 +#define M98095_085_AUX_ADC 0x85 +#define M98095_086_CFG_LINE 0x86 +#define M98095_087_CFG_MIC 0x87 +#define M98095_088_CFG_LEVEL 0x88 +#define M98095_089_JACK_DET_AUTO 0x89 +#define M98095_08A_JACK_DET_MANUAL 0x8A +#define M98095_08B_JACK_KEYSCAN_DBC 0x8B +#define M98095_08C_JACK_KEYSCAN_DLY 0x8C +#define M98095_08D_JACK_KEY_THRESH 0x8D +#define M98095_08E_JACK_DC_SLEW 0x8E +#define M98095_08F_JACK_TEST_CFG 0x8F +#define M98095_090_PWR_EN_IN 0x90 +#define M98095_091_PWR_EN_OUT 0x91 +#define M98095_092_PWR_EN_OUT 0x92 +#define M98095_093_BIAS_CTRL 0x93 +#define M98095_094_PWR_DAC_21 0x94 +#define M98095_095_PWR_DAC_03 0x95 +#define M98095_096_PWR_DAC_CK 0x96 +#define M98095_097_PWR_SYS 0x97 + +#define M98095_0FF_REV_ID 0xFF + +#define M98095_REG_CNT (0xFF+1) +#define M98095_REG_MAX_CACHED 0X97 + +/* MAX98095 Registers Bit Fields */ + +/* M98095_00F_HOST_CFG */ + #define M98095_SEG (1<<0) + #define M98095_XTEN (1<<1) + #define M98095_MDLLEN (1<<2) + +/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */ + #define M98095_CLKMODE_MASK 0xFF + +/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */ + #define M98095_DAI_MAS (1<<7) + #define M98095_DAI_WCI (1<<6) + #define M98095_DAI_BCI (1<<5) + #define M98095_DAI_DLY (1<<4) + #define M98095_DAI_TDM (1<<2) + #define M98095_DAI_FSW (1<<1) + #define M98095_DAI_WS (1<<0) + +/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */ + #define M98095_DAI_BSEL64 (1<<0) + #define M98095_DAI_DOSR_DIV2 (0<<5) + #define M98095_DAI_DOSR_DIV4 (1<<5) + +/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */ + #define M98095_S1NORMAL (1<<6) + #define M98095_S2NORMAL (2<<6) + #define M98095_S3NORMAL (3<<6) + #define M98095_SDATA (3<<0) + +/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */ + #define M98095_DAI_DHF (1<<3) + +/* M98095_045_DSP_CFG */ + #define M98095_DSPNORMAL (5<<4) + +/* M98095_048_MIX_DAC_LR */ + #define M98095_DAI1L_TO_DACR (1<<7) + #define M98095_DAI1R_TO_DACR (1<<6) + #define M98095_DAI2M_TO_DACR (1<<5) + #define M98095_DAI1L_TO_DACL (1<<3) + #define M98095_DAI1R_TO_DACL (1<<2) + #define M98095_DAI2M_TO_DACL (1<<1) + #define M98095_DAI3M_TO_DACL (1<<0) + +/* M98095_049_MIX_DAC_M */ + #define M98095_DAI1L_TO_DACM (1<<3) + #define M98095_DAI1R_TO_DACM (1<<2) + #define M98095_DAI2M_TO_DACM (1<<1) + #define M98095_DAI3M_TO_DACM (1<<0) + +/* M98095_04E_MIX_HP_CFG */ + #define M98095_HPNORMAL (3<<4) + +/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */ + #define M98095_MICPRE_MASK (3<<5) + #define M98095_MICPRE_SHIFT 5 + +/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */ + #define M98095_HP_MUTE (1<<7) + +/* M98095_066_LVL_RCV */ + #define M98095_REC_MUTE (1<<7) + +/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */ + #define M98095_SP_MUTE (1<<7) + +/* M98095_087_CFG_MIC */ + #define M98095_MICSEL_MASK (3<<0) + #define M98095_DIGMIC_L (1<<2) + #define M98095_DIGMIC_R (1<<3) + #define M98095_DIGMIC2L (1<<4) + #define M98095_DIGMIC2R (1<<5) + +/* M98095_088_CFG_LEVEL */ + #define M98095_VSEN (1<<6) + #define M98095_ZDEN (1<<5) + #define M98095_EQ2EN (1<<1) + #define M98095_EQ1EN (1<<0) + +/* M98095_090_PWR_EN_IN */ + #define M98095_INEN (1<<7) + #define M98095_MB2EN (1<<3) + #define M98095_MB1EN (1<<2) + #define M98095_MBEN (3<<2) + #define M98095_ADREN (1<<1) + #define M98095_ADLEN (1<<0) + +/* M98095_091_PWR_EN_OUT */ + #define M98095_HPLEN (1<<7) + #define M98095_HPREN (1<<6) + #define M98095_SPLEN (1<<5) + #define M98095_SPREN (1<<4) + #define M98095_RECEN (1<<3) + #define M98095_DALEN (1<<1) + #define M98095_DAREN (1<<0) + +/* M98095_092_PWR_EN_OUT */ + #define M98095_SPK_FIXEDSPECTRUM (0<<4) + #define M98095_SPK_SPREADSPECTRUM (1<<4) + +/* M98095_097_PWR_SYS */ + #define M98095_SHDNRUN (1<<7) + #define M98095_PERFMODE (1<<3) + #define M98095_HPPLYBACK (1<<2) + #define M98095_PWRSV8K (1<<1) + #define M98095_PWRSV (1<<0) + +#endif -- GitLab From 0d1d7ce95156e0b040f1a4029613716aafd791b1 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 6 Apr 2011 10:20:26 +0800 Subject: [PATCH 0513/5560] ASoC: sst_platform: initialize module_name properly module_name will be checked in register_sst_card. It will fail to register sst card if it's not initialized. Signed-off-by: Lu Guanqun Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index ee2c22475a76..bd9d928dc767 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -247,6 +247,7 @@ static int sst_platform_open(struct snd_pcm_substream *substream) return -ENOMEM; } stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; + stream->sstdrv_ops->module_name = SST_CARD_NAMES; /* registering with SST driver to get access to SST APIs to use */ ret_val = register_sst_card(stream->sstdrv_ops); if (ret_val) { -- GitLab From 83a3fd3cf0bfdadfdfc633f6437f9121e28252b9 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 6 Apr 2011 10:20:32 +0800 Subject: [PATCH 0514/5560] ASoC: sst_platform: free the resources on fail path Signed-off-by: Lu Guanqun Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index bd9d928dc767..848ad3ce732e 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -252,6 +252,8 @@ static int sst_platform_open(struct snd_pcm_substream *substream) ret_val = register_sst_card(stream->sstdrv_ops); if (ret_val) { pr_err("sst: sst card registration failed\n"); + kfree(stream->sstdrv_ops); + kfree(stream); return ret_val; } runtime->private_data = stream; -- GitLab From 0ed625b2f2751c249417bd28694e37ef48eb5fbb Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 6 Apr 2011 10:20:42 +0800 Subject: [PATCH 0515/5560] sst: make register_sst_card more self-contained register_sst_card is used in ASoC code with field `scard_ops` being NULL. Without this patch, there will be NULL dereference. Signed-off-by: Lu Guanqun Signed-off-by: Mark Brown --- drivers/staging/intel_sst/intel_sst_drv_interface.c | 1 - drivers/staging/intel_sst/intelmid.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index ea8e251b5099..cf10dd606638 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -508,7 +508,6 @@ int register_sst_card(struct intel_sst_card_ops *card) sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE; sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/ card->pcm_control = sst_pmic_ops.pcm_control; - sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT; return 0; } else { pr_err("strcmp fail %s\n", card->module_name); diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c index fb2292186703..1fb39d4f98e2 100644 --- a/drivers/staging/intel_sst/intelmid.c +++ b/drivers/staging/intel_sst/intelmid.c @@ -802,6 +802,7 @@ static int __devinit snd_intelmad_sst_register( pr_err("sst card registration failed\n"); return ret_val; } + sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT; sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id; intelmaddata->pmic_status = PMIC_UNINIT; -- GitLab From fb631eae1f2171033327e1b9ab427d4a113dc179 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Wed, 6 Apr 2011 10:20:37 +0800 Subject: [PATCH 0516/5560] ASoC: sst_platform: unregister sst card when being closed Signed-off-by: Lu Guanqun Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 848ad3ce732e..9ba941447d41 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -271,6 +271,7 @@ static int sst_platform_close(struct snd_pcm_substream *substream) str_id = stream->stream_info.str_id; if (str_id) ret_val = stream->sstdrv_ops->pcm_control->close(str_id); + unregister_sst_card(stream->sstdrv_ops); kfree(stream->sstdrv_ops); kfree(stream); return ret_val; -- GitLab From ba1835eb30a80a0e8a1c33724735f3a99a957cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 6 Apr 2011 07:49:04 -0700 Subject: [PATCH 0517/5560] vsprintf: make comment about vs{n,cn,}printf more understandable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "You probably want ... instead." sounds like a recommendation better not to use the v... functions. Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- lib/vsprintf.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index d3023df8477f..bba9caa375d0 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1301,8 +1301,7 @@ int format_decode(const char *fmt, struct printf_spec *spec) * return is greater than or equal to @size, the resulting * string is truncated. * - * Call this function if you are already dealing with a va_list. - * You probably want snprintf() instead. + * If you're not already dealing with a va_list consider using snprintf(). */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { @@ -1476,8 +1475,7 @@ EXPORT_SYMBOL(vsnprintf); * the @buf not including the trailing '\0'. If @size is == 0 the function * returns 0. * - * Call this function if you are already dealing with a va_list. - * You probably want scnprintf() instead. + * If you're not already dealing with a va_list consider using scnprintf(). * * See the vsnprintf() documentation for format string extensions over C99. */ @@ -1556,8 +1554,7 @@ EXPORT_SYMBOL(scnprintf); * into @buf. Use vsnprintf() or vscnprintf() in order to avoid * buffer overflows. * - * Call this function if you are already dealing with a va_list. - * You probably want sprintf() instead. + * If you're not already dealing with a va_list consider using sprintf(). * * See the vsnprintf() documentation for format string extensions over C99. */ -- GitLab From de9f52300d03915846c2baab27332ec462f7f6b0 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:43 +0000 Subject: [PATCH 0518/5560] tg3: Cleanup extended rx ring size code Hardcoded values are used in multiple places to describe the maximum rx ring sizes. This patch replaces those values with preprocessor constants. This patch also introduces a new TG3_FLG3_LRG_PROD_RING_CAP to determine if the device is capable of supporting larger ring sizes. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 37 +++++++++++++++++++------------------ drivers/net/tg3.h | 11 ++++++++--- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b7e03a6ebf25..8ffa5afd4141 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -97,14 +97,12 @@ * them in the NIC onboard memory. */ #define TG3_RX_STD_RING_SIZE(tp) \ - ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \ - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \ - RX_STD_MAX_SIZE_5717 : 512) + ((tp->tg3_flags3 & TG3_FLG3_LRG_PROD_RING_CAP) ? \ + TG3_RX_STD_MAX_SIZE_5717 : TG3_RX_STD_MAX_SIZE_5700) #define TG3_DEF_RX_RING_PENDING 200 #define TG3_RX_JMB_RING_SIZE(tp) \ - ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \ - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \ - 1024 : 256) + ((tp->tg3_flags3 & TG3_FLG3_LRG_PROD_RING_CAP) ? \ + TG3_RX_JMB_MAX_SIZE_5717 : TG3_RX_JMB_MAX_SIZE_5700) #define TG3_DEF_RX_JUMBO_RING_PENDING 100 #define TG3_RSS_INDIR_TBL_SIZE 128 @@ -8115,9 +8113,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) ((u64) tpr->rx_jmb_mapping >> 32)); tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tpr->rx_jmb_mapping & 0xffffffff)); + val = TG3_RX_JMB_RING_SIZE(tp) << + BDINFO_FLAGS_MAXLEN_SHIFT; tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, - (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) | - BDINFO_FLAGS_USE_EXT_RECV); + val | BDINFO_FLAGS_USE_EXT_RECV); if (!(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, @@ -8129,15 +8128,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) - val = RX_STD_MAX_SIZE_5705; + val = TG3_RX_STD_MAX_SIZE_5700; else - val = RX_STD_MAX_SIZE_5717; + val = TG3_RX_STD_MAX_SIZE_5717; val <<= BDINFO_FLAGS_MAXLEN_SHIFT; val |= (TG3_RX_STD_DMA_SZ << 2); } else val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT; } else - val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT; + val = TG3_RX_STD_MAX_SIZE_5700 << BDINFO_FLAGS_MAXLEN_SHIFT; tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val); @@ -8421,8 +8420,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + if (tp->tg3_flags3 & TG3_FLG3_LRG_PROD_RING_CAP) val |= RCVDBDI_MODE_LRG_RING_SZ; tw32(RCVDBDI_MODE, val); tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); @@ -13125,14 +13123,13 @@ static inline void vlan_features_add(struct net_device *dev, unsigned long flags static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) - return 4096; + if (tp->tg3_flags3 & TG3_FLG3_LRG_PROD_RING_CAP) + return TG3_RX_RET_MAX_SIZE_5717; else if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) - return 1024; + return TG3_RX_RET_MAX_SIZE_5700; else - return 512; + return TG3_RX_RET_MAX_SIZE_5705; } static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = { @@ -13430,6 +13427,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG; } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + tp->tg3_flags3 |= TG3_FLG3_LRG_PROD_RING_CAP; + if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 73884b69b749..4c498ed66059 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -25,9 +25,13 @@ #define TG3_RX_INTERNAL_RING_SZ_5906 32 -#define RX_STD_MAX_SIZE_5705 512 -#define RX_STD_MAX_SIZE_5717 2048 -#define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ +#define TG3_RX_STD_MAX_SIZE_5700 512 +#define TG3_RX_STD_MAX_SIZE_5717 2048 +#define TG3_RX_JMB_MAX_SIZE_5700 256 +#define TG3_RX_JMB_MAX_SIZE_5717 1024 +#define TG3_RX_RET_MAX_SIZE_5700 1024 +#define TG3_RX_RET_MAX_SIZE_5705 512 +#define TG3_RX_RET_MAX_SIZE_5717 4096 /* First 256 bytes are a mirror of PCI config space. */ #define TG3PCI_VENDOR 0x00000000 @@ -2897,6 +2901,7 @@ struct tg3 { #define TG3_FLG3_5701_DMA_BUG 0x00000008 #define TG3_FLG3_USE_PHYLIB 0x00000010 #define TG3_FLG3_MDIOBUS_INITED 0x00000020 +#define TG3_FLG3_LRG_PROD_RING_CAP 0x00000080 #define TG3_FLG3_RGMII_INBAND_DISABLE 0x00000100 #define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200 #define TG3_FLG3_RGMII_EXT_IBND_TX_EN 0x00000400 -- GitLab From 1407deb1a99f7ec7ed5b09798b02abea5aa44128 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:44 +0000 Subject: [PATCH 0519/5560] tg3: 5717_PLUS => 57765_PLUS The 57765 arrived before the 5717 and has a subset of the features supported by the 5717. This patch renames the 5717_PLUS flag so that it can be reintroduced to designate only 5717 and later devices. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 42 +++++++++++++++++++++--------------------- drivers/net/tg3.h | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8ffa5afd4141..4f8976bd2b40 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7095,7 +7095,7 @@ static int tg3_chip_reset(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { /* Force PCIe 1.0a mode */ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + !(tp->tg3_flags3 & TG3_FLG3_57765_PLUS) && tr32(TG3_PCIE_PHY_TSTCTL) == (TG3_PCIE_PHY_TSTCTL_PCIE10 | TG3_PCIE_PHY_TSTCTL_PSCRAM)) tw32(TG3_PCIE_PHY_TSTCTL, TG3_PCIE_PHY_TSTCTL_PSCRAM); @@ -7248,7 +7248,7 @@ static int tg3_chip_reset(struct tg3 *tp) if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + !(tp->tg3_flags3 & TG3_FLG3_57765_PLUS)) { val = tr32(0x7c00); tw32(0x7c00, val | (1 << 25)); @@ -7958,7 +7958,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) { val = tr32(TG3PCI_DMA_RW_CTRL) & ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT; if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) @@ -8126,7 +8126,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) BDINFO_FLAGS_DISABLED); } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) val = TG3_RX_STD_MAX_SIZE_5700; else @@ -8147,7 +8147,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->rx_jumbo_pending : 0; tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx); - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) { tw32(STD_REPLENISH_LWM, 32); tw32(JMB_REPLENISH_LWM, 16); } @@ -8218,7 +8218,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + (tp->tg3_flags3 & TG3_FLG3_57765_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 | @@ -8866,7 +8866,7 @@ static int tg3_test_interrupt(struct tg3 *tp) * Turn off MSI one shot mode. Otherwise this test has no * observable way to know whether the interrupt was delivered. */ - if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + if ((tp->tg3_flags3 & TG3_FLG3_57765_PLUS) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); @@ -8909,7 +8909,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (intr_ok) { /* Reenable MSI one shot mode. */ - if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + if ((tp->tg3_flags3 & TG3_FLG3_57765_PLUS) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); @@ -9212,7 +9212,7 @@ static int tg3_open(struct net_device *dev) goto err_out2; } - if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + if (!(tp->tg3_flags3 & TG3_FLG3_57765_PLUS) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { u32 val = tr32(PCIE_TRANSACTION_CFG); @@ -12470,7 +12470,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (cfg2 & (1 << 18)) tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS; - if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) || + if (((tp->tg3_flags3 & TG3_FLG3_57765_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)) @@ -12478,7 +12478,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + !(tp->tg3_flags3 & TG3_FLG3_57765_PLUS)) { u32 cfg3; tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); @@ -13335,7 +13335,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) - tp->tg3_flags3 |= TG3_FLG3_5717_PLUS; + tp->tg3_flags3 |= TG3_FLG3_57765_PLUS; /* Intentionally exclude ASIC_REV_5906 */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || @@ -13344,7 +13344,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) + (tp->tg3_flags3 & TG3_FLG3_57765_PLUS)) tp->tg3_flags3 |= TG3_FLG3_5755_PLUS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || @@ -13376,7 +13376,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* Determine TSO capabilities */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ; /* Do nothing. HW bug. */ - else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + else if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3; else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) @@ -13412,7 +13412,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) { tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX; tp->irq_max = TG3_IRQ_MAX_VECS; } @@ -13431,7 +13431,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) tp->tg3_flags3 |= TG3_FLG3_LRG_PROD_RING_CAP; - if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + if ((tp->tg3_flags3 & TG3_FLG3_57765_PLUS) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG; @@ -13637,7 +13637,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) + (tp->tg3_flags3 & TG3_FLG3_57765_PLUS)) tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; /* Set up tp->grc_local_ctrl before calling tg_power_up(). @@ -13716,7 +13716,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) !(tp->phy_flags & TG3_PHYFLG_IS_FET) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 && - !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + !(tp->tg3_flags3 & TG3_FLG3_57765_PLUS)) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || @@ -14052,7 +14052,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val) #endif #endif - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) { val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT; goto out; } @@ -14269,7 +14269,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl); - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) goto out; if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { @@ -14444,7 +14444,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) static void __devinit tg3_init_bufmgr_config(struct tg3 *tp) { - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) { tp->bufmgr_config.mbuf_read_dma_low_water = DEFAULT_MB_RDMA_LOW_WATER_5705; tp->bufmgr_config.mbuf_mac_rx_low_water = diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 4c498ed66059..6f34db5d7e5e 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2915,7 +2915,7 @@ struct tg3 { #define TG3_FLG3_SHORT_DMA_BUG 0x00200000 #define TG3_FLG3_USE_JUMBO_BDFLAG 0x00400000 #define TG3_FLG3_L1PLLPD_EN 0x00800000 -#define TG3_FLG3_5717_PLUS 0x01000000 +#define TG3_FLG3_57765_PLUS 0x01000000 #define TG3_FLG3_APE_HAS_NCSI 0x02000000 struct timer_list timer; -- GitLab From 0a58d6689bb7c0d49addbf6992aa97234bcfc96c Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:45 +0000 Subject: [PATCH 0520/5560] tg3: Reintroduce 5717_PLUS This patch reintroduces the TG3_FLG3_5717_PLUS to identify 5717 and later devices. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 40 ++++++++++++++++------------------------ drivers/net/tg3.h | 1 + 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4f8976bd2b40..dc6b60b65c0b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1042,8 +1042,7 @@ static int tg3_mdio_init(struct tg3 *tp) u32 reg; struct phy_device *phydev; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { u32 is_serdes; tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1; @@ -1621,8 +1620,7 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable) u32 reg; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || - ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) && + ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && (tp->phy_flags & TG3_PHYFLG_MII_SERDES))) return; @@ -2045,8 +2043,7 @@ static int tg3_phy_reset(struct tg3 *tp) } } - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) && + if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) return 0; @@ -7671,8 +7668,7 @@ static void tg3_rings_reset(struct tg3 *tp) /* Disable all transmit rings but the first. */ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16; - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2; @@ -7686,8 +7682,7 @@ static void tg3_rings_reset(struct tg3 *tp) /* Disable all receive return rings but the first. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17; else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16; @@ -8089,8 +8084,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) ((u64) tpr->rx_std_mapping >> 32)); tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tpr->rx_std_mapping & 0xffffffff)); - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) + if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC); @@ -10848,8 +10842,7 @@ static int tg3_test_memory(struct tg3 *tp) int err = 0; int i; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) mem_tbl = mem_tbl_5717; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) mem_tbl = mem_tbl_57765; @@ -11930,8 +11923,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tg3_get_57780_nvram_info(tp); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) tg3_get_5717_nvram_info(tp); else tg3_get_nvram_info(tp); @@ -13333,8 +13325,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->pdev_peer = tg3_find_peer(tp); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + tp->tg3_flags3 |= TG3_FLG3_5717_PLUS; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 || + (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) tp->tg3_flags3 |= TG3_FLG3_57765_PLUS; /* Intentionally exclude ASIC_REV_5906 */ @@ -13427,8 +13422,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG; } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) tp->tg3_flags3 |= TG3_FLG3_LRG_PROD_RING_CAP; if ((tp->tg3_flags3 & TG3_FLG3_57765_PLUS) && @@ -13962,8 +13956,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) tw32_f(NVRAM_CMD, NVRAM_CMD_RESET); else tg3_nvram_unlock(tp); - } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + } else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { if (PCI_FUNC(tp->pdev->devfn) & 1) mac_offset = 0xcc; if (PCI_FUNC(tp->pdev->devfn) > 1) @@ -14760,8 +14753,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) + !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) dev->netdev_ops = &tg3_netdev_ops; else dev->netdev_ops = &tg3_netdev_ops_dma_bug; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 6f34db5d7e5e..b8e6acc019b4 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2917,6 +2917,7 @@ struct tg3 { #define TG3_FLG3_L1PLLPD_EN 0x00800000 #define TG3_FLG3_57765_PLUS 0x01000000 #define TG3_FLG3_APE_HAS_NCSI 0x02000000 +#define TG3_FLG3_5717_PLUS 0x04000000 struct timer_list timer; u16 timer_counter; -- GitLab From d78b59f5d18bf064abae2fa5bc87f00545e2160a Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:46 +0000 Subject: [PATCH 0521/5560] tg3: Add 5720 ASIC rev This patch adds support for the 5720 ASIC rev. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 30 ++++++++++++++++++++++-------- drivers/net/tg3.h | 5 +++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index dc6b60b65c0b..53a1209d4f9c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2125,7 +2125,8 @@ static void tg3_frob_aux_power(struct tg3 *tp) if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) && tp->pdev_peer != tp->pdev) { struct net_device *dev_peer; @@ -7251,6 +7252,11 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(0x7c00, val | (1 << 25)); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + val = tr32(TG3_CPMU_CLCK_ORIDE); + tw32(TG3_CPMU_CLCK_ORIDE, val & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN); + } + /* Reprobe ASF enable state. */ tp->tg3_flags &= ~TG3_FLAG_ENABLE_ASF; tp->tg3_flags2 &= ~TG3_FLG2_ASF_NEW_HANDSHAKE; @@ -8214,7 +8220,8 @@ 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_57765_PLUS)) { val = tr32(TG3_RDMA_RSRVCTRL_REG); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK | TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK | TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK); @@ -8226,7 +8233,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val | TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K | @@ -9050,7 +9058,9 @@ static bool tg3_enable_msix(struct tg3 *tp) if (tp->irq_cnt > 1) { tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1); } @@ -13166,7 +13176,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719) + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) pci_read_config_dword(tp->pdev, TG3PCI_GEN2_PRODID_ASICREV, &prod_id_asic_rev); @@ -13321,11 +13332,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) tp->pdev_peer = tg3_find_peer(tp); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) tp->tg3_flags3 |= TG3_FLG3_5717_PLUS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 || @@ -13444,7 +13457,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; tp->pcie_readrq = 4096; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) tp->pcie_readrq = 2048; pcie_set_readrq(tp->pdev, tp->pcie_readrq); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index b8e6acc019b4..45605f2f7b54 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -58,6 +58,7 @@ #define TG3PCI_DEVICE_TIGON3_57791 0x16b2 #define TG3PCI_DEVICE_TIGON3_57795 0x16b6 #define TG3PCI_DEVICE_TIGON3_5719 0x1657 +#define TG3PCI_DEVICE_TIGON3_5720 0x165f /* 0x04 --> 0x2c unused */ #define TG3PCI_SUBVENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM #define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6 0x1644 @@ -167,6 +168,7 @@ #define ASIC_REV_5717 0x5717 #define ASIC_REV_57765 0x57785 #define ASIC_REV_5719 0x5719 +#define ASIC_REV_5720 0x5720 #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -1083,6 +1085,9 @@ #define CPMU_HST_ACC_MACCLK_6_25 0x00130000 /* 0x3620 --> 0x3630 unused */ +#define TG3_CPMU_CLCK_ORIDE 0x00003624 +#define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000 + #define TG3_CPMU_CLCK_STAT 0x00003630 #define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000 #define CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000 -- GitLab From 9b91b5f178605dd0d4debcbc184a3e97fcb4f591 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:47 +0000 Subject: [PATCH 0522/5560] tg3: Add 5720 NVRAM decoding The 5720 implements its own NVRAM pin strapping scheme. This patch adds the required support. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 117 +++++++++++++++++++++++++++++++++++++++++++++- drivers/net/tg3.h | 36 ++++++++++++++ 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 53a1209d4f9c..a079e745a071 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11889,6 +11889,118 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS; } +static void __devinit tg3_get_5720_nvram_info(struct tg3 *tp) +{ + u32 nvcfg1, nvmpinstrp; + + nvcfg1 = tr32(NVRAM_CFG1); + nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK; + + switch (nvmpinstrp) { + case FLASH_5720_EEPROM_HD: + case FLASH_5720_EEPROM_LD: + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + + nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; + tw32(NVRAM_CFG1, nvcfg1); + if (nvmpinstrp == FLASH_5720_EEPROM_HD) + tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; + else + tp->nvram_pagesize = ATMEL_AT24C02_CHIP_SIZE; + return; + case FLASH_5720VENDOR_M_ATMEL_DB011D: + case FLASH_5720VENDOR_A_ATMEL_DB011B: + case FLASH_5720VENDOR_A_ATMEL_DB011D: + case FLASH_5720VENDOR_M_ATMEL_DB021D: + case FLASH_5720VENDOR_A_ATMEL_DB021B: + case FLASH_5720VENDOR_A_ATMEL_DB021D: + case FLASH_5720VENDOR_M_ATMEL_DB041D: + case FLASH_5720VENDOR_A_ATMEL_DB041B: + case FLASH_5720VENDOR_A_ATMEL_DB041D: + case FLASH_5720VENDOR_M_ATMEL_DB081D: + case FLASH_5720VENDOR_A_ATMEL_DB081D: + case FLASH_5720VENDOR_ATMEL_45USPT: + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + tp->tg3_flags2 |= TG3_FLG2_FLASH; + + switch (nvmpinstrp) { + case FLASH_5720VENDOR_M_ATMEL_DB021D: + case FLASH_5720VENDOR_A_ATMEL_DB021B: + case FLASH_5720VENDOR_A_ATMEL_DB021D: + tp->nvram_size = TG3_NVRAM_SIZE_256KB; + break; + case FLASH_5720VENDOR_M_ATMEL_DB041D: + case FLASH_5720VENDOR_A_ATMEL_DB041B: + case FLASH_5720VENDOR_A_ATMEL_DB041D: + tp->nvram_size = TG3_NVRAM_SIZE_512KB; + break; + case FLASH_5720VENDOR_M_ATMEL_DB081D: + case FLASH_5720VENDOR_A_ATMEL_DB081D: + tp->nvram_size = TG3_NVRAM_SIZE_1MB; + break; + default: + tp->nvram_size = TG3_NVRAM_SIZE_128KB; + break; + } + break; + case FLASH_5720VENDOR_M_ST_M25PE10: + case FLASH_5720VENDOR_M_ST_M45PE10: + case FLASH_5720VENDOR_A_ST_M25PE10: + case FLASH_5720VENDOR_A_ST_M45PE10: + case FLASH_5720VENDOR_M_ST_M25PE20: + case FLASH_5720VENDOR_M_ST_M45PE20: + case FLASH_5720VENDOR_A_ST_M25PE20: + case FLASH_5720VENDOR_A_ST_M45PE20: + case FLASH_5720VENDOR_M_ST_M25PE40: + case FLASH_5720VENDOR_M_ST_M45PE40: + case FLASH_5720VENDOR_A_ST_M25PE40: + case FLASH_5720VENDOR_A_ST_M45PE40: + case FLASH_5720VENDOR_M_ST_M25PE80: + case FLASH_5720VENDOR_M_ST_M45PE80: + case FLASH_5720VENDOR_A_ST_M25PE80: + case FLASH_5720VENDOR_A_ST_M45PE80: + case FLASH_5720VENDOR_ST_25USPT: + case FLASH_5720VENDOR_ST_45USPT: + tp->nvram_jedecnum = JEDEC_ST; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + tp->tg3_flags2 |= TG3_FLG2_FLASH; + + switch (nvmpinstrp) { + case FLASH_5720VENDOR_M_ST_M25PE20: + case FLASH_5720VENDOR_M_ST_M45PE20: + case FLASH_5720VENDOR_A_ST_M25PE20: + case FLASH_5720VENDOR_A_ST_M45PE20: + tp->nvram_size = TG3_NVRAM_SIZE_256KB; + break; + case FLASH_5720VENDOR_M_ST_M25PE40: + case FLASH_5720VENDOR_M_ST_M45PE40: + case FLASH_5720VENDOR_A_ST_M25PE40: + case FLASH_5720VENDOR_A_ST_M45PE40: + tp->nvram_size = TG3_NVRAM_SIZE_512KB; + break; + case FLASH_5720VENDOR_M_ST_M25PE80: + case FLASH_5720VENDOR_M_ST_M45PE80: + case FLASH_5720VENDOR_A_ST_M25PE80: + case FLASH_5720VENDOR_A_ST_M45PE80: + tp->nvram_size = TG3_NVRAM_SIZE_1MB; + break; + default: + tp->nvram_size = TG3_NVRAM_SIZE_128KB; + break; + } + break; + default: + tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM; + return; + } + + tg3_nvram_get_pagesize(tp, nvcfg1); + if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528) + tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS; +} + /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { @@ -11933,8 +12045,11 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tg3_get_57780_nvram_info(tp); - else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) tg3_get_5717_nvram_info(tp); + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + tg3_get_5720_nvram_info(tp); else tg3_get_nvram_info(tp); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 45605f2f7b54..169a6cebf9f1 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1827,6 +1827,38 @@ #define FLASH_5717VENDOR_ATMEL_45USPT 0x03400000 #define FLASH_5717VENDOR_ST_25USPT 0x03400002 #define FLASH_5717VENDOR_ST_45USPT 0x03400001 +#define FLASH_5720_EEPROM_HD 0x00000001 +#define FLASH_5720_EEPROM_LD 0x00000003 +#define FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000 +#define FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002 +#define FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001 +#define FLASH_5720VENDOR_M_ATMEL_DB081D 0x01000003 +#define FLASH_5720VENDOR_M_ST_M25PE10 0x02000000 +#define FLASH_5720VENDOR_M_ST_M25PE20 0x02000002 +#define FLASH_5720VENDOR_M_ST_M25PE40 0x02000001 +#define FLASH_5720VENDOR_M_ST_M25PE80 0x02000003 +#define FLASH_5720VENDOR_M_ST_M45PE10 0x03000000 +#define FLASH_5720VENDOR_M_ST_M45PE20 0x03000002 +#define FLASH_5720VENDOR_M_ST_M45PE40 0x03000001 +#define FLASH_5720VENDOR_M_ST_M45PE80 0x03000003 +#define FLASH_5720VENDOR_A_ATMEL_DB011B 0x01800000 +#define FLASH_5720VENDOR_A_ATMEL_DB021B 0x01800002 +#define FLASH_5720VENDOR_A_ATMEL_DB041B 0x01800001 +#define FLASH_5720VENDOR_A_ATMEL_DB011D 0x01c00000 +#define FLASH_5720VENDOR_A_ATMEL_DB021D 0x01c00002 +#define FLASH_5720VENDOR_A_ATMEL_DB041D 0x01c00001 +#define FLASH_5720VENDOR_A_ATMEL_DB081D 0x01c00003 +#define FLASH_5720VENDOR_A_ST_M25PE10 0x02800000 +#define FLASH_5720VENDOR_A_ST_M25PE20 0x02800002 +#define FLASH_5720VENDOR_A_ST_M25PE40 0x02800001 +#define FLASH_5720VENDOR_A_ST_M25PE80 0x02800003 +#define FLASH_5720VENDOR_A_ST_M45PE10 0x02c00000 +#define FLASH_5720VENDOR_A_ST_M45PE20 0x02c00002 +#define FLASH_5720VENDOR_A_ST_M45PE40 0x02c00001 +#define FLASH_5720VENDOR_A_ST_M45PE80 0x02c00003 +#define FLASH_5720VENDOR_ATMEL_45USPT 0x03c00000 +#define FLASH_5720VENDOR_ST_25USPT 0x03c00002 +#define FLASH_5720VENDOR_ST_45USPT 0x03c00001 #define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000 #define FLASH_5752PAGE_SIZE_256 0x00000000 #define FLASH_5752PAGE_SIZE_512 0x10000000 @@ -3060,6 +3092,7 @@ struct tg3 { int nvram_lock_cnt; u32 nvram_size; +#define TG3_NVRAM_SIZE_2KB 0x00000800 #define TG3_NVRAM_SIZE_64KB 0x00010000 #define TG3_NVRAM_SIZE_128KB 0x00020000 #define TG3_NVRAM_SIZE_256KB 0x00040000 @@ -3075,6 +3108,9 @@ struct tg3 { #define JEDEC_SAIFUN 0x4f #define JEDEC_SST 0xbf +#define ATMEL_AT24C02_CHIP_SIZE TG3_NVRAM_SIZE_2KB +#define ATMEL_AT24C02_PAGE_SIZE (8) + #define ATMEL_AT24C64_CHIP_SIZE TG3_NVRAM_SIZE_64KB #define ATMEL_AT24C64_PAGE_SIZE (32) -- GitLab From f2096f94b514d88593355995d5dd276961e88af1 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:48 +0000 Subject: [PATCH 0523/5560] tg3: Add 5720 H2BMC support This patch adds support for the new Host to BMC feature. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 59 +++++++++++++++++++++++++++++++++++------------ drivers/net/tg3.h | 9 ++++++++ 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a079e745a071..263f151ab528 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4390,6 +4390,7 @@ static void tg3_serdes_parallel_detect(struct tg3 *tp) static int tg3_setup_phy(struct tg3 *tp, int force_reset) { + u32 val; int err; if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) @@ -4400,7 +4401,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) err = tg3_setup_copper_phy(tp, force_reset); if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) { - u32 val, scale; + u32 scale; val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK; if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5) @@ -4415,17 +4416,20 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) tw32(GRC_MISC_CFG, val); } + val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) | + (6 << TX_LENGTHS_IPG_SHIFT); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + val |= tr32(MAC_TX_LENGTHS) & + (TX_LENGTHS_JMB_FRM_LEN_MSK | + TX_LENGTHS_CNT_DWN_VAL_MSK); + if (tp->link_config.active_speed == SPEED_1000 && tp->link_config.active_duplex == DUPLEX_HALF) - tw32(MAC_TX_LENGTHS, - ((2 << TX_LENGTHS_IPG_CRS_SHIFT) | - (6 << TX_LENGTHS_IPG_SHIFT) | - (0xff << TX_LENGTHS_SLOT_TIME_SHIFT))); + tw32(MAC_TX_LENGTHS, val | + (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)); else - tw32(MAC_TX_LENGTHS, - ((2 << TX_LENGTHS_IPG_CRS_SHIFT) | - (6 << TX_LENGTHS_IPG_SHIFT) | - (32 << TX_LENGTHS_SLOT_TIME_SHIFT))); + tw32(MAC_TX_LENGTHS, val | + (32 << TX_LENGTHS_SLOT_TIME_SHIFT)); if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { if (netif_carrier_ok(tp->dev)) { @@ -4437,7 +4441,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) } if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) { - u32 val = tr32(PCIE_PWR_MGMT_THRESH); + val = tr32(PCIE_PWR_MGMT_THRESH); if (!netif_carrier_ok(tp->dev)) val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | tp->pwrmgmt_thresh; @@ -8164,10 +8168,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) /* The slot time is changed by tg3_setup_phy if we * run at gigabit with half duplex. */ - tw32(MAC_TX_LENGTHS, - (2 << TX_LENGTHS_IPG_CRS_SHIFT) | - (6 << TX_LENGTHS_IPG_SHIFT) | - (32 << TX_LENGTHS_SLOT_TIME_SHIFT)); + val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) | + (6 << TX_LENGTHS_IPG_SHIFT) | + (32 << TX_LENGTHS_SLOT_TIME_SHIFT); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + val |= tr32(MAC_TX_LENGTHS) & + (TX_LENGTHS_JMB_FRM_LEN_MSK | + TX_LENGTHS_CNT_DWN_VAL_MSK); + + tw32(MAC_TX_LENGTHS, val); /* Receive rules. */ tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS); @@ -8214,6 +8224,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || @@ -8447,9 +8460,17 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } tp->tx_mode = TX_MODE_ENABLE; + if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) { + val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE; + tp->tx_mode &= ~val; + tp->tx_mode |= tr32(MAC_TX_MODE) & val; + } + tw32_f(MAC_TX_MODE, tp->tx_mode); udelay(100); @@ -13880,7 +13901,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* Initialize data/descriptor byte/word swapping. */ val = tr32(GRC_MODE); - val &= GRC_MODE_HOST_STACKUP; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA | + GRC_MODE_WORD_SWAP_B2HRX_DATA | + GRC_MODE_B2HRX_ENABLE | + GRC_MODE_HTX2B_ENABLE | + GRC_MODE_HOST_STACKUP); + else + val &= GRC_MODE_HOST_STACKUP; + tw32(GRC_MODE, val | tp->grc_mode); tg3_switch_clocks(tp); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 169a6cebf9f1..a936727018f9 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -479,6 +479,8 @@ #define TX_MODE_BIG_BCKOFF_ENABLE 0x00000020 #define TX_MODE_LONG_PAUSE_ENABLE 0x00000040 #define TX_MODE_MBUF_LOCKUP_FIX 0x00000100 +#define TX_MODE_JMB_FRM_LEN 0x00400000 +#define TX_MODE_CNT_DN_MODE 0x00800000 #define MAC_TX_STATUS 0x00000460 #define TX_STATUS_XOFFED 0x00000001 #define TX_STATUS_SENT_XOFF 0x00000002 @@ -493,6 +495,8 @@ #define TX_LENGTHS_IPG_SHIFT 8 #define TX_LENGTHS_IPG_CRS_MASK 0x00003000 #define TX_LENGTHS_IPG_CRS_SHIFT 12 +#define TX_LENGTHS_JMB_FRM_LEN_MSK 0x00ff0000 +#define TX_LENGTHS_CNT_DWN_VAL_MSK 0xff000000 #define MAC_RX_MODE 0x00000468 #define RX_MODE_RESET 0x00000001 #define RX_MODE_ENABLE 0x00000002 @@ -1330,6 +1334,7 @@ #define RDMAC_MODE_MULT_DMA_RD_DIS 0x01000000 #define RDMAC_MODE_IPV4_LSO_EN 0x08000000 #define RDMAC_MODE_IPV6_LSO_EN 0x10000000 +#define RDMAC_MODE_H2BNC_VLAN_DET 0x20000000 #define RDMAC_STATUS 0x00004804 #define RDMAC_STATUS_TGTABORT 0x00000004 #define RDMAC_STATUS_MSTABORT 0x00000008 @@ -1622,6 +1627,8 @@ #define GRC_MODE_WSWAP_NONFRM_DATA 0x00000004 #define GRC_MODE_BSWAP_DATA 0x00000010 #define GRC_MODE_WSWAP_DATA 0x00000020 +#define GRC_MODE_BYTE_SWAP_B2HRX_DATA 0x00000040 +#define GRC_MODE_WORD_SWAP_B2HRX_DATA 0x00000080 #define GRC_MODE_SPLITHDR 0x00000100 #define GRC_MODE_NOFRM_CRACKING 0x00000200 #define GRC_MODE_INCL_CRC 0x00000400 @@ -1629,8 +1636,10 @@ #define GRC_MODE_NOIRQ_ON_SENDS 0x00002000 #define GRC_MODE_NOIRQ_ON_RCV 0x00004000 #define GRC_MODE_FORCE_PCI32BIT 0x00008000 +#define GRC_MODE_B2HRX_ENABLE 0x00008000 #define GRC_MODE_HOST_STACKUP 0x00010000 #define GRC_MODE_HOST_SENDBDS 0x00020000 +#define GRC_MODE_HTX2B_ENABLE 0x00040000 #define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000 #define GRC_MODE_NVRAM_WR_ENABLE 0x00200000 #define GRC_MODE_PCIE_TL_SEL 0x00000000 -- GitLab From 6418f2c1b57f9a5d4e7380f698635e5a445c2a50 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:49 +0000 Subject: [PATCH 0524/5560] tg3: Add 5720 PHY ID This patch adds the 5720 PHY ID. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 1 + drivers/net/tg3.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 263f151ab528..886174d75625 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -14673,6 +14673,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case TG3_PHY_ID_BCM5718S: return "5718S"; case TG3_PHY_ID_BCM57765: return "57765"; case TG3_PHY_ID_BCM5719C: return "5719C"; + case TG3_PHY_ID_BCM5720C: return "5720C"; case TG3_PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index a936727018f9..e7880d593aa8 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -3035,6 +3035,7 @@ struct tg3 { #define TG3_PHY_ID_BCM5718S 0xbc050ff0 #define TG3_PHY_ID_BCM57765 0x5c0d8a40 #define TG3_PHY_ID_BCM5719C 0x5c0d8a20 +#define TG3_PHY_ID_BCM5720C 0x5c0d8b60 #define TG3_PHY_ID_BCM5906 0xdc00ac40 #define TG3_PHY_ID_BCM8002 0x60010140 #define TG3_PHY_ID_INVALID 0xffffffff -- GitLab From ba1f3c76d7607a0af58834b79a055326619cbf2a Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:50 +0000 Subject: [PATCH 0525/5560] tg3: Enable 5720 support This patch adds the 5720 device ID to the PCI table, thus enabling 5720 support. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 886174d75625..a065beb229f1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -264,6 +264,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, -- GitLab From 66ee33bfda6237b009b6fb0e48690e31800ff334 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 5 Apr 2011 14:22:51 +0000 Subject: [PATCH 0526/5560] tg3: Support 4mb flash sizes for 5717 and 5719 If a 5717 or 5719 NVRAM part is manually strapped and is 2mb in size, the driver needs to look at the NVRAM size field rather than infer it from the strapping itself. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a065beb229f1..f944c6b97dd6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11866,6 +11866,8 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp) switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { case FLASH_5717VENDOR_ATMEL_MDB021D: + /* Detect size with tg3_nvram_get_size() */ + break; case FLASH_5717VENDOR_ATMEL_ADB021B: case FLASH_5717VENDOR_ATMEL_ADB021D: tp->nvram_size = TG3_NVRAM_SIZE_256KB; @@ -11891,8 +11893,10 @@ static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp) switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { case FLASH_5717VENDOR_ST_M_M25PE20: - case FLASH_5717VENDOR_ST_A_M25PE20: case FLASH_5717VENDOR_ST_M_M45PE20: + /* Detect size with tg3_nvram_get_size() */ + break; + case FLASH_5717VENDOR_ST_A_M25PE20: case FLASH_5717VENDOR_ST_A_M45PE20: tp->nvram_size = TG3_NVRAM_SIZE_256KB; break; -- GitLab From 1ca050d909add6825224c015d8cec2425b3edf27 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 5 Apr 2011 08:01:16 +0000 Subject: [PATCH 0527/5560] can: convert protocol handling to RCU This patch removes spin_locks at CAN socket creation time by using RCU. Inspired by the discussion with Kurt van Dijck and Eric Dumazet the RCU code was partly derived from af_phonet.c Signed-off-by: Oliver Hartkopp Reviewed-by: Eric Dumazet Acked-by: Kurt Van Dijck Signed-off-by: David S. Miller --- net/can/af_can.c | 52 +++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/net/can/af_can.c b/net/can/af_can.c index 733d66f1b05a..a8dcaa49675a 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -85,7 +85,7 @@ static struct kmem_cache *rcv_cache __read_mostly; /* table of registered CAN protocols */ static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; -static DEFINE_SPINLOCK(proto_tab_lock); +static DEFINE_MUTEX(proto_tab_lock); struct timer_list can_stattimer; /* timer for statistics update */ struct s_stats can_stats; /* packet statistics */ @@ -115,6 +115,19 @@ static void can_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); } +static struct can_proto *can_try_module_get(int protocol) +{ + struct can_proto *cp; + + rcu_read_lock(); + cp = rcu_dereference(proto_tab[protocol]); + if (cp && !try_module_get(cp->prot->owner)) + cp = NULL; + rcu_read_unlock(); + + return cp; +} + static int can_create(struct net *net, struct socket *sock, int protocol, int kern) { @@ -130,9 +143,12 @@ static int can_create(struct net *net, struct socket *sock, int protocol, if (!net_eq(net, &init_net)) return -EAFNOSUPPORT; + cp = can_try_module_get(protocol); + #ifdef CONFIG_MODULES - /* try to load protocol module kernel is modular */ - if (!proto_tab[protocol]) { + if (!cp) { + /* try to load protocol module if kernel is modular */ + err = request_module("can-proto-%d", protocol); /* @@ -143,22 +159,18 @@ static int can_create(struct net *net, struct socket *sock, int protocol, if (err && printk_ratelimit()) printk(KERN_ERR "can: request_module " "(can-proto-%d) failed.\n", protocol); + + cp = can_try_module_get(protocol); } #endif - spin_lock(&proto_tab_lock); - cp = proto_tab[protocol]; - if (cp && !try_module_get(cp->prot->owner)) - cp = NULL; - spin_unlock(&proto_tab_lock); - /* check for available protocol and correct usage */ if (!cp) return -EPROTONOSUPPORT; if (cp->type != sock->type) { - err = -EPROTONOSUPPORT; + err = -EPROTOTYPE; goto errout; } @@ -694,15 +706,16 @@ int can_proto_register(struct can_proto *cp) if (err < 0) return err; - spin_lock(&proto_tab_lock); + mutex_lock(&proto_tab_lock); + if (proto_tab[proto]) { printk(KERN_ERR "can: protocol %d already registered\n", proto); err = -EBUSY; } else - proto_tab[proto] = cp; + rcu_assign_pointer(proto_tab[proto], cp); - spin_unlock(&proto_tab_lock); + mutex_unlock(&proto_tab_lock); if (err < 0) proto_unregister(cp->prot); @@ -719,13 +732,12 @@ void can_proto_unregister(struct can_proto *cp) { int proto = cp->protocol; - spin_lock(&proto_tab_lock); - if (!proto_tab[proto]) { - printk(KERN_ERR "BUG: can: protocol %d is not registered\n", - proto); - } - proto_tab[proto] = NULL; - spin_unlock(&proto_tab_lock); + mutex_lock(&proto_tab_lock); + BUG_ON(proto_tab[proto] != cp); + rcu_assign_pointer(proto_tab[proto], NULL); + mutex_unlock(&proto_tab_lock); + + synchronize_rcu(); proto_unregister(cp->prot); } -- GitLab From 53478fef7490c90564dd328b395f238952d95c77 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Fri, 1 Apr 2011 14:27:47 +0000 Subject: [PATCH 0528/5560] qlcnic: Make PCI info available in all modes Before this fix, PCI info was available only when multiple NIC functions are present on the same port. Signed-off-by: Sony Chacko Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index cd88c7e1bfa9..d230fdde28af 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -3954,14 +3954,14 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) dev_info(dev, "failed to create crb sysfs entry\n"); if (device_create_bin_file(dev, &bin_attr_mem)) dev_info(dev, "failed to create mem sysfs entry\n"); + if (device_create_bin_file(dev, &bin_attr_pci_config)) + dev_info(dev, "failed to create pci config sysfs entry"); if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) return; if (device_create_bin_file(dev, &bin_attr_esw_config)) dev_info(dev, "failed to create esw config sysfs entry"); if (adapter->op_mode != QLCNIC_MGMT_FUNC) return; - if (device_create_bin_file(dev, &bin_attr_pci_config)) - dev_info(dev, "failed to create pci config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_npar_config)) dev_info(dev, "failed to create npar config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_pm_config)) @@ -3982,12 +3982,12 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) device_remove_file(dev, &dev_attr_diag_mode); device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_mem); + device_remove_bin_file(dev, &bin_attr_pci_config); if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) return; device_remove_bin_file(dev, &bin_attr_esw_config); if (adapter->op_mode != QLCNIC_MGMT_FUNC) return; - device_remove_bin_file(dev, &bin_attr_pci_config); device_remove_bin_file(dev, &bin_attr_npar_config); device_remove_bin_file(dev, &bin_attr_pm_config); device_remove_bin_file(dev, &bin_attr_esw_stats); -- GitLab From f848d6dd10e8e27d5dd61a8ab7174a7dde3a3db5 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Fri, 1 Apr 2011 14:27:59 +0000 Subject: [PATCH 0529/5560] qlcnic: Memory leak fix Fix a memory leak in error path of pci info. Signed-off-by: Sony Chacko Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index d230fdde28af..de6f86681a3c 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -464,8 +464,10 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { pfn = pci_info[i].id; - if (pfn > QLCNIC_MAX_PCI_FUNC) - return QL_STATUS_INVALID_PARAM; + if (pfn > QLCNIC_MAX_PCI_FUNC) { + ret = QL_STATUS_INVALID_PARAM; + goto err_eswitch; + } adapter->npars[pfn].active = (u8)pci_info[i].active; adapter->npars[pfn].type = (u8)pci_info[i].type; adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port; -- GitLab From b1fc6d3cfaff6fefd838b84532cb356f8a80da7b Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Fri, 1 Apr 2011 14:28:05 +0000 Subject: [PATCH 0530/5560] qlcnic: Cleanup patch 1. Changed adapter structure to move away from embedding hardware and receive context structs and use pointers to those objects 2. Packed all the structs that interface with FW 3. Removed unused code and structs Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 126 +++++++--------------- drivers/net/qlcnic/qlcnic_ctx.c | 135 ++++++++++++------------ drivers/net/qlcnic/qlcnic_ethtool.c | 40 +++---- drivers/net/qlcnic/qlcnic_hw.c | 56 +++++----- drivers/net/qlcnic/qlcnic_init.c | 26 ++--- drivers/net/qlcnic/qlcnic_main.c | 158 +++++++++++++++++----------- 6 files changed, 268 insertions(+), 273 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index dc44564ef6f9..15d950a4f46d 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -93,8 +93,6 @@ #define TX_IP_PKT 0x04 #define TX_TCP_LSO 0x05 #define TX_TCP_LSO6 0x06 -#define TX_IPSEC 0x07 -#define TX_IPSEC_CMD 0x0a #define TX_TCPV6_PKT 0x0b #define TX_UDPV6_PKT 0x0c @@ -200,7 +198,7 @@ struct rcv_desc { __le16 reserved; __le32 buffer_length; /* allocated buffer length (usually 2K) */ __le64 addr_buffer; -}; +} __packed; /* opcode field in status_desc */ #define QLCNIC_SYN_OFFLOAD 0x03 @@ -365,12 +363,6 @@ struct qlcnic_skb_frag { u64 length; }; -struct qlcnic_recv_crb { - u32 crb_rcv_producer[NUM_RCV_DESC_RINGS]; - u32 crb_sts_consumer[NUM_STS_DESC_RINGS]; - u32 sw_int_mask[NUM_STS_DESC_RINGS]; -}; - /* Following defines are for the state of the buffers */ #define QLCNIC_BUFFER_FREE 0 #define QLCNIC_BUFFER_BUSY 1 @@ -387,10 +379,10 @@ struct qlcnic_cmd_buffer { /* In rx_buffer, we do not need multiple fragments as is a single buffer */ struct qlcnic_rx_buffer { - struct list_head list; + u16 ref_handle; struct sk_buff *skb; + struct list_head list; u64 dma; - u16 ref_handle; }; /* Board types */ @@ -494,12 +486,12 @@ struct qlcnic_host_tx_ring { * present elsewhere. */ struct qlcnic_recv_context { + struct qlcnic_host_rds_ring *rds_rings; + struct qlcnic_host_sds_ring *sds_rings; u32 state; u16 context_id; u16 virt_port; - struct qlcnic_host_rds_ring *rds_rings; - struct qlcnic_host_sds_ring *sds_rings; }; /* HW context creation */ @@ -538,9 +530,6 @@ struct qlcnic_recv_context { #define QLCNIC_CDRP_CMD_DESTROY_RX_CTX 0x00000008 #define QLCNIC_CDRP_CMD_CREATE_TX_CTX 0x00000009 #define QLCNIC_CDRP_CMD_DESTROY_TX_CTX 0x0000000a -#define QLCNIC_CDRP_CMD_SETUP_STATISTICS 0x0000000e -#define QLCNIC_CDRP_CMD_GET_STATISTICS 0x0000000f -#define QLCNIC_CDRP_CMD_DELETE_STATISTICS 0x00000010 #define QLCNIC_CDRP_CMD_SET_MTU 0x00000012 #define QLCNIC_CDRP_CMD_READ_PHY 0x00000013 #define QLCNIC_CDRP_CMD_WRITE_PHY 0x00000014 @@ -549,17 +538,11 @@ struct qlcnic_recv_context { #define QLCNIC_CDRP_CMD_SET_FLOW_CTL 0x00000017 #define QLCNIC_CDRP_CMD_READ_MAX_MTU 0x00000018 #define QLCNIC_CDRP_CMD_READ_MAX_LRO 0x00000019 -#define QLCNIC_CDRP_CMD_CONFIGURE_TOE 0x0000001a -#define QLCNIC_CDRP_CMD_FUNC_ATTRIB 0x0000001b -#define QLCNIC_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c -#define QLCNIC_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d -#define QLCNIC_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e #define QLCNIC_CDRP_CMD_MAC_ADDRESS 0x0000001f #define QLCNIC_CDRP_CMD_GET_PCI_INFO 0x00000020 #define QLCNIC_CDRP_CMD_GET_NIC_INFO 0x00000021 #define QLCNIC_CDRP_CMD_SET_NIC_INFO 0x00000022 -#define QLCNIC_CDRP_CMD_RESET_NPAR 0x00000023 #define QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY 0x00000024 #define QLCNIC_CDRP_CMD_TOGGLE_ESWITCH 0x00000025 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 @@ -597,14 +580,14 @@ struct qlcnic_hostrq_sds_ring { __le32 ring_size; /* Ring entries */ __le16 msi_index; __le16 rsvd; /* Padding */ -}; +} __packed; struct qlcnic_hostrq_rds_ring { __le64 host_phys_addr; /* Ring base addr */ __le64 buff_size; /* Packet buffer size */ __le32 ring_size; /* Ring entries */ __le32 ring_kind; /* Class of ring */ -}; +} __packed; struct qlcnic_hostrq_rx_ctx { __le64 host_rsp_dma_addr; /* Response dma'd here */ @@ -625,17 +608,17 @@ struct qlcnic_hostrq_rx_ctx { - N hostrq_rds_rings - N hostrq_sds_rings */ char data[0]; -}; +} __packed; struct qlcnic_cardrsp_rds_ring{ __le32 host_producer_crb; /* Crb to use */ __le32 rsvd1; /* Padding */ -}; +} __packed; struct qlcnic_cardrsp_sds_ring { __le32 host_consumer_crb; /* Crb to use */ __le32 interrupt_crb; /* Crb to use */ -}; +} __packed; struct qlcnic_cardrsp_rx_ctx { /* These ring offsets are relative to data[0] below */ @@ -654,7 +637,7 @@ struct qlcnic_cardrsp_rx_ctx { - N cardrsp_rds_rings - N cardrs_sds_rings */ char data[0]; -}; +} __packed; #define SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings) \ (sizeof(HOSTRQ_RX) + \ @@ -674,7 +657,7 @@ struct qlcnic_hostrq_cds_ring { __le64 host_phys_addr; /* Ring base addr */ __le32 ring_size; /* Ring entries */ __le32 rsvd; /* Padding */ -}; +} __packed; struct qlcnic_hostrq_tx_ctx { __le64 host_rsp_dma_addr; /* Response dma'd here */ @@ -689,12 +672,12 @@ struct qlcnic_hostrq_tx_ctx { __le16 rsvd3; /* Padding */ struct qlcnic_hostrq_cds_ring cds_ring; /* Desc of cds ring */ u8 reserved[128]; /* future expansion */ -}; +} __packed; struct qlcnic_cardrsp_cds_ring { __le32 host_producer_crb; /* Crb to use */ __le32 interrupt_crb; /* Crb to use */ -}; +} __packed; struct qlcnic_cardrsp_tx_ctx { __le32 host_ctx_state; /* Starting state */ @@ -703,7 +686,7 @@ struct qlcnic_cardrsp_tx_ctx { u8 virt_port; /* Virtual/Logical id of port */ struct qlcnic_cardrsp_cds_ring cds_ring; /* Card cds settings */ u8 reserved[128]; /* future expansion */ -}; +} __packed; #define SIZEOF_HOSTRQ_TX(HOSTRQ_TX) (sizeof(HOSTRQ_TX)) #define SIZEOF_CARDRSP_TX(CARDRSP_TX) (sizeof(CARDRSP_TX)) @@ -782,50 +765,20 @@ struct qlcnic_nic_intr_coalesce { /* * Driver --> Firmware */ -#define QLCNIC_H2C_OPCODE_START 0 -#define QLCNIC_H2C_OPCODE_CONFIG_RSS 1 -#define QLCNIC_H2C_OPCODE_CONFIG_RSS_TBL 2 -#define QLCNIC_H2C_OPCODE_CONFIG_INTR_COALESCE 3 -#define QLCNIC_H2C_OPCODE_CONFIG_LED 4 -#define QLCNIC_H2C_OPCODE_CONFIG_PROMISCUOUS 5 -#define QLCNIC_H2C_OPCODE_CONFIG_L2_MAC 6 -#define QLCNIC_H2C_OPCODE_LRO_REQUEST 7 -#define QLCNIC_H2C_OPCODE_GET_SNMP_STATS 8 -#define QLCNIC_H2C_OPCODE_PROXY_START_REQUEST 9 -#define QLCNIC_H2C_OPCODE_PROXY_STOP_REQUEST 10 -#define QLCNIC_H2C_OPCODE_PROXY_SET_MTU 11 -#define QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE 12 -#define QLCNIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST 13 -#define QLCNIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST 14 -#define QLCNIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST 15 -#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_PROXY_STOP_DONE 20 -#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 21 -#define QLCNIC_C2C_OPCODE 22 -#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING 23 -#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 24 -#define QLCNIC_H2C_OPCODE_LAST 25 +#define QLCNIC_H2C_OPCODE_CONFIG_RSS 0x1 +#define QLCNIC_H2C_OPCODE_CONFIG_INTR_COALESCE 0x3 +#define QLCNIC_H2C_OPCODE_CONFIG_LED 0x4 +#define QLCNIC_H2C_OPCODE_LRO_REQUEST 0x7 +#define QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE 0xc +#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 0x12 +#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 0x15 +#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING 0x17 +#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 0x18 /* * Firmware --> Driver */ -#define QLCNIC_C2H_OPCODE_START 128 -#define QLCNIC_C2H_OPCODE_CONFIG_RSS_RESPONSE 129 -#define QLCNIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE 130 -#define QLCNIC_C2H_OPCODE_CONFIG_MAC_RESPONSE 131 -#define QLCNIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE 132 -#define QLCNIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE 133 -#define QLCNIC_C2H_OPCODE_LRO_DELETE_RESPONSE 134 -#define QLCNIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE 135 -#define QLCNIC_C2H_OPCODE_GET_SNMP_STATS 136 -#define QLCNIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY 137 -#define QLCNIC_C2H_OPCODE_INSTALL_LICENSE_REPLY 138 -#define QLCNIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139 -#define QLCNIC_C2H_OPCODE_GET_NET_STATS_RESPONSE 140 #define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141 -#define QLCNIC_C2H_OPCODE_LAST 142 #define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */ #define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */ @@ -894,7 +847,7 @@ struct qlcnic_nic_req { __le64 qhdr; __le64 req_hdr; __le64 words[6]; -}; +} __packed; struct qlcnic_mac_req { u8 op; @@ -905,7 +858,7 @@ struct qlcnic_mac_req { struct qlcnic_vlan_req { __le16 vlan_id; __le16 rsvd[3]; -}; +} __packed; struct qlcnic_ipaddr { __be32 ipv4; @@ -964,14 +917,14 @@ struct qlcnic_filter_hash { }; struct qlcnic_adapter { - struct qlcnic_hardware_context ahw; - + struct qlcnic_hardware_context *ahw; + struct qlcnic_recv_context *recv_ctx; + struct qlcnic_host_tx_ring *tx_ring; struct net_device *netdev; struct pci_dev *pdev; - struct list_head mac_list; - spinlock_t tx_clean_lock; - spinlock_t mac_learn_lock; + unsigned long state; + u32 flags; u16 num_txd; u16 num_rxd; @@ -989,7 +942,6 @@ struct qlcnic_adapter { u8 mc_enabled; u8 max_mc_count; - u8 rss_supported; u8 fw_wait_cnt; u8 fw_fail_cnt; u8 tx_timeo_cnt; @@ -1014,7 +966,6 @@ struct qlcnic_adapter { u32 fw_hal_version; u32 capabilities; - u32 flags; u32 irq; u32 temp; @@ -1039,9 +990,7 @@ struct qlcnic_adapter { struct qlcnic_nic_template *nic_ops; struct qlcnic_adapter_stats stats; - - struct qlcnic_recv_context recv_ctx; - struct qlcnic_host_tx_ring *tx_ring; + struct list_head mac_list; void __iomem *tgt_mask_reg; void __iomem *tgt_status_reg; @@ -1056,7 +1005,8 @@ struct qlcnic_adapter { struct qlcnic_filter_hash fhash; - unsigned long state; + spinlock_t tx_clean_lock; + spinlock_t mac_learn_lock; __le32 file_prd_off; /*File fw product offset*/ u32 fw_version; const struct firmware *fw; @@ -1078,7 +1028,7 @@ struct qlcnic_info { __le16 min_tx_bw; __le16 max_tx_bw; u8 reserved2[104]; -}; +} __packed; struct qlcnic_pci_info { __le16 id; /* pci function id */ @@ -1092,7 +1042,7 @@ struct qlcnic_pci_info { u8 mac[ETH_ALEN]; u8 reserved2[106]; -}; +} __packed; struct qlcnic_npar_info { u16 pvid; @@ -1209,7 +1159,7 @@ struct __qlcnic_esw_statistics { __le64 local_frames; __le64 numbytes; __le64 rsvd[3]; -}; +} __packed; struct qlcnic_esw_statistics { struct __qlcnic_esw_statistics rx; @@ -1293,7 +1243,7 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter); int qlcnic_check_fw_status(struct qlcnic_adapter *adapter); void qlcnic_watchdog_task(struct work_struct *work); -void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, +void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, struct qlcnic_host_rds_ring *rds_ring); int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max); void qlcnic_set_multi(struct net_device *netdev); diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 27631f23b3fd..050fa5a99ff7 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -67,11 +67,11 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu) { - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) { if (qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, recv_ctx->context_id, mtu, @@ -102,12 +102,12 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; u64 phys_addr; - int i, nrds_rings, nsds_rings; + u8 i, nrds_rings, nsds_rings; size_t rq_size, rsp_size; u32 cap, reg, val, reg2; int err; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; nrds_rings = adapter->max_rds_rings; nsds_rings = adapter->max_sds_rings; @@ -119,14 +119,14 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings, nsds_rings); - addr = pci_alloc_consistent(adapter->pdev, - rq_size, &hostrq_phys_addr); + addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size, + &hostrq_phys_addr, GFP_KERNEL); if (addr == NULL) return -ENOMEM; prq = (struct qlcnic_hostrq_rx_ctx *)addr; - addr = pci_alloc_consistent(adapter->pdev, - rsp_size, &cardrsp_phys_addr); + addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size, + &cardrsp_phys_addr, GFP_KERNEL); if (addr == NULL) { err = -ENOMEM; goto out_free_rq; @@ -151,7 +151,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) prq->num_rds_rings = cpu_to_le16(nrds_rings); prq->num_sds_rings = cpu_to_le16(nsds_rings); - prq->rds_ring_offset = cpu_to_le32(0); + prq->rds_ring_offset = 0; val = le32_to_cpu(prq->rds_ring_offset) + (sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings); @@ -187,7 +187,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) phys_addr = hostrq_phys_addr; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, (u32)(phys_addr >> 32), (u32)(phys_addr & 0xffffffff), @@ -207,7 +207,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) rds_ring = &recv_ctx->rds_rings[i]; reg = le32_to_cpu(prsp_rds[i].host_producer_crb); - rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 + reg; + rds_ring->crb_rcv_producer = adapter->ahw->pci_base0 + reg; } prsp_sds = ((struct qlcnic_cardrsp_sds_ring *) @@ -219,8 +219,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) reg = le32_to_cpu(prsp_sds[i].host_consumer_crb); reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb); - sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 + reg; - sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2; + sds_ring->crb_sts_consumer = adapter->ahw->pci_base0 + reg; + sds_ring->crb_intr_mask = adapter->ahw->pci_base0 + reg2; } recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); @@ -228,19 +228,20 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) recv_ctx->virt_port = prsp->virt_port; out_free_rsp: - pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); + dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp, + cardrsp_phys_addr); out_free_rq: - pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr); + dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr); return err; } static void qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter) { - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; if (qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, recv_ctx->context_id, QLCNIC_DESTROY_CTX_RESET, @@ -274,14 +275,14 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) *(tx_ring->hw_consumer) = 0; rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx); - rq_addr = pci_alloc_consistent(adapter->pdev, - rq_size, &rq_phys_addr); + rq_addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size, + &rq_phys_addr, GFP_KERNEL); if (!rq_addr) return -ENOMEM; rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx); - rsp_addr = pci_alloc_consistent(adapter->pdev, - rsp_size, &rsp_phys_addr); + rsp_addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size, + &rsp_phys_addr, GFP_KERNEL); if (!rsp_addr) { err = -ENOMEM; goto out_free_rq; @@ -313,7 +314,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) phys_addr = rq_phys_addr; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, (u32)(phys_addr >> 32), ((u32)phys_addr & 0xffffffff), @@ -322,7 +323,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) if (err == QLCNIC_RCODE_SUCCESS) { temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); - tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 + temp; + tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp; adapter->tx_context_id = le16_to_cpu(prsp->context_id); @@ -332,10 +333,11 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) err = -EIO; } - pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr); + dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr, + rsp_phys_addr); out_free_rq: - pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr); + dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr); return err; } @@ -344,7 +346,7 @@ static void qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter) { if (qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, adapter->tx_context_id, QLCNIC_DESTROY_CTX_RESET, @@ -361,7 +363,7 @@ qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val) { if (qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, reg, 0, @@ -378,7 +380,7 @@ int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val) { return qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, reg, val, @@ -398,20 +400,19 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) struct pci_dev *pdev = adapter->pdev; - recv_ctx = &adapter->recv_ctx; + recv_ctx = adapter->recv_ctx; tx_ring = adapter->tx_ring; - tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32), - &tx_ring->hw_cons_phys_addr); + tx_ring->hw_consumer = (__le32 *) dma_alloc_coherent(&pdev->dev, + sizeof(u32), &tx_ring->hw_cons_phys_addr, GFP_KERNEL); if (tx_ring->hw_consumer == NULL) { dev_err(&pdev->dev, "failed to allocate tx consumer\n"); return -ENOMEM; } - *(tx_ring->hw_consumer) = 0; /* cmd desc ring */ - addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), - &tx_ring->phys_addr); + addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring), + &tx_ring->phys_addr, GFP_KERNEL); if (addr == NULL) { dev_err(&pdev->dev, "failed to allocate tx desc ring\n"); @@ -423,9 +424,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; - addr = pci_alloc_consistent(adapter->pdev, + addr = dma_alloc_coherent(&adapter->pdev->dev, RCV_DESC_RINGSIZE(rds_ring), - &rds_ring->phys_addr); + &rds_ring->phys_addr, GFP_KERNEL); if (addr == NULL) { dev_err(&pdev->dev, "failed to allocate rds ring [%d]\n", ring); @@ -439,9 +440,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; - addr = pci_alloc_consistent(adapter->pdev, + addr = dma_alloc_coherent(&adapter->pdev->dev, STATUS_DESC_RINGSIZE(sds_ring), - &sds_ring->phys_addr); + &sds_ring->phys_addr, GFP_KERNEL); if (addr == NULL) { dev_err(&pdev->dev, "failed to allocate sds ring [%d]\n", ring); @@ -501,11 +502,11 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) struct qlcnic_host_tx_ring *tx_ring; int ring; - recv_ctx = &adapter->recv_ctx; + recv_ctx = adapter->recv_ctx; tx_ring = adapter->tx_ring; if (tx_ring->hw_consumer != NULL) { - pci_free_consistent(adapter->pdev, + dma_free_coherent(&adapter->pdev->dev, sizeof(u32), tx_ring->hw_consumer, tx_ring->hw_cons_phys_addr); @@ -513,7 +514,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) } if (tx_ring->desc_head != NULL) { - pci_free_consistent(adapter->pdev, + dma_free_coherent(&adapter->pdev->dev, TX_DESC_RINGSIZE(tx_ring), tx_ring->desc_head, tx_ring->phys_addr); tx_ring->desc_head = NULL; @@ -523,7 +524,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) rds_ring = &recv_ctx->rds_rings[ring]; if (rds_ring->desc_head != NULL) { - pci_free_consistent(adapter->pdev, + dma_free_coherent(&adapter->pdev->dev, RCV_DESC_RINGSIZE(rds_ring), rds_ring->desc_head, rds_ring->phys_addr); @@ -535,7 +536,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) sds_ring = &recv_ctx->sds_rings[ring]; if (sds_ring->desc_head != NULL) { - pci_free_consistent(adapter->pdev, + dma_free_coherent(&adapter->pdev->dev, STATUS_DESC_RINGSIZE(sds_ring), sds_ring->desc_head, sds_ring->phys_addr); @@ -551,9 +552,9 @@ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) int err; u32 arg1; - arg1 = adapter->ahw.pci_func | BIT_8; + arg1 = adapter->ahw->pci_func | BIT_8; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, arg1, 0, @@ -582,15 +583,15 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, void *nic_info_addr; size_t nic_size = sizeof(struct qlcnic_info); - nic_info_addr = pci_alloc_consistent(adapter->pdev, - nic_size, &nic_dma_t); + nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, + &nic_dma_t, GFP_KERNEL); if (!nic_info_addr) return -ENOMEM; memset(nic_info_addr, 0, nic_size); nic_info = (struct qlcnic_info *) nic_info_addr; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, MSD(nic_dma_t), LSD(nic_dma_t), @@ -623,7 +624,8 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, err = -EIO; } - pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t); + dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr, + nic_dma_t); return err; } @@ -639,8 +641,8 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) if (adapter->op_mode != QLCNIC_MGMT_FUNC) return err; - nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size, - &nic_dma_t); + nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, + &nic_dma_t, GFP_KERNEL); if (!nic_info_addr) return -ENOMEM; @@ -659,7 +661,7 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw); err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, MSD(nic_dma_t), LSD(nic_dma_t), @@ -672,7 +674,8 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) err = -EIO; } - pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t); + dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr, + nic_dma_t); return err; } @@ -687,15 +690,15 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, size_t npar_size = sizeof(struct qlcnic_pci_info); size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC; - pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size, - &pci_info_dma_t); + pci_info_addr = dma_alloc_coherent(&adapter->pdev->dev, pci_size, + &pci_info_dma_t, GFP_KERNEL); if (!pci_info_addr) return -ENOMEM; memset(pci_info_addr, 0, pci_size); npar = (struct qlcnic_pci_info *) pci_info_addr; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, MSD(pci_info_dma_t), LSD(pci_info_dma_t), @@ -721,7 +724,7 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, err = -EIO; } - pci_free_consistent(adapter->pdev, pci_size, pci_info_addr, + dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr, pci_info_dma_t); return err; } @@ -741,7 +744,7 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, arg1 |= pci_func << 8; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, arg1, 0, @@ -775,14 +778,14 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, return -ENOMEM; if (adapter->op_mode != QLCNIC_MGMT_FUNC && - func != adapter->ahw.pci_func) { + func != adapter->ahw->pci_func) { dev_err(&adapter->pdev->dev, "Not privilege to query stats for func=%d", func); return -EIO; } - stats_addr = pci_alloc_consistent(adapter->pdev, stats_size, - &stats_dma_t); + stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, + &stats_dma_t, GFP_KERNEL); if (!stats_addr) { dev_err(&adapter->pdev->dev, "Unable to allocate memory\n"); return -ENOMEM; @@ -793,7 +796,7 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, arg1 |= rx_tx << 15 | stats_size << 16; err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, arg1, MSD(stats_dma_t), @@ -816,7 +819,7 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, esw_stats->numbytes = le64_to_cpu(stats->numbytes); } - pci_free_consistent(adapter->pdev, stats_size, stats_addr, + dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, stats_dma_t); return err; } @@ -900,7 +903,7 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, arg1 |= BIT_14 | rx_tx << 15; return qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, arg1, 0, @@ -921,7 +924,7 @@ __qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, u8 pci_func; pci_func = (*arg1 >> 8); err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, *arg1, 0, @@ -999,7 +1002,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, } err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, + adapter->ahw->pci_func, adapter->fw_hal_version, arg1, arg2, diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 45b2755d6cba..7e53cad6be16 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -150,10 +150,10 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct qlcnic_adapter *adapter = netdev_priv(dev); int check_sfp_module = 0; - u16 pcifn = adapter->ahw.pci_func; + u16 pcifn = adapter->ahw->pci_func; /* read which mode */ - if (adapter->ahw.port_type == QLCNIC_GBE) { + if (adapter->ahw->port_type == QLCNIC_GBE) { ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | @@ -170,7 +170,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->duplex = adapter->link_duplex; ecmd->autoneg = adapter->link_autoneg; - } else if (adapter->ahw.port_type == QLCNIC_XGBE) { + } else if (adapter->ahw->port_type == QLCNIC_XGBE) { u32 val; val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR); @@ -201,7 +201,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; - switch (adapter->ahw.board_type) { + switch (adapter->ahw->board_type) { case QLCNIC_BRDTYPE_P3P_REF_QG: case QLCNIC_BRDTYPE_P3P_4_GB: case QLCNIC_BRDTYPE_P3P_4_GB_MM: @@ -238,7 +238,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->autoneg = AUTONEG_DISABLE; break; case QLCNIC_BRDTYPE_P3P_10G_TP: - if (adapter->ahw.port_type == QLCNIC_XGBE) { + if (adapter->ahw->port_type == QLCNIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); ecmd->advertising |= @@ -256,7 +256,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) break; default: dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", - adapter->ahw.board_type); + adapter->ahw->board_type); return -EIO; } @@ -288,7 +288,7 @@ qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) __u32 status; /* read which mode */ - if (adapter->ahw.port_type == QLCNIC_GBE) { + if (adapter->ahw->port_type == QLCNIC_GBE) { /* autonegotiation */ if (qlcnic_fw_cmd_set_phy(adapter, QLCNIC_NIU_GB_MII_MGMT_ADDR_AUTONEG, @@ -340,14 +340,14 @@ static void qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct qlcnic_adapter *adapter = netdev_priv(dev); - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring; u32 *regs_buff = p; int ring, i = 0, j = 0; memset(p, 0, qlcnic_get_regs_len(dev)); regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) | - (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; + (adapter->ahw->revision_id << 16) | (adapter->pdev)->device; regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); regs_buff[1] = QLCNIC_MGMT_API_VERSION; @@ -382,7 +382,7 @@ static u32 qlcnic_test_link(struct net_device *dev) u32 val; val = QLCRD32(adapter, CRB_XG_STATE_P3P); - val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val); + val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val); return (val == XG_LINK_UP_P3P) ? 0 : 1; } @@ -482,7 +482,7 @@ qlcnic_get_pauseparam(struct net_device *netdev, int port = adapter->physical_port; __u32 val; - if (adapter->ahw.port_type == QLCNIC_GBE) { + if (adapter->ahw->port_type == QLCNIC_GBE) { if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS)) return; /* get flow control settings */ @@ -504,7 +504,7 @@ qlcnic_get_pauseparam(struct net_device *netdev, pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val)); break; } - } else if (adapter->ahw.port_type == QLCNIC_XGBE) { + } else if (adapter->ahw->port_type == QLCNIC_XGBE) { if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS)) return; pause->rx_pause = 1; @@ -515,7 +515,7 @@ qlcnic_get_pauseparam(struct net_device *netdev, pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val)); } else { dev_err(&netdev->dev, "Unknown board type: %x\n", - adapter->ahw.port_type); + adapter->ahw->port_type); } } @@ -528,7 +528,7 @@ qlcnic_set_pauseparam(struct net_device *netdev, __u32 val; /* read mode */ - if (adapter->ahw.port_type == QLCNIC_GBE) { + if (adapter->ahw->port_type == QLCNIC_GBE) { if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS)) return -EIO; /* set flow control */ @@ -571,7 +571,7 @@ qlcnic_set_pauseparam(struct net_device *netdev, break; } QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val); - } else if (adapter->ahw.port_type == QLCNIC_XGBE) { + } else if (adapter->ahw->port_type == QLCNIC_XGBE) { if (!pause->rx_pause || pause->autoneg) return -EOPNOTSUPP; @@ -593,7 +593,7 @@ qlcnic_set_pauseparam(struct net_device *netdev, QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val); } else { dev_err(&netdev->dev, "Unknown board type: %x\n", - adapter->ahw.port_type); + adapter->ahw->port_type); } return 0; } @@ -639,8 +639,8 @@ static int qlcnic_irq_test(struct net_device *netdev) goto clear_it; adapter->diag_cnt = 0; - ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, - adapter->fw_hal_version, adapter->portnum, + ret = qlcnic_issue_cmd(adapter, adapter->ahw->pci_func, + adapter->fw_hal_version, adapter->ahw->pci_func, 0, 0, 0x00000011); if (ret) goto done; @@ -749,14 +749,14 @@ qlcnic_get_ethtool_stats(struct net_device *dev, return; memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics)); - ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func, + ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func, QLCNIC_QUERY_RX_COUNTER, &port_stats.rx); if (ret) return; qlcnic_fill_device_stats(&index, data, &port_stats.rx); - ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func, + ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func, QLCNIC_QUERY_TX_COUNTER, &port_stats.tx); if (ret) return; diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 616940f0a8d0..7e3f52690e3f 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -457,7 +457,7 @@ int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); - word = QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE | + word = QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE | ((u64)adapter->portnum << 16); req.req_hdr = cpu_to_le64(word); @@ -780,7 +780,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter, m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)]; if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) { - *addr = adapter->ahw.pci_base0 + m->start_2M + + *addr = adapter->ahw->pci_base0 + m->start_2M + (off - m->start_128M); return 0; } @@ -788,7 +788,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter, /* * Not in direct map, use crb window */ - *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + (off & MASK(16)); + *addr = adapter->ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16)); return 1; } @@ -801,7 +801,7 @@ static int qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off) { u32 window; - void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M; + void __iomem *addr = adapter->ahw->pci_base0 + CRB_WINDOW_2M; off -= QLCNIC_PCI_CRBSPACE; @@ -838,13 +838,13 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data) if (rv > 0) { /* indirect access */ - write_lock_irqsave(&adapter->ahw.crb_lock, flags); + write_lock_irqsave(&adapter->ahw->crb_lock, flags); crb_win_lock(adapter); rv = qlcnic_pci_set_crbwindow_2M(adapter, off); if (!rv) writel(data, addr); crb_win_unlock(adapter); - write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); + write_unlock_irqrestore(&adapter->ahw->crb_lock, flags); return rv; } @@ -869,12 +869,12 @@ qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) if (rv > 0) { /* indirect access */ - write_lock_irqsave(&adapter->ahw.crb_lock, flags); + write_lock_irqsave(&adapter->ahw->crb_lock, flags); crb_win_lock(adapter); if (!qlcnic_pci_set_crbwindow_2M(adapter, off)) data = readl(addr); crb_win_unlock(adapter); - write_unlock_irqrestore(&adapter->ahw.crb_lock, flags); + write_unlock_irqrestore(&adapter->ahw->crb_lock, flags); return data; } @@ -904,9 +904,9 @@ qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter, window = OCM_WIN_P3P(addr); - writel(window, adapter->ahw.ocm_win_crb); + writel(window, adapter->ahw->ocm_win_crb); /* read back to flush */ - readl(adapter->ahw.ocm_win_crb); + readl(adapter->ahw->ocm_win_crb); *start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr); return 0; @@ -920,13 +920,13 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, int ret; u32 start; - mutex_lock(&adapter->ahw.mem_lock); + mutex_lock(&adapter->ahw->mem_lock); ret = qlcnic_pci_set_window_2M(adapter, off, &start); if (ret != 0) goto unlock; - addr = adapter->ahw.pci_base0 + start; + addr = adapter->ahw->pci_base0 + start; if (op == 0) /* read */ *data = readq(addr); @@ -934,7 +934,7 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, writeq(*data, addr); unlock: - mutex_unlock(&adapter->ahw.mem_lock); + mutex_unlock(&adapter->ahw->mem_lock); return ret; } @@ -942,23 +942,23 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, void qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) { - void __iomem *addr = adapter->ahw.pci_base0 + + void __iomem *addr = adapter->ahw->pci_base0 + QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); - mutex_lock(&adapter->ahw.mem_lock); + mutex_lock(&adapter->ahw->mem_lock); *data = readq(addr); - mutex_unlock(&adapter->ahw.mem_lock); + mutex_unlock(&adapter->ahw->mem_lock); } void qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) { - void __iomem *addr = adapter->ahw.pci_base0 + + void __iomem *addr = adapter->ahw->pci_base0 + QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); - mutex_lock(&adapter->ahw.mem_lock); + mutex_lock(&adapter->ahw->mem_lock); writeq(data, addr); - mutex_unlock(&adapter->ahw.mem_lock); + mutex_unlock(&adapter->ahw->mem_lock); } #define MAX_CTL_CHECK 1000 @@ -997,7 +997,7 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, correct: off8 = off & ~0xf; - mutex_lock(&adapter->ahw.mem_lock); + mutex_lock(&adapter->ahw->mem_lock); writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); @@ -1049,7 +1049,7 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, ret = 0; done: - mutex_unlock(&adapter->ahw.mem_lock); + mutex_unlock(&adapter->ahw->mem_lock); return ret; } @@ -1091,7 +1091,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, correct: off8 = off & ~0xf; - mutex_lock(&adapter->ahw.mem_lock); + mutex_lock(&adapter->ahw->mem_lock); writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); @@ -1121,7 +1121,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, ret = 0; } - mutex_unlock(&adapter->ahw.mem_lock); + mutex_unlock(&adapter->ahw->mem_lock); return ret; } @@ -1145,7 +1145,7 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter) if (qlcnic_rom_fast_read(adapter, offset, &board_type)) return -EIO; - adapter->ahw.board_type = board_type; + adapter->ahw->board_type = board_type; if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) { u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I); @@ -1164,20 +1164,20 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter) case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: case QLCNIC_BRDTYPE_P3P_10G_XFP: case QLCNIC_BRDTYPE_P3P_10000_BASE_T: - adapter->ahw.port_type = QLCNIC_XGBE; + adapter->ahw->port_type = QLCNIC_XGBE; break; case QLCNIC_BRDTYPE_P3P_REF_QG: case QLCNIC_BRDTYPE_P3P_4_GB: case QLCNIC_BRDTYPE_P3P_4_GB_MM: - adapter->ahw.port_type = QLCNIC_GBE; + adapter->ahw->port_type = QLCNIC_GBE; break; case QLCNIC_BRDTYPE_P3P_10G_TP: - adapter->ahw.port_type = (adapter->portnum < 2) ? + adapter->ahw->port_type = (adapter->portnum < 2) ? QLCNIC_XGBE : QLCNIC_GBE; break; default: dev_err(&pdev->dev, "unknown board type %x\n", board_type); - adapter->ahw.port_type = QLCNIC_XGBE; + adapter->ahw->port_type = QLCNIC_XGBE; break; } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index a7f1d5b7e811..476ea14c0ff3 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -94,7 +94,7 @@ void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter) struct qlcnic_rx_buffer *rx_buf; int i, ring; - recv_ctx = &adapter->recv_ctx; + recv_ctx = adapter->recv_ctx; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; for (i = 0; i < rds_ring->num_desc; ++i) { @@ -119,7 +119,7 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter) struct qlcnic_rx_buffer *rx_buf; int i, ring; - recv_ctx = &adapter->recv_ctx; + recv_ctx = adapter->recv_ctx; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; @@ -173,7 +173,7 @@ void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter) struct qlcnic_host_tx_ring *tx_ring; int ring; - recv_ctx = &adapter->recv_ctx; + recv_ctx = adapter->recv_ctx; if (recv_ctx->rds_rings == NULL) goto skip_rds; @@ -226,7 +226,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) } tx_ring->cmd_buf_arr = cmd_buf_arr; - recv_ctx = &adapter->recv_ctx; + recv_ctx = adapter->recv_ctx; size = adapter->max_rds_rings * sizeof(struct qlcnic_host_rds_ring); rds_ring = kzalloc(size, GFP_KERNEL); @@ -864,7 +864,7 @@ qlcnic_validate_product_offs(struct qlcnic_adapter *adapter) for (i = 0; i < entries; i++) { __le32 flags, file_chiprev, offs; - u8 chiprev = adapter->ahw.revision_id; + u8 chiprev = adapter->ahw->revision_id; u32 flagbit; offs = cpu_to_le32(ptab_descr->findex) + @@ -1394,7 +1394,7 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, return skb; } -static int +static inline int qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb, u16 *vlan_tag) { @@ -1425,7 +1425,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, int ring, u64 sts_data0) { struct net_device *netdev = adapter->netdev; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + 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; @@ -1488,7 +1488,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, int ring, u64 sts_data0, u64 sts_data1) { struct net_device *netdev = adapter->netdev; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + 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; @@ -1625,7 +1625,7 @@ qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max) for (ring = 0; ring < adapter->max_rds_rings; ring++) { struct qlcnic_host_rds_ring *rds_ring = - &adapter->recv_ctx.rds_rings[ring]; + &adapter->recv_ctx->rds_rings[ring]; if (!list_empty(&sds_ring->free_list[ring])) { list_for_each(cur, &sds_ring->free_list[ring]) { @@ -1651,12 +1651,13 @@ qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max) } void -qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, +qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, struct qlcnic_host_rds_ring *rds_ring) { struct rcv_desc *pdesc; struct qlcnic_rx_buffer *buffer; - int producer, count = 0; + int count = 0; + u32 producer; struct list_head *head; producer = rds_ring->producer; @@ -1696,7 +1697,8 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, { struct rcv_desc *pdesc; struct qlcnic_rx_buffer *buffer; - int producer, count = 0; + int count = 0; + uint32_t producer; struct list_head *head; if (!spin_trylock(&rds_ring->lock)) diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index de6f86681a3c..dde7e4403830 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -113,7 +113,7 @@ static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl); -void +inline void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, struct qlcnic_host_tx_ring *tx_ring) { @@ -169,7 +169,7 @@ qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev) { int ring; struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) return -ENOMEM; @@ -193,14 +193,14 @@ qlcnic_napi_del(struct qlcnic_adapter *adapter) { int ring; struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; netif_napi_del(&sds_ring->napi); } - qlcnic_free_sds_rings(&adapter->recv_ctx); + qlcnic_free_sds_rings(adapter->recv_ctx); } static void @@ -208,7 +208,7 @@ qlcnic_napi_enable(struct qlcnic_adapter *adapter) { int ring; struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) return; @@ -225,7 +225,7 @@ qlcnic_napi_disable(struct qlcnic_adapter *adapter) { int ring; struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) return; @@ -359,7 +359,7 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter) struct pci_dev *pdev = adapter->pdev; int err, num_msix; - if (adapter->rss_supported) { + if (adapter->msix_supported) { num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ? MSIX_ENTRIES_PER_ADAPTER : 2; } else @@ -369,7 +369,7 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter) adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); - legacy_intrp = &legacy_intr[adapter->ahw.pci_func]; + legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; adapter->int_vec_bit = legacy_intrp->int_vec_bit; adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter, @@ -391,8 +391,7 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter) adapter->flags |= QLCNIC_MSIX_ENABLED; qlcnic_set_msix_bit(pdev, 1); - if (adapter->rss_supported) - adapter->max_sds_rings = num_msix; + adapter->max_sds_rings = num_msix; dev_info(&pdev->dev, "using msi-x interrupts\n"); return; @@ -407,7 +406,7 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter) if (use_msi && !pci_enable_msi(pdev)) { adapter->flags |= QLCNIC_MSI_ENABLED; adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter, - msi_tgt_status[adapter->ahw.pci_func]); + msi_tgt_status[adapter->ahw->pci_func]); dev_info(&pdev->dev, "using msi interrupts\n"); adapter->msix_entries[0].vector = pdev->irq; return; @@ -429,8 +428,8 @@ qlcnic_teardown_intr(struct qlcnic_adapter *adapter) static void qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) { - if (adapter->ahw.pci_base0 != NULL) - iounmap(adapter->ahw.pci_base0); + if (adapter->ahw->pci_base0 != NULL) + iounmap(adapter->ahw->pci_base0); } static int @@ -500,7 +499,7 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) u32 ref_count; int i, ret = 1; u32 data = QLCNIC_MGMT_FUNC; - void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; + void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; /* If other drivers are not in use set their privilege level */ ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); @@ -512,16 +511,16 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { id = i; if (adapter->npars[i].type != QLCNIC_TYPE_NIC || - id == adapter->ahw.pci_func) + id == adapter->ahw->pci_func) continue; data |= (qlcnic_config_npars & QLC_DEV_SET_DRV(0xf, id)); } } else { data = readl(priv_op); - data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw.pci_func)) | + data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) | (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, - adapter->ahw.pci_func)); + adapter->ahw->pci_func)); } writel(data, priv_op); qlcnic_api_unlock(adapter); @@ -539,22 +538,23 @@ qlcnic_check_vf(struct qlcnic_adapter *adapter) u32 op_mode, priv_level; /* Determine FW API version */ - adapter->fw_hal_version = readl(adapter->ahw.pci_base0 + QLCNIC_FW_API); + adapter->fw_hal_version = readl(adapter->ahw->pci_base0 + + QLCNIC_FW_API); /* Find PCI function number */ pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func); - msix_base_addr = adapter->ahw.pci_base0 + QLCNIC_MSIX_BASE; + msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE; msix_base = readl(msix_base_addr); func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; - adapter->ahw.pci_func = func; + adapter->ahw->pci_func = func; /* Determine function privilege level */ - priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; + priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; op_mode = readl(priv_op); if (op_mode == QLC_DEV_DRV_DEFAULT) priv_level = QLCNIC_MGMT_FUNC; else - priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); if (priv_level == QLCNIC_NON_PRIV_FUNC) { adapter->op_mode = QLCNIC_NON_PRIV_FUNC; @@ -593,13 +593,14 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); - adapter->ahw.pci_base0 = mem_ptr0; - adapter->ahw.pci_len0 = pci_len0; + adapter->ahw->pci_base0 = mem_ptr0; + adapter->ahw->pci_len0 = pci_len0; qlcnic_check_vf(adapter); - adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, - QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); + adapter->ahw->ocm_win_crb = qlcnic_get_ioaddr(adapter, + QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG( + adapter->ahw->pci_func))); return 0; } @@ -641,7 +642,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) dev_info(&pdev->dev, "firmware v%d.%d.%d\n", fw_major, fw_minor, fw_build); - if (adapter->ahw.port_type == QLCNIC_XGBE) { + if (adapter->ahw->port_type == QLCNIC_XGBE) { if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF; @@ -653,7 +654,7 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; - } else if (adapter->ahw.port_type == QLCNIC_GBE) { + } else if (adapter->ahw->port_type == QLCNIC_GBE) { adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G; adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; @@ -661,7 +662,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) } adapter->msix_supported = !!use_msi_x; - adapter->rss_supported = !!use_msi_x; adapter->num_txd = MAX_CMD_DESCRIPTORS; @@ -674,7 +674,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) int err; struct qlcnic_info nic_info; - err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func); + err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func); if (err) return err; @@ -736,7 +736,7 @@ qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) return 0; - esw_cfg.pci_func = adapter->ahw.pci_func; + esw_cfg.pci_func = adapter->ahw->pci_func; if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) return -EIO; qlcnic_set_vlan_config(adapter, &esw_cfg); @@ -793,14 +793,14 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) return 0; - priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; + priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; op_mode = readl(priv_op); - priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); if (op_mode == QLC_DEV_DRV_DEFAULT) priv_level = QLCNIC_MGMT_FUNC; else - priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { if (priv_level == QLCNIC_MGMT_FUNC) { @@ -1040,7 +1040,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) unsigned long flags = 0; struct net_device *netdev = adapter->netdev; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { handler = qlcnic_tmp_intr; @@ -1077,7 +1077,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter) int ring; struct qlcnic_host_sds_ring *sds_ring; - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; @@ -1117,14 +1117,14 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) return -EIO; for (ring = 0; ring < adapter->max_rds_rings; ring++) { - rds_ring = &adapter->recv_ctx.rds_rings[ring]; - qlcnic_post_rx_buffers(adapter, ring, rds_ring); + rds_ring = &adapter->recv_ctx->rds_rings[ring]; + qlcnic_post_rx_buffers(adapter, rds_ring); } qlcnic_set_multi(netdev); qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu); - adapter->ahw.linkup = 0; + adapter->ahw->linkup = 0; if (adapter->max_sds_rings > 1) qlcnic_config_rss(adapter, 1); @@ -1274,7 +1274,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) clear_bit(__QLCNIC_DEV_UP, &adapter->state); if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { for (ring = 0; ring < adapter->max_sds_rings; ring++) { - sds_ring = &adapter->recv_ctx.sds_rings[ring]; + sds_ring = &adapter->recv_ctx->sds_rings[ring]; qlcnic_disable_int(sds_ring); } } @@ -1295,6 +1295,39 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) netif_device_attach(netdev); } +static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) +{ + int err = 0; + adapter->ahw = kzalloc(sizeof(struct qlcnic_hardware_context), + GFP_KERNEL); + if (!adapter->ahw) { + dev_err(&adapter->pdev->dev, + "Failed to allocate recv ctx resources for adapter\n"); + err = -ENOMEM; + goto err_out; + } + adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), + GFP_KERNEL); + if (!adapter->recv_ctx) { + dev_err(&adapter->pdev->dev, + "Failed to allocate recv ctx resources for adapter\n"); + kfree(adapter->ahw); + adapter->ahw = NULL; + err = -ENOMEM; + } +err_out: + return err; +} + +static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) +{ + kfree(adapter->recv_ctx); + adapter->recv_ctx = NULL; + + kfree(adapter->ahw); + adapter->ahw = NULL; +} + int qlcnic_diag_alloc_res(struct net_device *netdev, int test) { struct qlcnic_adapter *adapter = netdev_priv(netdev); @@ -1327,13 +1360,13 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) } for (ring = 0; ring < adapter->max_rds_rings; ring++) { - rds_ring = &adapter->recv_ctx.rds_rings[ring]; - qlcnic_post_rx_buffers(adapter, ring, rds_ring); + rds_ring = &adapter->recv_ctx->rds_rings[ring]; + qlcnic_post_rx_buffers(adapter, rds_ring); } if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { for (ring = 0; ring < adapter->max_sds_rings; ring++) { - sds_ring = &adapter->recv_ctx.sds_rings[ring]; + sds_ring = &adapter->recv_ctx->sds_rings[ring]; qlcnic_enable_int(sds_ring); } } @@ -1503,23 +1536,26 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter = netdev_priv(netdev); adapter->netdev = netdev; adapter->pdev = pdev; - adapter->dev_rst_time = jiffies; + if (qlcnic_alloc_adapter_resources(adapter)) + goto err_out_free_netdev; + + adapter->dev_rst_time = jiffies; revision_id = pdev->revision; - adapter->ahw.revision_id = revision_id; + adapter->ahw->revision_id = revision_id; - rwlock_init(&adapter->ahw.crb_lock); - mutex_init(&adapter->ahw.mem_lock); + rwlock_init(&adapter->ahw->crb_lock); + mutex_init(&adapter->ahw->mem_lock); spin_lock_init(&adapter->tx_clean_lock); INIT_LIST_HEAD(&adapter->mac_list); err = qlcnic_setup_pci_map(adapter); if (err) - goto err_out_free_netdev; + goto err_out_free_hw; /* This will be reset for mezz cards */ - adapter->portnum = adapter->ahw.pci_func; + adapter->portnum = adapter->ahw->pci_func; err = qlcnic_get_board_info(adapter); if (err) { @@ -1547,7 +1583,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pr_info("%s: %s Board Chip rev 0x%x\n", module_name(THIS_MODULE), - brd_name, adapter->ahw.revision_id); + brd_name, adapter->ahw->revision_id); } qlcnic_clear_stats(adapter); @@ -1562,7 +1598,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); - switch (adapter->ahw.port_type) { + switch (adapter->ahw->port_type) { case QLCNIC_GBE: dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n", adapter->netdev->name); @@ -1587,6 +1623,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_out_iounmap: qlcnic_cleanup_pci_map(adapter); +err_out_free_hw: + qlcnic_free_adapter_resources(adapter); + err_out_free_netdev: free_netdev(netdev); @@ -1640,6 +1679,7 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); + qlcnic_free_adapter_resources(adapter); free_netdev(netdev); } static int __qlcnic_shutdown(struct pci_dev *pdev) @@ -2248,16 +2288,16 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) { struct net_device *netdev = adapter->netdev; - if (adapter->ahw.linkup && !linkup) { + if (adapter->ahw->linkup && !linkup) { netdev_info(netdev, "NIC Link is down\n"); - adapter->ahw.linkup = 0; + adapter->ahw->linkup = 0; if (netif_running(netdev)) { netif_carrier_off(netdev); netif_stop_queue(netdev); } - } else if (!adapter->ahw.linkup && linkup) { + } else if (!adapter->ahw->linkup && linkup) { netdev_info(netdev, "NIC Link is up\n"); - adapter->ahw.linkup = 1; + adapter->ahw->linkup = 1; if (netif_running(netdev)) { netif_carrier_on(netdev); netif_wake_queue(netdev); @@ -2493,7 +2533,7 @@ static void qlcnic_poll_controller(struct net_device *netdev) int ring; struct qlcnic_host_sds_ring *sds_ring; struct qlcnic_adapter *adapter = netdev_priv(netdev); - struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; + struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; disable_irq(adapter->irq); for (ring = 0; ring < adapter->max_sds_rings; ring++) { @@ -3503,7 +3543,7 @@ validate_esw_config(struct qlcnic_adapter *adapter, u8 pci_func; int i; - op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE); + op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; @@ -3569,13 +3609,13 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) return QL_STATUS_INVALID_PARAM; - if (adapter->ahw.pci_func != esw_cfg[i].pci_func) + if (adapter->ahw->pci_func != esw_cfg[i].pci_func) continue; op_mode = esw_cfg[i].op_mode; qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]); esw_cfg[i].op_mode = op_mode; - esw_cfg[i].pci_func = adapter->ahw.pci_func; + esw_cfg[i].pci_func = adapter->ahw->pci_func; switch (esw_cfg[i].op_mode) { case QLCNIC_PORT_DEFAULTS: -- GitLab From 036d61f05189c9c02de22dd19a1c64a4fd74a914 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Fri, 1 Apr 2011 14:28:11 +0000 Subject: [PATCH 0531/5560] qlcnic: Code optimization patch Optimized code resulted in achieving lower CPU utilization on transmit path and higher throughput for small packet sizes (64 bytes). Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 30 +++-- drivers/net/qlcnic/qlcnic_main.c | 210 +++++++++++++++---------------- 2 files changed, 115 insertions(+), 125 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 15d950a4f46d..a5b28d1475b1 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -434,50 +434,49 @@ struct qlcnic_adapter_stats { * be one Rcv Descriptor for normal packets, one for jumbo and may be others. */ struct qlcnic_host_rds_ring { - u32 producer; + void __iomem *crb_rcv_producer; + struct rcv_desc *desc_head; + struct qlcnic_rx_buffer *rx_buf_arr; u32 num_desc; + u32 producer; u32 dma_size; u32 skb_size; u32 flags; - void __iomem *crb_rcv_producer; - struct rcv_desc *desc_head; - struct qlcnic_rx_buffer *rx_buf_arr; struct list_head free_list; spinlock_t lock; dma_addr_t phys_addr; -}; +} ____cacheline_internodealigned_in_smp; struct qlcnic_host_sds_ring { u32 consumer; u32 num_desc; void __iomem *crb_sts_consumer; - void __iomem *crb_intr_mask; struct status_desc *desc_head; struct qlcnic_adapter *adapter; struct napi_struct napi; struct list_head free_list[NUM_RCV_DESC_RINGS]; + void __iomem *crb_intr_mask; int irq; dma_addr_t phys_addr; char name[IFNAMSIZ+4]; -}; +} ____cacheline_internodealigned_in_smp; struct qlcnic_host_tx_ring { u32 producer; - __le32 *hw_consumer; u32 sw_consumer; - void __iomem *crb_cmd_producer; u32 num_desc; - - struct netdev_queue *txq; - - struct qlcnic_cmd_buffer *cmd_buf_arr; + void __iomem *crb_cmd_producer; struct cmd_desc_type0 *desc_head; + struct qlcnic_cmd_buffer *cmd_buf_arr; + __le32 *hw_consumer; + dma_addr_t phys_addr; dma_addr_t hw_cons_phys_addr; -}; + struct netdev_queue *txq; +} ____cacheline_internodealigned_in_smp; /* * Receive context. There is one such structure per instance of the @@ -1328,8 +1327,7 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring) { - smp_mb(); - if (tx_ring->producer < tx_ring->sw_consumer) + if (likely(tx_ring->producer < tx_ring->sw_consumer)) return tx_ring->sw_consumer - tx_ring->producer; else return tx_ring->sw_consumer + tx_ring->num_desc - diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index dde7e4403830..3b740f55ca42 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1861,6 +1861,7 @@ static void qlcnic_change_filter(struct qlcnic_adapter *adapter, vlan_req->vlan_id = vlan_id; tx_ring->producer = get_next_index(producer, tx_ring->num_desc); + smp_mb(); } #define QLCNIC_MAC_HASH(MAC)\ @@ -1921,58 +1922,122 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, spin_unlock(&adapter->mac_learn_lock); } -static void -qlcnic_tso_check(struct net_device *netdev, - struct qlcnic_host_tx_ring *tx_ring, +static int +qlcnic_tx_pkt(struct qlcnic_adapter *adapter, struct cmd_desc_type0 *first_desc, struct sk_buff *skb) { - u8 opcode = TX_ETHER_PKT; - __be16 protocol = skb->protocol; - u16 flags = 0; - int copied, offset, copy_len, hdr_len = 0, tso = 0; + u8 opcode = 0, hdr_len = 0; + u16 flags = 0, vlan_tci = 0; + int copied, offset, copy_len; struct cmd_desc_type0 *hwdesc; struct vlan_ethhdr *vh; - struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; + u16 protocol = ntohs(skb->protocol); u32 producer = tx_ring->producer; - __le16 vlan_oob = first_desc->flags_opcode & - cpu_to_le16(FLAGS_VLAN_OOB); + + if (protocol == ETH_P_8021Q) { + vh = (struct vlan_ethhdr *)skb->data; + flags = FLAGS_VLAN_TAGGED; + vlan_tci = vh->h_vlan_TCI; + } else if (vlan_tx_tag_present(skb)) { + flags = FLAGS_VLAN_OOB; + vlan_tci = vlan_tx_tag_get(skb); + } + if (unlikely(adapter->pvid)) { + if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED)) + return -EIO; + if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED)) + goto set_flags; + + flags = FLAGS_VLAN_OOB; + vlan_tci = adapter->pvid; + } +set_flags: + qlcnic_set_tx_vlan_tci(first_desc, vlan_tci); + qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); if (*(skb->data) & BIT_0) { flags |= BIT_0; memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); } - - if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + opcode = TX_ETHER_PKT; + if ((adapter->netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && skb_shinfo(skb)->gso_size > 0) { hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); first_desc->total_hdr_length = hdr_len; - if (vlan_oob) { + + opcode = (protocol == ETH_P_IPV6) ? TX_TCP_LSO6 : TX_TCP_LSO; + + /* For LSO, we need to copy the MAC/IP/TCP headers into + * the descriptor ring */ + copied = 0; + offset = 2; + + if (flags & FLAGS_VLAN_OOB) { first_desc->total_hdr_length += VLAN_HLEN; first_desc->tcp_hdr_offset = VLAN_HLEN; first_desc->ip_hdr_offset = VLAN_HLEN; /* Only in case of TSO on vlan device */ flags |= FLAGS_VLAN_TAGGED; + + /* Create a TSO vlan header template for firmware */ + + hwdesc = &tx_ring->desc_head[producer]; + tx_ring->cmd_buf_arr[producer].skb = NULL; + + copy_len = min((int)sizeof(struct cmd_desc_type0) - + offset, hdr_len + VLAN_HLEN); + + vh = (struct vlan_ethhdr *)((char *) hwdesc + 2); + skb_copy_from_linear_data(skb, vh, 12); + vh->h_vlan_proto = htons(ETH_P_8021Q); + vh->h_vlan_TCI = htons(vlan_tci); + + skb_copy_from_linear_data_offset(skb, 12, + (char *)vh + 16, copy_len - 16); + + copied = copy_len - VLAN_HLEN; + offset = 0; + + producer = get_next_index(producer, tx_ring->num_desc); } - opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ? - TX_TCP_LSO6 : TX_TCP_LSO; - tso = 1; + while (copied < hdr_len) { + + copy_len = min((int)sizeof(struct cmd_desc_type0) - + offset, (hdr_len - copied)); + + hwdesc = &tx_ring->desc_head[producer]; + tx_ring->cmd_buf_arr[producer].skb = NULL; + + skb_copy_from_linear_data_offset(skb, copied, + (char *) hwdesc + offset, copy_len); + + copied += copy_len; + offset = 0; + + producer = get_next_index(producer, tx_ring->num_desc); + } + + tx_ring->producer = producer; + smp_mb(); + adapter->stats.lso_frames++; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { u8 l4proto; - if (protocol == cpu_to_be16(ETH_P_IP)) { + if (protocol == ETH_P_IP) { l4proto = ip_hdr(skb)->protocol; if (l4proto == IPPROTO_TCP) opcode = TX_TCP_PKT; else if (l4proto == IPPROTO_UDP) opcode = TX_UDP_PKT; - } else if (protocol == cpu_to_be16(ETH_P_IPV6)) { + } else if (protocol == ETH_P_IPV6) { l4proto = ipv6_hdr(skb)->nexthdr; if (l4proto == IPPROTO_TCP) @@ -1981,63 +2046,11 @@ qlcnic_tso_check(struct net_device *netdev, opcode = TX_UDPV6_PKT; } } - first_desc->tcp_hdr_offset += skb_transport_offset(skb); first_desc->ip_hdr_offset += skb_network_offset(skb); qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); - if (!tso) - return; - - /* For LSO, we need to copy the MAC/IP/TCP headers into - * the descriptor ring - */ - copied = 0; - offset = 2; - - if (vlan_oob) { - /* Create a TSO vlan header template for firmware */ - - hwdesc = &tx_ring->desc_head[producer]; - tx_ring->cmd_buf_arr[producer].skb = NULL; - - copy_len = min((int)sizeof(struct cmd_desc_type0) - offset, - hdr_len + VLAN_HLEN); - - vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); - skb_copy_from_linear_data(skb, vh, 12); - vh->h_vlan_proto = htons(ETH_P_8021Q); - vh->h_vlan_TCI = (__be16)swab16((u16)first_desc->vlan_TCI); - - skb_copy_from_linear_data_offset(skb, 12, - (char *)vh + 16, copy_len - 16); - - copied = copy_len - VLAN_HLEN; - offset = 0; - - producer = get_next_index(producer, tx_ring->num_desc); - } - - while (copied < hdr_len) { - - copy_len = min((int)sizeof(struct cmd_desc_type0) - offset, - (hdr_len - copied)); - - hwdesc = &tx_ring->desc_head[producer]; - tx_ring->cmd_buf_arr[producer].skb = NULL; - - skb_copy_from_linear_data_offset(skb, copied, - (char *)hwdesc + offset, copy_len); - - copied += copy_len; - offset = 0; - - producer = get_next_index(producer, tx_ring->num_desc); - } - - tx_ring->producer = producer; - barrier(); - adapter->stats.lso_frames++; + return 0; } static int @@ -2088,39 +2101,21 @@ qlcnic_map_tx_skb(struct pci_dev *pdev, return -ENOMEM; } -static int -qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter, - struct sk_buff *skb, - struct cmd_desc_type0 *first_desc) +static void +qlcnic_unmap_buffers(struct pci_dev *pdev, struct sk_buff *skb, + struct qlcnic_cmd_buffer *pbuf) { - u8 opcode = 0; - u16 flags = 0; - __be16 protocol = skb->protocol; - struct vlan_ethhdr *vh; + struct qlcnic_skb_frag *nf = &pbuf->frag_array[0]; + int nr_frags = skb_shinfo(skb)->nr_frags; + int i; - if (protocol == cpu_to_be16(ETH_P_8021Q)) { - vh = (struct vlan_ethhdr *)skb->data; - protocol = vh->h_vlan_encapsulated_proto; - flags = FLAGS_VLAN_TAGGED; - qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI)); - } else if (vlan_tx_tag_present(skb)) { - flags = FLAGS_VLAN_OOB; - qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb)); + for (i = 0; i < nr_frags; i++) { + nf = &pbuf->frag_array[i+1]; + pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); } - if (unlikely(adapter->pvid)) { - if (first_desc->vlan_TCI && - !(adapter->flags & QLCNIC_TAGGING_ENABLED)) - return -EIO; - if (first_desc->vlan_TCI && - (adapter->flags & QLCNIC_TAGGING_ENABLED)) - goto set_flags; - flags = FLAGS_VLAN_OOB; - qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid); - } -set_flags: - qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); - return 0; + nf = &pbuf->frag_array[0]; + pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); } static inline void @@ -2144,7 +2139,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) int i, k; u32 producer; - int frag_count, no_of_desc; + int frag_count; u32 num_txd = tx_ring->num_desc; if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { @@ -2161,12 +2156,8 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) frag_count = skb_shinfo(skb)->nr_frags + 1; - /* 4 fragments per cmd des */ - no_of_desc = (frag_count + 3) >> 2; - if (unlikely(qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH)) { netif_stop_queue(netdev); - smp_mb(); if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) netif_start_queue(netdev); else { @@ -2183,9 +2174,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) first_desc = hwdesc = &tx_ring->desc_head[producer]; qlcnic_clear_cmddesc((u64 *)hwdesc); - if (qlcnic_check_tx_tagging(adapter, skb, first_desc)) - goto drop_packet; - if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { adapter->stats.tx_dma_map_error++; goto drop_packet; @@ -2229,8 +2217,10 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } tx_ring->producer = get_next_index(producer, num_txd); + smp_mb(); - qlcnic_tso_check(netdev, tx_ring, first_desc, skb); + if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb))) + goto unwind_buff; if (qlcnic_mac_learn) qlcnic_send_filter(adapter, tx_ring, first_desc, skb); @@ -2242,6 +2232,8 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; +unwind_buff: + qlcnic_unmap_buffers(pdev, skb, pbuf); drop_packet: adapter->stats.txdropped++; dev_kfree_skb_any(skb); -- GitLab From b9796a14d9705c4be4a080a4fe39379a51681374 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Fri, 1 Apr 2011 14:28:15 +0000 Subject: [PATCH 0532/5560] qlcnic: Changes to VLAN code Made changes to VLAN code comply with new VLAN infrastructure in kernel Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ++- drivers/net/qlcnic/qlcnic_init.c | 15 ++++++------ drivers/net/qlcnic/qlcnic_main.c | 42 +++++++++++++++++++------------- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index a5b28d1475b1..be9c32944de5 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -29,6 +29,8 @@ #include #include +#include +#include #include "qlcnic_hdr.h" @@ -982,8 +984,8 @@ struct qlcnic_adapter { u8 mac_addr[ETH_ALEN]; u64 dev_rst_time; + unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)]; - struct vlan_group *vlgrp; struct qlcnic_npar_info *npars; struct qlcnic_eswitch *eswitch; struct qlcnic_nic_template *nic_ops; diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 476ea14c0ff3..74ec96da1762 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1467,10 +1467,10 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, skb->protocol = eth_type_trans(skb, netdev); - if ((vid != 0xffff) && adapter->vlgrp) - vlan_gro_receive(&sds_ring->napi, adapter->vlgrp, vid, skb); - else - napi_gro_receive(&sds_ring->napi, skb); + if (vid != 0xffff) + __vlan_hwaccel_put_tag(skb, vid); + + napi_gro_receive(&sds_ring->napi, skb); adapter->stats.rx_pkts++; adapter->stats.rxbytes += length; @@ -1552,10 +1552,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, length = skb->len; - if ((vid != 0xffff) && adapter->vlgrp) - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid); - else - netif_receive_skb(skb); + if (vid != 0xffff) + __vlan_hwaccel_put_tag(skb, vid); + netif_receive_skb(skb); adapter->stats.lro_pkts++; adapter->stats.lrobytes += length; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 3b740f55ca42..b75aef059adc 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -98,6 +97,9 @@ static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); static int qlcnicvf_start_firmware(struct qlcnic_adapter *); static void qlcnic_set_netdev_features(struct qlcnic_adapter *, struct qlcnic_esw_func_cfg *); +static void qlcnic_vlan_rx_add(struct net_device *, u16); +static void qlcnic_vlan_rx_del(struct net_device *, u16); + /* PCI Device ID Table */ #define ENTRY(device) \ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ @@ -317,13 +319,6 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) return 0; } -static void qlcnic_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct qlcnic_adapter *adapter = netdev_priv(netdev); - adapter->vlgrp = grp; -} - static const struct net_device_ops qlcnic_netdev_ops = { .ndo_open = qlcnic_open, .ndo_stop = qlcnic_close, @@ -334,7 +329,8 @@ static const struct net_device_ops qlcnic_netdev_ops = { .ndo_set_mac_address = qlcnic_set_mac, .ndo_change_mtu = qlcnic_change_mtu, .ndo_tx_timeout = qlcnic_tx_timeout, - .ndo_vlan_rx_register = qlcnic_vlan_rx_register, + .ndo_vlan_rx_add_vid = qlcnic_vlan_rx_add, + .ndo_vlan_rx_kill_vid = qlcnic_vlan_rx_del, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = qlcnic_poll_controller, #endif @@ -709,6 +705,22 @@ qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, adapter->pvid = 0; } +static void +qlcnic_vlan_rx_add(struct net_device *netdev, u16 vid) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + set_bit(vid, adapter->vlans); +} + +static void +qlcnic_vlan_rx_del(struct net_device *netdev, u16 vid) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + + qlcnic_restore_indev_addr(netdev, NETDEV_DOWN); + clear_bit(vid, adapter->vlans); +} + static void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, struct qlcnic_esw_func_cfg *esw_cfg) @@ -755,7 +767,7 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO); vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM); + NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER); if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) { features |= (NETIF_F_TSO | NETIF_F_TSO6); @@ -1448,7 +1460,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX); netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM); + NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER); if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) { netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); @@ -4068,14 +4080,10 @@ qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) qlcnic_config_indev_addr(adapter, netdev, event); - if (!adapter->vlgrp) - return; - - for (vid = 0; vid < VLAN_N_VID; vid++) { - dev = vlan_group_get_device(adapter->vlgrp, vid); + for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) { + dev = vlan_find_dev(netdev, vid); if (!dev) continue; - qlcnic_config_indev_addr(adapter, dev, event); } } -- GitLab From 8816d0099b9c0f48452b69471c2f54037f7e0e3b Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Fri, 1 Apr 2011 14:28:21 +0000 Subject: [PATCH 0533/5560] qlcnic: Remove unused code Cleaned up unused codes for interrupt coalescence settings Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 56 +++++++++++------------------ drivers/net/qlcnic/qlcnic_ethtool.c | 30 ++++++---------- drivers/net/qlcnic/qlcnic_hw.c | 20 +++++------ drivers/net/qlcnic/qlcnic_main.c | 21 +++-------- 4 files changed, 46 insertions(+), 81 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index be9c32944de5..9d2e630c3895 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -391,6 +391,25 @@ struct qlcnic_rx_buffer { #define QLCNIC_GBE 0x01 #define QLCNIC_XGBE 0x02 +/* + * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is + * adjusted based on configured MTU. + */ +#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3 +#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256 + +#define QLCNIC_INTR_DEFAULT 0x04 +#define QLCNIC_CONFIG_INTR_COALESCE 3 + +struct qlcnic_nic_intr_coalesce { + u8 type; + u8 sts_ring_mask; + u16 rx_packets; + u16 rx_time_us; + u16 flag; + u32 timer_out; +}; + /* * One hardware_context{} per adapter * contains interrupt info as well shared hardware info. @@ -409,6 +428,8 @@ struct qlcnic_hardware_context { u8 linkup; u16 port_type; u16 board_type; + + struct qlcnic_nic_intr_coalesce coal; }; struct qlcnic_adapter_stats { @@ -721,40 +742,6 @@ struct qlcnic_mac_list_s { uint8_t mac_addr[ETH_ALEN+2]; }; -/* - * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is - * adjusted based on configured MTU. - */ -#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3 -#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256 -#define QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS 64 -#define QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US 4 - -#define QLCNIC_INTR_DEFAULT 0x04 - -union qlcnic_nic_intr_coalesce_data { - struct { - u16 rx_packets; - u16 rx_time_us; - u16 tx_packets; - u16 tx_time_us; - } data; - u64 word; -}; - -struct qlcnic_nic_intr_coalesce { - u16 stats_time_us; - u16 rate_sample_time; - u16 flags; - u16 rsvd_1; - u32 low_threshold; - u32 high_threshold; - union qlcnic_nic_intr_coalesce_data normal; - union qlcnic_nic_intr_coalesce_data low; - union qlcnic_nic_intr_coalesce_data high; - union qlcnic_nic_intr_coalesce_data irq; -}; - #define QLCNIC_HOST_REQUEST 0x13 #define QLCNIC_REQUEST 0x14 @@ -1002,7 +989,6 @@ struct qlcnic_adapter { struct delayed_work fw_work; - struct qlcnic_nic_intr_coalesce coal; struct qlcnic_filter_hash fhash; diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 7e53cad6be16..24a79a6fc73d 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -936,8 +936,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, */ if (ethcoal->rx_coalesce_usecs > 0xffff || ethcoal->rx_max_coalesced_frames > 0xffff || - ethcoal->tx_coalesce_usecs > 0xffff || - ethcoal->tx_max_coalesced_frames > 0xffff || + ethcoal->tx_coalesce_usecs || + ethcoal->tx_max_coalesced_frames || ethcoal->rx_coalesce_usecs_irq || ethcoal->rx_max_coalesced_frames_irq || ethcoal->tx_coalesce_usecs_irq || @@ -959,21 +959,17 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, if (!ethcoal->rx_coalesce_usecs || !ethcoal->rx_max_coalesced_frames) { - adapter->coal.flags = QLCNIC_INTR_DEFAULT; - adapter->coal.normal.data.rx_time_us = + adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; + adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; - adapter->coal.normal.data.rx_packets = + adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; } else { - adapter->coal.flags = 0; - adapter->coal.normal.data.rx_time_us = - ethcoal->rx_coalesce_usecs; - adapter->coal.normal.data.rx_packets = - ethcoal->rx_max_coalesced_frames; + adapter->ahw->coal.flag = 0; + adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs; + adapter->ahw->coal.rx_packets = + ethcoal->rx_max_coalesced_frames; } - adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs; - adapter->coal.normal.data.tx_packets = - ethcoal->tx_max_coalesced_frames; qlcnic_config_intr_coalesce(adapter); @@ -988,12 +984,8 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev, if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) return -EINVAL; - ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us; - ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us; - ethcoal->rx_max_coalesced_frames = - adapter->coal.normal.data.rx_packets; - ethcoal->tx_max_coalesced_frames = - adapter->coal.normal.data.tx_packets; + ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; + ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets; return 0; } diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 7e3f52690e3f..3901be85dcac 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -532,33 +532,31 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) } } -#define QLCNIC_CONFIG_INTR_COALESCE 3 - /* * Send the interrupt coalescing parameter set by ethtool to the card. */ int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) { struct qlcnic_nic_req req; - u64 word[6]; - int rv, i; + int rv; memset(&req, 0, sizeof(struct qlcnic_nic_req)); req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); - word[0] = QLCNIC_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); - req.req_hdr = cpu_to_le64(word[0]); - - memcpy(&word[0], &adapter->coal, sizeof(adapter->coal)); - for (i = 0; i < 6; i++) - req.words[i] = cpu_to_le64(word[i]); + req.req_hdr = cpu_to_le64(QLCNIC_CONFIG_INTR_COALESCE | + ((u64) adapter->portnum << 16)); + req.words[0] = cpu_to_le64(((u64) adapter->ahw->coal.flag) << 32); + req.words[2] = cpu_to_le64(adapter->ahw->coal.rx_packets | + ((u64) adapter->ahw->coal.rx_time_us) << 16); + req.words[5] = cpu_to_le64(adapter->ahw->coal.timer_out | + ((u64) adapter->ahw->coal.type) << 32 | + ((u64) adapter->ahw->coal.sts_ring_mask) << 40); rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) dev_err(&adapter->netdev->dev, "Could not send interrupt coalescing parameters\n"); - return rv; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index b75aef059adc..8bf9a968f7f2 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1097,20 +1097,6 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter) } } -static void -qlcnic_init_coalesce_defaults(struct qlcnic_adapter *adapter) -{ - adapter->coal.flags = QLCNIC_INTR_DEFAULT; - adapter->coal.normal.data.rx_time_us = - QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; - adapter->coal.normal.data.rx_packets = - QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; - adapter->coal.normal.data.tx_time_us = - QLCNIC_DEFAULT_INTR_COALESCE_TX_TIME_US; - adapter->coal.normal.data.tx_packets = - QLCNIC_DEFAULT_INTR_COALESCE_TX_PACKETS; -} - static int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) { @@ -1244,8 +1230,6 @@ qlcnic_attach(struct qlcnic_adapter *adapter) goto err_out_free_hw; } - qlcnic_init_coalesce_defaults(adapter); - qlcnic_create_sysfs_entries(adapter); adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; @@ -1326,7 +1310,12 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) kfree(adapter->ahw); adapter->ahw = NULL; err = -ENOMEM; + goto err_out; } + /* Initialize interrupt coalesce parameters */ + adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; + adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; + adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; err_out: return err; } -- GitLab From f8d54811cb125094769704722e4eda6610339b92 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Fri, 1 Apr 2011 14:28:26 +0000 Subject: [PATCH 0534/5560] qlcnic: Use flt method to determine flash fw region Use flash layout table to get flash fw starting address and its size. If that fails, use legacy method. Signed-off-by: Sritej Velaga Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 3 ++- drivers/net/qlcnic/qlcnic_init.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9d2e630c3895..d9dd2c40c92f 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -292,6 +292,7 @@ struct uni_data_desc{ /* Flash Defines and Structures */ #define QLCNIC_FLT_LOCATION 0x3F1000 #define QLCNIC_FW_IMAGE_REGION 0x74 +#define QLCNIC_BOOTLD_REGION 0X72 struct qlcnic_flt_header { u16 version; u16 len; @@ -306,7 +307,7 @@ struct qlcnic_flt_entry { u8 reserved1; u32 size; u32 start_addr; - u32 end_add; + u32 end_addr; }; /* Magic number to let user know flash is programmed */ diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 74ec96da1762..4ec0eeb6bff9 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1130,9 +1130,20 @@ qlcnic_load_firmware(struct qlcnic_adapter *adapter) } else { u64 data; u32 hi, lo; - - size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8; - flashaddr = QLCNIC_BOOTLD_START; + int ret; + struct qlcnic_flt_entry bootld_entry; + + ret = qlcnic_get_flt_entry(adapter, QLCNIC_BOOTLD_REGION, + &bootld_entry); + if (!ret) { + size = bootld_entry.size / 8; + flashaddr = bootld_entry.start_addr; + } else { + size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8; + flashaddr = QLCNIC_BOOTLD_START; + dev_info(&pdev->dev, + "using legacy method to get flash fw region"); + } for (i = 0; i < size; i++) { if (qlcnic_rom_fast_read(adapter, -- GitLab From b56421d0b7527f8ecea3de030cf508468fdc9ba1 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Fri, 1 Apr 2011 14:28:31 +0000 Subject: [PATCH 0535/5560] qlcnic: Fix LRO disable o In dev->open LRO was enabled by default, enable it depending upon netdev->features , kernel may have disabled it. o Configure LRO when interface is up. Signed-off-by: Rajesh Borundia Signed-off-by: Anirban Chakraborty Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_ethtool.c | 26 ++++++++++++++++---------- drivers/net/qlcnic/qlcnic_hw.c | 6 ++++++ drivers/net/qlcnic/qlcnic_main.c | 3 ++- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 24a79a6fc73d..6be4d5a26c7c 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -998,22 +998,28 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) return -EINVAL; - if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) - return -EINVAL; + if (data & ETH_FLAG_LRO) { - if (!adapter->rx_csum) { - dev_info(&adapter->pdev->dev, "rx csum is off, " - "cannot toggle lro\n"); - return -EINVAL; - } + if (netdev->features & NETIF_F_LRO) + return 0; - if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO)) - return 0; + if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) + return -EINVAL; + + if (!adapter->rx_csum) { + dev_info(&adapter->pdev->dev, "rx csum is off, " + "cannot toggle lro\n"); + return -EINVAL; + } - if (data & ETH_FLAG_LRO) { hw_lro = QLCNIC_LRO_ENABLED; netdev->features |= NETIF_F_LRO; + } else { + + if (!(netdev->features & NETIF_F_LRO)) + return 0; + hw_lro = 0; netdev->features &= ~NETIF_F_LRO; } diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 3901be85dcac..498cca92126a 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -566,6 +566,9 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) u64 word; int rv; + if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) + return 0; + memset(&req, 0, sizeof(struct qlcnic_nic_req)); req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); @@ -711,6 +714,9 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter) u64 word; int rv; + if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) + return 0; + memset(&req, 0, sizeof(struct qlcnic_nic_req)); req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 8bf9a968f7f2..7f9edb2f1474 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -773,7 +773,8 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, features |= (NETIF_F_TSO | NETIF_F_TSO6); vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); } - if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) + + if (netdev->features & NETIF_F_LRO) features |= NETIF_F_LRO; if (esw_cfg->offload_flags & BIT_0) { -- GitLab From 191350e7887aa6d843f1097fc1de06cb59eb6ac1 Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Fri, 1 Apr 2011 14:28:36 +0000 Subject: [PATCH 0536/5560] qlcnic: Update version number to 5.0.16 Bumped up version number to 5.0.16 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 d9dd2c40c92f..dc6f7c69acac 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -36,8 +36,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 15 -#define QLCNIC_LINUX_VERSIONID "5.0.15" +#define _QLCNIC_LINUX_SUBVERSION 16 +#define QLCNIC_LINUX_VERSIONID "5.0.16" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) -- GitLab From d66f1886cab1b6539b0a54fb2ecc24ae830d103c Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 6 Apr 2011 22:34:00 +0200 Subject: [PATCH 0537/5560] openezx-devel is moderated for non-subscribers Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ed224e091a50..fa5bc3bbbc22 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -725,7 +725,7 @@ ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6) M: Daniel Ribeiro M: Stefan Schmidt M: Harald Welte -L: openezx-devel@lists.openezx.org (subscribers-only) +L: openezx-devel@lists.openezx.org (moderated for non-subscribers) W: http://www.openezx.org/ S: Maintained T: topgit git://git.openezx.org/openezx.git -- GitLab From 74e532ff3c634f20ee2eefe3f8f0083ea547c74c Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 08:43:41 +0000 Subject: [PATCH 0538/5560] sky2: support ethtool set_phys_id Use ethtool set_phys_id to control LED. Fixes issues with RTNL being held for extended periods. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/sky2.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2a91868788f7..afc925a340d1 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3826,23 +3826,24 @@ static void sky2_led(struct sky2_port *sky2, enum led_mode mode) } /* blink LED's for finding board */ -static int sky2_phys_id(struct net_device *dev, u32 data) +static int sky2_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct sky2_port *sky2 = netdev_priv(dev); - unsigned int i; - - if (data == 0) - data = UINT_MAX; - for (i = 0; i < data; i++) { + switch (state) { + case ETHTOOL_ID_ACTIVE: + return -EINVAL; + case ETHTOOL_ID_INACTIVE: + sky2_led(sky2, MO_LED_NORM); + break; + case ETHTOOL_ID_ON: sky2_led(sky2, MO_LED_ON); - if (msleep_interruptible(500)) - break; + break; + case ETHTOOL_ID_OFF: sky2_led(sky2, MO_LED_OFF); - if (msleep_interruptible(500)) - break; + break; } - sky2_led(sky2, MO_LED_NORM); return 0; } @@ -4269,7 +4270,7 @@ static const struct ethtool_ops sky2_ethtool_ops = { .set_ringparam = sky2_set_ringparam, .get_pauseparam = sky2_get_pauseparam, .set_pauseparam = sky2_set_pauseparam, - .phys_id = sky2_phys_id, + .set_phys_id = sky2_set_phys_id, .get_sset_count = sky2_get_sset_count, .get_ethtool_stats = sky2_get_ethtool_stats, .set_flags = sky2_set_flags, -- GitLab From a5b9f41c228f93d368ab0f292d890ea7143ca5aa Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 08:43:42 +0000 Subject: [PATCH 0539/5560] skge: implement set_phys_id Implement set_phys_id led control on SysKonnect board. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/skge.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 35b28f42d208..e579ff7579ad 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -786,28 +786,27 @@ static void skge_led(struct skge_port *skge, enum led_mode mode) } /* blink LED's for finding board */ -static int skge_phys_id(struct net_device *dev, u32 data) +static int skge_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct skge_port *skge = netdev_priv(dev); - unsigned long ms; - enum led_mode mode = LED_MODE_TST; - if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) - ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000; - else - ms = data * 1000; + switch (state) { + case ETHTOOL_ID_ACTIVE: + return -EINVAL; - while (ms > 0) { - skge_led(skge, mode); - mode ^= LED_MODE_TST; + case ETHTOOL_ID_ON: + skge_led(skge, LED_MODE_TST); + break; - if (msleep_interruptible(BLINK_MS)) - break; - ms -= BLINK_MS; - } + case ETHTOOL_ID_OFF: + skge_led(skge, LED_MODE_OFF); + break; - /* back to regular LED state */ - skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF); + case ETHTOOL_ID_INACTIVE: + /* back to regular LED state */ + skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF); + } return 0; } @@ -930,7 +929,7 @@ static const struct ethtool_ops skge_ethtool_ops = { .get_rx_csum = skge_get_rx_csum, .set_rx_csum = skge_set_rx_csum, .get_strings = skge_get_strings, - .phys_id = skge_phys_id, + .set_phys_id = skge_set_phys_id, .get_sset_count = skge_get_sset_count, .get_ethtool_stats = skge_get_ethtool_stats, }; -- GitLab From 81b8709c25e8c8f56224a24d860de7b77a772e83 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 08:43:50 +0000 Subject: [PATCH 0540/5560] tg3: implement ethtool set_phys_id Implement control of LED via set_phys_id. Note: since PHY is powered off if device is down, this board only allows blinking if device is up. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/tg3.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f944c6b97dd6..d37ae8747ad1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10341,35 +10341,38 @@ static void tg3_get_strings(struct net_device *dev, u32 stringset, u8 *buf) } } -static int tg3_phys_id(struct net_device *dev, u32 data) +static int tg3_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct tg3 *tp = netdev_priv(dev); - int i; if (!netif_running(tp->dev)) return -EAGAIN; - if (data == 0) - data = UINT_MAX / 2; + switch (state) { + case ETHTOOL_ID_ACTIVE: + return -EINVAL; - for (i = 0; i < (data * 2); i++) { - if ((i % 2) == 0) - tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | - LED_CTRL_1000MBPS_ON | - LED_CTRL_100MBPS_ON | - LED_CTRL_10MBPS_ON | - LED_CTRL_TRAFFIC_OVERRIDE | - LED_CTRL_TRAFFIC_BLINK | - LED_CTRL_TRAFFIC_LED); + case ETHTOOL_ID_ON: + tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | + LED_CTRL_1000MBPS_ON | + LED_CTRL_100MBPS_ON | + LED_CTRL_10MBPS_ON | + LED_CTRL_TRAFFIC_OVERRIDE | + LED_CTRL_TRAFFIC_BLINK | + LED_CTRL_TRAFFIC_LED); + break; - else - tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | - LED_CTRL_TRAFFIC_OVERRIDE); + case ETHTOOL_ID_OFF: + tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | + LED_CTRL_TRAFFIC_OVERRIDE); + break; - if (msleep_interruptible(500)) - break; + case ETHTOOL_ID_INACTIVE: + tw32(MAC_LED_CTRL, tp->led_ctrl); + break; } - tw32(MAC_LED_CTRL, tp->led_ctrl); + return 0; } @@ -11394,7 +11397,7 @@ static const struct ethtool_ops tg3_ethtool_ops = { .set_tso = tg3_set_tso, .self_test = tg3_self_test, .get_strings = tg3_get_strings, - .phys_id = tg3_phys_id, + .set_phys_id = tg3_set_phys_id, .get_ethtool_stats = tg3_get_ethtool_stats, .get_coalesce = tg3_get_coalesce, .set_coalesce = tg3_set_coalesce, -- GitLab From 12fcf941674fd781117a56f998d2bb28b4bc4cf1 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 08:43:51 +0000 Subject: [PATCH 0541/5560] cxgb3: implement set_phys_id Implement new ethtool set_phys_id on Chelsio cxgb3 board. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 910893143295..802c7a7c3b25 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1749,23 +1749,26 @@ static int restart_autoneg(struct net_device *dev) return 0; } -static int cxgb3_phys_id(struct net_device *dev, u32 data) +static int set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - int i; - if (data == 0) - data = 2; + switch (state) { + case ETHTOOL_ID_ACTIVE: + return -EINVAL; + + case ETHTOOL_ID_OFF: + t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0); + break; - for (i = 0; i < data * 2; i++) { + case ETHTOOL_ID_ON: + case ETHTOOL_ID_INACTIVE: t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, - (i & 1) ? F_GPIO0_OUT_VAL : 0); - if (msleep_interruptible(500)) - break; - } - t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, F_GPIO0_OUT_VAL); + } + return 0; } @@ -2107,7 +2110,7 @@ static const struct ethtool_ops cxgb_ethtool_ops = { .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = get_strings, - .phys_id = cxgb3_phys_id, + .set_phys_id = set_phys_id, .nway_reset = restart_autoneg, .get_sset_count = get_sset_count, .get_ethtool_stats = get_stats, -- GitLab From 6d8a7e6f52b0bf646739f2d4bad4643c64977b2a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 11:06:35 +0000 Subject: [PATCH 0542/5560] vxge: convert to set_phys_id Also fix up incorrect docbook comment Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-ethtool.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index c5eb034107fd..43c458323f83 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -134,22 +134,29 @@ static void vxge_ethtool_gregs(struct net_device *dev, /** * vxge_ethtool_idnic - To physically identify the nic on the system. * @dev : device pointer. - * @id : pointer to the structure with identification parameters given by - * ethtool. + * @state : requested LED state * * Used to physically identify the NIC on the system. - * The Link LED will blink for a time specified by the user. - * Return value: * 0 on success */ -static int vxge_ethtool_idnic(struct net_device *dev, u32 data) +static int vxge_ethtool_idnic(struct net_device *dev, + enum ethtool_phys_id_state state) { struct vxgedev *vdev = netdev_priv(dev); 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); - vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF); + switch (state) { + case ETHTOOL_ID_ACTIVE: + vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON); + break; + + case ETHTOOL_ID_INACTIVE: + vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF); + break; + + default: + return -EINVAL; + } return 0; } @@ -1183,7 +1190,7 @@ static const struct ethtool_ops vxge_ethtool_ops = { .get_tso = ethtool_op_get_tso, .set_tso = vxge_ethtool_op_set_tso, .get_strings = vxge_ethtool_get_strings, - .phys_id = vxge_ethtool_idnic, + .set_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, -- GitLab From 2e17e1aa80e914acd8a31a41b9bf1173186a976a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 11:06:36 +0000 Subject: [PATCH 0543/5560] bnx2: convert to set_phys_id In this case, need to add element to device private to hold original led state. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 56 ++++++++++++++++++++++------------------------ drivers/net/bnx2.h | 1 + 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 8e6d618b5305..05ddfb18d5bf 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7495,41 +7495,39 @@ bnx2_get_ethtool_stats(struct net_device *dev, } static int -bnx2_phys_id(struct net_device *dev, u32 data) +bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) { struct bnx2 *bp = netdev_priv(dev); - int i; - u32 save; - bnx2_set_power_state(bp, PCI_D0); + switch (state) { + case ETHTOOL_ID_ACTIVE: + bnx2_set_power_state(bp, PCI_D0); - if (data == 0) - data = 2; + bp->leds_save = REG_RD(bp, BNX2_MISC_CFG); + REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); + return -EINVAL; - save = REG_RD(bp, BNX2_MISC_CFG); - REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); + case ETHTOOL_ID_ON: + REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | + BNX2_EMAC_LED_1000MB_OVERRIDE | + BNX2_EMAC_LED_100MB_OVERRIDE | + BNX2_EMAC_LED_10MB_OVERRIDE | + BNX2_EMAC_LED_TRAFFIC_OVERRIDE | + BNX2_EMAC_LED_TRAFFIC); + break; - for (i = 0; i < (data * 2); i++) { - if ((i % 2) == 0) { - REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); - } - else { - REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | - BNX2_EMAC_LED_1000MB_OVERRIDE | - BNX2_EMAC_LED_100MB_OVERRIDE | - BNX2_EMAC_LED_10MB_OVERRIDE | - BNX2_EMAC_LED_TRAFFIC_OVERRIDE | - BNX2_EMAC_LED_TRAFFIC); - } - msleep_interruptible(500); - if (signal_pending(current)) - break; - } - REG_WR(bp, BNX2_EMAC_LED, 0); - REG_WR(bp, BNX2_MISC_CFG, save); + case ETHTOOL_ID_OFF: + REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); + break; - if (!netif_running(dev)) - bnx2_set_power_state(bp, PCI_D3hot); + case ETHTOOL_ID_INACTIVE: + REG_WR(bp, BNX2_EMAC_LED, 0); + REG_WR(bp, BNX2_MISC_CFG, bp->leds_save); + + if (!netif_running(dev)) + bnx2_set_power_state(bp, PCI_D3hot); + break; + } return 0; } @@ -7602,7 +7600,7 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .set_tso = bnx2_set_tso, .self_test = bnx2_self_test, .get_strings = bnx2_get_strings, - .phys_id = bnx2_phys_id, + .set_phys_id = bnx2_set_phys_id, .get_ethtool_stats = bnx2_get_ethtool_stats, .get_sset_count = bnx2_get_sset_count, .set_flags = bnx2_set_flags, diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 68020451dc4f..91e83562238e 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6922,6 +6922,7 @@ struct bnx2 { u8 num_tx_rings; u8 num_rx_rings; + u32 leds_save; u32 idle_chk_status_idx; #ifdef BCM_CNIC -- GitLab From 32d3613475d8c7d2170313b9105499dece6a3735 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 11:06:37 +0000 Subject: [PATCH 0544/5560] bnx2x: convert to set_phys_id Also cleanup error codes to no lie about things that driver doesn't support. If device is down report -EAGAIN (same as Broadcom), and if port doesn't blink then error as well. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 44 ++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index f5050155c6b5..147999459df5 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -2097,36 +2097,38 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } } -static int bnx2x_phys_id(struct net_device *dev, u32 data) +static int bnx2x_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct bnx2x *bp = netdev_priv(dev); - int i; if (!netif_running(dev)) - return 0; + return -EAGAIN; if (!bp->port.pmf) - return 0; + return -EOPNOTSUPP; - if (data == 0) - data = 2; + switch (state) { + case ETHTOOL_ID_ACTIVE: + return -EINVAL; - for (i = 0; i < (data * 2); i++) { - if ((i % 2) == 0) - bnx2x_set_led(&bp->link_params, &bp->link_vars, - LED_MODE_OPER, SPEED_1000); - else - bnx2x_set_led(&bp->link_params, &bp->link_vars, - LED_MODE_OFF, 0); + case ETHTOOL_ID_ON: + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OPER, SPEED_1000); + break; - msleep_interruptible(500); - if (signal_pending(current)) - break; - } + case ETHTOOL_ID_OFF: + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OFF, 0); - if (bp->link_vars.link_up) - bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER, - bp->link_vars.line_speed); + break; + + case ETHTOOL_ID_INACTIVE: + if (bp->link_vars.link_up) + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OPER, + bp->link_vars.line_speed); + } return 0; } @@ -2218,7 +2220,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .self_test = bnx2x_self_test, .get_sset_count = bnx2x_get_sset_count, .get_strings = bnx2x_get_strings, - .phys_id = bnx2x_phys_id, + .set_phys_id = bnx2x_set_phys_id, .get_ethtool_stats = bnx2x_get_ethtool_stats, .get_rxnfc = bnx2x_get_rxnfc, .get_rxfh_indir = bnx2x_get_rxfh_indir, -- GitLab From 1a64246913849b0cef0be88c23381468ce169ab6 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 11:06:40 +0000 Subject: [PATCH 0545/5560] benet: convert to set_phys_id Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_ethtool.c | 38 +++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 3937bca3d431..0899d9122278 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -313,6 +313,7 @@ struct be_adapter { char fw_ver[FW_VER_LEN]; u32 if_handle; /* Used to configure filtering */ u32 pmac_id; /* MAC addr handle used by BE card */ + u32 beacon_state; /* for set_phys_id */ bool eeh_err; bool link_up; diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 575ac659ceb4..a665697df824 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -526,29 +526,33 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) } static int -be_phys_id(struct net_device *netdev, u32 data) +be_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) { struct be_adapter *adapter = netdev_priv(netdev); - int status; - u32 cur; - - be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &cur); - if (cur == BEACON_STATE_ENABLED) - return 0; + switch (state) { + case ETHTOOL_ID_ACTIVE: + be_cmd_get_beacon_state(adapter, adapter->hba_port_num, + &adapter->beacon_state); + return -EINVAL; - if (data < 2) - data = 2; + case ETHTOOL_ID_ON: + be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, + BEACON_STATE_ENABLED); + break; - status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, - BEACON_STATE_ENABLED); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(data*HZ); + case ETHTOOL_ID_OFF: + be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, + BEACON_STATE_DISABLED); + break; - status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, - BEACON_STATE_DISABLED); + case ETHTOOL_ID_INACTIVE: + be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, + adapter->beacon_state); + } - return status; + return 0; } static bool @@ -753,7 +757,7 @@ const struct ethtool_ops be_ethtool_ops = { .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, .get_strings = be_get_stat_strings, - .phys_id = be_phys_id, + .set_phys_id = be_set_phys_id, .get_sset_count = be_get_sset_count, .get_ethtool_stats = be_get_ethtool_stats, .get_regs_len = be_get_reg_len, -- GitLab From 9871acf67c9af89c1e17aee907a3f36e88ccfb67 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 11:06:41 +0000 Subject: [PATCH 0546/5560] pcnet32: convert to set_phys_id Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/pcnet32.c | 74 ++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 46 deletions(-) diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index aee3bb0358bf..eb7ac4e48c71 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -295,12 +295,14 @@ struct pcnet32_private { struct net_device *next; struct mii_if_info mii_if; struct timer_list watchdog_timer; - struct timer_list blink_timer; u32 msg_enable; /* debug message level */ /* each bit indicates an available PHY */ u32 phymask; unsigned short chip_version; /* which variant this is */ + + /* saved registers during ethtool blink */ + u16 save_regs[4]; }; static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); @@ -324,8 +326,6 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits); static void pcnet32_ethtool_test(struct net_device *dev, struct ethtool_test *eth_test, u64 * data); static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1); -static int pcnet32_phys_id(struct net_device *dev, u32 data); -static void pcnet32_led_blink_callback(struct net_device *dev); static int pcnet32_get_regs_len(struct net_device *dev); static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *ptr); @@ -1022,7 +1022,8 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) return rc; } /* end pcnet32_loopback_test */ -static void pcnet32_led_blink_callback(struct net_device *dev) +static int pcnet32_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct pcnet32_private *lp = netdev_priv(dev); struct pcnet32_access *a = &lp->a; @@ -1030,50 +1031,31 @@ static void pcnet32_led_blink_callback(struct net_device *dev) unsigned long flags; int i; - spin_lock_irqsave(&lp->lock, flags); - for (i = 4; i < 8; i++) - a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000); - spin_unlock_irqrestore(&lp->lock, flags); - - mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT); -} + switch (state) { + case ETHTOOL_ID_ACTIVE: + /* Save the current value of the bcrs */ + spin_lock_irqsave(&lp->lock, flags); + for (i = 4; i < 8; i++) + lp->save_regs[i - 4] = a->read_bcr(ioaddr, i); + spin_unlock_irqrestore(&lp->lock, flags); + return -EINVAL; -static int pcnet32_phys_id(struct net_device *dev, u32 data) -{ - struct pcnet32_private *lp = netdev_priv(dev); - struct pcnet32_access *a = &lp->a; - ulong ioaddr = dev->base_addr; - unsigned long flags; - int i, regs[4]; + case ETHTOOL_ID_ON: + case ETHTOOL_ID_OFF: + /* Blink the led */ + spin_lock_irqsave(&lp->lock, flags); + for (i = 4; i < 8; i++) + a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000); + spin_unlock_irqrestore(&lp->lock, flags); + break; - if (!lp->blink_timer.function) { - init_timer(&lp->blink_timer); - lp->blink_timer.function = (void *)pcnet32_led_blink_callback; - lp->blink_timer.data = (unsigned long)dev; + case ETHTOOL_ID_INACTIVE: + /* Restore the original value of the bcrs */ + spin_lock_irqsave(&lp->lock, flags); + for (i = 4; i < 8; i++) + a->write_bcr(ioaddr, i, lp->save_regs[i - 4]); + spin_unlock_irqrestore(&lp->lock, flags); } - - /* Save the current value of the bcrs */ - spin_lock_irqsave(&lp->lock, flags); - for (i = 4; i < 8; i++) - regs[i - 4] = a->read_bcr(ioaddr, i); - spin_unlock_irqrestore(&lp->lock, flags); - - mod_timer(&lp->blink_timer, jiffies); - set_current_state(TASK_INTERRUPTIBLE); - - /* AV: the limit here makes no sense whatsoever */ - if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))) - data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ); - - msleep_interruptible(data * 1000); - del_timer_sync(&lp->blink_timer); - - /* Restore the original value of the bcrs */ - spin_lock_irqsave(&lp->lock, flags); - for (i = 4; i < 8; i++) - a->write_bcr(ioaddr, i, regs[i - 4]); - spin_unlock_irqrestore(&lp->lock, flags); - return 0; } @@ -1450,7 +1432,7 @@ static const struct ethtool_ops pcnet32_ethtool_ops = { .set_ringparam = pcnet32_set_ringparam, .get_strings = pcnet32_get_strings, .self_test = pcnet32_ethtool_test, - .phys_id = pcnet32_phys_id, + .set_phys_id = pcnet32_set_phys_id, .get_regs_len = pcnet32_get_regs_len, .get_regs = pcnet32_get_regs, .get_sset_count = pcnet32_get_sset_count, -- GitLab From 7bc93714042418cbc4ca89c51d3ab448ea3ef2fe Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 12:31:19 +0000 Subject: [PATCH 0547/5560] niu: convert to new ethtool set_phys_id Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/niu.c | 29 ++++++++++++++++------------- drivers/net/niu.h | 1 + 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 681a42ca5c51..ab4e7dd82d0b 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7888,28 +7888,31 @@ static void niu_force_led(struct niu *np, int on) nw64_mac(reg, val); } -static int niu_phys_id(struct net_device *dev, u32 data) +static int niu_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) + { struct niu *np = netdev_priv(dev); - u64 orig_led_state; - int i; if (!netif_running(dev)) return -EAGAIN; - if (data == 0) - data = 2; + switch (state) { + case ETHTOOL_ID_ACTIVE: + np->orig_led_state = niu_led_state_save(np); + return -EINVAL; - orig_led_state = niu_led_state_save(np); - for (i = 0; i < (data * 2); i++) { - int on = ((i % 2) == 0); + case ETHTOOL_ID_ON: + niu_force_led(np, 1); + break; - niu_force_led(np, on); + case ETHTOOL_ID_OFF: + niu_force_led(np, 0); + break; - if (msleep_interruptible(500)) - break; + case ETHTOOL_ID_INACTIVE: + niu_led_state_restore(np, np->orig_led_state); } - niu_led_state_restore(np, orig_led_state); return 0; } @@ -7932,7 +7935,7 @@ static const struct ethtool_ops niu_ethtool_ops = { .get_strings = niu_get_strings, .get_sset_count = niu_get_sset_count, .get_ethtool_stats = niu_get_ethtool_stats, - .phys_id = niu_phys_id, + .set_phys_id = niu_set_phys_id, .get_rxnfc = niu_get_nfc, .set_rxnfc = niu_set_nfc, .set_flags = niu_set_flags, diff --git a/drivers/net/niu.h b/drivers/net/niu.h index a41fa8ebe05f..51e177e1860d 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -3279,6 +3279,7 @@ struct niu { unsigned long xpcs_off; struct timer_list timer; + u64 orig_led_state; const struct niu_phy_ops *phy_ops; int phy_addr; -- GitLab From 034e345081cfb442abeb0e00fa26edeedb5ba96a Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 4 Apr 2011 15:09:25 +0000 Subject: [PATCH 0548/5560] s2io: convert to set_phys_id (v2) Convert to new ethtool set physical id model. Remove no longer used timer, and fix docbook comment. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/s2io.c | 86 ++++++++++++++++++++++------------------------ drivers/net/s2io.h | 3 -- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 356e74d20b80..cae08edb833e 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5484,83 +5484,79 @@ static void s2io_ethtool_gregs(struct net_device *dev, } } -/** - * s2io_phy_id - timer function that alternates adapter LED. - * @data : address of the private member of the device structure, which - * is a pointer to the s2io_nic structure, provided as an u32. - * Description: This is actually the timer function that alternates the - * adapter LED bit of the adapter control bit to set/reset every time on - * invocation. The timer is set for 1/2 a second, hence tha NIC blinks - * once every second. +/* + * s2io_set_led - control NIC led */ -static void s2io_phy_id(unsigned long data) +static void s2io_set_led(struct s2io_nic *sp, bool on) { - struct s2io_nic *sp = (struct s2io_nic *)data; struct XENA_dev_config __iomem *bar0 = sp->bar0; - u64 val64 = 0; - u16 subid; + u16 subid = sp->pdev->subsystem_device; + u64 val64; - subid = sp->pdev->subsystem_device; if ((sp->device_type == XFRAME_II_DEVICE) || ((subid & 0xFF) >= 0x07)) { val64 = readq(&bar0->gpio_control); - val64 ^= GPIO_CTRL_GPIO_0; + if (on) + val64 |= GPIO_CTRL_GPIO_0; + else + val64 &= ~GPIO_CTRL_GPIO_0; + writeq(val64, &bar0->gpio_control); } else { val64 = readq(&bar0->adapter_control); - val64 ^= ADAPTER_LED_ON; + if (on) + val64 |= ADAPTER_LED_ON; + else + val64 &= ~ADAPTER_LED_ON; + writeq(val64, &bar0->adapter_control); } - mod_timer(&sp->id_timer, jiffies + HZ / 2); } /** - * s2io_ethtool_idnic - To physically identify the nic on the system. - * @sp : private member of the device structure, which is a pointer to the - * s2io_nic structure. - * @id : pointer to the structure with identification parameters given by - * ethtool. + * s2io_ethtool_set_led - To physically identify the nic on the system. + * @dev : network device + * @state: led setting + * * Description: Used to physically identify the NIC on the system. * The Link LED will blink for a time specified by the user for * identification. * NOTE: The Link has to be Up to be able to blink the LED. Hence * identification is possible only if it's link is up. - * Return value: - * int , returns 0 on success */ -static int s2io_ethtool_idnic(struct net_device *dev, u32 data) +static int s2io_ethtool_set_led(struct net_device *dev, + enum ethtool_phys_id_state state) { - u64 val64 = 0, last_gpio_ctrl_val; struct s2io_nic *sp = netdev_priv(dev); struct XENA_dev_config __iomem *bar0 = sp->bar0; - u16 subid; + u16 subid = sp->pdev->subsystem_device; - subid = sp->pdev->subsystem_device; - last_gpio_ctrl_val = readq(&bar0->gpio_control); if ((sp->device_type == XFRAME_I_DEVICE) && ((subid & 0xFF) < 0x07)) { - val64 = readq(&bar0->adapter_control); + u64 val64 = readq(&bar0->adapter_control); if (!(val64 & ADAPTER_CNTL_EN)) { pr_err("Adapter Link down, cannot blink LED\n"); - return -EFAULT; + return -EAGAIN; } } - if (sp->id_timer.function == NULL) { - init_timer(&sp->id_timer); - sp->id_timer.function = s2io_phy_id; - sp->id_timer.data = (unsigned long)sp; - } - mod_timer(&sp->id_timer, jiffies); - if (data) - msleep_interruptible(data * HZ); - else - msleep_interruptible(MAX_FLICKER_TIME); - del_timer_sync(&sp->id_timer); - if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) { - writeq(last_gpio_ctrl_val, &bar0->gpio_control); - last_gpio_ctrl_val = readq(&bar0->gpio_control); + switch (state) { + case ETHTOOL_ID_ACTIVE: + sp->adapt_ctrl_org = readq(&bar0->gpio_control); + return -EINVAL; + + case ETHTOOL_ID_ON: + s2io_set_led(sp, true); + break; + + case ETHTOOL_ID_OFF: + s2io_set_led(sp, false); + break; + + case ETHTOOL_ID_INACTIVE: + if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) + writeq(sp->adapt_ctrl_org, &bar0->gpio_control); } return 0; @@ -6776,7 +6772,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { .set_ufo = ethtool_op_set_ufo, .self_test = s2io_ethtool_test, .get_strings = s2io_ethtool_get_strings, - .phys_id = s2io_ethtool_idnic, + .set_phys_id = s2io_ethtool_set_led, .get_ethtool_stats = s2io_get_ethtool_stats, .get_sset_count = s2io_get_sset_count, }; diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 7d160306b651..6b5c0231225c 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -893,9 +893,6 @@ struct s2io_nic { u16 all_multi_pos; u16 promisc_flg; - /* Id timer, used to blink NIC to physically identify NIC. */ - struct timer_list id_timer; - /* Restart timer, used to restart NIC if the device is stuck and * a schedule task that will set the correct Link state once the * NIC's PHY has stabilized after a state change. -- GitLab From 17938a6983d634a909d9779143a8dc2922720de5 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Sun, 3 Apr 2011 22:26:24 +0000 Subject: [PATCH 0549/5560] Signed bit field; int have_hotplug_status_watch:1 Fixes error from sparse: CHECK drivers/net/xen-netback/xenbus.c drivers/net/xen-netback/xenbus.c:29:40: error: dubious one-bit signed bitfield int have_hotplug_status_watch:1; Reported-by: Dr. David Alan Gilbert Signed-off-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netback/xenbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 22b8c3505991..1ce729d6af75 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -26,7 +26,7 @@ struct backend_info { struct xenvif *vif; enum xenbus_state frontend_state; struct xenbus_watch hotplug_status_watch; - int have_hotplug_status_watch:1; + u8 have_hotplug_status_watch:1; }; static int connect_rings(struct backend_info *); -- GitLab From 1f90d6657c1ce2eaa4c7fbd1fb36738542f2b650 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 6 Apr 2011 10:58:37 +0000 Subject: [PATCH 0550/5560] capi: Perform scheduled capifs removal udev fully replaces this special file system that only contains CAPI NCCI TTY device nodes. User space (pppdcapiplugin) works without noticing the difference. Signed-off-by: Jan Kiszka Signed-off-by: David S. Miller --- Documentation/feature-removal-schedule.txt | 10 - drivers/isdn/capi/Kconfig | 15 -- drivers/isdn/capi/Makefile | 1 - drivers/isdn/capi/capi.c | 24 +-- drivers/isdn/capi/capifs.c | 239 --------------------- drivers/isdn/capi/capifs.h | 28 --- 6 files changed, 4 insertions(+), 313 deletions(-) delete mode 100644 drivers/isdn/capi/capifs.c delete mode 100644 drivers/isdn/capi/capifs.h diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 274b32d12532..e38ccae81710 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -425,16 +425,6 @@ Who: anybody or Florian Mickler ---------------------------- -What: capifs -When: February 2011 -Files: drivers/isdn/capi/capifs.* -Why: udev fully replaces this special file system that only contains CAPI - NCCI TTY device nodes. User space (pppdcapiplugin) works without - noticing the difference. -Who: Jan Kiszka - ----------------------------- - What: KVM paravirt mmu host support When: January 2011 Why: The paravirt mmu host support is slower than non-paravirt mmu, both diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig index a168e8a891be..15c3ffd9d860 100644 --- a/drivers/isdn/capi/Kconfig +++ b/drivers/isdn/capi/Kconfig @@ -33,21 +33,6 @@ config ISDN_CAPI_CAPI20 standardized libcapi20 to access this functionality. You should say Y/M here. -config ISDN_CAPI_CAPIFS_BOOL - bool "CAPI2.0 filesystem support (DEPRECATED)" - depends on ISDN_CAPI_MIDDLEWARE && ISDN_CAPI_CAPI20 - help - This option provides a special file system, similar to /dev/pts with - device nodes for the special ttys established by using the - middleware extension above. - You no longer need this, udev fully replaces it. This feature is - scheduled for removal. - -config ISDN_CAPI_CAPIFS - tristate - depends on ISDN_CAPI_CAPIFS_BOOL - default ISDN_CAPI_CAPI20 - config ISDN_CAPI_CAPIDRV tristate "CAPI2.0 capidrv interface support" depends on ISDN_I4L diff --git a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile index 57123e3e4978..4d5b4b71db1e 100644 --- a/drivers/isdn/capi/Makefile +++ b/drivers/isdn/capi/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o obj-$(CONFIG_ISDN_CAPI_CAPIDRV) += capidrv.o -obj-$(CONFIG_ISDN_CAPI_CAPIFS) += capifs.o # Multipart objects. diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 0d7088367038..bea100983336 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -38,8 +38,6 @@ #include #include -#include "capifs.h" - MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); @@ -85,7 +83,6 @@ struct capiminor { struct kref kref; unsigned int minor; - struct dentry *capifs_dentry; struct capi20_appl *ap; u32 ncci; @@ -300,17 +297,8 @@ static void capiminor_free(struct capiminor *mp) static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { - struct capiminor *mp; - dev_t device; - - if (!(cdev->userflags & CAPIFLAG_HIGHJACKING)) - return; - - mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci); - if (mp) { - device = MKDEV(capinc_tty_driver->major, mp->minor); - mp->capifs_dentry = capifs_new_ncci(mp->minor, device); - } + if (cdev->userflags & CAPIFLAG_HIGHJACKING) + np->minorp = capiminor_alloc(&cdev->ap, np->ncci); } static void capincci_free_minor(struct capincci *np) @@ -319,8 +307,6 @@ static void capincci_free_minor(struct capincci *np) struct tty_struct *tty; if (mp) { - capifs_free_ncci(mp->capifs_dentry); - tty = tty_port_tty_get(&mp->port); if (tty) { tty_vhangup(tty); @@ -1514,10 +1500,8 @@ static int __init capi_init(void) proc_init(); -#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) - compileinfo = " (middleware+capifs)"; -#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE) - compileinfo = " (no capifs)"; +#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE + compileinfo = " (middleware)"; #else compileinfo = " (no middleware)"; #endif diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c deleted file mode 100644 index b4faed7fe0d3..000000000000 --- a/drivers/isdn/capi/capifs.c +++ /dev/null @@ -1,239 +0,0 @@ -/* $Id: capifs.c,v 1.1.2.3 2004/01/16 21:09:26 keil Exp $ - * - * Copyright 2000 by Carsten Paeth - * - * Heavily based on devpts filesystem from H. Peter Anvin - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include /* current */ - -#include "capifs.h" - -MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem"); -MODULE_AUTHOR("Carsten Paeth"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------------ */ - -#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N') - -static struct vfsmount *capifs_mnt; -static int capifs_mnt_count; - -static struct { - int setuid; - int setgid; - uid_t uid; - gid_t gid; - umode_t mode; -} config = {.mode = 0600}; - -/* ------------------------------------------------------------------ */ - -static int capifs_remount(struct super_block *s, int *flags, char *data) -{ - int setuid = 0; - int setgid = 0; - uid_t uid = 0; - gid_t gid = 0; - umode_t mode = 0600; - char *this_char; - char *new_opt = kstrdup(data, GFP_KERNEL); - - this_char = NULL; - while ((this_char = strsep(&data, ",")) != NULL) { - int n; - char dummy; - if (!*this_char) - continue; - if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) { - setuid = 1; - uid = n; - } else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) { - setgid = 1; - gid = n; - } else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1) - mode = n & ~S_IFMT; - else { - kfree(new_opt); - printk("capifs: called with bogus options\n"); - return -EINVAL; - } - } - - mutex_lock(&s->s_root->d_inode->i_mutex); - - replace_mount_options(s, new_opt); - config.setuid = setuid; - config.setgid = setgid; - config.uid = uid; - config.gid = gid; - config.mode = mode; - - mutex_unlock(&s->s_root->d_inode->i_mutex); - - return 0; -} - -static const struct super_operations capifs_sops = -{ - .statfs = simple_statfs, - .remount_fs = capifs_remount, - .show_options = generic_show_options, -}; - - -static int -capifs_fill_super(struct super_block *s, void *data, int silent) -{ - struct inode * inode; - - s->s_blocksize = 1024; - s->s_blocksize_bits = 10; - s->s_magic = CAPIFS_SUPER_MAGIC; - s->s_op = &capifs_sops; - s->s_time_gran = 1; - - inode = new_inode(s); - if (!inode) - goto fail; - inode->i_ino = 1; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - inode->i_nlink = 2; - - s->s_root = d_alloc_root(inode); - if (s->s_root) - return 0; - - printk("capifs: get root dentry failed\n"); - iput(inode); -fail: - return -ENOMEM; -} - -static struct dentry *capifs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) -{ - return mount_single(fs_type, flags, data, capifs_fill_super); -} - -static struct file_system_type capifs_fs_type = { - .owner = THIS_MODULE, - .name = "capifs", - .mount = capifs_mount, - .kill_sb = kill_anon_super, -}; - -static struct dentry *new_ncci(unsigned int number, dev_t device) -{ - struct super_block *s = capifs_mnt->mnt_sb; - struct dentry *root = s->s_root; - struct dentry *dentry; - struct inode *inode; - char name[10]; - int namelen; - - mutex_lock(&root->d_inode->i_mutex); - - namelen = sprintf(name, "%d", number); - dentry = lookup_one_len(name, root, namelen); - if (IS_ERR(dentry)) { - dentry = NULL; - goto unlock_out; - } - - if (dentry->d_inode) { - dput(dentry); - dentry = NULL; - goto unlock_out; - } - - inode = new_inode(s); - if (!inode) { - dput(dentry); - dentry = NULL; - goto unlock_out; - } - - /* config contents is protected by root's i_mutex */ - inode->i_uid = config.setuid ? config.uid : current_fsuid(); - inode->i_gid = config.setgid ? config.gid : current_fsgid(); - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_ino = number + 2; - init_special_inode(inode, S_IFCHR|config.mode, device); - - d_instantiate(dentry, inode); - dget(dentry); - -unlock_out: - mutex_unlock(&root->d_inode->i_mutex); - - return dentry; -} - -struct dentry *capifs_new_ncci(unsigned int number, dev_t device) -{ - struct dentry *dentry; - - if (simple_pin_fs(&capifs_fs_type, &capifs_mnt, &capifs_mnt_count) < 0) - return NULL; - - dentry = new_ncci(number, device); - if (!dentry) - simple_release_fs(&capifs_mnt, &capifs_mnt_count); - - return dentry; -} - -void capifs_free_ncci(struct dentry *dentry) -{ - struct dentry *root = capifs_mnt->mnt_sb->s_root; - struct inode *inode; - - if (!dentry) - return; - - mutex_lock(&root->d_inode->i_mutex); - - inode = dentry->d_inode; - if (inode) { - drop_nlink(inode); - d_delete(dentry); - dput(dentry); - } - dput(dentry); - - mutex_unlock(&root->d_inode->i_mutex); - - simple_release_fs(&capifs_mnt, &capifs_mnt_count); -} - -static int __init capifs_init(void) -{ - return register_filesystem(&capifs_fs_type); -} - -static void __exit capifs_exit(void) -{ - unregister_filesystem(&capifs_fs_type); -} - -EXPORT_SYMBOL(capifs_new_ncci); -EXPORT_SYMBOL(capifs_free_ncci); - -module_init(capifs_init); -module_exit(capifs_exit); diff --git a/drivers/isdn/capi/capifs.h b/drivers/isdn/capi/capifs.h deleted file mode 100644 index e193d1189531..000000000000 --- a/drivers/isdn/capi/capifs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $Id: capifs.h,v 1.1.2.2 2004/01/16 21:09:26 keil Exp $ - * - * Copyright 2000 by Carsten Paeth - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - */ - -#include - -#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) - -struct dentry *capifs_new_ncci(unsigned int num, dev_t device); -void capifs_free_ncci(struct dentry *dentry); - -#else - -static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device) -{ - return NULL; -} - -static inline void capifs_free_ncci(struct dentry *dentry) -{ -} - -#endif -- GitLab From 066413dac420c8225e3ef7f0f76c3255448782d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 5 Apr 2011 01:36:58 +0000 Subject: [PATCH 0551/5560] net: netxen: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather simple conversion to hw_features. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 2 +- drivers/net/netxen/netxen_nic_ethtool.c | 102 ------------------------ drivers/net/netxen/netxen_nic_init.c | 3 +- drivers/net/netxen/netxen_nic_main.c | 53 +++++++++--- 4 files changed, 46 insertions(+), 114 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index d7299f1a4940..15595b3a54c6 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1177,7 +1177,7 @@ struct netxen_adapter { u8 max_sds_rings; u8 driver_mismatch; u8 msix_supported; - u8 rx_csum; + u8 __pad; u8 pci_using_dac; u8 portnum; u8 physical_port; diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 3bdcc803ec68..29f90baaa79b 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -676,62 +676,6 @@ netxen_nic_get_ethtool_stats(struct net_device *dev, } } -static u32 netxen_nic_get_tx_csum(struct net_device *dev) -{ - return dev->features & NETIF_F_IP_CSUM; -} - -static u32 netxen_nic_get_rx_csum(struct net_device *dev) -{ - struct netxen_adapter *adapter = netdev_priv(dev); - return adapter->rx_csum; -} - -static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data) -{ - struct netxen_adapter *adapter = netdev_priv(dev); - - 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; -} - -static u32 netxen_nic_get_tso(struct net_device *dev) -{ - struct netxen_adapter *adapter = netdev_priv(dev); - - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0; - - return (dev->features & NETIF_F_TSO) != 0; -} - -static int netxen_nic_set_tso(struct net_device *dev, u32 data) -{ - if (data) { - struct netxen_adapter *adapter = netdev_priv(dev); - - dev->features |= NETIF_F_TSO; - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - dev->features |= NETIF_F_TSO6; - } else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} - static void netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { @@ -866,43 +810,6 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } -static int netxen_nic_set_flags(struct net_device *netdev, u32 data) -{ - struct netxen_adapter *adapter = netdev_priv(netdev); - int hw_lro; - - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) - return -EINVAL; - - 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 = NETXEN_NIC_LRO_DISABLED; - netdev->features &= ~NETIF_F_LRO; - } - - if (netxen_config_hw_lro(adapter, hw_lro)) - return -EIO; - - if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter)) - return -EIO; - - - return 0; -} - const struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, @@ -916,21 +823,12 @@ const struct ethtool_ops netxen_nic_ethtool_ops = { .set_ringparam = netxen_nic_set_ringparam, .get_pauseparam = netxen_nic_get_pauseparam, .set_pauseparam = netxen_nic_set_pauseparam, - .get_tx_csum = netxen_nic_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .get_tso = netxen_nic_get_tso, - .set_tso = netxen_nic_set_tso, .get_wol = netxen_nic_get_wol, .set_wol = netxen_nic_set_wol, .self_test = netxen_nic_diag_test, .get_strings = netxen_nic_get_strings, .get_ethtool_stats = netxen_nic_get_ethtool_stats, .get_sset_count = netxen_get_sset_count, - .get_rx_csum = netxen_nic_get_rx_csum, - .set_rx_csum = netxen_nic_set_rx_csum, .get_coalesce = netxen_get_intr_coalesce, .set_coalesce = netxen_set_intr_coalesce, - .get_flags = ethtool_op_get_flags, - .set_flags = netxen_nic_set_flags, }; diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 731077d8d962..7f999671c7b2 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1483,7 +1483,8 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter, if (!skb) goto no_skb; - if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) { + if (likely((adapter->netdev->features & NETIF_F_RXCSUM) + && cksum == STATUS_CKSUM_OK)) { adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 933671556c15..201b944bd463 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -485,6 +485,37 @@ static void netxen_set_multicast_list(struct net_device *dev) adapter->set_multi(dev); } +static u32 netxen_fix_features(struct net_device *dev, u32 features) +{ + if (!(features & NETIF_F_RXCSUM)) { + netdev_info(dev, "disabling LRO as RXCSUM is off\n"); + + features &= ~NETIF_F_LRO; + } + + return features; +} + +static int netxen_set_features(struct net_device *dev, u32 features) +{ + struct netxen_adapter *adapter = netdev_priv(dev); + int hw_lro; + + if (!((dev->features ^ features) & NETIF_F_LRO)) + return 0; + + hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED + : NETXEN_NIC_LRO_DISABLED; + + if (netxen_config_hw_lro(adapter, hw_lro)) + return -EIO; + + if (!(features & NETIF_F_LRO) && netxen_send_lro_cleanup(adapter)) + return -EIO; + + return 0; +} + static const struct net_device_ops netxen_netdev_ops = { .ndo_open = netxen_nic_open, .ndo_stop = netxen_nic_close, @@ -495,6 +526,8 @@ static const struct net_device_ops netxen_netdev_ops = { .ndo_set_mac_address = netxen_nic_set_mac, .ndo_change_mtu = netxen_nic_change_mtu, .ndo_tx_timeout = netxen_tx_timeout, + .ndo_fix_features = netxen_fix_features, + .ndo_set_features = netxen_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = netxen_nic_poll_controller, #endif @@ -1196,7 +1229,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter, int err = 0; struct pci_dev *pdev = adapter->pdev; - adapter->rx_csum = 1; adapter->mc_enabled = 0; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) adapter->max_mc_count = 38; @@ -1210,14 +1242,13 @@ netxen_setup_netdev(struct netxen_adapter *adapter, SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); - netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); - netdev->features |= (NETIF_F_GRO); - netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_RXCSUM; - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); - netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); - } + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + + netdev->vlan_features |= netdev->hw_features; if (adapter->pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; @@ -1225,10 +1256,12 @@ netxen_setup_netdev(struct netxen_adapter *adapter, } if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX) - netdev->features |= (NETIF_F_HW_VLAN_TX); + netdev->hw_features |= NETIF_F_HW_VLAN_TX; if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO) - netdev->features |= NETIF_F_LRO; + netdev->hw_features |= NETIF_F_LRO; + + netdev->features |= netdev->hw_features; netdev->irq = adapter->msix_entries[0].vector; -- GitLab From 94469f75321d13a42056514e2883590b91d84cba Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Apr 2011 11:47:23 +0000 Subject: [PATCH 0552/5560] qlcnic: convert to set_phys_id Convert driver to use new ethtool set_phys_id. Not completely sure that this is correct for all cases of device up/down and doing operation. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 + drivers/net/qlcnic/qlcnic_ethtool.c | 53 +++++++++++++++-------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index dc6f7c69acac..b6e0fc33585f 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -912,6 +912,7 @@ struct qlcnic_adapter { struct net_device *netdev; struct pci_dev *pdev; + bool blink_was_down; unsigned long state; u32 flags; diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 6be4d5a26c7c..3cd8a169694a 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -831,48 +831,51 @@ static int qlcnic_set_tso(struct net_device *dev, u32 data) return 0; } -static int qlcnic_blink_led(struct net_device *dev, u32 val) +static int qlcnic_set_led(struct net_device *dev, + enum ethtool_phys_id_state state) { 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)) { - 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; + switch (state) { + case ETHTOOL_ID_ACTIVE: + adapter->blink_was_down = false; + if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { + if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) + return -EIO; + + if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) { + clear_bit(__QLCNIC_RESETTING, &adapter->state); + return -EIO; + } + adapter->blink_was_down = true; } - } - ret = adapter->nic_ops->config_led(adapter, 1, 0xf); - if (ret) { + if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0) + return 0; + dev_err(&adapter->pdev->dev, "Failed to set LED blink state.\n"); - goto done; - } + break; - msleep_interruptible(val * 1000); + case ETHTOOL_ID_INACTIVE: + if (adapter->nic_ops->config_led(adapter, 0, 0xf) == 0) + return 0; - ret = adapter->nic_ops->config_led(adapter, 0, 0xf); - if (ret) { dev_err(&adapter->pdev->dev, "Failed to reset LED blink state.\n"); - goto done; + break; + + default: + return -EINVAL; } -done: - if (dev_down) { + if (adapter->blink_was_down) { qlcnic_diag_free_res(dev, max_sds_rings); clear_bit(__QLCNIC_RESETTING, &adapter->state); } - return ret; + return -EIO; } static void @@ -1078,7 +1081,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = { .set_coalesce = qlcnic_set_intr_coalesce, .get_flags = ethtool_op_get_flags, .set_flags = qlcnic_set_flags, - .phys_id = qlcnic_blink_led, + .set_phys_id = qlcnic_set_led, .set_msglevel = qlcnic_set_msglevel, .get_msglevel = qlcnic_get_msglevel, }; -- GitLab From 7b1b3afadf33627e707c5038af991ae2ce9b5ac5 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Apr 2011 11:58:36 +0000 Subject: [PATCH 0553/5560] ewrk3: convert to set_phys_id Use ethtool infrastructure for blinking, which is now does locking at higher level. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ewrk3.c | 56 +++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 380d0614a89a..c7ce4438e923 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1604,55 +1604,47 @@ static u32 ewrk3_get_link(struct net_device *dev) return !(cmr & CMR_LINK); } -static int ewrk3_phys_id(struct net_device *dev, u32 data) +static int ewrk3_set_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { struct ewrk3_private *lp = netdev_priv(dev); unsigned long iobase = dev->base_addr; - unsigned long flags; u8 cr; - int count; - - /* Toggle LED 4x per second */ - count = data << 2; - spin_lock_irqsave(&lp->hw_lock, flags); - - /* Bail if a PHYS_ID is already in progress */ - if (lp->led_mask == 0) { - spin_unlock_irqrestore(&lp->hw_lock, flags); - return -EBUSY; - } + spin_lock_irq(&lp->hw_lock); - /* Prevent ISR from twiddling the LED */ - lp->led_mask = 0; + switch (state) { + case ETHTOOL_ID_ACTIVE: + /* Prevent ISR from twiddling the LED */ + lp->led_mask = 0; + spin_unlock_irq(&lp->hw_lock); + return -EINVAL; - while (count--) { - /* Toggle the LED */ + case ETHTOOL_ID_ON: cr = inb(EWRK3_CR); - outb(cr ^ CR_LED, EWRK3_CR); + outb(cr | CR_LED, EWRK3_CR); + break; - /* Wait a little while */ - spin_unlock_irqrestore(&lp->hw_lock, flags); - msleep(250); - spin_lock_irqsave(&lp->hw_lock, flags); + case ETHTOOL_ID_OFF: + cr = inb(EWRK3_CR); + outb(cr & ~CR_LED, EWRK3_CR); + break; - /* Exit if we got a signal */ - if (signal_pending(current)) - break; + case ETHTOOL_ID_INACTIVE: + lp->led_mask = CR_LED; + cr = inb(EWRK3_CR); + outb(cr & ~CR_LED, EWRK3_CR); } + spin_unlock_irq(&lp->hw_lock); - lp->led_mask = CR_LED; - cr = inb(EWRK3_CR); - outb(cr & ~CR_LED, EWRK3_CR); - spin_unlock_irqrestore(&lp->hw_lock, flags); - return signal_pending(current) ? -ERESTARTSYS : 0; + return 0; } static const struct ethtool_ops ethtool_ops_203 = { .get_drvinfo = ewrk3_get_drvinfo, .get_settings = ewrk3_get_settings, .set_settings = ewrk3_set_settings, - .phys_id = ewrk3_phys_id, + .set_phys_id = ewrk3_set_phys_id, }; static const struct ethtool_ops ethtool_ops = { @@ -1660,7 +1652,7 @@ static const struct ethtool_ops ethtool_ops = { .get_settings = ewrk3_get_settings, .set_settings = ewrk3_set_settings, .get_link = ewrk3_get_link, - .phys_id = ewrk3_phys_id, + .set_phys_id = ewrk3_set_phys_id, }; /* -- GitLab From 912d398d28b4359c2fb1f3763f1ce4f86de8350e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 6 Apr 2011 18:40:12 +0000 Subject: [PATCH 0554/5560] net: fix skb_add_data_nocache() to calc csum correctly commit c6e1a0d12ca7b4f22c58e55a16beacfb7d3d8462 broken the calc (net: Allow no-cache copy from user on transmit) of checksum, which may cause some tcp packets be dropped because incorrect checksum. ssh does not work under today's net-next-2.6 tree. Signed-off-by: Wei Yongjun Acked-by: Tom Herbert Signed-off-by: David S. Miller --- include/net/sock.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 43bd515e92fd..9cbf23c815f5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1392,14 +1392,14 @@ static inline void sk_nocaps_add(struct sock *sk, int flags) static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb, char __user *from, char *to, - int copy) + int copy, int offset) { if (skb->ip_summed == CHECKSUM_NONE) { int err = 0; __wsum csum = csum_and_copy_from_user(from, to, copy, 0, &err); if (err) return err; - skb->csum = csum_block_add(skb->csum, csum, skb->len); + skb->csum = csum_block_add(skb->csum, csum, offset); } else if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) { if (!access_ok(VERIFY_READ, from, copy) || __copy_from_user_nocache(to, from, copy)) @@ -1413,11 +1413,12 @@ static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb, static inline int skb_add_data_nocache(struct sock *sk, struct sk_buff *skb, char __user *from, int copy) { - int err; + int err, offset = skb->len; - err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy), copy); + err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy), + copy, offset); if (err) - __skb_trim(skb, skb->len); + __skb_trim(skb, offset); return err; } @@ -1429,8 +1430,8 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from, { int err; - err = skb_do_copy_data_nocache(sk, skb, from, - page_address(page) + off, copy); + err = skb_do_copy_data_nocache(sk, skb, from, page_address(page) + off, + copy, skb->len); if (err) return err; -- GitLab From a7f2371f9e9730ccdb70d6d5803da2a732c97cf3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 10:24:23 +0200 Subject: [PATCH 0555/5560] ALSA: hda - Split EAPD init to a separate array from alc662_init_verbs So far, alc662_init_verbs[] is used for all ALC662-compatible chips, but the EAPD controls for 0x15 in there is invalid for ALC892. Also, since EAPDs should be set up in alc_auto_init_amp(), these static elements aren't needed for auto-parser, too. In this patch, the EAPD init verbs are split from alc662_init_verbs, and applied only to static quirks. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 55 +++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d566eac08d6c..4971d777d9c9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1268,6 +1268,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0665: case 0x10ec0862: case 0x10ec0889: + case 0x10ec0892: set_eapd(codec, 0x14, 1); set_eapd(codec, 0x15, 1); break; @@ -4244,6 +4245,7 @@ static void alc_power_eapd(struct hda_codec *codec) case 0x10ec0665: case 0x10ec0862: case 0x10ec0889: + case 0x10ec0892: set_eapd(codec, 0x14, 0); set_eapd(codec, 0x15, 0); break; @@ -17922,10 +17924,13 @@ static struct hda_verb alc662_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + { } +}; + +static struct hda_verb alc662_eapd_init_verbs[] = { /* always trun on EAPD */ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } }; @@ -18797,7 +18802,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { static struct alc_config_preset alc662_presets[] = { [ALC662_3ST_2ch_DIG] = { .mixers = { alc662_3ST_2ch_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18808,7 +18813,7 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_3ST_6ch_DIG] = { .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18820,7 +18825,7 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_3ST_6ch] = { .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), @@ -18830,7 +18835,7 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_5ST_DIG] = { .mixers = { alc662_base_mixer, alc662_chmode_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18841,7 +18846,9 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_LENOVO_101E] = { .mixers = { alc662_lenovo_101e_mixer }, - .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc662_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), @@ -18853,6 +18860,7 @@ static struct alc_config_preset alc662_presets[] = { [ALC662_ASUS_EEEPC_P701] = { .mixers = { alc662_eeepc_p701_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_eeepc_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -18866,6 +18874,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc662_eeepc_ep20_mixer, alc662_chmode_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_eeepc_ep20_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -18879,6 +18888,7 @@ static struct alc_config_preset alc662_presets[] = { [ALC662_ECS] = { .mixers = { alc662_ecs_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_ecs_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -18890,7 +18900,9 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC663_ASUS_M51VA] = { .mixers = { alc663_m51va_mixer }, - .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_m51va_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18902,7 +18914,9 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC663_ASUS_G71V] = { .mixers = { alc663_g71v_mixer }, - .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_g71v_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18914,7 +18928,9 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC663_ASUS_H13] = { .mixers = { alc663_m51va_mixer }, - .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_m51va_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), @@ -18924,7 +18940,9 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC663_ASUS_G50V] = { .mixers = { alc663_g50v_mixer }, - .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_g50v_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18939,6 +18957,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_21jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -18954,6 +18973,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc662_1bjd_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_1bjd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, @@ -18968,6 +18988,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_two_hp_m1_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_two_hp_amic_m1_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -18983,6 +19004,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_asus_21jd_clfe_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_21jd_amic_init_verbs}, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -18998,6 +19020,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_asus_15jd_clfe_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_15jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19013,6 +19036,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_two_hp_m2_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_two_hp_amic_m2_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19028,6 +19052,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_mode7_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_mode7_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19043,6 +19068,7 @@ static struct alc_config_preset alc662_presets[] = { .mixers = { alc663_mode8_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_mode8_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19057,7 +19083,9 @@ static struct alc_config_preset alc662_presets[] = { [ALC272_DELL] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc272_auto_capture_mixer, - .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc272_dell_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), @@ -19072,7 +19100,9 @@ static struct alc_config_preset alc662_presets[] = { [ALC272_DELL_ZM1] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc662_auto_capture_mixer, - .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc272_dell_zm1_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), @@ -19087,6 +19117,7 @@ static struct alc_config_preset alc662_presets[] = { [ALC272_SAMSUNG_NC10] = { .mixers = { alc272_nc10_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_21jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), .dac_nids = alc272_dac_nids, -- GitLab From 691f1fccf72e3092e3a7a79fd672940afc9305ef Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 10:31:43 +0200 Subject: [PATCH 0556/5560] ALSA: hda - Refactoring EAPD controls Reduced the duplicated codes. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 75 ++++++++++++++--------------------- 1 file changed, 30 insertions(+), 45 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4971d777d9c9..c798e18d453f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1236,6 +1236,34 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) on ? 2 : 0); } +/* turn on/off EAPD controls of the codec */ +static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) +{ + /* We currently only handle front, HP */ + switch (codec->vendor_id) { + case 0x10ec0260: + set_eapd(codec, 0x0f, on); + set_eapd(codec, 0x10, on); + break; + case 0x10ec0262: + case 0x10ec0267: + case 0x10ec0268: + case 0x10ec0269: + case 0x10ec0270: + case 0x10ec0272: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: + case 0x10ec0665: + case 0x10ec0862: + case 0x10ec0889: + case 0x10ec0892: + set_eapd(codec, 0x14, on); + set_eapd(codec, 0x15, on); + break; + } +} + static void alc_auto_init_amp(struct hda_codec *codec, int type) { unsigned int tmp; @@ -1251,28 +1279,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) snd_hda_sequence_write(codec, alc_gpio3_init_verbs); break; case ALC_INIT_DEFAULT: - switch (codec->vendor_id) { - case 0x10ec0260: - set_eapd(codec, 0x0f, 1); - set_eapd(codec, 0x10, 1); - break; - case 0x10ec0262: - case 0x10ec0267: - case 0x10ec0268: - case 0x10ec0269: - case 0x10ec0270: - case 0x10ec0272: - case 0x10ec0660: - case 0x10ec0662: - case 0x10ec0663: - case 0x10ec0665: - case 0x10ec0862: - case 0x10ec0889: - case 0x10ec0892: - set_eapd(codec, 0x14, 1); - set_eapd(codec, 0x15, 1); - break; - } + alc_auto_setup_eapd(codec, true); switch (codec->vendor_id) { case 0x10ec0260: snd_hda_codec_write(codec, 0x1a, 0, @@ -4227,29 +4234,7 @@ static void alc_free(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE static void alc_power_eapd(struct hda_codec *codec) { - /* We currently only handle front, HP */ - switch (codec->vendor_id) { - case 0x10ec0260: - set_eapd(codec, 0x0f, 0); - set_eapd(codec, 0x10, 0); - break; - case 0x10ec0262: - case 0x10ec0267: - case 0x10ec0268: - case 0x10ec0269: - case 0x10ec0270: - case 0x10ec0272: - case 0x10ec0660: - case 0x10ec0662: - case 0x10ec0663: - case 0x10ec0665: - case 0x10ec0862: - case 0x10ec0889: - case 0x10ec0892: - set_eapd(codec, 0x14, 0); - set_eapd(codec, 0x15, 0); - break; - } + alc_auto_setup_eapd(codec, false); } static int alc_suspend(struct hda_codec *codec, pm_message_t state) -- GitLab From 1c716153a87ae75c8bd63f1b6f7916300d87df7e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 10:37:16 +0200 Subject: [PATCH 0557/5560] ALSA: hda - Introduce shutup callback to Realtek spec struct Add shutup callback to be called codec-specifically for avoiding pop noises at suspend or shutdown. As a generic callback, just turn EAPD off. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c798e18d453f..3761fba5bcec 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -375,6 +375,7 @@ struct alc_spec { #ifdef CONFIG_SND_HDA_POWER_SAVE void (*power_hook)(struct hda_codec *codec); #endif + void (*shutup)(struct hda_codec *codec); /* for pin sensing */ unsigned int sense_updated: 1; @@ -1264,6 +1265,15 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) } } +/* generic shutup callback; + * just turning off EPAD and a little pause for avoiding pop-noise + */ +static void alc_eapd_shutup(struct hda_codec *codec) +{ + alc_auto_setup_eapd(codec, false); + msleep(200); +} + static void alc_auto_init_amp(struct hda_codec *codec, int type) { unsigned int tmp; @@ -4201,6 +4211,10 @@ static int alc_build_pcms(struct hda_codec *codec) static inline void alc_shutup(struct hda_codec *codec) { + struct alc_spec *spec = codec->spec; + + if (spec && spec->shutup) + spec->shutup(codec); snd_hda_shutup_pins(codec); } @@ -4250,6 +4264,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state) #ifdef SND_HDA_NEEDS_RESUME static int alc_resume(struct hda_codec *codec) { + msleep(150); /* to avoid pop noise */ codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); @@ -7370,6 +7385,7 @@ static int patch_alc260(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC260_AUTO) spec->init_hook = alc260_auto_init; + spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc260_loopbacks; @@ -13005,6 +13021,7 @@ static int patch_alc262(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC262_AUTO) spec->init_hook = alc262_auto_init; + spec->shutup = alc_eapd_shutup; alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -14079,6 +14096,7 @@ static int patch_alc268(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC268_AUTO) spec->init_hook = alc268_auto_init; + spec->shutup = alc_eapd_shutup; alc_init_jacks(codec); @@ -17397,6 +17415,7 @@ static int patch_alc861vd(struct hda_codec *codec) if (board_config == ALC861VD_AUTO) spec->init_hook = alc861vd_auto_init; + spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc861vd_loopbacks; @@ -19628,6 +19647,7 @@ static int patch_alc662(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC662_AUTO) spec->init_hook = alc662_auto_init; + spec->shutup = alc_eapd_shutup; alc_init_jacks(codec); -- GitLab From 5402e4cb80dc2cb407ca07e31cb7668ba45e5320 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 10:39:25 +0200 Subject: [PATCH 0558/5560] ALSA: hda - Rewrite alc269_suspend to alc269_shutup alc269_suspend is just calling the shut-up, so we can use the new shutup callback for the purpose. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3761fba5bcec..8406248236fe 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14808,7 +14808,6 @@ static void alc269_auto_init(struct hda_codec *codec) alc_inithook(codec); } -#ifdef SND_HDA_NEEDS_RESUME static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); @@ -14819,8 +14818,7 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) alc_write_coef_idx(codec, 0x04, val); } -#ifdef CONFIG_SND_HDA_POWER_SAVE -static int alc269_suspend(struct hda_codec *codec, pm_message_t state) +static void alc269_shutup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -14830,14 +14828,9 @@ static int alc269_suspend(struct hda_codec *codec, pm_message_t state) alc269_toggle_power_output(codec, 0); msleep(150); } - - alc_shutup(codec); - if (spec && spec->power_hook) - spec->power_hook(codec); - return 0; } -#endif /* CONFIG_SND_HDA_POWER_SAVE */ +#ifdef SND_HDA_NEEDS_RESUME static int alc269_resume(struct hda_codec *codec) { if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { @@ -15302,14 +15295,12 @@ static int patch_alc269(struct hda_codec *codec) spec->vmaster_nid = 0x02; codec->patch_ops = alc_patch_ops; -#ifdef CONFIG_SND_HDA_POWER_SAVE - codec->patch_ops.suspend = alc269_suspend; -#endif #ifdef SND_HDA_NEEDS_RESUME codec->patch_ops.resume = alc269_resume; #endif if (board_config == ALC269_AUTO) spec->init_hook = alc269_auto_init; + spec->shutup = alc269_shutup; alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE -- GitLab From 0e53f3440925aa36fe3bd2307e5fa0238a66f8bf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 12:27:32 +0200 Subject: [PATCH 0559/5560] ALSA: hda - Unmute mixer dynamically in alc662 auto-parser Instead of static init array, better to determine the connection and the mute status of the pin/mixer/DAC route dynamically. This fixes the uninitialized mixer 0x0f on ALC892. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8406248236fe..e3756a7ebee2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19319,14 +19319,21 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t srcs[HDA_MAX_CONNECTIONS]; alc_set_pin_output(codec, nid, pin_type); - /* need the manual connection? */ num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); - if (num <= 1) - return; for (i = 0; i < num; i++) { if (alc662_mix_to_dac(codec, srcs[i]) != dac) continue; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); + /* need the manual connection? */ + if (num > 1) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, i); + /* unmute mixer widget inputs */ + snd_hda_codec_write(codec, srcs[i], 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(0)); + snd_hda_codec_write(codec, srcs[i], 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(1)); return; } } -- GitLab From 10696aa0e56b29c6f3ce27081092785c564423e1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 12:46:45 +0200 Subject: [PATCH 0560/5560] ALSA: hda - Mute ADC as default in ALC882 and other auto-parsers Mute the ADC as default in the auto-parser dynamically instead of relying on the static init verbs. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e3756a7ebee2..e5dfed35ca67 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10852,6 +10852,11 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) const struct hda_input_mux *imux; int conns, mute, idx, item; + /* mute ADC */ + snd_hda_codec_write(codec, spec->adc_nids[c], 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_MUTE(0)); + conns = snd_hda_get_connections(codec, nid, conn_list, ARRAY_SIZE(conn_list)); if (conns < 0) -- GitLab From 35ffe11587fb6e93725d420aa17cf1e7a6bf427f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 12:34:26 +0200 Subject: [PATCH 0561/5560] ALSA: hda - Remove superfluous inits for ALC662 auto-parser Since we now set up the connections and mutes dynamically in the auto-parser, all static initializations via alc662_init_verbs & co are no longer needed. Let's drop them. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e5dfed35ca67..c22a7ca01997 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -17934,28 +17934,6 @@ static struct hda_verb alc662_eapd_init_verbs[] = { { } }; -static struct hda_verb alc663_init_verbs[] = { - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - { } -}; - -static struct hda_verb alc272_init_verbs[] = { - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - { } -}; - static struct hda_verb alc662_sue_init_verbs[] = { {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, @@ -19441,14 +19419,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux[0]; - add_verb(spec, alc662_init_verbs); - if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || - codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) - add_verb(spec, alc663_init_verbs); - - if (codec->vendor_id == 0x10ec0272) - add_verb(spec, alc272_init_verbs); - err = alc_auto_add_mic_boost(codec); if (err < 0) return err; -- GitLab From ad93ffe6e4fc02993987008e4a5dcdcf4c926cd5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 12:49:26 +0200 Subject: [PATCH 0562/5560] ALSA: hda - Fix unused variable warning in patch_realtek.c Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c22a7ca01997..b1e5eb17f1bc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14825,8 +14825,6 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) static void alc269_shutup(struct hda_codec *codec) { - struct alc_spec *spec = codec->spec; - if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) alc269_toggle_power_output(codec, 0); if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { -- GitLab From a12d3e1e1cb67bab2411966b345151c316633847 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Apr 2011 15:55:15 +0200 Subject: [PATCH 0563/5560] ALSA: hda - Remember connection lists The connection lists are static and we can reuse the previous results instead of querying via verb at each time. This will reduce the I/O in the runtime especially for some codec auto-parsers. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 69 +++++++++++++++++++++++++++++++++++++-- sound/pci/hda/hda_codec.h | 2 ++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2c79e96d0324..11ead159abd9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -307,6 +307,12 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, } EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); +static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *conn_list, int max_conns); +static bool add_conn_list(struct snd_array *array, hda_nid_t nid); +static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, + hda_nid_t *src, int len); + /** * snd_hda_get_connections - get connection list * @codec: the HDA codec @@ -320,7 +326,44 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); * Returns the number of connections, or a negative error code. */ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, - hda_nid_t *conn_list, int max_conns) + hda_nid_t *conn_list, int max_conns) +{ + struct snd_array *array = &codec->conn_lists; + int i, j, len, old_used; + hda_nid_t list[HDA_MAX_CONNECTIONS]; + + /* look up the cached results */ + for (i = 0; i < array->used; ) { + hda_nid_t *p = snd_array_elem(array, i); + len = p[1]; + if (nid == *p) + return copy_conn_list(nid, conn_list, max_conns, + p + 2, len); + i += len + 2; + } + + len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); + if (len < 0) + return len; + + /* add to the cache */ + old_used = array->used; + if (!add_conn_list(array, nid) || !add_conn_list(array, len)) + goto error_add; + for (i = 0; i < len; i++) + if (!add_conn_list(array, list[i])) + goto error_add; + + return copy_conn_list(nid, conn_list, max_conns, list, len); + + error_add: + array->used = old_used; + return -ENOMEM; +} +EXPORT_SYMBOL_HDA(snd_hda_get_connections); + +static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *conn_list, int max_conns) { unsigned int parm; int i, conn_len, conns; @@ -417,8 +460,28 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, } return conns; } -EXPORT_SYMBOL_HDA(snd_hda_get_connections); +static bool add_conn_list(struct snd_array *array, hda_nid_t nid) +{ + hda_nid_t *p = snd_array_new(array); + if (!p) + return false; + *p = nid; + return true; +} + +static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, + hda_nid_t *src, int len) +{ + if (len > max_dst) { + snd_printk(KERN_ERR "hda_codec: " + "Too many connections %d for NID 0x%x\n", + len, nid); + return -EINVAL; + } + memcpy(dst, src, len * sizeof(hda_nid_t)); + return len; +} /** * snd_hda_queue_unsol_event - add an unsolicited event to queue @@ -1017,6 +1080,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) list_del(&codec->list); snd_array_free(&codec->mixers); snd_array_free(&codec->nids); + snd_array_free(&codec->conn_lists); codec->bus->caddr_tbl[codec->addr] = NULL; if (codec->patch_ops.free) codec->patch_ops.free(codec); @@ -1077,6 +1141,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); + snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); if (codec->bus->modelname) { codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); if (!codec->modelname) { diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index e46d5420a9f2..7d57a66c1b31 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -825,6 +825,8 @@ struct hda_codec { struct hda_cache_rec amp_cache; /* cache for amp access */ struct hda_cache_rec cmd_cache; /* cache for other commands */ + struct snd_array conn_lists; /* connection-list array */ + struct mutex spdif_mutex; struct mutex control_mutex; unsigned int spdif_status; /* IEC958 status bits */ -- GitLab From eba71de2cb7c02c5ae4f2ad3656343da71bc4661 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 25 Mar 2011 10:13:43 -0400 Subject: [PATCH 0564/5560] selinux: Fix regression for Xorg Commit 6f5317e730505d5cbc851c435a2dfe3d5a21d343 introduced a bug in the handling of userspace object classes that is causing breakage for Xorg when XSELinux is enabled. Fix the bug by changing map_class() to return SECCLASS_NULL when the class cannot be mapped to a kernel object class. Reported-by: "Justin P. Mattock" Signed-off-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/ss/services.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 39d732145abe..f3f5dca81006 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -213,7 +213,7 @@ static u16 map_class(u16 pol_value) return i; } - return pol_value; + return SECCLASS_NULL; } static void map_decision(u16 tclass, struct av_decision *avd, -- GitLab From 1214eac73f798bccabc6adb55e7b2d787527c13c Mon Sep 17 00:00:00 2001 From: Harry Ciao Date: Thu, 7 Apr 2011 14:12:57 +0800 Subject: [PATCH 0565/5560] Initialize policydb.process_class eariler. Initialize policydb.process_class once all symtabs read from policy image, so that it could be used to setup the role_trans.tclass field when a lower version policy.X is loaded. Signed-off-by: Harry Ciao Signed-off-by: Eric Paris --- security/selinux/ss/policydb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index a493eae24e0a..82373eb2dc97 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -2275,6 +2275,11 @@ int policydb_read(struct policydb *p, void *fp) p->symtab[i].nprim = nprim; } + rc = -EINVAL; + p->process_class = string_to_security_class(p, "process"); + if (!p->process_class) + goto bad; + rc = avtab_read(&p->te_avtab, fp, p); if (rc) goto bad; @@ -2358,11 +2363,6 @@ int policydb_read(struct policydb *p, void *fp) if (rc) goto bad; - rc = -EINVAL; - p->process_class = string_to_security_class(p, "process"); - if (!p->process_class) - goto bad; - rc = -EINVAL; p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); -- GitLab From ff00c2a5b2308219ab952d01e5bb17b9ea772d7e Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 7 Apr 2011 11:05:56 -0700 Subject: [PATCH 0566/5560] [IA64] fix build warning in arch/ia64/oprofile/backtrace.c arch/ia64/oprofile/backtrace.c:63: warning: comparison of distinct pointer types lacks a cast Comparing a "u64 *" with an "unsigned long *". Make them match. Signed-off-by: Tony Luck --- arch/ia64/oprofile/backtrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c index 5cdd7e4a597c..f7b798993cea 100644 --- a/arch/ia64/oprofile/backtrace.c +++ b/arch/ia64/oprofile/backtrace.c @@ -29,7 +29,7 @@ typedef struct unsigned int depth; struct pt_regs *regs; struct unw_frame_info frame; - u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */ + unsigned long *prev_pfs_loc; /* state for WAR for old spinlock ool code */ } ia64_backtrace_t; /* Returns non-zero if the PC is in the Interrupt Vector Table */ -- GitLab From b0006e69615868f3dfdfe2bd64eb11973f1208fc Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 25 Mar 2011 20:21:55 +0100 Subject: [PATCH 0567/5560] ar9170usb: purge obsolete driver Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- Documentation/feature-removal-schedule.txt | 11 - MAINTAINERS | 7 - drivers/net/wireless/ath/Kconfig | 1 - drivers/net/wireless/ath/Makefile | 1 - drivers/net/wireless/ath/ar9170/Kconfig | 20 - drivers/net/wireless/ath/ar9170/Makefile | 3 - drivers/net/wireless/ath/ar9170/ar9170.h | 258 --- drivers/net/wireless/ath/ar9170/cmd.c | 127 -- drivers/net/wireless/ath/ar9170/cmd.h | 92 - drivers/net/wireless/ath/ar9170/eeprom.h | 179 -- drivers/net/wireless/ath/ar9170/hw.h | 430 ---- drivers/net/wireless/ath/ar9170/led.c | 181 -- drivers/net/wireless/ath/ar9170/mac.c | 519 ----- drivers/net/wireless/ath/ar9170/main.c | 2190 -------------------- drivers/net/wireless/ath/ar9170/phy.c | 1719 --------------- drivers/net/wireless/ath/ar9170/usb.c | 1008 --------- drivers/net/wireless/ath/ar9170/usb.h | 82 - 17 files changed, 6828 deletions(-) delete mode 100644 drivers/net/wireless/ath/ar9170/Kconfig delete mode 100644 drivers/net/wireless/ath/ar9170/Makefile delete mode 100644 drivers/net/wireless/ath/ar9170/ar9170.h delete mode 100644 drivers/net/wireless/ath/ar9170/cmd.c delete mode 100644 drivers/net/wireless/ath/ar9170/cmd.h delete mode 100644 drivers/net/wireless/ath/ar9170/eeprom.h delete mode 100644 drivers/net/wireless/ath/ar9170/hw.h delete mode 100644 drivers/net/wireless/ath/ar9170/led.c delete mode 100644 drivers/net/wireless/ath/ar9170/mac.c delete mode 100644 drivers/net/wireless/ath/ar9170/main.c delete mode 100644 drivers/net/wireless/ath/ar9170/phy.c delete mode 100644 drivers/net/wireless/ath/ar9170/usb.c delete mode 100644 drivers/net/wireless/ath/ar9170/usb.h diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 274b32d12532..05ed6f301d89 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -35,17 +35,6 @@ Who: Luis R. Rodriguez --------------------------- -What: AR9170USB -When: 2.6.40 - -Why: This driver is deprecated and the firmware is no longer - maintained. The replacement driver "carl9170" has been - around for a while, so the devices are still supported. - -Who: Christian Lamparter - ---------------------------- - What: IRQF_SAMPLE_RANDOM Check: IRQF_SAMPLE_RANDOM When: July 2009 diff --git a/MAINTAINERS b/MAINTAINERS index 5dd948b5bc6e..9f9104987a73 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1224,13 +1224,6 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k S: Supported F: drivers/net/wireless/ath/ath9k/ -ATHEROS AR9170 WIRELESS DRIVER -M: Christian Lamparter -L: linux-wireless@vger.kernel.org -W: http://wireless.kernel.org/en/users/Drivers/ar9170 -S: Obsolete -F: drivers/net/wireless/ath/ar9170/ - CARL9170 LINUX COMMUNITY WIRELESS DRIVER M: Christian Lamparter L: linux-wireless@vger.kernel.org diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 92c216263ee9..d1b23067619f 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -24,7 +24,6 @@ config ATH_DEBUG source "drivers/net/wireless/ath/ath5k/Kconfig" source "drivers/net/wireless/ath/ath9k/Kconfig" -source "drivers/net/wireless/ath/ar9170/Kconfig" source "drivers/net/wireless/ath/carl9170/Kconfig" endif diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 6d711ec97ec2..0e8f528c81c0 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -1,6 +1,5 @@ obj-$(CONFIG_ATH5K) += ath5k/ obj-$(CONFIG_ATH9K_HW) += ath9k/ -obj-$(CONFIG_AR9170_USB) += ar9170/ obj-$(CONFIG_CARL9170) += carl9170/ obj-$(CONFIG_ATH_COMMON) += ath.o diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig deleted file mode 100644 index 7b9672b0d090..000000000000 --- a/drivers/net/wireless/ath/ar9170/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -config AR9170_USB - tristate "Atheros AR9170 802.11n USB support (OBSOLETE)" - depends on USB && MAC80211 - select FW_LOADER - help - This driver is going to get replaced by carl9170. - - This is a driver for the Atheros "otus" 802.11n USB devices. - - These devices require additional firmware (2 files). - For now, these files can be downloaded from here: - - http://wireless.kernel.org/en/users/Drivers/ar9170 - - If you choose to build a module, it'll be called ar9170usb. - -config AR9170_LEDS - bool - depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB) - default y diff --git a/drivers/net/wireless/ath/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile deleted file mode 100644 index 8d91c7ee3215..000000000000 --- a/drivers/net/wireless/ath/ar9170/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o - -obj-$(CONFIG_AR9170_USB) += ar9170usb.o diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h deleted file mode 100644 index 371e4ce49528..000000000000 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Atheros AR9170 driver - * - * Driver specific definitions - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 __AR9170_H -#define __AR9170_H - -#include -#include -#include -#include -#ifdef CONFIG_AR9170_LEDS -#include -#endif /* CONFIG_AR9170_LEDS */ -#include "eeprom.h" -#include "hw.h" - -#include "../regd.h" - -#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1) - -enum ar9170_bw { - AR9170_BW_20, - AR9170_BW_40_BELOW, - AR9170_BW_40_ABOVE, - - __AR9170_NUM_BW, -}; - -static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type) -{ - switch (type) { - case NL80211_CHAN_NO_HT: - case NL80211_CHAN_HT20: - return AR9170_BW_20; - case NL80211_CHAN_HT40MINUS: - return AR9170_BW_40_BELOW; - case NL80211_CHAN_HT40PLUS: - return AR9170_BW_40_ABOVE; - default: - BUG(); - } -} - -enum ar9170_rf_init_mode { - AR9170_RFI_NONE, - AR9170_RFI_WARM, - AR9170_RFI_COLD, -}; - -#define AR9170_MAX_RX_BUFFER_SIZE 8192 - -#ifdef CONFIG_AR9170_LEDS -struct ar9170; - -struct ar9170_led { - struct ar9170 *ar; - struct led_classdev l; - char name[32]; - unsigned int toggled; - bool last_state; - bool registered; -}; - -#endif /* CONFIG_AR9170_LEDS */ - -enum ar9170_device_state { - AR9170_UNKNOWN_STATE, - AR9170_STOPPED, - AR9170_IDLE, - AR9170_STARTED, -}; - -struct ar9170_rxstream_mpdu_merge { - struct ar9170_rx_head plcp; - bool has_plcp; -}; - -struct ar9170_tx_queue_stats { - unsigned int len; - unsigned int limit; - unsigned int count; -}; - -#define AR9170_QUEUE_TIMEOUT 64 -#define AR9170_TX_TIMEOUT 8 -#define AR9170_JANITOR_DELAY 128 -#define AR9170_TX_INVALID_RATE 0xffffffff - -#define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH -#define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10) - -struct ar9170 { - struct ieee80211_hw *hw; - struct ath_common common; - struct mutex mutex; - enum ar9170_device_state state; - bool registered; - unsigned long bad_hw_nagger; - - int (*open)(struct ar9170 *); - void (*stop)(struct ar9170 *); - int (*tx)(struct ar9170 *, struct sk_buff *); - int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , - void *, u32 , void *); - void (*callback_cmd)(struct ar9170 *, u32 , void *); - int (*flush)(struct ar9170 *); - - /* interface mode settings */ - struct ieee80211_vif *vif; - - /* beaconing */ - struct sk_buff *beacon; - struct work_struct beacon_work; - bool enable_beacon; - - /* cryptographic engine */ - u64 usedkeys; - bool rx_software_decryption; - bool disable_offload; - - /* filter settings */ - u64 cur_mc_hash; - u32 cur_filter; - unsigned int filter_state; - bool sniffer_enabled; - - /* PHY */ - struct ieee80211_channel *channel; - int noise[4]; - - /* power calibration data */ - u8 power_5G_leg[4]; - u8 power_2G_cck[4]; - u8 power_2G_ofdm[4]; - u8 power_5G_ht20[8]; - u8 power_5G_ht40[8]; - u8 power_2G_ht20[8]; - u8 power_2G_ht40[8]; - - u8 phy_heavy_clip; - -#ifdef CONFIG_AR9170_LEDS - struct delayed_work led_work; - struct ar9170_led leds[AR9170_NUM_LEDS]; -#endif /* CONFIG_AR9170_LEDS */ - - /* qos queue settings */ - spinlock_t tx_stats_lock; - struct ar9170_tx_queue_stats tx_stats[5]; - struct ieee80211_tx_queue_params edcf[5]; - - spinlock_t cmdlock; - __le32 cmdbuf[PAYLOAD_MAX + 1]; - - /* MAC statistics */ - struct ieee80211_low_level_stats stats; - - /* EEPROM */ - struct ar9170_eeprom eeprom; - - /* tx queues - as seen by hw - */ - struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; - struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; - struct delayed_work tx_janitor; - - /* rxstream mpdu merge */ - struct ar9170_rxstream_mpdu_merge rx_mpdu; - struct sk_buff *rx_failover; - int rx_failover_missing; - - /* (cached) HW A-MPDU settings */ - u8 global_ampdu_density; - u8 global_ampdu_factor; -}; - -struct ar9170_tx_info { - unsigned long timeout; -}; - -#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) -#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) - -/* exported interface */ -void *ar9170_alloc(size_t priv_size); -int ar9170_register(struct ar9170 *ar, struct device *pdev); -void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); -void ar9170_unregister(struct ar9170 *ar); -void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); -void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); -int ar9170_nag_limiter(struct ar9170 *ar); - -/* MAC */ -void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -int ar9170_init_mac(struct ar9170 *ar); -int ar9170_set_qos(struct ar9170 *ar); -int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); -int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter); -int ar9170_set_operating_mode(struct ar9170 *ar); -int ar9170_set_beacon_timers(struct ar9170 *ar); -int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); -int ar9170_set_slot_time(struct ar9170 *ar); -int ar9170_set_basic_rates(struct ar9170 *ar); -int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); -int ar9170_update_beacon(struct ar9170 *ar); -void ar9170_new_beacon(struct work_struct *work); -int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype, - u8 keyidx, u8 *keydata, int keylen); -int ar9170_disable_key(struct ar9170 *ar, u8 id); - -/* LEDs */ -#ifdef CONFIG_AR9170_LEDS -int ar9170_register_leds(struct ar9170 *ar); -void ar9170_unregister_leds(struct ar9170 *ar); -#endif /* CONFIG_AR9170_LEDS */ -int ar9170_init_leds(struct ar9170 *ar); -int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state); - -/* PHY / RF */ -int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band); -int ar9170_init_rf(struct ar9170 *ar); -int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, - enum ar9170_rf_init_mode rfi, enum ar9170_bw bw); - -#endif /* __AR9170_H */ diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c deleted file mode 100644 index 6452c5055a63..000000000000 --- a/drivers/net/wireless/ath/ar9170/cmd.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Atheros AR9170 driver - * - * Basic HW register/memory/command access functions - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 "ar9170.h" -#include "cmd.h" - -int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) -{ - int err; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return 0; - - err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); - if (err) - wiphy_debug(ar->hw->wiphy, "writing memory failed\n"); - return err; -} - -int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) -{ - const __le32 buf[2] = { - cpu_to_le32(reg), - cpu_to_le32(val), - }; - int err; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return 0; - - err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), - (u8 *) buf, 0, NULL); - if (err) - wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n", - reg, val); - return err; -} - -int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out) -{ - int i, err; - __le32 *offs, *res; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return 0; - - /* abuse "out" for the register offsets, must be same length */ - offs = (__le32 *)out; - for (i = 0; i < nregs; i++) - offs[i] = cpu_to_le32(regs[i]); - - /* also use the same buffer for the input */ - res = (__le32 *)out; - - err = ar->exec_cmd(ar, AR9170_CMD_RREG, - 4 * nregs, (u8 *)offs, - 4 * nregs, (u8 *)res); - if (err) - return err; - - /* convert result to cpu endian */ - for (i = 0; i < nregs; i++) - out[i] = le32_to_cpu(res[i]); - - return 0; -} - -int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) -{ - return ar9170_read_mreg(ar, 1, ®, val); -} - -int ar9170_echo_test(struct ar9170 *ar, u32 v) -{ - __le32 echobuf = cpu_to_le32(v); - __le32 echores; - int err; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return -ENODEV; - - err = ar->exec_cmd(ar, AR9170_CMD_ECHO, - 4, (u8 *)&echobuf, - 4, (u8 *)&echores); - if (err) - return err; - - if (echobuf != echores) - return -EINVAL; - - return 0; -} diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h deleted file mode 100644 index ec8134b4b949..000000000000 --- a/drivers/net/wireless/ath/ar9170/cmd.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Atheros AR9170 driver - * - * Basic HW register/memory/command access functions - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 __CMD_H -#define __CMD_H - -#include "ar9170.h" - -/* basic HW access */ -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); -int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val); -int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out); -int ar9170_echo_test(struct ar9170 *ar, u32 v); - -/* - * Macros to facilitate writing multiple registers in a single - * write-combining USB command. Note that when the first group - * fails the whole thing will fail without any others attempted, - * but you won't know which write in the group failed. - */ -#define ar9170_regwrite_begin(ar) \ -do { \ - int __nreg = 0, __err = 0; \ - struct ar9170 *__ar = ar; - -#define ar9170_regwrite(r, v) do { \ - __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r); \ - __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v); \ - __nreg++; \ - if ((__nreg >= PAYLOAD_MAX/2)) { \ - if (IS_ACCEPTING_CMD(__ar)) \ - __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ - 8 * __nreg, \ - (u8 *) &__ar->cmdbuf[1], \ - 0, NULL); \ - __nreg = 0; \ - if (__err) \ - goto __regwrite_out; \ - } \ -} while (0) - -#define ar9170_regwrite_finish() \ -__regwrite_out : \ - if (__nreg) { \ - if (IS_ACCEPTING_CMD(__ar)) \ - __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ - 8 * __nreg, \ - (u8 *) &__ar->cmdbuf[1], \ - 0, NULL); \ - __nreg = 0; \ - } - -#define ar9170_regwrite_result() \ - __err; \ -} while (0); - -#endif /* __CMD_H */ diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h deleted file mode 100644 index 6c4663883423..000000000000 --- a/drivers/net/wireless/ath/ar9170/eeprom.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Atheros AR9170 driver - * - * EEPROM layout - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 __AR9170_EEPROM_H -#define __AR9170_EEPROM_H - -#define AR5416_MAX_CHAINS 2 -#define AR5416_MODAL_SPURS 5 - -struct ar9170_eeprom_modal { - __le32 antCtrlChain[AR5416_MAX_CHAINS]; - __le32 antCtrlCommon; - s8 antennaGainCh[AR5416_MAX_CHAINS]; - u8 switchSettling; - u8 txRxAttenCh[AR5416_MAX_CHAINS]; - u8 rxTxMarginCh[AR5416_MAX_CHAINS]; - s8 adcDesiredSize; - s8 pgaDesiredSize; - u8 xlnaGainCh[AR5416_MAX_CHAINS]; - u8 txEndToXpaOff; - u8 txEndToRxOn; - u8 txFrameToXpaOn; - u8 thresh62; - s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; - u8 xpdGain; - u8 xpd; - s8 iqCalICh[AR5416_MAX_CHAINS]; - s8 iqCalQCh[AR5416_MAX_CHAINS]; - u8 pdGainOverlap; - u8 ob; - u8 db; - u8 xpaBiasLvl; - u8 pwrDecreaseFor2Chain; - u8 pwrDecreaseFor3Chain; - u8 txFrameToDataStart; - u8 txFrameToPaOn; - u8 ht40PowerIncForPdadc; - u8 bswAtten[AR5416_MAX_CHAINS]; - u8 bswMargin[AR5416_MAX_CHAINS]; - u8 swSettleHt40; - u8 reserved[22]; - struct spur_channel { - __le16 spurChan; - u8 spurRangeLow; - u8 spurRangeHigh; - } __packed spur_channels[AR5416_MODAL_SPURS]; -} __packed; - -#define AR5416_NUM_PD_GAINS 4 -#define AR5416_PD_GAIN_ICEPTS 5 - -struct ar9170_calibration_data_per_freq { - u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; - u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; -} __packed; - -#define AR5416_NUM_5G_CAL_PIERS 8 -#define AR5416_NUM_2G_CAL_PIERS 4 - -#define AR5416_NUM_5G_TARGET_PWRS 8 -#define AR5416_NUM_2G_CCK_TARGET_PWRS 3 -#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 -#define AR5416_MAX_NUM_TGT_PWRS 8 - -struct ar9170_calibration_target_power_legacy { - u8 freq; - u8 power[4]; -} __packed; - -struct ar9170_calibration_target_power_ht { - u8 freq; - u8 power[8]; -} __packed; - -#define AR5416_NUM_CTLS 24 - -struct ar9170_calctl_edges { - u8 channel; -#define AR9170_CALCTL_EDGE_FLAGS 0xC0 - u8 power_flags; -} __packed; - -#define AR5416_NUM_BAND_EDGES 8 - -struct ar9170_calctl_data { - struct ar9170_calctl_edges - control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; -} __packed; - - -struct ar9170_eeprom { - __le16 length; - __le16 checksum; - __le16 version; - u8 operating_flags; -#define AR9170_OPFLAG_5GHZ 1 -#define AR9170_OPFLAG_2GHZ 2 - u8 misc; - __le16 reg_domain[2]; - u8 mac_address[6]; - u8 rx_mask; - u8 tx_mask; - __le16 rf_silent; - __le16 bluetooth_options; - __le16 device_capabilities; - __le32 build_number; - u8 deviceType; - u8 reserved[33]; - - u8 customer_data[64]; - - struct ar9170_eeprom_modal - modal_header[2]; - - u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; - u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; - - struct ar9170_calibration_data_per_freq - cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], - cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; - - /* power calibration data */ - struct ar9170_calibration_target_power_legacy - cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; - struct ar9170_calibration_target_power_ht - cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], - cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; - - struct ar9170_calibration_target_power_legacy - cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], - cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; - struct ar9170_calibration_target_power_ht - cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], - cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; - - /* conformance testing limits */ - u8 ctl_index[AR5416_NUM_CTLS]; - struct ar9170_calctl_data - ctl_data[AR5416_NUM_CTLS]; - - u8 pad; - __le16 subsystem_id; -} __packed; - -#endif /* __AR9170_EEPROM_H */ diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h deleted file mode 100644 index 06f1f3c951a4..000000000000 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Atheros AR9170 driver - * - * Hardware-specific definitions - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 __AR9170_HW_H -#define __AR9170_HW_H - -#define AR9170_MAX_CMD_LEN 64 - -enum ar9170_cmd { - AR9170_CMD_RREG = 0x00, - AR9170_CMD_WREG = 0x01, - AR9170_CMD_RMEM = 0x02, - AR9170_CMD_WMEM = 0x03, - AR9170_CMD_BITAND = 0x04, - AR9170_CMD_BITOR = 0x05, - AR9170_CMD_EKEY = 0x28, - AR9170_CMD_DKEY = 0x29, - AR9170_CMD_FREQUENCY = 0x30, - AR9170_CMD_RF_INIT = 0x31, - AR9170_CMD_SYNTH = 0x32, - AR9170_CMD_FREQ_START = 0x33, - AR9170_CMD_ECHO = 0x80, - AR9170_CMD_TALLY = 0x81, - AR9170_CMD_TALLY_APD = 0x82, - AR9170_CMD_CONFIG = 0x83, - AR9170_CMD_RESET = 0x90, - AR9170_CMD_DKRESET = 0x91, - AR9170_CMD_DKTX_STATUS = 0x92, - AR9170_CMD_FDC = 0xA0, - AR9170_CMD_WREEPROM = 0xB0, - AR9170_CMD_WFLASH = 0xB0, - AR9170_CMD_FLASH_ERASE = 0xB1, - AR9170_CMD_FLASH_PROG = 0xB2, - AR9170_CMD_FLASH_CHKSUM = 0xB3, - AR9170_CMD_FLASH_READ = 0xB4, - AR9170_CMD_FW_DL_INIT = 0xB5, - AR9170_CMD_MEM_WREEPROM = 0xBB, -}; - -/* endpoints */ -#define AR9170_EP_TX 1 -#define AR9170_EP_RX 2 -#define AR9170_EP_IRQ 3 -#define AR9170_EP_CMD 4 - -#define AR9170_EEPROM_START 0x1600 - -#define AR9170_GPIO_REG_BASE 0x1d0100 -#define AR9170_GPIO_REG_PORT_TYPE AR9170_GPIO_REG_BASE -#define AR9170_GPIO_REG_DATA (AR9170_GPIO_REG_BASE + 4) -#define AR9170_NUM_LEDS 2 - - -#define AR9170_USB_REG_BASE 0x1e1000 -#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108) -#define AR9170_DMA_CTL_ENABLE_TO_DEVICE 0x1 -#define AR9170_DMA_CTL_ENABLE_FROM_DEVICE 0x2 -#define AR9170_DMA_CTL_HIGH_SPEED 0x4 -#define AR9170_DMA_CTL_PACKET_MODE 0x8 - -#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) -#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) - - - -#define AR9170_MAC_REG_BASE 0x1c3000 - -#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514) -#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518) - -#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51C) -#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520) -#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524) - -#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610) -#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614) -#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618) -#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c) - -#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624) -#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628) - -#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62C) - -#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630) -#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634) -#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638) -#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c) -#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640) -#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64C) - -#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658) -#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674) -#define AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC BIT(0) -#define AR9170_MAC_REG_SNIFFER_DEFAULTS 0x02000000 -#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) -#define AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE BIT(3) -#define AR9170_MAC_REG_ENCRYPTION_DEFAULTS 0x70 - -#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680) -#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688) - -#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c) -#define AR9170_MAC_REG_FTF_ASSOC_REQ BIT(0) -#define AR9170_MAC_REG_FTF_ASSOC_RESP BIT(1) -#define AR9170_MAC_REG_FTF_REASSOC_REQ BIT(2) -#define AR9170_MAC_REG_FTF_REASSOC_RESP BIT(3) -#define AR9170_MAC_REG_FTF_PRB_REQ BIT(4) -#define AR9170_MAC_REG_FTF_PRB_RESP BIT(5) -#define AR9170_MAC_REG_FTF_BIT6 BIT(6) -#define AR9170_MAC_REG_FTF_BIT7 BIT(7) -#define AR9170_MAC_REG_FTF_BEACON BIT(8) -#define AR9170_MAC_REG_FTF_ATIM BIT(9) -#define AR9170_MAC_REG_FTF_DEASSOC BIT(10) -#define AR9170_MAC_REG_FTF_AUTH BIT(11) -#define AR9170_MAC_REG_FTF_DEAUTH BIT(12) -#define AR9170_MAC_REG_FTF_BIT13 BIT(13) -#define AR9170_MAC_REG_FTF_BIT14 BIT(14) -#define AR9170_MAC_REG_FTF_BIT15 BIT(15) -#define AR9170_MAC_REG_FTF_BAR BIT(24) -#define AR9170_MAC_REG_FTF_BA BIT(25) -#define AR9170_MAC_REG_FTF_PSPOLL BIT(26) -#define AR9170_MAC_REG_FTF_RTS BIT(27) -#define AR9170_MAC_REG_FTF_CTS BIT(28) -#define AR9170_MAC_REG_FTF_ACK BIT(29) -#define AR9170_MAC_REG_FTF_CFE BIT(30) -#define AR9170_MAC_REG_FTF_CFE_ACK BIT(31) -#define AR9170_MAC_REG_FTF_DEFAULTS 0x0700ffff -#define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff - -#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0) -#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6A4) -#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6A8) -#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6AC) -#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6B0) -#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6BC) -#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6CC) -#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6F4) - - -#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690) -#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698) - -#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6F0) - -#define AR9170_MAC_REG_POWERMANAGEMENT (AR9170_MAC_REG_BASE + 0x700) -#define AR9170_MAC_REG_POWERMGT_IBSS 0xe0 -#define AR9170_MAC_REG_POWERMGT_AP 0xa1 -#define AR9170_MAC_REG_POWERMGT_STA 0x2 -#define AR9170_MAC_REG_POWERMGT_AP_WDS 0x3 -#define AR9170_MAC_REG_POWERMGT_DEFAULTS (0xf << 24) - -#define AR9170_MAC_REG_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704) -#define AR9170_MAC_REG_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708) - -#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xB00) -#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xB04) -#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xB08) -#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xB0C) -#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xB10) -#define AR9170_MAC_REG_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xB14) -#define AR9170_MAC_REG_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xB18) - -#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xB28) - -#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xBB0) -#define AR9170_MAC_FCS_SWFCS 0x1 -#define AR9170_MAC_FCS_FIFO_PROT 0x4 - - -#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xB30) - -#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44) -#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48) - -#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C) -#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0) - -#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00) -#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50) - -#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xD7C) -#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f -#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 -#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000 -#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000 - -#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xD84) -#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xD88) -#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xD90) -#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xD94) -#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xDA0) -#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xDA4) - - -#define AR9170_PWR_REG_BASE 0x1D4000 - -#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) -#define AR9170_PWR_CLK_AHB_40MHZ 0 -#define AR9170_PWR_CLK_AHB_20_22MHZ 1 -#define AR9170_PWR_CLK_AHB_40_44MHZ 2 -#define AR9170_PWR_CLK_AHB_80_88MHZ 3 -#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70 - - -/* put beacon here in memory */ -#define AR9170_BEACON_BUFFER_ADDRESS 0x117900 - - -struct ar9170_tx_control { - __le16 length; - __le16 mac_control; - __le32 phy_control; - u8 frame_data[0]; -} __packed; - -/* these are either-or */ -#define AR9170_TX_MAC_PROT_RTS 0x0001 -#define AR9170_TX_MAC_PROT_CTS 0x0002 - -#define AR9170_TX_MAC_NO_ACK 0x0004 -/* if unset, MAC will only do SIFS space before frame */ -#define AR9170_TX_MAC_BACKOFF 0x0008 -#define AR9170_TX_MAC_BURST 0x0010 -#define AR9170_TX_MAC_AGGR 0x0020 - -/* encryption is a two-bit field */ -#define AR9170_TX_MAC_ENCR_NONE 0x0000 -#define AR9170_TX_MAC_ENCR_RC4 0x0040 -#define AR9170_TX_MAC_ENCR_CENC 0x0080 -#define AR9170_TX_MAC_ENCR_AES 0x00c0 - -#define AR9170_TX_MAC_MMIC 0x0100 -#define AR9170_TX_MAC_HW_DURATION 0x0200 -#define AR9170_TX_MAC_QOS_SHIFT 10 -#define AR9170_TX_MAC_QOS_MASK (3 << AR9170_TX_MAC_QOS_SHIFT) -#define AR9170_TX_MAC_AGGR_QOS_BIT1 0x0400 -#define AR9170_TX_MAC_AGGR_QOS_BIT2 0x0800 -#define AR9170_TX_MAC_DISABLE_TXOP 0x1000 -#define AR9170_TX_MAC_TXOP_RIFS 0x2000 -#define AR9170_TX_MAC_IMM_AMPDU 0x4000 -#define AR9170_TX_MAC_RATE_PROBE 0x8000 - -/* either-or */ -#define AR9170_TX_PHY_MOD_MASK 0x00000003 -#define AR9170_TX_PHY_MOD_CCK 0x00000000 -#define AR9170_TX_PHY_MOD_OFDM 0x00000001 -#define AR9170_TX_PHY_MOD_HT 0x00000002 - -/* depends on modulation */ -#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004 -#define AR9170_TX_PHY_GREENFIELD 0x00000004 - -#define AR9170_TX_PHY_BW_SHIFT 3 -#define AR9170_TX_PHY_BW_MASK (3 << AR9170_TX_PHY_BW_SHIFT) -#define AR9170_TX_PHY_BW_20MHZ 0 -#define AR9170_TX_PHY_BW_40MHZ 2 -#define AR9170_TX_PHY_BW_40MHZ_DUP 3 - -#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT 6 -#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT) - -#define AR9170_TX_PHY_TX_PWR_SHIFT 9 -#define AR9170_TX_PHY_TX_PWR_MASK (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT) - -/* not part of the hw-spec */ -#define AR9170_TX_PHY_QOS_SHIFT 25 -#define AR9170_TX_PHY_QOS_MASK (3 << AR9170_TX_PHY_QOS_SHIFT) - -#define AR9170_TX_PHY_TXCHAIN_SHIFT 15 -#define AR9170_TX_PHY_TXCHAIN_MASK (7 << AR9170_TX_PHY_TXCHAIN_SHIFT) -#define AR9170_TX_PHY_TXCHAIN_1 1 -/* use for cck, ofdm 6/9/12/18/24 and HT if capable */ -#define AR9170_TX_PHY_TXCHAIN_2 5 - -#define AR9170_TX_PHY_MCS_SHIFT 18 -#define AR9170_TX_PHY_MCS_MASK (0x7f << AR9170_TX_PHY_MCS_SHIFT) - -#define AR9170_TX_PHY_SHORT_GI 0x80000000 - -#define AR5416_MAX_RATE_POWER 63 - -struct ar9170_rx_head { - u8 plcp[12]; -} __packed; - -struct ar9170_rx_phystatus { - union { - struct { - u8 rssi_ant0, rssi_ant1, rssi_ant2, - rssi_ant0x, rssi_ant1x, rssi_ant2x, - rssi_combined; - } __packed; - u8 rssi[7]; - } __packed; - - u8 evm_stream0[6], evm_stream1[6]; - u8 phy_err; -} __packed; - -struct ar9170_rx_macstatus { - u8 SAidx, DAidx; - u8 error; - u8 status; -} __packed; - -#define AR9170_ENC_ALG_NONE 0x0 -#define AR9170_ENC_ALG_WEP64 0x1 -#define AR9170_ENC_ALG_TKIP 0x2 -#define AR9170_ENC_ALG_AESCCMP 0x4 -#define AR9170_ENC_ALG_WEP128 0x5 -#define AR9170_ENC_ALG_WEP256 0x6 -#define AR9170_ENC_ALG_CENC 0x7 - -#define AR9170_RX_ENC_SOFTWARE 0x8 - -static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) -{ - return (t->SAidx & 0xc0) >> 4 | - (t->DAidx & 0xc0) >> 6; -} - -#define AR9170_RX_STATUS_MODULATION_MASK 0x03 -#define AR9170_RX_STATUS_MODULATION_CCK 0x00 -#define AR9170_RX_STATUS_MODULATION_OFDM 0x01 -#define AR9170_RX_STATUS_MODULATION_HT 0x02 -#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03 - -/* depends on modulation */ -#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08 -#define AR9170_RX_STATUS_GREENFIELD 0x08 - -#define AR9170_RX_STATUS_MPDU_MASK 0x30 -#define AR9170_RX_STATUS_MPDU_SINGLE 0x00 -#define AR9170_RX_STATUS_MPDU_FIRST 0x20 -#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 -#define AR9170_RX_STATUS_MPDU_LAST 0x10 - -#define AR9170_RX_ERROR_RXTO 0x01 -#define AR9170_RX_ERROR_OVERRUN 0x02 -#define AR9170_RX_ERROR_DECRYPT 0x04 -#define AR9170_RX_ERROR_FCS 0x08 -#define AR9170_RX_ERROR_WRONG_RA 0x10 -#define AR9170_RX_ERROR_PLCP 0x20 -#define AR9170_RX_ERROR_MMIC 0x40 -#define AR9170_RX_ERROR_FATAL 0x80 - -struct ar9170_cmd_tx_status { - u8 dst[ETH_ALEN]; - __le32 rate; - __le16 status; -} __packed; - -#define AR9170_TX_STATUS_COMPLETE 0x00 -#define AR9170_TX_STATUS_RETRY 0x01 -#define AR9170_TX_STATUS_FAILED 0x02 - -struct ar9170_cmd_ba_failed_count { - __le16 failed; - __le16 rate; -} __packed; - -struct ar9170_cmd_response { - u8 flag; - u8 type; - __le16 padding; - - union { - struct ar9170_cmd_tx_status tx_status; - struct ar9170_cmd_ba_failed_count ba_fail_cnt; - u8 data[0]; - }; -} __packed; - -/* QoS */ - -/* mac80211 queue to HW/FW map */ -static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 }; - -/* HW/FW queue to mac80211 map */ -static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 }; - -enum ar9170_txq { - AR9170_TXQ_BE, - AR9170_TXQ_BK, - AR9170_TXQ_VI, - AR9170_TXQ_VO, - - __AR9170_NUM_TXQ, -}; - -#define AR9170_TXQ_DEPTH 32 -#define AR9170_TX_MAX_PENDING 128 -#define AR9170_RX_STREAM_MAX_SIZE 65535 - -#endif /* __AR9170_HW_H */ diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c deleted file mode 100644 index 832d90087f8a..000000000000 --- a/drivers/net/wireless/ath/ar9170/led.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Atheros AR9170 driver - * - * LED handling - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 "ar9170.h" -#include "cmd.h" - -int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state) -{ - return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state); -} - -int ar9170_init_leds(struct ar9170 *ar) -{ - int err; - - /* disable LEDs */ - /* GPIO [0/1 mode: output, 2/3: input] */ - err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3); - if (err) - goto out; - - /* GPIO 0/1 value: off */ - err = ar9170_set_leds_state(ar, 0); - -out: - return err; -} - -#ifdef CONFIG_AR9170_LEDS -static void ar9170_update_leds(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, led_work.work); - int i, tmp, blink_delay = 1000; - u32 led_val = 0; - bool rerun = false; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return ; - - mutex_lock(&ar->mutex); - for (i = 0; i < AR9170_NUM_LEDS; i++) - if (ar->leds[i].registered && ar->leds[i].toggled) { - led_val |= 1 << i; - - tmp = 70 + 200 / (ar->leds[i].toggled); - if (tmp < blink_delay) - blink_delay = tmp; - - if (ar->leds[i].toggled > 1) - ar->leds[i].toggled = 0; - - rerun = true; - } - - ar9170_set_leds_state(ar, led_val); - mutex_unlock(&ar->mutex); - - if (!rerun) - return; - - ieee80211_queue_delayed_work(ar->hw, - &ar->led_work, - msecs_to_jiffies(blink_delay)); -} - -static void ar9170_led_brightness_set(struct led_classdev *led, - enum led_brightness brightness) -{ - struct ar9170_led *arl = container_of(led, struct ar9170_led, l); - struct ar9170 *ar = arl->ar; - - if (unlikely(!arl->registered)) - return ; - - if (arl->last_state != !!brightness) { - arl->toggled++; - arl->last_state = !!brightness; - } - - if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) - ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); -} - -static int ar9170_register_led(struct ar9170 *ar, int i, char *name, - char *trigger) -{ - int err; - - snprintf(ar->leds[i].name, sizeof(ar->leds[i].name), - "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name); - - ar->leds[i].ar = ar; - ar->leds[i].l.name = ar->leds[i].name; - ar->leds[i].l.brightness_set = ar9170_led_brightness_set; - ar->leds[i].l.brightness = 0; - ar->leds[i].l.default_trigger = trigger; - - err = led_classdev_register(wiphy_dev(ar->hw->wiphy), - &ar->leds[i].l); - if (err) - wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", - ar->leds[i].name, err); - else - ar->leds[i].registered = true; - - return err; -} - -void ar9170_unregister_leds(struct ar9170 *ar) -{ - int i; - - for (i = 0; i < AR9170_NUM_LEDS; i++) - if (ar->leds[i].registered) { - led_classdev_unregister(&ar->leds[i].l); - ar->leds[i].registered = false; - ar->leds[i].toggled = 0; - } - - cancel_delayed_work_sync(&ar->led_work); -} - -int ar9170_register_leds(struct ar9170 *ar) -{ - int err; - - INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds); - - err = ar9170_register_led(ar, 0, "tx", - ieee80211_get_tx_led_name(ar->hw)); - if (err) - goto fail; - - err = ar9170_register_led(ar, 1, "assoc", - ieee80211_get_assoc_led_name(ar->hw)); - if (err) - goto fail; - - return 0; - -fail: - ar9170_unregister_leds(ar); - return err; -} - -#endif /* CONFIG_AR9170_LEDS */ diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c deleted file mode 100644 index 857e86104295..000000000000 --- a/drivers/net/wireless/ath/ar9170/mac.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Atheros AR9170 driver - * - * MAC programming - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 "ar9170.h" -#include "cmd.h" - -int ar9170_set_dyn_sifs_ack(struct ar9170 *ar) -{ - u32 val; - - if (conf_is_ht40(&ar->hw->conf)) - val = 0x010a; - else { - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) - val = 0x105; - else - val = 0x104; - } - - return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); -} - -int ar9170_set_slot_time(struct ar9170 *ar) -{ - u32 slottime = 20; - - if (!ar->vif) - return 0; - - if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || - ar->vif->bss_conf.use_short_slot) - slottime = 9; - - return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10); -} - -int ar9170_set_basic_rates(struct ar9170 *ar) -{ - u8 cck, ofdm; - - if (!ar->vif) - return 0; - - ofdm = ar->vif->bss_conf.basic_rates >> 4; - - /* FIXME: is still necessary? */ - if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) - cck = 0; - else - cck = ar->vif->bss_conf.basic_rates & 0xf; - - return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE, - ofdm << 8 | cck); -} - -int ar9170_set_qos(struct ar9170 *ar) -{ - ar9170_regwrite_begin(ar); - - ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min | - (ar->edcf[0].cw_max << 16)); - ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min | - (ar->edcf[1].cw_max << 16)); - ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min | - (ar->edcf[2].cw_max << 16)); - ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min | - (ar->edcf[3].cw_max << 16)); - ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min | - (ar->edcf[4].cw_max << 16)); - - ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS, - ((ar->edcf[0].aifs * 9 + 10)) | - ((ar->edcf[1].aifs * 9 + 10) << 12) | - ((ar->edcf[2].aifs * 9 + 10) << 24)); - ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS, - ((ar->edcf[2].aifs * 9 + 10) >> 8) | - ((ar->edcf[3].aifs * 9 + 10) << 4) | - ((ar->edcf[4].aifs * 9 + 10) << 16)); - - ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, - ar->edcf[0].txop | ar->edcf[1].txop << 16); - ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, - ar->edcf[2].txop | ar->edcf[3].txop << 16); - - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity) -{ - u32 val; - - /* don't allow AMPDU density > 8us */ - if (mpdudensity > 6) - return -EINVAL; - - /* Watch out! Otus uses slightly different density values. */ - val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0); - - ar9170_regwrite_begin(ar); - ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val); - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -int ar9170_init_mac(struct ar9170 *ar) -{ - ar9170_regwrite_begin(ar); - - ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40); - - ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0); - - /* enable MMIC */ - ar9170_regwrite(AR9170_MAC_REG_SNIFFER, - AR9170_MAC_REG_SNIFFER_DEFAULTS); - - ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80); - - ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70); - ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000); - ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10); - - /* CF-END mode */ - ar9170_regwrite(0x1c3b2c, 0x19000000); - - /* NAV protects ACK only (in TXOP) */ - ar9170_regwrite(0x1c3b38, 0x201); - - /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ - /* OTUS set AM to 0x1 */ - ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170); - - ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); - - /* AGG test code*/ - /* Aggregation MAX number and timeout */ - ar9170_regwrite(0x1c3b9c, 0x10000a); - - ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, - AR9170_MAC_REG_FTF_DEFAULTS); - - /* Enable deaggregator, response in sniffer mode */ - ar9170_regwrite(0x1c3c40, 0x1 | 1<<30); - - /* rate sets */ - ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f); - ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f); - ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb); - - /* MIMO response control */ - ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */ - - /* switch MAC to OTUS interface */ - ar9170_regwrite(0x1c3600, 0x3); - - ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff); - - /* set PHY register read timeout (??) */ - ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008); - - /* Disable Rx TimeOut, workaround for BB. */ - ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0); - - /* Set CPU clock frequency to 88/80MHz */ - ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL, - AR9170_PWR_CLK_AHB_80_88MHZ | - AR9170_PWR_CLK_DAC_160_INV_DLY); - - /* Set WLAN DMA interrupt mode: generate int per packet */ - ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011); - - ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT, - AR9170_MAC_FCS_FIFO_PROT); - - /* Disables the CF_END frame, undocumented register */ - ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND, - 0x141E0F48); - - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac) -{ - static const u8 zero[ETH_ALEN] = { 0 }; - - if (!mac) - mac = zero; - - ar9170_regwrite_begin(ar); - - ar9170_regwrite(reg, get_unaligned_le32(mac)); - ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); - - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) -{ - int err; - - ar9170_regwrite_begin(ar); - ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); - ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); - ar9170_regwrite_finish(); - err = ar9170_regwrite_result(); - if (err) - return err; - - ar->cur_mc_hash = mc_hash; - return 0; -} - -int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter) -{ - int err; - - err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter); - if (err) - return err; - - ar->cur_filter = filter; - return 0; -} - -static int ar9170_set_promiscouous(struct ar9170 *ar) -{ - u32 encr_mode, sniffer; - int err; - - err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer); - if (err) - return err; - - err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode); - if (err) - return err; - - if (ar->sniffer_enabled) { - sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC; - - /* - * Rx decryption works in place. - * - * If we don't disable it, the hardware will render all - * encrypted frames which are encrypted with an unknown - * key useless. - */ - - encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE; - ar->sniffer_enabled = true; - } else { - sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC; - - if (ar->rx_software_decryption) - encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE; - else - encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE; - } - - ar9170_regwrite_begin(ar); - ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode); - ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -int ar9170_set_operating_mode(struct ar9170 *ar) -{ - struct ath_common *common = &ar->common; - u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS; - u8 *mac_addr, *bssid; - int err; - - if (ar->vif) { - mac_addr = common->macaddr; - bssid = common->curbssid; - - switch (ar->vif->type) { - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_ADHOC: - pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS; - break; - case NL80211_IFTYPE_AP: - pm_mode |= AR9170_MAC_REG_POWERMGT_AP; - break; - case NL80211_IFTYPE_WDS: - pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS; - break; - case NL80211_IFTYPE_MONITOR: - ar->sniffer_enabled = true; - ar->rx_software_decryption = true; - break; - default: - pm_mode |= AR9170_MAC_REG_POWERMGT_STA; - break; - } - } else { - mac_addr = NULL; - bssid = NULL; - } - - err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); - if (err) - return err; - - err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); - if (err) - return err; - - err = ar9170_set_promiscouous(ar); - if (err) - return err; - - /* set AMPDU density to 8us. */ - err = ar9170_set_ampdu_density(ar, 6); - if (err) - return err; - - ar9170_regwrite_begin(ar); - - ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode); - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry) -{ - u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); - - return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); -} - -int ar9170_set_beacon_timers(struct ar9170 *ar) -{ - u32 v = 0; - u32 pretbtt = 0; - - if (ar->vif) { - v |= ar->vif->bss_conf.beacon_int; - - if (ar->enable_beacon) { - switch (ar->vif->type) { - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_ADHOC: - v |= BIT(25); - break; - case NL80211_IFTYPE_AP: - v |= BIT(24); - pretbtt = (ar->vif->bss_conf.beacon_int - 6) << - 16; - break; - default: - break; - } - } - - v |= ar->vif->bss_conf.dtim_period << 16; - } - - ar9170_regwrite_begin(ar); - ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); - ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); - ar9170_regwrite_finish(); - return ar9170_regwrite_result(); -} - -int ar9170_update_beacon(struct ar9170 *ar) -{ - struct sk_buff *skb; - __le32 *data, *old = NULL; - u32 word; - int i; - - skb = ieee80211_beacon_get(ar->hw, ar->vif); - if (!skb) - return -ENOMEM; - - data = (__le32 *)skb->data; - if (ar->beacon) - old = (__le32 *)ar->beacon->data; - - ar9170_regwrite_begin(ar); - for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { - /* - * XXX: This accesses beyond skb data for up - * to the last 3 bytes!! - */ - - if (old && (data[i] == old[i])) - continue; - - word = le32_to_cpu(data[i]); - ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word); - } - - /* XXX: use skb->cb info */ - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) - ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, - ((skb->len + 4) << (3 + 16)) + 0x0400); - else - ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, - ((skb->len + 4) << 16) + 0x001b); - - ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4); - ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS); - ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1); - - ar9170_regwrite_finish(); - - dev_kfree_skb(ar->beacon); - ar->beacon = skb; - - return ar9170_regwrite_result(); -} - -void ar9170_new_beacon(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, - beacon_work); - struct sk_buff *skb; - - if (unlikely(!IS_STARTED(ar))) - return ; - - mutex_lock(&ar->mutex); - - if (!ar->vif) - goto out; - - ar9170_update_beacon(ar); - - rcu_read_lock(); - while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif))) - ar9170_op_tx(ar->hw, skb); - - rcu_read_unlock(); - - out: - mutex_unlock(&ar->mutex); -} - -int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype, - u8 keyidx, u8 *keydata, int keylen) -{ - __le32 vals[7]; - static const u8 bcast[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - u8 dummy; - - mac = mac ? : bcast; - - vals[0] = cpu_to_le32((keyidx << 16) + id); - vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype); - vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 | - mac[3] << 8 | mac[2]); - memset(&vals[3], 0, 16); - if (keydata) - memcpy(&vals[3], keydata, keylen); - - return ar->exec_cmd(ar, AR9170_CMD_EKEY, - sizeof(vals), (u8 *)vals, - 1, &dummy); -} - -int ar9170_disable_key(struct ar9170 *ar, u8 id) -{ - __le32 val = cpu_to_le32(id); - u8 dummy; - - return ar->exec_cmd(ar, AR9170_CMD_EKEY, - sizeof(val), (u8 *)&val, - 1, &dummy); -} diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c deleted file mode 100644 index b761fec0d721..000000000000 --- a/drivers/net/wireless/ath/ar9170/main.c +++ /dev/null @@ -1,2190 +0,0 @@ -/* - * Atheros AR9170 driver - * - * mac80211 interaction code - * - * Copyright 2008, Johannes Berg - * Copyright 2009, Christian Lamparter - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 -#include -#include "ar9170.h" -#include "hw.h" -#include "cmd.h" - -static int modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); -MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); - -#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ - .bitrate = (_bitrate), \ - .flags = (_flags), \ - .hw_value = (_hw_rate) | (_txpidx) << 4, \ -} - -static struct ieee80211_rate __ar9170_ratetable[] = { - RATE(10, 0, 0, 0), - RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(60, 0xb, 0, 0), - RATE(90, 0xf, 0, 0), - RATE(120, 0xa, 0, 0), - RATE(180, 0xe, 0, 0), - RATE(240, 0x9, 0, 0), - RATE(360, 0xd, 1, 0), - RATE(480, 0x8, 2, 0), - RATE(540, 0xc, 3, 0), -}; -#undef RATE - -#define ar9170_g_ratetable (__ar9170_ratetable + 0) -#define ar9170_g_ratetable_size 12 -#define ar9170_a_ratetable (__ar9170_ratetable + 4) -#define ar9170_a_ratetable_size 8 - -/* - * NB: The hw_value is used as an index into the ar9170_phy_freq_params - * array in phy.c so that we don't have to do frequency lookups! - */ -#define CHAN(_freq, _idx) { \ - .center_freq = (_freq), \ - .hw_value = (_idx), \ - .max_power = 18, /* XXX */ \ -} - -static struct ieee80211_channel ar9170_2ghz_chantable[] = { - CHAN(2412, 0), - CHAN(2417, 1), - CHAN(2422, 2), - CHAN(2427, 3), - CHAN(2432, 4), - CHAN(2437, 5), - CHAN(2442, 6), - CHAN(2447, 7), - CHAN(2452, 8), - CHAN(2457, 9), - CHAN(2462, 10), - CHAN(2467, 11), - CHAN(2472, 12), - CHAN(2484, 13), -}; - -static struct ieee80211_channel ar9170_5ghz_chantable[] = { - CHAN(4920, 14), - CHAN(4940, 15), - CHAN(4960, 16), - CHAN(4980, 17), - CHAN(5040, 18), - CHAN(5060, 19), - CHAN(5080, 20), - CHAN(5180, 21), - CHAN(5200, 22), - CHAN(5220, 23), - CHAN(5240, 24), - CHAN(5260, 25), - CHAN(5280, 26), - CHAN(5300, 27), - CHAN(5320, 28), - CHAN(5500, 29), - CHAN(5520, 30), - CHAN(5540, 31), - CHAN(5560, 32), - CHAN(5580, 33), - CHAN(5600, 34), - CHAN(5620, 35), - CHAN(5640, 36), - CHAN(5660, 37), - CHAN(5680, 38), - CHAN(5700, 39), - CHAN(5745, 40), - CHAN(5765, 41), - CHAN(5785, 42), - CHAN(5805, 43), - CHAN(5825, 44), - CHAN(5170, 45), - CHAN(5190, 46), - CHAN(5210, 47), - CHAN(5230, 48), -}; -#undef CHAN - -#define AR9170_HT_CAP \ -{ \ - .ht_supported = true, \ - .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ - IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ - IEEE80211_HT_CAP_SGI_40 | \ - IEEE80211_HT_CAP_GRN_FLD | \ - IEEE80211_HT_CAP_DSSSCCK40 | \ - IEEE80211_HT_CAP_SM_PS, \ - .ampdu_factor = 3, \ - .ampdu_density = 6, \ - .mcs = { \ - .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \ - .rx_highest = cpu_to_le16(300), \ - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ - }, \ -} - -static struct ieee80211_supported_band ar9170_band_2GHz = { - .channels = ar9170_2ghz_chantable, - .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable), - .bitrates = ar9170_g_ratetable, - .n_bitrates = ar9170_g_ratetable_size, - .ht_cap = AR9170_HT_CAP, -}; - -static struct ieee80211_supported_band ar9170_band_5GHz = { - .channels = ar9170_5ghz_chantable, - .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable), - .bitrates = ar9170_a_ratetable, - .n_bitrates = ar9170_a_ratetable_size, - .ht_cap = AR9170_HT_CAP, -}; - -static void ar9170_tx(struct ar9170 *ar); - -static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr) -{ - return le16_to_cpu(hdr->seq_ctrl) >> 4; -} - -static inline u16 ar9170_get_seq(struct sk_buff *skb) -{ - struct ar9170_tx_control *txc = (void *) skb->data; - return ar9170_get_seq_h((void *) txc->frame_data); -} - -#ifdef AR9170_QUEUE_DEBUG -static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ar9170_tx_control *txc = (void *) skb->data; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; - - wiphy_debug(ar->hw->wiphy, - "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d " - "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", - skb, skb_get_queue_mapping(skb), - ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), - le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), - jiffies_to_msecs(arinfo->timeout - jiffies)); -} - -static void __ar9170_dump_txqueue(struct ar9170 *ar, - struct sk_buff_head *queue) -{ - struct sk_buff *skb; - int i = 0; - - printk(KERN_DEBUG "---[ cut here ]---\n"); - wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n", - skb_queue_len(queue)); - - skb_queue_walk(queue, skb) { - printk(KERN_DEBUG "index:%d =>\n", i++); - ar9170_print_txheader(ar, skb); - } - if (i != skb_queue_len(queue)) - printk(KERN_DEBUG "WARNING: queue frame counter " - "mismatch %d != %d\n", skb_queue_len(queue), i); - printk(KERN_DEBUG "---[ end ]---\n"); -} -#endif /* AR9170_QUEUE_DEBUG */ - -#ifdef AR9170_QUEUE_DEBUG -static void ar9170_dump_txqueue(struct ar9170 *ar, - struct sk_buff_head *queue) -{ - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - __ar9170_dump_txqueue(ar, queue); - spin_unlock_irqrestore(&queue->lock, flags); -} -#endif /* AR9170_QUEUE_DEBUG */ - -#ifdef AR9170_QUEUE_STOP_DEBUG -static void __ar9170_dump_txstats(struct ar9170 *ar) -{ - int i; - - wiphy_debug(ar->hw->wiphy, "QoS queue stats\n"); - - for (i = 0; i < __AR9170_NUM_TXQ; i++) - wiphy_debug(ar->hw->wiphy, - "queue:%d limit:%d len:%d waitack:%d stopped:%d\n", - i, ar->tx_stats[i].limit, ar->tx_stats[i].len, - skb_queue_len(&ar->tx_status[i]), - ieee80211_queue_stopped(ar->hw, i)); -} -#endif /* AR9170_QUEUE_STOP_DEBUG */ - -/* caller must guarantee exclusive access for _bin_ queue. */ -static void ar9170_recycle_expired(struct ar9170 *ar, - struct sk_buff_head *queue, - struct sk_buff_head *bin) -{ - struct sk_buff *skb, *old = NULL; - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - while ((skb = skb_peek(queue))) { - struct ieee80211_tx_info *txinfo; - struct ar9170_tx_info *arinfo; - - txinfo = IEEE80211_SKB_CB(skb); - arinfo = (void *) txinfo->rate_driver_data; - - if (time_is_before_jiffies(arinfo->timeout)) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "[%ld > %ld] frame expired => recycle\n", - jiffies, arinfo->timeout); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - __skb_unlink(skb, queue); - __skb_queue_tail(bin, skb); - } else { - break; - } - - if (unlikely(old == skb)) { - /* bail out - queue is shot. */ - - WARN_ON(1); - break; - } - old = skb; - } - spin_unlock_irqrestore(&queue->lock, flags); -} - -static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, - u16 tx_status) -{ - struct ieee80211_tx_info *txinfo; - unsigned int retries = 0; - - txinfo = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(txinfo); - - switch (tx_status) { - case AR9170_TX_STATUS_RETRY: - retries = 2; - case AR9170_TX_STATUS_COMPLETE: - txinfo->flags |= IEEE80211_TX_STAT_ACK; - break; - - case AR9170_TX_STATUS_FAILED: - retries = ar->hw->conf.long_frame_max_tx_count; - break; - - default: - wiphy_err(ar->hw->wiphy, - "invalid tx_status response (%x)\n", tx_status); - break; - } - - txinfo->status.rates[0].count = retries + 1; - skb_pull(skb, sizeof(struct ar9170_tx_control)); - ieee80211_tx_status_irqsafe(ar->hw, skb); -} - -void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data; - unsigned int queue = skb_get_queue_mapping(skb); - unsigned long flags; - - spin_lock_irqsave(&ar->tx_stats_lock, flags); - ar->tx_stats[queue].len--; - - if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { -#ifdef AR9170_QUEUE_STOP_DEBUG - wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue); - __ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_STOP_DEBUG */ - ieee80211_wake_queue(ar->hw, queue); - } - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - - if (info->flags & IEEE80211_TX_CTL_NO_ACK) { - ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); - } else { - arinfo->timeout = jiffies + - msecs_to_jiffies(AR9170_TX_TIMEOUT); - - skb_queue_tail(&ar->tx_status[queue], skb); - } - - if (!ar->tx_stats[queue].len && - !skb_queue_empty(&ar->tx_pending[queue])) { - ar9170_tx(ar); - } -} - -static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, - const u8 *mac, - struct sk_buff_head *queue, - const u32 rate) -{ - unsigned long flags; - struct sk_buff *skb; - - /* - * Unfortunately, the firmware does not tell to which (queued) frame - * this transmission status report belongs to. - * - * So we have to make risky guesses - with the scarce information - * the firmware provided (-> destination MAC, and phy_control) - - * and hope that we picked the right one... - */ - - spin_lock_irqsave(&queue->lock, flags); - skb_queue_walk(queue, skb) { - struct ar9170_tx_control *txc = (void *) skb->data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; - u32 r; - - if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "skip frame => DA %pM != %pM\n", - mac, ieee80211_get_DA(hdr)); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - continue; - } - - r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >> - AR9170_TX_PHY_MCS_SHIFT; - - if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "skip frame => rate %d != %d\n", rate, r); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - continue; - } - - __skb_unlink(skb, queue); - spin_unlock_irqrestore(&queue->lock, flags); - return skb; - } - -#ifdef AR9170_QUEUE_DEBUG - wiphy_err(ar->hw->wiphy, - "ESS:[%pM] does not have any outstanding frames in queue.\n", - mac); - __ar9170_dump_txqueue(ar, queue); -#endif /* AR9170_QUEUE_DEBUG */ - spin_unlock_irqrestore(&queue->lock, flags); - - return NULL; -} - -/* - * This worker tries to keeps an maintain tx_status queues. - * So we can guarantee that incoming tx_status reports are - * actually for a pending frame. - */ - -static void ar9170_tx_janitor(struct work_struct *work) -{ - struct ar9170 *ar = container_of(work, struct ar9170, - tx_janitor.work); - struct sk_buff_head waste; - unsigned int i; - bool resched = false; - - if (unlikely(!IS_STARTED(ar))) - return ; - - skb_queue_head_init(&waste); - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n", - i); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); - ar9170_dump_txqueue(ar, &ar->tx_status[i]); -#endif /* AR9170_QUEUE_DEBUG */ - - ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); - ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); - skb_queue_purge(&waste); - - if (!skb_queue_empty(&ar->tx_status[i]) || - !skb_queue_empty(&ar->tx_pending[i])) - resched = true; - } - - if (!resched) - return; - - ieee80211_queue_delayed_work(ar->hw, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); -} - -void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) -{ - struct ar9170_cmd_response *cmd = (void *) buf; - - if ((cmd->type & 0xc0) != 0xc0) { - ar->callback_cmd(ar, len, buf); - return; - } - - /* hardware event handlers */ - switch (cmd->type) { - case 0xc1: { - /* - * TX status notification: - * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1 - * - * XX always 81 - * YY always 00 - * M1-M6 is the MAC address - * R1-R4 is the transmit rate - * S1-S2 is the transmit status - */ - - struct sk_buff *skb; - u32 phy = le32_to_cpu(cmd->tx_status.rate); - u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> - AR9170_TX_PHY_QOS_SHIFT; -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "recv tx_status for %pm, p:%08x, q:%d\n", - cmd->tx_status.dst, phy, q); -#endif /* AR9170_QUEUE_DEBUG */ - - skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, - &ar->tx_status[q], - AR9170_TX_INVALID_RATE); - if (unlikely(!skb)) - return ; - - ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); - break; - } - - case 0xc0: - /* - * pre-TBTT event - */ - if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP) - ieee80211_queue_work(ar->hw, &ar->beacon_work); - break; - - case 0xc2: - /* - * (IBSS) beacon send notification - * bytes: 04 c2 XX YY B4 B3 B2 B1 - * - * XX always 80 - * YY always 00 - * B1-B4 "should" be the number of send out beacons. - */ - break; - - case 0xc3: - /* End of Atim Window */ - break; - - case 0xc4: - /* BlockACK bitmap */ - break; - - case 0xc5: - /* BlockACK events */ - break; - - case 0xc6: - /* Watchdog Interrupt */ - break; - - case 0xc9: - /* retransmission issue / SIFS/EIFS collision ?! */ - break; - - /* firmware debug */ - case 0xca: - printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, - (char *)buf + 4); - break; - case 0xcb: - len -= 4; - - switch (len) { - case 1: - printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n", - *((char *)buf + 4)); - break; - case 2: - printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n", - le16_to_cpup((__le16 *)((char *)buf + 4))); - break; - case 4: - printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n", - le32_to_cpup((__le32 *)((char *)buf + 4))); - break; - case 8: - printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n", - (unsigned long)le64_to_cpup( - (__le64 *)((char *)buf + 4))); - break; - } - break; - case 0xcc: - print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE, - (char *)buf + 4, len - 4); - break; - - default: - pr_info("received unhandled event %x\n", cmd->type); - print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); - break; - } -} - -static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) -{ - memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head)); - ar->rx_mpdu.has_plcp = false; -} - -int ar9170_nag_limiter(struct ar9170 *ar) -{ - bool print_message; - - /* - * we expect all sorts of errors in promiscuous mode. - * don't bother with it, it's OK! - */ - if (ar->sniffer_enabled) - return false; - - /* - * only go for frequent errors! The hardware tends to - * do some stupid thing once in a while under load, in - * noisy environments or just for fun! - */ - if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit()) - print_message = true; - else - print_message = false; - - /* reset threshold for "once in a while" */ - ar->bad_hw_nagger = jiffies + HZ / 4; - return print_message; -} - -static int ar9170_rx_mac_status(struct ar9170 *ar, - struct ar9170_rx_head *head, - struct ar9170_rx_macstatus *mac, - struct ieee80211_rx_status *status) -{ - u8 error, decrypt; - - BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); - BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); - - error = mac->error; - if (error & AR9170_RX_ERROR_MMIC) { - status->flag |= RX_FLAG_MMIC_ERROR; - error &= ~AR9170_RX_ERROR_MMIC; - } - - if (error & AR9170_RX_ERROR_PLCP) { - status->flag |= RX_FLAG_FAILED_PLCP_CRC; - error &= ~AR9170_RX_ERROR_PLCP; - - if (!(ar->filter_state & FIF_PLCPFAIL)) - return -EINVAL; - } - - if (error & AR9170_RX_ERROR_FCS) { - status->flag |= RX_FLAG_FAILED_FCS_CRC; - error &= ~AR9170_RX_ERROR_FCS; - - if (!(ar->filter_state & FIF_FCSFAIL)) - return -EINVAL; - } - - decrypt = ar9170_get_decrypt_type(mac); - if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && - decrypt != AR9170_ENC_ALG_NONE) - status->flag |= RX_FLAG_DECRYPTED; - - /* ignore wrong RA errors */ - error &= ~AR9170_RX_ERROR_WRONG_RA; - - if (error & AR9170_RX_ERROR_DECRYPT) { - error &= ~AR9170_RX_ERROR_DECRYPT; - /* - * Rx decryption is done in place, - * the original data is lost anyway. - */ - - return -EINVAL; - } - - /* drop any other error frames */ - if (unlikely(error)) { - /* TODO: update netdevice's RX dropped/errors statistics */ - - if (ar9170_nag_limiter(ar)) - wiphy_debug(ar->hw->wiphy, - "received frame with suspicious error code (%#x).\n", - error); - - return -EINVAL; - } - - status->band = ar->channel->band; - status->freq = ar->channel->center_freq; - - switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) { - case AR9170_RX_STATUS_MODULATION_CCK: - if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) - status->flag |= RX_FLAG_SHORTPRE; - switch (head->plcp[0]) { - case 0x0a: - status->rate_idx = 0; - break; - case 0x14: - status->rate_idx = 1; - break; - case 0x37: - status->rate_idx = 2; - break; - case 0x6e: - status->rate_idx = 3; - break; - default: - if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "invalid plcp cck rate (%x).\n", - head->plcp[0]); - return -EINVAL; - } - break; - - case AR9170_RX_STATUS_MODULATION_DUPOFDM: - case AR9170_RX_STATUS_MODULATION_OFDM: - switch (head->plcp[0] & 0xf) { - case 0xb: - status->rate_idx = 0; - break; - case 0xf: - status->rate_idx = 1; - break; - case 0xa: - status->rate_idx = 2; - break; - case 0xe: - status->rate_idx = 3; - break; - case 0x9: - status->rate_idx = 4; - break; - case 0xd: - status->rate_idx = 5; - break; - case 0x8: - status->rate_idx = 6; - break; - case 0xc: - status->rate_idx = 7; - break; - default: - if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "invalid plcp ofdm rate (%x).\n", - head->plcp[0]); - return -EINVAL; - } - if (status->band == IEEE80211_BAND_2GHZ) - status->rate_idx += 4; - break; - - case AR9170_RX_STATUS_MODULATION_HT: - if (head->plcp[3] & 0x80) - status->flag |= RX_FLAG_40MHZ; - if (head->plcp[6] & 0x80) - status->flag |= RX_FLAG_SHORT_GI; - - status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f); - status->flag |= RX_FLAG_HT; - break; - - default: - if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, "invalid modulation\n"); - return -EINVAL; - } - - return 0; -} - -static void ar9170_rx_phy_status(struct ar9170 *ar, - struct ar9170_rx_phystatus *phy, - struct ieee80211_rx_status *status) -{ - int i; - - BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); - - for (i = 0; i < 3; i++) - if (phy->rssi[i] != 0x80) - status->antenna |= BIT(i); - - /* post-process RSSI */ - for (i = 0; i < 7; i++) - if (phy->rssi[i] & 0x80) - phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; - - /* TODO: we could do something with phy_errors */ - status->signal = ar->noise[0] + phy->rssi_combined; -} - -static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) -{ - struct sk_buff *skb; - int reserved = 0; - struct ieee80211_hdr *hdr = (void *) buf; - - if (ieee80211_is_data_qos(hdr->frame_control)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); - reserved += NET_IP_ALIGN; - - if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) - reserved += NET_IP_ALIGN; - } - - if (ieee80211_has_a4(hdr->frame_control)) - reserved += NET_IP_ALIGN; - - reserved = 32 + (reserved & NET_IP_ALIGN); - - skb = dev_alloc_skb(len + reserved); - if (likely(skb)) { - skb_reserve(skb, reserved); - memcpy(skb_put(skb, len), buf, len); - } - - return skb; -} - -/* - * If the frame alignment is right (or the kernel has - * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there - * is only a single MPDU in the USB frame, then we could - * submit to mac80211 the SKB directly. However, since - * there may be multiple packets in one SKB in stream - * mode, and we need to observe the proper ordering, - * this is non-trivial. - */ - -static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) -{ - struct ar9170_rx_head *head; - struct ar9170_rx_macstatus *mac; - struct ar9170_rx_phystatus *phy = NULL; - struct ieee80211_rx_status status; - struct sk_buff *skb; - int mpdu_len; - - if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac)))) - return ; - - /* Received MPDU */ - mpdu_len = len - sizeof(*mac); - - mac = (void *)(buf + mpdu_len); - if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { - /* this frame is too damaged and can't be used - drop it */ - - return ; - } - - switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) { - case AR9170_RX_STATUS_MPDU_FIRST: - /* first mpdu packet has the plcp header */ - if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { - head = (void *) buf; - memcpy(&ar->rx_mpdu.plcp, (void *) buf, - sizeof(struct ar9170_rx_head)); - - mpdu_len -= sizeof(struct ar9170_rx_head); - buf += sizeof(struct ar9170_rx_head); - ar->rx_mpdu.has_plcp = true; - } else { - if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "plcp info is clipped.\n"); - return ; - } - break; - - case AR9170_RX_STATUS_MPDU_LAST: - /* last mpdu has a extra tail with phy status information */ - - if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { - mpdu_len -= sizeof(struct ar9170_rx_phystatus); - phy = (void *)(buf + mpdu_len); - } else { - if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "frame tail is clipped.\n"); - return ; - } - - case AR9170_RX_STATUS_MPDU_MIDDLE: - /* middle mpdus are just data */ - if (unlikely(!ar->rx_mpdu.has_plcp)) { - if (!ar9170_nag_limiter(ar)) - return ; - - wiphy_err(ar->hw->wiphy, - "rx stream did not start with a first_mpdu frame tag.\n"); - - return ; - } - - head = &ar->rx_mpdu.plcp; - break; - - case AR9170_RX_STATUS_MPDU_SINGLE: - /* single mpdu - has plcp (head) and phy status (tail) */ - head = (void *) buf; - - mpdu_len -= sizeof(struct ar9170_rx_head); - mpdu_len -= sizeof(struct ar9170_rx_phystatus); - - buf += sizeof(struct ar9170_rx_head); - phy = (void *)(buf + mpdu_len); - break; - - default: - BUG_ON(1); - break; - } - - if (unlikely(mpdu_len < FCS_LEN)) - return ; - - memset(&status, 0, sizeof(status)); - if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status))) - return ; - - if (phy) - ar9170_rx_phy_status(ar, phy, &status); - - skb = ar9170_rx_copy_data(buf, mpdu_len); - if (likely(skb)) { - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); - ieee80211_rx_irqsafe(ar->hw, skb); - } -} - -void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) -{ - unsigned int i, tlen, resplen, wlen = 0, clen = 0; - u8 *tbuf, *respbuf; - - tbuf = skb->data; - tlen = skb->len; - - while (tlen >= 4) { - clen = tbuf[1] << 8 | tbuf[0]; - wlen = ALIGN(clen, 4); - - /* check if this is stream has a valid tag.*/ - if (tbuf[2] != 0 || tbuf[3] != 0x4e) { - /* - * TODO: handle the highly unlikely event that the - * corrupted stream has the TAG at the right position. - */ - - /* check if the frame can be repaired. */ - if (!ar->rx_failover_missing) { - /* this is no "short read". */ - if (ar9170_nag_limiter(ar)) { - wiphy_err(ar->hw->wiphy, - "missing tag!\n"); - goto err_telluser; - } else - goto err_silent; - } - - if (ar->rx_failover_missing > tlen) { - if (ar9170_nag_limiter(ar)) { - wiphy_err(ar->hw->wiphy, - "possible multi stream corruption!\n"); - goto err_telluser; - } else - goto err_silent; - } - - memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); - ar->rx_failover_missing -= tlen; - - if (ar->rx_failover_missing <= 0) { - /* - * nested ar9170_rx call! - * termination is guranteed, even when the - * combined frame also have a element with - * a bad tag. - */ - - ar->rx_failover_missing = 0; - ar9170_rx(ar, ar->rx_failover); - - skb_reset_tail_pointer(ar->rx_failover); - skb_trim(ar->rx_failover, 0); - } - - return ; - } - - /* check if stream is clipped */ - if (wlen > tlen - 4) { - if (ar->rx_failover_missing) { - /* TODO: handle double stream corruption. */ - if (ar9170_nag_limiter(ar)) { - wiphy_err(ar->hw->wiphy, - "double rx stream corruption!\n"); - goto err_telluser; - } else - goto err_silent; - } - - /* - * save incomplete data set. - * the firmware will resend the missing bits when - * the rx - descriptor comes round again. - */ - - memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); - ar->rx_failover_missing = clen - tlen; - return ; - } - resplen = clen; - respbuf = tbuf + 4; - tbuf += wlen + 4; - tlen -= wlen + 4; - - i = 0; - - /* weird thing, but this is the same in the original driver */ - while (resplen > 2 && i < 12 && - respbuf[0] == 0xff && respbuf[1] == 0xff) { - i += 2; - resplen -= 2; - respbuf += 2; - } - - if (resplen < 4) - continue; - - /* found the 6 * 0xffff marker? */ - if (i == 12) - ar9170_handle_command_response(ar, respbuf, resplen); - else - ar9170_handle_mpdu(ar, respbuf, clen); - } - - if (tlen) { - if (net_ratelimit()) - wiphy_err(ar->hw->wiphy, - "%d bytes of unprocessed data left in rx stream!\n", - tlen); - - goto err_telluser; - } - - return ; - -err_telluser: - wiphy_err(ar->hw->wiphy, - "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n", - clen, wlen, tlen, ar->rx_failover_missing); - - if (ar->rx_failover_missing) - print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, - ar->rx_failover->data, - ar->rx_failover->len); - - print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, - skb->data, skb->len); - - wiphy_err(ar->hw->wiphy, - "If you see this message frequently, please check your hardware and cables.\n"); - -err_silent: - if (ar->rx_failover_missing) { - skb_reset_tail_pointer(ar->rx_failover); - skb_trim(ar->rx_failover, 0); - ar->rx_failover_missing = 0; - } -} - -#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ -do { \ - queue.aifs = ai_fs; \ - queue.cw_min = cwmin; \ - queue.cw_max = cwmax; \ - queue.txop = _txop; \ -} while (0) - -static int ar9170_op_start(struct ieee80211_hw *hw) -{ - struct ar9170 *ar = hw->priv; - int err, i; - - mutex_lock(&ar->mutex); - - /* reinitialize queues statistics */ - memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); - for (i = 0; i < __AR9170_NUM_TXQ; i++) - ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; - - /* reset QoS defaults */ - AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ - AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */ - AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */ - AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */ - AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ - - /* set sane AMPDU defaults */ - ar->global_ampdu_density = 6; - ar->global_ampdu_factor = 3; - - ar->bad_hw_nagger = jiffies; - - err = ar->open(ar); - if (err) - goto out; - - err = ar9170_init_mac(ar); - if (err) - goto out; - - err = ar9170_set_qos(ar); - if (err) - goto out; - - err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ); - if (err) - goto out; - - err = ar9170_init_rf(ar); - if (err) - goto out; - - /* start DMA */ - err = ar9170_write_reg(ar, 0x1c3d30, 0x100); - if (err) - goto out; - - ar->state = AR9170_STARTED; - -out: - mutex_unlock(&ar->mutex); - return err; -} - -static void ar9170_op_stop(struct ieee80211_hw *hw) -{ - struct ar9170 *ar = hw->priv; - unsigned int i; - - if (IS_STARTED(ar)) - ar->state = AR9170_IDLE; - - cancel_delayed_work_sync(&ar->tx_janitor); -#ifdef CONFIG_AR9170_LEDS - cancel_delayed_work_sync(&ar->led_work); -#endif - cancel_work_sync(&ar->beacon_work); - - mutex_lock(&ar->mutex); - - if (IS_ACCEPTING_CMD(ar)) { - ar9170_set_leds_state(ar, 0); - - /* stop DMA */ - ar9170_write_reg(ar, 0x1c3d30, 0); - ar->stop(ar); - } - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - skb_queue_purge(&ar->tx_pending[i]); - skb_queue_purge(&ar->tx_status[i]); - } - - mutex_unlock(&ar->mutex); -} - -static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - struct ar9170_tx_control *txc; - struct ieee80211_tx_info *info; - struct ieee80211_tx_rate *txrate; - struct ar9170_tx_info *arinfo; - unsigned int queue = skb_get_queue_mapping(skb); - u16 keytype = 0; - u16 len, icv = 0; - - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); - - hdr = (void *)skb->data; - info = IEEE80211_SKB_CB(skb); - len = skb->len; - - txc = (void *)skb_push(skb, sizeof(*txc)); - - if (info->control.hw_key) { - icv = info->control.hw_key->icv_len; - - switch (info->control.hw_key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - keytype = AR9170_TX_MAC_ENCR_RC4; - break; - case WLAN_CIPHER_SUITE_CCMP: - keytype = AR9170_TX_MAC_ENCR_AES; - break; - default: - WARN_ON(1); - goto err_out; - } - } - - /* Length */ - txc->length = cpu_to_le16(len + icv + 4); - - txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | - AR9170_TX_MAC_BACKOFF); - txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] << - AR9170_TX_MAC_QOS_SHIFT); - txc->mac_control |= cpu_to_le16(keytype); - txc->phy_control = cpu_to_le32(0); - - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); - - txrate = &info->control.rates[0]; - if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); - else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - - arinfo = (void *)info->rate_driver_data; - arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { - /* - * WARNING: - * Putting the QoS queue bits into an unexplored territory is - * certainly not elegant. - * - * In my defense: This idea provides a reasonable way to - * smuggle valuable information to the tx_status callback. - * Also, the idea behind this bit-abuse came straight from - * the original driver code. - */ - - txc->phy_control |= - cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); - - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); - } - - return 0; - -err_out: - skb_pull(skb, sizeof(*txc)); - return -EINVAL; -} - -static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ar9170_tx_control *txc; - struct ieee80211_tx_info *info; - struct ieee80211_rate *rate = NULL; - struct ieee80211_tx_rate *txrate; - u32 power, chains; - - txc = (void *) skb->data; - info = IEEE80211_SKB_CB(skb); - txrate = &info->control.rates[0]; - - if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) - txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); - - if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE); - - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ); - /* this works because 40 MHz is 2 and dup is 3 */ - if (txrate->flags & IEEE80211_TX_RC_DUP_DATA) - txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP); - - if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) - txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI); - - if (txrate->flags & IEEE80211_TX_RC_MCS) { - u32 r = txrate->idx; - u8 *txpower; - - /* heavy clip control */ - txc->phy_control |= cpu_to_le32((r & 0x7) << 7); - - r <<= AR9170_TX_PHY_MCS_SHIFT; - BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); - - txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); - txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); - - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { - if (info->band == IEEE80211_BAND_5GHZ) - txpower = ar->power_5G_ht40; - else - txpower = ar->power_2G_ht40; - } else { - if (info->band == IEEE80211_BAND_5GHZ) - txpower = ar->power_5G_ht20; - else - txpower = ar->power_2G_ht20; - } - - power = txpower[(txrate->idx) & 7]; - } else { - u8 *txpower; - u32 mod; - u32 phyrate; - u8 idx = txrate->idx; - - if (info->band != IEEE80211_BAND_2GHZ) { - idx += 4; - txpower = ar->power_5G_leg; - mod = AR9170_TX_PHY_MOD_OFDM; - } else { - if (idx < 4) { - txpower = ar->power_2G_cck; - mod = AR9170_TX_PHY_MOD_CCK; - } else { - mod = AR9170_TX_PHY_MOD_OFDM; - txpower = ar->power_2G_ofdm; - } - } - - rate = &__ar9170_ratetable[idx]; - - phyrate = rate->hw_value & 0xF; - power = txpower[(rate->hw_value & 0x30) >> 4]; - phyrate <<= AR9170_TX_PHY_MCS_SHIFT; - - txc->phy_control |= cpu_to_le32(mod); - txc->phy_control |= cpu_to_le32(phyrate); - } - - power <<= AR9170_TX_PHY_TX_PWR_SHIFT; - power &= AR9170_TX_PHY_TX_PWR_MASK; - txc->phy_control |= cpu_to_le32(power); - - /* set TX chains */ - if (ar->eeprom.tx_mask == 1) { - chains = AR9170_TX_PHY_TXCHAIN_1; - } else { - chains = AR9170_TX_PHY_TXCHAIN_2; - - /* >= 36M legacy OFDM - use only one chain */ - if (rate && rate->bitrate >= 360) - chains = AR9170_TX_PHY_TXCHAIN_1; - } - txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); -} - -static void ar9170_tx(struct ar9170 *ar) -{ - struct sk_buff *skb; - unsigned long flags; - struct ieee80211_tx_info *info; - struct ar9170_tx_info *arinfo; - unsigned int i, frames, frames_failed, remaining_space; - int err; - bool schedule_garbagecollector = false; - - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); - - if (unlikely(!IS_STARTED(ar))) - return ; - - remaining_space = AR9170_TX_MAX_PENDING; - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - spin_lock_irqsave(&ar->tx_stats_lock, flags); - frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, - skb_queue_len(&ar->tx_pending[i])); - - if (remaining_space < frames) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "tx quota reached queue:%d, " - "remaining slots:%d, needed:%d\n", - i, remaining_space, frames); -#endif /* AR9170_QUEUE_DEBUG */ - frames = remaining_space; - } - - ar->tx_stats[i].len += frames; - ar->tx_stats[i].count += frames; - if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, "queue %d full\n", i); - wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n"); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); - ar9170_dump_txqueue(ar, &ar->tx_status[i]); -#endif /* AR9170_QUEUE_DEBUG */ - -#ifdef AR9170_QUEUE_STOP_DEBUG - wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i); - __ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_STOP_DEBUG */ - ieee80211_stop_queue(ar->hw, i); - } - - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - - if (!frames) - continue; - - frames_failed = 0; - while (frames) { - skb = skb_dequeue(&ar->tx_pending[i]); - if (unlikely(!skb)) { - frames_failed += frames; - frames = 0; - break; - } - - info = IEEE80211_SKB_CB(skb); - arinfo = (void *) info->rate_driver_data; - - /* TODO: cancel stuck frames */ - arinfo->timeout = jiffies + - msecs_to_jiffies(AR9170_TX_TIMEOUT); - -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - - err = ar->tx(ar, skb); - if (unlikely(err)) { - frames_failed++; - dev_kfree_skb_any(skb); - } else { - remaining_space--; - schedule_garbagecollector = true; - } - - frames--; - } - -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "ar9170_tx report for queue %d\n", i); - - wiphy_debug(ar->hw->wiphy, - "unprocessed pending frames left:\n"); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); -#endif /* AR9170_QUEUE_DEBUG */ - - if (unlikely(frames_failed)) { -#ifdef AR9170_QUEUE_DEBUG - wiphy_debug(ar->hw->wiphy, - "frames failed %d =>\n", frames_failed); -#endif /* AR9170_QUEUE_DEBUG */ - - spin_lock_irqsave(&ar->tx_stats_lock, flags); - ar->tx_stats[i].len -= frames_failed; - ar->tx_stats[i].count -= frames_failed; -#ifdef AR9170_QUEUE_STOP_DEBUG - wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i); - __ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_STOP_DEBUG */ - ieee80211_wake_queue(ar->hw, i); - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - } - } - - if (!schedule_garbagecollector) - return; - - ieee80211_queue_delayed_work(ar->hw, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); -} - -void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_tx_info *info; - unsigned int queue; - - if (unlikely(!IS_STARTED(ar))) - goto err_free; - - if (unlikely(ar9170_tx_prepare(ar, skb))) - goto err_free; - - queue = skb_get_queue_mapping(skb); - info = IEEE80211_SKB_CB(skb); - ar9170_tx_prepare_phy(ar, skb); - skb_queue_tail(&ar->tx_pending[queue], skb); - - ar9170_tx(ar); - return; - -err_free: - dev_kfree_skb_any(skb); -} - -static int ar9170_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ar9170 *ar = hw->priv; - struct ath_common *common = &ar->common; - int err = 0; - - mutex_lock(&ar->mutex); - - if (ar->vif) { - err = -EBUSY; - goto unlock; - } - - ar->vif = vif; - memcpy(common->macaddr, vif->addr, ETH_ALEN); - - if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) { - ar->rx_software_decryption = true; - ar->disable_offload = true; - } - - ar->cur_filter = 0; - err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS); - if (err) - goto unlock; - - err = ar9170_set_operating_mode(ar); - -unlock: - mutex_unlock(&ar->mutex); - return err; -} - -static void ar9170_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ar9170 *ar = hw->priv; - - mutex_lock(&ar->mutex); - ar->vif = NULL; - ar9170_update_frame_filter(ar, 0); - ar9170_set_beacon_timers(ar); - dev_kfree_skb(ar->beacon); - ar->beacon = NULL; - ar->sniffer_enabled = false; - ar->rx_software_decryption = false; - ar9170_set_operating_mode(ar); - mutex_unlock(&ar->mutex); -} - -static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ar9170 *ar = hw->priv; - int err = 0; - - mutex_lock(&ar->mutex); - - if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - /* TODO */ - err = 0; - } - - if (changed & IEEE80211_CONF_CHANGE_PS) { - /* TODO */ - err = 0; - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - /* TODO */ - err = 0; - } - - if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - /* - * is it long_frame_max_tx_count or short_frame_max_tx_count? - */ - - err = ar9170_set_hwretry_limit(ar, - ar->hw->conf.long_frame_max_tx_count); - if (err) - goto out; - } - - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - - /* adjust slot time for 5 GHz */ - err = ar9170_set_slot_time(ar); - if (err) - goto out; - - err = ar9170_set_dyn_sifs_ack(ar); - if (err) - goto out; - - err = ar9170_set_channel(ar, hw->conf.channel, - AR9170_RFI_NONE, - nl80211_to_ar9170(hw->conf.channel_type)); - if (err) - goto out; - } - -out: - mutex_unlock(&ar->mutex); - return err; -} - -static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - u64 mchash; - struct netdev_hw_addr *ha; - - /* always get broadcast frames */ - mchash = 1ULL << (0xff >> 2); - - netdev_hw_addr_list_for_each(ha, mc_list) - mchash |= 1ULL << (ha->addr[5] >> 2); - - return mchash; -} - -static void ar9170_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast) -{ - struct ar9170 *ar = hw->priv; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return ; - - mutex_lock(&ar->mutex); - - /* mask supported flags */ - *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | - FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; - ar->filter_state = *new_flags; - /* - * We can support more by setting the sniffer bit and - * then checking the error flags, later. - */ - - if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) - multicast = ~0ULL; - - if (multicast != ar->cur_mc_hash) - ar9170_update_multicast(ar, multicast); - - if (changed_flags & FIF_CONTROL) { - u32 filter = AR9170_MAC_REG_FTF_PSPOLL | - AR9170_MAC_REG_FTF_RTS | - AR9170_MAC_REG_FTF_CTS | - AR9170_MAC_REG_FTF_ACK | - AR9170_MAC_REG_FTF_CFE | - AR9170_MAC_REG_FTF_CFE_ACK; - - if (*new_flags & FIF_CONTROL) - filter |= ar->cur_filter; - else - filter &= (~ar->cur_filter); - - ar9170_update_frame_filter(ar, filter); - } - - if (changed_flags & FIF_PROMISC_IN_BSS) { - ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; - ar9170_set_operating_mode(ar); - } - - mutex_unlock(&ar->mutex); -} - - -static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) -{ - struct ar9170 *ar = hw->priv; - struct ath_common *common = &ar->common; - int err = 0; - - mutex_lock(&ar->mutex); - - if (changed & BSS_CHANGED_BSSID) { - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - err = ar9170_set_operating_mode(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_BEACON_ENABLED) - ar->enable_beacon = bss_conf->enable_beacon; - - if (changed & BSS_CHANGED_BEACON) { - err = ar9170_update_beacon(ar); - if (err) - goto out; - } - - if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON | - BSS_CHANGED_BEACON_INT)) { - err = ar9170_set_beacon_timers(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_ASSOC) { -#ifndef CONFIG_AR9170_LEDS - /* enable assoc LED. */ - err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); -#endif /* CONFIG_AR9170_LEDS */ - } - - if (changed & BSS_CHANGED_HT) { - /* TODO */ - err = 0; - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - err = ar9170_set_slot_time(ar); - if (err) - goto out; - } - - if (changed & BSS_CHANGED_BASIC_RATES) { - err = ar9170_set_basic_rates(ar); - if (err) - goto out; - } - -out: - mutex_unlock(&ar->mutex); -} - -static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw) -{ - struct ar9170 *ar = hw->priv; - int err; - u64 tsf; -#define NR 3 - static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H, - AR9170_MAC_REG_TSF_L, - AR9170_MAC_REG_TSF_H }; - u32 val[NR]; - int loops = 0; - - mutex_lock(&ar->mutex); - - while (loops++ < 10) { - err = ar9170_read_mreg(ar, NR, addr, val); - if (err || val[0] == val[2]) - break; - } - - mutex_unlock(&ar->mutex); - - if (WARN_ON(err)) - return 0; - tsf = val[0]; - tsf = (tsf << 32) | val[1]; - return tsf; -#undef NR -} - -static int ar9170_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 ar9170 *ar = hw->priv; - int err = 0, i; - u8 ktype; - - if ((!ar->vif) || (ar->disable_offload)) - return -EOPNOTSUPP; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - ktype = AR9170_ENC_ALG_WEP64; - break; - case WLAN_CIPHER_SUITE_WEP104: - ktype = AR9170_ENC_ALG_WEP128; - break; - case WLAN_CIPHER_SUITE_TKIP: - ktype = AR9170_ENC_ALG_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - ktype = AR9170_ENC_ALG_AESCCMP; - break; - default: - return -EOPNOTSUPP; - } - - mutex_lock(&ar->mutex); - if (cmd == SET_KEY) { - if (unlikely(!IS_STARTED(ar))) { - err = -EOPNOTSUPP; - goto out; - } - - /* group keys need all-zeroes address */ - if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) - sta = NULL; - - if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { - for (i = 0; i < 64; i++) - if (!(ar->usedkeys & BIT(i))) - break; - if (i == 64) { - ar->rx_software_decryption = true; - ar9170_set_operating_mode(ar); - err = -ENOSPC; - goto out; - } - } else { - i = 64 + key->keyidx; - } - - key->hw_key_idx = i; - - err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0, - key->key, min_t(u8, 16, key->keylen)); - if (err) - goto out; - - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { - err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, - ktype, 1, key->key + 16, 16); - if (err) - goto out; - - /* - * hardware is not capable generating the MMIC - * for fragmented frames! - */ - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - } - - if (i < 64) - ar->usedkeys |= BIT(i); - - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - } else { - if (unlikely(!IS_STARTED(ar))) { - /* The device is gone... together with the key ;-) */ - err = 0; - goto out; - } - - err = ar9170_disable_key(ar, key->hw_key_idx); - if (err) - goto out; - - if (key->hw_key_idx < 64) { - ar->usedkeys &= ~BIT(key->hw_key_idx); - } else { - err = ar9170_upload_key(ar, key->hw_key_idx, NULL, - AR9170_ENC_ALG_NONE, 0, - NULL, 0); - if (err) - goto out; - - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { - err = ar9170_upload_key(ar, key->hw_key_idx, - NULL, - AR9170_ENC_ALG_NONE, 1, - NULL, 0); - if (err) - goto out; - } - - } - } - - ar9170_regwrite_begin(ar); - ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys); - ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32); - ar9170_regwrite_finish(); - err = ar9170_regwrite_result(); - -out: - mutex_unlock(&ar->mutex); - - return err; -} - -static int ar9170_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct ar9170 *ar = hw->priv; - u32 val; - int err; - - mutex_lock(&ar->mutex); - err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val); - ar->stats.dot11ACKFailureCount += val; - - memcpy(stats, &ar->stats, sizeof(*stats)); - mutex_unlock(&ar->mutex); - - return 0; -} - -static int ar9170_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - /* TODO: update noise value, e.g. call ar9170_set_channel */ - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = ar->noise[0]; - - return 0; -} - -static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *param) -{ - struct ar9170 *ar = hw->priv; - int ret; - - mutex_lock(&ar->mutex); - if (queue < __AR9170_NUM_TXQ) { - memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], - param, sizeof(*param)); - - ret = ar9170_set_qos(ar); - } else { - ret = -EINVAL; - } - - mutex_unlock(&ar->mutex); - return ret; -} - -static int ar9170_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn, - u8 buf_size) -{ - switch (action) { - case IEEE80211_AMPDU_RX_START: - case IEEE80211_AMPDU_RX_STOP: - /* Handled by firmware */ - break; - - default: - return -EOPNOTSUPP; - } - - return 0; -} - -static const struct ieee80211_ops ar9170_ops = { - .start = ar9170_op_start, - .stop = ar9170_op_stop, - .tx = ar9170_op_tx, - .add_interface = ar9170_op_add_interface, - .remove_interface = ar9170_op_remove_interface, - .config = ar9170_op_config, - .prepare_multicast = ar9170_op_prepare_multicast, - .configure_filter = ar9170_op_configure_filter, - .conf_tx = ar9170_conf_tx, - .bss_info_changed = ar9170_op_bss_info_changed, - .get_tsf = ar9170_op_get_tsf, - .set_key = ar9170_set_key, - .get_stats = ar9170_get_stats, - .get_survey = ar9170_get_survey, - .ampdu_action = ar9170_ampdu_action, -}; - -void *ar9170_alloc(size_t priv_size) -{ - struct ieee80211_hw *hw; - struct ar9170 *ar; - struct sk_buff *skb; - int i; - - /* - * this buffer is used for rx stream reconstruction. - * Under heavy load this device (or the transport layer?) - * tends to split the streams into separate rx descriptors. - */ - - skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); - if (!skb) - goto err_nomem; - - hw = ieee80211_alloc_hw(priv_size, &ar9170_ops); - if (!hw) - goto err_nomem; - - ar = hw->priv; - ar->hw = hw; - ar->rx_failover = skb; - - mutex_init(&ar->mutex); - spin_lock_init(&ar->cmdlock); - spin_lock_init(&ar->tx_stats_lock); - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - skb_queue_head_init(&ar->tx_status[i]); - skb_queue_head_init(&ar->tx_pending[i]); - } - ar9170_rx_reset_rx_mpdu(ar); - INIT_WORK(&ar->beacon_work, ar9170_new_beacon); - INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); - - /* all hw supports 2.4 GHz, so set channel to 1 by default */ - ar->channel = &ar9170_2ghz_chantable[0]; - - /* first part of wiphy init */ - ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_WDS) | - BIT(NL80211_IFTYPE_ADHOC); - ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; - - ar->hw->queues = __AR9170_NUM_TXQ; - ar->hw->extra_tx_headroom = 8; - - ar->hw->max_rates = 1; - ar->hw->max_rate_tries = 3; - - for (i = 0; i < ARRAY_SIZE(ar->noise); i++) - ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ - - return ar; - -err_nomem: - kfree_skb(skb); - return ERR_PTR(-ENOMEM); -} - -static int ar9170_read_eeprom(struct ar9170 *ar) -{ -#define RW 8 /* number of words to read at once */ -#define RB (sizeof(u32) * RW) - struct ath_regulatory *regulatory = &ar->common.regulatory; - u8 *eeprom = (void *)&ar->eeprom; - u8 *addr = ar->eeprom.mac_address; - __le32 offsets[RW]; - unsigned int rx_streams, tx_streams, tx_params = 0; - int i, j, err, bands = 0; - - BUILD_BUG_ON(sizeof(ar->eeprom) & 3); - - BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4); -#ifndef __CHECKER__ - /* don't want to handle trailing remains */ - BUILD_BUG_ON(sizeof(ar->eeprom) % RB); -#endif - - for (i = 0; i < sizeof(ar->eeprom)/RB; i++) { - for (j = 0; j < RW; j++) - offsets[j] = cpu_to_le32(AR9170_EEPROM_START + - RB * i + 4 * j); - - err = ar->exec_cmd(ar, AR9170_CMD_RREG, - RB, (u8 *) &offsets, - RB, eeprom + RB * i); - if (err) - return err; - } - -#undef RW -#undef RB - - if (ar->eeprom.length == cpu_to_le16(0xFFFF)) - return -ENODATA; - - if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { - ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz; - bands++; - } - if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { - ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz; - bands++; - } - - rx_streams = hweight8(ar->eeprom.rx_mask); - tx_streams = hweight8(ar->eeprom.tx_mask); - - if (rx_streams != tx_streams) - tx_params = IEEE80211_HT_MCS_TX_RX_DIFF; - - if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS) - tx_params = (tx_streams - 1) << - IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; - - ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; - ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params; - - /* - * I measured this, a bandswitch takes roughly - * 135 ms and a frequency switch about 80. - * - * FIXME: measure these values again once EEPROM settings - * are used, that will influence them! - */ - if (bands == 2) - ar->hw->channel_change_time = 135 * 1000; - else - ar->hw->channel_change_time = 80 * 1000; - - regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); - regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); - - /* second part of wiphy init */ - SET_IEEE80211_PERM_ADDR(ar->hw, addr); - - return bands ? 0 : -EINVAL; -} - -static int ar9170_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) -{ - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ar9170 *ar = hw->priv; - - return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); -} - -int ar9170_register(struct ar9170 *ar, struct device *pdev) -{ - struct ath_regulatory *regulatory = &ar->common.regulatory; - int err; - - /* try to read EEPROM, init MAC addr */ - err = ar9170_read_eeprom(ar); - if (err) - goto err_out; - - err = ath_regd_init(regulatory, ar->hw->wiphy, - ar9170_reg_notifier); - if (err) - goto err_out; - - err = ieee80211_register_hw(ar->hw); - if (err) - goto err_out; - - if (!ath_is_world_regd(regulatory)) - regulatory_hint(ar->hw->wiphy, regulatory->alpha2); - - err = ar9170_init_leds(ar); - if (err) - goto err_unreg; - -#ifdef CONFIG_AR9170_LEDS - err = ar9170_register_leds(ar); - if (err) - goto err_unreg; -#endif /* CONFIG_AR9170_LEDS */ - - dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", - wiphy_name(ar->hw->wiphy)); - - ar->registered = true; - return 0; - -err_unreg: - ieee80211_unregister_hw(ar->hw); - -err_out: - return err; -} - -void ar9170_unregister(struct ar9170 *ar) -{ - if (ar->registered) { -#ifdef CONFIG_AR9170_LEDS - ar9170_unregister_leds(ar); -#endif /* CONFIG_AR9170_LEDS */ - - ieee80211_unregister_hw(ar->hw); - } - - kfree_skb(ar->rx_failover); - mutex_destroy(&ar->mutex); -} diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c deleted file mode 100644 index 0dbfcf79ac96..000000000000 --- a/drivers/net/wireless/ath/ar9170/phy.c +++ /dev/null @@ -1,1719 +0,0 @@ -/* - * Atheros AR9170 driver - * - * PHY and RF code - * - * Copyright 2008, Johannes Berg - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 "ar9170.h" -#include "cmd.h" - -static int ar9170_init_power_cal(struct ar9170 *ar) -{ - ar9170_regwrite_begin(ar); - - ar9170_regwrite(0x1bc000 + 0x993c, 0x7f); - ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f); - ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f); - - ar9170_regwrite_finish(); - return ar9170_regwrite_result(); -} - -struct ar9170_phy_init { - u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20; -}; - -static struct ar9170_phy_init ar5416_phy_init[] = { - { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, }, - { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, }, - { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, }, - { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, }, - { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, }, - { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, }, - { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, - { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, }, - { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, - { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, - { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, }, - { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, }, - { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, }, - { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, }, - { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, }, - { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, }, - { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, }, - { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, }, - { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, }, - { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, }, - { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, }, - { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, }, - { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, }, - { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, }, - { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, }, - { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, }, - { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, }, - { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, - { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, }, - { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, }, - { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, }, - { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, }, - { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, }, - { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, }, - { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, - { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, }, - { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, }, - { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, }, - { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, }, - { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, }, - { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, }, - { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, }, - { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, }, - { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, }, - { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, }, - { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, }, - { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, }, - { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, }, - { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, }, - { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, }, - { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, }, - { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, }, - { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, }, - { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, }, - { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, }, - { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, }, - { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, }, - { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, }, - { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, }, - { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, }, - { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, - { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, }, - { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, }, - { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, }, - { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, }, - { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, }, - { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, }, - { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, }, - { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, }, - { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, }, - { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, }, - { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, }, - { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, }, - { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, }, - { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, }, - { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, }, - { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, }, - { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, }, - { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, }, - { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, }, - { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, }, - { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, }, - { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, }, - { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, }, - { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, }, - { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, }, - { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, }, - { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, }, - { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, }, - { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, }, - { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, - { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, }, - { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, }, - { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, - { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, }, - { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, }, - { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, }, - { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, }, - { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, }, - { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, }, - { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, }, - { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, - { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, }, - { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, }, - { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, }, - { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, }, - { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, }, - { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, }, - { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, }, - { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, - { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, }, - { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, }, - { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, }, - { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, }, - { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, }, - { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, }, - { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, }, - { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, }, - { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, }, - { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, - { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, }, - { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, }, - { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, }, - { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, }, - { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, }, - { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, }, - { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, }, - { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, }, - { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, }, - { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, }, - { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, - { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, - { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, - { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, }, - { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, }, - { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, }, - { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, - { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, }, - { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, }, - { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, }, - { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, }, - { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, }, - { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, }, - { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, }, - { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, }, - { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, }, - { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, }, - { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, }, - { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, }, - { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, - { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, - { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, }, - { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, }, - { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, }, - { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, }, - { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, - { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, }, - { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, - { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, }, - { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, }, - { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, }, - { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, }, - { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, }, - { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, }, - { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, }, - { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, }, - { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, }, - { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, }, - { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, }, - { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, }, - { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, - { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, - { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, - { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, }, - { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, }, - { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, }, - { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, - { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, }, - { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, - { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, - { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, - { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, - { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, }, - { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, - { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, - { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, - { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, - { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, - { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, - { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, - { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, - { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, - { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, -/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */ - { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, - { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, }, - { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, }, - { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, - { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, }, - { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, }, - { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, }, - { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, }, - { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, }, - { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, }, - { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, }, - { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, }, - { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, }, - { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, }, - { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, }, - { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, } -}; - -/* - * look up a certain register in ar5416_phy_init[] and return the init. value - * for the band and bandwidth given. Return 0 if register address not found. - */ -static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { - if (ar5416_phy_init[i].reg != reg) - continue; - - if (is_2ghz) { - if (is_40mhz) - return ar5416_phy_init[i]._2ghz_40; - else - return ar5416_phy_init[i]._2ghz_20; - } else { - if (is_40mhz) - return ar5416_phy_init[i]._5ghz_40; - else - return ar5416_phy_init[i]._5ghz_20; - } - } - return 0; -} - -/* - * initialize some phy regs from eeprom values in modal_header[] - * acc. to band and bandwith - */ -static int ar9170_init_phy_from_eeprom(struct ar9170 *ar, - bool is_2ghz, bool is_40mhz) -{ - static const u8 xpd2pd[16] = { - 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, - 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2 - }; - u32 defval, newval; - /* pointer to the modal_header acc. to band */ - struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz]; - - ar9170_regwrite_begin(ar); - - /* ant common control (index 0) */ - newval = le32_to_cpu(m->antCtrlCommon); - ar9170_regwrite(0x1c5964, newval); - - /* ant control chain 0 (index 1) */ - newval = le32_to_cpu(m->antCtrlChain[0]); - ar9170_regwrite(0x1c5960, newval); - - /* ant control chain 2 (index 2) */ - newval = le32_to_cpu(m->antCtrlChain[1]); - ar9170_regwrite(0x1c7960, newval); - - /* SwSettle (index 3) */ - if (!is_40mhz) { - defval = ar9170_get_default_phy_reg_val(0x1c5844, - is_2ghz, is_40mhz); - newval = (defval & ~0x3f80) | - ((m->switchSettling & 0x7f) << 7); - ar9170_regwrite(0x1c5844, newval); - } - - /* adcDesired, pdaDesired (index 4) */ - defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz); - newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) | - ((u8)m->adcDesiredSize); - ar9170_regwrite(0x1c5850, newval); - - /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */ - defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz); - newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) | - (m->txFrameToXpaOn << 8) | m->txFrameToXpaOn; - ar9170_regwrite(0x1c5834, newval); - - /* TxEndToRxOn (index 6) */ - defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz); - newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16); - ar9170_regwrite(0x1c5828, newval); - - /* thresh62 (index 7) */ - defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz); - newval = (defval & ~0x7f000) | (m->thresh62 << 12); - ar9170_regwrite(0x1c8864, newval); - - /* tx/rx attenuation chain 0 (index 8) */ - defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz); - newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12); - ar9170_regwrite(0x1c5848, newval); - - /* tx/rx attenuation chain 2 (index 9) */ - defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz); - newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12); - ar9170_regwrite(0x1c7848, newval); - - /* tx/rx margin chain 0 (index 10) */ - defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz); - newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18); - /* bsw margin chain 0 for 5GHz only */ - if (!is_2ghz) - newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10); - ar9170_regwrite(0x1c620c, newval); - - /* tx/rx margin chain 2 (index 11) */ - defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz); - newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18); - ar9170_regwrite(0x1c820c, newval); - - /* iqCall, iqCallq chain 0 (index 12) */ - defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz); - newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) | - ((u8)m->iqCalQCh[0] & 0x1f); - ar9170_regwrite(0x1c5920, newval); - - /* iqCall, iqCallq chain 2 (index 13) */ - defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz); - newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) | - ((u8)m->iqCalQCh[1] & 0x1f); - ar9170_regwrite(0x1c7920, newval); - - /* xpd gain mask (index 14) */ - defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz); - newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16); - ar9170_regwrite(0x1c6258, newval); - ar9170_regwrite_finish(); - - return ar9170_regwrite_result(); -} - -int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) -{ - int i, err; - u32 val; - bool is_2ghz = band == IEEE80211_BAND_2GHZ; - bool is_40mhz = conf_is_ht40(&ar->hw->conf); - - ar9170_regwrite_begin(ar); - - for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { - if (is_40mhz) { - if (is_2ghz) - val = ar5416_phy_init[i]._2ghz_40; - else - val = ar5416_phy_init[i]._5ghz_40; - } else { - if (is_2ghz) - val = ar5416_phy_init[i]._2ghz_20; - else - val = ar5416_phy_init[i]._5ghz_20; - } - - ar9170_regwrite(ar5416_phy_init[i].reg, val); - } - - ar9170_regwrite_finish(); - err = ar9170_regwrite_result(); - if (err) - return err; - - err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz); - if (err) - return err; - - err = ar9170_init_power_cal(ar); - if (err) - return err; - - /* XXX: remove magic! */ - if (is_2ghz) - err = ar9170_write_reg(ar, 0x1d4014, 0x5163); - else - err = ar9170_write_reg(ar, 0x1d4014, 0x5143); - - return err; -} - -struct ar9170_rf_init { - u32 reg, _5ghz, _2ghz; -}; - -static struct ar9170_rf_init ar9170_rf_init[] = { - /* bank 0 */ - { 0x1c58b0, 0x1e5795e5, 0x1e5795e5}, - { 0x1c58e0, 0x02008020, 0x02008020}, - /* bank 1 */ - { 0x1c58b0, 0x02108421, 0x02108421}, - { 0x1c58ec, 0x00000008, 0x00000008}, - /* bank 2 */ - { 0x1c58b0, 0x0e73ff17, 0x0e73ff17}, - { 0x1c58e0, 0x00000420, 0x00000420}, - /* bank 3 */ - { 0x1c58f0, 0x01400018, 0x01c00018}, - /* bank 4 */ - { 0x1c58b0, 0x000001a1, 0x000001a1}, - { 0x1c58e8, 0x00000001, 0x00000001}, - /* bank 5 */ - { 0x1c58b0, 0x00000013, 0x00000013}, - { 0x1c58e4, 0x00000002, 0x00000002}, - /* bank 6 */ - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00004000, 0x00004000}, - { 0x1c58b0, 0x00006c00, 0x00006c00}, - { 0x1c58b0, 0x00002c00, 0x00002c00}, - { 0x1c58b0, 0x00004800, 0x00004800}, - { 0x1c58b0, 0x00004000, 0x00004000}, - { 0x1c58b0, 0x00006000, 0x00006000}, - { 0x1c58b0, 0x00001000, 0x00001000}, - { 0x1c58b0, 0x00004000, 0x00004000}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00087c00, 0x00087c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00005400, 0x00005400}, - { 0x1c58b0, 0x00000c00, 0x00000c00}, - { 0x1c58b0, 0x00001800, 0x00001800}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00006c00, 0x00006c00}, - { 0x1c58b0, 0x00006c00, 0x00006c00}, - { 0x1c58b0, 0x00007c00, 0x00007c00}, - { 0x1c58b0, 0x00002c00, 0x00002c00}, - { 0x1c58b0, 0x00003c00, 0x00003c00}, - { 0x1c58b0, 0x00003800, 0x00003800}, - { 0x1c58b0, 0x00001c00, 0x00001c00}, - { 0x1c58b0, 0x00000800, 0x00000800}, - { 0x1c58b0, 0x00000408, 0x00000408}, - { 0x1c58b0, 0x00004c15, 0x00004c15}, - { 0x1c58b0, 0x00004188, 0x00004188}, - { 0x1c58b0, 0x0000201e, 0x0000201e}, - { 0x1c58b0, 0x00010408, 0x00010408}, - { 0x1c58b0, 0x00000801, 0x00000801}, - { 0x1c58b0, 0x00000c08, 0x00000c08}, - { 0x1c58b0, 0x0000181e, 0x0000181e}, - { 0x1c58b0, 0x00001016, 0x00001016}, - { 0x1c58b0, 0x00002800, 0x00002800}, - { 0x1c58b0, 0x00004010, 0x00004010}, - { 0x1c58b0, 0x0000081c, 0x0000081c}, - { 0x1c58b0, 0x00000115, 0x00000115}, - { 0x1c58b0, 0x00000015, 0x00000015}, - { 0x1c58b0, 0x00000066, 0x00000066}, - { 0x1c58b0, 0x0000001c, 0x0000001c}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000004, 0x00000004}, - { 0x1c58b0, 0x00000015, 0x00000015}, - { 0x1c58b0, 0x0000001f, 0x0000001f}, - { 0x1c58e0, 0x00000000, 0x00000400}, - /* bank 7 */ - { 0x1c58b0, 0x000000a0, 0x000000a0}, - { 0x1c58b0, 0x00000000, 0x00000000}, - { 0x1c58b0, 0x00000040, 0x00000040}, - { 0x1c58f0, 0x0000001c, 0x0000001c}, -}; - -static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) -{ - int err, i; - - ar9170_regwrite_begin(ar); - - for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++) - ar9170_regwrite(ar9170_rf_init[i].reg, - band5ghz ? ar9170_rf_init[i]._5ghz - : ar9170_rf_init[i]._2ghz); - - ar9170_regwrite_finish(); - err = ar9170_regwrite_result(); - if (err) - wiphy_err(ar->hw->wiphy, "rf init failed\n"); - return err; -} - -static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, - u32 freq, enum ar9170_bw bw) -{ - int err; - u32 d0, d1, td0, td1, fd0, fd1; - u8 chansel; - u8 refsel0 = 1, refsel1 = 0; - u8 lf_synth = 0; - - switch (bw) { - case AR9170_BW_40_ABOVE: - freq += 10; - break; - case AR9170_BW_40_BELOW: - freq -= 10; - break; - case AR9170_BW_20: - break; - case __AR9170_NUM_BW: - BUG(); - } - - if (band5ghz) { - if (freq % 10) { - chansel = (freq - 4800) / 5; - } else { - chansel = ((freq - 4800) / 10) * 2; - refsel0 = 0; - refsel1 = 1; - } - chansel = byte_rev_table[chansel]; - } else { - if (freq == 2484) { - chansel = 10 + (freq - 2274) / 5; - lf_synth = 1; - } else - chansel = 16 + (freq - 2272) / 5; - chansel *= 4; - chansel = byte_rev_table[chansel]; - } - - d1 = chansel; - d0 = 0x21 | - refsel0 << 3 | - refsel1 << 2 | - lf_synth << 1; - td0 = d0 & 0x1f; - td1 = d1 & 0x1f; - fd0 = td1 << 5 | td0; - - td0 = (d0 >> 5) & 0x7; - td1 = (d1 >> 5) & 0x7; - fd1 = td1 << 5 | td0; - - ar9170_regwrite_begin(ar); - - ar9170_regwrite(0x1c58b0, fd0); - ar9170_regwrite(0x1c58e8, fd1); - - ar9170_regwrite_finish(); - err = ar9170_regwrite_result(); - if (err) - return err; - - msleep(10); - - return 0; -} - -struct ar9170_phy_freq_params { - u8 coeff_exp; - u16 coeff_man; - u8 coeff_exp_shgi; - u16 coeff_man_shgi; -}; - -struct ar9170_phy_freq_entry { - u16 freq; - struct ar9170_phy_freq_params params[__AR9170_NUM_BW]; -}; - -/* NB: must be in sync with channel tables in main! */ -static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = { -/* - * freq, - * 20MHz, - * 40MHz (below), - * 40Mhz (above), - */ - { 2412, { - { 3, 21737, 3, 19563, }, - { 3, 21827, 3, 19644, }, - { 3, 21647, 3, 19482, }, - } }, - { 2417, { - { 3, 21692, 3, 19523, }, - { 3, 21782, 3, 19604, }, - { 3, 21602, 3, 19442, }, - } }, - { 2422, { - { 3, 21647, 3, 19482, }, - { 3, 21737, 3, 19563, }, - { 3, 21558, 3, 19402, }, - } }, - { 2427, { - { 3, 21602, 3, 19442, }, - { 3, 21692, 3, 19523, }, - { 3, 21514, 3, 19362, }, - } }, - { 2432, { - { 3, 21558, 3, 19402, }, - { 3, 21647, 3, 19482, }, - { 3, 21470, 3, 19323, }, - } }, - { 2437, { - { 3, 21514, 3, 19362, }, - { 3, 21602, 3, 19442, }, - { 3, 21426, 3, 19283, }, - } }, - { 2442, { - { 3, 21470, 3, 19323, }, - { 3, 21558, 3, 19402, }, - { 3, 21382, 3, 19244, }, - } }, - { 2447, { - { 3, 21426, 3, 19283, }, - { 3, 21514, 3, 19362, }, - { 3, 21339, 3, 19205, }, - } }, - { 2452, { - { 3, 21382, 3, 19244, }, - { 3, 21470, 3, 19323, }, - { 3, 21295, 3, 19166, }, - } }, - { 2457, { - { 3, 21339, 3, 19205, }, - { 3, 21426, 3, 19283, }, - { 3, 21252, 3, 19127, }, - } }, - { 2462, { - { 3, 21295, 3, 19166, }, - { 3, 21382, 3, 19244, }, - { 3, 21209, 3, 19088, }, - } }, - { 2467, { - { 3, 21252, 3, 19127, }, - { 3, 21339, 3, 19205, }, - { 3, 21166, 3, 19050, }, - } }, - { 2472, { - { 3, 21209, 3, 19088, }, - { 3, 21295, 3, 19166, }, - { 3, 21124, 3, 19011, }, - } }, - { 2484, { - { 3, 21107, 3, 18996, }, - { 3, 21192, 3, 19073, }, - { 3, 21022, 3, 18920, }, - } }, - { 4920, { - { 4, 21313, 4, 19181, }, - { 4, 21356, 4, 19220, }, - { 4, 21269, 4, 19142, }, - } }, - { 4940, { - { 4, 21226, 4, 19104, }, - { 4, 21269, 4, 19142, }, - { 4, 21183, 4, 19065, }, - } }, - { 4960, { - { 4, 21141, 4, 19027, }, - { 4, 21183, 4, 19065, }, - { 4, 21098, 4, 18988, }, - } }, - { 4980, { - { 4, 21056, 4, 18950, }, - { 4, 21098, 4, 18988, }, - { 4, 21014, 4, 18912, }, - } }, - { 5040, { - { 4, 20805, 4, 18725, }, - { 4, 20846, 4, 18762, }, - { 4, 20764, 4, 18687, }, - } }, - { 5060, { - { 4, 20723, 4, 18651, }, - { 4, 20764, 4, 18687, }, - { 4, 20682, 4, 18614, }, - } }, - { 5080, { - { 4, 20641, 4, 18577, }, - { 4, 20682, 4, 18614, }, - { 4, 20601, 4, 18541, }, - } }, - { 5180, { - { 4, 20243, 4, 18219, }, - { 4, 20282, 4, 18254, }, - { 4, 20204, 4, 18183, }, - } }, - { 5200, { - { 4, 20165, 4, 18148, }, - { 4, 20204, 4, 18183, }, - { 4, 20126, 4, 18114, }, - } }, - { 5220, { - { 4, 20088, 4, 18079, }, - { 4, 20126, 4, 18114, }, - { 4, 20049, 4, 18044, }, - } }, - { 5240, { - { 4, 20011, 4, 18010, }, - { 4, 20049, 4, 18044, }, - { 4, 19973, 4, 17976, }, - } }, - { 5260, { - { 4, 19935, 4, 17941, }, - { 4, 19973, 4, 17976, }, - { 4, 19897, 4, 17907, }, - } }, - { 5280, { - { 4, 19859, 4, 17873, }, - { 4, 19897, 4, 17907, }, - { 4, 19822, 4, 17840, }, - } }, - { 5300, { - { 4, 19784, 4, 17806, }, - { 4, 19822, 4, 17840, }, - { 4, 19747, 4, 17772, }, - } }, - { 5320, { - { 4, 19710, 4, 17739, }, - { 4, 19747, 4, 17772, }, - { 4, 19673, 4, 17706, }, - } }, - { 5500, { - { 4, 19065, 4, 17159, }, - { 4, 19100, 4, 17190, }, - { 4, 19030, 4, 17127, }, - } }, - { 5520, { - { 4, 18996, 4, 17096, }, - { 4, 19030, 4, 17127, }, - { 4, 18962, 4, 17065, }, - } }, - { 5540, { - { 4, 18927, 4, 17035, }, - { 4, 18962, 4, 17065, }, - { 4, 18893, 4, 17004, }, - } }, - { 5560, { - { 4, 18859, 4, 16973, }, - { 4, 18893, 4, 17004, }, - { 4, 18825, 4, 16943, }, - } }, - { 5580, { - { 4, 18792, 4, 16913, }, - { 4, 18825, 4, 16943, }, - { 4, 18758, 4, 16882, }, - } }, - { 5600, { - { 4, 18725, 4, 16852, }, - { 4, 18758, 4, 16882, }, - { 4, 18691, 4, 16822, }, - } }, - { 5620, { - { 4, 18658, 4, 16792, }, - { 4, 18691, 4, 16822, }, - { 4, 18625, 4, 16762, }, - } }, - { 5640, { - { 4, 18592, 4, 16733, }, - { 4, 18625, 4, 16762, }, - { 4, 18559, 4, 16703, }, - } }, - { 5660, { - { 4, 18526, 4, 16673, }, - { 4, 18559, 4, 16703, }, - { 4, 18493, 4, 16644, }, - } }, - { 5680, { - { 4, 18461, 4, 16615, }, - { 4, 18493, 4, 16644, }, - { 4, 18428, 4, 16586, }, - } }, - { 5700, { - { 4, 18396, 4, 16556, }, - { 4, 18428, 4, 16586, }, - { 4, 18364, 4, 16527, }, - } }, - { 5745, { - { 4, 18252, 4, 16427, }, - { 4, 18284, 4, 16455, }, - { 4, 18220, 4, 16398, }, - } }, - { 5765, { - { 4, 18189, 5, 32740, }, - { 4, 18220, 4, 16398, }, - { 4, 18157, 5, 32683, }, - } }, - { 5785, { - { 4, 18126, 5, 32626, }, - { 4, 18157, 5, 32683, }, - { 4, 18094, 5, 32570, }, - } }, - { 5805, { - { 4, 18063, 5, 32514, }, - { 4, 18094, 5, 32570, }, - { 4, 18032, 5, 32458, }, - } }, - { 5825, { - { 4, 18001, 5, 32402, }, - { 4, 18032, 5, 32458, }, - { 4, 17970, 5, 32347, }, - } }, - { 5170, { - { 4, 20282, 4, 18254, }, - { 4, 20321, 4, 18289, }, - { 4, 20243, 4, 18219, }, - } }, - { 5190, { - { 4, 20204, 4, 18183, }, - { 4, 20243, 4, 18219, }, - { 4, 20165, 4, 18148, }, - } }, - { 5210, { - { 4, 20126, 4, 18114, }, - { 4, 20165, 4, 18148, }, - { 4, 20088, 4, 18079, }, - } }, - { 5230, { - { 4, 20049, 4, 18044, }, - { 4, 20088, 4, 18079, }, - { 4, 20011, 4, 18010, }, - } }, -}; - -static const struct ar9170_phy_freq_params * -ar9170_get_hw_dyn_params(struct ieee80211_channel *channel, - enum ar9170_bw bw) -{ - unsigned int chanidx = 0; - u16 freq = 2412; - - if (channel) { - chanidx = channel->hw_value; - freq = channel->center_freq; - } - - BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params)); - - BUILD_BUG_ON(__AR9170_NUM_BW != 3); - - WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq); - - return &ar9170_phy_freq_params[chanidx].params[bw]; -} - - -int ar9170_init_rf(struct ar9170 *ar) -{ - const struct ar9170_phy_freq_params *freqpar; - __le32 cmd[7]; - int err; - - err = ar9170_init_rf_banks_0_7(ar, false); - if (err) - return err; - - err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20); - if (err) - return err; - - freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20); - - cmd[0] = cpu_to_le32(2412 * 1000); - cmd[1] = cpu_to_le32(0); - cmd[2] = cpu_to_le32(1); - cmd[3] = cpu_to_le32(freqpar->coeff_exp); - cmd[4] = cpu_to_le32(freqpar->coeff_man); - cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi); - cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi); - - /* RF_INIT echoes the command back to us */ - err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT, - sizeof(cmd), (u8 *)cmd, - sizeof(cmd), (u8 *)cmd); - if (err) - return err; - - msleep(1000); - - return ar9170_echo_test(ar, 0xaabbccdd); -} - -static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f) -{ - int idx = nfreqs - 2; - - while (idx >= 0) { - if (f >= freqs[idx]) - return idx; - idx--; - } - - return 0; -} - -static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) -{ - /* nothing to interpolate, it's horizontal */ - if (y2 == y1) - return y1; - - /* check if we hit one of the edges */ - if (x == x1) - return y1; - if (x == x2) - return y2; - - /* x1 == x2 is bad, hopefully == x */ - if (x2 == x1) - return y1; - - return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1)); -} - -static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2) -{ -#define SHIFT 8 - s32 y; - - y = ar9170_interpolate_s32(x << SHIFT, - x1 << SHIFT, y1 << SHIFT, - x2 << SHIFT, y2 << SHIFT); - - /* - * XXX: unwrap this expression - * Isn't it just DIV_ROUND_UP(y, 1<> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1)); -#undef SHIFT -} - -static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array) -{ - int i; - - for (i = 0; i < 3; i++) - if (x <= x_array[i + 1]) - break; - - return ar9170_interpolate_u8(x, - x_array[i], - y_array[i], - x_array[i + 1], - y_array[i + 1]); -} - -static int ar9170_set_freq_cal_data(struct ar9170 *ar, - struct ieee80211_channel *channel) -{ - u8 *cal_freq_pier; - u8 vpds[2][AR5416_PD_GAIN_ICEPTS]; - u8 pwrs[2][AR5416_PD_GAIN_ICEPTS]; - int chain, idx, i; - u32 phy_data = 0; - u8 f, tmp; - - switch (channel->band) { - case IEEE80211_BAND_2GHZ: - f = channel->center_freq - 2300; - cal_freq_pier = ar->eeprom.cal_freq_pier_2G; - i = AR5416_NUM_2G_CAL_PIERS - 1; - break; - - case IEEE80211_BAND_5GHZ: - f = (channel->center_freq - 4800) / 5; - cal_freq_pier = ar->eeprom.cal_freq_pier_5G; - i = AR5416_NUM_5G_CAL_PIERS - 1; - break; - - default: - return -EINVAL; - break; - } - - for (; i >= 0; i--) { - if (cal_freq_pier[i] != 0xff) - break; - } - if (i < 0) - return -EINVAL; - - idx = ar9170_find_freq_idx(i, cal_freq_pier, f); - - ar9170_regwrite_begin(ar); - - for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) { - for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) { - struct ar9170_calibration_data_per_freq *cal_pier_data; - int j; - - switch (channel->band) { - case IEEE80211_BAND_2GHZ: - cal_pier_data = &ar->eeprom. - cal_pier_data_2G[chain][idx]; - break; - - case IEEE80211_BAND_5GHZ: - cal_pier_data = &ar->eeprom. - cal_pier_data_5G[chain][idx]; - break; - - default: - return -EINVAL; - } - - for (j = 0; j < 2; j++) { - vpds[j][i] = ar9170_interpolate_u8(f, - cal_freq_pier[idx], - cal_pier_data->vpd_pdg[j][i], - cal_freq_pier[idx + 1], - cal_pier_data[1].vpd_pdg[j][i]); - - pwrs[j][i] = ar9170_interpolate_u8(f, - cal_freq_pier[idx], - cal_pier_data->pwr_pdg[j][i], - cal_freq_pier[idx + 1], - cal_pier_data[1].pwr_pdg[j][i]) / 2; - } - } - - for (i = 0; i < 76; i++) { - if (i < 25) { - tmp = ar9170_interpolate_val(i, &pwrs[0][0], - &vpds[0][0]); - } else { - tmp = ar9170_interpolate_val(i - 12, - &pwrs[1][0], - &vpds[1][0]); - } - - phy_data |= tmp << ((i & 3) << 3); - if ((i & 3) == 3) { - ar9170_regwrite(0x1c6280 + chain * 0x1000 + - (i & ~3), phy_data); - phy_data = 0; - } - } - - for (i = 19; i < 32; i++) - ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2), - 0x0); - } - - ar9170_regwrite_finish(); - return ar9170_regwrite_result(); -} - -static u8 ar9170_get_max_edge_power(struct ar9170 *ar, - struct ar9170_calctl_edges edges[], - u32 freq) -{ - int i; - u8 rc = AR5416_MAX_RATE_POWER; - u8 f; - if (freq < 3000) - f = freq - 2300; - else - f = (freq - 4800) / 5; - - for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { - if (edges[i].channel == 0xff) - break; - if (f == edges[i].channel) { - /* exact freq match */ - rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS; - break; - } - if (i > 0 && f < edges[i].channel) { - if (f > edges[i - 1].channel && - edges[i - 1].power_flags & - AR9170_CALCTL_EDGE_FLAGS) { - /* lower channel has the inband flag set */ - rc = edges[i - 1].power_flags & - ~AR9170_CALCTL_EDGE_FLAGS; - } - break; - } - } - - if (i == AR5416_NUM_BAND_EDGES) { - if (f > edges[i - 1].channel && - edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { - /* lower channel has the inband flag set */ - rc = edges[i - 1].power_flags & - ~AR9170_CALCTL_EDGE_FLAGS; - } - } - return rc; -} - -static u8 ar9170_get_heavy_clip(struct ar9170 *ar, - struct ar9170_calctl_edges edges[], - u32 freq, enum ar9170_bw bw) -{ - u8 f; - int i; - u8 rc = 0; - - if (freq < 3000) - f = freq - 2300; - else - f = (freq - 4800) / 5; - - if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE) - rc |= 0xf0; - - for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { - if (edges[i].channel == 0xff) - break; - if (f == edges[i].channel) { - if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) - rc |= 0x0f; - break; - } - } - - return rc; -} - -/* - * calculate the conformance test limits and the heavy clip parameter - * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) - */ -static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) -{ - u8 ctl_grp; /* CTL group */ - u8 ctl_idx; /* CTL index */ - int i, j; - struct ctl_modes { - u8 ctl_mode; - u8 max_power; - u8 *pwr_cal_data; - int pwr_cal_len; - } *modes; - - /* - * order is relevant in the mode_list_*: we fall back to the - * lower indices if any mode is missed in the EEPROM. - */ - struct ctl_modes mode_list_2ghz[] = { - { CTL_11B, 0, ar->power_2G_cck, 4 }, - { CTL_11G, 0, ar->power_2G_ofdm, 4 }, - { CTL_2GHT20, 0, ar->power_2G_ht20, 8 }, - { CTL_2GHT40, 0, ar->power_2G_ht40, 8 }, - }; - struct ctl_modes mode_list_5ghz[] = { - { CTL_11A, 0, ar->power_5G_leg, 4 }, - { CTL_5GHT20, 0, ar->power_5G_ht20, 8 }, - { CTL_5GHT40, 0, ar->power_5G_ht40, 8 }, - }; - int nr_modes; - -#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) - - ar->phy_heavy_clip = 0; - - /* - * TODO: investigate the differences between OTUS' - * hpreg.c::zfHpGetRegulatoryDomain() and - * ath/regd.c::ath_regd_get_band_ctl() - - * e.g. for FCC3_WORLD the OTUS procedure - * always returns CTL_FCC, while the one in ath/ delivers - * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. - */ - ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, - ar->hw->conf.channel->band); - - /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ - if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) - ctl_grp = CTL_FCC; - - if (ctl_grp != CTL_FCC) - /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ - return; - - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { - modes = mode_list_2ghz; - nr_modes = ARRAY_SIZE(mode_list_2ghz); - } else { - modes = mode_list_5ghz; - nr_modes = ARRAY_SIZE(mode_list_5ghz); - } - - for (i = 0; i < nr_modes; i++) { - u8 c = ctl_grp | modes[i].ctl_mode; - for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++) - if (c == ar->eeprom.ctl_index[ctl_idx]) - break; - if (ctl_idx < AR5416_NUM_CTLS) { - int f_off = 0; - - /* determine heav clip parameter from - the 11G edges array */ - if (modes[i].ctl_mode == CTL_11G) { - ar->phy_heavy_clip = - ar9170_get_heavy_clip(ar, - EDGES(ctl_idx, 1), - freq, bw); - } - - /* adjust freq for 40MHz */ - if (modes[i].ctl_mode == CTL_2GHT40 || - modes[i].ctl_mode == CTL_5GHT40) { - if (bw == AR9170_BW_40_BELOW) - f_off = -10; - else - f_off = 10; - } - - modes[i].max_power = - ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1), - freq+f_off); - - /* - * TODO: check if the regulatory max. power is - * controlled by cfg80211 for DFS - * (hpmain applies it to max_power itself for DFS freq) - */ - - } else { - /* - * Workaround in otus driver, hpmain.c, line 3906: - * if no data for 5GHT20 are found, take the - * legacy 5G value. - * We extend this here to fallback from any other *HT or - * 11G, too. - */ - int k = i; - - modes[i].max_power = AR5416_MAX_RATE_POWER; - while (k-- > 0) { - if (modes[k].max_power != - AR5416_MAX_RATE_POWER) { - modes[i].max_power = modes[k].max_power; - break; - } - } - } - - /* apply max power to pwr_cal_data (ar->power_*) */ - for (j = 0; j < modes[i].pwr_cal_len; j++) { - modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j], - modes[i].max_power); - } - } - - if (ar->phy_heavy_clip & 0xf0) { - ar->power_2G_ht40[0]--; - ar->power_2G_ht40[1]--; - ar->power_2G_ht40[2]--; - } - if (ar->phy_heavy_clip & 0xf) { - ar->power_2G_ht20[0]++; - ar->power_2G_ht20[1]++; - ar->power_2G_ht20[2]++; - } - - -#undef EDGES -} - -static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw) -{ - struct ar9170_calibration_target_power_legacy *ctpl; - struct ar9170_calibration_target_power_ht *ctph; - u8 *ctpres; - int ntargets; - int idx, i, n; - u8 ackpower, ackchains, f; - u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; - - if (freq < 3000) - f = freq - 2300; - else - f = (freq - 4800)/5; - - /* - * cycle through the various modes - * - * legacy modes first: 5G, 2G CCK, 2G OFDM - */ - for (i = 0; i < 3; i++) { - switch (i) { - case 0: /* 5 GHz legacy */ - ctpl = &ar->eeprom.cal_tgt_pwr_5G[0]; - ntargets = AR5416_NUM_5G_TARGET_PWRS; - ctpres = ar->power_5G_leg; - break; - case 1: /* 2.4 GHz CCK */ - ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0]; - ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS; - ctpres = ar->power_2G_cck; - break; - case 2: /* 2.4 GHz OFDM */ - ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0]; - ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; - ctpres = ar->power_2G_ofdm; - break; - default: - BUG(); - } - - for (n = 0; n < ntargets; n++) { - if (ctpl[n].freq == 0xff) - break; - pwr_freqs[n] = ctpl[n].freq; - } - ntargets = n; - idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f); - for (n = 0; n < 4; n++) - ctpres[n] = ar9170_interpolate_u8( - f, - ctpl[idx + 0].freq, - ctpl[idx + 0].power[n], - ctpl[idx + 1].freq, - ctpl[idx + 1].power[n]); - } - - /* - * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40 - */ - for (i = 0; i < 4; i++) { - switch (i) { - case 0: /* 5 GHz HT 20 */ - ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0]; - ntargets = AR5416_NUM_5G_TARGET_PWRS; - ctpres = ar->power_5G_ht20; - break; - case 1: /* 5 GHz HT 40 */ - ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0]; - ntargets = AR5416_NUM_5G_TARGET_PWRS; - ctpres = ar->power_5G_ht40; - break; - case 2: /* 2.4 GHz HT 20 */ - ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0]; - ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; - ctpres = ar->power_2G_ht20; - break; - case 3: /* 2.4 GHz HT 40 */ - ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0]; - ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; - ctpres = ar->power_2G_ht40; - break; - default: - BUG(); - } - - for (n = 0; n < ntargets; n++) { - if (ctph[n].freq == 0xff) - break; - pwr_freqs[n] = ctph[n].freq; - } - ntargets = n; - idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f); - for (n = 0; n < 8; n++) - ctpres[n] = ar9170_interpolate_u8( - f, - ctph[idx + 0].freq, - ctph[idx + 0].power[n], - ctph[idx + 1].freq, - ctph[idx + 1].power[n]); - } - - - /* calc. conformance test limits and apply to ar->power*[] */ - ar9170_calc_ctl(ar, freq, bw); - - /* set ACK/CTS TX power */ - ar9170_regwrite_begin(ar); - - if (ar->eeprom.tx_mask != 1) - ackchains = AR9170_TX_PHY_TXCHAIN_2; - else - ackchains = AR9170_TX_PHY_TXCHAIN_1; - - if (freq < 3000) - ackpower = ar->power_2G_ofdm[0] & 0x3f; - else - ackpower = ar->power_5G_leg[0] & 0x3f; - - ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26); - ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - ar9170_regwrite_finish(); - return ar9170_regwrite_result(); -} - -static int ar9170_calc_noise_dbm(u32 raw_noise) -{ - if (raw_noise & 0x100) - return ~((raw_noise & 0x0ff) >> 1); - else - return (raw_noise & 0xff) >> 1; -} - -int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, - enum ar9170_rf_init_mode rfi, enum ar9170_bw bw) -{ - const struct ar9170_phy_freq_params *freqpar; - u32 cmd, tmp, offs; - __le32 vals[8]; - int i, err; - bool bandswitch; - - /* clear BB heavy clip enable */ - err = ar9170_write_reg(ar, 0x1c59e0, 0x200); - if (err) - return err; - - /* may be NULL at first setup */ - if (ar->channel) - bandswitch = ar->channel->band != channel->band; - else - bandswitch = true; - - /* HW workaround */ - if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && - channel->center_freq <= 2417) - bandswitch = true; - - err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL); - if (err) - return err; - - if (rfi != AR9170_RFI_NONE || bandswitch) { - u32 val = 0x400; - - if (rfi == AR9170_RFI_COLD) - val = 0x800; - - /* warm/cold reset BB/ADDA */ - err = ar9170_write_reg(ar, 0x1d4004, val); - if (err) - return err; - - err = ar9170_write_reg(ar, 0x1d4004, 0x0); - if (err) - return err; - - err = ar9170_init_phy(ar, channel->band); - if (err) - return err; - - err = ar9170_init_rf_banks_0_7(ar, - channel->band == IEEE80211_BAND_5GHZ); - if (err) - return err; - - cmd = AR9170_CMD_RF_INIT; - } else { - cmd = AR9170_CMD_FREQUENCY; - } - - err = ar9170_init_rf_bank4_pwr(ar, - channel->band == IEEE80211_BAND_5GHZ, - channel->center_freq, bw); - if (err) - return err; - - switch (bw) { - case AR9170_BW_20: - tmp = 0x240; - offs = 0; - break; - case AR9170_BW_40_BELOW: - tmp = 0x2c4; - offs = 3; - break; - case AR9170_BW_40_ABOVE: - tmp = 0x2d4; - offs = 1; - break; - default: - BUG(); - return -ENOSYS; - } - - if (ar->eeprom.tx_mask != 1) - tmp |= 0x100; - - err = ar9170_write_reg(ar, 0x1c5804, tmp); - if (err) - return err; - - err = ar9170_set_freq_cal_data(ar, channel); - if (err) - return err; - - err = ar9170_set_power_cal(ar, channel->center_freq, bw); - if (err) - return err; - - freqpar = ar9170_get_hw_dyn_params(channel, bw); - - vals[0] = cpu_to_le32(channel->center_freq * 1000); - vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf)); - vals[2] = cpu_to_le32(offs << 2 | 1); - vals[3] = cpu_to_le32(freqpar->coeff_exp); - vals[4] = cpu_to_le32(freqpar->coeff_man); - vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi); - vals[6] = cpu_to_le32(freqpar->coeff_man_shgi); - vals[7] = cpu_to_le32(1000); - - err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals, - sizeof(vals), (u8 *)vals); - if (err) - return err; - - if (ar->phy_heavy_clip) { - err = ar9170_write_reg(ar, 0x1c59e0, - 0x200 | ar->phy_heavy_clip); - if (err) { - if (ar9170_nag_limiter(ar)) - wiphy_err(ar->hw->wiphy, - "failed to set heavy clip\n"); - } - } - - for (i = 0; i < 2; i++) { - ar->noise[i] = ar9170_calc_noise_dbm( - (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff); - - ar->noise[i + 2] = ar9170_calc_noise_dbm( - (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff); - } - - ar->channel = channel; - return 0; -} diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c deleted file mode 100644 index d3be6f9816b5..000000000000 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ /dev/null @@ -1,1008 +0,0 @@ -/* - * Atheros AR9170 driver - * - * USB - frontend - * - * Copyright 2008, Johannes Berg - * Copyright 2009, Christian Lamparter - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 -#include -#include -#include -#include "ar9170.h" -#include "cmd.h" -#include "hw.h" -#include "usb.h" - -MODULE_AUTHOR("Johannes Berg "); -MODULE_AUTHOR("Christian Lamparter "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); -MODULE_FIRMWARE("ar9170.fw"); - -enum ar9170_requirements { - AR9170_REQ_FW1_ONLY = 1, -}; - -static struct usb_device_id ar9170_usb_ids[] = { - /* Atheros 9170 */ - { USB_DEVICE(0x0cf3, 0x9170) }, - /* Atheros TG121N */ - { USB_DEVICE(0x0cf3, 0x1001) }, - /* TP-Link TL-WN821N v2 */ - { USB_DEVICE(0x0cf3, 0x1002) }, - /* 3Com Dual Band 802.11n USB Adapter */ - { USB_DEVICE(0x0cf3, 0x1010) }, - /* H3C Dual Band 802.11n USB Adapter */ - { USB_DEVICE(0x0cf3, 0x1011) }, - /* Cace Airpcap NX */ - { USB_DEVICE(0xcace, 0x0300) }, - /* D-Link DWA 160 A1 */ - { USB_DEVICE(0x07d1, 0x3c10) }, - /* D-Link DWA 160 A2 */ - { USB_DEVICE(0x07d1, 0x3a09) }, - /* Netgear WNA1000 */ - { USB_DEVICE(0x0846, 0x9040) }, - /* Netgear WNDA3100 */ - { USB_DEVICE(0x0846, 0x9010) }, - /* Netgear WN111 v2 */ - { USB_DEVICE(0x0846, 0x9001) }, - /* Zydas ZD1221 */ - { USB_DEVICE(0x0ace, 0x1221) }, - /* Proxim ORiNOCO 802.11n USB */ - { USB_DEVICE(0x1435, 0x0804) }, - /* WNC Generic 11n USB Dongle */ - { USB_DEVICE(0x1435, 0x0326) }, - /* ZyXEL NWD271N */ - { USB_DEVICE(0x0586, 0x3417) }, - /* Z-Com UB81 BG */ - { USB_DEVICE(0x0cde, 0x0023) }, - /* Z-Com UB82 ABG */ - { USB_DEVICE(0x0cde, 0x0026) }, - /* Sphairon Homelink 1202 */ - { USB_DEVICE(0x0cde, 0x0027) }, - /* Arcadyan WN7512 */ - { USB_DEVICE(0x083a, 0xf522) }, - /* Planex GWUS300 */ - { USB_DEVICE(0x2019, 0x5304) }, - /* IO-Data WNGDNUS2 */ - { USB_DEVICE(0x04bb, 0x093f) }, - /* AVM FRITZ!WLAN USB Stick N */ - { USB_DEVICE(0x057C, 0x8401) }, - /* NEC WL300NU-G */ - { USB_DEVICE(0x0409, 0x0249) }, - /* AVM FRITZ!WLAN USB Stick N 2.4 */ - { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, - /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ - { USB_DEVICE(0x1668, 0x1200) }, - - /* terminate */ - {} -}; -MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); - -static void ar9170_usb_submit_urb(struct ar9170_usb *aru) -{ - struct urb *urb; - unsigned long flags; - int err; - - if (unlikely(!IS_STARTED(&aru->common))) - return ; - - spin_lock_irqsave(&aru->tx_urb_lock, flags); - if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) { - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - return ; - } - atomic_inc(&aru->tx_submitted_urbs); - - urb = usb_get_from_anchor(&aru->tx_pending); - if (!urb) { - atomic_dec(&aru->tx_submitted_urbs); - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - - return ; - } - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - - aru->tx_pending_urbs--; - usb_anchor_urb(urb, &aru->tx_submitted); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - if (ar9170_nag_limiter(&aru->common)) - dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", - err); - - usb_unanchor_urb(urb); - atomic_dec(&aru->tx_submitted_urbs); - ar9170_tx_callback(&aru->common, urb->context); - } - - usb_free_urb(urb); -} - -static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); - - if (unlikely(!aru)) { - dev_kfree_skb_irq(skb); - return ; - } - - atomic_dec(&aru->tx_submitted_urbs); - - ar9170_tx_callback(&aru->common, skb); - - ar9170_usb_submit_urb(aru); -} - -static void ar9170_usb_tx_urb_complete(struct urb *urb) -{ -} - -static void ar9170_usb_irq_completed(struct urb *urb) -{ - struct ar9170_usb *aru = urb->context; - - switch (urb->status) { - /* everything is fine */ - case 0: - break; - - /* disconnect */ - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - goto free; - - default: - goto resubmit; - } - - ar9170_handle_command_response(&aru->common, urb->transfer_buffer, - urb->actual_length); - -resubmit: - usb_anchor_urb(urb, &aru->rx_submitted); - if (usb_submit_urb(urb, GFP_ATOMIC)) { - usb_unanchor_urb(urb); - goto free; - } - - return; - -free: - usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma); -} - -static void ar9170_usb_rx_completed(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); - int err; - - if (!aru) - goto free; - - switch (urb->status) { - /* everything is fine */ - case 0: - break; - - /* disconnect */ - case -ENOENT: - case -ECONNRESET: - case -ENODEV: - case -ESHUTDOWN: - goto free; - - default: - goto resubmit; - } - - skb_put(skb, urb->actual_length); - ar9170_rx(&aru->common, skb); - -resubmit: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); - - usb_anchor_urb(urb, &aru->rx_submitted); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - usb_unanchor_urb(urb); - goto free; - } - - return ; - -free: - dev_kfree_skb_irq(skb); -} - -static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, - struct urb *urb, gfp_t gfp) -{ - struct sk_buff *skb; - - skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp); - if (!skb) - return -ENOMEM; - - /* reserve some space for mac80211's radiotap */ - skb_reserve(skb, 32); - - usb_fill_bulk_urb(urb, aru->udev, - usb_rcvbulkpipe(aru->udev, AR9170_EP_RX), - skb->data, min(skb_tailroom(skb), - AR9170_MAX_RX_BUFFER_SIZE), - ar9170_usb_rx_completed, skb); - - return 0; -} - -static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru) -{ - struct urb *urb = NULL; - void *ibuf; - int err = -ENOMEM; - - /* initialize interrupt endpoint */ - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - goto out; - - ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma); - if (!ibuf) - goto out; - - usb_fill_int_urb(urb, aru->udev, - usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf, - 64, ar9170_usb_irq_completed, aru, 1); - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - usb_anchor_urb(urb, &aru->rx_submitted); - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - usb_unanchor_urb(urb); - usb_free_coherent(aru->udev, 64, urb->transfer_buffer, - urb->transfer_dma); - } - -out: - usb_free_urb(urb); - return err; -} - -static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru) -{ - struct urb *urb; - int i; - int err = -EINVAL; - - for (i = 0; i < AR9170_NUM_RX_URBS; i++) { - err = -ENOMEM; - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - goto err_out; - - err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL); - if (err) { - usb_free_urb(urb); - goto err_out; - } - - usb_anchor_urb(urb, &aru->rx_submitted); - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - usb_unanchor_urb(urb); - dev_kfree_skb_any((void *) urb->transfer_buffer); - usb_free_urb(urb); - goto err_out; - } - usb_free_urb(urb); - } - - /* the device now waiting for a firmware. */ - aru->common.state = AR9170_IDLE; - return 0; - -err_out: - - usb_kill_anchored_urbs(&aru->rx_submitted); - return err; -} - -static int ar9170_usb_flush(struct ar9170 *ar) -{ - struct ar9170_usb *aru = (void *) ar; - struct urb *urb; - int ret, err = 0; - - if (IS_STARTED(ar)) - aru->common.state = AR9170_IDLE; - - usb_wait_anchor_empty_timeout(&aru->tx_pending, - msecs_to_jiffies(800)); - while ((urb = usb_get_from_anchor(&aru->tx_pending))) { - ar9170_tx_callback(&aru->common, (void *) urb->context); - usb_free_urb(urb); - } - - /* lets wait a while until the tx - queues are dried out */ - ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, - msecs_to_jiffies(100)); - if (ret == 0) - err = -ETIMEDOUT; - - usb_kill_anchored_urbs(&aru->tx_submitted); - - if (IS_ACCEPTING_CMD(ar)) - aru->common.state = AR9170_STARTED; - - return err; -} - -static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) -{ - int err; - - aru->common.state = AR9170_UNKNOWN_STATE; - - err = ar9170_usb_flush(&aru->common); - if (err) - dev_err(&aru->udev->dev, "stuck tx urbs!\n"); - - usb_poison_anchored_urbs(&aru->tx_submitted); - usb_poison_anchored_urbs(&aru->rx_submitted); -} - -static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, - unsigned int plen, void *payload, - unsigned int outlen, void *out) -{ - struct ar9170_usb *aru = (void *) ar; - struct urb *urb = NULL; - unsigned long flags; - int err = -ENOMEM; - - if (unlikely(!IS_ACCEPTING_CMD(ar))) - return -EPERM; - - if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4)) - return -EINVAL; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (unlikely(!urb)) - goto err_free; - - ar->cmdbuf[0] = cpu_to_le32(plen); - ar->cmdbuf[0] |= cpu_to_le32(cmd << 8); - /* writing multiple regs fills this buffer already */ - if (plen && payload != (u8 *)(&ar->cmdbuf[1])) - memcpy(&ar->cmdbuf[1], payload, plen); - - spin_lock_irqsave(&aru->common.cmdlock, flags); - aru->readbuf = (u8 *)out; - aru->readlen = outlen; - spin_unlock_irqrestore(&aru->common.cmdlock, flags); - - usb_fill_int_urb(urb, aru->udev, - usb_sndintpipe(aru->udev, AR9170_EP_CMD), - aru->common.cmdbuf, plen + 4, - ar9170_usb_tx_urb_complete, NULL, 1); - - usb_anchor_urb(urb, &aru->tx_submitted); - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - usb_unanchor_urb(urb); - usb_free_urb(urb); - goto err_unbuf; - } - usb_free_urb(urb); - - err = wait_for_completion_timeout(&aru->cmd_wait, HZ); - if (err == 0) { - err = -ETIMEDOUT; - goto err_unbuf; - } - - if (aru->readlen != outlen) { - err = -EMSGSIZE; - goto err_unbuf; - } - - return 0; - -err_unbuf: - /* Maybe the device was removed in the second we were waiting? */ - if (IS_STARTED(ar)) { - dev_err(&aru->udev->dev, "no command feedback " - "received (%d).\n", err); - - /* provide some maybe useful debug information */ - print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE, - aru->common.cmdbuf, plen + 4); - dump_stack(); - } - - /* invalidate to avoid completing the next prematurely */ - spin_lock_irqsave(&aru->common.cmdlock, flags); - aru->readbuf = NULL; - aru->readlen = 0; - spin_unlock_irqrestore(&aru->common.cmdlock, flags); - -err_free: - - return err; -} - -static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ar9170_usb *aru = (struct ar9170_usb *) ar; - struct urb *urb; - - if (unlikely(!IS_STARTED(ar))) { - /* Seriously, what were you drink... err... thinking!? */ - return -EPERM; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (unlikely(!urb)) - return -ENOMEM; - - usb_fill_bulk_urb(urb, aru->udev, - usb_sndbulkpipe(aru->udev, AR9170_EP_TX), - skb->data, skb->len, - ar9170_usb_tx_urb_complete_frame, skb); - urb->transfer_flags |= URB_ZERO_PACKET; - - usb_anchor_urb(urb, &aru->tx_pending); - aru->tx_pending_urbs++; - - usb_free_urb(urb); - - ar9170_usb_submit_urb(aru); - return 0; -} - -static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) -{ - struct ar9170_usb *aru = (void *) ar; - unsigned long flags; - u32 in, out; - - if (unlikely(!buffer)) - return ; - - in = le32_to_cpup((__le32 *)buffer); - out = le32_to_cpu(ar->cmdbuf[0]); - - /* mask off length byte */ - out &= ~0xFF; - - if (aru->readlen >= 0) { - /* add expected length */ - out |= aru->readlen; - } else { - /* add obtained length */ - out |= in & 0xFF; - } - - /* - * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response - * length and we cannot predict the correct length in advance. - * So we only check if we provided enough space for the data. - */ - if (unlikely(out < in)) { - dev_warn(&aru->udev->dev, "received invalid command response " - "got %d bytes, instead of %d bytes " - "and the resp length is %d bytes\n", - in, out, len); - print_hex_dump_bytes("ar9170 invalid resp: ", - DUMP_PREFIX_OFFSET, buffer, len); - /* - * Do not complete, then the command times out, - * and we get a stack trace from there. - */ - return ; - } - - spin_lock_irqsave(&aru->common.cmdlock, flags); - if (aru->readbuf && len > 0) { - memcpy(aru->readbuf, buffer + 4, len - 4); - aru->readbuf = NULL; - } - complete(&aru->cmd_wait); - spin_unlock_irqrestore(&aru->common.cmdlock, flags); -} - -static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data, - size_t len, u32 addr, bool complete) -{ - int transfer, err; - u8 *buf = kmalloc(4096, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - - while (len) { - transfer = min_t(int, len, 4096); - memcpy(buf, data, transfer); - - err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0), - 0x30 /* FW DL */, 0x40 | USB_DIR_OUT, - addr >> 8, 0, buf, transfer, 1000); - - if (err < 0) { - kfree(buf); - return err; - } - - len -= transfer; - data += transfer; - addr += transfer; - } - kfree(buf); - - if (complete) { - err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0), - 0x31 /* FW DL COMPLETE */, - 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000); - } - - return 0; -} - -static int ar9170_usb_reset(struct ar9170_usb *aru) -{ - int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); - - if (lock) { - ret = usb_lock_device_for_reset(aru->udev, aru->intf); - if (ret < 0) { - dev_err(&aru->udev->dev, "unable to lock device " - "for reset (%d).\n", ret); - return ret; - } - } - - ret = usb_reset_device(aru->udev); - if (lock) - usb_unlock_device(aru->udev); - - /* let it rest - for a second - */ - msleep(1000); - - return ret; -} - -static int ar9170_usb_upload_firmware(struct ar9170_usb *aru) -{ - int err; - - if (!aru->init_values) - goto upload_fw_start; - - /* First, upload initial values to device RAM */ - err = ar9170_usb_upload(aru, aru->init_values->data, - aru->init_values->size, 0x102800, false); - if (err) { - dev_err(&aru->udev->dev, "firmware part 1 " - "upload failed (%d).\n", err); - return err; - } - -upload_fw_start: - - /* Then, upload the firmware itself and start it */ - return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, - 0x200000, true); -} - -static int ar9170_usb_init_transport(struct ar9170_usb *aru) -{ - struct ar9170 *ar = (void *) &aru->common; - int err; - - ar9170_regwrite_begin(ar); - - /* Set USB Rx stream mode MAX packet number to 2 */ - ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4); - - /* Set USB Rx stream mode timeout to 10us */ - ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80); - - ar9170_regwrite_finish(); - - err = ar9170_regwrite_result(); - if (err) - dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err); - - return err; -} - -static void ar9170_usb_stop(struct ar9170 *ar) -{ - struct ar9170_usb *aru = (void *) ar; - int ret; - - if (IS_ACCEPTING_CMD(ar)) - aru->common.state = AR9170_STOPPED; - - ret = ar9170_usb_flush(ar); - if (ret) - dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); - - usb_poison_anchored_urbs(&aru->tx_submitted); - - /* - * Note: - * So far we freed all tx urbs, but we won't dare to touch any rx urbs. - * Else we would end up with a unresponsive device... - */ -} - -static int ar9170_usb_open(struct ar9170 *ar) -{ - struct ar9170_usb *aru = (void *) ar; - int err; - - usb_unpoison_anchored_urbs(&aru->tx_submitted); - err = ar9170_usb_init_transport(aru); - if (err) { - usb_poison_anchored_urbs(&aru->tx_submitted); - return err; - } - - aru->common.state = AR9170_IDLE; - return 0; -} - -static int ar9170_usb_init_device(struct ar9170_usb *aru) -{ - int err; - - err = ar9170_usb_alloc_rx_irq_urb(aru); - if (err) - goto err_out; - - err = ar9170_usb_alloc_rx_bulk_urbs(aru); - if (err) - goto err_unrx; - - err = ar9170_usb_upload_firmware(aru); - if (err) { - err = ar9170_echo_test(&aru->common, 0x60d43110); - if (err) { - /* force user invention, by disabling the device */ - err = usb_driver_set_configuration(aru->udev, -1); - dev_err(&aru->udev->dev, "device is in a bad state. " - "please reconnect it!\n"); - goto err_unrx; - } - } - - return 0; - -err_unrx: - ar9170_usb_cancel_urbs(aru); - -err_out: - return err; -} - -static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) -{ - struct device *parent = aru->udev->dev.parent; - struct usb_device *udev; - - /* - * Store a copy of the usb_device pointer locally. - * This is because device_release_driver initiates - * ar9170_usb_disconnect, which in turn frees our - * driver context (aru). - */ - udev = aru->udev; - - complete(&aru->firmware_loading_complete); - - /* unbind anything failed */ - if (parent) - device_lock(parent); - - device_release_driver(&udev->dev); - if (parent) - device_unlock(parent); - - usb_put_dev(udev); -} - -static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) -{ - struct ar9170_usb *aru = context; - int err; - - aru->firmware = fw; - - if (!fw) { - dev_err(&aru->udev->dev, "firmware file not found.\n"); - goto err_freefw; - } - - err = ar9170_usb_init_device(aru); - if (err) - goto err_freefw; - - err = ar9170_usb_open(&aru->common); - if (err) - goto err_unrx; - - err = ar9170_register(&aru->common, &aru->udev->dev); - - ar9170_usb_stop(&aru->common); - if (err) - goto err_unrx; - - complete(&aru->firmware_loading_complete); - usb_put_dev(aru->udev); - return; - - err_unrx: - ar9170_usb_cancel_urbs(aru); - - err_freefw: - ar9170_usb_firmware_failed(aru); -} - -static void ar9170_usb_firmware_inits(const struct firmware *fw, - void *context) -{ - struct ar9170_usb *aru = context; - int err; - - if (!fw) { - dev_err(&aru->udev->dev, "file with init values not found.\n"); - ar9170_usb_firmware_failed(aru); - return; - } - - aru->init_values = fw; - - /* ok so we have the init values -- get code for two-stage */ - - err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw", - &aru->udev->dev, GFP_KERNEL, aru, - ar9170_usb_firmware_finish); - if (err) - ar9170_usb_firmware_failed(aru); -} - -static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context) -{ - struct ar9170_usb *aru = context; - int err; - - if (fw) { - ar9170_usb_firmware_finish(fw, context); - return; - } - - if (aru->req_one_stage_fw) { - dev_err(&aru->udev->dev, "ar9170.fw firmware file " - "not found and is required for this device\n"); - ar9170_usb_firmware_failed(aru); - return; - } - - dev_err(&aru->udev->dev, "ar9170.fw firmware file " - "not found, trying old firmware...\n"); - - err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw", - &aru->udev->dev, GFP_KERNEL, aru, - ar9170_usb_firmware_inits); - if (err) - ar9170_usb_firmware_failed(aru); -} - -static bool ar9170_requires_one_stage(const struct usb_device_id *id) -{ - if (!id->driver_info) - return false; - if (id->driver_info == AR9170_REQ_FW1_ONLY) - return true; - return false; -} - -static int ar9170_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct ar9170_usb *aru; - struct ar9170 *ar; - struct usb_device *udev; - int err; - - aru = ar9170_alloc(sizeof(*aru)); - if (IS_ERR(aru)) { - err = PTR_ERR(aru); - goto out; - } - - udev = interface_to_usbdev(intf); - usb_get_dev(udev); - aru->udev = udev; - aru->intf = intf; - ar = &aru->common; - - aru->req_one_stage_fw = ar9170_requires_one_stage(id); - - usb_set_intfdata(intf, aru); - SET_IEEE80211_DEV(ar->hw, &intf->dev); - - init_usb_anchor(&aru->rx_submitted); - init_usb_anchor(&aru->tx_pending); - init_usb_anchor(&aru->tx_submitted); - init_completion(&aru->cmd_wait); - init_completion(&aru->firmware_loading_complete); - spin_lock_init(&aru->tx_urb_lock); - - aru->tx_pending_urbs = 0; - atomic_set(&aru->tx_submitted_urbs, 0); - - aru->common.stop = ar9170_usb_stop; - aru->common.flush = ar9170_usb_flush; - aru->common.open = ar9170_usb_open; - aru->common.tx = ar9170_usb_tx; - aru->common.exec_cmd = ar9170_usb_exec_cmd; - aru->common.callback_cmd = ar9170_usb_callback_cmd; - -#ifdef CONFIG_PM - udev->reset_resume = 1; -#endif /* CONFIG_PM */ - err = ar9170_usb_reset(aru); - if (err) - goto err_freehw; - - usb_get_dev(aru->udev); - return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw", - &aru->udev->dev, GFP_KERNEL, aru, - ar9170_usb_firmware_step2); -err_freehw: - usb_set_intfdata(intf, NULL); - usb_put_dev(udev); - ieee80211_free_hw(ar->hw); -out: - return err; -} - -static void ar9170_usb_disconnect(struct usb_interface *intf) -{ - struct ar9170_usb *aru = usb_get_intfdata(intf); - - if (!aru) - return; - - aru->common.state = AR9170_IDLE; - - wait_for_completion(&aru->firmware_loading_complete); - - ar9170_unregister(&aru->common); - ar9170_usb_cancel_urbs(aru); - - usb_put_dev(aru->udev); - usb_set_intfdata(intf, NULL); - ieee80211_free_hw(aru->common.hw); - - release_firmware(aru->init_values); - release_firmware(aru->firmware); -} - -#ifdef CONFIG_PM -static int ar9170_suspend(struct usb_interface *intf, - pm_message_t message) -{ - struct ar9170_usb *aru = usb_get_intfdata(intf); - - if (!aru) - return -ENODEV; - - aru->common.state = AR9170_IDLE; - ar9170_usb_cancel_urbs(aru); - - return 0; -} - -static int ar9170_resume(struct usb_interface *intf) -{ - struct ar9170_usb *aru = usb_get_intfdata(intf); - int err; - - if (!aru) - return -ENODEV; - - usb_unpoison_anchored_urbs(&aru->rx_submitted); - usb_unpoison_anchored_urbs(&aru->tx_submitted); - - err = ar9170_usb_init_device(aru); - if (err) - goto err_unrx; - - err = ar9170_usb_open(&aru->common); - if (err) - goto err_unrx; - - return 0; - -err_unrx: - aru->common.state = AR9170_IDLE; - ar9170_usb_cancel_urbs(aru); - - return err; -} -#endif /* CONFIG_PM */ - -static struct usb_driver ar9170_driver = { - .name = "ar9170usb", - .probe = ar9170_usb_probe, - .disconnect = ar9170_usb_disconnect, - .id_table = ar9170_usb_ids, - .soft_unbind = 1, -#ifdef CONFIG_PM - .suspend = ar9170_suspend, - .resume = ar9170_resume, - .reset_resume = ar9170_resume, -#endif /* CONFIG_PM */ -}; - -static int __init ar9170_init(void) -{ - return usb_register(&ar9170_driver); -} - -static void __exit ar9170_exit(void) -{ - usb_deregister(&ar9170_driver); -} - -module_init(ar9170_init); -module_exit(ar9170_exit); diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h deleted file mode 100644 index 919b06046eb3..000000000000 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Atheros AR9170 USB driver - * - * Driver specific definitions - * - * Copyright 2008, Johannes Berg - * Copyright 2009, Christian Lamparter - * - * 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; see the file COPYING. If not, see - * http://www.gnu.org/licenses/. - * - * This file incorporates work covered by the following copyright and - * permission notice: - * Copyright (c) 2007-2008 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 __USB_H -#define __USB_H - -#include -#include -#include -#include -#include -#include -#include -#include "eeprom.h" -#include "hw.h" -#include "ar9170.h" - -#define AR9170_NUM_RX_URBS 16 -#define AR9170_NUM_TX_URBS 8 - -struct firmware; - -struct ar9170_usb { - struct ar9170 common; - struct usb_device *udev; - struct usb_interface *intf; - - struct usb_anchor rx_submitted; - struct usb_anchor tx_pending; - struct usb_anchor tx_submitted; - - bool req_one_stage_fw; - - spinlock_t tx_urb_lock; - atomic_t tx_submitted_urbs; - unsigned int tx_pending_urbs; - - struct completion cmd_wait; - struct completion firmware_loading_complete; - int readlen; - u8 *readbuf; - - const struct firmware *init_values; - const struct firmware *firmware; -}; - -#endif /* __USB_H */ -- GitLab From 08b8099c128d601fd675b212ef8b10397706b633 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Sun, 27 Mar 2011 01:15:53 +0100 Subject: [PATCH 0568/5560] wireless: rt2x00: rt{2500,73}usb.c fix duplicate ids based on the Ralink drivers: W = Windows_ralink_driver L = Linux_ralink_driver USB_IDs W_73 W_2500 L_73 L_2500 ============= ==== ====== ==== ====== 0x050d,0x7050 - - - YES 0x050d,0x705a - - YES - 0x1371,0x9022 - YES YES - 0x148f,0x2573 YES - YES - Signed-off-by: Xose Vazquez Perez Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 4 ---- drivers/net/wireless/rt2x00/rt73usb.c | 1 - 2 files changed, 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index d9e6cec56cb5..eac788160f55 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1909,13 +1909,10 @@ static struct usb_device_id rt2500usb_device_table[] = { /* Belkin */ { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt2500usb_ops) }, /* Cisco Systems */ { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) }, - /* CNet */ - { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt2500usb_ops) }, /* Conceptronic */ { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) }, /* D-LINK */ @@ -1938,7 +1935,6 @@ static struct usb_device_id rt2500usb_device_table[] = { /* Ralink */ { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) }, - { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) }, { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, /* Sagem */ { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) }, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 149e4f928325..6593059f9c7e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2406,7 +2406,6 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) }, /* Belkin */ - { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) }, -- GitLab From 3598e1774c94e55c71b585340e7dc4538f310e3f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 31 Mar 2011 17:36:26 +0200 Subject: [PATCH 0569/5560] iwlwifi: fix enqueue hcmd race conditions We mark command as huge by using meta->flags from other (non huge) command, but flags can be possibly overridden, when non huge command is enqueued, what can lead to: WARNING: at lib/dma-debug.c:696 dma_debug_device_change+0x1a3/0x1f0() DMA-API: device driver has pending DMA allocations while released from device [count=1] To fix introduce additional CMD_MAPPED to mark command as mapped and serialize iwl_enqueue_hcmd() with iwl_tx_cmd_complete() using hcmd_lock. Serialization will also fix possible race conditions, because q->read_ptr, q->write_ptr are modified/used in parallel. On the way fix whitespace. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-tx.c | 62 ++++++++++++++------------ 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a5d438d91821..746587546a4f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -309,6 +309,7 @@ enum { CMD_SIZE_HUGE = (1 << 0), CMD_ASYNC = (1 << 1), CMD_WANT_SKB = (1 << 2), + CMD_MAPPED = (1 << 3), }; #define DEF_CMD_PAYLOAD_SIZE 320 diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 277c9175dcf6..39a4180ee854 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -149,32 +149,31 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; int i; - bool huge = false; if (q->n_bd == 0) return; while (q->read_ptr != q->write_ptr) { - /* we have no way to tell if it is a huge cmd ATM */ i = get_cmd_index(q, q->read_ptr, 0); - if (txq->meta[i].flags & CMD_SIZE_HUGE) - huge = true; - else + if (txq->meta[i].flags & CMD_MAPPED) { pci_unmap_single(priv->pci_dev, dma_unmap_addr(&txq->meta[i], mapping), dma_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); + txq->meta[i].flags = 0; + } - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } - if (huge) { - i = q->n_window; + i = q->n_window; + if (txq->meta[i].flags & CMD_MAPPED) { pci_unmap_single(priv->pci_dev, dma_unmap_addr(&txq->meta[i], mapping), dma_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); + txq->meta[i].flags = 0; } } @@ -463,7 +462,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + spin_lock_irqsave(&priv->hcmd_lock, flags); + if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { + spin_unlock_irqrestore(&priv->hcmd_lock, flags); + IWL_ERR(priv, "No space in command queue\n"); if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { is_ct_kill = @@ -476,22 +479,17 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -ENOSPC; } - spin_lock_irqsave(&priv->hcmd_lock, flags); - - /* If this is a huge cmd, mark the huge flag also on the meta.flags - * of the _original_ cmd. This is used for DMA mapping clean up. - */ - if (cmd->flags & CMD_SIZE_HUGE) { - idx = get_cmd_index(q, q->write_ptr, 0); - txq->meta[idx].flags = CMD_SIZE_HUGE; - } - idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); out_cmd = txq->cmd[idx]; out_meta = &txq->meta[idx]; + if (WARN_ON(out_meta->flags & CMD_MAPPED)) { + spin_unlock_irqrestore(&priv->hcmd_lock, flags); + return -ENOSPC; + } + memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ - out_meta->flags = cmd->flags; + out_meta->flags = cmd->flags | CMD_MAPPED; if (cmd->flags & CMD_WANT_SKB) out_meta->source = cmd; if (cmd->flags & CMD_ASYNC) @@ -609,6 +607,10 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; + unsigned long flags; + void (*callback) (struct iwl_priv *priv, struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt); + /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced @@ -622,14 +624,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) return; } - /* If this is a huge cmd, clear the huge flag on the meta.flags - * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap - * the DMA buffer for the scan (huge) command. - */ - if (huge) { - cmd_index = get_cmd_index(&txq->q, index, 0); - txq->meta[cmd_index].flags = 0; - } + spin_lock_irqsave(&priv->hcmd_lock, flags); + cmd_index = get_cmd_index(&txq->q, index, huge); cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; @@ -639,12 +635,13 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) dma_unmap_len(meta, len), PCI_DMA_BIDIRECTIONAL); + callback = NULL; /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { meta->source->reply_page = (unsigned long)rxb_addr(rxb); rxb->page = NULL; - } else if (meta->callback) - meta->callback(priv, cmd, pkt); + } else + callback = meta->callback; iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); @@ -654,5 +651,12 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) get_cmd_string(cmd->hdr.cmd)); wake_up_interruptible(&priv->wait_command_queue); } + + /* Mark as unmapped */ meta->flags = 0; + + spin_unlock_irqrestore(&priv->hcmd_lock, flags); + + if (callback) + callback(priv, cmd, pkt); } -- GitLab From dc1a4068fce2657991c5c3b1f6849f7fc466c69f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 31 Mar 2011 17:36:27 +0200 Subject: [PATCH 0570/5560] iwlwifi: more priv->mutex serialization Check status bits with mutex taken, because when we wait for mutex unlock, status can change. Patch should also make remaining sync commands be send with priv->mutex taken. That will prevent execute these commands when we are currently reset firmware, what could possibly cause troubles. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 34 +++++++++++++++----------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 28ac0d44555e..70428e9b9f76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -483,12 +483,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) container_of(work, struct iwl_priv, bt_full_concurrency); struct iwl_rxon_context *ctx; + mutex_lock(&priv->mutex); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; + goto out; /* dont send host command if rf-kill is on */ if (!iwl_is_ready_rf(priv)) - return; + goto out; IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", priv->bt_full_concurrent ? @@ -498,15 +500,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) * LQ & RXON updated cmds must be sent before BT Config cmd * to avoid 3-wire collisions */ - mutex_lock(&priv->mutex); for_each_context(priv, ctx) { if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); iwlcore_commit_rxon(priv, ctx); } - mutex_unlock(&priv->mutex); priv->cfg->ops->hcmd->send_bt_config(priv); +out: + mutex_unlock(&priv->mutex); } /** @@ -2620,10 +2622,13 @@ static void iwl_bg_init_alive_start(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, init_alive_start.work); - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + mutex_lock(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + mutex_unlock(&priv->mutex); return; + } - mutex_lock(&priv->mutex); priv->cfg->ops->lib->init_alive_start(priv); mutex_unlock(&priv->mutex); } @@ -2633,15 +2638,16 @@ static void iwl_bg_alive_start(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, alive_start.work); + mutex_lock(&priv->mutex); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; + goto unlock; /* enable dram interrupt */ if (priv->cfg->ops->lib->isr_ops.reset) priv->cfg->ops->lib->isr_ops.reset(priv); - mutex_lock(&priv->mutex); iwl_alive_start(priv); +unlock: mutex_unlock(&priv->mutex); } @@ -3267,21 +3273,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); + mutex_lock(&priv->mutex); + if (iwl_is_rfkill(priv)) - goto out_exit; + goto out; if (test_bit(STATUS_EXIT_PENDING, &priv->status) || test_bit(STATUS_SCANNING, &priv->status)) - goto out_exit; + goto out; if (!iwl_is_associated_ctx(ctx)) - goto out_exit; + goto out; /* channel switch in progress */ if (priv->switch_rxon.switch_in_progress == true) - goto out_exit; + goto out; - mutex_lock(&priv->mutex); if (priv->cfg->ops->lib->set_channel_switch) { ch = channel->hw_value; @@ -3337,7 +3344,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, } out: mutex_unlock(&priv->mutex); -out_exit: if (!priv->switch_rxon.switch_in_progress) ieee80211_chswitch_done(ctx->vif, false); IWL_DEBUG_MAC80211(priv, "leave\n"); -- GitLab From 8447c163afeaa7e9f6f015088177b1c8511e0877 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 31 Mar 2011 17:36:28 +0200 Subject: [PATCH 0571/5560] iwlwifi: remove sync_cmd_mutex We now use priv->mutex to serialize sync command, remove old priv->sync_cmd_mutex and add assertion that priv->mutex must be locked. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 13 +++++-------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 70428e9b9f76..42fad62baf76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2371,9 +2371,6 @@ static void __iwl_down(struct iwl_priv *priv) priv->bt_full_concurrent = false; priv->bt_ci_compliance = 0; - /* Unblock any waiting calls */ - wake_up_interruptible_all(&priv->wait_command_queue); - /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ if (!exit_pending) @@ -3620,7 +3617,6 @@ static int iwl_init_drv(struct iwl_priv *priv) INIT_LIST_HEAD(&priv->free_frames); mutex_init(&priv->mutex); - mutex_init(&priv->sync_cmd_mutex); priv->ieee_channels = NULL; priv->ieee_rates = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 746587546a4f..1c9d2dd37cca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1307,7 +1307,6 @@ struct iwl_priv { spinlock_t hcmd_lock; /* protect hcmd */ spinlock_t reg_lock; /* protect hw register access */ struct mutex mutex; - struct mutex sync_cmd_mutex; /* enable serialization of sync commands */ /* basic pci-network driver stuff */ struct pci_dev *pci_dev; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 02499f684683..c71c0a45fa0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -171,14 +171,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int cmd_idx; int ret; - BUG_ON(cmd->flags & CMD_ASYNC); + lockdep_assert_held(&priv->mutex); /* A synchronous command can not have a callback set. */ - BUG_ON(cmd->callback); + BUG_ON((cmd->flags & CMD_ASYNC) || cmd->callback); IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - mutex_lock(&priv->sync_cmd_mutex); set_bit(STATUS_HCMD_ACTIVE, &priv->status); IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", @@ -189,7 +188,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) ret = cmd_idx; IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); - goto out; + return ret; } ret = wait_event_interruptible_timeout(priv->wait_command_queue, @@ -229,8 +228,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) goto cancel; } - ret = 0; - goto out; + return 0; cancel: if (cmd->flags & CMD_WANT_SKB) { @@ -248,8 +246,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) iwl_free_pages(priv, cmd->reply_page); cmd->reply_page = 0; } -out: - mutex_unlock(&priv->sync_cmd_mutex); + return ret; } -- GitLab From f4263c9857e6411ef2388868cc6c79a1602a654e Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Thu, 31 Mar 2011 09:25:41 -0700 Subject: [PATCH 0572/5560] nl80211: Add BSS parameters to station This allows user-space monitoring of BSS parameters for the associated station. This is useful for debugging and verifying that the paramaters are as expected. [Exactly the same as before but bundled into a single message] Signed-off-by: Paul Stewart Cc: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 35 ++++++++++++++++++++++++++++++++++- include/net/cfg80211.h | 34 ++++++++++++++++++++++++++++++++++ net/mac80211/cfg.c | 13 ++++++++++++- net/wireless/nl80211.c | 21 ++++++++++++++++++++- 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 30022189104d..16eea7229e99 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1221,6 +1221,36 @@ enum nl80211_rate_info { NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 }; +/** + * enum nl80211_sta_bss_param - BSS information collected by STA + * + * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM + * when getting information about the bitrate of a station. + * + * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved + * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag) + * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: whether short preamble is enabled + * (flag) + * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: whether short slot time is enabled + * (flag) + * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8) + * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16) + * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined + * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use + */ +enum nl80211_sta_bss_param { + __NL80211_STA_BSS_PARAM_INVALID, + NL80211_STA_BSS_PARAM_CTS_PROT, + NL80211_STA_BSS_PARAM_SHORT_PREAMBLE, + NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME, + NL80211_STA_BSS_PARAM_DTIM_PERIOD, + NL80211_STA_BSS_PARAM_BEACON_INTERVAL, + + /* keep last */ + __NL80211_STA_BSS_PARAM_AFTER_LAST, + NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1 +}; + /** * enum nl80211_sta_info - station information * @@ -1233,7 +1263,7 @@ enum nl80211_rate_info { * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute - * containing info as possible, see &enum nl80211_sta_info_txrate. + * containing info as possible, see &enum nl80211_rate_info * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this * station) @@ -1245,6 +1275,8 @@ enum nl80211_rate_info { * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested * attribute, like NL80211_STA_INFO_TX_BITRATE. + * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute + * containing info as possible, see &enum nl80211_sta_bss_param * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -1264,6 +1296,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_TX_FAILED, NL80211_STA_INFO_SIGNAL_AVG, NL80211_STA_INFO_RX_BITRATE, + NL80211_STA_INFO_BSS_PARAM, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2c4530451721..ba7384acf4e0 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -422,6 +422,7 @@ struct station_parameters { * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled * @STATION_INFO_SIGNAL_AVG: @signal_avg filled * @STATION_INFO_RX_BITRATE: @rxrate fields are filled + * @STATION_INFO_BSS_PARAM: @bss_param filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -439,6 +440,7 @@ enum station_info_flags { STATION_INFO_RX_DROP_MISC = 1<<12, STATION_INFO_SIGNAL_AVG = 1<<13, STATION_INFO_RX_BITRATE = 1<<14, + STATION_INFO_BSS_PARAM = 1<<15, }; /** @@ -472,6 +474,37 @@ struct rate_info { u16 legacy; }; +/** + * enum station_info_rate_flags - bitrate info flags + * + * Used by the driver to indicate the specific rate transmission + * type for 802.11n transmissions. + * + * @BSS_PARAM_FLAGS_CTS_PROT: whether CTS protection is enabled + * @BSS_PARAM_FLAGS_SHORT_PREAMBLE: whether short preamble is enabled + * @BSS_PARAM_FLAGS_SHORT_SLOT_TIME: whether short slot time is enabled + */ +enum bss_param_flags { + BSS_PARAM_FLAGS_CTS_PROT = 1<<0, + BSS_PARAM_FLAGS_SHORT_PREAMBLE = 1<<1, + BSS_PARAM_FLAGS_SHORT_SLOT_TIME = 1<<2, +}; + +/** + * struct sta_bss_parameters - BSS parameters for the attached station + * + * Information about the currently associated BSS + * + * @flags: bitflag of flags from &enum bss_param_flags + * @dtim_period: DTIM period for the BSS + * @beacon_interval: beacon interval + */ +struct sta_bss_parameters { + u8 flags; + u8 dtim_period; + u16 beacon_interval; +}; + /** * struct station_info - station information * @@ -515,6 +548,7 @@ struct station_info { u32 tx_retries; u32 tx_failed; u32 rx_dropped_misc; + struct sta_bss_parameters bss_param; int generation; }; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 334213571ad0..bf5d28da46e6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -342,7 +342,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_FAILED | STATION_INFO_TX_BITRATE | STATION_INFO_RX_BITRATE | - STATION_INFO_RX_DROP_MISC; + STATION_INFO_RX_DROP_MISC | + STATION_INFO_BSS_PARAM; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; @@ -389,6 +390,16 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->plink_state = sta->plink_state; #endif } + + sinfo->bss_param.flags = 0; + if (sdata->vif.bss_conf.use_cts_prot) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; + if (sdata->vif.bss_conf.use_short_preamble) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (sdata->vif.bss_conf.use_short_slot) + sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; + sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 40c90fb461c4..297d7ce4117b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2002,7 +2002,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, const u8 *mac_addr, struct station_info *sinfo) { void *hdr; - struct nlattr *sinfoattr; + struct nlattr *sinfoattr, *bss_param; hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION); if (!hdr) @@ -2062,6 +2062,25 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_TX_FAILED) NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, sinfo->tx_failed); + if (sinfo->filled & STATION_INFO_BSS_PARAM) { + bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); + if (!bss_param) + goto nla_put_failure; + + if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) + NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_CTS_PROT); + if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) + NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE); + if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) + NLA_PUT_FLAG(msg, + NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME); + NLA_PUT_U8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, + sinfo->bss_param.dtim_period); + NLA_PUT_U16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, + sinfo->bss_param.beacon_interval); + + nla_nest_end(msg, bss_param); + } nla_nest_end(msg, sinfoattr); return genlmsg_end(msg, hdr); -- GitLab From 2d3d0a88bd136f8e6f39bc53242712852e5d0bb2 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 1 Apr 2011 18:36:46 -0700 Subject: [PATCH 0573/5560] mwifiex: return success in set_default_key for WPA/WPA2 When testing wpa_supplicant with 'nl80211' driver to connect to an AP with WPA/WPA2 security, we notice the followings: 1) add_key is called firstly with the key from cfg80211 2) set_defaut_key is called next set_default_key() is specific to WEP keys and should not be called in case of WPA/WPA2 security. The set_default_key() won't be called if wpa_supplicant uses "-Dwext" option, but it's been called if "-Dnl80211" option is specified. We can fix this issue by adding a check to return from set_default_key() if WEP key is not configured. Signed-off-by: Amitkumar Karwar Signed-off-by: Yogesh Ashok Powar Signed-off-by: Marc Yang Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 2d9680044c12..4ac4f5a0ce61 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -228,6 +228,10 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); int ret; + /* Return if WEP key not configured */ + if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) + return 0; + ret = mwifiex_set_encode(priv, NULL, 0, key_index, 0); wiphy_dbg(wiphy, "info: set default Tx key index\n"); -- GitLab From 2be50b8df53f2f329b7ddcc8be286ef6a7469fd2 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Fri, 1 Apr 2011 18:36:47 -0700 Subject: [PATCH 0574/5560] mwifiex: remove redundant encryption_mode mapping remove MWIFIEX_ENCRYPTION_MODE_ and use WLAN_CIPHER_SUITE_ macros directly Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 76 ++++-------------------- drivers/net/wireless/mwifiex/init.c | 2 +- drivers/net/wireless/mwifiex/ioctl.h | 8 --- drivers/net/wireless/mwifiex/join.c | 2 +- drivers/net/wireless/mwifiex/scan.c | 12 ++-- drivers/net/wireless/mwifiex/sta_event.c | 2 +- 6 files changed, 19 insertions(+), 83 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4ac4f5a0ce61..ec0895f4e8d3 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -90,8 +90,8 @@ mwifiex_is_alg_wep(u32 cipher) int alg = 0; switch (cipher) { - case MWIFIEX_ENCRYPTION_MODE_WEP40: - case MWIFIEX_ENCRYPTION_MODE_WEP104: + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: alg = 1; break; default: @@ -101,55 +101,6 @@ mwifiex_is_alg_wep(u32 cipher) return alg; } -/* - * This function maps the given cipher type into driver specific type. - * - * It also sets a flag to indicate whether WPA is enabled or not. - * - * The mapping table is - - * Input cipher Driver cipher type WPA enabled? - * ------------ ------------------ ------------ - * IW_AUTH_CIPHER_NONE MWIFIEX_ENCRYPTION_MODE_NONE No - * WLAN_CIPHER_SUITE_WEP40 MWIFIEX_ENCRYPTION_MODE_WEP40 No - * WLAN_CIPHER_SUITE_WEP104 MWIFIEX_ENCRYPTION_MODE_WEP104 No - * WLAN_CIPHER_SUITE_TKIP MWIFIEX_ENCRYPTION_MODE_TKIP Yes - * WLAN_CIPHER_SUITE_CCMP MWIFIEX_ENCRYPTION_MODE_CCMP Yes - * Others -1 No - */ -static int -mwifiex_get_mwifiex_cipher(u32 cipher, int *wpa_enabled) -{ - int encrypt_mode; - - if (wpa_enabled) - *wpa_enabled = 0; - switch (cipher) { - case IW_AUTH_CIPHER_NONE: - encrypt_mode = MWIFIEX_ENCRYPTION_MODE_NONE; - break; - case WLAN_CIPHER_SUITE_WEP40: - encrypt_mode = MWIFIEX_ENCRYPTION_MODE_WEP40; - break; - case WLAN_CIPHER_SUITE_WEP104: - encrypt_mode = MWIFIEX_ENCRYPTION_MODE_WEP104; - break; - case WLAN_CIPHER_SUITE_TKIP: - encrypt_mode = MWIFIEX_ENCRYPTION_MODE_TKIP; - if (wpa_enabled) - *wpa_enabled = 1; - break; - case WLAN_CIPHER_SUITE_CCMP: - encrypt_mode = MWIFIEX_ENCRYPTION_MODE_CCMP; - if (wpa_enabled) - *wpa_enabled = 1; - break; - default: - encrypt_mode = -1; - } - - return encrypt_mode; -} - /* * This function retrieves the private structure from kernel wiphy structure. */ @@ -252,13 +203,9 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); int ret = 0; - int encrypt_mode; - - encrypt_mode = mwifiex_get_mwifiex_cipher(params->cipher, NULL); - if (encrypt_mode != -1) - ret = mwifiex_set_encode(priv, params->key, params->key_len, - key_index, 0); + ret = mwifiex_set_encode(priv, params->key, params->key_len, + key_index, 0); wiphy_dbg(wiphy, "info: crypto keys added\n"); @@ -1019,7 +966,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, struct mwifiex_802_11_ssid req_ssid; struct mwifiex_ssid_bssid ssid_bssid; int ret = 0; - int auth_type = 0, pairwise_encrypt_mode = 0, wpa_enabled = 0; + int auth_type = 0, pairwise_encrypt_mode = 0; int group_encrypt_mode = 0; int alg_is_wep = 0; @@ -1052,13 +999,13 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, /* "privacy" is set only for ad-hoc mode */ if (privacy) { /* - * Keep MWIFIEX_ENCRYPTION_MODE_WEP104 for now so that + * Keep WLAN_CIPHER_SUITE_WEP104 for now so that * the firmware can find a matching network from the * scan. The cfg80211 does not give us the encryption * mode at this stage so just setting it to WEP here. */ priv->sec_info.encryption_mode = - MWIFIEX_ENCRYPTION_MODE_WEP104; + WLAN_CIPHER_SUITE_WEP104; priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; } @@ -1074,16 +1021,13 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, auth_type = NL80211_AUTHTYPE_SHARED_KEY; if (sme->crypto.n_ciphers_pairwise) { - pairwise_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. - ciphers_pairwise[0], &wpa_enabled); - priv->sec_info.encryption_mode = pairwise_encrypt_mode; + priv->sec_info.encryption_mode = + sme->crypto.ciphers_pairwise[0]; priv->sec_info.authentication_mode = auth_type; } if (sme->crypto.cipher_group) { - group_encrypt_mode = mwifiex_get_mwifiex_cipher(sme->crypto. - cipher_group, &wpa_enabled); - priv->sec_info.encryption_mode = group_encrypt_mode; + priv->sec_info.encryption_mode = sme->crypto.cipher_group; priv->sec_info.authentication_mode = auth_type; } if (sme->ie) diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 43ea87d0f348..8189862da1f9 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -86,7 +86,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED; priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; - priv->sec_info.encryption_mode = MWIFIEX_ENCRYPTION_MODE_NONE; + priv->sec_info.encryption_mode = 0; for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++) memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key)); priv->wep_key_curr_index = 0; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d01160aa1db8..703a6d12ebf3 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -267,14 +267,6 @@ struct mwifiex_debug_info { u8 event_received; }; -enum { - MWIFIEX_ENCRYPTION_MODE_NONE = 0, - MWIFIEX_ENCRYPTION_MODE_WEP40 = 1, - MWIFIEX_ENCRYPTION_MODE_TKIP = 2, - MWIFIEX_ENCRYPTION_MODE_CCMP = 3, - MWIFIEX_ENCRYPTION_MODE_WEP104 = 4, -}; - #define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 #define MWIFIEX_MAX_KEY_LENGTH 32 #define WAPI_RXPN_LEN 16 diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 8a1eb2a9ab13..7a9e0b5962ed 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -869,7 +869,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, tmp_cap |= WLAN_CAPABILITY_IBSS; /* Set up privacy in bss_desc */ - if (priv->sec_info.encryption_mode != MWIFIEX_ENCRYPTION_MODE_NONE) { + if (priv->sec_info.encryption_mode) { /* Ad-Hoc capability privacy on */ dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status set privacy to WEP\n"); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 64ed60a80977..6bb52d0e6cfa 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -273,8 +273,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) - && priv->sec_info.encryption_mode == - MWIFIEX_ENCRYPTION_MODE_NONE && !bss_desc->privacy) { + && !priv->sec_info.encryption_mode + && !bss_desc->privacy) { return true; } return false; @@ -386,8 +386,8 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, element_id != WLAN_EID_WPA)) && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. element_id != WLAN_EID_RSN)) - && priv->sec_info.encryption_mode == - MWIFIEX_ENCRYPTION_MODE_NONE && bss_desc->privacy) { + && !priv->sec_info.encryption_mode + && bss_desc->privacy) { return true; } return false; @@ -408,8 +408,8 @@ mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, element_id != WLAN_EID_WPA)) && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. element_id != WLAN_EID_RSN)) - && priv->sec_info.encryption_mode != - MWIFIEX_ENCRYPTION_MODE_NONE && bss_desc->privacy) { + && priv->sec_info.encryption_mode + && bss_desc->privacy) { dev_dbg(priv->adapter->dev, "info: %s: dynamic " "WEP: index=%d wpa_ie=%#x wpa2_ie=%#x " "EncMode=%#x privacy=%#x\n", diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 0187185a1fc6..936d7c175e75 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -76,7 +76,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) priv->wapi_ie_len = 0; priv->sec_info.wapi_key_on = false; - priv->sec_info.encryption_mode = MWIFIEX_ENCRYPTION_MODE_NONE; + priv->sec_info.encryption_mode = 0; /* Enable auto data rate */ priv->is_data_rate_auto = true; -- GitLab From 5e65968a10bb628b87024161c9adc8dbd886b47a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 2 Apr 2011 03:39:47 +0200 Subject: [PATCH 0575/5560] ath9k: fix beacon slot processing in ad-hoc mode The recent cleanups in the beacon code fixed SWBA backoff calculation, however it did not remove a line of code that worked around the issues from the earlier version of the code. After the cleanup, the initial TSF based slot calculation now always returns 0 instead of ATH_BCBUF-1, so the previous hack that reversed the slot order needs to be removed, as ad-hoc mode does not use staggered beacons. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 74f33bc193fe..24861b247b44 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -392,14 +392,6 @@ void ath_beacon_tasklet(unsigned long data) tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); slot = (tsftu % (intval * ATH_BCBUF)) / intval; - /* - * Reverse the slot order to get slot 0 on the TBTT offset that does - * not require TSF adjustment and other slots adding - * slot/ATH_BCBUF * beacon_int to timestamp. For example, with - * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 .. - * and slot 0 is at correct offset to TBTT. - */ - slot = ATH_BCBUF - slot - 1; vif = sc->beacon.bslot[slot]; ath_dbg(common, ATH_DBG_BEACON, -- GitLab From 26cd322bacd3d65fffef6f8418c2fdad5b42e4b5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 2 Apr 2011 03:39:48 +0200 Subject: [PATCH 0576/5560] ath9k: use the hw opmode to select the beacon timer mode Since the beacon timers are global, the individual vif type should not be used to determine the beacon timer configuration mode, use the global opmode instead. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 24861b247b44..f6885278398a 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -700,7 +700,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) if (cur_conf->dtim_period == 0) cur_conf->dtim_period = 1; - switch (iftype) { + switch (sc->sc_ah->opmode) { case NL80211_IFTYPE_AP: ath_beacon_config_ap(sc, cur_conf); break; -- GitLab From fbd5d17b8e2b418b495599c554f9c4754b7f93c9 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 2 Apr 2011 11:25:54 +0300 Subject: [PATCH 0577/5560] zd1211rw: rename CR* macros to ZD_CR* With compat-wireless CR* macros in zd_usb.h conflict with CR macros in include/asm-generic/termbits.h. So rename CR* macros to ZD_CR*. Conversion was done with using sed and then 'over 80 character line' checkpatch.pl warnings and comment indents were fixed. Reported-by: Walter Goldens Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 262 ++++----- drivers/net/wireless/zd1211rw/zd_chip.h | 533 +++++++++--------- drivers/net/wireless/zd1211rw/zd_rf.h | 2 +- drivers/net/wireless/zd1211rw/zd_rf_al2230.c | 198 +++---- drivers/net/wireless/zd1211rw/zd_rf_al7230b.c | 240 ++++---- drivers/net/wireless/zd1211rw/zd_rf_rf2959.c | 78 +-- drivers/net/wireless/zd1211rw/zd_rf_uw2453.c | 86 +-- drivers/net/wireless/zd1211rw/zd_usb.c | 4 +- drivers/net/wireless/zd1211rw/zd_usb.h | 2 +- 9 files changed, 710 insertions(+), 695 deletions(-) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index a73a305d3cba..ff306d763e37 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -557,7 +557,7 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip) return r; } -/* CR157 can be optionally patched by the EEPROM for original ZD1211 */ +/* ZD_CR157 can be optionally patched by the EEPROM for original ZD1211 */ static int patch_cr157(struct zd_chip *chip) { int r; @@ -571,7 +571,7 @@ static int patch_cr157(struct zd_chip *chip) return r; dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8); - return zd_iowrite32_locked(chip, value >> 8, CR157); + return zd_iowrite32_locked(chip, value >> 8, ZD_CR157); } /* @@ -593,8 +593,8 @@ static int patch_6m_band_edge(struct zd_chip *chip, u8 channel) int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel) { struct zd_ioreq16 ioreqs[] = { - { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, - { CR47, 0x1e }, + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, + { ZD_CR47, 0x1e }, }; /* FIXME: Channel 11 is not the edge for all regulatory domains. */ @@ -608,69 +608,69 @@ int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel) static int zd1211_hw_reset_phy(struct zd_chip *chip) { static const struct zd_ioreq16 ioreqs[] = { - { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 }, - { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 }, - { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f }, - { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d }, - { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a }, - { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c }, - { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 }, - { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 }, - { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b }, - { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, - { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, - { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, - { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 }, - { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff }, - { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b }, - { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 }, - { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 }, - { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff }, - { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 }, - { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 }, - { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 }, - { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 }, - { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 }, - { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 }, - { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 }, - { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff }, - { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 }, - { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 }, - { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 }, - { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a }, - { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 }, - { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e }, - { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 }, + { ZD_CR0, 0x0a }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 }, + { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xa0 }, + { ZD_CR10, 0x81 }, { ZD_CR11, 0x00 }, { ZD_CR12, 0x7f }, + { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 }, { ZD_CR15, 0x3d }, + { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e }, { ZD_CR18, 0x0a }, + { ZD_CR19, 0x48 }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0c }, + { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 }, { ZD_CR24, 0x14 }, + { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 }, { ZD_CR27, 0x19 }, + { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 }, { ZD_CR30, 0x4b }, + { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 }, + { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 }, + { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c }, + { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 }, + { ZD_CR43, 0x10 }, { ZD_CR44, 0x12 }, { ZD_CR46, 0xff }, + { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b }, + { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 }, + { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 }, + { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff }, + { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 }, + { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 }, + { ZD_CR79, 0x68 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 }, + { ZD_CR82, 0x00 }, { ZD_CR83, 0x00 }, { ZD_CR84, 0x00 }, + { ZD_CR85, 0x02 }, { ZD_CR86, 0x00 }, { ZD_CR87, 0x00 }, + { ZD_CR88, 0xff }, { ZD_CR89, 0xfc }, { ZD_CR90, 0x00 }, + { ZD_CR91, 0x00 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x08 }, + { ZD_CR94, 0x00 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0xff }, + { ZD_CR97, 0xe7 }, { ZD_CR98, 0x00 }, { ZD_CR99, 0x00 }, + { ZD_CR100, 0x00 }, { ZD_CR101, 0xae }, { ZD_CR102, 0x02 }, + { ZD_CR103, 0x00 }, { ZD_CR104, 0x03 }, { ZD_CR105, 0x65 }, + { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, { ZD_CR108, 0x0a }, + { ZD_CR109, 0xaa }, { ZD_CR110, 0xaa }, { ZD_CR111, 0x25 }, + { ZD_CR112, 0x25 }, { ZD_CR113, 0x00 }, { ZD_CR119, 0x1e }, + { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 }, { }, - { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 }, - { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 }, - { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 }, - { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 }, - { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C }, - { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 }, - { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 }, - { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 }, - { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 }, - { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 }, - { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 }, - { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, - { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, - { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f }, - { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 }, - { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C }, - { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 }, - { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 }, - { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c }, - { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 }, - { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe }, - { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa }, - { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe }, - { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba }, - { CR170, 0xba }, { CR171, 0xba }, - /* Note: CR204 must lead the CR203 */ - { CR204, 0x7d }, + { ZD_CR5, 0x00 }, { ZD_CR6, 0x00 }, { ZD_CR7, 0x00 }, + { ZD_CR8, 0x00 }, { ZD_CR9, 0x20 }, { ZD_CR12, 0xf0 }, + { ZD_CR20, 0x0e }, { ZD_CR21, 0x0e }, { ZD_CR27, 0x10 }, + { ZD_CR44, 0x33 }, { ZD_CR47, 0x1E }, { ZD_CR83, 0x24 }, + { ZD_CR84, 0x04 }, { ZD_CR85, 0x00 }, { ZD_CR86, 0x0C }, + { ZD_CR87, 0x12 }, { ZD_CR88, 0x0C }, { ZD_CR89, 0x00 }, + { ZD_CR90, 0x10 }, { ZD_CR91, 0x08 }, { ZD_CR93, 0x00 }, + { ZD_CR94, 0x01 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0x50 }, + { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 }, { ZD_CR101, 0x13 }, + { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 }, + { ZD_CR105, 0x12 }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 }, + { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 }, + { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 }, + { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR120, 0x4f }, + { ZD_CR125, 0xaa }, { ZD_CR127, 0x03 }, { ZD_CR128, 0x14 }, + { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, { ZD_CR131, 0x0C }, + { ZD_CR136, 0xdf }, { ZD_CR137, 0x40 }, { ZD_CR138, 0xa0 }, + { ZD_CR139, 0xb0 }, { ZD_CR140, 0x99 }, { ZD_CR141, 0x82 }, + { ZD_CR142, 0x54 }, { ZD_CR143, 0x1c }, { ZD_CR144, 0x6c }, + { ZD_CR147, 0x07 }, { ZD_CR148, 0x4c }, { ZD_CR149, 0x50 }, + { ZD_CR150, 0x0e }, { ZD_CR151, 0x18 }, { ZD_CR160, 0xfe }, + { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa }, + { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe }, + { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba }, + { ZD_CR170, 0xba }, { ZD_CR171, 0xba }, + /* Note: ZD_CR204 must lead the ZD_CR203 */ + { ZD_CR204, 0x7d }, { }, - { CR203, 0x30 }, + { ZD_CR203, 0x30 }, }; int r, t; @@ -697,62 +697,62 @@ static int zd1211_hw_reset_phy(struct zd_chip *chip) static int zd1211b_hw_reset_phy(struct zd_chip *chip) { static const struct zd_ioreq16 ioreqs[] = { - { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 }, - { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 }, - { CR10, 0x81 }, - /* power control { { CR11, 1 << 6 }, */ - { CR11, 0x00 }, - { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 }, - { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e }, - { CR18, 0x0a }, { CR19, 0x48 }, - { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */ - { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 }, - { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 }, - { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 }, - { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */ - { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, - { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, - { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, - { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 }, - { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff }, - { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b }, - { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 }, - { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 }, - { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff }, - { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 }, - { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 }, - { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 }, - { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 }, - { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 }, - { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 }, - { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 }, - { CR94, 0x01 }, - { CR95, 0x20 }, /* ZD1211B */ - { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 }, - { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 }, - { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 }, - { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 }, - { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 }, - { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 }, - { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 }, - { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e }, - { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 }, - { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, - { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 }, - { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 }, - { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c }, - { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 }, - { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */ - { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */ - { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe }, - { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa }, - { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe }, - { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba }, - { CR170, 0xba }, { CR171, 0xba }, - /* Note: CR204 must lead the CR203 */ - { CR204, 0x7d }, + { ZD_CR0, 0x14 }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 }, + { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xe0 }, + { ZD_CR10, 0x81 }, + /* power control { { ZD_CR11, 1 << 6 }, */ + { ZD_CR11, 0x00 }, + { ZD_CR12, 0xf0 }, { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 }, + { ZD_CR15, 0x3d }, { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e }, + { ZD_CR18, 0x0a }, { ZD_CR19, 0x48 }, + { ZD_CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */ + { ZD_CR21, 0x0e }, { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 }, + { ZD_CR24, 0x14 }, { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 }, + { ZD_CR27, 0x10 }, { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 }, + { ZD_CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */ + { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 }, + { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 }, + { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c }, + { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 }, + { ZD_CR43, 0x10 }, { ZD_CR44, 0x33 }, { ZD_CR46, 0xff }, + { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b }, + { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 }, + { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 }, + { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff }, + { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 }, + { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 }, + { ZD_CR79, 0xf0 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 }, + { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 }, + { ZD_CR85, 0x00 }, { ZD_CR86, 0x0c }, { ZD_CR87, 0x12 }, + { ZD_CR88, 0x0c }, { ZD_CR89, 0x00 }, { ZD_CR90, 0x58 }, + { ZD_CR91, 0x04 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x00 }, + { ZD_CR94, 0x01 }, + { ZD_CR95, 0x20 }, /* ZD1211B */ + { ZD_CR96, 0x50 }, { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 }, + { ZD_CR99, 0x00 }, { ZD_CR100, 0x01 }, { ZD_CR101, 0x13 }, + { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 }, + { ZD_CR105, 0x12 }, { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, + { ZD_CR108, 0x0a }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 }, + { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 }, + { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 }, + { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x1e }, + { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 }, + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, + { ZD_CR131, 0x0c }, { ZD_CR136, 0xdf }, { ZD_CR137, 0xa0 }, + { ZD_CR138, 0xa8 }, { ZD_CR139, 0xb4 }, { ZD_CR140, 0x98 }, + { ZD_CR141, 0x82 }, { ZD_CR142, 0x53 }, { ZD_CR143, 0x1c }, + { ZD_CR144, 0x6c }, { ZD_CR147, 0x07 }, { ZD_CR148, 0x40 }, + { ZD_CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */ + { ZD_CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */ + { ZD_CR151, 0x18 }, { ZD_CR159, 0x70 }, { ZD_CR160, 0xfe }, + { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa }, + { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe }, + { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba }, + { ZD_CR170, 0xba }, { ZD_CR171, 0xba }, + /* Note: ZD_CR204 must lead the ZD_CR203 */ + { ZD_CR204, 0x7d }, {}, - { CR203, 0x30 }, + { ZD_CR203, 0x30 }, }; int r, t; @@ -1200,24 +1200,24 @@ int zd_chip_init_hw(struct zd_chip *chip) static int update_pwr_int(struct zd_chip *chip, u8 channel) { u8 value = chip->pwr_int_values[channel - 1]; - return zd_iowrite16_locked(chip, value, CR31); + return zd_iowrite16_locked(chip, value, ZD_CR31); } static int update_pwr_cal(struct zd_chip *chip, u8 channel) { u8 value = chip->pwr_cal_values[channel-1]; - return zd_iowrite16_locked(chip, value, CR68); + return zd_iowrite16_locked(chip, value, ZD_CR68); } static int update_ofdm_cal(struct zd_chip *chip, u8 channel) { struct zd_ioreq16 ioreqs[3]; - ioreqs[0].addr = CR67; + ioreqs[0].addr = ZD_CR67; ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; - ioreqs[1].addr = CR66; + ioreqs[1].addr = ZD_CR66; ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1]; - ioreqs[2].addr = CR65; + ioreqs[2].addr = ZD_CR65; ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1]; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -1236,9 +1236,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, return r; if (zd_chip_is_zd1211b(chip)) { static const struct zd_ioreq16 ioreqs[] = { - { CR69, 0x28 }, + { ZD_CR69, 0x28 }, {}, - { CR69, 0x2a }, + { ZD_CR69, 0x2a }, }; r = update_ofdm_cal(chip, channel); @@ -1269,7 +1269,7 @@ static int patch_cck_gain(struct zd_chip *chip) if (r) return r; dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); - return zd_iowrite16_locked(chip, value & 0xff, CR47); + return zd_iowrite16_locked(chip, value & 0xff, ZD_CR47); } int zd_chip_set_channel(struct zd_chip *chip, u8 channel) @@ -1505,9 +1505,9 @@ int zd_rfwritev_locked(struct zd_chip *chip, int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value) { const struct zd_ioreq16 ioreqs[] = { - { CR244, (value >> 16) & 0xff }, - { CR243, (value >> 8) & 0xff }, - { CR242, value & 0xff }, + { ZD_CR244, (value >> 16) & 0xff }, + { ZD_CR243, (value >> 8) & 0xff }, + { ZD_CR242, value & 0xff }, }; ZD_ASSERT(mutex_is_locked(&chip->mutex)); return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 14e4402a6111..4be7c3b5b265 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -61,277 +61,288 @@ enum { #define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset))) /* 8-bit hardware registers */ -#define CR0 CTL_REG(0x0000) -#define CR1 CTL_REG(0x0004) -#define CR2 CTL_REG(0x0008) -#define CR3 CTL_REG(0x000C) +#define ZD_CR0 CTL_REG(0x0000) +#define ZD_CR1 CTL_REG(0x0004) +#define ZD_CR2 CTL_REG(0x0008) +#define ZD_CR3 CTL_REG(0x000C) -#define CR5 CTL_REG(0x0010) +#define ZD_CR5 CTL_REG(0x0010) /* bit 5: if set short preamble used * bit 6: filter band - Japan channel 14 on, else off */ -#define CR6 CTL_REG(0x0014) -#define CR7 CTL_REG(0x0018) -#define CR8 CTL_REG(0x001C) +#define ZD_CR6 CTL_REG(0x0014) +#define ZD_CR7 CTL_REG(0x0018) +#define ZD_CR8 CTL_REG(0x001C) -#define CR4 CTL_REG(0x0020) +#define ZD_CR4 CTL_REG(0x0020) -#define CR9 CTL_REG(0x0024) -/* bit 2: antenna switch (together with CR10) */ -#define CR10 CTL_REG(0x0028) -/* bit 1: antenna switch (together with CR9) - * RF2959 controls with CR11 radion on and off +#define ZD_CR9 CTL_REG(0x0024) +/* bit 2: antenna switch (together with ZD_CR10) */ +#define ZD_CR10 CTL_REG(0x0028) +/* bit 1: antenna switch (together with ZD_CR9) + * RF2959 controls with ZD_CR11 radion on and off */ -#define CR11 CTL_REG(0x002C) +#define ZD_CR11 CTL_REG(0x002C) /* bit 6: TX power control for OFDM - * RF2959 controls with CR10 radio on and off + * RF2959 controls with ZD_CR10 radio on and off */ -#define CR12 CTL_REG(0x0030) -#define CR13 CTL_REG(0x0034) -#define CR14 CTL_REG(0x0038) -#define CR15 CTL_REG(0x003C) -#define CR16 CTL_REG(0x0040) -#define CR17 CTL_REG(0x0044) -#define CR18 CTL_REG(0x0048) -#define CR19 CTL_REG(0x004C) -#define CR20 CTL_REG(0x0050) -#define CR21 CTL_REG(0x0054) -#define CR22 CTL_REG(0x0058) -#define CR23 CTL_REG(0x005C) -#define CR24 CTL_REG(0x0060) /* CCA threshold */ -#define CR25 CTL_REG(0x0064) -#define CR26 CTL_REG(0x0068) -#define CR27 CTL_REG(0x006C) -#define CR28 CTL_REG(0x0070) -#define CR29 CTL_REG(0x0074) -#define CR30 CTL_REG(0x0078) -#define CR31 CTL_REG(0x007C) /* TX power control for RF in CCK mode */ -#define CR32 CTL_REG(0x0080) -#define CR33 CTL_REG(0x0084) -#define CR34 CTL_REG(0x0088) -#define CR35 CTL_REG(0x008C) -#define CR36 CTL_REG(0x0090) -#define CR37 CTL_REG(0x0094) -#define CR38 CTL_REG(0x0098) -#define CR39 CTL_REG(0x009C) -#define CR40 CTL_REG(0x00A0) -#define CR41 CTL_REG(0x00A4) -#define CR42 CTL_REG(0x00A8) -#define CR43 CTL_REG(0x00AC) -#define CR44 CTL_REG(0x00B0) -#define CR45 CTL_REG(0x00B4) -#define CR46 CTL_REG(0x00B8) -#define CR47 CTL_REG(0x00BC) /* CCK baseband gain - * (patch value might be in EEPROM) - */ -#define CR48 CTL_REG(0x00C0) -#define CR49 CTL_REG(0x00C4) -#define CR50 CTL_REG(0x00C8) -#define CR51 CTL_REG(0x00CC) /* TX power control for RF in 6-36M modes */ -#define CR52 CTL_REG(0x00D0) /* TX power control for RF in 48M mode */ -#define CR53 CTL_REG(0x00D4) /* TX power control for RF in 54M mode */ -#define CR54 CTL_REG(0x00D8) -#define CR55 CTL_REG(0x00DC) -#define CR56 CTL_REG(0x00E0) -#define CR57 CTL_REG(0x00E4) -#define CR58 CTL_REG(0x00E8) -#define CR59 CTL_REG(0x00EC) -#define CR60 CTL_REG(0x00F0) -#define CR61 CTL_REG(0x00F4) -#define CR62 CTL_REG(0x00F8) -#define CR63 CTL_REG(0x00FC) -#define CR64 CTL_REG(0x0100) -#define CR65 CTL_REG(0x0104) /* OFDM 54M calibration */ -#define CR66 CTL_REG(0x0108) /* OFDM 48M calibration */ -#define CR67 CTL_REG(0x010C) /* OFDM 36M calibration */ -#define CR68 CTL_REG(0x0110) /* CCK calibration */ -#define CR69 CTL_REG(0x0114) -#define CR70 CTL_REG(0x0118) -#define CR71 CTL_REG(0x011C) -#define CR72 CTL_REG(0x0120) -#define CR73 CTL_REG(0x0124) -#define CR74 CTL_REG(0x0128) -#define CR75 CTL_REG(0x012C) -#define CR76 CTL_REG(0x0130) -#define CR77 CTL_REG(0x0134) -#define CR78 CTL_REG(0x0138) -#define CR79 CTL_REG(0x013C) -#define CR80 CTL_REG(0x0140) -#define CR81 CTL_REG(0x0144) -#define CR82 CTL_REG(0x0148) -#define CR83 CTL_REG(0x014C) -#define CR84 CTL_REG(0x0150) -#define CR85 CTL_REG(0x0154) -#define CR86 CTL_REG(0x0158) -#define CR87 CTL_REG(0x015C) -#define CR88 CTL_REG(0x0160) -#define CR89 CTL_REG(0x0164) -#define CR90 CTL_REG(0x0168) -#define CR91 CTL_REG(0x016C) -#define CR92 CTL_REG(0x0170) -#define CR93 CTL_REG(0x0174) -#define CR94 CTL_REG(0x0178) -#define CR95 CTL_REG(0x017C) -#define CR96 CTL_REG(0x0180) -#define CR97 CTL_REG(0x0184) -#define CR98 CTL_REG(0x0188) -#define CR99 CTL_REG(0x018C) -#define CR100 CTL_REG(0x0190) -#define CR101 CTL_REG(0x0194) -#define CR102 CTL_REG(0x0198) -#define CR103 CTL_REG(0x019C) -#define CR104 CTL_REG(0x01A0) -#define CR105 CTL_REG(0x01A4) -#define CR106 CTL_REG(0x01A8) -#define CR107 CTL_REG(0x01AC) -#define CR108 CTL_REG(0x01B0) -#define CR109 CTL_REG(0x01B4) -#define CR110 CTL_REG(0x01B8) -#define CR111 CTL_REG(0x01BC) -#define CR112 CTL_REG(0x01C0) -#define CR113 CTL_REG(0x01C4) -#define CR114 CTL_REG(0x01C8) -#define CR115 CTL_REG(0x01CC) -#define CR116 CTL_REG(0x01D0) -#define CR117 CTL_REG(0x01D4) -#define CR118 CTL_REG(0x01D8) -#define CR119 CTL_REG(0x01DC) -#define CR120 CTL_REG(0x01E0) -#define CR121 CTL_REG(0x01E4) -#define CR122 CTL_REG(0x01E8) -#define CR123 CTL_REG(0x01EC) -#define CR124 CTL_REG(0x01F0) -#define CR125 CTL_REG(0x01F4) -#define CR126 CTL_REG(0x01F8) -#define CR127 CTL_REG(0x01FC) -#define CR128 CTL_REG(0x0200) -#define CR129 CTL_REG(0x0204) -#define CR130 CTL_REG(0x0208) -#define CR131 CTL_REG(0x020C) -#define CR132 CTL_REG(0x0210) -#define CR133 CTL_REG(0x0214) -#define CR134 CTL_REG(0x0218) -#define CR135 CTL_REG(0x021C) -#define CR136 CTL_REG(0x0220) -#define CR137 CTL_REG(0x0224) -#define CR138 CTL_REG(0x0228) -#define CR139 CTL_REG(0x022C) -#define CR140 CTL_REG(0x0230) -#define CR141 CTL_REG(0x0234) -#define CR142 CTL_REG(0x0238) -#define CR143 CTL_REG(0x023C) -#define CR144 CTL_REG(0x0240) -#define CR145 CTL_REG(0x0244) -#define CR146 CTL_REG(0x0248) -#define CR147 CTL_REG(0x024C) -#define CR148 CTL_REG(0x0250) -#define CR149 CTL_REG(0x0254) -#define CR150 CTL_REG(0x0258) -#define CR151 CTL_REG(0x025C) -#define CR152 CTL_REG(0x0260) -#define CR153 CTL_REG(0x0264) -#define CR154 CTL_REG(0x0268) -#define CR155 CTL_REG(0x026C) -#define CR156 CTL_REG(0x0270) -#define CR157 CTL_REG(0x0274) -#define CR158 CTL_REG(0x0278) -#define CR159 CTL_REG(0x027C) -#define CR160 CTL_REG(0x0280) -#define CR161 CTL_REG(0x0284) -#define CR162 CTL_REG(0x0288) -#define CR163 CTL_REG(0x028C) -#define CR164 CTL_REG(0x0290) -#define CR165 CTL_REG(0x0294) -#define CR166 CTL_REG(0x0298) -#define CR167 CTL_REG(0x029C) -#define CR168 CTL_REG(0x02A0) -#define CR169 CTL_REG(0x02A4) -#define CR170 CTL_REG(0x02A8) -#define CR171 CTL_REG(0x02AC) -#define CR172 CTL_REG(0x02B0) -#define CR173 CTL_REG(0x02B4) -#define CR174 CTL_REG(0x02B8) -#define CR175 CTL_REG(0x02BC) -#define CR176 CTL_REG(0x02C0) -#define CR177 CTL_REG(0x02C4) -#define CR178 CTL_REG(0x02C8) -#define CR179 CTL_REG(0x02CC) -#define CR180 CTL_REG(0x02D0) -#define CR181 CTL_REG(0x02D4) -#define CR182 CTL_REG(0x02D8) -#define CR183 CTL_REG(0x02DC) -#define CR184 CTL_REG(0x02E0) -#define CR185 CTL_REG(0x02E4) -#define CR186 CTL_REG(0x02E8) -#define CR187 CTL_REG(0x02EC) -#define CR188 CTL_REG(0x02F0) -#define CR189 CTL_REG(0x02F4) -#define CR190 CTL_REG(0x02F8) -#define CR191 CTL_REG(0x02FC) -#define CR192 CTL_REG(0x0300) -#define CR193 CTL_REG(0x0304) -#define CR194 CTL_REG(0x0308) -#define CR195 CTL_REG(0x030C) -#define CR196 CTL_REG(0x0310) -#define CR197 CTL_REG(0x0314) -#define CR198 CTL_REG(0x0318) -#define CR199 CTL_REG(0x031C) -#define CR200 CTL_REG(0x0320) -#define CR201 CTL_REG(0x0324) -#define CR202 CTL_REG(0x0328) -#define CR203 CTL_REG(0x032C) /* I2C bus template value & flash control */ -#define CR204 CTL_REG(0x0330) -#define CR205 CTL_REG(0x0334) -#define CR206 CTL_REG(0x0338) -#define CR207 CTL_REG(0x033C) -#define CR208 CTL_REG(0x0340) -#define CR209 CTL_REG(0x0344) -#define CR210 CTL_REG(0x0348) -#define CR211 CTL_REG(0x034C) -#define CR212 CTL_REG(0x0350) -#define CR213 CTL_REG(0x0354) -#define CR214 CTL_REG(0x0358) -#define CR215 CTL_REG(0x035C) -#define CR216 CTL_REG(0x0360) -#define CR217 CTL_REG(0x0364) -#define CR218 CTL_REG(0x0368) -#define CR219 CTL_REG(0x036C) -#define CR220 CTL_REG(0x0370) -#define CR221 CTL_REG(0x0374) -#define CR222 CTL_REG(0x0378) -#define CR223 CTL_REG(0x037C) -#define CR224 CTL_REG(0x0380) -#define CR225 CTL_REG(0x0384) -#define CR226 CTL_REG(0x0388) -#define CR227 CTL_REG(0x038C) -#define CR228 CTL_REG(0x0390) -#define CR229 CTL_REG(0x0394) -#define CR230 CTL_REG(0x0398) -#define CR231 CTL_REG(0x039C) -#define CR232 CTL_REG(0x03A0) -#define CR233 CTL_REG(0x03A4) -#define CR234 CTL_REG(0x03A8) -#define CR235 CTL_REG(0x03AC) -#define CR236 CTL_REG(0x03B0) - -#define CR240 CTL_REG(0x03C0) -/* bit 7: host-controlled RF register writes - * CR241-CR245: for hardware controlled writing of RF bits, not needed for - * USB +#define ZD_CR12 CTL_REG(0x0030) +#define ZD_CR13 CTL_REG(0x0034) +#define ZD_CR14 CTL_REG(0x0038) +#define ZD_CR15 CTL_REG(0x003C) +#define ZD_CR16 CTL_REG(0x0040) +#define ZD_CR17 CTL_REG(0x0044) +#define ZD_CR18 CTL_REG(0x0048) +#define ZD_CR19 CTL_REG(0x004C) +#define ZD_CR20 CTL_REG(0x0050) +#define ZD_CR21 CTL_REG(0x0054) +#define ZD_CR22 CTL_REG(0x0058) +#define ZD_CR23 CTL_REG(0x005C) +#define ZD_CR24 CTL_REG(0x0060) /* CCA threshold */ +#define ZD_CR25 CTL_REG(0x0064) +#define ZD_CR26 CTL_REG(0x0068) +#define ZD_CR27 CTL_REG(0x006C) +#define ZD_CR28 CTL_REG(0x0070) +#define ZD_CR29 CTL_REG(0x0074) +#define ZD_CR30 CTL_REG(0x0078) +#define ZD_CR31 CTL_REG(0x007C) /* TX power control for RF in + * CCK mode + */ +#define ZD_CR32 CTL_REG(0x0080) +#define ZD_CR33 CTL_REG(0x0084) +#define ZD_CR34 CTL_REG(0x0088) +#define ZD_CR35 CTL_REG(0x008C) +#define ZD_CR36 CTL_REG(0x0090) +#define ZD_CR37 CTL_REG(0x0094) +#define ZD_CR38 CTL_REG(0x0098) +#define ZD_CR39 CTL_REG(0x009C) +#define ZD_CR40 CTL_REG(0x00A0) +#define ZD_CR41 CTL_REG(0x00A4) +#define ZD_CR42 CTL_REG(0x00A8) +#define ZD_CR43 CTL_REG(0x00AC) +#define ZD_CR44 CTL_REG(0x00B0) +#define ZD_CR45 CTL_REG(0x00B4) +#define ZD_CR46 CTL_REG(0x00B8) +#define ZD_CR47 CTL_REG(0x00BC) /* CCK baseband gain + * (patch value might be in EEPROM) + */ +#define ZD_CR48 CTL_REG(0x00C0) +#define ZD_CR49 CTL_REG(0x00C4) +#define ZD_CR50 CTL_REG(0x00C8) +#define ZD_CR51 CTL_REG(0x00CC) /* TX power control for RF in + * 6-36M modes + */ +#define ZD_CR52 CTL_REG(0x00D0) /* TX power control for RF in + * 48M mode + */ +#define ZD_CR53 CTL_REG(0x00D4) /* TX power control for RF in + * 54M mode + */ +#define ZD_CR54 CTL_REG(0x00D8) +#define ZD_CR55 CTL_REG(0x00DC) +#define ZD_CR56 CTL_REG(0x00E0) +#define ZD_CR57 CTL_REG(0x00E4) +#define ZD_CR58 CTL_REG(0x00E8) +#define ZD_CR59 CTL_REG(0x00EC) +#define ZD_CR60 CTL_REG(0x00F0) +#define ZD_CR61 CTL_REG(0x00F4) +#define ZD_CR62 CTL_REG(0x00F8) +#define ZD_CR63 CTL_REG(0x00FC) +#define ZD_CR64 CTL_REG(0x0100) +#define ZD_CR65 CTL_REG(0x0104) /* OFDM 54M calibration */ +#define ZD_CR66 CTL_REG(0x0108) /* OFDM 48M calibration */ +#define ZD_CR67 CTL_REG(0x010C) /* OFDM 36M calibration */ +#define ZD_CR68 CTL_REG(0x0110) /* CCK calibration */ +#define ZD_CR69 CTL_REG(0x0114) +#define ZD_CR70 CTL_REG(0x0118) +#define ZD_CR71 CTL_REG(0x011C) +#define ZD_CR72 CTL_REG(0x0120) +#define ZD_CR73 CTL_REG(0x0124) +#define ZD_CR74 CTL_REG(0x0128) +#define ZD_CR75 CTL_REG(0x012C) +#define ZD_CR76 CTL_REG(0x0130) +#define ZD_CR77 CTL_REG(0x0134) +#define ZD_CR78 CTL_REG(0x0138) +#define ZD_CR79 CTL_REG(0x013C) +#define ZD_CR80 CTL_REG(0x0140) +#define ZD_CR81 CTL_REG(0x0144) +#define ZD_CR82 CTL_REG(0x0148) +#define ZD_CR83 CTL_REG(0x014C) +#define ZD_CR84 CTL_REG(0x0150) +#define ZD_CR85 CTL_REG(0x0154) +#define ZD_CR86 CTL_REG(0x0158) +#define ZD_CR87 CTL_REG(0x015C) +#define ZD_CR88 CTL_REG(0x0160) +#define ZD_CR89 CTL_REG(0x0164) +#define ZD_CR90 CTL_REG(0x0168) +#define ZD_CR91 CTL_REG(0x016C) +#define ZD_CR92 CTL_REG(0x0170) +#define ZD_CR93 CTL_REG(0x0174) +#define ZD_CR94 CTL_REG(0x0178) +#define ZD_CR95 CTL_REG(0x017C) +#define ZD_CR96 CTL_REG(0x0180) +#define ZD_CR97 CTL_REG(0x0184) +#define ZD_CR98 CTL_REG(0x0188) +#define ZD_CR99 CTL_REG(0x018C) +#define ZD_CR100 CTL_REG(0x0190) +#define ZD_CR101 CTL_REG(0x0194) +#define ZD_CR102 CTL_REG(0x0198) +#define ZD_CR103 CTL_REG(0x019C) +#define ZD_CR104 CTL_REG(0x01A0) +#define ZD_CR105 CTL_REG(0x01A4) +#define ZD_CR106 CTL_REG(0x01A8) +#define ZD_CR107 CTL_REG(0x01AC) +#define ZD_CR108 CTL_REG(0x01B0) +#define ZD_CR109 CTL_REG(0x01B4) +#define ZD_CR110 CTL_REG(0x01B8) +#define ZD_CR111 CTL_REG(0x01BC) +#define ZD_CR112 CTL_REG(0x01C0) +#define ZD_CR113 CTL_REG(0x01C4) +#define ZD_CR114 CTL_REG(0x01C8) +#define ZD_CR115 CTL_REG(0x01CC) +#define ZD_CR116 CTL_REG(0x01D0) +#define ZD_CR117 CTL_REG(0x01D4) +#define ZD_CR118 CTL_REG(0x01D8) +#define ZD_CR119 CTL_REG(0x01DC) +#define ZD_CR120 CTL_REG(0x01E0) +#define ZD_CR121 CTL_REG(0x01E4) +#define ZD_CR122 CTL_REG(0x01E8) +#define ZD_CR123 CTL_REG(0x01EC) +#define ZD_CR124 CTL_REG(0x01F0) +#define ZD_CR125 CTL_REG(0x01F4) +#define ZD_CR126 CTL_REG(0x01F8) +#define ZD_CR127 CTL_REG(0x01FC) +#define ZD_CR128 CTL_REG(0x0200) +#define ZD_CR129 CTL_REG(0x0204) +#define ZD_CR130 CTL_REG(0x0208) +#define ZD_CR131 CTL_REG(0x020C) +#define ZD_CR132 CTL_REG(0x0210) +#define ZD_CR133 CTL_REG(0x0214) +#define ZD_CR134 CTL_REG(0x0218) +#define ZD_CR135 CTL_REG(0x021C) +#define ZD_CR136 CTL_REG(0x0220) +#define ZD_CR137 CTL_REG(0x0224) +#define ZD_CR138 CTL_REG(0x0228) +#define ZD_CR139 CTL_REG(0x022C) +#define ZD_CR140 CTL_REG(0x0230) +#define ZD_CR141 CTL_REG(0x0234) +#define ZD_CR142 CTL_REG(0x0238) +#define ZD_CR143 CTL_REG(0x023C) +#define ZD_CR144 CTL_REG(0x0240) +#define ZD_CR145 CTL_REG(0x0244) +#define ZD_CR146 CTL_REG(0x0248) +#define ZD_CR147 CTL_REG(0x024C) +#define ZD_CR148 CTL_REG(0x0250) +#define ZD_CR149 CTL_REG(0x0254) +#define ZD_CR150 CTL_REG(0x0258) +#define ZD_CR151 CTL_REG(0x025C) +#define ZD_CR152 CTL_REG(0x0260) +#define ZD_CR153 CTL_REG(0x0264) +#define ZD_CR154 CTL_REG(0x0268) +#define ZD_CR155 CTL_REG(0x026C) +#define ZD_CR156 CTL_REG(0x0270) +#define ZD_CR157 CTL_REG(0x0274) +#define ZD_CR158 CTL_REG(0x0278) +#define ZD_CR159 CTL_REG(0x027C) +#define ZD_CR160 CTL_REG(0x0280) +#define ZD_CR161 CTL_REG(0x0284) +#define ZD_CR162 CTL_REG(0x0288) +#define ZD_CR163 CTL_REG(0x028C) +#define ZD_CR164 CTL_REG(0x0290) +#define ZD_CR165 CTL_REG(0x0294) +#define ZD_CR166 CTL_REG(0x0298) +#define ZD_CR167 CTL_REG(0x029C) +#define ZD_CR168 CTL_REG(0x02A0) +#define ZD_CR169 CTL_REG(0x02A4) +#define ZD_CR170 CTL_REG(0x02A8) +#define ZD_CR171 CTL_REG(0x02AC) +#define ZD_CR172 CTL_REG(0x02B0) +#define ZD_CR173 CTL_REG(0x02B4) +#define ZD_CR174 CTL_REG(0x02B8) +#define ZD_CR175 CTL_REG(0x02BC) +#define ZD_CR176 CTL_REG(0x02C0) +#define ZD_CR177 CTL_REG(0x02C4) +#define ZD_CR178 CTL_REG(0x02C8) +#define ZD_CR179 CTL_REG(0x02CC) +#define ZD_CR180 CTL_REG(0x02D0) +#define ZD_CR181 CTL_REG(0x02D4) +#define ZD_CR182 CTL_REG(0x02D8) +#define ZD_CR183 CTL_REG(0x02DC) +#define ZD_CR184 CTL_REG(0x02E0) +#define ZD_CR185 CTL_REG(0x02E4) +#define ZD_CR186 CTL_REG(0x02E8) +#define ZD_CR187 CTL_REG(0x02EC) +#define ZD_CR188 CTL_REG(0x02F0) +#define ZD_CR189 CTL_REG(0x02F4) +#define ZD_CR190 CTL_REG(0x02F8) +#define ZD_CR191 CTL_REG(0x02FC) +#define ZD_CR192 CTL_REG(0x0300) +#define ZD_CR193 CTL_REG(0x0304) +#define ZD_CR194 CTL_REG(0x0308) +#define ZD_CR195 CTL_REG(0x030C) +#define ZD_CR196 CTL_REG(0x0310) +#define ZD_CR197 CTL_REG(0x0314) +#define ZD_CR198 CTL_REG(0x0318) +#define ZD_CR199 CTL_REG(0x031C) +#define ZD_CR200 CTL_REG(0x0320) +#define ZD_CR201 CTL_REG(0x0324) +#define ZD_CR202 CTL_REG(0x0328) +#define ZD_CR203 CTL_REG(0x032C) /* I2C bus template value & flash + * control + */ +#define ZD_CR204 CTL_REG(0x0330) +#define ZD_CR205 CTL_REG(0x0334) +#define ZD_CR206 CTL_REG(0x0338) +#define ZD_CR207 CTL_REG(0x033C) +#define ZD_CR208 CTL_REG(0x0340) +#define ZD_CR209 CTL_REG(0x0344) +#define ZD_CR210 CTL_REG(0x0348) +#define ZD_CR211 CTL_REG(0x034C) +#define ZD_CR212 CTL_REG(0x0350) +#define ZD_CR213 CTL_REG(0x0354) +#define ZD_CR214 CTL_REG(0x0358) +#define ZD_CR215 CTL_REG(0x035C) +#define ZD_CR216 CTL_REG(0x0360) +#define ZD_CR217 CTL_REG(0x0364) +#define ZD_CR218 CTL_REG(0x0368) +#define ZD_CR219 CTL_REG(0x036C) +#define ZD_CR220 CTL_REG(0x0370) +#define ZD_CR221 CTL_REG(0x0374) +#define ZD_CR222 CTL_REG(0x0378) +#define ZD_CR223 CTL_REG(0x037C) +#define ZD_CR224 CTL_REG(0x0380) +#define ZD_CR225 CTL_REG(0x0384) +#define ZD_CR226 CTL_REG(0x0388) +#define ZD_CR227 CTL_REG(0x038C) +#define ZD_CR228 CTL_REG(0x0390) +#define ZD_CR229 CTL_REG(0x0394) +#define ZD_CR230 CTL_REG(0x0398) +#define ZD_CR231 CTL_REG(0x039C) +#define ZD_CR232 CTL_REG(0x03A0) +#define ZD_CR233 CTL_REG(0x03A4) +#define ZD_CR234 CTL_REG(0x03A8) +#define ZD_CR235 CTL_REG(0x03AC) +#define ZD_CR236 CTL_REG(0x03B0) + +#define ZD_CR240 CTL_REG(0x03C0) +/* bit 7: host-controlled RF register writes + * ZD_CR241-ZD_CR245: for hardware controlled writing of RF bits, not needed for + * USB */ -#define CR241 CTL_REG(0x03C4) -#define CR242 CTL_REG(0x03C8) -#define CR243 CTL_REG(0x03CC) -#define CR244 CTL_REG(0x03D0) -#define CR245 CTL_REG(0x03D4) - -#define CR251 CTL_REG(0x03EC) /* only used for activation and deactivation of - * Airoha RFs AL2230 and AL7230B - */ -#define CR252 CTL_REG(0x03F0) -#define CR253 CTL_REG(0x03F4) -#define CR254 CTL_REG(0x03F8) -#define CR255 CTL_REG(0x03FC) +#define ZD_CR241 CTL_REG(0x03C4) +#define ZD_CR242 CTL_REG(0x03C8) +#define ZD_CR243 CTL_REG(0x03CC) +#define ZD_CR244 CTL_REG(0x03D0) +#define ZD_CR245 CTL_REG(0x03D4) + +#define ZD_CR251 CTL_REG(0x03EC) /* only used for activation and + * deactivation of Airoha RFs AL2230 + * and AL7230B + */ +#define ZD_CR252 CTL_REG(0x03F0) +#define ZD_CR253 CTL_REG(0x03F4) +#define ZD_CR254 CTL_REG(0x03F8) +#define ZD_CR255 CTL_REG(0x03FC) #define CR_MAX_PHY_REG 255 diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h index 79dc1035592d..725b7c99b23d 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.h +++ b/drivers/net/wireless/zd1211rw/zd_rf.h @@ -55,7 +55,7 @@ struct zd_rf { * defaults to 1 (yes) */ u8 update_channel_int:1; - /* whether CR47 should be patched from the EEPROM, if the appropriate + /* whether ZD_CR47 should be patched from the EEPROM, if the appropriate * flag is set in the POD. The vendor driver suggests that this should * be done for all RF's, but a bug in their code prevents but their * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */ diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c index 74a8f7a55591..12babcb633c3 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c @@ -61,31 +61,31 @@ static const u32 zd1211b_al2230_table[][3] = { }; static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = { - { CR240, 0x57 }, { CR9, 0xe0 }, + { ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 }, }; static const struct zd_ioreq16 ioreqs_init_al2230s[] = { - { CR47, 0x1e }, /* MARK_002 */ - { CR106, 0x22 }, - { CR107, 0x2a }, /* MARK_002 */ - { CR109, 0x13 }, /* MARK_002 */ - { CR118, 0xf8 }, /* MARK_002 */ - { CR119, 0x12 }, { CR122, 0xe0 }, - { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */ - { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */ - { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */ + { ZD_CR47, 0x1e }, /* MARK_002 */ + { ZD_CR106, 0x22 }, + { ZD_CR107, 0x2a }, /* MARK_002 */ + { ZD_CR109, 0x13 }, /* MARK_002 */ + { ZD_CR118, 0xf8 }, /* MARK_002 */ + { ZD_CR119, 0x12 }, { ZD_CR122, 0xe0 }, + { ZD_CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */ + { ZD_CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */ + { ZD_CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */ }; static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) { int r; static const struct zd_ioreq16 ioreqs[] = { - { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, - { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, - { CR203, 0x06 }, + { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, + { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, + { ZD_CR203, 0x06 }, { }, - { CR240, 0x80 }, + { ZD_CR240, 0x80 }, }; r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -94,12 +94,12 @@ static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) /* related to antenna selection? */ if (chip->new_phy_layout) { - r = zd_iowrite16_locked(chip, 0xe1, CR9); + r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9); if (r) return r; } - return zd_iowrite16_locked(chip, 0x06, CR203); + return zd_iowrite16_locked(chip, 0x06, ZD_CR203); } static int zd1211_al2230_init_hw(struct zd_rf *rf) @@ -108,40 +108,40 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf) struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs_init[] = { - { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 }, - { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 }, - { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a }, - { CR109, 0x09 }, { CR110, 0x27 }, { CR111, 0x2b }, - { CR112, 0x2b }, { CR119, 0x0a }, { CR10, 0x89 }, + { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, + { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, + { ZD_CR44, 0x33 }, { ZD_CR106, 0x2a }, { ZD_CR107, 0x1a }, + { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, { ZD_CR111, 0x2b }, + { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, { ZD_CR10, 0x89 }, /* for newest (3rd cut) AL2300 */ - { CR17, 0x28 }, - { CR26, 0x93 }, { CR34, 0x30 }, + { ZD_CR17, 0x28 }, + { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 }, /* for newest (3rd cut) AL2300 */ - { CR35, 0x3e }, - { CR41, 0x24 }, { CR44, 0x32 }, + { ZD_CR35, 0x3e }, + { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, /* for newest (3rd cut) AL2300 */ - { CR46, 0x96 }, - { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 }, - { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, - { CR92, 0x0a }, { CR99, 0x28 }, { CR100, 0x00 }, - { CR101, 0x13 }, { CR102, 0x27 }, { CR106, 0x24 }, - { CR107, 0x2a }, { CR109, 0x09 }, { CR110, 0x13 }, - { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, - { CR114, 0x27 }, + { ZD_CR46, 0x96 }, + { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, + { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, + { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 }, + { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR106, 0x24 }, + { ZD_CR107, 0x2a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x13 }, + { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, + { ZD_CR114, 0x27 }, /* for newest (3rd cut) AL2300 */ - { CR115, 0x24 }, - { CR116, 0x24 }, { CR117, 0xf4 }, { CR118, 0xfc }, - { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 }, - { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff }, - { CR253, 0xff }, + { ZD_CR115, 0x24 }, + { ZD_CR116, 0x24 }, { ZD_CR117, 0xf4 }, { ZD_CR118, 0xfc }, + { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, { ZD_CR121, 0x77 }, + { ZD_CR122, 0xe0 }, { ZD_CR137, 0x88 }, { ZD_CR252, 0xff }, + { ZD_CR253, 0xff }, }; static const struct zd_ioreq16 ioreqs_pll[] = { /* shdnb(PLL_ON)=0 */ - { CR251, 0x2f }, + { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=1 */ - { CR251, 0x3f }, - { CR138, 0x28 }, { CR203, 0x06 }, + { ZD_CR251, 0x3f }, + { ZD_CR138, 0x28 }, { ZD_CR203, 0x06 }, }; static const u32 rv1[] = { @@ -161,7 +161,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf) 0x0805b6, 0x011687, 0x000688, - 0x0403b9, /* external control TX power (CR31) */ + 0x0403b9, /* external control TX power (ZD_CR31) */ 0x00dbba, 0x00099b, 0x0bdffc, @@ -221,52 +221,54 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf) struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs1[] = { - { CR10, 0x89 }, { CR15, 0x20 }, - { CR17, 0x2B }, /* for newest(3rd cut) AL2230 */ - { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 }, - { CR28, 0x3e }, { CR29, 0x00 }, - { CR33, 0x28 }, /* 5621 */ - { CR34, 0x30 }, - { CR35, 0x3e }, /* for newest(3rd cut) AL2230 */ - { CR41, 0x24 }, { CR44, 0x32 }, - { CR46, 0x99 }, /* for newest(3rd cut) AL2230 */ - { CR47, 0x1e }, + { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 }, + { ZD_CR17, 0x2B }, /* for newest(3rd cut) AL2230 */ + { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, + { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, + { ZD_CR33, 0x28 }, /* 5621 */ + { ZD_CR34, 0x30 }, + { ZD_CR35, 0x3e }, /* for newest(3rd cut) AL2230 */ + { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, + { ZD_CR46, 0x99 }, /* for newest(3rd cut) AL2230 */ + { ZD_CR47, 0x1e }, /* ZD1211B 05.06.10 */ - { CR48, 0x06 }, { CR49, 0xf9 }, { CR51, 0x01 }, - { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 }, - { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 }, - { CR69, 0x28 }, - - { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, - { CR87, 0x0a }, { CR89, 0x04 }, - { CR91, 0x00 }, /* 5621 */ - { CR92, 0x0a }, - { CR98, 0x8d }, /* 4804, for 1212 new algorithm */ - { CR99, 0x00 }, /* 5621 */ - { CR101, 0x13 }, { CR102, 0x27 }, - { CR106, 0x24 }, /* for newest(3rd cut) AL2230 */ - { CR107, 0x2a }, - { CR109, 0x13 }, /* 4804, for 1212 new algorithm */ - { CR110, 0x1f }, /* 4804, for 1212 new algorithm */ - { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, - { CR114, 0x27 }, - { CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */ - { CR116, 0x24 }, - { CR117, 0xfa }, /* for 1211b */ - { CR118, 0xfa }, /* for 1211b */ - { CR119, 0x10 }, - { CR120, 0x4f }, - { CR121, 0x6c }, /* for 1211b */ - { CR122, 0xfc }, /* E0->FC at 4902 */ - { CR123, 0x57 }, /* 5623 */ - { CR125, 0xad }, /* 4804, for 1212 new algorithm */ - { CR126, 0x6c }, /* 5614 */ - { CR127, 0x03 }, /* 4804, for 1212 new algorithm */ - { CR137, 0x50 }, /* 5614 */ - { CR138, 0xa8 }, - { CR144, 0xac }, /* 5621 */ - { CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 }, + { ZD_CR48, 0x06 }, { ZD_CR49, 0xf9 }, { ZD_CR51, 0x01 }, + { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 }, + { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 }, + { ZD_CR69, 0x28 }, + + { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, + { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, + { ZD_CR91, 0x00 }, /* 5621 */ + { ZD_CR92, 0x0a }, + { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */ + { ZD_CR99, 0x00 }, /* 5621 */ + { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, + { ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */ + { ZD_CR107, 0x2a }, + { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */ + { ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */ + { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, + { ZD_CR114, 0x27 }, + { ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) + * AL2230 + */ + { ZD_CR116, 0x24 }, + { ZD_CR117, 0xfa }, /* for 1211b */ + { ZD_CR118, 0xfa }, /* for 1211b */ + { ZD_CR119, 0x10 }, + { ZD_CR120, 0x4f }, + { ZD_CR121, 0x6c }, /* for 1211b */ + { ZD_CR122, 0xfc }, /* E0->FC at 4902 */ + { ZD_CR123, 0x57 }, /* 5623 */ + { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */ + { ZD_CR126, 0x6c }, /* 5614 */ + { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */ + { ZD_CR137, 0x50 }, /* 5614 */ + { ZD_CR138, 0xa8 }, + { ZD_CR144, 0xac }, /* 5621 */ + { ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 }, }; static const u32 rv1[] = { @@ -284,7 +286,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf) 0x6da010, /* Reg6 update for MP versio */ 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */ 0x116000, - 0x9dc020, /* External control TX power (CR31) */ + 0x9dc020, /* External control TX power (ZD_CR31) */ 0x5ddb00, /* RegA update for MP version */ 0xd99000, /* RegB update for MP version */ 0x3ffbd0, /* RegC update for MP version */ @@ -295,8 +297,8 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf) }; static const struct zd_ioreq16 ioreqs2[] = { - { CR251, 0x2f }, /* shdnb(PLL_ON)=0 */ - { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ + { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */ + { ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ }; static const u32 rv3[] = { @@ -308,7 +310,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf) static const struct zd_ioreq16 ioreqs3[] = { /* related to 6M band edge patching, happens unconditionally */ - { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, }; r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, @@ -361,8 +363,8 @@ static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel) const u32 *rv = zd1211_al2230_table[channel-1]; struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR138, 0x28 }, - { CR203, 0x06 }, + { ZD_CR138, 0x28 }, + { ZD_CR203, 0x06 }, }; r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS); @@ -393,8 +395,8 @@ static int zd1211_al2230_switch_radio_on(struct zd_rf *rf) { struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x00 }, - { CR251, 0x3f }, + { ZD_CR11, 0x00 }, + { ZD_CR251, 0x3f }, }; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -404,8 +406,8 @@ static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf) { struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x00 }, - { CR251, 0x7f }, + { ZD_CR11, 0x00 }, + { ZD_CR251, 0x7f }, }; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -415,8 +417,8 @@ static int al2230_switch_radio_off(struct zd_rf *rf) { struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x04 }, - { CR251, 0x2f }, + { ZD_CR11, 0x04 }, + { ZD_CR251, 0x2f }, }; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c index 65095d661e6b..385c670d1293 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c @@ -68,19 +68,19 @@ static const u32 rv_init2[] = { }; static const struct zd_ioreq16 ioreqs_sw[] = { - { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, - { CR38, 0x38 }, { CR136, 0xdf }, + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, + { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf }, }; static int zd1211b_al7230b_finalize(struct zd_chip *chip) { int r; static const struct zd_ioreq16 ioreqs[] = { - { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, - { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, - { CR203, 0x04 }, + { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, + { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, + { ZD_CR203, 0x04 }, { }, - { CR240, 0x80 }, + { ZD_CR240, 0x80 }, }; r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -89,12 +89,12 @@ static int zd1211b_al7230b_finalize(struct zd_chip *chip) if (chip->new_phy_layout) { /* antenna selection? */ - r = zd_iowrite16_locked(chip, 0xe5, CR9); + r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9); if (r) return r; } - return zd_iowrite16_locked(chip, 0x04, CR203); + return zd_iowrite16_locked(chip, 0x04, ZD_CR203); } static int zd1211_al7230b_init_hw(struct zd_rf *rf) @@ -106,66 +106,66 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf) * specified */ static const struct zd_ioreq16 ioreqs_1[] = { /* This one is 7230-specific, and happens before the rest */ - { CR240, 0x57 }, + { ZD_CR240, 0x57 }, { }, - { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 }, - { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 }, - { CR44, 0x33 }, + { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, + { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, + { ZD_CR44, 0x33 }, /* This value is different for 7230 (was: 0x2a) */ - { CR106, 0x22 }, - { CR107, 0x1a }, { CR109, 0x09 }, { CR110, 0x27 }, - { CR111, 0x2b }, { CR112, 0x2b }, { CR119, 0x0a }, + { ZD_CR106, 0x22 }, + { ZD_CR107, 0x1a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, + { ZD_CR111, 0x2b }, { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, /* This happened further down in AL2230, * and the value changed (was: 0xe0) */ - { CR122, 0xfc }, - { CR10, 0x89 }, + { ZD_CR122, 0xfc }, + { ZD_CR10, 0x89 }, /* for newest (3rd cut) AL2300 */ - { CR17, 0x28 }, - { CR26, 0x93 }, { CR34, 0x30 }, + { ZD_CR17, 0x28 }, + { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 }, /* for newest (3rd cut) AL2300 */ - { CR35, 0x3e }, - { CR41, 0x24 }, { CR44, 0x32 }, + { ZD_CR35, 0x3e }, + { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, /* for newest (3rd cut) AL2300 */ - { CR46, 0x96 }, - { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 }, - { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, - { CR92, 0x0a }, { CR99, 0x28 }, + { ZD_CR46, 0x96 }, + { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, + { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, + { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, /* This value is different for 7230 (was: 0x00) */ - { CR100, 0x02 }, - { CR101, 0x13 }, { CR102, 0x27 }, + { ZD_CR100, 0x02 }, + { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, /* This value is different for 7230 (was: 0x24) */ - { CR106, 0x22 }, + { ZD_CR106, 0x22 }, /* This value is different for 7230 (was: 0x2a) */ - { CR107, 0x3f }, - { CR109, 0x09 }, + { ZD_CR107, 0x3f }, + { ZD_CR109, 0x09 }, /* This value is different for 7230 (was: 0x13) */ - { CR110, 0x1f }, - { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 }, - { CR114, 0x27 }, + { ZD_CR110, 0x1f }, + { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, + { ZD_CR114, 0x27 }, /* for newest (3rd cut) AL2300 */ - { CR115, 0x24 }, + { ZD_CR115, 0x24 }, /* This value is different for 7230 (was: 0x24) */ - { CR116, 0x3f }, + { ZD_CR116, 0x3f }, /* This value is different for 7230 (was: 0xf4) */ - { CR117, 0xfa }, - { CR118, 0xfc }, { CR119, 0x10 }, { CR120, 0x4f }, - { CR121, 0x77 }, { CR137, 0x88 }, + { ZD_CR117, 0xfa }, + { ZD_CR118, 0xfc }, { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, + { ZD_CR121, 0x77 }, { ZD_CR137, 0x88 }, /* This one is 7230-specific */ - { CR138, 0xa8 }, + { ZD_CR138, 0xa8 }, /* This value is different for 7230 (was: 0xff) */ - { CR252, 0x34 }, + { ZD_CR252, 0x34 }, /* This value is different for 7230 (was: 0xff) */ - { CR253, 0x34 }, + { ZD_CR253, 0x34 }, /* PLL_OFF */ - { CR251, 0x2f }, + { ZD_CR251, 0x2f }, }; static const struct zd_ioreq16 ioreqs_2[] = { - { CR251, 0x3f }, /* PLL_ON */ - { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, - { CR38, 0x38 }, { CR136, 0xdf }, + { ZD_CR251, 0x3f }, /* PLL_ON */ + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, + { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf }, }; r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); @@ -192,10 +192,10 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf) if (r) return r; - r = zd_iowrite16_locked(chip, 0x06, CR203); + r = zd_iowrite16_locked(chip, 0x06, ZD_CR203); if (r) return r; - r = zd_iowrite16_locked(chip, 0x80, CR240); + r = zd_iowrite16_locked(chip, 0x80, ZD_CR240); if (r) return r; @@ -208,79 +208,79 @@ static int zd1211b_al7230b_init_hw(struct zd_rf *rf) struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs_1[] = { - { CR240, 0x57 }, { CR9, 0x9 }, + { ZD_CR240, 0x57 }, { ZD_CR9, 0x9 }, { }, - { CR10, 0x8b }, { CR15, 0x20 }, - { CR17, 0x2B }, /* for newest (3rd cut) AL2230 */ - { CR20, 0x10 }, /* 4N25->Stone Request */ - { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 }, - { CR28, 0x3e }, { CR29, 0x00 }, - { CR33, 0x28 }, /* 5613 */ - { CR34, 0x30 }, - { CR35, 0x3e }, /* for newest (3rd cut) AL2230 */ - { CR41, 0x24 }, { CR44, 0x32 }, - { CR46, 0x99 }, /* for newest (3rd cut) AL2230 */ - { CR47, 0x1e }, + { ZD_CR10, 0x8b }, { ZD_CR15, 0x20 }, + { ZD_CR17, 0x2B }, /* for newest (3rd cut) AL2230 */ + { ZD_CR20, 0x10 }, /* 4N25->Stone Request */ + { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, + { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, + { ZD_CR33, 0x28 }, /* 5613 */ + { ZD_CR34, 0x30 }, + { ZD_CR35, 0x3e }, /* for newest (3rd cut) AL2230 */ + { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, + { ZD_CR46, 0x99 }, /* for newest (3rd cut) AL2230 */ + { ZD_CR47, 0x1e }, /* ZD1215 5610 */ - { CR48, 0x00 }, { CR49, 0x00 }, { CR51, 0x01 }, - { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 }, - { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 }, - { CR69, 0x28 }, - - { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, - { CR87, 0x0A }, { CR89, 0x04 }, - { CR90, 0x58 }, /* 5112 */ - { CR91, 0x00 }, /* 5613 */ - { CR92, 0x0a }, - { CR98, 0x8d }, /* 4804, for 1212 new algorithm */ - { CR99, 0x00 }, { CR100, 0x02 }, { CR101, 0x13 }, - { CR102, 0x27 }, - { CR106, 0x20 }, /* change to 0x24 for AL7230B */ - { CR109, 0x13 }, /* 4804, for 1212 new algorithm */ - { CR112, 0x1f }, + { ZD_CR48, 0x00 }, { ZD_CR49, 0x00 }, { ZD_CR51, 0x01 }, + { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 }, + { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 }, + { ZD_CR69, 0x28 }, + + { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, + { ZD_CR87, 0x0A }, { ZD_CR89, 0x04 }, + { ZD_CR90, 0x58 }, /* 5112 */ + { ZD_CR91, 0x00 }, /* 5613 */ + { ZD_CR92, 0x0a }, + { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */ + { ZD_CR99, 0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 }, + { ZD_CR102, 0x27 }, + { ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */ + { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */ + { ZD_CR112, 0x1f }, }; static const struct zd_ioreq16 ioreqs_new_phy[] = { - { CR107, 0x28 }, - { CR110, 0x1f }, /* 5127, 0x13->0x1f */ - { CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */ - { CR116, 0x2a }, { CR118, 0xfa }, { CR119, 0x12 }, - { CR121, 0x6c }, /* 5613 */ + { ZD_CR107, 0x28 }, + { ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */ + { ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */ + { ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 }, + { ZD_CR121, 0x6c }, /* 5613 */ }; static const struct zd_ioreq16 ioreqs_old_phy[] = { - { CR107, 0x24 }, - { CR110, 0x13 }, /* 5127, 0x13->0x1f */ - { CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */ - { CR116, 0x24 }, { CR118, 0xfc }, { CR119, 0x11 }, - { CR121, 0x6a }, /* 5613 */ + { ZD_CR107, 0x24 }, + { ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */ + { ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */ + { ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 }, + { ZD_CR121, 0x6a }, /* 5613 */ }; static const struct zd_ioreq16 ioreqs_2[] = { - { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x24 }, - { CR117, 0xfa }, { CR120, 0x4f }, - { CR122, 0xfc }, /* E0->FCh at 4901 */ - { CR123, 0x57 }, /* 5613 */ - { CR125, 0xad }, /* 4804, for 1212 new algorithm */ - { CR126, 0x6c }, /* 5613 */ - { CR127, 0x03 }, /* 4804, for 1212 new algorithm */ - { CR130, 0x10 }, - { CR131, 0x00 }, /* 5112 */ - { CR137, 0x50 }, /* 5613 */ - { CR138, 0xa8 }, /* 5112 */ - { CR144, 0xac }, /* 5613 */ - { CR148, 0x40 }, /* 5112 */ - { CR149, 0x40 }, /* 4O07, 50->40 */ - { CR150, 0x1a }, /* 5112, 0C->1A */ - { CR252, 0x34 }, { CR253, 0x34 }, - { CR251, 0x2f }, /* PLL_OFF */ + { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 }, + { ZD_CR117, 0xfa }, { ZD_CR120, 0x4f }, + { ZD_CR122, 0xfc }, /* E0->FCh at 4901 */ + { ZD_CR123, 0x57 }, /* 5613 */ + { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */ + { ZD_CR126, 0x6c }, /* 5613 */ + { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */ + { ZD_CR130, 0x10 }, + { ZD_CR131, 0x00 }, /* 5112 */ + { ZD_CR137, 0x50 }, /* 5613 */ + { ZD_CR138, 0xa8 }, /* 5112 */ + { ZD_CR144, 0xac }, /* 5613 */ + { ZD_CR148, 0x40 }, /* 5112 */ + { ZD_CR149, 0x40 }, /* 4O07, 50->40 */ + { ZD_CR150, 0x1a }, /* 5112, 0C->1A */ + { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 }, + { ZD_CR251, 0x2f }, /* PLL_OFF */ }; static const struct zd_ioreq16 ioreqs_3[] = { - { CR251, 0x7f }, /* PLL_ON */ - { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 }, - { CR38, 0x38 }, { CR136, 0xdf }, + { ZD_CR251, 0x7f }, /* PLL_ON */ + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, + { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf }, }; r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); @@ -331,16 +331,16 @@ static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel) static const struct zd_ioreq16 ioreqs[] = { /* PLL_ON */ - { CR251, 0x3f }, - { CR203, 0x06 }, { CR240, 0x08 }, + { ZD_CR251, 0x3f }, + { ZD_CR203, 0x06 }, { ZD_CR240, 0x08 }, }; - r = zd_iowrite16_locked(chip, 0x57, CR240); + r = zd_iowrite16_locked(chip, 0x57, ZD_CR240); if (r) return r; /* PLL_OFF */ - r = zd_iowrite16_locked(chip, 0x2f, CR251); + r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251); if (r) return r; @@ -376,15 +376,15 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel) const u32 *rv = chan_rv[channel-1]; struct zd_chip *chip = zd_rf_to_chip(rf); - r = zd_iowrite16_locked(chip, 0x57, CR240); + r = zd_iowrite16_locked(chip, 0x57, ZD_CR240); if (r) return r; - r = zd_iowrite16_locked(chip, 0xe4, CR9); + r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9); if (r) return r; /* PLL_OFF */ - r = zd_iowrite16_locked(chip, 0x2f, CR251); + r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251); if (r) return r; r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv)); @@ -410,7 +410,7 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel) if (r) return r; - r = zd_iowrite16_locked(chip, 0x7f, CR251); + r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251); if (r) return r; @@ -421,8 +421,8 @@ static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf) { struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x00 }, - { CR251, 0x3f }, + { ZD_CR11, 0x00 }, + { ZD_CR251, 0x3f }, }; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -432,8 +432,8 @@ static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf) { struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x00 }, - { CR251, 0x7f }, + { ZD_CR11, 0x00 }, + { ZD_CR251, 0x7f }, }; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -443,8 +443,8 @@ static int al7230b_switch_radio_off(struct zd_rf *rf) { struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x04 }, - { CR251, 0x2f }, + { ZD_CR11, 0x04 }, + { ZD_CR251, 0x2f }, }; return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); @@ -456,7 +456,7 @@ static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel) { struct zd_chip *chip = zd_rf_to_chip(rf); struct zd_ioreq16 ioreqs[] = { - { CR128, 0x14 }, { CR129, 0x12 }, + { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, }; /* FIXME: Channel 11 is not the edge for all regulatory domains. */ diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c index 0597d862fbd2..032542614259 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c @@ -152,44 +152,44 @@ static int rf2959_init_hw(struct zd_rf *rf) struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR2, 0x1E }, { CR9, 0x20 }, { CR10, 0x89 }, - { CR11, 0x00 }, { CR15, 0xD0 }, { CR17, 0x68 }, - { CR19, 0x4a }, { CR20, 0x0c }, { CR21, 0x0E }, - { CR23, 0x48 }, + { ZD_CR2, 0x1E }, { ZD_CR9, 0x20 }, { ZD_CR10, 0x89 }, + { ZD_CR11, 0x00 }, { ZD_CR15, 0xD0 }, { ZD_CR17, 0x68 }, + { ZD_CR19, 0x4a }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0E }, + { ZD_CR23, 0x48 }, /* normal size for cca threshold */ - { CR24, 0x14 }, - /* { CR24, 0x20 }, */ - { CR26, 0x90 }, { CR27, 0x30 }, { CR29, 0x20 }, - { CR31, 0xb2 }, { CR32, 0x43 }, { CR33, 0x28 }, - { CR38, 0x30 }, { CR34, 0x0f }, { CR35, 0xF0 }, - { CR41, 0x2a }, { CR46, 0x7F }, { CR47, 0x1E }, - { CR51, 0xc5 }, { CR52, 0xc5 }, { CR53, 0xc5 }, - { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 }, - { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 }, - { CR85, 0x00 }, { CR86, 0x10 }, { CR87, 0x2A }, - { CR88, 0x10 }, { CR89, 0x24 }, { CR90, 0x18 }, - /* { CR91, 0x18 }, */ + { ZD_CR24, 0x14 }, + /* { ZD_CR24, 0x20 }, */ + { ZD_CR26, 0x90 }, { ZD_CR27, 0x30 }, { ZD_CR29, 0x20 }, + { ZD_CR31, 0xb2 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x28 }, + { ZD_CR38, 0x30 }, { ZD_CR34, 0x0f }, { ZD_CR35, 0xF0 }, + { ZD_CR41, 0x2a }, { ZD_CR46, 0x7F }, { ZD_CR47, 0x1E }, + { ZD_CR51, 0xc5 }, { ZD_CR52, 0xc5 }, { ZD_CR53, 0xc5 }, + { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, + { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 }, + { ZD_CR85, 0x00 }, { ZD_CR86, 0x10 }, { ZD_CR87, 0x2A }, + { ZD_CR88, 0x10 }, { ZD_CR89, 0x24 }, { ZD_CR90, 0x18 }, + /* { ZD_CR91, 0x18 }, */ /* should solve continous CTS frame problems */ - { CR91, 0x00 }, - { CR92, 0x0a }, { CR93, 0x00 }, { CR94, 0x01 }, - { CR95, 0x00 }, { CR96, 0x40 }, { CR97, 0x37 }, - { CR98, 0x05 }, { CR99, 0x28 }, { CR100, 0x00 }, - { CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 }, - { CR104, 0x18 }, { CR105, 0x12 }, + { ZD_CR91, 0x00 }, + { ZD_CR92, 0x0a }, { ZD_CR93, 0x00 }, { ZD_CR94, 0x01 }, + { ZD_CR95, 0x00 }, { ZD_CR96, 0x40 }, { ZD_CR97, 0x37 }, + { ZD_CR98, 0x05 }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 }, + { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, + { ZD_CR104, 0x18 }, { ZD_CR105, 0x12 }, /* normal size */ - { CR106, 0x1a }, - /* { CR106, 0x22 }, */ - { CR107, 0x24 }, { CR108, 0x0a }, { CR109, 0x13 }, - { CR110, 0x2F }, { CR111, 0x27 }, { CR112, 0x27 }, - { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x40 }, - { CR116, 0x40 }, { CR117, 0xF0 }, { CR118, 0xF0 }, - { CR119, 0x16 }, + { ZD_CR106, 0x1a }, + /* { ZD_CR106, 0x22 }, */ + { ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 }, + { ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, + { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 }, + { ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 }, + { ZD_CR119, 0x16 }, /* no TX continuation */ - { CR122, 0x00 }, - /* { CR122, 0xff }, */ - { CR127, 0x03 }, { CR131, 0x08 }, { CR138, 0x28 }, - { CR148, 0x44 }, { CR150, 0x10 }, { CR169, 0xBB }, - { CR170, 0xBB }, + { ZD_CR122, 0x00 }, + /* { ZD_CR122, 0xff }, */ + { ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 }, + { ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB }, + { ZD_CR170, 0xBB }, }; static const u32 rv[] = { @@ -210,7 +210,7 @@ static int rf2959_init_hw(struct zd_rf *rf) */ 0x294128, /* internal power */ /* 0x28252c, */ /* External control TX power */ - /* CR31_CCK, CR51_6-36M, CR52_48M, CR53_54M */ + /* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */ 0x2c0000, 0x300000, 0x340000, /* REG13(0xD) */ @@ -245,8 +245,8 @@ static int rf2959_set_channel(struct zd_rf *rf, u8 channel) static int rf2959_switch_radio_on(struct zd_rf *rf) { static const struct zd_ioreq16 ioreqs[] = { - { CR10, 0x89 }, - { CR11, 0x00 }, + { ZD_CR10, 0x89 }, + { ZD_CR11, 0x00 }, }; struct zd_chip *chip = zd_rf_to_chip(rf); @@ -256,8 +256,8 @@ static int rf2959_switch_radio_on(struct zd_rf *rf) static int rf2959_switch_radio_off(struct zd_rf *rf) { static const struct zd_ioreq16 ioreqs[] = { - { CR10, 0x15 }, - { CR11, 0x81 }, + { ZD_CR10, 0x15 }, + { ZD_CR11, 0x81 }, }; struct zd_chip *chip = zd_rf_to_chip(rf); diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c index 9e74eb1b67d5..860b0af7dc3e 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c @@ -314,42 +314,44 @@ static int uw2453_init_hw(struct zd_rf *rf) struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR10, 0x89 }, { CR15, 0x20 }, - { CR17, 0x28 }, /* 6112 no change */ - { CR23, 0x38 }, { CR24, 0x20 }, { CR26, 0x93 }, - { CR27, 0x15 }, { CR28, 0x3e }, { CR29, 0x00 }, - { CR33, 0x28 }, { CR34, 0x30 }, - { CR35, 0x43 }, /* 6112 3e->43 */ - { CR41, 0x24 }, { CR44, 0x32 }, - { CR46, 0x92 }, /* 6112 96->92 */ - { CR47, 0x1e }, - { CR48, 0x04 }, /* 5602 Roger */ - { CR49, 0xfa }, { CR79, 0x58 }, { CR80, 0x30 }, - { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 }, - { CR91, 0x00 }, { CR92, 0x0a }, { CR98, 0x8d }, - { CR99, 0x28 }, { CR100, 0x02 }, - { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */ - { CR102, 0x27 }, - { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */ - { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */ - { CR109, 0x13 }, - { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */ - { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 }, - { CR114, 0x23 }, /* 6221 27->23 */ - { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */ - { CR116, 0x24 }, /* 6220 1c->24 */ - { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */ - { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */ - { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */ - { CR120, 0x4f }, - { CR121, 0x1f }, /* 6220 4f->1f */ - { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad }, - { CR126, 0x6c }, { CR127, 0x03 }, - { CR128, 0x14 }, /* 6302 12->11 */ - { CR129, 0x12 }, /* 6301 10->0f */ - { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 }, - { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff }, - { CR253, 0xff }, + { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 }, + { ZD_CR17, 0x28 }, /* 6112 no change */ + { ZD_CR23, 0x38 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, + { ZD_CR27, 0x15 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, + { ZD_CR33, 0x28 }, { ZD_CR34, 0x30 }, + { ZD_CR35, 0x43 }, /* 6112 3e->43 */ + { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, + { ZD_CR46, 0x92 }, /* 6112 96->92 */ + { ZD_CR47, 0x1e }, + { ZD_CR48, 0x04 }, /* 5602 Roger */ + { ZD_CR49, 0xfa }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, + { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, + { ZD_CR91, 0x00 }, { ZD_CR92, 0x0a }, { ZD_CR98, 0x8d }, + { ZD_CR99, 0x28 }, { ZD_CR100, 0x02 }, + { ZD_CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */ + { ZD_CR102, 0x27 }, + { ZD_CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f + * 6221 1f->1c + */ + { ZD_CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */ + { ZD_CR109, 0x13 }, + { ZD_CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */ + { ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, + { ZD_CR114, 0x23 }, /* 6221 27->23 */ + { ZD_CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */ + { ZD_CR116, 0x24 }, /* 6220 1c->24 */ + { ZD_CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */ + { ZD_CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */ + { ZD_CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */ + { ZD_CR120, 0x4f }, + { ZD_CR121, 0x1f }, /* 6220 4f->1f */ + { ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad }, + { ZD_CR126, 0x6c }, { ZD_CR127, 0x03 }, + { ZD_CR128, 0x14 }, /* 6302 12->11 */ + { ZD_CR129, 0x12 }, /* 6301 10->0f */ + { ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 }, + { ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff }, + { ZD_CR253, 0xff }, }; static const u32 rv[] = { @@ -433,7 +435,7 @@ static int uw2453_init_hw(struct zd_rf *rf) * the one that produced a lock. */ UW2453_PRIV(rf)->config = found_config + 1; - return zd_iowrite16_locked(chip, 0x06, CR203); + return zd_iowrite16_locked(chip, 0x06, ZD_CR203); } static int uw2453_set_channel(struct zd_rf *rf, u8 channel) @@ -445,8 +447,8 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel) struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 }, - { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 }, + { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, + { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, }; r = uw2453_synth_set_channel(chip, channel, autocal); @@ -474,7 +476,7 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel) if (r) return r; - return zd_iowrite16_locked(chip, 0x06, CR203); + return zd_iowrite16_locked(chip, 0x06, ZD_CR203); } static int uw2453_switch_radio_on(struct zd_rf *rf) @@ -482,7 +484,7 @@ static int uw2453_switch_radio_on(struct zd_rf *rf) int r; struct zd_chip *chip = zd_rf_to_chip(rf); struct zd_ioreq16 ioreqs[] = { - { CR11, 0x00 }, { CR251, 0x3f }, + { ZD_CR11, 0x00 }, { ZD_CR251, 0x3f }, }; /* enter RXTX mode */ @@ -501,7 +503,7 @@ static int uw2453_switch_radio_off(struct zd_rf *rf) int r; struct zd_chip *chip = zd_rf_to_chip(rf); static const struct zd_ioreq16 ioreqs[] = { - { CR11, 0x04 }, { CR251, 0x2f }, + { ZD_CR11, 0x04 }, { ZD_CR251, 0x2f }, }; /* enter IDLE mode */ diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 58236e6d0921..c9c1362e9499 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1877,10 +1877,10 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits); - r = zd_usb_ioread16(usb, &bit_value_template, CR203); + r = zd_usb_ioread16(usb, &bit_value_template, ZD_CR203); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error %d: Couldn't read CR203\n", r); + "error %d: Couldn't read ZD_CR203\n", r); return r; } bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index b3df2c8116cc..3924258ce177 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -109,7 +109,7 @@ struct usb_req_rfwrite { __le16 bits; /* RF2595: 24 */ __le16 bit_values[0]; - /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ + /* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ } __packed; /* USB interrupt */ -- GitLab From ffbd308dce898a857de76d17cc05748505cf4ece Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Sun, 3 Apr 2011 19:05:28 +0530 Subject: [PATCH 0578/5560] mac80211: remove few obsolete flags Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 64d92d5a7f40..865fed4cc18b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -90,20 +90,11 @@ enum rx_mgmt_action { /* no action required */ RX_MGMT_NONE, - /* caller must call cfg80211_send_rx_auth() */ - RX_MGMT_CFG80211_AUTH, - - /* caller must call cfg80211_send_rx_assoc() */ - RX_MGMT_CFG80211_ASSOC, - /* caller must call cfg80211_send_deauth() */ RX_MGMT_CFG80211_DEAUTH, /* caller must call cfg80211_send_disassoc() */ RX_MGMT_CFG80211_DISASSOC, - - /* caller must tell cfg80211 about internal error */ - RX_MGMT_CFG80211_ASSOC_ERROR, }; /* utils */ -- GitLab From a0bbb58bcb70295ff05f870c93d34f9fbe614204 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 4 Apr 2011 11:04:57 +0300 Subject: [PATCH 0579/5560] wl1251: Prepare for idle mode support RFC for WL1251 idle mode support brought a few issues that are worth to update before adding the idle mode support. Since the idle mode can reuse the code that is now used in Power Save Mode (PSM), the flag psm in struct wl1251 is changed to variable station_mode to be able to distinguish between PSM and idle modes. As the station mode is different than the power power save mode command that is sent to chip, the enum wl1251_cmd_ps_mod values are used only when communicating with the chip and new enum wl1251_station_mode values are used inside the driver. Confusing comment about psm and elp relation is removed since the PSM is actually activated by putting the chip into Entreme Low Power (ELP) mode. Signed-off-by: Jarkko Nikula Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/cmd.h | 4 ++-- drivers/net/wireless/wl1251/event.c | 6 ++++-- drivers/net/wireless/wl1251/main.c | 6 +++--- drivers/net/wireless/wl1251/ps.c | 14 ++++++-------- drivers/net/wireless/wl1251/ps.h | 2 +- drivers/net/wireless/wl1251/wl1251.h | 8 ++++++-- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h index e5c74c631374..79ca5273c9e9 100644 --- a/drivers/net/wireless/wl1251/cmd.h +++ b/drivers/net/wireless/wl1251/cmd.h @@ -313,8 +313,8 @@ struct wl1251_cmd_vbm_update { } __packed; enum wl1251_cmd_ps_mode { - STATION_ACTIVE_MODE, - STATION_POWER_SAVE_MODE + CHIP_ACTIVE_MODE, + CHIP_POWER_SAVE_MODE }; struct wl1251_cmd_ps_params { diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c index dfc4579acb06..9f15ccaf8f05 100644 --- a/drivers/net/wireless/wl1251/event.c +++ b/drivers/net/wireless/wl1251/event.c @@ -68,14 +68,16 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) if (vector & BSS_LOSE_EVENT_ID) { wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); - if (wl->psm_requested && wl->psm) { + if (wl->psm_requested && + wl->station_mode != STATION_ACTIVE_MODE) { ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); if (ret < 0) return ret; } } - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && + wl->station_mode != STATION_ACTIVE_MODE) { wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); /* indicate to the stack, that beacons have been lost */ diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 12c9e635a6d6..04a054915dbe 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -497,7 +497,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) wl->rx_last_id = 0; wl->next_tx_complete = 0; wl->elp = false; - wl->psm = 0; + wl->station_mode = STATION_ACTIVE_MODE; wl->tx_queue_stopped = false; wl->power_level = WL1251_DEFAULT_POWER_LEVEL; wl->rssi_thold = 0; @@ -632,7 +632,7 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) wl->psm_requested = false; - if (wl->psm) { + if (wl->station_mode != STATION_ACTIVE_MODE) { ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); if (ret < 0) goto out_sleep; @@ -1384,7 +1384,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) wl->rx_config = WL1251_DEFAULT_RX_CONFIG; wl->rx_filter = WL1251_DEFAULT_RX_FILTER; wl->elp = false; - wl->psm = 0; + wl->station_mode = STATION_ACTIVE_MODE; wl->psm_requested = false; wl->tx_queue_stopped = false; wl->power_level = WL1251_DEFAULT_POWER_LEVEL; diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c index 9cc514703d2a..97a5b8c82f01 100644 --- a/drivers/net/wireless/wl1251/ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -39,7 +39,7 @@ void wl1251_elp_work(struct work_struct *work) mutex_lock(&wl->mutex); - if (wl->elp || !wl->psm) + if (wl->elp || wl->station_mode == STATION_ACTIVE_MODE) goto out; wl1251_debug(DEBUG_PSM, "chip to elp"); @@ -57,7 +57,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl) { unsigned long delay; - if (wl->psm) { + if (wl->station_mode != STATION_ACTIVE_MODE) { delay = msecs_to_jiffies(ELP_ENTRY_DELAY); ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); } @@ -104,7 +104,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) return 0; } -int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) +int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode) { int ret; @@ -128,15 +128,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) if (ret < 0) return ret; - ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); + ret = wl1251_cmd_ps_mode(wl, CHIP_POWER_SAVE_MODE); if (ret < 0) return ret; ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); if (ret < 0) return ret; - - wl->psm = 1; break; case STATION_ACTIVE_MODE: default: @@ -163,13 +161,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) if (ret < 0) return ret; - ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE); + ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE); if (ret < 0) return ret; - wl->psm = 0; break; } + wl->station_mode = mode; return ret; } diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/wl1251/ps.h index 55c3dda75e69..75efad246d67 100644 --- a/drivers/net/wireless/wl1251/ps.h +++ b/drivers/net/wireless/wl1251/ps.h @@ -26,7 +26,7 @@ #include "wl1251.h" #include "acx.h" -int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); +int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode); void wl1251_ps_elp_sleep(struct wl1251 *wl); int wl1251_ps_elp_wakeup(struct wl1251 *wl); void wl1251_elp_work(struct work_struct *work); diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index bb23cd522b22..bf245a87e80e 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -129,6 +129,11 @@ enum wl1251_partition_type { PART_TABLE_LEN }; +enum wl1251_station_mode { + STATION_ACTIVE_MODE, + STATION_POWER_SAVE_MODE, +}; + struct wl1251_partition { u32 size; u32 start; @@ -358,8 +363,7 @@ struct wl1251 { struct delayed_work elp_work; - /* we can be in psm, but not in elp, we have to differentiate */ - bool psm; + enum wl1251_station_mode station_mode; /* PSM mode requested */ bool psm_requested; -- GitLab From 1e5f52de216a32986a5c3cbc358dbb2620a03047 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 4 Apr 2011 11:04:58 +0300 Subject: [PATCH 0580/5560] wl1251: Add support for idle mode On Nokia N900 the wl1251 consumes the most power when the interface is up but not associated to access point (that supports PSM). In terms of battery current consumption, the consumption is ~180 mA higher when the interface is up but not associated and only ~5 mA higher when associated compared to interface down and driver not loaded cases. This patch adds support for the mac80211 idle notifications. Chip is put into idle very much the same way when entering into PSM by utilizing the Extreme Low Power (ELP) mode. I.e. idle is entered by setting necessary conditions in wl1251_ps_set_mode followed by a call to wl1251_ps_elp_sleep. It seems it is just enough the authorize ELP mode followed by CMD_DISCONNECT (thanks to Kalle Valo about the idea to use it). Without disconnect command the chip remains somewhat active and stays consuming ~20 mA. Idle mode is left by same way than PSM. The wl1251_join call is used to revert the CMD_DISCONNECT. Without it association to AP doesn't work when trying second time. With this patch the interface up but not associated case the battery current consumption is less than 1 mA higher compared to interface down case. Signed-off-by: Jarkko Nikula Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/main.c | 16 ++++++++++++++++ drivers/net/wireless/wl1251/ps.c | 11 +++++++++++ drivers/net/wireless/wl1251/wl1251.h | 1 + 3 files changed, 28 insertions(+) diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 04a054915dbe..a14a48c99cdc 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -639,6 +639,22 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) } } + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + if (conf->flags & IEEE80211_CONF_IDLE) { + ret = wl1251_ps_set_mode(wl, STATION_IDLE); + if (ret < 0) + goto out_sleep; + } else { + ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); + if (ret < 0) + goto out_sleep; + ret = wl1251_join(wl, wl->bss_type, wl->channel, + wl->beacon_int, wl->dtim_period); + if (ret < 0) + goto out_sleep; + } + } + if (conf->power_level != wl->power_level) { ret = wl1251_acx_tx_power(wl, conf->power_level); if (ret < 0) diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c index 97a5b8c82f01..db719f7d2692 100644 --- a/drivers/net/wireless/wl1251/ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -136,6 +136,17 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode) if (ret < 0) return ret; break; + case STATION_IDLE: + wl1251_debug(DEBUG_PSM, "entering idle"); + + ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); + if (ret < 0) + return ret; + + ret = wl1251_cmd_template_set(wl, CMD_DISCONNECT, NULL, 0); + if (ret < 0) + return ret; + break; case STATION_ACTIVE_MODE: default: wl1251_debug(DEBUG_PSM, "leaving psm"); diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index bf245a87e80e..a77f1bbbed0a 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -132,6 +132,7 @@ enum wl1251_partition_type { enum wl1251_station_mode { STATION_ACTIVE_MODE, STATION_POWER_SAVE_MODE, + STATION_IDLE, }; struct wl1251_partition { -- GitLab From 59575d1c717815d62f1b5aeac74e5e60a1b27428 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Apr 2011 22:56:16 +0530 Subject: [PATCH 0581/5560] ath9k: deny new interface addtion on IBSS mode The present check denies the IBSS interface addtion if we already have any other vifs. But it fails to deny interface addition if IBSS was already present. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3c5de73dcb4b..88073f4c2b6a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1479,8 +1479,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, } } - if ((vif->type == NL80211_IFTYPE_ADHOC) && - sc->nvifs > 0) { + if ((ah->opmode == NL80211_IFTYPE_ADHOC) || + ((vif->type == NL80211_IFTYPE_ADHOC) && + sc->nvifs > 0)) { ath_err(common, "Cannot create ADHOC interface when other" " interfaces already exist.\n"); ret = -EINVAL; -- GitLab From 66da424177db4f4f2fa7a462db5912655aad966f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Apr 2011 22:56:17 +0530 Subject: [PATCH 0582/5560] ath9k: Cleanup ath_vif struct Remove unused bssid from ath_vif and set av_bslot on beacon alloc/return. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath/ath9k/beacon.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 6 ------ 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a43f05993687..f3a753096d7d 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -346,9 +346,7 @@ struct ath_vif { int av_bslot; bool is_bslot_active; __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ - enum nl80211_iftype av_opmode; struct ath_buf *av_bcbuf; - u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */ }; /*******************/ diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index f6885278398a..dfd1b98a086b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -323,6 +323,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) if (avp->av_bslot != -1) { sc->beacon.bslot[avp->av_bslot] = NULL; sc->nbcnvifs--; + avp->av_bslot = -1; } bf = avp->av_bcbuf; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 88073f4c2b6a..6f300d7df88e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1450,7 +1450,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ath_vif *avp = (void *)vif->drv_priv; int ret = 0; mutex_lock(&sc->mutex); @@ -1491,10 +1490,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", vif->type); - /* Set the VIF opmode */ - avp->av_opmode = vif->type; - avp->av_bslot = -1; - sc->nvifs++; ath9k_do_vif_add_setup(hw, vif); @@ -1910,7 +1905,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID) { /* Set BSSID */ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN); common->curaid = 0; ath9k_hw_write_associd(ah); -- GitLab From 4f5ef75b155955bf92adc772c6660787151fc78c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Apr 2011 22:56:18 +0530 Subject: [PATCH 0583/5560] ath9k: Handle BSSID/AID for multiple interfaces As of now bssid/aid is overridden with recently changed vif's bss config. This may cause improper beacon updation due to bssid/aid mismatch. On station mode, select an associated sta vif as primary vif and configure that vif's bss into hw. Update the primary vif on interface change and bss info change. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +- drivers/net/wireless/ath/ath9k/main.c | 70 ++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f3a753096d7d..a972396049e5 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -344,7 +344,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid struct ath_vif { int av_bslot; - bool is_bslot_active; + bool is_bslot_active, primary_sta_vif; __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ struct ath_buf *av_bcbuf; }; @@ -546,6 +546,7 @@ struct ath_ant_comb { #define SC_OP_BT_SCAN BIT(13) #define SC_OP_ANI_RUN BIT(14) #define SC_OP_ENABLE_APM BIT(15) +#define SC_OP_PRIM_STA_VIF BIT(16) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6f300d7df88e..3181211ae248 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -841,10 +841,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, "Bss Info ASSOC %d, bssid: %pM\n", bss_conf->aid, common->curbssid); - /* New association, store aid */ - common->curaid = bss_conf->aid; - ath9k_hw_write_associd(ah); - /* * Request a re-configuration of Beacon related timers * on the receipt of the first Beacon frame (i.e., @@ -863,7 +859,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ath_start_ani(common); } else { ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); - common->curaid = 0; /* Stop ANI */ sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); @@ -1886,6 +1881,66 @@ static int ath9k_set_key(struct ieee80211_hw *hw, return ret; } +static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath_softc *sc = data; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ath_vif *avp = (void *)vif->drv_priv; + + switch (sc->sc_ah->opmode) { + case NL80211_IFTYPE_ADHOC: + /* There can be only one vif available */ + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + common->curaid = bss_conf->aid; + ath9k_hw_write_associd(sc->sc_ah); + break; + case NL80211_IFTYPE_STATION: + /* + * Skip iteration if primary station vif's bss info + * was not changed + */ + if (sc->sc_flags & SC_OP_PRIM_STA_VIF) + break; + + if (bss_conf->assoc) { + sc->sc_flags |= SC_OP_PRIM_STA_VIF; + avp->primary_sta_vif = true; + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + common->curaid = bss_conf->aid; + ath9k_hw_write_associd(sc->sc_ah); + } + break; + default: + break; + } +} + +static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ath_vif *avp = (void *)vif->drv_priv; + + /* Reconfigure bss info */ + if (avp->primary_sta_vif && !bss_conf->assoc) { + sc->sc_flags &= ~SC_OP_PRIM_STA_VIF; + avp->primary_sta_vif = false; + memset(common->curbssid, 0, ETH_ALEN); + common->curaid = 0; + } + + ieee80211_iterate_active_interfaces_atomic( + sc->hw, ath9k_bss_iter, sc); + + /* + * None of station vifs are associated. + * Clear bssid & aid + */ + if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && + !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) + ath9k_hw_write_associd(sc->sc_ah); +} static void ath9k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1903,10 +1958,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); if (changed & BSS_CHANGED_BSSID) { - /* Set BSSID */ - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - common->curaid = 0; - ath9k_hw_write_associd(ah); + ath9k_config_bss(sc, vif); /* Set aggregation protection mode parameters */ sc->config.ath_aggr_prot = 0; -- GitLab From 99e4d43ad5ff5778f92ee3bc40a29ac7cd8a28f4 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 4 Apr 2011 22:56:19 +0530 Subject: [PATCH 0584/5560] ath9k: configure beacons based on hw opmode Current ath9k code does not handle beacon timers on opmode specific. One such example is that a STA beacon config overwrites already configured AP vif's beacon timers during scan. On multi station vif case, configure beacon timers beased on primary vif selected. This also helps while moving back to single STA vif from multi STA vifs, where the power save is enabled and hw has to be reconfigured with proper beacon and bssid/aid. Otherwise connection poll will be triggered so frequently due to beacon loss. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/beacon.c | 99 +++++++++++++++++++------ drivers/net/wireless/ath/ath9k/main.c | 84 +++++++-------------- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 4 files changed, 103 insertions(+), 83 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a972396049e5..38835bc324b2 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -397,6 +397,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); int ath_beaconq_config(struct ath_softc *sc); +void ath_set_beacon(struct ath_softc *sc); void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); /*******/ diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index dfd1b98a086b..eccb0ec87adb 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -663,22 +663,63 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, ath9k_hw_set_interrupts(ah, ah->imask); } -void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) +static bool ath9k_allow_beacon_config(struct ath_softc *sc, + struct ieee80211_vif *vif) { struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - enum nl80211_iftype iftype; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ath_vif *avp = (void *)vif->drv_priv; - /* 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; + /* + * Can not have different beacon interval on multiple + * AP interface case + */ + if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && + (sc->nbcnvifs > 1) && + (vif->type == NL80211_IFTYPE_AP) && + (cur_conf->beacon_interval != bss_conf->beacon_int)) { + ath_dbg(common, ATH_DBG_CONFIG, + "Changing beacon interval of multiple \ + AP interfaces !\n"); + return false; + } + /* + * Can not configure station vif's beacon config + * while on AP opmode + */ + if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && + (vif->type != NL80211_IFTYPE_AP)) { + ath_dbg(common, ATH_DBG_CONFIG, + "STA vif's beacon not allowed on AP mode\n"); + return false; + } + /* + * Do not allow beacon config if HW was already configured + * with another STA vif + */ + if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && + (vif->type == NL80211_IFTYPE_STATION) && + (sc->sc_flags & SC_OP_BEACONS) && + !avp->primary_sta_vif) { + ath_dbg(common, ATH_DBG_CONFIG, + "Beacon already configured for a station interface\n"); + return false; } + return true; +} + +void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) +{ + struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + if (!ath9k_allow_beacon_config(sc, vif)) + return; + + /* Setup the beacon configuration parameters */ + cur_conf->beacon_interval = bss_conf->beacon_int; + cur_conf->dtim_period = bss_conf->dtim_period; cur_conf->listen_interval = 1; cur_conf->dtim_count = 1; cur_conf->bmiss_timeout = @@ -701,6 +742,15 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) if (cur_conf->dtim_period == 0) cur_conf->dtim_period = 1; + ath_set_beacon(sc); + sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; +} + +void ath_set_beacon(struct ath_softc *sc) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; + switch (sc->sc_ah->opmode) { case NL80211_IFTYPE_AP: ath_beacon_config_ap(sc, cur_conf); @@ -728,22 +778,23 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) int slot; bool found = false; - ath9k_ps_wakeup(sc); - if (status) { - for (slot = 0; slot < ATH_BCBUF; slot++) { - if (sc->beacon.bslot[slot]) { - avp = (void *)sc->beacon.bslot[slot]->drv_priv; - if (avp->is_bslot_active) { - found = true; - break; - } + for (slot = 0; slot < ATH_BCBUF; slot++) { + if (sc->beacon.bslot[slot]) { + avp = (void *)sc->beacon.bslot[slot]->drv_priv; + if (avp->is_bslot_active) { + found = true; + break; } } - if (found) { - /* Re-enable beaconing */ - ah->imask |= ATH9K_INT_SWBA; - ath9k_hw_set_interrupts(ah, ah->imask); - } + } + if (!found) + return; + + ath9k_ps_wakeup(sc); + if (status) { + /* Re-enable beaconing */ + ah->imask |= ATH9K_INT_SWBA; + ath9k_hw_set_interrupts(ah, ah->imask); } else { /* Disable SWBA interrupt */ ah->imask &= ~ATH9K_INT_SWBA; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3181211ae248..ddd5413c8da8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -299,7 +299,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { if (sc->sc_flags & SC_OP_BEACONS) - ath_beacon_config(sc, NULL); + ath_set_beacon(sc); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); ath_start_ani(common); @@ -828,43 +828,6 @@ irqreturn_t ath_isr(int irq, void *dev) #undef SCHED_INTR } -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_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - - if (bss_conf->assoc) { - ath_dbg(common, ATH_DBG_CONFIG, - "Bss Info ASSOC %d, bssid: %pM\n", - bss_conf->aid, common->curbssid); - - /* - * Request a re-configuration of Beacon related timers - * on the receipt of the first Beacon frame (i.e., - * after time sync with the AP). - */ - sc->ps_flags |= PS_BEACON_SYNC; - - /* Configure the beacon */ - ath_beacon_config(sc, vif); - - /* Reset rssi stats */ - sc->last_rssi = ATH_RSSI_DUMMY_MARKER; - sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; - - sc->sc_flags |= SC_OP_ANI_RUN; - ath_start_ani(common); - } else { - ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); - /* Stop ANI */ - sc->sc_flags &= ~SC_OP_ANI_RUN; - del_timer_sync(&common->ani.timer); - } -} - void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) { struct ath_hw *ah = sc->sc_ah; @@ -894,7 +857,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) goto out; } if (sc->sc_flags & SC_OP_BEACONS) - ath_beacon_config(sc, NULL); /* restart beacons */ + ath_set_beacon(sc); /* restart beacons */ /* Re-Enable interrupts */ ath9k_hw_set_interrupts(ah, ah->imask); @@ -1001,7 +964,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) sc->config.txpowlimit, &sc->curtxpow); if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) - ath_beacon_config(sc, NULL); /* restart beacons */ + ath_set_beacon(sc); /* restart beacons */ ath9k_hw_set_interrupts(ah, ah->imask); @@ -1408,9 +1371,6 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, if ((iter_data.naps + iter_data.nadhocs) > 0) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); - } else { - sc->sc_flags &= ~SC_OP_ANI_RUN; - del_timer_sync(&common->ani.timer); } } @@ -1894,6 +1854,9 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); common->curaid = bss_conf->aid; ath9k_hw_write_associd(sc->sc_ah); + /* configure beacon */ + if (bss_conf->enable_beacon) + ath_beacon_config(sc, vif); break; case NL80211_IFTYPE_STATION: /* @@ -1909,6 +1872,16 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); common->curaid = bss_conf->aid; ath9k_hw_write_associd(sc->sc_ah); + ath_dbg(common, ATH_DBG_CONFIG, + "Bss Info ASSOC %d, bssid: %pM\n", + bss_conf->aid, common->curbssid); + ath_beacon_config(sc, vif); + /* Reset rssi stats */ + sc->last_rssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; + + sc->sc_flags |= SC_OP_ANI_RUN; + ath_start_ani(common); } break; default: @@ -1924,7 +1897,10 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) /* Reconfigure bss info */ if (avp->primary_sta_vif && !bss_conf->assoc) { - sc->sc_flags &= ~SC_OP_PRIM_STA_VIF; + ath_dbg(common, ATH_DBG_CONFIG, + "Bss Info DISASSOC %d, bssid %pM\n", + common->curaid, common->curbssid); + sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); avp->primary_sta_vif = false; memset(common->curbssid, 0, ETH_ALEN); common->curaid = 0; @@ -1938,8 +1914,12 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) * Clear bssid & aid */ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && - !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) + !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { ath9k_hw_write_associd(sc->sc_ah); + /* Stop ANI */ + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); + } } static void ath9k_bss_info_changed(struct ieee80211_hw *hw, @@ -1948,7 +1928,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, u32 changed) { struct ath_softc *sc = hw->priv; - struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_vif *avp = (void *)vif->drv_priv; @@ -1965,9 +1944,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, 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 ; } /* Enable transmission of beacons (AP, IBSS, MESH) */ @@ -2008,7 +1984,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { - cur_conf->beacon_interval = bss_conf->beacon_int; /* * In case of AP mode, the HW TSF has to be reset * when the beacon interval changes. @@ -2020,9 +1995,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (!error) ath_beacon_config(sc, vif); ath9k_set_beaconing_status(sc, true); - } else { + } else ath_beacon_config(sc, vif); - } } if (changed & BSS_CHANGED_ERP_PREAMBLE) { @@ -2044,12 +2018,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; } - if (changed & BSS_CHANGED_ASSOC) { - ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", - bss_conf->assoc); - 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 a9c3f4672aa0..3842b7518661 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -574,7 +574,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) sc->ps_flags &= ~PS_BEACON_SYNC; ath_dbg(common, ATH_DBG_PS, "Reconfigure Beacon timers based on timestamp from the AP\n"); - ath_beacon_config(sc, NULL); + ath_set_beacon(sc); } if (ath_beacon_dtim_pending_cab(skb)) { -- GitLab From 0321708748d8f2ecfffa4a9feafb332312e4e57f Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Tue, 5 Apr 2011 14:18:09 +0530 Subject: [PATCH 0585/5560] mwl8k: Do not configure tx power unconditionally Instead of configuring tx power unconditionally, check for IEEE80211_CONF_CHANGE_POWER and configure it only when stack sets this flag Signed-off-by: Nishant Sarmukadam Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index ae56d2f32b2e..d5e047970345 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -4463,9 +4463,12 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) conf->power_level = 18; if (priv->ap_fw) { - rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); - if (rc) - goto out; + + if (conf->flags & IEEE80211_CONF_CHANGE_POWER) { + rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); + if (rc) + goto out; + } rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3); if (rc) -- GitLab From cebb28ba1ebb00edee4606547d81acf8db0f0532 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 5 Apr 2011 16:59:06 +0200 Subject: [PATCH 0586/5560] rt2x00: Drop __TIME__ usage The kernel already prints its build timestamp during boot, no need to repeat it in random drivers and produce different object files each time. Signed-off-by: Michal Marek Acked-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00debug.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index c92db3264741..66166ef037f5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -568,7 +568,6 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, blob->data = data; data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name); data += sprintf(data, "version:\t%s\n", DRV_VERSION); - data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__); blob->size = strlen(blob->data); return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); -- GitLab From 68e022dfeb548b48635888d1392f983977293573 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:48 -0700 Subject: [PATCH 0587/5560] iwlagn: remove unused variable Some code was removed, but a variable it used and that is now unused stayed around, kill it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sta.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index b0dcca07ff45..6ded0174a609 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -233,7 +233,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_station_entry *station; int i; u8 sta_id = IWL_INVALID_STATION; - u16 rate; if (is_ap) sta_id = ctx->ap_sta_id; -- GitLab From 3240cab3ddfb2637cfca3a078078cdeda44d0a99 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:49 -0700 Subject: [PATCH 0588/5560] iwlagn: clean up some 3945/4965 remnants When the driver was split, a bunch of definitions for the 3945 and 4965 devices stayed around, but they're now useless so remove (some of) them. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 28 - drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 - drivers/net/wireless/iwlwifi/iwl-commands.h | 591 +------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 235 ++------ drivers/net/wireless/iwlwifi/iwl-eeprom.h | 185 ------ drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 - drivers/net/wireless/iwlwifi/iwl-prph.h | 11 - 9 files changed, 63 insertions(+), 994 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 184828c72b31..b356a39a824f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -41,20 +41,6 @@ struct iwl_rate_info { u8 next_rs_tgg; /* next rate used in TGG rs algo */ }; -struct iwl3945_rate_info { - u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ - u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ - u8 prev_ieee; /* previous rate in IEEE speeds */ - u8 next_ieee; /* next rate in IEEE speeds */ - u8 prev_rs; /* previous rate used in rs algo */ - u8 next_rs; /* next rate used in rs algo */ - u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ - u8 next_rs_tgg; /* next rate used in TGG rs algo */ - u8 table_rs_index; /* index in rate scale table cmd */ - u8 prev_table_rs; /* prev in rate table cmd */ -}; - - /* * These serve as indexes into * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; @@ -75,7 +61,6 @@ enum { IWL_RATE_60M_INDEX, IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/ IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */ - IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1, IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, IWL_RATE_INVALID = IWL_RATE_COUNT, }; @@ -213,7 +198,6 @@ enum { IWL_CCK_BASIC_RATES_MASK) #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) -#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1) #define IWL_INVALID_VALUE -1 @@ -453,19 +437,9 @@ static inline u8 first_antenna(u8 mask) } -/** - * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info - * - * The specific throughput table used is based on the type of network - * the associated with, including A, B, G, and G w/ TGG protection - */ -extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); - /* Initialize station's rate scaling information after adding station */ extern void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id); -extern void iwl3945_rs_rate_init(struct iwl_priv *priv, - struct ieee80211_sta *sta, u8 sta_id); /** * iwl_rate_control_register - Register the rate control algorithm callbacks @@ -478,7 +452,6 @@ extern void iwl3945_rs_rate_init(struct iwl_priv *priv, * */ extern int iwlagn_rate_control_register(void); -extern int iwl3945_rate_control_register(void); /** * iwl_rate_control_unregister - Unregister the rate control callbacks @@ -487,6 +460,5 @@ extern int iwl3945_rate_control_register(void); * the driver is unloaded. */ extern void iwlagn_rate_control_unregister(void); -extern void iwl3945_rate_control_unregister(void); #endif /* __iwl_agn__rs__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 35f085ac336b..3782fe8194fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -474,7 +474,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); memset(&priv->stations[sta_id].sta.key, 0, - sizeof(struct iwl4965_keyinfo)); + sizeof(struct iwl_keyinfo)); priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 39313acb9cc7..80de8a1edacf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -66,7 +66,6 @@ #include "iwl-dev.h" /* configuration for the _agn devices */ -extern struct iwl_cfg iwl4965_agn_cfg; extern struct iwl_cfg iwl5300_agn_cfg; extern struct iwl_cfg iwl5100_agn_cfg; extern struct iwl_cfg iwl5350_agn_cfg; @@ -114,7 +113,6 @@ 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); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index cc2151482f31..e6058436aeb3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -103,9 +103,7 @@ enum { REPLY_WEPKEY = 0x20, /* RX, TX, LEDs */ - REPLY_3945_RX = 0x1b, /* 3945 only */ REPLY_TX = 0x1c, - REPLY_RATE_SCALE = 0x47, /* 3945 only */ REPLY_LEDS_CMD = 0x48, REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */ @@ -229,7 +227,7 @@ struct iwl_cmd_header { * There is one exception: uCode sets bit 15 when it originates * the response/notification, i.e. when the response/notification * is not a direct response to a command sent by the driver. For - * example, uCode issues REPLY_3945_RX when it sends a received frame + * example, uCode issues REPLY_RX when it sends a received frame * to the driver; it is not a direct response to any driver command. * * The Linux driver uses the following format: @@ -248,36 +246,6 @@ struct iwl_cmd_header { } __packed; -/** - * struct iwl3945_tx_power - * - * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH - * - * Each entry contains two values: - * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained - * linear value that multiplies the output of the digital signal processor, - * before being sent to the analog radio. - * 2) Radio gain. This sets the analog gain of the radio Tx path. - * It is a coarser setting, and behaves in a logarithmic (dB) fashion. - * - * Driver obtains values from struct iwl3945_tx_power power_gain_table[][]. - */ -struct iwl3945_tx_power { - u8 tx_gain; /* gain for analog radio */ - u8 dsp_atten; /* gain for DSP */ -} __packed; - -/** - * struct iwl3945_power_per_rate - * - * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH - */ -struct iwl3945_power_per_rate { - u8 rate; /* plcp */ - struct iwl3945_tx_power tpc; - u8 reserved; -} __packed; - /** * iwlagn rate_n_flags bit fields * @@ -376,30 +344,6 @@ struct iwl3945_power_per_rate { #define IWL_PWR_NUM_HT_OFDM_ENTRIES 24 #define IWL_PWR_CCK_ENTRIES 2 -/** - * union iwl4965_tx_power_dual_stream - * - * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH - * Use __le32 version (struct tx_power_dual_stream) when building command. - * - * Driver provides radio gain and DSP attenuation settings to device in pairs, - * one value for each transmitter chain. The first value is for transmitter A, - * second for transmitter B. - * - * For SISO bit rates, both values in a pair should be identical. - * For MIMO rates, one value may be different from the other, - * in order to balance the Tx output between the two transmitters. - * - * See more details in doc for TXPOWER in iwl-4965-hw.h. - */ -union iwl4965_tx_power_dual_stream { - struct { - u8 radio_tx_gain[2]; - u8 dsp_predis_atten[2]; - } s; - u32 dw; -}; - /** * struct tx_power_dual_stream * @@ -411,15 +355,6 @@ struct tx_power_dual_stream { __le32 dw; } __packed; -/** - * struct iwl4965_tx_power_db - * - * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH - */ -struct iwl4965_tx_power_db { - struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; -} __packed; - /** * Command REPLY_TX_POWER_DBM_CMD = 0x98 * struct iwlagn_tx_power_dbm_cmd @@ -724,46 +659,6 @@ enum { * regardless of whether RXON_FILTER_ASSOC_MSK is set. */ -struct iwl3945_rxon_cmd { - u8 node_addr[6]; - __le16 reserved1; - u8 bssid_addr[6]; - __le16 reserved2; - u8 wlap_bssid_addr[6]; - __le16 reserved3; - u8 dev_type; - u8 air_propagation; - __le16 reserved4; - u8 ofdm_basic_rates; - u8 cck_basic_rates; - __le16 assoc_id; - __le32 flags; - __le32 filter_flags; - __le16 channel; - __le16 reserved5; -} __packed; - -struct iwl4965_rxon_cmd { - u8 node_addr[6]; - __le16 reserved1; - u8 bssid_addr[6]; - __le16 reserved2; - u8 wlap_bssid_addr[6]; - __le16 reserved3; - u8 dev_type; - u8 air_propagation; - __le16 rx_chain; - u8 ofdm_basic_rates; - u8 cck_basic_rates; - __le16 assoc_id; - __le32 flags; - __le32 filter_flags; - __le16 channel; - u8 ofdm_ht_single_stream_basic_rates; - u8 ofdm_ht_dual_stream_basic_rates; -} __packed; - -/* 5000 HW just extend this command */ struct iwl_rxon_cmd { u8 node_addr[6]; __le16 reserved1; @@ -791,25 +686,6 @@ struct iwl_rxon_cmd { /* * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) */ -struct iwl3945_rxon_assoc_cmd { - __le32 flags; - __le32 filter_flags; - u8 ofdm_basic_rates; - u8 cck_basic_rates; - __le16 reserved; -} __packed; - -struct iwl4965_rxon_assoc_cmd { - __le32 flags; - __le32 filter_flags; - u8 ofdm_basic_rates; - u8 cck_basic_rates; - u8 ofdm_ht_single_stream_basic_rates; - u8 ofdm_ht_dual_stream_basic_rates; - __le16 rx_chain_select_flags; - __le16 reserved; -} __packed; - struct iwl5000_rxon_assoc_cmd { __le32 flags; __le32 filter_flags; @@ -845,26 +721,6 @@ struct iwl_rxon_time_cmd { /* * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) */ -struct iwl3945_channel_switch_cmd { - u8 band; - u8 expect_beacon; - __le16 channel; - __le32 rxon_flags; - __le32 rxon_filter_flags; - __le32 switch_time; - struct iwl3945_power_per_rate power[IWL_MAX_RATES]; -} __packed; - -struct iwl4965_channel_switch_cmd { - u8 band; - u8 expect_beacon; - __le16 channel; - __le32 rxon_flags; - __le32 rxon_filter_flags; - __le32 switch_time; - struct iwl4965_tx_power_db tx_power; -} __packed; - /** * struct iwl5000_channel_switch_cmd * @band: 0- 5.2GHz, 1- 2.4GHz @@ -978,15 +834,10 @@ struct iwl_qosparam_cmd { #define IWL_AP_ID 0 #define IWL_AP_ID_PAN 1 #define IWL_STA_ID 2 -#define IWL3945_BROADCAST_ID 24 -#define IWL3945_STATION_COUNT 25 -#define IWL4965_BROADCAST_ID 31 -#define IWL4965_STATION_COUNT 32 #define IWLAGN_PAN_BCAST_ID 14 #define IWLAGN_BROADCAST_ID 15 #define IWLAGN_STATION_COUNT 16 -#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ #define IWL_INVALID_STATION 255 #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) @@ -1034,16 +885,6 @@ struct iwl_qosparam_cmd { * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) -struct iwl4965_keyinfo { - __le16 key_flags; - u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ - u8 reserved1; - __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ - u8 key_offset; - u8 reserved2; - u8 key[16]; /* 16-byte unicast decryption key */ -} __packed; - /* agn */ struct iwl_keyinfo { __le16 key_flags; @@ -1085,7 +926,6 @@ struct sta_id_modify { * with info on security keys, aggregation parameters, and Tx rates for * initial Tx attempt and any retries (agn devices uses * REPLY_TX_LINK_QUALITY_CMD, - * 3945 uses REPLY_RATE_SCALE to set up rate tables). * * REPLY_ADD_STA sets up the table entry for one station, either creating * a new entry, or modifying a pre-existing one. @@ -1105,72 +945,6 @@ struct sta_id_modify { * entries for all STAs in network, starting with index IWL_STA_ID. */ -struct iwl3945_addsta_cmd { - u8 mode; /* 1: modify existing, 0: add new station */ - u8 reserved[3]; - struct sta_id_modify sta; - struct iwl4965_keyinfo key; - __le32 station_flags; /* STA_FLG_* */ - __le32 station_flags_msk; /* STA_FLG_* */ - - /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) - * corresponding to bit (e.g. bit 5 controls TID 5). - * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ - __le16 tid_disable_tx; - - __le16 rate_n_flags; - - /* TID for which to add block-ack support. - * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ - u8 add_immediate_ba_tid; - - /* TID for which to remove block-ack support. - * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ - u8 remove_immediate_ba_tid; - - /* Starting Sequence Number for added block-ack support. - * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ - __le16 add_immediate_ba_ssn; -} __packed; - -struct iwl4965_addsta_cmd { - u8 mode; /* 1: modify existing, 0: add new station */ - u8 reserved[3]; - struct sta_id_modify sta; - struct iwl4965_keyinfo key; - __le32 station_flags; /* STA_FLG_* */ - __le32 station_flags_msk; /* STA_FLG_* */ - - /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) - * corresponding to bit (e.g. bit 5 controls TID 5). - * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ - __le16 tid_disable_tx; - - __le16 reserved1; - - /* TID for which to add block-ack support. - * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ - u8 add_immediate_ba_tid; - - /* TID for which to remove block-ack support. - * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ - u8 remove_immediate_ba_tid; - - /* Starting Sequence Number for added block-ack support. - * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ - __le16 add_immediate_ba_ssn; - - /* - * Number of packets OK to transmit to station even though - * it is asleep -- used to synchronise PS-poll and u-APSD - * responses while ucode keeps track of STA sleep state. - */ - __le16 sleep_tx_count; - - __le16 reserved2; -} __packed; - -/* agn */ struct iwl_addsta_cmd { u8 mode; /* 1: modify existing, 0: add new station */ u8 reserved[3]; @@ -1339,62 +1113,6 @@ struct iwl_wep_cmd { #define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) -struct iwl3945_rx_frame_stats { - u8 phy_count; - u8 id; - u8 rssi; - u8 agc; - __le16 sig_avg; - __le16 noise_diff; - u8 payload[0]; -} __packed; - -struct iwl3945_rx_frame_hdr { - __le16 channel; - __le16 phy_flags; - u8 reserved1; - u8 rate; - __le16 len; - u8 payload[0]; -} __packed; - -struct iwl3945_rx_frame_end { - __le32 status; - __le64 timestamp; - __le32 beacon_timestamp; -} __packed; - -/* - * REPLY_3945_RX = 0x1b (response only, not a command) - * - * NOTE: DO NOT dereference from casts to this structure - * It is provided only for calculating minimum data set size. - * The actual offsets of the hdr and end are dynamic based on - * stats.phy_count - */ -struct iwl3945_rx_frame { - struct iwl3945_rx_frame_stats stats; - struct iwl3945_rx_frame_hdr hdr; - struct iwl3945_rx_frame_end end; -} __packed; - -#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame)) - -/* Fixed (non-configurable) rx data from phy */ - -#define IWL49_RX_RES_PHY_CNT 14 -#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4) -#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70) -#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ -#define IWL49_AGC_DB_POS (7) -struct iwl4965_rx_non_cfg_phy { - __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ - __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ - u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */ - u8 pad[0]; -} __packed; - - #define IWLAGN_RX_RES_PHY_CNT 8 #define IWLAGN_RX_RES_AGC_IDX 1 #define IWLAGN_RX_RES_RSSI_AB_IDX 2 @@ -1578,80 +1296,6 @@ struct iwl_rx_mpdu_res_start { * REPLY_TX = 0x1c (command) */ -struct iwl3945_tx_cmd { - /* - * MPDU byte count: - * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, - * + 8 byte IV for CCM or TKIP (not used for WEP) - * + Data payload - * + 8-byte MIC (not used for CCM/WEP) - * NOTE: Does not include Tx command bytes, post-MAC pad bytes, - * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i - * Range: 14-2342 bytes. - */ - __le16 len; - - /* - * MPDU or MSDU byte count for next frame. - * Used for fragmentation and bursting, but not 11n aggregation. - * Same as "len", but for next frame. Set to 0 if not applicable. - */ - __le16 next_frame_len; - - __le32 tx_flags; /* TX_CMD_FLG_* */ - - u8 rate; - - /* Index of recipient station in uCode's station table */ - u8 sta_id; - u8 tid_tspec; - u8 sec_ctl; - u8 key[16]; - union { - u8 byte[8]; - __le16 word[4]; - __le32 dw[2]; - } tkip_mic; - __le32 next_frame_info; - union { - __le32 life_time; - __le32 attempt; - } stop_time; - u8 supp_rates[2]; - u8 rts_retry_limit; /*byte 50 */ - u8 data_retry_limit; /*byte 51 */ - union { - __le16 pm_frame_timeout; - __le16 attempt_duration; - } timeout; - - /* - * Duration of EDCA burst Tx Opportunity, in 32-usec units. - * Set this if txop time is not specified by HCCA protocol (e.g. by AP). - */ - __le16 driver_txop; - - /* - * MAC header goes here, followed by 2 bytes padding if MAC header - * length is 26 or 30 bytes, followed by payload data - */ - u8 payload[0]; - struct ieee80211_hdr hdr[0]; -} __packed; - -/* - * REPLY_TX = 0x1c (response) - */ -struct iwl3945_tx_resp { - u8 failure_rts; - u8 failure_frame; - u8 bt_kill_count; - u8 rate; - __le32 wireless_media_time; - __le32 status; /* TX status */ -} __packed; - - /* * 4965 uCode updates these Tx attempt count values in host DRAM. * Used for managing Tx retries when expecting block-acks. @@ -1742,54 +1386,6 @@ struct iwl_tx_cmd { struct ieee80211_hdr hdr[0]; } __packed; -/* TX command response is sent after *3945* transmission attempts. - * - * NOTES: - * - * TX_STATUS_FAIL_NEXT_FRAG - * - * If the fragment flag in the MAC header for the frame being transmitted - * is set and there is insufficient time to transmit the next frame, the - * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'. - * - * TX_STATUS_FIFO_UNDERRUN - * - * Indicates the host did not provide bytes to the FIFO fast enough while - * a TX was in progress. - * - * TX_STATUS_FAIL_MGMNT_ABORT - * - * This status is only possible if the ABORT ON MGMT RX parameter was - * set to true with the TX command. - * - * If the MSB of the status parameter is set then an abort sequence is - * required. This sequence consists of the host activating the TX Abort - * control line, and then waiting for the TX Abort command response. This - * indicates that a the device is no longer in a transmit state, and that the - * command FIFO has been cleared. The host must then deactivate the TX Abort - * control line. Receiving is still allowed in this case. - */ -enum { - TX_3945_STATUS_SUCCESS = 0x01, - TX_3945_STATUS_DIRECT_DONE = 0x02, - TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82, - TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83, - TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84, - TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85, - TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86, - TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87, - TX_3945_STATUS_FAIL_DEST_PS = 0x88, - TX_3945_STATUS_FAIL_ABORTED = 0x89, - TX_3945_STATUS_FAIL_BT_RETRY = 0x8a, - TX_3945_STATUS_FAIL_STA_INVALID = 0x8b, - TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c, - TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d, - TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e, - TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, - TX_3945_STATUS_FAIL_TX_LOCKED = 0x90, - TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, -}; - /* * TX command response is sent after *agn* transmission attempts. * @@ -1907,43 +1503,6 @@ struct agg_tx_status { __le16 sequence; } __packed; -struct iwl4965_tx_resp { - u8 frame_count; /* 1 no aggregation, >1 aggregation */ - u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ - u8 failure_rts; /* # failures due to unsuccessful RTS */ - u8 failure_frame; /* # failures due to no ACK (unused for agg) */ - - /* For non-agg: Rate at which frame was successful. - * For agg: Rate at which all frames were transmitted. */ - __le32 rate_n_flags; /* RATE_MCS_* */ - - /* For non-agg: RTS + CTS + frame tx attempts time + ACK. - * For agg: RTS + CTS + aggregation tx time + block-ack time. */ - __le16 wireless_media_time; /* uSecs */ - - __le16 reserved; - __le32 pa_power1; /* RF power amplifier measurement (not used) */ - __le32 pa_power2; - - /* - * For non-agg: frame status TX_STATUS_* - * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status - * fields follow this one, up to frame_count. - * Bit fields: - * 11- 0: AGG_TX_STATE_* status code - * 15-12: Retry count for 1st frame in aggregation (retries - * occur if tx failed for this frame when it was a - * member of a previous aggregation block). If rate - * scaling is used, retry count indicates the rate - * table entry used for all frames in the new agg. - * 31-16: Sequence # for this frame's Tx cmd (not SSN!) - */ - union { - __le32 status; - struct agg_tx_status agg_status[0]; /* for each agg frame */ - } u; -} __packed; - /* * definitions for initial rate index field * bits [3:0] initial rate index @@ -2032,52 +1591,8 @@ struct iwl_compressed_ba_resp { /* * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) * - * See details under "TXPOWER" in iwl-4965-hw.h. */ -struct iwl3945_txpowertable_cmd { - u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ - u8 reserved; - __le16 channel; - struct iwl3945_power_per_rate power[IWL_MAX_RATES]; -} __packed; - -struct iwl4965_txpowertable_cmd { - u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ - u8 reserved; - __le16 channel; - struct iwl4965_tx_power_db tx_power; -} __packed; - - -/** - * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response - * - * REPLY_RATE_SCALE = 0x47 (command, has simple generic response) - * - * NOTE: The table of rates passed to the uCode via the - * RATE_SCALE command sets up the corresponding order of - * rates used for all related commands, including rate - * masks, etc. - * - * For example, if you set 9MB (PLCP 0x0f) as the first - * rate in the rate table, the bit mask for that rate - * when passed through ofdm_basic_rates on the REPLY_RXON - * command would be bit 0 (1 << 0) - */ -struct iwl3945_rate_scaling_info { - __le16 rate_n_flags; - u8 try_cnt; - u8 next_rate_index; -} __packed; - -struct iwl3945_rate_scaling_cmd { - u8 table_id; - u8 reserved[3]; - struct iwl3945_rate_scaling_info table[IWL_MAX_RATES]; -} __packed; - - /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ #define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) @@ -2698,14 +2213,6 @@ struct iwl_spectrum_notification { #define IWL_POWER_BT_SCO_ENA cpu_to_le16(BIT(8)) #define IWL_POWER_ADVANCE_PM_ENA_MSK cpu_to_le16(BIT(9)) -struct iwl3945_powertable_cmd { - __le16 flags; - u8 reserved[2]; - __le32 rx_data_timeout; - __le32 tx_data_timeout; - __le32 sleep_interval[IWL_POWER_VEC_SIZE]; -} __packed; - struct iwl_powertable_cmd { __le16 flags; u8 keep_alive_seconds; /* 3945 reserved */ @@ -2808,25 +2315,6 @@ struct iwl_ct_kill_throttling_config { * active_dwell < max_out_time */ -/* FIXME: rename to AP1, remove tpc */ -struct iwl3945_scan_channel { - /* - * type is defined as: - * 0:0 1 = active, 0 = passive - * 1:4 SSID direct bit map; if a bit is set, then corresponding - * SSID IE is transmitted in probe request. - * 5:7 reserved - */ - u8 type; - u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */ - struct iwl3945_tx_power tpc; - __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ - __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ -} __packed; - -/* set number of direct probes u8 type */ -#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1)))) - struct iwl_scan_channel { /* * type is defined as: @@ -2922,50 +2410,6 @@ struct iwl_ssid_ie { * struct iwl_scan_channel. */ -struct iwl3945_scan_cmd { - __le16 len; - u8 reserved0; - u8 channel_count; /* # channels in channel list */ - __le16 quiet_time; /* dwell only this # millisecs on quiet channel - * (only for active scan) */ - __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ - __le16 good_CRC_th; /* passive -> active promotion threshold */ - __le16 reserved1; - __le32 max_out_time; /* max usec to be away from associated (service) - * channel */ - __le32 suspend_time; /* pause scan this long (in "extended beacon - * format") when returning to service channel: - * 3945; 31:24 # beacons, 19:0 additional usec, - * 4965; 31:22 # beacons, 21:0 additional usec. - */ - __le32 flags; /* RXON_FLG_* */ - __le32 filter_flags; /* RXON_FILTER_* */ - - /* For active scans (set to all-0s for passive scans). - * Does not include payload. Must specify Tx rate; no rate scaling. */ - struct iwl3945_tx_cmd tx_cmd; - - /* For directed active scans (set to all-0s otherwise) */ - struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945]; - - /* - * Probe request frame, followed by channel list. - * - * Size of probe request frame is specified by byte count in tx_cmd. - * Channel list follows immediately after probe request frame. - * Number of channels in list is specified by channel_count. - * Each channel in list is of type: - * - * struct iwl3945_scan_channel channels[0]; - * - * NOTE: Only one band of channels can be scanned per pass. You - * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait - * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) - * before requesting another scan. - */ - u8 data[0]; -} __packed; - enum iwl_scan_flags { /* BIT(0) currently unused */ IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1), @@ -3092,20 +2536,6 @@ enum iwl_ibss_manager { * BEACON_NOTIFICATION = 0x90 (notification only, not a command) */ -struct iwl3945_beacon_notif { - struct iwl3945_tx_resp beacon_notify_hdr; - __le32 low_tsf; - __le32 high_tsf; - __le32 ibss_mgr_status; -} __packed; - -struct iwl4965_beacon_notif { - struct iwl4965_tx_resp beacon_notify_hdr; - __le32 low_tsf; - __le32 high_tsf; - __le32 ibss_mgr_status; -} __packed; - struct iwlagn_beacon_notif { struct iwlagn_tx_resp beacon_notify_hdr; __le32 low_tsf; @@ -3117,14 +2547,6 @@ struct iwlagn_beacon_notif { * REPLY_TX_BEACON = 0x91 (command, has simple generic response) */ -struct iwl3945_tx_beacon_cmd { - struct iwl3945_tx_cmd tx; - __le16 tim_idx; - u8 tim_size; - u8 reserved1; - struct ieee80211_hdr frame[0]; /* beacon frame */ -} __packed; - struct iwl_tx_beacon_cmd { struct iwl_tx_cmd tx; __le16 tim_idx; @@ -3473,13 +2895,6 @@ struct iwl_statistics_cmd { #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) #define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8) -struct iwl3945_notif_statistics { - __le32 flag; - struct iwl39_statistics_rx rx; - struct iwl39_statistics_tx tx; - struct iwl39_statistics_general general; -} __packed; - struct iwl_notif_statistics { __le32 flag; struct statistics_rx rx; @@ -4453,10 +3868,6 @@ struct iwl_rx_packet { __le32 len_n_flags; struct iwl_cmd_header hdr; union { - struct iwl3945_rx_frame rx_frame; - struct iwl3945_tx_resp tx_resp; - struct iwl3945_beacon_notif beacon_status; - struct iwl_alive_resp alive_frame; struct iwl_spectrum_notification spectrum_notif; struct iwl_csa_notification csa_notif; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6c30fa652e27..d778f52132cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1430,7 +1430,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, iwl_teardown_interface(priv, vif, false); - memset(priv->bssid, 0, ETH_ALEN); mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1c9d2dd37cca..8dc209a341aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -26,7 +26,6 @@ /* * Please use this file (iwl-dev.h) for driver implementation definitions. * Please use iwl-commands.h for uCode API definitions. - * Please use iwl-4965-hw.h for hardware-related definitions. */ #ifndef __iwl_dev_h__ @@ -179,53 +178,12 @@ struct iwl_tx_queue { #define IWL_NUM_SCAN_RATES (2) -struct iwl4965_channel_tgd_info { - u8 type; - s8 max_power; -}; - -struct iwl4965_channel_tgh_info { - s64 last_radar_time; -}; - -#define IWL4965_MAX_RATE (33) - -struct iwl3945_clip_group { - /* maximum power level to prevent clipping for each rate, derived by - * us from this band's saturation power in EEPROM */ - const s8 clip_powers[IWL_MAX_RATES]; -}; - -/* current Tx power values to use, one for each rate for each channel. - * requested power is limited by: - * -- regulatory EEPROM limits for this channel - * -- hardware capabilities (clip-powers) - * -- spectrum management - * -- user preference (e.g. iwconfig) - * when requested power is set, base power index must also be set. */ -struct iwl3945_channel_power_info { - struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ - s8 power_table_index; /* actual (compenst'd) index into gain table */ - s8 base_power_index; /* gain index for power at factory temp. */ - s8 requested_power; /* power (dBm) requested for this chnl/rate */ -}; - -/* current scan Tx power values to use, one for each scan rate for each - * channel. */ -struct iwl3945_scan_power_info { - struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ - s8 power_table_index; /* actual (compenst'd) index into gain table */ - s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ -}; - /* * One for each channel, holds all channel setup data * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant * with one another! */ struct iwl_channel_info { - struct iwl4965_channel_tgd_info tgd; - struct iwl4965_channel_tgh_info tgh; struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for * HT40 channel */ @@ -245,14 +203,6 @@ struct iwl_channel_info { s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ u8 ht40_flags; /* flags copied from EEPROM */ u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ - - /* Radio/DSP gain settings for each "normal" data Tx rate. - * These include, in addition to RF and DSP gain, a few fields for - * remembering/modifying gain settings (indexes). */ - struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE]; - - /* Radio/DSP gain settings for each scan rate, for directed scans. */ - struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; }; #define IWL_TX_FIFO_BK 0 /* shared */ @@ -501,9 +451,6 @@ struct iwl_station_priv_common { * When mac80211 creates a station it reserves some space (hw->sta_data_size) * in the structure for use by driver. This structure is places in that * space. - * - * The common struct MUST be first because it is shared between - * 3945 and agn! */ struct iwl_station_priv { struct iwl_station_priv_common common; @@ -621,14 +568,6 @@ struct iwl_tlv_ucode_header { u8 data[0]; }; -struct iwl4965_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num; - u16 frag_num; - unsigned long packet_time; - struct list_head list; -}; - struct iwl_sensitivity_ranges { u16 min_nrg_cck; u16 max_nrg_cck; @@ -724,8 +663,6 @@ struct iwl_hw_params { * Naming convention -- * iwl_ <-- Is part of iwlwifi * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) - * iwl4965_bg_ <-- Called from work queue context - * iwl4965_mac_ <-- mac80211 callback * ****************************************************************************/ extern void iwl_update_chain_flags(struct iwl_priv *priv); @@ -774,7 +711,6 @@ struct iwl_dma_ptr { /* Sensitivity and chain noise calibration */ #define INITIALIZATION_VALUE 0xFFFF -#define IWL4965_CAL_NUM_BEACONS 20 #define IWL_CAL_NUM_BEACONS 16 #define MAXIMUM_ALLOWED_PATHLOSS 15 @@ -808,24 +744,19 @@ struct iwl_dma_ptr { #define NRG_NUM_PREV_STAT_L 20 #define NUM_RX_CHAINS 3 -enum iwl4965_false_alarm_state { +enum iwlagn_false_alarm_state { IWL_FA_TOO_MANY = 0, IWL_FA_TOO_FEW = 1, IWL_FA_GOOD_RANGE = 2, }; -enum iwl4965_chain_noise_state { +enum iwlagn_chain_noise_state { IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ IWL_CHAIN_NOISE_ACCUMULATE, IWL_CHAIN_NOISE_CALIBRATED, IWL_CHAIN_NOISE_DONE, }; -enum iwl4965_calib_enabled_state { - IWL_CALIB_DISABLED = 0, /* must be 0 */ - IWL_CALIB_ENABLED = 1, -}; - /* * enum iwl_calib @@ -1132,12 +1063,6 @@ struct iwl_force_reset { }; /* extend beacon time format bit shifting */ -/* - * for _3945 devices - * bits 31:24 - extended - * bits 23:0 - interval - */ -#define IWL3945_EXT_BEACON_TIME_POS 24 /* * for _agn devices * bits 31:22 - extended @@ -1391,15 +1316,12 @@ struct iwl_priv { struct iwl_power_mgr power_data; struct iwl_tt_mgmt thermal_throttle; - /* context information */ - u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ - /* station table variables */ /* Note: if lock and sta_lock are needed, lock must be acquired first */ spinlock_t sta_lock; int num_stations; - struct iwl_station_entry stations[IWL_STATION_COUNT]; + struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; unsigned long ucode_key_table; /* queue refcounts */ @@ -1423,101 +1345,66 @@ struct iwl_priv { /* Last Rx'd beacon timestamp */ u64 timestamp; - union { -#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) - struct { - void *shared_virt; - dma_addr_t shared_phys; - - struct delayed_work thermal_periodic; - struct delayed_work rfkill_poll; - - struct iwl3945_notif_statistics statistics; -#ifdef CONFIG_IWLWIFI_DEBUGFS - struct iwl3945_notif_statistics accum_statistics; - struct iwl3945_notif_statistics delta_statistics; - struct iwl3945_notif_statistics max_delta; -#endif - - u32 sta_supp_rates; - int last_rx_rssi; /* From Rx packet statistics */ - - /* Rx'd packet timing information */ - u32 last_beacon_time; - u64 last_tsf; - - /* - * each calibration channel group in the - * EEPROM has a derived clip setting for - * each rate. - */ - const struct iwl3945_clip_group clip_groups[5]; - - } _3945; -#endif -#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE) - struct { - /* INT ICT Table */ - __le32 *ict_tbl; - void *ict_tbl_vir; - dma_addr_t ict_tbl_dma; - dma_addr_t aligned_ict_tbl_dma; - int ict_index; - u32 inta; - bool use_ict; - /* - * reporting the number of tids has AGG on. 0 means - * no AGGREGATION - */ - u8 agg_tids_count; - - struct iwl_rx_phy_res last_phy_res; - bool last_phy_res_valid; - - struct completion firmware_loading_complete; - - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; - - /* - * chain noise reset and gain commands are the - * two extra calibration commands follows the standard - * phy calibration commands - */ - u8 phy_calib_chain_noise_reset_cmd; - u8 phy_calib_chain_noise_gain_cmd; - - struct iwl_notif_statistics statistics; - struct iwl_bt_notif_statistics statistics_bt; - /* counts reply_tx error */ - struct reply_tx_error_statistics reply_tx_stats; - struct reply_agg_tx_error_statistics reply_agg_tx_stats; + struct { + /* INT ICT Table */ + __le32 *ict_tbl; + void *ict_tbl_vir; + dma_addr_t ict_tbl_dma; + dma_addr_t aligned_ict_tbl_dma; + int ict_index; + u32 inta; + bool use_ict; + /* + * reporting the number of tids has AGG on. 0 means + * no AGGREGATION + */ + u8 agg_tids_count; + + struct iwl_rx_phy_res last_phy_res; + bool last_phy_res_valid; + + struct completion firmware_loading_complete; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; + + /* + * chain noise reset and gain commands are the + * two extra calibration commands follows the standard + * phy calibration commands + */ + u8 phy_calib_chain_noise_reset_cmd; + u8 phy_calib_chain_noise_gain_cmd; + + struct iwl_notif_statistics statistics; + struct iwl_bt_notif_statistics statistics_bt; + /* counts reply_tx error */ + struct reply_tx_error_statistics reply_tx_stats; + struct reply_agg_tx_error_statistics reply_agg_tx_stats; #ifdef CONFIG_IWLWIFI_DEBUGFS - struct iwl_notif_statistics accum_statistics; - struct iwl_notif_statistics delta_statistics; - struct iwl_notif_statistics max_delta; - struct iwl_bt_notif_statistics accum_statistics_bt; - struct iwl_bt_notif_statistics delta_statistics_bt; - struct iwl_bt_notif_statistics max_delta_bt; -#endif - - /* notification wait support */ - struct list_head notif_waits; - spinlock_t notif_wait_lock; - wait_queue_head_t notif_waitq; - - /* remain-on-channel offload support */ - struct ieee80211_channel *hw_roc_channel; - struct delayed_work hw_roc_work; - enum nl80211_channel_type hw_roc_chantype; - int hw_roc_duration; - - struct sk_buff *offchan_tx_skb; - int offchan_tx_timeout; - struct ieee80211_channel *offchan_tx_chan; - } _agn; + struct iwl_notif_statistics accum_statistics; + struct iwl_notif_statistics delta_statistics; + struct iwl_notif_statistics max_delta; + struct iwl_bt_notif_statistics accum_statistics_bt; + struct iwl_bt_notif_statistics delta_statistics_bt; + struct iwl_bt_notif_statistics max_delta_bt; #endif - }; + /* notification wait support */ + struct list_head notif_waits; + spinlock_t notif_wait_lock; + wait_queue_head_t notif_waitq; + + /* remain-on-channel offload support */ + struct ieee80211_channel *hw_roc_channel; + struct delayed_work hw_roc_work; + enum nl80211_channel_type hw_roc_chantype; + int hw_roc_duration; + bool hw_roc_setup; + + struct sk_buff *offchan_tx_skb; + int offchan_tx_timeout; + struct ieee80211_channel *offchan_tx_chan; + } _agn; /* bt coex */ u8 bt_enable_flag; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 98aa8af01192..d0f858af30e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -110,10 +110,6 @@ 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 \ @@ -168,28 +164,6 @@ struct iwl_eeprom_enhanced_txpwr { s8 mimo3_max; } __packed; -/* 3945 Specific */ -#define EEPROM_3945_EEPROM_VERSION (0x2f) - -/* 4965 has two radio transmitters (and 3 radio receivers) */ -#define EEPROM_TX_POWER_TX_CHAINS (2) - -/* 4965 has room for up to 8 sets of txpower calibration data */ -#define EEPROM_TX_POWER_BANDS (8) - -/* 4965 factory calibration measures txpower gain settings for - * each of 3 target output levels */ -#define EEPROM_TX_POWER_MEASUREMENTS (3) - -/* 4965 Specific */ -/* 4965 driver does not work with txpower calibration version < 5 */ -#define EEPROM_4965_TX_POWER_VERSION (5) -#define EEPROM_4965_EEPROM_VERSION (0x2f) -#define EEPROM_4965_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */ -#define EEPROM_4965_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */ -#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */ -#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */ - /* 5000 Specific */ #define EEPROM_5000_TX_POWER_VERSION (4) #define EEPROM_5000_EEPROM_VERSION (0x11A) @@ -282,90 +256,6 @@ struct iwl_eeprom_enhanced_txpwr { /* 2.4 GHz */ extern const u8 iwl_eeprom_band_1[14]; -/* - * factory calibration data for one txpower level, on one channel, - * measured on one of the 2 tx chains (radio transmitter and associated - * antenna). EEPROM contains: - * - * 1) Temperature (degrees Celsius) of device when measurement was made. - * - * 2) Gain table index used to achieve the target measurement power. - * This refers to the "well-known" gain tables (see iwl-4965-hw.h). - * - * 3) Actual measured output power, in half-dBm ("34" = 17 dBm). - * - * 4) RF power amplifier detector level measurement (not used). - */ -struct iwl_eeprom_calib_measure { - u8 temperature; /* Device temperature (Celsius) */ - u8 gain_idx; /* Index into gain table */ - u8 actual_pow; /* Measured RF output power, half-dBm */ - s8 pa_det; /* Power amp detector level (not used) */ -} __packed; - - -/* - * measurement set for one channel. EEPROM contains: - * - * 1) Channel number measured - * - * 2) Measurements for each of 3 power levels for each of 2 radio transmitters - * (a.k.a. "tx chains") (6 measurements altogether) - */ -struct iwl_eeprom_calib_ch_info { - u8 ch_num; - struct iwl_eeprom_calib_measure - measurements[EEPROM_TX_POWER_TX_CHAINS] - [EEPROM_TX_POWER_MEASUREMENTS]; -} __packed; - -/* - * txpower subband info. - * - * For each frequency subband, EEPROM contains the following: - * - * 1) First and last channels within range of the subband. "0" values - * indicate that this sample set is not being used. - * - * 2) Sample measurement sets for 2 channels close to the range endpoints. - */ -struct iwl_eeprom_calib_subband_info { - u8 ch_from; /* channel number of lowest channel in subband */ - u8 ch_to; /* channel number of highest channel in subband */ - struct iwl_eeprom_calib_ch_info ch1; - struct iwl_eeprom_calib_ch_info ch2; -} __packed; - - -/* - * txpower calibration info. EEPROM contains: - * - * 1) Factory-measured saturation power levels (maximum levels at which - * tx power amplifier can output a signal without too much distortion). - * There is one level for 2.4 GHz band and one for 5 GHz band. These - * values apply to all channels within each of the bands. - * - * 2) Factory-measured power supply voltage level. This is assumed to be - * constant (i.e. same value applies to all channels/bands) while the - * factory measurements are being made. - * - * 3) Up to 8 sets of factory-measured txpower calibration values. - * These are for different frequency ranges, since txpower gain - * characteristics of the analog radio circuitry vary with frequency. - * - * Not all sets need to be filled with data; - * struct iwl_eeprom_calib_subband_info contains range of channels - * (0 if unused) for each set of data. - */ -struct iwl_eeprom_calib_info { - u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ - u8 saturation_power52; /* half-dBm */ - __le16 voltage; /* signed */ - struct iwl_eeprom_calib_subband_info - band_info[EEPROM_TX_POWER_BANDS]; -} __packed; - - #define ADDRESS_MSK 0x0000FFFF #define INDIRECT_TYPE_MSK 0x000F0000 #define INDIRECT_HOST 0x00010000 @@ -398,83 +288,8 @@ struct iwl_eeprom_calib_info { #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ -#define EEPROM_3945_RF_CFG_TYPE_MAX 0x0 -#define EEPROM_4965_RF_CFG_TYPE_MAX 0x1 - -/* Radio Config for 5000 and up */ -#define EEPROM_RF_CONFIG_TYPE_R3x3 0x0 -#define EEPROM_RF_CONFIG_TYPE_R2x2 0x1 -#define EEPROM_RF_CONFIG_TYPE_R1x2 0x2 #define EEPROM_RF_CONFIG_TYPE_MAX 0x3 -/* - * Per-channel regulatory data. - * - * Each channel that *might* be supported by iwl has a fixed location - * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory - * txpower (MSB). - * - * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz) - * channels (only for 4965, not supported by 3945) appear later in the EEPROM. - * - * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - */ -#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */ -#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */ -#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */ - -/* - * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, - * 5.0 GHz channels 7, 8, 11, 12, 16 - * (4915-5080MHz) (none of these is ever supported) - */ -#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */ -#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */ - -/* - * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 - * (5170-5320MHz) - */ -#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */ -#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */ - -/* - * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 - * (5500-5700MHz) - */ -#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */ -#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */ - -/* - * 5.7 GHz channels 145, 149, 153, 157, 161, 165 - * (5725-5825MHz) - */ -#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */ -#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */ - -/* - * 2.4 GHz HT40 channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11) - * - * The channel listed is the center of the lower 20 MHz half of the channel. - * The overall center frequency is actually 2 channels (10 MHz) above that, - * and the upper half of each HT40 channel is centered 4 channels (20 MHz) away - * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5, - * and the overall HT40 channel width centers on channel 3. - * - * NOTE: The RXON command uses 20 MHz channel numbers to specify the - * control channel to which to tune. RXON also specifies whether the - * control channel is the upper or lower half of a HT40 channel. - * - * NOTE: 4965 does not support HT40 channels on 2.4 GHz. - */ -#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0) /* 14 bytes */ - -/* - * 5.2 GHz HT40 channels 36 (40), 44 (48), 52 (56), 60 (64), - * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161) - */ -#define EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8) /* 22 bytes */ - #define EEPROM_REGULATORY_BAND_NO_HT40 (0) struct iwl_eeprom_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index c71c0a45fa0b..165e7567d8ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -51,9 +51,7 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_REMOVE_ALL_STA); IWL_CMD(REPLY_TXFIFO_FLUSH); IWL_CMD(REPLY_WEPKEY); - IWL_CMD(REPLY_3945_RX); IWL_CMD(REPLY_TX); - IWL_CMD(REPLY_RATE_SCALE); IWL_CMD(REPLY_LEDS_CMD); IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); IWL_CMD(COEX_PRIORITY_TABLE_CMD); diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 86f5123bccda..81c464747f59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -91,7 +91,6 @@ #define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000) #define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000) #define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000) -#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */ #define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000) #define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */ #define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060) @@ -234,16 +233,6 @@ #define BSM_SRAM_SIZE (1024) /* bytes */ -/* 3945 Tx scheduler registers */ -#define ALM_SCD_BASE (PRPH_BASE + 0x2E00) -#define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000) -#define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004) -#define ALM_SCD_TXFACT_REG (ALM_SCD_BASE + 0x010) -#define ALM_SCD_TXF4MF_REG (ALM_SCD_BASE + 0x014) -#define ALM_SCD_TXF5MF_REG (ALM_SCD_BASE + 0x020) -#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C) -#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030) - /** * Tx Scheduler * -- GitLab From 2dedbf58b2edbe940d370845dbf4210f1ddd2b31 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:50 -0700 Subject: [PATCH 0589/5560] iwlagn: make mac80211 handlers static Now that these handlers are no longer shared between 4965 and agn, they can be static. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 53 +++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 28 -------------- 2 files changed, 27 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 42fad62baf76..b701a03e9ebf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2921,7 +2921,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, } -int iwlagn_mac_start(struct ieee80211_hw *hw) +static int iwlagn_mac_start(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; int ret; @@ -2962,7 +2962,7 @@ int iwlagn_mac_start(struct ieee80211_hw *hw) return 0; } -void iwlagn_mac_stop(struct ieee80211_hw *hw) +static void iwlagn_mac_stop(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; @@ -2985,7 +2985,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = hw->priv; @@ -3000,11 +3000,11 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) IWL_DEBUG_MACDUMP(priv, "leave\n"); } -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) +static 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; @@ -3017,9 +3017,10 @@ void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -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) +static 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; @@ -3094,11 +3095,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -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, - u8 buf_size) +static 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, + u8 buf_size) { struct iwl_priv *priv = hw->priv; int ret = -EINVAL; @@ -3205,9 +3206,9 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, return ret; } -int iwlagn_mac_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static 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; @@ -3248,8 +3249,8 @@ int iwlagn_mac_sta_add(struct ieee80211_hw *hw, return 0; } -void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, - struct ieee80211_channel_switch *ch_switch) +static 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; @@ -3346,10 +3347,10 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -void iwlagn_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) +static 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; @@ -3396,7 +3397,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw, FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; } -void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) +static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) { struct iwl_priv *priv = hw->priv; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 80de8a1edacf..4a0a46e6be3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -337,32 +337,4 @@ void __releases(wait_entry) iwlagn_remove_notification(struct iwl_priv *priv, struct iwl_notification_wait *wait_entry); -/* mac80211 handlers (for 4965) */ -void 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, - u8 buf_size); -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__ */ -- GitLab From 7102762ef0ef330ab0601b6c3bc92bf9be5b1317 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:51 -0700 Subject: [PATCH 0590/5560] iwlagn: clean up ucode loading All agn devices behave the same, so there's no need to go through function pointers for any of the ucode loading functionality. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-2000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-5000.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-core.h | 7 +------ 7 files changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 2601b552c6fa..ad500631a407 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -185,13 +185,10 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, .dump_fh = iwl_dump_fh, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 55274a14af01..5e375d8089c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -266,13 +266,10 @@ static struct iwl_lib_ops iwl2000_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, .dump_fh = iwl_dump_fh, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl2030_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8cab3571047d..0e1f0b50f8e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -358,9 +358,6 @@ static struct iwl_lib_ops iwl5000_lib = { .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, .dump_fh = iwl_dump_fh, - .load_ucode = iwlagn_load_ucode, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, @@ -423,9 +420,6 @@ static struct iwl_lib_ops iwl5150_lib = { .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, - .load_ucode = iwlagn_load_ucode, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 7ecfbbc9457a..4d545e62e5c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -294,13 +294,10 @@ static struct iwl_lib_ops iwl6000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, .dump_fh = iwl_dump_fh, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, @@ -362,13 +359,10 @@ static struct iwl_lib_ops iwl6030_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, .dump_fh = iwl_dump_fh, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index d807e5e2b718..5d35e3504516 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -318,7 +318,7 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) goto restart; } - ret = priv->cfg->ops->lib->alive_notify(priv); + ret = iwlagn_alive_notify(priv); if (ret) { IWL_WARN(priv, "Could not complete ALIVE transition: %d\n", ret); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b701a03e9ebf..c8cd33387a59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2248,7 +2248,7 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } - ret = priv->cfg->ops->lib->alive_notify(priv); + ret = iwlagn_alive_notify(priv); if (ret) { IWL_WARN(priv, "Could not complete ALIVE transition [ntf]: %d\n", ret); @@ -2581,7 +2581,7 @@ static int __iwl_up(struct iwl_priv *priv) /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - ret = priv->cfg->ops->lib->load_ucode(priv); + ret = iwlagn_load_ucode(priv); if (ret) { IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", @@ -2626,7 +2626,7 @@ static void iwl_bg_init_alive_start(struct work_struct *data) return; } - priv->cfg->ops->lib->init_alive_start(priv); + iwlagn_init_alive_start(priv); mutex_unlock(&priv->mutex); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 967b4c008bc0..46c90b3cc30a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -177,14 +177,9 @@ struct iwl_lib_ops { void (*setup_deferred_work)(struct iwl_priv *priv); /* cancel deferred work */ void (*cancel_deferred_work)(struct iwl_priv *priv); - /* alive notification after init uCode load */ - void (*init_alive_start)(struct iwl_priv *priv); - /* alive notification */ - int (*alive_notify)(struct iwl_priv *priv); /* check validity of rtc data address */ int (*is_valid_rtc_data_addr)(u32 addr); - /* 1st ucode load */ - int (*load_ucode)(struct iwl_priv *priv); + int (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log, char **buf, bool display); void (*dump_nic_error_log)(struct iwl_priv *priv); -- GitLab From 4de10b188070b1b96743b1b912843af729ebe50f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 5 Apr 2011 09:41:52 -0700 Subject: [PATCH 0591/5560] iwlagn: remove more 3945/4965 related defines After driver split, remove unused #defines Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-prph.h | 327 ------------------------ 1 file changed, 327 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 81c464747f59..448b0eab54ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -97,142 +97,6 @@ #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) -/** - * BSM (Bootstrap State Machine) - * - * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program - * in special SRAM that does not power down when the embedded control - * processor is sleeping (e.g. for periodic power-saving shutdowns of radio). - * - * When powering back up after sleeps (or during initial uCode load), the BSM - * internally loads the short bootstrap program from the special SRAM into the - * embedded processor's instruction SRAM, and starts the processor so it runs - * the bootstrap program. - * - * This bootstrap program loads (via PCI busmaster DMA) instructions and data - * images for a uCode program from host DRAM locations. The host driver - * indicates DRAM locations and sizes for instruction and data images via the - * four BSM_DRAM_* registers. Once the bootstrap program loads the new program, - * the new program starts automatically. - * - * The uCode used for open-source drivers includes two programs: - * - * 1) Initialization -- performs hardware calibration and sets up some - * internal data, then notifies host via "initialize alive" notification - * (struct iwl_init_alive_resp) that it has completed all of its work. - * After signal from host, it then loads and starts the runtime program. - * The initialization program must be used when initially setting up the - * NIC after loading the driver. - * - * 2) Runtime/Protocol -- performs all normal runtime operations. This - * notifies host via "alive" notification (struct iwl_alive_resp) that it - * is ready to be used. - * - * When initializing the NIC, the host driver does the following procedure: - * - * 1) Load bootstrap program (instructions only, no data image for bootstrap) - * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND - * - * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction - * images in host DRAM. - * - * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked: - * BSM_WR_MEM_SRC_REG = 0 - * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND - * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image - * - * 4) Load bootstrap into instruction SRAM: - * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START - * - * 5) Wait for load completion: - * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0 - * - * 6) Enable future boot loads whenever NIC's power management triggers it: - * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN - * - * 7) Start the NIC by removing all reset bits: - * CSR_RESET = 0 - * - * The bootstrap uCode (already in instruction SRAM) loads initialization - * uCode. Initialization uCode performs data initialization, sends - * "initialize alive" notification to host, and waits for a signal from - * host to load runtime code. - * - * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction - * images in host DRAM. The last register loaded must be the instruction - * byte count register ("1" in MSbit tells initialization uCode to load - * the runtime uCode): - * BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD - * - * 5) Wait for "alive" notification, then issue normal runtime commands. - * - * Data caching during power-downs: - * - * Just before the embedded controller powers down (e.g for automatic - * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA) - * a current snapshot of the embedded processor's data SRAM into host DRAM. - * This caches the data while the embedded processor's memory is powered down. - * Location and size are controlled by BSM_DRAM_DATA_* registers. - * - * NOTE: Instruction SRAM does not need to be saved, since that doesn't - * change during operation; the original image (from uCode distribution - * file) can be used for reload. - * - * When powering back up, the BSM loads the bootstrap program. Bootstrap looks - * at the BSM_DRAM_* registers, which now point to the runtime instruction - * image and the cached (modified) runtime data (*not* the initialization - * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the - * uCode from where it left off before the power-down. - * - * NOTE: Initialization uCode does *not* run as part of the save/restore - * procedure. - * - * This save/restore method is mostly for autonomous power management during - * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and - * RFKILL should use complete restarts (with total re-initialization) of uCode, - * allowing total shutdown (including BSM memory). - * - * Note that, during normal operation, the host DRAM that held the initial - * startup data for the runtime code is now being used as a backup data cache - * for modified data! If you need to completely re-initialize the NIC, make - * sure that you use the runtime data image from the uCode distribution file, - * not the modified/saved runtime data. You may want to store a separate - * "clean" runtime data image in DRAM to avoid disk reads of distribution file. - */ - -/* BSM bit fields */ -#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */ -#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/ -#define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */ - -/* BSM addresses */ -#define BSM_BASE (PRPH_BASE + 0x3400) -#define BSM_END (PRPH_BASE + 0x3800) - -#define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */ -#define BSM_WR_MEM_SRC_REG (BSM_BASE + 0x004) /* source in BSM mem */ -#define BSM_WR_MEM_DST_REG (BSM_BASE + 0x008) /* dest in SRAM mem */ -#define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */ -#define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */ - -/* - * Pointers and size regs for bootstrap load and data SRAM save/restore. - * NOTE: 3945 pointers use bits 31:0 of DRAM address. - * 4965 pointers use bits 35:4 of DRAM address. - */ -#define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090) -#define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094) -#define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098) -#define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C) - -/* - * BSM special memory, stays powered on during power-save sleeps. - * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1) - */ -#define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800) -#define BSM_SRAM_SIZE (1024) /* bytes */ - - /** * Tx Scheduler * @@ -319,201 +183,10 @@ * Max Tx window size is the max number of contiguous TFDs that the scheduler * can keep track of at one time when creating block-ack chains of frames. * Note that "64" matches the number of ack bits in a block-ack packet. - * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize - * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values. */ #define SCD_WIN_SIZE 64 #define SCD_FRAME_LIMIT 64 -/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */ -#define IWL49_SCD_START_OFFSET 0xa02c00 - -/* - * 4965 tells driver SRAM address for internal scheduler structs via this reg. - * Value is valid only after "Alive" response from uCode. - */ -#define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x0) - -/* - * Driver may need to update queue-empty bits after changing queue's - * write and read pointers (indexes) during (re-)initialization (i.e. when - * scheduler is not tracking what's happening). - * Bit fields: - * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit - * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty - * NOTE: This register is not used by Linux driver. - */ -#define IWL49_SCD_EMPTY_BITS (IWL49_SCD_START_OFFSET + 0x4) - -/* - * Physical base address of array of byte count (BC) circular buffers (CBs). - * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode. - * This register points to BC CB for queue 0, must be on 1024-byte boundary. - * Others are spaced by 1024 bytes. - * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad. - * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff). - * Bit fields: - * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned. - */ -#define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10) - -/* - * Enables any/all Tx DMA/FIFO channels. - * Scheduler generates requests for only the active channels. - * Set this to 0xff to enable all 8 channels (normal usage). - * Bit fields: - * 7- 0: Enable (1), disable (0), one bit for each channel 0-7 - */ -#define IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c) -/* - * Queue (x) Write Pointers (indexes, really!), one for each Tx queue. - * Initialized and updated by driver as new TFDs are added to queue. - * NOTE: If using Block Ack, index must correspond to frame's - * Start Sequence Number; index = (SSN & 0xff) - * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses? - */ -#define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4) - -/* - * Queue (x) Read Pointers (indexes, really!), one for each Tx queue. - * For FIFO mode, index indicates next frame to transmit. - * For Scheduler-ACK mode, index indicates first frame in Tx window. - * Initialized by driver, updated by scheduler. - */ -#define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4) - -/* - * Select which queues work in chain mode (1) vs. not (0). - * Use chain mode to build chains of aggregated frames. - * Bit fields: - * 31-16: Reserved - * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time - * NOTE: If driver sets up queue for chain mode, it should be also set up - * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x). - */ -#define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_START_OFFSET + 0xd0) - -/* - * Select which queues interrupt driver when scheduler increments - * a queue's read pointer (index). - * Bit fields: - * 31-16: Reserved - * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled - * NOTE: This functionality is apparently a no-op; driver relies on interrupts - * from Rx queue to read Tx command responses and update Tx queues. - */ -#define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4) - -/* - * Queue search status registers. One for each queue. - * Sets up queue mode and assigns queue to Tx DMA channel. - * Bit fields: - * 19-10: Write mask/enable bits for bits 0-9 - * 9: Driver should init to "0" - * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0). - * Driver should init to "1" for aggregation mode, or "0" otherwise. - * 7-6: Driver should init to "0" - * 5: Window Size Left; indicates whether scheduler can request - * another TFD, based on window size, etc. Driver should init - * this bit to "1" for aggregation mode, or "0" for non-agg. - * 4-1: Tx FIFO to use (range 0-7). - * 0: Queue is active (1), not active (0). - * Other bits should be written as "0" - * - * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled - * via SCD_QUEUECHAIN_SEL. - */ -#define IWL49_SCD_QUEUE_STATUS_BITS(x)\ - (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4) - -/* Bit field positions */ -#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0) -#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1) -#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5) -#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8) - -/* Write masks */ -#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10) -#define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00) - -/** - * 4965 internal SRAM structures for scheduler, shared with driver ... - * - * Driver should clear and initialize the following areas after receiving - * "Alive" response from 4965 uCode, i.e. after initial - * uCode load, or after a uCode load done for error recovery: - * - * SCD_CONTEXT_DATA_OFFSET (size 128 bytes) - * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes) - * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes) - * - * Driver accesses SRAM via HBUS_TARG_MEM_* registers. - * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR. - * All OFFSET values must be added to this base address. - */ - -/* - * Queue context. One 8-byte entry for each of 16 queues. - * - * Driver should clear this entire area (size 0x80) to 0 after receiving - * "Alive" notification from uCode. Additionally, driver should init - * each queue's entry as follows: - * - * LS Dword bit fields: - * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64. - * - * MS Dword bit fields: - * 16-22: Frame limit. Driver should init to 10 (0xa). - * - * Driver should init all other bits to 0. - * - * Init must be done after driver receives "Alive" response from 4965 uCode, - * and when setting up queue for aggregation. - */ -#define IWL49_SCD_CONTEXT_DATA_OFFSET 0x380 -#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \ - (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) - -#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0) -#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F) -#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) -#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) - -/* - * Tx Status Bitmap - * - * Driver should clear this entire area (size 0x100) to 0 after receiving - * "Alive" notification from uCode. Area is used only by device itself; - * no other support (besides clearing) is required from driver. - */ -#define IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400 - -/* - * RAxTID to queue translation mapping. - * - * When queue is in Scheduler-ACK mode, frames placed in a that queue must be - * for only one combination of receiver address (RA) and traffic ID (TID), i.e. - * one QOS priority level destined for one station (for this wireless link, - * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit - * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK - * mode, the device ignores the mapping value. - * - * Bit fields, for each 16-bit map: - * 15-9: Reserved, set to 0 - * 8-4: Index into device's station table for recipient station - * 3-0: Traffic ID (tid), range 0-15 - * - * Driver should clear this entire area (size 32 bytes) to 0 after receiving - * "Alive" notification from uCode. To update a 16-bit map value, driver - * must read a dword-aligned value from device SRAM, replace the 16-bit map - * value of interest, and write the dword value back into device SRAM. - */ -#define IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500 - -/* Find translation table dword to read/write for given queue */ -#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ - ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) - #define IWL_SCD_TXFIFO_POS_TID (0) #define IWL_SCD_TXFIFO_POS_RA (4) #define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) -- GitLab From 08960dea6c736280a03cb947f445fdb94fdaa2ee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:53 -0700 Subject: [PATCH 0592/5560] iwlagn: remove pointless return variables A number of places just use a variable to return it right away, which is useless, so let's remove the variables there. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 9 ++------- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 ++----- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index e394e49228ba..97abc10f4f22 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2771,16 +2771,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, gfp_t gfp) { - struct iwl_lq_sta *lq_sta; struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; struct iwl_priv *priv; priv = (struct iwl_priv *)priv_rate; IWL_DEBUG_RATE(priv, "create station rate scale window\n"); - lq_sta = &sta_priv->lq_sta; - - return lq_sta; + return &sta_priv->lq_sta; } /* @@ -3259,7 +3256,6 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, { char buff[120]; int desc = 0; - ssize_t ret; struct iwl_lq_sta *lq_sta = file->private_data; struct iwl_priv *priv; @@ -3276,8 +3272,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, "Bit Rate= %d Mb/s\n", iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); - ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); - return ret; + return simple_read_from_buffer(user_buf, count, ppos, buff, desc); } static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 5d35e3504516..bb262a60e816 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -653,7 +653,5 @@ int iwl_verify_ucode(struct iwl_priv *priv) * Selection of bootstrap image (vs. other images) is arbitrary. */ image = (__le32 *)priv->ucode_boot.v_addr; len = priv->ucode_boot.len; - ret = iwl_verify_inst_full(priv, image, len); - - return ret; + return iwl_verify_inst_full(priv, image, len); } diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 8842411f1cf3..90f2b6464bc1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1572,12 +1572,10 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, int pos = 0; char buf[200]; 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; + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n", priv->bt_enable_flag); @@ -1608,8 +1606,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, break; } - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - return ret; + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, -- GitLab From 36127db02ec17828c1582bb6bc1f12160fd35d64 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 5 Apr 2011 09:41:54 -0700 Subject: [PATCH 0593/5560] iwlagn: return send calibration result In alive notification call, return the status from iwl_send_calib_results() Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index bb262a60e816..127c842fea55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -530,9 +530,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv) iwlagn_send_wimax_coex(priv); iwlagn_set_Xtal_calib(priv); - iwl_send_calib_results(priv); - - return 0; + return iwl_send_calib_results(priv); } -- GitLab From fb66216f9ebb146ad457829fcb62ae8f4348cda2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:55 -0700 Subject: [PATCH 0594/5560] iwlagn: simplify ucode check code The code in iwlcore_verify_inst_sparse really doesn't need to keep track of the number of errors it encountered since a single one is fatal. Also, the code in iwl_verify_inst_full is just used to print out some things, so rename it to iwl_print_inst and don't give it a return code and just make it print out the values. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 51 +++++++------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 127c842fea55..2205b6035207 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -542,8 +542,6 @@ int iwlagn_alive_notify(struct iwl_priv *priv) static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) { u32 val; - int ret = 0; - u32 errcnt = 0; u32 i; IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); @@ -555,56 +553,39 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, i + IWLAGN_RTC_INST_LOWER_BOUND); val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { - ret = -EIO; - errcnt++; - if (errcnt >= 3) - break; - } + if (val != le32_to_cpu(*image)) + return -EIO; } - return ret; + return 0; } -/** - * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host, - * looking at all data. - */ -static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, - u32 len) +static void iwl_print_mismatch_inst(struct iwl_priv *priv, + __le32 *image, u32 len) { u32 val; - u32 save_len = len; - int ret = 0; - u32 errcnt; + u32 offs; + int errors = 0; IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); - errcnt = 0; - for (; len > 0; len -= sizeof(u32), image++) { + for (offs = 0; + offs < len && errors < 20; + offs += sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "uCode INST section is invalid at " - "offset 0x%x, is 0x%x, s/b 0x%x\n", - save_len - len, val, le32_to_cpu(*image)); - ret = -EIO; - errcnt++; - if (errcnt >= 20) - break; + IWL_ERR(priv, "uCode INST section at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + offs, val, le32_to_cpu(*image)); + errors++; } } - - if (!errcnt) - IWL_DEBUG_INFO(priv, - "ucode image in INSTRUCTION memory is good\n"); - - return ret; } /** @@ -651,5 +632,7 @@ int iwl_verify_ucode(struct iwl_priv *priv) * Selection of bootstrap image (vs. other images) is arbitrary. */ image = (__le32 *)priv->ucode_boot.v_addr; len = priv->ucode_boot.len; - return iwl_verify_inst_full(priv, image, len); + iwl_print_mismatch_inst(priv, image, len); + + return -EIO; } -- GitLab From 35b1d92dfb361d24664381a0e4ae8ed47c771a66 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:56 -0700 Subject: [PATCH 0595/5560] iwlagn: verify specific ucode When we loaded a ucode, there's no point in checking any one that is present, we know which one is supposed to be present so also verify that it is exactly the right one. That also simplifies the code and makes it faster since it doesn't have to check all. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 51 +++++--------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- 3 files changed, 14 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 2205b6035207..c7b9b8377efe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -311,7 +311,7 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) /* initialize uCode was loaded... verify inst image. * This is a paranoid check, because we would not have gotten the * "initialize" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { + if (iwl_verify_ucode(priv, &priv->ucode_init)) { /* Runtime instruction load was bad; * take it all the way back down so we can try again */ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); @@ -539,8 +539,11 @@ int iwlagn_alive_notify(struct iwl_priv *priv) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, + struct fw_desc *fw_desc) { + __le32 *image = (__le32 *)fw_desc->v_addr; + u32 len = fw_desc->len; u32 val; u32 i; @@ -561,8 +564,10 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 } static void iwl_print_mismatch_inst(struct iwl_priv *priv, - __le32 *image, u32 len) + struct fw_desc *fw_desc) { + __le32 *image = (__le32 *)fw_desc->v_addr; + u32 len = fw_desc->len; u32 val; u32 offs; int errors = 0; @@ -592,47 +597,15 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, * iwl_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ -int iwl_verify_ucode(struct iwl_priv *priv) +int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc) { - __le32 *image; - u32 len; - int ret; - - /* Try bootstrap */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - ret = iwlcore_verify_inst_sparse(priv, image, len); - if (!ret) { + if (!iwlcore_verify_inst_sparse(priv, fw_desc)) { IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); return 0; } - /* Try initialize */ - image = (__le32 *)priv->ucode_init.v_addr; - len = priv->ucode_init.len; - ret = iwlcore_verify_inst_sparse(priv, image, len); - if (!ret) { - IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); - return 0; - } - - /* Try runtime/protocol */ - image = (__le32 *)priv->ucode_code.v_addr; - len = priv->ucode_code.len; - ret = iwlcore_verify_inst_sparse(priv, image, len); - if (!ret) { - IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); - return 0; - } - - IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); - - /* Since nothing seems to match, show first several data entries in - * instruction SRAM, so maybe visual inspection will give a clue. - * Selection of bootstrap image (vs. other images) is arbitrary. */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - iwl_print_mismatch_inst(priv, image, len); + IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); + iwl_print_mismatch_inst(priv, fw_desc); return -EIO; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c8cd33387a59..c66fcea4737b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2241,7 +2241,7 @@ static void iwl_alive_start(struct iwl_priv *priv) /* Initialize uCode has loaded Runtime uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "runtime" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { + if (iwl_verify_ucode(priv, &priv->ucode_code)) { /* Runtime instruction load was bad; * take it all the way back down so we can try again */ IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 4a0a46e6be3f..d2953bc7beee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -152,7 +152,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwlagn_init_alive_start(struct iwl_priv *priv); int iwlagn_alive_notify(struct iwl_priv *priv); -int iwl_verify_ucode(struct iwl_priv *priv); +int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc); void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); void iwlagn_send_prio_tbl(struct iwl_priv *priv); -- GitLab From 1fc352765fb461e4afafff4d650624df8ab6b6d6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:57 -0700 Subject: [PATCH 0596/5560] iwlagn: remove bootstrap code Only 4965 had a bootstrap microcode image, so the agn driver can completely ignore that and we can remove some code from it. 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-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn.c | 36 +++---------------------- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 -- 6 files changed, 4 insertions(+), 39 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index ad500631a407..53a6702f4063 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -141,7 +141,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = 0; priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 5e375d8089c4..9f973895ce86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -147,7 +147,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = 0; priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 0e1f0b50f8e8..653bb8ef2950 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -185,7 +185,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = 0; priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; @@ -231,7 +230,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = 0; priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 4d545e62e5c7..1e55f811431c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -176,7 +176,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = 0; priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c66fcea4737b..5e74eb0fd6ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1181,7 +1181,6 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); } static void iwl_nic_start(struct iwl_priv *priv) @@ -1239,8 +1238,8 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) } struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *boot; - size_t inst_size, data_size, init_size, init_data_size, boot_size; + const void *inst, *data, *init, *init_data; + size_t inst_size, data_size, init_size, init_data_size; u32 build; @@ -1271,7 +1270,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size); src = ucode->u.v2.data; break; case 0: @@ -1287,7 +1285,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); - pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size); src = ucode->u.v1.data; break; } @@ -1295,7 +1292,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, /* Verify size of file vs. image size info in file's header */ if (ucode_raw->size != hdr_size + pieces->inst_size + pieces->data_size + pieces->init_size + - pieces->init_data_size + pieces->boot_size) { + pieces->init_data_size) { IWL_ERR(priv, "uCode file size %d does not match expected size\n", @@ -1311,8 +1308,6 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, src += pieces->init_size; pieces->init_data = src; src += pieces->init_data_size; - pieces->boot = src; - src += pieces->boot_size; return 0; } @@ -1413,8 +1408,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, pieces->init_data_size = tlv_len; break; case IWL_UCODE_TLV_BOOT: - pieces->boot = tlv_data; - pieces->boot_size = tlv_len; + IWL_ERR(priv, "Found unexpected BOOT ucode\n"); break; case IWL_UCODE_TLV_PROBE_MAX_LEN: if (tlv_len != sizeof(u32)) @@ -1614,8 +1608,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) pieces.init_size); IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", pieces.init_data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n", - pieces.boot_size); /* Verify that uCode images will fit in card's SRAM */ if (pieces.inst_size > priv->hw_params.max_inst_size) { @@ -1642,12 +1634,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto try_again; } - if (pieces.boot_size > priv->hw_params.max_bsm_size) { - IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n", - pieces.boot_size); - goto try_again; - } - /* Allocate ucode buffers for card's bus-master loading ... */ /* Runtime instructions and 2 copies of data: @@ -1678,15 +1664,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto err_pci_alloc; } - /* Bootstrap (instructions only, no data) */ - if (pieces.boot_size) { - priv->ucode_boot.len = pieces.boot_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); - - if (!priv->ucode_boot.v_addr) - goto err_pci_alloc; - } - /* Now that we can no longer fail, copy information */ /* @@ -1749,11 +1726,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) pieces.init_data_size); } - /* Bootstrap instructions */ - IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", - pieces.boot_size); - memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); - /* * figure out the offset of chain noise reset and gain commands * base on the size of standard phy calibration commands table size diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8dc209a341aa..b3af2e8afc0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -641,7 +641,6 @@ struct iwl_hw_params { u8 max_beacon_itrvl; /* in 1024 ms */ u32 max_inst_size; u32 max_data_size; - u32 max_bsm_size; u32 ct_kill_threshold; /* value in hw-dependent units */ u32 ct_kill_exit_threshold; /* value in hw-dependent units */ /* for 1000, 6000 series and up */ @@ -1263,7 +1262,6 @@ struct iwl_priv { struct fw_desc ucode_data_backup; /* runtime data save/restore */ struct fw_desc ucode_init; /* initialization inst */ struct fw_desc ucode_init_data; /* initialization data */ - struct fw_desc ucode_boot; /* bootstrap inst */ enum ucode_type ucode_type; u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; -- GitLab From e649437fd6e2bae6f7b8a36a302a1ec4faa5d906 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:58 -0700 Subject: [PATCH 0597/5560] iwlagn: centralize and fix ucode restart The ucode restart has to take into account a number of things, like clearing the HCMD_ACTIVE and other status bits, and waking up the wait_command_queue. Currently, however, there are a number of places that neither do that, nor actually set the FW error bit that leads to proper restart handling, which means that in those cases things will probably just hang completely. To clean this up, make all ucode restart go through a single function, except for the cases where it's called during firmware loading. Also fix a bug in wimax coexist restart avoidance, it needs to first clear the status bits (and it has to clear the HCMD_ACTIVE one as well) and then wake up anything waiting on wait_command_queue. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 99 +++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-core.h | 3 + drivers/net/wireless/iwlwifi/iwl-tx.c | 4 +- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d778f52132cb..64b28b01ad86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -890,10 +890,8 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); } #endif -/** - * iwl_irq_handle_error - called for HW or SW error interrupt from card - */ -void iwl_irq_handle_error(struct iwl_priv *priv) + +void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) { unsigned int reload_msec; unsigned long reload_jiffies; @@ -904,18 +902,62 @@ void iwl_irq_handle_error(struct iwl_priv *priv) /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + /* Keep the restart process from trying to send host + * commands by clearing the ready bit */ + clear_bit(STATUS_READY, &priv->status); + + wake_up_interruptible(&priv->wait_command_queue); + + if (!ondemand) { + /* + * If firmware keep reloading, then it indicate something + * serious wrong and firmware having problem to recover + * from it. Instead of keep trying which will fill the syslog + * and hang the system, let's just stop it + */ + reload_jiffies = jiffies; + reload_msec = jiffies_to_msecs((long) reload_jiffies - + (long) priv->reload_jiffies); + priv->reload_jiffies = reload_jiffies; + if (reload_msec <= IWL_MIN_RELOAD_DURATION) { + priv->reload_count++; + if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) { + IWL_ERR(priv, "BUG_ON, Stop restarting\n"); + return; + } + } else + priv->reload_count = 0; + } + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { + if (priv->cfg->mod_params->restart_fw) { + IWL_DEBUG(priv, IWL_DL_FW_ERRORS, + "Restarting adapter due to uCode error.\n"); + queue_work(priv->workqueue, &priv->restart); + } else + IWL_DEBUG(priv, IWL_DL_FW_ERRORS, + "Detected FW error, but not restarting\n"); + } +} + +/** + * iwl_irq_handle_error - called for HW or SW error interrupt from card + */ +void iwl_irq_handle_error(struct iwl_priv *priv) +{ /* 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 + * Keep the restart process from trying to send host + * commands by clearing the ready bit. */ clear_bit(STATUS_READY, &priv->status); + clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + wake_up_interruptible(&priv->wait_command_queue); IWL_ERR(priv, "RF is used by WiMAX\n"); return; } @@ -935,38 +977,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv) &priv->contexts[IWL_RXON_CTX_BSS]); #endif - 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); - - /* - * If firmware keep reloading, then it indicate something - * serious wrong and firmware having problem to recover - * from it. Instead of keep trying which will fill the syslog - * and hang the system, let's just stop it - */ - reload_jiffies = jiffies; - reload_msec = jiffies_to_msecs((long) reload_jiffies - - (long) priv->reload_jiffies); - priv->reload_jiffies = reload_jiffies; - if (reload_msec <= IWL_MIN_RELOAD_DURATION) { - priv->reload_count++; - if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) { - IWL_ERR(priv, "BUG_ON, Stop restarting\n"); - return; - } - } else - priv->reload_count = 0; - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG(priv, IWL_DL_FW_ERRORS, - "Restarting adapter due to uCode error.\n"); - - if (priv->cfg->mod_params->restart_fw) - queue_work(priv->workqueue, &priv->restart); - } + iwlagn_fw_error(priv, false); } static int iwl_apm_stop_master(struct iwl_priv *priv) @@ -1755,15 +1766,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) break; } IWL_ERR(priv, "On demand firmware reload\n"); - /* Set the FW error flag -- cleared on iwl_down */ - set_bit(STATUS_FW_ERROR, &priv->status); - 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); - queue_work(priv->workqueue, &priv->restart); + iwlagn_fw_error(priv, true); break; } return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 46c90b3cc30a..8bc23468d82c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -729,4 +729,7 @@ static inline bool iwl_bt_statistics(struct iwl_priv *priv) extern bool bt_coex_active; extern bool bt_siso_mode; + +void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); + #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 39a4180ee854..fa81df22a103 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -474,7 +474,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) } if (!is_ct_kill) { IWL_ERR(priv, "Restarting adapter due to queue full\n"); - queue_work(priv->workqueue, &priv->restart); + iwlagn_fw_error(priv, false); } return -ENOSPC; } @@ -582,7 +582,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, if (nfreed++ > 0) { IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx, q->write_ptr, q->read_ptr); - queue_work(priv->workqueue, &priv->restart); + iwlagn_fw_error(priv, false); } } -- GitLab From 6009c39c6fc1cb988bdc90a395d9cce273afc7d5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:41:59 -0700 Subject: [PATCH 0598/5560] iwlagn: remove ucode_data_backup This was used only on 4965 in conjunction with the bootstrap ucode. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 19 +------------------ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5e74eb0fd6ee..e3095afc9554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1178,7 +1178,6 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) { iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); } @@ -1645,11 +1644,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) priv->ucode_data.len = pieces.data_size; iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); - priv->ucode_data_backup.len = pieces.data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); - - if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || - !priv->ucode_data_backup.v_addr) + if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr) goto err_pci_alloc; /* Initialization instructions and data */ @@ -1709,7 +1704,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", pieces.data_size); memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size); - memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size); /* Initialization instructions */ if (pieces.init_size) { @@ -2481,11 +2475,6 @@ static int __iwl_up(struct iwl_priv *priv) return -EIO; } - if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { - IWL_ERR(priv, "ucode not available for device bringup\n"); - return -EIO; - } - for_each_context(priv, ctx) { ret = iwlagn_alloc_bcast_station(priv, ctx); if (ret) { @@ -2542,12 +2531,6 @@ static int __iwl_up(struct iwl_priv *priv) iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - /* Copy original ucode data image from disk into backup cache. - * This will be used to initialize the on-board processor's - * data SRAM for a clean start when the runtime program first loads. */ - memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, - priv->ucode_data.len); - for (i = 0; i < MAX_HW_RESTARTS; i++) { /* load bootstrap state machine, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index b3af2e8afc0a..7619cee648f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1259,7 +1259,6 @@ struct iwl_priv { iwl_ucode.ver */ struct fw_desc ucode_code; /* runtime inst */ struct fw_desc ucode_data; /* runtime data original */ - struct fw_desc ucode_data_backup; /* runtime data save/restore */ struct fw_desc ucode_init; /* initialization inst */ struct fw_desc ucode_init_data; /* initialization data */ enum ucode_type ucode_type; -- GitLab From 901069c71415a76d731857ccda814e18ded062f7 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 5 Apr 2011 09:42:00 -0700 Subject: [PATCH 0599/5560] iwlagn: change Copyright to 2011 Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 4 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000-hw.h | 4 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 4 +- .../net/wireless/iwlwifi/iwl-agn-debugfs.c | 52 +++++++++---------- .../net/wireless/iwlwifi/iwl-agn-debugfs.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 4 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 +- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 6 +-- drivers/net/wireless/iwlwifi/iwl-csr.h | 4 +- drivers/net/wireless/iwlwifi/iwl-debug.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.c | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 4 +- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 4 +- drivers/net/wireless/iwlwifi/iwl-fh.h | 4 +- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl-helpers.h | 2 +- drivers/net/wireless/iwlwifi/iwl-io.h | 2 +- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.h | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 4 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwlwifi/iwl-spectrum.h | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +- drivers/net/wireless/iwlwifi/iwl-tx.c | 2 +- 53 files changed, 93 insertions(+), 93 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 53a6702f4063..5c3bb47de3a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 9f973895ce86..f87adbf11349 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 3975e45e7500..05ad47628b63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 653bb8ef2950..d2f4eb3f4b38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h index 47891e16a758..b27986e57c92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 1e55f811431c..c1f8d1d2b721 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 9006293e740c..7b761de77b0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index e37ae7261630..ef4d5079a7ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index b500aaae53ec..d1834aa7edf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -1,30 +1,30 @@ /****************************************************************************** -* -* 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 -*****************************************************************************/ + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 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 "iwl-agn.h" #include "iwl-agn-debugfs.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h index f2573b5486cd..9a3f329e508f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 27b5a3eec9dc..c6dd9b755a05 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 41543ad4cb84..861cc93957a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index a52b82c8e7a6..7bd19f4e66de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index 47e1fa4bacfd..34d77d22a360 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c index c1190d965614..4bb877e600c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h index 96f323dc5dd6..c0b7611b72c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3a02bea46328..9a3d69d9b8a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 97abc10f4f22..dbe6295bbf23 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index b356a39a824f..69a29932babc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index dfdbea6e8f99..c335ee6883ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 3782fe8194fd..079275f2c64d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index e3a8216a033c..348f74f1c8e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h index d55060427cac..d118ed29bf3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index cb8eacd5fdb5..2816b432c62f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index c7b9b8377efe..a7c913119f2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e3095afc9554..2f4fe16d1eea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d2953bc7beee..016b79e4421e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index e6058436aeb3..a2348ee61fd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 64b28b01ad86..6e9829fd6c03 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8bc23468d82c..696b056b070c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -73,7 +73,7 @@ struct iwl_cmd; #define IWLWIFI_VERSION "in-tree:" -#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" #define DRV_AUTHOR "" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 1123319f2e2b..5ab90ba7a024 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index ebdea3be3ef9..8489431ceb8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 90f2b6464bc1..92f6efd2c73f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7619cee648f4..0696e7ff0f37 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 4a487639d932..a635a7e75447 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 4cf864c664ee..f00172cb8a6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index c831a0f24613..f70d87162e59 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index d0f858af30e8..35bf54b38515 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 55b8370bc6d4..da06d136a357 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 165e7567d8ee..9177b553fe57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 8821f088ba7f..5da5761c74b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 0203a3bbf872..3ddb2fbe12f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index d7f2a0bb32c9..c2862d4e00e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 101eef12b3bb..05b8e8f7dd4a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 576795e2c75b..c43c8e66de73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index fe012032c28c..59635d784e27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 448b0eab54ac..c960195df989 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 6f9a2fa04763..984a42cfffe9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 3a4d9e6b0421..c517f6d8a15f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2011 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h index c4ca0b5d77da..cb80bb4ce45e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ieee80211 subsystem header files. * diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 6ded0174a609..c21515640077 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 206f1e1a0caf..ff64027ff4cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index fa81df22a103..565980fbb591 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. -- GitLab From 7415952ff789b1c1878119662d4dc011ac9d261e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 5 Apr 2011 09:42:01 -0700 Subject: [PATCH 0600/5560] iwlagn: check more error return code In alive notify, we should check return code instead of assume everything ok Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index a7c913119f2a..9c5abff6f04a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -432,6 +432,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv) unsigned long flags; int i, chan; u32 reg_val; + int ret; spin_lock_irqsave(&priv->lock, flags); @@ -527,9 +528,14 @@ int iwlagn_alive_notify(struct iwl_priv *priv) iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - iwlagn_send_wimax_coex(priv); + ret = iwlagn_send_wimax_coex(priv); + if (ret) + return ret; + + ret = iwlagn_set_Xtal_calib(priv); + if (ret) + return ret; - iwlagn_set_Xtal_calib(priv); return iwl_send_calib_results(priv); } -- GitLab From 3997ff39faa184a2ff670a6792cdb89ff51cf78f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:02 -0700 Subject: [PATCH 0601/5560] iwlagn: add feature flags Some new devices and microcode files will a greater variety of features, so the TLV-per-feature approach we took before will quickly make things harder to manage and increase the file size. Add a new TLV that has feature flags. Currently, it will contain: 1) a PAN feature flag, which moves from a separate TLV 2) a new BT stats bit that indicates whether the microcode image uses bluetooth statistics 3) a new MFP flag for management frame protection which can be enabled once the device/microcode supports 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 | 29 ++++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 17 +++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 2f4fe16d1eea..30b8b9e1bc2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1191,7 +1191,7 @@ static void iwl_nic_start(struct iwl_priv *priv) struct iwlagn_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; - bool pan; + u32 flags; }; static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); @@ -1418,7 +1418,23 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, case IWL_UCODE_TLV_PAN: if (tlv_len) goto invalid_tlv_len; - capa->pan = true; + capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; + break; + case IWL_UCODE_TLV_FLAGS: + /* must be at least one u32 */ + if (tlv_len < sizeof(u32)) + goto invalid_tlv_len; + /* and a proper number of u32s */ + if (tlv_len % sizeof(u32)) + goto invalid_tlv_len; + /* + * This driver only reads the first u32 as + * right now no more features are defined, + * if that changes then either the driver + * will not work with the new firmware, or + * it'll not take advantage of new features. + */ + capa->flags = le32_to_cpup((__le32 *)tlv_data); break; case IWL_UCODE_TLV_INIT_EVTLOG_PTR: if (tlv_len != sizeof(u32)) @@ -1681,12 +1697,16 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) priv->cfg->base_params->max_event_log_size; priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; - if (ucode_capa.pan) { + if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; } else priv->sta_key_max_num = STA_KEY_MAX_NUM; + if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS || + (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)) + priv->bt_statistics = true; + /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ @@ -2827,6 +2847,9 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; + if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) + hw->flags |= IEEE80211_HW_MFP_CAPABLE; + hw->sta_data_size = sizeof(struct iwl_station_priv); hw->vif_data_size = sizeof(struct iwl_vif_priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 696b056b070c..7b9f64ea9662 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -723,7 +723,7 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) static inline bool iwl_bt_statistics(struct iwl_priv *priv) { - return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics; + return priv->bt_statistics; } extern bool bt_coex_active; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0696e7ff0f37..2f7458d3be9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -535,6 +535,22 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, + /* 16 and 17 reserved for future use */ + IWL_UCODE_TLV_FLAGS = 18, +}; + +/** + * enum iwl_ucode_tlv_flag - ucode API flags + * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously + * was a separate TLV but moved here to save space. + * @IWL_UCODE_TLV_FLAGS_BTSTATS: This uCode image uses BT statistics, which + * may be true even if the device doesn't have BT. + * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). + */ +enum iwl_ucode_tlv_flag { + IWL_UCODE_TLV_FLAGS_PAN = BIT(0), + IWL_UCODE_TLV_FLAGS_BTSTATS = BIT(1), + IWL_UCODE_TLV_FLAGS_MFP = BIT(2), }; struct iwl_ucode_tlv { @@ -1410,6 +1426,7 @@ struct iwl_priv { bool bt_ch_announce; bool bt_full_concurrent; bool bt_ant_couple_ok; + bool bt_statistics; __le32 kill_ack_mask; __le32 kill_cts_mask; __le16 bt_valid; -- GitLab From 3d09cdff233b5a37ce9993c533e8da1403e2da30 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:03 -0700 Subject: [PATCH 0602/5560] iwlagn: fix ucode verify message My previous patch left a message talking about bootstrap, but that's clearly bogus. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 9c5abff6f04a..5187a2c20644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -606,7 +606,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc) { if (!iwlcore_verify_inst_sparse(priv, fw_desc)) { - IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); + IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); return 0; } -- GitLab From d7d5783c6668b54111cc77005755799e94261497 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:04 -0700 Subject: [PATCH 0603/5560] iwlagn: clean up alive handling Devices newer than 4965 don't actually send two different versions of the ALIVE command, so we always had a bug here since before this patch we copy more data than we got. Remove the iwl_init_alive_resp struct and don't use it. Since we also really don't need to track all the data received in ALIVE as we only use the error and log event tables later, we can also save space by just keeping those and not more data around in memory. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ++----- drivers/net/wireless/iwlwifi/iwl-commands.h | 48 --------------------- drivers/net/wireless/iwlwifi/iwl-dev.h | 8 ++-- drivers/net/wireless/iwlwifi/iwl-rx.c | 10 ++--- 4 files changed, 13 insertions(+), 69 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 30b8b9e1bc2e..b3b1e84c9311 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -590,10 +590,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) u32 num_wraps; /* # times uCode wrapped to top of log */ u32 next_entry; /* index of next entry to be written by uCode */ - if (priv->ucode_type == UCODE_INIT) - base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); - else - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + base = priv->device_pointers.error_event_table; if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { capacity = iwl_read_targ_mem(priv, base); num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); @@ -1871,12 +1868,11 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) u32 blink1, blink2, ilink1, ilink2; u32 pc, hcmd; + base = priv->device_pointers.error_event_table; if (priv->ucode_type == UCODE_INIT) { - base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); if (!base) base = priv->_agn.init_errlog_ptr; } else { - base = le32_to_cpu(priv->card_alive.error_event_table_ptr); if (!base) base = priv->_agn.inst_errlog_ptr; } @@ -1941,12 +1937,11 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, if (num_events == 0) return pos; + base = priv->device_pointers.log_event_table; if (priv->ucode_type == UCODE_INIT) { - base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); if (!base) base = priv->_agn.init_evtlog_ptr; } else { - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); if (!base) base = priv->_agn.inst_evtlog_ptr; } @@ -2055,13 +2050,12 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, int pos = 0; size_t bufsz = 0; + base = priv->device_pointers.log_event_table; if (priv->ucode_type == UCODE_INIT) { - base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); logsize = priv->_agn.init_evtlog_size; if (!base) base = priv->_agn.init_evtlog_ptr; } else { - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); logsize = priv->_agn.inst_evtlog_size; if (!base) base = priv->_agn.inst_evtlog_ptr; @@ -2415,8 +2409,6 @@ static void __iwl_down(struct iwl_priv *priv) iwl_apm_stop(priv); exit: - memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index a2348ee61fd9..a1a5c1b23096 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -388,54 +388,6 @@ struct iwl_tx_ant_config_cmd { #define UCODE_VALID_OK cpu_to_le32(0x1) #define INITIALIZE_SUBTYPE (9) -/* - * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command) - * - * uCode issues this "initialize alive" notification once the initialization - * uCode image has completed its work, and is ready to load the runtime image. - * This is the *first* "alive" notification that the driver will receive after - * rebooting uCode; the "initialize" alive is indicated by subtype field == 9. - * - * See comments documenting "BSM" (bootstrap state machine). - * - * For 4965, this notification contains important calibration data for - * calculating txpower settings: - * - * 1) Power supply voltage indication. The voltage sensor outputs higher - * values for lower voltage, and vice verse. - * - * 2) Temperature measurement parameters, for each of two channel widths - * (20 MHz and 40 MHz) supported by the radios. Temperature sensing - * is done via one of the receiver chains, and channel width influences - * the results. - * - * 3) Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation, - * for each of 5 frequency ranges. - */ -struct iwl_init_alive_resp { - u8 ucode_minor; - u8 ucode_major; - __le16 reserved1; - u8 sw_rev[8]; - u8 ver_type; - u8 ver_subtype; /* "9" for initialize alive */ - __le16 reserved2; - __le32 log_event_table_ptr; - __le32 error_event_table_ptr; - __le32 timestamp; - __le32 is_valid; - - /* calibration values from "initialize" uCode */ - __le32 voltage; /* signed, higher value is lower voltage */ - __le32 therm_r1[2]; /* signed, 1st for normal, 2nd for HT40 */ - __le32 therm_r2[2]; /* signed */ - __le32 therm_r3[2]; /* signed */ - __le32 therm_r4[2]; /* signed */ - __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups, - * 2 Tx chains */ -} __packed; - - /** * REPLY_ALIVE = 0x1 (response only, not a command) * diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2f7458d3be9c..b4bfcab233ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1285,10 +1285,10 @@ struct iwl_priv { struct iwl_switch_rxon switch_rxon; - /* 1st responses from initialize and runtime uCode images. - * _agn's initialize alive response contains some calibration data. */ - struct iwl_init_alive_resp card_alive_init; - struct iwl_alive_resp card_alive; + struct { + u32 error_event_table; + u32 log_event_table; + } device_pointers; u16 active_rate; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 984a42cfffe9..b5124de99624 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -239,16 +239,16 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, palive->is_valid, palive->ver_type, palive->ver_subtype); + priv->device_pointers.log_event_table = + le32_to_cpu(palive->log_event_table_ptr); + priv->device_pointers.error_event_table = + le32_to_cpu(palive->error_event_table_ptr); + if (palive->ver_subtype == INITIALIZE_SUBTYPE) { IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - memcpy(&priv->card_alive_init, - &pkt->u.alive_frame, - sizeof(struct iwl_init_alive_resp)); pwork = &priv->init_alive_start; } else { IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - memcpy(&priv->card_alive, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); pwork = &priv->alive_start; } -- GitLab From 17445b8c443bb1aaf7f85bcf60676d04be1c467c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:05 -0700 Subject: [PATCH 0604/5560] iwlagn: init cmd_queue earlier We know after loading the ucode whether it will support PAN or not, so we can also initialise the cmd_queue variable much earlier. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b3b1e84c9311..d700860434a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1700,6 +1700,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) } else priv->sta_key_max_num = STA_KEY_MAX_NUM; + if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + else + priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS || (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)) priv->bt_statistics = true; @@ -2518,12 +2523,6 @@ static int __iwl_up(struct iwl_priv *priv) iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - /* must be initialised before iwl_hw_nic_init */ - if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) - priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - else - priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - ret = iwlagn_hw_nic_init(priv); if (ret) { IWL_ERR(priv, "Unable to init nic\n"); -- GitLab From 917b6777b45ac49c436570e36eb09d9b8b84c434 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:06 -0700 Subject: [PATCH 0605/5560] iwlagn: remove BSM clock setting Again, a 4965 specific code path that we no longer need in iwlagn. 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-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.c | 12 ++---------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 6 files changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5c3bb47de3a7..de5b287920b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -249,7 +249,6 @@ static struct iwl_base_params iwl1000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .set_l0s = true, - .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, .led_compensation = 51, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index f87adbf11349..d22e0069801c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -356,7 +356,6 @@ static struct iwl_base_params iwl2000_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, .set_l0s = true, - .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 51, @@ -380,7 +379,6 @@ static struct iwl_base_params iwl2030_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, .set_l0s = true, - .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 57, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index d2f4eb3f4b38..de0e86a5d2f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -488,7 +488,6 @@ static struct iwl_base_params iwl5000_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .set_l0s = true, - .use_bsm = false, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c1f8d1d2b721..be2dbf7bd808 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -459,7 +459,6 @@ static struct iwl_base_params iwl6000_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, .set_l0s = true, - .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 51, @@ -482,7 +481,6 @@ static struct iwl_base_params iwl6050_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, .set_l0s = true, - .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, .led_compensation = 51, @@ -504,7 +502,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, .set_l0s = true, - .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 57, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 6e9829fd6c03..c46be36b9e2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1105,21 +1105,13 @@ int iwl_apm_init(struct iwl_priv *priv) } /* - * Enable DMA and BSM (if used) clocks, wait for them to stabilize. - * BSM (Boostrap State Machine) is only in 3945 and 4965; - * later devices (i.e. 5000 and later) have non-volatile SRAM, - * and don't need BSM to restore data after power-saving sleep. + * Enable DMA clock and wait for it to stabilize. * * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - if (priv->cfg->base_params->use_bsm) - iwl_write_prph(priv, APMG_CLK_EN_REG, - APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); - else - iwl_write_prph(priv, APMG_CLK_EN_REG, - APMG_CLK_VAL_DMA_CLK_RQT); + iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(20); /* Disable L1-Active */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7b9f64ea9662..ada76af124a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -283,7 +283,6 @@ struct iwl_base_params { /* for iwl_apm_init() */ u32 pll_cfg_val; bool set_l0s; - bool use_bsm; const u16 max_ll_items; const bool shadow_ram_support; -- GitLab From bc255930639122d788d1b6ce10d3c01cc2946398 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:07 -0700 Subject: [PATCH 0606/5560] iwlagn: remove hw_wa_rev The variable is never used. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d700860434a5..55a1d65c4baf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3688,7 +3688,6 @@ struct ieee80211_ops iwlagn_hw_ops = { static void iwl_hw_detect(struct iwl_priv *priv) { priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); - priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); priv->rev_id = priv->pci_dev->revision; IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index b4bfcab233ab..2c2d5b00a345 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1254,7 +1254,6 @@ struct iwl_priv { /* pci hardware address support */ void __iomem *hw_base; u32 hw_rev; - u32 hw_wa_rev; u8 rev_id; /* microcode/device supports multiple contexts */ -- GitLab From e98a130259ed6f88bc2833fa525b10453c92c047 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:08 -0700 Subject: [PATCH 0607/5560] iwlagn: remove hw_rev The hw_rev variable is used only during init, so there's no need to keep it around. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 11 ++++++----- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-eeprom.c | 8 ++++---- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 55a1d65c4baf..c3306bae0f1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3685,11 +3685,11 @@ struct ieee80211_ops iwlagn_hw_ops = { .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, }; -static void iwl_hw_detect(struct iwl_priv *priv) +static u32 iwl_hw_detect(struct iwl_priv *priv) { - priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); priv->rev_id = priv->pci_dev->revision; IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); + return _iwl_read32(priv, CSR_HW_REV); } static int iwl_set_hw_params(struct iwl_priv *priv) @@ -3740,6 +3740,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); unsigned long flags; u16 pci_cmd, num_mac; + u32 hw_rev; /************************ * 1. Allocating HW data @@ -3885,9 +3886,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - iwl_hw_detect(priv); + hw_rev = iwl_hw_detect(priv); IWL_INFO(priv, "Detected %s, REV=0x%X\n", - priv->cfg->name, priv->hw_rev); + priv->cfg->name, hw_rev); /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ @@ -3903,7 +3904,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 4. Read EEPROM *****************/ /* Read the EEPROM */ - err = iwl_eeprom_init(priv); + err = iwl_eeprom_init(priv, hw_rev); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); goto out_iounmap; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2c2d5b00a345..1779d603e3e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1253,7 +1253,6 @@ struct iwl_priv { /* pci hardware address support */ void __iomem *hw_base; - u32 hw_rev; u8 rev_id; /* microcode/device supports multiple contexts */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index f70d87162e59..4f8c13e9850b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -188,13 +188,13 @@ static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) CSR_OTP_GP_REG_OTP_ACCESS_MODE); } -static int iwlcore_get_nvm_type(struct iwl_priv *priv) +static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) { u32 otpgp; int nvm_type; /* OTP only valid for CP/PP and after */ - switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { + switch (hw_rev & CSR_HW_REV_TYPE_MSK) { case CSR_HW_REV_TYPE_NONE: IWL_ERR(priv, "Unknown hardware type\n"); return -ENOENT; @@ -394,7 +394,7 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) * * NOTE: This routine uses the non-debug IO access functions. */ -int iwl_eeprom_init(struct iwl_priv *priv) +int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) { __le16 *e; u32 gp = iwl_read32(priv, CSR_EEPROM_GP); @@ -404,7 +404,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) u16 validblockaddr = 0; u16 cache_addr = 0; - priv->nvm_device_type = iwlcore_get_nvm_type(priv); + priv->nvm_device_type = iwlcore_get_nvm_type(priv, hw_rev); if (priv->nvm_device_type == -ENOENT) return -ENOENT; /* allocate eeprom */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 35bf54b38515..6b4343bd4bd2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -302,7 +302,7 @@ struct iwl_eeprom_ops { }; -int iwl_eeprom_init(struct iwl_priv *priv); +int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); 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); -- GitLab From c2974a1d18832a9fffb2eb389c3878f5c4ed92f1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:09 -0700 Subject: [PATCH 0608/5560] iwlagn: remove rev_id The rev_id variable is only printed, we don't need to store 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 | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c3306bae0f1e..08bad17ca0ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3687,8 +3687,10 @@ struct ieee80211_ops iwlagn_hw_ops = { static u32 iwl_hw_detect(struct iwl_priv *priv) { - priv->rev_id = priv->pci_dev->revision; - IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); + u8 rev_id; + + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); return _iwl_read32(priv, CSR_HW_REV); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1779d603e3e6..54b20d8ac93f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1253,7 +1253,6 @@ struct iwl_priv { /* pci hardware address support */ void __iomem *hw_base; - u8 rev_id; /* microcode/device supports multiple contexts */ u8 valid_contexts; -- GitLab From 0e5884458eeadbb48ab3eb1d5f63b4a53a044a95 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:10 -0700 Subject: [PATCH 0609/5560] iwlagn: remove rxb page bookkeeping We never use the value in alloc_rxb_page, so there's no point in keeping it either. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 - drivers/net/wireless/iwlwifi/iwl-dev.h | 3 --- drivers/net/wireless/iwlwifi/iwl-rx.c | 1 - 3 files changed, 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9a3d69d9b8a4..9e47be6a7393 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -912,7 +912,6 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority) list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; - priv->alloc_rxb_page++; spin_unlock_irqrestore(&rxq->lock, flags); } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 54b20d8ac93f..72133368c1f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1191,7 +1191,6 @@ struct iwl_priv { int frames_count; enum ieee80211_band band; - int alloc_rxb_page; void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); @@ -1609,12 +1608,10 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page) { __free_pages(page, priv->hw_params.rx_page_order); - priv->alloc_rxb_page--; } static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page) { free_pages(page, priv->hw_params.rx_page_order); - priv->alloc_rxb_page--; } #endif /* __iwl_dev_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index b5124de99624..c421f566982f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -898,7 +898,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); ieee80211_rx(priv->hw, skb); - priv->alloc_rxb_page--; rxb->page = NULL; } -- GitLab From 519d8abd358afad825a1b919a2421d76779f23cd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:11 -0700 Subject: [PATCH 0610/5560] iwlagn: remove ISR ops The ISR (interrupt service routine) ops are now no longer necessary since they are the same for all devices this driver now handles. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-2000.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-5000.c | 14 -------------- drivers/net/wireless/iwlwifi/iwl-6000.c | 14 -------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 17 ++++++----------- drivers/net/wireless/iwlwifi/iwl-core.h | 11 ----------- 6 files changed, 6 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index de5b287920b4..1b2799291834 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -209,13 +209,6 @@ static struct iwl_lib_ops iwl1000_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .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-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index d22e0069801c..f602af4b9408 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -292,13 +292,6 @@ static struct iwl_lib_ops iwl2000_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .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-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index de0e86a5d2f7..fb00464cead5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -378,13 +378,6 @@ static struct iwl_lib_ops iwl5000_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .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, }, @@ -440,13 +433,6 @@ static struct iwl_lib_ops iwl5150_lib = { .calib_version = iwlagn_eeprom_calib_version, .query_addr = iwlagn_eeprom_query_addr, }, - .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 be2dbf7bd808..24d105b29aec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -320,13 +320,6 @@ static struct iwl_lib_ops iwl6000_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .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, }, @@ -385,13 +378,6 @@ static struct iwl_lib_ops iwl6030_lib = { .query_addr = iwlagn_eeprom_query_addr, .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, }, - .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 08bad17ca0ed..fd3aed8ed960 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2397,8 +2397,7 @@ static void __iwl_down(struct iwl_priv *priv) STATUS_EXIT_PENDING; /* device going down, Stop using ICT table */ - if (priv->cfg->ops->lib->isr_ops.disable) - priv->cfg->ops->lib->isr_ops.disable(priv); + iwl_disable_ict(priv); iwlagn_txq_ctx_stop(priv); iwlagn_rxq_stop(priv); @@ -2606,8 +2605,7 @@ static void iwl_bg_alive_start(struct work_struct *data) goto unlock; /* enable dram interrupt */ - if (priv->cfg->ops->lib->isr_ops.reset) - priv->cfg->ops->lib->isr_ops.reset(priv); + iwl_reset_ict(priv); iwl_alive_start(priv); unlock: @@ -3958,10 +3956,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_enable_msi(priv->pci_dev); - if (priv->cfg->ops->lib->isr_ops.alloc) - priv->cfg->ops->lib->isr_ops.alloc(priv); + iwl_alloc_isr_ict(priv); - err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, + err = request_irq(priv->pci_dev->irq, iwl_isr_ict, IRQF_SHARED, DRV_NAME, priv); if (err) { IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); @@ -4008,8 +4005,7 @@ 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); - if (priv->cfg->ops->lib->isr_ops.free) - priv->cfg->ops->lib->isr_ops.free(priv); + iwl_free_isr_ict(priv); out_disable_msi: pci_disable_msi(priv->pci_dev); iwl_uninit_drv(priv); @@ -4107,8 +4103,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_uninit_drv(priv); - if (priv->cfg->ops->lib->isr_ops.free) - priv->cfg->ops->lib->isr_ops.free(priv); + iwl_free_isr_ict(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 ada76af124a4..82939f851eb9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -122,14 +122,6 @@ 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); @@ -194,9 +186,6 @@ struct iwl_lib_ops { int (*send_tx_power) (struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv); - /* isr */ - struct iwl_isr_ops isr_ops; - /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; -- GitLab From 02a7fa00a6d145037d549c779ad7692deb504acc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Apr 2011 09:42:12 -0700 Subject: [PATCH 0611/5560] iwlagn: move IO functions out of line This generates a massive reduction in module size: with debug: text data bss dec hex filename 670300 13136 420 683856 a6f50 iwlagn.ko (before) 388347 13136 408 401891 621e3 iwlagn.ko (after) without debug: text data bss dec hex filename 528575 13072 420 542067 84573 iwlagn.ko (before) 294192 13072 408 307672 4b1d8 iwlagn.ko (after) This also removes all the IO debug functionality since it can easily be replaced by tracing, and makes the code unnecessarily complex. I haven't done any CPU utilisation measurements, but given that the hotpaths don't use much IO it is not likely to have a negative impact; in fact, the size reduction will reduce cache pressure which possibly improves performance. Finally, an unused function or two were removed. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 +- drivers/net/wireless/iwlwifi/iwl-debug.h | 2 - drivers/net/wireless/iwlwifi/iwl-eeprom.c | 36 +- drivers/net/wireless/iwlwifi/iwl-io.c | 274 ++++++++++ drivers/net/wireless/iwlwifi/iwl-io.h | 489 +----------------- 8 files changed, 326 insertions(+), 503 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-io.c diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 9d6ee836426c..3652931753e0 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.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-calib.o +iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index c6dd9b755a05..3bcaa10f9929 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -103,7 +103,7 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, EEPROM_SEM_TIMEOUT); if (ret >= 0) { - IWL_DEBUG_IO(priv, + IWL_DEBUG_EEPROM(priv, "Acquired semaphore after %d tries.\n", count+1); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 5187a2c20644..01a6d2fc795c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -561,7 +561,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, * if IWL_DL_IO is set */ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, i + IWLAGN_RTC_INST_LOWER_BOUND); - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + val = iwl_read32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; } @@ -587,9 +587,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, offs < len && errors < 20; offs += sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + val = iwl_read32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { IWL_ERR(priv, "uCode INST section at " "offset 0x%x, is 0x%x, s/b 0x%x\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index fd3aed8ed960..60bfde75ce87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -558,7 +558,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, } /* Set starting address; reads will auto-increment */ - _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr); rmb(); /* @@ -566,13 +566,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT); + time = iwl_read32(priv, HBUS_TARG_MEM_RDAT); if (mode == 0) { trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); } else { - data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + data = iwl_read32(priv, HBUS_TARG_MEM_RDAT); trace_iwlwifi_dev_ucode_cont_event(priv, time, data, ev); } @@ -1963,14 +1963,14 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, iwl_grab_nic_access(priv); /* Set starting address; reads will auto-increment */ - _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr); rmb(); /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT); + time = iwl_read32(priv, HBUS_TARG_MEM_RDAT); if (mode == 0) { /* data, ev */ if (bufsz) { @@ -1984,7 +1984,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, time, ev); } } else { - data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + data = iwl_read32(priv, HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", @@ -3689,7 +3689,7 @@ static u32 iwl_hw_detect(struct iwl_priv *priv) pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); - return _iwl_read32(priv, CSR_HW_REV); + return iwl_read32(priv, CSR_HW_REV); } static int iwl_set_hw_params(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 8489431ceb8b..2824ccbcc1fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -146,7 +146,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) #define IWL_DL_RX (1 << 24) #define IWL_DL_ISR (1 << 25) #define IWL_DL_HT (1 << 26) -#define IWL_DL_IO (1 << 27) /* 0xF0000000 - 0x10000000 */ #define IWL_DL_11H (1 << 28) #define IWL_DL_STATS (1 << 29) @@ -174,7 +173,6 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) #define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) #define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) -#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a) #define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) #define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 4f8c13e9850b..859b94a12297 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -226,15 +226,15 @@ static int iwl_init_otp_access(struct iwl_priv *priv) int ret; /* Enable 40MHz radio clock */ - _iwl_write32(priv, CSR_GP_CNTRL, - _iwl_read32(priv, CSR_GP_CNTRL) | - CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + iwl_write32(priv, CSR_GP_CNTRL, + iwl_read32(priv, CSR_GP_CNTRL) | + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* wait for clock to be ready */ ret = iwl_poll_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - 25000); + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + 25000); if (ret < 0) IWL_ERR(priv, "Time out access OTP\n"); else { @@ -261,17 +261,17 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat u32 r; u32 otpgp; - _iwl_write32(priv, CSR_EEPROM_REG, - CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); + iwl_write32(priv, CSR_EEPROM_REG, + CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); ret = iwl_poll_bit(priv, CSR_EEPROM_REG, - CSR_EEPROM_REG_READ_VALID_MSK, - CSR_EEPROM_REG_READ_VALID_MSK, - IWL_EEPROM_ACCESS_TIMEOUT); + CSR_EEPROM_REG_READ_VALID_MSK, + CSR_EEPROM_REG_READ_VALID_MSK, + IWL_EEPROM_ACCESS_TIMEOUT); if (ret < 0) { IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); return ret; } - r = _iwl_read_direct32(priv, CSR_EEPROM_REG); + r = iwl_read32(priv, CSR_EEPROM_REG); /* check for ECC errors: */ otpgp = iwl_read32(priv, CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { @@ -442,9 +442,9 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ret = -ENOENT; goto done; } - _iwl_write32(priv, CSR_EEPROM_GP, - iwl_read32(priv, CSR_EEPROM_GP) & - ~CSR_EEPROM_GP_IF_OWNER_MSK); + iwl_write32(priv, CSR_EEPROM_GP, + iwl_read32(priv, CSR_EEPROM_GP) & + ~CSR_EEPROM_GP_IF_OWNER_MSK); iwl_set_bit(priv, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | @@ -471,8 +471,8 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) for (addr = 0; addr < sz; addr += sizeof(u16)) { u32 r; - _iwl_write32(priv, CSR_EEPROM_REG, - CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); + iwl_write32(priv, CSR_EEPROM_REG, + CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); ret = iwl_poll_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, @@ -482,7 +482,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); goto done; } - r = _iwl_read_direct32(priv, CSR_EEPROM_REG); + r = iwl_read32(priv, CSR_EEPROM_REG); e[addr / 2] = cpu_to_le16(r >> 16); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c new file mode 100644 index 000000000000..51337416e4ca --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -0,0 +1,274 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * 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-io.h" + +#define IWL_POLL_INTERVAL 10 /* microseconds */ + +static inline void __iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) +{ + iwl_write32(priv, reg, iwl_read32(priv, reg) | mask); +} + +static inline void __iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) +{ + iwl_write32(priv, reg, iwl_read32(priv, reg) & ~mask); +} + +void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + __iwl_set_bit(priv, reg, mask); + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + __iwl_clear_bit(priv, reg, mask); + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +int iwl_poll_bit(struct iwl_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int t = 0; + + do { + if ((iwl_read32(priv, addr) & mask) == (bits & mask)) + return t; + udelay(IWL_POLL_INTERVAL); + t += IWL_POLL_INTERVAL; + } while (t < timeout); + + return -ETIMEDOUT; +} + +int iwl_grab_nic_access(struct iwl_priv *priv) +{ + int ret; + u32 val; + + lockdep_assert_held(&priv->reg_lock); + + /* this bit wakes up the NIC */ + __iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + + /* + * These bits say the device is running, and should keep running for + * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), + * but they do not indicate that embedded SRAM is restored yet; + * 3945 and 4965 have volatile SRAM, and must save/restore contents + * to/from host DRAM when sleeping/waking for power-saving. + * Each direction takes approximately 1/4 millisecond; with this + * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a + * series of register accesses are expected (e.g. reading Event Log), + * to keep device from sleeping. + * + * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that + * SRAM is okay/restored. We don't check that here because this call + * is just for hardware register access; but GP1 MAC_SLEEP check is a + * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). + * + * 5000 series and later (including 1000 series) have non-volatile SRAM, + * and do not save/restore SRAM when power cycling. + */ + ret = iwl_poll_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | + CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); + if (ret < 0) { + val = iwl_read32(priv, CSR_GP_CNTRL); + IWL_ERR(priv, + "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); + return -EIO; + } + + return 0; +} + +void iwl_release_nic_access(struct iwl_priv *priv) +{ + lockdep_assert_held(&priv->reg_lock); + __iwl_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); +} + +u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg) +{ + u32 value; + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + iwl_grab_nic_access(priv); + value = iwl_read32(priv, reg); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + + return value; +} + +void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) { + iwl_write32(priv, reg, value); + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask, + int timeout) +{ + int t = 0; + + do { + if ((iwl_read_direct32(priv, addr) & mask) == mask) + return t; + udelay(IWL_POLL_INTERVAL); + t += IWL_POLL_INTERVAL; + } while (t < timeout); + + return -ETIMEDOUT; +} + +static inline u32 __iwl_read_prph(struct iwl_priv *priv, u32 reg) +{ + iwl_write32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + rmb(); + return iwl_read32(priv, HBUS_TARG_PRPH_RDAT); +} + +static inline void __iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val) +{ + iwl_write32(priv, HBUS_TARG_PRPH_WADDR, + ((addr & 0x0000FFFF) | (3 << 24))); + wmb(); + iwl_write32(priv, HBUS_TARG_PRPH_WDAT, val); +} + +u32 iwl_read_prph(struct iwl_priv *priv, u32 reg) +{ + unsigned long flags; + u32 val; + + spin_lock_irqsave(&priv->reg_lock, flags); + iwl_grab_nic_access(priv); + val = __iwl_read_prph(priv, reg); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + return val; +} + +void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) { + __iwl_write_prph(priv, addr, val); + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + iwl_grab_nic_access(priv); + __iwl_write_prph(priv, reg, __iwl_read_prph(priv, reg) | mask); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, + u32 bits, u32 mask) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + iwl_grab_nic_access(priv); + __iwl_write_prph(priv, reg, + (__iwl_read_prph(priv, reg) & mask) | bits); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) +{ + unsigned long flags; + u32 val; + + spin_lock_irqsave(&priv->reg_lock, flags); + iwl_grab_nic_access(priv); + val = __iwl_read_prph(priv, reg); + __iwl_write_prph(priv, reg, (val & ~mask)); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) +{ + unsigned long flags; + u32 value; + + spin_lock_irqsave(&priv->reg_lock, flags); + iwl_grab_nic_access(priv); + + iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr); + rmb(); + value = iwl_read32(priv, HBUS_TARG_MEM_RDAT); + + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + return value; +} + +void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) { + iwl_write32(priv, HBUS_TARG_MEM_WADDR, addr); + wmb(); + iwl_write32(priv, HBUS_TARG_MEM_WDAT, val); + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, flags); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 3ddb2fbe12f9..ab632baf49d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -35,494 +35,47 @@ #include "iwl-debug.h" #include "iwl-devtrace.h" -/* - * IO, register, and NIC memory access functions - * - * NOTE on naming convention and macro usage for these - * - * A single _ prefix before a an access function means that no state - * check or debug information is printed when that function is called. - * - * A double __ prefix before an access function means that state is checked - * and the current line number and caller function name are printed in addition - * to any other debug output. - * - * The non-prefixed name is the #define that maps the caller into a - * #define that provides the caller's name and __LINE__ to the double - * prefix version. - * - * If you wish to call the function without any debug or state checking, - * you should use the single _ prefix version (as is used by dependent IO - * routines, for example _iwl_read_direct32 calls the non-check version of - * _iwl_read32.) - * - * These declarations are *extremely* useful in quickly isolating code deltas - * which result in misconfiguration of the hardware I/O. In combination with - * git-bisect and the IO debug level you can quickly determine the specific - * commit which breaks the IO sequence to the hardware. - * - */ - -static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) +static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val) { trace_iwlwifi_dev_iowrite8(priv, ofs, val); iowrite8(val, priv->hw_base + ofs); } -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv, - u32 ofs, u8 val) -{ - IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l); - _iwl_write8(priv, ofs, val); -} -#define iwl_write8(priv, ofs, val) \ - __iwl_write8(__FILE__, __LINE__, priv, ofs, val) -#else -#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val) -#endif - - -static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) +static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val) { trace_iwlwifi_dev_iowrite32(priv, ofs, val); iowrite32(val, priv->hw_base + ofs); } -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv, - u32 ofs, u32 val) -{ - IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); - _iwl_write32(priv, ofs, val); -} -#define iwl_write32(priv, ofs, val) \ - __iwl_write32(__FILE__, __LINE__, priv, ofs, val) -#else -#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val) -#endif - -static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs) +static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs) { u32 val = ioread32(priv->hw_base + ofs); trace_iwlwifi_dev_ioread32(priv, ofs, val); return val; } -#ifdef CONFIG_IWLWIFI_DEBUG -static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) -{ - IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l); - return _iwl_read32(priv, ofs); -} -#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs) -#else -#define iwl_read32(p, o) _iwl_read32(p, o) -#endif - -#define IWL_POLL_INTERVAL 10 /* microseconds */ -static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr, - u32 bits, u32 mask, int timeout) -{ - int t = 0; - - do { - if ((_iwl_read32(priv, addr) & mask) == (bits & mask)) - return t; - udelay(IWL_POLL_INTERVAL); - t += IWL_POLL_INTERVAL; - } while (t < timeout); - - return -ETIMEDOUT; -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline int __iwl_poll_bit(const char *f, u32 l, - struct iwl_priv *priv, u32 addr, - u32 bits, u32 mask, int timeout) -{ - int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout); - IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", - addr, bits, mask, - unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l); - return ret; -} -#define iwl_poll_bit(priv, addr, bits, mask, timeout) \ - __iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) -#else -#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t) -#endif - -static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) -{ - _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_set_bit(const char *f, u32 l, - struct iwl_priv *priv, u32 reg, u32 mask) -{ - u32 val = _iwl_read32(priv, reg) | mask; - IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); - _iwl_write32(priv, reg, val); -} -static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&p->reg_lock, reg_flags); - __iwl_set_bit(__FILE__, __LINE__, p, r, m); - spin_unlock_irqrestore(&p->reg_lock, reg_flags); -} -#else -static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&p->reg_lock, reg_flags); - _iwl_set_bit(p, r, m); - spin_unlock_irqrestore(&p->reg_lock, reg_flags); -} -#endif - -static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) -{ - _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_clear_bit(const char *f, u32 l, - struct iwl_priv *priv, u32 reg, u32 mask) -{ - u32 val = _iwl_read32(priv, reg) & ~mask; - IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); - _iwl_write32(priv, reg, val); -} -static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&p->reg_lock, reg_flags); - __iwl_clear_bit(__FILE__, __LINE__, p, r, m); - spin_unlock_irqrestore(&p->reg_lock, reg_flags); -} -#else -static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&p->reg_lock, reg_flags); - _iwl_clear_bit(p, r, m); - spin_unlock_irqrestore(&p->reg_lock, reg_flags); -} -#endif - -static inline int _iwl_grab_nic_access(struct iwl_priv *priv) -{ - int ret; - u32 val; - - /* this bit wakes up the NIC */ - _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - - /* - * These bits say the device is running, and should keep running for - * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), - * but they do not indicate that embedded SRAM is restored yet; - * 3945 and 4965 have volatile SRAM, and must save/restore contents - * to/from host DRAM when sleeping/waking for power-saving. - * Each direction takes approximately 1/4 millisecond; with this - * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a - * series of register accesses are expected (e.g. reading Event Log), - * to keep device from sleeping. - * - * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that - * SRAM is okay/restored. We don't check that here because this call - * is just for hardware register access; but GP1 MAC_SLEEP check is a - * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). - * - * 5000 series and later (including 1000 series) have non-volatile SRAM, - * and do not save/restore SRAM when power cycling. - */ - ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, - (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | - CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); - if (ret < 0) { - val = _iwl_read32(priv, CSR_GP_CNTRL); - IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); - _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); - return -EIO; - } - - return 0; -} - -#ifdef CONFIG_IWLWIFI_DEBUG -static inline int __iwl_grab_nic_access(const char *f, u32 l, - struct iwl_priv *priv) -{ - IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l); - return _iwl_grab_nic_access(priv); -} -#define iwl_grab_nic_access(priv) \ - __iwl_grab_nic_access(__FILE__, __LINE__, priv) -#else -#define iwl_grab_nic_access(priv) \ - _iwl_grab_nic_access(priv) -#endif - -static inline void _iwl_release_nic_access(struct iwl_priv *priv) -{ - _iwl_clear_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_release_nic_access(const char *f, u32 l, - struct iwl_priv *priv) -{ - - IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l); - _iwl_release_nic_access(priv); -} -#define iwl_release_nic_access(priv) \ - __iwl_release_nic_access(__FILE__, __LINE__, priv) -#else -#define iwl_release_nic_access(priv) \ - _iwl_release_nic_access(priv) -#endif - -static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg) -{ - return _iwl_read32(priv, reg); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline u32 __iwl_read_direct32(const char *f, u32 l, - struct iwl_priv *priv, u32 reg) -{ - u32 value = _iwl_read_direct32(priv, reg); - IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value, - f, l); - return value; -} -static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg) -{ - u32 value; - unsigned long reg_flags; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return value; -} - -#else -static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg) -{ - u32 value; - unsigned long reg_flags; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - value = _iwl_read_direct32(priv, reg); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return value; - -} -#endif - -static inline void _iwl_write_direct32(struct iwl_priv *priv, - u32 reg, u32 value) -{ - _iwl_write32(priv, reg, value); -} -static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - if (!iwl_grab_nic_access(priv)) { - _iwl_write_direct32(priv, reg, value); - iwl_release_nic_access(priv); - } - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} - -static inline void iwl_write_reg_buf(struct iwl_priv *priv, - u32 reg, u32 len, u32 *values) -{ - u32 count = sizeof(u32); - - if ((priv != NULL) && (values != NULL)) { - for (; 0 < len; len -= count, reg += count, values++) - iwl_write_direct32(priv, reg, *values); - } -} - -static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, - u32 mask, int timeout) -{ - int t = 0; - - do { - if ((iwl_read_direct32(priv, addr) & mask) == mask) - return t; - udelay(IWL_POLL_INTERVAL); - t += IWL_POLL_INTERVAL; - } while (t < timeout); - - return -ETIMEDOUT; -} - -#ifdef CONFIG_IWLWIFI_DEBUG -static inline int __iwl_poll_direct_bit(const char *f, u32 l, - struct iwl_priv *priv, - u32 addr, u32 mask, int timeout) -{ - int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout); - - if (unlikely(ret == -ETIMEDOUT)) - IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - " - "timedout - %s %d\n", addr, mask, f, l); - else - IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " - "- %s %d\n", addr, mask, ret, f, l); - return ret; -} -#define iwl_poll_direct_bit(priv, addr, mask, timeout) \ - __iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) -#else -#define iwl_poll_direct_bit _iwl_poll_direct_bit -#endif - -static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg) -{ - _iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); - rmb(); - return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT); -} -static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg) -{ - unsigned long reg_flags; - u32 val; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - val = _iwl_read_prph(priv, reg); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return val; -} - -static inline void _iwl_write_prph(struct iwl_priv *priv, - u32 addr, u32 val) -{ - _iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR, - ((addr & 0x0000FFFF) | (3 << 24))); - wmb(); - _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); -} - -static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val) -{ - unsigned long reg_flags; +void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask); +void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask); - spin_lock_irqsave(&priv->reg_lock, reg_flags); - if (!iwl_grab_nic_access(priv)) { - _iwl_write_prph(priv, addr, val); - iwl_release_nic_access(priv); - } - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} +int iwl_poll_bit(struct iwl_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout); +int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask, + int timeout); -#define _iwl_set_bits_prph(priv, reg, mask) \ - _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask)) +int iwl_grab_nic_access(struct iwl_priv *priv); +void iwl_release_nic_access(struct iwl_priv *priv); -static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) -{ - unsigned long reg_flags; +u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg); +void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value); - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - _iwl_set_bits_prph(priv, reg, mask); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} -#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \ - _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits)) +u32 iwl_read_prph(struct iwl_priv *priv, u32 reg); +void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val); +void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); +void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, + u32 bits, u32 mask); +void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); -static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, - u32 bits, u32 mask) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - _iwl_set_bits_mask_prph(priv, reg, bits, mask); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} - -static inline void iwl_clear_bits_prph(struct iwl_priv - *priv, u32 reg, u32 mask) -{ - unsigned long reg_flags; - u32 val; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - val = _iwl_read_prph(priv, reg); - _iwl_write_prph(priv, reg, (val & ~mask)); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} - -static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) -{ - unsigned long reg_flags; - u32 value; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - - _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); - rmb(); - value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return value; -} - -static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - if (!iwl_grab_nic_access(priv)) { - _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); - wmb(); - _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); - iwl_release_nic_access(priv); - } - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} - -static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr, - u32 len, u32 *values) -{ - unsigned long reg_flags; - - spin_lock_irqsave(&priv->reg_lock, reg_flags); - if (!iwl_grab_nic_access(priv)) { - _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); - wmb(); - for (; 0 < len; len -= sizeof(u32), values++) - _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values); - - iwl_release_nic_access(priv); - } - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); -} +u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr); +void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val); #endif -- GitLab From 146095557b01cf5ff5d66554d96cbb8133d94eb9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 5 Apr 2011 10:49:03 -0700 Subject: [PATCH 0612/5560] cfg80211: fix regulatory restore upon user hints When we restore regulatory settings its possible CRDA will not reply because of a bogus user entry. In this case the bogus entry will prevent any further processing on cfg80211 for regulatory domains even if we restore regulatory settings. To prevent this we suck out all pending requests when restoring regulatory settings and add them back into the queue after we have queued up the reset work. The impact of not having this applied is that a user with privileges can issue a userspace regulatory hint while we are disasocciating and this would prevent any further processing of regulatory domains. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 3332d5bce317..7b1a89b20ebf 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1744,6 +1744,8 @@ static void restore_regulatory_settings(bool reset_user) { char alpha2[2]; struct reg_beacon *reg_beacon, *btmp; + struct regulatory_request *reg_request, *tmp; + LIST_HEAD(tmp_reg_req_list); mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); @@ -1751,6 +1753,25 @@ static void restore_regulatory_settings(bool reset_user) reset_regdomains(); restore_alpha2(alpha2, reset_user); + /* + * If there's any pending requests we simply + * stash them to a temporary pending queue and + * add then after we've restored regulatory + * settings. + */ + spin_lock(®_requests_lock); + if (!list_empty(®_requests_list)) { + list_for_each_entry_safe(reg_request, tmp, + ®_requests_list, list) { + if (reg_request->initiator != + NL80211_REGDOM_SET_BY_USER) + continue; + list_del(®_request->list); + list_add_tail(®_request->list, &tmp_reg_req_list); + } + } + spin_unlock(®_requests_lock); + /* Clear beacon hints */ spin_lock_bh(®_pending_beacons_lock); if (!list_empty(®_pending_beacons)) { @@ -1785,8 +1806,31 @@ static void restore_regulatory_settings(bool reset_user) */ if (is_an_alpha2(alpha2)) regulatory_hint_user(user_alpha2); -} + if (list_empty(&tmp_reg_req_list)) + return; + + mutex_lock(&cfg80211_mutex); + mutex_lock(®_mutex); + + spin_lock(®_requests_lock); + list_for_each_entry_safe(reg_request, tmp, &tmp_reg_req_list, list) { + REG_DBG_PRINT("Adding request for country %c%c back " + "into the queue\n", + reg_request->alpha2[0], + reg_request->alpha2[1]); + list_del(®_request->list); + list_add_tail(®_request->list, ®_requests_list); + } + spin_unlock(®_requests_lock); + + mutex_unlock(®_mutex); + mutex_unlock(&cfg80211_mutex); + + REG_DBG_PRINT("Kicking the queue\n"); + + schedule_work(®_work); +} void regulatory_hint_disconnect(void) { -- GitLab From a90c7a313a1c5b4fc99f987a2ae8f92ab0ae35c7 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 5 Apr 2011 10:49:04 -0700 Subject: [PATCH 0613/5560] cfg80211: add a timer for invalid user reg hints We have no other option but to inform userspace that we have queued up their regulatory hint request when we are given one given that nl80211 operates atomically on user requests. The best we can do is accept the request, and add a delayed work item for processing failure and cancel it if we succeeed. Upon failure we restore the regulatory settings and ignore the user input. This fixes this reported bug: https://bugzilla.kernel.org/show_bug.cgi?id=28112 Reported-by: gregoryx.alagnou@intel.com Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7b1a89b20ebf..2714379ce2d6 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -106,6 +106,9 @@ struct reg_beacon { static void reg_todo(struct work_struct *work); static DECLARE_WORK(reg_work, reg_todo); +static void reg_timeout_work(struct work_struct *work); +static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work); + /* 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, @@ -1330,6 +1333,9 @@ static void reg_set_request_processed(void) need_more_processing = true; spin_unlock(®_requests_lock); + if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) + cancel_delayed_work_sync(®_timeout); + if (need_more_processing) schedule_work(®_work); } @@ -1440,8 +1446,17 @@ static void reg_process_hint(struct regulatory_request *reg_request) r = __regulatory_hint(wiphy, reg_request); /* This is required so that the orig_* parameters are saved */ if (r == -EALREADY && wiphy && - wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) + wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { wiphy_update_regulatory(wiphy, initiator); + return; + } + + /* + * We only time out user hints, given that they should be the only + * source of bogus requests. + */ + if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER) + schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); } /* @@ -2169,6 +2184,13 @@ void reg_device_remove(struct wiphy *wiphy) mutex_unlock(®_mutex); } +static void reg_timeout_work(struct work_struct *work) +{ + REG_DBG_PRINT("Timeout while waiting for CRDA to reply, " + "restoring regulatory settings"); + restore_regulatory_settings(true); +} + int __init regulatory_init(void) { int err = 0; @@ -2222,6 +2244,7 @@ void /* __init_or_exit */ regulatory_exit(void) struct reg_beacon *reg_beacon, *btmp; cancel_work_sync(®_work); + cancel_delayed_work_sync(®_timeout); mutex_lock(&cfg80211_mutex); mutex_lock(®_mutex); -- GitLab From 48454079c2d4b9ee65c570a22c5fdfe1827996a4 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 00:22:30 -0300 Subject: [PATCH 0614/5560] Bluetooth: Create struct l2cap_chan struct l2cap_chan cames to create a clear separation between what properties and data belongs to the L2CAP channel and what belongs to the socket. By now we just fold the struct sock * in struct l2cap_chan as all the channel info is struct l2cap_pinfo today. In the next commits we will see a move of channel stuff to struct l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 18 ++- net/bluetooth/l2cap_core.c | 247 ++++++++++++++++++++++------------ net/bluetooth/l2cap_sock.c | 6 +- 3 files changed, 175 insertions(+), 96 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 2b9ca0d5c4a0..6378bcc94e2b 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -276,9 +276,16 @@ struct l2cap_conn_param_update_rsp { #define L2CAP_CONN_PARAM_ACCEPTED 0x0000 #define L2CAP_CONN_PARAM_REJECTED 0x0001 -/* ----- L2CAP connections ----- */ +/* ----- L2CAP channels and connections ----- */ + +struct l2cap_chan { + struct sock *sk; + struct l2cap_chan *next_c; + struct l2cap_chan *prev_c; +}; + struct l2cap_chan_list { - struct sock *head; + struct l2cap_chan *head; rwlock_t lock; }; @@ -317,7 +324,7 @@ struct sock_del_list { #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 -/* ----- L2CAP channel and socket info ----- */ +/* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) #define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue) #define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue) @@ -389,8 +396,7 @@ struct l2cap_pinfo { struct work_struct busy_work; struct srej_list srej_l; struct l2cap_conn *conn; - struct sock *next_c; - struct sock *prev_c; + struct l2cap_chan *chan; }; #define L2CAP_CONF_REQ_SENT 0x01 @@ -471,7 +477,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent); struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err); -void l2cap_chan_del(struct sock *sk, int err); +void l2cap_chan_del(struct l2cap_chan *chan, int err); int l2cap_do_connect(struct sock *sk); #endif /* __L2CAP_H */ diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c3cebed205cc..e49d8f7b80a5 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -74,58 +74,58 @@ 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 channels ---- */ -static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) +static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) { - struct sock *s; - for (s = l->head; s; s = l2cap_pi(s)->next_c) { - if (l2cap_pi(s)->dcid == cid) + struct l2cap_chan *c; + for (c = l->head; c; c = c->next_c) { + if (l2cap_pi(c->sk)->dcid == cid) break; } - return s; + return c; } -static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) +static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) { - struct sock *s; - for (s = l->head; s; s = l2cap_pi(s)->next_c) { - if (l2cap_pi(s)->scid == cid) + struct l2cap_chan *c; + for (c = l->head; c; c = c->next_c) { + if (l2cap_pi(c->sk)->scid == cid) break; } - return s; + return c; } /* Find channel with given SCID. * Returns locked socket */ -static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) +static inline struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) { - struct sock *s; + struct l2cap_chan *c; read_lock(&l->lock); - s = __l2cap_get_chan_by_scid(l, cid); - if (s) - bh_lock_sock(s); + c = __l2cap_get_chan_by_scid(l, cid); + if (c) + bh_lock_sock(c->sk); read_unlock(&l->lock); - return s; + return c; } -static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) +static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) { - struct sock *s; - for (s = l->head; s; s = l2cap_pi(s)->next_c) { - if (l2cap_pi(s)->ident == ident) + struct l2cap_chan *c; + for (c = l->head; c; c = c->next_c) { + if (l2cap_pi(c->sk)->ident == ident) break; } - return s; + return c; } -static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) +static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) { - struct sock *s; + struct l2cap_chan *c; read_lock(&l->lock); - s = __l2cap_get_chan_by_ident(l, ident); - if (s) - bh_lock_sock(s); + c = __l2cap_get_chan_by_ident(l, ident); + if (c) + bh_lock_sock(c->sk); read_unlock(&l->lock); - return s; + return c; } static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) @@ -140,38 +140,52 @@ static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) return 0; } -static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk) +static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) +{ + struct l2cap_chan *chan; + + chan = kzalloc(sizeof(*chan), GFP_ATOMIC); + if (!chan) + return NULL; + + chan->sk = sk; + + return chan; +} + +static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct l2cap_chan *chan) { - sock_hold(sk); + sock_hold(chan->sk); if (l->head) - l2cap_pi(l->head)->prev_c = sk; + l->head->prev_c = chan; - l2cap_pi(sk)->next_c = l->head; - l2cap_pi(sk)->prev_c = NULL; - l->head = sk; + chan->next_c = l->head; + chan->prev_c = NULL; + l->head = chan; } -static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk) +static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct l2cap_chan *chan) { - struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c; + struct l2cap_chan *next = chan->next_c, *prev = chan->prev_c; write_lock_bh(&l->lock); - if (sk == l->head) + if (chan == l->head) l->head = next; if (next) - l2cap_pi(next)->prev_c = prev; + next->prev_c = prev; if (prev) - l2cap_pi(prev)->next_c = next; + prev->next_c = next; write_unlock_bh(&l->lock); - __sock_put(sk); + __sock_put(chan->sk); } -static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) +static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { struct l2cap_chan_list *l = &conn->chan_list; + struct sock *sk = chan->sk; BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); @@ -203,13 +217,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } - __l2cap_chan_link(l, sk); + __l2cap_chan_link(l, chan); } /* Delete channel. * Must be called on the locked socket. */ -void l2cap_chan_del(struct sock *sk, int err) +void l2cap_chan_del(struct l2cap_chan *chan, int err) { + struct sock *sk = chan->sk; struct l2cap_conn *conn = l2cap_pi(sk)->conn; struct sock *parent = bt_sk(sk)->parent; @@ -219,7 +234,7 @@ void l2cap_chan_del(struct sock *sk, int err) if (conn) { /* Unlink from channel list */ - l2cap_chan_unlink(&conn->chan_list, sk); + l2cap_chan_unlink(&conn->chan_list, chan); l2cap_pi(sk)->conn = NULL; hci_conn_put(conn->hcon); } @@ -253,6 +268,8 @@ void l2cap_chan_del(struct sock *sk, int err) kfree(l); } } + + kfree(chan); } static inline u8 l2cap_get_auth_type(struct sock *sk) @@ -487,7 +504,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) { struct l2cap_chan_list *l = &conn->chan_list; struct sock_del_list del, *tmp1, *tmp2; - struct sock *sk; + struct l2cap_chan *chan; BT_DBG("conn %p", conn); @@ -495,7 +512,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn) read_lock(&l->lock); - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { + for (chan = l->head; chan; chan = chan->next_c) { + struct sock *sk = chan->sk; bh_lock_sock(sk); if (sk->sk_type != SOCK_SEQPACKET && @@ -622,6 +640,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) { struct l2cap_chan_list *list = &conn->chan_list; struct sock *parent, *uninitialized_var(sk); + struct l2cap_chan *chan; BT_DBG(""); @@ -641,6 +660,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) if (!sk) goto clean; + chan = l2cap_chan_alloc(sk); + if (!chan) { + l2cap_sock_kill(sk); + goto clean; + } + write_lock_bh(&list->lock); hci_conn_hold(conn->hcon); @@ -651,7 +676,9 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) bt_accept_enqueue(parent, sk); - __l2cap_chan_add(conn, sk); + __l2cap_chan_add(conn, chan); + + l2cap_pi(sk)->chan = chan; l2cap_sock_set_timer(sk, sk->sk_sndtimeo); @@ -667,7 +694,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) static void l2cap_conn_ready(struct l2cap_conn *conn) { struct l2cap_chan_list *l = &conn->chan_list; - struct sock *sk; + struct l2cap_chan *chan; BT_DBG("conn %p", conn); @@ -676,7 +703,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) read_lock(&l->lock); - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { + for (chan = l->head; chan; chan = chan->next_c) { + struct sock *sk = chan->sk; bh_lock_sock(sk); if (conn->hcon->type == LE_LINK) { @@ -703,13 +731,14 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) { struct l2cap_chan_list *l = &conn->chan_list; - struct sock *sk; + struct l2cap_chan *chan; BT_DBG("conn %p", conn); read_lock(&l->lock); - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { + for (chan = l->head; chan; chan = chan->next_c) { + struct sock *sk = chan->sk; if (l2cap_pi(sk)->force_reliable) sk->sk_err = err; } @@ -768,6 +797,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) static void l2cap_conn_del(struct hci_conn *hcon, int err) { struct l2cap_conn *conn = hcon->l2cap_data; + struct l2cap_chan *chan; struct sock *sk; if (!conn) @@ -778,9 +808,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) kfree_skb(conn->rx_skb); /* Kill channels */ - while ((sk = conn->chan_list.head)) { + while ((chan = conn->chan_list.head)) { + sk = chan->sk; bh_lock_sock(sk); - l2cap_chan_del(sk, err); + l2cap_chan_del(chan, err); bh_unlock_sock(sk); l2cap_sock_kill(sk); } @@ -792,11 +823,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) kfree(conn); } -static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk) +static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { struct l2cap_chan_list *l = &conn->chan_list; write_lock_bh(&l->lock); - __l2cap_chan_add(conn, sk); + __l2cap_chan_add(conn, chan); write_unlock_bh(&l->lock); } @@ -837,6 +868,7 @@ int l2cap_do_connect(struct sock *sk) bdaddr_t *src = &bt_sk(sk)->src; bdaddr_t *dst = &bt_sk(sk)->dst; struct l2cap_conn *conn; + struct l2cap_chan *chan; struct hci_conn *hcon; struct hci_dev *hdev; __u8 auth_type; @@ -872,10 +904,19 @@ int l2cap_do_connect(struct sock *sk) goto done; } + chan = l2cap_chan_alloc(sk); + if (!chan) { + hci_conn_put(hcon); + err = -ENOMEM; + goto done; + } + /* Update source addr of the socket */ bacpy(src, conn->src); - l2cap_chan_add(conn, sk); + l2cap_chan_add(conn, chan); + + l2cap_pi(sk)->chan = chan; sk->sk_state = BT_CONNECT; l2cap_sock_set_timer(sk, sk->sk_sndtimeo); @@ -1387,12 +1428,13 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { struct l2cap_chan_list *l = &conn->chan_list; struct sk_buff *nskb; - struct sock *sk; + struct l2cap_chan *chan; BT_DBG("conn %p", conn); read_lock(&l->lock); - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { + for (chan = l->head; chan; chan = chan->next_c) { + struct sock *sk = chan->sk; if (sk->sk_type != SOCK_RAW) continue; @@ -1976,6 +2018,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd struct l2cap_chan_list *list = &conn->chan_list; struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; + struct l2cap_chan *chan; struct sock *parent, *sk = NULL; int result, status = L2CAP_CS_NO_INFO; @@ -2013,6 +2056,12 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd if (!sk) goto response; + chan = l2cap_chan_alloc(sk); + if (!chan) { + l2cap_sock_kill(sk); + goto response; + } + write_lock_bh(&list->lock); /* Check if we already have channel with that dcid */ @@ -2033,7 +2082,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd bt_accept_enqueue(parent, sk); - __l2cap_chan_add(conn, sk); + __l2cap_chan_add(conn, chan); + + l2cap_pi(sk)->chan = chan; + dcid = l2cap_pi(sk)->scid; l2cap_sock_set_timer(sk, sk->sk_sndtimeo); @@ -2105,6 +2157,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd { struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; u16 scid, dcid, result, status; + struct l2cap_chan *chan; struct sock *sk; u8 req[128]; @@ -2116,15 +2169,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); if (scid) { - sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); - if (!sk) + chan = l2cap_get_chan_by_scid(&conn->chan_list, scid); + if (!chan) return -EFAULT; } else { - sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); - if (!sk) + chan = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); + if (!chan) return -EFAULT; } + sk = chan->sk; + switch (result) { case L2CAP_CR_SUCCESS: sk->sk_state = BT_CONFIG; @@ -2155,7 +2210,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd break; } - l2cap_chan_del(sk, ECONNREFUSED); + l2cap_chan_del(chan, ECONNREFUSED); break; } @@ -2179,6 +2234,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; u16 dcid, flags; u8 rsp[64]; + struct l2cap_chan *chan; struct sock *sk; int len; @@ -2187,10 +2243,12 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); - sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); - if (!sk) + chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid); + if (!chan) return -ENOENT; + sk = chan->sk; + if (sk->sk_state != BT_CONFIG) { struct l2cap_cmd_rej rej; @@ -2269,6 +2327,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr { struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; u16 scid, flags, result; + struct l2cap_chan *chan; struct sock *sk; int len = cmd->len - sizeof(*rsp); @@ -2279,10 +2338,12 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result); - sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); - if (!sk) + chan = l2cap_get_chan_by_scid(&conn->chan_list, scid); + if (!chan) return 0; + sk = chan->sk; + switch (result) { case L2CAP_CONF_SUCCESS: l2cap_conf_rfc_get(sk, rsp->data, len); @@ -2349,6 +2410,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; struct l2cap_disconn_rsp rsp; u16 dcid, scid; + struct l2cap_chan *chan; struct sock *sk; scid = __le16_to_cpu(req->scid); @@ -2356,10 +2418,12 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); - sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); - if (!sk) + chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid); + if (!chan) return 0; + sk = chan->sk; + rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp); @@ -2375,7 +2439,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd return 0; } - l2cap_chan_del(sk, ECONNRESET); + l2cap_chan_del(chan, ECONNRESET); bh_unlock_sock(sk); l2cap_sock_kill(sk); @@ -2386,6 +2450,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd { struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; u16 dcid, scid; + struct l2cap_chan *chan; struct sock *sk; scid = __le16_to_cpu(rsp->scid); @@ -2393,10 +2458,12 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); - sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); - if (!sk) + chan = l2cap_get_chan_by_scid(&conn->chan_list, scid); + if (!chan) return 0; + sk = chan->sk; + /* don't delete l2cap channel if sk is owned by user */ if (sock_owned_by_user(sk)) { sk->sk_state = BT_DISCONN; @@ -2406,7 +2473,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd return 0; } - l2cap_chan_del(sk, 0); + l2cap_chan_del(chan, 0); bh_unlock_sock(sk); l2cap_sock_kill(sk); @@ -3538,18 +3605,20 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) { + struct l2cap_chan *chan; struct sock *sk; struct l2cap_pinfo *pi; u16 control; u8 tx_seq; int len; - sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); - if (!sk) { + chan = l2cap_get_chan_by_scid(&conn->chan_list, cid); + if (!chan) { BT_DBG("unknown cid 0x%4.4x", cid); goto drop; } + sk = chan->sk; pi = l2cap_pi(sk); BT_DBG("sk %p, len %d", sk, skb->len); @@ -3788,7 +3857,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) { struct l2cap_chan_list *l; struct l2cap_conn *conn = hcon->l2cap_data; - struct sock *sk; + struct l2cap_chan *chan; if (!conn) return 0; @@ -3799,7 +3868,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) read_lock(&l->lock); - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { + for (chan = l->head; chan; chan = chan->next_c) { + struct sock *sk = chan->sk; bh_lock_sock(sk); if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) { @@ -3872,7 +3942,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl if (!(flags & ACL_CONT)) { struct l2cap_hdr *hdr; - struct sock *sk; + struct l2cap_chan *chan; u16 cid; int len; @@ -3910,18 +3980,21 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl goto drop; } - sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); + chan = l2cap_get_chan_by_scid(&conn->chan_list, cid); - if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { - BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)", - len, l2cap_pi(sk)->imtu); - bh_unlock_sock(sk); - l2cap_conn_unreliable(conn, ECOMM); - goto drop; - } + if (chan && chan->sk) { + struct sock *sk = chan->sk; - if (sk) + if (l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { + BT_ERR("Frame exceeding recv MTU (len %d, " + "MTU %d)", len, + l2cap_pi(sk)->imtu); + bh_unlock_sock(sk); + l2cap_conn_unreliable(conn, ECOMM); + goto drop; + } bh_unlock_sock(sk); + } /* Allocate skb for the complete frame (with header) */ conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index f77308e63e58..7df81181a119 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -902,7 +902,7 @@ void __l2cap_sock_close(struct sock *sk, int reason) l2cap_sock_set_timer(sk, sk->sk_sndtimeo); l2cap_send_disconn_req(conn, sk, reason); } else - l2cap_chan_del(sk, reason); + l2cap_chan_del(l2cap_pi(sk)->chan, reason); break; case BT_CONNECT2: @@ -925,12 +925,12 @@ void __l2cap_sock_close(struct sock *sk, int reason) L2CAP_CONN_RSP, sizeof(rsp), &rsp); } - l2cap_chan_del(sk, reason); + l2cap_chan_del(l2cap_pi(sk)->chan, reason); break; case BT_CONNECT: case BT_DISCONN: - l2cap_chan_del(sk, reason); + l2cap_chan_del(l2cap_pi(sk)->chan, reason); break; default: -- GitLab From baa7e1fa6d2870462bd744df1c6ddbd497fe86d6 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 31 Mar 2011 16:17:41 -0300 Subject: [PATCH 0615/5560] Bluetooth: Use struct list_head for L2CAP channels list Use a well known Kernel API is always a good idea than implement your own list. In the future we might use RCU on this list. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 12 +-- net/bluetooth/l2cap_core.c | 188 +++++++++++++++------------------- 2 files changed, 88 insertions(+), 112 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 6378bcc94e2b..ddf4bc56a5b5 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -277,16 +277,9 @@ struct l2cap_conn_param_update_rsp { #define L2CAP_CONN_PARAM_REJECTED 0x0001 /* ----- L2CAP channels and connections ----- */ - struct l2cap_chan { struct sock *sk; - struct l2cap_chan *next_c; - struct l2cap_chan *prev_c; -}; - -struct l2cap_chan_list { - struct l2cap_chan *head; - rwlock_t lock; + struct list_head list; }; struct l2cap_conn { @@ -312,7 +305,8 @@ struct l2cap_conn { __u8 disc_reason; - struct l2cap_chan_list chan_list; + struct list_head chan_l; + rwlock_t chan_lock; }; struct sock_del_list { diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index e49d8f7b80a5..0dbbaf394c13 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -74,66 +74,75 @@ 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 channels ---- */ -static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) +static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) { struct l2cap_chan *c; - for (c = l->head; c; c = c->next_c) { - if (l2cap_pi(c->sk)->dcid == cid) - break; + + list_for_each_entry(c, &conn->chan_l, list) { + struct sock *s = c->sk; + if (l2cap_pi(s)->dcid == cid) + return c; } - return c; + return NULL; + } -static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) +static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) { struct l2cap_chan *c; - for (c = l->head; c; c = c->next_c) { - if (l2cap_pi(c->sk)->scid == cid) - break; + + list_for_each_entry(c, &conn->chan_l, list) { + struct sock *s = c->sk; + if (l2cap_pi(s)->scid == cid) + return c; } - return c; + return NULL; } /* Find channel with given SCID. * Returns locked socket */ -static inline struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) +static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) { struct l2cap_chan *c; - read_lock(&l->lock); - c = __l2cap_get_chan_by_scid(l, cid); + + read_lock(&conn->chan_lock); + c = __l2cap_get_chan_by_scid(conn, cid); if (c) bh_lock_sock(c->sk); - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); return c; } -static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) +static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) { struct l2cap_chan *c; - for (c = l->head; c; c = c->next_c) { - if (l2cap_pi(c->sk)->ident == ident) - break; + + list_for_each_entry(c, &conn->chan_l, list) { + struct sock *s = c->sk; + if (l2cap_pi(s)->ident == ident) + return c; } - return c; + return NULL; } -static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) +static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) { struct l2cap_chan *c; - read_lock(&l->lock); - c = __l2cap_get_chan_by_ident(l, ident); + + read_lock(&conn->chan_lock); + c = __l2cap_get_chan_by_ident(conn, ident); if (c) bh_lock_sock(c->sk); - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); return c; } -static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) +static u16 l2cap_alloc_cid(struct l2cap_conn *conn) { u16 cid = L2CAP_CID_DYN_START; for (; cid < L2CAP_CID_DYN_END; cid++) { - if (!__l2cap_get_chan_by_scid(l, cid)) + if (!__l2cap_get_chan_by_scid(conn, cid)) return cid; } @@ -153,38 +162,8 @@ static struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) return chan; } -static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct l2cap_chan *chan) -{ - sock_hold(chan->sk); - - if (l->head) - l->head->prev_c = chan; - - chan->next_c = l->head; - chan->prev_c = NULL; - l->head = chan; -} - -static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct l2cap_chan *chan) -{ - struct l2cap_chan *next = chan->next_c, *prev = chan->prev_c; - - write_lock_bh(&l->lock); - if (chan == l->head) - l->head = next; - - if (next) - next->prev_c = prev; - if (prev) - prev->next_c = next; - write_unlock_bh(&l->lock); - - __sock_put(chan->sk); -} - static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { - struct l2cap_chan_list *l = &conn->chan_list; struct sock *sk = chan->sk; BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, @@ -202,7 +181,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA; } else { /* Alloc CID for connection-oriented socket */ - l2cap_pi(sk)->scid = l2cap_alloc_cid(l); + l2cap_pi(sk)->scid = l2cap_alloc_cid(conn); l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } } else if (sk->sk_type == SOCK_DGRAM) { @@ -217,7 +196,9 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } - __l2cap_chan_link(l, chan); + sock_hold(sk); + + list_add(&chan->list, &conn->chan_l); } /* Delete channel. @@ -233,8 +214,12 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) BT_DBG("sk %p, conn %p, err %d", sk, conn, err); if (conn) { - /* Unlink from channel list */ - l2cap_chan_unlink(&conn->chan_list, chan); + /* Delete from channel list */ + write_lock_bh(&conn->chan_lock); + list_del(&chan->list); + write_unlock_bh(&conn->chan_lock); + __sock_put(sk); + l2cap_pi(sk)->conn = NULL; hci_conn_put(conn->hcon); } @@ -502,7 +487,6 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) /* ---- L2CAP connections ---- */ static void l2cap_conn_start(struct l2cap_conn *conn) { - struct l2cap_chan_list *l = &conn->chan_list; struct sock_del_list del, *tmp1, *tmp2; struct l2cap_chan *chan; @@ -510,10 +494,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) INIT_LIST_HEAD(&del.list); - read_lock(&l->lock); + read_lock(&conn->chan_lock); - for (chan = l->head; chan; chan = chan->next_c) { + list_for_each_entry(chan, &conn->chan_l, list) { struct sock *sk = chan->sk; + bh_lock_sock(sk); if (sk->sk_type != SOCK_SEQPACKET && @@ -593,7 +578,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) bh_unlock_sock(sk); } - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); list_for_each_entry_safe(tmp1, tmp2, &del.list, list) { bh_lock_sock(tmp1->sk); @@ -638,7 +623,6 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) static void l2cap_le_conn_ready(struct l2cap_conn *conn) { - struct l2cap_chan_list *list = &conn->chan_list; struct sock *parent, *uninitialized_var(sk); struct l2cap_chan *chan; @@ -666,11 +650,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) goto clean; } - write_lock_bh(&list->lock); + write_lock_bh(&conn->chan_lock); hci_conn_hold(conn->hcon); l2cap_sock_init(sk, parent); + bacpy(&bt_sk(sk)->src, conn->src); bacpy(&bt_sk(sk)->dst, conn->dst); @@ -685,7 +670,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) sk->sk_state = BT_CONNECTED; parent->sk_data_ready(parent, 0); - write_unlock_bh(&list->lock); + write_unlock_bh(&conn->chan_lock); clean: bh_unlock_sock(parent); @@ -693,7 +678,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) static void l2cap_conn_ready(struct l2cap_conn *conn) { - struct l2cap_chan_list *l = &conn->chan_list; struct l2cap_chan *chan; BT_DBG("conn %p", conn); @@ -701,10 +685,11 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) if (!conn->hcon->out && conn->hcon->type == LE_LINK) l2cap_le_conn_ready(conn); - read_lock(&l->lock); + read_lock(&conn->chan_lock); - for (chan = l->head; chan; chan = chan->next_c) { + list_for_each_entry(chan, &conn->chan_l, list) { struct sock *sk = chan->sk; + bh_lock_sock(sk); if (conn->hcon->type == LE_LINK) { @@ -724,26 +709,26 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) bh_unlock_sock(sk); } - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); } /* Notify sockets that we cannot guaranty reliability anymore */ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) { - struct l2cap_chan_list *l = &conn->chan_list; struct l2cap_chan *chan; BT_DBG("conn %p", conn); - read_lock(&l->lock); + read_lock(&conn->chan_lock); - for (chan = l->head; chan; chan = chan->next_c) { + list_for_each_entry(chan, &conn->chan_l, list) { struct sock *sk = chan->sk; + if (l2cap_pi(sk)->force_reliable) sk->sk_err = err; } - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); } static void l2cap_info_timeout(unsigned long arg) @@ -783,7 +768,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) conn->feat_mask = 0; spin_lock_init(&conn->lock); - rwlock_init(&conn->chan_list.lock); + rwlock_init(&conn->chan_lock); + + INIT_LIST_HEAD(&conn->chan_l); if (hcon->type != LE_LINK) setup_timer(&conn->info_timer, l2cap_info_timeout, @@ -797,7 +784,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) static void l2cap_conn_del(struct hci_conn *hcon, int err) { struct l2cap_conn *conn = hcon->l2cap_data; - struct l2cap_chan *chan; + struct l2cap_chan *chan, *l; struct sock *sk; if (!conn) @@ -808,7 +795,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) kfree_skb(conn->rx_skb); /* Kill channels */ - while ((chan = conn->chan_list.head)) { + list_for_each_entry_safe(chan, l, &conn->chan_l, list) { sk = chan->sk; bh_lock_sock(sk); l2cap_chan_del(chan, err); @@ -825,10 +812,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { - struct l2cap_chan_list *l = &conn->chan_list; - write_lock_bh(&l->lock); + write_lock_bh(&conn->chan_lock); __l2cap_chan_add(conn, chan); - write_unlock_bh(&l->lock); + write_unlock_bh(&conn->chan_lock); } /* ---- Socket interface ---- */ @@ -1426,14 +1412,13 @@ static void l2cap_chan_ready(struct sock *sk) /* Copy frame to all raw sockets on that connection */ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { - struct l2cap_chan_list *l = &conn->chan_list; struct sk_buff *nskb; struct l2cap_chan *chan; BT_DBG("conn %p", conn); - read_lock(&l->lock); - for (chan = l->head; chan; chan = chan->next_c) { + read_lock(&conn->chan_lock); + list_for_each_entry(chan, &conn->chan_l, list) { struct sock *sk = chan->sk; if (sk->sk_type != SOCK_RAW) continue; @@ -1448,7 +1433,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) if (sock_queue_rcv_skb(sk, nskb)) kfree_skb(nskb); } - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); } /* ---- L2CAP signalling commands ---- */ @@ -2015,7 +2000,6 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { - struct l2cap_chan_list *list = &conn->chan_list; struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; struct l2cap_chan *chan; @@ -2062,11 +2046,11 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd goto response; } - write_lock_bh(&list->lock); + write_lock_bh(&conn->chan_lock); /* Check if we already have channel with that dcid */ - if (__l2cap_get_chan_by_dcid(list, scid)) { - write_unlock_bh(&list->lock); + if (__l2cap_get_chan_by_dcid(conn, scid)) { + write_unlock_bh(&conn->chan_lock); sock_set_flag(sk, SOCK_ZAPPED); l2cap_sock_kill(sk); goto response; @@ -2115,7 +2099,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd status = L2CAP_CS_NO_INFO; } - write_unlock_bh(&list->lock); + write_unlock_bh(&conn->chan_lock); response: bh_unlock_sock(parent); @@ -2169,11 +2153,11 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); if (scid) { - chan = l2cap_get_chan_by_scid(&conn->chan_list, scid); + chan = l2cap_get_chan_by_scid(conn, scid); if (!chan) return -EFAULT; } else { - chan = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); + chan = l2cap_get_chan_by_ident(conn, cmd->ident); if (!chan) return -EFAULT; } @@ -2243,7 +2227,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); - chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid); + chan = l2cap_get_chan_by_scid(conn, dcid); if (!chan) return -ENOENT; @@ -2338,7 +2322,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result); - chan = l2cap_get_chan_by_scid(&conn->chan_list, scid); + chan = l2cap_get_chan_by_scid(conn, scid); if (!chan) return 0; @@ -2418,7 +2402,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); - chan = l2cap_get_chan_by_scid(&conn->chan_list, dcid); + chan = l2cap_get_chan_by_scid(conn, dcid); if (!chan) return 0; @@ -2458,7 +2442,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); - chan = l2cap_get_chan_by_scid(&conn->chan_list, scid); + chan = l2cap_get_chan_by_scid(conn, scid); if (!chan) return 0; @@ -3612,7 +3596,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk u8 tx_seq; int len; - chan = l2cap_get_chan_by_scid(&conn->chan_list, cid); + chan = l2cap_get_chan_by_scid(conn, cid); if (!chan) { BT_DBG("unknown cid 0x%4.4x", cid); goto drop; @@ -3855,21 +3839,19 @@ static inline void l2cap_check_encryption(struct sock *sk, u8 encrypt) static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) { - struct l2cap_chan_list *l; struct l2cap_conn *conn = hcon->l2cap_data; struct l2cap_chan *chan; if (!conn) return 0; - l = &conn->chan_list; - BT_DBG("conn %p", conn); - read_lock(&l->lock); + read_lock(&conn->chan_lock); - for (chan = l->head; chan; chan = chan->next_c) { + list_for_each_entry(chan, &conn->chan_l, list) { struct sock *sk = chan->sk; + bh_lock_sock(sk); if (l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND) { @@ -3923,7 +3905,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) bh_unlock_sock(sk); } - read_unlock(&l->lock); + read_unlock(&conn->chan_lock); return 0; } @@ -3980,7 +3962,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl goto drop; } - chan = l2cap_get_chan_by_scid(&conn->chan_list, cid); + chan = l2cap_get_chan_by_scid(conn, cid); if (chan && chan->sk) { struct sock *sk = chan->sk; -- GitLab From 820ffdb3d25f74fbd553453f461709d52dfa72a2 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 1 Apr 2011 00:35:21 -0300 Subject: [PATCH 0616/5560] Bluetooth: Remove struct del_list As we use struct list_head to keep L2CAP channels list the workaround with del_list is not needed anymore. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 5 ----- net/bluetooth/l2cap_core.c | 24 +++++++----------------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ddf4bc56a5b5..d24b51c3ff8c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -309,11 +309,6 @@ struct l2cap_conn { rwlock_t chan_lock; }; -struct sock_del_list { - struct sock *sk; - struct list_head list; -}; - #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 #define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 #define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0dbbaf394c13..b0aaaa9cf00e 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -487,16 +487,13 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) /* ---- L2CAP connections ---- */ static void l2cap_conn_start(struct l2cap_conn *conn) { - struct sock_del_list del, *tmp1, *tmp2; - struct l2cap_chan *chan; + struct l2cap_chan *chan, *tmp; BT_DBG("conn %p", conn); - INIT_LIST_HEAD(&del.list); - read_lock(&conn->chan_lock); - list_for_each_entry(chan, &conn->chan_l, list) { + list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { struct sock *sk = chan->sk; bh_lock_sock(sk); @@ -520,10 +517,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) conn->feat_mask) && l2cap_pi(sk)->conf_state & L2CAP_CONF_STATE2_DEVICE) { - tmp1 = kzalloc(sizeof(struct sock_del_list), - GFP_ATOMIC); - tmp1->sk = sk; - list_add_tail(&tmp1->list, &del.list); + /* __l2cap_sock_close() calls list_del(chan) + * so release the lock */ + read_unlock_bh(&conn->chan_lock); + __l2cap_sock_close(sk, ECONNRESET); + read_lock_bh(&conn->chan_lock); bh_unlock_sock(sk); continue; } @@ -579,14 +577,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn) } read_unlock(&conn->chan_lock); - - list_for_each_entry_safe(tmp1, tmp2, &del.list, list) { - bh_lock_sock(tmp1->sk); - __l2cap_sock_close(tmp1->sk, ECONNRESET); - bh_unlock_sock(tmp1->sk); - list_del(&tmp1->list); - kfree(tmp1); - } } /* Find socket with cid and source bdaddr. -- GitLab From fc7f8a7ed4543853a99852ca405ea71fabe78946 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 13:59:37 -0300 Subject: [PATCH 0617/5560] Bluetooth: Move ident to struct l2cap_chan ident is chan property, no need to reside on socket. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 4 ++-- net/bluetooth/l2cap_core.c | 38 +++++++++++++++++------------------ net/bluetooth/l2cap_sock.c | 4 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d24b51c3ff8c..81829e5c407d 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -279,6 +279,8 @@ struct l2cap_conn_param_update_rsp { /* ----- L2CAP channels and connections ----- */ struct l2cap_chan { struct sock *sk; + __u8 ident; + struct list_head list; }; @@ -363,8 +365,6 @@ struct l2cap_pinfo { __u16 partial_sdu_len; struct sk_buff *sdu; - __u8 ident; - __u8 tx_win; __u8 max_tx; __u8 remote_tx_win; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b0aaaa9cf00e..6020e1e2f500 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -118,8 +118,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 struct l2cap_chan *c; list_for_each_entry(c, &conn->chan_l, list) { - struct sock *s = c->sk; - if (l2cap_pi(s)->ident == ident) + if (c->ident == ident) return c; } return NULL; @@ -410,8 +409,9 @@ static inline int __l2cap_no_conn_pending(struct sock *sk) return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND); } -static void l2cap_do_start(struct sock *sk) +static void l2cap_do_start(struct l2cap_chan *chan) { + struct sock *sk = chan->sk; struct l2cap_conn *conn = l2cap_pi(sk)->conn; if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { @@ -423,11 +423,11 @@ static void l2cap_do_start(struct sock *sk) req.scid = cpu_to_le16(l2cap_pi(sk)->scid); req.psm = l2cap_pi(sk)->psm; - l2cap_pi(sk)->ident = l2cap_get_ident(conn); + chan->ident = l2cap_get_ident(conn); l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, + sizeof(req), &req); } } else { struct l2cap_info_req req; @@ -529,11 +529,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) req.scid = cpu_to_le16(l2cap_pi(sk)->scid); req.psm = l2cap_pi(sk)->psm; - l2cap_pi(sk)->ident = l2cap_get_ident(conn); + chan->ident = l2cap_get_ident(conn); l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, + sizeof(req), &req); } else if (sk->sk_state == BT_CONNECT2) { struct l2cap_conn_rsp rsp; @@ -558,8 +558,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn) rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); } - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, + sizeof(rsp), &rsp); if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT || rsp.result != L2CAP_CR_SUCCESS) { @@ -694,7 +694,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) sk->sk_state = BT_CONNECTED; sk->sk_state_change(sk); } else if (sk->sk_state == BT_CONNECT) - l2cap_do_start(sk); + l2cap_do_start(chan); bh_unlock_sock(sk); } @@ -904,7 +904,7 @@ int l2cap_do_connect(struct sock *sk) if (l2cap_check_security(sk)) sk->sk_state = BT_CONNECTED; } else - l2cap_do_start(sk); + l2cap_do_start(chan); } err = 0; @@ -2064,7 +2064,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd l2cap_sock_set_timer(sk, sk->sk_sndtimeo); - l2cap_pi(sk)->ident = cmd->ident; + chan->ident = cmd->ident; if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { if (l2cap_check_security(sk)) { @@ -2157,7 +2157,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd switch (result) { case L2CAP_CR_SUCCESS: sk->sk_state = BT_CONFIG; - l2cap_pi(sk)->ident = 0; + chan->ident = 0; l2cap_pi(sk)->dcid = dcid; l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; @@ -3862,10 +3862,10 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) req.scid = cpu_to_le16(l2cap_pi(sk)->scid); req.psm = l2cap_pi(sk)->psm; - l2cap_pi(sk)->ident = l2cap_get_ident(conn); + chan->ident = l2cap_get_ident(conn); l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND; - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req); } else { l2cap_sock_clear_timer(sk); @@ -3888,8 +3888,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.result = cpu_to_le16(result); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, + sizeof(rsp), &rsp); } bh_unlock_sock(sk); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 7df81181a119..cad4bc7d36b2 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -818,7 +818,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, + l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { @@ -921,7 +921,7 @@ void __l2cap_sock_close(struct sock *sk, int reason) rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.result = cpu_to_le16(result); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, + l2cap_send_cmd(conn, l2cap_pi(sk)->chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); } -- GitLab From 73ffa904b78287f6acf8797e040150aa26a4af4a Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 14:16:54 -0300 Subject: [PATCH 0618/5560] Bluetooth: Move conf_{req,rsp} stuff to struct l2cap_chan They are also l2cap_chan specific. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 11 +++---- net/bluetooth/l2cap_core.c | 55 ++++++++++++++++++----------------- net/bluetooth/l2cap_sock.c | 8 ++--- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 81829e5c407d..bf918283712a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -281,6 +281,11 @@ struct l2cap_chan { struct sock *sk; __u8 ident; + __u8 conf_req[64]; + __u8 conf_len; + __u8 num_conf_req; + __u8 num_conf_rsp; + struct list_head list; }; @@ -337,8 +342,6 @@ struct l2cap_pinfo { __u16 omtu; __u16 flush_to; __u8 mode; - __u8 num_conf_req; - __u8 num_conf_rsp; __u8 fcs; __u8 sec_level; @@ -346,8 +349,6 @@ struct l2cap_pinfo { __u8 force_reliable; __u8 flushable; - __u8 conf_req[64]; - __u8 conf_len; __u8 conf_state; __u16 conn_state; @@ -447,7 +448,7 @@ void l2cap_cleanup_sockets(void); u8 l2cap_get_ident(struct l2cap_conn *conn); void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); -int l2cap_build_conf_req(struct sock *sk, void *data); +int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); int __l2cap_wait_ack(struct sock *sk); struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 6020e1e2f500..cb849b51632f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -569,8 +569,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn) l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; + l2cap_build_conf_req(chan, buf), buf); + chan->num_conf_req++; } bh_unlock_sock(sk); @@ -1598,8 +1598,9 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) } } -int l2cap_build_conf_req(struct sock *sk, void *data) +int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_conf_req *req = data; struct l2cap_conf_rfc rfc = { .mode = pi->mode }; @@ -1607,7 +1608,7 @@ int l2cap_build_conf_req(struct sock *sk, void *data) BT_DBG("sk %p", sk); - if (pi->num_conf_req || pi->num_conf_rsp) + if (chan->num_conf_req || chan->num_conf_rsp) goto done; switch (pi->mode) { @@ -1696,20 +1697,20 @@ int l2cap_build_conf_req(struct sock *sk, void *data) return ptr - data; } -static int l2cap_parse_conf_req(struct sock *sk, void *data) +static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); struct l2cap_conf_rsp *rsp = data; void *ptr = rsp->data; - void *req = pi->conf_req; - int len = pi->conf_len; + void *req = chan->conf_req; + int len = chan->conf_len; int type, hint, olen; unsigned long val; struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; u16 mtu = L2CAP_DEFAULT_MTU; u16 result = L2CAP_CONF_SUCCESS; - BT_DBG("sk %p", sk); + BT_DBG("chan %p", chan); while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&req, &type, &olen, &val); @@ -1750,7 +1751,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) } } - if (pi->num_conf_rsp || pi->num_conf_req > 1) + if (chan->num_conf_rsp || chan->num_conf_req > 1) goto done; switch (pi->mode) { @@ -1773,7 +1774,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) result = L2CAP_CONF_UNACCEPT; rfc.mode = pi->mode; - if (pi->num_conf_rsp == 1) + if (chan->num_conf_rsp == 1) return -ECONNREFUSED; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, @@ -1992,7 +1993,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd { struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; - struct l2cap_chan *chan; + struct l2cap_chan *chan = NULL; struct sock *parent, *sk = NULL; int result, status = L2CAP_CS_NO_INFO; @@ -2115,13 +2116,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd L2CAP_INFO_REQ, sizeof(info), &info); } - if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && + if (chan && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && result == L2CAP_CR_SUCCESS) { u8 buf[128]; l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; + l2cap_build_conf_req(chan, buf), buf); + chan->num_conf_req++; } return 0; @@ -2167,8 +2168,8 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, req), req); - l2cap_pi(sk)->num_conf_req++; + l2cap_build_conf_req(chan, req), req); + chan->num_conf_req++; break; case L2CAP_CR_PEND: @@ -2234,7 +2235,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); - if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) { + if (chan->conf_len + len > sizeof(chan->conf_req)) { l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, L2CAP_CONF_REJECT, flags), rsp); @@ -2242,8 +2243,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr } /* Store config. */ - memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len); - l2cap_pi(sk)->conf_len += len; + memcpy(chan->conf_req + chan->conf_len, req->data, len); + chan->conf_len += len; if (flags & 0x0001) { /* Incomplete config. Send empty response. */ @@ -2254,17 +2255,17 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr } /* Complete config. */ - len = l2cap_parse_conf_req(sk, rsp); + len = l2cap_parse_conf_req(chan, rsp); if (len < 0) { l2cap_send_disconn_req(conn, sk, ECONNRESET); goto unlock; } l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); - l2cap_pi(sk)->num_conf_rsp++; + chan->num_conf_rsp++; /* Reset config buffer. */ - l2cap_pi(sk)->conf_len = 0; + chan->conf_len = 0; if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE)) goto unlock; @@ -2288,8 +2289,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr u8 buf[64]; l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; + l2cap_build_conf_req(chan, buf), buf); + chan->num_conf_req++; } unlock: @@ -2324,7 +2325,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr break; case L2CAP_CONF_UNACCEPT: - if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { + if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { char req[64]; if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { @@ -2343,7 +2344,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, len, req); - l2cap_pi(sk)->num_conf_req++; + chan->num_conf_req++; if (result != L2CAP_CONF_SUCCESS) goto done; break; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index cad4bc7d36b2..244475ea045c 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -810,6 +810,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { struct l2cap_conn_rsp rsp; struct l2cap_conn *conn = l2cap_pi(sk)->conn; + struct l2cap_chan *chan = l2cap_pi(sk)->chan; u8 buf[128]; sk->sk_state = BT_CONFIG; @@ -818,7 +819,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->chan->ident, + l2cap_send_cmd(l2cap_pi(sk)->conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { @@ -828,8 +829,8 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); - l2cap_pi(sk)->num_conf_req++; + l2cap_build_conf_req(chan, buf), buf); + chan->num_conf_req++; release_sock(sk); return 0; @@ -1035,7 +1036,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) } /* Default config options */ - pi->conf_len = 0; pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; skb_queue_head_init(TX_QUEUE(sk)); skb_queue_head_init(SREJ_QUEUE(sk)); -- GitLab From 710f9b0a423cad155144742f6497efe5163ed750 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 14:30:37 -0300 Subject: [PATCH 0619/5560] Bluetooth: clean up l2cap_sock_recvmsg() Move some channel specific stuff to l2cap_core.c, this will make things more clear. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 3 +-- net/bluetooth/l2cap_core.c | 28 +++++++++++++++++++++++++++- net/bluetooth/l2cap_sock.c | 25 +------------------------ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index bf918283712a..469241353d78 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -446,9 +446,8 @@ extern struct bt_sock_list l2cap_sk_list; int l2cap_init_sockets(void); void l2cap_cleanup_sockets(void); -u8 l2cap_get_ident(struct l2cap_conn *conn); void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); -int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); +void __l2cap_connect_rsp_defer(struct sock *sk); int __l2cap_wait_ack(struct sock *sk); struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index cb849b51632f..b41e21f46231 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -70,6 +70,7 @@ static void l2cap_busy_work(struct work_struct *work); static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, u8 ident, u16 dlen, void *data); +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); @@ -1598,7 +1599,7 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) } } -int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) +static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) { struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); @@ -1934,6 +1935,31 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla return ptr - data; } +void __l2cap_connect_rsp_defer(struct sock *sk) +{ + struct l2cap_conn_rsp rsp; + struct l2cap_conn *conn = l2cap_pi(sk)->conn; + struct l2cap_chan *chan = l2cap_pi(sk)->chan; + u8 buf[128]; + + sk->sk_state = BT_CONFIG; + + rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); + rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); + l2cap_send_cmd(conn, chan->ident, + L2CAP_CONN_RSP, sizeof(rsp), &rsp); + + if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) + return; + + l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; + l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, + l2cap_build_conf_req(chan, buf), buf); + chan->num_conf_req++; +} + static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) { struct l2cap_pinfo *pi = l2cap_pi(sk); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 244475ea045c..450f57b106b9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -808,30 +808,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms lock_sock(sk); if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { - struct l2cap_conn_rsp rsp; - struct l2cap_conn *conn = l2cap_pi(sk)->conn; - struct l2cap_chan *chan = l2cap_pi(sk)->chan; - u8 buf[128]; - - sk->sk_state = BT_CONFIG; - - rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); - rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); - rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(l2cap_pi(sk)->conn, chan->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); - - if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { - release_sock(sk); - return 0; - } - - l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); - chan->num_conf_req++; - + __l2cap_connect_rsp_defer(sk); release_sock(sk); return 0; } -- GitLab From 525cd1851b9faaadf5ea33e05192b8d22f42487e Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 19:43:39 -0300 Subject: [PATCH 0620/5560] Bluetooth: Move conn_state to struct l2cap_chan This is part of "moving things to l2cap_chan". As one the first move it triggered a big number of changes in the funcions parameters, basically changing the struct sock param to struct l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 5 +- net/bluetooth/l2cap_core.c | 391 ++++++++++++++++++---------------- net/bluetooth/l2cap_sock.c | 16 +- 3 files changed, 217 insertions(+), 195 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 469241353d78..82d5b81a779b 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -286,6 +286,8 @@ struct l2cap_chan { __u8 num_conf_req; __u8 num_conf_rsp; + __u16 conn_state; + struct list_head list; }; @@ -350,7 +352,6 @@ struct l2cap_pinfo { __u8 flushable; __u8 conf_state; - __u16 conn_state; __u8 next_tx_seq; __u8 expected_ack_seq; @@ -456,7 +457,7 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len); void l2cap_do_send(struct sock *sk, struct sk_buff *skb); void l2cap_streaming_send(struct sock *sk); -int l2cap_ertm_send(struct sock *sk); +int l2cap_ertm_send(struct l2cap_chan *chan); void l2cap_sock_set_timer(struct sock *sk, long timeout); void l2cap_sock_clear_timer(struct sock *sk); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b41e21f46231..b5435cd74f99 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -340,10 +340,11 @@ void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *d hci_send_acl(conn->hcon, skb, flags); } -static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) +static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) { struct sk_buff *skb; struct l2cap_hdr *lh; + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); struct l2cap_conn *conn = pi->conn; struct sock *sk = (struct sock *)pi; int count, hlen = L2CAP_HDR_SIZE + 2; @@ -360,14 +361,14 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) count = min_t(unsigned int, conn->mtu, hlen); control |= L2CAP_CTRL_FRAME_TYPE; - if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { + if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { control |= L2CAP_CTRL_FINAL; - pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; + chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; } - if (pi->conn_state & L2CAP_CONN_SEND_PBIT) { + if (chan->conn_state & L2CAP_CONN_SEND_PBIT) { control |= L2CAP_CTRL_POLL; - pi->conn_state &= ~L2CAP_CONN_SEND_PBIT; + chan->conn_state &= ~L2CAP_CONN_SEND_PBIT; } skb = bt_skb_alloc(count, GFP_ATOMIC); @@ -392,17 +393,19 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) hci_send_acl(pi->conn->hcon, skb, flags); } -static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) +static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) { - if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); + + if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { control |= L2CAP_SUPER_RCV_NOT_READY; - pi->conn_state |= L2CAP_CONN_RNR_SENT; + chan->conn_state |= L2CAP_CONN_RNR_SENT; } else control |= L2CAP_SUPER_RCV_READY; control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; - l2cap_send_sframe(pi, control); + l2cap_send_sframe(chan, control); } static inline int __l2cap_no_conn_pending(struct sock *sk) @@ -949,9 +952,10 @@ int __l2cap_wait_ack(struct sock *sk) static void l2cap_monitor_timeout(unsigned long arg) { - struct sock *sk = (void *) arg; + struct l2cap_chan *chan = (void *) arg; + struct sock *sk = chan->sk; - BT_DBG("sk %p", sk); + BT_DBG("chan %p", chan); bh_lock_sock(sk); if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { @@ -963,13 +967,14 @@ static void l2cap_monitor_timeout(unsigned long arg) l2cap_pi(sk)->retry_count++; __mod_monitor_timer(); - l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL); + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); bh_unlock_sock(sk); } static void l2cap_retrans_timeout(unsigned long arg) { - struct sock *sk = (void *) arg; + struct l2cap_chan *chan = (void *) arg; + struct sock *sk = chan->sk; BT_DBG("sk %p", sk); @@ -977,9 +982,9 @@ static void l2cap_retrans_timeout(unsigned long arg) l2cap_pi(sk)->retry_count = 1; __mod_monitor_timer(); - l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; + chan->conn_state |= L2CAP_CONN_WAIT_F; - l2cap_send_rr_or_rnr(l2cap_pi(sk), L2CAP_CTRL_POLL); + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); bh_unlock_sock(sk); } @@ -1040,8 +1045,9 @@ void l2cap_streaming_send(struct sock *sk) } } -static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) +static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); struct sk_buff *skb, *tx_skb; u16 control, fcs; @@ -1069,9 +1075,9 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) bt_cb(skb)->retries++; control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); - if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { + if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { control |= L2CAP_CTRL_FINAL; - pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; + chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; } control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) @@ -1087,9 +1093,10 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) l2cap_do_send(sk, tx_skb); } -int l2cap_ertm_send(struct sock *sk) +int l2cap_ertm_send(struct l2cap_chan *chan) { struct sk_buff *skb, *tx_skb; + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; int nsent = 0; @@ -1112,9 +1119,9 @@ int l2cap_ertm_send(struct sock *sk) control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); control &= L2CAP_CTRL_SAR; - if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { + if (chan->conn_state & L2CAP_CONN_SEND_FBIT) { control |= L2CAP_CTRL_FINAL; - pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; + chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; } control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); @@ -1149,8 +1156,9 @@ int l2cap_ertm_send(struct sock *sk) return nsent; } -static int l2cap_retransmit_frames(struct sock *sk) +static int l2cap_retransmit_frames(struct l2cap_chan *chan) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); int ret; @@ -1158,32 +1166,32 @@ static int l2cap_retransmit_frames(struct sock *sk) sk->sk_send_head = TX_QUEUE(sk)->next; pi->next_tx_seq = pi->expected_ack_seq; - ret = l2cap_ertm_send(sk); + ret = l2cap_ertm_send(chan); return ret; } -static void l2cap_send_ack(struct l2cap_pinfo *pi) +static void l2cap_send_ack(struct l2cap_chan *chan) { - struct sock *sk = (struct sock *)pi; + struct sock *sk = chan->sk; u16 control = 0; - control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control |= l2cap_pi(sk)->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; - if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { + if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { control |= L2CAP_SUPER_RCV_NOT_READY; - pi->conn_state |= L2CAP_CONN_RNR_SENT; - l2cap_send_sframe(pi, control); + chan->conn_state |= L2CAP_CONN_RNR_SENT; + l2cap_send_sframe(chan, control); return; } - if (l2cap_ertm_send(sk) > 0) + if (l2cap_ertm_send(chan) > 0) return; control |= L2CAP_SUPER_RCV_READY; - l2cap_send_sframe(pi, control); + l2cap_send_sframe(chan, control); } -static void l2cap_send_srejtail(struct sock *sk) +static void l2cap_send_srejtail(struct l2cap_chan *chan) { struct srej_list *tail; u16 control; @@ -1191,10 +1199,10 @@ static void l2cap_send_srejtail(struct sock *sk) control = L2CAP_SUPER_SELECT_REJECT; control |= L2CAP_CTRL_FINAL; - tail = list_entry(SREJ_LIST(sk)->prev, struct srej_list, list); + tail = list_entry(SREJ_LIST(chan->sk)->prev, struct srej_list, list); control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; - l2cap_send_sframe(l2cap_pi(sk), control); + l2cap_send_sframe(chan, control); } static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb) @@ -1556,15 +1564,17 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) static void l2cap_ack_timeout(unsigned long arg) { - struct sock *sk = (void *) arg; + struct l2cap_chan *chan = (void *) arg; - bh_lock_sock(sk); - l2cap_send_ack(l2cap_pi(sk)); - bh_unlock_sock(sk); + bh_lock_sock(chan->sk); + l2cap_send_ack(chan); + bh_unlock_sock(chan->sk); } -static inline void l2cap_ertm_init(struct sock *sk) +static inline void l2cap_ertm_init(struct l2cap_chan *chan) { + struct sock *sk = chan->sk; + l2cap_pi(sk)->expected_ack_seq = 0; l2cap_pi(sk)->unacked_frames = 0; l2cap_pi(sk)->buffer_seq = 0; @@ -1572,11 +1582,11 @@ static inline void l2cap_ertm_init(struct sock *sk) l2cap_pi(sk)->frames_sent = 0; setup_timer(&l2cap_pi(sk)->retrans_timer, - l2cap_retrans_timeout, (unsigned long) sk); + l2cap_retrans_timeout, (unsigned long) chan); setup_timer(&l2cap_pi(sk)->monitor_timer, - l2cap_monitor_timeout, (unsigned long) sk); + l2cap_monitor_timeout, (unsigned long) chan); setup_timer(&l2cap_pi(sk)->ack_timer, - l2cap_ack_timeout, (unsigned long) sk); + l2cap_ack_timeout, (unsigned long) chan); __skb_queue_head_init(SREJ_QUEUE(sk)); __skb_queue_head_init(BUSY_QUEUE(sk)); @@ -2305,7 +2315,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_pi(sk)->expected_tx_seq = 0; __skb_queue_head_init(TX_QUEUE(sk)); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) - l2cap_ertm_init(sk); + l2cap_ertm_init(chan); l2cap_chan_ready(sk); goto unlock; @@ -2396,7 +2406,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_pi(sk)->expected_tx_seq = 0; __skb_queue_head_init(TX_QUEUE(sk)); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) - l2cap_ertm_init(sk); + l2cap_ertm_init(chan); l2cap_chan_ready(sk); } @@ -2777,30 +2787,30 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) return 0; } -static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) +static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u16 control = 0; pi->frames_sent = 0; control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; - if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { + if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { control |= L2CAP_SUPER_RCV_NOT_READY; - l2cap_send_sframe(pi, control); - pi->conn_state |= L2CAP_CONN_RNR_SENT; + l2cap_send_sframe(chan, control); + chan->conn_state |= L2CAP_CONN_RNR_SENT; } - if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) - l2cap_retransmit_frames(sk); + if (chan->conn_state & L2CAP_CONN_REMOTE_BUSY) + l2cap_retransmit_frames(chan); - l2cap_ertm_send(sk); + l2cap_ertm_send(chan); - if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && + if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) && pi->frames_sent == 0) { control |= L2CAP_SUPER_RCV_READY; - l2cap_send_sframe(pi, control); + l2cap_send_sframe(chan, control); } } @@ -2847,25 +2857,25 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s return 0; } -static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) +static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); struct sk_buff *_skb; int err; switch (control & L2CAP_CTRL_SAR) { case L2CAP_SDU_UNSEGMENTED: - if (pi->conn_state & L2CAP_CONN_SAR_SDU) + if (chan->conn_state & L2CAP_CONN_SAR_SDU) goto drop; - err = sock_queue_rcv_skb(sk, skb); + err = sock_queue_rcv_skb(chan->sk, skb); if (!err) return err; break; case L2CAP_SDU_START: - if (pi->conn_state & L2CAP_CONN_SAR_SDU) + if (chan->conn_state & L2CAP_CONN_SAR_SDU) goto drop; pi->sdu_len = get_unaligned_le16(skb->data); @@ -2884,12 +2894,12 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); - pi->conn_state |= L2CAP_CONN_SAR_SDU; + chan->conn_state |= L2CAP_CONN_SAR_SDU; pi->partial_sdu_len = skb->len; break; case L2CAP_SDU_CONTINUE: - if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) + if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) goto disconnect; if (!pi->sdu) @@ -2904,13 +2914,13 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c break; case L2CAP_SDU_END: - if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) + if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) goto disconnect; if (!pi->sdu) goto disconnect; - if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) { + if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) { pi->partial_sdu_len += skb->len; if (pi->partial_sdu_len > pi->imtu) @@ -2924,19 +2934,19 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c _skb = skb_clone(pi->sdu, GFP_ATOMIC); if (!_skb) { - pi->conn_state |= L2CAP_CONN_SAR_RETRY; + chan->conn_state |= L2CAP_CONN_SAR_RETRY; return -ENOMEM; } - err = sock_queue_rcv_skb(sk, _skb); + err = sock_queue_rcv_skb(chan->sk, _skb); if (err < 0) { kfree_skb(_skb); - pi->conn_state |= L2CAP_CONN_SAR_RETRY; + chan->conn_state |= L2CAP_CONN_SAR_RETRY; return err; } - pi->conn_state &= ~L2CAP_CONN_SAR_RETRY; - pi->conn_state &= ~L2CAP_CONN_SAR_SDU; + chan->conn_state &= ~L2CAP_CONN_SAR_RETRY; + chan->conn_state &= ~L2CAP_CONN_SAR_SDU; kfree_skb(pi->sdu); break; @@ -2950,13 +2960,14 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c pi->sdu = NULL; disconnect: - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan->sk, ECONNRESET); kfree_skb(skb); return 0; } -static int l2cap_try_push_rx_skb(struct sock *sk) +static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); struct sk_buff *skb; u16 control; @@ -2964,7 +2975,7 @@ static int l2cap_try_push_rx_skb(struct sock *sk) while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; - err = l2cap_ertm_reassembly_sdu(sk, skb, control); + err = l2cap_ertm_reassembly_sdu(chan, skb, control); if (err < 0) { skb_queue_head(BUSY_QUEUE(sk), skb); return -EBUSY; @@ -2973,22 +2984,22 @@ static int l2cap_try_push_rx_skb(struct sock *sk) pi->buffer_seq = (pi->buffer_seq + 1) % 64; } - if (!(pi->conn_state & L2CAP_CONN_RNR_SENT)) + if (!(chan->conn_state & L2CAP_CONN_RNR_SENT)) goto done; control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; - l2cap_send_sframe(pi, control); + l2cap_send_sframe(chan, control); l2cap_pi(sk)->retry_count = 1; del_timer(&pi->retrans_timer); __mod_monitor_timer(); - l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F; + chan->conn_state |= L2CAP_CONN_WAIT_F; done: - pi->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; - pi->conn_state &= ~L2CAP_CONN_RNR_SENT; + chan->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; + chan->conn_state &= ~L2CAP_CONN_RNR_SENT; BT_DBG("sk %p, Exit local busy", sk); @@ -3032,7 +3043,7 @@ static void l2cap_busy_work(struct work_struct *work) if (err) break; - if (l2cap_try_push_rx_skb(sk) == 0) + if (l2cap_try_push_rx_skb(l2cap_pi(sk)->chan) == 0) break; } @@ -3042,20 +3053,21 @@ static void l2cap_busy_work(struct work_struct *work) release_sock(sk); } -static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) +static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); int sctrl, err; - if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) { + if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; __skb_queue_tail(BUSY_QUEUE(sk), skb); - return l2cap_try_push_rx_skb(sk); + return l2cap_try_push_rx_skb(chan); } - err = l2cap_ertm_reassembly_sdu(sk, skb, control); + err = l2cap_ertm_reassembly_sdu(chan, skb, control); if (err >= 0) { pi->buffer_seq = (pi->buffer_seq + 1) % 64; return err; @@ -3064,15 +3076,15 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) /* Busy Condition */ BT_DBG("sk %p, Enter local busy", sk); - pi->conn_state |= L2CAP_CONN_LOCAL_BUSY; + chan->conn_state |= L2CAP_CONN_LOCAL_BUSY; bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; __skb_queue_tail(BUSY_QUEUE(sk), skb); sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; sctrl |= L2CAP_SUPER_RCV_NOT_READY; - l2cap_send_sframe(pi, sctrl); + l2cap_send_sframe(chan, sctrl); - pi->conn_state |= L2CAP_CONN_RNR_SENT; + chan->conn_state |= L2CAP_CONN_RNR_SENT; del_timer(&pi->ack_timer); @@ -3081,9 +3093,9 @@ static int l2cap_push_rx_skb(struct sock *sk, struct sk_buff *skb, u16 control) return err; } -static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control) +static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); struct sk_buff *_skb; int err = -EINVAL; @@ -3094,19 +3106,19 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, switch (control & L2CAP_CTRL_SAR) { case L2CAP_SDU_UNSEGMENTED: - if (pi->conn_state & L2CAP_CONN_SAR_SDU) { + if (chan->conn_state & L2CAP_CONN_SAR_SDU) { kfree_skb(pi->sdu); break; } - err = sock_queue_rcv_skb(sk, skb); + err = sock_queue_rcv_skb(chan->sk, skb); if (!err) return 0; break; case L2CAP_SDU_START: - if (pi->conn_state & L2CAP_CONN_SAR_SDU) { + if (chan->conn_state & L2CAP_CONN_SAR_SDU) { kfree_skb(pi->sdu); break; } @@ -3127,13 +3139,13 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); - pi->conn_state |= L2CAP_CONN_SAR_SDU; + chan->conn_state |= L2CAP_CONN_SAR_SDU; pi->partial_sdu_len = skb->len; err = 0; break; case L2CAP_SDU_CONTINUE: - if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) + if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) break; memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); @@ -3147,12 +3159,12 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, break; case L2CAP_SDU_END: - if (!(pi->conn_state & L2CAP_CONN_SAR_SDU)) + if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) break; memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); - pi->conn_state &= ~L2CAP_CONN_SAR_SDU; + chan->conn_state &= ~L2CAP_CONN_SAR_SDU; pi->partial_sdu_len += skb->len; if (pi->partial_sdu_len > pi->imtu) @@ -3160,7 +3172,7 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, if (pi->partial_sdu_len == pi->sdu_len) { _skb = skb_clone(pi->sdu, GFP_ATOMIC); - err = sock_queue_rcv_skb(sk, _skb); + err = sock_queue_rcv_skb(chan->sk, _skb); if (err < 0) kfree_skb(_skb); } @@ -3175,8 +3187,9 @@ static int l2cap_streaming_reassembly_sdu(struct sock *sk, struct sk_buff *skb, return err; } -static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq) +static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) { + struct sock *sk = chan->sk; struct sk_buff *skb; u16 control; @@ -3186,16 +3199,16 @@ static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq) skb = skb_dequeue(SREJ_QUEUE(sk)); control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; - l2cap_ertm_reassembly_sdu(sk, skb, control); + l2cap_ertm_reassembly_sdu(chan, skb, control); l2cap_pi(sk)->buffer_seq_srej = (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; tx_seq = (tx_seq + 1) % 64; } } -static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq) +static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct sock *sk = chan->sk; struct srej_list *l, *tmp; u16 control; @@ -3207,14 +3220,15 @@ static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq) } control = L2CAP_SUPER_SELECT_REJECT; control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; - l2cap_send_sframe(pi, control); + l2cap_send_sframe(chan, control); list_del(&l->list); list_add_tail(&l->list, SREJ_LIST(sk)); } } -static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) +static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); struct srej_list *new; u16 control; @@ -3222,7 +3236,7 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) while (tx_seq != pi->expected_tx_seq) { control = L2CAP_SUPER_SELECT_REJECT; control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; - l2cap_send_sframe(pi, control); + l2cap_send_sframe(chan, control); new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); new->tx_seq = pi->expected_tx_seq; @@ -3232,8 +3246,9 @@ static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq) pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; } -static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) +static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); u8 tx_seq = __get_txseq(rx_control); u8 req_seq = __get_reqseq(rx_control); @@ -3242,15 +3257,15 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str int num_to_ack = (pi->tx_win/6) + 1; int err = 0; - BT_DBG("sk %p len %d tx_seq %d rx_control 0x%4.4x", sk, skb->len, tx_seq, - rx_control); + BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len, + tx_seq, rx_control); if (L2CAP_CTRL_FINAL & rx_control && - l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { + chan->conn_state & L2CAP_CONN_WAIT_F) { del_timer(&pi->monitor_timer); if (pi->unacked_frames > 0) __mod_retrans_timer(); - pi->conn_state &= ~L2CAP_CONN_WAIT_F; + chan->conn_state &= ~L2CAP_CONN_WAIT_F; } pi->expected_ack_seq = req_seq; @@ -3269,25 +3284,25 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str goto drop; } - if (pi->conn_state == L2CAP_CONN_LOCAL_BUSY) + if (chan->conn_state == L2CAP_CONN_LOCAL_BUSY) goto drop; - if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { + if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { struct srej_list *first; first = list_first_entry(SREJ_LIST(sk), struct srej_list, list); if (tx_seq == first->tx_seq) { l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); - l2cap_check_srej_gap(sk, tx_seq); + l2cap_check_srej_gap(chan, tx_seq); list_del(&first->list); kfree(first); if (list_empty(SREJ_LIST(sk))) { pi->buffer_seq = pi->buffer_seq_srej; - pi->conn_state &= ~L2CAP_CONN_SREJ_SENT; - l2cap_send_ack(pi); + chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; + l2cap_send_ack(chan); BT_DBG("sk %p, Exit SREJ_SENT", sk); } } else { @@ -3299,11 +3314,11 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str list_for_each_entry(l, SREJ_LIST(sk), list) { if (l->tx_seq == tx_seq) { - l2cap_resend_srejframe(sk, tx_seq); + l2cap_resend_srejframe(chan, tx_seq); return 0; } } - l2cap_send_srejframe(sk, tx_seq); + l2cap_send_srejframe(chan, tx_seq); } } else { expected_tx_seq_offset = @@ -3315,7 +3330,7 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str if (tx_seq_offset < expected_tx_seq_offset) goto drop; - pi->conn_state |= L2CAP_CONN_SREJ_SENT; + chan->conn_state |= L2CAP_CONN_SREJ_SENT; BT_DBG("sk %p, Enter SREJ", sk); @@ -3326,9 +3341,9 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str __skb_queue_head_init(BUSY_QUEUE(sk)); l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); - pi->conn_state |= L2CAP_CONN_SEND_PBIT; + chan->conn_state |= L2CAP_CONN_SEND_PBIT; - l2cap_send_srejframe(sk, tx_seq); + l2cap_send_srejframe(chan, tx_seq); del_timer(&pi->ack_timer); } @@ -3337,29 +3352,29 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str expected: pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; - if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { + if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { bt_cb(skb)->tx_seq = tx_seq; bt_cb(skb)->sar = sar; __skb_queue_tail(SREJ_QUEUE(sk), skb); return 0; } - err = l2cap_push_rx_skb(sk, skb, rx_control); + err = l2cap_push_rx_skb(chan, skb, rx_control); if (err < 0) return 0; if (rx_control & L2CAP_CTRL_FINAL) { - if (pi->conn_state & L2CAP_CONN_REJ_ACT) - pi->conn_state &= ~L2CAP_CONN_REJ_ACT; + if (chan->conn_state & L2CAP_CONN_REJ_ACT) + chan->conn_state &= ~L2CAP_CONN_REJ_ACT; else - l2cap_retransmit_frames(sk); + l2cap_retransmit_frames(chan); } __mod_ack_timer(); pi->num_acked = (pi->num_acked + 1) % num_to_ack; if (pi->num_acked == num_to_ack - 1) - l2cap_send_ack(pi); + l2cap_send_ack(chan); return 0; @@ -3368,8 +3383,9 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str return 0; } -static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) +static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control) { + struct sock *sk = chan->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), @@ -3379,154 +3395,156 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) l2cap_drop_acked_frames(sk); if (rx_control & L2CAP_CTRL_POLL) { - pi->conn_state |= L2CAP_CONN_SEND_FBIT; - if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { - if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && + chan->conn_state |= L2CAP_CONN_SEND_FBIT; + if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { + if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && (pi->unacked_frames > 0)) __mod_retrans_timer(); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; - l2cap_send_srejtail(sk); + chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + l2cap_send_srejtail(chan); } else { - l2cap_send_i_or_rr_or_rnr(sk); + l2cap_send_i_or_rr_or_rnr(chan); } } else if (rx_control & L2CAP_CTRL_FINAL) { - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; - if (pi->conn_state & L2CAP_CONN_REJ_ACT) - pi->conn_state &= ~L2CAP_CONN_REJ_ACT; + if (chan->conn_state & L2CAP_CONN_REJ_ACT) + chan->conn_state &= ~L2CAP_CONN_REJ_ACT; else - l2cap_retransmit_frames(sk); + l2cap_retransmit_frames(chan); } else { - if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && + if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && (pi->unacked_frames > 0)) __mod_retrans_timer(); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; - if (pi->conn_state & L2CAP_CONN_SREJ_SENT) - l2cap_send_ack(pi); + chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + if (chan->conn_state & L2CAP_CONN_SREJ_SENT) + l2cap_send_ack(chan); else - l2cap_ertm_send(sk); + l2cap_ertm_send(chan); } } -static inline void l2cap_data_channel_rejframe(struct sock *sk, u16 rx_control) +static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_reqseq(rx_control); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); + BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; pi->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(sk); + l2cap_drop_acked_frames(chan->sk); if (rx_control & L2CAP_CTRL_FINAL) { - if (pi->conn_state & L2CAP_CONN_REJ_ACT) - pi->conn_state &= ~L2CAP_CONN_REJ_ACT; + if (chan->conn_state & L2CAP_CONN_REJ_ACT) + chan->conn_state &= ~L2CAP_CONN_REJ_ACT; else - l2cap_retransmit_frames(sk); + l2cap_retransmit_frames(chan); } else { - l2cap_retransmit_frames(sk); + l2cap_retransmit_frames(chan); - if (pi->conn_state & L2CAP_CONN_WAIT_F) - pi->conn_state |= L2CAP_CONN_REJ_ACT; + if (chan->conn_state & L2CAP_CONN_WAIT_F) + chan->conn_state |= L2CAP_CONN_REJ_ACT; } } -static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) +static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_reqseq(rx_control); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); + BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; if (rx_control & L2CAP_CTRL_POLL) { pi->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(sk); + l2cap_drop_acked_frames(chan->sk); - pi->conn_state |= L2CAP_CONN_SEND_FBIT; - l2cap_retransmit_one_frame(sk, tx_seq); + chan->conn_state |= L2CAP_CONN_SEND_FBIT; + l2cap_retransmit_one_frame(chan, tx_seq); - l2cap_ertm_send(sk); + l2cap_ertm_send(chan); - if (pi->conn_state & L2CAP_CONN_WAIT_F) { + if (chan->conn_state & L2CAP_CONN_WAIT_F) { pi->srej_save_reqseq = tx_seq; - pi->conn_state |= L2CAP_CONN_SREJ_ACT; + chan->conn_state |= L2CAP_CONN_SREJ_ACT; } } else if (rx_control & L2CAP_CTRL_FINAL) { - if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) && + if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) && pi->srej_save_reqseq == tx_seq) - pi->conn_state &= ~L2CAP_CONN_SREJ_ACT; + chan->conn_state &= ~L2CAP_CONN_SREJ_ACT; else - l2cap_retransmit_one_frame(sk, tx_seq); + l2cap_retransmit_one_frame(chan, tx_seq); } else { - l2cap_retransmit_one_frame(sk, tx_seq); - if (pi->conn_state & L2CAP_CONN_WAIT_F) { + l2cap_retransmit_one_frame(chan, tx_seq); + if (chan->conn_state & L2CAP_CONN_WAIT_F) { pi->srej_save_reqseq = tx_seq; - pi->conn_state |= L2CAP_CONN_SREJ_ACT; + chan->conn_state |= L2CAP_CONN_SREJ_ACT; } } } -static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control) +static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_reqseq(rx_control); - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, tx_seq, rx_control); + BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); - pi->conn_state |= L2CAP_CONN_REMOTE_BUSY; + chan->conn_state |= L2CAP_CONN_REMOTE_BUSY; pi->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(sk); + l2cap_drop_acked_frames(chan->sk); if (rx_control & L2CAP_CTRL_POLL) - pi->conn_state |= L2CAP_CONN_SEND_FBIT; + chan->conn_state |= L2CAP_CONN_SEND_FBIT; - if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { + if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) { del_timer(&pi->retrans_timer); if (rx_control & L2CAP_CTRL_POLL) - l2cap_send_rr_or_rnr(pi, L2CAP_CTRL_FINAL); + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); return; } if (rx_control & L2CAP_CTRL_POLL) - l2cap_send_srejtail(sk); + l2cap_send_srejtail(chan); else - l2cap_send_sframe(pi, L2CAP_SUPER_RCV_READY); + l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY); } -static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb) +static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) { - BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len); + struct sock *sk = chan->sk; + + BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); if (L2CAP_CTRL_FINAL & rx_control && - l2cap_pi(sk)->conn_state & L2CAP_CONN_WAIT_F) { + chan->conn_state & L2CAP_CONN_WAIT_F) { del_timer(&l2cap_pi(sk)->monitor_timer); if (l2cap_pi(sk)->unacked_frames > 0) __mod_retrans_timer(); - l2cap_pi(sk)->conn_state &= ~L2CAP_CONN_WAIT_F; + chan->conn_state &= ~L2CAP_CONN_WAIT_F; } switch (rx_control & L2CAP_CTRL_SUPERVISE) { case L2CAP_SUPER_RCV_READY: - l2cap_data_channel_rrframe(sk, rx_control); + l2cap_data_channel_rrframe(chan, rx_control); break; case L2CAP_SUPER_REJECT: - l2cap_data_channel_rejframe(sk, rx_control); + l2cap_data_channel_rejframe(chan, rx_control); break; case L2CAP_SUPER_SELECT_REJECT: - l2cap_data_channel_srejframe(sk, rx_control); + l2cap_data_channel_srejframe(chan, rx_control); break; case L2CAP_SUPER_RCV_NOT_READY: - l2cap_data_channel_rnrframe(sk, rx_control); + l2cap_data_channel_rnrframe(chan, rx_control); break; } @@ -3536,6 +3554,7 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) { + struct l2cap_chan *chan = l2cap_pi(sk)->chan; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control; u8 req_seq; @@ -3586,7 +3605,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) goto drop; } - l2cap_data_channel_iframe(sk, control, skb); + l2cap_data_channel_iframe(chan, control, skb); } else { if (len != 0) { BT_ERR("%d", len); @@ -3594,7 +3613,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) goto drop; } - l2cap_data_channel_sframe(sk, control, skb); + l2cap_data_channel_sframe(chan, control, skb); } return 0; @@ -3675,7 +3694,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk else pi->expected_tx_seq = (tx_seq + 1) % 64; - l2cap_streaming_reassembly_sdu(sk, skb, control); + l2cap_streaming_reassembly_sdu(chan, skb, control); goto done; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 450f57b106b9..66ec966ffc18 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -778,14 +778,16 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms if (pi->mode == L2CAP_MODE_STREAMING) { l2cap_streaming_send(sk); - } else { - if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && - (pi->conn_state & L2CAP_CONN_WAIT_F)) { - err = len; - break; - } - err = l2cap_ertm_send(sk); + err = len; + break; + } + + if ((pi->chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && + (pi->chan->conn_state & L2CAP_CONN_WAIT_F)) { + err = len; + break; } + err = l2cap_ertm_send(pi->chan); if (err >= 0) err = len; -- GitLab From 42e5c8027bad6f1591032941f0ebf4fc079405c8 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 19:58:34 -0300 Subject: [PATCH 0621/5560] Bluetooth: Move of ERTM *_seq vars to struct l2cap_chan As part of the moving channel to stuff to struct l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 20 +++--- net/bluetooth/l2cap_core.c | 128 ++++++++++++++++------------------ net/bluetooth/l2cap_sock.c | 2 +- 3 files changed, 73 insertions(+), 77 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 82d5b81a779b..9b43874ca6e4 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -288,6 +288,12 @@ struct l2cap_chan { __u16 conn_state; + __u8 next_tx_seq; + __u8 expected_ack_seq; + __u8 expected_tx_seq; + __u8 buffer_seq; + __u8 buffer_seq_srej; + struct list_head list; }; @@ -353,11 +359,6 @@ struct l2cap_pinfo { __u8 conf_state; - __u8 next_tx_seq; - __u8 expected_ack_seq; - __u8 expected_tx_seq; - __u8 buffer_seq; - __u8 buffer_seq_srej; __u8 srej_save_reqseq; __u8 frames_sent; __u8 unacked_frames; @@ -421,17 +422,16 @@ struct l2cap_pinfo { #define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \ jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); -static inline int l2cap_tx_window_full(struct sock *sk) +static inline int l2cap_tx_window_full(struct l2cap_chan *ch) { - struct l2cap_pinfo *pi = l2cap_pi(sk); int sub; - sub = (pi->next_tx_seq - pi->expected_ack_seq) % 64; + sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64; if (sub < 0) sub += 64; - return sub == pi->remote_tx_win; + return sub == l2cap_pi(ch->sk)->remote_tx_win; } #define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) @@ -456,7 +456,7 @@ struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen); int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len); void l2cap_do_send(struct sock *sk, struct sk_buff *skb); -void l2cap_streaming_send(struct sock *sk); +void l2cap_streaming_send(struct l2cap_chan *chan); int l2cap_ertm_send(struct l2cap_chan *chan); void l2cap_sock_set_timer(struct sock *sk, long timeout); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b5435cd74f99..d975092904c1 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -395,15 +395,13 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) { - struct l2cap_pinfo *pi = l2cap_pi(chan->sk); - if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { control |= L2CAP_SUPER_RCV_NOT_READY; chan->conn_state |= L2CAP_CONN_RNR_SENT; } else control |= L2CAP_SUPER_RCV_READY; - control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; l2cap_send_sframe(chan, control); } @@ -988,13 +986,14 @@ static void l2cap_retrans_timeout(unsigned long arg) bh_unlock_sock(sk); } -static void l2cap_drop_acked_frames(struct sock *sk) +static void l2cap_drop_acked_frames(struct l2cap_chan *chan) { + struct sock *sk = chan->sk; struct sk_buff *skb; while ((skb = skb_peek(TX_QUEUE(sk))) && l2cap_pi(sk)->unacked_frames) { - if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq) + if (bt_cb(skb)->tx_seq == chan->expected_ack_seq) break; skb = skb_dequeue(TX_QUEUE(sk)); @@ -1023,15 +1022,16 @@ void l2cap_do_send(struct sock *sk, struct sk_buff *skb) hci_send_acl(hcon, skb, flags); } -void l2cap_streaming_send(struct sock *sk) +void l2cap_streaming_send(struct l2cap_chan *chan) { + struct sock *sk = chan->sk; struct sk_buff *skb; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; while ((skb = skb_dequeue(TX_QUEUE(sk)))) { control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); - control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; + control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); if (pi->fcs == L2CAP_FCS_CRC16) { @@ -1041,7 +1041,7 @@ void l2cap_streaming_send(struct sock *sk) l2cap_do_send(sk, skb); - pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; + chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; } } @@ -1080,7 +1080,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; } - control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) + control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); @@ -1104,7 +1104,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan) if (sk->sk_state != BT_CONNECTED) return -ENOTCONN; - while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))) { + while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(chan))) { if (pi->remote_max_tx && bt_cb(skb)->retries == pi->remote_max_tx) { @@ -1123,8 +1123,8 @@ int l2cap_ertm_send(struct l2cap_chan *chan) control |= L2CAP_CTRL_FINAL; chan->conn_state &= ~L2CAP_CONN_SEND_FBIT; } - control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) - | (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); + control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) + | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); @@ -1137,8 +1137,8 @@ int l2cap_ertm_send(struct l2cap_chan *chan) __mod_retrans_timer(); - bt_cb(skb)->tx_seq = pi->next_tx_seq; - pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; + bt_cb(skb)->tx_seq = chan->next_tx_seq; + chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; if (bt_cb(skb)->retries == 1) pi->unacked_frames++; @@ -1159,23 +1159,21 @@ int l2cap_ertm_send(struct l2cap_chan *chan) static int l2cap_retransmit_frames(struct l2cap_chan *chan) { struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); int ret; if (!skb_queue_empty(TX_QUEUE(sk))) sk->sk_send_head = TX_QUEUE(sk)->next; - pi->next_tx_seq = pi->expected_ack_seq; + chan->next_tx_seq = chan->expected_ack_seq; ret = l2cap_ertm_send(chan); return ret; } static void l2cap_send_ack(struct l2cap_chan *chan) { - struct sock *sk = chan->sk; u16 control = 0; - control |= l2cap_pi(sk)->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { control |= L2CAP_SUPER_RCV_NOT_READY; @@ -1575,9 +1573,9 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) { struct sock *sk = chan->sk; - l2cap_pi(sk)->expected_ack_seq = 0; + chan->expected_ack_seq = 0; l2cap_pi(sk)->unacked_frames = 0; - l2cap_pi(sk)->buffer_seq = 0; + chan->buffer_seq = 0; l2cap_pi(sk)->num_acked = 0; l2cap_pi(sk)->frames_sent = 0; @@ -2311,8 +2309,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr sk->sk_state = BT_CONNECTED; - l2cap_pi(sk)->next_tx_seq = 0; - l2cap_pi(sk)->expected_tx_seq = 0; + chan->next_tx_seq = 0; + chan->expected_tx_seq = 0; __skb_queue_head_init(TX_QUEUE(sk)); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) l2cap_ertm_init(chan); @@ -2402,8 +2400,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; - l2cap_pi(sk)->next_tx_seq = 0; - l2cap_pi(sk)->expected_tx_seq = 0; + chan->next_tx_seq = 0; + chan->expected_tx_seq = 0; __skb_queue_head_init(TX_QUEUE(sk)); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) l2cap_ertm_init(chan); @@ -2794,7 +2792,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) pi->frames_sent = 0; - control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { control |= L2CAP_SUPER_RCV_NOT_READY; @@ -2814,10 +2812,10 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) } } -static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar) +static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar) { + struct sock *sk = chan->sk; struct sk_buff *next_skb; - struct l2cap_pinfo *pi = l2cap_pi(sk); int tx_seq_offset, next_tx_seq_offset; bt_cb(skb)->tx_seq = tx_seq; @@ -2829,7 +2827,7 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s return 0; } - tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; + tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; if (tx_seq_offset < 0) tx_seq_offset += 64; @@ -2838,7 +2836,7 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s return -EINVAL; next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - - pi->buffer_seq) % 64; + chan->buffer_seq) % 64; if (next_tx_seq_offset < 0) next_tx_seq_offset += 64; @@ -2981,13 +2979,13 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) return -EBUSY; } - pi->buffer_seq = (pi->buffer_seq + 1) % 64; + chan->buffer_seq = (chan->buffer_seq + 1) % 64; } if (!(chan->conn_state & L2CAP_CONN_RNR_SENT)) goto done; - control = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; l2cap_send_sframe(chan, control); l2cap_pi(sk)->retry_count = 1; @@ -3069,7 +3067,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c err = l2cap_ertm_reassembly_sdu(chan, skb, control); if (err >= 0) { - pi->buffer_seq = (pi->buffer_seq + 1) % 64; + chan->buffer_seq = (chan->buffer_seq + 1) % 64; return err; } @@ -3080,7 +3078,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; __skb_queue_tail(BUSY_QUEUE(sk), skb); - sctrl = pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; + sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; sctrl |= L2CAP_SUPER_RCV_NOT_READY; l2cap_send_sframe(chan, sctrl); @@ -3200,8 +3198,8 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) skb = skb_dequeue(SREJ_QUEUE(sk)); control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; l2cap_ertm_reassembly_sdu(chan, skb, control); - l2cap_pi(sk)->buffer_seq_srej = - (l2cap_pi(sk)->buffer_seq_srej + 1) % 64; + chan->buffer_seq_srej = + (chan->buffer_seq_srej + 1) % 64; tx_seq = (tx_seq + 1) % 64; } } @@ -3229,21 +3227,20 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) { struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); struct srej_list *new; u16 control; - while (tx_seq != pi->expected_tx_seq) { + while (tx_seq != chan->expected_tx_seq) { control = L2CAP_SUPER_SELECT_REJECT; - control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; + control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; l2cap_send_sframe(chan, control); new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); - new->tx_seq = pi->expected_tx_seq; - pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; + new->tx_seq = chan->expected_tx_seq; + chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; list_add_tail(&new->list, SREJ_LIST(sk)); } - pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; + chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; } static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) @@ -3268,13 +3265,13 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont chan->conn_state &= ~L2CAP_CONN_WAIT_F; } - pi->expected_ack_seq = req_seq; - l2cap_drop_acked_frames(sk); + chan->expected_ack_seq = req_seq; + l2cap_drop_acked_frames(chan); - if (tx_seq == pi->expected_tx_seq) + if (tx_seq == chan->expected_tx_seq) goto expected; - tx_seq_offset = (tx_seq - pi->buffer_seq) % 64; + tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; if (tx_seq_offset < 0) tx_seq_offset += 64; @@ -3293,14 +3290,14 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont first = list_first_entry(SREJ_LIST(sk), struct srej_list, list); if (tx_seq == first->tx_seq) { - l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); + l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); l2cap_check_srej_gap(chan, tx_seq); list_del(&first->list); kfree(first); if (list_empty(SREJ_LIST(sk))) { - pi->buffer_seq = pi->buffer_seq_srej; + chan->buffer_seq = chan->buffer_seq_srej; chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; l2cap_send_ack(chan); BT_DBG("sk %p, Exit SREJ_SENT", sk); @@ -3309,7 +3306,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont struct srej_list *l; /* duplicated tx_seq */ - if (l2cap_add_to_srej_queue(sk, skb, tx_seq, sar) < 0) + if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0) goto drop; list_for_each_entry(l, SREJ_LIST(sk), list) { @@ -3322,7 +3319,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont } } else { expected_tx_seq_offset = - (pi->expected_tx_seq - pi->buffer_seq) % 64; + (chan->expected_tx_seq - chan->buffer_seq) % 64; if (expected_tx_seq_offset < 0) expected_tx_seq_offset += 64; @@ -3335,11 +3332,11 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont BT_DBG("sk %p, Enter SREJ", sk); INIT_LIST_HEAD(SREJ_LIST(sk)); - pi->buffer_seq_srej = pi->buffer_seq; + chan->buffer_seq_srej = chan->buffer_seq; __skb_queue_head_init(SREJ_QUEUE(sk)); __skb_queue_head_init(BUSY_QUEUE(sk)); - l2cap_add_to_srej_queue(sk, skb, tx_seq, sar); + l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); chan->conn_state |= L2CAP_CONN_SEND_PBIT; @@ -3350,7 +3347,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont return 0; expected: - pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; + chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { bt_cb(skb)->tx_seq = tx_seq; @@ -3391,8 +3388,8 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), rx_control); - pi->expected_ack_seq = __get_reqseq(rx_control); - l2cap_drop_acked_frames(sk); + chan->expected_ack_seq = __get_reqseq(rx_control); + l2cap_drop_acked_frames(chan); if (rx_control & L2CAP_CTRL_POLL) { chan->conn_state |= L2CAP_CONN_SEND_FBIT; @@ -3430,15 +3427,14 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control) { - struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_reqseq(rx_control); BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; - pi->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(chan->sk); + chan->expected_ack_seq = tx_seq; + l2cap_drop_acked_frames(chan); if (rx_control & L2CAP_CTRL_FINAL) { if (chan->conn_state & L2CAP_CONN_REJ_ACT) @@ -3462,8 +3458,8 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; if (rx_control & L2CAP_CTRL_POLL) { - pi->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(chan->sk); + chan->expected_ack_seq = tx_seq; + l2cap_drop_acked_frames(chan); chan->conn_state |= L2CAP_CONN_SEND_FBIT; l2cap_retransmit_one_frame(chan, tx_seq); @@ -3497,8 +3493,8 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); chan->conn_state |= L2CAP_CONN_REMOTE_BUSY; - pi->expected_ack_seq = tx_seq; - l2cap_drop_acked_frames(chan->sk); + chan->expected_ack_seq = tx_seq; + l2cap_drop_acked_frames(chan); if (rx_control & L2CAP_CTRL_POLL) chan->conn_state |= L2CAP_CONN_SEND_FBIT; @@ -3584,12 +3580,12 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) } req_seq = __get_reqseq(control); - req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; + req_seq_offset = (req_seq - chan->expected_ack_seq) % 64; if (req_seq_offset < 0) req_seq_offset += 64; next_tx_seq_offset = - (pi->next_tx_seq - pi->expected_ack_seq) % 64; + (chan->next_tx_seq - chan->expected_ack_seq) % 64; if (next_tx_seq_offset < 0) next_tx_seq_offset += 64; @@ -3689,10 +3685,10 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk tx_seq = __get_txseq(control); - if (pi->expected_tx_seq == tx_seq) - pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64; + if (chan->expected_tx_seq == tx_seq) + chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; else - pi->expected_tx_seq = (tx_seq + 1) % 64; + chan->expected_tx_seq = (tx_seq + 1) % 64; l2cap_streaming_reassembly_sdu(chan, skb, control); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 66ec966ffc18..19574e43226a 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -777,7 +777,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms } if (pi->mode == L2CAP_MODE_STREAMING) { - l2cap_streaming_send(sk); + l2cap_streaming_send(pi->chan); err = len; break; } -- GitLab From 6a026610eee2c53ff59598905fcbaa979aec68d1 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 1 Apr 2011 00:38:50 -0300 Subject: [PATCH 0622/5560] Bluetooth: Move more ERTM stuff to struct l2cap_chan As part of the moving channel stuff to l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 10 +++---- net/bluetooth/l2cap_core.c | 51 +++++++++++++++++------------------ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9b43874ca6e4..041213b4175a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -293,6 +293,11 @@ struct l2cap_chan { __u8 expected_tx_seq; __u8 buffer_seq; __u8 buffer_seq_srej; + __u8 srej_save_reqseq; + __u8 frames_sent; + __u8 unacked_frames; + __u8 retry_count; + __u8 num_acked; struct list_head list; }; @@ -359,11 +364,6 @@ struct l2cap_pinfo { __u8 conf_state; - __u8 srej_save_reqseq; - __u8 frames_sent; - __u8 unacked_frames; - __u8 retry_count; - __u8 num_acked; __u16 sdu_len; __u16 partial_sdu_len; struct sk_buff *sdu; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d975092904c1..3f601d1c164a 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -924,7 +924,7 @@ int __l2cap_wait_ack(struct sock *sk) int timeo = HZ/5; add_wait_queue(sk_sleep(sk), &wait); - while ((l2cap_pi(sk)->unacked_frames > 0 && l2cap_pi(sk)->conn)) { + while ((l2cap_pi(sk)->chan->unacked_frames > 0 && l2cap_pi(sk)->conn)) { set_current_state(TASK_INTERRUPTIBLE); if (!timeo) @@ -956,13 +956,13 @@ static void l2cap_monitor_timeout(unsigned long arg) BT_DBG("chan %p", chan); bh_lock_sock(sk); - if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { + if (chan->retry_count >= l2cap_pi(sk)->remote_max_tx) { l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); bh_unlock_sock(sk); return; } - l2cap_pi(sk)->retry_count++; + chan->retry_count++; __mod_monitor_timer(); l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); @@ -977,7 +977,7 @@ static void l2cap_retrans_timeout(unsigned long arg) BT_DBG("sk %p", sk); bh_lock_sock(sk); - l2cap_pi(sk)->retry_count = 1; + chan->retry_count = 1; __mod_monitor_timer(); chan->conn_state |= L2CAP_CONN_WAIT_F; @@ -992,17 +992,17 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) struct sk_buff *skb; while ((skb = skb_peek(TX_QUEUE(sk))) && - l2cap_pi(sk)->unacked_frames) { + chan->unacked_frames) { if (bt_cb(skb)->tx_seq == chan->expected_ack_seq) break; skb = skb_dequeue(TX_QUEUE(sk)); kfree_skb(skb); - l2cap_pi(sk)->unacked_frames--; + chan->unacked_frames--; } - if (!l2cap_pi(sk)->unacked_frames) + if (!chan->unacked_frames) del_timer(&l2cap_pi(sk)->retrans_timer); } @@ -1141,9 +1141,9 @@ int l2cap_ertm_send(struct l2cap_chan *chan) chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; if (bt_cb(skb)->retries == 1) - pi->unacked_frames++; + chan->unacked_frames++; - pi->frames_sent++; + chan->frames_sent++; if (skb_queue_is_last(TX_QUEUE(sk), skb)) sk->sk_send_head = NULL; @@ -1574,10 +1574,10 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) struct sock *sk = chan->sk; chan->expected_ack_seq = 0; - l2cap_pi(sk)->unacked_frames = 0; + chan->unacked_frames = 0; chan->buffer_seq = 0; - l2cap_pi(sk)->num_acked = 0; - l2cap_pi(sk)->frames_sent = 0; + chan->num_acked = 0; + chan->frames_sent = 0; setup_timer(&l2cap_pi(sk)->retrans_timer, l2cap_retrans_timeout, (unsigned long) chan); @@ -2787,10 +2787,9 @@ static int l2cap_check_fcs(struct l2cap_pinfo *pi, struct sk_buff *skb) static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { - struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u16 control = 0; - pi->frames_sent = 0; + chan->frames_sent = 0; control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; @@ -2806,7 +2805,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) l2cap_ertm_send(chan); if (!(chan->conn_state & L2CAP_CONN_LOCAL_BUSY) && - pi->frames_sent == 0) { + chan->frames_sent == 0) { control |= L2CAP_SUPER_RCV_READY; l2cap_send_sframe(chan, control); } @@ -2988,7 +2987,7 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; l2cap_send_sframe(chan, control); - l2cap_pi(sk)->retry_count = 1; + chan->retry_count = 1; del_timer(&pi->retrans_timer); __mod_monitor_timer(); @@ -3260,7 +3259,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont if (L2CAP_CTRL_FINAL & rx_control && chan->conn_state & L2CAP_CONN_WAIT_F) { del_timer(&pi->monitor_timer); - if (pi->unacked_frames > 0) + if (chan->unacked_frames > 0) __mod_retrans_timer(); chan->conn_state &= ~L2CAP_CONN_WAIT_F; } @@ -3369,8 +3368,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont __mod_ack_timer(); - pi->num_acked = (pi->num_acked + 1) % num_to_ack; - if (pi->num_acked == num_to_ack - 1) + chan->num_acked = (chan->num_acked + 1) % num_to_ack; + if (chan->num_acked == num_to_ack - 1) l2cap_send_ack(chan); return 0; @@ -3383,7 +3382,6 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control) { struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), rx_control); @@ -3395,7 +3393,7 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co chan->conn_state |= L2CAP_CONN_SEND_FBIT; if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && - (pi->unacked_frames > 0)) + (chan->unacked_frames > 0)) __mod_retrans_timer(); chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; @@ -3414,7 +3412,7 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co } else { if ((chan->conn_state & L2CAP_CONN_REMOTE_BUSY) && - (pi->unacked_frames > 0)) + (chan->unacked_frames > 0)) __mod_retrans_timer(); chan->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; @@ -3450,7 +3448,6 @@ static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_c } static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) { - struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_reqseq(rx_control); BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); @@ -3467,19 +3464,19 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ l2cap_ertm_send(chan); if (chan->conn_state & L2CAP_CONN_WAIT_F) { - pi->srej_save_reqseq = tx_seq; + chan->srej_save_reqseq = tx_seq; chan->conn_state |= L2CAP_CONN_SREJ_ACT; } } else if (rx_control & L2CAP_CTRL_FINAL) { if ((chan->conn_state & L2CAP_CONN_SREJ_ACT) && - pi->srej_save_reqseq == tx_seq) + chan->srej_save_reqseq == tx_seq) chan->conn_state &= ~L2CAP_CONN_SREJ_ACT; else l2cap_retransmit_one_frame(chan, tx_seq); } else { l2cap_retransmit_one_frame(chan, tx_seq); if (chan->conn_state & L2CAP_CONN_WAIT_F) { - pi->srej_save_reqseq = tx_seq; + chan->srej_save_reqseq = tx_seq; chan->conn_state |= L2CAP_CONN_SREJ_ACT; } } @@ -3521,7 +3518,7 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont if (L2CAP_CTRL_FINAL & rx_control && chan->conn_state & L2CAP_CONN_WAIT_F) { del_timer(&l2cap_pi(sk)->monitor_timer); - if (l2cap_pi(sk)->unacked_frames > 0) + if (chan->unacked_frames > 0) __mod_retrans_timer(); chan->conn_state &= ~L2CAP_CONN_WAIT_F; } -- GitLab From 6f61fd475907bf0a1470cb969ee993a31d305513 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 20:09:37 -0300 Subject: [PATCH 0623/5560] Bluetooth: Move SDU related vars to struct l2cap_chan As part of the moving channel stuff to l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 8 ++-- net/bluetooth/l2cap_core.c | 74 +++++++++++++++++------------------ 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 041213b4175a..19d613bbcf00 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -298,6 +298,10 @@ struct l2cap_chan { __u8 unacked_frames; __u8 retry_count; __u8 num_acked; + __u16 sdu_len; + __u16 partial_sdu_len; + struct sk_buff *sdu; + struct list_head list; }; @@ -364,10 +368,6 @@ struct l2cap_pinfo { __u8 conf_state; - __u16 sdu_len; - __u16 partial_sdu_len; - struct sk_buff *sdu; - __u8 tx_win; __u8 max_tx; __u8 remote_tx_win; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3f601d1c164a..8ccfcdf3e083 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2875,13 +2875,13 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk if (chan->conn_state & L2CAP_CONN_SAR_SDU) goto drop; - pi->sdu_len = get_unaligned_le16(skb->data); + chan->sdu_len = get_unaligned_le16(skb->data); - if (pi->sdu_len > pi->imtu) + if (chan->sdu_len > pi->imtu) goto disconnect; - pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); - if (!pi->sdu) + chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); + if (!chan->sdu) return -ENOMEM; /* pull sdu_len bytes only after alloc, because of Local Busy @@ -2889,24 +2889,24 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk * only once, i.e., when alloc does not fail */ skb_pull(skb, 2); - memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); + memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); chan->conn_state |= L2CAP_CONN_SAR_SDU; - pi->partial_sdu_len = skb->len; + chan->partial_sdu_len = skb->len; break; case L2CAP_SDU_CONTINUE: if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) goto disconnect; - if (!pi->sdu) + if (!chan->sdu) goto disconnect; - pi->partial_sdu_len += skb->len; - if (pi->partial_sdu_len > pi->sdu_len) + chan->partial_sdu_len += skb->len; + if (chan->partial_sdu_len > chan->sdu_len) goto drop; - memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); + memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); break; @@ -2914,22 +2914,22 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) goto disconnect; - if (!pi->sdu) + if (!chan->sdu) goto disconnect; if (!(chan->conn_state & L2CAP_CONN_SAR_RETRY)) { - pi->partial_sdu_len += skb->len; + chan->partial_sdu_len += skb->len; - if (pi->partial_sdu_len > pi->imtu) + if (chan->partial_sdu_len > pi->imtu) goto drop; - if (pi->partial_sdu_len != pi->sdu_len) + if (chan->partial_sdu_len != chan->sdu_len) goto drop; - memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); + memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); } - _skb = skb_clone(pi->sdu, GFP_ATOMIC); + _skb = skb_clone(chan->sdu, GFP_ATOMIC); if (!_skb) { chan->conn_state |= L2CAP_CONN_SAR_RETRY; return -ENOMEM; @@ -2945,7 +2945,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk chan->conn_state &= ~L2CAP_CONN_SAR_RETRY; chan->conn_state &= ~L2CAP_CONN_SAR_SDU; - kfree_skb(pi->sdu); + kfree_skb(chan->sdu); break; } @@ -2953,8 +2953,8 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk return 0; drop: - kfree_skb(pi->sdu); - pi->sdu = NULL; + kfree_skb(chan->sdu); + chan->sdu = NULL; disconnect: l2cap_send_disconn_req(pi->conn, chan->sk, ECONNRESET); @@ -3104,7 +3104,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf switch (control & L2CAP_CTRL_SAR) { case L2CAP_SDU_UNSEGMENTED: if (chan->conn_state & L2CAP_CONN_SAR_SDU) { - kfree_skb(pi->sdu); + kfree_skb(chan->sdu); break; } @@ -3116,28 +3116,28 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf case L2CAP_SDU_START: if (chan->conn_state & L2CAP_CONN_SAR_SDU) { - kfree_skb(pi->sdu); + kfree_skb(chan->sdu); break; } - pi->sdu_len = get_unaligned_le16(skb->data); + chan->sdu_len = get_unaligned_le16(skb->data); skb_pull(skb, 2); - if (pi->sdu_len > pi->imtu) { + if (chan->sdu_len > pi->imtu) { err = -EMSGSIZE; break; } - pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC); - if (!pi->sdu) { + chan->sdu = bt_skb_alloc(chan->sdu_len, GFP_ATOMIC); + if (!chan->sdu) { err = -ENOMEM; break; } - memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); + memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); chan->conn_state |= L2CAP_CONN_SAR_SDU; - pi->partial_sdu_len = skb->len; + chan->partial_sdu_len = skb->len; err = 0; break; @@ -3145,11 +3145,11 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) break; - memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); + memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); - pi->partial_sdu_len += skb->len; - if (pi->partial_sdu_len > pi->sdu_len) - kfree_skb(pi->sdu); + chan->partial_sdu_len += skb->len; + if (chan->partial_sdu_len > chan->sdu_len) + kfree_skb(chan->sdu); else err = 0; @@ -3159,16 +3159,16 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf if (!(chan->conn_state & L2CAP_CONN_SAR_SDU)) break; - memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); + memcpy(skb_put(chan->sdu, skb->len), skb->data, skb->len); chan->conn_state &= ~L2CAP_CONN_SAR_SDU; - pi->partial_sdu_len += skb->len; + chan->partial_sdu_len += skb->len; - if (pi->partial_sdu_len > pi->imtu) + if (chan->partial_sdu_len > pi->imtu) goto drop; - if (pi->partial_sdu_len == pi->sdu_len) { - _skb = skb_clone(pi->sdu, GFP_ATOMIC); + if (chan->partial_sdu_len == chan->sdu_len) { + _skb = skb_clone(chan->sdu, GFP_ATOMIC); err = sock_queue_rcv_skb(chan->sk, _skb); if (err < 0) kfree_skb(_skb); @@ -3176,7 +3176,7 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf err = 0; drop: - kfree_skb(pi->sdu); + kfree_skb(chan->sdu); break; } -- GitLab From 2c03a7a49e0831646bd35d0877ec7d051d8f174b Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 20:15:28 -0300 Subject: [PATCH 0624/5560] Bluetooth: Move remote info to struct l2cap_chan As part of the moving channel stuff to l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 10 +++++----- net/bluetooth/l2cap_core.c | 32 ++++++++++++++++---------------- net/bluetooth/l2cap_sock.c | 4 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 19d613bbcf00..11c53cb4a116 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -302,6 +302,9 @@ struct l2cap_chan { __u16 partial_sdu_len; struct sk_buff *sdu; + __u8 remote_tx_win; + __u8 remote_max_tx; + __u16 remote_mps; struct list_head list; }; @@ -370,11 +373,8 @@ struct l2cap_pinfo { __u8 tx_win; __u8 max_tx; - __u8 remote_tx_win; - __u8 remote_max_tx; __u16 retrans_timeout; __u16 monitor_timeout; - __u16 remote_mps; __u16 mps; __le16 sport; @@ -431,7 +431,7 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch) if (sub < 0) sub += 64; - return sub == l2cap_pi(ch->sk)->remote_tx_win; + return sub == ch->remote_tx_win; } #define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) @@ -454,7 +454,7 @@ int __l2cap_wait_ack(struct sock *sk); struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len); struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen); -int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len); +int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len); void l2cap_do_send(struct sock *sk, struct sk_buff *skb); void l2cap_streaming_send(struct l2cap_chan *chan); int l2cap_ertm_send(struct l2cap_chan *chan); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8ccfcdf3e083..2176a003087e 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -956,7 +956,7 @@ static void l2cap_monitor_timeout(unsigned long arg) BT_DBG("chan %p", chan); bh_lock_sock(sk); - if (chan->retry_count >= l2cap_pi(sk)->remote_max_tx) { + if (chan->retry_count >= chan->remote_max_tx) { l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); bh_unlock_sock(sk); return; @@ -1065,8 +1065,8 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) } while ((skb = skb_queue_next(TX_QUEUE(sk), skb))); - if (pi->remote_max_tx && - bt_cb(skb)->retries == pi->remote_max_tx) { + if (chan->remote_max_tx && + bt_cb(skb)->retries == chan->remote_max_tx) { l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); return; } @@ -1106,8 +1106,8 @@ int l2cap_ertm_send(struct l2cap_chan *chan) while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(chan))) { - if (pi->remote_max_tx && - bt_cb(skb)->retries == pi->remote_max_tx) { + if (chan->remote_max_tx && + bt_cb(skb)->retries == chan->remote_max_tx) { l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); break; } @@ -1337,9 +1337,9 @@ struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, siz return skb; } -int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) +int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct sock *sk = chan->sk; struct sk_buff *skb; struct sk_buff_head sar_queue; u16 control; @@ -1347,20 +1347,20 @@ int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) skb_queue_head_init(&sar_queue); control = L2CAP_SDU_START; - skb = l2cap_create_iframe_pdu(sk, msg, pi->remote_mps, control, len); + skb = l2cap_create_iframe_pdu(sk, msg, chan->remote_mps, control, len); if (IS_ERR(skb)) return PTR_ERR(skb); __skb_queue_tail(&sar_queue, skb); - len -= pi->remote_mps; - size += pi->remote_mps; + len -= chan->remote_mps; + size += chan->remote_mps; while (len > 0) { size_t buflen; - if (len > pi->remote_mps) { + if (len > chan->remote_mps) { control = L2CAP_SDU_CONTINUE; - buflen = pi->remote_mps; + buflen = chan->remote_mps; } else { control = L2CAP_SDU_END; buflen = len; @@ -1810,13 +1810,13 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) break; case L2CAP_MODE_ERTM: - pi->remote_tx_win = rfc.txwin_size; - pi->remote_max_tx = rfc.max_transmit; + chan->remote_tx_win = rfc.txwin_size; + chan->remote_max_tx = rfc.max_transmit; if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); - pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); + chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); rfc.retrans_timeout = le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); @@ -1834,7 +1834,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); - pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); + chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); pi->conf_state |= L2CAP_CONF_MODE_DONE; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 19574e43226a..f90ca2586eaf 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -757,7 +757,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms case L2CAP_MODE_ERTM: case L2CAP_MODE_STREAMING: /* Entire SDU fits into one PDU */ - if (len <= pi->remote_mps) { + if (len <= pi->chan->remote_mps) { control = L2CAP_SDU_UNSEGMENTED; skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); if (IS_ERR(skb)) { @@ -771,7 +771,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms } else { /* Segment SDU into multiples PDUs */ - err = l2cap_sar_segment_sdu(sk, msg, len); + err = l2cap_sar_segment_sdu(pi->chan, msg, len); if (err < 0) goto done; } -- GitLab From e92c8e70faf5e3cc22979daba2a895359aa1eab2 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 1 Apr 2011 00:53:45 -0300 Subject: [PATCH 0625/5560] Bluetooth: Move ERTM timers to struct l2cap_chan This also triggered a change in l2cap_send_disconn_req() parameters. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 15 +++---- net/bluetooth/l2cap_core.c | 74 +++++++++++++++++------------------ net/bluetooth/l2cap_sock.c | 13 +++--- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 11c53cb4a116..5f4abea313a2 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -306,6 +306,10 @@ struct l2cap_chan { __u8 remote_max_tx; __u16 remote_mps; + struct timer_list retrans_timer; + struct timer_list monitor_timer; + struct timer_list ack_timer; + struct list_head list; }; @@ -379,9 +383,6 @@ struct l2cap_pinfo { __le16 sport; - struct timer_list retrans_timer; - struct timer_list monitor_timer; - struct timer_list ack_timer; struct sk_buff_head tx_queue; struct sk_buff_head srej_queue; struct sk_buff_head busy_queue; @@ -415,11 +416,11 @@ struct l2cap_pinfo { #define L2CAP_CONN_RNR_SENT 0x0200 #define L2CAP_CONN_SAR_RETRY 0x0400 -#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \ +#define __mod_retrans_timer() mod_timer(&chan->retrans_timer, \ jiffies + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); -#define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \ +#define __mod_monitor_timer() mod_timer(&chan->monitor_timer, \ jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); -#define __mod_ack_timer() mod_timer(&l2cap_pi(sk)->ack_timer, \ +#define __mod_ack_timer() mod_timer(&chan->ack_timer, \ jiffies + msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); static inline int l2cap_tx_window_full(struct l2cap_chan *ch) @@ -466,7 +467,7 @@ void l2cap_sock_kill(struct sock *sk); void l2cap_sock_init(struct sock *sk, struct sock *parent); struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); -void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err); +void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); void l2cap_chan_del(struct l2cap_chan *chan, int err); int l2cap_do_connect(struct sock *sk); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 2176a003087e..eaac13cb7932 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -241,9 +241,9 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { struct srej_list *l, *tmp; - del_timer(&l2cap_pi(sk)->retrans_timer); - del_timer(&l2cap_pi(sk)->monitor_timer); - del_timer(&l2cap_pi(sk)->ack_timer); + del_timer(&chan->retrans_timer); + del_timer(&chan->monitor_timer); + del_timer(&chan->ack_timer); skb_queue_purge(SREJ_QUEUE(sk)); skb_queue_purge(BUSY_QUEUE(sk)); @@ -462,19 +462,22 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) } } -void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) +void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) { + struct sock *sk; struct l2cap_disconn_req req; if (!conn) return; + sk = chan->sk; + skb_queue_purge(TX_QUEUE(sk)); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { - del_timer(&l2cap_pi(sk)->retrans_timer); - del_timer(&l2cap_pi(sk)->monitor_timer); - del_timer(&l2cap_pi(sk)->ack_timer); + del_timer(&chan->retrans_timer); + del_timer(&chan->monitor_timer); + del_timer(&chan->ack_timer); } req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid); @@ -957,7 +960,7 @@ static void l2cap_monitor_timeout(unsigned long arg) bh_lock_sock(sk); if (chan->retry_count >= chan->remote_max_tx) { - l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk, ECONNABORTED); + l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, ECONNABORTED); bh_unlock_sock(sk); return; } @@ -1003,7 +1006,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) } if (!chan->unacked_frames) - del_timer(&l2cap_pi(sk)->retrans_timer); + del_timer(&chan->retrans_timer); } void l2cap_do_send(struct sock *sk, struct sk_buff *skb) @@ -1067,7 +1070,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) if (chan->remote_max_tx && bt_cb(skb)->retries == chan->remote_max_tx) { - l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); + l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED); return; } @@ -1108,7 +1111,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan) if (chan->remote_max_tx && bt_cb(skb)->retries == chan->remote_max_tx) { - l2cap_send_disconn_req(pi->conn, sk, ECONNABORTED); + l2cap_send_disconn_req(pi->conn, chan, ECONNABORTED); break; } @@ -1579,12 +1582,11 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) chan->num_acked = 0; chan->frames_sent = 0; - setup_timer(&l2cap_pi(sk)->retrans_timer, - l2cap_retrans_timeout, (unsigned long) chan); - setup_timer(&l2cap_pi(sk)->monitor_timer, - l2cap_monitor_timeout, (unsigned long) chan); - setup_timer(&l2cap_pi(sk)->ack_timer, - l2cap_ack_timeout, (unsigned long) chan); + setup_timer(&chan->retrans_timer, l2cap_retrans_timeout, + (unsigned long) chan); + setup_timer(&chan->monitor_timer, l2cap_monitor_timeout, + (unsigned long) chan); + setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan); __skb_queue_head_init(SREJ_QUEUE(sk)); __skb_queue_head_init(BUSY_QUEUE(sk)); @@ -2291,7 +2293,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr /* Complete config. */ len = l2cap_parse_conf_req(chan, rsp); if (len < 0) { - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto unlock; } @@ -2363,7 +2365,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr char req[64]; if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -2372,7 +2374,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr len = l2cap_parse_conf_rsp(sk, rsp->data, len, req, &result); if (len < 0) { - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -2387,7 +2389,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr default: sk->sk_err = ECONNRESET; l2cap_sock_set_timer(sk, HZ * 5); - l2cap_send_disconn_req(conn, sk, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -2957,7 +2959,7 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk chan->sdu = NULL; disconnect: - l2cap_send_disconn_req(pi->conn, chan->sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); kfree_skb(skb); return 0; } @@ -2965,7 +2967,6 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) { struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); struct sk_buff *skb; u16 control; int err; @@ -2989,7 +2990,7 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) l2cap_send_sframe(chan, control); chan->retry_count = 1; - del_timer(&pi->retrans_timer); + del_timer(&chan->retrans_timer); __mod_monitor_timer(); chan->conn_state |= L2CAP_CONN_WAIT_F; @@ -3020,7 +3021,7 @@ static void l2cap_busy_work(struct work_struct *work) if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { err = -EBUSY; - l2cap_send_disconn_req(pi->conn, sk, EBUSY); + l2cap_send_disconn_req(pi->conn, pi->chan, EBUSY); break; } @@ -3083,7 +3084,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c chan->conn_state |= L2CAP_CONN_RNR_SENT; - del_timer(&pi->ack_timer); + del_timer(&chan->ack_timer); queue_work(_busy_wq, &pi->busy_work); @@ -3258,7 +3259,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont if (L2CAP_CTRL_FINAL & rx_control && chan->conn_state & L2CAP_CONN_WAIT_F) { - del_timer(&pi->monitor_timer); + del_timer(&chan->monitor_timer); if (chan->unacked_frames > 0) __mod_retrans_timer(); chan->conn_state &= ~L2CAP_CONN_WAIT_F; @@ -3276,7 +3277,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont /* invalid tx_seq */ if (tx_seq_offset >= pi->tx_win) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); goto drop; } @@ -3341,7 +3342,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont l2cap_send_srejframe(chan, tx_seq); - del_timer(&pi->ack_timer); + del_timer(&chan->ack_timer); } return 0; @@ -3484,7 +3485,6 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control) { - struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_reqseq(rx_control); BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); @@ -3497,7 +3497,7 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c chan->conn_state |= L2CAP_CONN_SEND_FBIT; if (!(chan->conn_state & L2CAP_CONN_SREJ_SENT)) { - del_timer(&pi->retrans_timer); + del_timer(&chan->retrans_timer); if (rx_control & L2CAP_CTRL_POLL) l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); return; @@ -3511,13 +3511,11 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_c static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) { - struct sock *sk = chan->sk; - BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); if (L2CAP_CTRL_FINAL & rx_control && chan->conn_state & L2CAP_CONN_WAIT_F) { - del_timer(&l2cap_pi(sk)->monitor_timer); + del_timer(&chan->monitor_timer); if (chan->unacked_frames > 0) __mod_retrans_timer(); chan->conn_state &= ~L2CAP_CONN_WAIT_F; @@ -3572,7 +3570,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) len -= 2; if (len > pi->mps) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); goto drop; } @@ -3588,13 +3586,13 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) /* check for invalid req-seq */ if (req_seq_offset > next_tx_seq_offset) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); goto drop; } if (__is_iframe(control)) { if (len < 0) { - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); goto drop; } @@ -3602,7 +3600,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) } else { if (len != 0) { BT_ERR("%d", len); - l2cap_send_disconn_req(pi->conn, sk, ECONNRESET); + l2cap_send_disconn_req(pi->conn, chan, ECONNRESET); goto drop; } diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index f90ca2586eaf..d66886f7eccb 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -866,6 +866,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) void __l2cap_sock_close(struct sock *sk, int reason) { struct l2cap_conn *conn = l2cap_pi(sk)->conn; + struct l2cap_chan *chan = l2cap_pi(sk)->chan; BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); @@ -880,9 +881,9 @@ void __l2cap_sock_close(struct sock *sk, int reason) sk->sk_type == SOCK_STREAM) && conn->hcon->type == ACL_LINK) { l2cap_sock_set_timer(sk, sk->sk_sndtimeo); - l2cap_send_disconn_req(conn, sk, reason); + l2cap_send_disconn_req(conn, chan, reason); } else - l2cap_chan_del(l2cap_pi(sk)->chan, reason); + l2cap_chan_del(chan, reason); break; case BT_CONNECT2: @@ -901,16 +902,16 @@ void __l2cap_sock_close(struct sock *sk, int reason) rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.result = cpu_to_le16(result); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(conn, l2cap_pi(sk)->chan->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, + sizeof(rsp), &rsp); } - l2cap_chan_del(l2cap_pi(sk)->chan, reason); + l2cap_chan_del(chan, reason); break; case BT_CONNECT: case BT_DISCONN: - l2cap_chan_del(l2cap_pi(sk)->chan, reason); + l2cap_chan_del(chan, reason); break; default: -- GitLab From f1c6775be6fc944e32e0150305d9753b9a846519 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 20:36:10 -0300 Subject: [PATCH 0626/5560] Bluetooth: Move srej and busy queues to struct l2cap_chan As part of the moving channel stuff to l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 6 ++--- net/bluetooth/l2cap_core.c | 42 +++++++++++++++++------------------ net/bluetooth/l2cap_sock.c | 2 -- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 5f4abea313a2..09f4a2fc2e20 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -309,6 +309,8 @@ struct l2cap_chan { struct timer_list retrans_timer; struct timer_list monitor_timer; struct timer_list ack_timer; + struct sk_buff_head srej_q; + struct sk_buff_head busy_q; struct list_head list; }; @@ -347,8 +349,6 @@ struct l2cap_conn { /* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) #define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue) -#define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue) -#define BUSY_QUEUE(sk) (&l2cap_pi(sk)->busy_queue) #define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list) struct srej_list { @@ -384,8 +384,6 @@ struct l2cap_pinfo { __le16 sport; struct sk_buff_head tx_queue; - struct sk_buff_head srej_queue; - struct sk_buff_head busy_queue; struct work_struct busy_work; struct srej_list srej_l; struct l2cap_conn *conn; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index eaac13cb7932..06c505b1476d 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -245,8 +245,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) del_timer(&chan->monitor_timer); del_timer(&chan->ack_timer); - skb_queue_purge(SREJ_QUEUE(sk)); - skb_queue_purge(BUSY_QUEUE(sk)); + skb_queue_purge(&chan->srej_q); + skb_queue_purge(&chan->busy_q); list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { list_del(&l->list); @@ -1588,8 +1588,8 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) (unsigned long) chan); setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan); - __skb_queue_head_init(SREJ_QUEUE(sk)); - __skb_queue_head_init(BUSY_QUEUE(sk)); + skb_queue_head_init(&chan->srej_q); + skb_queue_head_init(&chan->busy_q); INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); @@ -2815,16 +2815,15 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar) { - struct sock *sk = chan->sk; struct sk_buff *next_skb; int tx_seq_offset, next_tx_seq_offset; bt_cb(skb)->tx_seq = tx_seq; bt_cb(skb)->sar = sar; - next_skb = skb_peek(SREJ_QUEUE(sk)); + next_skb = skb_peek(&chan->srej_q); if (!next_skb) { - __skb_queue_tail(SREJ_QUEUE(sk), skb); + __skb_queue_tail(&chan->srej_q, skb); return 0; } @@ -2842,16 +2841,16 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, next_tx_seq_offset += 64; if (next_tx_seq_offset > tx_seq_offset) { - __skb_queue_before(SREJ_QUEUE(sk), next_skb, skb); + __skb_queue_before(&chan->srej_q, next_skb, skb); return 0; } - if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb)) + if (skb_queue_is_last(&chan->srej_q, next_skb)) break; - } while ((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb))); + } while ((next_skb = skb_queue_next(&chan->srej_q, next_skb))); - __skb_queue_tail(SREJ_QUEUE(sk), skb); + __skb_queue_tail(&chan->srej_q, skb); return 0; } @@ -2971,11 +2970,11 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) u16 control; int err; - while ((skb = skb_dequeue(BUSY_QUEUE(sk)))) { + while ((skb = skb_dequeue(&chan->busy_q))) { control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; err = l2cap_ertm_reassembly_sdu(chan, skb, control); if (err < 0) { - skb_queue_head(BUSY_QUEUE(sk), skb); + skb_queue_head(&chan->busy_q, skb); return -EBUSY; } @@ -3016,7 +3015,7 @@ static void l2cap_busy_work(struct work_struct *work) lock_sock(sk); add_wait_queue(sk_sleep(sk), &wait); - while ((skb = skb_peek(BUSY_QUEUE(sk)))) { + while ((skb = skb_peek(&pi->chan->busy_q))) { set_current_state(TASK_INTERRUPTIBLE); if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { @@ -3059,7 +3058,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; - __skb_queue_tail(BUSY_QUEUE(sk), skb); + __skb_queue_tail(&chan->busy_q, skb); return l2cap_try_push_rx_skb(chan); @@ -3076,7 +3075,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c chan->conn_state |= L2CAP_CONN_LOCAL_BUSY; bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; - __skb_queue_tail(BUSY_QUEUE(sk), skb); + __skb_queue_tail(&chan->busy_q, skb); sctrl = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; sctrl |= L2CAP_SUPER_RCV_NOT_READY; @@ -3187,15 +3186,14 @@ static int l2cap_streaming_reassembly_sdu(struct l2cap_chan *chan, struct sk_buf static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) { - struct sock *sk = chan->sk; struct sk_buff *skb; u16 control; - while ((skb = skb_peek(SREJ_QUEUE(sk)))) { + while ((skb = skb_peek(&chan->srej_q))) { if (bt_cb(skb)->tx_seq != tx_seq) break; - skb = skb_dequeue(SREJ_QUEUE(sk)); + skb = skb_dequeue(&chan->srej_q); control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; l2cap_ertm_reassembly_sdu(chan, skb, control); chan->buffer_seq_srej = @@ -3334,8 +3332,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont INIT_LIST_HEAD(SREJ_LIST(sk)); chan->buffer_seq_srej = chan->buffer_seq; - __skb_queue_head_init(SREJ_QUEUE(sk)); - __skb_queue_head_init(BUSY_QUEUE(sk)); + __skb_queue_head_init(&chan->srej_q); + __skb_queue_head_init(&chan->busy_q); l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); chan->conn_state |= L2CAP_CONN_SEND_PBIT; @@ -3352,7 +3350,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { bt_cb(skb)->tx_seq = tx_seq; bt_cb(skb)->sar = sar; - __skb_queue_tail(SREJ_QUEUE(sk), skb); + __skb_queue_tail(&chan->srej_q, skb); return 0; } diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d66886f7eccb..55dee999af94 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1018,8 +1018,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) /* Default config options */ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; skb_queue_head_init(TX_QUEUE(sk)); - skb_queue_head_init(SREJ_QUEUE(sk)); - skb_queue_head_init(BUSY_QUEUE(sk)); INIT_LIST_HEAD(SREJ_LIST(sk)); } -- GitLab From 311bb895e325e5f4d708c1ed2206da8a3885c83a Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 25 Mar 2011 20:41:00 -0300 Subject: [PATCH 0627/5560] Bluetooth: Move busy workqueue to struct l2cap_chan As part of the moving channel stuff to l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 2 +- net/bluetooth/l2cap_core.c | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 09f4a2fc2e20..d05d91f2fd32 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -311,6 +311,7 @@ struct l2cap_chan { struct timer_list ack_timer; struct sk_buff_head srej_q; struct sk_buff_head busy_q; + struct work_struct busy_work; struct list_head list; }; @@ -384,7 +385,6 @@ struct l2cap_pinfo { __le16 sport; struct sk_buff_head tx_queue; - struct work_struct busy_work; struct srej_list srej_l; struct l2cap_conn *conn; struct l2cap_chan *chan; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 06c505b1476d..d3b5d6489a80 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1591,7 +1591,7 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->srej_q); skb_queue_head_init(&chan->busy_q); - INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); + INIT_WORK(&chan->busy_work, l2cap_busy_work); sk->sk_backlog_rcv = l2cap_ertm_data_rcv; } @@ -3006,21 +3006,21 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) static void l2cap_busy_work(struct work_struct *work) { DECLARE_WAITQUEUE(wait, current); - struct l2cap_pinfo *pi = - container_of(work, struct l2cap_pinfo, busy_work); - struct sock *sk = (struct sock *)pi; + struct l2cap_chan *chan = + container_of(work, struct l2cap_chan, busy_work); + struct sock *sk = chan->sk; int n_tries = 0, timeo = HZ/5, err; struct sk_buff *skb; lock_sock(sk); add_wait_queue(sk_sleep(sk), &wait); - while ((skb = skb_peek(&pi->chan->busy_q))) { + while ((skb = skb_peek(&chan->busy_q))) { set_current_state(TASK_INTERRUPTIBLE); if (n_tries++ > L2CAP_LOCAL_BUSY_TRIES) { err = -EBUSY; - l2cap_send_disconn_req(pi->conn, pi->chan, EBUSY); + l2cap_send_disconn_req(l2cap_pi(sk)->conn, chan, EBUSY); break; } @@ -3040,7 +3040,7 @@ static void l2cap_busy_work(struct work_struct *work) if (err) break; - if (l2cap_try_push_rx_skb(l2cap_pi(sk)->chan) == 0) + if (l2cap_try_push_rx_skb(chan) == 0) break; } @@ -3052,8 +3052,6 @@ static void l2cap_busy_work(struct work_struct *work) static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) { - struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); int sctrl, err; if (chan->conn_state & L2CAP_CONN_LOCAL_BUSY) { @@ -3071,7 +3069,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c } /* Busy Condition */ - BT_DBG("sk %p, Enter local busy", sk); + BT_DBG("chan %p, Enter local busy", chan); chan->conn_state |= L2CAP_CONN_LOCAL_BUSY; bt_cb(skb)->sar = control >> L2CAP_CTRL_SAR_SHIFT; @@ -3085,7 +3083,7 @@ static int l2cap_push_rx_skb(struct l2cap_chan *chan, struct sk_buff *skb, u16 c del_timer(&chan->ack_timer); - queue_work(_busy_wq, &pi->busy_work); + queue_work(_busy_wq, &chan->busy_work); return err; } -- GitLab From 2ead70b8390d199ca04cd35311b51f5f3676079e Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Fri, 1 Apr 2011 15:13:36 -0300 Subject: [PATCH 0628/5560] Bluetooth: Fix lockdep warning with skb list lock This is a regression acctually, caused by the first patch series for creating a formal strcut l2cap_chan. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d3b5d6489a80..7264119b64a6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -236,6 +236,10 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) } else sk->sk_state_change(sk); + if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE && + l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE)) + goto free; + skb_queue_purge(TX_QUEUE(sk)); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { @@ -254,6 +258,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) } } +free: kfree(chan); } -- GitLab From 4b97291429bf59c09a969184a7d2ebde7287e7eb Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 6 Apr 2011 18:07:43 +0000 Subject: [PATCH 0629/5560] be2net: add rxhash support Add rxhash support, Based on initial work by Eric Dumazet. Cc: Eric Dumazet Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 5 +++++ drivers/net/benet/be_ethtool.c | 13 +++++++++++++ drivers/net/benet/be_main.c | 17 ++++++++++++----- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index ea1ea824d7c7..ab5be0545e38 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -485,6 +485,11 @@ static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) memcpy(mac, adapter->netdev->dev_addr, 3); } +static inline bool be_multi_rxq(const struct be_adapter *adapter) +{ + return adapter->num_rx_qs > 1; +} + extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index a665697df824..1565c81ff96c 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -735,6 +735,18 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, return status; } +static int be_set_flags(struct net_device *netdev, u32 data) +{ + struct be_adapter *adapter = netdev_priv(netdev); + int rc = -1; + + if (be_multi_rxq(adapter)) + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXHASH | + ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); + + return rc; +} + const struct ethtool_ops be_ethtool_ops = { .get_settings = be_get_settings, .get_drvinfo = be_get_drvinfo, @@ -764,4 +776,5 @@ const struct ethtool_ops be_ethtool_ops = { .get_regs = be_get_regs, .flash_device = be_do_flash, .self_test = be_self_test, + .set_flags = be_set_flags, }; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 2c3685389485..d762c2a3dd9b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -116,11 +116,6 @@ static char *ue_status_hi_desc[] = { "Unknown" }; -static inline bool be_multi_rxq(struct be_adapter *adapter) -{ - return (adapter->num_rx_qs > 1); -} - static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) { struct be_dma_mem *mem = &q->dma_mem; @@ -1012,6 +1007,9 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb->truesize = skb->len + sizeof(struct sk_buff); skb->protocol = eth_type_trans(skb, adapter->netdev); + if (adapter->netdev->features & NETIF_F_RXHASH) + skb->rxhash = rxcp->rss_hash; + if (unlikely(rxcp->vlanf)) { if (!adapter->vlan_grp || adapter->vlans_added == 0) { @@ -1072,6 +1070,8 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, skb->data_len = rxcp->pkt_size; skb->truesize += rxcp->pkt_size; skb->ip_summed = CHECKSUM_UNNECESSARY; + if (adapter->netdev->features & NETIF_F_RXHASH) + skb->rxhash = rxcp->rss_hash; if (likely(!rxcp->vlanf)) napi_gro_frags(&eq_obj->napi); @@ -1101,6 +1101,8 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter, AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); rxcp->pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); + rxcp->rss_hash = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp); if (rxcp->vlanf) { rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); @@ -1131,6 +1133,8 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter, AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); rxcp->pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); + rxcp->rss_hash = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp); if (rxcp->vlanf) { rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); @@ -2615,6 +2619,9 @@ static void be_netdev_init(struct net_device *netdev) NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_TSO6; + if (be_multi_rxq(adapter)) + netdev->features |= NETIF_F_RXHASH; + netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; -- GitLab From b0060586d23968d66325d775651d92ee830c032f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 6 Apr 2011 18:08:01 +0000 Subject: [PATCH 0630/5560] be2net: use common method to check for sriov function type Lancer and BE can both use SLI_INTF_REG to check a VF or a PF. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index ab5be0545e38..7e2040084654 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -458,18 +458,10 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) static inline void be_check_sriov_fn_type(struct be_adapter *adapter) { - u8 data; 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); - } + pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf); + adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; } static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) -- GitLab From 81be8f0ab47db1171dac0eb8b062291603b57dd4 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 6 Apr 2011 18:08:17 +0000 Subject: [PATCH 0631/5560] be2net: fix to get max VFs supported from adapter The user supplied num_vfs value need not be compared against a static BE_MAX_VF, but can be checked against the actual VFs that the device can support. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index d762c2a3dd9b..bc110782da88 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1947,7 +1947,20 @@ static void be_sriov_enable(struct be_adapter *adapter) be_check_sriov_fn_type(adapter); #ifdef CONFIG_PCI_IOV if (be_physfn(adapter) && num_vfs) { - int status; + int status, pos; + u16 nvfs; + + pos = pci_find_ext_capability(adapter->pdev, + PCI_EXT_CAP_ID_SRIOV); + pci_read_config_word(adapter->pdev, + pos + PCI_SRIOV_TOTAL_VF, &nvfs); + + if (num_vfs > nvfs) { + dev_info(&adapter->pdev->dev, + "Device supports %d VFs and not %d\n", + nvfs, num_vfs); + num_vfs = nvfs; + } status = pci_enable_sriov(adapter->pdev, num_vfs); adapter->sriov_enabled = status ? false : true; @@ -3284,13 +3297,6 @@ static int __init be_init_module(void) rx_frag_size = 2048; } - if (num_vfs > 32) { - printk(KERN_WARNING DRV_NAME - " : Module param num_vfs must not be greater than 32." - "Using 32\n"); - num_vfs = 32; - } - return pci_register_driver(&be_driver); } module_init(be_init_module); -- GitLab From 48f5a19168c228e6533401c563d9fcbc152bc33f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 6 Apr 2011 18:08:30 +0000 Subject: [PATCH 0632/5560] be2net: dynamically allocate adapter->vf_cfg Instead of a fixed sized array for vf_cfg, allocate the size dynamically depending on number of VFs the device supports. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 4 +--- drivers/net/benet/be_main.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 7e2040084654..d2c42f5d5e9e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -92,8 +92,6 @@ static inline char *nic_name(struct pci_dev *pdev) #define FW_VER_LEN 32 -#define BE_MAX_VF 32 - struct be_dma_mem { void *va; dma_addr_t dma; @@ -336,7 +334,7 @@ struct be_adapter { bool be3_native; bool sriov_enabled; - struct be_vf_cfg vf_cfg[BE_MAX_VF]; + struct be_vf_cfg *vf_cfg; u8 is_virtfn; u32 sli_family; u8 hba_port_num; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index bc110782da88..6e7df0dd418b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2838,6 +2838,7 @@ static void __devexit be_remove(struct pci_dev *pdev) be_ctrl_cleanup(adapter); + kfree(adapter->vf_cfg); be_sriov_disable(adapter); be_msix_disable(adapter); @@ -3022,16 +3023,23 @@ static int __devinit be_probe(struct pci_dev *pdev, } be_sriov_enable(adapter); + if (adapter->sriov_enabled) { + adapter->vf_cfg = kcalloc(num_vfs, + sizeof(struct be_vf_cfg), GFP_KERNEL); + + if (!adapter->vf_cfg) + goto free_netdev; + } status = be_ctrl_init(adapter); if (status) - goto free_netdev; + goto free_vf_cfg; if (lancer_chip(adapter)) { status = lancer_test_and_set_rdy_state(adapter); if (status) { dev_err(&pdev->dev, "Adapter in non recoverable error\n"); - goto free_netdev; + goto ctrl_clean; } } @@ -3093,6 +3101,8 @@ static int __devinit be_probe(struct pci_dev *pdev, be_stats_cleanup(adapter); ctrl_clean: be_ctrl_cleanup(adapter); +free_vf_cfg: + kfree(adapter->vf_cfg); free_netdev: be_sriov_disable(adapter); free_netdev(netdev); -- GitLab From 57841869197831542f25c739beaeab4465977878 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 6 Apr 2011 18:08:43 +0000 Subject: [PATCH 0633/5560] be2net: call FLR after setup wol in be_shutdown Calling setup_wol after a reset is inconsequential. The WOL setting should be programmed before FLR. And yes, FLR does not erase wol information. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 6e7df0dd418b..b8831403400c 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -3191,11 +3191,11 @@ static void be_shutdown(struct pci_dev *pdev) netif_device_detach(adapter->netdev); - be_cmd_reset_function(adapter); - if (adapter->wol) be_setup_wol(adapter, true); + be_cmd_reset_function(adapter); + pci_disable_device(pdev); } -- GitLab From b7af1dafdfaf8419065399d07fb7cbae14b286ef Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 7 Apr 2011 19:18:44 +0900 Subject: [PATCH 0634/5560] ASoC: Add data based control initialisation for CODECs and cards Allow CODEC and card drivers to point to an array of controls from their driver structure rather than explicitly calling snd_soc_add_controls(). Signed-off-by: Mark Brown --- include/sound/soc.h | 7 ++++++- sound/soc/soc-core.c | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 2720a9f3780b..435cb83c7f48 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -577,7 +577,9 @@ struct snd_soc_codec_driver { pm_message_t state); int (*resume)(struct snd_soc_codec *); - /* Default DAPM setup, added after probe() is run */ + /* Default control and setup, added after probe() is run */ + const struct snd_kcontrol_new *controls; + int num_controls; const struct snd_soc_dapm_widget *dapm_widgets; int num_dapm_widgets; const struct snd_soc_dapm_route *dapm_routes; @@ -747,6 +749,9 @@ struct snd_soc_card { struct snd_soc_pcm_runtime *rtd_aux; int num_aux_rtd; + const struct snd_kcontrol_new *controls; + int num_controls; + /* * Card-specific routes and widgets. */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f31afe9d4edd..f75f13926049 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1493,6 +1493,9 @@ static int soc_probe_codec(struct snd_soc_card *card, } } + if (driver->controls) + snd_soc_add_controls(codec, driver->controls, + driver->num_controls); if (driver->dapm_widgets) snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, driver->num_dapm_widgets); @@ -1890,6 +1893,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) } } + /* We should have a non-codec control add function but we don't */ + if (card->controls) + snd_soc_add_controls(list_first_entry(&card->codec_dev_list, + struct snd_soc_codec, + card_list), + card->controls, + card->num_controls); + if (card->dapm_widgets) snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, card->num_dapm_widgets); -- GitLab From b39e285545a2bd7f331a53b32c8c40748fdd348e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 7 Apr 2011 02:05:11 -0400 Subject: [PATCH 0635/5560] ASoC: SSM2602: add SPI support The ssm2602 codec has a SPI interface as well as I2C, so add the simple bit of glue to make it usable. Signed-off-by: Mike Frysinger Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- sound/soc/codecs/ssm2602.c | 56 +++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 78da05b5e5eb..ee7374e8e97e 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -40,7 +40,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_SGTL5000 if I2C select SND_SOC_SN95031 if INTEL_SCU_IPC select SND_SOC_SPDIF - select SND_SOC_SSM2602 if I2C + select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_TLV320AIC23 if I2C select SND_SOC_TLV320AIC26 if SPI_MASTER diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 8a2b52fa4a7e..7e2194975360 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -556,6 +557,43 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { .reg_cache_default = ssm2602_reg, }; +#if defined(CONFIG_SPI_MASTER) +static int __devinit ssm2602_spi_probe(struct spi_device *spi) +{ + struct ssm2602_priv *ssm2602; + int ret; + + ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL); + if (ssm2602 == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, ssm2602); + ssm2602->control_type = SND_SOC_SPI; + + ret = snd_soc_register_codec(&spi->dev, + &soc_codec_dev_ssm2602, &ssm2602_dai, 1); + if (ret < 0) + kfree(ssm2602); + return ret; +} + +static int __devexit ssm2602_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + kfree(spi_get_drvdata(spi)); + return 0; +} + +static struct spi_driver ssm2602_spi_driver = { + .driver = { + .name = "ssm2602", + .owner = THIS_MODULE, + }, + .probe = ssm2602_spi_probe, + .remove = __devexit_p(ssm2602_spi_remove), +}; +#endif + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) /* * ssm2602 2 wire address is determined by GPIO5 @@ -612,19 +650,29 @@ static struct i2c_driver ssm2602_i2c_driver = { static int __init ssm2602_modinit(void) { int ret = 0; + +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&ssm2602_spi_driver); + if (ret) + return ret; +#endif + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&ssm2602_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n", - ret); - } + if (ret) + return ret; #endif + return ret; } module_init(ssm2602_modinit); static void __exit ssm2602_exit(void) { +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&ssm2602_spi_driver); +#endif + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&ssm2602_i2c_driver); #endif -- GitLab From 774fd7baf87829248365a07fdd42ca9882b5dd64 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Fri, 8 Apr 2011 08:41:38 +0800 Subject: [PATCH 0636/5560] sst: fix compile error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add several include files to fix the below compile error. drivers/staging/intel_sst/intelmid.c: In function ‘snd_intelmad_sst_register’: drivers/staging/intel_sst/intelmid.c:805:2: error: ‘sst_drv_ctx’ undeclared (first use in this function) drivers/staging/intel_sst/intelmid.c:805:2: note: each undeclared identifier is reported only once for each function it appears in Signed-off-by: Lu Guanqun Signed-off-by: Mark Brown --- drivers/staging/intel_sst/intelmid.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c index 1fb39d4f98e2..4e4e4a96d863 100644 --- a/drivers/staging/intel_sst/intelmid.c +++ b/drivers/staging/intel_sst/intelmid.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,8 @@ #include #include "intel_sst.h" #include "intel_sst_ioctl.h" +#include "intel_sst_fw_ipc.h" +#include "intel_sst_common.h" #include "intelmid_snd_control.h" #include "intelmid.h" -- GitLab From e92702b1046a418a562878b22f92433517760921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 31 Mar 2011 01:01:35 +0000 Subject: [PATCH 0637/5560] skge: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit just IP_CSUM. This needs testing and so is not changed here. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/skge.c | 53 +++++----------------------------------------- drivers/net/skge.h | 1 - 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index e579ff7579ad..310dcbce2519 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -537,46 +537,6 @@ static int skge_nway_reset(struct net_device *dev) return 0; } -static int skge_set_sg(struct net_device *dev, u32 data) -{ - struct skge_port *skge = netdev_priv(dev); - struct skge_hw *hw = skge->hw; - - if (hw->chip_id == CHIP_ID_GENESIS && data) - return -EOPNOTSUPP; - return ethtool_op_set_sg(dev, data); -} - -static int skge_set_tx_csum(struct net_device *dev, u32 data) -{ - struct skge_port *skge = netdev_priv(dev); - struct skge_hw *hw = skge->hw; - - if (hw->chip_id == CHIP_ID_GENESIS && data) - return -EOPNOTSUPP; - - return ethtool_op_set_tx_csum(dev, data); -} - -static u32 skge_get_rx_csum(struct net_device *dev) -{ - struct skge_port *skge = netdev_priv(dev); - - return skge->rx_csum; -} - -/* Only Yukon supports checksum offload. */ -static int skge_set_rx_csum(struct net_device *dev, u32 data) -{ - struct skge_port *skge = netdev_priv(dev); - - if (skge->hw->chip_id == CHIP_ID_GENESIS && data) - return -EOPNOTSUPP; - - skge->rx_csum = data; - return 0; -} - static void skge_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *ecmd) { @@ -924,10 +884,6 @@ static const struct ethtool_ops skge_ethtool_ops = { .set_pauseparam = skge_set_pauseparam, .get_coalesce = skge_get_coalesce, .set_coalesce = skge_set_coalesce, - .set_sg = skge_set_sg, - .set_tx_csum = skge_set_tx_csum, - .get_rx_csum = skge_get_rx_csum, - .set_rx_csum = skge_set_rx_csum, .get_strings = skge_get_strings, .set_phys_id = skge_set_phys_id, .get_sset_count = skge_get_sset_count, @@ -3084,7 +3040,8 @@ static struct sk_buff *skge_rx_get(struct net_device *dev, } skb_put(skb, len); - if (skge->rx_csum) { + + if (dev->features & NETIF_F_RXCSUM) { skb->csum = csum; skb->ip_summed = CHECKSUM_COMPLETE; } @@ -3846,10 +3803,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge); if (hw->chip_id != CHIP_ID_GENESIS) { - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; - skge->rx_csum = 1; + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_RXCSUM; + dev->features |= dev->hw_features; } - dev->features |= NETIF_F_GRO; /* read the mac address */ memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 507addcaffa3..f055c47de47e 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -2460,7 +2460,6 @@ struct skge_port { struct timer_list link_timer; enum pause_control flow_control; enum pause_status flow_status; - u8 rx_csum; u8 blink_on; u8 wol; u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ -- GitLab From 6332c8d3a5e352fae854cbcac764622e083461e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 7 Apr 2011 02:43:48 +0000 Subject: [PATCH 0638/5560] net: benet: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simple conversion. This also fixes a bug in TX checksum toggling --- driver was changing NETIF_F_HW_CSUM instead of NETIF_F_IP_CSUM+NETIF_F_IPV6_CSUM. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 - drivers/net/benet/be_ethtool.c | 27 --------------------------- drivers/net/benet/be_main.c | 19 ++++++++++--------- 3 files changed, 10 insertions(+), 37 deletions(-) diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index d2c42f5d5e9e..a0b4743d7224 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -307,7 +307,6 @@ struct be_adapter { u16 work_counter; /* Ethtool knobs and info */ - bool rx_csum; /* BE card must perform rx-checksumming */ char fw_ver[FW_VER_LEN]; u32 if_handle; /* Used to configure filtering */ u32 pmac_id; /* MAC addr handle used by BE card */ diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 1565c81ff96c..96f5502e0ef7 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -261,25 +261,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) return 0; } -static u32 be_get_rx_csum(struct net_device *netdev) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - return adapter->rx_csum; -} - -static int be_set_rx_csum(struct net_device *netdev, uint32_t data) -{ - struct be_adapter *adapter = netdev_priv(netdev); - - if (data) - adapter->rx_csum = true; - else - adapter->rx_csum = false; - - return 0; -} - static void be_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) @@ -760,14 +741,6 @@ const struct ethtool_ops be_ethtool_ops = { .get_ringparam = be_get_ringparam, .get_pauseparam = be_get_pauseparam, .set_pauseparam = be_set_pauseparam, - .get_rx_csum = be_get_rx_csum, - .set_rx_csum = be_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, .get_strings = be_get_stat_strings, .set_phys_id = be_set_phys_id, .get_sset_count = be_get_sset_count, diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index b8831403400c..58a652f81862 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -988,9 +988,10 @@ static void be_rx_compl_process(struct be_adapter *adapter, struct be_rx_obj *rxo, struct be_rx_compl_info *rxcp) { + struct net_device *netdev = adapter->netdev; struct sk_buff *skb; - skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); + skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); if (unlikely(!skb)) { if (net_ratelimit()) dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); @@ -1000,13 +1001,13 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb_fill_rx_data(adapter, rxo, skb, rxcp); - if (likely(adapter->rx_csum && csum_passed(rxcp))) + if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp))) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb_checksum_none_assert(skb); skb->truesize = skb->len + sizeof(struct sk_buff); - skb->protocol = eth_type_trans(skb, adapter->netdev); + skb->protocol = eth_type_trans(skb, netdev); if (adapter->netdev->features & NETIF_F_RXHASH) skb->rxhash = rxcp->rss_hash; @@ -2627,10 +2628,12 @@ static void be_netdev_init(struct net_device *netdev) struct be_rx_obj *rxo; 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_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_GRO | NETIF_F_TSO6; + netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; + + netdev->features |= netdev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_FILTER; if (be_multi_rxq(adapter)) netdev->features |= NETIF_F_RXHASH; @@ -2643,8 +2646,6 @@ static void be_netdev_init(struct net_device *netdev) netdev->flags |= IFF_MULTICAST; - adapter->rx_csum = true; - /* Default settings for Rx and Tx flow control */ adapter->rx_fc = true; adapter->tx_fc = true; -- GitLab From 5ec8f9b8e6d87faa9d3a4b079b83e3c0d9c39921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 7 Apr 2011 02:43:48 +0000 Subject: [PATCH 0639/5560] net: enic: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the driver uses GRO and not LRO, LRO settings are ignored anyway and are removed here to avoid confusion. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 1 - drivers/net/enic/enic_main.c | 74 ++++-------------------------------- drivers/net/enic/enic_res.c | 4 +- 3 files changed, 10 insertions(+), 69 deletions(-) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 178b94d7f89b..38b351c7b979 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -84,7 +84,6 @@ struct enic { unsigned int flags; unsigned int mc_count; unsigned int uc_count; - int csum_rx_enabled; u32 port_mtu; u32 rx_coalesce_usecs; u32 tx_coalesce_usecs; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 9a3a0277bf21..b2245511c51a 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -251,56 +251,6 @@ static void enic_get_ethtool_stats(struct net_device *netdev, *(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].offset]; } -static u32 enic_get_rx_csum(struct net_device *netdev) -{ - struct enic *enic = netdev_priv(netdev); - return enic->csum_rx_enabled; -} - -static int enic_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct enic *enic = netdev_priv(netdev); - - if (data && !ENIC_SETTING(enic, RXCSUM)) - return -EINVAL; - - enic->csum_rx_enabled = !!data; - - return 0; -} - -static int enic_set_tx_csum(struct net_device *netdev, u32 data) -{ - struct enic *enic = netdev_priv(netdev); - - if (data && !ENIC_SETTING(enic, TXCSUM)) - return -EINVAL; - - if (data) - netdev->features |= NETIF_F_HW_CSUM; - else - netdev->features &= ~NETIF_F_HW_CSUM; - - return 0; -} - -static int enic_set_tso(struct net_device *netdev, u32 data) -{ - struct enic *enic = netdev_priv(netdev); - - if (data && !ENIC_SETTING(enic, TSO)) - return -EINVAL; - - if (data) - netdev->features |= - NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN; - else - netdev->features &= - ~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN); - - return 0; -} - static u32 enic_get_msglevel(struct net_device *netdev) { struct enic *enic = netdev_priv(netdev); @@ -388,17 +338,8 @@ static const struct ethtool_ops enic_ethtool_ops = { .get_strings = enic_get_strings, .get_sset_count = enic_get_sset_count, .get_ethtool_stats = enic_get_ethtool_stats, - .get_rx_csum = enic_get_rx_csum, - .set_rx_csum = enic_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = enic_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = enic_set_tso, .get_coalesce = enic_get_coalesce, .set_coalesce = enic_set_coalesce, - .get_flags = ethtool_op_get_flags, }; static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) @@ -1309,7 +1250,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, skb_put(skb, bytes_written); skb->protocol = eth_type_trans(skb, netdev); - if (enic->csum_rx_enabled && !csum_not_calc) { + if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) { skb->csum = htons(checksum); skb->ip_summed = CHECKSUM_COMPLETE; } @@ -2438,17 +2379,18 @@ static int __devinit enic_probe(struct pci_dev *pdev, dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag); } if (ENIC_SETTING(enic, TXCSUM)) - netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; + netdev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM; if (ENIC_SETTING(enic, TSO)) - netdev->features |= NETIF_F_TSO | + netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN; - if (ENIC_SETTING(enic, LRO)) - netdev->features |= NETIF_F_GRO; + if (ENIC_SETTING(enic, RXCSUM)) + netdev->hw_features |= NETIF_F_RXCSUM; + + netdev->features |= netdev->hw_features; + if (using_dac) netdev->features |= NETIF_F_HIGHDMA; - enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM); - err = register_netdev(netdev); if (err) { dev_err(dev, "Cannot register net device, aborting\n"); diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index f111a37419ce..6e5c6356e7df 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -98,9 +98,9 @@ int enic_get_vnic_config(struct enic *enic) "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n", enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu); dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d " - "tso/lro %d/%d intr timer %d usec rss %d\n", + "tso %d intr timer %d usec rss %d\n", ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM), - ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO), + ENIC_SETTING(enic, TSO), c->intr_timer_usec, ENIC_SETTING(enic, RSS)); return 0; -- GitLab From dc668910f4eaa233c241d43d96ed6b0b9258cc43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 7 Apr 2011 03:35:07 +0000 Subject: [PATCH 0640/5560] net: tg3: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup hint: Some features are calculated in tg3_get_invariants() and the rest in its caller --- tg3_init_one(). This is not changed here. Signed-off-by: Michał Mirosław Acked-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 135 +++++++++++----------------------------------- drivers/net/tg3.h | 2 - 2 files changed, 32 insertions(+), 105 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d37ae8747ad1..38962afdce61 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4816,7 +4816,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) skb = copy_skb; } - if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) && + if ((tp->dev->features & NETIF_F_RXCSUM) && (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) >> RXD_TCPCSUM_SHIFT) == 0xffff)) @@ -6127,6 +6127,16 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, return NETDEV_TX_OK; } +static u32 tg3_fix_features(struct net_device *dev, u32 features) +{ + struct tg3 *tp = netdev_priv(dev); + + if (dev->mtu > ETH_DATA_LEN && (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) + features &= ~NETIF_F_ALL_TSO; + + return features; +} + static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, int new_mtu) { @@ -6134,14 +6144,16 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, if (new_mtu > ETH_DATA_LEN) { if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { + netdev_update_features(dev); tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; - ethtool_op_set_tso(dev, 0); } else { tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE; } } else { - if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + netdev_update_features(dev); + } tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE; } } @@ -10021,33 +10033,6 @@ static void tg3_set_msglevel(struct net_device *dev, u32 value) tp->msg_enable = value; } -static int tg3_set_tso(struct net_device *dev, u32 value) -{ - struct tg3 *tp = netdev_priv(dev); - - if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { - if (value) - return -EINVAL; - return 0; - } - if ((dev->features & NETIF_F_IPV6_CSUM) && - ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) || - (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3))) { - if (value) { - dev->features |= NETIF_F_TSO6; - if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && - GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) - dev->features |= NETIF_F_TSO_ECN; - } else - dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN); - } - return ethtool_op_set_tso(dev, value); -} - static int tg3_nway_reset(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); @@ -10270,50 +10255,6 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam return err; } -static u32 tg3_get_rx_csum(struct net_device *dev) -{ - struct tg3 *tp = netdev_priv(dev); - return (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0; -} - -static int tg3_set_rx_csum(struct net_device *dev, u32 data) -{ - struct tg3 *tp = netdev_priv(dev); - - if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { - if (data != 0) - return -EINVAL; - return 0; - } - - spin_lock_bh(&tp->lock); - if (data) - tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; - else - tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; - spin_unlock_bh(&tp->lock); - - return 0; -} - -static int tg3_set_tx_csum(struct net_device *dev, u32 data) -{ - struct tg3 *tp = netdev_priv(dev); - - if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) { - if (data != 0) - return -EINVAL; - return 0; - } - - if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) - ethtool_op_set_tx_ipv6_csum(dev, data); - else - ethtool_op_set_tx_csum(dev, data); - - return 0; -} - static int tg3_get_sset_count(struct net_device *dev, int sset) { switch (sset) { @@ -11390,11 +11331,6 @@ static const struct ethtool_ops tg3_ethtool_ops = { .set_ringparam = tg3_set_ringparam, .get_pauseparam = tg3_get_pauseparam, .set_pauseparam = tg3_set_pauseparam, - .get_rx_csum = tg3_get_rx_csum, - .set_rx_csum = tg3_set_rx_csum, - .set_tx_csum = tg3_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = tg3_set_tso, .self_test = tg3_self_test, .get_strings = tg3_get_strings, .set_phys_id = tg3_set_phys_id, @@ -13262,11 +13198,6 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); -static inline void vlan_features_add(struct net_device *dev, unsigned long flags) -{ - dev->vlan_features |= flags; -} - static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) { if (tp->tg3_flags3 & TG3_FLG3_LRG_PROD_RING_CAP) @@ -13513,16 +13444,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* 5700 B0 chips do not support checksumming correctly due * to hardware bugs. */ - if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) - tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; - else { - unsigned long features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO; + if (tp->pci_chip_rev_id != CHIPREV_ID_5700_B0) { + u32 features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM; - tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) features |= NETIF_F_IPV6_CSUM; tp->dev->features |= features; - vlan_features_add(tp->dev, features); + tp->dev->hw_features |= features; + tp->dev->vlan_features |= features; } /* Determine TSO capabilities */ @@ -14794,6 +14723,7 @@ static const struct net_device_ops tg3_netdev_ops = { .ndo_do_ioctl = tg3_ioctl, .ndo_tx_timeout = tg3_tx_timeout, .ndo_change_mtu = tg3_change_mtu, + .ndo_fix_features = tg3_fix_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = tg3_poll_controller, #endif @@ -14824,6 +14754,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, u32 sndmbx, rcvmbx, intmbx; char str[40]; u64 dma_mask, persist_dma_mask; + u32 hw_features = 0; printk_once(KERN_INFO "%s\n", version); @@ -14984,27 +14915,25 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, * is off by default, but can be enabled using ethtool. */ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) && - (dev->features & NETIF_F_IP_CSUM)) { - dev->features |= NETIF_F_TSO; - vlan_features_add(dev, NETIF_F_TSO); - } + (dev->features & NETIF_F_IP_CSUM)) + hw_features |= NETIF_F_TSO; if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) || (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) { - if (dev->features & NETIF_F_IPV6_CSUM) { - dev->features |= NETIF_F_TSO6; - vlan_features_add(dev, NETIF_F_TSO6); - } + if (dev->features & NETIF_F_IPV6_CSUM) + hw_features |= NETIF_F_TSO6; if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) { - dev->features |= NETIF_F_TSO_ECN; - vlan_features_add(dev, NETIF_F_TSO_ECN); - } + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) + hw_features |= NETIF_F_TSO_ECN; } + dev->hw_features |= hw_features; + dev->features |= hw_features; + dev->vlan_features |= hw_features; + if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 && !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) && !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) { @@ -15133,7 +15062,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n", - (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, + (dev->features & NETIF_F_RXCSUM) != 0, (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) != 0, (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index e7880d593aa8..73dda2787103 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2883,7 +2883,6 @@ struct tg3 { u32 tg3_flags; #define TG3_FLAG_TAGGED_STATUS 0x00000001 #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 -#define TG3_FLAG_RX_CHECKSUMS 0x00000004 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_ENABLE_ASF 0x00000020 #define TG3_FLAG_ASPM_WORKAROUND 0x00000040 @@ -2909,7 +2908,6 @@ struct tg3 { #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 #define TG3_FLAG_CPMU_PRESENT 0x04000000 #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 -#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 #define TG3_FLAG_JUMBO_CAPABLE 0x20000000 #define TG3_FLAG_CHIP_RESETTING 0x40000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000 -- GitLab From 782d640afd15af7a1faf01cfe566ca4ac511319d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Thu, 7 Apr 2011 07:32:18 +0000 Subject: [PATCH 0641/5560] net: atl*: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Things left as they were: - atl1: is RX checksum really enabled? - atl2: copy-paste from atl1, with-errors-on-modify I presume - atl1c: there's a bug: MTU can't be changed if device is not up Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_ethtool.c | 8 -------- drivers/net/atl1c/atl1c_main.c | 23 ++++++++++++++--------- drivers/net/atl1e/atl1e_ethtool.c | 3 --- drivers/net/atl1e/atl1e_main.c | 12 ++++-------- drivers/net/atlx/atl1.c | 15 +++++---------- drivers/net/atlx/atl2.c | 14 +------------- 6 files changed, 24 insertions(+), 51 deletions(-) diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c index 7c521508313c..3af5a336a5af 100644 --- a/drivers/net/atl1c/atl1c_ethtool.c +++ b/drivers/net/atl1c/atl1c_ethtool.c @@ -113,11 +113,6 @@ static int atl1c_set_settings(struct net_device *netdev, return 0; } -static u32 atl1c_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_HW_CSUM) != 0; -} - static u32 atl1c_get_msglevel(struct net_device *netdev) { struct atl1c_adapter *adapter = netdev_priv(netdev); @@ -307,9 +302,6 @@ static const struct ethtool_ops atl1c_ethtool_ops = { .get_link = ethtool_op_get_link, .get_eeprom_len = atl1c_get_eeprom_len, .get_eeprom = atl1c_get_eeprom, - .get_tx_csum = atl1c_get_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, }; void atl1c_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 7d9d5067a65c..894d485bf5bc 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -484,6 +484,15 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; } + +static u32 atl1c_fix_features(struct net_device *netdev, u32 features) +{ + if (netdev->mtu > MAX_TSO_FRAME_SIZE) + features &= ~(NETIF_F_TSO | NETIF_F_TSO6); + + return features; +} + /* * atl1c_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure @@ -510,14 +519,8 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu) netdev->mtu = new_mtu; adapter->hw.max_frame_size = new_mtu; atl1c_set_rxbufsize(adapter, netdev); - if (new_mtu > MAX_TSO_FRAME_SIZE) { - adapter->netdev->features &= ~NETIF_F_TSO; - adapter->netdev->features &= ~NETIF_F_TSO6; - } else { - adapter->netdev->features |= NETIF_F_TSO; - adapter->netdev->features |= NETIF_F_TSO6; - } atl1c_down(adapter); + netdev_update_features(netdev); atl1c_up(adapter); clear_bit(__AT_RESETTING, &adapter->flags); if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { @@ -2585,6 +2588,7 @@ static const struct net_device_ops atl1c_netdev_ops = { .ndo_set_mac_address = atl1c_set_mac_addr, .ndo_set_multicast_list = atl1c_set_multi, .ndo_change_mtu = atl1c_change_mtu, + .ndo_fix_features = atl1c_fix_features, .ndo_do_ioctl = atl1c_ioctl, .ndo_tx_timeout = atl1c_tx_timeout, .ndo_get_stats = atl1c_get_stats, @@ -2605,12 +2609,13 @@ static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) atl1c_set_ethtool_ops(netdev); /* TODO: add when ready */ - netdev->features = NETIF_F_SG | + netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_TSO6; + netdev->features = netdev->hw_features | + NETIF_F_HW_VLAN_RX; return 0; } diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index 1209297433b8..47783749d9fa 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c @@ -382,9 +382,6 @@ static const struct ethtool_ops atl1e_ethtool_ops = { .get_eeprom_len = atl1e_get_eeprom_len, .get_eeprom = atl1e_get_eeprom, .set_eeprom = atl1e_set_eeprom, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = ethtool_op_set_tso, }; void atl1e_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 1ff001a8270c..c05b2e7c93d0 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1927,11 +1927,7 @@ void atl1e_down(struct atl1e_adapter *adapter) * reschedule our watchdog timer */ set_bit(__AT_DOWN, &adapter->flags); -#ifdef NETIF_F_LLTX netif_stop_queue(netdev); -#else - netif_tx_disable(netdev); -#endif /* reset MAC to disable all RX/TX */ atl1e_reset_hw(&adapter->hw); @@ -2223,10 +2219,10 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev) netdev->watchdog_timeo = AT_TX_WATCHDOG; atl1e_set_ethtool_ops(netdev); - netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - netdev->features |= NETIF_F_LLTX; - netdev->features |= NETIF_F_TSO; + netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO | + NETIF_F_HW_VLAN_TX; + netdev->features = netdev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_LLTX; return 0; } diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index e973d056dc8f..98334a1f0c5c 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2986,6 +2986,11 @@ static int __devinit atl1_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_SG; netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); + netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO; + + /* is this valid? see atl1_setup_mac_ctrl() */ + netdev->features |= NETIF_F_RXCSUM; + /* * patch for some L1 of old version, * the final version of L1 may not need these @@ -3595,12 +3600,6 @@ static int atl1_set_pauseparam(struct net_device *netdev, return 0; } -/* FIXME: is this right? -- CHS */ -static u32 atl1_get_rx_csum(struct net_device *netdev) -{ - return 1; -} - static void atl1_get_strings(struct net_device *netdev, u32 stringset, u8 *data) { @@ -3668,13 +3667,9 @@ static const struct ethtool_ops atl1_ethtool_ops = { .set_ringparam = atl1_set_ringparam, .get_pauseparam = atl1_get_pauseparam, .set_pauseparam = atl1_set_pauseparam, - .get_rx_csum = atl1_get_rx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, .get_link = ethtool_op_get_link, - .set_sg = ethtool_op_set_sg, .get_strings = atl1_get_strings, .nway_reset = atl1_nway_reset, .get_ethtool_stats = atl1_get_ethtool_stats, .get_sset_count = atl1_get_sset_count, - .set_tso = ethtool_op_set_tso, }; diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 937ef1afa5db..02761dd23fb8 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1411,9 +1411,8 @@ static int __devinit atl2_probe(struct pci_dev *pdev, err = -EIO; -#ifdef NETIF_F_HW_VLAN_TX + netdev->hw_features = NETIF_F_SG; netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); -#endif /* Init PHY as early as possible due to power saving issue */ atl2_phy_init(&adapter->hw); @@ -1840,11 +1839,6 @@ static int atl2_set_settings(struct net_device *netdev, return 0; } -static u32 atl2_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_HW_CSUM) != 0; -} - static u32 atl2_get_msglevel(struct net_device *netdev) { return 0; @@ -2112,12 +2106,6 @@ static const struct ethtool_ops atl2_ethtool_ops = { .get_eeprom_len = atl2_get_eeprom_len, .get_eeprom = atl2_get_eeprom, .set_eeprom = atl2_set_eeprom, - .get_tx_csum = atl2_get_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, -#ifdef NETIF_F_TSO - .get_tso = ethtool_op_get_tso, -#endif }; static void atl2_set_ethtool_ops(struct net_device *netdev) -- GitLab From d25b7c1ec7da4636587ad1a22b324bcd7b89b6bc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Apr 2011 16:39:39 +0900 Subject: [PATCH 0642/5560] ASoC: Remove special casing for registerless widgets Since we recently explicitly set the register for registerless widgets to no register there is no longer any need to special case power updates for them, we can allow them to be handled with the register compression code as other widgets are. As this is the only remaining user of dapm_generic_apply_power() and dapm_update_bits() also remove those functions. Noticed-by: Lu Guanqun Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 100 ------------------------------------------- 1 file changed, 100 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 05da8a8f0aef..567645c0308b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -322,45 +322,6 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, return -ENODEV; } -/* update dapm codec register bits */ -static int dapm_update_bits(struct snd_soc_dapm_widget *widget) -{ - int change, power; - unsigned int old, new; - struct snd_soc_codec *codec = widget->codec; - struct snd_soc_dapm_context *dapm = widget->dapm; - struct snd_soc_card *card = dapm->card; - - /* check for valid widgets */ - if (widget->reg < 0 || widget->id == snd_soc_dapm_input || - widget->id == snd_soc_dapm_output || - widget->id == snd_soc_dapm_hp || - widget->id == snd_soc_dapm_mic || - widget->id == snd_soc_dapm_line || - widget->id == snd_soc_dapm_spk) - return 0; - - power = widget->power; - if (widget->invert) - power = (power ? 0:1); - - old = snd_soc_read(codec, widget->reg); - new = (old & ~(0x1 << widget->shift)) | (power << widget->shift); - - change = old != new; - if (change) { - pop_dbg(dapm->dev, card->pop_time, - "pop test %s : %s in %d ms\n", - widget->name, widget->power ? "on" : "off", - card->pop_time); - pop_wait(card->pop_time); - snd_soc_write(codec, widget->reg, new); - } - dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg, - old, new, change); - return change; -} - /* create new dapm mixer control */ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) @@ -644,57 +605,6 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(dapm_reg_event); -/* Standard power change method, used to apply power changes to most - * widgets. - */ -static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) -{ - int ret; - - /* call any power change event handlers */ - if (w->event) - dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n", - w->power ? "on" : "off", - w->name, w->event_flags); - - /* power up pre event */ - if (w->power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } - - /* power down pre event */ - if (!w->power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - - dapm_update_bits(w); - - /* power up post event */ - if (w->power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } - - /* power down post event */ - if (!w->power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - - return 0; -} - /* Generic check to see if a widget should be powered. */ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) @@ -981,16 +891,6 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, NULL, SND_SOC_DAPM_POST_PMD); break; - case snd_soc_dapm_input: - case snd_soc_dapm_output: - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_line: - case snd_soc_dapm_spk: - /* No register support currently */ - ret = dapm_generic_apply_power(w); - break; - default: /* Queue it up for application */ cur_sort = sort[w->id]; -- GitLab From 466de9183570fe9fd21ef167951488fc9d513fcb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 19 Mar 2011 04:26:10 +0000 Subject: [PATCH 0643/5560] kconfig: Avoid buffer underrun in choice input commit 40aee729b350672c2550640622416a855e27938f ('kconfig: fix default value for choice input') fixed some cases where kconfig would select the wrong option from a choice with a single valid option and thus enter an infinite loop. However, this broke the test for user input of the form 'N?', because when kconfig selects the single valid option the input is zero-length and the test will read the byte before the input buffer. If this happens to contain '?' (as it will in a mips build on Debian unstable today) then kconfig again enters an infinite loop. Signed-off-by: Ben Hutchings Cc: stable@kernel.org [2.6.17+] Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 659326c3e895..006ad817cd5f 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -332,7 +332,7 @@ static int conf_choice(struct menu *menu) } if (!child) continue; - if (line[strlen(line) - 1] == '?') { + if (line[0] && line[strlen(line) - 1] == '?') { print_help(child); continue; } -- GitLab From b3b7f0550f84e06ae60df0a13c2992792fbd1af9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Apr 2011 20:39:23 +0800 Subject: [PATCH 0644/5560] crypto: caam - introduce missing kfree Error handling code following a kmalloc should free the allocated data. The semantic match that finds the problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,f1,l; position p1,p2; expression *ptr != NULL; @@ x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...x...+> } ( x->f1 = E | (x->f1 == NULL || ...) | f(...,x->f1,...) ) ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Acked-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index dce44b2d1833..20e12155af63 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1120,6 +1120,7 @@ static int __init caam_algapi_init(void) if (err < 0 && i == 0) { dev_err(ctrldev, "algapi error in job ring registration: %d\n", err); + kfree(jrdev); return err; } -- GitLab From a49e490c7a8a5c6c9474b1936ad8048f3e4440fc Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 8 Apr 2011 20:40:51 +0800 Subject: [PATCH 0645/5560] crypto: s5p-sss - add S5PV210 advanced crypto engine support This change adds support for AES encrypting and decrypting using advanced crypto engine found on Samsung S5PV210 and S5PC110 SoCs. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile | 1 + drivers/crypto/s5p-sss.c | 701 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 713 insertions(+) create mode 100644 drivers/crypto/s5p-sss.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index a27224aa883e..7957acbf76a2 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -271,4 +271,15 @@ config CRYPTO_DEV_PICOXCELL Saying m here will build a module named pipcoxcell_crypto. +config CRYPTO_DEV_S5P + tristate "Support for Samsung S5PV210 crypto accelerator" + depends on ARCH_S5PV210 + select CRYPTO_AES + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + help + This option allows you to have support for S5P crypto acceleration. + Select this to offload Samsung S5PV210 or S5PC110 from AES + algorithms execution. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 663c5efec13b..53ea50155319 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o +obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c new file mode 100644 index 000000000000..8115417a1c93 --- /dev/null +++ b/drivers/crypto/s5p-sss.c @@ -0,0 +1,701 @@ +/* + * Cryptographic API. + * + * Support for Samsung S5PV210 HW acceleration. + * + * Copyright (C) 2011 NetUP Inc. 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define _SBF(s, v) ((v) << (s)) +#define _BIT(b) _SBF(b, 1) + +/* Feed control registers */ +#define SSS_REG_FCINTSTAT 0x0000 +#define SSS_FCINTSTAT_BRDMAINT _BIT(3) +#define SSS_FCINTSTAT_BTDMAINT _BIT(2) +#define SSS_FCINTSTAT_HRDMAINT _BIT(1) +#define SSS_FCINTSTAT_PKDMAINT _BIT(0) + +#define SSS_REG_FCINTENSET 0x0004 +#define SSS_FCINTENSET_BRDMAINTENSET _BIT(3) +#define SSS_FCINTENSET_BTDMAINTENSET _BIT(2) +#define SSS_FCINTENSET_HRDMAINTENSET _BIT(1) +#define SSS_FCINTENSET_PKDMAINTENSET _BIT(0) + +#define SSS_REG_FCINTENCLR 0x0008 +#define SSS_FCINTENCLR_BRDMAINTENCLR _BIT(3) +#define SSS_FCINTENCLR_BTDMAINTENCLR _BIT(2) +#define SSS_FCINTENCLR_HRDMAINTENCLR _BIT(1) +#define SSS_FCINTENCLR_PKDMAINTENCLR _BIT(0) + +#define SSS_REG_FCINTPEND 0x000C +#define SSS_FCINTPEND_BRDMAINTP _BIT(3) +#define SSS_FCINTPEND_BTDMAINTP _BIT(2) +#define SSS_FCINTPEND_HRDMAINTP _BIT(1) +#define SSS_FCINTPEND_PKDMAINTP _BIT(0) + +#define SSS_REG_FCFIFOSTAT 0x0010 +#define SSS_FCFIFOSTAT_BRFIFOFUL _BIT(7) +#define SSS_FCFIFOSTAT_BRFIFOEMP _BIT(6) +#define SSS_FCFIFOSTAT_BTFIFOFUL _BIT(5) +#define SSS_FCFIFOSTAT_BTFIFOEMP _BIT(4) +#define SSS_FCFIFOSTAT_HRFIFOFUL _BIT(3) +#define SSS_FCFIFOSTAT_HRFIFOEMP _BIT(2) +#define SSS_FCFIFOSTAT_PKFIFOFUL _BIT(1) +#define SSS_FCFIFOSTAT_PKFIFOEMP _BIT(0) + +#define SSS_REG_FCFIFOCTRL 0x0014 +#define SSS_FCFIFOCTRL_DESSEL _BIT(2) +#define SSS_HASHIN_INDEPENDENT _SBF(0, 0x00) +#define SSS_HASHIN_CIPHER_INPUT _SBF(0, 0x01) +#define SSS_HASHIN_CIPHER_OUTPUT _SBF(0, 0x02) + +#define SSS_REG_FCBRDMAS 0x0020 +#define SSS_REG_FCBRDMAL 0x0024 +#define SSS_REG_FCBRDMAC 0x0028 +#define SSS_FCBRDMAC_BYTESWAP _BIT(1) +#define SSS_FCBRDMAC_FLUSH _BIT(0) + +#define SSS_REG_FCBTDMAS 0x0030 +#define SSS_REG_FCBTDMAL 0x0034 +#define SSS_REG_FCBTDMAC 0x0038 +#define SSS_FCBTDMAC_BYTESWAP _BIT(1) +#define SSS_FCBTDMAC_FLUSH _BIT(0) + +#define SSS_REG_FCHRDMAS 0x0040 +#define SSS_REG_FCHRDMAL 0x0044 +#define SSS_REG_FCHRDMAC 0x0048 +#define SSS_FCHRDMAC_BYTESWAP _BIT(1) +#define SSS_FCHRDMAC_FLUSH _BIT(0) + +#define SSS_REG_FCPKDMAS 0x0050 +#define SSS_REG_FCPKDMAL 0x0054 +#define SSS_REG_FCPKDMAC 0x0058 +#define SSS_FCPKDMAC_BYTESWAP _BIT(3) +#define SSS_FCPKDMAC_DESCEND _BIT(2) +#define SSS_FCPKDMAC_TRANSMIT _BIT(1) +#define SSS_FCPKDMAC_FLUSH _BIT(0) + +#define SSS_REG_FCPKDMAO 0x005C + +/* AES registers */ +#define SSS_REG_AES_CONTROL 0x4000 +#define SSS_AES_BYTESWAP_DI _BIT(11) +#define SSS_AES_BYTESWAP_DO _BIT(10) +#define SSS_AES_BYTESWAP_IV _BIT(9) +#define SSS_AES_BYTESWAP_CNT _BIT(8) +#define SSS_AES_BYTESWAP_KEY _BIT(7) +#define SSS_AES_KEY_CHANGE_MODE _BIT(6) +#define SSS_AES_KEY_SIZE_128 _SBF(4, 0x00) +#define SSS_AES_KEY_SIZE_192 _SBF(4, 0x01) +#define SSS_AES_KEY_SIZE_256 _SBF(4, 0x02) +#define SSS_AES_FIFO_MODE _BIT(3) +#define SSS_AES_CHAIN_MODE_ECB _SBF(1, 0x00) +#define SSS_AES_CHAIN_MODE_CBC _SBF(1, 0x01) +#define SSS_AES_CHAIN_MODE_CTR _SBF(1, 0x02) +#define SSS_AES_MODE_DECRYPT _BIT(0) + +#define SSS_REG_AES_STATUS 0x4004 +#define SSS_AES_BUSY _BIT(2) +#define SSS_AES_INPUT_READY _BIT(1) +#define SSS_AES_OUTPUT_READY _BIT(0) + +#define SSS_REG_AES_IN_DATA(s) (0x4010 + (s << 2)) +#define SSS_REG_AES_OUT_DATA(s) (0x4020 + (s << 2)) +#define SSS_REG_AES_IV_DATA(s) (0x4030 + (s << 2)) +#define SSS_REG_AES_CNT_DATA(s) (0x4040 + (s << 2)) +#define SSS_REG_AES_KEY_DATA(s) (0x4080 + (s << 2)) + +#define SSS_REG(dev, reg) ((dev)->ioaddr + (SSS_REG_##reg)) +#define SSS_READ(dev, reg) __raw_readl(SSS_REG(dev, reg)) +#define SSS_WRITE(dev, reg, val) __raw_writel((val), SSS_REG(dev, reg)) + +/* HW engine modes */ +#define FLAGS_AES_DECRYPT _BIT(0) +#define FLAGS_AES_MODE_MASK _SBF(1, 0x03) +#define FLAGS_AES_CBC _SBF(1, 0x01) +#define FLAGS_AES_CTR _SBF(1, 0x02) + +#define AES_KEY_LEN 16 +#define CRYPTO_QUEUE_LEN 1 + +struct s5p_aes_reqctx { + unsigned long mode; +}; + +struct s5p_aes_ctx { + struct s5p_aes_dev *dev; + + uint8_t aes_key[AES_MAX_KEY_SIZE]; + uint8_t nonce[CTR_RFC3686_NONCE_SIZE]; + int keylen; +}; + +struct s5p_aes_dev { + struct device *dev; + struct clk *clk; + void __iomem *ioaddr; + int irq_hash; + int irq_fc; + + struct ablkcipher_request *req; + struct s5p_aes_ctx *ctx; + struct scatterlist *sg_src; + struct scatterlist *sg_dst; + + struct tasklet_struct tasklet; + struct crypto_queue queue; + bool busy; + spinlock_t lock; +}; + +static struct s5p_aes_dev *s5p_dev; + +static void s5p_set_dma_indata(struct s5p_aes_dev *dev, struct scatterlist *sg) +{ + SSS_WRITE(dev, FCBRDMAS, sg_dma_address(sg)); + SSS_WRITE(dev, FCBRDMAL, sg_dma_len(sg)); +} + +static void s5p_set_dma_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg) +{ + SSS_WRITE(dev, FCBTDMAS, sg_dma_address(sg)); + SSS_WRITE(dev, FCBTDMAL, sg_dma_len(sg)); +} + +static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) +{ + /* holding a lock outside */ + dev->req->base.complete(&dev->req->base, err); + dev->busy = false; +} + +static void s5p_unset_outdata(struct s5p_aes_dev *dev) +{ + dma_unmap_sg(dev->dev, dev->sg_dst, 1, DMA_FROM_DEVICE); +} + +static void s5p_unset_indata(struct s5p_aes_dev *dev) +{ + dma_unmap_sg(dev->dev, dev->sg_src, 1, DMA_TO_DEVICE); +} + +static int s5p_set_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg) +{ + int err; + + if (!IS_ALIGNED(sg_dma_len(sg), AES_BLOCK_SIZE)) { + err = -EINVAL; + goto exit; + } + if (!sg_dma_len(sg)) { + err = -EINVAL; + goto exit; + } + + err = dma_map_sg(dev->dev, sg, 1, DMA_FROM_DEVICE); + if (!err) { + err = -ENOMEM; + goto exit; + } + + dev->sg_dst = sg; + err = 0; + + exit: + return err; +} + +static int s5p_set_indata(struct s5p_aes_dev *dev, struct scatterlist *sg) +{ + int err; + + if (!IS_ALIGNED(sg_dma_len(sg), AES_BLOCK_SIZE)) { + err = -EINVAL; + goto exit; + } + if (!sg_dma_len(sg)) { + err = -EINVAL; + goto exit; + } + + err = dma_map_sg(dev->dev, sg, 1, DMA_TO_DEVICE); + if (!err) { + err = -ENOMEM; + goto exit; + } + + dev->sg_src = sg; + err = 0; + + exit: + return err; +} + +static void s5p_aes_tx(struct s5p_aes_dev *dev) +{ + int err = 0; + + s5p_unset_outdata(dev); + + if (!sg_is_last(dev->sg_dst)) { + err = s5p_set_outdata(dev, sg_next(dev->sg_dst)); + if (err) { + s5p_aes_complete(dev, err); + return; + } + + s5p_set_dma_outdata(dev, dev->sg_dst); + } else + s5p_aes_complete(dev, err); +} + +static void s5p_aes_rx(struct s5p_aes_dev *dev) +{ + int err; + + s5p_unset_indata(dev); + + if (!sg_is_last(dev->sg_src)) { + err = s5p_set_indata(dev, sg_next(dev->sg_src)); + if (err) { + s5p_aes_complete(dev, err); + return; + } + + s5p_set_dma_indata(dev, dev->sg_src); + } +} + +static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + struct s5p_aes_dev *dev = platform_get_drvdata(pdev); + uint32_t status; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + + if (irq == dev->irq_fc) { + status = SSS_READ(dev, FCINTSTAT); + if (status & SSS_FCINTSTAT_BRDMAINT) + s5p_aes_rx(dev); + if (status & SSS_FCINTSTAT_BTDMAINT) + s5p_aes_tx(dev); + + SSS_WRITE(dev, FCINTPEND, status); + } + + spin_unlock_irqrestore(&dev->lock, flags); + + return IRQ_HANDLED; +} + +static void s5p_set_aes(struct s5p_aes_dev *dev, + uint8_t *key, uint8_t *iv, unsigned int keylen) +{ + void __iomem *keystart; + + memcpy(dev->ioaddr + SSS_REG_AES_IV_DATA(0), iv, 0x10); + + if (keylen == AES_KEYSIZE_256) + keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(0); + else if (keylen == AES_KEYSIZE_192) + keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(2); + else + keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(4); + + memcpy(keystart, key, keylen); +} + +static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode) +{ + struct ablkcipher_request *req = dev->req; + + uint32_t aes_control; + int err; + unsigned long flags; + + aes_control = SSS_AES_KEY_CHANGE_MODE; + if (mode & FLAGS_AES_DECRYPT) + aes_control |= SSS_AES_MODE_DECRYPT; + + if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) + aes_control |= SSS_AES_CHAIN_MODE_CBC; + else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) + aes_control |= SSS_AES_CHAIN_MODE_CTR; + + if (dev->ctx->keylen == AES_KEYSIZE_192) + aes_control |= SSS_AES_KEY_SIZE_192; + else if (dev->ctx->keylen == AES_KEYSIZE_256) + aes_control |= SSS_AES_KEY_SIZE_256; + + aes_control |= SSS_AES_FIFO_MODE; + + /* as a variant it is possible to use byte swapping on DMA side */ + aes_control |= SSS_AES_BYTESWAP_DI + | SSS_AES_BYTESWAP_DO + | SSS_AES_BYTESWAP_IV + | SSS_AES_BYTESWAP_KEY + | SSS_AES_BYTESWAP_CNT; + + spin_lock_irqsave(&dev->lock, flags); + + SSS_WRITE(dev, FCINTENCLR, + SSS_FCINTENCLR_BTDMAINTENCLR | SSS_FCINTENCLR_BRDMAINTENCLR); + SSS_WRITE(dev, FCFIFOCTRL, 0x00); + + err = s5p_set_indata(dev, req->src); + if (err) + goto indata_error; + + err = s5p_set_outdata(dev, req->dst); + if (err) + goto outdata_error; + + SSS_WRITE(dev, AES_CONTROL, aes_control); + s5p_set_aes(dev, dev->ctx->aes_key, req->info, dev->ctx->keylen); + + s5p_set_dma_indata(dev, req->src); + s5p_set_dma_outdata(dev, req->dst); + + SSS_WRITE(dev, FCINTENSET, + SSS_FCINTENSET_BTDMAINTENSET | SSS_FCINTENSET_BRDMAINTENSET); + + spin_unlock_irqrestore(&dev->lock, flags); + + return; + + outdata_error: + s5p_unset_indata(dev); + + indata_error: + s5p_aes_complete(dev, err); + spin_unlock_irqrestore(&dev->lock, flags); +} + +static void s5p_tasklet_cb(unsigned long data) +{ + struct s5p_aes_dev *dev = (struct s5p_aes_dev *)data; + struct crypto_async_request *async_req, *backlog; + struct s5p_aes_reqctx *reqctx; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + backlog = crypto_get_backlog(&dev->queue); + async_req = crypto_dequeue_request(&dev->queue); + spin_unlock_irqrestore(&dev->lock, flags); + + if (!async_req) + return; + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + dev->req = ablkcipher_request_cast(async_req); + dev->ctx = crypto_tfm_ctx(dev->req->base.tfm); + reqctx = ablkcipher_request_ctx(dev->req); + + s5p_aes_crypt_start(dev, reqctx->mode); +} + +static int s5p_aes_handle_req(struct s5p_aes_dev *dev, + struct ablkcipher_request *req) +{ + unsigned long flags; + int err; + + spin_lock_irqsave(&dev->lock, flags); + if (dev->busy) { + err = -EAGAIN; + spin_unlock_irqrestore(&dev->lock, flags); + goto exit; + } + dev->busy = true; + + err = ablkcipher_enqueue_request(&dev->queue, req); + spin_unlock_irqrestore(&dev->lock, flags); + + tasklet_schedule(&dev->tasklet); + + exit: + return err; +} + +static int s5p_aes_crypt(struct ablkcipher_request *req, unsigned long mode) +{ + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct s5p_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct s5p_aes_reqctx *reqctx = ablkcipher_request_ctx(req); + struct s5p_aes_dev *dev = ctx->dev; + + if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { + pr_err("request size is not exact amount of AES blocks\n"); + return -EINVAL; + } + + reqctx->mode = mode; + + return s5p_aes_handle_req(dev, req); +} + +static int s5p_aes_setkey(struct crypto_ablkcipher *cipher, + const uint8_t *key, unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + if (keylen != AES_KEYSIZE_128 && + keylen != AES_KEYSIZE_192 && + keylen != AES_KEYSIZE_256) + return -EINVAL; + + memcpy(ctx->aes_key, key, keylen); + ctx->keylen = keylen; + + return 0; +} + +static int s5p_aes_ecb_encrypt(struct ablkcipher_request *req) +{ + return s5p_aes_crypt(req, 0); +} + +static int s5p_aes_ecb_decrypt(struct ablkcipher_request *req) +{ + return s5p_aes_crypt(req, FLAGS_AES_DECRYPT); +} + +static int s5p_aes_cbc_encrypt(struct ablkcipher_request *req) +{ + return s5p_aes_crypt(req, FLAGS_AES_CBC); +} + +static int s5p_aes_cbc_decrypt(struct ablkcipher_request *req) +{ + return s5p_aes_crypt(req, FLAGS_AES_DECRYPT | FLAGS_AES_CBC); +} + +static int s5p_aes_cra_init(struct crypto_tfm *tfm) +{ + struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm); + + ctx->dev = s5p_dev; + tfm->crt_ablkcipher.reqsize = sizeof(struct s5p_aes_reqctx); + + return 0; +} + +static struct crypto_alg algs[] = { + { + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-s5p", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct s5p_aes_ctx), + .cra_alignmask = 0x0f, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = s5p_aes_cra_init, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = s5p_aes_setkey, + .encrypt = s5p_aes_ecb_encrypt, + .decrypt = s5p_aes_ecb_decrypt, + } + }, + { + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-s5p", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct s5p_aes_ctx), + .cra_alignmask = 0x0f, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = s5p_aes_cra_init, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + .setkey = s5p_aes_setkey, + .encrypt = s5p_aes_cbc_encrypt, + .decrypt = s5p_aes_cbc_decrypt, + } + }, +}; + +static int s5p_aes_probe(struct platform_device *pdev) +{ + int i, j, err = -ENODEV; + struct s5p_aes_dev *pdata; + struct device *dev = &pdev->dev; + struct resource *res; + + if (s5p_dev) + return -EEXIST; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + if (!devm_request_mem_region(dev, res->start, + resource_size(res), pdev->name)) + return -EBUSY; + + pdata->clk = clk_get(dev, "secss"); + if (IS_ERR(pdata->clk)) { + dev_err(dev, "failed to find secss clock source\n"); + return -ENOENT; + } + + clk_enable(pdata->clk); + + spin_lock_init(&pdata->lock); + pdata->ioaddr = devm_ioremap(dev, res->start, + resource_size(res)); + + pdata->irq_hash = platform_get_irq_byname(pdev, "hash"); + if (pdata->irq_hash < 0) { + err = pdata->irq_hash; + dev_warn(dev, "hash interrupt is not available.\n"); + goto err_irq; + } + err = devm_request_irq(dev, pdata->irq_hash, s5p_aes_interrupt, + IRQF_SHARED, pdev->name, pdev); + if (err < 0) { + dev_warn(dev, "hash interrupt is not available.\n"); + goto err_irq; + } + + pdata->irq_fc = platform_get_irq_byname(pdev, "feed control"); + if (pdata->irq_fc < 0) { + err = pdata->irq_fc; + dev_warn(dev, "feed control interrupt is not available.\n"); + goto err_irq; + } + err = devm_request_irq(dev, pdata->irq_fc, s5p_aes_interrupt, + IRQF_SHARED, pdev->name, pdev); + if (err < 0) { + dev_warn(dev, "feed control interrupt is not available.\n"); + goto err_irq; + } + + pdata->dev = dev; + platform_set_drvdata(pdev, pdata); + s5p_dev = pdata; + + tasklet_init(&pdata->tasklet, s5p_tasklet_cb, (unsigned long)pdata); + crypto_init_queue(&pdata->queue, CRYPTO_QUEUE_LEN); + + for (i = 0; i < ARRAY_SIZE(algs); i++) { + INIT_LIST_HEAD(&algs[i].cra_list); + err = crypto_register_alg(&algs[i]); + if (err) + goto err_algs; + } + + pr_info("s5p-sss driver registered\n"); + + return 0; + + err_algs: + dev_err(dev, "can't register '%s': %d\n", algs[i].cra_name, err); + + for (j = 0; j < i; j++) + crypto_unregister_alg(&algs[j]); + + tasklet_kill(&pdata->tasklet); + + err_irq: + clk_disable(pdata->clk); + clk_put(pdata->clk); + + s5p_dev = NULL; + platform_set_drvdata(pdev, NULL); + + return err; +} + +static int s5p_aes_remove(struct platform_device *pdev) +{ + struct s5p_aes_dev *pdata = platform_get_drvdata(pdev); + int i; + + if (!pdata) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(algs); i++) + crypto_unregister_alg(&algs[i]); + + tasklet_kill(&pdata->tasklet); + + clk_disable(pdata->clk); + clk_put(pdata->clk); + + s5p_dev = NULL; + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver s5p_aes_crypto = { + .probe = s5p_aes_probe, + .remove = s5p_aes_remove, + .driver = { + .owner = THIS_MODULE, + .name = "s5p-secss", + }, +}; + +static int __init s5p_aes_mod_init(void) +{ + return platform_driver_register(&s5p_aes_crypto); +} + +static void __exit s5p_aes_mod_exit(void) +{ + platform_driver_unregister(&s5p_aes_crypto); +} + +module_init(s5p_aes_mod_init); +module_exit(s5p_aes_mod_exit); + +MODULE_DESCRIPTION("S5PV210 AES hw acceleration support."); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Vladimir Zapolskiy "); -- GitLab From 1d5cc5559aaf5273cc1f9aac9b428e3a99d41de6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Mar 2011 16:12:43 -0700 Subject: [PATCH 0646/5560] iwlwifi: remove extranious macro from firmware define define of firmware filenames use extra macro to build the files name. Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-2000.c | 9 +++------ drivers/net/wireless/iwlwifi/iwl-5000.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-6000.c | 12 ++++-------- 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 1b2799291834..4323d27cc9f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -57,12 +57,10 @@ #define IWL100_UCODE_API_MIN 5 #define IWL1000_FW_PRE "iwlwifi-1000-" -#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" -#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) +#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" #define IWL100_FW_PRE "iwlwifi-100-" -#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" -#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) +#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" /* diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index f602af4b9408..564477d09153 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -60,16 +60,13 @@ #define IWL200_UCODE_API_MIN 5 #define IWL2030_FW_PRE "iwlwifi-2030-" -#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" -#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api) +#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" #define IWL2000_FW_PRE "iwlwifi-2000-" -#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" -#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api) +#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" #define IWL200_FW_PRE "iwlwifi-200-" -#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" -#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api) +#define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" static void iwl2000_set_ct_threshold(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 66f5fe8fe1ac..4dafc58800d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -59,12 +59,10 @@ #define IWL5150_UCODE_API_MIN 1 #define IWL5000_FW_PRE "iwlwifi-5000-" -#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" -#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api) +#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" #define IWL5150_FW_PRE "iwlwifi-5150-" -#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" -#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) +#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" /* NIC configuration for 5000 series */ static void iwl5000_nic_config(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 24d105b29aec..9fb2a42e5ea0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -60,20 +60,16 @@ #define IWL6000G2_UCODE_API_MIN 4 #define IWL6000_FW_PRE "iwlwifi-6000-" -#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" -#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api) +#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" #define IWL6050_FW_PRE "iwlwifi-6050-" -#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" -#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) +#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" #define IWL6005_FW_PRE "iwlwifi-6000g2a-" -#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" -#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api) +#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" #define IWL6030_FW_PRE "iwlwifi-6000g2b-" -#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" -#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api) +#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { -- GitLab From 3ecccbcd3c67374aeee447c08fcb9e39a99f7ee5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 29 Mar 2011 17:53:15 -0700 Subject: [PATCH 0647/5560] iwlagn: remove un-necessary function pointer After driver split, no need to use function pointer for those event and register dump function. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 -------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 -- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++------ drivers/net/wireless/iwlwifi/iwl-core.h | 8 ++------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 21 ++++++++------------- 8 files changed, 14 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 4323d27cc9f6..cb2f87101f9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -182,10 +182,6 @@ static struct iwl_lib_ops iwl1000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 564477d09153..e73ac80a721e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -262,10 +262,6 @@ static struct iwl_lib_ops iwl2000_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl2030_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 4dafc58800d9..4c8f72a77a72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -350,10 +350,6 @@ static struct iwl_lib_ops iwl5000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, @@ -406,9 +402,6 @@ static struct iwl_lib_ops iwl5150_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl5000_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9fb2a42e5ea0..80a335fc78cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -289,10 +289,6 @@ static struct iwl_lib_ops iwl6000_lib = { .rx_handler_setup = iwlagn_rx_handler_setup, .setup_deferred_work = iwlagn_setup_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, @@ -347,10 +343,6 @@ static struct iwl_lib_ops iwl6030_lib = { .setup_deferred_work = iwlagn_bt_setup_deferred_work, .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, .send_tx_power = iwlagn_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .set_channel_switch = iwl6000_hw_channel_switch, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 016b79e4421e..290a20814692 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -173,8 +173,6 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv); int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); -void iwl_dump_csr(struct iwl_priv *priv); -int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); /* rx */ void iwlagn_rx_queue_restock(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c46be36b9e2e..5e7281c22c0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -965,12 +965,10 @@ void iwl_irq_handle_error(struct iwl_priv *priv) IWL_ERR(priv, "Loaded firmware version: %s\n", priv->hw->wiphy->fw_version); - priv->cfg->ops->lib->dump_nic_error_log(priv); - if (priv->cfg->ops->lib->dump_csr) - priv->cfg->ops->lib->dump_csr(priv); - if (priv->cfg->ops->lib->dump_fh) - priv->cfg->ops->lib->dump_fh(priv, NULL, false); - priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); + iwl_dump_nic_error_log(priv); + iwl_dump_csr(priv); + iwl_dump_fh(priv, NULL, false); + iwl_dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) iwl_print_rx_config_cmd(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 82939f851eb9..43d4c92268e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -171,12 +171,6 @@ struct iwl_lib_ops { void (*cancel_deferred_work)(struct iwl_priv *priv); /* check validity of rtc data address */ int (*is_valid_rtc_data_addr)(u32 addr); - - int (*dump_nic_event_log)(struct iwl_priv *priv, - bool full_log, char **buf, bool display); - void (*dump_nic_error_log)(struct iwl_priv *priv); - void (*dump_csr)(struct iwl_priv *priv); - int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); int (*set_channel_switch)(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch); /* power management */ @@ -598,6 +592,8 @@ extern const struct dev_pm_ops iwl_pm_ops; void iwl_dump_nic_error_log(struct iwl_priv *priv); int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, char **buf, bool display); +void iwl_dump_csr(struct iwl_priv *priv); +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 92f6efd2c73f..93a86998a3b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -437,8 +437,7 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file, int pos = 0; ssize_t ret = -ENOMEM; - ret = pos = priv->cfg->ops->lib->dump_nic_event_log( - priv, true, &buf, true); + ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true); if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -462,8 +461,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, if (sscanf(buf, "%d", &event_log_flag) != 1) return -EFAULT; if (event_log_flag == 1) - priv->cfg->ops->lib->dump_nic_event_log(priv, true, - NULL, false); + iwl_dump_nic_event_log(priv, true, NULL, false); return count; } @@ -1268,8 +1266,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, if (sscanf(buf, "%d", &csr) != 1) return -EFAULT; - if (priv->cfg->ops->lib->dump_csr) - priv->cfg->ops->lib->dump_csr(priv); + iwl_dump_csr(priv); return count; } @@ -1359,13 +1356,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, int pos = 0; ssize_t ret = -EFAULT; - if (priv->cfg->ops->lib->dump_fh) { - ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); - if (buf) { - ret = simple_read_from_buffer(user_buf, - count, ppos, buf, pos); - kfree(buf); - } + ret = pos = iwl_dump_fh(priv, &buf, true); + if (buf) { + ret = simple_read_from_buffer(user_buf, + count, ppos, buf, pos); + kfree(buf); } return ret; -- GitLab From 68b993118f715cc631b62b6a50574e4701fe9ace Mon Sep 17 00:00:00 2001 From: Garen Tamrazian Date: Wed, 30 Mar 2011 02:29:32 -0700 Subject: [PATCH 0648/5560] iwlagn: fix radar frame rejection The microcode may sometimes reject TX frames when on a radar channel even after we associated as it clears information during association and needs to receive a new beacon before allowing that channel again. This manifests itself as a TX status value of TX_STATUS_FAIL_PASSIVE_NO_RX. So in this case, stop the corresponding queue and give the frame back to mac80211 for retransmission. We start the queue again when a beacon from the AP is received which will make the regulatory enforcement in the device allow transmitting again. Signed-off-by: Garen Tamrazian Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 29 ++++++++++++++------ drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 13 +++++++++ drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 3 ++ drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-helpers.h | 13 +++++++++ drivers/net/wireless/iwlwifi/iwl-rx.c | 21 ++++++++++++++ 7 files changed, 74 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9e47be6a7393..cccf7471c003 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -172,6 +172,7 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, + struct iwl_rxon_context *ctx, struct iwlagn_tx_resp *tx_resp, int txq_id, bool is_agg) { @@ -186,6 +187,13 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, if (!iwl_is_tx_success(status)) iwlagn_count_tx_err_status(priv, status); + if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && + iwl_is_associated_ctx(ctx) && ctx->vif && + ctx->vif->type == NL80211_IFTYPE_STATION) { + ctx->last_tx_rejected = true; + iwl_stop_queue(priv, &priv->txq[txq_id]); + } + IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " "0x%x retries %d\n", txq_id, @@ -242,15 +250,16 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, /* # frames attempted by Tx command */ if (agg->frame_count == 1) { + struct iwl_tx_info *txb; + /* Only one frame was attempted; no block-ack will arrive */ idx = start_idx; IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - iwlagn_set_tx_status(priv, - IEEE80211_SKB_CB( - priv->txq[txq_id].txb[idx].skb), - tx_resp, txq_id, true); + txb = &priv->txq[txq_id].txb[idx]; + iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(txb->skb), + txb->ctx, tx_resp, txq_id, true); agg->wait_for_ba = 0; } else { /* Two or more frames were attempted; expect block-ack */ @@ -391,7 +400,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_info *info; struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le16_to_cpu(tx_resp->status.status); + struct iwl_tx_info *txb; + u32 status = le16_to_cpu(tx_resp->status.status); int tid; int sta_id; int freed; @@ -406,7 +416,8 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, } txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + txb = &txq->txb[txq->q.read_ptr]; + info = IEEE80211_SKB_CB(txb->skb); memset(&info->status, 0, sizeof(info->status)); tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> @@ -450,12 +461,14 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, iwl_wake_queue(priv, txq); } } else { - iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); + iwlagn_set_tx_status(priv, info, txb->ctx, tx_resp, + txq_id, false); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if (priv->mac80211_registered && - (iwl_queue_space(&txq->q) > txq->q.low_mark)) + iwl_queue_space(&txq->q) > txq->q.low_mark && + status != TX_STATUS_FAIL_PASSIVE_NO_RX) iwl_wake_queue(priv, txq); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index c335ee6883ee..56f46ee3bacd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -29,6 +29,7 @@ #include "iwl-sta.h" #include "iwl-core.h" #include "iwl-agn-calib.h" +#include "iwl-helpers.h" static int iwlagn_disable_bss(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -600,6 +601,18 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, priv->timestamp = bss_conf->timestamp; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { + /* + * If we disassociate while there are pending + * frames, just wake up the queues and let the + * frames "escape" ... This shouldn't really + * be happening to start with, but we should + * not get stuck in this case either since it + * can happen if userspace gets confused. + */ + if (ctx->last_tx_rejected) { + ctx->last_tx_rejected = false; + iwl_wake_any_queue(priv, ctx); + } ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 01a6d2fc795c..5c30f6b19a7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -428,6 +428,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) int iwlagn_alive_notify(struct iwl_priv *priv) { const struct queue_to_fifo_ac *queue_to_fifo; + struct iwl_rxon_context *ctx; u32 a; unsigned long flags; int i, chan; @@ -501,6 +502,8 @@ int iwlagn_alive_notify(struct iwl_priv *priv) memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); for (i = 0; i < 4; i++) atomic_set(&priv->queue_stop_count[i], 0); + for_each_context(priv, ctx) + ctx->last_tx_rejected = false; /* reset to 0 to enable all the queue first */ priv->txq_ctx_active_msk = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 290a20814692..078a23e5d99d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -220,6 +220,7 @@ static inline u32 iwl_tx_status_to_mac80211(u32 status) case TX_STATUS_DIRECT_DONE: return IEEE80211_TX_STAT_ACK; case TX_STATUS_FAIL_DEST_PS: + case TX_STATUS_FAIL_PASSIVE_NO_RX: return IEEE80211_TX_STAT_TX_FILTERED; default: return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 72133368c1f5..14f7d8fb6886 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1170,6 +1170,8 @@ struct iwl_rxon_context { bool enabled, is_40mhz; u8 extension_chan_offset; } ht; + + bool last_tx_rejected; }; enum iwl_scan_type { diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 5da5761c74b1..9309ff2df4c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -131,6 +131,19 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, ieee80211_stop_queue(priv->hw, ac); } +static inline void iwl_wake_any_queue(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + u8 ac; + + for (ac = 0; ac < AC_NUM; ac++) { + IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n", + ac, (atomic_read(&priv->queue_stop_count[ac]) > 0) + ? "stopped" : "awake"); + iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]); + } +} + #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c421f566982f..4472761fc591 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -873,6 +873,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, { struct sk_buff *skb; __le16 fc = hdr->frame_control; + struct iwl_rxon_context *ctx; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -895,6 +896,26 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); iwl_update_stats(priv, false, fc, len); + + /* + * Wake any queues that were stopped due to a passive channel tx + * failure. This can happen because the regulatory enforcement in + * the device waits for a beacon before allowing transmission, + * sometimes even after already having transmitted frames for the + * association because the new RXON may reset the information. + */ + if (unlikely(ieee80211_is_beacon(fc))) { + for_each_context(priv, ctx) { + if (!ctx->last_tx_rejected) + continue; + if (compare_ether_addr(hdr->addr3, + ctx->active.bssid_addr)) + continue; + ctx->last_tx_rejected = false; + iwl_wake_any_queue(priv, ctx); + } + } + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); ieee80211_rx(priv->hw, skb); -- GitLab From a2b76b3b31568da9d281a393845f17689594ccdf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 29 Mar 2011 06:29:37 -0700 Subject: [PATCH 0649/5560] iwlwifi: fix bugs in change_interface If change_interface gets invoked during a firmware restart, it may crash; prevent that from happening by checking if ctx->vif is assigned. Additionally, in my initial commit I forgot to set the vif->p2p variable correctly, so fix that too. Cc: stable@kernel.org [2.6.38+] Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5e7281c22c0b..b5a06549b2a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1775,6 +1775,15 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&priv->mutex); + if (!ctx->vif || !iwl_is_ready_rf(priv)) { + /* + * Huh? But wait ... this can maybe happen when + * we're in the middle of a firmware restart! + */ + err = -EBUSY; + goto out; + } + interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; if (!(interface_modes & BIT(newtype))) { @@ -1802,6 +1811,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* success */ iwl_teardown_interface(priv, vif, true); vif->type = newtype; + vif->p2p = newp2p; err = iwl_setup_interface(priv, ctx); WARN_ON(err); /* -- GitLab From dcf6640f0f58affa93f158d8573b6868136e3d62 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 13:20:44 -0700 Subject: [PATCH 0650/5560] iwlagn: PAPD read for 2000 series devices For 2000 series NICs, disable OTP refresh in order to read correct PAPD table from high OTP block Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e73ac80a721e..86d7ffd6e38b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -98,6 +98,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv) iwl_set_bit(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); + if (priv->cfg->disable_otp_refresh) + iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010); } static struct iwl_sensitivity_ranges iwl2000_sensitivity = { @@ -409,7 +411,8 @@ static struct iwl_bt_params iwl2030_bt_params = { .need_dc_calib = true, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE, \ - .iq_invert = true \ + .iq_invert = true, \ + .disable_otp_refresh = true \ struct iwl_cfg iwl2000_2bgn_cfg = { .name = "2000 Series 2x2 BGN", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 43d4c92268e7..10a6f856356a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -331,6 +331,7 @@ struct iwl_ht_params { * @rx_with_siso_diversity: 1x1 device with rx antenna diversity * @internal_wimax_coex: internal wifi/wimax combo device * @iq_invert: I/Q inversion + * @disable_otp_refresh: disable OTP refresh current limit * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -381,6 +382,7 @@ struct iwl_cfg { const bool rx_with_siso_diversity; const bool internal_wimax_coex; const bool iq_invert; + const bool disable_otp_refresh; }; /*************************** -- GitLab From ece3cd2e8fb119a4394dcdc6ef921e85cdd4cc69 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:47 -0700 Subject: [PATCH 0651/5560] iwlagn: no 3945 define needed Remove 3945 define Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 69a29932babc..bdae82e7fa90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -83,7 +83,6 @@ enum { enum { IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, - IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, -- GitLab From ab4bf5ef5afce9d31cf5cf05ac80b3b01cbb24a3 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:35:09 -0700 Subject: [PATCH 0652/5560] iwlagn: remove unused 3945 define 3945 no longer apply Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-fh.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index da06d136a357..0f1052f80a53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -424,7 +424,6 @@ #define RX_LOW_WATERMARK 8 /* Size of one Rx buffer in host DRAM */ -#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */ #define IWL_RX_BUF_SIZE_4K (4 * 1024) #define IWL_RX_BUF_SIZE_8K (8 * 1024) @@ -443,7 +442,7 @@ struct iwl_rb_status { __le16 closed_fr_num; __le16 finished_rb_num; __le16 finished_fr_nam; - __le32 __unused; /* 3945 only */ + __le32 __unused; } __packed; -- GitLab From ee3cd7e04ca08ff0ec1ebb96be7e64aef928f511 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:35:10 -0700 Subject: [PATCH 0653/5560] iwlagn: cleanup to remove the reference for 3945 More clean up after driver split Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b5a06549b2a5..4c7649960983 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1049,7 +1049,6 @@ int iwl_apm_init(struct iwl_priv *priv) /* * Enable HAP INTA (interrupt from management bus) to * wake device's PCI Express link L1a -> L0s - * NOTE: This is no-op for 3945 (non-existant bit) */ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); -- GitLab From 6bb64697ed58909985487e885c269dafd09583f1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:50 -0700 Subject: [PATCH 0654/5560] iwlagn: remove more reference to legacy devices Remove the reference to both 3945 and 4965 in LED code Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-led.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index c2862d4e00e3..0d90004e8b1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -63,8 +63,8 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { /* * Adjust led blink rate to compensate on a MAC Clock difference on every HW - * Led blink rate analysis showed an average deviation of 0% on 3945, - * 5% on 4965 HW and 20% on 5000 series and up. + * Led blink rate analysis showed an average deviation of 20% on 5000 series + * and up. * Need to compensate on the led on/off time per HW according to the deviation * to achieve the desired led frequency * The calculation is: (100-averageDeviation)/100 * blinkTime -- GitLab From 15ade3ca647d95611814333cfe0885fd0184481e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:51 -0700 Subject: [PATCH 0655/5560] iwlagn: remove un-needed configuration After driver split, set_l0s config is no longer needed, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.c | 26 ++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 6 files changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index cb2f87101f9d..5a7281047a13 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -235,7 +235,6 @@ static struct iwl_base_params iwl1000_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .eeprom_size = OTP_LOW_IMAGE_SIZE, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, .led_compensation = 51, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 86d7ffd6e38b..9daf888b733c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -343,7 +343,6 @@ static struct iwl_base_params iwl2000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 51, @@ -366,7 +365,6 @@ static struct iwl_base_params iwl2030_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 57, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 4c8f72a77a72..8106423a2c84 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -464,7 +464,6 @@ static struct iwl_base_params iwl5000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 80a335fc78cb..7f0715eb0593 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -432,7 +432,6 @@ static struct iwl_base_params iwl6000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 51, @@ -454,7 +453,6 @@ static struct iwl_base_params iwl6050_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, .led_compensation = 51, @@ -475,7 +473,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = 0, - .set_l0s = true, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 57, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4c7649960983..0e98a8703e55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1061,20 +1061,18 @@ int iwl_apm_init(struct iwl_priv *priv) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - if (priv->cfg->base_params->set_l0s) { - lctl = iwl_pcie_link_ctl(priv); - if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == - PCI_CFG_LINK_CTRL_VAL_L1_EN) { - /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(priv, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); - } + lctl = iwl_pcie_link_ctl(priv); + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); } /* Configure analog phase-lock-loop before activating to D0A */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 10a6f856356a..7d303acc837c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -265,7 +265,6 @@ struct iwl_base_params { int num_of_ampdu_queues;/* def: HW dependent */ /* for iwl_apm_init() */ u32 pll_cfg_val; - bool set_l0s; const u16 max_ll_items; const bool shadow_ram_support; -- GitLab From 8ff84a2c99bc7f5f22d9d2b5365d821ce4f7a8f9 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:52 -0700 Subject: [PATCH 0656/5560] iwlagn: more cleanup to remove unused reference More cleanup code, no functional changes Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-fh.h | 35 ++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-prph.h | 16 +++-------- drivers/net/wireless/iwlwifi/iwl-tx.c | 1 - 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 0f1052f80a53..b90924e890a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -77,14 +77,14 @@ /** * Keep-Warm (KW) buffer base address. * - * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the + * Driver must allocate a 4KByte buffer that is for keeping the * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency - * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host + * DRAM access when doing Txing or Rxing. The dummy accesses prevent host * from going into a power-savings mode that would cause higher DRAM latency, * and possible data over/under-runs, before all Tx/Rx is complete. * * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) - * of the buffer, which must be 4K aligned. Once this is set up, the 4965 + * of the buffer, which must be 4K aligned. Once this is set up, the device * automatically invokes keep-warm accesses when normal accesses might not * be sufficient to maintain fast DRAM response. * @@ -97,7 +97,7 @@ /** * TFD Circular Buffers Base (CBBC) addresses * - * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident + * Device has 16 base pointer registers, one for each of 16 host-DRAM-resident * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte @@ -116,16 +116,16 @@ /** * Rx SRAM Control and Status Registers (RSCSR) * - * These registers provide handshake between driver and 4965 for the Rx queue + * These registers provide handshake between driver and device for the Rx queue * (this queue handles *all* command responses, notifications, Rx data, etc. - * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx + * sent from uCode to host driver). Unlike Tx, there is only one Rx * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 * mapping between RBDs and RBs. * * Driver must allocate host DRAM memory for the following, and set the - * physical address of each into 4965 registers: + * physical address of each into device registers: * * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 * entries (although any power of 2, up to 4096, is selectable by driver). @@ -140,20 +140,20 @@ * Driver sets physical address [35:8] of base of RBD circular buffer * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. * - * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers + * 2) Rx status buffer, 8 bytes, in which uCode indicates which Rx Buffers * (RBs) have been filled, via a "write pointer", actually the index of * the RB's corresponding RBD within the circular buffer. Driver sets * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. * * Bit fields in lower dword of Rx status buffer (upper dword not used - * by driver; see struct iwl4965_shared, val0): + * by driver: * 31-12: Not used by driver * 11- 0: Index of last filled Rx buffer descriptor - * (4965 writes, driver reads this value) + * (device writes, driver reads this value) * - * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must + * As the driver prepares Receive Buffers (RBs) for device to fill, driver must * enter pointers to these RBs into contiguous RBD circular buffer entries, - * and update the 4965's "write" index register, + * and update the device's "write" index register, * FH_RSCSR_CHNL0_RBDCB_WPTR_REG. * * This "write" index corresponds to the *next* RBD that the driver will make @@ -162,12 +162,12 @@ * RBs), should be 8 after preparing the first 8 RBs (for example), and must * wrap back to 0 at the end of the circular buffer (but don't wrap before * "read" index has advanced past 1! See below). - * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. + * NOTE: DEVICE EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. * - * As the 4965 fills RBs (referenced from contiguous RBDs within the circular + * As the device fills RBs (referenced from contiguous RBDs within the circular * buffer), it updates the Rx status buffer in host DRAM, 2) described above, * to tell the driver the index of the latest filled RBD. The driver must - * read this "read" index from DRAM after receiving an Rx interrupt from 4965. + * read this "read" index from DRAM after receiving an Rx interrupt from device * * The driver must also internally keep track of a third index, which is the * next RBD to process. When receiving an Rx interrupt, driver should process @@ -176,7 +176,7 @@ * driver may process the RB pointed to by RBD 0. Depending on volume of * traffic, there may be many RBs to process. * - * If read index == write index, 4965 thinks there is no room to put new data. + * If read index == write index, device thinks there is no room to put new data. * Due to this, the maximum number of filled RBs is 255, instead of 256. To * be safe, make sure that there is a gap of at least 2 RBDs between "write" * and "read" indexes; that is, make sure that there are no more than 254 @@ -303,7 +303,7 @@ /** * Transmit DMA Channel Control/Status Registers (TCSR) * - * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels + * Device has one configuration register for each of 8 Tx DMA/FIFO channels * supported in hardware (don't confuse these with the 16 Tx queues in DRAM, * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes. * @@ -326,7 +326,6 @@ #define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) /* Find Control/Status reg for given Tx DMA/FIFO channel */ -#define FH49_TCSR_CHNL_NUM (7) #define FH50_TCSR_CHNL_NUM (8) /* TCSR: tx_config register values */ diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index c960195df989..f00d188b2cfc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -107,17 +107,7 @@ * device. A queue maps to only one (selectable by driver) Tx DMA channel, * but one DMA channel may take input from several queues. * - * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows - * (cf. default_queue_to_tx_fifo in iwl-4965.c): - * - * 0 -- EDCA BK (background) frames, lowest priority - * 1 -- EDCA BE (best effort) frames, normal priority - * 2 -- EDCA VI (video) frames, higher priority - * 3 -- EDCA VO (voice) and management frames, highest priority - * 4 -- Commands (e.g. RXON, etc.) - * 5 -- unused (HCCA) - * 6 -- unused (HCCA) - * 7 -- not used by driver (device-internal only) + * Tx DMA FIFOs have dedicated purposes. * * For 5000 series and up, they are used differently * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): @@ -151,7 +141,7 @@ * Tx completion may end up being out-of-order). * * The driver must maintain the queue's Byte Count table in host DRAM - * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. + * for this mode. * This mode does not support fragmentation. * * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. @@ -164,7 +154,7 @@ * * Driver controls scheduler operation via 3 means: * 1) Scheduler registers - * 2) Shared scheduler data base in internal 4956 SRAM + * 2) Shared scheduler data base in internal SRAM * 3) Shared data in host DRAM * * Initialization: diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 565980fbb591..3732380c4ffe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -232,7 +232,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) * reclaiming packets (on 'tx done IRQ), if free space become > high mark, * Tx queue resumed. * - * See more detailed info in iwl-4965-hw.h. ***************************************************/ int iwl_queue_space(const struct iwl_queue *q) -- GitLab From 23c0fcc66b4345ea97ae588c2e01f10c994652ba Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:53 -0700 Subject: [PATCH 0657/5560] iwlagn: all _agn devices support power save mode Remove broken_power_save checking Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 ++----- drivers/net/wireless/iwlwifi/iwl-power.c | 4 +--- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 60bfde75ce87..23b89c2e71da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2828,9 +2828,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; - if (!priv->cfg->base_params->broken_powersave) - hw->flags |= IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + hw->flags |= IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS; if (priv->cfg->sku & IWL_SKU_N) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7d303acc837c..a0530d03b301 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -269,7 +269,6 @@ struct iwl_base_params { const u16 max_ll_items; const bool shadow_ram_support; u16 led_compensation; - const bool broken_powersave; int chain_noise_num_beacons; bool adv_thermal_throttle; bool support_ct_kill_exit; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 93a86998a3b1..2c58980f2d06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1723,11 +1723,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); - if (!priv->cfg->base_params->broken_powersave) { - DEBUGFS_ADD_FILE(sleep_level_override, dir_data, - S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); - } + DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c43c8e66de73..ae176d8da9e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -354,9 +354,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (priv->cfg->base_params->broken_powersave) - iwl_power_sleep_cam_cmd(priv, cmd); - else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) + if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) 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 && -- GitLab From ae89726a02049e8f61bb3c8bf5dbf1fc06527a07 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 1 Apr 2011 16:29:54 -0700 Subject: [PATCH 0658/5560] iwlagn: tx power calib always done in firmware Remove the config flag for tx power calib Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-core.h | 3 --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index cccf7471c003..bc5dfe2978f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -495,8 +495,10 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) void iwlagn_setup_deferred_work(struct iwl_priv *priv) { - /* in agn, the tx power calibration is done in uCode */ - priv->disable_tx_power_cal = 1; + /* + * nothing need to be done here anymore + * still keep for future use if needed + */ } int iwlagn_hw_valid_rtc_data_addr(u32 addr) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a0530d03b301..98dc544f112c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -250,8 +250,6 @@ struct iwl_mod_params { * @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 - * instead of uCode * @ucode_tracing: support ucode continuous tracing * @sensitivity_calib_by_driver: driver has the capability to perform * sensitivity calibration operation @@ -278,7 +276,6 @@ struct iwl_base_params { unsigned int wd_timeout; bool temperature_kelvin; u32 max_event_log_size; - const bool tx_power_by_driver; const bool ucode_tracing; const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 2c58980f2d06..9b1f9621b630 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1767,9 +1767,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &priv->disable_chain_noise_cal); - if (priv->cfg->base_params->tx_power_by_driver) - DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, - &priv->disable_tx_power_cal); return 0; err: diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 14f7d8fb6886..7fe68f8dd210 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1489,7 +1489,6 @@ struct iwl_priv { struct work_struct txpower_work; u32 disable_sens_cal; u32 disable_chain_noise_cal; - u32 disable_tx_power_cal; struct work_struct run_time_calib_work; struct timer_list statistics_periodic; struct timer_list ucode_trace; -- GitLab From 703bc583cb98a24eeedd297ee59dfa12852897d1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 3 Apr 2011 08:14:41 -0700 Subject: [PATCH 0659/5560] iwlagn: sensitivity and chain noise done by driver _agn driver should perform both sensitivity and chain noise calib. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-core.h | 6 ------ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 16 ++++++---------- 6 files changed, 6 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5a7281047a13..d1d7852f0ee4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -245,8 +245,6 @@ static struct iwl_base_params iwl1000_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 9daf888b733c..805b0394850e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -354,8 +354,6 @@ static struct iwl_base_params iwl2000_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; @@ -376,8 +374,6 @@ static struct iwl_base_params iwl2030_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 8106423a2c84..357137f08632 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -471,8 +471,6 @@ static struct iwl_base_params iwl5000_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 7f0715eb0593..8847b2113978 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -443,8 +443,6 @@ static struct iwl_base_params iwl6000_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; @@ -464,8 +462,6 @@ static struct iwl_base_params iwl6050_base_params = { .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; static struct iwl_base_params iwl6000_g2_base_params = { @@ -484,8 +480,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 98dc544f112c..57763c013ca9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -251,10 +251,6 @@ struct iwl_mod_params { * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging * @ucode_tracing: support ucode continuous tracing - * @sensitivity_calib_by_driver: driver has the capability to perform - * 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 { @@ -277,8 +273,6 @@ struct iwl_base_params { bool temperature_kelvin; u32 max_event_log_size; const bool ucode_tracing; - const bool sensitivity_calib_by_driver; - const bool chain_noise_calib_by_driver; const bool shadow_reg_enable; }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9b1f9621b630..c02f06901f8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1747,10 +1747,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->base_params->sensitivity_calib_by_driver) - DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); - if (priv->cfg->base_params->chain_noise_calib_by_driver) - DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); if (iwl_bt_statistics(priv)) @@ -1761,12 +1759,10 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); - if (priv->cfg->base_params->sensitivity_calib_by_driver) - DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, - &priv->disable_sens_cal); - if (priv->cfg->base_params->chain_noise_calib_by_driver) - DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, - &priv->disable_chain_noise_cal); + DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, + &priv->disable_sens_cal); + DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, + &priv->disable_chain_noise_cal); return 0; err: -- GitLab From 0da0e5bf1522d75d446f5124e17016628d0a149e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 8 Apr 2011 08:14:56 -0700 Subject: [PATCH 0660/5560] iwlagn: clean up & autodetect statistics There's no need to keep both normal and BT statistics versions around all the time in memory when we only use a subset of both. So keep only the subsets that we need in memory, depending on the debug config). Also, in doing so, we can remove all the calls to iwl_bt_statistics() in the driver as we'll just access the copied statistics now. Finally, also remove this call from the one place where it might still be needed and automatically detect what kind of statistics the device is sending based on their size. This way, we don't need to keep track of which devices do what any more, which is good since this is subject to change based on the ucode version (as some ucode even for non-BT devices will in fact use BT statistics). Warn upon encountering a statistics command from the ucode that isn't known, so we will find such issues earlier in the future. Signed-off-by: Johannes Berg Tested-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 1 - drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 1 - drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 43 +-- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 4 +- .../net/wireless/iwlwifi/iwl-agn-debugfs.c | 134 +++----- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 4 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 17 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 64 ---- drivers/net/wireless/iwlwifi/iwl-core.h | 7 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 41 ++- drivers/net/wireless/iwlwifi/iwl-rx.c | 298 +++++++++--------- 13 files changed, 243 insertions(+), 376 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 805b0394850e..a31314fdb053 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -383,7 +383,6 @@ static struct iwl_ht_params iwl2000_ht_params = { }; static struct iwl_bt_params iwl2030_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, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 357137f08632..7c286662d26a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -259,7 +259,7 @@ static void iwl5150_temperature(struct iwl_priv *priv) u32 vt = 0; s32 offset = iwl_temp_calib_to_offset(priv); - vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); + vt = le32_to_cpu(priv->statistics.common.temperature); vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; /* now vt hold the temperature in Kelvin */ priv->temperature = KELVIN_TO_CELSIUS(vt); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 8847b2113978..064981345c84 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -489,7 +489,6 @@ static struct iwl_ht_params iwl6000_ht_params = { }; 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, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 7b761de77b0a..0f6bb9b2e642 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) IWL_DEBUG_CALIB(priv, "<lock, flags); - if (iwl_bt_statistics(priv)) { - rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> - rx.general.common); - ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); - cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck); - } else { - rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); - ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); - cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); - } + rx_info = &priv->statistics.rx_non_phy; + ofdm = &priv->statistics.rx_ofdm; + cck = &priv->statistics.rx_cck; if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * 1) Which antennas are connected. * 2) Differential rx gain settings to balance the 3 receivers. */ -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) +void iwl_chain_noise_calibration(struct iwl_priv *priv) { struct iwl_chain_noise_data *data = NULL; @@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) } spin_lock_irqsave(&priv->lock, flags); - if (iwl_bt_statistics(priv)) { - rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> - rx.general.common); - } else { - rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> - rx.general); - } + + rx_info = &priv->statistics.rx_non_phy; + if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); rxon_chnum = le16_to_cpu(ctx->staging.channel); - if (iwl_bt_statistics(priv)) { - stat_band24 = !!(((struct iwl_bt_notif_statistics *) - stat_resp)->flag & - STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *) - stat_resp)->flag) >> 16; - } else { - stat_band24 = !!(((struct iwl_notif_statistics *) - stat_resp)->flag & - STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) - stat_resp)->flag) >> 16; - } + stat_band24 = + !!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); + stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16; /* Make sure we accumulate data for just the associated channel * (even if scanning). */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index ef4d5079a7ed..4ef4dd934254 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -66,8 +66,8 @@ #include "iwl-core.h" #include "iwl-commands.h" -void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); -void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); +void iwl_chain_noise_calibration(struct iwl_priv *priv); +void iwl_sensitivity_calibration(struct iwl_priv *priv); void iwl_init_sensitivity(struct iwl_priv *priv); void iwl_reset_run_time_calib(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index d1834aa7edf0..71a5f31cd7cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -39,10 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) int p = 0; u32 flag; - if (iwl_bt_statistics(priv)) - flag = le32_to_cpu(priv->_agn.statistics_bt.flag); - else - flag = le32_to_cpu(priv->_agn.statistics.flag); + flag = le32_to_cpu(priv->statistics.flag); p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); if (flag & UCODE_STATISTICS_CLEAR_MSK) @@ -88,43 +85,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (iwl_bt_statistics(priv)) { - ofdm = &priv->_agn.statistics_bt.rx.ofdm; - cck = &priv->_agn.statistics_bt.rx.cck; - general = &priv->_agn.statistics_bt.rx.general.common; - ht = &priv->_agn.statistics_bt.rx.ofdm_ht; - accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; - accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; - accum_general = - &priv->_agn.accum_statistics_bt.rx.general.common; - accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; - delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; - delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; - delta_general = - &priv->_agn.delta_statistics_bt.rx.general.common; - delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; - max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; - max_cck = &priv->_agn.max_delta_bt.rx.cck; - max_general = &priv->_agn.max_delta_bt.rx.general.common; - max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht; - } else { - ofdm = &priv->_agn.statistics.rx.ofdm; - cck = &priv->_agn.statistics.rx.cck; - general = &priv->_agn.statistics.rx.general; - ht = &priv->_agn.statistics.rx.ofdm_ht; - accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; - accum_cck = &priv->_agn.accum_statistics.rx.cck; - accum_general = &priv->_agn.accum_statistics.rx.general; - accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; - delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; - delta_cck = &priv->_agn.delta_statistics.rx.cck; - delta_general = &priv->_agn.delta_statistics.rx.general; - delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; - max_ofdm = &priv->_agn.max_delta.rx.ofdm; - max_cck = &priv->_agn.max_delta.rx.cck; - max_general = &priv->_agn.max_delta.rx.general; - max_ht = &priv->_agn.max_delta.rx.ofdm_ht; - } + ofdm = &priv->statistics.rx_ofdm; + cck = &priv->statistics.rx_cck; + general = &priv->statistics.rx_non_phy; + ht = &priv->statistics.rx_ofdm_ht; + accum_ofdm = &priv->accum_stats.rx_ofdm; + accum_cck = &priv->accum_stats.rx_cck; + accum_general = &priv->accum_stats.rx_non_phy; + accum_ht = &priv->accum_stats.rx_ofdm_ht; + delta_ofdm = &priv->delta_stats.rx_ofdm; + delta_cck = &priv->delta_stats.rx_cck; + delta_general = &priv->delta_stats.rx_non_phy; + delta_ht = &priv->delta_stats.rx_ofdm_ht; + max_ofdm = &priv->max_delta_stats.rx_ofdm; + max_cck = &priv->max_delta_stats.rx_cck; + max_general = &priv->max_delta_stats.rx_non_phy; + max_ht = &priv->max_delta_stats.rx_ofdm_ht; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, @@ -531,20 +507,13 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, } /* the statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - if (iwl_bt_statistics(priv)) { - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta_tx = &priv->_agn.delta_statistics_bt.tx; - max_tx = &priv->_agn.max_delta_bt.tx; - } else { - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta_tx = &priv->_agn.delta_statistics.tx; - max_tx = &priv->_agn.max_delta.tx; - } + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + tx = &priv->statistics.tx; + accum_tx = &priv->accum_stats.tx; + delta_tx = &priv->delta_stats.tx; + max_tx = &priv->max_delta_stats.tx; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, @@ -731,36 +700,21 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, } /* the statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - if (iwl_bt_statistics(priv)) { - general = &priv->_agn.statistics_bt.general.common; - dbg = &priv->_agn.statistics_bt.general.common.dbg; - div = &priv->_agn.statistics_bt.general.common.div; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; - accum_div = &priv->_agn.accum_statistics_bt.general.common.div; - delta_general = &priv->_agn.delta_statistics_bt.general.common; - max_general = &priv->_agn.max_delta_bt.general.common; - delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; - max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; - delta_div = &priv->_agn.delta_statistics_bt.general.common.div; - max_div = &priv->_agn.max_delta_bt.general.common.div; - } else { - general = &priv->_agn.statistics.general.common; - dbg = &priv->_agn.statistics.general.common.dbg; - div = &priv->_agn.statistics.general.common.div; - accum_general = &priv->_agn.accum_statistics.general.common; - accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; - accum_div = &priv->_agn.accum_statistics.general.common.div; - delta_general = &priv->_agn.delta_statistics.general.common; - max_general = &priv->_agn.max_delta.general.common; - delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; - max_dbg = &priv->_agn.max_delta.general.common.dbg; - delta_div = &priv->_agn.delta_statistics.general.common.div; - max_div = &priv->_agn.max_delta.general.common.div; - } + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + general = &priv->statistics.common; + dbg = &priv->statistics.common.dbg; + div = &priv->statistics.common.div; + accum_general = &priv->accum_stats.common; + accum_dbg = &priv->accum_stats.common.dbg; + accum_div = &priv->accum_stats.common.div; + delta_general = &priv->delta_stats.common; + max_general = &priv->max_delta_stats.common; + delta_dbg = &priv->delta_stats.common.dbg; + max_dbg = &priv->max_delta_stats.common.dbg; + delta_div = &priv->delta_stats.common.div; + max_div = &priv->max_delta_stats.common.div; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, @@ -876,8 +830,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - bt = &priv->_agn.statistics_bt.general.activity; - accum_bt = &priv->_agn.accum_statistics_bt.general.activity; + bt = &priv->statistics.bt_activity; + accum_bt = &priv->accum_stats.bt_activity; pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); @@ -918,10 +872,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", - le32_to_cpu(priv->_agn.statistics_bt.rx. - general.num_bt_kills), - priv->_agn.accum_statistics_bt.rx. - general.num_bt_kills); + le32_to_cpu(priv->statistics.num_bt_kills), + priv->statistics.accum_num_bt_kills); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index bc5dfe2978f0..e741128842bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -549,9 +549,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) void iwlagn_temperature(struct iwl_priv *priv) { /* store temperature from correct statistics (in Celsius) */ - priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ? - priv->_agn.statistics_bt.general.common.temperature : - priv->_agn.statistics.general.common.temperature); + priv->temperature = le32_to_cpu(priv->statistics.common.temperature); iwl_tt_handler(priv); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 23b89c2e71da..20499b764430 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1705,10 +1705,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) else priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS || - (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)) - priv->bt_statistics = true; - /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ @@ -2626,17 +2622,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - if (iwl_bt_statistics(priv)) { - iwl_chain_noise_calibration(priv, - (void *)&priv->_agn.statistics_bt); - iwl_sensitivity_calibration(priv, - (void *)&priv->_agn.statistics_bt); - } else { - iwl_chain_noise_calibration(priv, - (void *)&priv->_agn.statistics); - iwl_sensitivity_calibration(priv, - (void *)&priv->_agn.statistics); - } + iwl_chain_noise_calibration(priv); + iwl_sensitivity_calibration(priv); } mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index a1a5c1b23096..0edba8a6419b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2535,53 +2535,6 @@ struct rate_histogram { /* statistics command response */ -struct iwl39_statistics_rx_phy { - __le32 ina_cnt; - __le32 fina_cnt; - __le32 plcp_err; - __le32 crc32_err; - __le32 overrun_err; - __le32 early_overrun_err; - __le32 crc32_good; - __le32 false_alarm_cnt; - __le32 fina_sync_err_cnt; - __le32 sfd_timeout; - __le32 fina_timeout; - __le32 unresponded_rts; - __le32 rxe_frame_limit_overrun; - __le32 sent_ack_cnt; - __le32 sent_cts_cnt; -} __packed; - -struct iwl39_statistics_rx_non_phy { - __le32 bogus_cts; /* CTS received when not expecting CTS */ - __le32 bogus_ack; /* ACK received when not expecting ACK */ - __le32 non_bssid_frames; /* number of frames with BSSID that - * doesn't belong to the STA BSSID */ - __le32 filtered_frames; /* count frames that were dumped in the - * filtering process */ - __le32 non_channel_beacons; /* beacons with our bss id but not on - * our serving channel */ -} __packed; - -struct iwl39_statistics_rx { - struct iwl39_statistics_rx_phy ofdm; - struct iwl39_statistics_rx_phy cck; - struct iwl39_statistics_rx_non_phy general; -} __packed; - -struct iwl39_statistics_tx { - __le32 preamble_cnt; - __le32 rx_detected_cnt; - __le32 bt_prio_defer_cnt; - __le32 bt_prio_kill_cnt; - __le32 few_bytes_cnt; - __le32 cts_timeout; - __le32 ack_timeout; - __le32 expected_ack_cnt; - __le32 actual_ack_cnt; -} __packed; - struct statistics_dbg { __le32 burst_check; __le32 burst_count; @@ -2589,23 +2542,6 @@ struct statistics_dbg { __le32 reserved[3]; } __packed; -struct iwl39_statistics_div { - __le32 tx_on_a; - __le32 tx_on_b; - __le32 exec_time; - __le32 probe_time; -} __packed; - -struct iwl39_statistics_general { - __le32 temperature; - struct statistics_dbg dbg; - __le32 sleep_time; - __le32 slots_out; - __le32 slots_idle; - __le32 ttl_timestamp; - struct iwl39_statistics_div div; -} __packed; - struct statistics_rx_phy { __le32 ina_cnt; __le32 fina_cnt; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 57763c013ca9..6988335328e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -279,7 +279,6 @@ struct iwl_base_params { * @advanced_bt_coexist: support advanced bt coexist * @bt_init_traffic_load: specify initial bt traffic load * @bt_prio_boost: default bt priority boost value - * @bt_statistics: use BT version of statistics notification * @agg_time_limit: maximum number of uSec in aggregation * @ampdu_factor: Maximum A-MPDU length factor * @ampdu_density: Minimum A-MPDU spacing @@ -289,7 +288,6 @@ struct iwl_bt_params { bool advanced_bt_coexist; u8 bt_init_traffic_load; u8 bt_prio_boost; - const bool bt_statistics; u16 agg_time_limit; u8 ampdu_factor; u8 ampdu_density; @@ -696,11 +694,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) priv->cfg->bt_params->advanced_bt_coexist; } -static inline bool iwl_bt_statistics(struct iwl_priv *priv) -{ - return priv->bt_statistics; -} - extern bool bt_coex_active; extern bool bt_siso_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index c02f06901f8c..897efacb96eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1751,8 +1751,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); - if (iwl_bt_statistics(priv)) - DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); 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); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7fe68f8dd210..e84534c4d956 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -543,13 +543,12 @@ enum iwl_ucode_tlv_type { * enum iwl_ucode_tlv_flag - ucode API flags * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_BTSTATS: This uCode image uses BT statistics, which - * may be true even if the device doesn't have BT. + * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). */ enum iwl_ucode_tlv_flag { IWL_UCODE_TLV_FLAGS_PAN = BIT(0), - IWL_UCODE_TLV_FLAGS_BTSTATS = BIT(1), + IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1), IWL_UCODE_TLV_FLAGS_MFP = BIT(2), }; @@ -1356,6 +1355,31 @@ struct iwl_priv { /* Last Rx'd beacon timestamp */ u64 timestamp; + struct { + __le32 flag; + struct statistics_general_common common; + struct statistics_rx_non_phy rx_non_phy; + struct statistics_rx_phy rx_ofdm; + struct statistics_rx_ht_phy rx_ofdm_ht; + struct statistics_rx_phy rx_cck; + struct statistics_tx tx; +#ifdef CONFIG_IWLWIFI_DEBUGFS + struct statistics_bt_activity bt_activity; + __le32 num_bt_kills, accum_num_bt_kills; +#endif + } statistics; +#ifdef CONFIG_IWLWIFI_DEBUGFS + struct { + struct statistics_general_common common; + struct statistics_rx_non_phy rx_non_phy; + struct statistics_rx_phy rx_ofdm; + struct statistics_rx_ht_phy rx_ofdm_ht; + struct statistics_rx_phy rx_cck; + struct statistics_tx tx; + struct statistics_bt_activity bt_activity; + } accum_stats, delta_stats, max_delta_stats; +#endif + struct { /* INT ICT Table */ __le32 *ict_tbl; @@ -1387,19 +1411,9 @@ struct iwl_priv { u8 phy_calib_chain_noise_reset_cmd; u8 phy_calib_chain_noise_gain_cmd; - struct iwl_notif_statistics statistics; - struct iwl_bt_notif_statistics statistics_bt; /* counts reply_tx error */ struct reply_tx_error_statistics reply_tx_stats; struct reply_agg_tx_error_statistics reply_agg_tx_stats; -#ifdef CONFIG_IWLWIFI_DEBUGFS - struct iwl_notif_statistics accum_statistics; - struct iwl_notif_statistics delta_statistics; - struct iwl_notif_statistics max_delta; - struct iwl_bt_notif_statistics accum_statistics_bt; - struct iwl_bt_notif_statistics delta_statistics_bt; - struct iwl_bt_notif_statistics max_delta_bt; -#endif /* notification wait support */ struct list_head notif_waits; spinlock_t notif_wait_lock; @@ -1424,7 +1438,6 @@ struct iwl_priv { bool bt_ch_announce; bool bt_full_concurrent; bool bt_ant_couple_ok; - bool bt_statistics; __le32 kill_ack_mask; __le32 kill_cts_mask; __le16 bt_valid; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 4472761fc591..b49819ca2cd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -390,21 +390,16 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal * operation state. */ -static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +static bool iwl_good_ack_health(struct iwl_priv *priv, + struct statistics_tx *cur) { int actual_delta, expected_delta, ba_timeout_delta; - struct statistics_tx *cur, *old; + struct statistics_tx *old; if (priv->_agn.agg_tids_count) return true; - if (iwl_bt_statistics(priv)) { - cur = &pkt->u.stats_bt.tx; - old = &priv->_agn.statistics_bt.tx; - } else { - cur = &pkt->u.stats.tx; - old = &priv->_agn.statistics.tx; - } + old = &priv->statistics.tx; actual_delta = le32_to_cpu(cur->actual_ack_cnt) - le32_to_cpu(old->actual_ack_cnt); @@ -430,10 +425,10 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt * DEBUG is not, these will just compile out. */ IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", - priv->_agn.delta_statistics.tx.rx_detected_cnt); + priv->delta_stats.tx.rx_detected_cnt); IWL_DEBUG_RADIO(priv, "ack_or_ba_timeout_collision delta %d\n", - priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); + priv->delta_stats.tx.ack_or_ba_timeout_collision); #endif if (ba_timeout_delta >= BA_TIMEOUT_MAX) @@ -450,7 +445,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt * to improve the throughput. */ static bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, unsigned int msecs) + struct statistics_rx_phy *cur_ofdm, + struct statistics_rx_ht_phy *cur_ofdm_ht, + unsigned int msecs) { int delta; int threshold = priv->cfg->base_params->plcp_delta_threshold; @@ -460,29 +457,12 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, return true; } - if (iwl_bt_statistics(priv)) { - struct statistics_rx_bt *cur, *old; - - cur = &pkt->u.stats_bt.rx; - old = &priv->_agn.statistics_bt.rx; - - delta = le32_to_cpu(cur->ofdm.plcp_err) - - le32_to_cpu(old->ofdm.plcp_err) + - le32_to_cpu(cur->ofdm_ht.plcp_err) - - le32_to_cpu(old->ofdm_ht.plcp_err); - } else { - struct statistics_rx *cur, *old; - - cur = &pkt->u.stats.rx; - old = &priv->_agn.statistics.rx; - - delta = le32_to_cpu(cur->ofdm.plcp_err) - - le32_to_cpu(old->ofdm.plcp_err) + - le32_to_cpu(cur->ofdm_ht.plcp_err) - - le32_to_cpu(old->ofdm_ht.plcp_err); - } + delta = le32_to_cpu(cur_ofdm->plcp_err) - + le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) + + le32_to_cpu(cur_ofdm_ht->plcp_err) - + le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err); - /* Can be negative if firmware reseted statistics */ + /* Can be negative if firmware reset statistics */ if (delta <= 0) return true; @@ -497,44 +477,36 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, } static void iwl_recover_from_statistics(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) + struct statistics_rx_phy *cur_ofdm, + struct statistics_rx_ht_phy *cur_ofdm_ht, + struct statistics_tx *tx, + unsigned long stamp) { const struct iwl_mod_params *mod_params = priv->cfg->mod_params; unsigned int msecs; - unsigned long stamp; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - stamp = jiffies; msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); /* Only gather statistics and update time stamp when not associated */ if (!iwl_is_any_associated(priv)) - goto out; + return; /* Do not check/recover when do not have enough statistics data */ if (msecs < 99) return; - if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { + if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) { IWL_ERR(priv, "low ack count detected, restart firmware\n"); if (!iwl_force_reset(priv, IWL_FW_RESET, false)) return; } - if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs)) + if (mod_params->plcp_check && + !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) iwl_force_reset(priv, IWL_RF_RESET, false); - -out: - if (iwl_bt_statistics(priv)) - memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, - sizeof(priv->_agn.statistics_bt)); - else - memcpy(&priv->_agn.statistics, &pkt->u.stats, - sizeof(priv->_agn.statistics)); - - priv->rx_statistics_jiffies = stamp; } /* Calculate noise level, based on measurements during network silence just @@ -548,10 +520,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) int bcn_silence_a, bcn_silence_b, bcn_silence_c; int last_rx_noise; - if (iwl_bt_statistics(priv)) - rx_info = &(priv->_agn.statistics_bt.rx.general.common); - else - rx_info = &(priv->_agn.statistics.rx.general); + rx_info = &priv->statistics.rx_non_phy; + bcn_silence_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; bcn_silence_b = @@ -583,105 +553,153 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) last_rx_noise); } +#ifdef CONFIG_IWLWIFI_DEBUGFS /* * based on the assumption of all statistics counter are in DWORD * FIXME: This function is for debugging, do not deal with * the case of counters roll-over. */ -static void iwl_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) +static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta, + __le32 *max_delta, __le32 *accum, int size) { -#ifdef CONFIG_IWLWIFI_DEBUGFS - int i, size; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - struct statistics_general_common *general, *accum_general; - struct statistics_tx *tx, *accum_tx; - - if (iwl_bt_statistics(priv)) { - prev_stats = (__le32 *)&priv->_agn.statistics_bt; - accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; - size = sizeof(struct iwl_bt_notif_statistics); - general = &priv->_agn.statistics_bt.general.common; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta = (u32 *)&priv->_agn.delta_statistics_bt; - max_delta = (u32 *)&priv->_agn.max_delta_bt; - } else { - prev_stats = (__le32 *)&priv->_agn.statistics; - accum_stats = (u32 *)&priv->_agn.accum_statistics; - size = sizeof(struct iwl_notif_statistics); - general = &priv->_agn.statistics.general.common; - accum_general = &priv->_agn.accum_statistics.general.common; - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta = (u32 *)&priv->_agn.delta_statistics; - max_delta = (u32 *)&priv->_agn.max_delta; - } - for (i = sizeof(__le32); i < size; - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) + int i; + + for (i = 0; + i < size / sizeof(__le32); + i++, prev++, cur++, delta++, max_delta++, accum++) { + if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) { + *delta = cpu_to_le32( + le32_to_cpu(*cur) - le32_to_cpu(*prev)); + le32_add_cpu(accum, le32_to_cpu(*delta)); + if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta)) *max_delta = *delta; } } +} - /* reset accumulative statistics for "no-counter" type statistics */ - accum_general->temperature = general->temperature; - accum_general->temperature_m = general->temperature_m; - accum_general->ttl_timestamp = general->ttl_timestamp; - accum_tx->tx_power.ant_a = tx->tx_power.ant_a; - accum_tx->tx_power.ant_b = tx->tx_power.ant_b; - accum_tx->tx_power.ant_c = tx->tx_power.ant_c; -#endif +static void +iwl_accumulative_statistics(struct iwl_priv *priv, + struct statistics_general_common *common, + struct statistics_rx_non_phy *rx_non_phy, + struct statistics_rx_phy *rx_ofdm, + struct statistics_rx_ht_phy *rx_ofdm_ht, + struct statistics_rx_phy *rx_cck, + struct statistics_tx *tx, + struct statistics_bt_activity *bt_activity) +{ +#define ACCUM(_name) \ + accum_stats((__le32 *)&priv->statistics._name, \ + (__le32 *)_name, \ + (__le32 *)&priv->delta_stats._name, \ + (__le32 *)&priv->max_delta_stats._name, \ + (__le32 *)&priv->accum_stats._name, \ + sizeof(*_name)); + + ACCUM(common); + ACCUM(rx_non_phy); + ACCUM(rx_ofdm); + ACCUM(rx_ofdm_ht); + ACCUM(rx_cck); + ACCUM(tx); + if (bt_activity) + ACCUM(bt_activity); +#undef ACCUM } +#else +static inline void +iwl_accumulative_statistics(struct iwl_priv *priv, + struct statistics_general_common *common, + struct statistics_rx_non_phy *rx_non_phy, + struct statistics_rx_phy *rx_ofdm, + struct statistics_rx_ht_phy *rx_ofdm_ht, + struct statistics_rx_phy *rx_cck, + struct statistics_tx *tx, + struct statistics_bt_activity *bt_activity) +{ +} +#endif static void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { + unsigned long stamp = jiffies; const int reg_recalib_period = 60; int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + __le32 *flag; + struct statistics_general_common *common; + struct statistics_rx_non_phy *rx_non_phy; + struct statistics_rx_phy *rx_ofdm; + struct statistics_rx_ht_phy *rx_ofdm_ht; + struct statistics_rx_phy *rx_cck; + struct statistics_tx *tx; + struct statistics_bt_activity *bt_activity; + + len -= sizeof(struct iwl_cmd_header); /* skip header */ + + IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", + len); + + if (len == sizeof(struct iwl_bt_notif_statistics)) { + struct iwl_bt_notif_statistics *stats; + stats = &pkt->u.stats_bt; + flag = &stats->flag; + common = &stats->general.common; + rx_non_phy = &stats->rx.general.common; + rx_ofdm = &stats->rx.ofdm; + rx_ofdm_ht = &stats->rx.ofdm_ht; + rx_cck = &stats->rx.cck; + tx = &stats->tx; + bt_activity = &stats->general.activity; - if (iwl_bt_statistics(priv)) { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_bt_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->_agn.statistics_bt.general.common.temperature != - pkt->u.stats_bt.general.common.temperature) || - ((priv->_agn.statistics_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); - - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); +#ifdef CONFIG_IWLWIFI_DEBUGFS + /* handle this exception directly */ + priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills; + le32_add_cpu(&priv->statistics.accum_num_bt_kills, + le32_to_cpu(stats->rx.general.num_bt_kills)); +#endif + } else if (len == sizeof(struct iwl_notif_statistics)) { + struct iwl_notif_statistics *stats; + stats = &pkt->u.stats; + flag = &stats->flag; + common = &stats->general.common; + rx_non_phy = &stats->rx.general; + rx_ofdm = &stats->rx.ofdm; + rx_ofdm_ht = &stats->rx.ofdm_ht; + rx_cck = &stats->rx.cck; + tx = &stats->tx; + bt_activity = NULL; } else { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->_agn.statistics.general.common.temperature != - pkt->u.stats.general.common.temperature) || - ((priv->_agn.statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); - - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); + WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", + len, sizeof(struct iwl_bt_notif_statistics), + sizeof(struct iwl_notif_statistics)); + return; } - iwl_recover_from_statistics(priv, pkt); + change = common->temperature != priv->statistics.common.temperature || + (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK); + + iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm, + rx_ofdm_ht, rx_cck, tx, bt_activity); + + iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp); + + priv->statistics.flag = *flag; + memcpy(&priv->statistics.common, common, sizeof(*common)); + memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy)); + memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm)); + memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht)); + memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck)); + memcpy(&priv->statistics.tx, tx, sizeof(*tx)); +#ifdef CONFIG_IWLWIFI_DEBUGFS + if (bt_activity) + memcpy(&priv->statistics.bt_activity, bt_activity, + sizeof(*bt_activity)); +#endif + + priv->rx_statistics_jiffies = stamp; set_bit(STATUS_STATISTICS, &priv->status); @@ -708,18 +726,12 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv, if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { #ifdef CONFIG_IWLWIFI_DEBUGFS - memset(&priv->_agn.accum_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.delta_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.max_delta, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.accum_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.delta_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.max_delta_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); + memset(&priv->accum_stats, 0, + sizeof(priv->accum_stats)); + memset(&priv->delta_stats, 0, + sizeof(priv->delta_stats)); + memset(&priv->max_delta_stats, 0, + sizeof(priv->max_delta_stats)); #endif IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); } -- GitLab From 6fc3ba999994b675c4e6af77ac4e1a6bfd8e6128 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 4 Apr 2011 06:16:29 -0700 Subject: [PATCH 0661/5560] iwlagn: downgrade warning on unknown TLV If we maintain API properly, then there isn't really a reason to warn about this since we'll just be adding things that are safe to ignore, so downgrade the warning to debug info level. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 20499b764430..47a4cda9eb72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1481,7 +1481,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, le32_to_cpup((__le32 *)tlv_data); break; default: - IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); + IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); break; } } -- GitLab From 5ecd602e76b925eb19c31d8e861876c9a56321f3 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Fri, 8 Apr 2011 08:23:23 -0700 Subject: [PATCH 0662/5560] ibmasm: fix comment typo The patch below fixes a typo in a comment. Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- drivers/misc/ibmasm/ibmasmfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index d2d5d23416dd..89947723a27d 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -29,7 +29,7 @@ /* * The IBMASM file virtual filesystem. It creates the following hierarchy - * dymamically when mounted from user space: + * dynamically when mounted from user space: * * /ibmasm * |-- 0 -- GitLab From 93ae653491f0a413d5f4d9aa4df45d09ecb55d62 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 8 Apr 2011 13:03:02 -0700 Subject: [PATCH 0663/5560] cnic: Fix rtnl deadlock When cnic_stop_hw() -> cnic_cm_stop_bnx2x_hw() is called under rtnl_lock() from NETDEV_DOWN event, it waits for cnic_delete_task() to complete. It will deadlock when cnic_delete_task() takes rtnl_lock() before calling cnic_ulp_stop_one(). We fix it by removing the rtnl_lock() in cnic_delete_task(). cnic_ulp_stop_one() has mutex and atomic bit ops to prevent important operations from being done more than once, so it is not necessary to take rtnl_lock(). Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 5dfbff06631c..cde59b4e5ef8 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3983,9 +3983,7 @@ static void cnic_delete_task(struct work_struct *work) if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) { struct drv_ctl_info info; - rtnl_lock(); cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI); - rtnl_unlock(); info.cmd = DRV_CTL_ISCSI_STOPPED_CMD; cp->ethdev->drv_ctl(dev->netdev, &info); -- GitLab From c5e06360317d9c7a91de983749d136c4089e5379 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Fri, 8 Apr 2011 13:06:25 -0700 Subject: [PATCH 0664/5560] cxgb4: drop phys_id interface and implement the newer set_phys_id Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4_main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 5352c8a23f4d..0af9c9f0ca78 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -1336,15 +1336,20 @@ static int restart_autoneg(struct net_device *dev) return 0; } -static int identify_port(struct net_device *dev, u32 data) +static int identify_port(struct net_device *dev, + enum ethtool_phys_id_state state) { + unsigned int val; struct adapter *adap = netdev2adap(dev); - if (data == 0) - data = 2; /* default to 2 seconds */ + if (state == ETHTOOL_ID_ACTIVE) + val = 0xffff; + else if (state == ETHTOOL_ID_INACTIVE) + val = 0; + else + return -EINVAL; - return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, - data * 5); + return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, val); } static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps) @@ -2011,7 +2016,7 @@ static struct ethtool_ops cxgb_ethtool_ops = { .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = get_strings, - .phys_id = identify_port, + .set_phys_id = identify_port, .nway_reset = restart_autoneg, .get_sset_count = get_sset_count, .get_ethtool_stats = get_stats, -- GitLab From 857a3d0fb648b450de4a87cc2df9055774cafd2d Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Fri, 8 Apr 2011 13:07:08 -0700 Subject: [PATCH 0665/5560] cxgb4vf: drop phys_id interface and implement the newer set_phys_id Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 6aad64df4dcb..b0d037ea367d 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -1352,11 +1352,20 @@ static int cxgb4vf_set_rx_csum(struct net_device *dev, u32 csum) /* * Identify the port by blinking the port's LED. */ -static int cxgb4vf_phys_id(struct net_device *dev, u32 id) +static int cxgb4vf_phys_id(struct net_device *dev, + enum ethtool_phys_id_state state) { + unsigned int val; struct port_info *pi = netdev_priv(dev); - return t4vf_identify_port(pi->adapter, pi->viid, 5); + if (state == ETHTOOL_ID_ACTIVE) + val = 0xffff; + else if (state == ETHTOOL_ID_INACTIVE) + val = 0; + else + return -EINVAL; + + return t4vf_identify_port(pi->adapter, pi->viid, val); } /* @@ -1588,7 +1597,7 @@ static struct ethtool_ops cxgb4vf_ethtool_ops = { .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = cxgb4vf_get_strings, - .phys_id = cxgb4vf_phys_id, + .set_phys_id = cxgb4vf_phys_id, .get_sset_count = cxgb4vf_get_sset_count, .get_ethtool_stats = cxgb4vf_get_ethtool_stats, .get_regs_len = cxgb4vf_get_regs_len, -- GitLab From 7422caa5a1a53ee6b21a687c61cc5435edf8c19f Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Fri, 8 Apr 2011 19:33:07 +0200 Subject: [PATCH 0666/5560] ufs: Fix a typo Signed-off-by: Alessio Igor Bogani Signed-off-by: Jiri Kosina --- fs/ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 03c255f12df5..6863599f7033 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -409,7 +409,7 @@ ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, } /** - * ufs_getfrag_bloc() - `get_block_t' function, interface between UFS and + * ufs_getfrag_block() - `get_block_t' function, interface between UFS and * readpage, writepage and so on */ -- GitLab From cb3e85fe19575cce8af82bc62a070c72e8f781b8 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Sat, 9 Apr 2011 01:43:18 +0200 Subject: [PATCH 0667/5560] HID: hidraw: fix samples miscompilation On systems where userspace doesn't have new hidraw.h populated to /usr/include, the hidraw sample won't compile as it's missing the new ioctl defitions. Introduce temporary ugly workaround to define the ioctls "manually" in such cases, just to avoid miscompilation in allmodconfig cases. Reported-by: Stephen Rothwell Signed-off-by: Jiri Kosina --- samples/hidraw/hid-example.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c index 40e3d6200582..816e2dcda7ca 100644 --- a/samples/hidraw/hid-example.c +++ b/samples/hidraw/hid-example.c @@ -14,6 +14,17 @@ #include #include +/* + * Ugly hack to work around failing compilation on systems that don't + * yet populate new version of hidraw.h to userspace. + * + * If you need this, please have your distro update the kernel headers. + */ +#ifndef HIDIOCSFEATURE +#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) +#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) +#endif + /* Unix */ #include #include -- GitLab From fefecc6989b4b24276797270c0e229c07be02ad3 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 8 Apr 2011 20:33:25 -0500 Subject: [PATCH 0668/5560] staging: rt2860sta and rt2870sta: Remove drivers replaced in net/wireless The staging driver rt2860sta is replaced by mainline driver rt2800pci, and rt2870sta is replaced by rt2800usb. As a result, the staging drivers are deleted. Signed-off-by: Larry Finger --- --- drivers/staging/Kconfig | 4 - drivers/staging/Makefile | 2 - drivers/staging/rt2860/Kconfig | 10 - drivers/staging/rt2860/Makefile | 52 - drivers/staging/rt2860/TODO | 16 - drivers/staging/rt2860/ap.h | 68 - drivers/staging/rt2860/chip/mac_pci.h | 355 - drivers/staging/rt2860/chip/mac_usb.h | 345 - drivers/staging/rt2860/chip/rt2860.h | 54 - drivers/staging/rt2860/chip/rt2870.h | 46 - drivers/staging/rt2860/chip/rt3070.h | 67 - drivers/staging/rt2860/chip/rt3090.h | 72 - drivers/staging/rt2860/chip/rt30xx.h | 47 - drivers/staging/rt2860/chip/rtmp_mac.h | 1308 ---- drivers/staging/rt2860/chip/rtmp_phy.h | 516 -- drivers/staging/rt2860/chips/rt3070.c | 169 - drivers/staging/rt2860/chips/rt3090.c | 121 - drivers/staging/rt2860/chips/rt30xx.c | 516 -- drivers/staging/rt2860/chlist.h | 113 - drivers/staging/rt2860/common/action.c | 606 -- drivers/staging/rt2860/common/action.h | 56 - drivers/staging/rt2860/common/ba_action.c | 1650 ----- drivers/staging/rt2860/common/cmm_aes.c | 1311 ---- drivers/staging/rt2860/common/cmm_asic.c | 2565 -------- drivers/staging/rt2860/common/cmm_cfg.c | 258 - drivers/staging/rt2860/common/cmm_data.c | 2361 ------- drivers/staging/rt2860/common/cmm_data_pci.c | 1096 ---- drivers/staging/rt2860/common/cmm_data_usb.c | 951 --- drivers/staging/rt2860/common/cmm_info.c | 955 --- drivers/staging/rt2860/common/cmm_mac_pci.c | 1661 ----- drivers/staging/rt2860/common/cmm_mac_usb.c | 1162 ---- drivers/staging/rt2860/common/cmm_sanity.c | 1205 ---- drivers/staging/rt2860/common/cmm_sync.c | 718 --- drivers/staging/rt2860/common/cmm_tkip.c | 833 --- drivers/staging/rt2860/common/cmm_wep.c | 473 -- drivers/staging/rt2860/common/cmm_wpa.c | 3010 --------- drivers/staging/rt2860/common/crypt_hmac.c | 187 - drivers/staging/rt2860/common/crypt_md5.c | 339 - drivers/staging/rt2860/common/crypt_sha2.c | 269 - drivers/staging/rt2860/common/dfs.c | 68 - drivers/staging/rt2860/common/ee_efuse.c | 351 - drivers/staging/rt2860/common/ee_prom.c | 197 - drivers/staging/rt2860/common/eeprom.c | 91 - drivers/staging/rt2860/common/mlme.c | 6068 ------------------ drivers/staging/rt2860/common/rt_channel.c | 1705 ----- drivers/staging/rt2860/common/rt_rf.c | 187 - drivers/staging/rt2860/common/rtmp_init.c | 3536 ---------- drivers/staging/rt2860/common/rtmp_mcu.c | 336 - drivers/staging/rt2860/common/rtmp_timer.c | 302 - drivers/staging/rt2860/common/spectrum.c | 2205 ------- drivers/staging/rt2860/crypt_hmac.h | 65 - drivers/staging/rt2860/crypt_md5.h | 73 - drivers/staging/rt2860/crypt_sha2.h | 73 - drivers/staging/rt2860/dfs.h | 39 - drivers/staging/rt2860/eeprom.h | 67 - drivers/staging/rt2860/iface/rtmp_pci.h | 80 - drivers/staging/rt2860/iface/rtmp_usb.h | 196 - drivers/staging/rt2860/mlme.h | 1050 --- drivers/staging/rt2860/oid.h | 779 --- drivers/staging/rt2860/pci_main_dev.c | 1192 ---- drivers/staging/rt2860/rt_config.h | 71 - drivers/staging/rt2860/rt_linux.c | 1367 ---- drivers/staging/rt2860/rt_linux.h | 835 --- drivers/staging/rt2860/rt_main_dev.c | 736 --- drivers/staging/rt2860/rt_pci_rbus.c | 837 --- drivers/staging/rt2860/rt_usb.c | 794 --- drivers/staging/rt2860/rtmp.h | 4332 ------------- drivers/staging/rt2860/rtmp_chip.h | 258 - drivers/staging/rt2860/rtmp_ckipmic.h | 63 - drivers/staging/rt2860/rtmp_def.h | 1427 ---- drivers/staging/rt2860/rtmp_dot11.h | 100 - drivers/staging/rt2860/rtmp_iface.h | 75 - drivers/staging/rt2860/rtmp_mcu.h | 49 - drivers/staging/rt2860/rtmp_os.h | 90 - drivers/staging/rt2860/rtmp_timer.h | 148 - drivers/staging/rt2860/rtmp_type.h | 89 - drivers/staging/rt2860/rtusb_io.h | 185 - drivers/staging/rt2860/spectrum.h | 189 - drivers/staging/rt2860/spectrum_def.h | 202 - drivers/staging/rt2860/sta/assoc.c | 1602 ----- drivers/staging/rt2860/sta/auth.c | 517 -- drivers/staging/rt2860/sta/auth_rsp.c | 142 - drivers/staging/rt2860/sta/connect.c | 2613 -------- drivers/staging/rt2860/sta/rtmp_data.c | 2552 -------- drivers/staging/rt2860/sta/sanity.c | 362 -- drivers/staging/rt2860/sta/sync.c | 1968 ------ drivers/staging/rt2860/sta/wpa.c | 374 -- drivers/staging/rt2860/sta_ioctl.c | 2912 --------- drivers/staging/rt2860/usb_main_dev.c | 927 --- drivers/staging/rt2860/wpa.h | 390 -- drivers/staging/rt2870/Kconfig | 9 - drivers/staging/rt2870/Makefile | 55 - drivers/staging/rt2870/TODO | 17 - drivers/staging/rt2870/aironet.h | 1 - drivers/staging/rt2870/ap.h | 1 - drivers/staging/rt2870/chips/rt3070.c | 1 - drivers/staging/rt2870/chips/rt30xx.c | 1 - drivers/staging/rt2870/chlist.h | 1 - drivers/staging/rt2870/common/acction.c | 1 - drivers/staging/rt2870/common/action.c | 1 - drivers/staging/rt2870/common/action.h | 1 - drivers/staging/rt2870/common/ba_action.c | 1 - drivers/staging/rt2870/common/cmm_aes.c | 1 - drivers/staging/rt2870/common/cmm_asic.c | 1 - drivers/staging/rt2870/common/cmm_cfg.c | 1 - drivers/staging/rt2870/common/cmm_data.c | 1 - drivers/staging/rt2870/common/cmm_data_usb.c | 1 - drivers/staging/rt2870/common/cmm_info.c | 1 - drivers/staging/rt2870/common/cmm_mac_usb.c | 1 - drivers/staging/rt2870/common/cmm_profile.c | 1 - drivers/staging/rt2870/common/cmm_sanity.c | 1 - drivers/staging/rt2870/common/cmm_sync.c | 1 - drivers/staging/rt2870/common/cmm_tkip.c | 1 - drivers/staging/rt2870/common/cmm_wep.c | 1 - drivers/staging/rt2870/common/cmm_wpa.c | 1 - drivers/staging/rt2870/common/crypt_hmac.c | 1 - drivers/staging/rt2870/common/crypt_md5.c | 1 - drivers/staging/rt2870/common/crypt_sha2.c | 1 - drivers/staging/rt2870/common/dfs.c | 1 - drivers/staging/rt2870/common/ee_efuse.c | 1 - drivers/staging/rt2870/common/eeprom.c | 1 - drivers/staging/rt2870/common/md5.c | 1 - drivers/staging/rt2870/common/mlme.c | 1 - drivers/staging/rt2870/common/rt_channel.c | 1 - drivers/staging/rt2870/common/rt_rf.c | 1 - drivers/staging/rt2870/common/rtmp_init.c | 1 - drivers/staging/rt2870/common/rtmp_mcu.c | 1 - drivers/staging/rt2870/common/rtmp_timer.c | 1 - drivers/staging/rt2870/common/rtmp_tkip.c | 1 - drivers/staging/rt2870/common/rtmp_wep.c | 1 - drivers/staging/rt2870/common/rtusb_bulk.c | 1232 ---- drivers/staging/rt2870/common/rtusb_data.c | 262 - drivers/staging/rt2870/common/rtusb_io.c | 2104 ------ drivers/staging/rt2870/common/spectrum.c | 1 - drivers/staging/rt2870/dfs.h | 1 - drivers/staging/rt2870/md5.h | 1 - drivers/staging/rt2870/mlme.h | 1 - drivers/staging/rt2870/oid.h | 1 - drivers/staging/rt2870/rt28xx.h | 1 - drivers/staging/rt2870/rt_config.h | 1 - drivers/staging/rt2870/rt_linux.c | 1 - drivers/staging/rt2870/rt_linux.h | 1 - drivers/staging/rt2870/rt_main_dev.c | 1 - drivers/staging/rt2870/rt_profile.c | 1 - drivers/staging/rt2870/rt_usb.c | 1 - drivers/staging/rt2870/rtmp.h | 1 - drivers/staging/rt2870/rtmp_ckipmic.h | 1 - drivers/staging/rt2870/rtmp_def.h | 1 - drivers/staging/rt2870/rtmp_type.h | 1 - drivers/staging/rt2870/spectrum.h | 1 - drivers/staging/rt2870/spectrum_def.h | 1 - drivers/staging/rt2870/sta/aironet.c | 1 - drivers/staging/rt2870/sta/assoc.c | 1 - drivers/staging/rt2870/sta/auth.c | 1 - drivers/staging/rt2870/sta/auth_rsp.c | 1 - drivers/staging/rt2870/sta/connect.c | 1 - drivers/staging/rt2870/sta/rtmp_data.c | 1 - drivers/staging/rt2870/sta/sanity.c | 1 - drivers/staging/rt2870/sta/sync.c | 1 - drivers/staging/rt2870/sta/wpa.c | 1 - drivers/staging/rt2870/sta_ioctl.c | 1 - drivers/staging/rt2870/usb_main_dev.c | 1 - drivers/staging/rt2870/wpa.h | 1 - 163 files changed, 74159 deletions(-) delete mode 100644 drivers/staging/rt2860/Kconfig delete mode 100644 drivers/staging/rt2860/Makefile delete mode 100644 drivers/staging/rt2860/TODO delete mode 100644 drivers/staging/rt2860/ap.h delete mode 100644 drivers/staging/rt2860/chip/mac_pci.h delete mode 100644 drivers/staging/rt2860/chip/mac_usb.h delete mode 100644 drivers/staging/rt2860/chip/rt2860.h delete mode 100644 drivers/staging/rt2860/chip/rt2870.h delete mode 100644 drivers/staging/rt2860/chip/rt3070.h delete mode 100644 drivers/staging/rt2860/chip/rt3090.h delete mode 100644 drivers/staging/rt2860/chip/rt30xx.h delete mode 100644 drivers/staging/rt2860/chip/rtmp_mac.h delete mode 100644 drivers/staging/rt2860/chip/rtmp_phy.h delete mode 100644 drivers/staging/rt2860/chips/rt3070.c delete mode 100644 drivers/staging/rt2860/chips/rt3090.c delete mode 100644 drivers/staging/rt2860/chips/rt30xx.c delete mode 100644 drivers/staging/rt2860/chlist.h delete mode 100644 drivers/staging/rt2860/common/action.c delete mode 100644 drivers/staging/rt2860/common/action.h delete mode 100644 drivers/staging/rt2860/common/ba_action.c delete mode 100644 drivers/staging/rt2860/common/cmm_aes.c delete mode 100644 drivers/staging/rt2860/common/cmm_asic.c delete mode 100644 drivers/staging/rt2860/common/cmm_cfg.c delete mode 100644 drivers/staging/rt2860/common/cmm_data.c delete mode 100644 drivers/staging/rt2860/common/cmm_data_pci.c delete mode 100644 drivers/staging/rt2860/common/cmm_data_usb.c delete mode 100644 drivers/staging/rt2860/common/cmm_info.c delete mode 100644 drivers/staging/rt2860/common/cmm_mac_pci.c delete mode 100644 drivers/staging/rt2860/common/cmm_mac_usb.c delete mode 100644 drivers/staging/rt2860/common/cmm_sanity.c delete mode 100644 drivers/staging/rt2860/common/cmm_sync.c delete mode 100644 drivers/staging/rt2860/common/cmm_tkip.c delete mode 100644 drivers/staging/rt2860/common/cmm_wep.c delete mode 100644 drivers/staging/rt2860/common/cmm_wpa.c delete mode 100644 drivers/staging/rt2860/common/crypt_hmac.c delete mode 100644 drivers/staging/rt2860/common/crypt_md5.c delete mode 100644 drivers/staging/rt2860/common/crypt_sha2.c delete mode 100644 drivers/staging/rt2860/common/dfs.c delete mode 100644 drivers/staging/rt2860/common/ee_efuse.c delete mode 100644 drivers/staging/rt2860/common/ee_prom.c delete mode 100644 drivers/staging/rt2860/common/eeprom.c delete mode 100644 drivers/staging/rt2860/common/mlme.c delete mode 100644 drivers/staging/rt2860/common/rt_channel.c delete mode 100644 drivers/staging/rt2860/common/rt_rf.c delete mode 100644 drivers/staging/rt2860/common/rtmp_init.c delete mode 100644 drivers/staging/rt2860/common/rtmp_mcu.c delete mode 100644 drivers/staging/rt2860/common/rtmp_timer.c delete mode 100644 drivers/staging/rt2860/common/spectrum.c delete mode 100644 drivers/staging/rt2860/crypt_hmac.h delete mode 100644 drivers/staging/rt2860/crypt_md5.h delete mode 100644 drivers/staging/rt2860/crypt_sha2.h delete mode 100644 drivers/staging/rt2860/dfs.h delete mode 100644 drivers/staging/rt2860/eeprom.h delete mode 100644 drivers/staging/rt2860/iface/rtmp_pci.h delete mode 100644 drivers/staging/rt2860/iface/rtmp_usb.h delete mode 100644 drivers/staging/rt2860/mlme.h delete mode 100644 drivers/staging/rt2860/oid.h delete mode 100644 drivers/staging/rt2860/pci_main_dev.c delete mode 100644 drivers/staging/rt2860/rt_config.h delete mode 100644 drivers/staging/rt2860/rt_linux.c delete mode 100644 drivers/staging/rt2860/rt_linux.h delete mode 100644 drivers/staging/rt2860/rt_main_dev.c delete mode 100644 drivers/staging/rt2860/rt_pci_rbus.c delete mode 100644 drivers/staging/rt2860/rt_usb.c delete mode 100644 drivers/staging/rt2860/rtmp.h delete mode 100644 drivers/staging/rt2860/rtmp_chip.h delete mode 100644 drivers/staging/rt2860/rtmp_ckipmic.h delete mode 100644 drivers/staging/rt2860/rtmp_def.h delete mode 100644 drivers/staging/rt2860/rtmp_dot11.h delete mode 100644 drivers/staging/rt2860/rtmp_iface.h delete mode 100644 drivers/staging/rt2860/rtmp_mcu.h delete mode 100644 drivers/staging/rt2860/rtmp_os.h delete mode 100644 drivers/staging/rt2860/rtmp_timer.h delete mode 100644 drivers/staging/rt2860/rtmp_type.h delete mode 100644 drivers/staging/rt2860/rtusb_io.h delete mode 100644 drivers/staging/rt2860/spectrum.h delete mode 100644 drivers/staging/rt2860/spectrum_def.h delete mode 100644 drivers/staging/rt2860/sta/assoc.c delete mode 100644 drivers/staging/rt2860/sta/auth.c delete mode 100644 drivers/staging/rt2860/sta/auth_rsp.c delete mode 100644 drivers/staging/rt2860/sta/connect.c delete mode 100644 drivers/staging/rt2860/sta/rtmp_data.c delete mode 100644 drivers/staging/rt2860/sta/sanity.c delete mode 100644 drivers/staging/rt2860/sta/sync.c delete mode 100644 drivers/staging/rt2860/sta/wpa.c delete mode 100644 drivers/staging/rt2860/sta_ioctl.c delete mode 100644 drivers/staging/rt2860/usb_main_dev.c delete mode 100644 drivers/staging/rt2860/wpa.h delete mode 100644 drivers/staging/rt2870/Kconfig delete mode 100644 drivers/staging/rt2870/Makefile delete mode 100644 drivers/staging/rt2870/TODO delete mode 100644 drivers/staging/rt2870/aironet.h delete mode 100644 drivers/staging/rt2870/ap.h delete mode 100644 drivers/staging/rt2870/chips/rt3070.c delete mode 100644 drivers/staging/rt2870/chips/rt30xx.c delete mode 100644 drivers/staging/rt2870/chlist.h delete mode 100644 drivers/staging/rt2870/common/acction.c delete mode 100644 drivers/staging/rt2870/common/action.c delete mode 100644 drivers/staging/rt2870/common/action.h delete mode 100644 drivers/staging/rt2870/common/ba_action.c delete mode 100644 drivers/staging/rt2870/common/cmm_aes.c delete mode 100644 drivers/staging/rt2870/common/cmm_asic.c delete mode 100644 drivers/staging/rt2870/common/cmm_cfg.c delete mode 100644 drivers/staging/rt2870/common/cmm_data.c delete mode 100644 drivers/staging/rt2870/common/cmm_data_usb.c delete mode 100644 drivers/staging/rt2870/common/cmm_info.c delete mode 100644 drivers/staging/rt2870/common/cmm_mac_usb.c delete mode 100644 drivers/staging/rt2870/common/cmm_profile.c delete mode 100644 drivers/staging/rt2870/common/cmm_sanity.c delete mode 100644 drivers/staging/rt2870/common/cmm_sync.c delete mode 100644 drivers/staging/rt2870/common/cmm_tkip.c delete mode 100644 drivers/staging/rt2870/common/cmm_wep.c delete mode 100644 drivers/staging/rt2870/common/cmm_wpa.c delete mode 100644 drivers/staging/rt2870/common/crypt_hmac.c delete mode 100644 drivers/staging/rt2870/common/crypt_md5.c delete mode 100644 drivers/staging/rt2870/common/crypt_sha2.c delete mode 100644 drivers/staging/rt2870/common/dfs.c delete mode 100644 drivers/staging/rt2870/common/ee_efuse.c delete mode 100644 drivers/staging/rt2870/common/eeprom.c delete mode 100644 drivers/staging/rt2870/common/md5.c delete mode 100644 drivers/staging/rt2870/common/mlme.c delete mode 100644 drivers/staging/rt2870/common/rt_channel.c delete mode 100644 drivers/staging/rt2870/common/rt_rf.c delete mode 100644 drivers/staging/rt2870/common/rtmp_init.c delete mode 100644 drivers/staging/rt2870/common/rtmp_mcu.c delete mode 100644 drivers/staging/rt2870/common/rtmp_timer.c delete mode 100644 drivers/staging/rt2870/common/rtmp_tkip.c delete mode 100644 drivers/staging/rt2870/common/rtmp_wep.c delete mode 100644 drivers/staging/rt2870/common/rtusb_bulk.c delete mode 100644 drivers/staging/rt2870/common/rtusb_data.c delete mode 100644 drivers/staging/rt2870/common/rtusb_io.c delete mode 100644 drivers/staging/rt2870/common/spectrum.c delete mode 100644 drivers/staging/rt2870/dfs.h delete mode 100644 drivers/staging/rt2870/md5.h delete mode 100644 drivers/staging/rt2870/mlme.h delete mode 100644 drivers/staging/rt2870/oid.h delete mode 100644 drivers/staging/rt2870/rt28xx.h delete mode 100644 drivers/staging/rt2870/rt_config.h delete mode 100644 drivers/staging/rt2870/rt_linux.c delete mode 100644 drivers/staging/rt2870/rt_linux.h delete mode 100644 drivers/staging/rt2870/rt_main_dev.c delete mode 100644 drivers/staging/rt2870/rt_profile.c delete mode 100644 drivers/staging/rt2870/rt_usb.c delete mode 100644 drivers/staging/rt2870/rtmp.h delete mode 100644 drivers/staging/rt2870/rtmp_ckipmic.h delete mode 100644 drivers/staging/rt2870/rtmp_def.h delete mode 100644 drivers/staging/rt2870/rtmp_type.h delete mode 100644 drivers/staging/rt2870/spectrum.h delete mode 100644 drivers/staging/rt2870/spectrum_def.h delete mode 100644 drivers/staging/rt2870/sta/aironet.c delete mode 100644 drivers/staging/rt2870/sta/assoc.c delete mode 100644 drivers/staging/rt2870/sta/auth.c delete mode 100644 drivers/staging/rt2870/sta/auth_rsp.c delete mode 100644 drivers/staging/rt2870/sta/connect.c delete mode 100644 drivers/staging/rt2870/sta/rtmp_data.c delete mode 100644 drivers/staging/rt2870/sta/sanity.c delete mode 100644 drivers/staging/rt2870/sta/sync.c delete mode 100644 drivers/staging/rt2870/sta/wpa.c delete mode 100644 drivers/staging/rt2870/sta_ioctl.c delete mode 100644 drivers/staging/rt2870/usb_main_dev.c delete mode 100644 drivers/staging/rt2870/wpa.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index dca4a0bb6ca9..e9254f509e85 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -67,10 +67,6 @@ source "drivers/staging/echo/Kconfig" source "drivers/staging/brcm80211/Kconfig" -source "drivers/staging/rt2860/Kconfig" - -source "drivers/staging/rt2870/Kconfig" - source "drivers/staging/comedi/Kconfig" source "drivers/staging/olpc_dcon/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index eb93012b6f59..dc642ab5974e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -17,8 +17,6 @@ obj-$(CONFIG_W35UND) += winbond/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_ECHO) += echo/ obj-$(CONFIG_BRCM80211) += brcm80211/ -obj-$(CONFIG_RT2860) += rt2860/ -obj-$(CONFIG_RT2870) += rt2870/ obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_ASUS_OLED) += asus_oled/ diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig deleted file mode 100644 index f3a7e47df5e9..000000000000 --- a/drivers/staging/rt2860/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config RT2860 - tristate "Ralink 2860/3090 wireless support" - depends on PCI && X86 && WLAN - select WIRELESS_EXT - select WEXT_PRIV - select CRC_CCITT - select FW_LOADER - ---help--- - This is an experimental driver for the Ralink 2860 and 3090 - wireless chips. diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile deleted file mode 100644 index 6dd0aa5d0791..000000000000 --- a/drivers/staging/rt2860/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -obj-$(CONFIG_RT2860) += rt2860sta.o - -# TODO: all of these should be removed -ccflags-y := -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -ccflags-y += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860 -ccflags-y += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3090 -ccflags-y += -DDBG - -rt2860sta-y := \ - common/crypt_md5.o \ - common/crypt_sha2.o \ - common/crypt_hmac.o \ - common/mlme.o \ - common/cmm_wep.o \ - common/action.o \ - common/cmm_data.o \ - common/rtmp_init.o \ - common/cmm_tkip.o \ - common/cmm_aes.o \ - common/cmm_sync.o \ - common/eeprom.o \ - common/cmm_sanity.o \ - common/cmm_info.o \ - common/cmm_cfg.o \ - common/cmm_wpa.o \ - common/dfs.o \ - common/spectrum.o \ - common/rtmp_timer.o \ - common/rt_channel.o \ - common/cmm_asic.o \ - sta/assoc.o \ - sta/auth.o \ - sta/auth_rsp.o \ - sta/sync.o \ - sta/sanity.o \ - sta/rtmp_data.o \ - sta/connect.o \ - sta/wpa.o \ - rt_linux.o \ - rt_main_dev.o \ - sta_ioctl.o \ - common/ba_action.o \ - pci_main_dev.o \ - rt_pci_rbus.o \ - common/cmm_mac_pci.o \ - common/cmm_data_pci.o \ - common/ee_prom.o \ - common/rtmp_mcu.o \ - common/ee_efuse.o \ - chips/rt30xx.o \ - common/rt_rf.o \ - chips/rt3090.o diff --git a/drivers/staging/rt2860/TODO b/drivers/staging/rt2860/TODO deleted file mode 100644 index 8e2f6ee0a2be..000000000000 --- a/drivers/staging/rt2860/TODO +++ /dev/null @@ -1,16 +0,0 @@ -I'm hesitant to add a TODO file here, as the wireless developers would -really have people help them out on the "clean" rt2860 driver that can -be found at the http://rt2x00.serialmonkey.com/ site. - -But, if you wish to clean up this driver instead, here's a short list of -things that need to be done to get it into a more mergable shape: - -TODO: - - checkpatch.pl clean - - sparse clean - - port to in-kernel 80211 stack and common rt2x00 infrastructure - - review by the wireless developer community - -Please send any patches or complaints about this driver to Greg -Kroah-Hartman and don't bother the upstream wireless -kernel developers about it, they want nothing to do with it. diff --git a/drivers/staging/rt2860/ap.h b/drivers/staging/rt2860/ap.h deleted file mode 100644 index 2737c0c022f9..000000000000 --- a/drivers/staging/rt2860/ap.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - -Module Name: -ap.h - -Abstract: -Miniport generic portion header file - -Revision History: -Who When What --------- ---------- ---------------------------------------------- -Paul Lin 08-01-2002 created -James Tan 09-06-2002 modified (Revise NTCRegTable) -John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver -*/ -#ifndef __AP_H__ -#define __AP_H__ - -/* ap_wpa.c */ -void WpaStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, - OUT STATE_MACHINE_FUNC Trans[]); - -#ifdef RTMP_MAC_USB -void BeaconUpdateExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); -#endif /* RTMP_MAC_USB // */ - -void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack); - -void MacTableReset(struct rt_rtmp_adapter *pAd); - -struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd, - u8 *pAddr, - u8 apidx, IN BOOLEAN CleanAll); - -BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd, - u16 wcid, u8 *pAddr); - -struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, - u8 *pAddr); - -#endif /* __AP_H__ */ diff --git a/drivers/staging/rt2860/chip/mac_pci.h b/drivers/staging/rt2860/chip/mac_pci.h deleted file mode 100644 index b8868a5b9e04..000000000000 --- a/drivers/staging/rt2860/chip/mac_pci.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - mac_pci.h - - Abstract: - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix some typos - --------- ---------- ---------------------------------------------- - */ - -#ifndef __MAC_PCI_H__ -#define __MAC_PCI_H__ - -#include "../rtmp_type.h" -#include "rtmp_mac.h" -#include "rtmp_phy.h" -#include "../rtmp_iface.h" -#include "../rtmp_dot11.h" - -/* */ -/* Device ID & Vendor ID related definitions, */ -/* NOTE: you should not add the new VendorID/DeviceID here unless you know for sure what chip it belongs too. */ -/* */ -#define NIC_PCI_VENDOR_ID 0x1814 -#define PCIBUS_INTEL_VENDOR 0x8086 - -#if !defined(PCI_CAP_ID_EXP) -#define PCI_CAP_ID_EXP 0x10 -#endif -#if !defined(PCI_EXP_LNKCTL) -#define PCI_EXP_LNKCTL 0x10 -#endif -#if !defined(PCI_CLASS_BRIDGE_PCI) -#define PCI_CLASS_BRIDGE_PCI 0x0604 -#endif - -#define TXINFO_SIZE 0 -#define RTMP_PKT_TAIL_PADDING 0 -#define fRTMP_ADAPTER_NEED_STOP_TX 0 - -#define AUX_CTRL 0x10c - -/* */ -/* TX descriptor format, Tx ring, Mgmt Ring */ -/* */ -struct PACKED rt_txd { - /* Word 0 */ - u32 SDPtr0; - /* Word 1 */ - u32 SDLen1:14; - u32 LastSec1:1; - u32 Burst:1; - u32 SDLen0:14; - u32 LastSec0:1; - u32 DMADONE:1; - /*Word2 */ - u32 SDPtr1; - /*Word3 */ - u32 rsv2:24; - u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correct position */ - u32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */ - u32 rsv:2; - u32 TCO:1; /* */ - u32 UCO:1; /* */ - u32 ICO:1; /* */ -}; - -/* */ -/* Rx descriptor format, Rx Ring */ -/* */ -typedef struct PACKED rt_rxd { - /* Word 0 */ - u32 SDP0; - /* Word 1 */ - u32 SDL1:14; - u32 Rsv:2; - u32 SDL0:14; - u32 LS0:1; - u32 DDONE:1; - /* Word 2 */ - u32 SDP1; - /* Word 3 */ - u32 BA:1; - u32 DATA:1; - u32 NULLDATA:1; - u32 FRAG:1; - u32 U2M:1; /* 1: this RX frame is unicast to me */ - u32 Mcast:1; /* 1: this is a multicast frame */ - u32 Bcast:1; /* 1: this is a broadcast frame */ - u32 MyBss:1; /* 1: this frame belongs to the same BSSID */ - u32 Crc:1; /* 1: CRC error */ - u32 CipherErr:2; /* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */ - u32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. */ - u32 HTC:1; - u32 RSSI:1; - u32 L2PAD:1; - u32 AMPDU:1; - u32 Decrypted:1; /* this frame is being decrypted. */ - u32 PlcpSignal:1; /* To be moved */ - u32 PlcpRssil:1; /* To be moved */ - u32 Rsv1:13; -} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; - -typedef union _TX_ATTENUATION_CTRL_STRUC { - struct { - unsigned long RF_ISOLATION_ENABLE:1; - unsigned long Reserve2:7; - unsigned long PCIE_PHY_TX_ATTEN_VALUE:3; - unsigned long PCIE_PHY_TX_ATTEN_EN:1; - unsigned long Reserve1:20; - } field; - - unsigned long word; -} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC; - -/* ----------------- EEPROM Related MACRO ----------------- */ - -/* 8051 firmware image for RT2860 - base address = 0x4000 */ -#define FIRMWARE_IMAGE_BASE 0x2000 -#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 /* 8kbyte */ - -/* ----------------- Frimware Related MACRO ----------------- */ -#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ - do { \ - unsigned long _i, _firm; \ - RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \ - \ - for (_i = 0; _i < _FwLen; _i += 4) { \ - _firm = _pFwImage[_i] + \ - (_pFwImage[_i+3] << 24) + \ - (_pFwImage[_i+2] << 16) + \ - (_pFwImage[_i+1] << 8); \ - RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm); \ - } \ - RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000); \ - RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001); \ - \ - /* initialize BBP R/W access agent */ \ - RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \ - RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \ - } while (0) - -/* ----------------- TX Related MACRO ----------------- */ -#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) do {} while (0) -#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do {} while (0) - -#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ - ((freeNum) >= (unsigned long)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */ -#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) do {} while (0) - -#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \ - (((freeNum != (TX_RING_SIZE-1)) && \ - (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum < 3)) - -#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \ - RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) - -#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - /* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) */ - -#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) - -#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ - RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) - -#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) \ - RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) - -#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \ - RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) - -#define HAL_LastTxIdx(_pAd, _QueIdx, _LastTxIdx) \ - /*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx) */ - -#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \ - RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx) -/* RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/ - -#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ - MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen) - -#define GET_TXRING_FREENO(_pAd, _QueIdx) \ - (_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx) ? \ - (_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \ - : \ - (_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1); - -#define GET_MGMTRING_FREENO(_pAd) \ - (_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \ - (_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \ - : \ - (_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1); - -/* ----------------- RX Related MACRO ----------------- */ - -/* ----------------- ASIC Related MACRO ----------------- */ -/* reset MAC of a station entry to 0x000000000000 */ -#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \ - AsicDelWcidTab(pAd, Wcid); - -/* add this entry into ASIC RX WCID search table */ -#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \ - AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr); - -/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ -/* Set MAC register value according operation mode */ -#define RTMP_UPDATE_PROTECT(pAd) \ - AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0); -/* end johnli */ - -/* remove Pair-wise key material from ASIC */ -#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) \ - AsicRemovePairwiseKeyEntry(pAd, BssIdx, (u8)Wcid); - -/* add Client security information into ASIC WCID table and IVEIV table */ -#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \ - RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \ - pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry); - -#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry) \ - { /* update pairwise key information to ASIC Shared Key Table */ \ - AsicAddSharedKeyEntry(pAd, apidx, KeyID, \ - pAd->SharedKey[apidx][KeyID].CipherAlg, \ - pAd->SharedKey[apidx][KeyID].Key, \ - pAd->SharedKey[apidx][KeyID].TxMic, \ - pAd->SharedKey[apidx][KeyID].RxMic); \ - /* update ASIC WCID attribute table and IVEIV table */ \ - RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \ - pAd->SharedKey[apidx][KeyID].CipherAlg, \ - pEntry); } - -/* Insert the BA bitmap to ASIC for the Wcid entry */ -#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ - do { \ - u32 _Value = 0, _Offset; \ - _Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \ - RTMP_IO_READ32((_pAd), _Offset, &_Value);\ - _Value |= (0x10000<<(_TID)); \ - RTMP_IO_WRITE32((_pAd), _Offset, _Value);\ - } while (0) - -/* Remove the BA bitmap from ASIC for the Wcid entry */ -/* bitmap field starts at 0x10000 in ASIC WCID table */ -#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ - do { \ - u32 _Value = 0, _Offset; \ - _Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \ - RTMP_IO_READ32((_pAd), _Offset, &_Value); \ - _Value &= (~(0x10000 << (_TID))); \ - RTMP_IO_WRITE32((_pAd), _Offset, _Value); \ - } while (0) - -/* ----------------- Interface Related MACRO ----------------- */ - -/* */ -/* Enable & Disable NIC interrupt via writing interrupt mask register */ -/* Since it use ADAPTER structure, it have to be put after structure definition. */ -/* */ -#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd) \ - do { \ - RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0); /* 0: disable */ \ - RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \ - } while (0) - -#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\ - do { \ - RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/); /* 1:enable */ \ - RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \ - } while (0) - -#define RTMP_IRQ_INIT(pAd) \ - { pAd->int_enable_reg = ((DELAYINTMASK) | \ - (RxINT|TxDataInt|TxMgmtInt)) & ~(0x03); \ - pAd->int_disable_mask = 0; \ - pAd->int_pending = 0; } - -#define RTMP_IRQ_ENABLE(pAd) \ - { /* clear garbage ints */ \ - RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\ - RTMP_ASIC_INTERRUPT_ENABLE(pAd); } - -/* ----------------- MLME Related MACRO ----------------- */ -#define RTMP_MLME_HANDLER(pAd) MlmeHandler(pAd) - -#define RTMP_MLME_PRE_SANITY_CHECK(pAd) - -#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ - RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); - -#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \ - MlmeRestartStateMachine(pAd) - -#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\ - HandleCounterMeasure(_pAd, _pEntry) - -/* ----------------- Power Save Related MACRO ----------------- */ -#define RTMP_PS_POLL_ENQUEUE(pAd) EnqueuePsPoll(pAd) - -/* For RTMPPCIePowerLinkCtrlRestore () function */ -#define RESTORE_HALT 1 -#define RESTORE_WAKEUP 2 -#define RESTORE_CLOSE 3 - -#define PowerSafeCID 1 -#define PowerRadioOffCID 2 -#define PowerWakeCID 3 -#define CID0MASK 0x000000ff -#define CID1MASK 0x0000ff00 -#define CID2MASK 0x00ff0000 -#define CID3MASK 0xff000000 - -#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \ - RT28xxPciStaAsicForceWakeup(pAd, bFromTx); - -#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ - RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); - -#define RTMP_SET_PSM_BIT(_pAd, _val) \ - MlmeSetPsmBit(_pAd, _val); - -#define RTMP_MLME_RADIO_ON(pAd) \ - RT28xxPciMlmeRadioOn(pAd); - -#define RTMP_MLME_RADIO_OFF(pAd) \ - RT28xxPciMlmeRadioOFF(pAd); - -#endif /*__MAC_PCI_H__ // */ diff --git a/drivers/staging/rt2860/chip/mac_usb.h b/drivers/staging/rt2860/chip/mac_usb.h deleted file mode 100644 index e8158fb58648..000000000000 --- a/drivers/staging/rt2860/chip/mac_usb.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - mac_usb.h - - Abstract: - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix a typo - --------- ---------- ---------------------------------------------- - */ - -#ifndef __MAC_USB_H__ -#define __MAC_USB_H__ - -#include "../rtmp_type.h" -#include "rtmp_mac.h" -#include "rtmp_phy.h" -#include "../rtmp_iface.h" -#include "../rtmp_dot11.h" - -#define USB_CYC_CFG 0x02a4 - -#define BEACON_RING_SIZE 2 -#define MGMTPIPEIDX 0 /* EP6 is highest priority */ - -#define RTMP_PKT_TAIL_PADDING 11 /* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */ - -#define fRTMP_ADAPTER_NEED_STOP_TX \ - (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ - fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \ - fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS) - -/* */ -/* RXINFO appends at the end of each rx packet. */ -/* */ -#define RXINFO_SIZE 4 -#define RT2870_RXDMALEN_FIELD_SIZE 4 - -typedef struct PACKED rt_rxinfo { - u32 BA:1; - u32 DATA:1; - u32 NULLDATA:1; - u32 FRAG:1; - u32 U2M:1; /* 1: this RX frame is unicast to me */ - u32 Mcast:1; /* 1: this is a multicast frame */ - u32 Bcast:1; /* 1: this is a broadcast frame */ - u32 MyBss:1; /* 1: this frame belongs to the same BSSID */ - u32 Crc:1; /* 1: CRC error */ - u32 CipherErr:2; /* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */ - u32 AMSDU:1; /* rx with 802.3 header, not 802.11 header. */ - u32 HTC:1; - u32 RSSI:1; - u32 L2PAD:1; - u32 AMPDU:1; /* To be moved */ - u32 Decrypted:1; - u32 PlcpRssil:1; - u32 CipherAlg:1; - u32 LastAMSDU:1; - u32 PlcpSignal:12; -} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; - -/* */ -/* TXINFO */ -/* */ -#define TXINFO_SIZE 4 - -struct rt_txinfo { - /* Word 0 */ - u32 USBDMATxPktLen:16; /*used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. */ - u32 rsv:8; - u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correct position */ - u32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */ - u32 SwUseLastRound:1; /* Software use. */ - u32 rsv2:2; /* Software use. */ - u32 USBDMANextVLD:1; /*used ONLY in USB bulk Aggregation, NextValid */ - u32 USBDMATxburst:1; /*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */ -}; - -/* */ -/* Management ring buffer format */ -/* */ -struct rt_mgmt { - BOOLEAN Valid; - u8 *pBuffer; - unsigned long Length; -}; - -/*////////////////////////////////////////////////////////////////////////// */ -/* The struct rt_tx_buffer structure forms the transmitted USB packet to the device */ -/*////////////////////////////////////////////////////////////////////////// */ -struct rt_tx_buffer { - union { - u8 WirelessPacket[TX_BUFFER_NORMSIZE]; - struct rt_header_802_11 NullFrame; - struct rt_pspoll_frame PsPollPacket; - struct rt_rts_frame RTSFrame; - } field; - u8 Aggregation[4]; /*Buffer for save Aggregation size. */ -}; - -struct rt_httx_buffer { - union { - u8 WirelessPacket[MAX_TXBULK_SIZE]; - struct rt_header_802_11 NullFrame; - struct rt_pspoll_frame PsPollPacket; - struct rt_rts_frame RTSFrame; - } field; - u8 Aggregation[4]; /*Buffer for save Aggregation size. */ -}; - -/* used to track driver-generated write irps */ -struct rt_tx_context { - void *pAd; /*Initialized in MiniportInitialize */ - PURB pUrb; /*Initialized in MiniportInitialize */ - PIRP pIrp; /*used to cancel pending bulk out. */ - /*Initialized in MiniportInitialize */ - struct rt_tx_buffer *TransferBuffer; /*Initialized in MiniportInitialize */ - unsigned long BulkOutSize; - u8 BulkOutPipeId; - u8 SelfIdx; - BOOLEAN InUse; - BOOLEAN bWaitingBulkOut; /* at least one packet is in this TxContext, ready for making IRP anytime. */ - BOOLEAN bFullForBulkOut; /* all tx buffer are full , so waiting for tx bulkout. */ - BOOLEAN IRPPending; - BOOLEAN LastOne; - BOOLEAN bAggregatible; - u8 Header_802_3[LENGTH_802_3]; - u8 Rsv[2]; - unsigned long DataOffset; - u32 TxRate; - dma_addr_t data_dma; /* urb dma on linux */ - -}; - -/* used to track driver-generated write irps */ -struct rt_ht_tx_context { - void *pAd; /*Initialized in MiniportInitialize */ - PURB pUrb; /*Initialized in MiniportInitialize */ - PIRP pIrp; /*used to cancel pending bulk out. */ - /*Initialized in MiniportInitialize */ - struct rt_httx_buffer *TransferBuffer; /*Initialized in MiniportInitialize */ - unsigned long BulkOutSize; /* Indicate the total bulk-out size in bytes in one bulk-transmission */ - u8 BulkOutPipeId; - BOOLEAN IRPPending; - BOOLEAN LastOne; - BOOLEAN bCurWriting; - BOOLEAN bRingEmpty; - BOOLEAN bCopySavePad; - u8 SavedPad[8]; - u8 Header_802_3[LENGTH_802_3]; - unsigned long CurWritePosition; /* Indicate the buffer offset which packet will be inserted start from. */ - unsigned long CurWriteRealPos; /* Indicate the buffer offset which packet now are writing to. */ - unsigned long NextBulkOutPosition; /* Indicate the buffer start offset of a bulk-transmission */ - unsigned long ENextBulkOutPosition; /* Indicate the buffer end offset of a bulk-transmission */ - u32 TxRate; - dma_addr_t data_dma; /* urb dma on linux */ -}; - -/* */ -/* Structure to keep track of receive packets and buffers to indicate */ -/* receive data to the protocol. */ -/* */ -struct rt_rx_context { - u8 *TransferBuffer; - void *pAd; - PIRP pIrp; /*used to cancel pending bulk in. */ - PURB pUrb; - /*These 2 Boolean shouldn't both be 1 at the same time. */ - unsigned long BulkInOffset; /* number of packets waiting for reordering . */ -/* BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication */ - BOOLEAN bRxHandling; /* Notify this packet is being process now. */ - BOOLEAN InUse; /* USB Hardware Occupied. Wait for USB HW to put packet. */ - BOOLEAN Readable; /* Receive Complete back. OK for driver to indicate receiving packet. */ - BOOLEAN IRPPending; /* TODO: To be removed */ - atomic_t IrpLock; - spinlock_t RxContextLock; - dma_addr_t data_dma; /* urb dma on linux */ -}; - -/****************************************************************************** - - USB Frimware Related MACRO - -******************************************************************************/ -/* 8051 firmware image for usb - use last-half base address = 0x3000 */ -#define FIRMWARE_IMAGE_BASE 0x3000 -#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 /* 4kbyte */ - -#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ - RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen) - -/****************************************************************************** - - USB TX Related MACRO - -******************************************************************************/ -#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) \ - do { \ - RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - if (pAd->DeQueueRunning[QueIdx]) { \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx)); \ - continue; \ - } else { \ - pAd->DeQueueRunning[QueIdx] = TRUE; \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ - } \ - } while (0) - -#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \ - do { \ - RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - pAd->DeQueueRunning[QueIdx] = FALSE; \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - } while (0) - -#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ - (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS) - -#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ - do {} while (0) - -#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \ - ((_TxFrameType == TX_RALINK_FRAME) && \ - (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx))) - -#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) - -#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - RtmpUSB_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) - -#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ - RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) - -#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) \ - RtmpUSB_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) - -#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \ - RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) - -#define HAL_LastTxIdx(pAd, QueIdx, TxIdx) \ - /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx) */ - -#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \ - RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx) - -#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \ - RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) - -#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ - RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen) - -#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) /*(_pAd->TxRing[_QueIdx].TxSwFreeIdx) */ -#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx) - -/* ----------------- RX Related MACRO ----------------- */ - -/* - * Device Hardware Interface Related MACRO - */ -#define RTMP_IRQ_INIT(pAd) do {} while (0) -#define RTMP_IRQ_ENABLE(pAd) do {} while (0) - -/* - * MLME Related MACRO - */ -#define RTMP_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd) - -#define RTMP_MLME_PRE_SANITY_CHECK(pAd) \ - { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \ - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \ - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } } - -#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ - { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \ - RTUSBMlmeUp(pAd); } - -#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \ - { MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \ - RTUSBMlmeUp(pAd); } - -#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \ - { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(struct rt_mac_table_entry)); \ - RTUSBMlmeUp(_pAd); \ - } - -/* - * Power Save Related MACRO - */ -#define RTMP_PS_POLL_ENQUEUE(pAd) \ - { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \ - RTUSBKickBulkOut(pAd); } - -#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \ - RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx); - -#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ - RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); - -#define RTMP_SET_PSM_BIT(_pAd, _val) \ - {\ - if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \ - MlmeSetPsmBit(_pAd, _val);\ - else { \ - u16 _psm_val; \ - _psm_val = _val; \ - RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(u16)); \ - } \ - } - -#define RTMP_MLME_RADIO_ON(pAd) \ - RT28xxUsbMlmeRadioOn(pAd); - -#define RTMP_MLME_RADIO_OFF(pAd) \ - RT28xxUsbMlmeRadioOFF(pAd); - -#endif /*__MAC_USB_H__ // */ diff --git a/drivers/staging/rt2860/chip/rt2860.h b/drivers/staging/rt2860/chip/rt2860.h deleted file mode 100644 index f30b80820b92..000000000000 --- a/drivers/staging/rt2860/chip/rt2860.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -#ifndef __RT2860_H__ -#define __RT2860_H__ - -#include "mac_pci.h" - -#ifndef RTMP_PCI_SUPPORT -#error "For RT2860, you should define the compile flag -DRTMP_PCI_SUPPORT" -#endif - -#ifndef RTMP_MAC_PCI -#error "For RT2880, you should define the compile flag -DRTMP_MAC_PCI" -#endif - -/* */ -/* Device ID & Vendor ID, these values should match EEPROM value */ -/* */ -#define NIC2860_PCI_DEVICE_ID 0x0601 -#define NIC2860_PCIe_DEVICE_ID 0x0681 -#define NIC2760_PCI_DEVICE_ID 0x0701 /* 1T/2R Cardbus ??? */ -#define NIC2790_PCIe_DEVICE_ID 0x0781 /* 1T/2R miniCard */ - -#define VEN_AWT_PCIe_DEVICE_ID 0x1059 -#define VEN_AWT_PCI_VENDOR_ID 0x1A3B - -#define EDIMAX_PCI_VENDOR_ID 0x1432 - -#endif /*__RT2860_H__ // */ diff --git a/drivers/staging/rt2860/chip/rt2870.h b/drivers/staging/rt2860/chip/rt2870.h deleted file mode 100644 index 8263f1baefae..000000000000 --- a/drivers/staging/rt2860/chip/rt2870.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ -#ifndef __RT2870_H__ -#define __RT2870_H__ - -#ifdef RT2870 - -#ifndef RTMP_USB_SUPPORT -#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT" -#endif - -#ifndef RTMP_MAC_USB -#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB" -#endif - -#include "../rtmp_type.h" -#include "mac_usb.h" - -/*#define RTMP_CHIP_NAME "RT2870" */ - -#endif /* RT2870 // */ -#endif /*__RT2870_H__ // */ diff --git a/drivers/staging/rt2860/chip/rt3070.h b/drivers/staging/rt2860/chip/rt3070.h deleted file mode 100644 index 172ce7054233..000000000000 --- a/drivers/staging/rt2860/chip/rt3070.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt3070.h - - Abstract: - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - */ - -#ifndef __RT3070_H__ -#define __RT3070_H__ - -#ifdef RT3070 - -#ifndef RTMP_USB_SUPPORT -#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT" -#endif - -#ifndef RTMP_MAC_USB -#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB" -#endif - -#ifndef RTMP_RF_RW_SUPPORT -#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT" -#endif - -#ifndef RT30xx -#error "For RT3070, you should define the compile flag -DRT30xx" -#endif - -#include "mac_usb.h" -#include "rt30xx.h" - -/* */ -/* Device ID & Vendor ID, these values should match EEPROM value */ -/* */ - -#endif /* RT3070 // */ - -#endif /*__RT3070_H__ // */ diff --git a/drivers/staging/rt2860/chip/rt3090.h b/drivers/staging/rt2860/chip/rt3090.h deleted file mode 100644 index 102b938e74bd..000000000000 --- a/drivers/staging/rt2860/chip/rt3090.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt3090.h - - Abstract: - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - */ - -#ifndef __RT3090_H__ -#define __RT3090_H__ - -#ifdef RT3090 - -#ifndef RTMP_PCI_SUPPORT -#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT" -#endif - -#ifndef RTMP_MAC_PCI -#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI" -#endif - -#ifndef RTMP_RF_RW_SUPPORT -#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT" -#endif - -#ifndef RT30xx -#error "For RT3090, you should define the compile flag -DRT30xx" -#endif - -#define PCIE_PS_SUPPORT - -#include "mac_pci.h" -#include "rt30xx.h" - -/* */ -/* Device ID & Vendor ID, these values should match EEPROM value */ -/* */ -#define NIC3090_PCIe_DEVICE_ID 0x3090 /* 1T/1R miniCard */ -#define NIC3091_PCIe_DEVICE_ID 0x3091 /* 1T/2R miniCard */ -#define NIC3092_PCIe_DEVICE_ID 0x3092 /* 2T/2R miniCard */ - -#endif /* RT3090 // */ - -#endif /*__RT3090_H__ // */ diff --git a/drivers/staging/rt2860/chip/rt30xx.h b/drivers/staging/rt2860/chip/rt30xx.h deleted file mode 100644 index 02e1d728fb41..000000000000 --- a/drivers/staging/rt2860/chip/rt30xx.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt30xx.h - - Abstract: - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - */ - -#ifndef __RT30XX_H__ -#define __RT30XX_H__ - -#ifdef RT30xx - -extern struct rt_reg_pair RT30xx_RFRegTable[]; -extern u8 NUM_RF_REG_PARMS; - -#endif /* RT30xx // */ - -#endif /*__RT30XX_H__ // */ diff --git a/drivers/staging/rt2860/chip/rtmp_mac.h b/drivers/staging/rt2860/chip/rtmp_mac.h deleted file mode 100644 index 3d1e4915b956..000000000000 --- a/drivers/staging/rt2860/chip/rtmp_mac.h +++ /dev/null @@ -1,1308 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_mac.h - - Abstract: - Ralink Wireless Chip MAC related definition & structures - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix a comments, and typos - -------- ---------- ---------------------------------------------- -*/ - -#ifndef __RTMP_MAC_H__ -#define __RTMP_MAC_H__ - -/* ================================================================================= */ -/* TX / RX ring descriptor format */ -/* ================================================================================= */ - -/* the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. */ -/* MAC block uses this TXINFO to control the transmission behavior of this frame. */ -#define FIFO_MGMT 0 -#define FIFO_HCCA 1 -#define FIFO_EDCA 2 - -/* */ -/* TXD Wireless Information format for Tx ring and Mgmt Ring */ -/* */ -/*txop : for txop mode */ -/* 0:txop for the MPDU frame will be handles by ASIC by register */ -/* 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS */ -struct PACKED rt_txwi { - /* Word 0 */ - /* ex: 00 03 00 40 means txop = 3, PHYMODE = 1 */ - u32 FRAG:1; /* 1 to inform TKIP engine this is a fragment. */ - u32 MIMOps:1; /* the remote peer is in dynamic MIMO-PS mode */ - u32 CFACK:1; - u32 TS:1; - - u32 AMPDU:1; - u32 MpduDensity:3; - u32 txop:2; /*FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. */ - u32 rsv:6; - - u32 MCS:7; - u32 BW:1; /*channel bandwidth 20MHz or 40 MHz */ - u32 ShortGI:1; - u32 STBC:2; /* 1: STBC support MCS =0-7, 2,3 : RESERVE */ - u32 Ifs:1; /* */ -/* u32 rsv2:2; //channel bandwidth 20MHz or 40 MHz */ - u32 rsv2:1; - u32 TxBF:1; /* 3*3 */ - u32 PHYMODE:2; - /* Word1 */ - /* ex: 1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38 */ - u32 ACK:1; - u32 NSEQ:1; - u32 BAWinSize:6; - u32 WirelessCliID:8; - u32 MPDUtotalByteCount:12; - u32 PacketId:4; - /*Word2 */ - u32 IV; - /*Word3 */ - u32 EIV; -}; - -/* */ -/* RXWI wireless information format, in PBF. invisible in driver. */ -/* */ -struct PACKED rt_rxwi { - /* Word 0 */ - u32 WirelessCliID:8; - u32 KeyIndex:2; - u32 BSSID:3; - u32 UDF:3; - u32 MPDUtotalByteCount:12; - u32 TID:4; - /* Word 1 */ - u32 FRAG:4; - u32 SEQUENCE:12; - u32 MCS:7; - u32 BW:1; - u32 ShortGI:1; - u32 STBC:2; - u32 rsv:3; - u32 PHYMODE:2; /* 1: this RX frame is unicast to me */ - /*Word2 */ - u32 RSSI0:8; - u32 RSSI1:8; - u32 RSSI2:8; - u32 rsv1:8; - /*Word3 */ - u32 SNR0:8; - u32 SNR1:8; - u32 FOFFSET:8; /* RT35xx */ - u32 rsv2:8; - /*u32 rsv2:16; */ -}; - -/* ================================================================================= */ -/* Register format */ -/* ================================================================================= */ - -/* */ -/* SCH/DMA registers - base address 0x0200 */ -/* */ -/* INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit */ -/* */ -#define DMA_CSR0 0x200 -#define INT_SOURCE_CSR 0x200 -typedef union _INT_SOURCE_CSR_STRUC { - struct { - u32 RxDelayINT:1; - u32 TxDelayINT:1; - u32 RxDone:1; - u32 Ac0DmaDone:1; /*4 */ - u32 Ac1DmaDone:1; - u32 Ac2DmaDone:1; - u32 Ac3DmaDone:1; - u32 HccaDmaDone:1; /* bit7 */ - u32 MgmtDmaDone:1; - u32 MCUCommandINT:1; /*bit 9 */ - u32 RxTxCoherent:1; - u32 TBTTInt:1; - u32 PreTBTT:1; - u32 TXFifoStatusInt:1; /*FIFO Statistics is full, sw should read 0x171c */ - u32 AutoWakeup:1; /*bit14 */ - u32 GPTimer:1; - u32 RxCoherent:1; /*bit16 */ - u32 TxCoherent:1; - u32: 14; - } field; - u32 word; -} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC; - -/* */ -/* INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF */ -/* */ -#define INT_MASK_CSR 0x204 -typedef union _INT_MASK_CSR_STRUC { - struct { - u32 RXDelay_INT_MSK:1; - u32 TxDelay:1; - u32 RxDone:1; - u32 Ac0DmaDone:1; - u32 Ac1DmaDone:1; - u32 Ac2DmaDone:1; - u32 Ac3DmaDone:1; - u32 HccaDmaDone:1; - u32 MgmtDmaDone:1; - u32 MCUCommandINT:1; - u32: 20; - u32 RxCoherent:1; - u32 TxCoherent:1; - } field; - u32 word; -} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC; - -#define WPDMA_GLO_CFG 0x208 -typedef union _WPDMA_GLO_CFG_STRUC { - struct { - u32 EnableTxDMA:1; - u32 TxDMABusy:1; - u32 EnableRxDMA:1; - u32 RxDMABusy:1; - u32 WPDMABurstSIZE:2; - u32 EnTXWriteBackDDONE:1; - u32 BigEndian:1; - u32 RXHdrScater:8; - u32 HDR_SEG_LEN:16; - } field; - u32 word; -} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC; - -#define WPDMA_RST_IDX 0x20c -typedef union _WPDMA_RST_IDX_STRUC { - struct { - u32 RST_DTX_IDX0:1; - u32 RST_DTX_IDX1:1; - u32 RST_DTX_IDX2:1; - u32 RST_DTX_IDX3:1; - u32 RST_DTX_IDX4:1; - u32 RST_DTX_IDX5:1; - u32 rsv:10; - u32 RST_DRX_IDX0:1; - u32: 15; - } field; - u32 word; -} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC; -#define DELAY_INT_CFG 0x0210 -typedef union _DELAY_INT_CFG_STRUC { - struct { - u32 RXMAX_PTIME:8; - u32 RXMAX_PINT:7; - u32 RXDLY_INT_EN:1; - u32 TXMAX_PTIME:8; - u32 TXMAX_PINT:7; - u32 TXDLY_INT_EN:1; - } field; - u32 word; -} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC; -#define WMM_AIFSN_CFG 0x0214 -typedef union _AIFSN_CSR_STRUC { - struct { - u32 Aifsn0:4; /* for AC_BE */ - u32 Aifsn1:4; /* for AC_BK */ - u32 Aifsn2:4; /* for AC_VI */ - u32 Aifsn3:4; /* for AC_VO */ - u32 Rsv:16; - } field; - u32 word; -} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC; -/* */ -/* CWMIN_CSR: CWmin for each EDCA AC */ -/* */ -#define WMM_CWMIN_CFG 0x0218 -typedef union _CWMIN_CSR_STRUC { - struct { - u32 Cwmin0:4; /* for AC_BE */ - u32 Cwmin1:4; /* for AC_BK */ - u32 Cwmin2:4; /* for AC_VI */ - u32 Cwmin3:4; /* for AC_VO */ - u32 Rsv:16; - } field; - u32 word; -} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC; - -/* */ -/* CWMAX_CSR: CWmin for each EDCA AC */ -/* */ -#define WMM_CWMAX_CFG 0x021c -typedef union _CWMAX_CSR_STRUC { - struct { - u32 Cwmax0:4; /* for AC_BE */ - u32 Cwmax1:4; /* for AC_BK */ - u32 Cwmax2:4; /* for AC_VI */ - u32 Cwmax3:4; /* for AC_VO */ - u32 Rsv:16; - } field; - u32 word; -} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC; - -/* */ -/* AC_TXOP_CSR0: AC_BK/AC_BE TXOP register */ -/* */ -#define WMM_TXOP0_CFG 0x0220 -typedef union _AC_TXOP_CSR0_STRUC { - struct { - u16 Ac0Txop; /* for AC_BK, in unit of 32us */ - u16 Ac1Txop; /* for AC_BE, in unit of 32us */ - } field; - u32 word; -} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC; - -/* */ -/* AC_TXOP_CSR1: AC_VO/AC_VI TXOP register */ -/* */ -#define WMM_TXOP1_CFG 0x0224 -typedef union _AC_TXOP_CSR1_STRUC { - struct { - u16 Ac2Txop; /* for AC_VI, in unit of 32us */ - u16 Ac3Txop; /* for AC_VO, in unit of 32us */ - } field; - u32 word; -} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC; - -#define RINGREG_DIFF 0x10 -#define GPIO_CTRL_CFG 0x0228 /*MAC_CSR13 */ -#define MCU_CMD_CFG 0x022c -#define TX_BASE_PTR0 0x0230 /*AC_BK base address */ -#define TX_MAX_CNT0 0x0234 -#define TX_CTX_IDX0 0x0238 -#define TX_DTX_IDX0 0x023c -#define TX_BASE_PTR1 0x0240 /*AC_BE base address */ -#define TX_MAX_CNT1 0x0244 -#define TX_CTX_IDX1 0x0248 -#define TX_DTX_IDX1 0x024c -#define TX_BASE_PTR2 0x0250 /*AC_VI base address */ -#define TX_MAX_CNT2 0x0254 -#define TX_CTX_IDX2 0x0258 -#define TX_DTX_IDX2 0x025c -#define TX_BASE_PTR3 0x0260 /*AC_VO base address */ -#define TX_MAX_CNT3 0x0264 -#define TX_CTX_IDX3 0x0268 -#define TX_DTX_IDX3 0x026c -#define TX_BASE_PTR4 0x0270 /*HCCA base address */ -#define TX_MAX_CNT4 0x0274 -#define TX_CTX_IDX4 0x0278 -#define TX_DTX_IDX4 0x027c -#define TX_BASE_PTR5 0x0280 /*MGMT base address */ -#define TX_MAX_CNT5 0x0284 -#define TX_CTX_IDX5 0x0288 -#define TX_DTX_IDX5 0x028c -#define TX_MGMTMAX_CNT TX_MAX_CNT5 -#define TX_MGMTCTX_IDX TX_CTX_IDX5 -#define TX_MGMTDTX_IDX TX_DTX_IDX5 -#define RX_BASE_PTR 0x0290 /*RX base address */ -#define RX_MAX_CNT 0x0294 -#define RX_CRX_IDX 0x0298 -#define RX_DRX_IDX 0x029c - -#define USB_DMA_CFG 0x02a0 -typedef union _USB_DMA_CFG_STRUC { - struct { - u32 RxBulkAggTOut:8; /*Rx Bulk Aggregation TimeOut in unit of 33ns */ - u32 RxBulkAggLmt:8; /*Rx Bulk Aggregation Limit in unit of 256 bytes */ - u32 phyclear:1; /*phy watch dog enable. write 1 */ - u32 rsv:2; - u32 TxClear:1; /*Clear USB DMA TX path */ - u32 TxopHalt:1; /*Halt TXOP count down when TX buffer is full. */ - u32 RxBulkAggEn:1; /*Enable Rx Bulk Aggregation */ - u32 RxBulkEn:1; /*Enable USB DMA Rx */ - u32 TxBulkEn:1; /*Enable USB DMA Tx */ - u32 EpoutValid:6; /*OUT endpoint data valid */ - u32 RxBusy:1; /*USB DMA RX FSM busy */ - u32 TxBusy:1; /*USB DMA TX FSM busy */ - } field; - u32 word; -} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC; - -/* */ -/* 3 PBF registers */ -/* */ -/* */ -/* Most are for debug. Driver doesn't touch PBF register. */ -#define PBF_SYS_CTRL 0x0400 -#define PBF_CFG 0x0408 -#define PBF_MAX_PCNT 0x040C -#define PBF_CTRL 0x0410 -#define PBF_INT_STA 0x0414 -#define PBF_INT_ENA 0x0418 -#define TXRXQ_PCNT 0x0438 -#define PBF_DBG 0x043c -#define PBF_CAP_CTRL 0x0440 - -#ifdef RT30xx -#ifdef RTMP_EFUSE_SUPPORT -/* eFuse registers */ -#define EFUSE_CTRL 0x0580 -#define EFUSE_DATA0 0x0590 -#define EFUSE_DATA1 0x0594 -#define EFUSE_DATA2 0x0598 -#define EFUSE_DATA3 0x059c -#endif /* RTMP_EFUSE_SUPPORT // */ -#endif /* RT30xx // */ - -#define OSC_CTRL 0x5a4 -#define PCIE_PHY_TX_ATTENUATION_CTRL 0x05C8 -#define LDO_CFG0 0x05d4 -#define GPIO_SWITCH 0x05dc - -/* */ -/* 4 MAC registers */ -/* */ -/* */ -/* 4.1 MAC SYSTEM configuration registers (offset:0x1000) */ -/* */ -#define MAC_CSR0 0x1000 -typedef union _ASIC_VER_ID_STRUC { - struct { - u16 ASICRev; /* reversion : 0 */ - u16 ASICVer; /* version : 2860 */ - } field; - u32 word; -} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC; -#define MAC_SYS_CTRL 0x1004 /*MAC_CSR1 */ -#define MAC_ADDR_DW0 0x1008 /* MAC ADDR DW0 */ -#define MAC_ADDR_DW1 0x100c /* MAC ADDR DW1 */ -/* */ -/* MAC_CSR2: STA MAC register 0 */ -/* */ -typedef union _MAC_DW0_STRUC { - struct { - u8 Byte0; /* MAC address byte 0 */ - u8 Byte1; /* MAC address byte 1 */ - u8 Byte2; /* MAC address byte 2 */ - u8 Byte3; /* MAC address byte 3 */ - } field; - u32 word; -} MAC_DW0_STRUC, *PMAC_DW0_STRUC; - -/* */ -/* MAC_CSR3: STA MAC register 1 */ -/* */ -typedef union _MAC_DW1_STRUC { - struct { - u8 Byte4; /* MAC address byte 4 */ - u8 Byte5; /* MAC address byte 5 */ - u8 U2MeMask; - u8 Rsvd1; - } field; - u32 word; -} MAC_DW1_STRUC, *PMAC_DW1_STRUC; - -#define MAC_BSSID_DW0 0x1010 /* MAC BSSID DW0 */ -#define MAC_BSSID_DW1 0x1014 /* MAC BSSID DW1 */ - -/* */ -/* MAC_CSR5: BSSID register 1 */ -/* */ -typedef union _MAC_CSR5_STRUC { - struct { - u8 Byte4; /* BSSID byte 4 */ - u8 Byte5; /* BSSID byte 5 */ - u16 BssIdMask:2; /* 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID */ - u16 MBssBcnNum:3; - u16 Rsvd:11; - } field; - u32 word; -} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC; - -#define MAX_LEN_CFG 0x1018 /* rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16 */ -#define BBP_CSR_CFG 0x101c /* */ -/* */ -/* BBP_CSR_CFG: BBP serial control register */ -/* */ -typedef union _BBP_CSR_CFG_STRUC { - struct { - u32 Value:8; /* Register value to program into BBP */ - u32 RegNum:8; /* Selected BBP register */ - u32 fRead:1; /* 0: Write BBP, 1: Read BBP */ - u32 Busy:1; /* 1: ASIC is busy execute BBP programming. */ - u32 BBP_PAR_DUR:1; /* 0: 4 MAC clock cycles 1: 8 MAC clock cycles */ - u32 BBP_RW_MODE:1; /* 0: use serial mode 1:parallel */ - u32: 12; - } field; - u32 word; -} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC; -#define RF_CSR_CFG0 0x1020 -/* */ -/* RF_CSR_CFG: RF control register */ -/* */ -typedef union _RF_CSR_CFG0_STRUC { - struct { - u32 RegIdAndContent:24; /* Register value to program into BBP */ - u32 bitwidth:5; /* Selected BBP register */ - u32 StandbyMode:1; /* 0: high when stand by 1: low when standby */ - u32 Sel:1; /* 0:RF_LE0 activate 1:RF_LE1 activate */ - u32 Busy:1; /* 0: idle 1: 8busy */ - } field; - u32 word; -} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC; -#define RF_CSR_CFG1 0x1024 -typedef union _RF_CSR_CFG1_STRUC { - struct { - u32 RegIdAndContent:24; /* Register value to program into BBP */ - u32 RFGap:5; /* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */ - u32 rsv:7; /* 0: idle 1: 8busy */ - } field; - u32 word; -} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC; -#define RF_CSR_CFG2 0x1028 /* */ -typedef union _RF_CSR_CFG2_STRUC { - struct { - u32 RegIdAndContent:24; /* Register value to program into BBP */ - u32 rsv:8; /* 0: idle 1: 8busy */ - } field; - u32 word; -} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC; -#define LED_CFG 0x102c /* MAC_CSR14 */ -typedef union _LED_CFG_STRUC { - struct { - u32 OnPeriod:8; /* blinking on period unit 1ms */ - u32 OffPeriod:8; /* blinking off period unit 1ms */ - u32 SlowBlinkPeriod:6; /* slow blinking period. unit:1ms */ - u32 rsv:2; - u32 RLedMode:2; /* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */ - u32 GLedMode:2; /* green Led Mode */ - u32 YLedMode:2; /* yellow Led Mode */ - u32 LedPolar:1; /* Led Polarity. 0: active low1: active high */ - u32: 1; - } field; - u32 word; -} LED_CFG_STRUC, *PLED_CFG_STRUC; -/* */ -/* 4.2 MAC TIMING configuration registers (offset:0x1100) */ -/* */ -#define XIFS_TIME_CFG 0x1100 /* MAC_CSR8 MAC_CSR9 */ -typedef union _IFS_SLOT_CFG_STRUC { - struct { - u32 CckmSifsTime:8; /* unit 1us. Applied after CCK RX/TX */ - u32 OfdmSifsTime:8; /* unit 1us. Applied after OFDM RX/TX */ - u32 OfdmXifsTime:4; /*OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND */ - u32 EIFS:9; /* unit 1us */ - u32 BBRxendEnable:1; /* reference RXEND signal to begin XIFS defer */ - u32 rsv:2; - } field; - u32 word; -} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC; - -#define BKOFF_SLOT_CFG 0x1104 /* mac_csr9 last 8 bits */ -#define NAV_TIME_CFG 0x1108 /* NAV (MAC_CSR15) */ -#define CH_TIME_CFG 0x110C /* Count as channel busy */ -#define PBF_LIFE_TIMER 0x1110 /*TX/RX MPDU timestamp timer (free run)Unit: 1us */ -#define BCN_TIME_CFG 0x1114 /* TXRX_CSR9 */ - -#define BCN_OFFSET0 0x042C -#define BCN_OFFSET1 0x0430 - -/* */ -/* BCN_TIME_CFG : Synchronization control register */ -/* */ -typedef union _BCN_TIME_CFG_STRUC { - struct { - u32 BeaconInterval:16; /* in unit of 1/16 TU */ - u32 bTsfTicking:1; /* Enable TSF auto counting */ - u32 TsfSyncMode:2; /* Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode */ - u32 bTBTTEnable:1; - u32 bBeaconGen:1; /* Enable beacon generator */ - u32: 3; - u32 TxTimestampCompensate:8; - } field; - u32 word; -} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC; -#define TBTT_SYNC_CFG 0x1118 /* txrx_csr10 */ -#define TSF_TIMER_DW0 0x111C /* Local TSF timer lsb 32 bits. Read-only */ -#define TSF_TIMER_DW1 0x1120 /* msb 32 bits. Read-only. */ -#define TBTT_TIMER 0x1124 /* TImer remains till next TBTT. Read-only. TXRX_CSR14 */ -#define INT_TIMER_CFG 0x1128 /* */ -#define INT_TIMER_EN 0x112c /* GP-timer and pre-tbtt Int enable */ -#define CH_IDLE_STA 0x1130 /* channel idle time */ -#define CH_BUSY_STA 0x1134 /* channle busy time */ -/* */ -/* 4.2 MAC POWER configuration registers (offset:0x1200) */ -/* */ -#define MAC_STATUS_CFG 0x1200 /* old MAC_CSR12 */ -#define PWR_PIN_CFG 0x1204 /* old MAC_CSR12 */ -#define AUTO_WAKEUP_CFG 0x1208 /* old MAC_CSR10 */ -/* */ -/* AUTO_WAKEUP_CFG: Manual power control / status register */ -/* */ -typedef union _AUTO_WAKEUP_STRUC { - struct { - u32 AutoLeadTime:8; - u32 NumofSleepingTbtt:7; /* ForceWake has high privilege than PutToSleep when both set */ - u32 EnableAutoWakeup:1; /* 0:sleep, 1:awake */ - u32: 16; - } field; - u32 word; -} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC; -/* */ -/* 4.3 MAC TX configuration registers (offset:0x1300) */ -/* */ - -#define EDCA_AC0_CFG 0x1300 /*AC_TXOP_CSR0 0x3474 */ -#define EDCA_AC1_CFG 0x1304 -#define EDCA_AC2_CFG 0x1308 -#define EDCA_AC3_CFG 0x130c -typedef union _EDCA_AC_CFG_STRUC { - struct { - u32 AcTxop:8; /* in unit of 32us */ - u32 Aifsn:4; /* # of slot time */ - u32 Cwmin:4; /* */ - u32 Cwmax:4; /*unit power of 2 */ - u32: 12; /* */ - } field; - u32 word; -} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC; - -#define EDCA_TID_AC_MAP 0x1310 -#define TX_PWR_CFG_0 0x1314 -#define TX_PWR_CFG_1 0x1318 -#define TX_PWR_CFG_2 0x131C -#define TX_PWR_CFG_3 0x1320 -#define TX_PWR_CFG_4 0x1324 -#define TX_PIN_CFG 0x1328 -#define TX_BAND_CFG 0x132c /* 0x1 use upper 20MHz. 0 juse lower 20MHz */ -#define TX_SW_CFG0 0x1330 -#define TX_SW_CFG1 0x1334 -#define TX_SW_CFG2 0x1338 -#define TXOP_THRES_CFG 0x133c -#define TXOP_CTRL_CFG 0x1340 -#define TX_RTS_CFG 0x1344 - -typedef union _TX_RTS_CFG_STRUC { - struct { - u32 AutoRtsRetryLimit:8; - u32 RtsThres:16; /* unit:byte */ - u32 RtsFbkEn:1; /* enable rts rate fallback */ - u32 rsv:7; /* 1: HT non-STBC control frame enable */ - } field; - u32 word; -} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC; -#define TX_TIMEOUT_CFG 0x1348 -typedef union _TX_TIMEOUT_CFG_STRUC { - struct { - u32 rsv:4; - u32 MpduLifeTime:4; /* expiration time = 2^(9+MPDU LIFE TIME) us */ - u32 RxAckTimeout:8; /* unit:slot. Used for TX precedure */ - u32 TxopTimeout:8; /*TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) */ - u32 rsv2:8; /* 1: HT non-STBC control frame enable */ - } field; - u32 word; -} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC; -#define TX_RTY_CFG 0x134c -typedef union PACKED _TX_RTY_CFG_STRUC { - struct { - u32 ShortRtyLimit:8; /* short retry limit */ - u32 LongRtyLimit:8; /* long retry limit */ - u32 LongRtyThre:12; /* Long retry threshold */ - u32 NonAggRtyMode:1; /* Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ - u32 AggRtyMode:1; /* Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ - u32 TxautoFBEnable:1; /* Tx retry PHY rate auto fallback enable */ - u32 rsv:1; /* 1: HT non-STBC control frame enable */ - } field; - u32 word; -} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC; -#define TX_LINK_CFG 0x1350 -typedef union PACKED _TX_LINK_CFG_STRUC { - struct PACKED { - u32 RemoteMFBLifeTime:8; /*remote MFB life time. unit : 32us */ - u32 MFBEnable:1; /* TX apply remote MFB 1:enable */ - u32 RemoteUMFSEnable:1; /* remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7) */ - u32 TxMRQEn:1; /* MCS request TX enable */ - u32 TxRDGEn:1; /* RDG TX enable */ - u32 TxCFAckEn:1; /* Piggyback CF-ACK enable */ - u32 rsv:3; /* */ - u32 RemotMFB:8; /* remote MCS feedback */ - u32 RemotMFS:8; /*remote MCS feedback sequence number */ - } field; - u32 word; -} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC; -#define HT_FBK_CFG0 0x1354 -typedef union PACKED _HT_FBK_CFG0_STRUC { - struct { - u32 HTMCS0FBK:4; - u32 HTMCS1FBK:4; - u32 HTMCS2FBK:4; - u32 HTMCS3FBK:4; - u32 HTMCS4FBK:4; - u32 HTMCS5FBK:4; - u32 HTMCS6FBK:4; - u32 HTMCS7FBK:4; - } field; - u32 word; -} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC; -#define HT_FBK_CFG1 0x1358 -typedef union _HT_FBK_CFG1_STRUC { - struct { - u32 HTMCS8FBK:4; - u32 HTMCS9FBK:4; - u32 HTMCS10FBK:4; - u32 HTMCS11FBK:4; - u32 HTMCS12FBK:4; - u32 HTMCS13FBK:4; - u32 HTMCS14FBK:4; - u32 HTMCS15FBK:4; - } field; - u32 word; -} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC; -#define LG_FBK_CFG0 0x135c -typedef union _LG_FBK_CFG0_STRUC { - struct { - u32 OFDMMCS0FBK:4; /*initial value is 0 */ - u32 OFDMMCS1FBK:4; /*initial value is 0 */ - u32 OFDMMCS2FBK:4; /*initial value is 1 */ - u32 OFDMMCS3FBK:4; /*initial value is 2 */ - u32 OFDMMCS4FBK:4; /*initial value is 3 */ - u32 OFDMMCS5FBK:4; /*initial value is 4 */ - u32 OFDMMCS6FBK:4; /*initial value is 5 */ - u32 OFDMMCS7FBK:4; /*initial value is 6 */ - } field; - u32 word; -} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC; -#define LG_FBK_CFG1 0x1360 -typedef union _LG_FBK_CFG1_STRUC { - struct { - u32 CCKMCS0FBK:4; /*initial value is 0 */ - u32 CCKMCS1FBK:4; /*initial value is 0 */ - u32 CCKMCS2FBK:4; /*initial value is 1 */ - u32 CCKMCS3FBK:4; /*initial value is 2 */ - u32 rsv:16; - } field; - u32 word; -} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC; - -/*======================================================= */ -/*================ Protection Paramater================================ */ -/*======================================================= */ -#define CCK_PROT_CFG 0x1364 /*CCK Protection */ -#define ASIC_SHORTNAV 1 -#define ASIC_longNAV 2 -#define ASIC_RTS 1 -#define ASIC_CTS 2 -typedef union _PROT_CFG_STRUC { - struct { - u32 ProtectRate:16; /*Protection control frame rate for CCK TX(RTS/CTS/CFEnd). */ - u32 ProtectCtrl:2; /*Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv */ - u32 ProtectNav:2; /*TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv */ - u32 TxopAllowCck:1; /*CCK TXOP allowance.0:disallow. */ - u32 TxopAllowOfdm:1; /*CCK TXOP allowance.0:disallow. */ - u32 TxopAllowMM20:1; /*CCK TXOP allowance. 0:disallow. */ - u32 TxopAllowMM40:1; /*CCK TXOP allowance.0:disallow. */ - u32 TxopAllowGF20:1; /*CCK TXOP allowance.0:disallow. */ - u32 TxopAllowGF40:1; /*CCK TXOP allowance.0:disallow. */ - u32 RTSThEn:1; /*RTS threshold enable on CCK TX */ - u32 rsv:5; - } field; - u32 word; -} PROT_CFG_STRUC, *PPROT_CFG_STRUC; - -#define OFDM_PROT_CFG 0x1368 /*OFDM Protection */ -#define MM20_PROT_CFG 0x136C /*MM20 Protection */ -#define MM40_PROT_CFG 0x1370 /*MM40 Protection */ -#define GF20_PROT_CFG 0x1374 /*GF20 Protection */ -#define GF40_PROT_CFG 0x1378 /*GR40 Protection */ -#define EXP_CTS_TIME 0x137C /* */ -#define EXP_ACK_TIME 0x1380 /* */ - -/* */ -/* 4.4 MAC RX configuration registers (offset:0x1400) */ -/* */ -#define RX_FILTR_CFG 0x1400 /*TXRX_CSR0 */ -#define AUTO_RSP_CFG 0x1404 /*TXRX_CSR4 */ -/* */ -/* TXRX_CSR4: Auto-Responder/ */ -/* */ -typedef union _AUTO_RSP_CFG_STRUC { - struct { - u32 AutoResponderEnable:1; - u32 BACAckPolicyEnable:1; /* 0:long, 1:short preamble */ - u32 CTS40MMode:1; /* Response CTS 40MHz duplicate mode */ - u32 CTS40MRef:1; /* Response CTS 40MHz duplicate mode */ - u32 AutoResponderPreamble:1; /* 0:long, 1:short preamble */ - u32 rsv:1; /* Power bit value in conrtrol frame */ - u32 DualCTSEn:1; /* Power bit value in conrtrol frame */ - u32 AckCtsPsmBit:1; /* Power bit value in conrtrol frame */ - u32: 24; - } field; - u32 word; -} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC; - -#define LEGACY_BASIC_RATE 0x1408 /* TXRX_CSR5 0x3054 */ -#define HT_BASIC_RATE 0x140c -#define HT_CTRL_CFG 0x1410 -#define SIFS_COST_CFG 0x1414 -#define RX_PARSER_CFG 0x1418 /*Set NAV for all received frames */ - -/* */ -/* 4.5 MAC Security configuration (offset:0x1500) */ -/* */ -#define TX_SEC_CNT0 0x1500 /* */ -#define RX_SEC_CNT0 0x1504 /* */ -#define CCMP_FC_MUTE 0x1508 /* */ -/* */ -/* 4.6 HCCA/PSMP (offset:0x1600) */ -/* */ -#define TXOP_HLDR_ADDR0 0x1600 -#define TXOP_HLDR_ADDR1 0x1604 -#define TXOP_HLDR_ET 0x1608 -#define QOS_CFPOLL_RA_DW0 0x160c -#define QOS_CFPOLL_A1_DW1 0x1610 -#define QOS_CFPOLL_QC 0x1614 -/* */ -/* 4.7 MAC Statistis registers (offset:0x1700) */ -/* */ -#define RX_STA_CNT0 0x1700 /* */ -#define RX_STA_CNT1 0x1704 /* */ -#define RX_STA_CNT2 0x1708 /* */ - -/* */ -/* RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count */ -/* */ -typedef union _RX_STA_CNT0_STRUC { - struct { - u16 CrcErr; - u16 PhyErr; - } field; - u32 word; -} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC; - -/* */ -/* RX_STA_CNT1_STRUC: RX False CCA count & RX long frame count */ -/* */ -typedef union _RX_STA_CNT1_STRUC { - struct { - u16 FalseCca; - u16 PlcpErr; - } field; - u32 word; -} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC; - -/* */ -/* RX_STA_CNT2_STRUC: */ -/* */ -typedef union _RX_STA_CNT2_STRUC { - struct { - u16 RxDupliCount; - u16 RxFifoOverflowCount; - } field; - u32 word; -} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC; -#define TX_STA_CNT0 0x170C /* */ -/* */ -/* STA_CSR3: TX Beacon count */ -/* */ -typedef union _TX_STA_CNT0_STRUC { - struct { - u16 TxFailCount; - u16 TxBeaconCount; - } field; - u32 word; -} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC; -#define TX_STA_CNT1 0x1710 /* */ -/* */ -/* TX_STA_CNT1: TX tx count */ -/* */ -typedef union _TX_STA_CNT1_STRUC { - struct { - u16 TxSuccess; - u16 TxRetransmit; - } field; - u32 word; -} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC; -#define TX_STA_CNT2 0x1714 /* */ -/* */ -/* TX_STA_CNT2: TX tx count */ -/* */ -typedef union _TX_STA_CNT2_STRUC { - struct { - u16 TxZeroLenCount; - u16 TxUnderFlowCount; - } field; - u32 word; -} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC; -#define TX_STA_FIFO 0x1718 /* */ -/* */ -/* TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register */ -/* */ -typedef union PACKED _TX_STA_FIFO_STRUC { - struct { - u32 bValid:1; /* 1:This register contains a valid TX result */ - u32 PidType:4; - u32 TxSuccess:1; /* Tx No retry success */ - u32 TxAggre:1; /* Tx Retry Success */ - u32 TxAckRequired:1; /* Tx fail */ - u32 wcid:8; /*wireless client index */ -/* u32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */ - u32 SuccessRate:13; /*include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */ - u32 TxBF:1; - u32 Reserve:2; - } field; - u32 word; -} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC; -/* Debug counter */ -#define TX_AGG_CNT 0x171c -typedef union _TX_AGG_CNT_STRUC { - struct { - u16 NonAggTxCount; - u16 AggTxCount; - } field; - u32 word; -} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC; -/* Debug counter */ -#define TX_AGG_CNT0 0x1720 -typedef union _TX_AGG_CNT0_STRUC { - struct { - u16 AggSize1Count; - u16 AggSize2Count; - } field; - u32 word; -} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC; -/* Debug counter */ -#define TX_AGG_CNT1 0x1724 -typedef union _TX_AGG_CNT1_STRUC { - struct { - u16 AggSize3Count; - u16 AggSize4Count; - } field; - u32 word; -} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC; -#define TX_AGG_CNT2 0x1728 -typedef union _TX_AGG_CNT2_STRUC { - struct { - u16 AggSize5Count; - u16 AggSize6Count; - } field; - u32 word; -} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC; -/* Debug counter */ -#define TX_AGG_CNT3 0x172c -typedef union _TX_AGG_CNT3_STRUC { - struct { - u16 AggSize7Count; - u16 AggSize8Count; - } field; - u32 word; -} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC; -/* Debug counter */ -#define TX_AGG_CNT4 0x1730 -typedef union _TX_AGG_CNT4_STRUC { - struct { - u16 AggSize9Count; - u16 AggSize10Count; - } field; - u32 word; -} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC; -#define TX_AGG_CNT5 0x1734 -typedef union _TX_AGG_CNT5_STRUC { - struct { - u16 AggSize11Count; - u16 AggSize12Count; - } field; - u32 word; -} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC; -#define TX_AGG_CNT6 0x1738 -typedef union _TX_AGG_CNT6_STRUC { - struct { - u16 AggSize13Count; - u16 AggSize14Count; - } field; - u32 word; -} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC; -#define TX_AGG_CNT7 0x173c -typedef union _TX_AGG_CNT7_STRUC { - struct { - u16 AggSize15Count; - u16 AggSize16Count; - } field; - u32 word; -} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC; -#define MPDU_DENSITY_CNT 0x1740 -typedef union _MPDU_DEN_CNT_STRUC { - struct { - u16 TXZeroDelCount; /*TX zero length delimiter count */ - u16 RXZeroDelCount; /*RX zero length delimiter count */ - } field; - u32 word; -} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC; -/* */ -/* TXRX control registers - base address 0x3000 */ -/* */ -/* rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first.. */ -#define TXRX_CSR1 0x77d0 - -/* */ -/* Security key table memory, base address = 0x1000 */ -/* */ -#define MAC_WCID_BASE 0x1800 /*8-bytes(use only 6-bytes) * 256 entry = */ -#define HW_WCID_ENTRY_SIZE 8 -#define PAIRWISE_KEY_TABLE_BASE 0x4000 /* 32-byte * 256-entry = -byte */ -#define HW_KEY_ENTRY_SIZE 0x20 -#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 /* 8-byte * 256-entry = -byte */ -#define MAC_IVEIV_TABLE_BASE 0x6000 /* 8-byte * 256-entry = -byte */ -#define HW_IVEIV_ENTRY_SIZE 8 -#define MAC_WCID_ATTRIBUTE_BASE 0x6800 /* 4-byte * 256-entry = -byte */ -#define HW_WCID_ATTRI_SIZE 4 -#define WCID_RESERVED 0x6bfc -#define SHARED_KEY_TABLE_BASE 0x6c00 /* 32-byte * 16-entry = 512-byte */ -#define SHARED_KEY_MODE_BASE 0x7000 /* 32-byte * 16-entry = 512-byte */ -#define HW_SHARED_KEY_MODE_SIZE 4 -#define SHAREDKEYTABLE 0 -#define PAIRWISEKEYTABLE 1 - -typedef union _SHAREDKEY_MODE_STRUC { - struct { - u32 Bss0Key0CipherAlg:3; - u32: 1; - u32 Bss0Key1CipherAlg:3; - u32: 1; - u32 Bss0Key2CipherAlg:3; - u32: 1; - u32 Bss0Key3CipherAlg:3; - u32: 1; - u32 Bss1Key0CipherAlg:3; - u32: 1; - u32 Bss1Key1CipherAlg:3; - u32: 1; - u32 Bss1Key2CipherAlg:3; - u32: 1; - u32 Bss1Key3CipherAlg:3; - u32: 1; - } field; - u32 word; -} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC; - -/* 8-byte per entry, 64-entry for pairwise key table */ -struct rt_hw_wcid_entry { - u8 Address[6]; - u8 Rsv[2]; -}; - -/* ================================================================================= */ -/* WCID format */ -/* ================================================================================= */ -/*7.1 WCID ENTRY format : 8bytes */ -struct rt_wcid_entry { - u8 RXBABitmap7; /* bit0 for TID8, bit7 for TID 15 */ - u8 RXBABitmap0; /* bit0 for TID0, bit7 for TID 7 */ - u8 MAC[6]; /* 0 for shared key table. 1 for pairwise key table */ -}; - -/*8.1.1 SECURITY KEY format : 8DW */ -/* 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table */ -struct rt_hw_key_entry { - u8 Key[16]; - u8 TxMic[8]; - u8 RxMic[8]; -}; - -/*8.1.2 IV/EIV format : 2DW */ - -/*8.1.3 RX attribute entry format : 1DW */ -struct rt_mac_attribute { - u32 KeyTab:1; /* 0 for shared key table. 1 for pairwise key table */ - u32 PairKeyMode:3; - u32 BSSIDIdx:3; /*multipleBSS index for the WCID */ - u32 RXWIUDF:3; - u32 rsv:22; -}; - -/* ================================================================================= */ -/* HOST-MCU communication data structure */ -/* ================================================================================= */ - -/* */ -/* H2M_MAILBOX_CSR: Host-to-MCU Mailbox */ -/* */ -typedef union _H2M_MAILBOX_STRUC { - struct { - u32 LowByte:8; - u32 HighByte:8; - u32 CmdToken:8; - u32 Owner:8; - } field; - u32 word; -} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC; - -/* */ -/* M2H_CMD_DONE_CSR: MCU-to-Host command complete indication */ -/* */ -typedef union _M2H_CMD_DONE_STRUC { - struct { - u32 CmdToken0; - u32 CmdToken1; - u32 CmdToken2; - u32 CmdToken3; - } field; - u32 word; -} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC; - -/*NAV_TIME_CFG :NAV */ -typedef union _NAV_TIME_CFG_STRUC { - struct { - u8 Sifs; /* in unit of 1-us */ - u8 SlotTime; /* in unit of 1-us */ - u16 Eifs:9; /* in unit of 1-us */ - u16 ZeroSifs:1; /* Applied zero SIFS timer after OFDM RX 0: disable */ - u16 rsv:6; - } field; - u32 word; -} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC; - -/* */ -/* RX_FILTR_CFG: /RX configuration register */ -/* */ -typedef union _RX_FILTR_CFG_STRUC { - struct { - u32 DropCRCErr:1; /* Drop CRC error */ - u32 DropPhyErr:1; /* Drop physical error */ - u32 DropNotToMe:1; /* Drop not to me unicast frame */ - u32 DropNotMyBSSID:1; /* Drop fram ToDs bit is true */ - - u32 DropVerErr:1; /* Drop version error frame */ - u32 DropMcast:1; /* Drop multicast frames */ - u32 DropBcast:1; /* Drop broadcast frames */ - u32 DropDuplicate:1; /* Drop duplicate frame */ - - u32 DropCFEndAck:1; /* Drop Ps-Poll */ - u32 DropCFEnd:1; /* Drop Ps-Poll */ - u32 DropAck:1; /* Drop Ps-Poll */ - u32 DropCts:1; /* Drop Ps-Poll */ - - u32 DropRts:1; /* Drop Ps-Poll */ - u32 DropPsPoll:1; /* Drop Ps-Poll */ - u32 DropBA:1; /* */ - u32 DropBAR:1; /* */ - - u32 DropRsvCntlType:1; - u32: 15; - } field; - u32 word; -} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC; - -/* */ -/* PHY_CSR4: RF serial control register */ -/* */ -typedef union _PHY_CSR4_STRUC { - struct { - u32 RFRegValue:24; /* Register value (include register id) serial out to RF/IF chip. */ - u32 NumberOfBits:5; /* Number of bits used in RFRegValue (I:20, RFMD:22) */ - u32 IFSelect:1; /* 1: select IF to program, 0: select RF to program */ - u32 PLL_LD:1; /* RF PLL_LD status */ - u32 Busy:1; /* 1: ASIC is busy execute RF programming. */ - } field; - u32 word; -} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC; - -/* */ -/* SEC_CSR5: shared key table security mode register */ -/* */ -typedef union _SEC_CSR5_STRUC { - struct { - u32 Bss2Key0CipherAlg:3; - u32: 1; - u32 Bss2Key1CipherAlg:3; - u32: 1; - u32 Bss2Key2CipherAlg:3; - u32: 1; - u32 Bss2Key3CipherAlg:3; - u32: 1; - u32 Bss3Key0CipherAlg:3; - u32: 1; - u32 Bss3Key1CipherAlg:3; - u32: 1; - u32 Bss3Key2CipherAlg:3; - u32: 1; - u32 Bss3Key3CipherAlg:3; - u32: 1; - } field; - u32 word; -} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC; - -/* */ -/* HOST_CMD_CSR: For HOST to interrupt embedded processor */ -/* */ -typedef union _HOST_CMD_CSR_STRUC { - struct { - u32 HostCommand:8; - u32 Rsv:24; - } field; - u32 word; -} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC; - -/* */ -/* AIFSN_CSR: AIFSN for each EDCA AC */ -/* */ - -/* */ -/* E2PROM_CSR: EEPROM control register */ -/* */ -typedef union _E2PROM_CSR_STRUC { - struct { - u32 Reload:1; /* Reload EEPROM content, write one to reload, self-cleared. */ - u32 EepromSK:1; - u32 EepromCS:1; - u32 EepromDI:1; - u32 EepromDO:1; - u32 Type:1; /* 1: 93C46, 0:93C66 */ - u32 LoadStatus:1; /* 1:loading, 0:done */ - u32 Rsvd:25; - } field; - u32 word; -} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC; - -/* */ -/* QOS_CSR0: TXOP holder address0 register */ -/* */ -typedef union _QOS_CSR0_STRUC { - struct { - u8 Byte0; /* MAC address byte 0 */ - u8 Byte1; /* MAC address byte 1 */ - u8 Byte2; /* MAC address byte 2 */ - u8 Byte3; /* MAC address byte 3 */ - } field; - u32 word; -} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC; - -/* */ -/* QOS_CSR1: TXOP holder address1 register */ -/* */ -typedef union _QOS_CSR1_STRUC { - struct { - u8 Byte4; /* MAC address byte 4 */ - u8 Byte5; /* MAC address byte 5 */ - u8 Rsvd0; - u8 Rsvd1; - } field; - u32 word; -} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC; - -#define RF_CSR_CFG 0x500 -typedef union _RF_CSR_CFG_STRUC { - struct { - u32 RF_CSR_DATA:8; /* DATA */ - u32 TESTCSR_RFACC_REGNUM:5; /* RF register ID */ - u32 Rsvd2:3; /* Reserved */ - u32 RF_CSR_WR:1; /* 0: read 1: write */ - u32 RF_CSR_KICK:1; /* kick RF register read/write */ - u32 Rsvd1:14; /* Reserved */ - } field; - u32 word; -} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC; - -/* */ -/* Other on-chip shared memory space, base = 0x2000 */ -/* */ - -/* CIS space - base address = 0x2000 */ -#define HW_CIS_BASE 0x2000 - -/* Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function. */ -#define HW_CS_CTS_BASE 0x7700 -/* DFS CTS frame base address. It's where mac stores CTS frame for DFS. */ -#define HW_DFS_CTS_BASE 0x7780 -#define HW_CTS_FRAME_SIZE 0x80 - -/* 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes */ -/* to save debugging settings */ -#define HW_DEBUG_SETTING_BASE 0x77f0 /* 0x77f0~0x77ff total 16 bytes */ -#define HW_DEBUG_SETTING_BASE2 0x7770 /* 0x77f0~0x77ff total 16 bytes */ - -/* In order to support maximum 8 MBSS and its maximum length is 512 for each beacon */ -/* Three section discontinue memory segments will be used. */ -/* 1. The original region for BCN 0~3 */ -/* 2. Extract memory from FCE table for BCN 4~5 */ -/* 3. Extract memory from Pair-wise key table for BCN 6~7 */ -/* It occupied those memory of wcid 238~253 for BCN 6 */ -/* and wcid 222~237 for BCN 7 */ -#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */ -#define HW_BEACON_BASE0 0x7800 -#define HW_BEACON_BASE1 0x7A00 -#define HW_BEACON_BASE2 0x7C00 -#define HW_BEACON_BASE3 0x7E00 -#define HW_BEACON_BASE4 0x7200 -#define HW_BEACON_BASE5 0x7400 -#define HW_BEACON_BASE6 0x5DC0 -#define HW_BEACON_BASE7 0x5BC0 - -#define HW_BEACON_MAX_COUNT 8 -#define HW_BEACON_OFFSET 0x0200 -#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE) - -/* HOST-MCU shared memory - base address = 0x2100 */ -#define HOST_CMD_CSR 0x404 -#define H2M_MAILBOX_CSR 0x7010 -#define H2M_MAILBOX_CID 0x7014 -#define H2M_MAILBOX_STATUS 0x701c -#define H2M_INT_SRC 0x7024 -#define H2M_BBP_AGENT 0x7028 -#define M2H_CMD_DONE_CSR 0x000c -#define MCU_TXOP_ARRAY_BASE 0x000c /* TODO: to be provided by Albert */ -#define MCU_TXOP_ENTRY_SIZE 32 /* TODO: to be provided by Albert */ -#define MAX_NUM_OF_TXOP_ENTRY 16 /* TODO: must be same with 8051 firmware */ -#define MCU_MBOX_VERSION 0x01 /* TODO: to be confirmed by Albert */ -#define MCU_MBOX_VERSION_OFFSET 5 /* TODO: to be provided by Albert */ - -/* */ -/* Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT, */ -/* */ -/* */ -/* DMA RING DESCRIPTOR */ -/* */ -#define E2PROM_CSR 0x0004 -#define IO_CNTL_CSR 0x77d0 - -/* ================================================================ */ -/* Tx / Rx / Mgmt ring descriptor definition */ -/* ================================================================ */ - -/* the following PID values are used to mark outgoing frame type in TXD->PID so that */ -/* proper TX statistics can be collected based on these categories */ -/* b3-2 of PID field - */ -#define PID_MGMT 0x05 -#define PID_BEACON 0x0c -#define PID_DATA_NORMALUCAST 0x02 -#define PID_DATA_AMPDU 0x04 -#define PID_DATA_NO_ACK 0x08 -#define PID_DATA_NOT_NORM_ACK 0x03 -/* value domain of pTxD->HostQId (4-bit: 0~15) */ -#define QID_AC_BK 1 /* meet ACI definition in 802.11e */ -#define QID_AC_BE 0 /* meet ACI definition in 802.11e */ -#define QID_AC_VI 2 -#define QID_AC_VO 3 -#define QID_HCCA 4 -#define NUM_OF_TX_RING 4 -#define QID_MGMT 13 -#define QID_RX 14 -#define QID_OTHER 15 - -#endif /* __RTMP_MAC_H__ // */ diff --git a/drivers/staging/rt2860/chip/rtmp_phy.h b/drivers/staging/rt2860/chip/rtmp_phy.h deleted file mode 100644 index a52221f1294e..000000000000 --- a/drivers/staging/rt2860/chip/rtmp_phy.h +++ /dev/null @@ -1,516 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_phy.h - - Abstract: - Ralink Wireless Chip PHY(BBP/RF) related definition & structures - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#ifndef __RTMP_PHY_H__ -#define __RTMP_PHY_H__ - -/* - RF sections -*/ -#define RF_R00 0 -#define RF_R01 1 -#define RF_R02 2 -#define RF_R03 3 -#define RF_R04 4 -#define RF_R05 5 -#define RF_R06 6 -#define RF_R07 7 -#define RF_R08 8 -#define RF_R09 9 -#define RF_R10 10 -#define RF_R11 11 -#define RF_R12 12 -#define RF_R13 13 -#define RF_R14 14 -#define RF_R15 15 -#define RF_R16 16 -#define RF_R17 17 -#define RF_R18 18 -#define RF_R19 19 -#define RF_R20 20 -#define RF_R21 21 -#define RF_R22 22 -#define RF_R23 23 -#define RF_R24 24 -#define RF_R25 25 -#define RF_R26 26 -#define RF_R27 27 -#define RF_R28 28 -#define RF_R29 29 -#define RF_R30 30 -#define RF_R31 31 - -/* value domain of pAd->RfIcType */ -#define RFIC_2820 1 /* 2.4G 2T3R */ -#define RFIC_2850 2 /* 2.4G/5G 2T3R */ -#define RFIC_2720 3 /* 2.4G 1T2R */ -#define RFIC_2750 4 /* 2.4G/5G 1T2R */ -#define RFIC_3020 5 /* 2.4G 1T1R */ -#define RFIC_2020 6 /* 2.4G B/G */ -#define RFIC_3021 7 /* 2.4G 1T2R */ -#define RFIC_3022 8 /* 2.4G 2T2R */ -#define RFIC_3052 9 /* 2.4G/5G 2T2R */ - -/* - BBP sections -*/ -#define BBP_R0 0 /* version */ -#define BBP_R1 1 /* TSSI */ -#define BBP_R2 2 /* TX configure */ -#define BBP_R3 3 -#define BBP_R4 4 -#define BBP_R5 5 -#define BBP_R6 6 -#define BBP_R14 14 /* RX configure */ -#define BBP_R16 16 -#define BBP_R17 17 /* RX sensibility */ -#define BBP_R18 18 -#define BBP_R21 21 -#define BBP_R22 22 -#define BBP_R24 24 -#define BBP_R25 25 -#define BBP_R26 26 -#define BBP_R27 27 -#define BBP_R31 31 -#define BBP_R49 49 /*TSSI */ -#define BBP_R50 50 -#define BBP_R51 51 -#define BBP_R52 52 -#define BBP_R55 55 -#define BBP_R62 62 /* Rx SQ0 Threshold HIGH */ -#define BBP_R63 63 -#define BBP_R64 64 -#define BBP_R65 65 -#define BBP_R66 66 -#define BBP_R67 67 -#define BBP_R68 68 -#define BBP_R69 69 -#define BBP_R70 70 /* Rx AGC SQ CCK Xcorr threshold */ -#define BBP_R73 73 -#define BBP_R75 75 -#define BBP_R77 77 -#define BBP_R78 78 -#define BBP_R79 79 -#define BBP_R80 80 -#define BBP_R81 81 -#define BBP_R82 82 -#define BBP_R83 83 -#define BBP_R84 84 -#define BBP_R86 86 -#define BBP_R91 91 -#define BBP_R92 92 -#define BBP_R94 94 /* Tx Gain Control */ -#define BBP_R103 103 -#define BBP_R105 105 -#define BBP_R106 106 -#define BBP_R113 113 -#define BBP_R114 114 -#define BBP_R115 115 -#define BBP_R116 116 -#define BBP_R117 117 -#define BBP_R118 118 -#define BBP_R119 119 -#define BBP_R120 120 -#define BBP_R121 121 -#define BBP_R122 122 -#define BBP_R123 123 -#ifdef RT30xx -#define BBP_R138 138 /* add by johnli, RF power sequence setup, ADC dynamic on/off control */ -#endif /* RT30xx // */ - -#define BBPR94_DEFAULT 0x06 /* Add 1 value will gain 1db */ - -/* */ -/* BBP & RF are using indirect access. Before write any value into it. */ -/* We have to make sure there is no outstanding command pending via checking busy bit. */ -/* */ -#define MAX_BUSY_COUNT 100 /* Number of retry before failing access BBP & RF indirect register */ - -/*#define PHY_TR_SWITCH_TIME 5 // usec */ - -/*#define BBP_R17_LOW_SENSIBILITY 0x50 */ -/*#define BBP_R17_MID_SENSIBILITY 0x41 */ -/*#define BBP_R17_DYNAMIC_UP_BOUND 0x40 */ - -#define RSSI_FOR_VERY_LOW_SENSIBILITY -35 -#define RSSI_FOR_LOW_SENSIBILITY -58 -#define RSSI_FOR_MID_LOW_SENSIBILITY -80 -#define RSSI_FOR_MID_SENSIBILITY -90 - -/***************************************************************************** - RF register Read/Write marco definition - *****************************************************************************/ -#ifdef RTMP_MAC_PCI -#define RTMP_RF_IO_WRITE32(_A, _V) \ -{ \ - if ((_A)->bPCIclkOff == FALSE) { \ - PHY_CSR4_STRUC _value; \ - unsigned long _busyCnt = 0; \ - \ - do { \ - RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word); \ - if (_value.field.Busy == IDLE) \ - break; \ - _busyCnt++; \ - } while (_busyCnt < MAX_BUSY_COUNT); \ - if (_busyCnt < MAX_BUSY_COUNT) { \ - RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \ - } \ - } \ -} -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V) -#endif /* RTMP_MAC_USB // */ - -#ifdef RT30xx -#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV) -#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V) -#endif /* RT30xx // */ - -/***************************************************************************** - BBP register Read/Write marco definitions. - we read/write the bbp value by register's ID. - Generate PER to test BA - *****************************************************************************/ -#ifdef RTMP_MAC_PCI -/* - basic marco for BBP read operation. - _pAd: the data structure pointer of struct rt_rtmp_adapter - _bbpID : the bbp register ID - _pV: data pointer used to save the value of queried bbp register. - _bViaMCU: if we need access the bbp via the MCU. -*/ -#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \ - do { \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int _busyCnt, _secCnt, _regID; \ - \ - _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \ - for (_busyCnt = 0; _busyCnt < MAX_BUSY_COUNT; _busyCnt++) { \ - RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \ - if (BbpCsr.field.Busy == BUSY) \ - continue; \ - BbpCsr.word = 0; \ - BbpCsr.field.fRead = 1; \ - BbpCsr.field.BBP_RW_MODE = 1; \ - BbpCsr.field.Busy = 1; \ - BbpCsr.field.RegNum = _bbpID; \ - RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \ - if ((_bViaMCU) == TRUE) { \ - AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \ - RTMPusecDelay(1000); \ - } \ - for (_secCnt = 0; _secCnt < MAX_BUSY_COUNT; _secCnt++) { \ - RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \ - if (BbpCsr.field.Busy == IDLE) \ - break; \ - } \ - if ((BbpCsr.field.Busy == IDLE) && \ - (BbpCsr.field.RegNum == _bbpID)) { \ - *(_pV) = (u8)BbpCsr.field.Value; \ - break; \ - } \ - } \ - if (BbpCsr.field.Busy == BUSY) { \ - DBGPRINT_ERR("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID); \ - *(_pV) = (_pAd)->BbpWriteLatch[_bbpID]; \ - if ((_bViaMCU) == TRUE) { \ - RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \ - BbpCsr.field.Busy = 0; \ - RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \ - } \ - } \ - } while (0) - -/* - This marco used for the BBP read operation which didn't need via MCU. -*/ -#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ - RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE) - -/* - This marco used for the BBP read operation which need via MCU. - But for some chipset which didn't have mcu (e.g., RBUS based chipset), we - will use this function too and didn't access the bbp register via the MCU. -*/ -/* Read BBP register by register's ID. Generate PER to test BA */ -#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int i, k; \ - BOOLEAN brc; \ - BbpCsr.field.Busy = IDLE; \ - if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \ - && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ - && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \ - && ((_A)->bPCIclkOff == FALSE) \ - && ((_A)->brt30xxBanMcuCmd == FALSE)) { \ - for (i = 0; i < MAX_BUSY_COUNT; i++) { \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - if (BbpCsr.field.Busy == BUSY) { \ - continue; \ - } \ - BbpCsr.word = 0; \ - BbpCsr.field.fRead = 1; \ - BbpCsr.field.BBP_RW_MODE = 1; \ - BbpCsr.field.Busy = 1; \ - BbpCsr.field.RegNum = _I; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ - if (brc == TRUE) { \ - for (k = 0; k < MAX_BUSY_COUNT; k++) { \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - if (BbpCsr.field.Busy == IDLE) \ - break; \ - } \ - if ((BbpCsr.field.Busy == IDLE) && \ - (BbpCsr.field.RegNum == _I)) { \ - *(_pV) = (u8)BbpCsr.field.Value; \ - break; \ - } \ - } else { \ - BbpCsr.field.Busy = 0; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - } \ - } \ - } \ - else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ - && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \ - && ((_A)->bPCIclkOff == FALSE)) { \ - for (i = 0; i < MAX_BUSY_COUNT; i++) { \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - if (BbpCsr.field.Busy == BUSY) { \ - continue; \ - } \ - BbpCsr.word = 0; \ - BbpCsr.field.fRead = 1; \ - BbpCsr.field.BBP_RW_MODE = 1; \ - BbpCsr.field.Busy = 1; \ - BbpCsr.field.RegNum = _I; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ - for (k = 0; k < MAX_BUSY_COUNT; k++) { \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - if (BbpCsr.field.Busy == IDLE) \ - break; \ - } \ - if ((BbpCsr.field.Busy == IDLE) && \ - (BbpCsr.field.RegNum == _I)) { \ - *(_pV) = (u8)BbpCsr.field.Value; \ - break; \ - } \ - } \ - } else { \ - DBGPRINT_ERR(" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)); \ - *(_pV) = (_A)->BbpWriteLatch[_I]; \ - } \ - if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) { \ - DBGPRINT_ERR("BBP read R%d=0x%x fail\n", _I, BbpCsr.word); \ - *(_pV) = (_A)->BbpWriteLatch[_I]; \ - } \ -} - -/* - basic marco for BBP write operation. - _pAd: the data structure pointer of struct rt_rtmp_adapter - _bbpID : the bbp register ID - _pV: data used to save the value of queried bbp register. - _bViaMCU: if we need access the bbp via the MCU. -*/ -#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \ - do { \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int _busyCnt, _regID; \ - \ - _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \ - for (_busyCnt = 0; _busyCnt < MAX_BUSY_COUNT; _busyCnt++) { \ - RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word); \ - if (BbpCsr.field.Busy == BUSY) \ - continue; \ - BbpCsr.word = 0; \ - BbpCsr.field.fRead = 0; \ - BbpCsr.field.BBP_RW_MODE = 1; \ - BbpCsr.field.Busy = 1; \ - BbpCsr.field.Value = _pV; \ - BbpCsr.field.RegNum = _bbpID; \ - RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \ - if ((_bViaMCU) == TRUE) { \ - AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \ - if ((_pAd)->OpMode == OPMODE_AP) \ - RTMPusecDelay(1000); \ - } \ - (_pAd)->BbpWriteLatch[_bbpID] = _pV; \ - break; \ - } \ - if (_busyCnt == MAX_BUSY_COUNT) { \ - DBGPRINT_ERR("BBP write R%d fail\n", _bbpID); \ - if ((_bViaMCU) == TRUE) { \ - RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \ - BbpCsr.field.Busy = 0; \ - RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word); \ - } \ - } \ - } while (0) - -/* - This marco used for the BBP write operation which didn't need via MCU. -*/ -#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \ - RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE) - -/* - This marco used for the BBP write operation which need via MCU. - But for some chipset which didn't have mcu (e.g., RBUS based chipset), we - will use this function too and didn't access the bbp register via the MCU. -*/ -/* Write BBP register by register's ID & value */ -#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int BusyCnt = 0; \ - BOOLEAN brc; \ - if (_I < MAX_NUM_OF_BBP_LATCH) { \ - if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \ - && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ - && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \ - && ((_A)->bPCIclkOff == FALSE) \ - && ((_A)->brt30xxBanMcuCmd == FALSE)) { \ - if (_A->AccessBBPFailCount > 20) { \ - AsicResetBBPAgent(_A); \ - _A->AccessBBPFailCount = 0; \ - } \ - for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - if (BbpCsr.field.Busy == BUSY) \ - continue; \ - BbpCsr.word = 0; \ - BbpCsr.field.fRead = 0; \ - BbpCsr.field.BBP_RW_MODE = 1; \ - BbpCsr.field.Busy = 1; \ - BbpCsr.field.Value = _V; \ - BbpCsr.field.RegNum = _I; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ - if (brc == TRUE) { \ - (_A)->BbpWriteLatch[_I] = _V; \ - } else { \ - BbpCsr.field.Busy = 0; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - } \ - break; \ - } \ - } \ - else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \ - && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ - && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \ - && ((_A)->bPCIclkOff == FALSE)) { \ - if (_A->AccessBBPFailCount > 20) { \ - AsicResetBBPAgent(_A); \ - _A->AccessBBPFailCount = 0; \ - } \ - for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - if (BbpCsr.field.Busy == BUSY) \ - continue; \ - BbpCsr.word = 0; \ - BbpCsr.field.fRead = 0; \ - BbpCsr.field.BBP_RW_MODE = 1; \ - BbpCsr.field.Busy = 1; \ - BbpCsr.field.Value = _V; \ - BbpCsr.field.RegNum = _I; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ - (_A)->BbpWriteLatch[_I] = _V; \ - break; \ - } \ - } else { \ - DBGPRINT_ERR(" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)); \ - } \ - if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) { \ - if (BusyCnt == MAX_BUSY_COUNT) \ - (_A)->AccessBBPFailCount++; \ - DBGPRINT_ERR("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff); \ - } \ - } else { \ - DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundary ****** \n"); \ - } \ -} -#endif /* RTMP_MAC_PCI // */ - -#ifdef RTMP_MAC_USB -#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) -#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) - -#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) -#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) -#endif /* RTMP_MAC_USB // */ - -#ifdef RT30xx -#define RTMP_ASIC_MMPS_DISABLE(_pAd) \ - do { \ - u32 _macData; \ - u8 _bbpData = 0; \ - /* disable MMPS BBP control register */ \ - RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \ - _bbpData &= ~(0x04); /*bit 2*/ \ - RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \ - \ - /* disable MMPS MAC control register */ \ - RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ - _macData &= ~(0x09); /*bit 0, 3*/ \ - RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ - } while (0) - -#define RTMP_ASIC_MMPS_ENABLE(_pAd) \ - do { \ - u32 _macData; \ - u8 _bbpData = 0; \ - /* enable MMPS BBP control register */ \ - RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \ - _bbpData |= (0x04); /*bit 2*/ \ - RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \ - \ - /* enable MMPS MAC control register */ \ - RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ - _macData |= (0x09); /*bit 0, 3*/ \ - RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ - } while (0) - -#endif /* RT30xx // */ - -#endif /* __RTMP_PHY_H__ // */ diff --git a/drivers/staging/rt2860/chips/rt3070.c b/drivers/staging/rt2860/chips/rt3070.c deleted file mode 100644 index 3a17fd10ec1f..000000000000 --- a/drivers/staging/rt2860/chips/rt3070.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt3070.c - - Abstract: - Specific funcitons and variables for RT3070 - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#ifdef RT3070 - -#include "../rt_config.h" - -#ifndef RTMP_RF_RW_SUPPORT -#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" -#endif /* RTMP_RF_RW_SUPPORT // */ - -void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd) -{ - int i; - u8 RFValue; - - /* Driver must read EEPROM to get RfIcType before initial RF registers */ - /* Initialize RF register to default value */ - if (IS_RT3070(pAd) || IS_RT3071(pAd)) { - /* Init RF calibration */ - /* Driver should toggle RF R30 bit7 before init RF registers */ - u32 RfReg = 0; - u32 data; - - RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg); - RfReg |= 0x80; - RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg); - RTMPusecDelay(1000); - RfReg &= 0x7F; - RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg); - - /* Initialize RF register to default value */ - for (i = 0; i < NUM_RF_REG_PARMS; i++) { - RT30xxWriteRFRegister(pAd, - RT30xx_RFRegTable[i].Register, - RT30xx_RFRegTable[i].Value); - } - - /* add by johnli */ - if (IS_RT3070(pAd)) { - /* */ - /* The DAC issue(LDO_CFG0) has been fixed in RT3070(F). */ - /* The voltage raising patch is no longer needed for RT3070(F) */ - /* */ - if ((pAd->MACVersion & 0xffff) < 0x0201) { - /* Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate */ - RTUSBReadMACRegister(pAd, LDO_CFG0, &data); - data = ((data & 0xF0FFFFFF) | 0x0D000000); - RTUSBWriteMACRegister(pAd, LDO_CFG0, data); - } - } else if (IS_RT3071(pAd)) { - /* Driver should set RF R6 bit6 on before init RF registers */ - RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg); - RfReg |= 0x40; - RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg); - - /* init R31 */ - RT30xxWriteRFRegister(pAd, RF_R31, 0x14); - - /* RT3071 version E has fixed this issue */ - if ((pAd->NicConfig2.field.DACTestBit == 1) - && ((pAd->MACVersion & 0xffff) < 0x0211)) { - /* patch tx EVM issue temporarily */ - RTUSBReadMACRegister(pAd, LDO_CFG0, &data); - data = ((data & 0xE0FFFFFF) | 0x0D000000); - RTUSBWriteMACRegister(pAd, LDO_CFG0, data); - } else { - RTMP_IO_READ32(pAd, LDO_CFG0, &data); - data = ((data & 0xE0FFFFFF) | 0x01000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, data); - } - - /* patch LNA_PE_G1 failed issue */ - RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data); - data &= ~(0x20); - RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data); - } - /*For RF filter Calibration */ - RTMPFilterCalibration(pAd); - - /* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */ - /* */ - /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */ - /* Raising RF voltage is no longer needed for RT3070(F) */ - /* */ - if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) { - RT30xxWriteRFRegister(pAd, RF_R27, 0x3); - } else if ((IS_RT3071(pAd)) - && ((pAd->MACVersion & 0xffff) < 0x0211)) { - RT30xxWriteRFRegister(pAd, RF_R27, 0x3); - } - /* set led open drain enable */ - RTUSBReadMACRegister(pAd, OPT_14, &data); - data |= 0x01; - RTUSBWriteMACRegister(pAd, OPT_14, data); - - /* move from RT30xxLoadRFNormalModeSetup because it's needed for both RT3070 and RT3071 */ - /* TX_LO1_en, RF R17 register Bit 3 to 0 */ - RT30xxReadRFRegister(pAd, RF_R17, &RFValue); - RFValue &= (~0x08); - /* to fix rx long range issue */ - if (pAd->NicConfig2.field.ExternalLNAForG == 0) { - if ((IS_RT3071(pAd) - && ((pAd->MACVersion & 0xffff) >= 0x0211)) - || IS_RT3070(pAd)) { - RFValue |= 0x20; - } - } - /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */ - if (pAd->TxMixerGain24G >= 1) { - RFValue &= (~0x7); /* clean bit [2:0] */ - RFValue |= pAd->TxMixerGain24G; - } - RT30xxWriteRFRegister(pAd, RF_R17, RFValue); - - if (IS_RT3071(pAd)) { - /* add by johnli, RF power sequence setup, load RF normal operation-mode setup */ - RT30xxLoadRFNormalModeSetup(pAd); - } else if (IS_RT3070(pAd)) { - /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */ - /* LDORF_VC, RF R27 register Bit 2 to 0 */ - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */ - /* Raising RF voltage is no longer needed for RT3070(F) */ - if ((pAd->MACVersion & 0xffff) < 0x0201) - RFValue = (RFValue & (~0x77)) | 0x3; - else - RFValue = (RFValue & (~0x77)); - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - /* end johnli */ - } - } - -} -#endif /* RT3070 // */ diff --git a/drivers/staging/rt2860/chips/rt3090.c b/drivers/staging/rt2860/chips/rt3090.c deleted file mode 100644 index 334720ee1345..000000000000 --- a/drivers/staging/rt2860/chips/rt3090.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt3090.c - - Abstract: - Specific functions and variables for RT3070 - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix a typo - -------- ---------- ---------------------------------------------- -*/ - -#ifdef RT3090 - -#include "../rt_config.h" - -#ifndef RTMP_RF_RW_SUPPORT -#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" -#endif /* RTMP_RF_RW_SUPPORT // */ - -void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd) -{ - int i; - /* Driver must read EEPROM to get RfIcType before initial RF registers */ - /* Initialize RF register to default value */ - if (IS_RT3090(pAd)) { - /* Init RF calibration */ - /* Driver should toggle RF R30 bit7 before init RF registers */ - u8 RfReg; - u32 data; - - RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg); - RfReg |= 0x80; - RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg); - RTMPusecDelay(1000); - RfReg &= 0x7F; - RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg); - - /* init R24, R31 */ - RT30xxWriteRFRegister(pAd, RF_R24, 0x0F); - RT30xxWriteRFRegister(pAd, RF_R31, 0x0F); - - /* RT309x version E has fixed this issue */ - if ((pAd->NicConfig2.field.DACTestBit == 1) - && ((pAd->MACVersion & 0xffff) < 0x0211)) { - /* patch tx EVM issue temporarily */ - RTMP_IO_READ32(pAd, LDO_CFG0, &data); - data = ((data & 0xE0FFFFFF) | 0x0D000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, data); - } else { - RTMP_IO_READ32(pAd, LDO_CFG0, &data); - data = ((data & 0xE0FFFFFF) | 0x01000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, data); - } - - /* patch LNA_PE_G1 failed issue */ - RTMP_IO_READ32(pAd, GPIO_SWITCH, &data); - data &= ~(0x20); - RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data); - - /* Initialize RF register to default value */ - for (i = 0; i < NUM_RF_REG_PARMS; i++) { - RT30xxWriteRFRegister(pAd, - RT30xx_RFRegTable[i].Register, - RT30xx_RFRegTable[i].Value); - } - - /* Driver should set RF R6 bit6 on before calibration */ - RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg); - RfReg |= 0x40; - RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg); - - /*For RF filter Calibration */ - RTMPFilterCalibration(pAd); - - /* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */ - if ((pAd->MACVersion & 0xffff) < 0x0211) - RT30xxWriteRFRegister(pAd, RF_R27, 0x3); - - /* set led open drain enable */ - RTMP_IO_READ32(pAd, OPT_14, &data); - data |= 0x01; - RTMP_IO_WRITE32(pAd, OPT_14, data); - - /* set default antenna as main */ - if (pAd->RfIcType == RFIC_3020) - AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); - - /* add by johnli, RF power sequence setup, load RF normal operation-mode setup */ - RT30xxLoadRFNormalModeSetup(pAd); - } - -} - -#endif /* RT3090 // */ diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c deleted file mode 100644 index 354debfe1477..000000000000 --- a/drivers/staging/rt2860/chips/rt30xx.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt30xx.c - - Abstract: - Specific functions and variables for RT30xx. - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix some typos - -------- ---------- ---------------------------------------------- -*/ - -#ifdef RT30xx - -#ifndef RTMP_RF_RW_SUPPORT -#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" -#endif /* RTMP_RF_RW_SUPPORT // */ - -#include "../rt_config.h" - -/* */ -/* RF register initialization set */ -/* */ -struct rt_reg_pair RT30xx_RFRegTable[] = { - {RF_R04, 0x40} - , - {RF_R05, 0x03} - , - {RF_R06, 0x02} - , - {RF_R07, 0x60} - , - {RF_R09, 0x0F} - , - {RF_R10, 0x41} - , - {RF_R11, 0x21} - , - {RF_R12, 0x7B} - , - {RF_R14, 0x90} - , - {RF_R15, 0x58} - , - {RF_R16, 0xB3} - , - {RF_R17, 0x92} - , - {RF_R18, 0x2C} - , - {RF_R19, 0x02} - , - {RF_R20, 0xBA} - , - {RF_R21, 0xDB} - , - {RF_R24, 0x16} - , - {RF_R25, 0x01} - , - {RF_R29, 0x1F} - , -}; - -u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair)); - -/* Antenna diversity use GPIO3 and EESK pin for control */ -/* Antenna and EEPROM access are both using EESK pin, */ -/* Therefor we should avoid accessing EESK at the same time */ -/* Then restore antenna after EEPROM access */ -/* The original name of this function is AsicSetRxAnt(), now change to */ -/*void AsicSetRxAnt( */ -void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant) -{ - u32 Value; -#ifdef RTMP_MAC_PCI - u32 x; -#endif - - if ((pAd->EepromAccess) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - return; - } - /* the antenna selection is through firmware and MAC register(GPIO3) */ - if (Ant == 0) { - /* Main antenna */ -#ifdef RTMP_MAC_PCI - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x |= (EESK); - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); -#else - AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0); -#endif /* RTMP_MAC_PCI // */ - - RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); - Value &= ~(0x0808); - RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("AsicSetRxAnt, switch to main antenna\n")); - } else { - /* Aux antenna */ -#ifdef RTMP_MAC_PCI - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EESK); - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); -#else - AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0); -#endif /* RTMP_MAC_PCI // */ - RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); - Value &= ~(0x0808); - Value |= 0x08; - RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("AsicSetRxAnt, switch to aux antenna\n")); - } -} - -/* - ======================================================================== - - Routine Description: - For RF filter calibration purpose - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd) -{ - u8 R55x = 0, value, FilterTarget = 0x1E, BBPValue = 0; - u32 loop = 0, count = 0, loopcnt = 0, ReTry = 0; - u8 RF_R24_Value = 0; - - /* Give bbp filter initial value */ - pAd->Mlme.CaliBW20RfR24 = 0x1F; - pAd->Mlme.CaliBW40RfR24 = 0x2F; /*Bit[5] must be 1 for BW 40 */ - - do { - if (loop == 1) { /*BandWidth = 40 MHz */ - /* Write 0x27 to RF_R24 to program filter */ - RF_R24_Value = 0x27; - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - FilterTarget = 0x15; - else - FilterTarget = 0x19; - - /* when calibrate BW40, BBP mask must set to BW40. */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - BBPValue |= (0x10); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - - /* set to BW40 */ - RT30xxReadRFRegister(pAd, RF_R31, &value); - value |= 0x20; - RT30xxWriteRFRegister(pAd, RF_R31, value); - } else { /*BandWidth = 20 MHz */ - /* Write 0x07 to RF_R24 to program filter */ - RF_R24_Value = 0x07; - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - FilterTarget = 0x13; - else - FilterTarget = 0x16; - - /* set to BW20 */ - RT30xxReadRFRegister(pAd, RF_R31, &value); - value &= (~0x20); - RT30xxWriteRFRegister(pAd, RF_R31, value); - } - - /* Write 0x01 to RF_R22 to enable baseband loopback mode */ - RT30xxReadRFRegister(pAd, RF_R22, &value); - value |= 0x01; - RT30xxWriteRFRegister(pAd, RF_R22, value); - - /* Write 0x00 to BBP_R24 to set power & frequency of passband test tone */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); - - do { - /* Write 0x90 to BBP_R25 to transmit test tone */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); - - RTMPusecDelay(1000); - /* Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); - R55x = value & 0xFF; - - } while ((ReTry++ < 100) && (R55x == 0)); - - /* Write 0x06 to BBP_R24 to set power & frequency of stopband test tone */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06); - - while (TRUE) { - /* Write 0x90 to BBP_R25 to transmit test tone */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); - - /*We need to wait for calibration */ - RTMPusecDelay(1000); - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); - value &= 0xFF; - if ((R55x - value) < FilterTarget) { - RF_R24_Value++; - } else if ((R55x - value) == FilterTarget) { - RF_R24_Value++; - count++; - } else { - break; - } - - /* prevent infinite loop; causes driver hang. */ - if (loopcnt++ > 100) { - DBGPRINT(RT_DEBUG_ERROR, - ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", - loopcnt)); - break; - } - /* Write RF_R24 to program filter */ - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - } - - if (count > 0) { - RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0)); - } - /* Store for future usage */ - if (loopcnt < 100) { - if (loop++ == 0) { - /*BandWidth = 20 MHz */ - pAd->Mlme.CaliBW20RfR24 = (u8)RF_R24_Value; - } else { - /*BandWidth = 40 MHz */ - pAd->Mlme.CaliBW40RfR24 = (u8)RF_R24_Value; - break; - } - } else - break; - - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - - /* reset count */ - count = 0; - } while (TRUE); - - /* */ - /* Set back to initial state */ - /* */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); - - RT30xxReadRFRegister(pAd, RF_R22, &value); - value &= ~(0x01); - RT30xxWriteRFRegister(pAd, RF_R22, value); - - /* set BBP back to BW20 */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", - pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); -} - -/* add by johnli, RF power sequence setup */ -/* - ========================================================================== - Description: - - Load RF normal operation-mode setup - - ========================================================================== - */ -void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd) -{ - u8 RFValue; - - /* RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 */ - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - RFValue = (RFValue & (~0x0C)) | 0x31; - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - /* TX_LO2_en, RF R15 register Bit 3 to 0 */ - RT30xxReadRFRegister(pAd, RF_R15, &RFValue); - RFValue &= (~0x08); - RT30xxWriteRFRegister(pAd, RF_R15, RFValue); - - /* move to NICInitRT30xxRFRegisters - // TX_LO1_en, RF R17 register Bit 3 to 0 - RT30xxReadRFRegister(pAd, RF_R17, &RFValue); - RFValue &= (~0x08); - // to fix rx long range issue - if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0)) - { - RFValue |= 0x20; - } - // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h - if (pAd->TxMixerGain24G >= 2) - { - RFValue &= (~0x7); // clean bit [2:0] - RFValue |= pAd->TxMixerGain24G; - } - RT30xxWriteRFRegister(pAd, RF_R17, RFValue); - */ - - /* RX_LO1_en, RF R20 register Bit 3 to 0 */ - RT30xxReadRFRegister(pAd, RF_R20, &RFValue); - RFValue &= (~0x08); - RT30xxWriteRFRegister(pAd, RF_R20, RFValue); - - /* RX_LO2_en, RF R21 register Bit 3 to 0 */ - RT30xxReadRFRegister(pAd, RF_R21, &RFValue); - RFValue &= (~0x08); - RT30xxWriteRFRegister(pAd, RF_R21, RFValue); - - /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */ - /* LDORF_VC, RF R27 register Bit 2 to 0 */ - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */ - /* Raising RF voltage is no longer needed for RT3070(F) */ - if (IS_RT3090(pAd)) { /* RT309x and RT3071/72 */ - if ((pAd->MACVersion & 0xffff) < 0x0211) - RFValue = (RFValue & (~0x77)) | 0x3; - else - RFValue = (RFValue & (~0x77)); - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - } - /* end johnli */ -} - -/* - ========================================================================== - Description: - - Load RF sleep-mode setup - - ========================================================================== - */ -void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd) -{ - u8 RFValue; - u32 MACValue; - -#ifdef RTMP_MAC_USB - if (!IS_RT3572(pAd)) -#endif /* RTMP_MAC_USB // */ - { - /* RF_BLOCK_en. RF R1 register Bit 0 to 0 */ - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - RFValue &= (~0x01); - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 */ - RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue &= (~0x30); - RT30xxWriteRFRegister(pAd, RF_R07, RFValue); - - /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 */ - RT30xxReadRFRegister(pAd, RF_R09, &RFValue); - RFValue &= (~0x0E); - RT30xxWriteRFRegister(pAd, RF_R09, RFValue); - - /* RX_CTB_en, RF R21 register Bit 7 to 0 */ - RT30xxReadRFRegister(pAd, RF_R21, &RFValue); - RFValue &= (~0x80); - RT30xxWriteRFRegister(pAd, RF_R21, RFValue); - } - - if (IS_RT3090(pAd) || /* IS_RT3090 including RT309x and RT3071/72 */ - IS_RT3572(pAd) || - (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) { -#ifdef RTMP_MAC_USB - if (!IS_RT3572(pAd)) -#endif /* RTMP_MAC_USB // */ - { - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - RFValue |= 0x77; - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - } - - RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); - MACValue |= 0x1D000000; - RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); - } -} - -/* - ========================================================================== - Description: - - Reverse RF sleep-mode setup - - ========================================================================== - */ -void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd) -{ - u8 RFValue; - u32 MACValue; - -#ifdef RTMP_MAC_USB - if (!IS_RT3572(pAd)) -#endif /* RTMP_MAC_USB // */ - { - /* RF_BLOCK_en, RF R1 register Bit 0 to 1 */ - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - RFValue |= 0x01; - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 */ - RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue |= 0x20; - RT30xxWriteRFRegister(pAd, RF_R07, RFValue); - - /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 */ - RT30xxReadRFRegister(pAd, RF_R09, &RFValue); - RFValue |= 0x0E; - RT30xxWriteRFRegister(pAd, RF_R09, RFValue); - - /* RX_CTB_en, RF R21 register Bit 7 to 1 */ - RT30xxReadRFRegister(pAd, RF_R21, &RFValue); - RFValue |= 0x80; - RT30xxWriteRFRegister(pAd, RF_R21, RFValue); - } - - if (IS_RT3090(pAd) || /* IS_RT3090 including RT309x and RT3071/72 */ - IS_RT3572(pAd) || - IS_RT3390(pAd) || - (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) { -#ifdef RTMP_MAC_USB - if (!IS_RT3572(pAd)) -#endif /* RTMP_MAC_USB // */ - { - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - if ((pAd->MACVersion & 0xffff) < 0x0211) - RFValue = (RFValue & (~0x77)) | 0x3; - else - RFValue = (RFValue & (~0x77)); - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - } - /* RT3071 version E has fixed this issue */ - if ((pAd->NicConfig2.field.DACTestBit == 1) - && ((pAd->MACVersion & 0xffff) < 0x0211)) { - /* patch tx EVM issue temporarily */ - RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); - MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); - } else { - RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); - MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); - } - } - - if (IS_RT3572(pAd)) - RT30xxWriteRFRegister(pAd, RF_R08, 0x80); -} - -/* end johnli */ - -void RT30xxHaltAction(struct rt_rtmp_adapter *pAd) -{ - u32 TxPinCfg = 0x00050F0F; - - /* */ - /* Turn off LNA_PE or TRSW_POL */ - /* */ - if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) { - if ((IS_RT3071(pAd) || IS_RT3572(pAd)) -#ifdef RTMP_EFUSE_SUPPORT - && (pAd->bUseEfuse) -#endif /* RTMP_EFUSE_SUPPORT // */ - ) { - TxPinCfg &= 0xFFFBF0F0; /* bit18 off */ - } else { - TxPinCfg &= 0xFFFFF0F0; - } - - RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); - } -} - -#endif /* RT30xx // */ diff --git a/drivers/staging/rt2860/chlist.h b/drivers/staging/rt2860/chlist.h deleted file mode 100644 index 1231e69d518b..000000000000 --- a/drivers/staging/rt2860/chlist.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - chlist.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Fonchi Wu 2007-12-19 created -*/ - -#ifndef __CHLIST_H__ -#define __CHLIST_H__ - -#include "rtmp_type.h" -#include "rtmp_def.h" - -#define ODOR 0 -#define IDOR 1 -#define BOTH 2 - -#define BAND_5G 0 -#define BAND_24G 1 -#define BAND_BOTH 2 - -struct rt_ch_desp { - u8 FirstChannel; - u8 NumOfCh; - char MaxTxPwr; /* dBm */ - u8 Geography; /* 0:out door, 1:in door, 2:both */ - BOOLEAN DfsReq; /* Dfs require, 0: No, 1: yes. */ -}; - -struct rt_ch_region { - u8 CountReg[3]; - u8 DfsType; /* 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56 */ - struct rt_ch_desp ChDesp[10]; -}; - -extern struct rt_ch_region ChRegion[]; - -struct rt_ch_freq_map { - u16 channel; - u16 freqKHz; -}; - -extern struct rt_ch_freq_map CH_HZ_ID_MAP[]; -extern int CH_HZ_ID_MAP_NUM; - -#define MAP_CHANNEL_ID_TO_KHZ(_ch, _khz) \ - do { \ - int _chIdx; \ - for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++) {\ - if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel) { \ - (_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;\ - break; \ - } \ - } \ - if (_chIdx == CH_HZ_ID_MAP_NUM) \ - (_khz) = 2412000; \ - } while (0) - -#define MAP_KHZ_TO_CHANNEL_ID(_khz, _ch) \ - do { \ - int _chIdx; \ - for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++) {\ - if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz) {\ - (_ch) = CH_HZ_ID_MAP[_chIdx].channel; \ - break; \ - } \ - } \ - if (_chIdx == CH_HZ_ID_MAP_NUM) \ - (_ch) = 1; \ - } while (0) - -void BuildChannelListEx(struct rt_rtmp_adapter *pAd); - -void BuildBeaconChList(struct rt_rtmp_adapter *pAd, - u8 *pBuf, unsigned long *pBufLen); - -void N_ChannelCheck(struct rt_rtmp_adapter *pAd); - -void N_SetCenCh(struct rt_rtmp_adapter *pAd); - -u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel); - -#endif /* __CHLIST_H__ */ diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c deleted file mode 100644 index 56ad236e1144..000000000000 --- a/drivers/staging/rt2860/common/action.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - action.c - - Abstract: - Handle association related requests either from WSTA or from local MLME - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Jan Lee 2006 created for rt2860 - */ - -#include "../rt_config.h" -#include "action.h" - -static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -/* - ========================================================================== - Description: - association state machine init, including state transition and timer init - Parameters: - S - pointer to the association state machine - Note: - The state machine looks like the following - - ASSOC_IDLE - MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action - MT2_PEER_DISASSOC_REQ peer_disassoc_action - MT2_PEER_ASSOC_REQ drop - MT2_PEER_REASSOC_REQ drop - MT2_CLS3ERR cls3err_action - ========================================================================== - */ -void ActionStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, - OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE, - MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE, - ACT_MACHINE_BASE); - - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, - (STATE_MACHINE_FUNC) PeerSpectrumAction); - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, - (STATE_MACHINE_FUNC) PeerQOSAction); - - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, - (STATE_MACHINE_FUNC) ReservedAction); - - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, - (STATE_MACHINE_FUNC) PeerBAAction); - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, - (STATE_MACHINE_FUNC) PeerHTAction); - StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, - (STATE_MACHINE_FUNC) MlmeADDBAAction); - StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, - (STATE_MACHINE_FUNC) MlmeDELBAAction); - StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, - (STATE_MACHINE_FUNC) MlmeDELBAAction); - - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, - (STATE_MACHINE_FUNC) PeerPublicAction); - StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, - (STATE_MACHINE_FUNC) PeerRMAction); - - StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, - (STATE_MACHINE_FUNC) MlmeQOSAction); - StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, - (STATE_MACHINE_FUNC) MlmeDLSAction); - StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, - (STATE_MACHINE_FUNC) MlmeInvalidAction); -} - -void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_addba_req *pInfo; - u8 Addr[6]; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long Idx; - struct rt_frame_addba_req Frame; - unsigned long FrameLen; - struct rt_ba_ori_entry *pBAEntry = NULL; - - pInfo = (struct rt_mlme_addba_req *)Elem->Msg; - NdisZeroMemory(&Frame, sizeof(struct rt_frame_addba_req)); - - if (MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) { - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("BA - MlmeADDBAAction() allocate memory failed \n")); - return; - } - /* 1. find entry */ - Idx = - pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; - if (Idx == 0) { - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_ERROR, - ("BA - MlmeADDBAAction() can't find BAOriEntry \n")); - return; - } else { - pBAEntry = &pAd->BATable.BAOriEntry[Idx]; - } - - { - if (ADHOC_ON(pAd)) - ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, - pAd->CurrentAddress, - pAd->CommonCfg.Bssid); - else - ActHeaderInit(pAd, &Frame.Hdr, - pAd->CommonCfg.Bssid, - pAd->CurrentAddress, - pInfo->pAddr); - } - - Frame.Category = CATEGORY_BA; - Frame.Action = ADDBA_REQ; - Frame.BaParm.AMSDUSupported = 0; - Frame.BaParm.BAPolicy = IMMED_BA; - Frame.BaParm.TID = pInfo->TID; - Frame.BaParm.BufSize = pInfo->BaBufSize; - Frame.Token = pInfo->Token; - Frame.TimeOutValue = pInfo->TimeOutValue; - Frame.BaStartSeq.field.FragNum = 0; - Frame.BaStartSeq.field.StartSeq = - pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; - - *(u16 *) (&Frame.BaParm) = - cpu2le16(*(u16 *) (&Frame.BaParm)); - Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue); - Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word); - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_frame_addba_req), &Frame, END_OF_ARGS); - - MiniportMMRequest(pAd, - (MGMT_USE_QUEUE_FLAG | - MapUserPriorityToAccessCategory[pInfo->TID]), - pOutBuffer, FrameLen); - - MlmeFreeMemory(pAd, pOutBuffer); - - DBGPRINT(RT_DEBUG_TRACE, - ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", - Frame.BaStartSeq.field.StartSeq, FrameLen, - Frame.BaParm.BufSize)); - } -} - -/* - ========================================================================== - Description: - send DELBA and delete BaEntry if any - Parametrs: - Elem - MLME message struct rt_mlme_delba_req - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_delba_req *pInfo; - u8 *pOutBuffer = NULL; - u8 *pOutBuffer2 = NULL; - int NStatus; - unsigned long Idx; - struct rt_frame_delba_req Frame; - unsigned long FrameLen; - struct rt_frame_bar FrameBar; - - pInfo = (struct rt_mlme_delba_req *)Elem->Msg; - /* must send back DELBA */ - NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req)); - DBGPRINT(RT_DEBUG_TRACE, - ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); - - if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) { - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_ERROR, - ("BA - MlmeDELBAAction() allocate memory failed 1. \n")); - return; - } - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_ERROR, - ("BA - MlmeDELBAAction() allocate memory failed 2. \n")); - return; - } - /* SEND BAR (Send BAR to refresh peer reordering buffer.) */ - Idx = - pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID]; - - BarHeaderInit(pAd, &FrameBar, - pAd->MacTab.Content[pInfo->Wcid].Addr, - pAd->CurrentAddress); - - FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton. */ - FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton. */ - FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton. */ - FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton. */ - FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton. */ - FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton. */ - - MakeOutgoingFrame(pOutBuffer2, &FrameLen, - sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer2); - DBGPRINT(RT_DEBUG_TRACE, - ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); - - /* SEND DELBA FRAME */ - FrameLen = 0; - - { - if (ADHOC_ON(pAd)) - ActHeaderInit(pAd, &Frame.Hdr, - pAd->MacTab.Content[pInfo->Wcid]. - Addr, pAd->CurrentAddress, - pAd->CommonCfg.Bssid); - else - ActHeaderInit(pAd, &Frame.Hdr, - pAd->CommonCfg.Bssid, - pAd->CurrentAddress, - pAd->MacTab.Content[pInfo->Wcid]. - Addr); - } - - Frame.Category = CATEGORY_BA; - Frame.Action = DELBA; - Frame.DelbaParm.Initiator = pInfo->Initiator; - Frame.DelbaParm.TID = pInfo->TID; - Frame.ReasonCode = 39; /* Time Out */ - *(u16 *) (&Frame.DelbaParm) = - cpu2le16(*(u16 *) (&Frame.DelbaParm)); - Frame.ReasonCode = cpu2le16(Frame.ReasonCode); - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_TRACE, - ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", - pInfo->Initiator)); - } -} - -void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - /*u8 * pOutBuffer = NULL; */ - /*Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11 */ -} - -void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Action = Elem->Msg[LENGTH_802_11 + 1]; - - switch (Action) { - case ADDBA_REQ: - PeerAddBAReqAction(pAd, Elem); - break; - case ADDBA_RESP: - PeerAddBARspAction(pAd, Elem); - break; - case DELBA: - PeerDelBAAction(pAd, Elem); - break; - } -} - -void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) - return; -} - -static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Category; - - if (Elem->MsgLen <= LENGTH_802_11) { - return; - } - - Category = Elem->Msg[LENGTH_802_11]; - DBGPRINT(RT_DEBUG_TRACE, - ("Rcv reserved category(%d) Action Frame\n", Category)); - hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen); -} - -void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - return; -} - -static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem) -{ - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen; - struct rt_frame_ht_info HTINFOframe, *pFrame; - u8 *pAddr; - - /* 2. Always send back ADDBA Response */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("ACTION - respond_ht_information_exchange_action() allocate memory failed \n")); - return; - } - /* get RA */ - pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0]; - pAddr = pFrame->Hdr.Addr2; - - NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info)); - /* 2-1. Prepare ADDBA Response frame. */ - { - if (ADHOC_ON(pAd)) - ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, - pAd->CurrentAddress, - pAd->CommonCfg.Bssid); - else - ActHeaderInit(pAd, &HTINFOframe.Hdr, - pAd->CommonCfg.Bssid, pAd->CurrentAddress, - pAddr); - } - - HTINFOframe.Category = CATEGORY_HT; - HTINFOframe.Action = HT_INFO_EXCHANGE; - HTINFOframe.HT_Info.Request = 0; - HTINFOframe.HT_Info.Forty_MHz_Intolerant = - pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant; - HTINFOframe.HT_Info.STA_Channel_Width = - pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth; - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS); - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); -} - -void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Action = Elem->Msg[LENGTH_802_11 + 1]; - - if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) - return; - - switch (Action) { - case NOTIFY_BW_ACTION: - DBGPRINT(RT_DEBUG_TRACE, - ("ACTION - HT Notify Channel bandwidth action----> \n")); - - if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) { - /* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */ - /* sending BW_Notify Action frame, and cause us to linkup and linkdown. */ - /* In legacy mode, don't need to parse HT action frame. */ - DBGPRINT(RT_DEBUG_TRACE, - ("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n", - Elem->Msg[LENGTH_802_11 + 2])); - break; - } - - if (Elem->Msg[LENGTH_802_11 + 2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */ - pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0; - - break; - case SMPS_ACTION: - /* 7.3.1.25 */ - DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n")); - if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) { - pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE; - } else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) { - pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC; - } else { - pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("Aid(%d) MIMO PS = %d\n", Elem->Wcid, - pAd->MacTab.Content[Elem->Wcid].MmpsMode)); - /* rt2860c : add something for smps change. */ - break; - - case SETPCO_ACTION: - break; - case MIMO_CHA_MEASURE_ACTION: - break; - case HT_INFO_EXCHANGE: - { - struct rt_ht_information_octet *pHT_info; - - pHT_info = - (struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 + - 2]; - /* 7.4.8.10 */ - DBGPRINT(RT_DEBUG_TRACE, - ("ACTION - HT Information Exchange action----> \n")); - if (pHT_info->Request) { - respond_ht_information_exchange_action(pAd, - Elem); - } - } - break; - } -} - -/* - ========================================================================== - Description: - Retry sending ADDBA Reqest. - - IRQL = DISPATCH_LEVEL - - Parametrs: - p8023Header: if this is already 802.3 format, p8023Header is NULL - - Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. - FALSE , then continue indicaterx at this moment. - ========================================================================== - */ -void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd) -{ - struct rt_mac_table_entry *pEntry; - int i, total; - u8 TID; - - total = pAd->MacTab.Size * NUM_OF_TID; - - for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) { - if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) { - pEntry = - &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i]. - Wcid]; - TID = pAd->BATable.BAOriEntry[i].TID; - - ASSERT(pAd->BATable.BAOriEntry[i].Wcid < - MAX_LEN_OF_MAC_TABLE); - } - total--; - } -} - -void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry) -{ - struct rt_frame_bar FrameBar; - unsigned long FrameLen; - int NStatus; - u8 *pOutBuffer = NULL; - u16 Sequence; - u8 i, TID; - u16 idx; - struct rt_ba_ori_entry *pBAEntry; - - for (i = 0; i < NUM_OF_TID; i++) { - idx = pEntry->BAOriWcidArray[i]; - if (idx == 0) { - continue; - } - pBAEntry = &pAd->BATable.BAOriEntry[idx]; - - if (pBAEntry->ORI_BA_Status == Originator_Done) { - TID = pBAEntry->TID; - - ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE); - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_ERROR, - ("BA - MlmeADDBAAction() allocate memory failed \n")); - return; - } - - Sequence = pEntry->TxSeq[TID]; - - BarHeaderInit(pAd, &FrameBar, pEntry->Addr, - pAd->CurrentAddress); - - FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */ - FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton. */ - FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton. */ - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_frame_bar), &FrameBar, - END_OF_ARGS); - /*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */ - if (1) /* Now we always send BAR. */ - { - /*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */ - MiniportMMRequest(pAd, - (MGMT_USE_QUEUE_FLAG | - MapUserPriorityToAccessCategory - [TID]), pOutBuffer, - FrameLen); - - } - MlmeFreeMemory(pAd, pOutBuffer); - } - } -} - -void ActHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, - u8 *Addr1, u8 *Addr2, u8 *Addr3) -{ - NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11)); - pHdr80211->FC.Type = BTYPE_MGMT; - pHdr80211->FC.SubType = SUBTYPE_ACTION; - - COPY_MAC_ADDR(pHdr80211->Addr1, Addr1); - COPY_MAC_ADDR(pHdr80211->Addr2, Addr2); - COPY_MAC_ADDR(pHdr80211->Addr3, Addr3); -} - -void BarHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA) -{ - NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar)); - pCntlBar->FC.Type = BTYPE_CNTL; - pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ; - pCntlBar->BarControl.MTID = 0; - pCntlBar->BarControl.Compressed = 1; - pCntlBar->BarControl.ACKPolicy = 0; - - pCntlBar->Duration = - 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba)); - - COPY_MAC_ADDR(pCntlBar->Addr1, pDA); - COPY_MAC_ADDR(pCntlBar->Addr2, pSA); -} - -/* - ========================================================================== - Description: - Insert Category and action code into the action frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - 3. category code of the frame. - 4. action code of the frame. - - Return : None. - ========================================================================== - */ -void InsertActField(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, u8 Category, u8 ActCode) -{ - unsigned long TempLen; - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &Category, 1, &ActCode, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} diff --git a/drivers/staging/rt2860/common/action.h b/drivers/staging/rt2860/common/action.h deleted file mode 100644 index 974f8b84039f..000000000000 --- a/drivers/staging/rt2860/common/action.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - aironet.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Paul Lin 04-06-15 Initial -*/ - -#ifndef __ACTION_H__ -#define __ACTION_H__ - -struct PACKED rt_ht_information_octet { - u8 Request:1; - u8 Forty_MHz_Intolerant:1; - u8 STA_Channel_Width:1; - u8 Reserved:5; -}; - -struct PACKED rt_frame_ht_info { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - struct rt_ht_information_octet HT_Info; -}; - -#endif /* __ACTION_H__ */ diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c deleted file mode 100644 index 133bc1b87d2c..000000000000 --- a/drivers/staging/rt2860/common/ba_action.c +++ /dev/null @@ -1,1650 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -#include "../rt_config.h" -#include - -#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) /*1 // initial sequence number of BA session */ - -#define ORI_SESSION_MAX_RETRY 8 -#define ORI_BA_SESSION_TIMEOUT (2000) /* ms */ -#define REC_BA_SESSION_IDLE_TIMEOUT (1000) /* ms */ - -#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms */ -#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * OS_HZ)/1000) /* system ticks -- 100 ms */ - -#define RESET_RCV_SEQ (0xFFFF) - -static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd, - struct reordering_mpdu *mpdu_blk); - -struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx); - -struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx); - -void BAOriSessionSetupTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3); - -void BARecSessionIdleTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3); - -BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout); -BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout); - -#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \ - Announce_Reordering_Packet(_pAd, _mpdu_blk); - -void BA_MaxWinSizeReasign(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntryPeer, u8 * pWinSize) -{ - u8 MaxSize; - - if (pAd->MACVersion >= RALINK_2883_VERSION) /* 3*3 */ - { - if (pAd->MACVersion >= RALINK_3070_VERSION) { - if (pEntryPeer->WepStatus != - Ndis802_11EncryptionDisabled) - MaxSize = 7; /* for non-open mode */ - else - MaxSize = 13; - } else - MaxSize = 31; - } else if (pAd->MACVersion >= RALINK_2880E_VERSION) /* 2880 e */ - { - if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled) - MaxSize = 7; /* for non-open mode */ - else - MaxSize = 13; - } else - MaxSize = 7; - - DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n", - *pWinSize, MaxSize)); - - if ((*pWinSize) > MaxSize) { - DBGPRINT(RT_DEBUG_TRACE, - ("ba> reassign max win size from %d to %d\n", - *pWinSize, MaxSize)); - - *pWinSize = MaxSize; - } -} - -void Announce_Reordering_Packet(struct rt_rtmp_adapter *pAd, - IN struct reordering_mpdu *mpdu) -{ - void *pPacket; - - pPacket = mpdu->pPacket; - - if (mpdu->bAMSDU) { - ASSERT(0); - BA_Reorder_AMSDU_Announce(pAd, pPacket); - } else { - /* */ - /* pass this 802.3 packet to upper layer or forward this packet to WM directly */ - /* */ - - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, - RTMP_GET_PACKET_IF(pPacket)); - } -} - -/* - * Insert a reordering mpdu into sorted linked list by sequence no. - */ -BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, - struct reordering_mpdu *mpdu) -{ - - struct reordering_mpdu **ppScan = &list->next; - - while (*ppScan != NULL) { - if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ)) { - ppScan = &(*ppScan)->next; - } else if ((*ppScan)->Sequence == mpdu->Sequence) { - /* give up this duplicated frame */ - return (FALSE); - } else { - /* find position */ - break; - } - } - - mpdu->next = *ppScan; - *ppScan = mpdu; - list->qlen++; - return TRUE; -} - -/* - * caller lock critical section if necessary - */ -static inline void ba_enqueue(struct reordering_list *list, - struct reordering_mpdu *mpdu_blk) -{ - list->qlen++; - mpdu_blk->next = list->next; - list->next = mpdu_blk; -} - -/* - * caller lock critical section if necessary - */ -static inline struct reordering_mpdu *ba_dequeue(struct reordering_list *list) -{ - struct reordering_mpdu *mpdu_blk = NULL; - - ASSERT(list); - - if (list->qlen) { - list->qlen--; - mpdu_blk = list->next; - if (mpdu_blk) { - list->next = mpdu_blk->next; - mpdu_blk->next = NULL; - } - } - return mpdu_blk; -} - -static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct - reordering_list - *list) -{ - return (ba_dequeue(list)); -} - -static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct - reordering_list - *list) -{ - ASSERT(list); - - return (list->next); -} - -/* - * free all resource for reordering mechanism - */ -void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd) -{ - struct rt_ba_table *Tab; - struct rt_ba_rec_entry *pBAEntry; - struct reordering_mpdu *mpdu_blk; - int i; - - Tab = &pAd->BATable; - - /* I. release all pending reordering packet */ - NdisAcquireSpinLock(&pAd->BATabLock); - for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) { - pBAEntry = &Tab->BARecEntry[i]; - if (pBAEntry->REC_BA_Status != Recipient_NONE) { - while ((mpdu_blk = - ba_reordering_mpdu_dequeue(&pBAEntry->list))) { - ASSERT(mpdu_blk->pPacket); - RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, - NDIS_STATUS_FAILURE); - ba_mpdu_blk_free(pAd, mpdu_blk); - } - } - } - NdisReleaseSpinLock(&pAd->BATabLock); - - ASSERT(pBAEntry->list.qlen == 0); - /* II. free memory of reordering mpdu table */ - NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock); - os_free_mem(pAd, pAd->mpdu_blk_pool.mem); - NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); -} - -/* - * Allocate all resource for reordering mechanism - */ -BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num) -{ - int i; - u8 *mem; - struct reordering_mpdu *mpdu_blk; - struct reordering_list *freelist; - - /* allocate spinlock */ - NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock); - - /* initialize freelist */ - freelist = &pAd->mpdu_blk_pool.freelist; - freelist->next = NULL; - freelist->qlen = 0; - - DBGPRINT(RT_DEBUG_TRACE, - ("Allocate %d memory for BA reordering\n", - (u32)(num * sizeof(struct reordering_mpdu)))); - - /* allocate number of mpdu_blk memory */ - os_alloc_mem(pAd, (u8 **) & mem, - (num * sizeof(struct reordering_mpdu))); - - pAd->mpdu_blk_pool.mem = mem; - - if (mem == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("Can't Allocate Memory for BA Reordering\n")); - return (FALSE); - } - - /* build mpdu_blk free list */ - for (i = 0; i < num; i++) { - /* get mpdu_blk */ - mpdu_blk = (struct reordering_mpdu *)mem; - /* initial mpdu_blk */ - NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu)); - /* next mpdu_blk */ - mem += sizeof(struct reordering_mpdu); - /* insert mpdu_blk into freelist */ - ba_enqueue(freelist, mpdu_blk); - } - - return (TRUE); -} - -/*static int blk_count=0; // sample take off, no use */ - -static struct reordering_mpdu *ba_mpdu_blk_alloc(struct rt_rtmp_adapter *pAd) -{ - struct reordering_mpdu *mpdu_blk; - - NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock); - mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist); - if (mpdu_blk) { -/* blk_count++; */ - /* reset mpdu_blk */ - NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu)); - } - NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); - return mpdu_blk; -} - -static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd, - struct reordering_mpdu *mpdu_blk) -{ - ASSERT(mpdu_blk); - - NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock); -/* blk_count--; */ - ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk); - NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock); -} - -static u16 ba_indicate_reordering_mpdus_in_order(struct rt_rtmp_adapter *pAd, - struct rt_ba_rec_entry *pBAEntry, - u16 StartSeq) -{ - struct reordering_mpdu *mpdu_blk; - u16 LastIndSeq = RESET_RCV_SEQ; - - NdisAcquireSpinLock(&pBAEntry->RxReRingLock); - - while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) { - /* find in-order frame */ - if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ)) { - break; - } - /* dequeue in-order frame from reodering list */ - mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list); - /* pass this frame up */ - ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); - /* move to next sequence */ - StartSeq = mpdu_blk->Sequence; - LastIndSeq = StartSeq; - /* free mpdu_blk */ - ba_mpdu_blk_free(pAd, mpdu_blk); - } - - NdisReleaseSpinLock(&pBAEntry->RxReRingLock); - - /* update last indicated sequence */ - return LastIndSeq; -} - -static void ba_indicate_reordering_mpdus_le_seq(struct rt_rtmp_adapter *pAd, - struct rt_ba_rec_entry *pBAEntry, - u16 Sequence) -{ - struct reordering_mpdu *mpdu_blk; - - NdisAcquireSpinLock(&pBAEntry->RxReRingLock); - while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) { - /* find in-order frame */ - if ((mpdu_blk->Sequence == Sequence) - || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) { - /* dequeue in-order frame from reodering list */ - mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list); - /* pass this frame up */ - ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); - /* free mpdu_blk */ - ba_mpdu_blk_free(pAd, mpdu_blk); - } else { - break; - } - } - NdisReleaseSpinLock(&pBAEntry->RxReRingLock); -} - -static void ba_refresh_reordering_mpdus(struct rt_rtmp_adapter *pAd, - struct rt_ba_rec_entry *pBAEntry) -{ - struct reordering_mpdu *mpdu_blk; - - NdisAcquireSpinLock(&pBAEntry->RxReRingLock); - - /* dequeue in-order frame from reodering list */ - while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) { - /* pass this frame up */ - ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk); - - pBAEntry->LastIndSeq = mpdu_blk->Sequence; - ba_mpdu_blk_free(pAd, mpdu_blk); - - /* update last indicated sequence */ - } - ASSERT(pBAEntry->list.qlen == 0); - pBAEntry->LastIndSeq = RESET_RCV_SEQ; - NdisReleaseSpinLock(&pBAEntry->RxReRingLock); -} - -/*static */ -void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd, - struct rt_ba_rec_entry *pBAEntry, - unsigned long Now32) -{ - u16 Sequence; - -/* if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) && */ -/* (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //|| */ -/* (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) && */ -/* (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8))) */ - if (RTMP_TIME_AFTER - ((unsigned long)Now32, - (unsigned long)(pBAEntry->LastIndSeqAtTimer + - (MAX_REORDERING_PACKET_TIMEOUT / 6))) - && (pBAEntry->list.qlen > 1) - ) { - DBGPRINT(RT_DEBUG_TRACE, - ("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", - pBAEntry->list.qlen, Now32, - (pBAEntry->LastIndSeqAtTimer), - (int)((long)Now32 - - (long)(pBAEntry->LastIndSeqAtTimer)), - MAX_REORDERING_PACKET_TIMEOUT, pBAEntry->LastIndSeq)); - ba_refresh_reordering_mpdus(pAd, pBAEntry); - pBAEntry->LastIndSeqAtTimer = Now32; - } else - if (RTMP_TIME_AFTER - ((unsigned long)Now32, - (unsigned long)(pBAEntry->LastIndSeqAtTimer + - (REORDERING_PACKET_TIMEOUT))) - && (pBAEntry->list.qlen > 0) - ) { - /* */ - /* force LastIndSeq to shift to LastIndSeq+1 */ - /* */ - Sequence = (pBAEntry->LastIndSeq + 1) & MAXSEQ; - ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence); - pBAEntry->LastIndSeqAtTimer = Now32; - pBAEntry->LastIndSeq = Sequence; - /* */ - /* indicate in-order mpdus */ - /* */ - Sequence = - ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, - Sequence); - if (Sequence != RESET_RCV_SEQ) { - pBAEntry->LastIndSeq = Sequence; - } - - DBGPRINT(RT_DEBUG_OFF, - ("%x, flush one!\n", pBAEntry->LastIndSeq)); - - } -} - -/* - * generate ADDBA request to - * set up BA agreement - */ -void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 TID, - u16 TimeOut, - unsigned long DelayTime, IN BOOLEAN isForced) -{ - /*struct rt_mlme_addba_req AddbaReq; */ - struct rt_ba_ori_entry *pBAEntry = NULL; - u16 Idx; - BOOLEAN Cancelled; - - if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) - && (isForced == FALSE)) - return; - - /* if this entry is limited to use legacy tx mode, it doesn't generate BA. */ - if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT) - return; - - if ((pEntry->BADeclineBitmap & (1 << TID)) && (isForced == FALSE)) { - /* try again after 3 secs */ - DelayTime = 3000; -/* DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n")); */ -/* return; */ - } - - Idx = pEntry->BAOriWcidArray[TID]; - if (Idx == 0) { - /* allocate a BA session */ - pBAEntry = BATableAllocOriEntry(pAd, &Idx); - if (pBAEntry == NULL) { - DBGPRINT(RT_DEBUG_TRACE, - ("ADDBA - MlmeADDBAAction() allocate BA session failed \n")); - return; - } - } else { - pBAEntry = &pAd->BATable.BAOriEntry[Idx]; - } - - if (pBAEntry->ORI_BA_Status >= Originator_WaitRes) { - return; - } - - pEntry->BAOriWcidArray[TID] = Idx; - - /* Initialize BA session */ - pBAEntry->ORI_BA_Status = Originator_WaitRes; - pBAEntry->Wcid = pEntry->Aid; - pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit; - pBAEntry->Sequence = BA_ORI_INIT_SEQ; - pBAEntry->Token = 1; /* (2008-01-21) Jan Lee recommends it - this token can't be 0 */ - pBAEntry->TID = TID; - pBAEntry->TimeOutValue = TimeOut; - pBAEntry->pAdapter = pAd; - - if (!(pEntry->TXBAbitmap & (1 << TID))) { - RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, - GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), - pBAEntry, FALSE); - } else - RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); - - /* set timer to send ADDBA request */ - RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime); -} - -void BAOriSessionAdd(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_frame_addba_rsp * pFrame) -{ - struct rt_ba_ori_entry *pBAEntry = NULL; - BOOLEAN Cancelled; - u8 TID; - u16 Idx; - u8 *pOutBuffer2 = NULL; - int NStatus; - unsigned long FrameLen; - struct rt_frame_bar FrameBar; - - TID = pFrame->BaParm.TID; - Idx = pEntry->BAOriWcidArray[TID]; - pBAEntry = &pAd->BATable.BAOriEntry[Idx]; - - /* Start fill in parameters. */ - if ((Idx != 0) && (pBAEntry->TID == TID) - && (pBAEntry->ORI_BA_Status == Originator_WaitRes)) { - pBAEntry->BAWinSize = - min(pBAEntry->BAWinSize, ((u8)pFrame->BaParm.BufSize)); - BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize); - - pBAEntry->TimeOutValue = pFrame->TimeOutValue; - pBAEntry->ORI_BA_Status = Originator_Done; - pAd->BATable.numDoneOriginator++; - - /* reset sequence number */ - pBAEntry->Sequence = BA_ORI_INIT_SEQ; - /* Set Bitmap flag. */ - pEntry->TXBAbitmap |= (1 << TID); - RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); - - pBAEntry->ORIBATimer.TimerValue = 0; /*pFrame->TimeOutValue; */ - - DBGPRINT(RT_DEBUG_TRACE, - ("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", - __func__, pEntry->TXBAbitmap, pBAEntry->BAWinSize, - pBAEntry->ORIBATimer.TimerValue)); - - /* SEND BAR ; */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("BA - BAOriSessionAdd() allocate memory failed \n")); - return; - } - - BarHeaderInit(pAd, &FrameBar, - pAd->MacTab.Content[pBAEntry->Wcid].Addr, - pAd->CurrentAddress); - - FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */ - FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; /* make sure sequence not clear in DEL funciton. */ - FrameBar.BarControl.TID = pBAEntry->TID; /* make sure sequence not clear in DEL funciton. */ - MakeOutgoingFrame(pOutBuffer2, &FrameLen, - sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer2); - - if (pBAEntry->ORIBATimer.TimerValue) - RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); /* in mSec */ - } -} - -BOOLEAN BARecSessionAdd(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_frame_addba_req * pFrame) -{ - struct rt_ba_rec_entry *pBAEntry = NULL; - BOOLEAN Status = TRUE; - BOOLEAN Cancelled; - u16 Idx; - u8 TID; - u8 BAWinSize; - /*u32 Value; */ - /*u32 offset; */ - - ASSERT(pEntry); - - /* find TID */ - TID = pFrame->BaParm.TID; - - BAWinSize = - min(((u8)pFrame->BaParm.BufSize), - (u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit); - - /* Intel patch */ - if (BAWinSize == 0) { - BAWinSize = 64; - } - - Idx = pEntry->BARecWcidArray[TID]; - - if (Idx == 0) { - pBAEntry = BATableAllocRecEntry(pAd, &Idx); - } else { - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - /* flush all pending reordering mpdus */ - ba_refresh_reordering_mpdus(pAd, pBAEntry); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __func__, - pAd->BATable.numAsRecipient, Idx, pFrame->BaParm.BufSize, - BAWinSize)); - - /* Start fill in parameters. */ - if (pBAEntry != NULL) { - ASSERT(pBAEntry->list.qlen == 0); - - pBAEntry->REC_BA_Status = Recipient_HandleRes; - pBAEntry->BAWinSize = BAWinSize; - pBAEntry->Wcid = pEntry->Aid; - pBAEntry->TID = TID; - pBAEntry->TimeOutValue = pFrame->TimeOutValue; - pBAEntry->REC_BA_Status = Recipient_Accept; - /* initial sequence number */ - pBAEntry->LastIndSeq = RESET_RCV_SEQ; /*pFrame->BaStartSeq.field.StartSeq; */ - - DBGPRINT(RT_DEBUG_OFF, - ("Start Seq = %08x\n", - pFrame->BaStartSeq.field.StartSeq)); - - if (pEntry->RXBAbitmap & (1 << TID)) { - RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); - } else { - RTMPInitTimer(pAd, &pBAEntry->RECBATimer, - GET_TIMER_FUNCTION - (BARecSessionIdleTimeout), pBAEntry, - TRUE); - } - - /* Set Bitmap flag. */ - pEntry->RXBAbitmap |= (1 << TID); - pEntry->BARecWcidArray[TID] = Idx; - - pEntry->BADeclineBitmap &= ~(1 << TID); - - /* Set BA session mask in WCID table. */ - RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID); - - DBGPRINT(RT_DEBUG_TRACE, - ("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", - pEntry->Aid, pEntry->RXBAbitmap, - pEntry->BARecWcidArray[TID])); - } else { - Status = FALSE; - DBGPRINT(RT_DEBUG_TRACE, - ("Can't Accept ADDBA for %pM TID = %d\n", - pEntry->Addr, TID)); - } - return (Status); -} - -struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx) -{ - int i; - struct rt_ba_rec_entry *pBAEntry = NULL; - - NdisAcquireSpinLock(&pAd->BATabLock); - - if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION) { - DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n", - pAd->BATable.numAsRecipient, - MAX_BARECI_SESSION)); - goto done; - } - /* reserve idx 0 to identify BAWcidArray[TID] as empty */ - for (i = 1; i < MAX_LEN_OF_BA_REC_TABLE; i++) { - pBAEntry = &pAd->BATable.BARecEntry[i]; - if ((pBAEntry->REC_BA_Status == Recipient_NONE)) { - /* get one */ - pAd->BATable.numAsRecipient++; - pBAEntry->REC_BA_Status = Recipient_USED; - *Idx = i; - break; - } - } - -done: - NdisReleaseSpinLock(&pAd->BATabLock); - return pBAEntry; -} - -struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx) -{ - int i; - struct rt_ba_ori_entry *pBAEntry = NULL; - - NdisAcquireSpinLock(&pAd->BATabLock); - - if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE)) { - goto done; - } - /* reserve idx 0 to identify BAWcidArray[TID] as empty */ - for (i = 1; i < MAX_LEN_OF_BA_ORI_TABLE; i++) { - pBAEntry = &pAd->BATable.BAOriEntry[i]; - if ((pBAEntry->ORI_BA_Status == Originator_NONE)) { - /* get one */ - pAd->BATable.numAsOriginator++; - pBAEntry->ORI_BA_Status = Originator_USED; - pBAEntry->pAdapter = pAd; - *Idx = i; - break; - } - } - -done: - NdisReleaseSpinLock(&pAd->BATabLock); - return pBAEntry; -} - -void BATableFreeOriEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx) -{ - struct rt_ba_ori_entry *pBAEntry = NULL; - struct rt_mac_table_entry *pEntry; - - if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) - return; - - pBAEntry = &pAd->BATable.BAOriEntry[Idx]; - - if (pBAEntry->ORI_BA_Status != Originator_NONE) { - pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; - pEntry->BAOriWcidArray[pBAEntry->TID] = 0; - - NdisAcquireSpinLock(&pAd->BATabLock); - if (pBAEntry->ORI_BA_Status == Originator_Done) { - pAd->BATable.numDoneOriginator -= 1; - pEntry->TXBAbitmap &= (~(1 << (pBAEntry->TID))); - DBGPRINT(RT_DEBUG_TRACE, - ("BATableFreeOriEntry numAsOriginator= %ld\n", - pAd->BATable.numAsRecipient)); - /* Erase Bitmap flag. */ - } - - ASSERT(pAd->BATable.numAsOriginator != 0); - - pAd->BATable.numAsOriginator -= 1; - - pBAEntry->ORI_BA_Status = Originator_NONE; - pBAEntry->Token = 0; - NdisReleaseSpinLock(&pAd->BATabLock); - } -} - -void BATableFreeRecEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx) -{ - struct rt_ba_rec_entry *pBAEntry = NULL; - struct rt_mac_table_entry *pEntry; - - if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE)) - return; - - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - - if (pBAEntry->REC_BA_Status != Recipient_NONE) { - pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; - pEntry->BARecWcidArray[pBAEntry->TID] = 0; - - NdisAcquireSpinLock(&pAd->BATabLock); - - ASSERT(pAd->BATable.numAsRecipient != 0); - - pAd->BATable.numAsRecipient -= 1; - - pBAEntry->REC_BA_Status = Recipient_NONE; - NdisReleaseSpinLock(&pAd->BATabLock); - } -} - -void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd, - u8 Wcid, - u8 TID, - IN BOOLEAN bPassive, IN BOOLEAN bForceSend) -{ - unsigned long Idx = 0; - struct rt_ba_ori_entry *pBAEntry; - BOOLEAN Cancelled; - - if (Wcid >= MAX_LEN_OF_MAC_TABLE) { - return; - } - /* */ - /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */ - /* */ - Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID]; - if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) { - if (bForceSend == TRUE) { - /* force send specified TID DelBA */ - struct rt_mlme_delba_req DelbaReq; - struct rt_mlme_queue_elem *Elem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - if (Elem != NULL) { - NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); - NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem)); - - COPY_MAC_ADDR(DelbaReq.Addr, - pAd->MacTab.Content[Wcid].Addr); - DelbaReq.Wcid = Wcid; - DelbaReq.TID = TID; - DelbaReq.Initiator = ORIGINATOR; - Elem->MsgLen = sizeof(DelbaReq); - NdisMoveMemory(Elem->Msg, &DelbaReq, - sizeof(DelbaReq)); - MlmeDELBAAction(pAd, Elem); - kfree(Elem); - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("%s(bForceSend):alloc memory failed!\n", - __func__)); - } - } - - return; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID)); - - pBAEntry = &pAd->BATable.BAOriEntry[Idx]; - DBGPRINT(RT_DEBUG_TRACE, - ("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, - Wcid, TID, pBAEntry->ORI_BA_Status)); - /* */ - /* Prepare DelBA action frame and send to the peer. */ - /* */ - if ((bPassive == FALSE) && (TID == pBAEntry->TID) - && (pBAEntry->ORI_BA_Status == Originator_Done)) { - struct rt_mlme_delba_req DelbaReq; - struct rt_mlme_queue_elem *Elem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - if (Elem != NULL) { - NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); - NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem)); - - COPY_MAC_ADDR(DelbaReq.Addr, - pAd->MacTab.Content[Wcid].Addr); - DelbaReq.Wcid = Wcid; - DelbaReq.TID = pBAEntry->TID; - DelbaReq.Initiator = ORIGINATOR; - Elem->MsgLen = sizeof(DelbaReq); - NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); - MlmeDELBAAction(pAd, Elem); - kfree(Elem); - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("%s():alloc memory failed!\n", __func__)); - return; - } - } - RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); - BATableFreeOriEntry(pAd, Idx); - - if (bPassive) { - /*BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); */ - } -} - -void BARecSessionTearDown(struct rt_rtmp_adapter *pAd, - u8 Wcid, u8 TID, IN BOOLEAN bPassive) -{ - unsigned long Idx = 0; - struct rt_ba_rec_entry *pBAEntry; - - if (Wcid >= MAX_LEN_OF_MAC_TABLE) { - return; - } - /* */ - /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */ - /* */ - Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; - if (Idx == 0) - return; - - DBGPRINT(RT_DEBUG_TRACE, - ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID)); - - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - DBGPRINT(RT_DEBUG_TRACE, - ("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, - Wcid, TID, pBAEntry->REC_BA_Status)); - /* */ - /* Prepare DelBA action frame and send to the peer. */ - /* */ - if ((TID == pBAEntry->TID) - && (pBAEntry->REC_BA_Status == Recipient_Accept)) { - struct rt_mlme_delba_req DelbaReq; - BOOLEAN Cancelled; - /*unsigned long offset; */ - /*u32 VALUE; */ - - RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); - - /* */ - /* 1. Send DELBA Action Frame */ - /* */ - if (bPassive == FALSE) { - struct rt_mlme_queue_elem *Elem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - if (Elem != NULL) { - NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); - NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem)); - - COPY_MAC_ADDR(DelbaReq.Addr, - pAd->MacTab.Content[Wcid].Addr); - DelbaReq.Wcid = Wcid; - DelbaReq.TID = TID; - DelbaReq.Initiator = RECIPIENT; - Elem->MsgLen = sizeof(DelbaReq); - NdisMoveMemory(Elem->Msg, &DelbaReq, - sizeof(DelbaReq)); - MlmeDELBAAction(pAd, Elem); - kfree(Elem); - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("%s():alloc memory failed!\n", - __func__)); - return; - } - } - - /* */ - /* 2. Free resource of BA session */ - /* */ - /* flush all pending reordering mpdus */ - ba_refresh_reordering_mpdus(pAd, pBAEntry); - - NdisAcquireSpinLock(&pAd->BATabLock); - - /* Erase Bitmap flag. */ - pBAEntry->LastIndSeq = RESET_RCV_SEQ; - pBAEntry->BAWinSize = 0; - /* Erase Bitmap flag at software mactable */ - pAd->MacTab.Content[Wcid].RXBAbitmap &= - (~(1 << (pBAEntry->TID))); - pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; - - RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); - - NdisReleaseSpinLock(&pAd->BATabLock); - - } - - BATableFreeRecEntry(pAd, Idx); -} - -void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid) -{ - int i; - - for (i = 0; i < NUM_OF_TID; i++) { - BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE); - BARecSessionTearDown(pAd, Wcid, i, FALSE); - } -} - -/* - ========================================================================== - Description: - Retry sending ADDBA Reqest. - - IRQL = DISPATCH_LEVEL - - Parametrs: - p8023Header: if this is already 802.3 format, p8023Header is NULL - - Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. - FALSE , then continue indicaterx at this moment. - ========================================================================== - */ -void BAOriSessionSetupTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3) -{ - struct rt_ba_ori_entry *pBAEntry = (struct rt_ba_ori_entry *)FunctionContext; - struct rt_mac_table_entry *pEntry; - struct rt_rtmp_adapter *pAd; - - if (pBAEntry == NULL) - return; - - pAd = pBAEntry->pAdapter; - - { - /* Do nothing if monitor mode is on */ - if (MONITOR_ON(pAd)) - return; - } - - pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; - - if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) - && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) { - struct rt_mlme_addba_req AddbaReq; - - NdisZeroMemory(&AddbaReq, sizeof(AddbaReq)); - COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr); - AddbaReq.Wcid = (u8)(pEntry->Aid); - AddbaReq.TID = pBAEntry->TID; - AddbaReq.BaBufSize = - pAd->CommonCfg.BACapability.field.RxBAWinLimit; - AddbaReq.TimeOutValue = 0; - AddbaReq.Token = pBAEntry->Token; - MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, - sizeof(struct rt_mlme_addba_req), (void *)& AddbaReq); - RTMP_MLME_HANDLER(pAd); - DBGPRINT(RT_DEBUG_TRACE, - ("BA Ori Session Timeout(%d) : Send ADD BA again\n", - pBAEntry->Token)); - - pBAEntry->Token++; - RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); - } else { - BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]); - } -} - -/* - ========================================================================== - Description: - Retry sending ADDBA Reqest. - - IRQL = DISPATCH_LEVEL - - Parametrs: - p8023Header: if this is already 802.3 format, p8023Header is NULL - - Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. - FALSE , then continue indicaterx at this moment. - ========================================================================== - */ -void BARecSessionIdleTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - - struct rt_ba_rec_entry *pBAEntry = (struct rt_ba_rec_entry *)FunctionContext; - struct rt_rtmp_adapter *pAd; - unsigned long Now32; - - if (pBAEntry == NULL) - return; - - if ((pBAEntry->REC_BA_Status == Recipient_Accept)) { - NdisGetSystemUpTime(&Now32); - - if (RTMP_TIME_AFTER - ((unsigned long)Now32, - (unsigned long)(pBAEntry->LastIndSeqAtTimer + - REC_BA_SESSION_IDLE_TIMEOUT))) { - pAd = pBAEntry->pAdapter; - /* flush all pending reordering mpdus */ - ba_refresh_reordering_mpdus(pAd, pBAEntry); - DBGPRINT(RT_DEBUG_OFF, - ("%ld: REC BA session Timeout\n", Now32)); - } - } -} - -void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - /* 7.4.4.1 */ - /*unsigned long Idx; */ - u8 Status = 1; - u8 pAddr[6]; - struct rt_frame_addba_rsp ADDframe; - u8 *pOutBuffer = NULL; - int NStatus; - struct rt_frame_addba_req * pAddreqFrame = NULL; - /*u8 BufSize; */ - unsigned long FrameLen; - unsigned long *ptemp; - struct rt_mac_table_entry *pMacEntry; - - DBGPRINT(RT_DEBUG_TRACE, - ("%s ==> (Wcid = %d)\n", __func__, Elem->Wcid)); - - /*hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); */ - - /*ADDBA Request from unknown peer, ignore this. */ - if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) - return; - - pMacEntry = &pAd->MacTab.Content[Elem->Wcid]; - DBGPRINT(RT_DEBUG_TRACE, ("BA - PeerAddBAReqAction----> \n")); - ptemp = (unsigned long *)Elem->Msg; - /*DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); */ - - if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) { - - if ((pAd->CommonCfg.bBADecline == FALSE) - && IS_HT_STA(pMacEntry)) { - pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]); - DBGPRINT(RT_DEBUG_OFF, - ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid)); - if (BARecSessionAdd - (pAd, &pAd->MacTab.Content[Elem->Wcid], - pAddreqFrame)) - Status = 0; - else - Status = 38; /* more parameters have invalid values */ - } else { - Status = 37; /* the request has been declined. */ - } - } - - if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI) - ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC); - - pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]); - /* 2. Always send back ADDBA Response */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("ACTION - PeerBAAction() allocate memory failed \n")); - return; - } - - NdisZeroMemory(&ADDframe, sizeof(struct rt_frame_addba_rsp)); - - /* 2-1. Prepare ADDBA Response frame. */ - { - if (ADHOC_ON(pAd)) - ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, - pAd->CurrentAddress, - pAd->CommonCfg.Bssid); - else - ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, - pAd->CurrentAddress, pAddr); - } - - ADDframe.Category = CATEGORY_BA; - ADDframe.Action = ADDBA_RESP; - ADDframe.Token = pAddreqFrame->Token; - /* What is the Status code?? need to check. */ - ADDframe.StatusCode = Status; - ADDframe.BaParm.BAPolicy = IMMED_BA; - ADDframe.BaParm.AMSDUSupported = 0; - ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID; - ADDframe.BaParm.BufSize = - min(((u8)pAddreqFrame->BaParm.BufSize), - (u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit); - if (ADDframe.BaParm.BufSize == 0) { - ADDframe.BaParm.BufSize = 64; - } - ADDframe.TimeOutValue = 0; /*pAddreqFrame->TimeOutValue; */ - - *(u16 *) (&ADDframe.BaParm) = - cpu2le16(*(u16 *) (&ADDframe.BaParm)); - ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode); - ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue); - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_frame_addba_rsp), &ADDframe, END_OF_ARGS); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - DBGPRINT(RT_DEBUG_TRACE, - ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid, - ADDframe.BaParm.TID, ADDframe.BaParm.BufSize)); -} - -void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - /*u8 Idx, i; */ - /*u8 * pOutBuffer = NULL; */ - struct rt_frame_addba_rsp * pFrame = NULL; - /*struct rt_ba_ori_entry *pBAEntry; */ - - /*ADDBA Response from unknown peer, ignore this. */ - if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) - return; - - DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __func__, Elem->Wcid)); - - /*hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen); */ - - if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen)) { - pFrame = (struct rt_frame_addba_rsp *) (&Elem->Msg[0]); - - DBGPRINT(RT_DEBUG_TRACE, - ("\t\t StatusCode = %d\n", pFrame->StatusCode)); - switch (pFrame->StatusCode) { - case 0: - /* I want a BAsession with this peer as an originator. */ - BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], - pFrame); - break; - default: - /* check status == USED ??? */ - BAOriSessionTearDown(pAd, Elem->Wcid, - pFrame->BaParm.TID, TRUE, FALSE); - break; - } - /* Rcv Decline StatusCode */ - if ((pFrame->StatusCode == 37) - || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) - && (pFrame->StatusCode != 0)) - ) { - pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= - 1 << pFrame->BaParm.TID; - } - } -} - -void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - /*u8 Idx; */ - /*u8 * pOutBuffer = NULL; */ - struct rt_frame_delba_req * pDelFrame = NULL; - - DBGPRINT(RT_DEBUG_TRACE, ("%s ==>\n", __func__)); - /*DELBA Request from unknown peer, ignore this. */ - if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen)) { - pDelFrame = (struct rt_frame_delba_req *) (&Elem->Msg[0]); - if (pDelFrame->DelbaParm.Initiator == ORIGINATOR) { - DBGPRINT(RT_DEBUG_TRACE, - ("BA - PeerDelBAAction----> ORIGINATOR\n")); - BARecSessionTearDown(pAd, Elem->Wcid, - pDelFrame->DelbaParm.TID, TRUE); - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", - pDelFrame->ReasonCode)); - /*hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen); */ - BAOriSessionTearDown(pAd, Elem->Wcid, - pDelFrame->DelbaParm.TID, TRUE, - FALSE); - } - } -} - -BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd, - unsigned long Wcid, - unsigned long MsgLen, struct rt_frame_ba_req * pMsg) -{ - struct rt_frame_ba_req * pFrame = pMsg; - /*PRTMP_REORDERBUF pBuffer; */ - /*PRTMP_REORDERBUF pDmaBuf; */ - struct rt_ba_rec_entry *pBAEntry; - /*BOOLEAN Result; */ - unsigned long Idx; - /*u8 NumRxPkt; */ - u8 TID; /*, i; */ - - TID = (u8)pFrame->BARControl.TID; - - DBGPRINT(RT_DEBUG_TRACE, - ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID)); - /*hex_dump("BAR", (char *)pFrame, MsgLen); */ - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return FALSE; - - /* First check the size, it MUST not exceed the mlme queue size */ - if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen); - return FALSE; - } else if (MsgLen != sizeof(struct rt_frame_ba_req)) { - DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen); - return FALSE; - } else if (MsgLen != sizeof(struct rt_frame_ba_req)) { - DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen); - return FALSE; - } - - if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8)) { - /* if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search. */ - Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - } else { - return FALSE; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, - pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq)); - - if (SEQ_SMALLER - (pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, - MAXSEQ)) { - /*DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq)); */ - ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, - pFrame->BAStartingSeq.field. - StartSeq); - pBAEntry->LastIndSeq = - (pFrame->BAStartingSeq.field.StartSeq == - 0) ? MAXSEQ : (pFrame->BAStartingSeq.field.StartSeq - 1); - } - /*ba_refresh_reordering_mpdus(pAd, pBAEntry); */ - return TRUE; -} - -/* -Description : Send PSMP Action frame If PSMP mode switches. -*/ -void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp) -{ - u8 *pOutBuffer = NULL; - int NStatus; - /*unsigned long Idx; */ - struct rt_frame_psmp_action Frame; - unsigned long FrameLen; - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_ERROR, - ("BA - MlmeADDBAAction() allocate memory failed \n")); - return; - } - - ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, - pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr); - - Frame.Category = CATEGORY_HT; - Frame.Action = SMPS_ACTION; - switch (Psmp) { - case MMPS_ENABLE: -#ifdef RT30xx - if (IS_RT30xx(pAd) - && (pAd->Antenna.field.RxPath > 1 - || pAd->Antenna.field.TxPath > 1)) { - RTMP_ASIC_MMPS_DISABLE(pAd); - } -#endif /* RT30xx // */ - Frame.Psmp = 0; - break; - case MMPS_DYNAMIC: - Frame.Psmp = 3; - break; - case MMPS_STATIC: -#ifdef RT30xx - if (IS_RT30xx(pAd) - && (pAd->Antenna.field.RxPath > 1 - || pAd->Antenna.field.TxPath > 1)) { - RTMP_ASIC_MMPS_ENABLE(pAd); - } -#endif /* RT30xx // */ - Frame.Psmp = 1; - break; - } - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_frame_psmp_action), &Frame, END_OF_ARGS); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_ERROR, ("HT - SendPSMPAction( %d ) \n", Frame.Psmp)); -} - -#define RADIO_MEASUREMENT_REQUEST_ACTION 0 - -struct PACKED rt_beacon_request { - u8 RegulatoryClass; - u8 ChannelNumber; - u16 RandomInterval; - u16 MeasurementDuration; - u8 MeasurementMode; - u8 BSSID[MAC_ADDR_LEN]; - u8 ReportingCondition; - u8 Threshold; - u8 SSIDIE[2]; /* 2 byte */ -}; - -struct PACKED rt_measurement_req { - u8 ID; - u8 Length; - u8 Token; - u8 RequestMode; - u8 Type; -}; - -void convert_reordering_packet_to_preAMSDU_or_802_3_packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, - u8 - FromWhichBSSID) -{ - void *pRxPkt; - u8 Header802_3[LENGTH_802_3]; - - /* 1. get 802.3 Header */ - /* 2. remove LLC */ - /* a. pointer pRxBlk->pData to payload */ - /* b. modify pRxBlk->DataSize */ - - RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); - - ASSERT(pRxBlk->pRxPacket); - pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); - - SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID)); - SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData); - SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize); - SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize); - - /* */ - /* copy 802.3 header, if necessary */ - /* */ - if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) { - { -#ifdef LINUX - NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), - Header802_3, LENGTH_802_3); -#endif - } - } -} - -#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \ - do \ - { \ - if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \ - { \ - Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \ - } \ - else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \ - { \ - Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \ - } \ - else \ - { \ - Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \ - } \ - } while (0); - -static void ba_enqueue_reordering_packet(struct rt_rtmp_adapter *pAd, - struct rt_ba_rec_entry *pBAEntry, - struct rt_rx_blk *pRxBlk, - u8 FromWhichBSSID) -{ - struct reordering_mpdu *mpdu_blk; - u16 Sequence = (u16)pRxBlk->pHeader->Sequence; - - mpdu_blk = ba_mpdu_blk_alloc(pAd); - if ((mpdu_blk != NULL) && (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) { - /* Write RxD buffer address & allocated buffer length */ - NdisAcquireSpinLock(&pBAEntry->RxReRingLock); - - mpdu_blk->Sequence = Sequence; - - mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU); - - convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, - pRxBlk, - FromWhichBSSID); - - STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); - - /* */ - /* it is necessary for reordering packet to record */ - /* which BSS it come from */ - /* */ - RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID); - - mpdu_blk->pPacket = pRxBlk->pRxPacket; - - if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) - == FALSE) { - /* had been already within reordering list */ - /* don't indicate */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_SUCCESS); - ba_mpdu_blk_free(pAd, mpdu_blk); - } - - ASSERT((0 <= pBAEntry->list.qlen) - && (pBAEntry->list.qlen <= pBAEntry->BAWinSize)); - NdisReleaseSpinLock(&pBAEntry->RxReRingLock); - } else { - DBGPRINT(RT_DEBUG_ERROR, - (" (%d) Can't allocate reordering mpdu blk\n", - pBAEntry->list.qlen)); - - /* - * flush all pending reordering mpdus - * and receiving mpdu to upper layer - * make tcp/ip to take care reordering mechanism - */ - /*ba_refresh_reordering_mpdus(pAd, pBAEntry); */ - ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence); - - pBAEntry->LastIndSeq = Sequence; - INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); - } -} - -/* - ========================================================================== - Description: - Indicate this packet to upper layer or put it into reordering buffer - - Parametrs: - pRxBlk : carry necessary packet info 802.11 format - FromWhichBSSID : the packet received from which BSS - - Return : - none - - Note : - the packet queued into reordering buffer need to cover to 802.3 format - or pre_AMSDU format - ========================================================================== - */ - -void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - u16 Idx; - struct rt_ba_rec_entry *pBAEntry = NULL; - u16 Sequence = pRxBlk->pHeader->Sequence; - unsigned long Now32; - u8 Wcid = pRxBlk->pRxWI->WirelessCliID; - u8 TID = pRxBlk->pRxWI->TID; - - if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) - && (pRxBlk->DataSize > MAX_RX_PKT_LEN)) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - - if (Wcid < MAX_LEN_OF_MAC_TABLE) { - Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; - if (Idx == 0) { - /* Rec BA Session had been torn down */ - INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); - return; - } - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - } else { - /* impossible ! */ - ASSERT(0); - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - - ASSERT(pBAEntry); - - /* update last rx time */ - NdisGetSystemUpTime(&Now32); - - pBAEntry->rcvSeq = Sequence; - - ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32); - pBAEntry->LastIndSeqAtTimer = Now32; - - /* */ - /* Reset Last Indicate Sequence */ - /* */ - if (pBAEntry->LastIndSeq == RESET_RCV_SEQ) { - ASSERT((pBAEntry->list.qlen == 0) - && (pBAEntry->list.next == NULL)); - - /* reset rcv sequence of BA session */ - pBAEntry->LastIndSeq = Sequence; - pBAEntry->LastIndSeqAtTimer = Now32; - INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); - return; - } - - /* */ - /* I. Check if in order. */ - /* */ - if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) { - u16 LastIndSeq; - - pBAEntry->LastIndSeq = Sequence; - INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); - LastIndSeq = - ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, - pBAEntry->LastIndSeq); - if (LastIndSeq != RESET_RCV_SEQ) { - pBAEntry->LastIndSeq = LastIndSeq; - } - pBAEntry->LastIndSeqAtTimer = Now32; - } - /* */ - /* II. Drop Duplicated Packet */ - /* */ - else if (Sequence == pBAEntry->LastIndSeq) { - - /* drop and release packet */ - pBAEntry->nDropPacket++; - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - } - /* */ - /* III. Drop Old Received Packet */ - /* */ - else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) { - - /* drop and release packet */ - pBAEntry->nDropPacket++; - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - } - /* */ - /* IV. Receive Sequence within Window Size */ - /* */ - else if (SEQ_SMALLER - (Sequence, - (((pBAEntry->LastIndSeq + pBAEntry->BAWinSize + 1)) & MAXSEQ), - MAXSEQ)) { - ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, - FromWhichBSSID); - } - /* */ - /* V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer */ - /* */ - else { - long WinStartSeq, TmpSeq; - - TmpSeq = Sequence - (pBAEntry->BAWinSize) - 1; - if (TmpSeq < 0) { - TmpSeq = (MAXSEQ + 1) + TmpSeq; - } - WinStartSeq = (TmpSeq + 1) & MAXSEQ; - ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq); - pBAEntry->LastIndSeq = WinStartSeq; /*TmpSeq; */ - - pBAEntry->LastIndSeqAtTimer = Now32; - - ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, - FromWhichBSSID); - - TmpSeq = - ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, - pBAEntry->LastIndSeq); - if (TmpSeq != RESET_RCV_SEQ) { - pBAEntry->LastIndSeq = TmpSeq; - } - } -} diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c deleted file mode 100644 index d70d229a6e53..000000000000 --- a/drivers/staging/rt2860/common/cmm_aes.c +++ /dev/null @@ -1,1311 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - cmm_aes.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Wu 02-25-02 Initial -*/ - -#include "../rt_config.h" - -struct aes_context { - u32 erk[64]; /* encryption round keys */ - u32 drk[64]; /* decryption round keys */ - int nr; /* number of rounds */ -}; - -/*****************************/ -/******** SBOX Table *********/ -/*****************************/ - -u8 SboxTable[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -void xor_32(u8 *a, u8 *b, u8 *out) -{ - int i; - - for (i = 0; i < 4; i++) { - out[i] = a[i] ^ b[i]; - } -} - -void xor_128(u8 *a, u8 *b, u8 *out) -{ - int i; - - for (i = 0; i < 16; i++) { - out[i] = a[i] ^ b[i]; - } -} - -u8 RTMPCkipSbox(u8 a) -{ - return SboxTable[(int)a]; -} - -void next_key(u8 *key, int round) -{ - u8 rcon; - u8 sbox_key[4]; - u8 rcon_table[12] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x36, 0x36 - }; - - sbox_key[0] = RTMPCkipSbox(key[13]); - sbox_key[1] = RTMPCkipSbox(key[14]); - sbox_key[2] = RTMPCkipSbox(key[15]); - sbox_key[3] = RTMPCkipSbox(key[12]); - - rcon = rcon_table[round]; - - xor_32(&key[0], sbox_key, &key[0]); - key[0] = key[0] ^ rcon; - - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -void byte_sub(u8 *in, u8 *out) -{ - int i; - - for (i = 0; i < 16; i++) { - out[i] = RTMPCkipSbox(in[i]); - } -} - -/************************************/ -/* bitwise_xor() */ -/* A 128 bit, bitwise exclusive or */ -/************************************/ - -void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out) -{ - int i; - for (i = 0; i < 16; i++) { - out[i] = ina[i] ^ inb[i]; - } -} - -void shift_row(u8 *in, u8 *out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -void mix_column(u8 *in, u8 *out) -{ - int i; - u8 add1b[4]; - u8 add1bf7[4]; - u8 rotl[4]; - u8 swap_halfs[4]; - u8 andf7[4]; - u8 rotr[4]; - u8 temp[4]; - u8 tempb[4]; - - for (i = 0; i < 4; i++) { - if ((in[i] & 0x80) == 0x80) - add1b[i] = 0x1b; - else - add1b[i] = 0x00; - } - - swap_halfs[0] = in[2]; /* Swap halfs */ - swap_halfs[1] = in[3]; - swap_halfs[2] = in[0]; - swap_halfs[3] = in[1]; - - rotl[0] = in[3]; /* Rotate left 8 bits */ - rotl[1] = in[0]; - rotl[2] = in[1]; - rotl[3] = in[2]; - - andf7[0] = in[0] & 0x7f; - andf7[1] = in[1] & 0x7f; - andf7[2] = in[2] & 0x7f; - andf7[3] = in[3] & 0x7f; - - for (i = 3; i > 0; i--) { /* logical shift left 1 bit */ - andf7[i] = andf7[i] << 1; - if ((andf7[i - 1] & 0x80) == 0x80) { - andf7[i] = (andf7[i] | 0x01); - } - } - andf7[0] = andf7[0] << 1; - andf7[0] = andf7[0] & 0xfe; - - xor_32(add1b, andf7, add1bf7); - - xor_32(in, add1bf7, rotr); - - temp[0] = rotr[0]; /* Rotate right 8 bits */ - rotr[0] = rotr[1]; - rotr[1] = rotr[2]; - rotr[2] = rotr[3]; - rotr[3] = temp[0]; - - xor_32(add1bf7, rotr, temp); - xor_32(swap_halfs, rotl, tempb); - xor_32(temp, tempb, out); -} - -/************************************************/ -/* construct_mic_header1() */ -/* Builds the first MIC header block from */ -/* header fields. */ -/************************************************/ - -void construct_mic_header1(unsigned char *mic_header1, - int header_length, unsigned char *mpdu) -{ - mic_header1[0] = (unsigned char)((header_length - 2) / 256); - mic_header1[1] = (unsigned char)((header_length - 2) % 256); - mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ - mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ - mic_header1[4] = mpdu[4]; /* A1 */ - mic_header1[5] = mpdu[5]; - mic_header1[6] = mpdu[6]; - mic_header1[7] = mpdu[7]; - mic_header1[8] = mpdu[8]; - mic_header1[9] = mpdu[9]; - mic_header1[10] = mpdu[10]; /* A2 */ - mic_header1[11] = mpdu[11]; - mic_header1[12] = mpdu[12]; - mic_header1[13] = mpdu[13]; - mic_header1[14] = mpdu[14]; - mic_header1[15] = mpdu[15]; -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ - -void construct_mic_header2(unsigned char *mic_header2, - unsigned char *mpdu, int a4_exists, int qc_exists) -{ - int i; - - for (i = 0; i < 16; i++) - mic_header2[i] = 0x00; - - mic_header2[0] = mpdu[16]; /* A3 */ - mic_header2[1] = mpdu[17]; - mic_header2[2] = mpdu[18]; - mic_header2[3] = mpdu[19]; - mic_header2[4] = mpdu[20]; - mic_header2[5] = mpdu[21]; - - /* In Sequence Control field, mute sequence numer bits (12-bit) */ - mic_header2[6] = mpdu[22] & 0x0f; /* SC */ - mic_header2[7] = 0x00; /* mpdu[23]; */ - - if ((!qc_exists) && a4_exists) { - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - - } - - if (qc_exists && (!a4_exists)) { - mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ - mic_header2[9] = mpdu[25] & 0x00; - } - - if (qc_exists && a4_exists) { - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - - mic_header2[14] = mpdu[30] & 0x0f; - mic_header2[15] = mpdu[31] & 0x00; - } -} - -/************************************************/ -/* construct_mic_iv() */ -/* Builds the MIC IV from header fields and PN */ -/************************************************/ - -void construct_mic_iv(unsigned char *mic_iv, - int qc_exists, - int a4_exists, - unsigned char *mpdu, - unsigned int payload_length, unsigned char *pn_vector) -{ - int i; - - mic_iv[0] = 0x59; - if (qc_exists && a4_exists) - mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ - if (qc_exists && !a4_exists) - mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ - if (!qc_exists) - mic_iv[1] = 0x00; - for (i = 2; i < 8; i++) - mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ -#ifdef CONSISTENT_PN_ORDER - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */ -#else - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ -#endif - mic_iv[14] = (unsigned char)(payload_length / 256); - mic_iv[15] = (unsigned char)(payload_length % 256); - -} - -/****************************************/ -/* aes128k128d() */ -/* Performs a 128 bit AES encrypt with */ -/* 128 bit data. */ -/****************************************/ -void aes128k128d(unsigned char *key, unsigned char *data, - unsigned char *ciphertext) -{ - int round; - int i; - unsigned char intermediatea[16]; - unsigned char intermediateb[16]; - unsigned char round_key[16]; - - for (i = 0; i < 16; i++) - round_key[i] = key[i]; - - for (round = 0; round < 11; round++) { - if (round == 0) { - xor_128(round_key, data, ciphertext); - next_key(round_key, round); - } else if (round == 10) { - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - xor_128(intermediateb, round_key, ciphertext); - } else { /* 1 - 9 */ - - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - mix_column(&intermediateb[0], &intermediatea[0]); - mix_column(&intermediateb[4], &intermediatea[4]); - mix_column(&intermediateb[8], &intermediatea[8]); - mix_column(&intermediateb[12], &intermediatea[12]); - xor_128(intermediatea, round_key, ciphertext); - next_key(round_key, round); - } - } - -} - -void construct_ctr_preload(unsigned char *ctr_preload, - int a4_exists, - int qc_exists, - unsigned char *mpdu, unsigned char *pn_vector, int c) -{ - - int i = 0; - for (i = 0; i < 16; i++) - ctr_preload[i] = 0x00; - i = 0; - - ctr_preload[0] = 0x01; /* flag */ - if (qc_exists && a4_exists) - ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ - if (qc_exists && !a4_exists) - ctr_preload[1] = mpdu[24] & 0x0f; - - for (i = 2; i < 8; i++) - ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ -#ifdef CONSISTENT_PN_ORDER - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */ -#else - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ -#endif - ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ - ctr_preload[15] = (unsigned char)(c % 256); - -} - -BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd, - u8 *pData, - unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey) -{ - u8 KeyID; - u32 HeaderLen; - u8 PN[6]; - u32 payload_len; - u32 num_blocks; - u32 payload_remainder; - u16 fc; - u8 fc0; - u8 fc1; - u32 frame_type; - u32 frame_subtype; - u32 from_ds; - u32 to_ds; - int a4_exists; - int qc_exists; - u8 aes_out[16]; - int payload_index; - u32 i; - u8 ctr_preload[16]; - u8 chain_buffer[16]; - u8 padded_buffer[16]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 MIC[8]; - u8 TrailMIC[8]; - - fc0 = *pData; - fc1 = *(pData + 1); - - fc = *((u16 *)pData); - - frame_type = ((fc0 >> 2) & 0x03); - frame_subtype = ((fc0 >> 4) & 0x0f); - - from_ds = (fc1 & 0x2) >> 1; - to_ds = (fc1 & 0x1); - - a4_exists = (from_ds & to_ds); - qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ - (frame_subtype == 0x09) || /* Likely to change. */ - (frame_subtype == 0x0a) || (frame_subtype == 0x0b) - ); - - HeaderLen = 24; - if (a4_exists) - HeaderLen += 6; - - KeyID = *((u8 *)(pData + HeaderLen + 3)); - KeyID = KeyID >> 6; - - if (pWpaKey[KeyID].KeyLen == 0) { - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", - KeyID)); - return FALSE; - } - - PN[0] = *(pData + HeaderLen); - PN[1] = *(pData + HeaderLen + 1); - PN[2] = *(pData + HeaderLen + 4); - PN[3] = *(pData + HeaderLen + 5); - PN[4] = *(pData + HeaderLen + 6); - PN[5] = *(pData + HeaderLen + 7); - - payload_len = DataByteCnt - HeaderLen - 8 - 8; /* 8 bytes for CCMP header , 8 bytes for MIC */ - payload_remainder = (payload_len) % 16; - num_blocks = (payload_len) / 16; - - /* Find start of payload */ - payload_index = HeaderLen + 8; /*IV+EIV */ - - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, - a4_exists, qc_exists, pData, PN, i + 1); - - aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); - - bitwise_xor(aes_out, pData + payload_index, chain_buffer); - NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16); - payload_index += 16; - } - - /* */ - /* If there is a short final block, then pad it */ - /* encrypt it and copy the unpadded part back */ - /* */ - if (payload_remainder > 0) { - construct_ctr_preload(ctr_preload, - a4_exists, - qc_exists, pData, PN, num_blocks + 1); - - NdisZeroMemory(padded_buffer, 16); - NdisMoveMemory(padded_buffer, pData + payload_index, - payload_remainder); - - aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); - - bitwise_xor(aes_out, padded_buffer, chain_buffer); - NdisMoveMemory(pData + payload_index - 8, chain_buffer, - payload_remainder); - payload_index += payload_remainder; - } - /* */ - /* Descrypt the MIC */ - /* */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pData, PN, 0); - NdisZeroMemory(padded_buffer, 16); - NdisMoveMemory(padded_buffer, pData + payload_index, 8); - - aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); - - bitwise_xor(aes_out, padded_buffer, chain_buffer); - - NdisMoveMemory(TrailMIC, chain_buffer, 8); - - /* */ - /* Calculate MIC */ - /* */ - - /*Force the protected frame bit on */ - *(pData + 1) = *(pData + 1) | 0x40; - - /* Find start of payload */ - /* Because the CCMP header has been removed */ - payload_index = HeaderLen; - - construct_mic_iv(mic_iv, qc_exists, a4_exists, pData, payload_len, PN); - - construct_mic_header1(mic_header1, HeaderLen, pData); - - construct_mic_header2(mic_header2, pData, a4_exists, qc_exists); - - aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - - /* iterate through each 16 byte payload block */ - for (i = 0; i < num_blocks; i++) { - bitwise_xor(aes_out, pData + payload_index, chain_buffer); - payload_index += 16; - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - } - - /* Add on the final payload block if it needs padding */ - if (payload_remainder > 0) { - NdisZeroMemory(padded_buffer, 16); - NdisMoveMemory(padded_buffer, pData + payload_index, - payload_remainder); - - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - } - /* aes_out contains padded mic, discard most significant */ - /* 8 bytes to generate 64 bit MIC */ - for (i = 0; i < 8; i++) - MIC[i] = aes_out[i]; - - if (!NdisEqualMemory(MIC, TrailMIC, 8)) { - DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); /*MIC error. */ - return FALSE; - } - - return TRUE; -} - -/* ========================= AES En/Decryption ========================== */ -#ifndef uint8 -#define uint8 unsigned char -#endif - -#ifndef uint32 -#define uint32 unsigned int -#endif - -/* forward S-box */ -static uint32 FSb[256] = { - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* forward table */ -#define FT \ -\ - V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ - V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ - V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ - V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ - V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ - V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ - V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ - V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ - V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ - V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ - V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ - V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ - V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ - V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ - V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ - V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ - V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ - V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ - V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ - V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ - V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ - V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ - V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ - V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ - V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ - V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ - V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ - V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ - V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ - V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ - V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ - V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ - V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ - V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ - V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ - V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ - V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ - V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ - V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ - V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ - V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ - V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ - V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ - V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ - V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ - V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ - V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ - V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ - V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ - V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ - V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ - V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ - V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ - V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ - V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ - V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ - V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ - V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ - V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ - V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ - V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ - V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ - V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ - V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) - -#define V(a,b,c,d) 0x##a##b##c##d -static uint32 FT0[256] = { FT }; - -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static uint32 FT1[256] = { FT }; - -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static uint32 FT2[256] = { FT }; - -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static uint32 FT3[256] = { FT }; - -#undef V - -#undef FT - -/* reverse S-box */ - -static uint32 RSb[256] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* reverse table */ - -#define RT \ -\ - V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ - V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ - V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ - V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ - V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ - V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ - V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ - V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ - V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ - V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ - V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ - V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ - V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ - V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ - V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ - V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ - V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ - V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ - V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ - V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ - V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ - V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ - V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ - V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ - V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ - V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ - V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ - V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ - V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ - V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ - V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ - V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ - V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ - V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ - V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ - V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ - V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ - V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ - V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ - V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ - V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ - V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ - V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ - V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ - V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ - V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ - V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ - V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ - V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ - V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ - V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ - V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ - V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ - V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ - V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ - V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ - V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ - V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ - V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ - V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ - V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ - V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ - V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ - V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) - -#define V(a,b,c,d) 0x##a##b##c##d -static uint32 RT0[256] = { RT }; - -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static uint32 RT1[256] = { RT }; - -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static uint32 RT2[256] = { RT }; - -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static uint32 RT3[256] = { RT }; - -#undef V - -#undef RT - -/* round constants */ - -static uint32 RCON[10] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000 -}; - -/* key schedule tables */ - -static int KT_init = 1; - -static uint32 KT0[256]; -static uint32 KT1[256]; -static uint32 KT2[256]; -static uint32 KT3[256]; - -/* platform-independent 32-bit integer manipulation macros */ - -#define GET_UINT32(n,b,i) \ -{ \ - (n) = ( (uint32) (b)[(i) ] << 24 ) \ - | ( (uint32) (b)[(i) + 1] << 16 ) \ - | ( (uint32) (b)[(i) + 2] << 8 ) \ - | ( (uint32) (b)[(i) + 3] ); \ -} - -#define PUT_UINT32(n,b,i) \ -{ \ - (b)[(i) ] = (uint8) ( (n) >> 24 ); \ - (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ - (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ - (b)[(i) + 3] = (uint8) ( (n) ); \ -} - -int rt_aes_set_key(struct aes_context * ctx, uint8 * key, int nbits) -{ - int i; - uint32 *RK, *SK; - - switch (nbits) { - case 128: - ctx->nr = 10; - break; - case 192: - ctx->nr = 12; - break; - case 256: - ctx->nr = 14; - break; - default: - return (1); - } - - RK = (uint32 *) ctx->erk; - - for (i = 0; i < (nbits >> 5); i++) { - GET_UINT32(RK[i], key, i * 4); - } - - /* setup encryption round keys */ - - switch (nbits) { - case 128: - - for (i = 0; i < 10; i++, RK += 4) { - RK[4] = RK[0] ^ RCON[i] ^ - (FSb[(uint8) (RK[3] >> 16)] << 24) ^ - (FSb[(uint8) (RK[3] >> 8)] << 16) ^ - (FSb[(uint8) (RK[3])] << 8) ^ - (FSb[(uint8) (RK[3] >> 24)]); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 192: - - for (i = 0; i < 8; i++, RK += 6) { - RK[6] = RK[0] ^ RCON[i] ^ - (FSb[(uint8) (RK[5] >> 16)] << 24) ^ - (FSb[(uint8) (RK[5] >> 8)] << 16) ^ - (FSb[(uint8) (RK[5])] << 8) ^ - (FSb[(uint8) (RK[5] >> 24)]); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 256: - - for (i = 0; i < 7; i++, RK += 8) { - RK[8] = RK[0] ^ RCON[i] ^ - (FSb[(uint8) (RK[7] >> 16)] << 24) ^ - (FSb[(uint8) (RK[7] >> 8)] << 16) ^ - (FSb[(uint8) (RK[7])] << 8) ^ - (FSb[(uint8) (RK[7] >> 24)]); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - (FSb[(uint8) (RK[11] >> 24)] << 24) ^ - (FSb[(uint8) (RK[11] >> 16)] << 16) ^ - (FSb[(uint8) (RK[11] >> 8)] << 8) ^ - (FSb[(uint8) (RK[11])]); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - } - - /* setup decryption round keys */ - - if (KT_init) { - for (i = 0; i < 256; i++) { - KT0[i] = RT0[FSb[i]]; - KT1[i] = RT1[FSb[i]]; - KT2[i] = RT2[FSb[i]]; - KT3[i] = RT3[FSb[i]]; - } - - KT_init = 0; - } - - SK = (uint32 *) ctx->drk; - - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - - for (i = 1; i < ctx->nr; i++) { - RK -= 8; - - *SK++ = KT0[(uint8) (*RK >> 24)] ^ - KT1[(uint8) (*RK >> 16)] ^ - KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)]; - RK++; - - *SK++ = KT0[(uint8) (*RK >> 24)] ^ - KT1[(uint8) (*RK >> 16)] ^ - KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)]; - RK++; - - *SK++ = KT0[(uint8) (*RK >> 24)] ^ - KT1[(uint8) (*RK >> 16)] ^ - KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)]; - RK++; - - *SK++ = KT0[(uint8) (*RK >> 24)] ^ - KT1[(uint8) (*RK >> 16)] ^ - KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)]; - RK++; - } - - RK -= 8; - - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - - return (0); -} - -/* AES 128-bit block encryption routine */ - -void rt_aes_encrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16]) -{ - uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = (uint32 *) ctx->erk; - GET_UINT32(X0, input, 0); - X0 ^= RK[0]; - GET_UINT32(X1, input, 4); - X1 ^= RK[1]; - GET_UINT32(X2, input, 8); - X2 ^= RK[2]; - GET_UINT32(X3, input, 12); - X3 ^= RK[3]; - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - RK += 4; \ - \ - X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y3 ) ]; \ - \ - X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y0 ) ]; \ - \ - X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y1 ) ]; \ - \ - X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y2 ) ]; \ -} - - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */ - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */ - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */ - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */ - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */ - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */ - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */ - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */ - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */ - - if (ctx->nr > 10) { - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */ - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */ - } - - if (ctx->nr > 12) { - AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */ - AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */ - } - - /* last round */ - - RK += 4; - - X0 = RK[0] ^ (FSb[(uint8) (Y0 >> 24)] << 24) ^ - (FSb[(uint8) (Y1 >> 16)] << 16) ^ - (FSb[(uint8) (Y2 >> 8)] << 8) ^ (FSb[(uint8) (Y3)]); - - X1 = RK[1] ^ (FSb[(uint8) (Y1 >> 24)] << 24) ^ - (FSb[(uint8) (Y2 >> 16)] << 16) ^ - (FSb[(uint8) (Y3 >> 8)] << 8) ^ (FSb[(uint8) (Y0)]); - - X2 = RK[2] ^ (FSb[(uint8) (Y2 >> 24)] << 24) ^ - (FSb[(uint8) (Y3 >> 16)] << 16) ^ - (FSb[(uint8) (Y0 >> 8)] << 8) ^ (FSb[(uint8) (Y1)]); - - X3 = RK[3] ^ (FSb[(uint8) (Y3 >> 24)] << 24) ^ - (FSb[(uint8) (Y0 >> 16)] << 16) ^ - (FSb[(uint8) (Y1 >> 8)] << 8) ^ (FSb[(uint8) (Y2)]); - - PUT_UINT32(X0, output, 0); - PUT_UINT32(X1, output, 4); - PUT_UINT32(X2, output, 8); - PUT_UINT32(X3, output, 12); -} - -/* AES 128-bit block decryption routine */ - -void rt_aes_decrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16]) -{ - uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = (uint32 *) ctx->drk; - - GET_UINT32(X0, input, 0); - X0 ^= RK[0]; - GET_UINT32(X1, input, 4); - X1 ^= RK[1]; - GET_UINT32(X2, input, 8); - X2 ^= RK[2]; - GET_UINT32(X3, input, 12); - X3 ^= RK[3]; - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - RK += 4; \ - \ - X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y1 ) ]; \ - \ - X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y2 ) ]; \ - \ - X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y3 ) ]; \ - \ - X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y0 ) ]; \ -} - - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */ - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */ - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */ - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */ - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */ - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */ - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */ - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */ - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */ - - if (ctx->nr > 10) { - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */ - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */ - } - - if (ctx->nr > 12) { - AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */ - AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */ - } - - /* last round */ - - RK += 4; - - X0 = RK[0] ^ (RSb[(uint8) (Y0 >> 24)] << 24) ^ - (RSb[(uint8) (Y3 >> 16)] << 16) ^ - (RSb[(uint8) (Y2 >> 8)] << 8) ^ (RSb[(uint8) (Y1)]); - - X1 = RK[1] ^ (RSb[(uint8) (Y1 >> 24)] << 24) ^ - (RSb[(uint8) (Y0 >> 16)] << 16) ^ - (RSb[(uint8) (Y3 >> 8)] << 8) ^ (RSb[(uint8) (Y2)]); - - X2 = RK[2] ^ (RSb[(uint8) (Y2 >> 24)] << 24) ^ - (RSb[(uint8) (Y1 >> 16)] << 16) ^ - (RSb[(uint8) (Y0 >> 8)] << 8) ^ (RSb[(uint8) (Y3)]); - - X3 = RK[3] ^ (RSb[(uint8) (Y3 >> 24)] << 24) ^ - (RSb[(uint8) (Y2 >> 16)] << 16) ^ - (RSb[(uint8) (Y1 >> 8)] << 8) ^ (RSb[(uint8) (Y0)]); - - PUT_UINT32(X0, output, 0); - PUT_UINT32(X1, output, 4); - PUT_UINT32(X2, output, 8); - PUT_UINT32(X3, output, 12); -} - -/* - ========================================================================== - Description: - ENCRYPT AES GTK before sending in EAPOL frame. - AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function. - This function references to RFC 3394 for aes key wrap algorithm. - Return: - ========================================================================== -*/ -void AES_GTK_KEY_WRAP(u8 * key, - u8 * plaintext, - u32 p_len, u8 * ciphertext) -{ - u8 A[8], BIN[16], BOUT[16]; - u8 R[512]; - int num_blocks = p_len / 8; /* unit:64bits */ - int i, j; - struct aes_context aesctx; - u8 xor; - - rt_aes_set_key(&aesctx, key, 128); - - /* Init IA */ - for (i = 0; i < 8; i++) - A[i] = 0xa6; - - /*Input plaintext */ - for (i = 0; i < num_blocks; i++) { - for (j = 0; j < 8; j++) - R[8 * (i + 1) + j] = plaintext[8 * i + j]; - } - - /* Key Mix */ - for (j = 0; j < 6; j++) { - for (i = 1; i <= num_blocks; i++) { - /*phase 1 */ - NdisMoveMemory(BIN, A, 8); - NdisMoveMemory(&BIN[8], &R[8 * i], 8); - rt_aes_encrypt(&aesctx, BIN, BOUT); - - NdisMoveMemory(A, &BOUT[0], 8); - xor = num_blocks * j + i; - A[7] = BOUT[7] ^ xor; - NdisMoveMemory(&R[8 * i], &BOUT[8], 8); - } - } - - /* Output ciphertext */ - NdisMoveMemory(ciphertext, A, 8); - - for (i = 1; i <= num_blocks; i++) { - for (j = 0; j < 8; j++) - ciphertext[8 * i + j] = R[8 * i + j]; - } -} - -/* - ======================================================================== - - Routine Description: - Misc function to decrypt AES body - - Arguments: - - Return Value: - - Note: - This function references to RFC 3394 for aes key unwrap algorithm. - - ======================================================================== -*/ -void AES_GTK_KEY_UNWRAP(u8 * key, - u8 * plaintext, - u32 c_len, u8 * ciphertext) -{ - u8 A[8], BIN[16], BOUT[16]; - u8 xor; - int i, j; - struct aes_context aesctx; - u8 *R; - int num_blocks = c_len / 8; /* unit:64bits */ - - os_alloc_mem(NULL, (u8 **) & R, 512); - - if (R == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("AES_GTK_KEY_UNWRAP: no memory!\n")); - return; - } - /* End of if */ - /* Initialize */ - NdisMoveMemory(A, ciphertext, 8); - /*Input plaintext */ - for (i = 0; i < (c_len - 8); i++) { - R[i] = ciphertext[i + 8]; - } - - rt_aes_set_key(&aesctx, key, 128); - - for (j = 5; j >= 0; j--) { - for (i = (num_blocks - 1); i > 0; i--) { - xor = (num_blocks - 1) * j + i; - NdisMoveMemory(BIN, A, 8); - BIN[7] = A[7] ^ xor; - NdisMoveMemory(&BIN[8], &R[(i - 1) * 8], 8); - rt_aes_decrypt(&aesctx, BIN, BOUT); - NdisMoveMemory(A, &BOUT[0], 8); - NdisMoveMemory(&R[(i - 1) * 8], &BOUT[8], 8); - } - } - - /* OUTPUT */ - for (i = 0; i < c_len; i++) { - plaintext[i] = R[i]; - } - - os_free_mem(NULL, R); -} diff --git a/drivers/staging/rt2860/common/cmm_asic.c b/drivers/staging/rt2860/common/cmm_asic.c deleted file mode 100644 index 4d77e83eb418..000000000000 --- a/drivers/staging/rt2860/common/cmm_asic.c +++ /dev/null @@ -1,2565 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - cmm_asic.c - - Abstract: - Functions used to communicate with ASIC - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -/* Reset the RFIC setting to new series */ -struct rt_rtmp_rf_regs RF2850RegTable[] = { -/* ch R1 R2 R3(TX0~4=0) R4 */ - {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b} - , - {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f} - , - {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b} - , - {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f} - , - {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b} - , - {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f} - , - {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b} - , - {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f} - , - {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b} - , - {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f} - , - {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b} - , - {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f} - , - {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b} - , - {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193} - , - - /* 802.11 UNI / HyperLan 2 */ - {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3} - , - {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193} - , - {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183} - , - {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3} - , - {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b} - , - {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b} - , - {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193} - , - {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3} - , - {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b} - , - {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183} - , - {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193} - , - {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3} - , /* Plugfest#4, Day4, change RFR3 left4th 9->5. */ - - /* 802.11 HyperLan 2 */ - {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783} - , - - /* 2008.04.30 modified */ - /* The system team has AN to improve the EVM value */ - /* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */ - {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793} - , - {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3} - , - {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193} - , - - {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183} - , - {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b} - , - {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3} - , - {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193} - , - {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183} - , - {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193} - , - {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b} - , /* 0x980ed1bb->0x980ed15b required by Rory 20070927 */ - {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3} - , - {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b} - , - {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193} - , - {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b} - , - {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183} - , - - /* 802.11 UNII */ - {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7} - , - {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187} - , - {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f} - , - {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f} - , - {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7} - , - {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187} - , - {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197} - , - {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f} - , - {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327} - , - {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307} - , - {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f} - , - - /* Japan */ - {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b} - , - {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13} - , - {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b} - , - {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23} - , - {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13} - , - {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b} - , - {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23} - , - - /* still lack of MMAC(Japan) ch 34,38,42,46 */ -}; - -u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs)); - -struct rt_frequency_item FreqItems3020[] = { - /**************************************************/ - /* ISM : 2.4 to 2.483 GHz // */ - /**************************************************/ - /* 11g */ - /**************************************************/ - /*-CH---N-------R---K----------- */ - {1, 241, 2, 2} - , - {2, 241, 2, 7} - , - {3, 242, 2, 2} - , - {4, 242, 2, 7} - , - {5, 243, 2, 2} - , - {6, 243, 2, 7} - , - {7, 244, 2, 2} - , - {8, 244, 2, 7} - , - {9, 245, 2, 2} - , - {10, 245, 2, 7} - , - {11, 246, 2, 2} - , - {12, 246, 2, 7} - , - {13, 247, 2, 2} - , - {14, 248, 2, 4} - , -}; - -u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item)); - -void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable) -{ - u8 i; - HT_FBK_CFG0_STRUC HtCfg0; - HT_FBK_CFG1_STRUC HtCfg1; - LG_FBK_CFG0_STRUC LgCfg0; - LG_FBK_CFG1_STRUC LgCfg1; - struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate; - - /* set to initial value */ - HtCfg0.word = 0x65432100; - HtCfg1.word = 0xedcba988; - LgCfg0.word = 0xedcba988; - LgCfg1.word = 0x00002100; - - pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1; - for (i = 1; i < *((u8 *)pRateTable); i++) { - pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i; - switch (pCurrTxRate->Mode) { - case 0: /*CCK */ - break; - case 1: /*OFDM */ - { - switch (pCurrTxRate->CurrMCS) { - case 0: - LgCfg0.field.OFDMMCS0FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 1: - LgCfg0.field.OFDMMCS1FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 2: - LgCfg0.field.OFDMMCS2FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 3: - LgCfg0.field.OFDMMCS3FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 4: - LgCfg0.field.OFDMMCS4FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 5: - LgCfg0.field.OFDMMCS5FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 6: - LgCfg0.field.OFDMMCS6FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - case 7: - LgCfg0.field.OFDMMCS7FBK = - (pNextTxRate->Mode == - MODE_OFDM) ? (pNextTxRate-> - CurrMCS + - 8) : pNextTxRate-> - CurrMCS; - break; - } - } - break; - case 2: /*HT-MIX */ - case 3: /*HT-GF */ - { - if ((pNextTxRate->Mode >= MODE_HTMIX) - && (pCurrTxRate->CurrMCS != - pNextTxRate->CurrMCS)) { - switch (pCurrTxRate->CurrMCS) { - case 0: - HtCfg0.field.HTMCS0FBK = - pNextTxRate->CurrMCS; - break; - case 1: - HtCfg0.field.HTMCS1FBK = - pNextTxRate->CurrMCS; - break; - case 2: - HtCfg0.field.HTMCS2FBK = - pNextTxRate->CurrMCS; - break; - case 3: - HtCfg0.field.HTMCS3FBK = - pNextTxRate->CurrMCS; - break; - case 4: - HtCfg0.field.HTMCS4FBK = - pNextTxRate->CurrMCS; - break; - case 5: - HtCfg0.field.HTMCS5FBK = - pNextTxRate->CurrMCS; - break; - case 6: - HtCfg0.field.HTMCS6FBK = - pNextTxRate->CurrMCS; - break; - case 7: - HtCfg0.field.HTMCS7FBK = - pNextTxRate->CurrMCS; - break; - case 8: - HtCfg1.field.HTMCS8FBK = - pNextTxRate->CurrMCS; - break; - case 9: - HtCfg1.field.HTMCS9FBK = - pNextTxRate->CurrMCS; - break; - case 10: - HtCfg1.field.HTMCS10FBK = - pNextTxRate->CurrMCS; - break; - case 11: - HtCfg1.field.HTMCS11FBK = - pNextTxRate->CurrMCS; - break; - case 12: - HtCfg1.field.HTMCS12FBK = - pNextTxRate->CurrMCS; - break; - case 13: - HtCfg1.field.HTMCS13FBK = - pNextTxRate->CurrMCS; - break; - case 14: - HtCfg1.field.HTMCS14FBK = - pNextTxRate->CurrMCS; - break; - case 15: - HtCfg1.field.HTMCS15FBK = - pNextTxRate->CurrMCS; - break; - default: - DBGPRINT(RT_DEBUG_ERROR, - ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", - pCurrTxRate-> - CurrMCS)); - } - } - } - break; - } - - pNextTxRate = pCurrTxRate; - } - - RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word); - RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word); - RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word); - RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word); -} - -/* - ======================================================================== - - Routine Description: - Set MAC register value according operation mode. - OperationMode AND bNonGFExist are for MM and GF Proteciton. - If MM or GF mask is not set, those passing argument doesn't not take effect. - - Operation mode meaning: - = 0 : Pure HT, no preotection. - = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS. - = 0x10: No Transmission in 40M is protected. - = 0x11: Transmission in both 40M and 20M shall be protected - if (bNonGFExist) - we should choose not to use GF. But still set correct ASIC registers. - ======================================================================== -*/ -void AsicUpdateProtect(struct rt_rtmp_adapter *pAd, - u16 OperationMode, - u8 SetMask, - IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist) -{ - PROT_CFG_STRUC ProtCfg, ProtCfg4; - u32 Protect[6]; - u16 offset; - u8 i; - u32 MacReg = 0; - - if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) { - return; - } - - if (pAd->BATable.numDoneOriginator) { - /* */ - /* enable the RTS/CTS to avoid channel collision */ - /* */ - SetMask = ALLN_SETPROTECT; - OperationMode = 8; - } - /* Config ASIC RTS threshold register */ - RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg); - MacReg &= 0xFF0000FF; - /* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */ - if (((pAd->CommonCfg.BACapability.field.AmsduEnable) || - (pAd->CommonCfg.bAggregationCapable == TRUE)) - && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) { - MacReg |= (0x1000 << 8); - } else { - MacReg |= (pAd->CommonCfg.RtsThreshold << 8); - } - - RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg); - - /* Initial common protection settings */ - RTMPZeroMemory(Protect, sizeof(Protect)); - ProtCfg4.word = 0; - ProtCfg.word = 0; - ProtCfg.field.TxopAllowGF40 = 1; - ProtCfg.field.TxopAllowGF20 = 1; - ProtCfg.field.TxopAllowMM40 = 1; - ProtCfg.field.TxopAllowMM20 = 1; - ProtCfg.field.TxopAllowOfdm = 1; - ProtCfg.field.TxopAllowCck = 1; - ProtCfg.field.RTSThEn = 1; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - - /* update PHY mode and rate */ - if (pAd->CommonCfg.Channel > 14) - ProtCfg.field.ProtectRate = 0x4000; - ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate; - - /* Handle legacy(B/G) protection */ - if (bDisableBGProtect) { - /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */ - ProtCfg.field.ProtectCtrl = 0; - Protect[0] = ProtCfg.word; - Protect[1] = ProtCfg.word; - pAd->FlgCtsEnabled = 0; /* CTS-self is not used */ - } else { - /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */ - ProtCfg.field.ProtectCtrl = 0; /* CCK do not need to be protected */ - Protect[0] = ProtCfg.word; - ProtCfg.field.ProtectCtrl = ASIC_CTS; /* OFDM needs using CCK to protect */ - Protect[1] = ProtCfg.word; - pAd->FlgCtsEnabled = 1; /* CTS-self is used */ - } - - /* Decide HT frame protection. */ - if ((SetMask & ALLN_SETPROTECT) != 0) { - switch (OperationMode) { - case 0x0: - /* NO PROTECT */ - /* 1.All STAs in the BSS are 20/40 MHz HT */ - /* 2. in ai 20/40MHz BSS */ - /* 3. all STAs are 20MHz in a 20MHz BSS */ - /* Pure HT. no protection. */ - - /* MM20_PROT_CFG */ - /* Reserved (31:27) */ - /* PROT_TXOP(25:20) -- 010111 */ - /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ - /* PROT_CTRL(17:16) -- 00 (None) */ - /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M) */ - Protect[2] = 0x01744004; - - /* MM40_PROT_CFG */ - /* Reserved (31:27) */ - /* PROT_TXOP(25:20) -- 111111 */ - /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ - /* PROT_CTRL(17:16) -- 00 (None) */ - /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) */ - Protect[3] = 0x03f44084; - - /* CF20_PROT_CFG */ - /* Reserved (31:27) */ - /* PROT_TXOP(25:20) -- 010111 */ - /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ - /* PROT_CTRL(17:16) -- 00 (None) */ - /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M) */ - Protect[4] = 0x01744004; - - /* CF40_PROT_CFG */ - /* Reserved (31:27) */ - /* PROT_TXOP(25:20) -- 111111 */ - /* PROT_NAV(19:18) -- 01 (Short NAV protection) */ - /* PROT_CTRL(17:16) -- 00 (None) */ - /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) */ - Protect[5] = 0x03f44084; - - if (bNonGFExist) { - /* PROT_NAV(19:18) -- 01 (Short NAV protectiion) */ - /* PROT_CTRL(17:16) -- 01 (RTS/CTS) */ - Protect[4] = 0x01754004; - Protect[5] = 0x03f54084; - } - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; - break; - - case 1: - /* This is "HT non-member protection mode." */ - /* If there may be non-HT STAs my BSS */ - ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None) */ - ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1. */ - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { - ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18.. */ - ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */ - } - /*Assign Protection method for 20&40 MHz packets */ - ProtCfg.field.ProtectCtrl = ASIC_RTS; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - ProtCfg4.field.ProtectCtrl = ASIC_RTS; - ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; - Protect[2] = ProtCfg.word; - Protect[3] = ProtCfg4.word; - Protect[4] = ProtCfg.word; - Protect[5] = ProtCfg4.word; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; - break; - - case 2: - /* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */ - ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None) */ - ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1. */ - - /*Assign Protection method for 40MHz packets */ - ProtCfg4.field.ProtectCtrl = ASIC_RTS; - ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; - Protect[2] = ProtCfg.word; - Protect[3] = ProtCfg4.word; - if (bNonGFExist) { - ProtCfg.field.ProtectCtrl = ASIC_RTS; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - } - Protect[4] = ProtCfg.word; - Protect[5] = ProtCfg4.word; - - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; - break; - - case 3: - /* HT mixed mode. PROTECT ALL! */ - /* Assign Rate */ - ProtCfg.word = 0x01744004; /*duplicaet legacy 24M. BW set 1. */ - ProtCfg4.word = 0x03f44084; - /* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */ - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { - ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18.. */ - ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */ - } - /*Assign Protection method for 20&40 MHz packets */ - ProtCfg.field.ProtectCtrl = ASIC_RTS; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - ProtCfg4.field.ProtectCtrl = ASIC_RTS; - ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; - Protect[2] = ProtCfg.word; - Protect[3] = ProtCfg4.word; - Protect[4] = ProtCfg.word; - Protect[5] = ProtCfg4.word; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; - break; - - case 8: - /* Special on for Atheros problem n chip. */ - Protect[2] = 0x01754004; - Protect[3] = 0x03f54084; - Protect[4] = 0x01754004; - Protect[5] = 0x03f54084; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; - break; - } - } - - offset = CCK_PROT_CFG; - for (i = 0; i < 6; i++) { - if ((SetMask & (1 << i))) { - RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]); - } - } -} - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan) -{ - unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; - char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */ - u8 index; - u32 Value = 0; /*BbpReg, Value; */ - struct rt_rtmp_rf_regs *RFRegTable; - u8 RFValue; - - RFValue = 0; - /* Search Tx power value */ - /* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */ - /* in ChannelList, so use TxPower array instead. */ - /* */ - for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) { - if (Channel == pAd->TxPower[index].Channel) { - TxPwer = pAd->TxPower[index].Power; - TxPwer2 = pAd->TxPower[index].Power2; - break; - } - } - - if (index == MAX_NUM_OF_CHANNELS) { - DBGPRINT(RT_DEBUG_ERROR, - ("AsicSwitchChannel: Can't find the Channel#%d \n", - Channel)); - } -#ifdef RT30xx - /* The RF programming sequence is difference between 3xxx and 2xxx */ - if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd)) - && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) - || (pAd->RfIcType == RFIC_3021) - || (pAd->RfIcType == RFIC_3022))) { - /* modify by WY for Read RF Reg. error */ - - for (index = 0; index < NUM_OF_3020_CHNL; index++) { - if (Channel == FreqItems3020[index].Channel) { - /* Programming channel parameters */ - RT30xxWriteRFRegister(pAd, RF_R02, - FreqItems3020[index].N); - RT30xxWriteRFRegister(pAd, RF_R03, - FreqItems3020[index].K); - RT30xxReadRFRegister(pAd, RF_R06, &RFValue); - RFValue = - (RFValue & 0xFC) | FreqItems3020[index].R; - RT30xxWriteRFRegister(pAd, RF_R06, RFValue); - - /* Set Tx0 Power */ - RT30xxReadRFRegister(pAd, RF_R12, &RFValue); - RFValue = (RFValue & 0xE0) | TxPwer; - RT30xxWriteRFRegister(pAd, RF_R12, RFValue); - - /* Set Tx1 Power */ - RT30xxReadRFRegister(pAd, RF_R13, &RFValue); - RFValue = (RFValue & 0xE0) | TxPwer2; - RT30xxWriteRFRegister(pAd, RF_R13, RFValue); - - /* Tx/Rx Stream setting */ - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - /*if (IS_RT3090(pAd)) */ - /* RFValue |= 0x01; // Enable RF block. */ - RFValue &= 0x03; /*clear bit[7~2] */ - if (pAd->Antenna.field.TxPath == 1) - RFValue |= 0xA0; - else if (pAd->Antenna.field.TxPath == 2) - RFValue |= 0x80; - if (pAd->Antenna.field.RxPath == 1) - RFValue |= 0x50; - else if (pAd->Antenna.field.RxPath == 2) - RFValue |= 0x40; - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - /* Set RF offset */ - RT30xxReadRFRegister(pAd, RF_R23, &RFValue); - RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; - RT30xxWriteRFRegister(pAd, RF_R23, RFValue); - - /* Set BW */ - if (!bScan - && (pAd->CommonCfg.BBPCurrentBW == BW_40)) { - RFValue = pAd->Mlme.CaliBW40RfR24; - /*DISABLE_11N_CHECK(pAd); */ - } else { - RFValue = pAd->Mlme.CaliBW20RfR24; - } - RT30xxWriteRFRegister(pAd, RF_R24, RFValue); - RT30xxWriteRFRegister(pAd, RF_R31, RFValue); - - /* Enable RF tuning */ - RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue = RFValue | 0x1; - RT30xxWriteRFRegister(pAd, RF_R07, RFValue); - - /* latch channel for future usage. */ - pAd->LatchRfRegs.Channel = Channel; - - DBGPRINT(RT_DEBUG_TRACE, - ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", - Channel, pAd->RfIcType, TxPwer, - TxPwer2, pAd->Antenna.field.TxPath, - FreqItems3020[index].N, - FreqItems3020[index].K, - FreqItems3020[index].R)); - - break; - } - } - } else -#endif /* RT30xx // */ - { - RFRegTable = RF2850RegTable; - switch (pAd->RfIcType) { - case RFIC_2820: - case RFIC_2850: - case RFIC_2720: - case RFIC_2750: - - for (index = 0; index < NUM_OF_2850_CHNL; index++) { - if (Channel == RFRegTable[index].Channel) { - R2 = RFRegTable[index].R2; - if (pAd->Antenna.field.TxPath == 1) { - R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1; */ - } - - if (pAd->Antenna.field.RxPath == 2) { - R2 |= 0x40; /* write 1 to off Rxpath. */ - } else if (pAd->Antenna.field.RxPath == - 1) { - R2 |= 0x20040; /* write 1 to off RxPath */ - } - - if (Channel > 14) { - /* initialize R3, R4 */ - R3 = (RFRegTable[index]. - R3 & 0xffffc1ff); - R4 = (RFRegTable[index]. - R4 & (~0x001f87c0)) | - (pAd->RfFreqOffset << 15); - - /* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */ - /* R3 */ - if ((TxPwer >= -7) - && (TxPwer < 0)) { - TxPwer = (7 + TxPwer); - TxPwer = - (TxPwer > - 0xF) ? (0xF) - : (TxPwer); - R3 |= (TxPwer << 10); - DBGPRINT(RT_DEBUG_ERROR, - ("AsicSwitchChannel: TxPwer=%d \n", - TxPwer)); - } else { - TxPwer = - (TxPwer > - 0xF) ? (0xF) - : (TxPwer); - R3 |= - (TxPwer << 10) | (1 - << - 9); - } - - /* R4 */ - if ((TxPwer2 >= -7) - && (TxPwer2 < 0)) { - TxPwer2 = (7 + TxPwer2); - TxPwer2 = - (TxPwer2 > - 0xF) ? (0xF) - : (TxPwer2); - R4 |= (TxPwer2 << 7); - DBGPRINT(RT_DEBUG_ERROR, - ("AsicSwitchChannel: TxPwer2=%d \n", - TxPwer2)); - } else { - TxPwer2 = - (TxPwer2 > - 0xF) ? (0xF) - : (TxPwer2); - R4 |= - (TxPwer2 << 7) | (1 - << - 6); - } - } else { - R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); /* set TX power0 */ - R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6); /* Set freq Offset & TxPwr1 */ - } - - /* Based on BBP current mode before changing RF channel. */ - if (!bScan - && (pAd->CommonCfg.BBPCurrentBW == - BW_40)) { - R4 |= 0x200000; - } - /* Update variables */ - pAd->LatchRfRegs.Channel = Channel; - pAd->LatchRfRegs.R1 = - RFRegTable[index].R1; - pAd->LatchRfRegs.R2 = R2; - pAd->LatchRfRegs.R3 = R3; - pAd->LatchRfRegs.R4 = R4; - - /* Set RF value 1's set R3[bit2] = [0] */ - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R1); - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R2); - RTMP_RF_IO_WRITE32(pAd, - (pAd->LatchRfRegs. - R3 & (~0x04))); - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R4); - - RTMPusecDelay(200); - - /* Set RF value 2's set R3[bit2] = [1] */ - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R1); - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R2); - RTMP_RF_IO_WRITE32(pAd, - (pAd->LatchRfRegs. - R3 | 0x04)); - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R4); - - RTMPusecDelay(200); - - /* Set RF value 3's set R3[bit2] = [0] */ - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R1); - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R2); - RTMP_RF_IO_WRITE32(pAd, - (pAd->LatchRfRegs. - R3 & (~0x04))); - RTMP_RF_IO_WRITE32(pAd, - pAd->LatchRfRegs.R4); - - break; - } - } - break; - - default: - break; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n", - Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9, - (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath, - pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2, - pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4)); - } - - /* Change BBP setting during siwtch from a->g, g->a */ - if (Channel <= 14) { - unsigned long TxPinCfg = 0x00050F0A; /*Gary 2007/08/09 0x050A0A */ - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, - (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, - (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, - (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); /*(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue. */ - /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */ - - /* Rx High power VGA offset for LNA select */ - if (pAd->NicConfig2.field.ExternalLNAForG) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); - } else { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); - } - - /* 5G band selection PIN, bit1 and bit2 are complement */ - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); - Value &= (~0x6); - Value |= (0x04); - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); - - /* Turn off unused PA or LNA when only 1T or 1R */ - if (pAd->Antenna.field.TxPath == 1) { - TxPinCfg &= 0xFFFFFFF3; - } - if (pAd->Antenna.field.RxPath == 1) { - TxPinCfg &= 0xFFFFF3FF; - } - - RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); - -#if defined(RT3090) || defined(RT3390) - /* PCIe PHY Transmit attenuation adjustment */ - if (IS_RT3090A(pAd) || IS_RT3390(pAd)) { - TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = { - .word = 0}; - - RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, - &TxAttenuationCtrl.word); - - if (Channel == 14) /* Channel #14 */ - { - TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; /* Enable PCIe PHY Tx attenuation */ - TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; /* 9/16 full drive level */ - } else /* Channel #1~#13 */ - { - TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; /* Disable PCIe PHY Tx attenuation */ - TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; /* n/a */ - } - - RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, - TxAttenuationCtrl.word); - } -#endif - } else { - unsigned long TxPinCfg = 0x00050F05; /*Gary 2007/8/9 0x050505 */ - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, - (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, - (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, - (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); /*(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue. */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2); - - /* Rx High power VGA offset for LNA select */ - if (pAd->NicConfig2.field.ExternalLNAForA) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); - } else { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); - } - - /* 5G band selection PIN, bit1 and bit2 are complement */ - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); - Value &= (~0x6); - Value |= (0x02); - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); - - /* Turn off unused PA or LNA when only 1T or 1R */ - if (pAd->Antenna.field.TxPath == 1) { - TxPinCfg &= 0xFFFFFFF3; - } - if (pAd->Antenna.field.RxPath == 1) { - TxPinCfg &= 0xFFFFF3FF; - } - - RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); - - } - - /* R66 should be set according to Channel and use 20MHz when scanning */ - /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */ - if (bScan) - RTMPSetAGCInitValue(pAd, BW_20); - else - RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); - - /* */ - /* On 11A, We should delay and wait RF/BBP to be stable */ - /* and the appropriate time should be 1000 micro seconds */ - /* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */ - /* */ - RTMPusecDelay(1000); -} - -void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd) -{ - BBP_CSR_CFG_STRUC BbpCsr; - DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n")); - /* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */ - RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word); - BbpCsr.field.Busy = 0; - RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word); -} - -/* - ========================================================================== - Description: - This function is required for 2421 only, and should not be used during - site survey. It's only required after NIC decided to stay at a channel - for a longer period. - When this function is called, it's always after AsicSwitchChannel(). - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel) -{ -} - -void AsicRfTuningExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ -} - -/* - ========================================================================== - Description: - Gives CCK TX rate 2 more dB TX power. - This routine works only in LINK UP in INFRASTRUCTURE mode. - - calculate desired Tx power in RF R3.Tx0~5, should consider - - 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) - 1. TxPowerPercentage - 2. auto calibration based on TSSI feedback - 3. extra 2 db for CCK - 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP - - NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), - it should be called AFTER MlmeDynamicTxRatSwitching() - ========================================================================== - */ -void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd) -{ - int i, j; - char DeltaPwr = 0; - BOOLEAN bAutoTxAgc = FALSE; - u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep; - u8 BbpR1 = 0, BbpR49 = 0, idx; - char *pTxAgcCompensate; - unsigned long TxPwr[5]; - char Value; - char Rssi = -127; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || -#ifdef RTMP_MAC_PCI - (pAd->bPCIclkOff == TRUE) || -#endif /* RTMP_MAC_PCI // */ - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - return; - - Rssi = RTMPMaxRssi(pAd, - pAd->StaCfg.RssiSample.AvgRssi0, - pAd->StaCfg.RssiSample.AvgRssi1, - pAd->StaCfg.RssiSample.AvgRssi2); - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) { - if (pAd->CommonCfg.CentralChannel > 14) { - TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; - TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; - TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; - TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; - TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; - } else { - TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; - TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; - TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; - TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; - TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; - } - } else { - if (pAd->CommonCfg.Channel > 14) { - TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; - TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; - TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; - TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; - TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; - } else { - TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; - TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; - TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; - TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; - TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; - } - } - - /* TX power compensation for temperature variation based on TSSI. try every 4 second */ - if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) { - if (pAd->CommonCfg.Channel <= 14) { - /* bg channel */ - bAutoTxAgc = pAd->bAutoTxAgcG; - TssiRef = pAd->TssiRefG; - pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; - pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; - TxAgcStep = pAd->TxAgcStepG; - pTxAgcCompensate = &pAd->TxAgcCompensateG; - } else { - /* a channel */ - bAutoTxAgc = pAd->bAutoTxAgcA; - TssiRef = pAd->TssiRefA; - pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; - pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; - TxAgcStep = pAd->TxAgcStepA; - pTxAgcCompensate = &pAd->TxAgcCompensateA; - } - - if (bAutoTxAgc) { - /* BbpR1 is unsigned char */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); - - /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ - /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ - /* step value is defined in pAd->TxAgcStepG for tx power value */ - - /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ - /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 - above value are examined in mass factory production */ - /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ - - /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */ - /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ - /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */ - - if (BbpR49 > pTssiMinusBoundary[1]) { - /* Reading is larger than the reference value */ - /* check for how large we need to decrease the Tx power */ - for (idx = 1; idx < 5; idx++) { - if (BbpR49 <= pTssiMinusBoundary[idx]) /* Found the range */ - break; - } - /* The index is the step we should decrease, idx = 0 means there is nothing to compensate */ -/* if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */ - *pTxAgcCompensate = -(TxAgcStep * (idx - 1)); -/* else */ -/* *pTxAgcCompensate = -((u8)R3); */ - - DeltaPwr += (*pTxAgcCompensate); - DBGPRINT(RT_DEBUG_TRACE, - ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", - BbpR49, TssiRef, TxAgcStep, idx - 1)); - } else if (BbpR49 < pTssiPlusBoundary[1]) { - /* Reading is smaller than the reference value */ - /* check for how large we need to increase the Tx power */ - for (idx = 1; idx < 5; idx++) { - if (BbpR49 >= pTssiPlusBoundary[idx]) /* Found the range */ - break; - } - /* The index is the step we should increase, idx = 0 means there is nothing to compensate */ - *pTxAgcCompensate = TxAgcStep * (idx - 1); - DeltaPwr += (*pTxAgcCompensate); - DBGPRINT(RT_DEBUG_TRACE, - ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", - BbpR49, TssiRef, TxAgcStep, idx - 1)); - } else { - *pTxAgcCompensate = 0; - DBGPRINT(RT_DEBUG_TRACE, - (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", - BbpR49, TssiRef, TxAgcStep, 0)); - } - } - } else { - if (pAd->CommonCfg.Channel <= 14) { - bAutoTxAgc = pAd->bAutoTxAgcG; - pTxAgcCompensate = &pAd->TxAgcCompensateG; - } else { - bAutoTxAgc = pAd->bAutoTxAgcA; - pTxAgcCompensate = &pAd->TxAgcCompensateA; - } - - if (bAutoTxAgc) - DeltaPwr += (*pTxAgcCompensate); - } - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); - BbpR1 &= 0xFC; - - /* calculate delta power based on the percentage specified from UI */ - /* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */ - /* We lower TX power here according to the percentage specified from UI */ - if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) /* AUTO TX POWER control */ - { - { - /* to patch high power issue with some APs, like Belkin N1. */ - if (Rssi > -35) { - BbpR1 |= 0x02; /* DeltaPwr -= 12; */ - } else if (Rssi > -40) { - BbpR1 |= 0x01; /* DeltaPwr -= 6; */ - } else; - } - } else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW */ - ; - else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1; */ - { - DeltaPwr -= 1; - } else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3; */ - { - DeltaPwr -= 3; - } else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6; */ - { - BbpR1 |= 0x01; - } else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9; */ - { - BbpR1 |= 0x01; - DeltaPwr -= 3; - } else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12; */ - { - BbpR1 |= 0x02; - } - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); - - /* reset different new tx power for different TX rate */ - for (i = 0; i < 5; i++) { - if (TxPwr[i] != 0xffffffff) { - for (j = 0; j < 8; j++) { - Value = (char)((TxPwr[i] >> j * 4) & 0x0F); /* 0 ~ 15 */ - - if ((Value + DeltaPwr) < 0) { - Value = 0; /* min */ - } else if ((Value + DeltaPwr) > 0xF) { - Value = 0xF; /* max */ - } else { - Value += DeltaPwr; /* temperature compensation */ - } - - /* fill new value to CSR offset */ - TxPwr[i] = - (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value - << j - * 4); - } - - /* write tx power value to CSR */ - /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M - TX power for OFDM 6M/9M - TX power for CCK5.5M/11M - TX power for CCK1M/2M */ - /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ - RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]); - } - } - -} - -/* - ========================================================================== - Description: - put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup - automatically. Instead, MCU will issue a TwakeUpInterrupt to host after - the wakeup timer timeout. Driver has to issue a separate command to wake - PHY up. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, - u16 TbttNumToNextWakeUp) -{ - RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp); -} - -/* - ========================================================================== - Description: - AsicForceWakeup() is used whenever manual wakeup is required - AsicForceSleep() should only be used when not in INFRA BSS. When - in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead. - ========================================================================== - */ -void AsicForceSleep(struct rt_rtmp_adapter *pAd) -{ - -} - -/* - ========================================================================== - Description: - AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup) - expired. - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - ========================================================================== - */ -void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx) -{ - DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n")); - RTMP_STA_FORCE_WAKEUP(pAd, bFromTx); -} - -/* - ========================================================================== - Description: - Set My BSSID - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid) -{ - unsigned long Addr4; - DBGPRINT(RT_DEBUG_TRACE, - ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0], - pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5])); - - Addr4 = (unsigned long)(pBssid[0]) | - (unsigned long)(pBssid[1] << 8) | - (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24); - RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4); - - Addr4 = 0; - /* always one BSSID in STA mode */ - Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8); - - RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4); -} - -void AsicSetMcastWC(struct rt_rtmp_adapter *pAd) -{ - struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID]; - u16 offset; - - pEntry->Sst = SST_ASSOC; - pEntry->Aid = MCAST_WCID; /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */ - pEntry->PsMode = PWR_ACTIVE; - pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate; - offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid) -{ - unsigned long Addr0 = 0x0, Addr1 = 0x0; - unsigned long offset; - - DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid)); - offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE; - RTMP_IO_WRITE32(pAd, offset, Addr0); - offset += 4; - RTMP_IO_WRITE32(pAd, offset, Addr1); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicEnableRDG(struct rt_rtmp_adapter *pAd) -{ - TX_LINK_CFG_STRUC TxLinkCfg; - u32 Data = 0; - - RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); - TxLinkCfg.field.TxRDGEn = 1; - RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); - - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); - Data &= 0xFFFFFF00; - Data |= 0x80; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); - - /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */ -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicDisableRDG(struct rt_rtmp_adapter *pAd) -{ - TX_LINK_CFG_STRUC TxLinkCfg; - u32 Data = 0; - - RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); - TxLinkCfg.field.TxRDGEn = 0; - RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); - - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); - - Data &= 0xFFFFFF00; - /*Data |= 0x20; */ -#ifndef WIFI_TEST - /*if ( pAd->CommonCfg.bEnableTxBurst ) */ - /* Data |= 0x60; // for performance issue not set the TXOP to 0 */ -#endif - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE) - && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE) - ) { - /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */ - if (pAd->CommonCfg.bEnableTxBurst) - Data |= 0x20; - } - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); -} - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicDisableSync(struct rt_rtmp_adapter *pAd) -{ - BCN_TIME_CFG_STRUC csr; - - DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n")); - - /* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */ - /* that NIC will never wakes up because TSF stops and no more */ - /* TBTT interrupts */ - pAd->TbttTickCount = 0; - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); - csr.field.bBeaconGen = 0; - csr.field.bTBTTEnable = 0; - csr.field.TsfSyncMode = 0; - csr.field.bTsfTicking = 0; - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); - -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicEnableBssSync(struct rt_rtmp_adapter *pAd) -{ - BCN_TIME_CFG_STRUC csr; - - DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n")); - - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); -/* RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */ - { - csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */ - csr.field.bTsfTicking = 1; - csr.field.TsfSyncMode = 1; /* sync TSF in INFRASTRUCTURE mode */ - csr.field.bBeaconGen = 0; /* do NOT generate BEACON */ - csr.field.bTBTTEnable = 1; - } - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); -} - -/* - ========================================================================== - Description: - Note: - BEACON frame in shared memory should be built ok before this routine - can be called. Otherwise, a garbage frame maybe transmitted out every - Beacon period. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd) -{ - BCN_TIME_CFG_STRUC csr9; - u8 *ptr; - u32 i; - - DBGPRINT(RT_DEBUG_TRACE, - ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", - pAd->BeaconTxWI.MPDUtotalByteCount)); - - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word); - csr9.field.bBeaconGen = 0; - csr9.field.bTBTTEnable = 0; - csr9.field.bTsfTicking = 0; - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); - -#ifdef RTMP_MAC_PCI - /* move BEACON TXD and frame content to on-chip memory */ - ptr = (u8 *)& pAd->BeaconTxWI; - for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */ - { - u32 longptr = - *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + - (*(ptr + 3) << 24); - RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); - ptr += 4; - } - - /* start right after the 16-byte TXWI field */ - ptr = pAd->BeaconBuf; - for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) { - u32 longptr = - *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + - (*(ptr + 3) << 24); - RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); - ptr += 4; - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - /* move BEACON TXD and frame content to on-chip memory */ - ptr = (u8 *)& pAd->BeaconTxWI; - for (i = 0; i < TXWI_SIZE; i += 2) /* 16-byte TXWI field */ - { - /*u32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */ - /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */ - RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2); - ptr += 2; - } - - /* start right after the 16-byte TXWI field */ - ptr = pAd->BeaconBuf; - for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) { - /*u32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */ - /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */ - RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2); - ptr += 2; - } -#endif /* RTMP_MAC_USB // */ - - /* */ - /* For Wi-Fi faily generated beacons between participating stations. */ - /* Set TBTT phase adaptive adjustment step to 8us (default 16us) */ - /* don't change settings 2006-5- by Jerry */ - /*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */ - - /* start sending BEACON */ - csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */ - csr9.field.bTsfTicking = 1; - csr9.field.TsfSyncMode = 2; /* sync TSF in IBSS mode */ - csr9.field.bTBTTEnable = 1; - csr9.field.bBeaconGen = 1; - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); -} - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm) -{ - EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg; - AC_TXOP_CSR0_STRUC csr0; - AC_TXOP_CSR1_STRUC csr1; - AIFSN_CSR_STRUC AifsnCsr; - CWMIN_CSR_STRUC CwminCsr; - CWMAX_CSR_STRUC CwmaxCsr; - int i; - - Ac0Cfg.word = 0; - Ac1Cfg.word = 0; - Ac2Cfg.word = 0; - Ac3Cfg.word = 0; - if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) { - DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n")); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED); - for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { - if (pAd->MacTab.Content[i].ValidAsCLI - || pAd->MacTab.Content[i].ValidAsApCli) - CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab. - Content[i], - fCLIENT_STATUS_WMM_CAPABLE); - } - - /*======================================================== */ - /* MAC Register has a copy . */ - /*======================================================== */ -/*#ifndef WIFI_TEST */ - if (pAd->CommonCfg.bEnableTxBurst) { - /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */ - Ac0Cfg.field.AcTxop = 0x20; /* Suggest by John for TxBurst in HT Mode */ - } else - Ac0Cfg.field.AcTxop = 0; /* QID_AC_BE */ -/*#else */ -/* Ac0Cfg.field.AcTxop = 0; // QID_AC_BE */ -/*#endif */ - Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac0Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); - - Ac1Cfg.field.AcTxop = 0; /* QID_AC_BK */ - Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac1Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); - - if (pAd->CommonCfg.PhyMode == PHY_11B) { - Ac2Cfg.field.AcTxop = 192; /* AC_VI: 192*32us ~= 6ms */ - Ac3Cfg.field.AcTxop = 96; /* AC_VO: 96*32us ~= 3ms */ - } else { - Ac2Cfg.field.AcTxop = 96; /* AC_VI: 96*32us ~= 3ms */ - Ac3Cfg.field.AcTxop = 48; /* AC_VO: 48*32us ~= 1.5ms */ - } - Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac2Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); - Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac3Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); - - /*======================================================== */ - /* DMA Register has a copy too. */ - /*======================================================== */ - csr0.field.Ac0Txop = 0; /* QID_AC_BE */ - csr0.field.Ac1Txop = 0; /* QID_AC_BK */ - RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); - if (pAd->CommonCfg.PhyMode == PHY_11B) { - csr1.field.Ac2Txop = 192; /* AC_VI: 192*32us ~= 6ms */ - csr1.field.Ac3Txop = 96; /* AC_VO: 96*32us ~= 3ms */ - } else { - csr1.field.Ac2Txop = 96; /* AC_VI: 96*32us ~= 3ms */ - csr1.field.Ac3Txop = 48; /* AC_VO: 48*32us ~= 1.5ms */ - } - RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); - - CwminCsr.word = 0; - CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS; - CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS; - CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS; - CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS; - RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); - - CwmaxCsr.word = 0; - CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS; - CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS; - CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS; - CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS; - RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); - - RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222); - - NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm)); - } else { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED); - /*======================================================== */ - /* MAC Register has a copy. */ - /*======================================================== */ - /* */ - /* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */ - /* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */ - /* */ - /*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */ - - Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE]; - Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE]; - Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE]; - Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; /*+1; */ - - Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; - Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; /*+2; */ - Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK]; - Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; /*+1; */ - - Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10; - if (pAd->Antenna.field.TxPath == 1) { - Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1; - Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1; - } else { - Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI]; - Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI]; - } - Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1; -#ifdef RTMP_MAC_USB - Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3; -#endif /* RTMP_MAC_USB // */ - - { - /* Tuning for Wi-Fi WMM S06 */ - if (pAd->CommonCfg.bWiFiTest && - pEdcaParm->Aifsn[QID_AC_VI] == 10) - Ac2Cfg.field.Aifsn -= 1; - - /* Tuning for TGn Wi-Fi 5.2.32 */ - /* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */ - if (STA_TGN_WIFI_ON(pAd) && - pEdcaParm->Aifsn[QID_AC_VI] == 10) { - Ac0Cfg.field.Aifsn = 3; - Ac2Cfg.field.AcTxop = 5; - } -#ifdef RT30xx - if (pAd->RfIcType == RFIC_3020 - || pAd->RfIcType == RFIC_2020) { - /* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */ - Ac2Cfg.field.Aifsn = 5; - } -#endif /* RT30xx // */ - } - - Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO]; - Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO]; - Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO]; - Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO]; - -/*#ifdef WIFI_TEST */ - if (pAd->CommonCfg.bWiFiTest) { - if (Ac3Cfg.field.AcTxop == 102) { - Ac0Cfg.field.AcTxop = - pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm-> - Txop[QID_AC_BE] : 10; - Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1; /* AIFSN must >= 1 */ - Ac1Cfg.field.AcTxop = - pEdcaParm->Txop[QID_AC_BK]; - Ac1Cfg.field.Aifsn = - pEdcaParm->Aifsn[QID_AC_BK]; - Ac2Cfg.field.AcTxop = - pEdcaParm->Txop[QID_AC_VI]; - } /* End of if */ - } -/*#endif // WIFI_TEST // */ - - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); - RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); - RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); - RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); - - /*======================================================== */ - /* DMA Register has a copy too. */ - /*======================================================== */ - csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop; - csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop; - RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); - - csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop; - csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop; - RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); - - CwminCsr.word = 0; - CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE]; - CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK]; - CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI]; - CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; /*for TGn wifi test */ - RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); - - CwmaxCsr.word = 0; - CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE]; - CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK]; - CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI]; - CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO]; - RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); - - AifsnCsr.word = 0; - AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BE]; */ - AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BK]; */ - AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VI]; */ - - { - /* Tuning for Wi-Fi WMM S06 */ - if (pAd->CommonCfg.bWiFiTest && - pEdcaParm->Aifsn[QID_AC_VI] == 10) - AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4; - - /* Tuning for TGn Wi-Fi 5.2.32 */ - /* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */ - if (STA_TGN_WIFI_ON(pAd) && - pEdcaParm->Aifsn[QID_AC_VI] == 10) { - AifsnCsr.field.Aifsn0 = 3; - AifsnCsr.field.Aifsn2 = 7; - } - - if (INFRA_ON(pAd)) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab. - Content[BSSID_WCID], - fCLIENT_STATUS_WMM_CAPABLE); - } - - { - AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; /*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */ -#ifdef RT30xx - /* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */ - if (pAd->RfIcType == RFIC_3020 - || pAd->RfIcType == RFIC_2020) { - AifsnCsr.field.Aifsn2 = 0x2; /*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */ - } -#endif /* RT30xx // */ - } - RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word); - - NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, - sizeof(struct rt_edca_parm)); - if (!ADHOC_ON(pAd)) { - DBGPRINT(RT_DEBUG_TRACE, - ("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", - pEdcaParm->EdcaUpdateCount)); - DBGPRINT(RT_DEBUG_TRACE, - (" AC_BE %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0], - pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5, - pEdcaParm->bACM[0])); - DBGPRINT(RT_DEBUG_TRACE, - (" AC_BK %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1], - pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5, - pEdcaParm->bACM[1])); - DBGPRINT(RT_DEBUG_TRACE, - (" AC_VI %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2], - pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5, - pEdcaParm->bACM[2])); - DBGPRINT(RT_DEBUG_TRACE, - (" AC_VO %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3], - pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5, - pEdcaParm->bACM[3])); - } - } - -} - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime) -{ - unsigned long SlotTime; - u32 RegValue = 0; - - if (pAd->CommonCfg.Channel > 14) - bUseShortSlotTime = TRUE; - - if (bUseShortSlotTime - && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) - return; - else if ((!bUseShortSlotTime) - && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))) - return; - - if (bUseShortSlotTime) - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); - else - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); - - SlotTime = (bUseShortSlotTime) ? 9 : 20; - - { - /* force using short SLOT time for FAE to demo performance when TxBurst is ON */ - if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) - && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))) - || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) - && (pAd->CommonCfg.BACapability.field.Policy == - BA_NOTUSE)) - ) { - /* In this case, we will think it is doing Wi-Fi test */ - /* And we will not set to short slot when bEnableTxBurst is TRUE. */ - } else if (pAd->CommonCfg.bEnableTxBurst) { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); - SlotTime = 9; - } - } - - /* */ - /* For some reasons, always set it to short slot time. */ - /* */ - /* ToDo: Should consider capability with 11B */ - /* */ - { - if (pAd->StaCfg.BssType == BSS_ADHOC) { - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); - SlotTime = 20; - } - } - - RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue); - RegValue = RegValue & 0xFFFFFF00; - - RegValue |= SlotTime; - - RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue); -} - -/* - ======================================================================== - Description: - Add Shared key information into ASIC. - Update shared key, TxMic and RxMic to Asic Shared key table - Update its cipherAlg to Asic Shared key Mode. - - Return: - ======================================================================== -*/ -void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd, - u8 BssIndex, - u8 KeyIdx, - u8 CipherAlg, - u8 *pKey, u8 *pTxMic, u8 *pRxMic) -{ - unsigned long offset; /*, csr0; */ - SHAREDKEY_MODE_STRUC csr1; -#ifdef RTMP_MAC_PCI - int i; -#endif /* RTMP_MAC_PCI // */ - - DBGPRINT(RT_DEBUG_TRACE, - ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex, - KeyIdx)); -/*============================================================================================ */ - - DBGPRINT(RT_DEBUG_TRACE, - ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], - BssIndex * 4 + KeyIdx)); - DBGPRINT_RAW(RT_DEBUG_TRACE, - (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], - pKey[5], pKey[6], pKey[7], pKey[8], pKey[9], - pKey[10], pKey[11], pKey[12], pKey[13], pKey[14], - pKey[15])); - if (pRxMic) { - DBGPRINT_RAW(RT_DEBUG_TRACE, - (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3], - pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7])); - } - if (pTxMic) { - DBGPRINT_RAW(RT_DEBUG_TRACE, - (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3], - pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7])); - } -/*============================================================================================ */ - /* */ - /* fill key material - key + TX MIC + RX MIC */ - /* */ -#ifdef RTMP_MAC_PCI - offset = - SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE; - for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); - } - - offset += MAX_LEN_OF_SHARE_KEY; - if (pTxMic) { - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); - } - } - - offset += 8; - if (pRxMic) { - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); - } - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - { - offset = - SHARED_KEY_TABLE_BASE + (4 * BssIndex + - KeyIdx) * HW_KEY_ENTRY_SIZE; - RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY); - - offset += MAX_LEN_OF_SHARE_KEY; - if (pTxMic) { - RTUSBMultiWrite(pAd, offset, pTxMic, 8); - } - - offset += 8; - if (pRxMic) { - RTUSBMultiWrite(pAd, offset, pRxMic, 8); - } - } -#endif /* RTMP_MAC_USB // */ - - /* */ - /* Update cipher algorithm. WSTA always use BSS0 */ - /* */ - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), - &csr1.word); - DBGPRINT(RT_DEBUG_TRACE, - ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", - BssIndex, KeyIdx, csr1.word)); - if ((BssIndex % 2) == 0) { - if (KeyIdx == 0) - csr1.field.Bss0Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss0Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss0Key2CipherAlg = CipherAlg; - else - csr1.field.Bss0Key3CipherAlg = CipherAlg; - } else { - if (KeyIdx == 0) - csr1.field.Bss1Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss1Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss1Key2CipherAlg = CipherAlg; - else - csr1.field.Bss1Key3CipherAlg = CipherAlg; - } - DBGPRINT(RT_DEBUG_TRACE, - ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", - BssIndex, csr1.word)); - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), - csr1.word); - -} - -/* IRQL = DISPATCH_LEVEL */ -void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd, - u8 BssIndex, u8 KeyIdx) -{ - /*unsigned long SecCsr0; */ - SHAREDKEY_MODE_STRUC csr1; - - DBGPRINT(RT_DEBUG_TRACE, - ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx)); - - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), - &csr1.word); - if ((BssIndex % 2) == 0) { - if (KeyIdx == 0) - csr1.field.Bss0Key0CipherAlg = 0; - else if (KeyIdx == 1) - csr1.field.Bss0Key1CipherAlg = 0; - else if (KeyIdx == 2) - csr1.field.Bss0Key2CipherAlg = 0; - else - csr1.field.Bss0Key3CipherAlg = 0; - } else { - if (KeyIdx == 0) - csr1.field.Bss1Key0CipherAlg = 0; - else if (KeyIdx == 1) - csr1.field.Bss1Key1CipherAlg = 0; - else if (KeyIdx == 2) - csr1.field.Bss1Key2CipherAlg = 0; - else - csr1.field.Bss1Key3CipherAlg = 0; - } - DBGPRINT(RT_DEBUG_TRACE, - ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", - BssIndex, csr1.word)); - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), - csr1.word); - ASSERT(BssIndex < 4); - ASSERT(KeyIdx < 4); - -} - -void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd, - u16 WCID, - u8 BssIndex, - u8 CipherAlg, - IN BOOLEAN bUsePairewiseKeyTable) -{ - unsigned long WCIDAttri = 0, offset; - - /* */ - /* Update WCID attribute. */ - /* Only TxKey could update WCID attribute. */ - /* */ - offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE); - WCIDAttri = - (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable); - RTMP_IO_WRITE32(pAd, offset, WCIDAttri); -} - -void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd, - u16 WCID, unsigned long uIV, unsigned long uEIV) -{ - unsigned long offset; - - offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); - - RTMP_IO_WRITE32(pAd, offset, uIV); - RTMP_IO_WRITE32(pAd, offset + 4, uEIV); -} - -void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd, - u16 WCID, u8 *pAddr) -{ - unsigned long offset; - unsigned long Addr; - - offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE); - Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24); - RTMP_IO_WRITE32(pAd, offset, Addr); - Addr = pAddr[4] + (pAddr[5] << 8); - RTMP_IO_WRITE32(pAd, offset + 4, Addr); -} - -/* - ======================================================================== - - Routine Description: - Set Cipher Key, Cipher algorithm, IV/EIV to Asic - - Arguments: - pAd Pointer to our adapter - WCID WCID Entry number. - BssIndex BSSID index, station or none multiple BSSID support - this value should be 0. - KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled - pCipherKey Pointer to Cipher Key. - bUsePairewiseKeyTable TRUE means saved the key in SharedKey table, - otherwise PairewiseKey table - bTxKey This is the transmit key if enabled. - - Return Value: - None - - Note: - This routine will set the relative key stuff to Asic including WCID attribute, - Cipher Key, Cipher algorithm and IV/EIV. - - IV/EIV will be update if this CipherKey is the transmission key because - ASIC will base on IV's KeyID value to select Cipher Key. - - If bTxKey sets to FALSE, this is not the TX key, but it could be - RX key - - For AP mode bTxKey must be always set to TRUE. - ======================================================================== -*/ -void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd, - u16 WCID, - u8 BssIndex, - u8 KeyIdx, - struct rt_cipher_key *pCipherKey, - IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey) -{ - unsigned long offset; -/* unsigned long WCIDAttri = 0; */ - u8 IV4 = 0; - u8 *pKey = pCipherKey->Key; -/* unsigned long KeyLen = pCipherKey->KeyLen; */ - u8 *pTxMic = pCipherKey->TxMic; - u8 *pRxMic = pCipherKey->RxMic; - u8 *pTxtsc = pCipherKey->TxTsc; - u8 CipherAlg = pCipherKey->CipherAlg; - SHAREDKEY_MODE_STRUC csr1; -#ifdef RTMP_MAC_PCI - u8 i; -#endif /* RTMP_MAC_PCI // */ - -/* ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */ - - DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n")); - /* */ - /* 1.) decide key table offset */ - /* */ - if (bUsePairewiseKeyTable) - offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); - else - offset = - SHARED_KEY_TABLE_BASE + (4 * BssIndex + - KeyIdx) * HW_KEY_ENTRY_SIZE; - - /* */ - /* 2.) Set Key to Asic */ - /* */ - /*for (i = 0; i < KeyLen; i++) */ -#ifdef RTMP_MAC_PCI - for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); - } - offset += MAX_LEN_OF_PEER_KEY; - - /* */ - /* 3.) Set MIC key if available */ - /* */ - if (pTxMic) { - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); - } - } - offset += LEN_TKIP_TXMICK; - - if (pRxMic) { - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); - } - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY); - offset += MAX_LEN_OF_PEER_KEY; - - /* */ - /* 3.) Set MIC key if available */ - /* */ - if (pTxMic) { - RTUSBMultiWrite(pAd, offset, pTxMic, 8); - } - offset += LEN_TKIP_TXMICK; - - if (pRxMic) { - RTUSBMultiWrite(pAd, offset, pRxMic, 8); - } -#endif /* RTMP_MAC_USB // */ - - /* */ - /* 4.) Modify IV/EIV if needs */ - /* This will force Asic to use this key ID by setting IV. */ - /* */ - if (bTxKey) { -#ifdef RTMP_MAC_PCI - offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); - /* */ - /* Write IV */ - /* */ - RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]); - RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f)); - RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]); - - IV4 = (KeyIdx << 6); - if ((CipherAlg == CIPHER_TKIP) - || (CipherAlg == CIPHER_TKIP_NO_MIC) - || (CipherAlg == CIPHER_AES)) - IV4 |= 0x20; /* turn on extension bit means EIV existence */ - - RTMP_IO_WRITE8(pAd, offset + 3, IV4); - - /* */ - /* Write EIV */ - /* */ - offset += 4; - for (i = 0; i < 4; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]); - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - u32 tmpVal; - - /* */ - /* Write IV */ - /* */ - IV4 = (KeyIdx << 6); - if ((CipherAlg == CIPHER_TKIP) - || (CipherAlg == CIPHER_TKIP_NO_MIC) - || (CipherAlg == CIPHER_AES)) - IV4 |= 0x20; /* turn on extension bit means EIV existence */ - - tmpVal = - pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + - (pTxtsc[0] << 16) + (IV4 << 24); - RTMP_IO_WRITE32(pAd, offset, tmpVal); - - /* */ - /* Write EIV */ - /* */ - offset += 4; - RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]); -#endif /* RTMP_MAC_USB // */ - - AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, - bUsePairewiseKeyTable); - } - - if (!bUsePairewiseKeyTable) { - /* */ - /* Only update the shared key security mode */ - /* */ - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), - &csr1.word); - if ((BssIndex % 2) == 0) { - if (KeyIdx == 0) - csr1.field.Bss0Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss0Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss0Key2CipherAlg = CipherAlg; - else - csr1.field.Bss0Key3CipherAlg = CipherAlg; - } else { - if (KeyIdx == 0) - csr1.field.Bss1Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss1Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss1Key2CipherAlg = CipherAlg; - else - csr1.field.Bss1Key3CipherAlg = CipherAlg; - } - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), - csr1.word); - } - - DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n")); -} - -/* - ======================================================================== - Description: - Add Pair-wise key material into ASIC. - Update pairwise key, TxMic and RxMic to Asic Pair-wise key table - - Return: - ======================================================================== -*/ -void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd, - u8 *pAddr, - u8 WCID, struct rt_cipher_key *pCipherKey) -{ - int i; - unsigned long offset; - u8 *pKey = pCipherKey->Key; - u8 *pTxMic = pCipherKey->TxMic; - u8 *pRxMic = pCipherKey->RxMic; -#ifdef DBG - u8 CipherAlg = pCipherKey->CipherAlg; -#endif /* DBG // */ - - /* EKEY */ - offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); -#ifdef RTMP_MAC_PCI - for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY); -#endif /* RTMP_MAC_USB // */ - for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) { - u32 Value; - RTMP_IO_READ32(pAd, offset + i, &Value); - } - - offset += MAX_LEN_OF_PEER_KEY; - - /* MIC KEY */ - if (pTxMic) { -#ifdef RTMP_MAC_PCI - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8); -#endif /* RTMP_MAC_USB // */ - } - offset += 8; - if (pRxMic) { -#ifdef RTMP_MAC_PCI - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8); -#endif /* RTMP_MAC_USB // */ - } - - DBGPRINT(RT_DEBUG_TRACE, - ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID, - CipherName[CipherAlg])); - DBGPRINT(RT_DEBUG_TRACE, - (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5], - pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11], - pKey[12], pKey[13], pKey[14], pKey[15])); - if (pRxMic) { - DBGPRINT(RT_DEBUG_TRACE, - (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3], - pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7])); - } - if (pTxMic) { - DBGPRINT(RT_DEBUG_TRACE, - (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3], - pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7])); - } -} - -/* - ======================================================================== - Description: - Remove Pair-wise key material from ASIC. - - Return: - ======================================================================== -*/ -void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd, - u8 BssIdx, u8 Wcid) -{ - unsigned long WCIDAttri; - u16 offset; - - /* re-set the entry's WCID attribute as OPEN-NONE. */ - offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); - WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE; - RTMP_IO_WRITE32(pAd, offset, WCIDAttri); -} - -BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, - u8 Command, - u8 Token, u8 Arg0, u8 Arg1) -{ - - if (pAd->chipOps.sendCommandToMcu) - pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1); - - return TRUE; -} - -void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant) -{ -#ifdef RT30xx - /* RT3572 ATE need not to do this. */ - RT30xxSetRxAnt(pAd, Ant); -#endif /* RT30xx // */ -} - -void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel) -{ - if (pAd->chipOps.AsicRfTurnOff) { - pAd->chipOps.AsicRfTurnOff(pAd); - } else { - /* RF R2 bit 18 = 0 */ - u32 R1 = 0, R2 = 0, R3 = 0; - u8 index; - struct rt_rtmp_rf_regs *RFRegTable; - - RFRegTable = RF2850RegTable; - - switch (pAd->RfIcType) { - case RFIC_2820: - case RFIC_2850: - case RFIC_2720: - case RFIC_2750: - - for (index = 0; index < NUM_OF_2850_CHNL; index++) { - if (Channel == RFRegTable[index].Channel) { - R1 = RFRegTable[index].R1 & 0xffffdfff; - R2 = RFRegTable[index].R2 & 0xfffbffff; - R3 = RFRegTable[index].R3 & 0xfff3ffff; - - RTMP_RF_IO_WRITE32(pAd, R1); - RTMP_RF_IO_WRITE32(pAd, R2); - - /* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */ - /* Set RF R2 bit18=0, R3 bit[18:19]=0 */ - /*if (pAd->StaCfg.bRadio == FALSE) */ - if (1) { - RTMP_RF_IO_WRITE32(pAd, R3); - - DBGPRINT(RT_DEBUG_TRACE, - ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n", - Channel, - pAd->RfIcType, R2, - R3)); - } else - DBGPRINT(RT_DEBUG_TRACE, - ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n", - Channel, - pAd->RfIcType, R2)); - break; - } - } - break; - - default: - break; - } - } -} - -void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel) -{ - /* RF R2 bit 18 = 0 */ - u32 R1 = 0, R2 = 0, R3 = 0; - u8 index; - struct rt_rtmp_rf_regs *RFRegTable; - -#ifdef PCIE_PS_SUPPORT - /* The RF programming sequence is difference between 3xxx and 2xxx */ - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) { - return; - } -#endif /* PCIE_PS_SUPPORT // */ - - RFRegTable = RF2850RegTable; - - switch (pAd->RfIcType) { - case RFIC_2820: - case RFIC_2850: - case RFIC_2720: - case RFIC_2750: - - for (index = 0; index < NUM_OF_2850_CHNL; index++) { - if (Channel == RFRegTable[index].Channel) { - R3 = pAd->LatchRfRegs.R3; - R3 &= 0xfff3ffff; - R3 |= 0x00080000; - RTMP_RF_IO_WRITE32(pAd, R3); - - R1 = RFRegTable[index].R1; - RTMP_RF_IO_WRITE32(pAd, R1); - - R2 = RFRegTable[index].R2; - if (pAd->Antenna.field.TxPath == 1) { - R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1; */ - } - - if (pAd->Antenna.field.RxPath == 2) { - R2 |= 0x40; /* write 1 to off Rxpath. */ - } else if (pAd->Antenna.field.RxPath == 1) { - R2 |= 0x20040; /* write 1 to off RxPath */ - } - RTMP_RF_IO_WRITE32(pAd, R2); - - break; - } - } - break; - - default: - break; - } - - DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n", - Channel, pAd->RfIcType, R2)); -} diff --git a/drivers/staging/rt2860/common/cmm_cfg.c b/drivers/staging/rt2860/common/cmm_cfg.c deleted file mode 100644 index 727f79929258..000000000000 --- a/drivers/staging/rt2860/common/cmm_cfg.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - cmm_cfg.c - - Abstract: - Ralink WiFi Driver configuration related subroutines - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -char *GetPhyMode(int Mode) -{ - switch (Mode) { - case MODE_CCK: - return "CCK"; - - case MODE_OFDM: - return "OFDM"; - case MODE_HTMIX: - return "HTMIX"; - - case MODE_HTGREENFIELD: - return "GREEN"; - default: - return "N/A"; - } -} - -char *GetBW(int BW) -{ - switch (BW) { - case BW_10: - return "10M"; - - case BW_20: - return "20M"; - case BW_40: - return "40M"; - default: - return "N/A"; - } -} - -/* - ========================================================================== - Description: - Set Country Region to pAd->CommonCfg.CountryRegion. - This command will not work, if the field of CountryRegion in eeprom is programmed. - - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== -*/ -int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band) -{ - long region, regionMax; - u8 *pCountryRegion; - - region = simple_strtol(arg, 0, 10); - - if (band == BAND_24G) { - pCountryRegion = &pAd->CommonCfg.CountryRegion; - regionMax = REGION_MAXIMUM_BG_BAND; - } else { - pCountryRegion = &pAd->CommonCfg.CountryRegionForABand; - regionMax = REGION_MAXIMUM_A_BAND; - } - - /* TODO: Is it neccesay for following check??? */ - /* Country can be set only when EEPROM not programmed */ - if (*pCountryRegion & 0x80) { - DBGPRINT(RT_DEBUG_ERROR, - ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n")); - return FALSE; - } - - if ((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) { - *pCountryRegion = (u8)region; - } else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) { - *pCountryRegion = (u8)region; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("CfgSetCountryRegion():region(%ld) out of range!\n", - region)); - return FALSE; - } - - return TRUE; - -} - -/* - ========================================================================== - Description: - Set Wireless Mode - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== -*/ -int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg) -{ - int MaxPhyMode = PHY_11G; - long WirelessMode; - - MaxPhyMode = PHY_11N_5G; - - WirelessMode = simple_strtol(arg, 0, 10); - if (WirelessMode <= MaxPhyMode) { - pAd->CommonCfg.PhyMode = WirelessMode; - return TRUE; - } - - return FALSE; - -} - -int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg) -{ - long ShortSlot; - - ShortSlot = simple_strtol(arg, 0, 10); - - if (ShortSlot == 1) - pAd->CommonCfg.bUseShortSlotTime = TRUE; - else if (ShortSlot == 0) - pAd->CommonCfg.bUseShortSlotTime = FALSE; - else - return FALSE; /*Invalid argument */ - - return TRUE; -} - -/* - ========================================================================== - Description: - Set WEP KEY base on KeyIdx - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== -*/ -int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd, - char *keyString, - struct rt_cipher_key *pSharedKey, int keyIdx) -{ - int KeyLen; - int i; - u8 CipherAlg = CIPHER_NONE; - BOOLEAN bKeyIsHex = FALSE; - - /* TODO: Shall we do memset for the original key info?? */ - memset(pSharedKey, 0, sizeof(struct rt_cipher_key)); - KeyLen = strlen(keyString); - switch (KeyLen) { - case 5: /*wep 40 Ascii type */ - case 13: /*wep 104 Ascii type */ - bKeyIsHex = FALSE; - pSharedKey->KeyLen = KeyLen; - NdisMoveMemory(pSharedKey->Key, keyString, KeyLen); - break; - - case 10: /*wep 40 Hex type */ - case 26: /*wep 104 Hex type */ - for (i = 0; i < KeyLen; i++) { - if (!isxdigit(*(keyString + i))) - return FALSE; /*Not Hex value; */ - } - bKeyIsHex = TRUE; - pSharedKey->KeyLen = KeyLen / 2; - AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen); - break; - - default: /*Invalid argument */ - DBGPRINT(RT_DEBUG_TRACE, - ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", - keyIdx, keyString)); - return FALSE; - } - - pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64); - DBGPRINT(RT_DEBUG_TRACE, - ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", keyIdx, - (bKeyIsHex == FALSE ? "Ascii" : "Hex"), - CipherName[CipherAlg])); - - return TRUE; -} - -/* - ========================================================================== - Description: - Set WPA PSK key - - Arguments: - pAdapter Pointer to our adapter - keyString WPA pre-shared key string - pHashStr String used for password hash function - hashStrLen Length of the hash string - pPMKBuf Output buffer of WPAPSK key - - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== -*/ -int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd, - char *keyString, - u8 * pHashStr, - int hashStrLen, u8 *pPMKBuf) -{ - int keyLen; - u8 keyMaterial[40]; - - keyLen = strlen(keyString); - if ((keyLen < 8) || (keyLen > 64)) { - DBGPRINT(RT_DEBUG_TRACE, - ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n", - keyLen, keyString)); - return FALSE; - } - - memset(pPMKBuf, 0, 32); - if (keyLen == 64) { - AtoH(keyString, pPMKBuf, 32); - } else { - PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial); - NdisMoveMemory(pPMKBuf, keyMaterial, 32); - } - - return TRUE; -} diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c deleted file mode 100644 index 33799e1449ae..000000000000 --- a/drivers/staging/rt2860/common/cmm_data.c +++ /dev/null @@ -1,2361 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#include "../rt_config.h" - -u8 SNAP_802_1H[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -u8 SNAP_BRIDGE_TUNNEL[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; - -/* Add Cisco Aironet SNAP heade for CCX2 support */ -u8 SNAP_AIRONET[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 }; -u8 CKIP_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 }; -u8 EAPOL_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; -u8 EAPOL[] = { 0x88, 0x8e }; -u8 TPID[] = { 0x81, 0x00 }; /* VLAN related */ - -u8 IPX[] = { 0x81, 0x37 }; -u8 APPLE_TALK[] = { 0x80, 0xf3 }; - -u8 RateIdToPlcpSignal[12] = { - 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 *//* see BBP spec */ - 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 *//* see IEEE802.11a-1999 p.14 */ - 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ -}; /* see IEEE802.11a-1999 p.14 */ - -u8 OfdmSignalToRateId[16] = { - RATE_54, RATE_54, RATE_54, RATE_54, /* OFDM PLCP Signal = 0, 1, 2, 3 respectively */ - RATE_54, RATE_54, RATE_54, RATE_54, /* OFDM PLCP Signal = 4, 5, 6, 7 respectively */ - RATE_48, RATE_24, RATE_12, RATE_6, /* OFDM PLCP Signal = 8, 9, 10, 11 respectively */ - RATE_54, RATE_36, RATE_18, RATE_9, /* OFDM PLCP Signal = 12, 13, 14, 15 respectively */ -}; - -u8 OfdmRateToRxwiMCS[12] = { - 0, 0, 0, 0, - 0, 1, 2, 3, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */ - 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */ -}; - -u8 RxwiMCSToOfdmRate[12] = { - RATE_6, RATE_9, RATE_12, RATE_18, - RATE_24, RATE_36, RATE_48, RATE_54, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */ - 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */ -}; - -char *MCSToMbps[] = - { "1Mbps", "2Mbps", "5.5Mbps", "11Mbps", "06Mbps", "09Mbps", "12Mbps", -"18Mbps", "24Mbps", "36Mbps", "48Mbps", "54Mbps", "MM-0", "MM-1", "MM-2", "MM-3", -"MM-4", "MM-5", "MM-6", "MM-7", "MM-8", "MM-9", "MM-10", "MM-11", "MM-12", "MM-13", -"MM-14", "MM-15", "MM-32", "ee1", "ee2", "ee3" }; - -u8 default_cwmin[] = - { CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS - 1, CW_MIN_IN_BITS - 2 }; -/*u8 default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; */ -u8 default_sta_aifsn[] = { 3, 7, 2, 2 }; - -u8 MapUserPriorityToAccessCategory[8] = - { QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, -QID_AC_VO, QID_AC_VO }; - -/* - ======================================================================== - - Routine Description: - API for MLME to transmit management frame to AP (BSS Mode) - or station (IBSS Mode) - - Arguments: - pAd Pointer to our adapter - pData Pointer to the outgoing 802.11 frame - Length Size of outgoing management frame - - Return Value: - NDIS_STATUS_FAILURE - NDIS_STATUS_PENDING - NDIS_STATUS_SUCCESS - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -int MiniportMMRequest(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u8 *pData, u32 Length) -{ - void *pPacket; - int Status = NDIS_STATUS_SUCCESS; - unsigned long FreeNum; - u8 rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; /*RTMP_HW_HDR_LEN]; */ -#ifdef RTMP_MAC_PCI - unsigned long IrqFlags = 0; - u8 IrqState; -#endif /* RTMP_MAC_PCI // */ - BOOLEAN bUseDataQ = FALSE; - int retryCnt = 0; - - ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); - - if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) { - bUseDataQ = TRUE; - QueIdx &= (~MGMT_USE_QUEUE_FLAG); - } -#ifdef RTMP_MAC_PCI - /* 2860C use Tx Ring */ - IrqState = pAd->irq_disabled; - if (pAd->MACVersion == 0x28600100) { - QueIdx = (bUseDataQ == TRUE ? QueIdx : 3); - bUseDataQ = TRUE; - } - if (bUseDataQ && (!IrqState)) - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); -#endif /* RTMP_MAC_PCI // */ - - do { - /* Reset is in progress, stop immediately */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || - RTMP_TEST_FLAG(pAd, - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST) - || !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { - Status = NDIS_STATUS_FAILURE; - break; - } - /* Check Free priority queue */ - /* Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing. */ -#ifdef RTMP_MAC_PCI - if (bUseDataQ) { - retryCnt = MAX_DATAMM_RETRY; - /* free Tx(QueIdx) resources */ - RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); - FreeNum = GET_TXRING_FREENO(pAd, QueIdx); - } else -#endif /* RTMP_MAC_PCI // */ - { - FreeNum = GET_MGMTRING_FREENO(pAd); - } - - if ((FreeNum > 0)) { - /* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870 */ - NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE)); - Status = - RTMPAllocateNdisPacket(pAd, &pPacket, - (u8 *)& rtmpHwHdr, - (TXINFO_SIZE + TXWI_SIZE), - pData, Length); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_WARN, - ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n")); - break; - } - /*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; */ - /*pAd->CommonCfg.MlmeRate = RATE_2; */ - -#ifdef RTMP_MAC_PCI - if (bUseDataQ) { - Status = - MlmeDataHardTransmit(pAd, QueIdx, pPacket); - retryCnt--; - } else -#endif /* RTMP_MAC_PCI // */ - Status = MlmeHardTransmit(pAd, QueIdx, pPacket); - if (Status == NDIS_STATUS_SUCCESS) - retryCnt = 0; - else - RTMPFreeNdisPacket(pAd, pPacket); - } else { - pAd->RalinkCounters.MgmtRingFullCount++; -#ifdef RTMP_MAC_PCI - if (bUseDataQ) { - retryCnt--; - DBGPRINT(RT_DEBUG_TRACE, - ("retryCnt %d\n", retryCnt)); - if (retryCnt == 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n", - QueIdx, - pAd->RalinkCounters. - MgmtRingFullCount)); - } - } -#endif /* RTMP_MAC_PCI // */ - DBGPRINT(RT_DEBUG_ERROR, - ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n", - QueIdx, - pAd->RalinkCounters.MgmtRingFullCount)); - } - } while (retryCnt > 0); - -#ifdef RTMP_MAC_PCI - if (bUseDataQ && (!IrqState)) - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); -#endif /* RTMP_MAC_PCI // */ - - return Status; -} - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware transmit function - - Arguments: - pAd Pointer to our adapter - pBuffer Pointer to memory of outgoing frame - Length Size of outgoing management frame - - Return Value: - NDIS_STATUS_FAILURE - NDIS_STATUS_PENDING - NDIS_STATUS_SUCCESS - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -int MlmeHardTransmit(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - struct rt_header_802_11 * pHeader_802_11; - - if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) - ) { - return NDIS_STATUS_FAILURE; - } - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - if (pSrcBufVA == NULL) - return NDIS_STATUS_FAILURE; - - pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); - -#ifdef RTMP_MAC_PCI - if (pAd->MACVersion == 0x28600100) - return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket); - else -#endif /* RTMP_MAC_PCI // */ - return MlmeHardTransmitMgmtRing(pAd, QueIdx, pPacket); - -} - -int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - struct rt_header_802_11 * pHeader_802_11; - BOOLEAN bAckRequired, bInsertTimestamp; - u8 MlmeRate; - struct rt_txwi * pFirstTxWI; - struct rt_mac_table_entry *pMacEntry = NULL; - u8 PID; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - /* Make sure MGMT ring resource won't be used by other threads */ - RTMP_SEM_LOCK(&pAd->MgmtRingLock); - if (pSrcBufVA == NULL) { - /* The buffer shouldn't be NULL */ - RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); - return NDIS_STATUS_FAILURE; - } - - { - /* outgoing frame always wakeup PHY to prevent frame lost */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - AsicForceWakeup(pAd, TRUE); - } - - pFirstTxWI = (struct rt_txwi *) (pSrcBufVA + TXINFO_SIZE); - pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); /*TXWI_SIZE); */ - - if (pHeader_802_11->Addr1[0] & 0x01) { - MlmeRate = pAd->CommonCfg.BasicMlmeRate; - } else { - MlmeRate = pAd->CommonCfg.MlmeRate; - } - - /* Verify Mlme rate for a / g bands. */ - if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */ - MlmeRate = RATE_6; - - if ((pHeader_802_11->FC.Type == BTYPE_DATA) && - (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { - pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); - } - - { - /* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. */ - if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED - || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) { - if (pAd->LatchRfRegs.Channel > 14) - pAd->CommonCfg.MlmeTransmit.field.MODE = 1; - else - pAd->CommonCfg.MlmeTransmit.field.MODE = 0; - } - } - - /* */ - /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */ - /* Snice it's been set to 0 while on MgtMacHeaderInit */ - /* By the way this will cause frame to be send on PWR_SAVE failed. */ - /* */ - pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; /* (pAd->StaCfg.Psm == PWR_SAVE); */ - - /* */ - /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ - /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ -/* if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */ - { - if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) || - ((pHeader_802_11->FC.Type == BTYPE_DATA) && - ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) || - (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) { - if (pAd->StaCfg.Psm == PWR_SAVE) - pHeader_802_11->FC.PwrMgmt = PWR_SAVE; - else - pHeader_802_11->FC.PwrMgmt = - pAd->CommonCfg.bAPSDForcePowerSave; - } - } - - bInsertTimestamp = FALSE; - if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */ - { - /*Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue. */ - if ((pAd->OpMode == OPMODE_STA) - && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) { - pHeader_802_11->FC.PwrMgmt = PWR_SAVE; - } - bAckRequired = FALSE; - } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */ - { - /*pAd->Sequence++; */ - /*pHeader_802_11->Sequence = pAd->Sequence; */ - - if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */ - { - bAckRequired = FALSE; - pHeader_802_11->Duration = 0; - } else { - bAckRequired = TRUE; - pHeader_802_11->Duration = - RTMPCalcDuration(pAd, MlmeRate, 14); - if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) - && (pHeader_802_11->FC.Type == BTYPE_MGMT)) { - bInsertTimestamp = TRUE; - bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Response */ - } else - if ((pHeader_802_11->FC.SubType == - SUBTYPE_PROBE_REQ) - && (pHeader_802_11->FC.Type == BTYPE_MGMT)) { - bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Request */ - } - } - } - - pHeader_802_11->Sequence = pAd->Sequence++; - if (pAd->Sequence > 0xfff) - pAd->Sequence = 0; - - /* Before radar detection done, mgmt frame can not be sent but probe req */ - /* Because we need to use probe req to trigger driver to send probe req in passive scan */ - if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) - && (pAd->CommonCfg.bIEEE80211H == 1) - && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeHardTransmit --> radar detect not in normal mode!\n")); -/* if (!IrqState) */ - RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); - return (NDIS_STATUS_FAILURE); - } - - /* */ - /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */ - /* should always has only one physical buffer, and the whole frame size equals */ - /* to the first scatter buffer size */ - /* */ - - /* Initialize TX Descriptor */ - /* For inter-frame gap, the number is for this frame and next frame */ - /* For MLME rate, we will fix as 2Mb to match other vendor's implement */ -/* pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */ - -/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */ - PID = PID_MGMT; - - if (pMacEntry == NULL) { - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, - FALSE, bAckRequired, FALSE, 0, RESERVED_WCID, - (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0, - (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, - IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); - } else { - /* dont use low rate to send QoS Null data frame */ - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, - bInsertTimestamp, FALSE, bAckRequired, FALSE, - 0, pMacEntry->Aid, - (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), - pMacEntry->MaxHTPhyMode.field.MCS, 0, - (u8)pMacEntry->MaxHTPhyMode.field.MCS, - IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); - } - - /* Now do hardware-depened kick out. */ - HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen); - - /* Make sure to release MGMT ring resource */ -/* if (!IrqState) */ - RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); - return NDIS_STATUS_SUCCESS; -} - -/******************************************************************************** - - New DeQueue Procedures. - - ********************************************************************************/ - -#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \ - do{ \ - if (bIntContext == FALSE) \ - RTMP_IRQ_LOCK((lock), IrqFlags); \ - }while(0) - -#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \ - do{ \ - if (bIntContext == FALSE) \ - RTMP_IRQ_UNLOCK((lock), IrqFlags); \ - }while(0) - -/* - ======================================================================== - Tx Path design algorithm: - Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal), - Specific Packet Type. Following show the classification rule and policy for each kinds of packets. - Classification Rule=> - Multicast: (*addr1 & 0x01) == 0x01 - Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc. - 11N Rate : If peer support HT - (1).AMPDU -- If TXBA is negotiated. - (2).AMSDU -- If AMSDU is capable for both peer and ourself. - *). AMSDU can embedded in a AMPDU, but now we didn't support it. - (3).Normal -- Other packets which send as 11n rate. - - B/G Rate : If peer is b/g only. - (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6 - (2).Normal -- Other packets which send as b/g rate. - Fragment: - The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment. - - Classified Packet Handle Rule=> - Multicast: - No ACK, //pTxBlk->bAckRequired = FALSE; - No WMM, //pTxBlk->bWMM = FALSE; - No piggyback, //pTxBlk->bPiggyBack = FALSE; - Force LowRate, //pTxBlk->bForceLowRate = TRUE; - Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use - the same policy to handle it. - Force LowRate, //pTxBlk->bForceLowRate = TRUE; - - 11N Rate : - No piggyback, //pTxBlk->bPiggyBack = FALSE; - - (1).AMSDU - pTxBlk->bWMM = TRUE; - (2).AMPDU - pTxBlk->bWMM = TRUE; - (3).Normal - - B/G Rate : - (1).ARALINK - - (2).Normal - ======================================================================== -*/ -static u8 TxPktClassification(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - u8 TxFrameType = TX_UNKOWN_FRAME; - u8 Wcid; - struct rt_mac_table_entry *pMacEntry = NULL; - BOOLEAN bHTRate = FALSE; - - Wcid = RTMP_GET_PACKET_WCID(pPacket); - if (Wcid == MCAST_WCID) { /* Handle for RA is Broadcast/Multicast Address. */ - return TX_MCAST_FRAME; - } - /* Handle for unicast packets */ - pMacEntry = &pAd->MacTab.Content[Wcid]; - if (RTMP_GET_PACKET_LOWRATE(pPacket)) { /* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame */ - TxFrameType = TX_LEGACY_FRAME; - } else if (IS_HT_RATE(pMacEntry)) { /* it's a 11n capable packet */ - - /* Depends on HTPhyMode to check if the peer support the HTRate transmission. */ - /* Currently didn't support A-MSDU embedded in A-MPDU */ - bHTRate = TRUE; - if (RTMP_GET_PACKET_MOREDATA(pPacket) - || (pMacEntry->PsMode == PWR_SAVE)) - TxFrameType = TX_LEGACY_FRAME; - else if ((pMacEntry-> - TXBAbitmap & (1 << (RTMP_GET_PACKET_UP(pPacket)))) != - 0) - return TX_AMPDU_FRAME; - else if (CLIENT_STATUS_TEST_FLAG - (pMacEntry, fCLIENT_STATUS_AMSDU_INUSED)) - return TX_AMSDU_FRAME; - else - TxFrameType = TX_LEGACY_FRAME; - } else { /* it's a legacy b/g packet. */ - if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { /* if peer support Ralink Aggregation, we use it. */ - TxFrameType = TX_RALINK_FRAME; - } else { - TxFrameType = TX_LEGACY_FRAME; - } - } - - /* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. */ - if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) - && (TxFrameType == TX_LEGACY_FRAME)) - TxFrameType = TX_FRAG_FRAME; - - return TxFrameType; -} - -BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - struct rt_packet_info PacketInfo; - void *pPacket; - struct rt_mac_table_entry *pMacEntry = NULL; - - pPacket = pTxBlk->pPacket; - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, - &pTxBlk->SrcBufLen); - - pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); - pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket); - pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket); - pTxBlk->FrameGap = IFS_HTTXOP; /* ASIC determine Frame Gap */ - - if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket)) - TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); - else - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame); - - /* Default to clear this flag */ - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS); - - if (pTxBlk->Wcid == MCAST_WCID) { - pTxBlk->pMacEntry = NULL; - { - pTxBlk->pTransmit = - &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; - } - - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); /* AckRequired = FALSE, when broadcast packet in Adhoc mode. */ - /*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); */ - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag); - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); - if (RTMP_GET_PACKET_MOREDATA(pPacket)) { - TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); - } - - } else { - pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid]; - pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode; - - pMacEntry = pTxBlk->pMacEntry; - - /* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. */ - if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK) - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); - else - TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); - - if ((pAd->OpMode == OPMODE_STA) && - (ADHOC_ON(pAd)) && - (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) { - if (pAd->CommonCfg.PSPXlink) - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); - } - - { - { - - /* If support WMM, enable it. */ - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_WMM_INUSED) - && CLIENT_STATUS_TEST_FLAG(pMacEntry, - fCLIENT_STATUS_WMM_CAPABLE)) - TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM); - -/* if (pAd->StaCfg.bAutoTxRateSwitch) */ -/* TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); */ - } - } - - if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) { - if ((RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) { /* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. */ - pTxBlk->pTransmit = - &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; - - /* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? */ - if (IS_HT_STA(pTxBlk->pMacEntry) && - (CLIENT_STATUS_TEST_FLAG - (pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) - && ((pAd->CommonCfg.bRdg == TRUE) - && CLIENT_STATUS_TEST_FLAG(pMacEntry, - fCLIENT_STATUS_RDG_CAPABLE))) - { - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); - TX_BLK_SET_FLAG(pTxBlk, - fTX_bForceNonQoS); - } - } - - if ((IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) { /* Currently piggy-back only support when peer is operate in b/g mode. */ - TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack); - } - - if (RTMP_GET_PACKET_MOREDATA(pPacket)) { - TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); - } - } else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) { - TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag); - } - - pMacEntry->DebugTxCount++; - } - - return TRUE; -} - -BOOLEAN CanDoAggregateTransmit(struct rt_rtmp_adapter *pAd, - char * pPacket, struct rt_tx_blk *pTxBlk) -{ - - /*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); */ - - if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID) - return FALSE; - - if (RTMP_GET_PACKET_DHCP(pPacket) || - RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket)) - return FALSE; - - if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket)) > (RX_BUFFER_AGGRESIZE - 100))) { /* For AMSDU, allow the packets with total length < max-amsdu size */ - return FALSE; - } - - if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) { /* For RALINK-Aggregation, allow two frames in one batch. */ - return FALSE; - } - - if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) /* must be unicast to AP */ - return TRUE; - else - return FALSE; - -} - -/* - ======================================================================== - - Routine Description: - To do the enqueue operation and extract the first item of waiting - list. If a number of available shared memory segments could meet - the request of extracted item, the extracted item will be fragmented - into shared memory segments. - - Arguments: - pAd Pointer to our adapter - pQueue Pointer to Waiting Queue - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 QIdx, /* BulkOutPipeId */ - u8 Max_Tx_Packets) -{ - struct rt_queue_entry *pEntry = NULL; - void *pPacket; - int Status = NDIS_STATUS_SUCCESS; - u8 Count = 0; - struct rt_queue_header *pQueue; - unsigned long FreeNumber[NUM_OF_TX_RING]; - u8 QueIdx, sQIdx, eQIdx; - unsigned long IrqFlags = 0; - BOOLEAN hasTxDesc = FALSE; - struct rt_tx_blk TxBlk; - struct rt_tx_blk *pTxBlk; - - if (QIdx == NUM_OF_TX_RING) { - sQIdx = 0; - eQIdx = 3; /* 4 ACs, start from 0. */ - } else { - sQIdx = eQIdx = QIdx; - } - - for (QueIdx = sQIdx; QueIdx <= eQIdx; QueIdx++) { - Count = 0; - - RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags); - - while (1) { - if ((RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS | - fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); - return; - } - - if (Count >= Max_Tx_Packets) - break; - - DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags); - if (&pAd->TxSwQueue[QueIdx] == NULL) { - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, - IrqFlags); - break; - } -#ifdef RTMP_MAC_PCI - FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); - - if (FreeNumber[QueIdx] <= 5) { - /* free Tx(QueIdx) resources */ - RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); - FreeNumber[QueIdx] = - GET_TXRING_FREENO(pAd, QueIdx); - } -#endif /* RTMP_MAC_PCI // */ - - /* probe the Queue Head */ - pQueue = &pAd->TxSwQueue[QueIdx]; - pEntry = pQueue->Head; - if (pEntry == NULL) { - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, - IrqFlags); - break; - } - - pTxBlk = &TxBlk; - NdisZeroMemory((u8 *)pTxBlk, sizeof(struct rt_tx_blk)); - /*InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it. */ - pTxBlk->QueIdx = QueIdx; - - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - - /* Early check to make sure we have enoguh Tx Resource. */ - hasTxDesc = - RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, - FreeNumber[QueIdx], - pPacket); - if (!hasTxDesc) { - pAd->PrivateInfo.TxRingFullCnt++; - - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, - IrqFlags); - - break; - } - - pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket); - pEntry = RemoveHeadQueue(pQueue); - pTxBlk->TotalFrameNum++; - pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary */ - pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); - pTxBlk->pPacket = pPacket; - InsertTailQueue(&pTxBlk->TxPacketList, - PACKET_TO_QUEUE_ENTRY(pPacket)); - - if (pTxBlk->TxFrameType == TX_RALINK_FRAME - || pTxBlk->TxFrameType == TX_AMSDU_FRAME) { - /* Enhance SW Aggregation Mechanism */ - if (NEED_QUEUE_BACK_FOR_AGG - (pAd, QueIdx, FreeNumber[QueIdx], - pTxBlk->TxFrameType)) { - InsertHeadQueue(pQueue, - PACKET_TO_QUEUE_ENTRY - (pPacket)); - DEQUEUE_UNLOCK(&pAd->irq_lock, - bIntContext, IrqFlags); - break; - } - - do { - pEntry = pQueue->Head; - if (pEntry == NULL) - break; - - /* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */ - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - FreeNumber[QueIdx] = - GET_TXRING_FREENO(pAd, QueIdx); - hasTxDesc = - RTMP_HAS_ENOUGH_FREE_DESC(pAd, - pTxBlk, - FreeNumber - [QueIdx], - pPacket); - if ((hasTxDesc == FALSE) - || - (CanDoAggregateTransmit - (pAd, pPacket, pTxBlk) == FALSE)) - break; - - /*Remove the packet from the TxSwQueue and insert into pTxBlk */ - pEntry = RemoveHeadQueue(pQueue); - ASSERT(pEntry); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - pTxBlk->TotalFrameNum++; - pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary */ - pTxBlk->TotalFrameLen += - GET_OS_PKT_LEN(pPacket); - InsertTailQueue(&pTxBlk->TxPacketList, - PACKET_TO_QUEUE_ENTRY - (pPacket)); - } while (1); - - if (pTxBlk->TxPacketList.Number == 1) - pTxBlk->TxFrameType = TX_LEGACY_FRAME; - } -#ifdef RTMP_MAC_USB - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); -#endif /* RTMP_MAC_USB // */ - Count += pTxBlk->TxPacketList.Number; - - /* Do HardTransmit now. */ - Status = STAHardTransmit(pAd, pTxBlk, QueIdx); - -#ifdef RTMP_MAC_PCI - DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); - /* static rate also need NICUpdateFifoStaCounters() function. */ - /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ - NICUpdateFifoStaCounters(pAd); -#endif /* RTMP_MAC_PCI // */ - - } - - RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); - -#ifdef RTMP_MAC_USB - if (!hasTxDesc) - RTUSBKickBulkOut(pAd); -#endif /* RTMP_MAC_USB // */ - } - -} - -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pAd Pointer to our adapter - Rate Transmit rate - Size Frame size in units of byte - - Return Value: - Duration number in units of usec - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size) -{ - unsigned long Duration = 0; - - if (Rate < RATE_FIRST_OFDM_RATE) /* CCK */ - { - if ((Rate > RATE_1) - && OPSTATUS_TEST_FLAG(pAd, - fOP_STATUS_SHORT_PREAMBLE_INUSED)) - Duration = 96; /* 72+24 preamble+plcp */ - else - Duration = 192; /* 144+48 preamble+plcp */ - - Duration += (u16)((Size << 4) / RateIdTo500Kbps[Rate]); - if ((Size << 4) % RateIdTo500Kbps[Rate]) - Duration++; - } else if (Rate <= RATE_LAST_OFDM_RATE) /* OFDM rates */ - { - Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension */ - Duration += - 4 * (u16)((11 + Size * 4) / RateIdTo500Kbps[Rate]); - if ((11 + Size * 4) % RateIdTo500Kbps[Rate]) - Duration += 4; - } else /*mimo rate */ - { - Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension */ - } - - return (u16)Duration; -} - -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pTxWI Pointer to head of each MPDU to HW. - Ack Setting for Ack requirement bit - Fragment Setting for Fragment bit - RetryMode Setting for retry mode - Ifs Setting for IFS gap - Rate Setting for transmit rate - Service Setting for service - Length Frame length - TxPreamble Short or Long preamble when using CCK rates - QueIdx - 0-3, according to 802.11e/d4.4 June/2003 - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - See also : BASmartHardTransmit() ! - - ======================================================================== -*/ -void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq, /* HW new a sequence. */ - u8 BASize, - u8 WCID, - unsigned long Length, - u8 PID, - u8 TID, - u8 TxRate, - u8 Txopmode, - IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit) -{ - struct rt_mac_table_entry *pMac = NULL; - struct rt_txwi TxWI; - struct rt_txwi * pTxWI; - - if (WCID < MAX_LEN_OF_MAC_TABLE) - pMac = &pAd->MacTab.Content[WCID]; - - /* */ - /* Always use Long preamble before verifiation short preamble functionality works well. */ - /* Todo: remove the following line if short preamble functionality works */ - /* */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - NdisZeroMemory(&TxWI, TXWI_SIZE); - pTxWI = &TxWI; - - pTxWI->FRAG = FRAG; - - pTxWI->CFACK = CFACK; - pTxWI->TS = InsTimestamp; - pTxWI->AMPDU = AMPDU; - pTxWI->ACK = Ack; - pTxWI->txop = Txopmode; - - pTxWI->NSEQ = NSeq; - /* John tune the performace with Intel Client in 20 MHz performance */ - BASize = pAd->CommonCfg.TxBASize; - if (pAd->MACVersion == 0x28720200) { - if (BASize > 13) - BASize = 13; - } else { - if (BASize > 7) - BASize = 7; - } - pTxWI->BAWinSize = BASize; - pTxWI->ShortGI = pTransmit->field.ShortGI; - pTxWI->STBC = pTransmit->field.STBC; - - pTxWI->WirelessCliID = WCID; - pTxWI->MPDUtotalByteCount = Length; - pTxWI->PacketId = PID; - - /* If CCK or OFDM, BW must be 20 */ - pTxWI->BW = - (pTransmit->field.MODE <= - MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); - - pTxWI->MCS = pTransmit->field.MCS; - pTxWI->PHYMODE = pTransmit->field.MODE; - pTxWI->CFACK = CfAck; - - if (pMac) { - if (pAd->CommonCfg.bMIMOPSEnable) { - if ((pMac->MmpsMode == MMPS_DYNAMIC) - && (pTransmit->field.MCS > 7)) { - /* Dynamic MIMO Power Save Mode */ - pTxWI->MIMOps = 1; - } else if (pMac->MmpsMode == MMPS_STATIC) { - /* Static MIMO Power Save Mode */ - if (pTransmit->field.MODE >= MODE_HTMIX - && pTransmit->field.MCS > 7) { - pTxWI->MCS = 7; - pTxWI->MIMOps = 0; - } - } - } - /*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; */ - if (pMac->bIAmBadAtheros - && (pMac->WepStatus != Ndis802_11WEPDisabled)) { - pTxWI->MpduDensity = 7; - } else { - pTxWI->MpduDensity = pMac->MpduDensity; - } - } - - pTxWI->PacketId = pTxWI->MCS; - NdisMoveMemory(pOutTxWI, &TxWI, sizeof(struct rt_txwi)); -} - -void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd, - struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk) -{ - HTTRANSMIT_SETTING *pTransmit; - struct rt_mac_table_entry *pMacEntry; - u8 BASize; - - ASSERT(pTxWI); - - pTransmit = pTxBlk->pTransmit; - pMacEntry = pTxBlk->pMacEntry; - - /* */ - /* Always use Long preamble before verifiation short preamble functionality works well. */ - /* Todo: remove the following line if short preamble functionality works */ - /* */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - NdisZeroMemory(pTxWI, TXWI_SIZE); - - pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag); - pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired); - pTxWI->txop = pTxBlk->FrameGap; - - pTxWI->WirelessCliID = pTxBlk->Wcid; - - pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; - pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack); - - /* If CCK or OFDM, BW must be 20 */ - pTxWI->BW = - (pTransmit->field.MODE <= - MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); - pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE); - - /* John tune the performace with Intel Client in 20 MHz performance */ - BASize = pAd->CommonCfg.TxBASize; - if ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) { - u8 RABAOriIdx = 0; /*The RA's BA Originator table index. */ - - RABAOriIdx = - pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority]; - BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize; - } - - pTxWI->TxBF = pTransmit->field.TxBF; - pTxWI->BAWinSize = BASize; - pTxWI->ShortGI = pTransmit->field.ShortGI; - pTxWI->STBC = pTransmit->field.STBC; - - pTxWI->MCS = pTransmit->field.MCS; - pTxWI->PHYMODE = pTransmit->field.MODE; - - if (pMacEntry) { - if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) - && (pTransmit->field.MCS > 7)) { - /* Dynamic MIMO Power Save Mode */ - pTxWI->MIMOps = 1; - } else if (pMacEntry->MmpsMode == MMPS_STATIC) { - /* Static MIMO Power Save Mode */ - if (pTransmit->field.MODE >= MODE_HTMIX - && pTransmit->field.MCS > 7) { - pTxWI->MCS = 7; - pTxWI->MIMOps = 0; - } - } - - if (pMacEntry->bIAmBadAtheros - && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) { - pTxWI->MpduDensity = 7; - } else { - pTxWI->MpduDensity = pMacEntry->MpduDensity; - } - } - - /* for rate adapation */ - pTxWI->PacketId = pTxWI->MCS; -} - -void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd, - struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk) -{ - PHTTRANSMIT_SETTING /*pTxHTPhyMode, */ pTransmit; - struct rt_mac_table_entry *pMacEntry; - - /* */ - /* update TXWI */ - /* */ - pMacEntry = pTxBlk->pMacEntry; - pTransmit = pTxBlk->pTransmit; - - /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ - /*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) */ - /*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) */ - if (pMacEntry->bAutoTxRateSwitch) { - pTxWI->txop = IFS_HTTXOP; - - /* If CCK or OFDM, BW must be 20 */ - pTxWI->BW = - (pTransmit->field.MODE <= - MODE_OFDM) ? (BW_20) : (pTransmit->field.BW); - pTxWI->ShortGI = pTransmit->field.ShortGI; - pTxWI->STBC = pTransmit->field.STBC; - - pTxWI->MCS = pTransmit->field.MCS; - pTxWI->PHYMODE = pTransmit->field.MODE; - - /* set PID for TxRateSwitching */ - pTxWI->PacketId = pTransmit->field.MCS; - } - - pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE : FALSE); - pTxWI->MIMOps = 0; - - if (pAd->CommonCfg.bMIMOPSEnable) { - /* MIMO Power Save Mode */ - if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) - && (pTransmit->field.MCS > 7)) { - /* Dynamic MIMO Power Save Mode */ - pTxWI->MIMOps = 1; - } else if (pMacEntry->MmpsMode == MMPS_STATIC) { - /* Static MIMO Power Save Mode */ - if ((pTransmit->field.MODE >= MODE_HTMIX) - && (pTransmit->field.MCS > 7)) { - pTxWI->MCS = 7; - pTxWI->MIMOps = 0; - } - } - } - - pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; - -} - -/* should be called only when - */ -/* 1. MEADIA_CONNECTED */ -/* 2. AGGREGATION_IN_USED */ -/* 3. Fragmentation not in used */ -/* 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible */ -BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd, - u8 *pPrevAddr1, u8 *p8023hdr) -{ - - /* can't aggregate EAPOL (802.1x) frame */ - if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e)) - return FALSE; - - /* can't aggregate multicast/broadcast frame */ - if (p8023hdr[0] & 0x01) - return FALSE; - - if (INFRA_ON(pAd)) /* must be unicast to AP */ - return TRUE; - else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) /* unicast to same STA */ - return TRUE; - else - return FALSE; -} - -/* - ======================================================================== - - Routine Description: - Check the MSDU Aggregation policy - 1.HT aggregation is A-MSDU - 2.legaacy rate aggregation is software aggregation by Ralink. - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd, - unsigned long TxRate, struct rt_mac_table_entry *pMacEntry) -{ - unsigned long AFlags = - (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE); - - if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) { - if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) { - return TRUE; - } -#ifdef AGGREGATION_SUPPORT - if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { /* legacy Ralink Aggregation support */ - return TRUE; - } -#endif /* AGGREGATION_SUPPORT // */ - } - - return FALSE; - -} - -/* - ======================================================================== - - Routine Description: - Check and fine the packet waiting in SW queue with highest priority - - Arguments: - pAd Pointer to our adapter - - Return Value: - pQueue Pointer to Waiting Queue - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 *pQueIdx) -{ - - unsigned long Number; - /* 2004-11-15 to be removed. test aggregation only */ -/* if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) */ -/* return NULL; */ - - Number = pAd->TxSwQueue[QID_AC_BK].Number - + pAd->TxSwQueue[QID_AC_BE].Number - + pAd->TxSwQueue[QID_AC_VI].Number - + pAd->TxSwQueue[QID_AC_VO].Number; - - if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) { - *pQueIdx = QID_AC_VO; - return (&pAd->TxSwQueue[QID_AC_VO]); - } else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL) { - *pQueIdx = QID_AC_VI; - return (&pAd->TxSwQueue[QID_AC_VI]); - } else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL) { - *pQueIdx = QID_AC_BE; - return (&pAd->TxSwQueue[QID_AC_BE]); - } else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL) { - *pQueIdx = QID_AC_BK; - return (&pAd->TxSwQueue[QID_AC_BK]); - } - /* No packet pending in Tx Sw queue */ - *pQueIdx = QID_AC_BK; - - return (NULL); -} - -/* - ======================================================================== - - Routine Description: - Suspend MSDU transmission - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd) -{ - DBGPRINT(RT_DEBUG_TRACE, ("SCANNING, suspend MSDU transmission ...\n")); - - /* */ - /* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and */ - /* use Lowbound as R66 value on ScanNextChannel(...) */ - /* */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, - &pAd->BbpTuning.R66CurrentValue); - - /* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) */ - /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); */ - RTMPSetAGCInitValue(pAd, BW_20); - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings */ -} - -/* - ======================================================================== - - Routine Description: - Resume MSDU transmission - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd) -{ -/* u8 IrqState; */ - - DBGPRINT(RT_DEBUG_TRACE, ("SCAN done, resume MSDU transmission ...\n")); - - /* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value */ - /* R66 should not be 0 */ - if (pAd->BbpTuning.R66CurrentValue == 0) { - pAd->BbpTuning.R66CurrentValue = 0x38; - DBGPRINT_ERR("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"); - } - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, - pAd->BbpTuning.R66CurrentValue); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); -/* sample, for IRQ LOCK to SEM LOCK */ -/* IrqState = pAd->irq_disabled; */ -/* if (IrqState) */ -/* RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); */ -/* else */ - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); -} - -u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pData, unsigned long DataSize) -{ - u16 PayloadSize; - u16 SubFrameSize; - struct rt_header_802_3 * pAMSDUsubheader; - u32 nMSDU; - u8 Header802_3[14]; - - u8 *pPayload, *pDA, *pSA, *pRemovedLLCSNAP; - void *pClonePacket; - - nMSDU = 0; - - while (DataSize > LENGTH_802_3) { - - nMSDU++; - - /*hex_dump("subheader", pData, 64); */ - pAMSDUsubheader = (struct rt_header_802_3 *) pData; - /*pData += LENGTH_802_3; */ - PayloadSize = - pAMSDUsubheader->Octet[1] + - (pAMSDUsubheader->Octet[0] << 8); - SubFrameSize = PayloadSize + LENGTH_802_3; - - if ((DataSize < SubFrameSize) || (PayloadSize > 1518)) { - break; - } - /*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n", nMSDU, PayloadSize)); */ - - pPayload = pData + LENGTH_802_3; - pDA = pData; - pSA = pData + MAC_ADDR_LEN; - - /* convert to 802.3 header */ - CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, - pRemovedLLCSNAP); - - if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) { - /* avoid local heap overflow, use dyanamic allocation */ - struct rt_mlme_queue_elem *Elem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - if (Elem != NULL) { - memmove(Elem->Msg + - (LENGTH_802_11 + LENGTH_802_1_H), - pPayload, PayloadSize); - Elem->MsgLen = - LENGTH_802_11 + LENGTH_802_1_H + - PayloadSize; - /*WpaEAPOLKeyAction(pAd, Elem); */ - REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, - Elem->Msg, - Elem->MsgLen, 0, 0, 0, - 0); - kfree(Elem); - } - } - - { - if (pRemovedLLCSNAP) { - pPayload -= LENGTH_802_3; - PayloadSize += LENGTH_802_3; - NdisMoveMemory(pPayload, &Header802_3[0], - LENGTH_802_3); - } - } - - pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize); - if (pClonePacket) { - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, - RTMP_GET_PACKET_IF - (pPacket)); - } - - /* A-MSDU has padding to multiple of 4 including subframe header. */ - /* align SubFrameSize up to multiple of 4 */ - SubFrameSize = (SubFrameSize + 3) & (~0x3); - - if (SubFrameSize > 1528 || SubFrameSize < 32) { - break; - } - - if (DataSize > SubFrameSize) { - pData += SubFrameSize; - DataSize -= SubFrameSize; - } else { - /* end of A-MSDU */ - DataSize = 0; - } - } - - /* finally release original rx packet */ - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - - return nMSDU; -} - -u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - u8 *pData; - u16 DataSize; - u32 nMSDU = 0; - - pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket); - DataSize = (u16)GET_OS_PKT_LEN(pPacket); - - nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize); - - return nMSDU; -} - -/* - ========================================================================== - Description: - Look up the MAC address in the MAC table. Return NULL if not found. - Return: - pEntry - pointer to the MAC entry; NULL is not found - ========================================================================== -*/ -struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr) -{ - unsigned long HashIdx; - struct rt_mac_table_entry *pEntry = NULL; - - HashIdx = MAC_ADDR_HASH_INDEX(pAddr); - pEntry = pAd->MacTab.Hash[HashIdx]; - - while (pEntry - && (pEntry->ValidAsCLI || pEntry->ValidAsWDS - || pEntry->ValidAsApCli || pEntry->ValidAsMesh)) { - if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { - break; - } else - pEntry = pEntry->pNext; - } - - return pEntry; -} - -struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd, - u8 *pAddr, - u8 apidx, IN BOOLEAN CleanAll) -{ - u8 HashIdx; - int i, FirstWcid; - struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry; -/* u16 offset; */ -/* unsigned long addr; */ - - /* if FULL, return */ - if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) - return NULL; - - FirstWcid = 1; - - if (pAd->StaCfg.BssType == BSS_INFRA) - FirstWcid = 2; - - /* allocate one MAC entry */ - NdisAcquireSpinLock(&pAd->MacTabLock); - for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup */ - { - /* pick up the first available vacancy */ - if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) && - (pAd->MacTab.Content[i].ValidAsWDS == FALSE) && - (pAd->MacTab.Content[i].ValidAsApCli == FALSE) && - (pAd->MacTab.Content[i].ValidAsMesh == FALSE) - ) { - pEntry = &pAd->MacTab.Content[i]; - if (CleanAll == TRUE) { - pEntry->MaxSupportedRate = RATE_11; - pEntry->CurrTxRate = RATE_11; - NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry)); - pEntry->PairwiseKey.KeyLen = 0; - pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - } - { - { - pEntry->ValidAsCLI = TRUE; - pEntry->ValidAsWDS = FALSE; - pEntry->ValidAsApCli = FALSE; - pEntry->ValidAsMesh = FALSE; - pEntry->ValidAsDls = FALSE; - } - } - - pEntry->bIAmBadAtheros = FALSE; - pEntry->pAd = pAd; - pEntry->CMTimerRunning = FALSE; - pEntry->EnqueueEapolStartTimerRunning = - EAPOL_START_DISABLE; - pEntry->RSNIE_Len = 0; - NdisZeroMemory(pEntry->R_Counter, - sizeof(pEntry->R_Counter)); - pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; - - if (pEntry->ValidAsMesh) - pEntry->apidx = - (apidx - MIN_NET_DEVICE_FOR_MESH); - else if (pEntry->ValidAsApCli) - pEntry->apidx = - (apidx - MIN_NET_DEVICE_FOR_APCLI); - else if (pEntry->ValidAsWDS) - pEntry->apidx = - (apidx - MIN_NET_DEVICE_FOR_WDS); - else - pEntry->apidx = apidx; - - { - { - pEntry->AuthMode = pAd->StaCfg.AuthMode; - pEntry->WepStatus = - pAd->StaCfg.WepStatus; - pEntry->PrivacyFilter = - Ndis802_11PrivFilterAcceptAll; -#ifdef RTMP_MAC_PCI - AsicRemovePairwiseKeyEntry(pAd, - pEntry-> - apidx, - (u8)i); -#endif /* RTMP_MAC_PCI // */ - } - } - - pEntry->GTKState = REKEY_NEGOTIATING; - pEntry->PairwiseKey.KeyLen = 0; - pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; - - pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; - COPY_MAC_ADDR(pEntry->Addr, pAddr); - pEntry->Sst = SST_NOT_AUTH; - pEntry->AuthState = AS_NOT_AUTH; - pEntry->Aid = (u16)i; /*0; */ - pEntry->CapabilityInfo = 0; - pEntry->PsMode = PWR_ACTIVE; - pEntry->PsQIdleCount = 0; - pEntry->NoDataIdleCount = 0; - pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; - pEntry->ContinueTxFailCnt = 0; - InitializeQueueHeader(&pEntry->PsQueue); - - pAd->MacTab.Size++; - /* Add this entry into ASIC RX WCID search table */ - RTMP_STA_ENTRY_ADD(pAd, pEntry); - - DBGPRINT(RT_DEBUG_TRACE, - ("MacTableInsertEntry - allocate entry #%d, Total= %d\n", - i, pAd->MacTab.Size)); - break; - } - } - - /* add this MAC entry into HASH table */ - if (pEntry) { - HashIdx = MAC_ADDR_HASH_INDEX(pAddr); - if (pAd->MacTab.Hash[HashIdx] == NULL) { - pAd->MacTab.Hash[HashIdx] = pEntry; - } else { - pCurrEntry = pAd->MacTab.Hash[HashIdx]; - while (pCurrEntry->pNext != NULL) - pCurrEntry = pCurrEntry->pNext; - pCurrEntry->pNext = pEntry; - } - } - - NdisReleaseSpinLock(&pAd->MacTabLock); - return pEntry; -} - -/* - ========================================================================== - Description: - Delete a specified client from MAC table - ========================================================================== - */ -BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd, - u16 wcid, u8 *pAddr) -{ - u16 HashIdx; - struct rt_mac_table_entry *pEntry, *pPrevEntry, *pProbeEntry; - BOOLEAN Cancelled; - /*u16 offset; // unused variable */ - /*u8 j; // unused variable */ - - if (wcid >= MAX_LEN_OF_MAC_TABLE) - return FALSE; - - NdisAcquireSpinLock(&pAd->MacTabLock); - - HashIdx = MAC_ADDR_HASH_INDEX(pAddr); - /*pEntry = pAd->MacTab.Hash[HashIdx]; */ - pEntry = &pAd->MacTab.Content[wcid]; - - if (pEntry - && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS - || pEntry->ValidAsMesh)) { - if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) { - - /* Delete this entry from ASIC on-chip WCID Table */ - RTMP_STA_ENTRY_MAC_RESET(pAd, wcid); - - /* free resources of BA */ - BASessionTearDownALL(pAd, pEntry->Aid); - - pPrevEntry = NULL; - pProbeEntry = pAd->MacTab.Hash[HashIdx]; - ASSERT(pProbeEntry); - - /* update Hash list */ - do { - if (pProbeEntry == pEntry) { - if (pPrevEntry == NULL) { - pAd->MacTab.Hash[HashIdx] = - pEntry->pNext; - } else { - pPrevEntry->pNext = - pEntry->pNext; - } - break; - } - - pPrevEntry = pProbeEntry; - pProbeEntry = pProbeEntry->pNext; - } while (pProbeEntry); - - /* not found ! */ - ASSERT(pProbeEntry != NULL); - - RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid); - - if (pEntry->EnqueueEapolStartTimerRunning != - EAPOL_START_DISABLE) { - RTMPCancelTimer(&pEntry-> - EnqueueStartForPSKTimer, - &Cancelled); - pEntry->EnqueueEapolStartTimerRunning = - EAPOL_START_DISABLE; - } - - NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry)); - pAd->MacTab.Size--; - DBGPRINT(RT_DEBUG_TRACE, - ("MacTableDeleteEntry1 - Total= %d\n", - pAd->MacTab.Size)); - } else { - DBGPRINT(RT_DEBUG_OFF, - ("\n%s: Impossible Wcid = %d !\n", - __func__, wcid)); - } - } - - NdisReleaseSpinLock(&pAd->MacTabLock); - - /*Reset operating mode when no Sta. */ - if (pAd->MacTab.Size == 0) { - pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0; - RTMP_UPDATE_PROTECT(pAd); /* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ - } - - return TRUE; -} - -/* - ========================================================================== - Description: - This routine reset the entire MAC table. All packets pending in - the power-saving queues are freed here. - ========================================================================== - */ -void MacTableReset(struct rt_rtmp_adapter *pAd) -{ - int i; - - DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n")); - /*NdisAcquireSpinLock(&pAd->MacTabLock); */ - - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { -#ifdef RTMP_MAC_PCI - RTMP_STA_ENTRY_MAC_RESET(pAd, i); -#endif /* RTMP_MAC_PCI // */ - if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) { - - /* free resources of BA */ - BASessionTearDownALL(pAd, i); - - pAd->MacTab.Content[i].ValidAsCLI = FALSE; - -#ifdef RTMP_MAC_USB - NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6); - RTMP_STA_ENTRY_MAC_RESET(pAd, i); -#endif /* RTMP_MAC_USB // */ - - /*AsicDelWcidTab(pAd, i); */ - } - } - - return; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void AssocParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_assoc_req *AssocReq, - u8 *pAddr, - u16 CapabilityInfo, - unsigned long Timeout, u16 ListenIntv) -{ - COPY_MAC_ADDR(AssocReq->Addr, pAddr); - /* Add mask to support 802.11b mode only */ - AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; /* not cf-pollable, not cf-poll-request */ - AssocReq->Timeout = Timeout; - AssocReq->ListenIntv = ListenIntv; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void DisassocParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_disassoc_req *DisassocReq, - u8 *pAddr, u16 Reason) -{ - COPY_MAC_ADDR(DisassocReq->Addr, pAddr); - DisassocReq->Reason = Reason; -} - -/* - ======================================================================== - - Routine Description: - Check the out going frame, if this is an DHCP or ARP datagram - will be duplicate another frame at low data rate transmit. - - Arguments: - pAd Pointer to our adapter - pPacket Pointer to outgoing Ndis frame - - Return Value: - TRUE To be duplicate at Low data rate transmit. (1mb) - FALSE Do nothing. - - IRQL = DISPATCH_LEVEL - - Note: - - MAC header + IP Header + UDP Header - 14 Bytes 20 Bytes - - UDP Header - 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| - Source Port - 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| - Destination Port - - port 0x43 means Bootstrap Protocol, server. - Port 0x44 means Bootstrap Protocol, client. - - ======================================================================== -*/ - -BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - struct rt_packet_info PacketInfo; - unsigned long NumberOfBytesRead = 0; - unsigned long CurrentOffset = 0; - void *pVirtualAddress = NULL; - u32 NdisBufferLength; - u8 *pSrc; - u16 Protocol; - u8 ByteOffset36 = 0; - u8 ByteOffset38 = 0; - BOOLEAN ReadFirstParm = TRUE; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, (u8 **) & pVirtualAddress, - &NdisBufferLength); - - NumberOfBytesRead += NdisBufferLength; - pSrc = (u8 *)pVirtualAddress; - Protocol = *(pSrc + 12) * 256 + *(pSrc + 13); - - /* */ - /* Check DHCP & BOOTP protocol */ - /* */ - while (NumberOfBytesRead <= PacketInfo.TotalPacketLength) { - if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE)) { - CurrentOffset = - 35 - (NumberOfBytesRead - NdisBufferLength); - ByteOffset36 = *(pSrc + CurrentOffset); - ReadFirstParm = FALSE; - } - - if (NumberOfBytesRead >= 37) { - CurrentOffset = - 37 - (NumberOfBytesRead - NdisBufferLength); - ByteOffset38 = *(pSrc + CurrentOffset); - /*End of Read */ - break; - } - return FALSE; - } - - /* Check for DHCP & BOOTP protocol */ - if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43)) { - /* */ - /* 2054 (hex 0806) for ARP datagrams */ - /* if this packet is not ARP datagrams, then do nothing */ - /* ARP datagrams will also be duplicate at 1mb broadcast frames */ - /* */ - if (Protocol != 0x0806) - return FALSE; - } - - return TRUE; -} - -BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - u16 TypeLen; - u8 Byte0, Byte1; - u8 *pSrcBuf; - u32 pktLen; - u16 srcPort, dstPort; - BOOLEAN status = TRUE; - - pSrcBuf = GET_OS_PKT_DATAPTR(pPacket); - pktLen = GET_OS_PKT_LEN(pPacket); - - ASSERT(pSrcBuf); - - RTMP_SET_PACKET_SPECIFIC(pPacket, 0); - - /* get Ethernet protocol field */ - TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13]; - - pSrcBuf += LENGTH_802_3; /* Skip the Ethernet Header. */ - - if (TypeLen <= 1500) { /* 802.3, 802.3 LLC */ - /* - DestMAC(6) + SrcMAC(6) + Length(2) + - DSAP(1) + SSAP(1) + Control(1) + - if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header. - => + SNAP (5, OriginationID(3) + etherType(2)) - */ - if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA - && pSrcBuf[2] == 0x03) { - Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 6, - &Byte0, &Byte1); - RTMP_SET_PACKET_LLCSNAP(pPacket, 1); - TypeLen = (u16)((Byte0 << 8) + Byte1); - pSrcBuf += 8; /* Skip this LLC/SNAP header */ - } else { - /*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it. */ - } - } - /* If it's a VLAN packet, get the real Type/Length field. */ - if (TypeLen == 0x8100) { - /* 0x8100 means VLAN packets */ - - /* Dest. MAC Address (6-bytes) + - Source MAC Address (6-bytes) + - Length/Type = 802.1Q Tag Type (2-byte) + - Tag Control Information (2-bytes) + - Length / Type (2-bytes) + - data payload (0-n bytes) + - Pad (0-p bytes) + - Frame Check Sequence (4-bytes) */ - - RTMP_SET_PACKET_VLAN(pPacket, 1); - Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 2, &Byte0, - &Byte1); - TypeLen = (u16)((Byte0 << 8) + Byte1); - - pSrcBuf += 4; /* Skip the VLAN Header. */ - } - - switch (TypeLen) { - case 0x0800: - { - ASSERT((pktLen > 34)); - if (*(pSrcBuf + 9) == 0x11) { /* udp packet */ - ASSERT((pktLen > 34)); /* 14 for ethernet header, 20 for IP header */ - - pSrcBuf += 20; /* Skip the IP header */ - srcPort = - OS_NTOHS(get_unaligned - ((u16 *)(pSrcBuf))); - dstPort = - OS_NTOHS(get_unaligned - ((u16 *)(pSrcBuf + 2))); - - if ((srcPort == 0x44 && dstPort == 0x43) || (srcPort == 0x43 && dstPort == 0x44)) { /*It's a BOOTP/DHCP packet */ - RTMP_SET_PACKET_DHCP(pPacket, 1); - } - } - } - break; - case 0x0806: - { - /*ARP Packet. */ - RTMP_SET_PACKET_DHCP(pPacket, 1); - } - break; - case 0x888e: - { - /* EAPOL Packet. */ - RTMP_SET_PACKET_EAPOL(pPacket, 1); - } - break; - default: - status = FALSE; - break; - } - - return status; - -} - -void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd, - struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI) -{ - char rssi0 = pRxWI->RSSI0; - char rssi1 = pRxWI->RSSI1; - char rssi2 = pRxWI->RSSI2; - - if (rssi0 != 0) { - pRssi->LastRssi0 = ConvertToRssi(pAd, (char)rssi0, RSSI_0); - pRssi->AvgRssi0X8 = - (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0; - pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3; - } - - if (rssi1 != 0) { - pRssi->LastRssi1 = ConvertToRssi(pAd, (char)rssi1, RSSI_1); - pRssi->AvgRssi1X8 = - (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1; - pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3; - } - - if (rssi2 != 0) { - pRssi->LastRssi2 = ConvertToRssi(pAd, (char)rssi2, RSSI_2); - pRssi->AvgRssi2X8 = - (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2; - pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3; - } -} - -/* Normal legacy Rx packet indication */ -void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - void *pRxPacket = pRxBlk->pRxPacket; - u8 Header802_3[LENGTH_802_3]; - - /* 1. get 802.3 Header */ - /* 2. remove LLC */ - /* a. pointer pRxBlk->pData to payload */ - /* b. modify pRxBlk->DataSize */ - RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); - - if (pRxBlk->DataSize > MAX_RX_PKT_LEN) { - - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); - return; - } - - STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); - -#ifdef RTMP_MAC_USB - if (pAd->CommonCfg.bDisableReordering == 0) { - struct rt_ba_rec_entry *pBAEntry; - unsigned long Now32; - u8 Wcid = pRxBlk->pRxWI->WirelessCliID; - u8 TID = pRxBlk->pRxWI->TID; - u16 Idx; - -#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms */ - - if (Wcid < MAX_LEN_OF_MAC_TABLE) { - Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; - if (Idx != 0) { - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - /* update last rx time */ - NdisGetSystemUpTime(&Now32); - if ((pBAEntry->list.qlen > 0) && - RTMP_TIME_AFTER((unsigned long)Now32, - (unsigned long)(pBAEntry-> - LastIndSeqAtTimer - + - (REORDERING_PACKET_TIMEOUT))) - ) { - DBGPRINT(RT_DEBUG_OFF, - ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", - pRxBlk->Flags, - pRxBlk->pRxWI->TID, - pRxBlk->RxD.AMPDU)); - hex_dump("Dump the legacy Packet:", - GET_OS_PKT_DATAPTR(pRxBlk-> - pRxPacket), - 64); - ba_flush_reordering_timeout_mpdus(pAd, - pBAEntry, - Now32); - } - } - } - } -#endif /* RTMP_MAC_USB // */ - - wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID); - - /* */ - /* pass this 802.3 packet to upper layer or forward this packet to WM directly */ - /* */ - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID); -} - -/* Normal, AMPDU or AMSDU */ -void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) - && (pAd->CommonCfg.bDisableReordering == 0)) { - Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID); - } else { - if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) { - /* handle A-MSDU */ - Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID); - } else { - Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); - } - } -} - -void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - u8 Header802_3[LENGTH_802_3]; - u16 Msdu2Size; - u16 Payload1Size, Payload2Size; - u8 *pData2; - void *pPacket2 = NULL; - - Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData + 1) << 8); - - if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) { - /* skip two byte MSDU2 len */ - pRxBlk->pData += 2; - pRxBlk->DataSize -= 2; - } else { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - - /* get 802.3 Header and remove LLC */ - RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3); - - ASSERT(pRxBlk->pRxPacket); - - /* Ralink Aggregation frame */ - pAd->RalinkCounters.OneSecRxAggregationCount++; - Payload1Size = pRxBlk->DataSize - Msdu2Size; - Payload2Size = Msdu2Size - LENGTH_802_3; - - pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3; - - pPacket2 = - duplicate_pkt(pAd, (pData2 - LENGTH_802_3), LENGTH_802_3, pData2, - Payload2Size, FromWhichBSSID); - - if (!pPacket2) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - /* update payload size of 1st packet */ - pRxBlk->DataSize = Payload1Size; - wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID); - - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, - FromWhichBSSID); - - if (pPacket2) { - ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID); - } -} - -#define RESET_FRAGFRAME(_fragFrame) \ - { \ - _fragFrame.RxSize = 0; \ - _fragFrame.Sequence = 0; \ - _fragFrame.LastFrag = 0; \ - _fragFrame.Flags = 0; \ - } - -void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) -{ - struct rt_header_802_11 * pHeader = pRxBlk->pHeader; - void *pRxPacket = pRxBlk->pRxPacket; - u8 *pData = pRxBlk->pData; - u16 DataSize = pRxBlk->DataSize; - void *pRetPacket = NULL; - u8 *pFragBuffer = NULL; - BOOLEAN bReassDone = FALSE; - u8 HeaderRoom = 0; - - ASSERT(pHeader); - - HeaderRoom = pData - (u8 *) pHeader; - - /* Re-assemble the fragmented packets */ - if (pHeader->Frag == 0) /* Frag. Number is 0 : First frag or only one pkt */ - { - /* the first pkt of fragment, record it. */ - if (pHeader->FC.MoreFrag) { - ASSERT(pAd->FragFrame.pFragPacket); - pFragBuffer = - GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket); - pAd->FragFrame.RxSize = DataSize + HeaderRoom; - NdisMoveMemory(pFragBuffer, pHeader, - pAd->FragFrame.RxSize); - pAd->FragFrame.Sequence = pHeader->Sequence; - pAd->FragFrame.LastFrag = pHeader->Frag; /* Should be 0 */ - ASSERT(pAd->FragFrame.LastFrag == 0); - goto done; /* end of processing this frame */ - } - } else /*Middle & End of fragment */ - { - if ((pHeader->Sequence != pAd->FragFrame.Sequence) || - (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) { - /* Fragment is not the same sequence or out of fragment number order */ - /* Reset Fragment control blk */ - RESET_FRAGFRAME(pAd->FragFrame); - DBGPRINT(RT_DEBUG_ERROR, - ("Fragment is not the same sequence or out of fragment number order.\n")); - goto done; /* give up this frame */ - } else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) { - /* Fragment frame is too large, it exeeds the maximum frame size. */ - /* Reset Fragment control blk */ - RESET_FRAGFRAME(pAd->FragFrame); - DBGPRINT(RT_DEBUG_ERROR, - ("Fragment frame is too large, it exeeds the maximum frame size.\n")); - goto done; /* give up this frame */ - } - /* */ - /* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment. */ - /* In this case, we will dropt it. */ - /* */ - if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) { - DBGPRINT(RT_DEBUG_ERROR, - ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", - pHeader->Sequence, pHeader->Frag)); - goto done; /* give up this frame */ - } - - pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket); - - /* concatenate this fragment into the re-assembly buffer */ - NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, - DataSize); - pAd->FragFrame.RxSize += DataSize; - pAd->FragFrame.LastFrag = pHeader->Frag; /* Update fragment number */ - - /* Last fragment */ - if (pHeader->FC.MoreFrag == FALSE) { - bReassDone = TRUE; - } - } - -done: - /* always release rx fragmented packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); - - /* return defragmented packet if packet is reassembled completely */ - /* otherwise return NULL */ - if (bReassDone) { - void *pNewFragPacket; - - /* allocate a new packet buffer for fragment */ - pNewFragPacket = - RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); - if (pNewFragPacket) { - /* update RxBlk */ - pRetPacket = pAd->FragFrame.pFragPacket; - pAd->FragFrame.pFragPacket = pNewFragPacket; - pRxBlk->pHeader = - (struct rt_header_802_11 *) GET_OS_PKT_DATAPTR(pRetPacket); - pRxBlk->pData = (u8 *) pRxBlk->pHeader + HeaderRoom; - pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom; - pRxBlk->pRxPacket = pRetPacket; - } else { - RESET_FRAGFRAME(pAd->FragFrame); - } - } - - return pRetPacket; -} - -void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - u32 nMSDU; - - update_os_packet_info(pAd, pRxBlk, FromWhichBSSID); - RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID); - nMSDU = - deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, - pRxBlk->DataSize); -} - -void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - struct rt_mac_table_entry *pEntry = NULL; - - { - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID); - return; - } - - if (pEntry == NULL) { - DBGPRINT(RT_DEBUG_WARN, - ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n")); - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } -} - -#define BCN_TBTT_OFFSET 64 /*defer 64 us */ -void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd) -{ - - u32 Offset; - - Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET); - - pAd->TbttTickCount++; - - /* */ - /* The updated BeaconInterval Value will affect Beacon Interval after two TBTT */ - /* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER */ - /* */ - if (Offset == (BCN_TBTT_OFFSET - 2)) { - BCN_TIME_CFG_STRUC csr; - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); - csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1; /* ASIC register in units of 1/16 TU = 64us */ - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); - } else { - if (Offset == (BCN_TBTT_OFFSET - 1)) { - BCN_TIME_CFG_STRUC csr; - - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); - csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; /* ASIC register in units of 1/16 TU */ - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); - } - } -} diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c deleted file mode 100644 index bef0bbd8cef7..000000000000 --- a/drivers/staging/rt2860/common/cmm_data_pci.c +++ /dev/null @@ -1,1096 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -/* - All functions in this file must be PCI-depended, or you should out your function - in other files. - -*/ -#include "../rt_config.h" - -u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 * FreeNumber) -{ - - u8 *pDMAHeaderBufVA; - u16 TxIdx, RetTxIdx; - struct rt_txd * pTxD; - u32 BufBasePaLow; - struct rt_rtmp_tx_ring *pTxRing; - u16 hwHeaderLen; - - /* */ - /* get Tx Ring Resource */ - /* */ - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = - RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */ - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) { - /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */ - hwHeaderLen = - pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + - pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; - } else { - /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - } - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, - TXINFO_SIZE + TXWI_SIZE + hwHeaderLen); - - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - - /* */ - /* build Tx Descriptor */ - /* */ - - pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa; - NdisZeroMemory(pTxD, TXD_SIZE); - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */ - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = (bIsLast) ? 1 : 0; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - /* */ - /* Update Tx index */ - /* */ - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; -} - -u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, - u16 * FreeNumber) -{ - - u8 *pDMAHeaderBufVA; - u16 TxIdx, RetTxIdx; - struct rt_txd * pTxD; - u32 BufBasePaLow; - struct rt_rtmp_tx_ring *pTxRing; - u16 hwHeaderLen; - - /* */ - /* get Tx Ring Resource */ - /* */ - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = - RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */ - /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, - TXINFO_SIZE + TXWI_SIZE + hwHeaderLen); - - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - - /* */ - /* build Tx Descriptor */ - /* */ - pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa; - NdisZeroMemory(pTxD, TXD_SIZE); - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */ - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = (bIsLast) ? 1 : 0; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - /* */ - /* Update Tx index */ - /* */ - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; -} - -u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 frameNum, u16 * FreeNumber) -{ - BOOLEAN bIsLast; - u8 *pDMAHeaderBufVA; - u16 TxIdx, RetTxIdx; - struct rt_txd * pTxD; - u32 BufBasePaLow; - struct rt_rtmp_tx_ring *pTxRing; - u16 hwHdrLen; - u32 firstDMALen; - - bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0); - - /* */ - /* get Tx Ring Resource */ - /* */ - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = - RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - if (frameNum == 0) { - /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */ - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */ - hwHdrLen = - pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + - pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; - else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */ - hwHdrLen = - pTxBlk->MpduHeaderLen - - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + - LENGTH_ARALINK_HEADER_FIELD; - else - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; - } else { - firstDMALen = pTxBlk->MpduHeaderLen; - } - - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen); - - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - - /* */ - /* build Tx Descriptor */ - /* */ - pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa; - NdisZeroMemory(pTxD, TXD_SIZE); - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = firstDMALen; /* include padding */ - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = (bIsLast) ? 1 : 0; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - /* */ - /* Update Tx index */ - /* */ - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; - -} - -void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u16 totalMPDUSize, u16 FirstTxIdx) -{ - - struct rt_txwi * pTxWI; - struct rt_rtmp_tx_ring *pTxRing; - - /* */ - /* get Tx Ring Resource */ - /* */ - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - pTxWI = (struct rt_txwi *) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa; - pTxWI->MPDUtotalByteCount = totalMPDUSize; - -} - -void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u16 LastTxIdx) -{ - struct rt_txd * pTxD; - struct rt_rtmp_tx_ring *pTxRing; - - /* */ - /* get Tx Ring Resource */ - /* */ - pTxRing = &pAd->TxRing[QueIdx]; - - /* */ - /* build Tx Descriptor */ - /* */ - pTxD = (struct rt_txd *) pTxRing->Cell[LastTxIdx].AllocVa; - - pTxD->LastSec1 = 1; - -} - -u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 fragNum, u16 * FreeNumber) -{ - u8 *pDMAHeaderBufVA; - u16 TxIdx, RetTxIdx; - struct rt_txd * pTxD; - u32 BufBasePaLow; - struct rt_rtmp_tx_ring *pTxRing; - u16 hwHeaderLen; - u32 firstDMALen; - - /* */ - /* Get Tx Ring Resource */ - /* */ - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = - RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - /* */ - /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */ - /* */ - /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen); - - /* */ - /* Build Tx Descriptor */ - /* */ - pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa; - NdisZeroMemory(pTxD, TXD_SIZE); - - if (fragNum == pTxBlk->TotalFragNum) { - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - } - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = firstDMALen; /* include padding */ - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = 1; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - pTxBlk->Priv += pTxBlk->SrcBufLen; - - /* */ - /* Update Tx index */ - /* */ - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; - -} - -/* - Must be run in Interrupt context - This function handle PCI specific TxDesc and cpu index update and kick the packet out. - */ -int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - void *pPacket, - u8 *pSrcBufVA, u32 SrcBufLen) -{ - struct rt_txd * pTxD; - unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx; - - pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[SwIdx].AllocVa; - - pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket; - pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL; - - RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT); - pTxD->LastSec0 = 1; - pTxD->LastSec1 = 1; - pTxD->DMADONE = 0; - pTxD->SDLen1 = 0; - pTxD->SDPtr0 = - PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); - pTxD->SDLen0 = SrcBufLen; - -/*================================================================== */ -/* DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n")); - for (i = 0; i < (TXWI_SIZE+24); i++) - { - - DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i))); - if ( i%4 == 3) - DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: ")); - if ( i%16 == 15) - DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n ")); - } - DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n "));*/ -/*======================================================================= */ - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - /* Increase TX_CTX_IDX, but write to register later. */ - INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); - - RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); - - return 0; -} - -/* - ======================================================================== - - Routine Description: - Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound - - Arguments: - pRxD Pointer to the Rx descriptor - - Return Value: - NDIS_STATUS_SUCCESS No err - NDIS_STATUS_FAILURE Error - - Note: - - ======================================================================== -*/ -int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHeader, - struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD) -{ - struct rt_cipher_key *pWpaKey; - int dBm; - - /* Phy errors & CRC errors */ - if ( /*(pRxD->PhyErr) || */ (pRxD->Crc)) { - /* Check RSSI for Noise Hist statistic collection. */ - dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; - if (dBm <= -87) - pAd->StaCfg.RPIDensity[0] += 1; - else if (dBm <= -82) - pAd->StaCfg.RPIDensity[1] += 1; - else if (dBm <= -77) - pAd->StaCfg.RPIDensity[2] += 1; - else if (dBm <= -72) - pAd->StaCfg.RPIDensity[3] += 1; - else if (dBm <= -67) - pAd->StaCfg.RPIDensity[4] += 1; - else if (dBm <= -62) - pAd->StaCfg.RPIDensity[5] += 1; - else if (dBm <= -57) - pAd->StaCfg.RPIDensity[6] += 1; - else if (dBm > -57) - pAd->StaCfg.RPIDensity[7] += 1; - - return (NDIS_STATUS_FAILURE); - } - /* Add Rx size to channel load counter, we should ignore error counts */ - pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14); - - /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */ - if (pHeader != NULL) { - if (pHeader->FC.ToDs) { - return (NDIS_STATUS_FAILURE); - } - } - /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ - /* I am kind of doubting the U2M bit operation */ - /* if (pRxD->U2M == 0) */ - /* return(NDIS_STATUS_FAILURE); */ - - /* drop decyption fail frame */ - if (pRxD->CipherErr) { - if (pRxD->CipherErr == 2) { - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("pRxD ERROR: ICV ok but MICErr ")); - } else if (pRxD->CipherErr == 1) { - DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxD ERROR: ICV Err ")); - } else if (pRxD->CipherErr == 3) - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("pRxD ERROR: Key not valid ")); - - if (((pRxD->CipherErr & 1) == 1) - && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) - RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - - DBGPRINT_RAW(RT_DEBUG_TRACE, - (" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n", - pRxD->CipherErr, pRxD->SDL0, - pRxD->Mcast | pRxD->Bcast, pRxD->MyBss, - pRxWI->WirelessCliID, -/* CipherName[pRxD->CipherAlg], */ - pRxWI->KeyIndex)); - - /* */ - /* MIC Error */ - /* */ - if (pRxD->CipherErr == 2) { - pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; - if (pAd->StaCfg.WpaSupplicantUP) - WpaSendMicFailureToWpaSupplicant(pAd, - (pWpaKey-> - Type == - PAIRWISEKEY) ? - TRUE : FALSE); - else - RTMPReportMicError(pAd, pWpaKey); - - if (((pRxD->CipherErr & 2) == 2) - && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) - RTMPSendWirelessEvent(pAd, - IW_MIC_ERROR_EVENT_FLAG, - pAd->MacTab. - Content[BSSID_WCID].Addr, - BSS0, 0); - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n")); - } - - if (pHeader == NULL) - return (NDIS_STATUS_SUCCESS); - /*if ((pRxD->CipherAlg == CIPHER_AES) && - (pHeader->Sequence == pAd->FragFrame.Sequence)) - { - // - // Acceptable since the First FragFrame no CipherErr problem. - // - return(NDIS_STATUS_SUCCESS); - } */ - - return (NDIS_STATUS_FAILURE); - } - - return (NDIS_STATUS_SUCCESS); -} - -BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx) -{ - struct rt_rtmp_tx_ring *pTxRing; - struct rt_txd * pTxD; - void *pPacket; - u8 FREE = 0; - struct rt_txd TxD, *pOriTxD; - /*unsigned long IrqFlags; */ - BOOLEAN bReschedule = FALSE; - - ASSERT(QueIdx < NUM_OF_TX_RING); - pTxRing = &pAd->TxRing[QueIdx]; - - RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, - &pTxRing->TxDmaIdx); - while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) { -/* RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); */ - - /* static rate also need NICUpdateFifoStaCounters() function. */ - /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ - NICUpdateFifoStaCounters(pAd); - - /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */ - FREE++; - pTxD = - (struct rt_txd *) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa); - pOriTxD = pTxD; - NdisMoveMemory(&TxD, pTxD, sizeof(struct rt_txd)); - pTxD = &TxD; - - pTxD->DMADONE = 0; - - { - pPacket = - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket; - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, - pTxD->SDLen1, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_SUCCESS); - } - /*Always assign pNdisPacket as NULL after clear */ - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL; - - pPacket = - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket; - - ASSERT(pPacket == NULL); - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, - pTxD->SDLen1, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_SUCCESS); - } - /*Always assign pNextNdisPacket as NULL after clear */ - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = - NULL; - } - - pAd->RalinkCounters.TransmittedByteCount += - (pTxD->SDLen1 + pTxD->SDLen0); - pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx]++; - INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE); - /* get tx_tdx_idx again */ - RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, - &pTxRing->TxDmaIdx); - NdisMoveMemory(pOriTxD, pTxD, sizeof(struct rt_txd)); - -/* RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); */ - } - - return bReschedule; - -} - -/* - ======================================================================== - - Routine Description: - Process TX Rings DMA Done interrupt, running in DPC level - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd, - INT_SOURCE_CSR_STRUC TxRingBitmap) -{ -/* u8 Count = 0; */ - unsigned long IrqFlags; - BOOLEAN bReschedule = FALSE; - - /* Make sure Tx ring resource won't be used by other threads */ - /*NdisAcquireSpinLock(&pAd->TxRingLock); */ - - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - - if (TxRingBitmap.field.Ac0DmaDone) - bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE); - - if (TxRingBitmap.field.Ac3DmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO); - - if (TxRingBitmap.field.Ac2DmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI); - - if (TxRingBitmap.field.Ac1DmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK); - - /* Make sure to release Tx ring resource */ - /*NdisReleaseSpinLock(&pAd->TxRingLock); */ - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - - /* Dequeue outgoing frames from TxSwQueue[] and process it */ - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - - return bReschedule; -} - -/* - ======================================================================== - - Routine Description: - Process MGMT ring DMA done interrupt, running in DPC level - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd) -{ - struct rt_txd * pTxD; - void *pPacket; -/* int i; */ - u8 FREE = 0; - struct rt_rtmp_mgmt_ring *pMgmtRing = &pAd->MgmtRing; - - NdisAcquireSpinLock(&pAd->MgmtRingLock); - - RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); - while (pMgmtRing->TxSwFreeIdx != pMgmtRing->TxDmaIdx) { - FREE++; - pTxD = - (struct rt_txd *) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx]. - AllocVa); - pTxD->DMADONE = 0; - pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; - - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; - - pPacket = - pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; - INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); - - } - NdisReleaseSpinLock(&pAd->MgmtRingLock); - -} - -/* - ======================================================================== - - Routine Description: - Arguments: - Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon. - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd) -{ - { - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - } - } -} - -/* - ======================================================================== - - Routine Description: - Arguments: - pAd Pointer to our adapter. Rewrite beacon content before next send-out. - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd) -{ - { - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPHandlePreTBTTInterrupt...\n")); - } - } - -} - -void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - - if (pAd == NULL) { - DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n")); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n")); - - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - - GloCfg.field.EnTXWriteBackDDONE = 0; - GloCfg.field.EnableRxDMA = 0; - GloCfg.field.EnableTxDMA = 0; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - RTMPEnableRxTx(pAd); - - DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n")); -} - -void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd, - OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN * pbReschedule, - IN u32 * pRxPending) -{ - struct rt_rxd * pRxD; - void *pRxPacket = NULL; - void *pNewPacket; - void *AllocVa; - dma_addr_t AllocPa; - BOOLEAN bReschedule = FALSE; - struct rt_rtmp_dmacb *pRxCell; - - RTMP_SEM_LOCK(&pAd->RxRingLock); - - if (*pRxPending == 0) { - /* Get how may packets had been received */ - RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx); - - if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) { - /* no more rx packets */ - bReschedule = FALSE; - goto done; - } - /* get rx pending count */ - if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx) - *pRxPending = - pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx; - else - *pRxPending = - pAd->RxRing.RxDmaIdx + RX_RING_SIZE - - pAd->RxRing.RxSwReadIdx; - - } - - pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx]; - - /* Point to Rx indexed rx ring descriptor */ - pRxD = (struct rt_rxd *) pRxCell->AllocVa; - - if (pRxD->DDONE == 0) { - *pRxPending = 0; - /* DMAIndx had done but DDONE bit not ready */ - bReschedule = TRUE; - goto done; - } - - /* return rx descriptor */ - NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE); - - pNewPacket = - RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, - &AllocVa, &AllocPa); - - if (pNewPacket) { - /* unmap the rx buffer */ - PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa, - pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); - pRxPacket = pRxCell->pNdisPacket; - - pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE; - pRxCell->pNdisPacket = (void *)pNewPacket; - pRxCell->DmaBuf.AllocVa = AllocVa; - pRxCell->DmaBuf.AllocPa = AllocPa; - /* update SDP0 to new buffer of rx packet */ - pRxD->SDP0 = AllocPa; - } else { - /*DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); */ - pRxPacket = NULL; - bReschedule = TRUE; - } - - pRxD->DDONE = 0; - - /* had handled one rx packet */ - *pRxPending = *pRxPending - 1; - - /* update rx descriptor and kick rx */ - INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE); - - pAd->RxRing.RxCpuIdx = - (pAd->RxRing.RxSwReadIdx == - 0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxSwReadIdx - 1); - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - -done: - RTMP_SEM_UNLOCK(&pAd->RxRingLock); - *pbReschedule = bReschedule; - return pRxPacket; -} - -int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - struct rt_txd * pTxD; - struct rt_header_802_11 * pHeader_802_11; - BOOLEAN bAckRequired, bInsertTimestamp; - unsigned long SrcBufPA; - /*u8 TxBufIdx; */ - u8 MlmeRate; - unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; - struct rt_txwi * pFirstTxWI; - /*unsigned long i; */ - /*HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame. */ - unsigned long FreeNum; - struct rt_mac_table_entry *pMacEntry = NULL; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - if (pSrcBufVA == NULL) { - /* The buffer shouldn't be NULL */ - return NDIS_STATUS_FAILURE; - } - /* Make sure MGMT ring resource won't be used by other threads */ - /*NdisAcquireSpinLock(&pAd->TxRingLock); */ - - FreeNum = GET_TXRING_FREENO(pAd, QueIdx); - - if (FreeNum == 0) { - /*NdisReleaseSpinLock(&pAd->TxRingLock); */ - return NDIS_STATUS_FAILURE; - } - - SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; - - pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; - - if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) { - DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n")); - /*NdisReleaseSpinLock(&pAd->TxRingLock); */ - return NDIS_STATUS_FAILURE; - } - - { - /* outgoing frame always wakeup PHY to prevent frame lost */ - /* if (pAd->StaCfg.Psm == PWR_SAVE) */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - AsicForceWakeup(pAd, TRUE); - } - pFirstTxWI = (struct rt_txwi *) pSrcBufVA; - - pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE); - if (pHeader_802_11->Addr1[0] & 0x01) { - MlmeRate = pAd->CommonCfg.BasicMlmeRate; - } else { - MlmeRate = pAd->CommonCfg.MlmeRate; - } - - if ((pHeader_802_11->FC.Type == BTYPE_DATA) && - (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { - pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); - } - /* Verify Mlme rate for a / g bands. */ - if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */ - MlmeRate = RATE_6; - - /* */ - /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */ - /* Snice it's been set to 0 while on MgtMacHeaderInit */ - /* By the way this will cause frame to be send on PWR_SAVE failed. */ - /* */ - /* */ - /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ - /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ - if (pHeader_802_11->FC.Type != BTYPE_DATA) { - if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) - || !(pAd->CommonCfg.bAPSDCapable - && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) { - pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; - } else { - pHeader_802_11->FC.PwrMgmt = - pAd->CommonCfg.bAPSDForcePowerSave; - } - } - - bInsertTimestamp = FALSE; - if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */ - { - bAckRequired = FALSE; - } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */ - { - if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */ - { - bAckRequired = FALSE; - pHeader_802_11->Duration = 0; - } else { - bAckRequired = TRUE; - pHeader_802_11->Duration = - RTMPCalcDuration(pAd, MlmeRate, 14); - if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) { - bInsertTimestamp = TRUE; - } - } - } - pHeader_802_11->Sequence = pAd->Sequence++; - if (pAd->Sequence > 0xfff) - pAd->Sequence = 0; - /* Before radar detection done, mgmt frame can not be sent but probe req */ - /* Because we need to use probe req to trigger driver to send probe req in passive scan */ - if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) - && (pAd->CommonCfg.bIEEE80211H == 1) - && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeHardTransmit --> radar detect not in normal mode!\n")); - /*NdisReleaseSpinLock(&pAd->TxRingLock); */ - return (NDIS_STATUS_FAILURE); - } - /* */ - /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */ - /* should always has only one ohysical buffer, and the whole frame size equals */ - /* to the first scatter buffer size */ - /* */ - - /* Initialize TX Descriptor */ - /* For inter-frame gap, the number is for this frame and next frame */ - /* For MLME rate, we will fix as 2Mb to match other vendor's implement */ -/* pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */ - -/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */ - /* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. */ - if (pMacEntry == NULL) { - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, - FALSE, bAckRequired, FALSE, 0, RESERVED_WCID, - (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, - (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, - IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); - } else { - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, - bInsertTimestamp, FALSE, bAckRequired, FALSE, - 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE), - pMacEntry->MaxHTPhyMode.field.MCS, 0, - (u8)pMacEntry->MaxHTPhyMode.field.MCS, - IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); - } - - pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; - pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; -/* pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */ - SrcBufPA = - PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); - - RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); - pTxD->LastSec0 = 1; - pTxD->LastSec1 = 1; - pTxD->SDLen0 = SrcBufLen; - pTxD->SDLen1 = 0; - pTxD->SDPtr0 = SrcBufPA; - pTxD->DMADONE = 0; - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - /* Increase TX_CTX_IDX, but write to register later. */ - INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); - - RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10, - pAd->TxRing[QueIdx].TxCpuIdx); - - /* Make sure to release MGMT ring resource */ -/* NdisReleaseSpinLock(&pAd->TxRingLock); */ - - return NDIS_STATUS_SUCCESS; -} - -int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket) -{ - if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) - ) { - return NDIS_STATUS_FAILURE; - } - - return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket); -} - -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pTxD Pointer to transmit descriptor - Ack Setting for Ack requirement bit - Fragment Setting for Fragment bit - RetryMode Setting for retry mode - Ifs Setting for IFS gap - Rate Setting for transmit rate - Service Setting for service - Length Frame length - TxPreamble Short or Long preamble when using CCK rates - QueIdx - 0-3, according to 802.11e/d4.4 June/2003 - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd, - struct rt_txd * pTxD, - IN BOOLEAN bWIV, u8 QueueSEL) -{ - /* */ - /* Always use Long preamble before verifiation short preamble functionality works well. */ - /* Todo: remove the following line if short preamble functionality works */ - /* */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - - pTxD->WIV = (bWIV) ? 1 : 0; - pTxD->QSEL = (QueueSEL); - /*RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan */ - /*pTxD->QSEL= FIFO_EDCA; */ - pTxD->DMADONE = 0; -} diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c deleted file mode 100644 index 5637857ae9eb..000000000000 --- a/drivers/staging/rt2860/common/cmm_data_usb.c +++ /dev/null @@ -1,951 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -/* - All functions in this file must be USB-depended, or you should out your function - in other files. - -*/ - -#ifdef RTMP_MAC_USB - -#include "../rt_config.h" - -/* - We can do copy the frame into pTxContext when match following conditions. - => - => - => -*/ -static inline int RtmpUSBCanDoWrite(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - struct rt_ht_tx_context *pHTTXContext) -{ - int canWrite = NDIS_STATUS_RESOURCES; - - if (((pHTTXContext->CurWritePosition) < - pHTTXContext->NextBulkOutPosition) - && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > - pHTTXContext->NextBulkOutPosition) { - DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c1!\n")); - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - } else if ((pHTTXContext->CurWritePosition == 8) - && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) { - DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c2!\n")); - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - } else if (pHTTXContext->bCurWriting == TRUE) { - DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c3!\n")); - } else { - canWrite = NDIS_STATUS_SUCCESS; - } - - return canWrite; -} - -u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 * FreeNumber) -{ - - /* Dummy function. Should be removed in the future. */ - return 0; - -} - -u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 fragNum, u16 * FreeNumber) -{ - struct rt_ht_tx_context *pHTTXContext; - u16 hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length. */ - u32 fillOffset; - struct rt_txinfo *pTxInfo; - struct rt_txwi *pTxWI; - u8 *pWirelessPacket = NULL; - u8 QueIdx; - int Status; - unsigned long IrqFlags; - u32 USBDMApktLen = 0, DMAHdrLen, padding; - BOOLEAN TxQLastRound = FALSE; - - /* */ - /* get Tx Ring Resource & Dma Buffer address */ - /* */ - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - pHTTXContext = &pAd->TxContext[QueIdx]; - fillOffset = pHTTXContext->CurWritePosition; - - if (fragNum == 0) { - /* Check if we have enough space for this bulk-out batch. */ - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) { - pHTTXContext->bCurWriting = TRUE; - - /* Reserve space for 8 bytes padding. */ - if ((pHTTXContext->ENextBulkOutPosition == - pHTTXContext->CurWritePosition)) { - pHTTXContext->ENextBulkOutPosition += 8; - pHTTXContext->CurWritePosition += 8; - fillOffset += 8; - } - pTxBlk->Priv = 0; - pHTTXContext->CurWriteRealPos = - pHTTXContext->CurWritePosition; - } else { - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], - IrqFlags); - - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, - NDIS_STATUS_FAILURE); - return (Status); - } - } else { - /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */ - Status = - ((pHTTXContext->bCurWriting == - TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); - if (Status == NDIS_STATUS_SUCCESS) { - fillOffset += pTxBlk->Priv; - } else { - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], - IrqFlags); - - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, - NDIS_STATUS_FAILURE); - return (Status); - } - } - - NdisZeroMemory((u8 *)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE); - pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]); - pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - pWirelessPacket = - &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - /* copy TXWI + WLAN Header + LLC into DMA Header Buffer */ - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - /* Build our URB for USBD */ - DMAHdrLen = TXWI_SIZE + hwHdrLen; - USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; - padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */ - USBDMApktLen += padding; - - pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen); - - /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */ - RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE, FIFO_EDCA, - FALSE /*NextValid */ , FALSE); - - if (fragNum == pTxBlk->TotalFragNum) { - pTxInfo->USBDMATxburst = 0; - if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906) > - MAX_TXBULK_LIMIT) { - pTxInfo->SwUseLastRound = 1; - TxQLastRound = TRUE; - } - } else { - pTxInfo->USBDMATxburst = 1; - } - - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, - TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - - /* Zero the last padding. */ - pWirelessPacket += pTxBlk->SrcBufLen; - NdisZeroMemory(pWirelessPacket, padding + 8); - - if (fragNum == pTxBlk->TotalFragNum) { - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - /* Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. */ - pHTTXContext->CurWritePosition += pTxBlk->Priv; - if (TxQLastRound == TRUE) - pHTTXContext->CurWritePosition = 8; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - /* Finally, set bCurWriting as FALSE */ - pHTTXContext->bCurWriting = FALSE; - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - /* succeed and release the skb buffer */ - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - } - - return (Status); - -} - -u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, - u16 * FreeNumber) -{ - struct rt_ht_tx_context *pHTTXContext; - u16 hwHdrLen; - u32 fillOffset; - struct rt_txinfo *pTxInfo; - struct rt_txwi *pTxWI; - u8 *pWirelessPacket; - u8 QueIdx; - unsigned long IrqFlags; - int Status; - u32 USBDMApktLen = 0, DMAHdrLen, padding; - BOOLEAN bTxQLastRound = FALSE; - - /* For USB, didn't need PCI_MAP_SINGLE() */ - /*SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); */ - - /* */ - /* get Tx Ring Resource & Dma Buffer address */ - /* */ - QueIdx = pTxBlk->QueIdx; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - pHTTXContext = &pAd->TxContext[QueIdx]; - fillOffset = pHTTXContext->CurWritePosition; - - /* Check ring full. */ - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) { - pHTTXContext->bCurWriting = TRUE; - - pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]); - pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - /* Reserve space for 8 bytes padding. */ - if ((pHTTXContext->ENextBulkOutPosition == - pHTTXContext->CurWritePosition)) { - pHTTXContext->ENextBulkOutPosition += 8; - pHTTXContext->CurWritePosition += 8; - fillOffset += 8; - } - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pWirelessPacket = - &pHTTXContext->TransferBuffer->field. - WirelessPacket[fillOffset]; - - /* copy TXWI + WLAN Header + LLC into DMA Header Buffer */ - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - /* Build our URB for USBD */ - DMAHdrLen = TXWI_SIZE + hwHdrLen; - USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; - padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */ - USBDMApktLen += padding; - - pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen); - - /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */ - RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE, - FIFO_EDCA, FALSE /*NextValid */ , FALSE); - - if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > - MAX_TXBULK_LIMIT) { - pTxInfo->SwUseLastRound = 1; - bTxQLastRound = TRUE; - } - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, - TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - - /* We unlock it here to prevent the first 8 bytes maybe over-writed issue. */ - /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. */ - /* 2. An interrupt break our routine and handle bulk-out complete. */ - /* 3. In the bulk-out compllete, it need to do another bulk-out, */ - /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */ - /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */ - /* 4. Interrupt complete. */ - /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */ - /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */ - /* and the packet will wrong. */ - pHTTXContext->CurWriteRealPos += - (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, - pTxBlk->SrcBufLen); - pWirelessPacket += pTxBlk->SrcBufLen; - NdisZeroMemory(pWirelessPacket, padding + 8); - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - pHTTXContext->CurWritePosition += pTxBlk->Priv; - if (bTxQLastRound) - pHTTXContext->CurWritePosition = 8; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pHTTXContext->bCurWriting = FALSE; - } - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - /* succeed and release the skb buffer */ - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - - return (Status); - -} - -u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 frameNum, u16 * FreeNumber) -{ - struct rt_ht_tx_context *pHTTXContext; - u16 hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length. */ - u32 fillOffset; - struct rt_txinfo *pTxInfo; - struct rt_txwi *pTxWI; - u8 *pWirelessPacket = NULL; - u8 QueIdx; - int Status; - unsigned long IrqFlags; - /*u32 USBDMApktLen = 0, DMAHdrLen, padding; */ - - /* */ - /* get Tx Ring Resource & Dma Buffer address */ - /* */ - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (frameNum == 0) { - /* Check if we have enough space for this bulk-out batch. */ - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) { - pHTTXContext->bCurWriting = TRUE; - - pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]); - pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - /* Reserve space for 8 bytes padding. */ - if ((pHTTXContext->ENextBulkOutPosition == - pHTTXContext->CurWritePosition)) { - - pHTTXContext->CurWritePosition += 8; - pHTTXContext->ENextBulkOutPosition += 8; - } - fillOffset = pHTTXContext->CurWritePosition; - pHTTXContext->CurWriteRealPos = - pHTTXContext->CurWritePosition; - - pWirelessPacket = - &pHTTXContext->TransferBuffer->field. - WirelessPacket[fillOffset]; - - /* */ - /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */ - /* */ - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */ - hwHdrLen = - pTxBlk->MpduHeaderLen - - LENGTH_AMSDU_SUBFRAMEHEAD + - pTxBlk->HdrPadLen + - LENGTH_AMSDU_SUBFRAMEHEAD; - else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */ - hwHdrLen = - pTxBlk->MpduHeaderLen - - LENGTH_ARALINK_HEADER_FIELD + - pTxBlk->HdrPadLen + - LENGTH_ARALINK_HEADER_FIELD; - else - /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */ - hwHdrLen = - pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - /* Update the pTxBlk->Priv. */ - pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; - - /* pTxInfo->USBDMApktLen now just a temp value and will to correct latter. */ - RTMPWriteTxInfo(pAd, pTxInfo, (u16)(pTxBlk->Priv), - FALSE, FIFO_EDCA, FALSE /*NextValid */ , - FALSE); - - /* Copy it. */ - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, - pTxBlk->Priv); - pHTTXContext->CurWriteRealPos += pTxBlk->Priv; - pWirelessPacket += pTxBlk->Priv; - } - } else { /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */ - - Status = - ((pHTTXContext->bCurWriting == - TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); - if (Status == NDIS_STATUS_SUCCESS) { - fillOffset = - (pHTTXContext->CurWritePosition + pTxBlk->Priv); - pWirelessPacket = - &pHTTXContext->TransferBuffer->field. - WirelessPacket[fillOffset]; - - /*hwHdrLen = pTxBlk->MpduHeaderLen; */ - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, - pTxBlk->MpduHeaderLen); - pWirelessPacket += (pTxBlk->MpduHeaderLen); - pTxBlk->Priv += pTxBlk->MpduHeaderLen; - } else { /* It should not happened now unless we are going to shutdown. */ - DBGPRINT(RT_DEBUG_ERROR, - ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n")); - Status = NDIS_STATUS_FAILURE; - } - } - - /* We unlock it here to prevent the first 8 bytes maybe over-write issue. */ - /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. */ - /* 2. An interrupt break our routine and handle bulk-out complete. */ - /* 3. In the bulk-out compllete, it need to do another bulk-out, */ - /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */ - /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */ - /* 4. Interrupt complete. */ - /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */ - /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */ - /* and the packet will wrong. */ - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_ERROR, - ("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", - pHTTXContext->CurWritePosition, - pHTTXContext->NextBulkOutPosition)); - goto done; - } - /* Copy the frame content into DMA buffer and update the pTxBlk->Priv */ - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - pWirelessPacket += pTxBlk->SrcBufLen; - pTxBlk->Priv += pTxBlk->SrcBufLen; - -done: - /* Release the skb buffer here */ - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - - return (Status); - -} - -void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u16 totalMPDUSize, u16 TxIdx) -{ - u8 QueIdx; - struct rt_ht_tx_context *pHTTXContext; - u32 fillOffset; - struct rt_txinfo *pTxInfo; - struct rt_txwi *pTxWI; - u32 USBDMApktLen, padding; - unsigned long IrqFlags; - u8 *pWirelessPacket; - - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (pHTTXContext->bCurWriting == TRUE) { - fillOffset = pHTTXContext->CurWritePosition; - if (((pHTTXContext->ENextBulkOutPosition == - pHTTXContext->CurWritePosition) - || ((pHTTXContext->ENextBulkOutPosition - 8) == - pHTTXContext->CurWritePosition)) - && (pHTTXContext->bCopySavePad == TRUE)) - pWirelessPacket = (u8 *)(&pHTTXContext->SavedPad[0]); - else - pWirelessPacket = - (u8 *)(&pHTTXContext->TransferBuffer->field. - WirelessPacket[fillOffset]); - - /* */ - /* Update TxInfo->USBDMApktLen , */ - /* the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding */ - /* */ - pTxInfo = (struct rt_txinfo *)(pWirelessPacket); - - /* Calculate the bulk-out padding */ - USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE; - padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */ - USBDMApktLen += padding; - - pTxInfo->USBDMATxPktLen = USBDMApktLen; - - /* */ - /* Update TXWI->MPDUtotalByteCount , */ - /* the length = 802.11 header + payload_of_all_batch_frames */ - pTxWI = (struct rt_txwi *) (pWirelessPacket + TXINFO_SIZE); - pTxWI->MPDUtotalByteCount = totalMPDUSize; - - /* */ - /* Update the pHTTXContext->CurWritePosition */ - /* */ - pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen); - if ((pHTTXContext->CurWritePosition + 3906) > MAX_TXBULK_LIMIT) { /* Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. */ - pHTTXContext->CurWritePosition = 8; - pTxInfo->SwUseLastRound = 1; - } - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - /* */ - /* Zero the last padding. */ - /* */ - pWirelessPacket = - (&pHTTXContext->TransferBuffer->field. - WirelessPacket[fillOffset + pTxBlk->Priv]); - NdisZeroMemory(pWirelessPacket, padding + 8); - - /* Finally, set bCurWriting as FALSE */ - pHTTXContext->bCurWriting = FALSE; - - } else { /* It should not happened now unless we are going to shutdown. */ - DBGPRINT(RT_DEBUG_ERROR, - ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n")); - } - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - -} - -void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u16 TxIdx) -{ - /* DO nothing for USB. */ -} - -/* - When can do bulk-out: - 1. TxSwFreeIdx < TX_RING_SIZE; - It means has at least one Ring entity is ready for bulk-out, kick it out. - 2. If TxSwFreeIdx == TX_RING_SIZE - Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out. - -*/ -void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, u8 QueIdx) -{ - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - RTUSBKickBulkOut(pAd); - -} - -/* - Must be run in Interrupt context - This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. - */ -int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - void *pPacket, - u8 *pSrcBufVA, u32 SrcBufLen) -{ - struct rt_txinfo *pTxInfo; - unsigned long BulkOutSize; - u8 padLen; - u8 *pDest; - unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx; - struct rt_tx_context *pMLMEContext = - (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa; - unsigned long IrqFlags; - - pTxInfo = (struct rt_txinfo *)(pSrcBufVA); - - /* Build our URB for USBD */ - BulkOutSize = SrcBufLen; - BulkOutSize = (BulkOutSize + 3) & (~3); - RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE), - TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - - BulkOutSize += 4; /* Always add 4 extra bytes at every packet. */ - - /* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */ - if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) - BulkOutSize += 4; - - padLen = BulkOutSize - SrcBufLen; - ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); - - /* Now memzero all extra padding bytes. */ - pDest = (u8 *)(pSrcBufVA + SrcBufLen); - skb_put(GET_OS_PKT_TYPE(pPacket), padLen); - NdisZeroMemory(pDest, padLen); - - RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; - pMLMEContext->TransferBuffer = - (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket)); - - /* Length in TxInfo should be 8 less than bulkout size. */ - pMLMEContext->BulkOutSize = BulkOutSize; - pMLMEContext->InUse = TRUE; - pMLMEContext->bWaitingBulkOut = TRUE; - - /*for debug */ - /*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */ - - /*pAd->RalinkCounters.KickTxCount++; */ - /*pAd->RalinkCounters.OneSecTxDoneCount++; */ - - /*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */ - /* needKickOut = TRUE; */ - - /* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */ - pAd->MgmtRing.TxSwFreeIdx--; - INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); - - RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - /*if (needKickOut) */ - RTUSBKickBulkOut(pAd); - - return 0; -} - -void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - u8 * pNullFrame, u32 frameLen) -{ - if (pAd->NullContext.InUse == FALSE) { - struct rt_tx_context *pNullContext; - struct rt_txinfo *pTxInfo; - struct rt_txwi * pTxWI; - u8 *pWirelessPkt; - - pNullContext = &(pAd->NullContext); - - /* Set the in use bit */ - pNullContext->InUse = TRUE; - pWirelessPkt = - (u8 *)& pNullContext->TransferBuffer->field. - WirelessPacket[0]; - - RTMPZeroMemory(&pWirelessPkt[0], 100); - pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0]; - RTMPWriteTxInfo(pAd, pTxInfo, - (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), - TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - pTxInfo->QSEL = FIFO_EDCA; - pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE]; - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, - FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, - 0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, - IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); - - RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE], - &pAd->NullFrame, sizeof(struct rt_header_802_11)); - pAd->NullContext.BulkOutSize = - TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; - - /* Fill out frame length information for global Bulk out arbitor */ - /*pNullContext->BulkOutSize = TransferBufferLength; */ - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - send NULL Frame @%d Mbps...\n", - RateIdToMbps[pAd->CommonCfg.TxRate])); - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); - - /* Kick bulk out */ - RTUSBKickBulkOut(pAd); - } - -} - -/* -======================================================================== -Routine Description: - Get a received packet. - -Arguments: - pAd device control block - pSaveRxD receive descriptor information - *pbReschedule need reschedule flag - *pRxPending pending received packet flag - -Return Value: - the received packet - -Note: -======================================================================== -*/ -void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd, - OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN * pbReschedule, - IN u32 * pRxPending) -{ - struct rt_rx_context *pRxContext; - void *pSkb; - u8 *pData; - unsigned long ThisFrameLen; - unsigned long RxBufferLength; - struct rt_rxwi * pRxWI; - - pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; - if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) - return NULL; - - RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; - if (RxBufferLength < - (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) + - sizeof(struct rt_rxinfo))) { - goto label_null; - } - - pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */ - /* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */ - ThisFrameLen = *pData + (*(pData + 1) << 8); - if (ThisFrameLen == 0) { - DBGPRINT(RT_DEBUG_TRACE, - ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", - pAd->NextRxBulkInReadIndex, ThisFrameLen, - pRxContext->BulkInOffset)); - goto label_null; - } - if ((ThisFrameLen & 0x3) != 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", - pAd->NextRxBulkInReadIndex, ThisFrameLen, - pRxContext->BulkInOffset)); - goto label_null; - } - - if ((ThisFrameLen + 8) > RxBufferLength) /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */ - { - DBGPRINT(RT_DEBUG_TRACE, - ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", - pAd->NextRxBulkInReadIndex, ThisFrameLen, - pRxContext->BulkInOffset, RxBufferLength, - pAd->ReadPosition)); - - /* error frame. finish this loop */ - goto label_null; - } - /* skip USB frame length field */ - pData += RT2870_RXDMALEN_FIELD_SIZE; - pRxWI = (struct rt_rxwi *) pData; - if (pRxWI->MPDUtotalByteCount > ThisFrameLen) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", - __FUNCTION__, pRxWI->MPDUtotalByteCount, - ThisFrameLen)); - goto label_null; - } - /* allocate a rx packet */ - pSkb = dev_alloc_skb(ThisFrameLen); - if (pSkb == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", - __FUNCTION__)); - goto label_null; - } - /* copy the rx packet */ - memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen); - RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0); - RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS); - - /* copy RxD */ - *pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen); - - /* update next packet read position. */ - pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */ - - return pSkb; - -label_null: - - return NULL; -} - -/* - ======================================================================== - - Routine Description: - Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound - - Arguments: - pRxD Pointer to the Rx descriptor - - Return Value: - NDIS_STATUS_SUCCESS No err - NDIS_STATUS_FAILURE Error - - Note: - - ======================================================================== -*/ -int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHeader, - struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxINFO) -{ - struct rt_cipher_key *pWpaKey; - int dBm; - - if (pAd->bPromiscuous == TRUE) - return (NDIS_STATUS_SUCCESS); - if (pRxINFO == NULL) - return (NDIS_STATUS_FAILURE); - - /* Phy errors & CRC errors */ - if (pRxINFO->Crc) { - /* Check RSSI for Noise Hist statistic collection. */ - dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; - if (dBm <= -87) - pAd->StaCfg.RPIDensity[0] += 1; - else if (dBm <= -82) - pAd->StaCfg.RPIDensity[1] += 1; - else if (dBm <= -77) - pAd->StaCfg.RPIDensity[2] += 1; - else if (dBm <= -72) - pAd->StaCfg.RPIDensity[3] += 1; - else if (dBm <= -67) - pAd->StaCfg.RPIDensity[4] += 1; - else if (dBm <= -62) - pAd->StaCfg.RPIDensity[5] += 1; - else if (dBm <= -57) - pAd->StaCfg.RPIDensity[6] += 1; - else if (dBm > -57) - pAd->StaCfg.RPIDensity[7] += 1; - - return (NDIS_STATUS_FAILURE); - } - /* Add Rx size to channel load counter, we should ignore error counts */ - pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount + 14); - - /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */ - if (pHeader->FC.ToDs) { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n")); - return NDIS_STATUS_FAILURE; - } - /* Paul 04-03 for OFDM Rx length issue */ - if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); - return NDIS_STATUS_FAILURE; - } - /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ - /* I am kind of doubting the U2M bit operation */ - /* if (pRxD->U2M == 0) */ - /* return(NDIS_STATUS_FAILURE); */ - - /* drop decyption fail frame */ - if (pRxINFO->Decrypted && pRxINFO->CipherErr) { - - if (((pRxINFO->CipherErr & 1) == 1) - && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) - RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - - if (((pRxINFO->CipherErr & 2) == 2) - && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) - RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - /* */ - /* MIC Error */ - /* */ - if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) { - pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; - RTMPReportMicError(pAd, pWpaKey); - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n")); - } - - if (pRxINFO->Decrypted && - (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == - CIPHER_AES) - && (pHeader->Sequence == pAd->FragFrame.Sequence)) { - /* */ - /* Acceptable since the First FragFrame no CipherErr problem. */ - /* */ - return (NDIS_STATUS_SUCCESS); - } - - return (NDIS_STATUS_FAILURE); - } - - return (NDIS_STATUS_SUCCESS); -} - -void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - if (pAd && pAd->Mlme.AutoWakeupTimerRunning) { - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - pAd->Mlme.AutoWakeupTimerRunning = FALSE; - } -} - -void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx) -{ - BOOLEAN Canceled; - - if (pAd->Mlme.AutoWakeupTimerRunning) - RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled); - - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); -} - -void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, - u16 TbttNumToNextWakeUp) -{ - - /* we have decided to SLEEP, so at least do it for a BEACON period. */ - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT); - pAd->Mlme.AutoWakeupTimerRunning = TRUE; - - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); /* send POWER-SAVE command to MCU. Timeout 40us. */ - - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); - -} - -#endif /* RTMP_MAC_USB // */ diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c deleted file mode 100644 index 25302e8363b9..000000000000 --- a/drivers/staging/rt2860/common/cmm_info.c +++ /dev/null @@ -1,955 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -#include -#include "../rt_config.h" - -/* - ======================================================================== - - Routine Description: - Remove WPA Key process - - Arguments: - pAd Pointer to our adapter - pBuf Pointer to the where the key stored - - Return Value: - NDIS_SUCCESS Add key successfully - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates) -{ - NDIS_802_11_RATES aryRates; - - memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES)); - switch (pAdapter->CommonCfg.PhyMode) { - case PHY_11A: /* A only */ - switch (Rates) { - case 6000000: /*6M */ - aryRates[0] = 0x0c; /* 6M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_0; - break; - case 9000000: /*9M */ - aryRates[0] = 0x12; /* 9M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_1; - break; - case 12000000: /*12M */ - aryRates[0] = 0x18; /* 12M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_2; - break; - case 18000000: /*18M */ - aryRates[0] = 0x24; /* 18M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_3; - break; - case 24000000: /*24M */ - aryRates[0] = 0x30; /* 24M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_4; - break; - case 36000000: /*36M */ - aryRates[0] = 0x48; /* 36M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_5; - break; - case 48000000: /*48M */ - aryRates[0] = 0x60; /* 48M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_6; - break; - case 54000000: /*54M */ - aryRates[0] = 0x6c; /* 54M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_7; - break; - case -1: /*Auto */ - default: - aryRates[0] = 0x6c; /* 54Mbps */ - aryRates[1] = 0x60; /* 48Mbps */ - aryRates[2] = 0x48; /* 36Mbps */ - aryRates[3] = 0x30; /* 24Mbps */ - aryRates[4] = 0x24; /* 18M */ - aryRates[5] = 0x18; /* 12M */ - aryRates[6] = 0x12; /* 9M */ - aryRates[7] = 0x0c; /* 6M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_AUTO; - break; - } - break; - case PHY_11BG_MIXED: /* B/G Mixed */ - case PHY_11B: /* B only */ - case PHY_11ABG_MIXED: /* A/B/G Mixed */ - default: - switch (Rates) { - case 1000000: /*1M */ - aryRates[0] = 0x02; - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_0; - break; - case 2000000: /*2M */ - aryRates[0] = 0x04; - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_1; - break; - case 5000000: /*5.5M */ - aryRates[0] = 0x0b; /* 5.5M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_2; - break; - case 11000000: /*11M */ - aryRates[0] = 0x16; /* 11M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_3; - break; - case 6000000: /*6M */ - aryRates[0] = 0x0c; /* 6M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_0; - break; - case 9000000: /*9M */ - aryRates[0] = 0x12; /* 9M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_1; - break; - case 12000000: /*12M */ - aryRates[0] = 0x18; /* 12M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_2; - break; - case 18000000: /*18M */ - aryRates[0] = 0x24; /* 18M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_3; - break; - case 24000000: /*24M */ - aryRates[0] = 0x30; /* 24M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_4; - break; - case 36000000: /*36M */ - aryRates[0] = 0x48; /* 36M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_5; - break; - case 48000000: /*48M */ - aryRates[0] = 0x60; /* 48M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_6; - break; - case 54000000: /*54M */ - aryRates[0] = 0x6c; /* 54M */ - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_7; - break; - case -1: /*Auto */ - default: - if (pAdapter->CommonCfg.PhyMode == PHY_11B) { /*B Only */ - aryRates[0] = 0x16; /* 11Mbps */ - aryRates[1] = 0x0b; /* 5.5Mbps */ - aryRates[2] = 0x04; /* 2Mbps */ - aryRates[3] = 0x02; /* 1Mbps */ - } else { /*(B/G) Mixed or (A/B/G) Mixed */ - aryRates[0] = 0x6c; /* 54Mbps */ - aryRates[1] = 0x60; /* 48Mbps */ - aryRates[2] = 0x48; /* 36Mbps */ - aryRates[3] = 0x30; /* 24Mbps */ - aryRates[4] = 0x16; /* 11Mbps */ - aryRates[5] = 0x0b; /* 5.5Mbps */ - aryRates[6] = 0x04; /* 2Mbps */ - aryRates[7] = 0x02; /* 1Mbps */ - } - pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_AUTO; - break; - } - break; - } - - NdisZeroMemory(pAdapter->CommonCfg.DesireRate, - MAX_LEN_OF_SUPPORTED_RATES); - NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, - sizeof(NDIS_802_11_RATES)); - DBGPRINT(RT_DEBUG_TRACE, - (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n", - pAdapter->CommonCfg.DesireRate[0], - pAdapter->CommonCfg.DesireRate[1], - pAdapter->CommonCfg.DesireRate[2], - pAdapter->CommonCfg.DesireRate[3], - pAdapter->CommonCfg.DesireRate[4], - pAdapter->CommonCfg.DesireRate[5], - pAdapter->CommonCfg.DesireRate[6], - pAdapter->CommonCfg.DesireRate[7])); - /* Changing DesiredRate may affect the MAX TX rate we used to TX frames out */ - MlmeUpdateTxRates(pAdapter, FALSE, 0); -} - -/* - ======================================================================== - - Routine Description: - Remove All WPA Keys - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd) -{ - - u8 i; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", - pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus)); - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - /* For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after */ - /* Link up. And it will be replaced if user changed it. */ - if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) - return; - - /* For WPA-None, there is no need to remove it, since WinXP won't set it again after */ - /* Link up. And it will be replaced if user changed it. */ - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) - return; - - /* set BSSID wcid entry of the Pair-wise Key table as no-security mode */ - AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID); - - /* set all shared key mode as no-security. */ - for (i = 0; i < SHARE_KEY_NUM; i++) { - DBGPRINT(RT_DEBUG_TRACE, - ("remove %s key #%d\n", - CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i)); - NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(struct rt_cipher_key)); - - AsicRemoveSharedKeyEntry(pAd, BSS0, i); - } - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); -} - -/* - ======================================================================== - - Routine Description: - As STA's BSSID is a WC too, it uses shared key table. - This function write correct unicast TX key to ASIC WCID. - And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey. - Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key) - Caller guarantee WEP calls this function when set Txkey, default key index=0~3. - - Arguments: - pAd Pointer to our adapter - pKey Pointer to the where the key stored - - Return Value: - NDIS_SUCCESS Add key successfully - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -/* - ======================================================================== - Routine Description: - Change NIC PHY mode. Re-association may be necessary. possible settings - include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED - - Arguments: - pAd - Pointer to our adapter - phymode - - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode) -{ - int i; - /* the selected phymode must be supported by the RF IC encoded in E2PROM */ - - /* if no change, do nothing */ - /* bug fix - if (pAd->CommonCfg.PhyMode == phymode) - return; - */ - pAd->CommonCfg.PhyMode = (u8)phymode; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", - pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel)); - - BuildChannelList(pAd); - - /* sanity check user setting */ - for (i = 0; i < pAd->ChannelListNum; i++) { - if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel) - break; - } - - if (i == pAd->ChannelListNum) { - pAd->CommonCfg.Channel = FirstChannel(pAd); - DBGPRINT(RT_DEBUG_ERROR, - ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", - pAd->CommonCfg.Channel)); - } - - NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); - NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES); - NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES); - switch (phymode) { - case PHY_11B: - pAd->CommonCfg.SupRate[0] = 0x82; /* 1 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[1] = 0x84; /* 2 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[2] = 0x8B; /* 5.5 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[3] = 0x96; /* 11 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRateLen = 4; - pAd->CommonCfg.ExtRateLen = 0; - pAd->CommonCfg.DesireRate[0] = 2; /* 1 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[1] = 4; /* 2 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[2] = 11; /* 5.5 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[3] = 22; /* 11 mbps, in units of 0.5 Mbps */ - /*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use */ - break; - - case PHY_11G: - case PHY_11BG_MIXED: - case PHY_11ABG_MIXED: - case PHY_11N_2_4G: - case PHY_11ABGN_MIXED: - case PHY_11BGN_MIXED: - case PHY_11GN_MIXED: - pAd->CommonCfg.SupRate[0] = 0x82; /* 1 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[1] = 0x84; /* 2 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[2] = 0x8B; /* 5.5 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[3] = 0x96; /* 11 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[4] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[5] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[6] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRateLen = 8; - pAd->CommonCfg.ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.ExtRate[1] = 0x18; /* 12 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.ExtRate[2] = 0x30; /* 24 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.ExtRate[3] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.ExtRateLen = 4; - pAd->CommonCfg.DesireRate[0] = 2; /* 1 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[1] = 4; /* 2 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[2] = 11; /* 5.5 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[3] = 22; /* 11 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[4] = 12; /* 6 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[5] = 18; /* 9 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[6] = 24; /* 12 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[7] = 36; /* 18 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[8] = 48; /* 24 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[9] = 72; /* 36 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[10] = 96; /* 48 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[11] = 108; /* 54 mbps, in units of 0.5 Mbps */ - break; - - case PHY_11A: - case PHY_11AN_MIXED: - case PHY_11AGN_MIXED: - case PHY_11N_5G: - pAd->CommonCfg.SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */ - pAd->CommonCfg.SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.SupRateLen = 8; - pAd->CommonCfg.ExtRateLen = 0; - pAd->CommonCfg.DesireRate[0] = 12; /* 6 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[1] = 18; /* 9 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[2] = 24; /* 12 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[3] = 36; /* 18 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[4] = 48; /* 24 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[5] = 72; /* 36 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[6] = 96; /* 48 mbps, in units of 0.5 Mbps */ - pAd->CommonCfg.DesireRate[7] = 108; /* 54 mbps, in units of 0.5 Mbps */ - /*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use */ - break; - - default: - break; - } - - pAd->CommonCfg.BandState = UNKNOWN_BAND; -} - -/* - ======================================================================== - Routine Description: - Caller ensures we has 802.11n support. - Calls at setting HT from AP/STASetinformation - - Arguments: - pAd - Pointer to our adapter - phymode - - - ======================================================================== -*/ -void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode) -{ - /*unsigned long *pmcs; */ - u32 Value = 0; - u8 BBPValue = 0; - u8 BBP3Value = 0; - u8 RxStream = pAd->CommonCfg.RxStream; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n", - pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS, - pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI)); - - /* Don't zero supportedHyPhy structure. */ - RTMPZeroMemory(&pAd->CommonCfg.HtCapability, - sizeof(pAd->CommonCfg.HtCapability)); - RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, - sizeof(pAd->CommonCfg.AddHTInfo)); - RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, - sizeof(pAd->CommonCfg.NewExtChanOffset)); - RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, - sizeof(pAd->CommonCfg.DesiredHtPhy)); - - if (pAd->CommonCfg.bRdg) { - pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1; - pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1; - } else { - pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0; - pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0; - } - - pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3; - pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSetHT : RxBAWinLimit = %d\n", - pAd->CommonCfg.BACapability.field.RxBAWinLimit)); - - /* Mimo power save, A-MSDU size, */ - pAd->CommonCfg.DesiredHtPhy.AmsduEnable = - (u16)pAd->CommonCfg.BACapability.field.AmsduEnable; - pAd->CommonCfg.DesiredHtPhy.AmsduSize = - (u8)pAd->CommonCfg.BACapability.field.AmsduSize; - pAd->CommonCfg.DesiredHtPhy.MimoPs = - (u8)pAd->CommonCfg.BACapability.field.MMPSmode; - pAd->CommonCfg.DesiredHtPhy.MpduDensity = - (u8)pAd->CommonCfg.BACapability.field.MpduDensity; - - pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = - (u16)pAd->CommonCfg.BACapability.field.AmsduSize; - pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = - (u16)pAd->CommonCfg.BACapability.field.MMPSmode; - pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = - (u8)pAd->CommonCfg.BACapability.field.MpduDensity; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n", - pAd->CommonCfg.DesiredHtPhy.AmsduSize, - pAd->CommonCfg.DesiredHtPhy.MimoPs, - pAd->CommonCfg.DesiredHtPhy.MpduDensity, - pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor)); - - if (pHTPhyMode->HtMode == HTMODE_GF) { - pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1; - pAd->CommonCfg.DesiredHtPhy.GF = 1; - } else - pAd->CommonCfg.DesiredHtPhy.GF = 0; - - /* Decide Rx MCSSet */ - switch (RxStream) { - case 1: - pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff; - pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00; - break; - - case 2: - pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff; - pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff; - break; - - case 3: /* 3*3 */ - pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff; - pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff; - pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff; - break; - } - - if (pAd->CommonCfg.bForty_Mhz_Intolerant - && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40)) { - pHTPhyMode->BW = BW_20; - pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1; - } - - if (pHTPhyMode->BW == BW_40) { - pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; /* MCS 32 */ - pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1; - if (pAd->CommonCfg.Channel <= 14) - pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1; - - pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1; - pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1; - pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = - (pHTPhyMode->ExtOffset == - EXTCHA_BELOW) ? (EXTCHA_BELOW) : EXTCHA_ABOVE; - /* Set Regsiter for extension channel position. */ - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value); - if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW)) { - Value |= 0x1; - BBP3Value |= (0x20); - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); - } else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE)) { - Value &= 0xfe; - BBP3Value &= (~0x20); - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); - } - /* Turn on BBP 40MHz mode now only as AP . */ - /* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection. */ - if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd) - ) { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - BBPValue |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value); - pAd->CommonCfg.BBPCurrentBW = BW_40; - } - } else { - pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0; - pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0; - pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; - pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE; - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - /* Turn on BBP 20MHz mode by request here. */ - { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - pAd->CommonCfg.BBPCurrentBW = BW_20; - } - } - - if (pHTPhyMode->STBC == STBC_USE) { - pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1; - pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1; - pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1; - pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1; - } else { - pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0; - pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0; - } - - if (pHTPhyMode->SHORTGI == GI_400) { - pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1; - pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1; - pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1; - pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1; - } else { - pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0; - pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0; - pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0; - pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0; - } - - /* We support link adaptation for unsolicit MCS feedback, set to 2. */ - pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; /*MCSFBK_UNSOLICIT; */ - pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel; - /* 1, the extension channel above the control channel. */ - - /* EDCA parameters used for AP's own transmission */ - if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) { - pAd->CommonCfg.APEdcaParm.bValid = TRUE; - pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; - pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; - pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; - pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; - - pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; - pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; - pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; - pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; - - pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6; - pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10; - pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; - pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; - - pAd->CommonCfg.APEdcaParm.Txop[0] = 0; - pAd->CommonCfg.APEdcaParm.Txop[1] = 0; - pAd->CommonCfg.APEdcaParm.Txop[2] = 94; - pAd->CommonCfg.APEdcaParm.Txop[3] = 47; - } - AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); - - { - RTMPSetIndividualHT(pAd, 0); - } - -} - -/* - ======================================================================== - Routine Description: - Caller ensures we has 802.11n support. - Calls at setting HT from AP/STASetinformation - - Arguments: - pAd - Pointer to our adapter - phymode - - - ======================================================================== -*/ -void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx) -{ - struct rt_ht_phy_info *pDesired_ht_phy = NULL; - u8 TxStream = pAd->CommonCfg.TxStream; - u8 DesiredMcs = MCS_AUTO; - - do { - { - pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo; - DesiredMcs = - pAd->StaCfg.DesiredTransmitSetting.field.MCS; - /*pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; */ - break; - } - } while (FALSE); - - if (pDesired_ht_phy == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); - return; - } - RTMPZeroMemory(pDesired_ht_phy, sizeof(struct rt_ht_phy_info)); - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); - /* Check the validity of MCS */ - if ((TxStream == 1) - && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) { - DBGPRINT(RT_DEBUG_WARN, - ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", - DesiredMcs)); - DesiredMcs = MCS_7; - } - - if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) - && (DesiredMcs == MCS_32)) { - DBGPRINT(RT_DEBUG_WARN, - ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); - DesiredMcs = MCS_0; - } - - pDesired_ht_phy->bHtEnable = TRUE; - - /* Decide desired Tx MCS */ - switch (TxStream) { - case 1: - if (DesiredMcs == MCS_AUTO) { - pDesired_ht_phy->MCSSet[0] = 0xff; - pDesired_ht_phy->MCSSet[1] = 0x00; - } else if (DesiredMcs <= MCS_7) { - pDesired_ht_phy->MCSSet[0] = 1 << DesiredMcs; - pDesired_ht_phy->MCSSet[1] = 0x00; - } - break; - - case 2: - if (DesiredMcs == MCS_AUTO) { - pDesired_ht_phy->MCSSet[0] = 0xff; - pDesired_ht_phy->MCSSet[1] = 0xff; - } else if (DesiredMcs <= MCS_15) { - unsigned long mode; - - mode = DesiredMcs / 8; - if (mode < 2) - pDesired_ht_phy->MCSSet[mode] = - (1 << (DesiredMcs - mode * 8)); - } - break; - - case 3: /* 3*3 */ - if (DesiredMcs == MCS_AUTO) { - /* MCS0 ~ MCS23, 3 bytes */ - pDesired_ht_phy->MCSSet[0] = 0xff; - pDesired_ht_phy->MCSSet[1] = 0xff; - pDesired_ht_phy->MCSSet[2] = 0xff; - } else if (DesiredMcs <= MCS_23) { - unsigned long mode; - - mode = DesiredMcs / 8; - if (mode < 3) - pDesired_ht_phy->MCSSet[mode] = - (1 << (DesiredMcs - mode * 8)); - } - break; - } - - if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) { - if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) - pDesired_ht_phy->MCSSet[4] = 0x1; - } - /* update HT Rate setting */ - if (pAd->OpMode == OPMODE_STA) - MlmeUpdateHtTxRates(pAd, BSS0); - else - MlmeUpdateHtTxRates(pAd, apidx); -} - -/* - ======================================================================== - Routine Description: - Update HT IE from our capability. - - Arguments: - Send all HT IE in beacon/probe rsp/assoc rsp/action frame. - - ======================================================================== -*/ -void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt, - u8 * pMcsSet, - struct rt_ht_capability_ie * pHtCapability, - struct rt_add_ht_info_ie * pAddHtInfo) -{ - RTMPZeroMemory(pHtCapability, sizeof(struct rt_ht_capability_ie)); - RTMPZeroMemory(pAddHtInfo, sizeof(struct rt_add_ht_info_ie)); - - pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth; - pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs; - pHtCapability->HtCapInfo.GF = pRtHt->GF; - pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20; - pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40; - pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC; - pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC; - pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize; - pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor; - pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity; - - pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset; - pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth; - pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode; - pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent; - RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet */ pMcsSet, 4); /* rt2860 only support MCS max=32, no need to copy all 16 uchar. */ - - DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateHTIE <== \n")); -} - -/* - ======================================================================== - Description: - Add Client security information into ASIC WCID table and IVEIV table. - Return: - ======================================================================== -*/ -void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd, - u8 BssIdx, - u8 KeyIdx, - u8 CipherAlg, struct rt_mac_table_entry *pEntry) -{ - u32 WCIDAttri = 0; - u16 offset; - u8 IVEIV = 0; - u16 Wcid = 0; - - { - { - if (BssIdx > BSS0) { - DBGPRINT(RT_DEBUG_ERROR, - ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", - BssIdx)); - return; - } - /* 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists. */ - /* 2. In Infra mode, the AID:1 MUST be wcid of infra STA. */ - /* the AID:2~ assign to mesh link entry. */ - if (pEntry) - Wcid = pEntry->Aid; - else - Wcid = MCAST_WCID; - } - } - - /* Update WCID attribute table */ - offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); - - { - if (pEntry && pEntry->ValidAsMesh) - WCIDAttri = (CipherAlg << 1) | PAIRWISEKEYTABLE; - else - WCIDAttri = (CipherAlg << 1) | SHAREDKEYTABLE; - } - - RTMP_IO_WRITE32(pAd, offset, WCIDAttri); - - /* Update IV/EIV table */ - offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE); - - /* WPA mode */ - if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) - || (CipherAlg == CIPHER_AES)) { - /* Eiv bit on. keyid always is 0 for pairwise key */ - IVEIV = (KeyIdx << 6) | 0x20; - } else { - /* WEP KeyIdx is default tx key. */ - IVEIV = (KeyIdx << 6); - } - - /* For key index and ext IV bit, so only need to update the position(offset+3). */ -#ifdef RTMP_MAC_PCI - RTMP_IO_WRITE8(pAd, offset + 3, IVEIV); -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - RTUSBMultiWrite_OneByte(pAd, offset + 3, &IVEIV); -#endif /* RTMP_MAC_USB // */ - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n", - Wcid, KeyIdx, CipherName[CipherAlg])); - DBGPRINT(RT_DEBUG_TRACE, (" WCIDAttri = 0x%x \n", WCIDAttri)); - -} - -/* - ========================================================================== - Description: - Parse encryption type -Arguments: - pAdapter Pointer to our adapter - wrq Pointer to the ioctl argument - - Return Value: - None - - Note: - ========================================================================== -*/ -char *GetEncryptType(char enc) -{ - if (enc == Ndis802_11WEPDisabled) - return "NONE"; - if (enc == Ndis802_11WEPEnabled) - return "WEP"; - if (enc == Ndis802_11Encryption2Enabled) - return "TKIP"; - if (enc == Ndis802_11Encryption3Enabled) - return "AES"; - if (enc == Ndis802_11Encryption4Enabled) - return "TKIPAES"; - else - return "UNKNOW"; -} - -char *GetAuthMode(char auth) -{ - if (auth == Ndis802_11AuthModeOpen) - return "OPEN"; - if (auth == Ndis802_11AuthModeShared) - return "SHARED"; - if (auth == Ndis802_11AuthModeAutoSwitch) - return "AUTOWEP"; - if (auth == Ndis802_11AuthModeWPA) - return "WPA"; - if (auth == Ndis802_11AuthModeWPAPSK) - return "WPAPSK"; - if (auth == Ndis802_11AuthModeWPANone) - return "WPANONE"; - if (auth == Ndis802_11AuthModeWPA2) - return "WPA2"; - if (auth == Ndis802_11AuthModeWPA2PSK) - return "WPA2PSK"; - if (auth == Ndis802_11AuthModeWPA1WPA2) - return "WPA1WPA2"; - if (auth == Ndis802_11AuthModeWPA1PSKWPA2PSK) - return "WPA1PSKWPA2PSK"; - - return "UNKNOW"; -} - -int SetCommonHT(struct rt_rtmp_adapter *pAd) -{ - struct rt_oid_set_ht_phymode SetHT; - - if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) - return FALSE; - - SetHT.PhyMode = pAd->CommonCfg.PhyMode; - SetHT.TransmitNo = ((u8)pAd->Antenna.field.TxPath); - SetHT.HtMode = (u8)pAd->CommonCfg.RegTransmitSetting.field.HTMODE; - SetHT.ExtOffset = - (u8)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA; - SetHT.MCS = MCS_AUTO; - SetHT.BW = (u8)pAd->CommonCfg.RegTransmitSetting.field.BW; - SetHT.STBC = (u8)pAd->CommonCfg.RegTransmitSetting.field.STBC; - SetHT.SHORTGI = (u8)pAd->CommonCfg.RegTransmitSetting.field.ShortGI; - - RTMPSetHT(pAd, &SetHT); - - return TRUE; -} - -char *RTMPGetRalinkEncryModeStr(u16 encryMode) -{ - switch (encryMode) { - case Ndis802_11WEPDisabled: - return "NONE"; - case Ndis802_11WEPEnabled: - return "WEP"; - case Ndis802_11Encryption2Enabled: - return "TKIP"; - case Ndis802_11Encryption3Enabled: - return "AES"; - case Ndis802_11Encryption4Enabled: - return "TKIPAES"; - default: - return "UNKNOW"; - } -} diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c deleted file mode 100644 index d06f0a6dc379..000000000000 --- a/drivers/staging/rt2860/common/cmm_mac_pci.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#ifdef RTMP_MAC_PCI -#include "../rt_config.h" - -/* - ======================================================================== - - Routine Description: - Allocate DMA memory blocks for send, receive - - Arguments: - Adapter Pointer to our adapter - - Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) -{ - int Status = NDIS_STATUS_SUCCESS; - unsigned long RingBasePaHigh; - unsigned long RingBasePaLow; - void *RingBaseVa; - int index, num; - struct rt_txd * pTxD; - struct rt_rxd * pRxD; - unsigned long ErrorValue = 0; - struct rt_rtmp_tx_ring *pTxRing; - struct rt_rtmp_dmabuf *pDmaBuf; - void *pPacket; -/* PRTMP_REORDERBUF pReorderBuf; */ - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); - do { - /* */ - /* Allocate all ring descriptors, include TxD, RxD, MgmtD. */ - /* Although each size is different, to prevent cacheline and alignment */ - /* issue, I intentional set them all to 64 bytes. */ - /* */ - for (num = 0; num < NUM_OF_TX_RING; num++) { - unsigned long BufBasePaHigh; - unsigned long BufBasePaLow; - void *BufBaseVa; - - /* */ - /* Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA) */ - /* */ - pAd->TxDescRing[num].AllocSize = - TX_RING_SIZE * TXD_SIZE; - RTMP_AllocateTxDescMemory(pAd, num, - pAd->TxDescRing[num]. - AllocSize, FALSE, - &pAd->TxDescRing[num].AllocVa, - &pAd->TxDescRing[num]. - AllocPa); - - if (pAd->TxDescRing[num].AllocVa == NULL) { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR("Failed to allocate a big buffer\n"); - Status = NDIS_STATUS_RESOURCES; - break; - } - /* Zero init this memory block */ - NdisZeroMemory(pAd->TxDescRing[num].AllocVa, - pAd->TxDescRing[num].AllocSize); - - /* Save PA & VA for further operation */ - RingBasePaHigh = - RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num]. - AllocPa); - RingBasePaLow = - RTMP_GetPhysicalAddressLow(pAd->TxDescRing[num]. - AllocPa); - RingBaseVa = pAd->TxDescRing[num].AllocVa; - - /* */ - /* Allocate all 1st TXBuf's memory for this TxRing */ - /* */ - pAd->TxBufSpace[num].AllocSize = - TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; - RTMP_AllocateFirstTxBuffer(pAd, num, - pAd->TxBufSpace[num]. - AllocSize, FALSE, - &pAd->TxBufSpace[num]. - AllocVa, - &pAd->TxBufSpace[num]. - AllocPa); - - if (pAd->TxBufSpace[num].AllocVa == NULL) { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR("Failed to allocate a big buffer\n"); - Status = NDIS_STATUS_RESOURCES; - break; - } - /* Zero init this memory block */ - NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, - pAd->TxBufSpace[num].AllocSize); - - /* Save PA & VA for further operation */ - BufBasePaHigh = - RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num]. - AllocPa); - BufBasePaLow = - RTMP_GetPhysicalAddressLow(pAd->TxBufSpace[num]. - AllocPa); - BufBaseVa = pAd->TxBufSpace[num].AllocVa; - - /* */ - /* Initialize Tx Ring Descriptor and associated buffer memory */ - /* */ - pTxRing = &pAd->TxRing[num]; - for (index = 0; index < TX_RING_SIZE; index++) { - pTxRing->Cell[index].pNdisPacket = NULL; - pTxRing->Cell[index].pNextNdisPacket = NULL; - /* Init Tx Ring Size, Va, Pa variables */ - pTxRing->Cell[index].AllocSize = TXD_SIZE; - pTxRing->Cell[index].AllocVa = RingBaseVa; - RTMP_SetPhysicalAddressHigh(pTxRing-> - Cell[index].AllocPa, - RingBasePaHigh); - RTMP_SetPhysicalAddressLow(pTxRing->Cell[index]. - AllocPa, - RingBasePaLow); - - /* Setup Tx Buffer size & address. only 802.11 header will store in this space */ - pDmaBuf = &pTxRing->Cell[index].DmaBuf; - pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; - pDmaBuf->AllocVa = BufBaseVa; - RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, - BufBasePaHigh); - RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, - BufBasePaLow); - - /* link the pre-allocated TxBuf to TXD */ - pTxD = - (struct rt_txd *) pTxRing->Cell[index].AllocVa; - pTxD->SDPtr0 = BufBasePaLow; - /* advance to next ring descriptor address */ - pTxD->DMADONE = 1; - RingBasePaLow += TXD_SIZE; - RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE; - - /* advance to next TxBuf address */ - BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; - BufBaseVa = - (u8 *)BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; - } - DBGPRINT(RT_DEBUG_TRACE, - ("TxRing[%d]: total %d entry allocated\n", num, - index)); - } - if (Status == NDIS_STATUS_RESOURCES) - break; - - /* */ - /* Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler */ - /* */ - pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; - RTMP_AllocateMgmtDescMemory(pAd, - pAd->MgmtDescRing.AllocSize, - FALSE, - &pAd->MgmtDescRing.AllocVa, - &pAd->MgmtDescRing.AllocPa); - - if (pAd->MgmtDescRing.AllocVa == NULL) { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR("Failed to allocate a big buffer\n"); - Status = NDIS_STATUS_RESOURCES; - break; - } - /* Zero init this memory block */ - NdisZeroMemory(pAd->MgmtDescRing.AllocVa, - pAd->MgmtDescRing.AllocSize); - - /* Save PA & VA for further operation */ - RingBasePaHigh = - RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); - RingBasePaLow = - RTMP_GetPhysicalAddressLow(pAd->MgmtDescRing.AllocPa); - RingBaseVa = pAd->MgmtDescRing.AllocVa; - - /* */ - /* Initialize MGMT Ring and associated buffer memory */ - /* */ - for (index = 0; index < MGMT_RING_SIZE; index++) { - pAd->MgmtRing.Cell[index].pNdisPacket = NULL; - pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; - /* Init MGMT Ring Size, Va, Pa variables */ - pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; - pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; - RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index]. - AllocPa, RingBasePaHigh); - RTMP_SetPhysicalAddressLow(pAd->MgmtRing.Cell[index]. - AllocPa, RingBasePaLow); - - /* Offset to next ring descriptor address */ - RingBasePaLow += TXD_SIZE; - RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE; - - /* link the pre-allocated TxBuf to TXD */ - pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[index].AllocVa; - pTxD->DMADONE = 1; - - /* no pre-allocated buffer required in MgmtRing for scatter-gather case */ - } - DBGPRINT(RT_DEBUG_TRACE, - ("MGMT Ring: total %d entry allocated\n", index)); - - /* */ - /* Allocate RX ring descriptor's memory except Tx ring which allocated eariler */ - /* */ - pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; - RTMP_AllocateRxDescMemory(pAd, - pAd->RxDescRing.AllocSize, - FALSE, - &pAd->RxDescRing.AllocVa, - &pAd->RxDescRing.AllocPa); - - if (pAd->RxDescRing.AllocVa == NULL) { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR("Failed to allocate a big buffer\n"); - Status = NDIS_STATUS_RESOURCES; - break; - } - /* Zero init this memory block */ - NdisZeroMemory(pAd->RxDescRing.AllocVa, - pAd->RxDescRing.AllocSize); - - DBGPRINT(RT_DEBUG_OFF, - ("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, - pAd->RxDescRing.AllocSize)); - - /* Save PA & VA for further operation */ - RingBasePaHigh = - RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); - RingBasePaLow = - RTMP_GetPhysicalAddressLow(pAd->RxDescRing.AllocPa); - RingBaseVa = pAd->RxDescRing.AllocVa; - - /* */ - /* Initialize Rx Ring and associated buffer memory */ - /* */ - for (index = 0; index < RX_RING_SIZE; index++) { - /* Init RX Ring Size, Va, Pa variables */ - pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; - pAd->RxRing.Cell[index].AllocVa = RingBaseVa; - RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index]. - AllocPa, RingBasePaHigh); - RTMP_SetPhysicalAddressLow(pAd->RxRing.Cell[index]. - AllocPa, RingBasePaLow); - - /*NdisZeroMemory(RingBaseVa, RXD_SIZE); */ - - /* Offset to next ring descriptor address */ - RingBasePaLow += RXD_SIZE; - RingBaseVa = (u8 *)RingBaseVa + RXD_SIZE; - - /* Setup Rx associated Buffer size & allocate share memory */ - pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; - pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; - pPacket = RTMP_AllocateRxPacketBuffer(pAd, - pDmaBuf-> - AllocSize, FALSE, - &pDmaBuf->AllocVa, - &pDmaBuf-> - AllocPa); - - /* keep allocated rx packet */ - pAd->RxRing.Cell[index].pNdisPacket = pPacket; - - /* Error handling */ - if (pDmaBuf->AllocVa == NULL) { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR("Failed to allocate RxRing's 1st buffer\n"); - Status = NDIS_STATUS_RESOURCES; - break; - } - /* Zero init this memory block */ - NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); - - /* Write RxD buffer address & allocated buffer length */ - pRxD = (struct rt_rxd *) pAd->RxRing.Cell[index].AllocVa; - pRxD->SDP0 = - RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); - pRxD->DDONE = 0; - - } - - DBGPRINT(RT_DEBUG_TRACE, - ("Rx Ring: total %d entry allocated\n", index)); - - } while (FALSE); - - NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame)); - pAd->FragFrame.pFragPacket = - RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); - - if (pAd->FragFrame.pFragPacket == NULL) { - Status = NDIS_STATUS_RESOURCES; - } - - if (Status != NDIS_STATUS_SUCCESS) { - /* Log error inforamtion */ - NdisWriteErrorLogEntry(pAd->AdapterHandle, - NDIS_ERROR_CODE_OUT_OF_RESOURCES, - 1, ErrorValue); - } - /* Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here. */ - { - DBGPRINT(RT_DEBUG_TRACE, - ("--> NICInitTxRxRingAndBacklogQueue\n")); - -/* - // Disable DMA. - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - GloCfg.word &= 0xff0; - GloCfg.field.EnTXWriteBackDDONE =1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); -*/ - - /* Initialize all transmit related software queues */ - for (index = 0; index < NUM_OF_TX_RING; index++) { - InitializeQueueHeader(&pAd->TxSwQueue[index]); - /* Init TX rings index pointer */ - pAd->TxRing[index].TxSwFreeIdx = 0; - pAd->TxRing[index].TxCpuIdx = 0; - /*RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) , pAd->TxRing[i].TX_CTX_IDX); */ - } - - /* Init RX Ring index pointer */ - pAd->RxRing.RxSwReadIdx = 0; - pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1; - /*RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0); */ - - /* init MGMT ring index pointer */ - pAd->MgmtRing.TxSwFreeIdx = 0; - pAd->MgmtRing.TxCpuIdx = 0; - - pAd->PrivateInfo.TxRingFullCnt = 0; - - DBGPRINT(RT_DEBUG_TRACE, - ("<-- NICInitTxRxRingAndBacklogQueue\n")); - } - - DBGPRINT_S(Status, - ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); - return Status; -} - -/* - ======================================================================== - - Routine Description: - Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero. - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - Reset NIC to initial state AS IS system boot up time. - - ======================================================================== -*/ -void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType) -{ - struct rt_txd * pTxD; - struct rt_rxd * pRxD; - struct rt_queue_entry *pEntry; - void *pPacket; - int i; - struct rt_rtmp_tx_ring *pTxRing; - unsigned long IrqFlags; - /*u32 RxSwReadIdx; */ - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, - pAd->RalinkCounters.PendingNdisPacketCount)); - switch (RingType) { - case QID_AC_BK: - case QID_AC_BE: - case QID_AC_VI: - case QID_AC_VO: - - pTxRing = &pAd->TxRing[RingType]; - - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - /* We have to clean all descriptors in case some error happened with reset */ - for (i = 0; i < TX_RING_SIZE; i++) /* We have to scan all TX ring */ - { - pTxD = (struct rt_txd *) pTxRing->Cell[i].AllocVa; - - pPacket = (void *)pTxRing->Cell[i].pNdisPacket; - /* release scatter-and-gather char */ - if (pPacket) { - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_FAILURE); - pTxRing->Cell[i].pNdisPacket = NULL; - } - - pPacket = - (void *)pTxRing->Cell[i].pNextNdisPacket; - /* release scatter-and-gather char */ - if (pPacket) { - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_FAILURE); - pTxRing->Cell[i].pNextNdisPacket = NULL; - } - } - - RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, - &pTxRing->TxDmaIdx); - pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx; - pTxRing->TxCpuIdx = pTxRing->TxDmaIdx; - RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, - pTxRing->TxCpuIdx); - - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - while (pAd->TxSwQueue[RingType].Head != NULL) { - pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - DBGPRINT(RT_DEBUG_TRACE, - ("Release 1 NDIS packet from s/w backlog queue\n")); - } - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - break; - - case QID_MGMT: - /* We have to clean all descriptors in case some error happened with reset */ - NdisAcquireSpinLock(&pAd->MgmtRingLock); - - for (i = 0; i < MGMT_RING_SIZE; i++) { - pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[i].AllocVa; - - pPacket = - (void *)pAd->MgmtRing.Cell[i].pNdisPacket; - /* rlease scatter-and-gather char */ - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, - pTxD->SDLen0, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_FAILURE); - } - pAd->MgmtRing.Cell[i].pNdisPacket = NULL; - - pPacket = - (void *)pAd->MgmtRing.Cell[i]. - pNextNdisPacket; - /* release scatter-and-gather char */ - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, - pTxD->SDLen1, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_FAILURE); - } - pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL; - - } - - RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx); - pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx; - pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx; - RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); - - NdisReleaseSpinLock(&pAd->MgmtRingLock); - pAd->RalinkCounters.MgmtRingFullCount = 0; - break; - - case QID_RX: - /* We have to clean all descriptors in case some error happened with reset */ - NdisAcquireSpinLock(&pAd->RxRingLock); - - for (i = 0; i < RX_RING_SIZE; i++) { - pRxD = (struct rt_rxd *) pAd->RxRing.Cell[i].AllocVa; - pRxD->DDONE = 0; - } - - RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx); - pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx; - pAd->RxRing.RxCpuIdx = - ((pAd->RxRing.RxDmaIdx == - 0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxDmaIdx - 1)); - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - - NdisReleaseSpinLock(&pAd->RxRingLock); - break; - - default: - break; - } -} - -void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd) -{ - int index, num, j; - struct rt_rtmp_tx_ring *pTxRing; - struct rt_txd * pTxD; - void *pPacket; - unsigned int IrqFlags; - - /*struct os_cookie *pObj =(struct os_cookie *)pAd->OS_Cookie; */ - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n")); - - /* Free TxSwQueue Packet */ - for (index = 0; index < NUM_OF_TX_RING; index++) { - struct rt_queue_entry *pEntry; - void *pPacket; - struct rt_queue_header *pQueue; - - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - pQueue = &pAd->TxSwQueue[index]; - while (pQueue->Head) { - pEntry = RemoveHeadQueue(pQueue); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - } - - /* Free Tx Ring Packet */ - for (index = 0; index < NUM_OF_TX_RING; index++) { - pTxRing = &pAd->TxRing[index]; - - for (j = 0; j < TX_RING_SIZE; j++) { - pTxD = (struct rt_txd *) (pTxRing->Cell[j].AllocVa); - pPacket = pTxRing->Cell[j].pNdisPacket; - - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, - pTxD->SDLen0, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_SUCCESS); - } - /*Always assign pNdisPacket as NULL after clear */ - pTxRing->Cell[j].pNdisPacket = NULL; - - pPacket = pTxRing->Cell[j].pNextNdisPacket; - - if (pPacket) { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, - pTxD->SDLen1, - PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_SUCCESS); - } - /*Always assign pNextNdisPacket as NULL after clear */ - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = - NULL; - - } - } - - for (index = RX_RING_SIZE - 1; index >= 0; index--) { - if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) - && (pAd->RxRing.Cell[index].pNdisPacket)) { - PCI_UNMAP_SINGLE(pAd, - pAd->RxRing.Cell[index].DmaBuf.AllocPa, - pAd->RxRing.Cell[index].DmaBuf. - AllocSize, PCI_DMA_FROMDEVICE); - RELEASE_NDIS_PACKET(pAd, - pAd->RxRing.Cell[index].pNdisPacket, - NDIS_STATUS_SUCCESS); - } - } - NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(struct rt_rtmp_dmacb)); - - if (pAd->RxDescRing.AllocVa) { - RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize, - pAd->RxDescRing.AllocVa, - pAd->RxDescRing.AllocPa); - } - NdisZeroMemory(&pAd->RxDescRing, sizeof(struct rt_rtmp_dmabuf)); - - if (pAd->MgmtDescRing.AllocVa) { - RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize, - pAd->MgmtDescRing.AllocVa, - pAd->MgmtDescRing.AllocPa); - } - NdisZeroMemory(&pAd->MgmtDescRing, sizeof(struct rt_rtmp_dmabuf)); - - for (num = 0; num < NUM_OF_TX_RING; num++) { - if (pAd->TxBufSpace[num].AllocVa) { - RTMP_FreeFirstTxBuffer(pAd, - pAd->TxBufSpace[num].AllocSize, - FALSE, - pAd->TxBufSpace[num].AllocVa, - pAd->TxBufSpace[num].AllocPa); - } - NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(struct rt_rtmp_dmabuf)); - - if (pAd->TxDescRing[num].AllocVa) { - RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize, - pAd->TxDescRing[num].AllocVa, - pAd->TxDescRing[num].AllocPa); - } - NdisZeroMemory(&pAd->TxDescRing[num], sizeof(struct rt_rtmp_dmabuf)); - } - - if (pAd->FragFrame.pFragPacket) - RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, - NDIS_STATUS_SUCCESS); - - DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n")); -} - -/*************************************************************************** - * - * register related procedures. - * - **************************************************************************/ -/* -======================================================================== -Routine Description: - Disable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RT28XXDMADisable(struct rt_rtmp_adapter *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - GloCfg.word &= 0xff0; - GloCfg.field.EnTXWriteBackDDONE = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); -} - -/* -======================================================================== -Routine Description: - Enable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - int i = 0; - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); - do { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) - && (GloCfg.field.RxDMABusy == 0)) - break; - - DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); - RTMPusecDelay(1000); - i++; - } while (i < 200); - - RTMPusecDelay(50); - - GloCfg.field.EnTXWriteBackDDONE = 1; - GloCfg.field.WPDMABurstSIZE = 2; - GloCfg.field.EnableRxDMA = 1; - GloCfg.field.EnableTxDMA = 1; - - DBGPRINT(RT_DEBUG_TRACE, - ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - -} - -BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command) -{ - u32 CmdStatus = 0, CID = 0, i; - u32 ThisCIDMask = 0; - - i = 0; - do { - RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID); - /* Find where the command is. Because this is randomly specified by firmware. */ - if ((CID & CID0MASK) == Command) { - ThisCIDMask = CID0MASK; - break; - } else if ((((CID & CID1MASK) >> 8) & 0xff) == Command) { - ThisCIDMask = CID1MASK; - break; - } else if ((((CID & CID2MASK) >> 16) & 0xff) == Command) { - ThisCIDMask = CID2MASK; - break; - } else if ((((CID & CID3MASK) >> 24) & 0xff) == Command) { - ThisCIDMask = CID3MASK; - break; - } - - RTMPusecDelay(100); - i++; - } while (i < 200); - - /* Get CommandStatus Value */ - RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus); - - /* This command's status is at the same position as command. So AND command position's bitmask to read status. */ - if (i < 200) { - /* If Status is 1, the command is success. */ - if (((CmdStatus & ThisCIDMask) == 0x1) - || ((CmdStatus & ThisCIDMask) == 0x100) - || ((CmdStatus & ThisCIDMask) == 0x10000) - || ((CmdStatus & ThisCIDMask) == 0x1000000)) { - DBGPRINT(RT_DEBUG_TRACE, - ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", - CID, CmdStatus)); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); - return TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, - ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", - CID, CmdStatus)); - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", - Command, CmdStatus)); - } - /* Clear Command and Status. */ - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); - - return FALSE; -} - -/* -======================================================================== -Routine Description: - Write Beacon buffer to Asic. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd, - int apidx, - unsigned long FrameLen, unsigned long UpdatePos) -{ - unsigned long CapInfoPos = 0; - u8 *ptr, *ptr_update, *ptr_capinfo; - u32 i; - BOOLEAN bBcnReq = FALSE; - u8 bcn_idx = 0; - - { - DBGPRINT(RT_DEBUG_ERROR, - ("%s() : No valid Interface be found.\n", __func__)); - return; - } - - /*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) */ - /* || ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) */ - /* || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */ - /* ) */ - if (bBcnReq == FALSE) { - /* when the ra interface is down, do not send its beacon frame */ - /* clear all zero */ - for (i = 0; i < TXWI_SIZE; i += 4) - RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, - 0x00); - } else { - ptr = (u8 *)& pAd->BeaconTxWI; - for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */ - { - u32 longptr = - *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) + - (*(ptr + 3) << 24); - RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, - longptr); - ptr += 4; - } - - /* Update CapabilityInfo in Beacon */ - for (i = CapInfoPos; i < (CapInfoPos + 2); i++) { - RTMP_IO_WRITE8(pAd, - pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + - i, *ptr_capinfo); - ptr_capinfo++; - } - - if (FrameLen > UpdatePos) { - for (i = UpdatePos; i < (FrameLen); i++) { - RTMP_IO_WRITE8(pAd, - pAd->BeaconOffset[bcn_idx] + - TXWI_SIZE + i, *ptr_update); - ptr_update++; - } - } - - } - -} - -void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx) -{ - AUTO_WAKEUP_STRUC AutoWakeupCfg; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - return; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) { - DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n")); - return; - } - - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); - - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - /* Support PCIe Advance Power Save */ - if (bFromTx == TRUE && (pAd->Mlme.bPsPollTimerRunning == TRUE)) { - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - RTMPusecDelay(3000); - DBGPRINT(RT_DEBUG_TRACE, - ("=======AsicForceWakeup===bFromTx\n")); - } - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) { -#ifdef PCIE_PS_SUPPORT - /* add by johnli, RF power sequence setup, load RF normal operation-mode setup */ - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd)) { - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - - if (pChipOps->AsicReverseRfFromSleepMode) - pChipOps-> - AsicReverseRfFromSleepMode(pAd); - } else -#endif /* PCIE_PS_SUPPORT // */ - { - /* end johnli */ - /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */ - if (INFRA_ON(pAd) - && (pAd->CommonCfg.CentralChannel != - pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo. - ChannelWidth == BW_40)) { - /* Must using 40MHz. */ - AsicSwitchChannel(pAd, - pAd->CommonCfg. - CentralChannel, - FALSE); - AsicLockChannel(pAd, - pAd->CommonCfg. - CentralChannel); - } else { - /* Must using 20MHz. */ - AsicSwitchChannel(pAd, - pAd->CommonCfg. - Channel, FALSE); - AsicLockChannel(pAd, - pAd->CommonCfg.Channel); - } - } - } -#ifdef PCIE_PS_SUPPORT - /* 3090 MCU Wakeup command needs more time to be stable. */ - /* Before stable, don't issue other MCU command to prevent from firmware error. */ - if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n")); - RTMP_SEM_LOCK(&pAd->McuCmdLock); - pAd->brt30xxBanMcuCmd = FALSE; - RTMP_SEM_UNLOCK(&pAd->McuCmdLock); - } -#endif /* PCIE_PS_SUPPORT // */ - } else { - /* PCI, 2860-PCIe */ - DBGPRINT(RT_DEBUG_TRACE, - ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n")); - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - } - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); - DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n")); -} - -void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, - u16 TbttNumToNextWakeUp) -{ - BOOLEAN brc; - - if (pAd->StaCfg.bRadio == FALSE) { - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - return; - } - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - unsigned long Now = 0; - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) { - DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n")); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - return; - } - - NdisGetSystemUpTime(&Now); - /* If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM. */ - /* Because Some AP can't queuing outgoing frames immediately. */ - if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) - && (pAd->Mlme.LastSendNULLpsmTime <= Now)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Now = %lu, LastSendNULLpsmTime=%lu : RxCountSinceLastNULL = %lu. \n", - Now, pAd->Mlme.LastSendNULLpsmTime, - pAd->RalinkCounters.RxCountSinceLastNULL)); - return; - } else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) - && - ((pAd->Mlme.LastSendNULLpsmTime + - pAd->CommonCfg.BeaconPeriod) >= Now)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", - Now, pAd->Mlme.LastSendNULLpsmTime, - pAd->RalinkCounters.RxCountSinceLastNULL)); - return; - } - - brc = - RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, - TbttNumToNextWakeUp); - if (brc == TRUE) - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); - } else { - AUTO_WAKEUP_STRUC AutoWakeupCfg; - /* we have decided to SLEEP, so at least do it for a BEACON period. */ - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - /*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); */ - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; - AutoWakeupCfg.field.EnableAutoWakeup = 1; - AutoWakeupCfg.field.AutoLeadTime = 5; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00); /* send POWER-SAVE command to MCU. Timeout 40us. */ - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); - DBGPRINT(RT_DEBUG_TRACE, - ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__, - TbttNumToNextWakeUp)); - } - -} - -void PsPollWakeExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - unsigned long flags; - - DBGPRINT(RT_DEBUG_TRACE, ("-->PsPollWakeExec \n")); - RTMP_INT_LOCK(&pAd->irq_lock, flags); - if (pAd->Mlme.bPsPollTimerRunning) { - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - } - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -#ifdef PCIE_PS_SUPPORT - /* For rt30xx power solution 3, Use software timer to wake up in psm. So call */ - /* AsicForceWakeup here instead of handling twakeup interrupt. */ - if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd)) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n")); - AsicForceWakeup(pAd, DOT11POWERSAVE); - } -#endif /* PCIE_PS_SUPPORT // */ -} - -void RadioOnExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - WPDMA_GLO_CFG_STRUC DmaCfg; - BOOLEAN Cancelled; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n")); -/*KH Debug: Add the compile flag "RT2860 and condition */ -#ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); -#endif /* RTMP_PCI_SUPPORT // */ - return; - } - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { - DBGPRINT(RT_DEBUG_TRACE, - ("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n")); -#ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); -#endif /* RTMP_PCI_SUPPORT // */ - return; - } -/*KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes. */ -#ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - } -#endif /* RTMP_PCI_SUPPORT // */ - if (pAd->StaCfg.bRadio == TRUE) { - pAd->bPCIclkOff = FALSE; - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - /* 2. Send wake up command. */ - AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); - /* 2-1. wait command ok. */ - AsicCheckCommanOk(pAd, PowerWakeCID); - - /* When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt. */ - /*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT)); */ - RTMP_ASIC_INTERRUPT_ENABLE(pAd); - - /* 3. Enable Tx DMA. */ - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - DmaCfg.field.EnableTxDMA = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word); - - /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */ - if (INFRA_ON(pAd) - && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == - BW_40)) { - /* Must using 40MHz. */ - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, - FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - } else { - /* Must using 20MHz. */ - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - } - -/*KH Debug:The following codes should be enclosed by RT3090 compile flag */ - if (pChipOps->AsicReverseRfFromSleepMode) - pChipOps->AsicReverseRfFromSleepMode(pAd); - -#ifdef PCIE_PS_SUPPORT -/* 3090 MCU Wakeup command needs more time to be stable. */ -/* Before stable, don't issue other MCU command to prevent from firmware error. */ - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - RTMP_SEM_LOCK(&pAd->McuCmdLock); - pAd->brt30xxBanMcuCmd = FALSE; - RTMP_SEM_UNLOCK(&pAd->McuCmdLock); - } -#endif /* PCIE_PS_SUPPORT // */ - - /* Clear Radio off flag */ - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - /* Set LED */ - RTMPSetLED(pAd, LED_RADIO_ON); - - if (pAd->StaCfg.Psm == PWR_ACTIVE) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, - pAd->StaCfg.BBPR3); - } - } else { - RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); - } -} - -/* - ========================================================================== - Description: - This routine sends command to firmware and turn our chip to wake up mode from power save mode. - Both RadioOn and .11 power save function needs to call this routine. - Input: - Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On. Need to restore PCI host value. - Level = other value : normal wake up function. - - ========================================================================== - */ -BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level) -{ - /*WPDMA_GLO_CFG_STRUC DmaCfg; */ - BOOLEAN Cancelled; - /*u32 MACValue; */ - - if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE) - return FALSE; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - } - if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE && - (Level == GUIRADIO_OFF || Level == GUI_IDLE_POWER_SAVE)) || - RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) { - /* Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore */ - /* return condition here. */ - /* - if (((pAd->MACVersion&0xffff0000) != 0x28600000) - && ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID) - ||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID))) - */ - { - DBGPRINT(RT_DEBUG_TRACE, - ("RT28xxPciAsicRadioOn ()\n")); - /* 1. Set PCI Link Control in Configuration Space. */ - RTMPPCIeLinkCtrlValueRestore(pAd, - RESTORE_WAKEUP); - RTMPusecDelay(6000); - } - } - } -#ifdef PCIE_PS_SUPPORT - if (! - (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)))) -#endif /* PCIE_PS_SUPPORT // */ - { - pAd->bPCIclkOff = FALSE; - DBGPRINT(RT_DEBUG_TRACE, - ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff)); - } - /* 2. Send wake up command. */ - AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); - pAd->bPCIclkOff = FALSE; - /* 2-1. wait command ok. */ - AsicCheckCommanOk(pAd, PowerWakeCID); - RTMP_ASIC_INTERRUPT_ENABLE(pAd); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); - if (Level == GUI_IDLE_POWER_SAVE) { -#ifdef PCIE_PS_SUPPORT - - /* add by johnli, RF power sequence setup, load RF normal operation-mode setup */ - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) { - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - - if (pChipOps->AsicReverseRfFromSleepMode) - pChipOps->AsicReverseRfFromSleepMode(pAd); - /* 3090 MCU Wakeup command needs more time to be stable. */ - /* Before stable, don't issue other MCU command to prevent from firmware error. */ - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == - 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == - TRUE)) { - RTMP_SEM_LOCK(&pAd->McuCmdLock); - pAd->brt30xxBanMcuCmd = FALSE; - RTMP_SEM_UNLOCK(&pAd->McuCmdLock); - } - } else - /* end johnli */ -#endif /* PCIE_PS_SUPPORT // */ - { - /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */ - { - if (INFRA_ON(pAd) - && (pAd->CommonCfg.CentralChannel != - pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo. - ChannelWidth == BW_40)) { - /* Must using 40MHz. */ - AsicSwitchChannel(pAd, - pAd->CommonCfg. - CentralChannel, - FALSE); - AsicLockChannel(pAd, - pAd->CommonCfg. - CentralChannel); - } else { - /* Must using 20MHz. */ - AsicSwitchChannel(pAd, - pAd->CommonCfg. - Channel, FALSE); - AsicLockChannel(pAd, - pAd->CommonCfg.Channel); - } - } - - } - } - return TRUE; - -} - -/* - ========================================================================== - Description: - This routine sends command to firmware and turn our chip to power save mode. - Both RadioOff and .11 power save function needs to call this routine. - Input: - Level = GUIRADIO_OFF : GUI Radio Off mode - Level = DOT11POWERSAVE : 802.11 power save mode - Level = RTMP_HALT : When Disable device. - - ========================================================================== - */ -BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd, - u8 Level, u16 TbttNumToNextWakeUp) -{ - WPDMA_GLO_CFG_STRUC DmaCfg; - u8 i, tempBBP_R3 = 0; - BOOLEAN brc = FALSE, Cancelled; - u32 TbTTTime = 0; - u32 PsPollTime = 0 /*, MACValue */ ; - unsigned long BeaconPeriodTime; - u32 RxDmaIdx, RxCpuIdx; - DBGPRINT(RT_DEBUG_TRACE, - ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", - Level, pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, - pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx)); - - if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE) - return FALSE; - - /* Check Rx DMA busy status, if more than half is occupied, give up this radio off. */ - RTMP_IO_READ32(pAd, RX_DRX_IDX, &RxDmaIdx); - RTMP_IO_READ32(pAd, RX_CRX_IDX, &RxCpuIdx); - if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE / 3)) { - DBGPRINT(RT_DEBUG_TRACE, - ("AsicRadioOff ===> return1. RxDmaIdx = %d , RxCpuIdx = %d. \n", - RxDmaIdx, RxCpuIdx)); - return FALSE; - } else if ((RxCpuIdx >= RxDmaIdx) - && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE / 3)) { - DBGPRINT(RT_DEBUG_TRACE, - ("AsicRadioOff ===> return2. RxCpuIdx = %d. RxDmaIdx = %d , \n", - RxCpuIdx, RxDmaIdx)); - return FALSE; - } - /* Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. */ - /*pAd->bPCIclkOffDisableTx = TRUE; */ - RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && pAd->OpMode == OPMODE_STA - && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - - if (Level == DOT11POWERSAVE) { - RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime); - TbTTTime &= 0x1ffff; - /* 00. check if need to do sleep in this DTIM period. If next beacon will arrive within 30ms , ...doesn't necessarily sleep. */ - /* TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms */ - if (((64 * TbTTTime) < ((LEAD_TIME * 1024) + 40000)) - && (TbttNumToNextWakeUp == 0)) { - DBGPRINT(RT_DEBUG_TRACE, - ("TbTTTime = 0x%x , give up this sleep. \n", - TbTTTime)); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - /*pAd->bPCIclkOffDisableTx = FALSE; */ - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); - return FALSE; - } else { - PsPollTime = - (64 * TbTTTime - LEAD_TIME * 1024) / 1000; -#ifdef PCIE_PS_SUPPORT - if ((IS_RT3090(pAd) || IS_RT3572(pAd) - || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field. - rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field. - EnableNewPS == TRUE)) { - PsPollTime -= 5; - } else -#endif /* PCIE_PS_SUPPORT // */ - PsPollTime -= 3; - - BeaconPeriodTime = - pAd->CommonCfg.BeaconPeriod * 102 / 100; - if (TbttNumToNextWakeUp > 0) - PsPollTime += - ((TbttNumToNextWakeUp - - 1) * BeaconPeriodTime); - - pAd->Mlme.bPsPollTimerRunning = TRUE; - RTMPSetTimer(&pAd->Mlme.PsPollTimer, - PsPollTime); - } - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n")); - } - - pAd->bPCIclkOffDisableTx = FALSE; - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); - - /* Set to 1R. */ - if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA) { - tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3); - } - /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */ - if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP) - && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) { - /* Must using 40MHz. */ - AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); - } else { - /* Must using 20MHz. */ - AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); - } - - if (Level != RTMP_HALT) { - /* Change Interrupt bitmask. */ - /* When PCI clock is off, don't want to service interrupt. */ - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); - } else { - RTMP_ASIC_INTERRUPT_DISABLE(pAd); - } - - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - /* 2. Send Sleep command */ - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); - /* send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power */ - AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1); - /* 2-1. Wait command success */ - /* Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task. */ - brc = AsicCheckCommanOk(pAd, PowerSafeCID); - - /* 3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe. */ - /* If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem. */ - if ((Level == DOT11POWERSAVE) && (brc == TRUE)) { - AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00); /* lowbyte = 0 means to do power safe, NOT turn off radio. */ - /* 3-1. Wait command success */ - AsicCheckCommanOk(pAd, PowerRadioOffCID); - } else if (brc == TRUE) { - AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00); /* lowbyte = 0 means to do power safe, NOT turn off radio. */ - /* 3-1. Wait command success */ - AsicCheckCommanOk(pAd, PowerRadioOffCID); - } - /* 1. Wait DMA not busy */ - i = 0; - do { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - if ((DmaCfg.field.RxDMABusy == 0) - && (DmaCfg.field.TxDMABusy == 0)) - break; - RTMPusecDelay(20); - i++; - } while (i < 50); - - /* - if (i >= 50) - { - pAd->CheckDmaBusyCount++; - DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount)); - } - else - { - pAd->CheckDmaBusyCount = 0; - } - */ -/*KH Debug:My original codes have the following codes, but currecnt codes do not have it. */ -/* Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment. */ - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280); -/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ); */ - -#ifdef PCIE_PS_SUPPORT - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n")); - pAd->bPCIclkOff = TRUE; - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); - /* For this case, doesn't need to below actions, so return here. */ - return brc; - } -#endif /* PCIE_PS_SUPPORT // */ - - if (Level == DOT11POWERSAVE) { - AUTO_WAKEUP_STRUC AutoWakeupCfg; - /*RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90); */ - - /* we have decided to SLEEP, so at least do it for a BEACON period. */ - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - /* 1. Set auto wake up timer. */ - AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; - AutoWakeupCfg.field.EnableAutoWakeup = 1; - AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - } - /* 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. */ - if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA) { - if ((brc == TRUE) && (i < 50)) - RTMPPCIeLinkCtrlSetting(pAd, 1); - } - /* 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function */ - else if (pAd->OpMode == OPMODE_STA) { - if ((brc == TRUE) && (i < 50)) - RTMPPCIeLinkCtrlSetting(pAd, 3); - } - /*pAd->bPCIclkOffDisableTx = FALSE; */ - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); - return TRUE; -} - -void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd) -{ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__)); - - if ((pAd->OpMode == OPMODE_AP) || ((pAd->OpMode == OPMODE_STA) - && - (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_PCIE_DEVICE) - || pAd->StaCfg.PSControl.field. - EnableNewPS == FALSE))) { - RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); - /*NICResetFromError(pAd); */ - - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - /* Enable Tx/Rx */ - RTMPEnableRxTx(pAd); - - /* Clear Radio off flag */ - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); - - /* Set LED */ - RTMPSetLED(pAd, LED_RADIO_ON); - } - - if ((pAd->OpMode == OPMODE_STA) && - (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - BOOLEAN Cancelled; - - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40); - } -} - -void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd) -{ - BOOLEAN brc = TRUE; - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - /* Link down first if any association exists */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) { - struct rt_mlme_disassoc_req DisReq; - struct rt_mlme_queue_elem *pMsgElem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - - if (pMsgElem) { - COPY_MAC_ADDR(&DisReq.Addr, - pAd->CommonCfg.Bssid); - DisReq.Reason = REASON_DISASSOC_STA_LEAVING; - - pMsgElem->Machine = ASSOC_STATE_MACHINE; - pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; - pMsgElem->MsgLen = - sizeof(struct rt_mlme_disassoc_req); - NdisMoveMemory(pMsgElem->Msg, &DisReq, - sizeof - (struct rt_mlme_disassoc_req)); - - MlmeDisassocReqAction(pAd, pMsgElem); - kfree(pMsgElem); - - RTMPusecDelay(1000); - } - } - } - - DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__)); - - /* Set Radio off flag */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - { - BOOLEAN Cancelled; - if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, - &Cancelled); - RTMP_CLEAR_FLAG(pAd, - fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - } - /* If during power safe mode. */ - if (pAd->StaCfg.bRadio == TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("-->MlmeRadioOff() return on bRadio == TRUE; \n")); - return; - } - /* Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF). */ - if (IDLE_ON(pAd) && - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) - { - RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); - } - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - BOOLEAN Cancelled; - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, - &Cancelled); - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, - &Cancelled); - } - } - /* Link down first if any association exists */ - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) - LinkDown(pAd, FALSE); - RTMPusecDelay(10000); - /*========================================== */ - /* Clean up old bss table */ - BssTableInit(&pAd->ScanTab); - - /* - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) - { - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); - return; - } - */ - } - - /* Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown */ - RTMPSetLED(pAd, LED_RADIO_OFF); - -/*KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs. */ -/*KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer */ -/*to avoid the deadlock with PCIe Power saving function. */ - if (pAd->OpMode == OPMODE_STA && - OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) && - pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) { - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); - } else { - brc = RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); - - if (brc == FALSE) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s call RT28xxPciAsicRadioOff fail!\n", - __func__)); - } - } -/* -*/ -} - -#endif /* RTMP_MAC_PCI // */ diff --git a/drivers/staging/rt2860/common/cmm_mac_usb.c b/drivers/staging/rt2860/common/cmm_mac_usb.c deleted file mode 100644 index 64a65a460c29..000000000000 --- a/drivers/staging/rt2860/common/cmm_mac_usb.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#ifdef RTMP_MAC_USB - -#include "../rt_config.h" - -/* -======================================================================== -Routine Description: - Initialize receive data structures. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_RESOURCES - -Note: - Initialize all receive releated private buffer, include those define - in struct rt_rtmp_adapter structure and all private data structures. The mahor - work is to allocate buffer for each packet and chain buffer to - NDIS packet descriptor. -======================================================================== -*/ -int NICInitRecv(struct rt_rtmp_adapter *pAd) -{ - u8 i; - int Status = NDIS_STATUS_SUCCESS; - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); - pObj = pObj; - - /*InterlockedExchange(&pAd->PendingRx, 0); */ - pAd->PendingRx = 0; - pAd->NextRxBulkInReadIndex = 0; /* Next Rx Read index */ - pAd->NextRxBulkInIndex = 0; /*RX_RING_SIZE -1; // Rx Bulk pointer */ - pAd->NextRxBulkInPosition = 0; - - for (i = 0; i < (RX_RING_SIZE); i++) { - struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); - - /*Allocate URB */ - pRxContext->pUrb = RTUSB_ALLOC_URB(0); - if (pRxContext->pUrb == NULL) { - Status = NDIS_STATUS_RESOURCES; - goto out1; - } - /* Allocate transfer buffer */ - pRxContext->TransferBuffer = - RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, - &pRxContext->data_dma); - if (pRxContext->TransferBuffer == NULL) { - Status = NDIS_STATUS_RESOURCES; - goto out1; - } - - NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); - - pRxContext->pAd = pAd; - pRxContext->pIrp = NULL; - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pRxContext->Readable = FALSE; - /*pRxContext->ReorderInUse = FALSE; */ - pRxContext->bRxHandling = FALSE; - pRxContext->BulkInOffset = 0; - } - - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status)); - return Status; - -out1: - for (i = 0; i < (RX_RING_SIZE); i++) { - struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); - - if (NULL != pRxContext->TransferBuffer) { - RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, - pRxContext->TransferBuffer, - pRxContext->data_dma); - pRxContext->TransferBuffer = NULL; - } - - if (NULL != pRxContext->pUrb) { - RTUSB_UNLINK_URB(pRxContext->pUrb); - RTUSB_FREE_URB(pRxContext->pUrb); - pRxContext->pUrb = NULL; - } - } - - return Status; -} - -/* -======================================================================== -Routine Description: - Initialize transmit data structures. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_RESOURCES - -Note: -======================================================================== -*/ -int NICInitTransmit(struct rt_rtmp_adapter *pAd) -{ -#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \ - Context->pUrb = RTUSB_ALLOC_URB(0); \ - if (Context->pUrb == NULL) { \ - DBGPRINT(RT_DEBUG_ERROR, msg1); \ - Status = NDIS_STATUS_RESOURCES; \ - goto err1; } \ - \ - Context->TransferBuffer = \ - (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \ - if (Context->TransferBuffer == NULL) { \ - DBGPRINT(RT_DEBUG_ERROR, msg2); \ - Status = NDIS_STATUS_RESOURCES; \ - goto err2; } - -#define LM_URB_FREE(pObj, Context, BufferSize) \ - if (NULL != Context->pUrb) { \ - RTUSB_UNLINK_URB(Context->pUrb); \ - RTUSB_FREE_URB(Context->pUrb); \ - Context->pUrb = NULL; } \ - if (NULL != Context->TransferBuffer) { \ - RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ - Context->TransferBuffer, \ - Context->data_dma); \ - Context->TransferBuffer = NULL; } - - u8 i, acidx; - int Status = NDIS_STATUS_SUCCESS; - struct rt_tx_context *pNullContext = &(pAd->NullContext); - struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext); - struct rt_tx_context *pRTSContext = &(pAd->RTSContext); - struct rt_tx_context *pMLMEContext = NULL; -/* struct rt_ht_tx_context *pHTTXContext = NULL; */ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - void *RingBaseVa; -/* struct rt_rtmp_tx_ring *pTxRing; */ - struct rt_rtmp_mgmt_ring *pMgmtRing; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); - pObj = pObj; - - /* Init 4 set of Tx parameters */ - for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) { - /* Initialize all Transmit releated queues */ - InitializeQueueHeader(&pAd->TxSwQueue[acidx]); - - /* Next Local tx ring pointer waiting for buck out */ - pAd->NextBulkOutIndex[acidx] = acidx; - pAd->BulkOutPending[acidx] = FALSE; /* Buck Out control flag */ - /*pAd->DataBulkDoneIdx[acidx] = 0; */ - } - - /*pAd->NextMLMEIndex = 0; */ - /*pAd->PushMgmtIndex = 0; */ - /*pAd->PopMgmtIndex = 0; */ - /*InterlockedExchange(&pAd->MgmtQueueSize, 0); */ - /*InterlockedExchange(&pAd->TxCount, 0); */ - - /*pAd->PrioRingFirstIndex = 0; */ - /*pAd->PrioRingTxCnt = 0; */ - - do { - /* */ - /* TX_RING_SIZE, 4 ACs */ - /* */ - for (acidx = 0; acidx < 4; acidx++) { - struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]); - - NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context)); - /*Allocate URB */ - LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *, - sizeof(struct rt_httx_buffer), Status, - ("<-- ERROR in Alloc TX TxContext[%d] urb!\n", - acidx), done, - ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n", - acidx), out1); - - NdisZeroMemory(pHTTXContext->TransferBuffer-> - Aggregation, 4); - pHTTXContext->pAd = pAd; - pHTTXContext->pIrp = NULL; - pHTTXContext->IRPPending = FALSE; - pHTTXContext->NextBulkOutPosition = 0; - pHTTXContext->ENextBulkOutPosition = 0; - pHTTXContext->CurWritePosition = 0; - pHTTXContext->CurWriteRealPos = 0; - pHTTXContext->BulkOutSize = 0; - pHTTXContext->BulkOutPipeId = acidx; - pHTTXContext->bRingEmpty = TRUE; - pHTTXContext->bCopySavePad = FALSE; - pAd->BulkOutPending[acidx] = FALSE; - } - - /* */ - /* MGMT_RING_SIZE */ - /* */ - - /* Allocate MGMT ring descriptor's memory */ - pAd->MgmtDescRing.AllocSize = - MGMT_RING_SIZE * sizeof(struct rt_tx_context); - os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa), - pAd->MgmtDescRing.AllocSize); - if (pAd->MgmtDescRing.AllocVa == NULL) { - DBGPRINT_ERR("Failed to allocate a big buffer for MgmtDescRing!\n"); - Status = NDIS_STATUS_RESOURCES; - goto out1; - } - NdisZeroMemory(pAd->MgmtDescRing.AllocVa, - pAd->MgmtDescRing.AllocSize); - RingBaseVa = pAd->MgmtDescRing.AllocVa; - - /* Initialize MGMT Ring and associated buffer memory */ - pMgmtRing = &pAd->MgmtRing; - for (i = 0; i < MGMT_RING_SIZE; i++) { - /* link the pre-allocated Mgmt buffer to MgmtRing.Cell */ - pMgmtRing->Cell[i].AllocSize = sizeof(struct rt_tx_context); - pMgmtRing->Cell[i].AllocVa = RingBaseVa; - pMgmtRing->Cell[i].pNdisPacket = NULL; - pMgmtRing->Cell[i].pNextNdisPacket = NULL; - - /*Allocate URB for MLMEContext */ - pMLMEContext = - (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; - pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); - if (pMLMEContext->pUrb == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("<-- ERROR in Alloc TX MLMEContext[%d] urb!\n", - i)); - Status = NDIS_STATUS_RESOURCES; - goto out2; - } - pMLMEContext->pAd = pAd; - pMLMEContext->pIrp = NULL; - pMLMEContext->TransferBuffer = NULL; - pMLMEContext->InUse = FALSE; - pMLMEContext->IRPPending = FALSE; - pMLMEContext->bWaitingBulkOut = FALSE; - pMLMEContext->BulkOutSize = 0; - pMLMEContext->SelfIdx = i; - - /* Offset to next ring descriptor address */ - RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context); - } - DBGPRINT(RT_DEBUG_TRACE, - ("MGMT Ring: total %d entry allocated\n", i)); - - /*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); */ - pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; - pAd->MgmtRing.TxCpuIdx = 0; - pAd->MgmtRing.TxDmaIdx = 0; - - /* */ - /* BEACON_RING_SIZE */ - /* */ - for (i = 0; i < BEACON_RING_SIZE; i++) /* 2 */ - { - struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]); - - NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context)); - - /*Allocate URB */ - LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *, - sizeof(struct rt_tx_buffer), Status, - ("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n", - i), out2, - ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n", - i), out3); - - pBeaconContext->pAd = pAd; - pBeaconContext->pIrp = NULL; - pBeaconContext->InUse = FALSE; - pBeaconContext->IRPPending = FALSE; - } - - /* */ - /* NullContext */ - /* */ - NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context)); - - /*Allocate URB */ - LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer), - Status, - ("<-- ERROR in Alloc TX NullContext urb!\n"), - out3, - ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"), - out4); - - pNullContext->pAd = pAd; - pNullContext->pIrp = NULL; - pNullContext->InUse = FALSE; - pNullContext->IRPPending = FALSE; - - /* */ - /* RTSContext */ - /* */ - NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context)); - - /*Allocate URB */ - LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer), - Status, - ("<-- ERROR in Alloc TX RTSContext urb!\n"), - out4, - ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"), - out5); - - pRTSContext->pAd = pAd; - pRTSContext->pIrp = NULL; - pRTSContext->InUse = FALSE; - pRTSContext->IRPPending = FALSE; - - /* */ - /* PsPollContext */ - /* */ - /*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */ - /*Allocate URB */ - LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *, - sizeof(struct rt_tx_buffer), Status, - ("<-- ERROR in Alloc TX PsPollContext urb!\n"), - out5, - ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"), - out6); - - pPsPollContext->pAd = pAd; - pPsPollContext->pIrp = NULL; - pPsPollContext->InUse = FALSE; - pPsPollContext->IRPPending = FALSE; - pPsPollContext->bAggregatible = FALSE; - pPsPollContext->LastOne = TRUE; - - } while (FALSE); - -done: - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status)); - - return Status; - - /* --------------------------- ERROR HANDLE --------------------------- */ -out6: - LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer)); - -out5: - LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer)); - -out4: - LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer)); - -out3: - for (i = 0; i < BEACON_RING_SIZE; i++) { - struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]); - if (pBeaconContext) - LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer)); - } - -out2: - if (pAd->MgmtDescRing.AllocVa) { - pMgmtRing = &pAd->MgmtRing; - for (i = 0; i < MGMT_RING_SIZE; i++) { - pMLMEContext = - (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; - if (pMLMEContext) - LM_URB_FREE(pObj, pMLMEContext, - sizeof(struct rt_tx_buffer)); - } - os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); - pAd->MgmtDescRing.AllocVa = NULL; - } - -out1: - for (acidx = 0; acidx < 4; acidx++) { - struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]); - if (pTxContext) - LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer)); - } - - /* Here we didn't have any pre-allocated memory need to free. */ - - return Status; -} - -/* -======================================================================== -Routine Description: - Allocate DMA memory blocks for send, receive. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - -Note: -======================================================================== -*/ -int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) -{ -/* struct rt_counter_802_11 pCounter = &pAd->WlanCounters; */ - int Status; - int num; - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); - - do { - /* Init the struct rt_cmdq and CmdQLock */ - NdisAllocateSpinLock(&pAd->CmdQLock); - NdisAcquireSpinLock(&pAd->CmdQLock); - RTUSBInitializeCmdQ(&pAd->CmdQ); - NdisReleaseSpinLock(&pAd->CmdQLock); - - NdisAllocateSpinLock(&pAd->MLMEBulkOutLock); - /*NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); */ - NdisAllocateSpinLock(&pAd->BulkOutLock[0]); - NdisAllocateSpinLock(&pAd->BulkOutLock[1]); - NdisAllocateSpinLock(&pAd->BulkOutLock[2]); - NdisAllocateSpinLock(&pAd->BulkOutLock[3]); - NdisAllocateSpinLock(&pAd->BulkOutLock[4]); - NdisAllocateSpinLock(&pAd->BulkOutLock[5]); - NdisAllocateSpinLock(&pAd->BulkInLock); - - for (num = 0; num < NUM_OF_TX_RING; num++) { - NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]); - } - -/* NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX */ - -/* NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */ -/* NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */ - -/* for(num=0; numBATable.BARecEntry[num].RxReRingLock); */ -/* } */ - - /* */ - /* Init Mac Table */ - /* */ -/* MacTableInitialize(pAd); */ - - /* */ - /* Init send data structures and related parameters */ - /* */ - Status = NICInitTransmit(pAd); - if (Status != NDIS_STATUS_SUCCESS) - break; - - /* */ - /* Init receive data structures and related parameters */ - /* */ - Status = NICInitRecv(pAd); - if (Status != NDIS_STATUS_SUCCESS) - break; - - pAd->PendingIoCount = 1; - - } while (FALSE); - - NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame)); - pAd->FragFrame.pFragPacket = - RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); - - if (pAd->FragFrame.pFragPacket == NULL) { - Status = NDIS_STATUS_RESOURCES; - } - - DBGPRINT_S(Status, - ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); - return Status; -} - -/* -======================================================================== -Routine Description: - Calls USB_InterfaceStop and frees memory allocated for the URBs - calls NdisMDeregisterDevice and frees the memory - allocated in VNetInitialize for the Adapter Object - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd) -{ -#define LM_URB_FREE(pObj, Context, BufferSize) \ - if (NULL != Context->pUrb) { \ - RTUSB_UNLINK_URB(Context->pUrb); \ - RTUSB_FREE_URB(Context->pUrb); \ - Context->pUrb = NULL; } \ - if (NULL != Context->TransferBuffer) { \ - RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ - Context->TransferBuffer, \ - Context->data_dma); \ - Context->TransferBuffer = NULL; } - - u32 i, acidx; - struct rt_tx_context *pNullContext = &pAd->NullContext; - struct rt_tx_context *pPsPollContext = &pAd->PsPollContext; - struct rt_tx_context *pRTSContext = &pAd->RTSContext; -/* struct rt_ht_tx_context *pHTTXContext; */ - /*PRTMP_REORDERBUF pReorderBuf; */ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; -/* struct rt_rtmp_tx_ring *pTxRing; */ - - DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); - pObj = pObj; - - /* Free all resources for the RECEIVE buffer queue. */ - for (i = 0; i < (RX_RING_SIZE); i++) { - struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); - if (pRxContext) - LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE); - } - - /* Free PsPoll frame resource */ - LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer)); - - /* Free NULL frame resource */ - LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer)); - - /* Free RTS frame resource */ - LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer)); - - /* Free beacon frame resource */ - for (i = 0; i < BEACON_RING_SIZE; i++) { - struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]); - if (pBeaconContext) - LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer)); - } - - /* Free mgmt frame resource */ - for (i = 0; i < MGMT_RING_SIZE; i++) { - struct rt_tx_context *pMLMEContext = - (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; - /*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_tx_buffer)); */ - if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) { - RTMPFreeNdisPacket(pAd, - pAd->MgmtRing.Cell[i].pNdisPacket); - pAd->MgmtRing.Cell[i].pNdisPacket = NULL; - pMLMEContext->TransferBuffer = NULL; - } - - if (pMLMEContext) { - if (NULL != pMLMEContext->pUrb) { - RTUSB_UNLINK_URB(pMLMEContext->pUrb); - RTUSB_FREE_URB(pMLMEContext->pUrb); - pMLMEContext->pUrb = NULL; - } - } - } - if (pAd->MgmtDescRing.AllocVa) - os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); - - /* Free Tx frame resource */ - for (acidx = 0; acidx < 4; acidx++) { - struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]); - if (pHTTXContext) - LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer)); - } - - if (pAd->FragFrame.pFragPacket) - RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, - NDIS_STATUS_SUCCESS); - - for (i = 0; i < 6; i++) { - NdisFreeSpinLock(&pAd->BulkOutLock[i]); - } - - NdisFreeSpinLock(&pAd->BulkInLock); - NdisFreeSpinLock(&pAd->MLMEBulkOutLock); - - NdisFreeSpinLock(&pAd->CmdQLock); - /* Clear all pending bulk-out request flags. */ - RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); - -/* NdisFreeSpinLock(&pAd->MacTabLock); */ - -/* for(i=0; iBATable.BARecEntry[i].RxReRingLock); */ -/* } */ - - DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n")); -} - -/* -======================================================================== -Routine Description: - Write WLAN MAC address to USB 2870. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - -Note: -======================================================================== -*/ -int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd) -{ - MAC_DW0_STRUC StaMacReg0; - MAC_DW1_STRUC StaMacReg1; - int Status = NDIS_STATUS_SUCCESS; - LARGE_INTEGER NOW; - - /* initialize the random number generator */ - RTMP_GetCurrentSystemTime(&NOW); - - if (pAd->bLocalAdminMAC != TRUE) { - pAd->CurrentAddress[0] = pAd->PermanentAddress[0]; - pAd->CurrentAddress[1] = pAd->PermanentAddress[1]; - pAd->CurrentAddress[2] = pAd->PermanentAddress[2]; - pAd->CurrentAddress[3] = pAd->PermanentAddress[3]; - pAd->CurrentAddress[4] = pAd->PermanentAddress[4]; - pAd->CurrentAddress[5] = pAd->PermanentAddress[5]; - } - /* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC */ - StaMacReg0.field.Byte0 = pAd->CurrentAddress[0]; - StaMacReg0.field.Byte1 = pAd->CurrentAddress[1]; - StaMacReg0.field.Byte2 = pAd->CurrentAddress[2]; - StaMacReg0.field.Byte3 = pAd->CurrentAddress[3]; - StaMacReg1.field.Byte4 = pAd->CurrentAddress[4]; - StaMacReg1.field.Byte5 = pAd->CurrentAddress[5]; - StaMacReg1.field.U2MeMask = 0xff; - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("Local MAC = %pM\n", pAd->CurrentAddress)); - - RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word); - RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word); - return Status; -} - -/* -======================================================================== -Routine Description: - Disable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RT28XXDMADisable(struct rt_rtmp_adapter *pAd) -{ - /* no use */ -} - -/* -======================================================================== -Routine Description: - Enable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - USB_DMA_CFG_STRUC UsbCfg; - int i = 0; - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); - do { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) - && (GloCfg.field.RxDMABusy == 0)) - break; - - DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); - RTMPusecDelay(1000); - i++; - } while (i < 200); - - RTMPusecDelay(50); - GloCfg.field.EnTXWriteBackDDONE = 1; - GloCfg.field.EnableRxDMA = 1; - GloCfg.field.EnableTxDMA = 1; - DBGPRINT(RT_DEBUG_TRACE, - ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - - UsbCfg.word = 0; - UsbCfg.field.phyclear = 0; - /* usb version is 1.1,do not use bulk in aggregation */ - if (pAd->BulkInMaxPacketSize == 512) - UsbCfg.field.RxBulkAggEn = 1; - /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */ - UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3; - UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */ - UsbCfg.field.RxBulkEn = 1; - UsbCfg.field.TxBulkEn = 1; - - RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word); - -} - -/******************************************************************** - * - * 2870 Beacon Update Related functions. - * - ********************************************************************/ - -/* -======================================================================== -Routine Description: - Write Beacon buffer to Asic. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd, - int apidx, - unsigned long FrameLen, unsigned long UpdatePos) -{ - u8 *pBeaconFrame = NULL; - u8 *ptr; - u32 i, padding; - struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync; - u32 longValue; -/* u16 shortValue; */ - BOOLEAN bBcnReq = FALSE; - u8 bcn_idx = 0; - - if (pBeaconFrame == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n")); - return; - } - - if (pBeaconSync == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n")); - return; - } - /*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */ - /* ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */ - /* ) */ - if (bBcnReq == FALSE) { - /* when the ra interface is down, do not send its beacon frame */ - /* clear all zero */ - for (i = 0; i < TXWI_SIZE; i += 4) { - RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, - 0x00); - } - pBeaconSync->BeaconBitMap &= - (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); - NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE); - } else { - ptr = (u8 *)& pAd->BeaconTxWI; - if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) { /* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */ - pBeaconSync->BeaconBitMap &= - (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); - NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], - &pAd->BeaconTxWI, TXWI_SIZE); - } - - if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != - (1 << bcn_idx)) { - for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */ - { - longValue = - *ptr + (*(ptr + 1) << 8) + - (*(ptr + 2) << 16) + (*(ptr + 3) << 24); - RTMP_IO_WRITE32(pAd, - pAd->BeaconOffset[bcn_idx] + i, - longValue); - ptr += 4; - } - } - - ptr = pBeaconSync->BeaconBuf[bcn_idx]; - padding = (FrameLen & 0x01); - NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding); - FrameLen += padding; - for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) { - if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) { - NdisMoveMemory(ptr, pBeaconFrame, 2); - /*shortValue = *ptr + (*(ptr+1)<<8); */ - /*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */ - RTUSBMultiWrite(pAd, - pAd->BeaconOffset[bcn_idx] + - TXWI_SIZE + i, ptr, 2); - } - ptr += 2; - pBeaconFrame += 2; - } - - pBeaconSync->BeaconBitMap |= (1 << bcn_idx); - - /* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */ - } - -} - -void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd) -{ - struct rt_beacon_sync *pBeaconSync; - int i, offset; - BOOLEAN Cancelled = TRUE; - - pBeaconSync = pAd->CommonCfg.pBeaconSync; - if (pBeaconSync && pBeaconSync->EnableBeacon) { - int NumOfBcn; - - { - NumOfBcn = MAX_MESH_NUM; - } - - RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); - - for (i = 0; i < NumOfBcn; i++) { - NdisZeroMemory(pBeaconSync->BeaconBuf[i], - HW_BEACON_OFFSET); - NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); - - for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4) - RTMP_IO_WRITE32(pAd, - pAd->BeaconOffset[i] + offset, - 0x00); - - pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; - pBeaconSync->TimIELocationInBeacon[i] = 0; - } - pBeaconSync->BeaconBitMap = 0; - pBeaconSync->DtimBitOn = 0; - } -} - -void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd) -{ - int apidx; - struct rt_beacon_sync *pBeaconSync; -/* LARGE_INTEGER tsfTime, deltaTime; */ - - pBeaconSync = pAd->CommonCfg.pBeaconSync; - if (pBeaconSync && pBeaconSync->EnableBeacon) { - int NumOfBcn; - - { - NumOfBcn = MAX_MESH_NUM; - } - - for (apidx = 0; apidx < NumOfBcn; apidx++) { - u8 CapabilityInfoLocationInBeacon = 0; - u8 TimIELocationInBeacon = 0; - - NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], - HW_BEACON_OFFSET); - pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = - CapabilityInfoLocationInBeacon; - pBeaconSync->TimIELocationInBeacon[apidx] = - TimIELocationInBeacon; - NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], - TXWI_SIZE); - } - pBeaconSync->BeaconBitMap = 0; - pBeaconSync->DtimBitOn = 0; - pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE; - - pAd->CommonCfg.BeaconAdjust = 0; - pAd->CommonCfg.BeaconFactor = - 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10); - pAd->CommonCfg.BeaconRemain = - (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1; - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", - pAd->CommonCfg.BeaconFactor, - pAd->CommonCfg.BeaconRemain)); - RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, - 10 /*pAd->CommonCfg.BeaconPeriod */ ); - - } -} - -void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd) -{ - struct rt_beacon_sync *pBeaconSync; - int i; - - os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync), - sizeof(struct rt_beacon_sync)); - /*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */ - if (pAd->CommonCfg.pBeaconSync) { - pBeaconSync = pAd->CommonCfg.pBeaconSync; - NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync)); - for (i = 0; i < HW_BEACON_MAX_COUNT; i++) { - NdisZeroMemory(pBeaconSync->BeaconBuf[i], - HW_BEACON_OFFSET); - pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; - pBeaconSync->TimIELocationInBeacon[i] = 0; - NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); - } - pBeaconSync->BeaconBitMap = 0; - - /*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */ - pBeaconSync->EnableBeacon = TRUE; - } -} - -void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd) -{ - struct rt_beacon_sync *pBeaconSync; - BOOLEAN Cancelled = TRUE; - int i; - - if (pAd->CommonCfg.pBeaconSync) { - pBeaconSync = pAd->CommonCfg.pBeaconSync; - pBeaconSync->EnableBeacon = FALSE; - RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); - pBeaconSync->BeaconBitMap = 0; - - for (i = 0; i < HW_BEACON_MAX_COUNT; i++) { - NdisZeroMemory(pBeaconSync->BeaconBuf[i], - HW_BEACON_OFFSET); - pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; - pBeaconSync->TimIELocationInBeacon[i] = 0; - NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); - } - - os_free_mem(pAd, pAd->CommonCfg.pBeaconSync); - pAd->CommonCfg.pBeaconSync = NULL; - } -} - -/* - ======================================================================== - Routine Description: - For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism - to update the beacon context in each Beacon interval. Here we use a periodical timer - to simulate the TBTT interrupt to handle the beacon context update. - - Arguments: - SystemSpecific1 - Not used. - FunctionContext - Pointer to our Adapter context. - SystemSpecific2 - Not used. - SystemSpecific3 - Not used. - - Return Value: - None - - ======================================================================== -*/ -void BeaconUpdateExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - LARGE_INTEGER tsfTime_a; /*, tsfTime_b, deltaTime_exp, deltaTime_ab; */ - u32 delta, delta2MS, period2US, remain, remain_low, remain_high; -/* BOOLEAN positive; */ - - if (pAd->CommonCfg.IsUpdateBeacon == TRUE) { - ReSyncBeaconTime(pAd); - - } - - RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart); - RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart); - - /*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */ - period2US = (pAd->CommonCfg.BeaconPeriod << 10); - remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart; - remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10); - remain = - (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10); - delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain; - - delta2MS = (delta >> 10); - if (delta2MS > 150) { - pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100; - pAd->CommonCfg.IsUpdateBeacon = FALSE; - } else { - pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10; - pAd->CommonCfg.IsUpdateBeacon = TRUE; - } - -} - -/******************************************************************** - * - * 2870 Radio on/off Related functions. - * - ********************************************************************/ -void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd) -{ - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - - DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n")); - - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - { - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - RTMPusecDelay(10000); - } - /*NICResetFromError(pAd); */ - - /* Enable Tx/Rx */ - RTMPEnableRxTx(pAd); - - if (pChipOps->AsicReverseRfFromSleepMode) - pChipOps->AsicReverseRfFromSleepMode(pAd); - - /* Clear Radio off flag */ - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - RTUSBBulkReceive(pAd); - - /* Set LED */ - RTMPSetLED(pAd, LED_RADIO_ON); -} - -void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - u32 Value, i; - - DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n")); - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - /* Clear PMKID cache. */ - pAd->StaCfg.SavedPMKNum = 0; - RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info))); - - /* Link down first if any association exists */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) { - struct rt_mlme_disassoc_req DisReq; - struct rt_mlme_queue_elem *pMsgElem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - - if (pMsgElem) { - COPY_MAC_ADDR(&DisReq.Addr, - pAd->CommonCfg.Bssid); - DisReq.Reason = REASON_DISASSOC_STA_LEAVING; - - pMsgElem->Machine = ASSOC_STATE_MACHINE; - pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; - pMsgElem->MsgLen = - sizeof(struct rt_mlme_disassoc_req); - NdisMoveMemory(pMsgElem->Msg, &DisReq, - sizeof - (struct rt_mlme_disassoc_req)); - - MlmeDisassocReqAction(pAd, pMsgElem); - kfree(pMsgElem); - - RTMPusecDelay(1000); - } - } - } - /* Set Radio off flag */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - { - /* Link down first if any association exists */ - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) - LinkDown(pAd, FALSE); - RTMPusecDelay(10000); - - /*========================================== */ - /* Clean up old bss table */ - BssTableInit(&pAd->ScanTab); - } - - /* Set LED */ - RTMPSetLED(pAd, LED_RADIO_OFF); - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) { - /* Must using 40MHz. */ - AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); - } else { - /* Must using 20MHz. */ - AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); - } - - /* Disable Tx/Rx DMA */ - RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); /* disable DMA */ - GloCfg.field.EnableTxDMA = 0; - GloCfg.field.EnableRxDMA = 0; - RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); /* abort all TX rings */ - - /* Waiting for DMA idle */ - i = 0; - do { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) - && (GloCfg.field.RxDMABusy == 0)) - break; - - RTMPusecDelay(1000); - } while (i++ < 100); - - /* Disable MAC Tx/Rx */ - RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); - Value &= (0xfffffff3); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); - - { - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); - } -} - -#endif /* RTMP_MAC_USB // */ diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c deleted file mode 100644 index 3bfb4ad00c1a..000000000000 --- a/drivers/staging/rt2860/common/cmm_sanity.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - sanity.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John Chang 2004-09-01 add WMM support -*/ -#include "../rt_config.h" - -extern u8 CISCO_OUI[]; - -extern u8 WPA_OUI[]; -extern u8 RSN_OUI[]; -extern u8 WME_INFO_ELEM[]; -extern u8 WME_PARM_ELEM[]; -extern u8 Ccx2QosInfo[]; -extern u8 RALINK_OUI[]; -extern u8 BROADCOM_OUI[]; -extern u8 WPS_OUI[]; - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, unsigned long MsgLen, u8 *pAddr2) -{ - struct rt_mlme_addba_req *pInfo; - - pInfo = (struct rt_mlme_addba_req *)Msg; - - if ((MsgLen != sizeof(struct rt_mlme_addba_req))) { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeAddBAReqSanity fail - message length not correct.\n")); - return FALSE; - } - - if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n")); - return FALSE; - } - - if ((pInfo->pAddr[0] & 0x01) == 0x01) { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeAddBAReqSanity fail - broadcast address not support BA\n")); - return FALSE; - } - - return TRUE; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen) -{ - struct rt_mlme_delba_req *pInfo; - pInfo = (struct rt_mlme_delba_req *)Msg; - - if ((MsgLen != sizeof(struct rt_mlme_delba_req))) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeDelBAReqSanity fail - message length not correct.\n")); - return FALSE; - } - - if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n")); - return FALSE; - } - - if ((pInfo->TID & 0xf0)) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n")); - return FALSE; - } - - if (NdisEqualMemory - (pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, - MAC_ADDR_LEN) == 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n")); - return FALSE; - } - - return TRUE; -} - -BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, - unsigned long MsgLen, u8 *pAddr2) -{ - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg; - struct rt_frame_addba_req * pAddFrame; - pAddFrame = (struct rt_frame_addba_req *) (pMsg); - if (MsgLen < (sizeof(struct rt_frame_addba_req))) { - DBGPRINT(RT_DEBUG_ERROR, - ("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", - MsgLen)); - return FALSE; - } - /* we support immediate BA. */ - *(u16 *) (&pAddFrame->BaParm) = - cpu2le16(*(u16 *) (&pAddFrame->BaParm)); - pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); - pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word); - - if (pAddFrame->BaParm.BAPolicy != IMMED_BA) { - DBGPRINT(RT_DEBUG_ERROR, - ("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", - pAddFrame->BaParm.BAPolicy)); - DBGPRINT(RT_DEBUG_ERROR, - ("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", - pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, - pAddFrame->BaParm.AMSDUSupported)); - return FALSE; - } - /* we support immediate BA. */ - if (pAddFrame->BaParm.TID & 0xfff0) { - DBGPRINT(RT_DEBUG_ERROR, - ("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", - pAddFrame->BaParm.TID)); - return FALSE; - } - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - return TRUE; -} - -BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, unsigned long MsgLen) -{ - struct rt_frame_addba_rsp * pAddFrame; - - pAddFrame = (struct rt_frame_addba_rsp *) (pMsg); - if (MsgLen < (sizeof(struct rt_frame_addba_rsp))) { - DBGPRINT(RT_DEBUG_ERROR, - ("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", - MsgLen)); - return FALSE; - } - /* we support immediate BA. */ - *(u16 *) (&pAddFrame->BaParm) = - cpu2le16(*(u16 *) (&pAddFrame->BaParm)); - pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode); - pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); - - if (pAddFrame->BaParm.BAPolicy != IMMED_BA) { - DBGPRINT(RT_DEBUG_ERROR, - ("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", - pAddFrame->BaParm.BAPolicy)); - return FALSE; - } - /* we support immediate BA. */ - if (pAddFrame->BaParm.TID & 0xfff0) { - DBGPRINT(RT_DEBUG_ERROR, - ("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", - pAddFrame->BaParm.TID)); - return FALSE; - } - return TRUE; - -} - -BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd, - u8 Wcid, void * pMsg, unsigned long MsgLen) -{ - /*struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *)pMsg; */ - struct rt_frame_delba_req * pDelFrame; - if (MsgLen != (sizeof(struct rt_frame_delba_req))) - return FALSE; - - if (Wcid >= MAX_LEN_OF_MAC_TABLE) - return FALSE; - - pDelFrame = (struct rt_frame_delba_req *) (pMsg); - - *(u16 *) (&pDelFrame->DelbaParm) = - cpu2le16(*(u16 *) (&pDelFrame->DelbaParm)); - pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode); - - if (pDelFrame->DelbaParm.TID & 0xfff0) - return FALSE; - - return TRUE; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen, u8 MsgChannel, u8 *pAddr2, u8 *pBssid, char Ssid[], u8 * pSsidLen, u8 * pBssType, u16 * pBeaconPeriod, u8 * pChannel, u8 * pNewChannel, OUT LARGE_INTEGER * pTimestamp, struct rt_cf_parm * pCfParm, u16 * pAtimWin, u16 * pCapabilityInfo, u8 * pErp, u8 * pDtimCount, u8 * pDtimPeriod, u8 * pBcastFlag, u8 * pMessageToMe, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, u8 * pCkipFlag, u8 * pAironetCellPowerLimit, struct rt_edca_parm *pEdcaParm, struct rt_qbss_load_parm *pQbssLoad, struct rt_qos_capability_parm *pQosCapability, unsigned long * pRalinkIe, u8 * pHtCapabilityLen, u8 * pPreNHtCapabilityLen, struct rt_ht_capability_ie * pHtCapability, u8 * AddHtInfoLen, struct rt_add_ht_info_ie * AddHtInfo, u8 * NewExtChannelOffset, /* Ht extension channel offset(above or below) */ - u16 * LengthVIE, - struct rt_ndis_802_11_variable_ies *pVIE) -{ - u8 *Ptr; - u8 TimLen; - struct rt_frame_802_11 * pFrame; - struct rt_eid * pEid; - u8 SubType; - u8 Sanity; - /*u8 ECWMin, ECWMax; */ - /*MAC_CSR9_STRUC Csr9; */ - unsigned long Length = 0; - - /* For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel */ - /* 1. If the AP is 11n enabled, then check the control channel. */ - /* 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!) */ - u8 CtrlChannel = 0; - - /* Add for 3 necessary EID field check */ - Sanity = 0; - - *pAtimWin = 0; - *pErp = 0; - *pDtimCount = 0; - *pDtimPeriod = 0; - *pBcastFlag = 0; - *pMessageToMe = 0; - *pExtRateLen = 0; - *pCkipFlag = 0; /* Default of CkipFlag is 0 */ - *pAironetCellPowerLimit = 0xFF; /* Default of AironetCellPowerLimit is 0xFF */ - *LengthVIE = 0; /* Set the length of VIE to init value 0 */ - *pHtCapabilityLen = 0; /* Set the length of VIE to init value 0 */ - if (pAd->OpMode == OPMODE_STA) - *pPreNHtCapabilityLen = 0; /* Set the length of VIE to init value 0 */ - *AddHtInfoLen = 0; /* Set the length of VIE to init value 0 */ - *pRalinkIe = 0; - *pNewChannel = 0; - *NewExtChannelOffset = 0xff; /*Default 0xff means no such IE */ - pCfParm->bValid = FALSE; /* default: no IE_CF found */ - pQbssLoad->bValid = FALSE; /* default: no IE_QBSS_LOAD found */ - pEdcaParm->bValid = FALSE; /* default: no IE_EDCA_PARAMETER found */ - pQosCapability->bValid = FALSE; /* default: no IE_QOS_CAPABILITY found */ - - pFrame = (struct rt_frame_802_11 *) Msg; - - /* get subtype from header */ - SubType = (u8)pFrame->Hdr.FC.SubType; - - /* get Addr2 and BSSID from header */ - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3); - - Ptr = pFrame->Octet; - Length += LENGTH_802_11; - - /* get timestamp from payload and advance the pointer */ - NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN); - - pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart); - pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart); - - Ptr += TIMESTAMP_LEN; - Length += TIMESTAMP_LEN; - - /* get beacon interval from payload and advance the pointer */ - NdisMoveMemory(pBeaconPeriod, Ptr, 2); - Ptr += 2; - Length += 2; - - /* get capability info from payload and advance the pointer */ - NdisMoveMemory(pCapabilityInfo, Ptr, 2); - Ptr += 2; - Length += 2; - - if (CAP_IS_ESS_ON(*pCapabilityInfo)) - *pBssType = BSS_INFRA; - else - *pBssType = BSS_ADHOC; - - pEid = (struct rt_eid *) Ptr; - - /* get variable fields from payload and advance the pointer */ - while ((Length + 2 + pEid->Len) <= MsgLen) { - /* */ - /* Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow. */ - /* */ - if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) { - DBGPRINT(RT_DEBUG_WARN, - ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n", - (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN)); - break; - } - - switch (pEid->Eid) { - case IE_SSID: - /* Already has one SSID EID in this beacon, ignore the second one */ - if (Sanity & 0x1) - break; - if (pEid->Len <= MAX_LEN_OF_SSID) { - NdisMoveMemory(Ssid, pEid->Octet, pEid->Len); - *pSsidLen = pEid->Len; - Sanity |= 0x1; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n", - pEid->Len)); - return FALSE; - } - break; - - case IE_SUPP_RATES: - if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { - Sanity |= 0x2; - NdisMoveMemory(SupRate, pEid->Octet, pEid->Len); - *pSupRateLen = pEid->Len; - - /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */ - /* from ScanTab. We should report as is. And filter out unsupported */ - /* rates in MlmeAux. */ - /* Check against the supported rates */ - /* RTMPCheckRates(pAd, SupRate, pSupRateLen); */ - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n", - pEid->Len)); - return FALSE; - } - break; - - case IE_HT_CAP: - if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension! */ - { - NdisMoveMemory(pHtCapability, pEid->Octet, - sizeof(struct rt_ht_capability_ie)); - *pHtCapabilityLen = SIZE_HT_CAP_IE; /* Nnow we only support 26 bytes. */ - - *(u16 *) (&pHtCapability->HtCapInfo) = - cpu2le16(*(u16 *) - (&pHtCapability->HtCapInfo)); - *(u16 *) (&pHtCapability->ExtHtCapInfo) = - cpu2le16(*(u16 *) - (&pHtCapability->ExtHtCapInfo)); - - { - *pPreNHtCapabilityLen = 0; /* Nnow we only support 26 bytes. */ - - Ptr = (u8 *)pVIE; - NdisMoveMemory(Ptr + *LengthVIE, - &pEid->Eid, - pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); - } - } else { - DBGPRINT(RT_DEBUG_WARN, - ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", - pEid->Len)); - } - - break; - case IE_ADD_HT: - if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) { - /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */ - /* copy first sizeof(struct rt_add_ht_info_ie) */ - NdisMoveMemory(AddHtInfo, pEid->Octet, - sizeof(struct rt_add_ht_info_ie)); - *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; - - CtrlChannel = AddHtInfo->ControlChan; - - *(u16 *) (&AddHtInfo->AddHtInfo2) = - cpu2le16(*(u16 *) - (&AddHtInfo->AddHtInfo2)); - *(u16 *) (&AddHtInfo->AddHtInfo3) = - cpu2le16(*(u16 *) - (&AddHtInfo->AddHtInfo3)); - - { - Ptr = (u8 *)pVIE; - NdisMoveMemory(Ptr + *LengthVIE, - &pEid->Eid, - pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); - } - } else { - DBGPRINT(RT_DEBUG_WARN, - ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n")); - } - - break; - case IE_SECONDARY_CH_OFFSET: - if (pEid->Len == 1) { - *NewExtChannelOffset = pEid->Octet[0]; - } else { - DBGPRINT(RT_DEBUG_WARN, - ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); - } - - break; - case IE_FH_PARM: - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n")); - break; - - case IE_DS_PARM: - if (pEid->Len == 1) { - *pChannel = *pEid->Octet; - - { - if (ChannelSanity(pAd, *pChannel) == 0) { - - return FALSE; - } - } - - Sanity |= 0x4; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n", - pEid->Len)); - return FALSE; - } - break; - - case IE_CF_PARM: - if (pEid->Len == 6) { - pCfParm->bValid = TRUE; - pCfParm->CfpCount = pEid->Octet[0]; - pCfParm->CfpPeriod = pEid->Octet[1]; - pCfParm->CfpMaxDuration = - pEid->Octet[2] + 256 * pEid->Octet[3]; - pCfParm->CfpDurRemaining = - pEid->Octet[4] + 256 * pEid->Octet[5]; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n")); - return FALSE; - } - break; - - case IE_IBSS_PARM: - if (pEid->Len == 2) { - NdisMoveMemory(pAtimWin, pEid->Octet, - pEid->Len); - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n")); - return FALSE; - } - break; - - case IE_TIM: - if (INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) { - GetTimBit((char *)pEid, pAd->StaActive.Aid, - &TimLen, pBcastFlag, pDtimCount, - pDtimPeriod, pMessageToMe); - } - break; - case IE_CHANNEL_SWITCH_ANNOUNCEMENT: - if (pEid->Len == 3) { - *pNewChannel = pEid->Octet[1]; /*extract new channel number */ - } - break; - - /* New for WPA */ - /* CCX v2 has the same IE, we need to parse that too */ - /* Wifi WMM use the same IE vale, need to parse that too */ - /* case IE_WPA: */ - case IE_VENDOR_SPECIFIC: - /* Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. */ - /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */ - /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4)) - { - if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30)) - { - { - NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(struct rt_ht_capability_ie)); - *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes. - } - } - if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26)) - { - { - NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(struct rt_add_ht_info_ie)); - *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes. - } - } - } - */ - /* Check the OUI version, filter out non-standard usage */ - if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) - && (pEid->Len == 7)) { - /**pRalinkIe = pEid->Octet[3]; */ - if (pEid->Octet[3] != 0) - *pRalinkIe = pEid->Octet[3]; - else - *pRalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */ - } - /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */ - - /* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, */ - /* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE */ - else if ((*pHtCapabilityLen == 0) - && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, - 3) && (pEid->Len >= 4) - && (pAd->OpMode == OPMODE_STA)) { - if ((pEid->Octet[3] == OUI_PREN_HT_CAP) - && (pEid->Len >= 30) - && (*pHtCapabilityLen == 0)) { - NdisMoveMemory(pHtCapability, - &pEid->Octet[4], - sizeof - (struct rt_ht_capability_ie)); - *pPreNHtCapabilityLen = SIZE_HT_CAP_IE; - } - - if ((pEid->Octet[3] == OUI_PREN_ADD_HT) - && (pEid->Len >= 26)) { - NdisMoveMemory(AddHtInfo, - &pEid->Octet[4], - sizeof(struct rt_add_ht_info_ie)); - *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; - } - } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) { - /* Copy to pVIE which will report to microsoft bssid list. */ - Ptr = (u8 *)pVIE; - NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, - pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); - } else - if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) - && (pEid->Len == 24)) { - u8 *ptr; - int i; - - /* parsing EDCA parameters */ - pEdcaParm->bValid = TRUE; - pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ - pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ - pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ - pEdcaParm->EdcaUpdateCount = - pEid->Octet[6] & 0x0f; - pEdcaParm->bAPSDCapable = - (pEid->Octet[6] & 0x80) ? 1 : 0; - ptr = &pEid->Octet[8]; - for (i = 0; i < 4; i++) { - u8 aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */ - pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */ - pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */ - pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */ - pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */ - pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */ - ptr += 4; /* point to next AC */ - } - } else - if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) - && (pEid->Len == 7)) { - /* parsing EDCA parameters */ - pEdcaParm->bValid = TRUE; - pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ - pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ - pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ - pEdcaParm->EdcaUpdateCount = - pEid->Octet[6] & 0x0f; - pEdcaParm->bAPSDCapable = - (pEid->Octet[6] & 0x80) ? 1 : 0; - - /* use default EDCA parameter */ - pEdcaParm->bACM[QID_AC_BE] = 0; - pEdcaParm->Aifsn[QID_AC_BE] = 3; - pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS; - pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS; - pEdcaParm->Txop[QID_AC_BE] = 0; - - pEdcaParm->bACM[QID_AC_BK] = 0; - pEdcaParm->Aifsn[QID_AC_BK] = 7; - pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS; - pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS; - pEdcaParm->Txop[QID_AC_BK] = 0; - - pEdcaParm->bACM[QID_AC_VI] = 0; - pEdcaParm->Aifsn[QID_AC_VI] = 2; - pEdcaParm->Cwmin[QID_AC_VI] = - CW_MIN_IN_BITS - 1; - pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS; - pEdcaParm->Txop[QID_AC_VI] = 96; /* AC_VI: 96*32us ~= 3ms */ - - pEdcaParm->bACM[QID_AC_VO] = 0; - pEdcaParm->Aifsn[QID_AC_VO] = 2; - pEdcaParm->Cwmin[QID_AC_VO] = - CW_MIN_IN_BITS - 2; - pEdcaParm->Cwmax[QID_AC_VO] = - CW_MAX_IN_BITS - 1; - pEdcaParm->Txop[QID_AC_VO] = 48; /* AC_VO: 48*32us ~= 1.5ms */ - } - - break; - - case IE_EXT_SUPP_RATES: - if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { - NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); - *pExtRateLen = pEid->Len; - - /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */ - /* from ScanTab. We should report as is. And filter out unsupported */ - /* rates in MlmeAux. */ - /* Check against the supported rates */ - /* RTMPCheckRates(pAd, ExtRate, pExtRateLen); */ - } - break; - - case IE_ERP: - if (pEid->Len == 1) { - *pErp = (u8)pEid->Octet[0]; - } - break; - - case IE_AIRONET_CKIP: - /* 0. Check Aironet IE length, it must be larger or equal to 28 */ - /* Cisco AP350 used length as 28 */ - /* Cisco AP12XX used length as 30 */ - if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2)) - break; - - /* 1. Copy CKIP flag byte to buffer for process */ - *pCkipFlag = *(pEid->Octet + 8); - break; - - case IE_AP_TX_POWER: - /* AP Control of Client Transmit Power */ - /*0. Check Aironet IE length, it must be 6 */ - if (pEid->Len != 0x06) - break; - - /* Get cell power limit in dBm */ - if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1) - *pAironetCellPowerLimit = *(pEid->Octet + 4); - break; - - /* WPA2 & 802.11i RSN */ - case IE_RSN: - /* There is no OUI for version anymore, check the group cipher OUI before copying */ - if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) { - /* Copy to pVIE which will report to microsoft bssid list. */ - Ptr = (u8 *)pVIE; - NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, - pEid->Len + 2); - *LengthVIE += (pEid->Len + 2); - } - break; - - default: - break; - } - - Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len] */ - pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len); - } - - /* For some 11a AP. it did not have the channel EID, patch here */ - { - u8 LatchRfChannel = MsgChannel; - if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) { - if (CtrlChannel != 0) - *pChannel = CtrlChannel; - else - *pChannel = LatchRfChannel; - Sanity |= 0x4; - } - } - - if (Sanity != 0x7) { - DBGPRINT(RT_DEBUG_LOUD, - ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", - Sanity)); - return FALSE; - } else { - return TRUE; - } - -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== - */ -BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 * pBssType, - char Ssid[], - u8 * pSsidLen, u8 * pScanType) -{ - struct rt_mlme_scan_req *Info; - - Info = (struct rt_mlme_scan_req *)(Msg); - *pBssType = Info->BssType; - *pSsidLen = Info->SsidLen; - NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen); - *pScanType = Info->ScanType; - - if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC - || *pBssType == BSS_ANY) - && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE)) { - return TRUE; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeScanReqSanity fail - wrong BssType or ScanType\n")); - return FALSE; - } -} - -/* IRQL = DISPATCH_LEVEL */ -u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel) -{ - int i; - - for (i = 0; i < pAd->ChannelListNum; i++) { - if (channel == pAd->ChannelList[i].Channel) - return 1; - } - return 0; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 *pAddr2, u16 * pReason) -{ - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - NdisMoveMemory(pReason, &pFrame->Octet[0], 2); - - return TRUE; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 *pAddr, - u16 * pAlg, - u16 * pSeq, - u16 * pStatus, char * pChlgText) -{ - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - - COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2); - NdisMoveMemory(pAlg, &pFrame->Octet[0], 2); - NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); - NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); - - if (*pAlg == AUTH_MODE_OPEN) { - if (*pSeq == 1 || *pSeq == 2) { - return TRUE; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAuthSanity fail - wrong Seg#\n")); - return FALSE; - } - } else if (*pAlg == AUTH_MODE_KEY) { - if (*pSeq == 1 || *pSeq == 4) { - return TRUE; - } else if (*pSeq == 2 || *pSeq == 3) { - NdisMoveMemory(pChlgText, &pFrame->Octet[8], - CIPHER_TEXT_LEN); - return TRUE; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAuthSanity fail - wrong Seg#\n")); - return FALSE; - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAuthSanity fail - wrong algorithm\n")); - return FALSE; - } -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== - */ -BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 *pAddr, - unsigned long * pTimeout, u16 * pAlg) -{ - struct rt_mlme_auth_req *pInfo; - - pInfo = (struct rt_mlme_auth_req *)Msg; - COPY_MAC_ADDR(pAddr, pInfo->Addr); - *pTimeout = pInfo->Timeout; - *pAlg = pInfo->Alg; - - if (((*pAlg == AUTH_MODE_KEY) || (*pAlg == AUTH_MODE_OPEN) - ) && ((*pAddr & 0x01) == 0)) { - return TRUE; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeAuthReqSanity fail - wrong algorithm\n")); - return FALSE; - } -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 *pApAddr, - u16 * pCapabilityInfo, - unsigned long * pTimeout, u16 * pListenIntv) -{ - struct rt_mlme_assoc_req *pInfo; - - pInfo = (struct rt_mlme_assoc_req *)Msg; - *pTimeout = pInfo->Timeout; /* timeout */ - COPY_MAC_ADDR(pApAddr, pInfo->Addr); /* AP address */ - *pCapabilityInfo = pInfo->CapabilityInfo; /* capability info */ - *pListenIntv = pInfo->ListenIntv; - - return TRUE; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 *pAddr2, u16 * pReason) -{ - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - NdisMoveMemory(pReason, &pFrame->Octet[0], 2); - - return TRUE; -} - -/* - ======================================================================== - Routine Description: - Sanity check NetworkType (11b, 11g or 11a) - - Arguments: - pBss - Pointer to BSS table. - - Return Value: - Ndis802_11DS .......(11b) - Ndis802_11OFDM24....(11g) - Ndis802_11OFDM5.....(11a) - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss) -{ - NDIS_802_11_NETWORK_TYPE NetWorkType; - u8 rate, i; - - NetWorkType = Ndis802_11DS; - - if (pBss->Channel <= 14) { - /* */ - /* First check support Rate. */ - /* */ - for (i = 0; i < pBss->SupRateLen; i++) { - rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit */ - if ((rate == 2) || (rate == 4) || (rate == 11) - || (rate == 22)) { - continue; - } else { - /* */ - /* Otherwise (even rate > 108) means Ndis802_11OFDM24 */ - /* */ - NetWorkType = Ndis802_11OFDM24; - break; - } - } - - /* */ - /* Second check Extend Rate. */ - /* */ - if (NetWorkType != Ndis802_11OFDM24) { - for (i = 0; i < pBss->ExtRateLen; i++) { - rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit */ - if ((rate == 2) || (rate == 4) || (rate == 11) - || (rate == 22)) { - continue; - } else { - /* */ - /* Otherwise (even rate > 108) means Ndis802_11OFDM24 */ - /* */ - NetWorkType = Ndis802_11OFDM24; - break; - } - } - } - } else { - NetWorkType = Ndis802_11OFDM5; - } - - if (pBss->HtCapabilityLen != 0) { - if (NetWorkType == Ndis802_11OFDM5) - NetWorkType = Ndis802_11OFDM5_N; - else - NetWorkType = Ndis802_11OFDM24_N; - } - - return NetWorkType; -} - -/* - ========================================================================== - Description: - Check the validity of the received EAPoL frame - Return: - TRUE if all parameters are OK, - FALSE otherwise - ========================================================================== - */ -BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd, - struct rt_eapol_packet * pMsg, - unsigned long MsgLen, - u8 MsgType, struct rt_mac_table_entry *pEntry) -{ - u8 mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE]; - BOOLEAN bReplayDiff = FALSE; - BOOLEAN bWPA2 = FALSE; - struct rt_key_info EapolKeyInfo; - u8 GroupKeyIndex = 0; - - NdisZeroMemory(mic, sizeof(mic)); - NdisZeroMemory(digest, sizeof(digest)); - NdisZeroMemory(KEYDATA, sizeof(KEYDATA)); - NdisZeroMemory((u8 *)& EapolKeyInfo, sizeof(EapolKeyInfo)); - - NdisMoveMemory((u8 *)& EapolKeyInfo, - (u8 *)& pMsg->KeyDesc.KeyInfo, sizeof(struct rt_key_info)); - - *((u16 *) & EapolKeyInfo) = cpu2le16(*((u16 *) & EapolKeyInfo)); - - /* Choose WPA2 or not */ - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) - || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) - bWPA2 = TRUE; - - /* 0. Check MsgType */ - if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) { - DBGPRINT(RT_DEBUG_ERROR, - ("The message type is invalid(%d)! \n", MsgType)); - return FALSE; - } - /* 1. Replay counter check */ - if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) /* For supplicant */ - { - /* First validate replay counter, only accept message with larger replay counter. */ - /* Let equal pass, some AP start with all zero replay counter */ - u8 ZeroReplay[LEN_KEY_DESC_REPLAY]; - - NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); - if ((RTMPCompareMemory - (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, - LEN_KEY_DESC_REPLAY) != 1) - && - (RTMPCompareMemory - (pMsg->KeyDesc.ReplayCounter, ZeroReplay, - LEN_KEY_DESC_REPLAY) != 0)) { - bReplayDiff = TRUE; - } - } else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) /* For authenticator */ - { - /* check Replay Counter coresponds to MSG from authenticator, otherwise discard */ - if (!NdisEqualMemory - (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, - LEN_KEY_DESC_REPLAY)) { - bReplayDiff = TRUE; - } - } - /* Replay Counter different condition */ - if (bReplayDiff) { - /* send wireless event - for replay counter different */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, - pEntry->Addr, pEntry->apidx, 0); - - if (MsgType < EAPOL_GROUP_MSG_1) { - DBGPRINT(RT_DEBUG_ERROR, - ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", - MsgType)); - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("Replay Counter Different in group msg %d of 2-way handshake!\n", - (MsgType - EAPOL_PAIR_MSG_4))); - } - - hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - hex_dump("Current replay counter ", pEntry->R_Counter, - LEN_KEY_DESC_REPLAY); - return FALSE; - } - /* 2. Verify MIC except Pairwise Msg1 */ - if (MsgType != EAPOL_PAIR_MSG_1) { - u8 rcvd_mic[LEN_KEY_DESC_MIC]; - - /* Record the received MIC for check later */ - NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, - LEN_KEY_DESC_MIC); - NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - - if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP) /* TKIP */ - { - HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg, - MsgLen, mic, MD5_DIGEST_SIZE); - } else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES) /* AES */ - { - HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg, - MsgLen, digest, SHA1_DIGEST_SIZE); - NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); - } - - if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) { - /* send wireless event - for MIC different */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_MIC_DIFF_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - if (MsgType < EAPOL_GROUP_MSG_1) { - DBGPRINT(RT_DEBUG_ERROR, - ("MIC Different in pairwise msg %d of 4-way handshake!\n", - MsgType)); - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("MIC Different in group msg %d of 2-way handshake!\n", - (MsgType - EAPOL_PAIR_MSG_4))); - } - - hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC); - hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC); - - return FALSE; - } - } - /* 1. Decrypt the Key Data field if GTK is included. */ - /* 2. Extract the context of the Key Data field if it exist. */ - /* The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear. */ - /* The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. */ - if (CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyDataLen) > 0) { - /* Decrypt this field */ - if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) - || (MsgType == EAPOL_GROUP_MSG_1)) { - if ((EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)) { - /* AES */ - AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, - CONV_ARRARY_TO_u16(pMsg-> - KeyDesc. - KeyDataLen), - pMsg->KeyDesc.KeyData); - } else { - int i; - u8 Key[32]; - /* Decrypt TKIP GTK */ - /* Construct 32 bytes RC4 Key */ - NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16); - NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, - 32); - /*discard first 256 bytes */ - for (i = 0; i < 256; i++) - ARCFOUR_BYTE(&pAd->PrivateInfo. - WEPCONTEXT); - /* Decrypt GTK. Becareful, there is no ICV to check the result is correct or not */ - ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, - KEYDATA, pMsg->KeyDesc.KeyData, - CONV_ARRARY_TO_u16(pMsg-> - KeyDesc. - KeyDataLen)); - } - - if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) - GroupKeyIndex = EapolKeyInfo.KeyIndex; - - } else if ((MsgType == EAPOL_PAIR_MSG_2) - || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) { - NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, - CONV_ARRARY_TO_u16(pMsg->KeyDesc. - KeyDataLen)); - } else { - - return TRUE; - } - - /* Parse Key Data field to */ - /* 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) */ - /* 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 */ - /* 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) */ - if (!RTMPParseEapolKeyData(pAd, KEYDATA, - CONV_ARRARY_TO_u16(pMsg->KeyDesc. - KeyDataLen), - GroupKeyIndex, MsgType, bWPA2, - pEntry)) { - return FALSE; - } - } - - return TRUE; - -} diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c deleted file mode 100644 index aefe1b774650..000000000000 --- a/drivers/staging/rt2860/common/cmm_sync.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - cmm_sync.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John Chang 2004-09-01 modified for rt2561/2661 -*/ -#include "../rt_config.h" - -/* 2.4 Ghz channel plan index in the TxPower arrays. */ -#define BG_BAND_REGION_0_START 0 /* 1,2,3,4,5,6,7,8,9,10,11 */ -#define BG_BAND_REGION_0_SIZE 11 -#define BG_BAND_REGION_1_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13 */ -#define BG_BAND_REGION_1_SIZE 13 -#define BG_BAND_REGION_2_START 9 /* 10,11 */ -#define BG_BAND_REGION_2_SIZE 2 -#define BG_BAND_REGION_3_START 9 /* 10,11,12,13 */ -#define BG_BAND_REGION_3_SIZE 4 -#define BG_BAND_REGION_4_START 13 /* 14 */ -#define BG_BAND_REGION_4_SIZE 1 -#define BG_BAND_REGION_5_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */ -#define BG_BAND_REGION_5_SIZE 14 -#define BG_BAND_REGION_6_START 2 /* 3,4,5,6,7,8,9 */ -#define BG_BAND_REGION_6_SIZE 7 -#define BG_BAND_REGION_7_START 4 /* 5,6,7,8,9,10,11,12,13 */ -#define BG_BAND_REGION_7_SIZE 9 -#define BG_BAND_REGION_31_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */ -#define BG_BAND_REGION_31_SIZE 14 - -/* 5 Ghz channel plan index in the TxPower arrays. */ -u8 A_BAND_REGION_0_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 }; -u8 A_BAND_REGION_1_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, -132, 136, 140 }; -u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 }; -u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 }; -u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 }; -u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 }; -u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 }; -u8 A_BAND_REGION_7_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, -132, 136, 140, 149, 153, 157, 161, 165, 169, 173 }; -u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 }; -u8 A_BAND_REGION_9_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, -149, 153, 157, 161, 165 }; -u8 A_BAND_REGION_10_CHANNEL_LIST[] = - { 36, 40, 44, 48, 149, 153, 157, 161, 165 }; -u8 A_BAND_REGION_11_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, -157, 161 }; -u8 A_BAND_REGION_12_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, -132, 136, 140 }; -u8 A_BAND_REGION_13_CHANNEL_LIST[] = - { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, -149, 153, 157, 161 }; -u8 A_BAND_REGION_14_CHANNEL_LIST[] = - { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, -153, 157, 161, 165 }; -u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 }; - -/*BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */ -u8 BaSizeArray[4] = { 8, 16, 32, 64 }; - -/* - ========================================================================== - Description: - Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type, - and 3) PHY-mode user selected. - The outcome is used by driver when doing site survey. - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void BuildChannelList(struct rt_rtmp_adapter *pAd) -{ - u8 i, j, index = 0, num = 0; - u8 *pChannelList = NULL; - - NdisZeroMemory(pAd->ChannelList, - MAX_NUM_OF_CHANNELS * sizeof(struct rt_channel_tx_power)); - - /* if not 11a-only mode, channel list starts from 2.4Ghz band */ - if ((pAd->CommonCfg.PhyMode != PHY_11A) - && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) - && (pAd->CommonCfg.PhyMode != PHY_11N_5G) - ) { - switch (pAd->CommonCfg.CountryRegion & 0x7f) { - case REGION_0_BG_BAND: /* 1 -11 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_0_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_0_SIZE); - index += BG_BAND_REGION_0_SIZE; - break; - case REGION_1_BG_BAND: /* 1 - 13 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_1_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_1_SIZE); - index += BG_BAND_REGION_1_SIZE; - break; - case REGION_2_BG_BAND: /* 10 - 11 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_2_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_2_SIZE); - index += BG_BAND_REGION_2_SIZE; - break; - case REGION_3_BG_BAND: /* 10 - 13 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_3_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_3_SIZE); - index += BG_BAND_REGION_3_SIZE; - break; - case REGION_4_BG_BAND: /* 14 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_4_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_4_SIZE); - index += BG_BAND_REGION_4_SIZE; - break; - case REGION_5_BG_BAND: /* 1 - 14 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_5_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_5_SIZE); - index += BG_BAND_REGION_5_SIZE; - break; - case REGION_6_BG_BAND: /* 3 - 9 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_6_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_6_SIZE); - index += BG_BAND_REGION_6_SIZE; - break; - case REGION_7_BG_BAND: /* 5 - 13 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_7_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_7_SIZE); - index += BG_BAND_REGION_7_SIZE; - break; - case REGION_31_BG_BAND: /* 1 - 14 */ - NdisMoveMemory(&pAd->ChannelList[index], - &pAd->TxPower[BG_BAND_REGION_31_START], - sizeof(struct rt_channel_tx_power) * - BG_BAND_REGION_31_SIZE); - index += BG_BAND_REGION_31_SIZE; - break; - default: /* Error. should never happen */ - break; - } - for (i = 0; i < index; i++) - pAd->ChannelList[i].MaxTxPwr = 20; - } - - if ((pAd->CommonCfg.PhyMode == PHY_11A) - || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) - || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) - || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) - || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) - || (pAd->CommonCfg.PhyMode == PHY_11N_5G) - ) { - switch (pAd->CommonCfg.CountryRegionForABand & 0x7f) { - case REGION_0_A_BAND: - num = - sizeof(A_BAND_REGION_0_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_0_CHANNEL_LIST; - break; - case REGION_1_A_BAND: - num = - sizeof(A_BAND_REGION_1_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_1_CHANNEL_LIST; - break; - case REGION_2_A_BAND: - num = - sizeof(A_BAND_REGION_2_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_2_CHANNEL_LIST; - break; - case REGION_3_A_BAND: - num = - sizeof(A_BAND_REGION_3_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_3_CHANNEL_LIST; - break; - case REGION_4_A_BAND: - num = - sizeof(A_BAND_REGION_4_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_4_CHANNEL_LIST; - break; - case REGION_5_A_BAND: - num = - sizeof(A_BAND_REGION_5_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_5_CHANNEL_LIST; - break; - case REGION_6_A_BAND: - num = - sizeof(A_BAND_REGION_6_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_6_CHANNEL_LIST; - break; - case REGION_7_A_BAND: - num = - sizeof(A_BAND_REGION_7_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_7_CHANNEL_LIST; - break; - case REGION_8_A_BAND: - num = - sizeof(A_BAND_REGION_8_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_8_CHANNEL_LIST; - break; - case REGION_9_A_BAND: - num = - sizeof(A_BAND_REGION_9_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_9_CHANNEL_LIST; - break; - - case REGION_10_A_BAND: - num = - sizeof(A_BAND_REGION_10_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_10_CHANNEL_LIST; - break; - - case REGION_11_A_BAND: - num = - sizeof(A_BAND_REGION_11_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_11_CHANNEL_LIST; - break; - case REGION_12_A_BAND: - num = - sizeof(A_BAND_REGION_12_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_12_CHANNEL_LIST; - break; - case REGION_13_A_BAND: - num = - sizeof(A_BAND_REGION_13_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_13_CHANNEL_LIST; - break; - case REGION_14_A_BAND: - num = - sizeof(A_BAND_REGION_14_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_14_CHANNEL_LIST; - break; - case REGION_15_A_BAND: - num = - sizeof(A_BAND_REGION_15_CHANNEL_LIST) / - sizeof(u8); - pChannelList = A_BAND_REGION_15_CHANNEL_LIST; - break; - default: /* Error. should never happen */ - DBGPRINT(RT_DEBUG_WARN, - ("countryregion=%d not support", - pAd->CommonCfg.CountryRegionForABand)); - break; - } - - if (num != 0) { - u8 RadarCh[15] = - { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, - 128, 132, 136, 140 }; - for (i = 0; i < num; i++) { - for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) { - if (pChannelList[i] == - pAd->TxPower[j].Channel) - NdisMoveMemory(&pAd-> - ChannelList[index - + i], - &pAd->TxPower[j], - sizeof - (struct rt_channel_tx_power)); - } - for (j = 0; j < 15; j++) { - if (pChannelList[i] == RadarCh[j]) - pAd->ChannelList[index + - i].DfsReq = - TRUE; - } - pAd->ChannelList[index + i].MaxTxPwr = 20; - } - index += num; - } - } - - pAd->ChannelListNum = index; - DBGPRINT(RT_DEBUG_TRACE, - ("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n", - pAd->CommonCfg.CountryRegion, - pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, - pAd->CommonCfg.PhyMode, pAd->ChannelListNum)); -#ifdef DBG - for (i = 0; i < pAd->ChannelListNum; i++) { - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", - pAd->ChannelList[i].Channel, - pAd->ChannelList[i].Power, - pAd->ChannelList[i].Power2)); - } -#endif -} - -/* - ========================================================================== - Description: - This routine return the first channel number according to the country - code selection and RF IC selection (signal band or dual band). It is called - whenever driver need to start a site survey of all supported channels. - Return: - ch - the first channel number of current country code setting - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -u8 FirstChannel(struct rt_rtmp_adapter *pAd) -{ - return pAd->ChannelList[0].Channel; -} - -/* - ========================================================================== - Description: - This routine returns the next channel number. This routine is called - during driver need to start a site survey of all supported channels. - Return: - next_channel - the next channel number valid in current country code setting. - Note: - return 0 if no more next channel - ========================================================================== - */ -u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel) -{ - int i; - u8 next_channel = 0; - - for (i = 0; i < (pAd->ChannelListNum - 1); i++) - if (channel == pAd->ChannelList[i].Channel) { - next_channel = pAd->ChannelList[i + 1].Channel; - break; - } - return next_channel; -} - -/* - ========================================================================== - Description: - This routine is for Cisco Compatible Extensions 2.X - Spec31. AP Control of Client Transmit Power - Return: - None - Note: - Required by Aironet dBm(mW) - 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW), - 17dBm(50mw), 20dBm(100mW) - - We supported - 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%), - 14dBm(75%), 15dBm(100%) - - The client station's actual transmit power shall be within +/- 5dB of - the minimum value or next lower value. - ========================================================================== - */ -void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd, - u8 AironetCellPowerLimit) -{ - /*valud 0xFF means that hasn't found power limit information */ - /*from the AP's Beacon/Probe response. */ - if (AironetCellPowerLimit == 0xFF) - return; - - if (AironetCellPowerLimit < 6) /*Used Lowest Power Percentage. */ - pAd->CommonCfg.TxPowerPercentage = 6; - else if (AironetCellPowerLimit < 9) - pAd->CommonCfg.TxPowerPercentage = 10; - else if (AironetCellPowerLimit < 12) - pAd->CommonCfg.TxPowerPercentage = 25; - else if (AironetCellPowerLimit < 14) - pAd->CommonCfg.TxPowerPercentage = 50; - else if (AironetCellPowerLimit < 15) - pAd->CommonCfg.TxPowerPercentage = 75; - else - pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum */ - - if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault) - pAd->CommonCfg.TxPowerPercentage = - pAd->CommonCfg.TxPowerDefault; - -} - -char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber) -{ - u8 RssiOffset, LNAGain; - - /* Rssi equals to zero should be an invalid value */ - if (Rssi == 0) - return -99; - - LNAGain = GET_LNA_GAIN(pAd); - if (pAd->LatchRfRegs.Channel > 14) { - if (RssiNumber == 0) - RssiOffset = pAd->ARssiOffset0; - else if (RssiNumber == 1) - RssiOffset = pAd->ARssiOffset1; - else - RssiOffset = pAd->ARssiOffset2; - } else { - if (RssiNumber == 0) - RssiOffset = pAd->BGRssiOffset0; - else if (RssiNumber == 1) - RssiOffset = pAd->BGRssiOffset1; - else - RssiOffset = pAd->BGRssiOffset2; - } - - return (-12 - RssiOffset - LNAGain - Rssi); -} - -/* - ========================================================================== - Description: - Scan next channel - ========================================================================== - */ -void ScanNextChannel(struct rt_rtmp_adapter *pAd) -{ - struct rt_header_802_11 Hdr80211; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen = 0; - u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0; - u16 Status; - struct rt_header_802_11 * pHdr80211; - u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; - - { - if (MONITOR_ON(pAd)) - return; - } - - if (pAd->MlmeAux.Channel == 0) { - if ((pAd->CommonCfg.BBPCurrentBW == BW_40) - && (INFRA_ON(pAd) - || (pAd->OpMode == OPMODE_AP)) - ) { - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, - FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - BBPValue |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n", - pAd->CommonCfg.CentralChannel, - pAd->ScanTab.BssNr)); - } else { - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n", - pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); - } - - { - /* */ - /* To prevent data lost. */ - /* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */ - /* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */ - /* */ - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) - && (INFRA_ON(pAd))) { - NStatus = - MlmeAllocateMemory(pAd, - (void *)& pOutBuffer); - if (NStatus == NDIS_STATUS_SUCCESS) { - pHdr80211 = (struct rt_header_802_11 *) pOutBuffer; - MgtMacHeaderInit(pAd, pHdr80211, - SUBTYPE_NULL_FUNC, 1, - pAd->CommonCfg.Bssid, - pAd->CommonCfg.Bssid); - pHdr80211->Duration = 0; - pHdr80211->FC.Type = BTYPE_DATA; - pHdr80211->FC.PwrMgmt = - (pAd->StaCfg.Psm == PWR_SAVE); - - /* Send using priority queue */ - MiniportMMRequest(pAd, 0, pOutBuffer, - sizeof - (struct rt_header_802_11)); - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeScanReqAction -- Send PSM Data frame\n")); - MlmeFreeMemory(pAd, pOutBuffer); - RTMPusecDelay(5000); - } - } - - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_SUCCESS; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, - 2, &Status); - } - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - } -#ifdef RTMP_MAC_USB - else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) - && (pAd->OpMode == OPMODE_STA)) { - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE); - } -#endif /* RTMP_MAC_USB // */ - else { - { - /* BBP and RF are not accessible in PS mode, we has to wake them up first */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - AsicForceWakeup(pAd, TRUE); - - /* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */ - if (pAd->StaCfg.Psm == PWR_SAVE) - RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); - } - - AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); - AsicLockChannel(pAd, pAd->MlmeAux.Channel); - - { - if (pAd->MlmeAux.Channel > 14) { - if ((pAd->CommonCfg.bIEEE80211H == 1) - && RadarChannelCheck(pAd, - pAd->MlmeAux. - Channel)) { - ScanType = SCAN_PASSIVE; - ScanTimeIn5gChannel = MIN_CHANNEL_TIME; - } - } - } - - /*Global country domain(ch1-11:active scan, ch12-14 passive scan) */ - if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) - && ((pAd->CommonCfg.CountryRegion & 0x7f) == - REGION_31_BG_BAND)) { - ScanType = SCAN_PASSIVE; - } - /* We need to shorten active scan time in order for WZC connect issue */ - /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */ - if (ScanType == FAST_SCAN_ACTIVE) - RTMPSetTimer(&pAd->MlmeAux.ScanTimer, - FAST_ACTIVE_SCAN_TIME); - else /* must be SCAN_PASSIVE or SCAN_ACTIVE */ - { - if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) - || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) - || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) - ) { - if (pAd->MlmeAux.Channel > 14) - RTMPSetTimer(&pAd->MlmeAux.ScanTimer, - ScanTimeIn5gChannel); - else - RTMPSetTimer(&pAd->MlmeAux.ScanTimer, - MIN_CHANNEL_TIME); - } else - RTMPSetTimer(&pAd->MlmeAux.ScanTimer, - MAX_CHANNEL_TIME); - } - - if ((ScanType == SCAN_ACTIVE) - || (ScanType == FAST_SCAN_ACTIVE) - ) { - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - ScanNextChannel() allocate memory fail\n")); - - { - pAd->Mlme.SyncMachine.CurrState = - SYNC_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, - MLME_CNTL_STATE_MACHINE, - MT2_SCAN_CONF, 2, &Status); - } - - return; - } - /* There is no need to send broadcast probe request if active scan is in effect. */ - if ((ScanType == SCAN_ACTIVE) - || (ScanType == FAST_SCAN_ACTIVE) - ) - SsidLen = pAd->MlmeAux.SsidLen; - else - SsidLen = 0; - - MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, - BROADCAST_ADDR, BROADCAST_ADDR); - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &Hdr80211, 1, - &SsidIe, 1, &SsidLen, SsidLen, - pAd->MlmeAux.Ssid, 1, &SupRateIe, 1, - &pAd->CommonCfg.SupRateLen, - pAd->CommonCfg.SupRateLen, - pAd->CommonCfg.SupRate, END_OF_ARGS); - - if (pAd->CommonCfg.ExtRateLen) { - unsigned long Tmp; - MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, - 1, &ExtRateIe, - 1, &pAd->CommonCfg.ExtRateLen, - pAd->CommonCfg.ExtRateLen, - pAd->CommonCfg.ExtRate, - END_OF_ARGS); - FrameLen += Tmp; - } - - if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { - unsigned long Tmp; - u8 HtLen; - u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 }; - - if (pAd->bBroadComHT == TRUE) { - HtLen = - pAd->MlmeAux.HtCapabilityLen + 4; - - MakeOutgoingFrame(pOutBuffer + FrameLen, - &Tmp, 1, &WpaIe, 1, - &HtLen, 4, - &BROADCOM[0], - pAd->MlmeAux. - HtCapabilityLen, - &pAd->MlmeAux. - HtCapability, - END_OF_ARGS); - } else { - HtLen = pAd->MlmeAux.HtCapabilityLen; - - MakeOutgoingFrame(pOutBuffer + FrameLen, - &Tmp, 1, &HtCapIe, 1, - &HtLen, HtLen, - &pAd->CommonCfg. - HtCapability, - END_OF_ARGS); - } - FrameLen += Tmp; - } - - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - } - /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe response */ - - pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN; - } -} - -void MgtProbReqMacHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, - u8 SubType, - u8 ToDs, u8 *pDA, u8 *pBssid) -{ - NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11)); - - pHdr80211->FC.Type = BTYPE_MGMT; - pHdr80211->FC.SubType = SubType; - if (SubType == SUBTYPE_ACK) - pHdr80211->FC.Type = BTYPE_CNTL; - pHdr80211->FC.ToDs = ToDs; - COPY_MAC_ADDR(pHdr80211->Addr1, pDA); - COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress); - COPY_MAC_ADDR(pHdr80211->Addr3, pBssid); -} diff --git a/drivers/staging/rt2860/common/cmm_tkip.c b/drivers/staging/rt2860/common/cmm_tkip.c deleted file mode 100644 index 4881ef9ba022..000000000000 --- a/drivers/staging/rt2860/common/cmm_tkip.c +++ /dev/null @@ -1,833 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - cmm_tkip.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Wu 02-25-02 Initial -*/ - -#include "../rt_config.h" - -/* Rotation functions on 32 bit values */ -#define ROL32( A, n ) \ - ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) -#define ROR32( A, n ) ROL32( (A), 32-(n) ) - -u32 Tkip_Sbox_Lower[256] = { - 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54, - 0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A, - 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B, - 0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B, - 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F, - 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F, - 0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5, - 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F, - 0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB, - 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97, - 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED, - 0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A, - 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94, - 0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3, - 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04, - 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D, - 0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39, - 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95, - 0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83, - 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76, - 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4, - 0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B, - 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0, - 0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18, - 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51, - 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85, - 0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12, - 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9, - 0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7, - 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A, - 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8, - 0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A -}; - -u32 Tkip_Sbox_Upper[256] = { - 0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91, - 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC, - 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB, - 0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B, - 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83, - 0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A, - 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F, - 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA, - 0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B, - 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13, - 0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6, - 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85, - 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11, - 0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B, - 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1, - 0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF, - 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E, - 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6, - 0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B, - 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD, - 0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8, - 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2, - 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49, - 0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10, - 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97, - 0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F, - 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C, - 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27, - 0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33, - 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5, - 0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0, - 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C -}; - -/* */ -/* Expanded IV for TKIP function. */ -/* */ -struct PACKED rt_tkip_iv { - union PACKED { - struct PACKED { - u8 rc0; - u8 rc1; - u8 rc2; - - union PACKED { - struct PACKED { - u8 Rsvd:5; - u8 ExtIV:1; - u8 KeyID:2; - } field; - u8 Byte; - } CONTROL; - } field; - - unsigned long word; - } IV16; - - unsigned long IV32; -}; - -/* - ======================================================================== - - Routine Description: - Convert from u8[] to unsigned long in a portable way - - Arguments: - pMICKey pointer to MIC Key - - Return Value: - None - - Note: - - ======================================================================== -*/ -unsigned long RTMPTkipGetUInt32(u8 *pMICKey) -{ - unsigned long res = 0; - int i; - - for (i = 0; i < 4; i++) { - res |= (*pMICKey++) << (8 * i); - } - - return res; -} - -/* - ======================================================================== - - Routine Description: - Convert from unsigned long to u8[] in a portable way - - Arguments: - pDst pointer to destination for convert unsigned long to u8[] - val the value for convert - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPTkipPutUInt32(IN u8 *pDst, unsigned long val) -{ - int i; - - for (i = 0; i < 4; i++) { - *pDst++ = (u8)(val & 0xff); - val >>= 8; - } -} - -/* - ======================================================================== - - Routine Description: - Set the MIC Key. - - Arguments: - pAd Pointer to our adapter - pMICKey pointer to MIC Key - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPTkipSetMICKey(struct rt_tkip_key_info *pTkip, u8 *pMICKey) -{ - /* Set the key */ - pTkip->K0 = RTMPTkipGetUInt32(pMICKey); - pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4); - /* and reset the message */ - pTkip->L = pTkip->K0; - pTkip->R = pTkip->K1; - pTkip->nBytesInM = 0; - pTkip->M = 0; -} - -/* - ======================================================================== - - Routine Description: - Calculate the MIC Value. - - Arguments: - pAd Pointer to our adapter - uChar Append this uChar - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar) -{ - /* Append the byte to our word-sized buffer */ - pTkip->M |= (uChar << (8 * pTkip->nBytesInM)); - pTkip->nBytesInM++; - /* Process the word if it is full. */ - if (pTkip->nBytesInM >= 4) { - pTkip->L ^= pTkip->M; - pTkip->R ^= ROL32(pTkip->L, 17); - pTkip->L += pTkip->R; - pTkip->R ^= - ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip-> - L & 0x00ff00ff) << 8); - pTkip->L += pTkip->R; - pTkip->R ^= ROL32(pTkip->L, 3); - pTkip->L += pTkip->R; - pTkip->R ^= ROR32(pTkip->L, 2); - pTkip->L += pTkip->R; - /* Clear the buffer */ - pTkip->M = 0; - pTkip->nBytesInM = 0; - } -} - -/* - ======================================================================== - - Routine Description: - Calculate the MIC Value. - - Arguments: - pAd Pointer to our adapter - pSrc Pointer to source data for Calculate MIC Value - Len Indicate the length of the source data - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes) -{ - /* This is simple */ - while (nBytes > 0) { - RTMPTkipAppendByte(pTkip, *pSrc++); - nBytes--; - } -} - -/* - ======================================================================== - - Routine Description: - Get the MIC Value. - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - the MIC Value is store in pAd->PrivateInfo.MIC - ======================================================================== -*/ -void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip) -{ - /* Append the minimum padding */ - RTMPTkipAppendByte(pTkip, 0x5a); - RTMPTkipAppendByte(pTkip, 0); - RTMPTkipAppendByte(pTkip, 0); - RTMPTkipAppendByte(pTkip, 0); - RTMPTkipAppendByte(pTkip, 0); - /* and then zeroes until the length is a multiple of 4 */ - while (pTkip->nBytesInM != 0) { - RTMPTkipAppendByte(pTkip, 0); - } - /* The appendByte function has already computed the result. */ - RTMPTkipPutUInt32(pTkip->MIC, pTkip->L); - RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R); -} - -/* - ======================================================================== - - Routine Description: - Init Tkip function. - - Arguments: - pAd Pointer to our adapter - pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. - KeyId TK Key ID - pTA Pointer to transmitter address - pMICKey pointer to MIC Key - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd, - u8 *pKey, - u8 KeyId, - u8 *pTA, - u8 *pMICKey, - u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32) -{ - struct rt_tkip_iv tkipIv; - - /* Prepare 8 bytes TKIP encapsulation for MPDU */ - NdisZeroMemory(&tkipIv, sizeof(struct rt_tkip_iv)); - tkipIv.IV16.field.rc0 = *(pTSC + 1); - tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f; - tkipIv.IV16.field.rc2 = *pTSC; - tkipIv.IV16.field.CONTROL.field.ExtIV = 1; /* 0: non-extended IV, 1: an extended IV */ - tkipIv.IV16.field.CONTROL.field.KeyID = KeyId; -/* tkipIv.IV32 = *(unsigned long *)(pTSC + 2); */ - NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); /* Copy IV */ - - *pIV16 = tkipIv.IV16.word; - *pIV32 = tkipIv.IV32; -} - -/* - ======================================================================== - - Routine Description: - Init MIC Value calculation function which include set MIC key & - calculate first 16 bytes (DA + SA + priority + 0) - - Arguments: - pAd Pointer to our adapter - pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. - pDA Pointer to DA address - pSA Pointer to SA address - pMICKey pointer to MIC Key - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd, - u8 *pKey, - u8 *pDA, - u8 *pSA, u8 UserPriority, u8 *pMICKey) -{ - unsigned long Priority = UserPriority; - - /* Init MIC value calculation */ - RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey); - /* DA */ - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN); - /* SA */ - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN); - /* Priority + 3 bytes of 0 */ - RTMPTkipAppend(&pAd->PrivateInfo.Tx, (u8 *)& Priority, 4); -} - -/* - ======================================================================== - - Routine Description: - Compare MIC value of received MSDU - - Arguments: - pAd Pointer to our adapter - pSrc Pointer to the received Plain text data - pDA Pointer to DA address - pSA Pointer to SA address - pMICKey pointer to MIC Key - Len the length of the received plain text data exclude MIC value - - Return Value: - TRUE MIC value matched - FALSE MIC value mismatched - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd, - u8 *pSrc, - u8 *pDA, - u8 *pSA, - u8 *pMICKey, - u8 UserPriority, u32 Len) -{ - u8 OldMic[8]; - unsigned long Priority = UserPriority; - - /* Init MIC value calculation */ - RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey); - /* DA */ - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN); - /* SA */ - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN); - /* Priority + 3 bytes of 0 */ - RTMPTkipAppend(&pAd->PrivateInfo.Rx, (u8 *)& Priority, 4); - - /* Calculate MIC value from plain text data */ - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len); - - /* Get MIC valude from received frame */ - NdisMoveMemory(OldMic, pSrc + Len, 8); - - /* Get MIC value from decrypted plain data */ - RTMPTkipGetMIC(&pAd->PrivateInfo.Rx); - - /* Move MIC value from MSDU, this steps should move to data path. */ - /* Since the MIC value might cross MPDUs. */ - if (!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); /*MIC error. */ - - return (FALSE); - } - return (TRUE); -} - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware transmit function - - Arguments: - pAd Pointer to our adapter - void * Pointer to Ndis Packet for MIC calculation - pEncap Pointer to LLC encap data - LenEncap Total encap length, might be 0 which indicates no encap - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pEncap, - struct rt_cipher_key *pKey, u8 apidx) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - u8 *pSrc; - u8 UserPriority; - u8 vlan_offset = 0; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - UserPriority = RTMP_GET_PACKET_UP(pPacket); - pSrc = pSrcBufVA; - - /* determine if this is a vlan packet */ - if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100) - vlan_offset = 4; - - { - RTMPInitMICEngine(pAd, - pKey->Key, - pSrc, pSrc + 6, UserPriority, pKey->TxMic); - } - - if (pEncap != NULL) { - /* LLC encapsulation */ - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6); - /* Protocol Type */ - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, - 2); - } - SrcBufLen -= (14 + vlan_offset); - pSrc += (14 + vlan_offset); - do { - if (SrcBufLen > 0) { - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen); - } - - break; /* No need handle next packet */ - - } while (TRUE); /* End of copying payload */ - - /* Compute the final MIC Value */ - RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); -} - -/************************************************************/ -/* tkip_sbox() */ -/* Returns a 16 bit value from a 64K entry table. The Table */ -/* is synthesized from two 256 entry byte wide tables. */ -/************************************************************/ - -u32 tkip_sbox(u32 index) -{ - u32 index_low; - u32 index_high; - u32 left, right; - - index_low = (index % 256); - index_high = ((index >> 8) % 256); - - left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256); - right = - Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256); - - return (left ^ right); -} - -u32 rotr1(u32 a) -{ - unsigned int b; - - if ((a & 0x01) == 0x01) { - b = (a >> 1) | 0x8000; - } else { - b = (a >> 1) & 0x7fff; - } - b = b % 65536; - return b; -} - -void RTMPTkipMixKey(u8 * key, u8 * ta, unsigned long pnl, /* Least significant 16 bits of PN */ - unsigned long pnh, /* Most significant 32 bits of PN */ - u8 * rc4key, u32 * p1k) -{ - - u32 tsc0; - u32 tsc1; - u32 tsc2; - - u32 ppk0; - u32 ppk1; - u32 ppk2; - u32 ppk3; - u32 ppk4; - u32 ppk5; - - int i; - int j; - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - /* Phase 1, step 1 */ - p1k[0] = tsc1; - p1k[1] = tsc0; - p1k[2] = (u32)(ta[0] + (ta[1] * 256)); - p1k[3] = (u32)(ta[2] + (ta[3] * 256)); - p1k[4] = (u32)(ta[4] + (ta[5] * 256)); - - /* Phase 1, step 2 */ - for (i = 0; i < 8; i++) { - j = 2 * (i & 1); - p1k[0] = - (p1k[0] + - tkip_sbox((p1k[4] ^ ((256 * key[1 + j]) + key[j])) % - 65536)) % 65536; - p1k[1] = - (p1k[1] + - tkip_sbox((p1k[0] ^ ((256 * key[5 + j]) + key[4 + j])) % - 65536)) % 65536; - p1k[2] = - (p1k[2] + - tkip_sbox((p1k[1] ^ ((256 * key[9 + j]) + key[8 + j])) % - 65536)) % 65536; - p1k[3] = - (p1k[3] + - tkip_sbox((p1k[2] ^ ((256 * key[13 + j]) + key[12 + j])) % - 65536)) % 65536; - p1k[4] = - (p1k[4] + - tkip_sbox((p1k[3] ^ (((256 * key[1 + j]) + key[j]))) % - 65536)) % 65536; - p1k[4] = (p1k[4] + i) % 65536; - } - - /* Phase 2, Step 1 */ - ppk0 = p1k[0]; - ppk1 = p1k[1]; - ppk2 = p1k[2]; - ppk3 = p1k[3]; - ppk4 = p1k[4]; - ppk5 = (p1k[4] + tsc2) % 65536; - - /* Phase2, Step 2 */ - ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256 * key[1]) + key[0])) % 65536); - ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256 * key[3]) + key[2])) % 65536); - ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256 * key[5]) + key[4])) % 65536); - ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256 * key[7]) + key[6])) % 65536); - ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256 * key[9]) + key[8])) % 65536); - ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256 * key[11]) + key[10])) % 65536); - - ppk0 = ppk0 + rotr1(ppk5 ^ ((256 * key[13]) + key[12])); - ppk1 = ppk1 + rotr1(ppk0 ^ ((256 * key[15]) + key[14])); - ppk2 = ppk2 + rotr1(ppk1); - ppk3 = ppk3 + rotr1(ppk2); - ppk4 = ppk4 + rotr1(ppk3); - ppk5 = ppk5 + rotr1(ppk4); - - /* Phase 2, Step 3 */ - /* Phase 2, Step 3 */ - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - rc4key[0] = (tsc2 >> 8) % 256; - rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; - rc4key[2] = tsc2 % 256; - rc4key[3] = ((ppk5 ^ ((256 * key[1]) + key[0])) >> 1) % 256; - - rc4key[4] = ppk0 % 256; - rc4key[5] = (ppk0 >> 8) % 256; - - rc4key[6] = ppk1 % 256; - rc4key[7] = (ppk1 >> 8) % 256; - - rc4key[8] = ppk2 % 256; - rc4key[9] = (ppk2 >> 8) % 256; - - rc4key[10] = ppk3 % 256; - rc4key[11] = (ppk3 >> 8) % 256; - - rc4key[12] = ppk4 % 256; - rc4key[13] = (ppk4 >> 8) % 256; - - rc4key[14] = ppk5 % 256; - rc4key[15] = (ppk5 >> 8) % 256; -} - -/* */ -/* TRUE: Success! */ -/* FALSE: Decrypt Error! */ -/* */ -BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd, - u8 *pData, - unsigned long DataByteCnt, - u8 UserPriority, struct rt_cipher_key *pWpaKey) -{ - u8 KeyID; - u32 HeaderLen; - u8 fc0; - u8 fc1; - u16 fc; - u32 frame_type; - u32 frame_subtype; - u32 from_ds; - u32 to_ds; - int a4_exists; - int qc_exists; - u16 duration; - u16 seq_control; - u16 qos_control; - u8 TA[MAC_ADDR_LEN]; - u8 DA[MAC_ADDR_LEN]; - u8 SA[MAC_ADDR_LEN]; - u8 RC4Key[16]; - u32 p1k[5]; /*for mix_key; */ - unsigned long pnl; /* Least significant 16 bits of PN */ - unsigned long pnh; /* Most significant 32 bits of PN */ - u32 num_blocks; - u32 payload_remainder; - struct rt_arcfourcontext ArcFourContext; - u32 crc32 = 0; - u32 trailfcs = 0; - u8 MIC[8]; - u8 TrailMIC[8]; - - fc0 = *pData; - fc1 = *(pData + 1); - - fc = *((u16 *)pData); - - frame_type = ((fc0 >> 2) & 0x03); - frame_subtype = ((fc0 >> 4) & 0x0f); - - from_ds = (fc1 & 0x2) >> 1; - to_ds = (fc1 & 0x1); - - a4_exists = (from_ds & to_ds); - qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ - (frame_subtype == 0x09) || /* Likely to change. */ - (frame_subtype == 0x0a) || (frame_subtype == 0x0b) - ); - - HeaderLen = 24; - if (a4_exists) - HeaderLen += 6; - - KeyID = *((u8 *)(pData + HeaderLen + 3)); - KeyID = KeyID >> 6; - - if (pWpaKey[KeyID].KeyLen == 0) { - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", - KeyID)); - return FALSE; - } - - duration = *((u16 *)(pData + 2)); - - seq_control = *((u16 *)(pData + 22)); - - if (qc_exists) { - if (a4_exists) { - qos_control = *((u16 *)(pData + 30)); - } else { - qos_control = *((u16 *)(pData + 24)); - } - } - - if (to_ds == 0 && from_ds == 1) { - NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN); - NdisMoveMemory(SA, pData + 16, MAC_ADDR_LEN); - NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN); /*BSSID */ - } else if (to_ds == 0 && from_ds == 0) { - NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN); - NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN); - NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN); - } else if (to_ds == 1 && from_ds == 0) { - NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN); - NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN); - NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN); - } else if (to_ds == 1 && from_ds == 1) { - NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN); - NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN); - NdisMoveMemory(SA, pData + 22, MAC_ADDR_LEN); - } - - num_blocks = (DataByteCnt - 16) / 16; - payload_remainder = (DataByteCnt - 16) % 16; - - pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2); - pnh = *((unsigned long *)(pData + HeaderLen + 4)); - pnh = cpu2le32(pnh); - RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k); - - ARCFOUR_INIT(&ArcFourContext, RC4Key, 16); - - ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, - pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8); - NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4); - crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); /*Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). */ - crc32 ^= 0xffffffff; /* complement */ - - if (crc32 != cpu2le32(trailfcs)) { - DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); /*ICV error. */ - - return (FALSE); - } - - NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8); - RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, - pWpaKey[KeyID].RxMic); - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, - DataByteCnt - HeaderLen - 8 - 12); - RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); - NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8); - - if (!NdisEqualMemory(MIC, TrailMIC, 8)) { - DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); /*MIC error. */ - /*RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630 */ - return (FALSE); - } - /*DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!\n"); */ - return TRUE; -} diff --git a/drivers/staging/rt2860/common/cmm_wep.c b/drivers/staging/rt2860/common/cmm_wep.c deleted file mode 100644 index 76f880cb39b0..000000000000 --- a/drivers/staging/rt2860/common/cmm_wep.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_wep.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Wu 10-28-02 Initial -*/ - -#include "../rt_config.h" - -u32 FCSTAB_32[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -/* -u8 WEPKEY[] = { - //IV - 0x00, 0x11, 0x22, - //WEP KEY - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC - }; - */ - -/* - ======================================================================== - - Routine Description: - Init WEP function. - - Arguments: - pAd Pointer to our adapter - pKey Pointer to the WEP KEY - KeyId WEP Key ID - KeyLen the length of WEP KEY - pDest Pointer to the destination which Encryption data will store in. - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd, - u8 *pKey, - u8 KeyId, u8 KeyLen, IN u8 *pDest) -{ - u32 i; - u8 WEPKEY[] = { - /*IV */ - 0x00, 0x11, 0x22, - /*WEP KEY */ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0xAA, 0xBB, 0xCC - }; - - pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; /*Init crc32. */ - - { - NdisMoveMemory(WEPKEY + 3, pKey, KeyLen); - - for (i = 0; i < 3; i++) - WEPKEY[i] = RandomByte(pAd); /*Call mlme RandomByte() function. */ - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); /*INIT SBOX, KEYLEN+3(IV) */ - - NdisMoveMemory(pDest, WEPKEY, 3); /*Append Init Vector */ - } - *(pDest + 3) = (KeyId << 6); /*Append KEYID */ - -} - -/* - ======================================================================== - - Routine Description: - Encrypt transimitted data - - Arguments: - pAd Pointer to our adapter - pSrc Pointer to the transimitted source data that will be encrypt - pDest Pointer to the destination where entryption data will be store in. - Len Indicate the length of the source data - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPEncryptData(struct rt_rtmp_adapter *pAd, - u8 *pSrc, u8 *pDest, u32 Len) -{ - pAd->PrivateInfo.FCSCRC32 = - RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len); - ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len); -} - -/* - ======================================================================== - - Routine Description: - Decrypt received WEP data - - Arguments: - pAdapter Pointer to our adapter - pSrc Pointer to the received data - Len the length of the received data - - Return Value: - TRUE Decrypt WEP data success - FALSE Decrypt WEP data failed - - Note: - - ======================================================================== -*/ -BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd, - u8 *pData, - unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey) -{ - u32 trailfcs; - u32 crc32; - u8 KeyIdx; - u8 WEPKEY[] = { - /*IV */ - 0x00, 0x11, 0x22, - /*WEP KEY */ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0xAA, 0xBB, 0xCC - }; - u8 *pPayload = (u8 *) pData + LENGTH_802_11; - unsigned long payload_len = DataByteCnt - LENGTH_802_11; - - NdisMoveMemory(WEPKEY, pPayload, 3); /*Get WEP IV */ - - KeyIdx = (*(pPayload + 3) & 0xc0) >> 6; - if (pGroupKey[KeyIdx].KeyLen == 0) - return (FALSE); - - NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, - pGroupKey[KeyIdx].KeyLen); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, - pGroupKey[KeyIdx].KeyLen + 3); - ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, - payload_len - 4); - NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4); - crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); /*Skip last 4 bytes(FCS). */ - crc32 ^= 0xffffffff; /* complement */ - - if (crc32 != cpu2le32(trailfcs)) { - DBGPRINT(RT_DEBUG_TRACE, ("WEP Data CRC Error!\n")); /*CRC error. */ - return (FALSE); - } - return (TRUE); -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Encryption Algorithm "struct rt_arcfour" initialize - - Arguments: - Ctx Pointer to struct rt_arcfour CONTEXT (SBOX) - pKey Pointer to the WEP KEY - KeyLen Indicate the length fo the WEP KEY - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen) -{ - u8 t, u; - u32 keyindex; - u32 stateindex; - u8 *state; - u32 counter; - - state = Ctx->STATE; - Ctx->X = 0; - Ctx->Y = 0; - for (counter = 0; counter < 256; counter++) - state[counter] = (u8)counter; - keyindex = 0; - stateindex = 0; - for (counter = 0; counter < 256; counter++) { - t = state[counter]; - stateindex = (stateindex + pKey[keyindex] + t) & 0xff; - u = state[stateindex]; - state[stateindex] = t; - state[counter] = u; - if (++keyindex >= KeyLen) - keyindex = 0; - } -} - -/* - ======================================================================== - - Routine Description: - Get bytes from struct rt_arcfour CONTEXT (S-BOX) - - Arguments: - Ctx Pointer to struct rt_arcfour CONTEXT (SBOX) - - Return Value: - u8 - the value of the struct rt_arcfour CONTEXT (S-BOX) - - Note: - - ======================================================================== -*/ -u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx) -{ - u32 x; - u32 y; - u8 sx, sy; - u8 *state; - - state = Ctx->STATE; - x = (Ctx->X + 1) & 0xff; - sx = state[x]; - y = (sx + Ctx->Y) & 0xff; - sy = state[y]; - Ctx->X = x; - Ctx->Y = y; - state[y] = sx; - state[x] = sy; - - return (state[(sx + sy) & 0xff]); - -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Decryption Algorithm - - Arguments: - Ctx Pointer to struct rt_arcfour CONTEXT (SBOX) - pDest Pointer to the Destination - pSrc Pointer to the Source data - Len Indicate the length of the Source data - - Return Value: - None - - Note: - - ======================================================================== -*/ -void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx, - u8 *pDest, u8 *pSrc, u32 Len) -{ - u32 i; - - for (i = 0; i < Len; i++) - pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Encryption Algorithm - - Arguments: - Ctx Pointer to struct rt_arcfour CONTEXT (SBOX) - pDest Pointer to the Destination - pSrc Pointer to the Source data - Len Indicate the length of the Source dta - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx, - u8 *pDest, u8 *pSrc, u32 Len) -{ - u32 i; - - for (i = 0; i < Len; i++) - pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK. - - Arguments: - Ctx Pointer to struct rt_arcfour CONTEXT (SBOX) - pDest Pointer to the Destination - pSrc Pointer to the Source data - Len Indicate the length of the Source dta - - ======================================================================== -*/ - -void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx, - u8 *pDest, u8 *pSrc, u32 Len) -{ - u32 i; - /*discard first 256 bytes */ - for (i = 0; i < 256; i++) - ARCFOUR_BYTE(Ctx); - - for (i = 0; i < Len; i++) - pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); -} - -/* - ======================================================================== - - Routine Description: - Calculate a new FCS given the current FCS and the new data. - - Arguments: - Fcs the original FCS value - Cp pointer to the data which will be calculate the FCS - Len the length of the data - - Return Value: - u32 - FCS 32 bits - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len) -{ - while (Len--) - Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]); - - return (Fcs); -} - -/* - ======================================================================== - - Routine Description: - Get last FCS and encrypt it to the destination - - Arguments: - pDest Pointer to the Destination - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest) -{ - pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */ - pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32); - - ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, - (u8 *)& pAd->PrivateInfo.FCSCRC32, 4); -} diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c deleted file mode 100644 index 616ebec50c61..000000000000 --- a/drivers/staging/rt2860/common/cmm_wpa.c +++ /dev/null @@ -1,3010 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - wpa.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Jan Lee 03-07-22 Initial - Paul Lin 03-11-28 Modify for supplicant -*/ -#include "../rt_config.h" -/* WPA OUI */ -u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 }; -u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 }; -u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 }; -u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 }; -u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 }; -u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 }; -u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 }; -u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 }; - -/* WPA2 OUI */ -u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; -u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; - -static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 keyDescVer, - u8 MsgType, - u8 DefaultKeyIdx, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_LEN, struct rt_eapol_packet * pMsg); - -static void CalculateMIC(u8 KeyDescVer, - u8 * PTK, struct rt_eapol_packet * pMsg); - -static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -/* - ========================================================================== - Description: - association state machine init, including state transition and timer init - Parameters: - S - pointer to the association state machine - ========================================================================== - */ -void WpaStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE, - MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK, - WPA_MACHINE_BASE); - - StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, - (STATE_MACHINE_FUNC) WpaEAPPacketAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, - (STATE_MACHINE_FUNC) WpaEAPOLStartAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, - (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, - (STATE_MACHINE_FUNC) WpaEAPOLKeyAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, - (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction); -} - -/* - ========================================================================== - Description: - this is state machine function. - When receiving EAP packets which is for 802.1x authentication use. - Not use in PSK case - Return: - ========================================================================== -*/ -void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -/* - ========================================================================== - Description: - Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c - Return: - ========================================================================== -*/ -void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mac_table_entry *pEntry; - struct rt_header_802_11 * pHeader; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n")); - - pHeader = (struct rt_header_802_11 *) Elem->Msg; - - /*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */ - if (Elem->MsgLen == 6) - pEntry = MacTableLookup(pAd, Elem->Msg); - else { - pEntry = MacTableLookup(pAd, pHeader->Addr2); - } - - if (pEntry) { - DBGPRINT(RT_DEBUG_TRACE, - (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", - pEntry->PortSecured, pEntry->WpaState, - pEntry->AuthMode, pEntry->PMKID_CacheIdx)); - - if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) - && (pEntry->WpaState < AS_PTKSTART) - && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) - || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) - || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) - && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) { - pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; - pEntry->WpaState = AS_INITPSK; - pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; - NdisZeroMemory(pEntry->R_Counter, - sizeof(pEntry->R_Counter)); - pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; - - WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); - } - } -} - -/* - ========================================================================== - Description: - This is state machine function. - When receiving EAPOL packets which is for 802.1x key management. - Use both in WPA, and WPAPSK case. - In this function, further dispatch to different functions according to the received packet. 3 categories are : - 1. normal 4-way pairwisekey and 2-way groupkey handshake - 2. MIC error (Countermeasures attack) report packet from STA. - 3. Request for pairwise/group key update from STA - Return: - ========================================================================== -*/ -void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mac_table_entry *pEntry; - struct rt_header_802_11 * pHeader; - struct rt_eapol_packet * pEapol_packet; - struct rt_key_info peerKeyInfo; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n")); - - pHeader = (struct rt_header_802_11 *) Elem->Msg; - pEapol_packet = - (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo)); - NdisMoveMemory((u8 *)& peerKeyInfo, - (u8 *)& pEapol_packet->KeyDesc.KeyInfo, - sizeof(struct rt_key_info)); - - hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet, - (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H)); - - *((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo)); - - do { - pEntry = MacTableLookup(pAd, pHeader->Addr2); - - if (!pEntry - || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - break; - - if (pEntry->AuthMode < Ndis802_11AuthModeWPA) - break; - - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPoL-Key frame from STA %pMF\n", - pEntry->Addr)); - - if (((pEapol_packet->ProVer != EAPOL_VER) - && (pEapol_packet->ProVer != EAPOL_VER2)) - || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) - && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) { - DBGPRINT(RT_DEBUG_ERROR, - ("Key descripter does not match with WPA rule\n")); - break; - } - /* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */ - /* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */ - if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) - && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) { - DBGPRINT(RT_DEBUG_ERROR, - ("Key descripter version not match(TKIP) \n")); - break; - } - /* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */ - /* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */ - else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) - && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) { - DBGPRINT(RT_DEBUG_ERROR, - ("Key descripter version not match(AES) \n")); - break; - } - /* Check if this STA is in class 3 state and the WPA state is started */ - if ((pEntry->Sst == SST_ASSOC) - && (pEntry->WpaState >= AS_INITPSK)) { - /* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */ - /* or not. */ - /* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */ - /* Key frame from the Authenticator must not have the Ack bit set. */ - if (peerKeyInfo.KeyAck == 1) { - /* The frame is snet by Authenticator. */ - /* So the Supplicant side shall handle this. */ - - if ((peerKeyInfo.Secure == 0) - && (peerKeyInfo.Request == 0) - && (peerKeyInfo.Error == 0) - && (peerKeyInfo.KeyType == PAIRWISEKEY)) { - /* Process 1. the message 1 of 4-way HS in WPA or WPA2 */ - /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */ - /* 2. the message 3 of 4-way HS in WPA */ - /* EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */ - if (peerKeyInfo.KeyMic == 0) - PeerPairMsg1Action(pAd, pEntry, - Elem); - else - PeerPairMsg3Action(pAd, pEntry, - Elem); - } else if ((peerKeyInfo.Secure == 1) - && (peerKeyInfo.KeyMic == 1) - && (peerKeyInfo.Request == 0) - && (peerKeyInfo.Error == 0)) { - /* Process 1. the message 3 of 4-way HS in WPA2 */ - /* EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */ - /* 2. the message 1 of group KS in WPA or WPA2 */ - /* EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */ - if (peerKeyInfo.KeyType == PAIRWISEKEY) - PeerPairMsg3Action(pAd, pEntry, - Elem); - else - PeerGroupMsg1Action(pAd, pEntry, - Elem); - } - } else { - /* The frame is snet by Supplicant. */ - /* So the Authenticator side shall handle this. */ - if ((peerKeyInfo.Request == 0) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.KeyMic == 1)) { - if (peerKeyInfo.Secure == 0 - && peerKeyInfo.KeyType == - PAIRWISEKEY) { - /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */ - /* Process 1. message 2 of 4-way HS in WPA or WPA2 */ - /* 2. message 4 of 4-way HS in WPA */ - if (CONV_ARRARY_TO_u16 - (pEapol_packet->KeyDesc. - KeyDataLen) == 0) { - PeerPairMsg4Action(pAd, - pEntry, - Elem); - } else { - PeerPairMsg2Action(pAd, - pEntry, - Elem); - } - } else if (peerKeyInfo.Secure == 1 - && peerKeyInfo.KeyType == - PAIRWISEKEY) { - /* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */ - /* Process message 4 of 4-way HS in WPA2 */ - PeerPairMsg4Action(pAd, pEntry, - Elem); - } else if (peerKeyInfo.Secure == 1 - && peerKeyInfo.KeyType == - GROUPKEY) { - /* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */ - /* Process message 2 of Group key HS in WPA or WPA2 */ - PeerGroupMsg2Action(pAd, pEntry, - &Elem-> - Msg - [LENGTH_802_11], - (Elem-> - MsgLen - - LENGTH_802_11)); - } - } - } - } - } while (FALSE); -} - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware encryption before really - sent out to air. - - Arguments: - pAd Pointer to our adapter - void * Pointer to outgoing Ndis frame - NumberOfFrag Number of fragment required - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pHeader802_3, - u32 HdrLen, - u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame) -{ - void *pPacket; - int Status; - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - do { - /* build a NDIS packet */ - Status = - RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, - pData, DataLen); - if (Status != NDIS_STATUS_SUCCESS) - break; - - if (bClearFrame) - RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1); - else - RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0); - { - RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); - - RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID); /* set a default value */ - if (pEntry->apidx != 0) - RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, - pEntry-> - apidx); - - RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid); - RTMP_SET_PACKET_MOREDATA(pPacket, FALSE); - } - - { - /* send out the packet */ - Status = STASendPacket(pAd, pPacket); - if (Status == NDIS_STATUS_SUCCESS) { - u8 Index; - - /* Dequeue one frame from TxSwQueue0..3 queue and process it */ - /* There are three place calling dequeue for TX ring. */ - /* 1. Here, right after queueing the frame. */ - /* 2. At the end of TxRingTxDone service routine. */ - /* 3. Upon NDIS call RTMPSendPackets */ - if ((!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - && - (!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) { - for (Index = 0; Index < 5; Index++) - if (pAd->TxSwQueue[Index]. - Number > 0) - RTMPDeQueuePacket(pAd, - FALSE, - Index, - MAX_TX_PROCESS); - } - } - } - - } while (FALSE); -} - -/* - ========================================================================== - Description: - This is a function to initialize 4-way handshake - - Return: - - ========================================================================== -*/ -void WPAStart4WayHS(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, unsigned long TimeInterval) -{ - u8 Header802_3[14]; - struct rt_eapol_packet EAPOLPKT; - u8 *pBssid = NULL; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n")); - - if (RTMP_TEST_FLAG - (pAd, - fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS)) - { - DBGPRINT(RT_DEBUG_ERROR, - ("[ERROR]WPAStart4WayHS : The interface is closed...\n")); - return; - } - - if (pBssid == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n")); - return; - } - /* Check the status */ - if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) { - DBGPRINT(RT_DEBUG_ERROR, - ("[ERROR]WPAStart4WayHS : Not expect calling\n")); - return; - } - - /* Increment replay counter by 1 */ - ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); - - /* Randomly generate ANonce */ - GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce); - - /* Construct EAPoL message - Pairwise Msg 1 */ - /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0, /* Default key index */ - pEntry->ANonce, NULL, /* TxRSC */ - NULL, /* GTK */ - NULL, /* RSNIE */ - 0, /* RSNIE length */ - &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); - RTMPToWirelessSta(pAd, pEntry, Header802_3, - LENGTH_802_3, (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, - (pEntry->PortSecured == - WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); - - /* Trigger Retry Timer */ - RTMPModTimer(&pEntry->RetryTimer, TimeInterval); - - /* Update State */ - pEntry->WpaState = AS_PTKSTART; - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== WPAStart4WayHS: send Msg1 of 4-way \n")); - -} - -/* - ======================================================================== - - Routine Description: - Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2 - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - u8 PTK[80]; - u8 Header802_3[14]; - struct rt_eapol_packet * pMsg1; - u32 MsgLen; - struct rt_eapol_packet EAPOLPKT; - u8 *pCurrentAddr = NULL; - u8 *pmk_ptr = NULL; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 *rsnie_ptr = NULL; - u8 rsnie_len = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n")); - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - return; - - { - pCurrentAddr = pAd->CurrentAddress; - pmk_ptr = pAd->StaCfg.PMK; - group_cipher = pAd->StaCfg.GroupCipher; - rsnie_ptr = pAd->StaCfg.RSN_IE; - rsnie_len = pAd->StaCfg.RSNIE_Len; - } - - /* Store the received frame */ - pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer Pairwise message 1 - Replay Counter */ - if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) - == FALSE) - return; - - /* Store Replay counter, it will use to verify message 3 and construct message 2 */ - NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - - /* Store ANonce */ - NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, - LEN_KEY_DESC_NONCE); - - /* Generate random SNonce */ - GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce); - - { - /* Calculate PTK(ANonce, SNonce) */ - WpaDerivePTK(pAd, - pmk_ptr, - pEntry->ANonce, - pEntry->Addr, - pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK); - - /* Save key to PTK entry */ - NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); - } - - /* Update WpaState */ - pEntry->WpaState = AS_PTKINIT_NEGOTIATING; - - /* Construct EAPoL message - Pairwise Msg 2 */ - /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0, /* DefaultKeyIdx */ - pEntry->SNonce, NULL, /* TxRsc */ - NULL, /* GTK */ - (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); - - RTMPToWirelessSta(pAd, pEntry, - Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n")); -} - -/* - ========================================================================== - Description: - When receiving the second packet of 4-way pairwisekey handshake. - Return: - ========================================================================== -*/ -void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - u8 PTK[80]; - BOOLEAN Cancelled; - struct rt_header_802_11 * pHeader; - struct rt_eapol_packet EAPOLPKT; - struct rt_eapol_packet * pMsg2; - u32 MsgLen; - u8 Header802_3[LENGTH_802_3]; - u8 TxTsc[6]; - u8 *pBssid = NULL; - u8 *pmk_ptr = NULL; - u8 *gtk_ptr = NULL; - u8 default_key = 0; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 *rsnie_ptr = NULL; - u8 rsnie_len = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n")); - - if ((!pEntry) || (!pEntry->ValidAsCLI)) - return; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - return; - - /* check Entry in valid State */ - if (pEntry->WpaState < AS_PTKSTART) - return; - - /* pointer to 802.11 header */ - pHeader = (struct rt_header_802_11 *) Elem->Msg; - - /* skip 802.11_header(24-byte) and LLC_header(8) */ - pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Store SNonce */ - NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, - LEN_KEY_DESC_NONCE); - - { - /* Derive PTK */ - WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce, /* ANONCE */ - (u8 *) pBssid, pEntry->SNonce, /* SNONCE */ - pEntry->Addr, PTK, LEN_PTK); - - NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); - } - - /* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */ - if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) - == FALSE) - return; - - do { - /* delete retry timer */ - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - - /* Change state */ - pEntry->WpaState = AS_PTKINIT_NEGOTIATING; - - /* Increment replay counter by 1 */ - ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); - - /* Construct EAPoL message - Pairwise Msg 3 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, - group_cipher, - EAPOL_PAIR_MSG_3, - default_key, - pEntry->ANonce, - TxTsc, - (u8 *) gtk_ptr, - (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); - RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, - (pEntry->PortSecured == - WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); - - pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR; - RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); - - /* Update State */ - pEntry->WpaState = AS_PTKINIT_NEGOTIATING; - } while (FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n")); -} - -/* - ======================================================================== - - Routine Description: - Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4 - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - struct rt_header_802_11 * pHeader; - u8 Header802_3[14]; - struct rt_eapol_packet EAPOLPKT; - struct rt_eapol_packet * pMsg3; - u32 MsgLen; - u8 *pCurrentAddr = NULL; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n")); - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - return; - - { - pCurrentAddr = pAd->CurrentAddress; - group_cipher = pAd->StaCfg.GroupCipher; - - } - - /* Record 802.11 header & the received EAPOL packet Msg3 */ - pHeader = (struct rt_header_802_11 *) Elem->Msg; - pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */ - if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) - == FALSE) - return; - - /* Save Replay counter, it will use construct message 4 */ - NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - - /* Double check ANonce */ - if (!NdisEqualMemory - (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) { - return; - } - /* Construct EAPoL message - Pairwise Msg 4 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0, /* group key index not used in message 4 */ - NULL, /* Nonce not used in message 4 */ - NULL, /* TxRSC not used in message 4 */ - NULL, /* GTK not used in message 4 */ - NULL, /* RSN IE not used in message 4 */ - 0, &EAPOLPKT); - - /* Update WpaState */ - pEntry->WpaState = AS_PTKINITDONE; - - /* Update pairwise key */ - { - struct rt_cipher_key *pSharedKey; - - pSharedKey = &pAd->SharedKey[BSS0][0]; - - NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); - - /* Prepare pair-wise key information into shared key table */ - NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key)); - pSharedKey->KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], - LEN_TKIP_RXMICK); - NdisMoveMemory(pSharedKey->TxMic, - &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], - LEN_TKIP_TXMICK); - - /* Decide its ChiperAlg */ - if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) - pSharedKey->CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) - pSharedKey->CipherAlg = CIPHER_AES; - else - pSharedKey->CipherAlg = CIPHER_NONE; - - /* Update these related information to struct rt_mac_table_entry */ - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], - LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, - &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], - LEN_TKIP_TXMICK); - pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg; - - /* Update pairwise key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pSharedKey->CipherAlg, - pSharedKey->Key, - pSharedKey->TxMic, pSharedKey->RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - 0, pSharedKey->CipherAlg, pEntry); - - } - - /* open 802.1x port control and privacy filter */ - if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK || - pEntry->AuthMode == Ndis802_11AuthModeWPA2) { - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - - STA_PORT_SECURED(pAd); - /* Indicate Connected for GUI */ - pAd->IndicateMediaState = NdisMediaStateConnected; - DBGPRINT(RT_DEBUG_TRACE, - ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", - GetAuthMode(pEntry->AuthMode), - GetEncryptType(pEntry->WepStatus), - GetEncryptType(group_cipher))); - } else { - } - - /* Init 802.3 header and send out */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); - RTMPToWirelessSta(pAd, pEntry, - Header802_3, sizeof(Header802_3), - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n")); -} - -/* - ========================================================================== - Description: - When receiving the last packet of 4-way pairwisekey handshake. - Initialize 2-way groupkey handshake following. - Return: - ========================================================================== -*/ -void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - struct rt_eapol_packet * pMsg4; - struct rt_header_802_11 * pHeader; - u32 MsgLen; - BOOLEAN Cancelled; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n")); - - do { - if ((!pEntry) || (!pEntry->ValidAsCLI)) - break; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - break; - - if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING) - break; - - /* pointer to 802.11 header */ - pHeader = (struct rt_header_802_11 *) Elem->Msg; - - /* skip 802.11_header(24-byte) and LLC_header(8) */ - pMsg4 = - (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */ - if (PeerWpaMessageSanity - (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE) - break; - - /* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */ - NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key)); - - /* reset IVEIV in Asic */ - AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0); - - pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, - &pEntry->PTK[TKIP_AP_RXMICK_OFFSET], - LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, - &pEntry->PTK[TKIP_AP_TXMICK_OFFSET], - LEN_TKIP_TXMICK); - - /* Set pairwise key to Asic */ - { - pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) - pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP; - else if (pEntry->WepStatus == - Ndis802_11Encryption3Enabled) - pEntry->PairwiseKey.CipherAlg = CIPHER_AES; - - /* Add Pair-wise key to Asic */ - AsicAddPairwiseKeyEntry(pAd, - pEntry->Addr, - (u8)pEntry->Aid, - &pEntry->PairwiseKey); - - /* update WCID attribute table and IVEIV table for this entry */ - RTMPAddWcidAttributeEntry(pAd, - pEntry->apidx, - 0, - pEntry->PairwiseKey.CipherAlg, - pEntry); - } - - /* 4. upgrade state */ - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - pEntry->WpaState = AS_PTKINITDONE; - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - - if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 || - pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) { - pEntry->GTKState = REKEY_ESTABLISHED; - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - - /* send wireless event - for set key done WPA2 */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_SET_KEY_DONE_WPA2_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_OFF, - ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", - pEntry->AuthMode, - GetAuthMode(pEntry->AuthMode), - pEntry->WepStatus, - GetEncryptType(pEntry->WepStatus), - group_cipher, GetEncryptType(group_cipher))); - } else { - /* 5. init Group 2-way handshake if necessary. */ - WPAStart2WayGroupHS(pAd, pEntry); - - pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR; - RTMPModTimer(&pEntry->RetryTimer, - PEER_MSG3_RETRY_EXEC_INTV); - } - } while (FALSE); - -} - -/* - ========================================================================== - Description: - This is a function to send the first packet of 2-way groupkey handshake - Return: - - ========================================================================== -*/ -void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry) -{ - u8 Header802_3[14]; - u8 TxTsc[6]; - struct rt_eapol_packet EAPOLPKT; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 default_key = 0; - u8 *gnonce_ptr = NULL; - u8 *gtk_ptr = NULL; - u8 *pBssid = NULL; - - DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n")); - - if ((!pEntry) || (!pEntry->ValidAsCLI)) - return; - - do { - /* Increment replay counter by 1 */ - ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); - - /* Construct EAPoL message - Group Msg 1 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, - group_cipher, - EAPOL_GROUP_MSG_1, - default_key, - (u8 *) gnonce_ptr, - TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); - RTMPToWirelessSta(pAd, pEntry, - Header802_3, LENGTH_802_3, - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, - FALSE); - - } while (FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n")); - - return; -} - -/* - ======================================================================== - - Routine Description: - Process Group key 2-way handshaking - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - u8 Header802_3[14]; - struct rt_eapol_packet EAPOLPKT; - struct rt_eapol_packet * pGroup; - u32 MsgLen; - BOOLEAN Cancelled; - u8 default_key = 0; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 *pCurrentAddr = NULL; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n")); - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - { - pCurrentAddr = pAd->CurrentAddress; - group_cipher = pAd->StaCfg.GroupCipher; - default_key = pAd->StaCfg.DefaultKeyId; - } - - /* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */ - pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */ - if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) - == FALSE) - return; - - /* delete retry timer */ - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - - /* Save Replay counter, it will use to construct message 2 */ - NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - - /* Construct EAPoL message - Group Msg 2 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL, /* Nonce not used */ - NULL, /* TxRSC not used */ - NULL, /* GTK not used */ - NULL, /* RSN IE not used */ - 0, &EAPOLPKT); - - /* open 802.1x port control and privacy filter */ - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - - STA_PORT_SECURED(pAd); - /* Indicate Connected for GUI */ - pAd->IndicateMediaState = NdisMediaStateConnected; - - DBGPRINT(RT_DEBUG_TRACE, - ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", - GetAuthMode(pEntry->AuthMode), - GetEncryptType(pEntry->WepStatus), - GetEncryptType(group_cipher))); - - /* init header and Fill Packet and send Msg 2 to authenticator */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); - RTMPToWirelessSta(pAd, pEntry, - Header802_3, sizeof(Header802_3), - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerGroupMsg1Action: sned group message 2\n")); -} - -/* - ========================================================================== - Description: - When receiving the last packet of 2-way groupkey handshake. - Return: - ========================================================================== -*/ -void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - void * Msg, u32 MsgLen) -{ - u32 Len; - u8 *pData; - BOOLEAN Cancelled; - struct rt_eapol_packet * pMsg2; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n")); - - do { - if ((!pEntry) || (!pEntry->ValidAsCLI)) - break; - - if (MsgLen < - (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) - - MAX_LEN_OF_RSNIE - 2)) - break; - - if (pEntry->WpaState != AS_PTKINITDONE) - break; - - pData = (u8 *)Msg; - pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H); - Len = MsgLen - LENGTH_802_1_H; - - /* Sanity Check peer group message 2 - Replay Counter, MIC */ - if (PeerWpaMessageSanity - (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE) - break; - - /* 3. upgrade state */ - - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - pEntry->GTKState = REKEY_ESTABLISHED; - - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) - || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) { - /* send wireless event - for set key done WPA2 */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_SET_KEY_DONE_WPA2_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_OFF, - ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", - pEntry->AuthMode, - GetAuthMode(pEntry->AuthMode), - pEntry->WepStatus, - GetEncryptType(pEntry->WepStatus), - group_cipher, GetEncryptType(group_cipher))); - } else { - /* send wireless event - for set key done WPA */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_SET_KEY_DONE_WPA1_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_OFF, - ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", - pEntry->AuthMode, - GetAuthMode(pEntry->AuthMode), - pEntry->WepStatus, - GetEncryptType(pEntry->WepStatus), - group_cipher, GetEncryptType(group_cipher))); - } - } while (FALSE); -} - -/* - ======================================================================== - - Routine Description: - Classify WPA EAP message type - - Arguments: - EAPType Value of EAP message type - MsgType Internal Message definition for MLME state machine - - Return Value: - TRUE Found appropriate message type - FALSE No appropriate message type - - IRQL = DISPATCH_LEVEL - - Note: - All these constants are defined in wpa.h - For supplicant, there is only EAPOL Key message available - - ======================================================================== -*/ -BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType) -{ - switch (EAPType) { - case EAPPacket: - *MsgType = MT2_EAPPacket; - break; - case EAPOLStart: - *MsgType = MT2_EAPOLStart; - break; - case EAPOLLogoff: - *MsgType = MT2_EAPOLLogoff; - break; - case EAPOLKey: - *MsgType = MT2_EAPOLKey; - break; - case EAPOLASFAlert: - *MsgType = MT2_EAPOLASFAlert; - break; - default: - return FALSE; - } - return TRUE; -} - -/* - ======================================================================== - - Routine Description: - The pseudo-random function(PRF) that hashes various inputs to - derive a pseudo-random value. To add liveness to the pseudo-random - value, a nonce should be one of the inputs. - - It is used to generate PTK, GTK or some specific random value. - - Arguments: - u8 *key, - the key material for HMAC_SHA1 use - int key_len - the length of key - u8 *prefix - a prefix label - int prefix_len - the length of the label - u8 *data - a specific data with variable length - int data_len - the length of a specific data - int len - the output length - - Return Value: - u8 *output - the calculated result - - Note: - 802.11i-2004 Annex H.3 - - ======================================================================== -*/ -void PRF(u8 * key, - int key_len, - u8 * prefix, - int prefix_len, - u8 * data, int data_len, u8 * output, int len) -{ - int i; - u8 *input; - int currentindex = 0; - int total_len; - - /* Allocate memory for input */ - os_alloc_mem(NULL, (u8 **) & input, 1024); - - if (input == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n")); - return; - } - /* Generate concatenation input */ - NdisMoveMemory(input, prefix, prefix_len); - - /* Concatenate a single octet containing 0 */ - input[prefix_len] = 0; - - /* Concatenate specific data */ - NdisMoveMemory(&input[prefix_len + 1], data, data_len); - total_len = prefix_len + 1 + data_len; - - /* Concatenate a single octet containing 0 */ - /* This octet shall be update later */ - input[total_len] = 0; - total_len++; - - /* Iterate to calculate the result by hmac-sha-1 */ - /* Then concatenate to last result */ - for (i = 0; i < (len + 19) / 20; i++) { - HMAC_SHA1(key, key_len, input, total_len, &output[currentindex], - SHA1_DIGEST_SIZE); - currentindex += 20; - - /* update the last octet */ - input[total_len - 1]++; - } - os_free_mem(NULL, input); -} - -/* -* F(P, S, c, i) = U1 xor U2 xor ... Uc -* U1 = PRF(P, S || Int(i)) -* U2 = PRF(P, U1) -* Uc = PRF(P, Uc-1) -*/ - -static void F(char *password, unsigned char *ssid, int ssidlength, - int iterations, int count, unsigned char *output) -{ - unsigned char digest[36], digest1[SHA1_DIGEST_SIZE]; - int i, j; - - /* U1 = PRF(P, S || int(i)) */ - memcpy(digest, ssid, ssidlength); - digest[ssidlength] = (unsigned char)((count >> 24) & 0xff); - digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff); - digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff); - digest[ssidlength + 3] = (unsigned char)(count & 0xff); - HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE); /* for WPA update */ - - /* output = U1 */ - memcpy(output, digest1, SHA1_DIGEST_SIZE); - - for (i = 1; i < iterations; i++) { - /* Un = PRF(P, Un-1) */ - HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); /* for WPA update */ - memcpy(digest1, digest, SHA1_DIGEST_SIZE); - - /* output = output xor Un */ - for (j = 0; j < SHA1_DIGEST_SIZE; j++) { - output[j] ^= digest[j]; - } - } -} - -/* -* password - ascii string up to 63 characters in length -* ssid - octet string up to 32 octets -* ssidlength - length of ssid in octets -* output must be 40 octets in length and outputs 256 bits of key -*/ -int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output) -{ - if ((strlen(password) > 63) || (ssidlength > 32)) - return 0; - - F(password, ssid, ssidlength, 4096, 1, output); - F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]); - return 1; -} - -/* - ======================================================================== - - Routine Description: - It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK. - It shall be called by 4-way handshake processing. - - Arguments: - pAd - pointer to our pAdapter context - PMK - pointer to PMK - ANonce - pointer to ANonce - AA - pointer to Authenticator Address - SNonce - pointer to SNonce - SA - pointer to Supplicant Address - len - indicate the length of PTK (octet) - - Return Value: - Output pointer to the PTK - - Note: - Refer to IEEE 802.11i-2004 8.5.1.2 - - ======================================================================== -*/ -void WpaDerivePTK(struct rt_rtmp_adapter *pAd, - u8 * PMK, - u8 * ANonce, - u8 * AA, - u8 * SNonce, - u8 * SA, u8 * output, u32 len) -{ - u8 concatenation[76]; - u32 CurrPos = 0; - u8 temp[32]; - u8 Prefix[] = - { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', - 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n' - }; - - /* initiate the concatenation input */ - NdisZeroMemory(temp, sizeof(temp)); - NdisZeroMemory(concatenation, 76); - - /* Get smaller address */ - if (RTMPCompareMemory(SA, AA, 6) == 1) - NdisMoveMemory(concatenation, AA, 6); - else - NdisMoveMemory(concatenation, SA, 6); - CurrPos += 6; - - /* Get larger address */ - if (RTMPCompareMemory(SA, AA, 6) == 1) - NdisMoveMemory(&concatenation[CurrPos], SA, 6); - else - NdisMoveMemory(&concatenation[CurrPos], AA, 6); - - /* store the larger mac address for backward compatible of */ - /* ralink proprietary STA-key issue */ - NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); - CurrPos += 6; - - /* Get smaller Nonce */ - if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) - NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue */ - else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) - NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); - else - NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); - CurrPos += 32; - - /* Get larger Nonce */ - if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) - NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue */ - else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) - NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); - else - NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); - CurrPos += 32; - - hex_dump("concatenation=", concatenation, 76); - - /* Use PRF to generate PTK */ - PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len); - -} - -/* - ======================================================================== - - Routine Description: - Generate random number by software. - - Arguments: - pAd - pointer to our pAdapter context - macAddr - pointer to local MAC address - - Return Value: - - Note: - 802.1ii-2004 Annex H.5 - - ======================================================================== -*/ -void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random) -{ - int i, curr; - u8 local[80], KeyCounter[32]; - u8 result[80]; - unsigned long CurrentTime; - u8 prefix[] = - { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' }; - - /* Zero the related information */ - NdisZeroMemory(result, 80); - NdisZeroMemory(local, 80); - NdisZeroMemory(KeyCounter, 32); - - for (i = 0; i < 32; i++) { - /* copy the local MAC address */ - COPY_MAC_ADDR(local, macAddr); - curr = MAC_ADDR_LEN; - - /* concatenate the current time */ - NdisGetSystemUpTime(&CurrentTime); - NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime)); - curr += sizeof(CurrentTime); - - /* concatenate the last result */ - NdisMoveMemory(&local[curr], result, 32); - curr += 32; - - /* concatenate a variable */ - NdisMoveMemory(&local[curr], &i, 2); - curr += 2; - - /* calculate the result */ - PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32); - } - - NdisMoveMemory(random, result, 32); -} - -/* - ======================================================================== - - Routine Description: - Build cipher suite in RSN-IE. - It only shall be called by RTMPMakeRSNIE. - - Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - WepStatus - indicate the encryption type - bMixCipher - a boolean to indicate the pairwise cipher and group - cipher are the same or not - - Return Value: - - Note: - - ======================================================================== -*/ -static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd, - u8 ElementID, - u32 WepStatus, - IN BOOLEAN bMixCipher, - u8 FlexibleCipher, - u8 *pRsnIe, u8 * rsn_len) -{ - u8 PairwiseCnt; - - *rsn_len = 0; - - /* decide WPA2 or WPA1 */ - if (ElementID == Wpa2Ie) { - struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe; - - /* Assign the verson as 1 */ - pRsnie_cipher->version = 1; - - switch (WepStatus) { - /* TKIP mode */ - case Ndis802_11Encryption2Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_TKIP, 4); - *rsn_len = sizeof(struct rt_rsnie2); - break; - - /* AES mode */ - case Ndis802_11Encryption3Enabled: - if (bMixCipher) - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_TKIP, 4); - else - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_CCMP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_CCMP, 4); - *rsn_len = sizeof(struct rt_rsnie2); - break; - - /* TKIP-AES mix mode */ - case Ndis802_11Encryption4Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); - - PairwiseCnt = 1; - /* Insert WPA2 TKIP as the first pairwise cipher */ - if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_TKIP, 4); - /* Insert WPA2 AES as the secondary pairwise cipher */ - if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0]. - oui + 4, OUI_WPA2_CCMP, - 4); - PairwiseCnt = 2; - } - } else { - /* Insert WPA2 AES as the first pairwise cipher */ - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_CCMP, 4); - } - - pRsnie_cipher->ucount = PairwiseCnt; - *rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1)); - break; - } - - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) { - u32 GroupCipher = pAd->StaCfg.GroupCipher; - switch (GroupCipher) { - case Ndis802_11GroupWEP40Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_WEP40, 4); - break; - case Ndis802_11GroupWEP104Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_WEP104, 4); - break; - } - } - /* swap for big-endian platform */ - pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); - pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); - } else { - struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe; - - /* Assign OUI and version */ - NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4); - pRsnie_cipher->version = 1; - - switch (WepStatus) { - /* TKIP mode */ - case Ndis802_11Encryption2Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_TKIP, 4); - *rsn_len = sizeof(struct rt_rsnie); - break; - - /* AES mode */ - case Ndis802_11Encryption3Enabled: - if (bMixCipher) - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_TKIP, 4); - else - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_CCMP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_CCMP, 4); - *rsn_len = sizeof(struct rt_rsnie); - break; - - /* TKIP-AES mix mode */ - case Ndis802_11Encryption4Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); - - PairwiseCnt = 1; - /* Insert WPA TKIP as the first pairwise cipher */ - if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_TKIP, 4); - /* Insert WPA AES as the secondary pairwise cipher */ - if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0]. - oui + 4, OUI_WPA_CCMP, - 4); - PairwiseCnt = 2; - } - } else { - /* Insert WPA AES as the first pairwise cipher */ - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_CCMP, 4); - } - - pRsnie_cipher->ucount = PairwiseCnt; - *rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1)); - break; - } - - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) { - u32 GroupCipher = pAd->StaCfg.GroupCipher; - switch (GroupCipher) { - case Ndis802_11GroupWEP40Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_WEP40, 4); - break; - case Ndis802_11GroupWEP104Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_WEP104, 4); - break; - } - } - /* swap for big-endian platform */ - pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); - pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); - } -} - -/* - ======================================================================== - - Routine Description: - Build AKM suite in RSN-IE. - It only shall be called by RTMPMakeRSNIE. - - Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - AuthMode - indicate the authentication mode - apidx - indicate the interface index - - Return Value: - - Note: - - ======================================================================== -*/ -static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd, - u8 ElementID, - u32 AuthMode, - u8 apidx, - u8 *pRsnIe, u8 * rsn_len) -{ - struct rt_rsnie_auth *pRsnie_auth; - u8 AkmCnt = 1; /* default as 1 */ - - pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len)); - - /* decide WPA2 or WPA1 */ - if (ElementID == Wpa2Ie) { - - switch (AuthMode) { - case Ndis802_11AuthModeWPA2: - case Ndis802_11AuthModeWPA1WPA2: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA2_8021X_AKM, 4); - break; - - case Ndis802_11AuthModeWPA2PSK: - case Ndis802_11AuthModeWPA1PSKWPA2PSK: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA2_PSK_AKM, 4); - break; - default: - AkmCnt = 0; - break; - - } - } else { - switch (AuthMode) { - case Ndis802_11AuthModeWPA: - case Ndis802_11AuthModeWPA1WPA2: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA_8021X_AKM, 4); - break; - - case Ndis802_11AuthModeWPAPSK: - case Ndis802_11AuthModeWPA1PSKWPA2PSK: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA_PSK_AKM, 4); - break; - - case Ndis802_11AuthModeWPANone: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA_NONE_AKM, 4); - break; - default: - AkmCnt = 0; - break; - } - } - - pRsnie_auth->acount = AkmCnt; - pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount); - - /* update current RSNIE length */ - (*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1))); - -} - -/* - ======================================================================== - - Routine Description: - Build capability in RSN-IE. - It only shall be called by RTMPMakeRSNIE. - - Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - apidx - indicate the interface index - - Return Value: - - Note: - - ======================================================================== -*/ -static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd, - u8 ElementID, - u8 apidx, - u8 *pRsnIe, u8 * rsn_len) -{ - RSN_CAPABILITIES *pRSN_Cap; - - /* it could be ignored in WPA1 mode */ - if (ElementID == WpaIe) - return; - - pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len)); - - pRSN_Cap->word = cpu2le16(pRSN_Cap->word); - - (*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length */ - -} - -/* - ======================================================================== - - Routine Description: - Build RSN IE context. It is not included element-ID and length. - - Arguments: - pAd - pointer to our pAdapter context - AuthMode - indicate the authentication mode - WepStatus - indicate the encryption type - apidx - indicate the interface index - - Return Value: - - Note: - - ======================================================================== -*/ -void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd, - u32 AuthMode, u32 WepStatus, u8 apidx) -{ - u8 *pRsnIe = NULL; /* primary RSNIE */ - u8 *rsnielen_cur_p = 0; /* the length of the primary RSNIE */ - u8 *rsnielen_ex_cur_p = 0; /* the length of the secondary RSNIE */ - u8 PrimaryRsnie; - BOOLEAN bMixCipher = FALSE; /* indicate the pairwise and group cipher are different */ - u8 p_offset; - WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES; /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */ - - rsnielen_cur_p = NULL; - rsnielen_ex_cur_p = NULL; - - { - { - if (pAd->StaCfg.WpaSupplicantUP != - WPA_SUPPLICANT_DISABLE) { - if (AuthMode < Ndis802_11AuthModeWPA) - return; - } else { - /* Support WPAPSK or WPA2PSK in STA-Infra mode */ - /* Support WPANone in STA-Adhoc mode */ - if ((AuthMode != Ndis802_11AuthModeWPAPSK) && - (AuthMode != Ndis802_11AuthModeWPA2PSK) && - (AuthMode != Ndis802_11AuthModeWPANone) - ) - return; - } - - DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n")); - - /* Zero RSNIE context */ - pAd->StaCfg.RSNIE_Len = 0; - NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE); - - /* Pointer to RSNIE */ - rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len; - pRsnIe = pAd->StaCfg.RSN_IE; - - bMixCipher = pAd->StaCfg.bMixCipher; - } - } - - /* indicate primary RSNIE as WPA or WPA2 */ - if ((AuthMode == Ndis802_11AuthModeWPA) || - (AuthMode == Ndis802_11AuthModeWPAPSK) || - (AuthMode == Ndis802_11AuthModeWPANone) || - (AuthMode == Ndis802_11AuthModeWPA1WPA2) || - (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) - PrimaryRsnie = WpaIe; - else - PrimaryRsnie = Wpa2Ie; - - { - /* Build the primary RSNIE */ - /* 1. insert cipher suite */ - RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, - FlexibleCipher, pRsnIe, &p_offset); - - /* 2. insert AKM */ - RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, - &p_offset); - - /* 3. insert capability */ - RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset); - } - - /* 4. update the RSNIE length */ - *rsnielen_cur_p = p_offset; - - hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p)); - -} - -/* - ========================================================================== - Description: - Check whether the received frame is EAP frame. - - Arguments: - pAd - pointer to our pAdapter context - pEntry - pointer to active entry - pData - the received frame - DataByteCount - the received frame's length - FromWhichBSSID - indicate the interface index - - Return: - TRUE - This frame is EAP frame - FALSE - otherwise - ========================================================================== -*/ -BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pData, - unsigned long DataByteCount, u8 FromWhichBSSID) -{ - unsigned long Body_len; - BOOLEAN Cancelled; - - if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H)) - return FALSE; - - /* Skip LLC header */ - if (NdisEqualMemory(SNAP_802_1H, pData, 6) || - /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */ - NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) { - pData += 6; - } - /* Skip 2-bytes EAPoL type */ - if (NdisEqualMemory(EAPOL, pData, 2)) { - pData += 2; - } else - return FALSE; - - switch (*(pData + 1)) { - case EAPPacket: - Body_len = (*(pData + 2) << 8) | (*(pData + 3)); - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", - Body_len)); - break; - case EAPOLStart: - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOL-Start frame, TYPE = 1 \n")); - if (pEntry->EnqueueEapolStartTimerRunning != - EAPOL_START_DISABLE) { - DBGPRINT(RT_DEBUG_TRACE, - ("Cancel the EnqueueEapolStartTimerRunning \n")); - RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, - &Cancelled); - pEntry->EnqueueEapolStartTimerRunning = - EAPOL_START_DISABLE; - } - break; - case EAPOLLogoff: - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOLLogoff frame, TYPE = 2 \n")); - break; - case EAPOLKey: - Body_len = (*(pData + 2) << 8) | (*(pData + 3)); - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", - Body_len)); - break; - case EAPOLASFAlert: - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOLASFAlert frame, TYPE = 4 \n")); - break; - default: - return FALSE; - - } - return TRUE; -} - -/* - ========================================================================== - Description: - Report the EAP message type - - Arguments: - msg - EAPOL_PAIR_MSG_1 - EAPOL_PAIR_MSG_2 - EAPOL_PAIR_MSG_3 - EAPOL_PAIR_MSG_4 - EAPOL_GROUP_MSG_1 - EAPOL_GROUP_MSG_2 - - Return: - message type string - - ========================================================================== -*/ -char *GetEapolMsgType(char msg) -{ - if (msg == EAPOL_PAIR_MSG_1) - return "Pairwise Message 1"; - else if (msg == EAPOL_PAIR_MSG_2) - return "Pairwise Message 2"; - else if (msg == EAPOL_PAIR_MSG_3) - return "Pairwise Message 3"; - else if (msg == EAPOL_PAIR_MSG_4) - return "Pairwise Message 4"; - else if (msg == EAPOL_GROUP_MSG_1) - return "Group Message 1"; - else if (msg == EAPOL_GROUP_MSG_2) - return "Group Message 2"; - else - return "Invalid Message"; -} - -/* - ======================================================================== - - Routine Description: - Check Sanity RSN IE of EAPoL message - - Arguments: - - Return Value: - - ======================================================================== -*/ -BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd, - u8 *pData, - u8 DataLen, - struct rt_mac_table_entry *pEntry, u8 * Offset) -{ - u8 *pVIE; - u8 len; - struct rt_eid * pEid; - BOOLEAN result = FALSE; - - pVIE = pData; - len = DataLen; - *Offset = 0; - - while (len > sizeof(struct rt_rsnie2)) { - pEid = (struct rt_eid *) pVIE; - /* WPA RSN IE */ - if ((pEid->Eid == IE_WPA) - && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) { - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA - || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) - && - (NdisEqualMemory - (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) - && (pEntry->RSNIE_Len == (pEid->Len + 2))) { - result = TRUE; - } - - *Offset += (pEid->Len + 2); - } - /* WPA2 RSN IE */ - else if ((pEid->Eid == IE_RSN) - && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) { - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 - || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) - && (pEid->Eid == pEntry->RSN_IE[0]) - && ((pEid->Len + 2) >= pEntry->RSNIE_Len) - && - (NdisEqualMemory - (pEid->Octet, &pEntry->RSN_IE[2], - pEntry->RSNIE_Len - 2))) { - - result = TRUE; - } - - *Offset += (pEid->Len + 2); - } else { - break; - } - - pVIE += (pEid->Len + 2); - len -= (pEid->Len + 2); - } - - return result; - -} - -/* - ======================================================================== - - Routine Description: - Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK. - GTK is encaptulated in KDE format at p.83 802.11i D10 - - Arguments: - - Return Value: - - Note: - 802.11i D10 - - ======================================================================== -*/ -BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd, - u8 *pKeyData, - u8 KeyDataLen, - u8 GroupKeyIndex, - u8 MsgType, - IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry) -{ - struct rt_kde_encap * pKDE = NULL; - u8 *pMyKeyData = pKeyData; - u8 KeyDataLength = KeyDataLen; - u8 GTKLEN = 0; - u8 DefaultIdx = 0; - u8 skip_offset; - - /* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */ - if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) { - /* Check RSN IE whether it is WPA2/WPA2PSK */ - if (!RTMPCheckRSNIE - (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) { - /* send wireless event - for RSN IE different */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_RSNIE_DIFF_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_ERROR, - ("RSN_IE Different in msg %d of 4-way handshake!\n", - MsgType)); - hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen); - hex_dump("Desired RSN_IE ", pEntry->RSN_IE, - pEntry->RSNIE_Len); - - return FALSE; - } else { - if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) { - WpaShowAllsuite(pMyKeyData, skip_offset); - - /* skip RSN IE */ - pMyKeyData += skip_offset; - KeyDataLength -= skip_offset; - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", - skip_offset)); - } else - return TRUE; - } - } - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", - KeyDataLength)); - /*hex_dump("remain data", pMyKeyData, KeyDataLength); */ - - /* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */ - if (bWPA2 - && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) { - if (KeyDataLength >= 8) /* KDE format exclude GTK length */ - { - pKDE = (struct rt_kde_encap *) pMyKeyData; - - DefaultIdx = pKDE->GTKEncap.Kid; - - /* Sanity check - KED length */ - if (KeyDataLength < (pKDE->Len + 2)) { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: The len from KDE is too short \n")); - return FALSE; - } - /* Get GTK length - refer to IEEE 802.11i-2004 p.82 */ - GTKLEN = pKDE->Len - 6; - if (GTKLEN < LEN_AES_KEY) { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: GTK Key length is too short (%d) \n", - GTKLEN)); - return FALSE; - } - - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: KDE format length is too short \n")); - return FALSE; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", - DefaultIdx, GTKLEN)); - /* skip it */ - pMyKeyData += 8; - KeyDataLength -= 8; - - } else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) { - DefaultIdx = GroupKeyIndex; - DBGPRINT(RT_DEBUG_TRACE, - ("GTK DefaultKeyID=%d \n", DefaultIdx)); - } - /* Sanity check - shared key index must be 1 ~ 3 */ - if (DefaultIdx < 1 || DefaultIdx > 3) { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: GTK Key index(%d) is invalid in %s %s \n", - DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), - GetEapolMsgType(MsgType))); - return FALSE; - } - - { - struct rt_cipher_key *pSharedKey; - - /* set key material, TxMic and RxMic */ - NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32); - pAd->StaCfg.DefaultKeyId = DefaultIdx; - - pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]; - - /* Prepare pair-wise key information into shared key table */ - NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key)); - pSharedKey->KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK); - NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], - LEN_TKIP_RXMICK); - NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], - LEN_TKIP_TXMICK); - - /* Update Shared Key CipherAlg */ - pSharedKey->CipherAlg = CIPHER_NONE; - if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) - pSharedKey->CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.GroupCipher == - Ndis802_11Encryption3Enabled) - pSharedKey->CipherAlg = CIPHER_AES; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) - pSharedKey->CipherAlg = CIPHER_WEP64; - else if (pAd->StaCfg.GroupCipher == - Ndis802_11GroupWEP104Enabled) - pSharedKey->CipherAlg = CIPHER_WEP128; - - /* Update group key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pSharedKey->CipherAlg, - pSharedKey->Key, - pSharedKey->TxMic, pSharedKey->RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pSharedKey->CipherAlg, NULL); - } - - return TRUE; - -} - -/* - ======================================================================== - - Routine Description: - Construct EAPoL message for WPA handshaking - Its format is below, - - +--------------------+ - | Protocol Version | 1 octet - +--------------------+ - | Protocol Type | 1 octet - +--------------------+ - | Body Length | 2 octets - +--------------------+ - | Descriptor Type | 1 octet - +--------------------+ - | Key Information | 2 octets - +--------------------+ - | Key Length | 1 octet - +--------------------+ - | Key Repaly Counter | 8 octets - +--------------------+ - | Key Nonce | 32 octets - +--------------------+ - | Key IV | 16 octets - +--------------------+ - | Key RSC | 8 octets - +--------------------+ - | Key ID or Reserved | 8 octets - +--------------------+ - | Key MIC | 16 octets - +--------------------+ - | Key Data Length | 2 octets - +--------------------+ - | Key Data | n octets - +--------------------+ - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - Note: - - ======================================================================== -*/ -void ConstructEapolMsg(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 MsgType, - u8 DefaultKeyIdx, - u8 * KeyNonce, - u8 * TxRSC, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_Len, struct rt_eapol_packet * pMsg) -{ - BOOLEAN bWPA2 = FALSE; - u8 KeyDescVer; - - /* Choose WPA2 or not */ - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || - (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) - bWPA2 = TRUE; - - /* Init Packet and Fill header */ - pMsg->ProVer = EAPOL_VER; - pMsg->ProType = EAPOLKey; - - /* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */ - SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG); - - /* Fill in EAPoL descriptor */ - if (bWPA2) - pMsg->KeyDesc.Type = WPA2_KEY_DESC; - else - pMsg->KeyDesc.Type = WPA1_KEY_DESC; - - /* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */ - { - /* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */ - /* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */ - KeyDescVer = - (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) - || (GroupKeyWepStatus == - Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) - : (DESC_TYPE_TKIP)); - } - - pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer; - - /* Specify Key Type as Group(0) or Pairwise(1) */ - if (MsgType >= EAPOL_GROUP_MSG_1) - pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY; - else - pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - - /* Specify Key Index, only group_msg1_WPA1 */ - if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)) - pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx; - - if (MsgType == EAPOL_PAIR_MSG_3) - pMsg->KeyDesc.KeyInfo.Install = 1; - - if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) - || (MsgType == EAPOL_GROUP_MSG_1)) - pMsg->KeyDesc.KeyInfo.KeyAck = 1; - - if (MsgType != EAPOL_PAIR_MSG_1) - pMsg->KeyDesc.KeyInfo.KeyMic = 1; - - if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || - (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) { - pMsg->KeyDesc.KeyInfo.Secure = 1; - } - - if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || - (MsgType == EAPOL_GROUP_MSG_1))) { - pMsg->KeyDesc.KeyInfo.EKD_DL = 1; - } - /* key Information element has done. */ - *(u16 *) (&pMsg->KeyDesc.KeyInfo) = - cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo)); - - /* Fill in Key Length */ - { - if (MsgType >= EAPOL_GROUP_MSG_1) { - /* the length of group key cipher */ - pMsg->KeyDesc.KeyLength[1] = - ((GroupKeyWepStatus == - Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : - LEN_AES_KEY); - } else { - /* the length of pairwise key cipher */ - pMsg->KeyDesc.KeyLength[1] = - ((pEntry->WepStatus == - Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : - LEN_AES_KEY); - } - } - - /* Fill in replay counter */ - NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, - LEN_KEY_DESC_REPLAY); - - /* Fill Key Nonce field */ - /* ANonce : pairwise_msg1 & pairwise_msg3 */ - /* SNonce : pairwise_msg2 */ - /* GNonce : group_msg1_wpa1 */ - if ((MsgType <= EAPOL_PAIR_MSG_3) - || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)))) - NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, - LEN_KEY_DESC_NONCE); - - /* Fill key IV - WPA2 as 0, WPA1 as random */ - if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) { - /* Suggest IV be random number plus some number, */ - NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], - LEN_KEY_DESC_IV); - pMsg->KeyDesc.KeyIv[15] += 2; - } - /* Fill Key RSC field */ - /* It contains the RSC for the GTK being installed. */ - if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) - || (MsgType == EAPOL_GROUP_MSG_1)) { - NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6); - } - /* Clear Key MIC field for MIC calculation later */ - NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - - ConstructEapolKeyData(pEntry, - GroupKeyWepStatus, - KeyDescVer, - MsgType, - DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg); - - /* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */ - if (MsgType != EAPOL_PAIR_MSG_1) { - CalculateMIC(KeyDescVer, pEntry->PTK, pMsg); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("===> ConstructEapolMsg for %s %s\n", - ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); - DBGPRINT(RT_DEBUG_TRACE, - (" Body length = %d \n", - CONV_ARRARY_TO_u16(pMsg->Body_Len))); - DBGPRINT(RT_DEBUG_TRACE, - (" Key length = %d \n", - CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength))); - -} - -/* - ======================================================================== - - Routine Description: - Construct the Key Data field of EAPoL message - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 keyDescVer, - u8 MsgType, - u8 DefaultKeyIdx, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_LEN, struct rt_eapol_packet * pMsg) -{ - u8 *mpool, *Key_Data, *Rc4GTK; - u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)]; - unsigned long data_offset; - BOOLEAN bWPA2Capable = FALSE; - struct rt_rtmp_adapter *pAd = pEntry->pAd; - BOOLEAN GTK_Included = FALSE; - - /* Choose WPA2 or not */ - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || - (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) - bWPA2Capable = TRUE; - - if (MsgType == EAPOL_PAIR_MSG_1 || - MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) - return; - - /* allocate memory pool */ - os_alloc_mem(NULL, (u8 **) & mpool, 1500); - - if (mpool == NULL) - return; - - /* Rc4GTK Len = 512 */ - Rc4GTK = (u8 *) ROUND_UP(mpool, 4); - /* Key_Data Len = 512 */ - Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4); - - NdisZeroMemory(Key_Data, 512); - SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0); - data_offset = 0; - - /* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */ - if (RSNIE_LEN - && ((MsgType == EAPOL_PAIR_MSG_2) - || (MsgType == EAPOL_PAIR_MSG_3))) { - u8 *pmkid_ptr = NULL; - u8 pmkid_len = 0; - - RTMPInsertRSNIE(&Key_Data[data_offset], - &data_offset, - RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len); - } - - /* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */ - if (bWPA2Capable - && ((MsgType == EAPOL_PAIR_MSG_3) - || (MsgType == EAPOL_GROUP_MSG_1))) { - /* Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h */ - Key_Data[data_offset + 0] = 0xDD; - - if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { - Key_Data[data_offset + 1] = 0x16; /* 4+2+16(OUI+DataType+DataField) */ - } else { - Key_Data[data_offset + 1] = 0x26; /* 4+2+32(OUI+DataType+DataField) */ - } - - Key_Data[data_offset + 2] = 0x00; - Key_Data[data_offset + 3] = 0x0F; - Key_Data[data_offset + 4] = 0xAC; - Key_Data[data_offset + 5] = 0x01; - - /* GTK KDE format - 802.11i-2004 Figure-43x */ - Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03); - Key_Data[data_offset + 7] = 0x00; /* Reserved Byte */ - - data_offset += 8; - } - - /* Encapsulate GTK */ - /* Only for pairwise_msg3_WPA2 and group_msg1 */ - if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) - || (MsgType == EAPOL_GROUP_MSG_1)) { - /* Fill in GTK */ - if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { - NdisMoveMemory(&Key_Data[data_offset], GTK, - LEN_AES_KEY); - data_offset += LEN_AES_KEY; - } else { - NdisMoveMemory(&Key_Data[data_offset], GTK, - TKIP_GTK_LENGTH); - data_offset += TKIP_GTK_LENGTH; - } - - GTK_Included = TRUE; - } - - /* This whole key-data field shall be encrypted if a GTK is included. */ - /* Encrypt the data material in key data field with KEK */ - if (GTK_Included) { - /*hex_dump("GTK_Included", Key_Data, data_offset); */ - - if ((keyDescVer == DESC_TYPE_AES)) { - u8 remainder = 0; - u8 pad_len = 0; - - /* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */ - /* shall be used to encrypt the Key Data field using the KEK field from */ - /* the derived PTK. */ - - /* If the Key Data field uses the NIST AES key wrap, then the Key Data field */ - /* shall be padded before encrypting if the key data length is less than 16 */ - /* octets or if it is not a multiple of 8. The padding consists of appending */ - /* a single octet 0xdd followed by zero or more 0x00 octets. */ - if ((remainder = data_offset & 0x07) != 0) { - int i; - - pad_len = (8 - remainder); - Key_Data[data_offset] = 0xDD; - for (i = 1; i < pad_len; i++) - Key_Data[data_offset + i] = 0; - - data_offset += pad_len; - } - - AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, - data_offset, Rc4GTK); - /* AES wrap function will grow 8 bytes in length */ - data_offset += 8; - } else { - /* Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field - using the KEK field from the derived PTK. */ - - /* PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */ - /* put TxTsc in Key RSC field */ - pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; /*Init crc32. */ - - /* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */ - NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, - LEN_KEY_DESC_IV); - NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16], - LEN_EAP_EK); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); /*INIT SBOX, KEYLEN+3(IV) */ - pAd->PrivateInfo.FCSCRC32 = - RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, - data_offset); - WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, - Key_Data, data_offset); - } - - NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset); - } else { - NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset); - } - - /* Update key data length field and total body length */ - SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset); - INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset); - - os_free_mem(NULL, mpool); - -} - -/* - ======================================================================== - - Routine Description: - Calcaulate MIC. It is used during 4-ways handsharking. - - Arguments: - pAd - pointer to our pAdapter context - PeerWepStatus - indicate the encryption type - - Return Value: - - Note: - - ======================================================================== -*/ -static void CalculateMIC(u8 KeyDescVer, - u8 * PTK, struct rt_eapol_packet * pMsg) -{ - u8 *OutBuffer; - unsigned long FrameLen = 0; - u8 mic[LEN_KEY_DESC_MIC]; - u8 digest[80]; - - /* allocate memory for MIC calculation */ - os_alloc_mem(NULL, (u8 **) & OutBuffer, 512); - - if (OutBuffer == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n")); - return; - } - /* make a frame for calculating MIC. */ - MakeOutgoingFrame(OutBuffer, &FrameLen, - CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg, - END_OF_ARGS); - - NdisZeroMemory(mic, sizeof(mic)); - - /* Calculate MIC */ - if (KeyDescVer == DESC_TYPE_AES) { - HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest, - SHA1_DIGEST_SIZE); - NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); - } else { - HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic, - MD5_DIGEST_SIZE); - } - - /* store the calculated MIC */ - NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); - - os_free_mem(NULL, OutBuffer); -} - -/* - ======================================================================== - - Routine Description: - Some received frames can't decrypt by Asic, so decrypt them by software. - - Arguments: - pAd - pointer to our pAdapter context - PeerWepStatus - indicate the encryption type - - Return Value: - NDIS_STATUS_SUCCESS - decryption successful - NDIS_STATUS_FAILURE - decryption failure - - ======================================================================== -*/ -int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, - IN NDIS_802_11_ENCRYPTION_STATUS - GroupCipher, struct rt_cipher_key *pShard_key) -{ - struct rt_rxwi * pRxWI = pRxBlk->pRxWI; - - /* handle WEP decryption */ - if (GroupCipher == Ndis802_11Encryption1Enabled) { - if (RTMPSoftDecryptWEP - (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, - pShard_key)) { - - /*Minus IV[4] & ICV[4] */ - pRxWI->MPDUtotalByteCount -= 8; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR : Software decrypt WEP data fails.\n")); - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - } - /* handle TKIP decryption */ - else if (GroupCipher == Ndis802_11Encryption2Enabled) { - if (RTMPSoftDecryptTKIP - (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, - pShard_key)) { - - /*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */ - pRxWI->MPDUtotalByteCount -= 20; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR : RTMPSoftDecryptTKIP Failed\n")); - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - } - /* handle AES decryption */ - else if (GroupCipher == Ndis802_11Encryption3Enabled) { - if (RTMPSoftDecryptAES - (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, - pShard_key)) { - - /*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */ - pRxWI->MPDUtotalByteCount -= 16; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR : RTMPSoftDecryptAES Failed\n")); - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - } else { - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - - return NDIS_STATUS_SUCCESS; - -} - -u8 *GetSuiteFromRSNIE(u8 *rsnie, - u32 rsnie_len, u8 type, u8 * count) -{ - struct rt_eid * pEid; - int len; - u8 *pBuf; - int offset = 0; - struct rt_rsnie_auth *pAkm; - u16 acount; - BOOLEAN isWPA2 = FALSE; - - pEid = (struct rt_eid *) rsnie; - len = rsnie_len - 2; /* exclude IE and length */ - pBuf = (u8 *)& pEid->Octet[0]; - - /* set default value */ - *count = 0; - - /* Check length */ - if ((len <= 0) || (pEid->Len != len)) { - DBGPRINT_ERR("%s : The length is invalid\n", __func__); - return NULL; - } - /* Check WPA or WPA2 */ - if (pEid->Eid == IE_WPA) { - struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf; - u16 ucount; - - if (len < sizeof(struct rt_rsnie)) { - DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__); - return NULL; - } - /* Get the count of pairwise cipher */ - ucount = cpu2le16(pRsnie->ucount); - if (ucount > 2) { - DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount); - return NULL; - } - /* Get the group cipher */ - if (type == GROUP_SUITE) { - *count = 1; - return pRsnie->mcast; - } - /* Get the pairwise cipher suite */ - else if (type == PAIRWISE_SUITE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s : The count of pairwise cipher is %d\n", - __func__, ucount)); - *count = ucount; - return pRsnie->ucast[0].oui; - } - - offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1)); - - } else if (pEid->Eid == IE_RSN) { - struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf; - u16 ucount; - - isWPA2 = TRUE; - - if (len < sizeof(struct rt_rsnie2)) { - DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__); - return NULL; - } - /* Get the count of pairwise cipher */ - ucount = cpu2le16(pRsnie->ucount); - if (ucount > 2) { - DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount); - return NULL; - } - /* Get the group cipher */ - if (type == GROUP_SUITE) { - *count = 1; - return pRsnie->mcast; - } - /* Get the pairwise cipher suite */ - else if (type == PAIRWISE_SUITE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s : The count of pairwise cipher is %d\n", - __func__, ucount)); - *count = ucount; - return pRsnie->ucast[0].oui; - } - - offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1)); - - } else { - DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid); - return NULL; - } - - /* skip group cipher and pairwise cipher suite */ - pBuf += offset; - len -= offset; - - if (len < sizeof(struct rt_rsnie_auth)) { - DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__); - return NULL; - } - /* pointer to AKM count */ - pAkm = (struct rt_rsnie_auth *)pBuf; - - /* Get the count of pairwise cipher */ - acount = cpu2le16(pAkm->acount); - if (acount > 2) { - DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount); - return NULL; - } - /* Get the AKM suite */ - if (type == AKM_SUITE) { - DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n", - __func__, acount)); - *count = acount; - return pAkm->auth[0].oui; - } - offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1)); - - pBuf += offset; - len -= offset; - - /* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */ - if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) { - /* Skip RSN capability and PMKID-Count */ - pBuf += (sizeof(RSN_CAPABILITIES) + 2); - len -= (sizeof(RSN_CAPABILITIES) + 2); - - /* Get PMKID */ - if (type == PMKID_LIST) { - *count = 1; - return pBuf; - } - } else { - DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__); - return NULL; - } - - *count = 0; - /*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */ - return NULL; - -} - -void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len) -{ - u8 *pSuite = NULL; - u8 count; - - hex_dump("RSNIE", rsnie, rsnie_len); - - /* group cipher */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count); - if (pSuite != NULL) { - hex_dump("group cipher", pSuite, 4 * count); - } - /* pairwise cipher */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count); - if (pSuite != NULL) { - hex_dump("pairwise cipher", pSuite, 4 * count); - } - /* AKM */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count); - if (pSuite != NULL) { - hex_dump("AKM suite", pSuite, 4 * count); - } - /* PMKID */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count); - if (pSuite != NULL) { - hex_dump("PMKID", pSuite, LEN_PMKID); - } - -} - -void RTMPInsertRSNIE(u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 *rsnie_ptr, - u8 rsnie_len, - u8 *pmkid_ptr, u8 pmkid_len) -{ - u8 *pTmpBuf; - unsigned long TempLen = 0; - u8 extra_len = 0; - u16 pmk_count = 0; - u8 ie_num; - u8 total_len = 0; - u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC }; - - pTmpBuf = pFrameBuf; - - /* PMKID-List Must larger than 0 and the multiple of 16. */ - if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) { - extra_len = sizeof(u16)+ pmkid_len; - - pmk_count = (pmkid_len >> 4); - pmk_count = cpu2le16(pmk_count); - } else { - DBGPRINT(RT_DEBUG_WARN, - ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n", - __func__, pmkid_len)); - } - - if (rsnie_len != 0) { - ie_num = IE_WPA; - total_len = rsnie_len; - - if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) { - ie_num = IE_RSN; - total_len += extra_len; - } - - /* construct RSNIE body */ - MakeOutgoingFrame(pTmpBuf, &TempLen, - 1, &ie_num, - 1, &total_len, - rsnie_len, rsnie_ptr, END_OF_ARGS); - - pTmpBuf += TempLen; - *pFrameLen = *pFrameLen + TempLen; - - if (ie_num == IE_RSN) { - /* Insert PMKID-List field */ - if (extra_len > 0) { - MakeOutgoingFrame(pTmpBuf, &TempLen, - 2, &pmk_count, - pmkid_len, pmkid_ptr, - END_OF_ARGS); - - pTmpBuf += TempLen; - *pFrameLen = *pFrameLen + TempLen; - } - } - } - - return; -} diff --git a/drivers/staging/rt2860/common/crypt_hmac.c b/drivers/staging/rt2860/common/crypt_hmac.c deleted file mode 100644 index d7ab08ec1a41..000000000000 --- a/drivers/staging/rt2860/common/crypt_hmac.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - *************************************************************************/ - -#include "../crypt_hmac.h" - -#ifdef HMAC_SHA1_SUPPORT -/* -======================================================================== -Routine Description: - HMAC using SHA1 hash function - -Arguments: - key Secret key - key_len The length of the key in bytes - message Message context - message_len The length of message in bytes - macLen Request the length of message authentication code - -Return Value: - mac Message authentication code - -Note: - None -======================================================================== -*/ -void HMAC_SHA1(IN const u8 Key[], - u32 KeyLen, - IN const u8 Message[], - u32 MessageLen, u8 MAC[], u32 MACLen) -{ - struct rt_sha1_ctx sha_ctx1; - struct rt_sha1_ctx sha_ctx2; - u8 K0[SHA1_BLOCK_SIZE]; - u8 Digest[SHA1_DIGEST_SIZE]; - u32 index; - - NdisZeroMemory(&sha_ctx1, sizeof(struct rt_sha1_ctx)); - NdisZeroMemory(&sha_ctx2, sizeof(struct rt_sha1_ctx)); - /* - * If the length of K = B(Block size): K0 = K. - * If the length of K > B: hash K to obtain an L byte string, - * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). - * If the length of K < B: append zeros to the end of K to create a B-byte string K0 - */ - NdisZeroMemory(K0, SHA1_BLOCK_SIZE); - if (KeyLen <= SHA1_BLOCK_SIZE) - NdisMoveMemory(K0, Key, KeyLen); - else - RT_SHA1(Key, KeyLen, K0); - /* End of if */ - - /* Exclusive-Or K0 with ipad */ - /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ - for (index = 0; index < SHA1_BLOCK_SIZE; index++) - K0[index] ^= 0x36; - /* End of for */ - - RT_SHA1_Init(&sha_ctx1); - /* H(K0^ipad) */ - SHA1_Append(&sha_ctx1, K0, sizeof(K0)); - /* H((K0^ipad)||text) */ - SHA1_Append(&sha_ctx1, Message, MessageLen); - SHA1_End(&sha_ctx1, Digest); - - /* Exclusive-Or K0 with opad and remove ipad */ - /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ - for (index = 0; index < SHA1_BLOCK_SIZE; index++) - K0[index] ^= 0x36 ^ 0x5c; - /* End of for */ - - RT_SHA1_Init(&sha_ctx2); - /* H(K0^opad) */ - SHA1_Append(&sha_ctx2, K0, sizeof(K0)); - /* H( (K0^opad) || H((K0^ipad)||text) ) */ - SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE); - SHA1_End(&sha_ctx2, Digest); - - if (MACLen > SHA1_DIGEST_SIZE) - NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE); - else - NdisMoveMemory(MAC, Digest, MACLen); -} /* End of HMAC_SHA1 */ -#endif /* HMAC_SHA1_SUPPORT */ - -#ifdef HMAC_MD5_SUPPORT -/* -======================================================================== -Routine Description: - HMAC using MD5 hash function - -Arguments: - key Secret key - key_len The length of the key in bytes - message Message context - message_len The length of message in bytes - macLen Request the length of message authentication code - -Return Value: - mac Message authentication code - -Note: - None -======================================================================== -*/ -void HMAC_MD5(IN const u8 Key[], - u32 KeyLen, - IN const u8 Message[], - u32 MessageLen, u8 MAC[], u32 MACLen) -{ - struct rt_md5_ctx_struc md5_ctx1; - struct rt_md5_ctx_struc md5_ctx2; - u8 K0[MD5_BLOCK_SIZE]; - u8 Digest[MD5_DIGEST_SIZE]; - u32 index; - - NdisZeroMemory(&md5_ctx1, sizeof(struct rt_md5_ctx_struc)); - NdisZeroMemory(&md5_ctx2, sizeof(struct rt_md5_ctx_struc)); - /* - * If the length of K = B(Block size): K0 = K. - * If the length of K > B: hash K to obtain an L byte string, - * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). - * If the length of K < B: append zeros to the end of K to create a B-byte string K0 - */ - NdisZeroMemory(K0, MD5_BLOCK_SIZE); - if (KeyLen <= MD5_BLOCK_SIZE) { - NdisMoveMemory(K0, Key, KeyLen); - } else { - RT_MD5(Key, KeyLen, K0); - } - - /* Exclusive-Or K0 with ipad */ - /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ - for (index = 0; index < MD5_BLOCK_SIZE; index++) - K0[index] ^= 0x36; - /* End of for */ - - MD5_Init(&md5_ctx1); - /* H(K0^ipad) */ - MD5_Append(&md5_ctx1, K0, sizeof(K0)); - /* H((K0^ipad)||text) */ - MD5_Append(&md5_ctx1, Message, MessageLen); - MD5_End(&md5_ctx1, Digest); - - /* Exclusive-Or K0 with opad and remove ipad */ - /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ - for (index = 0; index < MD5_BLOCK_SIZE; index++) - K0[index] ^= 0x36 ^ 0x5c; - /* End of for */ - - MD5_Init(&md5_ctx2); - /* H(K0^opad) */ - MD5_Append(&md5_ctx2, K0, sizeof(K0)); - /* H( (K0^opad) || H((K0^ipad)||text) ) */ - MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE); - MD5_End(&md5_ctx2, Digest); - - if (MACLen > MD5_DIGEST_SIZE) - NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE); - else - NdisMoveMemory(MAC, Digest, MACLen); -} /* End of HMAC_SHA256 */ -#endif /* HMAC_MD5_SUPPORT */ - -/* End of crypt_hmac.c */ diff --git a/drivers/staging/rt2860/common/crypt_md5.c b/drivers/staging/rt2860/common/crypt_md5.c deleted file mode 100644 index 6deab659c22b..000000000000 --- a/drivers/staging/rt2860/common/crypt_md5.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - *************************************************************************/ - -#include "../crypt_md5.h" - -#ifdef MD5_SUPPORT -/* - * F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) -#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */ - -#define ROUND1(a, b, c, d, x, s, ac) { \ - (a) += F((b),(c),(d)) + (x) + (u32)(ac); \ - (a) = ROTL32((a),(s)); \ - (a) += (b); \ -} -#define ROUND2(a, b, c, d, x, s, ac) { \ - (a) += G((b),(c),(d)) + (x) + (u32)(ac); \ - (a) = ROTL32((a),(s)); \ - (a) += (b); \ -} -#define ROUND3(a, b, c, d, x, s, ac) { \ - (a) += H((b),(c),(d)) + (x) + (u32)(ac); \ - (a) = ROTL32((a),(s)); \ - (a) += (b); \ -} -#define ROUND4(a, b, c, d, x, s, ac) { \ - (a) += I((b),(c),(d)) + (x) + (u32)(ac); \ - (a) = ROTL32((a),(s)); \ - (a) += (b); \ -} -static const u32 MD5_DefaultHashValue[4] = { - 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL -}; -#endif /* MD5_SUPPORT */ - -#ifdef MD5_SUPPORT -/* -======================================================================== -Routine Description: - Initial Md5_CTX_STRUC - -Arguments: - pMD5_CTX Pointer to Md5_CTX_STRUC - -Return Value: - None - -Note: - None -======================================================================== -*/ -void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX) -{ - NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue, - sizeof(MD5_DefaultHashValue)); - NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE); - pMD5_CTX->BlockLen = 0; - pMD5_CTX->MessageLen = 0; -} /* End of MD5_Init */ - -/* -======================================================================== -Routine Description: - MD5 computation for one block (512 bits) - -Arguments: - pMD5_CTX Pointer to Md5_CTX_STRUC - -Return Value: - None - -Note: - T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round -======================================================================== -*/ -void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX) -{ - u32 X_i; - u32 X[16]; - u32 a, b, c, d; - - /* Prepare the message schedule, {X_i} */ - NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE); - for (X_i = 0; X_i < 16; X_i++) - X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */ - /* End of for */ - - /* MD5 hash computation */ - /* Initialize the working variables */ - a = pMD5_CTX->HashValue[0]; - b = pMD5_CTX->HashValue[1]; - c = pMD5_CTX->HashValue[2]; - d = pMD5_CTX->HashValue[3]; - - /* - * Round 1 - * Let [abcd k s i] denote the operation - * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s) - */ - ROUND1(a, b, c, d, X[0], 7, 0xd76aa478); /* 1 */ - ROUND1(d, a, b, c, X[1], 12, 0xe8c7b756); /* 2 */ - ROUND1(c, d, a, b, X[2], 17, 0x242070db); /* 3 */ - ROUND1(b, c, d, a, X[3], 22, 0xc1bdceee); /* 4 */ - ROUND1(a, b, c, d, X[4], 7, 0xf57c0faf); /* 5 */ - ROUND1(d, a, b, c, X[5], 12, 0x4787c62a); /* 6 */ - ROUND1(c, d, a, b, X[6], 17, 0xa8304613); /* 7 */ - ROUND1(b, c, d, a, X[7], 22, 0xfd469501); /* 8 */ - ROUND1(a, b, c, d, X[8], 7, 0x698098d8); /* 9 */ - ROUND1(d, a, b, c, X[9], 12, 0x8b44f7af); /* 10 */ - ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */ - ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */ - ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */ - ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */ - ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */ - ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */ - - /* - * Round 2 - * Let [abcd k s i] denote the operation - * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s) - */ - ROUND2(a, b, c, d, X[1], 5, 0xf61e2562); /* 17 */ - ROUND2(d, a, b, c, X[6], 9, 0xc040b340); /* 18 */ - ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */ - ROUND2(b, c, d, a, X[0], 20, 0xe9b6c7aa); /* 20 */ - ROUND2(a, b, c, d, X[5], 5, 0xd62f105d); /* 21 */ - ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */ - ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */ - ROUND2(b, c, d, a, X[4], 20, 0xe7d3fbc8); /* 24 */ - ROUND2(a, b, c, d, X[9], 5, 0x21e1cde6); /* 25 */ - ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */ - ROUND2(c, d, a, b, X[3], 14, 0xf4d50d87); /* 27 */ - ROUND2(b, c, d, a, X[8], 20, 0x455a14ed); /* 28 */ - ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */ - ROUND2(d, a, b, c, X[2], 9, 0xfcefa3f8); /* 30 */ - ROUND2(c, d, a, b, X[7], 14, 0x676f02d9); /* 31 */ - ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */ - - /* - * Round 3 - * Let [abcd k s t] denote the operation - * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s) - */ - ROUND3(a, b, c, d, X[5], 4, 0xfffa3942); /* 33 */ - ROUND3(d, a, b, c, X[8], 11, 0x8771f681); /* 34 */ - ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */ - ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */ - ROUND3(a, b, c, d, X[1], 4, 0xa4beea44); /* 37 */ - ROUND3(d, a, b, c, X[4], 11, 0x4bdecfa9); /* 38 */ - ROUND3(c, d, a, b, X[7], 16, 0xf6bb4b60); /* 39 */ - ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */ - ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */ - ROUND3(d, a, b, c, X[0], 11, 0xeaa127fa); /* 42 */ - ROUND3(c, d, a, b, X[3], 16, 0xd4ef3085); /* 43 */ - ROUND3(b, c, d, a, X[6], 23, 0x4881d05); /* 44 */ - ROUND3(a, b, c, d, X[9], 4, 0xd9d4d039); /* 45 */ - ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */ - ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */ - ROUND3(b, c, d, a, X[2], 23, 0xc4ac5665); /* 48 */ - - /* - * Round 4 - * Let [abcd k s t] denote the operation - * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s) - */ - ROUND4(a, b, c, d, X[0], 6, 0xf4292244); /* 49 */ - ROUND4(d, a, b, c, X[7], 10, 0x432aff97); /* 50 */ - ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */ - ROUND4(b, c, d, a, X[5], 21, 0xfc93a039); /* 52 */ - ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */ - ROUND4(d, a, b, c, X[3], 10, 0x8f0ccc92); /* 54 */ - ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */ - ROUND4(b, c, d, a, X[1], 21, 0x85845dd1); /* 56 */ - ROUND4(a, b, c, d, X[8], 6, 0x6fa87e4f); /* 57 */ - ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */ - ROUND4(c, d, a, b, X[6], 15, 0xa3014314); /* 59 */ - ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */ - ROUND4(a, b, c, d, X[4], 6, 0xf7537e82); /* 61 */ - ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */ - ROUND4(c, d, a, b, X[2], 15, 0x2ad7d2bb); /* 63 */ - ROUND4(b, c, d, a, X[9], 21, 0xeb86d391); /* 64 */ - - /* Compute the i^th intermediate hash value H^(i) */ - pMD5_CTX->HashValue[0] += a; - pMD5_CTX->HashValue[1] += b; - pMD5_CTX->HashValue[2] += c; - pMD5_CTX->HashValue[3] += d; - - NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE); - pMD5_CTX->BlockLen = 0; -} /* End of MD5_Hash */ - -/* -======================================================================== -Routine Description: - The message is appended to block. If block size > 64 bytes, the MD5_Hash -will be called. - -Arguments: - pMD5_CTX Pointer to struct rt_md5_ctx_struc - message Message context - messageLen The length of message in bytes - -Return Value: - None - -Note: - None -======================================================================== -*/ -void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX, - IN const u8 Message[], u32 MessageLen) -{ - u32 appendLen = 0; - u32 diffLen = 0; - - while (appendLen != MessageLen) { - diffLen = MessageLen - appendLen; - if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) { - NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, - Message + appendLen, diffLen); - pMD5_CTX->BlockLen += diffLen; - appendLen += diffLen; - } else { - NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, - Message + appendLen, - MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); - appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); - pMD5_CTX->BlockLen = MD5_BLOCK_SIZE; - MD5_Hash(pMD5_CTX); - } /* End of if */ - } /* End of while */ - pMD5_CTX->MessageLen += MessageLen; -} /* End of MD5_Append */ - -/* -======================================================================== -Routine Description: - 1. Append bit 1 to end of the message - 2. Append the length of message in rightmost 64 bits - 3. Transform the Hash Value to digest message - -Arguments: - pMD5_CTX Pointer to struct rt_md5_ctx_struc - -Return Value: - digestMessage Digest message - -Note: - None -======================================================================== -*/ -void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[]) -{ - u32 index; - u64 message_length_bits; - - /* append 1 bits to end of the message */ - NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80); - - /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ - if (pMD5_CTX->BlockLen > 55) - MD5_Hash(pMD5_CTX); - /* End of if */ - - /* Append the length of message in rightmost 64 bits */ - message_length_bits = pMD5_CTX->MessageLen * 8; - message_length_bits = cpu2le64(message_length_bits); - NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8); - MD5_Hash(pMD5_CTX); - - /* Return message digest, transform the u32 hash value to bytes */ - for (index = 0; index < 4; index++) - pMD5_CTX->HashValue[index] = - cpu2le32(pMD5_CTX->HashValue[index]); - /* End of for */ - NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE); -} /* End of MD5_End */ - -/* -======================================================================== -Routine Description: - MD5 algorithm - -Arguments: - message Message context - messageLen The length of message in bytes - -Return Value: - digestMessage Digest message - -Note: - None -======================================================================== -*/ -void RT_MD5(IN const u8 Message[], - u32 MessageLen, u8 DigestMessage[]) -{ - struct rt_md5_ctx_struc md5_ctx; - - NdisZeroMemory(&md5_ctx, sizeof(struct rt_md5_ctx_struc)); - MD5_Init(&md5_ctx); - MD5_Append(&md5_ctx, Message, MessageLen); - MD5_End(&md5_ctx, DigestMessage); -} /* End of RT_MD5 */ - -#endif /* MD5_SUPPORT */ - -/* End of crypt_md5.c */ diff --git a/drivers/staging/rt2860/common/crypt_sha2.c b/drivers/staging/rt2860/common/crypt_sha2.c deleted file mode 100644 index fa83fb287fe5..000000000000 --- a/drivers/staging/rt2860/common/crypt_sha2.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - *************************************************************************/ - -#include "../crypt_sha2.h" - -/* Basic operations */ -#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */ -#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */ -#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */ -#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */ -#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */ - -/* Basic functions */ -#define Ch(x,y,z) ((x & y) ^ ((~x) & z)) -#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) -#define Parity(x,y,z) (x ^ y ^ z) - -#ifdef SHA1_SUPPORT -/* SHA1 constants */ -#define SHA1_MASK 0x0000000f -static const u32 SHA1_K[4] = { - 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL -}; - -static const u32 SHA1_DefaultHashValue[5] = { - 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL -}; - -/* -======================================================================== -Routine Description: - Initial struct rt_sha1_ctx - -Arguments: - pSHA_CTX Pointer to struct rt_sha1_ctx - -Return Value: - None - -Note: - None -======================================================================== -*/ -void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX) -{ - NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue, - sizeof(SHA1_DefaultHashValue)); - NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE); - pSHA_CTX->MessageLen = 0; - pSHA_CTX->BlockLen = 0; -} /* End of RT_SHA1_Init */ - -/* -======================================================================== -Routine Description: - SHA1 computation for one block (512 bits) - -Arguments: - pSHA_CTX Pointer to struct rt_sha1_ctx - -Return Value: - None - -Note: - None -======================================================================== -*/ -void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX) -{ - u32 W_i, t, s; - u32 W[16]; - u32 a, b, c, d, e, T, f_t = 0; - - /* Prepare the message schedule, {W_i}, 0 < t < 15 */ - NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE); - for (W_i = 0; W_i < 16; W_i++) - W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ - /* End of for */ - - /* SHA256 hash computation */ - /* Initialize the working variables */ - a = pSHA_CTX->HashValue[0]; - b = pSHA_CTX->HashValue[1]; - c = pSHA_CTX->HashValue[2]; - d = pSHA_CTX->HashValue[3]; - e = pSHA_CTX->HashValue[4]; - - /* 80 rounds */ - for (t = 0; t < 80; t++) { - s = t & SHA1_MASK; - if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */ - W[s] = - (W[(s + 13) & SHA1_MASK]) ^ (W[(s + 8) & SHA1_MASK]) - ^ (W[(s + 2) & SHA1_MASK]) ^ W[s]; - W[s] = ROTL32(W[s], 1); - } /* End of if */ - switch (t / 20) { - case 0: - f_t = Ch(b, c, d); - break; - case 1: - f_t = Parity(b, c, d); - break; - case 2: - f_t = Maj(b, c, d); - break; - case 3: - f_t = Parity(b, c, d); - break; - } /* End of switch */ - T = ROTL32(a, 5) + f_t + e + SHA1_K[t / 20] + W[s]; - e = d; - d = c; - c = ROTL32(b, 30); - b = a; - a = T; - } /* End of for */ - - /* Compute the i^th intermediate hash value H^(i) */ - pSHA_CTX->HashValue[0] += a; - pSHA_CTX->HashValue[1] += b; - pSHA_CTX->HashValue[2] += c; - pSHA_CTX->HashValue[3] += d; - pSHA_CTX->HashValue[4] += e; - - NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE); - pSHA_CTX->BlockLen = 0; -} /* End of SHA1_Hash */ - -/* -======================================================================== -Routine Description: - The message is appended to block. If block size > 64 bytes, the SHA1_Hash -will be called. - -Arguments: - pSHA_CTX Pointer to struct rt_sha1_ctx - message Message context - messageLen The length of message in bytes - -Return Value: - None - -Note: - None -======================================================================== -*/ -void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX, - IN const u8 Message[], u32 MessageLen) -{ - u32 appendLen = 0; - u32 diffLen = 0; - - while (appendLen != MessageLen) { - diffLen = MessageLen - appendLen; - if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) { - NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, - Message + appendLen, diffLen); - pSHA_CTX->BlockLen += diffLen; - appendLen += diffLen; - } else { - NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, - Message + appendLen, - SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen); - appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen); - pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE; - SHA1_Hash(pSHA_CTX); - } /* End of if */ - } /* End of while */ - pSHA_CTX->MessageLen += MessageLen; -} /* End of SHA1_Append */ - -/* -======================================================================== -Routine Description: - 1. Append bit 1 to end of the message - 2. Append the length of message in rightmost 64 bits - 3. Transform the Hash Value to digest message - -Arguments: - pSHA_CTX Pointer to struct rt_sha1_ctx - -Return Value: - digestMessage Digest message - -Note: - None -======================================================================== -*/ -void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[]) -{ - u32 index; - u64 message_length_bits; - - /* Append bit 1 to end of the message */ - NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80); - - /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ - if (pSHA_CTX->BlockLen > 55) - SHA1_Hash(pSHA_CTX); - /* End of if */ - - /* Append the length of message in rightmost 64 bits */ - message_length_bits = pSHA_CTX->MessageLen * 8; - message_length_bits = cpu2be64(message_length_bits); - NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8); - SHA1_Hash(pSHA_CTX); - - /* Return message digest, transform the u32 hash value to bytes */ - for (index = 0; index < 5; index++) - pSHA_CTX->HashValue[index] = - cpu2be32(pSHA_CTX->HashValue[index]); - /* End of for */ - NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE); -} /* End of SHA1_End */ - -/* -======================================================================== -Routine Description: - SHA1 algorithm - -Arguments: - message Message context - messageLen The length of message in bytes - -Return Value: - digestMessage Digest message - -Note: - None -======================================================================== -*/ -void RT_SHA1(IN const u8 Message[], - u32 MessageLen, u8 DigestMessage[]) -{ - - struct rt_sha1_ctx sha_ctx; - - NdisZeroMemory(&sha_ctx, sizeof(struct rt_sha1_ctx)); - RT_SHA1_Init(&sha_ctx); - SHA1_Append(&sha_ctx, Message, MessageLen); - SHA1_End(&sha_ctx, DigestMessage); -} /* End of RT_SHA1 */ -#endif /* SHA1_SUPPORT */ - -/* End of crypt_sha2.c */ diff --git a/drivers/staging/rt2860/common/dfs.c b/drivers/staging/rt2860/common/dfs.c deleted file mode 100644 index 71cbb2665243..000000000000 --- a/drivers/staging/rt2860/common/dfs.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - ap_dfs.c - - Abstract: - Support DFS function. - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -/* - ======================================================================== - - Routine Description: - Radar channel check routine - - Arguments: - pAd Pointer to our adapter - - Return Value: - TRUE need to do radar detect - FALSE need not to do radar detect - - ======================================================================== -*/ -BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch) -{ - int i; - BOOLEAN result = FALSE; - - for (i = 0; i < pAd->ChannelListNum; i++) { - if (Ch == pAd->ChannelList[i].Channel) { - result = pAd->ChannelList[i].DfsReq; - break; - } - } - - return result; -} diff --git a/drivers/staging/rt2860/common/ee_efuse.c b/drivers/staging/rt2860/common/ee_efuse.c deleted file mode 100644 index fed0ba452271..000000000000 --- a/drivers/staging/rt2860/common/ee_efuse.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - ee_efuse.c - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -#define EFUSE_USAGE_MAP_START 0x2d0 -#define EFUSE_USAGE_MAP_END 0x2fc -#define EFUSE_USAGE_MAP_SIZE 45 - -#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin" -#define MAX_EEPROM_BIN_FILE_SIZE 1024 - -#define EFUSE_TAG 0x2fe - -typedef union _EFUSE_CTRL_STRUC { - struct { - u32 EFSROM_AOUT:6; - u32 EFSROM_MODE:2; - u32 EFSROM_LDO_OFF_TIME:6; - u32 EFSROM_LDO_ON_TIME:2; - u32 EFSROM_AIN:10; - u32 RESERVED:4; - u32 EFSROM_KICK:1; - u32 SEL_EFUSE:1; - } field; - u32 word; -} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC; - -/* -======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - -======================================================================== -*/ -u8 eFuseReadRegisters(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 Length, u16 * pData) -{ - EFUSE_CTRL_STRUC eFuseCtrlStruc; - int i; - u16 efuseDataOffset; - u32 data; - - RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); - - /*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */ - /*Use the eeprom logical address and covert to address to block number */ - eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; - - /*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0. */ - eFuseCtrlStruc.field.EFSROM_MODE = 0; - - /*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */ - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */ - i = 0; - while (i < 500) { - /*rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); */ - RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); - if (eFuseCtrlStruc.field.EFSROM_KICK == 0) { - break; - } - RTMPusecDelay(2); - i++; - } - - /*if EFSROM_AOUT is not found in physical address, write 0xffff */ - if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) { - for (i = 0; i < Length / 2; i++) - *(pData + 2 * i) = 0xffff; - } else { - /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C) */ - efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC); - /*data hold 4 bytes data. */ - /*In RTMP_IO_READ32 will automatically execute 32-bytes swapping */ - RTMP_IO_READ32(pAd, efuseDataOffset, &data); - /*Decide the upper 2 bytes or the bottom 2 bytes. */ - /* Little-endian S | S Big-endian */ - /* addr 3 2 1 0 | 0 1 2 3 */ - /* Ori-V D C B A | A B C D */ - /*After swapping */ - /* D C B A | D C B A */ - /*Return 2-bytes */ - /*The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC. */ - /*For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes. */ - data = data >> (8 * (Offset & 0x3)); - - NdisMoveMemory(pData, &data, Length); - } - - return (u8)eFuseCtrlStruc.field.EFSROM_AOUT; - -} - -/* -======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - -======================================================================== -*/ -void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd, - u16 Offset, - u16 Length, u16 * pData) -{ - EFUSE_CTRL_STRUC eFuseCtrlStruc; - int i; - u16 efuseDataOffset; - u32 data; - - RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); - - /*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */ - eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; - - /*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. */ - /*Read in physical view */ - eFuseCtrlStruc.field.EFSROM_MODE = 1; - - /*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */ - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */ - i = 0; - while (i < 500) { - RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); - if (eFuseCtrlStruc.field.EFSROM_KICK == 0) - break; - RTMPusecDelay(2); - i++; - } - - /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) */ - /*Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits. */ - /*The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes */ - /*Decide which EFUSE_DATA to read */ - /*590:F E D C */ - /*594:B A 9 8 */ - /*598:7 6 5 4 */ - /*59C:3 2 1 0 */ - efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC); - - RTMP_IO_READ32(pAd, efuseDataOffset, &data); - - data = data >> (8 * (Offset & 0x3)); - - NdisMoveMemory(pData, &data, Length); - -} - -/* -======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - -======================================================================== -*/ -static void eFuseReadPhysical(struct rt_rtmp_adapter *pAd, - u16 *lpInBuffer, - unsigned long nInBufferSize, - u16 *lpOutBuffer, unsigned long nOutBufferSize) -{ - u16 *pInBuf = (u16 *) lpInBuffer; - u16 *pOutBuf = (u16 *) lpOutBuffer; - - u16 Offset = pInBuf[0]; /*addr */ - u16 Length = pInBuf[1]; /*length */ - int i; - - for (i = 0; i < Length; i += 2) { - eFusePhysicalReadRegisters(pAd, Offset + i, 2, &pOutBuf[i / 2]); - } -} - -/* -======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - -======================================================================== -*/ -int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg) -{ - u16 i; - u16 LogicalAddress; - u16 efusefreenum = 0; - if (!pAd->bUseEfuse) - return FALSE; - for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) { - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if ((LogicalAddress & 0xff) == 0) { - efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i + 1); - break; - } else if (((LogicalAddress >> 8) & 0xff) == 0) { - efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i); - break; - } - - if (i == EFUSE_USAGE_MAP_END) - efusefreenum = 0; - } - printk(KERN_DEBUG "efuseFreeNumber is %d\n", efusefreenum); - return TRUE; -} - -int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg) -{ - u16 InBuf[3]; - int i = 0; - if (!pAd->bUseEfuse) - return FALSE; - - printk(KERN_DEBUG "Block 0: "); - - for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) { - InBuf[0] = 2 * i; - InBuf[1] = 2; - InBuf[2] = 0x0; - - eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - if (i && i % 4 == 0) { - printk(KERN_CONT "\n"); - printk(KERN_DEBUG "Block %x:", i / 8); - } - printk(KERN_CONT "%04x ", InBuf[2]); - } - printk(KERN_CONT "\n"); - - return TRUE; -} - -int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 * pValue) -{ - eFuseReadRegisters(pAd, Offset, 2, pValue); - return (*pValue); -} - -int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd) -{ - u16 value; - - if (IS_RT30xx(pAd)) { - eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value); - pAd->EFuseTag = (value & 0xff); - } - return 0; -} - -void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock) -{ - u16 i; - u16 LogicalAddress; - if (!pAd->bUseEfuse) { - DBGPRINT(RT_DEBUG_TRACE, - ("eFuseGetFreeBlockCount Only supports efuse Mode\n")); - return; - } - for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) { - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if ((LogicalAddress & 0xff) == 0) { - *EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i + 1); - break; - } else if (((LogicalAddress >> 8) & 0xff) == 0) { - *EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i); - break; - } - - if (i == EFUSE_USAGE_MAP_END) - *EfuseFreeBlock = 0; - } - DBGPRINT(RT_DEBUG_TRACE, - ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock)); -} - -int eFuse_init(struct rt_rtmp_adapter *pAd) -{ - u32 EfuseFreeBlock = 0; - DBGPRINT(RT_DEBUG_ERROR, - ("NVM is Efuse and its size =%x[%x-%x] \n", - EFUSE_USAGE_MAP_SIZE, EFUSE_USAGE_MAP_START, - EFUSE_USAGE_MAP_END)); - eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock); - - return 0; -} diff --git a/drivers/staging/rt2860/common/ee_prom.c b/drivers/staging/rt2860/common/ee_prom.c deleted file mode 100644 index 2083740a844b..000000000000 --- a/drivers/staging/rt2860/common/ee_prom.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - ee_prom.c - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -/* IRQL = PASSIVE_LEVEL */ -static inline void RaiseClock(struct rt_rtmp_adapter *pAd, u32 * x) -{ - *x = *x | EESK; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); - RTMPusecDelay(1); /* Max frequency = 1MHz in Spec. definition */ -} - -/* IRQL = PASSIVE_LEVEL */ -static inline void LowerClock(struct rt_rtmp_adapter *pAd, u32 * x) -{ - *x = *x & ~EESK; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); - RTMPusecDelay(1); -} - -/* IRQL = PASSIVE_LEVEL */ -static inline u16 ShiftInBits(struct rt_rtmp_adapter *pAd) -{ - u32 x, i; - u16 data = 0; - - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - x &= ~(EEDO | EEDI); - - for (i = 0; i < 16; i++) { - data = data << 1; - RaiseClock(pAd, &x); - - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - LowerClock(pAd, &x); /*prevent read failed */ - - x &= ~(EEDI); - if (x & EEDO) - data |= 1; - } - - return data; -} - -/* IRQL = PASSIVE_LEVEL */ -static inline void ShiftOutBits(struct rt_rtmp_adapter *pAd, - u16 data, u16 count) -{ - u32 x, mask; - - mask = 0x01 << (count - 1); - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - x &= ~(EEDO | EEDI); - - do { - x &= ~EEDI; - if (data & mask) - x |= EEDI; - - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - - mask = mask >> 1; - } while (mask); - - x &= ~EEDI; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); -} - -/* IRQL = PASSIVE_LEVEL */ -static inline void EEpromCleanup(struct rt_rtmp_adapter *pAd) -{ - u32 x; - - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - x &= ~(EECS | EEDI); - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - RaiseClock(pAd, &x); - LowerClock(pAd, &x); -} - -static inline void EWEN(struct rt_rtmp_adapter *pAd) -{ - u32 x; - - /* reset bits and set EECS */ - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - /* kick a pulse */ - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - - /* output the read_opcode and six pulse in that order */ - ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5); - ShiftOutBits(pAd, 0, 6); - - EEpromCleanup(pAd); -} - -static inline void EWDS(struct rt_rtmp_adapter *pAd) -{ - u32 x; - - /* reset bits and set EECS */ - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - /* kick a pulse */ - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - - /* output the read_opcode and six pulse in that order */ - ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5); - ShiftOutBits(pAd, 0, 6); - - EEpromCleanup(pAd); -} - -/* IRQL = PASSIVE_LEVEL */ -int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 * pValue) -{ - u32 x; - u16 data; - - Offset /= 2; - /* reset bits and set EECS */ - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - /* patch can not access e-Fuse issue */ - if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) { - /* kick a pulse */ - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - } - /* output the read_opcode and register number in that order */ - ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3); - ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); - - /* Now read the data (16 bits) in from the selected EEPROM word */ - data = ShiftInBits(pAd); - - EEpromCleanup(pAd); - - *pValue = data; - - return NDIS_STATUS_SUCCESS; -} diff --git a/drivers/staging/rt2860/common/eeprom.c b/drivers/staging/rt2860/common/eeprom.c deleted file mode 100644 index 94670076d32b..000000000000 --- a/drivers/staging/rt2860/common/eeprom.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - eeprom.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs -*/ -#include "../rt_config.h" - -int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType) -{ - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; -#ifdef RT30xx -#ifdef RTMP_EFUSE_SUPPORT - u32 eFuseCtrl, MacCsr0; - int index; - - index = 0; - do { - RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); - pAd->MACVersion = MacCsr0; - - if ((pAd->MACVersion != 0x00) - && (pAd->MACVersion != 0xFFFFFFFF)) - break; - - RTMPusecDelay(10); - } while (index++ < 100); - - pAd->bUseEfuse = FALSE; - RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl); - pAd->bUseEfuse = ((eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0; - if (pAd->bUseEfuse) { - pChipOps->eeinit = eFuse_init; - pChipOps->eeread = rtmp_ee_efuse_read16; - return 0; - } else - DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n")); -#endif /* RTMP_EFUSE_SUPPORT // */ -#endif /* RT30xx // */ - - switch (infType) { -#ifdef RTMP_PCI_SUPPORT - case RTMP_DEV_INF_PCI: - pChipOps->eeinit = NULL; - pChipOps->eeread = rtmp_ee_prom_read16; - break; -#endif /* RTMP_PCI_SUPPORT // */ -#ifdef RTMP_USB_SUPPORT - case RTMP_DEV_INF_USB: - pChipOps->eeinit = NULL; - pChipOps->eeread = RTUSBReadEEPROM16; - break; -#endif /* RTMP_USB_SUPPORT // */ - - default: - DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n")); - break; - } - - return 0; -} diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c deleted file mode 100644 index e48eac0f3a29..000000000000 --- a/drivers/staging/rt2860/common/mlme.c +++ /dev/null @@ -1,6068 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - mlme.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John Chang 2004-08-25 Modify from RT2500 code base - John Chang 2004-09-06 modified for RT2600 -*/ - -#include "../rt_config.h" -#include -#include - -u8 CISCO_OUI[] = { 0x00, 0x40, 0x96 }; - -u8 WPA_OUI[] = { 0x00, 0x50, 0xf2, 0x01 }; -u8 RSN_OUI[] = { 0x00, 0x0f, 0xac }; -u8 WME_INFO_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01 }; -u8 WME_PARM_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01 }; -u8 Ccx2QosInfo[] = { 0x00, 0x40, 0x96, 0x04 }; -u8 RALINK_OUI[] = { 0x00, 0x0c, 0x43 }; -u8 BROADCOM_OUI[] = { 0x00, 0x90, 0x4c }; -u8 WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 }; -u8 PRE_N_HT_OUI[] = { 0x00, 0x90, 0x4c }; - -u8 RateSwitchTable[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x11, 0x00, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 35, 45, - 0x03, 0x00, 3, 20, 45, - 0x04, 0x21, 0, 30, 50, - 0x05, 0x21, 1, 20, 50, - 0x06, 0x21, 2, 20, 50, - 0x07, 0x21, 3, 15, 50, - 0x08, 0x21, 4, 15, 30, - 0x09, 0x21, 5, 10, 25, - 0x0a, 0x21, 6, 8, 25, - 0x0b, 0x21, 7, 8, 25, - 0x0c, 0x20, 12, 15, 30, - 0x0d, 0x20, 13, 8, 20, - 0x0e, 0x20, 14, 8, 20, - 0x0f, 0x20, 15, 8, 25, - 0x10, 0x22, 15, 8, 25, - 0x11, 0x00, 0, 0, 0, - 0x12, 0x00, 0, 0, 0, - 0x13, 0x00, 0, 0, 0, - 0x14, 0x00, 0, 0, 0, - 0x15, 0x00, 0, 0, 0, - 0x16, 0x00, 0, 0, 0, - 0x17, 0x00, 0, 0, 0, - 0x18, 0x00, 0, 0, 0, - 0x19, 0x00, 0, 0, 0, - 0x1a, 0x00, 0, 0, 0, - 0x1b, 0x00, 0, 0, 0, - 0x1c, 0x00, 0, 0, 0, - 0x1d, 0x00, 0, 0, 0, - 0x1e, 0x00, 0, 0, 0, - 0x1f, 0x00, 0, 0, 0, -}; - -u8 RateSwitchTable11B[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x04, 0x03, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 35, 45, - 0x03, 0x00, 3, 20, 45, -}; - -u8 RateSwitchTable11BG[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0a, 0x00, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 35, 45, - 0x03, 0x00, 3, 20, 45, - 0x04, 0x10, 2, 20, 35, - 0x05, 0x10, 3, 16, 35, - 0x06, 0x10, 4, 10, 25, - 0x07, 0x10, 5, 16, 25, - 0x08, 0x10, 6, 10, 25, - 0x09, 0x10, 7, 10, 13, -}; - -u8 RateSwitchTable11G[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x08, 0x00, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x10, 0, 20, 101, - 0x01, 0x10, 1, 20, 35, - 0x02, 0x10, 2, 20, 35, - 0x03, 0x10, 3, 16, 35, - 0x04, 0x10, 4, 10, 25, - 0x05, 0x10, 5, 16, 25, - 0x06, 0x10, 6, 10, 25, - 0x07, 0x10, 7, 10, 13, -}; - -u8 RateSwitchTable11N1S[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0c, 0x0a, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 25, 45, - 0x03, 0x21, 0, 20, 35, - 0x04, 0x21, 1, 20, 35, - 0x05, 0x21, 2, 20, 35, - 0x06, 0x21, 3, 15, 35, - 0x07, 0x21, 4, 15, 30, - 0x08, 0x21, 5, 10, 25, - 0x09, 0x21, 6, 8, 14, - 0x0a, 0x21, 7, 8, 14, - 0x0b, 0x23, 7, 8, 14, -}; - -u8 RateSwitchTable11N2S[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0e, 0x0c, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 25, 45, - 0x03, 0x21, 0, 20, 35, - 0x04, 0x21, 1, 20, 35, - 0x05, 0x21, 2, 20, 35, - 0x06, 0x21, 3, 15, 35, - 0x07, 0x21, 4, 15, 30, - 0x08, 0x20, 11, 15, 30, - 0x09, 0x20, 12, 15, 30, - 0x0a, 0x20, 13, 8, 20, - 0x0b, 0x20, 14, 8, 20, - 0x0c, 0x20, 15, 8, 25, - 0x0d, 0x22, 15, 8, 15, -}; - -u8 RateSwitchTable11N3S[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0b, 0x00, 0, 0, 0, /* 0x0a, 0x00, 0, 0, 0, // Initial used item after association */ - 0x00, 0x21, 0, 30, 101, - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x20, 11, 15, 30, /* Required by System-Alan @ 20080812 */ - 0x06, 0x20, 12, 15, 30, /* 0x05, 0x20, 12, 15, 30, */ - 0x07, 0x20, 13, 8, 20, /* 0x06, 0x20, 13, 8, 20, */ - 0x08, 0x20, 14, 8, 20, /* 0x07, 0x20, 14, 8, 20, */ - 0x09, 0x20, 15, 8, 25, /* 0x08, 0x20, 15, 8, 25, */ - 0x0a, 0x22, 15, 8, 25, /* 0x09, 0x22, 15, 8, 25, */ -}; - -u8 RateSwitchTable11N2SForABand[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0b, 0x09, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x21, 0, 30, 101, - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x21, 5, 15, 30, - 0x06, 0x20, 12, 15, 30, - 0x07, 0x20, 13, 8, 20, - 0x08, 0x20, 14, 8, 20, - 0x09, 0x20, 15, 8, 25, - 0x0a, 0x22, 15, 8, 25, -}; - -u8 RateSwitchTable11N3SForABand[] = { /* 3*3 */ -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0b, 0x09, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x21, 0, 30, 101, - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x21, 5, 15, 30, - 0x06, 0x20, 12, 15, 30, - 0x07, 0x20, 13, 8, 20, - 0x08, 0x20, 14, 8, 20, - 0x09, 0x20, 15, 8, 25, - 0x0a, 0x22, 15, 8, 25, -}; - -u8 RateSwitchTable11BGN1S[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0c, 0x0a, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 25, 45, - 0x03, 0x21, 0, 20, 35, - 0x04, 0x21, 1, 20, 35, - 0x05, 0x21, 2, 20, 35, - 0x06, 0x21, 3, 15, 35, - 0x07, 0x21, 4, 15, 30, - 0x08, 0x21, 5, 10, 25, - 0x09, 0x21, 6, 8, 14, - 0x0a, 0x21, 7, 8, 14, - 0x0b, 0x23, 7, 8, 14, -}; - -u8 RateSwitchTable11BGN2S[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0e, 0x0c, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x00, 0, 40, 101, - 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 25, 45, - 0x03, 0x21, 0, 20, 35, - 0x04, 0x21, 1, 20, 35, - 0x05, 0x21, 2, 20, 35, - 0x06, 0x21, 3, 15, 35, - 0x07, 0x21, 4, 15, 30, - 0x08, 0x20, 11, 15, 30, - 0x09, 0x20, 12, 15, 30, - 0x0a, 0x20, 13, 8, 20, - 0x0b, 0x20, 14, 8, 20, - 0x0c, 0x20, 15, 8, 25, - 0x0d, 0x22, 15, 8, 15, -}; - -u8 RateSwitchTable11BGN3S[] = { /* 3*3 */ -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0a, 0x00, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x21, 0, 30, 101, /*50 */ - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 20, 50, - 0x04, 0x21, 4, 15, 50, - 0x05, 0x20, 20, 15, 30, - 0x06, 0x20, 21, 8, 20, - 0x07, 0x20, 22, 8, 20, - 0x08, 0x20, 23, 8, 25, - 0x09, 0x22, 23, 8, 25, -}; - -u8 RateSwitchTable11BGN2SForABand[] = { -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0b, 0x09, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x21, 0, 30, 101, /*50 */ - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x21, 5, 15, 30, - 0x06, 0x20, 12, 15, 30, - 0x07, 0x20, 13, 8, 20, - 0x08, 0x20, 14, 8, 20, - 0x09, 0x20, 15, 8, 25, - 0x0a, 0x22, 15, 8, 25, -}; - -u8 RateSwitchTable11BGN3SForABand[] = { /* 3*3 */ -/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */ - 0x0c, 0x09, 0, 0, 0, /* Initial used item after association */ - 0x00, 0x21, 0, 30, 101, /*50 */ - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x21, 5, 15, 30, - 0x06, 0x21, 12, 15, 30, - 0x07, 0x20, 20, 15, 30, - 0x08, 0x20, 21, 8, 20, - 0x09, 0x20, 22, 8, 20, - 0x0a, 0x20, 23, 8, 25, - 0x0b, 0x22, 23, 8, 25, -}; - -extern u8 OfdmRateToRxwiMCS[]; -/* since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. */ -/* otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate */ -unsigned long BasicRateMask[12] = - { 0xfffff001 /* 1-Mbps */ , 0xfffff003 /* 2 Mbps */ , 0xfffff007 /* 5.5 */ , -0xfffff00f /* 11 */ , - 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , - 0xfffff0ff /* 18 */ , - 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , - 0xffffffff /* 54 */ -}; - -u8 BROADCAST_ADDR[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -u8 ZERO_MAC_ADDR[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -/* e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than */ -/* this value, then it's quaranteed capable of operating in 36 mbps TX rate in */ -/* clean environment. */ -/* TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100 */ -char RssiSafeLevelForTxRate[] = - { -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 }; - -u8 RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100 }; -u16 RateIdTo500Kbps[] = - { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200 }; - -u8 SsidIe = IE_SSID; -u8 SupRateIe = IE_SUPP_RATES; -u8 ExtRateIe = IE_EXT_SUPP_RATES; -u8 HtCapIe = IE_HT_CAP; -u8 AddHtInfoIe = IE_ADD_HT; -u8 NewExtChanIe = IE_SECONDARY_CH_OFFSET; -u8 ErpIe = IE_ERP; -u8 DsIe = IE_DS_PARM; -u8 TimIe = IE_TIM; -u8 WpaIe = IE_WPA; -u8 Wpa2Ie = IE_WPA2; -u8 IbssIe = IE_IBSS_PARM; - -extern u8 WPA_OUI[]; - -u8 SES_OUI[] = { 0x00, 0x90, 0x4c }; - -u8 ZeroSsid[32] = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -/* - ========================================================================== - Description: - initialize the MLME task and its data structure (queue, spinlock, - timer, state machines). - - IRQL = PASSIVE_LEVEL - - Return: - always return NDIS_STATUS_SUCCESS - - ========================================================================== -*/ -int MlmeInit(struct rt_rtmp_adapter *pAd) -{ - int Status = NDIS_STATUS_SUCCESS; - - DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n")); - - do { - Status = MlmeQueueInit(&pAd->Mlme.Queue); - if (Status != NDIS_STATUS_SUCCESS) - break; - - pAd->Mlme.bRunning = FALSE; - NdisAllocateSpinLock(&pAd->Mlme.TaskLock); - - { - BssTableInit(&pAd->ScanTab); - - /* init STA state machines */ - AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, - pAd->Mlme.AssocFunc); - AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, - pAd->Mlme.AuthFunc); - AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, - pAd->Mlme.AuthRspFunc); - SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, - pAd->Mlme.SyncFunc); - - /* Since we are using switch/case to implement it, the init is different from the above */ - /* state machine init */ - MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL); - } - - WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, - pAd->Mlme.WpaFunc); - - ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, - pAd->Mlme.ActFunc); - - /* Init mlme periodic timer */ - RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, - GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE); - - /* Set mlme periodic timer */ - RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV); - - /* software-based RX Antenna diversity */ - RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, - GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, - FALSE); - - { -#ifdef RTMP_PCI_SUPPORT - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - /* only PCIe cards need these two timers */ - RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, - GET_TIMER_FUNCTION - (PsPollWakeExec), pAd, FALSE); - RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, - GET_TIMER_FUNCTION(RadioOnExec), - pAd, FALSE); - } -#endif /* RTMP_PCI_SUPPORT // */ - - RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, - GET_TIMER_FUNCTION(LinkDownExec), pAd, - FALSE); - -#ifdef RTMP_MAC_USB - RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer, - GET_TIMER_FUNCTION - (RtmpUsbStaAsicForceWakeupTimeout), pAd, - FALSE); - pAd->Mlme.AutoWakeupTimerRunning = FALSE; -#endif /* RTMP_MAC_USB // */ - } - - } while (FALSE); - - DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n")); - - return Status; -} - -/* - ========================================================================== - Description: - main loop of the MLME - Pre: - Mlme has to be initialized, and there are something inside the queue - Note: - This function is invoked from MPSetInformation and MPReceive; - This task guarantee only one MlmeHandler will run. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeHandler(struct rt_rtmp_adapter *pAd) -{ - struct rt_mlme_queue_elem *Elem = NULL; - - /* Only accept MLME and Frame from peer side, no other (control/data) frame should */ - /* get into this state machine */ - - NdisAcquireSpinLock(&pAd->Mlme.TaskLock); - if (pAd->Mlme.bRunning) { - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); - return; - } else { - pAd->Mlme.bRunning = TRUE; - } - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); - - while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", - pAd->Mlme.Queue.Num)); - break; - } - /*From message type, determine which state machine I should drive */ - if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) { -#ifdef RTMP_MAC_USB - if (Elem->MsgType == MT2_RESET_CONF) { - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("reset MLME state machine!\n")); - MlmeRestartStateMachine(pAd); - Elem->Occupied = FALSE; - Elem->MsgLen = 0; - continue; - } -#endif /* RTMP_MAC_USB // */ - - /* if dequeue success */ - switch (Elem->Machine) { - /* STA state machines */ - case ASSOC_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme. - AssocMachine, Elem); - break; - case AUTH_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme. - AuthMachine, Elem); - break; - case AUTH_RSP_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme. - AuthRspMachine, Elem); - break; - case SYNC_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme. - SyncMachine, Elem); - break; - case MLME_CNTL_STATE_MACHINE: - MlmeCntlMachinePerformAction(pAd, - &pAd->Mlme. - CntlMachine, Elem); - break; - case WPA_PSK_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme. - WpaPskMachine, Elem); - break; - - case ACTION_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme.ActMachine, - Elem); - break; - - case WPA_STATE_MACHINE: - StateMachinePerformAction(pAd, - &pAd->Mlme.WpaMachine, - Elem); - break; - - default: - DBGPRINT(RT_DEBUG_TRACE, - ("ERROR: Illegal machine %ld in MlmeHandler()\n", - Elem->Machine)); - break; - } /* end of switch */ - - /* free MLME element */ - Elem->Occupied = FALSE; - Elem->MsgLen = 0; - - } else { - DBGPRINT_ERR("MlmeHandler: MlmeQueue empty\n"); - } - } - - NdisAcquireSpinLock(&pAd->Mlme.TaskLock); - pAd->Mlme.bRunning = FALSE; - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); -} - -/* - ========================================================================== - Description: - Destructor of MLME (Destroy queue, state machine, spin lock and timer) - Parameters: - Adapter - NIC Adapter pointer - Post: - The MLME task will no longer work properly - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -void MlmeHalt(struct rt_rtmp_adapter *pAd) -{ - BOOLEAN Cancelled; - - DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n")); - - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { - /* disable BEACON generation and other BEACON related hardware timers */ - AsicDisableSync(pAd); - } - - { - /* Cancel pending timers */ - RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); - -#ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - } -#endif /* RTMP_MAC_PCI // */ - - RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled); - -#ifdef RTMP_MAC_USB - RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled); -#endif /* RTMP_MAC_USB // */ - } - - RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled); - - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - - /* Set LED */ - RTMPSetLED(pAd, LED_HALT); - RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it. */ -#ifdef RTMP_MAC_USB - { - LED_CFG_STRUC LedCfg; - RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word); - LedCfg.field.LedPolar = 0; - LedCfg.field.RLedMode = 0; - LedCfg.field.GLedMode = 0; - LedCfg.field.YLedMode = 0; - RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word); - } -#endif /* RTMP_MAC_USB // */ - - if (pChipOps->AsicHaltAction) - pChipOps->AsicHaltAction(pAd); - } - - RTMPusecDelay(5000); /* 5 msec to guarantee Ant Diversity timer canceled */ - - MlmeQueueDestroy(&pAd->Mlme.Queue); - NdisFreeSpinLock(&pAd->Mlme.TaskLock); - - DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n")); -} - -void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd) -{ - pAd->RalinkCounters.LastOneSecRxOkDataCnt = - pAd->RalinkCounters.OneSecRxOkDataCnt; - /* clear all OneSecxxx counters. */ - pAd->RalinkCounters.OneSecBeaconSentCnt = 0; - pAd->RalinkCounters.OneSecFalseCCACnt = 0; - pAd->RalinkCounters.OneSecRxFcsErrCnt = 0; - pAd->RalinkCounters.OneSecRxOkCnt = 0; - pAd->RalinkCounters.OneSecTxFailCount = 0; - pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0; - pAd->RalinkCounters.OneSecTxRetryOkCount = 0; - pAd->RalinkCounters.OneSecRxOkDataCnt = 0; - pAd->RalinkCounters.OneSecReceivedByteCount = 0; - pAd->RalinkCounters.OneSecTransmittedByteCount = 0; - - /* TODO: for debug only. to be removed */ - pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0; - pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0; - pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0; - pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0; - pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0; - pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0; - pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0; - pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0; - pAd->RalinkCounters.OneSecTxDoneCount = 0; - pAd->RalinkCounters.OneSecRxCount = 0; - pAd->RalinkCounters.OneSecTxAggregationCount = 0; - pAd->RalinkCounters.OneSecRxAggregationCount = 0; - - return; -} - -/* - ========================================================================== - Description: - This routine is executed periodically to - - 1. Decide if it's a right time to turn on PwrMgmt bit of all - outgoiing frames - 2. Calculate ChannelQuality based on statistics of the last - period, so that TX rate won't toggling very frequently between a - successful TX and a failed TX. - 3. If the calculated ChannelQuality indicated current connection not - healthy, then a ROAMing attempt is tried here. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) /* 8 sec */ -void MlmePeriodicExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - unsigned long TxTotalCnt; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - -#ifdef RTMP_MAC_PCI - { - /* If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. */ - /* Move code to here, because following code will return when radio is off */ - if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == - 0) && (pAd->StaCfg.bHardwareRadio == TRUE) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) - /*&&(pAd->bPCIclkOff == FALSE) */ - ) { - u32 data = 0; - - /* Read GPIO pin2 as Hardware controlled radio state */ -#ifndef RT3090 - RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data); -#endif /* RT3090 // */ -/*KH(PCIE PS):Added based on Jane<-- */ -#ifdef RT3090 -/* Read GPIO pin2 as Hardware controlled radio state */ -/* We need to Read GPIO if HW said so no mater what advance power saving */ - if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) - && - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) - && (pAd->StaCfg.PSControl.field.EnablePSinIdle == - TRUE)) { - /* Want to make sure device goes to L0 state before reading register. */ - RTMPPCIeLinkCtrlValueRestore(pAd, 0); - RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data); - RTMPPCIeLinkCtrlSetting(pAd, 3); - } else - RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data); -#endif /* RT3090 // */ -/*KH(PCIE PS):Added based on Jane--> */ - - if (data & 0x04) { - pAd->StaCfg.bHwRadio = TRUE; - } else { - pAd->StaCfg.bHwRadio = FALSE; - } - if (pAd->StaCfg.bRadio != - (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) { - pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio - && pAd->StaCfg.bSwRadio); - if (pAd->StaCfg.bRadio == TRUE) { - MlmeRadioOn(pAd); - /* Update extra information */ - pAd->ExtraInfo = EXTRA_INFO_CLEAR; - } else { - MlmeRadioOff(pAd); - /* Update extra information */ - pAd->ExtraInfo = HW_RADIO_OFF; - } - } - } - } -#endif /* RTMP_MAC_PCI // */ - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_RADIO_MEASUREMENT | - fRTMP_ADAPTER_RESET_IN_PROGRESS)))) - return; - - RTMP_MLME_PRE_SANITY_CHECK(pAd); - - { - /* Do nothing if monitor mode is on */ - if (MONITOR_ON(pAd)) - return; - - if (pAd->Mlme.PeriodicRound & 0x1) { - /* This is the fix for wifi 11n extension channel overlapping test case. for 2860D */ - if (((pAd->MACVersion & 0xffff) == 0x0101) && - (STA_TGN_WIFI_ON(pAd)) && - (pAd->CommonCfg.IOTestParm.bToggle == FALSE)) - { - RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf); - pAd->CommonCfg.IOTestParm.bToggle = TRUE; - } else if ((STA_TGN_WIFI_ON(pAd)) && - ((pAd->MACVersion & 0xffff) == 0x0101)) { - RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f); - pAd->CommonCfg.IOTestParm.bToggle = FALSE; - } - } - } - - pAd->bUpdateBcnCntDone = FALSE; - -/* RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); */ - pAd->Mlme.PeriodicRound++; - -#ifdef RTMP_MAC_USB - /* execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. */ - NICUpdateFifoStaCounters(pAd); -#endif /* RTMP_MAC_USB // */ - - /* execute every 500ms */ - if ((pAd->Mlme.PeriodicRound % 5 == 0) - && RTMPAutoRateSwitchCheck(pAd) - /*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ ) - { - /* perform dynamic tx rate switching based on past TX history */ - { - if ((OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) - ) - && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))) - MlmeDynamicTxRateSwitching(pAd); - } - } - /* Normal 1 second Mlme PeriodicExec. */ - if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0) { - pAd->Mlme.OneSecPeriodicRound++; - - /*ORIBATimerTimeout(pAd); */ - - /* Media status changed, report to NDIS */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) { - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - pAd->IndicateMediaState = - NdisMediaStateConnected; - RTMP_IndicateMediaState(pAd); - - } else { - pAd->IndicateMediaState = - NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - } - } - - NdisGetSystemUpTime(&pAd->Mlme.Now32); - - /* add the most up-to-date h/w raw counters into software variable, so that */ - /* the dynamic tuning mechanism below are based on most up-to-date information */ - NICUpdateRawCounters(pAd); - -#ifdef RTMP_MAC_USB - RTUSBWatchDog(pAd); -#endif /* RTMP_MAC_USB // */ - - /* Need statistics after read counter. So put after NICUpdateRawCounters */ - ORIBATimerTimeout(pAd); - - /* if MGMT RING is full more than twice within 1 second, we consider there's */ - /* a hardware problem stucking the TX path. In this case, try a hardware reset */ - /* to recover the system */ - /* if (pAd->RalinkCounters.MgmtRingFullCount >= 2) */ - /* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR); */ - /* else */ - /* pAd->RalinkCounters.MgmtRingFullCount = 0; */ - - /* The time period for checking antenna is according to traffic */ - { - if (pAd->Mlme.bEnableAutoAntennaCheck) { - TxTotalCnt = - pAd->RalinkCounters.OneSecTxNoRetryOkCount + - pAd->RalinkCounters.OneSecTxRetryOkCount + - pAd->RalinkCounters.OneSecTxFailCount; - - /* dynamic adjust antenna evaluation period according to the traffic */ - if (TxTotalCnt > 50) { - if (pAd->Mlme.OneSecPeriodicRound % - 10 == 0) { - AsicEvaluateRxAnt(pAd); - } - } else { - if (pAd->Mlme.OneSecPeriodicRound % 3 == - 0) { - AsicEvaluateRxAnt(pAd); - } - } - } - } - - STAMlmePeriodicExec(pAd); - - MlmeResetRalinkCounters(pAd); - - { -#ifdef RTMP_MAC_PCI - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) - && (pAd->bPCIclkOff == FALSE)) -#endif /* RTMP_MAC_PCI // */ - { - /* When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock */ - /* and sending CTS-to-self over and over. */ - /* Software Patch Solution: */ - /* 1. Polling debug state register 0x10F4 every one second. */ - /* 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred. */ - /* 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again. */ - - u32 MacReg = 0; - - RTMP_IO_READ32(pAd, 0x10F4, &MacReg); - if (((MacReg & 0x20000000) && (MacReg & 0x80)) - || ((MacReg & 0x20000000) - && (MacReg & 0x20))) { - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1); - RTMPusecDelay(1); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC); - - DBGPRINT(RT_DEBUG_WARN, - ("Warning, MAC specific condition occurs \n")); - } - } - } - - RTMP_MLME_HANDLER(pAd); - } - - pAd->bUpdateBcnCntDone = FALSE; -} - -/* - ========================================================================== - Validate SSID for connection try and rescan purpose - Valid SSID will have visible chars only. - The valid length is from 0 to 32. - IRQL = DISPATCH_LEVEL - ========================================================================== - */ -BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen) -{ - int index; - - if (SsidLen > MAX_LEN_OF_SSID) - return (FALSE); - - /* Check each character value */ - for (index = 0; index < SsidLen; index++) { - if (pSsid[index] < 0x20) - return (FALSE); - } - - /* All checked */ - return (TRUE); -} - -void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 ** ppTable, - u8 *pTableSize, u8 *pInitTxRateIdx) -{ - do { - /* decide the rate table for tuning */ - if (pAd->CommonCfg.TxRateTableSize > 0) { - *ppTable = RateSwitchTable; - *pTableSize = RateSwitchTable[0]; - *pInitTxRateIdx = RateSwitchTable[1]; - - break; - } - - if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) { - if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) { /* 11N 1S Adhoc */ - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = RateSwitchTable11N1S[1]; - - } else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) { /* 11N 2S Adhoc */ - if (pAd->LatchRfRegs.Channel <= 14) { - *ppTable = RateSwitchTable11N2S; - *pTableSize = RateSwitchTable11N2S[0]; - *pInitTxRateIdx = - RateSwitchTable11N2S[1]; - } else { - *ppTable = RateSwitchTable11N2SForABand; - *pTableSize = - RateSwitchTable11N2SForABand[0]; - *pInitTxRateIdx = - RateSwitchTable11N2SForABand[1]; - } - - } else if ((pEntry->RateLen == 4) - && (pEntry->HTCapability.MCSSet[0] == 0) - && (pEntry->HTCapability.MCSSet[1] == 0) - ) { - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; - - } else if (pAd->LatchRfRegs.Channel <= 14) { - *ppTable = RateSwitchTable11BG; - *pTableSize = RateSwitchTable11BG[0]; - *pInitTxRateIdx = RateSwitchTable11BG[1]; - - } else { - *ppTable = RateSwitchTable11G; - *pTableSize = RateSwitchTable11G[0]; - *pInitTxRateIdx = RateSwitchTable11G[1]; - - } - break; - } - /*if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */ - /* ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */ - if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) { /* 11BGN 1S AP */ - *ppTable = RateSwitchTable11BGN1S; - *pTableSize = RateSwitchTable11BGN1S[0]; - *pInitTxRateIdx = RateSwitchTable11BGN1S[1]; - - break; - } - /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */ - /* (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */ - if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) { /* 11BGN 2S AP */ - if (pAd->LatchRfRegs.Channel <= 14) { - *ppTable = RateSwitchTable11BGN2S; - *pTableSize = RateSwitchTable11BGN2S[0]; - *pInitTxRateIdx = RateSwitchTable11BGN2S[1]; - - } else { - *ppTable = RateSwitchTable11BGN2SForABand; - *pTableSize = RateSwitchTable11BGN2SForABand[0]; - *pInitTxRateIdx = - RateSwitchTable11BGN2SForABand[1]; - - } - break; - } - /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */ - if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) { /* 11N 1S AP */ - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = RateSwitchTable11N1S[1]; - - break; - } - /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */ - if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) { /* 11N 2S AP */ - if (pAd->LatchRfRegs.Channel <= 14) { - *ppTable = RateSwitchTable11N2S; - *pTableSize = RateSwitchTable11N2S[0]; - *pInitTxRateIdx = RateSwitchTable11N2S[1]; - } else { - *ppTable = RateSwitchTable11N2SForABand; - *pTableSize = RateSwitchTable11N2SForABand[0]; - *pInitTxRateIdx = - RateSwitchTable11N2SForABand[1]; - } - - break; - } - /*else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */ - if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode == PHY_11B) - /*Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode */ - /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) */ - ) { /* B only AP */ - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; - - break; - } - /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */ - if ((pEntry->RateLen > 8) - && (pEntry->HTCapability.MCSSet[0] == 0) - && (pEntry->HTCapability.MCSSet[1] == 0) - ) { /* B/G mixed AP */ - *ppTable = RateSwitchTable11BG; - *pTableSize = RateSwitchTable11BG[0]; - *pInitTxRateIdx = RateSwitchTable11BG[1]; - - break; - } - /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */ - if ((pEntry->RateLen == 8) - && (pEntry->HTCapability.MCSSet[0] == 0) - && (pEntry->HTCapability.MCSSet[1] == 0) - ) { /* G only AP */ - *ppTable = RateSwitchTable11G; - *pTableSize = RateSwitchTable11G[0]; - *pInitTxRateIdx = RateSwitchTable11G[1]; - - break; - } - - { - /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */ - if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) { /* Legacy mode */ - if (pAd->CommonCfg.MaxTxRate <= RATE_11) { - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; - } else if ((pAd->CommonCfg.MaxTxRate > RATE_11) - && (pAd->CommonCfg.MinTxRate > - RATE_11)) { - *ppTable = RateSwitchTable11G; - *pTableSize = RateSwitchTable11G[0]; - *pInitTxRateIdx = RateSwitchTable11G[1]; - - } else { - *ppTable = RateSwitchTable11BG; - *pTableSize = RateSwitchTable11BG[0]; - *pInitTxRateIdx = - RateSwitchTable11BG[1]; - } - break; - } - if (pAd->LatchRfRegs.Channel <= 14) { - if (pAd->CommonCfg.TxStream == 1) { - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = - RateSwitchTable11N1S[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unknown mode,default use 11N 1S AP \n")); - } else { - *ppTable = RateSwitchTable11N2S; - *pTableSize = RateSwitchTable11N2S[0]; - *pInitTxRateIdx = - RateSwitchTable11N2S[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unknown mode,default use 11N 2S AP \n")); - } - } else { - if (pAd->CommonCfg.TxStream == 1) { - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = - RateSwitchTable11N1S[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unknown mode,default use 11N 1S AP \n")); - } else { - *ppTable = RateSwitchTable11N2SForABand; - *pTableSize = - RateSwitchTable11N2SForABand[0]; - *pInitTxRateIdx = - RateSwitchTable11N2SForABand[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unknown mode,default use 11N 2S AP \n")); - } - } - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("DRS: unknown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", - pAd->StaActive.SupRateLen, - pAd->StaActive.ExtRateLen, - pAd->StaActive.SupportedPhyInfo.MCSSet[0], - pAd->StaActive.SupportedPhyInfo. - MCSSet[1])); - } - } while (FALSE); -} - -void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd) -{ - unsigned long TxTotalCnt; - int i; - - /* - We return here in ATE mode, because the statistics - that ATE need are not collected via this routine. - */ -#if defined(RT305x)||defined(RT3070) - /* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18 */ - if (!pAd->CommonCfg.HighPowerPatchDisabled) { -#ifdef RT3070 - if ((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) -#endif /* RT3070 // */ - { - if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0) - && (pAd->StaCfg.RssiSample.AvgRssi0 > - (pAd->BbpRssiToDbmDelta - 35))) { - RT30xxWriteRFRegister(pAd, RF_R27, 0x20); - } else { - RT30xxWriteRFRegister(pAd, RF_R27, 0x23); - } - } - } -#endif -#ifdef PCIE_PS_SUPPORT -/* don't perform idle-power-save mechanism within 3 min after driver initialization. */ -/* This can make rebooter test more robust */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) - && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) - && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { - if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { - if (pAd->StaCfg.PSControl.field.EnableNewPS == - TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s\n", __func__)); - RT28xxPciAsicRadioOff(pAd, - GUI_IDLE_POWER_SAVE, - 0); - } else { - AsicSendCommandToMcu(pAd, 0x30, - PowerSafeCID, 0xff, - 0x2); - /* Wait command success */ - AsicCheckCommanOk(pAd, PowerSafeCID); - RTMP_SET_FLAG(pAd, - fRTMP_ADAPTER_IDLE_RADIO_OFF); - DBGPRINT(RT_DEBUG_TRACE, - ("PSM - rt30xx Issue Sleep command)\n")); - } - } else if (pAd->Mlme.OneSecPeriodicRound > 180) { - if (pAd->StaCfg.PSControl.field.EnableNewPS == - TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s\n", __func__)); - RT28xxPciAsicRadioOff(pAd, - GUI_IDLE_POWER_SAVE, - 0); - } else { - AsicSendCommandToMcu(pAd, 0x30, - PowerSafeCID, 0xff, - 0x02); - /* Wait command success */ - AsicCheckCommanOk(pAd, PowerSafeCID); - RTMP_SET_FLAG(pAd, - fRTMP_ADAPTER_IDLE_RADIO_OFF); - DBGPRINT(RT_DEBUG_TRACE, - ("PSM - rt28xx Issue Sleep command)\n")); - } - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n", - pAd->CommonCfg.SsidLen, - pAd->CommonCfg.Ssid[0], - pAd->CommonCfg.Ssid[1], - pAd->CommonCfg.Ssid[2], - pAd->CommonCfg.Ssid[3], pAd->MlmeAux.SsidLen, - pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1], - pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3])); - } - } -#endif /* PCIE_PS_SUPPORT // */ - - if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) { - /* WPA MIC error should block association attempt for 60 seconds */ - if (pAd->StaCfg.bBlockAssoc && - RTMP_TIME_AFTER(pAd->Mlme.Now32, - pAd->StaCfg.LastMicErrorTime + - (60 * OS_HZ))) - pAd->StaCfg.bBlockAssoc = FALSE; - } - - if ((pAd->PreMediaState != pAd->IndicateMediaState) - && (pAd->CommonCfg.bWirelessEvent)) { - if (pAd->IndicateMediaState == NdisMediaStateConnected) { - RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - } - pAd->PreMediaState = pAd->IndicateMediaState; - } - - if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd)) { - } else { - AsicStaBbpTuning(pAd); - } - - TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + - pAd->RalinkCounters.OneSecTxRetryOkCount + - pAd->RalinkCounters.OneSecTxFailCount; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - /* update channel quality for Roaming and UI LinkQuality display */ - MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32); - } - /* must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if */ - /* Radio is currently in noisy environment */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - AsicAdjustTxPower(pAd); - - if (INFRA_ON(pAd)) { - - /* Is PSM bit consistent with user power management policy? */ - /* This is the only place that will set PSM bit ON. */ - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - MlmeCheckPsmChange(pAd, pAd->Mlme.Now32); - - pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt; - - if ((RTMP_TIME_AFTER - (pAd->Mlme.Now32, - pAd->StaCfg.LastBeaconRxTime + (1 * OS_HZ))) - && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - && - (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) < - 600))) { - RTMPSetAGCInitValue(pAd, BW_20); - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", - (0x2E + GET_LNA_GAIN(pAd)))); - } - /*if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && */ - /* (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)) */ - { - if (pAd->CommonCfg.bAPSDCapable - && pAd->CommonCfg.APEdcaParm.bAPSDCapable) { - /* When APSD is enabled, the period changes as 20 sec */ - if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8) - RTMPSendNullFrame(pAd, - pAd->CommonCfg.TxRate, - TRUE); - } else { - /* Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) */ - if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) { - if (pAd->CommonCfg.bWmmCapable) - RTMPSendNullFrame(pAd, - pAd-> - CommonCfg. - TxRate, TRUE); - else - RTMPSendNullFrame(pAd, - pAd-> - CommonCfg. - TxRate, - FALSE); - } - } - } - - if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) { - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", - pAd->RalinkCounters.BadCQIAutoRecoveryCount)); - - /* Lost AP, send disconnect & link down event */ - LinkDown(pAd, FALSE); - - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, - 0); - - /* RTMPPatchMacBbpBug(pAd); */ - MlmeAutoReconnectLastSSID(pAd); - } else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) { - pAd->RalinkCounters.BadCQIAutoRecoveryCount++; - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", - pAd->RalinkCounters.BadCQIAutoRecoveryCount)); - MlmeAutoReconnectLastSSID(pAd); - } - - if (pAd->StaCfg.bAutoRoaming) { - BOOLEAN rv = FALSE; - char dBmToRoam = pAd->StaCfg.dBmToRoam; - char MaxRssi = RTMPMaxRssi(pAd, - pAd->StaCfg.RssiSample. - LastRssi0, - pAd->StaCfg.RssiSample. - LastRssi1, - pAd->StaCfg.RssiSample. - LastRssi2); - - /* Scanning, ignore Roaming */ - if (!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) - && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) - && (MaxRssi <= dBmToRoam)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, - (char)dBmToRoam)); - - /* Add auto seamless roaming */ - if (rv == FALSE) - rv = MlmeCheckForFastRoaming(pAd); - - if (rv == FALSE) { - if ((pAd->StaCfg.LastScanTime + - 10 * OS_HZ) < pAd->Mlme.Now32) { - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - Roaming, No eligible entry, try new scan!\n")); - pAd->StaCfg.ScanCnt = 2; - pAd->StaCfg.LastScanTime = - pAd->Mlme.Now32; - MlmeAutoScan(pAd); - } - } - } - } - } else if (ADHOC_ON(pAd)) { - /* If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState */ - /* to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can */ - /* join later. */ - if (RTMP_TIME_AFTER - (pAd->Mlme.Now32, - pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) - && OPSTATUS_TEST_FLAG(pAd, - fOP_STATUS_MEDIA_STATE_CONNECTED)) { - struct rt_mlme_start_req StartReq; - - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n")); - LinkDown(pAd, FALSE); - - StartParmFill(pAd, &StartReq, - (char *) pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, - sizeof(struct rt_mlme_start_req), &StartReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; - } - - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { - struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i]; - - if (pEntry->ValidAsCLI == FALSE) - continue; - - if (RTMP_TIME_AFTER - (pAd->Mlme.Now32, - pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)) - MacTableDeleteEntry(pAd, pEntry->Aid, - pEntry->Addr); - } - } else /* no INFRA nor ADHOC connection */ - { - - if (pAd->StaCfg.bScanReqIsFromWebUI && - RTMP_TIME_BEFORE(pAd->Mlme.Now32, - pAd->StaCfg.LastScanTime + (30 * OS_HZ))) - goto SKIP_AUTO_SCAN_CONN; - else - pAd->StaCfg.bScanReqIsFromWebUI = FALSE; - - if ((pAd->StaCfg.bAutoReconnect == TRUE) - && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP) - && - (MlmeValidateSSID - (pAd->MlmeAux.AutoReconnectSsid, - pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) { - if ((pAd->ScanTab.BssNr == 0) - && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) { - struct rt_mlme_scan_req ScanReq; - - if (RTMP_TIME_AFTER - (pAd->Mlme.Now32, - pAd->StaCfg.LastScanTime + (10 * OS_HZ))) { - DBGPRINT(RT_DEBUG_TRACE, - ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", - pAd->MlmeAux. - AutoReconnectSsid)); - ScanParmFill(pAd, &ScanReq, - (char *)pAd->MlmeAux. - AutoReconnectSsid, - pAd->MlmeAux. - AutoReconnectSsidLen, - BSS_ANY, SCAN_ACTIVE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, - MT2_MLME_SCAN_REQ, - sizeof - (struct rt_mlme_scan_req), - &ScanReq); - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_OID_LIST_SCAN; - /* Reset Missed scan number */ - pAd->StaCfg.LastScanTime = - pAd->Mlme.Now32; - } else if (pAd->StaCfg.BssType == BSS_ADHOC) /* Quit the forever scan when in a very clean room */ - MlmeAutoReconnectLastSSID(pAd); - } else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { - if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0) { - MlmeAutoScan(pAd); - pAd->StaCfg.LastScanTime = - pAd->Mlme.Now32; - } else { - MlmeAutoReconnectLastSSID(pAd); - } - } - } - } - -SKIP_AUTO_SCAN_CONN: - - if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap != 0) - && (pAd->MacTab.fAnyBASession == FALSE)) { - pAd->MacTab.fAnyBASession = TRUE; - AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, - FALSE); - } else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap == 0) - && (pAd->MacTab.fAnyBASession == TRUE)) { - pAd->MacTab.fAnyBASession = FALSE; - AsicUpdateProtect(pAd, - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); - } - - return; -} - -/* Link down report */ -void LinkDownExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - if (pAd != NULL) { - struct rt_mlme_disassoc_req DisassocReq; - - if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) && - (INFRA_ON(pAd))) { - DBGPRINT(RT_DEBUG_TRACE, - ("LinkDownExec(): disassociate with current AP...\n")); - DisassocParmFill(pAd, &DisassocReq, - pAd->CommonCfg.Bssid, - REASON_DISASSOC_STA_LEAVING); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, - MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), - &DisassocReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; - - pAd->IndicateMediaState = NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_DOWN; - } - } -} - -/* IRQL = DISPATCH_LEVEL */ -void MlmeAutoScan(struct rt_rtmp_adapter *pAd) -{ - /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */ - if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n")); - MlmeEnqueue(pAd, - MLME_CNTL_STATE_MACHINE, - OID_802_11_BSSID_LIST_SCAN, - pAd->MlmeAux.AutoReconnectSsidLen, - pAd->MlmeAux.AutoReconnectSsid); - RTMP_MLME_HANDLER(pAd); - } -} - -/* IRQL = DISPATCH_LEVEL */ -void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd) -{ - if (pAd->StaCfg.bAutoConnectByBssid) { - DBGPRINT(RT_DEBUG_TRACE, - ("Driver auto reconnect to last OID_802_11_BSSID " - "setting - %pM\n", pAd->MlmeAux.Bssid)); - - pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; - MlmeEnqueue(pAd, - MLME_CNTL_STATE_MACHINE, - OID_802_11_BSSID, MAC_ADDR_LEN, pAd->MlmeAux.Bssid); - - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - - RTMP_MLME_HANDLER(pAd); - } - /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */ - else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && - (MlmeValidateSSID - (pAd->MlmeAux.AutoReconnectSsid, - pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) { - struct rt_ndis_802_11_ssid OidSsid; - OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen; - NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, - pAd->MlmeAux.AutoReconnectSsidLen); - - DBGPRINT(RT_DEBUG_TRACE, - ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", - pAd->MlmeAux.AutoReconnectSsid, - pAd->MlmeAux.AutoReconnectSsidLen)); - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, - sizeof(struct rt_ndis_802_11_ssid), &OidSsid); - RTMP_MLME_HANDLER(pAd); - } -} - -/* - ========================================================================== - Description: - This routine checks if there're other APs out there capable for - roaming. Caller should call this routine only when Link up in INFRA mode - and channel quality is below CQI_GOOD_THRESHOLD. - - IRQL = DISPATCH_LEVEL - - Output: - ========================================================================== - */ -void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32) -{ - u16 i; - struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab; - struct rt_bss_entry *pBss; - - DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n")); - /* put all roaming candidates into RoamTab, and sort in RSSI order */ - BssTableInit(pRoamTab); - for (i = 0; i < pAd->ScanTab.BssNr; i++) { - pBss = &pAd->ScanTab.BssEntry[i]; - - if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) < - Now32) - continue; /* AP disappear */ - if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING) - continue; /* RSSI too weak. forget it. */ - if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) - continue; /* skip current AP */ - if (pBss->Rssi < - (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA)) - continue; /* only AP with stronger RSSI is eligible for roaming */ - - /* AP passing all above rules is put into roaming candidate table */ - NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, - sizeof(struct rt_bss_entry)); - pRoamTab->BssNr += 1; - } - - if (pRoamTab->BssNr > 0) { - /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */ - if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { - pAd->RalinkCounters.PoorCQIRoamingCount++; - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - Roaming attempt #%ld\n", - pAd->RalinkCounters.PoorCQIRoamingCount)); - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_MLME_ROAMING_REQ, 0, NULL); - RTMP_MLME_HANDLER(pAd); - } - } - DBGPRINT(RT_DEBUG_TRACE, - ("<== MlmeCheckForRoaming(# of candidate= %d)\n", - pRoamTab->BssNr)); -} - -/* - ========================================================================== - Description: - This routine checks if there're other APs out there capable for - roaming. Caller should call this routine only when link up in INFRA mode - and channel quality is below CQI_GOOD_THRESHOLD. - - IRQL = DISPATCH_LEVEL - - Output: - ========================================================================== - */ -BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd) -{ - u16 i; - struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab; - struct rt_bss_entry *pBss; - - DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n")); - /* put all roaming candidates into RoamTab, and sort in RSSI order */ - BssTableInit(pRoamTab); - for (i = 0; i < pAd->ScanTab.BssNr; i++) { - pBss = &pAd->ScanTab.BssEntry[i]; - - if ((pBss->Rssi <= -50) - && (pBss->Channel == pAd->CommonCfg.Channel)) - continue; /* RSSI too weak. forget it. */ - if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) - continue; /* skip current AP */ - if (!SSID_EQUAL - (pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, - pAd->CommonCfg.SsidLen)) - continue; /* skip different SSID */ - if (pBss->Rssi < - (RTMPMaxRssi - (pAd, pAd->StaCfg.RssiSample.LastRssi0, - pAd->StaCfg.RssiSample.LastRssi1, - pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA)) - continue; /* skip AP without better RSSI */ - - DBGPRINT(RT_DEBUG_TRACE, - ("LastRssi0 = %d, pBss->Rssi = %d\n", - RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, - pAd->StaCfg.RssiSample.LastRssi1, - pAd->StaCfg.RssiSample.LastRssi2), - pBss->Rssi)); - /* AP passing all above rules is put into roaming candidate table */ - NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, - sizeof(struct rt_bss_entry)); - pRoamTab->BssNr += 1; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr)); - if (pRoamTab->BssNr > 0) { - /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */ - if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { - pAd->RalinkCounters.PoorCQIRoamingCount++; - DBGPRINT(RT_DEBUG_TRACE, - ("MMCHK - Roaming attempt #%ld\n", - pAd->RalinkCounters.PoorCQIRoamingCount)); - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_MLME_ROAMING_REQ, 0, NULL); - RTMP_MLME_HANDLER(pAd); - return TRUE; - } - } - - return FALSE; -} - -void MlmeSetTxRate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate) -{ - u8 MaxMode = MODE_OFDM; - - MaxMode = MODE_HTGREENFIELD; - - if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) - && (pAd->Antenna.field.TxPath == 2)) - pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE; - else - pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; - - if (pTxRate->CurrMCS < MCS_AUTO) - pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS; - - if (pAd->StaCfg.HTPhyMode.field.MCS > 7) - pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; - - if (ADHOC_ON(pAd)) { - /* If peer adhoc is b-only mode, we can't send 11g rate. */ - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - pEntry->HTPhyMode.field.STBC = STBC_NONE; - - /* */ - /* For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary */ - /* */ - pEntry->HTPhyMode.field.MODE = pTxRate->Mode; - pEntry->HTPhyMode.field.ShortGI = - pAd->StaCfg.HTPhyMode.field.ShortGI; - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - - /* Patch speed error in status page */ - pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE; - } else { - if (pTxRate->Mode <= MaxMode) - pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode; - - if (pTxRate->ShortGI - && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI)) - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400; - else - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - - /* Reexam each bandwidth's SGI support. */ - if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) { - if ((pEntry->HTPhyMode.field.BW == BW_20) - && - (!CLIENT_STATUS_TEST_FLAG - (pEntry, fCLIENT_STATUS_SGI20_CAPABLE))) - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - if ((pEntry->HTPhyMode.field.BW == BW_40) - && - (!CLIENT_STATUS_TEST_FLAG - (pEntry, fCLIENT_STATUS_SGI40_CAPABLE))) - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - } - /* Turn RTS/CTS rate to 6Mbps. */ - if ((pEntry->HTPhyMode.field.MCS == 0) - && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) { - pEntry->HTPhyMode.field.MCS = - pAd->StaCfg.HTPhyMode.field.MCS; - if (pAd->MacTab.fAnyBASession) { - AsicUpdateProtect(pAd, HT_FORCERTSCTS, - ALLN_SETPROTECT, TRUE, - (BOOLEAN) pAd->MlmeAux. - AddHtInfo.AddHtInfo2. - NonGfPresent); - } else { - AsicUpdateProtect(pAd, - pAd->MlmeAux.AddHtInfo. - AddHtInfo2.OperaionMode, - ALLN_SETPROTECT, TRUE, - (BOOLEAN) pAd->MlmeAux. - AddHtInfo.AddHtInfo2. - NonGfPresent); - } - } else if ((pEntry->HTPhyMode.field.MCS == 8) - && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) { - pEntry->HTPhyMode.field.MCS = - pAd->StaCfg.HTPhyMode.field.MCS; - if (pAd->MacTab.fAnyBASession) { - AsicUpdateProtect(pAd, HT_FORCERTSCTS, - ALLN_SETPROTECT, TRUE, - (BOOLEAN) pAd->MlmeAux. - AddHtInfo.AddHtInfo2. - NonGfPresent); - } else { - AsicUpdateProtect(pAd, - pAd->MlmeAux.AddHtInfo. - AddHtInfo2.OperaionMode, - ALLN_SETPROTECT, TRUE, - (BOOLEAN) pAd->MlmeAux. - AddHtInfo.AddHtInfo2. - NonGfPresent); - } - } else if ((pEntry->HTPhyMode.field.MCS != 0) - && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) { - AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, - TRUE, - (BOOLEAN) pAd->MlmeAux.AddHtInfo. - AddHtInfo2.NonGfPresent); - - } else if ((pEntry->HTPhyMode.field.MCS != 8) - && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) { - AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, - TRUE, - (BOOLEAN) pAd->MlmeAux.AddHtInfo. - AddHtInfo2.NonGfPresent); - } - - pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC; - pEntry->HTPhyMode.field.ShortGI = - pAd->StaCfg.HTPhyMode.field.ShortGI; - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; - if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) - && pAd->WIFItestbed.bGreenField) - pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD; - } - - pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word); -} - -/* - ========================================================================== - Description: - This routine calculates the acumulated TxPER of eaxh TxRate. And - according to the calculation result, change CommonCfg.TxRate which - is the stable TX Rate we expect the Radio situation could sustained. - - CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate} - Output: - CommonCfg.TxRate - - - IRQL = DISPATCH_LEVEL - - NOTE: - call this routine every second - ========================================================================== - */ -void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd) -{ - u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; - unsigned long i, AccuTxTotalCnt = 0, TxTotalCnt; - unsigned long TxErrorRatio = 0; - BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE; - struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL; - u8 *pTable; - u8 TableSize = 0; - u8 InitTxRateIdx = 0, TrainUp, TrainDown; - char Rssi, RssiOffset = 0; - TX_STA_CNT1_STRUC StaTx1; - TX_STA_CNT0_STRUC TxStaCnt0; - unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; - struct rt_mac_table_entry *pEntry; - struct rt_rssi_sample *pRssi = &pAd->StaCfg.RssiSample; - - /* */ - /* walk through MAC table, see if need to change AP's TX rate toward each entry */ - /* */ - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { - pEntry = &pAd->MacTab.Content[i]; - - /* check if this entry need to switch rate automatically */ - if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) - continue; - - if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) { - Rssi = RTMPMaxRssi(pAd, - pRssi->AvgRssi0, - pRssi->AvgRssi1, pRssi->AvgRssi2); - - /* Update statistic counter */ - RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); - pAd->bUpdateBcnCntDone = TRUE; - TxRetransmit = StaTx1.field.TxRetransmit; - TxSuccess = StaTx1.field.TxSuccess; - TxFailCount = TxStaCnt0.field.TxFailCount; - TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; - - pAd->RalinkCounters.OneSecTxRetryOkCount += - StaTx1.field.TxRetransmit; - pAd->RalinkCounters.OneSecTxNoRetryOkCount += - StaTx1.field.TxSuccess; - pAd->RalinkCounters.OneSecTxFailCount += - TxStaCnt0.field.TxFailCount; - pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += - StaTx1.field.TxSuccess; - pAd->WlanCounters.RetryCount.u.LowPart += - StaTx1.field.TxRetransmit; - pAd->WlanCounters.FailedCount.u.LowPart += - TxStaCnt0.field.TxFailCount; - - /* if no traffic in the past 1-sec period, don't change TX rate, */ - /* but clear all bad history. because the bad history may affect the next */ - /* Chariot throughput test */ - AccuTxTotalCnt = - pAd->RalinkCounters.OneSecTxNoRetryOkCount + - pAd->RalinkCounters.OneSecTxRetryOkCount + - pAd->RalinkCounters.OneSecTxFailCount; - - if (TxTotalCnt) - TxErrorRatio = - ((TxRetransmit + - TxFailCount) * 100) / TxTotalCnt; - } else { - if (INFRA_ON(pAd) && (i == 1)) - Rssi = RTMPMaxRssi(pAd, - pRssi->AvgRssi0, - pRssi->AvgRssi1, - pRssi->AvgRssi2); - else - Rssi = RTMPMaxRssi(pAd, - pEntry->RssiSample.AvgRssi0, - pEntry->RssiSample.AvgRssi1, - pEntry->RssiSample.AvgRssi2); - - TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + - pEntry->OneSecTxRetryOkCount + - pEntry->OneSecTxFailCount; - - if (TxTotalCnt) - TxErrorRatio = - ((pEntry->OneSecTxRetryOkCount + - pEntry->OneSecTxFailCount) * 100) / - TxTotalCnt; - } - - if (TxTotalCnt) { - /* - Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool - We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings - */ - if (TxErrorRatio == 100) { - TX_RTY_CFG_STRUC TxRtyCfg, TxRtyCfgtmp; - unsigned long Index; - unsigned long MACValue; - - RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word); - TxRtyCfgtmp.word = TxRtyCfg.word; - TxRtyCfg.field.LongRtyLimit = 0x0; - TxRtyCfg.field.ShortRtyLimit = 0x0; - RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word); - - RTMPusecDelay(1); - - Index = 0; - MACValue = 0; - do { - RTMP_IO_READ32(pAd, TXRXQ_PCNT, - &MACValue); - if ((MACValue & 0xffffff) == 0) - break; - Index++; - RTMPusecDelay(1000); - } while ((Index < 330) - && - (!RTMP_TEST_FLAG - (pAd, - fRTMP_ADAPTER_HALT_IN_PROGRESS))); - - RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word); - TxRtyCfg.field.LongRtyLimit = - TxRtyCfgtmp.field.LongRtyLimit; - TxRtyCfg.field.ShortRtyLimit = - TxRtyCfgtmp.field.ShortRtyLimit; - RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word); - } - } - - CurrRateIdx = pEntry->CurrTxRateIndex; - - MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, - &InitTxRateIdx); - - if (CurrRateIdx >= TableSize) { - CurrRateIdx = TableSize - 1; - } - /* When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. */ - /* So need to sync here. */ - pCurrTxRate = - (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5]; - if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS) - /*&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) */ - ) { - - /* Need to sync Real Tx rate and our record. */ - /* Then return for next DRS. */ - pCurrTxRate = - (struct rt_rtmp_tx_rate_switch *) & pTable[(InitTxRateIdx + 1) - * 5]; - pEntry->CurrTxRateIndex = InitTxRateIdx; - MlmeSetTxRate(pAd, pEntry, pCurrTxRate); - - /* reset all OneSecTx counters */ - RESET_ONE_SEC_TX_CNT(pEntry); - continue; - } - /* decide the next upgrade rate and downgrade rate, if any */ - if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx - 1; - } else if (CurrRateIdx == 0) { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx; - } else if (CurrRateIdx == (TableSize - 1)) { - UpRateIdx = CurrRateIdx; - DownRateIdx = CurrRateIdx - 1; - } - - pCurrTxRate = - (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5]; - - if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) { - TrainUp = - (pCurrTxRate->TrainUp + - (pCurrTxRate->TrainUp >> 1)); - TrainDown = - (pCurrTxRate->TrainDown + - (pCurrTxRate->TrainDown >> 1)); - } else { - TrainUp = pCurrTxRate->TrainUp; - TrainDown = pCurrTxRate->TrainDown; - } - - /*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; */ - - /* */ - /* Keep the last time TxRateChangeAction status. */ - /* */ - pEntry->LastTimeTxRateChangeAction = - pEntry->LastSecTxRateChangeAction; - - /* */ - /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */ - /* (criteria copied from RT2500 for Netopia case) */ - /* */ - if (TxTotalCnt <= 15) { - char idx = 0; - u8 TxRateIdx; - u8 MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = - 0, MCS5 = 0, MCS6 = 0, MCS7 = 0; - u8 MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; - u8 MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; /* 3*3 */ - - /* check the existence and index of each needed MCS */ - while (idx < pTable[0]) { - pCurrTxRate = - (struct rt_rtmp_tx_rate_switch *) & pTable[(idx + 1) * - 5]; - - if (pCurrTxRate->CurrMCS == MCS_0) { - MCS0 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_1) { - MCS1 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_2) { - MCS2 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_3) { - MCS3 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_4) { - MCS4 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_5) { - MCS5 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_6) { - MCS6 = idx; - } - /*else if (pCurrTxRate->CurrMCS == MCS_7) */ - else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) /* prevent the highest MCS using short GI when 1T and low throughput */ - { - MCS7 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_12) { - MCS12 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_13) { - MCS13 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_14) { - MCS14 = idx; - } - else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800)) /*we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI */ - { - MCS15 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_20) /* 3*3 */ - { - MCS20 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_21) { - MCS21 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_22) { - MCS22 = idx; - } else if (pCurrTxRate->CurrMCS == MCS_23) { - MCS23 = idx; - } - idx++; - } - - if (pAd->LatchRfRegs.Channel <= 14) { - if (pAd->NicConfig2.field.ExternalLNAForG) { - RssiOffset = 2; - } else { - RssiOffset = 5; - } - } else { - if (pAd->NicConfig2.field.ExternalLNAForA) { - RssiOffset = 5; - } else { - RssiOffset = 8; - } - } - - /*if (MCS15) */ - if ((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11N3S) || (pTable == RateSwitchTable)) { /* N mode with 3 stream // 3*3 */ - if (MCS23 && (Rssi >= -70)) - TxRateIdx = MCS23; - else if (MCS22 && (Rssi >= -72)) - TxRateIdx = MCS22; - else if (MCS21 && (Rssi >= -76)) - TxRateIdx = MCS21; - else if (MCS20 && (Rssi >= -78)) - TxRateIdx = MCS20; - else if (MCS4 && (Rssi >= -82)) - TxRateIdx = MCS4; - else if (MCS3 && (Rssi >= -84)) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi >= -86)) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi >= -88)) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } -/* else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable)) */ - else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) || (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand)) /* 3*3 */ - { /* N mode with 2 stream */ - if (MCS15 && (Rssi >= (-70 + RssiOffset))) - TxRateIdx = MCS15; - else if (MCS14 && (Rssi >= (-72 + RssiOffset))) - TxRateIdx = MCS14; - else if (MCS13 && (Rssi >= (-76 + RssiOffset))) - TxRateIdx = MCS13; - else if (MCS12 && (Rssi >= (-78 + RssiOffset))) - TxRateIdx = MCS12; - else if (MCS4 && (Rssi >= (-82 + RssiOffset))) - TxRateIdx = MCS4; - else if (MCS3 && (Rssi >= (-84 + RssiOffset))) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi >= (-86 + RssiOffset))) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi >= (-88 + RssiOffset))) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) { /* N mode with 1 stream */ - if (MCS7 && (Rssi > (-72 + RssiOffset))) - TxRateIdx = MCS7; - else if (MCS6 && (Rssi > (-74 + RssiOffset))) - TxRateIdx = MCS6; - else if (MCS5 && (Rssi > (-77 + RssiOffset))) - TxRateIdx = MCS5; - else if (MCS4 && (Rssi > (-79 + RssiOffset))) - TxRateIdx = MCS4; - else if (MCS3 && (Rssi > (-81 + RssiOffset))) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi > (-83 + RssiOffset))) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi > (-86 + RssiOffset))) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } else { /* Legacy mode */ - if (MCS7 && (Rssi > -70)) - TxRateIdx = MCS7; - else if (MCS6 && (Rssi > -74)) - TxRateIdx = MCS6; - else if (MCS5 && (Rssi > -78)) - TxRateIdx = MCS5; - else if (MCS4 && (Rssi > -82)) - TxRateIdx = MCS4; - else if (MCS4 == 0) /* for B-only mode */ - TxRateIdx = MCS3; - else if (MCS3 && (Rssi > -85)) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi > -87)) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi > -90)) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } - - /* if (TxRateIdx != pAd->CommonCfg.TxRateIndex) */ - { - pEntry->CurrTxRateIndex = TxRateIdx; - pNextTxRate = - (struct rt_rtmp_tx_rate_switch *) & - pTable[(pEntry->CurrTxRateIndex + 1) * 5]; - MlmeSetTxRate(pAd, pEntry, pNextTxRate); - } - - NdisZeroMemory(pEntry->TxQuality, - sizeof(u16)* - MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pEntry->PER, - sizeof(u8)* - MAX_STEP_OF_TX_RATE_SWITCH); - pEntry->fLastSecAccordingRSSI = TRUE; - /* reset all OneSecTx counters */ - RESET_ONE_SEC_TX_CNT(pEntry); - - continue; - } - - if (pEntry->fLastSecAccordingRSSI == TRUE) { - pEntry->fLastSecAccordingRSSI = FALSE; - pEntry->LastSecTxRateChangeAction = 0; - /* reset all OneSecTx counters */ - RESET_ONE_SEC_TX_CNT(pEntry); - - continue; - } - - do { - BOOLEAN bTrainUpDown = FALSE; - - pEntry->CurrTxRateStableTime++; - - /* downgrade TX quality if PER >= Rate-Down threshold */ - if (TxErrorRatio >= TrainDown) { - bTrainUpDown = TRUE; - pEntry->TxQuality[CurrRateIdx] = - DRS_TX_QUALITY_WORST_BOUND; - } - /* upgrade TX quality if PER <= Rate-Up threshold */ - else if (TxErrorRatio <= TrainUp) { - bTrainUpDown = TRUE; - bUpgradeQuality = TRUE; - if (pEntry->TxQuality[CurrRateIdx]) - pEntry->TxQuality[CurrRateIdx]--; /* quality very good in CurrRate */ - - if (pEntry->TxRateUpPenalty) - pEntry->TxRateUpPenalty--; - else if (pEntry->TxQuality[UpRateIdx]) - pEntry->TxQuality[UpRateIdx]--; /* may improve next UP rate's quality */ - } - - pEntry->PER[CurrRateIdx] = (u8)TxErrorRatio; - - if (bTrainUpDown) { - /* perform DRS - consider TxRate Down first, then rate up. */ - if ((CurrRateIdx != DownRateIdx) - && (pEntry->TxQuality[CurrRateIdx] >= - DRS_TX_QUALITY_WORST_BOUND)) { - pEntry->CurrTxRateIndex = DownRateIdx; - } else if ((CurrRateIdx != UpRateIdx) - && (pEntry->TxQuality[UpRateIdx] <= - 0)) { - pEntry->CurrTxRateIndex = UpRateIdx; - } - } - } while (FALSE); - - /* if rate-up happen, clear all bad history of all TX rates */ - if (pEntry->CurrTxRateIndex > CurrRateIdx) { - pEntry->CurrTxRateStableTime = 0; - pEntry->TxRateUpPenalty = 0; - pEntry->LastSecTxRateChangeAction = 1; /* rate UP */ - NdisZeroMemory(pEntry->TxQuality, - sizeof(u16)* - MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pEntry->PER, - sizeof(u8)* - MAX_STEP_OF_TX_RATE_SWITCH); - - /* */ - /* For TxRate fast train up */ - /* */ - if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) { - RTMPSetTimer(&pAd->StaCfg. - StaQuickResponeForRateUpTimer, - 100); - - pAd->StaCfg. - StaQuickResponeForRateUpTimerRunning = TRUE; - } - bTxRateChanged = TRUE; - } - /* if rate-down happen, only clear DownRate's bad history */ - else if (pEntry->CurrTxRateIndex < CurrRateIdx) { - pEntry->CurrTxRateStableTime = 0; - pEntry->TxRateUpPenalty = 0; /* no penalty */ - pEntry->LastSecTxRateChangeAction = 2; /* rate DOWN */ - pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; - pEntry->PER[pEntry->CurrTxRateIndex] = 0; - - /* */ - /* For TxRate fast train down */ - /* */ - if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) { - RTMPSetTimer(&pAd->StaCfg. - StaQuickResponeForRateUpTimer, - 100); - - pAd->StaCfg. - StaQuickResponeForRateUpTimerRunning = TRUE; - } - bTxRateChanged = TRUE; - } else { - pEntry->LastSecTxRateChangeAction = 0; /* rate no change */ - bTxRateChanged = FALSE; - } - - pEntry->LastTxOkCount = TxSuccess; - { - u8 tmpTxRate; - - /* to fix tcp ack issue */ - if (!bTxRateChanged - && (pAd->RalinkCounters.OneSecReceivedByteCount > - (pAd->RalinkCounters. - OneSecTransmittedByteCount * 5))) { - tmpTxRate = DownRateIdx; - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n", - pAd->RalinkCounters. - OneSecReceivedByteCount, - pAd->RalinkCounters. - OneSecTransmittedByteCount, - pEntry->CurrTxRateIndex, - tmpTxRate)); - } else { - tmpTxRate = pEntry->CurrTxRateIndex; - } - - pNextTxRate = - (struct rt_rtmp_tx_rate_switch *) & pTable[(tmpTxRate + 1) * - 5]; - } - if (bTxRateChanged && pNextTxRate) { - MlmeSetTxRate(pAd, pEntry, pNextTxRate); - } - /* reset all OneSecTx counters */ - RESET_ONE_SEC_TX_CNT(pEntry); - } -} - -/* - ======================================================================== - Routine Description: - Station side, Auto TxRate faster train up timer call back function. - - Arguments: - SystemSpecific1 - Not used. - FunctionContext - Pointer to our Adapter context. - SystemSpecific2 - Not used. - SystemSpecific3 - Not used. - - Return Value: - None - - ======================================================================== -*/ -void StaQuickResponeForRateUpExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; - unsigned long TxTotalCnt; - unsigned long TxErrorRatio = 0; - BOOLEAN bTxRateChanged; /*, bUpgradeQuality = FALSE; */ - struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL; - u8 *pTable; - u8 TableSize = 0; - u8 InitTxRateIdx = 0, TrainUp, TrainDown; - TX_STA_CNT1_STRUC StaTx1; - TX_STA_CNT0_STRUC TxStaCnt0; - char Rssi, ratio; - unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; - struct rt_mac_table_entry *pEntry; - unsigned long i; - - pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; - - /* */ - /* walk through MAC table, see if need to change AP's TX rate toward each entry */ - /* */ - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { - pEntry = &pAd->MacTab.Content[i]; - - /* check if this entry need to switch rate automatically */ - if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) - continue; - - if (INFRA_ON(pAd) && (i == 1)) - Rssi = RTMPMaxRssi(pAd, - pAd->StaCfg.RssiSample.AvgRssi0, - pAd->StaCfg.RssiSample.AvgRssi1, - pAd->StaCfg.RssiSample.AvgRssi2); - else - Rssi = RTMPMaxRssi(pAd, - pEntry->RssiSample.AvgRssi0, - pEntry->RssiSample.AvgRssi1, - pEntry->RssiSample.AvgRssi2); - - CurrRateIdx = pAd->CommonCfg.TxRateIndex; - - MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, - &InitTxRateIdx); - - /* decide the next upgrade rate and downgrade rate, if any */ - if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx - 1; - } else if (CurrRateIdx == 0) { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx; - } else if (CurrRateIdx == (TableSize - 1)) { - UpRateIdx = CurrRateIdx; - DownRateIdx = CurrRateIdx - 1; - } - - pCurrTxRate = - (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5]; - - if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) { - TrainUp = - (pCurrTxRate->TrainUp + - (pCurrTxRate->TrainUp >> 1)); - TrainDown = - (pCurrTxRate->TrainDown + - (pCurrTxRate->TrainDown >> 1)); - } else { - TrainUp = pCurrTxRate->TrainUp; - TrainDown = pCurrTxRate->TrainDown; - } - - if (pAd->MacTab.Size == 1) { - /* Update statistic counter */ - RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); - - TxRetransmit = StaTx1.field.TxRetransmit; - TxSuccess = StaTx1.field.TxSuccess; - TxFailCount = TxStaCnt0.field.TxFailCount; - TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; - - pAd->RalinkCounters.OneSecTxRetryOkCount += - StaTx1.field.TxRetransmit; - pAd->RalinkCounters.OneSecTxNoRetryOkCount += - StaTx1.field.TxSuccess; - pAd->RalinkCounters.OneSecTxFailCount += - TxStaCnt0.field.TxFailCount; - pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += - StaTx1.field.TxSuccess; - pAd->WlanCounters.RetryCount.u.LowPart += - StaTx1.field.TxRetransmit; - pAd->WlanCounters.FailedCount.u.LowPart += - TxStaCnt0.field.TxFailCount; - - if (TxTotalCnt) - TxErrorRatio = - ((TxRetransmit + - TxFailCount) * 100) / TxTotalCnt; - } else { - TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + - pEntry->OneSecTxRetryOkCount + - pEntry->OneSecTxFailCount; - - if (TxTotalCnt) - TxErrorRatio = - ((pEntry->OneSecTxRetryOkCount + - pEntry->OneSecTxFailCount) * 100) / - TxTotalCnt; - } - - /* */ - /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */ - /* (criteria copied from RT2500 for Netopia case) */ - /* */ - if (TxTotalCnt <= 12) { - NdisZeroMemory(pAd->DrsCounters.TxQuality, - sizeof(u16)* - MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pAd->DrsCounters.PER, - sizeof(u8)* - MAX_STEP_OF_TX_RATE_SWITCH); - - if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) - && (CurrRateIdx != DownRateIdx)) { - pAd->CommonCfg.TxRateIndex = DownRateIdx; - pAd->DrsCounters.TxQuality[CurrRateIdx] = - DRS_TX_QUALITY_WORST_BOUND; - } else - if ((pAd->DrsCounters.LastSecTxRateChangeAction == - 2) && (CurrRateIdx != UpRateIdx)) { - pAd->CommonCfg.TxRateIndex = UpRateIdx; - } - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("QuickDRS: TxTotalCnt <= 15, train back to original rate \n")); - return; - } - - do { - unsigned long OneSecTxNoRetryOKRationCount; - - if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0) - ratio = 5; - else - ratio = 4; - - /* downgrade TX quality if PER >= Rate-Down threshold */ - if (TxErrorRatio >= TrainDown) { - pAd->DrsCounters.TxQuality[CurrRateIdx] = - DRS_TX_QUALITY_WORST_BOUND; - } - - pAd->DrsCounters.PER[CurrRateIdx] = - (u8)TxErrorRatio; - - OneSecTxNoRetryOKRationCount = (TxSuccess * ratio); - - /* perform DRS - consider TxRate Down first, then rate up. */ - if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) - && (CurrRateIdx != DownRateIdx)) { - if ((pAd->DrsCounters.LastTxOkCount + 2) >= - OneSecTxNoRetryOKRationCount) { - pAd->CommonCfg.TxRateIndex = - DownRateIdx; - pAd->DrsCounters. - TxQuality[CurrRateIdx] = - DRS_TX_QUALITY_WORST_BOUND; - - } - - } else - if ((pAd->DrsCounters.LastSecTxRateChangeAction == - 2) && (CurrRateIdx != UpRateIdx)) { - if ((TxErrorRatio >= 50) - || (TxErrorRatio >= TrainDown)) { - - } else if ((pAd->DrsCounters.LastTxOkCount + 2) - >= OneSecTxNoRetryOKRationCount) { - pAd->CommonCfg.TxRateIndex = UpRateIdx; - } - } - } while (FALSE); - - /* if rate-up happen, clear all bad history of all TX rates */ - if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) { - pAd->DrsCounters.TxRateUpPenalty = 0; - NdisZeroMemory(pAd->DrsCounters.TxQuality, - sizeof(u16)* - MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pAd->DrsCounters.PER, - sizeof(u8)* - MAX_STEP_OF_TX_RATE_SWITCH); - bTxRateChanged = TRUE; - } - /* if rate-down happen, only clear DownRate's bad history */ - else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) { - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("QuickDRS: --TX rate from %d to %d \n", - CurrRateIdx, pAd->CommonCfg.TxRateIndex)); - - pAd->DrsCounters.TxRateUpPenalty = 0; /* no penalty */ - pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = - 0; - pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0; - bTxRateChanged = TRUE; - } else { - bTxRateChanged = FALSE; - } - - pNextTxRate = - (struct rt_rtmp_tx_rate_switch *) & - pTable[(pAd->CommonCfg.TxRateIndex + 1) * 5]; - if (bTxRateChanged && pNextTxRate) { - MlmeSetTxRate(pAd, pEntry, pNextTxRate); - } - } -} - -/* - ========================================================================== - Description: - This routine is executed periodically inside MlmePeriodicExec() after - association with an AP. - It checks if StaCfg.Psm is consistent with user policy (recorded in - StaCfg.WindowsPowerMode). If not, enforce user policy. However, - there're some conditions to consider: - 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all - the time when Mibss==TRUE - 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE - if outgoing traffic available in TxRing or MgmtRing. - Output: - 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32) -{ - unsigned long PowerMode; - - /* condition - */ - /* 1. Psm maybe ON only happen in INFRASTRUCTURE mode */ - /* 2. user wants either MAX_PSP or FAST_PSP */ - /* 3. but current psm is not in PWR_SAVE */ - /* 4. CNTL state machine is not doing SCANning */ - /* 5. no TX SUCCESS event for the past 1-sec period */ - PowerMode = pAd->StaCfg.WindowsPowerMode; - - if (INFRA_ON(pAd) && - (PowerMode != Ndis802_11PowerModeCAM) && - (pAd->StaCfg.Psm == PWR_ACTIVE) && -/* (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) */ - (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && - RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP) - /*&& - (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && - (pAd->RalinkCounters.OneSecTxRetryOkCount == 0) */ - ) { - NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime); - pAd->RalinkCounters.RxCountSinceLastNULL = 0; - RTMP_SET_PSM_BIT(pAd, PWR_SAVE); - if (! - (pAd->CommonCfg.bAPSDCapable - && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) { - RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE); - } else { - RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); - } - } -} - -/* IRQL = PASSIVE_LEVEL */ -/* IRQL = DISPATCH_LEVEL */ -void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm) -{ - AUTO_RSP_CFG_STRUC csr4; - - pAd->StaCfg.Psm = psm; - RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word); - csr4.field.AckCtsPsmBit = (psm == PWR_SAVE) ? 1 : 0; - RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word); - - DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm)); -} - -/* - ========================================================================== - Description: - This routine calculates TxPER, RxPER of the past N-sec period. And - according to the calculation result, ChannelQuality is calculated here - to decide if current AP is still doing the job. - - If ChannelQuality is not good, a ROAMing attempt may be tried later. - Output: - StaCfg.ChannelQuality - 0..100 - - IRQL = DISPATCH_LEVEL - - NOTE: This routine decide channle quality based on RX CRC error ratio. - Caller should make sure a function call to NICUpdateRawCounters(pAd) - is performed right before this routine, so that this routine can decide - channel quality based on the most up-to-date information - ========================================================================== - */ -void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pMacEntry, unsigned long Now32) -{ - unsigned long TxOkCnt, TxCnt, TxPER, TxPRR; - unsigned long RxCnt, RxPER; - u8 NorRssi; - char MaxRssi; - struct rt_rssi_sample *pRssiSample = NULL; - u32 OneSecTxNoRetryOkCount = 0; - u32 OneSecTxRetryOkCount = 0; - u32 OneSecTxFailCount = 0; - u32 OneSecRxOkCnt = 0; - u32 OneSecRxFcsErrCnt = 0; - unsigned long ChannelQuality = 0; /* 0..100, Channel Quality Indication for Roaming */ - unsigned long BeaconLostTime = pAd->StaCfg.BeaconLostTime; - - if (pAd->OpMode == OPMODE_STA) { - pRssiSample = &pAd->StaCfg.RssiSample; - OneSecTxNoRetryOkCount = - pAd->RalinkCounters.OneSecTxNoRetryOkCount; - OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount; - OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount; - OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt; - OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt; - } - - MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0, - pRssiSample->LastRssi1, pRssiSample->LastRssi2); - - /* */ - /* calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics */ - /* */ - TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount; - TxCnt = TxOkCnt + OneSecTxFailCount; - if (TxCnt < 5) { - TxPER = 0; - TxPRR = 0; - } else { - TxPER = (OneSecTxFailCount * 100) / TxCnt; - TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt; - } - - /* */ - /* calculate RX PER - don't take RxPER into consideration if too few sample */ - /* */ - RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt; - if (RxCnt < 5) - RxPER = 0; - else - RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt; - - /* */ - /* decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER */ - /* */ - if ((pAd->OpMode == OPMODE_STA) && INFRA_ON(pAd) && (OneSecTxNoRetryOkCount < 2) && /* no heavy traffic */ - ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32)) { - DBGPRINT(RT_DEBUG_TRACE, - ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", - BeaconLostTime, TxOkCnt)); - ChannelQuality = 0; - } else { - /* Normalize Rssi */ - if (MaxRssi > -40) - NorRssi = 100; - else if (MaxRssi < -90) - NorRssi = 0; - else - NorRssi = (MaxRssi + 90) * 2; - - /* ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) */ - ChannelQuality = (RSSI_WEIGHTING * NorRssi + - TX_WEIGHTING * (100 - TxPRR) + - RX_WEIGHTING * (100 - RxPER)) / 100; - } - - if (pAd->OpMode == OPMODE_STA) - pAd->Mlme.ChannelQuality = - (ChannelQuality > 100) ? 100 : ChannelQuality; - -} - -/* IRQL = DISPATCH_LEVEL */ -void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble) -{ - AUTO_RSP_CFG_STRUC csr4; - - /* */ - /* Always use Long preamble before verifiation short preamble functionality works well. */ - /* Todo: remove the following line if short preamble functionality works */ - /* */ - /*TxPreamble = Rt802_11PreambleLong; */ - - RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word); - if (TxPreamble == Rt802_11PreambleLong) { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeSetTxPreamble (= long PREAMBLE)\n")); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - csr4.field.AutoResponderPreamble = 0; - } else { - /* NOTE: 1Mbps should always use long preamble */ - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeSetTxPreamble (= short PREAMBLE)\n")); - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - csr4.field.AutoResponderPreamble = 1; - } - - RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word); -} - -/* - ========================================================================== - Description: - Update basic rate bitmap - ========================================================================== - */ - -void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAdapter) -{ - int i, j; - /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ - u8 rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; - u8 *sup_p = pAdapter->CommonCfg.SupRate; - u8 *ext_p = pAdapter->CommonCfg.ExtRate; - unsigned long bitmap = pAdapter->CommonCfg.BasicRateBitmap; - - /* if A mode, always use fix BasicRateBitMap */ - /*if (pAdapter->CommonCfg.Channel == PHY_11A) */ - if (pAdapter->CommonCfg.Channel > 14) - pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */ - /* End of if */ - - if (pAdapter->CommonCfg.BasicRateBitmap > 4095) { - /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */ - return; - } - /* End of if */ - for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) { - sup_p[i] &= 0x7f; - ext_p[i] &= 0x7f; - } /* End of for */ - - for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) { - if (bitmap & (1 << i)) { - for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) { - if (sup_p[j] == rate[i]) - sup_p[j] |= 0x80; - /* End of if */ - } /* End of for */ - - for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) { - if (ext_p[j] == rate[i]) - ext_p[j] |= 0x80; - /* End of if */ - } /* End of for */ - } /* End of if */ - } /* End of for */ -} /* End of UpdateBasicRateBitmap */ - -/* IRQL = PASSIVE_LEVEL */ -/* IRQL = DISPATCH_LEVEL */ -/* bLinkUp is to identify the initial link speed. */ -/* TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps. */ -void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx) -{ - int i, num; - u8 Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1; - u8 MinSupport = RATE_54; - unsigned long BasicRateBitmap = 0; - u8 CurrBasicRate = RATE_1; - u8 *pSupRate, SupRateLen, *pExtRate, ExtRateLen; - PHTTRANSMIT_SETTING pHtPhy = NULL; - PHTTRANSMIT_SETTING pMaxHtPhy = NULL; - PHTTRANSMIT_SETTING pMinHtPhy = NULL; - BOOLEAN *auto_rate_cur_p; - u8 HtMcs = MCS_AUTO; - - /* find max desired rate */ - UpdateBasicRateBitmap(pAd); - - num = 0; - auto_rate_cur_p = NULL; - for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) { - switch (pAd->CommonCfg.DesireRate[i] & 0x7f) { - case 2: - Rate = RATE_1; - num++; - break; - case 4: - Rate = RATE_2; - num++; - break; - case 11: - Rate = RATE_5_5; - num++; - break; - case 22: - Rate = RATE_11; - num++; - break; - case 12: - Rate = RATE_6; - num++; - break; - case 18: - Rate = RATE_9; - num++; - break; - case 24: - Rate = RATE_12; - num++; - break; - case 36: - Rate = RATE_18; - num++; - break; - case 48: - Rate = RATE_24; - num++; - break; - case 72: - Rate = RATE_36; - num++; - break; - case 96: - Rate = RATE_48; - num++; - break; - case 108: - Rate = RATE_54; - num++; - break; - /*default: Rate = RATE_1; break; */ - } - if (MaxDesire < Rate) - MaxDesire = Rate; - } - -/*=========================================================================== */ -/*=========================================================================== */ - { - pHtPhy = &pAd->StaCfg.HTPhyMode; - pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; - pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; - - auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch; - HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS; - - if ((pAd->StaCfg.BssType == BSS_ADHOC) && - (pAd->CommonCfg.PhyMode == PHY_11B) && - (MaxDesire > RATE_11)) { - MaxDesire = RATE_11; - } - } - - pAd->CommonCfg.MaxDesiredRate = MaxDesire; - pMinHtPhy->word = 0; - pMaxHtPhy->word = 0; - pHtPhy->word = 0; - - /* Auto rate switching is enabled only if more than one DESIRED RATES are */ - /* specified; otherwise disabled */ - if (num <= 1) { - /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */ - /*pAd->CommonCfg.bAutoTxRateSwitch = FALSE; */ - *auto_rate_cur_p = FALSE; - } else { - /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */ - /*pAd->CommonCfg.bAutoTxRateSwitch = TRUE; */ - *auto_rate_cur_p = TRUE; - } - - if (HtMcs != MCS_AUTO) { - /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */ - /*pAd->CommonCfg.bAutoTxRateSwitch = FALSE; */ - *auto_rate_cur_p = FALSE; - } else { - /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */ - /*pAd->CommonCfg.bAutoTxRateSwitch = TRUE; */ - *auto_rate_cur_p = TRUE; - } - - if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) { - pSupRate = &pAd->StaActive.SupRate[0]; - pExtRate = &pAd->StaActive.ExtRate[0]; - SupRateLen = pAd->StaActive.SupRateLen; - ExtRateLen = pAd->StaActive.ExtRateLen; - } else { - pSupRate = &pAd->CommonCfg.SupRate[0]; - pExtRate = &pAd->CommonCfg.ExtRate[0]; - SupRateLen = pAd->CommonCfg.SupRateLen; - ExtRateLen = pAd->CommonCfg.ExtRateLen; - } - - /* find max supported rate */ - for (i = 0; i < SupRateLen; i++) { - switch (pSupRate[i] & 0x7f) { - case 2: - Rate = RATE_1; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0001; - break; - case 4: - Rate = RATE_2; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0002; - break; - case 11: - Rate = RATE_5_5; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0004; - break; - case 22: - Rate = RATE_11; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0008; - break; - case 12: - Rate = RATE_6; /*if (pSupRate[i] & 0x80) */ - BasicRateBitmap |= 0x0010; - break; - case 18: - Rate = RATE_9; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0020; - break; - case 24: - Rate = RATE_12; /*if (pSupRate[i] & 0x80) */ - BasicRateBitmap |= 0x0040; - break; - case 36: - Rate = RATE_18; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0080; - break; - case 48: - Rate = RATE_24; /*if (pSupRate[i] & 0x80) */ - BasicRateBitmap |= 0x0100; - break; - case 72: - Rate = RATE_36; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0200; - break; - case 96: - Rate = RATE_48; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0400; - break; - case 108: - Rate = RATE_54; - if (pSupRate[i] & 0x80) - BasicRateBitmap |= 0x0800; - break; - default: - Rate = RATE_1; - break; - } - if (MaxSupport < Rate) - MaxSupport = Rate; - - if (MinSupport > Rate) - MinSupport = Rate; - } - - for (i = 0; i < ExtRateLen; i++) { - switch (pExtRate[i] & 0x7f) { - case 2: - Rate = RATE_1; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0001; - break; - case 4: - Rate = RATE_2; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0002; - break; - case 11: - Rate = RATE_5_5; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0004; - break; - case 22: - Rate = RATE_11; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0008; - break; - case 12: - Rate = RATE_6; /*if (pExtRate[i] & 0x80) */ - BasicRateBitmap |= 0x0010; - break; - case 18: - Rate = RATE_9; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0020; - break; - case 24: - Rate = RATE_12; /*if (pExtRate[i] & 0x80) */ - BasicRateBitmap |= 0x0040; - break; - case 36: - Rate = RATE_18; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0080; - break; - case 48: - Rate = RATE_24; /*if (pExtRate[i] & 0x80) */ - BasicRateBitmap |= 0x0100; - break; - case 72: - Rate = RATE_36; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0200; - break; - case 96: - Rate = RATE_48; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0400; - break; - case 108: - Rate = RATE_54; - if (pExtRate[i] & 0x80) - BasicRateBitmap |= 0x0800; - break; - default: - Rate = RATE_1; - break; - } - if (MaxSupport < Rate) - MaxSupport = Rate; - - if (MinSupport > Rate) - MinSupport = Rate; - } - - RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap); - - /* bug fix */ - /* pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; */ - - /* calculate the exptected ACK rate for each TX rate. This info is used to caculate */ - /* the DURATION field of outgoing uniicast DATA/MGMT frame */ - for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) { - if (BasicRateBitmap & (0x01 << i)) - CurrBasicRate = (u8)i; - pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", - RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire])); - /* max tx rate = min {max desire rate, max supported rate} */ - if (MaxSupport < MaxDesire) - pAd->CommonCfg.MaxTxRate = MaxSupport; - else - pAd->CommonCfg.MaxTxRate = MaxDesire; - - pAd->CommonCfg.MinTxRate = MinSupport; - /* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success */ - /* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending */ - /* on average RSSI */ - /* 1. RSSI >= -70db, start at 54 Mbps (short distance) */ - /* 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) */ - /* 3. -75 > RSSI, start at 11 Mbps (long distance) */ - if (*auto_rate_cur_p) { - short dbm = 0; - - dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta; - - if (bLinkUp == TRUE) - pAd->CommonCfg.TxRate = RATE_24; - else - pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - - if (dbm < -75) - pAd->CommonCfg.TxRate = RATE_11; - else if (dbm < -70) - pAd->CommonCfg.TxRate = RATE_24; - - /* should never exceed MaxTxRate (consider 11B-only mode) */ - if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate) - pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - - pAd->CommonCfg.TxRateIndex = 0; - } else { - pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - pHtPhy->field.MCS = - (pAd->CommonCfg.MaxTxRate > - 3) ? (pAd->CommonCfg.MaxTxRate - - 4) : pAd->CommonCfg.MaxTxRate; - pHtPhy->field.MODE = - (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK; - - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = - pHtPhy->field.STBC; - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = - pHtPhy->field.ShortGI; - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = - pHtPhy->field.MCS; - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = - pHtPhy->field.MODE; - } - - if (pAd->CommonCfg.TxRate <= RATE_11) { - pMaxHtPhy->field.MODE = MODE_CCK; - pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate; - pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate; - } else { - pMaxHtPhy->field.MODE = MODE_OFDM; - pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate]; - if (pAd->CommonCfg.MinTxRate >= RATE_6 - && (pAd->CommonCfg.MinTxRate <= RATE_54)) { - pMinHtPhy->field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate]; - } else { - pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate; - } - } - - pHtPhy->word = (pMaxHtPhy->word); - if (bLinkUp && (pAd->OpMode == OPMODE_STA)) { - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word; - pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = - pMaxHtPhy->word; - pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = - pMinHtPhy->word; - } else { - switch (pAd->CommonCfg.PhyMode) { - case PHY_11BG_MIXED: - case PHY_11B: - case PHY_11BGN_MIXED: - pAd->CommonCfg.MlmeRate = RATE_1; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; - pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; - -/*#ifdef WIFI_TEST */ - pAd->CommonCfg.RtsRate = RATE_11; -/*#else */ -/* pAd->CommonCfg.RtsRate = RATE_1; */ -/*#endif */ - break; - case PHY_11G: - case PHY_11A: - case PHY_11AGN_MIXED: - case PHY_11GN_MIXED: - case PHY_11N_2_4G: - case PHY_11AN_MIXED: - case PHY_11N_5G: - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.RtsRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - break; - case PHY_11ABG_MIXED: - case PHY_11ABGN_MIXED: - if (pAd->CommonCfg.Channel <= 14) { - pAd->CommonCfg.MlmeRate = RATE_1; - pAd->CommonCfg.RtsRate = RATE_1; - pAd->CommonCfg.MlmeTransmit.field.MODE = - MODE_CCK; - pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; - } else { - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.RtsRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = - MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - } - break; - default: /* error */ - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - pAd->CommonCfg.RtsRate = RATE_1; - break; - } - /* */ - /* Keep Basic Mlme Rate. */ - /* */ - pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = - pAd->CommonCfg.MlmeTransmit.word; - if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM) - pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = - OfdmRateToRxwiMCS[RATE_24]; - else - pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = - RATE_1; - pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate; - } - - DBGPRINT(RT_DEBUG_TRACE, - (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n", - RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], - RateIdToMbps[pAd->CommonCfg.MaxTxRate], - RateIdToMbps[pAd->CommonCfg.MinTxRate], - /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) */ - *auto_rate_cur_p)); - DBGPRINT(RT_DEBUG_TRACE, - (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n", - RateIdToMbps[pAd->CommonCfg.TxRate], - RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap)); - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n", - pAd->CommonCfg.MlmeTransmit.word, - pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word, - pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word, - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word)); -} - -/* - ========================================================================== - Description: - This function update HT Rate setting. - Input Wcid value is valid for 2 case : - 1. it's used for Station in infra mode that copy AP rate to Mactable. - 2. OR Station in adhoc mode to copy peer's HT rate to Mactable. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx) -{ - u8 StbcMcs; /*j, StbcMcs, bitmask; */ - char i; /* 3*3 */ - struct rt_ht_capability *pRtHtCap = NULL; - struct rt_ht_phy_info *pActiveHtPhy = NULL; - unsigned long BasicMCS; - u8 j, bitmask; - struct rt_ht_phy_info *pDesireHtPhy = NULL; - PHTTRANSMIT_SETTING pHtPhy = NULL; - PHTTRANSMIT_SETTING pMaxHtPhy = NULL; - PHTTRANSMIT_SETTING pMinHtPhy = NULL; - BOOLEAN *auto_rate_cur_p; - - DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates===> \n")); - - auto_rate_cur_p = NULL; - - { - pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; - pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; - pHtPhy = &pAd->StaCfg.HTPhyMode; - pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; - pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; - - auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch; - } - - if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) { - if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) - return; - - pRtHtCap = &pAd->StaActive.SupportedHtPhy; - pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo; - StbcMcs = (u8)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs; - BasicMCS = - pAd->MlmeAux.AddHtInfo.MCSSet[0] + - (pAd->MlmeAux.AddHtInfo.MCSSet[1] << 8) + (StbcMcs << 16); - if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) - && (pAd->Antenna.field.TxPath == 2)) - pMaxHtPhy->field.STBC = STBC_USE; - else - pMaxHtPhy->field.STBC = STBC_NONE; - } else { - if (pDesireHtPhy->bHtEnable == FALSE) - return; - - pRtHtCap = &pAd->CommonCfg.DesiredHtPhy; - StbcMcs = (u8)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs; - BasicMCS = - pAd->CommonCfg.AddHTInfo.MCSSet[0] + - (pAd->CommonCfg.AddHTInfo.MCSSet[1] << 8) + (StbcMcs << 16); - if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) - && (pAd->Antenna.field.TxPath == 2)) - pMaxHtPhy->field.STBC = STBC_USE; - else - pMaxHtPhy->field.STBC = STBC_NONE; - } - - /* Decide MAX ht rate. */ - if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) - pMaxHtPhy->field.MODE = MODE_HTGREENFIELD; - else - pMaxHtPhy->field.MODE = MODE_HTMIX; - - if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) - && (pRtHtCap->ChannelWidth)) - pMaxHtPhy->field.BW = BW_40; - else - pMaxHtPhy->field.BW = BW_20; - - if (pMaxHtPhy->field.BW == BW_20) - pMaxHtPhy->field.ShortGI = - (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap-> - ShortGIfor20); - else - pMaxHtPhy->field.ShortGI = - (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap-> - ShortGIfor40); - - if (pDesireHtPhy->MCSSet[4] != 0) { - pMaxHtPhy->field.MCS = 32; - } - - for (i = 23; i >= 0; i--) /* 3*3 */ - { - j = i / 8; - bitmask = (1 << (i - (j * 8))); - - if ((pActiveHtPhy->MCSSet[j] & bitmask) - && (pDesireHtPhy->MCSSet[j] & bitmask)) { - pMaxHtPhy->field.MCS = i; - break; - } - - if (i == 0) - break; - } - - /* Copy MIN ht rate. rt2860??? */ - pMinHtPhy->field.BW = BW_20; - pMinHtPhy->field.MCS = 0; - pMinHtPhy->field.STBC = 0; - pMinHtPhy->field.ShortGI = 0; - /*If STA assigns fixed rate. update to fixed here. */ - if ((pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) { - if (pDesireHtPhy->MCSSet[4] != 0) { - pMaxHtPhy->field.MCS = 32; - pMinHtPhy->field.MCS = 32; - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n", - pMinHtPhy->field.MCS)); - } - - for (i = 23; (char)i >= 0; i--) /* 3*3 */ - { - j = i / 8; - bitmask = (1 << (i - (j * 8))); - if ((pDesireHtPhy->MCSSet[j] & bitmask) - && (pActiveHtPhy->MCSSet[j] & bitmask)) { - pMaxHtPhy->field.MCS = i; - pMinHtPhy->field.MCS = i; - break; - } - if (i == 0) - break; - } - } - - /* Decide ht rate */ - pHtPhy->field.STBC = pMaxHtPhy->field.STBC; - pHtPhy->field.BW = pMaxHtPhy->field.BW; - pHtPhy->field.MODE = pMaxHtPhy->field.MODE; - pHtPhy->field.MCS = pMaxHtPhy->field.MCS; - pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI; - - /* use default now. rt2860 */ - if (pDesireHtPhy->MCSSet[0] != 0xff) - *auto_rate_cur_p = FALSE; - else - *auto_rate_cur_p = TRUE; - - DBGPRINT(RT_DEBUG_TRACE, - (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", - pAd->CommonCfg.DesiredHtPhy.AmsduSize)); - DBGPRINT(RT_DEBUG_TRACE, - ("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", - pActiveHtPhy->MCSSet[0], pHtPhy->field.MCS, pHtPhy->field.BW, - pHtPhy->field.ShortGI, pHtPhy->field.MODE)); - DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates<=== \n")); -} - -void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab) -{ - int i; - - Tab->numAsOriginator = 0; - Tab->numAsRecipient = 0; - Tab->numDoneOriginator = 0; - NdisAllocateSpinLock(&pAd->BATabLock); - for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) { - Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE; - NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock)); - } - for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) { - Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE; - } -} - -/* IRQL = DISPATCH_LEVEL */ -void MlmeRadioOff(struct rt_rtmp_adapter *pAd) -{ - RTMP_MLME_RADIO_OFF(pAd); -} - -/* IRQL = DISPATCH_LEVEL */ -void MlmeRadioOn(struct rt_rtmp_adapter *pAd) -{ - RTMP_MLME_RADIO_ON(pAd); -} - -/* =========================================================================================== */ -/* bss_table.c */ -/* =========================================================================================== */ - -/*! \brief initialize BSS table - * \param p_tab pointer to the table - * \return none - * \pre - * \post - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - */ -void BssTableInit(struct rt_bss_table *Tab) -{ - int i; - - Tab->BssNr = 0; - Tab->BssOverlapNr = 0; - for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) { - NdisZeroMemory(&Tab->BssEntry[i], sizeof(struct rt_bss_entry)); - Tab->BssEntry[i].Rssi = -127; /* initial the rssi as a minimum value */ - } -} - -/*! \brief search the BSS table by SSID - * \param p_tab pointer to the bss table - * \param ssid SSID string - * \return index of the table, BSS_NOT_FOUND if not in the table - * \pre - * \post - * \note search by sequential search - - IRQL = DISPATCH_LEVEL - - */ -unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel) -{ - u8 i; - - for (i = 0; i < Tab->BssNr; i++) { - /* */ - /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */ - /* We should distinguish this case. */ - /* */ - if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || - ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && - MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) { - return i; - } - } - return (unsigned long)BSS_NOT_FOUND; -} - -unsigned long BssSsidTableSearch(struct rt_bss_table *Tab, - u8 *pBssid, - u8 *pSsid, u8 SsidLen, u8 Channel) -{ - u8 i; - - for (i = 0; i < Tab->BssNr; i++) { - /* */ - /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */ - /* We should distinguish this case. */ - /* */ - if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || - ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && - MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) && - SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, - Tab->BssEntry[i].SsidLen)) { - return i; - } - } - return (unsigned long)BSS_NOT_FOUND; -} - -unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab, - u8 *Bssid, - u8 *pSsid, - u8 SsidLen, u8 Channel) -{ - u8 i; - - for (i = 0; i < Tab->BssNr; i++) { - if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || - ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && - MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) && - (SSID_EQUAL - (pSsid, SsidLen, Tab->BssEntry[i].Ssid, - Tab->BssEntry[i].SsidLen) - || (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) - || - (NdisEqualMemory - (Tab->BssEntry[i].Ssid, ZeroSsid, - Tab->BssEntry[i].SsidLen)))) { - return i; - } - } - return (unsigned long)BSS_NOT_FOUND; -} - -unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab, - u8 *pSsid, u8 SsidLen) -{ - u8 i; - - for (i = 0; i < Tab->BssNr; i++) { - if (SSID_EQUAL - (pSsid, SsidLen, Tab->BssEntry[i].Ssid, - Tab->BssEntry[i].SsidLen)) { - return i; - } - } - return (unsigned long)BSS_NOT_FOUND; -} - -/* IRQL = DISPATCH_LEVEL */ -void BssTableDeleteEntry(struct rt_bss_table *Tab, - u8 *pBssid, u8 Channel) -{ - u8 i, j; - - for (i = 0; i < Tab->BssNr; i++) { - if ((Tab->BssEntry[i].Channel == Channel) && - (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) { - for (j = i; j < Tab->BssNr - 1; j++) { - NdisMoveMemory(&(Tab->BssEntry[j]), - &(Tab->BssEntry[j + 1]), - sizeof(struct rt_bss_entry)); - } - NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), - sizeof(struct rt_bss_entry)); - Tab->BssNr -= 1; - return; - } - } -} - -/* - ======================================================================== - Routine Description: - Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed. - - Arguments: - // IRQL = DISPATCH_LEVEL - ======================================================================== -*/ -void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd, - struct rt_ba_ori_entry *pBAORIEntry) -{ - - if (pBAORIEntry->ORI_BA_Status != Originator_NONE) { - NdisAcquireSpinLock(&pAd->BATabLock); - if (pBAORIEntry->ORI_BA_Status == Originator_Done) { - pAd->BATable.numAsOriginator -= 1; - DBGPRINT(RT_DEBUG_TRACE, - ("BATableDeleteORIEntry numAsOriginator= %ld\n", - pAd->BATable.numAsRecipient)); - /* Erase Bitmap flag. */ - } - pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1 << (pBAORIEntry->TID))); /* If STA mode, erase flag here */ - pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; /* If STA mode, erase flag here */ - pBAORIEntry->ORI_BA_Status = Originator_NONE; - pBAORIEntry->Token = 1; - /* Not clear Sequence here. */ - NdisReleaseSpinLock(&pAd->BATabLock); - } -} - -/*! \brief - * \param - * \return - * \pre - * \post - - IRQL = DISPATCH_LEVEL - - */ -void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * pCfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */ - u8 HtCapabilityLen, - u8 AddHtInfoLen, - u8 NewExtChanOffset, - u8 Channel, - char Rssi, - IN LARGE_INTEGER TimeStamp, - u8 CkipFlag, - struct rt_edca_parm *pEdcaParm, - struct rt_qos_capability_parm *pQosCapability, - struct rt_qbss_load_parm *pQbssLoad, - u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE) -{ - COPY_MAC_ADDR(pBss->Bssid, pBssid); - /* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID */ - pBss->Hidden = 1; - if (SsidLen > 0) { - /* For hidden SSID AP, it might send beacon with SSID len equal to 0 */ - /* Or send beacon /probe response with SSID len matching real SSID length, */ - /* but SSID is all zero. such as "00-00-00-00" with length 4. */ - /* We have to prevent this case overwrite correct table */ - if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) { - NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID); - NdisMoveMemory(pBss->Ssid, Ssid, SsidLen); - pBss->SsidLen = SsidLen; - pBss->Hidden = 0; - } - } else - pBss->SsidLen = 0; - pBss->BssType = BssType; - pBss->BeaconPeriod = BeaconPeriod; - if (BssType == BSS_INFRA) { - if (pCfParm->bValid) { - pBss->CfpCount = pCfParm->CfpCount; - pBss->CfpPeriod = pCfParm->CfpPeriod; - pBss->CfpMaxDuration = pCfParm->CfpMaxDuration; - pBss->CfpDurRemaining = pCfParm->CfpDurRemaining; - } - } else { - pBss->AtimWin = AtimWin; - } - - pBss->CapabilityInfo = CapabilityInfo; - /* The privacy bit indicate security is ON, it maight be WEP, TKIP or AES */ - /* Combine with AuthMode, they will decide the connection methods. */ - pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo); - ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES); - if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES) - NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen); - else - NdisMoveMemory(pBss->SupRate, SupRate, - MAX_LEN_OF_SUPPORTED_RATES); - pBss->SupRateLen = SupRateLen; - ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES); - NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen); - pBss->NewExtChanOffset = NewExtChanOffset; - pBss->ExtRateLen = ExtRateLen; - pBss->Channel = Channel; - pBss->CentralChannel = Channel; - pBss->Rssi = Rssi; - /* Update CkipFlag. if not exists, the value is 0x0 */ - pBss->CkipFlag = CkipFlag; - - /* New for microsoft Fixed IEs */ - NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8); - pBss->FixIEs.BeaconInterval = BeaconPeriod; - pBss->FixIEs.Capabilities = CapabilityInfo; - - /* New for microsoft Variable IEs */ - if (LengthVIE != 0) { - pBss->VarIELen = LengthVIE; - NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen); - } else { - pBss->VarIELen = 0; - } - - pBss->AddHtInfoLen = 0; - pBss->HtCapabilityLen = 0; - if (HtCapabilityLen > 0) { - pBss->HtCapabilityLen = HtCapabilityLen; - NdisMoveMemory(&pBss->HtCapability, pHtCapability, - HtCapabilityLen); - if (AddHtInfoLen > 0) { - pBss->AddHtInfoLen = AddHtInfoLen; - NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, - AddHtInfoLen); - - if ((pAddHtInfo->ControlChan > 2) - && (pAddHtInfo->AddHtInfo.ExtChanOffset == - EXTCHA_BELOW) - && (pHtCapability->HtCapInfo.ChannelWidth == - BW_40)) { - pBss->CentralChannel = - pAddHtInfo->ControlChan - 2; - } else - if ((pAddHtInfo->AddHtInfo.ExtChanOffset == - EXTCHA_ABOVE) - && (pHtCapability->HtCapInfo.ChannelWidth == - BW_40)) { - pBss->CentralChannel = - pAddHtInfo->ControlChan + 2; - } - } - } - - BssCipherParse(pBss); - - /* new for QOS */ - if (pEdcaParm) - NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(struct rt_edca_parm)); - else - pBss->EdcaParm.bValid = FALSE; - if (pQosCapability) - NdisMoveMemory(&pBss->QosCapability, pQosCapability, - sizeof(struct rt_qos_capability_parm)); - else - pBss->QosCapability.bValid = FALSE; - if (pQbssLoad) - NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, - sizeof(struct rt_qbss_load_parm)); - else - pBss->QbssLoad.bValid = FALSE; - - { - struct rt_eid * pEid; - u16 Length = 0; - - NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN); - NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN); - pEid = (struct rt_eid *) pVIE; - while ((Length + 2 + (u16)pEid->Len) <= LengthVIE) { - switch (pEid->Eid) { - case IE_WPA: - if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) { - if ((pEid->Len + 2) > MAX_CUSTOM_LEN) { - pBss->WpaIE.IELen = 0; - break; - } - pBss->WpaIE.IELen = pEid->Len + 2; - NdisMoveMemory(pBss->WpaIE.IE, pEid, - pBss->WpaIE.IELen); - } - break; - case IE_RSN: - if (NdisEqualMemory - (pEid->Octet + 2, RSN_OUI, 3)) { - if ((pEid->Len + 2) > MAX_CUSTOM_LEN) { - pBss->RsnIE.IELen = 0; - break; - } - pBss->RsnIE.IELen = pEid->Len + 2; - NdisMoveMemory(pBss->RsnIE.IE, pEid, - pBss->RsnIE.IELen); - } - break; - } - Length = Length + 2 + (u16)pEid->Len; /* Eid[1] + Len[1]+ content[Len] */ - pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len); - } - } -} - -/*! - * \brief insert an entry into the bss table - * \param p_tab The BSS table - * \param Bssid BSSID - * \param ssid SSID - * \param ssid_len Length of SSID - * \param bss_type - * \param beacon_period - * \param timestamp - * \param p_cf - * \param atim_win - * \param cap - * \param rates - * \param rates_len - * \param channel_idx - * \return none - * \pre - * \post - * \note If SSID is identical, the old entry will be replaced by the new one - - IRQL = DISPATCH_LEVEL - - */ -unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *Tab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */ - u8 HtCapabilityLen, - u8 AddHtInfoLen, - u8 NewExtChanOffset, - u8 ChannelNo, - char Rssi, - IN LARGE_INTEGER TimeStamp, - u8 CkipFlag, - struct rt_edca_parm *pEdcaParm, - struct rt_qos_capability_parm *pQosCapability, - struct rt_qbss_load_parm *pQbssLoad, - u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE) -{ - unsigned long Idx; - - Idx = - BssTableSearchWithSSID(Tab, pBssid, (u8 *) Ssid, SsidLen, - ChannelNo); - if (Idx == BSS_NOT_FOUND) { - if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) { - /* */ - /* It may happen when BSS Table was full. */ - /* The desired AP will not be added into BSS Table */ - /* In this case, if we found the desired AP then overwrite BSS Table. */ - /* */ - if (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) - || SSID_EQUAL(pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen, Ssid, - SsidLen)) { - Idx = Tab->BssOverlapNr; - BssEntrySet(pAd, &Tab->BssEntry[Idx], - pBssid, Ssid, SsidLen, - BssType, BeaconPeriod, - CfParm, AtimWin, - CapabilityInfo, SupRate, - SupRateLen, ExtRate, - ExtRateLen, pHtCapability, - pAddHtInfo, HtCapabilityLen, - AddHtInfoLen, - NewExtChanOffset, ChannelNo, - Rssi, TimeStamp, CkipFlag, - pEdcaParm, pQosCapability, - pQbssLoad, LengthVIE, pVIE); - Tab->BssOverlapNr = - (Tab->BssOverlapNr++) % - MAX_LEN_OF_BSS_TABLE; - } - return Idx; - } else { - return BSS_NOT_FOUND; - } - } - Idx = Tab->BssNr; - BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, - BssType, BeaconPeriod, CfParm, AtimWin, - CapabilityInfo, SupRate, SupRateLen, ExtRate, - ExtRateLen, pHtCapability, pAddHtInfo, - HtCapabilityLen, AddHtInfoLen, NewExtChanOffset, - ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, - pQosCapability, pQbssLoad, LengthVIE, pVIE); - Tab->BssNr++; - } else { - /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */ - if ((SSID_EQUAL - (Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, - Tab->BssEntry[Idx].SsidLen)) - || - (NdisEqualMemory - (Tab->BssEntry[Idx].Ssid, ZeroSsid, - Tab->BssEntry[Idx].SsidLen))) { - BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, - SsidLen, BssType, BeaconPeriod, CfParm, - AtimWin, CapabilityInfo, SupRate, - SupRateLen, ExtRate, ExtRateLen, - pHtCapability, pAddHtInfo, HtCapabilityLen, - AddHtInfoLen, NewExtChanOffset, ChannelNo, - Rssi, TimeStamp, CkipFlag, pEdcaParm, - pQosCapability, pQbssLoad, LengthVIE, pVIE); - } - } - - return Idx; -} - -/* IRQL = DISPATCH_LEVEL */ -void BssTableSsidSort(struct rt_rtmp_adapter *pAd, - struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen) -{ - int i; - BssTableInit(OutTab); - - for (i = 0; i < pAd->ScanTab.BssNr; i++) { - struct rt_bss_entry *pInBss = &pAd->ScanTab.BssEntry[i]; - BOOLEAN bIsHiddenApIncluded = FALSE; - - if (((pAd->CommonCfg.bIEEE80211H == 1) && - (pAd->MlmeAux.Channel > 14) && - RadarChannelCheck(pAd, pInBss->Channel)) - ) { - if (pInBss->Hidden) - bIsHiddenApIncluded = TRUE; - } - - if ((pInBss->BssType == pAd->StaCfg.BssType) && - (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) - || bIsHiddenApIncluded)) { - struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; - - /* 2.4G/5G N only mode */ - if ((pInBss->HtCapabilityLen == 0) && - ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) - || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) { - DBGPRINT(RT_DEBUG_TRACE, - ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); - continue; - } - /* New for WPA2 */ - /* Check the Authmode first */ - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { - /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */ - if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) - && (pAd->StaCfg.AuthMode != - pInBss->AuthModeAux)) - /* None matched */ - continue; - - /* Check cipher suite, AP must have more secured cipher than station setting */ - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPAPSK)) { - /* If it's not mixed mode, we should only let BSS pass with the same encryption */ - if (pInBss->WPA.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != - pInBss->WPA.GroupCipher) - continue; - - /* check group cipher */ - if ((pAd->StaCfg.WepStatus < - pInBss->WPA.GroupCipher) - && (pInBss->WPA.GroupCipher != - Ndis802_11GroupWEP40Enabled) - && (pInBss->WPA.GroupCipher != - Ndis802_11GroupWEP104Enabled)) - continue; - - /* check pairwise cipher, skip if none matched */ - /* If profile set to AES, let it pass without question. */ - /* If profile set to TKIP, we must find one mateched */ - if ((pAd->StaCfg.WepStatus == - Ndis802_11Encryption2Enabled) - && (pAd->StaCfg.WepStatus != - pInBss->WPA.PairCipher) - && (pAd->StaCfg.WepStatus != - pInBss->WPA.PairCipherAux)) - continue; - } else - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2PSK)) { - /* If it's not mixed mode, we should only let BSS pass with the same encryption */ - if (pInBss->WPA2.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != - pInBss->WPA2.GroupCipher) - continue; - - /* check group cipher */ - if ((pAd->StaCfg.WepStatus < - pInBss->WPA.GroupCipher) - && (pInBss->WPA2.GroupCipher != - Ndis802_11GroupWEP40Enabled) - && (pInBss->WPA2.GroupCipher != - Ndis802_11GroupWEP104Enabled)) - continue; - - /* check pairwise cipher, skip if none matched */ - /* If profile set to AES, let it pass without question. */ - /* If profile set to TKIP, we must find one mateched */ - if ((pAd->StaCfg.WepStatus == - Ndis802_11Encryption2Enabled) - && (pAd->StaCfg.WepStatus != - pInBss->WPA2.PairCipher) - && (pAd->StaCfg.WepStatus != - pInBss->WPA2.PairCipherAux)) - continue; - } - } - /* Bss Type matched, SSID matched. */ - /* We will check wepstatus for qualification Bss */ - else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) { - DBGPRINT(RT_DEBUG_TRACE, - ("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", - pAd->StaCfg.WepStatus, - pInBss->WepStatus)); - /* */ - /* For the SESv2 case, we will not qualify WepStatus. */ - /* */ - if (!pInBss->bSES) - continue; - } - /* Since the AP is using hidden SSID, and we are trying to connect to ANY */ - /* It definitely will fail. So, skip it. */ - /* CCX also require not even try to connect it! */ - if (SsidLen == 0) - continue; - - /* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */ - /* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */ - if ((pInBss->CentralChannel != pInBss->Channel) && - (pAd->CommonCfg.RegTransmitSetting.field.BW == - BW_40)) { - if (RTMPCheckChannel - (pAd, pInBss->CentralChannel, - pInBss->Channel) == FALSE) { - pAd->CommonCfg.RegTransmitSetting.field. - BW = BW_20; - SetCommonHT(pAd); - pAd->CommonCfg.RegTransmitSetting.field. - BW = BW_40; - } else { - if (pAd->CommonCfg.DesiredHtPhy. - ChannelWidth == BAND_WIDTH_20) { - SetCommonHT(pAd); - } - } - } - /* copy matching BSS from InTab to OutTab */ - NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry)); - - OutTab->BssNr++; - } else if ((pInBss->BssType == pAd->StaCfg.BssType) - && (SsidLen == 0)) { - struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; - - /* 2.4G/5G N only mode */ - if ((pInBss->HtCapabilityLen == 0) && - ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) - || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) { - DBGPRINT(RT_DEBUG_TRACE, - ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); - continue; - } - /* New for WPA2 */ - /* Check the Authmode first */ - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { - /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */ - if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) - && (pAd->StaCfg.AuthMode != - pInBss->AuthModeAux)) - /* None matched */ - continue; - - /* Check cipher suite, AP must have more secured cipher than station setting */ - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPAPSK)) { - /* If it's not mixed mode, we should only let BSS pass with the same encryption */ - if (pInBss->WPA.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != - pInBss->WPA.GroupCipher) - continue; - - /* check group cipher */ - if (pAd->StaCfg.WepStatus < - pInBss->WPA.GroupCipher) - continue; - - /* check pairwise cipher, skip if none matched */ - /* If profile set to AES, let it pass without question. */ - /* If profile set to TKIP, we must find one mateched */ - if ((pAd->StaCfg.WepStatus == - Ndis802_11Encryption2Enabled) - && (pAd->StaCfg.WepStatus != - pInBss->WPA.PairCipher) - && (pAd->StaCfg.WepStatus != - pInBss->WPA.PairCipherAux)) - continue; - } else - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2PSK)) { - /* If it's not mixed mode, we should only let BSS pass with the same encryption */ - if (pInBss->WPA2.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != - pInBss->WPA2.GroupCipher) - continue; - - /* check group cipher */ - if (pAd->StaCfg.WepStatus < - pInBss->WPA2.GroupCipher) - continue; - - /* check pairwise cipher, skip if none matched */ - /* If profile set to AES, let it pass without question. */ - /* If profile set to TKIP, we must find one mateched */ - if ((pAd->StaCfg.WepStatus == - Ndis802_11Encryption2Enabled) - && (pAd->StaCfg.WepStatus != - pInBss->WPA2.PairCipher) - && (pAd->StaCfg.WepStatus != - pInBss->WPA2.PairCipherAux)) - continue; - } - } - /* Bss Type matched, SSID matched. */ - /* We will check wepstatus for qualification Bss */ - else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) - continue; - - /* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */ - /* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */ - if ((pInBss->CentralChannel != pInBss->Channel) && - (pAd->CommonCfg.RegTransmitSetting.field.BW == - BW_40)) { - if (RTMPCheckChannel - (pAd, pInBss->CentralChannel, - pInBss->Channel) == FALSE) { - pAd->CommonCfg.RegTransmitSetting.field. - BW = BW_20; - SetCommonHT(pAd); - pAd->CommonCfg.RegTransmitSetting.field. - BW = BW_40; - } - } - /* copy matching BSS from InTab to OutTab */ - NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry)); - - OutTab->BssNr++; - } - - if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE) - break; - } - - BssTableSortByRssi(OutTab); -} - -/* IRQL = DISPATCH_LEVEL */ -void BssTableSortByRssi(struct rt_bss_table *OutTab) -{ - int i, j; - struct rt_bss_entry TmpBss; - - for (i = 0; i < OutTab->BssNr - 1; i++) { - for (j = i + 1; j < OutTab->BssNr; j++) { - if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) { - NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], - sizeof(struct rt_bss_entry)); - NdisMoveMemory(&OutTab->BssEntry[j], - &OutTab->BssEntry[i], - sizeof(struct rt_bss_entry)); - NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, - sizeof(struct rt_bss_entry)); - } - } - } -} - -void BssCipherParse(struct rt_bss_entry *pBss) -{ - struct rt_eid * pEid; - u8 *pTmp; - struct rt_rsn_ie_header * pRsnHeader; - struct rt_cipher_suite_struct * pCipher; - struct rt_akm_suite * pAKM; - u16 Count; - int Length; - NDIS_802_11_ENCRYPTION_STATUS TmpCipher; - - /* */ - /* WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. */ - /* */ - if (pBss->Privacy) { - pBss->WepStatus = Ndis802_11WEPEnabled; - } else { - pBss->WepStatus = Ndis802_11WEPDisabled; - } - /* Set default to disable & open authentication before parsing variable IE */ - pBss->AuthMode = Ndis802_11AuthModeOpen; - pBss->AuthModeAux = Ndis802_11AuthModeOpen; - - /* Init WPA setting */ - pBss->WPA.PairCipher = Ndis802_11WEPDisabled; - pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled; - pBss->WPA.GroupCipher = Ndis802_11WEPDisabled; - pBss->WPA.RsnCapability = 0; - pBss->WPA.bMixMode = FALSE; - - /* Init WPA2 setting */ - pBss->WPA2.PairCipher = Ndis802_11WEPDisabled; - pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled; - pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled; - pBss->WPA2.RsnCapability = 0; - pBss->WPA2.bMixMode = FALSE; - - Length = (int)pBss->VarIELen; - - while (Length > 0) { - /* Parse cipher suite base on WPA1 & WPA2, they should be parsed differently */ - pTmp = ((u8 *)pBss->VarIEs) + pBss->VarIELen - Length; - pEid = (struct rt_eid *) pTmp; - switch (pEid->Eid) { - case IE_WPA: - if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) - && (pEid->Len == 7)) { - pBss->bSES = TRUE; - break; - } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != - 1) { - /* if unsupported vendor specific IE */ - break; - } - /* Skip OUI, version, and multicast suite */ - /* This part should be improved in the future when AP supported multiple cipher suite. */ - /* For now, it's OK since almost all APs have fixed cipher suite supported. */ - /* pTmp = (u8 *)pEid->Octet; */ - pTmp += 11; - - /* Cipher Suite Selectors from Spec P802.11i/D3.2 P26. */ - /* Value Meaning */ - /* 0 None */ - /* 1 WEP-40 */ - /* 2 Tkip */ - /* 3 WRAP */ - /* 4 AES */ - /* 5 WEP-104 */ - /* Parse group cipher */ - switch (*pTmp) { - case 1: - pBss->WPA.GroupCipher = - Ndis802_11GroupWEP40Enabled; - break; - case 5: - pBss->WPA.GroupCipher = - Ndis802_11GroupWEP104Enabled; - break; - case 2: - pBss->WPA.GroupCipher = - Ndis802_11Encryption2Enabled; - break; - case 4: - pBss->WPA.GroupCipher = - Ndis802_11Encryption3Enabled; - break; - default: - break; - } - /* number of unicast suite */ - pTmp += 1; - - /* skip all unicast cipher suites */ - /*Count = *(u16 *)pTmp; */ - Count = (pTmp[1] << 8) + pTmp[0]; - pTmp += sizeof(u16); - - /* Parsing all unicast cipher suite */ - while (Count > 0) { - /* Skip OUI */ - pTmp += 3; - TmpCipher = Ndis802_11WEPDisabled; - switch (*pTmp) { - case 1: - case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */ - TmpCipher = - Ndis802_11Encryption1Enabled; - break; - case 2: - TmpCipher = - Ndis802_11Encryption2Enabled; - break; - case 4: - TmpCipher = - Ndis802_11Encryption3Enabled; - break; - default: - break; - } - if (TmpCipher > pBss->WPA.PairCipher) { - /* Move the lower cipher suite to PairCipherAux */ - pBss->WPA.PairCipherAux = - pBss->WPA.PairCipher; - pBss->WPA.PairCipher = TmpCipher; - } else { - pBss->WPA.PairCipherAux = TmpCipher; - } - pTmp++; - Count--; - } - - /* 4. get AKM suite counts */ - /*Count = *(u16 *)pTmp; */ - Count = (pTmp[1] << 8) + pTmp[0]; - pTmp += sizeof(u16); - pTmp += 3; - - switch (*pTmp) { - case 1: - /* Set AP support WPA-enterprise mode */ - if (pBss->AuthMode == Ndis802_11AuthModeOpen) - pBss->AuthMode = Ndis802_11AuthModeWPA; - else - pBss->AuthModeAux = - Ndis802_11AuthModeWPA; - break; - case 2: - /* Set AP support WPA-PSK mode */ - if (pBss->AuthMode == Ndis802_11AuthModeOpen) - pBss->AuthMode = - Ndis802_11AuthModeWPAPSK; - else - pBss->AuthModeAux = - Ndis802_11AuthModeWPAPSK; - break; - default: - break; - } - pTmp += 1; - - /* Fixed for WPA-None */ - if (pBss->BssType == BSS_ADHOC) { - pBss->AuthMode = Ndis802_11AuthModeWPANone; - pBss->AuthModeAux = Ndis802_11AuthModeWPANone; - pBss->WepStatus = pBss->WPA.GroupCipher; - /* Patched bugs for old driver */ - if (pBss->WPA.PairCipherAux == - Ndis802_11WEPDisabled) - pBss->WPA.PairCipherAux = - pBss->WPA.GroupCipher; - } else - pBss->WepStatus = pBss->WPA.PairCipher; - - /* Check the Pair & Group, if different, turn on mixed mode flag */ - if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher) - pBss->WPA.bMixMode = TRUE; - - break; - - case IE_RSN: - pRsnHeader = (struct rt_rsn_ie_header *) pTmp; - - /* 0. Version must be 1 */ - if (le2cpu16(pRsnHeader->Version) != 1) - break; - pTmp += sizeof(struct rt_rsn_ie_header); - - /* 1. Check group cipher */ - pCipher = (struct rt_cipher_suite_struct *) pTmp; - if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) - break; - - /* Parse group cipher */ - switch (pCipher->Type) { - case 1: - pBss->WPA2.GroupCipher = - Ndis802_11GroupWEP40Enabled; - break; - case 5: - pBss->WPA2.GroupCipher = - Ndis802_11GroupWEP104Enabled; - break; - case 2: - pBss->WPA2.GroupCipher = - Ndis802_11Encryption2Enabled; - break; - case 4: - pBss->WPA2.GroupCipher = - Ndis802_11Encryption3Enabled; - break; - default: - break; - } - /* set to correct offset for next parsing */ - pTmp += sizeof(struct rt_cipher_suite_struct); - - /* 2. Get pairwise cipher counts */ - /*Count = *(u16 *)pTmp; */ - Count = (pTmp[1] << 8) + pTmp[0]; - pTmp += sizeof(u16); - - /* 3. Get pairwise cipher */ - /* Parsing all unicast cipher suite */ - while (Count > 0) { - /* Skip OUI */ - pCipher = (struct rt_cipher_suite_struct *) pTmp; - TmpCipher = Ndis802_11WEPDisabled; - switch (pCipher->Type) { - case 1: - case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */ - TmpCipher = - Ndis802_11Encryption1Enabled; - break; - case 2: - TmpCipher = - Ndis802_11Encryption2Enabled; - break; - case 4: - TmpCipher = - Ndis802_11Encryption3Enabled; - break; - default: - break; - } - if (TmpCipher > pBss->WPA2.PairCipher) { - /* Move the lower cipher suite to PairCipherAux */ - pBss->WPA2.PairCipherAux = - pBss->WPA2.PairCipher; - pBss->WPA2.PairCipher = TmpCipher; - } else { - pBss->WPA2.PairCipherAux = TmpCipher; - } - pTmp += sizeof(struct rt_cipher_suite_struct); - Count--; - } - - /* 4. get AKM suite counts */ - /*Count = *(u16 *)pTmp; */ - Count = (pTmp[1] << 8) + pTmp[0]; - pTmp += sizeof(u16); - - /* 5. Get AKM ciphers */ - /* Parsing all AKM ciphers */ - while (Count > 0) { - pAKM = (struct rt_akm_suite *) pTmp; - if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) - break; - - switch (pAKM->Type) { - case 1: - /* Set AP support WPA-enterprise mode */ - if (pBss->AuthMode == - Ndis802_11AuthModeOpen) - pBss->AuthMode = - Ndis802_11AuthModeWPA2; - else - pBss->AuthModeAux = - Ndis802_11AuthModeWPA2; - break; - case 2: - /* Set AP support WPA-PSK mode */ - if (pBss->AuthMode == - Ndis802_11AuthModeOpen) - pBss->AuthMode = - Ndis802_11AuthModeWPA2PSK; - else - pBss->AuthModeAux = - Ndis802_11AuthModeWPA2PSK; - break; - default: - if (pBss->AuthMode == - Ndis802_11AuthModeOpen) - pBss->AuthMode = - Ndis802_11AuthModeMax; - else - pBss->AuthModeAux = - Ndis802_11AuthModeMax; - break; - } - pTmp += (Count * sizeof(struct rt_akm_suite)); - Count--; - } - - /* Fixed for WPA-None */ - if (pBss->BssType == BSS_ADHOC) { - pBss->AuthMode = Ndis802_11AuthModeWPANone; - pBss->AuthModeAux = Ndis802_11AuthModeWPANone; - pBss->WPA.PairCipherAux = - pBss->WPA2.PairCipherAux; - pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher; - pBss->WepStatus = pBss->WPA.GroupCipher; - /* Patched bugs for old driver */ - if (pBss->WPA.PairCipherAux == - Ndis802_11WEPDisabled) - pBss->WPA.PairCipherAux = - pBss->WPA.GroupCipher; - } - pBss->WepStatus = pBss->WPA2.PairCipher; - - /* 6. Get RSN capability */ - /*pBss->WPA2.RsnCapability = *(u16 *)pTmp; */ - pBss->WPA2.RsnCapability = (pTmp[1] << 8) + pTmp[0]; - pTmp += sizeof(u16); - - /* Check the Pair & Group, if different, turn on mixed mode flag */ - if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher) - pBss->WPA2.bMixMode = TRUE; - - break; - default: - break; - } - Length -= (pEid->Len + 2); - } -} - -/* =========================================================================================== */ -/* mac_table.c */ -/* =========================================================================================== */ - -/*! \brief generates a random mac address value for IBSS BSSID - * \param Addr the bssid location - * \return none - * \pre - * \post - */ -void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr) -{ - int i; - - for (i = 0; i < MAC_ADDR_LEN; i++) { - pAddr[i] = RandomByte(pAd); - } - - pAddr[0] = (pAddr[0] & 0xfe) | 0x02; /* the first 2 bits must be 01xxxxxxxx */ -} - -/*! \brief init the management mac frame header - * \param p_hdr mac header - * \param subtype subtype of the frame - * \param p_ds destination address, don't care if it is a broadcast address - * \return none - * \pre the station has the following information in the pAd->StaCfg - * - bssid - * - station address - * \post - * \note this function initializes the following field - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - */ -void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, - u8 SubType, - u8 ToDs, u8 *pDA, u8 *pBssid) -{ - NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11)); - - pHdr80211->FC.Type = BTYPE_MGMT; - pHdr80211->FC.SubType = SubType; -/* if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type */ -/* pHdr80211->FC.Type = BTYPE_CNTL; */ - pHdr80211->FC.ToDs = ToDs; - COPY_MAC_ADDR(pHdr80211->Addr1, pDA); - COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress); - COPY_MAC_ADDR(pHdr80211->Addr3, pBssid); -} - -/* =========================================================================================== */ -/* mem_mgmt.c */ -/* =========================================================================================== */ - -/*!*************************************************************************** - * This routine build an outgoing frame, and fill all information specified - * in argument list to the frame body. The actual frame size is the summation - * of all arguments. - * input params: - * Buffer - pointer to a pre-allocated memory segment - * args - a list of pairs. - * NOTE NOTE NOTE! the last argument must be NULL, otherwise this - * function will FAIL! - * return: - * Size of the buffer - * usage: - * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS); - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ****************************************************************************/ -unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * FrameLen, ...) -{ - u8 *p; - int leng; - unsigned long TotLeng; - va_list Args; - - /* calculates the total length */ - TotLeng = 0; - va_start(Args, FrameLen); - do { - leng = va_arg(Args, int); - if (leng == END_OF_ARGS) { - break; - } - p = va_arg(Args, void *); - NdisMoveMemory(&Buffer[TotLeng], p, leng); - TotLeng = TotLeng + leng; - } while (TRUE); - - va_end(Args); /* clean up */ - *FrameLen = TotLeng; - return TotLeng; -} - -/* =========================================================================================== */ -/* mlme_queue.c */ -/* =========================================================================================== */ - -/*! \brief Initialize The MLME Queue, used by MLME Functions - * \param *Queue The MLME Queue - * \return Always Return NDIS_STATE_SUCCESS in this implementation - * \pre - * \post - * \note Because this is done only once (at the init stage), no need to be locked - - IRQL = PASSIVE_LEVEL - - */ -int MlmeQueueInit(struct rt_mlme_queue *Queue) -{ - int i; - - NdisAllocateSpinLock(&Queue->Lock); - - Queue->Num = 0; - Queue->Head = 0; - Queue->Tail = 0; - - for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) { - Queue->Entry[i].Occupied = FALSE; - Queue->Entry[i].MsgLen = 0; - NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE); - } - - return NDIS_STATUS_SUCCESS; -} - -/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread - * \param *Queue The MLME Queue - * \param Machine The State Machine Id - * \param MsgType The Message Type - * \param MsgLen The Message length - * \param *Msg The message pointer - * \return TRUE if enqueue is successful, FALSE if the queue is full - * \pre - * \post - * \note The message has to be initialized - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - */ -BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd, - unsigned long Machine, - unsigned long MsgType, unsigned long MsgLen, void * Msg) -{ - int Tail; - struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return FALSE; - - /* First check the size, it MUST not exceed the mlme queue size */ - if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR("MlmeEnqueue: msg too large, size = %ld \n", MsgLen); - return FALSE; - } - - if (MlmeQueueFull(Queue)) { - return FALSE; - } - - NdisAcquireSpinLock(&(Queue->Lock)); - Tail = Queue->Tail; - Queue->Tail++; - Queue->Num++; - if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) { - Queue->Tail = 0; - } - - Queue->Entry[Tail].Wcid = RESERVED_WCID; - Queue->Entry[Tail].Occupied = TRUE; - Queue->Entry[Tail].Machine = Machine; - Queue->Entry[Tail].MsgType = MsgType; - Queue->Entry[Tail].MsgLen = MsgLen; - - if (Msg != NULL) { - NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); - } - - NdisReleaseSpinLock(&(Queue->Lock)); - return TRUE; -} - -/*! \brief This function is used when Recv gets a MLME message - * \param *Queue The MLME Queue - * \param TimeStampHigh The upper 32 bit of timestamp - * \param TimeStampLow The lower 32 bit of timestamp - * \param Rssi The receiving RSSI strength - * \param MsgLen The length of the message - * \param *Msg The message pointer - * \return TRUE if everything ok, FALSE otherwise (like Queue Full) - * \pre - * \post - - IRQL = DISPATCH_LEVEL - - */ -BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd, - unsigned long Wcid, - unsigned long TimeStampHigh, - unsigned long TimeStampLow, - u8 Rssi0, - u8 Rssi1, - u8 Rssi2, - unsigned long MsgLen, void * Msg, u8 Signal) -{ - int Tail, Machine; - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - int MsgType; - struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, - fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) { - DBGPRINT_ERR("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"); - return FALSE; - } - /* First check the size, it MUST not exceed the mlme queue size */ - if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen); - return FALSE; - } - - if (MlmeQueueFull(Queue)) { - return FALSE; - } - - { - if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) { - DBGPRINT_ERR("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType); - return FALSE; - } - } - - /* OK, we got all the informations, it is time to put things into queue */ - NdisAcquireSpinLock(&(Queue->Lock)); - Tail = Queue->Tail; - Queue->Tail++; - Queue->Num++; - if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) { - Queue->Tail = 0; - } - Queue->Entry[Tail].Occupied = TRUE; - Queue->Entry[Tail].Machine = Machine; - Queue->Entry[Tail].MsgType = MsgType; - Queue->Entry[Tail].MsgLen = MsgLen; - Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow; - Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh; - Queue->Entry[Tail].Rssi0 = Rssi0; - Queue->Entry[Tail].Rssi1 = Rssi1; - Queue->Entry[Tail].Rssi2 = Rssi2; - Queue->Entry[Tail].Signal = Signal; - Queue->Entry[Tail].Wcid = (u8)Wcid; - - Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel; - - if (Msg != NULL) { - NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); - } - - NdisReleaseSpinLock(&(Queue->Lock)); - - RTMP_MLME_HANDLER(pAd); - - return TRUE; -} - -/*! \brief Dequeue a message from the MLME Queue - * \param *Queue The MLME Queue - * \param *Elem The message dequeued from MLME Queue - * \return TRUE if the Elem contains something, FALSE otherwise - * \pre - * \post - - IRQL = DISPATCH_LEVEL - - */ -BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem) -{ - NdisAcquireSpinLock(&(Queue->Lock)); - *Elem = &(Queue->Entry[Queue->Head]); - Queue->Num--; - Queue->Head++; - if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) { - Queue->Head = 0; - } - NdisReleaseSpinLock(&(Queue->Lock)); - return TRUE; -} - -/* IRQL = DISPATCH_LEVEL */ -void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd) -{ -#ifdef RTMP_MAC_PCI - struct rt_mlme_queue_elem *Elem = NULL; -#endif /* RTMP_MAC_PCI // */ - BOOLEAN Cancelled; - - DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n")); - -#ifdef RTMP_MAC_PCI - NdisAcquireSpinLock(&pAd->Mlme.TaskLock); - if (pAd->Mlme.bRunning) { - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); - return; - } else { - pAd->Mlme.bRunning = TRUE; - } - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); - - /* Remove all Mlme queues elements */ - while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) { - /*From message type, determine which state machine I should drive */ - if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) { - /* free MLME element */ - Elem->Occupied = FALSE; - Elem->MsgLen = 0; - - } else { - DBGPRINT_ERR("MlmeRestartStateMachine: MlmeQueue empty\n"); - } - } -#endif /* RTMP_MAC_PCI // */ - - { - /* Cancel all timer events */ - /* Be careful to cancel new added timer */ - RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); - - } - - /* Change back to original channel in case of doing scan */ - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - - /* Resume MSDU which is turned off durning scan */ - RTMPResumeMsduTransmission(pAd); - - { - /* Set all state machines back IDLE */ - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - pAd->Mlme.ActMachine.CurrState = ACT_IDLE; - } - -#ifdef RTMP_MAC_PCI - /* Remove running state */ - NdisAcquireSpinLock(&pAd->Mlme.TaskLock); - pAd->Mlme.bRunning = FALSE; - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); -#endif /* RTMP_MAC_PCI // */ -} - -/*! \brief test if the MLME Queue is empty - * \param *Queue The MLME Queue - * \return TRUE if the Queue is empty, FALSE otherwise - * \pre - * \post - - IRQL = DISPATCH_LEVEL - - */ -BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue) -{ - BOOLEAN Ans; - - NdisAcquireSpinLock(&(Queue->Lock)); - Ans = (Queue->Num == 0); - NdisReleaseSpinLock(&(Queue->Lock)); - - return Ans; -} - -/*! \brief test if the MLME Queue is full - * \param *Queue The MLME Queue - * \return TRUE if the Queue is empty, FALSE otherwise - * \pre - * \post - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - */ -BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue) -{ - BOOLEAN Ans; - - NdisAcquireSpinLock(&(Queue->Lock)); - Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE - || Queue->Entry[Queue->Tail].Occupied); - NdisReleaseSpinLock(&(Queue->Lock)); - - return Ans; -} - -/*! \brief The destructor of MLME Queue - * \param - * \return - * \pre - * \post - * \note Clear Mlme Queue, Set Queue->Num to Zero. - - IRQL = PASSIVE_LEVEL - - */ -void MlmeQueueDestroy(struct rt_mlme_queue *pQueue) -{ - NdisAcquireSpinLock(&(pQueue->Lock)); - pQueue->Num = 0; - pQueue->Head = 0; - pQueue->Tail = 0; - NdisReleaseSpinLock(&(pQueue->Lock)); - NdisFreeSpinLock(&(pQueue->Lock)); -} - -/*! \brief To substitute the message type if the message is coming from external - * \param pFrame The frame received - * \param *Machine The state machine - * \param *MsgType the message type for the state machine - * \return TRUE if the substitution is successful, FALSE otherwise - * \pre - * \post - - IRQL = DISPATCH_LEVEL - - */ -BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd, - struct rt_frame_802_11 * pFrame, - int * Machine, int * MsgType) -{ - u16 Seq, Alg; - u8 EAPType; - u8 *pData; - - /* Pointer to start of data frames including SNAP header */ - pData = (u8 *)pFrame + LENGTH_802_11; - - /* The only data type will pass to this function is EAPOL frame */ - if (pFrame->Hdr.FC.Type == BTYPE_DATA) { - { - *Machine = WPA_STATE_MACHINE; - EAPType = - *((u8 *) pFrame + LENGTH_802_11 + - LENGTH_802_1_H + 1); - return (WpaMsgTypeSubst(EAPType, (int *) MsgType)); - } - } - - switch (pFrame->Hdr.FC.SubType) { - case SUBTYPE_ASSOC_REQ: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_ASSOC_REQ; - break; - case SUBTYPE_ASSOC_RSP: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_ASSOC_RSP; - break; - case SUBTYPE_REASSOC_REQ: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_REASSOC_REQ; - break; - case SUBTYPE_REASSOC_RSP: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_REASSOC_RSP; - break; - case SUBTYPE_PROBE_REQ: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_PROBE_REQ; - break; - case SUBTYPE_PROBE_RSP: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_PROBE_RSP; - break; - case SUBTYPE_BEACON: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_BEACON; - break; - case SUBTYPE_ATIM: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_ATIM; - break; - case SUBTYPE_DISASSOC: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_DISASSOC_REQ; - break; - case SUBTYPE_AUTH: - /* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */ - NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(u16)); - NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(u16)); - if (Seq == 1 || Seq == 3) { - *Machine = AUTH_RSP_STATE_MACHINE; - *MsgType = MT2_PEER_AUTH_ODD; - } else if (Seq == 2 || Seq == 4) { - if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) { - *Machine = AUTH_STATE_MACHINE; - *MsgType = MT2_PEER_AUTH_EVEN; - } - } else { - return FALSE; - } - break; - case SUBTYPE_DEAUTH: - *Machine = AUTH_RSP_STATE_MACHINE; - *MsgType = MT2_PEER_DEAUTH; - break; - case SUBTYPE_ACTION: - *Machine = ACTION_STATE_MACHINE; - /* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */ - if ((pFrame->Octet[0] & 0x7F) > MAX_PEER_CATE_MSG) { - *MsgType = MT2_ACT_INVALID; - } else { - *MsgType = (pFrame->Octet[0] & 0x7F); - } - break; - default: - return FALSE; - break; - } - - return TRUE; -} - -/* =========================================================================================== */ -/* state_machine.c */ -/* =========================================================================================== */ - -/*! \brief Initialize the state machine. - * \param *S pointer to the state machine - * \param Trans State machine transition function - * \param StNr number of states - * \param MsgNr number of messages - * \param DefFunc default function, when there is invalid state/message combination - * \param InitState initial state of the state machine - * \param Base StateMachine base, internal use only - * \pre p_sm should be a legal pointer - * \post - - IRQL = PASSIVE_LEVEL - - */ -void StateMachineInit(struct rt_state_machine *S, - IN STATE_MACHINE_FUNC Trans[], - unsigned long StNr, - unsigned long MsgNr, - IN STATE_MACHINE_FUNC DefFunc, - unsigned long InitState, unsigned long Base) -{ - unsigned long i, j; - - /* set number of states and messages */ - S->NrState = StNr; - S->NrMsg = MsgNr; - S->Base = Base; - - S->TransFunc = Trans; - - /* init all state transition to default function */ - for (i = 0; i < StNr; i++) { - for (j = 0; j < MsgNr; j++) { - S->TransFunc[i * MsgNr + j] = DefFunc; - } - } - - /* set the starting state */ - S->CurrState = InitState; -} - -/*! \brief This function fills in the function pointer into the cell in the state machine - * \param *S pointer to the state machine - * \param St state - * \param Msg incoming message - * \param f the function to be executed when (state, message) combination occurs at the state machine - * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state - * \post - - IRQL = PASSIVE_LEVEL - - */ -void StateMachineSetAction(struct rt_state_machine *S, - unsigned long St, - unsigned long Msg, IN STATE_MACHINE_FUNC Func) -{ - unsigned long MsgIdx; - - MsgIdx = Msg - S->Base; - - if (St < S->NrState && MsgIdx < S->NrMsg) { - /* boundary checking before setting the action */ - S->TransFunc[St * S->NrMsg + MsgIdx] = Func; - } -} - -/*! \brief This function does the state transition - * \param *Adapter the NIC adapter pointer - * \param *S the state machine - * \param *Elem the message to be executed - * \return None - - IRQL = DISPATCH_LEVEL - - */ -void StateMachinePerformAction(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem) -{ - (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base])) - (pAd, Elem); -} - -/* - ========================================================================== - Description: - The drop function, when machine executes this, the message is simply - ignored. This function does nothing, the message is freed in - StateMachinePerformAction() - ========================================================================== - */ -void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -/* =========================================================================================== */ -/* lfsr.c */ -/* =========================================================================================== */ - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed) -{ - if (Seed == 0) - pAd->Mlme.ShiftReg = 1; - else - pAd->Mlme.ShiftReg = Seed; -} - -/* - ========================================================================== - Description: - ========================================================================== - */ -u8 RandomByte(struct rt_rtmp_adapter *pAd) -{ - unsigned long i; - u8 R, Result; - - R = 0; - - if (pAd->Mlme.ShiftReg == 0) - NdisGetSystemUpTime((unsigned long *) & pAd->Mlme.ShiftReg); - - for (i = 0; i < 8; i++) { - if (pAd->Mlme.ShiftReg & 0x00000001) { - pAd->Mlme.ShiftReg = - ((pAd->Mlme. - ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000; - Result = 1; - } else { - pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1; - Result = 0; - } - R = (R << 1) | Result; - } - - return R; -} - -/* - ======================================================================== - - Routine Description: - Verify the support rate for different PHY type - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -void RTMPCheckRates(struct rt_rtmp_adapter *pAd, - IN u8 SupRate[], IN u8 * SupRateLen) -{ - u8 RateIdx, i, j; - u8 NewRate[12], NewRateLen; - - NewRateLen = 0; - - if (pAd->CommonCfg.PhyMode == PHY_11B) - RateIdx = 4; - else - RateIdx = 12; - - /* Check for support rates exclude basic rate bit */ - for (i = 0; i < *SupRateLen; i++) - for (j = 0; j < RateIdx; j++) - if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j]) - NewRate[NewRateLen++] = SupRate[i]; - - *SupRateLen = NewRateLen; - NdisMoveMemory(SupRate, NewRate, NewRateLen); -} - -BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd, - u8 CentralChannel, u8 Channel) -{ - u8 k; - u8 UpperChannel = 0, LowerChannel = 0; - u8 NoEffectChannelinList = 0; - - /* Find upper and lower channel according to 40MHz current operation. */ - if (CentralChannel < Channel) { - UpperChannel = Channel; - if (CentralChannel > 2) - LowerChannel = CentralChannel - 2; - else - return FALSE; - } else if (CentralChannel > Channel) { - UpperChannel = CentralChannel + 2; - LowerChannel = Channel; - } - - for (k = 0; k < pAd->ChannelListNum; k++) { - if (pAd->ChannelList[k].Channel == UpperChannel) { - NoEffectChannelinList++; - } - if (pAd->ChannelList[k].Channel == LowerChannel) { - NoEffectChannelinList++; - } - } - - DBGPRINT(RT_DEBUG_TRACE, - ("Total Channel in Channel List = [%d]\n", - NoEffectChannelinList)); - if (NoEffectChannelinList == 2) - return TRUE; - else - return FALSE; -} - -/* - ======================================================================== - - Routine Description: - Verify the support rate for HT phy type - - Arguments: - pAd Pointer to our adapter - - Return Value: - FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode) - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd, - u8 Wcid, - struct rt_ht_capability_ie * pHtCapability, - struct rt_add_ht_info_ie * pAddHtInfo) -{ - if (Wcid >= MAX_LEN_OF_MAC_TABLE) - return FALSE; - - /* If use AMSDU, set flag. */ - if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], - fCLIENT_STATUS_AMSDU_INUSED); - /* Save Peer Capability */ - if (pHtCapability->HtCapInfo.ShortGIfor20) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], - fCLIENT_STATUS_SGI20_CAPABLE); - if (pHtCapability->HtCapInfo.ShortGIfor40) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], - fCLIENT_STATUS_SGI40_CAPABLE); - if (pHtCapability->HtCapInfo.TxSTBC) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], - fCLIENT_STATUS_TxSTBC_CAPABLE); - if (pHtCapability->HtCapInfo.RxSTBC) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], - fCLIENT_STATUS_RxSTBC_CAPABLE); - if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) { - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], - fCLIENT_STATUS_RDG_CAPABLE); - } - - if (Wcid < MAX_LEN_OF_MAC_TABLE) { - pAd->MacTab.Content[Wcid].MpduDensity = - pHtCapability->HtCapParm.MpduDensity; - } - /* Will check ChannelWidth for MCSSet[4] below */ - pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1; - switch (pAd->CommonCfg.RxStream) { - case 1: - pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; - pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00; - pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00; - pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00; - break; - case 2: - pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; - pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff; - pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00; - pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00; - break; - case 3: - pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff; - pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff; - pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff; - pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00; - break; - } - - pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = - pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy. - ChannelWidth; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n", - pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, - pAddHtInfo->AddHtInfo.RecomWidth, - pAd->CommonCfg.DesiredHtPhy.ChannelWidth, - pAd->NicConfig2.field.BW40MAvailForA, - pAd->NicConfig2.field.BW40MAvailForG, - pAd->CommonCfg.PhyMode)); - - pAd->MlmeAux.HtCapability.HtCapInfo.GF = - pHtCapability->HtCapInfo.GF & pAd->CommonCfg.DesiredHtPhy.GF; - - /* Send Assoc Req with my HT capability. */ - pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = - pAd->CommonCfg.DesiredHtPhy.AmsduSize; - pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = - pAd->CommonCfg.DesiredHtPhy.MimoPs; - pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = - (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability-> - HtCapInfo. - ShortGIfor20); - pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = - (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability-> - HtCapInfo. - ShortGIfor40); - pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = - (pAd->CommonCfg.DesiredHtPhy.TxSTBC) & (pHtCapability->HtCapInfo. - RxSTBC); - pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = - (pAd->CommonCfg.DesiredHtPhy.RxSTBC) & (pHtCapability->HtCapInfo. - TxSTBC); - pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = - pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor; - pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = - pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity; - pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = - pHtCapability->ExtHtCapInfo.PlusHTC; - pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = - pHtCapability->ExtHtCapInfo.PlusHTC; - if (pAd->CommonCfg.bRdg) { - pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = - pHtCapability->ExtHtCapInfo.RDGSupport; - pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1; - } - - if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20) - pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; /* BW20 can't transmit MCS32 */ - - COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability); - return TRUE; -} - -/* - ======================================================================== - - Routine Description: - Verify the support rate for different PHY type - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd) -{ - u8 MinimumRate; - u8 ProperMlmeRate; /*= RATE_54; */ - u8 i, j, RateIdx = 12; /*1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ - BOOLEAN bMatch = FALSE; - - switch (pAd->CommonCfg.PhyMode) { - case PHY_11B: - ProperMlmeRate = RATE_11; - MinimumRate = RATE_1; - break; - case PHY_11BG_MIXED: - case PHY_11ABGN_MIXED: - case PHY_11BGN_MIXED: - if ((pAd->MlmeAux.SupRateLen == 4) && - (pAd->MlmeAux.ExtRateLen == 0)) - /* B only AP */ - ProperMlmeRate = RATE_11; - else - ProperMlmeRate = RATE_24; - - if (pAd->MlmeAux.Channel <= 14) - MinimumRate = RATE_1; - else - MinimumRate = RATE_6; - break; - case PHY_11A: - case PHY_11N_2_4G: /* rt2860 need to check mlmerate for 802.11n */ - case PHY_11GN_MIXED: - case PHY_11AGN_MIXED: - case PHY_11AN_MIXED: - case PHY_11N_5G: - ProperMlmeRate = RATE_24; - MinimumRate = RATE_6; - break; - case PHY_11ABG_MIXED: - ProperMlmeRate = RATE_24; - if (pAd->MlmeAux.Channel <= 14) - MinimumRate = RATE_1; - else - MinimumRate = RATE_6; - break; - default: /* error */ - ProperMlmeRate = RATE_1; - MinimumRate = RATE_1; - break; - } - - for (i = 0; i < pAd->MlmeAux.SupRateLen; i++) { - for (j = 0; j < RateIdx; j++) { - if ((pAd->MlmeAux.SupRate[i] & 0x7f) == - RateIdTo500Kbps[j]) { - if (j == ProperMlmeRate) { - bMatch = TRUE; - break; - } - } - } - - if (bMatch) - break; - } - - if (bMatch == FALSE) { - for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++) { - for (j = 0; j < RateIdx; j++) { - if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == - RateIdTo500Kbps[j]) { - if (j == ProperMlmeRate) { - bMatch = TRUE; - break; - } - } - } - - if (bMatch) - break; - } - } - - if (bMatch == FALSE) { - ProperMlmeRate = MinimumRate; - } - - pAd->CommonCfg.MlmeRate = MinimumRate; - pAd->CommonCfg.RtsRate = ProperMlmeRate; - if (pAd->CommonCfg.MlmeRate >= RATE_6) { - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = - MODE_OFDM; - pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - } else { - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; - pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate; - pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = - MODE_CCK; - pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = - pAd->CommonCfg.MlmeRate; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n", - pAd->CommonCfg.MlmeTransmit.word)); -} - -char RTMPMaxRssi(struct rt_rtmp_adapter *pAd, - char Rssi0, char Rssi1, char Rssi2) -{ - char larger = -127; - - if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0)) { - larger = Rssi0; - } - - if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0)) { - larger = max(Rssi0, Rssi1); - } - - if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0)) { - larger = max(larger, Rssi2); - } - - if (larger == -127) - larger = 0; - - return larger; -} - -/* - ======================================================================== - Routine Description: - Periodic evaluate antenna link status - - Arguments: - pAd - Adapter pointer - - Return Value: - None - - ======================================================================== -*/ -void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd) -{ - u8 BBPR3 = 0; - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_NIC_NOT_EXIST | - fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) || - OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) -#ifdef RT30xx - || (pAd->EepromAccess) -#endif /* RT30xx // */ -#ifdef RT3090 - || (pAd->bPCIclkOff == TRUE) -#endif /* RT3090 // */ - ) - return; - - { - /*if (pAd->StaCfg.Psm == PWR_SAVE) */ - /* return; */ - - { - - if (pAd->StaCfg.Psm == PWR_SAVE) - return; - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); - BBPR3 &= (~0x18); - if (pAd->Antenna.field.RxPath == 3) { - BBPR3 |= (0x10); - } else if (pAd->Antenna.field.RxPath == 2) { - BBPR3 |= (0x8); - } else if (pAd->Antenna.field.RxPath == 1) { - BBPR3 |= (0x0); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = BBPR3; -#endif /* RTMP_MAC_PCI // */ - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) - ) { - unsigned long TxTotalCnt = - pAd->RalinkCounters.OneSecTxNoRetryOkCount + - pAd->RalinkCounters.OneSecTxRetryOkCount + - pAd->RalinkCounters.OneSecTxFailCount; - - /* dynamic adjust antenna evaluation period according to the traffic */ - if (TxTotalCnt > 50) { - RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, - 20); - pAd->Mlme.bLowThroughput = FALSE; - } else { - RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, - 300); - pAd->Mlme.bLowThroughput = TRUE; - } - } - } - - } - -} - -/* - ======================================================================== - Routine Description: - After evaluation, check antenna link status - - Arguments: - pAd - Adapter pointer - - Return Value: - None - - ======================================================================== -*/ -void AsicRxAntEvalTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - u8 BBPR3 = 0; - char larger = -127, rssi0, rssi1, rssi2; - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_NIC_NOT_EXIST) || - OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) -#ifdef RT30xx - || (pAd->EepromAccess) -#endif /* RT30xx // */ -#ifdef RT3090 - || (pAd->bPCIclkOff == TRUE) -#endif /* RT3090 // */ - ) - return; - - { - /*if (pAd->StaCfg.Psm == PWR_SAVE) */ - /* return; */ - { - if (pAd->StaCfg.Psm == PWR_SAVE) - return; - - /* if the traffic is low, use average rssi as the criteria */ - if (pAd->Mlme.bLowThroughput == TRUE) { - rssi0 = pAd->StaCfg.RssiSample.LastRssi0; - rssi1 = pAd->StaCfg.RssiSample.LastRssi1; - rssi2 = pAd->StaCfg.RssiSample.LastRssi2; - } else { - rssi0 = pAd->StaCfg.RssiSample.AvgRssi0; - rssi1 = pAd->StaCfg.RssiSample.AvgRssi1; - rssi2 = pAd->StaCfg.RssiSample.AvgRssi2; - } - - if (pAd->Antenna.field.RxPath == 3) { - larger = max(rssi0, rssi1); - - if (larger > (rssi2 + 20)) - pAd->Mlme.RealRxPath = 2; - else - pAd->Mlme.RealRxPath = 3; - } else if (pAd->Antenna.field.RxPath == 2) { - if (rssi0 > (rssi1 + 20)) - pAd->Mlme.RealRxPath = 1; - else - pAd->Mlme.RealRxPath = 2; - } - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); - BBPR3 &= (~0x18); - if (pAd->Mlme.RealRxPath == 3) { - BBPR3 |= (0x10); - } else if (pAd->Mlme.RealRxPath == 2) { - BBPR3 |= (0x8); - } else if (pAd->Mlme.RealRxPath == 1) { - BBPR3 |= (0x0); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = BBPR3; -#endif /* RTMP_MAC_PCI // */ - } - } - -} - -void APSDPeriodicExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - return; - - pAd->CommonCfg.TriggerTimerCount++; - -/* Driver should not send trigger frame, it should be send by application layer */ -/* - if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable - && (pAd->CommonCfg.bNeedSendTriggerFrame || - (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO)))) - { - DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n")); - RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); - pAd->CommonCfg.bNeedSendTriggerFrame = FALSE; - pAd->CommonCfg.TriggerTimerCount = 0; - pAd->CommonCfg.bInServicePeriod = TRUE; - }*/ -} - -/* - ======================================================================== - Routine Description: - Set/reset MAC registers according to bPiggyBack parameter - - Arguments: - pAd - Adapter pointer - bPiggyBack - Enable / Disable Piggy-Back - - Return Value: - None - - ======================================================================== -*/ -void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack) -{ - TX_LINK_CFG_STRUC TxLinkCfg; - - RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); - - TxLinkCfg.field.TxCFAckEn = bPiggyBack; - RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); -} - -/* - ======================================================================== - Routine Description: - check if this entry need to switch rate automatically - - Arguments: - pAd - pEntry - - Return Value: - TURE - FALSE - - ======================================================================== -*/ -BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry) -{ - BOOLEAN result = TRUE; - - { - /* only associated STA counts */ - if (pEntry && (pEntry->ValidAsCLI) - && (pEntry->Sst == SST_ASSOC)) { - result = pAd->StaCfg.bAutoTxRateSwitch; - } else - result = FALSE; - } - - return result; -} - -BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd) -{ - { - if (pAd->StaCfg.bAutoTxRateSwitch) - return TRUE; - } - return FALSE; -} - -/* - ======================================================================== - Routine Description: - check if this entry need to fix tx legacy rate - - Arguments: - pAd - pEntry - - Return Value: - TURE - FALSE - - ======================================================================== -*/ -u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry) -{ - u8 tx_mode = FIXED_TXMODE_HT; - - { - tx_mode = - (u8)pAd->StaCfg.DesiredTransmitSetting.field. - FixedTxMode; - } - - return tx_mode; -} - -/* - ======================================================================== - Routine Description: - Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified. - - Arguments: - pAd - pEntry - - Return Value: - TURE - FALSE - - ======================================================================== -*/ -void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry) -{ - HTTRANSMIT_SETTING TransmitSetting; - - if (fixed_tx_mode == FIXED_TXMODE_HT) - return; - - TransmitSetting.word = 0; - - TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE; - TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS; - - if (fixed_tx_mode == FIXED_TXMODE_CCK) { - TransmitSetting.field.MODE = MODE_CCK; - /* CCK mode allow MCS 0~3 */ - if (TransmitSetting.field.MCS > MCS_3) - TransmitSetting.field.MCS = MCS_3; - } else { - TransmitSetting.field.MODE = MODE_OFDM; - /* OFDM mode allow MCS 0~7 */ - if (TransmitSetting.field.MCS > MCS_7) - TransmitSetting.field.MCS = MCS_7; - } - - if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE) { - pEntry->HTPhyMode.word = TransmitSetting.word; - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n", - pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), - pEntry->HTPhyMode.field.MCS)); - } -} - -/* - ========================================================================== - Description: - dynamic tune BBP R66 to find a balance between sensibility and - noise isolation - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd) -{ - u8 OrigR66Value = 0, R66; /*, R66UpperBound = 0x30, R66LowerBound = 0x30; */ - char Rssi; - - /* 2860C did not support Fase CCA, therefore can't tune */ - if (pAd->MACVersion == 0x28600100) - return; - - /* */ - /* work as a STA */ - /* */ - if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) /* no R66 tuning when SCANNING */ - return; - - if ((pAd->OpMode == OPMODE_STA) - && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) - ) - && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) -#ifdef RTMP_MAC_PCI - && (pAd->bPCIclkOff == FALSE) -#endif /* RTMP_MAC_PCI // */ - ) { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value); - R66 = OrigR66Value; - - if (pAd->Antenna.field.RxPath > 1) - Rssi = - (pAd->StaCfg.RssiSample.AvgRssi0 + - pAd->StaCfg.RssiSample.AvgRssi1) >> 1; - else - Rssi = pAd->StaCfg.RssiSample.AvgRssi0; - - if (pAd->LatchRfRegs.Channel <= 14) { /*BG band */ -#ifdef RT30xx - /* RT3070 is a no LNA solution, it should have different control regarding to AGC gain control */ - /* Otherwise, it will have some throughput side effect when low RSSI */ - - if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd) - || IS_RT3390(pAd)) { - if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { - R66 = - 0x1C + 2 * GET_LNA_GAIN(pAd) + 0x20; - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } else { - R66 = 0x1C + 2 * GET_LNA_GAIN(pAd); - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } - } else -#endif /* RT30xx // */ - { - if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { - R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10; - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } else { - R66 = 0x2E + GET_LNA_GAIN(pAd); - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } - } - } else { /*A band */ - if (pAd->CommonCfg.BBPCurrentBW == BW_20) { - if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { - R66 = - 0x32 + (GET_LNA_GAIN(pAd) * 5) / 3 + - 0x10; - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } else { - R66 = - 0x32 + (GET_LNA_GAIN(pAd) * 5) / 3; - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } - } else { - if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { - R66 = - 0x3A + (GET_LNA_GAIN(pAd) * 5) / 3 + - 0x10; - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } else { - R66 = - 0x3A + (GET_LNA_GAIN(pAd) * 5) / 3; - if (OrigR66Value != R66) { - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R66, R66); - } - } - } - } - - } -} - -void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth) -{ - u8 R66 = 0x30; - - if (pAd->LatchRfRegs.Channel <= 14) { /* BG band */ -#ifdef RT30xx - /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */ - - if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd) - || IS_RT3390(pAd)) { - R66 = 0x1C + 2 * GET_LNA_GAIN(pAd); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); - } else -#endif /* RT30xx // */ - { - R66 = 0x2E + GET_LNA_GAIN(pAd); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); - } - } else { /*A band */ - { - if (BandWidth == BW_20) { - R66 = - (u8)(0x32 + - (GET_LNA_GAIN(pAd) * 5) / 3); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); - } else { - R66 = - (u8)(0x3A + - (GET_LNA_GAIN(pAd) * 5) / 3); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); - } - } - } - -} diff --git a/drivers/staging/rt2860/common/rt_channel.c b/drivers/staging/rt2860/common/rt_channel.c deleted file mode 100644 index 538798981177..000000000000 --- a/drivers/staging/rt2860/common/rt_channel.c +++ /dev/null @@ -1,1705 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ -#include "../rt_config.h" - -struct rt_ch_freq_map CH_HZ_ID_MAP[] = { - {1, 2412} - , - {2, 2417} - , - {3, 2422} - , - {4, 2427} - , - {5, 2432} - , - {6, 2437} - , - {7, 2442} - , - {8, 2447} - , - {9, 2452} - , - {10, 2457} - , - {11, 2462} - , - {12, 2467} - , - {13, 2472} - , - {14, 2484} - , - - /* UNII */ - {36, 5180} - , - {40, 5200} - , - {44, 5220} - , - {48, 5240} - , - {52, 5260} - , - {56, 5280} - , - {60, 5300} - , - {64, 5320} - , - {149, 5745} - , - {153, 5765} - , - {157, 5785} - , - {161, 5805} - , - {165, 5825} - , - {167, 5835} - , - {169, 5845} - , - {171, 5855} - , - {173, 5865} - , - - /* HiperLAN2 */ - {100, 5500} - , - {104, 5520} - , - {108, 5540} - , - {112, 5560} - , - {116, 5580} - , - {120, 5600} - , - {124, 5620} - , - {128, 5640} - , - {132, 5660} - , - {136, 5680} - , - {140, 5700} - , - - /* Japan MMAC */ - {34, 5170} - , - {38, 5190} - , - {42, 5210} - , - {46, 5230} - , - - /* Japan */ - {184, 4920} - , - {188, 4940} - , - {192, 4960} - , - {196, 4980} - , - - {208, 5040} - , /* Japan, means J08 */ - {212, 5060} - , /* Japan, means J12 */ - {216, 5080} - , /* Japan, means J16 */ -}; - -int CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP) / sizeof(struct rt_ch_freq_map)); - -struct rt_ch_region ChRegion[] = { - { /* Antigua and Berbuda */ - "AG", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Argentina */ - "AR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Aruba */ - "AW", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Australia */ - "AU", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Austria */ - "AT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, TRUE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Bahamas */ - "BS", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Barbados */ - "BB", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Bermuda */ - "BM", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Brazil */ - "BR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 24, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Belgium */ - "BE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 18, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 18, IDOR, FALSE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* Bulgaria */ - "BG", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, ODOR, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Canada */ - "CA", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Cayman IsLands */ - "KY", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Chile */ - "CL", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 20, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 20, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 5, 20, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* China */ - "CN", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {149, 4, 27, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Colombia */ - "CO", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 17, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Costa Rica */ - "CR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 17, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Cyprus */ - "CY", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Czech_Republic */ - "CZ", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* Denmark */ - "DK", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Dominican Republic */ - "DO", - CE, - { - {1, 0, 20, BOTH, FALSE} - , /* 2.4 G, ch 0 */ - {149, 4, 20, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Equador */ - "EC", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {100, 11, 27, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* El Salvador */ - "SV", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 30, BOTH, TRUE} - , /* 5G, ch 52~64 */ - {149, 4, 36, BOTH, TRUE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Finland */ - "FI", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* France */ - "FR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* Germany */ - "DE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Greece */ - "GR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, ODOR, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Guam */ - "GU", - CE, - { - {1, 11, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {36, 4, 17, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Guatemala */ - "GT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 17, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Haiti */ - "HT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 17, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Honduras */ - "HN", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {149, 4, 27, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Hong Kong */ - "HK", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Hungary */ - "HU", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* Iceland */ - "IS", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* India */ - "IN", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {149, 4, 24, IDOR, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Indonesia */ - "ID", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {149, 4, 27, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Ireland */ - "IE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, ODOR, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Israel */ - "IL", - CE, - { - {1, 3, 20, IDOR, FALSE} - , /* 2.4 G, ch 1~3 */ - {4, 6, 20, BOTH, FALSE} - , /* 2.4 G, ch 4~9 */ - {10, 4, 20, IDOR, FALSE} - , /* 2.4 G, ch 10~13 */ - {0} - , /* end */ - } - } - , - - { /* Italy */ - "IT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, ODOR, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Japan */ - "JP", - JAP, - { - {1, 14, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~14 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {0} - , /* end */ - } - } - , - - { /* Jordan */ - "JO", - CE, - { - {1, 13, 20, IDOR, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {149, 4, 23, IDOR, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Latvia */ - "LV", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Liechtenstein */ - "LI", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Lithuania */ - "LT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Luxemburg */ - "LU", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Malaysia */ - "MY", - CE, - { - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 5, 20, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Malta */ - "MT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Marocco */ - "MA", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 24, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {0} - , /* end */ - } - } - , - - { /* Mexico */ - "MX", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 5, 30, IDOR, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Netherlands */ - "NL", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* New Zealand */ - "NZ", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 24, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Norway */ - "NO", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 24, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 24, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Peru */ - "PE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {149, 4, 27, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Portugal */ - "PT", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Poland */ - "PL", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Romania */ - "RO", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Russia */ - "RU", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {149, 4, 20, IDOR, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Saudi Arabia */ - "SA", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 23, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Serbia_and_Montenegro */ - "CS", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {0} - , /* end */ - } - } - , - - { /* Singapore */ - "SG", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {149, 4, 20, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Slovakia */ - "SK", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Slovenia */ - "SI", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* South Africa */ - "ZA", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {149, 4, 30, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* South Korea */ - "KR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 20, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 20, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 8, 20, BOTH, FALSE} - , /* 5G, ch 100~128 */ - {149, 4, 20, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Spain */ - "ES", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 17, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Sweden */ - "SE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Switzerland */ - "CH", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~13 */ - {36, 4, 23, IDOR, TRUE} - , /* 5G, ch 36~48 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* Taiwan */ - "TW", - CE, - { - {1, 11, 30, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {52, 4, 23, IDOR, FALSE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* Turkey */ - "TR", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {36, 4, 23, BOTH, FALSE} - , /* 5G, ch 36~48 */ - {52, 4, 23, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {0} - , /* end */ - } - } - , - - { /* UK */ - "GB", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {36, 4, 23, IDOR, FALSE} - , /* 5G, ch 52~64 */ - {52, 4, 23, IDOR, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {0} - , /* end */ - } - } - , - - { /* Ukraine */ - "UA", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {0} - , /* end */ - } - } - , - - { /* United_Arab_Emirates */ - "AE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {0} - , /* end */ - } - } - , - - { /* United_States */ - "US", - CE, - { - {1, 11, 30, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {36, 4, 17, IDOR, FALSE} - , /* 5G, ch 52~64 */ - {52, 4, 24, BOTH, TRUE} - , /* 5G, ch 52~64 */ - {100, 11, 30, BOTH, TRUE} - , /* 5G, ch 100~140 */ - {149, 5, 30, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , - - { /* Venezuela */ - "VE", - CE, - { - {1, 13, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {149, 4, 27, BOTH, FALSE} - , /* 5G, ch 149~161 */ - {0} - , /* end */ - } - } - , - - { /* Default */ - "", - CE, - { - {1, 11, 20, BOTH, FALSE} - , /* 2.4 G, ch 1~11 */ - {36, 4, 20, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {52, 4, 20, BOTH, FALSE} - , /* 5G, ch 52~64 */ - {100, 11, 20, BOTH, FALSE} - , /* 5G, ch 100~140 */ - {149, 5, 20, BOTH, FALSE} - , /* 5G, ch 149~165 */ - {0} - , /* end */ - } - } - , -}; - -static struct rt_ch_region *GetChRegion(u8 *CntryCode) -{ - int loop = 0; - struct rt_ch_region *pChRegion = NULL; - - while (strcmp((char *)ChRegion[loop].CountReg, "") != 0) { - if (strncmp - ((char *)ChRegion[loop].CountReg, (char *)CntryCode, - 2) == 0) { - pChRegion = &ChRegion[loop]; - break; - } - loop++; - } - - if (pChRegion == NULL) - pChRegion = &ChRegion[loop]; - return pChRegion; -} - -static void ChBandCheck(u8 PhyMode, u8 *pChType) -{ - switch (PhyMode) { - case PHY_11A: - case PHY_11AN_MIXED: - *pChType = BAND_5G; - break; - case PHY_11ABG_MIXED: - case PHY_11AGN_MIXED: - case PHY_11ABGN_MIXED: - *pChType = BAND_BOTH; - break; - - default: - *pChType = BAND_24G; - break; - } -} - -static u8 FillChList(struct rt_rtmp_adapter *pAd, - struct rt_ch_desp *pChDesp, - u8 Offset, u8 increment) -{ - int i, j, l; - u8 channel; - - j = Offset; - for (i = 0; i < pChDesp->NumOfCh; i++) { - channel = pChDesp->FirstChannel + i * increment; - for (l = 0; l < MAX_NUM_OF_CHANNELS; l++) { - if (channel == pAd->TxPower[l].Channel) { - pAd->ChannelList[j].Power = - pAd->TxPower[l].Power; - pAd->ChannelList[j].Power2 = - pAd->TxPower[l].Power2; - break; - } - } - if (l == MAX_NUM_OF_CHANNELS) - continue; - - pAd->ChannelList[j].Channel = - pChDesp->FirstChannel + i * increment; - pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr; - pAd->ChannelList[j].DfsReq = pChDesp->DfsReq; - j++; - } - pAd->ChannelListNum = j; - - return j; -} - -static inline void CreateChList(struct rt_rtmp_adapter *pAd, - struct rt_ch_region *pChRegion, u8 Geography) -{ - int i; - u8 offset = 0; - struct rt_ch_desp *pChDesp; - u8 ChType; - u8 increment; - - if (pChRegion == NULL) - return; - - ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); - - for (i = 0; i < 10; i++) { - pChDesp = &pChRegion->ChDesp[i]; - if (pChDesp->FirstChannel == 0) - break; - - if (ChType == BAND_5G) { - if (pChDesp->FirstChannel <= 14) - continue; - } else if (ChType == BAND_24G) { - if (pChDesp->FirstChannel > 14) - continue; - } - - if ((pChDesp->Geography == BOTH) - || (pChDesp->Geography == Geography)) { - if (pChDesp->FirstChannel > 14) - increment = 4; - else - increment = 1; - offset = FillChList(pAd, pChDesp, offset, increment); - } - } -} - -void BuildChannelListEx(struct rt_rtmp_adapter *pAd) -{ - struct rt_ch_region *pChReg; - - pChReg = GetChRegion(pAd->CommonCfg.CountryCode); - CreateChList(pAd, pChReg, pAd->CommonCfg.Geography); -} - -void BuildBeaconChList(struct rt_rtmp_adapter *pAd, - u8 *pBuf, unsigned long *pBufLen) -{ - int i; - unsigned long TmpLen; - struct rt_ch_region *pChRegion; - struct rt_ch_desp *pChDesp; - u8 ChType; - - pChRegion = GetChRegion(pAd->CommonCfg.CountryCode); - - if (pChRegion == NULL) - return; - - ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); - *pBufLen = 0; - - for (i = 0; i < 10; i++) { - pChDesp = &pChRegion->ChDesp[i]; - if (pChDesp->FirstChannel == 0) - break; - - if (ChType == BAND_5G) { - if (pChDesp->FirstChannel <= 14) - continue; - } else if (ChType == BAND_24G) { - if (pChDesp->FirstChannel > 14) - continue; - } - - if ((pChDesp->Geography == BOTH) - || (pChDesp->Geography == pAd->CommonCfg.Geography)) { - MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen, - 1, &pChDesp->FirstChannel, - 1, &pChDesp->NumOfCh, - 1, &pChDesp->MaxTxPwr, END_OF_ARGS); - *pBufLen += TmpLen; - } - } -} - -static BOOLEAN IsValidChannel(struct rt_rtmp_adapter *pAd, u8 channel) -{ - int i; - - for (i = 0; i < pAd->ChannelListNum; i++) { - if (pAd->ChannelList[i].Channel == channel) - break; - } - - if (i == pAd->ChannelListNum) - return FALSE; - else - return TRUE; -} - -static u8 GetExtCh(u8 Channel, u8 Direction) -{ - char ExtCh; - - if (Direction == EXTCHA_ABOVE) - ExtCh = Channel + 4; - else - ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0; - - return ExtCh; -} - -void N_ChannelCheck(struct rt_rtmp_adapter *pAd) -{ - /*u8 ChannelNum = pAd->ChannelListNum; */ - u8 Channel = pAd->CommonCfg.Channel; - - if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) - && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) { - if (Channel > 14) { - if ((Channel == 36) || (Channel == 44) - || (Channel == 52) || (Channel == 60) - || (Channel == 100) || (Channel == 108) - || (Channel == 116) || (Channel == 124) - || (Channel == 132) || (Channel == 149) - || (Channel == 157)) { - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = - EXTCHA_ABOVE; - } else if ((Channel == 40) || (Channel == 48) - || (Channel == 56) || (Channel == 64) - || (Channel == 104) || (Channel == 112) - || (Channel == 120) || (Channel == 128) - || (Channel == 136) || (Channel == 153) - || (Channel == 161)) { - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = - EXTCHA_BELOW; - } else { - pAd->CommonCfg.RegTransmitSetting.field.BW = - BW_20; - } - } else { - do { - u8 ExtCh; - u8 Dir = - pAd->CommonCfg.RegTransmitSetting.field. - EXTCHA; - ExtCh = GetExtCh(Channel, Dir); - if (IsValidChannel(pAd, ExtCh)) - break; - - Dir = - (Dir == - EXTCHA_ABOVE) ? EXTCHA_BELOW : - EXTCHA_ABOVE; - ExtCh = GetExtCh(Channel, Dir); - if (IsValidChannel(pAd, ExtCh)) { - pAd->CommonCfg.RegTransmitSetting.field. - EXTCHA = Dir; - break; - } - pAd->CommonCfg.RegTransmitSetting.field.BW = - BW_20; - } while (FALSE); - - if (Channel == 14) { - pAd->CommonCfg.RegTransmitSetting.field.BW = - BW_20; - /*pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT() */ - } - } - } - -} - -void N_SetCenCh(struct rt_rtmp_adapter *pAd) -{ - if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) { - if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == - EXTCHA_ABOVE) { - pAd->CommonCfg.CentralChannel = - pAd->CommonCfg.Channel + 2; - } else { - if (pAd->CommonCfg.Channel == 14) - pAd->CommonCfg.CentralChannel = - pAd->CommonCfg.Channel - 1; - else - pAd->CommonCfg.CentralChannel = - pAd->CommonCfg.Channel - 2; - } - } else { - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - } -} - -u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel) -{ - int i; - for (i = 0; i < pAd->ChannelListNum; i++) { - if (pAd->ChannelList[i].Channel == channel) - break; - } - - if (i == pAd->ChannelListNum) - return 0xff; - else - return pAd->ChannelList[i].MaxTxPwr; -} diff --git a/drivers/staging/rt2860/common/rt_rf.c b/drivers/staging/rt2860/common/rt_rf.c deleted file mode 100644 index 2895447ffc48..000000000000 --- a/drivers/staging/rt2860/common/rt_rf.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt_rf.c - - Abstract: - Ralink Wireless driver RF related functions - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -#ifdef RTMP_RF_RW_SUPPORT -/* - ======================================================================== - - Routine Description: Write RT30xx RF register through MAC - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd, - u8 regID, u8 value) -{ - RF_CSR_CFG_STRUC rfcsr; - u32 i = 0; - - do { - RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); - - if (!rfcsr.field.RF_CSR_KICK) - break; - i++; - } - while ((i < RETRY_LIMIT) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); - - if ((i == RETRY_LIMIT) - || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Retry count exhausted or device removed!\n")); - return STATUS_UNSUCCESSFUL; - } - - rfcsr.field.RF_CSR_WR = 1; - rfcsr.field.RF_CSR_KICK = 1; - rfcsr.field.TESTCSR_RFACC_REGNUM = regID; - rfcsr.field.RF_CSR_DATA = value; - - RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); - - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: Read RT30xx RF register through MAC - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd, - u8 regID, u8 *pValue) -{ - RF_CSR_CFG_STRUC rfcsr; - u32 i = 0, k = 0; - - for (i = 0; i < MAX_BUSY_COUNT; i++) { - RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); - - if (rfcsr.field.RF_CSR_KICK == BUSY) { - continue; - } - rfcsr.word = 0; - rfcsr.field.RF_CSR_WR = 0; - rfcsr.field.RF_CSR_KICK = 1; - rfcsr.field.TESTCSR_RFACC_REGNUM = regID; - RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); - for (k = 0; k < MAX_BUSY_COUNT; k++) { - RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); - - if (rfcsr.field.RF_CSR_KICK == IDLE) - break; - } - if ((rfcsr.field.RF_CSR_KICK == IDLE) && - (rfcsr.field.TESTCSR_RFACC_REGNUM == regID)) { - *pValue = (u8)rfcsr.field.RF_CSR_DATA; - break; - } - } - if (rfcsr.field.RF_CSR_KICK == BUSY) { - DBGPRINT_ERR("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word, i, k); - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; -} - -void NICInitRFRegisters(struct rt_rtmp_adapter *pAd) -{ - if (pAd->chipOps.AsicRfInit) - pAd->chipOps.AsicRfInit(pAd); -} - -void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd) -{ - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - - pChipOps->pRFRegTable = NULL; - pChipOps->AsicRfInit = NULL; - pChipOps->AsicRfTurnOn = NULL; - pChipOps->AsicRfTurnOff = NULL; - pChipOps->AsicReverseRfFromSleepMode = NULL; - pChipOps->AsicHaltAction = NULL; - /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */ - -#ifdef RT30xx - if (IS_RT30xx(pAd)) { - pChipOps->pRFRegTable = RT30xx_RFRegTable; - pChipOps->AsicHaltAction = RT30xxHaltAction; -#ifdef RT3070 - if ((IS_RT3070(pAd) || IS_RT3071(pAd)) - && (pAd->infType == RTMP_DEV_INF_USB)) { - pChipOps->AsicRfInit = NICInitRT3070RFRegisters; - if (IS_RT3071(pAd)) { - pChipOps->AsicRfTurnOff = - RT30xxLoadRFSleepModeSetup; - pChipOps->AsicReverseRfFromSleepMode = - RT30xxReverseRFSleepModeSetup; - } - } -#endif /* RT3070 // */ -#ifdef RT3090 - if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI)) { - pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; - pChipOps->AsicRfInit = NICInitRT3090RFRegisters; - pChipOps->AsicReverseRfFromSleepMode = - RT30xxReverseRFSleepModeSetup; - } -#endif /* RT3090 // */ - } -#endif /* RT30xx // */ -} - -#endif /* RTMP_RF_RW_SUPPORT // */ diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c deleted file mode 100644 index 5fa193eac0d3..000000000000 --- a/drivers/staging/rt2860/common/rtmp_init.c +++ /dev/null @@ -1,3536 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_init.c - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ -#include "../rt_config.h" - -u8 BIT8[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; -char *CipherName[] = - { "none", "wep64", "wep128", "TKIP", "AES", "CKIP64", "CKIP128" }; - -/* */ -/* BBP register initialization set */ -/* */ -struct rt_reg_pair BBPRegTable[] = { - {BBP_R65, 0x2C}, /* fix rssi issue */ - {BBP_R66, 0x38}, /* Also set this default value to pAd->BbpTuning.R66CurrentValue at initial */ - {BBP_R69, 0x12}, - {BBP_R70, 0xa}, /* BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa */ - {BBP_R73, 0x10}, - {BBP_R81, 0x37}, - {BBP_R82, 0x62}, - {BBP_R83, 0x6A}, - {BBP_R84, 0x99}, /* 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before */ - {BBP_R86, 0x00}, /* middle range issue, Rory @2008-01-28 */ - {BBP_R91, 0x04}, /* middle range issue, Rory @2008-01-28 */ - {BBP_R92, 0x00}, /* middle range issue, Rory @2008-01-28 */ - {BBP_R103, 0x00}, /* near range high-power issue, requested from Gary @2008-0528 */ - {BBP_R105, 0x05}, /* 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before. */ - {BBP_R106, 0x35}, /* for ShortGI throughput */ -}; - -#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(struct rt_reg_pair)) - -/* */ -/* ASIC register initialization sets */ -/* */ - -struct rt_rtmp_reg_pair MACRegTable[] = { -#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200) - {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */ - {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */ -#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100) - {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */ - {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */ -#else -#error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]! -#endif /* HW_BEACON_OFFSET // */ - - {LEGACY_BASIC_RATE, 0x0000013f}, /* Basic rate set bitmap */ - {HT_BASIC_RATE, 0x00008003}, /* Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI. */ - {MAC_SYS_CTRL, 0x00}, /* 0x1004, , default Disable RX */ - {RX_FILTR_CFG, 0x17f97}, /*0x1400 , RX filter control, */ - {BKOFF_SLOT_CFG, 0x209}, /* default set short slot time, CC_DELAY_TIME should be 2 */ - /*{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23 */ - {TX_SW_CFG0, 0x0}, /* Gary,2008-05-21 for CWC test */ - {TX_SW_CFG1, 0x80606}, /* Gary,2006-08-23 */ - {TX_LINK_CFG, 0x1020}, /* Gary,2006-08-23 */ - /*{TX_TIMEOUT_CFG, 0x00182090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT */ - {TX_TIMEOUT_CFG, 0x000a2090}, /* CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 */ - {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, /* 0x3018, MAX frame length. Max PSDU = 16kbytes. */ - {LED_CFG, 0x7f031e46}, /* Gary, 2006-08-23 */ - - {PBF_MAX_PCNT, 0x1F3FBF9F}, /*0x1F3f7f9f}, //Jan, 2006/04/20 */ - - {TX_RTY_CFG, 0x47d01f0f}, /* Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 */ - - {AUTO_RSP_CFG, 0x00000013}, /* Initial Auto_Responder, because QA will turn off Auto-Responder */ - {CCK_PROT_CFG, 0x05740003 /*0x01740003 */ }, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */ - {OFDM_PROT_CFG, 0x05740003 /*0x01740003 */ }, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */ -#ifdef RTMP_MAC_USB - {PBF_CFG, 0xf40006}, /* Only enable Queue 2 */ - {MM40_PROT_CFG, 0x3F44084}, /* Initial Auto_Responder, because QA will turn off Auto-Responder */ - {WPDMA_GLO_CFG, 0x00000030}, -#endif /* RTMP_MAC_USB // */ - {GF20_PROT_CFG, 0x01744004}, /* set 19:18 --> Short NAV for MIMO PS */ - {GF40_PROT_CFG, 0x03F44084}, - {MM20_PROT_CFG, 0x01744004}, -#ifdef RTMP_MAC_PCI - {MM40_PROT_CFG, 0x03F54084}, -#endif /* RTMP_MAC_PCI // */ - {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f *//*0x000024bf */ }, /*Extension channel backoff. */ - {TX_RTS_CFG, 0x00092b20}, - {EXP_ACK_TIME, 0x002400ca}, /* default value */ - - {TXOP_HLDR_ET, 0x00000002}, - - /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us - is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0 - and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping - will always lost. So we change the SIFS of CCK from 10us to 16us. */ - {XIFS_TIME_CFG, 0x33a41010}, - {PWR_PIN_CFG, 0x00000003}, /* patch for 2880-E */ -}; - -struct rt_rtmp_reg_pair STAMACRegTable[] = { - {WMM_AIFSN_CFG, 0x00002273}, - {WMM_CWMIN_CFG, 0x00002344}, - {WMM_CWMAX_CFG, 0x000034aa}, -}; - -#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(struct rt_rtmp_reg_pair)) -#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(struct rt_rtmp_reg_pair)) - -/* - ======================================================================== - - Routine Description: - Allocate struct rt_rtmp_adapter data block and do some initialization - - Arguments: - Adapter Pointer to our adapter - - Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -int RTMPAllocAdapterBlock(void *handle, - struct rt_rtmp_adapter * * ppAdapter) -{ - struct rt_rtmp_adapter *pAd; - int Status; - int index; - u8 *pBeaconBuf = NULL; - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n")); - - *ppAdapter = NULL; - - do { - /* Allocate struct rt_rtmp_adapter memory block */ - pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG); - if (pBeaconBuf == NULL) { - Status = NDIS_STATUS_FAILURE; - DBGPRINT_ERR("Failed to allocate memory - BeaconBuf!\n"); - break; - } - NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE); - - Status = AdapterBlockAllocateMemory(handle, (void **) & pAd); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR("Failed to allocate memory - ADAPTER\n"); - break; - } - pAd->BeaconBuf = pBeaconBuf; - DBGPRINT(RT_DEBUG_OFF, - ("=== pAd = %p, size = %d ===\n", pAd, - (u32)sizeof(struct rt_rtmp_adapter))); - - /* Init spin locks */ - NdisAllocateSpinLock(&pAd->MgmtRingLock); -#ifdef RTMP_MAC_PCI - NdisAllocateSpinLock(&pAd->RxRingLock); -#ifdef RT3090 - NdisAllocateSpinLock(&pAd->McuCmdLock); -#endif /* RT3090 // */ -#endif /* RTMP_MAC_PCI // */ - - for (index = 0; index < NUM_OF_TX_RING; index++) { - NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]); - NdisAllocateSpinLock(&pAd->DeQueueLock[index]); - pAd->DeQueueRunning[index] = FALSE; - } - - NdisAllocateSpinLock(&pAd->irq_lock); - - } while (FALSE); - - if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf)) - kfree(pBeaconBuf); - - *ppAdapter = pAd; - - DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status)); - return Status; -} - -/* - ======================================================================== - - Routine Description: - Read initial Tx power per MCS and BW from EEPROM - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPReadTxPwrPerRate(struct rt_rtmp_adapter *pAd) -{ - unsigned long data, Adata, Gdata; - u16 i, value, value2; - int Apwrdelta, Gpwrdelta; - u8 t1, t2, t3, t4; - BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE; - - /* */ - /* Get power delta for 20MHz and 40MHz. */ - /* */ - DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n")); - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2); - Apwrdelta = 0; - Gpwrdelta = 0; - - if ((value2 & 0xff) != 0xff) { - if ((value2 & 0x80)) - Gpwrdelta = (value2 & 0xf); - - if ((value2 & 0x40)) - bGpwrdeltaMinus = FALSE; - else - bGpwrdeltaMinus = TRUE; - } - if ((value2 & 0xff00) != 0xff00) { - if ((value2 & 0x8000)) - Apwrdelta = ((value2 & 0xf00) >> 8); - - if ((value2 & 0x4000)) - bApwrdeltaMinus = FALSE; - else - bApwrdeltaMinus = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, - ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta)); - - /* */ - /* Get Txpower per MCS for 20MHz in 2.4G. */ - /* */ - for (i = 0; i < 5; i++) { - RT28xx_EEPROM_READ16(pAd, - EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4, - value); - data = value; - if (bApwrdeltaMinus == FALSE) { - t1 = (value & 0xf) + (Apwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value & 0xf0) >> 4) + (Apwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value & 0xf00) >> 8) + (Apwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value & 0xf000) >> 12) + (Apwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } else { - if ((value & 0xf) > Apwrdelta) - t1 = (value & 0xf) - (Apwrdelta); - else - t1 = 0; - if (((value & 0xf0) >> 4) > Apwrdelta) - t2 = ((value & 0xf0) >> 4) - (Apwrdelta); - else - t2 = 0; - if (((value & 0xf00) >> 8) > Apwrdelta) - t3 = ((value & 0xf00) >> 8) - (Apwrdelta); - else - t3 = 0; - if (((value & 0xf000) >> 12) > Apwrdelta) - t4 = ((value & 0xf000) >> 12) - (Apwrdelta); - else - t4 = 0; - } - Adata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12); - if (bGpwrdeltaMinus == FALSE) { - t1 = (value & 0xf) + (Gpwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value & 0xf0) >> 4) + (Gpwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value & 0xf00) >> 8) + (Gpwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value & 0xf000) >> 12) + (Gpwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } else { - if ((value & 0xf) > Gpwrdelta) - t1 = (value & 0xf) - (Gpwrdelta); - else - t1 = 0; - if (((value & 0xf0) >> 4) > Gpwrdelta) - t2 = ((value & 0xf0) >> 4) - (Gpwrdelta); - else - t2 = 0; - if (((value & 0xf00) >> 8) > Gpwrdelta) - t3 = ((value & 0xf00) >> 8) - (Gpwrdelta); - else - t3 = 0; - if (((value & 0xf000) >> 12) > Gpwrdelta) - t4 = ((value & 0xf000) >> 12) - (Gpwrdelta); - else - t4 = 0; - } - Gdata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12); - - RT28xx_EEPROM_READ16(pAd, - EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4 + - 2, value); - if (bApwrdeltaMinus == FALSE) { - t1 = (value & 0xf) + (Apwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value & 0xf0) >> 4) + (Apwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value & 0xf00) >> 8) + (Apwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value & 0xf000) >> 12) + (Apwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } else { - if ((value & 0xf) > Apwrdelta) - t1 = (value & 0xf) - (Apwrdelta); - else - t1 = 0; - if (((value & 0xf0) >> 4) > Apwrdelta) - t2 = ((value & 0xf0) >> 4) - (Apwrdelta); - else - t2 = 0; - if (((value & 0xf00) >> 8) > Apwrdelta) - t3 = ((value & 0xf00) >> 8) - (Apwrdelta); - else - t3 = 0; - if (((value & 0xf000) >> 12) > Apwrdelta) - t4 = ((value & 0xf000) >> 12) - (Apwrdelta); - else - t4 = 0; - } - Adata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28)); - if (bGpwrdeltaMinus == FALSE) { - t1 = (value & 0xf) + (Gpwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value & 0xf0) >> 4) + (Gpwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value & 0xf00) >> 8) + (Gpwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value & 0xf000) >> 12) + (Gpwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } else { - if ((value & 0xf) > Gpwrdelta) - t1 = (value & 0xf) - (Gpwrdelta); - else - t1 = 0; - if (((value & 0xf0) >> 4) > Gpwrdelta) - t2 = ((value & 0xf0) >> 4) - (Gpwrdelta); - else - t2 = 0; - if (((value & 0xf00) >> 8) > Gpwrdelta) - t3 = ((value & 0xf00) >> 8) - (Gpwrdelta); - else - t3 = 0; - if (((value & 0xf000) >> 12) > Gpwrdelta) - t4 = ((value & 0xf000) >> 12) - (Gpwrdelta); - else - t4 = 0; - } - Gdata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28)); - data |= (value << 16); - - /* For 20M/40M Power Delta issue */ - pAd->Tx20MPwrCfgABand[i] = data; - pAd->Tx20MPwrCfgGBand[i] = data; - pAd->Tx40MPwrCfgABand[i] = Adata; - pAd->Tx40MPwrCfgGBand[i] = Gdata; - - if (data != 0xffffffff) - RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, data); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", - data, Adata, Gdata)); - } -} - -/* - ======================================================================== - - Routine Description: - Read initial channel power parameters from EEPROM - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPReadChannelPwr(struct rt_rtmp_adapter *pAd) -{ - u8 i, choffset; - EEPROM_TX_PWR_STRUC Power; - EEPROM_TX_PWR_STRUC Power2; - - /* Read Tx power value for all channels */ - /* Value from 1 - 0x7f. Default value is 24. */ - /* Power value : 2.4G 0x00 (0) ~ 0x1F (31) */ - /* : 5.5G 0xF9 (-7) ~ 0x0F (15) */ - - /* 0. 11b/g, ch1 - ch 14 */ - for (i = 0; i < 7; i++) { - RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, - Power.word); - RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, - Power2.word); - pAd->TxPower[i * 2].Channel = i * 2 + 1; - pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2; - - if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0)) - pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER; - else - pAd->TxPower[i * 2].Power = Power.field.Byte0; - - if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0)) - pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER; - else - pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1; - - if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0)) - pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER; - else - pAd->TxPower[i * 2].Power2 = Power2.field.Byte0; - - if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0)) - pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER; - else - pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1; - } - - /* 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz) */ - /* 1.1 Fill up channel */ - choffset = 14; - for (i = 0; i < 4; i++) { - pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0; - pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2; - pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4; - pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; - } - - /* 1.2 Fill up power */ - for (i = 0; i < 6; i++) { - RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, - Power.word); - RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, - Power2.word); - - if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7)) - pAd->TxPower[i * 2 + choffset + 0].Power = - Power.field.Byte0; - - if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7)) - pAd->TxPower[i * 2 + choffset + 1].Power = - Power.field.Byte1; - - if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7)) - pAd->TxPower[i * 2 + choffset + 0].Power2 = - Power2.field.Byte0; - - if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7)) - pAd->TxPower[i * 2 + choffset + 1].Power2 = - Power2.field.Byte1; - } - - /* 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz) */ - /* 2.1 Fill up channel */ - choffset = 14 + 12; - for (i = 0; i < 5; i++) { - pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0; - pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2; - pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4; - pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; - } - pAd->TxPower[3 * 5 + choffset + 0].Channel = 140; - pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; - - /* 2.2 Fill up power */ - for (i = 0; i < 8; i++) { - RT28xx_EEPROM_READ16(pAd, - EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + - i * 2, Power.word); - RT28xx_EEPROM_READ16(pAd, - EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + - i * 2, Power2.word); - - if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7)) - pAd->TxPower[i * 2 + choffset + 0].Power = - Power.field.Byte0; - - if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7)) - pAd->TxPower[i * 2 + choffset + 1].Power = - Power.field.Byte1; - - if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7)) - pAd->TxPower[i * 2 + choffset + 0].Power2 = - Power2.field.Byte0; - - if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7)) - pAd->TxPower[i * 2 + choffset + 1].Power2 = - Power2.field.Byte1; - } - - /* 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz) */ - /* 3.1 Fill up channel */ - choffset = 14 + 12 + 16; - /*for (i = 0; i < 2; i++) */ - for (i = 0; i < 3; i++) { - pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0; - pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2; - pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4; - pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; - } - pAd->TxPower[3 * 3 + choffset + 0].Channel = 171; - pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; - - pAd->TxPower[3 * 3 + choffset + 1].Channel = 173; - pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; - - /* 3.2 Fill up power */ - /*for (i = 0; i < 4; i++) */ - for (i = 0; i < 6; i++) { - RT28xx_EEPROM_READ16(pAd, - EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + - i * 2, Power.word); - RT28xx_EEPROM_READ16(pAd, - EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + - i * 2, Power2.word); - - if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7)) - pAd->TxPower[i * 2 + choffset + 0].Power = - Power.field.Byte0; - - if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7)) - pAd->TxPower[i * 2 + choffset + 1].Power = - Power.field.Byte1; - - if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7)) - pAd->TxPower[i * 2 + choffset + 0].Power2 = - Power2.field.Byte0; - - if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7)) - pAd->TxPower[i * 2 + choffset + 1].Power2 = - Power2.field.Byte1; - } - - /* 4. Print and Debug */ - /*choffset = 14 + 12 + 16 + 7; */ - choffset = 14 + 12 + 16 + 11; - -} - -/* - ======================================================================== - - Routine Description: - Read the following from the registry - 1. All the parameters - 2. NetworkAddres - - Arguments: - Adapter Pointer to our adapter - WrapperConfigurationContext For use by NdisOpenConfiguration - - Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -int NICReadRegParameters(struct rt_rtmp_adapter *pAd, - void *WrapperConfigurationContext) -{ - int Status = NDIS_STATUS_SUCCESS; - DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status)); - return Status; -} - -/* - ======================================================================== - - Routine Description: - Read initial parameters from EEPROM - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr) -{ - u32 data = 0; - u16 i, value, value2; - u8 TmpPhy; - EEPROM_TX_PWR_STRUC Power; - EEPROM_VERSION_STRUC Version; - EEPROM_ANTENNA_STRUC Antenna; - EEPROM_NIC_CONFIG2_STRUC NicConfig2; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n")); - - if (pAd->chipOps.eeinit) - pAd->chipOps.eeinit(pAd); - - /* Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 */ - RTMP_IO_READ32(pAd, E2PROM_CSR, &data); - DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data)); - - if ((data & 0x30) == 0) - pAd->EEPROMAddressNum = 6; /* 93C46 */ - else if ((data & 0x30) == 0x10) - pAd->EEPROMAddressNum = 8; /* 93C66 */ - else - pAd->EEPROMAddressNum = 8; /* 93C86 */ - DBGPRINT(RT_DEBUG_TRACE, - ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum)); - - /* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to initialize */ - /* MAC address registers according to E2PROM setting */ - if (mac_addr == NULL || - strlen((char *)mac_addr) != 17 || - mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' || - mac_addr[11] != ':' || mac_addr[14] != ':') { - u16 Addr01, Addr23, Addr45; - - RT28xx_EEPROM_READ16(pAd, 0x04, Addr01); - RT28xx_EEPROM_READ16(pAd, 0x06, Addr23); - RT28xx_EEPROM_READ16(pAd, 0x08, Addr45); - - pAd->PermanentAddress[0] = (u8)(Addr01 & 0xff); - pAd->PermanentAddress[1] = (u8)(Addr01 >> 8); - pAd->PermanentAddress[2] = (u8)(Addr23 & 0xff); - pAd->PermanentAddress[3] = (u8)(Addr23 >> 8); - pAd->PermanentAddress[4] = (u8)(Addr45 & 0xff); - pAd->PermanentAddress[5] = (u8)(Addr45 >> 8); - - DBGPRINT(RT_DEBUG_TRACE, - ("Initialize MAC Address from E2PROM \n")); - } else { - int j; - char *macptr; - - macptr = (char *)mac_addr; - - for (j = 0; j < MAC_ADDR_LEN; j++) { - AtoH(macptr, &pAd->PermanentAddress[j], 1); - macptr = macptr + 3; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("Initialize MAC Address from module parameter \n")); - } - - { - /*more conveninet to test mbssid, so ap's bssid &0xf1 */ - if (pAd->PermanentAddress[0] == 0xff) - pAd->PermanentAddress[0] = RandomByte(pAd) & 0xf8; - - /*if (pAd->PermanentAddress[5] == 0xff) */ - /* pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8; */ - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("E2PROM MAC: =%pM\n", pAd->PermanentAddress)); - if (pAd->bLocalAdminMAC == FALSE) { - MAC_DW0_STRUC csr2; - MAC_DW1_STRUC csr3; - COPY_MAC_ADDR(pAd->CurrentAddress, - pAd->PermanentAddress); - csr2.field.Byte0 = pAd->CurrentAddress[0]; - csr2.field.Byte1 = pAd->CurrentAddress[1]; - csr2.field.Byte2 = pAd->CurrentAddress[2]; - csr2.field.Byte3 = pAd->CurrentAddress[3]; - RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word); - csr3.word = 0; - csr3.field.Byte4 = pAd->CurrentAddress[4]; - csr3.field.Byte5 = pAd->CurrentAddress[5]; - csr3.field.U2MeMask = 0xff; - RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("E2PROM MAC: =%pM\n", - pAd->PermanentAddress)); - } - } - - /* if not return early. cause fail at emulation. */ - /* Init the channel number for TX channel power */ - RTMPReadChannelPwr(pAd); - - /* if E2PROM version mismatch with driver's expectation, then skip */ - /* all subsequent E2RPOM retieval and set a system error bit to notify GUI */ - RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word); - pAd->EepromVersion = - Version.field.Version + Version.field.FaeReleaseNumber * 256; - DBGPRINT(RT_DEBUG_TRACE, - ("E2PROM: Version = %d, FAE release #%d\n", - Version.field.Version, Version.field.FaeReleaseNumber)); - - if (Version.field.Version > VALID_EEPROM_VERSION) { - DBGPRINT_ERR("E2PROM: WRONG VERSION 0x%x, should be %d\n", Version.field.Version, VALID_EEPROM_VERSION); - /*pAd->SystemErrorBitmap |= 0x00000001; - - // hard-code default value when no proper E2PROM installed - pAd->bAutoTxAgcA = FALSE; - pAd->bAutoTxAgcG = FALSE; - - // Default the channel power - for (i = 0; i < MAX_NUM_OF_CHANNELS; i++) - pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER; - - // Default the channel power - for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++) - pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER; - - for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++) - pAd->EEPROMDefaultValue[i] = 0xffff; - return; */ - } - /* Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd */ - RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value); - pAd->EEPROMDefaultValue[0] = value; - - RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value); - pAd->EEPROMDefaultValue[1] = value; - - RT28xx_EEPROM_READ16(pAd, 0x38, value); /* Country Region */ - pAd->EEPROMDefaultValue[2] = value; - - for (i = 0; i < 8; i++) { - RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i * 2, - value); - pAd->EEPROMDefaultValue[i + 3] = value; - } - - /* We have to parse NIC configuration 0 at here. */ - /* If TSSI did not have preloaded value, it should reset the TxAutoAgc to false */ - /* Therefore, we have to read TxAutoAgc control beforehand. */ - /* Read Tx AGC control bit */ - Antenna.word = pAd->EEPROMDefaultValue[0]; - if (Antenna.word == 0xFFFF) { -#ifdef RT30xx - if (IS_RT3090(pAd) || IS_RT3390(pAd)) { - Antenna.word = 0; - Antenna.field.RfIcType = RFIC_3020; - Antenna.field.TxPath = 1; - Antenna.field.RxPath = 1; - } else -#endif /* RT30xx // */ - { - - Antenna.word = 0; - Antenna.field.RfIcType = RFIC_2820; - Antenna.field.TxPath = 1; - Antenna.field.RxPath = 2; - DBGPRINT(RT_DEBUG_WARN, - ("E2PROM error, hard code as 0x%04x\n", - Antenna.word)); - } - } - /* Choose the desired Tx&Rx stream. */ - if ((pAd->CommonCfg.TxStream == 0) - || (pAd->CommonCfg.TxStream > Antenna.field.TxPath)) - pAd->CommonCfg.TxStream = Antenna.field.TxPath; - - if ((pAd->CommonCfg.RxStream == 0) - || (pAd->CommonCfg.RxStream > Antenna.field.RxPath)) { - pAd->CommonCfg.RxStream = Antenna.field.RxPath; - - if ((pAd->MACVersion < RALINK_2883_VERSION) && - (pAd->CommonCfg.RxStream > 2)) { - /* only 2 Rx streams for RT2860 series */ - pAd->CommonCfg.RxStream = 2; - } - } - /* 3*3 */ - /* read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2 */ - /* yet implement */ - for (i = 0; i < 3; i++) { - } - - NicConfig2.word = pAd->EEPROMDefaultValue[1]; - - { - if ((NicConfig2.word & 0x00ff) == 0xff) { - NicConfig2.word &= 0xff00; - } - - if ((NicConfig2.word >> 8) == 0xff) { - NicConfig2.word &= 0x00ff; - } - } - - if (NicConfig2.field.DynamicTxAgcControl == 1) - pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE; - else - pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", - Antenna.field.RxPath, Antenna.field.TxPath)); - - /* Save the antenna for future use */ - pAd->Antenna.word = Antenna.word; - - /* Set the RfICType here, then we can initialize RFIC related operation callbacks */ - pAd->Mlme.RealRxPath = (u8)Antenna.field.RxPath; - pAd->RfIcType = (u8)Antenna.field.RfIcType; - -#ifdef RTMP_RF_RW_SUPPORT - RtmpChipOpsRFHook(pAd); -#endif /* RTMP_RF_RW_SUPPORT // */ - -#ifdef RTMP_MAC_PCI - sprintf((char *)pAd->nickname, "RT2860STA"); -#endif /* RTMP_MAC_PCI // */ - - /* */ - /* Reset PhyMode if we don't support 802.11a */ - /* Only RFIC_2850 & RFIC_2750 support 802.11a */ - /* */ - if ((Antenna.field.RfIcType != RFIC_2850) - && (Antenna.field.RfIcType != RFIC_2750) - && (Antenna.field.RfIcType != RFIC_3052)) { - if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) || - (pAd->CommonCfg.PhyMode == PHY_11A)) - pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; - else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || - (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) || - (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || - (pAd->CommonCfg.PhyMode == PHY_11N_5G)) - pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED; - } - /* Read TSSI reference and TSSI boundary for temperature compensation. This is ugly */ - /* 0. 11b/g */ - { - /* these are tempature reference value (0x00 ~ 0xFE) - ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 - TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) + - TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */ - RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word); - pAd->TssiMinusBoundaryG[4] = Power.field.Byte0; - pAd->TssiMinusBoundaryG[3] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0x70, Power.word); - pAd->TssiMinusBoundaryG[2] = Power.field.Byte0; - pAd->TssiMinusBoundaryG[1] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0x72, Power.word); - pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */ - pAd->TssiPlusBoundaryG[1] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0x74, Power.word); - pAd->TssiPlusBoundaryG[2] = Power.field.Byte0; - pAd->TssiPlusBoundaryG[3] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0x76, Power.word); - pAd->TssiPlusBoundaryG[4] = Power.field.Byte0; - pAd->TxAgcStepG = Power.field.Byte1; - pAd->TxAgcCompensateG = 0; - pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG; - pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG; - - /* Disable TxAgc if the based value is not right */ - if (pAd->TssiRefG == 0xff) - pAd->bAutoTxAgcG = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, - ("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n", - pAd->TssiMinusBoundaryG[4], - pAd->TssiMinusBoundaryG[3], - pAd->TssiMinusBoundaryG[2], - pAd->TssiMinusBoundaryG[1], pAd->TssiRefG, - pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], - pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4], - pAd->TxAgcStepG, pAd->bAutoTxAgcG)); - } - /* 1. 11a */ - { - RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word); - pAd->TssiMinusBoundaryA[4] = Power.field.Byte0; - pAd->TssiMinusBoundaryA[3] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word); - pAd->TssiMinusBoundaryA[2] = Power.field.Byte0; - pAd->TssiMinusBoundaryA[1] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word); - pAd->TssiRefA = Power.field.Byte0; - pAd->TssiPlusBoundaryA[1] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word); - pAd->TssiPlusBoundaryA[2] = Power.field.Byte0; - pAd->TssiPlusBoundaryA[3] = Power.field.Byte1; - RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word); - pAd->TssiPlusBoundaryA[4] = Power.field.Byte0; - pAd->TxAgcStepA = Power.field.Byte1; - pAd->TxAgcCompensateA = 0; - pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA; - pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA; - - /* Disable TxAgc if the based value is not right */ - if (pAd->TssiRefA == 0xff) - pAd->bAutoTxAgcA = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, - ("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n", - pAd->TssiMinusBoundaryA[4], - pAd->TssiMinusBoundaryA[3], - pAd->TssiMinusBoundaryA[2], - pAd->TssiMinusBoundaryA[1], pAd->TssiRefA, - pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], - pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4], - pAd->TxAgcStepA, pAd->bAutoTxAgcA)); - } - pAd->BbpRssiToDbmDelta = 0x0; - - /* Read frequency offset setting for RF */ - RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value); - if ((value & 0x00FF) != 0x00FF) - pAd->RfFreqOffset = (unsigned long)(value & 0x00FF); - else - pAd->RfFreqOffset = 0; - DBGPRINT(RT_DEBUG_TRACE, - ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset)); - - /*CountryRegion byte offset (38h) */ - value = pAd->EEPROMDefaultValue[2] >> 8; /* 2.4G band */ - value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; /* 5G band */ - - if ((value <= REGION_MAXIMUM_BG_BAND) - && (value2 <= REGION_MAXIMUM_A_BAND)) { - pAd->CommonCfg.CountryRegion = ((u8)value) | 0x80; - pAd->CommonCfg.CountryRegionForABand = ((u8)value2) | 0x80; - TmpPhy = pAd->CommonCfg.PhyMode; - pAd->CommonCfg.PhyMode = 0xff; - RTMPSetPhyMode(pAd, TmpPhy); - SetCommonHT(pAd); - } - /* */ - /* Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch. */ - /* The valid value are (-10 ~ 10) */ - /* */ - RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value); - pAd->BGRssiOffset0 = value & 0x00ff; - pAd->BGRssiOffset1 = (value >> 8); - RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET + 2, value); - pAd->BGRssiOffset2 = value & 0x00ff; - pAd->ALNAGain1 = (value >> 8); - RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value); - pAd->BLNAGain = value & 0x00ff; - pAd->ALNAGain0 = (value >> 8); - - /* Validate 11b/g RSSI_0 offset. */ - if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10)) - pAd->BGRssiOffset0 = 0; - - /* Validate 11b/g RSSI_1 offset. */ - if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10)) - pAd->BGRssiOffset1 = 0; - - /* Validate 11b/g RSSI_2 offset. */ - if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10)) - pAd->BGRssiOffset2 = 0; - - RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value); - pAd->ARssiOffset0 = value & 0x00ff; - pAd->ARssiOffset1 = (value >> 8); - RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2), value); - pAd->ARssiOffset2 = value & 0x00ff; - pAd->ALNAGain2 = (value >> 8); - - if (((u8)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00)) - pAd->ALNAGain1 = pAd->ALNAGain0; - if (((u8)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00)) - pAd->ALNAGain2 = pAd->ALNAGain0; - - /* Validate 11a RSSI_0 offset. */ - if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10)) - pAd->ARssiOffset0 = 0; - - /* Validate 11a RSSI_1 offset. */ - if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10)) - pAd->ARssiOffset1 = 0; - - /*Validate 11a RSSI_2 offset. */ - if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10)) - pAd->ARssiOffset2 = 0; - -#ifdef RT30xx - /* */ - /* Get TX mixer gain setting */ - /* 0xff are invalid value */ - /* Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero. */ - /* RT359X default value is 0x02 */ - /* */ - if (IS_RT30xx(pAd) || IS_RT3572(pAd)) { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value); - pAd->TxMixerGain24G = 0; - value &= 0x00ff; - if (value != 0xff) { - value &= 0x07; - pAd->TxMixerGain24G = (u8)value; - } - } -#endif /* RT30xx // */ - - /* */ - /* Get LED Setting. */ - /* */ - RT28xx_EEPROM_READ16(pAd, 0x3a, value); - pAd->LedCntl.word = (value >> 8); - RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value); - pAd->Led1 = value; - RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value); - pAd->Led2 = value; - RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value); - pAd->Led3 = value; - - RTMPReadTxPwrPerRate(pAd); - -#ifdef RT30xx -#ifdef RTMP_EFUSE_SUPPORT - RtmpEfuseSupportCheck(pAd); -#endif /* RTMP_EFUSE_SUPPORT // */ -#endif /* RT30xx // */ - - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n")); -} - -/* - ======================================================================== - - Routine Description: - Set default value from EEPROM - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd) -{ - u32 data = 0; - u8 BBPR1 = 0; - u16 i; -/* EEPROM_ANTENNA_STRUC Antenna; */ - EEPROM_NIC_CONFIG2_STRUC NicConfig2; - u8 BBPR3 = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n")); - for (i = 3; i < NUM_EEPROM_BBP_PARMS; i++) { - u8 BbpRegIdx, BbpValue; - - if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) - && (pAd->EEPROMDefaultValue[i] != 0)) { - BbpRegIdx = (u8)(pAd->EEPROMDefaultValue[i] >> 8); - BbpValue = (u8)(pAd->EEPROMDefaultValue[i] & 0xff); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue); - } - } - - NicConfig2.word = pAd->EEPROMDefaultValue[1]; - - { - if ((NicConfig2.word & 0x00ff) == 0xff) { - NicConfig2.word &= 0xff00; - } - - if ((NicConfig2.word >> 8) == 0xff) { - NicConfig2.word &= 0x00ff; - } - } - - /* Save the antenna for future use */ - pAd->NicConfig2.word = NicConfig2.word; - -#ifdef RT30xx - /* set default antenna as main */ - if (pAd->RfIcType == RFIC_3020) - AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); -#endif /* RT30xx // */ - - /* */ - /* Send LED Setting to MCU. */ - /* */ - if (pAd->LedCntl.word == 0xFF) { - pAd->LedCntl.word = 0x01; - pAd->Led1 = 0x5555; - pAd->Led2 = 0x2221; - -#ifdef RTMP_MAC_PCI - pAd->Led3 = 0xA9F8; -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - pAd->Led3 = 0x5627; -#endif /* RTMP_MAC_USB // */ - } - - AsicSendCommandToMcu(pAd, 0x52, 0xff, (u8)pAd->Led1, - (u8)(pAd->Led1 >> 8)); - AsicSendCommandToMcu(pAd, 0x53, 0xff, (u8)pAd->Led2, - (u8)(pAd->Led2 >> 8)); - AsicSendCommandToMcu(pAd, 0x54, 0xff, (u8)pAd->Led3, - (u8)(pAd->Led3 >> 8)); - AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity); - - pAd->LedIndicatorStrength = 0xFF; - RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, before link up */ - - { - /* Read Hardware controlled Radio state enable bit */ - if (NicConfig2.field.HardwareRadioControl == 1) { - pAd->StaCfg.bHardwareRadio = TRUE; - - /* Read GPIO pin2 as Hardware controlled radio state */ - RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data); - if ((data & 0x04) == 0) { - pAd->StaCfg.bHwRadio = FALSE; - pAd->StaCfg.bRadio = FALSE; -/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - } - } else - pAd->StaCfg.bHardwareRadio = FALSE; - - if (pAd->StaCfg.bRadio == FALSE) { - RTMPSetLED(pAd, LED_RADIO_OFF); - } else { - RTMPSetLED(pAd, LED_RADIO_ON); -#ifdef RTMP_MAC_PCI -#ifdef RT3090 - AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff, - 0x02); - AsicCheckCommanOk(pAd, PowerRadioOffCID); -#endif /* RT3090 // */ -#ifndef RT3090 - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); -#endif /* RT3090 // */ - AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, - 0x00); - /* 2-1. wait command ok. */ - AsicCheckCommanOk(pAd, PowerWakeCID); -#endif /* RTMP_MAC_PCI // */ - } - } - -#ifdef RTMP_MAC_PCI -#ifdef RT30xx - if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - if (pChipOps->AsicReverseRfFromSleepMode) - pChipOps->AsicReverseRfFromSleepMode(pAd); - } - /* 3090 MCU Wakeup command needs more time to be stable. */ - /* Before stable, don't issue other MCU command to prevent from firmware error. */ - - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - DBGPRINT(RT_DEBUG_TRACE, ("%s, release Mcu Lock\n", __func__)); - RTMP_SEM_LOCK(&pAd->McuCmdLock); - pAd->brt30xxBanMcuCmd = FALSE; - RTMP_SEM_UNLOCK(&pAd->McuCmdLock); - } -#endif /* RT30xx // */ -#endif /* RTMP_MAC_PCI // */ - - /* Turn off patching for cardbus controller */ - if (NicConfig2.field.CardbusAcceleration == 1) { -/* pAd->bTest1 = TRUE; */ - } - - if (NicConfig2.field.DynamicTxAgcControl == 1) - pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE; - else - pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE; - /* */ - /* Since BBP has been progamed, to make sure BBP setting will be */ - /* upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND! */ - /* */ - pAd->CommonCfg.BandState = UNKNOWN_BAND; - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); - BBPR3 &= (~0x18); - if (pAd->Antenna.field.RxPath == 3) { - BBPR3 |= (0x10); - } else if (pAd->Antenna.field.RxPath == 2) { - BBPR3 |= (0x8); - } else if (pAd->Antenna.field.RxPath == 1) { - BBPR3 |= (0x0); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); - - { - /* Handle the difference when 1T */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1); - if (pAd->Antenna.field.TxPath == 1) { - BBPR1 &= (~0x18); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1); - - DBGPRINT(RT_DEBUG_TRACE, - ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", - pAd->CommonCfg.bHardwareRadio, - pAd->CommonCfg.bHardwareRadio)); - } - -#ifdef RTMP_MAC_USB -#ifdef RT30xx - /* update registers from EEPROM for RT3071 or later(3572/3592). */ - - if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { - u8 RegIdx, RegValue; - u16 value; - - /* after RT3071, write BBP from EEPROM 0xF0 to 0x102 */ - for (i = 0xF0; i <= 0x102; i = i + 2) { - value = 0xFFFF; - RT28xx_EEPROM_READ16(pAd, i, value); - if ((value != 0xFFFF) && (value != 0)) { - RegIdx = (u8)(value >> 8); - RegValue = (u8)(value & 0xff); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx, - RegValue); - DBGPRINT(RT_DEBUG_TRACE, - ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n", - i, RegIdx, RegValue)); - } - } - - /* after RT3071, write RF from EEPROM 0x104 to 0x116 */ - for (i = 0x104; i <= 0x116; i = i + 2) { - value = 0xFFFF; - RT28xx_EEPROM_READ16(pAd, i, value); - if ((value != 0xFFFF) && (value != 0)) { - RegIdx = (u8)(value >> 8); - RegValue = (u8)(value & 0xff); - RT30xxWriteRFRegister(pAd, RegIdx, RegValue); - DBGPRINT(RT_DEBUG_TRACE, - ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n", - i, RegIdx, RegValue)); - } - } - } -#endif /* RT30xx // */ -#endif /* RTMP_MAC_USB // */ - - DBGPRINT(RT_DEBUG_TRACE, - ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", - pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, - pAd->RfIcType, pAd->LedCntl.word)); - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n")); -} - -/* - ======================================================================== - - Routine Description: - Initialize NIC hardware - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset) -{ - int Status = NDIS_STATUS_SUCCESS; - WPDMA_GLO_CFG_STRUC GloCfg; -#ifdef RTMP_MAC_PCI - u32 Value; - DELAY_INT_CFG_STRUC IntCfg; -#endif /* RTMP_MAC_PCI // */ -/* INT_MASK_CSR_STRUC IntMask; */ - unsigned long i = 0, j = 0; - AC_TXOP_CSR0_STRUC csr0; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n")); - - /* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */ -retry: - i = 0; - do { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) - && (GloCfg.field.RxDMABusy == 0)) - break; - - RTMPusecDelay(1000); - i++; - } while (i < 100); - DBGPRINT(RT_DEBUG_TRACE, - ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word)); - GloCfg.word &= 0xff0; - GloCfg.field.EnTXWriteBackDDONE = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - - /* Record HW Beacon offset */ - pAd->BeaconOffset[0] = HW_BEACON_BASE0; - pAd->BeaconOffset[1] = HW_BEACON_BASE1; - pAd->BeaconOffset[2] = HW_BEACON_BASE2; - pAd->BeaconOffset[3] = HW_BEACON_BASE3; - pAd->BeaconOffset[4] = HW_BEACON_BASE4; - pAd->BeaconOffset[5] = HW_BEACON_BASE5; - pAd->BeaconOffset[6] = HW_BEACON_BASE6; - pAd->BeaconOffset[7] = HW_BEACON_BASE7; - - /* */ - /* write all shared Ring's base address into ASIC */ - /* */ - - /* asic simulation sequence put this ahead before loading firmware. */ - /* pbf hardware reset */ -#ifdef RTMP_MAC_PCI - RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); /* 0x10000 for reset rx, 0x3f resets all 6 tx rings. */ - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f); - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00); -#endif /* RTMP_MAC_PCI // */ - - /* Initialze ASIC for TX & Rx operation */ - if (NICInitializeAsic(pAd, bHardReset) != NDIS_STATUS_SUCCESS) { - if (j++ == 0) { - NICLoadFirmware(pAd); - goto retry; - } - return NDIS_STATUS_FAILURE; - } - -#ifdef RTMP_MAC_PCI - /* Write AC_BK base address register */ - Value = - RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value)); - - /* Write AC_BE base address register */ - Value = - RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value)); - - /* Write AC_VI base address register */ - Value = - RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value)); - - /* Write AC_VO base address register */ - Value = - RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value)); - - /* Write MGMT_BASE_CSR register */ - Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value)); - - /* Write RX_BASE_CSR register */ - Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa); - RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value); - DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value)); - - /* Init RX Ring index pointer */ - pAd->RxRing.RxSwReadIdx = 0; - pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1; - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - - /* Init TX rings index pointer */ - { - for (i = 0; i < NUM_OF_TX_RING; i++) { - pAd->TxRing[i].TxSwFreeIdx = 0; - pAd->TxRing[i].TxCpuIdx = 0; - RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10), - pAd->TxRing[i].TxCpuIdx); - } - } - - /* init MGMT ring index pointer */ - pAd->MgmtRing.TxSwFreeIdx = 0; - pAd->MgmtRing.TxCpuIdx = 0; - RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); - - /* */ - /* set each Ring's SIZE into ASIC. Descriptor Size is fixed by design. */ - /* */ - - /* Write TX_RING_CSR0 register */ - Value = TX_RING_SIZE; - RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value); - RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value); - RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value); - RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value); - RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value); - Value = MGMT_RING_SIZE; - RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value); - - /* Write RX_RING_CSR register */ - Value = RX_RING_SIZE; - RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value); -#endif /* RTMP_MAC_PCI // */ - - /* WMM parameter */ - csr0.word = 0; - RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); - if (pAd->CommonCfg.PhyMode == PHY_11B) { - csr0.field.Ac0Txop = 192; /* AC_VI: 192*32us ~= 6ms */ - csr0.field.Ac1Txop = 96; /* AC_VO: 96*32us ~= 3ms */ - } else { - csr0.field.Ac0Txop = 96; /* AC_VI: 96*32us ~= 3ms */ - csr0.field.Ac1Txop = 48; /* AC_VO: 48*32us ~= 1.5ms */ - } - RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word); - -#ifdef RTMP_MAC_PCI - /* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */ - i = 0; - do { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) - && (GloCfg.field.RxDMABusy == 0)) - break; - - RTMPusecDelay(1000); - i++; - } while (i < 100); - - GloCfg.word &= 0xff0; - GloCfg.field.EnTXWriteBackDDONE = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - - IntCfg.word = 0; - RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word); -#endif /* RTMP_MAC_PCI // */ - - /* reset action */ - /* Load firmware */ - /* Status = NICLoadFirmware(pAd); */ - - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n")); - return Status; -} - -/* - ======================================================================== - - Routine Description: - Initialize ASIC - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset) -{ - unsigned long Index = 0; - u8 R0 = 0xff; - u32 MacCsr12 = 0, Counter = 0; -#ifdef RTMP_MAC_USB - u32 MacCsr0 = 0; - int Status; - u8 Value = 0xff; -#endif /* RTMP_MAC_USB // */ -#ifdef RT30xx - u8 bbpreg = 0; - u8 RFValue = 0; -#endif /* RT30xx // */ - u16 KeyIdx; - int i, apidx; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n")); - -#ifdef RTMP_MAC_PCI - RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3); /* To fix driver disable/enable hang issue when radio off */ - if (bHardReset == TRUE) { - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); - } else - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1); - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); - /* Initialize MAC register to default value */ - for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) { - RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, - MACRegTable[Index].Value); - } - - { - for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) { - RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, - STAMACRegTable[Index].Value); - } - } -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - /* */ - /* Make sure MAC gets ready after NICLoadFirmware(). */ - /* */ - Index = 0; - - /*To avoid hang-on issue when interface up in kernel 2.4, */ - /*we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly. */ - do { - RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); - - if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF)) - break; - - RTMPusecDelay(10); - } while (Index++ < 100); - - pAd->MACVersion = MacCsr0; - DBGPRINT(RT_DEBUG_TRACE, - ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); - /* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue. */ - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12); - MacCsr12 &= (~0x2000); - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12); - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); - RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0); - Status = RTUSBVenderReset(pAd); - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); - - /* Initialize MAC register to default value */ - for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) { -#ifdef RT30xx - if ((MACRegTable[Index].Register == TX_SW_CFG0) - && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd) - || IS_RT3090(pAd) || IS_RT3390(pAd))) { - MACRegTable[Index].Value = 0x00000400; - } -#endif /* RT30xx // */ - RTMP_IO_WRITE32(pAd, (u16)MACRegTable[Index].Register, - MACRegTable[Index].Value); - } - - { - for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) { - RTMP_IO_WRITE32(pAd, - (u16)STAMACRegTable[Index].Register, - STAMACRegTable[Index].Value); - } - } -#endif /* RTMP_MAC_USB // */ - -#ifdef RT30xx - /* Initialize RT3070 serial MAC registers which is different from RT2870 serial */ - if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { - RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); - - /* RT3071 version E has fixed this issue */ - if ((pAd->MACVersion & 0xffff) < 0x0211) { - if (pAd->NicConfig2.field.DACTestBit == 1) { - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically */ - } else { - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); /* To fix throughput drop drastically */ - } - } else { - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); - } - } else if (IS_RT3070(pAd)) { - if (((pAd->MACVersion & 0xffff) < 0x0201)) { - RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically */ - } else { - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0); - } - } -#endif /* RT30xx // */ - - /* */ - /* Before program BBP, we need to wait BBP/RF get wake up. */ - /* */ - Index = 0; - do { - RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12); - - if ((MacCsr12 & 0x03) == 0) /* if BB.RF is stable */ - break; - - DBGPRINT(RT_DEBUG_TRACE, - ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12)); - RTMPusecDelay(1000); - } while (Index++ < 100); - - /* The commands to firmware should be after these commands, these commands will init firmware */ - /* PCI and USB are not the same because PCI driver needs to wait for PCI bus ready */ - RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); /* initialize BBP R/W access agent */ - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0); -#ifdef RT3090 - /*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */ - AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0); - /*2008/11/28:KH add to fix the dead rf frequency offset bug--> */ -#endif /* RT3090 // */ - RTMPusecDelay(1000); - - /* Read BBP register, make sure BBP is up and running before write new data */ - Index = 0; - do { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0); - DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0)); - } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00))); - /*ASSERT(Index < 20); //this will cause BSOD on Check-build driver */ - - if ((R0 == 0xff) || (R0 == 0x00)) - return NDIS_STATUS_FAILURE; - - /* Initialize BBP register to default value */ - for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, - BBPRegTable[Index].Value); - } - -#ifdef RTMP_MAC_PCI - /* TODO: shiang, check MACVersion, currently, rbus-based chip use this. */ - if (pAd->MACVersion == 0x28720200) { - /*u8 value; */ - unsigned long value2; - - /*disable MLD by Bruce 20080704 */ - /*BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value); */ - /*BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4); */ - - /*Maximum PSDU length from 16K to 32K bytes */ - RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2); - value2 &= ~(0x3 << 12); - value2 |= (0x2 << 12); - RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2); - } -#endif /* RTMP_MAC_PCI // */ - - /* for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. */ - /* RT3090 should not program BBP R84 to 0x19, otherwise TX will block. */ - /*3070/71/72,3090,3090A( are included in RT30xx),3572,3390 */ - if (((pAd->MACVersion & 0xffff) != 0x0101) - && !(IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); - -#ifdef RT30xx -/* add by johnli, RF power sequence setup */ - if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { /*update for RT3070/71/72/90/91/92,3572,3390. */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33); - } - - if (IS_RT3090(pAd) || IS_RT3390(pAd)) /* RT309x, RT3071/72 */ - { - /* enable DC filter */ - if ((pAd->MACVersion & 0xffff) >= 0x0211) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); - } - /* improve power consumption */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg); - if (pAd->Antenna.field.TxPath == 1) { - /* turn off tx DAC_1 */ - bbpreg = (bbpreg | 0x20); - } - - if (pAd->Antenna.field.RxPath == 1) { - /* turn off tx ADC_1 */ - bbpreg &= (~0x2); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg); - - /* improve power consumption in RT3071 Ver.E */ - if ((pAd->MACVersion & 0xffff) >= 0x0211) { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); - bbpreg &= (~0x3); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); - } - } else if (IS_RT3070(pAd)) { - if ((pAd->MACVersion & 0xffff) >= 0x0201) { - /* enable DC filter */ - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); - - /* improve power consumption in RT3070 Ver.F */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); - bbpreg &= (~0x3); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); - } - /* TX_LO1_en, RF R17 register Bit 3 to 0 */ - RT30xxReadRFRegister(pAd, RF_R17, &RFValue); - RFValue &= (~0x08); - /* to fix rx long range issue */ - if (pAd->NicConfig2.field.ExternalLNAForG == 0) { - RFValue |= 0x20; - } - /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */ - if (pAd->TxMixerGain24G >= 1) { - RFValue &= (~0x7); /* clean bit [2:0] */ - RFValue |= pAd->TxMixerGain24G; - } - RT30xxWriteRFRegister(pAd, RF_R17, RFValue); - } -/* end johnli */ -#endif /* RT30xx // */ - - if (pAd->MACVersion == 0x28600100) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12); - } - - if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) /* 3*3 */ - { - /* enlarge MAX_LEN_CFG */ - u32 csr; - RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr); - csr &= 0xFFF; - csr |= 0x2000; - RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr); - } -#ifdef RTMP_MAC_USB - { - u8 MAC_Value[] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 }; - - /*Initialize WCID table */ - Value = 0xff; - for (Index = 0; Index < 254; Index++) { - RTUSBMultiWrite(pAd, - (u16)(MAC_WCID_BASE + Index * 8), - MAC_Value, 8); - } - } -#endif /* RTMP_MAC_USB // */ - - /* Add radio off control */ - { - if (pAd->StaCfg.bRadio == FALSE) { -/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n")); - } - } - - /* Clear raw counters */ - RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter); - RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter); - RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter); - RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter); - RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter); - - /* ASIC will keep garbage value after boot */ - /* Clear all shared key table when initial */ - /* This routine can be ignored in radio-ON/OFF operation. */ - if (bHardReset) { - for (KeyIdx = 0; KeyIdx < 4; KeyIdx++) { - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * KeyIdx, - 0); - } - - /* Clear all pairwise key table when initial */ - for (KeyIdx = 0; KeyIdx < 256; KeyIdx++) { - RTMP_IO_WRITE32(pAd, - MAC_WCID_ATTRIBUTE_BASE + - (KeyIdx * HW_WCID_ATTRI_SIZE), 1); - } - } - /* assert HOST ready bit */ -/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark */ -/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4); */ - - /* It isn't necessary to clear this space when not hard reset. */ - if (bHardReset == TRUE) { - /* clear all on-chip BEACON frame space */ - for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++) { - for (i = 0; i < HW_BEACON_OFFSET >> 2; i += 4) - RTMP_IO_WRITE32(pAd, - pAd->BeaconOffset[apidx] + i, - 0x00); - } - } -#ifdef RTMP_MAC_USB - AsicDisableSync(pAd); - /* Clear raw counters */ - RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter); - RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter); - RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter); - RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter); - RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter); - /* Default PCI clock cycle per ms is different as default setting, which is based on PCI. */ - RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter); - Counter &= 0xffffff00; - Counter |= 0x000001e; - RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter); -#endif /* RTMP_MAC_USB // */ - - { - /* for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. */ - if ((pAd->MACVersion & 0xffff) != 0x0101) - RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f); - } - - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n")); - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: - Reset NIC Asics - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - Reset NIC to initial state AS IS system boot up time. - - ======================================================================== -*/ -void NICIssueReset(struct rt_rtmp_adapter *pAd) -{ - u32 Value = 0; - DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n")); - - /* Abort Tx, prevent ASIC from writing to Host memory */ - /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000); */ - - /* Disable Rx, register value supposed will remain after reset */ - RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); - Value &= (0xfffffff3); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); - - /* Issue reset and clear from reset state */ - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); /* 2004-09-17 change from 0x01 */ - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00); - - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n")); -} - -/* - ======================================================================== - - Routine Description: - Check ASIC registers and find any reason the system might hang - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd) -{ - return (FALSE); -} - -void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd) -{ - TX_STA_FIFO_STRUC StaFifo; - struct rt_mac_table_entry *pEntry; - u8 i = 0; - u8 pid = 0, wcid = 0; - char reTry; - u8 succMCS; - - do { - RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word); - - if (StaFifo.field.bValid == 0) - break; - - wcid = (u8)StaFifo.field.wcid; - - /* ignore NoACK and MGMT frame use 0xFF as WCID */ - if ((StaFifo.field.TxAckRequired == 0) - || (wcid >= MAX_LEN_OF_MAC_TABLE)) { - i++; - continue; - } - - /* PID store Tx MCS Rate */ - pid = (u8)StaFifo.field.PidType; - - pEntry = &pAd->MacTab.Content[wcid]; - - pEntry->DebugFIFOCount++; - - if (StaFifo.field.TxBF) /* 3*3 */ - pEntry->TxBFCount++; - - if (!StaFifo.field.TxSuccess) { - pEntry->FIFOCount++; - pEntry->OneSecTxFailCount++; - - if (pEntry->FIFOCount >= 1) { - DBGPRINT(RT_DEBUG_TRACE, ("#")); - pEntry->NoBADataCountDown = 64; - - if (pEntry->PsMode == PWR_ACTIVE) { - int tid; - for (tid = 0; tid < NUM_OF_TID; tid++) { - BAOriSessionTearDown(pAd, - pEntry-> - Aid, tid, - FALSE, - FALSE); - } - - /* Update the continuous transmission counter except PS mode */ - pEntry->ContinueTxFailCnt++; - } else { - /* Clear the FIFOCount when sta in Power Save mode. Basically we assume */ - /* this tx error happened due to sta just go to sleep. */ - pEntry->FIFOCount = 0; - pEntry->ContinueTxFailCnt = 0; - } - /*pEntry->FIFOCount = 0; */ - } - /*pEntry->bSendBAR = TRUE; */ - } else { - if ((pEntry->PsMode != PWR_SAVE) - && (pEntry->NoBADataCountDown > 0)) { - pEntry->NoBADataCountDown--; - if (pEntry->NoBADataCountDown == 0) { - DBGPRINT(RT_DEBUG_TRACE, ("@\n")); - } - } - - pEntry->FIFOCount = 0; - pEntry->OneSecTxNoRetryOkCount++; - /* update NoDataIdleCount when successful send packet to STA. */ - pEntry->NoDataIdleCount = 0; - pEntry->ContinueTxFailCnt = 0; - } - - succMCS = StaFifo.field.SuccessRate & 0x7F; - - reTry = pid - succMCS; - - if (StaFifo.field.TxSuccess) { - pEntry->TXMCSExpected[pid]++; - if (pid == succMCS) { - pEntry->TXMCSSuccessful[pid]++; - } else { - pEntry->TXMCSAutoFallBack[pid][succMCS]++; - } - } else { - pEntry->TXMCSFailed[pid]++; - } - - if (reTry > 0) { - if ((pid >= 12) && succMCS <= 7) { - reTry -= 4; - } - pEntry->OneSecTxRetryOkCount += reTry; - } - - i++; - /* ASIC store 16 stack */ - } while (i < (2 * TX_RING_SIZE)); - -} - -/* - ======================================================================== - - Routine Description: - Read statistical counters from hardware registers and record them - in software variables for later on query - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd) -{ - u32 OldValue; /*, Value2; */ - /*unsigned long PageSum, OneSecTransmitCount; */ - /*unsigned long TxErrorRatio, Retry, Fail; */ - RX_STA_CNT0_STRUC RxStaCnt0; - RX_STA_CNT1_STRUC RxStaCnt1; - RX_STA_CNT2_STRUC RxStaCnt2; - TX_STA_CNT0_STRUC TxStaCnt0; - TX_STA_CNT1_STRUC StaTx1; - TX_STA_CNT2_STRUC StaTx2; - TX_AGG_CNT_STRUC TxAggCnt; - TX_AGG_CNT0_STRUC TxAggCnt0; - TX_AGG_CNT1_STRUC TxAggCnt1; - TX_AGG_CNT2_STRUC TxAggCnt2; - TX_AGG_CNT3_STRUC TxAggCnt3; - TX_AGG_CNT4_STRUC TxAggCnt4; - TX_AGG_CNT5_STRUC TxAggCnt5; - TX_AGG_CNT6_STRUC TxAggCnt6; - TX_AGG_CNT7_STRUC TxAggCnt7; - struct rt_counter_ralink *pRalinkCounters; - - pRalinkCounters = &pAd->RalinkCounters; - - RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word); - RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word); - - { - RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word); - /* Update RX PLCP error counter */ - pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr; - /* Update False CCA counter */ - pAd->RalinkCounters.OneSecFalseCCACnt += - RxStaCnt1.field.FalseCca; - } - - /* Update FCS counters */ - OldValue = pAd->WlanCounters.FCSErrorCount.u.LowPart; - pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); /* >> 7); */ - if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue) - pAd->WlanCounters.FCSErrorCount.u.HighPart++; - - /* Add FCS error count to private counters */ - pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr; - OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart; - pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr; - if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue) - pRalinkCounters->RealFcsErrCount.u.HighPart++; - - /* Update Duplicate Rcv check */ - pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount; - pAd->WlanCounters.FrameDuplicateCount.u.LowPart += - RxStaCnt2.field.RxDupliCount; - /* Update RX Overflow counter */ - pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount); - - /*pAd->RalinkCounters.RxCount = 0; */ -#ifdef RTMP_MAC_USB - if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) { - pAd->watchDogRxCnt = pRalinkCounters->RxCount; - pAd->watchDogRxOverFlowCnt = 0; - } else { - if (RxStaCnt2.field.RxFifoOverflowCount) - pAd->watchDogRxOverFlowCnt++; - else - pAd->watchDogRxOverFlowCnt = 0; - } -#endif /* RTMP_MAC_USB // */ - - /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */ - /* (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1))) */ - if (!pAd->bUpdateBcnCntDone) { - /* Update BEACON sent count */ - RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); - RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word); - pRalinkCounters->OneSecBeaconSentCnt += - TxStaCnt0.field.TxBeaconCount; - pRalinkCounters->OneSecTxRetryOkCount += - StaTx1.field.TxRetransmit; - pRalinkCounters->OneSecTxNoRetryOkCount += - StaTx1.field.TxSuccess; - pRalinkCounters->OneSecTxFailCount += - TxStaCnt0.field.TxFailCount; - pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += - StaTx1.field.TxSuccess; - pAd->WlanCounters.RetryCount.u.LowPart += - StaTx1.field.TxRetransmit; - pAd->WlanCounters.FailedCount.u.LowPart += - TxStaCnt0.field.TxFailCount; - } - - /*if (pAd->bStaFifoTest == TRUE) */ - { - RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word); - RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word); - pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount; - pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount; - pRalinkCounters->TxAgg1MPDUCount += - TxAggCnt0.field.AggSize1Count; - pRalinkCounters->TxAgg2MPDUCount += - TxAggCnt0.field.AggSize2Count; - - pRalinkCounters->TxAgg3MPDUCount += - TxAggCnt1.field.AggSize3Count; - pRalinkCounters->TxAgg4MPDUCount += - TxAggCnt1.field.AggSize4Count; - pRalinkCounters->TxAgg5MPDUCount += - TxAggCnt2.field.AggSize5Count; - pRalinkCounters->TxAgg6MPDUCount += - TxAggCnt2.field.AggSize6Count; - - pRalinkCounters->TxAgg7MPDUCount += - TxAggCnt3.field.AggSize7Count; - pRalinkCounters->TxAgg8MPDUCount += - TxAggCnt3.field.AggSize8Count; - pRalinkCounters->TxAgg9MPDUCount += - TxAggCnt4.field.AggSize9Count; - pRalinkCounters->TxAgg10MPDUCount += - TxAggCnt4.field.AggSize10Count; - - pRalinkCounters->TxAgg11MPDUCount += - TxAggCnt5.field.AggSize11Count; - pRalinkCounters->TxAgg12MPDUCount += - TxAggCnt5.field.AggSize12Count; - pRalinkCounters->TxAgg13MPDUCount += - TxAggCnt6.field.AggSize13Count; - pRalinkCounters->TxAgg14MPDUCount += - TxAggCnt6.field.AggSize14Count; - - pRalinkCounters->TxAgg15MPDUCount += - TxAggCnt7.field.AggSize15Count; - pRalinkCounters->TxAgg16MPDUCount += - TxAggCnt7.field.AggSize16Count; - - /* Calculate the transmitted A-MPDU count */ - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - TxAggCnt0.field.AggSize1Count; - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt0.field.AggSize2Count / 2); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt1.field.AggSize3Count / 3); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt1.field.AggSize4Count / 4); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt2.field.AggSize5Count / 5); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt2.field.AggSize6Count / 6); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt3.field.AggSize7Count / 7); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt3.field.AggSize8Count / 8); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt4.field.AggSize9Count / 9); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt4.field.AggSize10Count / 10); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt5.field.AggSize11Count / 11); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt5.field.AggSize12Count / 12); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt6.field.AggSize13Count / 13); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt6.field.AggSize14Count / 14); - - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt7.field.AggSize15Count / 15); - pRalinkCounters->TransmittedAMPDUCount.u.LowPart += - (TxAggCnt7.field.AggSize16Count / 16); - } - -} - -/* - ======================================================================== - - Routine Description: - Reset NIC from error - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - Reset NIC from error state - - ======================================================================== -*/ -void NICResetFromError(struct rt_rtmp_adapter *pAd) -{ - /* Reset BBP (according to alex, reset ASIC will force reset BBP */ - /* Therefore, skip the reset BBP */ - /* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2); */ - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1); - /* Remove ASIC from reset state */ - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); - - NICInitializeAdapter(pAd, FALSE); - NICInitAsicFromEEPROM(pAd); - - /* Switch to current channel, since during reset process, the connection should remains on. */ - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); -} - -int NICLoadFirmware(struct rt_rtmp_adapter *pAd) -{ - int status = NDIS_STATUS_SUCCESS; - if (pAd->chipOps.loadFirmware) - status = pAd->chipOps.loadFirmware(pAd); - - return status; -} - -/* - ======================================================================== - - Routine Description: - erase 8051 firmware image in MAC ASIC - - Arguments: - Adapter Pointer to our adapter - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -void NICEraseFirmware(struct rt_rtmp_adapter *pAd) -{ - if (pAd->chipOps.eraseFirmware) - pAd->chipOps.eraseFirmware(pAd); - -} /* End of NICEraseFirmware */ - -/* - ======================================================================== - - Routine Description: - Load Tx rate switching parameters - - Arguments: - Adapter Pointer to our adapter - - Return Value: - NDIS_STATUS_SUCCESS firmware image load ok - NDIS_STATUS_FAILURE image not found - - IRQL = PASSIVE_LEVEL - - Rate Table Format: - 1. (B0: Valid Item number) (B1:Initial item from zero) - 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec) - - ======================================================================== -*/ -int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd) -{ - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: - Compare two memory block - - Arguments: - pSrc1 Pointer to first memory address - pSrc2 Pointer to second memory address - - Return Value: - 0: memory is equal - 1: pSrc1 memory is larger - 2: pSrc2 memory is larger - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length) -{ - u8 *pMem1; - u8 *pMem2; - unsigned long Index = 0; - - pMem1 = (u8 *)pSrc1; - pMem2 = (u8 *)pSrc2; - - for (Index = 0; Index < Length; Index++) { - if (pMem1[Index] > pMem2[Index]) - return (1); - else if (pMem1[Index] < pMem2[Index]) - return (2); - } - - /* Equal */ - return (0); -} - -/* - ======================================================================== - - Routine Description: - Zero out memory block - - Arguments: - pSrc1 Pointer to memory address - Length Size - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPZeroMemory(void *pSrc, unsigned long Length) -{ - u8 *pMem; - unsigned long Index = 0; - - pMem = (u8 *)pSrc; - - for (Index = 0; Index < Length; Index++) { - pMem[Index] = 0x00; - } -} - -/* - ======================================================================== - - Routine Description: - Copy data from memory block 1 to memory block 2 - - Arguments: - pDest Pointer to destination memory address - pSrc Pointer to source memory address - Length Copy size - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length) -{ - u8 *pMem1; - u8 *pMem2; - u32 Index; - - ASSERT((Length == 0) || (pDest && pSrc)); - - pMem1 = (u8 *)pDest; - pMem2 = (u8 *)pSrc; - - for (Index = 0; Index < Length; Index++) { - pMem1[Index] = pMem2[Index]; - } -} - -/* - ======================================================================== - - Routine Description: - Initialize port configuration structure - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -void UserCfgInit(struct rt_rtmp_adapter *pAd) -{ - u32 key_index, bss_index; - - DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n")); - - /* */ - /* part I. initialize common configuration */ - /* */ -#ifdef RTMP_MAC_USB - pAd->BulkOutReq = 0; - - pAd->BulkOutComplete = 0; - pAd->BulkOutCompleteOther = 0; - pAd->BulkOutCompleteCancel = 0; - pAd->BulkInReq = 0; - pAd->BulkInComplete = 0; - pAd->BulkInCompleteFail = 0; - - /*pAd->QuickTimerP = 100; */ - /*pAd->TurnAggrBulkInCount = 0; */ - pAd->bUsbTxBulkAggre = 0; - - /* init as unused value to ensure driver will set to MCU once. */ - pAd->LedIndicatorStrength = 0xFF; - - pAd->CommonCfg.MaxPktOneTxBulk = 2; - pAd->CommonCfg.TxBulkFactor = 1; - pAd->CommonCfg.RxBulkFactor = 1; - - pAd->CommonCfg.TxPower = 100; /*mW */ - - NdisZeroMemory(&pAd->CommonCfg.IOTestParm, - sizeof(pAd->CommonCfg.IOTestParm)); -#endif /* RTMP_MAC_USB // */ - - for (key_index = 0; key_index < SHARE_KEY_NUM; key_index++) { - for (bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++) { - pAd->SharedKey[bss_index][key_index].KeyLen = 0; - pAd->SharedKey[bss_index][key_index].CipherAlg = - CIPHER_NONE; - } - } - - pAd->EepromAccess = FALSE; - - pAd->Antenna.word = 0; - pAd->CommonCfg.BBPCurrentBW = BW_20; - - pAd->LedCntl.word = 0; -#ifdef RTMP_MAC_PCI - pAd->LedIndicatorStrength = 0; - pAd->RLnkCtrlOffset = 0; - pAd->HostLnkCtrlOffset = 0; - pAd->StaCfg.PSControl.field.EnableNewPS = TRUE; - pAd->CheckDmaBusyCount = 0; -#endif /* RTMP_MAC_PCI // */ - - pAd->bAutoTxAgcA = FALSE; /* Default is OFF */ - pAd->bAutoTxAgcG = FALSE; /* Default is OFF */ - pAd->RfIcType = RFIC_2820; - - /* Init timer for reset complete event */ - pAd->CommonCfg.CentralChannel = 1; - pAd->bForcePrintTX = FALSE; - pAd->bForcePrintRX = FALSE; - pAd->bStaFifoTest = FALSE; - pAd->bProtectionTest = FALSE; - pAd->CommonCfg.Dsifs = 10; /* in units of usec */ - pAd->CommonCfg.TxPower = 100; /*mW */ - pAd->CommonCfg.TxPowerPercentage = 0xffffffff; /* AUTO */ - pAd->CommonCfg.TxPowerDefault = 0xffffffff; /* AUTO */ - pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; /* use Long preamble on TX by defaut */ - pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; - pAd->CommonCfg.RtsThreshold = 2347; - pAd->CommonCfg.FragmentThreshold = 2346; - pAd->CommonCfg.UseBGProtection = 0; /* 0: AUTO */ - pAd->CommonCfg.bEnableTxBurst = TRUE; /*0; */ - pAd->CommonCfg.PhyMode = 0xff; /* unknown */ - pAd->CommonCfg.BandState = UNKNOWN_BAND; - pAd->CommonCfg.RadarDetect.CSPeriod = 10; - pAd->CommonCfg.RadarDetect.CSCount = 0; - pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; - - pAd->CommonCfg.RadarDetect.ChMovingTime = 65; - pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3; - pAd->CommonCfg.bAPSDCapable = FALSE; - pAd->CommonCfg.bNeedSendTriggerFrame = FALSE; - pAd->CommonCfg.TriggerTimerCount = 0; - pAd->CommonCfg.bAPSDForcePowerSave = FALSE; - pAd->CommonCfg.bCountryFlag = FALSE; - pAd->CommonCfg.TxStream = 0; - pAd->CommonCfg.RxStream = 0; - - NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI)); - - NdisZeroMemory(&pAd->CommonCfg.HtCapability, - sizeof(pAd->CommonCfg.HtCapability)); - pAd->HTCEnable = FALSE; - pAd->bBroadComHT = FALSE; - pAd->CommonCfg.bRdg = FALSE; - - NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, - sizeof(pAd->CommonCfg.AddHTInfo)); - pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; - pAd->CommonCfg.BACapability.field.MpduDensity = 0; - pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; - pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; /*32; */ - pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; /*32; */ - DBGPRINT(RT_DEBUG_TRACE, - ("--> UserCfgInit. BACapability = 0x%x\n", - pAd->CommonCfg.BACapability.word)); - - pAd->CommonCfg.BACapability.field.AutoBA = FALSE; - BATableInit(pAd, &pAd->BATable); - - pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1; - pAd->CommonCfg.bHTProtect = 1; - pAd->CommonCfg.bMIMOPSEnable = TRUE; - /*2008/11/05:KH add to support Antenna power-saving of AP<-- */ - pAd->CommonCfg.bGreenAPEnable = FALSE; - /*2008/11/05:KH add to support Antenna power-saving of AP--> */ - pAd->CommonCfg.bBADecline = FALSE; - pAd->CommonCfg.bDisableReordering = FALSE; - - if (pAd->MACVersion == 0x28720200) { - pAd->CommonCfg.TxBASize = 13; /*by Jerry recommend */ - } else { - pAd->CommonCfg.TxBASize = 7; - } - - pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word; - - /*pAd->CommonCfg.HTPhyMode.field.BW = BW_20; */ - /*pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO; */ - /*pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800; */ - /*pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE; */ - pAd->CommonCfg.TxRate = RATE_6; - - pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6; - pAd->CommonCfg.MlmeTransmit.field.BW = BW_20; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - - pAd->CommonCfg.BeaconPeriod = 100; /* in mSec */ - - /* */ - /* part II. initialize STA specific configuration */ - /* */ - { - RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT); - RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST); - RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST); - RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST); - - pAd->StaCfg.Psm = PWR_ACTIVE; - - pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled; - pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled; - pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled; - pAd->StaCfg.bMixCipher = FALSE; - pAd->StaCfg.DefaultKeyId = 0; - - /* 802.1x port control */ - pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP; - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - pAd->StaCfg.LastMicErrorTime = 0; - pAd->StaCfg.MicErrCnt = 0; - pAd->StaCfg.bBlockAssoc = FALSE; - pAd->StaCfg.WpaState = SS_NOTUSE; - - pAd->CommonCfg.NdisRadioStateOff = FALSE; /* New to support microsoft disable radio with OID command */ - - pAd->StaCfg.RssiTrigger = 0; - NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(struct rt_rssi_sample)); - pAd->StaCfg.RssiTriggerMode = - RSSI_TRIGGERED_UPON_BELOW_THRESHOLD; - pAd->StaCfg.AtimWin = 0; - pAd->StaCfg.DefaultListenCount = 3; /*default listen count; */ - pAd->StaCfg.BssType = BSS_INFRA; /* BSS_INFRA or BSS_ADHOC or BSS_MONITOR */ - pAd->StaCfg.bScanReqIsFromWebUI = FALSE; - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); - - pAd->StaCfg.bAutoTxRateSwitch = TRUE; - pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; - } - -#ifdef PCIE_PS_SUPPORT - pAd->brt30xxBanMcuCmd = FALSE; - pAd->b3090ESpecialChip = FALSE; -/*KH Debug:the following must be removed */ - pAd->StaCfg.PSControl.field.rt30xxPowerMode = 3; - pAd->StaCfg.PSControl.field.rt30xxForceASPMTest = 0; - pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM = 1; -#endif /* PCIE_PS_SUPPORT // */ - - /* global variables mXXXX used in MAC protocol state machines */ - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); - - /* PHY specification */ - pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; /* default PHY mode */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); /* CCK use long preamble */ - - { - /* user desired power mode */ - pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; - pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM; - pAd->StaCfg.bWindowsACCAMEnable = FALSE; - - RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, - GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), - pAd, FALSE); - pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; - - /* Patch for Ndtest */ - pAd->StaCfg.ScanCnt = 0; - - pAd->StaCfg.bHwRadio = TRUE; /* Default Hardware Radio status is On */ - pAd->StaCfg.bSwRadio = TRUE; /* Default Software Radio status is On */ - pAd->StaCfg.bRadio = TRUE; /* bHwRadio && bSwRadio */ - pAd->StaCfg.bHardwareRadio = FALSE; /* Default is OFF */ - pAd->StaCfg.bShowHiddenSSID = FALSE; /* Default no show */ - - /* Nitro mode control */ - pAd->StaCfg.bAutoReconnect = TRUE; - - /* Save the init time as last scan time, the system should do scan after 2 seconds. */ - /* This patch is for driver wake up from standby mode, system will do scan right away. */ - NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); - if (pAd->StaCfg.LastScanTime > 10 * OS_HZ) - pAd->StaCfg.LastScanTime -= (10 * OS_HZ); - - NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE + 1); -#ifdef RTMP_MAC_PCI - sprintf((char *)pAd->nickname, "RT2860STA"); -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - sprintf((char *)pAd->nickname, "RT2870STA"); -#endif /* RTMP_MAC_USB // */ - RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, - GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), - pAd, FALSE); - pAd->StaCfg.IEEE8021X = FALSE; - pAd->StaCfg.IEEE8021x_required_keys = FALSE; - pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; - pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; - pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE; - - NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); - - pAd->StaCfg.bAutoConnectByBssid = FALSE; - pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME; - NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); - pAd->StaCfg.WpaPassPhraseLen = 0; - pAd->StaCfg.bAutoRoaming = FALSE; - pAd->StaCfg.bForceTxBurst = FALSE; - } - - /* Default for extra information is not valid */ - pAd->ExtraInfo = EXTRA_INFO_CLEAR; - - /* Default Config change flag */ - pAd->bConfigChanged = FALSE; - - /* */ - /* part III. AP configurations */ - /* */ - - /* */ - /* part IV. others */ - /* */ - /* dynamic BBP R66:sensibity tuning to overcome background noise */ - pAd->BbpTuning.bEnable = TRUE; - pAd->BbpTuning.FalseCcaLowerThreshold = 100; - pAd->BbpTuning.FalseCcaUpperThreshold = 512; - pAd->BbpTuning.R66Delta = 4; - pAd->Mlme.bEnableAutoAntennaCheck = TRUE; - - /* */ - /* Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value. */ - /* if not initial this value, the default value will be 0. */ - /* */ - pAd->BbpTuning.R66CurrentValue = 0x38; - - pAd->Bbp94 = BBPR94_DEFAULT; - pAd->BbpForCCK = FALSE; - - /* Default is FALSE for test bit 1 */ - /*pAd->bTest1 = FALSE; */ - - /* initialize MAC table and allocate spin lock */ - NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table)); - InitializeQueueHeader(&pAd->MacTab.McastPsQueue); - NdisAllocateSpinLock(&pAd->MacTabLock); - - /*RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE); */ - /*RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV); */ - - pAd->CommonCfg.bWiFiTest = FALSE; -#ifdef RTMP_MAC_PCI - pAd->bPCIclkOff = FALSE; -#endif /* RTMP_MAC_PCI // */ - - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n")); -} - -/* IRQL = PASSIVE_LEVEL */ -/* */ -/* FUNCTION: AtoH(char *, u8 *, int) */ -/* */ -/* PURPOSE: Converts ascii string to network order hex */ -/* */ -/* PARAMETERS: */ -/* src - pointer to input ascii string */ -/* dest - pointer to output hex */ -/* destlen - size of dest */ -/* */ -/* COMMENTS: */ -/* */ -/* 2 ascii bytes make a hex byte so must put 1st ascii byte of pair */ -/* into upper nibble and 2nd ascii byte of pair into lower nibble. */ -/* */ -/* IRQL = PASSIVE_LEVEL */ - -void AtoH(char *src, u8 *dest, int destlen) -{ - char *srcptr; - u8 *destTemp; - - srcptr = src; - destTemp = (u8 *)dest; - - while (destlen--) { - *destTemp = hex_to_bin(*srcptr++) << 4; /* Put 1st ascii byte in upper nibble. */ - *destTemp += hex_to_bin(*srcptr++); /* Add 2nd ascii byte to above. */ - destTemp++; - } -} - -/*+++Mark by shiang, not use now, need to remove after confirm */ -/*---Mark by shiang, not use now, need to remove after confirm */ - -/* - ======================================================================== - - Routine Description: - Init timer objects - - Arguments: - pAd Pointer to our adapter - pTimer Timer structure - pTimerFunc Function to execute when timer expired - Repeat Ture for period timer - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPInitTimer(struct rt_rtmp_adapter *pAd, - struct rt_ralink_timer *pTimer, - void *pTimerFunc, void *pData, IN BOOLEAN Repeat) -{ - /* */ - /* Set Valid to TRUE for later used. */ - /* It will crash if we cancel a timer or set a timer */ - /* that we haven't initialize before. */ - /* */ - pTimer->Valid = TRUE; - - pTimer->PeriodicType = Repeat; - pTimer->State = FALSE; - pTimer->cookie = (unsigned long)pData; - -#ifdef RTMP_TIMER_TASK_SUPPORT - pTimer->pAd = pAd; -#endif /* RTMP_TIMER_TASK_SUPPORT // */ - - RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (void *)pTimer); -} - -/* - ======================================================================== - - Routine Description: - Init timer objects - - Arguments: - pTimer Timer structure - Value Timer value in milliseconds - - Return Value: - None - - Note: - To use this routine, must call RTMPInitTimer before. - - ======================================================================== -*/ -void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value) -{ - if (pTimer->Valid) { - pTimer->TimerValue = Value; - pTimer->State = FALSE; - if (pTimer->PeriodicType == TRUE) { - pTimer->Repeat = TRUE; - RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value); - } else { - pTimer->Repeat = FALSE; - RTMP_OS_Add_Timer(&pTimer->TimerObj, Value); - } - } else { - DBGPRINT_ERR("RTMPSetTimer failed, Timer hasn't been initialize!\n"); - } -} - -/* - ======================================================================== - - Routine Description: - Init timer objects - - Arguments: - pTimer Timer structure - Value Timer value in milliseconds - - Return Value: - None - - Note: - To use this routine, must call RTMPInitTimer before. - - ======================================================================== -*/ -void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value) -{ - BOOLEAN Cancel; - - if (pTimer->Valid) { - pTimer->TimerValue = Value; - pTimer->State = FALSE; - if (pTimer->PeriodicType == TRUE) { - RTMPCancelTimer(pTimer, &Cancel); - RTMPSetTimer(pTimer, Value); - } else { - RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value); - } - } else { - DBGPRINT_ERR("RTMPModTimer failed, Timer hasn't been initialize!\n"); - } -} - -/* - ======================================================================== - - Routine Description: - Cancel timer objects - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - 1.) To use this routine, must call RTMPInitTimer before. - 2.) Reset NIC to initial state AS IS system boot up time. - - ======================================================================== -*/ -void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled) -{ - if (pTimer->Valid) { - if (pTimer->State == FALSE) - pTimer->Repeat = FALSE; - - RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled); - - if (*pCancelled == TRUE) - pTimer->State = TRUE; - -#ifdef RTMP_TIMER_TASK_SUPPORT - /* We need to go-through the TimerQ to findout this timer handler and remove it if */ - /* it's still waiting for execution. */ - RtmpTimerQRemove(pTimer->pAd, pTimer); -#endif /* RTMP_TIMER_TASK_SUPPORT // */ - } else { - DBGPRINT_ERR("RTMPCancelTimer failed, Timer hasn't been initialize!\n"); - } -} - -/* - ======================================================================== - - Routine Description: - Set LED Status - - Arguments: - pAd Pointer to our adapter - Status LED Status - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status) -{ - /*unsigned long data; */ - u8 HighByte = 0; - u8 LowByte; - - LowByte = pAd->LedCntl.field.LedMode & 0x7f; - switch (Status) { - case LED_LINK_DOWN: - HighByte = 0x20; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - pAd->LedIndicatorStrength = 0; - break; - case LED_LINK_UP: - if (pAd->CommonCfg.Channel > 14) - HighByte = 0xa0; - else - HighByte = 0x60; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - break; - case LED_RADIO_ON: - HighByte = 0x20; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - break; - case LED_HALT: - LowByte = 0; /* Driver sets MAC register and MAC controls LED */ - case LED_RADIO_OFF: - HighByte = 0; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - break; - case LED_WPS: - HighByte = 0x10; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - break; - case LED_ON_SITE_SURVEY: - HighByte = 0x08; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - break; - case LED_POWER_UP: - HighByte = 0x04; - AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - break; - default: - DBGPRINT(RT_DEBUG_WARN, - ("RTMPSetLED::Unknown Status %d\n", Status)); - break; - } - - /* */ - /* Keep LED status for LED SiteSurvey mode. */ - /* After SiteSurvey, we will set the LED mode to previous status. */ - /* */ - if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP)) - pAd->LedStatus = Status; - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", - pAd->LedCntl.field.LedMode, HighByte, LowByte)); -} - -/* - ======================================================================== - - Routine Description: - Set LED Signal Strength - - Arguments: - pAd Pointer to our adapter - Dbm Signal Strength - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - Can be run on any IRQL level. - - According to Microsoft Zero Config Wireless Signal Strength definition as belows. - <= -90 No Signal - <= -81 Very Low - <= -71 Low - <= -67 Good - <= -57 Very Good - > -57 Excellent - ======================================================================== -*/ -void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm) -{ - u8 nLed = 0; - - if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH) { - if (Dbm <= -90) - nLed = 0; - else if (Dbm <= -81) - nLed = 1; - else if (Dbm <= -71) - nLed = 3; - else if (Dbm <= -67) - nLed = 7; - else if (Dbm <= -57) - nLed = 15; - else - nLed = 31; - - /* */ - /* Update Signal Strength to firmware if changed. */ - /* */ - if (pAd->LedIndicatorStrength != nLed) { - AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, - pAd->LedCntl.field.Polarity); - pAd->LedIndicatorStrength = nLed; - } - } -} - -/* - ======================================================================== - - Routine Description: - Enable RX - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL <= DISPATCH_LEVEL - - Note: - Before Enable RX, make sure you have enabled Interrupt. - ======================================================================== -*/ -void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd) -{ -/* WPDMA_GLO_CFG_STRUC GloCfg; */ -/* unsigned long i = 0; */ - u32 rx_filter_flag; - - DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n")); - - /* Enable Rx DMA. */ - RT28XXDMAEnable(pAd); - - /* enable RX of MAC block */ - if (pAd->OpMode == OPMODE_AP) { - rx_filter_flag = APNORMAL; - - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); /* enable RX of DMA block */ - } else { - if (pAd->CommonCfg.PSPXlink) - rx_filter_flag = PSPXLINK; - else - rx_filter_flag = STANORMAL; /* Station not drop control frame will fail WiFi Certification. */ - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); - } - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); - DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n")); -} - -/*+++Add by shiang, move from os/linux/rt_main_dev.c */ -void CfgInitHook(struct rt_rtmp_adapter *pAd) -{ - pAd->bBroadComHT = TRUE; -} - -int rt28xx_init(struct rt_rtmp_adapter *pAd, - char *pDefaultMac, char *pHostName) -{ - u32 index; - u8 TmpPhy; - int Status; - u32 MacCsr0 = 0; - -#ifdef RTMP_MAC_PCI - { - /* If dirver doesn't wake up firmware here, */ - /* NICLoadFirmware will hang forever when interface is up again. */ - /* RT2860 PCI */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) && - OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - AUTO_WAKEUP_STRUC AutoWakeupCfg; - AsicForceWakeup(pAd, TRUE); - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, - AutoWakeupCfg.word); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - } - } -#endif /* RTMP_MAC_PCI // */ - - /* reset Adapter flags */ - RTMP_CLEAR_FLAGS(pAd); - - /* Init BssTab & ChannelInfo tabbles for auto channel select. */ - - /* Allocate BA Reordering memory */ - ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM); - - /* Make sure MAC gets ready. */ - index = 0; - do { - RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); - pAd->MACVersion = MacCsr0; - - if ((pAd->MACVersion != 0x00) - && (pAd->MACVersion != 0xFFFFFFFF)) - break; - - RTMPusecDelay(10); - } while (index++ < 100); - DBGPRINT(RT_DEBUG_TRACE, - ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); - -#ifdef RTMP_MAC_PCI -#ifdef PCIE_PS_SUPPORT - /*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register at pcie L.1 level */ - if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0); - MacCsr0 |= 0x402; - RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0); - DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0)); - } -#endif /* PCIE_PS_SUPPORT // */ - - /* To fix driver disable/enable hang issue when radio off */ - RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); -#endif /* RTMP_MAC_PCI // */ - - /* Disable DMA */ - RT28XXDMADisable(pAd); - - /* Load 8051 firmware */ - Status = NICLoadFirmware(pAd); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR("NICLoadFirmware failed, Status[=0x%08x]\n", Status); - goto err1; - } - - NICLoadRateSwitchingParams(pAd); - - /* Disable interrupts here which is as soon as possible */ - /* This statement should never be true. We might consider to remove it later */ -#ifdef RTMP_MAC_PCI - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { - RTMP_ASIC_INTERRUPT_DISABLE(pAd); - } -#endif /* RTMP_MAC_PCI // */ - - Status = RTMPAllocTxRxRingMemory(pAd); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status); - goto err1; - } - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); - - /* initialize MLME */ - /* */ - - Status = RtmpMgmtTaskInit(pAd); - if (Status != NDIS_STATUS_SUCCESS) - goto err2; - - Status = MlmeInit(pAd); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR("MlmeInit failed, Status[=0x%08x]\n", Status); - goto err2; - } - /* Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default */ - /* */ - UserCfgInit(pAd); - Status = RtmpNetTaskInit(pAd); - if (Status != NDIS_STATUS_SUCCESS) - goto err3; - -/* COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); */ -/* pAd->bForcePrintTX = TRUE; */ - - CfgInitHook(pAd); - - NdisAllocateSpinLock(&pAd->MacTabLock); - - MeasureReqTabInit(pAd); - TpcReqTabInit(pAd); - - /* */ - /* Init the hardware, we need to init asic before read registry, otherwise mac register will be reset */ - /* */ - Status = NICInitializeAdapter(pAd, TRUE); - if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR("NICInitializeAdapter failed, Status[=0x%08x]\n", Status); - if (Status != NDIS_STATUS_SUCCESS) - goto err3; - } - - DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); - -#ifdef RTMP_MAC_USB - pAd->CommonCfg.bMultipleIRP = FALSE; - - if (pAd->CommonCfg.bMultipleIRP) - pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE; - else - pAd->CommonCfg.NumOfBulkInIRP = 1; -#endif /* RTMP_MAC_USB // */ - - /*Init Ba Capability parameters. */ -/* RT28XX_BA_INIT(pAd); */ - pAd->CommonCfg.DesiredHtPhy.MpduDensity = - (u8)pAd->CommonCfg.BACapability.field.MpduDensity; - pAd->CommonCfg.DesiredHtPhy.AmsduEnable = - (u16)pAd->CommonCfg.BACapability.field.AmsduEnable; - pAd->CommonCfg.DesiredHtPhy.AmsduSize = - (u16)pAd->CommonCfg.BACapability.field.AmsduSize; - pAd->CommonCfg.DesiredHtPhy.MimoPs = - (u16)pAd->CommonCfg.BACapability.field.MMPSmode; - /* UPdata to HT IE */ - pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = - (u16)pAd->CommonCfg.BACapability.field.MMPSmode; - pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = - (u16)pAd->CommonCfg.BACapability.field.AmsduSize; - pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = - (u8)pAd->CommonCfg.BACapability.field.MpduDensity; - - /* after reading Registry, we now know if in AP mode or STA mode */ - - /* Load 8051 firmware; crash when FW image not existent */ - /* Status = NICLoadFirmware(pAd); */ - /* if (Status != NDIS_STATUS_SUCCESS) */ - /* break; */ - - DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); - - /* We should read EEPROM for all cases. rt2860b */ - NICReadEEPROMParameters(pAd, (u8 *)pDefaultMac); - - DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); - - NICInitAsicFromEEPROM(pAd); /*rt2860b */ - - /* Set PHY to appropriate mode */ - TmpPhy = pAd->CommonCfg.PhyMode; - pAd->CommonCfg.PhyMode = 0xff; - RTMPSetPhyMode(pAd, TmpPhy); - SetCommonHT(pAd); - - /* No valid channels. */ - if (pAd->ChannelListNum == 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); - goto err4; - } - - DBGPRINT(RT_DEBUG_OFF, - ("MCS Set = %02x %02x %02x %02x %02x\n", - pAd->CommonCfg.HtCapability.MCSSet[0], - pAd->CommonCfg.HtCapability.MCSSet[1], - pAd->CommonCfg.HtCapability.MCSSet[2], - pAd->CommonCfg.HtCapability.MCSSet[3], - pAd->CommonCfg.HtCapability.MCSSet[4])); - -#ifdef RTMP_RF_RW_SUPPORT - /*Init RT30xx RFRegisters after read RFIC type from EEPROM */ - NICInitRFRegisters(pAd); -#endif /* RTMP_RF_RW_SUPPORT // */ - -/* APInitialize(pAd); */ - - /* */ - /* Initialize RF register to default value */ - /* */ - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - - /* 8051 firmware require the signal during booting time. */ - /*2008/11/28:KH marked the following codes to patch Frequency offset bug */ - /*AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); */ - - if (pAd && (Status != NDIS_STATUS_SUCCESS)) { - /* */ - /* Undo everything if it failed */ - /* */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { -/* NdisMDeregisterInterrupt(&pAd->Interrupt); */ - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); - } -/* RTMPFreeAdapter(pAd); // we will free it in disconnect() */ - } else if (pAd) { - /* Microsoft HCT require driver send a disconnect event after driver initialization. */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); -/* pAd->IndicateMediaState = NdisMediaStateDisconnected; */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); - - DBGPRINT(RT_DEBUG_TRACE, - ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); - -#ifdef RTMP_MAC_USB - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); - - /* */ - /* Support multiple BulkIn IRP, */ - /* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. */ - /* */ - for (index = 0; index < pAd->CommonCfg.NumOfBulkInIRP; index++) { - RTUSBBulkReceive(pAd); - DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n")); - } -#endif /* RTMP_MAC_USB // */ - } /* end of else */ - - /* Set up the Mac address */ - RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]); - - DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status)); - - return TRUE; - -err4: -err3: - MlmeHalt(pAd); -err2: - RTMPFreeTxRxRingMemory(pAd); -err1: - - os_free_mem(pAd, pAd->mpdu_blk_pool.mem); /* free BA pool */ - - /* shall not set priv to NULL here because the priv didn't been free yet. */ - /*net_dev->ml_priv = 0; */ -#ifdef ST -err0: -#endif /* ST // */ - - DBGPRINT(RT_DEBUG_ERROR, ("rt28xx Initialized fail!\n")); - return FALSE; -} - -/*---Add by shiang, move from os/linux/rt_main_dev.c */ - -static int RtmpChipOpsRegister(struct rt_rtmp_adapter *pAd, int infType) -{ - struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps; - int status; - - memset(pChipOps, 0, sizeof(struct rt_rtmp_chip_op)); - - /* set eeprom related hook functions */ - status = RtmpChipOpsEepromHook(pAd, infType); - - /* set mcu related hook functions */ - switch (infType) { -#ifdef RTMP_PCI_SUPPORT - case RTMP_DEV_INF_PCI: - pChipOps->loadFirmware = RtmpAsicLoadFirmware; - pChipOps->eraseFirmware = RtmpAsicEraseFirmware; - pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu; - break; -#endif /* RTMP_PCI_SUPPORT // */ -#ifdef RTMP_USB_SUPPORT - case RTMP_DEV_INF_USB: - pChipOps->loadFirmware = RtmpAsicLoadFirmware; - pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu; - break; -#endif /* RTMP_USB_SUPPORT // */ - default: - break; - } - - return status; -} - -int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType) -{ - /*void *handle; */ - - /* Assign the interface type. We need use it when do register/EEPROM access. */ - pAd->infType = infType; - - pAd->OpMode = OPMODE_STA; - DBGPRINT(RT_DEBUG_TRACE, - ("STA Driver version-%s\n", STA_DRIVER_VERSION)); - -#ifdef RTMP_MAC_USB - sema_init(&(pAd->UsbVendorReq_semaphore), 1); - os_alloc_mem(pAd, (u8 **) & pAd->UsbVendorReqBuf, - MAX_PARAM_BUFFER_SIZE - 1); - if (pAd->UsbVendorReqBuf == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("Allocate vendor request temp buffer failed!\n")); - return FALSE; - } -#endif /* RTMP_MAC_USB // */ - - RtmpChipOpsRegister(pAd, infType); - - return 0; -} - -BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd) -{ - - RTMPFreeAdapter(pAd); - - return TRUE; -} - -/* not yet support MBSS */ -struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID) -{ - struct net_device *dev_p = NULL; - - { - dev_p = pAd->net_dev; - } - - ASSERT(dev_p); - return dev_p; /* return one of MBSS */ -} diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c deleted file mode 100644 index 80fa4160ed62..000000000000 --- a/drivers/staging/rt2860/common/rtmp_mcu.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_mcu.c - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "../rt_config.h" - -#include -#include - -#ifdef RTMP_MAC_USB - -#define FIRMWAREIMAGE_LENGTH 0x1000 - -#define FIRMWARE_2870_MIN_VERSION 12 -#define FIRMWARE_2870_FILENAME "rt2870.bin" -MODULE_FIRMWARE(FIRMWARE_2870_FILENAME); - -#define FIRMWARE_3070_MIN_VERSION 17 -#define FIRMWARE_3070_FILENAME "rt3070.bin" -MODULE_FIRMWARE(FIRMWARE_3070_FILENAME); - -#define FIRMWARE_3071_MIN_VERSION 17 -#define FIRMWARE_3071_FILENAME "rt3071.bin" /* for RT3071/RT3072 */ -MODULE_FIRMWARE(FIRMWARE_3071_FILENAME); - -#else /* RTMP_MAC_PCI */ - -#define FIRMWAREIMAGE_LENGTH 0x2000 - -#define FIRMWARE_2860_MIN_VERSION 11 -#define FIRMWARE_2860_FILENAME "rt2860.bin" -MODULE_FIRMWARE(FIRMWARE_2860_FILENAME); - -#define FIRMWARE_3090_MIN_VERSION 19 -#define FIRMWARE_3090_FILENAME "rt3090.bin" /* for RT3090/RT3390 */ -MODULE_FIRMWARE(FIRMWARE_3090_FILENAME); - -#endif - -/* - ======================================================================== - - Routine Description: - erase 8051 firmware image in MAC ASIC - - Arguments: - Adapter Pointer to our adapter - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd) -{ - unsigned long i; - - for (i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4) - RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0); - - return 0; -} - -static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter) -{ - const char *name; - const struct firmware *fw = NULL; - u8 min_version; - struct device *dev; - int err; - - if (adapter->firmware) - return adapter->firmware; - -#ifdef RTMP_MAC_USB - if (IS_RT3071(adapter)) { - name = FIRMWARE_3071_FILENAME; - min_version = FIRMWARE_3071_MIN_VERSION; - } else if (IS_RT3070(adapter)) { - name = FIRMWARE_3070_FILENAME; - min_version = FIRMWARE_3070_MIN_VERSION; - } else { - name = FIRMWARE_2870_FILENAME; - min_version = FIRMWARE_2870_MIN_VERSION; - } - dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev; -#else /* RTMP_MAC_PCI */ - if (IS_RT3090(adapter) || IS_RT3390(adapter)) { - name = FIRMWARE_3090_FILENAME; - min_version = FIRMWARE_3090_MIN_VERSION; - } else { - name = FIRMWARE_2860_FILENAME; - min_version = FIRMWARE_2860_MIN_VERSION; - } - dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev; -#endif - - err = request_firmware(&fw, name, dev); - if (err) { - dev_err(dev, "firmware file %s request failed (%d)\n", - name, err); - return NULL; - } - - if (fw->size < FIRMWAREIMAGE_LENGTH) { - dev_err(dev, "firmware file %s size is invalid\n", name); - goto invalid; - } - - /* is it new enough? */ - adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3]; - if (adapter->FirmwareVersion < min_version) { - dev_err(dev, - "firmware file %s is too old;" - " driver requires v%d or later\n", - name, min_version); - goto invalid; - } - - /* is the internal CRC correct? */ - if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) != - (fw->data[FIRMWAREIMAGE_LENGTH - 2] | - (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) { - dev_err(dev, "firmware file %s failed internal CRC\n", name); - goto invalid; - } - - adapter->firmware = fw; - return fw; - -invalid: - release_firmware(fw); - return NULL; -} - -/* - ======================================================================== - - Routine Description: - Load 8051 firmware file into MAC ASIC - - Arguments: - Adapter Pointer to our adapter - - Return Value: - NDIS_STATUS_SUCCESS firmware image load ok - NDIS_STATUS_FAILURE image not found - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd) -{ - const struct firmware *fw; - int Status = NDIS_STATUS_SUCCESS; - unsigned long Index; - u32 MacReg = 0; - - fw = rtmp_get_firmware(pAd); - if (!fw) - return NDIS_STATUS_FAILURE; - - RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH); - - /* check if MCU is ready */ - Index = 0; - do { - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg); - - if (MacReg & 0x80) - break; - - RTMPusecDelay(1000); - } while (Index++ < 1000); - - if (Index > 1000) { - DBGPRINT(RT_DEBUG_ERROR, - ("NICLoadFirmware: MCU is not ready\n")); - Status = NDIS_STATUS_FAILURE; - } - - DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status)); - - return Status; -} - -int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, - u8 Command, - u8 Token, u8 Arg0, u8 Arg1) -{ - HOST_CMD_CSR_STRUC H2MCmd; - H2M_MAILBOX_STRUC H2MMailbox; - unsigned long i = 0; - -#ifdef PCIE_PS_SUPPORT - /* 3090F power solution 3 has hw limitation that needs to ban all mcu command */ - /* when firmware is in radio state. For other chip doesn't have this limitation. */ - if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) { - RTMP_SEM_LOCK(&pAd->McuCmdLock); - if ((pAd->brt30xxBanMcuCmd == TRUE) - && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) { - RTMP_SEM_UNLOCK(&pAd->McuCmdLock); - DBGPRINT(RT_DEBUG_TRACE, - (" Ban Mcu Cmd %x in sleep mode\n", Command)); - return FALSE; - } else if ((Command == SLEEP_MCU_CMD) - || (Command == RFOFF_MCU_CMD)) { - pAd->brt30xxBanMcuCmd = TRUE; - } else if (Command != WAKE_MCU_CMD) { - pAd->brt30xxBanMcuCmd = FALSE; - } - - RTMP_SEM_UNLOCK(&pAd->McuCmdLock); - - } - if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) - && (Command == WAKE_MCU_CMD)) { - - do { - RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR, - &H2MMailbox.word); - if (H2MMailbox.field.Owner == 0) - break; - - RTMPusecDelay(2); - DBGPRINT(RT_DEBUG_INFO, - ("AsicSendCommanToMcu::Mail box is busy\n")); - } while (i++ < 100); - - if (i > 100) { - DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n"); - return FALSE; - } - - H2MMailbox.field.Owner = 1; /* pass ownership to MCU */ - H2MMailbox.field.CmdToken = Token; - H2MMailbox.field.HighByte = Arg1; - H2MMailbox.field.LowByte = Arg0; - RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); - - H2MCmd.word = 0; - H2MCmd.field.HostCommand = Command; - RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); - - } else -#endif /* PCIE_PS_SUPPORT // */ - { - do { - RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); - if (H2MMailbox.field.Owner == 0) - break; - - RTMPusecDelay(2); - } while (i++ < 100); - - if (i > 100) { -#ifdef RTMP_MAC_PCI -#endif /* RTMP_MAC_PCI // */ - { - DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n"); - } - return FALSE; - } -#ifdef RTMP_MAC_PCI -#endif /* RTMP_MAC_PCI // */ - - H2MMailbox.field.Owner = 1; /* pass ownership to MCU */ - H2MMailbox.field.CmdToken = Token; - H2MMailbox.field.HighByte = Arg1; - H2MMailbox.field.LowByte = Arg0; - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); - - H2MCmd.word = 0; - H2MCmd.field.HostCommand = Command; - RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); - - if (Command != 0x80) { - } - } -#ifdef PCIE_PS_SUPPORT - /* 3090 MCU Wakeup command needs more time to be stable. */ - /* Before stable, don't issue other MCU command to prevent from firmware error. */ - if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) - && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3) - && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) - && (Command == WAKE_MCU_CMD)) { - RTMPusecDelay(2000); - /*Put this is after RF programming. */ - /*NdisAcquireSpinLock(&pAd->McuCmdLock); */ - /*pAd->brt30xxBanMcuCmd = FALSE; */ - /*NdisReleaseSpinLock(&pAd->McuCmdLock); */ - } -#endif /* PCIE_PS_SUPPORT // */ - - return TRUE; -} diff --git a/drivers/staging/rt2860/common/rtmp_timer.c b/drivers/staging/rt2860/common/rtmp_timer.c deleted file mode 100644 index ab520909490f..000000000000 --- a/drivers/staging/rt2860/common/rtmp_timer.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_timer.c - - Abstract: - task for timer handling - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Shiang Tu 08-28-2008 init version - -*/ - -#include "../rt_config.h" - -BUILD_TIMER_FUNCTION(MlmePeriodicExec); -/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec); */ -BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout); -BUILD_TIMER_FUNCTION(APSDPeriodicExec); -BUILD_TIMER_FUNCTION(AsicRfTuningExec); -#ifdef RTMP_MAC_USB -BUILD_TIMER_FUNCTION(BeaconUpdateExec); -#endif /* RTMP_MAC_USB // */ - -BUILD_TIMER_FUNCTION(BeaconTimeout); -BUILD_TIMER_FUNCTION(ScanTimeout); -BUILD_TIMER_FUNCTION(AuthTimeout); -BUILD_TIMER_FUNCTION(AssocTimeout); -BUILD_TIMER_FUNCTION(ReassocTimeout); -BUILD_TIMER_FUNCTION(DisassocTimeout); -BUILD_TIMER_FUNCTION(LinkDownExec); -BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); -BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); -#ifdef RTMP_MAC_PCI -BUILD_TIMER_FUNCTION(PsPollWakeExec); -BUILD_TIMER_FUNCTION(RadioOnExec); -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); -#endif /* RTMP_MAC_USB // */ - -#if defined(AP_LED) || defined(STA_LED) -extern void LedCtrlMain(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); -BUILD_TIMER_FUNCTION(LedCtrlMain); -#endif - -#ifdef RTMP_TIMER_TASK_SUPPORT -static void RtmpTimerQHandle(struct rt_rtmp_adapter *pAd) -{ -#ifndef KTHREAD_SUPPORT - int status; -#endif - struct rt_ralink_timer *pTimer; - struct rt_rtmp_timer_task_entry *pEntry; - unsigned long irqFlag; - struct rt_rtmp_os_task *pTask; - - pTask = &pAd->timerTask; - while (!pTask->task_killed) { - pTimer = NULL; - -#ifdef KTHREAD_SUPPORT - RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); -#else - RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); -#endif - - if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED) - break; - - /* event happened. */ - while (pAd->TimerQ.pQHead) { - RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag); - pEntry = pAd->TimerQ.pQHead; - if (pEntry) { - pTimer = pEntry->pRaTimer; - - /* update pQHead */ - pAd->TimerQ.pQHead = pEntry->pNext; - if (pEntry == pAd->TimerQ.pQTail) - pAd->TimerQ.pQTail = NULL; - - /* return this queue entry to timerQFreeList. */ - pEntry->pNext = pAd->TimerQ.pQPollFreeList; - pAd->TimerQ.pQPollFreeList = pEntry; - } - RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag); - - if (pTimer) { - if ((pTimer->handle != NULL) - && (!pAd->PM_FlgSuspend)) - pTimer->handle(NULL, - (void *)pTimer->cookie, - NULL, pTimer); - if ((pTimer->Repeat) - && (pTimer->State == FALSE)) - RTMP_OS_Add_Timer(&pTimer->TimerObj, - pTimer->TimerValue); - } - } - -#ifndef KTHREAD_SUPPORT - if (status != 0) { - pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - break; - } -#endif - } -} - -int RtmpTimerQThread(IN void *Context) -{ - struct rt_rtmp_os_task *pTask; - struct rt_rtmp_adapter *pAd; - - pTask = Context; - pAd = pTask->priv; - - RtmpOSTaskCustomize(pTask); - - RtmpTimerQHandle(pAd); - - DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __func__)); -#ifndef KTHREAD_SUPPORT - pTask->taskPID = THREAD_PID_INIT_VALUE; -#endif - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - RtmpOSTaskNotifyToExit(pTask); - - return 0; - -} - -struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd, - struct rt_ralink_timer *pTimer) -{ - struct rt_rtmp_timer_task_entry *pQNode = NULL, *pQTail; - unsigned long irqFlags; - struct rt_rtmp_os_task *pTask = &pAd->timerTask; - - RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); - if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) { - if (pAd->TimerQ.pQPollFreeList) { - pQNode = pAd->TimerQ.pQPollFreeList; - pAd->TimerQ.pQPollFreeList = pQNode->pNext; - - pQNode->pRaTimer = pTimer; - pQNode->pNext = NULL; - - pQTail = pAd->TimerQ.pQTail; - if (pAd->TimerQ.pQTail != NULL) - pQTail->pNext = pQNode; - pAd->TimerQ.pQTail = pQNode; - if (pAd->TimerQ.pQHead == NULL) - pAd->TimerQ.pQHead = pQNode; - } - } - RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); - - if (pQNode) { -#ifdef KTHREAD_SUPPORT - WAKE_UP(pTask); -#else - RTMP_SEM_EVENT_UP(&pTask->taskSema); -#endif - } - - return pQNode; -} - -BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd, struct rt_ralink_timer *pTimer) -{ - struct rt_rtmp_timer_task_entry *pNode, *pPrev = NULL; - unsigned long irqFlags; - - RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); - if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) { - pNode = pAd->TimerQ.pQHead; - while (pNode) { - if (pNode->pRaTimer == pTimer) - break; - pPrev = pNode; - pNode = pNode->pNext; - } - - /* Now move it to freeList queue. */ - if (pNode) { - if (pNode == pAd->TimerQ.pQHead) - pAd->TimerQ.pQHead = pNode->pNext; - if (pNode == pAd->TimerQ.pQTail) - pAd->TimerQ.pQTail = pPrev; - if (pPrev != NULL) - pPrev->pNext = pNode->pNext; - - /* return this queue entry to timerQFreeList. */ - pNode->pNext = pAd->TimerQ.pQPollFreeList; - pAd->TimerQ.pQPollFreeList = pNode; - } - } - RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); - - return TRUE; -} - -void RtmpTimerQExit(struct rt_rtmp_adapter *pAd) -{ - struct rt_rtmp_timer_task_entry *pTimerQ; - unsigned long irqFlags; - - RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); - while (pAd->TimerQ.pQHead) { - pTimerQ = pAd->TimerQ.pQHead; - pAd->TimerQ.pQHead = pTimerQ->pNext; - /* remove the timeQ */ - } - pAd->TimerQ.pQPollFreeList = NULL; - os_free_mem(pAd, pAd->TimerQ.pTimerQPoll); - pAd->TimerQ.pQTail = NULL; - pAd->TimerQ.pQHead = NULL; -#ifndef KTHREAD_SUPPORT - pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; -#endif - RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); - -} - -void RtmpTimerQInit(struct rt_rtmp_adapter *pAd) -{ - int i; - struct rt_rtmp_timer_task_entry *pQNode, *pEntry; - unsigned long irqFlags; - - NdisAllocateSpinLock(&pAd->TimerQLock); - - NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ)); - - os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, - sizeof(struct rt_rtmp_timer_task_entry) * TIMER_QUEUE_SIZE_MAX); - if (pAd->TimerQ.pTimerQPoll) { - pEntry = NULL; - pQNode = (struct rt_rtmp_timer_task_entry *)pAd->TimerQ.pTimerQPoll; - NdisZeroMemory(pAd->TimerQ.pTimerQPoll, - sizeof(struct rt_rtmp_timer_task_entry) * - TIMER_QUEUE_SIZE_MAX); - - RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); - for (i = 0; i < TIMER_QUEUE_SIZE_MAX; i++) { - pQNode->pNext = pEntry; - pEntry = pQNode; - pQNode++; - } - pAd->TimerQ.pQPollFreeList = pEntry; - pAd->TimerQ.pQHead = NULL; - pAd->TimerQ.pQTail = NULL; - pAd->TimerQ.status = RTMP_TASK_STAT_INITED; - RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); - } -} -#endif /* RTMP_TIMER_TASK_SUPPORT // */ diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c deleted file mode 100644 index ceb622df12d7..000000000000 --- a/drivers/staging/rt2860/common/spectrum.c +++ /dev/null @@ -1,2205 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - action.c - - Abstract: - Handle association related requests either from WSTA or from local MLME - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - Fonchi Wu 2008 created for 802.11h - */ - -#include "../rt_config.h" -#include "action.h" - -/* The regulatory information in the USA (US) */ -struct rt_dot11_regulatory_information USARegulatoryInfo[] = { -/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ - {0, {0, 0, {0} - } - } - , /* Invlid entry */ - {1, {4, 16, {36, 40, 44, 48} - } - } - , - {2, {4, 23, {52, 56, 60, 64} - } - } - , - {3, {4, 29, {149, 153, 157, 161} - } - } - , - {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} - } - } - , - {5, {5, 30, {149, 153, 157, 161, 165} - } - } - , - {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - } - } - , - {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - } - } - , - {8, {5, 17, {11, 13, 15, 17, 19} - } - } - , - {9, {5, 30, {11, 13, 15, 17, 19} - } - } - , - {10, {2, 20, {21, 25} - } - } - , - {11, {2, 33, {21, 25} - } - } - , - {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} - } - } -}; - -#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information)) - -/* The regulatory information in Europe */ -struct rt_dot11_regulatory_information EuropeRegulatoryInfo[] = { -/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ - {0, {0, 0, {0} - } - } - , /* Invalid entry */ - {1, {4, 20, {36, 40, 44, 48} - } - } - , - {2, {4, 20, {52, 56, 60, 64} - } - } - , - {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} - } - } - , - {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} - } - } -}; - -#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information)) - -/* The regulatory information in Japan */ -struct rt_dot11_regulatory_information JapanRegulatoryInfo[] = { -/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ - {0, {0, 0, {0} - } - } - , /* Invalid entry */ - {1, {4, 22, {34, 38, 42, 46} - } - } - , - {2, {3, 24, {8, 12, 16} - } - } - , - {3, {3, 24, {8, 12, 16} - } - } - , - {4, {3, 24, {8, 12, 16} - } - } - , - {5, {3, 24, {8, 12, 16} - } - } - , - {6, {3, 22, {8, 12, 16} - } - } - , - {7, {4, 24, {184, 188, 192, 196} - } - } - , - {8, {4, 24, {184, 188, 192, 196} - } - } - , - {9, {4, 24, {184, 188, 192, 196} - } - } - , - {10, {4, 24, {184, 188, 192, 196} - } - } - , - {11, {4, 22, {184, 188, 192, 196} - } - } - , - {12, {4, 24, {7, 8, 9, 11} - } - } - , - {13, {4, 24, {7, 8, 9, 11} - } - } - , - {14, {4, 24, {7, 8, 9, 11} - } - } - , - {15, {4, 24, {7, 8, 9, 11} - } - } - , - {16, {6, 24, {183, 184, 185, 187, 188, 189} - } - } - , - {17, {6, 24, {183, 184, 185, 187, 188, 189} - } - } - , - {18, {6, 24, {183, 184, 185, 187, 188, 189} - } - } - , - {19, {6, 24, {183, 184, 185, 187, 188, 189} - } - } - , - {20, {6, 17, {183, 184, 185, 187, 188, 189} - } - } - , - {21, {6, 24, {6, 7, 8, 9, 10, 11} - } - } - , - {22, {6, 24, {6, 7, 8, 9, 10, 11} - } - } - , - {23, {6, 24, {6, 7, 8, 9, 10, 11} - } - } - , - {24, {6, 24, {6, 7, 8, 9, 10, 11} - } - } - , - {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189} - } - } - , - {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189} - } - } - , - {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189} - } - } - , - {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189} - } - } - , - {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189} - } - } - , - {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} - } - } - , - {31, {1, 23, {14} - } - } - , - {32, {4, 22, {52, 56, 60, 64} - } - } -}; - -#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information)) - -char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode) -{ - struct tx_pwr_cfg { - u8 Mode; - u8 MCS; - u16 req; - u8 shift; - u32 BitMask; - }; - - u32 Value; - int Idx; - u8 PhyMode; - char CurTxPwr; - u8 TxPwrRef = 0; - char DaltaPwr; - unsigned long TxPwr[5]; - - struct tx_pwr_cfg TxPwrCfg[] = { - {MODE_CCK, 0, 0, 4, 0x000000f0}, - {MODE_CCK, 1, 0, 0, 0x0000000f}, - {MODE_CCK, 2, 0, 12, 0x0000f000}, - {MODE_CCK, 3, 0, 8, 0x00000f00}, - - {MODE_OFDM, 0, 0, 20, 0x00f00000}, - {MODE_OFDM, 1, 0, 16, 0x000f0000}, - {MODE_OFDM, 2, 0, 28, 0xf0000000}, - {MODE_OFDM, 3, 0, 24, 0x0f000000}, - {MODE_OFDM, 4, 1, 4, 0x000000f0}, - {MODE_OFDM, 5, 1, 0, 0x0000000f}, - {MODE_OFDM, 6, 1, 12, 0x0000f000}, - {MODE_OFDM, 7, 1, 8, 0x00000f00} - , {MODE_HTMIX, 0, 1, 20, 0x00f00000}, - {MODE_HTMIX, 1, 1, 16, 0x000f0000}, - {MODE_HTMIX, 2, 1, 28, 0xf0000000}, - {MODE_HTMIX, 3, 1, 24, 0x0f000000}, - {MODE_HTMIX, 4, 2, 4, 0x000000f0}, - {MODE_HTMIX, 5, 2, 0, 0x0000000f}, - {MODE_HTMIX, 6, 2, 12, 0x0000f000}, - {MODE_HTMIX, 7, 2, 8, 0x00000f00}, - {MODE_HTMIX, 8, 2, 20, 0x00f00000}, - {MODE_HTMIX, 9, 2, 16, 0x000f0000}, - {MODE_HTMIX, 10, 2, 28, 0xf0000000}, - {MODE_HTMIX, 11, 2, 24, 0x0f000000}, - {MODE_HTMIX, 12, 3, 4, 0x000000f0}, - {MODE_HTMIX, 13, 3, 0, 0x0000000f}, - {MODE_HTMIX, 14, 3, 12, 0x0000f000}, - {MODE_HTMIX, 15, 3, 8, 0x00000f00} - }; -#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(struct tx_pwr_cfg)) - - CurTxPwr = 19; - - /* check Tx Power setting from UI. */ - if (pAd->CommonCfg.TxPowerPercentage > 90) ; - else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */ - CurTxPwr -= 1; - else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */ - CurTxPwr -= 3; - else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */ - CurTxPwr -= 6; - else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */ - CurTxPwr -= 9; - else /* reduce Pwr for 12 dB. */ - CurTxPwr -= 12; - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) { - if (pAd->CommonCfg.CentralChannel > 14) { - TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; - TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; - TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; - TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; - TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; - } else { - TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; - TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; - TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; - TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; - TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; - } - } else { - if (pAd->CommonCfg.Channel > 14) { - TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; - TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; - TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; - TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; - TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; - } else { - TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; - TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; - TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; - TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; - TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; - } - } - - switch (HTTxMode.field.MODE) { - case MODE_CCK: - case MODE_OFDM: - Value = TxPwr[1]; - TxPwrRef = (Value & 0x00000f00) >> 8; - - break; - - case MODE_HTMIX: - case MODE_HTGREENFIELD: - if (pAd->CommonCfg.TxStream == 1) { - Value = TxPwr[2]; - TxPwrRef = (Value & 0x00000f00) >> 8; - } else if (pAd->CommonCfg.TxStream == 2) { - Value = TxPwr[3]; - TxPwrRef = (Value & 0x00000f00) >> 8; - } - break; - } - - PhyMode = (HTTxMode.field.MODE == MODE_HTGREENFIELD) - ? MODE_HTMIX : HTTxMode.field.MODE; - - for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) { - if ((TxPwrCfg[Idx].Mode == PhyMode) - && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) { - Value = TxPwr[TxPwrCfg[Idx].req]; - DaltaPwr = - TxPwrRef - (char)((Value & TxPwrCfg[Idx].BitMask) - >> TxPwrCfg[Idx].shift); - CurTxPwr -= DaltaPwr; - break; - } - } - - return CurTxPwr; -} - -void MeasureReqTabInit(struct rt_rtmp_adapter *pAd) -{ - NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock); - - pAd->CommonCfg.pMeasureReqTab = - kmalloc(sizeof(struct rt_measure_req_tab), GFP_ATOMIC); - if (pAd->CommonCfg.pMeasureReqTab) - NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, - sizeof(struct rt_measure_req_tab)); - else - DBGPRINT(RT_DEBUG_ERROR, - ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", - __func__)); - - return; -} - -void MeasureReqTabExit(struct rt_rtmp_adapter *pAd) -{ - NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock); - - kfree(pAd->CommonCfg.pMeasureReqTab); - pAd->CommonCfg.pMeasureReqTab = NULL; - - return; -} - -struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken) -{ - u32 HashIdx; - struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab; - struct rt_measure_req_entry *pEntry = NULL; - struct rt_measure_req_entry *pPrevEntry = NULL; - - if (pTab == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pMeasureReqTab doesn't exist.\n", __func__)); - return NULL; - } - - RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); - - HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); - pEntry = pTab->Hash[HashIdx]; - - while (pEntry) { - if (pEntry->DialogToken == DialogToken) - break; - else { - pPrevEntry = pEntry; - pEntry = pEntry->pNext; - } - } - - RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); - - return pEntry; -} - -struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken) -{ - int i; - unsigned long HashIdx; - struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab; - struct rt_measure_req_entry *pEntry = NULL, *pCurrEntry; - unsigned long Now; - - if (pTab == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pMeasureReqTab doesn't exist.\n", __func__)); - return NULL; - } - - pEntry = MeasureReqLookUp(pAd, DialogToken); - if (pEntry == NULL) { - RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); - for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) { - NdisGetSystemUpTime(&Now); - pEntry = &pTab->Content[i]; - - if ((pEntry->Valid == TRUE) - && RTMP_TIME_AFTER((unsigned long)Now, - (unsigned long)(pEntry-> - lastTime + - MQ_REQ_AGE_OUT))) - { - struct rt_measure_req_entry *pPrevEntry = NULL; - unsigned long HashIdx = - MQ_DIALOGTOKEN_HASH_INDEX(pEntry-> - DialogToken); - struct rt_measure_req_entry *pProbeEntry = - pTab->Hash[HashIdx]; - - /* update Hash list */ - do { - if (pProbeEntry == pEntry) { - if (pPrevEntry == NULL) { - pTab->Hash[HashIdx] = - pEntry->pNext; - } else { - pPrevEntry->pNext = - pEntry->pNext; - } - break; - } - - pPrevEntry = pProbeEntry; - pProbeEntry = pProbeEntry->pNext; - } while (pProbeEntry); - - NdisZeroMemory(pEntry, - sizeof(struct rt_measure_req_entry)); - pTab->Size--; - - break; - } - - if (pEntry->Valid == FALSE) - break; - } - - if (i < MAX_MEASURE_REQ_TAB_SIZE) { - NdisGetSystemUpTime(&Now); - pEntry->lastTime = Now; - pEntry->Valid = TRUE; - pEntry->DialogToken = DialogToken; - pTab->Size++; - } else { - pEntry = NULL; - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pMeasureReqTab tab full.\n", __func__)); - } - - /* add this Neighbor entry into HASH table */ - if (pEntry) { - HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken); - if (pTab->Hash[HashIdx] == NULL) { - pTab->Hash[HashIdx] = pEntry; - } else { - pCurrEntry = pTab->Hash[HashIdx]; - while (pCurrEntry->pNext != NULL) - pCurrEntry = pCurrEntry->pNext; - pCurrEntry->pNext = pEntry; - } - } - - RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); - } - - return pEntry; -} - -void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken) -{ - struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab; - struct rt_measure_req_entry *pEntry = NULL; - - if (pTab == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pMeasureReqTab doesn't exist.\n", __func__)); - return; - } - /* if empty, return */ - if (pTab->Size == 0) { - DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n")); - return; - } - - pEntry = MeasureReqLookUp(pAd, DialogToken); - if (pEntry != NULL) { - struct rt_measure_req_entry *pPrevEntry = NULL; - unsigned long HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); - struct rt_measure_req_entry *pProbeEntry = pTab->Hash[HashIdx]; - - RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock); - /* update Hash list */ - do { - if (pProbeEntry == pEntry) { - if (pPrevEntry == NULL) { - pTab->Hash[HashIdx] = pEntry->pNext; - } else { - pPrevEntry->pNext = pEntry->pNext; - } - break; - } - - pPrevEntry = pProbeEntry; - pProbeEntry = pProbeEntry->pNext; - } while (pProbeEntry); - - NdisZeroMemory(pEntry, sizeof(struct rt_measure_req_entry)); - pTab->Size--; - - RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock); - } - - return; -} - -void TpcReqTabInit(struct rt_rtmp_adapter *pAd) -{ - NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock); - - pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(struct rt_tpc_req_tab), GFP_ATOMIC); - if (pAd->CommonCfg.pTpcReqTab) - NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(struct rt_tpc_req_tab)); - else - DBGPRINT(RT_DEBUG_ERROR, - ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", - __func__)); - - return; -} - -void TpcReqTabExit(struct rt_rtmp_adapter *pAd) -{ - NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock); - - kfree(pAd->CommonCfg.pTpcReqTab); - pAd->CommonCfg.pTpcReqTab = NULL; - - return; -} - -static struct rt_tpc_req_entry *TpcReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken) -{ - u32 HashIdx; - struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab; - struct rt_tpc_req_entry *pEntry = NULL; - struct rt_tpc_req_entry *pPrevEntry = NULL; - - if (pTab == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pTpcReqTab doesn't exist.\n", __func__)); - return NULL; - } - - RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); - - HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); - pEntry = pTab->Hash[HashIdx]; - - while (pEntry) { - if (pEntry->DialogToken == DialogToken) - break; - else { - pPrevEntry = pEntry; - pEntry = pEntry->pNext; - } - } - - RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); - - return pEntry; -} - -static struct rt_tpc_req_entry *TpcReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken) -{ - int i; - unsigned long HashIdx; - struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab; - struct rt_tpc_req_entry *pEntry = NULL, *pCurrEntry; - unsigned long Now; - - if (pTab == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pTpcReqTab doesn't exist.\n", __func__)); - return NULL; - } - - pEntry = TpcReqLookUp(pAd, DialogToken); - if (pEntry == NULL) { - RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); - for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) { - NdisGetSystemUpTime(&Now); - pEntry = &pTab->Content[i]; - - if ((pEntry->Valid == TRUE) - && RTMP_TIME_AFTER((unsigned long)Now, - (unsigned long)(pEntry-> - lastTime + - TPC_REQ_AGE_OUT))) - { - struct rt_tpc_req_entry *pPrevEntry = NULL; - unsigned long HashIdx = - TPC_DIALOGTOKEN_HASH_INDEX(pEntry-> - DialogToken); - struct rt_tpc_req_entry *pProbeEntry = - pTab->Hash[HashIdx]; - - /* update Hash list */ - do { - if (pProbeEntry == pEntry) { - if (pPrevEntry == NULL) { - pTab->Hash[HashIdx] = - pEntry->pNext; - } else { - pPrevEntry->pNext = - pEntry->pNext; - } - break; - } - - pPrevEntry = pProbeEntry; - pProbeEntry = pProbeEntry->pNext; - } while (pProbeEntry); - - NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry)); - pTab->Size--; - - break; - } - - if (pEntry->Valid == FALSE) - break; - } - - if (i < MAX_TPC_REQ_TAB_SIZE) { - NdisGetSystemUpTime(&Now); - pEntry->lastTime = Now; - pEntry->Valid = TRUE; - pEntry->DialogToken = DialogToken; - pTab->Size++; - } else { - pEntry = NULL; - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pTpcReqTab tab full.\n", __func__)); - } - - /* add this Neighbor entry into HASH table */ - if (pEntry) { - HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken); - if (pTab->Hash[HashIdx] == NULL) { - pTab->Hash[HashIdx] = pEntry; - } else { - pCurrEntry = pTab->Hash[HashIdx]; - while (pCurrEntry->pNext != NULL) - pCurrEntry = pCurrEntry->pNext; - pCurrEntry->pNext = pEntry; - } - } - - RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); - } - - return pEntry; -} - -static void TpcReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken) -{ - struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab; - struct rt_tpc_req_entry *pEntry = NULL; - - if (pTab == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: pTpcReqTab doesn't exist.\n", __func__)); - return; - } - /* if empty, return */ - if (pTab->Size == 0) { - DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n")); - return; - } - - pEntry = TpcReqLookUp(pAd, DialogToken); - if (pEntry != NULL) { - struct rt_tpc_req_entry *pPrevEntry = NULL; - unsigned long HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken); - struct rt_tpc_req_entry *pProbeEntry = pTab->Hash[HashIdx]; - - RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock); - /* update Hash list */ - do { - if (pProbeEntry == pEntry) { - if (pPrevEntry == NULL) { - pTab->Hash[HashIdx] = pEntry->pNext; - } else { - pPrevEntry->pNext = pEntry->pNext; - } - break; - } - - pPrevEntry = pProbeEntry; - pProbeEntry = pProbeEntry->pNext; - } while (pProbeEntry); - - NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry)); - pTab->Size--; - - RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock); - } - - return; -} - -/* - ========================================================================== - Description: - Get Current TimeS tamp. - - Parametrs: - - Return : Current Time Stamp. - ========================================================================== - */ -static u64 GetCurrentTimeStamp(struct rt_rtmp_adapter *pAd) -{ - /* get current time stamp. */ - return 0; -} - -/* - ========================================================================== - Description: - Get Current Transmit Power. - - Parametrs: - - Return : Current Time Stamp. - ========================================================================== - */ -static u8 GetCurTxPwr(struct rt_rtmp_adapter *pAd, u8 Wcid) -{ - return 16; /* 16 dBm */ -} - -/* - ========================================================================== - Description: - Get Current Transmit Power. - - Parametrs: - - Return : Current Time Stamp. - ========================================================================== - */ -void InsertChannelRepIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - char *pCountry, u8 RegulatoryClass) -{ - unsigned long TempLen; - u8 Len; - u8 IEId = IE_AP_CHANNEL_REPORT; - u8 *pChListPtr = NULL; - - Len = 1; - if (strncmp(pCountry, "US", 2) == 0) { - if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: USA Unknow Requlatory class (%d)\n", - __func__, RegulatoryClass)); - return; - } - - Len += - USARegulatoryInfo[RegulatoryClass].ChannelSet. - NumberOfChannels; - pChListPtr = - USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList; - } else if (strncmp(pCountry, "JP", 2) == 0) { - if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: JP Unknow Requlatory class (%d)\n", - __func__, RegulatoryClass)); - return; - } - - Len += - JapanRegulatoryInfo[RegulatoryClass].ChannelSet. - NumberOfChannels; - pChListPtr = - JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList; - } else { - DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n", - __func__, pCountry)); - return; - } - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &IEId, - 1, &Len, - 1, &RegulatoryClass, - Len - 1, pChListPtr, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} - -/* - ========================================================================== - Description: - Insert Dialog Token into frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - 3. Dialog token. - - Return : None. - ========================================================================== - */ -void InsertDialogToken(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, u8 DialogToken) -{ - unsigned long TempLen; - MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} - -/* - ========================================================================== - Description: - Insert TPC Request IE into frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - - Return : None. - ========================================================================== - */ -static void InsertTpcReqIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, unsigned long *pFrameLen) -{ - unsigned long TempLen; - unsigned long Len = 0; - u8 ElementID = IE_TPC_REQUEST; - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &ElementID, 1, &Len, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} - -/* - ========================================================================== - Description: - Insert TPC Report IE into frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - 3. Transmit Power. - 4. Link Margin. - - Return : None. - ========================================================================== - */ -void InsertTpcReportIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 TxPwr, u8 LinkMargin) -{ - unsigned long TempLen; - unsigned long Len = sizeof(struct rt_tpc_report_info); - u8 ElementID = IE_TPC_REPORT; - struct rt_tpc_report_info TpcReportIE; - - TpcReportIE.TxPwr = TxPwr; - TpcReportIE.LinkMargin = LinkMargin; - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &ElementID, - 1, &Len, Len, &TpcReportIE, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} - -/* - ========================================================================== - Description: - Insert Channel Switch Announcement IE into frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - 3. channel switch announcement mode. - 4. new selected channel. - 5. channel switch announcement count. - - Return : None. - ========================================================================== - */ -static void InsertChSwAnnIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 ChSwMode, - u8 NewChannel, u8 ChSwCnt) -{ - unsigned long TempLen; - unsigned long Len = sizeof(struct rt_ch_sw_ann_info); - u8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT; - struct rt_ch_sw_ann_info ChSwAnnIE; - - ChSwAnnIE.ChSwMode = ChSwMode; - ChSwAnnIE.Channel = NewChannel; - ChSwAnnIE.ChSwCnt = ChSwCnt; - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &ElementID, 1, &Len, Len, &ChSwAnnIE, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} - -/* - ========================================================================== - Description: - Insert Measure Request IE into frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - 3. Measure Token. - 4. Measure Request Mode. - 5. Measure Request Type. - 6. Measure Channel. - 7. Measure Start time. - 8. Measure Duration. - - Return : None. - ========================================================================== - */ -static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 Len, struct rt_measure_req_info * pMeasureReqIE) -{ - unsigned long TempLen; - u8 ElementID = IE_MEASUREMENT_REQUEST; - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &ElementID, - 1, &Len, - sizeof(struct rt_measure_req_info), pMeasureReqIE, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - return; -} - -/* - ========================================================================== - Description: - Insert Measure Report IE into frame. - - Parametrs: - 1. frame buffer pointer. - 2. frame length. - 3. Measure Token. - 4. Measure Request Mode. - 5. Measure Request Type. - 6. Length of Report Information - 7. Pointer of Report Information Buffer. - - Return : None. - ========================================================================== - */ -static void InsertMeasureReportIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - struct rt_measure_report_info * pMeasureReportIE, - u8 ReportLnfoLen, u8 *pReportInfo) -{ - unsigned long TempLen; - unsigned long Len; - u8 ElementID = IE_MEASUREMENT_REPORT; - - Len = sizeof(struct rt_measure_report_info) + ReportLnfoLen; - - MakeOutgoingFrame(pFrameBuf, &TempLen, - 1, &ElementID, - 1, &Len, Len, pMeasureReportIE, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - - if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) { - MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen, - ReportLnfoLen, pReportInfo, END_OF_ARGS); - - *pFrameLen = *pFrameLen + TempLen; - } - return; -} - -/* - ========================================================================== - Description: - Prepare Measurement request action frame and enqueue it into - management queue waiting for transmition. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd, - u8 *pOutBuffer, - unsigned long *pFrameLen, - u8 TotalLen, - u8 Category, - u8 Action, - u8 MeasureToken, - u8 MeasureReqMode, - u8 MeasureReqType, u8 NumOfRepetitions) -{ - unsigned long TempLen; - struct rt_measure_req_info MeasureReqIE; - - InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, - Action); - - /* fill Dialog Token */ - InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, - MeasureToken); - - /* fill Number of repetitions. */ - if (Category == CATEGORY_RM) { - MakeOutgoingFrame((pOutBuffer + *pFrameLen), &TempLen, - 2, &NumOfRepetitions, END_OF_ARGS); - - *pFrameLen += TempLen; - } - /* prepare Measurement IE. */ - NdisZeroMemory(&MeasureReqIE, sizeof(struct rt_measure_req_info)); - MeasureReqIE.Token = MeasureToken; - MeasureReqIE.ReqMode.word = MeasureReqMode; - MeasureReqIE.ReqType = MeasureReqType; - InsertMeasureReqIE(pAd, (pOutBuffer + *pFrameLen), pFrameLen, - TotalLen, &MeasureReqIE); - - return; -} - -/* - ========================================================================== - Description: - Prepare Measurement report action frame and enqueue it into - management queue waiting for transmition. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd, - u8 *pDA, - u8 DialogToken, - u8 MeasureToken, - u8 MeasureReqMode, - u8 MeasureReqType, - u8 ReportInfoLen, u8 *pReportInfo) -{ - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen; - struct rt_header_802_11 ActHdr; - struct rt_measure_report_info MeasureRepIE; - - /* build action frame header. */ - MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, - pAd->CurrentAddress); - - NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s() allocate memory failed \n", __func__)); - return; - } - NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11)); - FrameLen = sizeof(struct rt_header_802_11); - - InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, - CATEGORY_SPECTRUM, SPEC_MRP); - - /* fill Dialog Token */ - InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); - - /* prepare Measurement IE. */ - NdisZeroMemory(&MeasureRepIE, sizeof(struct rt_measure_report_info)); - MeasureRepIE.Token = MeasureToken; - MeasureRepIE.ReportMode = MeasureReqMode; - MeasureRepIE.ReportType = MeasureReqType; - InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, - &MeasureRepIE, ReportInfoLen, pReportInfo); - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - return; -} - -/* - ========================================================================== - Description: - Prepare TPC Request action frame and enqueue it into - management queue waiting for transmition. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken) -{ - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen; - - struct rt_header_802_11 ActHdr; - - /* build action frame header. */ - MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, - pAd->CurrentAddress); - - NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s() allocate memory failed \n", __func__)); - return; - } - NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11)); - FrameLen = sizeof(struct rt_header_802_11); - - InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, - CATEGORY_SPECTRUM, SPEC_TPCRQ); - - /* fill Dialog Token */ - InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); - - /* Insert TPC Request IE. */ - InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen); - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - return; -} - -/* - ========================================================================== - Description: - Prepare TPC Report action frame and enqueue it into - management queue waiting for transmition. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void EnqueueTPCRep(struct rt_rtmp_adapter *pAd, - u8 *pDA, - u8 DialogToken, u8 TxPwr, u8 LinkMargin) -{ - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen; - - struct rt_header_802_11 ActHdr; - - /* build action frame header. */ - MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, - pAd->CurrentAddress); - - NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s() allocate memory failed \n", __func__)); - return; - } - NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11)); - FrameLen = sizeof(struct rt_header_802_11); - - InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, - CATEGORY_SPECTRUM, SPEC_TPCRP); - - /* fill Dialog Token */ - InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); - - /* Insert TPC Request IE. */ - InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, - LinkMargin); - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - return; -} - -/* - ========================================================================== - Description: - Prepare Channel Switch Announcement action frame and enqueue it into - management queue waiting for transmition. - - Parametrs: - 1. the destination mac address of the frame. - 2. Channel switch announcement mode. - 2. a New selected channel. - - Return : None. - ========================================================================== - */ -void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd, - u8 *pDA, u8 ChSwMode, u8 NewCh) -{ - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen; - - struct rt_header_802_11 ActHdr; - - /* build action frame header. */ - MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, - pAd->CurrentAddress); - - NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s() allocate memory failed \n", __func__)); - return; - } - NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11)); - FrameLen = sizeof(struct rt_header_802_11); - - InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, - CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH); - - InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, - NewCh, 0); - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - return; -} - -static BOOLEAN DfsRequirementCheck(struct rt_rtmp_adapter *pAd, u8 Channel) -{ - BOOLEAN Result = FALSE; - int i; - - do { - /* check DFS procedure is running. */ - /* make sure DFS procedure won't start twice. */ - if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) { - Result = FALSE; - break; - } - /* check the new channel carried from Channel Switch Announcemnet is valid. */ - for (i = 0; i < pAd->ChannelListNum; i++) { - if ((Channel == pAd->ChannelList[i].Channel) - && (pAd->ChannelList[i].RemainingTimeForUse == 0)) { - /* found radar signal in the channel. the channel can't use at least for 30 minutes. */ - pAd->ChannelList[i].RemainingTimeForUse = 1800; /*30 min = 1800 sec */ - Result = TRUE; - break; - } - } - } while (FALSE); - - return Result; -} - -void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd, - u8 *pRA, - u8 *pTA, u8 ChSwMode, u8 Channel) -{ -} - -static void StartDFSProcedure(struct rt_rtmp_adapter *pAd, - u8 Channel, u8 ChSwMode) -{ - /* start DFS procedure */ - pAd->CommonCfg.Channel = Channel; - - N_ChannelCheck(pAd); - - pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE; - pAd->CommonCfg.RadarDetect.CSCount = 0; -} - -/* - ========================================================================== - Description: - Channel Switch Announcement action frame sanity check. - - Parametrs: - 1. MLME message containing the received frame - 2. message length. - 3. Channel switch announcement information buffer. - - Return : None. - ========================================================================== - */ - -/* - Channel Switch Announcement IE. - +----+-----+-----------+------------+-----------+ - | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt | - +----+-----+-----------+------------+-----------+ - 1 1 1 1 1 -*/ -static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, - unsigned long MsgLen, - struct rt_ch_sw_ann_info * pChSwAnnInfo) -{ - struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg; - u8 *pFramePtr = Fr->Octet; - BOOLEAN result = FALSE; - struct rt_eid * eid_ptr; - - /* skip 802.11 header. */ - MsgLen -= sizeof(struct rt_header_802_11); - - /* skip category and action code. */ - pFramePtr += 2; - MsgLen -= 2; - - if (pChSwAnnInfo == NULL) - return result; - - eid_ptr = (struct rt_eid *) pFramePtr; - while (((u8 *) eid_ptr + eid_ptr->Len + 1) < - ((u8 *)pFramePtr + MsgLen)) { - switch (eid_ptr->Eid) { - case IE_CHANNEL_SWITCH_ANNOUNCEMENT: - NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, - 1); - NdisMoveMemory(&pChSwAnnInfo->Channel, - eid_ptr->Octet + 1, 1); - NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, - eid_ptr->Octet + 2, 1); - - result = TRUE; - break; - - default: - break; - } - eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len); - } - - return result; -} - -/* - ========================================================================== - Description: - Measurement request action frame sanity check. - - Parametrs: - 1. MLME message containing the received frame - 2. message length. - 3. Measurement request information buffer. - - Return : None. - ========================================================================== - */ -static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, - unsigned long MsgLen, - u8 *pDialogToken, - struct rt_measure_req_info * pMeasureReqInfo, - struct rt_measure_req * pMeasureReq) -{ - struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg; - u8 *pFramePtr = Fr->Octet; - BOOLEAN result = FALSE; - struct rt_eid * eid_ptr; - u8 *ptr; - u64 MeasureStartTime; - u16 MeasureDuration; - - /* skip 802.11 header. */ - MsgLen -= sizeof(struct rt_header_802_11); - - /* skip category and action code. */ - pFramePtr += 2; - MsgLen -= 2; - - if (pMeasureReqInfo == NULL) - return result; - - NdisMoveMemory(pDialogToken, pFramePtr, 1); - pFramePtr += 1; - MsgLen -= 1; - - eid_ptr = (struct rt_eid *) pFramePtr; - while (((u8 *) eid_ptr + eid_ptr->Len + 1) < - ((u8 *)pFramePtr + MsgLen)) { - switch (eid_ptr->Eid) { - case IE_MEASUREMENT_REQUEST: - NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, - 1); - NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, - eid_ptr->Octet + 1, 1); - NdisMoveMemory(&pMeasureReqInfo->ReqType, - eid_ptr->Octet + 2, 1); - ptr = (u8 *)(eid_ptr->Octet + 3); - NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1); - NdisMoveMemory(&MeasureStartTime, ptr + 1, 8); - pMeasureReq->MeasureStartTime = - SWAP64(MeasureStartTime); - NdisMoveMemory(&MeasureDuration, ptr + 9, 2); - pMeasureReq->MeasureDuration = SWAP16(MeasureDuration); - - result = TRUE; - break; - - default: - break; - } - eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len); - } - - return result; -} - -/* - ========================================================================== - Description: - Measurement report action frame sanity check. - - Parametrs: - 1. MLME message containing the received frame - 2. message length. - 3. Measurement report information buffer. - 4. basic report information buffer. - - Return : None. - ========================================================================== - */ - -/* - Measurement Report IE. - +----+-----+-------+-------------+--------------+----------------+ - | ID | Len | Token | Report Mode | Measure Type | Measure Report | - +----+-----+-------+-------------+--------------+----------------+ - 1 1 1 1 1 variable - - Basic Report. - +--------+------------+----------+-----+ - | Ch Num | Start Time | Duration | Map | - +--------+------------+----------+-----+ - 1 8 2 1 - - Map Field Bit Format. - +-----+---------------+---------------------+-------+------------+----------+ - | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved | - +-----+---------------+---------------------+-------+------------+----------+ - 0 1 2 3 4 5-7 -*/ -static BOOLEAN PeerMeasureReportSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, - unsigned long MsgLen, - u8 *pDialogToken, - struct rt_measure_report_info * - pMeasureReportInfo, - u8 *pReportBuf) -{ - struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg; - u8 *pFramePtr = Fr->Octet; - BOOLEAN result = FALSE; - struct rt_eid * eid_ptr; - u8 *ptr; - - /* skip 802.11 header. */ - MsgLen -= sizeof(struct rt_header_802_11); - - /* skip category and action code. */ - pFramePtr += 2; - MsgLen -= 2; - - if (pMeasureReportInfo == NULL) - return result; - - NdisMoveMemory(pDialogToken, pFramePtr, 1); - pFramePtr += 1; - MsgLen -= 1; - - eid_ptr = (struct rt_eid *) pFramePtr; - while (((u8 *) eid_ptr + eid_ptr->Len + 1) < - ((u8 *)pFramePtr + MsgLen)) { - switch (eid_ptr->Eid) { - case IE_MEASUREMENT_REPORT: - NdisMoveMemory(&pMeasureReportInfo->Token, - eid_ptr->Octet, 1); - NdisMoveMemory(&pMeasureReportInfo->ReportMode, - eid_ptr->Octet + 1, 1); - NdisMoveMemory(&pMeasureReportInfo->ReportType, - eid_ptr->Octet + 2, 1); - if (pMeasureReportInfo->ReportType == RM_BASIC) { - struct rt_measure_basic_report * pReport = - (struct rt_measure_basic_report *) pReportBuf; - ptr = (u8 *)(eid_ptr->Octet + 3); - NdisMoveMemory(&pReport->ChNum, ptr, 1); - NdisMoveMemory(&pReport->MeasureStartTime, - ptr + 1, 8); - NdisMoveMemory(&pReport->MeasureDuration, - ptr + 9, 2); - NdisMoveMemory(&pReport->Map, ptr + 11, 1); - - } else if (pMeasureReportInfo->ReportType == RM_CCA) { - struct rt_measure_cca_report * pReport = - (struct rt_measure_cca_report *) pReportBuf; - ptr = (u8 *)(eid_ptr->Octet + 3); - NdisMoveMemory(&pReport->ChNum, ptr, 1); - NdisMoveMemory(&pReport->MeasureStartTime, - ptr + 1, 8); - NdisMoveMemory(&pReport->MeasureDuration, - ptr + 9, 2); - NdisMoveMemory(&pReport->CCA_Busy_Fraction, - ptr + 11, 1); - - } else if (pMeasureReportInfo->ReportType == - RM_RPI_HISTOGRAM) { - struct rt_measure_rpi_report * pReport = - (struct rt_measure_rpi_report *) pReportBuf; - ptr = (u8 *)(eid_ptr->Octet + 3); - NdisMoveMemory(&pReport->ChNum, ptr, 1); - NdisMoveMemory(&pReport->MeasureStartTime, - ptr + 1, 8); - NdisMoveMemory(&pReport->MeasureDuration, - ptr + 9, 2); - NdisMoveMemory(&pReport->RPI_Density, ptr + 11, - 8); - } - result = TRUE; - break; - - default: - break; - } - eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len); - } - - return result; -} - -/* - ========================================================================== - Description: - TPC Request action frame sanity check. - - Parametrs: - 1. MLME message containing the received frame - 2. message length. - 3. Dialog Token. - - Return : None. - ========================================================================== - */ -static BOOLEAN PeerTpcReqSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, - unsigned long MsgLen, u8 *pDialogToken) -{ - struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg; - u8 *pFramePtr = Fr->Octet; - BOOLEAN result = FALSE; - struct rt_eid * eid_ptr; - - MsgLen -= sizeof(struct rt_header_802_11); - - /* skip category and action code. */ - pFramePtr += 2; - MsgLen -= 2; - - if (pDialogToken == NULL) - return result; - - NdisMoveMemory(pDialogToken, pFramePtr, 1); - pFramePtr += 1; - MsgLen -= 1; - - eid_ptr = (struct rt_eid *) pFramePtr; - while (((u8 *) eid_ptr + eid_ptr->Len + 1) < - ((u8 *)pFramePtr + MsgLen)) { - switch (eid_ptr->Eid) { - case IE_TPC_REQUEST: - result = TRUE; - break; - - default: - break; - } - eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len); - } - - return result; -} - -/* - ========================================================================== - Description: - TPC Report action frame sanity check. - - Parametrs: - 1. MLME message containing the received frame - 2. message length. - 3. Dialog Token. - 4. TPC Report IE. - - Return : None. - ========================================================================== - */ -static BOOLEAN PeerTpcRepSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, - unsigned long MsgLen, - u8 *pDialogToken, - struct rt_tpc_report_info * pTpcRepInfo) -{ - struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg; - u8 *pFramePtr = Fr->Octet; - BOOLEAN result = FALSE; - struct rt_eid * eid_ptr; - - MsgLen -= sizeof(struct rt_header_802_11); - - /* skip category and action code. */ - pFramePtr += 2; - MsgLen -= 2; - - if (pDialogToken == NULL) - return result; - - NdisMoveMemory(pDialogToken, pFramePtr, 1); - pFramePtr += 1; - MsgLen -= 1; - - eid_ptr = (struct rt_eid *) pFramePtr; - while (((u8 *) eid_ptr + eid_ptr->Len + 1) < - ((u8 *)pFramePtr + MsgLen)) { - switch (eid_ptr->Eid) { - case IE_TPC_REPORT: - NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1); - NdisMoveMemory(&pTpcRepInfo->LinkMargin, - eid_ptr->Octet + 1, 1); - result = TRUE; - break; - - default: - break; - } - eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len); - } - - return result; -} - -/* - ========================================================================== - Description: - Channel Switch Announcement action frame handler. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_ch_sw_ann_info ChSwAnnInfo; - struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg; - u8 index = 0, Channel = 0, NewChannel = 0; - unsigned long Bssidx = 0; - - NdisZeroMemory(&ChSwAnnInfo, sizeof(struct rt_ch_sw_ann_info)); - if (!PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Invalid Channel Switch Action Frame.\n")); - return; - } - - if (pAd->OpMode == OPMODE_STA) { - Bssidx = - BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, - pAd->CommonCfg.Channel); - if (Bssidx == BSS_NOT_FOUND) { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerChSwAnnAction - Bssidx is not found\n")); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("\n****Bssidx is %d, Channel = %d\n", index, - pAd->ScanTab.BssEntry[Bssidx].Channel)); - hex_dump("SSID", pAd->ScanTab.BssEntry[Bssidx].Bssid, 6); - - Channel = pAd->CommonCfg.Channel; - NewChannel = ChSwAnnInfo.Channel; - - if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) - && (Channel != NewChannel)) { - /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */ - /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */ - AsicSwitchChannel(pAd, 1, FALSE); - AsicLockChannel(pAd, 1); - LinkDown(pAd, FALSE); - MlmeQueueInit(&pAd->Mlme.Queue); - BssTableInit(&pAd->ScanTab); - RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */ - - /* channel sanity check */ - for (index = 0; index < pAd->ChannelListNum; index++) { - if (pAd->ChannelList[index].Channel == - NewChannel) { - pAd->ScanTab.BssEntry[Bssidx].Channel = - NewChannel; - pAd->CommonCfg.Channel = NewChannel; - AsicSwitchChannel(pAd, - pAd->CommonCfg. - Channel, FALSE); - AsicLockChannel(pAd, - pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", - NewChannel)); - break; - } - } - - if (index >= pAd->ChannelListNum) { - DBGPRINT_ERR("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum); - } - } - } - - return; -} - -/* - ========================================================================== - Description: - Measurement Request action frame handler. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -static void PeerMeasureReqAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem) -{ - struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg; - u8 DialogToken; - struct rt_measure_req_info MeasureReqInfo; - struct rt_measure_req MeasureReq; - MEASURE_REPORT_MODE ReportMode; - - if (PeerMeasureReqSanity - (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, - &MeasureReq)) { - ReportMode.word = 0; - ReportMode.field.Incapable = 1; - EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, - MeasureReqInfo.Token, ReportMode.word, - MeasureReqInfo.ReqType, 0, NULL); - } - - return; -} - -/* - ========================================================================== - Description: - Measurement Report action frame handler. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem) -{ - struct rt_measure_report_info MeasureReportInfo; - struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg; - u8 DialogToken; - u8 *pMeasureReportInfo; - -/* if (pAd->CommonCfg.bIEEE80211H != TRUE) */ -/* return; */ - - pMeasureReportInfo = kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC); - if (pMeasureReportInfo == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s unable to alloc memory for measure report buffer (size=%zu).\n", - __func__, sizeof(struct rt_measure_rpi_report))); - return; - } - - NdisZeroMemory(&MeasureReportInfo, sizeof(struct rt_measure_report_info)); - NdisZeroMemory(pMeasureReportInfo, sizeof(struct rt_measure_rpi_report)); - if (PeerMeasureReportSanity - (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, - pMeasureReportInfo)) { - do { - struct rt_measure_req_entry *pEntry = NULL; - - /* Not a autonomous measure report. */ - /* check the dialog token field. drop it if the dialog token doesn't match. */ - if ((DialogToken != 0) - && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == - NULL)) - break; - - if (pEntry != NULL) - MeasureReqDelete(pAd, pEntry->DialogToken); - - if (MeasureReportInfo.ReportType == RM_BASIC) { - struct rt_measure_basic_report * pBasicReport = - (struct rt_measure_basic_report *) pMeasureReportInfo; - if ((pBasicReport->Map.field.Radar) - && - (DfsRequirementCheck - (pAd, pBasicReport->ChNum) == TRUE)) { - NotifyChSwAnnToPeerAPs(pAd, - pFr->Hdr.Addr1, - pFr->Hdr.Addr2, - 1, - pBasicReport-> - ChNum); - StartDFSProcedure(pAd, - pBasicReport->ChNum, - 1); - } - } - } while (FALSE); - } else - DBGPRINT(RT_DEBUG_TRACE, - ("Invalid Measurement Report Frame.\n")); - - kfree(pMeasureReportInfo); - - return; -} - -/* - ========================================================================== - Description: - TPC Request action frame handler. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -static void PeerTpcReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg; - u8 *pFramePtr = pFr->Octet; - u8 DialogToken; - u8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid); - u8 LinkMargin = 0; - char RealRssi; - - /* link margin: Ratio of the received signal power to the minimum desired by the station (STA). The */ - /* STA may incorporate rate information and channel conditions, including interference, into its computation */ - /* of link margin. */ - - RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), - ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), - ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); - - /* skip Category and action code. */ - pFramePtr += 2; - - /* Dialog token. */ - NdisMoveMemory(&DialogToken, pFramePtr, 1); - - LinkMargin = (RealRssi / MIN_RCV_PWR); - if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken)) - EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, - LinkMargin); - - return; -} - -/* - ========================================================================== - Description: - TPC Report action frame handler. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 DialogToken; - struct rt_tpc_report_info TpcRepInfo; - struct rt_tpc_req_entry *pEntry = NULL; - - NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info)); - if (PeerTpcRepSanity - (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) { - pEntry = TpcReqLookUp(pAd, DialogToken); - if (pEntry != NULL) { - TpcReqDelete(pAd, pEntry->DialogToken); - DBGPRINT(RT_DEBUG_TRACE, - ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n", - __func__, DialogToken, TpcRepInfo.TxPwr, - TpcRepInfo.LinkMargin)); - } - } - - return; -} - -/* - ========================================================================== - Description: - Spectrun action frames Handler such as channel switch annoucement, - measurement report, measurement request actions frames. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - - u8 Action = Elem->Msg[LENGTH_802_11 + 1]; - - if (pAd->CommonCfg.bIEEE80211H != TRUE) - return; - - switch (Action) { - case SPEC_MRQ: - /* current rt2860 unable do such measure specified in Measurement Request. */ - /* reject all measurement request. */ - PeerMeasureReqAction(pAd, Elem); - break; - - case SPEC_MRP: - PeerMeasureReportAction(pAd, Elem); - break; - - case SPEC_TPCRQ: - PeerTpcReqAction(pAd, Elem); - break; - - case SPEC_TPCRP: - PeerTpcRepAction(pAd, Elem); - break; - - case SPEC_CHANNEL_SWITCH: - - PeerChSwAnnAction(pAd, Elem); - break; - } - - return; -} - -/* - ========================================================================== - Description: - - Parametrs: - - Return : None. - ========================================================================== - */ -int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg) -{ - u32 Aid = 1; - u32 ArgIdx; - char *thisChar; - - MEASURE_REQ_MODE MeasureReqMode; - u8 MeasureReqToken = RandomByte(pAd); - u8 MeasureReqType = RM_BASIC; - u8 MeasureCh = 1; - u64 MeasureStartTime = GetCurrentTimeStamp(pAd); - struct rt_measure_req MeasureReq; - u8 TotalLen; - - struct rt_header_802_11 ActHdr; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen; - - NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s() allocate memory failed \n", __func__)); - goto END_OF_MEASURE_REQ; - } - - ArgIdx = 1; - while ((thisChar = strsep((char **)&arg, "-")) != NULL) { - switch (ArgIdx) { - case 1: /* Aid. */ - Aid = (u8)simple_strtol(thisChar, 0, 16); - break; - - case 2: /* Measurement Request Type. */ - MeasureReqType = simple_strtol(thisChar, 0, 16); - if (MeasureReqType > 3) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: unknow MeasureReqType(%d)\n", - __func__, MeasureReqType)); - goto END_OF_MEASURE_REQ; - } - break; - - case 3: /* Measurement channel. */ - MeasureCh = (u8)simple_strtol(thisChar, 0, 16); - break; - } - ArgIdx++; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__, - Aid, MeasureReqType, MeasureCh)); - if (!VALID_WCID(Aid)) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: unknow sta of Aid(%d)\n", __func__, Aid)); - goto END_OF_MEASURE_REQ; - } - - MeasureReqMode.word = 0; - MeasureReqMode.field.Enable = 1; - - MeasureReqInsert(pAd, MeasureReqToken); - - /* build action frame header. */ - MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, - pAd->MacTab.Content[Aid].Addr, pAd->CurrentAddress); - - NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11)); - FrameLen = sizeof(struct rt_header_802_11); - - TotalLen = sizeof(struct rt_measure_req_info) + sizeof(struct rt_measure_req); - - MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen, - sizeof(struct rt_measure_req_info), CATEGORY_RM, RM_BASIC, - MeasureReqToken, MeasureReqMode.word, - MeasureReqType, 0); - - MeasureReq.ChNum = MeasureCh; - MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime); - MeasureReq.MeasureDuration = cpu2le16(2000); - - { - unsigned long TempLen; - MakeOutgoingFrame(pOutBuffer + FrameLen, &TempLen, - sizeof(struct rt_measure_req), &MeasureReq, - END_OF_ARGS); - FrameLen += TempLen; - } - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (u32)FrameLen); - -END_OF_MEASURE_REQ: - MlmeFreeMemory(pAd, pOutBuffer); - - return TRUE; -} - -int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg) -{ - u32 Aid; - - u8 TpcReqToken = RandomByte(pAd); - - Aid = (u32)simple_strtol(arg, 0, 16); - - DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid)); - if (!VALID_WCID(Aid)) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s: unknow sta of Aid(%d)\n", __func__, Aid)); - return TRUE; - } - - TpcReqInsert(pAd, TpcReqToken); - - EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken); - - return TRUE; -} diff --git a/drivers/staging/rt2860/crypt_hmac.h b/drivers/staging/rt2860/crypt_hmac.h deleted file mode 100644 index 7a56515d7266..000000000000 --- a/drivers/staging/rt2860/crypt_hmac.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -/**************************************************************************** - Module Name: - HMAC - - Abstract: - FIPS 198: The Keyed-Hash Message Authentication Code (HMAC) - - Revision History: - Who When What - -------- ---------- ------------------------------------------ - Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256 -***************************************************************************/ -#ifndef __CRYPT_HMAC_H__ -#define __CRYPT_HMAC_H__ - -#ifdef CRYPT_TESTPLAN -#include "crypt_testplan.h" -#else -#include "rt_config.h" -#endif /* CRYPT_TESTPLAN */ - -#ifdef SHA1_SUPPORT -#define HMAC_SHA1_SUPPORT -void HMAC_SHA1(IN const u8 Key[], - u32 KeyLen, - IN const u8 Message[], - u32 MessageLen, u8 MAC[], u32 MACLen); -#endif /* SHA1_SUPPORT */ - -#ifdef MD5_SUPPORT -#define HMAC_MD5_SUPPORT -void HMAC_MD5(IN const u8 Key[], - u32 KeyLen, - IN const u8 Message[], - u32 MessageLen, u8 MAC[], u32 MACLen); -#endif /* MD5_SUPPORT */ - -#endif /* __CRYPT_HMAC_H__ */ diff --git a/drivers/staging/rt2860/crypt_md5.h b/drivers/staging/rt2860/crypt_md5.h deleted file mode 100644 index 26f974554b26..000000000000 --- a/drivers/staging/rt2860/crypt_md5.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -/**************************************************************************** - Module Name: - MD5 - - Abstract: - RFC1321: The MD5 Message-Digest Algorithm - - Revision History: - Who When What - -------- ---------- ------------------------------------------ - Eddy 2008/11/24 Create md5 -***************************************************************************/ - -#ifndef __CRYPT_MD5_H__ -#define __CRYPT_MD5_H__ - -#ifdef CRYPT_TESTPLAN -#include "crypt_testplan.h" -#else -#include "rt_config.h" -#endif /* CRYPT_TESTPLAN */ - -/* Algorithm options */ -#define MD5_SUPPORT - -#ifdef MD5_SUPPORT -#define MD5_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ -#define MD5_DIGEST_SIZE 16 /* 128 bits = 16 bytes */ - -struct rt_md5_ctx_struc { - u32 HashValue[4]; - u64 MessageLen; - u8 Block[MD5_BLOCK_SIZE]; - u32 BlockLen; -}; - -void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX); -void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX); -void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX, - IN const u8 Message[], u32 MessageLen); -void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[]); -void RT_MD5(IN const u8 Message[], - u32 MessageLen, u8 DigestMessage[]); -#endif /* MD5_SUPPORT */ - -#endif /* __CRYPT_MD5_H__ */ diff --git a/drivers/staging/rt2860/crypt_sha2.h b/drivers/staging/rt2860/crypt_sha2.h deleted file mode 100644 index 20d11ab865c1..000000000000 --- a/drivers/staging/rt2860/crypt_sha2.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -/**************************************************************************** - Module Name: - SHA2 - - Abstract: - FIPS 180-2: Secure Hash Standard (SHS) - - Revision History: - Who When What - -------- ---------- ------------------------------------------ - Eddy 2008/11/24 Create SHA1 - Eddy 2008/07/23 Create SHA256 -***************************************************************************/ - -#ifndef __CRYPT_SHA2_H__ -#define __CRYPT_SHA2_H__ - -#ifdef CRYPT_TESTPLAN -#include "crypt_testplan.h" -#else -#include "rt_config.h" -#endif /* CRYPT_TESTPLAN */ - -/* Algorithm options */ -#define SHA1_SUPPORT - -#ifdef SHA1_SUPPORT -#define SHA1_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ -#define SHA1_DIGEST_SIZE 20 /* 160 bits = 20 bytes */ -struct rt_sha1_ctx { - u32 HashValue[5]; /* 5 = (SHA1_DIGEST_SIZE / 32) */ - u64 MessageLen; /* total size */ - u8 Block[SHA1_BLOCK_SIZE]; - u32 BlockLen; -}; - -void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX); -void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX); -void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX, - IN const u8 Message[], u32 MessageLen); -void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[]); -void RT_SHA1(IN const u8 Message[], - u32 MessageLen, u8 DigestMessage[]); -#endif /* SHA1_SUPPORT */ - -#endif /* __CRYPT_SHA2_H__ */ diff --git a/drivers/staging/rt2860/dfs.h b/drivers/staging/rt2860/dfs.h deleted file mode 100644 index 5fbab259acae..000000000000 --- a/drivers/staging/rt2860/dfs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - dfs.h - - Abstract: - Support DFS function. - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Fonchi 03-12-2007 created -*/ - -BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch); diff --git a/drivers/staging/rt2860/eeprom.h b/drivers/staging/rt2860/eeprom.h deleted file mode 100644 index 72c8fb941655..000000000000 --- a/drivers/staging/rt2860/eeprom.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - eeprom.h - - Abstract: - Miniport header file for eeprom related information - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ -#ifndef __EEPROM_H__ -#define __EEPROM_H__ - -#ifdef RTMP_PCI_SUPPORT -/************************************************************************* - * Public function declarations for prom-based chipset - ************************************************************************/ -int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 *pValue); -#endif /* RTMP_PCI_SUPPORT // */ -#ifdef RTMP_USB_SUPPORT -/************************************************************************* - * Public function declarations for usb-based prom chipset - ************************************************************************/ -int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd, - u16 offset, u16 *pData); -#endif /* RTMP_USB_SUPPORT // */ - -#ifdef RT30xx -#ifdef RTMP_EFUSE_SUPPORT -int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 *pValue); -#endif /* RTMP_EFUSE_SUPPORT // */ -#endif /* RT30xx // */ - -/************************************************************************* - * Public function declarations for prom operation callback functions setting - ************************************************************************/ -int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType); - -#endif /* __EEPROM_H__ // */ diff --git a/drivers/staging/rt2860/iface/rtmp_pci.h b/drivers/staging/rt2860/iface/rtmp_pci.h deleted file mode 100644 index 3d66e386bd8a..000000000000 --- a/drivers/staging/rt2860/iface/rtmp_pci.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#ifndef __RTMP_PCI_H__ -#define __RTMP_PCI_H__ - -#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \ - ((struct os_cookie *)handle)->pci_dev = dev_p; - -#ifdef LINUX -/* set driver data */ -#define RT28XX_DRVDATA_SET(_a) pci_set_drvdata(_a, net_dev); - -#define RT28XX_PUT_DEVICE(dev_p) - -#define SA_SHIRQ IRQF_SHARED - -#ifdef PCI_MSI_SUPPORT -#define RTMP_MSI_ENABLE(_pAd) \ - { struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \ - (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) \ - == 0 ? TRUE : FALSE; \ - } - -#define RTMP_MSI_DISABLE(_pAd) \ - { struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \ - if (_pAd->HaveMsi == TRUE) \ - pci_disable_msi(_pObj->pci_dev); \ - _pAd->HaveMsi = FALSE; \ - } -#else -#define RTMP_MSI_ENABLE(_pAd) do {} while (0) -#define RTMP_MSI_DISABLE(_pAd) do {} while (0) -#endif /* PCI_MSI_SUPPORT */ - -#define RTMP_PCI_DEV_UNMAP() \ -{ if (net_dev->base_addr) { \ - iounmap((void *)(net_dev->base_addr)); \ - release_mem_region(pci_resource_start(dev_p, 0), \ - pci_resource_len(dev_p, 0)); } \ - if (net_dev->irq) \ - pci_release_regions(dev_p); } - -#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) {\ - if (pci_read_config_word(pci_dev, offset, ®16) == 0) \ - Configuration = le2cpu16(reg16); \ - else \ - Configuration = 0; } - -#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) {\ - reg16 = cpu2le16(Configuration); \ - pci_write_config_word(pci_dev, offset, reg16); } - -#endif /* LINUX */ - -#endif /* __RTMP_PCI_H__ */ diff --git a/drivers/staging/rt2860/iface/rtmp_usb.h b/drivers/staging/rt2860/iface/rtmp_usb.h deleted file mode 100644 index 571289637973..000000000000 --- a/drivers/staging/rt2860/iface/rtmp_usb.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#ifndef __RTMP_USB_H__ -#define __RTMP_USB_H__ - -#include "../rtusb_io.h" - -#ifdef LINUX -#include -#endif /* LINUX */ - -extern u8 EpToQueue[6]; - -#define RXBULKAGGRE_ZISE 12 -#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1)) -#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE) -#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE) -#define MAX_MLME_HANDLER_MEMORY 20 - -/* Flags for Bulkflags control for bulk out data */ -#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001 -#define fRTUSB_BULK_OUT_RTS 0x00000002 -#define fRTUSB_BULK_OUT_MLME 0x00000004 - -#define fRTUSB_BULK_OUT_PSPOLL 0x00000010 -#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000020 -#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000040 -#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000080 -#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000100 - -#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000 - -/* TODO:move to ./ate/include/iface/ate_usb.h */ - -#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext) \ -{ \ - if ((_txContext)->ENextBulkOutPosition == \ - (_txContext)->CurWritePosition) {\ - (_txContext)->bRingEmpty = TRUE; \ - } \ - /*NdisInterlockedDecrement(&(_p)->TxCount); */\ -} - -/****************************************************************************** - - USB Bulk operation related definitions - -******************************************************************************/ - -#ifdef LINUX -#define BULKAGGRE_ZISE 100 -#define RT28XX_PUT_DEVICE usb_put_dev -#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC) -#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, \ - GFP_ATOMIC) -#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, \ - BufSize, \ - pDma_addr) \ - usb_alloc_coherent(\ - pUsb_Dev, \ - BufSize, \ - GFP_ATOMIC, \ - pDma_addr) -#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, \ - BufSize, \ - pTransferBuf, \ - Dma_addr) \ - usb_free_coherent( \ - pUsb_Dev, \ - BufSize, \ - pTransferBuf, \ - Dma_addr) - -#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb) - -/* unlink urb */ -#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb) - -extern void dump_urb(struct urb *purb); - -#define InterlockedIncrement atomic_inc -#define NdisInterlockedIncrement atomic_inc -#define InterlockedDecrement atomic_dec -#define NdisInterlockedDecrement atomic_dec -#define InterlockedExchange atomic_set - -#endif /* LINUX */ - -#define NT_SUCCESS(status) (((status) >= 0) ? (TRUE) : (FALSE)) - -#define USBD_TRANSFER_DIRECTION_OUT 0 -#define USBD_TRANSFER_DIRECTION_IN 0 -#define USBD_SHORT_TRANSFER_OK 0 -#define PURB struct urb * - -#define PIRP void * -#define NDIS_OID u32 -#ifndef USB_ST_NOERROR -#define USB_ST_NOERROR 0 -#endif - -/* vendor-specific control operations */ -#define CONTROL_TIMEOUT_JIFFIES ((100 * OS_HZ) / 1000) -#define UNLINK_TIMEOUT_MS 3 - -void RTUSBBulkOutDataPacketComplete(struct urb *purb, struct pt_regs *pt_regs); -void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs *pt_regs); -void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs *pt_regs); -void RTUSBBulkOutRTSFrameComplete(struct urb *pUrb, struct pt_regs *pt_regs); -void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs *pt_regs); -void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs); - -#ifdef KTHREAD_SUPPORT -#define RTUSBMlmeUp(pAd) \ - do { \ - struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\ - if (_pTask->kthread_task) {\ - _pTask->kthread_running = TRUE; \ - wake_up(&_pTask->kthread_q); \ - } \ - } while (0) -#else -#define RTUSBMlmeUp(pAd) \ - do { \ - struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\ - CHECK_PID_LEGALITY(_pTask->taskPID) \ - { \ - RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \ - } \ - } while (0) -#endif - -#ifdef KTHREAD_SUPPORT -#define RTUSBCMDUp(pAd) \ - do { \ - struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask); \ - { \ - _pTask->kthread_running = TRUE; \ - wake_up(&_pTask->kthread_q); \ - } \ - } while (0) - -#else -#define RTUSBCMDUp(pAd) \ - do { \ - struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask); \ - CHECK_PID_LEGALITY(_pTask->taskPID) \ - {\ - RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \ - } \ - } while (0) -#endif - -#define DEVICE_VENDOR_REQUEST_OUT 0x40 -#define DEVICE_VENDOR_REQUEST_IN 0xc0 -/*#define INTERFACE_VENDOR_REQUEST_OUT 0x41*/ -/*#define INTERFACE_VENDOR_REQUEST_IN 0xc1*/ - -#define BULKOUT_MGMT_RESET_FLAG 0x80 - -#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F)) -#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F)) -#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0) - -#define RTMP_IRQ_REQUEST(net_dev) do {} while (0) -#define RTMP_IRQ_RELEASE(net_dev) do {} while (0) - -#endif /* __RTMP_USB_H__ */ diff --git a/drivers/staging/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h deleted file mode 100644 index a285851692ee..000000000000 --- a/drivers/staging/rt2860/mlme.h +++ /dev/null @@ -1,1050 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - mlme.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ------------------------------ - John Chang 2003-08-28 Created - John Chang 2004-09-06 modified for RT2600 - Justin P. Mattock 11/07/2010 Fix typos in comments - -*/ -#ifndef __MLME_H__ -#define __MLME_H__ - -#include "rtmp_dot11.h" - -/* maximum supported capability information */ -/* ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot */ -#define SUPPORTED_CAPABILITY_INFO 0x0533 - -#define END_OF_ARGS -1 -#define LFSR_MASK 0x80000057 -#define MLME_TASK_EXEC_INTV 100/*200*/ /* */ -#define LEAD_TIME 5 -#define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ /* MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec */ -#define REORDER_EXEC_INTV 100 /* 0.1 sec */ - -/* The definition of Radar detection duration region */ -#define CE 0 -#define FCC 1 -#define JAP 2 -#define JAP_W53 3 -#define JAP_W56 4 -#define MAX_RD_REGION 5 - -#define BEACON_LOST_TIME (4 * OS_HZ) /* 2048 msec = 2 sec */ - -#define DLS_TIMEOUT 1200 /* unit: msec */ -#define AUTH_TIMEOUT 300 /* unit: msec */ -#define ASSOC_TIMEOUT 300 /* unit: msec */ -#define JOIN_TIMEOUT 2000 /* unit: msec */ -#define SHORT_CHANNEL_TIME 90 /* unit: msec */ -#define MIN_CHANNEL_TIME 110 /* unit: msec, for dual band scan */ -#define MAX_CHANNEL_TIME 140 /* unit: msec, for single band scan */ -#define FAST_ACTIVE_SCAN_TIME 30 /* Active scan waiting for probe response time */ -#define CW_MIN_IN_BITS 4 /* actual CwMin = 2^CW_MIN_IN_BITS - 1 */ -#define LINK_DOWN_TIMEOUT 20000 /* unit: msec */ -#define AUTO_WAKEUP_TIMEOUT 70 /*unit: msec */ - -#define CW_MAX_IN_BITS 10 /* actual CwMax = 2^CW_MAX_IN_BITS - 1 */ - -/* Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). */ -/* Should not refer to this constant anymore */ -/*#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm */ -#define RSSI_FOR_MID_TX_POWER -55 /* -55 db is considered mid-distance */ -#define RSSI_FOR_LOW_TX_POWER -45 /* -45 db is considered very short distance and */ - /* eligible to use a lower TX power */ -#define RSSI_FOR_LOWEST_TX_POWER -30 -/*#define MID_TX_POWER_DELTA 0 // 0 db from full TX power upon mid-distance to AP */ -#define LOW_TX_POWER_DELTA 6 /* -3 db from full TX power upon very short distance. 1 grade is 0.5 db */ -#define LOWEST_TX_POWER_DELTA 16 /* -8 db from full TX power upon shortest distance. 1 grade is 0.5 db */ - -#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD 0 -#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD 1 -#define RSSI_THRESHOLD_FOR_ROAMING 25 -#define RSSI_DELTA 5 - -/* Channel Quality Indication */ -#define CQI_IS_GOOD(cqi) ((cqi) >= 50) -/*#define CQI_IS_FAIR(cqi) (((cqi) >= 20) && ((cqi) < 50)) */ -#define CQI_IS_POOR(cqi) (cqi < 50) /*(((cqi) >= 5) && ((cqi) < 20)) */ -#define CQI_IS_BAD(cqi) (cqi < 5) -#define CQI_IS_DEAD(cqi) (cqi == 0) - -/* weighting factor to calculate Channel quality, total should be 100% */ -#define RSSI_WEIGHTING 50 -#define TX_WEIGHTING 30 -#define RX_WEIGHTING 20 - -#define BSS_NOT_FOUND 0xFFFFFFFF - -#define MAX_LEN_OF_MLME_QUEUE 40 /*10 */ - -#define SCAN_PASSIVE 18 /* scan with no probe request, only wait beacon and probe response */ -#define SCAN_ACTIVE 19 /* scan with probe request, and wait beacon and probe response */ -#define SCAN_CISCO_PASSIVE 20 /* Single channel passive scan */ -#define SCAN_CISCO_ACTIVE 21 /* Single channel active scan */ -#define SCAN_CISCO_NOISE 22 /* Single channel passive scan for noise histogram collection */ -#define SCAN_CISCO_CHANNEL_LOAD 23 /* Single channel passive scan for channel load collection */ -#define FAST_SCAN_ACTIVE 24 /* scan with probe request, and wait beacon and probe response */ - -#define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01)) -#define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5]) -#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE) -#define TID_MAC_HASH(Addr, TID) (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5]) -#define TID_MAC_HASH_INDEX(Addr, TID) (TID_MAC_HASH(Addr, TID) % HASH_TABLE_SIZE) - -/* LED Control */ -/* association ON. one LED ON. another blinking when TX, OFF when idle */ -/* no association, both LED off */ -#define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46) -#define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46) - -/* bit definition of the 2-byte pBEACON->Capability field */ -#define CAP_IS_ESS_ON(x) (((x) & 0x0001) != 0) -#define CAP_IS_IBSS_ON(x) (((x) & 0x0002) != 0) -#define CAP_IS_CF_POLLABLE_ON(x) (((x) & 0x0004) != 0) -#define CAP_IS_CF_POLL_REQ_ON(x) (((x) & 0x0008) != 0) -#define CAP_IS_PRIVACY_ON(x) (((x) & 0x0010) != 0) -#define CAP_IS_SHORT_PREAMBLE_ON(x) (((x) & 0x0020) != 0) -#define CAP_IS_PBCC_ON(x) (((x) & 0x0040) != 0) -#define CAP_IS_AGILITY_ON(x) (((x) & 0x0080) != 0) -#define CAP_IS_SPECTRUM_MGMT(x) (((x) & 0x0100) != 0) /* 802.11e d9 */ -#define CAP_IS_QOS(x) (((x) & 0x0200) != 0) /* 802.11e d9 */ -#define CAP_IS_SHORT_SLOT(x) (((x) & 0x0400) != 0) -#define CAP_IS_APSD(x) (((x) & 0x0800) != 0) /* 802.11e d9 */ -#define CAP_IS_IMMED_BA(x) (((x) & 0x1000) != 0) /* 802.11e d9 */ -#define CAP_IS_DSSS_OFDM(x) (((x) & 0x2000) != 0) -#define CAP_IS_DELAY_BA(x) (((x) & 0x4000) != 0) /* 802.11e d9 */ - -#define CAP_GENERATE(ess, ibss, priv, s_pre, s_slot, spectrum) (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000)) - -#define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) /* 802.11g */ -#define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) /* 802.11g */ -#define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) /* 802.11g */ - -#define DRS_TX_QUALITY_WORST_BOUND 8 /* 3 // just test by gary */ -#define DRS_PENALTY 8 - -#define BA_NOTUSE 2 -/*BA Policy subfiled value in ADDBA frame */ -#define IMMED_BA 1 -#define DELAY_BA 0 - -/* BA Initiator subfield in DELBA frame */ -#define ORIGINATOR 1 -#define RECIPIENT 0 - -/* ADDBA Status Code */ -#define ADDBA_RESULTCODE_SUCCESS 0 -#define ADDBA_RESULTCODE_REFUSED 37 -#define ADDBA_RESULTCODE_INVALID_PARAMETERS 38 - -/* DELBA Reason Code */ -#define DELBA_REASONCODE_QSTA_LEAVING 36 -#define DELBA_REASONCODE_END_BA 37 -#define DELBA_REASONCODE_UNKNOWN_BA 38 -#define DELBA_REASONCODE_TIMEOUT 39 - -/* reset all OneSecTx counters */ -#define RESET_ONE_SEC_TX_CNT(__pEntry) \ -if (((__pEntry)) != NULL) { \ - (__pEntry)->OneSecTxRetryOkCount = 0; \ - (__pEntry)->OneSecTxFailCount = 0; \ - (__pEntry)->OneSecTxNoRetryOkCount = 0; \ -} - -/* */ -/* 802.11 frame formats */ -/* */ -/* HT Capability INFO field in HT Cap IE . */ -struct PACKED rt_ht_cap_info { - u16 AdvCoding:1; - u16 ChannelWidth:1; - u16 MimoPs:2; /*momi power safe */ - u16 GF:1; /*green field */ - u16 ShortGIfor20:1; - u16 ShortGIfor40:1; /*for40MHz */ - u16 TxSTBC:1; - u16 RxSTBC:2; - u16 DelayedBA:1; /*rt2860c not support */ - u16 AMsduSize:1; /* only support as zero */ - u16 CCKmodein40:1; - u16 PSMP:1; - u16 Forty_Mhz_Intolerant:1; - u16 LSIGTxopProSup:1; -}; - -/* HT Capability INFO field in HT Cap IE . */ -struct PACKED rt_ht_cap_parm { - u8 MaxRAmpduFactor:2; - u8 MpduDensity:3; - u8 rsv:3; /*momi power safe */ -}; - -/* HT Capability INFO field in HT Cap IE . */ -struct PACKED rt_ht_mcs_set { - u8 MCSSet[10]; - u8 SupRate[2]; /* unit : 1Mbps */ - u8 TxMCSSetDefined:1; - u8 TxRxNotEqual:1; - u8 TxStream:2; - u8 MpduDensity:1; - u8 rsv:3; - u8 rsv3[3]; -}; - -/* HT Capability INFO field in HT Cap IE . */ -struct PACKED rt_ext_ht_cap_info { - u16 Pco:1; - u16 TranTime:2; - u16 rsv:5; /*momi power safe */ - u16 MCSFeedback:2; /*0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv. */ - u16 PlusHTC:1; /*+HTC control field support */ - u16 RDGSupport:1; /*reverse Direction Grant support */ - u16 rsv2:4; -}; - -/* HT Beamforming field in HT Cap IE . */ -struct PACKED rt_ht_bf_cap { - unsigned long TxBFRecCapable:1; - unsigned long RxSoundCapable:1; - unsigned long TxSoundCapable:1; - unsigned long RxNDPCapable:1; - unsigned long TxNDPCapable:1; - unsigned long ImpTxBFCapable:1; - unsigned long Calibration:2; - unsigned long ExpCSICapable:1; - unsigned long ExpNoComSteerCapable:1; - unsigned long ExpComSteerCapable:1; - unsigned long ExpCSIFbk:2; - unsigned long ExpNoComBF:2; - unsigned long ExpComBF:2; - unsigned long MinGrouping:2; - unsigned long CSIBFAntSup:2; - unsigned long NoComSteerBFAntSup:2; - unsigned long ComSteerBFAntSup:2; - unsigned long CSIRowBFSup:2; - unsigned long ChanEstimation:2; - unsigned long rsv:3; -}; - -/* HT antenna selection field in HT Cap IE . */ -struct PACKED rt_ht_as_cap { - u8 AntSelect:1; - u8 ExpCSIFbkTxASEL:1; - u8 AntIndFbkTxASEL:1; - u8 ExpCSIFbk:1; - u8 AntIndFbk:1; - u8 RxASel:1; - u8 TxSoundPPDU:1; - u8 rsv:1; -}; - -/* Draft 1.0 set IE length 26, but is extensible.. */ -#define SIZE_HT_CAP_IE 26 -/* The structure for HT Capability IE. */ -struct PACKED rt_ht_capability_ie { - struct rt_ht_cap_info HtCapInfo; - struct rt_ht_cap_parm HtCapParm; -/* struct rt_ht_mcs_set HtMCSSet; */ - u8 MCSSet[16]; - struct rt_ext_ht_cap_info ExtHtCapInfo; - struct rt_ht_bf_cap TxBFCap; /* beamforming cap. rt2860c not support beamforming. */ - struct rt_ht_as_cap ASCap; /*antenna selection. */ -}; - -/* 802.11n draft3 related structure definitions. */ -/* 7.3.2.60 */ -#define dot11OBSSScanPassiveDwell 20 /* in TU. min amount of time that the STA continuously scans each channel when performing an active OBSS scan. */ -#define dot11OBSSScanActiveDwell 10 /* in TU.min amount of time that the STA continuously scans each channel when performing an passive OBSS scan. */ -#define dot11BSSWidthTriggerScanInterval 300 /* in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. */ -#define dot11OBSSScanPassiveTotalPerChannel 200 /* in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. */ -#define dot11OBSSScanActiveTotalPerChannel 20 /*in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan */ -#define dot11BSSWidthChannelTransactionDelayFactor 5 /* min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum */ - /* interval between overlapping BSS scan operations. */ -#define dot11BSSScanActivityThreshold 25 /* in %%, max total time that a STA may be active on the medium during a period of */ - /* (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without */ - /* being obligated to perform OBSS Scan operations. default is 25(== 0.25%) */ - -struct PACKED rt_overlap_bss_scan_ie { - u16 ScanPassiveDwell; - u16 ScanActiveDwell; - u16 TriggerScanInt; /* Trigger scan interval */ - u16 PassiveTalPerChannel; /* passive total per channel */ - u16 ActiveTalPerChannel; /* active total per channel */ - u16 DelayFactor; /* BSS width channel transition delay factor */ - u16 ScanActThre; /* Scan Activity threshold */ -}; - -/* 7.3.2.56. 20/40 Coexistence element used in Element ID = 72 = IE_2040_BSS_COEXIST */ -typedef union PACKED _BSS_2040_COEXIST_IE { - struct PACKED { - u8 InfoReq:1; - u8 Intolerant40:1; /* Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS. */ - u8 BSS20WidthReq:1; /* Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS. */ - u8 rsv:5; - } field; - u8 word; -} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE; - -struct rt_trigger_eventa { - BOOLEAN bValid; - u8 BSSID[6]; - u8 RegClass; /* Regulatory Class */ - u16 Channel; - unsigned long CDCounter; /* Maintain a separate count down counter for each Event A. */ -}; - -/* 20/40 trigger event table */ -/* If one Event (A) is deleted or created, or if Event (B) is detected or not detected, STA should send 2040BSSCoexistence to AP. */ -#define MAX_TRIGGER_EVENT 64 -struct rt_trigger_event_tab { - u8 EventANo; - struct rt_trigger_eventa EventA[MAX_TRIGGER_EVENT]; - unsigned long EventBCountDown; /* Count down counter for Event B. */ -}; - -/* 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY). */ -/* This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0 */ -struct PACKED rt_ext_cap_info_element { - u8 BssCoexistMgmtSupport:1; - u8 rsv:1; - u8 ExtendChannelSwitch:1; - u8 rsv2:5; -}; - -/* 802.11n 7.3.2.61 */ -struct PACKED rt_bss_2040_coexist_element { - u8 ElementID; /* ID = IE_2040_BSS_COEXIST = 72 */ - u8 Len; - BSS_2040_COEXIST_IE BssCoexistIe; -}; - -/*802.11n 7.3.2.59 */ -struct PACKED rt_bss_2040_intolerant_ch_report { - u8 ElementID; /* ID = IE_2040_BSS_INTOLERANT_REPORT = 73 */ - u8 Len; - u8 RegulatoryClass; - u8 ChList[0]; -}; - -/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */ -struct PACKED rt_cha_switch_announce_ie { - u8 SwitchMode; /*channel switch mode */ - u8 NewChannel; /* */ - u8 SwitchCount; /* */ -}; - -/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */ -struct PACKED rt_sec_cha_offset_ie { - u8 SecondaryChannelOffset; /* 1: Secondary above, 3: Secondary below, 0: no Secondary */ -}; - -/* This structure is extracted from struct struct rt_ht_capability */ -struct rt_ht_phy_info { - BOOLEAN bHtEnable; /* If we should use ht rate. */ - BOOLEAN bPreNHt; /* If we should use ht rate. */ - /*Subtract from HT Capability IE */ - u8 MCSSet[16]; -}; - -/*This structure subtracts ralink supports from all 802.11n-related features. */ -/*Features not listed here but contained in 802.11n spec are not supported in rt2860. */ -struct rt_ht_capability { - u16 ChannelWidth:1; - u16 MimoPs:2; /*mimo power safe MMPS_ */ - u16 GF:1; /*green field */ - u16 ShortGIfor20:1; - u16 ShortGIfor40:1; /*for40MHz */ - u16 TxSTBC:1; - u16 RxSTBC:2; /* 2 bits */ - u16 AmsduEnable:1; /* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benefit of 802.11n */ - u16 AmsduSize:1; /* Max receiving A-MSDU size */ - u16 rsv:5; - - /*Subtract from Addiont HT INFO IE */ - u8 MaxRAmpduFactor:2; - u8 MpduDensity:3; - u8 ExtChanOffset:2; /* Please note the difference with following u8 NewExtChannelOffset; from 802.11n */ - u8 RecomWidth:1; - - u16 OperaionMode:2; - u16 NonGfPresent:1; - u16 rsv3:1; - u16 OBSS_NonHTExist:1; - u16 rsv2:11; - - /* New Extension Channel Offset IE */ - u8 NewExtChannelOffset; - /* Extension Capability IE = 127 */ - u8 BSSCoexist2040; -}; - -/* field in Additional HT Information IE . */ -struct PACKED rt_add_htinfo { - u8 ExtChanOffset:2; - u8 RecomWidth:1; - u8 RifsMode:1; - u8 S_PSMPSup:1; /*Indicate support for scheduled PSMP */ - u8 SerInterGranu:3; /*service interval granularity */ -}; - -struct PACKED rt_add_htinfo2 { - u16 OperaionMode:2; - u16 NonGfPresent:1; - u16 rsv:1; - u16 OBSS_NonHTExist:1; - u16 rsv2:11; -}; - -/* TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved. */ -struct PACKED rt_add_htinfo3 { - u16 StbcMcs:6; - u16 DualBeacon:1; - u16 DualCTSProtect:1; - u16 STBCBeacon:1; - u16 LsigTxopProt:1; /* L-SIG TXOP protection full support */ - u16 PcoActive:1; - u16 PcoPhase:1; - u16 rsv:4; -}; - -#define SIZE_ADD_HT_INFO_IE 22 -struct PACKED rt_add_ht_info_ie { - u8 ControlChan; - struct rt_add_htinfo AddHtInfo; - struct rt_add_htinfo2 AddHtInfo2; - struct rt_add_htinfo3 AddHtInfo3; - u8 MCSSet[16]; /* Basic MCS set */ -}; - -struct PACKED rt_new_ext_chan_ie { - u8 NewExtChanOffset; -}; - -struct PACKED rt_frame_802_11 { - struct rt_header_802_11 Hdr; - u8 Octet[1]; -}; - -/* QoSNull embedding of management action. When HT Control MA field set to 1. */ -struct PACKED rt_ma_body { - u8 Category; - u8 Action; - u8 Octet[1]; -}; - -struct PACKED rt_header_802_3 { - u8 DAAddr1[MAC_ADDR_LEN]; - u8 SAAddr2[MAC_ADDR_LEN]; - u8 Octet[2]; -}; -/*//Block ACK related format */ -/* 2-byte BA Parameter field in DELBA frames to terminate an already set up bA */ -struct PACKED rt_delba_parm { - u16 Rsv:11; /* always set to 0 */ - u16 Initiator:1; /* 1: originator 0:recipient */ - u16 TID:4; /* value of TC os TS */ -}; - -/* 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA */ -struct PACKED rt_ba_parm { - u16 AMSDUSupported:1; /* 0: not permitted 1: permitted */ - u16 BAPolicy:1; /* 1: immediately BA 0:delayed BA */ - u16 TID:4; /* value of TC os TS */ - u16 BufSize:10; /* number of buffer of size 2304 octetsr */ -}; - -/* 2-byte BA Starting Seq CONTROL field */ -typedef union PACKED _BASEQ_CONTROL { - struct PACKED { - u16 FragNum:4; /* always set to 0 */ - u16 StartSeq:12; /* sequence number of the 1st MSDU for which this BAR is sent */ - } field; - u16 word; -} BASEQ_CONTROL, *PBASEQ_CONTROL; - -/*BAControl and BARControl are the same */ -/* 2-byte BA CONTROL field in BA frame */ -struct PACKED rt_ba_control { - u16 ACKPolicy:1; /* only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK */ - u16 MTID:1; /*EWC V1.24 */ - u16 Compressed:1; - u16 Rsv:9; - u16 TID:4; -}; - -/* 2-byte BAR CONTROL field in BAR frame */ -struct PACKED rt_bar_control { - u16 ACKPolicy:1; /* 0:normal ack, 1:no ack. */ - u16 MTID:1; /*if this bit1, use struct rt_frame_mtba_req, if 0, use struct rt_frame_ba_req */ - u16 Compressed:1; - u16 Rsv1:9; - u16 TID:4; -}; - -/* BARControl in MTBAR frame */ -struct PACKED rt_mtbar_control { - u16 ACKPolicy:1; - u16 MTID:1; - u16 Compressed:1; - u16 Rsv1:9; - u16 NumTID:4; -}; - -struct PACKED rt_per_tid_info { - u16 Rsv1:12; - u16 TID:4; -}; - -struct rt_each_tid { - struct rt_per_tid_info PerTID; - BASEQ_CONTROL BAStartingSeq; -}; - -/* BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap. */ -struct PACKED rt_frame_ba_req { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; - struct rt_bar_control BARControl; - BASEQ_CONTROL BAStartingSeq; -}; - -struct PACKED rt_frame_mtba_req { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; - struct rt_mtbar_control MTBARControl; - struct rt_per_tid_info PerTIDInfo; - BASEQ_CONTROL BAStartingSeq; -}; - -/* Compressed format is mandatory in HT STA */ -struct PACKED rt_frame_mtba { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; - struct rt_ba_control BAControl; - BASEQ_CONTROL BAStartingSeq; - u8 BitMap[8]; -}; - -struct PACKED rt_frame_psmp_action { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - u8 Psmp; /* 7.3.1.25 */ -}; - -struct PACKED rt_frame_action_hdr { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; -}; - -/*Action Frame */ -/*Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20 */ -struct PACKED rt_chan_switch_announce { - u8 ElementID; /* ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37 */ - u8 Len; - struct rt_cha_switch_announce_ie CSAnnounceIe; -}; - -/*802.11n : 7.3.2.20a */ -struct PACKED rt_second_chan_offset { - u8 ElementID; /* ID = IE_SECONDARY_CH_OFFSET = 62 */ - u8 Len; - struct rt_sec_cha_offset_ie SecChOffsetIe; -}; - -struct PACKED rt_frame_spetrum_cs { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - struct rt_chan_switch_announce CSAnnounce; - struct rt_second_chan_offset SecondChannel; -}; - -struct PACKED rt_frame_addba_req { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - u8 Token; /* 1 */ - struct rt_ba_parm BaParm; /* 2 - 10 */ - u16 TimeOutValue; /* 0 - 0 */ - BASEQ_CONTROL BaStartSeq; /* 0-0 */ -}; - -struct PACKED rt_frame_addba_rsp { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - u8 Token; - u16 StatusCode; - struct rt_ba_parm BaParm; /*0 - 2 */ - u16 TimeOutValue; -}; - -struct PACKED rt_frame_delba_req { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - struct rt_delba_parm DelbaParm; - u16 ReasonCode; -}; - -/*7.2.1.7 */ -struct PACKED rt_frame_bar { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; - struct rt_bar_control BarControl; - BASEQ_CONTROL StartingSeq; -}; - -/*7.2.1.7 */ -struct PACKED rt_frame_ba { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; - struct rt_bar_control BarControl; - BASEQ_CONTROL StartingSeq; - u8 bitmask[8]; -}; - -/* Radio Measurement Request Frame Format */ -struct PACKED rt_frame_rm_req_action { - struct rt_header_802_11 Hdr; - u8 Category; - u8 Action; - u8 Token; - u16 Repetition; - u8 data[0]; -}; - -struct PACKED rt_ht_ext_channel_switch_announcement_ie { - u8 ID; - u8 Length; - u8 ChannelSwitchMode; - u8 NewRegClass; - u8 NewChannelNum; - u8 ChannelSwitchCount; -}; - -/* */ -/* _Limit must be the 2**n - 1 */ -/* _SEQ1 , _SEQ2 must be within 0 ~ _Limit */ -/* */ -#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit))) -#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1))) -#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))) -#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \ - SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit)) - -/* */ -/* Contention-free parameter (without ID and Length) */ -/* */ -struct PACKED rt_cf_parm { - BOOLEAN bValid; /* 1: variable contains valid value */ - u8 CfpCount; - u8 CfpPeriod; - u16 CfpMaxDuration; - u16 CfpDurRemaining; -}; - -struct rt_cipher_suite { - NDIS_802_11_ENCRYPTION_STATUS PairCipher; /* Unicast cipher 1, this one has more secured cipher suite */ - NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; /* Unicast cipher 2 if AP announce two unicast cipher suite */ - NDIS_802_11_ENCRYPTION_STATUS GroupCipher; /* Group cipher */ - u16 RsnCapability; /* RSN capability from beacon */ - BOOLEAN bMixMode; /* Indicate Pair & Group cipher might be different */ -}; - -/* EDCA configuration from AP's BEACON/ProbeRsp */ -struct rt_edca_parm { - BOOLEAN bValid; /* 1: variable contains valid value */ - BOOLEAN bAdd; /* 1: variable contains valid value */ - BOOLEAN bQAck; - BOOLEAN bQueueRequest; - BOOLEAN bTxopRequest; - BOOLEAN bAPSDCapable; -/* BOOLEAN bMoreDataAck; */ - u8 EdcaUpdateCount; - u8 Aifsn[4]; /* 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO */ - u8 Cwmin[4]; - u8 Cwmax[4]; - u16 Txop[4]; /* in unit of 32-us */ - BOOLEAN bACM[4]; /* 1: Admission Control of AC_BK is mandatory */ -}; - -/* QBSS LOAD information from QAP's BEACON/ProbeRsp */ -struct rt_qbss_load_parm { - BOOLEAN bValid; /* 1: variable contains valid value */ - u16 StaNum; - u8 ChannelUtilization; - u16 RemainingAdmissionControl; /* in unit of 32-us */ -}; - -/* QBSS Info field in QSTA's assoc req */ -struct PACKED rt_qbss_sta_info_parm { - u8 UAPSD_AC_VO:1; - u8 UAPSD_AC_VI:1; - u8 UAPSD_AC_BK:1; - u8 UAPSD_AC_BE:1; - u8 Rsv1:1; - u8 MaxSPLength:2; - u8 Rsv2:1; -}; - -/* QBSS Info field in QAP's Beacon/ProbeRsp */ -struct PACKED rt_qbss_ap_info_parm { - u8 ParamSetCount:4; - u8 Rsv:3; - u8 UAPSD:1; -}; - -/* QOS Capability reported in QAP's BEACON/ProbeRsp */ -/* QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq */ -struct rt_qos_capability_parm { - BOOLEAN bValid; /* 1: variable contains valid value */ - BOOLEAN bQAck; - BOOLEAN bQueueRequest; - BOOLEAN bTxopRequest; -/* BOOLEAN bMoreDataAck; */ - u8 EdcaUpdateCount; -}; - -struct rt_wpa_ie { - u8 IELen; - u8 IE[MAX_CUSTOM_LEN]; -}; - -struct rt_bss_entry { - u8 Bssid[MAC_ADDR_LEN]; - u8 Channel; - u8 CentralChannel; /*Store the wide-band central channel for 40MHz. used in 40MHz AP. Or this is the same as Channel. */ - u8 BssType; - u16 AtimWin; - u16 BeaconPeriod; - - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 ExtRateLen; - struct rt_ht_capability_ie HtCapability; - u8 HtCapabilityLen; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 AddHtInfoLen; - u8 NewExtChanOffset; - char Rssi; - u8 Privacy; /* Indicate security function ON/OFF. Don't mess up with auth mode. */ - u8 Hidden; - - u16 DtimPeriod; - u16 CapabilityInfo; - - u16 CfpCount; - u16 CfpPeriod; - u16 CfpMaxDuration; - u16 CfpDurRemaining; - u8 SsidLen; - char Ssid[MAX_LEN_OF_SSID]; - - unsigned long LastBeaconRxTime; /* OS's timestamp */ - - BOOLEAN bSES; - - /* New for WPA2 */ - struct rt_cipher_suite WPA; /* AP announced WPA cipher suite */ - struct rt_cipher_suite WPA2; /* AP announced WPA2 cipher suite */ - - /* New for microsoft WPA support */ - struct rt_ndis_802_11_fixed_ies FixIEs; - NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; /* Addition mode for WPA2 / WPA capable AP */ - NDIS_802_11_AUTHENTICATION_MODE AuthMode; - NDIS_802_11_WEP_STATUS WepStatus; /* Unicast Encryption Algorithm extract from VAR_IE */ - u16 VarIELen; /* Length of next VIE include EID & Length */ - u8 VarIEs[MAX_VIE_LEN]; - - /* CCX Ckip information */ - u8 CkipFlag; - - /* CCX 2 TSF */ - u8 PTSF[4]; /* Parent TSF */ - u8 TTSF[8]; /* Target TSF */ - - /* 802.11e d9, and WMM */ - struct rt_edca_parm EdcaParm; - struct rt_qos_capability_parm QosCapability; - struct rt_qbss_load_parm QbssLoad; - struct rt_wpa_ie WpaIE; - struct rt_wpa_ie RsnIE; -}; - -struct rt_bss_table { - u8 BssNr; - u8 BssOverlapNr; - struct rt_bss_entry BssEntry[MAX_LEN_OF_BSS_TABLE]; -}; - -struct rt_mlme_queue_elem { - unsigned long Machine; - unsigned long MsgType; - unsigned long MsgLen; - u8 Msg[MGMT_DMA_BUFFER_SIZE]; - LARGE_INTEGER TimeStamp; - u8 Rssi0; - u8 Rssi1; - u8 Rssi2; - u8 Signal; - u8 Channel; - u8 Wcid; - BOOLEAN Occupied; -}; - -struct rt_mlme_queue { - unsigned long Num; - unsigned long Head; - unsigned long Tail; - spinlock_t Lock; - struct rt_mlme_queue_elem Entry[MAX_LEN_OF_MLME_QUEUE]; -}; - -typedef void(*STATE_MACHINE_FUNC) (void *Adaptor, struct rt_mlme_queue_elem *Elem); - -struct rt_state_machine { - unsigned long Base; - unsigned long NrState; - unsigned long NrMsg; - unsigned long CurrState; - STATE_MACHINE_FUNC *TransFunc; -}; - -/* MLME AUX data structure that holds temporarliy settings during a connection attempt. */ -/* Once this attempt succeeds, all settings will be copy to pAd->StaActive. */ -/* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */ -/* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */ -/* separate this under-trial settings away from pAd->StaActive so that once */ -/* this new attempt failed, driver can auto-recover back to the active settings. */ -struct rt_mlme_aux { - u8 BssType; - u8 Ssid[MAX_LEN_OF_SSID]; - u8 SsidLen; - u8 Bssid[MAC_ADDR_LEN]; - u8 AutoReconnectSsid[MAX_LEN_OF_SSID]; - u8 AutoReconnectSsidLen; - u16 Alg; - u8 ScanType; - u8 Channel; - u8 CentralChannel; - u16 Aid; - u16 CapabilityInfo; - u16 BeaconPeriod; - u16 CfpMaxDuration; - u16 CfpPeriod; - u16 AtimWin; - - /* Copy supported rate from desired AP's beacon. We are trying to match */ - /* AP's supported and extended rate settings. */ - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen; - u8 ExtRateLen; - struct rt_ht_capability_ie HtCapability; - u8 HtCapabilityLen; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 NewExtChannelOffset; - /*struct rt_ht_capability SupportedHtPhy; */ - - /* new for QOS */ - struct rt_qos_capability_parm APQosCapability; /* QOS capability of the current associated AP */ - struct rt_edca_parm APEdcaParm; /* EDCA parameters of the current associated AP */ - struct rt_qbss_load_parm APQbssLoad; /* QBSS load of the current associated AP */ - - /* new to keep Ralink specific feature */ - unsigned long APRalinkIe; - - struct rt_bss_table SsidBssTab; /* AP list for the same SSID */ - struct rt_bss_table RoamTab; /* AP list eligible for roaming */ - unsigned long BssIdx; - unsigned long RoamIdx; - - BOOLEAN CurrReqIsFromNdis; - - struct rt_ralink_timer BeaconTimer, ScanTimer; - struct rt_ralink_timer AuthTimer; - struct rt_ralink_timer AssocTimer, ReassocTimer, DisassocTimer; -}; - -struct rt_mlme_addba_req { - u8 Wcid; /* */ - u8 pAddr[MAC_ADDR_LEN]; - u8 BaBufSize; - u16 TimeOutValue; - u8 TID; - u8 Token; - u16 BaStartSeq; -}; - -struct rt_mlme_delba_req { - u8 Wcid; /* */ - u8 Addr[MAC_ADDR_LEN]; - u8 TID; - u8 Initiator; -}; - -/* assoc struct is equal to reassoc */ -struct rt_mlme_assoc_req { - u8 Addr[MAC_ADDR_LEN]; - u16 CapabilityInfo; - u16 ListenIntv; - unsigned long Timeout; -}; - -struct rt_mlme_disassoc_req { - u8 Addr[MAC_ADDR_LEN]; - u16 Reason; -}; - -struct rt_mlme_auth_req { - u8 Addr[MAC_ADDR_LEN]; - u16 Alg; - unsigned long Timeout; -}; - -struct rt_mlme_deauth_req { - u8 Addr[MAC_ADDR_LEN]; - u16 Reason; -}; - -struct rt_mlme_join_req { - unsigned long BssIdx; -}; - -struct rt_mlme_scan_req { - u8 Bssid[MAC_ADDR_LEN]; - u8 BssType; - u8 ScanType; - u8 SsidLen; - char Ssid[MAX_LEN_OF_SSID]; -}; - -struct rt_mlme_start_req { - char Ssid[MAX_LEN_OF_SSID]; - u8 SsidLen; -}; - -struct PACKED rt_eid { - u8 Eid; - u8 Len; - u8 Octet[1]; -}; - -struct PACKED rt_rtmp_tx_rate_switch { - u8 ItemNo; - u8 STBC:1; - u8 ShortGI:1; - u8 BW:1; - u8 Rsv1:1; - u8 Mode:2; - u8 Rsv2:2; - u8 CurrMCS; - u8 TrainUp; - u8 TrainDown; -}; - -/* ========================== AP mlme.h =============================== */ -#define TBTT_PRELOAD_TIME 384 /* usec. LomgPreamble + 24-byte at 1Mbps */ -#define DEFAULT_DTIM_PERIOD 1 - -#define MAC_TABLE_AGEOUT_TIME 300 /* unit: sec */ -#define MAC_TABLE_ASSOC_TIMEOUT 5 /* unit: sec */ -#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE) - -/* AP shall drop the sta if continue Tx fail count reach it. */ -#define MAC_ENTRY_LIFE_CHECK_CNT 20 /* packet cnt. */ - -/* Value domain of pMacEntry->Sst */ -typedef enum _Sst { - SST_NOT_AUTH, /* 0: equivalent to IEEE 802.11/1999 state 1 */ - SST_AUTH, /* 1: equivalent to IEEE 802.11/1999 state 2 */ - SST_ASSOC /* 2: equivalent to IEEE 802.11/1999 state 3 */ -} SST; - -/* value domain of pMacEntry->AuthState */ -typedef enum _AuthState { - AS_NOT_AUTH, - AS_AUTH_OPEN, /* STA has been authenticated using OPEN SYSTEM */ - AS_AUTH_KEY, /* STA has been authenticated using SHARED KEY */ - AS_AUTHENTICATING /* STA is waiting for AUTH seq#3 using SHARED KEY */ -} AUTH_STATE; - -/*for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114 */ -typedef enum _ApWpaState { - AS_NOTUSE, /* 0 */ - AS_DISCONNECT, /* 1 */ - AS_DISCONNECTED, /* 2 */ - AS_INITIALIZE, /* 3 */ - AS_AUTHENTICATION, /* 4 */ - AS_AUTHENTICATION2, /* 5 */ - AS_INITPMK, /* 6 */ - AS_INITPSK, /* 7 */ - AS_PTKSTART, /* 8 */ - AS_PTKINIT_NEGOTIATING, /* 9 */ - AS_PTKINITDONE, /* 10 */ - AS_UPDATEKEYS, /* 11 */ - AS_INTEGRITY_FAILURE, /* 12 */ - AS_KEYUPDATE, /* 13 */ -} AP_WPA_STATE; - -/* for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114 */ -typedef enum _GTKState { - REKEY_NEGOTIATING, - REKEY_ESTABLISHED, - KEYERROR, -} GTK_STATE; - -/* for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114 */ -typedef enum _WpaGTKState { - SETKEYS, - SETKEYS_DONE, -} WPA_GTK_STATE; -/* ====================== end of AP mlme.h ============================ */ - -#endif /* MLME_H__ */ diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h deleted file mode 100644 index 5a25f0d3cfeb..000000000000 --- a/drivers/staging/rt2860/oid.h +++ /dev/null @@ -1,779 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - oid.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Justin P. Mattock 11/07/2010 Fix typos in comments -*/ -#ifndef _OID_H_ -#define _OID_H_ - -/*#include */ - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif -/* */ -/* IEEE 802.11 Structures and definitions */ -/* */ -#define MAX_TX_POWER_LEVEL 100 /* mW */ -#define MAX_RSSI_TRIGGER -10 /* dBm */ -#define MIN_RSSI_TRIGGER -200 /* dBm */ -#define MAX_FRAG_THRESHOLD 2346 /* byte count */ -#define MIN_FRAG_THRESHOLD 256 /* byte count */ -#define MAX_RTS_THRESHOLD 2347 /* byte count */ - -/* new types for Media Specific Indications */ -/* Extension channel offset */ -#define EXTCHA_NONE 0 -#define EXTCHA_ABOVE 0x1 -#define EXTCHA_BELOW 0x3 - -/* BW */ -#define BAND_WIDTH_20 0 -#define BAND_WIDTH_40 1 -#define BAND_WIDTH_BOTH 2 -#define BAND_WIDTH_10 3 /* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */ -/* SHORTGI */ -#define GAP_INTERVAL_400 1 /* only support in HT mode */ -#define GAP_INTERVAL_800 0 -#define GAP_INTERVAL_BOTH 2 - -#define NdisMediaStateConnected 1 -#define NdisMediaStateDisconnected 0 - -#define NDIS_802_11_LENGTH_SSID 32 -#define NDIS_802_11_LENGTH_RATES 8 -#define NDIS_802_11_LENGTH_RATES_EX 16 -#define MAC_ADDR_LENGTH 6 -/*#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */ -#define MAX_NUM_OF_CHS 54 /* 14 channels @2.4G + 12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination */ -#define MAX_NUMBER_OF_EVENT 10 /* entry # in EVENT table */ -#define MAX_NUMBER_OF_MAC 32 /* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */ -#define MAX_NUMBER_OF_ACL 64 -#define MAX_LENGTH_OF_SUPPORT_RATES 12 /* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ -#define MAX_NUMBER_OF_DLS_ENTRY 4 - -#define RT_QUERY_SIGNAL_CONTEXT 0x0402 -#define RT_SET_IAPP_PID 0x0404 -#define RT_SET_APD_PID 0x0405 -#define RT_SET_DEL_MAC_ENTRY 0x0406 -#define RT_QUERY_EVENT_TABLE 0x0407 -/* */ -/* IEEE 802.11 OIDs */ -/* */ -#define OID_GET_SET_TOGGLE 0x8000 -#define OID_GET_SET_FROM_UI 0x4000 - -#define OID_802_11_ADD_WEP 0x0112 -#define OID_802_11_DISASSOCIATE 0x0114 -#define OID_802_11_BSSID_LIST_SCAN 0x0508 -#define OID_802_11_SSID 0x0509 -#define OID_802_11_BSSID 0x050A -#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528 - -#define RT_OID_DEVICE_NAME 0x0607 -#define RT_OID_VERSION_INFO 0x0608 -#define OID_802_11_BSSID_LIST 0x0609 -#define OID_802_3_CURRENT_ADDRESS 0x060A -#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B -#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C -#define OID_802_11_RSSI 0x060D -#define OID_802_11_STATISTICS 0x060E -#define OID_GEN_RCV_OK 0x060F -#define OID_GEN_RCV_NO_BUFFER 0x0610 -#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611 -#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612 -#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613 -#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614 -#define RT_OID_802_11_QUERY_PIDVID 0x0615 -/*for WPA_SUPPLICANT_SUPPORT */ -#define OID_SET_COUNTERMEASURES 0x0616 -#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621 -#define RT_OID_WE_VERSION_COMPILED 0x0622 -#define RT_OID_NEW_DRIVER 0x0623 - -#define RT_OID_DRIVER_DEVICE_NAME 0x0645 -#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647 - -typedef enum _NDIS_802_11_STATUS_TYPE { - Ndis802_11StatusType_Authentication, - Ndis802_11StatusType_MediaStreamMode, - Ndis802_11StatusType_PMKID_CandidateList, - Ndis802_11StatusTypeMax /* not a real type, defined as an upper bound */ -} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; - -typedef u8 NDIS_802_11_MAC_ADDRESS[6]; - -struct rt_ndis_802_11_status_indication { - NDIS_802_11_STATUS_TYPE StatusType; -}; - -/* mask for authentication/integrity fields */ -#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f - -#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 -#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 -#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E - -struct rt_ndis_802_11_authentication_request { - unsigned long Length; /* Length of structure */ - NDIS_802_11_MAC_ADDRESS Bssid; - unsigned long Flags; -}; - -/*Added new types for PMKID Candidate lists. */ -struct rt_pmkid_candidate { - NDIS_802_11_MAC_ADDRESS BSSID; - unsigned long Flags; -}; - -struct rt_ndis_802_11_pmkid_candidate_list { - unsigned long Version; /* Version of the structure */ - unsigned long NumCandidates; /* No. of pmkid candidates */ - struct rt_pmkid_candidate CandidateList[1]; -}; - -/*Flags for PMKID Candidate list structure */ -#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 - -/* Added new types for OFDM 5G and 2.4G */ -typedef enum _NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11Automode, - Ndis802_11OFDM5_N, - Ndis802_11OFDM24_N, - Ndis802_11NetworkTypeMax /* not a real type, defined as an upper bound */ -} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; - -struct rt_ndis_802_11_network_type_list { - u32 NumberOfItems; /* in list below, at least 1 */ - NDIS_802_11_NETWORK_TYPE NetworkType[1]; -}; - -typedef enum _NDIS_802_11_POWER_MODE { - Ndis802_11PowerModeCAM, - Ndis802_11PowerModeMAX_PSP, - Ndis802_11PowerModeFast_PSP, - Ndis802_11PowerModeLegacy_PSP, - Ndis802_11PowerModeMax /* not a real mode, defined as an upper bound */ -} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE; - -typedef unsigned long NDIS_802_11_TX_POWER_LEVEL; /* in milliwatts */ - -/* */ -/* Received Signal Strength Indication */ -/* */ -typedef long NDIS_802_11_RSSI; /* in dBm */ - -struct rt_ndis_802_11_configuration_fh { - unsigned long Length; /* Length of structure */ - unsigned long HopPattern; /* As defined by 802.11, MSB set */ - unsigned long HopSet; /* to one if non-802.11 */ - unsigned long DwellTime; /* units are Kusec */ -}; - -struct rt_ndis_802_11_configuration { - unsigned long Length; /* Length of structure */ - unsigned long BeaconPeriod; /* units are Kusec */ - unsigned long ATIMWindow; /* units are Kusec */ - unsigned long DSConfig; /* Frequency, units are kHz */ - struct rt_ndis_802_11_configuration_fh FHConfig; -}; - -struct rt_ndis_802_11_statistics { - unsigned long Length; /* Length of structure */ - LARGE_INTEGER TransmittedFragmentCount; - LARGE_INTEGER MulticastTransmittedFrameCount; - LARGE_INTEGER FailedCount; - LARGE_INTEGER RetryCount; - LARGE_INTEGER MultipleRetryCount; - LARGE_INTEGER RTSSuccessCount; - LARGE_INTEGER RTSFailureCount; - LARGE_INTEGER ACKFailureCount; - LARGE_INTEGER FrameDuplicateCount; - LARGE_INTEGER ReceivedFragmentCount; - LARGE_INTEGER MulticastReceivedFrameCount; - LARGE_INTEGER FCSErrorCount; - LARGE_INTEGER TKIPLocalMICFailures; - LARGE_INTEGER TKIPRemoteMICErrors; - LARGE_INTEGER TKIPICVErrors; - LARGE_INTEGER TKIPCounterMeasuresInvoked; - LARGE_INTEGER TKIPReplays; - LARGE_INTEGER CCMPFormatErrors; - LARGE_INTEGER CCMPReplays; - LARGE_INTEGER CCMPDecryptErrors; - LARGE_INTEGER FourWayHandshakeFailures; -}; - -typedef unsigned long NDIS_802_11_KEY_INDEX; -typedef unsigned long long NDIS_802_11_KEY_RSC; - -#define MAX_RADIUS_SRV_NUM 2 /* 802.1x failover number */ - -struct PACKED rt_radius_srv_info { - u32 radius_ip; - u32 radius_port; - u8 radius_key[64]; - u8 radius_key_len; -}; - -struct PACKED rt_radius_key_info { - u8 radius_srv_num; - struct rt_radius_srv_info radius_srv_info[MAX_RADIUS_SRV_NUM]; - u8 ieee8021xWEP; /* dynamic WEP */ - u8 key_index; - u8 key_length; /* length of key in bytes */ - u8 key_material[13]; -}; - -/* It's used by 802.1x daemon to require relative configuration */ -struct PACKED rt_radius_conf { - u32 Length; /* Length of this structure */ - u8 mbss_num; /* indicate multiple BSS number */ - u32 own_ip_addr; - u32 retry_interval; - u32 session_timeout_interval; - u8 EAPifname[8][IFNAMSIZ]; - u8 EAPifname_len[8]; - u8 PreAuthifname[8][IFNAMSIZ]; - u8 PreAuthifname_len[8]; - struct rt_radius_key_info RadiusInfo[8]; -}; - -/* Key mapping keys require a BSSID */ -struct rt_ndis_802_11_key { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - u32 KeyLength; /* length of key in bytes */ - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_KEY_RSC KeyRSC; - u8 KeyMaterial[1]; /* variable length depending on above field */ -}; - -struct rt_ndis_802_11_passphrase { - u32 KeyLength; /* length of key in bytes */ - NDIS_802_11_MAC_ADDRESS BSSID; - u8 KeyMaterial[1]; /* variable length depending on above field */ -}; - -struct rt_ndis_802_11_remove_key { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - NDIS_802_11_MAC_ADDRESS BSSID; -}; - -struct rt_ndis_802_11_wep { - u32 Length; /* Length of this structure */ - u32 KeyIndex; /* 0 is the per-client key, 1-N are the */ - /* global keys */ - u32 KeyLength; /* length of key in bytes */ - u8 KeyMaterial[1]; /* variable length depending on above field */ -}; - -typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE { - Ndis802_11IBSS, - Ndis802_11Infrastructure, - Ndis802_11AutoUnknown, - Ndis802_11Monitor, - Ndis802_11InfrastructureMax /* Not a real value, defined as upper bound */ -} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; - -/* Add new authentication modes */ -typedef enum _NDIS_802_11_AUTHENTICATION_MODE { - Ndis802_11AuthModeOpen, - Ndis802_11AuthModeShared, - Ndis802_11AuthModeAutoSwitch, - Ndis802_11AuthModeWPA, - Ndis802_11AuthModeWPAPSK, - Ndis802_11AuthModeWPANone, - Ndis802_11AuthModeWPA2, - Ndis802_11AuthModeWPA2PSK, - Ndis802_11AuthModeWPA1WPA2, - Ndis802_11AuthModeWPA1PSKWPA2PSK, - Ndis802_11AuthModeMax /* Not a real mode, defined as upper bound */ -} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; - -typedef u8 NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; /* Set of 8 data rates */ -typedef u8 NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; /* Set of 16 data rates */ - -struct PACKED rt_ndis_802_11_ssid { - u32 SsidLength; /* length of SSID field below, in bytes; */ - /* this can be zero. */ - u8 Ssid[NDIS_802_11_LENGTH_SSID]; /* SSID information field */ -}; - -struct PACKED rt_ndis_wlan_bssid { - unsigned long Length; /* Length of this structure */ - NDIS_802_11_MAC_ADDRESS MacAddress; /* BSSID */ - u8 Reserved[2]; - struct rt_ndis_802_11_ssid Ssid; /* SSID */ - unsigned long Privacy; /* WEP encryption requirement */ - NDIS_802_11_RSSI Rssi; /* receive signal strength in dBm */ - NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - struct rt_ndis_802_11_configuration Configuration; - NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; - NDIS_802_11_RATES SupportedRates; -}; - -struct PACKED rt_ndis_802_11_bssid_list { - u32 NumberOfItems; /* in list below, at least 1 */ - struct rt_ndis_wlan_bssid Bssid[1]; -}; - -/* Added Capabilities, IELength and IEs for each BSSID */ -struct PACKED rt_ndis_wlan_bssid_ex { - unsigned long Length; /* Length of this structure */ - NDIS_802_11_MAC_ADDRESS MacAddress; /* BSSID */ - u8 Reserved[2]; - struct rt_ndis_802_11_ssid Ssid; /* SSID */ - u32 Privacy; /* WEP encryption requirement */ - NDIS_802_11_RSSI Rssi; /* receive signal */ - /* strength in dBm */ - NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - struct rt_ndis_802_11_configuration Configuration; - NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; - NDIS_802_11_RATES_EX SupportedRates; - unsigned long IELength; - u8 IEs[1]; -}; - -struct PACKED rt_ndis_802_11_bssid_list_ex { - u32 NumberOfItems; /* in list below, at least 1 */ - struct rt_ndis_wlan_bssid_ex Bssid[1]; -}; - -struct PACKED rt_ndis_802_11_fixed_ies { - u8 Timestamp[8]; - u16 BeaconInterval; - u16 Capabilities; -}; - -struct rt_ndis_802_11_variable_ies { - u8 ElementID; - u8 Length; /* Number of bytes in data field */ - u8 data[1]; -}; - -typedef unsigned long NDIS_802_11_FRAGMENTATION_THRESHOLD; - -typedef unsigned long NDIS_802_11_RTS_THRESHOLD; - -typedef unsigned long NDIS_802_11_ANTENNA; - -typedef enum _NDIS_802_11_PRIVACY_FILTER { - Ndis802_11PrivFilterAcceptAll, - Ndis802_11PrivFilter8021xWEP -} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER; - -/* Added new encryption types */ -/* Also aliased typedef to new name */ -typedef enum _NDIS_802_11_WEP_STATUS { - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent, - Ndis802_11Encryption4Enabled, /* TKIP or AES mix */ - Ndis802_11Encryption4KeyAbsent, - Ndis802_11GroupWEP40Enabled, - Ndis802_11GroupWEP104Enabled, -} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, - NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; - -typedef enum _NDIS_802_11_RELOAD_DEFAULTS { - Ndis802_11ReloadWEPKeys -} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; - -#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 -#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 -#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 - -#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 -#define NDIS_802_11_AI_RESFI_STATUSCODE 2 -#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 - -struct rt_ndis_802_11_ai_reqfi { - u16 Capabilities; - u16 ListenInterval; - NDIS_802_11_MAC_ADDRESS CurrentAPAddress; -}; - -struct rt_ndis_802_11_ai_resfi { - u16 Capabilities; - u16 StatusCode; - u16 AssociationId; -}; - -struct rt_ndis_802_11_association_information { - unsigned long Length; - u16 AvailableRequestFixedIEs; - struct rt_ndis_802_11_ai_reqfi RequestFixedIEs; - unsigned long RequestIELength; - unsigned long OffsetRequestIEs; - u16 AvailableResponseFixedIEs; - struct rt_ndis_802_11_ai_resfi ResponseFixedIEs; - unsigned long ResponseIELength; - unsigned long OffsetResponseIEs; -}; - -struct rt_ndis_802_11_authentication_event { - struct rt_ndis_802_11_status_indication Status; - struct rt_ndis_802_11_authentication_request Request[1]; -}; - -/* 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE */ -typedef enum _NDIS_802_11_MEDIA_STREAM_MODE { - Ndis802_11MediaStreamOff, - Ndis802_11MediaStreamOn, -} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE; - -/* PMKID Structures */ -typedef u8 NDIS_802_11_PMKID_VALUE[16]; - -struct rt_bssid_info { - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_PMKID_VALUE PMKID; -}; - -struct rt_ndis_802_11_pmkid { - u32 Length; - u32 BSSIDInfoCount; - struct rt_bssid_info BSSIDInfo[1]; -}; - -struct rt_ndis_802_11_authentication_encryption { - NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; - NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported; -}; - -struct rt_ndis_802_11_capability { - unsigned long Length; - unsigned long Version; - unsigned long NoOfPMKIDs; - unsigned long NoOfAuthEncryptPairsSupported; - struct rt_ndis_802_11_authentication_encryption - AuthenticationEncryptionSupported[1]; -}; - -#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x01) /* Sync. with AP for wsc upnp daemon */ -#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02) - -#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09) -#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A) -#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C) -#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D) -#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x0E) /* Sync. with RT61 (for wpa_supplicant) */ -#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F) - -#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11) -enum { - SHOW_CONN_STATUS = 4, - SHOW_DRVIER_VERION = 5, - SHOW_BA_INFO = 6, - SHOW_DESC_INFO = 7, -#ifdef RTMP_MAC_USB - SHOW_RXBULK_INFO = 8, - SHOW_TXBULK_INFO = 9, -#endif /* RTMP_MAC_USB // */ - RAIO_OFF = 10, - RAIO_ON = 11, - SHOW_CFG_VALUE = 20, - SHOW_ADHOC_ENTRY_INFO = 21, -}; - -#define OID_802_11_BUILD_CHANNEL_EX 0x0714 -#define OID_802_11_GET_CH_LIST 0x0715 -#define OID_802_11_GET_COUNTRY_CODE 0x0716 -#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717 - -#define RT_OID_WSC_SET_PASSPHRASE 0x0740 /* passphrase for wpa(2)-psk */ -#define RT_OID_WSC_DRIVER_AUTO_CONNECT 0x0741 -#define RT_OID_WSC_QUERY_DEFAULT_PROFILE 0x0742 -#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX 0x0743 -#define RT_OID_WSC_SET_ACTION 0x0744 -#define RT_OID_WSC_SET_SSID 0x0745 -#define RT_OID_WSC_SET_PIN_CODE 0x0746 -#define RT_OID_WSC_SET_MODE 0x0747 /* PIN or PBC */ -#define RT_OID_WSC_SET_CONF_MODE 0x0748 /* Enrollee or Registrar */ -#define RT_OID_WSC_SET_PROFILE 0x0749 -#define RT_OID_WSC_CONFIG_STATUS 0x074F -#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750 -/* for consistency with RT61 */ -#define RT_OID_WSC_QUERY_STATUS 0x0751 -#define RT_OID_WSC_PIN_CODE 0x0752 -#define RT_OID_WSC_UUID 0x0753 -#define RT_OID_WSC_SET_SELECTED_REGISTRAR 0x0754 -#define RT_OID_WSC_EAPMSG 0x0755 -#define RT_OID_WSC_MANUFACTURER 0x0756 -#define RT_OID_WSC_MODEL_NAME 0x0757 -#define RT_OID_WSC_MODEL_NO 0x0758 -#define RT_OID_WSC_SERIAL_NO 0x0759 -#define RT_OID_WSC_MAC_ADDRESS 0x0760 - -/* New for MeetingHouse Api support */ -#define OID_MH_802_1X_SUPPORTED 0xFFEDC100 - -/* MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition! */ -typedef union _HTTRANSMIT_SETTING { - struct { - u16 MCS:7; /* MCS */ - u16 BW:1; /*channel bandwidth 20MHz or 40 MHz */ - u16 ShortGI:1; - u16 STBC:2; /*SPACE */ -/* u16 rsv:3; */ - u16 rsv:2; - u16 TxBF:1; - u16 MODE:2; /* Use definition MODE_xxx. */ - } field; - u16 word; -} HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING; - -typedef enum _RT_802_11_PREAMBLE { - Rt802_11PreambleLong, - Rt802_11PreambleShort, - Rt802_11PreambleAuto -} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE; - -typedef enum _RT_802_11_PHY_MODE { - PHY_11BG_MIXED = 0, - PHY_11B, - PHY_11A, - PHY_11ABG_MIXED, - PHY_11G, - PHY_11ABGN_MIXED, /* both band 5 */ - PHY_11N_2_4G, /* 11n-only with 2.4G band 6 */ - PHY_11GN_MIXED, /* 2.4G band 7 */ - PHY_11AN_MIXED, /* 5G band 8 */ - PHY_11BGN_MIXED, /* if check 802.11b. 9 */ - PHY_11AGN_MIXED, /* if check 802.11b. 10 */ - PHY_11N_5G, /* 11n-only with 5G band 11 */ -} RT_802_11_PHY_MODE; - -/* put all proprietery for-query objects here to reduce # of Query_OID */ -struct rt_802_11_link_status { - unsigned long CurrTxRate; /* in units of 0.5Mbps */ - unsigned long ChannelQuality; /* 0..100 % */ - unsigned long TxByteCount; /* both ok and fail */ - unsigned long RxByteCount; /* both ok and fail */ - unsigned long CentralChannel; /* 40MHz central channel number */ -}; - -struct rt_802_11_event_log { - LARGE_INTEGER SystemTime; /* timestammp via NdisGetCurrentSystemTime() */ - u8 Addr[MAC_ADDR_LENGTH]; - u16 Event; /* EVENT_xxx */ -}; - -struct rt_802_11_event_table { - unsigned long Num; - unsigned long Rsv; /* to align Log[] at LARGE_INTEGER boundary */ - struct rt_802_11_event_log Log[MAX_NUMBER_OF_EVENT]; -}; - -/* MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition! */ -typedef union _MACHTTRANSMIT_SETTING { - struct { - u16 MCS:7; /* MCS */ - u16 BW:1; /*channel bandwidth 20MHz or 40 MHz */ - u16 ShortGI:1; - u16 STBC:2; /*SPACE */ - u16 rsv:3; - u16 MODE:2; /* Use definition MODE_xxx. */ - } field; - u16 word; -} MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING; - -struct rt_802_11_mac_entry { - u8 Addr[MAC_ADDR_LENGTH]; - u8 Aid; - u8 Psm; /* 0:PWR_ACTIVE, 1:PWR_SAVE */ - u8 MimoPs; /* 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled */ - char AvgRssi0; - char AvgRssi1; - char AvgRssi2; - u32 ConnectedTime; - MACHTTRANSMIT_SETTING TxRate; -}; - -struct rt_802_11_mac_table { - unsigned long Num; - struct rt_802_11_mac_entry Entry[MAX_NUMBER_OF_MAC]; -}; - -/* structure for query/set hardware register - MAC, BBP, RF register */ -struct rt_802_11_hardware_register { - unsigned long HardwareType; /* 0:MAC, 1:BBP, 2:RF register, 3:EEPROM */ - unsigned long Offset; /* Q/S register offset addr */ - unsigned long Data; /* R/W data buffer */ -}; - -struct rt_802_11_ap_config { - unsigned long EnableTxBurst; /* 0-disable, 1-enable */ - unsigned long EnableTurboRate; /* 0-disable, 1-enable 72/100mbps turbo rate */ - unsigned long IsolateInterStaTraffic; /* 0-disable, 1-enable isolation */ - unsigned long HideSsid; /* 0-disable, 1-enable hiding */ - unsigned long UseBGProtection; /* 0-AUTO, 1-always ON, 2-always OFF */ - unsigned long UseShortSlotTime; /* 0-no use, 1-use 9-us short slot time */ - unsigned long Rsv1; /* must be 0 */ - unsigned long SystemErrorBitmap; /* ignore upon SET, return system error upon QUERY */ -}; - -/* structure to query/set STA_CONFIG */ -struct rt_802_11_sta_config { - unsigned long EnableTxBurst; /* 0-disable, 1-enable */ - unsigned long EnableTurboRate; /* 0-disable, 1-enable 72/100mbps turbo rate */ - unsigned long UseBGProtection; /* 0-AUTO, 1-always ON, 2-always OFF */ - unsigned long UseShortSlotTime; /* 0-no use, 1-use 9-us short slot time when applicable */ - unsigned long AdhocMode; /* 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only */ - unsigned long HwRadioStatus; /* 0-OFF, 1-ON, default is 1, Read-Only */ - unsigned long Rsv1; /* must be 0 */ - unsigned long SystemErrorBitmap; /* ignore upon SET, return system error upon QUERY */ -}; - -/* */ -/* For OID Query or Set about BA structure */ -/* */ -struct rt_oid_bacap { - u8 RxBAWinLimit; - u8 TxBAWinLimit; - u8 Policy; /* 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid */ - u8 MpduDensity; /* 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid */ - u8 AmsduEnable; /*Enable AMSDU transmisstion */ - u8 AmsduSize; /* 0:3839, 1:7935 bytes. u32 MSDUSizeToBytes[] = { 3839, 7935}; */ - u8 MMPSmode; /* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */ - BOOLEAN AutoBA; /* Auto BA will automatically */ -}; - -struct rt_802_11_acl_entry { - u8 Addr[MAC_ADDR_LENGTH]; - u16 Rsv; -}; - -struct PACKED rt_rt_802_11_acl { - unsigned long Policy; /* 0-disable, 1-positive list, 2-negative list */ - unsigned long Num; - struct rt_802_11_acl_entry Entry[MAX_NUMBER_OF_ACL]; -}; - -struct rt_802_11_wds { - unsigned long Num; - NDIS_802_11_MAC_ADDRESS Entry[24 /*MAX_NUM_OF_WDS_LINK */]; - unsigned long KeyLength; - u8 KeyMaterial[32]; -}; - -struct rt_802_11_tx_rates { - u8 SupRateLen; - u8 SupRate[MAX_LENGTH_OF_SUPPORT_RATES]; - u8 ExtRateLen; - u8 ExtRate[MAX_LENGTH_OF_SUPPORT_RATES]; -}; - -/* Definition of extra information code */ -#define GENERAL_LINK_UP 0x0 /* Link is Up */ -#define GENERAL_LINK_DOWN 0x1 /* Link is Down */ -#define HW_RADIO_OFF 0x2 /* Hardware radio off */ -#define SW_RADIO_OFF 0x3 /* Software radio off */ -#define AUTH_FAIL 0x4 /* Open authentication fail */ -#define AUTH_FAIL_KEYS 0x5 /* Shared authentication fail */ -#define ASSOC_FAIL 0x6 /* Association failed */ -#define EAP_MIC_FAILURE 0x7 /* Deauthentication because MIC failure */ -#define EAP_4WAY_TIMEOUT 0x8 /* Deauthentication on 4-way handshake timeout */ -#define EAP_GROUP_KEY_TIMEOUT 0x9 /* Deauthentication on group key handshake timeout */ -#define EAP_SUCCESS 0xa /* EAP succeed */ -#define DETECT_RADAR_SIGNAL 0xb /* Radar signal occur in current channel */ -#define EXTRA_INFO_MAX 0xb /* Indicate Last OID */ - -#define EXTRA_INFO_CLEAR 0xffffffff - -/* This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use. */ -struct rt_oid_set_ht_phymode { - RT_802_11_PHY_MODE PhyMode; /* */ - u8 TransmitNo; - u8 HtMode; /*HTMODE_GF or HTMODE_MM */ - u8 ExtOffset; /*extension channel above or below */ - u8 MCS; - u8 BW; - u8 STBC; - u8 SHORTGI; - u8 rsv; -}; - -#define MAX_CUSTOM_LEN 128 - -typedef enum _RT_802_11_D_CLIENT_MODE { - Rt802_11_D_None, - Rt802_11_D_Flexible, - Rt802_11_D_Strict, -} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE; - -struct rt_channel_list_info { - u8 ChannelList[MAX_NUM_OF_CHS]; /* list all supported channels for site survey */ - u8 ChannelListNum; /* number of channel in ChannelList[] */ -}; - -/* WSC configured credential */ -struct rt_wsc_credential { - struct rt_ndis_802_11_ssid SSID; /* mandatory */ - u16 AuthType; /* mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk */ - u16 EncrType; /* mandatory, 1: none, 2: wep, 4: tkip, 8: aes */ - u8 Key[64]; /* mandatory, Maximum 64 byte */ - u16 KeyLength; - u8 MacAddr[6]; /* mandatory, AP MAC address */ - u8 KeyIndex; /* optional, default is 1 */ - u8 Rsvd[3]; /* Make alignment */ -}; - -/* WSC configured profiles */ -struct rt_wsc_profile { - u32 ProfileCnt; - u32 ApplyProfileIdx; /* add by johnli, fix WPS test plan 5.1.1 */ - struct rt_wsc_credential Profile[8]; /* Support up to 8 profiles */ -}; - -#endif /* _OID_H_ */ diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c deleted file mode 100644 index 25fbb1880ff2..000000000000 --- a/drivers/staging/rt2860/pci_main_dev.c +++ /dev/null @@ -1,1192 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - pci_main_dev.c - - Abstract: - Create and register network interface for PCI based chipsets in Linux platform. - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix typos in some comments - -------- ---------- ---------------------------------------------- -*/ - -#include "rt_config.h" -#include -#include - -/* Following information will be show when you run 'modinfo' */ -/* If you have a solution for a bug in current version of driver, please e-mail me. */ -/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. */ -MODULE_AUTHOR("Jett Chen "); -MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("rt3090sta"); - -/* */ -/* Function declarations */ -/* */ -static void __devexit rt2860_remove_one(struct pci_dev *pci_dev); -static int __devinit rt2860_probe(struct pci_dev *pci_dev, - const struct pci_device_id *ent); -static void __exit rt2860_cleanup_module(void); -static int __init rt2860_init_module(void); - -static void RTMPInitPCIeDevice(IN struct pci_dev *pci_dev, - struct rt_rtmp_adapter *pAd); - -#ifdef CONFIG_PM -static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state); -static int rt2860_resume(struct pci_dev *pci_dev); -#endif /* CONFIG_PM // */ - -/* */ -/* Ralink PCI device table, include all supported chipsets */ -/* */ -static struct pci_device_id rt2860_pci_tbl[] __devinitdata = { -#ifdef RT2860 - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, /*RT28602.4G */ - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)}, - {PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)}, -#endif -#ifdef RT3090 - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)}, -#endif /* RT3090 // */ -#ifdef RT3390 - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)}, -#endif /* RT3390 // */ - {0,} /* terminate list */ -}; - -MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl); -#ifdef MODULE_VERSION -MODULE_VERSION(STA_DRIVER_VERSION); -#endif - -/* */ -/* Our PCI driver structure */ -/* */ -static struct pci_driver rt2860_driver = { -name: "rt2860", -id_table : rt2860_pci_tbl, -probe : rt2860_probe, -remove : __devexit_p(rt2860_remove_one), -#ifdef CONFIG_PM -suspend : rt2860_suspend, -resume : rt2860_resume, -#endif -}; - -/*************************************************************************** - * - * PCI device initialization related procedures. - * - ***************************************************************************/ -#ifdef CONFIG_PM - -void RT2860RejectPendingPackets(struct rt_rtmp_adapter *pAd) -{ - /* clear PS packets */ - /* clear TxSw packets */ -} - -static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state) -{ - struct net_device *net_dev = pci_get_drvdata(pci_dev); - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL; - int retval = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n")); - - if (net_dev == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); - } else { - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - /* we can not use IFF_UP because ra0 down but ra1 up */ - /* and 1 suspend/resume function for 1 module, not for each interface */ - /* so Linux will call suspend/resume function once */ - if (VIRTUAL_IF_NUM(pAd) > 0) { - /* avoid users do suspend after interface is down */ - - /* stop interface */ - netif_carrier_off(net_dev); - netif_stop_queue(net_dev); - - /* mark device as removed from system and therefore no longer available */ - netif_device_detach(net_dev); - - /* mark halt flag */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - /* take down the device */ - rt28xx_close((struct net_device *)net_dev); - - RT_MOD_DEC_USE_COUNT(); - } - } - - /* reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html */ - /* enable device to generate PME# when suspended */ - /* pci_choose_state(): Choose the power state of a PCI device to be suspended */ - retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1); - /* save the PCI configuration space of a device before suspending */ - pci_save_state(pci_dev); - /* disable PCI device after use */ - pci_disable_device(pci_dev); - - retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n")); - return retval; -} - -static int rt2860_resume(struct pci_dev *pci_dev) -{ - struct net_device *net_dev = pci_get_drvdata(pci_dev); - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL; - int retval; - - /* set the power state of a PCI device */ - /* PCI has 4 power states, DO (normal) ~ D3(less power) */ - /* in include/linux/pci.h, you can find that */ - /* #define PCI_D0 ((pci_power_t __force) 0) */ - /* #define PCI_D1 ((pci_power_t __force) 1) */ - /* #define PCI_D2 ((pci_power_t __force) 2) */ - /* #define PCI_D3hot ((pci_power_t __force) 3) */ - /* #define PCI_D3cold ((pci_power_t __force) 4) */ - /* #define PCI_UNKNOWN ((pci_power_t __force) 5) */ - /* #define PCI_POWER_ERROR ((pci_power_t __force) -1) */ - retval = pci_set_power_state(pci_dev, PCI_D0); - - /* restore the saved state of a PCI device */ - pci_restore_state(pci_dev); - - /* initialize device before it's used by a driver */ - if (pci_enable_device(pci_dev)) { - printk(KERN_ERR "rt2860: pci enable fail!\n"); - return 0; - } - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n")); - - if (net_dev == NULL) - DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); - else - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - if (pAd != NULL) { - /* we can not use IFF_UP because ra0 down but ra1 up */ - /* and 1 suspend/resume function for 1 module, not for each interface */ - /* so Linux will call suspend/resume function once */ - if (VIRTUAL_IF_NUM(pAd) > 0) { - /* mark device as attached from system and restart if needed */ - netif_device_attach(net_dev); - - if (rt28xx_open((struct net_device *)net_dev) != 0) { - /* open fail */ - DBGPRINT(RT_DEBUG_TRACE, - ("<=== rt2860_resume()\n")); - return 0; - } - /* increase MODULE use count */ - RT_MOD_INC_USE_COUNT(); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - netif_start_queue(net_dev); - netif_carrier_on(net_dev); - netif_wake_queue(net_dev); - } - } - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n")); - return 0; -} -#endif /* CONFIG_PM // */ - -static int __init rt2860_init_module(void) -{ - return pci_register_driver(&rt2860_driver); -} - -/* */ -/* Driver module unload function */ -/* */ -static void __exit rt2860_cleanup_module(void) -{ - pci_unregister_driver(&rt2860_driver); -} - -module_init(rt2860_init_module); -module_exit(rt2860_cleanup_module); - -/* */ -/* PCI device probe & initialization function */ -/* */ -static int __devinit rt2860_probe(IN struct pci_dev *pci_dev, - IN const struct pci_device_id *pci_id) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL; - struct net_device *net_dev; - void *handle; - char *print_name; - unsigned long csr_addr; - int rv = 0; - struct rt_rtmp_os_netdev_op_hook netDevHook; - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n")); - -/*PCIDevInit============================================== */ - /* wake up and enable device */ - rv = pci_enable_device(pci_dev); - - if (rv != 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("Enable PCI device failed, errno=%d!\n", rv)); - return rv; - } - - print_name = (char *)pci_name(pci_dev); - - rv = pci_request_regions(pci_dev, print_name); - - if (rv != 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("Request PCI resource failed, errno=%d!\n", rv)); - goto err_out; - } - /* map physical address to virtual address for accessing register */ - csr_addr = - (unsigned long)ioremap(pci_resource_start(pci_dev, 0), - pci_resource_len(pci_dev, 0)); - if (!csr_addr) { - DBGPRINT(RT_DEBUG_ERROR, - ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n", - print_name, (unsigned long)pci_resource_len(pci_dev, 0), - (unsigned long)pci_resource_start(pci_dev, 0))); - goto err_out_free_res; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", print_name, - (unsigned long)pci_resource_start(pci_dev, 0), - (unsigned long)csr_addr, pci_dev->irq)); - } - - /* Set DMA master */ - pci_set_master(pci_dev); - -/*RtmpDevInit============================================== */ - /* Allocate struct rt_rtmp_adapter adapter structure */ - handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); - if (handle == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s(): Allocate memory for os handle failed!\n", - __func__)); - goto err_out_iounmap; - } - - ((struct os_cookie *)handle)->pci_dev = pci_dev; - - rv = RTMPAllocAdapterBlock(handle, &pAd); /*shiang: we may need the pci_dev for allocate structure of "struct rt_rtmp_adapter" */ - if (rv != NDIS_STATUS_SUCCESS) - goto err_out_iounmap; - /* Here are the struct rt_rtmp_adapter structure with pci-bus specific parameters. */ - pAd->CSRBaseAddress = (u8 *)csr_addr; - DBGPRINT(RT_DEBUG_ERROR, - ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n", - (unsigned long)pAd->CSRBaseAddress, csr_addr)); - RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI); - -/*NetDevInit============================================== */ - net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); - if (net_dev == NULL) - goto err_out_free_radev; - - /* Here are the net_device structure with pci-bus specific parameters. */ - net_dev->irq = pci_dev->irq; /* Interrupt IRQ number */ - net_dev->base_addr = csr_addr; /* Save CSR virtual address and irq to device structure */ - pci_set_drvdata(pci_dev, net_dev); /* Set driver data */ - -/* for supporting Network Manager */ - /* Set the sysfs physical device reference for the network logical device - * if set prior to registration will cause a symlink during initialization. - */ - SET_NETDEV_DEV(net_dev, &(pci_dev->dev)); - -/*All done, it's time to register the net device to linux kernel. */ - /* Register this device */ - rv = RtmpOSNetDevAttach(net_dev, &netDevHook); - if (rv) - goto err_out_free_netdev; - - pAd->StaCfg.OriDevType = net_dev->type; - RTMPInitPCIeDevice(pci_dev, pAd); - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n")); - - return 0; /* probe ok */ - - /* --------------------------- ERROR HANDLE --------------------------- */ -err_out_free_netdev: - RtmpOSNetDevFree(net_dev); - -err_out_free_radev: - /* free struct rt_rtmp_adapter strcuture and os_cookie */ - RTMPFreeAdapter(pAd); - -err_out_iounmap: - iounmap((void *)(csr_addr)); - release_mem_region(pci_resource_start(pci_dev, 0), - pci_resource_len(pci_dev, 0)); - -err_out_free_res: - pci_release_regions(pci_dev); - -err_out: - pci_disable_device(pci_dev); - - DBGPRINT(RT_DEBUG_ERROR, - ("<=== rt2860_probe failed with rv = %d!\n", rv)); - - return -ENODEV; /* probe fail */ -} - -static void __devexit rt2860_remove_one(IN struct pci_dev *pci_dev) -{ - struct net_device *net_dev = pci_get_drvdata(pci_dev); - struct rt_rtmp_adapter *pAd = NULL; - unsigned long csr_addr = net_dev->base_addr; /* pAd->CSRBaseAddress; */ - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); - - if (pAd != NULL) { - /* Unregister/Free all allocated net_device. */ - RtmpPhyNetDevExit(pAd, net_dev); - - /* Unmap CSR base address */ - iounmap((char *)(csr_addr)); - - /* release memory region */ - release_mem_region(pci_resource_start(pci_dev, 0), - pci_resource_len(pci_dev, 0)); - - /* Free struct rt_rtmp_adapter related structures. */ - RtmpRaDevCtrlExit(pAd); - - } else { - /* Unregister network device */ - RtmpOSNetDevDetach(net_dev); - - /* Unmap CSR base address */ - iounmap((char *)(net_dev->base_addr)); - - /* release memory region */ - release_mem_region(pci_resource_start(pci_dev, 0), - pci_resource_len(pci_dev, 0)); - } - - /* Free the root net_device */ - RtmpOSNetDevFree(net_dev); - -} - -/* -======================================================================== -Routine Description: - Check the chipset vendor/product ID. - -Arguments: - _dev_p Point to the PCI or USB device - -Return Value: - TRUE Check ok - FALSE Check fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXChipsetCheck(IN void *_dev_p) -{ - /* always TRUE */ - return TRUE; -} - -/*************************************************************************** - * - * PCIe device initialization related procedures. - * - ***************************************************************************/ -static void RTMPInitPCIeDevice(struct pci_dev *pci_dev, struct rt_rtmp_adapter *pAd) -{ - u16 device_id; - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id); - device_id = le2cpu16(device_id); - pObj->DeviceID = device_id; - if ( -#ifdef RT2860 - (device_id == NIC2860_PCIe_DEVICE_ID) || - (device_id == NIC2790_PCIe_DEVICE_ID) || - (device_id == VEN_AWT_PCIe_DEVICE_ID) || -#endif -#ifdef RT3090 - (device_id == NIC3090_PCIe_DEVICE_ID) || - (device_id == NIC3091_PCIe_DEVICE_ID) || - (device_id == NIC3092_PCIe_DEVICE_ID) || -#endif /* RT3090 // */ - 0) { - u32 MacCsr0 = 0, Index = 0; - do { - RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); - - if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF)) - break; - - RTMPusecDelay(10); - } while (Index++ < 100); - - /* Support advanced power save after 2892/2790. */ - /* MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). */ - if ((MacCsr0 & 0xffff0000) != 0x28600000) - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE); - } -} - -void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd) -{ - int pos; - u16 reg16, data2, PCIePowerSaveLevel, Configuration; - u32 MacValue; - BOOLEAN bFindIntel = FALSE; - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) - return; - - DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); - /* Init EEPROM, and save settings */ - if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) { - RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel); - pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff; - - pAd->LnkCtrlBitMask = 0; - if ((PCIePowerSaveLevel & 0xff) == 0xff) { - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE); - DBGPRINT(RT_DEBUG_TRACE, - ("====> PCIePowerSaveLevel = 0x%x.\n", - PCIePowerSaveLevel)); - return; - } else { - PCIePowerSaveLevel &= 0x3; - RT28xx_EEPROM_READ16(pAd, 0x24, data2); - - if (! - (((data2 & 0xff00) == 0x9200) - && ((data2 & 0x80) != 0))) { - if (PCIePowerSaveLevel > 1) - PCIePowerSaveLevel = 1; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("====> Write 0x83 = 0x%x.\n", - PCIePowerSaveLevel)); - AsicSendCommandToMcu(pAd, 0x83, 0xff, - (u8)PCIePowerSaveLevel, 0x00); - RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel); - PCIePowerSaveLevel &= 0xff; - PCIePowerSaveLevel = PCIePowerSaveLevel >> 6; - switch (PCIePowerSaveLevel) { - case 0: /* Only support L0 */ - pAd->LnkCtrlBitMask = 0; - break; - case 1: /* Only enable L0s */ - pAd->LnkCtrlBitMask = 1; - break; - case 2: /* enable L1, L0s */ - pAd->LnkCtrlBitMask = 3; - break; - case 3: /* sync with host clk and enable L1, L0s */ - pAd->LnkCtrlBitMask = 0x103; - break; - } - RT28xx_EEPROM_READ16(pAd, 0x24, data2); - if ((PCIePowerSaveLevel & 0xff) != 0xff) { - PCIePowerSaveLevel &= 0x3; - - if (! - (((data2 & 0xff00) == 0x9200) - && ((data2 & 0x80) != 0))) { - if (PCIePowerSaveLevel > 1) - PCIePowerSaveLevel = 1; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("====> rt28xx Write 0x83 Command = 0x%x.\n", - PCIePowerSaveLevel)); - - AsicSendCommandToMcu(pAd, 0x83, 0xff, - (u8)PCIePowerSaveLevel, - 0x00); - } - DBGPRINT(RT_DEBUG_TRACE, - ("====> LnkCtrlBitMask = 0x%x.\n", - pAd->LnkCtrlBitMask)); - } - } else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { - u8 LinkCtrlSetting = 0; - - /* Check 3090E special setting chip. */ - RT28xx_EEPROM_READ16(pAd, 0x24, data2); - if ((data2 == 0x9280) && ((pAd->MACVersion & 0xffff) == 0x0211)) { - pAd->b3090ESpecialChip = TRUE; - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Special 3090E chip \n")); - } - - RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue); - /*enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting. */ - /*Force PCIE 125MHz CLK to toggle */ - MacValue |= 0x402; - RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue); - DBGPRINT_RAW(RT_DEBUG_ERROR, - (" AUX_CTRL = 0x%32x\n", MacValue)); - - /* for RT30xx F and after, PCIe interface, and for power solution 3 */ - if ((IS_VERSION_AFTER_F(pAd)) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2) - && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) { - RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue); - DBGPRINT_RAW(RT_DEBUG_ERROR, - (" Read AUX_CTRL = 0x%x\n", MacValue)); - /* turn on bit 12. */ - /*enable 32KHz clock mode for power saving */ - MacValue |= 0x1000; - if (MacValue != 0xffffffff) { - RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue); - DBGPRINT_RAW(RT_DEBUG_ERROR, - (" Write AUX_CTRL = 0x%x\n", - MacValue)); - /* 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11. */ - MacValue = 0x3ff11; - RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue); - DBGPRINT_RAW(RT_DEBUG_ERROR, - (" OSC_CTRL = 0x%x\n", MacValue)); - /* 2. Write PCI register Clk ref bit */ - RTMPrt3xSetPCIePowerLinkCtrl(pAd); - } else { - /* Error read Aux_Ctrl value. Force to use solution 1 */ - DBGPRINT(RT_DEBUG_ERROR, - (" Error Value in AUX_CTRL = 0x%x\n", - MacValue)); - pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1; - DBGPRINT(RT_DEBUG_ERROR, - (" Force to use power solution1 \n")); - } - } - /* 1. read setting from inf file. */ - - PCIePowerSaveLevel = - (u16)pAd->StaCfg.PSControl.field.rt30xxPowerMode; - DBGPRINT(RT_DEBUG_ERROR, - ("====> rt30xx Read PowerLevelMode = 0x%x.\n", - PCIePowerSaveLevel)); - /* 2. Check EnableNewPS. */ - if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) - PCIePowerSaveLevel = 1; - - if (IS_VERSION_BEFORE_F(pAd) - && (pAd->b3090ESpecialChip == FALSE)) { - /* Chip Version E only allow 1, So force set 1. */ - PCIePowerSaveLevel &= 0x1; - pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel; - DBGPRINT(RT_DEBUG_TRACE, - ("====> rt30xx E Write 0x83 Command = 0x%x.\n", - PCIePowerSaveLevel)); - - AsicSendCommandToMcu(pAd, 0x83, 0xff, - (u8)PCIePowerSaveLevel, 0x00); - } else { - /* Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out. */ - if (! - ((PCIePowerSaveLevel == 1) - || (PCIePowerSaveLevel == 3))) - PCIePowerSaveLevel = 1; - DBGPRINT(RT_DEBUG_ERROR, - ("====> rt30xx F Write 0x83 Command = 0x%x.\n", - PCIePowerSaveLevel)); - pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel; - /* for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in */ - /* PCI Configuration Space. Because firmware can't read PCI Configuration Space */ - if ((pAd->Rt3xxRalinkLinkCtrl & 0x2) - && (pAd->Rt3xxHostLinkCtrl & 0x2)) { - LinkCtrlSetting = 1; - } - DBGPRINT(RT_DEBUG_TRACE, - ("====> rt30xxF LinkCtrlSetting = 0x%x.\n", - LinkCtrlSetting)); - AsicSendCommandToMcu(pAd, 0x83, 0xff, - (u8)PCIePowerSaveLevel, - LinkCtrlSetting); - } - } - /* Find Ralink PCIe Device's Express Capability Offset */ - pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP); - - if (pos != 0) { - /* Ralink PCIe Device's Link Control Register Offset */ - pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL; - pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, - ®16); - Configuration = le2cpu16(reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", - pAd->RLnkCtrlOffset, Configuration)); - pAd->RLnkCtrlConfiguration = (Configuration & 0x103); - Configuration &= 0xfefc; - Configuration |= (0x0); -#ifdef RT2860 - if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)) { - reg16 = cpu2le16(Configuration); - pci_write_config_word(pObj->pci_dev, - pAd->RLnkCtrlOffset, reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", - pos + PCI_EXP_LNKCTL, Configuration)); - } -#endif /* RT2860 // */ - - RTMPFindHostPCIDev(pAd); - if (pObj->parent_pci_dev) { - u16 vendor_id; - - pci_read_config_word(pObj->parent_pci_dev, - PCI_VENDOR_ID, &vendor_id); - vendor_id = le2cpu16(vendor_id); - if (vendor_id == PCIBUS_INTEL_VENDOR) { - bFindIntel = TRUE; - RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1); - } - /* Find PCI-to-PCI Bridge Express Capability Offset */ - pos = - pci_find_capability(pObj->parent_pci_dev, - PCI_CAP_ID_EXP); - - if (pos != 0) { - BOOLEAN bChange = FALSE; - /* PCI-to-PCI Bridge Link Control Register Offset */ - pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL; - pci_read_config_word(pObj->parent_pci_dev, - pAd->HostLnkCtrlOffset, - ®16); - Configuration = le2cpu16(reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n", - pAd->HostLnkCtrlOffset, - Configuration)); - pAd->HostLnkCtrlConfiguration = - (Configuration & 0x103); - Configuration &= 0xfefc; - Configuration |= (0x0); - - switch (pObj->DeviceID) { -#ifdef RT2860 - case NIC2860_PCIe_DEVICE_ID: - case NIC2790_PCIe_DEVICE_ID: - bChange = TRUE; - break; -#endif /* RT2860 // */ -#ifdef RT3090 - case NIC3090_PCIe_DEVICE_ID: - case NIC3091_PCIe_DEVICE_ID: - case NIC3092_PCIe_DEVICE_ID: - if (bFindIntel == FALSE) - bChange = TRUE; - break; -#endif /* RT3090 // */ - default: - break; - } - - if (bChange) { - reg16 = cpu2le16(Configuration); - pci_write_config_word(pObj-> - parent_pci_dev, - pAd-> - HostLnkCtrlOffset, - reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n", - pAd->HostLnkCtrlOffset, - Configuration)); - } - } else { - pAd->HostLnkCtrlOffset = 0; - DBGPRINT(RT_DEBUG_ERROR, - ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n", - __func__)); - } - } - } else { - pAd->RLnkCtrlOffset = 0; - pAd->HostLnkCtrlOffset = 0; - DBGPRINT(RT_DEBUG_ERROR, - ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n", - __func__)); - } - - if (bFindIntel == FALSE) { - DBGPRINT(RT_DEBUG_TRACE, - ("Doesn't find Intel PCI host controller. \n")); - /* Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff */ - pAd->PCIePowerSaveLevel = 0xff; - if ((pAd->RLnkCtrlOffset != 0) -#ifdef RT3090 - && ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID)) -#endif /* RT3090 // */ - ) { - pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, - ®16); - Configuration = le2cpu16(reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n", - pAd->RLnkCtrlOffset, Configuration)); - pAd->RLnkCtrlConfiguration = (Configuration & 0x103); - Configuration &= 0xfefc; - Configuration |= (0x0); - reg16 = cpu2le16(Configuration); - pci_write_config_word(pObj->pci_dev, - pAd->RLnkCtrlOffset, reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", - pos + PCI_EXP_LNKCTL, Configuration)); - } - } -} - -void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd) -{ - u16 reg16; - u8 reg8; - u32 DevFn; - struct pci_dev *pPci_dev; - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) - return; - - DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); - - pObj->parent_pci_dev = NULL; - if (pObj->pci_dev->bus->parent) { - for (DevFn = 0; DevFn < 255; DevFn++) { - pPci_dev = - pci_get_slot(pObj->pci_dev->bus->parent, DevFn); - if (pPci_dev) { - pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, - ®16); - reg16 = le2cpu16(reg16); - pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, - ®8); - if ((reg16 == PCI_CLASS_BRIDGE_PCI) - && (reg8 == pObj->pci_dev->bus->number)) { - pObj->parent_pci_dev = pPci_dev; - } - } - } - } -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value. - Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1 - - ======================================================================== -*/ -void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level) -{ - u16 PCIePowerSaveLevel, reg16; - u16 Configuration; - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) - return; - -#ifdef RT2860 - if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))) - return; -#endif /* RT2860 // */ - /* Check PSControl Configuration */ - if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) - return; - - /*3090 will not execute the following codes. */ - /* Check interface : If not PCIe interface, return. */ - -#ifdef RT3090 - if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID)) - return; -#endif /* RT3090 // */ - - DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); - PCIePowerSaveLevel = pAd->PCIePowerSaveLevel; - if ((PCIePowerSaveLevel & 0xff) == 0xff) { - DBGPRINT(RT_DEBUG_TRACE, ("return \n")); - return; - } - - if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) { - PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, - Configuration); - if ((Configuration != 0) && (Configuration != 0xFFFF)) { - Configuration &= 0xfefc; - /* If call from interface down, restore to original setting. */ - if (Level == RESTORE_CLOSE) - Configuration |= pAd->HostLnkCtrlConfiguration; - else - Configuration |= 0x0; - PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, - pAd->HostLnkCtrlOffset, - Configuration); - DBGPRINT(RT_DEBUG_TRACE, - ("Restore PCI host : offset 0x%x = 0x%x\n", - pAd->HostLnkCtrlOffset, Configuration)); - } else - DBGPRINT(RT_DEBUG_ERROR, - ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", - Configuration)); - } - - if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) { - PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, - Configuration); - if ((Configuration != 0) && (Configuration != 0xFFFF)) { - Configuration &= 0xfefc; - /* If call from interface down, restore to original setting. */ - if (Level == RESTORE_CLOSE) - Configuration |= pAd->RLnkCtrlConfiguration; - else - Configuration |= 0x0; - PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, - Configuration); - DBGPRINT(RT_DEBUG_TRACE, - ("Restore Ralink : offset 0x%x = 0x%x\n", - pAd->RLnkCtrlOffset, Configuration)); - } else - DBGPRINT(RT_DEBUG_ERROR, - ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", - Configuration)); - } - - DBGPRINT(RT_DEBUG_TRACE, ("%s <===\n", __func__)); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value. - Because now frequently set our device to mode 1 or mode 3 will cause problem. - - ======================================================================== -*/ -void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max) -{ - u16 PCIePowerSaveLevel, reg16; - u16 Configuration; - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) - return; - -#ifdef RT2860 - if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))) - return; -#endif /* RT2860 // */ - /* Check PSControl Configuration */ - if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) - return; - - /* Check interface : If not PCIe interface, return. */ - /*Block 3090 to enter the following function */ - -#ifdef RT3090 - if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID) - || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID)) - return; -#endif /* RT3090 // */ - if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) { - DBGPRINT(RT_DEBUG_INFO, - ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n")); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__)); - PCIePowerSaveLevel = pAd->PCIePowerSaveLevel; - if ((PCIePowerSaveLevel & 0xff) == 0xff) { - DBGPRINT(RT_DEBUG_TRACE, ("return \n")); - return; - } - PCIePowerSaveLevel = PCIePowerSaveLevel >> 6; - - /* Skip non-exist deice right away */ - if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) { - PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, - Configuration); - switch (PCIePowerSaveLevel) { - case 0: - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 */ - Configuration &= 0xfefc; - break; - case 1: - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 */ - Configuration &= 0xfefc; - Configuration |= 0x1; - break; - case 2: - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */ - Configuration &= 0xfefc; - Configuration |= 0x3; - break; - case 3: - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */ - Configuration &= 0xfefc; - Configuration |= 0x103; - break; - } - PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, - Configuration); - DBGPRINT(RT_DEBUG_TRACE, - ("Write PCI host offset 0x%x = 0x%x\n", - pAd->HostLnkCtrlOffset, Configuration)); - } - - if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) { - /* first 2892 chip not allow to frequently set mode 3. will cause hang problem. */ - if (PCIePowerSaveLevel > Max) - PCIePowerSaveLevel = Max; - - PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, - Configuration); - switch (PCIePowerSaveLevel) { - case 0: - /* No PCI power safe */ - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 . */ - Configuration &= 0xfefc; - break; - case 1: - /* L0 */ - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 . */ - Configuration &= 0xfefc; - Configuration |= 0x1; - break; - case 2: - /* L0 and L1 */ - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */ - Configuration &= 0xfefc; - Configuration |= 0x3; - break; - case 3: - /* L0 , L1 and clock management. */ - /* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */ - Configuration &= 0xfefc; - Configuration |= 0x103; - pAd->bPCIclkOff = TRUE; - break; - } - PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, - Configuration); - DBGPRINT(RT_DEBUG_TRACE, - ("Write Ralink device : offset 0x%x = 0x%x\n", - pAd->RLnkCtrlOffset, Configuration)); - } - - DBGPRINT(RT_DEBUG_TRACE, ("RTMPPCIePowerLinkCtrl <==============\n")); -} - -/* - ======================================================================== - - Routine Description: - 1. Write a PCI register for rt30xx power solution 3 - - ======================================================================== -*/ -void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd) -{ - - unsigned long HostConfiguration = 0; - unsigned long Configuration; - struct os_cookie *pObj; - int pos; - u16 reg16; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - DBGPRINT(RT_DEBUG_INFO, - ("RTMPrt3xSetPCIePowerLinkCtrl.===> %lx\n", - pAd->StaCfg.PSControl.word)); - - /* Check PSControl Configuration */ - if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) - return; - RTMPFindHostPCIDev(pAd); - if (pObj->parent_pci_dev) { - /* Find PCI-to-PCI Bridge Express Capability Offset */ - pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP); - - if (pos != 0) - pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL; - - /* If configured to turn on L1. */ - HostConfiguration = 0; - if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) { - DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM\n")); - - /* Skip non-exist device right away */ - if ((pAd->HostLnkCtrlOffset != 0)) { - PCI_REG_READ_WORD(pObj->parent_pci_dev, - pAd->HostLnkCtrlOffset, - HostConfiguration); - /* Prepare Configuration to write to Host */ - HostConfiguration |= 0x3; - PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, - pAd->HostLnkCtrlOffset, - HostConfiguration); - pAd->Rt3xxHostLinkCtrl = HostConfiguration; - /* Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1. */ - /* Fix HostConfiguration bit0:1 = 0x3 for later use. */ - HostConfiguration = 0x3; - DBGPRINT(RT_DEBUG_TRACE, - ("PSM : Force ASPM : " - "Host device L1/L0s Value = 0x%lx\n", - HostConfiguration)); - } - } else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == - 1) { - - /* Skip non-exist deice right away */ - if ((pAd->HostLnkCtrlOffset != 0)) { - PCI_REG_READ_WORD(pObj->parent_pci_dev, - pAd->HostLnkCtrlOffset, - HostConfiguration); - pAd->Rt3xxHostLinkCtrl = HostConfiguration; - HostConfiguration &= 0x3; - DBGPRINT(RT_DEBUG_TRACE, - ("PSM : Follow Host ASPM : " - "Host device L1/L0s Value = 0x%lx\n", - HostConfiguration)); - } - } - } - /* Prepare to write Ralink setting. */ - /* Find Ralink PCIe Device's Express Capability Offset */ - pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP); - - if (pos != 0) { - /* Ralink PCIe Device's Link Control Register Offset */ - pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL; - pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, - ®16); - Configuration = le2cpu16(reg16); - DBGPRINT(RT_DEBUG_TRACE, - ("Read (Ralink PCIe Link Control Register) " - "offset 0x%x = 0x%lx\n", - pAd->RLnkCtrlOffset, Configuration)); - Configuration |= 0x100; - if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1) - || (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)) { - switch (HostConfiguration) { - case 0: - Configuration &= 0xffffffc; - break; - case 1: - Configuration &= 0xffffffc; - Configuration |= 0x1; - break; - case 2: - Configuration &= 0xffffffc; - Configuration |= 0x2; - break; - case 3: - Configuration |= 0x3; - break; - } - } - reg16 = cpu2le16(Configuration); - pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, - reg16); - pAd->Rt3xxRalinkLinkCtrl = Configuration; - DBGPRINT(RT_DEBUG_TRACE, - ("PSM :Write Ralink device L1/L0s Value = 0x%lx\n", - Configuration)); - } - DBGPRINT(RT_DEBUG_INFO, - ("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n")); -} diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h deleted file mode 100644 index d1adef8948af..000000000000 --- a/drivers/staging/rt2860/rt_config.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt_config.h - - Abstract: - Central header file to maintain all include files for all NDIS - miniport driver routines. - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Lin 08-01-2002 created - -*/ -#ifndef __RT_CONFIG_H__ -#define __RT_CONFIG_H__ - -#include "rtmp_type.h" -#include "rtmp_os.h" - -#include "rtmp_def.h" -#include "rtmp_chip.h" -#include "rtmp_timer.h" - -#include "oid.h" -#include "mlme.h" -#include "wpa.h" -#include "crypt_md5.h" -#include "crypt_sha2.h" -#include "crypt_hmac.h" -#include "rtmp.h" -#include "ap.h" -#include "dfs.h" -#include "chlist.h" -#include "spectrum.h" - -#include "eeprom.h" -#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT) -#include "rtmp_mcu.h" -#endif - -#ifdef IGMP_SNOOP_SUPPORT -#include "igmp_snoop.h" -#endif /* IGMP_SNOOP_SUPPORT // */ - -#endif /* __RT_CONFIG_H__ */ diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c deleted file mode 100644 index 1583347fcd52..000000000000 --- a/drivers/staging/rt2860/rt_linux.c +++ /dev/null @@ -1,1367 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -#include -#include -#include -#include "rt_config.h" - -unsigned long RTDebugLevel = RT_DEBUG_ERROR; - -/* for wireless system event message */ -char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = { - /* system status event */ - "had associated successfully", /* IW_ASSOC_EVENT_FLAG */ - "had disassociated", /* IW_DISASSOC_EVENT_FLAG */ - "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */ - "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */ - "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */ - "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */ - "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */ - "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */ - "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */ - "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */ - "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */ - "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */ - "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */ - "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */ - "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */ - "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */ - "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */ - "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */ - "scan terminate! Busy! Enqueue fail!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */ -}; - -/* for wireless IDS_spoof_attack event message */ -char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = { - "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */ - "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */ - "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */ - "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */ - "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */ - "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */ - "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */ - "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */ - "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */ - "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */ -}; - -/* for wireless IDS_flooding_attack event message */ -char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = { - "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */ - "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */ - "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */ - "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */ - "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */ - "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */ - "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */ -}; - -/* timeout -- ms */ -void RTMP_SetPeriodicTimer(struct timer_list *pTimer, - IN unsigned long timeout) -{ - timeout = ((timeout * OS_HZ) / 1000); - pTimer->expires = jiffies + timeout; - add_timer(pTimer); -} - -/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */ -void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd, - struct timer_list *pTimer, - IN TIMER_FUNCTION function, void *data) -{ - init_timer(pTimer); - pTimer->data = (unsigned long)data; - pTimer->function = function; -} - -void RTMP_OS_Add_Timer(struct timer_list *pTimer, - IN unsigned long timeout) -{ - if (timer_pending(pTimer)) - return; - - timeout = ((timeout * OS_HZ) / 1000); - pTimer->expires = jiffies + timeout; - add_timer(pTimer); -} - -void RTMP_OS_Mod_Timer(struct timer_list *pTimer, - IN unsigned long timeout) -{ - timeout = ((timeout * OS_HZ) / 1000); - mod_timer(pTimer, jiffies + timeout); -} - -void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN *pCancelled) -{ - if (timer_pending(pTimer)) { - *pCancelled = del_timer_sync(pTimer); - } else { - *pCancelled = TRUE; - } - -} - -void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry) -{ - /*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */ -} - -/* Unify all delay routine by using udelay */ -void RTMPusecDelay(unsigned long usec) -{ - unsigned long i; - - for (i = 0; i < (usec / 50); i++) - udelay(50); - - if (usec % 50) - udelay(usec % 50); -} - -void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time) -{ - time->u.LowPart = jiffies; -} - -/* pAd MUST allow to be NULL */ -int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size) -{ - *mem = kmalloc(size, GFP_ATOMIC); - if (*mem) - return NDIS_STATUS_SUCCESS; - else - return NDIS_STATUS_FAILURE; -} - -/* pAd MUST allow to be NULL */ -int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem) -{ - - ASSERT(mem); - kfree(mem); - return NDIS_STATUS_SUCCESS; -} - -void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size) -{ - struct sk_buff *skb; - /* Add 2 more bytes for ip header alignment */ - skb = dev_alloc_skb(size + 2); - - return (void *)skb; -} - -void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length) -{ - struct sk_buff *pkt; - - pkt = dev_alloc_skb(Length); - - if (pkt == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("can't allocate frag rx %ld size packet\n", Length)); - } - - if (pkt) { - RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); - } - - return (void *)pkt; -} - -void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress) -{ - struct sk_buff *pkt; - - pkt = dev_alloc_skb(Length); - - if (pkt == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("can't allocate tx %ld size packet\n", Length)); - } - - if (pkt) { - RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); - *VirtualAddress = (void *)pkt->data; - } else { - *VirtualAddress = (void *)NULL; - } - - return (void *)pkt; -} - -void build_tx_packet(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pFrame, unsigned long FrameLen) -{ - - struct sk_buff *pTxPkt; - - ASSERT(pPacket); - pTxPkt = RTPKT_TO_OSPKT(pPacket); - - NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen); -} - -void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd) -{ - struct os_cookie *os_cookie; - int index; - - os_cookie = (struct os_cookie *)pAd->OS_Cookie; - - kfree(pAd->BeaconBuf); - - NdisFreeSpinLock(&pAd->MgmtRingLock); - -#ifdef RTMP_MAC_PCI - NdisFreeSpinLock(&pAd->RxRingLock); -#ifdef RT3090 - NdisFreeSpinLock(&pAd->McuCmdLock); -#endif /* RT3090 // */ -#endif /* RTMP_MAC_PCI // */ - - for (index = 0; index < NUM_OF_TX_RING; index++) { - NdisFreeSpinLock(&pAd->TxSwQueueLock[index]); - NdisFreeSpinLock(&pAd->DeQueueLock[index]); - pAd->DeQueueRunning[index] = FALSE; - } - - NdisFreeSpinLock(&pAd->irq_lock); - - release_firmware(pAd->firmware); - - vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */ - kfree(os_cookie); -} - -BOOLEAN OS_Need_Clone_Packet(void) -{ - return FALSE; -} - -/* - ======================================================================== - - Routine Description: - clone an input NDIS PACKET to another one. The new internally created NDIS PACKET - must have only one NDIS BUFFER - return - byte copied. 0 means can't create NDIS PACKET - NOTE: internally created char should be destroyed by RTMPFreeNdisPacket - - Arguments: - pAd Pointer to our adapter - pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU. - *pSrcTotalLen return total packet length. This length is calculated with 802.3 format packet. - - Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - - Note: - - ======================================================================== -*/ -int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd, - IN BOOLEAN pInsAMSDUHdr, - void *pInPacket, - void **ppOutPacket) -{ - - struct sk_buff *pkt; - - ASSERT(pInPacket); - ASSERT(ppOutPacket); - - /* 1. Allocate a packet */ - pkt = dev_alloc_skb(2048); - - if (pkt == NULL) { - return NDIS_STATUS_FAILURE; - } - - skb_put(pkt, GET_OS_PKT_LEN(pInPacket)); - NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), - GET_OS_PKT_LEN(pInPacket)); - *ppOutPacket = OSPKT_TO_RTPKT(pkt); - - RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); - - printk(KERN_DEBUG "###Clone###\n"); - - return NDIS_STATUS_SUCCESS; -} - -/* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */ -int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd, - void **ppPacket, - u8 *pHeader, - u32 HeaderLen, - u8 *pData, u32 DataLen) -{ - void *pPacket; - ASSERT(pData); - ASSERT(DataLen); - - /* 1. Allocate a packet */ - pPacket = - (void **) dev_alloc_skb(HeaderLen + DataLen + - RTMP_PKT_TAIL_PADDING); - if (pPacket == NULL) { - *ppPacket = NULL; - pr_devel("RTMPAllocateNdisPacket Fail\n"); - - return NDIS_STATUS_FAILURE; - } - /* 2. clone the frame content */ - if (HeaderLen > 0) - NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen); - if (DataLen > 0) - NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, - DataLen); - - /* 3. update length of packet */ - skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen); - - RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); -/* printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */ - *ppPacket = pPacket; - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - Description: - This routine frees a miniport internally allocated char and its - corresponding NDIS_BUFFER and allocated memory. - ======================================================================== -*/ -void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket)); -} - -/* IRQL = DISPATCH_LEVEL */ -/* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */ -/* scatter gather buffer */ -int Sniff2BytesFromNdisBuffer(char *pFirstBuffer, - u8 DesiredOffset, - u8 *pByte0, u8 *pByte1) -{ - *pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset); - *pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1); - - return NDIS_STATUS_SUCCESS; -} - -void RTMP_QueryPacketInfo(void *pPacket, - struct rt_packet_info *pPacketInfo, - u8 **pSrcBufVA, u32 * pSrcBufLen) -{ - pPacketInfo->BufferCount = 1; - pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket); - pPacketInfo->PhysicalBufferCount = 1; - pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); - - *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); - *pSrcBufLen = GET_OS_PKT_LEN(pPacket); -} - -void RTMP_QueryNextPacketInfo(void **ppPacket, - struct rt_packet_info *pPacketInfo, - u8 **pSrcBufVA, u32 * pSrcBufLen) -{ - void *pPacket = NULL; - - if (*ppPacket) - pPacket = GET_OS_PKT_NEXT(*ppPacket); - - if (pPacket) { - pPacketInfo->BufferCount = 1; - pPacketInfo->pFirstBuffer = - (char *)GET_OS_PKT_DATAPTR(pPacket); - pPacketInfo->PhysicalBufferCount = 1; - pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); - - *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); - *pSrcBufLen = GET_OS_PKT_LEN(pPacket); - *ppPacket = GET_OS_PKT_NEXT(pPacket); - } else { - pPacketInfo->BufferCount = 0; - pPacketInfo->pFirstBuffer = NULL; - pPacketInfo->PhysicalBufferCount = 0; - pPacketInfo->TotalPacketLength = 0; - - *pSrcBufVA = NULL; - *pSrcBufLen = 0; - *ppPacket = NULL; - } -} - -void *DuplicatePacket(struct rt_rtmp_adapter *pAd, - void *pPacket, u8 FromWhichBSSID) -{ - struct sk_buff *skb; - void *pRetPacket = NULL; - u16 DataSize; - u8 *pData; - - DataSize = (u16)GET_OS_PKT_LEN(pPacket); - pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket); - - skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); - if (skb) { - skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); - pRetPacket = OSPKT_TO_RTPKT(skb); - } - - return pRetPacket; - -} - -void *duplicate_pkt(struct rt_rtmp_adapter *pAd, - u8 *pHeader802_3, - u32 HdrLen, - u8 *pData, - unsigned long DataSize, u8 FromWhichBSSID) -{ - struct sk_buff *skb; - void *pPacket = NULL; - - skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG); - if (skb != NULL) { - skb_reserve(skb, 2); - NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen); - skb_put(skb, HdrLen); - NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize); - skb_put(skb, DataSize); - skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); - pPacket = OSPKT_TO_RTPKT(skb); - } - - return pPacket; -} - -#define TKIP_TX_MIC_SIZE 8 -void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd, - void *pPacket) -{ - struct sk_buff *skb, *newskb; - - skb = RTPKT_TO_OSPKT(pPacket); - if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) { - /* alloc a new skb and copy the packet */ - newskb = - skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, - GFP_ATOMIC); - dev_kfree_skb_any(skb); - if (newskb == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("Extend Tx.MIC for packet failed!, dropping packet!\n")); - return NULL; - } - skb = newskb; - } - - return OSPKT_TO_RTPKT(skb); -} - -void *ClonePacket(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pData, unsigned long DataSize) -{ - struct sk_buff *pRxPkt; - struct sk_buff *pClonedPkt; - - ASSERT(pPacket); - pRxPkt = RTPKT_TO_OSPKT(pPacket); - - /* clone the packet */ - pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG); - - if (pClonedPkt) { - /* set the correct dataptr and data len */ - pClonedPkt->dev = pRxPkt->dev; - pClonedPkt->data = pData; - pClonedPkt->len = DataSize; - skb_set_tail_pointer(pClonedPkt, DataSize) - ASSERT(DataSize < 1530); - } - return pClonedPkt; -} - -/* */ -/* change OS packet DataPtr and DataLen */ -/* */ -void update_os_packet_info(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - struct sk_buff *pOSPkt; - - ASSERT(pRxBlk->pRxPacket); - pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); - - pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); - pOSPkt->data = pRxBlk->pData; - pOSPkt->len = pRxBlk->DataSize; - skb_set_tail_pointer(pOSPkt, pOSPkt->len); -} - -void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, - u8 *pHeader802_3, - u8 FromWhichBSSID) -{ - struct sk_buff *pOSPkt; - - ASSERT(pRxBlk->pRxPacket); - ASSERT(pHeader802_3); - - pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); - - pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); - pOSPkt->data = pRxBlk->pData; - pOSPkt->len = pRxBlk->DataSize; - skb_set_tail_pointer(pOSPkt, pOSPkt->len); - - /* */ - /* copy 802.3 header */ - /* */ - /* */ - - NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, - LENGTH_802_3); -} - -void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - - struct sk_buff *pRxPkt; - - ASSERT(pPacket); - - pRxPkt = RTPKT_TO_OSPKT(pPacket); - - /* Push up the protocol stack */ - pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); - - netif_rx(pRxPkt); -} - -struct rt_rtmp_sg_list * -rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg) -{ - sg->NumberOfElements = 1; - sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket); - sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket); - return sg; -} - -void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen) -{ - unsigned char *pt; - int x; - - if (RTDebugLevel < RT_DEBUG_TRACE) - return; - - pt = pSrcBufVA; - printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen); - for (x = 0; x < SrcBufLen; x++) { - if (x % 16 == 0) - printk(KERN_DEBUG "0x%04x : ", x); - printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x])); - if (x % 16 == 15) - printk(KERN_DEBUG "\n"); - } - printk(KERN_DEBUG "\n"); -} - -/* - ======================================================================== - - Routine Description: - Send log message through wireless event - - Support standard iw_event with IWEVCUSTOM. It is used below. - - iwreq_data.data.flags is used to store event_flag that is defined by user. - iwreq_data.data.length is the length of the event log. - - The format of the event log is composed of the entry's MAC address and - the desired log message (refer to pWirelessEventText). - - ex: 11:22:33:44:55:66 has associated successfully - - p.s. The requirement of Wireless Extension is v15 or newer. - - ======================================================================== -*/ -void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd, - u16 Event_flag, - u8 *pAddr, u8 BssIdx, char Rssi) -{ - - /*union iwreq_data wrqu; */ - char *pBuf = NULL, *pBufPtr = NULL; - u16 event, type, BufLen; - u8 event_table_len = 0; - - type = Event_flag & 0xFF00; - event = Event_flag & 0x00FF; - - switch (type) { - case IW_SYS_EVENT_FLAG_START: - event_table_len = IW_SYS_EVENT_TYPE_NUM; - break; - - case IW_SPOOF_EVENT_FLAG_START: - event_table_len = IW_SPOOF_EVENT_TYPE_NUM; - break; - - case IW_FLOOD_EVENT_FLAG_START: - event_table_len = IW_FLOOD_EVENT_TYPE_NUM; - break; - } - - if (event_table_len == 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s : The type(%0x02x) is not valid.\n", __func__, - type)); - return; - } - - if (event >= event_table_len) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s : The event(%0x02x) is not valid.\n", __func__, - event)); - return; - } - /*Allocate memory and copy the msg. */ - pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC); - if (pBuf != NULL) { - /*Prepare the payload */ - memset(pBuf, 0, IW_CUSTOM_MAX_LEN); - - pBufPtr = pBuf; - - if (pAddr) - pBufPtr += - sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr); - else if (BssIdx < MAX_MBSSID_NUM) - pBufPtr += - sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx); - else - pBufPtr += sprintf(pBufPtr, "(RT2860) "); - - if (type == IW_SYS_EVENT_FLAG_START) - pBufPtr += - sprintf(pBufPtr, "%s", - pWirelessSysEventText[event]); - else if (type == IW_SPOOF_EVENT_FLAG_START) - pBufPtr += - sprintf(pBufPtr, "%s (RSSI=%d)", - pWirelessSpoofEventText[event], Rssi); - else if (type == IW_FLOOD_EVENT_FLAG_START) - pBufPtr += - sprintf(pBufPtr, "%s", - pWirelessFloodEventText[event]); - else - pBufPtr += sprintf(pBufPtr, "%s", "unknown event"); - - pBufPtr[pBufPtr - pBuf] = '\0'; - BufLen = pBufPtr - pBuf; - - RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, - (u8 *)pBuf, BufLen); - /*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */ - - kfree(pBuf); - } else - DBGPRINT(RT_DEBUG_ERROR, - ("%s : Can't allocate memory for wireless event.\n", - __func__)); -} - -void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) -{ - struct sk_buff *pOSPkt; - struct rt_wlan_ng_prism2_header *ph; - int rate_index = 0; - u16 header_len = 0; - u8 temp_header[40] = { 0 }; - - u_int32_t ralinkrate[256] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112, 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, 27, 54, 81, 108, 162, 216, 243, 270, /* Last 38 */ - 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, - 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90, - 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, - 600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80 - }; - - ASSERT(pRxBlk->pRxPacket); - if (pRxBlk->DataSize < 10) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s : Size is too small! (%d)\n", __func__, - pRxBlk->DataSize)); - goto err_free_sk_buff; - } - - if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) > - RX_BUFFER_AGGRESIZE) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s : Size is too large! (%zu)\n", __func__, - pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header))); - goto err_free_sk_buff; - } - - pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); - pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0); - if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) { - pRxBlk->DataSize -= LENGTH_802_11; - if ((pRxBlk->pHeader->FC.ToDs == 1) && - (pRxBlk->pHeader->FC.FrDs == 1)) - header_len = LENGTH_802_11_WITH_ADDR4; - else - header_len = LENGTH_802_11; - - /* QOS */ - if (pRxBlk->pHeader->FC.SubType & 0x08) { - header_len += 2; - /* Data skip QOS control field */ - pRxBlk->DataSize -= 2; - } - /* Order bit: A-Ralink or HTC+ */ - if (pRxBlk->pHeader->FC.Order) { - header_len += 4; - /* Data skip HTC control field */ - pRxBlk->DataSize -= 4; - } - /* Copy Header */ - if (header_len <= 40) - NdisMoveMemory(temp_header, pRxBlk->pData, header_len); - - /* skip HW padding */ - if (pRxBlk->RxD.L2PAD) - pRxBlk->pData += (header_len + 2); - else - pRxBlk->pData += header_len; - } /*end if */ - - if (pRxBlk->DataSize < pOSPkt->len) { - skb_trim(pOSPkt, pRxBlk->DataSize); - } else { - skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len)); - } /*end if */ - - if ((pRxBlk->pData - pOSPkt->data) > 0) { - skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data)); - skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data)); - } /*end if */ - - if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) { - if (pskb_expand_head - (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0, - GFP_ATOMIC)) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s : Reallocate header size of sk_buff fail!\n", - __func__)); - goto err_free_sk_buff; - } /*end if */ - } /*end if */ - - if (header_len > 0) - NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, - header_len); - - ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt, - sizeof(struct rt_wlan_ng_prism2_header)); - NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header)); - - ph->msgcode = DIDmsg_lnxind_wlansniffrm; - ph->msglen = sizeof(struct rt_wlan_ng_prism2_header); - strcpy((char *)ph->devname, (char *)pAd->net_dev->name); - - ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; - ph->hosttime.status = 0; - ph->hosttime.len = 4; - ph->hosttime.data = jiffies; - - ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; - ph->mactime.status = 0; - ph->mactime.len = 0; - ph->mactime.data = 0; - - ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx; - ph->istx.status = 0; - ph->istx.len = 0; - ph->istx.data = 0; - - ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel; - ph->channel.status = 0; - ph->channel.len = 4; - - ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel; - - ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; - ph->rssi.status = 0; - ph->rssi.len = 4; - ph->rssi.data = - (u_int32_t) RTMPMaxRssi(pAd, - ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, - RSSI_0), ConvertToRssi(pAd, - pRxBlk-> - pRxWI-> - RSSI1, - RSSI_1), - ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, - RSSI_2)); - - ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; - ph->signal.status = 0; - ph->signal.len = 4; - ph->signal.data = 0; /*rssi + noise; */ - - ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; - ph->noise.status = 0; - ph->noise.len = 4; - ph->noise.data = 0; - - if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) { - rate_index = - 16 + ((u8)pRxBlk->pRxWI->BW * 16) + - ((u8)pRxBlk->pRxWI->ShortGI * 32) + - ((u8)pRxBlk->pRxWI->MCS); - } else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM) - rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4; - else - rate_index = (u8)(pRxBlk->pRxWI->MCS); - if (rate_index < 0) - rate_index = 0; - if (rate_index > 255) - rate_index = 255; - - ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; - ph->rate.status = 0; - ph->rate.len = 4; - ph->rate.data = ralinkrate[rate_index]; - - ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; - ph->frmlen.status = 0; - ph->frmlen.len = 4; - ph->frmlen.data = (u_int32_t) pRxBlk->DataSize; - - pOSPkt->pkt_type = PACKET_OTHERHOST; - pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev); - pOSPkt->ip_summed = CHECKSUM_NONE; - netif_rx(pOSPkt); - - return; - -err_free_sk_buff: - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); - return; - -} - -/******************************************************************************* - - Device IRQ related functions. - - *******************************************************************************/ -int RtmpOSIRQRequest(struct net_device *pNetDev) -{ -#ifdef RTMP_PCI_SUPPORT - struct net_device *net_dev = pNetDev; - struct rt_rtmp_adapter *pAd = NULL; - int retval = 0; - - GET_PAD_FROM_NET_DEV(pAd, pNetDev); - - ASSERT(pAd); - - if (pAd->infType == RTMP_DEV_INF_PCI) { - struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie); - RTMP_MSI_ENABLE(pAd); - retval = - request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ, - (net_dev)->name, (net_dev)); - if (retval != 0) - printk(KERN_ERR "rt2860: request_irq ERROR(%d)\n", retval); - } - - return retval; -#else - return 0; -#endif -} - -int RtmpOSIRQRelease(struct net_device *pNetDev) -{ - struct net_device *net_dev = pNetDev; - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - ASSERT(pAd); - -#ifdef RTMP_PCI_SUPPORT - if (pAd->infType == RTMP_DEV_INF_PCI) { - struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie); - synchronize_irq(pObj->pci_dev->irq); - free_irq(pObj->pci_dev->irq, (net_dev)); - RTMP_MSI_DISABLE(pAd); - } -#endif /* RTMP_PCI_SUPPORT // */ - - return 0; -} - -/******************************************************************************* - - File open/close related functions. - - *******************************************************************************/ -struct file *RtmpOSFileOpen(char *pPath, int flag, int mode) -{ - struct file *filePtr; - - filePtr = filp_open(pPath, flag, 0); - if (IS_ERR(filePtr)) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s(): Error %ld opening %s\n", __func__, - -PTR_ERR(filePtr), pPath)); - } - - return (struct file *)filePtr; -} - -int RtmpOSFileClose(struct file *osfd) -{ - filp_close(osfd, NULL); - return 0; -} - -void RtmpOSFileSeek(struct file *osfd, int offset) -{ - osfd->f_pos = offset; -} - -int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen) -{ - /* The object must have a read method */ - if (osfd->f_op && osfd->f_op->read) { - return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos); - } else { - DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n")); - return -1; - } -} - -int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen) -{ - return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen, - &osfd->f_pos); -} - -/******************************************************************************* - - Task create/management/kill related functions. - - *******************************************************************************/ -int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask) -{ - struct rt_rtmp_adapter *pAd; - int ret = NDIS_STATUS_FAILURE; - - pAd = pTask->priv; - -#ifdef KTHREAD_SUPPORT - if (pTask->kthread_task) { - kthread_stop(pTask->kthread_task); - ret = NDIS_STATUS_SUCCESS; - } -#else - CHECK_PID_LEGALITY(pTask->taskPID) { - printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n", - pTask->taskName, GET_PID_NUMBER(pTask->taskPID)); - mb(); - pTask->task_killed = 1; - mb(); - ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1); - if (ret) { - printk(KERN_WARNING - "kill task(%s) with pid(%d) failed(retVal=%d)!\n", - pTask->taskName, GET_PID_NUMBER(pTask->taskPID), - ret); - } else { - wait_for_completion(&pTask->taskComplete); - pTask->taskPID = THREAD_PID_INIT_VALUE; - pTask->task_killed = 0; - ret = NDIS_STATUS_SUCCESS; - } - } -#endif - - return ret; - -} - -int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask) -{ - -#ifndef KTHREAD_SUPPORT - complete_and_exit(&pTask->taskComplete, 0); -#endif - - return 0; -} - -void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask) -{ - -#ifndef KTHREAD_SUPPORT - - daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */); - - allow_signal(SIGTERM); - allow_signal(SIGKILL); - current->flags |= PF_NOFREEZE; - - /* signal that we've started the thread */ - complete(&pTask->taskComplete); - -#endif -} - -int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask, - IN int (*fn) (void *), IN void *arg) -{ - int status = NDIS_STATUS_SUCCESS; - -#ifdef KTHREAD_SUPPORT - pTask->task_killed = 0; - pTask->kthread_task = NULL; - pTask->kthread_task = kthread_run(fn, arg, pTask->taskName); - if (IS_ERR(pTask->kthread_task)) - status = NDIS_STATUS_FAILURE; -#else - pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS); - if (pid_number < 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("Attach task(%s) failed!\n", pTask->taskName)); - status = NDIS_STATUS_FAILURE; - } else { - pTask->taskPID = GET_PID(pid_number); - - /* Wait for the thread to start */ - wait_for_completion(&pTask->taskComplete); - status = NDIS_STATUS_SUCCESS; - } -#endif - return status; -} - -int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask, - char *pTaskName, void * pPriv) -{ - int len; - - ASSERT(pTask); - -#ifndef KTHREAD_SUPPORT - NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task)); -#endif - - len = strlen(pTaskName); - len = - len > - (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len; - NdisMoveMemory(&pTask->taskName[0], pTaskName, len); - pTask->priv = pPriv; - -#ifndef KTHREAD_SUPPORT - RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema)); - pTask->taskPID = THREAD_PID_INIT_VALUE; - - init_completion(&pTask->taskComplete); -#endif - - return NDIS_STATUS_SUCCESS; -} - -void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd) -{ - if (pAd->CommonCfg.bWirelessEvent) { - if (pAd->IndicateMediaState == NdisMediaStateConnected) { - RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - } else { - RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - } - } -} - -int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd, - u32 eventType, - int flags, - u8 *pSrcMac, - u8 *pData, u32 dataLen) -{ - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - if (flags > -1) - wrqu.data.flags = flags; - - if (pSrcMac) - memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN); - - if ((pData != NULL) && (dataLen > 0)) - wrqu.data.length = dataLen; - - wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData); - return 0; -} - -int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr) -{ - struct net_device *net_dev; - struct rt_rtmp_adapter *pAd; - - net_dev = pNetDev; - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - /* work-around for SuSE, due to them having their own interface name management system. */ - { - NdisZeroMemory(pAd->StaCfg.dev_name, 16); - NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, - strlen(net_dev->name)); - } - - NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6); - - return 0; -} - -/* - * Assign the network dev name for created Ralink WiFi interface. - */ -static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd, - struct net_device *dev, - char *pPrefixStr, int devIdx) -{ - struct net_device *existNetDev; - char suffixName[IFNAMSIZ]; - char desiredName[IFNAMSIZ]; - int ifNameIdx, prefixLen, slotNameLen; - int Status; - - prefixLen = strlen(pPrefixStr); - ASSERT((prefixLen < IFNAMSIZ)); - - for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) { - memset(suffixName, 0, IFNAMSIZ); - memset(desiredName, 0, IFNAMSIZ); - strncpy(&desiredName[0], pPrefixStr, prefixLen); - - sprintf(suffixName, "%d", ifNameIdx); - - slotNameLen = strlen(suffixName); - ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ)); - strcat(desiredName, suffixName); - - existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]); - if (existNetDev == NULL) - break; - else - RtmpOSNetDeviceRefPut(existNetDev); - } - - if (ifNameIdx < 32) { - strcpy(&dev->name[0], &desiredName[0]); - Status = NDIS_STATUS_SUCCESS; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", - pPrefixStr)); - Status = NDIS_STATUS_FAILURE; - } - - return Status; -} - -void RtmpOSNetDevClose(struct net_device *pNetDev) -{ - dev_close(pNetDev); -} - -void RtmpOSNetDevFree(struct net_device *pNetDev) -{ - ASSERT(pNetDev); - - free_netdev(pNetDev); -} - -int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize) -{ - /* assign it as null first. */ - *new_dev_p = NULL; - - DBGPRINT(RT_DEBUG_TRACE, - ("Allocate a net device with private data size=%d!\n", - privDataSize)); - *new_dev_p = alloc_etherdev(privDataSize); - if (*new_dev_p) - return NDIS_STATUS_SUCCESS; - else - return NDIS_STATUS_FAILURE; -} - -struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName) -{ - struct net_device *pTargetNetDev = NULL; - - pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName); - - return pTargetNetDev; -} - -void RtmpOSNetDeviceRefPut(struct net_device *pNetDev) -{ - /* - every time dev_get_by_name is called, and it has returned a valid struct - net_device*, dev_put should be called afterwards, because otherwise the - machine hangs when the device is unregistered (since dev->refcnt > 1). - */ - if (pNetDev) - dev_put(pNetDev); -} - -int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev) -{ - - /* TODO: Need to fix this */ - printk("WARNING: This function(%s) not implement yet!\n", __func__); - return 0; -} - -void RtmpOSNetDevDetach(struct net_device *pNetDev) -{ - unregister_netdev(pNetDev); -} - -int RtmpOSNetDevAttach(struct net_device *pNetDev, - struct rt_rtmp_os_netdev_op_hook *pDevOpHook) -{ - int ret, rtnl_locked = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n")); - /* If we need hook some callback function to the net device structure, now do it. */ - if (pDevOpHook) { - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, pNetDev); - - pNetDev->netdev_ops = pDevOpHook->netdev_ops; - - /* OS specific flags, here we used to indicate if we are virtual interface */ - pNetDev->priv_flags = pDevOpHook->priv_flags; - - if (pAd->OpMode == OPMODE_STA) - pNetDev->wireless_handlers = &rt28xx_iw_handler_def; - - /* copy the net device mac address to the net_device structure. */ - NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], - MAC_ADDR_LEN); - - rtnl_locked = pDevOpHook->needProtcted; - } - - if (rtnl_locked) - ret = register_netdevice(pNetDev); - else - ret = register_netdev(pNetDev); - - DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret)); - if (ret == 0) - return NDIS_STATUS_SUCCESS; - else - return NDIS_STATUS_FAILURE; -} - -struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd, - int devType, - int devNum, - int privMemSize, char *pNamePrefix) -{ - struct net_device *pNetDev = NULL; - int status; - - /* allocate a new network device */ - status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */); - if (status != NDIS_STATUS_SUCCESS) { - /* allocation fail, exit */ - DBGPRINT(RT_DEBUG_ERROR, - ("Allocate network device fail (%s)...\n", - pNamePrefix)); - return NULL; - } - - /* find an available interface name, max 32 interfaces */ - status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum); - if (status != NDIS_STATUS_SUCCESS) { - /* error! no available ra name can be used! */ - DBGPRINT(RT_DEBUG_ERROR, - ("Assign interface name (%s with suffix 0~32) failed...\n", - pNamePrefix)); - RtmpOSNetDevFree(pNetDev); - - return NULL; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("The name of the new %s interface is %s...\n", - pNamePrefix, pNetDev->name)); - } - - return pNetDev; -} diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h deleted file mode 100644 index 3efb88fdffc1..000000000000 --- a/drivers/staging/rt2860/rt_linux.h +++ /dev/null @@ -1,835 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt_linux.h - - Abstract: - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix typo in a comment - --------- ---------- ---------------------------------------------- -*/ - -#ifndef __RT_LINUX_H__ -#define __RT_LINUX_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* load firmware */ -#define __KERNEL_SYSCALLS__ -#include -#include -#include -#include /* for get_unaligned() */ - -#define KTHREAD_SUPPORT 1 -/* RT2870 2.1.0.0 has it disabled */ - -#ifdef KTHREAD_SUPPORT -#include -#include -#endif /* KTHREAD_SUPPORT // */ - -/*********************************************************************************** - * Profile related sections - ***********************************************************************************/ - -#ifdef RTMP_MAC_PCI -#define STA_DRIVER_VERSION "2.1.0.0" -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -#define STA_DRIVER_VERSION "2.1.0.0" -/* RT3070 version: 2.1.1.0 */ -#endif /* RTMP_MAC_USB // */ - -extern const struct iw_handler_def rt28xx_iw_handler_def; - -/*********************************************************************************** - * Compiler related definitions - ***********************************************************************************/ -#undef __inline -#define __inline static inline -#define IN -#define OUT -#define INOUT - -/*********************************************************************************** - * OS Specific definitions and data structures - ***********************************************************************************/ -typedef int (*HARD_START_XMIT_FUNC) (struct sk_buff *skb, - struct net_device *net_dev); - -#ifdef RTMP_MAC_PCI -#ifndef PCI_DEVICE -#define PCI_DEVICE(vend,dev) \ - .vendor = (vend), .device = (dev), \ - .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID -#endif /* PCI_DEVICE // */ -#endif /* RTMP_MAC_PCI // */ - -#define RT_MOD_INC_USE_COUNT() \ - if (!try_module_get(THIS_MODULE)) \ - { \ - DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __func__)); \ - return -1; \ - } - -#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE); - -#define RTMP_INC_REF(_A) 0 -#define RTMP_DEC_REF(_A) 0 -#define RTMP_GET_REF(_A) 0 - -/* This function will be called when query /proc */ -struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev); - -/*********************************************************************************** - * Network related constant definitions - ***********************************************************************************/ -#ifndef IFNAMSIZ -#define IFNAMSIZ 16 -#endif - -#define ETH_LENGTH_OF_ADDRESS 6 - -#define NDIS_STATUS_SUCCESS 0x00 -#define NDIS_STATUS_FAILURE 0x01 -#define NDIS_STATUS_INVALID_DATA 0x02 -#define NDIS_STATUS_RESOURCES 0x03 - -#define NDIS_SET_PACKET_STATUS(_p, _status) do{} while(0) -#define NdisWriteErrorLogEntry(_a, _b, _c, _d) do{} while(0) - -/* statistics counter */ -#define STATS_INC_RX_PACKETS(_pAd, _dev) -#define STATS_INC_TX_PACKETS(_pAd, _dev) - -#define STATS_INC_RX_BYTESS(_pAd, _dev, len) -#define STATS_INC_TX_BYTESS(_pAd, _dev, len) - -#define STATS_INC_RX_ERRORS(_pAd, _dev) -#define STATS_INC_TX_ERRORS(_pAd, _dev) - -#define STATS_INC_RX_DROPPED(_pAd, _dev) -#define STATS_INC_TX_DROPPED(_pAd, _dev) - -/*********************************************************************************** - * Ralink Specific network related constant definitions - ***********************************************************************************/ -#define MIN_NET_DEVICE_FOR_AID 0x00 /*0x00~0x3f */ -#define MIN_NET_DEVICE_FOR_MBSSID 0x00 /*0x00,0x10,0x20,0x30 */ -#define MIN_NET_DEVICE_FOR_WDS 0x10 /*0x40,0x50,0x60,0x70 */ -#define MIN_NET_DEVICE_FOR_APCLI 0x20 -#define MIN_NET_DEVICE_FOR_MESH 0x30 -#define MIN_NET_DEVICE_FOR_DLS 0x40 -#define NET_DEVICE_REAL_IDX_MASK 0x0f /* for each operation mode, we maximum support 15 entities. */ - -#define NDIS_PACKET_TYPE_DIRECTED 0 -#define NDIS_PACKET_TYPE_MULTICAST 1 -#define NDIS_PACKET_TYPE_BROADCAST 2 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 3 -#define NDIS_PACKET_TYPE_PROMISCUOUS 4 - -/*********************************************************************************** - * OS signaling related constant definitions - ***********************************************************************************/ - -/*********************************************************************************** - * OS file operation related data structure definitions - ***********************************************************************************/ -struct rt_rtmp_os_fs_info { - int fsuid; - int fsgid; - mm_segment_t fs; -}; - -#define IS_FILE_OPEN_ERR(_fd) IS_ERR((_fd)) - -/*********************************************************************************** - * OS semaphore related data structure and definitions - ***********************************************************************************/ -struct os_lock { - spinlock_t lock; - unsigned long flags; -}; - -/* */ -/* spin_lock enhanced for Nested spin lock */ -/* */ -#define NdisAllocateSpinLock(__lock) \ -{ \ - spin_lock_init((spinlock_t *)(__lock)); \ -} - -#define NdisFreeSpinLock(lock) \ - do{}while(0) - -#define RTMP_SEM_LOCK(__lock) \ -{ \ - spin_lock_bh((spinlock_t *)(__lock)); \ -} - -#define RTMP_SEM_UNLOCK(__lock) \ -{ \ - spin_unlock_bh((spinlock_t *)(__lock)); \ -} - -/* sample, use semaphore lock to replace IRQ lock, 2007/11/15 */ -#define RTMP_IRQ_LOCK(__lock, __irqflags) \ -{ \ - __irqflags = 0; \ - spin_lock_bh((spinlock_t *)(__lock)); \ - pAd->irq_disabled |= 1; \ -} - -#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \ -{ \ - pAd->irq_disabled &= 0; \ - spin_unlock_bh((spinlock_t *)(__lock)); \ -} - -#define RTMP_INT_LOCK(__lock, __irqflags) \ -{ \ - spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \ -} - -#define RTMP_INT_UNLOCK(__lock, __irqflag) \ -{ \ - spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \ -} - -#define NdisAcquireSpinLock RTMP_SEM_LOCK -#define NdisReleaseSpinLock RTMP_SEM_UNLOCK - -#ifndef wait_event_interruptible_timeout -#define __wait_event_interruptible_timeout(wq, condition, ret) \ -do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ - add_wait_queue(&wq, &__wait); \ - for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - ret = schedule_timeout(ret); \ - if (!ret) \ - break; \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ -} while (0) - -#define wait_event_interruptible_timeout(wq, condition, timeout) \ -({ \ - long __ret = timeout; \ - if (!(condition)) \ - __wait_event_interruptible_timeout(wq, condition, __ret); \ - __ret; \ -}) -#endif - -#define RTMP_SEM_EVENT_INIT_LOCKED(_pSema) sema_init((_pSema), 0) -#define RTMP_SEM_EVENT_INIT(_pSema) sema_init((_pSema), 1) -#define RTMP_SEM_EVENT_WAIT(_pSema, _status) ((_status) = down_interruptible((_pSema))) -#define RTMP_SEM_EVENT_UP(_pSema) up(_pSema) - -#ifdef KTHREAD_SUPPORT -#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_pAd, _pTask) \ -{ \ - wait_event_interruptible(_pTask->kthread_q, \ - _pTask->kthread_running || kthread_should_stop()); \ - _pTask->kthread_running = FALSE; \ - if (kthread_should_stop()) \ - { \ - RTMP_SET_FLAG(_pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); \ - break; \ - } \ -} -#endif - -#ifdef KTHREAD_SUPPORT -#define WAKE_UP(_pTask) \ - do{ \ - if ((_pTask)->kthread_task) \ - { \ - (_pTask)->kthread_running = TRUE; \ - wake_up(&(_pTask)->kthread_q); \ - } \ - }while(0) -#endif - -/*********************************************************************************** - * OS Memory Access related data structure and definitions - ***********************************************************************************/ -#define MEM_ALLOC_FLAG (GFP_ATOMIC) /*(GFP_DMA | GFP_ATOMIC) */ - -#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length) -#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length) -#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length) -#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length) -#define NdisCmpMemory(Destination, Source, Length) memcmp(Destination, Source, Length) -#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) -#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) - -#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE) -#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA) - -#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN) - -/*********************************************************************************** - * OS task related data structure and definitions - ***********************************************************************************/ -#define RTMP_OS_MGMT_TASK_FLAGS CLONE_VM - -#define THREAD_PID_INIT_VALUE NULL -#define GET_PID(_v) find_get_pid((_v)) -#define GET_PID_NUMBER(_v) pid_nr((_v)) -#define CHECK_PID_LEGALITY(_pid) if (pid_nr((_pid)) > 0) -#define KILL_THREAD_PID(_A, _B, _C) kill_pid((_A), (_B), (_C)) - -/*********************************************************************************** - * Timer related definitions and data structures. - **********************************************************************************/ -#define OS_HZ HZ - -typedef void (*TIMER_FUNCTION) (unsigned long); - -#define OS_WAIT(_time) \ -{ int _i; \ - long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\ - wait_queue_head_t _wait; \ - init_waitqueue_head(&_wait); \ - for (_i=0; _i<(_loop); _i++) \ - wait_event_interruptible_timeout(_wait, 0, ONE_TICK); } - -#define RTMP_TIME_AFTER(a,b) \ - (typecheck(unsigned long, (unsigned long)a) && \ - typecheck(unsigned long, (unsigned long)b) && \ - ((long)(b) - (long)(a) < 0)) - -#define RTMP_TIME_AFTER_EQ(a,b) \ - (typecheck(unsigned long, (unsigned long)a) && \ - typecheck(unsigned long, (unsigned long)b) && \ - ((long)(a) - (long)(b) >= 0)) -#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a) - -#define ONE_TICK 1 - -static inline void NdisGetSystemUpTime(unsigned long *time) -{ - *time = jiffies; -} - -/*********************************************************************************** - * OS specific cookie data structure binding to struct rt_rtmp_adapter - ***********************************************************************************/ - -struct os_cookie { -#ifdef RTMP_MAC_PCI - struct pci_dev *pci_dev; - struct pci_dev *parent_pci_dev; - u16 DeviceID; - dma_addr_t pAd_pa; -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - struct usb_device *pUsb_Dev; -#endif /* RTMP_MAC_USB // */ - - struct tasklet_struct rx_done_task; - struct tasklet_struct mgmt_dma_done_task; - struct tasklet_struct ac0_dma_done_task; - struct tasklet_struct ac1_dma_done_task; - struct tasklet_struct ac2_dma_done_task; - struct tasklet_struct ac3_dma_done_task; - struct tasklet_struct tbtt_task; -#ifdef RTMP_MAC_PCI - struct tasklet_struct fifo_statistic_full_task; -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - struct tasklet_struct null_frame_complete_task; - struct tasklet_struct rts_frame_complete_task; - struct tasklet_struct pspoll_frame_complete_task; -#endif /* RTMP_MAC_USB // */ - - unsigned long apd_pid; /*802.1x daemon pid */ - int ioctl_if_type; - int ioctl_if; -}; - -/*********************************************************************************** - * OS debugging and printing related definitions and data structure - ***********************************************************************************/ -#ifdef DBG -extern unsigned long RTDebugLevel; - -#define DBGPRINT_RAW(Level, Fmt) \ -do{ \ - if (Level <= RTDebugLevel) \ - { \ - printk Fmt; \ - } \ -}while(0) - -#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt) - -#define DBGPRINT_ERR(fmt, args...) printk(KERN_ERR fmt, ##args) - -#define DBGPRINT_S(Status, Fmt) \ -{ \ - printk Fmt; \ -} - -#else -#define DBGPRINT(Level, Fmt) -#define DBGPRINT_RAW(Level, Fmt) -#define DBGPRINT_S(Status, Fmt) -#define DBGPRINT_ERR(Fmt) -#endif - -#define ASSERT(x) - -void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); - -/********************************************************************************************************* - The following code are not revised, temporary put it here. - *********************************************************************************************************/ - -/*********************************************************************************** - * Device DMA Access related definitions and data structures. - **********************************************************************************/ -#ifdef RTMP_MAC_PCI -struct rt_rtmp_adapter; -dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr, - size_t size, int sd_idx, int direction); -void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr, - size_t size, int direction); - -#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \ - linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir) - -#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \ - linux_pci_unmap_single(_handle, _ptr, _size, _dir) - -#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \ - pci_alloc_consistent(_pci_dev, _size, _ptr) - -#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \ - pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr) - -#define DEV_ALLOC_SKB(_length) \ - dev_alloc_skb(_length) -#endif /* RTMP_MAC_PCI // */ - -/* - * unsigned long - * RTMP_GetPhysicalAddressLow( - * dma_addr_t PhysicalAddress); - */ -#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress) - -/* - * unsigned long - * RTMP_GetPhysicalAddressHigh( - * dma_addr_t PhysicalAddress); - */ -#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0) - -/* - * void - * RTMP_SetPhysicalAddressLow( - * dma_addr_t PhysicalAddress, - * unsigned long Value); - */ -#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \ - PhysicalAddress = Value; - -/* - * void - * RTMP_SetPhysicalAddressHigh( - * dma_addr_t PhysicalAddress, - * unsigned long Value); - */ -#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value) - -#define NdisMIndicateStatus(_w, _x, _y, _z) - -/*********************************************************************************** - * Device Register I/O Access related definitions and data structures. - **********************************************************************************/ -#ifdef RTMP_MAC_PCI -/*Patch for ASIC turst read/write bug, needs to remove after metel fix */ -#define RTMP_IO_READ32(_A, _R, _pV) \ -{ \ - if ((_A)->bPCIclkOff == FALSE) \ - { \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \ - } \ - else \ - *_pV = 0; \ -} - -#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \ -{ \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \ -} - -#define RTMP_IO_READ8(_A, _R, _pV) \ -{ \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ - (*_pV = readb((void *)((_A)->CSRBaseAddress + (_R)))); \ -} -#define RTMP_IO_WRITE32(_A, _R, _V) \ -{ \ - if ((_A)->bPCIclkOff == FALSE) \ - { \ - u32 Val; \ - Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ - writel((_V), (void *)((_A)->CSRBaseAddress + (_R))); \ - } \ -} - -#define RTMP_IO_FORCE_WRITE32(_A, _R, _V) \ -{ \ - u32 Val; \ - Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ - writel(_V, (void *)((_A)->CSRBaseAddress + (_R))); \ -} - -#if defined(RALINK_2880) || defined(RALINK_3052) -#define RTMP_IO_WRITE8(_A, _R, _V) \ -{ \ - unsigned long Val; \ - u8 _i; \ - _i = ((_R) & 0x3); \ - Val = readl((void *)((_A)->CSRBaseAddress + ((_R) - _i))); \ - Val = Val & (~(0x000000ff << ((_i)*8))); \ - Val = Val | ((unsigned long)(_V) << ((_i)*8)); \ - writel((Val), (void *)((_A)->CSRBaseAddress + ((_R) - _i))); \ -} -#else -#define RTMP_IO_WRITE8(_A, _R, _V) \ -{ \ - u32 Val; \ - Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ - writeb((_V), (u8 *)((_A)->CSRBaseAddress + (_R))); \ -} -#endif /* #if defined(BRCM_6358) || defined(RALINK_2880) // */ - -#define RTMP_IO_WRITE16(_A, _R, _V) \ -{ \ - u32 Val; \ - Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ - writew((_V), (u16 *)((_A)->CSRBaseAddress + (_R))); \ -} -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -/*Patch for ASIC turst read/write bug, needs to remove after metel fix */ -#define RTMP_IO_READ32(_A, _R, _pV) \ - RTUSBReadMACRegister((_A), (_R), (u32 *)(_pV)) - -#define RTMP_IO_READ8(_A, _R, _pV) \ -{ \ -} - -#define RTMP_IO_WRITE32(_A, _R, _V) \ - RTUSBWriteMACRegister((_A), (_R), (u32)(_V)) - -#define RTMP_IO_WRITE8(_A, _R, _V) \ -{ \ - u16 _Val = _V; \ - RTUSBSingleWrite((_A), (_R), (u16)(_Val)); \ -} - -#define RTMP_IO_WRITE16(_A, _R, _V) \ -{ \ - RTUSBSingleWrite((_A), (_R), (u16)(_V)); \ -} -#endif /* RTMP_MAC_USB // */ - -/*********************************************************************************** - * Network Related data structure and marco definitions - ***********************************************************************************/ -#define PKTSRC_NDIS 0x7f -#define PKTSRC_DRIVER 0x0f - -#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv) ((_pNetDev)->ml_priv = (_pPriv)) -#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev) ((_pNetDev)->ml_priv) -#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev) ((_pNetDev)->name) -#define RTMP_OS_NETDEV_GET_PHYADDR(_PNETDEV) ((_PNETDEV)->dev_addr) - -#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev) netif_start_queue((_pNetDev)) -#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev) netif_stop_queue((_pNetDev)) -#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev) netif_wake_queue((_pNetDev)) -#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev) netif_carrier_off((_pNetDev)) - -#define QUEUE_ENTRY_TO_PACKET(pEntry) \ - (void *)(pEntry) - -#define PACKET_TO_QUEUE_ENTRY(pPacket) \ - (struct rt_queue_entry *)(pPacket) - -#define GET_SG_LIST_FROM_PACKET(_p, _sc) \ - rt_get_sg_list_from_packet(_p, _sc) - -#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \ -{ \ - RTMPFreeNdisPacket(_pAd, _pPacket); \ -} - -/* - * packet helper - * - convert internal rt packet to os packet or - * os packet to rt packet - */ -#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p)) -#define OSPKT_TO_RTPKT(_p) ((void *)(_p)) - -#define GET_OS_PKT_DATAPTR(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->data) -#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr) \ - (RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr) - -#define GET_OS_PKT_LEN(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->len) -#define SET_OS_PKT_LEN(_pkt, _len) \ - (RTPKT_TO_OSPKT(_pkt)->len) = (_len) - -#define GET_OS_PKT_DATATAIL(_pkt) \ - (skb_tail_pointer(RTPKT_TO_OSPKT(_pkt)) -#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \ - (skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), _len)) - -#define GET_OS_PKT_HEAD(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->head) - -#define GET_OS_PKT_END(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->end) - -#define GET_OS_PKT_NETDEV(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->dev) -#define SET_OS_PKT_NETDEV(_pkt, _pNetDev) \ - (RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev) - -#define GET_OS_PKT_TYPE(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)) - -#define GET_OS_PKT_NEXT(_pkt) \ - (RTPKT_TO_OSPKT(_pkt)->next) - -#define OS_PKT_CLONED(_pkt) skb_cloned(RTPKT_TO_OSPKT(_pkt)) - -#define OS_NTOHS(_Val) \ - (ntohs(_Val)) -#define OS_HTONS(_Val) \ - (htons(_Val)) -#define OS_NTOHL(_Val) \ - (ntohl(_Val)) -#define OS_HTONL(_Val) \ - (htonl(_Val)) - -#define CB_OFF 10 - -/* User Priority */ -#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio) -#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0]) - -/* Fragment # */ -#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num) -#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1]) - -/* 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too. */ -/*(this value also as MAC(on-chip WCID) table index) */ -/* 0x80~0xff: TX to a WDS link. b0~6: WDS index */ -#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx) -#define RTMP_GET_PACKET_WCID(_p) ((u8)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2])) - -/* 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet */ -#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc) -#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3]) - -/* RTS/CTS-to-self protection method */ -#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num) -#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4]) -/* see RTMP_S(G)ET_PACKET_EMACTAB */ - -/* TX rate index */ -#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate) -#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5]) - -/* From which Interface */ -#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx) -#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6]) -#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss)) -#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS)) -#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI)) -#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH)) -#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p)) -#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p)) - -#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit) -#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7]) - -/* */ -/* Specific Packet Type definition */ -/* */ -#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11 - -#define RTMP_PACKET_SPECIFIC_DHCP 0x01 -#define RTMP_PACKET_SPECIFIC_EAPOL 0x02 -#define RTMP_PACKET_SPECIFIC_IPV4 0x04 -#define RTMP_PACKET_SPECIFIC_WAI 0x08 -#define RTMP_PACKET_SPECIFIC_VLAN 0x10 -#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20 - -/*Specific */ -#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg) - -/*DHCP */ -#define RTMP_SET_PACKET_DHCP(_p, _flg) \ - do{ \ - if (_flg) \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \ - else \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP); \ - }while(0) -#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP) - -/*EAPOL */ -#define RTMP_SET_PACKET_EAPOL(_p, _flg) \ - do{ \ - if (_flg) \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \ - else \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL); \ - }while(0) -#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL) - -/*WAI */ -#define RTMP_SET_PACKET_WAI(_p, _flg) \ - do{ \ - if (_flg) \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \ - else \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI); \ - }while(0) -#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI) - -#define RTMP_GET_PACKET_LOWRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI)) - -/*VLAN */ -#define RTMP_SET_PACKET_VLAN(_p, _flg) \ - do{ \ - if (_flg) \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \ - else \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN); \ - }while(0) -#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN) - -/*LLC/SNAP */ -#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \ - do{ \ - if (_flg) \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \ - else \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP); \ - }while(0) - -#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP) - -/* IP */ -#define RTMP_SET_PACKET_IPV4(_p, _flg) \ - do{ \ - if (_flg) \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \ - else \ - (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4); \ - }while(0) - -#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4) - -/* If this flag is set, it indicates that this EAPoL frame MUST be clear. */ -#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg) -#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12]) - -/* use bit3 of cb[CB_OFF+16] */ - -#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg) -#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22]) - -/* Max skb->cb = 48B = [CB_OFF+38] */ - -/*********************************************************************************** - * Other function prototypes definitions - ***********************************************************************************/ -void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); -int rt28xx_packet_xmit(struct sk_buff *skb); - -#ifdef RTMP_MAC_PCI -/* function declarations */ -#define IRQ_HANDLE_TYPE irqreturn_t - -IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance); -#endif /* RTMP_MAC_PCI // */ - -int rt28xx_sta_ioctl(struct net_device *net_dev, IN OUT struct ifreq *rq, int cmd); - -extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf); -extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); - -#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev) (_pAd) = (struct rt_rtmp_adapter *)(_net_dev)->ml_priv; - -#endif /* __RT_LINUX_H__ // */ diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c deleted file mode 100644 index 236dd36d349a..000000000000 --- a/drivers/staging/rt2860/rt_main_dev.c +++ /dev/null @@ -1,736 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt_main_dev.c - - Abstract: - Create and register network interface. - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix typos in comments - -------- ---------- ---------------------------------------------- -*/ - -#include "rt_config.h" - -/*---------------------------------------------------------------------*/ -/* Private Variables Used */ -/*---------------------------------------------------------------------*/ - -char *mac = ""; /* default 00:00:00:00:00:00 */ -char *hostname = ""; /* default CMPC */ -module_param(mac, charp, 0); -MODULE_PARM_DESC(mac, "rt28xx: wireless mac addr"); - -/*---------------------------------------------------------------------*/ -/* Prototypes of Functions Used */ -/*---------------------------------------------------------------------*/ - -/* public function prototype */ -int rt28xx_close(IN struct net_device *net_dev); -int rt28xx_open(struct net_device *net_dev); - -/* private function prototype */ -static int rt28xx_send_packets(IN struct sk_buff *skb_p, - IN struct net_device *net_dev); - -static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device - *net_dev); - -/* -======================================================================== -Routine Description: - Close raxx interface. - -Arguments: - *net_dev the raxx interface pointer - -Return Value: - 0 Open OK - otherwise Open Fail - -Note: - 1. if open fail, kernel will not call the close function. - 2. Free memory for - (1) Mlme Memory Handler: MlmeHalt() - (2) TX & RX: RTMPFreeTxRxRingMemory() - (3) BA Reordering: ba_reordering_resource_release() -======================================================================== -*/ -int MainVirtualIF_close(IN struct net_device *net_dev) -{ - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - /* Sanity check for pAd */ - if (pAd == NULL) - return 0; /* close ok */ - - netif_carrier_off(pAd->net_dev); - netif_stop_queue(pAd->net_dev); - - { - BOOLEAN Cancelled; - - if (INFRA_ON(pAd) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - struct rt_mlme_disassoc_req DisReq; - struct rt_mlme_queue_elem *MsgElem = - kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); - - if (MsgElem) { - COPY_MAC_ADDR(DisReq.Addr, - pAd->CommonCfg.Bssid); - DisReq.Reason = REASON_DEAUTH_STA_LEAVING; - - MsgElem->Machine = ASSOC_STATE_MACHINE; - MsgElem->MsgType = MT2_MLME_DISASSOC_REQ; - MsgElem->MsgLen = - sizeof(struct rt_mlme_disassoc_req); - NdisMoveMemory(MsgElem->Msg, &DisReq, - sizeof - (struct rt_mlme_disassoc_req)); - - /* Prevent to connect AP again in STAMlmePeriodicExec */ - pAd->MlmeAux.AutoReconnectSsidLen = 32; - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, - pAd->MlmeAux. - AutoReconnectSsidLen); - - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_OID_DISASSOC; - MlmeDisassocReqAction(pAd, MsgElem); - kfree(MsgElem); - } - - RTMPusecDelay(1000); - } - - RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, - &Cancelled); - RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, - &Cancelled); - } - - VIRTUAL_IF_DOWN(pAd); - - RT_MOD_DEC_USE_COUNT(); - - return 0; /* close ok */ -} - -/* -======================================================================== -Routine Description: - Open raxx interface. - -Arguments: - *net_dev the raxx interface pointer - -Return Value: - 0 Open OK - otherwise Open Fail - -Note: - 1. if open fail, kernel will not call the close function. - 2. Free memory for - (1) Mlme Memory Handler: MlmeHalt() - (2) TX & RX: RTMPFreeTxRxRingMemory() - (3) BA Reordering: ba_reordering_resource_release() -======================================================================== -*/ -int MainVirtualIF_open(IN struct net_device *net_dev) -{ - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - /* Sanity check for pAd */ - if (pAd == NULL) - return 0; /* close ok */ - - if (VIRTUAL_IF_UP(pAd) != 0) - return -1; - - /* increase MODULE use count */ - RT_MOD_INC_USE_COUNT(); - - netif_start_queue(net_dev); - netif_carrier_on(net_dev); - netif_wake_queue(net_dev); - - return 0; -} - -/* -======================================================================== -Routine Description: - Close raxx interface. - -Arguments: - *net_dev the raxx interface pointer - -Return Value: - 0 Open OK - otherwise Open Fail - -Note: - 1. if open fail, kernel will not call the close function. - 2. Free memory for - (1) Mlme Memory Handler: MlmeHalt() - (2) TX & RX: RTMPFreeTxRxRingMemory() - (3) BA Reordering: ba_reordering_resource_release() -======================================================================== -*/ -int rt28xx_close(struct net_device *dev) -{ - struct net_device *net_dev = (struct net_device *)dev; - struct rt_rtmp_adapter *pAd = NULL; - BOOLEAN Cancelled; - u32 i = 0; - -#ifdef RTMP_MAC_USB - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); - DECLARE_WAITQUEUE(wait, current); -#endif /* RTMP_MAC_USB // */ - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n")); - - Cancelled = FALSE; - /* Sanity check for pAd */ - if (pAd == NULL) - return 0; /* close ok */ - - { -#ifdef RTMP_MAC_PCI - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE); -#endif /* RTMP_MAC_PCI // */ - - /* If driver doesn't wake up firmware here, */ - /* NICLoadFirmware will hang forever when interface is up again. */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - AsicForceWakeup(pAd, TRUE); - } -#ifdef RTMP_MAC_USB - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); -#endif /* RTMP_MAC_USB // */ - - MlmeRadioOff(pAd); -#ifdef RTMP_MAC_PCI - pAd->bPCIclkOff = FALSE; -#endif /* RTMP_MAC_PCI // */ - } - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - - for (i = 0; i < NUM_OF_TX_RING; i++) { - while (pAd->DeQueueRunning[i] == TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("Waiting for TxQueue[%d] done..........\n", - i)); - RTMPusecDelay(1000); - } - } - -#ifdef RTMP_MAC_USB - /* ensure there are no more active urbs. */ - add_wait_queue(&unlink_wakeup, &wait); - pAd->wait = &unlink_wakeup; - - /* maybe wait for deletions to finish. */ - i = 0; - /*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */ - while (i < 25) { - unsigned long IrqFlags; - - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - if (pAd->PendingRx == 0) { - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - break; - } - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - - msleep(UNLINK_TIMEOUT_MS); /*Time in millisecond */ - i++; - } - pAd->wait = NULL; - remove_wait_queue(&unlink_wakeup, &wait); -#endif /* RTMP_MAC_USB // */ - - /* Stop Mlme state machine */ - MlmeHalt(pAd); - - /* Close net tasklets */ - RtmpNetTaskExit(pAd); - - { - MacTableReset(pAd); - } - - MeasureReqTabExit(pAd); - TpcReqTabExit(pAd); - - /* Close kernel threads */ - RtmpMgmtTaskExit(pAd); - -#ifdef RTMP_MAC_PCI - { - BOOLEAN brc; - /* unsigned long Value; */ - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { - RTMP_ASIC_INTERRUPT_DISABLE(pAd); - } - /* Receive packets to clear DMA index after disable interrupt. */ - /* RTMPHandleRxDoneInterrupt(pAd); */ - /* put radio off to save power when driver unloads. After radiooff, can't write/read register, so need to finish all. */ - /* register access before Radio off. */ - - brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0); - -/*In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */ - pAd->bPCIclkOff = FALSE; - - if (brc == FALSE) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s call RT28xxPciAsicRadioOff fail!\n", - __func__)); - } - } - -/* - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) - { - RTMP_ASIC_INTERRUPT_DISABLE(pAd); - } - - // Disable Rx, register value supposed will remain after reset - NICIssueReset(pAd); -*/ -#endif /* RTMP_MAC_PCI // */ - - /* Free IRQ */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { -#ifdef RTMP_MAC_PCI - /* Deregister interrupt function */ - RtmpOSIRQRelease(net_dev); -#endif /* RTMP_MAC_PCI // */ - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); - } - /* Free Ring or USB buffers */ - RTMPFreeTxRxRingMemory(pAd); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - - /* Free BA reorder resource */ - ba_reordering_resource_release(pAd); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); - -/*+++Modify by woody to solve the bulk fail+++*/ - { - } - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n")); - return 0; /* close ok */ -} /* End of rt28xx_close */ - -/* -======================================================================== -Routine Description: - Open raxx interface. - -Arguments: - *net_dev the raxx interface pointer - -Return Value: - 0 Open OK - otherwise Open Fail - -Note: -======================================================================== -*/ -int rt28xx_open(struct net_device *dev) -{ - struct net_device *net_dev = (struct net_device *)dev; - struct rt_rtmp_adapter *pAd = NULL; - int retval = 0; - /*struct os_cookie *pObj; */ - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - /* Sanity check for pAd */ - if (pAd == NULL) { - /* if 1st open fail, pAd will be free; - So the net_dev->ml_priv will be NULL in 2rd open */ - return -1; - } - - if (net_dev->priv_flags == INT_MAIN) { - if (pAd->OpMode == OPMODE_STA) - net_dev->wireless_handlers = - (struct iw_handler_def *)&rt28xx_iw_handler_def; - } - /* Request interrupt service routine for PCI device */ - /* register the interrupt routine with the os */ - RtmpOSIRQRequest(net_dev); - - /* Init IRQ parameters stored in pAd */ - RTMP_IRQ_INIT(pAd); - - /* Chip & other init */ - if (rt28xx_init(pAd, mac, hostname) == FALSE) - goto err; - - /* Enable Interrupt */ - RTMP_IRQ_ENABLE(pAd); - - /* Now Enable RxTx */ - RTMPEnableRxTx(pAd); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); - - { - u32 reg = 0; - RTMP_IO_READ32(pAd, 0x1300, ®); /* clear garbage interrupts */ - printk(KERN_DEBUG "0x1300 = %08x\n", reg); - } - - { -/* u32 reg; */ -/* u8 byte; */ -/* u16 tmp; */ - -/* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); */ - -/* tmp = 0x0805; */ -/* reg = (reg & 0xffff0000) | tmp; */ -/* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */ - - } -#ifdef RTMP_MAC_PCI - RTMPInitPCIeLinkCtrlValue(pAd); -#endif /* RTMP_MAC_PCI // */ - - return retval; - -err: -/*+++Add by shiang, move from rt28xx_init() to here. */ - RtmpOSIRQRelease(net_dev); -/*---Add by shiang, move from rt28xx_init() to here. */ - return -1; -} /* End of rt28xx_open */ - -static const struct net_device_ops rt2860_netdev_ops = { - .ndo_open = MainVirtualIF_open, - .ndo_stop = MainVirtualIF_close, - .ndo_do_ioctl = rt28xx_sta_ioctl, - .ndo_get_stats = RT28xx_get_ether_stats, - .ndo_validate_addr = NULL, - .ndo_set_mac_address = eth_mac_addr, - .ndo_change_mtu = eth_change_mtu, - .ndo_start_xmit = rt28xx_send_packets, -}; - -struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd, - struct rt_rtmp_os_netdev_op_hook *pNetDevHook) -{ - struct net_device *net_dev = NULL; -/* int Status; */ - - net_dev = - RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(struct rt_rtmp_adapter *), - INF_MAIN_DEV_NAME); - if (net_dev == NULL) { - printk - ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n"); - return NULL; - } - - NdisZeroMemory((unsigned char *)pNetDevHook, - sizeof(struct rt_rtmp_os_netdev_op_hook)); - pNetDevHook->netdev_ops = &rt2860_netdev_ops; - pNetDevHook->priv_flags = INT_MAIN; - pNetDevHook->needProtcted = FALSE; - - net_dev->ml_priv = (void *)pAd; - pAd->net_dev = net_dev; - - return net_dev; - -} - -/* -======================================================================== -Routine Description: - The entry point for Linux kernel sent packet to our driver. - -Arguments: - sk_buff *skb the pointer refer to a sk_buffer. - -Return Value: - 0 - -Note: - This function is the entry point of Tx Path for Os delivery packet to - our driver. You only can put OS-depened & STA/AP common handle procedures - in here. -======================================================================== -*/ -int rt28xx_packet_xmit(struct sk_buff *skb) -{ - struct net_device *net_dev = skb->dev; - struct rt_rtmp_adapter *pAd = NULL; - int status = NETDEV_TX_OK; - void *pPacket = (void *)skb; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - /* RT2870STA does this in RTMPSendPackets() */ - - { - /* Drop send request since we are in monitor mode */ - if (MONITOR_ON(pAd)) { - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - goto done; - } - } - - /* EapolStart size is 18 */ - if (skb->len < 14) { - /*printk("bad packet size: %d\n", pkt->len); */ - hex_dump("bad packet", skb->data, skb->len); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - goto done; - } - - RTMP_SET_PACKET_5VT(pPacket, 0); - STASendPackets((void *)pAd, (void **)&pPacket, 1); - - status = NETDEV_TX_OK; -done: - - return status; -} - -/* -======================================================================== -Routine Description: - Send a packet to WLAN. - -Arguments: - skb_p points to our adapter - dev_p which WLAN network interface - -Return Value: - 0: transmit successfully - otherwise: transmit fail - -Note: -======================================================================== -*/ -static int rt28xx_send_packets(IN struct sk_buff *skb_p, - IN struct net_device *net_dev) -{ - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - if (!(net_dev->flags & IFF_UP)) { - RELEASE_NDIS_PACKET(pAd, (void *)skb_p, - NDIS_STATUS_FAILURE); - return NETDEV_TX_OK; - } - - NdisZeroMemory((u8 *)&skb_p->cb[CB_OFF], 15); - RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); - - return rt28xx_packet_xmit(skb_p); -} - -/* This function will be called when query /proc */ -struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev) -{ - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); - - pAd->iw_stats.status = 0; /* Status - device dependent for now */ - - /* link quality */ - if (pAd->OpMode == OPMODE_STA) - pAd->iw_stats.qual.qual = - ((pAd->Mlme.ChannelQuality * 12) / 10 + 10); - - if (pAd->iw_stats.qual.qual > 100) - pAd->iw_stats.qual.qual = 100; - - if (pAd->OpMode == OPMODE_STA) { - pAd->iw_stats.qual.level = - RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, - pAd->StaCfg.RssiSample.LastRssi1, - pAd->StaCfg.RssiSample.LastRssi2); - } - - pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; /* noise level (dBm) */ - - pAd->iw_stats.qual.noise += 256 - 143; - pAd->iw_stats.qual.updated = 1; /* Flags to know if updated */ -#ifdef IW_QUAL_DBM - pAd->iw_stats.qual.updated |= IW_QUAL_DBM; /* Level + Noise are dBm */ -#endif /* IW_QUAL_DBM // */ - - pAd->iw_stats.discard.nwid = 0; /* Rx : Wrong nwid/essid */ - pAd->iw_stats.miss.beacon = 0; /* Missed beacons/superframe */ - - DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); - return &pAd->iw_stats; -} - -void tbtt_tasklet(unsigned long data) -{ -/*#define MAX_TX_IN_TBTT (16) */ - -} - -/* - ======================================================================== - - Routine Description: - return ethernet statistics counter - - Arguments: - net_dev Pointer to net_device - - Return Value: - net_device_stats* - - Note: - - ======================================================================== -*/ -static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device - *net_dev) -{ - struct rt_rtmp_adapter *pAd = NULL; - - if (net_dev) - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - if (pAd) { - - pAd->stats.rx_packets = - pAd->WlanCounters.ReceivedFragmentCount.QuadPart; - pAd->stats.tx_packets = - pAd->WlanCounters.TransmittedFragmentCount.QuadPart; - - pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount; - pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount; - - pAd->stats.rx_errors = pAd->Counters8023.RxErrors; - pAd->stats.tx_errors = pAd->Counters8023.TxErrors; - - pAd->stats.rx_dropped = 0; - pAd->stats.tx_dropped = 0; - - pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; /* multicast packets received */ - pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; /* Collision packets */ - - pAd->stats.rx_length_errors = 0; - pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; /* receiver ring buff overflow */ - pAd->stats.rx_crc_errors = 0; /*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */ - pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; /* recv'd frame alignment error */ - pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; /* recv'r fifo overrun */ - pAd->stats.rx_missed_errors = 0; /* receiver missed packet */ - - /* detailed tx_errors */ - pAd->stats.tx_aborted_errors = 0; - pAd->stats.tx_carrier_errors = 0; - pAd->stats.tx_fifo_errors = 0; - pAd->stats.tx_heartbeat_errors = 0; - pAd->stats.tx_window_errors = 0; - - /* for cslip etc */ - pAd->stats.rx_compressed = 0; - pAd->stats.tx_compressed = 0; - - return &pAd->stats; - } else - return NULL; -} - -BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev) -{ - - /* Unregister network device */ - if (net_dev != NULL) { - printk - ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", - net_dev->name); - RtmpOSNetDevDetach(net_dev); - } - - return TRUE; - -} - -/* -======================================================================== -Routine Description: - Allocate memory for adapter control block. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - -Note: -======================================================================== -*/ -int AdapterBlockAllocateMemory(void *handle, void ** ppAd) -{ - - *ppAd = vmalloc(sizeof(struct rt_rtmp_adapter)); - /* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */ - - if (*ppAd) { - NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter)); - ((struct rt_rtmp_adapter *)*ppAd)->OS_Cookie = handle; - return NDIS_STATUS_SUCCESS; - } else { - return NDIS_STATUS_FAILURE; - } -} diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c deleted file mode 100644 index f80ab4e6a0ac..000000000000 --- a/drivers/staging/rt2860/rt_pci_rbus.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt_pci_rbus.c - - Abstract: - Create and register network interface. - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix a typo - -------- ---------- ---------------------------------------------- -*/ - -#include "rt_config.h" -#include - -IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance); - -static void rx_done_tasklet(unsigned long data); -static void mgmt_dma_done_tasklet(unsigned long data); -static void ac0_dma_done_tasklet(unsigned long data); -static void ac1_dma_done_tasklet(unsigned long data); -static void ac2_dma_done_tasklet(unsigned long data); -static void ac3_dma_done_tasklet(unsigned long data); -static void fifo_statistic_full_tasklet(unsigned long data); - -/*---------------------------------------------------------------------*/ -/* Symbol & Macro Definitions */ -/*---------------------------------------------------------------------*/ -#define RT2860_INT_RX_DLY (1<<0) /* bit 0 */ -#define RT2860_INT_TX_DLY (1<<1) /* bit 1 */ -#define RT2860_INT_RX_DONE (1<<2) /* bit 2 */ -#define RT2860_INT_AC0_DMA_DONE (1<<3) /* bit 3 */ -#define RT2860_INT_AC1_DMA_DONE (1<<4) /* bit 4 */ -#define RT2860_INT_AC2_DMA_DONE (1<<5) /* bit 5 */ -#define RT2860_INT_AC3_DMA_DONE (1<<6) /* bit 6 */ -#define RT2860_INT_HCCA_DMA_DONE (1<<7) /* bit 7 */ -#define RT2860_INT_MGMT_DONE (1<<8) /* bit 8 */ - -#define INT_RX RT2860_INT_RX_DONE - -#define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) /*| RT2860_INT_TX_DLY) */ -#define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) /*| RT2860_INT_TX_DLY) */ -#define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) /*| RT2860_INT_TX_DLY) */ -#define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) /*| RT2860_INT_TX_DLY) */ -#define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) /*| RT2860_INT_TX_DLY) */ -#define INT_MGMT_DLY RT2860_INT_MGMT_DONE - -/*************************************************************************** - * - * Interface-depended memory allocation/Free related procedures. - * Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc., - * - **************************************************************************/ -/* Function for TxDesc Memory allocation. */ -void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd, - u32 Index, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - *VirtualAddress = - (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length, - PhysicalAddress); - -} - -/* Function for MgmtDesc Memory allocation. */ -void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - *VirtualAddress = - (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length, - PhysicalAddress); - -} - -/* Function for RxDesc Memory allocation. */ -void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - *VirtualAddress = - (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length, - PhysicalAddress); - -} - -/* Function for free allocated Desc Memory. */ -void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - void *VirtualAddress, - dma_addr_t PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, - PhysicalAddress); -} - -/* Function for TxData DMA Memory allocation. */ -void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd, - u32 Index, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - *VirtualAddress = - (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length, - PhysicalAddress); -} - -void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void *VirtualAddress, - dma_addr_t PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, - PhysicalAddress); -} - -/* - * FUNCTION: Allocate a common buffer for DMA - * ARGUMENTS: - * AdapterHandle: AdapterHandle - * Length: Number of bytes to allocate - * Cached: Whether or not the memory can be cached - * VirtualAddress: Pointer to memory is returned here - * PhysicalAddress: Physical address corresponding to virtual address - */ -void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - *VirtualAddress = - (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length, - PhysicalAddress); -} - -/* - * FUNCTION: Allocate a packet buffer for DMA - * ARGUMENTS: - * AdapterHandle: AdapterHandle - * Length: Number of bytes to allocate - * Cached: Whether or not the memory can be cached - * VirtualAddress: Pointer to memory is returned here - * PhysicalAddress: Physical address corresponding to virtual address - * Notes: - * Cached is ignored: always cached memory - */ -void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - OUT dma_addr_t * - PhysicalAddress) -{ - struct sk_buff *pkt; - - pkt = dev_alloc_skb(Length); - - if (pkt == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("can't allocate rx %ld size packet\n", Length)); - } - - if (pkt) { - RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); - *VirtualAddress = (void *)pkt->data; - *PhysicalAddress = - PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, - PCI_DMA_FROMDEVICE); - } else { - *VirtualAddress = (void *)NULL; - *PhysicalAddress = (dma_addr_t)NULL; - } - - return (void *)pkt; -} - -void Invalid_Remaining_Packet(struct rt_rtmp_adapter *pAd, unsigned long VirtualAddress) -{ - dma_addr_t PhysicalAddress; - - PhysicalAddress = - PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress + 1600), - RX_BUFFER_NORMSIZE - 1600, -1, PCI_DMA_FROMDEVICE); -} - -int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd) -{ - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->fifo_statistic_full_task, - fifo_statistic_full_tasklet, (unsigned long)pAd); - - return NDIS_STATUS_SUCCESS; -} - -void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd) -{ - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - tasklet_kill(&pObj->rx_done_task); - tasklet_kill(&pObj->mgmt_dma_done_task); - tasklet_kill(&pObj->ac0_dma_done_task); - tasklet_kill(&pObj->ac1_dma_done_task); - tasklet_kill(&pObj->ac2_dma_done_task); - tasklet_kill(&pObj->ac3_dma_done_task); - tasklet_kill(&pObj->tbtt_task); - tasklet_kill(&pObj->fifo_statistic_full_task); -} - -int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd) -{ - - return NDIS_STATUS_SUCCESS; -} - -/* -======================================================================== -Routine Description: - Close kernel threads. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - NONE - -Note: -======================================================================== -*/ -void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd) -{ - - return; -} - -static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode) -{ - u32 regValue; - - pAd->int_disable_mask &= ~(mode); - regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); - /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */ - { - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); /* 1:enable */ - } - /*else */ - /* DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */ - - if (regValue != 0) - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); -} - -static inline void rt2860_int_disable(struct rt_rtmp_adapter *pAd, unsigned int mode) -{ - u32 regValue; - - pAd->int_disable_mask |= mode; - regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); /* 0: disable */ - - if (regValue == 0) { - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); - } -} - -/*************************************************************************** - * - * tasklet related procedures. - * - **************************************************************************/ -static void mgmt_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - INT_SOURCE_CSR_STRUC IntSource; - struct os_cookie *pObj; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - -/* printk("mgmt_dma_done_process\n"); */ - IntSource.word = 0; - IntSource.field.MgmtDmaDone = 1; - pAd->int_pending &= ~INT_MGMT_DLY; - - RTMPHandleMgmtRingDmaDoneInterrupt(pAd); - - /* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, without any */ - /* bug report output */ - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if (pAd->int_pending & INT_MGMT_DLY) { - tasklet_hi_schedule(&pObj->mgmt_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_MGMT_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void rx_done_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - BOOLEAN bReschedule = 0; - struct os_cookie *pObj; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - pAd->int_pending &= ~(INT_RX); - bReschedule = STARxDoneInterruptHandle(pAd, 0); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid rotting packet - */ - if (pAd->int_pending & INT_RX || bReschedule) { - tasklet_hi_schedule(&pObj->rx_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable Rxint again */ - rt2860_int_enable(pAd, INT_RX); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - -} - -void fifo_statistic_full_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - struct os_cookie *pObj; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - pAd->int_pending &= ~(FifoStaFullInt); - NICUpdateFifoStaCounters(pAd); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid rotting packet - */ - if (pAd->int_pending & FifoStaFullInt) { - tasklet_hi_schedule(&pObj->fifo_statistic_full_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable Rxint again */ - - rt2860_int_enable(pAd, FifoStaFullInt); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - -} - -static void ac3_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - INT_SOURCE_CSR_STRUC IntSource; - struct os_cookie *pObj; - BOOLEAN bReschedule = 0; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - -/* printk("ac0_dma_done_process\n"); */ - IntSource.word = 0; - IntSource.field.Ac3DmaDone = 1; - pAd->int_pending &= ~INT_AC3_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) { - tasklet_hi_schedule(&pObj->ac3_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC3_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac2_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - INT_SOURCE_CSR_STRUC IntSource; - struct os_cookie *pObj; - BOOLEAN bReschedule = 0; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - IntSource.word = 0; - IntSource.field.Ac2DmaDone = 1; - pAd->int_pending &= ~INT_AC2_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) { - tasklet_hi_schedule(&pObj->ac2_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC2_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac1_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - INT_SOURCE_CSR_STRUC IntSource; - struct os_cookie *pObj; - BOOLEAN bReschedule = 0; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - -/* printk("ac0_dma_done_process\n"); */ - IntSource.word = 0; - IntSource.field.Ac1DmaDone = 1; - pAd->int_pending &= ~INT_AC1_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) { - tasklet_hi_schedule(&pObj->ac1_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC1_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac0_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data; - INT_SOURCE_CSR_STRUC IntSource; - struct os_cookie *pObj; - BOOLEAN bReschedule = 0; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - -/* printk("ac0_dma_done_process\n"); */ - IntSource.word = 0; - IntSource.field.Ac0DmaDone = 1; - pAd->int_pending &= ~INT_AC0_DLY; - -/* RTMPHandleMgmtRingDmaDoneInterrupt(pAd); */ - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) { - tasklet_hi_schedule(&pObj->ac0_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC0_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -/*************************************************************************** - * - * interrupt handler related procedures. - * - **************************************************************************/ -int print_int_count; - -IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance) -{ - struct net_device *net_dev = (struct net_device *)dev_instance; - struct rt_rtmp_adapter *pAd = NULL; - INT_SOURCE_CSR_STRUC IntSource; - struct os_cookie *pObj; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - /* Note 03312008: we can not return here before - RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word); - RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); - Or kernel will panic after ifconfig ra0 down sometimes */ - - /* */ - /* Initial the Interrupt source. */ - /* */ - IntSource.word = 0x00000000L; -/* McuIntSource.word = 0x00000000L; */ - - /* */ - /* Get the interrupt sources & saved to local variable */ - /* */ - /*RTMP_IO_READ32(pAd, where, &McuIntSource.word); */ - /*RTMP_IO_WRITE32(pAd, , McuIntSource.word); */ - - /* */ - /* Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp */ - /* And at the same time, clock maybe turned off that say there is no DMA service. */ - /* when ASIC get to sleep. */ - /* To prevent system hang on power saving. */ - /* We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up. */ - /* */ - /* RT2661 => when ASIC is sleeping, MAC register cannot be read and written. */ - /* RT2860 => when ASIC is sleeping, MAC register can be read and written. */ -/* if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */ - { - RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word); - RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); /* write 1 to clear */ - } -/* else */ -/* DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); */ - -/* RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear); */ -/* RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear); */ -/* DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n", */ -/* IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear)); */ - - /* Do nothing if Reset in progress */ - if (RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS))) { - return IRQ_HANDLED; - } - /* */ - /* Handle interrupt, walk through all bits */ - /* Should start from highest priority interrupt */ - /* The priority can be adjust by altering processing if statement */ - /* */ - -#ifdef DBG - -#endif - - pAd->bPCIclkOff = FALSE; - - /* If required spinlock, each interrupt service routine has to acquire */ - /* and release itself. */ - /* */ - - /* Do nothing if NIC doesn't exist */ - if (IntSource.word == 0xffffffff) { - RTMP_SET_FLAG(pAd, - (fRTMP_ADAPTER_NIC_NOT_EXIST | - fRTMP_ADAPTER_HALT_IN_PROGRESS)); - return IRQ_HANDLED; - } - - if (IntSource.word & TxCoherent) { - DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n")); - RTMPHandleRxCoherentInterrupt(pAd); - } - - if (IntSource.word & RxCoherent) { - DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n")); - RTMPHandleRxCoherentInterrupt(pAd); - } - - if (IntSource.word & FifoStaFullInt) { - if ((pAd->int_disable_mask & FifoStaFullInt) == 0) { - /* mask FifoStaFullInt */ - rt2860_int_disable(pAd, FifoStaFullInt); - tasklet_hi_schedule(&pObj->fifo_statistic_full_task); - } - pAd->int_pending |= FifoStaFullInt; - } - - if (IntSource.word & INT_MGMT_DLY) { - if ((pAd->int_disable_mask & INT_MGMT_DLY) == 0) { - rt2860_int_disable(pAd, INT_MGMT_DLY); - tasklet_hi_schedule(&pObj->mgmt_dma_done_task); - } - pAd->int_pending |= INT_MGMT_DLY; - } - - if (IntSource.word & INT_RX) { - if ((pAd->int_disable_mask & INT_RX) == 0) { - - /* mask Rxint */ - rt2860_int_disable(pAd, INT_RX); - tasklet_hi_schedule(&pObj->rx_done_task); - } - pAd->int_pending |= INT_RX; - } - - if (IntSource.word & INT_AC3_DLY) { - - if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC3_DLY); - tasklet_hi_schedule(&pObj->ac3_dma_done_task); - } - pAd->int_pending |= INT_AC3_DLY; - } - - if (IntSource.word & INT_AC2_DLY) { - - if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC2_DLY); - tasklet_hi_schedule(&pObj->ac2_dma_done_task); - } - pAd->int_pending |= INT_AC2_DLY; - } - - if (IntSource.word & INT_AC1_DLY) { - - pAd->int_pending |= INT_AC1_DLY; - - if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC1_DLY); - tasklet_hi_schedule(&pObj->ac1_dma_done_task); - } - - } - - if (IntSource.word & INT_AC0_DLY) { - -/* - if (IntSource.word & 0x2) { - u32 reg; - RTMP_IO_READ32(pAd, DELAY_INT_CFG, ®); - printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg); - } -*/ - pAd->int_pending |= INT_AC0_DLY; - - if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC0_DLY); - tasklet_hi_schedule(&pObj->ac0_dma_done_task); - } - - } - - if (IntSource.word & PreTBTTInt) { - RTMPHandlePreTBTTInterrupt(pAd); - } - - if (IntSource.word & TBTTInt) { - RTMPHandleTBTTInterrupt(pAd); - } - - { - if (IntSource.word & AutoWakeupInt) - RTMPHandleTwakeupInterrupt(pAd); - } - - return IRQ_HANDLED; -} - -/* - * invalid or writeback cache - * and convert virtual address to physical address - */ -dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr, - size_t size, int sd_idx, int direction) -{ - struct os_cookie *pObj; - - /* - ------ Porting Information ------ - > For Tx Alloc: - mgmt packets => sd_idx = 0 - SwIdx: pAd->MgmtRing.TxCpuIdx - pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa; - - data packets => sd_idx = 1 - TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx - QueIdx: pTxBlk->QueIdx - pTxD : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa; - - > For Rx Alloc: - sd_idx = -1 - */ - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - if (sd_idx == 1) { - struct rt_tx_blk *pTxBlk; - pTxBlk = (struct rt_tx_blk *)ptr; - return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, - pTxBlk->SrcBufLen, direction); - } else { - return pci_map_single(pObj->pci_dev, ptr, size, direction); - } - -} - -void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr, - size_t size, int direction) -{ - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - pci_unmap_single(pObj->pci_dev, dma_addr, size, direction); - -} diff --git a/drivers/staging/rt2860/rt_usb.c b/drivers/staging/rt2860/rt_usb.c deleted file mode 100644 index eb037d2e04a2..000000000000 --- a/drivers/staging/rt2860/rt_usb.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtusb_bulk.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Justin P. Mattock 11/07/2010 Fix some typos. - -*/ - -#include "rt_config.h" - -void dump_urb(struct urb *purb) -{ - printk(KERN_DEBUG "urb :0x%08lx\n", (unsigned long)purb); - printk(KERN_DEBUG "\tdev :0x%08lx\n", (unsigned long)purb->dev); - printk(KERN_DEBUG "\t\tdev->state :0x%d\n", purb->dev->state); - printk(KERN_DEBUG "\tpipe :0x%08x\n", purb->pipe); - printk(KERN_DEBUG "\tstatus :%d\n", purb->status); - printk(KERN_DEBUG "\ttransfer_flags :0x%08x\n", purb->transfer_flags); - printk(KERN_DEBUG "\ttransfer_buffer :0x%08lx\n", - (unsigned long)purb->transfer_buffer); - printk(KERN_DEBUG "\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length); - printk(KERN_DEBUG "\tactual_length :%d\n", purb->actual_length); - printk(KERN_DEBUG "\tsetup_packet :0x%08lx\n", - (unsigned long)purb->setup_packet); - printk(KERN_DEBUG "\tstart_frame :%d\n", purb->start_frame); - printk(KERN_DEBUG "\tnumber_of_packets :%d\n", purb->number_of_packets); - printk(KERN_DEBUG "\tinterval :%d\n", purb->interval); - printk(KERN_DEBUG "\terror_count :%d\n", purb->error_count); - printk(KERN_DEBUG "\tcontext :0x%08lx\n", - (unsigned long)purb->context); - printk(KERN_DEBUG "\tcomplete :0x%08lx\n\n", - (unsigned long)purb->complete); -} - -/* -======================================================================== -Routine Description: - Create kernel threads & tasklets. - -Arguments: - *net_dev Pointer to wireless net device interface - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - -Note: -======================================================================== -*/ -int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd) -{ - struct rt_rtmp_os_task *pTask; - int status; - - /* - Creat TimerQ Thread, We need init timerQ related structure before create the timer thread. - */ - RtmpTimerQInit(pAd); - - pTask = &pAd->timerTask; - RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd); - status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask); - if (status == NDIS_STATUS_FAILURE) { - printk(KERN_WARNING "%s: unable to start RtmpTimerQThread\n", - RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); - return NDIS_STATUS_FAILURE; - } - - /* Creat MLME Thread */ - pTask = &pAd->mlmeTask; - RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd); - status = RtmpOSTaskAttach(pTask, MlmeThread, pTask); - if (status == NDIS_STATUS_FAILURE) { - printk(KERN_WARNING "%s: unable to start MlmeThread\n", - RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); - return NDIS_STATUS_FAILURE; - } - - /* Creat Command Thread */ - pTask = &pAd->cmdQTask; - RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd); - status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask); - if (status == NDIS_STATUS_FAILURE) { - printk(KERN_WARNING "%s: unable to start RTUSBCmdThread\n", - RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); - return NDIS_STATUS_FAILURE; - } - - return NDIS_STATUS_SUCCESS; -} - -/* -======================================================================== -Routine Description: - Close kernel threads. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - NONE - -Note: -======================================================================== -*/ -void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd) -{ - int ret; - struct rt_rtmp_os_task *pTask; - - /* Sleep 50 milliseconds so pending io might finish normally */ - RTMPusecDelay(50000); - - /* We want to wait until all pending receives and sends to the */ - /* device object. We cancel any */ - /* irps. Wait until sends and receives have stopped. */ - RTUSBCancelPendingIRPs(pAd); - - /* We need clear timerQ related structure before exits of the timer thread. */ - RtmpTimerQExit(pAd); - - /* Terminate Mlme Thread */ - pTask = &pAd->mlmeTask; - ret = RtmpOSTaskKill(pTask); - if (ret == NDIS_STATUS_FAILURE) { - DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", - RTMP_OS_NETDEV_GET_DEVNAME(pAd-> - net_dev), - pTask->taskName)); - } - - /* Terminate cmdQ thread */ - pTask = &pAd->cmdQTask; -#ifdef KTHREAD_SUPPORT - if (pTask->kthread_task) -#else - CHECK_PID_LEGALITY(pTask->taskPID) -#endif - { - mb(); - NdisAcquireSpinLock(&pAd->CmdQLock); - pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; - NdisReleaseSpinLock(&pAd->CmdQLock); - mb(); - /*RTUSBCMDUp(pAd); */ - ret = RtmpOSTaskKill(pTask); - if (ret == NDIS_STATUS_FAILURE) { - DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", - RTMP_OS_NETDEV_GET_DEVNAME - (pAd->net_dev), - pTask->taskName)); - } - pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN; - } - - /* Terminate timer thread */ - pTask = &pAd->timerTask; - ret = RtmpOSTaskKill(pTask); - if (ret == NDIS_STATUS_FAILURE) { - DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", - RTMP_OS_NETDEV_GET_DEVNAME(pAd-> - net_dev), - pTask->taskName)); - } - -} - -static void rtusb_dataout_complete(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct urb *pUrb; - struct os_cookie *pObj; - struct rt_ht_tx_context *pHTTXContext; - u8 BulkOutPipeId; - int Status; - unsigned long IrqFlags; - - pUrb = (struct urb *)data; - pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; - pAd = pHTTXContext->pAd; - pObj = (struct os_cookie *)pAd->OS_Cookie; - Status = pUrb->status; - - /* Store BulkOut PipeId */ - BulkOutPipeId = pHTTXContext->BulkOutPipeId; - pAd->BulkOutDataOneSecCount++; - - /*DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, */ - /* pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */ - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - pAd->BulkOutPending[BulkOutPipeId] = FALSE; - pHTTXContext->IRPPending = FALSE; - pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; - - if (Status == USB_ST_NOERROR) { - pAd->BulkOutComplete++; - - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - - pAd->Counters8023.GoodTransmits++; - /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ - FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext); - /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ - - } else { /* STATUS_OTHER */ - u8 *pBuf; - - pAd->BulkOutCompleteOther++; - - pBuf = - &pHTTXContext->TransferBuffer->field. - WirelessPacket[pHTTXContext->NextBulkOutPosition]; - - if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST | - fRTMP_ADAPTER_BULKOUT_RESET))) { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = BulkOutPipeId; - pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq; - } - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("BulkOutDataPacket failed: ReasonCode=%d!\n", - Status)); - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", - pAd->BulkOutReq, pAd->BulkOutComplete, - pAd->BulkOutCompleteOther)); - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", - pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], - pBuf[5], pBuf[6], pBuf[7])); - /*DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); */ - - } - - /* */ - /* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */ - /* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */ - /* */ - /*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ - if ((pHTTXContext->ENextBulkOutPosition != - pHTTXContext->CurWritePosition) - && (pHTTXContext->ENextBulkOutPosition != - (pHTTXContext->CurWritePosition + 8)) - && !RTUSB_TEST_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_FRAG << - BulkOutPipeId))) { - /* Indicate There is data available */ - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << - BulkOutPipeId)); - } - /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ - - /* Always call Bulk routine, even reset bulk. */ - /* The protection of rest bulk should be in BulkOut routine */ - RTUSBKickBulkOut(pAd); -} - -static void rtusb_null_frame_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_tx_context *pNullContext; - struct urb *pUrb; - int Status; - unsigned long irqFlag; - - pUrb = (struct urb *)data; - pNullContext = (struct rt_tx_context *)pUrb->context; - pAd = pNullContext->pAd; - Status = pUrb->status; - - /* Reset Null frame context flags */ - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); - pNullContext->IRPPending = FALSE; - pNullContext->InUse = FALSE; - pAd->BulkOutPending[0] = FALSE; - pAd->watchDogTxPendingCnt[0] = 0; - - if (Status == USB_ST_NOERROR) { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } else { /* STATUS_OTHER */ - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", - Status)); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = - (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - } - } - - /* Always call Bulk routine, even reset bulk. */ - /* The protection of rest bulk should be in BulkOut routine */ - RTUSBKickBulkOut(pAd); -} - -static void rtusb_rts_frame_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_tx_context *pRTSContext; - struct urb *pUrb; - int Status; - unsigned long irqFlag; - - pUrb = (struct urb *)data; - pRTSContext = (struct rt_tx_context *)pUrb->context; - pAd = pRTSContext->pAd; - Status = pUrb->status; - - /* Reset RTS frame context flags */ - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); - pRTSContext->IRPPending = FALSE; - pRTSContext->InUse = FALSE; - - if (Status == USB_ST_NOERROR) { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } else { /* STATUS_OTHER */ - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Bulk Out RTS Frame Failed\n")); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = - (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - } - } - - RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); - pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE; - RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); - - /* Always call Bulk routine, even reset bulk. */ - /* The protection of rest bulk should be in BulkOut routine */ - RTUSBKickBulkOut(pAd); - -} - -static void rtusb_pspoll_frame_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_tx_context *pPsPollContext; - struct urb *pUrb; - int Status; - - pUrb = (struct urb *)data; - pPsPollContext = (struct rt_tx_context *)pUrb->context; - pAd = pPsPollContext->pAd; - Status = pUrb->status; - - /* Reset PsPoll context flags */ - pPsPollContext->IRPPending = FALSE; - pPsPollContext->InUse = FALSE; - pAd->watchDogTxPendingCnt[0] = 0; - - if (Status == USB_ST_NOERROR) { - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } else { /* STATUS_OTHER */ - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Bulk Out PSPoll Failed\n")); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = - (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } - } - - RTMP_SEM_LOCK(&pAd->BulkOutLock[0]); - pAd->BulkOutPending[0] = FALSE; - RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]); - - /* Always call Bulk routine, even reset bulk. */ - /* The protection of rest bulk should be in BulkOut routine */ - RTUSBKickBulkOut(pAd); - -} - -/* -======================================================================== -Routine Description: - Handle received packets. - -Arguments: - data - URB information pointer - -Return Value: - None - -Note: -======================================================================== -*/ -static void rx_done_tasklet(unsigned long data) -{ - struct urb *pUrb; - struct rt_rx_context *pRxContext; - struct rt_rtmp_adapter *pAd; - int Status; - unsigned int IrqFlags; - - pUrb = (struct urb *)data; - pRxContext = (struct rt_rx_context *)pUrb->context; - pAd = pRxContext->pAd; - Status = pUrb->status; - - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pRxContext->BulkInOffset += pUrb->actual_length; - /*NdisInterlockedDecrement(&pAd->PendingRx); */ - pAd->PendingRx--; - - if (Status == USB_ST_NOERROR) { - pAd->BulkInComplete++; - pAd->NextRxBulkInPosition = 0; - if (pRxContext->BulkInOffset) { /* As jan's comment, it may bulk-in success but size is zero. */ - pRxContext->Readable = TRUE; - INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE); - } - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - } else { /* STATUS_OTHER */ - pAd->BulkInCompleteFail++; - /* Still read this packet although it may comtain wrong bytes. */ - pRxContext->Readable = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - - /* Parsing all packets. because after reset, the index will reset to all zero. */ - if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_BULKIN_RESET | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n", - Status, pAd->NextRxBulkInIndex, - pAd->NextRxBulkInReadIndex, - pRxContext->pUrb->actual_length)); - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, - NULL, 0); - } - } - - ASSERT((pRxContext->InUse == pRxContext->IRPPending)); - - RTUSBBulkReceive(pAd); - - return; - -} - -static void rtusb_mgmt_dma_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_tx_context *pMLMEContext; - int index; - void *pPacket; - struct urb *pUrb; - int Status; - unsigned long IrqFlags; - - pUrb = (struct urb *)data; - pMLMEContext = (struct rt_tx_context *)pUrb->context; - pAd = pMLMEContext->pAd; - Status = pUrb->status; - index = pMLMEContext->SelfIdx; - - ASSERT((pAd->MgmtRing.TxDmaIdx == index)); - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - - if (Status != USB_ST_NOERROR) { - /*Bulk-Out fail status handle */ - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Bulk Out MLME Failed, Status=%d!\n", - Status)); - /* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */ - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = - (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - } - } - - pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - - RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); - /* Reset MLME context flags */ - pMLMEContext->IRPPending = FALSE; - pMLMEContext->InUse = FALSE; - pMLMEContext->bWaitingBulkOut = FALSE; - pMLMEContext->BulkOutSize = 0; - - pPacket = pAd->MgmtRing.Cell[index].pNdisPacket; - pAd->MgmtRing.Cell[index].pNdisPacket = NULL; - - /* Increase MgmtRing Index */ - INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE); - pAd->MgmtRing.TxSwFreeIdx++; - RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - /* No-matter success or fail, we free the mgmt packet. */ - if (pPacket) - RTMPFreeNdisPacket(pAd, pPacket); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - /* do nothing and return directly. */ - } else { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) { /* For Mgmt Bulk-Out failed, ignore it now. */ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - - /* Always call Bulk routine, even reset bulk. */ - /* The protection of rest bulk should be in BulkOut routine */ - if (pAd->MgmtRing.TxSwFreeIdx < - MGMT_RING_SIZE - /* pMLMEContext->bWaitingBulkOut == TRUE */) { - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - } - RTUSBKickBulkOut(pAd); - } - } - -} - -static void rtusb_ac3_dma_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_ht_tx_context *pHTTXContext; - u8 BulkOutPipeId = 3; - struct urb *pUrb; - - pUrb = (struct urb *)data; - pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; - pAd = pHTTXContext->pAd; - - rtusb_dataout_complete((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - /* do nothing and return directly. */ - } else { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, - MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, - fRTUSB_BULK_OUT_DATA_NORMAL << 3); - RTUSBKickBulkOut(pAd); - } - } - - return; -} - -static void rtusb_ac2_dma_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_ht_tx_context *pHTTXContext; - u8 BulkOutPipeId = 2; - struct urb *pUrb; - - pUrb = (struct urb *)data; - pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; - pAd = pHTTXContext->pAd; - - rtusb_dataout_complete((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - /* do nothing and return directly. */ - } else { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, - MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, - fRTUSB_BULK_OUT_DATA_NORMAL << 2); - RTUSBKickBulkOut(pAd); - } - } - - return; -} - -static void rtusb_ac1_dma_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_ht_tx_context *pHTTXContext; - u8 BulkOutPipeId = 1; - struct urb *pUrb; - - pUrb = (struct urb *)data; - pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; - pAd = pHTTXContext->pAd; - - rtusb_dataout_complete((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - /* do nothing and return directly. */ - } else { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, - MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, - fRTUSB_BULK_OUT_DATA_NORMAL << 1); - RTUSBKickBulkOut(pAd); - } - } - return; - -} - -static void rtusb_ac0_dma_done_tasklet(unsigned long data) -{ - struct rt_rtmp_adapter *pAd; - struct rt_ht_tx_context *pHTTXContext; - u8 BulkOutPipeId = 0; - struct urb *pUrb; - - pUrb = (struct urb *)data; - pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; - pAd = pHTTXContext->pAd; - - rtusb_dataout_complete((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - /* do nothing and return directly. */ - } else { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, - NULL, 0); - } else { - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, - MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL); - RTUSBKickBulkOut(pAd); - } - } - - return; - -} - -int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd) -{ - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - /* Create receive tasklet */ - tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet, - (unsigned long)pAd); - tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->null_frame_complete_task, - rtusb_null_frame_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->rts_frame_complete_task, - rtusb_rts_frame_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->pspoll_frame_complete_task, - rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd); - - return NDIS_STATUS_SUCCESS; -} - -void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd) -{ - struct os_cookie *pObj; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - tasklet_kill(&pObj->rx_done_task); - tasklet_kill(&pObj->mgmt_dma_done_task); - tasklet_kill(&pObj->ac0_dma_done_task); - tasklet_kill(&pObj->ac1_dma_done_task); - tasklet_kill(&pObj->ac2_dma_done_task); - tasklet_kill(&pObj->ac3_dma_done_task); - tasklet_kill(&pObj->tbtt_task); - tasklet_kill(&pObj->null_frame_complete_task); - tasklet_kill(&pObj->rts_frame_complete_task); - tasklet_kill(&pObj->pspoll_frame_complete_task); -} diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h deleted file mode 100644 index 3c31340c946a..000000000000 --- a/drivers/staging/rt2860/rtmp.h +++ /dev/null @@ -1,4332 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp.h - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Lin 2002-08-01 created - James Tan 2002-09-06 modified (Revise NTCRegTable) - John Chang 2004-09-06 modified for RT2600 - Justin P. Mattock 11/07/2010 Fix some typos -*/ -#ifndef __RTMP_H__ -#define __RTMP_H__ - -#include "spectrum_def.h" -#include "rtmp_dot11.h" -#include "rtmp_chip.h" - -struct rt_rtmp_adapter; - -/*#define DBG 1 */ - -/*#define DBG_DIAGNOSE 1 */ - -/*+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */ -#define MAX_DATAMM_RETRY 3 -#define MGMT_USE_QUEUE_FLAG 0x80 -/*---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */ - -#define MAXSEQ (0xFFF) - -extern unsigned char SNAP_AIRONET[]; -extern unsigned char CISCO_OUI[]; -extern u8 BaSizeArray[4]; - -extern u8 BROADCAST_ADDR[MAC_ADDR_LEN]; -extern u8 ZERO_MAC_ADDR[MAC_ADDR_LEN]; -extern unsigned long BIT32[32]; -extern u8 BIT8[8]; -extern char *CipherName[]; -extern char *MCSToMbps[]; -extern u8 RxwiMCSToOfdmRate[12]; -extern u8 SNAP_802_1H[6]; -extern u8 SNAP_BRIDGE_TUNNEL[6]; -extern u8 SNAP_AIRONET[8]; -extern u8 CKIP_LLC_SNAP[8]; -extern u8 EAPOL_LLC_SNAP[8]; -extern u8 EAPOL[2]; -extern u8 IPX[2]; -extern u8 APPLE_TALK[2]; -extern u8 RateIdToPlcpSignal[12]; /* see IEEE802.11a-1999 p.14 */ -extern u8 OfdmRateToRxwiMCS[]; -extern u8 OfdmSignalToRateId[16]; -extern u8 default_cwmin[4]; -extern u8 default_cwmax[4]; -extern u8 default_sta_aifsn[4]; -extern u8 MapUserPriorityToAccessCategory[8]; - -extern u16 RateUpPER[]; -extern u16 RateDownPER[]; -extern u8 Phy11BNextRateDownward[]; -extern u8 Phy11BNextRateUpward[]; -extern u8 Phy11BGNextRateDownward[]; -extern u8 Phy11BGNextRateUpward[]; -extern u8 Phy11ANextRateDownward[]; -extern u8 Phy11ANextRateUpward[]; -extern char RssiSafeLevelForTxRate[]; -extern u8 RateIdToMbps[]; -extern u16 RateIdTo500Kbps[]; - -extern u8 CipherSuiteWpaNoneTkip[]; -extern u8 CipherSuiteWpaNoneTkipLen; - -extern u8 CipherSuiteWpaNoneAes[]; -extern u8 CipherSuiteWpaNoneAesLen; - -extern u8 SsidIe; -extern u8 SupRateIe; -extern u8 ExtRateIe; - -extern u8 HtCapIe; -extern u8 AddHtInfoIe; -extern u8 NewExtChanIe; - -extern u8 ErpIe; -extern u8 DsIe; -extern u8 TimIe; -extern u8 WpaIe; -extern u8 Wpa2Ie; -extern u8 IbssIe; -extern u8 Ccx2Ie; -extern u8 WapiIe; - -extern u8 WPA_OUI[]; -extern u8 RSN_OUI[]; -extern u8 WAPI_OUI[]; -extern u8 WME_INFO_ELEM[]; -extern u8 WME_PARM_ELEM[]; -extern u8 Ccx2QosInfo[]; -extern u8 Ccx2IeInfo[]; -extern u8 RALINK_OUI[]; -extern u8 PowerConstraintIE[]; - -extern u8 RateSwitchTable[]; -extern u8 RateSwitchTable11B[]; -extern u8 RateSwitchTable11G[]; -extern u8 RateSwitchTable11BG[]; - -extern u8 RateSwitchTable11BGN1S[]; -extern u8 RateSwitchTable11BGN2S[]; -extern u8 RateSwitchTable11BGN2SForABand[]; -extern u8 RateSwitchTable11N1S[]; -extern u8 RateSwitchTable11N2S[]; -extern u8 RateSwitchTable11N2SForABand[]; - -extern u8 PRE_N_HT_OUI[]; - -struct rt_rssi_sample { - char LastRssi0; /* last received RSSI */ - char LastRssi1; /* last received RSSI */ - char LastRssi2; /* last received RSSI */ - char AvgRssi0; - char AvgRssi1; - char AvgRssi2; - short AvgRssi0X8; - short AvgRssi1X8; - short AvgRssi2X8; -}; - -/* */ -/* Queue structure and macros */ -/* */ -struct rt_queue_entry; - -struct rt_queue_entry { - struct rt_queue_entry *Next; -}; - -/* Queue structure */ -struct rt_queue_header { - struct rt_queue_entry *Head; - struct rt_queue_entry *Tail; - unsigned long Number; -}; - -#define InitializeQueueHeader(QueueHeader) \ -{ \ - (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \ - (QueueHeader)->Number = 0; \ -} - -#define RemoveHeadQueue(QueueHeader) \ -(QueueHeader)->Head; \ -{ \ - struct rt_queue_entry *pNext; \ - if ((QueueHeader)->Head != NULL) { \ - pNext = (QueueHeader)->Head->Next; \ - (QueueHeader)->Head->Next = NULL; \ - (QueueHeader)->Head = pNext; \ - if (pNext == NULL) \ - (QueueHeader)->Tail = NULL; \ - (QueueHeader)->Number--; \ - } \ -} - -#define InsertHeadQueue(QueueHeader, QueueEntry) \ -{ \ - ((struct rt_queue_entry *)QueueEntry)->Next = (QueueHeader)->Head; \ - (QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry); \ - if ((QueueHeader)->Tail == NULL) \ - (QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry); \ - (QueueHeader)->Number++; \ -} - -#define InsertTailQueue(QueueHeader, QueueEntry) \ -{ \ - ((struct rt_queue_entry *)QueueEntry)->Next = NULL; \ - if ((QueueHeader)->Tail) \ - (QueueHeader)->Tail->Next = (struct rt_queue_entry *)(QueueEntry); \ - else \ - (QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry); \ - (QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry); \ - (QueueHeader)->Number++; \ -} - -#define InsertTailQueueAc(pAd, pEntry, QueueHeader, QueueEntry) \ -{ \ - ((struct rt_queue_entry *)QueueEntry)->Next = NULL; \ - if ((QueueHeader)->Tail) \ - (QueueHeader)->Tail->Next = (struct rt_queue_entry *)(QueueEntry); \ - else \ - (QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry); \ - (QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry); \ - (QueueHeader)->Number++; \ -} - -/* */ -/* Macros for flag and ref count operations */ -/* */ -#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F)) -#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F)) -#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0) -#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0) -#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F)) -/* Macro for power save flag. */ -#define RTMP_SET_PSFLAG(_M, _F) ((_M)->PSFlags |= (_F)) -#define RTMP_CLEAR_PSFLAG(_M, _F) ((_M)->PSFlags &= ~(_F)) -#define RTMP_CLEAR_PSFLAGS(_M) ((_M)->PSFlags = 0) -#define RTMP_TEST_PSFLAG(_M, _F) (((_M)->PSFlags & (_F)) != 0) -#define RTMP_TEST_PSFLAGS(_M, _F) (((_M)->PSFlags & (_F)) == (_F)) - -#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F)) -#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F)) -#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0) - -#define CLIENT_STATUS_SET_FLAG(_pEntry, _F) ((_pEntry)->ClientStatusFlags |= (_F)) -#define CLIENT_STATUS_CLEAR_FLAG(_pEntry, _F) ((_pEntry)->ClientStatusFlags &= ~(_F)) -#define CLIENT_STATUS_TEST_FLAG(_pEntry, _F) (((_pEntry)->ClientStatusFlags & (_F)) != 0) - -#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F)) -#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F)) -#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0) - -#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled) -#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) -#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) -#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - -#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE) - -#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE)) -#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE)) - -#define INC_RING_INDEX(_idx, _RingSize) \ -{ \ - (_idx) = (_idx+1) % (_RingSize); \ -} - -/* StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here. */ -#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ -{ \ - _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \ - _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \ - _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \ - _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \ - _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \ - _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \ - _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \ - _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \ - _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \ - _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \ - _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \ - NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(u8) * 16);\ -} - -#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \ -{ \ - _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (u8)(_pHtCapability->HtCapInfo.AMsduSize); \ - _pAd->MacTab.Content[BSSID_WCID].MmpsMode = (u8)(_pHtCapability->HtCapInfo.MimoPs); \ - _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (u8)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \ -} - -/* */ -/* MACRO for 32-bit PCI register read / write */ -/* */ -/* Usage : RTMP_IO_READ32( */ -/* struct rt_rtmp_adapter *pAd, */ -/* unsigned long Register_Offset, */ -/* unsigned long * pValue) */ -/* */ -/* RTMP_IO_WRITE32( */ -/* struct rt_rtmp_adapter *pAd, */ -/* unsigned long Register_Offset, */ -/* unsigned long Value) */ -/* */ - -/* */ -/* Common fragment list structure - Identical to the scatter gather frag list structure */ -/* */ -/*#define struct rt_rtmp_sg_element SCATTER_GATHER_ELEMENT */ -/*#define struct rt_rtmp_sg_element *PSCATTER_GATHER_ELEMENT */ -#define NIC_MAX_PHYS_BUF_COUNT 8 - -struct rt_rtmp_sg_element { - void *Address; - unsigned long Length; - unsigned long *Reserved; -}; - -struct rt_rtmp_sg_list { - unsigned long NumberOfElements; - unsigned long *Reserved; - struct rt_rtmp_sg_element Elements[NIC_MAX_PHYS_BUF_COUNT]; -}; - -/* */ -/* Some utility macros */ -/* */ -#define GET_LNA_GAIN(_pAd) ((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2)))) - -#define INC_COUNTER64(Val) (Val.QuadPart++) - -#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON)) -#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON)) -#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR) -#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p)) - -/* Check LEAP & CCKM flags */ -#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) -#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE)) - -/* if original Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */ -#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \ -{ \ - if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) { \ - _pExtraLlcSnapEncap = SNAP_802_1H; \ - if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \ - NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) { \ - _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \ - } \ - } \ - else { \ - _pExtraLlcSnapEncap = NULL; \ - } \ -} - -/* New Define for new Tx Path. */ -#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \ -{ \ - if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) { \ - _pExtraLlcSnapEncap = SNAP_802_1H; \ - if (NdisEqualMemory(IPX, _pBufVA, 2) || \ - NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) { \ - _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \ - } \ - } \ - else { \ - _pExtraLlcSnapEncap = NULL; \ - } \ -} - -#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \ -{ \ - NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \ - NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \ - NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \ -} - -/* if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way. */ -/* else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field */ -/* else remove the LLC/SNAP field from the result Ethernet frame */ -/* Patch for WHQL only, which did not turn on Netbios but use IPX within its payload */ -/* Note: */ -/* _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO */ -/* _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed */ -#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \ -{ \ - char LLC_Len[2]; \ - \ - _pRemovedLLCSNAP = NULL; \ - if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \ - NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) { \ - u8 *pProto = _pData + 6; \ - \ - if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \ - NdisEqualMemory(SNAP_802_1H, _pData, 6)) { \ - LLC_Len[0] = (u8)(_DataSize / 256); \ - LLC_Len[1] = (u8)(_DataSize % 256); \ - MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ - } \ - else { \ - MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \ - _pRemovedLLCSNAP = _pData; \ - _DataSize -= LENGTH_802_1_H; \ - _pData += LENGTH_802_1_H; \ - } \ - } \ - else { \ - LLC_Len[0] = (u8)(_DataSize / 256); \ - LLC_Len[1] = (u8)(_DataSize % 256); \ - MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ - } \ -} - -/* Enqueue this frame to MLME engine */ -/* We need to enqueue the whole frame because MLME need to pass data type */ -/* information from 802.11 header */ -#ifdef RTMP_MAC_PCI -#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \ -{ \ - u32 High32TSF, Low32TSF; \ - RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF); \ - RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF); \ - MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1, (u8)_Rssi2, _FrameSize, _pFrame, (u8)_PlcpSignal); \ -} -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \ -{ \ - u32 High32TSF = 0, Low32TSF = 0; \ - MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1, (u8)_Rssi2, _FrameSize, _pFrame, (u8)_PlcpSignal); \ -} -#endif /* RTMP_MAC_USB // */ - -#define MAC_ADDR_EQUAL(pAddr1, pAddr2) RTMPEqualMemory((void *)(pAddr1), (void *)(pAddr2), MAC_ADDR_LEN) -#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1 == len2) && (RTMPEqualMemory(ssid1, ssid2, len1))) - -/* */ -/* Check if it is Japan W53(ch52,56,60,64) channel. */ -/* */ -#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64)) - -#define STA_EXTRA_SETTING(_pAd) - -#define STA_PORT_SECURED(_pAd) \ -{ \ - BOOLEAN Cancelled; \ - (_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \ - NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \ - (_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \ - (_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\ - NdisReleaseSpinLock(&(_pAd)->MacTabLock); \ - RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\ - STA_EXTRA_SETTING(_pAd); \ -} - -/* */ -/* Data buffer for DMA operation, the buffer must be contiguous physical memory */ -/* Both DMA to / from CPU use the same structure. */ -/* */ -struct rt_rtmp_dmabuf { - unsigned long AllocSize; - void *AllocVa; /* TxBuf virtual address */ - dma_addr_t AllocPa; /* TxBuf physical address */ -}; - -/* */ -/* Control block (Descriptor) for all ring descriptor DMA operation, buffer must be */ -/* contiguous physical memory. char stored the binding Rx packet descriptor */ -/* which won't be released, driver has to wait until upper layer return the packet */ -/* before giving up this rx ring descriptor to ASIC. NDIS_BUFFER is associated pair */ -/* to describe the packet buffer. For Tx, char stored the tx packet descriptor */ -/* which driver should ACK upper layer when the tx is physically done or failed. */ -/* */ -struct rt_rtmp_dmacb { - unsigned long AllocSize; /* Control block size */ - void *AllocVa; /* Control block virtual address */ - dma_addr_t AllocPa; /* Control block physical address */ - void *pNdisPacket; - void *pNextNdisPacket; - - struct rt_rtmp_dmabuf DmaBuf; /* Associated DMA buffer structure */ -}; - -struct rt_rtmp_tx_ring { - struct rt_rtmp_dmacb Cell[TX_RING_SIZE]; - u32 TxCpuIdx; - u32 TxDmaIdx; - u32 TxSwFreeIdx; /* software next free tx index */ -}; - -struct rt_rtmp_rx_ring { - struct rt_rtmp_dmacb Cell[RX_RING_SIZE]; - u32 RxCpuIdx; - u32 RxDmaIdx; - int RxSwReadIdx; /* software next read index */ -}; - -struct rt_rtmp_mgmt_ring { - struct rt_rtmp_dmacb Cell[MGMT_RING_SIZE]; - u32 TxCpuIdx; - u32 TxDmaIdx; - u32 TxSwFreeIdx; /* software next free tx index */ -}; - -/* */ -/* Statistic counter structure */ -/* */ -struct rt_counter_802_3 { - /* General Stats */ - unsigned long GoodTransmits; - unsigned long GoodReceives; - unsigned long TxErrors; - unsigned long RxErrors; - unsigned long RxNoBuffer; - - /* Ethernet Stats */ - unsigned long RcvAlignmentErrors; - unsigned long OneCollision; - unsigned long MoreCollisions; - -}; - -struct rt_counter_802_11 { - unsigned long Length; - LARGE_INTEGER LastTransmittedFragmentCount; - LARGE_INTEGER TransmittedFragmentCount; - LARGE_INTEGER MulticastTransmittedFrameCount; - LARGE_INTEGER FailedCount; - LARGE_INTEGER RetryCount; - LARGE_INTEGER MultipleRetryCount; - LARGE_INTEGER RTSSuccessCount; - LARGE_INTEGER RTSFailureCount; - LARGE_INTEGER ACKFailureCount; - LARGE_INTEGER FrameDuplicateCount; - LARGE_INTEGER ReceivedFragmentCount; - LARGE_INTEGER MulticastReceivedFrameCount; - LARGE_INTEGER FCSErrorCount; -}; - -struct rt_counter_ralink { - unsigned long TransmittedByteCount; /* both successful and failure, used to calculate TX throughput */ - unsigned long ReceivedByteCount; /* both CRC okay and CRC error, used to calculate RX throughput */ - unsigned long BeenDisassociatedCount; - unsigned long BadCQIAutoRecoveryCount; - unsigned long PoorCQIRoamingCount; - unsigned long MgmtRingFullCount; - unsigned long RxCountSinceLastNULL; - unsigned long RxCount; - unsigned long RxRingErrCount; - unsigned long KickTxCount; - unsigned long TxRingErrCount; - LARGE_INTEGER RealFcsErrCount; - unsigned long PendingNdisPacketCount; - - unsigned long OneSecOsTxCount[NUM_OF_TX_RING]; - unsigned long OneSecDmaDoneCount[NUM_OF_TX_RING]; - u32 OneSecTxDoneCount; - unsigned long OneSecRxCount; - u32 OneSecTxAggregationCount; - u32 OneSecRxAggregationCount; - u32 OneSecReceivedByteCount; - u32 OneSecFrameDuplicateCount; - - u32 OneSecTransmittedByteCount; /* both successful and failure, used to calculate TX throughput */ - u32 OneSecTxNoRetryOkCount; - u32 OneSecTxRetryOkCount; - u32 OneSecTxFailCount; - u32 OneSecFalseCCACnt; /* CCA error count, for debug purpose, might move to global counter */ - u32 OneSecRxOkCnt; /* RX without error */ - u32 OneSecRxOkDataCnt; /* unicast-to-me DATA frame count */ - u32 OneSecRxFcsErrCnt; /* CRC error */ - u32 OneSecBeaconSentCnt; - u32 LastOneSecTotalTxCount; /* OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount */ - u32 LastOneSecRxOkDataCnt; /* OneSecRxOkDataCnt */ - unsigned long DuplicateRcv; - unsigned long TxAggCount; - unsigned long TxNonAggCount; - unsigned long TxAgg1MPDUCount; - unsigned long TxAgg2MPDUCount; - unsigned long TxAgg3MPDUCount; - unsigned long TxAgg4MPDUCount; - unsigned long TxAgg5MPDUCount; - unsigned long TxAgg6MPDUCount; - unsigned long TxAgg7MPDUCount; - unsigned long TxAgg8MPDUCount; - unsigned long TxAgg9MPDUCount; - unsigned long TxAgg10MPDUCount; - unsigned long TxAgg11MPDUCount; - unsigned long TxAgg12MPDUCount; - unsigned long TxAgg13MPDUCount; - unsigned long TxAgg14MPDUCount; - unsigned long TxAgg15MPDUCount; - unsigned long TxAgg16MPDUCount; - - LARGE_INTEGER TransmittedOctetsInAMSDU; - LARGE_INTEGER TransmittedAMSDUCount; - LARGE_INTEGER ReceivedOctesInAMSDUCount; - LARGE_INTEGER ReceivedAMSDUCount; - LARGE_INTEGER TransmittedAMPDUCount; - LARGE_INTEGER TransmittedMPDUsInAMPDUCount; - LARGE_INTEGER TransmittedOctetsInAMPDUCount; - LARGE_INTEGER MPDUInReceivedAMPDUCount; -}; - -struct rt_counter_drs { - /* record each TX rate's quality. 0 is best, the bigger the worse. */ - u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH]; - u8 PER[MAX_STEP_OF_TX_RATE_SWITCH]; - u8 TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */ - unsigned long CurrTxRateStableTime; /* # of second in current TX rate */ - BOOLEAN fNoisyEnvironment; - BOOLEAN fLastSecAccordingRSSI; - u8 LastSecTxRateChangeAction; /* 0: no change, 1:rate UP, 2:rate down */ - u8 LastTimeTxRateChangeAction; /*Keep last time value of LastSecTxRateChangeAction */ - unsigned long LastTxOkCount; -}; - -/*************************************************************************** - * security key related data structure - **************************************************************************/ -struct rt_cipher_key { - u8 Key[16]; /* right now we implement 4 keys, 128 bits max */ - u8 RxMic[8]; /* make alignment */ - u8 TxMic[8]; - u8 TxTsc[6]; /* 48bit TSC value */ - u8 RxTsc[6]; /* 48bit TSC value */ - u8 CipherAlg; /* 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128 */ - u8 KeyLen; - u8 BssId[6]; - /* Key length for each key, 0: entry is invalid */ - u8 Type; /* Indicate Pairwise/Group when reporting MIC error */ -}; - -/* structure to define WPA Group Key Rekey Interval */ -struct PACKED rt_802_11_wpa_rekey { - unsigned long ReKeyMethod; /* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */ - unsigned long ReKeyInterval; /* time-based: seconds, packet-based: kilo-packets */ -}; - -#ifdef RTMP_MAC_USB -/*************************************************************************** - * RTUSB I/O related data structure - **************************************************************************/ -struct rt_set_asic_wcid { - unsigned long WCID; /* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */ - unsigned long SetTid; /* time-based: seconds, packet-based: kilo-packets */ - unsigned long DeleteTid; /* time-based: seconds, packet-based: kilo-packets */ - u8 Addr[MAC_ADDR_LEN]; /* avoid in interrupt when write key */ -}; - -struct rt_set_asic_wcid_attri { - unsigned long WCID; /* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */ - unsigned long Cipher; /* ASIC Cipher definition */ - u8 Addr[ETH_LENGTH_OF_ADDRESS]; -}; - -/* for USB interface, avoid in interrupt when write key */ -struct rt_add_pairwise_key_entry { - u8 MacAddr[6]; - u16 MacTabMatchWCID; /* ASIC */ - struct rt_cipher_key CipherKey; -}; - -/* Cipher suite type for mixed mode group cipher, P802.11i-2004 */ -typedef enum _RT_802_11_CIPHER_SUITE_TYPE { - Cipher_Type_NONE, - Cipher_Type_WEP40, - Cipher_Type_TKIP, - Cipher_Type_RSVD, - Cipher_Type_CCMP, - Cipher_Type_WEP104 -} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE; -#endif /* RTMP_MAC_USB // */ - -struct rt_rogueap_entry { - u8 Addr[MAC_ADDR_LEN]; - u8 ErrorCode[2]; /*00 01-Invalid authentication type */ - /*00 02-Authentication timeout */ - /*00 03-Challenge from AP failed */ - /*00 04-Challenge to AP failed */ - BOOLEAN Reported; -}; - -struct rt_rogueap_table { - u8 RogueApNr; - struct rt_rogueap_entry RogueApEntry[MAX_LEN_OF_BSS_TABLE]; -}; - -/* */ -/* Cisco IAPP format */ -/* */ -struct rt_cisco_iapp_content { - u16 Length; /*IAPP Length */ - u8 MessageType; /*IAPP type */ - u8 FunctionCode; /*IAPP function type */ - u8 DestinaionMAC[MAC_ADDR_LEN]; - u8 SourceMAC[MAC_ADDR_LEN]; - u16 Tag; /*Tag(element IE) - Adjacent AP report */ - u16 TagLength; /*Length of element not including 4 byte header */ - u8 OUI[4]; /*0x00, 0x40, 0x96, 0x00 */ - u8 PreviousAP[MAC_ADDR_LEN]; /*MAC Address of access point */ - u16 Channel; - u16 SsidLen; - u8 Ssid[MAX_LEN_OF_SSID]; - u16 Seconds; /*Seconds that the client has been disassociated. */ -}; - -/* - * Fragment Frame structure - */ -struct rt_fragment_frame { - void *pFragPacket; - unsigned long RxSize; - u16 Sequence; - u16 LastFrag; - unsigned long Flags; /* Some extra frame information. bit 0: LLC presented */ -}; - -/* */ -/* Packet information for NdisQueryPacket */ -/* */ -struct rt_packet_info { - u32 PhysicalBufferCount; /* Physical breaks of buffer descriptor chained */ - u32 BufferCount; /* Number of Buffer descriptor chained */ - u32 TotalPacketLength; /* Self explained */ - char *pFirstBuffer; /* Pointer to first buffer descriptor */ -}; - -/* */ -/* Arcfour Structure Added by PaulWu */ -/* */ -struct rt_arcfourcontext { - u32 X; - u32 Y; - u8 STATE[256]; -}; - -/* */ -/* Tkip Key structure which RC4 key & MIC calculation */ -/* */ -struct rt_tkip_key_info { - u32 nBytesInM; /* # bytes in M for MICKEY */ - unsigned long IV16; - unsigned long IV32; - unsigned long K0; /* for MICKEY Low */ - unsigned long K1; /* for MICKEY Hig */ - unsigned long L; /* Current state for MICKEY */ - unsigned long R; /* Current state for MICKEY */ - unsigned long M; /* Message accumulator for MICKEY */ - u8 RC4KEY[16]; - u8 MIC[8]; -}; - -/* */ -/* Private / Misc data, counters for driver internal use */ -/* */ -struct rt_private { - u32 SystemResetCnt; /* System reset counter */ - u32 TxRingFullCnt; /* Tx ring full occurrence number */ - u32 PhyRxErrCnt; /* PHY Rx error count, for debug purpose, might move to global counter */ - /* Variables for WEP encryption / decryption in rtmp_wep.c */ - u32 FCSCRC32; - struct rt_arcfourcontext WEPCONTEXT; - /* Tkip stuff */ - struct rt_tkip_key_info Tx; - struct rt_tkip_key_info Rx; -}; - -/*************************************************************************** - * Channel and BBP related data structures - **************************************************************************/ -/* structure to tune BBP R66 (BBP TUNING) */ -struct rt_bbp_r66_tuning { - BOOLEAN bEnable; - u16 FalseCcaLowerThreshold; /* default 100 */ - u16 FalseCcaUpperThreshold; /* default 512 */ - u8 R66Delta; - u8 R66CurrentValue; - BOOLEAN R66LowerUpperSelect; /*Before LinkUp, Used LowerBound or UpperBound as R66 value. */ -}; - -/* structure to store channel TX power */ -struct rt_channel_tx_power { - u16 RemainingTimeForUse; /*unit: sec */ - u8 Channel; - char Power; - char Power2; - u8 MaxTxPwr; - u8 DfsReq; -}; - -/* structure to store 802.11j channel TX power */ -struct rt_channel_11j_tx_power { - u8 Channel; - u8 BW; /* BW_10 or BW_20 */ - char Power; - char Power2; - u16 RemainingTimeForUse; /*unit: sec */ -}; - -struct rt_soft_rx_ant_diversity { - u8 EvaluatePeriod; /* 0:not evalute status, 1: evaluate status, 2: switching status */ - u8 EvaluateStableCnt; - u8 Pair1PrimaryRxAnt; /* 0:Ant-E1, 1:Ant-E2 */ - u8 Pair1SecondaryRxAnt; /* 0:Ant-E1, 1:Ant-E2 */ - u8 Pair2PrimaryRxAnt; /* 0:Ant-E3, 1:Ant-E4 */ - u8 Pair2SecondaryRxAnt; /* 0:Ant-E3, 1:Ant-E4 */ - short Pair1AvgRssi[2]; /* AvgRssi[0]:E1, AvgRssi[1]:E2 */ - short Pair2AvgRssi[2]; /* AvgRssi[0]:E3, AvgRssi[1]:E4 */ - short Pair1LastAvgRssi; /* */ - short Pair2LastAvgRssi; /* */ - unsigned long RcvPktNumWhenEvaluate; - BOOLEAN FirstPktArrivedWhenEvaluate; - struct rt_ralink_timer RxAntDiversityTimer; -}; - -/*************************************************************************** - * structure for radar detection and channel switch - **************************************************************************/ -struct rt_radar_detect { - /*BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h */ - u8 CSCount; /*Channel switch counter */ - u8 CSPeriod; /*Channel switch period (beacon count) */ - u8 RDCount; /*Radar detection counter */ - u8 RDMode; /*Radar Detection mode */ - u8 RDDurRegion; /*Radar detection duration region */ - u8 BBPR16; - u8 BBPR17; - u8 BBPR18; - u8 BBPR21; - u8 BBPR22; - u8 BBPR64; - unsigned long InServiceMonitorCount; /* unit: sec */ - u8 DfsSessionTime; - BOOLEAN bFastDfs; - u8 ChMovingTime; - u8 LongPulseRadarTh; -}; - -typedef enum _ABGBAND_STATE_ { - UNKNOWN_BAND, - BG_BAND, - A_BAND, -} ABGBAND_STATE; - -#ifdef RTMP_MAC_PCI -/* Power save method control */ -typedef union _PS_CONTROL { - struct { - unsigned long EnablePSinIdle:1; /* Enable radio off when not connected to AP. radio on only when sitesurvey, */ - unsigned long EnableNewPS:1; /* Enable new Chip power save function . New method can only be applied in chip version after 2872. and PCIe. */ - unsigned long rt30xxPowerMode:2; /* Power Level Mode for rt30xx chip */ - unsigned long rt30xxFollowHostASPM:1; /* Card Follows Host's setting for rt30xx chip. */ - unsigned long rt30xxForceASPMTest:1; /* Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode. */ - unsigned long rsv:26; /* Radio Measurement Enable */ - } field; - unsigned long word; -} PS_CONTROL, *PPS_CONTROL; -#endif /* RTMP_MAC_PCI // */ - -/*************************************************************************** - * structure for MLME state machine - **************************************************************************/ -struct rt_mlme { - /* STA state machines */ - struct rt_state_machine CntlMachine; - struct rt_state_machine AssocMachine; - struct rt_state_machine AuthMachine; - struct rt_state_machine AuthRspMachine; - struct rt_state_machine SyncMachine; - struct rt_state_machine WpaPskMachine; - struct rt_state_machine LeapMachine; - STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE]; - STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE]; - STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE]; - STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE]; - STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE]; - /* Action */ - struct rt_state_machine ActMachine; - - /* common WPA state machine */ - struct rt_state_machine WpaMachine; - STATE_MACHINE_FUNC WpaFunc[WPA_FUNC_SIZE]; - - unsigned long ChannelQuality; /* 0..100, Channel Quality Indication for Roaming */ - unsigned long Now32; /* latch the value of NdisGetSystemUpTime() */ - unsigned long LastSendNULLpsmTime; - - BOOLEAN bRunning; - spinlock_t TaskLock; - struct rt_mlme_queue Queue; - - u32 ShiftReg; - - struct rt_ralink_timer PeriodicTimer; - struct rt_ralink_timer APSDPeriodicTimer; - struct rt_ralink_timer LinkDownTimer; - struct rt_ralink_timer LinkUpTimer; -#ifdef RTMP_MAC_PCI - u8 bPsPollTimerRunning; - struct rt_ralink_timer PsPollTimer; - struct rt_ralink_timer RadioOnOffTimer; -#endif /* RTMP_MAC_PCI // */ - unsigned long PeriodicRound; - unsigned long OneSecPeriodicRound; - - u8 RealRxPath; - BOOLEAN bLowThroughput; - BOOLEAN bEnableAutoAntennaCheck; - struct rt_ralink_timer RxAntEvalTimer; - -#ifdef RT30xx - u8 CaliBW40RfR24; - u8 CaliBW20RfR24; -#endif /* RT30xx // */ - -#ifdef RTMP_MAC_USB - struct rt_ralink_timer AutoWakeupTimer; - BOOLEAN AutoWakeupTimerRunning; -#endif /* RTMP_MAC_USB // */ -}; - -/*************************************************************************** - * 802.11 N related data structures - **************************************************************************/ -struct reordering_mpdu { - struct reordering_mpdu *next; - void *pPacket; /* converted to 802.3 frame */ - int Sequence; /* sequence number of MPDU */ - BOOLEAN bAMSDU; -}; - -struct reordering_list { - struct reordering_mpdu *next; - int qlen; -}; - -struct reordering_mpdu_pool { - void *mem; - spinlock_t lock; - struct reordering_list freelist; -}; - -typedef enum _REC_BLOCKACK_STATUS { - Recipient_NONE = 0, - Recipient_USED, - Recipient_HandleRes, - Recipient_Accept -} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS; - -typedef enum _ORI_BLOCKACK_STATUS { - Originator_NONE = 0, - Originator_USED, - Originator_WaitRes, - Originator_Done -} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS; - -struct rt_ba_ori_entry { - u8 Wcid; - u8 TID; - u8 BAWinSize; - u8 Token; -/* Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header. */ - u16 Sequence; - u16 TimeOutValue; - ORI_BLOCKACK_STATUS ORI_BA_Status; - struct rt_ralink_timer ORIBATimer; - void *pAdapter; -}; - -struct rt_ba_rec_entry { - u8 Wcid; - u8 TID; - u8 BAWinSize; /* 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU. */ - /*u8 NumOfRxPkt; */ - /*u8 Curindidx; // the head in the RX reordering buffer */ - u16 LastIndSeq; -/* u16 LastIndSeqAtTimer; */ - u16 TimeOutValue; - struct rt_ralink_timer RECBATimer; - unsigned long LastIndSeqAtTimer; - unsigned long nDropPacket; - unsigned long rcvSeq; - REC_BLOCKACK_STATUS REC_BA_Status; -/* u8 RxBufIdxUsed; */ - /* corresponding virtual address for RX reordering packet storage. */ - /*RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF]; */ - spinlock_t RxReRingLock; /* Rx Ring spinlock */ -/* struct _BA_REC_ENTRY *pNext; */ - void *pAdapter; - struct reordering_list list; -}; - -struct rt_ba_table { - unsigned long numAsRecipient; /* I am recipient of numAsRecipient clients. These client are in the BARecEntry[] */ - unsigned long numAsOriginator; /* I am originator of numAsOriginator clients. These clients are in the BAOriEntry[] */ - unsigned long numDoneOriginator; /* count Done Originator sessions */ - struct rt_ba_ori_entry BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE]; - struct rt_ba_rec_entry BARecEntry[MAX_LEN_OF_BA_REC_TABLE]; -}; - -/*For QureyBATableOID use; */ -struct PACKED rt_oid_ba_rec_entry { - u8 MACAddr[MAC_ADDR_LEN]; - u8 BaBitmap; /* if (BaBitmap&(1<MaxHTPhyMode.field.MODE >= MODE_HTMIX) - -#define IS_HT_RATE(_pMacEntry) \ - (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) - -#define PEER_IS_HT_RATE(_pMacEntry) \ - (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) - -/*This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic) */ -struct rt_iot { - u8 Threshold[2]; - u8 ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE]; /* compare with threshold[0] */ - u8 RefreshNum[MAX_LEN_OF_BA_REC_TABLE]; /* compare with threshold[1] */ - unsigned long OneSecInWindowCount; - unsigned long OneSecFrameDuplicateCount; - unsigned long OneSecOutWindowCount; - u8 DelOriAct; - u8 DelRecAct; - u8 RTSShortProt; - u8 RTSLongProt; - BOOLEAN bRTSLongProtOn; - BOOLEAN bLastAtheros; - BOOLEAN bCurrentAtheros; - BOOLEAN bNowAtherosBurstOn; - BOOLEAN bNextDisableRxBA; - BOOLEAN bToggle; -}; - -/* This is the registry setting for 802.11n transmit setting. Used in advanced page. */ -typedef union _REG_TRANSMIT_SETTING { - struct { - /*u32 PhyMode:4; */ - /*u32 MCS:7; // MCS */ - u32 rsv0:10; - u32 TxBF:1; - u32 BW:1; /*channel bandwidth 20MHz or 40 MHz */ - u32 ShortGI:1; - u32 STBC:1; /*SPACE */ - u32 TRANSNO:2; - u32 HTMODE:1; - u32 EXTCHA:2; - u32 rsv:13; - } field; - u32 word; -} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING; - -typedef union _DESIRED_TRANSMIT_SETTING { - struct { - u16 MCS:7; /* MCS */ - u16 PhyMode:4; - u16 FixedTxMode:2; /* If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode. */ - u16 rsv:3; - } field; - u16 word; -} DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING; - -#ifdef RTMP_MAC_USB -/*************************************************************************** - * USB-based chip Beacon related data structures - **************************************************************************/ -#define BEACON_BITMAP_MASK 0xff -struct rt_beacon_sync { - u8 BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET]; - u8 BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE]; - unsigned long TimIELocationInBeacon[HW_BEACON_MAX_COUNT]; - unsigned long CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT]; - BOOLEAN EnableBeacon; /* trigger to enable beacon transmission. */ - u8 BeaconBitMap; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */ - u8 DtimBitOn; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */ -}; -#endif /* RTMP_MAC_USB // */ - -/*************************************************************************** - * Multiple SSID related data structures - **************************************************************************/ -#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */ -#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */ - -/* clear bcmc TIM bit */ -#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \ - pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0]; - -/* set bcmc TIM bit */ -#define WLAN_MR_TIM_BCMC_SET(apidx) \ - pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0]; - -/* clear a station PS TIM bit */ -#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \ - { u8 tim_offset = wcid >> 3; \ - u8 bit_offset = wcid & 0x7; \ - ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); } - -/* set a station PS TIM bit */ -#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \ - { u8 tim_offset = wcid >> 3; \ - u8 bit_offset = wcid & 0x7; \ - ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; } - -/* configuration common to OPMODE_AP as well as OPMODE_STA */ -struct rt_common_config { - - BOOLEAN bCountryFlag; - u8 CountryCode[3]; - u8 Geography; - u8 CountryRegion; /* Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel */ - u8 CountryRegionForABand; /* Enum of country region for A band */ - u8 PhyMode; /* PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED */ - u16 Dsifs; /* in units of usec */ - unsigned long PacketFilter; /* Packet filter for receiving */ - u8 RegulatoryClass; - - char Ssid[MAX_LEN_OF_SSID]; /* NOT NULL-terminated */ - u8 SsidLen; /* the actual ssid length in used */ - u8 LastSsidLen; /* the actual ssid length in used */ - char LastSsid[MAX_LEN_OF_SSID]; /* NOT NULL-terminated */ - u8 LastBssid[MAC_ADDR_LEN]; - - u8 Bssid[MAC_ADDR_LEN]; - u16 BeaconPeriod; - u8 Channel; - u8 CentralChannel; /* Central Channel when using 40MHz is indicating. not real channel. */ - - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 ExtRateLen; - u8 DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; /* OID_802_11_DESIRED_RATES */ - u8 MaxDesiredRate; - u8 ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES]; - - unsigned long BasicRateBitmap; /* backup basic ratebitmap */ - - BOOLEAN bAPSDCapable; - BOOLEAN bInServicePeriod; - BOOLEAN bAPSDAC_BE; - BOOLEAN bAPSDAC_BK; - BOOLEAN bAPSDAC_VI; - BOOLEAN bAPSDAC_VO; - - /* because TSPEC can modify the APSD flag, we need to keep the APSD flag - requested in association stage from the station; - we need to recover the APSD flag after the TSPEC is deleted. */ - BOOLEAN bACMAPSDBackup[4]; /* for delivery-enabled & trigger-enabled both */ - BOOLEAN bACMAPSDTr[4]; /* no use */ - - BOOLEAN bNeedSendTriggerFrame; - BOOLEAN bAPSDForcePowerSave; /* Force power save mode, should only use in APSD-STAUT */ - unsigned long TriggerTimerCount; - u8 MaxSPLength; - u8 BBPCurrentBW; /* BW_10, BW_20, BW_40 */ - /* move to MULTISSID_STRUCT for MBSS */ - /*HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI. */ - REG_TRANSMIT_SETTING RegTransmitSetting; /*registry transmit setting. this is for reading registry setting only. not useful. */ - /*u8 FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode */ - u8 TxRate; /* Same value to fill in TXD. TxRate is 6-bit */ - u8 MaxTxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11 */ - u8 TxRateIndex; /* Tx rate index in RateSwitchTable */ - u8 TxRateTableSize; /* Valid Tx rate table size in RateSwitchTable */ - /*BOOLEAN bAutoTxRateSwitch; */ - u8 MinTxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11 */ - u8 RtsRate; /* RATE_xxx */ - HTTRANSMIT_SETTING MlmeTransmit; /* MGMT frame PHY rate setting when operation at Ht rate. */ - u8 MlmeRate; /* RATE_xxx, used to send MLME frames */ - u8 BasicMlmeRate; /* Default Rate for sending MLME frames */ - - u16 RtsThreshold; /* in unit of BYTE */ - u16 FragmentThreshold; /* in unit of BYTE */ - - u8 TxPower; /* in unit of mW */ - unsigned long TxPowerPercentage; /* 0~100 % */ - unsigned long TxPowerDefault; /* keep for TxPowerPercentage */ - u8 PwrConstraint; - - BACAP_STRUC BACapability; /* NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0 */ - BACAP_STRUC REGBACapability; /* NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0 */ - - struct rt_iot IOTestParm; /* 802.11n InterOpbility Test Parameter; */ - unsigned long TxPreamble; /* Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto */ - BOOLEAN bUseZeroToDisableFragment; /* Microsoft use 0 as disable */ - unsigned long UseBGProtection; /* 0: auto, 1: always use, 2: always not use */ - BOOLEAN bUseShortSlotTime; /* 0: disable, 1 - use short slot (9us) */ - BOOLEAN bEnableTxBurst; /* 1: enble TX PACKET BURST (when BA is established or AP is not a legacy WMM AP), 0: disable TX PACKET BURST */ - BOOLEAN bAggregationCapable; /* 1: enable TX aggregation when the peer supports it */ - BOOLEAN bPiggyBackCapable; /* 1: enable TX piggy-back according MAC's version */ - BOOLEAN bIEEE80211H; /* 1: enable IEEE802.11h spec. */ - unsigned long DisableOLBCDetect; /* 0: enable OLBC detect; 1 disable OLBC detect */ - - BOOLEAN bRdg; - - BOOLEAN bWmmCapable; /* 0:disable WMM, 1:enable WMM */ - struct rt_qos_capability_parm APQosCapability; /* QOS capability of the current associated AP */ - struct rt_edca_parm APEdcaParm; /* EDCA parameters of the current associated AP */ - struct rt_qbss_load_parm APQbssLoad; /* QBSS load of the current associated AP */ - u8 AckPolicy[4]; /* ACK policy of the specified AC. see ACK_xxx */ - BOOLEAN bDLSCapable; /* 0:disable DLS, 1:enable DLS */ - /* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */ - /* BOOLEAN control, either ON or OFF. These flags should always be accessed via */ - /* OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros. */ - /* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition */ - unsigned long OpStatusFlags; - - BOOLEAN NdisRadioStateOff; /*For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff. */ - ABGBAND_STATE BandState; /* For setting BBP used on B/G or A mode. */ - - /* IEEE802.11H--DFS. */ - struct rt_radar_detect RadarDetect; - - /* HT */ - u8 BASize; /* USer desired BAWindowSize. Should not exceed our max capability */ - /*struct rt_ht_capability SupportedHtPhy; */ - struct rt_ht_capability DesiredHtPhy; - struct rt_ht_capability_ie HtCapability; - struct rt_add_ht_info_ie AddHTInfo; /* Useful as AP. */ - /*This IE is used with channel switch announcement element when changing to a new 40MHz. */ - /*This IE is included in channel switch announcement frames 7.4.1.5, beacons, probe Rsp. */ - struct rt_new_ext_chan_ie NewExtChanOffset; /*7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present */ - - BOOLEAN bHTProtect; - BOOLEAN bMIMOPSEnable; - BOOLEAN bBADecline; -/*2008/11/05: KH add to support Antenna power-saving of AP<-- */ - BOOLEAN bGreenAPEnable; -/*2008/11/05: KH add to support Antenna power-saving of AP--> */ - BOOLEAN bDisableReordering; - BOOLEAN bForty_Mhz_Intolerant; - BOOLEAN bExtChannelSwitchAnnouncement; - BOOLEAN bRcvBSSWidthTriggerEvents; - unsigned long LastRcvBSSWidthTriggerEventsTime; - - u8 TxBASize; - - /* Enable wireless event */ - BOOLEAN bWirelessEvent; - BOOLEAN bWiFiTest; /* Enable this parameter for WiFi test */ - - /* Tx & Rx Stream number selection */ - u8 TxStream; - u8 RxStream; - - BOOLEAN bHardwareRadio; /* Hardware controlled Radio enabled */ - -#ifdef RTMP_MAC_USB - BOOLEAN bMultipleIRP; /* Multiple Bulk IN flag */ - u8 NumOfBulkInIRP; /* if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1 */ - struct rt_ht_capability SupportedHtPhy; - unsigned long MaxPktOneTxBulk; - u8 TxBulkFactor; - u8 RxBulkFactor; - - BOOLEAN IsUpdateBeacon; - struct rt_beacon_sync *pBeaconSync; - struct rt_ralink_timer BeaconUpdateTimer; - u32 BeaconAdjust; - u32 BeaconFactor; - u32 BeaconRemain; -#endif /* RTMP_MAC_USB // */ - - spinlock_t MeasureReqTabLock; - struct rt_measure_req_tab *pMeasureReqTab; - - spinlock_t TpcReqTabLock; - struct rt_tpc_req_tab *pTpcReqTab; - - BOOLEAN PSPXlink; /* 0: Disable. 1: Enable */ - -#if defined(RT305x) || defined(RT30xx) - /* request by Gary, for High Power issue */ - u8 HighPowerPatchDisabled; -#endif - - BOOLEAN HT_DisallowTKIP; /* Restrict the encryption type in 11n HT mode */ -}; - -/* Modified by Wu Xi-Kun 4/21/2006 */ -/* STA configuration and status */ -struct rt_sta_admin_config { - /* GROUP 1 - */ - /* User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */ - /* the user intended configuration, but not necessary fully equal to the final */ - /* settings in ACTIVE BSS after negotiation/compromise with the BSS holder (either */ - /* AP or IBSS holder). */ - /* Once initialized, user configuration can only be changed via OID_xxx */ - u8 BssType; /* BSS_INFRA or BSS_ADHOC */ - u16 AtimWin; /* used when starting a new IBSS */ - - /* GROUP 2 - */ - /* User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */ - /* the user intended configuration, and should be always applied to the final */ - /* settings in ACTIVE BSS without compromising with the BSS holder. */ - /* Once initialized, user configuration can only be changed via OID_xxx */ - u8 RssiTrigger; - u8 RssiTriggerMode; /* RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD */ - u16 DefaultListenCount; /* default listen count; */ - unsigned long WindowsPowerMode; /* Power mode for AC power */ - unsigned long WindowsBatteryPowerMode; /* Power mode for battery if exists */ - BOOLEAN bWindowsACCAMEnable; /* Enable CAM power mode when AC on */ - BOOLEAN bAutoReconnect; /* Set to TRUE when setting OID_802_11_SSID with no matching BSSID */ - unsigned long WindowsPowerProfile; /* Windows power profile, for NDIS5.1 PnP */ - - /* MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1) */ - u16 Psm; /* power management mode (PWR_ACTIVE|PWR_SAVE) */ - u16 DisassocReason; - u8 DisassocSta[MAC_ADDR_LEN]; - u16 DeauthReason; - u8 DeauthSta[MAC_ADDR_LEN]; - u16 AuthFailReason; - u8 AuthFailSta[MAC_ADDR_LEN]; - - NDIS_802_11_PRIVACY_FILTER PrivacyFilter; /* PrivacyFilter enum for 802.1X */ - NDIS_802_11_AUTHENTICATION_MODE AuthMode; /* This should match to whatever microsoft defined */ - NDIS_802_11_WEP_STATUS WepStatus; - NDIS_802_11_WEP_STATUS OrigWepStatus; /* Original wep status set from OID */ - - /* Add to support different cipher suite for WPA2/WPA mode */ - NDIS_802_11_ENCRYPTION_STATUS GroupCipher; /* Multicast cipher suite */ - NDIS_802_11_ENCRYPTION_STATUS PairCipher; /* Unicast cipher suite */ - BOOLEAN bMixCipher; /* Indicate current Pair & Group use different cipher suites */ - u16 RsnCapability; - - NDIS_802_11_WEP_STATUS GroupKeyWepStatus; - - u8 WpaPassPhrase[64]; /* WPA PSK pass phrase */ - u32 WpaPassPhraseLen; /* the length of WPA PSK pass phrase */ - u8 PMK[32]; /* WPA PSK mode PMK */ - u8 PTK[64]; /* WPA PSK mode PTK */ - u8 GTK[32]; /* GTK from authenticator */ - struct rt_bssid_info SavedPMK[PMKID_NO]; - u32 SavedPMKNum; /* Saved PMKID number */ - - u8 DefaultKeyId; - - /* WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED */ - u8 PortSecured; - - /* For WPA countermeasures */ - unsigned long LastMicErrorTime; /* record last MIC error time */ - unsigned long MicErrCnt; /* Should be 0, 1, 2, then reset to zero (after disassociation). */ - BOOLEAN bBlockAssoc; /* Block associate attempt for 60 seconds after counter measure occurred. */ - /* For WPA-PSK supplicant state */ - WPA_STATE WpaState; /* Default is SS_NOTUSE and handled by microsoft 802.1x */ - u8 ReplayCounter[8]; - u8 ANonce[32]; /* ANonce for WPA-PSK from auhenticator */ - u8 SNonce[32]; /* SNonce for WPA-PSK */ - - u8 LastSNR0; /* last received BEACON's SNR */ - u8 LastSNR1; /* last received BEACON's SNR for 2nd antenna */ - struct rt_rssi_sample RssiSample; - unsigned long NumOfAvgRssiSample; - - unsigned long LastBeaconRxTime; /* OS's timestamp of the last BEACON RX time */ - unsigned long Last11bBeaconRxTime; /* OS's timestamp of the last 11B BEACON RX time */ - unsigned long Last11gBeaconRxTime; /* OS's timestamp of the last 11G BEACON RX time */ - unsigned long Last20NBeaconRxTime; /* OS's timestamp of the last 20MHz N BEACON RX time */ - - unsigned long LastScanTime; /* Record last scan time for issue BSSID_SCAN_LIST */ - unsigned long ScanCnt; /* Scan counts since most recent SSID, BSSID, SCAN OID request */ - BOOLEAN bSwRadio; /* Software controlled Radio On/Off, TRUE: On */ - BOOLEAN bHwRadio; /* Hardware controlled Radio On/Off, TRUE: On */ - BOOLEAN bRadio; /* Radio state, And of Sw & Hw radio state */ - BOOLEAN bHardwareRadio; /* Hardware controlled Radio enabled */ - BOOLEAN bShowHiddenSSID; /* Show all known SSID in SSID list get operation */ - - /* New for WPA, windows want us to keep association information and */ - /* Fixed IEs from last association response */ - struct rt_ndis_802_11_association_information AssocInfo; - u16 ReqVarIELen; /* Length of next VIE include EID & Length */ - u8 ReqVarIEs[MAX_VIE_LEN]; /* The content saved here should be little-endian format. */ - u16 ResVarIELen; /* Length of next VIE include EID & Length */ - u8 ResVarIEs[MAX_VIE_LEN]; - - u8 RSNIE_Len; - u8 RSN_IE[MAX_LEN_OF_RSNIE]; /* The content saved here should be little-endian format. */ - - unsigned long CLBusyBytes; /* Save the total bytes received during channel load scan time */ - u16 RPIDensity[8]; /* Array for RPI density collection */ - - u8 RMReqCnt; /* Number of measurement request saved. */ - u8 CurrentRMReqIdx; /* Number of measurement request saved. */ - BOOLEAN ParallelReq; /* Parallel measurement, only one request performed, */ - /* It must be the same channel with maximum duration */ - u16 ParallelDuration; /* Maximum duration for parallel measurement */ - u8 ParallelChannel; /* Only one channel with parallel measurement */ - u16 IAPPToken; /* IAPP dialog token */ - /* Hack for channel load and noise histogram parameters */ - u8 NHFactor; /* Parameter for Noise histogram */ - u8 CLFactor; /* Parameter for channel load */ - - struct rt_ralink_timer StaQuickResponeForRateUpTimer; - BOOLEAN StaQuickResponeForRateUpTimerRunning; - - u8 DtimCount; /* 0.. DtimPeriod-1 */ - u8 DtimPeriod; /* default = 3 */ - - /*////////////////////////////////////////////////////////////////////////////////////// */ - /* This is only for WHQL test. */ - BOOLEAN WhqlTest; - /*////////////////////////////////////////////////////////////////////////////////////// */ - - struct rt_ralink_timer WpaDisassocAndBlockAssocTimer; - /* Fast Roaming */ - BOOLEAN bAutoRoaming; /* 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI */ - char dBmToRoam; /* the condition to roam when receiving Rssi less than this value. It's negative value. */ - - BOOLEAN IEEE8021X; - BOOLEAN IEEE8021x_required_keys; - struct rt_cipher_key DesireSharedKey[4]; /* Record user desired WEP keys */ - u8 DesireSharedKeyId; - - /* 0: driver ignores wpa_supplicant */ - /* 1: wpa_supplicant initiates scanning and AP selection */ - /* 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters */ - u8 WpaSupplicantUP; - u8 WpaSupplicantScanCount; - BOOLEAN bRSN_IE_FromWpaSupplicant; - - char dev_name[16]; - u16 OriDevType; - - BOOLEAN bTGnWifiTest; - BOOLEAN bScanReqIsFromWebUI; - - HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; /* For transmit phy setting in TXWI. */ - DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; - struct rt_ht_phy_info DesiredHtPhyInfo; - BOOLEAN bAutoTxRateSwitch; - -#ifdef RTMP_MAC_PCI - u8 BBPR3; - /* PS Control has 2 meanings for advanced power save function. */ - /* 1. EnablePSinIdle : When no connection, always radio off except need to do site survey. */ - /* 2. EnableNewPS : will save more current in sleep or radio off mode. */ - PS_CONTROL PSControl; -#endif /* RTMP_MAC_PCI // */ - - BOOLEAN bAutoConnectByBssid; - unsigned long BeaconLostTime; /* seconds */ - BOOLEAN bForceTxBurst; /* 1: force enble TX PACKET BURST, 0: disable */ -}; - -/* This data structure keeps the current active BSS/IBSS's configuration that this STA */ -/* had agreed upon joining the network. Which means these parameters are usually decided */ -/* by the BSS/IBSS creator instead of user configuration. Data in this data structure */ -/* is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE. */ -/* Normally, after SCAN or failed roaming attempts, we need to recover back to */ -/* the current active settings. */ -struct rt_sta_active_config { - u16 Aid; - u16 AtimWin; /* in kusec; IBSS parameter set element */ - u16 CapabilityInfo; - u16 CfpMaxDuration; - u16 CfpPeriod; - - /* Copy supported rate from desired AP's beacon. We are trying to match */ - /* AP's supported and extended rate settings. */ - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen; - u8 ExtRateLen; - /* Copy supported ht from desired AP's beacon. We are trying to match */ - struct rt_ht_phy_info SupportedPhyInfo; - struct rt_ht_capability SupportedHtPhy; -}; - -struct rt_mac_table_entry; - -struct rt_mac_table_entry { - /*Choose 1 from ValidAsWDS and ValidAsCLI to validize. */ - BOOLEAN ValidAsCLI; /* Sta mode, set this TRUE after Linkup,too. */ - BOOLEAN ValidAsWDS; /* This is WDS Entry. only for AP mode. */ - BOOLEAN ValidAsApCli; /* This is a AP-Client entry, only for AP mode which enable AP-Client functions. */ - BOOLEAN ValidAsMesh; - BOOLEAN ValidAsDls; /* This is DLS Entry. only for STA mode. */ - BOOLEAN isCached; - BOOLEAN bIAmBadAtheros; /* Flag if this is Atheros chip that has IOT problem. We need to turn on RTS/CTS protection. */ - - u8 EnqueueEapolStartTimerRunning; /* Enqueue EAPoL-Start for triggering EAP SM */ - /*jan for wpa */ - /* record which entry revoke MIC Failure, if it leaves the BSS itself, AP won't update aMICFailTime MIB */ - u8 CMTimerRunning; - u8 apidx; /* MBSS number */ - u8 RSNIE_Len; - u8 RSN_IE[MAX_LEN_OF_RSNIE]; - u8 ANonce[LEN_KEY_DESC_NONCE]; - u8 SNonce[LEN_KEY_DESC_NONCE]; - u8 R_Counter[LEN_KEY_DESC_REPLAY]; - u8 PTK[64]; - u8 ReTryCounter; - struct rt_ralink_timer RetryTimer; - struct rt_ralink_timer EnqueueStartForPSKTimer; /* A timer which enqueue EAPoL-Start for triggering PSK SM */ - NDIS_802_11_AUTHENTICATION_MODE AuthMode; /* This should match to whatever microsoft defined */ - NDIS_802_11_WEP_STATUS WepStatus; - NDIS_802_11_WEP_STATUS GroupKeyWepStatus; - AP_WPA_STATE WpaState; - GTK_STATE GTKState; - u16 PortSecured; - NDIS_802_11_PRIVACY_FILTER PrivacyFilter; /* PrivacyFilter enum for 802.1X */ - struct rt_cipher_key PairwiseKey; - void *pAd; - int PMKID_CacheIdx; - u8 PMKID[LEN_PMKID]; - - u8 Addr[MAC_ADDR_LEN]; - u8 PsMode; - SST Sst; - AUTH_STATE AuthState; /* for SHARED KEY authentication state machine used only */ - BOOLEAN IsReassocSta; /* Indicate whether this is a reassociation procedure */ - u16 Aid; - u16 CapabilityInfo; - u8 LastRssi; - unsigned long NoDataIdleCount; - u16 StationKeepAliveCount; /* unit: second */ - unsigned long PsQIdleCount; - struct rt_queue_header PsQueue; - - u32 StaConnectTime; /* the live time of this station since associated with AP */ - - BOOLEAN bSendBAR; - u16 NoBADataCountDown; - - u32 CachedBuf[16]; /* u32 (4 bytes) for alignment */ - u32 TxBFCount; /* 3*3 */ - u32 FIFOCount; - u32 DebugFIFOCount; - u32 DebugTxCount; - BOOLEAN bDlsInit; - -/*==================================================== */ -/*WDS entry needs these */ -/* if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab */ - u32 MatchWDSTabIdx; - u8 MaxSupportedRate; - u8 CurrTxRate; - u8 CurrTxRateIndex; - /* to record the each TX rate's quality. 0 is best, the bigger the worse. */ - u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH]; -/* u16 OneSecTxOkCount; */ - u32 OneSecTxNoRetryOkCount; - u32 OneSecTxRetryOkCount; - u32 OneSecTxFailCount; - u32 ContinueTxFailCnt; - u32 CurrTxRateStableTime; /* # of second in current TX rate */ - u8 TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */ -/*==================================================== */ - - BOOLEAN fNoisyEnvironment; - BOOLEAN fLastSecAccordingRSSI; - u8 LastSecTxRateChangeAction; /* 0: no change, 1:rate UP, 2:rate down */ - char LastTimeTxRateChangeAction; /*Keep last time value of LastSecTxRateChangeAction */ - unsigned long LastTxOkCount; - u8 PER[MAX_STEP_OF_TX_RATE_SWITCH]; - - /* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */ - /* BOOLEAN control, either ON or OFF. These flags should always be accessed via */ - /* CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros. */ - /* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED */ - unsigned long ClientStatusFlags; - - HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; /* For transmit phy setting in TXWI. */ - - /* HT EWC MIMO-N used parameters */ - u16 RXBAbitmap; /* fill to on-chip RXWI_BA_BITMASK in 8.1.3RX attribute entry format */ - u16 TXBAbitmap; /* This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI */ - u16 TXAutoBAbitmap; - u16 BADeclineBitmap; - u16 BARecWcidArray[NUM_OF_TID]; /* The mapping wcid of recipient session. if RXBAbitmap bit is masked */ - u16 BAOriWcidArray[NUM_OF_TID]; /* The mapping wcid of originator session. if TXBAbitmap bit is masked */ - u16 BAOriSequence[NUM_OF_TID]; /* The mapping wcid of originator session. if TXBAbitmap bit is masked */ - - /* 802.11n features. */ - u8 MpduDensity; - u8 MaxRAmpduFactor; - u8 AMsduSize; - u8 MmpsMode; /* MIMO power save more. */ - - struct rt_ht_capability_ie HTCapability; - - BOOLEAN bAutoTxRateSwitch; - - u8 RateLen; - struct rt_mac_table_entry *pNext; - u16 TxSeq[NUM_OF_TID]; - u16 NonQosDataSeq; - - struct rt_rssi_sample RssiSample; - - u32 TXMCSExpected[16]; - u32 TXMCSSuccessful[16]; - u32 TXMCSFailed[16]; - u32 TXMCSAutoFallBack[16][16]; - - unsigned long LastBeaconRxTime; - - unsigned long AssocDeadLine; -}; - -struct rt_mac_table { - u16 Size; - struct rt_mac_table_entry *Hash[HASH_TABLE_SIZE]; - struct rt_mac_table_entry Content[MAX_LEN_OF_MAC_TABLE]; - struct rt_queue_header McastPsQueue; - unsigned long PsQIdleCount; - BOOLEAN fAnyStationInPsm; - BOOLEAN fAnyStationBadAtheros; /* Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip. */ - BOOLEAN fAnyTxOPForceDisable; /* Check if it is necessary to disable BE TxOP */ - BOOLEAN fAllStationAsRalink; /* Check if all stations are ralink-chipset */ - BOOLEAN fAnyStationIsLegacy; /* Check if I use legacy rate to transmit to my BSS Station/ */ - BOOLEAN fAnyStationNonGF; /* Check if any Station can't support GF. */ - BOOLEAN fAnyStation20Only; /* Check if any Station can't support GF. */ - BOOLEAN fAnyStationMIMOPSDynamic; /* Check if any Station is MIMO Dynamic */ - BOOLEAN fAnyBASession; /* Check if there is BA session. Force turn on RTS/CTS */ -/*2008/10/28: KH add to support Antenna power-saving of AP<-- */ -/*2008/10/28: KH add to support Antenna power-saving of AP--> */ -}; - -struct wificonf { - BOOLEAN bShortGI; - BOOLEAN bGreenField; -}; - -struct rt_rtmp_dev_info { - u8 chipName[16]; - RTMP_INF_TYPE infType; -}; - -struct rt_rtmp_chip_op { - /* Calibration access related callback functions */ - int (*eeinit) (struct rt_rtmp_adapter *pAd); /* int (*eeinit)(struct rt_rtmp_adapter *pAd); */ - int (*eeread) (struct rt_rtmp_adapter *pAd, u16 offset, u16 *pValue); /* int (*eeread)(struct rt_rtmp_adapter *pAd, int offset, u16 *pValue); */ - - /* MCU related callback functions */ - int (*loadFirmware) (struct rt_rtmp_adapter *pAd); /* int (*loadFirmware)(struct rt_rtmp_adapter *pAd); */ - int (*eraseFirmware) (struct rt_rtmp_adapter *pAd); /* int (*eraseFirmware)(struct rt_rtmp_adapter *pAd); */ - int (*sendCommandToMcu) (struct rt_rtmp_adapter *pAd, u8 cmd, u8 token, u8 arg0, u8 arg1);; /* int (*sendCommandToMcu)(struct rt_rtmp_adapter *pAd, u8 cmd, u8 token, u8 arg0, u8 arg1); */ - - /* RF access related callback functions */ - struct rt_reg_pair *pRFRegTable; - void (*AsicRfInit) (struct rt_rtmp_adapter *pAd); - void (*AsicRfTurnOn) (struct rt_rtmp_adapter *pAd); - void (*AsicRfTurnOff) (struct rt_rtmp_adapter *pAd); - void (*AsicReverseRfFromSleepMode) (struct rt_rtmp_adapter *pAd); - void (*AsicHaltAction) (struct rt_rtmp_adapter *pAd); -}; - -/* */ -/* The miniport adapter structure */ -/* */ -struct rt_rtmp_adapter { - void *OS_Cookie; /* save specific structure relative to OS */ - struct net_device *net_dev; - unsigned long VirtualIfCnt; - const struct firmware *firmware; - - struct rt_rtmp_chip_op chipOps; - u16 ThisTbttNumToNextWakeUp; - -#ifdef RTMP_MAC_PCI -/*****************************************************************************************/ -/* PCI related parameters */ -/*****************************************************************************************/ - u8 *CSRBaseAddress; /* PCI MMIO Base Address, all access will use */ - unsigned int irq_num; - - u16 LnkCtrlBitMask; - u16 RLnkCtrlConfiguration; - u16 RLnkCtrlOffset; - u16 HostLnkCtrlConfiguration; - u16 HostLnkCtrlOffset; - u16 PCIePowerSaveLevel; - unsigned long Rt3xxHostLinkCtrl; /* USed for 3090F chip */ - unsigned long Rt3xxRalinkLinkCtrl; /* USed for 3090F chip */ - u16 DeviceID; /* Read from PCI config */ - unsigned long AccessBBPFailCount; - BOOLEAN bPCIclkOff; /* flag that indicates if the PICE power status in Configuration Space.. */ - BOOLEAN bPCIclkOffDisableTx; /* */ - - BOOLEAN brt30xxBanMcuCmd; /*when = 0xff means all commands are ok to set . */ - BOOLEAN b3090ESpecialChip; /*3090E special chip that write EEPROM 0x24=0x9280. */ - unsigned long CheckDmaBusyCount; /* Check Interrupt Status Register Count. */ - - u32 int_enable_reg; - u32 int_disable_mask; - u32 int_pending; - - struct rt_rtmp_dmabuf TxBufSpace[NUM_OF_TX_RING]; /* Shared memory of all 1st pre-allocated TxBuf associated with each TXD */ - struct rt_rtmp_dmabuf RxDescRing; /* Shared memory for RX descriptors */ - struct rt_rtmp_dmabuf TxDescRing[NUM_OF_TX_RING]; /* Shared memory for Tx descriptors */ - struct rt_rtmp_tx_ring TxRing[NUM_OF_TX_RING]; /* AC0~4 + HCCA */ -#endif /* RTMP_MAC_PCI // */ - - spinlock_t irq_lock; - u8 irq_disabled; - -#ifdef RTMP_MAC_USB -/*****************************************************************************************/ -/* USB related parameters */ -/*****************************************************************************************/ - struct usb_config_descriptor *config; - u32 BulkInEpAddr; /* bulk-in endpoint address */ - u32 BulkOutEpAddr[6]; /* bulk-out endpoint address */ - - u32 NumberOfPipes; - u16 BulkOutMaxPacketSize; - u16 BulkInMaxPacketSize; - - /*======Control Flags */ - long PendingIoCount; - unsigned long BulkFlags; - BOOLEAN bUsbTxBulkAggre; /* Flags for bulk out data priority */ - - /*======Cmd Thread */ - struct rt_cmdq CmdQ; - spinlock_t CmdQLock; /* CmdQLock spinlock */ - struct rt_rtmp_os_task cmdQTask; - - /*======Semaphores (event) */ - struct semaphore UsbVendorReq_semaphore; - void *UsbVendorReqBuf; - wait_queue_head_t *wait; -#endif /* RTMP_MAC_USB // */ - -/*****************************************************************************************/ -/* RBUS related parameters */ -/*****************************************************************************************/ - -/*****************************************************************************************/ -/* Both PCI/USB related parameters */ -/*****************************************************************************************/ - /*struct rt_rtmp_dev_info chipInfo; */ - RTMP_INF_TYPE infType; - -/*****************************************************************************************/ -/* Driver Mgmt related parameters */ -/*****************************************************************************************/ - struct rt_rtmp_os_task mlmeTask; -#ifdef RTMP_TIMER_TASK_SUPPORT - /* If you want use timer task to handle the timer related jobs, enable this. */ - struct rt_rtmp_timer_task_queue TimerQ; - spinlock_t TimerQLock; - struct rt_rtmp_os_task timerTask; -#endif /* RTMP_TIMER_TASK_SUPPORT // */ - -/*****************************************************************************************/ -/* Tx related parameters */ -/*****************************************************************************************/ - BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; /* for ensuring RTUSBDeQueuePacket get call once */ - spinlock_t DeQueueLock[NUM_OF_TX_RING]; - -#ifdef RTMP_MAC_USB - /* Data related context and AC specified, 4 AC supported */ - spinlock_t BulkOutLock[6]; /* BulkOut spinlock for 4 ACs */ - spinlock_t MLMEBulkOutLock; /* MLME BulkOut lock */ - - struct rt_ht_tx_context TxContext[NUM_OF_TX_RING]; - spinlock_t TxContextQueueLock[NUM_OF_TX_RING]; /* TxContextQueue spinlock */ - - /* 4 sets of Bulk Out index and pending flag */ - u8 NextBulkOutIndex[4]; /* only used for 4 EDCA bulkout pipe */ - - BOOLEAN BulkOutPending[6]; /* used for total 6 bulkout pipe */ - u8 bulkResetPipeid; - BOOLEAN MgmtBulkPending; - unsigned long bulkResetReq[6]; -#endif /* RTMP_MAC_USB // */ - - /* resource for software backlog queues */ - struct rt_queue_header TxSwQueue[NUM_OF_TX_RING]; /* 4 AC + 1 HCCA */ - spinlock_t TxSwQueueLock[NUM_OF_TX_RING]; /* TxSwQueue spinlock */ - - struct rt_rtmp_dmabuf MgmtDescRing; /* Shared memory for MGMT descriptors */ - struct rt_rtmp_mgmt_ring MgmtRing; - spinlock_t MgmtRingLock; /* Prio Ring spinlock */ - -/*****************************************************************************************/ -/* Rx related parameters */ -/*****************************************************************************************/ - -#ifdef RTMP_MAC_PCI - struct rt_rtmp_rx_ring RxRing; - spinlock_t RxRingLock; /* Rx Ring spinlock */ -#ifdef RT3090 - spinlock_t McuCmdLock; /*MCU Command Queue spinlock */ -#endif /* RT3090 // */ -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - struct rt_rx_context RxContext[RX_RING_SIZE]; /* 1 for redundant multiple IRP bulk in. */ - spinlock_t BulkInLock; /* BulkIn spinlock for 4 ACs */ - u8 PendingRx; /* The Maximum pending Rx value should be RX_RING_SIZE. */ - u8 NextRxBulkInIndex; /* Indicate the current RxContext Index which hold by Host controller. */ - u8 NextRxBulkInReadIndex; /* Indicate the current RxContext Index which driver can read & process it. */ - unsigned long NextRxBulkInPosition; /* Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength. */ - unsigned long TransferBufferLength; /* current length of the packet buffer */ - unsigned long ReadPosition; /* current read position in a packet buffer */ -#endif /* RTMP_MAC_USB // */ - -/*****************************************************************************************/ -/* ASIC related parameters */ -/*****************************************************************************************/ - u32 MACVersion; /* MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101).. */ - - /* --------------------------- */ - /* E2PROM */ - /* --------------------------- */ - unsigned long EepromVersion; /* byte 0: version, byte 1: revision, byte 2~3: unused */ - unsigned long FirmwareVersion; /* byte 0: Minor version, byte 1: Major version, otherwise unused. */ - u16 EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS]; - u8 EEPROMAddressNum; /* 93c46=6 93c66=8 */ - BOOLEAN EepromAccess; - u8 EFuseTag; - - /* --------------------------- */ - /* BBP Control */ - /* --------------------------- */ - u8 BbpWriteLatch[140]; /* record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID */ - char BbpRssiToDbmDelta; /* change from u8 to char for high power */ - struct rt_bbp_r66_tuning BbpTuning; - - /* ---------------------------- */ - /* RFIC control */ - /* ---------------------------- */ - u8 RfIcType; /* RFIC_xxx */ - unsigned long RfFreqOffset; /* Frequency offset for channel switching */ - struct rt_rtmp_rf_regs LatchRfRegs; /* latch the latest RF programming value since RF IC doesn't support READ */ - - EEPROM_ANTENNA_STRUC Antenna; /* Since Antenna definition is different for a & g. We need to save it for future reference. */ - EEPROM_NIC_CONFIG2_STRUC NicConfig2; - - /* This soft Rx Antenna Diversity mechanism is used only when user set */ - /* RX Antenna = DIVERSITY ON */ - struct rt_soft_rx_ant_diversity RxAnt; - - u8 RFProgSeq; - struct rt_channel_tx_power TxPower[MAX_NUM_OF_CHANNELS]; /* Store Tx power value for all channels. */ - struct rt_channel_tx_power ChannelList[MAX_NUM_OF_CHANNELS]; /* list all supported channels for site survey */ - struct rt_channel_11j_tx_power TxPower11J[MAX_NUM_OF_11JCHANNELS]; /* 802.11j channel and bw */ - struct rt_channel_11j_tx_power ChannelList11J[MAX_NUM_OF_11JCHANNELS]; /* list all supported channels for site survey */ - - u8 ChannelListNum; /* number of channel in ChannelList[] */ - u8 Bbp94; - BOOLEAN BbpForCCK; - unsigned long Tx20MPwrCfgABand[5]; - unsigned long Tx20MPwrCfgGBand[5]; - unsigned long Tx40MPwrCfgABand[5]; - unsigned long Tx40MPwrCfgGBand[5]; - - BOOLEAN bAutoTxAgcA; /* Enable driver auto Tx Agc control */ - u8 TssiRefA; /* Store Tssi reference value as 25 temperature. */ - u8 TssiPlusBoundaryA[5]; /* Tssi boundary for increase Tx power to compensate. */ - u8 TssiMinusBoundaryA[5]; /* Tssi boundary for decrease Tx power to compensate. */ - u8 TxAgcStepA; /* Store Tx TSSI delta increment / decrement value */ - char TxAgcCompensateA; /* Store the compensation (TxAgcStep * (idx-1)) */ - - BOOLEAN bAutoTxAgcG; /* Enable driver auto Tx Agc control */ - u8 TssiRefG; /* Store Tssi reference value as 25 temperature. */ - u8 TssiPlusBoundaryG[5]; /* Tssi boundary for increase Tx power to compensate. */ - u8 TssiMinusBoundaryG[5]; /* Tssi boundary for decrease Tx power to compensate. */ - u8 TxAgcStepG; /* Store Tx TSSI delta increment / decrement value */ - char TxAgcCompensateG; /* Store the compensation (TxAgcStep * (idx-1)) */ - - char BGRssiOffset0; /* Store B/G RSSI#0 Offset value on EEPROM 0x46h */ - char BGRssiOffset1; /* Store B/G RSSI#1 Offset value */ - char BGRssiOffset2; /* Store B/G RSSI#2 Offset value */ - - char ARssiOffset0; /* Store A RSSI#0 Offset value on EEPROM 0x4Ah */ - char ARssiOffset1; /* Store A RSSI#1 Offset value */ - char ARssiOffset2; /* Store A RSSI#2 Offset value */ - - char BLNAGain; /* Store B/G external LNA#0 value on EEPROM 0x44h */ - char ALNAGain0; /* Store A external LNA#0 value for ch36~64 */ - char ALNAGain1; /* Store A external LNA#1 value for ch100~128 */ - char ALNAGain2; /* Store A external LNA#2 value for ch132~165 */ -#ifdef RT30xx - /* for 3572 */ - u8 Bbp25; - u8 Bbp26; - - u8 TxMixerGain24G; /* Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G */ - u8 TxMixerGain5G; -#endif /* RT30xx // */ - /* ---------------------------- */ - /* LED control */ - /* ---------------------------- */ - MCU_LEDCS_STRUC LedCntl; - u16 Led1; /* read from EEPROM 0x3c */ - u16 Led2; /* EEPROM 0x3e */ - u16 Led3; /* EEPROM 0x40 */ - u8 LedIndicatorStrength; - u8 RssiSingalstrengthOffet; - BOOLEAN bLedOnScanning; - u8 LedStatus; - -/*****************************************************************************************/ -/* 802.11 related parameters */ -/*****************************************************************************************/ - /* outgoing BEACON frame buffer and corresponding TXD */ - struct rt_txwi BeaconTxWI; - u8 *BeaconBuf; - u16 BeaconOffset[HW_BEACON_MAX_COUNT]; - - /* pre-build PS-POLL and NULL frame upon link up. for efficiency purpose. */ - struct rt_pspoll_frame PsPollFrame; - struct rt_header_802_11 NullFrame; - -#ifdef RTMP_MAC_USB - struct rt_tx_context BeaconContext[BEACON_RING_SIZE]; - struct rt_tx_context NullContext; - struct rt_tx_context PsPollContext; - struct rt_tx_context RTSContext; -#endif /* RTMP_MAC_USB // */ - -/*=========AP=========== */ - -/*=======STA=========== */ - /* ----------------------------------------------- */ - /* STA specific configuration & operation status */ - /* used only when pAd->OpMode == OPMODE_STA */ - /* ----------------------------------------------- */ - struct rt_sta_admin_config StaCfg; /* user desired settings */ - struct rt_sta_active_config StaActive; /* valid only when ADHOC_ON(pAd) || INFRA_ON(pAd) */ - char nickname[IW_ESSID_MAX_SIZE + 1]; /* nickname, only used in the iwconfig i/f */ - int PreMediaState; - -/*=======Common=========== */ - /* OP mode: either AP or STA */ - u8 OpMode; /* OPMODE_STA, OPMODE_AP */ - - int IndicateMediaState; /* Base on Indication state, default is NdisMediaStateDisConnected */ - - /* MAT related parameters */ - - /* configuration: read from Registry & E2PROM */ - BOOLEAN bLocalAdminMAC; /* Use user changed MAC */ - u8 PermanentAddress[MAC_ADDR_LEN]; /* Factory default MAC address */ - u8 CurrentAddress[MAC_ADDR_LEN]; /* User changed MAC address */ - - /* ------------------------------------------------------ */ - /* common configuration to both OPMODE_STA and OPMODE_AP */ - /* ------------------------------------------------------ */ - struct rt_common_config CommonCfg; - struct rt_mlme Mlme; - - /* AP needs those variables for site survey feature. */ - struct rt_mlme_aux MlmeAux; /* temporary settings used during MLME state machine */ - struct rt_bss_table ScanTab; /* store the latest SCAN result */ - - /*About MacTab, the sta driver will use #0 and #1 for multicast and AP. */ - struct rt_mac_table MacTab; /* ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table. */ - spinlock_t MacTabLock; - - struct rt_ba_table BATable; - - spinlock_t BATabLock; - struct rt_ralink_timer RECBATimer; - - /* encryption/decryption KEY tables */ - struct rt_cipher_key SharedKey[MAX_MBSSID_NUM][4]; /* STA always use SharedKey[BSS0][0..3] */ - - /* RX re-assembly buffer for fragmentation */ - struct rt_fragment_frame FragFrame; /* Frame storage for fragment frame */ - - /* various Counters */ - struct rt_counter_802_3 Counters8023; /* 802.3 counters */ - struct rt_counter_802_11 WlanCounters; /* 802.11 MIB counters */ - struct rt_counter_ralink RalinkCounters; /* Ralink proprietary counters */ - struct rt_counter_drs DrsCounters; /* counters for Dynamic TX Rate Switching */ - struct rt_private PrivateInfo; /* Private information & counters */ - - /* flags, see fRTMP_ADAPTER_xxx flags */ - unsigned long Flags; /* Represent current device status */ - unsigned long PSFlags; /* Power Save operation flag. */ - - /* current TX sequence # */ - u16 Sequence; - - /* Control disconnect / connect event generation */ - /*+++Not used anymore */ - unsigned long LinkDownTime; - /*--- */ - unsigned long LastRxRate; - unsigned long LastTxRate; - /*+++Used only for Station */ - BOOLEAN bConfigChanged; /* Config Change flag for the same SSID setting */ - /*--- */ - - unsigned long ExtraInfo; /* Extra information for displaying status */ - unsigned long SystemErrorBitmap; /* b0: E2PROM version error */ - - /*+++Not used anymore */ - unsigned long MacIcVersion; /* MAC/BBP serial interface issue solved after ver.D */ - /*--- */ - - /* --------------------------- */ - /* System event log */ - /* --------------------------- */ - struct rt_802_11_event_table EventTab; - - BOOLEAN HTCEnable; - - /*****************************************************************************************/ - /* Statistic related parameters */ - /*****************************************************************************************/ -#ifdef RTMP_MAC_USB - unsigned long BulkOutDataOneSecCount; - unsigned long BulkInDataOneSecCount; - unsigned long BulkLastOneSecCount; /* BulkOutDataOneSecCount + BulkInDataOneSecCount */ - unsigned long watchDogRxCnt; - unsigned long watchDogRxOverFlowCnt; - unsigned long watchDogTxPendingCnt[NUM_OF_TX_RING]; - int TransferedLength[NUM_OF_TX_RING]; -#endif /* RTMP_MAC_USB // */ - - BOOLEAN bUpdateBcnCntDone; - unsigned long watchDogMacDeadlock; /* prevent MAC/BBP into deadlock condition */ - /* ---------------------------- */ - /* DEBUG paramerts */ - /* ---------------------------- */ - /*unsigned long DebugSetting[4]; */ - BOOLEAN bBanAllBaSetup; - BOOLEAN bPromiscuous; - - /* ---------------------------- */ - /* rt2860c emulation-use Parameters */ - /* ---------------------------- */ - /*unsigned long rtsaccu[30]; */ - /*unsigned long ctsaccu[30]; */ - /*unsigned long cfendaccu[30]; */ - /*unsigned long bacontent[16]; */ - /*unsigned long rxint[RX_RING_SIZE+1]; */ - /*u8 rcvba[60]; */ - BOOLEAN bLinkAdapt; - BOOLEAN bForcePrintTX; - BOOLEAN bForcePrintRX; - /*BOOLEAN bDisablescanning; //defined in RT2870 USB */ - BOOLEAN bStaFifoTest; - BOOLEAN bProtectionTest; - BOOLEAN bBroadComHT; - /*+++Following add from RT2870 USB. */ - unsigned long BulkOutReq; - unsigned long BulkOutComplete; - unsigned long BulkOutCompleteOther; - unsigned long BulkOutCompleteCancel; /* seems not used now? */ - unsigned long BulkInReq; - unsigned long BulkInComplete; - unsigned long BulkInCompleteFail; - /*--- */ - - struct wificonf WIFItestbed; - - struct reordering_mpdu_pool mpdu_blk_pool; - - unsigned long OneSecondnonBEpackets; /* record non BE packets per second */ - -#ifdef LINUX - struct iw_statistics iw_stats; - - struct net_device_stats stats; -#endif /* LINUX // */ - - unsigned long TbttTickCount; -#ifdef PCI_MSI_SUPPORT - BOOLEAN HaveMsi; -#endif /* PCI_MSI_SUPPORT // */ - - u8 is_on; - -#define TIME_BASE (1000000/OS_HZ) -#define TIME_ONE_SECOND (1000000/TIME_BASE) - u8 flg_be_adjust; - unsigned long be_adjust_last_time; - - u8 FlgCtsEnabled; - u8 PM_FlgSuspend; - -#ifdef RT30xx -#ifdef RTMP_EFUSE_SUPPORT - BOOLEAN bUseEfuse; - u8 EEPROMImage[1024]; -#endif /* RTMP_EFUSE_SUPPORT // */ -#endif /* RT30xx // */ -}; - -#define DELAYINTMASK 0x0003fffb -#define INTMASK 0x0003fffb -#define IndMask 0x0003fffc -#define RxINT 0x00000005 /* Delayed Rx or indivi rx */ -#define TxDataInt 0x000000fa /* Delayed Tx or indivi tx */ -#define TxMgmtInt 0x00000102 /* Delayed Tx or indivi tx */ -#define TxCoherent 0x00020000 /* tx coherent */ -#define RxCoherent 0x00010000 /* rx coherent */ -#define McuCommand 0x00000200 /* mcu */ -#define PreTBTTInt 0x00001000 /* Pre-TBTT interrupt */ -#define TBTTInt 0x00000800 /* TBTT interrupt */ -#define GPTimeOutInt 0x00008000 /* GPtimeout interrupt */ -#define AutoWakeupInt 0x00004000 /* AutoWakeupInt interrupt */ -#define FifoStaFullInt 0x00002000 /* fifo statistics full interrupt */ - -/*************************************************************************** - * Rx Path software control block related data structures - **************************************************************************/ -struct rt_rx_blk { - RT28XX_RXD_STRUC RxD; - struct rt_rxwi *pRxWI; - struct rt_header_802_11 *pHeader; - void *pRxPacket; - u8 *pData; - u16 DataSize; - u16 Flags; - u8 UserPriority; /* for calculate TKIP MIC using */ -}; - -#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag) -#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag) -#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag)) - -#define fRX_WDS 0x0001 -#define fRX_AMSDU 0x0002 -#define fRX_ARALINK 0x0004 -#define fRX_HTC 0x0008 -#define fRX_PAD 0x0010 -#define fRX_AMPDU 0x0020 -#define fRX_QOS 0x0040 -#define fRX_INFRA 0x0080 -#define fRX_EAP 0x0100 -#define fRX_MESH 0x0200 -#define fRX_APCLI 0x0400 -#define fRX_DLS 0x0800 -#define fRX_WPI 0x1000 - -#define LENGTH_AMSDU_SUBFRAMEHEAD 14 -#define LENGTH_ARALINK_SUBFRAMEHEAD 14 -#define LENGTH_ARALINK_HEADER_FIELD 2 - -/*************************************************************************** - * Tx Path software control block related data structures - **************************************************************************/ -#define TX_UNKOWN_FRAME 0x00 -#define TX_MCAST_FRAME 0x01 -#define TX_LEGACY_FRAME 0x02 -#define TX_AMPDU_FRAME 0x04 -#define TX_AMSDU_FRAME 0x08 -#define TX_RALINK_FRAME 0x10 -#define TX_FRAG_FRAME 0x20 - -/* Currently the sizeof(struct rt_tx_blk) is 148 bytes. */ -struct rt_tx_blk { - u8 QueIdx; - u8 TxFrameType; /* Indicate the Transmission type of the all frames in one batch */ - u8 TotalFrameNum; /* Total frame number that wants to send-out in one batch */ - u16 TotalFragNum; /* Total frame fragments required in one batch */ - u16 TotalFrameLen; /* Total length of all frames that wants to send-out in one batch */ - - struct rt_queue_header TxPacketList; - struct rt_mac_table_entry *pMacEntry; /* NULL: packet with 802.11 RA field is multicast/broadcast address */ - HTTRANSMIT_SETTING *pTransmit; - - /* Following structure used for the characteristics of a specific packet. */ - void *pPacket; - u8 *pSrcBufHeader; /* Reference to the head of sk_buff->data */ - u8 *pSrcBufData; /* Reference to the sk_buff->data, will change depending on the handling progresss */ - u32 SrcBufLen; /* Length of packet payload which not including Layer 2 header */ - u8 *pExtraLlcSnapEncap; /* NULL means no extra LLC/SNAP is required */ - u8 HeaderBuf[128]; /* TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */ - /*RT2870 2.1.0.0 uses only 80 bytes */ - /*RT3070 2.1.1.0 uses only 96 bytes */ - /*RT3090 2.1.0.0 uses only 96 bytes */ - u8 MpduHeaderLen; /* 802.11 header length NOT including the padding */ - u8 HdrPadLen; /* recording Header Padding Length; */ - u8 apidx; /* The interface associated to this packet */ - u8 Wcid; /* The MAC entry associated to this packet */ - u8 UserPriority; /* priority class of packet */ - u8 FrameGap; /* what kind of IFS does this packet use */ - u8 MpduReqNum; /* number of fragments of this frame */ - u8 TxRate; /* TODO: Obsoleted? Should change to MCS? */ - u8 CipherAlg; /* cipher alogrithm */ - struct rt_cipher_key *pKey; - - u16 Flags; /*See following definitions for detail. */ - - /*YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer. */ - unsigned long Priv; /* Hardware specific value saved in here. */ -}; - -#define fTX_bRtsRequired 0x0001 /* Indicate if need send RTS frame for protection. Not used in RT2860/RT2870. */ -#define fTX_bAckRequired 0x0002 /* the packet need ack response */ -#define fTX_bPiggyBack 0x0004 /* Legacy device use Piggback or not */ -#define fTX_bHTRate 0x0008 /* allow to use HT rate */ -#define fTX_bForceNonQoS 0x0010 /* force to transmit frame without WMM-QoS in HT mode */ -#define fTX_bAllowFrag 0x0020 /* allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment */ -#define fTX_bMoreData 0x0040 /* there are more data packets in PowerSave Queue */ -#define fTX_bWMM 0x0080 /* QOS Data */ -#define fTX_bClearEAPFrame 0x0100 - -#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag) -#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0) -#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag)) - -/*************************************************************************** - * Other static inline function definitions - **************************************************************************/ -static inline void ConvertMulticastIP2MAC(u8 *pIpAddr, - u8 **ppMacAddr, - u16 ProtoType) -{ - if (pIpAddr == NULL) - return; - - if (ppMacAddr == NULL || *ppMacAddr == NULL) - return; - - switch (ProtoType) { - case ETH_P_IPV6: -/* memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */ - *(*ppMacAddr) = 0x33; - *(*ppMacAddr + 1) = 0x33; - *(*ppMacAddr + 2) = pIpAddr[12]; - *(*ppMacAddr + 3) = pIpAddr[13]; - *(*ppMacAddr + 4) = pIpAddr[14]; - *(*ppMacAddr + 5) = pIpAddr[15]; - break; - - case ETH_P_IP: - default: -/* memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */ - *(*ppMacAddr) = 0x01; - *(*ppMacAddr + 1) = 0x00; - *(*ppMacAddr + 2) = 0x5e; - *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f; - *(*ppMacAddr + 4) = pIpAddr[2]; - *(*ppMacAddr + 5) = pIpAddr[3]; - break; - } - - return; -} - -char *GetPhyMode(int Mode); -char *GetBW(int BW); - -/* */ -/* Private routines in rtmp_init.c */ -/* */ -int RTMPAllocAdapterBlock(void *handle, - struct rt_rtmp_adapter **ppAdapter); - -int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd); - -void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd); - -int NICReadRegParameters(struct rt_rtmp_adapter *pAd, - void *WrapperConfigurationContext); - -#ifdef RTMP_RF_RW_SUPPORT -void NICInitRFRegisters(struct rt_rtmp_adapter *pAd); - -void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd); - -int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd, - u8 regID, u8 value); - -int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd, - u8 regID, u8 *pValue); -#endif /* RTMP_RF_RW_SUPPORT // */ - -void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr); - -void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd); - -int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset); - -int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset); - -void NICIssueReset(struct rt_rtmp_adapter *pAd); - -void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType); - -void UserCfgInit(struct rt_rtmp_adapter *pAd); - -void NICResetFromError(struct rt_rtmp_adapter *pAd); - -int NICLoadFirmware(struct rt_rtmp_adapter *pAd); - -void NICEraseFirmware(struct rt_rtmp_adapter *pAd); - -int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd); - -BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd); - -void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd); - -void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd); - -void RTMPZeroMemory(void *pSrc, unsigned long Length); - -unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length); - -void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length); - -void AtoH(char *src, u8 *dest, int destlen); - -void RTMPPatchMacBbpBug(struct rt_rtmp_adapter *pAd); - -void RTMPInitTimer(struct rt_rtmp_adapter *pAd, - struct rt_ralink_timer *pTimer, - void *pTimerFunc, void *pData, IN BOOLEAN Repeat); - -void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value); - -void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value); - -void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled); - -void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status); - -void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm); - -void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd); - -/* */ -/* prototype in action.c */ -/* */ -void ActionStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, - OUT STATE_MACHINE_FUNC Trans[]); - -void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp); - -void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void RECBATimerTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd); - -void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry); - -void ActHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 *pHdr80211, - u8 *Addr1, u8 *Addr2, u8 *Addr3); - -void BarHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_frame_bar *pCntlBar, u8 *pDA, u8 *pSA); - -void InsertActField(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, u8 Category, u8 ActCode); - -BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd, - unsigned long Wcid, - unsigned long MsgLen, struct rt_frame_ba_req *pMsg); - -/* */ -/* Private routines in rtmp_data.c */ -/* */ -BOOLEAN RTMPHandleRxDoneInterrupt(struct rt_rtmp_adapter *pAd); - -BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd, - INT_SOURCE_CSR_STRUC TxRingBitmap); - -void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd); - -void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd); - -void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd); - -void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd); - -void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd); - -BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd, - u8 *pPrevAddr1, u8 *p8023hdr); - -BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd, - unsigned long TxRate, struct rt_mac_table_entry *pMacEntry); - -int Sniff2BytesFromNdisBuffer(char *pFirstBuffer, - u8 DesiredOffset, - u8 *pByte0, u8 *pByte1); - -int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket); - -void STASendPackets(void *MiniportAdapterContext, - void **ppPacketArray, u32 NumberOfPackets); - -void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, - IN BOOLEAN bIntContext, - u8 QueIdx, u8 Max_Tx_Packets); - -int RTMPHardTransmit(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 QueIdx, unsigned long *pFreeTXDLeft); - -int STAHardTransmit(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, u8 QueIdx); - -void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd, - u8 RingType, - u8 NumberRequired, u8 *FreeNumberIs); - -int MlmeHardTransmit(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket); - -int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket); - -#ifdef RTMP_MAC_PCI -int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket); - -int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd, - u8 QueIdx, void *pPacket); - -void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd, - struct rt_txd *pTxD, IN BOOLEAN bWIV, u8 QSEL); -#endif /* RTMP_MAC_PCI // */ - -u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size); - -void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq, /* HW new a sequence. */ - u8 BASize, - u8 WCID, - unsigned long Length, - u8 PID, - u8 TID, - u8 TxRate, - u8 Txopmode, - IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING *pTransmit); - -void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd, - struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk); - -void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd, - struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk); - -void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd); - -void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd); - -int MiniportMMRequest(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u8 *pData, u32 Length); - -/*+++mark by shiang, now this function merge to MiniportMMRequest() */ -/*---mark by shiang, now this function merge to MiniportMMRequest() */ - -void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd, - u8 TxRate, IN BOOLEAN bQosNull); - -void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd); - -void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd, - u8 *pDA, - IN unsigned int NextMpduSize, - u8 TxRate, - u8 RTSRate, - u16 AckDuration, - u8 QueIdx, u8 FrameGap); - -struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 * QueIdx); - -void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaKey); - -void WpaMicFailureReportFrame(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void WpaDisassocApAndBlockAssoc(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3); - -void WpaStaPairwiseKeySetting(struct rt_rtmp_adapter *pAd); - -void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd); - -int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd, - IN BOOLEAN pInsAMSDUHdr, - void *pInPacket, - void **ppOutPacket); - -int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd, - void **pPacket, - u8 *pHeader, - u32 HeaderLen, - u8 *pData, u32 DataLen); - -void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket); - -BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx); - -BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket); - -BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket); - -/* */ -/* Private routines in rtmp_wep.c */ -/* */ -void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd, - u8 *pKey, - u8 KeyId, u8 KeyLen, u8 *pDest); - -void RTMPEncryptData(struct rt_rtmp_adapter *pAd, - u8 *pSrc, u8 *pDest, u32 Len); - -BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd, - u8 *pData, - unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey); - -void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest); - -void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen); - -u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx); - -void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx, - u8 *pDest, u8 *pSrc, u32 Len); - -void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx, - u8 *pDest, u8 *pSrc, u32 Len); - -void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx, - u8 *pDest, u8 *pSrc, u32 Len); - -u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len); - -/* */ -/* MLME routines */ -/* */ - -/* Asic/RF/BBP related functions */ - -void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd); - -void AsicUpdateProtect(struct rt_rtmp_adapter *pAd, - u16 OperaionMode, - u8 SetMask, - IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist); - -void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, - u8 Channel, IN BOOLEAN bScan); - -void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel); - -void AsicRfTuningExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd); - -void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, - u16 TbttNumToNextWakeUp); - -void AsicForceSleep(struct rt_rtmp_adapter *pAd); - -void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx); - -void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid); - -void AsicSetMcastWC(struct rt_rtmp_adapter *pAd); - -void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid); - -void AsicEnableRDG(struct rt_rtmp_adapter *pAd); - -void AsicDisableRDG(struct rt_rtmp_adapter *pAd); - -void AsicDisableSync(struct rt_rtmp_adapter *pAd); - -void AsicEnableBssSync(struct rt_rtmp_adapter *pAd); - -void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd); - -void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm); - -void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime); - -void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd, - u8 BssIndex, - u8 KeyIdx, - u8 CipherAlg, - u8 *pKey, u8 *pTxMic, u8 *pRxMic); - -void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd, - u8 BssIndex, u8 KeyIdx); - -void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd, - u16 WCID, - u8 BssIndex, - u8 CipherAlg, - IN BOOLEAN bUsePairewiseKeyTable); - -void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd, - u16 WCID, unsigned long uIV, unsigned long uEIV); - -void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd, - u16 WCID, u8 *pAddr); - -void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd, - u16 WCID, - u8 BssIndex, - u8 KeyIdx, - struct rt_cipher_key *pCipherKey, - IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey); - -void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd, - u8 *pAddr, - u8 WCID, struct rt_cipher_key *pCipherKey); - -void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd, - u8 BssIdx, u8 Wcid); - -BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, - u8 Command, - u8 Token, u8 Arg0, u8 Arg1); - -#ifdef RTMP_MAC_PCI -BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command); -#endif /* RTMP_MAC_PCI // */ - -void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr); - -void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 *pHdr80211, - u8 SubType, - u8 ToDs, u8 *pDA, u8 *pBssid); - -void MlmeRadioOff(struct rt_rtmp_adapter *pAd); - -void MlmeRadioOn(struct rt_rtmp_adapter *pAd); - -void BssTableInit(struct rt_bss_table *Tab); - -void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab); - -unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel); - -unsigned long BssSsidTableSearch(struct rt_bss_table *Tab, - u8 *pBssid, - u8 *pSsid, u8 SsidLen, u8 Channel); - -unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab, - u8 *Bssid, - u8 *pSsid, - u8 SsidLen, u8 Channel); - -unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab, - u8 *pSsid, u8 SsidLen); - -void BssTableDeleteEntry(struct rt_bss_table *pTab, - u8 *pBssid, u8 Channel); - -void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd, - struct rt_ba_ori_entry *pBAORIEntry); - -void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */ - u8 HtCapabilityLen, - u8 AddHtInfoLen, - u8 NewExtChanOffset, - u8 Channel, - char Rssi, - IN LARGE_INTEGER TimeStamp, - u8 CkipFlag, - struct rt_edca_parm *pEdcaParm, - struct rt_qos_capability_parm *pQosCapability, - struct rt_qbss_load_parm *pQbssLoad, - u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE); - -unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *pTab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */ - u8 HtCapabilityLen, - u8 AddHtInfoLen, - u8 NewExtChanOffset, - u8 Channel, - char Rssi, - IN LARGE_INTEGER TimeStamp, - u8 CkipFlag, - struct rt_edca_parm *pEdcaParm, - struct rt_qos_capability_parm *pQosCapability, - struct rt_qbss_load_parm *pQbssLoad, - u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE); - -void BATableInsertEntry(struct rt_rtmp_adapter *pAd, - u16 Aid, - u16 TimeOutValue, - u16 StartingSeq, - u8 TID, - u8 BAWinSize, - u8 OriginatorStatus, IN BOOLEAN IsRecipient); - -void BssTableSsidSort(struct rt_rtmp_adapter *pAd, - struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen); - -void BssTableSortByRssi(struct rt_bss_table *OutTab); - -void BssCipherParse(struct rt_bss_entry *pBss); - -int MlmeQueueInit(struct rt_mlme_queue *Queue); - -void MlmeQueueDestroy(struct rt_mlme_queue *Queue); - -BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd, - unsigned long Machine, - unsigned long MsgType, unsigned long MsgLen, void *Msg); - -BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd, - unsigned long Wcid, - unsigned long TimeStampHigh, - unsigned long TimeStampLow, - u8 Rssi0, - u8 Rssi1, - u8 Rssi2, - unsigned long MsgLen, void *Msg, u8 Signal); - -BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem **Elem); - -void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd); - -BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue); - -BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue); - -BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd, - struct rt_frame_802_11 *pFrame, - int *Machine, int *MsgType); - -void StateMachineInit(struct rt_state_machine *Sm, - IN STATE_MACHINE_FUNC Trans[], - unsigned long StNr, - unsigned long MsgNr, - IN STATE_MACHINE_FUNC DefFunc, - unsigned long InitState, unsigned long Base); - -void StateMachineSetAction(struct rt_state_machine *S, - unsigned long St, unsigned long Msg, IN STATE_MACHINE_FUNC F); - -void StateMachinePerformAction(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem); - -void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void AssocStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, - OUT STATE_MACHINE_FUNC Trans[]); - -void ReassocTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void AssocTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void DisassocTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -/*---------------------------------------------- */ -void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeDisassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerAssocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerReassocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerDisassocAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void DisassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void AssocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void ReassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void Cls3errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr); - -void InvalidStateWhenAssoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void InvalidStateWhenReassoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void InvalidStateWhenDisassociate(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -#ifdef RTMP_MAC_USB -void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg); -#endif /* RTMP_MAC_USB // */ - -void ComposePsPoll(struct rt_rtmp_adapter *pAd); - -void ComposeNullFrame(struct rt_rtmp_adapter *pAd); - -void AssocPostProc(struct rt_rtmp_adapter *pAd, - u8 *pAddr2, - u16 CapabilityInfo, - u16 Aid, - u8 SupRate[], - u8 SupRateLen, - u8 ExtRate[], - u8 ExtRateLen, - struct rt_edca_parm *pEdcaParm, - struct rt_ht_capability_ie *pHtCapability, - u8 HtCapabilityLen, struct rt_add_ht_info_ie *pAddHtInfo); - -void AuthStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *sm, OUT STATE_MACHINE_FUNC Trans[]); - -void AuthTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr); - -void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -/*============================================= */ - -void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, - IN STATE_MACHINE_FUNC Trans[]); - -void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 *pHdr80211, - u16 Alg, - u16 Seq, - u16 Reason, u16 Status); - -/* */ -/* Private routines in dls.c */ -/* */ - -/*======================================== */ - -void SyncStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, - OUT STATE_MACHINE_FUNC Trans[]); - -void BeaconTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void ScanTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd); - -BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd); -/*========================================= */ - -void MlmeCntlInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]); - -void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, - struct rt_mlme_queue_elem *Elem); - -void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType); - -void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP); - -void IterateOnBssTab(struct rt_rtmp_adapter *pAd); - -void IterateOnBssTab2(struct rt_rtmp_adapter *pAd); - -void JoinParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_join_req *JoinReq, unsigned long BssIdx); - -void AssocParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_assoc_req *AssocReq, - u8 *pAddr, - u16 CapabilityInfo, - unsigned long Timeout, u16 ListenIntv); - -void ScanParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_scan_req *ScanReq, - char Ssid[], - u8 SsidLen, u8 BssType, u8 ScanType); - -void DisassocParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_disassoc_req *DisassocReq, - u8 *pAddr, u16 Reason); - -void StartParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_start_req *StartReq, - char Ssid[], u8 SsidLen); - -void AuthParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_auth_req *AuthReq, - u8 *pAddr, u16 Alg); - -void EnqueuePsPoll(struct rt_rtmp_adapter *pAd); - -void EnqueueBeaconFrame(struct rt_rtmp_adapter *pAd); - -void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -void ScanNextChannel(struct rt_rtmp_adapter *pAd); - -unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd); - -BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *BssType, - char ssid[], - u8 *SsidLen, u8 *ScanType); - -BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 MsgChannel, - u8 *pAddr2, - u8 *pBssid, - char Ssid[], - u8 *pSsidLen, - u8 *pBssType, - u16 *pBeaconPeriod, - u8 *pChannel, - u8 *pNewChannel, - OUT LARGE_INTEGER *pTimestamp, - struct rt_cf_parm *pCfParm, - u16 *pAtimWin, - u16 *pCapabilityInfo, - u8 *pErp, - u8 *pDtimCount, - u8 *pDtimPeriod, - u8 *pBcastFlag, - u8 *pMessageToMe, - u8 SupRate[], - u8 *pSupRateLen, - u8 ExtRate[], - u8 *pExtRateLen, - u8 *pCkipFlag, - u8 *pAironetCellPowerLimit, - struct rt_edca_parm *pEdcaParm, - struct rt_qbss_load_parm *pQbssLoad, - struct rt_qos_capability_parm *pQosCapability, - unsigned long *pRalinkIe, - u8 *pHtCapabilityLen, - u8 *pPreNHtCapabilityLen, - struct rt_ht_capability_ie *pHtCapability, - u8 *AddHtInfoLen, - struct rt_add_ht_info_ie *AddHtInfo, - u8 *NewExtChannel, - u16 *LengthVIE, - struct rt_ndis_802_11_variable_ies *pVIE); - -BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd, - void *pMsg, - unsigned long MsgLen, u8 *pAddr2); - -BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd, - void *pMsg, unsigned long MsgLen); - -BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd, - u8 Wcid, void *pMsg, unsigned long MsgLen); - -BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *pApAddr, - u16 *CapabilityInfo, - unsigned long *Timeout, u16 *ListenIntv); - -BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *pAddr, - unsigned long *Timeout, u16 *Alg); - -BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - char Ssid[], u8 *Ssidlen); - -BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *pAddr, - u16 *Alg, - u16 *Seq, - u16 *Status, char ChlgText[]); - -BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void *pMsg, unsigned long MsgLen, u8 *pAddr2, u16 *pCapabilityInfo, u16 *pStatus, u16 *pAid, u8 SupRate[], u8 *pSupRateLen, u8 ExtRate[], u8 *pExtRateLen, struct rt_ht_capability_ie *pHtCapability, struct rt_add_ht_info_ie *pAddHtInfo, /* AP might use this additional ht info IE */ - u8 *pHtCapabilityLen, - u8 *pAddHtInfoLen, - u8 *pNewExtChannelOffset, - struct rt_edca_parm *pEdcaParm, u8 *pCkipFlag); - -BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *pAddr2, u16 *Reason); - -BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd, - struct rt_eapol_packet *pMsg, - unsigned long MsgLen, - u8 MsgType, struct rt_mac_table_entry *pEntry); - -BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *pAddr2, u16 *Reason); - -BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, - unsigned long MsgLen, - u8 *pAddr2, - char Ssid[], u8 *pSsidLen); - -BOOLEAN GetTimBit(char *Ptr, - u16 Aid, - u8 *TimLen, - u8 *BcastFlag, - u8 *DtimCount, - u8 *DtimPeriod, u8 *MessageToMe); - -u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel); - -NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss); - -BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, unsigned long MsgLen); - -BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd, - void *Msg, unsigned long MsgLen, u8 *pAddr2); - -unsigned long MakeOutgoingFrame(u8 *Buffer, unsigned long *Length, ...); - -void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed); - -u8 RandomByte(struct rt_rtmp_adapter *pAd); - -void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pTxRate); - -void MlmePeriodicExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void LinkDownExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd); - -void MlmeAutoScan(struct rt_rtmp_adapter *pAd); - -void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd); - -BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen); - -void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32); - -BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd); - -void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd); - -void MlmeSetTxRate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate); - -void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 **ppTable, - u8 *pTableSize, u8 *pInitTxRateIdx); - -void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pMacEntry, unsigned long Now); - -void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32); - -void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm); - -void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble); - -void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAd); - -void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, - IN BOOLEAN bLinkUp, u8 apidx); - -void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx); - -void RTMPCheckRates(struct rt_rtmp_adapter *pAd, - IN u8 SupRate[], IN u8 *SupRateLen); - -BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd, - u8 CentralChannel, u8 Channel); - -BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd, - u8 Wcid, - struct rt_ht_capability_ie *pHtCapability, - struct rt_add_ht_info_ie *pAddHtInfo); - -void StaQuickResponeForRateUpExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3); - -void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd); - -char RTMPMaxRssi(struct rt_rtmp_adapter *pAd, - char Rssi0, char Rssi1, char Rssi2); - -#ifdef RT30xx -void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant); - -void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd); - -#ifdef RTMP_EFUSE_SUPPORT -/*2008/09/11:KH add to support efuse<-- */ -int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg); - -int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg); - -void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd, - u16 Offset, - u16 Length, u16 *pData); - -int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd); - -void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock); - -int eFuse_init(struct rt_rtmp_adapter *pAd); -/*2008/09/11:KH add to support efuse--> */ -#endif /* RTMP_EFUSE_SUPPORT // */ - -/* add by johnli, RF power sequence setup */ -void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd); - -void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd); - -void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd); -/* end johnli */ - -#ifdef RT3070 -void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd); -#endif /* RT3070 // */ -#ifdef RT3090 -void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd); -#endif /* RT3090 // */ - -void RT30xxHaltAction(struct rt_rtmp_adapter *pAd); - -void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant); -#endif /* RT30xx // */ - -void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd); - -void AsicRxAntEvalTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void APSDPeriodicExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry); - -u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry); - -void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry); - -BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd); - -int MlmeInit(struct rt_rtmp_adapter *pAd); - -void MlmeHandler(struct rt_rtmp_adapter *pAd); - -void MlmeHalt(struct rt_rtmp_adapter *pAd); - -void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd); - -void BuildChannelList(struct rt_rtmp_adapter *pAd); - -u8 FirstChannel(struct rt_rtmp_adapter *pAd); - -u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel); - -void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd, - u8 AironetCellPowerLimit); - -/* */ -/* Prototypes of function definition in rtmp_tkip.c */ -/* */ -void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd, - u8 *pTKey, - u8 KeyId, - u8 *pTA, - u8 *pMICKey, - u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32); - -void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd, - u8 *pKey, - u8 *pDA, - u8 *pSA, u8 UserPriority, u8 *pMICKey); - -BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd, - u8 *pSrc, - u8 *pDA, - u8 *pSA, - u8 *pMICKey, - u8 UserPriority, u32 Len); - -void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pEncap, - struct rt_cipher_key *pKey, u8 apidx); - -void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar); - -void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes); - -void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip); - -BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd, - u8 *pData, - unsigned long DataByteCnt, - u8 UserPriority, struct rt_cipher_key *pWpaKey); - -BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd, - u8 *pData, - unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey); - -/* */ -/* Prototypes of function definition in cmm_info.c */ -/* */ -int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band); - -int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg); - -int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg); - -int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd, - char *keyString, - struct rt_cipher_key *pSharedKey, int keyIdx); - -int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd, - char *keyString, - u8 *pHashStr, - int hashStrLen, u8 *pPMKBuf); - -/* */ -/* Prototypes of function definition in cmm_info.c */ -/* */ -void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd); - -void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode); - -void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt, - u8 *pMcsSet, - struct rt_ht_capability_ie *pHtCapability, - struct rt_add_ht_info_ie *pAddHtInfo); - -void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd, - u8 BssIdx, - u8 KeyIdx, - u8 CipherAlg, struct rt_mac_table_entry *pEntry); - -char *GetEncryptType(char enc); - -char *GetAuthMode(char auth); - -void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode); - -void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx); - -void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd, - u16 Event_flag, - u8 *pAddr, u8 BssIdx, char Rssi); - -char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber); - -/*=================================== - Function prototype in cmm_wpa.c - =================================== */ -void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pHeader802_3, - u32 HdrLen, - u8 *pData, - u32 DataLen, IN BOOLEAN bClearFrame); - -void WpaDerivePTK(struct rt_rtmp_adapter *pAd, - u8 *PMK, - u8 *ANonce, - u8 *AA, - u8 *SNonce, - u8 *SA, u8 *output, u32 len); - -void GenRandom(struct rt_rtmp_adapter *pAd, u8 *macAddr, u8 *random); - -BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pData, - unsigned long DataByteCount, u8 FromWhichBSSID); - -void AES_GTK_KEY_UNWRAP(u8 *key, - u8 *plaintext, - u32 c_len, u8 *ciphertext); - -BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd, - u8 *pKeyData, - u8 KeyDataLen, - u8 GroupKeyIndex, - u8 MsgType, - IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry); - -void ConstructEapolMsg(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 MsgType, - u8 DefaultKeyIdx, - u8 *KeyNonce, - u8 *TxRSC, - u8 *GTK, - u8 *RSNIE, - u8 RSNIE_Len, struct rt_eapol_packet *pMsg); - -int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, - IN NDIS_802_11_ENCRYPTION_STATUS - GroupCipher, - struct rt_cipher_key *pShard_key); - -void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd, - u32 AuthMode, u32 WepStatus, u8 apidx); - -/* */ -/* function prototype in ap_wpa.c */ -/* */ -void RTMPGetTxTscFromAsic(struct rt_rtmp_adapter *pAd, - u8 apidx, u8 *pTxTsc); - -void APInstallPairwiseKey(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry); - -u32 APValidateRSNIE(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pRsnIe, u8 rsnie_len); - -void HandleCounterMeasure(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry); - -void WPAStart4WayHS(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, unsigned long TimeInterval); - -void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry); - -void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem); - -void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem); - -void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem); - -void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem); - -void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem); - -void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - void *Msg, u32 MsgLen); - -void WpaDeriveGTK(u8 *PMK, - u8 *GNonce, - u8 *AA, u8 *output, u32 len); - -void AES_GTK_KEY_WRAP(u8 *key, - u8 *plaintext, - u32 p_len, u8 *ciphertext); - -/*typedef void (*TIMER_FUNCTION)(unsigned long); */ - -/* timeout -- ms */ -void RTMP_SetPeriodicTimer(struct timer_list *pTimer, - IN unsigned long timeout); - -void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd, - struct timer_list *pTimer, - IN TIMER_FUNCTION function, void *data); - -void RTMP_OS_Add_Timer(struct timer_list *pTimer, - IN unsigned long timeout); - -void RTMP_OS_Mod_Timer(struct timer_list *pTimer, - IN unsigned long timeout); - -void RTMP_OS_Del_Timer(struct timer_list *pTimer, - OUT BOOLEAN *pCancelled); - -void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry); - -void RTMPusecDelay(unsigned long usec); - -int os_alloc_mem(struct rt_rtmp_adapter *pAd, - u8 **mem, unsigned long size); - -int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem); - -void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress); - -void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd); - -int AdapterBlockAllocateMemory(void *handle, void **ppAd); - -void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd, - u32 Index, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress); - -void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd, - u32 Index, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress); - -void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void *VirtualAddress, - dma_addr_t PhysicalAddress); - -void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress); - -void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - dma_addr_t *PhysicalAddress); - -void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd, - unsigned long Length, - void *VirtualAddress, - dma_addr_t PhysicalAddress); - -void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size); - -void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress, - OUT dma_addr_t *PhysicalAddress); - -void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length, - IN BOOLEAN Cached, - void **VirtualAddress); - -void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd, - unsigned long Length); - -void RTMP_QueryPacketInfo(void *pPacket, - struct rt_packet_info *pPacketInfo, - u8 **pSrcBufVA, u32 *pSrcBufLen); - -void RTMP_QueryNextPacketInfo(void **ppPacket, - struct rt_packet_info *pPacketInfo, - u8 **pSrcBufVA, u32 *pSrcBufLen); - -BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk); - -struct rt_rtmp_sg_list *rt_get_sg_list_from_packet(void *pPacket, - struct rt_rtmp_sg_list *sg); - -void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket); - -u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket); - -struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID); - -void *duplicate_pkt(struct rt_rtmp_adapter *pAd, - u8 *pHeader802_3, - u32 HdrLen, - u8 *pData, - unsigned long DataSize, u8 FromWhichBSSID); - -void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd, - void *pOldPkt); - -void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd, - struct rt_ba_rec_entry *pBAEntry, - unsigned long Now32); - -void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 TID, - u16 TimeOut, - unsigned long DelayTime, IN BOOLEAN isForced); - -void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid); - -BOOLEAN OS_Need_Clone_Packet(void); - -void build_tx_packet(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pFrame, unsigned long FrameLen); - -void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd, - u8 Wcid, - u8 TID, - IN BOOLEAN bPassive, IN BOOLEAN bForceSend); - -void BARecSessionTearDown(struct rt_rtmp_adapter *pAd, - u8 Wcid, u8 TID, IN BOOLEAN bPassive); - -BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num); -void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd); - -char *rstrtok(char *s, IN const char *ct); - -/*//////// common ioctl functions ////////// */ -int SetCommonHT(struct rt_rtmp_adapter *pAd); - -int WpaCheckEapCode(struct rt_rtmp_adapter *pAd, - u8 *pFrame, u16 FrameLen, u16 OffSet); - -void WpaSendMicFailureToWpaSupplicant(struct rt_rtmp_adapter *pAd, - IN BOOLEAN bUnicast); - -int wext_notify_event_assoc(struct rt_rtmp_adapter *pAd); - -BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc); - -/* AMPDU packet indication */ -void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -/* AMSDU packet indication */ -void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -/* Normal legacy Rx packet indication */ -void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -void update_os_packet_info(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, - u8 *pHeader802_3, - u8 FromWhichBSSID); - -/* remove LLC and get 802_3 Header */ -#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \ -{ \ - u8 *_pRemovedLLCSNAP = NULL, *_pDA, *_pSA; \ - \ - if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) { \ - _pDA = _pRxBlk->pHeader->Addr3; \ - _pSA = (u8 *)_pRxBlk->pHeader + sizeof(struct rt_header_802_11); \ - } \ - else {\ - if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) {\ - _pDA = _pRxBlk->pHeader->Addr1; \ - if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \ - _pSA = _pRxBlk->pHeader->Addr2; \ - else \ - _pSA = _pRxBlk->pHeader->Addr3; \ - } \ - else { \ - _pDA = _pRxBlk->pHeader->Addr1; \ - _pSA = _pRxBlk->pHeader->Addr2; \ - } \ - } \ - \ - CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \ - _pRxBlk->DataSize, _pRemovedLLCSNAP); \ -} - -void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 FromWhichBSSID); - -#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\ - Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS); - /*announce_802_3_packet(_pAd, _pPacket); */ - -void *DuplicatePacket(struct rt_rtmp_adapter *pAd, - void *pPacket, u8 FromWhichBSSID); - -void *ClonePacket(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pData, unsigned long DataSize); - -/* Normal, AMPDU or AMSDU */ -void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID); - -void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd, - struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI); - -void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd, - OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN *pbReschedule, - IN u32 *pRxPending); - -void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk); - -enum { - DIDmsg_lnxind_wlansniffrm = 0x00000044, - DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044, - DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044, - DIDmsg_lnxind_wlansniffrm_channel = 0x00030044, - DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044, - DIDmsg_lnxind_wlansniffrm_sq = 0x00050044, - DIDmsg_lnxind_wlansniffrm_signal = 0x00060044, - DIDmsg_lnxind_wlansniffrm_noise = 0x00070044, - DIDmsg_lnxind_wlansniffrm_rate = 0x00080044, - DIDmsg_lnxind_wlansniffrm_istx = 0x00090044, - DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044 -}; -enum { - P80211ENUM_msgitem_status_no_value = 0x00 -}; -enum { - P80211ENUM_truth_false = 0x00, - P80211ENUM_truth_true = 0x01 -}; - -/* Definition from madwifi */ -struct rt_p80211item_uint32 { - u32 did; - u16 status; - u16 len; - u32 data; -}; - -struct rt_wlan_ng_prism2_header { - u32 msgcode; - u32 msglen; -#define WLAN_DEVNAMELEN_MAX 16 - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct rt_p80211item_uint32 hosttime; - struct rt_p80211item_uint32 mactime; - struct rt_p80211item_uint32 channel; - struct rt_p80211item_uint32 rssi; - struct rt_p80211item_uint32 sq; - struct rt_p80211item_uint32 signal; - struct rt_p80211item_uint32 noise; - struct rt_p80211item_uint32 rate; - struct rt_p80211item_uint32 istx; - struct rt_p80211item_uint32 frmlen; -}; - -/* The radio capture header precedes the 802.11 header. */ -struct PACKED rt_ieee80211_radiotap_header { - u8 it_version; /* Version 0. Only increases - * for drastic changes, - * introduction of compatible - * new fields does not count. - */ - u8 it_pad; - u16 it_len; /* length of the whole - * header in bytes, including - * it_version, it_pad, - * it_len, and data fields. - */ - u32 it_present; /* A bitmap telling which - * fields are present. Set bit 31 - * (0x80000000) to extend the - * bitmap by another 32 bits. - * Additional extensions are made - * by setting bit 31. - */ -}; - -enum ieee80211_radiotap_type { - IEEE80211_RADIOTAP_TSFT = 0, - IEEE80211_RADIOTAP_FLAGS = 1, - IEEE80211_RADIOTAP_RATE = 2, - IEEE80211_RADIOTAP_CHANNEL = 3, - IEEE80211_RADIOTAP_FHSS = 4, - IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, - IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, - IEEE80211_RADIOTAP_LOCK_QUALITY = 7, - IEEE80211_RADIOTAP_TX_ATTENUATION = 8, - IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, - IEEE80211_RADIOTAP_DBM_TX_POWER = 10, - IEEE80211_RADIOTAP_ANTENNA = 11, - IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, - IEEE80211_RADIOTAP_DB_ANTNOISE = 13 -}; - -#define WLAN_RADIOTAP_PRESENT ( \ - (1 << IEEE80211_RADIOTAP_TSFT) | \ - (1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - 0) - -struct rt_wlan_radiotap_header { - struct rt_ieee80211_radiotap_header wt_ihdr; - long long wt_tsft; - u8 wt_flags; - u8 wt_rate; -}; -/* Definition from madwifi */ - -void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk); - -void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates); - -int Set_FixedTxMode_Proc(struct rt_rtmp_adapter *pAd, char *arg); - -BOOLEAN RT28XXChipsetCheck(IN void *_dev_p); - -void RT28XXDMADisable(struct rt_rtmp_adapter *pAd); - -void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd); - -void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd, - int apidx, - unsigned long BeaconLen, unsigned long UpdatePos); - -int rt28xx_init(struct rt_rtmp_adapter *pAd, - char *pDefaultMac, char *pHostName); - -int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd); - -void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd); - -int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd); - -void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd); - -void tbtt_tasklet(unsigned long data); - -struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd, - struct rt_rtmp_os_netdev_op_hook *pNetHook); - -BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev); - -int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType); - -BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd); - -#ifdef RTMP_MAC_PCI -/* */ -/* Function Prototype in cmm_data_pci.c */ -/* */ -u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 *FreeNumber); - -u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, - u16 *FreeNumber); - -u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 frameNum, u16 *FreeNumber); - -u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 fragNum, u16 *FreeNumber); - -u16 RtmpPCI_WriteSubTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 *FreeNumber); - -void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u16 totalMPDUSize, - u16 FirstTxIdx); - -void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u16 LastTxIdx); - -void RtmpPCIDataKickOut(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, u8 QueIdx); - -int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - void *pPacket, - u8 *pSrcBufVA, u32 SrcBufLen); - -int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 *pHeader, - struct rt_rxwi *pRxWI, IN PRT28XX_RXD_STRUC pRxD); - -BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd, - u8 Level, u16 TbttNumToNextWakeUp); - -BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level); - -void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd); - -void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd); - -void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level); - -void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max); - -void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd); - -void PsPollWakeExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void RadioOnExec(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3); - -void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx); - -void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, - u16 TbttNumToNextWakeUp); - -void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd); - -void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd); -#endif /* RTMP_MAC_PCI // */ - -#ifdef RTMP_MAC_USB -/* */ -/* Function Prototype in rtusb_bulk.c */ -/* */ -void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd, - struct rt_tx_context *pTxContext, - u8 BulkOutPipeId, IN usb_complete_t Func); - -void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd, - struct rt_ht_tx_context *pTxContext, - u8 BulkOutPipeId, - unsigned long BulkOutSize, IN usb_complete_t Func); - -void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext); - -void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd); - -void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd); - -void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, - u8 BulkOutPipeId, u8 Index); - -void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd); - -void RTUSBBulkOutRTSFrame(struct rt_rtmp_adapter *pAd); - -void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd); - -void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd); - -void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index); - -void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd); - -void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd); - -void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd); - -void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd); - -void DoBulkIn(struct rt_rtmp_adapter *pAd); - -void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext); - -void RTUSBBulkRxHandle(IN unsigned long data); - -/* */ -/* Function Prototype in rtusb_io.c */ -/* */ -int RTUSBMultiRead(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length); - -int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd, - u16 Offset, const u8 *pData, u16 length); - -int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, - u16 Offset, const u8 *pData); - -int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd, - u8 Id, u8 *pValue); - -int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd, - u8 Id, u8 Value); - -int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value); - -int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd, - u32 TransferFlags, - u8 ReservedBits, - u8 Request, - u16 Value, - u16 Index, - void *TransferBuffer, - u32 TransferBufferLength); - -int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length); - -int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length); - -void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd); - -int RTUSBWakeUp(struct rt_rtmp_adapter *pAd); - -void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq); - -int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd, - IN NDIS_OID Oid, - IN BOOLEAN SetInformation, - void *pInformationBuffer, - u32 InformationBufferLength); - -int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd, - IN NDIS_OID Oid, - void *pInformationBuffer, - u32 InformationBufferLength); - -void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt); - -int RTUSBCmdThread(IN void *Context); - -void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd); - -void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd); - -void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd); - -void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd); - -void RTUSBWatchDog(struct rt_rtmp_adapter *pAd); - -int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd, - u16 Offset, u32 Value); - -int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd, - u16 Offset, u32 *pValue); - -int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 Value); - -int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd, - const u8 *pFwImage, unsigned long FwLen); - -int RTUSBVenderReset(struct rt_rtmp_adapter *pAd); - -int RTUSBSetHardWareRegister(struct rt_rtmp_adapter *pAdapter, void *pBuf); - -int RTUSBQueryHardWareRegister(struct rt_rtmp_adapter *pAdapter, - void *pBuf); - -void CMDHandler(struct rt_rtmp_adapter *pAd); - -int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAdapter); - -void MacTableInitialize(struct rt_rtmp_adapter *pAd); - -void MlmeSetPsm(struct rt_rtmp_adapter *pAd, u16 psm); - -int RTMPWPAAddKeyProc(struct rt_rtmp_adapter *pAd, void *pBuf); - -void AsicRxAntEvalAction(struct rt_rtmp_adapter *pAd); - -void append_pkt(struct rt_rtmp_adapter *pAd, - u8 *pHeader802_3, - u32 HdrLen, - u8 *pData, - unsigned long DataSize, void **ppPacket); - -u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 *pData, unsigned long DataSize); - -int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 *pHeader, - struct rt_rxwi *pRxWI, - IN PRT28XX_RXD_STRUC pRxINFO); - -void RTUSBMlmeHardTransmit(struct rt_rtmp_adapter *pAd, struct rt_mgmt *pMgmt); - -int MlmeThread(void *Context); - -/* */ -/* Function Prototype in rtusb_data.c */ -/* */ -int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd, - u8 BulkOutPipeId, - u32 NumberRequired); - -BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId); - -void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd, - struct rt_txinfo *pTxInfo, - u16 USBDMApktLen, - IN BOOLEAN bWiv, - u8 QueueSel, u8 NextValid, u8 TxBurst); - -/* */ -/* Function Prototype in cmm_data_usb.c */ -/* */ -u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 *FreeNumber); - -u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, - u16 *FreeNumber); - -u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 fragNum, u16 *FreeNumber); - -u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u8 frameNum, u16 *FreeNumber); - -void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, - u16 totalMPDUSize, u16 TxIdx); - -void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd, - u8 QueIdx, u16 TxIdx); - -void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, u8 QueIdx); - -int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - void *pPacket, - u8 *pSrcBufVA, u32 SrcBufLen); - -void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - u8 *pNullFrame, u32 frameLen); - -void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3); - -void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx); - -void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd, - u16 TbttNumToNextWakeUp); - -void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd); - -void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd); -#endif /* RTMP_MAC_USB // */ - -void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel); - -void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel); - -#ifdef RTMP_TIMER_TASK_SUPPORT -int RtmpTimerQThread(IN void *Context); - -struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd, - struct rt_ralink_timer *pTimer); - -BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd, - struct rt_ralink_timer *pTimer); - -void RtmpTimerQExit(struct rt_rtmp_adapter *pAd); - -void RtmpTimerQInit(struct rt_rtmp_adapter *pAd); -#endif /* RTMP_TIMER_TASK_SUPPORT // */ - -void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd); - -BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 MaxSupportedRateIn500Kbps, - struct rt_ht_capability_ie *pHtCapability, - u8 HtCapabilityLen, - struct rt_add_ht_info_ie *pAddHtInfo, - u8 AddHtInfoLen, u16 CapabilityInfo); - -BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *pElem, - struct rt_ralink_timer *pAuthTimer, - char *pSMName, - u16 SeqNo, - u8 *pNewElement, unsigned long ElementLen); - -void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd); - -void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd); - -void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth); - -int rt28xx_close(struct net_device *dev); -int rt28xx_open(struct net_device *dev); - -#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++) -#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--) -#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt) - -#ifdef LINUX -__inline int VIRTUAL_IF_UP(struct rt_rtmp_adapter *pAd) -{ - if (VIRTUAL_IF_NUM(pAd) == 0) { - if (rt28xx_open(pAd->net_dev) != 0) { - DBGPRINT(RT_DEBUG_TRACE, - ("rt28xx_open return fail!\n")); - return -1; - } - } else { - } - VIRTUAL_IF_INC(pAd); - return 0; -} - -__inline void VIRTUAL_IF_DOWN(struct rt_rtmp_adapter *pAd) -{ - VIRTUAL_IF_DEC(pAd); - if (VIRTUAL_IF_NUM(pAd) == 0) - rt28xx_close(pAd->net_dev); - return; -} -#endif /* LINUX // */ - -/* - OS Related funciton prototype definitions. - TODO: Maybe we need to move these function prototypes to other proper place. -*/ -int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd, - u32 eventType, - int flags, - u8 *pSrcMac, - u8 *pData, u32 dataLen); - -int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr); - -int RtmpOSNetDevAttach(struct net_device *pNetDev, - struct rt_rtmp_os_netdev_op_hook *pDevOpHook); - -void RtmpOSNetDevClose(struct net_device *pNetDev); - -void RtmpOSNetDevDetach(struct net_device *pNetDev); - -int RtmpOSNetDevAlloc(struct net_device **pNewNetDev, u32 privDataSize); - -void RtmpOSNetDevFree(struct net_device *pNetDev); - -struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName); - -void RtmpOSNetDeviceRefPut(struct net_device *pNetDev); - -struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd, - int devType, - int devNum, - int privMemSize, char *pNamePrefix); - -/* - Task operation related function prototypes -*/ -void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask); - -int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask); - -int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask); - -int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask, - char *pTaskName, void * pPriv); - -int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask, - IN int (*fn) (void *), IN void *arg); - -/* - File operation related function prototypes -*/ -struct file *RtmpOSFileOpen(IN char *pPath, IN int flag, IN int mode); - -int RtmpOSFileClose(struct file *osfd); - -void RtmpOSFileSeek(struct file *osfd, IN int offset); - -int RtmpOSFileRead(struct file *osfd, IN char *pDataPtr, IN int readLen); - -int RtmpOSFileWrite(struct file *osfd, IN char *pDataPtr, IN int writeLen); - -#endif /* __RTMP_H__ */ diff --git a/drivers/staging/rt2860/rtmp_chip.h b/drivers/staging/rt2860/rtmp_chip.h deleted file mode 100644 index 0adf2cd2deb7..000000000000 --- a/drivers/staging/rt2860/rtmp_chip.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_chip.h - - Abstract: - Ralink Wireless Chip related definition & structures - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#ifndef __RTMP_CHIP_H__ -#define __RTMP_CHIP_H__ - -#include "rtmp_type.h" - -#ifdef RT2860 -#include "chip/rt2860.h" -#endif /* RT2860 // */ -#ifdef RT2870 -#include "chip/rt2870.h" -#endif /* RT2870 // */ -#ifdef RT3070 -#include "chip/rt3070.h" -#endif /* RT3070 // */ -#ifdef RT3090 -#include "chip/rt3090.h" -#endif /* RT3090 // */ - -/* We will have a cost down version which mac version is 0x3090xxxx */ -/* */ -/* RT3090A facts */ -/* */ -/* a) 2.4 GHz */ -/* b) Replacement for RT3090 */ -/* c) Internal LNA */ -/* d) Interference over channel #14 */ -/* e) New BBP features (e.g., SIG re-modulation) */ -/* */ -#define IS_RT3090A(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30900000)) - -/* We will have a cost down version which mac version is 0x3090xxxx */ -#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd))) - -#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000) -#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000) -#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27)) - -#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd)) -/*#define IS_RT305X(_pAd) ((_pAd)->MACVersion == 0x28720200) */ - -/* RT3572, 3592, 3562, 3062 share the same MAC version */ -#define IS_RT3572(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x35720000) -#define IS_VERSION_BEFORE_F(_pAd) (((_pAd)->MACVersion&0xffff) <= 0x0211) -/* F version is 0x0212, E version is 0x0211. 309x can save more power after F version. */ -#define IS_VERSION_AFTER_F(_pAd) ((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE))) -/* */ -/* RT3390 facts */ -/* */ -/* a) Base on RT3090 (RF IC: RT3020) */ -/* b) 2.4 GHz */ -/* c) 1x1 */ -/* d) Single chip */ -/* e) Internal components: PA and LNA */ -/* */ -/*RT3390,RT3370 */ -#define IS_RT3390(_pAd) (((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000) - -/* ------------------------------------------------------ */ -/* PCI registers - base address 0x0000 */ -/* ------------------------------------------------------ */ -#define CHIP_PCI_CFG 0x0000 -#define CHIP_PCI_EECTRL 0x0004 -#define CHIP_PCI_MCUCTRL 0x0008 - -#define OPT_14 0x114 - -#define RETRY_LIMIT 10 - -/* ------------------------------------------------------ */ -/* BBP & RF definition */ -/* ------------------------------------------------------ */ -#define BUSY 1 -#define IDLE 0 - -/*------------------------------------------------------------------------- */ -/* EEPROM definition */ -/*------------------------------------------------------------------------- */ -#define EEDO 0x08 -#define EEDI 0x04 -#define EECS 0x02 -#define EESK 0x01 -#define EERL 0x80 - -#define EEPROM_WRITE_OPCODE 0x05 -#define EEPROM_READ_OPCODE 0x06 -#define EEPROM_EWDS_OPCODE 0x10 -#define EEPROM_EWEN_OPCODE 0x13 - -#define NUM_EEPROM_BBP_PARMS 19 /* Include NIC Config 0, 1, CR, TX ALC step, BBPs */ -#define NUM_EEPROM_TX_G_PARMS 7 -#define EEPROM_NIC1_OFFSET 0x34 /* The address is from NIC config 0, not BBP register ID */ -#define EEPROM_NIC2_OFFSET 0x36 /* The address is from NIC config 0, not BBP register ID */ -#define EEPROM_BBP_BASE_OFFSET 0xf0 /* The address is from NIC config 0, not BBP register ID */ -#define EEPROM_G_TX_PWR_OFFSET 0x52 -#define EEPROM_G_TX2_PWR_OFFSET 0x60 -#define EEPROM_LED1_OFFSET 0x3c -#define EEPROM_LED2_OFFSET 0x3e -#define EEPROM_LED3_OFFSET 0x40 -#define EEPROM_LNA_OFFSET 0x44 -#define EEPROM_RSSI_BG_OFFSET 0x46 -#define EEPROM_TXMIXER_GAIN_2_4G 0x48 -#define EEPROM_RSSI_A_OFFSET 0x4a -#define EEPROM_TXMIXER_GAIN_5G 0x4c -#define EEPROM_DEFINE_MAX_TXPWR 0x4e -#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde /* 20MHZ 2.4G tx power. */ -#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee /* 40MHZ 2.4G tx power. */ -#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa /* 20MHZ 5G tx power. */ -#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a /* 40MHZ 5G tx power. */ -#define EEPROM_A_TX_PWR_OFFSET 0x78 -#define EEPROM_A_TX2_PWR_OFFSET 0xa6 -/*#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j */ -/*#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe */ -/*#define EEPROM_TSSI_REF_OFFSET 0x54 */ -/*#define EEPROM_TSSI_DELTA_OFFSET 0x24 */ -/*#define EEPROM_CCK_TX_PWR_OFFSET 0x62 */ -/*#define EEPROM_CALIBRATE_OFFSET 0x7c */ -#define EEPROM_VERSION_OFFSET 0x02 -#define EEPROM_FREQ_OFFSET 0x3a -#define EEPROM_TXPOWER_BYRATE 0xde /* 20MHZ power. */ -#define EEPROM_TXPOWER_DELTA 0x50 /* 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ. */ -#define VALID_EEPROM_VERSION 1 - -/* - * EEPROM operation related marcos - */ -#define RT28xx_EEPROM_READ16(_pAd, _offset, _value) \ - (_pAd)->chipOps.eeread((struct rt_rtmp_adapter *)(_pAd), (u16)(_offset), (u16 *)&(_value)) - -/* ------------------------------------------------------------------- */ -/* E2PROM data layout */ -/* ------------------------------------------------------------------- */ - -/* */ -/* MCU_LEDCS: MCU LED Control Setting. */ -/* */ -typedef union _MCU_LEDCS_STRUC { - struct { - u8 LedMode:7; - u8 Polarity:1; - } field; - u8 word; -} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC; - -/* */ -/* EEPROM antenna select format */ -/* */ -typedef union _EEPROM_ANTENNA_STRUC { - struct { - u16 RxPath:4; /* 1: 1R, 2: 2R, 3: 3R */ - u16 TxPath:4; /* 1: 1T, 2: 2T */ - u16 RfIcType:4; /* see E2PROM document */ - u16 Rsv:4; - } field; - u16 word; -} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC; - -typedef union _EEPROM_NIC_CINFIG2_STRUC { - struct { - u16 HardwareRadioControl:1; /* 1:enable, 0:disable */ - u16 DynamicTxAgcControl:1; /* */ - u16 ExternalLNAForG:1; /* */ - u16 ExternalLNAForA:1; /* external LNA enable for 2.4G */ - u16 CardbusAcceleration:1; /* ! NOTE: 0 - enable, 1 - disable */ - u16 BW40MSidebandForG:1; - u16 BW40MSidebandForA:1; - u16 EnableWPSPBC:1; /* WPS PBC Control bit */ - u16 BW40MAvailForG:1; /* 0:enable, 1:disable */ - u16 BW40MAvailForA:1; /* 0:enable, 1:disable */ - u16 Rsv1:1; /* must be 0 */ - u16 AntDiversity:1; /* Antenna diversity */ - u16 Rsv2:3; /* must be 0 */ - u16 DACTestBit:1; /* control if driver should patch the DAC issue */ - } field; - u16 word; -} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC; - -/* */ -/* TX_PWR Value valid range 0xFA(-6) ~ 0x24(36) */ -/* */ -typedef union _EEPROM_TX_PWR_STRUC { - struct { - char Byte0; /* Low Byte */ - char Byte1; /* High Byte */ - } field; - u16 word; -} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC; - -typedef union _EEPROM_VERSION_STRUC { - struct { - u8 FaeReleaseNumber; /* Low Byte */ - u8 Version; /* High Byte */ - } field; - u16 word; -} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC; - -typedef union _EEPROM_LED_STRUC { - struct { - u16 PolarityRDY_G:1; /* Polarity RDY_G setting. */ - u16 PolarityRDY_A:1; /* Polarity RDY_A setting. */ - u16 PolarityACT:1; /* Polarity ACT setting. */ - u16 PolarityGPIO_0:1; /* Polarity GPIO#0 setting. */ - u16 PolarityGPIO_1:1; /* Polarity GPIO#1 setting. */ - u16 PolarityGPIO_2:1; /* Polarity GPIO#2 setting. */ - u16 PolarityGPIO_3:1; /* Polarity GPIO#3 setting. */ - u16 PolarityGPIO_4:1; /* Polarity GPIO#4 setting. */ - u16 LedMode:5; /* Led mode. */ - u16 Rsvd:3; /* Reserved */ - } field; - u16 word; -} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC; - -typedef union _EEPROM_TXPOWER_DELTA_STRUC { - struct { - u8 DeltaValue:6; /* Tx Power dalta value (MAX=4) */ - u8 Type:1; /* 1: plus the delta value, 0: minus the delta value */ - u8 TxPowerEnable:1; /* Enable */ - } field; - u8 value; -} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC; - -#endif /* __RTMP_CHIP_H__ // */ diff --git a/drivers/staging/rt2860/rtmp_ckipmic.h b/drivers/staging/rt2860/rtmp_ckipmic.h deleted file mode 100644 index 6ff935dd3dd1..000000000000 --- a/drivers/staging/rt2860/rtmp_ckipmic.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_ckipmic.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs -*/ -#ifndef __RTMP_CKIPMIC_H__ -#define __RTMP_CKIPMIC_H__ - -struct rt_mic_context { - /* --- MMH context */ - u8 CK[16]; /* the key */ - u8 coefficient[16]; /* current aes counter mode coefficients */ - unsigned long long accum; /* accumulated mic, reduced to u32 in final() */ - u32 position; /* current position (byte offset) in message */ - u8 part[4]; /* for conversion of message to u32 for mmh */ -}; - -void xor_128(u8 *a, u8 *b, u8 *out); - -u8 RTMPCkipSbox(u8 a); - -void xor_32(u8 *a, u8 *b, u8 *out); - -void next_key(u8 *key, int round); - -void byte_sub(u8 *in, u8 *out); - -void shift_row(u8 *in, u8 *out); - -void mix_column(u8 *in, u8 *out); - -#endif /*__RTMP_CKIPMIC_H__ */ diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h deleted file mode 100644 index 6ac617e7c9bb..000000000000 --- a/drivers/staging/rt2860/rtmp_def.h +++ /dev/null @@ -1,1427 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_def.h - - Abstract: - Miniport related definition header - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Lin 08-01-2002 created - John Chang 08-05-2003 add definition for 11g & other drafts - Justin P. Mattock 11/07/2010 Fix some typos -*/ -#ifndef __RTMP_DEF_H__ -#define __RTMP_DEF_H__ - -#include "oid.h" - -/* */ -/* Debug information verbosity: lower values indicate higher urgency */ -/* */ -#define RT_DEBUG_OFF 0 -#define RT_DEBUG_ERROR 1 -#define RT_DEBUG_WARN 2 -#define RT_DEBUG_TRACE 3 -#define RT_DEBUG_INFO 4 -#define RT_DEBUG_LOUD 5 - -#define NIC_TAG ((unsigned long)'0682') -#define NIC_DBG_char ("**RT28xx**") - -#ifdef RTMP_MAC_USB -#define TX_RING_SIZE 8 /* 1 */ -#define PRIO_RING_SIZE 8 -#define MGMT_RING_SIZE 32 /* PRIO_RING_SIZE */ -#define RX_RING_SIZE 8 -#define MAX_TX_PROCESS 4 -#define LOCAL_TXBUF_SIZE 2048 -#endif /* RTMP_MAC_USB // */ - -/*#define PACKED */ - -#define RALINK_2883_VERSION ((u32)0x28830300) -#define RALINK_2880E_VERSION ((u32)0x28720200) -#define RALINK_3070_VERSION ((u32)0x30700200) - -#define MAX_RX_PKT_LEN 1520 - -/* */ -/* Entry number for each DMA descriptor ring */ -/* */ - -#ifdef RTMP_MAC_PCI -#define TX_RING_SIZE 64 /*64 */ -#define MGMT_RING_SIZE 128 -#define RX_RING_SIZE 128 /*64 */ -#define MAX_TX_PROCESS TX_RING_SIZE /*8 */ -#define MAX_DMA_DONE_PROCESS TX_RING_SIZE -#define MAX_TX_DONE_PROCESS TX_RING_SIZE /*8 */ -#define LOCAL_TXBUF_SIZE 2 -#endif /* RTMP_MAC_PCI // */ - -#define MAX_RX_PROCESS 128 /*64 //32 */ -#define NUM_OF_LOCAL_TXBUF 2 -#define TXD_SIZE 16 -#define TXWI_SIZE 16 -#define RXD_SIZE 16 -#define RXWI_SIZE 16 -/* TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header */ -#define TX_DMA_1ST_BUFFER_SIZE 96 /* only the 1st physical buffer is pre-allocated */ -#define MGMT_DMA_BUFFER_SIZE 1536 /*2048 */ -#define RX_BUFFER_AGGRESIZE 3840 /*3904 //3968 //4096 //2048 //4096 */ -#define RX_BUFFER_NORMSIZE 3840 /*3904 //3968 //4096 //2048 //4096 */ -#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE -#define MAX_FRAME_SIZE 2346 /* Maximum 802.11 frame size */ -#define MAX_AGGREGATION_SIZE 3840 /*3904 //3968 //4096 */ -#define MAX_NUM_OF_TUPLE_CACHE 2 -#define MAX_MCAST_LIST_SIZE 32 -#define MAX_LEN_OF_VENDOR_DESC 64 -/*#define MAX_SIZE_OF_MCAST_PSQ (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ */ -#define MAX_SIZE_OF_MCAST_PSQ 32 - -#define MAX_RX_PROCESS_CNT (RX_RING_SIZE) - -/* - WMM Note: If memory of your system is not much, please reduce the definition; - or when you do WMM test, the queue for low priority AC will be full, i.e. - TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in - WLAN, maybe no packet buffers can get into the Ethernet driver. - - Sometimes no packet buffer can be get into the Ethernet driver, the system will - send flow control packet to the sender to slow down its sending rate. - So no WMM can be seen in the air. -*/ - -/* - Need to use 64 in vxworks for test case WMM A5-T07 - Two dnlink (10Mbps) from a WMM station to a non-WMM station. - If use 256, queue is not enough. - And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to - clConfig.clNum = RX_RING_SIZE * 4; -*/ -/* TODO: For VxWorks the size is 256. Shall we change the value as 256 for all OS? */ -#define MAX_PACKETS_IN_QUEUE (512) /*(512) // to pass WMM A5-WPAPSK */ - -#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32 -#define MAX_PACKETS_IN_PS_QUEUE 128 /*32 */ -#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */ - -#ifdef RTMP_EFUSE_SUPPORT -/*2008/09/11:KH add to support efuse<-- */ -#define MAX_EEPROM_BIN_FILE_SIZE 1024 -#define EFUSE_BUFFER_PATH "/tmp/RT30xxEEPROM.bin" -/*2008/09/11:KH add to support efuse--> */ -#endif /* RTMP_EFUSE_SUPPORT // */ - -/* RxFilter */ -#define STANORMAL 0x17f97 -#define APNORMAL 0x15f97 -#define PSPXLINK 0x17f93 -/* */ -/* struct rt_rtmp_adapter flags */ -/* */ -#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001 -#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002 -#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004 -#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008 -#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010 -#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020 -#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040 -#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080 -#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100 -#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200 -#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400 -#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800 -#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000 -#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000 -#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000 -#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000 -#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000 -#define fRTMP_ADAPTER_RADIO_OFF 0x00020000 -#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000 -#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000 -#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000 -#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000 -#define fRTMP_ADAPTER_SCAN_2040 0x04000000 -#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000 - -#define fRTMP_ADAPTER_START_UP 0x10000000 /*Device already initialized and enabled Tx/Rx. */ -#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000 -#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000 - -/* */ -/* STA operation status flags */ -/* */ -#define fOP_STATUS_INFRA_ON 0x00000001 -#define fOP_STATUS_ADHOC_ON 0x00000002 -#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004 -#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008 -#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010 -#define fOP_STATUS_RECEIVE_DTIM 0x00000020 -#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080 -#define fOP_STATUS_WMM_INUSED 0x00000100 -#define fOP_STATUS_AGGREGATION_INUSED 0x00000200 -#define fOP_STATUS_DOZE 0x00000400 /* debug purpose */ -#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 /* piggy-back, and aggregation */ -#define fOP_STATUS_APSD_INUSED 0x00001000 -#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000 -#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000 -#define fOP_STATUS_WAKEUP_NOW 0x00008000 -#define fOP_STATUS_PCIE_DEVICE 0x00020000 -#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE fOP_STATUS_PCIE_DEVICE - -/* */ -/* struct rt_rtmp_adapter PSFlags : related to advanced power save. */ -/* */ -/* Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up */ -#define fRTMP_PS_CAN_GO_SLEEP 0x00000001 -/* Indicate whether driver has issue a LinkControl command to PCIe L1 */ -#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND 0x00000002 -/* Indicate driver should disable kick off hardware to send packets from now. */ -#define fRTMP_PS_DISABLE_TX 0x00000004 -/* Indicate driver should IMMEDIATELY go to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me */ -/* This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */ -#define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008 -#define fRTMP_PS_TOGGLE_L1 0x00000010 /* Use Toggle L1 mechanism for rt28xx PCIe */ - -#ifdef RT3090 -#define WAKE_MCU_CMD 0x31 -#define SLEEP_MCU_CMD 0x30 -#define RFOFF_MCU_CMD 0x35 -#endif /* RT3090 // */ - -#define CCKSETPROTECT 0x1 -#define OFDMSETPROTECT 0x2 -#define MM20SETPROTECT 0x4 -#define MM40SETPROTECT 0x8 -#define GF20SETPROTECT 0x10 -#define GR40SETPROTECT 0x20 -#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT) - -/* */ -/* AP's client table operation status flags */ -/* */ -#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 /* CLIENT can parse QOS DATA frame */ -#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 /* CLIENT can receive Ralink's proprietary TX aggregation frame */ -#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 /* CLIENT support piggy-back */ -#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008 -#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010 -#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020 -#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040 -#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080 -#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100 -#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200 -#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400 -#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */ - -#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000 -/* */ -/* STA configuration flags */ -/* */ - -/* 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case */ -#define HT_NO_PROTECT 0 -#define HT_LEGACY_PROTECT 1 -#define HT_40_PROTECT 2 -#define HT_2040_PROTECT 3 -#define HT_RTSCTS_6M 7 -/*following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE. */ -#define HT_ATHEROS 8 /* rt2860c has problem with atheros chip. we need to turn on RTS/CTS . */ -#define HT_FORCERTSCTS 9 /* Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary. */ - -/* */ -/* RX Packet Filter control flags. Apply on pAd->PacketFilter */ -/* */ -#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED -#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST -#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST -#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST -#define fRX_FILTER_ACCEPT_PROMISCUOUS NDIS_PACKET_TYPE_PROMISCUOUS - -/* */ -/* Error code section */ -/* */ -/* NDIS_ERROR_CODE_ADAPTER_NOT_FOUND */ -#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L -#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L -#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L - -/* NDIS_ERROR_CODE_ADAPTER_DISABLED */ -#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L - -/* NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION */ -#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L -#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L - -/* NDIS_ERROR_CODE_OUT_OF_RESOURCES */ -#define ERRLOG_OUT_OF_MEMORY 0x00000401L -#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L -#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L -#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L -#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L -#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L -#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L -#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L - -/* NDIS_ERROR_CODE_HARDWARE_FAILURE */ -#define ERRLOG_SELFTEST_FAILED 0x00000501L -#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L -#define ERRLOG_REMOVE_MINIPORT 0x00000503L - -/* NDIS_ERROR_CODE_RESOURCE_CONFLICT */ -#define ERRLOG_MAP_IO_SPACE 0x00000601L -#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L -#define ERRLOG_NO_IO_RESOURCE 0x00000603L -#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L -#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L - -/* WDS definition */ -#define MAX_WDS_ENTRY 4 -#define WDS_PAIRWISE_KEY_OFFSET 60 /* WDS links use pairwise key#60 ~ 63 in ASIC pairwise key table */ - -#define WDS_DISABLE_MODE 0 -#define WDS_RESTRICT_MODE 1 -#define WDS_BRIDGE_MODE 2 -#define WDS_REPEATER_MODE 3 -#define WDS_LAZY_MODE 4 - -#define MAX_MESH_NUM 0 - -#define MAX_APCLI_NUM 0 - -#define MAX_MBSSID_NUM 1 -#ifdef MBSS_SUPPORT -#undef MAX_MBSSID_NUM -#define MAX_MBSSID_NUM (8 - MAX_MESH_NUM - MAX_APCLI_NUM) -#endif /* MBSS_SUPPORT // */ - -/* sanity check for apidx */ -#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \ - { if (apidx > MAX_MBSSID_NUM) { \ - DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx)); \ - apidx = MAIN_MBSSID; } } - -#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE ) - -#define MAIN_MBSSID 0 -#define FIRST_MBSSID 1 - -#define MAX_BEACON_SIZE 512 -/* If the MAX_MBSSID_NUM is larger than 6, */ -/* it shall reserve some WCID space(wcid 222~253) for beacon frames. */ -/* - these wcid 238~253 are reserved for beacon#6(ra6). */ -/* - these wcid 222~237 are reserved for beacon#7(ra7). */ -#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8) -#define HW_RESERVED_WCID 222 -#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7) -#define HW_RESERVED_WCID 238 -#else -#define HW_RESERVED_WCID 255 -#endif - -/* Then dedicate wcid of DFS and Carrier-Sense. */ -#define DFS_CTS_WCID (HW_RESERVED_WCID - 1) -#define CS_CTS_WCID (HW_RESERVED_WCID - 2) -#define LAST_SPECIFIC_WCID (HW_RESERVED_WCID - 2) - -/* If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211. */ -/* If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228. */ -#define MAX_AVAILABLE_CLIENT_WCID (LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1) - -/* TX need WCID to find Cipher Key */ -/* these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8. */ -#define GET_GroupKey_WCID(__wcid, __bssidx) \ - { \ - __wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx; \ - } - -#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM)))) - -/* definition to support multiple BSSID */ -#define BSS0 0 -#define BSS1 1 -#define BSS2 2 -#define BSS3 3 -#define BSS4 4 -#define BSS5 5 -#define BSS6 6 -#define BSS7 7 - -/*============================================================ */ -/* Length definitions */ -#define PEER_KEY_NO 2 -#define MAC_ADDR_LEN 6 -#define TIMESTAMP_LEN 8 -#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES /* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ -#define MAX_LEN_OF_KEY 32 /* 32 octets == 256 bits, Redefine for WPA */ -#define MAX_NUM_OF_CHANNELS MAX_NUM_OF_CHS /* 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */ -#define MAX_NUM_OF_11JCHANNELS 20 /* 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */ -#define MAX_LEN_OF_SSID 32 -#define CIPHER_TEXT_LEN 128 -#define HASH_TABLE_SIZE 256 -#define MAX_VIE_LEN 1024 /* New for WPA cipher suite variable IE sizes. */ -#define MAX_SUPPORT_MCS 32 -#define MAX_NUM_OF_BBP_LATCH 140 - -/*============================================================ */ -/* ASIC WCID Table definition. */ -/*============================================================ */ -#define BSSID_WCID 1 /* in infra mode, always put bssid with this WCID */ -#define MCAST_WCID 0x0 -#define BSS0Mcast_WCID 0x0 -#define BSS1Mcast_WCID 0xf8 -#define BSS2Mcast_WCID 0xf9 -#define BSS3Mcast_WCID 0xfa -#define BSS4Mcast_WCID 0xfb -#define BSS5Mcast_WCID 0xfc -#define BSS6Mcast_WCID 0xfd -#define BSS7Mcast_WCID 0xfe -#define RESERVED_WCID 0xff - -#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL - -#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC /* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */ - -#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID -#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID! -#endif - -#define MAX_NUM_OF_WDS_LINK_PERBSSID 3 -#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM) -#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT -#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1) - -#define NUM_OF_TID 8 -#define MAX_AID_BA 4 -#define MAX_LEN_OF_BA_REC_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2) /* (NUM_OF_TID*MAX_AID_BA + 32) //Block ACK recipient */ -#define MAX_LEN_OF_BA_ORI_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2) /* (NUM_OF_TID*MAX_AID_BA + 32) // Block ACK originator */ -#define MAX_LEN_OF_BSS_TABLE 64 -#define MAX_REORDERING_MPDU_NUM 512 - -/* key related definitions */ -#define SHARE_KEY_NUM 4 -#define MAX_LEN_OF_SHARE_KEY 16 /* byte count */ -#define MAX_LEN_OF_PEER_KEY 16 /* byte count */ -#define PAIRWISE_KEY_NUM 64 /* in MAC ASIC pairwise key table */ -#define GROUP_KEY_NUM 4 -#define PMK_LEN 32 -#define WDS_PAIRWISE_KEY_OFFSET 60 /* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */ -#define PMKID_NO 4 /* Number of PMKID saved supported */ -#define MAX_LEN_OF_MLME_BUFFER 2048 - -/* power status related definitions */ -#define PWR_ACTIVE 0 -#define PWR_SAVE 1 -#define PWR_MMPS 2 /*MIMO power save */ - -/* Auth and Assoc mode related definitions */ -#define AUTH_MODE_OPEN 0x00 -#define AUTH_MODE_KEY 0x01 - -/* BSS Type definitions */ -#define BSS_ADHOC 0 /* = Ndis802_11IBSS */ -#define BSS_INFRA 1 /* = Ndis802_11Infrastructure */ -#define BSS_ANY 2 /* = Ndis802_11AutoUnknown */ -#define BSS_MONITOR 3 /* = Ndis802_11Monitor */ - -/* Reason code definitions */ -#define REASON_RESERVED 0 -#define REASON_UNSPECIFY 1 -#define REASON_NO_longER_VALID 2 -#define REASON_DEAUTH_STA_LEAVING 3 -#define REASON_DISASSOC_INACTIVE 4 -#define REASON_DISASSPC_AP_UNABLE 5 -#define REASON_CLS2ERR 6 -#define REASON_CLS3ERR 7 -#define REASON_DISASSOC_STA_LEAVING 8 -#define REASON_STA_REQ_ASSOC_NOT_AUTH 9 -#define REASON_INVALID_IE 13 -#define REASON_MIC_FAILURE 14 -#define REASON_4_WAY_TIMEOUT 15 -#define REASON_GROUP_KEY_HS_TIMEOUT 16 -#define REASON_IE_DIFFERENT 17 -#define REASON_MCIPHER_NOT_VALID 18 -#define REASON_UCIPHER_NOT_VALID 19 -#define REASON_AKMP_NOT_VALID 20 -#define REASON_UNSUPPORT_RSNE_VER 21 -#define REASON_INVALID_RSNE_CAP 22 -#define REASON_8021X_AUTH_FAIL 23 -#define REASON_CIPHER_SUITE_REJECTED 24 -#define REASON_DECLINED 37 - -#define REASON_QOS_UNSPECIFY 32 -#define REASON_QOS_LACK_BANDWIDTH 33 -#define REASON_POOR_CHANNEL_CONDITION 34 -#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35 -#define REASON_QOS_QSTA_LEAVING_QBSS 36 -#define REASON_QOS_UNWANTED_MECHANISM 37 -#define REASON_QOS_MECH_SETUP_REQUIRED 38 -#define REASON_QOS_REQUEST_TIMEOUT 39 -#define REASON_QOS_CIPHER_NOT_SUPPORT 45 - -/* Status code definitions */ -#define MLME_SUCCESS 0 -#define MLME_UNSPECIFY_FAIL 1 -#define MLME_CANNOT_SUPPORT_CAP 10 -#define MLME_REASSOC_DENY_ASSOC_EXIST 11 -#define MLME_ASSOC_DENY_OUT_SCOPE 12 -#define MLME_ALG_NOT_SUPPORT 13 -#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14 -#define MLME_REJ_CHALLENGE_FAILURE 15 -#define MLME_REJ_TIMEOUT 16 -#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17 -#define MLME_ASSOC_REJ_DATA_RATE 18 - -#define MLME_ASSOC_REJ_NO_EXT_RATE 22 -#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23 -#define MLME_ASSOC_REJ_NO_CCK_OFDM 24 - -#define MLME_QOS_UNSPECIFY 32 -#define MLME_REQUEST_DECLINED 37 -#define MLME_REQUEST_WITH_INVALID_PARAM 38 -#define MLME_INVALID_GROUP_CIPHER 41 -#define MLME_INVALID_PAIRWISE_CIPHER 42 -#define MLME_INVALID_AKMP 43 -#define MLME_DLS_NOT_ALLOW_IN_QBSS 48 -#define MLME_DEST_STA_NOT_IN_QBSS 49 -#define MLME_DEST_STA_IS_NOT_A_QSTA 50 - -#define MLME_INVALID_FORMAT 0x51 -#define MLME_FAIL_NO_RESOURCE 0x52 -#define MLME_STATE_MACHINE_REJECT 0x53 -#define MLME_MAC_TABLE_FAIL 0x54 - -/* IE code */ -#define IE_SSID 0 -#define IE_SUPP_RATES 1 -#define IE_FH_PARM 2 -#define IE_DS_PARM 3 -#define IE_CF_PARM 4 -#define IE_TIM 5 -#define IE_IBSS_PARM 6 -#define IE_COUNTRY 7 /* 802.11d */ -#define IE_802_11D_REQUEST 10 /* 802.11d */ -#define IE_QBSS_LOAD 11 /* 802.11e d9 */ -#define IE_EDCA_PARAMETER 12 /* 802.11e d9 */ -#define IE_TSPEC 13 /* 802.11e d9 */ -#define IE_TCLAS 14 /* 802.11e d9 */ -#define IE_SCHEDULE 15 /* 802.11e d9 */ -#define IE_CHALLENGE_TEXT 16 -#define IE_POWER_CONSTRAint 32 /* 802.11h d3.3 */ -#define IE_POWER_CAPABILITY 33 /* 802.11h d3.3 */ -#define IE_TPC_REQUEST 34 /* 802.11h d3.3 */ -#define IE_TPC_REPORT 35 /* 802.11h d3.3 */ -#define IE_SUPP_CHANNELS 36 /* 802.11h d3.3 */ -#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 /* 802.11h d3.3 */ -#define IE_MEASUREMENT_REQUEST 38 /* 802.11h d3.3 */ -#define IE_MEASUREMENT_REPORT 39 /* 802.11h d3.3 */ -#define IE_QUIET 40 /* 802.11h d3.3 */ -#define IE_IBSS_DFS 41 /* 802.11h d3.3 */ -#define IE_ERP 42 /* 802.11g */ -#define IE_TS_DELAY 43 /* 802.11e d9 */ -#define IE_TCLAS_PROCESSING 44 /* 802.11e d9 */ -#define IE_QOS_CAPABILITY 46 /* 802.11e d6 */ -#define IE_HT_CAP 45 /* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */ -#define IE_AP_CHANNEL_REPORT 51 /* 802.11k d6 */ -#define IE_HT_CAP2 52 /* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */ -#define IE_RSN 48 /* 802.11i d3.0 */ -#define IE_WPA2 48 /* WPA2 */ -#define IE_EXT_SUPP_RATES 50 /* 802.11g */ -#define IE_SUPP_REG_CLASS 59 /* 802.11y. Supported regulatory classes. */ -#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 /* 802.11n */ -#define IE_ADD_HT 61 /* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */ -#define IE_ADD_HT2 53 /* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */ - -/* For 802.11n D3.03 */ -/*#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset element */ -#define IE_SECONDARY_CH_OFFSET 62 /* 802.11n D3.03 Secondary Channel Offset element */ -#define IE_WAPI 68 /* WAPI information element */ -#define IE_2040_BSS_COEXIST 72 /* 802.11n D3.0.3 */ -#define IE_2040_BSS_INTOLERANT_REPORT 73 /* 802.11n D3.03 */ -#define IE_OVERLAPBSS_SCAN_PARM 74 /* 802.11n D3.03 */ -#define IE_EXT_CAPABILITY 127 /* 802.11n D3.03 */ - -#define IE_WPA 221 /* WPA */ -#define IE_VENDOR_SPECIFIC 221 /* Wifi WMM (WME) */ - -#define OUI_BROADCOM_HT 51 /* */ -#define OUI_BROADCOM_HTADD 52 /* */ -#define OUI_PREN_HT_CAP 51 /* */ -#define OUI_PREN_ADD_HT 52 /* */ - -/* CCX information */ -#define IE_AIRONET_CKIP 133 /* CCX1.0 ID 85H for CKIP */ -#define IE_AP_TX_POWER 150 /* CCX 2.0 for AP transmit power */ -#define IE_MEASUREMENT_CAPABILITY 221 /* CCX 2.0 */ -#define IE_CCX_V2 221 -#define IE_AIRONET_IPADDRESS 149 /* CCX ID 95H for IP Address */ -#define IE_AIRONET_CCKMREASSOC 156 /* CCX ID 9CH for CCKM Reassociation Request element */ -#define CKIP_NEGOTIATION_LENGTH 30 -#define AIRONET_IPADDRESS_LENGTH 10 -#define AIRONET_CCKMREASSOC_LENGTH 24 - -/* ======================================================== */ -/* MLME state machine definition */ -/* ======================================================== */ - -/* STA MLME state mahcines */ -#define ASSOC_STATE_MACHINE 1 -#define AUTH_STATE_MACHINE 2 -#define AUTH_RSP_STATE_MACHINE 3 -#define SYNC_STATE_MACHINE 4 -#define MLME_CNTL_STATE_MACHINE 5 -#define WPA_PSK_STATE_MACHINE 6 -/*#define LEAP_STATE_MACHINE 7 */ -#define AIRONET_STATE_MACHINE 8 -#define ACTION_STATE_MACHINE 9 - -/* AP MLME state machines */ -#define AP_ASSOC_STATE_MACHINE 11 -#define AP_AUTH_STATE_MACHINE 12 -#define AP_SYNC_STATE_MACHINE 14 -#define AP_CNTL_STATE_MACHINE 15 -#define WSC_STATE_MACHINE 17 -#define WSC_UPNP_STATE_MACHINE 18 - -#define WPA_STATE_MACHINE 23 - -/* */ -/* STA's CONTROL/CONNECT state machine: states, events, total function # */ -/* */ -#define CNTL_IDLE 0 -#define CNTL_WAIT_DISASSOC 1 -#define CNTL_WAIT_JOIN 2 -#define CNTL_WAIT_REASSOC 3 -#define CNTL_WAIT_START 4 -#define CNTL_WAIT_AUTH 5 -#define CNTL_WAIT_ASSOC 6 -#define CNTL_WAIT_AUTH2 7 -#define CNTL_WAIT_OID_LIST_SCAN 8 -#define CNTL_WAIT_OID_DISASSOC 9 -#ifdef RTMP_MAC_USB -#define CNTL_WAIT_SCAN_FOR_CONNECT 10 -#endif /* RTMP_MAC_USB // */ - -#define MT2_ASSOC_CONF 34 -#define MT2_AUTH_CONF 35 -#define MT2_DEAUTH_CONF 36 -#define MT2_DISASSOC_CONF 37 -#define MT2_REASSOC_CONF 38 -#define MT2_PWR_MGMT_CONF 39 -#define MT2_JOIN_CONF 40 -#define MT2_SCAN_CONF 41 -#define MT2_START_CONF 42 -#define MT2_GET_CONF 43 -#define MT2_SET_CONF 44 -#define MT2_RESET_CONF 45 -#define MT2_FT_OTD_CONF 46 -#define MT2_MLME_ROAMING_REQ 52 - -#define CNTL_FUNC_SIZE 1 - -/* */ -/* STA's ASSOC state machine: states, events, total function # */ -/* */ -#define ASSOC_IDLE 0 -#define ASSOC_WAIT_RSP 1 -#define REASSOC_WAIT_RSP 2 -#define DISASSOC_WAIT_RSP 3 -#define MAX_ASSOC_STATE 4 - -#define ASSOC_MACHINE_BASE 0 -#define MT2_MLME_ASSOC_REQ 0 -#define MT2_MLME_REASSOC_REQ 1 -#define MT2_MLME_DISASSOC_REQ 2 -#define MT2_PEER_DISASSOC_REQ 3 -#define MT2_PEER_ASSOC_REQ 4 -#define MT2_PEER_ASSOC_RSP 5 -#define MT2_PEER_REASSOC_REQ 6 -#define MT2_PEER_REASSOC_RSP 7 -#define MT2_DISASSOC_TIMEOUT 8 -#define MT2_ASSOC_TIMEOUT 9 -#define MT2_REASSOC_TIMEOUT 10 -#define MAX_ASSOC_MSG 11 - -#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG) - -/* */ -/* ACT state machine: states, events, total function # */ -/* */ -#define ACT_IDLE 0 -#define MAX_ACT_STATE 1 - -#define ACT_MACHINE_BASE 0 - -/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please do not modify it by your self. */ -/*Category */ -#define MT2_PEER_SPECTRUM_CATE 0 -#define MT2_PEER_QOS_CATE 1 -#define MT2_PEER_DLS_CATE 2 -#define MT2_PEER_BA_CATE 3 -#define MT2_PEER_PUBLIC_CATE 4 -#define MT2_PEER_RM_CATE 5 -/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */ -#define MT2_PEER_HT_CATE 7 /* 7.4.7 */ -#define MAX_PEER_CATE_MSG 7 - -#define MT2_MLME_ADD_BA_CATE 8 -#define MT2_MLME_ORI_DELBA_CATE 9 -#define MT2_MLME_REC_DELBA_CATE 10 -#define MT2_MLME_QOS_CATE 11 -#define MT2_MLME_DLS_CATE 12 -#define MT2_ACT_INVALID 13 -#define MAX_ACT_MSG 14 - -/*Category field */ -#define CATEGORY_SPECTRUM 0 -#define CATEGORY_QOS 1 -#define CATEGORY_DLS 2 -#define CATEGORY_BA 3 -#define CATEGORY_PUBLIC 4 -#define CATEGORY_RM 5 -#define CATEGORY_HT 7 - -/* DLS Action frame definition */ -#define ACTION_DLS_REQUEST 0 -#define ACTION_DLS_RESPONSE 1 -#define ACTION_DLS_TEARDOWN 2 - -/*Spectrum Action field value 802.11h 7.4.1 */ -#define SPEC_MRQ 0 /* Request */ -#define SPEC_MRP 1 /*Report */ -#define SPEC_TPCRQ 2 -#define SPEC_TPCRP 3 -#define SPEC_CHANNEL_SWITCH 4 - -/*BA Action field value */ -#define ADDBA_REQ 0 -#define ADDBA_RESP 1 -#define DELBA 2 - -/*Public's Action field value in Public Category. Some in 802.11y and some in 11n */ -#define ACTION_BSS_2040_COEXIST 0 /* 11n */ -#define ACTION_DSE_ENABLEMENT 1 /* 11y D9.0 */ -#define ACTION_DSE_DEENABLEMENT 2 /* 11y D9.0 */ -#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 /* 11y D9.0 */ -#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 /* 11y D9.0 */ -#define ACTION_DSE_MEASUREMENT_REQ 5 /* 11y D9.0 */ -#define ACTION_DSE_MEASUREMENT_REPORT 6 /* 11y D9.0 */ -#define ACTION_MEASUREMENT_PILOT_ACTION 7 /* 11y D9.0 */ -#define ACTION_DSE_POWER_CONSTRAINT 8 /* 11y D9.0 */ - -/*HT Action field value */ -#define NOTIFY_BW_ACTION 0 -#define SMPS_ACTION 1 -#define PSMP_ACTION 2 -#define SETPCO_ACTION 3 -#define MIMO_CHA_MEASURE_ACTION 4 -#define MIMO_N_BEACONFORM 5 -#define MIMO_BEACONFORM 6 -#define ANTENNA_SELECT 7 -#define HT_INFO_EXCHANGE 8 - -#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG) -/* */ -/* STA's AUTHENTICATION state machine: states, events, total function # */ -/* */ -#define AUTH_REQ_IDLE 0 -#define AUTH_WAIT_SEQ2 1 -#define AUTH_WAIT_SEQ4 2 -#define MAX_AUTH_STATE 3 - -#define AUTH_MACHINE_BASE 0 -#define MT2_MLME_AUTH_REQ 0 -#define MT2_PEER_AUTH_EVEN 1 -#define MT2_AUTH_TIMEOUT 2 -#define MAX_AUTH_MSG 3 - -#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG) - -/* */ -/* STA's AUTH_RSP state machine: states, events, total function # */ -/* */ -#define AUTH_RSP_IDLE 0 -#define AUTH_RSP_WAIT_CHAL 1 -#define MAX_AUTH_RSP_STATE 2 - -#define AUTH_RSP_MACHINE_BASE 0 -#define MT2_AUTH_CHALLENGE_TIMEOUT 0 -#define MT2_PEER_AUTH_ODD 1 -#define MT2_PEER_DEAUTH 2 -#define MAX_AUTH_RSP_MSG 3 - -#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG) - -/* */ -/* STA's SYNC state machine: states, events, total function # */ -/* */ -#define SYNC_IDLE 0 /* merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state */ -#define JOIN_WAIT_BEACON 1 -#define SCAN_LISTEN 2 -#define MAX_SYNC_STATE 3 - -#define SYNC_MACHINE_BASE 0 -#define MT2_MLME_SCAN_REQ 0 -#define MT2_MLME_JOIN_REQ 1 -#define MT2_MLME_START_REQ 2 -#define MT2_PEER_BEACON 3 -#define MT2_PEER_PROBE_RSP 4 -#define MT2_PEER_ATIM 5 -#define MT2_SCAN_TIMEOUT 6 -#define MT2_BEACON_TIMEOUT 7 -#define MT2_ATIM_TIMEOUT 8 -#define MT2_PEER_PROBE_REQ 9 -#define MAX_SYNC_MSG 10 - -#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG) - -/*Messages for the DLS state machine */ -#define DLS_IDLE 0 -#define MAX_DLS_STATE 1 - -#define DLS_MACHINE_BASE 0 -#define MT2_MLME_DLS_REQ 0 -#define MT2_PEER_DLS_REQ 1 -#define MT2_PEER_DLS_RSP 2 -#define MT2_MLME_DLS_TEAR_DOWN 3 -#define MT2_PEER_DLS_TEAR_DOWN 4 -#define MAX_DLS_MSG 5 - -#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG) - -/* */ -/* WSC State machine: states, events, total function # */ -/* */ - -/* */ -/* AP's CONTROL/CONNECT state machine: states, events, total function # */ -/* */ -#define AP_CNTL_FUNC_SIZE 1 - -/* */ -/* AP's ASSOC state machine: states, events, total function # */ -/* */ -#define AP_ASSOC_IDLE 0 -#define AP_MAX_ASSOC_STATE 1 - -#define AP_ASSOC_MACHINE_BASE 0 -#define APMT2_MLME_DISASSOC_REQ 0 -#define APMT2_PEER_DISASSOC_REQ 1 -#define APMT2_PEER_ASSOC_REQ 2 -#define APMT2_PEER_REASSOC_REQ 3 -#define APMT2_CLS3ERR 4 -#define AP_MAX_ASSOC_MSG 5 - -#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG) - -/* */ -/* AP's AUTHENTICATION state machine: states, events, total function # */ -/* */ -#define AP_AUTH_REQ_IDLE 0 -#define AP_MAX_AUTH_STATE 1 - -#define AP_AUTH_MACHINE_BASE 0 -#define APMT2_MLME_DEAUTH_REQ 0 -#define APMT2_CLS2ERR 1 -#define APMT2_PEER_DEAUTH 2 -#define APMT2_PEER_AUTH_REQ 3 -#define APMT2_PEER_AUTH_CONFIRM 4 -#define AP_MAX_AUTH_MSG 5 - -#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG) - -/* */ -/* AP's SYNC state machine: states, events, total function # */ -/* */ -#define AP_SYNC_IDLE 0 -#define AP_SCAN_LISTEN 1 -#define AP_MAX_SYNC_STATE 2 - -#define AP_SYNC_MACHINE_BASE 0 -#define APMT2_PEER_PROBE_REQ 0 -#define APMT2_PEER_BEACON 1 -#define APMT2_MLME_SCAN_REQ 2 -#define APMT2_PEER_PROBE_RSP 3 -#define APMT2_SCAN_TIMEOUT 4 -#define APMT2_MLME_SCAN_CNCL 5 -#define AP_MAX_SYNC_MSG 6 - -#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG) - -/* */ -/* Common WPA state machine: states, events, total function # */ -/* */ -#define WPA_PTK 0 -#define MAX_WPA_PTK_STATE 1 - -#define WPA_MACHINE_BASE 0 -#define MT2_EAPPacket 0 -#define MT2_EAPOLStart 1 -#define MT2_EAPOLLogoff 2 -#define MT2_EAPOLKey 3 -#define MT2_EAPOLASFAlert 4 -#define MAX_WPA_MSG 5 - -#define WPA_FUNC_SIZE (MAX_WPA_PTK_STATE * MAX_WPA_MSG) - -/* ============================================================================= */ - -/* value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header */ -#define BTYPE_MGMT 0 -#define BTYPE_CNTL 1 -#define BTYPE_DATA 2 - -/* value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */ -#define SUBTYPE_ASSOC_REQ 0 -#define SUBTYPE_ASSOC_RSP 1 -#define SUBTYPE_REASSOC_REQ 2 -#define SUBTYPE_REASSOC_RSP 3 -#define SUBTYPE_PROBE_REQ 4 -#define SUBTYPE_PROBE_RSP 5 -#define SUBTYPE_BEACON 8 -#define SUBTYPE_ATIM 9 -#define SUBTYPE_DISASSOC 10 -#define SUBTYPE_AUTH 11 -#define SUBTYPE_DEAUTH 12 -#define SUBTYPE_ACTION 13 -#define SUBTYPE_ACTION_NO_ACK 14 - -/* value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */ -#define SUBTYPE_WRAPPER 7 -#define SUBTYPE_BLOCK_ACK_REQ 8 -#define SUBTYPE_BLOCK_ACK 9 -#define SUBTYPE_PS_POLL 10 -#define SUBTYPE_RTS 11 -#define SUBTYPE_CTS 12 -#define SUBTYPE_ACK 13 -#define SUBTYPE_CFEND 14 -#define SUBTYPE_CFEND_CFACK 15 - -/* value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */ -#define SUBTYPE_DATA 0 -#define SUBTYPE_DATA_CFACK 1 -#define SUBTYPE_DATA_CFPOLL 2 -#define SUBTYPE_DATA_CFACK_CFPOLL 3 -#define SUBTYPE_NULL_FUNC 4 -#define SUBTYPE_CFACK 5 -#define SUBTYPE_CFPOLL 6 -#define SUBTYPE_CFACK_CFPOLL 7 -#define SUBTYPE_QDATA 8 -#define SUBTYPE_QDATA_CFACK 9 -#define SUBTYPE_QDATA_CFPOLL 10 -#define SUBTYPE_QDATA_CFACK_CFPOLL 11 -#define SUBTYPE_QOS_NULL 12 -#define SUBTYPE_QOS_CFACK 13 -#define SUBTYPE_QOS_CFPOLL 14 -#define SUBTYPE_QOS_CFACK_CFPOLL 15 - -/* ACK policy of QOS Control field bit 6:5 */ -#define NORMAL_ACK 0x00 /* b6:5 = 00 */ -#define NO_ACK 0x20 /* b6:5 = 01 */ -#define NO_EXPLICIT_ACK 0x40 /* b6:5 = 10 */ -#define BLOCK_ACK 0x60 /* b6:5 = 11 */ - -/* */ -/* rtmp_data.c uses this definition */ -/* */ -#define LENGTH_802_11 24 -#define LENGTH_802_11_AND_H 30 -#define LENGTH_802_11_CRC_H 34 -#define LENGTH_802_11_CRC 28 -#define LENGTH_802_11_WITH_ADDR4 30 -#define LENGTH_802_3 14 -#define LENGTH_802_3_TYPE 2 -#define LENGTH_802_1_H 8 -#define LENGTH_EAPOL_H 4 -#define LENGTH_WMMQOS_H 2 -#define LENGTH_CRC 4 -#define MAX_SEQ_NUMBER 0x0fff -#define LENGTH_802_3_NO_TYPE 12 -#define LENGTH_802_1Q 4 /* VLAN related */ - -/* STA_CSR4.field.TxResult */ -#define TX_RESULT_SUCCESS 0 -#define TX_RESULT_ZERO_LENGTH 1 -#define TX_RESULT_UNDER_RUN 2 -#define TX_RESULT_OHY_ERROR 4 -#define TX_RESULT_RETRY_FAIL 6 - -/* All PHY rate summary in TXD */ -/* Preamble MODE in TxD */ -#define MODE_CCK 0 -#define MODE_OFDM 1 -#define MODE_HTMIX 2 -#define MODE_HTGREENFIELD 3 - -/* MCS for CCK. BW.SGI.STBC are reserved */ -#define MCS_longP_RATE_1 0 /* long preamble CCK 1Mbps */ -#define MCS_longP_RATE_2 1 /* long preamble CCK 1Mbps */ -#define MCS_longP_RATE_5_5 2 -#define MCS_longP_RATE_11 3 -#define MCS_SHORTP_RATE_1 4 /* long preamble CCK 1Mbps. short is forbidden in 1Mbps */ -#define MCS_SHORTP_RATE_2 5 /* short preamble CCK 2Mbps */ -#define MCS_SHORTP_RATE_5_5 6 -#define MCS_SHORTP_RATE_11 7 -/* To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved */ -#define MCS_RATE_6 0 /* legacy OFDM */ -#define MCS_RATE_9 1 /* OFDM */ -#define MCS_RATE_12 2 /* OFDM */ -#define MCS_RATE_18 3 /* OFDM */ -#define MCS_RATE_24 4 /* OFDM */ -#define MCS_RATE_36 5 /* OFDM */ -#define MCS_RATE_48 6 /* OFDM */ -#define MCS_RATE_54 7 /* OFDM */ -/* HT */ -#define MCS_0 0 /* 1S */ -#define MCS_1 1 -#define MCS_2 2 -#define MCS_3 3 -#define MCS_4 4 -#define MCS_5 5 -#define MCS_6 6 -#define MCS_7 7 -#define MCS_8 8 /* 2S */ -#define MCS_9 9 -#define MCS_10 10 -#define MCS_11 11 -#define MCS_12 12 -#define MCS_13 13 -#define MCS_14 14 -#define MCS_15 15 -#define MCS_16 16 /* 3*3 */ -#define MCS_17 17 -#define MCS_18 18 -#define MCS_19 19 -#define MCS_20 20 -#define MCS_21 21 -#define MCS_22 22 -#define MCS_23 23 -#define MCS_32 32 -#define MCS_AUTO 33 - -/* OID_HTPHYMODE */ -/* MODE */ -#define HTMODE_MM 0 -#define HTMODE_GF 1 - -/* Fixed Tx MODE - HT, CCK or OFDM */ -#define FIXED_TXMODE_HT 0 -#define FIXED_TXMODE_CCK 1 -#define FIXED_TXMODE_OFDM 2 -/* BW */ -#define BW_20 BAND_WIDTH_20 -#define BW_40 BAND_WIDTH_40 -#define BW_BOTH BAND_WIDTH_BOTH -#define BW_10 BAND_WIDTH_10 /* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */ - -/* SHORTGI */ -#define GI_400 GAP_INTERVAL_400 /* only support in HT mode */ -#define GI_BOTH GAP_INTERVAL_BOTH -#define GI_800 GAP_INTERVAL_800 -/* STBC */ -#define STBC_NONE 0 -#define STBC_USE 1 /* limited use in rt2860b phy */ -#define RXSTBC_ONE 1 /* rx support of one spatial stream */ -#define RXSTBC_TWO 2 /* rx support of 1 and 2 spatial stream */ -#define RXSTBC_THR 3 /* rx support of 1~3 spatial stream */ -/* MCS FEEDBACK */ -#define MCSFBK_NONE 0 /* not support mcs feedback / */ -#define MCSFBK_RSV 1 /* reserved */ -#define MCSFBK_UNSOLICIT 2 /* only support unsolict mcs feedback */ -#define MCSFBK_MRQ 3 /* response to both MRQ and unsolict mcs feedback */ - -/* MIMO power safe */ -#define MMPS_STATIC 0 -#define MMPS_DYNAMIC 1 -#define MMPS_RSV 2 -#define MMPS_ENABLE 3 - -/* A-MSDU size */ -#define AMSDU_0 0 -#define AMSDU_1 1 - -/* MCS use 7 bits */ -#define TXRATEMIMO 0x80 -#define TXRATEMCS 0x7F -#define TXRATEOFDM 0x7F -#define RATE_1 0 -#define RATE_2 1 -#define RATE_5_5 2 -#define RATE_11 3 -#define RATE_6 4 /* OFDM */ -#define RATE_9 5 /* OFDM */ -#define RATE_12 6 /* OFDM */ -#define RATE_18 7 /* OFDM */ -#define RATE_24 8 /* OFDM */ -#define RATE_36 9 /* OFDM */ -#define RATE_48 10 /* OFDM */ -#define RATE_54 11 /* OFDM */ -#define RATE_FIRST_OFDM_RATE RATE_6 -#define RATE_LAST_OFDM_RATE RATE_54 -#define RATE_6_5 12 /* HT mix */ -#define RATE_13 13 /* HT mix */ -#define RATE_19_5 14 /* HT mix */ -#define RATE_26 15 /* HT mix */ -#define RATE_39 16 /* HT mix */ -#define RATE_52 17 /* HT mix */ -#define RATE_58_5 18 /* HT mix */ -#define RATE_65 19 /* HT mix */ -#define RATE_78 20 /* HT mix */ -#define RATE_104 21 /* HT mix */ -#define RATE_117 22 /* HT mix */ -#define RATE_130 23 /* HT mix */ -/*#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only */ -#define HTRATE_0 12 -#define RATE_FIRST_MM_RATE HTRATE_0 -#define RATE_FIRST_HT_RATE HTRATE_0 -#define RATE_LAST_HT_RATE HTRATE_0 - -/* pTxWI->txop */ -#define IFS_HTTXOP 0 /* The txop will be handles by ASIC. */ -#define IFS_PIFS 1 -#define IFS_SIFS 2 -#define IFS_BACKOFF 3 - -/* pTxD->RetryMode */ -#define long_RETRY 1 -#define SHORT_RETRY 0 - -/* Country Region definition */ -#define REGION_MINIMUM_BG_BAND 0 -#define REGION_0_BG_BAND 0 /* 1-11 */ -#define REGION_1_BG_BAND 1 /* 1-13 */ -#define REGION_2_BG_BAND 2 /* 10-11 */ -#define REGION_3_BG_BAND 3 /* 10-13 */ -#define REGION_4_BG_BAND 4 /* 14 */ -#define REGION_5_BG_BAND 5 /* 1-14 */ -#define REGION_6_BG_BAND 6 /* 3-9 */ -#define REGION_7_BG_BAND 7 /* 5-13 */ -#define REGION_31_BG_BAND 31 /* 5-13 */ -#define REGION_MAXIMUM_BG_BAND 7 - -#define REGION_MINIMUM_A_BAND 0 -#define REGION_0_A_BAND 0 /* 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 */ -#define REGION_1_A_BAND 1 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */ -#define REGION_2_A_BAND 2 /* 36, 40, 44, 48, 52, 56, 60, 64 */ -#define REGION_3_A_BAND 3 /* 52, 56, 60, 64, 149, 153, 157, 161 */ -#define REGION_4_A_BAND 4 /* 149, 153, 157, 161, 165 */ -#define REGION_5_A_BAND 5 /* 149, 153, 157, 161 */ -#define REGION_6_A_BAND 6 /* 36, 40, 44, 48 */ -#define REGION_7_A_BAND 7 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173 */ -#define REGION_8_A_BAND 8 /* 52, 56, 60, 64 */ -#define REGION_9_A_BAND 9 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165 */ -#define REGION_10_A_BAND 10 /* 36, 40, 44, 48, 149, 153, 157, 161, 165 */ -#define REGION_11_A_BAND 11 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 */ -#define REGION_12_A_BAND 12 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */ -#define REGION_13_A_BAND 13 /* 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161 */ -#define REGION_14_A_BAND 14 /* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165 */ -#define REGION_15_A_BAND 15 /* 149, 153, 157, 161, 165, 169, 173 */ -#define REGION_MAXIMUM_A_BAND 15 - -/* pTxD->CipherAlg */ -#define CIPHER_NONE 0 -#define CIPHER_WEP64 1 -#define CIPHER_WEP128 2 -#define CIPHER_TKIP 3 -#define CIPHER_AES 4 -#define CIPHER_CKIP64 5 -#define CIPHER_CKIP128 6 -#define CIPHER_TKIP_NO_MIC 7 /* MIC appended by driver: not a valid value in hardware key table */ -#define CIPHER_SMS4 8 - -/* LED Status. */ -#define LED_LINK_DOWN 0 -#define LED_LINK_UP 1 -#define LED_RADIO_OFF 2 -#define LED_RADIO_ON 3 -#define LED_HALT 4 -#define LED_WPS 5 -#define LED_ON_SITE_SURVEY 6 -#define LED_POWER_UP 7 - -/* value domain of pAd->LedCntl.LedMode and E2PROM */ -#define LED_MODE_DEFAULT 0 -#define LED_MODE_TWO_LED 1 -/*#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8 */ -#define LED_MODE_SIGNAL_STREGTH 0x40 /* EEPROM define = 64 */ - -/* RC4 init value, used fro WEP & TKIP */ -#define PPPINITFCS32 0xffffffff /* Initial FCS value */ - -/* value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition */ -#define WPA_802_1X_PORT_SECURED 1 -#define WPA_802_1X_PORT_NOT_SECURED 2 - -#define PAIRWISE_KEY 1 -#define GROUP_KEY 2 - -/*definition of DRS */ -#define MAX_STEP_OF_TX_RATE_SWITCH 32 - -/* pre-allocated free NDIS PACKET/BUFFER poll for internal usage */ -#define MAX_NUM_OF_FREE_NDIS_PACKET 128 - -/*Block ACK */ -#define MAX_TX_REORDERBUF 64 -#define MAX_RX_REORDERBUF 64 -#define DEFAULT_TX_TIMEOUT 30 -#define DEFAULT_RX_TIMEOUT 30 - -/* definition of Recipient or Originator */ -#define I_RECIPIENT TRUE -#define I_ORIGINATOR FALSE - -#define DEFAULT_BBP_TX_POWER 0 -#define DEFAULT_RF_TX_POWER 5 - -#define MAX_INI_BUFFER_SIZE 4096 -#define MAX_PARAM_BUFFER_SIZE (2048) /* enough for ACL (18*64) */ - /*18 : the length of Mac address acceptable format "01:02:03:04:05:06;") */ - /*64 : MAX_NUM_OF_ACL_LIST */ -/* definition of pAd->OpMode */ -#define OPMODE_STA 0 -#define OPMODE_AP 1 -/*#define OPMODE_L3_BRG 2 // as AP and STA at the same time */ - -/* ========================= AP rtmp_def.h =========================== */ -/* value domain for pAd->EventTab.Log[].Event */ -#define EVENT_RESET_ACCESS_POint 0 /* Log = "hh:mm:ss Restart Access Point" */ -#define EVENT_ASSOCIATED 1 /* Log = "hh:mm:ss STA 00:01:02:03:04:05 associated" */ -#define EVENT_DISASSOCIATED 2 /* Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS" */ -#define EVENT_AGED_OUT 3 /* Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS" */ -#define EVENT_COUNTER_M 4 -#define EVENT_INVALID_PSK 5 -#define EVENT_MAX_EVENT_TYPE 6 -/* ==== end of AP rtmp_def.h ============ */ - -/* definition RSSI Number */ -#define RSSI_0 0 -#define RSSI_1 1 -#define RSSI_2 2 - -/* definition of radar detection */ -#define RD_NORMAL_MODE 0 /* Not found radar signal */ -#define RD_SWITCHING_MODE 1 /* Found radar signal, and doing channel switch */ -#define RD_SILENCE_MODE 2 /* After channel switch, need to be silence a while to ensure radar not found */ - -/*Driver defined cid for mapping status and command. */ -#define SLEEPCID 0x11 -#define WAKECID 0x22 -#define QUERYPOWERCID 0x33 -#define OWNERMCU 0x1 -#define OWNERCPU 0x0 - -/* MBSSID definition */ -#define ENTRY_NOT_FOUND 0xFF - -/* After Linux 2.6.9, - * VLAN module use Private (from user) interface flags (netdevice->priv_flags). - * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h - * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c - * - * For this reason, we MUST use EVEN value in priv_flags - */ -#define INT_MAIN 0x0100 -#define INT_MBSSID 0x0200 -#define INT_WDS 0x0300 -#define INT_APCLI 0x0400 -#define INT_MESH 0x0500 - -#define INF_MAIN_DEV_NAME "wlan" -#define INF_MBSSID_DEV_NAME "ra" -#define INF_WDS_DEV_NAME "wds" -#define INF_APCLI_DEV_NAME "apcli" -#define INF_MESH_DEV_NAME "mesh" - -/* WEP Key TYPE */ -#define WEP_HEXADECIMAL_TYPE 0 -#define WEP_ASCII_TYPE 1 - -/* WIRELESS EVENTS definition */ -/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */ -#define IW_CUSTOM_MAX_LEN 255 /* In bytes */ - -/* For system event - start */ -#define IW_SYS_EVENT_FLAG_START 0x0200 -#define IW_ASSOC_EVENT_FLAG 0x0200 -#define IW_DISASSOC_EVENT_FLAG 0x0201 -#define IW_DEAUTH_EVENT_FLAG 0x0202 -#define IW_AGEOUT_EVENT_FLAG 0x0203 -#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204 -#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205 -#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206 -#define IW_MIC_DIFF_EVENT_FLAG 0x0207 -#define IW_ICV_ERROR_EVENT_FLAG 0x0208 -#define IW_MIC_ERROR_EVENT_FLAG 0x0209 -#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A -#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B -#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C -#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D -#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E -#define IW_STA_LINKUP_EVENT_FLAG 0x020F -#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210 -#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211 -#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212 -/* if add new system event flag, please update the IW_SYS_EVENT_FLAG_END */ -#define IW_SYS_EVENT_FLAG_END 0x0212 -#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1) -/* For system event - end */ - -/* For spoof attack event - start */ -#define IW_SPOOF_EVENT_FLAG_START 0x0300 -#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300 -#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301 -#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302 -#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303 -#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304 -#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305 -#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306 -#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307 -#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308 -#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309 -/* if add new spoof attack event flag, please update the IW_SPOOF_EVENT_FLAG_END */ -#define IW_SPOOF_EVENT_FLAG_END 0x0309 -#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1) -/* For spoof attack event - end */ - -/* For flooding attack event - start */ -#define IW_FLOOD_EVENT_FLAG_START 0x0400 -#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400 -#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401 -#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402 -#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403 -#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404 -#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405 -#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406 -/* if add new flooding attack event flag, please update the IW_FLOOD_EVENT_FLAG_END */ -#define IW_FLOOD_EVENT_FLAG_END 0x0406 -#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1) -/* For flooding attack - end */ - -/* End - WIRELESS EVENTS definition */ - -/* definition for DLS, kathy */ -#define MAX_NUM_OF_INIT_DLS_ENTRY 1 -#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY - -/*Block ACK, kathy */ -#define MAX_TX_REORDERBUF 64 -#define MAX_RX_REORDERBUF 64 -#define DEFAULT_TX_TIMEOUT 30 -#define DEFAULT_RX_TIMEOUT 30 -#define MAX_BARECI_SESSION 8 - -#ifndef IW_ESSID_MAX_SIZE -/* Maximum size of the ESSID and pAd->nickname strings */ -#define IW_ESSID_MAX_SIZE 32 -#endif - -/* For AsicRadioOff/AsicRadioOn function */ -#define DOT11POWERSAVE 0 -#define GUIRADIO_OFF 1 -#define RTMP_HALT 2 -#define GUI_IDLE_POWER_SAVE 3 -/* -- */ - -/* definition for WpaSupport flag */ -#define WPA_SUPPLICANT_DISABLE 0 -#define WPA_SUPPLICANT_ENABLE 1 -#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 2 - -/* Endian byte swapping codes */ -#define SWAP16(x) \ - ((u16)( \ - (((u16)(x) & (u16)0x00ffU) << 8) | \ - (((u16)(x) & (u16)0xff00U) >> 8) )) - -#define SWAP32(x) \ - ((u32)( \ - (((u32)(x) & (u32)0x000000ffUL) << 24) | \ - (((u32)(x) & (u32)0x0000ff00UL) << 8) | \ - (((u32)(x) & (u32)0x00ff0000UL) >> 8) | \ - (((u32)(x) & (u32)0xff000000UL) >> 24) )) - -#define SWAP64(x) \ - ((u64)( \ - (u64)(((u64)(x) & (u64)0x00000000000000ffULL) << 56) | \ - (u64)(((u64)(x) & (u64)0x000000000000ff00ULL) << 40) | \ - (u64)(((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) | \ - (u64)(((u64)(x) & (u64)0x00000000ff000000ULL) << 8) | \ - (u64)(((u64)(x) & (u64)0x000000ff00000000ULL) >> 8) | \ - (u64)(((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) | \ - (u64)(((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) | \ - (u64)(((u64)(x) & (u64)0xff00000000000000ULL) >> 56) )) - -#define cpu2le64(x) ((u64)(x)) -#define le2cpu64(x) ((u64)(x)) -#define cpu2le32(x) ((u32)(x)) -#define le2cpu32(x) ((u32)(x)) -#define cpu2le16(x) ((u16)(x)) -#define le2cpu16(x) ((u16)(x)) -#define cpu2be64(x) SWAP64((x)) -#define be2cpu64(x) SWAP64((x)) -#define cpu2be32(x) SWAP32((x)) -#define be2cpu32(x) SWAP32((x)) -#define cpu2be16(x) SWAP16((x)) -#define be2cpu16(x) SWAP16((x)) - -#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x)) - -#define A2Dec(_X, _p) \ -{ \ - u8 *p; \ - _X = 0; \ - p = _p; \ - while (((*p >= '0') && (*p <= '9'))) \ - { \ - if ((*p >= '0') && (*p <= '9')) \ - _X = _X * 10 + *p - 48; \ - p++; \ - } \ -} - -#define A2Hex(_X, _p) \ -do{ \ - char *__p; \ - (_X) = 0; \ - __p = (char *)(_p); \ - while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9'))) \ - { \ - if ((*__p >= 'a') && (*__p <= 'f')) \ - (_X) = (_X) * 16 + *__p - 87; \ - else if ((*__p >= 'A') && (*__p <= 'F')) \ - (_X) = (_X) * 16 + *__p - 55; \ - else if ((*__p >= '0') && (*__p <= '9')) \ - (_X) = (_X) * 16 + *__p - 48; \ - __p++; \ - } \ -}while(0) - -#endif /* __RTMP_DEF_H__ */ diff --git a/drivers/staging/rt2860/rtmp_dot11.h b/drivers/staging/rt2860/rtmp_dot11.h deleted file mode 100644 index 4f8abd77ada5..000000000000 --- a/drivers/staging/rt2860/rtmp_dot11.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#ifndef __DOT11_BASE_H__ -#define __DOT11_BASE_H__ - -#include "rtmp_type.h" - -/* 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1. */ -struct PACKED rt_ht_control { - u32 MA:1; /*management action payload exist in (QoS Null+HTC) */ - u32 TRQ:1; /*sounding request */ - u32 MRQ:1; /*MCS feedback. Request for a MCS feedback */ - u32 MRSorASI:3; /* MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110. */ - u32 MFS:3; /*SET to the received value of MRS. 0x111 for unsolicited MFB. */ - u32 MFBorASC:7; /*Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available */ - u32 CalPos:2; /* calibration position */ - u32 CalSeq:2; /*calibration sequence */ - u32 FBKReq:2; /*feedback request */ - u32 CSISTEERING:2; /*CSI/ STEERING */ - u32 ZLFAnnouce:1; /* ZLF announcement */ - u32 rsv:5; /*calibration sequence */ - u32 ACConstraint:1; /*feedback request */ - u32 RDG:1; /*RDG / More PPDU */ -}; - -/* 2-byte QOS CONTROL field */ -struct PACKED rt_qos_control { - u16 TID:4; - u16 EOSP:1; - u16 AckPolicy:2; /*0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA */ - u16 AMsduPresent:1; - u16 Txop_QueueSize:8; -}; - -/* 2-byte Frame control field */ -struct PACKED rt_frame_control { - u16 Ver:2; /* Protocol version */ - u16 Type:2; /* MSDU type */ - u16 SubType:4; /* MSDU subtype */ - u16 ToDs:1; /* To DS indication */ - u16 FrDs:1; /* From DS indication */ - u16 MoreFrag:1; /* More fragment bit */ - u16 Retry:1; /* Retry status bit */ - u16 PwrMgmt:1; /* Power management bit */ - u16 MoreData:1; /* More data bit */ - u16 Wep:1; /* Wep data */ - u16 Order:1; /* Strict order expected */ -}; - -struct PACKED rt_header_802_11 { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; - u8 Addr3[MAC_ADDR_LEN]; - u16 Frag:4; - u16 Sequence:12; - u8 Octet[0]; -}; - -struct PACKED rt_pspoll_frame { - struct rt_frame_control FC; - u16 Aid; - u8 Bssid[MAC_ADDR_LEN]; - u8 Ta[MAC_ADDR_LEN]; -}; - -struct PACKED rt_rts_frame { - struct rt_frame_control FC; - u16 Duration; - u8 Addr1[MAC_ADDR_LEN]; - u8 Addr2[MAC_ADDR_LEN]; -}; - -#endif /* __DOT11_BASE_H__ // */ diff --git a/drivers/staging/rt2860/rtmp_iface.h b/drivers/staging/rt2860/rtmp_iface.h deleted file mode 100644 index 808c05529848..000000000000 --- a/drivers/staging/rt2860/rtmp_iface.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rt_iface.h - - Abstract: - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - */ - -#ifndef __RTMP_IFACE_H__ -#define __RTMP_IFACE_H__ - -#ifdef RTMP_PCI_SUPPORT -#include "iface/rtmp_pci.h" -#endif /* RTMP_PCI_SUPPORT // */ -#ifdef RTMP_USB_SUPPORT -#include "iface/rtmp_usb.h" -#endif /* RTMP_USB_SUPPORT // */ - -struct rt_inf_pci_config { - unsigned long CSRBaseAddress; /* PCI MMIO Base Address, all access will use */ - unsigned int irq_num; -}; - -struct rt_inf_usb_config { - u8 BulkInEpAddr; /* bulk-in endpoint address */ - u8 BulkOutEpAddr[6]; /* bulk-out endpoint address */ -}; - -struct rt_inf_rbus_config { - unsigned long csr_addr; - unsigned int irq; -}; - -typedef enum _RTMP_INF_TYPE_ { - RTMP_DEV_INF_UNKNOWN = 0, - RTMP_DEV_INF_PCI = 1, - RTMP_DEV_INF_USB = 2, - RTMP_DEV_INF_RBUS = 4, -} RTMP_INF_TYPE; - -typedef union _RTMP_INF_CONFIG_ { - struct rt_inf_pci_config pciConfig; - struct rt_inf_usb_config usbConfig; - struct rt_inf_rbus_config rbusConfig; -} RTMP_INF_CONFIG; - -#endif /* __RTMP_IFACE_H__ // */ diff --git a/drivers/staging/rt2860/rtmp_mcu.h b/drivers/staging/rt2860/rtmp_mcu.h deleted file mode 100644 index d0987e55cdad..000000000000 --- a/drivers/staging/rt2860/rtmp_mcu.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_mcu.h - - Abstract: - Miniport header file for mcu related information - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#ifndef __RTMP_MCU_H__ -#define __RTMP_MCU_H__ - -int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd); - -int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd); - -int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, - u8 Command, - u8 Token, u8 Arg0, u8 Arg1); - -#endif /* __RTMP_MCU_H__ // */ diff --git a/drivers/staging/rt2860/rtmp_os.h b/drivers/staging/rt2860/rtmp_os.h deleted file mode 100644 index 94c30c8ca662..000000000000 --- a/drivers/staging/rt2860/rtmp_os.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_os.h - - Abstract: - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - */ - -#ifndef __RTMP_OS_H__ -#define __RTMP_OS_H__ - -#ifdef LINUX -#include "rt_linux.h" -#endif /* LINUX // */ - -/* - This data structure mainly strip some callback function defined in - "struct net_device" in kernel source "include/linux/netdevice.h". - - The definition of this data structure may various depends on different - OS. Use it carefully. -*/ -struct rt_rtmp_os_netdev_op_hook { - const struct net_device_ops *netdev_ops; - void *priv; - int priv_flags; - unsigned char devAddr[6]; - unsigned char devName[16]; - unsigned char needProtcted; -}; - -typedef enum _RTMP_TASK_STATUS_ { - RTMP_TASK_STAT_UNKNOWN = 0, - RTMP_TASK_STAT_INITED = 1, - RTMP_TASK_STAT_RUNNING = 2, - RTMP_TASK_STAT_STOPED = 4, -} RTMP_TASK_STATUS; -#define RTMP_TASK_CAN_DO_INSERT (RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING) - -#define RTMP_OS_TASK_NAME_LEN 16 -struct rt_rtmp_os_task { - char taskName[RTMP_OS_TASK_NAME_LEN]; - void *priv; - /*unsigned long taskFlags; */ - RTMP_TASK_STATUS taskStatus; -#ifndef KTHREAD_SUPPORT - struct semaphore taskSema; - struct pid *taskPID; - struct completion taskComplete; -#endif - unsigned char task_killed; -#ifdef KTHREAD_SUPPORT - struct task_struct *kthread_task; - wait_queue_head_t kthread_q; - BOOLEAN kthread_running; -#endif -}; - -int RtmpOSIRQRequest(struct net_device *pNetDev); -int RtmpOSIRQRelease(struct net_device *pNetDev); - -#endif /* __RMTP_OS_H__ // */ diff --git a/drivers/staging/rt2860/rtmp_timer.h b/drivers/staging/rt2860/rtmp_timer.h deleted file mode 100644 index 15b628743500..000000000000 --- a/drivers/staging/rt2860/rtmp_timer.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_timer.h - - Abstract: - Ralink Wireless Driver timer related data structures and declarations - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Shiang Tu Aug-28-2008 init version - Justin P. Mattock 11/07/2010 Fix a typo - -*/ - -#ifndef __RTMP_TIMER_H__ -#define __RTMP_TIMER_H__ - -#include "rtmp_os.h" - -#define DECLARE_TIMER_FUNCTION(_func) \ - void rtmp_timer_##_func(unsigned long data) - -#define GET_TIMER_FUNCTION(_func) \ - rtmp_timer_##_func - -/* ----------------- Timer Related MARCO ---------------*/ -/* In some os or chipset, we have a lot of timer functions and will read/write register, */ -/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */ -/* submit to ctrl pipe). So we need a wrapper function to take care it. */ - -#ifdef RTMP_TIMER_TASK_SUPPORT -typedef void(*RTMP_TIMER_TASK_HANDLE) (void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3); -#endif /* RTMP_TIMER_TASK_SUPPORT // */ - -struct rt_ralink_timer { - struct timer_list TimerObj; /* Ndis Timer object */ - BOOLEAN Valid; /* Set to True when call RTMPInitTimer */ - BOOLEAN State; /* True if timer cancelled */ - BOOLEAN PeriodicType; /* True if timer is periodic timer */ - BOOLEAN Repeat; /* True if periodic timer */ - unsigned long TimerValue; /* Timer value in milliseconds */ - unsigned long cookie; /* os specific object */ -#ifdef RTMP_TIMER_TASK_SUPPORT - RTMP_TIMER_TASK_HANDLE handle; - void *pAd; -#endif /* RTMP_TIMER_TASK_SUPPORT // */ -}; - -#ifdef RTMP_TIMER_TASK_SUPPORT -struct rt_rtmp_timer_task_entry { - struct rt_ralink_timer *pRaTimer; - struct rt_rtmp_timer_task_entry *pNext; -}; - -#define TIMER_QUEUE_SIZE_MAX 128 -struct rt_rtmp_timer_task_queue { - unsigned int status; - unsigned char *pTimerQPoll; - struct rt_rtmp_timer_task_entry *pQPollFreeList; - struct rt_rtmp_timer_task_entry *pQHead; - struct rt_rtmp_timer_task_entry *pQTail; -}; - -#define BUILD_TIMER_FUNCTION(_func) \ -void rtmp_timer_##_func(unsigned long data) \ -{ \ - struct rt_ralink_timer *_pTimer = (struct rt_ralink_timer *)data; \ - struct rt_rtmp_timer_task_entry *_pQNode; \ - struct rt_rtmp_adapter *_pAd; \ - \ - _pTimer->handle = _func; \ - _pAd = (struct rt_rtmp_adapter *)_pTimer->pAd; \ - _pQNode = RtmpTimerQInsert(_pAd, _pTimer); \ - if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)) \ - RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ); \ -} -#else -#define BUILD_TIMER_FUNCTION(_func) \ -void rtmp_timer_##_func(unsigned long data) \ -{ \ - struct rt_ralink_timer *pTimer = (struct rt_ralink_timer *)data; \ - \ - _func(NULL, (void *)pTimer->cookie, NULL, pTimer); \ - if (pTimer->Repeat) \ - RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \ -} -#endif /* RTMP_TIMER_TASK_SUPPORT // */ - -DECLARE_TIMER_FUNCTION(MlmePeriodicExec); -DECLARE_TIMER_FUNCTION(MlmeRssiReportExec); -DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout); -DECLARE_TIMER_FUNCTION(APSDPeriodicExec); -DECLARE_TIMER_FUNCTION(AsicRfTuningExec); -#ifdef RTMP_MAC_USB -DECLARE_TIMER_FUNCTION(BeaconUpdateExec); -#endif /* RTMP_MAC_USB // */ - -DECLARE_TIMER_FUNCTION(BeaconTimeout); -DECLARE_TIMER_FUNCTION(ScanTimeout); -DECLARE_TIMER_FUNCTION(AuthTimeout); -DECLARE_TIMER_FUNCTION(AssocTimeout); -DECLARE_TIMER_FUNCTION(ReassocTimeout); -DECLARE_TIMER_FUNCTION(DisassocTimeout); -DECLARE_TIMER_FUNCTION(LinkDownExec); -DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec); -DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); -DECLARE_TIMER_FUNCTION(PsPollWakeExec); -DECLARE_TIMER_FUNCTION(RadioOnExec); - -#ifdef RTMP_MAC_USB -DECLARE_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); -#endif /* RTMP_MAC_USB // */ - -#if defined(AP_LED) || defined(STA_LED) -DECLARE_TIMER_FUNCTION(LedCtrlMain); -#endif - -#endif /* __RTMP_TIMER_H__ // */ diff --git a/drivers/staging/rt2860/rtmp_type.h b/drivers/staging/rt2860/rtmp_type.h deleted file mode 100644 index d9bb2d64c8b8..000000000000 --- a/drivers/staging/rt2860/rtmp_type.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_type.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Paul Lin 1-2-2004 -*/ -#ifndef __RTMP_TYPE_H__ -#define __RTMP_TYPE_H__ - -#include - -#define PACKED __attribute__ ((packed)) - -typedef unsigned char BOOLEAN; - -typedef union _LARGE_INTEGER { - struct { - u32 LowPart; - int HighPart; - } u; - long long QuadPart; -} LARGE_INTEGER; - -/* */ -/* Register set pair for initialzation register set definition */ -/* */ -struct rt_rtmp_reg_pair { - unsigned long Register; - unsigned long Value; -}; - -struct rt_reg_pair { - u8 Register; - u8 Value; -}; - -/* */ -/* Register set pair for initialzation register set definition */ -/* */ -struct rt_rtmp_rf_regs { - u8 Channel; - unsigned long R1; - unsigned long R2; - unsigned long R3; - unsigned long R4; -}; - -struct rt_frequency_item { - u8 Channel; - u8 N; - u8 R; - u8 K; -}; - -#define STATUS_SUCCESS 0x00 -#define STATUS_UNSUCCESSFUL 0x01 - -#endif /* __RTMP_TYPE_H__ // */ diff --git a/drivers/staging/rt2860/rtusb_io.h b/drivers/staging/rt2860/rtusb_io.h deleted file mode 100644 index 64a2fe435284..000000000000 --- a/drivers/staging/rt2860/rtusb_io.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* -*/ - -#ifndef __RTUSB_IO_H__ -#define __RTUSB_IO_H__ - -#include "rtmp_type.h" - -/* New for MeetingHouse Api support */ -#define CMDTHREAD_VENDOR_RESET 0x0D730101 /* cmd */ -#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 /* cmd */ -#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 /* cmd */ -#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 /* cmd */ -#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 /* cmd */ -#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A /* cmd */ -#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B /* cmd */ -#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C /* cmd */ -#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D /* cmd */ -#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 /* cmd */ -#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 /* cmd */ -#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A /* cmd */ -#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D /* cmd */ -#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 /* cmd */ -#define CMDTHREAD_RESET_BULK_IN 0x0D730211 /* cmd */ -#define CMDTHREAD_SET_PSM_BIT 0x0D730212 /* cmd */ -#define CMDTHREAD_SET_RADIO 0x0D730214 /* cmd */ -#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 /* cmd */ -#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 /* cmd */ -#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A /* cmd */ -#define CMDTHREAD_LINK_DOWN 0x0D73021B /* cmd */ -#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C /* cmd */ -#define CMDTHREAD_CHECK_GPIO 0x0D730215 /* cmd */ -#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 /* cmd */ -#define CMDTHREAD_SET_BW 0x0D730225 /* cmd */ -#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 /* cmd */ -#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 /* cmd */ -#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D /* cmd */ -#define RT_CMD_SET_KEY_TABLE 0x0D730228 /* cmd */ -#define RT_CMD_SET_RX_WCID_TABLE 0x0D730229 /* cmd */ -#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E /* cmd */ -#define CMDTHREAD_SET_GROUP_KEY 0x0D73023F /* cmd */ -#define CMDTHREAD_SET_PAIRWISE_KEY 0x0D730240 /* cmd */ - -#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 /* cmd */ -#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C /* cmd */ -#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 /* cmd */ -#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 /* cmd */ -#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 /* cmd */ -/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ -#define CMDTHREAD_UPDATE_PROTECT 0x0D790103 /* cmd */ -/* end johnli */ - -/*CMDTHREAD_MULTI_READ_MAC */ -/*CMDTHREAD_MULTI_WRITE_MAC */ -/*CMDTHREAD_VENDOR_EEPROM_READ */ -/*CMDTHREAD_VENDOR_EEPROM_WRITE */ -struct rt_cmdhandler_tlv { - u16 Offset; - u16 Length; - u8 DataFirst; -}; - -struct rt_cmdqelmt; - -struct rt_cmdqelmt { - u32 command; - void *buffer; - unsigned long bufferlength; - BOOLEAN CmdFromNdis; - BOOLEAN SetOperation; - struct rt_cmdqelmt *next; -}; - -struct rt_cmdq { - u32 size; - struct rt_cmdqelmt *head; - struct rt_cmdqelmt *tail; - u32 CmdQState; -}; - -#define EnqueueCmd(cmdq, cmdqelmt) \ -{ \ - if (cmdq->size == 0) \ - cmdq->head = cmdqelmt; \ - else \ - cmdq->tail->next = cmdqelmt; \ - cmdq->tail = cmdqelmt; \ - cmdqelmt->next = NULL; \ - cmdq->size++; \ -} - -/****************************************************************************** - - USB Cmd to ASIC Related MACRO - -******************************************************************************/ -/* reset MAC of a station entry to 0xFFFFFFFFFFFF */ -#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \ - { struct rt_set_asic_wcid SetAsicWcid; \ - SetAsicWcid.WCID = Wcid; \ - SetAsicWcid.SetTid = 0xffffffff; \ - SetAsicWcid.DeleteTid = 0xffffffff; \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \ - &SetAsicWcid, sizeof(struct rt_set_asic_wcid)); } - -/* add this entry into ASIC RX WCID search table */ -#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \ - pEntry, sizeof(struct rt_mac_table_entry)); - -/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ -/* Set MAC register value according operation mode */ -#define RTMP_UPDATE_PROTECT(pAd) \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0); -/* end johnli */ - -/* remove Pair-wise key material from ASIC */ -/* yet implement */ -#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) - -/* add Client security information into ASIC WCID table and IVEIV table */ -#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \ - { RTMP_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \ - if (pEntry->Aid >= 1) { \ - struct rt_set_asic_wcid_attri SetAsicWcidAttri; \ - SetAsicWcidAttri.WCID = pEntry->Aid; \ - if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \ - (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \ - { \ - SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \ - } \ - else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \ - { \ - SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \ - } \ - else SetAsicWcidAttri.Cipher = 0; \ - DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \ - &SetAsicWcidAttri, sizeof(struct rt_set_asic_wcid_attri)); } } - -/* Insert the BA bitmap to ASIC for the Wcid entry */ -#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ - do{ \ - struct rt_set_asic_wcid SetAsicWcid; \ - SetAsicWcid.WCID = (_Aid); \ - SetAsicWcid.SetTid = (0x10000<<(_TID)); \ - SetAsicWcid.DeleteTid = 0xffffffff; \ - RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(struct rt_set_asic_wcid)); \ - }while(0) - -/* Remove the BA bitmap from ASIC for the Wcid entry */ -#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ - do{ \ - struct rt_set_asic_wcid SetAsicWcid; \ - SetAsicWcid.WCID = (_Wcid); \ - SetAsicWcid.SetTid = (0xffffffff); \ - SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \ - RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(struct rt_set_asic_wcid)); \ - }while(0) - -#endif /* __RTUSB_IO_H__ // */ diff --git a/drivers/staging/rt2860/spectrum.h b/drivers/staging/rt2860/spectrum.h deleted file mode 100644 index 4c325ba7ba21..000000000000 --- a/drivers/staging/rt2860/spectrum.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - */ - -#ifndef __SPECTRUM_H__ -#define __SPECTRUM_H__ - -#include "rtmp_type.h" -#include "spectrum_def.h" - -char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode); - -/* - ========================================================================== - Description: - Prepare Measurement request action frame and enqueue it into - management queue waiting for transmission. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd, - u8 *pOutBuffer, - unsigned long *pFrameLen, - u8 TotalLen, - u8 Category, - u8 Action, - u8 MeasureToken, - u8 MeasureReqMode, - u8 MeasureReqType, - u8 NumOfRepetitions); - -/* - ========================================================================== - Description: - Prepare Measurement report action frame and enqueue it into - management queue waiting for transmission. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd, - u8 *pDA, - u8 DialogToken, - u8 MeasureToken, - u8 MeasureReqMode, - u8 MeasureReqType, - u8 ReportInfoLen, u8 *pReportInfo); - -/* - ========================================================================== - Description: - Prepare TPC Request action frame and enqueue it into - management queue waiting for transmission. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken); - -/* - ========================================================================== - Description: - Prepare TPC Report action frame and enqueue it into - management queue waiting for transmission. - - Parametrs: - 1. the destination mac address of the frame. - - Return : None. - ========================================================================== - */ -void EnqueueTPCRep(struct rt_rtmp_adapter *pAd, - u8 *pDA, - u8 DialogToken, u8 TxPwr, u8 LinkMargin); - -/* - ========================================================================== - Description: - Prepare Channel Switch Announcement action frame and enqueue it into - management queue waiting for transmission. - - Parametrs: - 1. the destination mac address of the frame. - 2. Channel switch announcement mode. - 2. a New selected channel. - - Return : None. - ========================================================================== - */ -void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd, - u8 *pDA, u8 ChSwMode, u8 NewCh); - -/* - ========================================================================== - Description: - Spectrun action frames Handler such as channel switch announcement, - measurement report, measurement request actions frames. - - Parametrs: - Elme - MLME message containing the received frame - - Return : None. - ========================================================================== - */ -void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -/* - ========================================================================== - Description: - - Parametrs: - - Return : None. - ========================================================================== - */ -int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg); - -int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg); - -int Set_PwrConstraint(struct rt_rtmp_adapter *pAd, char *arg); - -void MeasureReqTabInit(struct rt_rtmp_adapter *pAd); - -void MeasureReqTabExit(struct rt_rtmp_adapter *pAd); - -struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken); - -struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken); - -void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken); - -void InsertChannelRepIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - char *pCountry, u8 RegulatoryClass); - -void InsertTpcReportIE(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 TxPwr, u8 LinkMargin); - -void InsertDialogToken(struct rt_rtmp_adapter *pAd, - u8 *pFrameBuf, - unsigned long *pFrameLen, u8 DialogToken); - -void TpcReqTabInit(struct rt_rtmp_adapter *pAd); - -void TpcReqTabExit(struct rt_rtmp_adapter *pAd); - -void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd, - u8 *pRA, - u8 *pTA, u8 ChSwMode, u8 Channel); - -void RguClass_BuildBcnChList(struct rt_rtmp_adapter *pAd, - u8 *pBuf, unsigned long *pBufLen); -#endif /* __SPECTRUM_H__ // */ diff --git a/drivers/staging/rt2860/spectrum_def.h b/drivers/staging/rt2860/spectrum_def.h deleted file mode 100644 index 8ffcfb0d04f8..000000000000 --- a/drivers/staging/rt2860/spectrum_def.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - spectrum_def.h - - Abstract: - Handle association related requests either from WSTA or from local MLME - - Revision History: - Who When What - --------- ---------- ---------------------------------------------- - Fonchi Wu 2008 created for 802.11h - */ - -#ifndef __SPECTRUM_DEF_H__ -#define __SPECTRUM_DEF_H__ - -#define MAX_MEASURE_REQ_TAB_SIZE 32 -#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE - -#define MAX_TPC_REQ_TAB_SIZE 32 -#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE - -#define MIN_RCV_PWR 100 /* Negative value ((dBm) */ - -#define TPC_REQ_AGE_OUT 500 /* ms */ -#define MQ_REQ_AGE_OUT 500 /* ms */ - -#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE) -#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE) - -struct rt_measure_req_entry; - -struct rt_measure_req_entry { - struct rt_measure_req_entry *pNext; - unsigned long lastTime; - BOOLEAN Valid; - u8 DialogToken; - u8 MeasureDialogToken[3]; /* 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure. */ -}; - -struct rt_measure_req_tab { - u8 Size; - struct rt_measure_req_entry *Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE]; - struct rt_measure_req_entry Content[MAX_MEASURE_REQ_TAB_SIZE]; -}; - -struct rt_tpc_req_entry; - -struct rt_tpc_req_entry { - struct rt_tpc_req_entry *pNext; - unsigned long lastTime; - BOOLEAN Valid; - u8 DialogToken; -}; - -struct rt_tpc_req_tab { - u8 Size; - struct rt_tpc_req_entry *Hash[MAX_HASH_TPC_REQ_TAB_SIZE]; - struct rt_tpc_req_entry Content[MAX_TPC_REQ_TAB_SIZE]; -}; - -/* The regulatory information */ -struct rt_dot11_channel_set { - u8 NumberOfChannels; - u8 MaxTxPwr; - u8 ChannelList[16]; -}; - -struct rt_dot11_regulatory_information { - u8 RegulatoryClass; - struct rt_dot11_channel_set ChannelSet; -}; - -#define RM_TPC_REQ 0 -#define RM_MEASURE_REQ 1 - -#define RM_BASIC 0 -#define RM_CCA 1 -#define RM_RPI_HISTOGRAM 2 -#define RM_CH_LOAD 3 -#define RM_NOISE_HISTOGRAM 4 - -struct PACKED rt_tpc_report_info { - u8 TxPwr; - u8 LinkMargin; -}; - -struct PACKED rt_ch_sw_ann_info { - u8 ChSwMode; - u8 Channel; - u8 ChSwCnt; -}; - -typedef union PACKED _MEASURE_REQ_MODE { - struct PACKED { - u8 Parallel:1; - u8 Enable:1; - u8 Request:1; - u8 Report:1; - u8 DurationMandatory:1; - u8:3; - } field; - u8 word; -} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE; - -struct PACKED rt_measure_req { - u8 ChNum; - u64 MeasureStartTime; - u16 MeasureDuration; -}; - -struct PACKED rt_measure_req_info { - u8 Token; - MEASURE_REQ_MODE ReqMode; - u8 ReqType; - u8 Oct[0]; -}; - -typedef union PACKED _MEASURE_BASIC_REPORT_MAP { - struct PACKED { - u8 BSS:1; - - u8 OfdmPreamble:1; - u8 UnidentifiedSignal:1; - u8 Radar:1; - u8 Unmeasure:1; - u8 Rev:3; - } field; - u8 word; -} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP; - -struct PACKED rt_measure_basic_report { - u8 ChNum; - u64 MeasureStartTime; - u16 MeasureDuration; - MEASURE_BASIC_REPORT_MAP Map; -}; - -struct PACKED rt_measure_cca_report { - u8 ChNum; - u64 MeasureStartTime; - u16 MeasureDuration; - u8 CCA_Busy_Fraction; -}; - -struct PACKED rt_measure_rpi_report { - u8 ChNum; - u64 MeasureStartTime; - u16 MeasureDuration; - u8 RPI_Density[8]; -}; - -typedef union PACKED _MEASURE_REPORT_MODE { - struct PACKED { - u8 Late:1; - u8 Incapable:1; - u8 Refused:1; - u8 Rev:5; - } field; - u8 word; -} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE; - -struct PACKED rt_measure_report_info { - u8 Token; - u8 ReportMode; - u8 ReportType; - u8 Octect[0]; -}; - -struct PACKED rt_quiet_info { - u8 QuietCnt; - u8 QuietPeriod; - u16 QuietDuration; - u16 QuietOffset; -}; - -#endif /* __SPECTRUM_DEF_H__ // */ diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c deleted file mode 100644 index 59e931c3190d..000000000000 --- a/drivers/staging/rt2860/sta/assoc.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - assoc.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John 2004-9-3 porting from RT2500 - Justin P. Mattock 11/07/2010 Fix typos -*/ -#include "../rt_config.h" - -u8 CipherWpaTemplate[] = { - 0xdd, /* WPA IE */ - 0x16, /* Length */ - 0x00, 0x50, 0xf2, 0x01, /* oui */ - 0x01, 0x00, /* Version */ - 0x00, 0x50, 0xf2, 0x02, /* Multicast */ - 0x01, 0x00, /* Number of unicast */ - 0x00, 0x50, 0xf2, 0x02, /* unicast */ - 0x01, 0x00, /* number of authentication method */ - 0x00, 0x50, 0xf2, 0x01 /* authentication */ -}; - -u8 CipherWpa2Template[] = { - 0x30, /* RSN IE */ - 0x14, /* Length */ - 0x01, 0x00, /* Version */ - 0x00, 0x0f, 0xac, 0x02, /* group cipher, TKIP */ - 0x01, 0x00, /* number of pairwise */ - 0x00, 0x0f, 0xac, 0x02, /* unicast */ - 0x01, 0x00, /* number of authentication method */ - 0x00, 0x0f, 0xac, 0x02, /* authentication */ - 0x00, 0x00, /* RSN capability */ -}; - -u8 Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02 }; - -/* - ========================================================================== - Description: - association state machine init, including state transition and timer init - Parameters: - S - pointer to the association state machine - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -void AssocStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, - (STATE_MACHINE_FUNC) Drop, ASSOC_IDLE, - ASSOC_MACHINE_BASE); - - /* first column */ - StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, - (STATE_MACHINE_FUNC) MlmeAssocReqAction); - StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, - (STATE_MACHINE_FUNC) MlmeReassocReqAction); - StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, - (STATE_MACHINE_FUNC) MlmeDisassocReqAction); - StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, - (STATE_MACHINE_FUNC) PeerDisassocAction); - - /* second column */ - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenAssoc); - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenReassoc); - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, - (STATE_MACHINE_FUNC) - InvalidStateWhenDisassociate); - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, - (STATE_MACHINE_FUNC) PeerDisassocAction); - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, - (STATE_MACHINE_FUNC) PeerAssocRspAction); - /* */ - /* Patch 3Com AP MOde:3CRWE454G72 */ - /* We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp. */ - /* */ - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, - (STATE_MACHINE_FUNC) PeerAssocRspAction); - StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, - (STATE_MACHINE_FUNC) AssocTimeoutAction); - - /* third column */ - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenAssoc); - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenReassoc); - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, - (STATE_MACHINE_FUNC) - InvalidStateWhenDisassociate); - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, - (STATE_MACHINE_FUNC) PeerDisassocAction); - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, - (STATE_MACHINE_FUNC) PeerReassocRspAction); - /* */ - /* Patch, AP doesn't send Reassociate Rsp frame to Station. */ - /* */ - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, - (STATE_MACHINE_FUNC) PeerReassocRspAction); - StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, - (STATE_MACHINE_FUNC) ReassocTimeoutAction); - - /* fourth column */ - StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenAssoc); - StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenReassoc); - StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, - (STATE_MACHINE_FUNC) - InvalidStateWhenDisassociate); - StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, - (STATE_MACHINE_FUNC) PeerDisassocAction); - StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, - (STATE_MACHINE_FUNC) DisassocTimeoutAction); - - /* initialize the timer */ - RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, - GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE); - RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, - GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE); - RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, - GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE); -} - -/* - ========================================================================== - Description: - Association timeout procedure. After association timeout, this function - will be called and it will put a message into the MLME queue - Parameters: - Standard timer parameters - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AssocTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL); - RTMP_MLME_HANDLER(pAd); -} - -/* - ========================================================================== - Description: - Reassociation timeout procedure. After reassociation timeout, this - function will be called and put a message into the MLME queue - Parameters: - Standard timer parameters - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void ReassocTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL); - RTMP_MLME_HANDLER(pAd); -} - -/* - ========================================================================== - Description: - Disassociation timeout procedure. After disassociation timeout, this - function will be called and put a message into the MLME queue - Parameters: - Standard timer parameters - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void DisassocTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL); - RTMP_MLME_HANDLER(pAd); -} - -/* - ========================================================================== - Description: - mlme assoc req handling procedure - Parameters: - Adapter - Adapter pointer - Elem - MLME Queue Element - Pre: - the station has been authenticated and the following information is stored in the config - -# SSID - -# supported rates and their length - -# listen interval (Adapter->StaCfg.default_listen_count) - -# Transmit power (Adapter->StaCfg.tx_power) - Post : - -# An association request frame is generated and sent to the air - -# Association timer starts - -# Association state -> ASSOC_WAIT_RSP - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 ApAddr[6]; - struct rt_header_802_11 AssocHdr; - u8 WmeIe[9] = - { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, - 0x00 }; - u16 ListenIntv; - unsigned long Timeout; - u16 CapabilityInfo; - BOOLEAN TimerCancelled; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen = 0; - unsigned long tmp; - u16 VarIesOffset; - u16 Status; - - /* Block all authentication request during WPA block period */ - if (pAd->StaCfg.bBlockAssoc == TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Block Assoc request during WPA block period!\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, - &Status); - } - /* check sanity first */ - else if (MlmeAssocReqSanity - (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, - &Timeout, &ListenIntv)) { - RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled); - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr); - - /* Get an unused nonpaged memory */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - MlmeAssocReqAction() allocate memory failed \n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_ASSOC_CONF, 2, &Status); - return; - } - /* Add by James 03/06/27 */ - pAd->StaCfg.AssocInfo.Length = - sizeof(struct rt_ndis_802_11_association_information); - /* Association don't need to report MAC address */ - pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs = - NDIS_802_11_AI_REQFI_CAPABILITIES | - NDIS_802_11_AI_REQFI_LISTENINTERVAL; - pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = - CapabilityInfo; - pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = - ListenIntv; - /* Only reassociate need this */ - /*COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr); */ - pAd->StaCfg.AssocInfo.OffsetRequestIEs = - sizeof(struct rt_ndis_802_11_association_information); - - NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN); - /* First add SSID */ - VarIesOffset = 0; - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, - 1); - VarIesOffset += 1; - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, - &pAd->MlmeAux.SsidLen, 1); - VarIesOffset += 1; - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, - pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); - VarIesOffset += pAd->MlmeAux.SsidLen; - - /* Second add Supported rates */ - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, - 1); - VarIesOffset += 1; - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, - &pAd->MlmeAux.SupRateLen, 1); - VarIesOffset += 1; - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, - pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen); - VarIesOffset += pAd->MlmeAux.SupRateLen; - /* End Add by James */ - - if ((pAd->CommonCfg.Channel > 14) && - (pAd->CommonCfg.bIEEE80211H == TRUE)) - CapabilityInfo |= 0x0100; - - DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n")); - MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, - ApAddr); - - /* Build basic frame first */ - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &AssocHdr, - 2, &CapabilityInfo, - 2, &ListenIntv, - 1, &SsidIe, - 1, &pAd->MlmeAux.SsidLen, - pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, - 1, &SupRateIe, - 1, &pAd->MlmeAux.SupRateLen, - pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, - END_OF_ARGS); - - if (pAd->MlmeAux.ExtRateLen != 0) { - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &ExtRateIe, - 1, &pAd->MlmeAux.ExtRateLen, - pAd->MlmeAux.ExtRateLen, - pAd->MlmeAux.ExtRate, END_OF_ARGS); - FrameLen += tmp; - } - /* HT */ - if ((pAd->MlmeAux.HtCapabilityLen > 0) - && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { - unsigned long TmpLen; - u8 HtLen; - u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 }; - if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) { - HtLen = SIZE_HT_CAP_IE + 4; - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 1, &WpaIe, 1, &HtLen, - 4, &BROADCOM[0], - pAd->MlmeAux.HtCapabilityLen, - &pAd->MlmeAux.HtCapability, - END_OF_ARGS); - } else { - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 1, &HtCapIe, 1, - &pAd->MlmeAux.HtCapabilityLen, - pAd->MlmeAux.HtCapabilityLen, - &pAd->MlmeAux.HtCapability, - END_OF_ARGS); - } - FrameLen += TmpLen; - } - /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */ - /* Case I: (Aggregation + Piggy-Back) */ - /* 1. user enable aggregation, AND */ - /* 2. Mac support piggy-back */ - /* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */ - /* Case II: (Aggregation) */ - /* 1. user enable aggregation, AND */ - /* 2. AP annouces it's AGGREGATION-capable in BEACON */ - if (pAd->CommonCfg.bAggregationCapable) { - if ((pAd->CommonCfg.bPiggyBackCapable) - && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) { - unsigned long TmpLen; - u8 RalinkIe[9] = - { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, - 0x03, 0x00, 0x00, 0x00 }; - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 9, RalinkIe, - END_OF_ARGS); - FrameLen += TmpLen; - } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { - unsigned long TmpLen; - u8 RalinkIe[9] = - { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, - 0x01, 0x00, 0x00, 0x00 }; - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 9, RalinkIe, - END_OF_ARGS); - FrameLen += TmpLen; - } - } else { - unsigned long TmpLen; - u8 RalinkIe[9] = - { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, - 0x00, 0x00, 0x00 }; - MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9, - RalinkIe, END_OF_ARGS); - FrameLen += TmpLen; - } - - if (pAd->MlmeAux.APEdcaParm.bValid) { - if (pAd->CommonCfg.bAPSDCapable - && pAd->MlmeAux.APEdcaParm.bAPSDCapable) { - struct rt_qbss_sta_info_parm QosInfo; - - NdisZeroMemory(&QosInfo, - sizeof(struct rt_qbss_sta_info_parm)); - QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; - QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; - QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; - QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; - QosInfo.MaxSPLength = - pAd->CommonCfg.MaxSPLength; - WmeIe[8] |= *(u8 *)& QosInfo; - } else { - /* The Parameter Set Count is set to 0 in the association request frames */ - /* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */ - } - - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 9, &WmeIe[0], END_OF_ARGS); - FrameLen += tmp; - } - /* */ - /* Let WPA(#221) Element ID on the end of this association frame. */ - /* Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp. */ - /* For example: Put Vendor Specific IE on the front of WPA IE. */ - /* This happens on AP (Model No:Linksys WRK54G) */ - /* */ - if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) - ) - ) { - u8 RSNIe = IE_WPA; - - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2)) { - RSNIe = IE_WPA2; - } - - if ((pAd->StaCfg.WpaSupplicantUP != - WPA_SUPPLICANT_ENABLE) - && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE)) - RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, - pAd->StaCfg.WepStatus, BSS0); - - /* Check for WPA PMK cache list */ - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) { - int idx; - BOOLEAN FoundPMK = FALSE; - /* Search chched PMKID, append it if existed */ - for (idx = 0; idx < PMKID_NO; idx++) { - if (NdisEqualMemory - (ApAddr, - &pAd->StaCfg.SavedPMK[idx].BSSID, - 6)) { - FoundPMK = TRUE; - break; - } - } - if (FoundPMK) { - /* Set PMK number */ - *(u16 *)& pAd->StaCfg.RSN_IE[pAd-> - StaCfg. - RSNIE_Len] - = 1; - NdisMoveMemory(&pAd->StaCfg. - RSN_IE[pAd->StaCfg. - RSNIE_Len + 2], - &pAd->StaCfg. - SavedPMK[idx].PMKID, 16); - pAd->StaCfg.RSNIE_Len += 18; - } - } - - if ((pAd->StaCfg.WpaSupplicantUP == - WPA_SUPPLICANT_ENABLE) - && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == - TRUE)) { - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - pAd->StaCfg.RSNIE_Len, - pAd->StaCfg.RSN_IE, - END_OF_ARGS); - } else { - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &RSNIe, - 1, &pAd->StaCfg.RSNIE_Len, - pAd->StaCfg.RSNIE_Len, - pAd->StaCfg.RSN_IE, - END_OF_ARGS); - } - - FrameLen += tmp; - - if ((pAd->StaCfg.WpaSupplicantUP != - WPA_SUPPLICANT_ENABLE) - || (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == - FALSE)) { - /* Append Variable IE */ - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + - VarIesOffset, &RSNIe, 1); - VarIesOffset += 1; - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + - VarIesOffset, - &pAd->StaCfg.RSNIE_Len, 1); - VarIesOffset += 1; - } - NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, - pAd->StaCfg.RSN_IE, - pAd->StaCfg.RSNIE_Len); - VarIesOffset += pAd->StaCfg.RSNIE_Len; - - /* Set Variable IEs Length */ - pAd->StaCfg.ReqVarIELen = VarIesOffset; - } - - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout); - pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_INVALID_FORMAT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, - &Status); - } - -} - -/* - ========================================================================== - Description: - mlme reassoc req handling procedure - Parameters: - Elem - - Pre: - -# SSID (Adapter->StaCfg.ssid[]) - -# BSSID (AP address, Adapter->StaCfg.bssid) - -# Supported rates (Adapter->StaCfg.supported_rates[]) - -# Supported rates length (Adapter->StaCfg.supported_rates_len) - -# Tx power (Adapter->StaCfg.tx_power) - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 ApAddr[6]; - struct rt_header_802_11 ReassocHdr; - u8 WmeIe[9] = - { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, - 0x00 }; - u16 CapabilityInfo, ListenIntv; - unsigned long Timeout; - unsigned long FrameLen = 0; - BOOLEAN TimerCancelled; - int NStatus; - unsigned long tmp; - u8 *pOutBuffer = NULL; - u16 Status; - - /* Block all authentication request during WPA block period */ - if (pAd->StaCfg.bBlockAssoc == TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Block ReAssoc request during WPA block period!\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, - &Status); - } - /* the parameters are the same as the association */ - else if (MlmeAssocReqSanity - (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, - &Timeout, &ListenIntv)) { - RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled); - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - MlmeReassocReqAction() allocate memory failed \n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_REASSOC_CONF, 2, &Status); - return; - } - - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr); - - /* make frame, use bssid as the AP address?? */ - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Send RE-ASSOC request...\n")); - MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, - ApAddr, ApAddr); - MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11), - &ReassocHdr, 2, &CapabilityInfo, 2, - &ListenIntv, MAC_ADDR_LEN, ApAddr, 1, &SsidIe, - 1, &pAd->MlmeAux.SsidLen, - pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1, - &SupRateIe, 1, &pAd->MlmeAux.SupRateLen, - pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, - END_OF_ARGS); - - if (pAd->MlmeAux.ExtRateLen != 0) { - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &ExtRateIe, - 1, &pAd->MlmeAux.ExtRateLen, - pAd->MlmeAux.ExtRateLen, - pAd->MlmeAux.ExtRate, END_OF_ARGS); - FrameLen += tmp; - } - - if (pAd->MlmeAux.APEdcaParm.bValid) { - if (pAd->CommonCfg.bAPSDCapable - && pAd->MlmeAux.APEdcaParm.bAPSDCapable) { - struct rt_qbss_sta_info_parm QosInfo; - - NdisZeroMemory(&QosInfo, - sizeof(struct rt_qbss_sta_info_parm)); - QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; - QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; - QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; - QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; - QosInfo.MaxSPLength = - pAd->CommonCfg.MaxSPLength; - WmeIe[8] |= *(u8 *)& QosInfo; - } - - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 9, &WmeIe[0], END_OF_ARGS); - FrameLen += tmp; - } - /* HT */ - if ((pAd->MlmeAux.HtCapabilityLen > 0) - && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { - unsigned long TmpLen; - u8 HtLen; - u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 }; - if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) { - HtLen = SIZE_HT_CAP_IE + 4; - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 1, &WpaIe, 1, &HtLen, - 4, &BROADCOM[0], - pAd->MlmeAux.HtCapabilityLen, - &pAd->MlmeAux.HtCapability, - END_OF_ARGS); - } else { - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 1, &HtCapIe, 1, - &pAd->MlmeAux.HtCapabilityLen, - pAd->MlmeAux.HtCapabilityLen, - &pAd->MlmeAux.HtCapability, - END_OF_ARGS); - } - FrameLen += TmpLen; - } - /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */ - /* Case I: (Aggregation + Piggy-Back) */ - /* 1. user enable aggregation, AND */ - /* 2. Mac support piggy-back */ - /* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */ - /* Case II: (Aggregation) */ - /* 1. user enable aggregation, AND */ - /* 2. AP annouces it's AGGREGATION-capable in BEACON */ - if (pAd->CommonCfg.bAggregationCapable) { - if ((pAd->CommonCfg.bPiggyBackCapable) - && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) { - unsigned long TmpLen; - u8 RalinkIe[9] = - { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, - 0x03, 0x00, 0x00, 0x00 }; - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 9, RalinkIe, - END_OF_ARGS); - FrameLen += TmpLen; - } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { - unsigned long TmpLen; - u8 RalinkIe[9] = - { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, - 0x01, 0x00, 0x00, 0x00 }; - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 9, RalinkIe, - END_OF_ARGS); - FrameLen += TmpLen; - } - } else { - unsigned long TmpLen; - u8 RalinkIe[9] = - { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, - 0x00, 0x00, 0x00 }; - MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9, - RalinkIe, END_OF_ARGS); - FrameLen += TmpLen; - } - - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */ - pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP; - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_INVALID_FORMAT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, - &Status); - } -} - -/* - ========================================================================== - Description: - Upper layer issues disassoc request - Parameters: - Elem - - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -void MlmeDisassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_disassoc_req *pDisassocReq; - struct rt_header_802_11 DisassocHdr; - struct rt_header_802_11 * pDisassocHdr; - u8 *pOutBuffer = NULL; - unsigned long FrameLen = 0; - int NStatus; - BOOLEAN TimerCancelled; - unsigned long Timeout = 500; - u16 Status; - - /* skip sanity check */ - pDisassocReq = (struct rt_mlme_disassoc_req *)(Elem->Msg); - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, - &Status); - return; - } - - RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled); - - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Send DISASSOC request[BSSID::%pM (Reason=%d)\n", - pDisassocReq->Addr, pDisassocReq->Reason)); - MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr); /* patch peap ttls switching issue */ - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &DisassocHdr, - 2, &pDisassocReq->Reason, END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - - /* To patch Instance and Buffalo(N) AP */ - /* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */ - /* Therefore, we send both of them. */ - pDisassocHdr = (struct rt_header_802_11 *) pOutBuffer; - pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH; - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - - MlmeFreeMemory(pAd, pOutBuffer); - - pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING; - COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr); - - RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */ - pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP; - - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); - -} - -/* - ========================================================================== - Description: - peer sends assoc rsp back - Parameters: - Elme - MLME message containing the received frame - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void PeerAssocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 CapabilityInfo, Status, Aid; - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen; - u8 Addr2[MAC_ADDR_LEN]; - BOOLEAN TimerCancelled; - u8 CkipFlag; - struct rt_edca_parm EdcaParm; - struct rt_ht_capability_ie HtCapability; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 HtCapabilityLen = 0; - u8 AddHtInfoLen; - u8 NewExtChannelOffset = 0xff; - - if (PeerAssocRspSanity - (pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, - &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability, - &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, &NewExtChannelOffset, - &EdcaParm, &CkipFlag)) { - /* The frame is for me ? */ - if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", - Status)); - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n", - Elem->Wcid, - pAd->MacTab.Content[BSSID_WCID].AMsduSize, - pAd->MacTab.Content[BSSID_WCID]. - ClientStatusFlags)); - RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, - &TimerCancelled); - - if (Status == MLME_SUCCESS) { - u8 MaxSupportedRateIn500Kbps = 0; - u8 idx; - - /* supported rates array may not be sorted. sort it and find the maximum rate */ - for (idx = 0; idx < SupRateLen; idx++) { - if (MaxSupportedRateIn500Kbps < - (SupRate[idx] & 0x7f)) - MaxSupportedRateIn500Kbps = - SupRate[idx] & 0x7f; - } - - for (idx = 0; idx < ExtRateLen; idx++) { - if (MaxSupportedRateIn500Kbps < - (ExtRate[idx] & 0x7f)) - MaxSupportedRateIn500Kbps = - ExtRate[idx] & 0x7f; - } - /* go to procedure listed on page 376 */ - AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, - SupRate, SupRateLen, ExtRate, - ExtRateLen, &EdcaParm, - &HtCapability, HtCapabilityLen, - &AddHtInfo); - - StaAddMacTableEntry(pAd, - &pAd->MacTab. - Content[BSSID_WCID], - MaxSupportedRateIn500Kbps, - &HtCapability, - HtCapabilityLen, &AddHtInfo, - AddHtInfoLen, - CapabilityInfo); - } - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_ASSOC_CONF, 2, &Status); - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - PeerAssocRspAction() sanity check fail\n")); - } -} - -/* - ========================================================================== - Description: - peer sends reassoc rsp - Parametrs: - Elem - MLME message cntaining the received frame - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void PeerReassocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 CapabilityInfo; - u16 Status; - u16 Aid; - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen; - u8 Addr2[MAC_ADDR_LEN]; - u8 CkipFlag; - BOOLEAN TimerCancelled; - struct rt_edca_parm EdcaParm; - struct rt_ht_capability_ie HtCapability; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 HtCapabilityLen; - u8 AddHtInfoLen; - u8 NewExtChannelOffset = 0xff; - - if (PeerAssocRspSanity - (pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, - &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability, - &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, &NewExtChannelOffset, - &EdcaParm, &CkipFlag)) { - if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) /* The frame is for me ? */ - { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", - Status)); - RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, - &TimerCancelled); - - if (Status == MLME_SUCCESS) { - /* go to procedure listed on page 376 */ - AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, - SupRate, SupRateLen, ExtRate, - ExtRateLen, &EdcaParm, - &HtCapability, HtCapabilityLen, - &AddHtInfo); - - { - wext_notify_event_assoc(pAd); - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, - -1, - &pAd->MlmeAux. - Bssid[0], NULL, - 0); - } - - } - /* CkipFlag is no use for reassociate */ - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_REASSOC_CONF, 2, &Status); - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - PeerReassocRspAction() sanity check fail\n")); - } - -} - -/* - ========================================================================== - Description: - procedures on IEEE 802.11/1999 p.376 - Parametrs: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AssocPostProc(struct rt_rtmp_adapter *pAd, u8 *pAddr2, u16 CapabilityInfo, u16 Aid, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_edca_parm *pEdcaParm, struct rt_ht_capability_ie * pHtCapability, u8 HtCapabilityLen, struct rt_add_ht_info_ie * pAddHtInfo) /* AP might use this additional ht info IE */ -{ - unsigned long Idx; - - pAd->MlmeAux.BssType = BSS_INFRA; - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2); - pAd->MlmeAux.Aid = Aid; - pAd->MlmeAux.CapabilityInfo = - CapabilityInfo & SUPPORTED_CAPABILITY_INFO; - - /* Some HT AP might lost WMM IE. We add WMM ourselves. because HT requires QoS on. */ - if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE)) { - pEdcaParm->bValid = TRUE; - pEdcaParm->Aifsn[0] = 3; - pEdcaParm->Aifsn[1] = 7; - pEdcaParm->Aifsn[2] = 2; - pEdcaParm->Aifsn[3] = 2; - - pEdcaParm->Cwmin[0] = 4; - pEdcaParm->Cwmin[1] = 4; - pEdcaParm->Cwmin[2] = 3; - pEdcaParm->Cwmin[3] = 2; - - pEdcaParm->Cwmax[0] = 10; - pEdcaParm->Cwmax[1] = 10; - pEdcaParm->Cwmax[2] = 4; - pEdcaParm->Cwmax[3] = 3; - - pEdcaParm->Txop[0] = 0; - pEdcaParm->Txop[1] = 0; - pEdcaParm->Txop[2] = 96; - pEdcaParm->Txop[3] = 48; - - } - - NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(struct rt_edca_parm)); - - /* filter out un-supported rates */ - pAd->MlmeAux.SupRateLen = SupRateLen; - NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); - RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); - - /* filter out un-supported rates */ - pAd->MlmeAux.ExtRateLen = ExtRateLen; - NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); - RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); - - if (HtCapabilityLen > 0) { - RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo); - } - DBGPRINT(RT_DEBUG_TRACE, - ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", - pAd->MacTab.Content[BSSID_WCID].AMsduSize, - pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); - - DBGPRINT(RT_DEBUG_TRACE, - ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n", - pAd->MacTab.Content[BSSID_WCID].MmpsMode, - pAd->MacTab.Content[BSSID_WCID].AMsduSize)); - - /* Set New WPA information */ - Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel); - if (Idx == BSS_NOT_FOUND) { - DBGPRINT_ERR("ASSOC - Can't find BSS after receiving Assoc response\n"); - } else { - /* Init variable */ - pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0; - NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, - MAX_LEN_OF_RSNIE); - - /* Store appropriate RSN_IE for WPA SM negotiation later */ - if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) - && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0)) { - u8 *pVIE; - u16 len; - struct rt_eid * pEid; - - pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs; - len = pAd->ScanTab.BssEntry[Idx].VarIELen; - /*KH need to check again */ - /* Don't allow to go to sleep mode if authmode is WPA-related. */ - /*This can make Authentication process more smoothly. */ - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - - while (len > 0) { - pEid = (struct rt_eid *) pVIE; - /* For WPA/WPAPSK */ - if ((pEid->Eid == IE_WPA) - && - (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) - && (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA - || pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPAPSK)) { - NdisMoveMemory(pAd->MacTab. - Content[BSSID_WCID]. - RSN_IE, pVIE, - (pEid->Len + 2)); - pAd->MacTab.Content[BSSID_WCID]. - RSNIE_Len = (pEid->Len + 2); - DBGPRINT(RT_DEBUG_TRACE, - ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n")); - } - /* For WPA2/WPA2PSK */ - else if ((pEid->Eid == IE_RSN) - && - (NdisEqualMemory - (pEid->Octet + 2, RSN_OUI, 3)) - && (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2 - || pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2PSK)) { - NdisMoveMemory(pAd->MacTab. - Content[BSSID_WCID]. - RSN_IE, pVIE, - (pEid->Len + 2)); - pAd->MacTab.Content[BSSID_WCID]. - RSNIE_Len = (pEid->Len + 2); - DBGPRINT(RT_DEBUG_TRACE, - ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n")); - } - - pVIE += (pEid->Len + 2); - len -= (pEid->Len + 2); - } - - } - - if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0) { - DBGPRINT(RT_DEBUG_TRACE, - ("AssocPostProc===> no RSN_IE \n")); - } else { - hex_dump("RSN_IE", - pAd->MacTab.Content[BSSID_WCID].RSN_IE, - pAd->MacTab.Content[BSSID_WCID].RSNIE_Len); - } - } -} - -/* - ========================================================================== - Description: - left part of IEEE 802.11/1999 p.374 - Parameters: - Elem - MLME message containing the received frame - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void PeerDisassocAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Addr2[MAC_ADDR_LEN]; - u16 Reason; - - DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n")); - if (PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - PeerDisassocAction() Reason = %d\n", - Reason)); - if (INFRA_ON(pAd) - && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2)) { - - if (pAd->CommonCfg.bWirelessEvent) { - RTMPSendWirelessEvent(pAd, - IW_DISASSOC_EVENT_FLAG, - pAd->MacTab. - Content[BSSID_WCID].Addr, - BSS0, 0); - } - - LinkDown(pAd, TRUE); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, - 0); - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - PeerDisassocAction() sanity check fail\n")); - } - -} - -/* - ========================================================================== - Description: - what the state machine will do after assoc timeout - Parameters: - Elme - - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AssocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_REJ_TIMEOUT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - what the state machine will do after reassoc timeout - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void ReassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_REJ_TIMEOUT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - what the state machine will do after disassoc timeout - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void DisassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n")); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_SUCCESS; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, - &Status); -} - -void InvalidStateWhenAssoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n", - pAd->Mlme.AssocMachine.CurrState)); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status); -} - -void InvalidStateWhenReassoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n", - pAd->Mlme.AssocMachine.CurrState)); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status); -} - -void InvalidStateWhenDisassociate(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n", - pAd->Mlme.AssocMachine.CurrState)); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, - &Status); -} - -/* - ========================================================================== - Description: - right part of IEEE 802.11/1999 page 374 - Note: - This event should never cause ASSOC state machine perform state - transition, and has no relationship with CNTL machine. So we separate - this routine as a service outside of ASSOC state transition table. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void Cls3errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr) -{ - struct rt_header_802_11 DisassocHdr; - struct rt_header_802_11 * pDisassocHdr; - u8 *pOutBuffer = NULL; - unsigned long FrameLen = 0; - int NStatus; - u16 Reason = REASON_CLS3ERR; - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Class 3 Error, Send DISASSOC frame\n")); - MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid); /* patch peap ttls switching issue */ - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &DisassocHdr, - 2, &Reason, END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - - /* To patch Instance and Buffalo(N) AP */ - /* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */ - /* Therefore, we send both of them. */ - pDisassocHdr = (struct rt_header_802_11 *) pOutBuffer; - pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH; - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - - MlmeFreeMemory(pAd, pOutBuffer); - - pAd->StaCfg.DisassocReason = REASON_CLS3ERR; - COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr); -} - -int wext_notify_event_assoc(struct rt_rtmp_adapter *pAd) -{ - char custom[IW_CUSTOM_MAX] = { 0 }; - - if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX) { - NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs, - pAd->StaCfg.ReqVarIELen); - RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom, - pAd->StaCfg.ReqVarIELen); - } else - DBGPRINT(RT_DEBUG_TRACE, - ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n")); - - return 0; - -} - -BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 MaxSupportedRateIn500Kbps, - struct rt_ht_capability_ie * pHtCapability, - u8 HtCapabilityLen, - struct rt_add_ht_info_ie * pAddHtInfo, - u8 AddHtInfoLen, u16 CapabilityInfo) -{ - u8 MaxSupportedRate = RATE_11; - - if (ADHOC_ON(pAd)) - CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); - - switch (MaxSupportedRateIn500Kbps) { - case 108: - MaxSupportedRate = RATE_54; - break; - case 96: - MaxSupportedRate = RATE_48; - break; - case 72: - MaxSupportedRate = RATE_36; - break; - case 48: - MaxSupportedRate = RATE_24; - break; - case 36: - MaxSupportedRate = RATE_18; - break; - case 24: - MaxSupportedRate = RATE_12; - break; - case 18: - MaxSupportedRate = RATE_9; - break; - case 12: - MaxSupportedRate = RATE_6; - break; - case 22: - MaxSupportedRate = RATE_11; - break; - case 11: - MaxSupportedRate = RATE_5_5; - break; - case 4: - MaxSupportedRate = RATE_2; - break; - case 2: - MaxSupportedRate = RATE_1; - break; - default: - MaxSupportedRate = RATE_11; - break; - } - - if ((pAd->CommonCfg.PhyMode == PHY_11G) - && (MaxSupportedRate < RATE_FIRST_OFDM_RATE)) - return FALSE; - - /* 11n only */ - if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) - || (pAd->CommonCfg.PhyMode == PHY_11N_5G)) - && (HtCapabilityLen == 0)) - return FALSE; - - if (!pEntry) - return FALSE; - - NdisAcquireSpinLock(&pAd->MacTabLock); - if (pEntry) { - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) || - (pAd->CommonCfg.PhyMode == PHY_11B)) { - pEntry->RateLen = 4; - if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE) - MaxSupportedRate = RATE_11; - } else - pEntry->RateLen = 12; - - pEntry->MaxHTPhyMode.word = 0; - pEntry->MinHTPhyMode.word = 0; - pEntry->HTPhyMode.word = 0; - pEntry->MaxSupportedRate = MaxSupportedRate; - if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) { - pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; - pEntry->MaxHTPhyMode.field.MCS = - pEntry->MaxSupportedRate; - pEntry->MinHTPhyMode.field.MODE = MODE_CCK; - pEntry->MinHTPhyMode.field.MCS = - pEntry->MaxSupportedRate; - pEntry->HTPhyMode.field.MODE = MODE_CCK; - pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate; - } else { - pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; - pEntry->MaxHTPhyMode.field.MCS = - OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; - pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; - pEntry->MinHTPhyMode.field.MCS = - OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; - pEntry->HTPhyMode.field.MODE = MODE_OFDM; - pEntry->HTPhyMode.field.MCS = - OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; - } - pEntry->CapabilityInfo = CapabilityInfo; - CLIENT_STATUS_CLEAR_FLAG(pEntry, - fCLIENT_STATUS_AGGREGATION_CAPABLE); - CLIENT_STATUS_CLEAR_FLAG(pEntry, - fCLIENT_STATUS_PIGGYBACK_CAPABLE); - } - - NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability)); - /* If this Entry supports 802.11n, upgrade to HT rate. */ - if ((HtCapabilityLen != 0) - && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { - u8 j, bitmask; /*k,bitmask; */ - char i; - - if (ADHOC_ON(pAd)) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_WMM_CAPABLE); - if ((pHtCapability->HtCapInfo.GF) - && (pAd->CommonCfg.DesiredHtPhy.GF)) { - pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; - } else { - pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; - pAd->MacTab.fAnyStationNonGF = TRUE; - pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; - } - - if ((pHtCapability->HtCapInfo.ChannelWidth) && - (pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && - ((pAd->StaCfg.BssType == BSS_INFRA) - || ((pAd->StaCfg.BssType == BSS_ADHOC) - && (pAddHtInfo->AddHtInfo.ExtChanOffset == - pAd->CommonCfg.AddHTInfo.AddHtInfo. - ExtChanOffset)))) { - pEntry->MaxHTPhyMode.field.BW = BW_40; - pEntry->MaxHTPhyMode.field.ShortGI = - ((pAd->CommonCfg.DesiredHtPhy. - ShortGIfor40) & (pHtCapability->HtCapInfo. - ShortGIfor40)); - } else { - pEntry->MaxHTPhyMode.field.BW = BW_20; - pEntry->MaxHTPhyMode.field.ShortGI = - ((pAd->CommonCfg.DesiredHtPhy. - ShortGIfor20) & (pHtCapability->HtCapInfo. - ShortGIfor20)); - pAd->MacTab.fAnyStation20Only = TRUE; - } - - /* 3*3 */ - if (pAd->MACVersion >= RALINK_2883_VERSION - && pAd->MACVersion < RALINK_3070_VERSION) - pEntry->MaxHTPhyMode.field.TxBF = - pAd->CommonCfg.RegTransmitSetting.field.TxBF; - - /* find max fixed rate */ - for (i = 23; i >= 0; i--) /* 3*3 */ - { - j = i / 8; - bitmask = (1 << (i - (j * 8))); - if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) - && (pHtCapability->MCSSet[j] & bitmask)) { - pEntry->MaxHTPhyMode.field.MCS = i; - break; - } - if (i == 0) - break; - } - - if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) { - if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) { - /* Fix MCS as HT Duplicated Mode */ - pEntry->MaxHTPhyMode.field.BW = 1; - pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; - pEntry->MaxHTPhyMode.field.STBC = 0; - pEntry->MaxHTPhyMode.field.ShortGI = 0; - pEntry->MaxHTPhyMode.field.MCS = 32; - } else if (pEntry->MaxHTPhyMode.field.MCS > - pAd->StaCfg.HTPhyMode.field.MCS) { - /* STA supports fixed MCS */ - pEntry->MaxHTPhyMode.field.MCS = - pAd->StaCfg.HTPhyMode.field.MCS; - } - } - - pEntry->MaxHTPhyMode.field.STBC = - (pHtCapability->HtCapInfo. - RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); - pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity; - pEntry->MaxRAmpduFactor = - pHtCapability->HtCapParm.MaxRAmpduFactor; - pEntry->MmpsMode = (u8)pHtCapability->HtCapInfo.MimoPs; - pEntry->AMsduSize = (u8)pHtCapability->HtCapInfo.AMsduSize; - pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; - - if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable - && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE)) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_AMSDU_INUSED); - if (pHtCapability->HtCapInfo.ShortGIfor20) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_SGI20_CAPABLE); - if (pHtCapability->HtCapInfo.ShortGIfor40) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_SGI40_CAPABLE); - if (pHtCapability->HtCapInfo.TxSTBC) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_TxSTBC_CAPABLE); - if (pHtCapability->HtCapInfo.RxSTBC) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_RxSTBC_CAPABLE); - if (pHtCapability->ExtHtCapInfo.PlusHTC) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_HTC_CAPABLE); - if (pAd->CommonCfg.bRdg - && pHtCapability->ExtHtCapInfo.RDGSupport) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_RDG_CAPABLE); - if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03) - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); - NdisMoveMemory(&pEntry->HTCapability, pHtCapability, - HtCapabilityLen); - } else { - pAd->MacTab.fAnyStationIsLegacy = TRUE; - } - - pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; - pEntry->CurrTxRate = pEntry->MaxSupportedRate; - - /* Set asic auto fall back */ - if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) { - u8 *pTable; - u8 TableSize = 0; - - MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, - &pEntry->CurrTxRateIndex); - pEntry->bAutoTxRateSwitch = TRUE; - } else { - pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - pEntry->bAutoTxRateSwitch = FALSE; - - /* If the legacy mode is set, overwrite the transmit setting of this entry. */ - RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg. - DesiredTransmitSetting.field. - FixedTxMode, pEntry); - } - - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - pEntry->Sst = SST_ASSOC; - pEntry->AuthState = AS_AUTH_OPEN; - pEntry->AuthMode = pAd->StaCfg.AuthMode; - pEntry->WepStatus = pAd->StaCfg.WepStatus; - - NdisReleaseSpinLock(&pAd->MacTabLock); - - { - union iwreq_data wrqu; - wext_notify_event_assoc(pAd); - - memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - - } - return TRUE; -} diff --git a/drivers/staging/rt2860/sta/auth.c b/drivers/staging/rt2860/sta/auth.c deleted file mode 100644 index 23ea00b896b0..000000000000 --- a/drivers/staging/rt2860/sta/auth.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - auth.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John 2004-9-3 porting from RT2500 - Justin P. Mattock 11/07/2010 Fix typos -*/ -#include "../rt_config.h" - -/* - ========================================================================== - Description: - authenticate state machine init, including state transition and timer init - Parameters: - Sm - pointer to the auth state machine - Note: - The state machine looks like this - - AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4 - MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth - MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action - MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ - -void AuthStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, - (STATE_MACHINE_FUNC) Drop, AUTH_REQ_IDLE, - AUTH_MACHINE_BASE); - - /* the first column */ - StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, - (STATE_MACHINE_FUNC) MlmeAuthReqAction); - - /* the second column */ - StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenAuth); - StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, - (STATE_MACHINE_FUNC) PeerAuthRspAtSeq2Action); - StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, - (STATE_MACHINE_FUNC) AuthTimeoutAction); - - /* the third column */ - StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenAuth); - StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, - (STATE_MACHINE_FUNC) PeerAuthRspAtSeq4Action); - StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, - (STATE_MACHINE_FUNC) AuthTimeoutAction); - - RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, - GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE); -} - -/* - ========================================================================== - Description: - function to be executed at timer thread when auth timer expires - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AuthTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeout\n")); - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - /* send a de-auth to reset AP's state machine (Patch AP-Dir635) */ - if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2) - Cls2errAction(pAd, pAd->MlmeAux.Bssid); - - MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL); - RTMP_MLME_HANDLER(pAd); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - if (AUTH_ReqSend - (pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0)) - pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2; - else { - u16 Status; - - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_INVALID_FORMAT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, - &Status); - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Addr2[MAC_ADDR_LEN]; - u16 Seq, Status, RemoteStatus, Alg; - u8 ChlgText[CIPHER_TEXT_LEN]; - u8 CyperChlgText[CIPHER_TEXT_LEN + 8 + 8]; - u8 Element[2]; - struct rt_header_802_11 AuthHdr; - BOOLEAN TimerCancelled; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen = 0; - u16 Status2; - - if (PeerAuthSanity - (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, - (char *)ChlgText)) { - if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", - Alg, Status)); - RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, - &TimerCancelled); - - if (Status == MLME_SUCCESS) { - /* Authentication Mode "LEAP" has allow for CCX 1.X */ - if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) { - pAd->Mlme.AuthMachine.CurrState = - AUTH_REQ_IDLE; - MlmeEnqueue(pAd, - MLME_CNTL_STATE_MACHINE, - MT2_AUTH_CONF, 2, &Status); - } else { - /* 2. shared key, need to be challenged */ - Seq++; - RemoteStatus = MLME_SUCCESS; - - /* Get an unused nonpaged memory */ - NStatus = - MlmeAllocateMemory(pAd, - &pOutBuffer); - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n")); - pAd->Mlme.AuthMachine. - CurrState = AUTH_REQ_IDLE; - Status2 = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, - MLME_CNTL_STATE_MACHINE, - MT2_AUTH_CONF, 2, - &Status2); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - Send AUTH request seq#3...\n")); - MgtMacHeaderInit(pAd, &AuthHdr, - SUBTYPE_AUTH, 0, Addr2, - pAd->MlmeAux.Bssid); - AuthHdr.FC.Wep = 1; - /* Encrypt challenge text & auth information */ - RTMPInitWepEngine(pAd, - pAd-> - SharedKey[BSS0][pAd-> - StaCfg. - DefaultKeyId]. - Key, - pAd->StaCfg. - DefaultKeyId, - pAd-> - SharedKey[BSS0][pAd-> - StaCfg. - DefaultKeyId]. - KeyLen, - CyperChlgText); - - Alg = cpu2le16(*(u16 *) & Alg); - Seq = cpu2le16(*(u16 *) & Seq); - RemoteStatus = - cpu2le16(*(u16 *) & - RemoteStatus); - - RTMPEncryptData(pAd, (u8 *)& Alg, - CyperChlgText + 4, 2); - RTMPEncryptData(pAd, (u8 *)& Seq, - CyperChlgText + 6, 2); - RTMPEncryptData(pAd, - (u8 *)& RemoteStatus, - CyperChlgText + 8, 2); - Element[0] = 16; - Element[1] = 128; - RTMPEncryptData(pAd, Element, - CyperChlgText + 10, 2); - RTMPEncryptData(pAd, ChlgText, - CyperChlgText + 12, - 128); - RTMPSetICV(pAd, CyperChlgText + 140); - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), - &AuthHdr, - CIPHER_TEXT_LEN + 16, - CyperChlgText, - END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, - FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - RTMPSetTimer(&pAd->MlmeAux.AuthTimer, - AUTH_TIMEOUT); - pAd->Mlme.AuthMachine.CurrState = - AUTH_WAIT_SEQ4; - } - } else { - pAd->StaCfg.AuthFailReason = Status; - COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, - MT2_AUTH_CONF, 2, &Status); - } - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - PeerAuthSanity() sanity check fail\n")); - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Addr2[MAC_ADDR_LEN]; - u16 Alg, Seq, Status; - char ChlgText[CIPHER_TEXT_LEN]; - BOOLEAN TimerCancelled; - - if (PeerAuthSanity - (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, - ChlgText)) { - if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4) { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - Receive AUTH_RSP seq#4 to me\n")); - RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, - &TimerCancelled); - - if (Status != MLME_SUCCESS) { - pAd->StaCfg.AuthFailReason = Status; - COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); - } - - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, - 2, &Status); - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n")); - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_deauth_req *pInfo; - struct rt_header_802_11 DeauthHdr; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen = 0; - u16 Status; - - pInfo = (struct rt_mlme_deauth_req *)Elem->Msg; - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - MlmeDeauthReqAction() allocate memory fail\n")); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, - &Status); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - Send DE-AUTH request (Reason=%d)...\n", - pInfo->Reason)); - MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, - pAd->MlmeAux.Bssid); - MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11), - &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - pAd->StaCfg.DeauthReason = pInfo->Reason; - COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_SUCCESS; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status); - - /* send wireless event - for deauthentication */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID].Addr, - BSS0, 0); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n")); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_REJ_TIMEOUT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", - pAd->Mlme.AuthMachine.CurrState)); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - Some STA/AP - Note: - This action should never trigger AUTH state transition, therefore we - separate it from AUTH state machine, and make it as a standalone service - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr) -{ - struct rt_header_802_11 DeauthHdr; - u8 *pOutBuffer = NULL; - int NStatus; - unsigned long FrameLen = 0; - u16 Reason = REASON_CLS2ERR; - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH - Class 2 error, Send DEAUTH frame...\n")); - MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, - pAd->MlmeAux.Bssid); - MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11), - &DeauthHdr, 2, &Reason, END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - pAd->StaCfg.DeauthReason = Reason; - COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr); -} - -BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *pElem, - struct rt_ralink_timer *pAuthTimer, - char *pSMName, - u16 SeqNo, - u8 *pNewElement, unsigned long ElementLen) -{ - u16 Alg, Seq, Status; - u8 Addr[6]; - unsigned long Timeout; - struct rt_header_802_11 AuthHdr; - BOOLEAN TimerCancelled; - int NStatus; - u8 *pOutBuffer = NULL; - unsigned long FrameLen = 0, tmp = 0; - - /* Block all authentication request during WPA block period */ - if (pAd->StaCfg.bBlockAssoc == TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s - Block Auth request during WPA block period!\n", - pSMName)); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, - &Status); - } else - if (MlmeAuthReqSanity - (pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg)) { - /* reset timer */ - RTMPCancelTimer(pAuthTimer, &TimerCancelled); - - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr); - pAd->MlmeAux.Alg = Alg; - Seq = SeqNo; - Status = MLME_SUCCESS; - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", - pSMName, Alg)); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, - 2, &Status); - return FALSE; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName, - Alg)); - MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, - pAd->MlmeAux.Bssid); - MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11), - &AuthHdr, 2, &Alg, 2, &Seq, 2, &Status, - END_OF_ARGS); - - if (pNewElement && ElementLen) { - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - ElementLen, pNewElement, END_OF_ARGS); - FrameLen += tmp; - } - - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - RTMPSetTimer(pAuthTimer, Timeout); - return TRUE; - } else { - DBGPRINT_ERR("%s - MlmeAuthReqAction() sanity check failed\n", pSMName); - return FALSE; - } - - return TRUE; -} diff --git a/drivers/staging/rt2860/sta/auth_rsp.c b/drivers/staging/rt2860/sta/auth_rsp.c deleted file mode 100644 index 5b018b757308..000000000000 --- a/drivers/staging/rt2860/sta/auth_rsp.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - auth_rsp.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John 2004-10-1 copy from RT2560 -*/ -#include "../rt_config.h" - -/* - ========================================================================== - Description: - authentication state machine init procedure - Parameters: - Sm - the state machine - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, - IN STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, - (STATE_MACHINE_FUNC) Drop, AUTH_RSP_IDLE, - AUTH_RSP_MACHINE_BASE); - - /* column 1 */ - StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, - (STATE_MACHINE_FUNC) PeerDeauthAction); - - /* column 2 */ - StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, - (STATE_MACHINE_FUNC) PeerDeauthAction); - -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, - u16 Alg, - u16 Seq, - u16 Reason, u16 Status) -{ - struct rt_header_802_11 AuthHdr; - unsigned long FrameLen = 0; - u8 *pOutBuffer = NULL; - int NStatus; - - if (Reason != MLME_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n")); - return; - } - /*Get an unused nonpaged memory */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n")); - MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, - pAd->MlmeAux.Bssid); - MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11), - &AuthHdr, 2, &Alg, 2, &Seq, 2, &Reason, END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Addr2[MAC_ADDR_LEN]; - u16 Reason; - - if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) { - if (INFRA_ON(pAd) - && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid) - ) { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", - Reason)); - - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, - 0); - - /* send wireless event - for deauthentication */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, - pAd->MacTab. - Content[BSSID_WCID].Addr, - BSS0, 0); - - LinkDown(pAd, TRUE); - } - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("AUTH_RSP - PeerDeauthAction() sanity check fail\n")); - } -} diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c deleted file mode 100644 index 4996258f6ecd..000000000000 --- a/drivers/staging/rt2860/sta/connect.c +++ /dev/null @@ -1,2613 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - connect.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John 2004-08-08 Major modification from RT2560 - Justin P. Mattock 11/07/2010 Fix typos -*/ -#include "../rt_config.h" - -u8 CipherSuiteWpaNoneTkip[] = { - 0x00, 0x50, 0xf2, 0x01, /* oui */ - 0x01, 0x00, /* Version */ - 0x00, 0x50, 0xf2, 0x02, /* Multicast */ - 0x01, 0x00, /* Number of unicast */ - 0x00, 0x50, 0xf2, 0x02, /* unicast */ - 0x01, 0x00, /* number of authentication method */ - 0x00, 0x50, 0xf2, 0x00 /* authentication */ -}; - -u8 CipherSuiteWpaNoneTkipLen = - (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8)); - -u8 CipherSuiteWpaNoneAes[] = { - 0x00, 0x50, 0xf2, 0x01, /* oui */ - 0x01, 0x00, /* Version */ - 0x00, 0x50, 0xf2, 0x04, /* Multicast */ - 0x01, 0x00, /* Number of unicast */ - 0x00, 0x50, 0xf2, 0x04, /* unicast */ - 0x01, 0x00, /* number of authentication method */ - 0x00, 0x50, 0xf2, 0x00 /* authentication */ -}; - -u8 CipherSuiteWpaNoneAesLen = - (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8)); - -/* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */ -/* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */ -/* All settings successfuly negotiated firing MLME state machines become final settings */ -/* and are copied to pAd->StaActive */ -#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ -{ \ - NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \ - (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \ - NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \ - COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \ - (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \ - (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \ - (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \ - (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \ - (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \ - (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \ - (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \ - (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \ - (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \ - NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\ - (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \ - NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\ - NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));\ - NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(struct rt_qos_capability_parm));\ - NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(struct rt_qbss_load_parm));\ - COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \ - (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \ - (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\ - COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\ - (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\ -} - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - - ========================================================================== -*/ -void MlmeCntlInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]) -{ - /* Control state machine differs from other state machines, the interface */ - /* follows the standard interface */ - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, - struct rt_mlme_queue_elem *Elem) -{ - switch (pAd->Mlme.CntlMachine.CurrState) { - case CNTL_IDLE: - CntlIdleProc(pAd, Elem); - break; - case CNTL_WAIT_DISASSOC: - CntlWaitDisassocProc(pAd, Elem); - break; - case CNTL_WAIT_JOIN: - CntlWaitJoinProc(pAd, Elem); - break; - - /* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */ - /* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */ - /* Therefore not protected by NDIS's "only one outstanding OID request" */ - /* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */ - /* Current approach is to block new SET request at RTMPSetInformation() */ - /* when CntlMachine.CurrState is not CNTL_IDLE */ - case CNTL_WAIT_REASSOC: - CntlWaitReassocProc(pAd, Elem); - break; - - case CNTL_WAIT_START: - CntlWaitStartProc(pAd, Elem); - break; - case CNTL_WAIT_AUTH: - CntlWaitAuthProc(pAd, Elem); - break; - case CNTL_WAIT_AUTH2: - CntlWaitAuthProc2(pAd, Elem); - break; - case CNTL_WAIT_ASSOC: - CntlWaitAssocProc(pAd, Elem); - break; - - case CNTL_WAIT_OID_LIST_SCAN: - if (Elem->MsgType == MT2_SCAN_CONF) { - /* Resume TxRing after SCANING complete. We hope the out-of-service time */ - /* won't be too long to let upper layer time-out the waiting frames */ - RTMPResumeMsduTransmission(pAd); - - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - - /* */ - /* Set LED status to previous status. */ - /* */ - if (pAd->bLedOnScanning) { - pAd->bLedOnScanning = FALSE; - RTMPSetLED(pAd, pAd->LedStatus); - } - } - break; - - case CNTL_WAIT_OID_DISASSOC: - if (Elem->MsgType == MT2_DISASSOC_CONF) { - LinkDown(pAd, FALSE); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - } - break; -#ifdef RTMP_MAC_USB - /* */ - /* This state is for that we want to connect to an AP but */ - /* it didn't find on BSS List table. So we need to scan the air first, */ - /* after that we can try to connect to the desired AP if available. */ - /* */ - case CNTL_WAIT_SCAN_FOR_CONNECT: - if (Elem->MsgType == MT2_SCAN_CONF) { - /* Resume TxRing after SCANING complete. We hope the out-of-service time */ - /* won't be too long to let upper layer time-out the waiting frames */ - RTMPResumeMsduTransmission(pAd); -#ifdef CCX_SUPPORT - if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) { - /* Cisco scan request is finished, prepare beacon report */ - MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, - MT2_AIRONET_SCAN_DONE, 0, NULL); - } -#endif /* CCX_SUPPORT // */ - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - - /* */ - /* Check if we can connect to. */ - /* */ - BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, - (char *) pAd->MlmeAux. - AutoReconnectSsid, - pAd->MlmeAux.AutoReconnectSsidLen); - if (pAd->MlmeAux.SsidBssTab.BssNr > 0) { - MlmeAutoReconnectLastSSID(pAd); - } - } - break; -#endif /* RTMP_MAC_USB // */ - default: - DBGPRINT_ERR("ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType); - break; - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_disassoc_req DisassocReq; - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - switch (Elem->MsgType) { - case OID_802_11_SSID: - CntlOidSsidProc(pAd, Elem); - break; - - case OID_802_11_BSSID: - CntlOidRTBssidProc(pAd, Elem); - break; - - case OID_802_11_BSSID_LIST_SCAN: - CntlOidScanProc(pAd, Elem); - break; - - case OID_802_11_DISASSOCIATE: - DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, - REASON_DISASSOC_STA_LEAVING); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), &DisassocReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; - - if (pAd->StaCfg.WpaSupplicantUP != - WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) { - /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ - /* Since calling this indicate user don't want to connect to that SSID anymore. */ - pAd->MlmeAux.AutoReconnectSsidLen = 32; - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, - pAd->MlmeAux.AutoReconnectSsidLen); - } - break; - - case MT2_MLME_ROAMING_REQ: - CntlMlmeRoamingProc(pAd, Elem); - break; - - case OID_802_11_MIC_FAILURE_REPORT_FRAME: - WpaMicFailureReportFrame(pAd, Elem); - break; - - default: - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n", - Elem->MsgType)); - break; - } -} - -void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_scan_req ScanReq; - unsigned long BssIdx = BSS_NOT_FOUND; - struct rt_bss_entry CurrBss; - - /* record current BSS if network is connected. */ - /* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - BssIdx = - BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, - (u8 *)pAd->CommonCfg.Ssid, - pAd->CommonCfg.SsidLen, - pAd->CommonCfg.Channel); - if (BssIdx != BSS_NOT_FOUND) { - NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], - sizeof(struct rt_bss_entry)); - } - } - /* clean up previous SCAN result, add current BSS back to table if any */ - BssTableInit(&pAd->ScanTab); - if (BssIdx != BSS_NOT_FOUND) { - /* DDK Note: If the NIC is associated with a particular BSSID and SSID */ - /* that are not contained in the list of BSSIDs generated by this scan, the */ - /* BSSID description of the currently associated BSSID and SSID should be */ - /* appended to the list of BSSIDs in the NIC's database. */ - /* To ensure this, we append this BSS as the first entry in SCAN result */ - NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, - sizeof(struct rt_bss_entry)); - pAd->ScanTab.BssNr = 1; - } - - ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY, - SCAN_ACTIVE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, - sizeof(struct rt_mlme_scan_req), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; -} - -/* - ========================================================================== - Description: - Before calling this routine, user desired SSID should already been - recorded in CommonCfg.Ssid[] - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg; - struct rt_mlme_disassoc_req DisassocReq; - unsigned long Now; - - /* Step 1. record the desired user settings to MlmeAux */ - NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); - NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength); - pAd->MlmeAux.SsidLen = (u8)pOidSsid->SsidLength; - NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - pAd->MlmeAux.BssType = pAd->StaCfg.BssType; - - pAd->StaCfg.bAutoConnectByBssid = FALSE; - - /* */ - /* Update Reconnect Ssid, that user desired to connect. */ - /* */ - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); - NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen); - pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen; - - /* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */ - /* & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */ - BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, - (char *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); - - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n", - pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, - pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid)); - NdisGetSystemUpTime(&Now); - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && - (pAd->CommonCfg.SsidLen == - pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) - && NdisEqualMemory(pAd->CommonCfg.Ssid, - pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, - pAd->CommonCfg.SsidLen) - && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, - pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) { - /* Case 1. already connected with an AP who has the desired SSID */ - /* with highest RSSI */ - - /* Add checking Mode "LEAP" for CCX 1.0 */ - if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) - ) && - (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) { - /* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */ - /* connection process */ - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - disassociate with current AP...\n")); - DisassocParmFill(pAd, &DisassocReq, - pAd->CommonCfg.Bssid, - REASON_DISASSOC_STA_LEAVING); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, - MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), - &DisassocReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; - } else if (pAd->bConfigChanged == TRUE) { - /* case 1.2 Important Config has changed, we have to reconnect to the same AP */ - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n")); - DisassocParmFill(pAd, &DisassocReq, - pAd->CommonCfg.Bssid, - REASON_DISASSOC_STA_LEAVING); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, - MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), - &DisassocReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; - } else { - /* case 1.3. already connected to the SSID with highest RSSI. */ - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n")); - /* */ - /* (HCT 12.1) 1c_wlan_mediaevents required */ - /* media connect events are indicated when associating with the same AP */ - /* */ - if (INFRA_ON(pAd)) { - /* */ - /* Since MediaState already is NdisMediaStateConnected */ - /* We just indicate the connect event again to meet the WHQL required. */ - /* */ - pAd->IndicateMediaState = - NdisMediaStateConnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */ - } - - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, - &pAd->MlmeAux.Bssid[0], NULL, - 0); - } - } else if (INFRA_ON(pAd)) { - /* */ - /* For RT61 */ - /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */ - /* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */ - /* But media status is connected, so the SSID not report correctly. */ - /* */ - if (!SSID_EQUAL - (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, - pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) { - /* */ - /* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */ - /* */ - pAd->MlmeAux.CurrReqIsFromNdis = TRUE; - } - /* case 2. active INFRA association existent */ - /* roaming is done within miniport driver, nothing to do with configuration */ - /* utility. so upon a new SET(OID_802_11_SSID) is received, we just */ - /* disassociate with the current associated AP, */ - /* then perform a new association with this new SSID, no matter the */ - /* new/old SSID are the same or not. */ - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - disassociate with current AP...\n")); - DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, - REASON_DISASSOC_STA_LEAVING); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), &DisassocReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; - } else { - if (ADHOC_ON(pAd)) { - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - drop current ADHOC\n")); - LinkDown(pAd, FALSE); - OPSTATUS_CLEAR_FLAG(pAd, - fOP_STATUS_MEDIA_STATE_CONNECTED); - pAd->IndicateMediaState = NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_DOWN; - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n")); - } - - if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) && - (pAd->StaCfg.bAutoReconnect == TRUE) && - (pAd->MlmeAux.BssType == BSS_INFRA) && - (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) - == TRUE) - ) { - struct rt_mlme_scan_req ScanReq; - - DBGPRINT(RT_DEBUG_TRACE, - ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n")); - ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen, BSS_ANY, - SCAN_ACTIVE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, - sizeof(struct rt_mlme_scan_req), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_OID_LIST_SCAN; - /* Reset Missed scan number */ - pAd->StaCfg.LastScanTime = Now; - } else { - pAd->MlmeAux.BssIdx = 0; - IterateOnBssTab(pAd); - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - unsigned long BssIdx; - u8 *pOidBssid = (u8 *)Elem->Msg; - struct rt_mlme_disassoc_req DisassocReq; - struct rt_mlme_join_req JoinReq; - - /* record user desired settings */ - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid); - pAd->MlmeAux.BssType = pAd->StaCfg.BssType; - - /* find the desired BSS in the latest SCAN result table */ - BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel); - if (BssIdx == BSS_NOT_FOUND) { - struct rt_mlme_scan_req ScanReq; - - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n")); - /*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */ - - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - BSSID not found. start a new scan\n")); - ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, - sizeof(struct rt_mlme_scan_req), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; - /* Reset Missed scan number */ - NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); - return; - } - /* */ - /* Update Reconnect Ssid, that user desired to connect. */ - /* */ - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); - pAd->MlmeAux.AutoReconnectSsidLen = - pAd->ScanTab.BssEntry[BssIdx].SsidLen; - NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, - pAd->ScanTab.BssEntry[BssIdx].Ssid, - pAd->ScanTab.BssEntry[BssIdx].SsidLen); - - /* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */ - /* Because we need this entry to become the JOIN target in later on SYNC state machine */ - pAd->MlmeAux.BssIdx = 0; - pAd->MlmeAux.SsidBssTab.BssNr = 1; - NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], - &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry)); - - /* Add SSID into MlmeAux for site survey joining hidden SSID */ - pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen; - NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, - pAd->MlmeAux.SsidLen); - - { - if (INFRA_ON(pAd)) { - /* disassoc from current AP first */ - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - disassociate with current AP ...\n")); - DisassocParmFill(pAd, &DisassocReq, - pAd->CommonCfg.Bssid, - REASON_DISASSOC_STA_LEAVING); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, - MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), - &DisassocReq); - - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; - } else { - if (ADHOC_ON(pAd)) { - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - drop current ADHOC\n")); - LinkDown(pAd, FALSE); - OPSTATUS_CLEAR_FLAG(pAd, - fOP_STATUS_MEDIA_STATE_CONNECTED); - pAd->IndicateMediaState = - NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_DOWN; - DBGPRINT(RT_DEBUG_TRACE, - ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n")); - } - /* Change the wepstatus to original wepstatus */ - pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus; - pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus; - pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus; - - /* Check cipher suite, AP must have more secured cipher than station setting */ - /* Set the Pairwise and Group cipher to match the intended AP setting */ - /* We can only connect to AP with less secured cipher setting */ - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPAPSK)) { - pAd->StaCfg.GroupCipher = - pAd->ScanTab.BssEntry[BssIdx].WPA. - GroupCipher; - - if (pAd->StaCfg.WepStatus == - pAd->ScanTab.BssEntry[BssIdx].WPA. - PairCipher) - pAd->StaCfg.PairCipher = - pAd->ScanTab.BssEntry[BssIdx].WPA. - PairCipher; - else if (pAd->ScanTab.BssEntry[BssIdx].WPA. - PairCipherAux != Ndis802_11WEPDisabled) - pAd->StaCfg.PairCipher = - pAd->ScanTab.BssEntry[BssIdx].WPA. - PairCipherAux; - else /* There is no PairCipher Aux, downgrade our capability to TKIP */ - pAd->StaCfg.PairCipher = - Ndis802_11Encryption2Enabled; - } else - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2PSK)) { - pAd->StaCfg.GroupCipher = - pAd->ScanTab.BssEntry[BssIdx].WPA2. - GroupCipher; - - if (pAd->StaCfg.WepStatus == - pAd->ScanTab.BssEntry[BssIdx].WPA2. - PairCipher) - pAd->StaCfg.PairCipher = - pAd->ScanTab.BssEntry[BssIdx].WPA2. - PairCipher; - else if (pAd->ScanTab.BssEntry[BssIdx].WPA2. - PairCipherAux != Ndis802_11WEPDisabled) - pAd->StaCfg.PairCipher = - pAd->ScanTab.BssEntry[BssIdx].WPA2. - PairCipherAux; - else /* There is no PairCipher Aux, downgrade our capability to TKIP */ - pAd->StaCfg.PairCipher = - Ndis802_11Encryption2Enabled; - - /* RSN capability */ - pAd->StaCfg.RsnCapability = - pAd->ScanTab.BssEntry[BssIdx].WPA2. - RsnCapability; - } - /* Set Mix cipher flag */ - pAd->StaCfg.bMixCipher = - (pAd->StaCfg.PairCipher == - pAd->StaCfg.GroupCipher) ? FALSE : TRUE; - /*if (pAd->StaCfg.bMixCipher == TRUE) - { - // If mix cipher, re-build RSNIE - RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); - } */ - /* No active association, join the BSS immediately */ - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %pM ...\n", - pOidBssid)); - - JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, - sizeof(struct rt_mlme_join_req), &JoinReq); - - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; - } - } -} - -/* Roaming is the only external request triggering CNTL state machine */ -/* despite of other "SET OID" operation. All "SET OID" related operations */ -/* happen in sequence, because no other SET OID will be sent to this device */ -/* until the the previous SET operation is complete (successful o failed). */ -/* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */ -/* or been corrupted by other "SET OID"? */ -/* */ -/* IRQL = DISPATCH_LEVEL */ -void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 BBPValue = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n")); - - { - /*Let BBP register at 20MHz to do (fast) roaming. */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - - NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, - sizeof(pAd->MlmeAux.RoamTab)); - pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr; - - BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab); - pAd->MlmeAux.BssIdx = 0; - IterateOnBssTab(pAd); - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mlme_start_req StartReq; - - if (Elem->MsgType == MT2_DISASSOC_CONF) { - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n")); - - if (pAd->CommonCfg.bWirelessEvent) { - RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - } - - LinkDown(pAd, FALSE); - - /* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */ - if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) - && (pAd->StaCfg.BssType == BSS_ADHOC)) { - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n", - pAd->MlmeAux.Ssid)); - StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, - sizeof(struct rt_mlme_start_req), &StartReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; - } - /* case 2. try each matched BSS */ - else { - pAd->MlmeAux.BssIdx = 0; - - IterateOnBssTab(pAd); - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Reason; - struct rt_mlme_auth_req AuthReq; - - if (Elem->MsgType == MT2_JOIN_CONF) { - NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); - if (Reason == MLME_SUCCESS) { - /* 1. joined an IBSS, we are pretty much done here */ - if (pAd->MlmeAux.BssType == BSS_ADHOC) { - /* */ - /* 5G bands rules of Japan: */ - /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */ - /* */ - if ((pAd->CommonCfg.bIEEE80211H == 1) && - RadarChannelCheck(pAd, - pAd->CommonCfg.Channel) - ) { - pAd->Mlme.CntlMachine.CurrState = - CNTL_IDLE; - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", - pAd->CommonCfg.Channel)); - return; - } - - LinkUp(pAd, BSS_ADHOC); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - join the IBSS = %pM ...\n", - pAd->CommonCfg.Bssid)); - - pAd->IndicateMediaState = - NdisMediaStateConnected; - pAd->ExtraInfo = GENERAL_LINK_UP; - } - /* 2. joined a new INFRA network, start from authentication */ - else { - { - /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */ - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeShared) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeAutoSwitch)) { - AuthParmFill(pAd, &AuthReq, - pAd->MlmeAux.Bssid, - AUTH_MODE_KEY); - } else { - AuthParmFill(pAd, &AuthReq, - pAd->MlmeAux.Bssid, - AUTH_MODE_OPEN); - } - MlmeEnqueue(pAd, AUTH_STATE_MACHINE, - MT2_MLME_AUTH_REQ, - sizeof - (struct rt_mlme_auth_req), - &AuthReq); - } - - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_AUTH; - } - } else { - /* 3. failed, try next BSS */ - pAd->MlmeAux.BssIdx++; - IterateOnBssTab(pAd); - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Result; - - if (Elem->MsgType == MT2_START_CONF) { - NdisMoveMemory(&Result, Elem->Msg, sizeof(u16)); - if (Result == MLME_SUCCESS) { - /* */ - /* 5G bands rules of Japan: */ - /* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */ - /* */ - if ((pAd->CommonCfg.bIEEE80211H == 1) && - RadarChannelCheck(pAd, pAd->CommonCfg.Channel) - ) { - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", - pAd->CommonCfg.Channel)); - return; - } - NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo. - MCSSet[0], 16); - if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { - N_ChannelCheck(pAd); - SetCommonHT(pAd); - NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, - &pAd->CommonCfg.AddHTInfo, - sizeof(struct rt_add_ht_info_ie)); - RTMPCheckHt(pAd, BSSID_WCID, - &pAd->CommonCfg.HtCapability, - &pAd->CommonCfg.AddHTInfo); - pAd->StaActive.SupportedPhyInfo.bHtEnable = - TRUE; - NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo. - MCSSet[0], - &pAd->CommonCfg.HtCapability. - MCSSet[0], 16); - COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG - (pAd); - - if ((pAd->CommonCfg.HtCapability.HtCapInfo. - ChannelWidth == BW_40) - && (pAd->CommonCfg.AddHTInfo.AddHtInfo. - ExtChanOffset == EXTCHA_ABOVE)) { - pAd->MlmeAux.CentralChannel = - pAd->CommonCfg.Channel + 2; - } else - if ((pAd->CommonCfg.HtCapability.HtCapInfo. - ChannelWidth == BW_40) - && (pAd->CommonCfg.AddHTInfo.AddHtInfo. - ExtChanOffset == EXTCHA_BELOW)) { - pAd->MlmeAux.CentralChannel = - pAd->CommonCfg.Channel - 2; - } - } else { - pAd->StaActive.SupportedPhyInfo.bHtEnable = - FALSE; - } - LinkUp(pAd, BSS_ADHOC); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - /* Before send beacon, driver need do radar detection */ - if ((pAd->CommonCfg.Channel > 14) - && (pAd->CommonCfg.bIEEE80211H == 1) - && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { - pAd->CommonCfg.RadarDetect.RDMode = - RD_SILENCE_MODE; - pAd->CommonCfg.RadarDetect.RDCount = 0; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - start a new IBSS = %pM ...\n", - pAd->CommonCfg.Bssid)); - } else { - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Start IBSS fail. BUG!\n")); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Reason; - struct rt_mlme_assoc_req AssocReq; - struct rt_mlme_auth_req AuthReq; - - if (Elem->MsgType == MT2_AUTH_CONF) { - NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); - if (Reason == MLME_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); - AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, - pAd->MlmeAux.CapabilityInfo, - ASSOC_TIMEOUT, - pAd->StaCfg.DefaultListenCount); - - { - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, - MT2_MLME_ASSOC_REQ, - sizeof(struct rt_mlme_assoc_req), - &AssocReq); - - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_ASSOC; - } - } else { - /* This fail may because of the AP already keep us in its MAC table without */ - /* ageing-out. The previous authentication attempt must have let it remove us. */ - /* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */ - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - AUTH FAIL, try again...\n")); - - { - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeShared) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeAutoSwitch)) { - /* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */ - AuthParmFill(pAd, &AuthReq, - pAd->MlmeAux.Bssid, - AUTH_MODE_KEY); - } else { - AuthParmFill(pAd, &AuthReq, - pAd->MlmeAux.Bssid, - AUTH_MODE_OPEN); - } - MlmeEnqueue(pAd, AUTH_STATE_MACHINE, - MT2_MLME_AUTH_REQ, - sizeof(struct rt_mlme_auth_req), - &AuthReq); - - } - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2; - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Reason; - struct rt_mlme_assoc_req AssocReq; - struct rt_mlme_auth_req AuthReq; - - if (Elem->MsgType == MT2_AUTH_CONF) { - NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); - if (Reason == MLME_SUCCESS) { - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); - AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, - pAd->MlmeAux.CapabilityInfo, - ASSOC_TIMEOUT, - pAd->StaCfg.DefaultListenCount); - { - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, - MT2_MLME_ASSOC_REQ, - sizeof(struct rt_mlme_assoc_req), - &AssocReq); - - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_ASSOC; - } - } else { - if ((pAd->StaCfg.AuthMode == - Ndis802_11AuthModeAutoSwitch) - && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) { - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - AUTH FAIL, try OPEN system...\n")); - AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, - Ndis802_11AuthModeOpen); - MlmeEnqueue(pAd, AUTH_STATE_MACHINE, - MT2_MLME_AUTH_REQ, - sizeof(struct rt_mlme_auth_req), - &AuthReq); - - pAd->Mlme.CntlMachine.CurrState = - CNTL_WAIT_AUTH2; - } else { - /* not success, try next BSS */ - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - AUTH FAIL, give up; try next BSS\n")); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; /*??????? */ - pAd->MlmeAux.BssIdx++; - IterateOnBssTab(pAd); - } - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Reason; - - if (Elem->MsgType == MT2_ASSOC_CONF) { - NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16)); - if (Reason == MLME_SUCCESS) { - if (pAd->CommonCfg.bWirelessEvent) { - RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, - pAd->MacTab. - Content[BSSID_WCID].Addr, - BSS0, 0); - } - - LinkUp(pAd, BSS_INFRA); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Association successful on BSS #%ld\n", - pAd->MlmeAux.BssIdx)); - } else { - /* not success, try next BSS */ - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Association fails on BSS #%ld\n", - pAd->MlmeAux.BssIdx)); - pAd->MlmeAux.BssIdx++; - IterateOnBssTab(pAd); - } - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Result; - - if (Elem->MsgType == MT2_REASSOC_CONF) { - NdisMoveMemory(&Result, Elem->Msg, sizeof(u16)); - if (Result == MLME_SUCCESS) { - /* send wireless event - for association */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, - pAd->MacTab. - Content[BSSID_WCID].Addr, - BSS0, 0); - - /* */ - /* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */ - /* */ - LinkUp(pAd, BSS_INFRA); - - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Re-assocition successful on BSS #%ld\n", - pAd->MlmeAux.RoamIdx)); - } else { - /* reassoc failed, try to pick next BSS in the BSS Table */ - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - Re-assocition fails on BSS #%ld\n", - pAd->MlmeAux.RoamIdx)); - { - pAd->MlmeAux.RoamIdx++; - IterateOnBssTab2(pAd); - } - } - } -} - -void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd) -{ -#define AC0_DEF_TXOP 0 -#define AC1_DEF_TXOP 0 -#define AC2_DEF_TXOP 94 -#define AC3_DEF_TXOP 47 - - /* Turn on QOs if use HT rate. */ - if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) { - pAd->CommonCfg.APEdcaParm.bValid = TRUE; - pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; - pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; - pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; - pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; - - pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; - pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; - pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; - pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; - - pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10; - pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6; - pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; - pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; - - pAd->CommonCfg.APEdcaParm.Txop[0] = 0; - pAd->CommonCfg.APEdcaParm.Txop[1] = 0; - pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP; - pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP; - } - AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) -{ - unsigned long Now; - u32 Data; - BOOLEAN Cancelled; - u8 Value = 0, idx = 0, HashIdx = 0; - struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL; - - /* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */ - pAd->Mlme.ChannelQuality = 50; - - pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid); - if (pEntry) { - MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); - pEntry = NULL; - } - - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - - /* */ - /* ASSOC - DisassocTimeoutAction */ - /* CNTL - Dis-associate successful */ - /* ! LINK DOWN ! */ - /* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */ - /* */ - /* To prevent DisassocTimeoutAction to call Link down after we link up, */ - /* cancel the DisassocTimer no matter what it start or not. */ - /* */ - RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); - - COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); - - COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); - -#ifdef RTMP_MAC_PCI - /* Before power save before link up function, We will force use 1R. */ - /* So after link up, check Rx antenna # again. */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - if (pAd->Antenna.field.RxPath == 3) { - Value |= (0x10); - } else if (pAd->Antenna.field.RxPath == 2) { - Value |= (0x8); - } else if (pAd->Antenna.field.RxPath == 1) { - Value |= (0x0); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); - pAd->StaCfg.BBPR3 = Value; -#endif /* RTMP_MAC_PCI // */ - - if (BssType == BSS_ADHOC) { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); - - if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) - AdhocTurnOnQos(pAd); - - DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n")); - } else { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); - - DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n")); - } - - /* 3*3 */ - /* reset Tx beamforming bit */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x01); - Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - /* Change to AP channel */ - if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) { - /* Must use 40MHz. */ - pAd->CommonCfg.BBPCurrentBW = BW_40; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - Value |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - /* RX : control channel at lower */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = Value; -#endif /* RTMP_MAC_PCI // */ - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data &= 0xfffffffe; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - if (pAd->MACVersion == 0x28600100) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); - DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n")); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n", - pAd->CommonCfg.CentralChannel)); - } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == - BW_40)) { - /* Must use 40MHz. */ - pAd->CommonCfg.BBPCurrentBW = BW_40; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - Value |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data |= 0x1; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value |= (0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = Value; -#endif /* RTMP_MAC_PCI // */ - - if (pAd->MACVersion == 0x28600100) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); - DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n")); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n", - pAd->CommonCfg.CentralChannel)); - } else { - pAd->CommonCfg.BBPCurrentBW = BW_20; - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data &= 0xfffffffe; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RTMP_MAC_PCI - pAd->StaCfg.BBPR3 = Value; -#endif /* RTMP_MAC_PCI // */ - - if (pAd->MACVersion == 0x28600100) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); - DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n")); - } - - DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n")); - } - - RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); - - /* */ - /* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */ - /* */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, - &pAd->BbpTuning.R66CurrentValue); - - DBGPRINT(RT_DEBUG_TRACE, - ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n", - BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, - pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel)); - - DBGPRINT(RT_DEBUG_TRACE, - ("LINK UP! (Density =%d, )\n", - pAd->MacTab.Content[BSSID_WCID].MpduDensity)); - - AsicSetBssid(pAd, pAd->CommonCfg.Bssid); - - AsicSetSlotTime(pAd, TRUE); - AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); - - /* Call this for RTS protection for legacy rate, we will always enable RTS threshold, but normally it will not hit */ - AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, - FALSE); - - if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) { - /* Update HT protection for based on AP's operating mode. */ - if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { - AsicUpdateProtect(pAd, - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - OperaionMode, ALLN_SETPROTECT, FALSE, - TRUE); - } else - AsicUpdateProtect(pAd, - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - OperaionMode, ALLN_SETPROTECT, FALSE, - FALSE); - } - - NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs)); - - NdisGetSystemUpTime(&Now); - pAd->StaCfg.LastBeaconRxTime = Now; /* last RX timestamp */ - - if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) && - CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) { - MlmeSetTxPreamble(pAd, Rt802_11PreambleShort); - } - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); - - if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) { - } - pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; - - if (BssType == BSS_ADHOC) { - MakeIbssBeacon(pAd); - if ((pAd->CommonCfg.Channel > 14) - && (pAd->CommonCfg.bIEEE80211H == 1) - && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) { - ; /*Do nothing */ - } else { - AsicEnableIbssSync(pAd); - } - - /* In ad hoc mode, use MAC table from index 1. */ - /* p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */ - RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00); - RTMP_IO_WRITE32(pAd, 0x1808, 0x00); - - /* If WEP is enabled, add key material and cipherAlg into Asic */ - /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */ - - if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) { - u8 *Key; - u8 CipherAlg; - - for (idx = 0; idx < SHARE_KEY_NUM; idx++) { - CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg; - Key = pAd->SharedKey[BSS0][idx].Key; - - if (pAd->SharedKey[BSS0][idx].KeyLen > 0) { - /* Set key material and cipherAlg to Asic */ - AsicAddSharedKeyEntry(pAd, BSS0, idx, - CipherAlg, Key, - NULL, NULL); - - if (idx == pAd->StaCfg.DefaultKeyId) { - /* Update WCID attribute table and IVEIV table for this group key table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - idx, - CipherAlg, - NULL); - } - } - - } - } - /* If WPANone is enabled, add key material and cipherAlg into Asic */ - /* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */ - else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { - pAd->StaCfg.DefaultKeyId = 0; /* always be zero */ - - NdisZeroMemory(&pAd->SharedKey[BSS0][0], - sizeof(struct rt_cipher_key)); - pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, - pAd->StaCfg.PMK, LEN_TKIP_EK); - - if (pAd->StaCfg.PairCipher == - Ndis802_11Encryption2Enabled) { - NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, - &pAd->StaCfg.PMK[16], - LEN_TKIP_RXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, - &pAd->StaCfg.PMK[16], - LEN_TKIP_TXMICK); - } - /* Decide its ChiperAlg */ - if (pAd->StaCfg.PairCipher == - Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == - Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; - else { - DBGPRINT(RT_DEBUG_TRACE, - ("Unknow Cipher (=%d), set Cipher to AES\n", - pAd->StaCfg.PairCipher)); - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; - } - - /* Set key material and cipherAlg to Asic */ - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0].CipherAlg, - pAd->SharedKey[BSS0][0].Key, - pAd->SharedKey[BSS0][0].TxMic, - pAd->SharedKey[BSS0][0].RxMic); - - /* Update WCID attribute table and IVEIV table for this group key table */ - RTMPAddWcidAttributeEntry(pAd, BSS0, 0, - pAd->SharedKey[BSS0][0]. - CipherAlg, NULL); - - } - - } else /* BSS_INFRA */ - { - /* Check the new SSID with last SSID */ - while (Cancelled == TRUE) { - if (pAd->CommonCfg.LastSsidLen == - pAd->CommonCfg.SsidLen) { - if (RTMPCompareMemory - (pAd->CommonCfg.LastSsid, - pAd->CommonCfg.Ssid, - pAd->CommonCfg.LastSsidLen) == 0) { - /* Link to the old one no linkdown is required. */ - break; - } - } - /* Send link down event before set to link up */ - pAd->IndicateMediaState = NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_DOWN; - DBGPRINT(RT_DEBUG_TRACE, - ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n")); - break; - } - - /* */ - /* On WPA mode, Remove All Keys if not connect to the last BSSID */ - /* Key will be set after 4-way handshake. */ - /* */ - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { - unsigned long IV; - - /* Remove all WPA keys */ - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - RTMPWPARemoveAllKeys(pAd); - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - pAd->StaCfg.PrivacyFilter = - Ndis802_11PrivFilter8021xWEP; - - /* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */ - /* If IV related values are too large in GroupMsg2, AP would ignore this message. */ - IV = 1; - IV |= (pAd->StaCfg.DefaultKeyId << 30); - AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0); - } - /* NOTE: */ - /* the decision of using "short slot time" or not may change dynamically due to */ - /* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */ - - /* NOTE: */ - /* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */ - /* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */ - - ComposePsPoll(pAd); - ComposeNullFrame(pAd); - - AsicEnableBssSync(pAd); - - /* Add BSSID to WCID search table */ - AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid); - - /* If WEP is enabled, add pairwise and shared key */ - if (((pAd->StaCfg.WpaSupplicantUP) && - (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && - (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) || - ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) && - (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) { - u8 *Key; - u8 CipherAlg; - - for (idx = 0; idx < SHARE_KEY_NUM; idx++) { - CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg; - Key = pAd->SharedKey[BSS0][idx].Key; - - if (pAd->SharedKey[BSS0][idx].KeyLen > 0) { - /* Set key material and cipherAlg to Asic */ - AsicAddSharedKeyEntry(pAd, BSS0, idx, - CipherAlg, Key, - NULL, NULL); - - if (idx == pAd->StaCfg.DefaultKeyId) { - /* Assign group key info */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - idx, - CipherAlg, - NULL); - - pEntry->Aid = BSSID_WCID; - /* Assign pairwise key info */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - idx, - CipherAlg, - pEntry); - } - } - } - } - /* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */ - /* should wait until at least 2 active nodes in this BSSID. */ - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); - - /* For GUI ++ */ - if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) { - pAd->IndicateMediaState = NdisMediaStateConnected; - pAd->ExtraInfo = GENERAL_LINK_UP; - RTMP_IndicateMediaState(pAd); - } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) - { - if (pAd->StaCfg.WpaSupplicantUP == - WPA_SUPPLICANT_DISABLE) - RTMPSetTimer(&pAd->Mlme.LinkDownTimer, - LINK_DOWN_TIMEOUT); - } - /* -- */ - - /* Add BSSID in my MAC Table. */ - NdisAcquireSpinLock(&pAd->MacTabLock); - /* add this MAC entry into HASH table */ - if (pEntry) { - HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid); - if (pAd->MacTab.Hash[HashIdx] == NULL) { - pAd->MacTab.Hash[HashIdx] = pEntry; - } else { - pCurrEntry = pAd->MacTab.Hash[HashIdx]; - while (pCurrEntry->pNext != NULL) { - pCurrEntry = pCurrEntry->pNext; - } - pCurrEntry->pNext = pEntry; - } - } - RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid, - MAC_ADDR_LEN); - pEntry->Aid = BSSID_WCID; - pEntry->pAd = pAd; - pEntry->ValidAsCLI = TRUE; /*Although this is bssid..still set ValidAsCl */ - pAd->MacTab.Size = 1; /* infra mode always set MACtab size =1. */ - pEntry->Sst = SST_ASSOC; - pEntry->AuthState = SST_ASSOC; - pEntry->AuthMode = pAd->StaCfg.AuthMode; - pEntry->WepStatus = pAd->StaCfg.WepStatus; - if (pEntry->AuthMode < Ndis802_11AuthModeWPA) { - pEntry->WpaState = AS_NOTUSE; - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - } else { - pEntry->WpaState = AS_PTKSTART; - pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; - } - NdisReleaseSpinLock(&pAd->MacTabLock); - - DBGPRINT(RT_DEBUG_TRACE, - ("LINK UP! ClientStatusFlags=%lx)\n", - pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); - - MlmeUpdateTxRates(pAd, TRUE, BSS0); - MlmeUpdateHtTxRates(pAd, BSS0); - DBGPRINT(RT_DEBUG_TRACE, - ("LINK UP! (StaActive.bHtEnable =%d, )\n", - pAd->StaActive.SupportedPhyInfo.bHtEnable)); - - if (pAd->CommonCfg.bAggregationCapable) { - if ((pAd->CommonCfg.bPiggyBackCapable) - && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) { - OPSTATUS_SET_FLAG(pAd, - fOP_STATUS_PIGGYBACK_INUSED); - OPSTATUS_SET_FLAG(pAd, - fOP_STATUS_AGGREGATION_INUSED); - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_AGGREGATION_CAPABLE); - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_PIGGYBACK_CAPABLE); - RTMPSetPiggyBack(pAd, TRUE); - DBGPRINT(RT_DEBUG_TRACE, - ("Turn on Piggy-Back\n")); - } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { - OPSTATUS_SET_FLAG(pAd, - fOP_STATUS_AGGREGATION_INUSED); - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_AGGREGATION_CAPABLE); - DBGPRINT(RT_DEBUG_TRACE, - ("Ralink Aggregation\n")); - } - } - - if (pAd->MlmeAux.APRalinkIe != 0x0) { - if (CLIENT_STATUS_TEST_FLAG - (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) { - AsicEnableRDG(pAd); - } - OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); - CLIENT_STATUS_SET_FLAG(pEntry, - fCLIENT_STATUS_RALINK_CHIPSET); - } else { - OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); - CLIENT_STATUS_CLEAR_FLAG(pEntry, - fCLIENT_STATUS_RALINK_CHIPSET); - } - } - - DBGPRINT(RT_DEBUG_TRACE, - ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", - pAd->CommonCfg.BACapability.word, - pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags)); - - /* Set LED */ - RTMPSetLED(pAd, LED_LINK_UP); - - pAd->Mlme.PeriodicRound = 0; - pAd->Mlme.OneSecPeriodicRound = 0; - pAd->bConfigChanged = FALSE; /* Reset config flag */ - pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information after link is up */ - - /* Set basic auto fall back */ - { - u8 *pTable; - u8 TableSize = 0; - - MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], - &pTable, &TableSize, - &pAd->CommonCfg.TxRateIndex); - AsicUpdateAutoFallBackTable(pAd, pTable); - } - - NdisAcquireSpinLock(&pAd->MacTabLock); - pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word; - pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word; - if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) { - pEntry->bAutoTxRateSwitch = FALSE; - - if (pEntry->HTPhyMode.field.MCS == 32) - pEntry->HTPhyMode.field.ShortGI = GI_800; - - if ((pEntry->HTPhyMode.field.MCS > MCS_7) - || (pEntry->HTPhyMode.field.MCS == 32)) - pEntry->HTPhyMode.field.STBC = STBC_NONE; - - /* If the legacy mode is set, overwrite the transmit setting of this entry. */ - if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM) - RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg. - DesiredTransmitSetting.field. - FixedTxMode, pEntry); - } else - pEntry->bAutoTxRateSwitch = TRUE; - NdisReleaseSpinLock(&pAd->MacTabLock); - - /* Let Link Status Page display first initial rate. */ - pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word); - /* Select DAC according to HT or Legacy */ - if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value); - Value &= (~0x18); - if (pAd->Antenna.field.TxPath == 2) { - Value |= 0x10; - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value); - } else { - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value); - Value &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value); - } - - if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) { - } else if (pEntry->MaxRAmpduFactor == 0) { - /* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */ - /* Because our Init value is 1 at MACRegTable. */ - RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff); - } - /* Patch for Marvel AP to gain high throughput */ - /* Need to set as following, */ - /* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */ - /* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */ - /* 3. PBF_MAX_PCNT as 0x1F3FBF9F */ - /* 4. kick per two packets when dequeue */ - /* */ - /* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */ - /* */ - /* if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. */ - if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1)) - && (pAd->StaCfg.bForceTxBurst == FALSE) - && - (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) - && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) - || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) - && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) { - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); - Data &= 0xFFFFFF00; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); - - RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F); - DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n")); - } else if (pAd->CommonCfg.bEnableTxBurst) { - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); - Data &= 0xFFFFFF00; - Data |= 0x60; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); - pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE; - - RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F); - DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n")); - } else { - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); - Data &= 0xFFFFFF00; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); - - RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F); - DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n")); - } - - /* Re-check to turn on TX burst or not. */ - if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) - && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) { - pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE; - if (pAd->CommonCfg.bEnableTxBurst) { - u32 MACValue = 0; - /* Force disable TXOP value in this case. The same action in MLMEUpdateProtect too. */ - /* I didn't change PBF_MAX_PCNT setting. */ - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue); - MACValue &= 0xFFFFFF00; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue); - pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE; - } - } else { - pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE; - } - - pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE; - COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid); - DBGPRINT(RT_DEBUG_TRACE, - ("pAd->bNextDisableRxBA= %d \n", - pAd->CommonCfg.IOTestParm.bNextDisableRxBA)); - /* BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */ - /* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */ - /* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */ - - if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) { - if (pAd->StaCfg.WpaSupplicantUP && - (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && - (pAd->StaCfg.IEEE8021X == TRUE)) ; - else { - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; - pAd->StaCfg.PrivacyFilter = - Ndis802_11PrivFilterAcceptAll; - } - } - - NdisAcquireSpinLock(&pAd->MacTabLock); - pEntry->PortSecured = pAd->StaCfg.PortSecured; - NdisReleaseSpinLock(&pAd->MacTabLock); - - /* */ - /* Patch Atheros AP TX will breakdown issue. */ - /* AP Model: DLink DWL-8200AP */ - /* */ - if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) - && STA_TKIP_ON(pAd)) { - RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01); - } else { - RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00); - } - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); -} - -/* - ========================================================================== - - Routine Description: - Disconnect current BSSID - - Arguments: - pAd - Pointer to our adapter - IsReqFromAP - Request from AP - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - We need more information to know it's this requst from AP. - If yes! we need to do extra handling, for example, remove the WPA key. - Otherwise on 4-way handshaking will fail, since the WPA key didn't get - removed while auto reconnect. - Disconnect request from AP, it means we will start afresh 4-way handshaking - on WPA mode. - - ========================================================================== -*/ -void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP) -{ - u8 i, ByteValue = 0; - - /* Do nothing if monitor mode is on */ - if (MONITOR_ON(pAd)) - return; - - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - /* Comment the codes, because the line 2291 call the same function. */ - /* RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */ - /* Not allowed go to sleep within the linkdown function. */ - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - - if (pAd->CommonCfg.bWirelessEvent) { - RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID].Addr, - BSS0, 0); - } - - DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n")); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); - -#ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { - BOOLEAN Cancelled; - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - } - - pAd->bPCIclkOff = FALSE; -#endif /* RTMP_MAC_PCI // */ - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) - || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) { - AUTO_WAKEUP_STRUC AutoWakeupCfg; - AsicForceWakeup(pAd, TRUE); - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - } -#ifdef RTMP_MAC_PCI - pAd->bPCIclkOff = FALSE; -#endif /* RTMP_MAC_PCI // */ - - if (ADHOC_ON(pAd)) /* Adhoc mode link down */ - { - DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n")); - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); - pAd->IndicateMediaState = NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_DOWN; - BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, - pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - (" MacTab.Size=%d !\n", pAd->MacTab.Size)); - } else /* Infra structure mode */ - { - DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n")); - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); - - /* Saved last SSID for linkup comparison */ - pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen; - NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, - pAd->CommonCfg.LastSsidLen); - COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid); - if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) { - pAd->IndicateMediaState = NdisMediaStateDisconnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_DOWN; - DBGPRINT(RT_DEBUG_TRACE, - ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n")); - pAd->MlmeAux.CurrReqIsFromNdis = FALSE; - } else { - /* */ - /* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */ - /* Otherwise lost beacon or receive De-Authentication from AP, */ - /* then we should delete BSSID from BssTable. */ - /* If we don't delete from entry, roaming will fail. */ - /* */ - BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, - pAd->CommonCfg.Channel); - } - - /* restore back to - */ - /* 1. long slot (20 us) or short slot (9 us) time */ - /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */ - /* 3. short preamble */ - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); - - } - - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { - if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) - MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, - pAd->MacTab.Content[i].Addr); - } - - AsicSetSlotTime(pAd, TRUE); /*FALSE); */ - AsicSetEdcaParm(pAd, NULL); - - /* Set LED */ - RTMPSetLED(pAd, LED_LINK_DOWN); - pAd->LedIndicatorStrength = 0xF0; - RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware has not done it. */ - - AsicDisableSync(pAd); - - pAd->Mlme.PeriodicRound = 0; - pAd->Mlme.OneSecPeriodicRound = 0; - - if (pAd->StaCfg.BssType == BSS_INFRA) { - /* Remove StaCfg Information after link down */ - NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN); - NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID); - pAd->CommonCfg.SsidLen = 0; - } - - NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie)); - NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie)); - pAd->MlmeAux.HtCapabilityLen = 0; - pAd->MlmeAux.NewExtChannelOffset = 0xff; - - /* Reset WPA-PSK state. Only reset when supplicant enabled */ - if (pAd->StaCfg.WpaState != SS_NOTUSE) { - pAd->StaCfg.WpaState = SS_START; - /* Clear Replay counter */ - NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); - - } - /* */ - /* if link down come from AP, we need to remove all WPA keys on WPA mode. */ - /* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */ - /* */ - if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) { - /* Remove all WPA keys */ - RTMPWPARemoveAllKeys(pAd); - } - /* 802.1x port control */ - - /* Prevent clear PortSecured here with static WEP */ - /* NetworkManger set security policy first then set SSID to connect AP. */ - if (pAd->StaCfg.WpaSupplicantUP && - (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && - (pAd->StaCfg.IEEE8021X == FALSE)) { - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; - } else { - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP; - } - - NdisAcquireSpinLock(&pAd->MacTabLock); - NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table)); - pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured; - NdisReleaseSpinLock(&pAd->MacTabLock); - - pAd->StaCfg.MicErrCnt = 0; - - pAd->IndicateMediaState = NdisMediaStateDisconnected; - /* Update extra information to link is up */ - pAd->ExtraInfo = GENERAL_LINK_DOWN; - - pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; - -#ifdef RTMP_MAC_USB - pAd->bUsbTxBulkAggre = FALSE; -#endif /* RTMP_MAC_USB // */ - - /* Clean association information */ - NdisZeroMemory(&pAd->StaCfg.AssocInfo, - sizeof(struct rt_ndis_802_11_association_information)); - pAd->StaCfg.AssocInfo.Length = - sizeof(struct rt_ndis_802_11_association_information); - pAd->StaCfg.ReqVarIELen = 0; - pAd->StaCfg.ResVarIELen = 0; - - /* */ - /* Reset RSSI value after link down */ - /* */ - pAd->StaCfg.RssiSample.AvgRssi0 = 0; - pAd->StaCfg.RssiSample.AvgRssi0X8 = 0; - pAd->StaCfg.RssiSample.AvgRssi1 = 0; - pAd->StaCfg.RssiSample.AvgRssi1X8 = 0; - pAd->StaCfg.RssiSample.AvgRssi2 = 0; - pAd->StaCfg.RssiSample.AvgRssi2X8 = 0; - - /* Restore MlmeRate */ - pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate; - pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate; - - /* */ - /* After Link down, reset piggy-back setting in ASIC. Disable RDG. */ - /* */ - if (pAd->CommonCfg.BBPCurrentBW == BW_40) { - pAd->CommonCfg.BBPCurrentBW = BW_20; - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue); - ByteValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue); - } - /* Reset DAC */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue); - ByteValue &= (~0x18); - if (pAd->Antenna.field.TxPath == 2) { - ByteValue |= 0x10; - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue); - - RTMPSetPiggyBack(pAd, FALSE); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED); - - pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word; - - /* Restore all settings in the following. */ - AsicUpdateProtect(pAd, 0, - (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT), - TRUE, FALSE); - AsicDisableRDG(pAd); - pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE; - pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE; - - RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - -/* Allow go to sleep after linkdown steps. */ - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - - RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); - -#ifdef RT30xx - if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd)) - && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) { - RTMP_ASIC_MMPS_DISABLE(pAd); - } -#endif /* RT30xx // */ -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void IterateOnBssTab(struct rt_rtmp_adapter *pAd) -{ - struct rt_mlme_start_req StartReq; - struct rt_mlme_join_req JoinReq; - unsigned long BssIdx; - - /* Change the wepstatus to original wepstatus */ - pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus; - pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus; - pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus; - - BssIdx = pAd->MlmeAux.BssIdx; - if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) { - /* Check cipher suite, AP must have more secured cipher than station setting */ - /* Set the Pairwise and Group cipher to match the intended AP setting */ - /* We can only connect to AP with less secured cipher setting */ - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) - || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { - pAd->StaCfg.GroupCipher = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA. - GroupCipher; - - if (pAd->StaCfg.WepStatus == - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA. - PairCipher) - pAd->StaCfg.PairCipher = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. - WPA.PairCipher; - else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA. - PairCipherAux != Ndis802_11WEPDisabled) - pAd->StaCfg.PairCipher = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. - WPA.PairCipherAux; - else /* There is no PairCipher Aux, downgrade our capability to TKIP */ - pAd->StaCfg.PairCipher = - Ndis802_11Encryption2Enabled; - } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) - || (pAd->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2PSK)) { - pAd->StaCfg.GroupCipher = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. - GroupCipher; - - if (pAd->StaCfg.WepStatus == - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. - PairCipher) - pAd->StaCfg.PairCipher = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. - WPA2.PairCipher; - else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. - PairCipherAux != Ndis802_11WEPDisabled) - pAd->StaCfg.PairCipher = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx]. - WPA2.PairCipherAux; - else /* There is no PairCipher Aux, downgrade our capability to TKIP */ - pAd->StaCfg.PairCipher = - Ndis802_11Encryption2Enabled; - - /* RSN capability */ - pAd->StaCfg.RsnCapability = - pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2. - RsnCapability; - } - /* Set Mix cipher flag */ - pAd->StaCfg.bMixCipher = - (pAd->StaCfg.PairCipher == - pAd->StaCfg.GroupCipher) ? FALSE : TRUE; - /*if (pAd->StaCfg.bMixCipher == TRUE) - { - // If mix cipher, re-build RSNIE - RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); - } */ - - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - iterate BSS %ld of %d\n", BssIdx, - pAd->MlmeAux.SsidBssTab.BssNr)); - JoinParmFill(pAd, &JoinReq, BssIdx); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, - sizeof(struct rt_mlme_join_req), &JoinReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; - } else if (pAd->StaCfg.BssType == BSS_ADHOC) { - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n", - pAd->MlmeAux.Ssid)); - StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, - sizeof(struct rt_mlme_start_req), &StartReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; - } else /* no more BSS */ - { - - { - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n", - pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); - } - - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - } -} - -/* for re-association only */ -/* IRQL = DISPATCH_LEVEL */ -void IterateOnBssTab2(struct rt_rtmp_adapter *pAd) -{ - struct rt_mlme_assoc_req ReassocReq; - unsigned long BssIdx; - struct rt_bss_entry *pBss; - - BssIdx = pAd->MlmeAux.RoamIdx; - pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx]; - - if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) { - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - iterate BSS %ld of %d\n", BssIdx, - pAd->MlmeAux.RoamTab.BssNr)); - - AsicSwitchChannel(pAd, pBss->Channel, FALSE); - AsicLockChannel(pAd, pBss->Channel); - - /* reassociate message has the same structure as associate message */ - AssocParmFill(pAd, &ReassocReq, pBss->Bssid, - pBss->CapabilityInfo, ASSOC_TIMEOUT, - pAd->StaCfg.DefaultListenCount); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ, - sizeof(struct rt_mlme_assoc_req), &ReassocReq); - - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC; - } else /* no more BSS */ - { - - { - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n", - pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); - } - - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - } -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void JoinParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_join_req *JoinReq, unsigned long BssIdx) -{ - JoinReq->BssIdx = BssIdx; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void ScanParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_scan_req *ScanReq, - char Ssid[], - u8 SsidLen, u8 BssType, u8 ScanType) -{ - NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID); - ScanReq->SsidLen = SsidLen; - NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen); - ScanReq->BssType = BssType; - ScanReq->ScanType = ScanType; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void StartParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_start_req *StartReq, - char Ssid[], u8 SsidLen) -{ - ASSERT(SsidLen <= MAX_LEN_OF_SSID); - NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen); - StartReq->SsidLen = SsidLen; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -void AuthParmFill(struct rt_rtmp_adapter *pAd, - struct rt_mlme_auth_req *AuthReq, - u8 *pAddr, u16 Alg) -{ - COPY_MAC_ADDR(AuthReq->Addr, pAddr); - AuthReq->Alg = Alg; - AuthReq->Timeout = AUTH_TIMEOUT; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -#ifdef RTMP_MAC_PCI -void ComposePsPoll(struct rt_rtmp_adapter *pAd) -{ - NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame)); - pAd->PsPollFrame.FC.Type = BTYPE_CNTL; - pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; - pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; - COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); - COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); -} - -/* IRQL = DISPATCH_LEVEL */ -void ComposeNullFrame(struct rt_rtmp_adapter *pAd) -{ - NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11)); - pAd->NullFrame.FC.Type = BTYPE_DATA; - pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; - pAd->NullFrame.FC.ToDs = 1; - COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); - COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); - COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); -} -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg) -{ - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16), - &Msg); -} - -void ComposePsPoll(struct rt_rtmp_adapter *pAd) -{ - struct rt_txinfo *pTxInfo; - struct rt_txwi * pTxWI; - - DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n")); - NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame)); - - pAd->PsPollFrame.FC.PwrMgmt = 0; - pAd->PsPollFrame.FC.Type = BTYPE_CNTL; - pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; - pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; - COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); - COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); - - RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field. - WirelessPacket[0], 100); - pTxInfo = - (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field. - WirelessPacket[0]; - RTMPWriteTxInfo(pAd, pTxInfo, - (u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE, - EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - pTxWI = - (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field. - WirelessPacket[TXINFO_SIZE]; - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, - BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0, - (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, - IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); - RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field. - WirelessPacket[TXWI_SIZE + TXINFO_SIZE], - &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame)); - /* Append 4 extra zero bytes. */ - pAd->PsPollContext.BulkOutSize = - TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4; -} - -/* IRQL = DISPATCH_LEVEL */ -void ComposeNullFrame(struct rt_rtmp_adapter *pAd) -{ - struct rt_txinfo *pTxInfo; - struct rt_txwi * pTxWI; - - NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11)); - pAd->NullFrame.FC.Type = BTYPE_DATA; - pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; - pAd->NullFrame.FC.ToDs = 1; - COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); - COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); - COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); - RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field. - WirelessPacket[0], 100); - pTxInfo = - (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field. - WirelessPacket[0]; - RTMPWriteTxInfo(pAd, pTxInfo, - (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE, - EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - pTxWI = - (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field. - WirelessPacket[TXINFO_SIZE]; - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, - BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0, - (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, - IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); - RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field. - WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame, - sizeof(struct rt_header_802_11)); - pAd->NullContext.BulkOutSize = - TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; -} -#endif /* RTMP_MAC_USB // */ - -/* - ========================================================================== - Description: - Pre-build a BEACON frame in the shared memory - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== -*/ -unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd) -{ - u8 DsLen = 1, IbssLen = 2; - u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 }; - struct rt_header_802_11 BcnHdr; - u16 CapabilityInfo; - LARGE_INTEGER FakeTimestamp; - unsigned long FrameLen = 0; - struct rt_txwi * pTxWI = &pAd->BeaconTxWI; - u8 *pBeaconFrame = pAd->BeaconBuf; - BOOLEAN Privacy; - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen = 0; - u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 ExtRateLen = 0; - u8 RSNIe = IE_WPA; - - if ((pAd->CommonCfg.PhyMode == PHY_11B) - && (pAd->CommonCfg.Channel <= 14)) { - SupRate[0] = 0x82; /* 1 mbps */ - SupRate[1] = 0x84; /* 2 mbps */ - SupRate[2] = 0x8b; /* 5.5 mbps */ - SupRate[3] = 0x96; /* 11 mbps */ - SupRateLen = 4; - ExtRateLen = 0; - } else if (pAd->CommonCfg.Channel > 14) { - SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */ - SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ - SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */ - SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ - SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */ - SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ - SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ - SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ - SupRateLen = 8; - ExtRateLen = 0; - - /* */ - /* Also Update MlmeRate & RtsRate for G only & A only */ - /* */ - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.RtsRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = - MODE_OFDM; - pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = - OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - } else { - SupRate[0] = 0x82; /* 1 mbps */ - SupRate[1] = 0x84; /* 2 mbps */ - SupRate[2] = 0x8b; /* 5.5 mbps */ - SupRate[3] = 0x96; /* 11 mbps */ - SupRateLen = 4; - - ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps, */ - ExtRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ - ExtRate[2] = 0x18; /* 12 mbps, in units of 0.5 Mbps, */ - ExtRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ - ExtRate[4] = 0x30; /* 24 mbps, in units of 0.5 Mbps, */ - ExtRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ - ExtRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ - ExtRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ - ExtRateLen = 8; - } - - pAd->StaActive.SupRateLen = SupRateLen; - NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen); - pAd->StaActive.ExtRateLen = ExtRateLen; - NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen); - - /* compose IBSS beacon frame */ - MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, - pAd->CommonCfg.Bssid); - Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) - || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) - || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); - CapabilityInfo = - CAP_GENERATE(0, 1, Privacy, - (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), - 0, 0); - - MakeOutgoingFrame(pBeaconFrame, &FrameLen, - sizeof(struct rt_header_802_11), &BcnHdr, - TIMESTAMP_LEN, &FakeTimestamp, - 2, &pAd->CommonCfg.BeaconPeriod, - 2, &CapabilityInfo, - 1, &SsidIe, - 1, &pAd->CommonCfg.SsidLen, - pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, - 1, &SupRateIe, - 1, &SupRateLen, - SupRateLen, SupRate, - 1, &DsIe, - 1, &DsLen, - 1, &pAd->CommonCfg.Channel, - 1, &IbssIe, - 1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS); - - /* add ERP_IE and EXT_RAE IE of in 802.11g */ - if (ExtRateLen) { - unsigned long tmp; - - MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp, - 3, LocalErpIe, - 1, &ExtRateIe, - 1, &ExtRateLen, - ExtRateLen, ExtRate, END_OF_ARGS); - FrameLen += tmp; - } - /* If adhoc secruity is set for WPA-None, append the cipher suite IE */ - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { - unsigned long tmp; - RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, - BSS0); - - MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp, - 1, &RSNIe, - 1, &pAd->StaCfg.RSNIE_Len, - pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE, - END_OF_ARGS); - FrameLen += tmp; - } - - if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { - unsigned long TmpLen; - u8 HtLen, HtLen1; - - /* add HT Capability IE */ - HtLen = sizeof(pAd->CommonCfg.HtCapability); - HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo); - - MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, - 1, &HtCapIe, - 1, &HtLen, - HtLen, &pAd->CommonCfg.HtCapability, - 1, &AddHtInfoIe, - 1, &HtLen1, - HtLen1, &pAd->CommonCfg.AddHTInfo, - END_OF_ARGS); - - FrameLen += TmpLen; - } - /*beacon use reserved WCID 0xff */ - if (pAd->CommonCfg.Channel > 14) { - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, - TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON, - RATE_1, IFS_HTTXOP, FALSE, - &pAd->CommonCfg.MlmeTransmit); - } else { - /* Set to use 1Mbps for Adhoc beacon. */ - HTTRANSMIT_SETTING Transmit; - Transmit.word = 0; - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, - TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON, - RATE_1, IFS_HTTXOP, FALSE, &Transmit); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n", - FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, - pAd->CommonCfg.PhyMode)); - return FrameLen; -} diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c deleted file mode 100644 index e82c6b669eb2..000000000000 --- a/drivers/staging/rt2860/sta/rtmp_data.c +++ /dev/null @@ -1,2552 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtmp_data.c - - Abstract: - Data path subroutines - - Revision History: - Who When What - Justin P. Mattock 11/07/2010 Fix typos - -------- ---------- ---------------------------------------------- -*/ -#include "../rt_config.h" -#include - -void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); - struct rt_rxwi * pRxWI = pRxBlk->pRxWI; - u8 *pTmpBuf; - - if (pAd->StaCfg.WpaSupplicantUP) { - /* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */ - /* TBD : process fragmented EAPol frames */ - { - /* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */ - if (pAd->StaCfg.IEEE8021X == TRUE && - (EAP_CODE_SUCCESS == - WpaCheckEapCode(pAd, pRxBlk->pData, - pRxBlk->DataSize, - LENGTH_802_1_H))) { - u8 *Key; - u8 CipherAlg; - int idx = 0; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("Receive EAP-SUCCESS Packet\n")); - /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAd); - - if (pAd->StaCfg.IEEE8021x_required_keys == - FALSE) { - idx = pAd->StaCfg.DesireSharedKeyId; - CipherAlg = - pAd->StaCfg.DesireSharedKey[idx]. - CipherAlg; - Key = - pAd->StaCfg.DesireSharedKey[idx]. - Key; - - if (pAd->StaCfg.DesireSharedKey[idx]. - KeyLen > 0) { -#ifdef RTMP_MAC_PCI - struct rt_mac_table_entry *pEntry = - &pAd->MacTab. - Content[BSSID_WCID]; - - /* Set key material and cipherAlg to Asic */ - AsicAddSharedKeyEntry(pAd, BSS0, - idx, - CipherAlg, - Key, NULL, - NULL); - - /* Assign group key info */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - idx, - CipherAlg, - NULL); - - /* Assign pairwise key info */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - idx, - CipherAlg, - pEntry); - - pAd->IndicateMediaState = - NdisMediaStateConnected; - pAd->ExtraInfo = - GENERAL_LINK_UP; -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - union { - char buf[sizeof - (struct rt_ndis_802_11_wep) - + - MAX_LEN_OF_KEY - - 1]; - struct rt_ndis_802_11_wep keyinfo; - } - WepKey; - int len; - - NdisZeroMemory(&WepKey, - sizeof(WepKey)); - len = - pAd->StaCfg. - DesireSharedKey[idx].KeyLen; - - NdisMoveMemory(WepKey.keyinfo. - KeyMaterial, - pAd->StaCfg. - DesireSharedKey - [idx].Key, - pAd->StaCfg. - DesireSharedKey - [idx].KeyLen); - - WepKey.keyinfo.KeyIndex = - 0x80000000 + idx; - WepKey.keyinfo.KeyLength = len; - pAd->SharedKey[BSS0][idx]. - KeyLen = - (u8)(len <= 5 ? 5 : 13); - - pAd->IndicateMediaState = - NdisMediaStateConnected; - pAd->ExtraInfo = - GENERAL_LINK_UP; - /* need to enqueue cmd to thread */ - RTUSBEnqueueCmdFromNdis(pAd, - OID_802_11_ADD_WEP, - TRUE, - &WepKey, - sizeof - (WepKey. - keyinfo) - + len - - 1); -#endif /* RTMP_MAC_USB // */ - /* For Preventing ShardKey Table is cleared by remove key procedure. */ - pAd->SharedKey[BSS0][idx]. - CipherAlg = CipherAlg; - pAd->SharedKey[BSS0][idx]. - KeyLen = - pAd->StaCfg. - DesireSharedKey[idx].KeyLen; - NdisMoveMemory(pAd-> - SharedKey[BSS0] - [idx].Key, - pAd->StaCfg. - DesireSharedKey - [idx].Key, - pAd->StaCfg. - DesireSharedKey - [idx].KeyLen); - } - } - } - - Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); - return; - } - } else { - /* Special DATA frame that has to pass to MLME */ - /* 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process */ - /* 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process */ - { - pTmpBuf = pRxBlk->pData - LENGTH_802_11; - NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11); - REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, - pTmpBuf, - pRxBlk->DataSize + - LENGTH_802_11, pRxWI->RSSI0, - pRxWI->RSSI1, pRxWI->RSSI2, - pRxD->PlcpSignal); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("report EAPOL/AIRONET DATA to MLME (len=%d) !\n", - pRxBlk->DataSize)); - } - } - - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE); - return; - -} - -void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID) -{ - - /* non-EAP frame */ - if (!RTMPCheckWPAframe - (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) { - - { - /* drop all non-EAP DATA frame before */ - /* this client's Port-Access-Control is secured */ - if (pRxBlk->pHeader->FC.Wep) { - /* unsupported cipher suite */ - if (pAd->StaCfg.WepStatus == - Ndis802_11EncryptionDisabled) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, - pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - } else { - /* encryption in-use but receive a non-EAPOL clear text frame, drop it */ - if ((pAd->StaCfg.WepStatus != - Ndis802_11EncryptionDisabled) - && (pAd->StaCfg.PortSecured == - WPA_802_1X_PORT_NOT_SECURED)) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, - pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - } - } - RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP); - if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) { - /* Normal legacy, AMPDU or AMSDU */ - CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, - FromWhichBSSID); - - } else { - /* ARALINK */ - CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, - FromWhichBSSID); - } - } else { - RX_BLK_SET_FLAG(pRxBlk, fRX_EAP); - - if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) - && (pAd->CommonCfg.bDisableReordering == 0)) { - Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID); - } else { - /* Determine the destination of the EAP frame */ - /* to WPA state machine or upper layer */ - STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, - FromWhichBSSID); - } - } -} - -/* For TKIP frame, calculate the MIC value */ -BOOLEAN STACheckTkipMICValue(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_rx_blk *pRxBlk) -{ - struct rt_header_802_11 * pHeader = pRxBlk->pHeader; - u8 *pData = pRxBlk->pData; - u16 DataSize = pRxBlk->DataSize; - u8 UserPriority = pRxBlk->UserPriority; - struct rt_cipher_key *pWpaKey; - u8 *pDA, *pSA; - - pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex]; - - pDA = pHeader->Addr1; - if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) { - pSA = pHeader->Addr3; - } else { - pSA = pHeader->Addr2; - } - - if (RTMPTkipCompareMICValue(pAd, - pData, - pDA, - pSA, - pWpaKey->RxMic, - UserPriority, DataSize) == FALSE) { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n")); - - if (pAd->StaCfg.WpaSupplicantUP) { - WpaSendMicFailureToWpaSupplicant(pAd, - (pWpaKey->Type == - PAIRWISEKEY) ? TRUE : - FALSE); - } else { - RTMPReportMicError(pAd, pWpaKey); - } - - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, - NDIS_STATUS_FAILURE); - return FALSE; - } - - return TRUE; -} - -/* */ -/* All Rx routines use struct rt_rx_blk structure to hande rx events */ -/* It is very important to build pRxBlk attributes */ -/* 1. pHeader pointer to 802.11 Header */ -/* 2. pData pointer to payload including LLC (just skip Header) */ -/* 3. set payload size including LLC to DataSize */ -/* 4. set some flags with RX_BLK_SET_FLAG() */ -/* */ -void STAHandleRxDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) -{ - PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); - struct rt_rxwi * pRxWI = pRxBlk->pRxWI; - struct rt_header_802_11 * pHeader = pRxBlk->pHeader; - void *pRxPacket = pRxBlk->pRxPacket; - BOOLEAN bFragment = FALSE; - struct rt_mac_table_entry *pEntry = NULL; - u8 FromWhichBSSID = BSS0; - u8 UserPriority = 0; - - { - /* before LINK UP, all DATA frames are rejected */ - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - /* Drop not my BSS frames */ - if (pRxD->MyBss == 0) { - { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - } - - pAd->RalinkCounters.RxCountSinceLastNULL++; - if (pAd->CommonCfg.bAPSDCapable - && pAd->CommonCfg.APEdcaParm.bAPSDCapable - && (pHeader->FC.SubType & 0x08)) { - u8 *pData; - DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n")); - - /* Qos bit 4 */ - pData = (u8 *)pHeader + LENGTH_802_11; - if ((*pData >> 4) & 0x01) { - DBGPRINT(RT_DEBUG_INFO, - ("RxDone- Rcv EOSP frame, driver may fall into sleep\n")); - pAd->CommonCfg.bInServicePeriod = FALSE; - - /* Force driver to fall into sleep mode when rcv EOSP frame */ - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - u16 TbttNumToNextWakeUp; - u16 NextDtim = - pAd->StaCfg.DtimPeriod; - unsigned long Now; - - NdisGetSystemUpTime(&Now); - NextDtim -= - (u16)(Now - - pAd->StaCfg. - LastBeaconRxTime) / - pAd->CommonCfg.BeaconPeriod; - - TbttNumToNextWakeUp = - pAd->StaCfg.DefaultListenCount; - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_RECEIVE_DTIM) - && (TbttNumToNextWakeUp > NextDtim)) - TbttNumToNextWakeUp = NextDtim; - - RTMP_SET_PSM_BIT(pAd, PWR_SAVE); - /* if WMM-APSD is failed, try to disable following line */ - AsicSleepThenAutoWakeup(pAd, - TbttNumToNextWakeUp); - } - } - - if ((pHeader->FC.MoreData) - && (pAd->CommonCfg.bInServicePeriod)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Sending another trigger frame when More Data bit is set to 1\n")); - } - } - /* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */ - if ((pHeader->FC.SubType & 0x04)) /* bit 2 : no DATA */ - { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - /* Drop not my BSS frame (we can not only check the MyBss bit in RxD) */ - - if (INFRA_ON(pAd)) { - /* Infrastructure mode, check address 2 for BSSID */ - if (!RTMPEqualMemory - (&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6)) { - /* Receive frame not my BSSID */ - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - } else /* Ad-Hoc mode or Not associated */ - { - /* Ad-Hoc mode, check address 3 for BSSID */ - if (!RTMPEqualMemory - (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) { - /* Receive frame not my BSSID */ - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - } - - /* */ - /* find pEntry */ - /* */ - if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) { - pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; - } else { - /* 1. release packet if infra mode */ - /* 2. new a pEntry if ad-hoc mode */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - - /* infra or ad-hoc */ - if (INFRA_ON(pAd)) { - RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA); - ASSERT(pRxWI->WirelessCliID == BSSID_WCID); - } - /* check Atheros Client */ - if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) - && (pHeader->FC.Retry)) { - pEntry->bIAmBadAtheros = TRUE; - pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE; - pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE; - if (!STA_AES_ON(pAd)) { - AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, - FALSE); - } - } - } - - pRxBlk->pData = (u8 *) pHeader; - - /* */ - /* update RxBlk->pData, DataSize */ - /* 802.11 Header, QOS, HTC, Hw Padding */ - /* */ - - /* 1. skip 802.11 HEADER */ - { - pRxBlk->pData += LENGTH_802_11; - pRxBlk->DataSize -= LENGTH_802_11; - } - - /* 2. QOS */ - if (pHeader->FC.SubType & 0x08) { - RX_BLK_SET_FLAG(pRxBlk, fRX_QOS); - UserPriority = *(pRxBlk->pData) & 0x0f; - /* bit 7 in QoS Control field signals the HT A-MSDU format */ - if ((*pRxBlk->pData) & 0x80) { - RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU); - } - /* skip QOS contorl field */ - pRxBlk->pData += 2; - pRxBlk->DataSize -= 2; - } - pRxBlk->UserPriority = UserPriority; - - /* check if need to resend PS Poll when received packet with MoreData = 1 */ - if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) { - if ((((UserPriority == 0) || (UserPriority == 3)) && - pAd->CommonCfg.bAPSDAC_BE == 0) || - (((UserPriority == 1) || (UserPriority == 2)) && - pAd->CommonCfg.bAPSDAC_BK == 0) || - (((UserPriority == 4) || (UserPriority == 5)) && - pAd->CommonCfg.bAPSDAC_VI == 0) || - (((UserPriority == 6) || (UserPriority == 7)) && - pAd->CommonCfg.bAPSDAC_VO == 0)) { - /* non-UAPSD delivery-enabled AC */ - RTMP_PS_POLL_ENQUEUE(pAd); - } - } - /* 3. Order bit: A-Ralink or HTC+ */ - if (pHeader->FC.Order) { -#ifdef AGGREGATION_SUPPORT - if ((pRxWI->PHYMODE <= MODE_OFDM) - && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))) - { - RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK); - } else -#endif /* AGGREGATION_SUPPORT // */ - { - RX_BLK_SET_FLAG(pRxBlk, fRX_HTC); - /* skip HTC contorl field */ - pRxBlk->pData += 4; - pRxBlk->DataSize -= 4; - } - } - /* 4. skip HW padding */ - if (pRxD->L2PAD) { - /* just move pData pointer */ - /* because DataSize excluding HW padding */ - RX_BLK_SET_FLAG(pRxBlk, fRX_PAD); - pRxBlk->pData += 2; - } - - if (pRxD->BA) { - RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU); - } - /* */ - /* Case I Process Broadcast & Multicast data frame */ - /* */ - if (pRxD->Bcast || pRxD->Mcast) { - INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount); - - /* Drop Mcast/Bcast frame with fragment bit on */ - if (pHeader->FC.MoreFrag) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - /* Filter out Bcast frame which AP relayed for us */ - if (pHeader->FC.FrDs - && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - return; - } - - Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); - return; - } else if (pRxD->U2M) { - pAd->LastRxRate = - (u16)((pRxWI->MCS) + (pRxWI->BW << 7) + - (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14)); - - if (ADHOC_ON(pAd)) { - pEntry = MacTableLookup(pAd, pHeader->Addr2); - if (pEntry) - Update_Rssi_Sample(pAd, &pEntry->RssiSample, - pRxWI); - } - - Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); - - pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0); - pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1); - - pAd->RalinkCounters.OneSecRxOkDataCnt++; - - if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) { - /* re-assemble the fragmented packets */ - /* return complete frame (pRxPacket) or NULL */ - bFragment = TRUE; - pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk); - } - - if (pRxPacket) { - pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; - - /* process complete frame */ - if (bFragment && (pRxD->Decrypted) - && (pEntry->WepStatus == - Ndis802_11Encryption2Enabled)) { - /* Minus MIC length */ - pRxBlk->DataSize -= 8; - - /* For TKIP frame, calculate the MIC value */ - if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == - FALSE) { - return; - } - } - - STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, - FromWhichBSSID); - return; - } else { - /* just return */ - /* because RTMPDeFragmentDataFrame() will release rx packet, */ - /* if packet is fragmented */ - return; - } - } - - ASSERT(0); - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); -} - -void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) -{ - PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); - struct rt_rxwi * pRxWI = pRxBlk->pRxWI; - struct rt_header_802_11 * pHeader = pRxBlk->pHeader; - void *pRxPacket = pRxBlk->pRxPacket; - - do { - - /* check if need to resend PS Poll when received packet with MoreData = 1 */ - if ((pAd->StaCfg.Psm == PWR_SAVE) - && (pHeader->FC.MoreData == 1)) { - /* for UAPSD, all management frames will be VO priority */ - if (pAd->CommonCfg.bAPSDAC_VO == 0) { - /* non-UAPSD delivery-enabled AC */ - RTMP_PS_POLL_ENQUEUE(pAd); - } - } - - /* TODO: if MoreData == 0, station can go to sleep */ - - /* We should collect RSSI not only U2M data but also my beacon */ - if ((pHeader->FC.SubType == SUBTYPE_BEACON) - && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) - && (pAd->RxAnt.EvaluatePeriod == 0)) { - Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); - - pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0); - pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1); - } - - /* First check the size, it MUST not exceed the mlme queue size */ - if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount); - break; - } - - REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, - pRxWI->MPDUtotalByteCount, - pRxWI->RSSI0, pRxWI->RSSI1, - pRxWI->RSSI2, pRxD->PlcpSignal); - } while (FALSE); - - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS); -} - -void STAHandleRxControlFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) -{ - struct rt_rxwi * pRxWI = pRxBlk->pRxWI; - struct rt_header_802_11 * pHeader = pRxBlk->pHeader; - void *pRxPacket = pRxBlk->pRxPacket; - - switch (pHeader->FC.SubType) { - case SUBTYPE_BLOCK_ACK_REQ: - { - CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, - (pRxWI->MPDUtotalByteCount), - (struct rt_frame_ba_req *) pHeader); - } - break; - case SUBTYPE_BLOCK_ACK: - case SUBTYPE_ACK: - default: - break; - } - - RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); -} - -/* - ======================================================================== - - Routine Description: - Process RxDone interrupt, running in DPC level - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - This routine has to maintain Rx ring read pointer. - Need to consider QOS DATA format when converting to 802.3 - ======================================================================== -*/ -BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc) -{ - int Status; - u32 RxProcessed, RxPending; - BOOLEAN bReschedule = FALSE; - PRT28XX_RXD_STRUC pRxD; - u8 *pData; - struct rt_rxwi * pRxWI; - void *pRxPacket; - struct rt_header_802_11 * pHeader; - struct rt_rx_blk RxCell; - - RxProcessed = RxPending = 0; - - /* process whole rx ring */ - while (1) { - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST) || - !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { - break; - } -#ifdef RTMP_MAC_PCI - if (RxProcessed++ > MAX_RX_PROCESS_CNT) { - /* need to reschedule rx handle */ - bReschedule = TRUE; - break; - } -#endif /* RTMP_MAC_PCI // */ - - RxProcessed++; /* test */ - - /* 1. allocate a new data packet into rx ring to replace received packet */ - /* then processing the received packet */ - /* 2. the callee must take charge of release of packet */ - /* 3. As far as driver is concerned , */ - /* the rx packet must */ - /* a. be indicated to upper layer or */ - /* b. be released if it is discarded */ - pRxPacket = - GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, - &RxPending); - if (pRxPacket == NULL) { - /* no more packet to process */ - break; - } - /* get rx ring descriptor */ - pRxD = &(RxCell.RxD); - /* get rx data buffer */ - pData = GET_OS_PKT_DATAPTR(pRxPacket); - pRxWI = (struct rt_rxwi *) pData; - pHeader = (struct rt_header_802_11 *) (pData + RXWI_SIZE); - - /* build RxCell */ - RxCell.pRxWI = pRxWI; - RxCell.pHeader = pHeader; - RxCell.pRxPacket = pRxPacket; - RxCell.pData = (u8 *) pHeader; - RxCell.DataSize = pRxWI->MPDUtotalByteCount; - RxCell.Flags = 0; - - /* Increase Total receive byte counter after real data received no mater any error or not */ - pAd->RalinkCounters.ReceivedByteCount += - pRxWI->MPDUtotalByteCount; - pAd->RalinkCounters.OneSecReceivedByteCount += - pRxWI->MPDUtotalByteCount; - pAd->RalinkCounters.RxCount++; - - INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount); - - if (pRxWI->MPDUtotalByteCount < 14) - Status = NDIS_STATUS_FAILURE; - - if (MONITOR_ON(pAd)) { - send_monitor_packets(pAd, &RxCell); - break; - } - - /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */ - - /* Check for all RxD errors */ - Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD); - - /* Handle the received frame */ - if (Status == NDIS_STATUS_SUCCESS) { - switch (pHeader->FC.Type) { - /* CASE I, receive a DATA frame */ - case BTYPE_DATA: - { - /* process DATA frame */ - STAHandleRxDataFrame(pAd, &RxCell); - } - break; - /* CASE II, receive a MGMT frame */ - case BTYPE_MGMT: - { - STAHandleRxMgmtFrame(pAd, &RxCell); - } - break; - /* CASE III. receive a CNTL frame */ - case BTYPE_CNTL: - { - STAHandleRxControlFrame(pAd, &RxCell); - } - break; - /* discard other type */ - default: - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - break; - } - } else { - pAd->Counters8023.RxErrors++; - /* discard this frame */ - RELEASE_NDIS_PACKET(pAd, pRxPacket, - NDIS_STATUS_FAILURE); - } - } - - return bReschedule; -} - -/* - ======================================================================== - - Routine Description: - Arguments: - pAd Pointer to our adapter - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd) -{ - AsicForceWakeup(pAd, FALSE); -} - -/* -======================================================================== -Routine Description: - Early checking and OS-depened parsing for Tx packet send to our STA driver. - -Arguments: - void * MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd. - void ** ppPacketArray The packet array need to do transmission. - u32 NumberOfPackets Number of packet in packet array. - -Return Value: - NONE - -Note: - This function does early checking and classification for send-out packet. - You only can put OS-depened & STA related code in here. -======================================================================== -*/ -void STASendPackets(void *MiniportAdapterContext, - void **ppPacketArray, u32 NumberOfPackets) -{ - u32 Index; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)MiniportAdapterContext; - void *pPacket; - BOOLEAN allowToSend = FALSE; - - for (Index = 0; Index < NumberOfPackets; Index++) { - pPacket = ppPacketArray[Index]; - - do { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) - || RTMP_TEST_FLAG(pAd, - fRTMP_ADAPTER_HALT_IN_PROGRESS) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) { - /* Drop send request since hardware is in reset state */ - break; - } else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) { - /* Drop send request since there are no physical connection yet */ - break; - } else { - /* Record that orignal packet source is from NDIS layer,so that */ - /* later on driver knows how to release this NDIS PACKET */ - RTMP_SET_PACKET_WCID(pPacket, 0); /* this field is useless when in STA mode */ - RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); - NDIS_SET_PACKET_STATUS(pPacket, - NDIS_STATUS_PENDING); - pAd->RalinkCounters.PendingNdisPacketCount++; - - allowToSend = TRUE; - } - } while (FALSE); - - if (allowToSend == TRUE) - STASendPacket(pAd, pPacket); - else - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } - - /* Dequeue outgoing frames from TxSwQueue[] and process it */ - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - -} - -/* -======================================================================== -Routine Description: - This routine is used to do packet parsing and classification for Tx packet - to STA device, and it will en-queue packets to our TxSwQueue depends on AC - class. - -Arguments: - pAd Pointer to our adapter - pPacket Pointer to send packet - -Return Value: - NDIS_STATUS_SUCCESS If success to queue the packet into TxSwQueue. - NDIS_STATUS_FAILURE If failed to do en-queue. - -Note: - You only can put OS-indepened & STA related code in here. -======================================================================== -*/ -int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket) -{ - struct rt_packet_info PacketInfo; - u8 *pSrcBufVA; - u32 SrcBufLen; - u32 AllowFragSize; - u8 NumberOfFrag; - u8 RTSRequired; - u8 QueIdx, UserPriority; - struct rt_mac_table_entry *pEntry = NULL; - unsigned int IrqFlags; - u8 FlgIsIP = 0; - u8 Rate; - - /* Prepare packet information structure for buffer descriptor */ - /* chained within a single NDIS packet. */ - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - if (pSrcBufVA == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n", - SrcBufLen)); - /* Resource is low, system did not allocate virtual address */ - /* return NDIS_STATUS_FAILURE directly to upper layer */ - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - return NDIS_STATUS_FAILURE; - } - - if (SrcBufLen < 14) { - DBGPRINT(RT_DEBUG_ERROR, - ("STASendPacket --> Ndis Packet buffer error!\n")); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - return (NDIS_STATUS_FAILURE); - } - /* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */ - /* Note multicast packets in adhoc also use BSSID_WCID index. */ - { - if (INFRA_ON(pAd)) { - { - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID); - Rate = pAd->CommonCfg.TxRate; - } - } else if (ADHOC_ON(pAd)) { - if (*pSrcBufVA & 0x01) { - RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID); - pEntry = &pAd->MacTab.Content[MCAST_WCID]; - } else { - pEntry = MacTableLookup(pAd, pSrcBufVA); - } - Rate = pAd->CommonCfg.TxRate; - } - } - - if (!pEntry) { - DBGPRINT(RT_DEBUG_ERROR, - ("STASendPacket->Cannot find pEntry(%pM) in MacTab!\n", - pSrcBufVA)); - /* Resource is low, system did not allocate virtual address */ - /* return NDIS_STATUS_FAILURE directly to upper layer */ - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - return NDIS_STATUS_FAILURE; - } - - if (ADHOC_ON(pAd) - ) { - RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid); - } - /* */ - /* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */ - /* Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */ - RTMPCheckEtherType(pAd, pPacket); - - /* */ - /* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */ - /* */ - if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) - || (pAd->StaCfg.IEEE8021X == TRUE) - ) - && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) - || (pAd->StaCfg.MicErrCnt >= 2)) - && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE) - ) { - DBGPRINT(RT_DEBUG_TRACE, - ("STASendPacket --> Drop packet before port secured!\n")); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - - return (NDIS_STATUS_FAILURE); - } - - /* STEP 1. Decide number of fragments required to deliver this MSDU. */ - /* The estimation here is not very accurate because difficult to */ - /* take encryption overhead into consideration here. The result */ - /* "NumberOfFrag" is then just used to pre-check if enough free */ - /* TXD are available to hold this MSDU. */ - - if (*pSrcBufVA & 0x01) /* fragmentation not allowed on multicast & broadcast */ - NumberOfFrag = 1; - else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) - NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */ - else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED)) - NumberOfFrag = 1; /* Aggregation overwhelms fragmentation */ - else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) - || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD)) - NumberOfFrag = 1; /* MIMO RATE overwhelms fragmentation */ - else { - /* The calculated "NumberOfFrag" is a rough estimation because of various */ - /* encryption/encapsulation overhead not taken into consideration. This number is just */ - /* used to make sure enough free TXD are available before fragmentation takes place. */ - /* In case the actual required number of fragments of an NDIS packet */ - /* excceeds "NumberOfFrag"caculated here and not enough free TXD available, the */ - /* last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of */ - /* resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should */ - /* rarely happen and the penalty is just like a TX RETRY fail. Affordable. */ - - AllowFragSize = - (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - - LENGTH_CRC; - NumberOfFrag = - ((PacketInfo.TotalPacketLength - LENGTH_802_3 + - LENGTH_802_1_H) / AllowFragSize) + 1; - /* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */ - if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + - LENGTH_802_1_H) % AllowFragSize) == 0) { - NumberOfFrag--; - } - } - - /* Save fragment number to Ndis packet reserved field */ - RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag); - - /* STEP 2. Check the requirement of RTS: */ - /* If multiple fragment required, RTS is required only for the first fragment */ - /* if the fragment size is larger than RTS threshold */ - /* For RT28xx, Let ASIC send RTS/CTS */ - /* RTMP_SET_PACKET_RTS(pPacket, 0); */ - if (NumberOfFrag > 1) - RTSRequired = - (pAd->CommonCfg.FragmentThreshold > - pAd->CommonCfg.RtsThreshold) ? 1 : 0; - else - RTSRequired = - (PacketInfo.TotalPacketLength > - pAd->CommonCfg.RtsThreshold) ? 1 : 0; - - /* Save RTS requirement to Ndis packet reserved field */ - RTMP_SET_PACKET_RTS(pPacket, RTSRequired); - RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate); - - /* */ - /* STEP 3. Traffic classification. outcome = */ - /* */ - UserPriority = 0; - QueIdx = QID_AC_BE; - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && - CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) { - u16 Protocol; - u8 LlcSnapLen = 0, Byte0, Byte1; - do { - /* get Ethernet protocol field */ - Protocol = - (u16)((pSrcBufVA[12] << 8) + pSrcBufVA[13]); - if (Protocol <= 1500) { - /* get Ethernet protocol field from LLC/SNAP */ - if (Sniff2BytesFromNdisBuffer - (PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, - &Byte0, &Byte1) != NDIS_STATUS_SUCCESS) - break; - - Protocol = (u16)((Byte0 << 8) + Byte1); - LlcSnapLen = 8; - } - /* always AC_BE for non-IP packet */ - if (Protocol != 0x0800) - break; - - /* get IP header */ - if (Sniff2BytesFromNdisBuffer - (PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, - &Byte0, &Byte1) != NDIS_STATUS_SUCCESS) - break; - - /* return AC_BE if packet is not IPv4 */ - if ((Byte0 & 0xf0) != 0x40) - break; - - FlgIsIP = 1; - UserPriority = (Byte1 & 0xe0) >> 5; - QueIdx = MapUserPriorityToAccessCategory[UserPriority]; - - /* TODO: have to check ACM bit. apply TSPEC if ACM is ON */ - /* TODO: downgrade UP & QueIdx before passing ACM */ - /* - Under WMM ACM control, we dont need to check the bit; - Or when a TSPEC is built for VO but we will change to issue - BA session for BE here, so we will not use BA to send VO packets. - */ - if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) { - UserPriority = 0; - QueIdx = QID_AC_BE; - } - } while (FALSE); - } - - RTMP_SET_PACKET_UP(pPacket, UserPriority); - - /* Make sure SendTxWait queue resource won't be used by other threads */ - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) { - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - - return NDIS_STATUS_FAILURE; - } else { - InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx], - PACKET_TO_QUEUE_ENTRY(pPacket)); - } - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - - if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) && - IS_HT_STA(pEntry)) { - /*struct rt_mac_table_entry *pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; */ - if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) && - ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) && - (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) - /* For IOT compatibility, if */ - /* 1. It is Ralink chip or */ - /* 2. It is OPEN or AES mode, */ - /* then BA session can be bulit. */ - && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) - || (pEntry->WepStatus != Ndis802_11WEPEnabled - && pEntry->WepStatus != - Ndis802_11Encryption2Enabled)) - ) { - BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10, - FALSE); - } - } - - pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; /* TODO: for debug only. to be removed */ - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: - This subroutine will scan through relative ring descriptor to find - out available free ring descriptor and compare with request size. - - Arguments: - pAd Pointer to our adapter - QueIdx Selected TX Ring - - Return Value: - NDIS_STATUS_FAILURE Not enough free descriptor - NDIS_STATUS_SUCCESS Enough free descriptor - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -#ifdef RTMP_MAC_PCI -int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - u8 NumberRequired, u8 *FreeNumberIs) -{ - unsigned long FreeNumber = 0; - int Status = NDIS_STATUS_FAILURE; - - switch (QueIdx) { - case QID_AC_BK: - case QID_AC_BE: - case QID_AC_VI: - case QID_AC_VO: - if (pAd->TxRing[QueIdx].TxSwFreeIdx > - pAd->TxRing[QueIdx].TxCpuIdx) - FreeNumber = - pAd->TxRing[QueIdx].TxSwFreeIdx - - pAd->TxRing[QueIdx].TxCpuIdx - 1; - else - FreeNumber = - pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE - - pAd->TxRing[QueIdx].TxCpuIdx - 1; - - if (FreeNumber >= NumberRequired) - Status = NDIS_STATUS_SUCCESS; - break; - - case QID_MGMT: - if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx) - FreeNumber = - pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - - 1; - else - FreeNumber = - pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - - pAd->MgmtRing.TxCpuIdx - 1; - - if (FreeNumber >= NumberRequired) - Status = NDIS_STATUS_SUCCESS; - break; - - default: - DBGPRINT(RT_DEBUG_ERROR, - ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx)); - break; - } - *FreeNumberIs = (u8)FreeNumber; - - return (Status); -} -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -/* - Actually, this function used to check if the TxHardware Queue still has frame need to send. - If no frame need to send, go to sleep, else, still wake up. -*/ -int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd, - u8 QueIdx, - u8 NumberRequired, u8 *FreeNumberIs) -{ - /*unsigned long FreeNumber = 0; */ - int Status = NDIS_STATUS_FAILURE; - unsigned long IrqFlags; - struct rt_ht_tx_context *pHTTXContext; - - switch (QueIdx) { - case QID_AC_BK: - case QID_AC_BE: - case QID_AC_VI: - case QID_AC_VO: - { - pHTTXContext = &pAd->TxContext[QueIdx]; - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], - IrqFlags); - if ((pHTTXContext->CurWritePosition != - pHTTXContext->ENextBulkOutPosition) - || (pHTTXContext->IRPPending == TRUE)) { - Status = NDIS_STATUS_FAILURE; - } else { - Status = NDIS_STATUS_SUCCESS; - } - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], - IrqFlags); - } - break; - case QID_MGMT: - if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE) - Status = NDIS_STATUS_FAILURE; - else - Status = NDIS_STATUS_SUCCESS; - break; - default: - DBGPRINT(RT_DEBUG_ERROR, - ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx)); - break; - } - - return (Status); -} -#endif /* RTMP_MAC_USB // */ - -void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd) -{ -} - -void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd, - u8 TxRate, IN BOOLEAN bQosNull) -{ - u8 NullFrame[48]; - unsigned long Length; - struct rt_header_802_11 * pHeader_802_11; - - /* WPA 802.1x secured port control */ - if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) - || (pAd->StaCfg.IEEE8021X == TRUE) - ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) { - return; - } - - NdisZeroMemory(NullFrame, 48); - Length = sizeof(struct rt_header_802_11); - - pHeader_802_11 = (struct rt_header_802_11 *) NullFrame; - - pHeader_802_11->FC.Type = BTYPE_DATA; - pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC; - pHeader_802_11->FC.ToDs = 1; - COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid); - COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress); - COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid); - - if (pAd->CommonCfg.bAPSDForcePowerSave) { - pHeader_802_11->FC.PwrMgmt = PWR_SAVE; - } else { - pHeader_802_11->FC.PwrMgmt = - (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0; - } - pHeader_802_11->Duration = - pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14); - - pAd->Sequence++; - pHeader_802_11->Sequence = pAd->Sequence; - - /* Prepare QosNull function frame */ - if (bQosNull) { - pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL; - - /* copy QOS control bytes */ - NullFrame[Length] = 0; - NullFrame[Length + 1] = 0; - Length += 2; /* if pad with 2 bytes for alignment, APSD will fail */ - } - - HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length); - -} - -/* IRQL = DISPATCH_LEVEL */ -void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd, - u8 *pDA, - IN unsigned int NextMpduSize, - u8 TxRate, - u8 RTSRate, - u16 AckDuration, u8 QueIdx, u8 FrameGap) -{ -} - -/* -------------------------------------------------------- */ -/* FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM */ -/* Find the WPA key, either Group or Pairwise Key */ -/* LEAP + TKIP also use WPA key. */ -/* -------------------------------------------------------- */ -/* Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst */ -/* In Cisco CCX 2.0 Leap Authentication */ -/* WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey */ -/* Instead of the SharedKey, SharedKey Length may be Zero. */ -void STAFindCipherAlgorithm(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - NDIS_802_11_ENCRYPTION_STATUS Cipher; /* To indicate cipher used for this packet */ - u8 CipherAlg = CIPHER_NONE; /* cipher alogrithm */ - u8 KeyIdx = 0xff; - u8 *pSrcBufVA; - struct rt_cipher_key *pKey = NULL; - - pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket); - - { - /* Select Cipher */ - if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) - Cipher = pAd->StaCfg.GroupCipher; /* Cipher for Multicast or Broadcast */ - else - Cipher = pAd->StaCfg.PairCipher; /* Cipher for Unicast */ - - if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) { - ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= - CIPHER_CKIP128); - - /* 4-way handshaking frame must be clear */ - if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) - && (pAd->SharedKey[BSS0][0].CipherAlg) - && (pAd->SharedKey[BSS0][0].KeyLen)) { - CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; - KeyIdx = 0; - } - } else if (Cipher == Ndis802_11Encryption1Enabled) { - KeyIdx = pAd->StaCfg.DefaultKeyId; - } else if ((Cipher == Ndis802_11Encryption2Enabled) || - (Cipher == Ndis802_11Encryption3Enabled)) { - if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) /* multicast */ - KeyIdx = pAd->StaCfg.DefaultKeyId; - else if (pAd->SharedKey[BSS0][0].KeyLen) - KeyIdx = 0; - else - KeyIdx = pAd->StaCfg.DefaultKeyId; - } - - if (KeyIdx == 0xff) - CipherAlg = CIPHER_NONE; - else if ((Cipher == Ndis802_11EncryptionDisabled) - || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0)) - CipherAlg = CIPHER_NONE; - else if (pAd->StaCfg.WpaSupplicantUP && - (Cipher == Ndis802_11Encryption1Enabled) && - (pAd->StaCfg.IEEE8021X == TRUE) && - (pAd->StaCfg.PortSecured == - WPA_802_1X_PORT_NOT_SECURED)) - CipherAlg = CIPHER_NONE; - else { - /*Header_802_11.FC.Wep = 1; */ - CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg; - pKey = &pAd->SharedKey[BSS0][KeyIdx]; - } - } - - pTxBlk->CipherAlg = CipherAlg; - pTxBlk->pKey = pKey; -} - -void STABuildCommon802_11Header(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - struct rt_header_802_11 *pHeader_802_11; - - /* */ - /* MAKE A COMMON 802.11 HEADER */ - /* */ - - /* normal wlan header size : 24 octets */ - pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11); - - pHeader_802_11 = - (struct rt_header_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; - - NdisZeroMemory(pHeader_802_11, sizeof(struct rt_header_802_11)); - - pHeader_802_11->FC.FrDs = 0; - pHeader_802_11->FC.Type = BTYPE_DATA; - pHeader_802_11->FC.SubType = - ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : - SUBTYPE_DATA); - - if (pTxBlk->pMacEntry) { - if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) { - pHeader_802_11->Sequence = - pTxBlk->pMacEntry->NonQosDataSeq; - pTxBlk->pMacEntry->NonQosDataSeq = - (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ; - } else { - { - pHeader_802_11->Sequence = - pTxBlk->pMacEntry->TxSeq[pTxBlk-> - UserPriority]; - pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = - (pTxBlk->pMacEntry-> - TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ; - } - } - } else { - pHeader_802_11->Sequence = pAd->Sequence; - pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ; /* next sequence */ - } - - pHeader_802_11->Frag = 0; - - pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); - - { - if (INFRA_ON(pAd)) { - { - COPY_MAC_ADDR(pHeader_802_11->Addr1, - pAd->CommonCfg.Bssid); - COPY_MAC_ADDR(pHeader_802_11->Addr2, - pAd->CurrentAddress); - COPY_MAC_ADDR(pHeader_802_11->Addr3, - pTxBlk->pSrcBufHeader); - pHeader_802_11->FC.ToDs = 1; - } - } else if (ADHOC_ON(pAd)) { - COPY_MAC_ADDR(pHeader_802_11->Addr1, - pTxBlk->pSrcBufHeader); - COPY_MAC_ADDR(pHeader_802_11->Addr2, - pAd->CurrentAddress); - COPY_MAC_ADDR(pHeader_802_11->Addr3, - pAd->CommonCfg.Bssid); - pHeader_802_11->FC.ToDs = 0; - } - } - - if (pTxBlk->CipherAlg != CIPHER_NONE) - pHeader_802_11->FC.Wep = 1; - - /* ----------------------------------------------------------------- */ - /* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */ - /* ----------------------------------------------------------------- */ - if (pAd->CommonCfg.bAPSDForcePowerSave) - pHeader_802_11->FC.PwrMgmt = PWR_SAVE; - else - pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); -} - -void STABuildCache802_11Header(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, u8 * pHeader) -{ - struct rt_mac_table_entry *pMacEntry; - struct rt_header_802_11 * pHeader80211; - - pHeader80211 = (struct rt_header_802_11 *) pHeader; - pMacEntry = pTxBlk->pMacEntry; - - /* */ - /* Update the cached 802.11 HEADER */ - /* */ - - /* normal wlan header size : 24 octets */ - pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11); - - /* More Bit */ - pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData); - - /* Sequence */ - pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority]; - pMacEntry->TxSeq[pTxBlk->UserPriority] = - (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ; - - { - /* Check if the frame can be sent through DLS direct link interface */ - /* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */ - - /* The addr3 of normal packet send from DS is Dest Mac address. */ - if (ADHOC_ON(pAd)) - COPY_MAC_ADDR(pHeader80211->Addr3, - pAd->CommonCfg.Bssid); - else - COPY_MAC_ADDR(pHeader80211->Addr3, - pTxBlk->pSrcBufHeader); - } - - /* ----------------------------------------------------------------- */ - /* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */ - /* ----------------------------------------------------------------- */ - if (pAd->CommonCfg.bAPSDForcePowerSave) - pHeader80211->FC.PwrMgmt = PWR_SAVE; - else - pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE); -} - -static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk) -{ - u8 *pHeaderBufPtr; - struct rt_header_802_11 *pHeader_802_11; - void *pNextPacket; - u32 nextBufLen; - struct rt_queue_entry *pQEntry; - - STAFindCipherAlgorithm(pAd, pTxBlk); - STABuildCommon802_11Header(pAd, pTxBlk); - - pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; - pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr; - - /* steal "order" bit to mark "aggregation" */ - pHeader_802_11->FC.Order = 1; - - /* skip common header */ - pHeaderBufPtr += pTxBlk->MpduHeaderLen; - - if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { - /* */ - /* build QOS Control bytes */ - /* */ - *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); - - *(pHeaderBufPtr + 1) = 0; - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += 2; - } - /* padding at front of LLC header. LLC header should at 4-bytes alignment. */ - pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; - pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); - pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); - - /* For RA Aggregation, */ - /* put the 2nd MSDU length(extra 2-byte field) after struct rt_qos_control in little endian format */ - pQEntry = pTxBlk->TxPacketList.Head; - pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - nextBufLen = GET_OS_PKT_LEN(pNextPacket); - if (RTMP_GET_PACKET_VLAN(pNextPacket)) - nextBufLen -= LENGTH_802_1Q; - - *pHeaderBufPtr = (u8)nextBufLen & 0xff; - *(pHeaderBufPtr + 1) = (u8)(nextBufLen >> 8); - - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += 2; - - return pHeaderBufPtr; - -} - -static inline u8 *STA_Build_AMSDU_Frame_Header(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk) -{ - u8 *pHeaderBufPtr; /*, pSaveBufPtr; */ - struct rt_header_802_11 *pHeader_802_11; - - STAFindCipherAlgorithm(pAd, pTxBlk); - STABuildCommon802_11Header(pAd, pTxBlk); - - pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; - pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr; - - /* skip common header */ - pHeaderBufPtr += pTxBlk->MpduHeaderLen; - - /* */ - /* build QOS Control bytes */ - /* */ - *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); - - /* */ - /* A-MSDU packet */ - /* */ - *pHeaderBufPtr |= 0x80; - - *(pHeaderBufPtr + 1) = 0; - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += 2; - - /*pSaveBufPtr = pHeaderBufPtr; */ - - /* */ - /* padding at front of LLC header */ - /* LLC header should locate at 4-octets aligment */ - /* */ - /* @@@ MpduHeaderLen excluding padding @@@ */ - /* */ - pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; - pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); - pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); - - return pHeaderBufPtr; - -} - -void STA_AMPDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - struct rt_header_802_11 *pHeader_802_11; - u8 *pHeaderBufPtr; - u16 FreeNumber; - struct rt_mac_table_entry *pMacEntry; - BOOLEAN bVLANPkt; - struct rt_queue_entry *pQEntry; - - ASSERT(pTxBlk); - - while (pTxBlk->TxPacketList.Head) { - pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); - pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, - NDIS_STATUS_FAILURE); - continue; - } - - bVLANPkt = - (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); - - pMacEntry = pTxBlk->pMacEntry; - if (pMacEntry->isCached) { - /* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]! */ - NdisMoveMemory((u8 *)& pTxBlk-> - HeaderBuf[TXINFO_SIZE], - (u8 *)& pMacEntry->CachedBuf[0], - TXWI_SIZE + sizeof(struct rt_header_802_11)); - pHeaderBufPtr = - (u8 *)(&pTxBlk-> - HeaderBuf[TXINFO_SIZE + TXWI_SIZE]); - STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr); - } else { - STAFindCipherAlgorithm(pAd, pTxBlk); - STABuildCommon802_11Header(pAd, pTxBlk); - - pHeaderBufPtr = - &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; - } - - pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr; - - /* skip common header */ - pHeaderBufPtr += pTxBlk->MpduHeaderLen; - - /* */ - /* build QOS Control bytes */ - /* */ - *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); - *(pHeaderBufPtr + 1) = 0; - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += 2; - - /* */ - /* build HTC+ */ - /* HTC control filed following QoS field */ - /* */ - if ((pAd->CommonCfg.bRdg == TRUE) - && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, - fCLIENT_STATUS_RDG_CAPABLE)) { - if (pMacEntry->isCached == FALSE) { - /* mark HTC bit */ - pHeader_802_11->FC.Order = 1; - - NdisZeroMemory(pHeaderBufPtr, 4); - *(pHeaderBufPtr + 3) |= 0x80; - } - pHeaderBufPtr += 4; - pTxBlk->MpduHeaderLen += 4; - } - /*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */ - ASSERT(pTxBlk->MpduHeaderLen >= 24); - - /* skip 802.3 header */ - pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; - pTxBlk->SrcBufLen -= LENGTH_802_3; - - /* skip vlan tag */ - if (bVLANPkt) { - pTxBlk->pSrcBufData += LENGTH_802_1Q; - pTxBlk->SrcBufLen -= LENGTH_802_1Q; - } - /* */ - /* padding at front of LLC header */ - /* LLC header should locate at 4-octets aligment */ - /* */ - /* @@@ MpduHeaderLen excluding padding @@@ */ - /* */ - pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; - pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); - pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); - - { - - /* */ - /* Insert LLC-SNAP encapsulation - 8 octets */ - /* */ - EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk-> - pSrcBufData - 2, - pTxBlk-> - pExtraLlcSnapEncap); - if (pTxBlk->pExtraLlcSnapEncap) { - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pExtraLlcSnapEncap, 6); - pHeaderBufPtr += 6; - /* get 2 octets (TypeofLen) */ - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pSrcBufData - 2, 2); - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += LENGTH_802_1_H; - } - - } - - if (pMacEntry->isCached) { - RTMPWriteTxWI_Cache(pAd, - (struct rt_txwi *) (&pTxBlk-> - HeaderBuf - [TXINFO_SIZE]), - pTxBlk); - } else { - RTMPWriteTxWI_Data(pAd, - (struct rt_txwi *) (&pTxBlk-> - HeaderBuf - [TXINFO_SIZE]), - pTxBlk); - - NdisZeroMemory((u8 *)(&pMacEntry->CachedBuf[0]), - sizeof(pMacEntry->CachedBuf)); - NdisMoveMemory((u8 *)(&pMacEntry->CachedBuf[0]), - (u8 *)(&pTxBlk-> - HeaderBuf[TXINFO_SIZE]), - (pHeaderBufPtr - - (u8 *)(&pTxBlk-> - HeaderBuf[TXINFO_SIZE]))); - pMacEntry->isCached = TRUE; - } - - /* calculate Transmitted AMPDU count and ByteCount */ - { - pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u. - LowPart++; - pAd->RalinkCounters.TransmittedOctetsInAMPDUCount. - QuadPart += pTxBlk->SrcBufLen; - } - - /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */ - - HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber); - - /* */ - /* Kick out Tx */ - /* */ - if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) - HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - } - -} - -void STA_AMSDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - u8 *pHeaderBufPtr; - u16 FreeNumber; - u16 subFramePayloadLen = 0; /* AMSDU Subframe length without AMSDU-Header / Padding. */ - u16 totalMPDUSize = 0; - u8 *subFrameHeader; - u8 padding = 0; - u16 FirstTx = 0, LastTxIdx = 0; - BOOLEAN bVLANPkt; - int frameNum = 0; - struct rt_queue_entry *pQEntry; - - ASSERT(pTxBlk); - - ASSERT((pTxBlk->TxPacketList.Number > 1)); - - while (pTxBlk->TxPacketList.Head) { - pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); - pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, - NDIS_STATUS_FAILURE); - continue; - } - - bVLANPkt = - (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); - - /* skip 802.3 header */ - pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; - pTxBlk->SrcBufLen -= LENGTH_802_3; - - /* skip vlan tag */ - if (bVLANPkt) { - pTxBlk->pSrcBufData += LENGTH_802_1Q; - pTxBlk->SrcBufLen -= LENGTH_802_1Q; - } - - if (frameNum == 0) { - pHeaderBufPtr = - STA_Build_AMSDU_Frame_Header(pAd, pTxBlk); - - /* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */ - RTMPWriteTxWI_Data(pAd, - (struct rt_txwi *) (&pTxBlk-> - HeaderBuf - [TXINFO_SIZE]), - pTxBlk); - } else { - pHeaderBufPtr = &pTxBlk->HeaderBuf[0]; - padding = - ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + - subFramePayloadLen, - 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + - subFramePayloadLen); - NdisZeroMemory(pHeaderBufPtr, - padding + LENGTH_AMSDU_SUBFRAMEHEAD); - pHeaderBufPtr += padding; - pTxBlk->MpduHeaderLen = padding; - } - - /* */ - /* A-MSDU subframe */ - /* DA(6)+SA(6)+Length(2) + LLC/SNAP Encap */ - /* */ - subFrameHeader = pHeaderBufPtr; - subFramePayloadLen = pTxBlk->SrcBufLen; - - NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12); - - pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD; - pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD; - - /* */ - /* Insert LLC-SNAP encapsulation - 8 octets */ - /* */ - EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2, - pTxBlk->pExtraLlcSnapEncap); - - subFramePayloadLen = pTxBlk->SrcBufLen; - - if (pTxBlk->pExtraLlcSnapEncap) { - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pExtraLlcSnapEncap, 6); - pHeaderBufPtr += 6; - /* get 2 octets (TypeofLen) */ - NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2, - 2); - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += LENGTH_802_1_H; - subFramePayloadLen += LENGTH_802_1_H; - } - /* update subFrame Length field */ - subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8; - subFrameHeader[13] = subFramePayloadLen & 0xFF; - - totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; - - if (frameNum == 0) - FirstTx = - HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, - &FreeNumber); - else - LastTxIdx = - HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, - &FreeNumber); - - frameNum++; - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - /* calculate Transmitted AMSDU Count and ByteCount */ - { - pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++; - pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += - totalMPDUSize; - } - - } - - HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx); - HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx); - - /* */ - /* Kick out Tx */ - /* */ - if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) - HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); -} - -void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - struct rt_header_802_11 *pHeader_802_11; - u8 *pHeaderBufPtr; - u16 FreeNumber; - BOOLEAN bVLANPkt; - struct rt_queue_entry *pQEntry; - - ASSERT(pTxBlk); - - pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); - pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); - return; - } - - if (pTxBlk->TxFrameType == TX_MCAST_FRAME) { - INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount); - } - - if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket)) - TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired); - else - TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired); - - bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); - - if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate) - pTxBlk->TxRate = pAd->CommonCfg.MinTxRate; - - STAFindCipherAlgorithm(pAd, pTxBlk); - STABuildCommon802_11Header(pAd, pTxBlk); - - /* skip 802.3 header */ - pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; - pTxBlk->SrcBufLen -= LENGTH_802_3; - - /* skip vlan tag */ - if (bVLANPkt) { - pTxBlk->pSrcBufData += LENGTH_802_1Q; - pTxBlk->SrcBufLen -= LENGTH_802_1Q; - } - - pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; - pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr; - - /* skip common header */ - pHeaderBufPtr += pTxBlk->MpduHeaderLen; - - if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { - /* */ - /* build QOS Control bytes */ - /* */ - *(pHeaderBufPtr) = - ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg. - AckPolicy[pTxBlk-> - QueIdx] << 5)); - *(pHeaderBufPtr + 1) = 0; - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += 2; - } - /* The remaining content of MPDU header should locate at 4-octets alignment */ - pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; - pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); - pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); - - { - - /* */ - /* Insert LLC-SNAP encapsulation - 8 octets */ - /* */ - /* */ - /* if original Ethernet frame contains no LLC/SNAP, */ - /* then an extra LLC/SNAP encap is required */ - /* */ - EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, - pTxBlk->pExtraLlcSnapEncap); - if (pTxBlk->pExtraLlcSnapEncap) { - u8 vlan_size; - - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pExtraLlcSnapEncap, 6); - pHeaderBufPtr += 6; - /* skip vlan tag */ - vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0; - /* get 2 octets (TypeofLen) */ - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pSrcBufHeader + 12 + vlan_size, - 2); - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += LENGTH_802_1_H; - } - - } - - /* */ - /* prepare for TXWI */ - /* use Wcid as Key Index */ - /* */ - - RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]), - pTxBlk); - - /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */ - - HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber); - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - /* */ - /* Kick out Tx */ - /* */ - if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) - HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); -} - -void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - u8 *pHeaderBufPtr; - u16 FreeNumber; - u16 totalMPDUSize = 0; - u16 FirstTx, LastTxIdx; - int frameNum = 0; - BOOLEAN bVLANPkt; - struct rt_queue_entry *pQEntry; - - ASSERT(pTxBlk); - - ASSERT((pTxBlk->TxPacketList.Number == 2)); - - FirstTx = LastTxIdx = 0; /* Is it ok init they as 0? */ - while (pTxBlk->TxPacketList.Head) { - pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); - pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - - if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, - NDIS_STATUS_FAILURE); - continue; - } - - bVLANPkt = - (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); - - /* skip 802.3 header */ - pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; - pTxBlk->SrcBufLen -= LENGTH_802_3; - - /* skip vlan tag */ - if (bVLANPkt) { - pTxBlk->pSrcBufData += LENGTH_802_1Q; - pTxBlk->SrcBufLen -= LENGTH_802_1Q; - } - - if (frameNum == 0) { /* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */ - - pHeaderBufPtr = - STA_Build_ARalink_Frame_Header(pAd, pTxBlk); - - /* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */ - /* will be updated after final frame was handled. */ - RTMPWriteTxWI_Data(pAd, - (struct rt_txwi *) (&pTxBlk-> - HeaderBuf - [TXINFO_SIZE]), - pTxBlk); - - /* */ - /* Insert LLC-SNAP encapsulation - 8 octets */ - /* */ - EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk-> - pSrcBufData - 2, - pTxBlk-> - pExtraLlcSnapEncap); - - if (pTxBlk->pExtraLlcSnapEncap) { - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pExtraLlcSnapEncap, 6); - pHeaderBufPtr += 6; - /* get 2 octets (TypeofLen) */ - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pSrcBufData - 2, 2); - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += LENGTH_802_1_H; - } - } else { /* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */ - - pHeaderBufPtr = &pTxBlk->HeaderBuf[0]; - pTxBlk->MpduHeaderLen = 0; - - /* A-Ralink sub-sequent frame header is the same as 802.3 header. */ - /* DA(6)+SA(6)+FrameType(2) */ - NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, - 12); - pHeaderBufPtr += 12; - /* get 2 octets (TypeofLen) */ - NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2, - 2); - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD; - } - - totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen; - - /*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */ - if (frameNum == 0) - FirstTx = - HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, - &FreeNumber); - else - LastTxIdx = - HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, - &FreeNumber); - - frameNum++; - - pAd->RalinkCounters.OneSecTxAggregationCount++; - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - } - - HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx); - HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx); - - /* */ - /* Kick out Tx */ - /* */ - if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) - HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); - -} - -void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) -{ - struct rt_header_802_11 *pHeader_802_11; - u8 *pHeaderBufPtr; - u16 FreeNumber; - u8 fragNum = 0; - struct rt_packet_info PacketInfo; - u16 EncryptionOverhead = 0; - u32 FreeMpduSize, SrcRemainingBytes; - u16 AckDuration; - u32 NextMpduSize; - BOOLEAN bVLANPkt; - struct rt_queue_entry *pQEntry; - HTTRANSMIT_SETTING *pTransmit; - - ASSERT(pTxBlk); - - pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList); - pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) { - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); - return; - } - - ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag)); - bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE); - - STAFindCipherAlgorithm(pAd, pTxBlk); - STABuildCommon802_11Header(pAd, pTxBlk); - - if (pTxBlk->CipherAlg == CIPHER_TKIP) { - pTxBlk->pPacket = - duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket); - if (pTxBlk->pPacket == NULL) - return; - RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, - &pTxBlk->pSrcBufHeader, - &pTxBlk->SrcBufLen); - } - /* skip 802.3 header */ - pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3; - pTxBlk->SrcBufLen -= LENGTH_802_3; - - /* skip vlan tag */ - if (bVLANPkt) { - pTxBlk->pSrcBufData += LENGTH_802_1Q; - pTxBlk->SrcBufLen -= LENGTH_802_1Q; - } - - pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]; - pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr; - - /* skip common header */ - pHeaderBufPtr += pTxBlk->MpduHeaderLen; - - if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) { - /* */ - /* build QOS Control bytes */ - /* */ - *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); - - *(pHeaderBufPtr + 1) = 0; - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += 2; - } - /* */ - /* padding at front of LLC header */ - /* LLC header should locate at 4-octets aligment */ - /* */ - pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; - pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); - pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); - - /* */ - /* Insert LLC-SNAP encapsulation - 8 octets */ - /* */ - /* */ - /* if original Ethernet frame contains no LLC/SNAP, */ - /* then an extra LLC/SNAP encap is required */ - /* */ - EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, - pTxBlk->pExtraLlcSnapEncap); - if (pTxBlk->pExtraLlcSnapEncap) { - u8 vlan_size; - - NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6); - pHeaderBufPtr += 6; - /* skip vlan tag */ - vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0; - /* get 2 octets (TypeofLen) */ - NdisMoveMemory(pHeaderBufPtr, - pTxBlk->pSrcBufHeader + 12 + vlan_size, 2); - pHeaderBufPtr += 2; - pTxBlk->MpduHeaderLen += LENGTH_802_1_H; - } - - /* If TKIP is used and fragmentation is required. Driver has to */ - /* append TKIP MIC at tail of the scatter buffer */ - /* MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */ - if (pTxBlk->CipherAlg == CIPHER_TKIP) { - RTMPCalculateMICValue(pAd, pTxBlk->pPacket, - pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, - 0); - - /* NOTE: DON'T refer the skb->len directly after following copy. Because the length is not adjusted */ - /* to correct length, refer to pTxBlk->SrcBufLen for the packet length in following progress. */ - NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, - &pAd->PrivateInfo.Tx.MIC[0], 8); - /*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */ - pTxBlk->SrcBufLen += 8; - pTxBlk->TotalFrameLen += 8; - pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC; - } - /* */ - /* calculate the overhead bytes that encryption algorithm may add. This */ - /* affects the calculate of "duration" field */ - /* */ - if ((pTxBlk->CipherAlg == CIPHER_WEP64) - || (pTxBlk->CipherAlg == CIPHER_WEP128)) - EncryptionOverhead = 8; /*WEP: IV[4] + ICV[4]; */ - else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC) - EncryptionOverhead = 12; /*TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */ - else if (pTxBlk->CipherAlg == CIPHER_TKIP) - EncryptionOverhead = 20; /*TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8] */ - else if (pTxBlk->CipherAlg == CIPHER_AES) - EncryptionOverhead = 16; /* AES: IV[4] + EIV[4] + MIC[8] */ - else - EncryptionOverhead = 0; - - pTransmit = pTxBlk->pTransmit; - /* Decide the TX rate */ - if (pTransmit->field.MODE == MODE_CCK) - pTxBlk->TxRate = pTransmit->field.MCS; - else if (pTransmit->field.MODE == MODE_OFDM) - pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE; - else - pTxBlk->TxRate = RATE_6_5; - - /* decide how much time an ACK/CTS frame will consume in the air */ - if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE) - AckDuration = - RTMPCalcDuration(pAd, - pAd->CommonCfg.ExpectedACKRate[pTxBlk-> - TxRate], - 14); - else - AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14); - - /* Init the total payload length of this frame. */ - SrcRemainingBytes = pTxBlk->SrcBufLen; - - pTxBlk->TotalFragNum = 0xff; - - do { - - FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC; - - FreeMpduSize -= pTxBlk->MpduHeaderLen; - - if (SrcRemainingBytes <= FreeMpduSize) { /* this is the last or only fragment */ - - pTxBlk->SrcBufLen = SrcRemainingBytes; - - pHeader_802_11->FC.MoreFrag = 0; - pHeader_802_11->Duration = - pAd->CommonCfg.Dsifs + AckDuration; - - /* Indicate the lower layer that this's the last fragment. */ - pTxBlk->TotalFragNum = fragNum; - } else { /* more fragment is required */ - - pTxBlk->SrcBufLen = FreeMpduSize; - - NextMpduSize = - min(((u32)SrcRemainingBytes - pTxBlk->SrcBufLen), - ((u32)pAd->CommonCfg.FragmentThreshold)); - pHeader_802_11->FC.MoreFrag = 1; - pHeader_802_11->Duration = - (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + - RTMPCalcDuration(pAd, pTxBlk->TxRate, - NextMpduSize + EncryptionOverhead); - } - - if (fragNum == 0) - pTxBlk->FrameGap = IFS_HTTXOP; - else - pTxBlk->FrameGap = IFS_SIFS; - - RTMPWriteTxWI_Data(pAd, - (struct rt_txwi *) (&pTxBlk-> - HeaderBuf[TXINFO_SIZE]), - pTxBlk); - - HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber); - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - /* Update the frame number, remaining size of the NDIS packet payload. */ - - /* space for 802.11 header. */ - if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap) - pTxBlk->MpduHeaderLen -= LENGTH_802_1_H; - - fragNum++; - SrcRemainingBytes -= pTxBlk->SrcBufLen; - pTxBlk->pSrcBufData += pTxBlk->SrcBufLen; - - pHeader_802_11->Frag++; /* increase Frag # */ - - } while (SrcRemainingBytes > 0); - - /* */ - /* Kick out Tx */ - /* */ - if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) - HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); -} - -#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \ - while(_pTxBlk->TxPacketList.Head) \ - { \ - _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \ - RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \ - } - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware encryption before really - sent out to air. - - Arguments: - pAd Pointer to our adapter - void * Pointer to outgoing Ndis frame - NumberOfFrag Number of fragment required - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -int STAHardTransmit(struct rt_rtmp_adapter *pAd, - struct rt_tx_blk *pTxBlk, u8 QueIdx) -{ - char *pPacket; - struct rt_queue_entry *pQEntry; - - /* --------------------------------------------- */ - /* STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. */ - /* --------------------------------------------- */ - /* */ - ASSERT(pTxBlk->TxPacketList.Number); - if (pTxBlk->TxPacketList.Head == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("pTxBlk->TotalFrameNum == %ld!\n", - pTxBlk->TxPacketList.Number)); - return NDIS_STATUS_FAILURE; - } - - pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head); - - /* ------------------------------------------------------------------ */ - /* STEP 1. WAKE UP PHY */ - /* outgoing frame always wakeup PHY to prevent frame lost and */ - /* turn off PSM bit to improve performance */ - /* ------------------------------------------------------------------ */ - /* not to change PSM bit, just send this frame out? */ - if ((pAd->StaCfg.Psm == PWR_SAVE) - && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n")); -#ifdef RTMP_MAC_PCI - AsicForceWakeup(pAd, TRUE); -#endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0); -#endif /* RTMP_MAC_USB // */ - } - /* It should not change PSM bit, when APSD turn on. */ - if ((! - (pAd->CommonCfg.bAPSDCapable - && pAd->CommonCfg.APEdcaParm.bAPSDCapable) - && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE)) - || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) - || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) { - if ((pAd->StaCfg.Psm == PWR_SAVE) && - (pAd->StaCfg.WindowsPowerMode == - Ndis802_11PowerModeFast_PSP)) - RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); - } - - switch (pTxBlk->TxFrameType) { - case TX_AMPDU_FRAME: - STA_AMPDU_Frame_Tx(pAd, pTxBlk); - break; - case TX_AMSDU_FRAME: - STA_AMSDU_Frame_Tx(pAd, pTxBlk); - break; - case TX_LEGACY_FRAME: - STA_Legacy_Frame_Tx(pAd, pTxBlk); - break; - case TX_MCAST_FRAME: - STA_Legacy_Frame_Tx(pAd, pTxBlk); - break; - case TX_RALINK_FRAME: - STA_ARalink_Frame_Tx(pAd, pTxBlk); - break; - case TX_FRAG_FRAME: - STA_Fragment_Frame_Tx(pAd, pTxBlk); - break; - default: - { - /* It should not happened! */ - DBGPRINT(RT_DEBUG_ERROR, - ("Send a packet was not classified! It should not happen!\n")); - while (pTxBlk->TxPacketList.Number) { - pQEntry = - RemoveHeadQueue(&pTxBlk->TxPacketList); - pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); - if (pPacket) - RELEASE_NDIS_PACKET(pAd, pPacket, - NDIS_STATUS_FAILURE); - } - } - break; - } - - return (NDIS_STATUS_SUCCESS); - -} - -unsigned long HashBytesPolynomial(u8 * value, unsigned int len) -{ - unsigned char *word = value; - unsigned int ret = 0; - unsigned int i; - - for (i = 0; i < len; i++) { - int mod = i % 32; - ret ^= (unsigned int)(word[i]) << mod; - ret ^= (unsigned int)(word[i]) >> (32 - mod); - } - return ret; -} - -void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd, - void *pPacket, - u8 FromWhichBSSID) -{ - if (TRUE) { - announce_802_3_packet(pAd, pPacket); - } else { - /* release packet */ - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } -} diff --git a/drivers/staging/rt2860/sta/sanity.c b/drivers/staging/rt2860/sta/sanity.c deleted file mode 100644 index 0c32604f2d3f..000000000000 --- a/drivers/staging/rt2860/sta/sanity.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - sanity.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John Chang 2004-09-01 add WMM support - Justin P. Mattock 11/07/2010 Fix typos -*/ -#include "../rt_config.h" - -extern u8 CISCO_OUI[]; - -extern u8 WPA_OUI[]; -extern u8 RSN_OUI[]; -extern u8 WME_INFO_ELEM[]; -extern u8 WME_PARM_ELEM[]; -extern u8 Ccx2QosInfo[]; -extern u8 RALINK_OUI[]; -extern u8 BROADCOM_OUI[]; - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== - */ -BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - char Ssid[], u8 * pSsidLen) -{ - struct rt_mlme_start_req *Info; - - Info = (struct rt_mlme_start_req *)(Msg); - - if (Info->SsidLen > MAX_LEN_OF_SSID) { - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeStartReqSanity fail - wrong SSID length\n")); - return FALSE; - } - - *pSsidLen = Info->SsidLen; - NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen); - - return TRUE; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned long MsgLen, u8 *pAddr2, u16 * pCapabilityInfo, u16 * pStatus, u16 * pAid, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */ - u8 * pHtCapabilityLen, - u8 * pAddHtInfoLen, - u8 * pNewExtChannelOffset, - struct rt_edca_parm *pEdcaParm, u8 * pCkipFlag) -{ - char IeType, *Ptr; - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg; - struct rt_eid * pEid; - unsigned long Length = 0; - - *pNewExtChannelOffset = 0xff; - *pHtCapabilityLen = 0; - *pAddHtInfoLen = 0; - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - Ptr = (char *)pFrame->Octet; - Length += LENGTH_802_11; - - NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2); - Length += 2; - NdisMoveMemory(pStatus, &pFrame->Octet[2], 2); - Length += 2; - *pCkipFlag = 0; - *pExtRateLen = 0; - pEdcaParm->bValid = FALSE; - - if (*pStatus != MLME_SUCCESS) - return TRUE; - - NdisMoveMemory(pAid, &pFrame->Octet[4], 2); - Length += 2; - - /* Aid already swapped byte order in RTMPFrameEndianChange() for big endian platform */ - *pAid = (*pAid) & 0x3fff; /* AID is low 14-bit */ - - /* -- get supported rates from payload and advance the pointer */ - IeType = pFrame->Octet[6]; - *pSupRateLen = pFrame->Octet[7]; - if ((IeType != IE_SUPP_RATES) - || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAssocRspSanity fail - wrong SupportedRates IE\n")); - return FALSE; - } else - NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen); - - Length = Length + 2 + *pSupRateLen; - - /* many AP implement proprietary IEs in non-standard order, we'd better */ - /* tolerate mis-ordered IEs to get best compatibility */ - pEid = (struct rt_eid *) & pFrame->Octet[8 + (*pSupRateLen)]; - - /* get variable fields from payload and advance the pointer */ - while ((Length + 2 + pEid->Len) <= MsgLen) { - switch (pEid->Eid) { - case IE_EXT_SUPP_RATES: - if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { - NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); - *pExtRateLen = pEid->Len; - } - break; - - case IE_HT_CAP: - case IE_HT_CAP2: - if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension! */ - { - NdisMoveMemory(pHtCapability, pEid->Octet, - SIZE_HT_CAP_IE); - - *(u16 *) (&pHtCapability->HtCapInfo) = - cpu2le16(*(u16 *) - (&pHtCapability->HtCapInfo)); - *(u16 *) (&pHtCapability->ExtHtCapInfo) = - cpu2le16(*(u16 *) - (&pHtCapability->ExtHtCapInfo)); - - *pHtCapabilityLen = SIZE_HT_CAP_IE; - } else { - DBGPRINT(RT_DEBUG_WARN, - ("PeerAssocRspSanity - wrong IE_HT_CAP. \n")); - } - - break; - case IE_ADD_HT: - case IE_ADD_HT2: - if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) { - /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */ - /* copy first sizeof(struct rt_add_ht_info_ie) */ - NdisMoveMemory(pAddHtInfo, pEid->Octet, - sizeof(struct rt_add_ht_info_ie)); - - *(u16 *) (&pAddHtInfo->AddHtInfo2) = - cpu2le16(*(u16 *) - (&pAddHtInfo->AddHtInfo2)); - *(u16 *) (&pAddHtInfo->AddHtInfo3) = - cpu2le16(*(u16 *) - (&pAddHtInfo->AddHtInfo3)); - - *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE; - } else { - DBGPRINT(RT_DEBUG_WARN, - ("PeerAssocRspSanity - wrong IE_ADD_HT. \n")); - } - - break; - case IE_SECONDARY_CH_OFFSET: - if (pEid->Len == 1) { - *pNewExtChannelOffset = pEid->Octet[0]; - } else { - DBGPRINT(RT_DEBUG_WARN, - ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); - } - break; - - case IE_VENDOR_SPECIFIC: - /* handle WME PARAMTER ELEMENT */ - if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) - && (pEid->Len == 24)) { - u8 *ptr; - int i; - - /* parsing EDCA parameters */ - pEdcaParm->bValid = TRUE; - pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ - pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ - pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ - /*pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80; */ - pEdcaParm->EdcaUpdateCount = - pEid->Octet[6] & 0x0f; - pEdcaParm->bAPSDCapable = - (pEid->Octet[6] & 0x80) ? 1 : 0; - ptr = (u8 *)& pEid->Octet[8]; - for (i = 0; i < 4; i++) { - u8 aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */ - pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */ - pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */ - pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */ - pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */ - pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */ - ptr += 4; /* point to next AC */ - } - } - break; - default: - DBGPRINT(RT_DEBUG_TRACE, - ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", - pEid->Eid)); - break; - } - - Length = Length + 2 + pEid->Len; - pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len); - } - - return TRUE; -} - -/* - ========================================================================== - Description: - MLME message sanity check - Return: - TRUE if all parameters are OK, FALSE otherwise - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, - unsigned long MsgLen, - u8 *pAddr2, - char Ssid[], u8 * pSsidLen) -{ - u8 Idx; - u8 RateLen; - char IeType; - struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg; - - COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - - if ((pFrame->Octet[0] != IE_SSID) - || (pFrame->Octet[1] > MAX_LEN_OF_SSID)) { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n", - pFrame->Octet[0], pFrame->Octet[1])); - return FALSE; - } - - *pSsidLen = pFrame->Octet[1]; - NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen); - - Idx = *pSsidLen + 2; - - /* -- get supported rates from payload and advance the pointer */ - IeType = pFrame->Octet[Idx]; - RateLen = pFrame->Octet[Idx + 1]; - if (IeType != IE_SUPP_RATES) { - DBGPRINT(RT_DEBUG_TRACE, - ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n", - pFrame->Octet[Idx], pFrame->Octet[Idx + 1])); - return FALSE; - } else { - if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8)) - return (FALSE); - } - - return TRUE; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -BOOLEAN GetTimBit(char * Ptr, - u16 Aid, - u8 * TimLen, - u8 * BcastFlag, - u8 * DtimCount, - u8 * DtimPeriod, u8 * MessageToMe) -{ - u8 BitCntl, N1, N2, MyByte, MyBit; - char *IdxPtr; - - IdxPtr = Ptr; - - IdxPtr++; - *TimLen = *IdxPtr; - - /* get DTIM Count from TIM element */ - IdxPtr++; - *DtimCount = *IdxPtr; - - /* get DTIM Period from TIM element */ - IdxPtr++; - *DtimPeriod = *IdxPtr; - - /* get Bitmap Control from TIM element */ - IdxPtr++; - BitCntl = *IdxPtr; - - if ((*DtimCount == 0) && (BitCntl & 0x01)) - *BcastFlag = TRUE; - else - *BcastFlag = FALSE; - - /* Parse Partial Virtual Bitmap from TIM element */ - N1 = BitCntl & 0xfe; /* N1 is the first bitmap byte# */ - N2 = *TimLen - 4 + N1; /* N2 is the last bitmap byte# */ - - if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3))) - *MessageToMe = FALSE; - else { - MyByte = (Aid >> 3) - N1; /* my byte position in the bitmap byte-stream */ - MyBit = Aid % 16 - ((MyByte & 0x01) ? 8 : 0); - - IdxPtr += (MyByte + 1); - - /*if (*IdxPtr) */ - /* DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr)); */ - - if (*IdxPtr & (0x01 << MyBit)) - *MessageToMe = TRUE; - else - *MessageToMe = FALSE; - } - - return TRUE; -} diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c deleted file mode 100644 index 7054ba1323d0..000000000000 --- a/drivers/staging/rt2860/sta/sync.c +++ /dev/null @@ -1,1968 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - sync.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - John Chang 2004-09-01 modified for rt2561/2661 - Jan Lee 2006-08-01 modified for rt2860 for 802.11n - Justin P. Mattock 11/07/2010 Fix typos -*/ -#include "../rt_config.h" - -#define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) /* 2 sec */ - -/* - ========================================================================== - Description: - The sync state machine, - Parameters: - Sm - pointer to the state machine - Note: - the state machine looks like the following - - ========================================================================== - */ -void SyncStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, - (STATE_MACHINE_FUNC) Drop, SYNC_IDLE, - SYNC_MACHINE_BASE); - - /* column 1 */ - StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, - (STATE_MACHINE_FUNC) MlmeScanReqAction); - StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, - (STATE_MACHINE_FUNC) MlmeJoinReqAction); - StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, - (STATE_MACHINE_FUNC) MlmeStartReqAction); - StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, - (STATE_MACHINE_FUNC) PeerBeacon); - StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, - (STATE_MACHINE_FUNC) PeerProbeReqAction); - - /*column 2 */ - StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenScan); - StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenJoin); - StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenStart); - StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, - (STATE_MACHINE_FUNC) PeerBeaconAtJoinAction); - StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, - (STATE_MACHINE_FUNC) BeaconTimeoutAtJoinAction); - - /* column 3 */ - StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenScan); - StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenJoin); - StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, - (STATE_MACHINE_FUNC) InvalidStateWhenStart); - StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, - (STATE_MACHINE_FUNC) PeerBeaconAtScanAction); - StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, - (STATE_MACHINE_FUNC) PeerBeaconAtScanAction); - StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, - (STATE_MACHINE_FUNC) ScanTimeoutAction); - - /* timer init */ - RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, - GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE); - RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, - GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE); -} - -/* - ========================================================================== - Description: - Beacon timeout handler, executed in timer thread - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void BeaconTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeout\n")); - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) - return; - - if ((pAd->CommonCfg.BBPCurrentBW == BW_40) - ) { - u8 BBPValue = 0; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - BBPValue |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n", - pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr)); - } - - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL); - RTMP_MLME_HANDLER(pAd); -} - -/* - ========================================================================== - Description: - Scan timeout handler, executed in timer thread - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void ScanTimeout(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - - /* Do nothing if the driver is starting halt state. */ - /* This might happen when timer already been fired before cancel timer with mlmehalt */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) - return; - - if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) { - RTMP_MLME_HANDLER(pAd); - } else { - /* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */ - pAd->MlmeAux.Channel = 0; - ScanNextChannel(pAd); - if (pAd->CommonCfg.bWirelessEvent) { - RTMPSendWirelessEvent(pAd, - IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, - pAd->MacTab.Content[BSSID_WCID]. - Addr, BSS0, 0); - } - } -} - -/* - ========================================================================== - Description: - MLME SCAN req state machine procedure - ========================================================================== - */ -void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0; - BOOLEAN TimerCancelled; - unsigned long Now; - u16 Status; - struct rt_header_802_11 * pHdr80211; - u8 *pOutBuffer = NULL; - int NStatus; - - /* Check the total scan tries for one single OID command */ - /* If this is the CCX 2.0 Case, skip that! */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - MlmeScanReqAction before Startup\n")); - return; - } - /* Increase the scan retry counters. */ - pAd->StaCfg.ScanCnt++; - -#ifdef RTMP_MAC_PCI - if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) && - (IDLE_ON(pAd)) && - (pAd->StaCfg.bRadio == TRUE) && - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { - if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) { - AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, - 0x02); - AsicCheckCommanOk(pAd, PowerWakeCID); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); - DBGPRINT(RT_DEBUG_TRACE, - ("PSM - Issue Wake up command \n")); - } else { - RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); - } - } -#endif /* RTMP_MAC_PCI // */ - - /* first check the parameter sanity */ - if (MlmeScanReqSanity(pAd, - Elem->Msg, - Elem->MsgLen, - &BssType, (char *)Ssid, &SsidLen, &ScanType)) { - - /* Check for channel load and noise hist request */ - /* Suspend MSDU only at scan request, not the last two mentioned */ - /* Suspend MSDU transmission here */ - RTMPSuspendMsduTransmission(pAd); - - /* */ - /* To prevent data loss. */ - /* Send a NULL data with turned PSM bit on to current associated AP before SCAN progress. */ - /* And should send a NULL data with turned PSM bit off to AP, when scan progress done */ - /* */ - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) - && (INFRA_ON(pAd))) { - NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); - if (NStatus == NDIS_STATUS_SUCCESS) { - pHdr80211 = (struct rt_header_802_11 *) pOutBuffer; - MgtMacHeaderInit(pAd, pHdr80211, - SUBTYPE_NULL_FUNC, 1, - pAd->CommonCfg.Bssid, - pAd->CommonCfg.Bssid); - pHdr80211->Duration = 0; - pHdr80211->FC.Type = BTYPE_DATA; - pHdr80211->FC.PwrMgmt = PWR_SAVE; - - /* Send using priority queue */ - MiniportMMRequest(pAd, 0, pOutBuffer, - sizeof(struct rt_header_802_11)); - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n")); - MlmeFreeMemory(pAd, pOutBuffer); - RTMPusecDelay(5000); - } - } - - NdisGetSystemUpTime(&Now); - pAd->StaCfg.LastScanTime = Now; - /* reset all the timers */ - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); - - /* record desired BSS parameters */ - pAd->MlmeAux.BssType = BssType; - pAd->MlmeAux.ScanType = ScanType; - pAd->MlmeAux.SsidLen = SsidLen; - NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); - NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); - - /* start from the first channel */ - pAd->MlmeAux.Channel = FirstChannel(pAd); - - /* Let BBP register at 20MHz to do scan */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); - ScanNextChannel(pAd); - } else { - DBGPRINT_ERR("SYNC - MlmeScanReqAction() sanity check fail\n"); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_INVALID_FORMAT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, - &Status); - } -} - -/* - ========================================================================== - Description: - MLME JOIN req state machine procedure - ========================================================================== - */ -void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 BBPValue = 0; - struct rt_bss_entry *pBss; - BOOLEAN TimerCancelled; - struct rt_header_802_11 Hdr80211; - int NStatus; - unsigned long FrameLen = 0; - u8 *pOutBuffer = NULL; - u8 *pSupRate = NULL; - u8 SupRateLen; - u8 *pExtRate = NULL; - u8 ExtRateLen; - u8 ASupRate[] = { 0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C }; - u8 ASupRateLen = sizeof(ASupRate) / sizeof(u8); - struct rt_mlme_join_req *pInfo = (struct rt_mlme_join_req *)(Elem->Msg); - - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); - -#ifdef RTMP_MAC_PCI - if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) && - (IDLE_ON(pAd)) && - (pAd->StaCfg.bRadio == TRUE) && - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) { - RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); - } -#endif /* RTMP_MAC_PCI // */ - - /* reset all the timers */ - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); - - pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx]; - - /* record the desired SSID & BSSID we're waiting for */ - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid); - - /* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */ - if (pBss->Hidden == 0) { - RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); - NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen); - pAd->MlmeAux.SsidLen = pBss->SsidLen; - } - - pAd->MlmeAux.BssType = pBss->BssType; - pAd->MlmeAux.Channel = pBss->Channel; - pAd->MlmeAux.CentralChannel = pBss->CentralChannel; - - /* Let BBP register at 20MHz to do scan */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); - - /* switch channel and waiting for beacon timer */ - AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); - AsicLockChannel(pAd, pAd->MlmeAux.Channel); - RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT); - - do { - if (((pAd->CommonCfg.bIEEE80211H == 1) && - (pAd->MlmeAux.Channel > 14) && - RadarChannelCheck(pAd, pAd->MlmeAux.Channel)) - ) { - /* */ - /* We can't send any Probe request frame to meet 802.11h. */ - /* */ - if (pBss->Hidden == 0) - break; - } - /* */ - /* send probe request */ - /* */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); - if (NStatus == NDIS_STATUS_SUCCESS) { - if (pAd->MlmeAux.Channel <= 14) { - pSupRate = pAd->CommonCfg.SupRate; - SupRateLen = pAd->CommonCfg.SupRateLen; - pExtRate = pAd->CommonCfg.ExtRate; - ExtRateLen = pAd->CommonCfg.ExtRateLen; - } else { - /* */ - /* Overwrite Support Rate, CCK rate are not allowed */ - /* */ - pSupRate = ASupRate; - SupRateLen = ASupRateLen; - ExtRateLen = 0; - } - - if (pAd->MlmeAux.BssType == BSS_INFRA) - MgtMacHeaderInit(pAd, &Hdr80211, - SUBTYPE_PROBE_REQ, 0, - pAd->MlmeAux.Bssid, - pAd->MlmeAux.Bssid); - else - MgtMacHeaderInit(pAd, &Hdr80211, - SUBTYPE_PROBE_REQ, 0, - BROADCAST_ADDR, - BROADCAST_ADDR); - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &Hdr80211, - 1, &SsidIe, - 1, &pAd->MlmeAux.SsidLen, - pAd->MlmeAux.SsidLen, - pAd->MlmeAux.Ssid, 1, &SupRateIe, 1, - &SupRateLen, SupRateLen, pSupRate, - END_OF_ARGS); - - if (ExtRateLen) { - unsigned long Tmp; - MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp, - 1, &ExtRateIe, - 1, &ExtRateLen, - ExtRateLen, pExtRate, - END_OF_ARGS); - FrameLen += Tmp; - } - - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - } - } while (FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - Switch to ch %d, Wait BEACON from %pM\n", - pBss->Channel, pBss->Bssid)); - - pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON; -} - -/* - ========================================================================== - Description: - MLME START Request state machine procedure, starting an IBSS - ========================================================================== - */ -void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Ssid[MAX_LEN_OF_SSID], SsidLen; - BOOLEAN TimerCancelled; - - /* New for WPA security suites */ - u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */ - struct rt_ndis_802_11_variable_ies *pVIE = NULL; - LARGE_INTEGER TimeStamp; - BOOLEAN Privacy; - u16 Status; - - /* Init Variable IE structure */ - pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE; - pVIE->Length = 0; - TimeStamp.u.LowPart = 0; - TimeStamp.u.HighPart = 0; - - if (MlmeStartReqSanity - (pAd, Elem->Msg, Elem->MsgLen, (char *)Ssid, &SsidLen)) { - /* reset all the timers */ - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); - - /* */ - /* Start a new IBSS. All IBSS parameters are decided now.... */ - /* */ - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n")); - pAd->MlmeAux.BssType = BSS_ADHOC; - NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); - pAd->MlmeAux.SsidLen = SsidLen; - - /* generate a radom number as BSSID */ - MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid); - DBGPRINT(RT_DEBUG_TRACE, - ("MlmeStartReqAction - generate a radom number as BSSID \n")); - - Privacy = - (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) - || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) - || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled); - pAd->MlmeAux.CapabilityInfo = - CAP_GENERATE(0, 1, Privacy, - (pAd->CommonCfg.TxPreamble == - Rt802_11PreambleShort), 1, 0); - pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod; - pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin; - pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; - - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel; - - pAd->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen; - NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, - MAX_LEN_OF_SUPPORTED_RATES); - RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, - &pAd->MlmeAux.SupRateLen); - pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen; - NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, - MAX_LEN_OF_SUPPORTED_RATES); - RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, - &pAd->MlmeAux.ExtRateLen); - - if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { - RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, - &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], - &pAd->MlmeAux.HtCapability, - &pAd->MlmeAux.AddHtInfo); - pAd->MlmeAux.HtCapabilityLen = sizeof(struct rt_ht_capability_ie); - /* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */ - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n")); - } else { - pAd->MlmeAux.HtCapabilityLen = 0; - pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; - NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo. - MCSSet[0], 16); - } - /* temporarily not support QOS in IBSS */ - NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm)); - NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, - sizeof(struct rt_qbss_load_parm)); - NdisZeroMemory(&pAd->MlmeAux.APQosCapability, - sizeof(struct rt_qos_capability_parm)); - - AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); - AsicLockChannel(pAd, pAd->MlmeAux.Channel); - - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n", - pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, - pAd->MlmeAux.ExtRateLen)); - - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_SUCCESS; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, - &Status); - } else { - DBGPRINT_ERR("SYNC - MlmeStartReqAction() sanity check fail.\n"); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_INVALID_FORMAT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, - &Status); - } -} - -/* - ========================================================================== - Description: - peer sends beacon back when scanning - ========================================================================== - */ -void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; - u8 Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel, - SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe; - struct rt_cf_parm CfParm; - u16 BeaconPeriod, AtimWin, CapabilityInfo; - struct rt_frame_802_11 * pFrame; - LARGE_INTEGER TimeStamp; - u8 Erp; - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], - ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen, ExtRateLen; - u16 LenVIE; - u8 CkipFlag; - u8 AironetCellPowerLimit; - struct rt_edca_parm EdcaParm; - struct rt_qbss_load_parm QbssLoad; - struct rt_qos_capability_parm QosCapability; - unsigned long RalinkIe; - u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */ - struct rt_ndis_802_11_variable_ies *pVIE = NULL; - struct rt_ht_capability_ie HtCapability; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0; - u8 AddHtInfoLen; - u8 NewExtChannelOffset = 0xff; - - /* NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); */ - pFrame = (struct rt_frame_802_11 *) Elem->Msg; - /* Init Variable IE structure */ - pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE; - pVIE->Length = 0; - - RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); - RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie)); - - if (PeerBeaconAndProbeRspSanity(pAd, - Elem->Msg, - Elem->MsgLen, - Elem->Channel, - Addr2, - Bssid, - (char *)Ssid, - &SsidLen, - &BssType, - &BeaconPeriod, - &Channel, - &NewChannel, - &TimeStamp, - &CfParm, - &AtimWin, - &CapabilityInfo, - &Erp, - &DtimCount, - &DtimPeriod, - &BcastFlag, - &MessageToMe, - SupRate, - &SupRateLen, - ExtRate, - &ExtRateLen, - &CkipFlag, - &AironetCellPowerLimit, - &EdcaParm, - &QbssLoad, - &QosCapability, - &RalinkIe, - &HtCapabilityLen, - &PreNHtCapabilityLen, - &HtCapability, - &AddHtInfoLen, - &AddHtInfo, - &NewExtChannelOffset, &LenVIE, pVIE)) { - unsigned long Idx; - char Rssi = 0; - - Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); - if (Idx != BSS_NOT_FOUND) - Rssi = pAd->ScanTab.BssEntry[Idx].Rssi; - - Rssi = - RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), - ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), - ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); - - if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) - HtCapabilityLen = SIZE_HT_CAP_IE; - - Idx = - BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (char *)Ssid, - SsidLen, BssType, BeaconPeriod, &CfParm, - AtimWin, CapabilityInfo, SupRate, - SupRateLen, ExtRate, ExtRateLen, - &HtCapability, &AddHtInfo, HtCapabilityLen, - AddHtInfoLen, NewExtChannelOffset, Channel, - Rssi, TimeStamp, CkipFlag, &EdcaParm, - &QosCapability, &QbssLoad, LenVIE, pVIE); - - if (Idx != BSS_NOT_FOUND) { - NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, - &Elem->Msg[24], 4); - NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], - &Elem->TimeStamp.u.LowPart, 4); - NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], - &Elem->TimeStamp.u.LowPart, 4); - } - - } - /* sanity check fail, ignored */ -} - -/* - ========================================================================== - Description: - When waiting joining the (I)BSS, beacon received from external - ========================================================================== - */ -void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; - u8 Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe, - DtimCount, DtimPeriod, BcastFlag, NewChannel; - LARGE_INTEGER TimeStamp; - u16 BeaconPeriod, AtimWin, CapabilityInfo; - struct rt_cf_parm Cf; - BOOLEAN TimerCancelled; - u8 Erp; - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], - ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen, ExtRateLen; - u8 CkipFlag; - u16 LenVIE; - u8 AironetCellPowerLimit; - struct rt_edca_parm EdcaParm; - struct rt_qbss_load_parm QbssLoad; - struct rt_qos_capability_parm QosCapability; - u16 Status; - u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */ - struct rt_ndis_802_11_variable_ies *pVIE = NULL; - unsigned long RalinkIe; - unsigned long Idx; - struct rt_ht_capability_ie HtCapability; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0; - u8 AddHtInfoLen; - u8 NewExtChannelOffset = 0xff; - u8 CentralChannel; - BOOLEAN bAllowNrate = FALSE; - - /* Init Variable IE structure */ - pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE; - pVIE->Length = 0; - RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); - RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie)); - - if (PeerBeaconAndProbeRspSanity(pAd, - Elem->Msg, - Elem->MsgLen, - Elem->Channel, - Addr2, - Bssid, - (char *)Ssid, - &SsidLen, - &BssType, - &BeaconPeriod, - &Channel, - &NewChannel, - &TimeStamp, - &Cf, - &AtimWin, - &CapabilityInfo, - &Erp, - &DtimCount, - &DtimPeriod, - &BcastFlag, - &MessageToMe, - SupRate, - &SupRateLen, - ExtRate, - &ExtRateLen, - &CkipFlag, - &AironetCellPowerLimit, - &EdcaParm, - &QbssLoad, - &QosCapability, - &RalinkIe, - &HtCapabilityLen, - &PreNHtCapabilityLen, - &HtCapability, - &AddHtInfoLen, - &AddHtInfo, - &NewExtChannelOffset, &LenVIE, pVIE)) { - /* Disqualify 11b only adhoc when we are in 11g only adhoc mode */ - if ((BssType == BSS_ADHOC) - && (pAd->CommonCfg.PhyMode == PHY_11G) - && ((SupRateLen + ExtRateLen) < 12)) - return; - - /* BEACON from desired BSS/IBSS found. We should be able to decide most */ - /* BSS parameters here. */ - /* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATION? */ - /* Do we need to recover back all parameters belonging to previous BSS? */ - /* A. Should be not. There's no back-door recover to previous AP. It still needs */ - /* a new JOIN-AUTH-ASSOC sequence. */ - if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) { - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", - Channel)); - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, - &TimerCancelled); - - /* Update RSSI to prevent No signal display when cards first initialized */ - pAd->StaCfg.RssiSample.LastRssi0 = - ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); - pAd->StaCfg.RssiSample.LastRssi1 = - ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); - pAd->StaCfg.RssiSample.LastRssi2 = - ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); - pAd->StaCfg.RssiSample.AvgRssi0 = - pAd->StaCfg.RssiSample.LastRssi0; - pAd->StaCfg.RssiSample.AvgRssi0X8 = - pAd->StaCfg.RssiSample.AvgRssi0 << 3; - pAd->StaCfg.RssiSample.AvgRssi1 = - pAd->StaCfg.RssiSample.LastRssi1; - pAd->StaCfg.RssiSample.AvgRssi1X8 = - pAd->StaCfg.RssiSample.AvgRssi1 << 3; - pAd->StaCfg.RssiSample.AvgRssi2 = - pAd->StaCfg.RssiSample.LastRssi2; - pAd->StaCfg.RssiSample.AvgRssi2X8 = - pAd->StaCfg.RssiSample.AvgRssi2 << 3; - - /* */ - /* We need to check if SSID only set to any, then we can record the current SSID. */ - /* Otherwise will cause hidden SSID association failed. */ - /* */ - if (pAd->MlmeAux.SsidLen == 0) { - NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, - SsidLen); - pAd->MlmeAux.SsidLen = SsidLen; - } else { - Idx = - BssSsidTableSearch(&pAd->ScanTab, Bssid, - pAd->MlmeAux.Ssid, - pAd->MlmeAux.SsidLen, - Channel); - - if (Idx == BSS_NOT_FOUND) { - char Rssi = 0; - Rssi = - RTMPMaxRssi(pAd, - ConvertToRssi(pAd, - Elem-> - Rssi0, - RSSI_0), - ConvertToRssi(pAd, - Elem-> - Rssi1, - RSSI_1), - ConvertToRssi(pAd, - Elem-> - Rssi2, - RSSI_2)); - Idx = - BssTableSetEntry(pAd, &pAd->ScanTab, - Bssid, - (char *) Ssid, - SsidLen, BssType, - BeaconPeriod, &Cf, - AtimWin, - CapabilityInfo, - SupRate, - SupRateLen, - ExtRate, - ExtRateLen, - &HtCapability, - &AddHtInfo, - HtCapabilityLen, - AddHtInfoLen, - NewExtChannelOffset, - Channel, Rssi, - TimeStamp, - CkipFlag, - &EdcaParm, - &QosCapability, - &QbssLoad, LenVIE, - pVIE); - if (Idx != BSS_NOT_FOUND) { - NdisMoveMemory(pAd->ScanTab. - BssEntry[Idx]. - PTSF, - &Elem->Msg[24], - 4); - NdisMoveMemory(&pAd->ScanTab. - BssEntry[Idx]. - TTSF[0], - &Elem->TimeStamp. - u.LowPart, 4); - NdisMoveMemory(&pAd->ScanTab. - BssEntry[Idx]. - TTSF[4], - &Elem->TimeStamp. - u.LowPart, 4); - CapabilityInfo = - pAd->ScanTab.BssEntry[Idx]. - CapabilityInfo; - } - } else { - /* */ - /* Multiple SSID case, used correct CapabilityInfo */ - /* */ - CapabilityInfo = - pAd->ScanTab.BssEntry[Idx]. - CapabilityInfo; - } - } - NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN); - pAd->MlmeAux.CapabilityInfo = - CapabilityInfo & SUPPORTED_CAPABILITY_INFO; - pAd->MlmeAux.BssType = BssType; - pAd->MlmeAux.BeaconPeriod = BeaconPeriod; - pAd->MlmeAux.Channel = Channel; - pAd->MlmeAux.AtimWin = AtimWin; - pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod; - pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; - pAd->MlmeAux.APRalinkIe = RalinkIe; - - /* Copy AP's supported rate to MlmeAux for creating association request */ - /* Also filter out not supported rate */ - pAd->MlmeAux.SupRateLen = SupRateLen; - NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, - SupRateLen); - RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, - &pAd->MlmeAux.SupRateLen); - pAd->MlmeAux.ExtRateLen = ExtRateLen; - NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, - ExtRateLen); - RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, - &pAd->MlmeAux.ExtRateLen); - - NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, - 16); - - if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) - && (pAd->StaCfg.WepStatus != - Ndis802_11Encryption2Enabled)) - || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) { - bAllowNrate = TRUE; - } - - pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; - pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen; - - RTMPZeroMemory(&pAd->MlmeAux.HtCapability, - SIZE_HT_CAP_IE); - /* filter out un-supported ht rates */ - if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) - && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) - && (bAllowNrate))) { - RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, - &AddHtInfo, SIZE_ADD_HT_INFO_IE); - - /* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */ - NdisMoveMemory(pAd->StaActive.SupportedPhyInfo. - MCSSet, HtCapability.MCSSet, 16); - pAd->MlmeAux.NewExtChannelOffset = - NewExtChannelOffset; - pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE; - pAd->StaActive.SupportedPhyInfo.bHtEnable = - TRUE; - if (PreNHtCapabilityLen > 0) - pAd->StaActive.SupportedPhyInfo. - bPreNHt = TRUE; - RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, - &AddHtInfo); - /* Copy AP Parameter to StaActive. This is also in LinkUp. */ - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n", - pAd->StaActive.SupportedHtPhy. - MpduDensity, - pAd->StaActive.SupportedHtPhy. - MaxRAmpduFactor, - HtCapability.HtCapInfo.ChannelWidth)); - - if (AddHtInfoLen > 0) { - CentralChannel = AddHtInfo.ControlChan; - /* Check again the Bandwidth capability of this AP. */ - if ((AddHtInfo.ControlChan > 2) - && (AddHtInfo.AddHtInfo. - ExtChanOffset == EXTCHA_BELOW) - && (HtCapability.HtCapInfo. - ChannelWidth == BW_40)) { - CentralChannel = - AddHtInfo.ControlChan - 2; - } else - if ((AddHtInfo.AddHtInfo. - ExtChanOffset == EXTCHA_ABOVE) - && (HtCapability.HtCapInfo. - ChannelWidth == BW_40)) { - CentralChannel = - AddHtInfo.ControlChan + 2; - } - /* Check Error . */ - if (pAd->MlmeAux.CentralChannel != - CentralChannel) - DBGPRINT(RT_DEBUG_ERROR, - ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", - CentralChannel, - AddHtInfo.ControlChan, - pAd->MlmeAux. - CentralChannel)); - - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", - CentralChannel, - AddHtInfo.ControlChan)); - - } - - } else { - /* To prevent error, let legacy AP must have same CentralChannel and Channel. */ - if ((HtCapabilityLen == 0) - && (PreNHtCapabilityLen == 0)) - pAd->MlmeAux.CentralChannel = - pAd->MlmeAux.Channel; - - pAd->StaActive.SupportedPhyInfo.bHtEnable = - FALSE; - pAd->MlmeAux.NewExtChannelOffset = 0xff; - RTMPZeroMemory(&pAd->MlmeAux.HtCapability, - SIZE_HT_CAP_IE); - pAd->MlmeAux.HtCapabilityLen = 0; - RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, - SIZE_ADD_HT_INFO_IE); - } - - RTMPUpdateMlmeRate(pAd); - - /* copy QOS related information */ - if ((pAd->CommonCfg.bWmmCapable) - || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) - ) { - NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, - &EdcaParm, sizeof(struct rt_edca_parm)); - NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, - &QbssLoad, - sizeof(struct rt_qbss_load_parm)); - NdisMoveMemory(&pAd->MlmeAux.APQosCapability, - &QosCapability, - sizeof(struct rt_qos_capability_parm)); - } else { - NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, - sizeof(struct rt_edca_parm)); - NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, - sizeof(struct rt_qbss_load_parm)); - NdisZeroMemory(&pAd->MlmeAux.APQosCapability, - sizeof(struct rt_qos_capability_parm)); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", - pAd->MlmeAux.SupRateLen, - pAd->MlmeAux.ExtRateLen)); - - if (AironetCellPowerLimit != 0xFF) { - /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ - ChangeToCellPowerLimit(pAd, - AironetCellPowerLimit); - } else /*Used the default TX Power Percentage. */ - pAd->CommonCfg.TxPowerPercentage = - pAd->CommonCfg.TxPowerDefault; - - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_SUCCESS; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, - 2, &Status); - } - /* not to me BEACON, ignored */ - } - /* sanity check fail, ignore this frame */ -} - -/* - ========================================================================== - Description: - receive BEACON from peer - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; - char Ssid[MAX_LEN_OF_SSID]; - struct rt_cf_parm CfParm; - u8 SsidLen, MessageToMe = 0, BssType, Channel, NewChannel, index = 0; - u8 DtimCount = 0, DtimPeriod = 0, BcastFlag = 0; - u16 CapabilityInfo, AtimWin, BeaconPeriod; - LARGE_INTEGER TimeStamp; - u16 TbttNumToNextWakeUp; - u8 Erp; - u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], - ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; - u8 SupRateLen, ExtRateLen; - u8 CkipFlag; - u16 LenVIE; - u8 AironetCellPowerLimit; - struct rt_edca_parm EdcaParm; - struct rt_qbss_load_parm QbssLoad; - struct rt_qos_capability_parm QosCapability; - unsigned long RalinkIe; - /* New for WPA security suites */ - u8 VarIE[MAX_VIE_LEN]; /* Total VIE length = MAX_VIE_LEN - -5 */ - struct rt_ndis_802_11_variable_ies *pVIE = NULL; - struct rt_ht_capability_ie HtCapability; - struct rt_add_ht_info_ie AddHtInfo; /* AP might use this additional ht info IE */ - u8 HtCapabilityLen, PreNHtCapabilityLen; - u8 AddHtInfoLen; - u8 NewExtChannelOffset = 0xff; - - if (!(INFRA_ON(pAd) || ADHOC_ON(pAd) - )) - return; - - /* Init Variable IE structure */ - pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE; - pVIE->Length = 0; - RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); - RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie)); - - if (PeerBeaconAndProbeRspSanity(pAd, - Elem->Msg, - Elem->MsgLen, - Elem->Channel, - Addr2, - Bssid, - Ssid, - &SsidLen, - &BssType, - &BeaconPeriod, - &Channel, - &NewChannel, - &TimeStamp, - &CfParm, - &AtimWin, - &CapabilityInfo, - &Erp, - &DtimCount, - &DtimPeriod, - &BcastFlag, - &MessageToMe, - SupRate, - &SupRateLen, - ExtRate, - &ExtRateLen, - &CkipFlag, - &AironetCellPowerLimit, - &EdcaParm, - &QbssLoad, - &QosCapability, - &RalinkIe, - &HtCapabilityLen, - &PreNHtCapabilityLen, - &HtCapability, - &AddHtInfoLen, - &AddHtInfo, - &NewExtChannelOffset, &LenVIE, pVIE)) { - BOOLEAN is_my_bssid, is_my_ssid; - unsigned long Bssidx, Now; - struct rt_bss_entry *pBss; - char RealRssi = - RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), - ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), - ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); - - is_my_bssid = - MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE; - is_my_ssid = - SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, - pAd->CommonCfg.SsidLen) ? TRUE : FALSE; - - /* ignore BEACON not for my SSID */ - if ((!is_my_ssid) && (!is_my_bssid)) - return; - - /* It means STA waits disassoc completely from this AP, ignores this beacon. */ - if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC) - return; - - /* Copy Control channel for this BSSID. */ - if (AddHtInfoLen != 0) - Channel = AddHtInfo.ControlChan; - - if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) - HtCapabilityLen = SIZE_HT_CAP_IE; - - /* */ - /* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */ - /* */ - Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); - if (Bssidx == BSS_NOT_FOUND) { - /* discover new AP of this network, create BSS entry */ - Bssidx = - BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, - SsidLen, BssType, BeaconPeriod, - &CfParm, AtimWin, CapabilityInfo, - SupRate, SupRateLen, ExtRate, - ExtRateLen, &HtCapability, - &AddHtInfo, HtCapabilityLen, - AddHtInfoLen, NewExtChannelOffset, - Channel, RealRssi, TimeStamp, - CkipFlag, &EdcaParm, - &QosCapability, &QbssLoad, LenVIE, - pVIE); - if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ - return; - - NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, - &Elem->Msg[24], 4); - NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], - &Elem->TimeStamp.u.LowPart, 4); - NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], - &Elem->TimeStamp.u.LowPart, 4); - - } - - if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) - && (Channel != NewChannel)) { - /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */ - /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */ - AsicSwitchChannel(pAd, 1, FALSE); - AsicLockChannel(pAd, 1); - LinkDown(pAd, FALSE); - MlmeQueueInit(&pAd->Mlme.Queue); - BssTableInit(&pAd->ScanTab); - RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */ - - /* channel sanity check */ - for (index = 0; index < pAd->ChannelListNum; index++) { - if (pAd->ChannelList[index].Channel == - NewChannel) { - pAd->ScanTab.BssEntry[Bssidx].Channel = - NewChannel; - pAd->CommonCfg.Channel = NewChannel; - AsicSwitchChannel(pAd, - pAd->CommonCfg. - Channel, FALSE); - AsicLockChannel(pAd, - pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", - NewChannel)); - break; - } - } - - if (index >= pAd->ChannelListNum) { - DBGPRINT_ERR("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum); - } - } - /* if the ssid matched & bssid unmatched, we should select the bssid with large value. */ - /* This might happened when two STA start at the same time */ - if ((!is_my_bssid) && ADHOC_ON(pAd)) { - int i; - - /* Add the safeguard against the mismatch of adhoc wep status */ - if (pAd->StaCfg.WepStatus != - pAd->ScanTab.BssEntry[Bssidx].WepStatus) { - return; - } - /* collapse into the ADHOC network which has bigger BSSID value. */ - for (i = 0; i < 6; i++) { - if (Bssid[i] > pAd->CommonCfg.Bssid[i]) { - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - merge to the IBSS " - "with bigger BSSID=" - "%pM\n", Bssid)); - AsicDisableSync(pAd); - COPY_MAC_ADDR(pAd->CommonCfg.Bssid, - Bssid); - AsicSetBssid(pAd, pAd->CommonCfg.Bssid); - MakeIbssBeacon(pAd); /* re-build BEACON frame */ - AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ - is_my_bssid = TRUE; - break; - } else if (Bssid[i] < pAd->CommonCfg.Bssid[i]) - break; - } - } - - NdisGetSystemUpTime(&Now); - pBss = &pAd->ScanTab.BssEntry[Bssidx]; - pBss->Rssi = RealRssi; /* lastest RSSI */ - pBss->LastBeaconRxTime = Now; /* last RX timestamp */ - - /* */ - /* BEACON from my BSSID - either IBSS or INFRA network */ - /* */ - if (is_my_bssid) { - struct rt_rxwi RxWI; - - pAd->StaCfg.DtimCount = DtimCount; - pAd->StaCfg.DtimPeriod = DtimPeriod; - pAd->StaCfg.LastBeaconRxTime = Now; - - RxWI.RSSI0 = Elem->Rssi0; - RxWI.RSSI1 = Elem->Rssi1; - RxWI.RSSI2 = Elem->Rssi2; - - Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI); - if (AironetCellPowerLimit != 0xFF) { - /* */ - /* We get the Cisco (ccx) "TxPower Limit" required */ - /* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */ - /* */ - ChangeToCellPowerLimit(pAd, - AironetCellPowerLimit); - } else { - /* */ - /* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */ - /* Used the default TX Power Percentage, that set from UI. */ - /* */ - pAd->CommonCfg.TxPowerPercentage = - pAd->CommonCfg.TxPowerDefault; - } - - if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) { - u8 MaxSupportedRateIn500Kbps = 0; - u8 idx; - struct rt_mac_table_entry *pEntry; - - /* supported rates array may not be sorted. sort it and find the maximum rate */ - for (idx = 0; idx < SupRateLen; idx++) { - if (MaxSupportedRateIn500Kbps < - (SupRate[idx] & 0x7f)) - MaxSupportedRateIn500Kbps = - SupRate[idx] & 0x7f; - } - - for (idx = 0; idx < ExtRateLen; idx++) { - if (MaxSupportedRateIn500Kbps < - (ExtRate[idx] & 0x7f)) - MaxSupportedRateIn500Kbps = - ExtRate[idx] & 0x7f; - } - - /* look up the existing table */ - pEntry = MacTableLookup(pAd, Addr2); - - /* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. */ - /* To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */ - if ((ADHOC_ON(pAd) - && (Elem->Wcid == RESERVED_WCID)) - || (pEntry - && - ((pEntry->LastBeaconRxTime + - ADHOC_ENTRY_BEACON_LOST_TIME) < - Now))) { - if (pEntry == NULL) - /* Another adhoc joining, add to our MAC table. */ - pEntry = - MacTableInsertEntry(pAd, - Addr2, - BSS0, - FALSE); - - if (StaAddMacTableEntry(pAd, - pEntry, - MaxSupportedRateIn500Kbps, - &HtCapability, - HtCapabilityLen, - &AddHtInfo, - AddHtInfoLen, - CapabilityInfo) - == FALSE) { - DBGPRINT(RT_DEBUG_TRACE, - ("ADHOC - Add Entry failed.\n")); - return; - } - - if (pEntry && - (Elem->Wcid == RESERVED_WCID)) { - idx = pAd->StaCfg.DefaultKeyId; - RTMP_STA_SECURITY_INFO_ADD(pAd, - BSS0, - idx, - pEntry); - } - } - - if (pEntry && pEntry->ValidAsCLI) - pEntry->LastBeaconRxTime = Now; - - /* At least another peer in this IBSS, declare MediaState as CONNECTED */ - if (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - OPSTATUS_SET_FLAG(pAd, - fOP_STATUS_MEDIA_STATE_CONNECTED); - - pAd->IndicateMediaState = - NdisMediaStateConnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_UP; - AsicSetBssid(pAd, pAd->CommonCfg.Bssid); - - /* 2003/03/12 - john */ - /* Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that */ - /* "site survey" result should always include the current connected network. */ - /* */ - Bssidx = - BssTableSearch(&pAd->ScanTab, Bssid, - Channel); - if (Bssidx == BSS_NOT_FOUND) { - Bssidx = - BssTableSetEntry(pAd, - &pAd-> - ScanTab, - Bssid, - Ssid, - SsidLen, - BssType, - BeaconPeriod, - &CfParm, - AtimWin, - CapabilityInfo, - SupRate, - SupRateLen, - ExtRate, - ExtRateLen, - &HtCapability, - &AddHtInfo, - HtCapabilityLen, - AddHtInfoLen, - NewExtChannelOffset, - Channel, - RealRssi, - TimeStamp, - 0, - &EdcaParm, - &QosCapability, - &QbssLoad, - LenVIE, - pVIE); - } - DBGPRINT(RT_DEBUG_TRACE, - ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); - } - } - - if (INFRA_ON(pAd)) { - BOOLEAN bUseShortSlot, bUseBGProtection; - - /* decide to use/change to - */ - /* 1. long slot (20 us) or short slot (9 us) time */ - /* 2. turn on/off RTS/CTS and/or CTS-to-self protection */ - /* 3. short preamble */ - - /*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */ - bUseShortSlot = - CAP_IS_SHORT_SLOT(CapabilityInfo); - if (bUseShortSlot != - OPSTATUS_TEST_FLAG(pAd, - fOP_STATUS_SHORT_SLOT_INUSED)) - AsicSetSlotTime(pAd, bUseShortSlot); - - bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || /* always use */ - ((pAd->CommonCfg.UseBGProtection == 0) - && ERP_IS_USE_PROTECTION(Erp)); - - if (pAd->CommonCfg.Channel > 14) /* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */ - bUseBGProtection = FALSE; - - if (bUseBGProtection != - OPSTATUS_TEST_FLAG(pAd, - fOP_STATUS_BG_PROTECTION_INUSED)) - { - if (bUseBGProtection) { - OPSTATUS_SET_FLAG(pAd, - fOP_STATUS_BG_PROTECTION_INUSED); - AsicUpdateProtect(pAd, - pAd->MlmeAux. - AddHtInfo. - AddHtInfo2. - OperaionMode, - (OFDMSETPROTECT - | - CCKSETPROTECT - | - ALLN_SETPROTECT), - FALSE, - (pAd->MlmeAux. - AddHtInfo. - AddHtInfo2. - NonGfPresent - == 1)); - } else { - OPSTATUS_CLEAR_FLAG(pAd, - fOP_STATUS_BG_PROTECTION_INUSED); - AsicUpdateProtect(pAd, - pAd->MlmeAux. - AddHtInfo. - AddHtInfo2. - OperaionMode, - (OFDMSETPROTECT - | - CCKSETPROTECT - | - ALLN_SETPROTECT), - TRUE, - (pAd->MlmeAux. - AddHtInfo. - AddHtInfo2. - NonGfPresent - == 1)); - } - - DBGPRINT(RT_DEBUG_WARN, - ("SYNC - AP changed B/G protection to %d\n", - bUseBGProtection)); - } - /* check Ht protection mode. and adhere to the Non-GF device indication by AP. */ - if ((AddHtInfoLen != 0) && - ((AddHtInfo.AddHtInfo2.OperaionMode != - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - OperaionMode) - || (AddHtInfo.AddHtInfo2.NonGfPresent != - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - NonGfPresent))) { - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - NonGfPresent = - AddHtInfo.AddHtInfo2.NonGfPresent; - pAd->MlmeAux.AddHtInfo.AddHtInfo2. - OperaionMode = - AddHtInfo.AddHtInfo2.OperaionMode; - if (pAd->MlmeAux.AddHtInfo.AddHtInfo2. - NonGfPresent == 1) { - AsicUpdateProtect(pAd, - pAd->MlmeAux. - AddHtInfo. - AddHtInfo2. - OperaionMode, - ALLN_SETPROTECT, - FALSE, TRUE); - } else - AsicUpdateProtect(pAd, - pAd->MlmeAux. - AddHtInfo. - AddHtInfo2. - OperaionMode, - ALLN_SETPROTECT, - FALSE, FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - AP changed N OperaionMode to %d\n", - pAd->MlmeAux.AddHtInfo. - AddHtInfo2.OperaionMode)); - } - - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) - && ERP_IS_USE_BARKER_PREAMBLE(Erp)) { - MlmeSetTxPreamble(pAd, - Rt802_11PreambleLong); - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - AP forced to use long preamble\n")); - } - - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_WMM_INUSED) - && (EdcaParm.bValid == TRUE) - && (EdcaParm.EdcaUpdateCount != - pAd->CommonCfg.APEdcaParm. - EdcaUpdateCount)) { - DBGPRINT(RT_DEBUG_TRACE, - ("SYNC - AP change EDCA parameters(from %d to %d)\n", - pAd->CommonCfg.APEdcaParm. - EdcaUpdateCount, - EdcaParm.EdcaUpdateCount)); - AsicSetEdcaParm(pAd, &EdcaParm); - } - /* copy QOS related information */ - NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, - &QbssLoad, - sizeof(struct rt_qbss_load_parm)); - NdisMoveMemory(&pAd->CommonCfg.APQosCapability, - &QosCapability, - sizeof(struct rt_qos_capability_parm)); - } - /* only INFRASTRUCTURE mode support power-saving feature */ - if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) - || (pAd->CommonCfg.bAPSDForcePowerSave)) { - u8 FreeNumber; - /* 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL */ - /* 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE */ - /* 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE */ - /* 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE */ - /* 5. otherwise, put PHY back to sleep to save battery. */ - if (MessageToMe) { -#ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_PCIE_DEVICE)) { - /* Restore to correct BBP R3 value */ - if (pAd->Antenna.field.RxPath > - 1) - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R3, - pAd->StaCfg.BBPR3); - /* Turn clk to 80Mhz. */ - } -#endif /* RTMP_MAC_PCI // */ - if (pAd->CommonCfg.bAPSDCapable - && pAd->CommonCfg.APEdcaParm. - bAPSDCapable - && pAd->CommonCfg.bAPSDAC_BE - && pAd->CommonCfg.bAPSDAC_BK - && pAd->CommonCfg.bAPSDAC_VI - && pAd->CommonCfg.bAPSDAC_VO) { - pAd->CommonCfg. - bNeedSendTriggerFrame = - TRUE; - } else - RTMP_PS_POLL_ENQUEUE(pAd); - } else if (BcastFlag && (DtimCount == 0) - && OPSTATUS_TEST_FLAG(pAd, - fOP_STATUS_RECEIVE_DTIM)) - { -#ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_PCIE_DEVICE)) { - if (pAd->Antenna.field.RxPath > - 1) - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R3, - pAd->StaCfg.BBPR3); - } -#endif /* RTMP_MAC_PCI // */ - } else - if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) - || (pAd->TxSwQueue[QID_AC_BE].Number != - 0) - || (pAd->TxSwQueue[QID_AC_VI].Number != - 0) - || (pAd->TxSwQueue[QID_AC_VO].Number != - 0) - || - (RTMPFreeTXDRequest - (pAd, QID_AC_BK, TX_RING_SIZE - 1, - &FreeNumber) != NDIS_STATUS_SUCCESS) - || - (RTMPFreeTXDRequest - (pAd, QID_AC_BE, TX_RING_SIZE - 1, - &FreeNumber) != NDIS_STATUS_SUCCESS) - || - (RTMPFreeTXDRequest - (pAd, QID_AC_VI, TX_RING_SIZE - 1, - &FreeNumber) != NDIS_STATUS_SUCCESS) - || - (RTMPFreeTXDRequest - (pAd, QID_AC_VO, TX_RING_SIZE - 1, - &FreeNumber) != NDIS_STATUS_SUCCESS) - || - (RTMPFreeTXDRequest - (pAd, QID_MGMT, MGMT_RING_SIZE - 1, - &FreeNumber) != - NDIS_STATUS_SUCCESS)) { - /* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */ - /* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */ -#ifdef RTMP_MAC_PCI - if (OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_PCIE_DEVICE)) { - if (pAd->Antenna.field.RxPath > - 1) - RTMP_BBP_IO_WRITE8_BY_REG_ID - (pAd, BBP_R3, - pAd->StaCfg.BBPR3); - } -#endif /* RTMP_MAC_PCI // */ - } else { - if ((pAd->CommonCfg. - bACMAPSDTr[QID_AC_VO]) - || (pAd->CommonCfg. - bACMAPSDTr[QID_AC_VI]) - || (pAd->CommonCfg. - bACMAPSDTr[QID_AC_BK]) - || (pAd->CommonCfg. - bACMAPSDTr[QID_AC_BE])) { - /* - WMM Spec v1.0 3.6.2.4, - The WMM STA shall remain awake until it receives a - QoS Data or Null frame addressed to it, with the - EOSP subfield in QoS Control field set to 1. - - So we can not sleep here or we will suffer a case: - - PS Management Frame --> - Trigger frame --> - Beacon (TIM=0) (Beacon is closer to Trig frame) --> - Station goes to sleep --> - AP delivery queued UAPSD packets --> - Station can NOT receive the reply - - Maybe we need a timeout timer to avoid that we do - NOT receive the EOSP frame. - - We can not use More Data to check if SP is ended - due to MaxSPLength. - */ - } else { - u16 NextDtim = DtimCount; - - if (NextDtim == 0) - NextDtim = DtimPeriod; - - TbttNumToNextWakeUp = - pAd->StaCfg. - DefaultListenCount; - if (OPSTATUS_TEST_FLAG - (pAd, - fOP_STATUS_RECEIVE_DTIM) - && (TbttNumToNextWakeUp > - NextDtim)) - TbttNumToNextWakeUp = - NextDtim; - - if (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_DOZE)) { - /* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */ - pAd-> - ThisTbttNumToNextWakeUp - = - TbttNumToNextWakeUp; - AsicSleepThenAutoWakeup - (pAd, - pAd-> - ThisTbttNumToNextWakeUp); - } - } - } - } - } - /* not my BSSID, ignore it */ - } - /* sanity check fail, ignore this frame */ -} - -/* - ========================================================================== - Description: - Receive PROBE REQ from remote peer when operating in IBSS mode - ========================================================================== - */ -void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 Addr2[MAC_ADDR_LEN]; - char Ssid[MAX_LEN_OF_SSID]; - u8 SsidLen; - u8 HtLen, AddHtLen, NewExtLen; - struct rt_header_802_11 ProbeRspHdr; - int NStatus; - u8 *pOutBuffer = NULL; - unsigned long FrameLen = 0; - LARGE_INTEGER FakeTimestamp; - u8 DsLen = 1, IbssLen = 2; - u8 LocalErpIe[3] = { IE_ERP, 1, 0 }; - BOOLEAN Privacy; - u16 CapabilityInfo; - u8 RSNIe = IE_WPA; - - if (!ADHOC_ON(pAd)) - return; - - if (PeerProbeReqSanity - (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) { - if ((SsidLen == 0) - || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, - pAd->CommonCfg.SsidLen)) { - /* allocate and send out ProbeRsp frame */ - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - /*pAd->StaCfg.AtimWin = 0; // ?????? */ - - Privacy = - (pAd->StaCfg.WepStatus == - Ndis802_11Encryption1Enabled) - || (pAd->StaCfg.WepStatus == - Ndis802_11Encryption2Enabled) - || (pAd->StaCfg.WepStatus == - Ndis802_11Encryption3Enabled); - CapabilityInfo = - CAP_GENERATE(0, 1, Privacy, - (pAd->CommonCfg.TxPreamble == - Rt802_11PreambleShort), 0, 0); - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &ProbeRspHdr, - TIMESTAMP_LEN, &FakeTimestamp, - 2, &pAd->CommonCfg.BeaconPeriod, - 2, &CapabilityInfo, - 1, &SsidIe, - 1, &pAd->CommonCfg.SsidLen, - pAd->CommonCfg.SsidLen, - pAd->CommonCfg.Ssid, 1, &SupRateIe, 1, - &pAd->StaActive.SupRateLen, - pAd->StaActive.SupRateLen, - pAd->StaActive.SupRate, 1, &DsIe, 1, - &DsLen, 1, &pAd->CommonCfg.Channel, 1, - &IbssIe, 1, &IbssLen, 2, - &pAd->StaActive.AtimWin, END_OF_ARGS); - - if (pAd->StaActive.ExtRateLen) { - unsigned long tmp; - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 3, LocalErpIe, - 1, &ExtRateIe, - 1, &pAd->StaActive.ExtRateLen, - pAd->StaActive.ExtRateLen, - &pAd->StaActive.ExtRate, - END_OF_ARGS); - FrameLen += tmp; - } - /* If adhoc secruity is set for WPA-None, append the cipher suite IE */ - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { - unsigned long tmp; - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &RSNIe, - 1, &pAd->StaCfg.RSNIE_Len, - pAd->StaCfg.RSNIE_Len, - pAd->StaCfg.RSN_IE, - END_OF_ARGS); - FrameLen += tmp; - } - - if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { - unsigned long TmpLen; - u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 }; - HtLen = sizeof(pAd->CommonCfg.HtCapability); - AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); - NewExtLen = 1; - /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ - if (pAd->bBroadComHT == TRUE) { - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 1, &WpaIe, 4, - &BROADCOM[0], - pAd->MlmeAux. - HtCapabilityLen, - &pAd->MlmeAux. - HtCapability, - END_OF_ARGS); - } else { - MakeOutgoingFrame(pOutBuffer + FrameLen, - &TmpLen, 1, &HtCapIe, - 1, &HtLen, - sizeof - (struct rt_ht_capability_ie), - &pAd->CommonCfg. - HtCapability, 1, - &AddHtInfoIe, 1, - &AddHtLen, - sizeof - (struct rt_add_ht_info_ie), - &pAd->CommonCfg. - AddHTInfo, 1, - &NewExtChanIe, 1, - &NewExtLen, - sizeof - (struct rt_new_ext_chan_ie), - &pAd->CommonCfg. - NewExtChanOffset, - END_OF_ARGS); - } - FrameLen += TmpLen; - } - - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - } - } -} - -void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n")); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_REJ_TIMEOUT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - Scan timeout procedure. basically add channel index by 1 and rescan - ========================================================================== - */ -void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel); - - /* Only one channel scanned for CISCO beacon request */ - if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) || - (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) || - (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) || - (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD)) - pAd->MlmeAux.Channel = 0; - - /* this routine will stop if pAd->MlmeAux.Channel == 0 */ - ScanNextChannel(pAd); -} - -/* - ========================================================================== - Description: - ========================================================================== - */ -void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", - pAd->Mlme.SyncMachine.CurrState)); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - ========================================================================== - */ -void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", - pAd->Mlme.SyncMachine.CurrState)); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - ========================================================================== - */ -void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u16 Status; - DBGPRINT(RT_DEBUG_TRACE, - ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", - pAd->Mlme.SyncMachine.CurrState)); - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -void EnqueuePsPoll(struct rt_rtmp_adapter *pAd) -{ - - if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP) - pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE; - MiniportMMRequest(pAd, 0, (u8 *)& pAd->PsPollFrame, - sizeof(struct rt_pspoll_frame)); -} - -/* - ========================================================================== - Description: - ========================================================================== - */ -void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd) -{ - int NState; - u8 *pOutBuffer; - unsigned long FrameLen = 0; - struct rt_header_802_11 Hdr80211; - - DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n")); - - NState = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ - if (NState == NDIS_STATUS_SUCCESS) { - MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, - BROADCAST_ADDR, BROADCAST_ADDR); - - /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */ - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(struct rt_header_802_11), &Hdr80211, - 1, &SsidIe, - 1, &pAd->CommonCfg.SsidLen, - pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, - 1, &SupRateIe, - 1, &pAd->StaActive.SupRateLen, - pAd->StaActive.SupRateLen, - pAd->StaActive.SupRate, END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - } - -} - -BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd) -{ - return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE; -} diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c deleted file mode 100644 index ff348325028b..000000000000 --- a/drivers/staging/rt2860/sta/wpa.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - wpa.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Jan Lee 03-07-22 Initial - Paul Lin 03-11-28 Modify for supplicant - Justin P. Mattock 11/07/2010 Fix typos -*/ -#include "../rt_config.h" - -void inc_byte_array(u8 * counter, int len); - -/* - ======================================================================== - - Routine Description: - Process MIC error indication and record MIC error timer. - - Arguments: - pAd Pointer to our adapter - pWpaKey Pointer to the WPA key structure - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaKey) -{ - unsigned long Now; - u8 unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1 : 0); - - /* Record Last MIC error time and count */ - NdisGetSystemUpTime(&Now); - if (pAd->StaCfg.MicErrCnt == 0) { - pAd->StaCfg.MicErrCnt++; - pAd->StaCfg.LastMicErrorTime = Now; - NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); - } else if (pAd->StaCfg.MicErrCnt == 1) { - if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now) { - /* Update Last MIC error time, this did not violate two MIC errors within 60 seconds */ - pAd->StaCfg.LastMicErrorTime = Now; - } else { - - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_COUNTER_MEASURES_EVENT_FLAG, - pAd->MacTab. - Content[BSSID_WCID].Addr, - BSS0, 0); - - pAd->StaCfg.LastMicErrorTime = Now; - /* Violate MIC error counts, MIC countermeasures kicks in */ - pAd->StaCfg.MicErrCnt++; - /* We shall block all reception */ - /* We shall clean all Tx ring and disassociate from AP after next EAPOL frame */ - /* */ - /* No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets */ - /* if pAd->StaCfg.MicErrCnt greater than 2. */ - /* */ - /* RTMPRingCleanUp(pAd, QID_AC_BK); */ - /* RTMPRingCleanUp(pAd, QID_AC_BE); */ - /* RTMPRingCleanUp(pAd, QID_AC_VI); */ - /* RTMPRingCleanUp(pAd, QID_AC_VO); */ - /* RTMPRingCleanUp(pAd, QID_HCCA); */ - } - } else { - /* MIC error count >= 2 */ - /* This should not happen */ - ; - } - MlmeEnqueue(pAd, - MLME_CNTL_STATE_MACHINE, - OID_802_11_MIC_FAILURE_REPORT_FRAME, 1, &unicastKey); - - if (pAd->StaCfg.MicErrCnt == 2) { - RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100); - } -} - -#define LENGTH_EAP_H 4 -/* If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)). */ -int WpaCheckEapCode(struct rt_rtmp_adapter *pAd, - u8 *pFrame, u16 FrameLen, u16 OffSet) -{ - - u8 *pData; - int result = 0; - - if (FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H) - return result; - - pData = pFrame + OffSet; /* skip offset bytes */ - - if (*(pData + 1) == EAPPacket) /* 802.1x header - Packet Type */ - { - result = *(pData + 4); /* EAP header - Code */ - } - - return result; -} - -void WpaSendMicFailureToWpaSupplicant(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUnicast) -{ - char custom[IW_CUSTOM_MAX] = { 0 }; - - sprintf(custom, "MLME-MICHAELMICFAILURE.indication"); - if (bUnicast) - sprintf(custom, "%s unicast", custom); - - RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, (u8 *)custom, - strlen(custom)); - - return; -} - -void WpaMicFailureReportFrame(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - u8 *pOutBuffer = NULL; - u8 Header802_3[14]; - unsigned long FrameLen = 0; - struct rt_eapol_packet Packet; - u8 Mic[16]; - BOOLEAN bUnicast; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n")); - - bUnicast = (Elem->Msg[0] == 1 ? TRUE : FALSE); - pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER); - - /* init 802.3 header and Fill Packet */ - MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, - pAd->CurrentAddress, EAPOL); - - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.ProVer = EAPOL_VER; - Packet.ProType = EAPOLKey; - - Packet.KeyDesc.Type = WPA1_KEY_DESC; - - /* Request field presented */ - Packet.KeyDesc.KeyInfo.Request = 1; - - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { - Packet.KeyDesc.KeyInfo.KeyDescVer = 2; - } else /* TKIP */ - { - Packet.KeyDesc.KeyInfo.KeyDescVer = 1; - } - - Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY); - - /* KeyMic field presented */ - Packet.KeyDesc.KeyInfo.KeyMic = 1; - - /* Error field presented */ - Packet.KeyDesc.KeyInfo.Error = 1; - - /* Update packet length after decide Key data payload */ - SET_u16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG) - /* Key Replay Count */ - NdisMoveMemory(Packet.KeyDesc.ReplayCounter, - pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); - inc_byte_array(pAd->StaCfg.ReplayCounter, 8); - - /* Convert to little-endian format. */ - *((u16 *) & Packet.KeyDesc.KeyInfo) = - cpu2le16(*((u16 *) & Packet.KeyDesc.KeyInfo)); - - MlmeAllocateMemory(pAd, (u8 **) & pOutBuffer); /* allocate memory */ - if (pOutBuffer == NULL) { - return; - } - /* Prepare EAPOL frame for MIC calculation */ - /* Be careful, only EAPOL frame is counted for MIC calculation */ - MakeOutgoingFrame(pOutBuffer, &FrameLen, - CONV_ARRARY_TO_u16(Packet.Body_Len) + 4, &Packet, - END_OF_ARGS); - - /* Prepare and Fill MIC value */ - NdisZeroMemory(Mic, sizeof(Mic)); - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { /* AES */ - u8 digest[20] = { 0 }; - HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, - digest, SHA1_DIGEST_SIZE); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } else { /* TKIP */ - HMAC_MD5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, - Mic, MD5_DIGEST_SIZE); - } - NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - - /* copy frame to Tx ring and send MIC failure report frame to authenticator */ - RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID], - Header802_3, LENGTH_802_3, - (u8 *)& Packet, - CONV_ARRARY_TO_u16(Packet.Body_Len) + 4, FALSE); - - MlmeFreeMemory(pAd, (u8 *)pOutBuffer); - - DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n")); -} - -/** from wpa_supplicant - * inc_byte_array - Increment arbitrary length byte array by one - * @counter: Pointer to byte array - * @len: Length of the counter in bytes - * - * This function increments the last byte of the counter by one and continues - * rolling over to more significant bytes if the byte was incremented from - * 0xff to 0x00. - */ -void inc_byte_array(u8 * counter, int len) -{ - int pos = len - 1; - while (pos >= 0) { - counter[pos]++; - if (counter[pos] != 0) - break; - pos--; - } -} - -void WpaDisassocApAndBlockAssoc(void *SystemSpecific1, - void *FunctionContext, - void *SystemSpecific2, - void *SystemSpecific3) -{ - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext; - struct rt_mlme_disassoc_req DisassocReq; - - /* disassoc from current AP first */ - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n")); - DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, - REASON_MIC_FAILURE); - MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, - sizeof(struct rt_mlme_disassoc_req), &DisassocReq); - - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; - pAd->StaCfg.bBlockAssoc = TRUE; -} - -void WpaStaPairwiseKeySetting(struct rt_rtmp_adapter *pAd) -{ - struct rt_cipher_key *pSharedKey; - struct rt_mac_table_entry *pEntry; - - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - - /* Pairwise key shall use key#0 */ - pSharedKey = &pAd->SharedKey[BSS0][0]; - - NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); - - /* Prepare pair-wise key information into shared key table */ - NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key)); - pSharedKey->KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); - NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], - LEN_TKIP_RXMICK); - NdisMoveMemory(pSharedKey->TxMic, - &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); - - /* Decide its ChiperAlg */ - if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) - pSharedKey->CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) - pSharedKey->CipherAlg = CIPHER_AES; - else - pSharedKey->CipherAlg = CIPHER_NONE; - - /* Update these related information to struct rt_mac_table_entry */ - NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], - LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, - &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); - pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg; - - /* Update pairwise key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pSharedKey->CipherAlg, - pSharedKey->Key, - pSharedKey->TxMic, pSharedKey->RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pSharedKey->CipherAlg, pEntry); - STA_PORT_SECURED(pAd); - pAd->IndicateMediaState = NdisMediaStateConnected; - - DBGPRINT(RT_DEBUG_TRACE, - ("%s : AID(%d) port secured\n", __func__, pEntry->Aid)); - -} - -void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd) -{ - struct rt_cipher_key *pSharedKey; - - pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]; - - /* Prepare pair-wise key information into shared key table */ - NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key)); - pSharedKey->KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK); - NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], - LEN_TKIP_RXMICK); - NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], - LEN_TKIP_TXMICK); - - /* Update Shared Key CipherAlg */ - pSharedKey->CipherAlg = CIPHER_NONE; - if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) - pSharedKey->CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) - pSharedKey->CipherAlg = CIPHER_AES; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) - pSharedKey->CipherAlg = CIPHER_WEP64; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled) - pSharedKey->CipherAlg = CIPHER_WEP128; - - /* Update group key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pSharedKey->CipherAlg, - pSharedKey->Key, - pSharedKey->TxMic, pSharedKey->RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pSharedKey->CipherAlg, NULL); - -} diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c deleted file mode 100644 index 49b1013e7a03..000000000000 --- a/drivers/staging/rt2860/sta_ioctl.c +++ /dev/null @@ -1,2912 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - sta_ioctl.c - - Abstract: - IOCTL related subroutines - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Rory Chen 01-03-2003 created - Rory Chen 02-14-2005 modify to support RT61 - Justin P. Mattock 11/07/2010 Fix typos -*/ - -#include "rt_config.h" - -#ifdef DBG -extern unsigned long RTDebugLevel; -#endif - -#define NR_WEP_KEYS 4 -#define WEP_SMALL_KEY_LEN (40/8) -#define WEP_LARGE_KEY_LEN (104/8) - -#define GROUP_KEY_NO 4 - -extern u8 CipherWpa2Template[]; - -struct PACKED rt_version_info { - u8 DriverVersionW; - u8 DriverVersionX; - u8 DriverVersionY; - u8 DriverVersionZ; - u32 DriverBuildYear; - u32 DriverBuildMonth; - u32 DriverBuildDay; -}; - -static __s32 ralinkrate[] = { 2, 4, 11, 22, /* CCK */ - 12, 18, 24, 36, 48, 72, 96, 108, /* OFDM */ - 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, /* 20MHz, 800ns GI, MCS: 0 ~ 15 */ - 39, 78, 117, 156, 234, 312, 351, 390, /* 20MHz, 800ns GI, MCS: 16 ~ 23 */ - 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, /* 40MHz, 800ns GI, MCS: 0 ~ 15 */ - 81, 162, 243, 324, 486, 648, 729, 810, /* 40MHz, 800ns GI, MCS: 16 ~ 23 */ - 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, /* 20MHz, 400ns GI, MCS: 0 ~ 15 */ - 43, 87, 130, 173, 260, 317, 390, 433, /* 20MHz, 400ns GI, MCS: 16 ~ 23 */ - 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, /* 40MHz, 400ns GI, MCS: 0 ~ 15 */ - 90, 180, 270, 360, 540, 720, 810, 900 -}; - -int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg); - -int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg); - -void RTMPAddKey(struct rt_rtmp_adapter *pAd, struct rt_ndis_802_11_key *pKey) -{ - unsigned long KeyIdx; - struct rt_mac_table_entry *pEntry; - - DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n")); - - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { - if (pKey->KeyIndex & 0x80000000) { - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { - NdisZeroMemory(pAd->StaCfg.PMK, 32); - NdisMoveMemory(pAd->StaCfg.PMK, - pKey->KeyMaterial, - pKey->KeyLength); - goto end; - } - /* Update PTK */ - NdisZeroMemory(&pAd->SharedKey[BSS0][0], - sizeof(struct rt_cipher_key)); - pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, - pKey->KeyMaterial, LEN_TKIP_EK); - - if (pAd->StaCfg.PairCipher == - Ndis802_11Encryption2Enabled) { - NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, - pKey->KeyMaterial + LEN_TKIP_EK, - LEN_TKIP_TXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, - pKey->KeyMaterial + LEN_TKIP_EK + - LEN_TKIP_TXMICK, - LEN_TKIP_RXMICK); - } else { - NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, - pKey->KeyMaterial + LEN_TKIP_EK, - LEN_TKIP_TXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, - pKey->KeyMaterial + LEN_TKIP_EK + - LEN_TKIP_TXMICK, - LEN_TKIP_RXMICK); - } - - /* Decide its ChiperAlg */ - if (pAd->StaCfg.PairCipher == - Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == - Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; - else - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE; - - /* Update these related information to struct rt_mac_table_entry */ - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - NdisMoveMemory(pEntry->PairwiseKey.Key, - pAd->SharedKey[BSS0][0].Key, - LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, - pAd->SharedKey[BSS0][0].RxMic, - LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, - pAd->SharedKey[BSS0][0].TxMic, - LEN_TKIP_TXMICK); - pEntry->PairwiseKey.CipherAlg = - pAd->SharedKey[BSS0][0].CipherAlg; - - /* Update pairwise key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0].CipherAlg, - pAd->SharedKey[BSS0][0].Key, - pAd->SharedKey[BSS0][0].TxMic, - pAd->SharedKey[BSS0][0].RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0]. - CipherAlg, pEntry); - - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) { - /* set 802.1x port control */ - /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAd); - - /* Indicate Connected for GUI */ - pAd->IndicateMediaState = - NdisMediaStateConnected; - } - } else { - /* Update GTK */ - pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF); - NdisZeroMemory(&pAd-> - SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId], - sizeof(struct rt_cipher_key)); - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = - LEN_TKIP_EK; - NdisMoveMemory(pAd-> - SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId].Key, - pKey->KeyMaterial, LEN_TKIP_EK); - - if (pAd->StaCfg.GroupCipher == - Ndis802_11Encryption2Enabled) { - NdisMoveMemory(pAd-> - SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - RxMic, - pKey->KeyMaterial + LEN_TKIP_EK, - LEN_TKIP_TXMICK); - NdisMoveMemory(pAd-> - SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - TxMic, - pKey->KeyMaterial + LEN_TKIP_EK + - LEN_TKIP_TXMICK, - LEN_TKIP_RXMICK); - } else { - NdisMoveMemory(pAd-> - SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - TxMic, - pKey->KeyMaterial + LEN_TKIP_EK, - LEN_TKIP_TXMICK); - NdisMoveMemory(pAd-> - SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - RxMic, - pKey->KeyMaterial + LEN_TKIP_EK + - LEN_TKIP_TXMICK, - LEN_TKIP_RXMICK); - } - - /* Update Shared Key CipherAlg */ - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]. - CipherAlg = CIPHER_NONE; - if (pAd->StaCfg.GroupCipher == - Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]. - CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.GroupCipher == - Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]. - CipherAlg = CIPHER_AES; - - /* Update group key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pAd->SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - CipherAlg, - pAd->SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - Key, - pAd->SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - TxMic, - pAd->SharedKey[BSS0][pAd->StaCfg. - DefaultKeyId]. - RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pAd->SharedKey[BSS0][pAd-> - StaCfg. - DefaultKeyId]. - CipherAlg, NULL); - - /* set 802.1x port control */ - /*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAd); - - /* Indicate Connected for GUI */ - pAd->IndicateMediaState = NdisMediaStateConnected; - } - } else /* dynamic WEP from wpa_supplicant */ - { - u8 CipherAlg; - u8 *Key; - - if (pKey->KeyLength == 32) - goto end; - - KeyIdx = pKey->KeyIndex & 0x0fffffff; - - if (KeyIdx < 4) { - /* it is a default shared key, for Pairwise key setting */ - if (pKey->KeyIndex & 0x80000000) { - pEntry = MacTableLookup(pAd, pKey->BSSID); - - if (pEntry) { - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPAddKey: Set Pair-wise Key\n")); - - /* set key material and key length */ - pEntry->PairwiseKey.KeyLen = - (u8)pKey->KeyLength; - NdisMoveMemory(pEntry->PairwiseKey.Key, - &pKey->KeyMaterial, - pKey->KeyLength); - - /* set Cipher type */ - if (pKey->KeyLength == 5) - pEntry->PairwiseKey.CipherAlg = - CIPHER_WEP64; - else - pEntry->PairwiseKey.CipherAlg = - CIPHER_WEP128; - - /* Add Pair-wise key to Asic */ - AsicAddPairwiseKeyEntry(pAd, - pEntry->Addr, - (u8)pEntry-> - Aid, - &pEntry-> - PairwiseKey); - - /* update WCID attribute table and IVEIV table for this entry */ - RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, /* The value may be not zero */ - pEntry-> - PairwiseKey. - CipherAlg, - pEntry); - - } - } else { - /* Default key for tx (shared key) */ - pAd->StaCfg.DefaultKeyId = (u8)KeyIdx; - - /* set key material and key length */ - pAd->SharedKey[BSS0][KeyIdx].KeyLen = - (u8)pKey->KeyLength; - NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, - &pKey->KeyMaterial, - pKey->KeyLength); - - /* Set Ciper type */ - if (pKey->KeyLength == 5) - pAd->SharedKey[BSS0][KeyIdx].CipherAlg = - CIPHER_WEP64; - else - pAd->SharedKey[BSS0][KeyIdx].CipherAlg = - CIPHER_WEP128; - - CipherAlg = - pAd->SharedKey[BSS0][KeyIdx].CipherAlg; - Key = pAd->SharedKey[BSS0][KeyIdx].Key; - - /* Set Group key material to Asic */ - AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, - CipherAlg, Key, NULL, - NULL); - - /* Update WCID attribute table and IVEIV table for this group key table */ - RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, - CipherAlg, NULL); - - } - } - } -end: - return; -} - -char *rtstrchr(const char *s, int c) -{ - for (; *s != (char)c; ++s) - if (*s == '\0') - return NULL; - return (char *)s; -} - -/* -This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function -*/ - -int -rt_ioctl_giwname(struct net_device *dev, - struct iw_request_info *info, char *name, char *extra) -{ - strncpy(name, "Ralink STA", IFNAMSIZ); - /* RT2870 2.1.0.0 uses "RT2870 Wireless" */ - /* RT3090 2.1.0.0 uses "RT2860 Wireless" */ - return 0; -} - -int rt_ioctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - int chan = -1; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (freq->e > 1) - return -EINVAL; - - if ((freq->e == 0) && (freq->m <= 1000)) - chan = freq->m; /* Setting by channel number */ - else - MAP_KHZ_TO_CHANNEL_ID((freq->m / 100), chan); /* Setting by frequency - search the table , like 2.412G, 2.422G, */ - - if (ChannelSanity(pAdapter, chan) == TRUE) { - pAdapter->CommonCfg.Channel = chan; - DBGPRINT(RT_DEBUG_ERROR, - ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", - SIOCSIWFREQ, pAdapter->CommonCfg.Channel)); - } else - return -EINVAL; - - return 0; -} - -int rt_ioctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - u8 ch; - unsigned long m = 2412000; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - ch = pAdapter->CommonCfg.Channel; - - DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwfreq %d\n", ch)); - - MAP_CHANNEL_ID_TO_KHZ(ch, m); - freq->m = m * 100; - freq->e = 1; - return 0; -} - -int rt_ioctl_siwmode(struct net_device *dev, - struct iw_request_info *info, __u32 * mode, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - switch (*mode) { - case IW_MODE_ADHOC: - Set_NetworkType_Proc(pAdapter, "Adhoc"); - break; - case IW_MODE_INFRA: - Set_NetworkType_Proc(pAdapter, "Infra"); - break; - case IW_MODE_MONITOR: - Set_NetworkType_Proc(pAdapter, "Monitor"); - break; - default: - DBGPRINT(RT_DEBUG_TRACE, - ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", - *mode)); - return -EINVAL; - } - - /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */ - pAdapter->StaCfg.WpaState = SS_NOTUSE; - - return 0; -} - -int rt_ioctl_giwmode(struct net_device *dev, - struct iw_request_info *info, __u32 * mode, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - if (ADHOC_ON(pAdapter)) - *mode = IW_MODE_ADHOC; - else if (INFRA_ON(pAdapter)) - *mode = IW_MODE_INFRA; - else if (MONITOR_ON(pAdapter)) { - *mode = IW_MODE_MONITOR; - } else - *mode = IW_MODE_AUTO; - - DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode)); - return 0; -} - -int rt_ioctl_siwsens(struct net_device *dev, - struct iw_request_info *info, char *name, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - return 0; -} - -int rt_ioctl_giwsens(struct net_device *dev, - struct iw_request_info *info, char *name, char *extra) -{ - return 0; -} - -int rt_ioctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - struct iw_range *range = (struct iw_range *)extra; - u16 val; - int i; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwrange\n")); - data->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - range->txpower_capa = IW_TXPOW_DBM; - - if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) { - range->min_pmp = 1 * 1024; - range->max_pmp = 65535 * 1024; - range->min_pmt = 1 * 1024; - range->max_pmt = 1000 * 1024; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | - IW_POWER_UNICAST_R | IW_POWER_ALL_R; - } - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 14; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->min_retry = 0; - range->max_retry = 255; - - range->num_channels = pAdapter->ChannelListNum; - - val = 0; - for (i = 1; i <= range->num_channels; i++) { - u32 m = 2412000; - range->freq[val].i = pAdapter->ChannelList[i - 1].Channel; - MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i - 1].Channel, m); - range->freq[val].m = m * 100; /* OS_HZ */ - - range->freq[val].e = 1; - val++; - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - - range->max_qual.qual = 100; /* what is correct max? This was not - * documented exactly. At least - * 69 has been observed. */ - range->max_qual.level = 0; /* dB */ - range->max_qual.noise = 0; /* dB */ - - /* What would be suitable values for "average/typical" qual? */ - range->avg_qual.qual = 20; - range->avg_qual.level = -60; - range->avg_qual.noise = -95; - range->sensitivity = 3; - - range->max_encoding_tokens = NR_WEP_KEYS; - range->num_encoding_sizes = 2; - range->encoding_size[0] = 5; - range->encoding_size[1] = 13; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - /* IW_ENC_CAPA_* bit field */ - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - - return 0; -} - -int rt_ioctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - NDIS_802_11_MAC_ADDRESS Bssid; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) { - RTMP_MLME_RESET_STATE_MACHINE(pAdapter); - DBGPRINT(RT_DEBUG_TRACE, - ("MLME busy, reset MLME state machine!\n")); - } - /* tell CNTL state machine to call NdisMSetInformationComplete() after completing */ - /* this request, because this request is initiated by NDIS. */ - pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE; - /* Prevent to connect AP again in STAMlmePeriodicExec */ - pAdapter->MlmeAux.AutoReconnectSsidLen = 32; - - memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN); - MlmeEnqueue(pAdapter, - MLME_CNTL_STATE_MACHINE, - OID_802_11_BSSID, - sizeof(NDIS_802_11_MAC_ADDRESS), (void *) & Bssid); - - DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %pM\n", Bssid)); - - return 0; -} - -int rt_ioctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) { - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN); - } - /* Add for RT2870 */ - else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) { - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN); - } else { - DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n")); - return -ENOTCONN; - } - - return 0; -} - -/* - * Units are in db above the noise floor. That means the - * rssi values reported in the tx/rx descriptors in the - * driver are the SNR expressed in db. - * - * If you assume that the noise floor is -95, which is an - * excellent assumption 99.5 % of the time, then you can - * derive the absolute signal level (i.e. -95 + rssi). - * There are some other slight factors to take into account - * depending on whether the rssi measurement is from 11b, - * 11g, or 11a. These differences are at most 2db and - * can be documented. - * - * NB: various calculations are based on the orinoco/wavelan - * drivers for compatibility - */ -static void set_quality(struct rt_rtmp_adapter *pAdapter, - struct iw_quality *iq, signed char rssi) -{ - __u8 ChannelQuality; - - /* Normalize Rssi */ - if (rssi >= -50) - ChannelQuality = 100; - else if (rssi >= -80) /* between -50 ~ -80dbm */ - ChannelQuality = (__u8) (24 + ((rssi + 80) * 26) / 10); - else if (rssi >= -90) /* between -80 ~ -90dbm */ - ChannelQuality = (__u8) ((rssi + 90) * 26) / 10; - else - ChannelQuality = 0; - - iq->qual = (__u8) ChannelQuality; - - iq->level = (__u8) (rssi); - iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8) pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); /* noise level (dBm) */ - iq->noise += 256 - 143; - iq->updated = pAdapter->iw_stats.qual.updated; -} - -int rt_ioctl_iwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - struct sockaddr addr[IW_MAX_AP]; - struct iw_quality qual[IW_MAX_AP]; - int i; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - data->length = 0; - return 0; - /*return -ENETDOWN; */ - } - - for (i = 0; i < IW_MAX_AP; i++) { - if (i >= pAdapter->ScanTab.BssNr) - break; - addr[i].sa_family = ARPHRD_ETHER; - memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, - MAC_ADDR_LEN); - set_quality(pAdapter, &qual[i], - pAdapter->ScanTab.BssEntry[i].Rssi); - } - data->length = i; - memcpy(extra, &addr, i * sizeof(addr[0])); - data->flags = 1; /* signal quality present (sort of) */ - memcpy(extra + i * sizeof(addr[0]), &qual, i * sizeof(qual[i])); - - return 0; -} - -int rt_ioctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - unsigned long Now; - int Status = NDIS_STATUS_SUCCESS; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (MONITOR_ON(pAdapter)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Driver is in Monitor Mode now!\n")); - return -EINVAL; - } - - if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) { - pAdapter->StaCfg.WpaSupplicantScanCount++; - } - - pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE; - if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - return NDIS_STATUS_SUCCESS; - do { - Now = jiffies; - - if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) - && (pAdapter->StaCfg.WpaSupplicantScanCount > 3)) { - DBGPRINT(RT_DEBUG_TRACE, - ("WpaSupplicantScanCount > 3\n")); - Status = NDIS_STATUS_SUCCESS; - break; - } - - if ((OPSTATUS_TEST_FLAG - (pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) - && ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) - || (pAdapter->StaCfg.AuthMode == - Ndis802_11AuthModeWPAPSK)) - && (pAdapter->StaCfg.PortSecured == - WPA_802_1X_PORT_NOT_SECURED)) { - DBGPRINT(RT_DEBUG_TRACE, - ("Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n")); - Status = NDIS_STATUS_SUCCESS; - break; - } - - if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) { - RTMP_MLME_RESET_STATE_MACHINE(pAdapter); - DBGPRINT(RT_DEBUG_TRACE, - ("MLME busy, reset MLME state machine!\n")); - } - /* tell CNTL state machine to call NdisMSetInformationComplete() after completing */ - /* this request, because this request is initiated by NDIS. */ - pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE; - /* Reset allowed scan retries */ - pAdapter->StaCfg.ScanCnt = 0; - pAdapter->StaCfg.LastScanTime = Now; - - MlmeEnqueue(pAdapter, - MLME_CNTL_STATE_MACHINE, - OID_802_11_BSSID_LIST_SCAN, 0, NULL); - - Status = NDIS_STATUS_SUCCESS; - RTMP_MLME_HANDLER(pAdapter); - } while (0); - return NDIS_STATUS_SUCCESS; -} - -int rt_ioctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - int i = 0; - char *current_ev = extra, *previous_ev = extra; - char *end_buf; - char *current_val; - char custom[MAX_CUSTOM_LEN] = { 0 }; - struct iw_event iwe; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { - /* - * Still scanning, indicate the caller should try again. - */ - return -EAGAIN; - } - - if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) { - pAdapter->StaCfg.WpaSupplicantScanCount = 0; - } - - if (pAdapter->ScanTab.BssNr == 0) { - data->length = 0; - return 0; - } - - if (data->length > 0) - end_buf = extra + data->length; - else - end_buf = extra + IW_SCAN_MAX_DATA; - - for (i = 0; i < pAdapter->ScanTab.BssNr; i++) { - if (current_ev >= end_buf) { - return -E2BIG; - } - /*MAC address */ - /*================================ */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, - &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN); - - previous_ev = current_ev; - current_ev = - iwe_stream_add_event(info, current_ev, end_buf, &iwe, - IW_EV_ADDR_LEN); - if (current_ev == previous_ev) - return -E2BIG; - - /* - Protocol: - it will show scanned AP's WirelessMode. - it might be - 802.11a - 802.11a/n - 802.11g/n - 802.11b/g/n - 802.11g - 802.11b/g - */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWNAME; - - { - struct rt_bss_entry *pBssEntry = &pAdapter->ScanTab.BssEntry[i]; - BOOLEAN isGonly = FALSE; - int rateCnt = 0; - - if (pBssEntry->Channel > 14) { - if (pBssEntry->HtCapabilityLen != 0) - strcpy(iwe.u.name, "802.11a/n"); - else - strcpy(iwe.u.name, "802.11a"); - } else { - /* - if one of non B mode rate is set supported rate, it means G only. - */ - for (rateCnt = 0; - rateCnt < pBssEntry->SupRateLen; - rateCnt++) { - /* - 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate, it means G only. - */ - if (pBssEntry->SupRate[rateCnt] == 140 - || pBssEntry->SupRate[rateCnt] == - 146 - || pBssEntry->SupRate[rateCnt] >= - 152) - isGonly = TRUE; - } - - for (rateCnt = 0; - rateCnt < pBssEntry->ExtRateLen; - rateCnt++) { - if (pBssEntry->ExtRate[rateCnt] == 140 - || pBssEntry->ExtRate[rateCnt] == - 146 - || pBssEntry->ExtRate[rateCnt] >= - 152) - isGonly = TRUE; - } - - if (pBssEntry->HtCapabilityLen != 0) { - if (isGonly == TRUE) - strcpy(iwe.u.name, "802.11g/n"); - else - strcpy(iwe.u.name, - "802.11b/g/n"); - } else { - if (isGonly == TRUE) - strcpy(iwe.u.name, "802.11g"); - else { - if (pBssEntry->SupRateLen == 4 - && pBssEntry->ExtRateLen == - 0) - strcpy(iwe.u.name, - "802.11b"); - else - strcpy(iwe.u.name, - "802.11b/g"); - } - } - } - } - - previous_ev = current_ev; - current_ev = - iwe_stream_add_event(info, current_ev, end_buf, &iwe, - IW_EV_ADDR_LEN); - if (current_ev == previous_ev) - return -E2BIG; - - /*ESSID */ - /*================================ */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen; - iwe.u.data.flags = 1; - - previous_ev = current_ev; - current_ev = - iwe_stream_add_point(info, current_ev, end_buf, &iwe, - (char *)pAdapter->ScanTab. - BssEntry[i].Ssid); - if (current_ev == previous_ev) - return -E2BIG; - - /*Network Type */ - /*================================ */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS) { - iwe.u.mode = IW_MODE_ADHOC; - } else if (pAdapter->ScanTab.BssEntry[i].BssType == - Ndis802_11Infrastructure) { - iwe.u.mode = IW_MODE_INFRA; - } else { - iwe.u.mode = IW_MODE_AUTO; - } - iwe.len = IW_EV_UINT_LEN; - - previous_ev = current_ev; - current_ev = - iwe_stream_add_event(info, current_ev, end_buf, &iwe, - IW_EV_UINT_LEN); - if (current_ev == previous_ev) - return -E2BIG; - - /*Channel and Frequency */ - /*================================ */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - - previous_ev = current_ev; - current_ev = - iwe_stream_add_event(info, current_ev, end_buf, &iwe, - IW_EV_FREQ_LEN); - if (current_ev == previous_ev) - return -E2BIG; - - /*Add quality statistics */ - /*================================ */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - iwe.u.qual.level = 0; - iwe.u.qual.noise = 0; - set_quality(pAdapter, &iwe.u.qual, - pAdapter->ScanTab.BssEntry[i].Rssi); - current_ev = - iwe_stream_add_event(info, current_ev, end_buf, &iwe, - IW_EV_QUAL_LEN); - if (current_ev == previous_ev) - return -E2BIG; - - /*Encyption key */ - /*================================ */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - if (CAP_IS_PRIVACY_ON - (pAdapter->ScanTab.BssEntry[i].CapabilityInfo)) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - - previous_ev = current_ev; - current_ev = - iwe_stream_add_point(info, current_ev, end_buf, &iwe, - (char *)pAdapter-> - SharedKey[BSS0][(iwe.u.data. - flags & - IW_ENCODE_INDEX) - - 1].Key); - if (current_ev == previous_ev) - return -E2BIG; - - /*Bit Rate */ - /*================================ */ - if (pAdapter->ScanTab.BssEntry[i].SupRateLen) { - u8 tmpRate = - pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter-> - ScanTab. - BssEntry[i]. - SupRateLen - - 1]; - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - current_val = current_ev + IW_EV_LCP_LEN; - if (tmpRate == 0x82) - iwe.u.bitrate.value = 1 * 1000000; - else if (tmpRate == 0x84) - iwe.u.bitrate.value = 2 * 1000000; - else if (tmpRate == 0x8B) - iwe.u.bitrate.value = 5.5 * 1000000; - else if (tmpRate == 0x96) - iwe.u.bitrate.value = 11 * 1000000; - else - iwe.u.bitrate.value = (tmpRate / 2) * 1000000; - - if (tmpRate == 0x6c - && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen > - 0) { - int rate_count = ARRAY_SIZE(ralinkrate); - struct rt_ht_cap_info capInfo = - pAdapter->ScanTab.BssEntry[i].HtCapability. - HtCapInfo; - int shortGI = - capInfo.ChannelWidth ? capInfo. - ShortGIfor40 : capInfo.ShortGIfor20; - int maxMCS = - pAdapter->ScanTab.BssEntry[i].HtCapability. - MCSSet[1] ? 15 : 7; - int rate_index = - 12 + ((u8)capInfo.ChannelWidth * 24) + - ((u8)shortGI * 48) + ((u8)maxMCS); - - if (rate_index < 0) - rate_index = 0; - if (rate_index >= rate_count) - rate_index = rate_count - 1; - iwe.u.bitrate.value = - ralinkrate[rate_index] * 500000; - } - - iwe.u.bitrate.disabled = 0; - current_val = iwe_stream_add_value(info, current_ev, - current_val, end_buf, - &iwe, - IW_EV_PARAM_LEN); - - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - else - return -E2BIG; - } - /*WPA IE */ - if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0) { - memset(&iwe, 0, sizeof(iwe)); - memset(&custom[0], 0, MAX_CUSTOM_LEN); - memcpy(custom, - &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]), - pAdapter->ScanTab.BssEntry[i].WpaIE.IELen); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = - pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; - current_ev = - iwe_stream_add_point(info, current_ev, end_buf, - &iwe, custom); - if (current_ev == previous_ev) - return -E2BIG; - } - /*WPA2 IE */ - if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0) { - memset(&iwe, 0, sizeof(iwe)); - memset(&custom[0], 0, MAX_CUSTOM_LEN); - memcpy(custom, - &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]), - pAdapter->ScanTab.BssEntry[i].RsnIE.IELen); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = - pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; - current_ev = - iwe_stream_add_point(info, current_ev, end_buf, - &iwe, custom); - if (current_ev == previous_ev) - return -E2BIG; - } - } - - data->length = current_ev - extra; - pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE; - DBGPRINT(RT_DEBUG_ERROR, - ("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n", - i, pAdapter->ScanTab.BssNr, data->length)); - return 0; -} - -int rt_ioctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *essid) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (data->flags) { - char *pSsidString = NULL; - - /* Includes null character. */ - if (data->length > (IW_ESSID_MAX_SIZE + 1)) - return -E2BIG; - - pSsidString = kmalloc(MAX_LEN_OF_SSID + 1, MEM_ALLOC_FLAG); - if (pSsidString) { - NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID + 1); - NdisMoveMemory(pSsidString, essid, data->length); - if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE) - return -EINVAL; - } else - return -ENOMEM; - } else { - /* ANY ssid */ - if (Set_SSID_Proc(pAdapter, "") == FALSE) - return -EINVAL; - } - return 0; -} - -int rt_ioctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *essid) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - data->flags = 1; - if (MONITOR_ON(pAdapter)) { - data->length = 0; - return 0; - } - - if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - DBGPRINT(RT_DEBUG_TRACE, ("MediaState is connected\n")); - data->length = pAdapter->CommonCfg.SsidLen; - memcpy(essid, pAdapter->CommonCfg.Ssid, - pAdapter->CommonCfg.SsidLen); - } -#ifdef RTMP_MAC_USB - /* Add for RT2870 */ - else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) { - data->length = pAdapter->CommonCfg.SsidLen; - memcpy(essid, pAdapter->CommonCfg.Ssid, - pAdapter->CommonCfg.SsidLen); - } -#endif /* RTMP_MAC_USB // */ - else { /*the ANY ssid was specified */ - data->length = 0; - DBGPRINT(RT_DEBUG_TRACE, - ("MediaState is not connected, ess\n")); - } - - return 0; - -} - -int rt_ioctl_siwnickn(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *nickname) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (data->length > IW_ESSID_MAX_SIZE) - return -EINVAL; - - memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1); - memcpy(pAdapter->nickname, nickname, data->length); - - return 0; -} - -int rt_ioctl_giwnickn(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *nickname) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - if (data->length > strlen((char *)pAdapter->nickname) + 1) - data->length = strlen((char *)pAdapter->nickname) + 1; - if (data->length > 0) { - memcpy(nickname, pAdapter->nickname, data->length - 1); - nickname[data->length - 1] = '\0'; - } - return 0; -} - -int rt_ioctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - u16 val; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (rts->disabled) - val = MAX_RTS_THRESHOLD; - else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD) - return -EINVAL; - else if (rts->value == 0) - val = MAX_RTS_THRESHOLD; - else - val = rts->value; - - if (val != pAdapter->CommonCfg.RtsThreshold) - pAdapter->CommonCfg.RtsThreshold = val; - - return 0; -} - -int rt_ioctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - rts->value = pAdapter->CommonCfg.RtsThreshold; - rts->disabled = (rts->value == MAX_RTS_THRESHOLD); - rts->fixed = 1; - - return 0; -} - -int rt_ioctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - u16 val; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (frag->disabled) - val = MAX_FRAG_THRESHOLD; - else if (frag->value >= MIN_FRAG_THRESHOLD - && frag->value <= MAX_FRAG_THRESHOLD) - val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */ - else if (frag->value == 0) - val = MAX_FRAG_THRESHOLD; - else - return -EINVAL; - - pAdapter->CommonCfg.FragmentThreshold = val; - return 0; -} - -int rt_ioctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - frag->value = pAdapter->CommonCfg.FragmentThreshold; - frag->disabled = (frag->value == MAX_FRAG_THRESHOLD); - frag->fixed = 1; - - return 0; -} - -#define MAX_WEP_KEY_SIZE 13 -#define MIN_WEP_KEY_SIZE 5 -int rt_ioctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if ((erq->length == 0) && (erq->flags & IW_ENCODE_DISABLED)) { - pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled; - pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled; - pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled; - pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus; - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; - goto done; - } else if (erq->flags & IW_ENCODE_RESTRICTED - || erq->flags & IW_ENCODE_OPEN) { - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled; - pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled; - pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled; - pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus; - if (erq->flags & IW_ENCODE_RESTRICTED) - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared; - else - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; - } - - if (erq->length > 0) { - int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1; - /* Check the size of the key */ - if (erq->length > MAX_WEP_KEY_SIZE) { - return -EINVAL; - } - /* Check key index */ - if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) { - DBGPRINT(RT_DEBUG_TRACE, - ("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n", - keyIdx, pAdapter->StaCfg.DefaultKeyId)); - - /*Using default key */ - keyIdx = pAdapter->StaCfg.DefaultKeyId; - } else - pAdapter->StaCfg.DefaultKeyId = keyIdx; - - NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16); - - if (erq->length == MAX_WEP_KEY_SIZE) { - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = - MAX_WEP_KEY_SIZE; - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = - CIPHER_WEP128; - } else if (erq->length == MIN_WEP_KEY_SIZE) { - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = - MIN_WEP_KEY_SIZE; - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = - CIPHER_WEP64; - } else - /* Disable the key */ - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0; - - /* Check if the key is not marked as invalid */ - if (!(erq->flags & IW_ENCODE_NOKEY)) { - /* Copy the key in the driver */ - NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, - extra, erq->length); - } - } else { - /* Do we want to just set the transmit key index ? */ - int index = (erq->flags & IW_ENCODE_INDEX) - 1; - if ((index >= 0) && (index < 4)) { - pAdapter->StaCfg.DefaultKeyId = index; - } else - /* Don't complain if the mode is only changed */ - if (!(erq->flags & IW_ENCODE_MODE)) - return -EINVAL; - } - -done: - DBGPRINT(RT_DEBUG_TRACE, - ("==>rt_ioctl_siwencode::erq->flags=%x\n", erq->flags)); - DBGPRINT(RT_DEBUG_TRACE, - ("==>rt_ioctl_siwencode::AuthMode=%x\n", - pAdapter->StaCfg.AuthMode)); - DBGPRINT(RT_DEBUG_TRACE, - ("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n", - pAdapter->StaCfg.DefaultKeyId, - pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId]. - KeyLen)); - DBGPRINT(RT_DEBUG_TRACE, - ("==>rt_ioctl_siwencode::WepStatus=%x\n", - pAdapter->StaCfg.WepStatus)); - return 0; -} - -int -rt_ioctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *key) -{ - int kid; - struct rt_rtmp_adapter *pAdapter = NULL; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - kid = erq->flags & IW_ENCODE_INDEX; - DBGPRINT(RT_DEBUG_TRACE, - ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX)); - - if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) { - erq->length = 0; - erq->flags = IW_ENCODE_DISABLED; - } else if ((kid > 0) && (kid <= 4)) { - /* copy wep key */ - erq->flags = kid; /* NB: base 1 */ - if (erq->length > pAdapter->SharedKey[BSS0][kid - 1].KeyLen) - erq->length = pAdapter->SharedKey[BSS0][kid - 1].KeyLen; - memcpy(key, pAdapter->SharedKey[BSS0][kid - 1].Key, - erq->length); - /*if ((kid == pAdapter->PortCfg.DefaultKeyId)) */ - /*erq->flags |= IW_ENCODE_ENABLED; */ /* XXX */ - if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) - erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */ - else - erq->flags |= IW_ENCODE_OPEN; /* XXX */ - - } else if (kid == 0) { - if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) - erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */ - else - erq->flags |= IW_ENCODE_OPEN; /* XXX */ - erq->length = - pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId]. - KeyLen; - memcpy(key, - pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId]. - Key, erq->length); - /* copy default key ID */ - if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) - erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */ - else - erq->flags |= IW_ENCODE_OPEN; /* XXX */ - erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */ - erq->flags |= IW_ENCODE_ENABLED; /* XXX */ - } - - return 0; - -} - -void getBaInfo(struct rt_rtmp_adapter *pAd, char *pOutBuf) -{ - int i, j; - struct rt_ba_ori_entry *pOriBAEntry; - struct rt_ba_rec_entry *pRecBAEntry; - - for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) { - struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i]; - if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) - && (pEntry->Sst == SST_ASSOC)) - || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh)) { - sprintf(pOutBuf + strlen(pOutBuf), "\n%pM (Aid = %d) " - "(AP) -\n", pEntry->Addr, pEntry->Aid); - - sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf); - for (j = 0; j < NUM_OF_TID; j++) { - if (pEntry->BARecWcidArray[j] != 0) { - pRecBAEntry = - &pAd->BATable.BARecEntry[pEntry-> - BARecWcidArray - [j]]; - sprintf(pOutBuf + strlen(pOutBuf), - "TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", - j, pRecBAEntry->BAWinSize, - pRecBAEntry->LastIndSeq, - pRecBAEntry->list.qlen); - } - } - sprintf(pOutBuf, "%s\n", pOutBuf); - - sprintf(pOutBuf, "%s[Originator]\n", pOutBuf); - for (j = 0; j < NUM_OF_TID; j++) { - if (pEntry->BAOriWcidArray[j] != 0) { - pOriBAEntry = - &pAd->BATable.BAOriEntry[pEntry-> - BAOriWcidArray - [j]]; - sprintf(pOutBuf + strlen(pOutBuf), - "TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", - j, pOriBAEntry->BAWinSize, - pOriBAEntry->Sequence, - pEntry->TxSeq[j]); - } - } - sprintf(pOutBuf, "%s\n\n", pOutBuf); - } - if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30)) - break; - } - - return; -} - -int rt_ioctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer; - struct rt_mlme_queue_elem MsgElem; - struct rt_mlme_disassoc_req DisAssocReq; - struct rt_mlme_deauth_req DeAuthReq; - - GET_PAD_FROM_NET_DEV(pAd, dev); - - DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__)); - - if (pMlme == NULL) - return -EINVAL; - - switch (pMlme->cmd) { -#ifdef IW_MLME_DEAUTH - case IW_MLME_DEAUTH: - DBGPRINT(RT_DEBUG_TRACE, - ("====> %s - IW_MLME_DEAUTH\n", __func__)); - COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid); - DeAuthReq.Reason = pMlme->reason_code; - MsgElem.MsgLen = sizeof(struct rt_mlme_deauth_req); - NdisMoveMemory(MsgElem.Msg, &DeAuthReq, - sizeof(struct rt_mlme_deauth_req)); - MlmeDeauthReqAction(pAd, &MsgElem); - if (INFRA_ON(pAd)) { - LinkDown(pAd, FALSE); - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - } - break; -#endif /* IW_MLME_DEAUTH // */ -#ifdef IW_MLME_DISASSOC - case IW_MLME_DISASSOC: - DBGPRINT(RT_DEBUG_TRACE, - ("====> %s - IW_MLME_DISASSOC\n", __func__)); - COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid); - DisAssocReq.Reason = pMlme->reason_code; - - MsgElem.Machine = ASSOC_STATE_MACHINE; - MsgElem.MsgType = MT2_MLME_DISASSOC_REQ; - MsgElem.MsgLen = sizeof(struct rt_mlme_disassoc_req); - NdisMoveMemory(MsgElem.Msg, &DisAssocReq, - sizeof(struct rt_mlme_disassoc_req)); - - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; - MlmeDisassocReqAction(pAd, &MsgElem); - break; -#endif /* IW_MLME_DISASSOC // */ - default: - DBGPRINT(RT_DEBUG_TRACE, - ("====> %s - Unknow Command\n", __func__)); - break; - } - - return 0; -} - -int rt_ioctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - struct iw_param *param = &wrqu->param; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - switch (param->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - if (param->value == IW_AUTH_WPA_VERSION_WPA) { - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; - if (pAdapter->StaCfg.BssType == BSS_ADHOC) - pAdapter->StaCfg.AuthMode = - Ndis802_11AuthModeWPANone; - } else if (param->value == IW_AUTH_WPA_VERSION_WPA2) - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; - - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_CIPHER_PAIRWISE: - if (param->value == IW_AUTH_CIPHER_NONE) { - pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled; - pAdapter->StaCfg.OrigWepStatus = - pAdapter->StaCfg.WepStatus; - pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled; - } else if (param->value == IW_AUTH_CIPHER_WEP40 || - param->value == IW_AUTH_CIPHER_WEP104) { - pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled; - pAdapter->StaCfg.OrigWepStatus = - pAdapter->StaCfg.WepStatus; - pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled; - pAdapter->StaCfg.IEEE8021X = FALSE; - } else if (param->value == IW_AUTH_CIPHER_TKIP) { - pAdapter->StaCfg.WepStatus = - Ndis802_11Encryption2Enabled; - pAdapter->StaCfg.OrigWepStatus = - pAdapter->StaCfg.WepStatus; - pAdapter->StaCfg.PairCipher = - Ndis802_11Encryption2Enabled; - } else if (param->value == IW_AUTH_CIPHER_CCMP) { - pAdapter->StaCfg.WepStatus = - Ndis802_11Encryption3Enabled; - pAdapter->StaCfg.OrigWepStatus = - pAdapter->StaCfg.WepStatus; - pAdapter->StaCfg.PairCipher = - Ndis802_11Encryption3Enabled; - } - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_CIPHER_GROUP: - if (param->value == IW_AUTH_CIPHER_NONE) { - pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled; - } else if (param->value == IW_AUTH_CIPHER_WEP40 || - param->value == IW_AUTH_CIPHER_WEP104) { - pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled; - } else if (param->value == IW_AUTH_CIPHER_TKIP) { - pAdapter->StaCfg.GroupCipher = - Ndis802_11Encryption2Enabled; - } else if (param->value == IW_AUTH_CIPHER_CCMP) { - pAdapter->StaCfg.GroupCipher = - Ndis802_11Encryption3Enabled; - } - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_KEY_MGMT: - if (param->value == IW_AUTH_KEY_MGMT_802_1X) { - if (pAdapter->StaCfg.AuthMode == - Ndis802_11AuthModeWPAPSK) { - pAdapter->StaCfg.AuthMode = - Ndis802_11AuthModeWPA; - pAdapter->StaCfg.IEEE8021X = FALSE; - } else if (pAdapter->StaCfg.AuthMode == - Ndis802_11AuthModeWPA2PSK) { - pAdapter->StaCfg.AuthMode = - Ndis802_11AuthModeWPA2; - pAdapter->StaCfg.IEEE8021X = FALSE; - } else - /* WEP 1x */ - pAdapter->StaCfg.IEEE8021X = TRUE; - } else if (param->value == 0) { - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - } - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; - case IW_AUTH_PRIVACY_INVOKED: - /*if (param->value == 0) - { - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; - pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled; - pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus; - pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled; - pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled; - } */ - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_DROP_UNENCRYPTED: - if (param->value != 0) - pAdapter->StaCfg.PortSecured = - WPA_802_1X_PORT_NOT_SECURED; - else { - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - } - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_80211_AUTH_ALG: - if (param->value & IW_AUTH_ALG_SHARED_KEY) { - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared; - } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; - } else - return -EINVAL; - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", - __func__, param->value)); - break; - case IW_AUTH_WPA_ENABLED: - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", - __func__, param->value)); - break; - default: - return -EOPNOTSUPP; - } - - return 0; -} - -int rt_ioctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - struct iw_param *param = &wrqu->param; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - switch (param->flags & IW_AUTH_INDEX) { - case IW_AUTH_DROP_UNENCRYPTED: - param->value = - (pAdapter->StaCfg.WepStatus == - Ndis802_11WEPDisabled) ? 0 : 1; - break; - - case IW_AUTH_80211_AUTH_ALG: - param->value = - (pAdapter->StaCfg.AuthMode == - Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : - IW_AUTH_ALG_OPEN_SYSTEM; - break; - - case IW_AUTH_WPA_ENABLED: - param->value = - (pAdapter->StaCfg.AuthMode >= - Ndis802_11AuthModeWPA) ? 1 : 0; - break; - - default: - return -EOPNOTSUPP; - } - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_giwauth::param->value = %d!\n", param->value)); - return 0; -} - -void fnSetCipherKey(struct rt_rtmp_adapter *pAdapter, - int keyIdx, - u8 CipherAlg, - IN BOOLEAN bGTK, IN struct iw_encode_ext *ext) -{ - NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(struct rt_cipher_key)); - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, - LEN_TKIP_EK); - NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, - ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK); - NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, - ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, - LEN_TKIP_RXMICK); - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg; - - /* Update group key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAdapter, - BSS0, - keyIdx, - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, - pAdapter->SharedKey[BSS0][keyIdx].Key, - pAdapter->SharedKey[BSS0][keyIdx].TxMic, - pAdapter->SharedKey[BSS0][keyIdx].RxMic); - - if (bGTK) - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAdapter, - BSS0, - keyIdx, - pAdapter->SharedKey[BSS0][keyIdx]. - CipherAlg, NULL); - else - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAdapter, - BSS0, - keyIdx, - pAdapter->SharedKey[BSS0][keyIdx]. - CipherAlg, - &pAdapter->MacTab. - Content[BSSID_WCID]); -} - -int rt_ioctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAdapter = NULL; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int keyIdx, alg = ext->alg; - - GET_PAD_FROM_NET_DEV(pAdapter, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if (encoding->flags & IW_ENCODE_DISABLED) { - keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1; - /* set BSSID wcid entry of the Pair-wise Key table as no-security mode */ - AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID); - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0; - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE; - AsicRemoveSharedKeyEntry(pAdapter, 0, (u8)keyIdx); - NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], - sizeof(struct rt_cipher_key)); - DBGPRINT(RT_DEBUG_TRACE, - ("%s::Remove all keys!(encoding->flags = %x)\n", - __func__, encoding->flags)); - } else { - /* Get Key Index and convet to our own defined key index */ - keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1; - if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) - return -EINVAL; - - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - pAdapter->StaCfg.DefaultKeyId = keyIdx; - DBGPRINT(RT_DEBUG_TRACE, - ("%s::DefaultKeyId = %d\n", __func__, - pAdapter->StaCfg.DefaultKeyId)); - } - - switch (alg) { - case IW_ENCODE_ALG_NONE: - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_ENCODE_ALG_NONE\n", __func__)); - break; - case IW_ENCODE_ALG_WEP: - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", - __func__, ext->key_len, keyIdx)); - if (ext->key_len == MAX_WEP_KEY_SIZE) { - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = - MAX_WEP_KEY_SIZE; - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = - CIPHER_WEP128; - } else if (ext->key_len == MIN_WEP_KEY_SIZE) { - pAdapter->SharedKey[BSS0][keyIdx].KeyLen = - MIN_WEP_KEY_SIZE; - pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = - CIPHER_WEP64; - } else - return -EINVAL; - - NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, - 16); - NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, - ext->key, ext->key_len); - if (pAdapter->StaCfg.GroupCipher == - Ndis802_11GroupWEP40Enabled - || pAdapter->StaCfg.GroupCipher == - Ndis802_11GroupWEP104Enabled) { - /* Set Group key material to Asic */ - AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, - pAdapter-> - SharedKey[BSS0][keyIdx]. - CipherAlg, - pAdapter-> - SharedKey[BSS0][keyIdx]. - Key, NULL, NULL); - - /* Update WCID attribute table and IVEIV table for this group key table */ - RTMPAddWcidAttributeEntry(pAdapter, BSS0, - keyIdx, - pAdapter-> - SharedKey[BSS0] - [keyIdx].CipherAlg, - NULL); - - STA_PORT_SECURED(pAdapter); - - /* Indicate Connected for GUI */ - pAdapter->IndicateMediaState = - NdisMediaStateConnected; - } - break; - case IW_ENCODE_ALG_TKIP: - DBGPRINT(RT_DEBUG_TRACE, - ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", - __func__, keyIdx, ext->key_len)); - if (ext->key_len == 32) { - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - fnSetCipherKey(pAdapter, keyIdx, - CIPHER_TKIP, FALSE, ext); - if (pAdapter->StaCfg.AuthMode >= - Ndis802_11AuthModeWPA2) { - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - pAdapter->IndicateMediaState = - NdisMediaStateConnected; - } - } else if (ext-> - ext_flags & IW_ENCODE_EXT_GROUP_KEY) - { - fnSetCipherKey(pAdapter, keyIdx, - CIPHER_TKIP, TRUE, ext); - - /* set 802.1x port control */ - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - pAdapter->IndicateMediaState = - NdisMediaStateConnected; - } - } else - return -EINVAL; - break; - case IW_ENCODE_ALG_CCMP: - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, - FALSE, ext); - if (pAdapter->StaCfg.AuthMode >= - Ndis802_11AuthModeWPA2) - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - pAdapter->IndicateMediaState = - NdisMediaStateConnected; - } else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, - TRUE, ext); - - /* set 802.1x port control */ - /*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */ - STA_PORT_SECURED(pAdapter); - pAdapter->IndicateMediaState = - NdisMediaStateConnected; - } - break; - default: - return -EINVAL; - } - } - - return 0; -} - -int -rt_ioctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - char *pKey = NULL; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int idx, max_key_len; - - GET_PAD_FROM_NET_DEV(pAd, dev); - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_giwencodeext\n")); - - max_key_len = encoding->length - sizeof(*ext); - if (max_key_len < 0) - return -EINVAL; - - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > 4) - return -EINVAL; - idx--; - - if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || - (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)) { - if (idx != pAd->StaCfg.DefaultKeyId) { - ext->key_len = 0; - return 0; - } - } - } else - idx = pAd->StaCfg.DefaultKeyId; - - encoding->flags = idx + 1; - memset(ext, 0, sizeof(*ext)); - - ext->key_len = 0; - switch (pAd->StaCfg.WepStatus) { - case Ndis802_11WEPDisabled: - ext->alg = IW_ENCODE_ALG_NONE; - encoding->flags |= IW_ENCODE_DISABLED; - break; - case Ndis802_11WEPEnabled: - ext->alg = IW_ENCODE_ALG_WEP; - if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len) - return -E2BIG; - else { - ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen; - pKey = (char *)& (pAd->SharedKey[BSS0][idx].Key[0]); - } - break; - case Ndis802_11Encryption2Enabled: - case Ndis802_11Encryption3Enabled: - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) - ext->alg = IW_ENCODE_ALG_TKIP; - else - ext->alg = IW_ENCODE_ALG_CCMP; - - if (max_key_len < 32) - return -E2BIG; - else { - ext->key_len = 32; - pKey = (char *)& pAd->StaCfg.PMK[0]; - } - break; - default: - return -EINVAL; - } - - if (ext->key_len && pKey) { - encoding->flags |= IW_ENCODE_ENABLED; - memcpy(ext->key, pKey, ext->key_len); - } - - return 0; -} - -int rt_ioctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, dev); - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwgenie\n")); - pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; - if (wrqu->data.length > MAX_LEN_OF_RSNIE || - (wrqu->data.length && extra == NULL)) - return -EINVAL; - - if (wrqu->data.length) { - pAd->StaCfg.RSNIE_Len = wrqu->data.length; - NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, - pAd->StaCfg.RSNIE_Len); - pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE; - } else { - pAd->StaCfg.RSNIE_Len = 0; - NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE); - } - - return 0; -} - -int rt_ioctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - - GET_PAD_FROM_NET_DEV(pAd, dev); - - if ((pAd->StaCfg.RSNIE_Len == 0) || - (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) { - wrqu->data.length = 0; - return 0; - } - - if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) { - if (wrqu->data.length < pAd->StaCfg.RSNIE_Len) - return -E2BIG; - - wrqu->data.length = pAd->StaCfg.RSNIE_Len; - memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len); - } else { - u8 RSNIe = IE_WPA; - - if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) /* ID, Len */ - return -E2BIG; - wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2; - - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) - RSNIe = IE_RSN; - - extra[0] = (char)RSNIe; - extra[1] = pAd->StaCfg.RSNIE_Len; - memcpy(extra + 2, &pAd->StaCfg.RSN_IE[0], - pAd->StaCfg.RSNIE_Len); - } - - return 0; -} - -int rt_ioctl_siwpmksa(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer; - int CachedIdx = 0, idx = 0; - - GET_PAD_FROM_NET_DEV(pAd, dev); - - if (pPmksa == NULL) - return -EINVAL; - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwpmksa\n")); - switch (pPmksa->cmd) { - case IW_PMKSA_FLUSH: - NdisZeroMemory(pAd->StaCfg.SavedPMK, - sizeof(struct rt_bssid_info) * PMKID_NO); - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n")); - break; - case IW_PMKSA_REMOVE: - for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; - CachedIdx++) { - /* compare the BSSID */ - if (NdisEqualMemory - (pPmksa->bssid.sa_data, - pAd->StaCfg.SavedPMK[CachedIdx].BSSID, - MAC_ADDR_LEN)) { - NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx]. - BSSID, MAC_ADDR_LEN); - NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx]. - PMKID, 16); - for (idx = CachedIdx; - idx < (pAd->StaCfg.SavedPMKNum - 1); - idx++) { - NdisMoveMemory(&pAd->StaCfg. - SavedPMK[idx].BSSID[0], - &pAd->StaCfg. - SavedPMK[idx + - 1].BSSID[0], - MAC_ADDR_LEN); - NdisMoveMemory(&pAd->StaCfg. - SavedPMK[idx].PMKID[0], - &pAd->StaCfg. - SavedPMK[idx + - 1].PMKID[0], - 16); - } - pAd->StaCfg.SavedPMKNum--; - break; - } - } - - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n")); - break; - case IW_PMKSA_ADD: - for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; - CachedIdx++) { - /* compare the BSSID */ - if (NdisEqualMemory - (pPmksa->bssid.sa_data, - pAd->StaCfg.SavedPMK[CachedIdx].BSSID, - MAC_ADDR_LEN)) - break; - } - - /* Found, replace it */ - if (CachedIdx < PMKID_NO) { - DBGPRINT(RT_DEBUG_OFF, - ("Update PMKID, idx = %d\n", CachedIdx)); - NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx]. - BSSID[0], pPmksa->bssid.sa_data, - MAC_ADDR_LEN); - NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx]. - PMKID[0], pPmksa->pmkid, 16); - pAd->StaCfg.SavedPMKNum++; - } - /* Not found, replace the last one */ - else { - /* Randomly replace one */ - CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO); - DBGPRINT(RT_DEBUG_OFF, - ("Update PMKID, idx = %d\n", CachedIdx)); - NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx]. - BSSID[0], pPmksa->bssid.sa_data, - MAC_ADDR_LEN); - NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx]. - PMKID[0], pPmksa->pmkid, 16); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n")); - break; - default: - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwpmksa - Unknown Command!\n")); - break; - } - - return 0; -} - -int rt_ioctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - u32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed; - - GET_PAD_FROM_NET_DEV(pAd, dev); - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwrate::Network is down!\n")); - return -ENETDOWN; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed)); - /* rate = -1 => auto rate - rate = X, fixed = 1 => (fixed rate X) - */ - if (rate == -1) { - /*Auto Rate */ - pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; - pAd->StaCfg.bAutoTxRateSwitch = TRUE; - if ((pAd->CommonCfg.PhyMode <= PHY_11G) || - (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= - MODE_OFDM)) - RTMPSetDesiredRates(pAd, -1); - - SetCommonHT(pAd); - } else { - if (fixed) { - pAd->StaCfg.bAutoTxRateSwitch = FALSE; - if ((pAd->CommonCfg.PhyMode <= PHY_11G) || - (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field. - MODE <= MODE_OFDM)) - RTMPSetDesiredRates(pAd, rate); - else { - pAd->StaCfg.DesiredTransmitSetting.field.MCS = - MCS_AUTO; - SetCommonHT(pAd); - } - DBGPRINT(RT_DEBUG_TRACE, - ("rt_ioctl_siwrate::(HtMcs=%d)\n", - pAd->StaCfg.DesiredTransmitSetting.field. - MCS)); - } else { - /* TODO: rate = X, fixed = 0 => (rates <= X) */ - return -EOPNOTSUPP; - } - } - - return 0; -} - -int rt_ioctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct rt_rtmp_adapter *pAd = NULL; - int rate_index = 0, rate_count = 0; - HTTRANSMIT_SETTING ht_setting; -/* Remove to global variable - __s32 ralinkrate[] = - {2, 4, 11, 22, // CCK - 12, 18, 24, 36, 48, 72, 96, 108, // OFDM - 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15 - 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23 - 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15 - 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23 - 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15 - 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23 - 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15 - 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23 -*/ - GET_PAD_FROM_NET_DEV(pAd, dev); - - rate_count = ARRAY_SIZE(ralinkrate); - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - - if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) && - (INFRA_ON(pAd)) && - ((pAd->CommonCfg.PhyMode <= PHY_11G) - || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= - MODE_OFDM))) - ht_setting.word = pAd->StaCfg.HTPhyMode.word; - else - ht_setting.word = - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word; - - if (ht_setting.field.MODE >= MODE_HTMIX) { -/* rate_index = 12 + ((u8)ht_setting.field.BW *16) + ((u8)ht_setting.field.ShortGI *32) + ((u8)ht_setting.field.MCS); */ - rate_index = - 12 + ((u8)ht_setting.field.BW * 24) + - ((u8)ht_setting.field.ShortGI * 48) + - ((u8)ht_setting.field.MCS); - } else if (ht_setting.field.MODE == MODE_OFDM) - rate_index = (u8)(ht_setting.field.MCS) + 4; - else if (ht_setting.field.MODE == MODE_CCK) - rate_index = (u8)(ht_setting.field.MCS); - - if (rate_index < 0) - rate_index = 0; - - if (rate_index >= rate_count) - rate_index = rate_count - 1; - - wrqu->bitrate.value = ralinkrate[rate_index] * 500000; - wrqu->bitrate.disabled = 0; - - return 0; -} - -static const iw_handler rt_handler[] = { - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */ - (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL /* not used */ , /* SIOCSIWRANGE */ - (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL /* not used */ , /* SIOCSIWPRIV */ - (iw_handler) NULL /* kernel code */ , /* SIOCGIWPRIV */ - (iw_handler) NULL /* not used */ , /* SIOCSIWSTATS */ - (iw_handler) rt28xx_get_wireless_stats /* kernel code */ , /* SIOCGIWSTATS */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ - (iw_handler) NULL, /* SIOCSIWTHRSPY */ - (iw_handler) NULL, /* SIOCGIWTHRSPY */ - (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */ - (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */ - (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */ - (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */ - (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */ - (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */ - (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */ - (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */ - (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */ - (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */ - (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */ - (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */ - (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */ - (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) NULL, /* SIOCSIWTXPOW */ - (iw_handler) NULL, /* SIOCGIWTXPOW */ - (iw_handler) NULL, /* SIOCSIWRETRY */ - (iw_handler) NULL, /* SIOCGIWRETRY */ - (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */ - (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */ - (iw_handler) NULL, /* SIOCSIWPOWER */ - (iw_handler) NULL, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */ - (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */ - (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */ - (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */ - (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ - (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */ - (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */ -}; - -const struct iw_handler_def rt28xx_iw_handler_def = { - .standard = (iw_handler *) rt_handler, - .num_standard = sizeof(rt_handler) / sizeof(iw_handler), -#if IW_HANDLER_VERSION >= 7 - .get_wireless_stats = rt28xx_get_wireless_stats, -#endif -}; - -int rt28xx_sta_ioctl(IN struct net_device *net_dev, - IN OUT struct ifreq *rq, int cmd) -{ - struct os_cookie *pObj; - struct rt_rtmp_adapter *pAd = NULL; - struct iwreq *wrq = (struct iwreq *)rq; - BOOLEAN StateMachineTouched = FALSE; - int Status = NDIS_STATUS_SUCCESS; - - GET_PAD_FROM_NET_DEV(pAd, net_dev); - - pObj = (struct os_cookie *)pAd->OS_Cookie; - - /*check if the interface is down */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { - { - DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); - return -ENETDOWN; - } - } - - { /* determine this ioctl command is coming from which interface. */ - pObj->ioctl_if_type = INT_MAIN; - pObj->ioctl_if = MAIN_MBSSID; - } - - switch (cmd) { - case SIOCGIFHWADDR: - DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n")); - memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN); - break; - case SIOCGIWNAME: - { - char *name = &wrq->u.name[0]; - rt_ioctl_giwname(net_dev, NULL, name, NULL); - break; - } - case SIOCGIWESSID: /*Get ESSID */ - { - struct iw_point *essid = &wrq->u.essid; - rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer); - break; - } - case SIOCSIWESSID: /*Set ESSID */ - { - struct iw_point *essid = &wrq->u.essid; - rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer); - break; - } - case SIOCSIWNWID: /* set network id (the cell) */ - case SIOCGIWNWID: /* get network id */ - Status = -EOPNOTSUPP; - break; - case SIOCSIWFREQ: /*set channel/frequency (Hz) */ - { - struct iw_freq *freq = &wrq->u.freq; - rt_ioctl_siwfreq(net_dev, NULL, freq, NULL); - break; - } - case SIOCGIWFREQ: /* get channel/frequency (Hz) */ - { - struct iw_freq *freq = &wrq->u.freq; - rt_ioctl_giwfreq(net_dev, NULL, freq, NULL); - break; - } - case SIOCSIWNICKN: /*set node name/nickname */ - { - /*struct iw_point *data=&wrq->u.data; */ - /*rt_ioctl_siwnickn(net_dev, NULL, data, NULL); */ - break; - } - case SIOCGIWNICKN: /*get node name/nickname */ - { - struct iw_point *erq = NULL; - erq = &wrq->u.data; - erq->length = strlen((char *)pAd->nickname); - Status = - copy_to_user(erq->pointer, pAd->nickname, - erq->length); - if (Status) - Status = -EFAULT; - break; - } - case SIOCGIWRATE: /*get default bit rate (bps) */ - rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL); - break; - case SIOCSIWRATE: /*set default bit rate (bps) */ - rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL); - break; - case SIOCGIWRTS: /* get RTS/CTS threshold (bytes) */ - { - struct iw_param *rts = &wrq->u.rts; - rt_ioctl_giwrts(net_dev, NULL, rts, NULL); - break; - } - case SIOCSIWRTS: /*set RTS/CTS threshold (bytes) */ - { - struct iw_param *rts = &wrq->u.rts; - rt_ioctl_siwrts(net_dev, NULL, rts, NULL); - break; - } - case SIOCGIWFRAG: /*get fragmentation thr (bytes) */ - { - struct iw_param *frag = &wrq->u.frag; - rt_ioctl_giwfrag(net_dev, NULL, frag, NULL); - break; - } - case SIOCSIWFRAG: /*set fragmentation thr (bytes) */ - { - struct iw_param *frag = &wrq->u.frag; - rt_ioctl_siwfrag(net_dev, NULL, frag, NULL); - break; - } - case SIOCGIWENCODE: /*get encoding token & mode */ - { - struct iw_point *erq = &wrq->u.encoding; - if (erq) - rt_ioctl_giwencode(net_dev, NULL, erq, - erq->pointer); - break; - } - case SIOCSIWENCODE: /*set encoding token & mode */ - { - struct iw_point *erq = &wrq->u.encoding; - if (erq) - rt_ioctl_siwencode(net_dev, NULL, erq, - erq->pointer); - break; - } - case SIOCGIWAP: /*get access point MAC addresses */ - { - struct sockaddr *ap_addr = &wrq->u.ap_addr; - rt_ioctl_giwap(net_dev, NULL, ap_addr, - ap_addr->sa_data); - break; - } - case SIOCSIWAP: /*set access point MAC addresses */ - { - struct sockaddr *ap_addr = &wrq->u.ap_addr; - rt_ioctl_siwap(net_dev, NULL, ap_addr, - ap_addr->sa_data); - break; - } - case SIOCGIWMODE: /*get operation mode */ - { - __u32 *mode = &wrq->u.mode; - rt_ioctl_giwmode(net_dev, NULL, mode, NULL); - break; - } - case SIOCSIWMODE: /*set operation mode */ - { - __u32 *mode = &wrq->u.mode; - rt_ioctl_siwmode(net_dev, NULL, mode, NULL); - break; - } - case SIOCGIWSENS: /*get sensitivity (dBm) */ - case SIOCSIWSENS: /*set sensitivity (dBm) */ - case SIOCGIWPOWER: /*get Power Management settings */ - case SIOCSIWPOWER: /*set Power Management settings */ - case SIOCGIWTXPOW: /*get transmit power (dBm) */ - case SIOCSIWTXPOW: /*set transmit power (dBm) */ - case SIOCGIWRANGE: /*Get range of parameters */ - case SIOCGIWRETRY: /*get retry limits and lifetime */ - case SIOCSIWRETRY: /*set retry limits and lifetime */ - case RT_PRIV_IOCTL: - case RT_PRIV_IOCTL_EXT: - case RTPRIV_IOCTL_SET: - case RTPRIV_IOCTL_GSITESURVEY: - case SIOCGIWPRIV: - Status = -EOPNOTSUPP; - break; - case SIOCETHTOOL: - break; - default: - DBGPRINT(RT_DEBUG_ERROR, - ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd)); - Status = -EOPNOTSUPP; - break; - } - - if (StateMachineTouched) /* Upper layer sent a MLME-related operations */ - RTMP_MLME_HANDLER(pAd); - - return Status; -} - -/* - ========================================================================== - Description: - Set SSID - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== -*/ -int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg) -{ - struct rt_ndis_802_11_ssid Ssid, *pSsid = NULL; - BOOLEAN StateMachineTouched = FALSE; - int success = TRUE; - - if (strlen(arg) <= MAX_LEN_OF_SSID) { - NdisZeroMemory(&Ssid, sizeof(struct rt_ndis_802_11_ssid)); - if (strlen(arg) != 0) { - NdisMoveMemory(Ssid.Ssid, arg, strlen(arg)); - Ssid.SsidLength = strlen(arg); - } else /*ANY ssid */ - { - Ssid.SsidLength = 0; - memcpy(Ssid.Ssid, "", 0); - pAdapter->StaCfg.BssType = BSS_INFRA; - pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; - pAdapter->StaCfg.WepStatus = - Ndis802_11EncryptionDisabled; - } - pSsid = &Ssid; - - if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) { - RTMP_MLME_RESET_STATE_MACHINE(pAdapter); - DBGPRINT(RT_DEBUG_TRACE, - ("MLME busy, reset MLME state machine!\n")); - } - - if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) && - (pAdapter->StaCfg.WpaPassPhraseLen <= 64)) { - char passphrase_str[65] = { 0 }; - u8 keyMaterial[40]; - - RTMPMoveMemory(passphrase_str, - pAdapter->StaCfg.WpaPassPhrase, - pAdapter->StaCfg.WpaPassPhraseLen); - RTMPZeroMemory(pAdapter->StaCfg.PMK, 32); - if (pAdapter->StaCfg.WpaPassPhraseLen == 64) { - AtoH((char *)pAdapter->StaCfg.WpaPassPhrase, - pAdapter->StaCfg.PMK, 32); - } else { - PasswordHash((char *)pAdapter->StaCfg. - WpaPassPhrase, Ssid.Ssid, - Ssid.SsidLength, keyMaterial); - NdisMoveMemory(pAdapter->StaCfg.PMK, - keyMaterial, 32); - } - } - - pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE; - pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE; - pAdapter->bConfigChanged = TRUE; - - MlmeEnqueue(pAdapter, - MLME_CNTL_STATE_MACHINE, - OID_802_11_SSID, - sizeof(struct rt_ndis_802_11_ssid), (void *) pSsid); - - StateMachineTouched = TRUE; - DBGPRINT(RT_DEBUG_TRACE, - ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, - Ssid.Ssid)); - } else - success = FALSE; - - if (StateMachineTouched) /* Upper layer sent a MLME-related operations */ - RTMP_MLME_HANDLER(pAdapter); - - return success; -} - -/* - ========================================================================== - Description: - Set Network Type(Infrastructure/Adhoc mode) - Return: - TRUE if all parameters are OK, FALSE otherwise - ========================================================================== -*/ -int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg) -{ - u32 Value = 0; - - if (strcmp(arg, "Adhoc") == 0) { - if (pAdapter->StaCfg.BssType != BSS_ADHOC) { - /* Config has changed */ - pAdapter->bConfigChanged = TRUE; - if (MONITOR_ON(pAdapter)) { - RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, - STANORMAL); - RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); - Value &= (~0x80); - RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); - OPSTATUS_CLEAR_FLAG(pAdapter, - fOP_STATUS_MEDIA_STATE_CONNECTED); - pAdapter->StaCfg.bAutoReconnect = TRUE; - LinkDown(pAdapter, FALSE); - } - if (INFRA_ON(pAdapter)) { - /*BOOLEAN Cancelled; */ - /* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */ - /* Since calling this indicates users don't want to connect to that SSID anymore. */ - pAdapter->MlmeAux.AutoReconnectSsidLen = 32; - NdisZeroMemory(pAdapter->MlmeAux. - AutoReconnectSsid, - pAdapter->MlmeAux. - AutoReconnectSsidLen); - - LinkDown(pAdapter, FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n")); - } - } - pAdapter->StaCfg.BssType = BSS_ADHOC; - pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType; - DBGPRINT(RT_DEBUG_TRACE, - ("===>Set_NetworkType_Proc::(AD-HOC)\n")); - } else if (strcmp(arg, "Infra") == 0) { - if (pAdapter->StaCfg.BssType != BSS_INFRA) { - /* Config has changed */ - pAdapter->bConfigChanged = TRUE; - if (MONITOR_ON(pAdapter)) { - RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, - STANORMAL); - RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); - Value &= (~0x80); - RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); - OPSTATUS_CLEAR_FLAG(pAdapter, - fOP_STATUS_MEDIA_STATE_CONNECTED); - pAdapter->StaCfg.bAutoReconnect = TRUE; - LinkDown(pAdapter, FALSE); - } - if (ADHOC_ON(pAdapter)) { - /* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */ - /* Since calling this indicates users don't want to connect to that SSID anymore. */ - pAdapter->MlmeAux.AutoReconnectSsidLen = 32; - NdisZeroMemory(pAdapter->MlmeAux. - AutoReconnectSsid, - pAdapter->MlmeAux. - AutoReconnectSsidLen); - - LinkDown(pAdapter, FALSE); - } - } - pAdapter->StaCfg.BssType = BSS_INFRA; - pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType; - DBGPRINT(RT_DEBUG_TRACE, - ("===>Set_NetworkType_Proc::(INFRA)\n")); - } else if (strcmp(arg, "Monitor") == 0) { - u8 bbpValue = 0; - BCN_TIME_CFG_STRUC csr; - OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON); - OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON); - OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED); - /* disable all periodic state machine */ - pAdapter->StaCfg.bAutoReconnect = FALSE; - /* reset all mlme state machine */ - RTMP_MLME_RESET_STATE_MACHINE(pAdapter); - DBGPRINT(RT_DEBUG_TRACE, - ("fOP_STATUS_MEDIA_STATE_CONNECTED \n")); - if (pAdapter->CommonCfg.CentralChannel == 0) { - if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED) - pAdapter->CommonCfg.CentralChannel = 36; - else - pAdapter->CommonCfg.CentralChannel = 6; - } else - N_ChannelCheck(pAdapter); - - if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED && - pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 && - pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == - EXTCHA_ABOVE) { - /* 40MHz ,control channel at lower */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, - &bbpValue); - bbpValue &= (~0x18); - bbpValue |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, - bbpValue); - pAdapter->CommonCfg.BBPCurrentBW = BW_40; - /* RX : control channel at lower */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, - &bbpValue); - bbpValue &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, - bbpValue); - - RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value); - Value &= 0xfffffffe; - RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value); - pAdapter->CommonCfg.CentralChannel = - pAdapter->CommonCfg.Channel + 2; - AsicSwitchChannel(pAdapter, - pAdapter->CommonCfg.CentralChannel, - FALSE); - AsicLockChannel(pAdapter, - pAdapter->CommonCfg.CentralChannel); - DBGPRINT(RT_DEBUG_TRACE, - ("BW_40 ,control_channel(%d), CentralChannel(%d) \n", - pAdapter->CommonCfg.Channel, - pAdapter->CommonCfg.CentralChannel)); - } else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED - && pAdapter->CommonCfg.RegTransmitSetting.field.BW == - BW_40 - && pAdapter->CommonCfg.RegTransmitSetting.field. - EXTCHA == EXTCHA_BELOW) { - /* 40MHz ,control channel at upper */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, - &bbpValue); - bbpValue &= (~0x18); - bbpValue |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, - bbpValue); - pAdapter->CommonCfg.BBPCurrentBW = BW_40; - RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value); - Value |= 0x1; - RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, - &bbpValue); - bbpValue |= (0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, - bbpValue); - pAdapter->CommonCfg.CentralChannel = - pAdapter->CommonCfg.Channel - 2; - AsicSwitchChannel(pAdapter, - pAdapter->CommonCfg.CentralChannel, - FALSE); - AsicLockChannel(pAdapter, - pAdapter->CommonCfg.CentralChannel); - DBGPRINT(RT_DEBUG_TRACE, - ("BW_40 ,control_channel(%d), CentralChannel(%d) \n", - pAdapter->CommonCfg.Channel, - pAdapter->CommonCfg.CentralChannel)); - } else { - /* 20MHz */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, - &bbpValue); - bbpValue &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, - bbpValue); - pAdapter->CommonCfg.BBPCurrentBW = BW_20; - AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, - FALSE); - AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE, - ("BW_20, Channel(%d)\n", - pAdapter->CommonCfg.Channel)); - } - /* Enable Rx with promiscuous reception */ - RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3); - /* ASIC supports sniffer function with replacing RSSI with timestamp. */ - /*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */ - /*Value |= (0x80); */ - /*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */ - /* disable sync */ - RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word); - csr.field.bBeaconGen = 0; - csr.field.bTBTTEnable = 0; - csr.field.TsfSyncMode = 0; - RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word); - - pAdapter->StaCfg.BssType = BSS_MONITOR; - pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; /*ARPHRD_IEEE80211; // IEEE80211 */ - DBGPRINT(RT_DEBUG_TRACE, - ("===>Set_NetworkType_Proc::(MONITOR)\n")); - } - /* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */ - pAdapter->StaCfg.WpaState = SS_NOTUSE; - - DBGPRINT(RT_DEBUG_TRACE, - ("Set_NetworkType_Proc::(NetworkType=%d)\n", - pAdapter->StaCfg.BssType)); - - return TRUE; -} diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c deleted file mode 100644 index 322bf49ee906..000000000000 --- a/drivers/staging/rt2860/usb_main_dev.c +++ /dev/null @@ -1,927 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - *************************************************************************/ - -#include "rt_config.h" - -/* Following information will be show when you run 'modinfo' */ -/* If you have a solution for the bug in current version of driver, please e-mail me. */ -/* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */ -MODULE_AUTHOR("Paul Lin "); -MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver"); -MODULE_LICENSE("GPL"); -#ifdef MODULE_VERSION -MODULE_VERSION(STA_DRIVER_VERSION); -#endif - -/* module table */ -struct usb_device_id rtusb_usb_id[] = { -#ifdef RT2870 - {USB_DEVICE(0x148F, 0x2770)}, /* Ralink */ - {USB_DEVICE(0x148F, 0x2870)}, /* Ralink */ - {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */ - {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */ - {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */ - {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */ - {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */ - {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */ - {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */ - {USB_DEVICE(0x0789, 0x0164)}, /* Logitec 2870 */ - {USB_DEVICE(0x177f, 0x0302)}, /* lsusb */ - {USB_DEVICE(0x0B05, 0x1731)}, /* Asus */ - {USB_DEVICE(0x0B05, 0x1732)}, /* Asus */ - {USB_DEVICE(0x0B05, 0x1742)}, /* Asus */ - {USB_DEVICE(0x0DF6, 0x0017)}, /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x002B)}, /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x002C)}, /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x002D)}, /* Sitecom */ - {USB_DEVICE(0x14B2, 0x3C06)}, /* Conceptronic */ - {USB_DEVICE(0x14B2, 0x3C28)}, /* Conceptronic */ - {USB_DEVICE(0x2019, 0xED06)}, /* Planex Communications, Inc. */ - {USB_DEVICE(0x07D1, 0x3C09)}, /* D-Link */ - {USB_DEVICE(0x07D1, 0x3C11)}, /* D-Link */ - {USB_DEVICE(0x14B2, 0x3C07)}, /* AL */ - {USB_DEVICE(0x050D, 0x8053)}, /* Belkin */ - {USB_DEVICE(0x050D, 0x825B)}, /* Belkin */ - {USB_DEVICE(0x050D, 0x935A)}, /* Belkin F6D4050 v1 */ - {USB_DEVICE(0x050D, 0x935B)}, /* Belkin F6D4050 v2 */ - {USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */ - {USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */ - {USB_DEVICE(0x07AA, 0x002F)}, /* Corega */ - {USB_DEVICE(0x07AA, 0x003C)}, /* Corega */ - {USB_DEVICE(0x07AA, 0x003F)}, /* Corega */ - {USB_DEVICE(0x1044, 0x800B)}, /* Gigabyte */ - {USB_DEVICE(0x15A9, 0x0006)}, /* Sparklan */ - {USB_DEVICE(0x083A, 0xB522)}, /* SMC */ - {USB_DEVICE(0x083A, 0xA618)}, /* SMC */ - {USB_DEVICE(0x083A, 0x8522)}, /* Arcadyan */ - {USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */ - {USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */ - {USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */ - {USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */ - {USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */ - {USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */ - {USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */ - {USB_DEVICE(0x0471, 0x200f)}, /* Philips */ - {USB_DEVICE(0x14B2, 0x3C25)}, /* Draytek */ - {USB_DEVICE(0x13D3, 0x3247)}, /* AzureWave */ - {USB_DEVICE(0x083A, 0x6618)}, /* Accton */ - {USB_DEVICE(0x15c5, 0x0008)}, /* Amit */ - {USB_DEVICE(0x0E66, 0x0001)}, /* Hawking */ - {USB_DEVICE(0x0E66, 0x0003)}, /* Hawking */ - {USB_DEVICE(0x129B, 0x1828)}, /* Siemens */ - {USB_DEVICE(0x157E, 0x300E)}, /* U-Media */ - {USB_DEVICE(0x050d, 0x805c)}, - {USB_DEVICE(0x050d, 0x815c)}, - {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */ - {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */ - {USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */ - {USB_DEVICE(0x1690, 0x0740)}, /* Askey */ - {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */ - {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ - {USB_DEVICE(0x7392, 0x7718)}, - {USB_DEVICE(0x7392, 0x7717)}, - {USB_DEVICE(0x0411, 0x016f)}, /* MelCo.,Inc. WLI-UC-G301N */ - {USB_DEVICE(0x1737, 0x0070)}, /* Linksys WUSB100 */ - {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ - {USB_DEVICE(0x1737, 0x0078)}, /* Linksys WUSB100v2 */ - {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ - {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ - {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */ -#endif /* RT2870 // */ -#ifdef RT3070 - {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */ - {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */ - {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */ - {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */ - {USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */ - {USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */ - {USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */ - {USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */ - {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */ - {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */ - {USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */ - {USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */ - {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */ - {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */ - {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */ - {USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */ - {USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */ - {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */ - {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */ - {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */ - {USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */ - {USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */ - {USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */ - {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */ - {USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/ - {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */ - {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */ - {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */ - {USB_DEVICE(0x07B8, 0x3071)}, /* AboCom 3071 */ - {USB_DEVICE(0x07B8, 0x3072)}, /* Abocom 3072 */ - {USB_DEVICE(0x7392, 0x7711)}, /* Edimax 3070 */ - {USB_DEVICE(0x1A32, 0x0304)}, /* Quanta 3070 */ - {USB_DEVICE(0x1EDA, 0x2310)}, /* AirTies 3070 */ - {USB_DEVICE(0x07D1, 0x3C0A)}, /* D-Link 3072 */ - {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */ - {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */ - {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */ - {USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */ - {USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */ - {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */ - {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */ - {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */ - {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */ - {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */ - {USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */ - {USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */ - {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */ - {USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */ - {USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */ - {USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/ - {USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/ - {USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/ - {USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/ - {USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */ - {USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */ - {USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */ - {USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */ - {USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */ - {USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */ - {USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */ - {USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */ - {USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */ - {USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */ - {USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */ - {USB_DEVICE(0x0789, 0x0166)}, /* Edimax */ - {USB_DEVICE(0x148F, 0x2070)}, /* Edimax */ -#endif /* RT3070 // */ - {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */ - {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */ - {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */ - {USB_DEVICE(0x2019, 0xED14)}, /* Planex Communications, Inc. */ - {USB_DEVICE(0x0411, 0x015D)}, /* Buffalo Airstation WLI-UC-GN */ - {} /* Terminating entry */ -}; - -int const rtusb_usb_id_len = - sizeof(rtusb_usb_id) / sizeof(struct usb_device_id); - -MODULE_DEVICE_TABLE(usb, rtusb_usb_id); - -static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd); - -static int __devinit rt2870_probe(IN struct usb_interface *intf, - IN struct usb_device *usb_dev, - IN const struct usb_device_id *dev_id, - struct rt_rtmp_adapter **ppAd); - -#ifndef PF_NOFREEZE -#define PF_NOFREEZE 0 -#endif - -extern int rt28xx_close(IN struct net_device *net_dev); -extern int rt28xx_open(struct net_device *net_dev); - -static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, - IN struct usb_interface *intf, - struct rt_rtmp_adapter *pAd); - -/* -======================================================================== -Routine Description: - Check the chipset vendor/product ID. - -Arguments: - _dev_p Point to the PCI or USB device - -Return Value: - TRUE Check ok - FALSE Check fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXChipsetCheck(IN void *_dev_p) -{ - struct usb_interface *intf = (struct usb_interface *)_dev_p; - struct usb_device *dev_p = interface_to_usbdev(intf); - u32 i; - - for (i = 0; i < rtusb_usb_id_len; i++) { - if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor && - dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) { - printk(KERN_INFO "rt2870: idVendor = 0x%x, idProduct = 0x%x\n", - dev_p->descriptor.idVendor, - dev_p->descriptor.idProduct); - break; - } - } - - if (i == rtusb_usb_id_len) { - printk(KERN_ERR "rt2870: Error! Device Descriptor not matching!\n"); - return FALSE; - } - - return TRUE; -} - -/**************************************************************************/ -/**************************************************************************/ -/*tested for kernel 2.6series */ -/**************************************************************************/ -/**************************************************************************/ - -#ifdef CONFIG_PM -static int rt2870_suspend(struct usb_interface *intf, pm_message_t state); -static int rt2870_resume(struct usb_interface *intf); -#endif /* CONFIG_PM // */ - -static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, - IN struct usb_interface *intf, - struct rt_rtmp_adapter *pAd) -{ - struct usb_host_interface *iface_desc; - unsigned long BulkOutIdx; - u32 i; - - /* get the active interface descriptor */ - iface_desc = intf->cur_altsetting; - - /* get # of enpoints */ - pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints; - DBGPRINT(RT_DEBUG_TRACE, - ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints)); - - /* Configure Pipes */ - BulkOutIdx = 0; - - for (i = 0; i < pAd->NumberOfPipes; i++) { - if ((iface_desc->endpoint[i].desc.bmAttributes == - USB_ENDPOINT_XFER_BULK) && - ((iface_desc->endpoint[i].desc.bEndpointAddress & - USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) { - pAd->BulkInEpAddr = - iface_desc->endpoint[i].desc.bEndpointAddress; - pAd->BulkInMaxPacketSize = - le2cpu16(iface_desc->endpoint[i].desc. - wMaxPacketSize); - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("BULK IN MaxPacketSize = %d\n", - pAd->BulkInMaxPacketSize)); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("EP address = 0x%2x\n", - iface_desc->endpoint[i].desc. - bEndpointAddress)); - } else - if ((iface_desc->endpoint[i].desc.bmAttributes == - USB_ENDPOINT_XFER_BULK) - && - ((iface_desc->endpoint[i].desc. - bEndpointAddress & USB_ENDPOINT_DIR_MASK) == - USB_DIR_OUT)) { - /* there are 6 bulk out EP. EP6 highest priority. */ - /* EP1-4 is EDCA. EP5 is HCCA. */ - pAd->BulkOutEpAddr[BulkOutIdx++] = - iface_desc->endpoint[i].desc.bEndpointAddress; - pAd->BulkOutMaxPacketSize = - le2cpu16(iface_desc->endpoint[i].desc. - wMaxPacketSize); - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("BULK OUT MaxPacketSize = %d\n", - pAd->BulkOutMaxPacketSize)); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("EP address = 0x%2x \n", - iface_desc->endpoint[i].desc. - bEndpointAddress)); - } - } - - if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) { - printk - (KERN_ERR "%s: Could not find both bulk-in and bulk-out endpoints\n", - __FUNCTION__); - return FALSE; - } - - pAd->config = &dev->config->desc; - usb_set_intfdata(intf, pAd); - - return TRUE; - -} - -static int __devinit rtusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct rt_rtmp_adapter *pAd; - struct usb_device *dev; - int rv; - - dev = interface_to_usbdev(intf); - dev = usb_get_dev(dev); - - rv = rt2870_probe(intf, dev, id, &pAd); - if (rv != 0) - usb_put_dev(dev); - - return rv; -} - -static void rtusb_disconnect(struct usb_interface *intf) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct rt_rtmp_adapter *pAd; - - pAd = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - - rt2870_disconnect(dev, pAd); -} - -struct usb_driver rtusb_driver = { - .name = "rt2870", - .probe = rtusb_probe, - .disconnect = rtusb_disconnect, - .id_table = rtusb_usb_id, - -#ifdef CONFIG_PM -suspend:rt2870_suspend, -resume:rt2870_resume, -#endif -}; - -#ifdef CONFIG_PM - -void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd) -{ - /* clear PS packets */ - /* clear TxSw packets */ -} - -static int rt2870_suspend(struct usb_interface *intf, pm_message_t state) -{ - struct net_device *net_dev; - struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf); - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n")); - net_dev = pAd->net_dev; - netif_device_detach(net_dev); - - pAd->PM_FlgSuspend = 1; - if (netif_running(net_dev)) { - RTUSBCancelPendingBulkInIRP(pAd); - RTUSBCancelPendingBulkOutIRP(pAd); - } - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n")); - return 0; -} - -static int rt2870_resume(struct usb_interface *intf) -{ - struct net_device *net_dev; - struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf); - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n")); - - pAd->PM_FlgSuspend = 0; - net_dev = pAd->net_dev; - netif_device_attach(net_dev); - netif_start_queue(net_dev); - netif_carrier_on(net_dev); - netif_wake_queue(net_dev); - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n")); - return 0; -} -#endif /* CONFIG_PM // */ - -/* Init driver module */ -int __init rtusb_init(void) -{ - printk(KERN_DEBUG "rtusb init --->\n"); - return usb_register(&rtusb_driver); -} - -/* Deinit driver module */ -void __exit rtusb_exit(void) -{ - usb_deregister(&rtusb_driver); - printk(KERN_DEBUG "<--- rtusb exit\n"); -} - -module_init(rtusb_init); -module_exit(rtusb_exit); - -/*--------------------------------------------------------------------- */ -/* function declarations */ -/*--------------------------------------------------------------------- */ - -/* -======================================================================== -Routine Description: - MLME kernel thread. - -Arguments: - *Context the pAd, driver control block pointer - -Return Value: - 0 close the thread - -Note: -======================================================================== -*/ -int MlmeThread(IN void *Context) -{ - struct rt_rtmp_adapter *pAd; - struct rt_rtmp_os_task *pTask; - int status; - status = 0; - - pTask = Context; - pAd = pTask->priv; - - RtmpOSTaskCustomize(pTask); - - while (!pTask->task_killed) { -#ifdef KTHREAD_SUPPORT - RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); -#else - RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); - - /* unlock the device pointers */ - if (status != 0) { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - break; - } -#endif - - /* lock the device pointers , need to check if required */ - /*down(&(pAd->usbdev_semaphore)); */ - - if (!pAd->PM_FlgSuspend) - MlmeHandler(pAd); - } - - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__)); -#ifndef KTHREAD_SUPPORT - pTask->taskPID = THREAD_PID_INIT_VALUE; - complete_and_exit(&pTask->taskComplete, 0); -#endif - return 0; - -} - -/* -======================================================================== -Routine Description: - USB command kernel thread. - -Arguments: - *Context the pAd, driver control block pointer - -Return Value: - 0 close the thread - -Note: -======================================================================== -*/ -int RTUSBCmdThread(IN void *Context) -{ - struct rt_rtmp_adapter *pAd; - struct rt_rtmp_os_task *pTask; - int status; - status = 0; - - pTask = Context; - pAd = pTask->priv; - - RtmpOSTaskCustomize(pTask); - - NdisAcquireSpinLock(&pAd->CmdQLock); - pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; - NdisReleaseSpinLock(&pAd->CmdQLock); - - while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) { -#ifdef KTHREAD_SUPPORT - RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); -#else - /* lock the device pointers */ - RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); - - if (status != 0) { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - break; - } -#endif - - if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) - break; - - if (!pAd->PM_FlgSuspend) - CMDHandler(pAd); - } - - if (pAd && !pAd->PM_FlgSuspend) { /* Clear the CmdQElements. */ - struct rt_cmdqelmt *pCmdQElmt = NULL; - - NdisAcquireSpinLock(&pAd->CmdQLock); - pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; - while (pAd->CmdQ.size) { - RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt); - if (pCmdQElmt) { - if (pCmdQElmt->CmdFromNdis == TRUE) { - if (pCmdQElmt->buffer != NULL) - os_free_mem(pAd, - pCmdQElmt->buffer); - os_free_mem(pAd, (u8 *)pCmdQElmt); - } else { - if ((pCmdQElmt->buffer != NULL) - && (pCmdQElmt->bufferlength != 0)) - os_free_mem(pAd, - pCmdQElmt->buffer); - os_free_mem(pAd, (u8 *)pCmdQElmt); - } - } - } - - NdisReleaseSpinLock(&pAd->CmdQLock); - } - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n")); - -#ifndef KTHREAD_SUPPORT - pTask->taskPID = THREAD_PID_INIT_VALUE; - complete_and_exit(&pTask->taskComplete, 0); -#endif - return 0; - -} - -void RTUSBWatchDog(struct rt_rtmp_adapter *pAd) -{ - struct rt_ht_tx_context *pHTTXContext; - int idx; - unsigned long irqFlags; - PURB pUrb; - BOOLEAN needDumpSeq = FALSE; - u32 MACValue; - u32 TxRxQ_Pcnt; - - idx = 0; - RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); - if ((MACValue & 0xff) != 0) { - DBGPRINT(RT_DEBUG_TRACE, - ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n", - MACValue)); - RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); - while ((MACValue & 0xff) != 0 && (idx++ < 10)) { - RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); - RTMPusecDelay(1); - } - RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); - } - - if (pAd->watchDogRxOverFlowCnt >= 2) { - DBGPRINT(RT_DEBUG_TRACE, - ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); - if ((!RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_BULKIN_RESET | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - DBGPRINT(RT_DEBUG_TRACE, - ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, - NULL, 0); - needDumpSeq = TRUE; - } - pAd->watchDogRxOverFlowCnt = 0; - } - - RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt); - - for (idx = 0; idx < NUM_OF_TX_RING; idx++) { - pUrb = NULL; - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); - if ((pAd->BulkOutPending[idx] == TRUE) - && pAd->watchDogTxPendingCnt) { - int actual_length = 0, transfer_buffer_length = 0; - BOOLEAN isDataPacket = FALSE; - pAd->watchDogTxPendingCnt[idx]++; - - if ((pAd->watchDogTxPendingCnt[idx] > 2) && - (!RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST | - fRTMP_ADAPTER_BULKOUT_RESET))) - ) { - /* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */ - pHTTXContext = - (struct rt_ht_tx_context *)(&pAd->TxContext[idx]); - if (pHTTXContext->IRPPending) { /* Check TxContext. */ - pUrb = pHTTXContext->pUrb; - - actual_length = pUrb->actual_length; - transfer_buffer_length = - pUrb->transfer_buffer_length; - isDataPacket = TRUE; - } else if (idx == MGMTPIPEIDX) { - struct rt_tx_context *pMLMEContext, *pNULLContext, - *pPsPollContext; - - /*Check MgmtContext. */ - pMLMEContext = - (struct rt_tx_context *)(pAd->MgmtRing. - Cell[pAd->MgmtRing. - TxDmaIdx]. - AllocVa); - pPsPollContext = - (struct rt_tx_context *)(&pAd->PsPollContext); - pNULLContext = - (struct rt_tx_context *)(&pAd->NullContext); - - if (pMLMEContext->IRPPending) { - ASSERT(pMLMEContext-> - IRPPending); - pUrb = pMLMEContext->pUrb; - } else if (pNULLContext->IRPPending) { - ASSERT(pNULLContext-> - IRPPending); - pUrb = pNULLContext->pUrb; - } else if (pPsPollContext->IRPPending) { - ASSERT(pPsPollContext-> - IRPPending); - pUrb = pPsPollContext->pUrb; - } - } - - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], - irqFlags); - - printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n", - idx, pAd->watchDogTxPendingCnt[idx], - pAd->TransferedLength[idx], - actual_length, transfer_buffer_length); - - if (pUrb) { - if ((isDataPacket - && pAd->TransferedLength[idx] == - actual_length - && pAd->TransferedLength[idx] < - transfer_buffer_length - && actual_length != 0 -/* && TxRxQ_Pcnt==0 */ - && pAd->watchDogTxPendingCnt[idx] > - 3) - || isDataPacket == FALSE - || pAd->watchDogTxPendingCnt[idx] > - 6) { - DBGPRINT(RT_DEBUG_TRACE, - ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", - idx)); - DBGPRINT(RT_DEBUG_TRACE, - ("Unlink the pending URB!\n")); - /* unlink it now */ - RTUSB_UNLINK_URB(pUrb); - /* Sleep 200 microseconds to give cancellation time to work */ - /*RTMPusecDelay(200); */ - needDumpSeq = TRUE; - } - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("Unknown bulkOut URB maybe hanged!\n")); - } - } else { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], - irqFlags); - } - - if (isDataPacket == TRUE) - pAd->TransferedLength[idx] = actual_length; - } else { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); - } - } - - /* For Sigma debug, dump the ba_reordering sequence. */ - if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) { - u16 Idx; - struct rt_ba_rec_entry *pBAEntry = NULL; - u8 count = 0; - struct reordering_mpdu *mpdu_blk; - - Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; - - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) { - DBGPRINT(RT_DEBUG_TRACE, - ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); - NdisAcquireSpinLock(&pBAEntry->RxReRingLock); - mpdu_blk = pBAEntry->list.next; - while (mpdu_blk) { - DBGPRINT(RT_DEBUG_TRACE, - ("\t%d:Seq-%d, bAMSDU-%d!\n", count, - mpdu_blk->Sequence, - mpdu_blk->bAMSDU)); - mpdu_blk = mpdu_blk->next; - count++; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("\npBAEntry->LastIndSeq=%d!\n", - pBAEntry->LastIndSeq)); - NdisReleaseSpinLock(&pBAEntry->RxReRingLock); - } - } -} - -/* -======================================================================== -Routine Description: - Release allocated resources. - -Arguments: - *dev Point to the PCI or USB device - pAd driver control block pointer - -Return Value: - None - -Note: -======================================================================== -*/ -static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd) -{ - DBGPRINT(RT_DEBUG_ERROR, - ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", - dev->bus->bus_name, dev->devpath)); - if (!pAd) { - usb_put_dev(dev); - printk(KERN_ERR "rtusb_disconnect: pAd == NULL!\n"); - return; - } - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); - - /* for debug, wait to show some messages to /proc system */ - udelay(1); - - RtmpPhyNetDevExit(pAd, pAd->net_dev); - - /* FIXME: Shall we need following delay and flush the schedule?? */ - udelay(1); - flush_scheduled_work(); - udelay(1); - - /* free the root net_device */ - RtmpOSNetDevFree(pAd->net_dev); - - RtmpRaDevCtrlExit(pAd); - - /* release a use of the usb device structure */ - usb_put_dev(dev); - udelay(1); - - DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); -} - -static int __devinit rt2870_probe(IN struct usb_interface *intf, - IN struct usb_device *usb_dev, - IN const struct usb_device_id *dev_id, - struct rt_rtmp_adapter **ppAd) -{ - struct net_device *net_dev = NULL; - struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL; - int status, rv; - void *handle; - struct rt_rtmp_os_netdev_op_hook netDevHook; - - DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n")); - - /* Check chipset vendor/product ID */ - /*if (RT28XXChipsetCheck(_dev_p) == FALSE) */ - /* goto err_out; */ - -/*RtmpDevInit============================================= */ - /* Allocate struct rt_rtmp_adapter adapter structure */ - handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); - if (handle == NULL) { - printk - ("rt2870_probe(): Allocate memory for os handle failed!\n"); - return -ENOMEM; - } - ((struct os_cookie *)handle)->pUsb_Dev = usb_dev; - - rv = RTMPAllocAdapterBlock(handle, &pAd); - if (rv != NDIS_STATUS_SUCCESS) { - kfree(handle); - goto err_out; - } -/*USBDevInit============================================== */ - if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE) - goto err_out_free_radev; - - RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB); - -/*NetDevInit============================================== */ - net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); - if (net_dev == NULL) - goto err_out_free_radev; - - /* Here are the net_device structure with usb specific parameters. - * for supporting Network Manager. - * Set the sysfs physical device reference for the network logical device if set prior to registration will - * cause a symlink during initialization. - */ - SET_NETDEV_DEV(net_dev, &(usb_dev->dev)); - - pAd->StaCfg.OriDevType = net_dev->type; - -/*All done, it's time to register the net device to linux kernel. */ - /* Register this device */ - status = RtmpOSNetDevAttach(net_dev, &netDevHook); - if (status != 0) - goto err_out_free_netdev; - -#ifdef KTHREAD_SUPPORT - init_waitqueue_head(&pAd->mlmeTask.kthread_q); - init_waitqueue_head(&pAd->timerTask.kthread_q); - init_waitqueue_head(&pAd->cmdQTask.kthread_q); -#endif - - *ppAd = pAd; - - DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n")); - - return 0; - - /* --------------------------- ERROR HANDLE --------------------------- */ -err_out_free_netdev: - RtmpOSNetDevFree(net_dev); - -err_out_free_radev: - RTMPFreeAdapter(pAd); - -err_out: - *ppAd = NULL; - - return -1; - -} diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h deleted file mode 100644 index a7796d330b71..000000000000 --- a/drivers/staging/rt2860/wpa.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - wpa.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Justin P. Mattock 11/07/2010 Fix a typo -*/ - -#ifndef __WPA_H__ -#define __WPA_H__ - -/* EAPOL Key descriptor frame format related length */ -#define LEN_KEY_DESC_NONCE 32 -#define LEN_KEY_DESC_IV 16 -#define LEN_KEY_DESC_RSC 8 -#define LEN_KEY_DESC_ID 8 -#define LEN_KEY_DESC_REPLAY 8 -#define LEN_KEY_DESC_MIC 16 - -/* The length is the EAPoL-Key frame except key data field. */ -/* Please refer to 802.11i-2004 ,Figure 43u in p.78 */ -#define LEN_EAPOL_KEY_MSG (sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE) - -/* EAP Code Type. */ -#define EAP_CODE_REQUEST 1 -#define EAP_CODE_RESPONSE 2 -#define EAP_CODE_SUCCESS 3 -#define EAP_CODE_FAILURE 4 - -/* EAPOL frame Protocol Version */ -#define EAPOL_VER 1 -#define EAPOL_VER2 2 - -/* EAPOL-KEY Descriptor Type */ -#define WPA1_KEY_DESC 0xfe -#define WPA2_KEY_DESC 0x02 - -/* Key Descriptor Version of Key Information */ -#define DESC_TYPE_TKIP 1 -#define DESC_TYPE_AES 2 - -#define LEN_MSG1_2WAY 0x7f -#define MAX_LEN_OF_EAP_HS 256 - -#define LEN_MASTER_KEY 32 - -/* EAPOL EK, MK */ -#define LEN_EAP_EK 16 -#define LEN_EAP_MICK 16 -#define LEN_EAP_KEY ((LEN_EAP_EK)+(LEN_EAP_MICK)) -/* TKIP key related */ -#define LEN_PMKID 16 -#define LEN_TKIP_EK 16 -#define LEN_TKIP_RXMICK 8 -#define LEN_TKIP_TXMICK 8 -#define LEN_AES_EK 16 -#define LEN_AES_KEY LEN_AES_EK -#define LEN_TKIP_KEY ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK)) -#define TKIP_AP_TXMICK_OFFSET ((LEN_EAP_KEY)+(LEN_TKIP_EK)) -#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK) -#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK)) -#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY)) -#define MIN_LEN_OF_GTK 5 -#define LEN_PMK 32 -#define LEN_PMK_NAME 16 -#define LEN_NONCE 32 - -/* RSN IE Length definition */ -#define MAX_LEN_OF_RSNIE 255 -#define MIN_LEN_OF_RSNIE 8 - -#define KEY_LIFETIME 3600 - -/*EAP Packet Type */ -#define EAPPacket 0 -#define EAPOLStart 1 -#define EAPOLLogoff 2 -#define EAPOLKey 3 -#define EAPOLASFAlert 4 -#define EAPTtypeMax 5 - -#define EAPOL_MSG_INVALID 0 -#define EAPOL_PAIR_MSG_1 1 -#define EAPOL_PAIR_MSG_2 2 -#define EAPOL_PAIR_MSG_3 3 -#define EAPOL_PAIR_MSG_4 4 -#define EAPOL_GROUP_MSG_1 5 -#define EAPOL_GROUP_MSG_2 6 - -#define PAIRWISEKEY 1 -#define GROUPKEY 0 - -/* Retry timer counter initial value */ -#define PEER_MSG1_RETRY_TIMER_CTR 0 -#define PEER_MSG3_RETRY_TIMER_CTR 10 -#define GROUP_MSG1_RETRY_TIMER_CTR 20 - -/*#ifdef CONFIG_AP_SUPPORT */ -/* WPA mechanism retry timer interval */ -#define PEER_MSG1_RETRY_EXEC_INTV 1000 /* 1 sec */ -#define PEER_MSG3_RETRY_EXEC_INTV 3000 /* 3 sec */ -#define GROUP_KEY_UPDATE_EXEC_INTV 1000 /* 1 sec */ -#define PEER_GROUP_KEY_UPDATE_INIV 2000 /* 2 sec */ - -#define ENQUEUE_EAPOL_START_TIMER 200 /* 200 ms */ - -/* group rekey interval */ -#define TIME_REKEY 0 -#define PKT_REKEY 1 -#define DISABLE_REKEY 2 -#define MAX_REKEY 2 - -#define MAX_REKEY_INTER 0x3ffffff -/*#endif // CONFIG_AP_SUPPORT // */ - -#define GROUP_SUITE 0 -#define PAIRWISE_SUITE 1 -#define AKM_SUITE 2 -#define PMKID_LIST 3 - -#define EAPOL_START_DISABLE 0 -#define EAPOL_START_PSK 1 -#define EAPOL_START_1X 2 - -#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0) -#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0) -#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0) -#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0) - -#ifndef ROUND_UP -#define ROUND_UP(__x, __y) \ - (((unsigned long)((__x)+((__y)-1))) & ((unsigned long)~((__y)-1))) -#endif - -#define SET_u16_TO_ARRARY(_V, _LEN) \ -{ \ - _V[0] = (_LEN & 0xFF00) >> 8; \ - _V[1] = (_LEN & 0xFF); \ -} - -#define INC_u16_TO_ARRARY(_V, _LEN) \ -{ \ - u16 var_len; \ - \ - var_len = (_V[0]<<8) | (_V[1]); \ - var_len += _LEN; \ - \ - _V[0] = (var_len & 0xFF00) >> 8; \ - _V[1] = (var_len & 0xFF); \ -} - -#define CONV_ARRARY_TO_u16(_V) ((_V[0]<<8) | (_V[1])) - -#define ADD_ONE_To_64BIT_VAR(_V) \ -{ \ - u8 cnt = LEN_KEY_DESC_REPLAY; \ - do \ - { \ - cnt--; \ - _V[cnt]++; \ - if (cnt == 0) \ - break; \ - }while (_V[cnt] == 0); \ -} - -#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK)) - -/* EAPOL Key Information definition within Key descriptor format */ -struct PACKED rt_key_info { - u8 KeyMic:1; - u8 Secure:1; - u8 Error:1; - u8 Request:1; - u8 EKD_DL:1; /* EKD for AP; DL for STA */ - u8 Rsvd:3; - u8 KeyDescVer:3; - u8 KeyType:1; - u8 KeyIndex:2; - u8 Install:1; - u8 KeyAck:1; -}; - -/* EAPOL Key descriptor format */ -struct PACKED rt_key_descripter { - u8 Type; - struct rt_key_info KeyInfo; - u8 KeyLength[2]; - u8 ReplayCounter[LEN_KEY_DESC_REPLAY]; - u8 KeyNonce[LEN_KEY_DESC_NONCE]; - u8 KeyIv[LEN_KEY_DESC_IV]; - u8 KeyRsc[LEN_KEY_DESC_RSC]; - u8 KeyId[LEN_KEY_DESC_ID]; - u8 KeyMic[LEN_KEY_DESC_MIC]; - u8 KeyDataLen[2]; - u8 KeyData[MAX_LEN_OF_RSNIE]; -}; - -struct PACKED rt_eapol_packet { - u8 ProVer; - u8 ProType; - u8 Body_Len[2]; - struct rt_key_descripter KeyDesc; -}; - -/*802.11i D10 page 83 */ -struct PACKED rt_gtk_encap { - u8 Kid:2; - u8 tx:1; - u8 rsv:5; - u8 rsv1; - u8 GTK[TKIP_GTK_LENGTH]; -}; - -struct PACKED rt_kde_encap { - u8 Type; - u8 Len; - u8 OUI[3]; - u8 DataType; - struct rt_gtk_encap GTKEncap; -}; - -/* For WPA1 */ -struct PACKED rt_rsnie { - u8 oui[4]; - u16 version; - u8 mcast[4]; - u16 ucount; - struct PACKED { - u8 oui[4]; - } ucast[1]; -}; - -/* For WPA2 */ -struct PACKED rt_rsnie2 { - u16 version; - u8 mcast[4]; - u16 ucount; - struct PACKED { - u8 oui[4]; - } ucast[1]; -}; - -/* AKM Suite */ -struct PACKED rt_rsnie_auth { - u16 acount; - struct PACKED { - u8 oui[4]; - } auth[1]; -}; - -typedef union PACKED _RSN_CAPABILITIES { - struct PACKED { - u16 PreAuth:1; - u16 No_Pairwise:1; - u16 PTKSA_R_Counter:2; - u16 GTKSA_R_Counter:2; - u16 Rsvd:10; - } field; - u16 word; -} RSN_CAPABILITIES, *PRSN_CAPABILITIES; - -struct PACKED rt_eap_hdr { - u8 ProVer; - u8 ProType; - u8 Body_Len[2]; - u8 code; - u8 identifier; - u8 length[2]; /* including code and identifier, followed by length-2 octets of data */ -}; - -/* For supplicant state machine states. 802.11i Draft 4.1, p. 97 */ -/* We simplified it */ -typedef enum _WpaState { - SS_NOTUSE, /* 0 */ - SS_START, /* 1 */ - SS_WAIT_MSG_3, /* 2 */ - SS_WAIT_GROUP, /* 3 */ - SS_FINISH, /* 4 */ - SS_KEYUPDATE, /* 5 */ -} WPA_STATE; - -/* */ -/* The definition of the cipher combination */ -/* */ -/* bit3 bit2 bit1 bit0 */ -/* +------------+------------+ */ -/* | WPA | WPA2 | */ -/* +------+-----+------+-----+ */ -/* | TKIP | AES | TKIP | AES | */ -/* | 0 | 1 | 1 | 0 | -> 0x06 */ -/* | 0 | 1 | 1 | 1 | -> 0x07 */ -/* | 1 | 0 | 0 | 1 | -> 0x09 */ -/* | 1 | 0 | 1 | 1 | -> 0x0B */ -/* | 1 | 1 | 0 | 1 | -> 0x0D */ -/* | 1 | 1 | 1 | 0 | -> 0x0E */ -/* | 1 | 1 | 1 | 1 | -> 0x0F */ -/* +------+-----+------+-----+ */ -/* */ -typedef enum _WpaMixPairCipher { - MIX_CIPHER_NOTUSE = 0x00, - WPA_NONE_WPA2_TKIPAES = 0x03, /* WPA2-TKIPAES */ - WPA_AES_WPA2_TKIP = 0x06, - WPA_AES_WPA2_TKIPAES = 0x07, - WPA_TKIP_WPA2_AES = 0x09, - WPA_TKIP_WPA2_TKIPAES = 0x0B, - WPA_TKIPAES_WPA2_NONE = 0x0C, /* WPA-TKIPAES */ - WPA_TKIPAES_WPA2_AES = 0x0D, - WPA_TKIPAES_WPA2_TKIP = 0x0E, - WPA_TKIPAES_WPA2_TKIPAES = 0x0F, -} WPA_MIX_PAIR_CIPHER; - -struct PACKED rt_rsn_ie_header { - u8 Eid; - u8 Length; - u16 Version; /* Little endian format */ -}; - -/* Cipher suite selector types */ -struct PACKED rt_cipher_suite_struct { - u8 Oui[3]; - u8 Type; -}; - -/* Authentication and Key Management suite selector */ -struct PACKED rt_akm_suite { - u8 Oui[3]; - u8 Type; -}; - -/* RSN capability */ -struct PACKED rt_rsn_capability { - u16 Rsv:10; - u16 GTKSAReplayCnt:2; - u16 PTKSAReplayCnt:2; - u16 NoPairwise:1; - u16 PreAuth:1; -}; - -/*======================================== - The prototype is defined in cmm_wpa.c - ========================================*/ -BOOLEAN WpaMsgTypeSubst(u8 EAPType, int *MsgType); - -void PRF(u8 *key, int key_len, u8 *prefix, int prefix_len, - u8 *data, int data_len, u8 *output, int len); - -int PasswordHash(char *password, - unsigned char *ssid, int ssidlength, unsigned char *output); - -u8 *GetSuiteFromRSNIE(u8 *rsnie, u32 rsnie_len, u8 type, u8 *count); - -void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len); - -void RTMPInsertRSNIE(u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 *rsnie_ptr, - u8 rsnie_len, - u8 *pmkid_ptr, u8 pmkid_len); - -#endif diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig deleted file mode 100644 index e988680b5be4..000000000000 --- a/drivers/staging/rt2870/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config RT2870 - tristate "Ralink 2870/3070 wireless support" - depends on USB && (X86 || ARM) && WLAN - select WIRELESS_EXT - select WEXT_PRIV - select CRC_CCITT - select FW_LOADER - ---help--- - This is an experimental driver for the Ralink xx70 wireless chips. diff --git a/drivers/staging/rt2870/Makefile b/drivers/staging/rt2870/Makefile deleted file mode 100644 index b499910ed738..000000000000 --- a/drivers/staging/rt2870/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# -obj-$(CONFIG_RT2870) += rt2870sta.o - -# TODO: all of these should be removed -ccflags-y := -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -ccflags-y += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRTMP_TIMER_TASK_SUPPORT -ccflags-y += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3070 -ccflags-y += -DDBG - -rt2870sta-y := \ - common/crypt_md5.o \ - common/crypt_sha2.o \ - common/crypt_hmac.o \ - common/mlme.o \ - common/cmm_wep.o \ - common/action.o \ - common/cmm_data.o \ - common/rtmp_init.o \ - common/cmm_tkip.o \ - common/cmm_aes.o \ - common/cmm_sync.o \ - common/eeprom.o \ - common/cmm_sanity.o \ - common/cmm_info.o \ - common/cmm_cfg.o \ - common/cmm_wpa.o \ - common/dfs.o \ - common/spectrum.o \ - common/rtmp_timer.o \ - common/rt_channel.o \ - common/cmm_asic.o \ - sta/assoc.o \ - sta/auth.o \ - sta/auth_rsp.o \ - sta/sync.o \ - sta/sanity.o \ - sta/rtmp_data.o \ - sta/connect.o \ - sta/wpa.o \ - rt_linux.o \ - rt_main_dev.o \ - sta_ioctl.o \ - common/ba_action.o \ - usb_main_dev.o \ - rt_usb.o \ - common/cmm_mac_usb.o \ - common/rtusb_io.o \ - common/rtusb_bulk.o \ - common/rtusb_data.o \ - common/cmm_data_usb.o \ - common/rtmp_mcu.o \ - common/ee_efuse.o \ - chips/rt30xx.o \ - common/rt_rf.o \ - chips/rt3070.o diff --git a/drivers/staging/rt2870/TODO b/drivers/staging/rt2870/TODO deleted file mode 100644 index 2df1bfed9a58..000000000000 --- a/drivers/staging/rt2870/TODO +++ /dev/null @@ -1,17 +0,0 @@ -I'm hesitant to add a TODO file here, as the wireless developers would -really have people help them out on the "clean" rt2870 driver that can -be found at the http://rt2x00.serialmonkey.com/ site. - -But, if you wish to clean up this driver instead, here's a short list of -things that need to be done to get it into a more mergable shape: - -TODO: - - checkpatch.pl clean - - sparse clean - - port to in-kernel 80211 stack and common rt2x00 infrastructure - - remove reading from /etc/ config files - - review by the wireless developer community - -Please send any patches or complaints about this driver to Greg -Kroah-Hartman and don't bother the upstream wireless -kernel developers about it, they want nothing to do with it. diff --git a/drivers/staging/rt2870/aironet.h b/drivers/staging/rt2870/aironet.h deleted file mode 100644 index ae6259710a4f..000000000000 --- a/drivers/staging/rt2870/aironet.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/aironet.h" diff --git a/drivers/staging/rt2870/ap.h b/drivers/staging/rt2870/ap.h deleted file mode 100644 index fe04b5f45f20..000000000000 --- a/drivers/staging/rt2870/ap.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/ap.h" diff --git a/drivers/staging/rt2870/chips/rt3070.c b/drivers/staging/rt2870/chips/rt3070.c deleted file mode 100644 index 3a6db5ea89ab..000000000000 --- a/drivers/staging/rt2870/chips/rt3070.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/chips/rt3070.c" diff --git a/drivers/staging/rt2870/chips/rt30xx.c b/drivers/staging/rt2870/chips/rt30xx.c deleted file mode 100644 index 6c56b84c75d9..000000000000 --- a/drivers/staging/rt2870/chips/rt30xx.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/chips/rt30xx.c" diff --git a/drivers/staging/rt2870/chlist.h b/drivers/staging/rt2870/chlist.h deleted file mode 100644 index 31999583b379..000000000000 --- a/drivers/staging/rt2870/chlist.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/chlist.h" diff --git a/drivers/staging/rt2870/common/acction.c b/drivers/staging/rt2870/common/acction.c deleted file mode 100644 index fd806c3871aa..000000000000 --- a/drivers/staging/rt2870/common/acction.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/action.c" diff --git a/drivers/staging/rt2870/common/action.c b/drivers/staging/rt2870/common/action.c deleted file mode 100644 index fd806c3871aa..000000000000 --- a/drivers/staging/rt2870/common/action.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/action.c" diff --git a/drivers/staging/rt2870/common/action.h b/drivers/staging/rt2870/common/action.h deleted file mode 100644 index 9a1895525f30..000000000000 --- a/drivers/staging/rt2870/common/action.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/action.h" diff --git a/drivers/staging/rt2870/common/ba_action.c b/drivers/staging/rt2870/common/ba_action.c deleted file mode 100644 index a9e6a09d994f..000000000000 --- a/drivers/staging/rt2870/common/ba_action.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/ba_action.c" diff --git a/drivers/staging/rt2870/common/cmm_aes.c b/drivers/staging/rt2870/common/cmm_aes.c deleted file mode 100644 index 15d6a14d2d9c..000000000000 --- a/drivers/staging/rt2870/common/cmm_aes.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_aes.c" diff --git a/drivers/staging/rt2870/common/cmm_asic.c b/drivers/staging/rt2870/common/cmm_asic.c deleted file mode 100644 index 38de817991ff..000000000000 --- a/drivers/staging/rt2870/common/cmm_asic.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_asic.c" diff --git a/drivers/staging/rt2870/common/cmm_cfg.c b/drivers/staging/rt2870/common/cmm_cfg.c deleted file mode 100644 index 6b2bdd7d44ec..000000000000 --- a/drivers/staging/rt2870/common/cmm_cfg.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_cfg.c" diff --git a/drivers/staging/rt2870/common/cmm_data.c b/drivers/staging/rt2870/common/cmm_data.c deleted file mode 100644 index df775c3cf691..000000000000 --- a/drivers/staging/rt2870/common/cmm_data.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_data.c" diff --git a/drivers/staging/rt2870/common/cmm_data_usb.c b/drivers/staging/rt2870/common/cmm_data_usb.c deleted file mode 100644 index 704675fccb7d..000000000000 --- a/drivers/staging/rt2870/common/cmm_data_usb.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_data_usb.c" diff --git a/drivers/staging/rt2870/common/cmm_info.c b/drivers/staging/rt2870/common/cmm_info.c deleted file mode 100644 index 226187ee5561..000000000000 --- a/drivers/staging/rt2870/common/cmm_info.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_info.c" diff --git a/drivers/staging/rt2870/common/cmm_mac_usb.c b/drivers/staging/rt2870/common/cmm_mac_usb.c deleted file mode 100644 index b26af4af890b..000000000000 --- a/drivers/staging/rt2870/common/cmm_mac_usb.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_mac_usb.c" diff --git a/drivers/staging/rt2870/common/cmm_profile.c b/drivers/staging/rt2870/common/cmm_profile.c deleted file mode 100644 index 9926e45aba3c..000000000000 --- a/drivers/staging/rt2870/common/cmm_profile.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_profile.c" diff --git a/drivers/staging/rt2870/common/cmm_sanity.c b/drivers/staging/rt2870/common/cmm_sanity.c deleted file mode 100644 index cb3352118c57..000000000000 --- a/drivers/staging/rt2870/common/cmm_sanity.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_sanity.c" diff --git a/drivers/staging/rt2870/common/cmm_sync.c b/drivers/staging/rt2870/common/cmm_sync.c deleted file mode 100644 index 5e7221d7cb27..000000000000 --- a/drivers/staging/rt2870/common/cmm_sync.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_sync.c" diff --git a/drivers/staging/rt2870/common/cmm_tkip.c b/drivers/staging/rt2870/common/cmm_tkip.c deleted file mode 100644 index f73c71bafe86..000000000000 --- a/drivers/staging/rt2870/common/cmm_tkip.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_tkip.c" diff --git a/drivers/staging/rt2870/common/cmm_wep.c b/drivers/staging/rt2870/common/cmm_wep.c deleted file mode 100644 index 5f681078387f..000000000000 --- a/drivers/staging/rt2870/common/cmm_wep.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_wep.c" diff --git a/drivers/staging/rt2870/common/cmm_wpa.c b/drivers/staging/rt2870/common/cmm_wpa.c deleted file mode 100644 index 04a54bb21853..000000000000 --- a/drivers/staging/rt2870/common/cmm_wpa.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/cmm_wpa.c" diff --git a/drivers/staging/rt2870/common/crypt_hmac.c b/drivers/staging/rt2870/common/crypt_hmac.c deleted file mode 100644 index 24d84e7724fb..000000000000 --- a/drivers/staging/rt2870/common/crypt_hmac.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/crypt_hmac.c" diff --git a/drivers/staging/rt2870/common/crypt_md5.c b/drivers/staging/rt2870/common/crypt_md5.c deleted file mode 100644 index 457a2caca1e3..000000000000 --- a/drivers/staging/rt2870/common/crypt_md5.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/crypt_md5.c" diff --git a/drivers/staging/rt2870/common/crypt_sha2.c b/drivers/staging/rt2870/common/crypt_sha2.c deleted file mode 100644 index 07ffb300c193..000000000000 --- a/drivers/staging/rt2870/common/crypt_sha2.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/crypt_sha2.c" diff --git a/drivers/staging/rt2870/common/dfs.c b/drivers/staging/rt2870/common/dfs.c deleted file mode 100644 index ac2da4c0e2ca..000000000000 --- a/drivers/staging/rt2870/common/dfs.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/dfs.c" diff --git a/drivers/staging/rt2870/common/ee_efuse.c b/drivers/staging/rt2870/common/ee_efuse.c deleted file mode 100644 index 0e34e65e5f28..000000000000 --- a/drivers/staging/rt2870/common/ee_efuse.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/ee_efuse.c" diff --git a/drivers/staging/rt2870/common/eeprom.c b/drivers/staging/rt2870/common/eeprom.c deleted file mode 100644 index def09658fd81..000000000000 --- a/drivers/staging/rt2870/common/eeprom.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/eeprom.c" diff --git a/drivers/staging/rt2870/common/md5.c b/drivers/staging/rt2870/common/md5.c deleted file mode 100644 index 195645c0e1a8..000000000000 --- a/drivers/staging/rt2870/common/md5.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/md5.c" diff --git a/drivers/staging/rt2870/common/mlme.c b/drivers/staging/rt2870/common/mlme.c deleted file mode 100644 index f88040abd26b..000000000000 --- a/drivers/staging/rt2870/common/mlme.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/mlme.c" diff --git a/drivers/staging/rt2870/common/rt_channel.c b/drivers/staging/rt2870/common/rt_channel.c deleted file mode 100644 index c8ceb4c177d9..000000000000 --- a/drivers/staging/rt2870/common/rt_channel.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rt_channel.c" diff --git a/drivers/staging/rt2870/common/rt_rf.c b/drivers/staging/rt2870/common/rt_rf.c deleted file mode 100644 index b81cff34969b..000000000000 --- a/drivers/staging/rt2870/common/rt_rf.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rt_rf.c" diff --git a/drivers/staging/rt2870/common/rtmp_init.c b/drivers/staging/rt2870/common/rtmp_init.c deleted file mode 100644 index eef10efda196..000000000000 --- a/drivers/staging/rt2870/common/rtmp_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rtmp_init.c" diff --git a/drivers/staging/rt2870/common/rtmp_mcu.c b/drivers/staging/rt2870/common/rtmp_mcu.c deleted file mode 100644 index 20b7f13d60f8..000000000000 --- a/drivers/staging/rt2870/common/rtmp_mcu.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rtmp_mcu.c" diff --git a/drivers/staging/rt2870/common/rtmp_timer.c b/drivers/staging/rt2870/common/rtmp_timer.c deleted file mode 100644 index fd4aedcd5e8b..000000000000 --- a/drivers/staging/rt2870/common/rtmp_timer.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rtmp_timer.c" diff --git a/drivers/staging/rt2870/common/rtmp_tkip.c b/drivers/staging/rt2870/common/rtmp_tkip.c deleted file mode 100644 index 240bf67f521f..000000000000 --- a/drivers/staging/rt2870/common/rtmp_tkip.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rtmp_tkip.c" diff --git a/drivers/staging/rt2870/common/rtmp_wep.c b/drivers/staging/rt2870/common/rtmp_wep.c deleted file mode 100644 index ae255adc9f7f..000000000000 --- a/drivers/staging/rt2870/common/rtmp_wep.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/rtmp_wep.c" diff --git a/drivers/staging/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c deleted file mode 100644 index 679b802d2169..000000000000 --- a/drivers/staging/rt2870/common/rtusb_bulk.c +++ /dev/null @@ -1,1232 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtusb_bulk.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Paul Lin 06-25-2004 created - -*/ - -#ifdef RTMP_MAC_USB - -#include "../rt_config.h" -/* Match total 6 bulkout endpoint to corresponding queue. */ -u8 EpToQueue[6] = - { FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT }; - -/*static BOOLEAN SingleBulkOut = FALSE; */ - -void RTUSB_FILL_BULK_URB(struct urb *pUrb, - struct usb_device *pUsb_Dev, - unsigned int bulkpipe, - void *pTransferBuf, - int BufSize, usb_complete_t Complete, void *pContext) -{ - - usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, - (usb_complete_t) Complete, pContext); - -} - -void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd, - struct rt_tx_context *pTxContext, - u8 BulkOutPipeId, IN usb_complete_t Func) -{ - PURB pUrb; - u8 *pSrc = NULL; - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - pUrb = pTxContext->pUrb; - ASSERT(pUrb); - - /* Store BulkOut PipeId */ - pTxContext->BulkOutPipeId = BulkOutPipeId; - - if (pTxContext->bAggregatible) { - pSrc = &pTxContext->TransferBuffer->Aggregation[2]; - } else { - pSrc = - (u8 *)pTxContext->TransferBuffer->field.WirelessPacket; - } - - /*Initialize a tx bulk urb */ - RTUSB_FILL_BULK_URB(pUrb, - pObj->pUsb_Dev, - usb_sndbulkpipe(pObj->pUsb_Dev, - pAd->BulkOutEpAddr[BulkOutPipeId]), - pSrc, pTxContext->BulkOutSize, Func, pTxContext); - - if (pTxContext->bAggregatible) - pUrb->transfer_dma = - (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2); - else - pUrb->transfer_dma = pTxContext->data_dma; - - pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - -} - -void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd, - struct rt_ht_tx_context *pTxContext, - u8 BulkOutPipeId, - unsigned long BulkOutSize, IN usb_complete_t Func) -{ - PURB pUrb; - u8 *pSrc = NULL; - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - pUrb = pTxContext->pUrb; - ASSERT(pUrb); - - /* Store BulkOut PipeId */ - pTxContext->BulkOutPipeId = BulkOutPipeId; - - pSrc = - &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext-> - NextBulkOutPosition]; - - /*Initialize a tx bulk urb */ - RTUSB_FILL_BULK_URB(pUrb, - pObj->pUsb_Dev, - usb_sndbulkpipe(pObj->pUsb_Dev, - pAd->BulkOutEpAddr[BulkOutPipeId]), - pSrc, BulkOutSize, Func, pTxContext); - - pUrb->transfer_dma = - (pTxContext->data_dma + pTxContext->NextBulkOutPosition); - pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - -} - -void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext) -{ - PURB pUrb; - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - unsigned long RX_bulk_size; - - pUrb = pRxContext->pUrb; - ASSERT(pUrb); - - if (pAd->BulkInMaxPacketSize == 64) - RX_bulk_size = 4096; - else - RX_bulk_size = MAX_RXBULK_SIZE; - - /*Initialize a rx bulk urb */ - RTUSB_FILL_BULK_URB(pUrb, - pObj->pUsb_Dev, - usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr), - &(pRxContext-> - TransferBuffer[pAd->NextRxBulkInPosition]), - RX_bulk_size - (pAd->NextRxBulkInPosition), - (usb_complete_t) RTUSBBulkRxComplete, - (void *)pRxContext); - - pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition; - pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ - -#define BULK_OUT_LOCK(pLock, IrqFlags) \ - if (1 /*!(in_interrupt() & 0xffff0000)*/) \ - RTMP_IRQ_LOCK((pLock), IrqFlags); - -#define BULK_OUT_UNLOCK(pLock, IrqFlags) \ - if (1 /*!(in_interrupt() & 0xffff0000)*/) \ - RTMP_IRQ_UNLOCK((pLock), IrqFlags); - -void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, - u8 BulkOutPipeId, u8 Index) -{ - - struct rt_ht_tx_context *pHTTXContext; - PURB pUrb; - int ret = 0; - struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL; - struct rt_txwi *pTxWI; - unsigned long TmpBulkEndPos, ThisBulkSize; - unsigned long IrqFlags = 0, IrqFlags2 = 0; - u8 *pWirelessPkt, *pAppendant; - BOOLEAN bTxQLastRound = FALSE; - u8 allzero[4] = { 0x0, 0x0, 0x0, 0x0 }; - - BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - return; - } - pAd->BulkOutPending[BulkOutPipeId] = TRUE; - - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) - ) { - pAd->BulkOutPending[BulkOutPipeId] = FALSE; - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - return; - } - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - - pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); - - BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); - if ((pHTTXContext->ENextBulkOutPosition == - pHTTXContext->CurWritePosition) - || ((pHTTXContext->ENextBulkOutPosition - 8) == - pHTTXContext->CurWritePosition)) { - BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], - IrqFlags2); - - BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - pAd->BulkOutPending[BulkOutPipeId] = FALSE; - - /* Clear Data flag */ - RTUSB_CLEAR_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_FRAG << - BulkOutPipeId)); - RTUSB_CLEAR_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << - BulkOutPipeId)); - - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - return; - } - /* Clear Data flag */ - RTUSB_CLEAR_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); - RTUSB_CLEAR_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); - - /*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */ - /* pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */ - /* pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */ - pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; - ThisBulkSize = 0; - TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; - pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; - - if ((pHTTXContext->bCopySavePad == TRUE)) { - if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("e1, allzero : %x %x %x %x %x %x %x %x \n", - pHTTXContext->SavedPad[0], - pHTTXContext->SavedPad[1], - pHTTXContext->SavedPad[2], - pHTTXContext->SavedPad[3] - , pHTTXContext->SavedPad[4], - pHTTXContext->SavedPad[5], - pHTTXContext->SavedPad[6], - pHTTXContext->SavedPad[7])); - } - NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], - pHTTXContext->SavedPad, 8); - pHTTXContext->bCopySavePad = FALSE; - if (pAd->bForcePrintTX == TRUE) - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", - pHTTXContext->CurWritePosition, - pHTTXContext->NextBulkOutPosition, - pHTTXContext->ENextBulkOutPosition)); - } - - do { - pTxInfo = (struct rt_txinfo *)&pWirelessPkt[TmpBulkEndPos]; - pTxWI = - (struct rt_txwi *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; - - if (pAd->bForcePrintTX == TRUE) - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBBulkOutDataPacket AMPDU = %d.\n", - pTxWI->AMPDU)); - - /* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items */ - /*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ - if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { - if (((ThisBulkSize & 0xffff8000) != 0) - || ((ThisBulkSize & 0x1000) == 0x1000)) { - /* Limit BulkOut size to about 4k bytes. */ - pHTTXContext->ENextBulkOutPosition = - TmpBulkEndPos; - break; - } else - if (((pAd->BulkOutMaxPacketSize < 512) - && ((ThisBulkSize & 0xfffff800) != - 0)) - /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ - ) { - /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ - /* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ - pHTTXContext->ENextBulkOutPosition = - TmpBulkEndPos; - break; - } - } - /* end Iverson */ - else { - if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) { /* Limit BulkOut size to about 24k bytes. */ - pHTTXContext->ENextBulkOutPosition = - TmpBulkEndPos; - break; - } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ - /* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ - pHTTXContext->ENextBulkOutPosition = - TmpBulkEndPos; - break; - } - } - - if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { - pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; - break; - } - - if (pTxInfo->QSEL != FIFO_EDCA) { - DBGPRINT(RT_DEBUG_ERROR, - ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", - __func__, pTxInfo->QSEL)); - DBGPRINT(RT_DEBUG_ERROR, - ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", - pHTTXContext->CurWritePosition, - pHTTXContext->NextBulkOutPosition, - pHTTXContext->ENextBulkOutPosition, - pHTTXContext->bCopySavePad)); - hex_dump("Wrong QSel Pkt:", - (u8 *)&pWirelessPkt[TmpBulkEndPos], - (pHTTXContext->CurWritePosition - - pHTTXContext->NextBulkOutPosition)); - } - - if (pTxInfo->USBDMATxPktLen <= 8) { - BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], - IrqFlags2); - DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ , - ("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", - pHTTXContext->BulkOutSize, - pHTTXContext->bCopySavePad, - pHTTXContext->CurWritePosition, - pHTTXContext->NextBulkOutPosition, - pHTTXContext->CurWriteRealPos)); - { - DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ - , - ("%x %x %x %x %x %x %x %x \n", - pHTTXContext->SavedPad[0], - pHTTXContext->SavedPad[1], - pHTTXContext->SavedPad[2], - pHTTXContext->SavedPad[3] - , pHTTXContext->SavedPad[4], - pHTTXContext->SavedPad[5], - pHTTXContext->SavedPad[6], - pHTTXContext->SavedPad[7])); - } - pAd->bForcePrintTX = TRUE; - BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], - IrqFlags); - pAd->BulkOutPending[BulkOutPipeId] = FALSE; - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], - IrqFlags); - /*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); */ - return; - } - /* Increase Total transmit byte counter */ - pAd->RalinkCounters.OneSecTransmittedByteCount += - pTxWI->MPDUtotalByteCount; - pAd->RalinkCounters.TransmittedByteCount += - pTxWI->MPDUtotalByteCount; - - pLastTxInfo = pTxInfo; - - /* Make sure we use EDCA QUEUE. */ - pTxInfo->QSEL = FIFO_EDCA; - ThisBulkSize += (pTxInfo->USBDMATxPktLen + 4); - TmpBulkEndPos += (pTxInfo->USBDMATxPktLen + 4); - - if (TmpBulkEndPos != pHTTXContext->CurWritePosition) - pTxInfo->USBDMANextVLD = 1; - - if (pTxInfo->SwUseLastRound == 1) { - if (pHTTXContext->CurWritePosition == 8) - pTxInfo->USBDMANextVLD = 0; - pTxInfo->SwUseLastRound = 0; - - bTxQLastRound = TRUE; - pHTTXContext->ENextBulkOutPosition = 8; - - break; - } - - } while (TRUE); - - /* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */ - if (pLastTxInfo) - pLastTxInfo->USBDMANextVLD = 0; - - /* - We need to copy SavedPad when following condition matched! - 1. Not the last round of the TxQueue and - 2. any match of following cases: - (1). The End Position of this bulk out is reach to the Currenct Write position and - the TxInfo and related header already write to the CurWritePosition. - =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition) - - (2). The EndPosition of the bulk out is not reach to the Current Write Position. - =>(ENextBulkOutPosition != CurWritePosition) - */ - if ((bTxQLastRound == FALSE) && - (((pHTTXContext->ENextBulkOutPosition == - pHTTXContext->CurWritePosition) - && (pHTTXContext->CurWriteRealPos > - pHTTXContext->CurWritePosition)) - || (pHTTXContext->ENextBulkOutPosition != - pHTTXContext->CurWritePosition)) - ) { - NdisMoveMemory(pHTTXContext->SavedPad, - &pWirelessPkt[pHTTXContext-> - ENextBulkOutPosition], 8); - pHTTXContext->bCopySavePad = TRUE; - if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) { - u8 *pBuf = &pHTTXContext->SavedPad[0]; - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", - pBuf[0], pBuf[1], pBuf[2], pBuf[3], - pBuf[4], pBuf[5], pBuf[6], pBuf[7], - pHTTXContext->CurWritePosition, - pHTTXContext->CurWriteRealPos, - pHTTXContext->bCurWriting, - pHTTXContext->NextBulkOutPosition, - TmpBulkEndPos, ThisBulkSize)); - - pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", - pBuf[0], pBuf[1], pBuf[2], pBuf[3], - pBuf[4], pBuf[5], pBuf[6], pBuf[7])); - } - /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */ - } - - if (pAd->bForcePrintTX == TRUE) - DBGPRINT(RT_DEBUG_TRACE, - ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", - ThisBulkSize, pHTTXContext->CurWritePosition, - pHTTXContext->NextBulkOutPosition, - pHTTXContext->ENextBulkOutPosition, - pHTTXContext->bCopySavePad)); - /*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound)); */ - - /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */ - pAppendant = &pWirelessPkt[TmpBulkEndPos]; - NdisZeroMemory(pAppendant, 8); - ThisBulkSize += 4; - pHTTXContext->LastOne = TRUE; - if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0) - ThisBulkSize += 4; - pHTTXContext->BulkOutSize = ThisBulkSize; - - pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; - BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); - - /* Init Tx context descriptor */ - RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, - (usb_complete_t) RTUSBBulkOutDataPacketComplete); - - pUrb = pHTTXContext->pUrb; - ret = RTUSB_SUBMIT_URB(pUrb); - if (ret != 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", - ret)); - - BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - pAd->BulkOutPending[BulkOutPipeId] = FALSE; - pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - - return; - } - - BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - pHTTXContext->IRPPending = TRUE; - BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - pAd->BulkOutReq++; - -} - -void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs) -{ - struct rt_ht_tx_context *pHTTXContext; - struct rt_rtmp_adapter *pAd; - struct os_cookie *pObj; - u8 BulkOutPipeId; - - pHTTXContext = (struct rt_ht_tx_context *)pUrb->context; - pAd = pHTTXContext->pAd; - pObj = (struct os_cookie *)pAd->OS_Cookie; - - /* Store BulkOut PipeId */ - BulkOutPipeId = pHTTXContext->BulkOutPipeId; - pAd->BulkOutDataOneSecCount++; - - switch (BulkOutPipeId) { - case 0: - pObj->ac0_dma_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->ac0_dma_done_task); - break; - case 1: - pObj->ac1_dma_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->ac1_dma_done_task); - break; - case 2: - pObj->ac2_dma_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->ac2_dma_done_task); - break; - case 3: - pObj->ac3_dma_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->ac3_dma_done_task); - break; - } - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: NULL frame use BulkOutPipeId = 0 - - ======================================================================== -*/ -void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd) -{ - struct rt_tx_context *pNullContext = &(pAd->NullContext); - PURB pUrb; - int ret = 0; - unsigned long IrqFlags; - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); - if ((pAd->BulkOutPending[0] == TRUE) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); - return; - } - pAd->BulkOutPending[0] = TRUE; - pAd->watchDogTxPendingCnt[0] = 1; - pNullContext->IRPPending = TRUE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); - - /* Increase Total transmit byte counter */ - pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; - - /* Clear Null frame bulk flag */ - RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); - - /* Init Tx context descriptor */ - RTUSBInitTxDesc(pAd, pNullContext, 0, - (usb_complete_t) RTUSBBulkOutNullFrameComplete); - - pUrb = pNullContext->pUrb; - ret = RTUSB_SUBMIT_URB(pUrb); - if (ret != 0) { - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); - pAd->BulkOutPending[0] = FALSE; - pAd->watchDogTxPendingCnt[0] = 0; - pNullContext->IRPPending = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); - - DBGPRINT(RT_DEBUG_ERROR, - ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", - ret)); - return; - } - -} - -/* NULL frame use BulkOutPipeId = 0 */ -void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs) -{ - struct rt_rtmp_adapter *pAd; - struct rt_tx_context *pNullContext; - int Status; - struct os_cookie *pObj; - - pNullContext = (struct rt_tx_context *)pUrb->context; - pAd = pNullContext->pAd; - Status = pUrb->status; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - pObj->null_frame_complete_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->null_frame_complete_task); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: MLME use BulkOutPipeId = 0 - - ======================================================================== -*/ -void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index) -{ - struct rt_tx_context *pMLMEContext; - PURB pUrb; - int ret = 0; - unsigned long IrqFlags; - - pMLMEContext = - (struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa; - pUrb = pMLMEContext->pUrb; - - if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) || - (pMLMEContext->InUse == FALSE) || - (pMLMEContext->bWaitingBulkOut == FALSE)) { - - /* Clear MLME bulk flag */ - RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - - return; - } - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - return; - } - - pAd->BulkOutPending[MGMTPIPEIDX] = TRUE; - pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1; - pMLMEContext->IRPPending = TRUE; - pMLMEContext->bWaitingBulkOut = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - - /* Increase Total transmit byte counter */ - pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; - - /* Clear MLME bulk flag */ - RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - - /* Init Tx context descriptor */ - RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, - (usb_complete_t) RTUSBBulkOutMLMEPacketComplete); - - /*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */ - pUrb->transfer_dma = 0; - pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); - - pUrb = pMLMEContext->pUrb; - ret = RTUSB_SUBMIT_URB(pUrb); - if (ret != 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", - ret)); - RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; - pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0; - pMLMEContext->IRPPending = FALSE; - pMLMEContext->bWaitingBulkOut = TRUE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - - return; - } - /*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */ -/* printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */ -} - -void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs) -{ - struct rt_tx_context *pMLMEContext; - struct rt_rtmp_adapter *pAd; - int Status; - struct os_cookie *pObj; - int index; - - /*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */ - pMLMEContext = (struct rt_tx_context *)pUrb->context; - pAd = pMLMEContext->pAd; - pObj = (struct os_cookie *)pAd->OS_Cookie; - Status = pUrb->status; - index = pMLMEContext->SelfIdx; - - pObj->mgmt_dma_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->mgmt_dma_done_task); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: PsPoll use BulkOutPipeId = 0 - - ======================================================================== -*/ -void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd) -{ - struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext); - PURB pUrb; - int ret = 0; - unsigned long IrqFlags; - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); - if ((pAd->BulkOutPending[0] == TRUE) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); - return; - } - pAd->BulkOutPending[0] = TRUE; - pAd->watchDogTxPendingCnt[0] = 1; - pPsPollContext->IRPPending = TRUE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); - - /* Clear PS-Poll bulk flag */ - RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); - - /* Init Tx context descriptor */ - RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, - (usb_complete_t) RTUSBBulkOutPsPollComplete); - - pUrb = pPsPollContext->pUrb; - ret = RTUSB_SUBMIT_URB(pUrb); - if (ret != 0) { - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); - pAd->BulkOutPending[0] = FALSE; - pAd->watchDogTxPendingCnt[0] = 0; - pPsPollContext->IRPPending = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); - - DBGPRINT(RT_DEBUG_ERROR, - ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", - ret)); - return; - } - -} - -/* PS-Poll frame use BulkOutPipeId = 0 */ -void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs) -{ - struct rt_rtmp_adapter *pAd; - struct rt_tx_context *pPsPollContext; - int Status; - struct os_cookie *pObj; - - pPsPollContext = (struct rt_tx_context *)pUrb->context; - pAd = pPsPollContext->pAd; - Status = pUrb->status; - - pObj = (struct os_cookie *)pAd->OS_Cookie; - pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->pspoll_frame_complete_task); -} - -void DoBulkIn(struct rt_rtmp_adapter *pAd) -{ - struct rt_rx_context *pRxContext; - PURB pUrb; - int ret = 0; - unsigned long IrqFlags; - - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); - if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) - || (pRxContext->InUse == TRUE)) { - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - return; - } - pRxContext->InUse = TRUE; - pRxContext->IRPPending = TRUE; - pAd->PendingRx++; - pAd->BulkInReq++; - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - - /* Init Rx context descriptor */ - NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset); - RTUSBInitRxDesc(pAd, pRxContext); - - pUrb = pRxContext->pUrb; - ret = RTUSB_SUBMIT_URB(pUrb); - if (ret != 0) { /* fail */ - - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pAd->PendingRx--; - pAd->BulkInReq--; - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - DBGPRINT(RT_DEBUG_ERROR, - ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret)); - } else { /* success */ - ASSERT((pRxContext->InUse == pRxContext->IRPPending)); - /*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */ - } -} - -/* - ======================================================================== - - Routine Description: - USB_RxPacket initializes a URB and uses the Rx IRP to submit it - to USB. It checks if an Rx Descriptor is available and passes the - the coresponding buffer to be filled. If no descriptor is available - fails the request. When setting the completion routine we pass our - Adapter Object as Context. - - Arguments: - - Return Value: - TRUE found matched tuple cache - FALSE no matched found - - Note: - - ======================================================================== -*/ -#define fRTMP_ADAPTER_NEED_STOP_RX \ - (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ - fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ - fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET) - -#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \ - (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ - fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \ - fRTMP_ADAPTER_REMOVE_IN_PROGRESS) - -void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd) -{ - struct rt_rx_context *pRxContext; - unsigned long IrqFlags; - - /* sanity check */ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX)) - return; - - while (1) { - - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]); - if (((pRxContext->InUse == FALSE) - && (pRxContext->Readable == TRUE)) - && (pRxContext->bRxHandling == FALSE)) { - pRxContext->bRxHandling = TRUE; - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - - /* read RxContext, Since not */ - STARxDoneInterruptHandle(pAd, TRUE); - - /* Finish to handle this bulkIn buffer. */ - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - pRxContext->BulkInOffset = 0; - pRxContext->Readable = FALSE; - pRxContext->bRxHandling = FALSE; - pAd->ReadPosition = 0; - pAd->TransferBufferLength = 0; - INC_RING_INDEX(pAd->NextRxBulkInReadIndex, - RX_RING_SIZE); - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - - } else { - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - break; - } - } - - if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX))) - DoBulkIn(pAd); - -} - -/* - ======================================================================== - - Routine Description: - This routine process Rx Irp and call rx complete function. - - Arguments: - DeviceObject Pointer to the device object for next lower - device. DeviceObject passed in here belongs to - the next lower driver in the stack because we - were invoked via IoCallDriver in USB_RxPacket - AND it is not OUR device object - Irp Ptr to completed IRP - Context Ptr to our Adapter object (context specified - in IoSetCompletionRoutine - - Return Value: - Always returns STATUS_MORE_PROCESSING_REQUIRED - - Note: - Always returns STATUS_MORE_PROCESSING_REQUIRED - ======================================================================== -*/ -void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs) -{ - /* use a receive tasklet to handle received packets; */ - /* or sometimes hardware IRQ will be disabled here, so we can not */ - /* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */ - struct rt_rx_context *pRxContext; - struct rt_rtmp_adapter *pAd; - struct os_cookie *pObj; - - pRxContext = (struct rt_rx_context *)pUrb->context; - pAd = pRxContext->pAd; - pObj = (struct os_cookie *)pAd->OS_Cookie; - - pObj->rx_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->rx_done_task); - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd) -{ - /* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX) - ) { - /* 2. PS-Poll frame is next */ - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) - RTUSBBulkOutPsPoll(pAd); - /* 5. Mlme frame is next */ - else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) || - (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) { - RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx); - } - /* 6. Data frame normal is next */ - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) { - if (((!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - || - (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - )) { - RTUSBBulkOutDataPacket(pAd, 0, - pAd-> - NextBulkOutIndex[0]); - } - } - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) { - if (((!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - || - (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - )) { - RTUSBBulkOutDataPacket(pAd, 1, - pAd-> - NextBulkOutIndex[1]); - } - } - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) { - if (((!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - || - (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - )) { - RTUSBBulkOutDataPacket(pAd, 2, - pAd-> - NextBulkOutIndex[2]); - } - } - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) { - if (((!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - || - (!OPSTATUS_TEST_FLAG - (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - )) { - RTUSBBulkOutDataPacket(pAd, 3, - pAd-> - NextBulkOutIndex[3]); - } - } - /* 7. Null frame is the last */ - else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) { - if (!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { - RTUSBBulkOutNullFrame(pAd); - } - } - /* 8. No data available */ - else - ; - } -} - -/* - ======================================================================== - - Routine Description: - Call from Reset action after BulkOut failed. - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd) -{ - u8 Idx; - struct rt_ht_tx_context *pTxContext; - - DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n")); - - for (Idx = 0; Idx < 4; Idx++) { - pTxContext = &pAd->TxContext[Idx]; - - pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition; - pTxContext->LastOne = FALSE; - NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); - pAd->BulkOutPending[Idx] = FALSE; - NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); - } - - DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd) -{ - DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n")); - DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd) -{ - RTUSBCancelPendingBulkInIRP(pAd); - RTUSBCancelPendingBulkOutIRP(pAd); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd) -{ - struct rt_rx_context *pRxContext; - u32 i; - - DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n")); - for (i = 0; i < (RX_RING_SIZE); i++) { - pRxContext = &(pAd->RxContext[i]); - if (pRxContext->IRPPending == TRUE) { - RTUSB_UNLINK_URB(pRxContext->pUrb); - pRxContext->IRPPending = FALSE; - pRxContext->InUse = FALSE; - /*NdisInterlockedDecrement(&pAd->PendingRx); */ - /*pAd->PendingRx--; */ - } - } - DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd) -{ - struct rt_ht_tx_context *pHTTXContext; - struct rt_tx_context *pMLMEContext; - struct rt_tx_context *pBeaconContext; - struct rt_tx_context *pNullContext; - struct rt_tx_context *pPsPollContext; - struct rt_tx_context *pRTSContext; - u32 i, Idx; -/* unsigned int IrqFlags; */ -/* spinlock_t *pLock; */ -/* BOOLEAN *pPending; */ - -/* pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */ -/* pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */ - - for (Idx = 0; Idx < 4; Idx++) { - pHTTXContext = &(pAd->TxContext[Idx]); - - if (pHTTXContext->IRPPending == TRUE) { - - /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ - /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ - /* when the last IRP on the list has been cancelled; that's how we exit this loop */ - /* */ - - RTUSB_UNLINK_URB(pHTTXContext->pUrb); - - /* Sleep 200 microseconds to give cancellation time to work */ - RTMPusecDelay(200); - } - - pAd->BulkOutPending[Idx] = FALSE; - } - - /*RTMP_IRQ_LOCK(pLock, IrqFlags); */ - for (i = 0; i < MGMT_RING_SIZE; i++) { - pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa; - if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) { - - /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ - /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ - /* when the last IRP on the list has been cancelled; that's how we exit this loop */ - /* */ - - RTUSB_UNLINK_URB(pMLMEContext->pUrb); - pMLMEContext->IRPPending = FALSE; - - /* Sleep 200 microsecs to give cancellation time to work */ - RTMPusecDelay(200); - } - } - pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; - /*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */ - - for (i = 0; i < BEACON_RING_SIZE; i++) { - pBeaconContext = &(pAd->BeaconContext[i]); - - if (pBeaconContext->IRPPending == TRUE) { - - /* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */ - /* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */ - /* when the last IRP on the list has been cancelled; that's how we exit this loop */ - /* */ - - RTUSB_UNLINK_URB(pBeaconContext->pUrb); - - /* Sleep 200 microsecs to give cancellation time to work */ - RTMPusecDelay(200); - } - } - - pNullContext = &(pAd->NullContext); - if (pNullContext->IRPPending == TRUE) - RTUSB_UNLINK_URB(pNullContext->pUrb); - - pRTSContext = &(pAd->RTSContext); - if (pRTSContext->IRPPending == TRUE) - RTUSB_UNLINK_URB(pRTSContext->pUrb); - - pPsPollContext = &(pAd->PsPollContext); - if (pPsPollContext->IRPPending == TRUE) - RTUSB_UNLINK_URB(pPsPollContext->pUrb); - - for (Idx = 0; Idx < 4; Idx++) { - NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]); - pAd->BulkOutPending[Idx] = FALSE; - NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]); - } -} - -#endif /* RTMP_MAC_USB // */ diff --git a/drivers/staging/rt2870/common/rtusb_data.c b/drivers/staging/rt2870/common/rtusb_data.c deleted file mode 100644 index 5b72bcdaa78f..000000000000 --- a/drivers/staging/rt2870/common/rtusb_data.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtusb_data.c - - Abstract: - Ralink USB driver Tx/Rx functions. - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Jan 03-25-2006 created - -*/ - -#ifdef RTMP_MAC_USB - -#include "../rt_config.h" - -extern u8 Phy11BGNextRateUpward[]; /* defined in mlme.c */ -extern u8 EpToQueue[]; - -void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd, - u8 *pData, unsigned long DataSize) -{ - void *pPacket; - u32 nMSDU; - struct sk_buff *pSkb; - - nMSDU = 0; - /* allocate a rx packet */ - pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE); - pPacket = (void *)OSPKT_TO_RTPKT(pSkb); - if (pSkb) { - - /* convert 802.11 to 802.3 packet */ - pSkb->dev = get_netdev_from_bssid(pAd, BSS0); - RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); - deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize); - } else { - DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n")); - } -} - -/* - ======================================================================== - - Routine Description: - This subroutine will scan through releative ring descriptor to find - out available free ring descriptor and compare with request size. - - Arguments: - pAd Pointer to our adapter - RingType Selected Ring - - Return Value: - NDIS_STATUS_FAILURE Not enough free descriptor - NDIS_STATUS_SUCCESS Enough free descriptor - - Note: - - ======================================================================== -*/ -int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd, - u8 BulkOutPipeId, - u32 NumberRequired) -{ -/* u8 FreeNumber = 0; */ -/* u32 Index; */ - int Status = NDIS_STATUS_FAILURE; - unsigned long IrqFlags; - struct rt_ht_tx_context *pHTTXContext; - - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) - && - ((pHTTXContext->CurWritePosition + NumberRequired + - LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)) { - - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << - BulkOutPipeId)); - } else if ((pHTTXContext->CurWritePosition == 8) - && (pHTTXContext->NextBulkOutPosition < - (NumberRequired + LOCAL_TXBUF_SIZE))) { - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << - BulkOutPipeId)); - } else if (pHTTXContext->bCurWriting == TRUE) { - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", - BulkOutPipeId, pHTTXContext->CurWritePosition, - pHTTXContext->NextBulkOutPosition)); - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL << - BulkOutPipeId)); - } else { - Status = NDIS_STATUS_SUCCESS; - } - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - - return Status; -} - -int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd, - u8 BulkOutPipeId) -{ - unsigned long IrqFlags; - struct rt_ht_tx_context *pHTTXContext; - - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - pHTTXContext->bCurWriting = FALSE; - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - - return NDIS_STATUS_SUCCESS; -} - -BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId) -{ - unsigned long IrqFlags; - struct rt_ht_tx_context *pHTTXContext; - BOOLEAN needQueBack = FALSE; - - pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - if ((pHTTXContext->IRPPending == - TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */) { - if ((pHTTXContext->CurWritePosition < - pHTTXContext->ENextBulkOutPosition) - && - (((pHTTXContext->ENextBulkOutPosition + - MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) - || (pHTTXContext->CurWritePosition > - MAX_AGGREGATION_SIZE))) { - needQueBack = TRUE; - } else - if ((pHTTXContext->CurWritePosition > - pHTTXContext->ENextBulkOutPosition) - && - ((pHTTXContext->ENextBulkOutPosition + - MAX_AGGREGATION_SIZE) < - pHTTXContext->CurWritePosition)) { - needQueBack = TRUE; - } - } - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - - return needQueBack; - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd) -{ - u8 Index; - struct rt_queue_entry *pEntry; - void *pPacket; - struct rt_queue_header *pQueue; - - for (Index = 0; Index < 4; Index++) { - NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); - while (pAd->TxSwQueue[Index].Head != NULL) { - pQueue = (struct rt_queue_header *)&(pAd->TxSwQueue[Index]); - pEntry = RemoveHeadQueue(pQueue); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } - NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]); - - } - -} - -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pTxD Pointer to transmit descriptor - Ack Setting for Ack requirement bit - Fragment Setting for Fragment bit - RetryMode Setting for retry mode - Ifs Setting for IFS gap - Rate Setting for transmit rate - Service Setting for service - Length Frame length - TxPreamble Short or Long preamble when using CCK rates - QueIdx - 0-3, according to 802.11e/d4.4 June/2003 - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ - -void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd, - struct rt_txinfo *pTxInfo, - u16 USBDMApktLen, - IN BOOLEAN bWiv, - u8 QueueSel, u8 NextValid, u8 TxBurst) -{ - pTxInfo->USBDMATxPktLen = USBDMApktLen; - pTxInfo->QSEL = QueueSel; - if (QueueSel != FIFO_EDCA) - DBGPRINT(RT_DEBUG_TRACE, - ("====> QueueSel != FIFO_EDCA<============\n")); - pTxInfo->USBDMANextVLD = FALSE; /*NextValid; // Need to check with Jan about this. */ - pTxInfo->USBDMATxburst = TxBurst; - pTxInfo->WIV = bWiv; - pTxInfo->SwUseLastRound = 0; - pTxInfo->rsv = 0; - pTxInfo->rsv2 = 0; -} - -#endif /* RTMP_MAC_USB // */ diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c deleted file mode 100644 index 7d2f7e05814d..000000000000 --- a/drivers/staging/rt2870/common/rtusb_io.c +++ /dev/null @@ -1,2104 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * 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. * - * * - ************************************************************************* - - Module Name: - rtusb_io.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Paul Lin 06-25-2004 created -*/ - -#ifdef RTMP_MAC_USB - -#include "../rt_config.h" - -/* - ======================================================================== - - Routine Description: NIC initialization complete - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ - -static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd) -{ - int Status; - - Status = RTUSB_VendorRequest(pAd, - USBD_TRANSFER_DIRECTION_OUT, - DEVICE_VENDOR_REQUEST_OUT, - 0x01, 0x8, 0, NULL, 0); - - return Status; -} - -/* - ======================================================================== - - Routine Description: Write Firmware to NIC. - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd, - const u8 *pFwImage, unsigned long FwLen) -{ - u32 MacReg; - int Status; -/* unsigned long i; */ - u16 writeLen; - - Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg); - - writeLen = FwLen; - RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen); - - Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff); - Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff); - Status = RTUSBFirmwareRun(pAd); - - /*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */ - RTMPusecDelay(10000); - RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CSR, 0); - AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00); /*reset rf by MCU supported by new firmware */ - /*2008/11/28:KH add to fix the dead rf frequency offset bug--> */ - - return Status; -} - -int RTUSBVenderReset(struct rt_rtmp_adapter *pAd) -{ - int Status; - DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n")); - Status = RTUSB_VendorRequest(pAd, - USBD_TRANSFER_DIRECTION_OUT, - DEVICE_VENDOR_REQUEST_OUT, - 0x01, 0x1, 0, NULL, 0); - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n")); - return Status; -} - -/* - ======================================================================== - - Routine Description: Read various length data from RT2573 - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBMultiRead(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length) -{ - int Status; - - Status = RTUSB_VendorRequest(pAd, - (USBD_TRANSFER_DIRECTION_IN | - USBD_SHORT_TRANSFER_OK), - DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset, - pData, length); - - return Status; -} - -/* - ======================================================================== - - Routine Description: Write various length data to RT2573 - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, - u16 Offset, const u8 *pData) -{ - int Status; - - /* TODO: In 2870, use this funciton carefully cause it's not stable. */ - Status = RTUSB_VendorRequest(pAd, - USBD_TRANSFER_DIRECTION_OUT, - DEVICE_VENDOR_REQUEST_OUT, - 0x6, 0, Offset, (u8 *)pData, 1); - - return Status; -} - -int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd, - u16 Offset, const u8 *pData, u16 length) -{ - int Status; - - u16 index = 0, Value; - const u8 *pSrc = pData; - u16 resude = 0; - - resude = length % 2; - length += resude; - do { - Value = (u16)(*pSrc | (*(pSrc + 1) << 8)); - Status = RTUSBSingleWrite(pAd, Offset + index, Value); - index += 2; - length -= 2; - pSrc = pSrc + 2; - } while (length > 0); - - return Status; -} - -int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd, - u16 Offset, u16 Value) -{ - int Status; - - Status = RTUSB_VendorRequest(pAd, - USBD_TRANSFER_DIRECTION_OUT, - DEVICE_VENDOR_REQUEST_OUT, - 0x2, Value, Offset, NULL, 0); - - return Status; - -} - -/* - ======================================================================== - - Routine Description: Read 32-bit MAC register - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd, - u16 Offset, u32 *pValue) -{ - int Status = 0; - u32 localVal; - - Status = RTUSB_VendorRequest(pAd, - (USBD_TRANSFER_DIRECTION_IN | - USBD_SHORT_TRANSFER_OK), - DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset, - &localVal, 4); - - *pValue = le2cpu32(localVal); - - if (Status < 0) - *pValue = 0xffffffff; - - return Status; -} - -/* - ======================================================================== - - Routine Description: Write 32-bit MAC register - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd, - u16 Offset, u32 Value) -{ - int Status; - u32 localVal; - - localVal = Value; - - Status = RTUSBSingleWrite(pAd, Offset, (u16)(localVal & 0xffff)); - Status = - RTUSBSingleWrite(pAd, Offset + 2, - (u16)((localVal & 0xffff0000) >> 16)); - - return Status; -} - -/* - ======================================================================== - - Routine Description: Read 8-bit BBP register - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd, - u8 Id, u8 *pValue) -{ - BBP_CSR_CFG_STRUC BbpCsr; - u32 i = 0; - int status; - - /* Verify the busy condition */ - do { - status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); - if (status >= 0) { - if (!(BbpCsr.field.Busy == BUSY)) - break; - } - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", - i)); - i++; - } while ((i < RETRY_LIMIT) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); - - if ((i == RETRY_LIMIT) - || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - /* */ - /* Read failed then Return Default value. */ - /* */ - *pValue = pAd->BbpWriteLatch[Id]; - - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Retry count exhausted or device removed!!!\n")); - return STATUS_UNSUCCESSFUL; - } - /* Prepare for write material */ - BbpCsr.word = 0; - BbpCsr.field.fRead = 1; - BbpCsr.field.Busy = 1; - BbpCsr.field.RegNum = Id; - RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); - - i = 0; - /* Verify the busy condition */ - do { - status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); - if (status >= 0) { - if (!(BbpCsr.field.Busy == BUSY)) { - *pValue = (u8)BbpCsr.field.Value; - break; - } - } - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", - i)); - i++; - } while ((i < RETRY_LIMIT) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); - - if ((i == RETRY_LIMIT) - || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - /* */ - /* Read failed then Return Default value. */ - /* */ - *pValue = pAd->BbpWriteLatch[Id]; - - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Retry count exhausted or device removed!!!\n")); - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: Write 8-bit BBP register - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd, - u8 Id, u8 Value) -{ - BBP_CSR_CFG_STRUC BbpCsr; - u32 i = 0; - int status; - /* Verify the busy condition */ - do { - status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); - if (status >= 0) { - if (!(BbpCsr.field.Busy == BUSY)) - break; - } - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", - i)); - i++; - } while ((i < RETRY_LIMIT) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); - - if ((i == RETRY_LIMIT) - || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Retry count exhausted or device removed!!!\n")); - return STATUS_UNSUCCESSFUL; - } - /* Prepare for write material */ - BbpCsr.word = 0; - BbpCsr.field.fRead = 0; - BbpCsr.field.Value = Value; - BbpCsr.field.Busy = 1; - BbpCsr.field.RegNum = Id; - RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); - - pAd->BbpWriteLatch[Id] = Value; - - return STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: Write RF register through MAC - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value) -{ - PHY_CSR4_STRUC PhyCsr4; - u32 i = 0; - int status; - - NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC)); - do { - status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word); - if (status >= 0) { - if (!(PhyCsr4.field.Busy)) - break; - } - DBGPRINT(RT_DEBUG_TRACE, - ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", - i)); - i++; - } while ((i < RETRY_LIMIT) - && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); - - if ((i == RETRY_LIMIT) - || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { - DBGPRINT_RAW(RT_DEBUG_ERROR, - ("Retry count exhausted or device removed!!!\n")); - return STATUS_UNSUCCESSFUL; - } - - RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value); - - return STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length) -{ - int Status = STATUS_SUCCESS; - - Status = RTUSB_VendorRequest(pAd, - (USBD_TRANSFER_DIRECTION_IN | - USBD_SHORT_TRANSFER_OK), - DEVICE_VENDOR_REQUEST_IN, 0x9, 0, Offset, - pData, length); - - return Status; -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd, - u16 Offset, u8 *pData, u16 length) -{ - int Status = STATUS_SUCCESS; - - Status = RTUSB_VendorRequest(pAd, - USBD_TRANSFER_DIRECTION_OUT, - DEVICE_VENDOR_REQUEST_OUT, - 0x8, 0, Offset, pData, length); - - return Status; -} - -int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd, - u16 offset, u16 *pData) -{ - int status; - u16 localData; - - status = RTUSBReadEEPROM(pAd, offset, (u8 *)(&localData), 2); - if (status == STATUS_SUCCESS) - *pData = le2cpu16(localData); - - return status; - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd) -{ - u32 value; - - /* Timeout 0x40 x 50us */ - value = (SLEEPCID << 16) + (OWNERMCU << 24) + (0x40 << 8) + 1; - RTUSBWriteMACRegister(pAd, 0x7010, value); - RTUSBWriteMACRegister(pAd, 0x404, 0x30); - /*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); */ - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value)); - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBWakeUp(struct rt_rtmp_adapter *pAd) -{ - int Status; - - Status = RTUSB_VendorRequest(pAd, - USBD_TRANSFER_DIRECTION_OUT, - DEVICE_VENDOR_REQUEST_OUT, - 0x01, 0x09, 0, NULL, 0); - - return Status; -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq) -{ - cmdq->head = NULL; - cmdq->tail = NULL; - cmdq->size = 0; - cmdq->CmdQState = RTMP_TASK_STAT_INITED; -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd, - IN NDIS_OID Oid, - IN BOOLEAN SetInformation, - void *pInformationBuffer, - u32 InformationBufferLength) -{ - int status; - struct rt_cmdqelmt *cmdqelmt = NULL; - struct rt_rtmp_os_task *pTask = &pAd->cmdQTask; - -#ifdef KTHREAD_SUPPORT - if (pTask->kthread_task == NULL) -#else - CHECK_PID_LEGALITY(pTask->taskPID) { - } - else -#endif - return NDIS_STATUS_RESOURCES; - - status = os_alloc_mem(pAd, (u8 **) (&cmdqelmt), sizeof(struct rt_cmdqelmt)); - if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) - return NDIS_STATUS_RESOURCES; - - cmdqelmt->buffer = NULL; - if (pInformationBuffer != NULL) { - status = - os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer, - InformationBufferLength); - if ((status != NDIS_STATUS_SUCCESS) - || (cmdqelmt->buffer == NULL)) { - kfree(cmdqelmt); - return NDIS_STATUS_RESOURCES; - } else { - NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, - InformationBufferLength); - cmdqelmt->bufferlength = InformationBufferLength; - } - } else - cmdqelmt->bufferlength = 0; - - cmdqelmt->command = Oid; - cmdqelmt->CmdFromNdis = TRUE; - if (SetInformation == TRUE) - cmdqelmt->SetOperation = TRUE; - else - cmdqelmt->SetOperation = FALSE; - - NdisAcquireSpinLock(&pAd->CmdQLock); - if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) { - EnqueueCmd((&pAd->CmdQ), cmdqelmt); - status = NDIS_STATUS_SUCCESS; - } else { - status = NDIS_STATUS_FAILURE; - } - NdisReleaseSpinLock(&pAd->CmdQLock); - - if (status == NDIS_STATUS_FAILURE) { - if (cmdqelmt->buffer) - os_free_mem(pAd, cmdqelmt->buffer); - os_free_mem(pAd, cmdqelmt); - } else - RTUSBCMDUp(pAd); - - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd, - IN NDIS_OID Oid, - void *pInformationBuffer, - u32 InformationBufferLength) -{ - int status; - struct rt_cmdqelmt *cmdqelmt = NULL; - - status = os_alloc_mem(pAd, (u8 **) & cmdqelmt, sizeof(struct rt_cmdqelmt)); - if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) - return NDIS_STATUS_RESOURCES; - NdisZeroMemory(cmdqelmt, sizeof(struct rt_cmdqelmt)); - - if (InformationBufferLength > 0) { - status = - os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer, - InformationBufferLength); - if ((status != NDIS_STATUS_SUCCESS) - || (cmdqelmt->buffer == NULL)) { - os_free_mem(pAd, cmdqelmt); - return NDIS_STATUS_RESOURCES; - } else { - NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, - InformationBufferLength); - cmdqelmt->bufferlength = InformationBufferLength; - } - } else { - cmdqelmt->buffer = NULL; - cmdqelmt->bufferlength = 0; - } - - cmdqelmt->command = Oid; - cmdqelmt->CmdFromNdis = FALSE; - - if (cmdqelmt != NULL) { - NdisAcquireSpinLock(&pAd->CmdQLock); - if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) { - EnqueueCmd((&pAd->CmdQ), cmdqelmt); - status = NDIS_STATUS_SUCCESS; - } else { - status = NDIS_STATUS_FAILURE; - } - NdisReleaseSpinLock(&pAd->CmdQLock); - - if (status == NDIS_STATUS_FAILURE) { - if (cmdqelmt->buffer) - os_free_mem(pAd, cmdqelmt->buffer); - os_free_mem(pAd, cmdqelmt); - } else - RTUSBCMDUp(pAd); - } - return NDIS_STATUS_SUCCESS; -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt) -{ - *pcmdqelmt = cmdq->head; - - if (*pcmdqelmt != NULL) { - cmdq->head = cmdq->head->next; - cmdq->size--; - if (cmdq->size == 0) - cmdq->tail = NULL; - } -} - -/* - ======================================================================== - usb_control_msg - Builds a control urb, sends it off and waits for completion - @dev: pointer to the usb device to send the message to - @pipe: endpoint "pipe" to send the message to - @request: USB message request value - @requesttype: USB message request type value - @value: USB message value - @index: USB message index value - @data: pointer to the data to send - @size: length in bytes of the data to send - @timeout: time in jiffies to wait for the message to complete before - timing out (if 0 the wait is forever) - Context: !in_interrupt () - - This function sends a simple control message to a specified endpoint - and waits for the message to complete, or timeout. - If successful, it returns the number of bytes transferred, otherwise a negative error number. - - Don't use this function from within an interrupt context, like a - bottom half handler. If you need an asynchronous message, or need to send - a message from within interrupt context, use usb_submit_urb() - If a thread in your driver uses this call, make sure your disconnect() - method can wait for it to complete. Since you don't have a handle on - the URB used, you can't cancel the request. - - Routine Description: - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd, - u32 TransferFlags, - u8 RequestType, - u8 Request, - u16 Value, - u16 Index, - void *TransferBuffer, - u32 TransferBufferLength) -{ - int ret = 0; - struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { - DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n")); - return -1; - } else if (in_interrupt()) { - DBGPRINT(RT_DEBUG_ERROR, - ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n", - Request, Value, Index)); - - return -1; - } else { -#define MAX_RETRY_COUNT 10 - - int retryCount = 0; - void *tmpBuf = TransferBuffer; - - ret = down_interruptible(&(pAd->UsbVendorReq_semaphore)); - if (pAd->UsbVendorReqBuf) { - ASSERT(TransferBufferLength < MAX_PARAM_BUFFER_SIZE); - - tmpBuf = (void *)pAd->UsbVendorReqBuf; - NdisZeroMemory(pAd->UsbVendorReqBuf, - TransferBufferLength); - - if (RequestType == DEVICE_VENDOR_REQUEST_OUT) - NdisMoveMemory(tmpBuf, TransferBuffer, - TransferBufferLength); - } - - do { - if (RequestType == DEVICE_VENDOR_REQUEST_OUT) - ret = - usb_control_msg(pObj->pUsb_Dev, - usb_sndctrlpipe(pObj-> - pUsb_Dev, - 0), Request, - RequestType, Value, Index, - tmpBuf, - TransferBufferLength, - CONTROL_TIMEOUT_JIFFIES); - else if (RequestType == DEVICE_VENDOR_REQUEST_IN) - ret = - usb_control_msg(pObj->pUsb_Dev, - usb_rcvctrlpipe(pObj-> - pUsb_Dev, - 0), Request, - RequestType, Value, Index, - tmpBuf, - TransferBufferLength, - CONTROL_TIMEOUT_JIFFIES); - else { - DBGPRINT(RT_DEBUG_ERROR, - ("vendor request direction is failed\n")); - ret = -1; - } - - retryCount++; - if (ret < 0) { - DBGPRINT(RT_DEBUG_OFF, ("#\n")); - RTMPusecDelay(5000); - } - } while ((ret < 0) && (retryCount < MAX_RETRY_COUNT)); - - if ((pAd->UsbVendorReqBuf) - && (RequestType == DEVICE_VENDOR_REQUEST_IN)) - NdisMoveMemory(TransferBuffer, tmpBuf, - TransferBufferLength); - up(&(pAd->UsbVendorReq_semaphore)); - - if (ret < 0) { - DBGPRINT(RT_DEBUG_ERROR, - ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n", - ret, TransferFlags, - (RequestType == - DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), - Request, Index)); - if (Request == 0x2) - DBGPRINT(RT_DEBUG_ERROR, - ("\tRequest Value=0x%04x!\n", Value)); - - if ((TransferBuffer != NULL) - && (TransferBufferLength > 0)) - hex_dump("Failed TransferBuffer value", - TransferBuffer, TransferBufferLength); - } - - } - - if (ret != -1) - return STATUS_SUCCESS; - else - return STATUS_UNSUCCESSFUL; -} - -/* - ======================================================================== - - Routine Description: - Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT - synchronously. Callers of this function must be running at - PASSIVE LEVEL. - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -int RTUSB_ResetDevice(struct rt_rtmp_adapter *pAd) -{ - int Status = TRUE; - - DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n")); - /*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); */ - return Status; -} - -void CMDHandler(struct rt_rtmp_adapter *pAd) -{ - struct rt_cmdqelmt *cmdqelmt; - u8 *pData; - int NdisStatus = NDIS_STATUS_SUCCESS; -/* unsigned long Now = 0; */ - int ntStatus; -/* unsigned long IrqFlags; */ - - while (pAd && pAd->CmdQ.size > 0) { - NdisStatus = NDIS_STATUS_SUCCESS; - - NdisAcquireSpinLock(&pAd->CmdQLock); - RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt); - NdisReleaseSpinLock(&pAd->CmdQLock); - - if (cmdqelmt == NULL) - break; - - pData = cmdqelmt->buffer; - - if (! - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { - switch (cmdqelmt->command) { - case CMDTHREAD_CHECK_GPIO: - { - u32 data; - - { - /* Read GPIO pin2 as Hardware controlled radio state */ - - RTUSBReadMACRegister(pAd, - GPIO_CTRL_CFG, - &data); - - if (data & 0x04) { - pAd->StaCfg.bHwRadio = - TRUE; - } else { - pAd->StaCfg.bHwRadio = - FALSE; - } - - if (pAd->StaCfg.bRadio != - (pAd->StaCfg.bHwRadio - && pAd->StaCfg.bSwRadio)) { - pAd->StaCfg.bRadio = - (pAd->StaCfg. - bHwRadio - && pAd->StaCfg. - bSwRadio); - if (pAd->StaCfg. - bRadio == TRUE) { - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("!!! Radio On !!!\n")); - - MlmeRadioOn - (pAd); - /* Update extra information */ - pAd->ExtraInfo = - EXTRA_INFO_CLEAR; - } else { - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("!!! Radio Off !!!\n")); - - MlmeRadioOff - (pAd); - /* Update extra information */ - pAd->ExtraInfo = - HW_RADIO_OFF; - } - } - } - } - break; - - case CMDTHREAD_QKERIODIC_EXECUT: - { - StaQuickResponeForRateUpExec(NULL, pAd, - NULL, - NULL); - } - break; - - case CMDTHREAD_RESET_BULK_OUT: - { - u32 MACValue; - u8 Index; - int ret = 0; - struct rt_ht_tx_context *pHTTXContext; -/* struct rt_rtmp_tx_ring *pTxRing; */ - unsigned long IrqFlags; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", - pAd->bulkResetPipeid)); - /* All transfers must be aborted or cancelled before attempting to reset the pipe. */ - /*RTUSBCancelPendingBulkOutIRP(pAd); */ - /* Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007 */ - Index = 0; - do { - RTUSBReadMACRegister(pAd, - TXRXQ_PCNT, - &MACValue); - if ((MACValue & 0xf00000 - /*0x800000 */) == 0) - break; - Index++; - RTMPusecDelay(10000); - } while (Index < 100); - MACValue = 0; - RTUSBReadMACRegister(pAd, USB_DMA_CFG, - &MACValue); - /* To prevent Read Register error, we 2nd check the validity. */ - if ((MACValue & 0xc00000) == 0) - RTUSBReadMACRegister(pAd, - USB_DMA_CFG, - &MACValue); - /* To prevent Read Register error, we 3rd check the validity. */ - if ((MACValue & 0xc00000) == 0) - RTUSBReadMACRegister(pAd, - USB_DMA_CFG, - &MACValue); - MACValue |= 0x80000; - RTUSBWriteMACRegister(pAd, USB_DMA_CFG, - MACValue); - - /* Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */ - RTMPusecDelay(1000); - - MACValue &= (~0x80000); - RTUSBWriteMACRegister(pAd, USB_DMA_CFG, - MACValue); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n")); - - /* Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */ - /*RTMPusecDelay(5000); */ - - if ((pAd-> - bulkResetPipeid & - BULKOUT_MGMT_RESET_FLAG) == - BULKOUT_MGMT_RESET_FLAG) { - RTMP_CLEAR_FLAG(pAd, - fRTMP_ADAPTER_BULKOUT_RESET); - if (pAd->MgmtRing.TxSwFreeIdx < - MGMT_RING_SIZE - /* pMLMEContext->bWaitingBulkOut == TRUE */ - ) { - RTUSB_SET_BULK_FLAG(pAd, - fRTUSB_BULK_OUT_MLME); - } - RTUSBKickBulkOut(pAd); - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("\tTX MGMT RECOVER Done!\n")); - } else { - pHTTXContext = - &(pAd-> - TxContext[pAd-> - bulkResetPipeid]); - /*NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */ - RTMP_INT_LOCK(&pAd-> - BulkOutLock[pAd-> - bulkResetPipeid], - IrqFlags); - if (pAd-> - BulkOutPending[pAd-> - bulkResetPipeid] - == FALSE) { - pAd-> - BulkOutPending[pAd-> - bulkResetPipeid] - = TRUE; - pHTTXContext-> - IRPPending = TRUE; - pAd-> - watchDogTxPendingCnt - [pAd-> - bulkResetPipeid] = - 1; - - /* no matter what, clean the flag */ - RTMP_CLEAR_FLAG(pAd, - fRTMP_ADAPTER_BULKOUT_RESET); - - /*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */ - RTMP_INT_UNLOCK(&pAd-> - BulkOutLock - [pAd-> - bulkResetPipeid], - IrqFlags); - { - RTUSBInitHTTxDesc - (pAd, - pHTTXContext, - pAd-> - bulkResetPipeid, - pHTTXContext-> - BulkOutSize, - (usb_complete_t) - RTUSBBulkOutDataPacketComplete); - - ret = RTUSB_SUBMIT_URB - (pHTTXContext-> - pUrb); - if (ret != 0) { - RTMP_INT_LOCK - (&pAd-> - BulkOutLock - [pAd-> - bulkResetPipeid], - IrqFlags); - pAd-> - BulkOutPending - [pAd-> - bulkResetPipeid] - = - FALSE; - pHTTXContext-> - IRPPending - = - FALSE; - pAd-> - watchDogTxPendingCnt - [pAd-> - bulkResetPipeid] - = 0; - RTMP_INT_UNLOCK - (&pAd-> - BulkOutLock - [pAd-> - bulkResetPipeid], - IrqFlags); - - DBGPRINT - (RT_DEBUG_ERROR, - ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", - ret)); - } else { - RTMP_IRQ_LOCK - (&pAd-> - BulkOutLock - [pAd-> - bulkResetPipeid], - IrqFlags); - DBGPRINT_RAW - (RT_DEBUG_TRACE, - ("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n", - pAd-> - bulkResetPipeid, - pHTTXContext-> - CurWritePosition, - pHTTXContext-> - NextBulkOutPosition, - pHTTXContext-> - ENextBulkOutPosition, - pHTTXContext-> - bCopySavePad, - pAd-> - BulkOutPending - [pAd-> - bulkResetPipeid])); - DBGPRINT_RAW - (RT_DEBUG_TRACE, - ("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", - pAd-> - BulkOutReq, - pAd-> - BulkOutComplete, - pAd-> - BulkOutCompleteOther)); - RTMP_IRQ_UNLOCK - (&pAd-> - BulkOutLock - [pAd-> - bulkResetPipeid], - IrqFlags); - DBGPRINT_RAW - (RT_DEBUG_TRACE, - ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", - pAd-> - bulkResetReq - [pAd-> - bulkResetPipeid], - pHTTXContext-> - pUrb-> - status)); - - } - } - } else { - /*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */ - /*RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); */ - - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", - pAd-> - bulkResetReq[pAd-> - bulkResetPipeid], - pAd-> - bulkResetPipeid)); - if (pAd-> - bulkResetPipeid == - 0) { - u8 - pendingContext - = 0; - struct rt_ht_tx_context * - pHTTXContext - = - (struct rt_ht_tx_context *) - (&pAd-> - TxContext - [pAd-> - bulkResetPipeid]); - struct rt_tx_context * - pMLMEContext - = - (struct rt_tx_context *) - (pAd-> - MgmtRing. - Cell[pAd-> - MgmtRing. - TxDmaIdx]. - AllocVa); - struct rt_tx_context * - pNULLContext - = - (struct rt_tx_context *) - (&pAd-> - PsPollContext); - struct rt_tx_context * - pPsPollContext - = - (struct rt_tx_context *) - (&pAd-> - NullContext); - - if (pHTTXContext->IRPPending) - pendingContext - |= - 1; - else if - (pMLMEContext-> - IRPPending) - pendingContext - |= - 2; - else if - (pNULLContext-> - IRPPending) - pendingContext - |= - 4; - else if - (pPsPollContext-> - IRPPending) - pendingContext - |= - 8; - else - pendingContext - = 0; - - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("\tTX Occupied by %d!\n", - pendingContext)); - } - /* no matter what, clean the flag */ - RTMP_CLEAR_FLAG(pAd, - fRTMP_ADAPTER_BULKOUT_RESET); - - RTMP_INT_UNLOCK(&pAd-> - BulkOutLock - [pAd-> - bulkResetPipeid], - IrqFlags); - - RTUSB_SET_BULK_FLAG(pAd, - (fRTUSB_BULK_OUT_DATA_NORMAL - << - pAd-> - bulkResetPipeid)); - } - - RTMPDeQueuePacket(pAd, FALSE, - NUM_OF_TX_RING, - MAX_TX_PROCESS); - /*RTUSBKickBulkOut(pAd); */ - } - - } - /* - // Don't cancel BULKIN. - while ((atomic_read(&pAd->PendingRx) > 0) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) - { - if (atomic_read(&pAd->PendingRx) > 0) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n")); - RTUSBCancelPendingBulkInIRP(pAd); - } - RTMPusecDelay(100000); - } - - if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) - { - u8 i; - RTUSBRxPacket(pAd); - pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index - pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer - for (i = 0; i < (RX_RING_SIZE); i++) - { - struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); - - pRxContext->pAd = pAd; - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pRxContext->Readable = FALSE; - pRxContext->ReorderInUse = FALSE; - - } - RTUSBBulkReceive(pAd); - DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n")); - } */ - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n")); - break; - - case CMDTHREAD_RESET_BULK_IN: - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n")); - - /* All transfers must be aborted or cancelled before attempting to reset the pipe. */ - { - u32 MACValue; - { - /*while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) */ - if ((pAd->PendingRx > 0) - && - (!RTMP_TEST_FLAG - (pAd, - fRTMP_ADAPTER_NIC_NOT_EXIST))) { - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("BulkIn IRP Pending!!!\n")); - RTUSBCancelPendingBulkInIRP - (pAd); - RTMPusecDelay(100000); - pAd->PendingRx = 0; - } - } - /* Wait 10ms before reading register. */ - RTMPusecDelay(10000); - ntStatus = - RTUSBReadMACRegister(pAd, MAC_CSR0, - &MACValue); - - if ((NT_SUCCESS(ntStatus) == TRUE) && - (!(RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_RESET_IN_PROGRESS - | fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_HALT_IN_PROGRESS - | - fRTMP_ADAPTER_NIC_NOT_EXIST))))) - { - u8 i; - - if (RTMP_TEST_FLAG - (pAd, - (fRTMP_ADAPTER_RESET_IN_PROGRESS - | fRTMP_ADAPTER_RADIO_OFF - | - fRTMP_ADAPTER_HALT_IN_PROGRESS - | - fRTMP_ADAPTER_NIC_NOT_EXIST))) - break; - pAd->NextRxBulkInPosition = - pAd->RxContext[pAd-> - NextRxBulkInIndex]. - BulkInOffset; - DBGPRINT(RT_DEBUG_TRACE, - ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n", - pAd-> - NextRxBulkInIndex, - pAd-> - NextRxBulkInReadIndex, - pAd-> - NextRxBulkInPosition, - pAd->BulkInReq, - pAd->BulkInComplete, - pAd-> - BulkInCompleteFail)); - for (i = 0; i < RX_RING_SIZE; - i++) { - DBGPRINT(RT_DEBUG_TRACE, - ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n", - i, - pAd-> - RxContext[i]. - IRPPending, - pAd-> - RxContext[i]. - InUse, - pAd-> - RxContext[i]. - Readable)); - } - /* - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n")); - - pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index - pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer - for (i = 0; i < (RX_RING_SIZE); i++) - { - struct rt_rx_context *pRxContext = &(pAd->RxContext[i]); - - pRxContext->pAd = pAd; - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pRxContext->Readable = FALSE; - pRxContext->ReorderInUse = FALSE; - - } */ - RTMP_CLEAR_FLAG(pAd, - fRTMP_ADAPTER_BULKIN_RESET); - for (i = 0; - i < - pAd->CommonCfg. - NumOfBulkInIRP; i++) { - /*RTUSBBulkReceive(pAd); */ - struct rt_rx_context *pRxContext; - PURB pUrb; - int ret = 0; - unsigned long IrqFlags; - - RTMP_IRQ_LOCK(&pAd-> - BulkInLock, - IrqFlags); - pRxContext = - &(pAd-> - RxContext[pAd-> - NextRxBulkInIndex]); - if ((pAd->PendingRx > 0) - || (pRxContext-> - Readable == - TRUE) - || (pRxContext-> - InUse == - TRUE)) { - RTMP_IRQ_UNLOCK - (&pAd-> - BulkInLock, - IrqFlags); - break; - } - pRxContext->InUse = - TRUE; - pRxContext->IRPPending = - TRUE; - pAd->PendingRx++; - pAd->BulkInReq++; - RTMP_IRQ_UNLOCK(&pAd-> - BulkInLock, - IrqFlags); - - /* Init Rx context descriptor */ - RTUSBInitRxDesc(pAd, - pRxContext); - pUrb = pRxContext->pUrb; - ret = RTUSB_SUBMIT_URB(pUrb); - if (ret != 0) { /* fail */ - - RTMP_IRQ_LOCK - (&pAd-> - BulkInLock, - IrqFlags); - pRxContext-> - InUse = - FALSE; - pRxContext-> - IRPPending = - FALSE; - pAd-> - PendingRx--; - pAd-> - BulkInReq--; - RTMP_IRQ_UNLOCK - (&pAd-> - BulkInLock, - IrqFlags); - DBGPRINT - (RT_DEBUG_ERROR, - ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", - ret, - pUrb-> - status)); - } else { /* success */ - /*DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", */ - /* pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); */ - DBGPRINT_RAW - (RT_DEBUG_TRACE, - ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", - pUrb-> - status)); - ASSERT((pRxContext->InUse == pRxContext->IRPPending)); - } - } - - } else { - /* Card must be removed */ - if (NT_SUCCESS(ntStatus) != - TRUE) { - RTMP_SET_FLAG(pAd, - fRTMP_ADAPTER_NIC_NOT_EXIST); - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n")); - } else { - DBGPRINT_RAW - (RT_DEBUG_ERROR, - ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", - pAd->Flags)); - } - } - } - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n")); - break; - - case CMDTHREAD_SET_ASIC_WCID: - { - struct rt_set_asic_wcid SetAsicWcid; - u16 offset; - u32 MACValue, MACRValue = 0; - SetAsicWcid = - *((struct rt_set_asic_wcid *)(pData)); - - if (SetAsicWcid.WCID >= - MAX_LEN_OF_MAC_TABLE) - return; - - offset = - MAC_WCID_BASE + - ((u8)SetAsicWcid.WCID) * - HW_WCID_ENTRY_SIZE; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", - SetAsicWcid.WCID, - SetAsicWcid.SetTid, - SetAsicWcid.DeleteTid)); - MACValue = - (pAd->MacTab. - Content[SetAsicWcid.WCID]. - Addr[3] << 24) + - (pAd->MacTab. - Content[SetAsicWcid.WCID]. - Addr[2] << 16) + - (pAd->MacTab. - Content[SetAsicWcid.WCID]. - Addr[1] << 8) + - (pAd->MacTab. - Content[SetAsicWcid.WCID].Addr[0]); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("1-MACValue= %x,\n", - MACValue)); - RTUSBWriteMACRegister(pAd, offset, - MACValue); - /* Read bitmask */ - RTUSBReadMACRegister(pAd, offset + 4, - &MACRValue); - if (SetAsicWcid.DeleteTid != 0xffffffff) - MACRValue &= - (~SetAsicWcid.DeleteTid); - if (SetAsicWcid.SetTid != 0xffffffff) - MACRValue |= - (SetAsicWcid.SetTid); - MACRValue &= 0xffff0000; - - MACValue = - (pAd->MacTab. - Content[SetAsicWcid.WCID]. - Addr[5] << 8) + - pAd->MacTab.Content[SetAsicWcid. - WCID].Addr[4]; - MACValue |= MACRValue; - RTUSBWriteMACRegister(pAd, offset + 4, - MACValue); - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("2-MACValue= %x,\n", - MACValue)); - } - break; - - case CMDTHREAD_SET_ASIC_WCID_CIPHER: - { - struct rt_set_asic_wcid_attri SetAsicWcidAttri; - u16 offset; - u32 MACRValue = 0; - SHAREDKEY_MODE_STRUC csr1; - SetAsicWcidAttri = - *((struct rt_set_asic_wcid_attri *) - (pData)); - - if (SetAsicWcidAttri.WCID >= - MAX_LEN_OF_MAC_TABLE) - return; - - offset = - MAC_WCID_ATTRIBUTE_BASE + - ((u8)SetAsicWcidAttri.WCID) * - HW_WCID_ATTRI_SIZE; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", - SetAsicWcidAttri.WCID, - SetAsicWcidAttri.Cipher)); - /* Read bitmask */ - RTUSBReadMACRegister(pAd, offset, - &MACRValue); - MACRValue = 0; - MACRValue |= - (((u8)SetAsicWcidAttri. - Cipher) << 1); - - RTUSBWriteMACRegister(pAd, offset, - MACRValue); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("2-offset = %x , MACValue= %x,\n", - offset, MACRValue)); - - offset = - PAIRWISE_IVEIV_TABLE_BASE + - ((u8)SetAsicWcidAttri.WCID) * - HW_IVEIV_ENTRY_SIZE; - MACRValue = 0; - if ((SetAsicWcidAttri.Cipher <= - CIPHER_WEP128)) - MACRValue |= - (pAd->StaCfg. - DefaultKeyId << 30); - else - MACRValue |= (0x20000000); - RTUSBWriteMACRegister(pAd, offset, - MACRValue); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("2-offset = %x , MACValue= %x,\n", - offset, MACRValue)); - - /* */ - /* Update cipher algorithm. WSTA always use BSS0 */ - /* */ - /* for adhoc mode only ,because wep status slow than add key, when use zero config */ - if (pAd->StaCfg.BssType == BSS_ADHOC) { - offset = - MAC_WCID_ATTRIBUTE_BASE; - - RTUSBReadMACRegister(pAd, - offset, - &MACRValue); - MACRValue &= (~0xe); - MACRValue |= - (((u8)SetAsicWcidAttri. - Cipher) << 1); - - RTUSBWriteMACRegister(pAd, - offset, - MACRValue); - - /*Update group key cipher,,because wep status slow than add key, when use zero config */ - RTUSBReadMACRegister(pAd, - SHARED_KEY_MODE_BASE - + - 4 * (0 / - 2), - &csr1. - word); - - csr1.field.Bss0Key0CipherAlg = - SetAsicWcidAttri.Cipher; - csr1.field.Bss0Key1CipherAlg = - SetAsicWcidAttri.Cipher; - - RTUSBWriteMACRegister(pAd, - SHARED_KEY_MODE_BASE - + - 4 * (0 / - 2), - csr1. - word); - } - } - break; - -/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 --> */ - case RT_CMD_SET_KEY_TABLE: /*General call for AsicAddPairwiseKeyEntry() */ - { - struct rt_add_pairwise_key_entry KeyInfo; - KeyInfo = - *((struct rt_add_pairwise_key_entry *) - (pData)); - AsicAddPairwiseKeyEntry(pAd, - KeyInfo.MacAddr, - (u8)KeyInfo. - MacTabMatchWCID, - &KeyInfo. - CipherKey); - } - break; - - case RT_CMD_SET_RX_WCID_TABLE: /*General call for RTMPAddWcidAttributeEntry() */ - { - struct rt_mac_table_entry *pEntry; - u8 KeyIdx = 0; - u8 CipherAlg = CIPHER_NONE; - u8 ApIdx = BSS0; - - pEntry = (struct rt_mac_table_entry *)(pData); - - RTMPAddWcidAttributeEntry(pAd, - ApIdx, - KeyIdx, - CipherAlg, - pEntry); - } - break; -/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 <-- */ - - case CMDTHREAD_SET_CLIENT_MAC_ENTRY: - { - struct rt_mac_table_entry *pEntry; - pEntry = (struct rt_mac_table_entry *)pData; - - { - AsicRemovePairwiseKeyEntry(pAd, - pEntry-> - apidx, - (u8) - pEntry-> - Aid); - if ((pEntry->AuthMode <= - Ndis802_11AuthModeAutoSwitch) - && (pEntry->WepStatus == - Ndis802_11Encryption1Enabled)) - { - u32 uIV = 1; - u8 *ptr; - - ptr = (u8 *)& uIV; - *(ptr + 3) = - (pAd->StaCfg. - DefaultKeyId << 6); - AsicUpdateWCIDIVEIV(pAd, - pEntry-> - Aid, - uIV, - 0); - AsicUpdateWCIDAttribute - (pAd, pEntry->Aid, - BSS0, - pAd-> - SharedKey[BSS0] - [pAd->StaCfg. - DefaultKeyId]. - CipherAlg, FALSE); - } else if (pEntry->AuthMode == - Ndis802_11AuthModeWPANone) - { - u32 uIV = 1; - u8 *ptr; - - ptr = (u8 *)& uIV; - *(ptr + 3) = - (pAd->StaCfg. - DefaultKeyId << 6); - AsicUpdateWCIDIVEIV(pAd, - pEntry-> - Aid, - uIV, - 0); - AsicUpdateWCIDAttribute - (pAd, pEntry->Aid, - BSS0, - pAd-> - SharedKey[BSS0] - [pAd->StaCfg. - DefaultKeyId]. - CipherAlg, FALSE); - } else { - /* */ - /* Other case, disable engine. */ - /* Don't worry WPA key, we will add WPA Key after 4-Way handshaking. */ - /* */ - u16 offset; - offset = - MAC_WCID_ATTRIBUTE_BASE - + - (pEntry->Aid * - HW_WCID_ATTRI_SIZE); - /* RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0 */ - RTUSBWriteMACRegister - (pAd, offset, 0); - } - } - - AsicUpdateRxWCIDTable(pAd, pEntry->Aid, - pEntry->Addr); - DBGPRINT(RT_DEBUG_TRACE, - ("UpdateRxWCIDTable(): Aid=%d, " - "Addr=%pM!\n", - pEntry->Aid, - pEntry->Addr)); - } - break; - -/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */ - case CMDTHREAD_UPDATE_PROTECT: - { - AsicUpdateProtect(pAd, 0, - (ALLN_SETPROTECT), - TRUE, 0); - } - break; -/* end johnli */ - - case OID_802_11_ADD_WEP: - { - u32 i; - u32 KeyIdx; - struct rt_ndis_802_11_wep *pWepKey; - - DBGPRINT(RT_DEBUG_TRACE, - ("CmdThread::OID_802_11_ADD_WEP \n")); - - pWepKey = (struct rt_ndis_802_11_wep *)pData; - KeyIdx = pWepKey->KeyIndex & 0x0fffffff; - - /* it is a shared key */ - if ((KeyIdx >= 4) - || ((pWepKey->KeyLength != 5) - && (pWepKey->KeyLength != - 13))) { - NdisStatus = - NDIS_STATUS_INVALID_DATA; - DBGPRINT(RT_DEBUG_ERROR, - ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n")); - } else { - u8 CipherAlg; - pAd->SharedKey[BSS0][KeyIdx]. - KeyLen = - (u8)pWepKey->KeyLength; - NdisMoveMemory(pAd-> - SharedKey[BSS0] - [KeyIdx].Key, - &pWepKey-> - KeyMaterial, - pWepKey-> - KeyLength); - CipherAlg = - (pAd-> - SharedKey[BSS0][KeyIdx]. - KeyLen == - 5) ? CIPHER_WEP64 : - CIPHER_WEP128; - - /* */ - /* Change the WEP cipher to CKIP cipher if CKIP KP on. */ - /* Funk UI or Meetinghouse UI will add ckip key from this path. */ - /* */ - - if (pAd->OpMode == OPMODE_STA) { - pAd->MacTab. - Content[BSSID_WCID]. - PairwiseKey. - CipherAlg = - pAd-> - SharedKey[BSS0] - [KeyIdx].CipherAlg; - pAd->MacTab. - Content[BSSID_WCID]. - PairwiseKey.KeyLen = - pAd-> - SharedKey[BSS0] - [KeyIdx].KeyLen; - } - pAd->SharedKey[BSS0][KeyIdx]. - CipherAlg = CipherAlg; - if (pWepKey-> - KeyIndex & 0x80000000) { - /* Default key for tx (shared key) */ - u8 IVEIV[8]; - u32 WCIDAttri, Value; - u16 offset, offset2; - NdisZeroMemory(IVEIV, - 8); - pAd->StaCfg. - DefaultKeyId = - (u8)KeyIdx; - /* Add BSSID to WCTable. because this is Tx wep key. */ - /* WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0 */ - WCIDAttri = - (CipherAlg << 1) | - SHAREDKEYTABLE; - - offset = - MAC_WCID_ATTRIBUTE_BASE - + - (BSSID_WCID * - HW_WCID_ATTRI_SIZE); - RTUSBWriteMACRegister - (pAd, offset, - WCIDAttri); - /* 1. IV/EIV */ - /* Specify key index to find shared key. */ - IVEIV[3] = (u8)(KeyIdx << 6); /*WEP Eiv bit off. groupkey index is not 0 */ - offset = - PAIRWISE_IVEIV_TABLE_BASE - + - (BSS0Mcast_WCID * - HW_IVEIV_ENTRY_SIZE); - offset2 = - PAIRWISE_IVEIV_TABLE_BASE - + - (BSSID_WCID * - HW_IVEIV_ENTRY_SIZE); - for (i = 0; i < 8;) { - Value = - IVEIV[i]; - Value += - (IVEIV - [i + - 1] << 8); - Value += - (IVEIV - [i + - 2] << 16); - Value += - (IVEIV - [i + - 3] << 24); - RTUSBWriteMACRegister - (pAd, - offset + i, - Value); - RTUSBWriteMACRegister - (pAd, - offset2 + - i, Value); - i += 4; - } - - /* 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0 */ - WCIDAttri = - (pAd-> - SharedKey[BSS0] - [KeyIdx]. - CipherAlg << 1) | - SHAREDKEYTABLE; - offset = - MAC_WCID_ATTRIBUTE_BASE - + - (BSS0Mcast_WCID * - HW_WCID_ATTRI_SIZE); - DBGPRINT(RT_DEBUG_TRACE, - ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", - offset, - WCIDAttri)); - RTUSBWriteMACRegister - (pAd, offset, - WCIDAttri); - - } - AsicAddSharedKeyEntry(pAd, BSS0, - (u8) - KeyIdx, - CipherAlg, - pWepKey-> - KeyMaterial, - NULL, - NULL); - DBGPRINT(RT_DEBUG_TRACE, - ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", - KeyIdx, - pWepKey->KeyLength)); - } - } - break; - - case CMDTHREAD_802_11_COUNTER_MEASURE: - break; - - case CMDTHREAD_SET_GROUP_KEY: - WpaStaGroupKeySetting(pAd); - break; - - case CMDTHREAD_SET_PAIRWISE_KEY: - WpaStaPairwiseKeySetting(pAd); - break; - - case CMDTHREAD_SET_PSM_BIT: - { - u16 *pPsm = (u16 *) pData; - MlmeSetPsmBit(pAd, *pPsm); - } - break; - case CMDTHREAD_FORCE_WAKE_UP: - AsicForceWakeup(pAd, TRUE); - break; - - default: - DBGPRINT(RT_DEBUG_ERROR, - ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", - cmdqelmt->command)); - break; - } - } - - if (cmdqelmt->CmdFromNdis == TRUE) { - if (cmdqelmt->buffer != NULL) - os_free_mem(pAd, cmdqelmt->buffer); - os_free_mem(pAd, cmdqelmt); - } else { - if ((cmdqelmt->buffer != NULL) - && (cmdqelmt->bufferlength != 0)) - os_free_mem(pAd, cmdqelmt->buffer); - os_free_mem(pAd, cmdqelmt); - } - } /* end of while */ -} - -#endif /* RTMP_MAC_USB // */ diff --git a/drivers/staging/rt2870/common/spectrum.c b/drivers/staging/rt2870/common/spectrum.c deleted file mode 100644 index 1cf2c263f452..000000000000 --- a/drivers/staging/rt2870/common/spectrum.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/common/spectrum.c" diff --git a/drivers/staging/rt2870/dfs.h b/drivers/staging/rt2870/dfs.h deleted file mode 100644 index 1fdbd7bc5de5..000000000000 --- a/drivers/staging/rt2870/dfs.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/dfs.h" diff --git a/drivers/staging/rt2870/md5.h b/drivers/staging/rt2870/md5.h deleted file mode 100644 index d60cd05b54f7..000000000000 --- a/drivers/staging/rt2870/md5.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/md5.h" diff --git a/drivers/staging/rt2870/mlme.h b/drivers/staging/rt2870/mlme.h deleted file mode 100644 index 58753ac441de..000000000000 --- a/drivers/staging/rt2870/mlme.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/mlme.h" diff --git a/drivers/staging/rt2870/oid.h b/drivers/staging/rt2870/oid.h deleted file mode 100644 index 1223d81bfc62..000000000000 --- a/drivers/staging/rt2870/oid.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/oid.h" diff --git a/drivers/staging/rt2870/rt28xx.h b/drivers/staging/rt2870/rt28xx.h deleted file mode 100644 index 29bad957de48..000000000000 --- a/drivers/staging/rt2870/rt28xx.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt28xx.h" diff --git a/drivers/staging/rt2870/rt_config.h b/drivers/staging/rt2870/rt_config.h deleted file mode 100644 index 1f6d6ed5630c..000000000000 --- a/drivers/staging/rt2870/rt_config.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt_config.h" diff --git a/drivers/staging/rt2870/rt_linux.c b/drivers/staging/rt2870/rt_linux.c deleted file mode 100644 index 88c697bf90eb..000000000000 --- a/drivers/staging/rt2870/rt_linux.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt_linux.c" diff --git a/drivers/staging/rt2870/rt_linux.h b/drivers/staging/rt2870/rt_linux.h deleted file mode 100644 index b2aeafbd5189..000000000000 --- a/drivers/staging/rt2870/rt_linux.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt_linux.h" diff --git a/drivers/staging/rt2870/rt_main_dev.c b/drivers/staging/rt2870/rt_main_dev.c deleted file mode 100644 index 121e1636017a..000000000000 --- a/drivers/staging/rt2870/rt_main_dev.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt_main_dev.c" diff --git a/drivers/staging/rt2870/rt_profile.c b/drivers/staging/rt2870/rt_profile.c deleted file mode 100644 index 15988c5d9df7..000000000000 --- a/drivers/staging/rt2870/rt_profile.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt_profile.c" diff --git a/drivers/staging/rt2870/rt_usb.c b/drivers/staging/rt2870/rt_usb.c deleted file mode 100644 index 5e02d4c88d73..000000000000 --- a/drivers/staging/rt2870/rt_usb.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rt_usb.c" diff --git a/drivers/staging/rt2870/rtmp.h b/drivers/staging/rt2870/rtmp.h deleted file mode 100644 index e5ef89f8bef1..000000000000 --- a/drivers/staging/rt2870/rtmp.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rtmp.h" diff --git a/drivers/staging/rt2870/rtmp_ckipmic.h b/drivers/staging/rt2870/rtmp_ckipmic.h deleted file mode 100644 index 0e7f1dfd4547..000000000000 --- a/drivers/staging/rt2870/rtmp_ckipmic.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rtmp_ckipmic.h" diff --git a/drivers/staging/rt2870/rtmp_def.h b/drivers/staging/rt2870/rtmp_def.h deleted file mode 100644 index 839d791b4f62..000000000000 --- a/drivers/staging/rt2870/rtmp_def.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rtmp_def.h" diff --git a/drivers/staging/rt2870/rtmp_type.h b/drivers/staging/rt2870/rtmp_type.h deleted file mode 100644 index fbf97d0fa5d3..000000000000 --- a/drivers/staging/rt2870/rtmp_type.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/rtmp_type.h" diff --git a/drivers/staging/rt2870/spectrum.h b/drivers/staging/rt2870/spectrum.h deleted file mode 100644 index 8aa23a1833b1..000000000000 --- a/drivers/staging/rt2870/spectrum.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/spectrum.h" diff --git a/drivers/staging/rt2870/spectrum_def.h b/drivers/staging/rt2870/spectrum_def.h deleted file mode 100644 index a65f551e3918..000000000000 --- a/drivers/staging/rt2870/spectrum_def.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/spectrum_def.h" diff --git a/drivers/staging/rt2870/sta/aironet.c b/drivers/staging/rt2870/sta/aironet.c deleted file mode 100644 index 72b7f2e6bf7f..000000000000 --- a/drivers/staging/rt2870/sta/aironet.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/aironet.c" diff --git a/drivers/staging/rt2870/sta/assoc.c b/drivers/staging/rt2870/sta/assoc.c deleted file mode 100644 index 46564d7a01a9..000000000000 --- a/drivers/staging/rt2870/sta/assoc.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/assoc.c" diff --git a/drivers/staging/rt2870/sta/auth.c b/drivers/staging/rt2870/sta/auth.c deleted file mode 100644 index 57632f9ec784..000000000000 --- a/drivers/staging/rt2870/sta/auth.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/auth.c" diff --git a/drivers/staging/rt2870/sta/auth_rsp.c b/drivers/staging/rt2870/sta/auth_rsp.c deleted file mode 100644 index 783e266d3e8f..000000000000 --- a/drivers/staging/rt2870/sta/auth_rsp.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/auth_rsp.c" diff --git a/drivers/staging/rt2870/sta/connect.c b/drivers/staging/rt2870/sta/connect.c deleted file mode 100644 index f6c7bbf542dc..000000000000 --- a/drivers/staging/rt2870/sta/connect.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/connect.c" diff --git a/drivers/staging/rt2870/sta/rtmp_data.c b/drivers/staging/rt2870/sta/rtmp_data.c deleted file mode 100644 index b67e06952bcf..000000000000 --- a/drivers/staging/rt2870/sta/rtmp_data.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/rtmp_data.c" diff --git a/drivers/staging/rt2870/sta/sanity.c b/drivers/staging/rt2870/sta/sanity.c deleted file mode 100644 index f1f2333bb993..000000000000 --- a/drivers/staging/rt2870/sta/sanity.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/sanity.c" diff --git a/drivers/staging/rt2870/sta/sync.c b/drivers/staging/rt2870/sta/sync.c deleted file mode 100644 index 66c8772ad346..000000000000 --- a/drivers/staging/rt2870/sta/sync.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/sync.c" diff --git a/drivers/staging/rt2870/sta/wpa.c b/drivers/staging/rt2870/sta/wpa.c deleted file mode 100644 index 57a2eb2d0896..000000000000 --- a/drivers/staging/rt2870/sta/wpa.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../rt2860/sta/wpa.c" diff --git a/drivers/staging/rt2870/sta_ioctl.c b/drivers/staging/rt2870/sta_ioctl.c deleted file mode 100644 index 3553a6c898b9..000000000000 --- a/drivers/staging/rt2870/sta_ioctl.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/sta_ioctl.c" diff --git a/drivers/staging/rt2870/usb_main_dev.c b/drivers/staging/rt2870/usb_main_dev.c deleted file mode 100644 index 6e63bc50047a..000000000000 --- a/drivers/staging/rt2870/usb_main_dev.c +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/usb_main_dev.c" diff --git a/drivers/staging/rt2870/wpa.h b/drivers/staging/rt2870/wpa.h deleted file mode 100644 index 712507224146..000000000000 --- a/drivers/staging/rt2870/wpa.h +++ /dev/null @@ -1 +0,0 @@ -#include "../rt2860/wpa.h" -- GitLab From 52ba67bf85889828b3766207fa43ce7159c84c78 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Apr 2011 21:05:11 +0900 Subject: [PATCH 0669/5560] ASoC: Force all DAPM contexts into the same bias state Currently we allow all DAPM contexts to determine their own bias level. While this should in general work in most situations and will deliver the lowest possible power it causes problems for our integration with the card bias level as we're calling the card bias level functions for each DAPM context even though they're card wide but don't say which CODEC we're calling them for. Mitigate against this by forcing everything to be in the same state. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 567645c0308b..68879209b315 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1101,6 +1101,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) } } + /* Force all contexts in the card to the same bias state */ + power = 0; + list_for_each_entry(d, &card->dapm_list, list) + if (d->dev_power) + power = 1; + list_for_each_entry(d, &card->dapm_list, list) + d->dev_power = power; + + /* Run all the bias changes in parallel */ list_for_each_entry(d, &dapm->card->dapm_list, list) async_schedule_domain(dapm_pre_sequence_async, d, -- GitLab From 0d86733cce776ca0262b850ee8eb46bc52dc8244 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 6 Apr 2011 11:38:14 +0900 Subject: [PATCH 0670/5560] ASoC: Allow DAPM pin operations to match any context The DAPM pin operations currently require that the specific DAPM context that the pin being operated in is contained in be specified. With multi component and especially with the addition of a per-card DAPM context this isn't ideal as it means that things like disabling unused pins on CODECs require looking up the CODEC DAPM context. Fix this by falling back to matching a widget in any context if there isn't a match in the current context. The code isn't ideal currently but will do the job. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 68879209b315..2ee738c08ca4 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1477,6 +1477,19 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, } } + /* Try again in other contexts */ + list_for_each_entry(w, &dapm->card->widgets, list) { + if (!strcmp(w->name, pin)) { + dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", + pin, status); + w->connected = status; + /* Allow disabling of forced pins */ + if (status == 0) + w->force = 0; + return 0; + } + } + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } @@ -2317,6 +2330,17 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, } } + /* Try again with other contexts */ + list_for_each_entry(w, &dapm->card->widgets, list) { + if (!strcmp(w->name, pin)) { + dev_dbg(w->dapm->dev, + "dapm: force enable pin %s\n", pin); + w->connected = 1; + w->force = 1; + return 0; + } + } + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } -- GitLab From 1d1dbf8135ab2f3603cc72e39e0f68784f453c39 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 6 Mar 2011 18:02:21 +0100 Subject: [PATCH 0671/5560] exec: introduce get_user_arg_ptr() helper Introduce get_user_arg_ptr() helper, convert count() and copy_strings() to use it. No functional changes, preparation. This helper is trivial, it just reads the pointer from argv/envp user-space array. Signed-off-by: Oleg Nesterov Reviewed-by: KOSAKI Motohiro Tested-by: KOSAKI Motohiro --- fs/exec.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 5e62d26a4fec..b12e24fe1c5e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -398,6 +398,17 @@ int bprm_mm_init(struct linux_binprm *bprm) return err; } +static const char __user * +get_user_arg_ptr(const char __user * const __user *argv, int nr) +{ + const char __user *ptr; + + if (get_user(ptr, argv + nr)) + return ERR_PTR(-EFAULT); + + return ptr; +} + /* * count() counts the number of strings in array ARGV. */ @@ -407,13 +418,14 @@ static int count(const char __user * const __user * argv, int max) if (argv != NULL) { for (;;) { - const char __user * p; + const char __user *p = get_user_arg_ptr(argv, i); - if (get_user(p, argv)) - return -EFAULT; if (!p) break; - argv++; + + if (IS_ERR(p)) + return -EFAULT; + if (i++ >= max) return -E2BIG; @@ -443,16 +455,18 @@ static int copy_strings(int argc, const char __user *const __user *argv, int len; unsigned long pos; - if (get_user(str, argv+argc) || - !(len = strnlen_user(str, MAX_ARG_STRLEN))) { - ret = -EFAULT; + ret = -EFAULT; + str = get_user_arg_ptr(argv, argc); + if (IS_ERR(str)) goto out; - } - if (!valid_arg_len(bprm, len)) { - ret = -E2BIG; + len = strnlen_user(str, MAX_ARG_STRLEN); + if (!len) + goto out; + + ret = -E2BIG; + if (!valid_arg_len(bprm, len)) goto out; - } /* We're going to work our way backwords. */ pos = bprm->p; -- GitLab From ba2d01629d0d167598cfea85adc7926822bbfc45 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 6 Mar 2011 18:02:37 +0100 Subject: [PATCH 0672/5560] exec: introduce struct user_arg_ptr No functional changes, preparation. Introduce struct user_arg_ptr, change do_execve() paths to use it instead of "char __user * const __user *argv". This makes the argv/envp arguments opaque, we are ready to handle the compat case which needs argv pointing to compat_uptr_t. Suggested-by: Linus Torvalds Signed-off-by: Oleg Nesterov Reviewed-by: KOSAKI Motohiro Tested-by: KOSAKI Motohiro --- fs/exec.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index b12e24fe1c5e..526a0399d963 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -398,12 +398,15 @@ int bprm_mm_init(struct linux_binprm *bprm) return err; } -static const char __user * -get_user_arg_ptr(const char __user * const __user *argv, int nr) +struct user_arg_ptr { + const char __user *const __user *native; +}; + +static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) { const char __user *ptr; - if (get_user(ptr, argv + nr)) + if (get_user(ptr, argv.native + nr)) return ERR_PTR(-EFAULT); return ptr; @@ -412,11 +415,11 @@ get_user_arg_ptr(const char __user * const __user *argv, int nr) /* * count() counts the number of strings in array ARGV. */ -static int count(const char __user * const __user * argv, int max) +static int count(struct user_arg_ptr argv, int max) { int i = 0; - if (argv != NULL) { + if (argv.native != NULL) { for (;;) { const char __user *p = get_user_arg_ptr(argv, i); @@ -442,7 +445,7 @@ static int count(const char __user * const __user * argv, int max) * processes's memory to the new process's stack. The call to get_user_pages() * ensures the destination page is created and not swapped out. */ -static int copy_strings(int argc, const char __user *const __user *argv, +static int copy_strings(int argc, struct user_arg_ptr argv, struct linux_binprm *bprm) { struct page *kmapped_page = NULL; @@ -533,14 +536,19 @@ static int copy_strings(int argc, const char __user *const __user *argv, /* * Like copy_strings, but get argv and its values from kernel memory. */ -int copy_strings_kernel(int argc, const char *const *argv, +int copy_strings_kernel(int argc, const char *const *__argv, struct linux_binprm *bprm) { int r; mm_segment_t oldfs = get_fs(); + struct user_arg_ptr argv = { + .native = (const char __user *const __user *)__argv, + }; + set_fs(KERNEL_DS); - r = copy_strings(argc, (const char __user *const __user *)argv, bprm); + r = copy_strings(argc, argv, bprm); set_fs(oldfs); + return r; } EXPORT_SYMBOL(copy_strings_kernel); @@ -1393,10 +1401,10 @@ EXPORT_SYMBOL(search_binary_handler); /* * sys_execve() executes a new program. */ -int do_execve(const char * filename, - const char __user *const __user *argv, - const char __user *const __user *envp, - struct pt_regs * regs) +static int do_execve_common(const char *filename, + struct user_arg_ptr argv, + struct user_arg_ptr envp, + struct pt_regs *regs) { struct linux_binprm *bprm; struct file *file; @@ -1503,6 +1511,16 @@ int do_execve(const char * filename, return retval; } +int do_execve(const char *filename, + const char __user *const __user *__argv, + const char __user *const __user *__envp, + struct pt_regs *regs) +{ + struct user_arg_ptr argv = { .native = __argv }; + struct user_arg_ptr envp = { .native = __envp }; + return do_execve_common(filename, argv, envp, regs); +} + void set_binfmt(struct linux_binfmt *new) { struct mm_struct *mm = current->mm; -- GitLab From 0e028465d18b7c6797fcbdea632299d16097c5cd Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 6 Mar 2011 18:02:54 +0100 Subject: [PATCH 0673/5560] exec: unify do_execve/compat_do_execve code Add the appropriate members into struct user_arg_ptr and teach get_user_arg_ptr() to handle is_compat = T case correctly. This allows us to remove the compat_do_execve() code from fs/compat.c and reimplement compat_do_execve() as the trivial wrapper on top of do_execve_common(is_compat => true). In fact, this fixes another (minor) bug. "compat_uptr_t str" can overflow after "str += len" in compat_copy_strings() if a 64bit application execs via sys32_execve(). Unexport acct_arg_size() and get_arg_page(), fs/compat.c doesn't need them any longer. Signed-off-by: Oleg Nesterov Reviewed-by: KOSAKI Motohiro Tested-by: KOSAKI Motohiro --- fs/compat.c | 235 ---------------------------------------- fs/exec.c | 62 +++++++++-- include/linux/binfmts.h | 4 - 3 files changed, 50 insertions(+), 251 deletions(-) diff --git a/fs/compat.c b/fs/compat.c index 72fe6cda9108..0ea00832de23 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1306,241 +1306,6 @@ compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int return do_sys_open(dfd, filename, flags, mode); } -/* - * compat_count() counts the number of arguments/envelopes. It is basically - * a copy of count() from fs/exec.c, except that it works with 32 bit argv - * and envp pointers. - */ -static int compat_count(compat_uptr_t __user *argv, int max) -{ - int i = 0; - - if (argv != NULL) { - for (;;) { - compat_uptr_t p; - - if (get_user(p, argv)) - return -EFAULT; - if (!p) - break; - argv++; - if (i++ >= max) - return -E2BIG; - - if (fatal_signal_pending(current)) - return -ERESTARTNOHAND; - cond_resched(); - } - } - return i; -} - -/* - * compat_copy_strings() is basically a copy of copy_strings() from fs/exec.c - * except that it works with 32 bit argv and envp pointers. - */ -static int compat_copy_strings(int argc, compat_uptr_t __user *argv, - struct linux_binprm *bprm) -{ - struct page *kmapped_page = NULL; - char *kaddr = NULL; - unsigned long kpos = 0; - int ret; - - while (argc-- > 0) { - compat_uptr_t str; - int len; - unsigned long pos; - - if (get_user(str, argv+argc) || - !(len = strnlen_user(compat_ptr(str), MAX_ARG_STRLEN))) { - ret = -EFAULT; - goto out; - } - - if (len > MAX_ARG_STRLEN) { - ret = -E2BIG; - goto out; - } - - /* We're going to work our way backwords. */ - pos = bprm->p; - str += len; - bprm->p -= len; - - while (len > 0) { - int offset, bytes_to_copy; - - if (fatal_signal_pending(current)) { - ret = -ERESTARTNOHAND; - goto out; - } - cond_resched(); - - offset = pos % PAGE_SIZE; - if (offset == 0) - offset = PAGE_SIZE; - - bytes_to_copy = offset; - if (bytes_to_copy > len) - bytes_to_copy = len; - - offset -= bytes_to_copy; - pos -= bytes_to_copy; - str -= bytes_to_copy; - len -= bytes_to_copy; - - if (!kmapped_page || kpos != (pos & PAGE_MASK)) { - struct page *page; - - page = get_arg_page(bprm, pos, 1); - if (!page) { - ret = -E2BIG; - goto out; - } - - if (kmapped_page) { - flush_kernel_dcache_page(kmapped_page); - kunmap(kmapped_page); - put_page(kmapped_page); - } - kmapped_page = page; - kaddr = kmap(kmapped_page); - kpos = pos & PAGE_MASK; - flush_cache_page(bprm->vma, kpos, - page_to_pfn(kmapped_page)); - } - if (copy_from_user(kaddr+offset, compat_ptr(str), - bytes_to_copy)) { - ret = -EFAULT; - goto out; - } - } - } - ret = 0; -out: - if (kmapped_page) { - flush_kernel_dcache_page(kmapped_page); - kunmap(kmapped_page); - put_page(kmapped_page); - } - return ret; -} - -/* - * compat_do_execve() is mostly a copy of do_execve(), with the exception - * that it processes 32 bit argv and envp pointers. - */ -int compat_do_execve(char * filename, - compat_uptr_t __user *argv, - compat_uptr_t __user *envp, - struct pt_regs * regs) -{ - struct linux_binprm *bprm; - struct file *file; - struct files_struct *displaced; - bool clear_in_exec; - int retval; - - retval = unshare_files(&displaced); - if (retval) - goto out_ret; - - retval = -ENOMEM; - bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); - if (!bprm) - goto out_files; - - retval = prepare_bprm_creds(bprm); - if (retval) - goto out_free; - - retval = check_unsafe_exec(bprm); - if (retval < 0) - goto out_free; - clear_in_exec = retval; - current->in_execve = 1; - - file = open_exec(filename); - retval = PTR_ERR(file); - if (IS_ERR(file)) - goto out_unmark; - - sched_exec(); - - bprm->file = file; - bprm->filename = filename; - bprm->interp = filename; - - retval = bprm_mm_init(bprm); - if (retval) - goto out_file; - - bprm->argc = compat_count(argv, MAX_ARG_STRINGS); - if ((retval = bprm->argc) < 0) - goto out; - - bprm->envc = compat_count(envp, MAX_ARG_STRINGS); - if ((retval = bprm->envc) < 0) - goto out; - - retval = prepare_binprm(bprm); - if (retval < 0) - goto out; - - retval = copy_strings_kernel(1, &bprm->filename, bprm); - if (retval < 0) - goto out; - - bprm->exec = bprm->p; - retval = compat_copy_strings(bprm->envc, envp, bprm); - if (retval < 0) - goto out; - - retval = compat_copy_strings(bprm->argc, argv, bprm); - if (retval < 0) - goto out; - - retval = search_binary_handler(bprm, regs); - if (retval < 0) - goto out; - - /* execve succeeded */ - current->fs->in_exec = 0; - current->in_execve = 0; - acct_update_integrals(current); - free_bprm(bprm); - if (displaced) - put_files_struct(displaced); - return retval; - -out: - if (bprm->mm) { - acct_arg_size(bprm, 0); - mmput(bprm->mm); - } - -out_file: - if (bprm->file) { - allow_write_access(bprm->file); - fput(bprm->file); - } - -out_unmark: - if (clear_in_exec) - current->fs->in_exec = 0; - current->in_execve = 0; - -out_free: - free_bprm(bprm); - -out_files: - if (displaced) - reset_files_struct(displaced); -out_ret: - return retval; -} - #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) static int poll_select_copy_remaining(struct timespec *end_time, void __user *p, diff --git a/fs/exec.c b/fs/exec.c index 526a0399d963..89d788ca7829 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -167,7 +168,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) #ifdef CONFIG_MMU -void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) +static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) { struct mm_struct *mm = current->mm; long diff = (long)(pages - bprm->vma_pages); @@ -186,7 +187,7 @@ void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) #endif } -struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, +static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { struct page *page; @@ -305,11 +306,11 @@ static bool valid_arg_len(struct linux_binprm *bprm, long len) #else -void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) +static inline void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) { } -struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, +static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { struct page *page; @@ -399,17 +400,36 @@ int bprm_mm_init(struct linux_binprm *bprm) } struct user_arg_ptr { - const char __user *const __user *native; +#ifdef CONFIG_COMPAT + bool is_compat; +#endif + union { + const char __user *const __user *native; +#ifdef CONFIG_COMPAT + compat_uptr_t __user *compat; +#endif + } ptr; }; static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr) { - const char __user *ptr; + const char __user *native; + +#ifdef CONFIG_COMPAT + if (unlikely(argv.is_compat)) { + compat_uptr_t compat; + + if (get_user(compat, argv.ptr.compat + nr)) + return ERR_PTR(-EFAULT); - if (get_user(ptr, argv.native + nr)) + return compat_ptr(compat); + } +#endif + + if (get_user(native, argv.ptr.native + nr)) return ERR_PTR(-EFAULT); - return ptr; + return native; } /* @@ -419,7 +439,7 @@ static int count(struct user_arg_ptr argv, int max) { int i = 0; - if (argv.native != NULL) { + if (argv.ptr.native != NULL) { for (;;) { const char __user *p = get_user_arg_ptr(argv, i); @@ -542,7 +562,7 @@ int copy_strings_kernel(int argc, const char *const *__argv, int r; mm_segment_t oldfs = get_fs(); struct user_arg_ptr argv = { - .native = (const char __user *const __user *)__argv, + .ptr.native = (const char __user *const __user *)__argv, }; set_fs(KERNEL_DS); @@ -1516,10 +1536,28 @@ int do_execve(const char *filename, const char __user *const __user *__envp, struct pt_regs *regs) { - struct user_arg_ptr argv = { .native = __argv }; - struct user_arg_ptr envp = { .native = __envp }; + struct user_arg_ptr argv = { .ptr.native = __argv }; + struct user_arg_ptr envp = { .ptr.native = __envp }; + return do_execve_common(filename, argv, envp, regs); +} + +#ifdef CONFIG_COMPAT +int compat_do_execve(char *filename, + compat_uptr_t __user *__argv, + compat_uptr_t __user *__envp, + struct pt_regs *regs) +{ + struct user_arg_ptr argv = { + .is_compat = true, + .ptr.compat = __argv, + }; + struct user_arg_ptr envp = { + .is_compat = true, + .ptr.compat = __envp, + }; return do_execve_common(filename, argv, envp, regs); } +#endif void set_binfmt(struct linux_binfmt *new) { diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c3d6512eded1..8845613fd7e3 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -60,10 +60,6 @@ struct linux_binprm { unsigned long loader, exec; }; -extern void acct_arg_size(struct linux_binprm *bprm, unsigned long pages); -extern struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, - int write); - #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) -- GitLab From ae6b585eeb74670a2dec1fe4394bdfbdb9395cc2 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 6 Mar 2011 18:03:11 +0100 Subject: [PATCH 0674/5560] exec: document acct_arg_size() Add the comment to explain acct_arg_size(). Signed-off-by: Oleg Nesterov Reviewed-by: KOSAKI Motohiro --- fs/exec.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/exec.c b/fs/exec.c index 89d788ca7829..5cb53f0232b1 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -167,7 +167,12 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) } #ifdef CONFIG_MMU - +/* + * The nascent bprm->mm is not visible until exec_mmap() but it can + * use a lot of memory, account these pages in current->mm temporary + * for oom_badness()->get_mm_rss(). Once exec succeeds or fails, we + * change the counter back via acct_arg_size(0). + */ static void acct_arg_size(struct linux_binprm *bprm, unsigned long pages) { struct mm_struct *mm = current->mm; -- GitLab From cdb650a4b5eaf1c0aedbfd7dd6afd6d465c3b0a0 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 27 Feb 2011 01:34:08 +0100 Subject: [PATCH 0675/5560] drm: minor kref_put() nits There's no need to pass kref_put() the address of a function (just the function will do just fine) nor to cast its unused return to void. Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/gpu/drm/radeon/radeon_fence.c | 2 +- drivers/gpu/drm/ttm/ttm_object.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 9e59868d354e..ab83472553c6 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -322,7 +322,7 @@ void radeon_fence_unref(struct radeon_fence **fence) *fence = NULL; if (tmp) { - kref_put(&tmp->kref, &radeon_fence_destroy); + kref_put(&tmp->kref, radeon_fence_destroy); } } diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index 75e9d6f86ba4..ebddd443d91a 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c @@ -206,7 +206,7 @@ void ttm_base_object_unref(struct ttm_base_object **p_base) */ write_lock(&tdev->object_lock); - (void)kref_put(&base->refcount, &ttm_release_base); + kref_put(&base->refcount, ttm_release_base); write_unlock(&tdev->object_lock); } EXPORT_SYMBOL(ttm_base_object_unref); -- GitLab From 8620d81fadc0747f567909aa7ae2eeb7135a64e9 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 15 Mar 2011 01:14:14 +0100 Subject: [PATCH 0676/5560] ARM: Remove duplicate linux/sched.h include from arch/arm/plat-iop/time.c There's no need to include linux/sched.h more than once in arch/arm/plat-iop/time.c Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- arch/arm/plat-iop/time.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 07f23bb42bed..7cdc5161ff2b 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include -- GitLab From 58c2ee4007bea04cc37041fcbd380fadb7b7be82 Mon Sep 17 00:00:00 2001 From: Nikanth Karthikesan Date: Tue, 15 Mar 2011 10:59:02 +0530 Subject: [PATCH 0677/5560] mm: Fix section mismatch for setup_zone_pageset() build_all_zonelists() which is not __meminit, calls setup_zone_pageset(). Signed-off-by: Nikanth Karthikesan Signed-off-by: Jiri Kosina --- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7945247b1e53..48c9737ad49a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3448,7 +3448,7 @@ static void setup_pagelist_highmark(struct per_cpu_pageset *p, pcp->batch = PAGE_SHIFT * 8; } -static __meminit void setup_zone_pageset(struct zone *zone) +static void setup_zone_pageset(struct zone *zone) { int cpu; -- GitLab From 853a1378ed6d6c9214d3a8f62d33186c6283cb51 Mon Sep 17 00:00:00 2001 From: Nikanth Karthikesan Date: Tue, 15 Mar 2011 10:59:27 +0530 Subject: [PATCH 0678/5560] cs5535: Fix section mismatch Fix section mismatch by annotating using variable name suffix. Signed-off-by: Nikanth Karthikesan Signed-off-by: Jiri Kosina --- drivers/misc/cs5535-mfgpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index d02d302ee6d5..e01e08c8c88b 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -329,7 +329,7 @@ static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) return err; } -static struct platform_driver cs5535_mfgpt_drv = { +static struct platform_driver cs5535_mfgpt_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, @@ -340,7 +340,7 @@ static struct platform_driver cs5535_mfgpt_drv = { static int __init cs5535_mfgpt_init(void) { - return platform_driver_register(&cs5535_mfgpt_drv); + return platform_driver_register(&cs5535_mfgpt_driver); } module_init(cs5535_mfgpt_init); -- GitLab From 1dd45aae79b821620ce45765e6210d77173fcecd Mon Sep 17 00:00:00 2001 From: Nikanth Karthikesan Date: Thu, 17 Mar 2011 11:04:14 +0530 Subject: [PATCH 0679/5560] ldm: Silence "ldm_validate_partition_table(): Disk read failed" when booting with "quiet" When the kernel does partition detection, on certain configurations with external fibre channel raid systems (e.g. clariion from EMC) the read would fail. And "ldm_validate_partition_table(): Disk read failed" messages are printed to the console. But the failure to read is not a critical error. Now since the message is flagged as KERN_CRIT, it gets printed even when booting with the "quiet" kernel parameter. Fix it by using KERN_INFO, as the failure to read here is not really an error. Signed-off-by: Nikanth Karthikesan Reported-by : Klaus Hartmann Signed-off-by: Anton Altaparmakov Signed-off-by: Jiri Kosina --- fs/partitions/ldm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c index b10e3540d5b7..ea648b913beb 100644 --- a/fs/partitions/ldm.c +++ b/fs/partitions/ldm.c @@ -565,7 +565,7 @@ static bool ldm_validate_partition_table(struct parsed_partitions *state) data = read_part_sector(state, 0, §); if (!data) { - ldm_crit ("Disk read failed."); + ldm_info ("Disk read failed."); return false; } -- GitLab From 205a44a436e2af83ce9b88144f0eacbb16f8e915 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 16 Mar 2011 21:36:32 +0100 Subject: [PATCH 0680/5560] drm: radeon: Fix printk typo 'ib poll' Signed-off-by: Paul Bolle Signed-off-by: Jiri Kosina --- drivers/gpu/drm/radeon/radeon_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index bbc9cd823334..d86254d7f80a 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -194,7 +194,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr); radeon_bo_unreserve(rdev->ib_pool.robj); if (r) { - DRM_ERROR("radeon: failed to map ib poll (%d).\n", r); + DRM_ERROR("radeon: failed to map ib pool (%d).\n", r); return r; } for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { -- GitLab From 99172a2f9edb3517f610fb93356a6a6a0c30f0c8 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 18 Mar 2011 11:33:08 -0600 Subject: [PATCH 0681/5560] add printk.time=1 boot-time hint to Kconfig.debug help text Cite Documentation/kernel-parameters.txt for an alternative to building with PRINTK_TIME compiled in. Signed-off-by: Jim Cromie Signed-off-by: Jiri Kosina --- lib/Kconfig.debug | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 6f440d82b58d..b38cc34281b8 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -7,7 +7,8 @@ config PRINTK_TIME included in printk output. This allows you to measure the interval between kernel operations, including bootup operations. This is useful for identifying long delays - in kernel startup. + in kernel startup. Or add printk.time=1 at boot-time. + See Documentation/kernel-parameters.txt config ENABLE_WARN_DEPRECATED bool "Enable __deprecated logic" -- GitLab From b0c3af5ef0d7b38eb1ba522becd47123ac9736d2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 23 Mar 2011 12:55:37 -0700 Subject: [PATCH 0682/5560] arm: mach-u300/gpio: Fix mem_region resource size miscalculations Convert off-by-1 r->end - r->start to resource_size(r) Signed-off-by: Joe Perches Acked-by: Linus Walleij Signed-off-by: Jiri Kosina --- arch/arm/mach-u300/gpio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c index d92790140fe5..94837a4e146b 100644 --- a/arch/arm/mach-u300/gpio.c +++ b/arch/arm/mach-u300/gpio.c @@ -581,8 +581,7 @@ static int __init gpio_probe(struct platform_device *pdev) if (!memres) goto err_no_resource; - if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller") - == NULL) { + if (!request_mem_region(memres->start, resource_size(memres), "GPIO Controller")) { err = -ENODEV; goto err_no_ioregion; } @@ -640,7 +639,7 @@ static int __init gpio_probe(struct platform_device *pdev) free_irq(gpio_ports[i].irq, &gpio_ports[i]); iounmap(virtbase); err_no_ioremap: - release_mem_region(memres->start, memres->end - memres->start); + release_mem_region(memres->start, resource_size(memres)); err_no_ioregion: err_no_resource: clk_disable(clk); @@ -660,7 +659,7 @@ static int __exit gpio_remove(struct platform_device *pdev) for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++) free_irq(gpio_ports[i].irq, &gpio_ports[i]); iounmap(virtbase); - release_mem_region(memres->start, memres->end - memres->start); + release_mem_region(memres->start, resource_size(memres)); clk_disable(clk); clk_put(clk); return 0; -- GitLab From 06794eaeb766989e450c1b459ae28da76e1f8719 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 23 Mar 2011 12:55:36 -0700 Subject: [PATCH 0683/5560] treewide: Fix iomap resource size miscalculations Convert off-by-1 r->end - r->start to resource_size(r) Signed-off-by: Joe Perches Acked-by: David Brown Acked-by: Linus Walleij Acked-by: Florian Fainelli Acked-by: Wim Van Sebroeck Acked-by: Ralf Baechle Signed-off-by: Jiri Kosina --- arch/arm/mach-ux500/mbox-db5500.c | 6 ++---- arch/mips/rb532/gpio.c | 2 +- drivers/video/msm/mddi.c | 2 +- drivers/watchdog/bcm63xx_wdt.c | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-ux500/mbox-db5500.c b/arch/arm/mach-ux500/mbox-db5500.c index a4ffb9f4f461..2b2d51caf9d8 100644 --- a/arch/arm/mach-ux500/mbox-db5500.c +++ b/arch/arm/mach-ux500/mbox-db5500.c @@ -416,8 +416,7 @@ struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv) dev_dbg(&(mbox->pdev->dev), "Resource name: %s start: 0x%X, end: 0x%X\n", resource->name, resource->start, resource->end); - mbox->virtbase_peer = - ioremap(resource->start, resource->end - resource->start); + mbox->virtbase_peer = ioremap(resource->start, resource_size(resource)); if (!mbox->virtbase_peer) { dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n"); mbox = NULL; @@ -440,8 +439,7 @@ struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv) dev_dbg(&(mbox->pdev->dev), "Resource name: %s start: 0x%X, end: 0x%X\n", resource->name, resource->start, resource->end); - mbox->virtbase_local = - ioremap(resource->start, resource->end - resource->start); + mbox->virtbase_local = ioremap(resource->start, resource_size(resource)); if (!mbox->virtbase_local) { dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n"); mbox = NULL; diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index 37de05d595e7..6c47dfeb7be3 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c @@ -185,7 +185,7 @@ int __init rb532_gpio_init(void) struct resource *r; r = rb532_gpio_reg0_res; - rb532_gpio_chip->regbase = ioremap_nocache(r->start, r->end - r->start); + rb532_gpio_chip->regbase = ioremap_nocache(r->start, resource_size(r)); if (!rb532_gpio_chip->regbase) { printk(KERN_ERR "rb532: cannot remap GPIO register 0\n"); diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index b66d86ac7cea..178b0720bd79 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -679,7 +679,7 @@ static int __devinit mddi_probe(struct platform_device *pdev) printk(KERN_ERR "mddi: no associated mem resource!\n"); return -ENOMEM; } - mddi->base = ioremap(resource->start, resource->end - resource->start); + mddi->base = ioremap(resource->start, resource_size(resource)); if (!mddi->base) { printk(KERN_ERR "mddi: failed to remap base!\n"); ret = -EINVAL; diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 3c5045a206dd..5064e8317521 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -248,7 +248,7 @@ static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev) return -ENODEV; } - bcm63xx_wdt_device.regs = ioremap_nocache(r->start, r->end - r->start); + bcm63xx_wdt_device.regs = ioremap_nocache(r->start, resource_size(r)); if (!bcm63xx_wdt_device.regs) { dev_err(&pdev->dev, "failed to remap I/O resources\n"); return -ENXIO; -- GitLab From 9f0af69b2dd34d2c21817d599db7bdb3c972a759 Mon Sep 17 00:00:00 2001 From: Nikanth Karthikesan Date: Thu, 24 Mar 2011 11:46:18 +0530 Subject: [PATCH 0684/5560] sysfs-memory: fix uninitialized variable warning and clean-up code. sysfs-memory: Fix uninitialized variable warning and clean-up code. Signed-off-by: Nikanth Karthikesan Signed-off-by: Jiri Kosina --- drivers/base/memory.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 3da6a43b7756..89ffb4425d1d 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -396,15 +396,14 @@ memory_probe_store(struct class *class, struct class_attribute *attr, ret = add_memory(nid, phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); if (ret) - break; + goto out; phys_addr += MIN_MEMORY_BLOCK_SIZE; } - if (ret) - count = ret; - - return count; + ret = count; +out: + return ret; } static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); -- GitLab From 6eab04a87677a37cf15b52e2b4b4fd57917102ad Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Fri, 8 Apr 2011 19:49:08 -0700 Subject: [PATCH 0685/5560] treewide: remove extra semicolons Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- arch/arm/mach-at91/at91cap9_devices.c | 2 +- arch/arm/mach-at91/at91sam9g45_devices.c | 2 +- arch/arm/mach-at91/at91sam9rl_devices.c | 2 +- arch/arm/mach-tegra/tegra2_clocks.c | 2 +- arch/s390/hypfs/hypfs.h | 2 +- arch/um/drivers/mmapper_kern.c | 2 +- drivers/gpio/langwell_gpio.c | 2 +- drivers/leds/leds-mc13783.c | 2 +- drivers/net/can/softing/softing_main.c | 2 +- drivers/net/wireless/ath/ath9k/phy.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/rtlwifi/core.c | 2 +- drivers/net/wireless/rtlwifi/pci.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 4 ++-- drivers/power/intel_mid_battery.c | 2 +- drivers/scsi/be2iscsi/be_main.c | 4 ++-- drivers/scsi/lpfc/lpfc_bsg.c | 2 +- drivers/scsi/pm8001/pm8001_init.c | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 4 ++-- drivers/target/target_core_alua.c | 4 ++-- drivers/target/target_core_transport.c | 2 +- drivers/tty/serial/mrst_max3110.c | 2 +- drivers/video/mxsfb.c | 2 +- drivers/xen/evtchn.c | 2 +- drivers/xen/swiotlb-xen.c | 2 +- fs/logfs/readwrite.c | 2 +- fs/ocfs2/refcounttree.c | 2 +- kernel/pm_qos_params.c | 2 +- mm/hugetlb.c | 2 +- net/netfilter/ipset/ip_set_bitmap_ip.c | 2 +- net/sunrpc/addr.c | 2 +- security/selinux/selinuxfs.c | 8 ++++---- tools/power/x86/turbostat/turbostat.c | 2 +- 33 files changed, 40 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index d1f775e86353..308ce7a87edd 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -171,7 +171,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) */ usba_udc_data.pdata.vbus_pin = -EINVAL; usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); if (data && data->vbus_pin > 0) { at91_set_gpio_input(data->vbus_pin, 0); diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 1e8f275c17f6..5e9f8a4c38df 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -256,7 +256,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) { usba_udc_data.pdata.vbus_pin = -EINVAL; usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); if (data && data->vbus_pin > 0) { at91_set_gpio_input(data->vbus_pin, 0); diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 53aaa94df75a..c49262bddd85 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -145,7 +145,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) */ usba_udc_data.pdata.vbus_pin = -EINVAL; usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); - memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); if (data && data->vbus_pin > 0) { at91_set_gpio_input(data->vbus_pin, 0); diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c index 6d7c4eea4dcb..3b6f290fde4c 100644 --- a/arch/arm/mach-tegra/tegra2_clocks.c +++ b/arch/arm/mach-tegra/tegra2_clocks.c @@ -337,7 +337,7 @@ static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p) const struct clk_mux_sel *sel; int shift; - val = clk_readl(c->reg + SUPER_CLK_MUX);; + val = clk_readl(c->reg + SUPER_CLK_MUX); BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index 80c1526f2af3..d9df5a060a83 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h @@ -47,7 +47,7 @@ struct hypfs_dbfs_data { void *buf; void *buf_free_ptr; size_t size; - struct hypfs_dbfs_file *dbfs_file;; + struct hypfs_dbfs_file *dbfs_file; struct kref kref; }; diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index 7e0619c2c2c6..c0ef803c7c70 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -116,7 +116,7 @@ static int __init mmapper_init(void) if (err) { printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", err); - return err;; + return err; } return 0; } diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 560ab648cf18..1b06f67e1f69 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c @@ -122,7 +122,7 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, lnw_gpio_set(chip, offset, value); spin_lock_irqsave(&lnw->lock, flags); value = readl(gpdr); - value |= BIT(offset % 32);; + value |= BIT(offset % 32); writel(value, gpdr); spin_unlock_irqrestore(&lnw->lock, flags); return 0; diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c index f05bb08d0f09..f369e56d6547 100644 --- a/drivers/leds/leds-mc13783.c +++ b/drivers/leds/leds-mc13783.c @@ -234,7 +234,7 @@ static int __devinit mc13783_leds_prepare(struct platform_device *pdev) MC13783_LED_Cx_PERIOD; if (pdata->flags & MC13783_LED_TRIODE_TC3) - reg |= MC13783_LED_Cx_TRIODE_TC_BIT;; + reg |= MC13783_LED_Cx_TRIODE_TC_BIT; ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg); if (ret) diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index aeea9f9ff6e8..8d7595344a62 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -797,7 +797,7 @@ static __devinit int softing_pdev_probe(struct platform_device *pdev) ret = -EINVAL; pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!pres) - goto platform_resource_failed;; + goto platform_resource_failed; card->dpram_phys = pres->start; card->dpram_size = pres->end - pres->start + 1; card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size); diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 5e3d7496986e..3a7cd7523d5c 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -54,7 +54,7 @@ #define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ int i; \ for (i = 0; i < (_iniarray)->ia_rows; i++) \ - (_bank)[i] = INI_RA((_iniarray), i, _col);; \ + (_bank)[i] = INI_RA((_iniarray), i, _col); \ } while (0) #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 581dc9f10273..31233a330372 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2062,7 +2062,7 @@ static const char *desc_lookup(u32 num) max = ARRAY_SIZE(advanced_lookup) - 1; for (i = 0; i < max; i++) { if (advanced_lookup[i].num == num) - break;; + break; } return advanced_lookup[i].name; } diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index e4f4aee8f298..d52fa27103c6 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -719,7 +719,7 @@ 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;; + 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)); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 9cd7703c2a30..baa2efeeedf6 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1226,7 +1226,7 @@ static unsigned int _rtl_mac_to_hwqueue(__le16 fc, hw_queue_index = VI_QUEUE; break; case 2: - hw_queue_index = BE_QUEUE;; + hw_queue_index = BE_QUEUE; break; case 3: hw_queue_index = BK_QUEUE; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 05477f465a75..7432c85a8dff 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -729,7 +729,7 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) rtl_write_word(rtlpriv, REG_CR, 0x2ff); if (_rtl92ce_llt_table_init(hw) == false) - return false;; + return false; rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); rtl_write_byte(rtlpriv, REG_HISRE, 0xff); @@ -786,7 +786,7 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); - return true;; + return true; } static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index bce3a01da2f0..cffcb7c00b00 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c @@ -522,7 +522,7 @@ static int pmic_battery_set_charger(struct pmic_power_module_info *pbi, if (retval) { dev_warn(pbi->dev, "%s(): ipc pmic read failed\n", __func__); - return retval;; + return retval; } return 0; diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 24e20ba9633c..44ac4aef879f 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -618,7 +618,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) + BE2_NOPOUT_REQ)); phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2; - phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; + phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count; phba->params.num_sge_per_io = BE2_SGE; phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ; @@ -781,7 +781,7 @@ static irqreturn_t be_isr(int irq, void *dev_id) int isr; phba = dev_id; - ctrl = &phba->ctrl;; + ctrl = &phba->ctrl; isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET + (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE)); if (!isr) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 0dd43bb91618..04fef038b1ff 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -595,7 +595,7 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job) dd_data->context_un.iocb.cmdiocbq = cmdiocbq; dd_data->context_un.iocb.rspiocbq = rspiocbq; dd_data->context_un.iocb.set_job = job; - dd_data->context_un.iocb.bmp = NULL;; + dd_data->context_un.iocb.bmp = NULL; dd_data->context_un.iocb.ndlp = ndlp; if (phba->cfg_poll & DISABLE_FCP_RING_INT) { diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 002360da01e3..172cefb6deb9 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -160,7 +160,7 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha) static void pm8001_tasklet(unsigned long opaque) { struct pm8001_hba_info *pm8001_ha; - pm8001_ha = (struct pm8001_hba_info *)opaque;; + pm8001_ha = (struct pm8001_hba_info *)opaque; if (unlikely(!pm8001_ha)) BUG_ON(1); PM8001_CHIP_DISP->isr(pm8001_ha); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d17ed9a94a0c..8b4d99a224f3 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1051,7 +1051,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, } DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt))); } else { - bsg_job->reply->result = DID_OK << 16;; + bsg_job->reply->result = DID_OK << 16; bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; bsg_job->reply_len = 0; @@ -1146,7 +1146,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt))); } else { - bsg_job->reply->result = DID_OK << 16;; + bsg_job->reply->result = DID_OK << 16; bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; bsg_job->reply_len = 0; } diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 2c5fcfed5934..e7dddafe73f6 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -1036,7 +1036,7 @@ core_alua_allocate_lu_gp(const char *name, int def_group) lu_gp = kmem_cache_zalloc(t10_alua_lu_gp_cache, GFP_KERNEL); if (!(lu_gp)) { printk(KERN_ERR "Unable to allocate struct t10_alua_lu_gp\n"); - return ERR_PTR(-ENOMEM);; + return ERR_PTR(-ENOMEM); } INIT_LIST_HEAD(&lu_gp->lu_gp_list); INIT_LIST_HEAD(&lu_gp->lu_gp_mem_list); @@ -1044,7 +1044,7 @@ core_alua_allocate_lu_gp(const char *name, int def_group) atomic_set(&lu_gp->lu_gp_ref_cnt, 0); if (def_group) { - lu_gp->lu_gp_id = se_global->alua_lu_gps_counter++;; + lu_gp->lu_gp_id = se_global->alua_lu_gps_counter++; lu_gp->lu_gp_valid_id = 1; se_global->alua_lu_gps_count++; } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ff9ace01e27a..39ac190080e2 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2131,7 +2131,7 @@ static void transport_failure_reset_queue_depth(struct se_device *dev) { unsigned long flags; - spin_lock_irqsave(&SE_HBA(dev)->hba_queue_lock, flags);; + spin_lock_irqsave(&SE_HBA(dev)->hba_queue_lock, flags); atomic_inc(&dev->depth_left); atomic_inc(&SE_HBA(dev)->left_queue_depth); spin_unlock_irqrestore(&SE_HBA(dev)->hba_queue_lock, flags); diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 37e13c3d91d9..8890612a8d9a 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -56,7 +56,7 @@ struct uart_max3110 { wait_queue_head_t wq; struct task_struct *main_thread; struct task_struct *read_thread; - struct mutex thread_mutex;; + struct mutex thread_mutex; u32 baud; u16 cur_conf; diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 7d0284882984..0b2f2dd41416 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -401,7 +401,7 @@ static int mxsfb_set_par(struct fb_info *fb_info) writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER | - CTRL_SET_BUS_WIDTH(host->ld_intf_width);; + CTRL_SET_BUS_WIDTH(host->ld_intf_width); switch (fb_info->var.bits_per_pixel) { case 16: diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index ef11daf0cafe..dbc13e94b612 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -470,7 +470,7 @@ static int evtchn_open(struct inode *inode, struct file *filp) filp->private_data = u; - return nonseekable_open(inode, filp);; + return nonseekable_open(inode, filp); } static int evtchn_release(struct inode *inode, struct file *filp) diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 54469c3eeacd..65ea21a97492 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -54,7 +54,7 @@ u64 start_dma_addr; static dma_addr_t xen_phys_to_bus(phys_addr_t paddr) { - return phys_to_machine(XPADDR(paddr)).maddr;; + return phys_to_machine(XPADDR(paddr)).maddr; } static phys_addr_t xen_bus_to_phys(dma_addr_t baddr) diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index ee99a9f5dfd3..3dcb3a60c331 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c @@ -481,7 +481,7 @@ static int inode_write_alias(struct super_block *sb, val = inode_val0(inode); break; case INODE_USED_OFS: - val = cpu_to_be64(li->li_used_bytes);; + val = cpu_to_be64(li->li_used_bytes); break; case INODE_SIZE_OFS: val = cpu_to_be64(i_size_read(inode)); diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index c384d634872a..c4feceda2d96 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -3707,7 +3707,7 @@ int ocfs2_refcount_cow_xattr(struct inode *inode, context->cow_start = cow_start; context->cow_len = cow_len; context->ref_tree = ref_tree; - context->ref_root_bh = ref_root_bh;; + context->ref_root_bh = ref_root_bh; context->cow_object = xv; context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_jbd; diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 0da058bff8eb..beb184689af9 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c @@ -385,7 +385,7 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf, s32 value; unsigned long flags; struct pm_qos_object *o; - struct pm_qos_request_list *pm_qos_req = filp->private_data;; + struct pm_qos_request_list *pm_qos_req = filp->private_data; if (!pm_qos_req) return -EINVAL; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bb0b7c128015..838fe25f704c 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -475,7 +475,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, /* If reserves cannot be used, ensure enough pages are in the pool */ if (avoid_reserve && h->free_huge_pages - h->resv_huge_pages == 0) - goto err;; + goto err; for_each_zone_zonelist_nodemask(zone, z, zonelist, MAX_NR_ZONES - 1, nodemask) { diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c index bca96990218d..cc2992299e74 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/net/netfilter/ipset/ip_set_bitmap_ip.c @@ -293,7 +293,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[], for (; !before(ip_to, ip); ip += map->hosts) { id = ip_to_id(map, ip); - ret = adtfn(set, &id, timeout);; + ret = adtfn(set, &id, timeout); if (ret && !ip_set_eexist(ret, flags)) return ret; diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 1419d0cdbbac..4195233c4914 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c @@ -151,7 +151,7 @@ static size_t rpc_pton4(const char *buf, const size_t buflen, return 0; sin->sin_family = AF_INET; - return sizeof(struct sockaddr_in);; + return sizeof(struct sockaddr_in); } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index ea39cb742ae5..47b7d624a6e1 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -280,7 +280,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, length = -ENOMEM; if (count >= PAGE_SIZE) - goto out;; + goto out; /* No partial writes. */ length = -EINVAL; @@ -876,12 +876,12 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) length = task_has_security(current, SECURITY__COMPUTE_USER); if (length) - goto out;; + goto out; length = -ENOMEM; con = kzalloc(size + 1, GFP_KERNEL); if (!con) - goto out;; + goto out; length = -ENOMEM; user = kzalloc(size + 1, GFP_KERNEL); @@ -941,7 +941,7 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size) length = -ENOMEM; scon = kzalloc(size + 1, GFP_KERNEL); if (!scon) - goto out;; + goto out; length = -ENOMEM; tcon = kzalloc(size + 1, GFP_KERNEL); diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 362a0cb448db..6d8ef4a3a9b5 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -990,7 +990,7 @@ int fork_it(char **argv) if (!retval) print_counters(cnt_delta); - fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);; + fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); return 0; } -- GitLab From 687566990640e476aeeed844947f2ecadc4717d3 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 29 Mar 2011 09:36:51 -0700 Subject: [PATCH 0686/5560] arch:Kconfig.locks Remove unused config option. Signed-off-by: Justin P. Mattock Acked-by: Steven Rostedt Acked-by: Heiko Carstens Signed-off-by: Jiri Kosina --- arch/Kconfig | 3 --- kernel/Kconfig.locks | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index f78c2be4242b..8d24bacaa61e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -144,9 +144,6 @@ config HAVE_CLK config HAVE_DMA_API_DEBUG bool -config HAVE_DEFAULT_NO_SPIN_MUTEXES - bool - config HAVE_HW_BREAKPOINT bool depends on PERF_EVENTS diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks index 88c92fb44618..5068e2a4e75f 100644 --- a/kernel/Kconfig.locks +++ b/kernel/Kconfig.locks @@ -199,4 +199,4 @@ config INLINE_WRITE_UNLOCK_IRQRESTORE def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE config MUTEX_SPIN_ON_OWNER - def_bool SMP && !DEBUG_MUTEXES && !HAVE_DEFAULT_NO_SPIN_MUTEXES + def_bool SMP && !DEBUG_MUTEXES -- GitLab From 6c655db070ad0e43f66b45fed4c526d6aac07107 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 30 Mar 2011 10:55:03 -0700 Subject: [PATCH 0687/5560] m68k: fix comment typo 'occcured' The patch below changes a typo occcured to occurred in two comments. Signed-off-by: Justin P. Mattock Signed-off-by: Jiri Kosina --- arch/m68k/include/asm/MC68EZ328.h | 2 +- arch/m68k/include/asm/MC68VZ328.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/m68k/include/asm/MC68EZ328.h b/arch/m68k/include/asm/MC68EZ328.h index 69b7f9139e5e..d1bde58ab0dd 100644 --- a/arch/m68k/include/asm/MC68EZ328.h +++ b/arch/m68k/include/asm/MC68EZ328.h @@ -1047,7 +1047,7 @@ typedef volatile struct { #define WATCHDOG_EN 0x0001 /* Watchdog Enabled */ #define WATCHDOG_ISEL 0x0002 /* Select the watchdog interrupt */ -#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occcured */ +#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occurred */ #define WATCHDOG_CNT_MASK 0x0300 /* Watchdog Counter */ #define WATCHDOG_CNT_SHIFT 8 diff --git a/arch/m68k/include/asm/MC68VZ328.h b/arch/m68k/include/asm/MC68VZ328.h index 2b9bf626a0a5..6bd1bf1f85ea 100644 --- a/arch/m68k/include/asm/MC68VZ328.h +++ b/arch/m68k/include/asm/MC68VZ328.h @@ -1143,7 +1143,7 @@ typedef struct { #define WATCHDOG_EN 0x0001 /* Watchdog Enabled */ #define WATCHDOG_ISEL 0x0002 /* Select the watchdog interrupt */ -#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occcured */ +#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occurred */ #define WATCHDOG_CNT_MASK 0x0300 /* Watchdog Counter */ #define WATCHDOG_CNT_SHIFT 8 -- GitLab From 6e4d2d9eb22dc9e9f0abfb1a464405b97a461cde Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 6 Apr 2011 21:40:13 +0000 Subject: [PATCH 0688/5560] usb: plusb: Whitespace This patch cleans up a couple of instances of incorrect whitespace Signed-off-by: Simon Wood Signed-off-by: David S. Miller --- drivers/net/usb/plusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index 823c53751307..2fe1bb5d7ba5 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c @@ -134,13 +134,13 @@ static struct usb_driver plusb_driver = { static int __init plusb_init(void) { - return usb_register(&plusb_driver); + return usb_register(&plusb_driver); } module_init(plusb_init); static void __exit plusb_exit(void) { - usb_deregister(&plusb_driver); + usb_deregister(&plusb_driver); } module_exit(plusb_exit); -- GitLab From 647da406e5e6cef87d17ee4d3c65c7b496883a3f Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 6 Apr 2011 21:40:14 +0000 Subject: [PATCH 0689/5560] usb: plusb: Add support for PL-25A1 This patch adds support for the PL-25A1 by adding the appropriate USB ID's. This chip is used in the Belkin 'Windows Easy Transfer' Cables. Signed-off-by: Simon Wood Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 2 +- drivers/net/usb/plusb.c | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 3ec22c307797..9d4f9117260f 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -258,7 +258,7 @@ config USB_NET_NET1080 optionally with LEDs that indicate traffic config USB_NET_PLUSB - tristate "Prolific PL-2301/2302 based cables" + tristate "Prolific PL-2301/2302/25A1 based cables" # if the handshake/init/reset problems, from original 'plusb', # are ever resolved ... then remove "experimental" depends on USB_USBNET && EXPERIMENTAL diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index 2fe1bb5d7ba5..f46aa07bfa69 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c @@ -45,6 +45,14 @@ * seems to get wedged under load. Prolific docs are weak, and * don't identify differences between PL2301 and PL2302, much less * anything to explain the different PL2302 versions observed. + * + * NOTE: pl2501 has several modes, including pl2301 and pl2302 + * compatibility. Some docs suggest the difference between 2301 + * and 2302 is only to make MS-Windows use a different driver... + * + * pl25a1 glue based on patch from Tony Gibbs. Prolific "docs" on + * this chip are as usual incomplete about what control messages + * are supported. */ /* @@ -95,7 +103,7 @@ static int pl_reset(struct usbnet *dev) } static const struct driver_info prolific_info = { - .description = "Prolific PL-2301/PL-2302", + .description = "Prolific PL-2301/PL-2302/PL-25A1", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT, /* some PL-2302 versions seem to fail usb_set_interface() */ .reset = pl_reset, @@ -111,6 +119,7 @@ static const struct driver_info prolific_info = { static const struct usb_device_id products [] = { +/* full speed cables */ { USB_DEVICE(0x067b, 0x0000), // PL-2301 .driver_info = (unsigned long) &prolific_info, @@ -119,6 +128,15 @@ static const struct usb_device_id products [] = { .driver_info = (unsigned long) &prolific_info, }, +/* high speed cables */ +{ + USB_DEVICE(0x067b, 0x25a1), /* PL-25A1, no eeprom */ + .driver_info = (unsigned long) &prolific_info, +}, { + USB_DEVICE(0x050d, 0x258a), /* Belkin F5U258/F5U279 (PL-25A1) */ + .driver_info = (unsigned long) &prolific_info, +}, + { }, // END }; MODULE_DEVICE_TABLE(usb, products); @@ -145,5 +163,5 @@ static void __exit plusb_exit(void) module_exit(plusb_exit); MODULE_AUTHOR("David Brownell"); -MODULE_DESCRIPTION("Prolific PL-2301/2302 USB Host to Host Link Driver"); +MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver"); MODULE_LICENSE("GPL"); -- GitLab From 5325e92f33eef5fb54e2e63185d965b4be59a4b3 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 6 Apr 2011 21:40:15 +0000 Subject: [PATCH 0690/5560] usb: plusb: Add debug to reset function This patch adds some debug to the reset function to print out the reason why it fails. Signed-off-by: Simon Wood Signed-off-by: David S. Miller --- drivers/net/usb/plusb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index f46aa07bfa69..217aec8a768f 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c @@ -94,11 +94,15 @@ pl_set_QuickLink_features(struct usbnet *dev, int val) static int pl_reset(struct usbnet *dev) { + int status; + /* some units seem to need this reset, others reject it utterly. * FIXME be more like "naplink" or windows drivers. */ - (void) pl_set_QuickLink_features(dev, + status = pl_set_QuickLink_features(dev, PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E); + if (status != 0 && netif_msg_probe(dev)) + netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status); return 0; } -- GitLab From 5c04c819a20af40adb7d282199f4e34e14fa05c5 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 7 Apr 2011 04:51:50 +0000 Subject: [PATCH 0691/5560] fib_validate_source(): pass sk_buff instead of mark This makes sk_buff available for other use in fib_validate_source(). Signed-off-by: Michael Smith Signed-off-by: David S. Miller --- include/net/ip_fib.h | 6 +++--- net/ipv4/fib_frontend.c | 10 ++++------ net/ipv4/route.c | 16 ++++++++-------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index e5d66ec88cf6..514627f56339 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -227,9 +227,9 @@ extern struct fib_table *fib_get_table(struct net *net, u32 id); /* Exported by fib_frontend.c */ extern const struct nla_policy rtm_ipv4_policy[]; extern void ip_fib_init(void); -extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, - u32 *itag, u32 mark); +extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, + u8 tos, int oif, struct net_device *dev, + __be32 *spec_dst, u32 *itag); extern void fib_select_default(struct fib_result *res); /* Exported by fib_semantics.c */ diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 451088330bbb..f162f84b8d6d 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -188,9 +188,9 @@ EXPORT_SYMBOL(inet_dev_addr_type); * - check, that packet arrived from expected physical interface. * called with rcu_read_lock() */ -int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, - struct net_device *dev, __be32 *spec_dst, - u32 *itag, u32 mark) +int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, + int oif, struct net_device *dev, __be32 *spec_dst, + u32 *itag) { struct in_device *in_dev; struct flowi4 fl4; @@ -202,7 +202,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, fl4.flowi4_oif = 0; fl4.flowi4_iif = oif; - fl4.flowi4_mark = mark; fl4.daddr = src; fl4.saddr = dst; fl4.flowi4_tos = tos; @@ -214,8 +213,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, no_addr = in_dev->ifa_list == NULL; rpf = IN_DEV_RPFILTER(in_dev); accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); - if (mark && !IN_DEV_SRC_VMARK(in_dev)) - fl4.flowi4_mark = 0; + fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; } if (in_dev == NULL) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1628be530314..052c9123e576 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1871,8 +1871,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto e_inval; spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); } else { - err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, - &itag, 0); + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst, + &itag); if (err < 0) goto e_err; } @@ -1981,8 +1981,8 @@ static int __mkroute_input(struct sk_buff *skb, } - err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), - in_dev->dev, &spec_dst, &itag, skb->mark); + err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), + in_dev->dev, &spec_dst, &itag); if (err < 0) { ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, saddr); @@ -2150,9 +2150,9 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto brd_input; if (res.type == RTN_LOCAL) { - err = fib_validate_source(saddr, daddr, tos, + err = fib_validate_source(skb, saddr, daddr, tos, net->loopback_dev->ifindex, - dev, &spec_dst, &itag, skb->mark); + dev, &spec_dst, &itag); if (err < 0) goto martian_source_keep_err; if (err) @@ -2176,8 +2176,8 @@ out: return err; if (ipv4_is_zeronet(saddr)) spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); else { - err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, - &itag, skb->mark); + err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst, + &itag); if (err < 0) goto martian_source_keep_err; if (err) -- GitLab From 990078afbf90e0175e71da2df04595b99153514c Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 7 Apr 2011 04:51:51 +0000 Subject: [PATCH 0692/5560] Disable rp_filter for IPsec packets The reverse path filter interferes with IPsec subnet-to-subnet tunnels, especially when the link to the IPsec peer is on an interface other than the one hosting the default route. With dynamic routing, where the peer might be reachable through eth0 today and eth1 tomorrow, it's difficult to keep rp_filter enabled unless fake routes to the remote subnets are configured on the interface currently used to reach the peer. IPsec provides a much stronger anti-spoofing policy than rp_filter, so this patch disables the rp_filter for packets with a security path. Signed-off-by: Michael Smith Signed-off-by: David S. Miller --- include/net/xfrm.h | 9 +++++++++ net/ipv4/fib_frontend.c | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6ae4bc5ce8a7..65ea31348631 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -957,6 +957,15 @@ struct sec_path { struct xfrm_state *xvec[XFRM_MAX_DEPTH]; }; +static inline int secpath_exists(struct sk_buff *skb) +{ +#ifdef CONFIG_XFRM + return skb->sp != NULL; +#else + return 0; +#endif +} + static inline struct sec_path * secpath_get(struct sec_path *sp) { diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index f162f84b8d6d..22524716fe70 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -44,6 +44,7 @@ #include #include #include +#include #ifndef CONFIG_IP_MULTIPLE_TABLES @@ -211,7 +212,10 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, in_dev = __in_dev_get_rcu(dev); if (in_dev) { no_addr = in_dev->ifa_list == NULL; - rpf = IN_DEV_RPFILTER(in_dev); + + /* Ignore rp_filter for packets protected by IPsec. */ + rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(in_dev); + accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; } -- GitLab From 4e01d2d1cac683477b539b40b7b4662d6a9c436f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 8 Apr 2011 02:38:46 +0000 Subject: [PATCH 0693/5560] net: Remove invalid offloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove offload changing ethtool ops which drivers don't really support: - fs_enet - ucc_geth Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 2 -- drivers/net/ucc_geth_ethtool.c | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 24cb953900dd..a9388944f1d3 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -956,8 +956,6 @@ static const struct ethtool_ops fs_ethtool_ops = { .get_link = ethtool_op_get_link, .get_msglevel = fs_get_msglevel, .set_msglevel = fs_set_msglevel, - .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ - .set_sg = ethtool_op_set_sg, .get_regs = fs_get_regs, }; diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 6f92e48f02d3..537fbc0a4401 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c @@ -410,7 +410,6 @@ static const struct ethtool_ops uec_ethtool_ops = { .set_ringparam = uec_set_ringparam, .get_pauseparam = uec_get_pauseparam, .set_pauseparam = uec_set_pauseparam, - .set_sg = ethtool_op_set_sg, .get_sset_count = uec_get_sset_count, .get_strings = uec_get_strings, .get_ethtool_stats = uec_get_ethtool_stats, -- GitLab From 8b8ddc68df13032a5666438b48dfb7a86de3a610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 8 Apr 2011 02:38:47 +0000 Subject: [PATCH 0694/5560] net: benet: convert to hw_features - fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix up after merge with NETIF_F_RXHASH implementation. This allows to toggle NETIF_F_RXHASH and NETIF_F_HW_VLAN_TX. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 58a652f81862..289c73aa6875 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2629,14 +2629,13 @@ static void be_netdev_init(struct net_device *netdev) int i; netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_TX; + if (be_multi_rxq(adapter)) + netdev->hw_features |= NETIF_F_RXHASH; netdev->features |= netdev->hw_features | - NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_FILTER; - - if (be_multi_rxq(adapter)) - netdev->features |= NETIF_F_RXHASH; + NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; -- GitLab From 350fb32ae45ec74ea9cc117c728c48b8e840f0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 8 Apr 2011 06:35:56 +0000 Subject: [PATCH 0695/5560] net: r8169: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simple conversion with a bit of needed cleanup. This also fixes: - confusion around vlan_features in rtl8169_vlan_mode(), - problem with broken TSO for too big MTU (the limit is set at 0xFFF --- max MSS field value). SG+IP_CSUM+TSO is left disabled by default, based on suggestion by David Dillow. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/r8169.c | 95 ++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 62 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index caa99cdb5818..058524f3eb49 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1286,14 +1286,15 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return ret; } -static u32 rtl8169_get_rx_csum(struct net_device *dev) +static u32 rtl8169_fix_features(struct net_device *dev, u32 features) { - struct rtl8169_private *tp = netdev_priv(dev); + if (dev->mtu > MSSMask) + features &= ~NETIF_F_ALL_TSO; - return tp->cp_cmd & RxChkSum; + return features; } -static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) +static int rtl8169_set_features(struct net_device *dev, u32 features) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; @@ -1301,11 +1302,16 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) spin_lock_irqsave(&tp->lock, flags); - if (data) + if (features & NETIF_F_RXCSUM) tp->cp_cmd |= RxChkSum; else tp->cp_cmd &= ~RxChkSum; + if (dev->features & NETIF_F_HW_VLAN_RX) + tp->cp_cmd |= RxVlan; + else + tp->cp_cmd &= ~RxVlan; + RTL_W16(CPlusCmd, tp->cp_cmd); RTL_R16(CPlusCmd); @@ -1321,27 +1327,6 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; } -#define NETIF_F_HW_VLAN_TX_RX (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX) - -static void rtl8169_vlan_mode(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - - spin_lock_irqsave(&tp->lock, flags); - if (dev->features & NETIF_F_HW_VLAN_RX) - tp->cp_cmd |= RxVlan; - else - tp->cp_cmd &= ~RxVlan; - RTL_W16(CPlusCmd, tp->cp_cmd); - /* PCI commit */ - RTL_R16(CPlusCmd); - spin_unlock_irqrestore(&tp->lock, flags); - - dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX; -} - static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) { u32 opts2 = le32_to_cpu(desc->opts2); @@ -1522,28 +1507,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) } } -static int rtl8169_set_flags(struct net_device *dev, u32 data) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned long old_feat = dev->features; - int rc; - - if ((tp->mac_version == RTL_GIGA_MAC_VER_05) && - !(data & ETH_FLAG_RXVLAN)) { - netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n"); - return -EINVAL; - } - - rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); - if (rc) - return rc; - - if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) - rtl8169_vlan_mode(dev); - - return 0; -} - static const struct ethtool_ops rtl8169_ethtool_ops = { .get_drvinfo = rtl8169_get_drvinfo, .get_regs_len = rtl8169_get_regs_len, @@ -1552,19 +1515,12 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { .set_settings = rtl8169_set_settings, .get_msglevel = rtl8169_get_msglevel, .set_msglevel = rtl8169_set_msglevel, - .get_rx_csum = rtl8169_get_rx_csum, - .set_rx_csum = rtl8169_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = ethtool_op_set_tso, .get_regs = rtl8169_get_regs, .get_wol = rtl8169_get_wol, .set_wol = rtl8169_set_wol, .get_strings = rtl8169_get_strings, .get_sset_count = rtl8169_get_sset_count, .get_ethtool_stats = rtl8169_get_ethtool_stats, - .set_flags = rtl8169_set_flags, - .get_flags = ethtool_op_get_flags, }; static void rtl8169_get_mac_version(struct rtl8169_private *tp, @@ -2979,6 +2935,8 @@ static const struct net_device_ops rtl8169_netdev_ops = { .ndo_tx_timeout = rtl8169_tx_timeout, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = rtl8169_change_mtu, + .ndo_fix_features = rtl8169_fix_features, + .ndo_set_features = rtl8169_set_features, .ndo_set_mac_address = rtl_set_mac_address, .ndo_do_ioctl = rtl8169_ioctl, .ndo_set_multicast_list = rtl_set_rx_mode, @@ -3425,7 +3383,19 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT); - dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO; + /* don't enable SG, IP_CSUM and TSO by default - it might not work + * properly for all devices */ + dev->features |= NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HIGHDMA; + + if (tp->mac_version == RTL_GIGA_MAC_VER_05) + /* 8110SCd requires hardware Rx VLAN - disallow toggling */ + dev->hw_features &= ~NETIF_F_HW_VLAN_RX; tp->intr_mask = 0xffff; tp->hw_start = cfg->hw_start; @@ -3545,7 +3515,7 @@ static int rtl8169_open(struct net_device *dev) rtl8169_init_phy(dev, tp); - rtl8169_vlan_mode(dev); + rtl8169_set_features(dev, dev->features); rtl_pll_power_up(tp); @@ -4318,6 +4288,8 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->mtu = new_mtu; + netdev_update_features(dev); + return 0; } @@ -4642,12 +4614,11 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) { - if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->gso_size; + u32 mss = skb_shinfo(skb)->gso_size; + + if (mss) + return LargeSend | ((mss & MSSMask) << MSSShift); - if (mss) - return LargeSend | ((mss & MSSMask) << MSSShift); - } if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = ip_hdr(skb); -- GitLab From 044a890c5a0fb7ac60c70bbb4e1b79e59272e504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sat, 9 Apr 2011 00:58:18 +0000 Subject: [PATCH 0696/5560] net: 8139cp: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/8139cp.c | 46 ++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index dd16e83933a2..10c45051caea 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -758,8 +758,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; - if (dev->features & NETIF_F_TSO) - mss = skb_shinfo(skb)->gso_size; + mss = skb_shinfo(skb)->gso_size; if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; @@ -1416,32 +1415,23 @@ static void cp_set_msglevel(struct net_device *dev, u32 value) cp->msg_enable = value; } -static u32 cp_get_rx_csum(struct net_device *dev) +static int cp_set_features(struct net_device *dev, u32 features) { struct cp_private *cp = netdev_priv(dev); - return (cpr16(CpCmd) & RxChkSum) ? 1 : 0; -} + unsigned long flags; -static int cp_set_rx_csum(struct net_device *dev, u32 data) -{ - struct cp_private *cp = netdev_priv(dev); - u16 cmd = cp->cpcmd, newcmd; + if (!((dev->features ^ features) & NETIF_F_RXCSUM)) + return 0; - newcmd = cmd; + spin_lock_irqsave(&cp->lock, flags); - if (data) - newcmd |= RxChkSum; + if (features & NETIF_F_RXCSUM) + cp->cpcmd |= RxChkSum; else - newcmd &= ~RxChkSum; - - if (newcmd != cmd) { - unsigned long flags; + cp->cpcmd &= ~RxChkSum; - spin_lock_irqsave(&cp->lock, flags); - cp->cpcmd = newcmd; - cpw16_f(CpCmd, newcmd); - spin_unlock_irqrestore(&cp->lock, flags); - } + cpw16_f(CpCmd, cp->cpcmd); + spin_unlock_irqrestore(&cp->lock, flags); return 0; } @@ -1554,11 +1544,6 @@ static const struct ethtool_ops cp_ethtool_ops = { .get_link = ethtool_op_get_link, .get_msglevel = cp_get_msglevel, .set_msglevel = cp_set_msglevel, - .get_rx_csum = cp_get_rx_csum, - .set_rx_csum = cp_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ - .set_sg = ethtool_op_set_sg, - .set_tso = ethtool_op_set_tso, .get_regs = cp_get_regs, .get_wol = cp_get_wol, .set_wol = cp_set_wol, @@ -1831,6 +1816,7 @@ static const struct net_device_ops cp_netdev_ops = { .ndo_do_ioctl = cp_ioctl, .ndo_start_xmit = cp_start_xmit, .ndo_tx_timeout = cp_tx_timeout, + .ndo_set_features = cp_set_features, #if CP_VLAN_TAG_USED .ndo_vlan_rx_register = cp_vlan_rx_register, #endif @@ -1934,6 +1920,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) cp->cpcmd = (pci_using_dac ? PCIDAC : 0) | PCIMulRW | RxChkSum | CpRxOn | CpTxOn; + dev->features |= NETIF_F_RXCSUM; + dev->hw_features |= NETIF_F_RXCSUM; + regs = ioremap(pciaddr, CP_REGS_SIZE); if (!regs) { rc = -EIO; @@ -1966,9 +1955,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_using_dac) dev->features |= NETIF_F_HIGHDMA; -#if 0 /* disabled by default until verified */ - dev->features |= NETIF_F_TSO; -#endif + /* disabled by default until verified */ + dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; dev->irq = pdev->irq; -- GitLab From 5e982f3bfdd5d063f8806a26c87843496a35d26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sat, 9 Apr 2011 02:46:55 +0000 Subject: [PATCH 0697/5560] net: stmmac: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also removes TSO as it's made fully in software --- better to leave this to networking core. If the MAC features can be detected at probe time and not at open, then stmmac_fix_features could be simplified by limiting hw_features. That's also better for users as they don't see offloads being togglable but never turned on. Redundant fallbacks for TX csum are removed as it's already handled by network core. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_ethtool.c | 14 ----- drivers/net/stmmac/stmmac_main.c | 83 ++++++++--------------------- 2 files changed, 23 insertions(+), 74 deletions(-) diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index fd719edc7f7c..156a805c6c23 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -197,13 +197,6 @@ static void stmmac_ethtool_gregs(struct net_device *dev, } } -static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) -{ - struct stmmac_priv *priv = netdev_priv(dev); - - return priv->rx_coe; -} - static void stmmac_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) @@ -358,11 +351,6 @@ static struct ethtool_ops stmmac_ethtool_ops = { .get_regs = stmmac_ethtool_gregs, .get_regs_len = stmmac_ethtool_get_regs_len, .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 = ethtool_op_set_tx_ipv6_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, .get_pauseparam = stmmac_get_pauseparam, .set_pauseparam = stmmac_set_pauseparam, .get_ethtool_stats = stmmac_get_ethtool_stats, @@ -370,8 +358,6 @@ static struct ethtool_ops stmmac_ethtool_ops = { .get_wol = stmmac_get_wol, .set_wol = stmmac_set_wol, .get_sset_count = stmmac_get_sset_count, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, }; 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 0e5f03135b50..62fa51ed93ff 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -139,7 +139,6 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); static irqreturn_t stmmac_interrupt(int irq, void *dev_id); -static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev); /** * stmmac_verify_args - verify the driver parameters. @@ -843,6 +842,7 @@ static int stmmac_open(struct net_device *dev) pr_info("stmmac: Rx Checksum Offload Engine supported\n"); if (priv->plat->tx_coe) pr_info("\tTX Checksum insertion supported\n"); + netdev_update_features(dev); /* Initialise the MMC (if present) to disable all interrupts. */ writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); @@ -927,46 +927,6 @@ static int stmmac_release(struct net_device *dev) return 0; } -/* - * To perform emulated hardware segmentation on skb. - */ -static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb) -{ - struct sk_buff *segs, *curr_skb; - int gso_segs = skb_shinfo(skb)->gso_segs; - - /* Estimate the number of fragments in the worst case */ - if (unlikely(stmmac_tx_avail(priv) < gso_segs)) { - netif_stop_queue(priv->dev); - TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n", - __func__); - if (stmmac_tx_avail(priv) < gso_segs) - return NETDEV_TX_BUSY; - - netif_wake_queue(priv->dev); - } - TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n", - skb, skb->len); - - segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO); - if (IS_ERR(segs)) - goto sw_tso_end; - - do { - curr_skb = segs; - segs = segs->next; - TX_DBG("\t\tcurrent skb->len: %d, *curr %p," - "*next %p\n", curr_skb->len, curr_skb, segs); - curr_skb->next = NULL; - stmmac_xmit(curr_skb, priv->dev); - } while (segs); - -sw_tso_end: - dev_kfree_skb(skb); - - return NETDEV_TX_OK; -} - static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb, struct net_device *dev, int csum_insertion) @@ -1044,16 +1004,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) !skb_is_gso(skb) ? "isn't" : "is"); #endif - if (unlikely(skb_is_gso(skb))) - return stmmac_sw_tso(priv, skb); - - if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { - if (unlikely((!priv->plat->tx_coe) || - (priv->no_csum_insertion))) - skb_checksum_help(skb); - else - csum_insertion = 1; - } + csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); desc = priv->dma_tx + entry; first = desc; @@ -1373,18 +1324,29 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } + dev->mtu = new_mtu; + netdev_update_features(dev); + + return 0; +} + +static u32 stmmac_fix_features(struct net_device *dev, u32 features) +{ + struct stmmac_priv *priv = netdev_priv(dev); + + if (!priv->rx_coe) + features &= ~NETIF_F_RXCSUM; + if (!priv->plat->tx_coe) + features &= ~NETIF_F_ALL_CSUM; + /* Some GMAC devices have a bugged Jumbo frame support that * 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->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) - priv->no_csum_insertion = 1; - else - priv->no_csum_insertion = 0; + if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) + features &= ~NETIF_F_ALL_CSUM; - dev->mtu = new_mtu; - - return 0; + return features; } static irqreturn_t stmmac_interrupt(int irq, void *dev_id) @@ -1464,6 +1426,7 @@ static const struct net_device_ops stmmac_netdev_ops = { .ndo_start_xmit = stmmac_xmit, .ndo_stop = stmmac_release, .ndo_change_mtu = stmmac_change_mtu, + .ndo_fix_features = stmmac_fix_features, .ndo_set_multicast_list = stmmac_multicast_list, .ndo_tx_timeout = stmmac_tx_timeout, .ndo_do_ioctl = stmmac_ioctl, @@ -1494,8 +1457,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_HIGHDMA | - NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + dev->features |= dev->hw_features | NETIF_F_HIGHDMA; dev->watchdog_timeo = msecs_to_jiffies(watchdog); #ifdef STMMAC_VLAN_TAG_USED /* Both mac100 and gmac support receive VLAN tag detection */ -- GitLab From e6a46416d4233c99a041ca35c1f692ecae9f942d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 10 Apr 2011 03:13:21 +0000 Subject: [PATCH 0698/5560] net: ksz884x: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also fixes possible race when changing receive checksum state and removes IPV6_CSUM_GEN_HACK as it's always set. BTW, The claim about fake IPV6 checksum looks dubious. If that were true, then there's a problem in networking core and should be fixed there and not in random drivers. BTW#2, there's no MAINTAINERS entry for this driver. I assume this driver is supported by Micrel? Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/ksz884x.c | 73 +++++++++++++------------------------------ 1 file changed, 21 insertions(+), 52 deletions(-) diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 7f7d5708a658..2c37a3804303 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -1221,7 +1221,6 @@ struct ksz_port_info { #define LINK_INT_WORKING (1 << 0) #define SMALL_PACKET_TX_BUG (1 << 1) #define HALF_DUPLEX_SIGNAL_BUG (1 << 2) -#define IPV6_CSUM_GEN_HACK (1 << 3) #define RX_HUGE_FRAME (1 << 4) #define STP_SUPPORT (1 << 8) @@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw) if (1 == rc) hw->features |= HALF_DUPLEX_SIGNAL_BUG; } - hw->features |= IPV6_CSUM_GEN_HACK; return rc; } @@ -4887,8 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) left = hw_alloc_pkt(hw, skb->len, num); if (left) { if (left < num || - ((hw->features & IPV6_CSUM_GEN_HACK) && - (CHECKSUM_PARTIAL == skb->ip_summed) && + ((CHECKSUM_PARTIAL == skb->ip_summed) && (ETH_P_IPV6 == htons(skb->protocol)))) { struct sk_buff *org_skb = skb; @@ -6583,57 +6580,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev, } /** - * netdev_get_rx_csum - get receive checksum support + * netdev_set_features - set receive checksum support * @dev: Network device. - * - * This function gets receive checksum support setting. - * - * Return true if receive checksum is enabled; false otherwise. - */ -static u32 netdev_get_rx_csum(struct net_device *dev) -{ - struct dev_priv *priv = netdev_priv(dev); - struct dev_info *hw_priv = priv->adapter; - struct ksz_hw *hw = &hw_priv->hw; - - return hw->rx_cfg & - (DMA_RX_CSUM_UDP | - DMA_RX_CSUM_TCP | - DMA_RX_CSUM_IP); -} - -/** - * netdev_set_rx_csum - set receive checksum support - * @dev: Network device. - * @data: Zero to disable receive checksum support. + * @features: New device features (offloads). * * This function sets receive checksum support setting. * * Return 0 if successful; otherwise an error code. */ -static int netdev_set_rx_csum(struct net_device *dev, u32 data) +static int netdev_set_features(struct net_device *dev, u32 features) { struct dev_priv *priv = netdev_priv(dev); struct dev_info *hw_priv = priv->adapter; struct ksz_hw *hw = &hw_priv->hw; - u32 new_setting = hw->rx_cfg; - if (data) - new_setting |= - (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP | - DMA_RX_CSUM_IP); - else - new_setting &= - ~(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP | - DMA_RX_CSUM_IP); - new_setting &= ~DMA_RX_CSUM_UDP; mutex_lock(&hw_priv->lock); - if (new_setting != hw->rx_cfg) { - hw->rx_cfg = new_setting; - if (hw->enabled) - writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); - } + + /* see note in hw_setup() */ + if (features & NETIF_F_RXCSUM) + hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP; + else + hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP); + + if (hw->enabled) + writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); + mutex_unlock(&hw_priv->lock); + return 0; } @@ -6658,12 +6631,6 @@ static struct ethtool_ops netdev_ethtool_ops = { .get_strings = netdev_get_strings, .get_sset_count = netdev_get_sset_count, .get_ethtool_stats = netdev_get_ethtool_stats, - .get_rx_csum = netdev_get_rx_csum, - .set_rx_csum = netdev_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, }; /* @@ -6828,14 +6795,15 @@ static int __init netdev_init(struct net_device *dev) /* 500 ms timeout */ dev->watchdog_timeo = HZ / 2; - dev->features |= NETIF_F_IP_CSUM; + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; /* * Hardware does not really support IPv6 checksum generation, but - * driver actually runs faster with this on. Refer IPV6_CSUM_GEN_HACK. + * driver actually runs faster with this on. */ - dev->features |= NETIF_F_IPV6_CSUM; - dev->features |= NETIF_F_SG; + dev->hw_features |= NETIF_F_IPV6_CSUM; + + dev->features |= dev->hw_features; sema_init(&priv->proc_sem, 1); @@ -6860,6 +6828,7 @@ static const struct net_device_ops netdev_ops = { .ndo_start_xmit = netdev_tx, .ndo_tx_timeout = netdev_tx_timeout, .ndo_change_mtu = netdev_change_mtu, + .ndo_set_features = netdev_set_features, .ndo_set_mac_address = netdev_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = netdev_ioctl, -- GitLab From f593fe363268e7354b3a7f3907170de1ac4de7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 10 Apr 2011 03:13:21 +0000 Subject: [PATCH 0699/5560] net: via-velocity: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trivial conversion. This also enables toggling TX VLAN offload and fixes TX checksumming race with offload changes. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 0d6fec6b7d93..77315ad1e7e2 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2600,8 +2600,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb, /* * Handle hardware checksum */ - if ((dev->features & NETIF_F_IP_CSUM) && - (skb->ip_summed == CHECKSUM_PARTIAL)) { + if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = ip_hdr(skb); if (ip->protocol == IPPROTO_TCP) td_ptr->tdesc1.TCR |= TCR0_TCPCK; @@ -2841,6 +2840,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi dev->ethtool_ops = &velocity_ethtool_ops; netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT); + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HW_VLAN_TX; dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM; @@ -3457,13 +3457,10 @@ static const struct ethtool_ops velocity_ethtool_ops = { .get_settings = velocity_get_settings, .set_settings = velocity_set_settings, .get_drvinfo = velocity_get_drvinfo, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, .get_wol = velocity_ethtool_get_wol, .set_wol = velocity_ethtool_set_wol, .get_msglevel = velocity_get_msglevel, .set_msglevel = velocity_set_msglevel, - .set_sg = ethtool_op_set_sg, .get_link = velocity_get_link, .get_coalesce = velocity_get_coalesce, .set_coalesce = velocity_set_coalesce, -- GitLab From 8d7dfc2b57bb2cad0731dedd58ec1d70bcca1ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 10 Apr 2011 04:47:46 +0000 Subject: [PATCH 0700/5560] net: bnx2: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 109 ++++++++++++--------------------------------- drivers/net/bnx2.h | 2 - 2 files changed, 28 insertions(+), 83 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 05ddfb18d5bf..0a52079bafef 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3174,7 +3174,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) } skb_checksum_none_assert(skb); - if (bp->rx_csum && + if ((bp->dev->features & NETIF_F_RXCSUM) && (status & (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_UDP_DATAGRAM))) { @@ -7189,38 +7189,6 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) return 0; } -static u32 -bnx2_get_rx_csum(struct net_device *dev) -{ - struct bnx2 *bp = netdev_priv(dev); - - return bp->rx_csum; -} - -static int -bnx2_set_rx_csum(struct net_device *dev, u32 data) -{ - struct bnx2 *bp = netdev_priv(dev); - - bp->rx_csum = data; - return 0; -} - -static int -bnx2_set_tso(struct net_device *dev, u32 data) -{ - struct bnx2 *bp = netdev_priv(dev); - - if (data) { - dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - dev->features |= NETIF_F_TSO6; - } else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_TSO_ECN); - return 0; -} - static struct { char string[ETH_GSTRING_LEN]; } bnx2_stats_str_arr[] = { @@ -7532,43 +7500,37 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) return 0; } -static int -bnx2_set_tx_csum(struct net_device *dev, u32 data) +static u32 +bnx2_fix_features(struct net_device *dev, u32 features) { struct bnx2 *bp = netdev_priv(dev); - if (CHIP_NUM(bp) == CHIP_NUM_5709) - return ethtool_op_set_tx_ipv6_csum(dev, data); - else - return ethtool_op_set_tx_csum(dev, data); + if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) + features |= NETIF_F_HW_VLAN_RX; + + return features; } static int -bnx2_set_flags(struct net_device *dev, u32 data) +bnx2_set_features(struct net_device *dev, u32 features) { struct bnx2 *bp = netdev_priv(dev); - int rc; - - if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) && - !(data & ETH_FLAG_RXVLAN)) - return -EINVAL; /* TSO with VLAN tag won't work with current firmware */ - if (!(data & ETH_FLAG_TXVLAN)) - return -EINVAL; - - rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | - ETH_FLAG_TXVLAN); - if (rc) - return rc; + if (features & NETIF_F_HW_VLAN_TX) + dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO); + else + dev->vlan_features &= ~NETIF_F_ALL_TSO; - if ((!!(data & ETH_FLAG_RXVLAN) != + if ((!!(features & NETIF_F_HW_VLAN_RX) != !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) && netif_running(dev)) { bnx2_netif_stop(bp, false); + dev->features = features; bnx2_set_rx_mode(dev); bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); bnx2_netif_start(bp, false); + return 1; } return 0; @@ -7593,18 +7555,11 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .set_ringparam = bnx2_set_ringparam, .get_pauseparam = bnx2_get_pauseparam, .set_pauseparam = bnx2_set_pauseparam, - .get_rx_csum = bnx2_get_rx_csum, - .set_rx_csum = bnx2_set_rx_csum, - .set_tx_csum = bnx2_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = bnx2_set_tso, .self_test = bnx2_self_test, .get_strings = bnx2_get_strings, .set_phys_id = bnx2_set_phys_id, .get_ethtool_stats = bnx2_get_ethtool_stats, .get_sset_count = bnx2_get_sset_count, - .set_flags = bnx2_set_flags, - .get_flags = ethtool_op_get_flags, }; /* Called with rtnl_lock */ @@ -8116,8 +8071,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->tx_ring_size = MAX_TX_DESC_CNT; bnx2_set_rx_ring_size(bp, 255); - bp->rx_csum = 1; - bp->tx_quick_cons_trip_int = 2; bp->tx_quick_cons_trip = 20; bp->tx_ticks_int = 18; @@ -8309,17 +8262,14 @@ static const struct net_device_ops bnx2_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnx2_change_mac_addr, .ndo_change_mtu = bnx2_change_mtu, + .ndo_fix_features = bnx2_fix_features, + .ndo_set_features = bnx2_set_features, .ndo_tx_timeout = bnx2_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2, #endif }; -static inline void vlan_features_add(struct net_device *dev, u32 flags) -{ - dev->vlan_features |= flags; -} - static int __devinit bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -8359,20 +8309,17 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) memcpy(dev->dev_addr, bp->mac_addr, 6); memcpy(dev->perm_addr, bp->mac_addr, 6); - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO | - NETIF_F_RXHASH; - vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - dev->features |= NETIF_F_IPV6_CSUM; - vlan_features_add(dev, NETIF_F_IPV6_CSUM); - } - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; - vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - dev->features |= NETIF_F_TSO6; - vlan_features_add(dev, NETIF_F_TSO6); - } + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_TSO_ECN | + NETIF_F_RXHASH | NETIF_F_RXCSUM; + + if (CHIP_NUM(bp) == CHIP_NUM_5709) + dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + + dev->vlan_features = dev->hw_features; + dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->features |= dev->hw_features; + if ((rc = register_netdev(dev))) { dev_err(&pdev->dev, "Cannot register net device\n"); goto error; diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 91e83562238e..bf371f6fe154 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6754,8 +6754,6 @@ struct bnx2 { u32 rx_max_ring_idx; u32 rx_max_pg_ring_idx; - u32 rx_csum; - /* TX constants */ int tx_ring_size; u32 tx_wake_thresh; -- GitLab From 900d18c79d0c4d8c33079c163c6b8c7d8b9c4db6 Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Sun, 10 Apr 2011 15:02:00 +0200 Subject: [PATCH 0701/5560] xtensa: remove obsolete BKL kernel option from defconfig The BKL doesn't exist anymore so remove CONFIG_LOCK_KERNEL. This work was supported by a hardware donation from the CE Linux Forum. Signed-off-by: Alessio Igor Bogani Signed-off-by: Jiri Kosina --- arch/xtensa/configs/s6105_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig index 42b7feba71b7..4891abbf16bc 100644 --- a/arch/xtensa/configs/s6105_defconfig +++ b/arch/xtensa/configs/s6105_defconfig @@ -23,7 +23,6 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y -- GitLab From 0d60b281dc7fd2ae7ec6463f916138fd2d182bee Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Apr 2011 07:22:58 +0000 Subject: [PATCH 0702/5560] video: s3c-fb: make runtime pm functions static This patch makes runtime pm functions static. Signed-off-by: Jingoo Han Signed-off-by: Paul Mundt --- drivers/video/s3c-fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 3b6cdcac8f1a..2d075f0684d9 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -1549,7 +1549,7 @@ static int s3c_fb_resume(struct device *dev) return 0; } -int s3c_fb_runtime_suspend(struct device *dev) +static int s3c_fb_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s3c_fb *sfb = platform_get_drvdata(pdev); @@ -1569,7 +1569,7 @@ int s3c_fb_runtime_suspend(struct device *dev) return 0; } -int s3c_fb_runtime_resume(struct device *dev) +static int s3c_fb_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s3c_fb *sfb = platform_get_drvdata(pdev); -- GitLab From b07f3bbee12163a6b48991138a37b87a1126462a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 11 Apr 2011 07:25:37 +0000 Subject: [PATCH 0703/5560] video: s3c-fb: add spinlock to interrupt routine The spinlock is added to interrupt routine to ensure that the driver is protected against multiple accesses. Signed-off-by: Jingoo Han Signed-off-by: Paul Mundt --- drivers/video/s3c-fb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 2d075f0684d9..3fa7911ac906 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -182,6 +182,7 @@ struct s3c_fb_vsync { /** * struct s3c_fb - overall hardware state of the hardware + * @slock: The spinlock protection for this data sturcture. * @dev: The device that we bound to, for printing, etc. * @regs_res: The resource we claimed for the IO registers. * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. @@ -195,6 +196,7 @@ struct s3c_fb_vsync { * @vsync_info: VSYNC-related information (count, queues...) */ struct s3c_fb { + spinlock_t slock; struct device *dev; struct resource *regs_res; struct clk *bus_clk; @@ -947,6 +949,8 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id) void __iomem *regs = sfb->regs; u32 irq_sts_reg; + spin_lock(&sfb->slock); + irq_sts_reg = readl(regs + VIDINTCON1); if (irq_sts_reg & VIDINTCON1_INT_FRAME) { @@ -963,6 +967,7 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id) */ s3c_fb_disable_irq(sfb); + spin_unlock(&sfb->slock); return IRQ_HANDLED; } @@ -1339,6 +1344,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) sfb->pdata = pd; sfb->variant = fbdrv->variant; + spin_lock_init(&sfb->slock); + sfb->bus_clk = clk_get(dev, "lcd"); if (IS_ERR(sfb->bus_clk)) { dev_err(dev, "failed to get bus clock\n"); -- GitLab From 5d9f11cf5038587cc53975deb8beaa1a876a7a7b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 8 Apr 2011 12:07:22 +0000 Subject: [PATCH 0704/5560] ethtool: prevent null pointer dereference with NTUPLE set but no set_rx_ntuple This change is meant to prevent a possible null pointer dereference if NETIF_F_NTUPLE is defined but the set_rx_ntuple function pointer is not. The main motivation behind this patch is to eventually replace the ntuple interfaces entirely with the network flow classifier interfaces. This allows the device drivers to maintain the ntuple check internally while using the network flow classifier interface for setting up and displaying rules. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- net/core/ethtool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 1b7fa984de7d..704e176ad3a9 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -910,6 +910,9 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL; int ret; + if (!ops->set_rx_ntuple) + return -EOPNOTSUPP; + if (!(dev->features & NETIF_F_NTUPLE)) return -EINVAL; -- GitLab From 127fe533ae56d7f4e7b5011869870982eba25723 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 8 Apr 2011 18:01:59 +0000 Subject: [PATCH 0705/5560] v3 ethtool: add ntuple flow specifier data to network flow classifier This change is meant to add an ntuple data extensions to the rx network flow classification specifiers. The idea is to allow ntuple to be displayed via the network flow classification interface. The first patch had some left over stuff from the original flow extension flags I had added. That bit is removed in this patch. The second had some left over comments that stated we ignored bits in the masks when we actually match them. This work is based on input from Ben Hutchings. Signed-off-by: Alexander Duyck Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 53 +++++++++++++++++++++++++---------------- net/socket.c | 14 +++++------ 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c04d1316d221..c7eff13d2f34 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -380,27 +380,42 @@ struct ethtool_usrip4_spec { __u8 proto; }; +union ethtool_flow_union { + struct ethtool_tcpip4_spec tcp_ip4_spec; + struct ethtool_tcpip4_spec udp_ip4_spec; + struct ethtool_tcpip4_spec sctp_ip4_spec; + struct ethtool_ah_espip4_spec ah_ip4_spec; + struct ethtool_ah_espip4_spec esp_ip4_spec; + struct ethtool_usrip4_spec usr_ip4_spec; + struct ethhdr ether_spec; + __u8 hdata[60]; +}; + +struct ethtool_flow_ext { + __be16 vlan_etype; + __be16 vlan_tci; + __be32 data[2]; +}; + /** * struct ethtool_rx_flow_spec - specification for RX flow filter * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW * @h_u: Flow fields to match (dependent on @flow_type) - * @m_u: Masks for flow field bits to be ignored + * @h_ext: Additional fields to match + * @m_u: Masks for flow field bits to be matched + * @m_ext: Masks for additional field bits to be matched + * Note, all additional fields must be ignored unless @flow_type + * includes the %FLOW_EXT flag. * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC * if packets should be discarded * @location: Index of filter in hardware table */ struct ethtool_rx_flow_spec { __u32 flow_type; - union { - struct ethtool_tcpip4_spec tcp_ip4_spec; - struct ethtool_tcpip4_spec udp_ip4_spec; - struct ethtool_tcpip4_spec sctp_ip4_spec; - struct ethtool_ah_espip4_spec ah_ip4_spec; - struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_usrip4_spec usr_ip4_spec; - struct ethhdr ether_spec; - __u8 hdata[72]; - } h_u, m_u; + union ethtool_flow_union h_u; + struct ethtool_flow_ext h_ext; + union ethtool_flow_union m_u; + struct ethtool_flow_ext m_ext; __u64 ring_cookie; __u32 location; }; @@ -458,16 +473,10 @@ struct ethtool_rxnfc { struct compat_ethtool_rx_flow_spec { u32 flow_type; - union { - struct ethtool_tcpip4_spec tcp_ip4_spec; - struct ethtool_tcpip4_spec udp_ip4_spec; - struct ethtool_tcpip4_spec sctp_ip4_spec; - struct ethtool_ah_espip4_spec ah_ip4_spec; - struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_usrip4_spec usr_ip4_spec; - struct ethhdr ether_spec; - u8 hdata[72]; - } h_u, m_u; + union ethtool_flow_union h_u; + struct ethtool_flow_ext h_ext; + union ethtool_flow_union m_u; + struct ethtool_flow_ext m_ext; compat_u64 ring_cookie; u32 location; }; @@ -1072,6 +1081,8 @@ struct ethtool_ops { #define IPV4_FLOW 0x10 /* hash only */ #define IPV6_FLOW 0x11 /* hash only */ #define ETHER_FLOW 0x12 /* spec only (ether_spec) */ +/* Flag to enable additional fields in struct ethtool_rx_flow_spec */ +#define FLOW_EXT 0x80000000 /* L3-L4 network traffic flow hash options */ #define RXH_L2DA (1 << 1) diff --git a/net/socket.c b/net/socket.c index 5212447c86e7..575c84f2af19 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2643,13 +2643,13 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) return -EFAULT; if (convert_in) { - /* We expect there to be holes between fs.m_u and + /* We expect there to be holes between fs.m_ext and * fs.ring_cookie and at the end of fs, but nowhere else. */ - BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_u) + - sizeof(compat_rxnfc->fs.m_u) != - offsetof(struct ethtool_rxnfc, fs.m_u) + - sizeof(rxnfc->fs.m_u)); + BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + + sizeof(compat_rxnfc->fs.m_ext) != + offsetof(struct ethtool_rxnfc, fs.m_ext) + + sizeof(rxnfc->fs.m_ext)); BUILD_BUG_ON( offsetof(struct compat_ethtool_rxnfc, fs.location) - offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != @@ -2657,7 +2657,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) offsetof(struct ethtool_rxnfc, fs.ring_cookie)); if (copy_in_user(rxnfc, compat_rxnfc, - (void *)(&rxnfc->fs.m_u + 1) - + (void *)(&rxnfc->fs.m_ext + 1) - (void *)rxnfc) || copy_in_user(&rxnfc->fs.ring_cookie, &compat_rxnfc->fs.ring_cookie, @@ -2674,7 +2674,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) if (convert_out) { if (copy_in_user(compat_rxnfc, rxnfc, - (const void *)(&rxnfc->fs.m_u + 1) - + (const void *)(&rxnfc->fs.m_ext + 1) - (const void *)rxnfc) || copy_in_user(&compat_rxnfc->fs.ring_cookie, &rxnfc->fs.ring_cookie, -- GitLab From 1b3291241a658fb4d4bbdb41483e1f53c26445ec Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 6 Apr 2011 13:47:50 +0000 Subject: [PATCH 0706/5560] qlge: use ethtool set_phys_id This is a stab at replacing old ethtool phys_id with set_phys_id on the Qlogic 10Gb driver. Compile tested only. Not sure if set_led_cfg will flash continuously, or needs to be replaced by ETHTOOL_ID_ON/ETHTOOL_ID_OFF Signed-off-by: Stephen Hemminger Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_ethtool.c | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 8149cc9de4ca..687754da2a9f 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -412,31 +412,31 @@ static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) return 0; } -static int ql_phys_id(struct net_device *ndev, u32 data) +static int ql_set_phys_id(struct net_device *ndev, + enum ethtool_phys_id_state state) + { struct ql_adapter *qdev = netdev_priv(ndev); - u32 led_reg, i; - int status; - /* Save the current LED settings */ - status = ql_mb_get_led_cfg(qdev); - if (status) - return status; - led_reg = qdev->led_config; + switch (state) { + case ETHTOOL_ID_ACTIVE: + /* Save the current LED settings */ + if (ql_mb_get_led_cfg(qdev)) + return -EIO; - /* Start blinking the led */ - if (!data || data > 300) - data = 300; - - for (i = 0; i < (data * 10); i++) + /* Start blinking */ ql_mb_set_led_cfg(qdev, QL_LED_BLINK); + return 0; - /* Restore LED settings */ - status = ql_mb_set_led_cfg(qdev, led_reg); - if (status) - return status; + case ETHTOOL_ID_INACTIVE: + /* Restore LED settings */ + if (ql_mb_set_led_cfg(qdev, qdev->led_config)) + return -EIO; + return 0; - return 0; + default: + return -EINVAL; + } } static int ql_start_loopback(struct ql_adapter *qdev) @@ -703,7 +703,7 @@ const struct ethtool_ops qlge_ethtool_ops = { .get_msglevel = ql_get_msglevel, .set_msglevel = ql_set_msglevel, .get_link = ethtool_op_get_link, - .phys_id = ql_phys_id, + .set_phys_id = ql_set_phys_id, .self_test = ql_self_test, .get_pauseparam = ql_get_pauseparam, .set_pauseparam = ql_set_pauseparam, -- GitLab From bde3528f17aebb9c74d6b0ef81860868c91af049 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 8 Apr 2011 13:45:11 +0000 Subject: [PATCH 0707/5560] gianfar: Clean up implementation of RX network flow classification This code was cribbed from niu, so gfar_set_hash_opts() begins by converting the ethtool flow class code into a class code for Sun Neptune hardware, then does the same thing again for the hardware it's really dealing with. It may also return -1 (-EPERM) for some unhandled ethtool flow class codes. Remove the useless code and definitions, and fix the error code. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/gianfar.h | 17 ------------ drivers/net/gianfar_ethtool.c | 52 +---------------------------------- 2 files changed, 1 insertion(+), 68 deletions(-) diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index ec5d595ce2e2..57ee3b009d75 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -382,23 +382,6 @@ extern const char gfar_driver_version[]; #define BD_LFLAG(flags) ((flags) << 16) #define BD_LENGTH_MASK 0x0000ffff -#define CLASS_CODE_UNRECOG 0x00 -#define CLASS_CODE_DUMMY1 0x01 -#define CLASS_CODE_ETHERTYPE1 0x02 -#define CLASS_CODE_ETHERTYPE2 0x03 -#define CLASS_CODE_USER_PROG1 0x04 -#define CLASS_CODE_USER_PROG2 0x05 -#define CLASS_CODE_USER_PROG3 0x06 -#define CLASS_CODE_USER_PROG4 0x07 -#define CLASS_CODE_TCP_IPV4 0x08 -#define CLASS_CODE_UDP_IPV4 0x09 -#define CLASS_CODE_AH_ESP_IPV4 0x0a -#define CLASS_CODE_SCTP_IPV4 0x0b -#define CLASS_CODE_TCP_IPV6 0x0c -#define CLASS_CODE_UDP_IPV6 0x0d -#define CLASS_CODE_AH_ESP_IPV6 0x0e -#define CLASS_CODE_SCTP_IPV6 0x0f - #define FPR_FILER_MASK 0xFFFFFFFF #define MAX_FILER_IDX 0xFF diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 3bc8e276ba4d..0840590958dd 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -645,42 +645,6 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) } #endif -static int gfar_ethflow_to_class(int flow_type, u64 *class) -{ - switch (flow_type) { - case TCP_V4_FLOW: - *class = CLASS_CODE_TCP_IPV4; - break; - case UDP_V4_FLOW: - *class = CLASS_CODE_UDP_IPV4; - break; - case AH_V4_FLOW: - case ESP_V4_FLOW: - *class = CLASS_CODE_AH_ESP_IPV4; - break; - case SCTP_V4_FLOW: - *class = CLASS_CODE_SCTP_IPV4; - break; - case TCP_V6_FLOW: - *class = CLASS_CODE_TCP_IPV6; - break; - case UDP_V6_FLOW: - *class = CLASS_CODE_UDP_IPV6; - break; - case AH_V6_FLOW: - case ESP_V6_FLOW: - *class = CLASS_CODE_AH_ESP_IPV6; - break; - case SCTP_V6_FLOW: - *class = CLASS_CODE_SCTP_IPV6; - break; - default: - return 0; - } - - return 1; -} - static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) { u32 fcr = 0x0, fpr = FPR_FILER_MASK; @@ -778,11 +742,6 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u case UDP_V6_FLOW: cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP; break; - case IPV4_FLOW: - cmp_rqfpr = RQFPR_IPV4; - case IPV6_FLOW: - cmp_rqfpr = RQFPR_IPV6; - break; default: printk(KERN_ERR "Right now this class is not supported\n"); return 0; @@ -848,18 +807,9 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) { - u64 class; - - if (!gfar_ethflow_to_class(cmd->flow_type, &class)) - return -EINVAL; - - if (class < CLASS_CODE_USER_PROG1 || - class > CLASS_CODE_SCTP_IPV6) - return -EINVAL; - /* write the filer rules here */ if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) - return -1; + return -EINVAL; return 0; } -- GitLab From c44d79950b2daa1025e62eede73e4e4a274d1ef3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 8 Apr 2011 13:49:15 +0000 Subject: [PATCH 0708/5560] niu: Recognise original ethtool class code for AH/ESP flow hashing When the RX network flow classification interface was originally defined for reporting and controlling of flow hashing, AH and ESP were not given distinct flow class codes (apparently because the Sun Neptune hardware treats them very similarly). For flow steering, they must be distinguished, so new and separate flow class codes were added for AH and ESP. But for backward- compatibility, flow hash operations should continue to support the original class codes. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/niu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index ab4e7dd82d0b..9e6330bc0531 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7022,6 +7022,7 @@ static int niu_ethflow_to_class(int flow_type, u64 *class) case UDP_V4_FLOW: *class = CLASS_CODE_UDP_IPV4; break; + case AH_ESP_V4_FLOW: case AH_V4_FLOW: case ESP_V4_FLOW: *class = CLASS_CODE_AH_ESP_IPV4; @@ -7035,6 +7036,7 @@ static int niu_ethflow_to_class(int flow_type, u64 *class) case UDP_V6_FLOW: *class = CLASS_CODE_UDP_IPV6; break; + case AH_ESP_V6_FLOW: case AH_V6_FLOW: case ESP_V6_FLOW: *class = CLASS_CODE_AH_ESP_IPV6; -- GitLab From b8eeee68dc81f08993ed5dc18dc6d574ba146674 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Sat, 9 Apr 2011 10:57:59 +0900 Subject: [PATCH 0709/5560] ASoC: SAMSUNG: Add WM8580 PCM Machine driver This patch add WM8580 PCM machine driver to support PCM audio on SMDKC110, SMDKV210, SMDK6450, SMDK6440 boards. Playback and Capture supports 8kHz sampling rates. and It is tested on SMDKC110, SMDKV210, SMDK6450 Signed-off-by: Sangbeom Kim Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 8 ++ sound/soc/samsung/Makefile | 2 + sound/soc/samsung/smdk_wm8580pcm.c | 206 +++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 sound/soc/samsung/smdk_wm8580pcm.c diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index a3fdfb631469..b8c7a2e0d21c 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -162,3 +162,11 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF select SND_SAMSUNG_SPDIF help Say Y if you want to add support for SoC S/PDIF audio on the SMDK. + +config SND_SOC_SMDK_WM8580_PCM + tristate "SoC PCM Audio support for WM8580 on SMDK" + depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) + select SND_SOC_WM8580 + select SND_SAMSUNG_PCM + help + Say Y if you want to add support for SoC audio on the SMDK. diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 294dec05c26d..6c598fc51a01 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -34,6 +34,7 @@ snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-goni-wm8994-objs := goni_wm8994.o snd-soc-smdk-spdif-objs := smdk_spdif.o +snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o @@ -51,3 +52,4 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o +obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c new file mode 100644 index 000000000000..0d12092df164 --- /dev/null +++ b/sound/soc/samsung/smdk_wm8580pcm.c @@ -0,0 +1,206 @@ +/* + * sound/soc/samsung/smdk_wm8580pcm.c + * + * Copyright (c) 2011 Samsung Electronics 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 the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include + +#include "../codecs/wm8580.h" +#include "dma.h" +#include "pcm.h" + +/* + * Board Settings: + * o '1' means 'ON' + * o '0' means 'OFF' + * o 'X' means 'Don't care' + * + * SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111 + * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000 + */ + +#define SMDK_WM8580_EXT_OSC 12000000 +#define SMDK_WM8580_EXT_MCLK 4096000 +#define SMDK_WM8580_EXT_VOICE 2048000 + +static unsigned long mclk_freq; +static unsigned long xtal_freq; + +/* + * If MCLK clock directly gets from XTAL, we don't have to use PLL + * to make MCLK, but if XTAL clock source connects with other codec + * pin (like XTI), we should have to set codec's PLL to make MCLK. + * Because Samsung SoC does not support pcmcdclk output like I2S. + */ + +static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int rfs, ret; + + switch (params_rate(params)) { + case 8000: + break; + default: + printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", + __func__, __LINE__, params_rate(params)); + return -EINVAL; + } + + rfs = mclk_freq / params_rate(params) / 2; + + /* Set the codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B + | SND_SOC_DAIFMT_IB_NF + | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* Set the cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B + | SND_SOC_DAIFMT_IB_NF + | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + if (mclk_freq == xtal_freq) { + ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK, + mclk_freq, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, + WM8580_CLKSRC_MCLK); + if (ret < 0) + return ret; + } else { + ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA, + mclk_freq, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, + WM8580_CLKSRC_PLLA); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, + xtal_freq, mclk_freq); + if (ret < 0) + return ret; + } + + /* Set PCM source clock on CPU */ + ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX, + mclk_freq, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* Set SCLK_DIV for making bclk */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops smdk_wm8580_pcm_ops = { + .hw_params = smdk_wm8580_pcm_hw_params, +}; + +static struct snd_soc_dai_link smdk_dai[] = { + { + .name = "WM8580 PAIF PCM RX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-pcm.0", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .ops = &smdk_wm8580_pcm_ops, + }, { + .name = "WM8580 PAIF PCM TX", + .stream_name = "Capture", + .cpu_dai_name = "samsung-pcm.0", + .codec_dai_name = "wm8580-hifi-capture", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .ops = &smdk_wm8580_pcm_ops, + }, +}; + +static struct snd_soc_card smdk_pcm = { + .name = "SMDK-PCM", + .dai_link = smdk_dai, + .num_links = 2, +}; + +/* + * After SMDKC110 Base Board's Rev is '0.1', 12MHz External OSC(X1) + * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4), + * 2.0484Mhz, directly with MCLK both Codec and SoC. + */ +static int __devinit snd_smdk_probe(struct platform_device *pdev) +{ + int ret = 0; + + xtal_freq = SMDK_WM8580_EXT_OSC; + mclk_freq = SMDK_WM8580_EXT_MCLK; + + if (machine_is_smdkc110() || machine_is_smdkv210()) + xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE; + + smdk_pcm.dev = &pdev->dev; + ret = snd_soc_register_card(&smdk_pcm); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); + return ret; + } + + return 0; +} + +static int __devexit snd_smdk_remove(struct platform_device *pdev) +{ + snd_soc_unregister_card(&smdk_pcm); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver snd_smdk_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "samsung-smdk-pcm", + }, + .probe = snd_smdk_probe, + .remove = __devexit_p(snd_smdk_remove), +}; + +static int __init smdk_audio_init(void) +{ + return platform_driver_register(&snd_smdk_driver); +} + +module_init(smdk_audio_init); + +static void __exit smdk_audio_exit(void) +{ + platform_driver_unregister(&snd_smdk_driver); +} + +module_exit(smdk_audio_exit); + +MODULE_AUTHOR("Sangbeom Kim, "); +MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM"); +MODULE_LICENSE("GPL"); -- GitLab From 0671fd8ef4b32200e75396cd299f0853002fc11e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 8 Apr 2011 14:50:44 +0900 Subject: [PATCH 0710/5560] ASoC: Add soc_remove_dai_links card->num_rtd should be 0 after soc_romve_dai_link Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f75f13926049..1f114673e952 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1453,6 +1453,16 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) } } +static void soc_remove_dai_links(struct snd_soc_card *card) +{ + int i; + + for (i = 0; i < card->num_rtd; i++) + soc_remove_dai_link(card, i); + + card->num_rtd = 0; +} + static void soc_set_name_prefix(struct snd_soc_card *card, struct snd_soc_codec *codec) { @@ -1960,8 +1970,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) soc_remove_aux_dev(card, i); probe_dai_err: - for (i = 0; i < card->num_links; i++) - soc_remove_dai_link(card, i); + soc_remove_dai_links(card); card_probe_error: if (card->remove) @@ -2023,8 +2032,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card) soc_remove_aux_dev(card, i); /* remove and free each DAI */ - for (i = 0; i < card->num_rtd; i++) - soc_remove_dai_link(card, i); + soc_remove_dai_links(card); soc_cleanup_card_debugfs(card); -- GitLab From c93993aca45a223452d2a95383b655c85878c6e8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 8 Feb 2011 14:09:41 +0000 Subject: [PATCH 0711/5560] ASoC: Add WM8915 CODEC driver The WM8915 is an ultra low power mobile CODEC designed for smartphones, featuring a mixture of digital and analogue I/O with flexible mixing options and advanced low power accessory detection functionality in a compact package. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/wm8915.h | 55 + sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8915.c | 2925 +++++++++++++++++++++++++++++ sound/soc/codecs/wm8915.h | 3717 +++++++++++++++++++++++++++++++++++++ 5 files changed, 6703 insertions(+) create mode 100644 include/sound/wm8915.h create mode 100644 sound/soc/codecs/wm8915.c create mode 100644 sound/soc/codecs/wm8915.h diff --git a/include/sound/wm8915.h b/include/sound/wm8915.h new file mode 100644 index 000000000000..5817d762f6f3 --- /dev/null +++ b/include/sound/wm8915.h @@ -0,0 +1,55 @@ +/* + * linux/sound/wm8915.h -- Platform data for WM8915 + * + * Copyright 2011 Wolfson Microelectronics. PLC. + * + * 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 __LINUX_SND_WM8903_H +#define __LINUX_SND_WM8903_H + +enum wm8915_inmode { + WM8915_DIFFERRENTIAL_1 = 0, /* IN1xP - IN1xN */ + WM8915_INVERTING = 1, /* IN1xN */ + WM8915_NON_INVERTING = 2, /* IN1xP */ + WM8915_DIFFERENTIAL_2 = 3, /* IN2xP - IN2xP */ +}; + +/** + * ReTune Mobile configurations are specified with a label, sample + * rate and set of values to write (the enable bits will be ignored). + * + * Configurations are expected to be generated using the ReTune Mobile + * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/ + */ +struct wm8915_retune_mobile_config { + const char *name; + int rate; + u16 regs[20]; +}; + +#define WM8915_SET_DEFAULT 0x10000 + +struct wm8915_pdata { + int irq_flags; /** Set IRQ trigger flags; default active low */ + + int ldo_ena; /** GPIO for LDO1; -1 for none */ + + int micdet_def; /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */ + + enum wm8915_inmode inl_mode; + enum wm8915_inmode inr_mode; + + u32 spkmute_seq; /** Value for register 0x802 */ + + int gpio_base; + u32 gpio_default[5]; + + int num_retune_mobile_cfgs; + struct wm8915_retune_mobile_config *retune_mobile_cfgs; +}; + +#endif diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ee7374e8e97e..54d5dd6c63af 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -73,6 +73,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C select SND_SOC_WM8904 if I2C + select SND_SOC_WM8915 if I2C select SND_SOC_WM8940 if I2C select SND_SOC_WM8955 if I2C select SND_SOC_WM8960 if I2C @@ -302,6 +303,9 @@ config SND_SOC_WM8903 config SND_SOC_WM8904 tristate +config SND_SOC_WM8915 + tristate + config SND_SOC_WM8940 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index f030c1826746..02425e6a87e3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -57,6 +57,7 @@ snd-soc-wm8804-objs := wm8804.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8904-objs := wm8904.o +snd-soc-wm8915-objs := wm8915.o snd-soc-wm8940-objs := wm8940.o snd-soc-wm8955-objs := wm8955.o snd-soc-wm8960-objs := wm8960.o @@ -146,6 +147,7 @@ obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o +obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c new file mode 100644 index 000000000000..3adad2872c7e --- /dev/null +++ b/sound/soc/codecs/wm8915.c @@ -0,0 +1,2925 @@ +/* + * wm8915.c - WM8915 audio codec interface + * + * Copyright 2011 Wolfson Microelectronics PLC. + * Author: Mark Brown + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "wm8915.h" + +#define WM8915_AIFS 2 + +#define HPOUT1L 1 +#define HPOUT1R 2 +#define HPOUT2L 4 +#define HPOUT2R 8 + +#define WM8915_NUM_SUPPLIES 6 +static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = { + "DCVDD", + "DBVDD", + "AVDD1", + "AVDD2", + "CPVDD", + "MICVDD", +}; + +struct wm8915_priv { + struct snd_soc_codec *codec; + + int ldo1ena; + + int sysclk; + + int fll_src; + int fll_fref; + int fll_fout; + + struct completion fll_lock; + + u16 dcs_pending; + struct completion dcs_done; + + u16 hpout_ena; + u16 hpout_pending; + + struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES]; + struct notifier_block disable_nb[WM8915_NUM_SUPPLIES]; + + struct wm8915_pdata pdata; + + int rx_rate[WM8915_AIFS]; + + /* Platform dependant ReTune mobile configuration */ + int num_retune_mobile_texts; + const char **retune_mobile_texts; + int retune_mobile_cfg[2]; + struct soc_enum retune_mobile_enum; + + struct snd_soc_jack *jack; + bool detecting; + bool jack_mic; + wm8915_polarity_fn polarity_cb; + +#ifdef CONFIG_GPIOLIB + struct gpio_chip gpio_chip; +#endif +}; + +/* We can't use the same notifier block for more than one supply and + * there's no way I can see to get from a callback to the caller + * except container_of(). + */ +#define WM8915_REGULATOR_EVENT(n) \ +static int wm8915_regulator_event_##n(struct notifier_block *nb, \ + unsigned long event, void *data) \ +{ \ + struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \ + disable_nb[n]); \ + if (event & REGULATOR_EVENT_DISABLE) { \ + wm8915->codec->cache_sync = 1; \ + } \ + return 0; \ +} + +WM8915_REGULATOR_EVENT(0) +WM8915_REGULATOR_EVENT(1) +WM8915_REGULATOR_EVENT(2) +WM8915_REGULATOR_EVENT(3) +WM8915_REGULATOR_EVENT(4) +WM8915_REGULATOR_EVENT(5) + +static const u16 wm8915_reg[WM8915_MAX_REGISTER] = { + [WM8915_SOFTWARE_RESET] = 0x8915, + [WM8915_POWER_MANAGEMENT_7] = 0x10, + [WM8915_DAC1_HPOUT1_VOLUME] = 0x88, + [WM8915_DAC2_HPOUT2_VOLUME] = 0x88, + [WM8915_DAC1_LEFT_VOLUME] = 0x2c0, + [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0, + [WM8915_DAC2_LEFT_VOLUME] = 0x2c0, + [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0, + [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80, + [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80, + [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80, + [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80, + [WM8915_MICBIAS_1] = 0x39, + [WM8915_MICBIAS_2] = 0x39, + [WM8915_LDO_1] = 0x3, + [WM8915_LDO_2] = 0x13, + [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4, + [WM8915_HEADPHONE_DETECT_1] = 0x20, + [WM8915_MIC_DETECT_1] = 0x7600, + [WM8915_MIC_DETECT_2] = 0xbf, + [WM8915_CHARGE_PUMP_1] = 0x1f25, + [WM8915_CHARGE_PUMP_2] = 0xab19, + [WM8915_DC_SERVO_5] = 0x2a2a, + [WM8915_CONTROL_INTERFACE_1] = 0x8004, + [WM8915_CLOCKING_1] = 0x10, + [WM8915_AIF_RATE] = 0x83, + [WM8915_FLL_CONTROL_4] = 0x5dc0, + [WM8915_FLL_CONTROL_5] = 0xc84, + [WM8915_FLL_EFS_2] = 0x2, + [WM8915_AIF1_TX_LRCLK_1] = 0x80, + [WM8915_AIF1_TX_LRCLK_2] = 0x8, + [WM8915_AIF1_RX_LRCLK_1] = 0x80, + [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818, + [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818, + [WM8915_AIF1TX_TEST] = 0x7, + [WM8915_AIF2_TX_LRCLK_1] = 0x80, + [WM8915_AIF2_TX_LRCLK_2] = 0x8, + [WM8915_AIF2_RX_LRCLK_1] = 0x80, + [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818, + [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818, + [WM8915_AIF2TX_TEST] = 0x1, + [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP1_TX_FILTERS] = 0x2000, + [WM8915_DSP1_RX_FILTERS_1] = 0x200, + [WM8915_DSP1_RX_FILTERS_2] = 0x10, + [WM8915_DSP1_DRC_1] = 0x98, + [WM8915_DSP1_DRC_2] = 0x845, + [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318, + [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300, + [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca, + [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400, + [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8, + [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5, + [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145, + [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75, + [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5, + [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58, + [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373, + [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54, + [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558, + [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e, + [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829, + [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad, + [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103, + [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564, + [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559, + [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000, + [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP2_TX_FILTERS] = 0x2000, + [WM8915_DSP2_RX_FILTERS_1] = 0x200, + [WM8915_DSP2_RX_FILTERS_2] = 0x10, + [WM8915_DSP2_DRC_1] = 0x98, + [WM8915_DSP2_DRC_2] = 0x845, + [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318, + [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300, + [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca, + [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400, + [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8, + [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5, + [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145, + [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75, + [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5, + [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58, + [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373, + [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54, + [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558, + [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e, + [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829, + [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad, + [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103, + [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564, + [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559, + [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000, + [WM8915_OVERSAMPLING] = 0xd, + [WM8915_SIDETONE] = 0x1040, + [WM8915_GPIO_1] = 0xa101, + [WM8915_GPIO_2] = 0xa101, + [WM8915_GPIO_3] = 0xa101, + [WM8915_GPIO_4] = 0xa101, + [WM8915_GPIO_5] = 0xa101, + [WM8915_PULL_CONTROL_2] = 0x140, + [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f, + [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf, + [WM8915_RIGHT_PDM_SPEAKER] = 0x1, + [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69, + [WM8915_PDM_SPEAKER_VOLUME] = 0x66, + [WM8915_WRITE_SEQUENCER_0] = 0x1, + [WM8915_WRITE_SEQUENCER_1] = 0x1, + [WM8915_WRITE_SEQUENCER_3] = 0x6, + [WM8915_WRITE_SEQUENCER_4] = 0x40, + [WM8915_WRITE_SEQUENCER_5] = 0x1, + [WM8915_WRITE_SEQUENCER_6] = 0xf, + [WM8915_WRITE_SEQUENCER_7] = 0x6, + [WM8915_WRITE_SEQUENCER_8] = 0x1, + [WM8915_WRITE_SEQUENCER_9] = 0x3, + [WM8915_WRITE_SEQUENCER_10] = 0x104, + [WM8915_WRITE_SEQUENCER_12] = 0x60, + [WM8915_WRITE_SEQUENCER_13] = 0x11, + [WM8915_WRITE_SEQUENCER_14] = 0x401, + [WM8915_WRITE_SEQUENCER_16] = 0x50, + [WM8915_WRITE_SEQUENCER_17] = 0x3, + [WM8915_WRITE_SEQUENCER_18] = 0x100, + [WM8915_WRITE_SEQUENCER_20] = 0x51, + [WM8915_WRITE_SEQUENCER_21] = 0x3, + [WM8915_WRITE_SEQUENCER_22] = 0x104, + [WM8915_WRITE_SEQUENCER_23] = 0xa, + [WM8915_WRITE_SEQUENCER_24] = 0x60, + [WM8915_WRITE_SEQUENCER_25] = 0x3b, + [WM8915_WRITE_SEQUENCER_26] = 0x502, + [WM8915_WRITE_SEQUENCER_27] = 0x100, + [WM8915_WRITE_SEQUENCER_28] = 0x2fff, + [WM8915_WRITE_SEQUENCER_32] = 0x2fff, + [WM8915_WRITE_SEQUENCER_36] = 0x2fff, + [WM8915_WRITE_SEQUENCER_40] = 0x2fff, + [WM8915_WRITE_SEQUENCER_44] = 0x2fff, + [WM8915_WRITE_SEQUENCER_48] = 0x2fff, + [WM8915_WRITE_SEQUENCER_52] = 0x2fff, + [WM8915_WRITE_SEQUENCER_56] = 0x2fff, + [WM8915_WRITE_SEQUENCER_60] = 0x2fff, + [WM8915_WRITE_SEQUENCER_64] = 0x1, + [WM8915_WRITE_SEQUENCER_65] = 0x1, + [WM8915_WRITE_SEQUENCER_67] = 0x6, + [WM8915_WRITE_SEQUENCER_68] = 0x40, + [WM8915_WRITE_SEQUENCER_69] = 0x1, + [WM8915_WRITE_SEQUENCER_70] = 0xf, + [WM8915_WRITE_SEQUENCER_71] = 0x6, + [WM8915_WRITE_SEQUENCER_72] = 0x1, + [WM8915_WRITE_SEQUENCER_73] = 0x3, + [WM8915_WRITE_SEQUENCER_74] = 0x104, + [WM8915_WRITE_SEQUENCER_76] = 0x60, + [WM8915_WRITE_SEQUENCER_77] = 0x11, + [WM8915_WRITE_SEQUENCER_78] = 0x401, + [WM8915_WRITE_SEQUENCER_80] = 0x50, + [WM8915_WRITE_SEQUENCER_81] = 0x3, + [WM8915_WRITE_SEQUENCER_82] = 0x100, + [WM8915_WRITE_SEQUENCER_84] = 0x60, + [WM8915_WRITE_SEQUENCER_85] = 0x3b, + [WM8915_WRITE_SEQUENCER_86] = 0x502, + [WM8915_WRITE_SEQUENCER_87] = 0x100, + [WM8915_WRITE_SEQUENCER_88] = 0x2fff, + [WM8915_WRITE_SEQUENCER_92] = 0x2fff, + [WM8915_WRITE_SEQUENCER_96] = 0x2fff, + [WM8915_WRITE_SEQUENCER_100] = 0x2fff, + [WM8915_WRITE_SEQUENCER_104] = 0x2fff, + [WM8915_WRITE_SEQUENCER_108] = 0x2fff, + [WM8915_WRITE_SEQUENCER_112] = 0x2fff, + [WM8915_WRITE_SEQUENCER_116] = 0x2fff, + [WM8915_WRITE_SEQUENCER_120] = 0x2fff, + [WM8915_WRITE_SEQUENCER_124] = 0x2fff, + [WM8915_WRITE_SEQUENCER_128] = 0x1, + [WM8915_WRITE_SEQUENCER_129] = 0x1, + [WM8915_WRITE_SEQUENCER_131] = 0x6, + [WM8915_WRITE_SEQUENCER_132] = 0x40, + [WM8915_WRITE_SEQUENCER_133] = 0x1, + [WM8915_WRITE_SEQUENCER_134] = 0xf, + [WM8915_WRITE_SEQUENCER_135] = 0x6, + [WM8915_WRITE_SEQUENCER_136] = 0x1, + [WM8915_WRITE_SEQUENCER_137] = 0x3, + [WM8915_WRITE_SEQUENCER_138] = 0x106, + [WM8915_WRITE_SEQUENCER_140] = 0x61, + [WM8915_WRITE_SEQUENCER_141] = 0x11, + [WM8915_WRITE_SEQUENCER_142] = 0x401, + [WM8915_WRITE_SEQUENCER_144] = 0x50, + [WM8915_WRITE_SEQUENCER_145] = 0x3, + [WM8915_WRITE_SEQUENCER_146] = 0x102, + [WM8915_WRITE_SEQUENCER_148] = 0x51, + [WM8915_WRITE_SEQUENCER_149] = 0x3, + [WM8915_WRITE_SEQUENCER_150] = 0x106, + [WM8915_WRITE_SEQUENCER_151] = 0xa, + [WM8915_WRITE_SEQUENCER_152] = 0x61, + [WM8915_WRITE_SEQUENCER_153] = 0x3b, + [WM8915_WRITE_SEQUENCER_154] = 0x502, + [WM8915_WRITE_SEQUENCER_155] = 0x100, + [WM8915_WRITE_SEQUENCER_156] = 0x2fff, + [WM8915_WRITE_SEQUENCER_160] = 0x2fff, + [WM8915_WRITE_SEQUENCER_164] = 0x2fff, + [WM8915_WRITE_SEQUENCER_168] = 0x2fff, + [WM8915_WRITE_SEQUENCER_172] = 0x2fff, + [WM8915_WRITE_SEQUENCER_176] = 0x2fff, + [WM8915_WRITE_SEQUENCER_180] = 0x2fff, + [WM8915_WRITE_SEQUENCER_184] = 0x2fff, + [WM8915_WRITE_SEQUENCER_188] = 0x2fff, + [WM8915_WRITE_SEQUENCER_192] = 0x1, + [WM8915_WRITE_SEQUENCER_193] = 0x1, + [WM8915_WRITE_SEQUENCER_195] = 0x6, + [WM8915_WRITE_SEQUENCER_196] = 0x40, + [WM8915_WRITE_SEQUENCER_197] = 0x1, + [WM8915_WRITE_SEQUENCER_198] = 0xf, + [WM8915_WRITE_SEQUENCER_199] = 0x6, + [WM8915_WRITE_SEQUENCER_200] = 0x1, + [WM8915_WRITE_SEQUENCER_201] = 0x3, + [WM8915_WRITE_SEQUENCER_202] = 0x106, + [WM8915_WRITE_SEQUENCER_204] = 0x61, + [WM8915_WRITE_SEQUENCER_205] = 0x11, + [WM8915_WRITE_SEQUENCER_206] = 0x401, + [WM8915_WRITE_SEQUENCER_208] = 0x50, + [WM8915_WRITE_SEQUENCER_209] = 0x3, + [WM8915_WRITE_SEQUENCER_210] = 0x102, + [WM8915_WRITE_SEQUENCER_212] = 0x61, + [WM8915_WRITE_SEQUENCER_213] = 0x3b, + [WM8915_WRITE_SEQUENCER_214] = 0x502, + [WM8915_WRITE_SEQUENCER_215] = 0x100, + [WM8915_WRITE_SEQUENCER_216] = 0x2fff, + [WM8915_WRITE_SEQUENCER_220] = 0x2fff, + [WM8915_WRITE_SEQUENCER_224] = 0x2fff, + [WM8915_WRITE_SEQUENCER_228] = 0x2fff, + [WM8915_WRITE_SEQUENCER_232] = 0x2fff, + [WM8915_WRITE_SEQUENCER_236] = 0x2fff, + [WM8915_WRITE_SEQUENCER_240] = 0x2fff, + [WM8915_WRITE_SEQUENCER_244] = 0x2fff, + [WM8915_WRITE_SEQUENCER_248] = 0x2fff, + [WM8915_WRITE_SEQUENCER_252] = 0x2fff, + [WM8915_WRITE_SEQUENCER_256] = 0x60, + [WM8915_WRITE_SEQUENCER_258] = 0x601, + [WM8915_WRITE_SEQUENCER_260] = 0x50, + [WM8915_WRITE_SEQUENCER_262] = 0x100, + [WM8915_WRITE_SEQUENCER_264] = 0x1, + [WM8915_WRITE_SEQUENCER_266] = 0x104, + [WM8915_WRITE_SEQUENCER_267] = 0x100, + [WM8915_WRITE_SEQUENCER_268] = 0x2fff, + [WM8915_WRITE_SEQUENCER_272] = 0x2fff, + [WM8915_WRITE_SEQUENCER_276] = 0x2fff, + [WM8915_WRITE_SEQUENCER_280] = 0x2fff, + [WM8915_WRITE_SEQUENCER_284] = 0x2fff, + [WM8915_WRITE_SEQUENCER_288] = 0x2fff, + [WM8915_WRITE_SEQUENCER_292] = 0x2fff, + [WM8915_WRITE_SEQUENCER_296] = 0x2fff, + [WM8915_WRITE_SEQUENCER_300] = 0x2fff, + [WM8915_WRITE_SEQUENCER_304] = 0x2fff, + [WM8915_WRITE_SEQUENCER_308] = 0x2fff, + [WM8915_WRITE_SEQUENCER_312] = 0x2fff, + [WM8915_WRITE_SEQUENCER_316] = 0x2fff, + [WM8915_WRITE_SEQUENCER_320] = 0x61, + [WM8915_WRITE_SEQUENCER_322] = 0x601, + [WM8915_WRITE_SEQUENCER_324] = 0x50, + [WM8915_WRITE_SEQUENCER_326] = 0x102, + [WM8915_WRITE_SEQUENCER_328] = 0x1, + [WM8915_WRITE_SEQUENCER_330] = 0x106, + [WM8915_WRITE_SEQUENCER_331] = 0x100, + [WM8915_WRITE_SEQUENCER_332] = 0x2fff, + [WM8915_WRITE_SEQUENCER_336] = 0x2fff, + [WM8915_WRITE_SEQUENCER_340] = 0x2fff, + [WM8915_WRITE_SEQUENCER_344] = 0x2fff, + [WM8915_WRITE_SEQUENCER_348] = 0x2fff, + [WM8915_WRITE_SEQUENCER_352] = 0x2fff, + [WM8915_WRITE_SEQUENCER_356] = 0x2fff, + [WM8915_WRITE_SEQUENCER_360] = 0x2fff, + [WM8915_WRITE_SEQUENCER_364] = 0x2fff, + [WM8915_WRITE_SEQUENCER_368] = 0x2fff, + [WM8915_WRITE_SEQUENCER_372] = 0x2fff, + [WM8915_WRITE_SEQUENCER_376] = 0x2fff, + [WM8915_WRITE_SEQUENCER_380] = 0x2fff, + [WM8915_WRITE_SEQUENCER_384] = 0x60, + [WM8915_WRITE_SEQUENCER_386] = 0x601, + [WM8915_WRITE_SEQUENCER_388] = 0x61, + [WM8915_WRITE_SEQUENCER_390] = 0x601, + [WM8915_WRITE_SEQUENCER_392] = 0x50, + [WM8915_WRITE_SEQUENCER_394] = 0x300, + [WM8915_WRITE_SEQUENCER_396] = 0x1, + [WM8915_WRITE_SEQUENCER_398] = 0x304, + [WM8915_WRITE_SEQUENCER_400] = 0x40, + [WM8915_WRITE_SEQUENCER_402] = 0xf, + [WM8915_WRITE_SEQUENCER_404] = 0x1, + [WM8915_WRITE_SEQUENCER_407] = 0x100, +}; + +static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); +static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0); +static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0); +static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); +static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); +static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); + +static const char *sidetone_hpf_text[] = { + "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" +}; + +static const struct soc_enum sidetone_hpf = + SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text); + +static const char *hpf_mode_text[] = { + "HiFi", "Custom", "Voice" +}; + +static const struct soc_enum dsp1tx_hpf_mode = + SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text); + +static const struct soc_enum dsp2tx_hpf_mode = + SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text); + +static const char *hpf_cutoff_text[] = { + "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" +}; + +static const struct soc_enum dsp1tx_hpf_cutoff = + SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text); + +static const struct soc_enum dsp2tx_hpf_cutoff = + SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text); + +static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct wm8915_pdata *pdata = &wm8915->pdata; + int base, best, best_val, save, i, cfg, iface; + + if (!wm8915->num_retune_mobile_texts) + return; + + switch (block) { + case 0: + base = WM8915_DSP1_RX_EQ_GAINS_1; + if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) & + WM8915_DSP1RX_SRC) + iface = 1; + else + iface = 0; + break; + case 1: + base = WM8915_DSP1_RX_EQ_GAINS_2; + if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) & + WM8915_DSP2RX_SRC) + iface = 1; + else + iface = 0; + break; + default: + return; + } + + /* Find the version of the currently selected configuration + * with the nearest sample rate. */ + cfg = wm8915->retune_mobile_cfg[block]; + best = 0; + best_val = INT_MAX; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8915->retune_mobile_texts[cfg]) == 0 && + abs(pdata->retune_mobile_cfgs[i].rate + - wm8915->rx_rate[iface]) < best_val) { + best = i; + best_val = abs(pdata->retune_mobile_cfgs[i].rate + - wm8915->rx_rate[iface]); + } + } + + dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n", + block, + pdata->retune_mobile_cfgs[best].name, + pdata->retune_mobile_cfgs[best].rate, + wm8915->rx_rate[iface]); + + /* The EQ will be disabled while reconfiguring it, remember the + * current configuration. + */ + save = snd_soc_read(codec, base); + save &= WM8915_DSP1RX_EQ_ENA; + + for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++) + snd_soc_update_bits(codec, base + i, 0xffff, + pdata->retune_mobile_cfgs[best].regs[i]); + + snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save); +} + +/* Icky as hell but saves code duplication */ +static int wm8915_get_retune_mobile_block(const char *name) +{ + if (strcmp(name, "DSP1 EQ Mode") == 0) + return 0; + if (strcmp(name, "DSP2 EQ Mode") == 0) + return 1; + return -EINVAL; +} + +static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct wm8915_pdata *pdata = &wm8915->pdata; + int block = wm8915_get_retune_mobile_block(kcontrol->id.name); + int value = ucontrol->value.integer.value[0]; + + if (block < 0) + return block; + + if (value >= pdata->num_retune_mobile_cfgs) + return -EINVAL; + + wm8915->retune_mobile_cfg[block] = value; + + wm8915_set_retune_mobile(codec, block); + + return 0; +} + +static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int block = wm8915_get_retune_mobile_block(kcontrol->id.name); + + ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block]; + + return 0; +} + +static const struct snd_kcontrol_new wm8915_snd_controls[] = { +SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME, + WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv), +SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME, + WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0), + +SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES, + 0, 5, 24, 0, sidetone_tlv), +SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES, + 0, 5, 24, 0, sidetone_tlv), +SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0), +SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf), +SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0), + +SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME, + WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv), +SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME, + WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv), + +SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS, + 13, 1, 0), +SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0), +SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode), +SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff), + +SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS, + 13, 1, 0), +SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0), +SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode), +SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff), + +SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME, + WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME, + WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME, + WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME, + WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME, + WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME, + WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1), + +SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0), +SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0), +SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0), +SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0), + +SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0), +SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0), + +SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4, + 8, 0, out_digital_tlv), +SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4, + 8, 0, out_digital_tlv), + +SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME, + WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv), +SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME, + WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0), + +SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME, + WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv), +SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME, + WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0), + +SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0, + spk_tlv), +SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER, + WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1), +SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER, + WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0), + +SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0), +SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0), +}; + +static const struct snd_kcontrol_new wm8915_eq_controls[] = { +SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0, + eq_tlv), + +SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0, + eq_tlv), +}; + +static int cp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msleep(5); + break; + default: + BUG(); + return -EINVAL; + } + + return 0; +} + +static int rmv_short_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec); + + /* Record which outputs we enabled */ + switch (event) { + case SND_SOC_DAPM_PRE_PMD: + wm8915->hpout_pending &= ~w->shift; + break; + case SND_SOC_DAPM_PRE_PMU: + wm8915->hpout_pending |= w->shift; + break; + default: + BUG(); + return -EINVAL; + } + + return 0; +} + +static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask) +{ + struct i2c_client *i2c = to_i2c_client(codec->dev); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int i, ret; + unsigned long timeout = 200; + + snd_soc_write(codec, WM8915_DC_SERVO_2, mask); + + /* Use the interrupt if possible */ + do { + if (i2c->irq) { + timeout = wait_for_completion_timeout(&wm8915->dcs_done, + msecs_to_jiffies(200)); + if (timeout == 0) + dev_err(codec->dev, "DC servo timed out\n"); + + } else { + msleep(1); + if (--i) { + timeout = 0; + break; + } + } + + ret = snd_soc_read(codec, WM8915_DC_SERVO_2); + dev_dbg(codec->dev, "DC servo state: %x\n", ret); + } while (ret & mask); + + if (timeout == 0) + dev_err(codec->dev, "DC servo timed out for %x\n", mask); + else + dev_dbg(codec->dev, "DC servo complete for %x\n", mask); +} + +static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm, + enum snd_soc_dapm_type event, int subseq) +{ + struct snd_soc_codec *codec = container_of(dapm, + struct snd_soc_codec, dapm); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + u16 val, mask; + + /* Complete any pending DC servo starts */ + if (wm8915->dcs_pending) { + dev_dbg(codec->dev, "Starting DC servo for %x\n", + wm8915->dcs_pending); + + /* Trigger a startup sequence */ + wait_for_dc_servo(codec, wm8915->dcs_pending + << WM8915_DCS_TRIG_STARTUP_0_SHIFT); + + wm8915->dcs_pending = 0; + } + + if (wm8915->hpout_pending != wm8915->hpout_ena) { + dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n", + wm8915->hpout_ena, wm8915->hpout_pending); + + val = 0; + mask = 0; + if (wm8915->hpout_pending & HPOUT1L) { + val |= WM8915_HPOUT1L_RMV_SHORT; + mask |= WM8915_HPOUT1L_RMV_SHORT; + } else { + mask |= WM8915_HPOUT1L_RMV_SHORT | + WM8915_HPOUT1L_OUTP | + WM8915_HPOUT1L_DLY; + } + + if (wm8915->hpout_pending & HPOUT1R) { + val |= WM8915_HPOUT1R_RMV_SHORT; + mask |= WM8915_HPOUT1R_RMV_SHORT; + } else { + mask |= WM8915_HPOUT1R_RMV_SHORT | + WM8915_HPOUT1R_OUTP | + WM8915_HPOUT1R_DLY; + } + + snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val); + + val = 0; + mask = 0; + if (wm8915->hpout_pending & HPOUT2L) { + val |= WM8915_HPOUT2L_RMV_SHORT; + mask |= WM8915_HPOUT2L_RMV_SHORT; + } else { + mask |= WM8915_HPOUT2L_RMV_SHORT | + WM8915_HPOUT2L_OUTP | + WM8915_HPOUT2L_DLY; + } + + if (wm8915->hpout_pending & HPOUT2R) { + val |= WM8915_HPOUT2R_RMV_SHORT; + mask |= WM8915_HPOUT2R_RMV_SHORT; + } else { + mask |= WM8915_HPOUT2R_RMV_SHORT | + WM8915_HPOUT2R_OUTP | + WM8915_HPOUT2R_DLY; + } + + snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val); + + wm8915->hpout_ena = wm8915->hpout_pending; + } +} + +static int dcs_start(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + wm8915->dcs_pending |= 1 << w->shift; + break; + default: + BUG(); + return -EINVAL; + } + + return 0; +} + +static const char *sidetone_text[] = { + "IN1", "IN2", +}; + +static const struct soc_enum left_sidetone_enum = + SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text); + +static const struct snd_kcontrol_new left_sidetone = + SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum); + +static const struct soc_enum right_sidetone_enum = + SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text); + +static const struct snd_kcontrol_new right_sidetone = + SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum); + +static const char *spk_text[] = { + "DAC1L", "DAC1R", "DAC2L", "DAC2R" +}; + +static const struct soc_enum spkl_enum = + SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text); + +static const struct snd_kcontrol_new spkl_mux = + SOC_DAPM_ENUM("SPKL", spkl_enum); + +static const struct soc_enum spkr_enum = + SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text); + +static const struct snd_kcontrol_new spkr_mux = + SOC_DAPM_ENUM("SPKR", spkr_enum); + +static const char *dsp1rx_text[] = { + "AIF1", "AIF2" +}; + +static const struct soc_enum dsp1rx_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text); + +static const struct snd_kcontrol_new dsp1rx = + SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum); + +static const char *dsp2rx_text[] = { + "AIF2", "AIF1" +}; + +static const struct soc_enum dsp2rx_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text); + +static const struct snd_kcontrol_new dsp2rx = + SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum); + +static const char *aif2tx_text[] = { + "DSP2", "DSP1", "AIF1" +}; + +static const struct soc_enum aif2tx_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text); + +static const struct snd_kcontrol_new aif2tx = + SOC_DAPM_ENUM("AIF2TX", aif2tx_enum); + +static const char *inmux_text[] = { + "ADC", "DMIC1", "DMIC2" +}; + +static const struct soc_enum in1_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text); + +static const struct snd_kcontrol_new in1_mux = + SOC_DAPM_ENUM("IN1 Mux", in1_enum); + +static const struct soc_enum in2_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text); + +static const struct snd_kcontrol_new in2_mux = + SOC_DAPM_ENUM("IN2 Mux", in2_enum); + +static const struct snd_kcontrol_new dac2r_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac2l_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac1r_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac1l_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp1txl[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp1txr[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp2txl[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp2txr[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + + +static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("IN1LN"), +SND_SOC_DAPM_INPUT("IN1LP"), +SND_SOC_DAPM_INPUT("IN1RN"), +SND_SOC_DAPM_INPUT("IN1RP"), + +SND_SOC_DAPM_INPUT("IN2LN"), +SND_SOC_DAPM_INPUT("IN2LP"), +SND_SOC_DAPM_INPUT("IN2RN"), +SND_SOC_DAPM_INPUT("IN2RP"), + +SND_SOC_DAPM_INPUT("DMIC1DAT"), +SND_SOC_DAPM_INPUT("DMIC2DAT"), + +SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event, + SND_SOC_DAPM_POST_PMU), + +SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0), +SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0), +SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0), + +SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0), + +SND_SOC_DAPM_PGA("ADC", SND_SOC_NOPM, 0, 0, NULL, 0), + +SND_SOC_DAPM_MUX("IN1 Mux", SND_SOC_NOPM, 0, 0, &in1_mux), +SND_SOC_DAPM_MUX("IN2 Mux", SND_SOC_NOPM, 0, 0, &in2_mux), + +SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0), + +/* FIXME - these need to be concentrator widgets */ +SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0), + +SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0), +SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0), +SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0), +SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0), + +SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0), +SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0), + +SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone), +SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone), + +SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0), +SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0), +SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0), +SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0), + +SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0, + dsp2txl, ARRAY_SIZE(dsp2txl)), +SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0, + dsp2txr, ARRAY_SIZE(dsp2txr)), +SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0, + dsp1txl, ARRAY_SIZE(dsp1txl)), +SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0, + dsp1txr, ARRAY_SIZE(dsp1txr)), + +SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0, + dac2l_mix, ARRAY_SIZE(dac2l_mix)), +SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0, + dac2r_mix, ARRAY_SIZE(dac2r_mix)), +SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, + dac1l_mix, ARRAY_SIZE(dac1l_mix)), +SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, + dac1r_mix, ARRAY_SIZE(dac1r_mix)), + +SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0), +SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0), +SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0), +SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0), + +SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, + WM8915_POWER_MANAGEMENT_4, 9, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, + WM8915_POWER_MANAGEMENT_4, 8, 0), + +SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, + WM8915_POWER_MANAGEMENT_6, 9, 0), +SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, + WM8915_POWER_MANAGEMENT_6, 8, 0), + +SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, + WM8915_POWER_MANAGEMENT_4, 5, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, + WM8915_POWER_MANAGEMENT_4, 4, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, + WM8915_POWER_MANAGEMENT_4, 3, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, + WM8915_POWER_MANAGEMENT_4, 2, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, + WM8915_POWER_MANAGEMENT_4, 1, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0, + WM8915_POWER_MANAGEMENT_4, 0, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5, + WM8915_POWER_MANAGEMENT_6, 5, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4, + WM8915_POWER_MANAGEMENT_6, 4, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3, + WM8915_POWER_MANAGEMENT_6, 3, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2, + WM8915_POWER_MANAGEMENT_6, 2, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1, + WM8915_POWER_MANAGEMENT_6, 1, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0, + WM8915_POWER_MANAGEMENT_6, 0, 0), + +/* We route as stereo pairs so define some dummy widgets to squash + * things down for now. RXA = 0,1, RXB = 2,3 and so on */ +SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0), + +SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx), +SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx), +SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx), + +SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux), +SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux), +SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0), + +SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_OUTPUT("HPOUT1L"), +SND_SOC_DAPM_OUTPUT("HPOUT1R"), +SND_SOC_DAPM_OUTPUT("HPOUT2L"), +SND_SOC_DAPM_OUTPUT("HPOUT2R"), +SND_SOC_DAPM_OUTPUT("SPKDAT"), +}; + +static const struct snd_soc_dapm_route wm8915_dapm_routes[] = { + { "AIFCLK", NULL, "SYSCLK" }, + { "SYSDSPCLK", NULL, "SYSCLK" }, + { "Charge Pump", NULL, "SYSCLK" }, + + { "MICB1", NULL, "LDO2" }, + { "MICB2", NULL, "LDO2" }, + + { "IN1L PGA", NULL, "IN2LN" }, + { "IN1L PGA", NULL, "IN2LP" }, + { "IN1L PGA", NULL, "IN1LN" }, + { "IN1L PGA", NULL, "IN1LP" }, + + { "IN1R PGA", NULL, "IN2RN" }, + { "IN1R PGA", NULL, "IN2RP" }, + { "IN1R PGA", NULL, "IN1RN" }, + { "IN1R PGA", NULL, "IN1RP" }, + + { "ADCL", NULL, "IN1L PGA" }, + + { "ADCR", NULL, "IN1R PGA" }, + + { "DMIC1L", NULL, "DMIC1DAT" }, + { "DMIC1R", NULL, "DMIC1DAT" }, + { "DMIC2L", NULL, "DMIC2DAT" }, + { "DMIC2R", NULL, "DMIC2DAT" }, + + { "DMIC2L", NULL, "DMIC2" }, + { "DMIC2R", NULL, "DMIC2" }, + { "DMIC1L", NULL, "DMIC1" }, + { "DMIC1R", NULL, "DMIC1" }, + + { "ADC", NULL, "ADCL" }, + { "ADC", NULL, "ADCR" }, + + { "IN1 Mux", "ADC", "ADC" }, + { "IN1 Mux", "DMIC1", "DMIC1" }, + { "IN1 Mux", "DMIC2", "DMIC2" }, + + { "IN2 Mux", "ADC", "ADC" }, + { "IN2 Mux", "DMIC1", "DMIC1" }, + { "IN2 Mux", "DMIC2", "DMIC2" }, + + { "Left Sidetone", "IN1", "IN1 Mux" }, + { "Left Sidetone", "IN2", "IN2 Mux" }, + + { "Right Sidetone", "IN1", "IN1 Mux" }, + { "Right Sidetone", "IN2", "IN2 Mux" }, + + { "DSP1TXL", "IN1 Switch", "IN1 Mux" }, + { "DSP1TXR", "IN1 Switch", "IN1 Mux" }, + + { "DSP2TXL", "IN1 Switch", "IN2 Mux" }, + { "DSP2TXR", "IN1 Switch", "IN2 Mux" }, + + { "AIF1TX0", NULL, "DSP1TXL" }, + { "AIF1TX1", NULL, "DSP1TXR" }, + { "AIF1TX2", NULL, "DSP2TXL" }, + { "AIF1TX3", NULL, "DSP2TXR" }, + { "AIF1TX4", NULL, "AIF2RX0" }, + { "AIF1TX5", NULL, "AIF2RX1" }, + + { "AIF1RX0", NULL, "AIFCLK" }, + { "AIF1RX1", NULL, "AIFCLK" }, + { "AIF1RX2", NULL, "AIFCLK" }, + { "AIF1RX3", NULL, "AIFCLK" }, + { "AIF1RX4", NULL, "AIFCLK" }, + { "AIF1RX5", NULL, "AIFCLK" }, + + { "AIF2RX0", NULL, "AIFCLK" }, + { "AIF2RX1", NULL, "AIFCLK" }, + + { "DSP1RXL", NULL, "SYSDSPCLK" }, + { "DSP1RXR", NULL, "SYSDSPCLK" }, + { "DSP2RXL", NULL, "SYSDSPCLK" }, + { "DSP2RXR", NULL, "SYSDSPCLK" }, + { "DSP1TXL", NULL, "SYSDSPCLK" }, + { "DSP1TXR", NULL, "SYSDSPCLK" }, + { "DSP2TXL", NULL, "SYSDSPCLK" }, + { "DSP2TXR", NULL, "SYSDSPCLK" }, + + { "AIF1RXA", NULL, "AIF1RX0" }, + { "AIF1RXA", NULL, "AIF1RX1" }, + { "AIF1RXB", NULL, "AIF1RX2" }, + { "AIF1RXB", NULL, "AIF1RX3" }, + { "AIF1RXC", NULL, "AIF1RX4" }, + { "AIF1RXC", NULL, "AIF1RX5" }, + + { "AIF2RX", NULL, "AIF2RX0" }, + { "AIF2RX", NULL, "AIF2RX1" }, + + { "AIF2TX", "DSP2", "DSP2TX" }, + { "AIF2TX", "DSP1", "DSP1RX" }, + { "AIF2TX", "AIF1", "AIF1RXC" }, + + { "DSP1RXL", NULL, "DSP1RX" }, + { "DSP1RXR", NULL, "DSP1RX" }, + { "DSP2RXL", NULL, "DSP2RX" }, + { "DSP2RXR", NULL, "DSP2RX" }, + + { "DSP2TX", NULL, "DSP2TXL" }, + { "DSP2TX", NULL, "DSP2TXR" }, + + { "DSP1RX", "AIF1", "AIF1RXA" }, + { "DSP1RX", "AIF2", "AIF2RX" }, + + { "DSP2RX", "AIF1", "AIF1RXB" }, + { "DSP2RX", "AIF2", "AIF2RX" }, + + { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" }, + { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" }, + { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" }, + { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" }, + { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" }, + { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" }, + { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" }, + { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" }, + { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC1L", NULL, "DAC1L Mixer" }, + { "DAC1R", NULL, "DAC1R Mixer" }, + { "DAC2L", NULL, "DAC2L Mixer" }, + { "DAC2R", NULL, "DAC2R Mixer" }, + + { "HPOUT2L PGA", NULL, "Charge Pump" }, + { "HPOUT2L PGA", NULL, "DAC2L" }, + { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, + { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, + { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, + { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, + + { "HPOUT2R PGA", NULL, "Charge Pump" }, + { "HPOUT2R PGA", NULL, "DAC2R" }, + { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, + { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, + { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, + { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, + + { "HPOUT1L PGA", NULL, "Charge Pump" }, + { "HPOUT1L PGA", NULL, "DAC1L" }, + { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, + { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, + { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, + { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, + + { "HPOUT1R PGA", NULL, "Charge Pump" }, + { "HPOUT1R PGA", NULL, "DAC1R" }, + { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, + { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, + { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, + { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" }, + + { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, + { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, + { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" }, + { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" }, + + { "SPKL", "DAC1L", "DAC1L" }, + { "SPKL", "DAC1R", "DAC1R" }, + { "SPKL", "DAC2L", "DAC2L" }, + { "SPKL", "DAC2R", "DAC2R" }, + + { "SPKR", "DAC1L", "DAC1L" }, + { "SPKR", "DAC1R", "DAC1R" }, + { "SPKR", "DAC2L", "DAC2L" }, + { "SPKR", "DAC2R", "DAC2R" }, + + { "SPKL PGA", NULL, "SPKL" }, + { "SPKR PGA", NULL, "SPKR" }, + + { "SPKDAT", NULL, "SPKL PGA" }, + { "SPKDAT", NULL, "SPKR PGA" }, +}; + +static int wm8915_readable_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + /* Due to the sparseness of the register map the compiler + * output from an explicit switch statement ends up being much + * more efficient than a table. + */ + switch (reg) { + case WM8915_SOFTWARE_RESET: + case WM8915_POWER_MANAGEMENT_1: + case WM8915_POWER_MANAGEMENT_2: + case WM8915_POWER_MANAGEMENT_3: + case WM8915_POWER_MANAGEMENT_4: + case WM8915_POWER_MANAGEMENT_5: + case WM8915_POWER_MANAGEMENT_6: + case WM8915_POWER_MANAGEMENT_7: + case WM8915_POWER_MANAGEMENT_8: + case WM8915_LEFT_LINE_INPUT_VOLUME: + case WM8915_RIGHT_LINE_INPUT_VOLUME: + case WM8915_LINE_INPUT_CONTROL: + case WM8915_DAC1_HPOUT1_VOLUME: + case WM8915_DAC2_HPOUT2_VOLUME: + case WM8915_DAC1_LEFT_VOLUME: + case WM8915_DAC1_RIGHT_VOLUME: + case WM8915_DAC2_LEFT_VOLUME: + case WM8915_DAC2_RIGHT_VOLUME: + case WM8915_OUTPUT1_LEFT_VOLUME: + case WM8915_OUTPUT1_RIGHT_VOLUME: + case WM8915_OUTPUT2_LEFT_VOLUME: + case WM8915_OUTPUT2_RIGHT_VOLUME: + case WM8915_MICBIAS_1: + case WM8915_MICBIAS_2: + case WM8915_LDO_1: + case WM8915_LDO_2: + case WM8915_ACCESSORY_DETECT_MODE_1: + case WM8915_ACCESSORY_DETECT_MODE_2: + case WM8915_HEADPHONE_DETECT_1: + case WM8915_HEADPHONE_DETECT_2: + case WM8915_MIC_DETECT_1: + case WM8915_MIC_DETECT_2: + case WM8915_MIC_DETECT_3: + case WM8915_CHARGE_PUMP_1: + case WM8915_CHARGE_PUMP_2: + case WM8915_DC_SERVO_1: + case WM8915_DC_SERVO_2: + case WM8915_DC_SERVO_3: + case WM8915_DC_SERVO_5: + case WM8915_DC_SERVO_6: + case WM8915_DC_SERVO_7: + case WM8915_DC_SERVO_READBACK_0: + case WM8915_ANALOGUE_HP_1: + case WM8915_ANALOGUE_HP_2: + case WM8915_CHIP_REVISION: + case WM8915_CONTROL_INTERFACE_1: + case WM8915_WRITE_SEQUENCER_CTRL_1: + case WM8915_WRITE_SEQUENCER_CTRL_2: + case WM8915_AIF_CLOCKING_1: + case WM8915_AIF_CLOCKING_2: + case WM8915_CLOCKING_1: + case WM8915_CLOCKING_2: + case WM8915_AIF_RATE: + case WM8915_FLL_CONTROL_1: + case WM8915_FLL_CONTROL_2: + case WM8915_FLL_CONTROL_3: + case WM8915_FLL_CONTROL_4: + case WM8915_FLL_CONTROL_5: + case WM8915_FLL_CONTROL_6: + case WM8915_FLL_EFS_1: + case WM8915_FLL_EFS_2: + case WM8915_AIF1_CONTROL: + case WM8915_AIF1_BCLK: + case WM8915_AIF1_TX_LRCLK_1: + case WM8915_AIF1_TX_LRCLK_2: + case WM8915_AIF1_RX_LRCLK_1: + case WM8915_AIF1_RX_LRCLK_2: + case WM8915_AIF1TX_DATA_CONFIGURATION_1: + case WM8915_AIF1TX_DATA_CONFIGURATION_2: + case WM8915_AIF1RX_DATA_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION: + case WM8915_AIF1RX_MONO_CONFIGURATION: + case WM8915_AIF1TX_TEST: + case WM8915_AIF2_CONTROL: + case WM8915_AIF2_BCLK: + case WM8915_AIF2_TX_LRCLK_1: + case WM8915_AIF2_TX_LRCLK_2: + case WM8915_AIF2_RX_LRCLK_1: + case WM8915_AIF2_RX_LRCLK_2: + case WM8915_AIF2TX_DATA_CONFIGURATION_1: + case WM8915_AIF2TX_DATA_CONFIGURATION_2: + case WM8915_AIF2RX_DATA_CONFIGURATION: + case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF2RX_MONO_CONFIGURATION: + case WM8915_AIF2TX_TEST: + case WM8915_DSP1_TX_LEFT_VOLUME: + case WM8915_DSP1_TX_RIGHT_VOLUME: + case WM8915_DSP1_RX_LEFT_VOLUME: + case WM8915_DSP1_RX_RIGHT_VOLUME: + case WM8915_DSP1_TX_FILTERS: + case WM8915_DSP1_RX_FILTERS_1: + case WM8915_DSP1_RX_FILTERS_2: + case WM8915_DSP1_DRC_1: + case WM8915_DSP1_DRC_2: + case WM8915_DSP1_DRC_3: + case WM8915_DSP1_DRC_4: + case WM8915_DSP1_DRC_5: + case WM8915_DSP1_RX_EQ_GAINS_1: + case WM8915_DSP1_RX_EQ_GAINS_2: + case WM8915_DSP1_RX_EQ_BAND_1_A: + case WM8915_DSP1_RX_EQ_BAND_1_B: + case WM8915_DSP1_RX_EQ_BAND_1_PG: + case WM8915_DSP1_RX_EQ_BAND_2_A: + case WM8915_DSP1_RX_EQ_BAND_2_B: + case WM8915_DSP1_RX_EQ_BAND_2_C: + case WM8915_DSP1_RX_EQ_BAND_2_PG: + case WM8915_DSP1_RX_EQ_BAND_3_A: + case WM8915_DSP1_RX_EQ_BAND_3_B: + case WM8915_DSP1_RX_EQ_BAND_3_C: + case WM8915_DSP1_RX_EQ_BAND_3_PG: + case WM8915_DSP1_RX_EQ_BAND_4_A: + case WM8915_DSP1_RX_EQ_BAND_4_B: + case WM8915_DSP1_RX_EQ_BAND_4_C: + case WM8915_DSP1_RX_EQ_BAND_4_PG: + case WM8915_DSP1_RX_EQ_BAND_5_A: + case WM8915_DSP1_RX_EQ_BAND_5_B: + case WM8915_DSP1_RX_EQ_BAND_5_PG: + case WM8915_DSP2_TX_LEFT_VOLUME: + case WM8915_DSP2_TX_RIGHT_VOLUME: + case WM8915_DSP2_RX_LEFT_VOLUME: + case WM8915_DSP2_RX_RIGHT_VOLUME: + case WM8915_DSP2_TX_FILTERS: + case WM8915_DSP2_RX_FILTERS_1: + case WM8915_DSP2_RX_FILTERS_2: + case WM8915_DSP2_DRC_1: + case WM8915_DSP2_DRC_2: + case WM8915_DSP2_DRC_3: + case WM8915_DSP2_DRC_4: + case WM8915_DSP2_DRC_5: + case WM8915_DSP2_RX_EQ_GAINS_1: + case WM8915_DSP2_RX_EQ_GAINS_2: + case WM8915_DSP2_RX_EQ_BAND_1_A: + case WM8915_DSP2_RX_EQ_BAND_1_B: + case WM8915_DSP2_RX_EQ_BAND_1_PG: + case WM8915_DSP2_RX_EQ_BAND_2_A: + case WM8915_DSP2_RX_EQ_BAND_2_B: + case WM8915_DSP2_RX_EQ_BAND_2_C: + case WM8915_DSP2_RX_EQ_BAND_2_PG: + case WM8915_DSP2_RX_EQ_BAND_3_A: + case WM8915_DSP2_RX_EQ_BAND_3_B: + case WM8915_DSP2_RX_EQ_BAND_3_C: + case WM8915_DSP2_RX_EQ_BAND_3_PG: + case WM8915_DSP2_RX_EQ_BAND_4_A: + case WM8915_DSP2_RX_EQ_BAND_4_B: + case WM8915_DSP2_RX_EQ_BAND_4_C: + case WM8915_DSP2_RX_EQ_BAND_4_PG: + case WM8915_DSP2_RX_EQ_BAND_5_A: + case WM8915_DSP2_RX_EQ_BAND_5_B: + case WM8915_DSP2_RX_EQ_BAND_5_PG: + case WM8915_DAC1_MIXER_VOLUMES: + case WM8915_DAC1_LEFT_MIXER_ROUTING: + case WM8915_DAC1_RIGHT_MIXER_ROUTING: + case WM8915_DAC2_MIXER_VOLUMES: + case WM8915_DAC2_LEFT_MIXER_ROUTING: + case WM8915_DAC2_RIGHT_MIXER_ROUTING: + case WM8915_DSP1_TX_LEFT_MIXER_ROUTING: + case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING: + case WM8915_DSP2_TX_LEFT_MIXER_ROUTING: + case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING: + case WM8915_DSP_TX_MIXER_SELECT: + case WM8915_DAC_SOFTMUTE: + case WM8915_OVERSAMPLING: + case WM8915_SIDETONE: + case WM8915_GPIO_1: + case WM8915_GPIO_2: + case WM8915_GPIO_3: + case WM8915_GPIO_4: + case WM8915_GPIO_5: + case WM8915_PULL_CONTROL_1: + case WM8915_PULL_CONTROL_2: + case WM8915_INTERRUPT_STATUS_1: + case WM8915_INTERRUPT_STATUS_2: + case WM8915_INTERRUPT_RAW_STATUS_2: + case WM8915_INTERRUPT_STATUS_1_MASK: + case WM8915_INTERRUPT_STATUS_2_MASK: + case WM8915_INTERRUPT_CONTROL: + case WM8915_LEFT_PDM_SPEAKER: + case WM8915_RIGHT_PDM_SPEAKER: + case WM8915_PDM_SPEAKER_MUTE_SEQUENCE: + case WM8915_PDM_SPEAKER_VOLUME: + return 1; + default: + return 0; + } +} + +static int wm8915_volatile_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + switch (reg) { + case WM8915_SOFTWARE_RESET: + case WM8915_CHIP_REVISION: + case WM8915_LDO_1: + case WM8915_LDO_2: + case WM8915_INTERRUPT_STATUS_1: + case WM8915_INTERRUPT_STATUS_2: + case WM8915_INTERRUPT_RAW_STATUS_2: + case WM8915_DC_SERVO_READBACK_0: + case WM8915_DC_SERVO_2: + case WM8915_DC_SERVO_6: + case WM8915_DC_SERVO_7: + case WM8915_FLL_CONTROL_6: + case WM8915_MIC_DETECT_3: + case WM8915_HEADPHONE_DETECT_1: + case WM8915_HEADPHONE_DETECT_2: + return 1; + default: + return 0; + } +} + +static int wm8915_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915); +} + +static int wm8915_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1, + WM8915_BG_ENA, WM8915_BG_ENA); + msleep(2); + } + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + if (ret != 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + + if (wm8915->pdata.ldo_ena >= 0) { + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, + 1); + msleep(5); + } + + codec->cache_only = false; + snd_soc_cache_sync(codec); + } + + snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1, + WM8915_BG_ENA, 0); + break; + + case SND_SOC_BIAS_OFF: + codec->cache_only = true; + if (wm8915->pdata.ldo_ena >= 0) + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0); + regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + break; + } + + codec->dapm.bias_level = level; + + return 0; +} + +static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + int aifctrl = 0; + int bclk = 0; + int lrclk_tx = 0; + int lrclk_rx = 0; + int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg; + + switch (dai->id) { + case 0: + aifctrl_reg = WM8915_AIF1_CONTROL; + bclk_reg = WM8915_AIF1_BCLK; + lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2; + lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2; + break; + case 1: + aifctrl_reg = WM8915_AIF2_CONTROL; + bclk_reg = WM8915_AIF2_BCLK; + lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2; + lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2; + break; + default: + BUG(); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + bclk |= WM8915_AIF1_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + lrclk_tx |= WM8915_AIF1TX_LRCLK_INV; + lrclk_rx |= WM8915_AIF1RX_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_IF: + bclk |= WM8915_AIF1_BCLK_INV; + lrclk_tx |= WM8915_AIF1TX_LRCLK_INV; + lrclk_rx |= WM8915_AIF1RX_LRCLK_INV; + break; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBS_CFM: + lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR; + lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + bclk |= WM8915_AIF1_BCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + bclk |= WM8915_AIF1_BCLK_MSTR; + lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR; + lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + break; + case SND_SOC_DAIFMT_DSP_B: + aifctrl |= 1; + break; + case SND_SOC_DAIFMT_I2S: + aifctrl |= 2; + break; + case SND_SOC_DAIFMT_LEFT_J: + aifctrl |= 3; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl); + snd_soc_update_bits(codec, bclk_reg, + WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR, + bclk); + snd_soc_update_bits(codec, lrclk_tx_reg, + WM8915_AIF1TX_LRCLK_INV | + WM8915_AIF1TX_LRCLK_MSTR, + lrclk_tx); + snd_soc_update_bits(codec, lrclk_rx_reg, + WM8915_AIF1RX_LRCLK_INV | + WM8915_AIF1RX_LRCLK_MSTR, + lrclk_rx); + + return 0; +} + +static const int bclk_divs[] = { + 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 +}; + +static const int dsp_divs[] = { + 48000, 32000, 16000, 8000 +}; + +static int wm8915_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int bits, i, bclk_rate, best, cur_val; + int aifdata = 0; + int bclk = 0; + int lrclk = 0; + int dsp = 0; + int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift; + + if (!wm8915->sysclk) { + dev_err(codec->dev, "SYSCLK not configured\n"); + return -EINVAL; + } + + switch (dai->id) { + case 0: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) { + aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION; + lrclk_reg = WM8915_AIF1_RX_LRCLK_1; + } else { + aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1; + lrclk_reg = WM8915_AIF1_TX_LRCLK_1; + } + bclk_reg = WM8915_AIF1_BCLK; + dsp_shift = 0; + break; + case 1: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) { + aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION; + lrclk_reg = WM8915_AIF2_RX_LRCLK_1; + } else { + aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1; + lrclk_reg = WM8915_AIF2_TX_LRCLK_1; + } + bclk_reg = WM8915_AIF2_BCLK; + dsp_shift = WM8915_DSP2_DIV_SHIFT; + break; + default: + BUG(); + return -EINVAL; + } + + bclk_rate = snd_soc_params_to_bclk(params); + if (bclk_rate < 0) { + dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate); + return bclk_rate; + } + + /* Needs looking at for TDM */ + bits = snd_pcm_format_width(params_format(params)); + if (bits < 0) + return bits; + aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits; + + for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) { + if (dsp_divs[i] == params_rate(params)) + break; + } + if (i == ARRAY_SIZE(dsp_divs)) { + dev_err(codec->dev, "Unsupported sample rate %dHz\n", + params_rate(params)); + return -EINVAL; + } + dsp |= i << dsp_shift; + + /* Pick a divisor for BCLK as close as we can get to ideal */ + best = 0; + for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { + cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate; + if (cur_val < 0) /* BCLK table is sorted */ + break; + best = i; + } + bclk_rate = wm8915->sysclk / bclk_divs[best]; + dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n", + bclk_divs[best], bclk_rate); + bclk |= best; + + lrclk = bclk_rate / params_rate(params); + dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", + lrclk, bclk_rate / lrclk); + + snd_soc_update_bits(codec, aifdata_reg, + WM8915_AIF1TX_WL_MASK | + WM8915_AIF1TX_SLOT_LEN_MASK, + aifdata); + snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk); + snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK, + lrclk); + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2, + WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp); + + wm8915->rx_rate[dai->id] = params_rate(params); + + return 0; +} + +static int wm8915_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int lfclk = 0; + int src; + int old; + + /* Disable SYSCLK while we reconfigure */ + old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1); + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, + WM8915_SYSCLK_ENA, 0); + + switch (clk_id) { + case WM8915_SYSCLK_MCLK1: + wm8915->sysclk = freq; + src = 0; + break; + case WM8915_SYSCLK_MCLK2: + wm8915->sysclk = freq; + src = 1; + break; + case WM8915_SYSCLK_FLL: + wm8915->sysclk = freq; + src = 2; + break; + default: + dev_err(codec->dev, "Unsupported clock source %d\n", clk_id); + return -EINVAL; + } + + switch (wm8915->sysclk) { + case 6144000: + snd_soc_update_bits(codec, WM8915_AIF_RATE, + WM8915_SYSCLK_RATE, 0); + break; + case 12288000: + snd_soc_update_bits(codec, WM8915_AIF_RATE, + WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE); + break; + case 32000: + case 32768: + lfclk = WM8915_LFCLK_ENA; + break; + default: + dev_warn(codec->dev, "Unsupported clock rate %dHz\n", + wm8915->sysclk); + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, + WM8915_SYSCLK_SRC_MASK, + src << WM8915_SYSCLK_SRC_SHIFT); + snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk); + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, + WM8915_SYSCLK_ENA, old); + + return 0; +} + +struct _fll_div { + u16 fll_fratio; + u16 fll_outdiv; + u16 fll_refclk_div; + u16 fll_loop_gain; + u16 fll_ref_freq; + u16 n; + u16 theta; + u16 lambda; +}; + +static struct { + unsigned int min; + unsigned int max; + u16 fll_fratio; + int ratio; +} fll_fratios[] = { + { 0, 64000, 4, 16 }, + { 64000, 128000, 3, 8 }, + { 128000, 256000, 2, 4 }, + { 256000, 1000000, 1, 2 }, + { 1000000, 13500000, 0, 1 }, +}; + +static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, + unsigned int Fout) +{ + unsigned int target; + unsigned int div; + unsigned int fratio, gcd_fll; + int i; + + /* Fref must be <=13.5MHz */ + div = 1; + fll_div->fll_refclk_div = 0; + while ((Fref / div) > 13500000) { + div *= 2; + fll_div->fll_refclk_div++; + + if (div > 8) { + pr_err("Can't scale %dMHz input down to <=13.5MHz\n", + Fref); + return -EINVAL; + } + } + + pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); + + /* Apply the division for our remaining calculations */ + Fref /= div; + + if (Fref >= 3000000) + fll_div->fll_loop_gain = 5; + else + fll_div->fll_loop_gain = 0; + + if (Fref >= 48000) + fll_div->fll_ref_freq = 0; + else + fll_div->fll_ref_freq = 1; + + /* Fvco should be 90-100MHz; don't check the upper bound */ + div = 2; + while (Fout * div < 90000000) { + div++; + if (div > 64) { + pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", + Fout); + return -EINVAL; + } + } + target = Fout * div; + fll_div->fll_outdiv = div - 1; + + pr_debug("FLL Fvco=%dHz\n", target); + + /* Find an appropraite FLL_FRATIO and factor it out of the target */ + for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { + if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { + fll_div->fll_fratio = fll_fratios[i].fll_fratio; + fratio = fll_fratios[i].ratio; + break; + } + } + if (i == ARRAY_SIZE(fll_fratios)) { + pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); + return -EINVAL; + } + + fll_div->n = target / (fratio * Fref); + + if (target % Fref == 0) { + fll_div->theta = 0; + fll_div->lambda = 0; + } else { + gcd_fll = gcd(target, fratio * Fref); + + fll_div->theta = (target - (fll_div->n * fratio * Fref)) + / gcd_fll; + fll_div->lambda = (fratio * Fref) / gcd_fll; + } + + pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", + fll_div->n, fll_div->theta, fll_div->lambda); + pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", + fll_div->fll_fratio, fll_div->fll_outdiv, + fll_div->fll_refclk_div); + + return 0; +} + +static int wm8915_set_fll(struct snd_soc_dai *dai, int fll_id, int source, + unsigned int Fref, unsigned int Fout) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct _fll_div fll_div; + unsigned long timeout; + int ret, reg; + + /* Any change? */ + if (source == wm8915->fll_src && Fref == wm8915->fll_fref && + Fout == wm8915->fll_fout) + return 0; + + if (Fout == 0) { + dev_dbg(codec->dev, "FLL disabled\n"); + + wm8915->fll_fref = 0; + wm8915->fll_fout = 0; + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1, + WM8915_FLL_ENA, 0); + + return 0; + } + + ret = fll_factors(&fll_div, Fref, Fout); + if (ret != 0) + return ret; + + switch (source) { + case WM8915_FLL_MCLK1: + reg = 0; + break; + case WM8915_FLL_MCLK2: + reg = 1; + case WM8915_FLL_DACLRCLK1: + reg = 2; + break; + case WM8915_FLL_BCLK1: + reg = 3; + break; + default: + dev_err(codec->dev, "Unknown FLL source %d\n", ret); + return -EINVAL; + } + + reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT; + reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT; + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5, + WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ | + WM8915_FLL_REFCLK_SRC_MASK, reg); + + reg = 0; + if (fll_div.theta || fll_div.lambda) + reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT); + else + reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT; + snd_soc_write(codec, WM8915_FLL_EFS_2, reg); + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2, + WM8915_FLL_OUTDIV_MASK | + WM8915_FLL_FRATIO_MASK, + (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) | + (fll_div.fll_fratio)); + + snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta); + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4, + WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK, + (fll_div.n << WM8915_FLL_N_SHIFT) | + fll_div.fll_loop_gain); + + snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda); + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1, + WM8915_FLL_ENA, WM8915_FLL_ENA); + + /* The FLL supports live reconfiguration - kick that in case we were + * already enabled. + */ + snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK); + + /* Wait for the FLL to lock, using the interrupt if possible */ + if (Fref > 1000000) + timeout = usecs_to_jiffies(300); + else + timeout = msecs_to_jiffies(2); + + wait_for_completion_timeout(&wm8915->fll_lock, timeout); + + dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); + + wm8915->fll_fref = Fref; + wm8915->fll_fout = Fout; + wm8915->fll_src = source; + + return 0; +} + +#ifdef CONFIG_GPIOLIB +static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip) +{ + return container_of(chip, struct wm8915_priv, gpio_chip); +} + +static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + + snd_soc_update_bits(codec, WM8915_GPIO_1 + offset, + WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT); +} + +static int wm8915_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + int val; + + val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT); + + return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset, + WM8915_GP1_FN_MASK | WM8915_GP1_DIR | + WM8915_GP1_LVL, val); +} + +static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + int ret; + + ret = snd_soc_read(codec, WM8915_GPIO_1 + offset); + if (ret < 0) + return ret; + + return (ret & WM8915_GP1_LVL) != 0; +} + +static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + + return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset, + WM8915_GP1_FN_MASK | WM8915_GP1_DIR, + (1 << WM8915_GP1_FN_SHIFT) | + (1 << WM8915_GP1_DIR_SHIFT)); +} + +static struct gpio_chip wm8915_template_chip = { + .label = "wm8915", + .owner = THIS_MODULE, + .direction_output = wm8915_gpio_direction_out, + .set = wm8915_gpio_set, + .direction_input = wm8915_gpio_direction_in, + .get = wm8915_gpio_get, + .can_sleep = 1, +}; + +static void wm8915_init_gpio(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int ret; + + wm8915->gpio_chip = wm8915_template_chip; + wm8915->gpio_chip.ngpio = 5; + wm8915->gpio_chip.dev = codec->dev; + + if (wm8915->pdata.gpio_base) + wm8915->gpio_chip.base = wm8915->pdata.gpio_base; + else + wm8915->gpio_chip.base = -1; + + ret = gpiochip_add(&wm8915->gpio_chip); + if (ret != 0) + dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); +} + +static void wm8915_free_gpio(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = gpiochip_remove(&wm8915->gpio_chip); + if (ret != 0) + dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); +} +#else +static void wm8915_init_gpio(struct snd_soc_codec *codec) +{ +} + +static void wm8915_free_gpio(struct snd_soc_codec *codec) +{ +} +#endif + +/** + * wm8915_detect - Enable default WM8915 jack detection + * + * The WM8915 has advanced accessory detection support for headsets. + * This function provides a default implementation which integrates + * the majority of this functionality with minimal user configuration. + * + * This will detect headset, headphone and short circuit button and + * will also detect inverted microphone ground connections and update + * the polarity of the connections. + */ +int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + wm8915_polarity_fn polarity_cb) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + + wm8915->jack = jack; + wm8915->detecting = true; + wm8915->polarity_cb = polarity_cb; + + if (wm8915->polarity_cb) + wm8915->polarity_cb(codec, 0); + + /* Clear discarge to avoid noise during detection */ + snd_soc_update_bits(codec, WM8915_MICBIAS_1, + WM8915_MICB1_DISCH, 0); + snd_soc_update_bits(codec, WM8915_MICBIAS_2, + WM8915_MICB2_DISCH, 0); + + /* LDO2 powers the microphones, SYSCLK clocks detection */ + snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); + snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); + + /* We start off just enabling microphone detection - even a + * plain headphone will trigger detection. + */ + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_ENA, WM8915_MICD_ENA); + + /* Slowest detection rate, gives debounce for initial detection */ + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + WM8915_MICD_RATE_MASK); + + /* Enable interrupts and we're off */ + snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK, + WM8915_IM_MICD_EINT, 0); + + return 0; +} +EXPORT_SYMBOL_GPL(wm8915_detect); + +static void wm8915_micd(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int val, reg; + + val = snd_soc_read(codec, WM8915_MIC_DETECT_3); + + dev_dbg(codec->dev, "Microphone event: %x\n", val); + + if (!(val & WM8915_MICD_VALID)) { + dev_warn(codec->dev, "Microphone detection state invalid\n"); + return; + } + + /* No accessory, reset everything and report removal */ + if (!(val & WM8915_MICD_STS)) { + dev_dbg(codec->dev, "Jack removal detected\n"); + wm8915->jack_mic = false; + wm8915->detecting = true; + snd_soc_jack_report(wm8915->jack, 0, + SND_JACK_HEADSET | SND_JACK_BTN_0); + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + WM8915_MICD_RATE_MASK); + return; + } + + /* If the measurement is very high we've got a microphone but + * do a little debounce to account for mechanical issues. + */ + if (val & 0x400) { + dev_dbg(codec->dev, "Microphone detected\n"); + snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET, + SND_JACK_HEADSET | SND_JACK_BTN_0); + wm8915->jack_mic = true; + wm8915->detecting = false; + } + + /* If we detected a lower impedence during initial startup + * then we probably have the wrong polarity, flip it. Don't + * do this for the lowest impedences to speed up detection of + * plain headphones. + */ + if (wm8915->detecting && (val & 0x3f0)) { + reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2); + reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC | + WM8915_MICD_BIAS_SRC; + snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2, + WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC | + WM8915_MICD_BIAS_SRC, reg); + + if (wm8915->polarity_cb) + wm8915->polarity_cb(codec, + (reg & WM8915_MICD_SRC) != 0); + + dev_dbg(codec->dev, "Set microphone polarity to %d\n", + (reg & WM8915_MICD_SRC) != 0); + + return; + } + + /* Don't distinguish between buttons, just report any low + * impedence as BTN_0. + */ + if (val & 0x3fc) { + if (wm8915->jack_mic) { + dev_dbg(codec->dev, "Mic button detected\n"); + snd_soc_jack_report(wm8915->jack, + SND_JACK_HEADSET | SND_JACK_BTN_0, + SND_JACK_HEADSET | SND_JACK_BTN_0); + } else { + dev_dbg(codec->dev, "Headphone detected\n"); + snd_soc_jack_report(wm8915->jack, + SND_JACK_HEADPHONE, + SND_JACK_HEADSET | + SND_JACK_BTN_0); + wm8915->detecting = false; + } + } + + /* Increase poll rate to give better responsiveness for buttons */ + if (!wm8915->detecting) + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + 5 << WM8915_MICD_RATE_SHIFT); +} + +static irqreturn_t wm8915_irq(int irq, void *data) +{ + struct snd_soc_codec *codec = data; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int irq_val; + + irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2); + if (irq_val < 0) { + dev_err(codec->dev, "Failed to read IRQ status: %d\n", + irq_val); + return IRQ_NONE; + } + irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK); + + if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) { + dev_dbg(codec->dev, "DC servo IRQ\n"); + complete(&wm8915->dcs_done); + } + + if (irq_val & WM8915_FIFOS_ERR_EINT) + dev_err(codec->dev, "Digital core FIFO error\n"); + + if (irq_val & WM8915_FLL_LOCK_EINT) { + dev_dbg(codec->dev, "FLL locked\n"); + complete(&wm8915->fll_lock); + } + + if (irq_val & WM8915_MICD_EINT) + wm8915_micd(codec); + + if (irq_val) { + snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val); + + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } +} + +static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct wm8915_pdata *pdata = &wm8915->pdata; + + struct snd_kcontrol_new controls[] = { + SOC_ENUM_EXT("DSP1 EQ Mode", + wm8915->retune_mobile_enum, + wm8915_get_retune_mobile_enum, + wm8915_put_retune_mobile_enum), + SOC_ENUM_EXT("DSP2 EQ Mode", + wm8915->retune_mobile_enum, + wm8915_get_retune_mobile_enum, + wm8915_put_retune_mobile_enum), + }; + int ret, i, j; + const char **t; + + /* We need an array of texts for the enum API but the number + * of texts is likely to be less than the number of + * configurations due to the sample rate dependency of the + * configurations. */ + wm8915->num_retune_mobile_texts = 0; + wm8915->retune_mobile_texts = NULL; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + for (j = 0; j < wm8915->num_retune_mobile_texts; j++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8915->retune_mobile_texts[j]) == 0) + break; + } + + if (j != wm8915->num_retune_mobile_texts) + continue; + + /* Expand the array... */ + t = krealloc(wm8915->retune_mobile_texts, + sizeof(char *) * + (wm8915->num_retune_mobile_texts + 1), + GFP_KERNEL); + if (t == NULL) + continue; + + /* ...store the new entry... */ + t[wm8915->num_retune_mobile_texts] = + pdata->retune_mobile_cfgs[i].name; + + /* ...and remember the new version. */ + wm8915->num_retune_mobile_texts++; + wm8915->retune_mobile_texts = t; + } + + dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", + wm8915->num_retune_mobile_texts); + + wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts; + wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts; + + ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); + if (ret != 0) + dev_err(codec->dev, + "Failed to add ReTune Mobile controls: %d\n", ret); +} + +static int wm8915_probe(struct snd_soc_codec *codec) +{ + int ret; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c = to_i2c_client(codec->dev); + struct snd_soc_dapm_context *dapm = &codec->dapm; + int i, irq_flags; + + wm8915->codec = codec; + + init_completion(&wm8915->dcs_done); + init_completion(&wm8915->fll_lock); + + dapm->idle_bias_off = true; + dapm->bias_level = SND_SOC_BIAS_OFF; + + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + goto err; + } + + for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) + wm8915->supplies[i].supply = wm8915_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + goto err; + } + + wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0; + wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1; + wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2; + wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3; + wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4; + wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) { + ret = regulator_register_notifier(wm8915->supplies[i].consumer, + &wm8915->disable_nb[i]); + if (ret != 0) { + dev_err(codec->dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + if (wm8915->pdata.ldo_ena >= 0) { + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1); + msleep(5); + } + + ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET); + if (ret < 0) { + dev_err(codec->dev, "Failed to read ID register: %d\n", ret); + goto err_enable; + } + if (ret != 0x8915) { + dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret); + ret = -EINVAL; + goto err_enable; + } + + ret = snd_soc_read(codec, WM8915_CHIP_REVISION); + if (ret < 0) { + dev_err(codec->dev, "Failed to read device revision: %d\n", + ret); + goto err_enable; + } + + dev_info(codec->dev, "revision %c\n", + (ret & WM8915_CHIP_REV_MASK) + 'A'); + + if (wm8915->pdata.ldo_ena >= 0) { + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0); + } else { + ret = wm8915_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + goto err_enable; + } + } + + codec->cache_only = true; + + /* Apply platform data settings */ + snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL, + WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK, + wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT | + wm8915->pdata.inr_mode); + + for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) { + if (!wm8915->pdata.gpio_default[i]) + continue; + + snd_soc_write(codec, WM8915_GPIO_1 + i, + wm8915->pdata.gpio_default[i] & 0xffff); + } + + if (wm8915->pdata.spkmute_seq) + snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE, + WM8915_SPK_MUTE_ENDIAN | + WM8915_SPK_MUTE_SEQ1_MASK, + wm8915->pdata.spkmute_seq); + + snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2, + WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC | + WM8915_MICD_SRC, wm8915->pdata.micdet_def); + + /* Latch volume update bits */ + snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME, + WM8915_IN1_VU, WM8915_IN1_VU); + snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME, + WM8915_IN1_VU, WM8915_IN1_VU); + + snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + + snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + + snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME, + WM8915_DSP1TX_VU, WM8915_DSP1TX_VU); + snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME, + WM8915_DSP1TX_VU, WM8915_DSP1TX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME, + WM8915_DSP2TX_VU, WM8915_DSP2TX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME, + WM8915_DSP2TX_VU, WM8915_DSP2TX_VU); + + snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME, + WM8915_DSP1RX_VU, WM8915_DSP1RX_VU); + snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME, + WM8915_DSP1RX_VU, WM8915_DSP1RX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME, + WM8915_DSP2RX_VU, WM8915_DSP2RX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME, + WM8915_DSP2RX_VU, WM8915_DSP2RX_VU); + + /* No support currently for the underclocked TDM modes and + * pick a default TDM layout with each channel pair working with + * slots 0 and 1. */ + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION, + WM8915_AIF1RX_CHAN0_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION, + WM8915_AIF1RX_CHAN1_SLOTS_MASK | + WM8915_AIF1RX_CHAN1_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION, + WM8915_AIF1RX_CHAN2_SLOTS_MASK | + WM8915_AIF1RX_CHAN2_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION, + WM8915_AIF1RX_CHAN3_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION, + WM8915_AIF1RX_CHAN4_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION, + WM8915_AIF1RX_CHAN5_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1); + + snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION, + WM8915_AIF2RX_CHAN0_SLOTS_MASK | + WM8915_AIF2RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION, + WM8915_AIF2RX_CHAN1_SLOTS_MASK | + WM8915_AIF2RX_CHAN1_START_SLOT_MASK, + 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1); + + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION, + WM8915_AIF1TX_CHAN0_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION, + WM8915_AIF1TX_CHAN1_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION, + WM8915_AIF1TX_CHAN2_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION, + WM8915_AIF1TX_CHAN3_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION, + WM8915_AIF1TX_CHAN4_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION, + WM8915_AIF1TX_CHAN5_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1); + + snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION, + WM8915_AIF2TX_CHAN0_SLOTS_MASK | + WM8915_AIF2TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION, + WM8915_AIF2TX_CHAN1_SLOTS_MASK | + WM8915_AIF2TX_CHAN1_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1); + + if (wm8915->pdata.num_retune_mobile_cfgs) + wm8915_retune_mobile_pdata(codec); + else + snd_soc_add_controls(codec, wm8915_eq_controls, + ARRAY_SIZE(wm8915_eq_controls)); + + /* If the TX LRCLK pins are not in LRCLK mode configure the + * AIFs to source their clocks from the RX LRCLKs. + */ + if ((snd_soc_read(codec, WM8915_GPIO_1))) + snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2, + WM8915_AIF1TX_LRCLK_MODE, + WM8915_AIF1TX_LRCLK_MODE); + + if ((snd_soc_read(codec, WM8915_GPIO_2))) + snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2, + WM8915_AIF2TX_LRCLK_MODE, + WM8915_AIF2TX_LRCLK_MODE); + + regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); + + wm8915_init_gpio(codec); + + if (i2c->irq) { + if (wm8915->pdata.irq_flags) + irq_flags = wm8915->pdata.irq_flags; + else + irq_flags = IRQF_TRIGGER_LOW; + + irq_flags |= IRQF_ONESHOT; + + ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq, + irq_flags, "wm8915", codec); + if (ret == 0) { + /* Unmask the interrupt */ + snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL, + WM8915_IM_IRQ, 0); + + /* Enable error reporting and DC servo status */ + snd_soc_update_bits(codec, + WM8915_INTERRUPT_STATUS_2_MASK, + WM8915_IM_DCS_DONE_23_EINT | + WM8915_IM_DCS_DONE_01_EINT | + WM8915_IM_FLL_LOCK_EINT | + WM8915_IM_FIFOS_ERR_EINT, + 0); + } else { + dev_err(codec->dev, "Failed to request IRQ: %d\n", + ret); + } + } + + return 0; + +err_enable: + if (wm8915->pdata.ldo_ena >= 0) + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0); + + regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); +err: + return ret; +} + +static int wm8915_remove(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c = to_i2c_client(codec->dev); + int i; + + snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL, + WM8915_IM_IRQ, WM8915_IM_IRQ); + + if (i2c->irq) + free_irq(i2c->irq, codec); + + wm8915_free_gpio(codec); + + for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) + regulator_unregister_notifier(wm8915->supplies[i].consumer, + &wm8915->disable_nb[i]); + regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wm8915 = { + .probe = wm8915_probe, + .remove = wm8915_remove, + .set_bias_level = wm8915_set_bias_level, + .seq_notifier = wm8915_seq_notifier, + .reg_cache_size = WM8915_MAX_REGISTER + 1, + .reg_word_size = sizeof(u16), + .reg_cache_default = wm8915_reg, + .volatile_register = wm8915_volatile_register, + .readable_register = wm8915_readable_register, + .compress_type = SND_SOC_RBTREE_COMPRESSION, + .controls = wm8915_snd_controls, + .num_controls = ARRAY_SIZE(wm8915_snd_controls), + .dapm_widgets = wm8915_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets), + .dapm_routes = wm8915_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes), +}; + +#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) +#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8915_dai_ops = { + .set_fmt = wm8915_set_fmt, + .hw_params = wm8915_hw_params, + .set_sysclk = wm8915_set_sysclk, + .set_pll = wm8915_set_fll, +}; + +static struct snd_soc_dai_driver wm8915_dai[] = { + { + .name = "wm8915-aif1", + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 6, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 6, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .ops = &wm8915_dai_ops, + }, + { + .name = "wm8915-aif2", + .playback = { + .stream_name = "AIF2 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .capture = { + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .ops = &wm8915_dai_ops, + }, +}; + +static __devinit int wm8915_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8915_priv *wm8915; + int ret; + + wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL); + if (wm8915 == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, wm8915); + + if (dev_get_platdata(&i2c->dev)) + memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev), + sizeof(wm8915->pdata)); + + if (wm8915->pdata.ldo_ena > 0) { + ret = gpio_request_one(wm8915->pdata.ldo_ena, + GPIOF_OUT_INIT_LOW, "WM8915 ENA"); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n", + wm8915->pdata.ldo_ena, ret); + goto err; + } + } + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_wm8915, wm8915_dai, + ARRAY_SIZE(wm8915_dai)); + if (ret < 0) + goto err_gpio; + + return ret; + +err_gpio: + if (wm8915->pdata.ldo_ena > 0) + gpio_free(wm8915->pdata.ldo_ena); +err: + kfree(wm8915); + + return ret; +} + +static __devexit int wm8915_i2c_remove(struct i2c_client *client) +{ + struct wm8915_priv *wm8915 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + if (wm8915->pdata.ldo_ena > 0) + gpio_free(wm8915->pdata.ldo_ena); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static const struct i2c_device_id wm8915_i2c_id[] = { + { "wm8915", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id); + +static struct i2c_driver wm8915_i2c_driver = { + .driver = { + .name = "wm8915", + .owner = THIS_MODULE, + }, + .probe = wm8915_i2c_probe, + .remove = __devexit_p(wm8915_i2c_remove), + .id_table = wm8915_i2c_id, +}; + +static int __init wm8915_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&wm8915_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n", + ret); + } + + return ret; +} +module_init(wm8915_modinit); + +static void __exit wm8915_exit(void) +{ + i2c_del_driver(&wm8915_i2c_driver); +} +module_exit(wm8915_exit); + +MODULE_DESCRIPTION("ASoC WM8915 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8915.h b/sound/soc/codecs/wm8915.h new file mode 100644 index 000000000000..200ffd7bf953 --- /dev/null +++ b/sound/soc/codecs/wm8915.h @@ -0,0 +1,3717 @@ +/* + * wm8915.h - WM8915 audio codec interface + * + * Copyright 2011 Wolfson Microelectronics PLC. + * Author: Mark Brown + * + * 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. + */ + +#ifndef _WM8915_H +#define _WM8915_H + +#define WM8915_SYSCLK_MCLK1 1 +#define WM8915_SYSCLK_MCLK2 2 +#define WM8915_SYSCLK_FLL 3 + +#define WM8915_FLL_MCLK1 1 +#define WM8915_FLL_MCLK2 2 +#define WM8915_FLL_DACLRCLK1 3 +#define WM8915_FLL_BCLK1 4 + +typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity); + +int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + wm8915_polarity_fn polarity_cb); + +/* + * Register values. + */ +#define WM8915_SOFTWARE_RESET 0x00 +#define WM8915_POWER_MANAGEMENT_1 0x01 +#define WM8915_POWER_MANAGEMENT_2 0x02 +#define WM8915_POWER_MANAGEMENT_3 0x03 +#define WM8915_POWER_MANAGEMENT_4 0x04 +#define WM8915_POWER_MANAGEMENT_5 0x05 +#define WM8915_POWER_MANAGEMENT_6 0x06 +#define WM8915_POWER_MANAGEMENT_7 0x07 +#define WM8915_POWER_MANAGEMENT_8 0x08 +#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10 +#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11 +#define WM8915_LINE_INPUT_CONTROL 0x12 +#define WM8915_DAC1_HPOUT1_VOLUME 0x15 +#define WM8915_DAC2_HPOUT2_VOLUME 0x16 +#define WM8915_DAC1_LEFT_VOLUME 0x18 +#define WM8915_DAC1_RIGHT_VOLUME 0x19 +#define WM8915_DAC2_LEFT_VOLUME 0x1A +#define WM8915_DAC2_RIGHT_VOLUME 0x1B +#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C +#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D +#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E +#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F +#define WM8915_MICBIAS_1 0x20 +#define WM8915_MICBIAS_2 0x21 +#define WM8915_LDO_1 0x28 +#define WM8915_LDO_2 0x29 +#define WM8915_ACCESSORY_DETECT_MODE_1 0x30 +#define WM8915_ACCESSORY_DETECT_MODE_2 0x31 +#define WM8915_HEADPHONE_DETECT_1 0x34 +#define WM8915_HEADPHONE_DETECT_2 0x35 +#define WM8915_MIC_DETECT_1 0x38 +#define WM8915_MIC_DETECT_2 0x39 +#define WM8915_MIC_DETECT_3 0x3A +#define WM8915_CHARGE_PUMP_1 0x40 +#define WM8915_CHARGE_PUMP_2 0x41 +#define WM8915_DC_SERVO_1 0x50 +#define WM8915_DC_SERVO_2 0x51 +#define WM8915_DC_SERVO_3 0x52 +#define WM8915_DC_SERVO_5 0x54 +#define WM8915_DC_SERVO_6 0x55 +#define WM8915_DC_SERVO_7 0x56 +#define WM8915_DC_SERVO_READBACK_0 0x57 +#define WM8915_ANALOGUE_HP_1 0x60 +#define WM8915_ANALOGUE_HP_2 0x61 +#define WM8915_CHIP_REVISION 0x100 +#define WM8915_CONTROL_INTERFACE_1 0x101 +#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110 +#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111 +#define WM8915_AIF_CLOCKING_1 0x200 +#define WM8915_AIF_CLOCKING_2 0x201 +#define WM8915_CLOCKING_1 0x208 +#define WM8915_CLOCKING_2 0x209 +#define WM8915_AIF_RATE 0x210 +#define WM8915_FLL_CONTROL_1 0x220 +#define WM8915_FLL_CONTROL_2 0x221 +#define WM8915_FLL_CONTROL_3 0x222 +#define WM8915_FLL_CONTROL_4 0x223 +#define WM8915_FLL_CONTROL_5 0x224 +#define WM8915_FLL_CONTROL_6 0x225 +#define WM8915_FLL_EFS_1 0x226 +#define WM8915_FLL_EFS_2 0x227 +#define WM8915_AIF1_CONTROL 0x300 +#define WM8915_AIF1_BCLK 0x301 +#define WM8915_AIF1_TX_LRCLK_1 0x302 +#define WM8915_AIF1_TX_LRCLK_2 0x303 +#define WM8915_AIF1_RX_LRCLK_1 0x304 +#define WM8915_AIF1_RX_LRCLK_2 0x305 +#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306 +#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307 +#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308 +#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309 +#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A +#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B +#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C +#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D +#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E +#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F +#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310 +#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311 +#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312 +#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313 +#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314 +#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315 +#define WM8915_AIF1TX_TEST 0x31A +#define WM8915_AIF2_CONTROL 0x320 +#define WM8915_AIF2_BCLK 0x321 +#define WM8915_AIF2_TX_LRCLK_1 0x322 +#define WM8915_AIF2_TX_LRCLK_2 0x323 +#define WM8915_AIF2_RX_LRCLK_1 0x324 +#define WM8915_AIF2_RX_LRCLK_2 0x325 +#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326 +#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327 +#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328 +#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329 +#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A +#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B +#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C +#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D +#define WM8915_AIF2TX_TEST 0x32F +#define WM8915_DSP1_TX_LEFT_VOLUME 0x400 +#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401 +#define WM8915_DSP1_RX_LEFT_VOLUME 0x402 +#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403 +#define WM8915_DSP1_TX_FILTERS 0x410 +#define WM8915_DSP1_RX_FILTERS_1 0x420 +#define WM8915_DSP1_RX_FILTERS_2 0x421 +#define WM8915_DSP1_DRC_1 0x440 +#define WM8915_DSP1_DRC_2 0x441 +#define WM8915_DSP1_DRC_3 0x442 +#define WM8915_DSP1_DRC_4 0x443 +#define WM8915_DSP1_DRC_5 0x444 +#define WM8915_DSP1_RX_EQ_GAINS_1 0x480 +#define WM8915_DSP1_RX_EQ_GAINS_2 0x481 +#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482 +#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483 +#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484 +#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485 +#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486 +#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487 +#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488 +#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489 +#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A +#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B +#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C +#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D +#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E +#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F +#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490 +#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491 +#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492 +#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493 +#define WM8915_DSP2_TX_LEFT_VOLUME 0x500 +#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501 +#define WM8915_DSP2_RX_LEFT_VOLUME 0x502 +#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503 +#define WM8915_DSP2_TX_FILTERS 0x510 +#define WM8915_DSP2_RX_FILTERS_1 0x520 +#define WM8915_DSP2_RX_FILTERS_2 0x521 +#define WM8915_DSP2_DRC_1 0x540 +#define WM8915_DSP2_DRC_2 0x541 +#define WM8915_DSP2_DRC_3 0x542 +#define WM8915_DSP2_DRC_4 0x543 +#define WM8915_DSP2_DRC_5 0x544 +#define WM8915_DSP2_RX_EQ_GAINS_1 0x580 +#define WM8915_DSP2_RX_EQ_GAINS_2 0x581 +#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582 +#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583 +#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584 +#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585 +#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586 +#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587 +#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588 +#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589 +#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A +#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B +#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C +#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D +#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E +#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F +#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590 +#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591 +#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592 +#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593 +#define WM8915_DAC1_MIXER_VOLUMES 0x600 +#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601 +#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602 +#define WM8915_DAC2_MIXER_VOLUMES 0x603 +#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604 +#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605 +#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606 +#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607 +#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608 +#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609 +#define WM8915_DSP_TX_MIXER_SELECT 0x60A +#define WM8915_DAC_SOFTMUTE 0x610 +#define WM8915_OVERSAMPLING 0x620 +#define WM8915_SIDETONE 0x621 +#define WM8915_GPIO_1 0x700 +#define WM8915_GPIO_2 0x701 +#define WM8915_GPIO_3 0x702 +#define WM8915_GPIO_4 0x703 +#define WM8915_GPIO_5 0x704 +#define WM8915_PULL_CONTROL_1 0x720 +#define WM8915_PULL_CONTROL_2 0x721 +#define WM8915_INTERRUPT_STATUS_1 0x730 +#define WM8915_INTERRUPT_STATUS_2 0x731 +#define WM8915_INTERRUPT_RAW_STATUS_2 0x732 +#define WM8915_INTERRUPT_STATUS_1_MASK 0x738 +#define WM8915_INTERRUPT_STATUS_2_MASK 0x739 +#define WM8915_INTERRUPT_CONTROL 0x740 +#define WM8915_LEFT_PDM_SPEAKER 0x800 +#define WM8915_RIGHT_PDM_SPEAKER 0x801 +#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802 +#define WM8915_PDM_SPEAKER_VOLUME 0x803 +#define WM8915_WRITE_SEQUENCER_0 0x3000 +#define WM8915_WRITE_SEQUENCER_1 0x3001 +#define WM8915_WRITE_SEQUENCER_2 0x3002 +#define WM8915_WRITE_SEQUENCER_3 0x3003 +#define WM8915_WRITE_SEQUENCER_4 0x3004 +#define WM8915_WRITE_SEQUENCER_5 0x3005 +#define WM8915_WRITE_SEQUENCER_6 0x3006 +#define WM8915_WRITE_SEQUENCER_7 0x3007 +#define WM8915_WRITE_SEQUENCER_8 0x3008 +#define WM8915_WRITE_SEQUENCER_9 0x3009 +#define WM8915_WRITE_SEQUENCER_10 0x300A +#define WM8915_WRITE_SEQUENCER_11 0x300B +#define WM8915_WRITE_SEQUENCER_12 0x300C +#define WM8915_WRITE_SEQUENCER_13 0x300D +#define WM8915_WRITE_SEQUENCER_14 0x300E +#define WM8915_WRITE_SEQUENCER_15 0x300F +#define WM8915_WRITE_SEQUENCER_16 0x3010 +#define WM8915_WRITE_SEQUENCER_17 0x3011 +#define WM8915_WRITE_SEQUENCER_18 0x3012 +#define WM8915_WRITE_SEQUENCER_19 0x3013 +#define WM8915_WRITE_SEQUENCER_20 0x3014 +#define WM8915_WRITE_SEQUENCER_21 0x3015 +#define WM8915_WRITE_SEQUENCER_22 0x3016 +#define WM8915_WRITE_SEQUENCER_23 0x3017 +#define WM8915_WRITE_SEQUENCER_24 0x3018 +#define WM8915_WRITE_SEQUENCER_25 0x3019 +#define WM8915_WRITE_SEQUENCER_26 0x301A +#define WM8915_WRITE_SEQUENCER_27 0x301B +#define WM8915_WRITE_SEQUENCER_28 0x301C +#define WM8915_WRITE_SEQUENCER_29 0x301D +#define WM8915_WRITE_SEQUENCER_30 0x301E +#define WM8915_WRITE_SEQUENCER_31 0x301F +#define WM8915_WRITE_SEQUENCER_32 0x3020 +#define WM8915_WRITE_SEQUENCER_33 0x3021 +#define WM8915_WRITE_SEQUENCER_34 0x3022 +#define WM8915_WRITE_SEQUENCER_35 0x3023 +#define WM8915_WRITE_SEQUENCER_36 0x3024 +#define WM8915_WRITE_SEQUENCER_37 0x3025 +#define WM8915_WRITE_SEQUENCER_38 0x3026 +#define WM8915_WRITE_SEQUENCER_39 0x3027 +#define WM8915_WRITE_SEQUENCER_40 0x3028 +#define WM8915_WRITE_SEQUENCER_41 0x3029 +#define WM8915_WRITE_SEQUENCER_42 0x302A +#define WM8915_WRITE_SEQUENCER_43 0x302B +#define WM8915_WRITE_SEQUENCER_44 0x302C +#define WM8915_WRITE_SEQUENCER_45 0x302D +#define WM8915_WRITE_SEQUENCER_46 0x302E +#define WM8915_WRITE_SEQUENCER_47 0x302F +#define WM8915_WRITE_SEQUENCER_48 0x3030 +#define WM8915_WRITE_SEQUENCER_49 0x3031 +#define WM8915_WRITE_SEQUENCER_50 0x3032 +#define WM8915_WRITE_SEQUENCER_51 0x3033 +#define WM8915_WRITE_SEQUENCER_52 0x3034 +#define WM8915_WRITE_SEQUENCER_53 0x3035 +#define WM8915_WRITE_SEQUENCER_54 0x3036 +#define WM8915_WRITE_SEQUENCER_55 0x3037 +#define WM8915_WRITE_SEQUENCER_56 0x3038 +#define WM8915_WRITE_SEQUENCER_57 0x3039 +#define WM8915_WRITE_SEQUENCER_58 0x303A +#define WM8915_WRITE_SEQUENCER_59 0x303B +#define WM8915_WRITE_SEQUENCER_60 0x303C +#define WM8915_WRITE_SEQUENCER_61 0x303D +#define WM8915_WRITE_SEQUENCER_62 0x303E +#define WM8915_WRITE_SEQUENCER_63 0x303F +#define WM8915_WRITE_SEQUENCER_64 0x3040 +#define WM8915_WRITE_SEQUENCER_65 0x3041 +#define WM8915_WRITE_SEQUENCER_66 0x3042 +#define WM8915_WRITE_SEQUENCER_67 0x3043 +#define WM8915_WRITE_SEQUENCER_68 0x3044 +#define WM8915_WRITE_SEQUENCER_69 0x3045 +#define WM8915_WRITE_SEQUENCER_70 0x3046 +#define WM8915_WRITE_SEQUENCER_71 0x3047 +#define WM8915_WRITE_SEQUENCER_72 0x3048 +#define WM8915_WRITE_SEQUENCER_73 0x3049 +#define WM8915_WRITE_SEQUENCER_74 0x304A +#define WM8915_WRITE_SEQUENCER_75 0x304B +#define WM8915_WRITE_SEQUENCER_76 0x304C +#define WM8915_WRITE_SEQUENCER_77 0x304D +#define WM8915_WRITE_SEQUENCER_78 0x304E +#define WM8915_WRITE_SEQUENCER_79 0x304F +#define WM8915_WRITE_SEQUENCER_80 0x3050 +#define WM8915_WRITE_SEQUENCER_81 0x3051 +#define WM8915_WRITE_SEQUENCER_82 0x3052 +#define WM8915_WRITE_SEQUENCER_83 0x3053 +#define WM8915_WRITE_SEQUENCER_84 0x3054 +#define WM8915_WRITE_SEQUENCER_85 0x3055 +#define WM8915_WRITE_SEQUENCER_86 0x3056 +#define WM8915_WRITE_SEQUENCER_87 0x3057 +#define WM8915_WRITE_SEQUENCER_88 0x3058 +#define WM8915_WRITE_SEQUENCER_89 0x3059 +#define WM8915_WRITE_SEQUENCER_90 0x305A +#define WM8915_WRITE_SEQUENCER_91 0x305B +#define WM8915_WRITE_SEQUENCER_92 0x305C +#define WM8915_WRITE_SEQUENCER_93 0x305D +#define WM8915_WRITE_SEQUENCER_94 0x305E +#define WM8915_WRITE_SEQUENCER_95 0x305F +#define WM8915_WRITE_SEQUENCER_96 0x3060 +#define WM8915_WRITE_SEQUENCER_97 0x3061 +#define WM8915_WRITE_SEQUENCER_98 0x3062 +#define WM8915_WRITE_SEQUENCER_99 0x3063 +#define WM8915_WRITE_SEQUENCER_100 0x3064 +#define WM8915_WRITE_SEQUENCER_101 0x3065 +#define WM8915_WRITE_SEQUENCER_102 0x3066 +#define WM8915_WRITE_SEQUENCER_103 0x3067 +#define WM8915_WRITE_SEQUENCER_104 0x3068 +#define WM8915_WRITE_SEQUENCER_105 0x3069 +#define WM8915_WRITE_SEQUENCER_106 0x306A +#define WM8915_WRITE_SEQUENCER_107 0x306B +#define WM8915_WRITE_SEQUENCER_108 0x306C +#define WM8915_WRITE_SEQUENCER_109 0x306D +#define WM8915_WRITE_SEQUENCER_110 0x306E +#define WM8915_WRITE_SEQUENCER_111 0x306F +#define WM8915_WRITE_SEQUENCER_112 0x3070 +#define WM8915_WRITE_SEQUENCER_113 0x3071 +#define WM8915_WRITE_SEQUENCER_114 0x3072 +#define WM8915_WRITE_SEQUENCER_115 0x3073 +#define WM8915_WRITE_SEQUENCER_116 0x3074 +#define WM8915_WRITE_SEQUENCER_117 0x3075 +#define WM8915_WRITE_SEQUENCER_118 0x3076 +#define WM8915_WRITE_SEQUENCER_119 0x3077 +#define WM8915_WRITE_SEQUENCER_120 0x3078 +#define WM8915_WRITE_SEQUENCER_121 0x3079 +#define WM8915_WRITE_SEQUENCER_122 0x307A +#define WM8915_WRITE_SEQUENCER_123 0x307B +#define WM8915_WRITE_SEQUENCER_124 0x307C +#define WM8915_WRITE_SEQUENCER_125 0x307D +#define WM8915_WRITE_SEQUENCER_126 0x307E +#define WM8915_WRITE_SEQUENCER_127 0x307F +#define WM8915_WRITE_SEQUENCER_128 0x3080 +#define WM8915_WRITE_SEQUENCER_129 0x3081 +#define WM8915_WRITE_SEQUENCER_130 0x3082 +#define WM8915_WRITE_SEQUENCER_131 0x3083 +#define WM8915_WRITE_SEQUENCER_132 0x3084 +#define WM8915_WRITE_SEQUENCER_133 0x3085 +#define WM8915_WRITE_SEQUENCER_134 0x3086 +#define WM8915_WRITE_SEQUENCER_135 0x3087 +#define WM8915_WRITE_SEQUENCER_136 0x3088 +#define WM8915_WRITE_SEQUENCER_137 0x3089 +#define WM8915_WRITE_SEQUENCER_138 0x308A +#define WM8915_WRITE_SEQUENCER_139 0x308B +#define WM8915_WRITE_SEQUENCER_140 0x308C +#define WM8915_WRITE_SEQUENCER_141 0x308D +#define WM8915_WRITE_SEQUENCER_142 0x308E +#define WM8915_WRITE_SEQUENCER_143 0x308F +#define WM8915_WRITE_SEQUENCER_144 0x3090 +#define WM8915_WRITE_SEQUENCER_145 0x3091 +#define WM8915_WRITE_SEQUENCER_146 0x3092 +#define WM8915_WRITE_SEQUENCER_147 0x3093 +#define WM8915_WRITE_SEQUENCER_148 0x3094 +#define WM8915_WRITE_SEQUENCER_149 0x3095 +#define WM8915_WRITE_SEQUENCER_150 0x3096 +#define WM8915_WRITE_SEQUENCER_151 0x3097 +#define WM8915_WRITE_SEQUENCER_152 0x3098 +#define WM8915_WRITE_SEQUENCER_153 0x3099 +#define WM8915_WRITE_SEQUENCER_154 0x309A +#define WM8915_WRITE_SEQUENCER_155 0x309B +#define WM8915_WRITE_SEQUENCER_156 0x309C +#define WM8915_WRITE_SEQUENCER_157 0x309D +#define WM8915_WRITE_SEQUENCER_158 0x309E +#define WM8915_WRITE_SEQUENCER_159 0x309F +#define WM8915_WRITE_SEQUENCER_160 0x30A0 +#define WM8915_WRITE_SEQUENCER_161 0x30A1 +#define WM8915_WRITE_SEQUENCER_162 0x30A2 +#define WM8915_WRITE_SEQUENCER_163 0x30A3 +#define WM8915_WRITE_SEQUENCER_164 0x30A4 +#define WM8915_WRITE_SEQUENCER_165 0x30A5 +#define WM8915_WRITE_SEQUENCER_166 0x30A6 +#define WM8915_WRITE_SEQUENCER_167 0x30A7 +#define WM8915_WRITE_SEQUENCER_168 0x30A8 +#define WM8915_WRITE_SEQUENCER_169 0x30A9 +#define WM8915_WRITE_SEQUENCER_170 0x30AA +#define WM8915_WRITE_SEQUENCER_171 0x30AB +#define WM8915_WRITE_SEQUENCER_172 0x30AC +#define WM8915_WRITE_SEQUENCER_173 0x30AD +#define WM8915_WRITE_SEQUENCER_174 0x30AE +#define WM8915_WRITE_SEQUENCER_175 0x30AF +#define WM8915_WRITE_SEQUENCER_176 0x30B0 +#define WM8915_WRITE_SEQUENCER_177 0x30B1 +#define WM8915_WRITE_SEQUENCER_178 0x30B2 +#define WM8915_WRITE_SEQUENCER_179 0x30B3 +#define WM8915_WRITE_SEQUENCER_180 0x30B4 +#define WM8915_WRITE_SEQUENCER_181 0x30B5 +#define WM8915_WRITE_SEQUENCER_182 0x30B6 +#define WM8915_WRITE_SEQUENCER_183 0x30B7 +#define WM8915_WRITE_SEQUENCER_184 0x30B8 +#define WM8915_WRITE_SEQUENCER_185 0x30B9 +#define WM8915_WRITE_SEQUENCER_186 0x30BA +#define WM8915_WRITE_SEQUENCER_187 0x30BB +#define WM8915_WRITE_SEQUENCER_188 0x30BC +#define WM8915_WRITE_SEQUENCER_189 0x30BD +#define WM8915_WRITE_SEQUENCER_190 0x30BE +#define WM8915_WRITE_SEQUENCER_191 0x30BF +#define WM8915_WRITE_SEQUENCER_192 0x30C0 +#define WM8915_WRITE_SEQUENCER_193 0x30C1 +#define WM8915_WRITE_SEQUENCER_194 0x30C2 +#define WM8915_WRITE_SEQUENCER_195 0x30C3 +#define WM8915_WRITE_SEQUENCER_196 0x30C4 +#define WM8915_WRITE_SEQUENCER_197 0x30C5 +#define WM8915_WRITE_SEQUENCER_198 0x30C6 +#define WM8915_WRITE_SEQUENCER_199 0x30C7 +#define WM8915_WRITE_SEQUENCER_200 0x30C8 +#define WM8915_WRITE_SEQUENCER_201 0x30C9 +#define WM8915_WRITE_SEQUENCER_202 0x30CA +#define WM8915_WRITE_SEQUENCER_203 0x30CB +#define WM8915_WRITE_SEQUENCER_204 0x30CC +#define WM8915_WRITE_SEQUENCER_205 0x30CD +#define WM8915_WRITE_SEQUENCER_206 0x30CE +#define WM8915_WRITE_SEQUENCER_207 0x30CF +#define WM8915_WRITE_SEQUENCER_208 0x30D0 +#define WM8915_WRITE_SEQUENCER_209 0x30D1 +#define WM8915_WRITE_SEQUENCER_210 0x30D2 +#define WM8915_WRITE_SEQUENCER_211 0x30D3 +#define WM8915_WRITE_SEQUENCER_212 0x30D4 +#define WM8915_WRITE_SEQUENCER_213 0x30D5 +#define WM8915_WRITE_SEQUENCER_214 0x30D6 +#define WM8915_WRITE_SEQUENCER_215 0x30D7 +#define WM8915_WRITE_SEQUENCER_216 0x30D8 +#define WM8915_WRITE_SEQUENCER_217 0x30D9 +#define WM8915_WRITE_SEQUENCER_218 0x30DA +#define WM8915_WRITE_SEQUENCER_219 0x30DB +#define WM8915_WRITE_SEQUENCER_220 0x30DC +#define WM8915_WRITE_SEQUENCER_221 0x30DD +#define WM8915_WRITE_SEQUENCER_222 0x30DE +#define WM8915_WRITE_SEQUENCER_223 0x30DF +#define WM8915_WRITE_SEQUENCER_224 0x30E0 +#define WM8915_WRITE_SEQUENCER_225 0x30E1 +#define WM8915_WRITE_SEQUENCER_226 0x30E2 +#define WM8915_WRITE_SEQUENCER_227 0x30E3 +#define WM8915_WRITE_SEQUENCER_228 0x30E4 +#define WM8915_WRITE_SEQUENCER_229 0x30E5 +#define WM8915_WRITE_SEQUENCER_230 0x30E6 +#define WM8915_WRITE_SEQUENCER_231 0x30E7 +#define WM8915_WRITE_SEQUENCER_232 0x30E8 +#define WM8915_WRITE_SEQUENCER_233 0x30E9 +#define WM8915_WRITE_SEQUENCER_234 0x30EA +#define WM8915_WRITE_SEQUENCER_235 0x30EB +#define WM8915_WRITE_SEQUENCER_236 0x30EC +#define WM8915_WRITE_SEQUENCER_237 0x30ED +#define WM8915_WRITE_SEQUENCER_238 0x30EE +#define WM8915_WRITE_SEQUENCER_239 0x30EF +#define WM8915_WRITE_SEQUENCER_240 0x30F0 +#define WM8915_WRITE_SEQUENCER_241 0x30F1 +#define WM8915_WRITE_SEQUENCER_242 0x30F2 +#define WM8915_WRITE_SEQUENCER_243 0x30F3 +#define WM8915_WRITE_SEQUENCER_244 0x30F4 +#define WM8915_WRITE_SEQUENCER_245 0x30F5 +#define WM8915_WRITE_SEQUENCER_246 0x30F6 +#define WM8915_WRITE_SEQUENCER_247 0x30F7 +#define WM8915_WRITE_SEQUENCER_248 0x30F8 +#define WM8915_WRITE_SEQUENCER_249 0x30F9 +#define WM8915_WRITE_SEQUENCER_250 0x30FA +#define WM8915_WRITE_SEQUENCER_251 0x30FB +#define WM8915_WRITE_SEQUENCER_252 0x30FC +#define WM8915_WRITE_SEQUENCER_253 0x30FD +#define WM8915_WRITE_SEQUENCER_254 0x30FE +#define WM8915_WRITE_SEQUENCER_255 0x30FF +#define WM8915_WRITE_SEQUENCER_256 0x3100 +#define WM8915_WRITE_SEQUENCER_257 0x3101 +#define WM8915_WRITE_SEQUENCER_258 0x3102 +#define WM8915_WRITE_SEQUENCER_259 0x3103 +#define WM8915_WRITE_SEQUENCER_260 0x3104 +#define WM8915_WRITE_SEQUENCER_261 0x3105 +#define WM8915_WRITE_SEQUENCER_262 0x3106 +#define WM8915_WRITE_SEQUENCER_263 0x3107 +#define WM8915_WRITE_SEQUENCER_264 0x3108 +#define WM8915_WRITE_SEQUENCER_265 0x3109 +#define WM8915_WRITE_SEQUENCER_266 0x310A +#define WM8915_WRITE_SEQUENCER_267 0x310B +#define WM8915_WRITE_SEQUENCER_268 0x310C +#define WM8915_WRITE_SEQUENCER_269 0x310D +#define WM8915_WRITE_SEQUENCER_270 0x310E +#define WM8915_WRITE_SEQUENCER_271 0x310F +#define WM8915_WRITE_SEQUENCER_272 0x3110 +#define WM8915_WRITE_SEQUENCER_273 0x3111 +#define WM8915_WRITE_SEQUENCER_274 0x3112 +#define WM8915_WRITE_SEQUENCER_275 0x3113 +#define WM8915_WRITE_SEQUENCER_276 0x3114 +#define WM8915_WRITE_SEQUENCER_277 0x3115 +#define WM8915_WRITE_SEQUENCER_278 0x3116 +#define WM8915_WRITE_SEQUENCER_279 0x3117 +#define WM8915_WRITE_SEQUENCER_280 0x3118 +#define WM8915_WRITE_SEQUENCER_281 0x3119 +#define WM8915_WRITE_SEQUENCER_282 0x311A +#define WM8915_WRITE_SEQUENCER_283 0x311B +#define WM8915_WRITE_SEQUENCER_284 0x311C +#define WM8915_WRITE_SEQUENCER_285 0x311D +#define WM8915_WRITE_SEQUENCER_286 0x311E +#define WM8915_WRITE_SEQUENCER_287 0x311F +#define WM8915_WRITE_SEQUENCER_288 0x3120 +#define WM8915_WRITE_SEQUENCER_289 0x3121 +#define WM8915_WRITE_SEQUENCER_290 0x3122 +#define WM8915_WRITE_SEQUENCER_291 0x3123 +#define WM8915_WRITE_SEQUENCER_292 0x3124 +#define WM8915_WRITE_SEQUENCER_293 0x3125 +#define WM8915_WRITE_SEQUENCER_294 0x3126 +#define WM8915_WRITE_SEQUENCER_295 0x3127 +#define WM8915_WRITE_SEQUENCER_296 0x3128 +#define WM8915_WRITE_SEQUENCER_297 0x3129 +#define WM8915_WRITE_SEQUENCER_298 0x312A +#define WM8915_WRITE_SEQUENCER_299 0x312B +#define WM8915_WRITE_SEQUENCER_300 0x312C +#define WM8915_WRITE_SEQUENCER_301 0x312D +#define WM8915_WRITE_SEQUENCER_302 0x312E +#define WM8915_WRITE_SEQUENCER_303 0x312F +#define WM8915_WRITE_SEQUENCER_304 0x3130 +#define WM8915_WRITE_SEQUENCER_305 0x3131 +#define WM8915_WRITE_SEQUENCER_306 0x3132 +#define WM8915_WRITE_SEQUENCER_307 0x3133 +#define WM8915_WRITE_SEQUENCER_308 0x3134 +#define WM8915_WRITE_SEQUENCER_309 0x3135 +#define WM8915_WRITE_SEQUENCER_310 0x3136 +#define WM8915_WRITE_SEQUENCER_311 0x3137 +#define WM8915_WRITE_SEQUENCER_312 0x3138 +#define WM8915_WRITE_SEQUENCER_313 0x3139 +#define WM8915_WRITE_SEQUENCER_314 0x313A +#define WM8915_WRITE_SEQUENCER_315 0x313B +#define WM8915_WRITE_SEQUENCER_316 0x313C +#define WM8915_WRITE_SEQUENCER_317 0x313D +#define WM8915_WRITE_SEQUENCER_318 0x313E +#define WM8915_WRITE_SEQUENCER_319 0x313F +#define WM8915_WRITE_SEQUENCER_320 0x3140 +#define WM8915_WRITE_SEQUENCER_321 0x3141 +#define WM8915_WRITE_SEQUENCER_322 0x3142 +#define WM8915_WRITE_SEQUENCER_323 0x3143 +#define WM8915_WRITE_SEQUENCER_324 0x3144 +#define WM8915_WRITE_SEQUENCER_325 0x3145 +#define WM8915_WRITE_SEQUENCER_326 0x3146 +#define WM8915_WRITE_SEQUENCER_327 0x3147 +#define WM8915_WRITE_SEQUENCER_328 0x3148 +#define WM8915_WRITE_SEQUENCER_329 0x3149 +#define WM8915_WRITE_SEQUENCER_330 0x314A +#define WM8915_WRITE_SEQUENCER_331 0x314B +#define WM8915_WRITE_SEQUENCER_332 0x314C +#define WM8915_WRITE_SEQUENCER_333 0x314D +#define WM8915_WRITE_SEQUENCER_334 0x314E +#define WM8915_WRITE_SEQUENCER_335 0x314F +#define WM8915_WRITE_SEQUENCER_336 0x3150 +#define WM8915_WRITE_SEQUENCER_337 0x3151 +#define WM8915_WRITE_SEQUENCER_338 0x3152 +#define WM8915_WRITE_SEQUENCER_339 0x3153 +#define WM8915_WRITE_SEQUENCER_340 0x3154 +#define WM8915_WRITE_SEQUENCER_341 0x3155 +#define WM8915_WRITE_SEQUENCER_342 0x3156 +#define WM8915_WRITE_SEQUENCER_343 0x3157 +#define WM8915_WRITE_SEQUENCER_344 0x3158 +#define WM8915_WRITE_SEQUENCER_345 0x3159 +#define WM8915_WRITE_SEQUENCER_346 0x315A +#define WM8915_WRITE_SEQUENCER_347 0x315B +#define WM8915_WRITE_SEQUENCER_348 0x315C +#define WM8915_WRITE_SEQUENCER_349 0x315D +#define WM8915_WRITE_SEQUENCER_350 0x315E +#define WM8915_WRITE_SEQUENCER_351 0x315F +#define WM8915_WRITE_SEQUENCER_352 0x3160 +#define WM8915_WRITE_SEQUENCER_353 0x3161 +#define WM8915_WRITE_SEQUENCER_354 0x3162 +#define WM8915_WRITE_SEQUENCER_355 0x3163 +#define WM8915_WRITE_SEQUENCER_356 0x3164 +#define WM8915_WRITE_SEQUENCER_357 0x3165 +#define WM8915_WRITE_SEQUENCER_358 0x3166 +#define WM8915_WRITE_SEQUENCER_359 0x3167 +#define WM8915_WRITE_SEQUENCER_360 0x3168 +#define WM8915_WRITE_SEQUENCER_361 0x3169 +#define WM8915_WRITE_SEQUENCER_362 0x316A +#define WM8915_WRITE_SEQUENCER_363 0x316B +#define WM8915_WRITE_SEQUENCER_364 0x316C +#define WM8915_WRITE_SEQUENCER_365 0x316D +#define WM8915_WRITE_SEQUENCER_366 0x316E +#define WM8915_WRITE_SEQUENCER_367 0x316F +#define WM8915_WRITE_SEQUENCER_368 0x3170 +#define WM8915_WRITE_SEQUENCER_369 0x3171 +#define WM8915_WRITE_SEQUENCER_370 0x3172 +#define WM8915_WRITE_SEQUENCER_371 0x3173 +#define WM8915_WRITE_SEQUENCER_372 0x3174 +#define WM8915_WRITE_SEQUENCER_373 0x3175 +#define WM8915_WRITE_SEQUENCER_374 0x3176 +#define WM8915_WRITE_SEQUENCER_375 0x3177 +#define WM8915_WRITE_SEQUENCER_376 0x3178 +#define WM8915_WRITE_SEQUENCER_377 0x3179 +#define WM8915_WRITE_SEQUENCER_378 0x317A +#define WM8915_WRITE_SEQUENCER_379 0x317B +#define WM8915_WRITE_SEQUENCER_380 0x317C +#define WM8915_WRITE_SEQUENCER_381 0x317D +#define WM8915_WRITE_SEQUENCER_382 0x317E +#define WM8915_WRITE_SEQUENCER_383 0x317F +#define WM8915_WRITE_SEQUENCER_384 0x3180 +#define WM8915_WRITE_SEQUENCER_385 0x3181 +#define WM8915_WRITE_SEQUENCER_386 0x3182 +#define WM8915_WRITE_SEQUENCER_387 0x3183 +#define WM8915_WRITE_SEQUENCER_388 0x3184 +#define WM8915_WRITE_SEQUENCER_389 0x3185 +#define WM8915_WRITE_SEQUENCER_390 0x3186 +#define WM8915_WRITE_SEQUENCER_391 0x3187 +#define WM8915_WRITE_SEQUENCER_392 0x3188 +#define WM8915_WRITE_SEQUENCER_393 0x3189 +#define WM8915_WRITE_SEQUENCER_394 0x318A +#define WM8915_WRITE_SEQUENCER_395 0x318B +#define WM8915_WRITE_SEQUENCER_396 0x318C +#define WM8915_WRITE_SEQUENCER_397 0x318D +#define WM8915_WRITE_SEQUENCER_398 0x318E +#define WM8915_WRITE_SEQUENCER_399 0x318F +#define WM8915_WRITE_SEQUENCER_400 0x3190 +#define WM8915_WRITE_SEQUENCER_401 0x3191 +#define WM8915_WRITE_SEQUENCER_402 0x3192 +#define WM8915_WRITE_SEQUENCER_403 0x3193 +#define WM8915_WRITE_SEQUENCER_404 0x3194 +#define WM8915_WRITE_SEQUENCER_405 0x3195 +#define WM8915_WRITE_SEQUENCER_406 0x3196 +#define WM8915_WRITE_SEQUENCER_407 0x3197 +#define WM8915_WRITE_SEQUENCER_408 0x3198 +#define WM8915_WRITE_SEQUENCER_409 0x3199 +#define WM8915_WRITE_SEQUENCER_410 0x319A +#define WM8915_WRITE_SEQUENCER_411 0x319B +#define WM8915_WRITE_SEQUENCER_412 0x319C +#define WM8915_WRITE_SEQUENCER_413 0x319D +#define WM8915_WRITE_SEQUENCER_414 0x319E +#define WM8915_WRITE_SEQUENCER_415 0x319F +#define WM8915_WRITE_SEQUENCER_416 0x31A0 +#define WM8915_WRITE_SEQUENCER_417 0x31A1 +#define WM8915_WRITE_SEQUENCER_418 0x31A2 +#define WM8915_WRITE_SEQUENCER_419 0x31A3 +#define WM8915_WRITE_SEQUENCER_420 0x31A4 +#define WM8915_WRITE_SEQUENCER_421 0x31A5 +#define WM8915_WRITE_SEQUENCER_422 0x31A6 +#define WM8915_WRITE_SEQUENCER_423 0x31A7 +#define WM8915_WRITE_SEQUENCER_424 0x31A8 +#define WM8915_WRITE_SEQUENCER_425 0x31A9 +#define WM8915_WRITE_SEQUENCER_426 0x31AA +#define WM8915_WRITE_SEQUENCER_427 0x31AB +#define WM8915_WRITE_SEQUENCER_428 0x31AC +#define WM8915_WRITE_SEQUENCER_429 0x31AD +#define WM8915_WRITE_SEQUENCER_430 0x31AE +#define WM8915_WRITE_SEQUENCER_431 0x31AF +#define WM8915_WRITE_SEQUENCER_432 0x31B0 +#define WM8915_WRITE_SEQUENCER_433 0x31B1 +#define WM8915_WRITE_SEQUENCER_434 0x31B2 +#define WM8915_WRITE_SEQUENCER_435 0x31B3 +#define WM8915_WRITE_SEQUENCER_436 0x31B4 +#define WM8915_WRITE_SEQUENCER_437 0x31B5 +#define WM8915_WRITE_SEQUENCER_438 0x31B6 +#define WM8915_WRITE_SEQUENCER_439 0x31B7 +#define WM8915_WRITE_SEQUENCER_440 0x31B8 +#define WM8915_WRITE_SEQUENCER_441 0x31B9 +#define WM8915_WRITE_SEQUENCER_442 0x31BA +#define WM8915_WRITE_SEQUENCER_443 0x31BB +#define WM8915_WRITE_SEQUENCER_444 0x31BC +#define WM8915_WRITE_SEQUENCER_445 0x31BD +#define WM8915_WRITE_SEQUENCER_446 0x31BE +#define WM8915_WRITE_SEQUENCER_447 0x31BF +#define WM8915_WRITE_SEQUENCER_448 0x31C0 +#define WM8915_WRITE_SEQUENCER_449 0x31C1 +#define WM8915_WRITE_SEQUENCER_450 0x31C2 +#define WM8915_WRITE_SEQUENCER_451 0x31C3 +#define WM8915_WRITE_SEQUENCER_452 0x31C4 +#define WM8915_WRITE_SEQUENCER_453 0x31C5 +#define WM8915_WRITE_SEQUENCER_454 0x31C6 +#define WM8915_WRITE_SEQUENCER_455 0x31C7 +#define WM8915_WRITE_SEQUENCER_456 0x31C8 +#define WM8915_WRITE_SEQUENCER_457 0x31C9 +#define WM8915_WRITE_SEQUENCER_458 0x31CA +#define WM8915_WRITE_SEQUENCER_459 0x31CB +#define WM8915_WRITE_SEQUENCER_460 0x31CC +#define WM8915_WRITE_SEQUENCER_461 0x31CD +#define WM8915_WRITE_SEQUENCER_462 0x31CE +#define WM8915_WRITE_SEQUENCER_463 0x31CF +#define WM8915_WRITE_SEQUENCER_464 0x31D0 +#define WM8915_WRITE_SEQUENCER_465 0x31D1 +#define WM8915_WRITE_SEQUENCER_466 0x31D2 +#define WM8915_WRITE_SEQUENCER_467 0x31D3 +#define WM8915_WRITE_SEQUENCER_468 0x31D4 +#define WM8915_WRITE_SEQUENCER_469 0x31D5 +#define WM8915_WRITE_SEQUENCER_470 0x31D6 +#define WM8915_WRITE_SEQUENCER_471 0x31D7 +#define WM8915_WRITE_SEQUENCER_472 0x31D8 +#define WM8915_WRITE_SEQUENCER_473 0x31D9 +#define WM8915_WRITE_SEQUENCER_474 0x31DA +#define WM8915_WRITE_SEQUENCER_475 0x31DB +#define WM8915_WRITE_SEQUENCER_476 0x31DC +#define WM8915_WRITE_SEQUENCER_477 0x31DD +#define WM8915_WRITE_SEQUENCER_478 0x31DE +#define WM8915_WRITE_SEQUENCER_479 0x31DF +#define WM8915_WRITE_SEQUENCER_480 0x31E0 +#define WM8915_WRITE_SEQUENCER_481 0x31E1 +#define WM8915_WRITE_SEQUENCER_482 0x31E2 +#define WM8915_WRITE_SEQUENCER_483 0x31E3 +#define WM8915_WRITE_SEQUENCER_484 0x31E4 +#define WM8915_WRITE_SEQUENCER_485 0x31E5 +#define WM8915_WRITE_SEQUENCER_486 0x31E6 +#define WM8915_WRITE_SEQUENCER_487 0x31E7 +#define WM8915_WRITE_SEQUENCER_488 0x31E8 +#define WM8915_WRITE_SEQUENCER_489 0x31E9 +#define WM8915_WRITE_SEQUENCER_490 0x31EA +#define WM8915_WRITE_SEQUENCER_491 0x31EB +#define WM8915_WRITE_SEQUENCER_492 0x31EC +#define WM8915_WRITE_SEQUENCER_493 0x31ED +#define WM8915_WRITE_SEQUENCER_494 0x31EE +#define WM8915_WRITE_SEQUENCER_495 0x31EF +#define WM8915_WRITE_SEQUENCER_496 0x31F0 +#define WM8915_WRITE_SEQUENCER_497 0x31F1 +#define WM8915_WRITE_SEQUENCER_498 0x31F2 +#define WM8915_WRITE_SEQUENCER_499 0x31F3 +#define WM8915_WRITE_SEQUENCER_500 0x31F4 +#define WM8915_WRITE_SEQUENCER_501 0x31F5 +#define WM8915_WRITE_SEQUENCER_502 0x31F6 +#define WM8915_WRITE_SEQUENCER_503 0x31F7 +#define WM8915_WRITE_SEQUENCER_504 0x31F8 +#define WM8915_WRITE_SEQUENCER_505 0x31F9 +#define WM8915_WRITE_SEQUENCER_506 0x31FA +#define WM8915_WRITE_SEQUENCER_507 0x31FB +#define WM8915_WRITE_SEQUENCER_508 0x31FC +#define WM8915_WRITE_SEQUENCER_509 0x31FD +#define WM8915_WRITE_SEQUENCER_510 0x31FE +#define WM8915_WRITE_SEQUENCER_511 0x31FF + +#define WM8915_REGISTER_COUNT 706 +#define WM8915_MAX_REGISTER 0x31FF + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Software Reset + */ +#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */ +#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */ +#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */ + +/* + * R1 (0x01) - Power Management (1) + */ +#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */ +#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */ +#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */ +#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ +#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */ +#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */ +#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */ +#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ +#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */ +#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */ +#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */ +#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */ +#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */ +#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */ +#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */ +#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */ +#define WM8915_BG_ENA 0x0001 /* BG_ENA */ +#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */ +#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */ +#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */ + +/* + * R2 (0x02) - Power Management (2) + */ +#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */ +#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */ +#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */ +#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ +#define WM8915_INL_ENA 0x0020 /* INL_ENA */ +#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */ +#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */ +#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */ +#define WM8915_INR_ENA 0x0010 /* INR_ENA */ +#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */ +#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */ +#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */ +#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */ +#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */ +#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */ +#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */ + +/* + * R3 (0x03) - Power Management (3) + */ +#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */ +#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */ +#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */ +#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */ +#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */ +#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */ +#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */ +#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */ +#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */ +#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */ +#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */ +#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */ +#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */ +#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */ +#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */ +#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */ +#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */ +#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */ +#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */ +#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */ +#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */ +#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */ +#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */ +#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */ +#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */ +#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ +#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ +#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ +#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */ +#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ +#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ +#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ + +/* + * R4 (0x04) - Power Management (4) + */ +#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */ + +/* + * R5 (0x05) - Power Management (5) + */ +#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */ +#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */ +#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */ +#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */ +#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */ +#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */ +#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */ +#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */ +#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */ +#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */ +#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */ +#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */ +#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */ +#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */ +#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */ +#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */ +#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */ +#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */ +#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */ +#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */ +#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */ +#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */ +#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */ +#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */ + +/* + * R6 (0x06) - Power Management (6) + */ +#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */ + +/* + * R7 (0x07) - Power Management (7) + */ +#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */ +#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */ +#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */ +#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */ +#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */ +#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */ +#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */ +#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */ +#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */ +#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */ +#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */ +#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */ +#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */ +#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */ + +/* + * R8 (0x08) - Power Management (8) + */ +#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */ +#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */ +#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */ +#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */ +#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */ +#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */ +#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */ +#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */ +#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */ +#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */ +#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */ + +/* + * R16 (0x10) - Left Line Input Volume + */ +#define WM8915_IN1_VU 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */ +#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */ +#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */ +#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */ +#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */ +#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */ +#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */ +#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */ + +/* + * R17 (0x11) - Right Line Input Volume + */ +#define WM8915_IN1_VU 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */ +#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */ +#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */ +#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */ +#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */ +#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */ +#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */ +#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */ + +/* + * R18 (0x12) - Line Input Control + */ +#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */ +#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */ +#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */ +#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */ +#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */ +#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */ + +/* + * R21 (0x15) - DAC1 HPOUT1 Volume + */ +#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */ +#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */ +#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */ +#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */ +#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */ +#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */ + +/* + * R22 (0x16) - DAC2 HPOUT2 Volume + */ +#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */ +#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */ +#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */ +#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */ +#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */ +#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */ + +/* + * R24 (0x18) - DAC1 Left Volume + */ +#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */ +#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */ +#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */ +#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */ +#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */ +#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */ + +/* + * R25 (0x19) - DAC1 Right Volume + */ +#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */ +#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */ +#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */ +#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */ +#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */ +#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */ + +/* + * R26 (0x1A) - DAC2 Left Volume + */ +#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */ +#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */ +#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */ +#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */ +#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */ +#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */ + +/* + * R27 (0x1B) - DAC2 Right Volume + */ +#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */ +#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */ +#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */ +#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */ +#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */ +#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */ + +/* + * R28 (0x1C) - Output1 Left Volume + */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */ +#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */ +#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */ + +/* + * R29 (0x1D) - Output1 Right Volume + */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */ +#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */ +#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */ + +/* + * R30 (0x1E) - Output2 Left Volume + */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */ +#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */ +#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */ + +/* + * R31 (0x1F) - Output2 Right Volume + */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */ +#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */ +#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */ + +/* + * R32 (0x20) - MICBIAS (1) + */ +#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */ +#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ +#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ +#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ +#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */ +#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */ +#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */ +#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ +#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */ +#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */ +#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */ +#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */ +#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */ +#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */ +#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ + +/* + * R33 (0x21) - MICBIAS (2) + */ +#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */ +#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ +#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ +#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ +#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */ +#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */ +#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */ +#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ +#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */ +#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */ +#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */ +#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */ +#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */ +#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */ +#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ + +/* + * R40 (0x28) - LDO 1 + */ +#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */ +#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */ +#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */ +#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */ +#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */ +#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */ +#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */ +#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */ +#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */ +#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */ +#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */ + +/* + * R41 (0x29) - LDO 2 + */ +#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */ +#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */ +#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */ +#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */ +#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */ +#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */ +#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */ +#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */ +#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */ +#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */ +#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ + +/* + * R48 (0x30) - Accessory Detect Mode 1 + */ +#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */ +#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */ +#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */ + +/* + * R49 (0x31) - Accessory Detect Mode 2 + */ +#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */ +#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */ +#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */ +#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */ +#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */ +#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */ +#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */ +#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */ +#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */ +#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */ +#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */ +#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */ + +/* + * R52 (0x34) - Headphone Detect 1 + */ +#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */ +#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */ +#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */ +#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */ +#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */ +#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */ +#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */ +#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */ +#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */ +#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */ +#define WM8915_HP_POLL 0x0001 /* HP_POLL */ +#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */ +#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */ +#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */ + +/* + * R53 (0x35) - Headphone Detect 2 + */ +#define WM8915_HP_DONE 0x0080 /* HP_DONE */ +#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */ +#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */ +#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */ +#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */ +#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */ +#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */ + +/* + * R56 (0x38) - Mic Detect 1 + */ +#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */ +#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */ +#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */ +#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */ +#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */ +#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */ +#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */ +#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */ +#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */ +#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */ +#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */ + +/* + * R57 (0x39) - Mic Detect 2 + */ +#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */ +#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */ +#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */ + +/* + * R58 (0x3A) - Mic Detect 3 + */ +#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ +#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ +#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ +#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */ +#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */ +#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */ +#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */ +#define WM8915_MICD_STS 0x0001 /* MICD_STS */ +#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */ +#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */ +#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */ + +/* + * R64 (0x40) - Charge Pump (1) + */ +#define WM8915_CP_ENA 0x8000 /* CP_ENA */ +#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */ +#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */ +#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */ + +/* + * R65 (0x41) - Charge Pump (2) + */ +#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */ +#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */ +#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */ +#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */ + +/* + * R80 (0x50) - DC Servo (1) + */ +#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */ +#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */ + +/* + * R81 (0x51) - DC Servo (2) + */ +#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */ +#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */ + +/* + * R82 (0x52) - DC Servo (3) + */ +#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */ + +/* + * R84 (0x54) - DC Servo (5) + */ +#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */ + +/* + * R85 (0x55) - DC Servo (6) + */ +#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */ + +/* + * R86 (0x56) - DC Servo (7) + */ +#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */ + +/* + * R87 (0x57) - DC Servo Readback 0 + */ +#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */ + +/* + * R96 (0x60) - Analogue HP (1) + */ +#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */ +#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */ +#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */ +#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */ + +/* + * R97 (0x61) - Analogue HP (2) + */ +#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */ +#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */ +#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */ +#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */ + +/* + * R256 (0x100) - Chip Revision + */ +#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */ +#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */ +#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */ + +/* + * R257 (0x101) - Control Interface (1) + */ +#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */ +#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */ +#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */ +#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */ + +/* + * R272 (0x110) - Write Sequencer Ctrl (1) + */ +#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */ +#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */ +#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */ +#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ +#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ +#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ +#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ +#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ +#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */ +#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */ +#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */ +#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */ +#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */ +#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */ +#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */ + +/* + * R273 (0x111) - Write Sequencer Ctrl (2) + */ +#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */ +#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */ +#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */ +#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ +#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */ + +/* + * R512 (0x200) - AIF Clocking (1) + */ +#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */ +#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */ +#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */ +#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */ +#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */ +#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */ +#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */ +#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */ +#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */ +#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */ +#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ + +/* + * R513 (0x201) - AIF Clocking (2) + */ +#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */ +#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */ +#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */ +#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */ +#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */ +#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */ + +/* + * R520 (0x208) - Clocking (1) + */ +#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */ +#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */ +#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */ +#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */ +#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */ +#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */ +#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */ +#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ +#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */ +#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */ +#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */ +#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */ + +/* + * R521 (0x209) - Clocking (2) + */ +#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */ +#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */ +#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */ +#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */ +#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */ +#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */ +#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */ +#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */ +#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */ + +/* + * R528 (0x210) - AIF Rate + */ +#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */ +#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */ +#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */ +#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */ + +/* + * R544 (0x220) - FLL Control (1) + */ +#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */ +#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */ +#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */ +#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */ +#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */ +#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */ +#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */ +#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */ + +/* + * R545 (0x221) - FLL Control (2) + */ +#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */ +#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */ +#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */ +#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ +#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ +#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ + +/* + * R546 (0x222) - FLL Control (3) + */ +#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */ +#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */ +#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */ + +/* + * R547 (0x223) - FLL Control (4) + */ +#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */ +#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */ +#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */ +#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */ +#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */ +#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */ + +/* + * R548 (0x224) - FLL Control (5) + */ +#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */ +#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */ +#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */ +#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */ +#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */ +#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */ +#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */ +#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */ +#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */ +#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */ +#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */ +#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */ +#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */ +#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */ +#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */ +#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */ +#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */ + +/* + * R549 (0x225) - FLL Control (6) + */ +#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */ +#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */ +#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */ +#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */ +#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */ +#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */ +#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */ + +/* + * R550 (0x226) - FLL EFS 1 + */ +#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */ +#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */ +#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */ + +/* + * R551 (0x227) - FLL EFS 2 + */ +#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */ +#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */ +#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */ +#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */ +#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */ +#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */ +#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */ + +/* + * R768 (0x300) - AIF1 Control + */ +#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */ +#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */ +#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */ +#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ +#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */ +#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */ +#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */ + +/* + * R769 (0x301) - AIF1 BCLK + */ +#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */ +#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */ +#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */ + +/* + * R770 (0x302) - AIF1 TX LRCLK(1) + */ +#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */ +#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */ +#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */ + +/* + * R771 (0x303) - AIF1 TX LRCLK(2) + */ +#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */ +#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */ +#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */ +#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */ + +/* + * R772 (0x304) - AIF1 RX LRCLK(1) + */ +#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */ +#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */ +#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */ + +/* + * R773 (0x305) - AIF1 RX LRCLK(2) + */ +#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */ +#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */ +#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */ +#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */ + +/* + * R774 (0x306) - AIF1TX Data Configuration (1) + */ +#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */ +#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */ +#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */ +#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */ + +/* + * R775 (0x307) - AIF1TX Data Configuration (2) + */ +#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */ +#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */ +#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */ +#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */ + +/* + * R776 (0x308) - AIF1RX Data Configuration + */ +#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */ +#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */ +#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */ +#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */ + +/* + * R777 (0x309) - AIF1TX Channel 0 Configuration + */ +#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */ + +/* + * R778 (0x30A) - AIF1TX Channel 1 Configuration + */ +#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */ + +/* + * R779 (0x30B) - AIF1TX Channel 2 Configuration + */ +#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */ + +/* + * R780 (0x30C) - AIF1TX Channel 3 Configuration + */ +#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */ + +/* + * R781 (0x30D) - AIF1TX Channel 4 Configuration + */ +#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */ + +/* + * R782 (0x30E) - AIF1TX Channel 5 Configuration + */ +#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */ + +/* + * R783 (0x30F) - AIF1RX Channel 0 Configuration + */ +#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */ + +/* + * R784 (0x310) - AIF1RX Channel 1 Configuration + */ +#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */ + +/* + * R785 (0x311) - AIF1RX Channel 2 Configuration + */ +#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */ + +/* + * R786 (0x312) - AIF1RX Channel 3 Configuration + */ +#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */ + +/* + * R787 (0x313) - AIF1RX Channel 4 Configuration + */ +#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */ + +/* + * R788 (0x314) - AIF1RX Channel 5 Configuration + */ +#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */ + +/* + * R789 (0x315) - AIF1RX Mono Configuration + */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */ + +/* + * R794 (0x31A) - AIF1TX Test + */ +#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */ + +/* + * R800 (0x320) - AIF2 Control + */ +#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */ +#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */ +#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */ +#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */ +#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */ +#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */ +#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */ + +/* + * R801 (0x321) - AIF2 BCLK + */ +#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */ +#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */ +#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */ + +/* + * R802 (0x322) - AIF2 TX LRCLK(1) + */ +#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */ +#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */ +#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */ + +/* + * R803 (0x323) - AIF2 TX LRCLK(2) + */ +#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */ +#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */ +#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */ +#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */ + +/* + * R804 (0x324) - AIF2 RX LRCLK(1) + */ +#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */ +#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */ +#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */ + +/* + * R805 (0x325) - AIF2 RX LRCLK(2) + */ +#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */ +#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */ +#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */ +#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */ + +/* + * R806 (0x326) - AIF2TX Data Configuration (1) + */ +#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */ +#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */ +#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */ +#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */ + +/* + * R807 (0x327) - AIF2TX Data Configuration (2) + */ +#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */ +#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */ +#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */ +#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */ + +/* + * R808 (0x328) - AIF2RX Data Configuration + */ +#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */ +#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */ +#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */ +#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */ + +/* + * R809 (0x329) - AIF2TX Channel 0 Configuration + */ +#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */ + +/* + * R810 (0x32A) - AIF2TX Channel 1 Configuration + */ +#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */ + +/* + * R811 (0x32B) - AIF2RX Channel 0 Configuration + */ +#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */ + +/* + * R812 (0x32C) - AIF2RX Channel 1 Configuration + */ +#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */ + +/* + * R813 (0x32D) - AIF2RX Mono Configuration + */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */ + +/* + * R815 (0x32F) - AIF2TX Test + */ +#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */ +#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */ +#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */ +#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */ + +/* + * R1024 (0x400) - DSP1 TX Left Volume + */ +#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */ +#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */ +#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */ +#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */ + +/* + * R1025 (0x401) - DSP1 TX Right Volume + */ +#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */ +#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */ +#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */ +#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */ + +/* + * R1026 (0x402) - DSP1 RX Left Volume + */ +#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */ +#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */ +#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */ +#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */ + +/* + * R1027 (0x403) - DSP1 RX Right Volume + */ +#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */ +#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */ +#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */ +#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */ + +/* + * R1040 (0x410) - DSP1 TX Filters + */ +#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */ +#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */ +#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */ +#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */ +#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */ +#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */ +#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */ +#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */ +#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */ +#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */ +#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */ +#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */ +#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */ +#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */ + +/* + * R1056 (0x420) - DSP1 RX Filters (1) + */ +#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */ +#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */ +#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */ +#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */ + +/* + * R1057 (0x421) - DSP1 RX Filters (2) + */ +#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */ +#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */ +#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */ +#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */ +#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */ +#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */ +#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */ + +/* + * R1088 (0x440) - DSP1 DRC (1) + */ +#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */ + +/* + * R1089 (0x441) - DSP1 DRC (2) + */ +#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */ +#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */ +#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */ +#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */ +#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */ +#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */ +#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */ +#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */ +#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */ +#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */ + +/* + * R1090 (0x442) - DSP1 DRC (3) + */ +#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */ +#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */ +#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */ +#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */ +#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */ +#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */ +#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */ +#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */ +#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */ +#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */ +#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */ +#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */ +#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */ +#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */ +#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */ + +/* + * R1091 (0x443) - DSP1 DRC (4) + */ +#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */ + +/* + * R1092 (0x444) - DSP1 DRC (5) + */ +#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */ + +/* + * R1152 (0x480) - DSP1 RX EQ Gains (1) + */ +#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */ +#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */ +#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */ +#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */ + +/* + * R1153 (0x481) - DSP1 RX EQ Gains (2) + */ +#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */ + +/* + * R1154 (0x482) - DSP1 RX EQ Band 1 A + */ +#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */ + +/* + * R1155 (0x483) - DSP1 RX EQ Band 1 B + */ +#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */ + +/* + * R1156 (0x484) - DSP1 RX EQ Band 1 PG + */ +#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */ + +/* + * R1157 (0x485) - DSP1 RX EQ Band 2 A + */ +#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */ + +/* + * R1158 (0x486) - DSP1 RX EQ Band 2 B + */ +#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */ + +/* + * R1159 (0x487) - DSP1 RX EQ Band 2 C + */ +#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */ + +/* + * R1160 (0x488) - DSP1 RX EQ Band 2 PG + */ +#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */ + +/* + * R1161 (0x489) - DSP1 RX EQ Band 3 A + */ +#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */ + +/* + * R1162 (0x48A) - DSP1 RX EQ Band 3 B + */ +#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */ + +/* + * R1163 (0x48B) - DSP1 RX EQ Band 3 C + */ +#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */ + +/* + * R1164 (0x48C) - DSP1 RX EQ Band 3 PG + */ +#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */ + +/* + * R1165 (0x48D) - DSP1 RX EQ Band 4 A + */ +#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */ + +/* + * R1166 (0x48E) - DSP1 RX EQ Band 4 B + */ +#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */ + +/* + * R1167 (0x48F) - DSP1 RX EQ Band 4 C + */ +#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */ + +/* + * R1168 (0x490) - DSP1 RX EQ Band 4 PG + */ +#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */ + +/* + * R1169 (0x491) - DSP1 RX EQ Band 5 A + */ +#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */ + +/* + * R1170 (0x492) - DSP1 RX EQ Band 5 B + */ +#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */ + +/* + * R1171 (0x493) - DSP1 RX EQ Band 5 PG + */ +#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */ + +/* + * R1280 (0x500) - DSP2 TX Left Volume + */ +#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */ +#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */ +#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */ +#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */ + +/* + * R1281 (0x501) - DSP2 TX Right Volume + */ +#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */ +#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */ +#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */ +#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */ + +/* + * R1282 (0x502) - DSP2 RX Left Volume + */ +#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */ +#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */ +#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */ +#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */ + +/* + * R1283 (0x503) - DSP2 RX Right Volume + */ +#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */ +#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */ +#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */ +#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */ + +/* + * R1296 (0x510) - DSP2 TX Filters + */ +#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */ +#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */ +#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */ +#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */ +#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */ +#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */ +#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */ +#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */ +#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */ +#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */ +#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */ +#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */ +#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */ +#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */ + +/* + * R1312 (0x520) - DSP2 RX Filters (1) + */ +#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */ +#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */ +#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */ +#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */ + +/* + * R1313 (0x521) - DSP2 RX Filters (2) + */ +#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */ +#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */ +#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */ +#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */ +#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */ +#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */ +#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */ + +/* + * R1344 (0x540) - DSP2 DRC (1) + */ +#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */ + +/* + * R1345 (0x541) - DSP2 DRC (2) + */ +#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */ +#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */ +#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */ +#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */ +#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */ +#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */ +#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */ +#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */ +#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */ +#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */ + +/* + * R1346 (0x542) - DSP2 DRC (3) + */ +#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */ +#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */ +#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */ +#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */ +#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */ +#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */ +#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */ +#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */ +#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */ +#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */ +#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */ +#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */ +#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */ +#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */ +#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */ + +/* + * R1347 (0x543) - DSP2 DRC (4) + */ +#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */ + +/* + * R1348 (0x544) - DSP2 DRC (5) + */ +#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */ + +/* + * R1408 (0x580) - DSP2 RX EQ Gains (1) + */ +#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */ +#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */ +#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */ +#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */ + +/* + * R1409 (0x581) - DSP2 RX EQ Gains (2) + */ +#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */ + +/* + * R1410 (0x582) - DSP2 RX EQ Band 1 A + */ +#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */ + +/* + * R1411 (0x583) - DSP2 RX EQ Band 1 B + */ +#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */ + +/* + * R1412 (0x584) - DSP2 RX EQ Band 1 PG + */ +#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */ + +/* + * R1413 (0x585) - DSP2 RX EQ Band 2 A + */ +#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */ + +/* + * R1414 (0x586) - DSP2 RX EQ Band 2 B + */ +#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */ + +/* + * R1415 (0x587) - DSP2 RX EQ Band 2 C + */ +#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */ + +/* + * R1416 (0x588) - DSP2 RX EQ Band 2 PG + */ +#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */ + +/* + * R1417 (0x589) - DSP2 RX EQ Band 3 A + */ +#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */ + +/* + * R1418 (0x58A) - DSP2 RX EQ Band 3 B + */ +#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */ + +/* + * R1419 (0x58B) - DSP2 RX EQ Band 3 C + */ +#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */ + +/* + * R1420 (0x58C) - DSP2 RX EQ Band 3 PG + */ +#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */ + +/* + * R1421 (0x58D) - DSP2 RX EQ Band 4 A + */ +#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */ + +/* + * R1422 (0x58E) - DSP2 RX EQ Band 4 B + */ +#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */ + +/* + * R1423 (0x58F) - DSP2 RX EQ Band 4 C + */ +#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */ + +/* + * R1424 (0x590) - DSP2 RX EQ Band 4 PG + */ +#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */ + +/* + * R1425 (0x591) - DSP2 RX EQ Band 5 A + */ +#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */ + +/* + * R1426 (0x592) - DSP2 RX EQ Band 5 B + */ +#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */ + +/* + * R1427 (0x593) - DSP2 RX EQ Band 5 PG + */ +#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */ + +/* + * R1536 (0x600) - DAC1 Mixer Volumes + */ +#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */ +#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */ +#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */ + +/* + * R1537 (0x601) - DAC1 Left Mixer Routing + */ +#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */ +#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */ +#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */ +#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */ + +/* + * R1538 (0x602) - DAC1 Right Mixer Routing + */ +#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */ +#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */ +#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */ +#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */ + +/* + * R1539 (0x603) - DAC2 Mixer Volumes + */ +#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */ +#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */ +#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */ + +/* + * R1540 (0x604) - DAC2 Left Mixer Routing + */ +#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */ +#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */ +#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */ +#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */ + +/* + * R1541 (0x605) - DAC2 Right Mixer Routing + */ +#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */ +#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */ +#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */ +#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */ + +/* + * R1542 (0x606) - DSP1 TX Left Mixer Routing + */ +#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */ +#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */ +#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */ +#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */ + +/* + * R1543 (0x607) - DSP1 TX Right Mixer Routing + */ +#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */ +#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */ +#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */ +#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */ + +/* + * R1544 (0x608) - DSP2 TX Left Mixer Routing + */ +#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */ +#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */ +#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */ +#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */ + +/* + * R1545 (0x609) - DSP2 TX Right Mixer Routing + */ +#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */ +#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */ +#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */ +#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */ + +/* + * R1546 (0x60A) - DSP TX Mixer Select + */ +#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */ +#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */ +#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */ +#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */ + +/* + * R1552 (0x610) - DAC Softmute + */ +#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */ +#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */ +#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */ +#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ + +/* + * R1568 (0x620) - Oversampling + */ +#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */ +#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */ +#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */ +#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */ +#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */ +#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */ +#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */ +#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */ +#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */ +#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */ +#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */ +#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */ +#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */ +#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */ +#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */ +#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */ + +/* + * R1569 (0x621) - Sidetone + */ +#define WM8915_ST_LPF 0x1000 /* ST_LPF */ +#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */ +#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */ +#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */ +#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */ +#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */ +#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */ +#define WM8915_ST_HPF 0x0040 /* ST_HPF */ +#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */ +#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */ +#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */ +#define WM8915_STR_SEL 0x0002 /* STR_SEL */ +#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */ +#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */ +#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */ +#define WM8915_STL_SEL 0x0001 /* STL_SEL */ +#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */ +#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */ +#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */ + +/* + * R1792 (0x700) - GPIO 1 + */ +#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */ +#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */ +#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */ +#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */ +#define WM8915_GP1_PU 0x4000 /* GP1_PU */ +#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */ +#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */ +#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */ +#define WM8915_GP1_PD 0x2000 /* GP1_PD */ +#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */ +#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */ +#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */ +#define WM8915_GP1_POL 0x0400 /* GP1_POL */ +#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */ +#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */ +#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */ +#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ +#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ +#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ +#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ +#define WM8915_GP1_DB 0x0100 /* GP1_DB */ +#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */ +#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */ +#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */ +#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */ +#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */ +#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */ +#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */ +#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */ +#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */ +#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */ + +/* + * R1793 (0x701) - GPIO 2 + */ +#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */ +#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */ +#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */ +#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */ +#define WM8915_GP2_PU 0x4000 /* GP2_PU */ +#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */ +#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */ +#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */ +#define WM8915_GP2_PD 0x2000 /* GP2_PD */ +#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */ +#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */ +#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */ +#define WM8915_GP2_POL 0x0400 /* GP2_POL */ +#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */ +#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */ +#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */ +#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ +#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ +#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ +#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ +#define WM8915_GP2_DB 0x0100 /* GP2_DB */ +#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */ +#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */ +#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */ +#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */ +#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */ +#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */ +#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */ +#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */ +#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */ +#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */ + +/* + * R1794 (0x702) - GPIO 3 + */ +#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */ +#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */ +#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */ +#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */ +#define WM8915_GP3_PU 0x4000 /* GP3_PU */ +#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */ +#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */ +#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */ +#define WM8915_GP3_PD 0x2000 /* GP3_PD */ +#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */ +#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */ +#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */ +#define WM8915_GP3_POL 0x0400 /* GP3_POL */ +#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */ +#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */ +#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */ +#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ +#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ +#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ +#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ +#define WM8915_GP3_DB 0x0100 /* GP3_DB */ +#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */ +#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */ +#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */ +#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */ +#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */ +#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */ +#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */ +#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */ +#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */ +#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */ + +/* + * R1795 (0x703) - GPIO 4 + */ +#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */ +#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */ +#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */ +#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */ +#define WM8915_GP4_PU 0x4000 /* GP4_PU */ +#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */ +#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */ +#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */ +#define WM8915_GP4_PD 0x2000 /* GP4_PD */ +#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */ +#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */ +#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */ +#define WM8915_GP4_POL 0x0400 /* GP4_POL */ +#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */ +#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */ +#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */ +#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ +#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ +#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ +#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ +#define WM8915_GP4_DB 0x0100 /* GP4_DB */ +#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */ +#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */ +#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */ +#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */ +#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */ +#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */ +#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */ +#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */ +#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */ +#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */ + +/* + * R1796 (0x704) - GPIO 5 + */ +#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */ +#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */ +#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */ +#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */ +#define WM8915_GP5_PU 0x4000 /* GP5_PU */ +#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */ +#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */ +#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */ +#define WM8915_GP5_PD 0x2000 /* GP5_PD */ +#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */ +#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */ +#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */ +#define WM8915_GP5_POL 0x0400 /* GP5_POL */ +#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */ +#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */ +#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */ +#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */ +#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */ +#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */ +#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */ +#define WM8915_GP5_DB 0x0100 /* GP5_DB */ +#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */ +#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */ +#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */ +#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */ +#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */ +#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */ +#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */ +#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */ +#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */ +#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */ + +/* + * R1824 (0x720) - Pull Control (1) + */ +#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */ +#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */ +#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */ +#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ +#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */ +#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */ +#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */ +#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ +#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */ +#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */ +#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */ +#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */ +#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */ +#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */ +#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */ +#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ +#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */ +#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */ +#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */ +#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */ +#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */ +#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */ +#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */ +#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ +#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */ +#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */ +#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */ +#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ +#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */ +#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */ +#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */ +#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ +#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */ +#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */ +#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */ +#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ +#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */ +#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */ +#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */ +#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ + +/* + * R1825 (0x721) - Pull Control (2) + */ +#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */ +#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */ +#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */ +#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ +#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */ +#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */ +#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */ +#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */ +#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */ +#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */ +#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */ +#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */ +#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */ +#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */ +#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */ +#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */ +#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */ +#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */ +#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */ +#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */ +#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */ +#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */ +#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */ +#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */ + +/* + * R1840 (0x730) - Interrupt Status 1 + */ +#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */ +#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */ +#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */ +#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */ +#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */ +#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */ +#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */ +#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */ +#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */ +#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */ +#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */ +#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */ +#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */ +#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */ +#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */ +#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */ +#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */ +#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */ +#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */ +#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */ + +/* + * R1841 (0x731) - Interrupt Status 2 + */ +#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */ +#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */ +#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */ +#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */ +#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */ +#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */ +#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */ +#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */ +#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */ +#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */ +#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */ +#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */ +#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */ +#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */ +#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */ +#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */ +#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */ +#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */ +#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */ +#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */ +#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */ +#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */ +#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */ + +/* + * R1842 (0x732) - Interrupt Raw Status 2 + */ +#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */ +#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */ +#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */ +#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */ +#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */ +#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */ +#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */ +#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */ +#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */ +#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */ +#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */ +#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */ +#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */ +#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */ +#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */ + +/* + * R1848 (0x738) - Interrupt Status 1 Mask + */ +#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */ +#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */ +#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */ +#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */ +#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ +#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ +#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ +#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ +#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ +#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ +#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ +#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ +#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ +#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ +#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ +#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ +#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ +#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ +#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ +#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ + +/* + * R1849 (0x739) - Interrupt Status 2 Mask + */ +#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */ +#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */ +#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */ +#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */ +#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */ +#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */ +#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */ +#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */ + +/* + * R1856 (0x740) - Interrupt Control + */ +#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */ +#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */ +#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */ +#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */ + +/* + * R2048 (0x800) - Left PDM Speaker + */ +#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */ +#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */ +#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */ +#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */ +#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */ +#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */ +#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */ + +/* + * R2049 (0x801) - Right PDM Speaker + */ +#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */ +#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */ +#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */ +#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */ +#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */ +#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */ +#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */ + +/* + * R2050 (0x802) - PDM Speaker Mute Sequence + */ +#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */ +#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */ +#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */ + +/* + * R2051 (0x803) - PDM Speaker Volume + */ +#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */ +#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */ +#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */ +#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */ +#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */ +#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */ + +#endif -- GitLab From 4bb3f43c6e3f3f6897f60ee1bab423ce23539d2c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 8 Apr 2011 16:49:42 +0900 Subject: [PATCH 0712/5560] ASoC: Add initial WM1250-EV1 Springbank audio I/O module driver The WM1250-EV1 Springbank audio I/O module for the Wolfson Glenfarclas reference platform provides a simple audio I/O with an independant clock domain, intended to simulate cellular modem and bluetooth subsystems within the platform. The card supports some limited GPIO based control but this is currently not implemented. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/Kconfig | 4 ++ sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm1250-ev1.c | 108 ++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 sound/soc/codecs/wm1250-ev1.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 54d5dd6c63af..2a6971891d31 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -53,6 +53,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WL1273 if MFD_WL1273_CORE + select SND_SOC_WM1250_EV1 if I2C select SND_SOC_WM2000 if I2C select SND_SOC_WM8350 if MFD_WM8350 select SND_SOC_WM8400 if MFD_WM8400 @@ -246,6 +247,9 @@ config SND_SOC_UDA1380 config SND_SOC_WL1273 tristate +config SND_SOC_WM1250_EV1 + tristate + config SND_SOC_WM8350 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 02425e6a87e3..4cb2f42dbffa 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -38,6 +38,7 @@ snd-soc-twl6040-objs := twl6040.o snd-soc-uda134x-objs := uda134x.o snd-soc-uda1380-objs := uda1380.o snd-soc-wl1273-objs := wl1273.o +snd-soc-wm1250-ev1-objs := wm1250-ev1.o snd-soc-wm8350-objs := wm8350.o snd-soc-wm8400-objs := wm8400.o snd-soc-wm8510-objs := wm8510.o @@ -128,6 +129,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o +obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c new file mode 100644 index 000000000000..9cf699e165ec --- /dev/null +++ b/sound/soc/codecs/wm1250-ev1.c @@ -0,0 +1,108 @@ +/* + * Driver for the 1250-EV1 audio I/O module + * + * Copyright 2011 Wolfson Microelectronics plc + * + * 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. + * + */ + +#include +#include +#include + +#include +#include + +static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = { +SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0), + +SND_SOC_DAPM_INPUT("WM1250 Input"), +SND_SOC_DAPM_INPUT("WM1250 Output"), +}; + +static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = { + { "ADC", NULL, "WM1250 Input" }, + { "WM1250 Output", NULL, "DAC" }, +}; + +static struct snd_soc_dai_driver wm1250_ev1_dai = { + .name = "wm1250-ev1", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}; + +static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { + .dapm_widgets = wm1250_ev1_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), + .dapm_routes = wm1250_ev1_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), +}; + +static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1, + &wm1250_ev1_dai, 1); +} + +static int __devexit wm1250_ev1_remove(struct i2c_client *i2c) +{ + snd_soc_unregister_codec(&i2c->dev); + + return 0; +} + +static const struct i2c_device_id wm1250_ev1_i2c_id[] = { + { "wm1250-ev1", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm1250_ev1__id); + +static struct i2c_driver wm1250_ev1_i2c_driver = { + .driver = { + .name = "wm1250-ev1", + .owner = THIS_MODULE, + }, + .probe = wm1250_ev1_probe, + .remove = __devexit_p(wm1250_ev1_remove), + .id_table = wm1250_ev1_i2c_id, +}; + +static int __init wm1250_ev1_modinit(void) +{ + int ret = 0; + + ret = i2c_add_driver(&wm1250_ev1_i2c_driver); + if (ret != 0) + pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret); + + return ret; +} +module_init(wm1250_ev1_modinit); + +static void __exit wm1250_ev1_exit(void) +{ + i2c_del_driver(&wm1250_ev1_i2c_driver); +} +module_exit(wm1250_ev1_exit); + +MODULE_AUTHOR("Mark Brown "); +MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver"); +MODULE_LICENSE("GPL"); -- GitLab From 73d6ac633c6c0ca703f90db0b808d9593e46aef6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 11 Apr 2011 10:43:50 +0000 Subject: [PATCH 0713/5560] caif: code cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup of new CAIF code. * make local functions static * remove code that is never used * expand get_caif_conf() since wrapper is no longer needed * make args to comparison functions const * rename connect_req_to_link_param to keep exported names consistent Compile tested only. Signed-off-by: Stephen Hemminger Acked-by: Sjur Brændeland Signed-off-by: David S. Miller --- include/net/caif/caif_dev.h | 27 +----- include/net/caif/cfctrl.h | 12 +-- include/net/caif/cfmuxl.h | 2 - include/net/caif/cfpkt.h | 75 --------------- include/net/caif/cfsrvl.h | 3 +- net/caif/caif_config_util.c | 6 +- net/caif/caif_dev.c | 24 ++--- net/caif/cfcnfg.c | 2 +- net/caif/cfctrl.c | 75 ++------------- net/caif/cfmuxl.c | 35 ------- net/caif/cfpkt_skbuff.c | 178 +----------------------------------- net/caif/cfsrvl.c | 7 +- 12 files changed, 30 insertions(+), 416 deletions(-) diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h index 8eff83b95366..7e3f7a6d2ba3 100644 --- a/include/net/caif/caif_dev.h +++ b/include/net/caif/caif_dev.h @@ -74,19 +74,8 @@ int caif_connect_client(struct caif_connect_request *conn_req, int caif_disconnect_client(struct cflayer *client_layer); /** - * caif_release_client - Release adaptation layer reference to client. - * - * @client_layer: Client layer. - * - * Releases a client/adaptation layer use of the caif stack. - * This function must be used after caif_disconnect_client to - * decrease the reference count of the service layer. - */ -void caif_release_client(struct cflayer *client_layer); - -/** - * connect_req_to_link_param - Translate configuration parameters - * from socket format to internal format. + * caif_connect_req_to_link_param - Translate configuration parameters + * from socket format to internal format. * @cnfg: Pointer to configuration handler * @con_req: Configuration parameters supplied in function * caif_connect_client @@ -94,14 +83,8 @@ void caif_release_client(struct cflayer *client_layer); * setting up channels. * */ -int connect_req_to_link_param(struct cfcnfg *cnfg, - struct caif_connect_request *con_req, - struct cfctrl_link_param *channel_setup_param); - -/** - * get_caif_conf() - Get the configuration handler. - */ -struct cfcnfg *get_caif_conf(void); - +int caif_connect_req_to_link_param(struct cfcnfg *cnfg, + struct caif_connect_request *con_req, + struct cfctrl_link_param *setup_param); #endif /* CAIF_DEV_H_ */ diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h index e54f6396fa4c..d84416fa175a 100644 --- a/include/net/caif/cfctrl.h +++ b/include/net/caif/cfctrl.h @@ -121,19 +121,9 @@ int cfctrl_linkup_request(struct cflayer *cfctrl, struct cflayer *user_layer); int cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid, struct cflayer *client); -void cfctrl_sleep_req(struct cflayer *cfctrl); -void cfctrl_wake_req(struct cflayer *cfctrl); -void cfctrl_getstartreason_req(struct cflayer *cfctrl); + struct cflayer *cfctrl_create(void); -void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn); -void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up); struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer); -bool cfctrl_req_eq(struct cfctrl_request_info *r1, - struct cfctrl_request_info *r2); -void cfctrl_insert_req(struct cfctrl *ctrl, - struct cfctrl_request_info *req); -struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, - struct cfctrl_request_info *req); void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer); #endif /* CFCTRL_H_ */ diff --git a/include/net/caif/cfmuxl.h b/include/net/caif/cfmuxl.h index 4e1b4f33423e..5847a196b8ad 100644 --- a/include/net/caif/cfmuxl.h +++ b/include/net/caif/cfmuxl.h @@ -16,7 +16,5 @@ int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid); struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid); int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *up, u8 phyid); struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 linkid); -bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid); -u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id); #endif /* CFMUXL_H_ */ diff --git a/include/net/caif/cfpkt.h b/include/net/caif/cfpkt.h index fbc681beff52..8b550f8950d7 100644 --- a/include/net/caif/cfpkt.h +++ b/include/net/caif/cfpkt.h @@ -16,12 +16,6 @@ struct cfpkt; */ struct cfpkt *cfpkt_create(u16 len); -/* Create a CAIF packet. - * data Data to copy. - * len Length of packet to be created - * @return New packet. - */ -struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len); /* * Destroy a CAIF Packet. * pkt Packet to be destoyed. @@ -181,22 +175,6 @@ u16 cfpkt_iterate(struct cfpkt *pkt, u16 (*iter_func)(u16 chks, void *buf, u16 len), u16 data); -/* Append by giving user access to packet buffer - * cfpkt Packet to append to - * buf Buffer inside pkt that user shall copy data into - * buflen Length of buffer and number of bytes added to packet - * @return 0 on error, 1 on success - */ -int cfpkt_raw_append(struct cfpkt *cfpkt, void **buf, unsigned int buflen); - -/* Extract by giving user access to packet buffer - * cfpkt Packet to extract from - * buf Buffer inside pkt that user shall copy data from - * buflen Length of buffer and number of bytes removed from packet - * @return 0 on error, 1 on success - */ -int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen); - /* Map from a "native" packet (e.g. Linux Socket Buffer) to a CAIF packet. * dir - Direction indicating whether this packet is to be sent or received. * nativepkt - The native packet to be transformed to a CAIF packet @@ -210,59 +188,6 @@ struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt); */ void *cfpkt_tonative(struct cfpkt *pkt); -/* - * Insert a packet in the packet queue. - * pktq Packet queue to insert into - * pkt Packet to be inserted in queue - * prio Priority of packet - */ -void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, - unsigned short prio); - -/* - * Remove a packet from the packet queue. - * pktq Packet queue to fetch packets from. - * @return Dequeued packet. - */ -struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq); - -/* - * Peek into a packet from the packet queue. - * pktq Packet queue to fetch packets from. - * @return Peeked packet. - */ -struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq); - -/* - * Initiates the packet queue. - * @return Pointer to new packet queue. - */ -struct cfpktq *cfpktq_create(void); - -/* - * Get the number of packets in the queue. - * pktq Packet queue to fetch count from. - * @return Number of packets in queue. - */ -int cfpkt_qcount(struct cfpktq *pktq); - -/* - * Put content of packet into buffer for debuging purposes. - * pkt Packet to copy data from - * buf Buffer to copy data into - * buflen Length of data to copy - * @return Pointer to copied data - */ -char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen); - -/* - * Clones a packet and releases the original packet. - * This is used for taking ownership of a packet e.g queueing. - * pkt Packet to clone and release. - * @return Cloned packet. - */ -struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt); - /* * Returns packet information for a packet. diff --git a/include/net/caif/cfsrvl.h b/include/net/caif/cfsrvl.h index b1fa87ee0992..6c8279c1ae9a 100644 --- a/include/net/caif/cfsrvl.h +++ b/include/net/caif/cfsrvl.h @@ -22,7 +22,6 @@ struct cfsrvl { struct kref ref; }; -void cfsrvl_release(struct kref *kref); struct cflayer *cfvei_create(u8 linkid, struct dev_info *dev_info); struct cflayer *cfdgml_create(u8 linkid, struct dev_info *dev_info); struct cflayer *cfutill_create(u8 linkid, struct dev_info *dev_info); @@ -31,7 +30,7 @@ struct cflayer *cfrfml_create(u8 linkid, struct dev_info *dev_info, int mtu_size); struct cflayer *cfdbgl_create(u8 linkid, struct dev_info *dev_info); bool cfsrvl_phyid_match(struct cflayer *layer, int phyid); -void cfservl_destroy(struct cflayer *layer); + void cfsrvl_init(struct cfsrvl *service, u8 channel_id, struct dev_info *dev_info, diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c index d522d8c1703e..9b63e4e3910e 100644 --- a/net/caif/caif_config_util.c +++ b/net/caif/caif_config_util.c @@ -10,9 +10,9 @@ #include #include -int connect_req_to_link_param(struct cfcnfg *cnfg, - struct caif_connect_request *s, - struct cfctrl_link_param *l) +int caif_connect_req_to_link_param(struct cfcnfg *cnfg, + struct caif_connect_request *s, + struct cfctrl_link_param *l) { struct dev_info *dev_info; enum cfcnfg_phy_preference pref; diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index a42a408306e4..b533bb09a002 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -257,7 +257,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, break; } dev_hold(dev); - cfcnfg_add_phy_layer(get_caif_conf(), + cfcnfg_add_phy_layer(cfg, phy_type, dev, &caifd->layer, @@ -300,7 +300,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, if (atomic_read(&caifd->in_use)) netdev_warn(dev, "Unregistering an active CAIF device\n"); - cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); + cfcnfg_del_phy_layer(cfg, &caifd->layer); dev_put(dev); atomic_set(&caifd->state, what); break; @@ -322,24 +322,18 @@ static struct notifier_block caif_device_notifier = { .priority = 0, }; - -struct cfcnfg *get_caif_conf(void) -{ - return cfg; -} -EXPORT_SYMBOL(get_caif_conf); - int caif_connect_client(struct caif_connect_request *conn_req, struct cflayer *client_layer, int *ifindex, int *headroom, int *tailroom) { struct cfctrl_link_param param; int ret; - ret = connect_req_to_link_param(get_caif_conf(), conn_req, ¶m); + + ret = caif_connect_req_to_link_param(cfg, conn_req, ¶m); if (ret) return ret; /* Hook up the adaptation layer. */ - return cfcnfg_add_adaptation_layer(get_caif_conf(), ¶m, + return cfcnfg_add_adaptation_layer(cfg, ¶m, client_layer, ifindex, headroom, tailroom); } @@ -347,16 +341,10 @@ EXPORT_SYMBOL(caif_connect_client); int caif_disconnect_client(struct cflayer *adap_layer) { - return cfcnfg_disconn_adapt_layer(get_caif_conf(), adap_layer); + return cfcnfg_disconn_adapt_layer(cfg, adap_layer); } EXPORT_SYMBOL(caif_disconnect_client); -void caif_release_client(struct cflayer *adap_layer) -{ - cfcnfg_release_adap_layer(adap_layer); -} -EXPORT_SYMBOL(caif_release_client); - /* Per-namespace Caif devices handling */ static int caif_init_net(struct net *net) { diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index f1f98d967d8a..25c0b198e285 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -253,7 +253,7 @@ static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) { } -int protohead[CFCTRL_SRV_MASK] = { +static const int protohead[CFCTRL_SRV_MASK] = { [CFCTRL_SRV_VEI] = 4, [CFCTRL_SRV_DATAGRAM] = 7, [CFCTRL_SRV_UTIL] = 4, diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 3cd8f978e309..397a2c099e2c 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -58,7 +58,8 @@ struct cflayer *cfctrl_create(void) return &this->serv.layer; } -static bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2) +static bool param_eq(const struct cfctrl_link_param *p1, + const struct cfctrl_link_param *p2) { bool eq = p1->linktype == p2->linktype && @@ -100,8 +101,8 @@ static bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2) return false; } -bool cfctrl_req_eq(struct cfctrl_request_info *r1, - struct cfctrl_request_info *r2) +static bool cfctrl_req_eq(const struct cfctrl_request_info *r1, + const struct cfctrl_request_info *r2) { if (r1->cmd != r2->cmd) return false; @@ -112,7 +113,7 @@ bool cfctrl_req_eq(struct cfctrl_request_info *r1, } /* Insert request at the end */ -void cfctrl_insert_req(struct cfctrl *ctrl, +static void cfctrl_insert_req(struct cfctrl *ctrl, struct cfctrl_request_info *req) { spin_lock(&ctrl->info_list_lock); @@ -123,8 +124,8 @@ void cfctrl_insert_req(struct cfctrl *ctrl, } /* Compare and remove request */ -struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, - struct cfctrl_request_info *req) +static struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, + struct cfctrl_request_info *req) { struct cfctrl_request_info *p, *tmp, *first; @@ -154,16 +155,6 @@ struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer) return &this->res; } -void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn) -{ - this->dn = dn; -} - -void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up) -{ - this->up = up; -} - static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl) { info->hdr_len = 0; @@ -304,58 +295,6 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, return ret; } -void cfctrl_sleep_req(struct cflayer *layer) -{ - int ret; - struct cfctrl *cfctrl = container_obj(layer); - struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); - if (!pkt) { - pr_warn("Out of memory\n"); - return; - } - cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP); - init_info(cfpkt_info(pkt), cfctrl); - ret = - cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); - if (ret < 0) - cfpkt_destroy(pkt); -} - -void cfctrl_wake_req(struct cflayer *layer) -{ - int ret; - struct cfctrl *cfctrl = container_obj(layer); - struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); - if (!pkt) { - pr_warn("Out of memory\n"); - return; - } - cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE); - init_info(cfpkt_info(pkt), cfctrl); - ret = - cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); - if (ret < 0) - cfpkt_destroy(pkt); -} - -void cfctrl_getstartreason_req(struct cflayer *layer) -{ - int ret; - struct cfctrl *cfctrl = container_obj(layer); - struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); - if (!pkt) { - pr_warn("Out of memory\n"); - return; - } - cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON); - init_info(cfpkt_info(pkt), cfctrl); - ret = - cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); - if (ret < 0) - cfpkt_destroy(pkt); -} - - void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) { struct cfctrl_request_info *p, *tmp; diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 24f1ffa74b06..f8ce0f3d9210 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -71,41 +71,6 @@ int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid) return 0; } -bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid) -{ - struct list_head *node; - struct cflayer *layer; - struct cfmuxl *muxl = container_obj(layr); - bool match = false; - spin_lock(&muxl->receive_lock); - - list_for_each(node, &muxl->srvl_list) { - layer = list_entry(node, struct cflayer, node); - if (cfsrvl_phyid_match(layer, phyid)) { - match = true; - break; - } - - } - spin_unlock(&muxl->receive_lock); - return match; -} - -u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id) -{ - struct cflayer *up; - int phyid; - struct cfmuxl *muxl = container_obj(layr); - spin_lock(&muxl->receive_lock); - up = get_up(muxl, channel_id); - if (up != NULL) - phyid = cfsrvl_getphyid(up); - else - phyid = 0; - spin_unlock(&muxl->receive_lock); - return phyid; -} - int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid) { struct cfmuxl *muxl = (struct cfmuxl *) layr; diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c index d7e865e2ff65..20c6cb3522e0 100644 --- a/net/caif/cfpkt_skbuff.c +++ b/net/caif/cfpkt_skbuff.c @@ -42,22 +42,22 @@ struct cfpkt_priv_data { bool erronous; }; -inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt) +static inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt) { return (struct cfpkt_priv_data *) pkt->skb.cb; } -inline bool is_erronous(struct cfpkt *pkt) +static inline bool is_erronous(struct cfpkt *pkt) { return cfpkt_priv(pkt)->erronous; } -inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt) +static inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt) { return &pkt->skb; } -inline struct cfpkt *skb_to_pkt(struct sk_buff *skb) +static inline struct cfpkt *skb_to_pkt(struct sk_buff *skb) { return (struct cfpkt *) skb; } @@ -317,17 +317,6 @@ int cfpkt_setlen(struct cfpkt *pkt, u16 len) } EXPORT_SYMBOL(cfpkt_setlen); -struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len) -{ - struct cfpkt *pkt = cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX); - if (!pkt) - return NULL; - if (unlikely(data != NULL)) - cfpkt_add_body(pkt, data, len); - return pkt; -} -EXPORT_SYMBOL(cfpkt_create_uplink); - struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, u16 expectlen) @@ -408,169 +397,12 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) } EXPORT_SYMBOL(cfpkt_split); -char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen) -{ - struct sk_buff *skb = pkt_to_skb(pkt); - char *p = buf; - int i; - - /* - * Sanity check buffer length, it needs to be at least as large as - * the header info: ~=50+ bytes - */ - if (buflen < 50) - return NULL; - - snprintf(buf, buflen, "%s: pkt:%p len:%ld(%ld+%ld) {%ld,%ld} data: [", - is_erronous(pkt) ? "ERRONOUS-SKB" : - (skb->data_len != 0 ? "COMPLEX-SKB" : "SKB"), - skb, - (long) skb->len, - (long) (skb_tail_pointer(skb) - skb->data), - (long) skb->data_len, - (long) (skb->data - skb->head), - (long) (skb_tail_pointer(skb) - skb->head)); - p = buf + strlen(buf); - - for (i = 0; i < skb_tail_pointer(skb) - skb->data && i < 300; i++) { - if (p > buf + buflen - 10) { - sprintf(p, "..."); - p = buf + strlen(buf); - break; - } - sprintf(p, "%02x,", skb->data[i]); - p = buf + strlen(buf); - } - sprintf(p, "]\n"); - return buf; -} -EXPORT_SYMBOL(cfpkt_log_pkt); - -int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen) -{ - struct sk_buff *skb = pkt_to_skb(pkt); - struct sk_buff *lastskb; - - caif_assert(buf != NULL); - if (unlikely(is_erronous(pkt))) - return -EPROTO; - /* Make sure SKB is writable */ - if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { - PKT_ERROR(pkt, "skb_cow_data failed\n"); - return -EPROTO; - } - - if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "linearize failed\n"); - return -EPROTO; - } - - if (unlikely(skb_tailroom(skb) < buflen)) { - PKT_ERROR(pkt, "buffer too short - failed\n"); - return -EPROTO; - } - - *buf = skb_put(skb, buflen); - return 1; -} -EXPORT_SYMBOL(cfpkt_raw_append); - -int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen) -{ - struct sk_buff *skb = pkt_to_skb(pkt); - - caif_assert(buf != NULL); - if (unlikely(is_erronous(pkt))) - return -EPROTO; - - if (unlikely(buflen > skb->len)) { - PKT_ERROR(pkt, "buflen too large - failed\n"); - return -EPROTO; - } - - if (unlikely(buflen > skb_headlen(skb))) { - if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "linearize failed\n"); - return -EPROTO; - } - } - - *buf = skb->data; - skb_pull(skb, buflen); - - return 1; -} -EXPORT_SYMBOL(cfpkt_raw_extract); - -inline bool cfpkt_erroneous(struct cfpkt *pkt) +bool cfpkt_erroneous(struct cfpkt *pkt) { return cfpkt_priv(pkt)->erronous; } EXPORT_SYMBOL(cfpkt_erroneous); -struct cfpktq *cfpktq_create(void) -{ - struct cfpktq *q = kmalloc(sizeof(struct cfpktq), GFP_ATOMIC); - if (!q) - return NULL; - skb_queue_head_init(&q->head); - atomic_set(&q->count, 0); - spin_lock_init(&q->lock); - return q; -} -EXPORT_SYMBOL(cfpktq_create); - -void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio) -{ - atomic_inc(&pktq->count); - spin_lock(&pktq->lock); - skb_queue_tail(&pktq->head, pkt_to_skb(pkt)); - spin_unlock(&pktq->lock); - -} -EXPORT_SYMBOL(cfpkt_queue); - -struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq) -{ - struct cfpkt *tmp; - spin_lock(&pktq->lock); - tmp = skb_to_pkt(skb_peek(&pktq->head)); - spin_unlock(&pktq->lock); - return tmp; -} -EXPORT_SYMBOL(cfpkt_qpeek); - -struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq) -{ - struct cfpkt *pkt; - spin_lock(&pktq->lock); - pkt = skb_to_pkt(skb_dequeue(&pktq->head)); - if (pkt) { - atomic_dec(&pktq->count); - caif_assert(atomic_read(&pktq->count) >= 0); - } - spin_unlock(&pktq->lock); - return pkt; -} -EXPORT_SYMBOL(cfpkt_dequeue); - -int cfpkt_qcount(struct cfpktq *pktq) -{ - return atomic_read(&pktq->count); -} -EXPORT_SYMBOL(cfpkt_qcount); - -struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt) -{ - struct cfpkt *clone; - clone = skb_to_pkt(skb_clone(pkt_to_skb(pkt), GFP_ATOMIC)); - /* Free original packet. */ - cfpkt_destroy(pkt); - if (!clone) - return NULL; - return clone; -} -EXPORT_SYMBOL(cfpkt_clone_release); struct caif_payload_info *cfpkt_info(struct cfpkt *pkt) { diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index ab5e542526bf..24ba392f203b 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c @@ -151,12 +151,7 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) return -EINVAL; } -void cfservl_destroy(struct cflayer *layer) -{ - kfree(layer); -} - -void cfsrvl_release(struct kref *kref) +static void cfsrvl_release(struct kref *kref) { struct cfsrvl *service = container_of(kref, struct cfsrvl, ref); kfree(service); -- GitLab From 4dd820c088d201e526840c9dbc2f0b87a0a41868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 11 Apr 2011 10:43:51 +0000 Subject: [PATCH 0714/5560] caif: Don't resend if dev_queue_xmit fails. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CAIF Link Layer returns an error, we no longer try to re-build the CAIF packet and resend it. Instead, we simply return any transmission errors to the socket client. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 21 ++++----------------- net/caif/caif_socket.c | 35 +++-------------------------------- net/caif/cfdgml.c | 7 +------ net/caif/cffrml.c | 8 +------- net/caif/cfmuxl.c | 7 +------ net/caif/cfserl.c | 7 +------ net/caif/cfutill.c | 7 +------ net/caif/cfveil.c | 5 +---- net/caif/cfvidl.c | 5 +---- 9 files changed, 14 insertions(+), 88 deletions(-) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index b533bb09a002..a518fdd4da0a 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -120,25 +120,12 @@ static int transmit(struct cflayer *layer, struct cfpkt *pkt) { struct caif_device_entry *caifd = container_of(layer, struct caif_device_entry, layer); - struct sk_buff *skb, *skb2; - int ret = -EINVAL; + struct sk_buff *skb; + skb = cfpkt_tonative(pkt); skb->dev = caifd->netdev; - /* - * Don't allow SKB to be destroyed upon error, but signal resend - * notification to clients. We can't rely on the return value as - * congestion (NET_XMIT_CN) sometimes drops the packet, sometimes don't. - */ - if (netif_queue_stopped(caifd->netdev)) - return -EAGAIN; - skb2 = skb_get(skb); - - ret = dev_queue_xmit(skb2); - - if (!ret) - kfree_skb(skb); - else - return -EAGAIN; + + dev_queue_xmit(skb); return 0; } diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 37a4034dfc29..20212424e2e8 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -519,43 +519,14 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk, int noblock, long timeo) { struct cfpkt *pkt; - int ret, loopcnt = 0; pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb); memset(cfpkt_info(pkt), 0, sizeof(struct caif_payload_info)); - do { - - ret = -ETIMEDOUT; - /* Slight paranoia, probably not needed. */ - if (unlikely(loopcnt++ > 1000)) { - pr_warn("transmit retries failed, error = %d\n", ret); - break; - } + if (cf_sk->layer.dn == NULL) + return -EINVAL; - if (cf_sk->layer.dn != NULL) - ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt); - if (likely(ret >= 0)) - break; - /* if transmit return -EAGAIN, then retry */ - if (noblock && ret == -EAGAIN) - break; - timeo = caif_wait_for_flow_on(cf_sk, 0, timeo, &ret); - if (signal_pending(current)) { - ret = sock_intr_errno(timeo); - break; - } - if (ret) - break; - if (cf_sk->sk.sk_state != CAIF_CONNECTED || - sock_flag(&cf_sk->sk, SOCK_DEAD) || - (cf_sk->sk.sk_shutdown & RCV_SHUTDOWN)) { - ret = -EPIPE; - cf_sk->sk.sk_err = EPIPE; - break; - } - } while (ret == -EAGAIN); - return ret; + return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt); } /* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */ diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index 054fdb5aeb88..0382dec84fdc 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c @@ -108,10 +108,5 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) */ info->hdr_len = 4; info->dev_info = &service->dev_info; - ret = layr->dn->transmit(layr->dn, pkt); - if (ret < 0) { - u32 tmp32; - cfpkt_extr_head(pkt, &tmp32, 4); - } - return ret; + return layr->dn->transmit(layr->dn, pkt); } diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index a445043931ae..2423fed8e26c 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c @@ -120,7 +120,6 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) int tmp; u16 chks; u16 len; - int ret; struct cffrml *this = container_obj(layr); if (this->dofcs) { chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff); @@ -137,12 +136,7 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) pr_err("Packet is erroneous!\n"); return -EPROTO; } - ret = layr->dn->transmit(layr->dn, pkt); - if (ret < 0) { - /* Remove header on faulty packet. */ - cfpkt_extr_head(pkt, &tmp, 2); - } - return ret; + return layr->dn->transmit(layr->dn, pkt); } static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index f8ce0f3d9210..ebfda2c9290b 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -184,7 +184,6 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) { - int ret; struct cfmuxl *muxl = container_obj(layr); u8 linkid; struct cflayer *dn; @@ -198,11 +197,7 @@ static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) info->hdr_len += 1; linkid = info->channel_id; cfpkt_add_head(pkt, &linkid, 1); - ret = dn->transmit(dn, pkt); - /* Remove MUX protocol header upon error. */ - if (ret < 0) - cfpkt_extr_head(pkt, &linkid, 1); - return ret; + return dn->transmit(dn, pkt); } static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index 8303fe3ebf89..2715c84cfa87 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -179,15 +179,10 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt) { struct cfserl *layr = container_obj(layer); - int ret; u8 tmp8 = CFSERL_STX; if (layr->usestx) cfpkt_add_head(newpkt, &tmp8, 1); - ret = layer->dn->transmit(layer->dn, newpkt); - if (ret < 0) - cfpkt_extr_head(newpkt, &tmp8, 1); - - return ret; + return layer->dn->transmit(layer->dn, newpkt); } static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c index 315c0d601368..98e027db18ed 100644 --- a/net/caif/cfutill.c +++ b/net/caif/cfutill.c @@ -100,10 +100,5 @@ static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt) */ info->hdr_len = 1; info->dev_info = &service->dev_info; - ret = layr->dn->transmit(layr->dn, pkt); - if (ret < 0) { - u32 tmp32; - cfpkt_extr_head(pkt, &tmp32, 4); - } - return ret; + return layr->dn->transmit(layr->dn, pkt); } diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index c3b1dec4acf6..1a588cd818ea 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -96,8 +96,5 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) info->channel_id = service->layer.id; info->hdr_len = 1; info->dev_info = &service->dev_info; - ret = layr->dn->transmit(layr->dn, pkt); - if (ret < 0) - cfpkt_extr_head(pkt, &tmp, 1); - return ret; + return layr->dn->transmit(layr->dn, pkt); } diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c index bf6fef2a0eff..b2f5989ad455 100644 --- a/net/caif/cfvidl.c +++ b/net/caif/cfvidl.c @@ -60,8 +60,5 @@ static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt) info = cfpkt_info(pkt); info->channel_id = service->layer.id; info->dev_info = &service->dev_info; - ret = layr->dn->transmit(layr->dn, pkt); - if (ret < 0) - cfpkt_extr_head(pkt, &videoheader, 4); - return ret; + return layr->dn->transmit(layr->dn, pkt); } -- GitLab From 39b9afbb4c0750742eb61b7a015e12f483e0b4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sjur=20Br=C3=A6ndeland?= Date: Mon, 11 Apr 2011 10:43:52 +0000 Subject: [PATCH 0715/5560] caif: Add BUG_ON if dev_info is missing in packet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- net/caif/cfmuxl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index ebfda2c9290b..fc2497468571 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -188,7 +188,8 @@ static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) u8 linkid; struct cflayer *dn; struct caif_payload_info *info = cfpkt_info(pkt); - dn = get_dn(muxl, cfpkt_info(pkt)->dev_info); + BUG_ON(!info); + dn = get_dn(muxl, info->dev_info); if (dn == NULL) { pr_warn("Send data on unknown phy ID = %d (0x%x)\n", info->dev_info->id, info->dev_info->id); -- GitLab From f344c25dbab1a392ef7a7afc8ca061b3b7285423 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 11 Apr 2011 15:49:26 -0700 Subject: [PATCH 0716/5560] niu: Fix warnings due to -Wunused-but-set-variable Most of these were legitimate, and once case was a real bug (not propagating errors from ->xcvr_init() methods). Signed-off-by: David S. Miller --- drivers/net/niu.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9e6330bc0531..3fa1e9cdb4a8 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -1233,7 +1233,7 @@ static int link_status_1g_rgmii(struct niu *np, int *link_up_p) bmsr = err; if (bmsr & BMSR_LSTATUS) { - u16 adv, lpa, common, estat; + u16 adv, lpa; err = mii_read(np, np->phy_addr, MII_ADVERTISE); if (err < 0) @@ -1245,12 +1245,9 @@ static int link_status_1g_rgmii(struct niu *np, int *link_up_p) goto out; lpa = err; - common = adv & lpa; - err = mii_read(np, np->phy_addr, MII_ESTATUS); if (err < 0) goto out; - estat = err; link_up = 1; current_speed = SPEED_1000; current_duplex = DUPLEX_FULL; @@ -1650,7 +1647,7 @@ static int xcvr_init_10g(struct niu *np) break; } - return 0; + return err; } static int mii_reset(struct niu *np) @@ -2381,17 +2378,14 @@ static int serdes_init_10g_serdes(struct niu *np) struct niu_link_config *lp = &np->link_config; unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i; u64 ctrl_val, test_cfg_val, sig, mask, val; - u64 reset_val; switch (np->port) { case 0: - reset_val = ENET_SERDES_RESET_0; ctrl_reg = ENET_SERDES_0_CTRL_CFG; test_cfg_reg = ENET_SERDES_0_TEST_CFG; pll_cfg = ENET_SERDES_0_PLL_CFG; break; case 1: - reset_val = ENET_SERDES_RESET_1; ctrl_reg = ENET_SERDES_1_CTRL_CFG; test_cfg_reg = ENET_SERDES_1_TEST_CFG; pll_cfg = ENET_SERDES_1_PLL_CFG; @@ -8135,7 +8129,7 @@ static int __devinit niu_pci_vpd_scan_props(struct niu *np, netif_printk(np, probe, KERN_DEBUG, np->dev, "VPD_SCAN: start[%x] end[%x]\n", start, end); while (start < end) { - int len, err, instance, type, prop_len; + int len, err, prop_len; char namebuf[64]; u8 *prop_buf; int max_len; @@ -8151,8 +8145,6 @@ static int __devinit niu_pci_vpd_scan_props(struct niu *np, len = err; start += 3; - instance = niu_pci_eeprom_read(np, start); - type = niu_pci_eeprom_read(np, start + 3); prop_len = niu_pci_eeprom_read(np, start + 4); err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64); if (err < 0) -- GitLab From 420dd718ad0bc4a4e07ae0ac7f8eac7545eb253a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Apr 2011 21:40:29 -0700 Subject: [PATCH 0717/5560] ASoC: Fix mis cherry-pick of wm1250-ev1 driver Signed-off-by: Mark Brown --- sound/soc/codecs/wm1250-ev1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index 9cf699e165ec..14d0716bf009 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c @@ -73,7 +73,7 @@ static const struct i2c_device_id wm1250_ev1_i2c_id[] = { { "wm1250-ev1", 0 }, { } }; -MODULE_DEVICE_TABLE(i2c, wm1250_ev1__id); +MODULE_DEVICE_TABLE(i2c, wm1250_ev1_i2c_id); static struct i2c_driver wm1250_ev1_i2c_driver = { .driver = { -- GitLab From 92a47674f57b4a84a43ce93b0dfdb596c0543749 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Mon, 11 Apr 2011 23:34:37 -0700 Subject: [PATCH 0718/5560] Input: gpio_keys - add support for EV_ABS With this patch you can setup a group of GPIOs representing a specific position on an EV_ABS axis. Signed-off-by: Alexander Stein Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 9 +++++++-- include/linux/gpio_keys.h | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index eb3006361ee4..73e58a96ab99 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -324,7 +324,12 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata) unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; - input_event(input, type, button->code, !!state); + if (type == EV_ABS) { + if (state) + input_event(input, type, button->code, button->value); + } else { + input_event(input, type, button->code, !!state); + } input_sync(input); } @@ -363,7 +368,7 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, struct gpio_button_data *bdata, struct gpio_keys_button *button) { - char *desc = button->desc ? button->desc : "gpio_keys"; + const char *desc = button->desc ? button->desc : "gpio_keys"; struct device *dev = &pdev->dev; unsigned long irqflags; int irq, error; diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index dd1a56fbe924..3204edfe6b19 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -3,14 +3,15 @@ struct gpio_keys_button { /* Configuration parameters */ - int code; /* input event code (KEY_*, SW_*) */ + unsigned int code; /* input event code (KEY_*, SW_*) */ int gpio; int active_low; - char *desc; - int type; /* input event type (EV_KEY, EV_SW) */ + const char *desc; + unsigned int type; /* input event type (EV_KEY, EV_SW, EV_ABS) */ int wakeup; /* configure the button as a wake-up source */ int debounce_interval; /* debounce ticks interval in msecs */ bool can_disable; + int value; /* axis value for EV_ABS */ }; struct gpio_keys_platform_data { -- GitLab From 467112777c462a592c27338eeea5d1a320e82b5f Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Mon, 11 Apr 2011 23:34:48 -0700 Subject: [PATCH 0719/5560] Input: gpio-keys - add support for setting device name This patch allows to set a device name which helps distinguishing several gpio-keys devices. Signed-off-by: Alexander Stein Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 2 +- include/linux/gpio_keys.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 73e58a96ab99..6e6145b9a4c1 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -473,7 +473,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ddata); input_set_drvdata(input, ddata); - input->name = pdev->name; + input->name = pdata->name ? : pdev->name; input->phys = "gpio-keys/input0"; input->dev.parent = &pdev->dev; input->open = gpio_keys_open; diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 3204edfe6b19..b5ca4b2c08ec 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -22,6 +22,7 @@ struct gpio_keys_platform_data { unsigned int rep:1; /* enable input subsystem auto repeat */ int (*enable)(struct device *dev); void (*disable)(struct device *dev); + const char *name; /* input device name */ }; #endif -- GitLab From 4203306506ebe4eaaa84a2cbd7c1eb2fc0128faa Mon Sep 17 00:00:00 2001 From: Zhang Jiejing Date: Mon, 11 Apr 2011 23:48:23 -0700 Subject: [PATCH 0720/5560] Input: add driver for Maxim max11801 touchscreen controller Add MAXI max11801 resistive touchscreen controller driver. This driver uses Auto Mode and Aperture Mode. Support for other max1180x devices can be added to this driver as well, as they use almost the same register addresses and codes. You can find data sheet here: http://www.maxim-ic.com/datasheet/index.mvp/id/5943 Signed-off-by: Zhang Jiejing Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 12 ++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/max11801_ts.c | 272 ++++++++++++++++++++++++ 3 files changed, 285 insertions(+) create mode 100644 drivers/input/touchscreen/max11801_ts.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 112ec55f2939..6b2d441a7dde 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -248,6 +248,18 @@ config TOUCHSCREEN_LPC32XX To compile this driver as a module, choose M here: the module will be called lpc32xx_ts. +config TOUCHSCREEN_MAX11801 + tristate "MAX11801 based touchscreens" + depends on I2C + help + Say Y here if you have a MAX11801 based touchscreen + controller. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called max11801_ts. + config TOUCHSCREEN_MCS5000 tristate "MELFAS MCS-5000 touchscreen" depends on I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index ca94098d4c92..282d6f76ae26 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o +obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c new file mode 100644 index 000000000000..4f2713d92791 --- /dev/null +++ b/drivers/input/touchscreen/max11801_ts.c @@ -0,0 +1,272 @@ +/* + * Driver for MAXI MAX11801 - A Resistive touch screen controller with + * i2c interface + * + * Copyright (C) 2011 Freescale Semiconductor, Inc. + * Author: Zhang Jiejing + * + * Based on mcs5000_ts.c + * + * 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. + */ + +/* + * This driver aims to support the series of MAXI touch chips max11801 + * through max11803. The main difference between these 4 chips can be + * found in the table below: + * ----------------------------------------------------- + * | CHIP | AUTO MODE SUPPORT(FIFO) | INTERFACE | + * |----------------------------------------------------| + * | max11800 | YES | SPI | + * | max11801 | YES | I2C | + * | max11802 | NO | SPI | + * | max11803 | NO | I2C | + * ------------------------------------------------------ + * + * Currently, this driver only supports max11801. + * + * Data Sheet: + * http://www.maxim-ic.com/datasheet/index.mvp/id/5943 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Register Address define */ +#define GENERNAL_STATUS_REG 0x00 +#define GENERNAL_CONF_REG 0x01 +#define MESURE_RES_CONF_REG 0x02 +#define MESURE_AVER_CONF_REG 0x03 +#define ADC_SAMPLE_TIME_CONF_REG 0x04 +#define PANEL_SETUPTIME_CONF_REG 0x05 +#define DELAY_CONVERSION_CONF_REG 0x06 +#define TOUCH_DETECT_PULLUP_CONF_REG 0x07 +#define AUTO_MODE_TIME_CONF_REG 0x08 /* only for max11800/max11801 */ +#define APERTURE_CONF_REG 0x09 /* only for max11800/max11801 */ +#define AUX_MESURE_CONF_REG 0x0a +#define OP_MODE_CONF_REG 0x0b + +/* FIFO is found only in max11800 and max11801 */ +#define FIFO_RD_CMD (0x50 << 1) +#define MAX11801_FIFO_INT (1 << 2) +#define MAX11801_FIFO_OVERFLOW (1 << 3) + +#define XY_BUFSIZE 4 +#define XY_BUF_OFFSET 4 + +#define MAX11801_MAX_X 0xfff +#define MAX11801_MAX_Y 0xfff + +#define MEASURE_TAG_OFFSET 2 +#define MEASURE_TAG_MASK (3 << MEASURE_TAG_OFFSET) +#define EVENT_TAG_OFFSET 0 +#define EVENT_TAG_MASK (3 << EVENT_TAG_OFFSET) +#define MEASURE_X_TAG (0 << MEASURE_TAG_OFFSET) +#define MEASURE_Y_TAG (1 << MEASURE_TAG_OFFSET) + +/* These are the state of touch event state machine */ +enum { + EVENT_INIT, + EVENT_MIDDLE, + EVENT_RELEASE, + EVENT_FIFO_END +}; + +struct max11801_data { + struct i2c_client *client; + struct input_dev *input_dev; +}; + +static u8 read_register(struct i2c_client *client, int addr) +{ + /* XXX: The chip ignores LSB of register address */ + return i2c_smbus_read_byte_data(client, addr << 1); +} + +static int max11801_write_reg(struct i2c_client *client, int addr, int data) +{ + /* XXX: The chip ignores LSB of register address */ + return i2c_smbus_write_byte_data(client, addr << 1, data); +} + +static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id) +{ + struct max11801_data *data = dev_id; + struct i2c_client *client = data->client; + int status, i, ret; + u8 buf[XY_BUFSIZE]; + int x = -1; + int y = -1; + + status = read_register(data->client, GENERNAL_STATUS_REG); + + if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) { + status = read_register(data->client, GENERNAL_STATUS_REG); + + ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD, + XY_BUFSIZE, buf); + + /* + * We should get 4 bytes buffer that contains X,Y + * and event tag + */ + if (ret < XY_BUFSIZE) + goto out; + + for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) { + if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) + x = (buf[i] << XY_BUF_OFFSET) + + (buf[i + 1] >> XY_BUF_OFFSET); + else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) + y = (buf[i] << XY_BUF_OFFSET) + + (buf[i + 1] >> XY_BUF_OFFSET); + } + + if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK)) + goto out; + + switch (buf[1] & EVENT_TAG_MASK) { + case EVENT_INIT: + /* fall through */ + case EVENT_MIDDLE: + input_report_abs(data->input_dev, ABS_X, x); + input_report_abs(data->input_dev, ABS_Y, y); + input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); + input_sync(data->input_dev); + break; + + case EVENT_RELEASE: + input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); + input_sync(data->input_dev); + break; + + case EVENT_FIFO_END: + break; + } + } +out: + return IRQ_HANDLED; +} + +static void __devinit max11801_ts_phy_init(struct max11801_data *data) +{ + struct i2c_client *client = data->client; + + /* Average X,Y, take 16 samples, average eight media sample */ + max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); + /* X,Y panel setup time set to 20us */ + max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); + /* Rough pullup time (2uS), Fine pullup time (10us) */ + max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); + /* Auto mode init period = 5ms , scan period = 5ms*/ + max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); + /* Aperture X,Y set to +- 4LSB */ + max11801_write_reg(client, APERTURE_CONF_REG, 0x33); + /* Enable Power, enable Automode, enable Aperture, enable Average X,Y */ + max11801_write_reg(client, OP_MODE_CONF_REG, 0x36); +} + +static int __devinit max11801_ts_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max11801_data *data; + struct input_dev *input_dev; + int error; + + data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!data || !input_dev) { + dev_err(&client->dev, "Failed to allocate memory\n"); + error = -ENOMEM; + goto err_free_mem; + } + + data->client = client; + data->input_dev = input_dev; + + input_dev->name = "max11801_ts"; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = &client->dev; + + __set_bit(EV_ABS, input_dev->evbit); + __set_bit(EV_KEY, input_dev->evbit); + __set_bit(BTN_TOUCH, input_dev->keybit); + input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0); + input_set_drvdata(input_dev, data); + + max11801_ts_phy_init(data); + + error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "max11801_ts", data); + if (error) { + dev_err(&client->dev, "Failed to register interrupt\n"); + goto err_free_mem; + } + + error = input_register_device(data->input_dev); + if (error) + goto err_free_irq; + + i2c_set_clientdata(client, data); + return 0; + +err_free_irq: + free_irq(client->irq, data); +err_free_mem: + input_free_device(input_dev); + kfree(data); + return error; +} + +static __devexit int max11801_ts_remove(struct i2c_client *client) +{ + struct max11801_data *data = i2c_get_clientdata(client); + + free_irq(client->irq, data); + input_unregister_device(data->input_dev); + kfree(data); + + return 0; +} + +static const struct i2c_device_id max11801_ts_id[] = { + {"max11801", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, max11801_ts_id); + +static struct i2c_driver max11801_ts_driver = { + .driver = { + .name = "max11801_ts", + .owner = THIS_MODULE, + }, + .id_table = max11801_ts_id, + .probe = max11801_ts_probe, + .remove = __devexit_p(max11801_ts_remove), +}; + +static int __init max11801_ts_init(void) +{ + return i2c_add_driver(&max11801_ts_driver); +} + +static void __exit max11801_ts_exit(void) +{ + i2c_del_driver(&max11801_ts_driver); +} + +module_init(max11801_ts_init); +module_exit(max11801_ts_exit); + +MODULE_AUTHOR("Zhang Jiejing "); +MODULE_DESCRIPTION("Touchscreen driver for MAXI MAX11801 controller"); +MODULE_LICENSE("GPL"); -- GitLab From f98e5b80add20ec20b9a3e450c3378eb9a163848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 12 Apr 2011 09:59:29 +0200 Subject: [PATCH 0721/5560] tty: fix typo in descripton of tty_termios_encode_baud_rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Acked-by: Alan Cox Signed-off-by: Jiri Kosina --- drivers/tty/tty_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 1a1135d580a2..d73c593795a1 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -309,7 +309,7 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); * @ospeed: output speed * * Encode the speeds set into the passed termios structure. This is - * used as a library helper for drivers os that they can report back + * used as a library helper for drivers so that they can report back * the actual speed selected when it differs from the speed requested * * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour -- GitLab From 384f5c96ea05aba24a11172ebd6f5d427ca199fc Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 12 Apr 2011 21:08:37 +0900 Subject: [PATCH 0722/5560] fat: use new setup() for ->dir_ops too Signed-off-by: OGAWA Hirofumi --- fs/fat/fat.h | 3 +-- fs/fat/inode.c | 4 +--- fs/fat/namei_msdos.c | 4 ++-- fs/fat/namei_vfat.c | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index f50408901f7e..dc163b8d7699 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -319,8 +319,7 @@ extern struct inode *fat_build_inode(struct super_block *sb, struct msdos_dir_entry *de, loff_t i_pos); extern int fat_sync_inode(struct inode *inode); extern int fat_fill_super(struct super_block *sb, void *data, int silent, - const struct inode_operations *fs_dir_inode_ops, - int isvfat, void (*setup)(struct super_block *)); + int isvfat, void (*setup)(struct super_block *)); extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 8d68690bdcf1..c27704dc485e 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1238,8 +1238,7 @@ static int fat_read_root(struct inode *inode) /* * Read the super block of an MS-DOS FS. */ -int fat_fill_super(struct super_block *sb, void *data, int silent, - const struct inode_operations *fs_dir_inode_ops, int isvfat, +int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, void (*setup)(struct super_block *)) { struct inode *root_inode = NULL, *fat_inode = NULL; @@ -1268,7 +1267,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, sb->s_magic = MSDOS_SUPER_MAGIC; sb->s_op = &fat_sops; sb->s_export_op = &fat_export_ops; - sbi->dir_ops = fs_dir_inode_ops; ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 711499040eb6..3b222dafd15b 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -659,14 +659,14 @@ static const struct inode_operations msdos_dir_inode_operations = { static void setup(struct super_block *sb) { + MSDOS_SB(sb)->dir_ops = &msdos_dir_inode_operations; sb->s_d_op = &msdos_dentry_operations; sb->s_flags |= MS_NOATIME; } static int msdos_fill_super(struct super_block *sb, void *data, int silent) { - return fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, - 0, setup); + return fat_fill_super(sb, data, silent, 0, setup); } static struct dentry *msdos_mount(struct file_system_type *fs_type, diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index adae3fb7451a..20b4ea53fdc4 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1065,6 +1065,7 @@ static const struct inode_operations vfat_dir_inode_operations = { static void setup(struct super_block *sb) { + MSDOS_SB(sb)->dir_ops = &vfat_dir_inode_operations; if (MSDOS_SB(sb)->options.name_check != 's') sb->s_d_op = &vfat_ci_dentry_ops; else @@ -1073,8 +1074,7 @@ static void setup(struct super_block *sb) static int vfat_fill_super(struct super_block *sb, void *data, int silent) { - return fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, - 1, setup); + return fat_fill_super(sb, data, silent, 1, setup); } static struct dentry *vfat_mount(struct file_system_type *fs_type, -- GitLab From 700309295551ef9217e4ae00a5b1d3030fc5438c Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 12 Apr 2011 21:08:38 +0900 Subject: [PATCH 0723/5560] fat: Fix possible null deref in fat_cache_add() Reported-by: Signed-off-by: OGAWA Hirofumi --- fs/fat/cache.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/fat/cache.c b/fs/fat/cache.c index ae8200f84e39..1cc7038e273d 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -151,6 +151,13 @@ static void fat_cache_add(struct inode *inode, struct fat_cache_id *new) spin_unlock(&MSDOS_I(inode)->cache_lru_lock); tmp = fat_cache_alloc(inode); + if (!tmp) { + spin_lock(&MSDOS_I(inode)->cache_lru_lock); + MSDOS_I(inode)->nr_caches--; + spin_unlock(&MSDOS_I(inode)->cache_lru_lock); + return; + } + spin_lock(&MSDOS_I(inode)->cache_lru_lock); cache = fat_cache_merge(inode, new); if (cache != NULL) { -- GitLab From 2c8a5ffb94bbb4f04aaf8a923e9098fb7a51a75a Mon Sep 17 00:00:00 2001 From: Alexey Fisher Date: Tue, 12 Apr 2011 21:08:38 +0900 Subject: [PATCH 0724/5560] fat: Convert fat_fs_error to use %pV - convert fat_fs_error to use %pV - be consequent and use "supor_block *sb" instead of "supor_block *s" - use devise name in each message. Signed-off-by: Alexey Fisher Signed-off-by: OGAWA Hirofumi --- fs/fat/fat.h | 10 +++++----- fs/fat/misc.c | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index dc163b8d7699..a768dad77907 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -325,12 +325,12 @@ extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2); /* fat/misc.c */ extern void -__fat_fs_error(struct super_block *s, int report, const char *fmt, ...) +__fat_fs_error(struct super_block *sb, int report, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))) __cold; -#define fat_fs_error(s, fmt, args...) \ - __fat_fs_error(s, 1, fmt , ## args) -#define fat_fs_error_ratelimit(s, fmt, args...) \ - __fat_fs_error(s, __ratelimit(&MSDOS_SB(s)->ratelimit), fmt , ## args) +#define fat_fs_error(sb, fmt, args...) \ + __fat_fs_error(sb, 1, fmt , ## args) +#define fat_fs_error_ratelimit(sb, fmt, args...) \ + __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args) extern int fat_clusters_flush(struct super_block *sb); extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 970e682ea754..e4f09629424e 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -20,26 +20,26 @@ * In case the file system is remounted read-only, it can be made writable * again by remounting it. */ -void __fat_fs_error(struct super_block *s, int report, const char *fmt, ...) +void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...) { - struct fat_mount_options *opts = &MSDOS_SB(s)->options; + struct fat_mount_options *opts = &MSDOS_SB(sb)->options; va_list args; + struct va_format vaf; if (report) { - printk(KERN_ERR "FAT: Filesystem error (dev %s)\n", s->s_id); - - printk(KERN_ERR " "); va_start(args, fmt); - vprintk(fmt, args); + vaf.fmt = fmt; + vaf.va = &args; + printk(KERN_ERR "FAT-fs (%s): error, %pV\n", sb->s_id, &vaf); va_end(args); - printk("\n"); } if (opts->errors == FAT_ERRORS_PANIC) - panic("FAT: fs panic from previous error\n"); - else if (opts->errors == FAT_ERRORS_RO && !(s->s_flags & MS_RDONLY)) { - s->s_flags |= MS_RDONLY; - printk(KERN_ERR "FAT: Filesystem has been set read-only\n"); + panic("FAT-fs (%s): fs panic from previous error\n", sb->s_id); + else if (opts->errors == FAT_ERRORS_RO && !(sb->s_flags & MS_RDONLY)) { + sb->s_flags |= MS_RDONLY; + printk(KERN_ERR "FAT-fs (%s): Filesystem has been " + "set read-only\n", sb->s_id); } } EXPORT_SYMBOL_GPL(__fat_fs_error); -- GitLab From 81ac21d34a91e85b029cd86e2ed5eeae8d7c3cd4 Mon Sep 17 00:00:00 2001 From: Alexey Fisher Date: Tue, 12 Apr 2011 21:08:38 +0900 Subject: [PATCH 0725/5560] fat: Add fat_msg() function for preformated FAT messages Add fat_msg() to replace not cosequent used printk() in fs/fat/* New message format should be as fallow: FAT-fs (sda1): some thing happened. Signed-off-by: Alexey Fisher Signed-off-by: OGAWA Hirofumi --- fs/fat/fat.h | 2 ++ fs/fat/misc.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index a768dad77907..8276cc282dec 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -331,6 +331,8 @@ __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...) __fat_fs_error(sb, 1, fmt , ## args) #define fat_fs_error_ratelimit(sb, fmt, args...) \ __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args) +void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))) __cold; extern int fat_clusters_flush(struct super_block *sb); extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, diff --git a/fs/fat/misc.c b/fs/fat/misc.c index e4f09629424e..3dcabc1bd8c3 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -44,6 +44,22 @@ void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...) } EXPORT_SYMBOL_GPL(__fat_fs_error); +/** + * fat_msg() - print preformated FAT specific messages. Every thing what is + * not fat_fs_error() should be fat_msg(). + */ +void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + printk("%sFAT-fs (%s): %pV\n", level, sb->s_id, &vaf); + va_end(args); +} + /* Flushes the number of free clusters on FAT32 */ /* XXX: Need to write one per FSINFO block. Currently only writes 1 */ int fat_clusters_flush(struct super_block *sb) -- GitLab From 869f58c0cdba3ae6880ab6113617e62672198773 Mon Sep 17 00:00:00 2001 From: Alexey Fisher Date: Tue, 12 Apr 2011 21:08:38 +0900 Subject: [PATCH 0726/5560] fat: Replace all printk with fat_msg() Replace all printk with fat_msg() Signed-off-by: Alexey Fisher Signed-off-by: OGAWA Hirofumi --- fs/fat/dir.c | 32 ++++++++++++----------- fs/fat/fatent.c | 4 +-- fs/fat/inode.c | 67 ++++++++++++++++++++++++------------------------- fs/fat/misc.c | 6 ++--- 4 files changed, 55 insertions(+), 54 deletions(-) diff --git a/fs/fat/dir.c b/fs/fat/dir.c index ee42b9e0b16a..4ad64732cbce 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -98,7 +98,7 @@ static int fat__get_entry(struct inode *dir, loff_t *pos, *bh = sb_bread(sb, phys); if (*bh == NULL) { - printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n", + fat_msg(sb, KERN_ERR, "Directory bread(block %llu) failed", (llu)phys); /* skip this block */ *pos = (iblock + 1) << sb->s_blocksize_bits; @@ -136,9 +136,10 @@ static inline int fat_get_entry(struct inode *dir, loff_t *pos, * but ignore that right now. * Ahem... Stack smashing in ring 0 isn't fun. Fixed. */ -static int uni16_to_x8(unsigned char *ascii, const wchar_t *uni, int len, - int uni_xlate, struct nls_table *nls) +static int uni16_to_x8(struct super_block *sb, unsigned char *ascii, + const wchar_t *uni, int len, struct nls_table *nls) { + int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate; const wchar_t *ip; wchar_t ec; unsigned char *op; @@ -166,23 +167,23 @@ static int uni16_to_x8(unsigned char *ascii, const wchar_t *uni, int len, } if (unlikely(*ip)) { - printk(KERN_WARNING "FAT: filename was truncated while " - "converting."); + fat_msg(sb, KERN_WARNING, "filename was truncated while " + "converting."); } *op = 0; return (op - ascii); } -static inline int fat_uni_to_x8(struct msdos_sb_info *sbi, const wchar_t *uni, +static inline int fat_uni_to_x8(struct super_block *sb, const wchar_t *uni, unsigned char *buf, int size) { + struct msdos_sb_info *sbi = MSDOS_SB(sb); if (sbi->options.utf8) return utf16s_to_utf8s(uni, FAT_MAX_UNI_CHARS, UTF16_HOST_ENDIAN, buf, size); else - return uni16_to_x8(buf, uni, size, sbi->options.unicode_xlate, - sbi->nls_io); + return uni16_to_x8(sb, buf, uni, size, sbi->nls_io); } static inline int @@ -419,7 +420,7 @@ int fat_search_long(struct inode *inode, const unsigned char *name, /* Compare shortname */ bufuname[last_u] = 0x0000; - len = fat_uni_to_x8(sbi, bufuname, bufname, sizeof(bufname)); + len = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname)); if (fat_name_match(sbi, name, name_len, bufname, len)) goto found; @@ -428,7 +429,7 @@ int fat_search_long(struct inode *inode, const unsigned char *name, int size = PATH_MAX - FAT_MAX_UNI_SIZE; /* Compare longname */ - len = fat_uni_to_x8(sbi, unicode, longname, size); + len = fat_uni_to_x8(sb, unicode, longname, size); if (fat_name_match(sbi, name, name_len, longname, len)) goto found; } @@ -545,7 +546,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent, if (nr_slots) { void *longname = unicode + FAT_MAX_UNI_CHARS; int size = PATH_MAX - FAT_MAX_UNI_SIZE; - int len = fat_uni_to_x8(sbi, unicode, longname, size); + int len = fat_uni_to_x8(sb, unicode, longname, size); fill_name = longname; fill_len = len; @@ -621,7 +622,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent, if (isvfat) { bufuname[j] = 0x0000; - i = fat_uni_to_x8(sbi, bufuname, bufname, sizeof(bufname)); + i = fat_uni_to_x8(sb, bufuname, bufname, sizeof(bufname)); } if (nr_slots) { /* hack for fat_ioctl_filldir() */ @@ -979,6 +980,7 @@ static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) { + struct super_block *sb = dir->i_sb; struct msdos_dir_entry *de; struct buffer_head *bh; int err = 0, nr_slots; @@ -1013,8 +1015,8 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) */ err = __fat_remove_entries(dir, sinfo->slot_off, nr_slots); if (err) { - printk(KERN_WARNING - "FAT: Couldn't remove the long name slots\n"); + fat_msg(sb, KERN_WARNING, + "Couldn't remove the long name slots"); } } @@ -1265,7 +1267,7 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots, if (sbi->fat_bits != 32) goto error; } else if (MSDOS_I(dir)->i_start == 0) { - printk(KERN_ERR "FAT: Corrupted directory (i_pos %lld)\n", + fat_msg(sb, KERN_ERR, "Corrupted directory (i_pos %lld)", MSDOS_I(dir)->i_pos); err = -EIO; goto error; diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index b47d2c9f4fa1..2e81ac0df7e2 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -95,7 +95,7 @@ static int fat12_ent_bread(struct super_block *sb, struct fat_entry *fatent, err_brelse: brelse(bhs[0]); err: - printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", (llu)blocknr); + fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", (llu)blocknr); return -EIO; } @@ -108,7 +108,7 @@ static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent, fatent->fat_inode = MSDOS_SB(sb)->fat_inode; fatent->bhs[0] = sb_bread(sb, blocknr); if (!fatent->bhs[0]) { - printk(KERN_ERR "FAT: FAT read failed (blocknr %llu)\n", + fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", (llu)blocknr); return -EIO; } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index c27704dc485e..7a6c819893f2 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -619,8 +619,8 @@ static int __fat_write_inode(struct inode *inode, int wait) bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits); if (!bh) { - printk(KERN_ERR "FAT: unable to read inode block " - "for updating (i_pos %lld)\n", i_pos); + fat_msg(sb, KERN_ERR, "unable to read inode block " + "for updating (i_pos %lld)", i_pos); return -EIO; } spin_lock(&sbi->inode_hash_lock); @@ -976,8 +976,8 @@ static const match_table_t vfat_tokens = { {Opt_err, NULL} }; -static int parse_options(char *options, int is_vfat, int silent, int *debug, - struct fat_mount_options *opts) +static int parse_options(struct super_block *sb, char *options, int is_vfat, + int silent, int *debug, struct fat_mount_options *opts) { char *p; substring_t args[MAX_OPT_ARGS]; @@ -1168,15 +1168,15 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, /* obsolete mount options */ case Opt_obsolate: - printk(KERN_INFO "FAT: \"%s\" option is obsolete, " - "not supported now\n", p); + fat_msg(sb, KERN_INFO, "\"%s\" option is obsolete, " + "not supported now", p); break; /* unknown option */ default: if (!silent) { - printk(KERN_ERR - "FAT: Unrecognized mount option \"%s\" " - "or missing value\n", p); + fat_msg(sb, KERN_ERR, + "Unrecognized mount option \"%s\" " + "or missing value", p); } return -EINVAL; } @@ -1185,7 +1185,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, out: /* UTF-8 doesn't provide FAT semantics */ if (!strcmp(opts->iocharset, "utf8")) { - printk(KERN_ERR "FAT: utf8 is not a recommended IO charset" + fat_msg(sb, KERN_ERR, "utf8 is not a recommended IO charset" " for FAT filesystems, filesystem will be " "case sensitive!\n"); } @@ -1270,7 +1270,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); - error = parse_options(data, isvfat, silent, &debug, &sbi->options); + error = parse_options(sb, data, isvfat, silent, &debug, &sbi->options); if (error) goto out_fail; @@ -1280,20 +1280,20 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sb_min_blocksize(sb, 512); bh = sb_bread(sb, 0); if (bh == NULL) { - printk(KERN_ERR "FAT: unable to read boot sector\n"); + fat_msg(sb, KERN_ERR, "unable to read boot sector"); goto out_fail; } b = (struct fat_boot_sector *) bh->b_data; if (!b->reserved) { if (!silent) - printk(KERN_ERR "FAT: bogus number of reserved sectors\n"); + fat_msg(sb, KERN_ERR, "bogus number of reserved sectors"); brelse(bh); goto out_invalid; } if (!b->fats) { if (!silent) - printk(KERN_ERR "FAT: bogus number of FAT structure\n"); + fat_msg(sb, KERN_ERR, "bogus number of FAT structure"); brelse(bh); goto out_invalid; } @@ -1306,7 +1306,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, media = b->media; if (!fat_valid_media(media)) { if (!silent) - printk(KERN_ERR "FAT: invalid media value (0x%02x)\n", + fat_msg(sb, KERN_ERR, "invalid media value (0x%02x)", media); brelse(bh); goto out_invalid; @@ -1316,7 +1316,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, || (logical_sector_size < 512) || (logical_sector_size > 4096)) { if (!silent) - printk(KERN_ERR "FAT: bogus logical sector size %u\n", + fat_msg(sb, KERN_ERR, "bogus logical sector size %u", logical_sector_size); brelse(bh); goto out_invalid; @@ -1324,15 +1324,15 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sbi->sec_per_clus = b->sec_per_clus; if (!is_power_of_2(sbi->sec_per_clus)) { if (!silent) - printk(KERN_ERR "FAT: bogus sectors per cluster %u\n", + fat_msg(sb, KERN_ERR, "bogus sectors per cluster %u", sbi->sec_per_clus); brelse(bh); goto out_invalid; } if (logical_sector_size < sb->s_blocksize) { - printk(KERN_ERR "FAT: logical sector size too small for device" - " (logical sector size = %u)\n", logical_sector_size); + fat_msg(sb, KERN_ERR, "logical sector size too small for device" + " (logical sector size = %u)", logical_sector_size); brelse(bh); goto out_fail; } @@ -1340,14 +1340,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, brelse(bh); if (!sb_set_blocksize(sb, logical_sector_size)) { - printk(KERN_ERR "FAT: unable to set blocksize %u\n", + fat_msg(sb, KERN_ERR, "unable to set blocksize %u", logical_sector_size); goto out_fail; } bh = sb_bread(sb, 0); if (bh == NULL) { - printk(KERN_ERR "FAT: unable to read boot sector" - " (logical sector size = %lu)\n", + fat_msg(sb, KERN_ERR, "unable to read boot sector" + " (logical sector size = %lu)", sb->s_blocksize); goto out_fail; } @@ -1383,16 +1383,16 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, fsinfo_bh = sb_bread(sb, sbi->fsinfo_sector); if (fsinfo_bh == NULL) { - printk(KERN_ERR "FAT: bread failed, FSINFO block" - " (sector = %lu)\n", sbi->fsinfo_sector); + fat_msg(sb, KERN_ERR, "bread failed, FSINFO block" + " (sector = %lu)", sbi->fsinfo_sector); brelse(bh); goto out_fail; } fsinfo = (struct fat_boot_fsinfo *)fsinfo_bh->b_data; if (!IS_FSINFO(fsinfo)) { - printk(KERN_WARNING "FAT: Invalid FSINFO signature: " - "0x%08x, 0x%08x (sector = %lu)\n", + fat_msg(sb, KERN_WARNING, "Invalid FSINFO signature: " + "0x%08x, 0x%08x (sector = %lu)", le32_to_cpu(fsinfo->signature1), le32_to_cpu(fsinfo->signature2), sbi->fsinfo_sector); @@ -1413,8 +1413,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sbi->dir_entries = get_unaligned_le16(&b->dir_entries); if (sbi->dir_entries & (sbi->dir_per_block - 1)) { if (!silent) - printk(KERN_ERR "FAT: bogus directroy-entries per block" - " (%u)\n", sbi->dir_entries); + fat_msg(sb, KERN_ERR, "bogus directroy-entries per block" + " (%u)", sbi->dir_entries); brelse(bh); goto out_invalid; } @@ -1436,7 +1436,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT); if (total_clusters > MAX_FAT(sb)) { if (!silent) - printk(KERN_ERR "FAT: count of clusters too big (%u)\n", + fat_msg(sb, KERN_ERR, "count of clusters too big (%u)", total_clusters); brelse(bh); goto out_invalid; @@ -1469,7 +1469,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sprintf(buf, "cp%d", sbi->options.codepage); sbi->nls_disk = load_nls(buf); if (!sbi->nls_disk) { - printk(KERN_ERR "FAT: codepage %s not found\n", buf); + fat_msg(sb, KERN_ERR, "codepage %s not found", buf); goto out_fail; } @@ -1477,7 +1477,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, if (sbi->options.isvfat) { sbi->nls_io = load_nls(sbi->options.iocharset); if (!sbi->nls_io) { - printk(KERN_ERR "FAT: IO charset %s not found\n", + fat_msg(sb, KERN_ERR, "IO charset %s not found", sbi->options.iocharset); goto out_fail; } @@ -1501,7 +1501,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, insert_inode_hash(root_inode); sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) { - printk(KERN_ERR "FAT: get root inode failed\n"); + fat_msg(sb, KERN_ERR, "get root inode failed"); goto out_fail; } @@ -1510,8 +1510,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, out_invalid: error = -EINVAL; if (!silent) - printk(KERN_INFO "VFS: Can't find a valid FAT filesystem" - " on dev %s.\n", sb->s_id); + fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem"); out_fail: if (fat_inode) diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 3dcabc1bd8c3..6d93360ca0cc 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -73,15 +73,15 @@ int fat_clusters_flush(struct super_block *sb) bh = sb_bread(sb, sbi->fsinfo_sector); if (bh == NULL) { - printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n"); + fat_msg(sb, KERN_ERR, "bread failed in fat_clusters_flush"); return -EIO; } fsinfo = (struct fat_boot_fsinfo *)bh->b_data; /* Sanity check */ if (!IS_FSINFO(fsinfo)) { - printk(KERN_ERR "FAT: Invalid FSINFO signature: " - "0x%08x, 0x%08x (sector = %lu)\n", + fat_msg(sb, KERN_ERR, "Invalid FSINFO signature: " + "0x%08x, 0x%08x (sector = %lu)", le32_to_cpu(fsinfo->signature1), le32_to_cpu(fsinfo->signature2), sbi->fsinfo_sector); -- GitLab From f68e542f3478147986a9c8958942ec649dc06201 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 12 Apr 2011 21:08:39 +0900 Subject: [PATCH 0727/5560] fat: Fix statfs->f_namelen pathconf(, _PC_NAME_MAX) is too small for long Unicode filename on fat. 255 as max filename size on fat is Unicode UTF-16 characters. it's not byte size. https://bugzilla.kernel.org/show_bug.cgi?id=16469 To fix it, this returns "len * NLS_MAX_CHARSET_SIZE" instead. Reported-by: Takumi Asaki Signed-off-by: OGAWA Hirofumi --- fs/fat/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 7a6c819893f2..cb8d8391ac0b 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -581,7 +581,8 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bavail = sbi->free_clusters; buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); - buf->f_namelen = sbi->options.isvfat ? FAT_LFN_LEN : 12; + buf->f_namelen = + (sbi->options.isvfat ? FAT_LFN_LEN : 12) * NLS_MAX_CHARSET_SIZE; return 0; } -- GitLab From d83d282bcbf24ec8ddd4f0eb57f7ad302c431b8a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 11 Apr 2011 16:00:00 -0700 Subject: [PATCH 0728/5560] s2io: Fix warnings due to -Wunused-but-set-variable. Most of these are cases where we are trying to read back a register after a write to ensure completion. Simply pre-fixing the readl() or readq() with "(void)" is sufficient because these are volatile operations and the compiler cannot eliminate them just because no real assignment takes place. The case of free_rxd_blk()'s assignments to "struct buffAdd *ba" is a real spurious assignment as this variable is completely otherwise unused. Signed-off-by: David S. Miller Acked-by: Jon Mason --- drivers/net/s2io.c | 5 +---- drivers/net/s2io.h | 10 ++++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ca8e75e9a7ee..2d5cc6142c04 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2244,13 +2244,12 @@ static int verify_xena_quiescence(struct s2io_nic *sp) static void fix_mac_address(struct s2io_nic *sp) { struct XENA_dev_config __iomem *bar0 = sp->bar0; - u64 val64; int i = 0; while (fix_mac[i] != END_SIGN) { writeq(fix_mac[i++], &bar0->gpio_control); udelay(10); - val64 = readq(&bar0->gpio_control); + (void) readq(&bar0->gpio_control); } } @@ -2727,7 +2726,6 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) int j; struct sk_buff *skb; struct RxD_t *rxdp; - struct buffAdd *ba; struct RxD1 *rxdp1; struct RxD3 *rxdp3; struct mac_info *mac_control = &sp->mac_control; @@ -2751,7 +2749,6 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) memset(rxdp, 0, sizeof(struct RxD1)); } else if (sp->rxd_mode == RXD_MODE_3B) { rxdp3 = (struct RxD3 *)rxdp; - ba = &mac_control->rings[ring_no].ba[blk][j]; pci_unmap_single(sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 628fd278866a..800b3a44e653 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -1002,18 +1002,16 @@ static inline void writeq(u64 val, void __iomem *addr) #define LF 2 static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order) { - u32 ret; - if (order == LF) { writel((u32) (val), addr); - ret = readl(addr); + (void) readl(addr); writel((u32) (val >> 32), (addr + 4)); - ret = readl(addr + 4); + (void) readl(addr + 4); } else { writel((u32) (val >> 32), (addr + 4)); - ret = readl(addr + 4); + (void) readl(addr + 4); writel((u32) (val), addr); - ret = readl(addr); + (void) readl(addr); } } -- GitLab From cd883a791b55c3c52ce402cd551585fed092d240 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 8 Apr 2011 11:11:21 +0000 Subject: [PATCH 0729/5560] vxge: always enable hardware time stamp Hardware time stamp calculation can only be enabled by the privileged function. Enable it always by default and simply use the ethtool interface to set a flag to indicate whether or not the respective function driver should indicate the timestamp along with the received packet. Also, make certain fields in vxge_hw_device_config bit-fields to reduce the size of the struct. Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.h | 70 +++++++++++++++++---------------- drivers/net/vxge/vxge-main.c | 43 ++++++++++++-------- drivers/net/vxge/vxge-traffic.h | 2 +- 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index 3c53aa732c9d..359b9b9f8041 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -412,44 +412,48 @@ struct vxge_hw_vp_config { * See also: struct vxge_hw_tim_intr_config{}. */ struct vxge_hw_device_config { - u32 dma_blockpool_initial; - u32 dma_blockpool_max; -#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE 0 -#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE 0 -#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE 4 -#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE 4096 - -#define VXGE_HW_MAX_PAYLOAD_SIZE_512 2 - - u32 intr_mode; -#define VXGE_HW_INTR_MODE_IRQLINE 0 -#define VXGE_HW_INTR_MODE_MSIX 1 -#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT 2 - -#define VXGE_HW_INTR_MODE_DEF 0 - - u32 rth_en; -#define VXGE_HW_RTH_DISABLE 0 -#define VXGE_HW_RTH_ENABLE 1 -#define VXGE_HW_RTH_DEFAULT 0 - - u32 rth_it_type; -#define VXGE_HW_RTH_IT_TYPE_SOLO_IT 0 -#define VXGE_HW_RTH_IT_TYPE_MULTI_IT 1 -#define VXGE_HW_RTH_IT_TYPE_DEFAULT 0 - - u32 rts_mac_en; + u32 device_poll_millis; +#define VXGE_HW_MIN_DEVICE_POLL_MILLIS 1 +#define VXGE_HW_MAX_DEVICE_POLL_MILLIS 100000 +#define VXGE_HW_DEF_DEVICE_POLL_MILLIS 1000 + + u32 dma_blockpool_initial; + u32 dma_blockpool_max; +#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE 0 +#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE 0 +#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE 4 +#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE 4096 + +#define VXGE_HW_MAX_PAYLOAD_SIZE_512 2 + + u32 intr_mode:2, +#define VXGE_HW_INTR_MODE_IRQLINE 0 +#define VXGE_HW_INTR_MODE_MSIX 1 +#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT 2 + +#define VXGE_HW_INTR_MODE_DEF 0 + + rth_en:1, +#define VXGE_HW_RTH_DISABLE 0 +#define VXGE_HW_RTH_ENABLE 1 +#define VXGE_HW_RTH_DEFAULT 0 + + rth_it_type:1, +#define VXGE_HW_RTH_IT_TYPE_SOLO_IT 0 +#define VXGE_HW_RTH_IT_TYPE_MULTI_IT 1 +#define VXGE_HW_RTH_IT_TYPE_DEFAULT 0 + + rts_mac_en:1, #define VXGE_HW_RTS_MAC_DISABLE 0 #define VXGE_HW_RTS_MAC_ENABLE 1 #define VXGE_HW_RTS_MAC_DEFAULT 0 - struct vxge_hw_vp_config vp_config[VXGE_HW_MAX_VIRTUAL_PATHS]; - - u32 device_poll_millis; -#define VXGE_HW_MIN_DEVICE_POLL_MILLIS 1 -#define VXGE_HW_MAX_DEVICE_POLL_MILLIS 100000 -#define VXGE_HW_DEF_DEVICE_POLL_MILLIS 1000 + hwts_en:1; +#define VXGE_HW_HWTS_DISABLE 0 +#define VXGE_HW_HWTS_ENABLE 1 +#define VXGE_HW_HWTS_DEFAULT 1 + struct vxge_hw_vp_config vp_config[VXGE_HW_MAX_VIRTUAL_PATHS]; }; /** diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index aff68c1118d4..d192dad8ff21 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3112,8 +3112,7 @@ 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) +static enum vxge_hw_status vxge_timestamp_config(struct __vxge_hw_device *devh) { enum vxge_hw_status status; u64 val64; @@ -3123,27 +3122,24 @@ static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev, * 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; + val64 = VXGE_HW_XMAC_TIMESTAMP_EN | + VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) | + VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0); - status = vxge_hw_mgmt_reg_write(vdev->devh, + status = vxge_hw_mgmt_reg_write(devh, vxge_hw_mgmt_reg_type_mrpcim, 0, offsetof(struct vxge_hw_mrpcim_reg, xmac_timestamp), val64); - vxge_hw_device_flush_io(vdev->devh); + vxge_hw_device_flush_io(devh); + devh->config.hwts_en = VXGE_HW_HWTS_ENABLE; 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))) @@ -3164,10 +3160,6 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data) 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; @@ -3186,8 +3178,7 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data) 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) + if (vdev->devh->config.hwts_en != VXGE_HW_HWTS_ENABLE) return -EFAULT; vdev->rx_hwts = 1; @@ -4575,6 +4566,24 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit4; } + /* Always enable HWTS. This will always cause the FCS to be invalid, + * due to the fact that HWTS is using the FCS as the location of the + * timestamp. The HW FCS checking will still correctly determine if + * there is a valid checksum, and the FCS is being removed by the driver + * anyway. So no fucntionality is being lost. Since it is always + * enabled, we now simply use the ioctl call to set whether or not the + * driver should be paying attention to the HWTS. + */ + if (is_privileged == VXGE_HW_OK) { + status = vxge_timestamp_config(hldev); + if (status != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, "%s: HWTS enable failed", + VXGE_DRIVER_NAME); + ret = -EFAULT; + goto _exit4; + } + } + vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL); /* set private device info */ diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 6c2fc0b72af5..4a518a3b131c 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -240,7 +240,7 @@ struct vxge_hw_tim_intr_config { u32 btimer_val; #define VXGE_HW_MIN_TIM_BTIMER_VAL 0 #define VXGE_HW_MAX_TIM_BTIMER_VAL 67108864 -#define VXGE_HW_USE_FLASH_DEFAULT 0xffffffff +#define VXGE_HW_USE_FLASH_DEFAULT (~0) u32 timer_ac_en; #define VXGE_HW_TIM_TIMER_AC_ENABLE 1 -- GitLab From 9f9b16458134ba9f06ef6f15369513aa9eebc81c Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 8 Apr 2011 11:11:22 +0000 Subject: [PATCH 0730/5560] vxge: spin-lock issue In vxge_hw_vpath_close, __vxge_hw_vp_terminate memsets the vpath which clobbers the spin lock state, then the driver attempts to acquire the spin lock. Resolve this by not zeroing the lock part of vpath struct, clean-up vpath locking in init, close, and fix locking hole in fw_api call. Issue found by Bob Picco Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 48 ++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 401bebf59502..32763b2dd73f 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -159,16 +159,15 @@ 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; + struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg; enum vxge_hw_status status; u64 val64; - u32 retry = 0, max_retry = 100; - - vp_reg = vpath->vp_reg; + u32 retry = 0, max_retry = 3; - if (vpath->vp_open) { - max_retry = 3; - spin_lock(&vpath->lock); + spin_lock(&vpath->lock); + if (!vpath->vp_open) { + spin_unlock(&vpath->lock); + max_retry = 100; } writeq(*data0, &vp_reg->rts_access_steer_data0); @@ -1000,7 +999,7 @@ __vxge_hw_vpath_addr_get(struct __vxge_hw_virtualpath *vpath, /** * vxge_hw_device_hw_info_get - Get the hw information * Returns the vpath mask that has the bits set for each vpath allocated - * for the driver, FW version information and the first mac addresse for + * for the driver, FW version information, and the first mac address for * each vpath */ enum vxge_hw_status __devinit @@ -1064,9 +1063,10 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_vpath_pointer[i]); + spin_lock_init(&vpath.lock); vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) (bar0 + val64); - vpath.vp_open = 0; + vpath.vp_open = VXGE_HW_VP_NOT_OPEN; status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info); if (status != VXGE_HW_OK) @@ -1090,7 +1090,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_vpath_pointer[i]); vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) (bar0 + val64); - vpath.vp_open = 0; + vpath.vp_open = VXGE_HW_VP_NOT_OPEN; status = __vxge_hw_vpath_addr_get(&vpath, hw_info->mac_addrs[i], @@ -4646,7 +4646,27 @@ static void __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id) 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)); + /* If the whole struct __vxge_hw_virtualpath is zeroed, nothing will + * work after the interface is brought down. + */ + spin_lock(&vpath->lock); + vpath->vp_open = VXGE_HW_VP_NOT_OPEN; + spin_unlock(&vpath->lock); + + vpath->vpmgmt_reg = NULL; + vpath->nofl_db = NULL; + vpath->max_mtu = 0; + vpath->vsport_number = 0; + vpath->max_kdfc_db = 0; + vpath->max_nofl_db = 0; + vpath->ringh = NULL; + vpath->fifoh = NULL; + memset(&vpath->vpath_handles, 0, sizeof(struct list_head)); + vpath->stats_block = 0; + vpath->hw_stats = NULL; + vpath->hw_stats_sav = NULL; + vpath->sw_stats = NULL; + exit: return; } @@ -4670,7 +4690,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); + spin_lock_init(&vpath->lock); vpath->vp_id = vp_id; vpath->vp_open = VXGE_HW_VP_OPEN; vpath->hldev = hldev; @@ -5019,10 +5039,6 @@ 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; } -- GitLab From 6ba1037c3d871ab70e342631516dbf841c35b086 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Fri, 8 Apr 2011 11:11:23 +0000 Subject: [PATCH 0731/5560] vxge: update driver version Update vxge driver version to 2.5.3 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 581e21525e85..b9efa28bab3e 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 "5" -#define VXGE_VERSION_FIX "2" -#define VXGE_VERSION_BUILD "22259" +#define VXGE_VERSION_FIX "3" +#define VXGE_VERSION_BUILD "22640" #define VXGE_VERSION_FOR "k" #define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) -- GitLab From 607bf324ab3d780e1ec20b1b1a3bfaa3be58a957 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 12 Apr 2011 15:22:26 +0800 Subject: [PATCH 0732/5560] slub: Fix a typo in config name There's no config named SLAB_DEBUG, and it should be a typo of SLUB_DEBUG. Acked-by: Christoph Lameter Signed-off-by: Li Zefan Signed-off-by: Pekka Enberg --- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index f881874843a5..129f10cdfc59 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3203,7 +3203,7 @@ static void __init kmem_cache_bootstrap_fixup(struct kmem_cache *s) list_for_each_entry(p, &n->partial, lru) p->slab = s; -#ifdef CONFIG_SLAB_DEBUG +#ifdef CONFIG_SLUB_DEBUG list_for_each_entry(p, &n->full, lru) p->slab = s; #endif -- GitLab From 143780c6562080c1117cd9197ee1b33c0d838376 Mon Sep 17 00:00:00 2001 From: "Allan, Bruce W" Date: Mon, 11 Apr 2011 13:01:59 +0000 Subject: [PATCH 0733/5560] ethtool: time to blink provided in seconds not jiffies When blinking for a duration set by the user, the value specified is in seconds but it is used as the number of jiffies in the timeout after which the Physical ID indicator is deactivated. Fix by converting the timeout to seconds. Signed-off-by: Bruce Allan Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 704e176ad3a9..43ef09fedd6e 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1653,7 +1653,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) if (rc == 0) { /* Driver will handle this itself */ schedule_timeout_interruptible( - id.data ? id.data : MAX_SCHEDULE_TIMEOUT); + id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT); } else { /* Driver expects to be called periodically */ do { -- GitLab From e8306f989483e4b97a8b37dd268de6c8c6f35e75 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 6 Apr 2011 11:41:10 +0530 Subject: [PATCH 0734/5560] mac80211: Check for queued frames before entering power save. In a highly noisy environment, the tx rate of the driver drops and the application slows down since it has not yet received ACKs for the frames already queued in the hardware. Since this ACK may take more than 100ms, stopping the dev queues for entering PS at this stage breaks applications, WMM test cases in my testing. If there are frames already pending in the tx queue, postponing the PS logic helps to avoid redundant queue stops. When power save is enabled by default and in a noisy environment, this API certainly helps in improving the average throughput. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- include/net/mac80211.h | 4 ++++ net/mac80211/driver-ops.h | 13 +++++++++++++ net/mac80211/driver-trace.h | 20 ++++++++++++++++++++ net/mac80211/mlme.c | 17 +++++++++-------- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 965f1b16e53a..361bc5d85b1a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1819,6 +1819,9 @@ enum ieee80211_ampdu_mlme_action { * @set_ringparam: Set tx and rx ring sizes. * * @get_ringparam: Get tx and rx ring current and maximum sizes. + * + * @tx_frames_pending: Check if there is any pending frame in the hardware + * queues before entering power save. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1906,6 +1909,7 @@ struct ieee80211_ops { int (*set_ringparam)(struct ieee80211_hw *hw, u32 tx, u32 rx); void (*get_ringparam)(struct ieee80211_hw *hw, u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); + bool (*tx_frames_pending)(struct ieee80211_hw *hw); }; /** diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 9c0d62bb0ea3..00a0685f2403 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -552,4 +552,17 @@ static inline void drv_get_ringparam(struct ieee80211_local *local, trace_drv_return_void(local); } +static inline bool drv_tx_frames_pending(struct ieee80211_local *local) +{ + bool ret = false; + + might_sleep(); + + trace_drv_tx_frames_pending(local); + if (local->ops->tx_frames_pending) + ret = local->ops->tx_frames_pending(&local->hw); + trace_drv_return_bool(local, ret); + + return ret; +} #endif /* __MAC80211_DRIVER_OPS */ diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 45aab80738e2..c8c934d48b7a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -74,6 +74,21 @@ TRACE_EVENT(drv_return_int, TP_printk(LOCAL_PR_FMT " - %d", LOCAL_PR_ARG, __entry->ret) ); +TRACE_EVENT(drv_return_bool, + TP_PROTO(struct ieee80211_local *local, bool ret), + TP_ARGS(local, ret), + TP_STRUCT__entry( + LOCAL_ENTRY + __field(bool, ret) + ), + TP_fast_assign( + LOCAL_ASSIGN; + __entry->ret = ret; + ), + TP_printk(LOCAL_PR_FMT " - %s", LOCAL_PR_ARG, (__entry->ret) ? + "true" : "false") +); + TRACE_EVENT(drv_return_u64, TP_PROTO(struct ieee80211_local *local, u64 ret), TP_ARGS(local, ret), @@ -964,6 +979,11 @@ TRACE_EVENT(drv_get_ringparam, ) ); +DEFINE_EVENT(local_only_evt, drv_tx_frames_pending, + TP_PROTO(struct ieee80211_local *local), + TP_ARGS(local) +); + DEFINE_EVENT(local_only_evt, drv_offchannel_tx_cancel_wait, TP_PROTO(struct ieee80211_local *local), TP_ARGS(local) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 865fed4cc18b..a41f234bd486 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -761,15 +761,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { netif_tx_stop_all_queues(sdata->dev); - /* - * Flush all the frames queued in the driver before - * going to power save - */ - drv_flush(local, false); - ieee80211_send_nullfunc(local, sdata, 1); - /* Flush once again to get the tx status of nullfunc frame */ - drv_flush(local, false); + if (drv_tx_frames_pending(local)) + mod_timer(&local->dynamic_ps_timer, jiffies + + msecs_to_jiffies( + local->hw.conf.dynamic_ps_timeout)); + else { + ieee80211_send_nullfunc(local, sdata, 1); + /* Flush to get the tx status of nullfunc frame */ + drv_flush(local, false); + } } if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && -- GitLab From 15b91e830dbf300d653b3fe70f6ef71b568164a3 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Wed, 6 Apr 2011 11:41:11 +0530 Subject: [PATCH 0735/5560] ath9k: Implement dev_tx_frames_pending callback. This function returns true if there is atleast one frame in any one of the tx queues. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ba1c9a684eff..93b9fa2cbaf8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2201,6 +2201,21 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) ath9k_ps_restore(sc); } +static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) +{ + struct ath_softc *sc = hw->priv; + int i; + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + + if (ath9k_has_pending_frames(sc, &sc->tx.txq[i])) + return true; + } + return false; +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2223,4 +2238,5 @@ struct ieee80211_ops ath9k_ops = { .rfkill_poll = ath9k_rfkill_poll_state, .set_coverage_class = ath9k_set_coverage_class, .flush = ath9k_flush, + .tx_frames_pending = ath9k_tx_frames_pending, }; -- GitLab From d88525e8fdc00c0078d38353caffc29e5a9c70cc Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 6 Apr 2011 21:42:52 +0530 Subject: [PATCH 0736/5560] ath9k_hw: Fix instable target power control b/w CCK/OFDM The problem is that when the attenuation is increased, the rate will start to drop from MCS7 -> MCS6, and finally will see MCS1 -> CCK_11Mbps. When the rate is changed b/w CCK and OFDM, it will use register desired_scale to calculate how much tx gain need to change. The output power with the same tx gain for CCK and OFDM modulated signals are different. This difference is constant for AR9280 but not AR9285/AR9271. It has different PA architecture a constant. So it should be calibrated against this PA characteristic. The driver has to read the calibrated values from EEPROM and set the tx power registers accordingly. Signed-off-by: Rajkumar Manoharan Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_phy.h | 6 +++++ drivers/net/wireless/ath/ath9k/eeprom.h | 6 ++++- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 26 +++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 37663dbbcf57..47780ef1c892 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -483,7 +483,11 @@ #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 +#define AR_PHY_TX_PWRCTRL8 0xa278 + #define AR_PHY_TX_PWRCTRL9 0xa27C + +#define AR_PHY_TX_PWRCTRL10 0xa394 #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 @@ -495,6 +499,8 @@ #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 +#define AR_PHY_CH0_TX_PWRCTRL12 0xa3dc +#define AR_PHY_CH0_TX_PWRCTRL13 0xa3e0 #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index bd82447f5b78..3e316133f114 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -436,7 +436,11 @@ struct modal_eep_4k_header { u8 db2_2:4, db2_3:4; u8 db2_4:4, reserved:4; #endif - u8 futureModal[4]; + u8 tx_diversity; + u8 flc_pwr_thresh; + u8 bb_scale_smrt_antenna; +#define EEP_4K_BB_DESIRED_SCALE_MASK 0x1f + u8 futureModal[1]; struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS]; } __packed; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index bc77a308c901..6f714dd72365 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -781,6 +781,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, { struct modal_eep_4k_header *pModal; struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; + struct base_eep_header_4k *pBase = &eep->baseEepHeader; u8 txRxAttenLocal; u8 ob[5], db1[5], db2[5]; u8 ant_div_control1, ant_div_control2; @@ -1003,6 +1004,31 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); } + if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { + u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & + EEP_4K_BB_DESIRED_SCALE_MASK); + if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { + u32 pwrctrl, mask, clr; + + mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); + REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); + + mask = BIT(0)|BIT(5)|BIT(15); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); + + mask = BIT(0)|BIT(5); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); + } + } } static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) -- GitLab From 18bf965702058f5f8039e6a46bb5ebaa18d38ebd Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 6 Apr 2011 16:46:55 -0700 Subject: [PATCH 0737/5560] mwifiex: fix cmd_skb headroom decreasing issue Before calling host_to_card() to send the cmd to firmware, we use skb_push() to add 4 bytes SDIO interface header at the start of the data buffer. Since cmd_skb data structure will be re-used at a later time, we need to restore its headroom by removing the 4 bytes header. Signed-off-by: Bing Zhao Signed-off-by: Marc Yang Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a9aeb31af455..8676480ead94 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -206,6 +206,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, cmd_node->cmd_skb->data, cmd_node->cmd_skb->len, NULL); + skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN); + if (ret == -1) { dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); if (wait_queue) -- GitLab From 6a35a0ac5771fa962c45926678d1f194cbc98c4e Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 6 Apr 2011 16:46:56 -0700 Subject: [PATCH 0738/5560] mwifiex: use common keyinfo bitmap for different key types Instead of having separate key information definitions for each type of key, a common key information bitmap is used. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/fw.h | 27 +++------------------- drivers/net/wireless/mwifiex/sta_cmd.c | 27 +++++++++++----------- drivers/net/wireless/mwifiex/sta_cmdresp.c | 3 +-- drivers/net/wireless/mwifiex/sta_ioctl.c | 3 +-- 4 files changed, 18 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 2b938115b26a..f8c008f8f476 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -72,33 +72,12 @@ enum KEY_TYPE_ID { KEY_TYPE_ID_AES, KEY_TYPE_ID_WAPI, }; - -enum KEY_INFO_WEP { - KEY_INFO_WEP_MCAST = 0x01, - KEY_INFO_WEP_UNICAST = 0x02, - KEY_INFO_WEP_ENABLED = 0x04 -}; - -enum KEY_INFO_TKIP { - KEY_INFO_TKIP_MCAST = 0x01, - KEY_INFO_TKIP_UNICAST = 0x02, - KEY_INFO_TKIP_ENABLED = 0x04 -}; - -enum KEY_INFO_AES { - KEY_INFO_AES_MCAST = 0x01, - KEY_INFO_AES_UNICAST = 0x02, - KEY_INFO_AES_ENABLED = 0x04 -}; +#define KEY_MCAST BIT(0) +#define KEY_UNICAST BIT(1) +#define KEY_ENABLED BIT(2) #define WAPI_KEY_LEN 50 -enum KEY_INFO_WAPI { - KEY_INFO_WAPI_MCAST = 0x01, - KEY_INFO_WAPI_UNICAST = 0x02, - KEY_INFO_WAPI_ENABLED = 0x04 -}; - #define MAX_POLL_TRIES 100 #define MAX_MULTI_INTERFACE_POLL_TRIES 1000 diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6fff26153e26..19de6524d428 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -500,9 +500,8 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, key_param_set->key_type_id = cpu_to_le16(KEY_TYPE_ID_WEP); key_param_set->key_info = - cpu_to_le16(KEY_INFO_WEP_ENABLED | - KEY_INFO_WEP_UNICAST | - KEY_INFO_WEP_MCAST); + cpu_to_le16(KEY_ENABLED | KEY_UNICAST | + KEY_MCAST); key_param_set->key_len = cpu_to_le16(priv->wep_key[i].key_length); /* Set WEP key index */ @@ -589,10 +588,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, cpu_to_le16(KEY_TYPE_ID_WAPI); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_INFO_WAPI_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_INFO_WAPI_ENABLED); + cpu_to_le16(!KEY_ENABLED); key_material->key_param_set.key[0] = enc_key->key_index; if (!priv->sec_info.wapi_key_on) @@ -604,10 +603,10 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) { /* WAPI pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_WAPI_UNICAST); + cpu_to_le16(KEY_UNICAST); } else { /* WAPI group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_WAPI_MCAST); + cpu_to_le16(KEY_MCAST); priv->sec_info.wapi_key_on = true; } @@ -634,32 +633,32 @@ static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, cpu_to_le16(KEY_TYPE_ID_AES); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_INFO_AES_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_INFO_AES_ENABLED); + cpu_to_le16(!KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* AES pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_AES_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* AES group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_AES_MCAST); + cpu_to_le16(KEY_MCAST); } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); key_material->key_param_set.key_type_id = cpu_to_le16(KEY_TYPE_ID_TKIP); key_material->key_param_set.key_info = - cpu_to_le16(KEY_INFO_TKIP_ENABLED); + cpu_to_le16(KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* TKIP pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_TKIP_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* TKIP group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_INFO_TKIP_MCAST); + cpu_to_le16(KEY_MCAST); } if (key_material->key_param_set.key_type_id) { diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 74add45b99b6..648df690f5d1 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -574,8 +574,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, &resp->params.key_material; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { - if ((le16_to_cpu(key->key_param_set.key_info) & - KEY_INFO_TKIP_MCAST)) { + if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { dev_dbg(priv->adapter->dev, "info: key: GTK is set\n"); priv->wpa_is_gtk_set = true; priv->scan_block = false; diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index b163507b1fe0..2fcdbc224e08 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -1729,8 +1729,7 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, sizeof(ibss_key->key_param_set.key_len)); ibss_key->key_param_set.key_type_id = cpu_to_le16(KEY_TYPE_ID_TKIP); - ibss_key->key_param_set.key_info - = cpu_to_le16(KEY_INFO_TKIP_ENABLED); + ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED); /* Send the key as GTK to firmware */ encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST; -- GitLab From 264bbec811024e39fe8f9e7a45743f81f373529e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 7 Apr 2011 19:24:23 +0200 Subject: [PATCH 0739/5560] ath9k: fix PS-Poll reception on AR9160 and earlier I can't find any valid reason for not setting the ATH9K_RX_FILTER_PSPOLL flag on older hardware and neither the documentation nor the reference code mention any reason for excluding older hardware here. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 3842b7518661..ef198ae71eb7 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -426,9 +426,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) else rfilt |= ATH9K_RX_FILTER_BEACON; - if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || - AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && - (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && + if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || (sc->rx.rxfilter & FIF_PSPOLL)) rfilt |= ATH9K_RX_FILTER_PSPOLL; -- GitLab From 952949738aba19f84dae9def18e0baa58f0ce0b8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 7 Apr 2011 19:30:32 +0200 Subject: [PATCH 0740/5560] ath9k: fix too early enabling of rx during ath_startrecv() rx should only be enabled after enough rx buffers have been given to the hardware, however ath_rx_buf_link was calling ath9k_hw_rxena after every single added buffer. Fix this by calling ath9k_hw_rxena directly from the rx tasklet after completion instead. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index ef198ae71eb7..b81bfc4d66ef 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -75,7 +75,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) *sc->rx.rxlink = bf->bf_daddr; sc->rx.rxlink = &ds->ds_link; - ath9k_hw_rxena(ah); } static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) @@ -1765,6 +1764,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) } else { list_move_tail(&bf->list, &sc->rx.rxbuf); ath_rx_buf_link(sc, bf); + ath9k_hw_rxena(ah); } } while (1); -- GitLab From a22e93f5d819f11d2a2d6332e20ff5b462e5c208 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 7 Apr 2011 20:40:32 +0200 Subject: [PATCH 0741/5560] iwl4965: drop a lone pr_err() iwl4965_rate_control_register() prints a message at KERN_ERR level. It looks like it's just a debugging message, so pr_err() seems to be overdone. But none of the similar functions in drivers/net/wireless print a message, so let's just drop it. Signed-off-by: Paul Bolle Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965-rs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 31ac672b64e1..89509392ef5d 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c @@ -2860,7 +2860,6 @@ static struct rate_control_ops rs_4965_ops = { int iwl4965_rate_control_register(void) { - pr_err("Registering 4965 rate control operations\n"); return ieee80211_rate_control_register(&rs_4965_ops); } -- GitLab From 581a8b0feeed8877aab3a8ca4c972419790cd07f Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:27 -0700 Subject: [PATCH 0742/5560] nl80211: rename NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE To NL80211_MESH_SETUP_IE. This reflects our ability to insert any ie into a mesh beacon, not simply path selection ies. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 9 +++++---- include/net/cfg80211.h | 8 ++++---- net/mac80211/cfg.c | 15 +++++++-------- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/mesh.c | 6 +++--- net/mac80211/mesh_plink.c | 2 +- net/mac80211/tx.c | 2 +- net/wireless/mesh.c | 4 ++-- net/wireless/nl80211.c | 11 ++++++----- 9 files changed, 31 insertions(+), 30 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 16eea7229e99..ecf6b68a96da 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -545,6 +545,7 @@ enum nl80211_commands { /* 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 +#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE /** * enum nl80211_attrs - nl80211 netlink attributes @@ -1719,9 +1720,9 @@ enum nl80211_meshconf_params { * 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_IE: Information elements for this mesh, for instance, a + * robust security network ie, or a vendor specific information element that + * vendors will use to identify the path selection methods and metrics in use. * * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use @@ -1730,7 +1731,7 @@ 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, + NL80211_MESH_SETUP_IE, /* keep last */ __NL80211_MESH_SETUP_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ba7384acf4e0..1d02ddf5a8a3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -689,8 +689,8 @@ struct mesh_config { * @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 + * @ie: vendor information elements (optional) + * @ie_len: length of vendor information elements * * These parameters are fixed when the mesh is created. */ @@ -699,8 +699,8 @@ struct mesh_setup { u8 mesh_id_len; u8 path_sel_proto; u8 path_metric; - const u8 *vendor_ie; - u8 vendor_ie_len; + const u8 *ie; + u8 ie_len; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bf5d28da46e6..d9428afd8bf6 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1034,26 +1034,25 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, u8 *new_ie; const u8 *old_ie; - /* first allocate the new vendor information element */ + /* allocate information elements */ new_ie = NULL; - old_ie = ifmsh->vendor_ie; + old_ie = ifmsh->ie; - ifmsh->vendor_ie_len = setup->vendor_ie_len; - if (setup->vendor_ie_len) { - new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len, + if (setup->ie_len) { + new_ie = kmemdup(setup->ie, setup->ie_len, GFP_KERNEL); if (!new_ie) return -ENOMEM; } + ifmsh->ie_len = setup->ie_len; + ifmsh->ie = new_ie; + kfree(old_ie); /* 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; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6eb2c8523eeb..6450100594ba 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -488,8 +488,8 @@ struct ieee80211_if_mesh { struct mesh_config mshcfg; u32 mesh_seqnum; bool accepting_plinks; - const u8 *vendor_ie; - u8 vendor_ie_len; + const u8 *ie; + u8 ie_len; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2a57cc02c618..1c244c0c7664 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -279,9 +279,9 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) 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 (sdata->u.mesh.ie) { + int len = sdata->u.mesh.ie_len; + const u8 *data = sdata->u.mesh.ie; if (skb_tailroom(skb) > len) memcpy(skb_put(skb, len), data, len); } diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 44b53931ba5e..c705b20e1acb 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, __le16 reason) { struct ieee80211_local *local = sdata->local; struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + - sdata->u.mesh.vendor_ie_len); + sdata->u.mesh.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 ce4596ed1268..17b10be31f55 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2262,7 +2262,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, /* headroom, head length, tail length and maximum TIM length */ skb = dev_alloc_skb(local->tx_headroom + 400 + - sdata->u.mesh.vendor_ie_len); + sdata->u.mesh.ie_len); if (!skb) goto out; diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 73e39c171ffb..0d4b2260f96f 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -53,8 +53,8 @@ const struct mesh_config default_mesh_config = { 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, + .ie = NULL, + .ie_len = 0, }; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 297d7ce4117b..ccd825a5857e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2823,7 +2823,7 @@ 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, + [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, }; @@ -2925,13 +2925,14 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, IEEE80211_PATH_METRIC_VENDOR : IEEE80211_PATH_METRIC_AIRTIME; - if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) { + + if (tb[NL80211_MESH_SETUP_IE]) { struct nlattr *ieattr = - tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]; + tb[NL80211_MESH_SETUP_IE]; if (!is_valid_ie_attr(ieattr)) return -EINVAL; - setup->vendor_ie = nla_data(ieattr); - setup->vendor_ie_len = nla_len(ieattr); + setup->ie = nla_data(ieattr); + setup->ie_len = nla_len(ieattr); } return 0; -- GitLab From 15d5dda623139bbf6165030fc251bbd5798f4130 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:28 -0700 Subject: [PATCH 0743/5560] cfg80211/nl80211: Add userspace authentication flag to mesh setup During mesh setup, use NL80211_MESH_SETUP_USERSPACE_AUTH flag to create a secure mesh and route management frames to userspace. Also, NL80211_CMD_GET_WIPHY now returns a flag NL80211_SUPPORT_MESH_AUTH if the wiphy's mesh implementation supports routing of mesh auth frames to userspace. This is useful for forward compatibility between old kernels and new userspace tools. Signed-off-by: Javier Cardona Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 9 +++++++++ include/net/cfg80211.h | 5 +++++ net/wireless/mesh.c | 4 ++++ net/wireless/nl80211.c | 5 +++++ 4 files changed, 23 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index ecf6b68a96da..0e652d860819 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -887,6 +887,9 @@ enum nl80211_commands { * changed once the mesh is active. * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute * containing attributes from &enum nl80211_meshconf_params. + * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver + * allows auth frames in a mesh to be passed to userspace for processing via + * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -1075,6 +1078,8 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, + NL80211_ATTR_SUPPORT_MESH_AUTH, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1724,6 +1729,9 @@ enum nl80211_meshconf_params { * robust security network ie, or a vendor specific information element that * vendors will use to identify the path selection methods and metrics in use. * + * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication + * daemon will be authenticating mesh candidates. + * * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use */ @@ -1732,6 +1740,7 @@ enum nl80211_mesh_setup_params { NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, NL80211_MESH_SETUP_IE, + NL80211_MESH_SETUP_USERSPACE_AUTH, /* keep last */ __NL80211_MESH_SETUP_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1d02ddf5a8a3..e77603bd1630 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -691,6 +691,7 @@ struct mesh_config { * @path_metric: which metric to use * @ie: vendor information elements (optional) * @ie_len: length of vendor information elements + * @is_secure: or not * * These parameters are fixed when the mesh is created. */ @@ -701,6 +702,7 @@ struct mesh_setup { u8 path_metric; const u8 *ie; u8 ie_len; + bool is_secure; }; /** @@ -1451,6 +1453,8 @@ struct cfg80211_ops { * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate * unicast and multicast TX keys. + * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing + * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1463,6 +1467,7 @@ enum wiphy_flags { WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), WIPHY_FLAG_IBSS_RSN = BIT(8), WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9), + WIPHY_FLAG_MESH_AUTH = BIT(10), }; struct mac_address { diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 0d4b2260f96f..0e5c122ce324 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -72,6 +72,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; + if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && + setup->is_secure) + return -EOPNOTSUPP; + if (wdev->mesh_id_len) return -EALREADY; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ccd825a5857e..cbedfc2a42a2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, + [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, .len = NL80211_HT_CAPABILITY_LEN }, @@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); + if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, @@ -2823,6 +2826,7 @@ 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_USERSPACE_AUTH] = { .type = NLA_FLAG }, [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, }; @@ -2934,6 +2938,7 @@ static int nl80211_parse_mesh_setup(struct genl_info *info, setup->ie = nla_data(ieattr); setup->ie_len = nla_len(ieattr); } + setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); return 0; } -- GitLab From 5cff5e01e818029a5d2c3c31b7ae5e5e7ee70452 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:29 -0700 Subject: [PATCH 0744/5560] mac80211: ignore peers if security is enabled for this mesh Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 1 + net/mac80211/ieee80211_i.h | 1 + net/mac80211/mesh.c | 4 ++++ net/mac80211/mesh_plink.c | 4 ++++ net/wireless/mesh.c | 1 + 5 files changed, 11 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d9428afd8bf6..dc623d884d02 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1053,6 +1053,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, 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->is_secure = setup->is_secure; return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6450100594ba..8d6d6e3d95da 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -490,6 +490,7 @@ struct ieee80211_if_mesh { bool accepting_plinks; const u8 *ie; u8 ie_len; + bool is_secure; }; #ifdef CONFIG_MAC80211_MESH diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 1c244c0c7664..47a26c0f6993 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -573,6 +573,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, &elems); + /* ignore beacons from secure mesh peers if our security is off */ + if (elems.rsn_len && !sdata->u.mesh.is_secure) + return; + if (elems.ds_params && elems.ds_params_len == 1) freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); else diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index c705b20e1acb..bafe25594e09 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -449,6 +449,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m mpl_dbg("Mesh plink: missing necessary peer link ie\n"); return; } + if (elems.rsn_len && !sdata->u.mesh.is_secure) { + mpl_dbg("Mesh plink: can't establish link with secure peer\n"); + return; + } ftype = mgmt->u.action.u.plink_action.action_code; ie_len = elems.peer_link_len; diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 0e5c122ce324..e0226e8265a3 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -55,6 +55,7 @@ const struct mesh_setup default_mesh_setup = { .path_metric = IEEE80211_PATH_METRIC_AIRTIME, .ie = NULL, .ie_len = 0, + .is_secure = false, }; int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, -- GitLab From b39c48fac1fc915a5dcd024bf6e9aabc855ed591 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:30 -0700 Subject: [PATCH 0745/5560] nl80211/mac80211: let userspace authenticate stations Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ net/mac80211/cfg.c | 6 ++++++ net/wireless/nl80211.c | 5 ++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0e652d860819..5ec4ac3a0ef4 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1174,6 +1174,7 @@ enum nl80211_iftype { * with short barker preamble * @NL80211_STA_FLAG_WME: station is WME/QoS capable * @NL80211_STA_FLAG_MFP: station uses management frame protection + * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated * @NL80211_STA_FLAG_MAX: highest station flag number currently defined * @__NL80211_STA_FLAG_AFTER_LAST: internal use */ @@ -1183,6 +1184,7 @@ enum nl80211_sta_flags { NL80211_STA_FLAG_SHORT_PREAMBLE, NL80211_STA_FLAG_WME, NL80211_STA_FLAG_MFP, + NL80211_STA_FLAG_AUTHENTICATED, /* keep last */ __NL80211_STA_FLAG_AFTER_LAST, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index dc623d884d02..1c25723eacda 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -686,6 +686,12 @@ static void sta_apply_parameters(struct ieee80211_local *local, if (set & BIT(NL80211_STA_FLAG_MFP)) sta->flags |= WLAN_STA_MFP; } + + if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { + sta->flags &= ~WLAN_STA_AUTH; + if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) + sta->flags |= WLAN_STA_AUTH; + } spin_unlock_irqrestore(&sta->flaglock, flags); /* diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cbedfc2a42a2..ce29a0d0e88e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1925,6 +1925,7 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, + [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, }; static int parse_station_flags(struct genl_info *info, @@ -2284,7 +2285,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) err = -EINVAL; if (params.supported_rates) err = -EINVAL; - if (params.sta_flags_mask) + if (params.sta_flags_mask & + ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | + BIT(NL80211_STA_FLAG_AUTHORIZED))) err = -EINVAL; break; default: -- GitLab From 71839121a0f35f9968d2e204a76eb22683156fd8 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:31 -0700 Subject: [PATCH 0746/5560] mac80211: Let user space receive and send mesh auth/deauth frames Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/main.c | 4 +++- net/mac80211/rx.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index dc50fc3153e5..e2db3dc23953 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -545,7 +545,9 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { }, [NL80211_IFTYPE_MESH_POINT] = { .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4), + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4), }, }; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fc2ff78582ca..359fc394a3b0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -502,7 +502,8 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_probe_req(hdr->frame_control) || ieee80211_is_probe_resp(hdr->frame_control) || - ieee80211_is_beacon(hdr->frame_control)) + ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_auth(hdr->frame_control)) return RX_CONTINUE; return RX_DROP_MONITOR; -- GitLab From 53e805111b69d55834f4e1ed0a31a97ea0b9e425 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:32 -0700 Subject: [PATCH 0747/5560] mac80211: ignore peer link requests from unauthenticated stations. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index bafe25594e09..5d0dd9217e5f 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -372,6 +372,9 @@ int mesh_plink_open(struct sta_info *sta) __le16 llid; struct ieee80211_sub_if_data *sdata = sta->sdata; + if (!test_sta_flags(sta, WLAN_STA_AUTH)) + return -EPERM; + spin_lock_bh(&sta->lock); get_random_bytes(&llid, 2); sta->llid = llid; @@ -484,6 +487,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m return; } + if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { + mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); + rcu_read_unlock(); + return; + } + if (sta && sta->plink_state == PLINK_BLOCKED) { rcu_read_unlock(); return; -- GitLab From 96b78dff0321d881ef27d858a462c476e0444619 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:33 -0700 Subject: [PATCH 0748/5560] nl80211/mac80211: Perform PLINK_ACTION on new station Modify the NEW_STATION command to accept PLINK_ACTIONS, in case userspace wants to create stations and initiate a peer link right away (for authenticated stations) or create a blocked station (for debugging). Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 2 +- net/wireless/nl80211.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 5d0dd9217e5f..b327e0e6c730 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, if (!sta) return NULL; - sta->flags = WLAN_STA_AUTHORIZED; + sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH; sta->sta.supp_rates[local->hw.conf.channel->band] = rates; rate_control_rate_init(sta); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ce29a0d0e88e..f4cb8efe2e5f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2349,11 +2349,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) params.ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); + if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) + params.plink_action = + nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); + if (parse_station_flags(info, ¶ms)) return -EINVAL; if (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 -EINVAL; -- GitLab From c93b5e717ec47b57abfe0229360bc11e77520984 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:34 -0700 Subject: [PATCH 0749/5560] nl80211: New notification to discover mesh peer candidates. Notify userspace when a beacon/presp is received from a suitable mesh peer candidate for whom no sta information exists. Userspace can then decide to create a sta info for the candidate. If userspace is not ready to authenticate the peer right away, it can create the sta info with the authenticated flag unset and set it later. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/nl80211.h | 12 ++++++++++++ include/net/cfg80211.h | 16 ++++++++++++++++ net/wireless/mesh.c | 14 ++++++++++++++ net/wireless/nl80211.c | 38 ++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 ++++ 5 files changed, 84 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 5ec4ac3a0ef4..b87481866dde 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -410,6 +410,16 @@ * notification. This event is used to indicate that an unprotected * disassociation frame was dropped when MFP is in use. * + * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a + * beacon or probe response from a compatible mesh peer. This is only + * sent while no station information (sta_info) exists for the new peer + * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On + * reception of this notification, userspace may decide to create a new + * station (@NL80211_CMD_NEW_STATION). To stop this notification from + * reoccurring, the userspace authentication daemon may want to create the + * new station with the AUTHENTICATED flag unset and maybe change it later + * depending on the authentication result. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -522,6 +532,8 @@ enum nl80211_commands { NL80211_CMD_UNPROT_DEAUTHENTICATE, NL80211_CMD_UNPROT_DISASSOCIATE, + NL80211_CMD_NEW_PEER_CANDIDATE, + /* 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 e77603bd1630..f40cd30847de 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2488,6 +2488,22 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, */ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); +/** + * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate + * + * @dev: network device + * @macaddr: the MAC address of the new candidate + * @ie: information elements advertised by the peer candidate + * @ie_len: lenght of the information elements buffer + * @gfp: allocation flags + * + * This function notifies cfg80211 that the mesh peer candidate has been + * detected, most likely via a beacon or, less likely, via a probe response. + * cfg80211 then sends a notification to userspace. + */ +void cfg80211_notify_new_peer_candidate(struct net_device *dev, + const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); + /** * DOC: RFkill integration * diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index e0226e8265a3..5c116083eeca 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c @@ -1,5 +1,6 @@ #include #include +#include "nl80211.h" #include "core.h" /* Default values, timeouts in ms */ @@ -110,6 +111,19 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, return err; } +void cfg80211_notify_new_peer_candidate(struct net_device *dev, + const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) + return; + + nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, + macaddr, ie, ie_len, gfp); +} +EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); + static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, struct net_device *dev) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f4cb8efe2e5f..58f501a35022 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5818,6 +5818,44 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *macaddr, const u8* ie, u8 ie_len, + gfp_t gfp) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); + 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, macaddr); + if (ie_len && ie) + NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); + + 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); +} + void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, enum nl80211_key_type key_type, int key_id, diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index dcac5cd6f017..f2af6955a665 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -50,6 +50,10 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, struct net_device *netdev, u16 reason, const u8 *ie, size_t ie_len, bool from_ap); +void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *macaddr, const u8* ie, u8 ie_len, + gfp_t gfp); void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, -- GitLab From 1570ca59279a74db73b8ff840abdfaf64a9ee2ff Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Thu, 7 Apr 2011 15:08:35 -0700 Subject: [PATCH 0750/5560] mac80211: send notification on new peer candidate for our secure mesh Also, advertise support for mesh authentication. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/main.c | 5 +++++ net/mac80211/mesh.c | 4 +--- net/mac80211/mesh.h | 3 ++- net/mac80211/mesh_plink.c | 18 +++++++++++++----- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index e2db3dc23953..0ab2a8df312d 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -762,6 +762,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); #endif + /* if the underlying driver supports mesh, mac80211 will (at least) + * provide routing of mesh authentication frames to userspace */ + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_MESH_POINT)) + local->hw.wiphy->flags |= WIPHY_FLAG_MESH_AUTH; + /* mac80211 supports control port protocol changing */ local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 47a26c0f6993..11207979e2e2 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -590,9 +590,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (elems.mesh_id && elems.mesh_config && mesh_matches_local(&elems, sdata)) { supp_rates = ieee80211_sta_get_rates(local, &elems, band); - - mesh_neighbour_update(mgmt->sa, supp_rates, sdata, - mesh_peer_accepts_plinks(&elems)); + mesh_neighbour_update(mgmt->sa, supp_rates, sdata, &elems); } } diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index b99e230fe31c..10acf1cc8082 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -226,7 +226,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); /* Mesh plinks */ void mesh_neighbour_update(u8 *hw_addr, u32 rates, - struct ieee80211_sub_if_data *sdata, bool add); + struct ieee80211_sub_if_data *sdata, + struct ieee802_11_elems *ie); bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); void mesh_plink_broken(struct sta_info *sta); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index b327e0e6c730..84e5b056af02 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, return 0; } -void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, - bool peer_accepting_plinks) +void mesh_neighbour_update(u8 *hw_addr, u32 rates, + struct ieee80211_sub_if_data *sdata, + struct ieee802_11_elems *elems) { struct ieee80211_local *local = sdata->local; struct sta_info *sta; @@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data sta = sta_info_get(sdata, hw_addr); if (!sta) { rcu_read_unlock(); - - sta = mesh_plink_alloc(sdata, hw_addr, rates); + /* Userspace handles peer allocation when security is enabled + * */ + if (sdata->u.mesh.is_secure) + cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, + elems->ie_start, elems->total_len, + GFP_KERNEL); + else + sta = mesh_plink_alloc(sdata, hw_addr, rates); if (!sta) return; if (sta_info_insert_rcu(sta)) { @@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data sta->last_rx = jiffies; sta->sta.supp_rates[local->hw.conf.channel->band] = rates; - if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && + if (mesh_peer_accepts_plinks(elems) && + sta->plink_state == PLINK_LISTEN && sdata->u.mesh.accepting_plinks && sdata->u.mesh.mshcfg.auto_open_plinks) mesh_plink_open(sta); -- GitLab From 7d75541499319dff375af252345ae1999540b4a9 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Fri, 8 Apr 2011 15:30:34 +0530 Subject: [PATCH 0751/5560] ath9k: Add RSSI information from control and extension chains Export RSSI information from all the control and extension channel chains to debugfs. Also add rx antenna information to debugfs. This will be useful for debugging purpose. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 40 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/debug.h | 7 +++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index a762cadb3ab7..34f191ec8e8c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -845,7 +845,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 1152; + unsigned int len = 0, size = 1400; ssize_t retval = 0; buf = kzalloc(size, GFP_KERNEL); @@ -874,6 +874,34 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, "%18s : %10u\n", "DECRYPT BUSY ERR", sc->debug.stats.rxstats.decrypt_busy_err); + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-CTL0", + sc->debug.stats.rxstats.rs_rssi_ctl0); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-CTL1", + sc->debug.stats.rxstats.rs_rssi_ctl1); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-CTL2", + sc->debug.stats.rxstats.rs_rssi_ctl2); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-EXT0", + sc->debug.stats.rxstats.rs_rssi_ext0); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-EXT1", + sc->debug.stats.rxstats.rs_rssi_ext1); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "RSSI-EXT2", + sc->debug.stats.rxstats.rs_rssi_ext2); + + len += snprintf(buf + len, size - len, + "%18s : %10d\n", "Rx Antenna", + sc->debug.stats.rxstats.rs_antenna); + PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); @@ -948,6 +976,16 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) RX_PHY_ERR_INC(phyerr); } + sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; + sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; + sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; + + sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; + sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; + sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; + + sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; + #undef RX_STAT_INC #undef RX_PHY_ERR_INC } diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 59338de0ce19..1f9f8eada465 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -157,6 +157,13 @@ struct ath_rx_stats { u32 post_delim_crc_err; u32 decrypt_busy_err; u32 phy_err_stats[ATH9K_PHYERR_MAX]; + int8_t rs_rssi_ctl0; + int8_t rs_rssi_ctl1; + int8_t rs_rssi_ctl2; + int8_t rs_rssi_ext0; + int8_t rs_rssi_ext1; + int8_t rs_rssi_ext2; + u8 rs_antenna; }; struct ath_stats { -- GitLab From d0ef824b9a712b866e38212089ade3a7114225a4 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Fri, 8 Apr 2011 15:30:35 +0530 Subject: [PATCH 0752/5560] ath9k: Update gain table for AR9485 Update Tx gain 23 for all tx gain table. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index f91f73e50d00..fbdde29f0ab8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -396,7 +396,7 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -469,7 +469,7 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -635,7 +635,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -728,7 +728,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, @@ -827,7 +827,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, -- GitLab From f60c49b67dd6db2ccb740a6a671414f9dab00c4f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 8 Apr 2011 17:06:25 +0530 Subject: [PATCH 0753/5560] ath9k: Fix kernel panic on module unload The commit "ath9k: configure beacons based on hw opmode" introduced a regression which leads to kernel panic. Failed to stop ani timer during the driver unload while any of the beaconing vif is running. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index eccb0ec87adb..b56f69e7677b 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -320,6 +320,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) if (avp->av_bcbuf != NULL) { struct ath_buf *bf; + avp->is_bslot_active = false; if (avp->av_bslot != -1) { sc->beacon.bslot[avp->av_bslot] = NULL; sc->nbcnvifs--; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93b9fa2cbaf8..a55a8929810b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1375,6 +1375,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, if ((iter_data.naps + iter_data.nadhocs) > 0) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); + } else { + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); } } -- GitLab From ebe27c91af8b7f4810ae906fbd3eeb2d87850026 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 8 Apr 2011 21:24:24 +0530 Subject: [PATCH 0754/5560] {mac|nl}80211: Add station connected time Add station connected time in debugfs. This will be helpful to get a measure of stability of the connection and for debugging stress issues Cc: Senthilkumar Balasubramanian Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- include/linux/nl80211.h | 2 ++ include/net/cfg80211.h | 4 ++++ net/mac80211/cfg.c | 7 ++++++- net/mac80211/debugfs_sta.c | 26 ++++++++++++++++++++++++++ net/mac80211/sta_info.c | 3 +++ net/mac80211/sta_info.h | 2 ++ net/wireless/nl80211.c | 3 +++ 7 files changed, 46 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index b87481866dde..be8df57b789d 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1297,6 +1297,7 @@ enum nl80211_sta_bss_param { * attribute, like NL80211_STA_INFO_TX_BITRATE. * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute * containing info as possible, see &enum nl80211_sta_bss_param + * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */ @@ -1317,6 +1318,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_SIGNAL_AVG, NL80211_STA_INFO_RX_BITRATE, NL80211_STA_INFO_BSS_PARAM, + NL80211_STA_INFO_CONNECTED_TIME, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f40cd30847de..d30eada7c6cd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -423,6 +423,7 @@ struct station_parameters { * @STATION_INFO_SIGNAL_AVG: @signal_avg filled * @STATION_INFO_RX_BITRATE: @rxrate fields are filled * @STATION_INFO_BSS_PARAM: @bss_param filled + * @STATION_INFO_CONNECTED_TIME: @connected_time filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -441,6 +442,7 @@ enum station_info_flags { STATION_INFO_SIGNAL_AVG = 1<<13, STATION_INFO_RX_BITRATE = 1<<14, STATION_INFO_BSS_PARAM = 1<<15, + STATION_INFO_CONNECTED_TIME = 1<<16 }; /** @@ -511,6 +513,7 @@ struct sta_bss_parameters { * Station information filled by driver for get_station() and dump_station. * * @filled: bitflag of flags from &enum station_info_flags + * @connected_time: time(in secs) since a station is last connected * @inactive_time: time since last station activity (tx/rx) in milliseconds * @rx_bytes: bytes received from this station * @tx_bytes: bytes transmitted to this station @@ -533,6 +536,7 @@ struct sta_bss_parameters { */ struct station_info { u32 filled; + u32 connected_time; u32 inactive_time; u32 rx_bytes; u32 tx_bytes; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1c25723eacda..a6d191f2a0fe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -330,6 +330,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = sta->sdata; + struct timespec uptime; sinfo->generation = sdata->local->sta_generation; @@ -343,7 +344,11 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_BITRATE | STATION_INFO_RX_BITRATE | STATION_INFO_RX_DROP_MISC | - STATION_INFO_BSS_PARAM; + STATION_INFO_BSS_PARAM | + STATION_INFO_CONNECTED_TIME; + + do_posix_clock_monotonic_gettime(&uptime); + sinfo->connected_time = uptime.tv_sec - sta->last_connected; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index c04a1396cf8d..c008232731eb 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -92,6 +92,31 @@ static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, } STA_OPS(inactive_ms); + +static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct sta_info *sta = file->private_data; + struct timespec uptime; + struct tm result; + long connected_time_secs; + char buf[100]; + int res; + do_posix_clock_monotonic_gettime(&uptime); + connected_time_secs = uptime.tv_sec - sta->last_connected; + time_to_tm(connected_time_secs, 0, &result); + result.tm_year -= 70; + result.tm_mday -= 1; + res = scnprintf(buf, sizeof(buf), + "years - %d\nmonths - %d\ndays - %d\nclock - %d:%d:%d\n\n", + result.tm_year, result.tm_mon, result.tm_mday, + result.tm_hour, result.tm_min, result.tm_sec); + return simple_read_from_buffer(userbuf, count, ppos, buf, res); +} +STA_OPS(connected_time); + + + static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -324,6 +349,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) DEBUGFS_ADD(flags); DEBUGFS_ADD(num_ps_buf_frames); DEBUGFS_ADD(inactive_ms); + DEBUGFS_ADD(connected_time); DEBUGFS_ADD(last_seq_ctrl); DEBUGFS_ADD(agg_status); DEBUGFS_ADD(dev); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 999f8fbf0b4b..8a9068ac0673 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -228,6 +228,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct sta_info *sta; + struct timespec uptime; int i; sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); @@ -245,6 +246,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->sdata = sdata; sta->last_rx = jiffies; + do_posix_clock_monotonic_gettime(&uptime); + sta->last_connected = uptime.tv_sec; ewma_init(&sta->avg_signal, 1024, 8); if (sta_prepare_rate_control(local, sta, gfp)) { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 43238e99cfb3..984a03db3553 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -226,6 +226,7 @@ enum plink_state { * @rx_bytes: Number of bytes received from this STA * @wep_weak_iv_count: number of weak WEP IVs received from this station * @last_rx: time (in jiffies) when last frame was received from this STA + * @last_connected: time (in seconds) when a station got connected * @num_duplicates: number of duplicate frames received from this STA * @rx_fragments: number of received MPDUs * @rx_dropped: number of dropped MPDUs from this STA @@ -295,6 +296,7 @@ struct sta_info { unsigned long rx_packets, rx_bytes; unsigned long wep_weak_iv_count; unsigned long last_rx; + long last_connected; unsigned long num_duplicates; unsigned long rx_fragments; unsigned long rx_dropped; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 58f501a35022..0efa7fd01150 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2020,6 +2020,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); if (!sinfoattr) goto nla_put_failure; + if (sinfo->filled & STATION_INFO_CONNECTED_TIME) + NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME, + sinfo->connected_time); if (sinfo->filled & STATION_INFO_INACTIVE_TIME) NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME, sinfo->inactive_time); -- GitLab From 1296433bf39a8dea852aafad1f29b775f993bca1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 8 Apr 2011 20:49:16 +0200 Subject: [PATCH 0755/5560] ath9k_hw: remove unnecessary parts of the AR9380 SREV check Older versions have not been sold and the driver does not explicitly check for them anyway, so we can simply ignore the macRev here. Reduces ath9k_hw size on mips by more than 2 KB. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/reg.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 693d543937b5..2fbbe8842bb9 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -858,9 +858,7 @@ #define AR_SREV_9300(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) #define AR_SREV_9300_20_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) + ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300) #define AR_SREV_9485(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) -- GitLab From ba30c4a58ceb10e81dbf6bd80aeb6a4db42db8fe Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Sat, 9 Apr 2011 00:25:37 +0530 Subject: [PATCH 0756/5560] mwl8k: Fix checkpatch.pl and sparse warnings and errors Fix checkpatch errors and warnings comprising of indent errors, spaces and __packed warnings. Also fix 'make C = 2' warnings. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 8913180a7bd3..fb472f4924d0 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -701,7 +701,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) "helper image\n", pci_name(priv->pdev)); return rc; } - msleep(5); + msleep(20); rc = mwl8k_feed_fw_image(priv, fw->data, fw->size); } else { @@ -823,8 +823,8 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) /* * Make sure the packet header is in the DMA header format (4-address * without QoS), the necessary crypto padding between the header and the - * payload has already been provided by mac80211, but it doesn't add tail - * padding when HW crypto is enabled. + * payload has already been provided by mac80211, but it doesn't add + * tail padding when HW crypto is enabled. * * We have the following trailer padding requirements: * - WEP: 4 trailer bytes (ICV) @@ -1487,9 +1487,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) if (timeout) { WARN_ON(priv->pending_tx_pkts); - if (retry) { + if (retry) wiphy_notice(hw->wiphy, "tx rings drained\n"); - } break; } @@ -1649,8 +1648,8 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) /* Rate control is happening in the firmware. * Ensure no tx rate is being reported. */ - info->status.rates[0].idx = -1; - info->status.rates[0].count = 1; + info->status.rates[0].idx = -1; + info->status.rates[0].count = 1; if (MWL8K_TXD_SUCCESS(status)) info->flags |= IEEE80211_TX_STAT_ACK; @@ -1688,7 +1687,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) } /* caller must hold priv->stream_lock when calling the stream functions */ -struct mwl8k_ampdu_stream * +static struct mwl8k_ampdu_stream * mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) { struct mwl8k_ampdu_stream *stream; @@ -2657,7 +2656,7 @@ struct mwl8k_cmd_tx_power { __le16 bw; __le16 sub_ch; __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, struct ieee80211_conf *conf, @@ -3520,13 +3519,13 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, #define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00 #define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01 -enum { +enum ba_stream_action_type { MWL8K_BA_CREATE, MWL8K_BA_UPDATE, MWL8K_BA_DESTROY, MWL8K_BA_FLUSH, MWL8K_BA_CHECK, -} ba_stream_action_type; +}; struct mwl8k_create_ba_stream { @@ -3780,7 +3779,7 @@ struct mwl8k_cmd_update_encryption { __u8 mac_addr[6]; __u8 encr_type; -} __attribute__((packed)); +} __packed; struct mwl8k_cmd_set_key { struct mwl8k_cmd_pkt header; @@ -3800,7 +3799,7 @@ struct mwl8k_cmd_set_key { __le16 tkip_tsc_low; __le32 tkip_tsc_high; __u8 mac_addr[6]; -} __attribute__((packed)); +} __packed; enum { MWL8K_ENCR_ENABLE, @@ -4502,7 +4501,7 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { struct mwl8k_priv *priv = hw->priv; - u32 ap_legacy_rates; + u32 ap_legacy_rates = 0; u8 ap_mcs_rates[16]; int rc; -- GitLab From a065784620a2b78a2bbd00e066c004644d227ea8 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 8 Apr 2011 15:33:12 -0400 Subject: [PATCH 0757/5560] ath5k: improve pcal error handling for ENOMEM case The ath5k driver does kmalloc allocations for pcal info in a loop. But, if one fails it was simply returning -ENOMEM without freeing already allocated memory. This patch corrects that oversight. Reported-by: Eugene A. Shatokhin Signed-off-by: John W. Linville Reviewed-by: Bob Copeland --- drivers/net/wireless/ath/ath5k/eeprom.c | 129 +++++++++++++----------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index b6561f785c6e..fb12027e0346 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; } +static int +ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) +{ + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; + struct ath5k_chan_pcal_info *chinfo; + u8 pier, pdg; + + switch (mode) { + case AR5K_EEPROM_MODE_11A: + if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) + return 0; + chinfo = ee->ee_pwr_cal_a; + break; + case AR5K_EEPROM_MODE_11B: + if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) + return 0; + chinfo = ee->ee_pwr_cal_b; + break; + case AR5K_EEPROM_MODE_11G: + if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) + return 0; + chinfo = ee->ee_pwr_cal_g; + break; + default: + return -EINVAL; + } + + for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { + if (!chinfo[pier].pd_curves) + continue; + + for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { + struct ath5k_pdgain_info *pd = + &chinfo[pier].pd_curves[pdg]; + + if (pd != NULL) { + kfree(pd->pd_step); + kfree(pd->pd_pwr); + } + } + + kfree(chinfo[pier].pd_curves); + } + + return 0; +} + /* Convert RF5111 specific data to generic raw data * used by interpolation code */ static int @@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, GFP_KERNEL); if (!chinfo[pier].pd_curves) - return -ENOMEM; + goto err_out; /* Only one curve for RF5111 * find out which one and place @@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; + goto err_out; /* Fill raw dataset * (convert power to 0.25dB units @@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, } return 0; + +err_out: + ath5k_eeprom_free_pcal_info(ah, mode); + return -ENOMEM; } /* Parse EEPROM data */ @@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, GFP_KERNEL); if (!chinfo[pier].pd_curves) - return -ENOMEM; + goto err_out; /* Fill pd_curves */ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { @@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(pd->pd_points, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; - + goto err_out; /* Fill raw dataset * (all power levels are in 0.25dB units) */ @@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(pd->pd_points, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; + goto err_out; /* Fill raw dataset * (all power levels are in 0.25dB units) */ @@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, } return 0; + +err_out: + ath5k_eeprom_free_pcal_info(ah, mode); + return -ENOMEM; } /* Parse EEPROM data */ @@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, GFP_KERNEL); if (!chinfo[pier].pd_curves) - return -ENOMEM; + goto err_out; /* Fill pd_curves */ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { @@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, sizeof(u8), GFP_KERNEL); if (!pd->pd_step) - return -ENOMEM; + goto err_out; pd->pd_pwr = kcalloc(pd->pd_points, sizeof(s16), GFP_KERNEL); if (!pd->pd_pwr) - return -ENOMEM; + goto err_out; /* Fill raw dataset * convert all pwr levels to @@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, } return 0; + +err_out: + ath5k_eeprom_free_pcal_info(ah, mode); + return -ENOMEM; } /* Parse EEPROM data */ @@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) return 0; } -static int -ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *chinfo; - u8 pier, pdg; - - switch (mode) { - case AR5K_EEPROM_MODE_11A: - if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_a; - break; - case AR5K_EEPROM_MODE_11B: - if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_b; - break; - case AR5K_EEPROM_MODE_11G: - if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_g; - break; - default: - return -EINVAL; - } - - for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { - if (!chinfo[pier].pd_curves) - continue; - - for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { - struct ath5k_pdgain_info *pd = - &chinfo[pier].pd_curves[pdg]; - - if (pd != NULL) { - kfree(pd->pd_step); - kfree(pd->pd_pwr); - } - } - - kfree(chinfo[pier].pd_curves); - } - - return 0; -} - /* Read conformance test limits used for regulatory control */ static int ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) -- GitLab From 6d7b97b23e114c8fbb825e6721164d228c1af3fc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 21:37:14 +0200 Subject: [PATCH 0758/5560] ath5k: fix tx status reporting issues During normal operation, minstrel was showing suspicious EWMA probabilities exceeding 100%. It looks like the tx status reporting in ath5k was not properly clearing the rate index for rates which were never attempted. This is caused by uninitialized stale data in the on-stack tx status information, which is reused when more frames are received. To fix this, rely on ts->ts_final_idx to select the last attempted rate, instead of checking whether ts->ts_rate is set. Additionally, the conversion from the driver rate index back to the mac80211 rate index can be dropped, as the mac80211 tx status will still have the original rate index which was used to set up the descriptor. Additionally, one more inaccuracy was fixed - the final rate attempt count only needs to be increased by one if the transmission attempt was successful. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4d7f21ee111c..753662f98f75 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1580,21 +1580,14 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, info = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); - for (i = 0; i < 4; i++) { + for (i = 0; i <= ts->ts_final_idx; i++) { struct ieee80211_tx_rate *r = &info->status.rates[i]; - if (ts->ts_rate[i]) { - r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); - r->count = ts->ts_retry[i]; - } else { - r->idx = -1; - r->count = 0; - } + r->count = ts->ts_retry[i]; } - /* count the successful attempt as well */ - info->status.rates[ts->ts_final_idx].count++; + info->status.rates[ts->ts_final_idx + 1].idx = -1; if (unlikely(ts->ts_status)) { sc->stats.ack_fail++; @@ -1609,6 +1602,9 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, } else { info->flags |= IEEE80211_TX_STAT_ACK; info->status.ack_signal = ts->ts_rssi; + + /* count the successful attempt as well */ + info->status.rates[ts->ts_final_idx].count++; } /* -- GitLab From a27049e2c926bcf68360532a5ae66e408296ae85 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 23:10:19 +0200 Subject: [PATCH 0759/5560] ath5k: fix short preamble rate duration value Subtract the difference in preamble duration (in usec) from the value returned by ieee80211_generic_frame_duration. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/pcu.c | 31 ++++++++++---------------- drivers/net/wireless/ath/ath5k/qcu.c | 2 +- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 8a06dbd39629..996d8afafdb7 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1233,7 +1233,7 @@ 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); + int len, struct ieee80211_rate *rate, bool shortpre); 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); diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index a702817daf72..e342e470fb05 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -75,7 +75,7 @@ static const unsigned int ack_rates_high[] = * bwmodes. */ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, - int len, struct ieee80211_rate *rate) + int len, struct ieee80211_rate *rate, bool shortpre) { struct ath5k_softc *sc = ah->ah_sc; int sifs, preamble, plcp_bits, sym_time; @@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, /* Fallback */ if (!ah->ah_bwmode) { - dur = ieee80211_generic_frame_duration(sc->hw, - NULL, len, rate); - return le16_to_cpu(dur); + __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw, + NULL, len, rate); + + /* subtract difference between long and short preamble */ + dur = le16_to_cpu(raw_dur); + if (shortpre) + dur -= 96; + + return dur; } bitrate = rate->bitrate; @@ -263,27 +269,14 @@ 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 = ath5k_hw_get_frame_duration(ah, 10, rate); + tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); 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 - */ + tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); ath5k_hw_reg_write(ah, tx_time, reg + (AR5K_SET_SHORT_PREAMBLE << 2)); } diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 3343fb9e4940..93abcfacd990 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) else rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; - ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); + ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); /* ack_tx_time includes an SIFS already */ eifs = ack_tx_time + sifs + 2 * slot_time; -- GitLab From 488a50176c169eb36544b4f970c8bba68ede30a1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 23:10:20 +0200 Subject: [PATCH 0760/5560] ath5k: fix SIFS time handling ath5k uses 8 usec as a sifs time, extracted from the initvals, whereas the standard requires a sifs time of 10. The difference originates from the fact that the SIFS register has an offset of 2 usec. Fix the SIFS time definition to use the standard value of 10 usec and subtract 2 usecs when writing the SIFS register. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +-- drivers/net/wireless/ath/ath5k/qcu.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 996d8afafdb7..a49aeac378cd 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -224,8 +224,7 @@ /* 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_BG 10 #define AR5K_INIT_SIFS_DEFAULT_A 16 #define AR5K_INIT_SIFS_HALF_RATE 32 #define AR5K_INIT_SIFS_QUARTER_RATE 64 diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 93abcfacd990..b18c5021aac3 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) return -EINVAL; sifs = ath5k_hw_get_default_sifs(ah); - sifs_clock = ath5k_hw_htoclock(ah, sifs); + sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); /* EIFS * Txtime of ack at lowest rate + SIFS + DIFS -- GitLab From b1ad1b6febb7772583c98d9a879fbbdb82a726a7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 9 Apr 2011 23:10:21 +0200 Subject: [PATCH 0761/5560] ath5k: fix slot time handling Set the slot time based on the mac80211 short slot vs long slot setting instead of just forcing long slot for all CCK-enabled channels. This slightly improves 802.11g mode performance in in my tests. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 + drivers/net/wireless/ath/ath5k/mac80211-ops.c | 9 +++++++++ drivers/net/wireless/ath/ath5k/pcu.c | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index a49aeac378cd..4bb381cae08d 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1057,6 +1057,7 @@ struct ath5k_hw { u8 ah_coverage_class; bool ah_ack_bitrate_high; u8 ah_bwmode; + bool ah_short_slot; /* Antenna Control */ u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 9be29b728b1c..807bd6440169 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_BEACON_INT) sc->bintval = bss_conf->beacon_int; + if (changes & BSS_CHANGED_ERP_SLOT) { + int slot_time; + + ah->ah_short_slot = bss_conf->use_short_slot; + slot_time = ath5k_hw_get_default_slottime(ah) + + 3 * ah->ah_coverage_class; + ath5k_hw_set_ifs_intervals(ah, slot_time); + } + if (changes & BSS_CHANGED_ASSOC) { avf->assoc = bss_conf->assoc; if (bss_conf->assoc) diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e342e470fb05..71b60b7c617e 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -151,9 +151,9 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) 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_DEFAULT; + if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) slot_time = AR5K_INIT_SLOT_TIME_B; break; } -- GitLab From c5e0a88aa2e0f42cdb4c79c977c52f6bc38ec160 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:13 +0200 Subject: [PATCH 0762/5560] ath5k: optimize tx descriptor setup Use local variables to reduce the number of load/store operations on uncached memory. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 38 ++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 16b44ff7dd3e..0a8a9efaf8b4 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -184,6 +184,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; + u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; @@ -209,7 +210,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, tx_power = AR5K_TUNE_MAX_TXPOWER; /* Clear descriptor */ - memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); + memset(&desc->ud.ds_tx5212.tx_stat, 0, + sizeof(desc->ud.ds_tx5212.tx_stat)); /* Setup control descriptor */ @@ -221,7 +223,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) return -EINVAL; - tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; + txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; /* Verify and set buffer length */ @@ -232,21 +234,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) return -EINVAL; - tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; + txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; - tx_ctl->tx_control_0 |= - AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | - AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); - tx_ctl->tx_control_1 |= AR5K_REG_SM(type, - AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); - tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); - tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; + txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | + AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); + txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); + txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); + txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \ - tx_ctl->tx_control_##_c |= \ - AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ + txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ } _TX_FLAGS(0, CLRDMASK); @@ -262,8 +260,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, * WEP crap */ if (key_index != AR5K_TXKEYIX_INVALID) { - tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, + txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; + txctl1 |= AR5K_REG_SM(key_index, AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); } @@ -274,12 +272,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if ((flags & AR5K_TXDESC_RTSENA) && (flags & AR5K_TXDESC_CTSENA)) return -EINVAL; - tx_ctl->tx_control_2 |= rtscts_duration & - AR5K_4W_TX_DESC_CTL2_RTS_DURATION; - tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, + txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; + txctl3 |= AR5K_REG_SM(rtscts_rate, AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); } + tx_ctl->tx_control_0 = txctl0; + tx_ctl->tx_control_1 = txctl1; + tx_ctl->tx_control_2 = txctl2; + tx_ctl->tx_control_3 = txctl3; + return 0; } -- GitLab From fe12081cb664cd5d412dc56de0585a80484b1331 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:14 +0200 Subject: [PATCH 0763/5560] ath5k: remove ts_rate from ath5k_tx_status It is no longer necessary for preparing mac80211 tx status Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 1 - drivers/net/wireless/ath/ath5k/desc.c | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 4bb381cae08d..aa588a0521c1 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -452,7 +452,6 @@ struct ath5k_tx_status { u16 ts_seqnum; u16 ts_tstamp; u8 ts_status; - u8 ts_rate[4]; u8 ts_retry[4]; u8 ts_final_idx; s8 ts_rssi; diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 0a8a9efaf8b4..990a3b421443 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -375,8 +375,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = 1; ts->ts_status = 0; - ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, - AR5K_2W_TX_DESC_CTL0_XMIT_RATE); ts->ts_retry[0] = ts->ts_longretry; ts->ts_final_idx = 0; @@ -439,32 +437,21 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; switch (ts->ts_final_idx) { case 3: - ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); - ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); ts->ts_longretry += ts->ts_retry[2]; /* fall through */ case 2: - ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); - ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[1]; /* fall through */ case 1: - ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, - AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); - ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[0]; /* fall through */ case 0: - ts->ts_rate[0] = tx_ctl->tx_control_3 & - AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; break; } -- GitLab From b161b89fb97b30233526d31c5f94397ed94ffea6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:15 +0200 Subject: [PATCH 0764/5560] ath5k: optimize tx status processing Use ACCESS_ONCE to reduce the number of variable reloads on uncached memory Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 37 +++++++++++++++------------ 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 990a3b421443..3758b967029a 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -401,32 +401,38 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; + u32 txstat0, txstat1, txctl2; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_status = &desc->ud.ds_tx5212.tx_stat; + txstat1 = ACCESS_ONCE(tx_status->tx_status_1); + /* No frame has been send or error */ - if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) + if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) return -EINPROGRESS; + txstat0 = ACCESS_ONCE(tx_status->tx_status_0); + txctl2 = ACCESS_ONCE(tx_ctl->tx_control_2); + /* * Get descriptor status */ - ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_tstamp = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_shortretry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_longretry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_seqnum = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_SEQ_NUM); - ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_rssi = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); - ts->ts_antenna = (tx_status->tx_status_1 & + ts->ts_antenna = (txstat1 & AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; ts->ts_status = 0; - ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, + ts->ts_final_idx = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); /* The longretry counter has the number of un-acked retries @@ -437,17 +443,17 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; switch (ts->ts_final_idx) { case 3: - ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, + ts->ts_retry[2] = AR5K_REG_MS(txctl2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); ts->ts_longretry += ts->ts_retry[2]; /* fall through */ case 2: - ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, + ts->ts_retry[1] = AR5K_REG_MS(txctl2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[1]; /* fall through */ case 1: - ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, + ts->ts_retry[0] = AR5K_REG_MS(txctl2, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); ts->ts_longretry += ts->ts_retry[0]; /* fall through */ @@ -456,15 +462,14 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, } /* TX error */ - if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) + if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { + if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) ts->ts_status |= AR5K_TXERR_XRETRY; - if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) + if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) ts->ts_status |= AR5K_TXERR_FIFO; - if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) + if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) ts->ts_status |= AR5K_TXERR_FILT; } -- GitLab From b2fd97d0190a400b49a2f910109a4a492bfea319 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:16 +0200 Subject: [PATCH 0765/5560] ath5k: optimize rx status processing Use ACCESS_ONCE to reduce the number of redundant loads on uncached memory Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 41 ++++++++++++--------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 3758b967029a..e366d30ef039 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -603,37 +603,37 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, struct ath5k_rx_status *rs) { struct ath5k_hw_rx_status *rx_status; + u32 rxstat0, rxstat1; rx_status = &desc->ud.ds_rx.rx_stat; + rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); /* No frame received / not ready */ - if (unlikely(!(rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_DONE))) + if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) return -EINPROGRESS; memset(rs, 0, sizeof(struct ath5k_rx_status)); + rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); /* * Frame receive status */ - rs->rs_datalen = rx_status->rx_status_0 & - AR5K_5212_RX_DESC_STATUS0_DATA_LEN; - rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, + rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; + rs->rs_rssi = AR5K_REG_MS(rxstat0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); - rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, + rs->rs_rate = AR5K_REG_MS(rxstat0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); - rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, + rs->rs_antenna = AR5K_REG_MS(rxstat0, AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); - rs->rs_more = !!(rx_status->rx_status_0 & - AR5K_5212_RX_DESC_STATUS0_MORE); - rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); + rs->rs_tstamp = AR5K_REG_MS(rxstat1, AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); /* * Key table status */ - if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) - rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) + rs->rs_keyix = AR5K_REG_MS(rxstat1, AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); else rs->rs_keyix = AR5K_RXKEYIX_INVALID; @@ -641,27 +641,22 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, /* * Receive/descriptor errors */ - if (!(rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) + if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) rs->rs_status |= AR5K_RXERR_CRC; - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_phyerr = AR5K_REG_MS(rxstat1, AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); if (!ah->ah_capabilities.cap_has_phyerr_counters) ath5k_ani_phy_error_report(ah, rs->rs_phyerr); } - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) rs->rs_status |= AR5K_RXERR_DECRYPT; - if (rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) + if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) rs->rs_status |= AR5K_RXERR_MIC; } return 0; -- GitLab From ed8950857f728303a1463ac9267e72c278738bf6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:17 +0200 Subject: [PATCH 0766/5560] ath5k: remove ts_retry from ath5k_tx_status Reusing the configured retry counts from the skb cb is more efficient than reloading the data from uncached memory. Replace ts_longretry (unused) with ts_final_retry which contains the retry count for the final rate only Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 3 +-- drivers/net/wireless/ath/ath5k/base.c | 11 +++++++-- drivers/net/wireless/ath/ath5k/desc.c | 34 +++----------------------- 3 files changed, 13 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index aa588a0521c1..fcaf4ed84ca5 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -452,11 +452,10 @@ struct ath5k_tx_status { u16 ts_seqnum; u16 ts_tstamp; u8 ts_status; - u8 ts_retry[4]; u8 ts_final_idx; + u8 ts_final_retry; s8 ts_rssi; u8 ts_shortretry; - u8 ts_longretry; u8 ts_virtcol; u8 ts_antenna; }; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 753662f98f75..1a561b89221e 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1573,20 +1573,27 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, struct ath5k_txq *txq, struct ath5k_tx_status *ts) { struct ieee80211_tx_info *info; + u8 tries[3]; int i; sc->stats.tx_all_count++; sc->stats.tx_bytes_count += skb->len; info = IEEE80211_SKB_CB(skb); + tries[0] = info->status.rates[0].count; + tries[1] = info->status.rates[1].count; + tries[2] = info->status.rates[2].count; + ieee80211_tx_info_clear_status(info); - for (i = 0; i <= ts->ts_final_idx; i++) { + + for (i = 0; i < ts->ts_final_idx; i++) { struct ieee80211_tx_rate *r = &info->status.rates[i]; - r->count = ts->ts_retry[i]; + r->count = tries[i]; } + info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; info->status.rates[ts->ts_final_idx + 1].idx = -1; if (unlikely(ts->ts_status)) { diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index e366d30ef039..0391813befd1 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -366,7 +366,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, + ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); /*TODO: ts->ts_virtcol + test*/ ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, @@ -375,7 +375,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = 1; ts->ts_status = 0; - ts->ts_retry[0] = ts->ts_longretry; ts->ts_final_idx = 0; if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { @@ -401,7 +400,7 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; - u32 txstat0, txstat1, txctl2; + u32 txstat0, txstat1; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_status = &desc->ud.ds_tx5212.tx_stat; @@ -413,7 +412,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, return -EINPROGRESS; txstat0 = ACCESS_ONCE(tx_status->tx_status_0); - txctl2 = ACCESS_ONCE(tx_ctl->tx_control_2); /* * Get descriptor status @@ -422,7 +420,7 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); ts->ts_shortretry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_longretry = AR5K_REG_MS(txstat0, + ts->ts_final_retry = AR5K_REG_MS(txstat0, AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); ts->ts_seqnum = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_SEQ_NUM); @@ -435,32 +433,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_final_idx = AR5K_REG_MS(txstat1, AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); - /* The longretry counter has the number of un-acked retries - * for the final rate. To get the total number of retries - * we have to add the retry counters for the other rates - * as well - */ - ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; - switch (ts->ts_final_idx) { - case 3: - ts->ts_retry[2] = AR5K_REG_MS(txctl2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); - ts->ts_longretry += ts->ts_retry[2]; - /* fall through */ - case 2: - ts->ts_retry[1] = AR5K_REG_MS(txctl2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); - ts->ts_longretry += ts->ts_retry[1]; - /* fall through */ - case 1: - ts->ts_retry[0] = AR5K_REG_MS(txctl2, - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); - ts->ts_longretry += ts->ts_retry[0]; - /* fall through */ - case 0: - break; - } - /* TX error */ if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) -- GitLab From 5b7916ad8c29da9f30fbf03a8b61862acdba00ce Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:18 +0200 Subject: [PATCH 0767/5560] ath5k: clean up debugfs code The pointers to the debugfs entries do not need to be saved, because they will be recursively removed when the wiphy is unregistered. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 1 - drivers/net/wireless/ath/ath5k/debug.c | 65 ++++++++------------------ drivers/net/wireless/ath/ath5k/debug.h | 17 ------- 3 files changed, 19 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1a561b89221e..a799d04e0c8c 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2901,7 +2901,6 @@ ath5k_deinit_softc(struct ath5k_softc *sc) * 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); diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 0230f30e9e9a..0bf7313b8a17 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -888,65 +888,38 @@ static const struct file_operations fops_queue = { void ath5k_debug_init_device(struct ath5k_softc *sc) { - sc->debug.level = ath5k_debug; + struct dentry *phydir; - sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", - sc->hw->wiphy->debugfsdir); + sc->debug.level = ath5k_debug; - sc->debug.debugfs_debug = debugfs_create_file("debug", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_debug); + phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir); + if (!phydir) + return; - sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_registers); + debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc, + &fops_debug); - sc->debug.debugfs_beacon = debugfs_create_file("beacon", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_beacon); + debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers); - sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, - sc->debug.debugfs_phydir, sc, &fops_reset); + debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc, + &fops_beacon); - sc->debug.debugfs_antenna = debugfs_create_file("antenna", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_antenna); + debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset); - sc->debug.debugfs_misc = debugfs_create_file("misc", - S_IRUSR, - sc->debug.debugfs_phydir, sc, &fops_misc); + debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc, + &fops_antenna); - sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, - &fops_frameerrors); + debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc); - sc->debug.debugfs_ani = debugfs_create_file("ani", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, - &fops_ani); + debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc, + &fops_frameerrors); - sc->debug.debugfs_queue = debugfs_create_file("queue", - S_IWUSR | S_IRUSR, - sc->debug.debugfs_phydir, sc, - &fops_queue); -} + debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani); -void -ath5k_debug_finish_device(struct ath5k_softc *sc) -{ - debugfs_remove(sc->debug.debugfs_debug); - debugfs_remove(sc->debug.debugfs_registers); - debugfs_remove(sc->debug.debugfs_beacon); - debugfs_remove(sc->debug.debugfs_reset); - debugfs_remove(sc->debug.debugfs_antenna); - debugfs_remove(sc->debug.debugfs_misc); - debugfs_remove(sc->debug.debugfs_frameerrors); - debugfs_remove(sc->debug.debugfs_ani); - debugfs_remove(sc->debug.debugfs_queue); - debugfs_remove(sc->debug.debugfs_phydir); + debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc, + &fops_queue); } - /* functions used in other places */ void diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index b0355aef68d3..193dd2d4ea3c 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -68,17 +68,6 @@ struct ath5k_buf; struct ath5k_dbg_info { unsigned int level; /* debug level */ - /* debugfs entries */ - struct dentry *debugfs_phydir; - struct dentry *debugfs_debug; - struct dentry *debugfs_registers; - struct dentry *debugfs_beacon; - struct dentry *debugfs_reset; - struct dentry *debugfs_antenna; - struct dentry *debugfs_misc; - struct dentry *debugfs_frameerrors; - struct dentry *debugfs_ani; - struct dentry *debugfs_queue; }; /** @@ -140,9 +129,6 @@ enum ath5k_debug_level { void ath5k_debug_init_device(struct ath5k_softc *sc); -void -ath5k_debug_finish_device(struct ath5k_softc *sc); - void ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); @@ -166,9 +152,6 @@ ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) static inline void ath5k_debug_init_device(struct ath5k_softc *sc) {} -static inline void -ath5k_debug_finish_device(struct ath5k_softc *sc) {} - static inline void ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} -- GitLab From c266c71a9cbdccb40fb6f4c05d4ddaa6226e5eba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 10 Apr 2011 18:32:19 +0200 Subject: [PATCH 0768/5560] ath5k: reduce interrupt load caused by rx/tx interrupts While the rx/tx tasklet is pending, new unnecessary interrupts may arrive. Decrease the load by temporarily disabling the interrupts until the tasklet has completed. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 13 ++++++++ drivers/net/wireless/ath/ath5k/base.c | 45 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath5k/base.h | 4 +++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index fcaf4ed84ca5..e303db7ee6f6 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -872,6 +872,19 @@ enum ath5k_int { AR5K_INT_QTRIG = 0x40000000, /* Non common */ AR5K_INT_GLOBAL = 0x80000000, + AR5K_INT_TX_ALL = AR5K_INT_TXOK + | AR5K_INT_TXDESC + | AR5K_INT_TXERR + | AR5K_INT_TXEOL + | AR5K_INT_TXURN, + + AR5K_INT_RX_ALL = AR5K_INT_RXOK + | AR5K_INT_RXDESC + | AR5K_INT_RXERR + | AR5K_INT_RXNOFRM + | AR5K_INT_RXEOL + | AR5K_INT_RXORN, + AR5K_INT_COMMON = AR5K_INT_RXOK | AR5K_INT_RXDESC | AR5K_INT_RXERR diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a799d04e0c8c..c7da00454397 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1443,6 +1443,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) return true; } +static void +ath5k_set_current_imask(struct ath5k_softc *sc) +{ + enum ath5k_int imask = sc->imask; + unsigned long flags; + + spin_lock_irqsave(&sc->irqlock, flags); + if (sc->rx_pending) + imask &= ~AR5K_INT_RX_ALL; + if (sc->tx_pending) + imask &= ~AR5K_INT_TX_ALL; + ath5k_hw_set_imr(sc->ah, imask); + spin_unlock_irqrestore(&sc->irqlock, flags); +} + static void ath5k_tasklet_rx(unsigned long data) { @@ -1506,6 +1521,8 @@ ath5k_tasklet_rx(unsigned long data) } while (ath5k_rxbuf_setup(sc, bf) == 0); unlock: spin_unlock(&sc->rxbuflock); + sc->rx_pending = false; + ath5k_set_current_imask(sc); } @@ -1693,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data) for (i=0; i < AR5K_NUM_TX_QUEUES; i++) if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) ath5k_tx_processq(sc, &sc->txqs[i]); + + sc->tx_pending = false; + ath5k_set_current_imask(sc); } @@ -2122,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ } +static void +ath5k_schedule_rx(struct ath5k_softc *sc) +{ + sc->rx_pending = true; + tasklet_schedule(&sc->rxtq); +} + +static void +ath5k_schedule_tx(struct ath5k_softc *sc) +{ + sc->tx_pending = true; + tasklet_schedule(&sc->txtq); +} + irqreturn_t ath5k_intr(int irq, void *dev_id) { @@ -2164,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id) ieee80211_queue_work(sc->hw, &sc->reset_work); } else - tasklet_schedule(&sc->rxtq); + ath5k_schedule_rx(sc); } else { if (status & AR5K_INT_SWBA) { tasklet_hi_schedule(&sc->beacontq); @@ -2182,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id) ath5k_hw_update_tx_triglevel(ah, true); } if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) - tasklet_schedule(&sc->rxtq); + ath5k_schedule_rx(sc); if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | AR5K_INT_TXERR | AR5K_INT_TXEOL)) - tasklet_schedule(&sc->txtq); + ath5k_schedule_tx(sc); if (status & AR5K_INT_BMISS) { /* TODO */ } @@ -2204,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id) } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); + if (sc->rx_pending || sc->tx_pending) + ath5k_set_current_imask(sc); + if (unlikely(!counter)) ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); @@ -2575,6 +2612,8 @@ ath5k_init_hw(struct ath5k_softc *sc) static void stop_tasklets(struct ath5k_softc *sc) { + sc->rx_pending = false; + sc->tx_pending = false; tasklet_kill(&sc->rxtq); tasklet_kill(&sc->txtq); tasklet_kill(&sc->calib); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 978f1f4ac2f3..4c4e36064a3b 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -207,6 +207,10 @@ struct ath5k_softc { enum ath5k_int imask; /* interrupt mask copy */ + spinlock_t irqlock; + bool rx_pending; /* rx tasklet pending */ + bool tx_pending; /* tx tasklet pending */ + u8 lladdr[ETH_ALEN]; u8 bssidmask[ETH_ALEN]; -- GitLab From 0f8e94d2ae4f7966d09c8105ccabb3b3d8238a4d Mon Sep 17 00:00:00 2001 From: roel Date: Sun, 10 Apr 2011 21:09:50 +0200 Subject: [PATCH 0769/5560] ath9k_hw: index out of bounds Check whether index is within bounds before testing the element Both spurChans arrays in modalHeader5G and modalHeader2G have 5 elements, AR_EEPROM_MODAL_SPURS is defined 5. So unless a break occurs, in the last iteration (i=5) we tried to access spurChansPtr[5] before testing whether i was within bounds. Fix this. Signed-off-by: Roel Kluin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eb250d6b8038..93398de0bf67 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -401,7 +401,7 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, ar9003_hw_spur_ofdm_clear(ah); - for (i = 0; spurChansPtr[i] && i < 5; i++) { + for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) { freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; if (abs(freq_offset) < range) { ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); -- GitLab From f0bce44f5f2eb37dba58aa992d0c58da92ded201 Mon Sep 17 00:00:00 2001 From: roel Date: Sun, 10 Apr 2011 21:09:55 +0200 Subject: [PATCH 0770/5560] ath9k: index out of bounds Check whether index is within bounds before testing the element Signed-off-by: Roel Kluin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index a3241cd089b1..2a40532126f3 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1092,8 +1092,7 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, if (!(rate->flags & IEEE80211_TX_RC_MCS)) return rate->idx; - while (rate->idx > mcs_rix_off[i] && - i < ARRAY_SIZE(mcs_rix_off)) { + while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) { rix++; i++; } -- GitLab From 228bdfca9a09c1263c24509b4bc23a67be168e1a Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Sun, 10 Apr 2011 18:30:23 -0500 Subject: [PATCH 0771/5560] rtlwifi: rtl8192ce: Fix LED initialization Driver rtl8192ce does not initialize the LED correctly. Signed-off-by: Chaoming Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 12 +++++++----- drivers/net/wireless/rtlwifi/pci.c | 3 ++- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 14 +++++++++++--- drivers/net/wireless/rtlwifi/rtl8192ce/led.h | 1 - drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 1 - 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index dd5318ed7872..9477785f1168 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -251,14 +251,16 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) bool blocked; u8 valid = 0; - radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); + /*set init state to on */ + rtlpriv->rfkill.rfkill_state = 1; + wiphy_rfkill_set_hw_state(hw->wiphy, 0); - /*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"); + radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid); if (valid) { + printk(KERN_INFO "rtlwifi: 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; diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index efded435d596..59a150ce3064 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1785,7 +1785,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) rtl_pci_deinit(hw); rtl_deinit_core(hw); - rtlpriv->cfg->ops->deinit_sw_leds(hw); + if (rtlpriv->cfg->ops->deinit_sw_leds) + rtlpriv->cfg->ops->deinit_sw_leds(hw); _rtl_pci_io_handler_release(hw); rtlpriv->cfg->ops->deinit_sw_vars(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 7b1da8d7508f..d21b934b5c33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -32,6 +32,14 @@ #include "reg.h" #include "led.h" +static void _rtl92ce_init_led(struct ieee80211_hw *hw, + struct rtl_led *pled, enum rtl_led_pin ledpin) +{ + pled->hw = hw; + pled->ledpin = ledpin; + pled->ledon = false; +} + void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) { u8 ledcfg; @@ -97,10 +105,10 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) { -} + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); -void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) -{ + _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); + _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); } void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 10da3018f4b7..94332b3af5b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -31,7 +31,6 @@ #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); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b1cc4d44f534..f4e2f3dcccae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -131,7 +131,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .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 = rtl92ce_phy_query_rf_reg, -- GitLab From 3dfd7f606645279c788f48cfdfdf9565ec72c4f0 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 11 Apr 2011 16:39:40 +0530 Subject: [PATCH 0772/5560] ath9k: Implement integer mode for AR9485 This fixes random disconnect. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 15 +++++-- drivers/net/wireless/ath/ath9k/hw.c | 45 +++++++++++++-------- drivers/net/wireless/ath/ath9k/phy.h | 1 - drivers/net/wireless/ath/ath9k/reg.h | 31 +++++++++++--- 4 files changed, 67 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 93398de0bf67..1bc33f51e466 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -75,9 +75,18 @@ 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 */ - if (AR_SREV_9485(ah)) - channelSel = CHANSEL_2G_9485(freq); - else + if (AR_SREV_9485(ah)) { + u32 chan_frac; + + /* + * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0 + * ndiv = ((chan_mhz * 4) / 3) / freq_ref; + * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 + */ + channelSel = (freq * 4) / 120; + chan_frac = (((freq * 4) % 120) * 0x20000) / 120; + channelSel = (channelSel << 17) | chan_frac; + } else channelSel = CHANSEL_2G(freq); /* Set to 2G mode */ bMode = 1; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1b5bd13b0a6c..3a8c41c782e9 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -676,42 +676,55 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); -#define DPLL2_KD_VAL 0x3D -#define DPLL2_KI_VAL 0x06 -#define DPLL3_PHASE_SHIFT_VAL 0x1 - +#define DPLL3_PHASE_SHIFT_VAL 0x1 static void ath9k_hw_init_pll(struct ath_hw *ah, struct ath9k_channel *chan) { u32 pll; if (AR_SREV_9485(ah)) { - REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); - REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); - - REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, - AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); - REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); - udelay(1000); + /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_BB_DPLL2_PLL_PWD, 0x1); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_DPLL2_KD, 0x40); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_DPLL2_KI, 0x4); - REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, + AR_CH0_BB_DPLL1_REFDIV, 0x5); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, + AR_CH0_BB_DPLL1_NINI, 0x58); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, + AR_CH0_BB_DPLL1_NFRAC, 0x0); REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, - AR_CH0_DPLL2_KD, DPLL2_KD_VAL); + AR_CH0_BB_DPLL2_OUTDIV, 0x1); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1); REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, - AR_CH0_DPLL2_KI, DPLL2_KI_VAL); + AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1); + /* program BB PLL phase_shift to 0x6 */ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, - AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); - REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); + AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6); + + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_BB_DPLL2_PLL_PWD, 0x0); udelay(1000); + + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, + AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); } pll = ath9k_hw_compute_pll_control(ah, chan); REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); + if (AR_SREV_9485(ah)) + udelay(1000); + /* Switch the core clock for ar9271 to 117Mhz */ if (AR_SREV_9271(ah)) { udelay(500); diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index f50e2c29f71e..8e5fe9d7f174 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -19,7 +19,6 @@ #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 diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 2fbbe8842bb9..6acbf0e2240b 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1086,14 +1086,35 @@ enum { #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 #define AR_ENT_OTP_MPSD 0x00800000 -#define AR_CH0_BB_DPLL2 0x16184 + +#define AR_CH0_BB_DPLL1 0x16180 +#define AR_CH0_BB_DPLL1_REFDIV 0xF8000000 +#define AR_CH0_BB_DPLL1_REFDIV_S 27 +#define AR_CH0_BB_DPLL1_NINI 0x07FC0000 +#define AR_CH0_BB_DPLL1_NINI_S 18 +#define AR_CH0_BB_DPLL1_NFRAC 0x0003FFFF +#define AR_CH0_BB_DPLL1_NFRAC_S 0 + +#define AR_CH0_BB_DPLL2 0x16184 +#define AR_CH0_BB_DPLL2_LOCAL_PLL 0x40000000 +#define AR_CH0_BB_DPLL2_LOCAL_PLL_S 30 +#define AR_CH0_DPLL2_KI 0x3C000000 +#define AR_CH0_DPLL2_KI_S 26 +#define AR_CH0_DPLL2_KD 0x03F80000 +#define AR_CH0_DPLL2_KD_S 19 +#define AR_CH0_BB_DPLL2_EN_NEGTRIG 0x00040000 +#define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18 +#define AR_CH0_BB_DPLL2_PLL_PWD 0x00010000 +#define AR_CH0_BB_DPLL2_PLL_PWD_S 16 +#define AR_CH0_BB_DPLL2_OUTDIV 0x0000E000 +#define AR_CH0_BB_DPLL2_OUTDIV_S 13 + #define AR_CH0_BB_DPLL3 0x16188 +#define AR_CH0_BB_DPLL3_PHASE_SHIFT 0x3F800000 +#define AR_CH0_BB_DPLL3_PHASE_SHIFT_S 23 + #define AR_CH0_DDR_DPLL2 0x16244 #define AR_CH0_DDR_DPLL3 0x16248 -#define AR_CH0_DPLL2_KD 0x03F80000 -#define AR_CH0_DPLL2_KD_S 19 -#define AR_CH0_DPLL2_KI 0x3C000000 -#define AR_CH0_DPLL2_KI_S 26 #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 #define AR_PHY_CCA_NOM_VAL_2GHZ -118 -- GitLab From 2d05a0c2b4ac614cb5e0eba75d39a37205d129e8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Apr 2011 20:22:28 +0530 Subject: [PATCH 0773/5560] ath9k_hw: Remove unused code in AR9287 eeprom Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 25 +------------------- 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 2f0712ea49a6..13579752a300 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -858,35 +858,12 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, { struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct modal_eep_ar9287_header *pModal = &eep->modalHeader; - u16 antWrites[AR9287_ANT_16S]; u32 regChainOffset, regval; u8 txRxAttenLocal; - int i, j, offset_num; + int i; pModal = &eep->modalHeader; - antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF); - antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF); - antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF); - antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF); - antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF); - antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF); - antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF); - antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF); - - offset_num = 8; - - for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) { - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3); - antWrites[j++] = 0; - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3); - antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3); - antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); - } - REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); for (i = 0; i < AR9287_MAX_CHAINS; i++) { -- GitLab From 5fb32faf821586312dc0b51a64bfa17ad0633daf Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Apr 2011 20:22:29 +0530 Subject: [PATCH 0774/5560] ath9k_hw: update Ar9003 intervals to fix carrier leak Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- .../wireless/ath/ath9k/ar9003_2p2_initvals.h | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 9ecca93392e8..7f30bc686438 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -34,10 +34,10 @@ 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, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -119,14 +119,14 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { {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, 0x00033800, 0x00033800, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, @@ -835,10 +835,10 @@ static const u32 ar9300_2p2_baseband_core[][2] = { static const u32 ar9300Modes_high_power_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}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -920,14 +920,14 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, @@ -941,10 +941,10 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -1026,14 +1026,14 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, @@ -1307,10 +1307,10 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { static const u32 ar9300Modes_low_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}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -1392,14 +1392,14 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { {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}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, - {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -- GitLab From 901c1113da1efc98881233a8a67f98286a0b766a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 11 Apr 2011 20:22:30 +0530 Subject: [PATCH 0775/5560] ath9k_hw: update AR9003 low_ob_db_tx_gain to improve spur performance Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- .../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 7f30bc686438..f915a3dbfcad 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -1307,9 +1307,9 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = { static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -1329,21 +1329,21 @@ static const u32 ar9300Modes_low_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}, @@ -1361,44 +1361,44 @@ static const u32 ar9300Modes_low_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, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {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, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, -- GitLab From b3ba44c6d1633692b45910ee77064e635e2c3143 Mon Sep 17 00:00:00 2001 From: Mark Davis Date: Tue, 12 Apr 2011 00:19:10 -0400 Subject: [PATCH 0776/5560] rt2800usb: Add seven new USB IDs Adds USB IDs for seven previously missing devices. Additionally, all instances of 'Conceptronic' have been replaced by the OEM name. Devices added are.. 0411:01a2 - Buffalo WLI-UC-GNM, RT3070V 0586:341e - ZyXEL NWD2105, RT3070 13b1:002f - Linksys AE1000, RT3572 13b1:0031 - Cisco / Linksys AM10, RT3072 14b2:3c2c - Keebox W150NU / Alpha Networks WUS-N12, RT3070 157e:3013 - TRENDnet TEW-645UB, RT2770+RT2720 15a9:0012 - Airlink AWLL7025 / Gemtek WUBR-208N, RT2870+RT2850 Signed-off-by: Mark Davis Acked-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 35 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6ba31a0e8f78..d2f5c87305a4 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -710,6 +710,16 @@ static struct usb_device_id rt2800usb_device_table[] = { { 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) }, + /* Alpha Networks */ + { 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) }, + { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c2c), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Amit */ { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Askey */ @@ -736,15 +746,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Buffalo */ { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Conceptronic */ - { 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) }, - { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0411, 0x01a2), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Corega */ { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -776,6 +778,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Gemtek */ + { USB_DEVICE(0x15a9, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Gigabyte */ { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -792,6 +796,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x04bb, 0x0947), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x04bb, 0x0948), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Linksys */ + { USB_DEVICE(0x13b1, 0x0031), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Logitec */ @@ -870,8 +875,9 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sweex */ { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* U-Media*/ + /* U-Media */ { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x157e, 0x3013), USB_DEVICE_DATA(&rt2800usb_ops) }, /* ZCOM */ { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -883,6 +889,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Zyxel */ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0586, 0x3418), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0586, 0x341e), USB_DEVICE_DATA(&rt2800usb_ops) }, #ifdef CONFIG_RT2800USB_RT33XX /* Ralink */ { USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -901,6 +908,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) }, /* I-O DATA */ { USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Linksys */ + { USB_DEVICE(0x13b1, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ @@ -915,6 +924,9 @@ static struct usb_device_id rt2800usb_device_table[] = { * Unclear what kind of devices these are (they aren't supported by the * vendor linux driver). */ + /* Alpha Networks */ + { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Amigo */ { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -933,9 +945,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0411, 0x0148), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x0150), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0411, 0x015d), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Conceptronic */ - { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Corega */ { USB_DEVICE(0x07aa, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07aa, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, -- GitLab From 6f11c819d5fb24b637f2db605e5d3c270c979627 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 12 Apr 2011 12:42:22 +0530 Subject: [PATCH 0777/5560] ath9k: Register id table for platform device Currently the device id in the platform driver is hardcoded to an id which is specific to AR9130/AR9132 SOCs as it supports only wmac (wireless mac) of these SOCs. But this needs to be dynamic when we want to support different wmac of SOCs. So add id_table to driver to make it extendable to more SOCs. Signed-off-by: Vasanthakumar Thiagarajan Acked-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ahb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9cb0efa9b4c0..5193ed58a17b 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -21,6 +21,14 @@ #include #include "ath9k.h" +const struct platform_device_id ath9k_platform_id_table[] = { + { + .name = "ath9k", + .driver_data = AR5416_AR9100_DEVID, + }, + {}, +}; + /* return bus cachesize in 4B word units */ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) { @@ -57,6 +65,7 @@ static int ath_ahb_probe(struct platform_device *pdev) struct ath_softc *sc; struct ieee80211_hw *hw; struct resource *res; + const struct platform_device_id *id = platform_get_device_id(pdev); int irq; int ret = 0; struct ath_hw *ah; @@ -116,7 +125,7 @@ static int ath_ahb_probe(struct platform_device *pdev) goto err_free_hw; } - ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); + ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops); if (ret) { dev_err(&pdev->dev, "failed to initialize device\n"); goto err_irq; @@ -165,8 +174,11 @@ static struct platform_driver ath_ahb_driver = { .name = "ath9k", .owner = THIS_MODULE, }, + .id_table = ath9k_platform_id_table, }; +MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table); + int ath_ahb_init(void) { return platform_driver_register(&ath_ahb_driver); -- GitLab From bcc6d47903612c3861201cc3a866fb604f26b8b2 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 7 Apr 2011 19:48:33 +0000 Subject: [PATCH 0778/5560] net: vlan: make non-hw-accel rx path similar to hw-accel Now there are 2 paths for rx vlan frames. When rx-vlan-hw-accel is enabled, skb is untagged by NIC, vlan_tci is set and the skb gets into vlan code in __netif_receive_skb - vlan_hwaccel_do_receive. For non-rx-vlan-hw-accel however, tagged skb goes thru whole __netif_receive_skb, it's untagged in ptype_base hander and reinjected This incosistency is fixed by this patch. Vlan untagging happens early in __netif_receive_skb so the rest of code (ptype_all handlers, rx_handlers) see the skb like it was untagged by hw. Signed-off-by: Jiri Pirko v1->v2: remove "inline" from vlan_core.c functions Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 10 ++- net/8021q/vlan.c | 8 -- net/8021q/vlan.h | 2 - net/8021q/vlan_core.c | 85 +++++++++++++++++++- net/8021q/vlan_dev.c | 173 ---------------------------------------- net/core/dev.c | 8 +- 6 files changed, 99 insertions(+), 187 deletions(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 635e1faec412..998b29930b80 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -132,7 +132,8 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci, int polling); -extern bool vlan_hwaccel_do_receive(struct sk_buff **skb); +extern bool vlan_do_receive(struct sk_buff **skb); +extern struct sk_buff *vlan_untag(struct sk_buff *skb); extern gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb); @@ -166,13 +167,18 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return NET_XMIT_SUCCESS; } -static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb) +static inline bool vlan_do_receive(struct sk_buff **skb) { if ((*skb)->vlan_tci & VLAN_VID_MASK) (*skb)->pkt_type = PACKET_OTHERHOST; return false; } +inline struct sk_buff *vlan_untag(struct sk_buff *skb) +{ + return skb; +} + static inline gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index e47600b4e2e3..14ef5efbc653 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -49,11 +49,6 @@ const char vlan_version[] = DRV_VERSION; static const char vlan_copyright[] = "Ben Greear "; static const char vlan_buggyright[] = "David S. Miller "; -static struct packet_type vlan_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_8021Q), - .func = vlan_skb_recv, /* VLAN receive method */ -}; - /* End of global variables definitions. */ static void vlan_group_free(struct vlan_group *grp) @@ -684,7 +679,6 @@ static int __init vlan_proto_init(void) if (err < 0) goto err4; - dev_add_pack(&vlan_packet_type); vlan_ioctl_set(vlan_ioctl_handler); return 0; @@ -705,8 +699,6 @@ static void __exit vlan_cleanup_module(void) unregister_netdevice_notifier(&vlan_notifier_block); - dev_remove_pack(&vlan_packet_type); - unregister_pernet_subsys(&vlan_net_ops); rcu_barrier(); /* Wait for completion of call_rcu()'s */ diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 5687c9b95f33..c3408def8a19 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -75,8 +75,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) } /* found in vlan_dev.c */ -int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev); void vlan_dev_set_ingress_priority(const struct net_device *dev, u32 skb_prio, u16 vlan_prio); int vlan_dev_set_egress_priority(const struct net_device *dev, diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index ce8e3ab3e7a5..41495dc2a4c9 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -4,7 +4,7 @@ #include #include "vlan.h" -bool vlan_hwaccel_do_receive(struct sk_buff **skbp) +bool vlan_do_receive(struct sk_buff **skbp) { struct sk_buff *skb = *skbp; u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; @@ -88,3 +88,86 @@ gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, return napi_gro_frags(napi); } EXPORT_SYMBOL(vlan_gro_frags); + +static struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) +{ + if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) { + if (skb_cow(skb, skb_headroom(skb)) < 0) + skb = NULL; + if (skb) { + /* Lifted from Gleb's VLAN code... */ + memmove(skb->data - ETH_HLEN, + skb->data - VLAN_ETH_HLEN, 12); + skb->mac_header += VLAN_HLEN; + } + } + return skb; +} + +static void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr) +{ + __be16 proto; + unsigned char *rawp; + + /* + * Was a VLAN packet, grab the encapsulated protocol, which the layer + * three protocols care about. + */ + + proto = vhdr->h_vlan_encapsulated_proto; + if (ntohs(proto) >= 1536) { + skb->protocol = proto; + return; + } + + rawp = skb->data; + if (*(unsigned short *) rawp == 0xFFFF) + /* + * This is a magic hack to spot IPX packets. Older Novell + * breaks the protocol design and runs IPX over 802.3 without + * an 802.2 LLC layer. We look for FFFF which isn't a used + * 802.2 SSAP/DSAP. This won't work for fault tolerant netware + * but does for the rest. + */ + skb->protocol = htons(ETH_P_802_3); + else + /* + * Real 802.2 LLC + */ + skb->protocol = htons(ETH_P_802_2); +} + +struct sk_buff *vlan_untag(struct sk_buff *skb) +{ + struct vlan_hdr *vhdr; + u16 vlan_tci; + + if (unlikely(vlan_tx_tag_present(skb))) { + /* vlan_tci is already set-up so leave this for another time */ + return skb; + } + + skb = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + goto err_free; + + if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) + goto err_free; + + vhdr = (struct vlan_hdr *) skb->data; + vlan_tci = ntohs(vhdr->h_vlan_TCI); + __vlan_hwaccel_put_tag(skb, vlan_tci); + + skb_pull_rcsum(skb, VLAN_HLEN); + vlan_set_encap_proto(skb, vhdr); + + skb = vlan_check_reorder_header(skb); + if (unlikely(!skb)) + goto err_free; + + return skb; + +err_free: + kfree_skb(skb); + return NULL; +} diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b84a46b30c0c..d174c312b7f1 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -65,179 +65,6 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb) return 0; } -static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) -{ - if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) { - if (skb_cow(skb, skb_headroom(skb)) < 0) - skb = NULL; - if (skb) { - /* Lifted from Gleb's VLAN code... */ - memmove(skb->data - ETH_HLEN, - skb->data - VLAN_ETH_HLEN, 12); - skb->mac_header += VLAN_HLEN; - } - } - - return skb; -} - -static inline void vlan_set_encap_proto(struct sk_buff *skb, - struct vlan_hdr *vhdr) -{ - __be16 proto; - unsigned char *rawp; - - /* - * Was a VLAN packet, grab the encapsulated protocol, which the layer - * three protocols care about. - */ - - proto = vhdr->h_vlan_encapsulated_proto; - if (ntohs(proto) >= 1536) { - skb->protocol = proto; - return; - } - - rawp = skb->data; - if (*(unsigned short *)rawp == 0xFFFF) - /* - * This is a magic hack to spot IPX packets. Older Novell - * breaks the protocol design and runs IPX over 802.3 without - * an 802.2 LLC layer. We look for FFFF which isn't a used - * 802.2 SSAP/DSAP. This won't work for fault tolerant netware - * but does for the rest. - */ - skb->protocol = htons(ETH_P_802_3); - else - /* - * Real 802.2 LLC - */ - skb->protocol = htons(ETH_P_802_2); -} - -/* - * Determine the packet's protocol ID. The rule here is that we - * assume 802.3 if the type field is short enough to be a length. - * This is normal practice and works for any 'now in use' protocol. - * - * Also, at this point we assume that we ARE dealing exclusively with - * VLAN packets, or packets that should be made into VLAN packets based - * on a default VLAN ID. - * - * NOTE: Should be similar to ethernet/eth.c. - * - * SANITY NOTE: This method is called when a packet is moving up the stack - * towards userland. To get here, it would have already passed - * through the ethernet/eth.c eth_type_trans() method. - * SANITY NOTE 2: We are referencing to the VLAN_HDR frields, which MAY be - * stored UNALIGNED in the memory. RISC systems don't like - * such cases very much... - * SANITY NOTE 2a: According to Dave Miller & Alexey, it will always be - * aligned, so there doesn't need to be any of the unaligned - * stuff. It has been commented out now... --Ben - * - */ -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_pcpu_stats *rx_stats; - struct net_device *vlan_dev; - u16 vlan_id; - u16 vlan_tci; - - skb = skb_share_check(skb, GFP_ATOMIC); - if (skb == NULL) - goto err_free; - - if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) - goto err_free; - - vhdr = (struct vlan_hdr *)skb->data; - vlan_tci = ntohs(vhdr->h_vlan_TCI); - vlan_id = vlan_tci & VLAN_VID_MASK; - - rcu_read_lock(); - vlan_dev = vlan_find_dev(dev, vlan_id); - - /* If the VLAN device is defined, we use it. - * If not, and the VID is 0, it is a 802.1p packet (not - * really a VLAN), so we will just netif_rx it later to the - * original interface, but with the skb->proto set to the - * wrapped proto: we do nothing here. - */ - - if (!vlan_dev) { - if (vlan_id) { - pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n", - __func__, vlan_id, dev->name); - goto err_unlock; - } - rx_stats = NULL; - } else { - skb->dev = vlan_dev; - - rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats); - - u64_stats_update_begin(&rx_stats->syncp); - rx_stats->rx_packets++; - rx_stats->rx_bytes += skb->len; - - skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci); - - pr_debug("%s: priority: %u for TCI: %hu\n", - __func__, skb->priority, vlan_tci); - - switch (skb->pkt_type) { - case PACKET_BROADCAST: - /* Yeah, stats collect these together.. */ - /* stats->broadcast ++; // no such counter :-( */ - break; - - case PACKET_MULTICAST: - rx_stats->rx_multicast++; - break; - - case PACKET_OTHERHOST: - /* Our lower layer thinks this is not local, let's make - * sure. - * This allows the VLAN to have a different MAC than the - * underlying device, and still route correctly. - */ - if (!compare_ether_addr(eth_hdr(skb)->h_dest, - skb->dev->dev_addr)) - skb->pkt_type = PACKET_HOST; - break; - default: - break; - } - u64_stats_update_end(&rx_stats->syncp); - } - - skb_pull_rcsum(skb, VLAN_HLEN); - vlan_set_encap_proto(skb, vhdr); - - if (vlan_dev) { - skb = vlan_check_reorder_header(skb); - if (!skb) { - rx_stats->rx_errors++; - goto err_unlock; - } - } - - netif_rx(skb); - - rcu_read_unlock(); - return NET_RX_SUCCESS; - -err_unlock: - rcu_read_unlock(); -err_free: - atomic_long_inc(&dev->rx_dropped); - kfree_skb(skb); - return NET_RX_DROP; -} - static inline u16 vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) { diff --git a/net/core/dev.c b/net/core/dev.c index 95897ff3a76f..d1aebf7c6494 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3130,6 +3130,12 @@ static int __netif_receive_skb(struct sk_buff *skb) __this_cpu_inc(softnet_data.processed); + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { + skb = vlan_untag(skb); + if (unlikely(!skb)) + goto out; + } + #ifdef CONFIG_NET_CLS_ACT if (skb->tc_verd & TC_NCLS) { skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); @@ -3177,7 +3183,7 @@ static int __netif_receive_skb(struct sk_buff *skb) ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = NULL; } - if (vlan_hwaccel_do_receive(&skb)) { + if (vlan_do_receive(&skb)) { ret = __netif_receive_skb(skb); goto out; } else if (unlikely(!skb)) -- GitLab From 872674858fe236b746317741013c830bb70775c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 12 Apr 2011 09:56:38 +0000 Subject: [PATCH 0779/5560] net: add RTNL_ASSERT in __netdev_update_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- net/core/dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index d1aebf7c6494..f523eee3141c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5247,6 +5247,8 @@ int __netdev_update_features(struct net_device *dev) u32 features; int err = 0; + ASSERT_RTNL(); + features = netdev_get_wanted_features(dev); if (dev->netdev_ops->ndo_fix_features) -- GitLab From f5d640371dacda100a32a30e8013f957aff26ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 10 Apr 2011 03:13:21 +0000 Subject: [PATCH 0780/5560] net: sky2: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caveats: - driver modifies vlan_features on HW VLAN TX changes - broken RX checksum will be reenabled on features change Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/sky2.c | 161 +++++++++++++++++---------------------------- drivers/net/sky2.h | 1 - 2 files changed, 59 insertions(+), 103 deletions(-) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 336c762515b2..a4b8fe564eb0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1198,12 +1198,12 @@ static void rx_set_checksum(struct sky2_port *sky2) sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), - (sky2->flags & SKY2_FLAG_RX_CHECKSUM) + (sky2->netdev->features & NETIF_F_RXCSUM) ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); } /* Enable/disable receive hash calculation (RSS) */ -static void rx_set_rss(struct net_device *dev) +static void rx_set_rss(struct net_device *dev, u32 features) { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; @@ -1216,7 +1216,7 @@ static void rx_set_rss(struct net_device *dev) } /* Program RSS initial values */ - if (dev->features & NETIF_F_RXHASH) { + if (features & NETIF_F_RXHASH) { u32 key[nkeys]; get_random_bytes(key, nkeys * sizeof(u32)); @@ -1322,32 +1322,32 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; } -#define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX) +#define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) -static void sky2_vlan_mode(struct net_device *dev) +static void sky2_vlan_mode(struct net_device *dev, u32 features) { struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; u16 port = sky2->port; - if (dev->features & NETIF_F_HW_VLAN_RX) + if (features & NETIF_F_HW_VLAN_RX) sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON); else sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF); - dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN; - if (dev->features & NETIF_F_HW_VLAN_TX) + if (features & NETIF_F_HW_VLAN_TX) { sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON); - else { + + dev->vlan_features |= SKY2_VLAN_OFFLOADS; + } else { sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF); /* Can't do transmit offload of vlan without hw vlan */ - dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG - | NETIF_F_ALL_CSUM); + dev->vlan_features &= ~SKY2_VLAN_OFFLOADS; } } @@ -1463,7 +1463,7 @@ static void sky2_rx_start(struct sky2_port *sky2) rx_set_checksum(sky2); if (!(hw->flags & SKY2_HW_RSS_BROKEN)) - rx_set_rss(sky2->netdev); + rx_set_rss(sky2->netdev, sky2->netdev->features); /* submit Rx ring */ for (i = 0; i < sky2->rx_pending; i++) { @@ -1626,7 +1626,8 @@ static void sky2_hw_up(struct sky2_port *sky2) sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, sky2->tx_ring_size - 1); - sky2_vlan_mode(sky2->netdev); + sky2_vlan_mode(sky2->netdev, sky2->netdev->features); + netdev_update_features(sky2->netdev); sky2_rx_start(sky2); } @@ -2261,12 +2262,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) hw->chip_id == CHIP_ID_YUKON_FE_P)) return -EINVAL; - /* TSO, etc on Yukon Ultra and MTU > 1500 not supported */ - if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) - dev->features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); - if (!netif_running(dev)) { dev->mtu = new_mtu; + netdev_update_features(dev); return 0; } @@ -2288,6 +2286,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) sky2_rx_clean(sky2); dev->mtu = new_mtu; + netdev_update_features(dev); mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); @@ -2535,8 +2534,11 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) "%s: receive checksum problem (status = %#x)\n", sky2->netdev->name, status); - /* Disable checksum offload */ - sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; + /* Disable checksum offload + * It will be reenabled on next ndo_set_features, but if it's + * really broken, will get disabled again + */ + sky2->netdev->features &= ~NETIF_F_RXCSUM; sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), BMU_DIS_RX_CHKSUM); } @@ -2591,7 +2593,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) /* This chip reports checksum status differently */ if (hw->flags & SKY2_HW_NEW_LE) { - if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) && + if ((dev->features & NETIF_F_RXCSUM) && (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && (le->css & CSS_TCPUDPCSOK)) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2616,7 +2618,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) sky2->rx_tag = length; /* fall through */ case OP_RXCHKS: - if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) + if (likely(dev->features & NETIF_F_RXCSUM)) sky2_rx_checksum(sky2, status); break; @@ -3552,28 +3554,6 @@ static const struct sky2_stat { { "tx_fifo_underrun", GM_TXE_FIFO_UR }, }; -static u32 sky2_get_rx_csum(struct net_device *dev) -{ - struct sky2_port *sky2 = netdev_priv(dev); - - return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM); -} - -static int sky2_set_rx_csum(struct net_device *dev, u32 data) -{ - struct sky2_port *sky2 = netdev_priv(dev); - - if (data) - sky2->flags |= SKY2_FLAG_RX_CHECKSUM; - else - sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; - - sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), - data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); - - return 0; -} - static u32 sky2_get_msglevel(struct net_device *netdev) { struct sky2_port *sky2 = netdev_priv(netdev); @@ -4084,34 +4064,6 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, } } -/* In order to do Jumbo packets on these chips, need to turn off the - * transmit store/forward. Therefore checksum offload won't work. - */ -static int no_tx_offload(struct net_device *dev) -{ - const struct sky2_port *sky2 = netdev_priv(dev); - const struct sky2_hw *hw = sky2->hw; - - return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U; -} - -static int sky2_set_tx_csum(struct net_device *dev, u32 data) -{ - if (data && no_tx_offload(dev)) - return -EINVAL; - - return ethtool_op_set_tx_csum(dev, data); -} - - -static int sky2_set_tso(struct net_device *dev, u32 data) -{ - if (data && no_tx_offload(dev)) - return -EINVAL; - - return ethtool_op_set_tso(dev, data); -} - static int sky2_get_eeprom_len(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); @@ -4214,31 +4166,36 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); } -static int sky2_set_flags(struct net_device *dev, u32 data) +static u32 sky2_fix_features(struct net_device *dev, u32 features) { - struct sky2_port *sky2 = netdev_priv(dev); - unsigned long old_feat = dev->features; - u32 supported = 0; - int rc; + const struct sky2_port *sky2 = netdev_priv(dev); + const struct sky2_hw *hw = sky2->hw; - if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN)) - supported |= ETH_FLAG_RXHASH; + /* In order to do Jumbo packets on these chips, need to turn off the + * transmit store/forward. Therefore checksum offload won't work. + */ + if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) + features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM); - if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN)) - supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN; + return features; +} - printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n", - supported, data); +static int sky2_set_features(struct net_device *dev, u32 features) +{ + struct sky2_port *sky2 = netdev_priv(dev); + u32 changed = dev->features ^ features; - rc = ethtool_op_set_flags(dev, data, supported); - if (rc) - return rc; + if (changed & NETIF_F_RXCSUM) { + u32 on = features & NETIF_F_RXCSUM; + sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), + on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + } - if ((old_feat ^ dev->features) & NETIF_F_RXHASH) - rx_set_rss(dev); + if (changed & NETIF_F_RXHASH) + rx_set_rss(dev, features); - if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN) - sky2_vlan_mode(dev); + if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) + sky2_vlan_mode(dev, features); return 0; } @@ -4258,11 +4215,6 @@ static const struct ethtool_ops sky2_ethtool_ops = { .get_eeprom_len = sky2_get_eeprom_len, .get_eeprom = sky2_get_eeprom, .set_eeprom = sky2_set_eeprom, - .set_sg = ethtool_op_set_sg, - .set_tx_csum = sky2_set_tx_csum, - .set_tso = sky2_set_tso, - .get_rx_csum = sky2_get_rx_csum, - .set_rx_csum = sky2_set_rx_csum, .get_strings = sky2_get_strings, .get_coalesce = sky2_get_coalesce, .set_coalesce = sky2_set_coalesce, @@ -4273,8 +4225,6 @@ static const struct ethtool_ops sky2_ethtool_ops = { .set_phys_id = sky2_set_phys_id, .get_sset_count = sky2_get_sset_count, .get_ethtool_stats = sky2_get_ethtool_stats, - .set_flags = sky2_set_flags, - .get_flags = ethtool_op_get_flags, }; #ifdef CONFIG_SKY2_DEBUG @@ -4554,6 +4504,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = { .ndo_set_mac_address = sky2_set_mac_address, .ndo_set_multicast_list = sky2_set_multicast, .ndo_change_mtu = sky2_change_mtu, + .ndo_fix_features = sky2_fix_features, + .ndo_set_features = sky2_set_features, .ndo_tx_timeout = sky2_tx_timeout, .ndo_get_stats64 = sky2_get_stats, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -4569,6 +4521,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = { .ndo_set_mac_address = sky2_set_mac_address, .ndo_set_multicast_list = sky2_set_multicast, .ndo_change_mtu = sky2_change_mtu, + .ndo_fix_features = sky2_fix_features, + .ndo_set_features = sky2_set_features, .ndo_tx_timeout = sky2_tx_timeout, .ndo_get_stats64 = sky2_get_stats, }, @@ -4601,7 +4555,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, /* Auto speed and flow control */ sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE; if (hw->chip_id != CHIP_ID_YUKON_XL) - sky2->flags |= SKY2_FLAG_RX_CHECKSUM; + dev->hw_features |= NETIF_F_RXCSUM; sky2->flow_mode = FC_BOTH; @@ -4620,18 +4574,21 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->port = port; - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG - | NETIF_F_TSO | NETIF_F_GRO; + dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO; if (highmem) dev->features |= NETIF_F_HIGHDMA; /* Enable receive hashing unless hardware is known broken */ if (!(hw->flags & SKY2_HW_RSS_BROKEN)) - dev->features |= NETIF_F_RXHASH; + dev->hw_features |= NETIF_F_RXHASH; + + if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) { + dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_features |= SKY2_VLAN_OFFLOADS; + } - if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->features |= dev->hw_features; /* read the mac address */ memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 0c6d10c5f053..318c9ae7bf91 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2254,7 +2254,6 @@ struct sky2_port { u8 wol; /* WAKE_ bits */ u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ u16 flags; -#define SKY2_FLAG_RX_CHECKSUM 0x0001 #define SKY2_FLAG_AUTO_SPEED 0x0002 #define SKY2_FLAG_AUTO_PAUSE 0x0004 -- GitLab From d1423c7ab847e72a63e0e3512a1a7f3bce55ae01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 10 Apr 2011 04:49:55 +0000 Subject: [PATCH 0781/5560] net: ps3_gelic: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/ps3_gelic_net.c | 26 +++++--------------------- drivers/net/ps3_gelic_net.h | 3 --- drivers/net/ps3_gelic_wireless.c | 4 ---- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index ffdf7349ef7a..4383ed21813e 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -951,7 +951,7 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, skb->protocol = eth_type_trans(skb, netdev); /* checksum offload */ - if (card->rx_csum) { + if (netdev->features & NETIF_F_RXCSUM) { if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) && (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK))) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1312,21 +1312,6 @@ static int gelic_ether_set_settings(struct net_device *netdev, return 0; } -u32 gelic_net_get_rx_csum(struct net_device *netdev) -{ - struct gelic_card *card = netdev_card(netdev); - - return card->rx_csum; -} - -int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) -{ - struct gelic_card *card = netdev_card(netdev); - - card->rx_csum = data; - return 0; -} - static void gelic_net_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { @@ -1411,10 +1396,6 @@ static const struct ethtool_ops gelic_ether_ethtool_ops = { .get_settings = gelic_ether_get_settings, .set_settings = gelic_ether_set_settings, .get_link = ethtool_op_get_link, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_rx_csum = gelic_net_get_rx_csum, - .set_rx_csum = gelic_net_set_rx_csum, .get_wol = gelic_net_get_wol, .set_wol = gelic_net_set_wol, }; @@ -1512,7 +1493,11 @@ int __devinit gelic_net_setup_netdev(struct net_device *netdev, int status; u64 v1, v2; + netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + netdev->features = NETIF_F_IP_CSUM; + if (GELIC_CARD_RX_CSUM_DEFAULT) + netdev->features |= NETIF_F_RXCSUM; status = lv1_net_control(bus_id(card), dev_id(card), GELIC_LV1_GET_MAC_ADDRESS, @@ -1756,7 +1741,6 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev) /* setup card structure */ card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT | GELIC_CARD_PORT_STATUS_CHANGED; - card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT; if (gelic_card_init_chain(card, &card->tx_chain, diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h index fadadf9097a3..d9a55b93898b 100644 --- a/drivers/net/ps3_gelic_net.h +++ b/drivers/net/ps3_gelic_net.h @@ -290,7 +290,6 @@ struct gelic_card { struct gelic_descr_chain tx_chain; struct gelic_descr_chain rx_chain; int rx_dma_restart_required; - int rx_csum; /* * tx_lock guards tx descriptor list and * tx_dma_progress. @@ -377,8 +376,6 @@ extern int gelic_net_setup_netdev(struct net_device *netdev, /* shared ethtool ops */ extern void gelic_net_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info); -extern u32 gelic_net_get_rx_csum(struct net_device *netdev); -extern int gelic_net_set_rx_csum(struct net_device *netdev, u32 data); extern void gelic_net_poll_controller(struct net_device *netdev); #endif /* _GELIC_NET_H */ diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index b5ae29d20f2e..2e62938c0f82 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -2581,10 +2581,6 @@ static const struct net_device_ops gelic_wl_netdevice_ops = { static const struct ethtool_ops gelic_wl_ethtool_ops = { .get_drvinfo = gelic_net_get_drvinfo, .get_link = gelic_wl_get_link, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_rx_csum = gelic_net_get_rx_csum, - .set_rx_csum = gelic_net_set_rx_csum, }; static void __devinit gelic_wl_setup_netdev_ops(struct net_device *netdev) -- GitLab From e5ee20e70f078d584572709962f5d90f876912c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 12 Apr 2011 09:38:23 +0000 Subject: [PATCH 0782/5560] net: bna: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: looks like bnad->conf_mutex is duplicating rtnl_lock. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 22 +++++------- drivers/net/bna/bnad.h | 2 -- drivers/net/bna/bnad_ethtool.c | 63 ---------------------------------- 3 files changed, 9 insertions(+), 78 deletions(-) diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 9f356d5d0f33..b9f253470da2 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -501,7 +501,7 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) skb_put(skb, ntohs(cmpl->length)); if (likely - (bnad->rx_csum && + ((bnad->netdev->features & NETIF_F_RXCSUM) && (((flags & BNA_CQ_EF_IPV4) && (flags & BNA_CQ_EF_L3_CKSUM_OK)) || (flags & BNA_CQ_EF_IPV6)) && @@ -2903,23 +2903,20 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac) { struct net_device *netdev = bnad->netdev; - netdev->features |= NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; + netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_TX; - netdev->features |= NETIF_F_GRO; - pr_warn("bna: GRO enabled, using kernel stack GRO\n"); + netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_TSO | NETIF_F_TSO6; - netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + netdev->features |= netdev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; if (using_dac) netdev->features |= NETIF_F_HIGHDMA; - netdev->features |= - NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; - - netdev->vlan_features = netdev->features; netdev->mem_start = bnad->mmio_start; netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1; @@ -2970,7 +2967,6 @@ bnad_init(struct bnad *bnad, bnad->txq_depth = BNAD_TXQ_DEPTH; bnad->rxq_depth = BNAD_RXQ_DEPTH; - bnad->rx_csum = true; bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO; bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO; diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index a89117fa4970..ccdabad0a40c 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -237,8 +237,6 @@ struct bnad { struct bna_rx_config rx_config[BNAD_MAX_RXS]; struct bna_tx_config tx_config[BNAD_MAX_TXS]; - u32 rx_csum; - void __iomem *bar0; /* BAR0 address */ struct bna bna; diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index 142d6047da27..c51e078e8f0d 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -806,61 +806,6 @@ bnad_set_pauseparam(struct net_device *netdev, return 0; } -static u32 -bnad_get_rx_csum(struct net_device *netdev) -{ - u32 rx_csum; - struct bnad *bnad = netdev_priv(netdev); - - rx_csum = bnad->rx_csum; - return rx_csum; -} - -static int -bnad_set_rx_csum(struct net_device *netdev, u32 rx_csum) -{ - struct bnad *bnad = netdev_priv(netdev); - - mutex_lock(&bnad->conf_mutex); - bnad->rx_csum = rx_csum; - mutex_unlock(&bnad->conf_mutex); - return 0; -} - -static int -bnad_set_tx_csum(struct net_device *netdev, u32 tx_csum) -{ - struct bnad *bnad = netdev_priv(netdev); - - mutex_lock(&bnad->conf_mutex); - if (tx_csum) { - netdev->features |= NETIF_F_IP_CSUM; - netdev->features |= NETIF_F_IPV6_CSUM; - } else { - netdev->features &= ~NETIF_F_IP_CSUM; - netdev->features &= ~NETIF_F_IPV6_CSUM; - } - mutex_unlock(&bnad->conf_mutex); - return 0; -} - -static int -bnad_set_tso(struct net_device *netdev, u32 tso) -{ - struct bnad *bnad = netdev_priv(netdev); - - mutex_lock(&bnad->conf_mutex); - if (tso) { - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - } else { - netdev->features &= ~NETIF_F_TSO; - netdev->features &= ~NETIF_F_TSO6; - } - mutex_unlock(&bnad->conf_mutex); - return 0; -} - static void bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string) { @@ -1256,14 +1201,6 @@ static struct ethtool_ops bnad_ethtool_ops = { .set_ringparam = bnad_set_ringparam, .get_pauseparam = bnad_get_pauseparam, .set_pauseparam = bnad_set_pauseparam, - .get_rx_csum = bnad_get_rx_csum, - .set_rx_csum = bnad_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = bnad_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = bnad_set_tso, .get_strings = bnad_get_strings, .get_ethtool_stats = bnad_get_ethtool_stats, .get_sset_count = bnad_get_sset_count -- GitLab From 66371c44136b566f39f70c72cb4d117558bee3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 12 Apr 2011 09:38:23 +0000 Subject: [PATCH 0783/5560] net: bnx2x: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since ndo_fix_features callback is postponing features change when bp->recovery_state != BNX2X_RECOVERY_DONE, netdev_update_features() has to be called again when this condition changes. Previously, ethtool_ops->set_flags callback returned -EBUSY in that case (it's not possible in the new model). Signed-off-by: Michał Mirosław v5: - don't delay set_features, as it's rtnl_locked - same as recovery process v4: - complete bp->rx_csum -> NETIF_F_RXCSUM conversion - add check for failed ndo_set_features in ndo_open callback v3: - include NETIF_F_LRO in hw_features - don't call netdev_update_features() if bnx2x_nic_load() failed v2: - comment in ndo_fix_features callback Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 1 - drivers/net/bnx2x/bnx2x_cmn.c | 49 ++++++++++++++-- drivers/net/bnx2x/bnx2x_cmn.h | 3 + drivers/net/bnx2x/bnx2x_ethtool.c | 95 ------------------------------- drivers/net/bnx2x/bnx2x_main.c | 27 ++++----- 5 files changed, 57 insertions(+), 118 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index e0fca701d2f3..9e87417f6ec7 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -918,7 +918,6 @@ struct bnx2x { int tx_ring_size; - u32 rx_csum; /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ #define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index e83ac6dd6fc0..bec33a87bcdc 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -640,7 +640,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb_checksum_none_assert(skb); - if (bp->rx_csum) { + if (bp->dev->features & NETIF_F_RXCSUM) { if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; else @@ -2443,11 +2443,21 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) } +static int bnx2x_reload_if_running(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + if (unlikely(!netif_running(dev))) + return 0; + + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + return bnx2x_nic_load(bp, LOAD_NORMAL); +} + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { struct bnx2x *bp = netdev_priv(dev); - int rc = 0; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); @@ -2464,12 +2474,39 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) */ dev->mtu = new_mtu; - if (netif_running(dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); + return bnx2x_reload_if_running(dev); +} + +u32 bnx2x_fix_features(struct net_device *dev, u32 features) +{ + struct bnx2x *bp = netdev_priv(dev); + + /* TPA requires Rx CSUM offloading */ + if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa) + features &= ~NETIF_F_LRO; + + return features; +} + +int bnx2x_set_features(struct net_device *dev, u32 features) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 flags = bp->flags; + + if (features & NETIF_F_LRO) + flags |= TPA_ENABLE_FLAG; + else + flags &= ~TPA_ENABLE_FLAG; + + if (flags ^ bp->flags) { + bp->flags = flags; + + if (bp->recovery_state == BNX2X_RECOVERY_DONE) + return bnx2x_reload_if_running(dev); + /* else: bnx2x_nic_load() will be called at end of recovery */ } - return rc; + return 0; } void bnx2x_tx_timeout(struct net_device *dev) diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 775fef031ad8..1cdab69b2a51 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -431,6 +431,9 @@ void bnx2x_free_mem_bp(struct bnx2x *bp); */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu); +u32 bnx2x_fix_features(struct net_device *dev, u32 features); +int bnx2x_set_features(struct net_device *dev, u32 features); + /** * tx timeout netdev callback * diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 147999459df5..ad7d91e499f4 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1299,91 +1299,6 @@ static int bnx2x_set_pauseparam(struct net_device *dev, return 0; } -static int bnx2x_set_flags(struct net_device *dev, u32 data) -{ - struct bnx2x *bp = netdev_priv(dev); - int changed = 0; - int rc = 0; - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - if (!(data & ETH_FLAG_RXVLAN)) - return -EINVAL; - - if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa) - return -EINVAL; - - rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN | - ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH); - if (rc) - return rc; - - /* TPA requires Rx CSUM offloading */ - if ((data & ETH_FLAG_LRO) && bp->rx_csum) { - if (!(bp->flags & TPA_ENABLE_FLAG)) { - bp->flags |= TPA_ENABLE_FLAG; - changed = 1; - } - } else if (bp->flags & TPA_ENABLE_FLAG) { - dev->features &= ~NETIF_F_LRO; - bp->flags &= ~TPA_ENABLE_FLAG; - changed = 1; - } - - if (changed && netif_running(dev)) { - bnx2x_nic_unload(bp, UNLOAD_NORMAL); - rc = bnx2x_nic_load(bp, LOAD_NORMAL); - } - - return rc; -} - -static u32 bnx2x_get_rx_csum(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - return bp->rx_csum; -} - -static int bnx2x_set_rx_csum(struct net_device *dev, u32 data) -{ - struct bnx2x *bp = netdev_priv(dev); - int rc = 0; - - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); - return -EAGAIN; - } - - bp->rx_csum = data; - - /* Disable TPA, when Rx CSUM is disabled. Otherwise all - TPA'ed packets will be discarded due to wrong TCP CSUM */ - if (!data) { - u32 flags = ethtool_op_get_flags(dev); - - rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO)); - } - - return rc; -} - -static int bnx2x_set_tso(struct net_device *dev, u32 data) -{ - if (data) { - dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); - dev->features |= NETIF_F_TSO6; - } else { - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); - dev->features &= ~NETIF_F_TSO6; - } - - return 0; -} - static const struct { char string[ETH_GSTRING_LEN]; } bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { @@ -2207,16 +2122,6 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .set_ringparam = bnx2x_set_ringparam, .get_pauseparam = bnx2x_get_pauseparam, .set_pauseparam = bnx2x_set_pauseparam, - .get_rx_csum = bnx2x_get_rx_csum, - .set_rx_csum = bnx2x_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .set_flags = bnx2x_set_flags, - .get_flags = ethtool_op_get_flags, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = bnx2x_set_tso, .self_test = bnx2x_self_test, .get_sset_count = bnx2x_get_sset_count, .get_strings = bnx2x_get_strings, diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index a6915aafa695..696e84afdc53 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -8904,8 +8904,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->multi_mode = multi_mode; bp->int_mode = int_mode; - bp->dev->features |= NETIF_F_GRO; - /* Set TPA flags */ if (disable_tpa) { bp->flags &= ~TPA_ENABLE_FLAG; @@ -8925,8 +8923,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->tx_ring_size = MAX_TX_AVAIL; - bp->rx_csum = 1; - /* make sure that the numbers are in the right granularity */ bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR; bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR; @@ -9304,6 +9300,8 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = bnx2x_ioctl, .ndo_change_mtu = bnx2x_change_mtu, + .ndo_fix_features = bnx2x_fix_features, + .ndo_set_features = bnx2x_set_features, .ndo_tx_timeout = bnx2x_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2x, @@ -9430,20 +9428,17 @@ 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_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); - dev->features |= NETIF_F_TSO6; - dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - dev->vlan_features |= NETIF_F_SG; - dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | + NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX; + + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA; + + dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX; if (bp->flags & USING_DAC_FLAG) - dev->vlan_features |= NETIF_F_HIGHDMA; - dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); - dev->vlan_features |= NETIF_F_TSO6; + dev->features |= NETIF_F_HIGHDMA; #ifdef BCM_DCBNL dev->dcbnl_ops = &bnx2x_dcbnl_ops; -- GitLab From 6d95ff974a4b51121777973ffba7547c648da974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 12 Apr 2011 09:48:17 +0000 Subject: [PATCH 0784/5560] net: ioc3: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/ioc3-eth.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index c8ee8d28767b..96c95617195f 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -90,8 +90,6 @@ struct ioc3_private { u32 emcr, ehar_h, ehar_l; spinlock_t ioc3_lock; struct mii_if_info mii; - unsigned long flags; -#define IOC3_FLAG_RX_CHECKSUMS 1 struct pci_dev *pdev; @@ -609,7 +607,7 @@ static inline void ioc3_rx(struct net_device *dev) goto next; } - if (likely(ip->flags & IOC3_FLAG_RX_CHECKSUMS)) + if (likely(dev->features & NETIF_F_RXCSUM)) ioc3_tcpudp_checksum(skb, w0 & ERXBUF_IPCKSUM_MASK, len); @@ -1328,6 +1326,7 @@ static int __devinit ioc3_probe(struct pci_dev *pdev, dev->watchdog_timeo = 5 * HZ; dev->netdev_ops = &ioc3_netdev_ops; dev->ethtool_ops = &ioc3_ethtool_ops; + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM; dev->features = NETIF_F_IP_CSUM; sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); @@ -1618,37 +1617,12 @@ static u32 ioc3_get_link(struct net_device *dev) return rc; } -static u32 ioc3_get_rx_csum(struct net_device *dev) -{ - struct ioc3_private *ip = netdev_priv(dev); - - return ip->flags & IOC3_FLAG_RX_CHECKSUMS; -} - -static int ioc3_set_rx_csum(struct net_device *dev, u32 data) -{ - struct ioc3_private *ip = netdev_priv(dev); - - spin_lock_bh(&ip->ioc3_lock); - if (data) - ip->flags |= IOC3_FLAG_RX_CHECKSUMS; - else - ip->flags &= ~IOC3_FLAG_RX_CHECKSUMS; - spin_unlock_bh(&ip->ioc3_lock); - - return 0; -} - static const struct ethtool_ops ioc3_ethtool_ops = { .get_drvinfo = ioc3_get_drvinfo, .get_settings = ioc3_get_settings, .set_settings = ioc3_set_settings, .nway_reset = ioc3_nway_reset, .get_link = ioc3_get_link, - .get_rx_csum = ioc3_get_rx_csum, - .set_rx_csum = ioc3_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum }; static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -- GitLab From 1aac62671686e6234c91b5f6fc4caaa850419d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Tue, 12 Apr 2011 04:07:39 +0000 Subject: [PATCH 0785/5560] net: vlan_features comment clarification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław 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 09d262415769..cb8178ab3c52 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1035,7 +1035,7 @@ struct net_device { u32 hw_features; /* user-requested features */ u32 wanted_features; - /* VLAN feature mask */ + /* mask of features inheritable by VLAN devices */ u32 vlan_features; /* Net device feature bits; if you change something, -- GitLab From 095d3da610d4022d341c517c59dd5a5d656d966f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Apr 2011 15:58:41 -0700 Subject: [PATCH 0786/5560] 9p: Kill set but unused variable in 9p_client_{read,write}() and p9_client_readdir() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following warnings: net/9p/client.c:1305:18: warning: variable ‘total’ set but not used [-Wunused-but-set-variable] net/9p/client.c:1370:18: warning: variable ‘total’ set but not used [-Wunused-but-set-variable] net/9p/client.c:1769:18: warning: variable ‘total’ set but not used [-Wunused-but-set-variable] Signed-off-by: David S. Miller --- net/9p/client.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index 48b8e084e710..0ce959218607 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1302,7 +1302,7 @@ int p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, u32 count) { - int err, rsize, total; + int err, rsize; struct p9_client *clnt; struct p9_req_t *req; char *dataptr; @@ -1311,7 +1311,6 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, (long long unsigned) offset, count); err = 0; clnt = fid->clnt; - total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) @@ -1367,7 +1366,7 @@ int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, u64 offset, u32 count) { - int err, rsize, total; + int err, rsize; struct p9_client *clnt; struct p9_req_t *req; @@ -1375,7 +1374,6 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, fid->fid, (long long unsigned) offset, count); err = 0; clnt = fid->clnt; - total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) @@ -1766,7 +1764,7 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate); int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) { - int err, rsize, total; + int err, rsize; struct p9_client *clnt; struct p9_req_t *req; char *dataptr; @@ -1776,7 +1774,6 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) err = 0; clnt = fid->clnt; - total = 0; rsize = fid->iounit; if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ) -- GitLab From 24743537d3f784a8b3014e934fad0a9c45e4e789 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Apr 2011 16:14:21 -0700 Subject: [PATCH 0787/5560] atm: iphase: Fix set-but-not-used warnings. The "iavcc" and "iadev" cases are obvious. The intr_status and frmr_intr cases are reading a register to clear the chip status. This driver is pretty old and creaky, and uses volatile pointer dereferences to do register I/O when it should be using readl() and friends. However that it outside of the scope of these changes. Signed-off-by: David S. Miller --- drivers/atm/iphase.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 1c674a91f146..dee4f01a64d8 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -613,7 +613,6 @@ static int ia_que_tx (IADEV *iadev) { struct sk_buff *skb; int num_desc; struct atm_vcc *vcc; - struct ia_vcc *iavcc; num_desc = ia_avail_descs(iadev); while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) { @@ -627,7 +626,6 @@ static int ia_que_tx (IADEV *iadev) { printk("Free the SKB on closed vci %d \n", vcc->vci); break; } - iavcc = INPH_IA_VCC(vcc); if (ia_pkt_tx (vcc, skb)) { skb_queue_head(&iadev->tx_backlog, skb); } @@ -823,8 +821,6 @@ static void IaFrontEndIntr(IADEV *iadev) { volatile IA_SUNI *suni; volatile ia_mb25_t *mb25; volatile suni_pm7345_t *suni_pm7345; - u32 intr_status; - u_int frmr_intr; if(iadev->phy_type & FE_25MBIT_PHY) { mb25 = (ia_mb25_t*)iadev->phy; @@ -832,18 +828,18 @@ static void IaFrontEndIntr(IADEV *iadev) { } else if (iadev->phy_type & FE_DS3_PHY) { suni_pm7345 = (suni_pm7345_t *)iadev->phy; /* clear FRMR interrupts */ - frmr_intr = suni_pm7345->suni_ds3_frm_intr_stat; + (void) suni_pm7345->suni_ds3_frm_intr_stat; iadev->carrier_detect = Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); } else if (iadev->phy_type & FE_E3_PHY ) { suni_pm7345 = (suni_pm7345_t *)iadev->phy; - frmr_intr = suni_pm7345->suni_e3_frm_maint_intr_ind; + (void) suni_pm7345->suni_e3_frm_maint_intr_ind; iadev->carrier_detect = Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS)); } else { suni = (IA_SUNI *)iadev->phy; - intr_status = suni->suni_rsop_status & 0xff; + (void) suni->suni_rsop_status; iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV)); } if (iadev->carrier_detect) @@ -2660,7 +2656,6 @@ static void ia_close(struct atm_vcc *vcc) static int ia_open(struct atm_vcc *vcc) { - IADEV *iadev; struct ia_vcc *ia_vcc; int error; if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) @@ -2668,7 +2663,6 @@ static int ia_open(struct atm_vcc *vcc) IF_EVENT(printk("ia: not partially allocated resources\n");) vcc->dev_data = NULL; } - iadev = INPH_IA_DEV(vcc->dev); if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC) { IF_EVENT(printk("iphase open: unspec part\n");) @@ -3052,11 +3046,9 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) { static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb) { IADEV *iadev; - struct ia_vcc *iavcc; unsigned long flags; iadev = INPH_IA_DEV(vcc->dev); - iavcc = INPH_IA_VCC(vcc); if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer)))) { if (!skb) -- GitLab From 6139e75f4a413bdc8f366fc11e437347be8abc59 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Apr 2011 19:27:51 -0700 Subject: [PATCH 0788/5560] net: Missing 'inline' in vlan-disabled vlan_untag() Reported-by: Stephen Rothwell Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 998b29930b80..546d9d35fbd4 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -174,7 +174,7 @@ static inline bool vlan_do_receive(struct sk_buff **skb) return false; } -inline struct sk_buff *vlan_untag(struct sk_buff *skb) +static inline struct sk_buff *vlan_untag(struct sk_buff *skb) { return skb; } -- GitLab From 910d80513056589d3b12b3aad8598d19e0a0a5bd Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Tue, 12 Apr 2011 23:14:38 -0700 Subject: [PATCH 0789/5560] Input: atmel_mxt_ts - support 12bit resolution Atmel touchscreen chip can support 12bit resolution and this patch modifies to get maximum x and y size from platform data. Signed-off-by: Joonyoung Shim Acked-by: Iiro Valkonen Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 53 +++++++++++++++++------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4012436633b1..a97905a17b72 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -196,9 +196,12 @@ #define MXT_PRESS (1 << 6) #define MXT_DETECT (1 << 7) +/* Touch orient bits */ +#define MXT_XY_SWITCH (1 << 0) +#define MXT_X_INVERT (1 << 1) +#define MXT_Y_INVERT (1 << 2) + /* Touchscreen absolute values */ -#define MXT_MAX_XC 0x3ff -#define MXT_MAX_YC 0x3ff #define MXT_MAX_AREA 0xff #define MXT_MAX_FINGER 10 @@ -246,6 +249,8 @@ struct mxt_data { struct mxt_info info; struct mxt_finger finger[MXT_MAX_FINGER]; unsigned int irq; + unsigned int max_x; + unsigned int max_y; }; static bool mxt_object_readable(unsigned int type) @@ -549,8 +554,13 @@ static void mxt_input_touchevent(struct mxt_data *data, if (!(status & (MXT_PRESS | MXT_MOVE))) return; - x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6); - y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2); + x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); + y = (message->message[2] << 4) | ((message->message[3] & 0xf)); + if (data->max_x < 1024) + x = x >> 2; + if (data->max_y < 1024) + y = y >> 2; + area = message->message[4]; dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, @@ -845,6 +855,20 @@ static int mxt_initialize(struct mxt_data *data) return 0; } +static void mxt_calc_resolution(struct mxt_data *data) +{ + unsigned int max_x = data->pdata->x_size - 1; + unsigned int max_y = data->pdata->y_size - 1; + + if (data->pdata->orient & MXT_XY_SWITCH) { + data->max_x = max_y; + data->max_y = max_x; + } else { + data->max_x = max_x; + data->max_y = max_y; + } +} + static ssize_t mxt_object_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1052,31 +1076,32 @@ static int __devinit mxt_probe(struct i2c_client *client, input_dev->open = mxt_input_open; input_dev->close = mxt_input_close; + data->client = client; + data->input_dev = input_dev; + data->pdata = pdata; + data->irq = client->irq; + + mxt_calc_resolution(data); + __set_bit(EV_ABS, input_dev->evbit); __set_bit(EV_KEY, input_dev->evbit); __set_bit(BTN_TOUCH, input_dev->keybit); /* For single touch */ input_set_abs_params(input_dev, ABS_X, - 0, MXT_MAX_XC, 0, 0); + 0, data->max_x, 0, 0); input_set_abs_params(input_dev, ABS_Y, - 0, MXT_MAX_YC, 0, 0); + 0, data->max_y, 0, 0); /* For multi touch */ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, - 0, MXT_MAX_XC, 0, 0); + 0, data->max_x, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, - 0, MXT_MAX_YC, 0, 0); + 0, data->max_y, 0, 0); input_set_drvdata(input_dev, data); - - data->client = client; - data->input_dev = input_dev; - data->pdata = pdata; - data->irq = client->irq; - i2c_set_clientdata(client, data); error = mxt_initialize(data); -- GitLab From 08960a070add74cda8c968b8ace5418a5acf17c3 Mon Sep 17 00:00:00 2001 From: Iiro Valkonen Date: Tue, 12 Apr 2011 23:16:40 -0700 Subject: [PATCH 0790/5560] Input: atmel_mxt_ts - make CHG line high after enabling interrupts Make the CHG line (interrupt line) go high after the interrupts have been enabled to make sure we don't miss the falling edge. Signed-off-by: Iiro Valkonen Acked-by: Joonyoung Shim Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index a97905a17b72..2accf1dffee9 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -814,10 +814,6 @@ static int mxt_initialize(struct mxt_data *data) if (error) return error; - error = mxt_make_highchg(data); - if (error) - return error; - mxt_handle_pdata(data); /* Backup to memory */ @@ -1005,6 +1001,10 @@ static ssize_t mxt_update_fw_store(struct device *dev, enable_irq(data->irq); + error = mxt_make_highchg(data); + if (error) + return error; + return count; } @@ -1115,6 +1115,10 @@ static int __devinit mxt_probe(struct i2c_client *client, goto err_free_object; } + error = mxt_make_highchg(data); + if (error) + goto err_free_irq; + error = input_register_device(input_dev); if (error) goto err_free_irq; -- GitLab From 8b86c1c28f569301aa1a113a060f9ed803300903 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Tue, 12 Apr 2011 23:18:59 -0700 Subject: [PATCH 0791/5560] Input: atmel_mxt_ts - convert to MT protocol B Atmel touchscreen chips can use MT protocol B because they can assign unique id to ABS_MT_TRACKING_ID from finger id provided by hardware. Signed-off-by: Joonyoung Shim Reviewed-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 27 +++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 2accf1dffee9..1e61387c73ca 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -504,19 +504,21 @@ static void mxt_input_report(struct mxt_data *data, int single_id) if (!finger[id].status) continue; - input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, - finger[id].status != MXT_RELEASE ? - finger[id].area : 0); - input_report_abs(input_dev, ABS_MT_POSITION_X, - finger[id].x); - input_report_abs(input_dev, ABS_MT_POSITION_Y, - finger[id].y); - input_mt_sync(input_dev); + input_mt_slot(input_dev, id); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, + finger[id].status != MXT_RELEASE); - if (finger[id].status == MXT_RELEASE) - finger[id].status = 0; - else + if (finger[id].status != MXT_RELEASE) { finger_num++; + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, + finger[id].area); + input_report_abs(input_dev, ABS_MT_POSITION_X, + finger[id].x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, + finger[id].y); + } else { + finger[id].status = 0; + } } input_report_key(input_dev, BTN_TOUCH, finger_num > 0); @@ -1094,6 +1096,7 @@ static int __devinit mxt_probe(struct i2c_client *client, 0, data->max_y, 0, 0); /* For multi touch */ + input_mt_init_slots(input_dev, MXT_MAX_FINGER); input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, -- GitLab From 82a58a8b7f293e5bab3dd41ee160867bcad41f37 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Apr 2011 09:09:17 +0300 Subject: [PATCH 0792/5560] ASoC: tlv320dac33: Lower the OSC calibration time To get correct calibration, we can decrease the time needed for the OSC to calibrate itself. With this change we can save ~15ms in the OSC calibration phase. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 4857f2ae0666..869c1a9766b5 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -939,8 +939,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) /* Write registers 0x08 and 0x09 (MSB, LSB) */ dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset); - /* calib time: 128 is a nice number ;) */ - dac33_write(codec, DAC33_CALIB_TIME, 128); + /* OSC calibration time */ + dac33_write(codec, DAC33_CALIB_TIME, 96); /* adjustment treshold & step */ dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) | -- GitLab From edb2fd9524cc2a55fb5a2e878b6e4e83f9e63fd0 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 13 Apr 2011 09:45:45 +0200 Subject: [PATCH 0793/5560] include/linux/leds-regulator.h: fix syntax in example code Fix struct field initializer syntax in some example code from a comment, this will make copying and pasting the code more straightforward. Signed-off-by: Antonio Ospite Signed-off-by: Jiri Kosina --- include/linux/leds-regulator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/leds-regulator.h b/include/linux/leds-regulator.h index 5a8eb389aab8..e2337a8c90b0 100644 --- a/include/linux/leds-regulator.h +++ b/include/linux/leds-regulator.h @@ -16,7 +16,7 @@ * Use "vled" as supply id when declaring the regulator consumer: * * static struct regulator_consumer_supply pcap_regulator_VVIB_consumers [] = { - * { .dev_name = "leds-regulator.0", supply = "vled" }, + * { .dev_name = "leds-regulator.0", .supply = "vled" }, * }; * * If you have several regulator driven LEDs, you can append a numerical id to -- GitLab From 9d5e6bdb3013acfb311ab407eeca0b6a6a3dedbf Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 13 Apr 2011 11:12:34 +0200 Subject: [PATCH 0794/5560] ath9k_hw: don't touch with treewide double semicolon removal This is a partial revert of 6eab04a87677 ("treewide: remove extra semicolons"). Wireless tree removes the code in question, so drop the hunk to avoid conflict. Reported-by: Stephen Rothwell Signed-off-by: Jiri Kosina --- drivers/net/wireless/ath/ath9k/phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 3a7cd7523d5c..5e3d7496986e 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -54,7 +54,7 @@ #define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ int i; \ for (i = 0; i < (_iniarray)->ia_rows; i++) \ - (_bank)[i] = INI_RA((_iniarray), i, _col); \ + (_bank)[i] = INI_RA((_iniarray), i, _col);; \ } while (0) #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 -- GitLab From 91eb7c08c6cb3b8eeba1c61f5753c56dcb77f018 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Wed, 13 Apr 2011 13:51:38 +0200 Subject: [PATCH 0795/5560] netfilter: ipset: SCTP, UDPLITE support added SCTP and UDPLITE port support added to the hash:*port* set types. Signed-off-by: Jozsef Kadlecsik Signed-off-by: Patrick McHardy --- include/linux/netfilter/ipset/ip_set_getport.h | 2 ++ net/netfilter/ipset/ip_set_getport.c | 16 +++++++++++++++- net/netfilter/ipset/ip_set_hash_ipport.c | 2 +- net/netfilter/ipset/ip_set_hash_ipportip.c | 2 +- net/netfilter/ipset/ip_set_hash_ipportnet.c | 2 +- net/netfilter/ipset/ip_set_hash_netport.c | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/linux/netfilter/ipset/ip_set_getport.h b/include/linux/netfilter/ipset/ip_set_getport.h index 5aebd170f899..90d09300e954 100644 --- a/include/linux/netfilter/ipset/ip_set_getport.h +++ b/include/linux/netfilter/ipset/ip_set_getport.h @@ -22,7 +22,9 @@ static inline bool ip_set_proto_with_ports(u8 proto) { switch (proto) { case IPPROTO_TCP: + case IPPROTO_SCTP: case IPPROTO_UDP: + case IPPROTO_UDPLITE: return true; } return false; diff --git a/net/netfilter/ipset/ip_set_getport.c b/net/netfilter/ipset/ip_set_getport.c index 8d5227212686..757143b2240a 100644 --- a/net/netfilter/ipset/ip_set_getport.c +++ b/net/netfilter/ipset/ip_set_getport.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,20 @@ get_port(const struct sk_buff *skb, int protocol, unsigned int protooff, *port = src ? th->source : th->dest; break; } - case IPPROTO_UDP: { + case IPPROTO_SCTP: { + sctp_sctphdr_t _sh; + const sctp_sctphdr_t *sh; + + sh = skb_header_pointer(skb, protooff, sizeof(_sh), &_sh); + if (sh == NULL) + /* No choice either */ + return false; + + *port = src ? sh->source : sh->dest; + break; + } + case IPPROTO_UDP: + case IPPROTO_UDPLITE: { struct udphdr _udph; const struct udphdr *uh; diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index b9214145d357..14281b6b8074 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c @@ -491,7 +491,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, .dimension = IPSET_DIM_TWO, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_ipport_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 4642872df6e1..401c8a2531db 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -509,7 +509,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, .dimension = IPSET_DIM_THREE, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_ipportip_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 2cb84a54b7ad..4743e5402522 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -574,7 +574,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, .dimension = IPSET_DIM_THREE, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_ipportnet_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index 8598676f2a05..d2a40362dd3a 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c @@ -526,7 +526,7 @@ static struct ip_set_type hash_netport_type __read_mostly = { .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, .dimension = IPSET_DIM_TWO, .family = AF_UNSPEC, - .revision = 0, + .revision = 1, .create = hash_netport_create, .create_policy = { [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, -- GitLab From 8962d87129ec0a820d17ac44cbf3f51010ad8db8 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 13 Apr 2011 08:47:32 -0400 Subject: [PATCH 0796/5560] ath5k: improve comments for optimized tx descriptor setup Comment the use of local variables to reduce the number of load/store operations on uncached memory, in hopes of not losing this optimization accidentally in the future. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/desc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 0391813befd1..dd7cd95c364a 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -184,6 +184,11 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, { struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; + + /* + * Use local variables for these to reduce load/store access on + * uncached memory + */ u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; tx_ctl = &desc->ud.ds_tx5212.tx_ctl; @@ -209,7 +214,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (tx_power > AR5K_TUNE_MAX_TXPOWER) tx_power = AR5K_TUNE_MAX_TXPOWER; - /* Clear descriptor */ + /* Clear descriptor status area */ memset(&desc->ud.ds_tx5212.tx_stat, 0, sizeof(desc->ud.ds_tx5212.tx_stat)); -- GitLab From 39d5a3ee355fa903ef4609402c79f570eb9fc4d2 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 15:40:12 -0300 Subject: [PATCH 0797/5560] Bluetooth: Move SREJ list to struct l2cap_chan As part of moving all the Channel related operation to struct l2cap_chan. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 13 ++++++------- net/bluetooth/l2cap_core.c | 22 +++++++++++----------- net/bluetooth/l2cap_sock.c | 1 - 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d05d91f2fd32..ec56d8861a4e 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -277,6 +277,11 @@ struct l2cap_conn_param_update_rsp { #define L2CAP_CONN_PARAM_REJECTED 0x0001 /* ----- L2CAP channels and connections ----- */ +struct srej_list { + __u8 tx_seq; + struct list_head list; +}; + struct l2cap_chan { struct sock *sk; __u8 ident; @@ -312,6 +317,7 @@ struct l2cap_chan { struct sk_buff_head srej_q; struct sk_buff_head busy_q; struct work_struct busy_work; + struct list_head srej_l; struct list_head list; }; @@ -350,12 +356,6 @@ struct l2cap_conn { /* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) #define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue) -#define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list) - -struct srej_list { - __u8 tx_seq; - struct list_head list; -}; struct l2cap_pinfo { struct bt_sock bt; @@ -385,7 +385,6 @@ struct l2cap_pinfo { __le16 sport; struct sk_buff_head tx_queue; - struct srej_list srej_l; struct l2cap_conn *conn; struct l2cap_chan *chan; }; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 7264119b64a6..9580d6cd55da 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -252,7 +252,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) skb_queue_purge(&chan->srej_q); skb_queue_purge(&chan->busy_q); - list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { + list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { list_del(&l->list); kfree(l); } @@ -1205,7 +1205,7 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan) control = L2CAP_SUPER_SELECT_REJECT; control |= L2CAP_CTRL_FINAL; - tail = list_entry(SREJ_LIST(chan->sk)->prev, struct srej_list, list); + tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; l2cap_send_sframe(chan, control); @@ -1596,6 +1596,8 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->srej_q); skb_queue_head_init(&chan->busy_q); + INIT_LIST_HEAD(&chan->srej_l); + INIT_WORK(&chan->busy_work, l2cap_busy_work); sk->sk_backlog_rcv = l2cap_ertm_data_rcv; @@ -3207,11 +3209,10 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) { - struct sock *sk = chan->sk; struct srej_list *l, *tmp; u16 control; - list_for_each_entry_safe(l, tmp, SREJ_LIST(sk), list) { + list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { if (l->tx_seq == tx_seq) { list_del(&l->list); kfree(l); @@ -3221,13 +3222,12 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; l2cap_send_sframe(chan, control); list_del(&l->list); - list_add_tail(&l->list, SREJ_LIST(sk)); + list_add_tail(&l->list, &chan->srej_l); } } static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) { - struct sock *sk = chan->sk; struct srej_list *new; u16 control; @@ -3239,7 +3239,7 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); new->tx_seq = chan->expected_tx_seq; chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; - list_add_tail(&new->list, SREJ_LIST(sk)); + list_add_tail(&new->list, &chan->srej_l); } chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; } @@ -3288,7 +3288,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont if (chan->conn_state & L2CAP_CONN_SREJ_SENT) { struct srej_list *first; - first = list_first_entry(SREJ_LIST(sk), + first = list_first_entry(&chan->srej_l, struct srej_list, list); if (tx_seq == first->tx_seq) { l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); @@ -3297,7 +3297,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont list_del(&first->list); kfree(first); - if (list_empty(SREJ_LIST(sk))) { + if (list_empty(&chan->srej_l)) { chan->buffer_seq = chan->buffer_seq_srej; chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; l2cap_send_ack(chan); @@ -3310,7 +3310,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0) goto drop; - list_for_each_entry(l, SREJ_LIST(sk), list) { + list_for_each_entry(l, &chan->srej_l, list) { if (l->tx_seq == tx_seq) { l2cap_resend_srejframe(chan, tx_seq); return 0; @@ -3332,7 +3332,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont BT_DBG("sk %p, Enter SREJ", sk); - INIT_LIST_HEAD(SREJ_LIST(sk)); + INIT_LIST_HEAD(&chan->srej_l); chan->buffer_seq_srej = chan->buffer_seq; __skb_queue_head_init(&chan->srej_q); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 55dee999af94..16a223bfa8f5 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1018,7 +1018,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) /* Default config options */ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; skb_queue_head_init(TX_QUEUE(sk)); - INIT_LIST_HEAD(SREJ_LIST(sk)); } static struct proto l2cap_proto = { -- GitLab From 49208c9c7b483098401683fef5cfbd66931ca643 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 15:59:54 -0300 Subject: [PATCH 0798/5560] Bluetooth: Remove some sk references from l2cap_core.c Change some BT_DBG messages and consequently remove some struct sock declarations. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9580d6cd55da..0edfa658090a 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -211,7 +211,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_sock_clear_timer(sk); - BT_DBG("sk %p, conn %p, err %d", sk, conn, err); + BT_DBG("chan %p, conn %p, err %d", chan, conn, err); if (conn) { /* Delete from channel list */ @@ -361,7 +361,7 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) if (pi->fcs == L2CAP_FCS_CRC16) hlen += 2; - BT_DBG("pi %p, control 0x%2.2x", pi, control); + BT_DBG("chan %p, control 0x%2.2x", chan, control); count = min_t(unsigned int, conn->mtu, hlen); control |= L2CAP_CTRL_FRAME_TYPE; @@ -982,7 +982,7 @@ static void l2cap_retrans_timeout(unsigned long arg) struct l2cap_chan *chan = (void *) arg; struct sock *sk = chan->sk; - BT_DBG("sk %p", sk); + BT_DBG("chan %p", chan); bh_lock_sock(sk); chan->retry_count = 1; @@ -1618,13 +1618,12 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) { - struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); struct l2cap_conf_req *req = data; struct l2cap_conf_rfc rfc = { .mode = pi->mode }; void *ptr = req->data; - BT_DBG("sk %p", sk); + BT_DBG("chan %p", chan); if (chan->num_conf_req || chan->num_conf_rsp) goto done; @@ -2972,7 +2971,6 @@ static int l2cap_ertm_reassembly_sdu(struct l2cap_chan *chan, struct sk_buff *sk static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) { - struct sock *sk = chan->sk; struct sk_buff *skb; u16 control; int err; @@ -3005,7 +3003,7 @@ static int l2cap_try_push_rx_skb(struct l2cap_chan *chan) chan->conn_state &= ~L2CAP_CONN_LOCAL_BUSY; chan->conn_state &= ~L2CAP_CONN_RNR_SENT; - BT_DBG("sk %p, Exit local busy", sk); + BT_DBG("chan %p, Exit local busy", chan); return 0; } @@ -3246,8 +3244,7 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) { - struct sock *sk = chan->sk; - struct l2cap_pinfo *pi = l2cap_pi(sk); + struct l2cap_pinfo *pi = l2cap_pi(chan->sk); u8 tx_seq = __get_txseq(rx_control); u8 req_seq = __get_reqseq(rx_control); u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; @@ -3301,7 +3298,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont chan->buffer_seq = chan->buffer_seq_srej; chan->conn_state &= ~L2CAP_CONN_SREJ_SENT; l2cap_send_ack(chan); - BT_DBG("sk %p, Exit SREJ_SENT", sk); + BT_DBG("chan %p, Exit SREJ_SENT", chan); } } else { struct srej_list *l; @@ -3330,7 +3327,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont chan->conn_state |= L2CAP_CONN_SREJ_SENT; - BT_DBG("sk %p, Enter SREJ", sk); + BT_DBG("chan %p, Enter SREJ", chan); INIT_LIST_HEAD(&chan->srej_l); chan->buffer_seq_srej = chan->buffer_seq; @@ -3383,9 +3380,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control) { - struct sock *sk = chan->sk; - - BT_DBG("sk %p, req_seq %d ctrl 0x%4.4x", sk, __get_reqseq(rx_control), + BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, __get_reqseq(rx_control), rx_control); chan->expected_ack_seq = __get_reqseq(rx_control); @@ -3633,7 +3628,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk sk = chan->sk; pi = l2cap_pi(sk); - BT_DBG("sk %p, len %d", sk, skb->len); + BT_DBG("chan %p, len %d", chan, skb->len); if (sk->sk_state != BT_CONNECTED) goto drop; @@ -3691,7 +3686,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk goto done; default: - BT_DBG("sk %p: bad mode 0x%2.2x", sk, pi->mode); + BT_DBG("chan %p: bad mode 0x%2.2x", chan, pi->mode); break; } -- GitLab From c916fbe45c1f30417fa28e62cbbfae295a3f315c Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 16:00:55 -0300 Subject: [PATCH 0799/5560] Bluetooth: Remove unneeded uninitialized_vars() That was unnecessary use of it. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0edfa658090a..5fc852a9ae59 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -623,7 +623,7 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) static void l2cap_le_conn_ready(struct l2cap_conn *conn) { - struct sock *parent, *uninitialized_var(sk); + struct sock *parent, *sk; struct l2cap_chan *chan; BT_DBG(""); -- GitLab From 58d35f87effa0235181a24d55576aaa756ef7312 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 4 Apr 2011 16:16:44 -0300 Subject: [PATCH 0800/5560] Bluetooth: Move tx queue to struct l2cap_chan tx_q is the queue used by ERTM mode. Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 4 ++-- net/bluetooth/l2cap_core.c | 40 +++++++++++++++++------------------ net/bluetooth/l2cap_sock.c | 7 +++--- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ec56d8861a4e..7a215a7f9e39 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -314,6 +314,8 @@ struct l2cap_chan { struct timer_list retrans_timer; struct timer_list monitor_timer; struct timer_list ack_timer; + struct sk_buff *tx_send_head; + struct sk_buff_head tx_q; struct sk_buff_head srej_q; struct sk_buff_head busy_q; struct work_struct busy_work; @@ -355,7 +357,6 @@ struct l2cap_conn { /* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) -#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue) struct l2cap_pinfo { struct bt_sock bt; @@ -384,7 +385,6 @@ struct l2cap_pinfo { __le16 sport; - struct sk_buff_head tx_queue; struct l2cap_conn *conn; struct l2cap_chan *chan; }; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5fc852a9ae59..97827506dc94 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -240,7 +240,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE)) goto free; - skb_queue_purge(TX_QUEUE(sk)); + skb_queue_purge(&chan->tx_q); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { struct srej_list *l, *tmp; @@ -477,7 +477,7 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, in sk = chan->sk; - skb_queue_purge(TX_QUEUE(sk)); + skb_queue_purge(&chan->tx_q); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { del_timer(&chan->retrans_timer); @@ -996,15 +996,14 @@ static void l2cap_retrans_timeout(unsigned long arg) static void l2cap_drop_acked_frames(struct l2cap_chan *chan) { - struct sock *sk = chan->sk; struct sk_buff *skb; - while ((skb = skb_peek(TX_QUEUE(sk))) && + while ((skb = skb_peek(&chan->tx_q)) && chan->unacked_frames) { if (bt_cb(skb)->tx_seq == chan->expected_ack_seq) break; - skb = skb_dequeue(TX_QUEUE(sk)); + skb = skb_dequeue(&chan->tx_q); kfree_skb(skb); chan->unacked_frames--; @@ -1037,7 +1036,7 @@ void l2cap_streaming_send(struct l2cap_chan *chan) struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; - while ((skb = skb_dequeue(TX_QUEUE(sk)))) { + while ((skb = skb_dequeue(&chan->tx_q))) { control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); @@ -1060,7 +1059,7 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) struct sk_buff *skb, *tx_skb; u16 control, fcs; - skb = skb_peek(TX_QUEUE(sk)); + skb = skb_peek(&chan->tx_q); if (!skb) return; @@ -1068,10 +1067,10 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) if (bt_cb(skb)->tx_seq == tx_seq) break; - if (skb_queue_is_last(TX_QUEUE(sk), skb)) + if (skb_queue_is_last(&chan->tx_q, skb)) return; - } while ((skb = skb_queue_next(TX_QUEUE(sk), skb))); + } while ((skb = skb_queue_next(&chan->tx_q, skb))); if (chan->remote_max_tx && bt_cb(skb)->retries == chan->remote_max_tx) { @@ -1112,7 +1111,7 @@ int l2cap_ertm_send(struct l2cap_chan *chan) if (sk->sk_state != BT_CONNECTED) return -ENOTCONN; - while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(chan))) { + while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) { if (chan->remote_max_tx && bt_cb(skb)->retries == chan->remote_max_tx) { @@ -1153,10 +1152,10 @@ int l2cap_ertm_send(struct l2cap_chan *chan) chan->frames_sent++; - if (skb_queue_is_last(TX_QUEUE(sk), skb)) - sk->sk_send_head = NULL; + if (skb_queue_is_last(&chan->tx_q, skb)) + chan->tx_send_head = NULL; else - sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); + chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); nsent++; } @@ -1166,11 +1165,10 @@ int l2cap_ertm_send(struct l2cap_chan *chan) static int l2cap_retransmit_frames(struct l2cap_chan *chan) { - struct sock *sk = chan->sk; int ret; - if (!skb_queue_empty(TX_QUEUE(sk))) - sk->sk_send_head = TX_QUEUE(sk)->next; + if (!skb_queue_empty(&chan->tx_q)) + chan->tx_send_head = chan->tx_q.next; chan->next_tx_seq = chan->expected_ack_seq; ret = l2cap_ertm_send(chan); @@ -1384,9 +1382,9 @@ int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t le len -= buflen; size += buflen; } - skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); - if (sk->sk_send_head == NULL) - sk->sk_send_head = sar_queue.next; + skb_queue_splice_tail(&sar_queue, &chan->tx_q); + if (chan->tx_send_head == NULL) + chan->tx_send_head = sar_queue.next; return size; } @@ -2319,7 +2317,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr chan->next_tx_seq = 0; chan->expected_tx_seq = 0; - __skb_queue_head_init(TX_QUEUE(sk)); + skb_queue_head_init(&chan->tx_q); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) l2cap_ertm_init(chan); @@ -2410,7 +2408,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr sk->sk_state = BT_CONNECTED; chan->next_tx_seq = 0; chan->expected_tx_seq = 0; - __skb_queue_head_init(TX_QUEUE(sk)); + skb_queue_head_init(&chan->tx_q); if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) l2cap_ertm_init(chan); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 16a223bfa8f5..b2bfa1e0d74e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -764,10 +764,10 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms err = PTR_ERR(skb); goto done; } - __skb_queue_tail(TX_QUEUE(sk), skb); + __skb_queue_tail(&pi->chan->tx_q, skb); - if (sk->sk_send_head == NULL) - sk->sk_send_head = skb; + if (pi->chan->tx_send_head == NULL) + pi->chan->tx_send_head = skb; } else { /* Segment SDU into multiples PDUs */ @@ -1017,7 +1017,6 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent) /* Default config options */ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; - skb_queue_head_init(TX_QUEUE(sk)); } static struct proto l2cap_proto = { -- GitLab From cd69a03af1106c486033df600c7945957ea5abeb Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 5 Apr 2011 15:24:40 -0300 Subject: [PATCH 0801/5560] Bluetooth: Fix wrong comparison in listen() We should check for the pi->scid there. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index b2bfa1e0d74e..473e5973d8fe 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -269,7 +269,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) goto done; } - if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->dcid) { + if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->scid) { bdaddr_t *src = &bt_sk(sk)->src; u16 psm; -- GitLab From 0733119c0bed37eda4bb832d049939a0dc53a233 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 5 Apr 2011 22:29:31 -0300 Subject: [PATCH 0802/5560] Bluetooth: Clean up ath3k_load_firmware() Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 5577ed656e2f..695d4414bd4c 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -138,9 +138,6 @@ static int ath3k_load_firmware(struct usb_device *udev, count -= size; } - kfree(send_buf); - return 0; - error: kfree(send_buf); return err; -- GitLab From 9f69bda6aa8b365169b4a6fd35432ee40574d661 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 7 Apr 2011 16:40:25 -0300 Subject: [PATCH 0803/5560] Bluetooth: Add proper handling of received LE data Despite it works, handling through l2cap_data_channel() is wrongs. That function should handle only connection oriented data. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 97827506dc94..c9c1f9257a91 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3728,6 +3728,36 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str return 0; } +static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) +{ + struct sock *sk; + + sk = l2cap_get_sock_by_scid(0, cid, conn->src); + 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) + goto drop; + + if (l2cap_pi(sk)->imtu < skb->len) + goto drop; + + if (!sock_queue_rcv_skb(sk, skb)) + goto done; + +drop: + kfree_skb(skb); + +done: + if (sk) + bh_unlock_sock(sk); + return 0; +} + static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) { struct l2cap_hdr *lh = (void *) skb->data; @@ -3757,6 +3787,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) l2cap_conless_channel(conn, psm, skb); break; + case L2CAP_CID_LE_DATA: + l2cap_att_channel(conn, cid, skb); + break; + default: l2cap_data_channel(conn, cid, skb); break; -- GitLab From e1ba1f15469903b6f443fbf00f069d169e3fba6d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Apr 2011 13:01:59 +0200 Subject: [PATCH 0804/5560] Bluetooth: Fix Out Of Band pairing when mgmt interface is disabled Use kernel stored remote Out Of Band data only if management interface is enabled. Otherwise HCI_OP_REMOTE_OOB_DATA_NEG_REPLY was sent to controller even if remote Out Of Band data was present in bluetoothd. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 7a3398d9cd65..c7eb073fe633 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2497,6 +2497,9 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, hci_dev_lock(hdev); + if (!test_bit(HCI_MGMT, &hdev->flags)) + goto unlock; + data = hci_find_remote_oob_data(hdev, &ev->bdaddr); if (data) { struct hci_cp_remote_oob_data_reply cp; @@ -2515,6 +2518,7 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, &cp); } +unlock: hci_dev_unlock(hdev); } -- GitLab From 78b4a56c28c096a1eb02f1d864eb450eb910e43d Mon Sep 17 00:00:00 2001 From: Jiejing Zhang Date: Thu, 7 Apr 2011 20:37:06 +0800 Subject: [PATCH 0805/5560] Bluetooth: hci_uart: check the return value of recv() Check the return value of hu->proto->recv() in hci_uart_tty_receive() the recv() may return error, check it, not add this to statistics. Signed-off-by: Jiejing Zhang Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/hci_ath.c | 7 ++++++- drivers/bluetooth/hci_ldisc.c | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index bd34406faaae..4093935ddf42 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -201,8 +201,13 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) /* Recv data */ static int ath_recv(struct hci_uart *hu, void *data, int count) { - if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) + int ret; + + ret = hci_recv_stream_fragment(hu->hdev, data, count); + if (ret < 0) { BT_ERR("Frame Reassembly Failed"); + return ret; + } return count; } diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 48ad2a7ab080..320f71803a2b 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -359,6 +359,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) */ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) { + int ret; struct hci_uart *hu = (void *)tty->disc_data; if (!hu || tty != hu->tty) @@ -368,8 +369,9 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f return; spin_lock(&hu->rx_lock); - hu->proto->recv(hu, (void *) data, count); - hu->hdev->stat.byte_rx += count; + ret = hu->proto->recv(hu, (void *) data, count); + if (ret > 0) + hu->hdev->stat.byte_rx += count; spin_unlock(&hu->rx_lock); tty_unthrottle(tty); -- GitLab From b86ed368f1f0b19de1918c57e4b056e73d5613a0 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 7 Apr 2011 18:53:45 -0300 Subject: [PATCH 0806/5560] Bluetooth: Check return value of hci_recv_stream_fragment() It may return error and in this case we do add to the stats. Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/hci_h4.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 7b8ad93e2c36..2fcd8b387d69 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) /* Recv data */ static int h4_recv(struct hci_uart *hu, void *data, int count) { - if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) + int ret; + + ret = hci_recv_stream_fragment(hu->hdev, data, count); + if (ret < 0) { BT_ERR("Frame Reassembly Failed"); + return ret; + } return count; } -- GitLab From 9f72c1d977e47a7d182d49ea131067cba0a96ab8 Mon Sep 17 00:00:00 2001 From: Kevin Gan Date: Fri, 8 Apr 2011 18:19:33 -0700 Subject: [PATCH 0807/5560] Bluetooth: btmrvl: support Marvell Bluetooth device SD8787 The SD8787 firmware image is shared with mwifiex driver. Whoever gets loaded first will be responsible for firmware downloading. Signed-off-by: Kevin Gan Signed-off-by: Tristan Xu Signed-off-by: Bing Zhao Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/Kconfig | 4 +- drivers/bluetooth/btmrvl_sdio.c | 124 ++++++++++++++++++++++++-------- drivers/bluetooth/btmrvl_sdio.h | 68 +++++++++--------- 3 files changed, 132 insertions(+), 64 deletions(-) diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 8e0de9a05867..11b41fd40c27 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -188,7 +188,7 @@ config BT_MRVL The core driver to support Marvell Bluetooth devices. This driver is required if you want to support - Marvell Bluetooth devices, such as 8688. + Marvell Bluetooth devices, such as 8688/8787. Say Y here to compile Marvell Bluetooth driver into the kernel or say M to compile it as module. @@ -201,7 +201,7 @@ config BT_MRVL_SDIO The driver for Marvell Bluetooth chipsets with SDIO interface. This driver is required if you want to use Marvell Bluetooth - devices with SDIO interface. Currently only SD8688 chipset is + devices with SDIO interface. Currently SD8688/SD8787 chipsets are supported. Say Y here to compile support for Marvell BT-over-SDIO driver diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index dcc2a6ec23f0..7f521d4ac657 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -49,15 +49,59 @@ static u8 user_rmmod; static u8 sdio_ireg; +static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = { + .cfg = 0x03, + .host_int_mask = 0x04, + .host_intstatus = 0x05, + .card_status = 0x20, + .sq_read_base_addr_a0 = 0x10, + .sq_read_base_addr_a1 = 0x11, + .card_fw_status0 = 0x40, + .card_fw_status1 = 0x41, + .card_rx_len = 0x42, + .card_rx_unit = 0x43, + .io_port_0 = 0x00, + .io_port_1 = 0x01, + .io_port_2 = 0x02, +}; +static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = { + .cfg = 0x00, + .host_int_mask = 0x02, + .host_intstatus = 0x03, + .card_status = 0x30, + .sq_read_base_addr_a0 = 0x40, + .sq_read_base_addr_a1 = 0x41, + .card_revision = 0x5c, + .card_fw_status0 = 0x60, + .card_fw_status1 = 0x61, + .card_rx_len = 0x62, + .card_rx_unit = 0x63, + .io_port_0 = 0x78, + .io_port_1 = 0x79, + .io_port_2 = 0x7a, +}; + static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { .helper = "sd8688_helper.bin", .firmware = "sd8688.bin", + .reg = &btmrvl_reg_8688, + .sd_blksz_fw_dl = 64, +}; + +static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { + .helper = NULL, + .firmware = "mrvl/sd8787_uapsta.bin", + .reg = &btmrvl_reg_8787, + .sd_blksz_fw_dl = 256, }; static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8688 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, + /* Marvell SD8787 Bluetooth device */ + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), + .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, { } /* Terminating entry */ }; @@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) u8 reg; int ret; - reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret); + reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret); if (!ret) card->rx_unit = reg; @@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) *dat = 0; - fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); + fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); if (ret) return -EIO; - fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); + fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret); if (ret) return -EIO; @@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat) u8 reg; int ret; - reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret); + reg = sdio_readb(card->func, card->reg->card_rx_len, &ret); if (!ret) *dat = (u16) reg << card->rx_unit; @@ -113,7 +157,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, { int ret; - sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret); + sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret); if (ret) { BT_ERR("Unable to enable the host interrupt!"); ret = -EIO; @@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, u8 host_int_mask; int ret; - host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret); + host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret); if (ret) return -EIO; host_int_mask &= ~mask; - sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret); + sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret); if (ret < 0) { BT_ERR("Unable to disable the host interrupt!"); return -EIO; @@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits) int ret; for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { - status = sdio_readb(card->func, CARD_STATUS_REG, &ret); + status = sdio_readb(card->func, card->reg->card_status, &ret); if (ret) goto failed; if ((status & bits) == bits) @@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) u8 base0, base1; void *tmpfwbuf = NULL; u8 *fwbuf; - u16 len; + u16 len, blksz_dl = card->sd_blksz_fw_dl; int txlen = 0, tx_blocks = 0, count = 0; ret = request_firmware(&fw_firmware, card->firmware, @@ -345,7 +389,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) for (tries = 0; tries < MAX_POLL_TRIES; tries++) { base0 = sdio_readb(card->func, - SQ_READ_BASE_ADDRESS_A0_REG, &ret); + card->reg->sq_read_base_addr_a0, &ret); if (ret) { BT_ERR("BASE0 register read failed:" " base0 = 0x%04X(%d)." @@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) goto done; } base1 = sdio_readb(card->func, - SQ_READ_BASE_ADDRESS_A1_REG, &ret); + card->reg->sq_read_base_addr_a1, &ret); if (ret) { BT_ERR("BASE1 register read failed:" " base1 = 0x%04X(%d)." @@ -403,20 +447,19 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) if (firmwarelen - offset < txlen) txlen = firmwarelen - offset; - tx_blocks = - (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE; + tx_blocks = (txlen + blksz_dl - 1) / blksz_dl; memcpy(fwbuf, &firmware[offset], txlen); } ret = sdio_writesb(card->func, card->ioport, fwbuf, - tx_blocks * SDIO_BLOCK_SIZE); + tx_blocks * blksz_dl); if (ret < 0) { BT_ERR("FW download, writesb(%d) failed @%d", count, offset); - sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, - &ret); + sdio_writeb(card->func, HOST_CMD53_FIN, + card->reg->cfg, &ret); if (ret) BT_ERR("writeb failed (CFG)"); } @@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) priv = card->priv; - ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); + ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret); if (ret) { BT_ERR("sdio_readb: read int status register failed"); return; @@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), - HOST_INTSTATUS_REG, &ret); + card->reg->host_intstatus, &ret); if (ret) { BT_ERR("sdio_writeb: clear int status register failed"); return; @@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) goto release_irq; } - reg = sdio_readb(func, IO_PORT_0_REG, &ret); + reg = sdio_readb(func, card->reg->io_port_0, &ret); if (ret < 0) { ret = -EIO; goto release_irq; @@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) card->ioport = reg; - reg = sdio_readb(func, IO_PORT_1_REG, &ret); + reg = sdio_readb(func, card->reg->io_port_1, &ret); if (ret < 0) { ret = -EIO; goto release_irq; @@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) card->ioport |= (reg << 8); - reg = sdio_readb(func, IO_PORT_2_REG, &ret); + reg = sdio_readb(func, card->reg->io_port_2, &ret); if (ret < 0) { ret = -EIO; goto release_irq; @@ -815,6 +858,8 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) { int ret = 0; + u8 fws0; + int pollnum = MAX_POLL_TRIES; if (!card || !card->func) { BT_ERR("card or function is NULL!"); @@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) goto done; } - ret = btmrvl_sdio_download_helper(card); + /* Check if other function driver is downloading the firmware */ + fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); if (ret) { - BT_ERR("Failed to download helper!"); + BT_ERR("Failed to read FW downloading status!"); ret = -EIO; goto done; } + if (fws0) { + BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0); + + /* Give other function more time to download the firmware */ + pollnum *= 10; + } else { + if (card->helper) { + ret = btmrvl_sdio_download_helper(card); + if (ret) { + BT_ERR("Failed to download helper!"); + ret = -EIO; + goto done; + } + } - if (btmrvl_sdio_download_fw_w_helper(card)) { - BT_ERR("Failed to download firmware!"); - ret = -EIO; - goto done; + if (btmrvl_sdio_download_fw_w_helper(card)) { + BT_ERR("Failed to download firmware!"); + ret = -EIO; + goto done; + } } - if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) { + if (btmrvl_sdio_verify_fw_download(card, pollnum)) { BT_ERR("FW failed to be active in time!"); ret = -ETIMEDOUT; goto done; @@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv) sdio_claim_host(card->func); - sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret); + sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret); sdio_release_host(card->func); @@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func, if (id->driver_data) { struct btmrvl_sdio_device *data = (void *) id->driver_data; - card->helper = data->helper; + card->helper = data->helper; card->firmware = data->firmware; + card->reg = data->reg; + card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; } if (btmrvl_sdio_register_dev(card) < 0) { @@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION); MODULE_LICENSE("GPL v2"); MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("sd8688.bin"); +MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h index 27329f107e5a..43d35a609ca9 100644 --- a/drivers/bluetooth/btmrvl_sdio.h +++ b/drivers/bluetooth/btmrvl_sdio.h @@ -47,44 +47,46 @@ /* Max retry number of CMD53 write */ #define MAX_WRITE_IOMEM_RETRY 2 -/* Host Control Registers */ -#define IO_PORT_0_REG 0x00 -#define IO_PORT_1_REG 0x01 -#define IO_PORT_2_REG 0x02 - -#define CONFIG_REG 0x03 -#define HOST_POWER_UP BIT(1) -#define HOST_CMD53_FIN BIT(2) - -#define HOST_INT_MASK_REG 0x04 -#define HIM_DISABLE 0xff -#define HIM_ENABLE (BIT(0) | BIT(1)) - -#define HOST_INTSTATUS_REG 0x05 -#define UP_LD_HOST_INT_STATUS BIT(0) -#define DN_LD_HOST_INT_STATUS BIT(1) - -/* Card Control Registers */ -#define SQ_READ_BASE_ADDRESS_A0_REG 0x10 -#define SQ_READ_BASE_ADDRESS_A1_REG 0x11 - -#define CARD_STATUS_REG 0x20 -#define DN_LD_CARD_RDY BIT(0) -#define CARD_IO_READY BIT(3) - -#define CARD_FW_STATUS0_REG 0x40 -#define CARD_FW_STATUS1_REG 0x41 -#define FIRMWARE_READY 0xfedc - -#define CARD_RX_LEN_REG 0x42 -#define CARD_RX_UNIT_REG 0x43 - +/* register bitmasks */ +#define HOST_POWER_UP BIT(1) +#define HOST_CMD53_FIN BIT(2) + +#define HIM_DISABLE 0xff +#define HIM_ENABLE (BIT(0) | BIT(1)) + +#define UP_LD_HOST_INT_STATUS BIT(0) +#define DN_LD_HOST_INT_STATUS BIT(1) + +#define DN_LD_CARD_RDY BIT(0) +#define CARD_IO_READY BIT(3) + +#define FIRMWARE_READY 0xfedc + + +struct btmrvl_sdio_card_reg { + u8 cfg; + u8 host_int_mask; + u8 host_intstatus; + u8 card_status; + u8 sq_read_base_addr_a0; + u8 sq_read_base_addr_a1; + u8 card_revision; + u8 card_fw_status0; + u8 card_fw_status1; + u8 card_rx_len; + u8 card_rx_unit; + u8 io_port_0; + u8 io_port_1; + u8 io_port_2; +}; struct btmrvl_sdio_card { struct sdio_func *func; u32 ioport; const char *helper; const char *firmware; + const struct btmrvl_sdio_card_reg *reg; + u16 sd_blksz_fw_dl; u8 rx_unit; struct btmrvl_private *priv; }; @@ -92,6 +94,8 @@ struct btmrvl_sdio_card { struct btmrvl_sdio_device { const char *helper; const char *firmware; + const struct btmrvl_sdio_card_reg *reg; + u16 sd_blksz_fw_dl; }; -- GitLab From 01b07e2d84c887b432353ead846f4497a33b5f5d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Apr 2011 23:39:10 -0700 Subject: [PATCH 0808/5560] ASoC: Move WM8915 FLL operations onto the CODEC Since the WM8915 FLL is not tied to a particular audio interface move it to a CODEC wide operation. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8915.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c index 3adad2872c7e..083609418bf4 100644 --- a/sound/soc/codecs/wm8915.c +++ b/sound/soc/codecs/wm8915.c @@ -1997,10 +1997,9 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, return 0; } -static int wm8915_set_fll(struct snd_soc_dai *dai, int fll_id, int source, +static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source, unsigned int Fref, unsigned int Fout) { - struct snd_soc_codec *codec = dai->codec; struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); struct _fll_div fll_div; unsigned long timeout; @@ -2776,6 +2775,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8915 = { .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets), .dapm_routes = wm8915_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes), + .set_pll = wm8915_set_fll, }; #define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ @@ -2788,7 +2788,6 @@ static struct snd_soc_dai_ops wm8915_dai_ops = { .set_fmt = wm8915_set_fmt, .hw_params = wm8915_hw_params, .set_sysclk = wm8915_set_sysclk, - .set_pll = wm8915_set_fll, }; static struct snd_soc_dai_driver wm8915_dai[] = { -- GitLab From 9a841ebb9cac3f1b7253bb01c304f89b1af25aba Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 12 Apr 2011 17:51:37 -0700 Subject: [PATCH 0809/5560] ASoC: Create card DAPM widgets early so they can be used in callbacks This helps with things like setting up the initial state. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1f114673e952..3b3a377d0874 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1878,6 +1878,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); #endif + if (card->dapm_widgets) + snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, + card->num_dapm_widgets); + /* initialise the sound card only once */ if (card->probe) { ret = card->probe(card); @@ -1911,9 +1915,6 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) card->controls, card->num_controls); - if (card->dapm_widgets) - snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, - card->num_dapm_widgets); if (card->dapm_routes) snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, card->num_dapm_routes); -- GitLab From 9b8dc66fbae53def2547df8c0a5cbe8924ea2b1f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 12 Apr 2011 17:24:39 -0700 Subject: [PATCH 0810/5560] ASoC: Initial audio support for Speyside on Cragganmore 6410 This is minimal code required to get audio out of the Speyside audio subsystem on the Wolfson Cragganmore 6410 reference platform. It sets up the link between the CPU and AIF1 of the WM8915 on the system, enabling audio playback via the headphone and speaker outputs of the device (which require no further configuration except runtime). It allows verification of basic functionality of the system. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/Kconfig | 6 ++ sound/soc/samsung/Makefile | 2 + sound/soc/samsung/speyside.c | 123 +++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 sound/soc/samsung/speyside.c diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index b8c7a2e0d21c..726af2ede795 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -170,3 +170,9 @@ config SND_SOC_SMDK_WM8580_PCM select SND_SAMSUNG_PCM help Say Y if you want to add support for SoC audio on the SMDK. + +config SND_SOC_SPEYSIDE + tristate "Audio support for Wolfson Speyside" + depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 + select SND_SAMSUNG_I2S + select SND_SOC_WM8915 diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 6c598fc51a01..683843a2744f 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -35,6 +35,7 @@ snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-goni-wm8994-objs := goni_wm8994.o snd-soc-smdk-spdif-objs := smdk_spdif.o snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o +snd-soc-speyside-objs := speyside.o obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o @@ -53,3 +54,4 @@ obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o +obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c new file mode 100644 index 000000000000..f6dcee7b218b --- /dev/null +++ b/sound/soc/samsung/speyside.c @@ -0,0 +1,123 @@ +/* + * Speyside audio support + * + * Copyright 2011 Wolfson Microelectronics + * + * 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. + */ + +#include +#include + +#include "../codecs/wm8915.h" + +static int speyside_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int ret; + + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, 0, WM8915_FLL_MCLK1, + 32768, 256 * 48000); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_FLL, + 256 * 48000, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops speyside_ops = { + .hw_params = speyside_hw_params, +}; + +static struct snd_soc_dai_link speyside_dai[] = { + { + .name = "CPU", + .stream_name = "CPU", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm8915-aif1", + .platform_name = "samsung-audio", + .codec_name = "wm8915.1-001a", + .ops = &speyside_ops, + }, +}; + +static struct snd_soc_card speyside = { + .name = "Speyside", + .dai_link = speyside_dai, + .num_links = ARRAY_SIZE(speyside_dai), +}; + +static __devinit int speyside_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &speyside; + int ret; + + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + return ret; + } + + return 0; +} + +static int __devexit speyside_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver speyside_driver = { + .driver = { + .name = "speyside", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = speyside_probe, + .remove = __devexit_p(speyside_remove), +}; + +static int __init speyside_audio_init(void) +{ + return platform_driver_register(&speyside_driver); +} +module_init(speyside_audio_init); + +static void __exit speyside_audio_exit(void) +{ + platform_driver_unregister(&speyside_driver); +} +module_exit(speyside_audio_exit); + +MODULE_DESCRIPTION("Speyside audio support"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:speyside"); -- GitLab From ecfb1adf5f037eaff0b678918d84a8febd9f1c3e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Apr 2011 23:09:15 -0700 Subject: [PATCH 0811/5560] ASoC: Add basic widgets for WM8915 Speyside Provide widgets for the basic widgets connected directly to the WM8915 on Speyside - the headphones, speaker, digital and analogue microphones. For the outputs this is just documentation, for the inputs this ensures that the relevant microphone biases are enabled when they are in use. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/speyside.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index f6dcee7b218b..6ec44a354a6d 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -63,10 +63,38 @@ static struct snd_soc_dai_link speyside_dai[] = { }, }; +static struct snd_soc_dapm_widget widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + + SND_SOC_DAPM_SPK("Main Speaker", NULL), + + SND_SOC_DAPM_MIC("Main AMIC", NULL), + SND_SOC_DAPM_MIC("Main DMIC", NULL), +}; + +static struct snd_soc_dapm_route audio_paths[] = { + { "IN1LP", NULL, "MICB2" }, + { "MICB2", NULL, "Main AMIC" }, + + { "DMIC1DAT", NULL, "MICB1" }, + { "DMIC2DAT", NULL, "MICB1" }, + { "MICB1", NULL, "Main DMIC" }, + + { "Headphone", NULL, "HPOUT1L" }, + { "Headphone", NULL, "HPOUT1R" }, + + { "Main Speaker", NULL, "SPKDAT" }, +}; + static struct snd_soc_card speyside = { .name = "Speyside", .dai_link = speyside_dai, .num_links = ARRAY_SIZE(speyside_dai), + + .dapm_widgets = widgets, + .num_dapm_widgets = ARRAY_SIZE(widgets), + .dapm_routes = audio_paths, + .num_dapm_routes = ARRAY_SIZE(audio_paths), }; static __devinit int speyside_probe(struct platform_device *pdev) -- GitLab From ea0a591a28b9249ea585f2cf8045e43f57f48fbb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Apr 2011 23:32:03 -0700 Subject: [PATCH 0812/5560] ASoC: Optimise clock management for WM8915 Speyside Dynamically enable and disable the FLL on the WM8915, configuring the system clock to 256fs for 48kHz when the device is active but reverting to using the input 32.768kHz clock directly at other times to support features such as jack detection with minimal power consumption. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/speyside.c | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 6ec44a354a6d..1e51750fd3a2 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -14,6 +14,33 @@ #include "../codecs/wm8915.h" +static int speyside_set_bias_level(struct snd_soc_card *card, + enum snd_soc_bias_level level) +{ + struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + int ret; + + switch (level) { + case SND_SOC_BIAS_STANDBY: + ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_MCLK1, + 32768, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, WM8915_FLL_MCLK1, + 0, 0, 0); + if (ret < 0) { + pr_err("Failed to stop FLL\n"); + return ret; + } + + default: + break; + } + + return 0; +} + static int speyside_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -51,6 +78,13 @@ static struct snd_soc_ops speyside_ops = { .hw_params = speyside_hw_params, }; +static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai *dai = rtd->codec_dai; + + return snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK1, 32768, 0); +} + static struct snd_soc_dai_link speyside_dai[] = { { .name = "CPU", @@ -59,6 +93,7 @@ static struct snd_soc_dai_link speyside_dai[] = { .codec_dai_name = "wm8915-aif1", .platform_name = "samsung-audio", .codec_name = "wm8915.1-001a", + .init = speyside_wm8915_init, .ops = &speyside_ops, }, }; @@ -91,6 +126,8 @@ static struct snd_soc_card speyside = { .dai_link = speyside_dai, .num_links = ARRAY_SIZE(speyside_dai), + .set_bias_level = speyside_set_bias_level, + .dapm_widgets = widgets, .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_paths, -- GitLab From ea3e98e75a6f38522450b66e22e34267977915ef Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 11 Apr 2011 23:42:25 -0700 Subject: [PATCH 0813/5560] ASoC: Support the sub speaker driver on Speyside Speyside includes a WM9081 configured as an external speaker driver taking an analogue input from HPOUT2 on the WM8915 on the system. Add support for this to the driver, using a prefix of "Sub" for the WM9081 controls to ensure we avoid collisions with controls on the WM8915. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/Kconfig | 1 + sound/soc/samsung/speyside.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 726af2ede795..459566bfcd35 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -176,3 +176,4 @@ config SND_SOC_SPEYSIDE depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 select SND_SAMSUNG_I2S select SND_SOC_WM8915 + select SND_SOC_WM9081 diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 1e51750fd3a2..0adaf7fe6814 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -13,6 +13,7 @@ #include #include "../codecs/wm8915.h" +#include "../codecs/wm9081.h" static int speyside_set_bias_level(struct snd_soc_card *card, enum snd_soc_bias_level level) @@ -98,6 +99,30 @@ static struct snd_soc_dai_link speyside_dai[] = { }, }; +static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) +{ + snd_soc_dapm_nc_pin(dapm, "LINEOUT"); + + /* At any time the WM9081 is active it will have this clock */ + return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, + 48000 * 256, 0); +} + +static struct snd_soc_aux_dev speyside_aux_dev[] = { + { + .name = "wm9081", + .codec_name = "wm9081.1-006c", + .init = speyside_wm9081_init, + }, +}; + +static struct snd_soc_codec_conf speyside_codec_conf[] = { + { + .dev_name = "wm9081.1-006c", + .name_prefix = "Sub", + }, +}; + static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), @@ -118,6 +143,11 @@ static struct snd_soc_dapm_route audio_paths[] = { { "Headphone", NULL, "HPOUT1L" }, { "Headphone", NULL, "HPOUT1R" }, + { "Sub IN1", NULL, "HPOUT2L" }, + { "Sub IN2", NULL, "HPOUT2R" }, + + { "Main Speaker", NULL, "Sub SPKN" }, + { "Main Speaker", NULL, "Sub SPKP" }, { "Main Speaker", NULL, "SPKDAT" }, }; @@ -125,6 +155,10 @@ static struct snd_soc_card speyside = { .name = "Speyside", .dai_link = speyside_dai, .num_links = ARRAY_SIZE(speyside_dai), + .aux_dev = speyside_aux_dev, + .num_aux_devs = ARRAY_SIZE(speyside_aux_dev), + .codec_conf = speyside_codec_conf, + .num_configs = ARRAY_SIZE(speyside_codec_conf), .set_bias_level = speyside_set_bias_level, -- GitLab From 68688e78ed4bc8d1a811ca29e2f8681561706db3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 12 Apr 2011 00:00:36 -0700 Subject: [PATCH 0814/5560] ASoC: Add Speyside headset jack detection support Speyside makes use of support the WM8915 has for detecting the polarity of the microphone and ground connections on headsets, using a GPIO to control the polarity of the ground connection and switching between the two microphone bias supplies available on the device in order to do so. As a result of this the detection support is more involved than for most other CODECs, using a callback to configure the current polarity of the jack and translate this into the board-specific connections required for the current scenario. On Android some additional work is required to hook this up to the application layer as the Android HeadsetObserver monitors a custom drivers/switch API rather than the standard Linux APIs. This can be done by either updating HeadsetObserver or modifying the ALSA core to report via drivers/switch as well. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/speyside.c | 78 +++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 0adaf7fe6814..612a39e0e108 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -11,10 +11,14 @@ #include #include +#include +#include #include "../codecs/wm8915.h" #include "../codecs/wm9081.h" +#define WM8915_HPSEL_GPIO 214 + static int speyside_set_bias_level(struct snd_soc_card *card, enum snd_soc_bias_level level) { @@ -79,11 +83,74 @@ static struct snd_soc_ops speyside_ops = { .hw_params = speyside_hw_params, }; +static struct snd_soc_jack speyside_headset; + +/* Headset jack detection DAPM pins */ +static struct snd_soc_jack_pin speyside_headset_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, +}; + +/* Default the headphone selection to active high */ +static int speyside_jack_polarity; + +static int speyside_get_micbias(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + if (speyside_jack_polarity && (strcmp(source->name, "MICB1") == 0)) + return 1; + if (!speyside_jack_polarity && (strcmp(source->name, "MICB2") == 0)) + return 1; + + return 0; +} + +static void speyside_set_polarity(struct snd_soc_codec *codec, + int polarity) +{ + speyside_jack_polarity = !polarity; + gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity); + + /* Re-run DAPM to make sure we're using the correct mic bias */ + snd_soc_dapm_sync(&codec->dapm); +} + static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *dai = rtd->codec_dai; + struct snd_soc_codec *codec = rtd->codec; + int ret; + + ret = snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK1, 32768, 0); + if (ret < 0) + return ret; + + ret = gpio_request(WM8915_HPSEL_GPIO, "HP_SEL"); + if (ret != 0) + pr_err("Failed to request HP_SEL GPIO: %d\n", ret); + gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity); - return snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK1, 32768, 0); + ret = snd_soc_jack_new(codec, "Headset", + SND_JACK_HEADSET | SND_JACK_BTN_0, + &speyside_headset); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&speyside_headset, + ARRAY_SIZE(speyside_headset_pins), + speyside_headset_pins); + if (ret) + return ret; + + wm8915_detect(codec, &speyside_headset, speyside_set_polarity); + + return 0; } static struct snd_soc_dai_link speyside_dai[] = { @@ -125,6 +192,7 @@ static struct snd_soc_codec_conf speyside_codec_conf[] = { static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_SPK("Main Speaker", NULL), @@ -133,7 +201,15 @@ static struct snd_soc_dapm_widget widgets[] = { }; static struct snd_soc_dapm_route audio_paths[] = { + { "IN1RN", NULL, "MICB1" }, + { "IN1RP", NULL, "MICB1" }, + { "IN1RN", NULL, "MICB2" }, + { "IN1RP", NULL, "MICB2" }, + { "MICB1", NULL, "Headset Mic", speyside_get_micbias }, + { "MICB2", NULL, "Headset Mic", speyside_get_micbias }, + { "IN1LP", NULL, "MICB2" }, + { "IN1RN", NULL, "MICB1" }, { "MICB2", NULL, "Main AMIC" }, { "DMIC1DAT", NULL, "MICB1" }, -- GitLab From ea0e60de385a984ab54d6694b03119d1706f548e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 12 Apr 2011 00:09:53 -0700 Subject: [PATCH 0815/5560] ASoC: Add pin switches for fixed analogue inputs and outputs on Speyside Pin switches enable direct control of the DAPM state from userspace, enabling simple enabling and disabling of the path. This is especially useful for outputs such as the speaker which are composed of several physical devices as it allows them to be controlled as a group. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/speyside.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 612a39e0e108..e171a321889f 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -190,6 +190,12 @@ static struct snd_soc_codec_conf speyside_codec_conf[] = { }, }; +static const struct snd_kcontrol_new controls[] = { + SOC_DAPM_PIN_SWITCH("Main Speaker"), + SOC_DAPM_PIN_SWITCH("Main DMIC"), + SOC_DAPM_PIN_SWITCH("Main AMIC"), +}; + static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -238,6 +244,8 @@ static struct snd_soc_card speyside = { .set_bias_level = speyside_set_bias_level, + .controls = controls, + .num_controls = ARRAY_SIZE(controls), .dapm_widgets = widgets, .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_paths, -- GitLab From 556e4fb1d801b0f977b1522e14fb06e2f3059f4c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 12 Apr 2011 14:15:10 -0700 Subject: [PATCH 0816/5560] ASoC: Add stub baseband link on Speyside Demonstrate the connection of a baseband to the system. We add a DAI for the link to the baseband. This will become visible to the application layer - audio should be started from the application layer using an application such as this: http://opensource.wolfsonmicro.com/~gg/bluetooth-pcm/bluetooth_pcm.c which starts up audio as for CPU based playback and record up to the point where data is streamed. Due to non-availability of baseband simulation hardware we reuse the configuration for the CPU link with the CODEC acting as clock master, allowing signals to be observed with a scope. A more standard system would have separate configuration for the baseband with its own ops structure and operations. Normally the baseband would be clock master as the baseband audio will be synchronised to the external telephony network. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/speyside.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index e171a321889f..a0c14a87e23d 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -164,6 +164,15 @@ static struct snd_soc_dai_link speyside_dai[] = { .init = speyside_wm8915_init, .ops = &speyside_ops, }, + { + .name = "Baseband", + .stream_name = "Baseband", + .cpu_dai_name = "wm8915-aif2", + .codec_dai_name = "wm1250-ev1", + .codec_name = "wm1250-ev1.1-0027", + .platform_name = "samsung-audio", + .ops = &speyside_ops, + }, }; static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) @@ -194,6 +203,8 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Main Speaker"), SOC_DAPM_PIN_SWITCH("Main DMIC"), SOC_DAPM_PIN_SWITCH("Main AMIC"), + SOC_DAPM_PIN_SWITCH("WM1250 Input"), + SOC_DAPM_PIN_SWITCH("WM1250 Output"), }; static struct snd_soc_dapm_widget widgets[] = { -- GitLab From b7a5d14c607093de1a030e9933bc8c95ab2afd3f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 12 Apr 2011 17:37:52 -0700 Subject: [PATCH 0817/5560] ASoC: Mark Speyside widgets as ignoring suspend Allow audio paths through the Speyside system to be kept active while the system is suspended (for example, when on a voice call) by marking all the external widgets and the DAI link to the WM1250-EV1 baseband module as ignoring suspend. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/speyside.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index a0c14a87e23d..337855a3f2fe 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -153,6 +153,19 @@ static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int speyside_late_probe(struct snd_soc_card *card) +{ + snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); + snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); + snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); + snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); + snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); + snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); + + return 0; +} + static struct snd_soc_dai_link speyside_dai[] = { { .name = "CPU", @@ -172,6 +185,7 @@ static struct snd_soc_dai_link speyside_dai[] = { .codec_name = "wm1250-ev1.1-0027", .platform_name = "samsung-audio", .ops = &speyside_ops, + .ignore_suspend = 1, }, }; @@ -261,6 +275,8 @@ static struct snd_soc_card speyside = { .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_paths, .num_dapm_routes = ARRAY_SIZE(audio_paths), + + .late_probe = speyside_late_probe, }; static __devinit int speyside_probe(struct platform_device *pdev) -- GitLab From d06e48db1670b29b3f62f1dfe4a36af237d5aa0d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Apr 2011 19:31:01 +0200 Subject: [PATCH 0818/5560] ASoC: Make struct snd_soc_card's dapm_widgets and dapm_routes const Those should not be modified (and are not) by the core code, so make them const. This also makes them consistent with the same members of snd_soc_codec. Signed-off-by: Lars-Peter Clausen Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 435cb83c7f48..cb6b18b6eece 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -755,9 +755,9 @@ struct snd_soc_card { /* * Card-specific routes and widgets. */ - struct snd_soc_dapm_widget *dapm_widgets; + const struct snd_soc_dapm_widget *dapm_widgets; int num_dapm_widgets; - struct snd_soc_dapm_route *dapm_routes; + const struct snd_soc_dapm_route *dapm_routes; int num_dapm_routes; struct work_struct deferred_resume_work; -- GitLab From 13319699113a78e90625ece124666d3ee53033f6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Apr 2011 19:31:03 +0200 Subject: [PATCH 0819/5560] ASoC: JZ4740: Convert qi_lb60 codec to table based DAPM setup Use the newly introduced dapm_widgets, dpam_routes and fields of the snd_soc_card struct to setup DAPM. Signed-off-by: Lars-Peter Clausen Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/jz4740/qi_lb60.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 49723e3e7e38..875abc94a00b 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -70,12 +70,6 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - snd_soc_dapm_new_controls(dapm, qi_lb60_widgets, - ARRAY_SIZE(qi_lb60_widgets)); - snd_soc_dapm_add_routes(dapm, qi_lb60_routes, - ARRAY_SIZE(qi_lb60_routes)); - snd_soc_dapm_sync(dapm); - return 0; } @@ -93,6 +87,11 @@ static struct snd_soc_card qi_lb60 = { .name = "QI LB60", .dai_link = &qi_lb60_dai, .num_links = 1, + + .dapm_widgets = qi_lb60_widgets, + .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets), + .dapm_routes = qi_lb60_routes, + .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), }; static struct platform_device *qi_lb60_snd_device; -- GitLab From c6f0ede7c563497f6d7fef847a965d7fd63d86f9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Apr 2011 19:31:04 +0200 Subject: [PATCH 0820/5560] ASoC: JZ4740: qi_lb60: Use gpio_request_array to request and setup gpios This patch changes the qi_lb60 setup code to use gpio_request_array instead of manually calling gpio_request and gpio_direction_output for each gpio. Doing so makes the code a bit more compact. Signed-off-by: Lars-Peter Clausen Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/jz4740/qi_lb60.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 875abc94a00b..8c4e84bcc320 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -96,6 +96,11 @@ static struct snd_soc_card qi_lb60 = { static struct platform_device *qi_lb60_snd_device; +static const struct gpio qi_lb60_gpios[] = { + { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" }, + { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, +}; + static int __init qi_lb60_init(void) { int ret; @@ -105,23 +110,12 @@ static int __init qi_lb60_init(void) if (!qi_lb60_snd_device) return -ENOMEM; - ret = gpio_request(QI_LB60_SND_GPIO, "SND"); + ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); if (ret) { - pr_err("qi_lb60 snd: Failed to request SND GPIO(%d): %d\n", - QI_LB60_SND_GPIO, ret); + pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret); goto err_device_put; } - ret = gpio_request(QI_LB60_AMP_GPIO, "AMP"); - if (ret) { - pr_err("qi_lb60 snd: Failed to request AMP GPIO(%d): %d\n", - QI_LB60_AMP_GPIO, ret); - goto err_gpio_free_snd; - } - - gpio_direction_output(QI_LB60_SND_GPIO, 0); - gpio_direction_output(QI_LB60_AMP_GPIO, 0); - platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); ret = platform_device_add(qi_lb60_snd_device); @@ -134,10 +128,8 @@ static int __init qi_lb60_init(void) err_unset_pdata: platform_set_drvdata(qi_lb60_snd_device, NULL); -/*err_gpio_free_amp:*/ - gpio_free(QI_LB60_AMP_GPIO); -err_gpio_free_snd: - gpio_free(QI_LB60_SND_GPIO); +/*err_gpio_free_array:*/ + gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); err_device_put: platform_device_put(qi_lb60_snd_device); @@ -147,9 +139,8 @@ module_init(qi_lb60_init); static void __exit qi_lb60_exit(void) { - gpio_free(QI_LB60_AMP_GPIO); - gpio_free(QI_LB60_SND_GPIO); platform_device_unregister(qi_lb60_snd_device); + gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); } module_exit(qi_lb60_exit); -- GitLab From 621206b76825f24ccb650b9f59c18c17f6760a4c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Apr 2011 19:31:05 +0200 Subject: [PATCH 0821/5560] ASoC: JZ4740: qi_lb60: Use the SND_SOC_DAPM_EVENT_OFF for the speakers status Use SND_SOC_DAPM_EVENT_OFF for determining whether the speaker should be turned on or off instead of open coding it. Signed-off-by: Lars-Peter Clausen Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/jz4740/qi_lb60.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 8c4e84bcc320..c5fc339f68f1 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -27,11 +27,7 @@ static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, struct snd_kcontrol *ctrl, int event) { - int on = 0; - if (event & SND_SOC_DAPM_POST_PMU) - on = 1; - else if (event & SND_SOC_DAPM_PRE_PMD) - on = 0; + int on = !SND_SOC_DAPM_EVENT_OFF(event); gpio_set_value(QI_LB60_SND_GPIO, on); gpio_set_value(QI_LB60_AMP_GPIO, on); -- GitLab From 674479124f8cbc4b5507d914ccd63ad08fd5326e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 12 Apr 2011 19:33:29 +0200 Subject: [PATCH 0822/5560] ASoC: codecs: JZ4740: Convert to table based controls and DAPM setup Use the newly introduced dapm_widgets, dpam_routes and controls fields of the snd_soc_dai_driver struct to setup controls and DAPM. Signed-off-by: Lars-Peter Clausen Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/jz4740.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index f5ccdbf7ebc6..e373f8f06907 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -294,20 +294,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) { - struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); - snd_soc_add_controls(codec, jz4740_codec_controls, - ARRAY_SIZE(jz4740_codec_controls)); - - snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets, - ARRAY_SIZE(jz4740_codec_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes, - ARRAY_SIZE(jz4740_codec_dapm_routes)); - jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; @@ -348,6 +337,13 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { .reg_cache_default = jz4740_codec_regs, .reg_word_size = sizeof(u32), .reg_cache_size = 2, + + .controls = jz4740_codec_controls, + .num_controls = ARRAY_SIZE(jz4740_codec_controls), + .dapm_widgets = jz4740_codec_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets), + .dapm_routes = jz4740_codec_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes), }; static int __devinit jz4740_codec_probe(struct platform_device *pdev) -- GitLab From 8b5933c380fc66a6311739f9b36a812383f82141 Mon Sep 17 00:00:00 2001 From: amit salecha Date: Thu, 7 Apr 2011 01:58:42 +0000 Subject: [PATCH 0823/5560] net: ethtool support to configure number of channels Ethtool support to configure RX, TX and other channels. combined field in struct ethtool_channels to reflect set of channel (RX, TX or other). Other channel can be link interrupts, SR-IOV coordination etc. ETHTOOL_GCHANNELS will report max and current number of RX channels, max and current number of TX channels, max and current number of other channel or max and current number of combined channel. Number of channel can be modify upto max number of channel through ETHTOOL_SCHANNELS command. Ben Hutchings: o define 'combined' and 'other' types. Most multiqueue drivers pair up RX and TX queues so that most channels combine RX and TX work. o Please could you use a kernel-doc comment to describe the structure. Signed-off-by: Amit Kumar Salecha Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 36 ++++++++++++++++++++++++++++++++++++ net/core/ethtool.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 12cfbd0be2ee..ad22a68c2e5d 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -229,6 +229,34 @@ struct ethtool_ringparam { __u32 tx_pending; }; +/** + * struct ethtool_channels - configuring number of network channel + * @cmd: ETHTOOL_{G,S}CHANNELS + * @max_rx: Read only. Maximum number of receive channel the driver support. + * @max_tx: Read only. Maximum number of transmit channel the driver support. + * @max_other: Read only. Maximum number of other channel the driver support. + * @max_combined: Read only. Maximum number of combined channel the driver + * support. Set of queues RX, TX or other. + * @rx_count: Valid values are in the range 1 to the max_rx. + * @tx_count: Valid values are in the range 1 to the max_tx. + * @other_count: Valid values are in the range 1 to the max_other. + * @combined_count: Valid values are in the range 1 to the max_combined. + * + * This can be used to configure RX, TX and other channels. + */ + +struct ethtool_channels { + __u32 cmd; + __u32 max_rx; + __u32 max_tx; + __u32 max_other; + __u32 max_combined; + __u32 rx_count; + __u32 tx_count; + __u32 other_count; + __u32 combined_count; +}; + /* for configuring link flow control parameters */ struct ethtool_pauseparam { __u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ @@ -818,6 +846,9 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * Returns a negative error code or zero. * @set_rxfh_indir: Set the contents of the RX flow hash indirection table. * Returns a negative error code or zero. + * @get_channels: Get number of channels. + * @set_channels: Set number of channels. Returns a negative error code or + * zero. * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must @@ -891,6 +922,9 @@ struct ethtool_ops { struct ethtool_rxfh_indir *); int (*set_rxfh_indir)(struct net_device *, const struct ethtool_rxfh_indir *); + void (*get_channels)(struct net_device *, struct ethtool_channels *); + int (*set_channels)(struct net_device *, struct ethtool_channels *); + }; #endif /* __KERNEL__ */ @@ -959,6 +993,8 @@ struct ethtool_ops { #define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */ #define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */ +#define ETHTOOL_GCHANNELS 0x0000003c /* Get no of channels */ +#define ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 43ef09fedd6e..41dee2de13ad 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1446,6 +1446,35 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) return dev->ethtool_ops->set_ringparam(dev, &ringparam); } +static noinline_for_stack int ethtool_get_channels(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS }; + + if (!dev->ethtool_ops->get_channels) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_channels(dev, &channels); + + if (copy_to_user(useraddr, &channels, sizeof(channels))) + return -EFAULT; + return 0; +} + +static noinline_for_stack int ethtool_set_channels(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_channels channels; + + if (!dev->ethtool_ops->set_channels) + return -EOPNOTSUPP; + + if (copy_from_user(&channels, useraddr, sizeof(channels))) + return -EFAULT; + + return dev->ethtool_ops->set_channels(dev, &channels); +} + static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; @@ -2007,6 +2036,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_SGRO: rc = ethtool_set_one_feature(dev, useraddr, ethcmd); break; + case ETHTOOL_GCHANNELS: + rc = ethtool_get_channels(dev, useraddr); + break; + case ETHTOOL_SCHANNELS: + rc = ethtool_set_channels(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } -- GitLab From b19f7f71b6fa5e0c49f65082044b8a2ff1009f00 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 13 Apr 2011 05:03:24 +0000 Subject: [PATCH 0824/5560] macb: Add rx overrun counter Signed-off-by: Alexander Stein Signed-off-by: David S. Miller --- drivers/net/macb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 2cb4e792f871..629bd2649c0c 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -576,6 +576,11 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) * add that if/when we get our hands on a full-blown MII PHY. */ + if (status & MACB_BIT(ISR_ROVR)) { + /* We missed at least one packet */ + bp->hw_stats.rx_overruns++; + } + if (status & MACB_BIT(HRESP)) { /* * TODO: Reset the hardware, and maybe move the printk @@ -1024,7 +1029,8 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev) hwstat->rx_jabbers + hwstat->rx_undersize_pkts + hwstat->rx_length_mismatch); - nstat->rx_over_errors = hwstat->rx_resource_errors; + nstat->rx_over_errors = hwstat->rx_resource_errors + + hwstat->rx_overruns; nstat->rx_crc_errors = hwstat->rx_fcs_errors; nstat->rx_frame_errors = hwstat->rx_align_errors; nstat->rx_fifo_errors = hwstat->rx_overruns; -- GitLab From 74ae2fd7d326750d973920c30d5269596724ca71 Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Wed, 13 Apr 2011 11:51:43 -0700 Subject: [PATCH 0825/5560] stmmac: review Wol and enable the Unicast support Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/dwmac1000_core.c | 5 +++-- drivers/net/stmmac/stmmac_ethtool.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index 6ae4c3f4c63c..f20455cbfbbc 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -178,10 +178,11 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode) { unsigned int pmt = 0; - if (mode == WAKE_MAGIC) { + if (mode & WAKE_MAGIC) { CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n"); pmt |= power_down | magic_pkt_en; - } else if (mode == WAKE_UCAST) { + } + if (mode & WAKE_UCAST) { CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n"); pmt |= global_unicast; } diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index 156a805c6c23..0e61ac8707cb 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -308,7 +308,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) spin_lock_irq(&priv->lock); if (device_can_wakeup(priv->device)) { - wol->supported = WAKE_MAGIC; + wol->supported = WAKE_MAGIC | WAKE_UCAST; wol->wolopts = priv->wolopts; } spin_unlock_irq(&priv->lock); @@ -317,7 +317,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct stmmac_priv *priv = netdev_priv(dev); - u32 support = WAKE_MAGIC; + u32 support = WAKE_MAGIC | WAKE_UCAST; if (!device_can_wakeup(priv->device)) return -EINVAL; -- GitLab From 12488e01fb2b06bb3f6ee137efc88e29d827817e Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Fri, 8 Apr 2011 14:38:27 +0530 Subject: [PATCH 0826/5560] mwl8k: interrupt handling changes We do not need to enable all the interrupts in mwl8k_probe_hw. We need to enable only MWL8K_A2H_INT_OPC_DONE interrupt for sending commands to the firmware. Keep the other interrupts masked in mwl8k_probe_hw. Also, in mwl8k_start, where we expect other interrupts, enable only those interrupts we are interested in. Signed-off-by: Nishant Sarmukadam Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index fb472f4924d0..d2416709ba52 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -4284,6 +4284,8 @@ static int mwl8k_start(struct ieee80211_hw *hw) /* Enable interrupts */ iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); + iowrite32(MWL8K_A2H_EVENTS, + priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); rc = mwl8k_fw_lock(hw); if (!rc) { @@ -5282,7 +5284,8 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY| MWL8K_A2H_INT_BA_WATCHDOG, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); - iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); + iowrite32(MWL8K_A2H_INT_OPC_DONE, + priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); rc = request_irq(priv->pdev->irq, mwl8k_interrupt, IRQF_SHARED, MWL8K_NAME, hw); -- GitLab From 8e26a0303614e766f993b1ac4a5bfbf80436d9dd Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 12 Apr 2011 18:23:16 +0200 Subject: [PATCH 0827/5560] ath9k: introduce ATH9K_{PCI,AHB} config options Currently ath9k only available in menuconfig if PCI bus support is enabled. However the driver is required for the built-in wireless MACs of the Atheros AR9130/AR9132 SoCs. These SoCs have no PCI controller, the wireless MAC is connected to the AHB bus on them. Introduce separated config options for the supported buses, in order to allow building of ath9h without PCI bus support. As a bonus, this patch removes the cross-reference of the ATHEROS_AR71XX option which is not present in the kernel. Cc: Luis R. Rodriguez Cc: Vasanthakumar Thiagarajan Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Kconfig | 21 ++++++++++++++++++++- drivers/net/wireless/ath/ath9k/Makefile | 4 ++-- drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index ad57a6d23110..d9ff8413ab9a 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -5,7 +5,7 @@ config ATH9K_COMMON config ATH9K tristate "Atheros 802.11n wireless cards support" - depends on PCI && MAC80211 + depends on MAC80211 select ATH9K_HW select MAC80211_LEDS select LEDS_CLASS @@ -23,6 +23,25 @@ config ATH9K If you choose to build a module, it'll be called ath9k. +config ATH9K_PCI + bool "Atheros ath9k PCI/PCIe bus support" + depends on ATH9K && PCI + default PCI + ---help--- + This option enables the PCI bus support in ath9k. + + Say Y, if you have a compatible PCI/PCIe wireless card. + +config ATH9K_AHB + bool "Atheros ath9k AHB bus support" + depends on ATH9K + default n + ---help--- + This option enables the AHB bus support in ath9k. + + Say Y, if you have a SoC with a compatible built-in + wireless MAC. Say N if unsure. + config ATH9K_DEBUGFS bool "Atheros ath9k debugging" depends on ATH9K && DEBUG_FS diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 4d66ca8042eb..ca4c436e0f65 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -6,8 +6,8 @@ ath9k-y += beacon.o \ xmit.o \ ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o -ath9k-$(CONFIG_PCI) += pci.o -ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o +ath9k-$(CONFIG_ATH9K_PCI) += pci.o +ath9k-$(CONFIG_ATH9K_AHB) += ahb.o ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o obj-$(CONFIG_ATH9K) += ath9k.o diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 38835bc324b2..77ad407e9fa3 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -665,7 +665,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); bool ath9k_uses_beacons(int type); -#ifdef CONFIG_PCI +#ifdef CONFIG_ATH9K_PCI int ath_pci_init(void); void ath_pci_exit(void); #else @@ -673,7 +673,7 @@ static inline int ath_pci_init(void) { return 0; }; static inline void ath_pci_exit(void) {}; #endif -#ifdef CONFIG_ATHEROS_AR71XX +#ifdef CONFIG_ATH9K_AHB int ath_ahb_init(void); void ath_ahb_exit(void); #else -- GitLab From 4114fa21465ec7ee9526173676d3122a98bbbbd8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 12 Apr 2011 19:15:22 +0200 Subject: [PATCH 0828/5560] mac80211: receive EAP frames from a station in an AP VLAN on the main AP This makes it easier to handle moving stations to VLAN interfaces that are part of a different bridge. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rx.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 359fc394a3b0..54858a68abd7 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1586,7 +1586,7 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) } static int -__ieee80211_data_to_8023(struct ieee80211_rx_data *rx) +__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control) { struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; @@ -1594,6 +1594,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) struct ethhdr *ehdr; int ret; + *port_control = false; if (ieee80211_has_a4(hdr->frame_control) && sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) return -1; @@ -1612,11 +1613,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) return -1; ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type); - if (ret < 0 || !check_port_control) + if (ret < 0) return ret; ehdr = (struct ethhdr *) rx->skb->data; - if (ehdr->h_proto != rx->sdata->control_port_protocol) + if (ehdr->h_proto == rx->sdata->control_port_protocol) + *port_control = true; + else if (check_port_control) return -1; return 0; @@ -1917,6 +1920,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) struct net_device *dev = sdata->dev; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; __le16 fc = hdr->frame_control; + bool port_control; int err; if (unlikely(!ieee80211_is_data(hdr->frame_control))) @@ -1933,13 +1937,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) sdata->vif.type == NL80211_IFTYPE_AP) return RX_DROP_MONITOR; - err = __ieee80211_data_to_8023(rx); + err = __ieee80211_data_to_8023(rx, &port_control); if (unlikely(err)) return RX_DROP_UNUSABLE; if (!ieee80211_frame_allowed(rx, fc)) return RX_DROP_MONITOR; + if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && + unlikely(port_control) && sdata->bss) { + sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, + u.ap); + dev = sdata->dev; + rx->sdata = sdata; + } + rx->skb->dev = dev; dev->stats.rx_packets++; -- GitLab From d0805c1c5758f8fd16c88bf1efa8fb4be4408ce1 Mon Sep 17 00:00:00 2001 From: Brian Cavagnolo Date: Tue, 12 Apr 2011 11:06:28 -0700 Subject: [PATCH 0829/5560] mwl8k: use traffic threshold to decide when to start ampdu Currently, ampdu stream is created on the first qos packet to an HT sta. The overhead of setting up the BA session may not be justified if the outgoing packet rate is minimal (e.g., ping). So we only allow ampdu streams after seeing a critical number of packets in an arbitrary one-second interval. Based on work by Nishant Sarmukadam Signed-off-by: Brian Cavagnolo Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 45 +++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index d2416709ba52..28ebaec80be6 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -289,10 +289,17 @@ struct mwl8k_vif { #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) +struct tx_traffic_info { + u32 start_time; + u32 pkts; +}; + +#define MWL8K_MAX_TID 8 struct mwl8k_sta { /* Index into station database. Returned by UPDATE_STADB. */ u8 peer_id; u8 is_ampdu_allowed; + struct tx_traffic_info tx_stats[MWL8K_MAX_TID]; }; #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv)) @@ -1754,6 +1761,41 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) return NULL; } +#define MWL8K_AMPDU_PACKET_THRESHOLD 64 +static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid) +{ + struct mwl8k_sta *sta_info = MWL8K_STA(sta); + struct tx_traffic_info *tx_stats; + + BUG_ON(tid >= MWL8K_MAX_TID); + tx_stats = &sta_info->tx_stats[tid]; + + return sta_info->is_ampdu_allowed && + tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD; +} + +static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) +{ + struct mwl8k_sta *sta_info = MWL8K_STA(sta); + struct tx_traffic_info *tx_stats; + + BUG_ON(tid >= MWL8K_MAX_TID); + tx_stats = &sta_info->tx_stats[tid]; + + if (tx_stats->start_time == 0) + tx_stats->start_time = jiffies; + + /* reset the packet count after each second elapses. If the number of + * packets ever exceeds the ampdu_min_traffic threshold, we will allow + * an ampdu stream to be started. + */ + if (jiffies - tx_stats->start_time > HZ) { + tx_stats->pkts = 0; + tx_stats->start_time = 0; + } else + tx_stats->pkts++; +} + static void mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) { @@ -1840,6 +1882,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) skb->protocol != cpu_to_be16(ETH_P_PAE) && sta->ht_cap.ht_supported && priv->ap_fw) { tid = qos & 0xf; + mwl8k_tx_count_packet(sta, tid); spin_lock(&priv->stream_lock); stream = mwl8k_lookup_stream(hw, sta->addr, tid); if (stream != NULL) { @@ -1880,7 +1923,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) * prevents sequence number mismatch at the recepient * as described above. */ - if (MWL8K_STA(sta)->is_ampdu_allowed) { + if (mwl8k_ampdu_allowed(sta, tid)) { stream = mwl8k_add_stream(hw, sta, tid); if (stream != NULL) start_ba_session = true; -- GitLab From 9efabad2b228ef820f5ce969baa62860cf65b9ea Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:33 +0530 Subject: [PATCH 0830/5560] ath9k_htc: Remove AR7010 v1.0 support All the AR7010 devices supoprted by ath9k_htc are based on version v1.1, so remove support for v1.0. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f1b8af64569c..3d53d9899628 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -17,11 +17,9 @@ #include "htc.h" /* identify firmware images */ -#define FIRMWARE_AR7010 "ar7010.fw" #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" #define FIRMWARE_AR9271 "ar9271.fw" -MODULE_FIRMWARE(FIRMWARE_AR7010); MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); MODULE_FIRMWARE(FIRMWARE_AR9271); @@ -1026,10 +1024,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, /* Find out which firmware to load */ if (IS_AR7010_DEVICE(id->driver_info)) - if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) - hif_dev->fw_name = FIRMWARE_AR7010_1_1; - else - hif_dev->fw_name = FIRMWARE_AR7010; + hif_dev->fw_name = FIRMWARE_AR7010_1_1; else hif_dev->fw_name = FIRMWARE_AR9271; -- GitLab From ce18f391aa872a910e7798c340b6cf22d02c77a2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:42 +0530 Subject: [PATCH 0831/5560] ath9k_htc: Rename firmware Since the new FW requires backward incompatible host driver changes, rename the FW to allow older driver versions to work with the older FW. 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 3d53d9899628..23094b70d6eb 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -17,8 +17,8 @@ #include "htc.h" /* identify firmware images */ -#define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" -#define FIRMWARE_AR9271 "ar9271.fw" +#define FIRMWARE_AR7010_1_1 "htc_7010.fw" +#define FIRMWARE_AR9271 "htc_9271.fw" MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); MODULE_FIRMWARE(FIRMWARE_AR9271); -- GitLab From 29bbfb2491316f9a3888e74b0de7fccdbde67aaa Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:51 +0530 Subject: [PATCH 0832/5560] ath9k_htc: Add a WMI command to get the firmware version Also, update the wiphy information and use the correct device pointer when registering. This would fix ethtool. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 ++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 32 +++++++++++++++++++ drivers/net/wireless/ath/ath9k/wmi.c | 2 ++ drivers/net/wireless/ath/ath9k/wmi.h | 6 ++++ 4 files changed, 43 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ec47be94b74f..9544cd7fd440 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -388,6 +388,9 @@ struct ath9k_htc_priv { struct htc_target *htc; struct wmi *wmi; + u16 fw_version_major; + u16 fw_version_minor; + enum htc_endpoint_id wmi_cmd_ep; enum htc_endpoint_id beacon_ep; enum htc_endpoint_id cab_ep; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8303b34bdc90..6bbfca58deda 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -782,6 +782,32 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } +static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) +{ + struct ieee80211_hw *hw = priv->hw; + struct wmi_fw_version cmd_rsp; + int ret; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_GET_FW_VERSION); + if (ret) + return -EINVAL; + + priv->fw_version_major = be16_to_cpu(cmd_rsp.major); + priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor); + + snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d", + priv->fw_version_major, + priv->fw_version_minor); + + dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n", + priv->fw_version_major, + priv->fw_version_minor); + + return 0; +} + static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid, char *product, u32 drv_info) { @@ -801,6 +827,10 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, common = ath9k_hw_common(ah); ath9k_set_hw_capab(priv, hw); + error = ath9k_init_firmware_version(priv); + if (error != 0) + goto err_fw; + /* Initialize regulatory */ error = ath_regd_init(&common->regulatory, priv->hw->wiphy, ath9k_reg_notifier); @@ -861,6 +891,8 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, err_tx: /* Nothing */ err_regd: + /* Nothing */ +err_fw: ath9k_deinit_priv(priv); err_init: return error; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index d3d24904f62f..267a98fcf5f2 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -23,6 +23,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_ECHO_CMDID"; case WMI_ACCESS_MEMORY_CMDID: return "WMI_ACCESS_MEMORY_CMDID"; + case WMI_GET_FW_VERSION: + return "WMI_GET_FW_VERSION"; case WMI_DISABLE_INTR_CMDID: return "WMI_DISABLE_INTR_CMDID"; case WMI_ENABLE_INTR_CMDID: diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 42084277522d..6a36572b6fb8 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -31,11 +31,17 @@ struct wmi_cmd_hdr { __be16 seq_no; } __packed; +struct wmi_fw_version { + __be16 major; + __be16 minor; + +} __packed; enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, /* Commands to Target */ + WMI_GET_FW_VERSION, WMI_DISABLE_INTR_CMDID, WMI_ENABLE_INTR_CMDID, WMI_RX_LINK_CMDID, -- GitLab From 1c165c972b040f9ce199b8d8d3cc4f619872cba5 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:22:59 +0530 Subject: [PATCH 0833/5560] ath9k_htc: Fix WMI and beacon header Match the beacon header with that of the firmware. Also, the firmware reports the TSF for an SWBA, so store it. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/wmi.c | 7 ++++++- drivers/net/wireless/ath/ath9k/wmi.h | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 9544cd7fd440..cf7909ec0769 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -96,8 +96,8 @@ struct tx_mgmt_hdr { } __packed; struct tx_beacon_header { - u8 len_changed; u8 vif_index; + u8 len_changed; u16 rev; } __packed; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 267a98fcf5f2..96171a2c6873 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -156,6 +156,7 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, struct wmi_cmd_hdr *hdr; u16 cmd_id; void *wmi_event; + struct wmi_event_swba *swba; #ifdef CONFIG_ATH9K_HTC_DEBUGFS __be32 txrate; #endif @@ -170,7 +171,11 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); switch (cmd_id) { case WMI_SWBA_EVENTID: - wmi->beacon_pending = *(u8 *)wmi_event; + swba = (struct wmi_event_swba *) wmi_event; + + wmi->tsf = be64_to_cpu(swba->tsf); + wmi->beacon_pending = swba->beacon_pending; + tasklet_schedule(&wmi->drv_priv->swba_tasklet); break; case WMI_FATAL_EVENTID: diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 6a36572b6fb8..2fa91a941a72 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -36,6 +36,11 @@ struct wmi_fw_version { __be16 minor; } __packed; + +struct wmi_event_swba { + __be64 tsf; + u8 beacon_pending; +}; enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, @@ -106,6 +111,7 @@ struct wmi { u32 cmd_rsp_len; bool stopped; + u64 tsf; u8 beacon_pending; spinlock_t wmi_lock; -- GitLab From 832f6a18fc2aead14954c081ece03b7a5b425f81 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:08 +0530 Subject: [PATCH 0834/5560] ath9k_htc: Add beacon slots Beacon transmission is now handled through a slot mechanism. This allows multiple beaconing interfaces to be be present. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 13 +- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 123 ++++++++++++++++-- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 5 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 12 +- drivers/net/wireless/ath/ath9k/wmi.c | 4 +- 5 files changed, 138 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index cf7909ec0769..31c649605d79 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -244,6 +244,7 @@ struct ath9k_htc_vif { u8 index; u16 seq_no; bool beacon_configured; + int bslot; }; struct ath9k_vif_iter_data { @@ -351,10 +352,14 @@ struct ath_led { int brightness; }; +#define BSTUCK_THRESHOLD 10 + struct htc_beacon_config { + struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; u16 beacon_interval; u16 dtim_period; u16 bmiss_timeout; + u32 bmiss_cnt; }; struct ath_btcoex { @@ -414,7 +419,6 @@ struct ath9k_htc_priv { u16 txpowlimit; u16 nvifs; u16 nstations; - u32 bmiss_cnt; bool rearm_ani; bool reconfig_beacon; @@ -425,7 +429,6 @@ struct ath9k_htc_priv { bool tx_queues_stop; spinlock_t tx_lock; - struct ieee80211_vif *vif; struct htc_beacon_config cur_beacon_conf; unsigned int rxfilter; struct tasklet_struct swba_tasklet; @@ -473,11 +476,15 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) void ath9k_htc_reset(struct ath9k_htc_priv *priv); +void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); +void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); -void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); +void ath9k_htc_swba(struct ath9k_htc_priv *priv); void ath9k_htc_rxep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 8f56158e5887..b561f703e467 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -172,12 +172,13 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, imask |= ATH9K_INT_SWBA; ath_dbg(common, ATH_DBG_CONFIG, - "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", + "AP Beacon config, intval: %d, nexttbtt: %u " + "imask: 0x%x\n", bss_conf->beacon_interval, nexttbtt, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); - priv->bmiss_cnt = 0; + priv->cur_beacon_conf.bmiss_cnt = 0; htc_imask = cpu_to_be32(imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); } @@ -214,7 +215,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); - priv->bmiss_cnt = 0; + priv->cur_beacon_conf.bmiss_cnt = 0; htc_imask = cpu_to_be32(imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); } @@ -225,9 +226,11 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, dev_kfree_skb_any(skb); } -void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) +static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, + int slot) { - struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; + struct ieee80211_vif *vif; + struct ath9k_htc_vif *avp; struct tx_beacon_header beacon_hdr; struct ath9k_htc_tx_ctl tx_ctl; struct ieee80211_tx_info *info; @@ -237,21 +240,18 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); - /* FIXME: Handle BMISS */ - if (beacon_pending != 0) { - priv->bmiss_cnt++; - return; - } - spin_lock_bh(&priv->beacon_lock); + vif = priv->cur_beacon_conf.bslot[slot]; + avp = (struct ath9k_htc_vif *)vif->drv_priv; + if (unlikely(priv->op_flags & OP_SCANNING)) { spin_unlock_bh(&priv->beacon_lock); return; } /* Get a new beacon */ - beacon = ieee80211_beacon_get(priv->hw, priv->vif); + beacon = ieee80211_beacon_get(priv->hw, vif); if (!beacon) { spin_unlock_bh(&priv->beacon_lock); return; @@ -276,6 +276,69 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) spin_unlock_bh(&priv->beacon_lock); } +static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + unsigned long flags; + u64 tsf; + u32 tsftu; + u16 intval; + int slot; + + intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; + + spin_lock_irqsave(&priv->wmi->wmi_lock, flags); + tsf = priv->wmi->tsf; + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + + tsftu = TSF_TO_TU(tsf >> 32, tsf); + slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; + slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; + + ath_dbg(common, ATH_DBG_BEACON, + "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", + slot, tsf, tsftu, intval); + + return slot; +} + +void ath9k_htc_swba(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + unsigned long flags; + int slot; + + spin_lock_irqsave(&priv->wmi->wmi_lock, flags); + if (priv->wmi->beacon_pending != 0) { + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + priv->cur_beacon_conf.bmiss_cnt++; + if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { + ath_dbg(common, ATH_DBG_BEACON, + "Beacon stuck, HW reset\n"); + ath9k_htc_reset(priv); + } + return; + } + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + + if (priv->cur_beacon_conf.bmiss_cnt) { + ath_dbg(common, ATH_DBG_BEACON, + "Resuming beacon xmit after %u misses\n", + priv->cur_beacon_conf.bmiss_cnt); + priv->cur_beacon_conf.bmiss_cnt = 0; + } + + slot = ath9k_htc_choose_bslot(priv); + spin_lock_bh(&priv->beacon_lock); + if (priv->cur_beacon_conf.bslot[slot] == NULL) { + spin_unlock_bh(&priv->beacon_lock); + return; + } + spin_unlock_bh(&priv->beacon_lock); + + ath9k_htc_send_beacon(priv, slot); +} + /* Currently, only for IBSS */ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) { @@ -307,6 +370,42 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) } } +void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + int i = 0; + + spin_lock_bh(&priv->beacon_lock); + for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) { + if (priv->cur_beacon_conf.bslot[i] == NULL) { + avp->bslot = i; + break; + } + } + + priv->cur_beacon_conf.bslot[avp->bslot] = vif; + spin_unlock_bh(&priv->beacon_lock); + + ath_dbg(common, ATH_DBG_CONFIG, + "Added interface at beacon slot: %d\n", avp->bslot); +} + +void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + + spin_lock_bh(&priv->beacon_lock); + priv->cur_beacon_conf.bslot[avp->bslot] = NULL; + spin_unlock_bh(&priv->beacon_lock); + + ath_dbg(common, ATH_DBG_CONFIG, + "Removed interface at beacon slot: %d\n", avp->bslot); +} + static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { bool *beacon_configured = (bool *)data; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 6bbfca58deda..9405e0ad7032 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -643,7 +643,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, { struct ath_hw *ah = NULL; struct ath_common *common; - int ret = 0, csz = 0; + int i, ret = 0, csz = 0; priv->op_flags |= OP_INVALID; @@ -711,6 +711,9 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, if (ret) goto err_queues; + for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) + priv->cur_beacon_conf.bslot[i] = NULL; + ath9k_init_crypto(priv); ath9k_init_channels_rates(priv); ath9k_init_misc(priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index db8c0c044e9e..293a9b38e22e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1281,9 +1281,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, priv->vif_slot |= (1 << avp->index); priv->nvifs++; - priv->vif = vif; INC_VIF(priv, vif->type); + + if ((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) + ath9k_htc_assign_bslot(priv, vif); + ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && @@ -1321,9 +1325,13 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, priv->vif_slot &= ~(1 << avp->index); ath9k_htc_remove_station(priv, vif, NULL); - priv->vif = NULL; DEC_VIF(priv, vif->type); + + if ((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) + ath9k_htc_remove_bslot(priv, vif); + ath9k_htc_set_opmode(priv); /* diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 96171a2c6873..a39552b3077b 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -126,7 +126,7 @@ void ath9k_swba_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - ath9k_htc_swba(priv, priv->wmi->beacon_pending); + ath9k_htc_swba(priv); } void ath9k_fatal_work(struct work_struct *work) @@ -173,8 +173,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, case WMI_SWBA_EVENTID: swba = (struct wmi_event_swba *) wmi_event; + spin_lock(&wmi->wmi_lock); wmi->tsf = be64_to_cpu(swba->tsf); wmi->beacon_pending = swba->beacon_pending; + spin_unlock(&wmi->wmi_lock); tasklet_schedule(&wmi->drv_priv->swba_tasklet); break; -- GitLab From 9b674a0207c9b75ddcdcdb07e46843fac8267507 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:17 +0530 Subject: [PATCH 0835/5560] ath9k_htc: Add TSF adjust capability In multi-interface mode, beacons/probe responses that are sent out must have their timestamp field updated. Calculate the TSF adjustment value for each beaconing interface and set it in the frame properly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 ++ .../net/wireless/ath/ath9k/htc_drv_beacon.c | 36 +++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 12 ++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 31c649605d79..87e4ca911a58 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -245,6 +245,7 @@ struct ath9k_htc_vif { u16 seq_no; bool beacon_configured; int bslot; + __le64 tsfadjust; }; struct ath9k_vif_iter_data { @@ -480,6 +481,8 @@ void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); +void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index b561f703e467..2fad613add51 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -234,6 +234,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct tx_beacon_header beacon_hdr; struct ath9k_htc_tx_ctl tx_ctl; struct ieee80211_tx_info *info; + struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; u8 *tx_fhdr; @@ -257,6 +258,13 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, return; } + /* + * Update the TSF adjust value here, the HW will + * add this value for every beacon. + */ + mgmt = (struct ieee80211_mgmt *)beacon->data; + mgmt->u.beacon.timestamp = avp->tsfadjust; + info = IEEE80211_SKB_CB(beacon); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = @@ -406,6 +414,34 @@ void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, "Removed interface at beacon slot: %d\n", avp->bslot); } +/* + * Calculate the TSF adjustment value for all slots + * other than zero. + */ +void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv; + struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; + u64 tsfadjust; + + if (avp->bslot == 0) + return; + + /* + * The beacon interval cannot be different for multi-AP mode, + * and we reach here only for VIF slots greater than zero, + * so beacon_interval is guaranteed to be set in cur_conf. + */ + tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; + avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); + + ath_dbg(common, ATH_DBG_CONFIG, + "tsfadjust is: %llu for bslot: %d\n", + (unsigned long long)tsfadjust, avp->bslot); +} + static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { bool *beacon_configured = (bool *)data; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 293a9b38e22e..6926ac0d5e5c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1291,8 +1291,10 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && - !(priv->op_flags & OP_ANI_RUNNING)) + !(priv->op_flags & OP_ANI_RUNNING)) { + ath9k_hw_set_tsfadjust(priv->ah, 1); ath9k_htc_start_ani(priv); + } ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); @@ -1652,6 +1654,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { ath_dbg(common, ATH_DBG_CONFIG, "Beacon enabled for BSS: %pM\n", bss_conf->bssid); + ath9k_htc_set_tsfadjust(priv, vif); priv->op_flags |= OP_ENABLE_BEACON; ath9k_htc_beacon_config(priv, vif); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 4a4f27ba96af..b3f94850821e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -82,11 +82,12 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr; + struct ieee80211_mgmt *mgmt; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; - struct ath9k_htc_vif *avp; + struct ath9k_htc_vif *avp = NULL; struct ath9k_htc_tx_ctl tx_ctl; enum htc_endpoint_id epid; u16 qnum; @@ -195,6 +196,15 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); + /* + * Set the TSF adjust value for probe response + * frame also. + */ + if (avp && unlikely(ieee80211_is_probe_resp(fc))) { + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.probe_resp.timestamp = avp->tsfadjust; + } + tx_ctl.type = ATH9K_HTC_NORMAL; mgmt_hdr.node_idx = sta_idx; -- GitLab From 2493a547ee81e6daca812d5dd7cf9357aebc379b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:26 +0530 Subject: [PATCH 0836/5560] ath9k_htc: Configure the beacon queue Set operating parameters (cwmin, cwmax) for the beacon queue in AP mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 77 +++++++++++-------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 2fad613add51..7aafd2179398 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -18,6 +18,50 @@ #define FUDGE 2 +void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) +{ + struct ath_hw *ah = priv->ah; + struct ath9k_tx_queue_info qi, qi_be; + + memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); + memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); + + ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); + + if (priv->ah->opmode == NL80211_IFTYPE_AP) { + qi.tqi_aifs = 1; + qi.tqi_cwmin = 0; + qi.tqi_cwmax = 0; + } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { + int qnum = priv->hwq_map[WME_AC_BE]; + + ath9k_hw_get_txq_props(ah, qnum, &qi_be); + + qi.tqi_aifs = qi_be.tqi_aifs; + + /* + * For WIFI Beacon Distribution + * Long slot time : 2x cwmin + * Short slot time : 4x cwmin + */ + if (ah->slottime == ATH9K_SLOT_TIME_20) + qi.tqi_cwmin = 2*qi_be.tqi_cwmin; + else + qi.tqi_cwmin = 4*qi_be.tqi_cwmin; + + qi.tqi_cwmax = qi_be.tqi_cwmax; + + } + + if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { + ath_err(ath9k_hw_common(ah), + "Unable to update beacon queue %u!\n", priv->beaconq); + } else { + ath9k_hw_resettxqueue(ah, priv->beaconq); + } +} + + static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, struct htc_beacon_config *bss_conf) { @@ -176,6 +220,8 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, "imask: 0x%x\n", bss_conf->beacon_interval, nexttbtt, imask); + ath9k_htc_beaconq_config(priv); + WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); priv->cur_beacon_conf.bmiss_cnt = 0; @@ -347,37 +393,6 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv) ath9k_htc_send_beacon(priv, slot); } -/* Currently, only for IBSS */ -void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) -{ - struct ath_hw *ah = priv->ah; - struct ath9k_tx_queue_info qi, qi_be; - int qnum = priv->hwq_map[WME_AC_BE]; - - memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); - memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); - - ath9k_hw_get_txq_props(ah, qnum, &qi_be); - - qi.tqi_aifs = qi_be.tqi_aifs; - /* For WIFI Beacon Distribution - * Long slot time : 2x cwmin - * Short slot time : 4x cwmin - */ - if (ah->slottime == ATH9K_SLOT_TIME_20) - qi.tqi_cwmin = 2*qi_be.tqi_cwmin; - else - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; - qi.tqi_cwmax = qi_be.tqi_cwmax; - - if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { - ath_err(ath9k_hw_common(ah), - "Unable to update beacon queue %u!\n", qnum); - } else { - ath9k_hw_resettxqueue(ah, priv->beaconq); - } -} - void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif) { -- GitLab From 7d547eb4bb664c5a6b7c8790c2ecb0aec5d15385 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:34 +0530 Subject: [PATCH 0837/5560] ath9k_htc: Handle buffered frames in AP mode Use the CAB endpoint to send buffered multicast or broadcast frames after each SWBA event. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 6 ++- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 43 +++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 5 ++- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 14 ++++-- 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 87e4ca911a58..a072a9eb3f3e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -292,6 +292,7 @@ struct ath9k_htc_tx_ctl { #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) +#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) @@ -301,6 +302,7 @@ struct ath_tx_stats { u32 skb_queued; u32 skb_completed; u32 skb_dropped; + u32 cab_queued; u32 queue_stats[WME_NUM_AC]; }; @@ -324,6 +326,7 @@ struct ath9k_debug { #define TX_STAT_INC(c) do { } while (0) #define RX_STAT_INC(c) do { } while (0) +#define CAB_STAT_INC do { } while (0) #define TX_QSTAT_INC(c) do { } while (0) @@ -505,7 +508,8 @@ void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); -int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); +int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, + struct sk_buff *skb, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 7aafd2179398..c96779c24296 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -272,6 +272,48 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, dev_kfree_skb_any(skb); } +static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, + int slot) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ieee80211_vif *vif; + struct sk_buff *skb; + struct ieee80211_hdr *hdr; + int padpos, padsize, ret; + + spin_lock_bh(&priv->beacon_lock); + + vif = priv->cur_beacon_conf.bslot[slot]; + + skb = ieee80211_get_buffered_bc(priv->hw, vif); + + while(skb) { + hdr = (struct ieee80211_hdr *) skb->data; + + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len > padpos) { + if (skb_headroom(skb) < padsize) { + dev_kfree_skb_any(skb); + goto next; + } + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, padpos); + } + + ret = ath9k_htc_tx_start(priv, skb, true); + if (ret != 0) { + ath_dbg(common, ATH_DBG_FATAL, + "Failed to send CAB frame\n"); + dev_kfree_skb_any(skb); + } + next: + skb = ieee80211_get_buffered_bc(priv->hw, vif); + } + + spin_unlock_bh(&priv->beacon_lock); +} + static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, int slot) { @@ -390,6 +432,7 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv) } spin_unlock_bh(&priv->beacon_lock); + ath9k_htc_send_buffered(priv, slot); ath9k_htc_send_beacon(priv, slot); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9405e0ad7032..b1c68bff72a6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -748,7 +748,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_HOST_BROADCAST_PS_BUFFERING; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 6926ac0d5e5c..8f38075d1240 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -797,6 +797,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "SKBs dropped", priv->debug.tx_stats.skb_dropped); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CAB queued", + priv->debug.tx_stats.cab_queued); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "BE queued", @@ -1054,7 +1057,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) memmove(skb->data, skb->data + padsize, padpos); } - ret = ath9k_htc_tx_start(priv, skb); + ret = ath9k_htc_tx_start(priv, skb, false); if (ret != 0) { if (ret == -ENOMEM) { ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index b3f94850821e..0e2855893669 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -79,7 +79,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, return error; } -int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) +int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, + struct sk_buff *skb, bool is_cab) { struct ieee80211_hdr *hdr; struct ieee80211_mgmt *mgmt; @@ -170,6 +171,12 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) tx_fhdr = skb_push(skb, sizeof(tx_hdr)); memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); + if (is_cab) { + CAB_STAT_INC; + epid = priv->cab_ep; + goto send; + } + qnum = skb_get_queue_mapping(skb); switch (qnum) { @@ -222,7 +229,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); epid = priv->mgmt_ep; } - +send: return htc_send(priv->htc, skb, epid, &tx_ctl); } @@ -326,7 +333,8 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, } else if ((ep_id == priv->data_bk_ep) || (ep_id == priv->data_be_ep) || (ep_id == priv->data_vi_ep) || - (ep_id == priv->data_vo_ep)) { + (ep_id == priv->data_vo_ep) || + (ep_id == priv->cab_ep)) { skb_pull(skb, sizeof(struct tx_frame_hdr)); } else { ath_err(common, "Unsupported TX EPID: %d\n", ep_id); -- GitLab From b0a6ba983e3663bf256ca2e79d17bb846878cd9e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:44 +0530 Subject: [PATCH 0838/5560] ath9k_htc: Fix beacon miss under heavy load Transmission of beacons becomes erratic when TX load is high, since the latency involved in the generation of a SWBA interrupt on the target to the actual sending of a beacon is quite high for USB devices. Fix this by adjusting the beacon response time. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 7 ++++ .../net/wireless/ath/ath9k/htc_drv_beacon.c | 39 ++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index a072a9eb3f3e..133fc6dc3929 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -358,6 +358,13 @@ struct ath_led { #define BSTUCK_THRESHOLD 10 +/* + * Adjust these when the max. no of beaconing interfaces is + * increased. + */ +#define DEFAULT_SWBA_RESPONSE 40 /* in TUs */ +#define MIN_SWBA_RESPONSE 10 /* in TUs */ + struct htc_beacon_config { struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF]; u16 beacon_interval; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index c96779c24296..48bc28823f6f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -198,6 +198,15 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, intval /= ATH9K_HTC_MAX_BCN_VIF; nexttbtt = intval; + /* + * To reduce beacon misses under heavy TX load, + * set the beacon response time to a larger value. + */ + if (intval > DEFAULT_SWBA_RESPONSE) + priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; + else + priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; + if (priv->op_flags & OP_TSF_RESET) { ath9k_hw_reset_tsf(priv->ah); priv->op_flags &= ~OP_TSF_RESET; @@ -216,9 +225,10 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, imask |= ATH9K_INT_SWBA; ath_dbg(common, ATH_DBG_CONFIG, - "AP Beacon config, intval: %d, nexttbtt: %u " + "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d " "imask: 0x%x\n", - bss_conf->beacon_interval, nexttbtt, imask); + bss_conf->beacon_interval, nexttbtt, + priv->ah->config.sw_beacon_response_time, imask); ath9k_htc_beaconq_config(priv); @@ -252,12 +262,22 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, nexttbtt += intval; } while (nexttbtt < tsftu); + /* + * Only one IBSS interfce is allowed. + */ + if (intval > DEFAULT_SWBA_RESPONSE) + priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE; + else + priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; + if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; ath_dbg(common, ATH_DBG_CONFIG, - "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", - bss_conf->beacon_interval, nexttbtt, imask); + "IBSS Beacon config, intval: %d, nexttbtt: %u, " + "resp_time: %d, imask: 0x%x\n", + bss_conf->beacon_interval, nexttbtt, + priv->ah->config.sw_beacon_response_time, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); @@ -317,6 +337,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, int slot) { + struct ath_common *common = ath9k_hw_common(priv->ah); struct ieee80211_vif *vif; struct ath9k_htc_vif *avp; struct tx_beacon_header beacon_hdr; @@ -325,6 +346,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; u8 *tx_fhdr; + int ret; memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); @@ -367,7 +389,14 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); - htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); + ret = htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); + if (ret != 0) { + if (ret == -ENOMEM) { + ath_dbg(common, ATH_DBG_BSTUCK, + "Failed to send beacon, no free TX buffer\n"); + } + dev_kfree_skb_any(beacon); + } spin_unlock_bh(&priv->beacon_lock); } -- GitLab From f4c88991f51e097b6541f998fd23d477999e5886 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:23:52 +0530 Subject: [PATCH 0839/5560] ath9k_htc: Queue WMI events Use a queue to handle WMI events and schedule a tasklet to process the events. This fixes the race between the WMI event ISR and the SWBA tasklet when the arrival of WMI events in quick succession could overwrite the SWBA data before the tasklet from a previous iteration could have been scheduled. Also, drain the WMI queue properly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 +- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 27 +++--- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 3 + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 - drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 +- drivers/net/wireless/ath/ath9k/wmi.c | 97 ++++++++++++------- drivers/net/wireless/ath/ath9k/wmi.h | 7 +- 7 files changed, 89 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 133fc6dc3929..20511af33f5f 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -497,7 +497,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); -void ath9k_htc_swba(struct ath9k_htc_priv *priv); +void ath9k_htc_swba(struct ath9k_htc_priv *priv, + struct wmi_event_swba *swba); void ath9k_htc_rxep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 48bc28823f6f..2180a9da3801 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -401,10 +401,10 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, spin_unlock_bh(&priv->beacon_lock); } -static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) +static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, + struct wmi_event_swba *swba) { struct ath_common *common = ath9k_hw_common(priv->ah); - unsigned long flags; u64 tsf; u32 tsftu; u16 intval; @@ -412,10 +412,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; - spin_lock_irqsave(&priv->wmi->wmi_lock, flags); - tsf = priv->wmi->tsf; - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); - + tsf = be64_to_cpu(swba->tsf); tsftu = TSF_TO_TU(tsf >> 32, tsf); slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; @@ -427,33 +424,31 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv) return slot; } -void ath9k_htc_swba(struct ath9k_htc_priv *priv) +void ath9k_htc_swba(struct ath9k_htc_priv *priv, + struct wmi_event_swba *swba) { struct ath_common *common = ath9k_hw_common(priv->ah); - unsigned long flags; int slot; - spin_lock_irqsave(&priv->wmi->wmi_lock, flags); - if (priv->wmi->beacon_pending != 0) { - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + if (swba->beacon_pending != 0) { priv->cur_beacon_conf.bmiss_cnt++; if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { - ath_dbg(common, ATH_DBG_BEACON, + ath_dbg(common, ATH_DBG_BSTUCK, "Beacon stuck, HW reset\n"); - ath9k_htc_reset(priv); + ieee80211_queue_work(priv->hw, + &priv->fatal_work); } return; } - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); if (priv->cur_beacon_conf.bmiss_cnt) { - ath_dbg(common, ATH_DBG_BEACON, + ath_dbg(common, ATH_DBG_BSTUCK, "Resuming beacon xmit after %u misses\n", priv->cur_beacon_conf.bmiss_cnt); priv->cur_beacon_conf.bmiss_cnt = 0; } - slot = ath9k_htc_choose_bslot(priv); + slot = ath9k_htc_choose_bslot(priv, swba); spin_lock_bh(&priv->beacon_lock); if (priv->cur_beacon_conf.bslot[slot] == NULL) { spin_unlock_bh(&priv->beacon_lock); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 7e630a81b453..459ba0d36f4c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -436,6 +436,9 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) /* Stop RX */ WMI_CMD(WMI_STOP_RECV_CMDID); + /* Clear the WMI event queue */ + ath9k_wmi_event_drain(priv); + /* * The MIB counters have to be disabled here, * since the target doesn't do it. diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index b1c68bff72a6..921d76f32016 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -676,8 +676,6 @@ 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->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, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8f38075d1240..81dfe0782f74 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -202,6 +202,8 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); + ath9k_wmi_event_drain(priv); + caldata = &priv->caldata; ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); if (ret) { @@ -255,6 +257,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); + ath9k_wmi_event_drain(priv); + ath_dbg(common, ATH_DBG_CONFIG, "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", priv->ah->curchan->channel, @@ -1172,12 +1176,13 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); - tasklet_kill(&priv->swba_tasklet); tasklet_kill(&priv->rx_tasklet); tasklet_kill(&priv->tx_tasklet); skb_queue_purge(&priv->tx_queue); + ath9k_wmi_event_drain(priv); + mutex_unlock(&priv->mutex); /* Cancel all the running timers/work .. */ diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index a39552b3077b..45784754dbc2 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -104,9 +104,12 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) wmi->drv_priv = priv; wmi->stopped = false; + skb_queue_head_init(&wmi->wmi_event_queue); mutex_init(&wmi->op_mutex); mutex_init(&wmi->multi_write_mutex); init_completion(&wmi->cmd_wait); + tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, + (unsigned long)wmi); return wmi; } @@ -122,11 +125,64 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) kfree(priv->wmi); } -void ath9k_swba_tasklet(unsigned long data) +void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv) { - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + unsigned long flags; - ath9k_htc_swba(priv); + tasklet_kill(&priv->wmi->wmi_event_tasklet); + spin_lock_irqsave(&priv->wmi->wmi_lock, flags); + __skb_queue_purge(&priv->wmi->wmi_event_queue); + spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); +} + +void ath9k_wmi_event_tasklet(unsigned long data) +{ + struct wmi *wmi = (struct wmi *)data; + struct ath9k_htc_priv *priv = wmi->drv_priv; + struct wmi_cmd_hdr *hdr; + void *wmi_event; + struct wmi_event_swba *swba; + struct sk_buff *skb = NULL; + unsigned long flags; + u16 cmd_id; +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + __be32 txrate; +#endif + + do { + spin_lock_irqsave(&wmi->wmi_lock, flags); + skb = __skb_dequeue(&wmi->wmi_event_queue); + if (!skb) { + spin_unlock_irqrestore(&wmi->wmi_lock, flags); + return; + } + spin_unlock_irqrestore(&wmi->wmi_lock, flags); + + hdr = (struct wmi_cmd_hdr *) skb->data; + cmd_id = be16_to_cpu(hdr->command_id); + wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); + + switch (cmd_id) { + case WMI_SWBA_EVENTID: + swba = (struct wmi_event_swba *) wmi_event; + ath9k_htc_swba(priv, swba); + 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 + txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; + wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); +#endif + break; + default: + break; + } + + kfree_skb(skb); + } while (1); } void ath9k_fatal_work(struct work_struct *work) @@ -155,11 +211,6 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, struct wmi *wmi = (struct wmi *) priv; struct wmi_cmd_hdr *hdr; u16 cmd_id; - void *wmi_event; - struct wmi_event_swba *swba; -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - __be32 txrate; -#endif if (unlikely(wmi->stopped)) goto free_skb; @@ -168,32 +219,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, cmd_id = be16_to_cpu(hdr->command_id); if (cmd_id & 0x1000) { - wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); - switch (cmd_id) { - case WMI_SWBA_EVENTID: - swba = (struct wmi_event_swba *) wmi_event; - - spin_lock(&wmi->wmi_lock); - wmi->tsf = be64_to_cpu(swba->tsf); - wmi->beacon_pending = swba->beacon_pending; - spin_unlock(&wmi->wmi_lock); - - 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 - txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; - wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); -#endif - break; - default: - break; - } - kfree_skb(skb); + spin_lock(&wmi->wmi_lock); + __skb_queue_tail(&wmi->wmi_event_queue, skb); + spin_unlock(&wmi->wmi_lock); + tasklet_schedule(&wmi->wmi_event_tasklet); return; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 2fa91a941a72..ff5ba2b30ecc 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -106,13 +106,13 @@ struct wmi { struct mutex op_mutex; struct completion cmd_wait; enum wmi_cmd_id last_cmd_id; + struct sk_buff_head wmi_event_queue; + struct tasklet_struct wmi_event_tasklet; u16 tx_seq_id; u8 *cmd_rsp_buf; u32 cmd_rsp_len; bool stopped; - u64 tsf; - u8 beacon_pending; spinlock_t wmi_lock; atomic_t mwrite_cnt; @@ -129,8 +129,9 @@ 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_swba_tasklet(unsigned long data); +void ath9k_wmi_event_tasklet(unsigned long data); void ath9k_fatal_work(struct work_struct *work); +void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); #define WMI_CMD(_wmi_cmd) \ do { \ -- GitLab From 8e42e4ba98f986be64016df79eacbb671dbd3d18 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:00 +0530 Subject: [PATCH 0840/5560] ath9k_htc: Move debug code to a separate file Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 2 + .../net/wireless/ath/ath9k/htc_drv_debug.c | 219 ++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 212 ----------------- 3 files changed, 221 insertions(+), 212 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/htc_drv_debug.c diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index ca4c436e0f65..05a6fade7b1c 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -48,4 +48,6 @@ ath9k_htc-y += htc_hst.o \ htc_drv_init.o \ htc_drv_gpio.o +ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o + obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c new file mode 100644 index 000000000000..8b679aab338a --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2010-2011 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" + +static struct dentry *ath9k_debugfs_root; + +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_target_stats cmd_rsp; + char buf[512]; + unsigned int len = 0; + int ret = 0; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_TGT_STATS_CMDID); + if (ret) + return -EINVAL; + + + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Short Retries", + be32_to_cpu(cmd_rsp.tx_shortretry)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Long Retries", + be32_to_cpu(cmd_rsp.tx_longretry)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Xretries", + be32_to_cpu(cmd_rsp.tx_xretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Unaggr. Xretries", + be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Xretries (HT)", + be32_to_cpu(cmd_rsp.ht_tx_xretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%19s : %10u\n", "TX Rate", priv->debug.txrate); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_tgt_stats = { + .read = read_file_tgt_stats, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_xmit(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Buffers queued", + priv->debug.tx_stats.buf_queued); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Buffers completed", + priv->debug.tx_stats.buf_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs queued", + priv->debug.tx_stats.skb_queued); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs completed", + priv->debug.tx_stats.skb_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs dropped", + priv->debug.tx_stats.skb_dropped); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CAB queued", + priv->debug.tx_stats.cab_queued); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BE queued", + priv->debug.tx_stats.queue_stats[WME_AC_BE]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BK queued", + priv->debug.tx_stats.queue_stats[WME_AC_BK]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VI queued", + priv->debug.tx_stats.queue_stats[WME_AC_VI]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VO queued", + priv->debug.tx_stats.queue_stats[WME_AC_VO]); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_xmit = { + .read = read_file_xmit, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_recv(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs allocated", + priv->debug.rx_stats.skb_allocated); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs completed", + priv->debug.rx_stats.skb_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs Dropped", + priv->debug.rx_stats.skb_dropped); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_recv = { + .read = read_file_recv, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +int ath9k_htc_init_debug(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + + if (!ath9k_debugfs_root) + return -ENOENT; + + priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), + ath9k_debugfs_root); + if (!priv->debug.debugfs_phy) + goto err; + + priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_stats); + if (!priv->debug.debugfs_tgt_stats) + goto err; + + + priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_xmit); + if (!priv->debug.debugfs_xmit) + goto err; + + priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_recv); + if (!priv->debug.debugfs_recv) + goto err; + + return 0; + +err: + ath9k_htc_exit_debug(ah); + return -ENOMEM; +} + +void ath9k_htc_exit_debug(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + + debugfs_remove(priv->debug.debugfs_recv); + debugfs_remove(priv->debug.debugfs_xmit); + debugfs_remove(priv->debug.debugfs_tgt_stats); + debugfs_remove(priv->debug.debugfs_phy); +} + +int ath9k_htc_debug_create_root(void) +{ + ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); + if (!ath9k_debugfs_root) + return -ENOENT; + + return 0; +} + +void ath9k_htc_debug_remove_root(void) +{ + debugfs_remove(ath9k_debugfs_root); + ath9k_debugfs_root = NULL; +} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 81dfe0782f74..59710e75f051 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -16,10 +16,6 @@ #include "htc.h" -#ifdef CONFIG_ATH9K_HTC_DEBUGFS -static struct dentry *ath9k_debugfs_root; -#endif - /*************/ /* Utilities */ /*************/ @@ -720,214 +716,6 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, return ret; } -/*********/ -/* DEBUG */ -/*********/ - -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - -static int ath9k_debugfs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath9k_htc_priv *priv = file->private_data; - struct ath9k_htc_target_stats cmd_rsp; - char buf[512]; - unsigned int len = 0; - int ret = 0; - - memset(&cmd_rsp, 0, sizeof(cmd_rsp)); - - WMI_CMD(WMI_TGT_STATS_CMDID); - if (ret) - return -EINVAL; - - - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Short Retries", - be32_to_cpu(cmd_rsp.tx_shortretry)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Long Retries", - be32_to_cpu(cmd_rsp.tx_longretry)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries", - be32_to_cpu(cmd_rsp.tx_xretries)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Unaggr. Xretries", - be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries (HT)", - be32_to_cpu(cmd_rsp.ht_tx_xretries)); - len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Rate", priv->debug.txrate); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_tgt_stats = { - .read = read_file_tgt_stats, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t read_file_xmit(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath9k_htc_priv *priv = file->private_data; - char buf[512]; - unsigned int len = 0; - - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Buffers queued", - priv->debug.tx_stats.buf_queued); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Buffers completed", - priv->debug.tx_stats.buf_completed); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs queued", - priv->debug.tx_stats.skb_queued); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.tx_stats.skb_completed); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs dropped", - priv->debug.tx_stats.skb_dropped); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "CAB queued", - priv->debug.tx_stats.cab_queued); - - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "BE queued", - priv->debug.tx_stats.queue_stats[WME_AC_BE]); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "BK queued", - priv->debug.tx_stats.queue_stats[WME_AC_BK]); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "VI queued", - priv->debug.tx_stats.queue_stats[WME_AC_VI]); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "VO queued", - priv->debug.tx_stats.queue_stats[WME_AC_VO]); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_xmit = { - .read = read_file_xmit, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t read_file_recv(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath9k_htc_priv *priv = file->private_data; - char buf[512]; - unsigned int len = 0; - - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs allocated", - priv->debug.rx_stats.skb_allocated); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.rx_stats.skb_completed); - len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs Dropped", - priv->debug.rx_stats.skb_dropped); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_recv = { - .read = read_file_recv, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -int ath9k_htc_init_debug(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - if (!ath9k_debugfs_root) - return -ENOENT; - - priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), - ath9k_debugfs_root); - if (!priv->debug.debugfs_phy) - goto err; - - priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_stats); - if (!priv->debug.debugfs_tgt_stats) - goto err; - - - priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_xmit); - if (!priv->debug.debugfs_xmit) - goto err; - - priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_recv); - if (!priv->debug.debugfs_recv) - goto err; - - return 0; - -err: - ath9k_htc_exit_debug(ah); - return -ENOMEM; -} - -void ath9k_htc_exit_debug(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - debugfs_remove(priv->debug.debugfs_recv); - debugfs_remove(priv->debug.debugfs_xmit); - debugfs_remove(priv->debug.debugfs_tgt_stats); - debugfs_remove(priv->debug.debugfs_phy); -} - -int ath9k_htc_debug_create_root(void) -{ - ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!ath9k_debugfs_root) - return -ENOENT; - - return 0; -} - -void ath9k_htc_debug_remove_root(void) -{ - debugfs_remove(ath9k_debugfs_root); - ath9k_debugfs_root = NULL; -} - -#endif /* CONFIG_ATH9K_HTC_DEBUGFS */ - /*******/ /* ANI */ /*******/ -- GitLab From 719c4cf6b1b113e9caf377c6607ae45758a85871 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:10 +0530 Subject: [PATCH 0841/5560] ath9k_htc: Add RX error statistics Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 16 +++ .../net/wireless/ath/ath9k/htc_drv_debug.c | 109 ++++++++++++++++-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 + 3 files changed, 118 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 20511af33f5f..0e48fa0efa77 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -296,6 +296,9 @@ struct ath9k_htc_tx_ctl { #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) +void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, + struct ath_htc_rx_status *rxs); + struct ath_tx_stats { u32 buf_queued; u32 buf_completed; @@ -310,6 +313,14 @@ struct ath_rx_stats { u32 skb_allocated; u32 skb_completed; u32 skb_dropped; + u32 err_crc; + u32 err_decrypt_crc; + u32 err_mic; + u32 err_pre_delim; + u32 err_post_delim; + u32 err_decrypt_busy; + u32 err_phy; + u32 err_phy_stats[ATH9K_PHYERR_MAX]; }; struct ath9k_debug { @@ -330,6 +341,11 @@ struct ath9k_debug { #define TX_QSTAT_INC(c) do { } while (0) +static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, + struct ath_htc_rx_status *rxs) +{ +} + #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #define ATH_LED_PIN_DEF 1 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 8b679aab338a..6fc6cb749362 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -123,27 +123,118 @@ static const struct file_operations fops_xmit = { .llseek = default_llseek, }; +void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, + struct ath_htc_rx_status *rxs) +{ +#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++ + + if (rxs->rs_status & ATH9K_RXERR_CRC) + priv->debug.rx_stats.err_crc++; + if (rxs->rs_status & ATH9K_RXERR_DECRYPT) + priv->debug.rx_stats.err_decrypt_crc++; + if (rxs->rs_status & ATH9K_RXERR_MIC) + priv->debug.rx_stats.err_mic++; + if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE) + priv->debug.rx_stats.err_pre_delim++; + if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST) + priv->debug.rx_stats.err_post_delim++; + if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY) + priv->debug.rx_stats.err_decrypt_busy++; + + if (rxs->rs_status & ATH9K_RXERR_PHY) { + priv->debug.rx_stats.err_phy++; + if (rxs->rs_phyerr < ATH9K_PHYERR_MAX) + RX_PHY_ERR_INC(rxs->rs_phyerr); + } + +#undef RX_PHY_ERR_INC +} + static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { +#define PHY_ERR(s, p) \ + len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \ + priv->debug.rx_stats.err_phy_stats[p]); + struct ath9k_htc_priv *priv = file->private_data; - char buf[512]; - unsigned int len = 0; + char *buf; + unsigned int len = 0, size = 1500; + ssize_t retval = 0; - len += snprintf(buf + len, sizeof(buf) - len, + buf = kzalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + len += snprintf(buf + len, size - len, "%20s : %10u\n", "SKBs allocated", priv->debug.rx_stats.skb_allocated); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, size - len, "%20s : %10u\n", "SKBs completed", priv->debug.rx_stats.skb_completed); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, size - len, "%20s : %10u\n", "SKBs Dropped", priv->debug.rx_stats.skb_dropped); - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "CRC ERR", + priv->debug.rx_stats.err_crc); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "DECRYPT CRC ERR", + priv->debug.rx_stats.err_decrypt_crc); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "MIC ERR", + priv->debug.rx_stats.err_mic); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "PRE-DELIM CRC ERR", + priv->debug.rx_stats.err_pre_delim); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "POST-DELIM CRC ERR", + priv->debug.rx_stats.err_post_delim); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "DECRYPT BUSY ERR", + priv->debug.rx_stats.err_decrypt_busy); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "TOTAL PHY ERR", + priv->debug.rx_stats.err_phy); + + + PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); + PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); + PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); + PHY_ERR("RATE", ATH9K_PHYERR_RATE); + PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); + PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); + PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); + PHY_ERR("TOR", ATH9K_PHYERR_TOR); + PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); + PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); + PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); + PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); + PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); + PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); + PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); + PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); + PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); + PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); + PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); + PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); + PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); + PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); + PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); + PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); + PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); + PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); + + if (len > size) + len = size; + + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + + return retval; + +#undef PHY_ERR } static const struct file_operations fops_recv = { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 0e2855893669..a62495d1330a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -540,6 +540,8 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, goto rx_next; } + ath9k_htc_err_stat_rx(priv, rxstatus); + /* Get the RX status information */ memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); -- GitLab From b1563a4c3d721cb0496b8e1fb874f08a8f2b62cc Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:19 +0530 Subject: [PATCH 0842/5560] ath9k_htc: Fix RX length check The length of the received SKB could be equal to HTC_RX_FRAME_HEADER_SIZE in case of packets with phy/crc errors, in which case they are dropped without being processed. Fix this check so that the error counters are updated correctly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a62495d1330a..7cd3e4e66aa6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -525,8 +525,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, int last_rssi = ATH_RSSI_DUMMY_MARKER; __le16 fc; - if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { - ath_err(common, "Corrupted RX frame, dropping\n"); + if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { + ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", + skb->len); goto rx_next; } -- GitLab From e723f3900c3b23feb427672c6ccfe5d4243d2c2d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:25 +0530 Subject: [PATCH 0843/5560] ath9k_htc: Remove unused WMI commands WMI_TGT_TXQ_ENABLE_CMDID WMI_HOST_ATTACH WMI_DEBUG_INFO_CMDID WMI_BEACON_UPDATE_CMDID WMI_RESET_CMDID WMI_RX_LINK_CMDID WMI_STOP_DMA_RECV_CMDID Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.c | 14 -------------- drivers/net/wireless/ath/ath9k/wmi.h | 7 ------- 2 files changed, 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 45784754dbc2..3b8f25fbecfd 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -29,16 +29,12 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_DISABLE_INTR_CMDID"; case WMI_ENABLE_INTR_CMDID: return "WMI_ENABLE_INTR_CMDID"; - case WMI_RX_LINK_CMDID: - return "WMI_RX_LINK_CMDID"; case WMI_ATH_INIT_CMDID: return "WMI_ATH_INIT_CMDID"; case WMI_ABORT_TXQ_CMDID: return "WMI_ABORT_TXQ_CMDID"; case WMI_STOP_TX_DMA_CMDID: return "WMI_STOP_TX_DMA_CMDID"; - case WMI_STOP_DMA_RECV_CMDID: - return "WMI_STOP_DMA_RECV_CMDID"; case WMI_ABORT_TX_DMA_CMDID: return "WMI_ABORT_TX_DMA_CMDID"; case WMI_DRAIN_TXQ_CMDID: @@ -53,8 +49,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_FLUSH_RECV_CMDID"; case WMI_SET_MODE_CMDID: return "WMI_SET_MODE_CMDID"; - case WMI_RESET_CMDID: - return "WMI_RESET_CMDID"; case WMI_NODE_CREATE_CMDID: return "WMI_NODE_CREATE_CMDID"; case WMI_NODE_REMOVE_CMDID: @@ -63,8 +57,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_VAP_REMOVE_CMDID"; case WMI_VAP_CREATE_CMDID: return "WMI_VAP_CREATE_CMDID"; - case WMI_BEACON_UPDATE_CMDID: - return "WMI_BEACON_UPDATE_CMDID"; case WMI_REG_READ_CMDID: return "WMI_REG_READ_CMDID"; case WMI_REG_WRITE_CMDID: @@ -73,10 +65,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_RC_STATE_CHANGE_CMDID"; case WMI_RC_RATE_UPDATE_CMDID: return "WMI_RC_RATE_UPDATE_CMDID"; - case WMI_DEBUG_INFO_CMDID: - return "WMI_DEBUG_INFO_CMDID"; - case WMI_HOST_ATTACH: - return "WMI_HOST_ATTACH"; case WMI_TARGET_IC_UPDATE_CMDID: return "WMI_TARGET_IC_UPDATE_CMDID"; case WMI_TGT_STATS_CMDID: @@ -85,8 +73,6 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_TX_AGGR_ENABLE_CMDID"; case WMI_TGT_DETACH_CMDID: return "WMI_TGT_DETACH_CMDID"; - case WMI_TGT_TXQ_ENABLE_CMDID: - return "WMI_TGT_TXQ_ENABLE_CMDID"; case WMI_AGGR_LIMIT_CMD: return "WMI_AGGR_LIMIT_CMD"; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index ff5ba2b30ecc..3ab9604fd6bd 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -49,11 +49,9 @@ enum wmi_cmd_id { WMI_GET_FW_VERSION, WMI_DISABLE_INTR_CMDID, WMI_ENABLE_INTR_CMDID, - WMI_RX_LINK_CMDID, WMI_ATH_INIT_CMDID, WMI_ABORT_TXQ_CMDID, WMI_STOP_TX_DMA_CMDID, - WMI_STOP_DMA_RECV_CMDID, WMI_ABORT_TX_DMA_CMDID, WMI_DRAIN_TXQ_CMDID, WMI_DRAIN_TXQ_ALL_CMDID, @@ -61,23 +59,18 @@ enum wmi_cmd_id { WMI_STOP_RECV_CMDID, WMI_FLUSH_RECV_CMDID, WMI_SET_MODE_CMDID, - WMI_RESET_CMDID, WMI_NODE_CREATE_CMDID, WMI_NODE_REMOVE_CMDID, WMI_VAP_REMOVE_CMDID, WMI_VAP_CREATE_CMDID, - WMI_BEACON_UPDATE_CMDID, WMI_REG_READ_CMDID, WMI_REG_WRITE_CMDID, WMI_RC_STATE_CHANGE_CMDID, WMI_RC_RATE_UPDATE_CMDID, - WMI_DEBUG_INFO_CMDID, - WMI_HOST_ATTACH, WMI_TARGET_IC_UPDATE_CMDID, WMI_TGT_STATS_CMDID, WMI_TX_AGGR_ENABLE_CMDID, WMI_TGT_DETACH_CMDID, - WMI_TGT_TXQ_ENABLE_CMDID, WMI_AGGR_LIMIT_CMD = 0x0026, }; -- GitLab From 40dc9e4b86963b77918f1b8fa02b98c1e420a7e1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:31 +0530 Subject: [PATCH 0844/5560] ath9k_htc: Use SKB's private area for TX parameters For all packets sent through the USB_WLAN_TX_PIPE endpoint, the private area of the SKB's tx_info can be used to store driver-specific information. For packets sent through USB_REG_OUT_PIPE, this will not make a difference since they are routed through a separate routine that doesn't access the private region. This would help in situations where TX information is required in the URB callback. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 17 +++++++++-------- drivers/net/wireless/ath/ath9k/htc.h | 14 +++++++++++++- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 11 +++++++---- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 15 ++++++++------- drivers/net/wireless/ath/ath9k/htc_hst.c | 18 +++++++++--------- drivers/net/wireless/ath/ath9k/htc_hst.h | 5 ++--- drivers/net/wireless/ath/ath9k/wmi.c | 2 +- 7 files changed, 49 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 23094b70d6eb..e252576760d1 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -284,9 +284,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) return ret; } -static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, - struct ath9k_htc_tx_ctl *tx_ctl) +static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) { + struct ath9k_htc_tx_ctl *tx_ctl; unsigned long flags; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); @@ -305,12 +305,14 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); hif_dev->tx.tx_skb_cnt++; - /* Send normal frames immediately */ - if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) + tx_ctl = HTC_SKB_CB(skb); + + /* Send normal/mgmt/beacon frames immediately */ + if (tx_ctl->type != ATH9K_HTC_AMPDU) __hif_usb_tx(hif_dev); /* Check if AMPDUs have to be sent immediately */ - if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && + if ((tx_ctl->type == ATH9K_HTC_AMPDU) && (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && (hif_dev->tx.tx_skb_cnt < 2)) { __hif_usb_tx(hif_dev); @@ -352,15 +354,14 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) } } -static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, - struct ath9k_htc_tx_ctl *tx_ctl) +static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; int ret = 0; switch (pipe_id) { case USB_WLAN_TX_PIPE: - ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); + ret = hif_usb_send_tx(hif_dev, skb); break; case USB_REG_OUT_PIPE: ret = hif_usb_send_regout(hif_dev, skb); diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0e48fa0efa77..2eabfe4ad268 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -67,8 +67,11 @@ enum htc_opmode { }; #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) -#define ATH9K_HTC_AMPDU 1 + +#define ATH9K_HTC_AMPDU 1 #define ATH9K_HTC_NORMAL 2 +#define ATH9K_HTC_BEACON 3 +#define ATH9K_HTC_MGMT 4 #define ATH9K_HTC_TX_CTSONLY 0x1 #define ATH9K_HTC_TX_RTSCTS 0x2 @@ -288,6 +291,15 @@ struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ }; +static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + + BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) > + IEEE80211_TX_INFO_DRIVER_DATA_SIZE); + return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data; +} + #ifdef CONFIG_ATH9K_HTC_DEBUGFS #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 2180a9da3801..713def184519 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -341,7 +341,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif; struct ath9k_htc_vif *avp; struct tx_beacon_header beacon_hdr; - struct ath9k_htc_tx_ctl tx_ctl; + struct ath9k_htc_tx_ctl *tx_ctl; struct ieee80211_tx_info *info; struct ieee80211_mgmt *mgmt; struct sk_buff *beacon; @@ -349,7 +349,6 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, int ret; memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); - memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); spin_lock_bh(&priv->beacon_lock); @@ -384,12 +383,16 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); } - tx_ctl.type = ATH9K_HTC_NORMAL; + tx_ctl = HTC_SKB_CB(beacon); + memset(tx_ctl, 0, sizeof(*tx_ctl)); + + tx_ctl->type = ATH9K_HTC_BEACON; + beacon_hdr.vif_index = avp->index; tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); - ret = htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); + ret = htc_send(priv->htc, beacon, priv->beacon_ep); if (ret != 0) { if (ret == -ENOMEM) { ath_dbg(common, ATH_DBG_BSTUCK, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 7cd3e4e66aa6..ab55dff4721f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -89,13 +89,16 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; - struct ath9k_htc_tx_ctl tx_ctl; + struct ath9k_htc_tx_ctl *tx_ctl; enum htc_endpoint_id epid; u16 qnum; __le16 fc; u8 *tx_fhdr; u8 sta_idx, vif_idx; + tx_ctl = HTC_SKB_CB(skb); + memset(tx_ctl, 0, sizeof(*tx_ctl)); + hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; @@ -126,8 +129,6 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, sta_idx = priv->vif_sta_pos[vif_idx]; } - memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); - if (ieee80211_is_data(fc)) { struct tx_frame_hdr tx_hdr; u32 flags = 0; @@ -139,10 +140,10 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_hdr.vif_idx = vif_idx; if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - tx_ctl.type = ATH9K_HTC_AMPDU; + tx_ctl->type = ATH9K_HTC_AMPDU; tx_hdr.data_type = ATH9K_HTC_AMPDU; } else { - tx_ctl.type = ATH9K_HTC_NORMAL; + tx_ctl->type = ATH9K_HTC_NORMAL; tx_hdr.data_type = ATH9K_HTC_NORMAL; } @@ -212,7 +213,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, mgmt->u.probe_resp.timestamp = avp->tsfadjust; } - tx_ctl.type = ATH9K_HTC_NORMAL; + tx_ctl->type = ATH9K_HTC_MGMT; mgmt_hdr.node_idx = sta_idx; mgmt_hdr.vif_idx = vif_idx; @@ -230,7 +231,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, epid = priv->mgmt_ep; } send: - return htc_send(priv->htc, skb, epid, &tx_ctl); + return htc_send(priv->htc, skb, epid); } static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index c41ab8c30161..6ee53de45c6a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -17,8 +17,8 @@ #include "htc.h" static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, - u16 len, u8 flags, u8 epid, - struct ath9k_htc_tx_ctl *tx_ctl) + u16 len, u8 flags, u8 epid) + { struct htc_frame_hdr *hdr; struct htc_endpoint *endpoint = &target->endpoint[epid]; @@ -30,8 +30,8 @@ static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, hdr->flags = flags; hdr->payload_len = cpu_to_be16(len); - status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, - tx_ctl); + status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb); + return status; } @@ -162,7 +162,7 @@ static int htc_config_pipe_credits(struct htc_target *target) target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; - ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -197,7 +197,7 @@ static int htc_setup_complete(struct htc_target *target) target->htc_flags |= HTC_OP_START_WAIT; - ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -268,7 +268,7 @@ int htc_connect_service(struct htc_target *target, conn_msg->dl_pipeid = endpoint->dl_pipeid; conn_msg->ul_pipeid = endpoint->ul_pipeid; - ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -287,9 +287,9 @@ int htc_connect_service(struct htc_target *target, } int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) + enum htc_endpoint_id epid) { - return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); + return htc_issue_send(target, skb, skb->len, 0, epid); } void htc_stop(struct htc_target *target) diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index ecd018798c47..3531552672e0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -35,8 +35,7 @@ struct ath9k_htc_hif { void (*start) (void *hif_handle, u8 pipe); void (*stop) (void *hif_handle, u8 pipe); - int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, - struct ath9k_htc_tx_ctl *tx_ctl); + int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); }; enum htc_endpoint_id { @@ -206,7 +205,7 @@ int htc_connect_service(struct htc_target *target, struct htc_service_connreq *service_connreq, enum htc_endpoint_id *conn_rsp_eid); int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); + enum htc_endpoint_id eid); void htc_stop(struct htc_target *target); void htc_start(struct htc_target *target); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 3b8f25fbecfd..83d1e0e5dd8c 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -267,7 +267,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, hdr->command_id = cpu_to_be16(cmd); hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); - return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); + return htc_send(wmi->htc, skb, wmi->ctrl_epid); } int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, -- GitLab From b97c57ff3f568b33ed91915f48431feae2dab288 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:37 +0530 Subject: [PATCH 0845/5560] ath9k_htc: Sync struct ath9k_htc_target_sta with FW Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 30 +++---------------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 6 ++-- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 2eabfe4ad268..e096624d9073 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -104,17 +104,6 @@ struct tx_beacon_header { u16 rev; } __packed; -struct ath9k_htc_target_hw { - u32 flags; - u32 flags_ext; - u32 ampdu_limit; - u8 ampdu_subframes; - u8 tx_chainmask; - u8 tx_chainmask_legacy; - u8 rtscts_ratecode; - u8 protmode; -} __packed; - struct ath9k_htc_cap_target { u32 flags; u32 flags_ext; @@ -146,27 +135,16 @@ struct ath9k_htc_target_vif { #define ATH_HTC_STA_ERP 0x0004 #define ATH_HTC_STA_HT 0x0008 -/* FIXME: UAPSD variables */ struct ath9k_htc_target_sta { - u16 associd; - u16 txpower; - u32 ucastkey; u8 macaddr[ETH_ALEN]; u8 bssid[ETH_ALEN]; u8 sta_index; u8 vif_index; - u8 vif_sta; - __be16 flags; /* ATH_HTC_STA_* */ - u16 htcap; - u8 valid; - u16 capinfo; - struct ath9k_htc_target_hw *hw; - struct ath9k_htc_target_vif *vif; - u16 txseqmgmt; u8 is_vif_sta; - u16 maxampdu; - u16 iv16; - u32 iv32; + __be16 flags; /* ATH_HTC_STA_* */ + __be16 htcap; + __be16 maxampdu; + u8 pad; } __packed; struct ath9k_htc_target_aggr { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 59710e75f051..9bb20f33638c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -382,7 +382,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) tsta.is_vif_sta = 1; tsta.sta_index = sta_idx; tsta.vif_index = hvif.index; - tsta.maxampdu = 0xffff; + tsta.maxampdu = cpu_to_be16(0xffff); WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); if (ret) { @@ -463,9 +463,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, ista = (struct ath9k_htc_sta *) sta->drv_priv; memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); - tsta.associd = common->curaid; tsta.is_vif_sta = 0; - tsta.valid = true; ista->index = sta_idx; } else { memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); @@ -474,7 +472,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, tsta.sta_index = sta_idx; tsta.vif_index = avp->index; - tsta.maxampdu = 0xffff; + tsta.maxampdu = cpu_to_be16(0xffff); if (sta && sta->ht_cap.ht_supported) tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); -- GitLab From e4c62506fcfa7c1fa7c586ab518a172c3a65db0f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:43 +0530 Subject: [PATCH 0846/5560] ath9k_htc: Sync struct ath9k_htc_target_vif with FW Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 12 +++--------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 8 ++++---- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index e096624d9073..f74f45f238af 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -117,17 +117,11 @@ struct ath9k_htc_cap_target { struct ath9k_htc_target_vif { u8 index; - u8 des_bssid[ETH_ALEN]; - __be32 opmode; + u8 opmode; u8 myaddr[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - u32 flags; - u32 flags_ext; - u16 ps_sta; - __be16 rtsthreshold; u8 ath_cap; - u8 node; - s8 mcast_rate; + __be16 rtsthreshold; + u8 pad; } __packed; #define ATH_HTC_STA_AUTH 0x0001 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9bb20f33638c..400226702e0a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -349,7 +349,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); - hvif.opmode = cpu_to_be32(HTC_M_MONITOR); + hvif.opmode = HTC_M_MONITOR; hvif.index = ffz(priv->vif_slot); WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); @@ -1039,13 +1039,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, switch (vif->type) { case NL80211_IFTYPE_STATION: - hvif.opmode = cpu_to_be32(HTC_M_STA); + hvif.opmode = HTC_M_STA; break; case NL80211_IFTYPE_ADHOC: - hvif.opmode = cpu_to_be32(HTC_M_IBSS); + hvif.opmode = HTC_M_IBSS; break; case NL80211_IFTYPE_AP: - hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); + hvif.opmode = HTC_M_HOSTAP; break; default: ath_err(common, -- GitLab From 0a8579f6b7c3f4332ad9eb6615c7631ef9cd4ed6 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:49 +0530 Subject: [PATCH 0847/5560] ath9k_htc: Sync struct ath9k_htc_cap_target with FW Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index f74f45f238af..1568c3692da4 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -113,6 +113,7 @@ struct ath9k_htc_cap_target { u8 tx_chainmask_legacy; u8 rtscts_ratecode; u8 protmode; + u8 pad; } __packed; struct ath9k_htc_target_vif { -- GitLab From ee3fa1bdadd998652083a7814af745f765a06a25 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:24:55 +0530 Subject: [PATCH 0848/5560] ath9k_htc: Remove unused WMI_WLAN_TXCOMP_EVENTID Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 3ab9604fd6bd..a81d554edb8e 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -80,7 +80,6 @@ enum wmi_event_id { WMI_FATAL_EVENTID, WMI_TXTO_EVENTID, WMI_BMISS_EVENTID, - WMI_WLAN_TXCOMP_EVENTID, WMI_DELBA_EVENTID, WMI_TXRATE_EVENTID, }; -- GitLab From 658ef04fd42a587b17a379ad9208023473442ddd Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:00 +0530 Subject: [PATCH 0849/5560] ath9k_htc: Move TX specific stuff to a separate structure 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_gpio.c | 8 +++---- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 22 ++++++++--------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 24 +++++++++---------- 5 files changed, 40 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1568c3692da4..3af8a58d400f 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -260,6 +260,13 @@ struct ath9k_htc_rx { spinlock_t rxbuflock; }; +struct ath9k_htc_tx { + bool tx_queues_stop; + spinlock_t tx_lock; + + struct sk_buff_head tx_queue; +}; + struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ }; @@ -433,22 +440,20 @@ struct ath9k_htc_priv { u16 nstations; bool rearm_ani; bool reconfig_beacon; + unsigned int rxfilter; struct ath9k_hw_cal_data caldata; + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; spinlock_t beacon_lock; + struct htc_beacon_config cur_beacon_conf; - bool tx_queues_stop; - spinlock_t tx_lock; + struct ath9k_htc_rx rx; + struct ath9k_htc_tx tx; - struct htc_beacon_config cur_beacon_conf; - unsigned int rxfilter; struct tasklet_struct swba_tasklet; struct tasklet_struct rx_tasklet; - struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; - struct ath9k_htc_rx rx; struct tasklet_struct tx_tasklet; - struct sk_buff_head tx_queue; struct delayed_work ani_work; struct work_struct ps_work; struct work_struct fatal_work; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 459ba0d36f4c..1f6df4a1d224 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -398,9 +398,9 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) /* Start TX */ htc_start(priv->htc); - spin_lock_bh(&priv->tx_lock); - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.tx_queues_stop = false; + spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); WMI_CMD(WMI_ENABLE_INTR_CMDID); @@ -431,7 +431,7 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) ieee80211_stop_queues(hw); htc_stop(priv->htc); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); - skb_queue_purge(&priv->tx_queue); + skb_queue_purge(&priv->tx.tx_queue); /* Stop RX */ WMI_CMD(WMI_STOP_RECV_CMDID); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 921d76f32016..c270da7be10f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -673,7 +673,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, spin_lock_init(&priv->wmi->wmi_lock); spin_lock_init(&priv->beacon_lock); - spin_lock_init(&priv->tx_lock); + spin_lock_init(&priv->tx.tx_lock); mutex_init(&priv->mutex); mutex_init(&priv->htc_pm_lock); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 400226702e0a..ff3a49577a02 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -707,9 +707,9 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, (aggr.aggr_enable) ? "Starting" : "Stopping", sta->addr, tid); - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); return ret; } @@ -853,9 +853,9 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 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); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.tx_queues_stop = true; + spin_unlock_bh(&priv->tx.tx_lock); } else { ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Tx failed\n"); @@ -923,9 +923,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) priv->op_flags &= ~OP_INVALID; htc_start(priv->htc); - spin_lock_bh(&priv->tx_lock); - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.tx_queues_stop = false; + spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); @@ -965,7 +965,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) tasklet_kill(&priv->rx_tasklet); tasklet_kill(&priv->tx_tasklet); - skb_queue_purge(&priv->tx_queue); + skb_queue_purge(&priv->tx.tx_queue); ath9k_wmi_event_drain(priv); @@ -1563,9 +1563,9 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_OPERATIONAL: ista = (struct ath9k_htc_sta *) sta->drv_priv; - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = AGGR_OPERATIONAL; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); break; default: ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index ab55dff4721f..6f7987d7b6b0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -239,10 +239,10 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, { bool ret = false; - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) ret = true; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); return ret; } @@ -257,7 +257,7 @@ void ath9k_tx_tasklet(unsigned long data) struct sk_buff *skb = NULL; __le16 fc; - while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { + while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; @@ -292,9 +292,9 @@ void ath9k_tx_tasklet(unsigned long data) if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { ieee80211_start_tx_ba_session(sta, tid, 0); - spin_lock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); ista->tid_state[tid] = AGGR_PROGRESS; - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); } } } @@ -307,16 +307,16 @@ void ath9k_tx_tasklet(unsigned long data) } /* Wake TX queues if needed */ - spin_lock_bh(&priv->tx_lock); - if (priv->tx_queues_stop) { - priv->tx_queues_stop = false; - spin_unlock_bh(&priv->tx_lock); + spin_lock_bh(&priv->tx.tx_lock); + if (priv->tx.tx_queues_stop) { + priv->tx.tx_queues_stop = false; + spin_unlock_bh(&priv->tx.tx_lock); ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Waking up TX queues\n"); ieee80211_wake_queues(priv->hw); return; } - spin_unlock_bh(&priv->tx_lock); + spin_unlock_bh(&priv->tx.tx_lock); } void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, @@ -348,13 +348,13 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, if (txok) tx_info->flags |= IEEE80211_TX_STAT_ACK; - skb_queue_tail(&priv->tx_queue, skb); + skb_queue_tail(&priv->tx.tx_queue, skb); tasklet_schedule(&priv->tx_tasklet); } int ath9k_tx_init(struct ath9k_htc_priv *priv) { - skb_queue_head_init(&priv->tx_queue); + skb_queue_head_init(&priv->tx.tx_queue); return 0; } -- GitLab From 15f6d6d52fe0d9fcf8c09788caff5d1684e5f12c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:06 +0530 Subject: [PATCH 0850/5560] ath9k_htc: Reduce TX queue size The current max queue length of 1024 is quite large and unnecessary. 256 suffices well enough even for high throughput situations. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7b9d863d4035..f82b32bbf4e2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -31,7 +31,7 @@ /* FIXME: Verify these numbers (with Windows) */ #define MAX_TX_URB_NUM 8 -#define MAX_TX_BUF_NUM 1024 +#define MAX_TX_BUF_NUM 256 #define MAX_TX_BUF_SIZE 32768 #define MAX_TX_AGGR_NUM 20 -- GitLab From e8e3860765641d5e9d1607ec50191cb33c28371d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:12 +0530 Subject: [PATCH 0851/5560] ath9k_htc: Sync MGMT/DATA packet headers with firmware Add a new cookie field that would be filled by the host. This can be used to match the TX status WMI event with the appropriate packet. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 3af8a58d400f..3185fe7568cb 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -85,7 +85,8 @@ struct tx_frame_hdr { __be32 flags; /* ATH9K_HTC_TX_* */ u8 key_type; u8 keyix; - u8 reserved[26]; + u8 cookie; + u8 pad; } __packed; struct tx_mgmt_hdr { @@ -95,7 +96,8 @@ struct tx_mgmt_hdr { u8 flags; u8 key_type; u8 keyix; - u16 reserved; + u8 cookie; + u8 pad; } __packed; struct tx_beacon_header { -- GitLab From 16c56ae87509d9bbcd8c711dc4f99b38c234d6c5 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:18 +0530 Subject: [PATCH 0852/5560] ath9k_htc: Add a new WMI event WMI_TXSTATUS_EVENTID This event will be generated by the target for packet completions. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/wmi.h | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index a81d554edb8e..8c877dc2e2e0 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -41,6 +41,44 @@ struct wmi_event_swba { __be64 tsf; u8 beacon_pending; }; + +/* + * 64 - HTC header - WMI header - 1 / txstatus + * And some other hdr. space is also accounted for. + * 13 seems to be the magic number. + */ +#define HTC_MAX_TX_STATUS 13 + +#define ATH9K_HTC_TXSTAT_ACK BIT(0) +#define ATH9K_HTC_TXSTAT_FILT BIT(1) +#define ATH9K_HTC_TXSTAT_RTC_CTS BIT(2) +#define ATH9K_HTC_TXSTAT_MCS BIT(3) +#define ATH9K_HTC_TXSTAT_CW40 BIT(4) +#define ATH9K_HTC_TXSTAT_SGI BIT(5) + +/* + * Legacy rates are indicated as indices. + * HT rates are indicated as dot11 numbers. + * This allows us to resrict the rate field + * to 4 bits. + */ +#define ATH9K_HTC_TXSTAT_RATE 0x0f +#define ATH9K_HTC_TXSTAT_RATE_S 0 + +#define ATH9K_HTC_TXSTAT_EPID 0xf0 +#define ATH9K_HTC_TXSTAT_EPID_S 4 + +struct __wmi_event_txstatus { + u8 cookie; + u8 ts_rate; /* Also holds EP ID */ + u8 ts_flags; +}; + +struct wmi_event_txstatus { + u8 cnt; + struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS]; +} __packed; + enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, @@ -82,6 +120,7 @@ enum wmi_event_id { WMI_BMISS_EVENTID, WMI_DELBA_EVENTID, WMI_TXRATE_EVENTID, + WMI_TXSTATUS_EVENTID, }; #define MAX_CMD_NUMBER 62 -- GitLab From 3deff76095c4ac4252e27c537db3041f619c23a2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:23 +0530 Subject: [PATCH 0853/5560] ath9k_htc: Increase URB count for REG_IN pipe Using a single URB for receiving WMI events is insufficient, increase it to 64 to not lose WMI events in high throughput situations. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 99 ++++++++++++++---------- drivers/net/wireless/ath/ath9k/hif_usb.h | 4 +- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index e252576760d1..0b63a48462c7 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -566,6 +566,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) case -ESHUTDOWN: goto free; default: + skb_reset_tail_pointer(skb); + skb_trim(skb, 0); + goto resubmit; } @@ -590,23 +593,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, nskb); - - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) { - kfree_skb(nskb); - urb->context = NULL; - } - - return; } resubmit: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); - + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret) + if (ret) { + usb_unanchor_urb(urb); goto free; + } return; free: @@ -747,43 +742,67 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) return ret; } -static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) +static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - if (hif_dev->reg_in_urb) { - usb_kill_urb(hif_dev->reg_in_urb); - if (hif_dev->reg_in_urb->context) - kfree_skb((void *)hif_dev->reg_in_urb->context); - usb_free_urb(hif_dev->reg_in_urb); - hif_dev->reg_in_urb = NULL; - } + usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); } -static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) +static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - struct sk_buff *skb; + struct urb *urb = NULL; + struct sk_buff *skb = NULL; + int i, ret; - hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (hif_dev->reg_in_urb == NULL) - return -ENOMEM; + init_usb_anchor(&hif_dev->reg_in_submitted); - skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); - if (!skb) - goto err; + for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { - usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, - usb_rcvbulkpipe(hif_dev->udev, - USB_REG_IN_PIPE), - skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb); + /* Allocate URB */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (urb == NULL) { + ret = -ENOMEM; + goto err_urb; + } - if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) - goto err; + /* Allocate buffer */ + skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; + goto err_skb; + } + + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), + skb->data, MAX_REG_IN_BUF_SIZE, + ath9k_hif_usb_reg_in_cb, skb); + + /* Anchor URB */ + usb_anchor_urb(urb, &hif_dev->reg_in_submitted); + + /* Submit URB */ + ret = usb_submit_urb(urb, GFP_KERNEL); + if (ret) { + usb_unanchor_urb(urb); + goto err_submit; + } + + /* + * Drop reference count. + * This ensures that the URB is freed when killing them. + */ + usb_free_urb(urb); + } return 0; -err: - ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); - return -ENOMEM; +err_submit: + kfree_skb(skb); +err_skb: + usb_free_urb(urb); +err_urb: + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); + return ret; } static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) @@ -800,7 +819,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) goto err_rx; /* Register Read */ - if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) + if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) goto err_reg; return 0; @@ -815,7 +834,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->regout_submitted); - ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); + ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); ath9k_hif_usb_dealloc_tx_urbs(hif_dev); ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index f82b32bbf4e2..8b98d646e91a 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -40,7 +40,7 @@ #define MAX_PKT_NUM_IN_TRANSFER 10 #define MAX_REG_OUT_URB_NUM 1 -#define MAX_REG_OUT_BUF_NUM 8 +#define MAX_REG_IN_URB_NUM 64 #define MAX_REG_IN_BUF_SIZE 64 @@ -90,9 +90,9 @@ struct hif_device_usb { const struct firmware *firmware; struct htc_target *htc_handle; struct hif_usb_tx tx; - struct urb *reg_in_urb; struct usb_anchor regout_submitted; struct usb_anchor rx_submitted; + struct usb_anchor reg_in_submitted; struct sk_buff *remain_skb; const char *fw_name; int rx_remain_len; -- GitLab From 8e86a54715c4102a8ed697939de9ebd9715dc59c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:29 +0530 Subject: [PATCH 0854/5560] ath9k_htc: Fix TX queue management Handle queue start/stop properly by maintaining a counter to check if the pending frame count has exceeded the threshold. Otherwise, packets would be dropped needlessly. While at it, use a simple flag to track queue status and use helper functions too. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 13 +++++-- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 4 ++ drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 21 ++++------ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 39 ++++++++++++++----- 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 3185fe7568cb..fc4c466e7563 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -262,11 +262,16 @@ struct ath9k_htc_rx { spinlock_t rxbuflock; }; -struct ath9k_htc_tx { - bool tx_queues_stop; - spinlock_t tx_lock; +#define ATH9K_HTC_TX_RESERVE 10 +#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) + +#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) +struct ath9k_htc_tx { + u8 flags; + int queued_cnt; struct sk_buff_head tx_queue; + spinlock_t tx_lock; }; struct ath9k_htc_tx_ctl { @@ -532,6 +537,8 @@ int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); int get_hw_qnum(u16 queue, int *hwq_map); int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo); +void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); +void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 713def184519..de37d46bb0d0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -326,6 +326,10 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, ath_dbg(common, ATH_DBG_FATAL, "Failed to send CAB frame\n"); dev_kfree_skb_any(skb); + } else { + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.queued_cnt++; + spin_unlock_bh(&priv->tx.tx_lock); } next: skb = ieee80211_get_buffered_bc(priv->hw, vif); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 1f6df4a1d224..92e4b312a98b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -399,7 +399,7 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) /* Start TX */ htc_start(priv->htc); spin_lock_bh(&priv->tx.tx_lock); - priv->tx.tx_queues_stop = false; + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ff3a49577a02..690113673d25 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -833,6 +833,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ieee80211_hdr *hdr; struct ath9k_htc_priv *priv = hw->priv; + struct ath_common *common = ath9k_hw_common(priv->ah); int padpos, padsize, ret; hdr = (struct ieee80211_hdr *) skb->data; @@ -841,28 +842,22 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) padpos = ath9k_cmn_padpos(hdr->frame_control); padsize = padpos & 3; if (padsize && skb->len > padpos) { - if (skb_headroom(skb) < padsize) + if (skb_headroom(skb) < padsize) { + ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n"); goto fail_tx; + } skb_push(skb, padsize); memmove(skb->data, skb->data + padsize, padpos); } ret = ath9k_htc_tx_start(priv, skb, false); if (ret != 0) { - if (ret == -ENOMEM) { - ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Stopping TX queues\n"); - ieee80211_stop_queues(hw); - spin_lock_bh(&priv->tx.tx_lock); - priv->tx.tx_queues_stop = true; - spin_unlock_bh(&priv->tx.tx_lock); - } else { - ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Tx failed\n"); - } + ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); goto fail_tx; } + ath9k_htc_check_stop_queues(priv); + return; fail_tx: @@ -924,7 +919,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) htc_start(priv->htc); spin_lock_bh(&priv->tx.tx_lock); - priv->tx.tx_queues_stop = false; + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; spin_unlock_bh(&priv->tx.tx_lock); ieee80211_wake_queues(hw); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 6f7987d7b6b0..1cbe194179ab 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -53,6 +53,29 @@ int get_hw_qnum(u16 queue, int *hwq_map) } } +void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv) +{ + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.queued_cnt++; + if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) && + !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { + priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP; + ieee80211_stop_queues(priv->hw); + } + spin_unlock_bh(&priv->tx.tx_lock); +} + +void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) +{ + spin_lock_bh(&priv->tx.tx_lock); + if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) && + (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) { + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; + ieee80211_wake_queues(priv->hw); + } + spin_unlock_bh(&priv->tx.tx_lock); +} + int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -302,21 +325,17 @@ void ath9k_tx_tasklet(unsigned long data) rcu_read_unlock(); send_mac80211: + spin_lock_bh(&priv->tx.tx_lock); + if (WARN_ON(--priv->tx.queued_cnt < 0)) + priv->tx.queued_cnt = 0; + spin_unlock_bh(&priv->tx.tx_lock); + /* Send status to mac80211 */ ieee80211_tx_status(priv->hw, skb); } /* Wake TX queues if needed */ - spin_lock_bh(&priv->tx.tx_lock); - if (priv->tx.tx_queues_stop) { - priv->tx.tx_queues_stop = false; - spin_unlock_bh(&priv->tx.tx_lock); - ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, - "Waking up TX queues\n"); - ieee80211_wake_queues(priv->hw); - return; - } - spin_unlock_bh(&priv->tx.tx_lock); + ath9k_htc_check_wake_queues(priv); } void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, -- GitLab From d67ee5339363608adce786ec8fd62a0fb2b66116 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:35 +0530 Subject: [PATCH 0855/5560] ath9k_htc: Introduce new HTC API A new routine that takes an endpoint explicitly is introduced. The normal htc_send() now retrieves the endpoint from the packet's private data. This would be useful in TX completion when the endpoint ID would be required. While at it, use a helper function to map the queue to endpoint. Data/mgmt/beacon packets use htc_send(), while WMI comamnds pass the endpoint to HTC. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + .../net/wireless/ath/ath9k/htc_drv_beacon.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 56 +++++++++++-------- drivers/net/wireless/ath/ath9k/htc_hst.c | 12 +++- drivers/net/wireless/ath/ath9k/htc_hst.h | 5 +- drivers/net/wireless/ath/ath9k/wmi.c | 2 +- 6 files changed, 49 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index fc4c466e7563..356f49c180b3 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -276,6 +276,7 @@ struct ath9k_htc_tx { struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ + u8 epid; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index de37d46bb0d0..97b116fb4e11 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -391,12 +391,13 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, memset(tx_ctl, 0, sizeof(*tx_ctl)); tx_ctl->type = ATH9K_HTC_BEACON; + tx_ctl->epid = priv->beacon_ep; beacon_hdr.vif_index = avp->index; tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); - ret = htc_send(priv->htc, beacon, priv->beacon_ep); + ret = htc_send(priv->htc, beacon); if (ret != 0) { if (ret == -ENOMEM) { ath_dbg(common, ATH_DBG_BSTUCK, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 1cbe194179ab..d17662fa604a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -76,6 +76,34 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) spin_unlock_bh(&priv->tx.tx_lock); } +static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, + u16 qnum) +{ + enum htc_endpoint_id epid; + + switch (qnum) { + case 0: + TX_QSTAT_INC(WME_AC_VO); + epid = priv->data_vo_ep; + break; + case 1: + TX_QSTAT_INC(WME_AC_VI); + epid = priv->data_vi_ep; + break; + case 2: + TX_QSTAT_INC(WME_AC_BE); + epid = priv->data_be_ep; + break; + case 3: + default: + TX_QSTAT_INC(WME_AC_BK); + epid = priv->data_bk_ep; + break; + } + + return epid; +} + int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -113,7 +141,6 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; struct ath9k_htc_tx_ctl *tx_ctl; - enum htc_endpoint_id epid; u16 qnum; __le16 fc; u8 *tx_fhdr; @@ -197,31 +224,12 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, if (is_cab) { CAB_STAT_INC; - epid = priv->cab_ep; + tx_ctl->epid = priv->cab_ep; goto send; } qnum = skb_get_queue_mapping(skb); - - switch (qnum) { - case 0: - TX_QSTAT_INC(WME_AC_VO); - epid = priv->data_vo_ep; - break; - case 1: - TX_QSTAT_INC(WME_AC_VI); - epid = priv->data_vi_ep; - break; - case 2: - TX_QSTAT_INC(WME_AC_BE); - epid = priv->data_be_ep; - break; - case 3: - default: - TX_QSTAT_INC(WME_AC_BK); - epid = priv->data_bk_ep; - break; - } + tx_ctl->epid = get_htc_epid(priv, qnum); } else { struct tx_mgmt_hdr mgmt_hdr; @@ -251,10 +259,10 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); - epid = priv->mgmt_ep; + tx_ctl->epid = priv->mgmt_ep; } send: - return htc_send(priv->htc, skb, epid); + return htc_send(priv->htc, skb); } static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 6ee53de45c6a..be87f4757bf5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -286,8 +286,16 @@ int htc_connect_service(struct htc_target *target, return ret; } -int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id epid) +int htc_send(struct htc_target *target, struct sk_buff *skb) +{ + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid); +} + +int htc_send_epid(struct htc_target *target, struct sk_buff *skb, + enum htc_endpoint_id epid) { return htc_issue_send(target, skb, skb->len, 0, epid); } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 3531552672e0..064a324b5228 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -204,8 +204,9 @@ int htc_init(struct htc_target *target); int htc_connect_service(struct htc_target *target, struct htc_service_connreq *service_connreq, enum htc_endpoint_id *conn_rsp_eid); -int htc_send(struct htc_target *target, struct sk_buff *skb, - enum htc_endpoint_id eid); +int htc_send(struct htc_target *target, struct sk_buff *skb); +int htc_send_epid(struct htc_target *target, struct sk_buff *skb, + enum htc_endpoint_id epid); void htc_stop(struct htc_target *target); void htc_start(struct htc_target *target); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 83d1e0e5dd8c..e66f6c333028 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -267,7 +267,7 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, hdr->command_id = cpu_to_be16(cmd); hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); - return htc_send(wmi->htc, skb, wmi->ctrl_epid); + return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid); } int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, -- GitLab From 729bd3ab460d3bb8236cc8f6fd0289201124112d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:41 +0530 Subject: [PATCH 0856/5560] ath9k_htc: Move endpoint header parsing to TX tasklet There is no need to do endpoint header removal in the ISR. Also, this is needed when TX slot management is added later on. Use a helper function to strip the driver header. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 68 ++++++++++++------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 356f49c180b3..0831ca3de95c 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -277,6 +277,7 @@ struct ath9k_htc_tx { struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ u8 epid; + u8 txok; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index d17662fa604a..7b218dad55d9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -104,6 +104,30 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, return epid; } +static inline int strip_drv_header(struct ath9k_htc_priv *priv, + struct sk_buff *skb) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + + if (tx_ctl->epid == priv->mgmt_ep) { + skb_pull(skb, sizeof(struct tx_mgmt_hdr)); + } else if ((tx_ctl->epid == priv->data_bk_ep) || + (tx_ctl->epid == priv->data_be_ep) || + (tx_ctl->epid == priv->data_vi_ep) || + (tx_ctl->epid == priv->data_vo_ep) || + (tx_ctl->epid == priv->cab_ep)) { + skb_pull(skb, sizeof(struct tx_frame_hdr)); + } else { + ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); + return -EINVAL; + } + + return 0; +} + int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -281,22 +305,40 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, void ath9k_tx_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + struct ath9k_htc_tx_ctl *tx_ctl; struct ieee80211_vif *vif; struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info; struct sk_buff *skb = NULL; __le16 fc; + bool txok; while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + if (strip_drv_header(priv, skb) < 0) { + dev_kfree_skb_any(skb); + continue; + } + + tx_ctl = HTC_SKB_CB(skb); hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; tx_info = IEEE80211_SKB_CB(skb); vif = tx_info->control.vif; + txok = tx_ctl->txok; memset(&tx_info->status, 0, sizeof(tx_info->status)); + /* + * URB submission failed for this frame, it never reached + * the target. + */ + if (!txok) + goto send_mac80211; + + tx_info->flags |= IEEE80211_TX_STAT_ACK; + if (!vif) goto send_mac80211; @@ -350,30 +392,10 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, bool txok) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; - struct ath_common *common = ath9k_hw_common(priv->ah); - struct ieee80211_tx_info *tx_info; - - if (!skb) - return; - - if (ep_id == priv->mgmt_ep) { - skb_pull(skb, sizeof(struct tx_mgmt_hdr)); - } else if ((ep_id == priv->data_bk_ep) || - (ep_id == priv->data_be_ep) || - (ep_id == priv->data_vi_ep) || - (ep_id == priv->data_vo_ep) || - (ep_id == priv->cab_ep)) { - skb_pull(skb, sizeof(struct tx_frame_hdr)); - } else { - ath_err(common, "Unsupported TX EPID: %d\n", ep_id); - dev_kfree_skb_any(skb); - return; - } - - tx_info = IEEE80211_SKB_CB(skb); + struct ath9k_htc_tx_ctl *tx_ctl; - if (txok) - tx_info->flags |= IEEE80211_TX_STAT_ACK; + tx_ctl = HTC_SKB_CB(skb); + tx_ctl->txok = txok; skb_queue_tail(&priv->tx.tx_queue, skb); tasklet_schedule(&priv->tx_tasklet); -- GitLab From 2c5d57f004673a9c8658e20b1fa3f992b5a10f70 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:47 +0530 Subject: [PATCH 0857/5560] ath9k_htc: Add TX slots Maintain a bitmap of slots for transmission and update the cookie field for every packet with the slot value. This value would be used for matching packets when TX completion processing is added. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 5 +- .../net/wireless/ath/ath9k/htc_drv_beacon.c | 17 +++++-- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 14 +++-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 51 ++++++++++++++++--- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0831ca3de95c..45cf75579438 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -271,6 +271,7 @@ struct ath9k_htc_tx { u8 flags; int queued_cnt; struct sk_buff_head tx_queue; + DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); spinlock_t tx_lock; }; @@ -532,7 +533,7 @@ void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, - struct sk_buff *skb, bool is_cab); + struct sk_buff *skb, u8 slot, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); @@ -541,6 +542,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo); void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); +int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); +void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 97b116fb4e11..bf7ef1b7eb3f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -299,7 +299,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif; struct sk_buff *skb; struct ieee80211_hdr *hdr; - int padpos, padsize, ret; + int padpos, padsize, ret, tx_slot; spin_lock_bh(&priv->beacon_lock); @@ -321,11 +321,20 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, memmove(skb->data, skb->data + padsize, padpos); } - ret = ath9k_htc_tx_start(priv, skb, true); + tx_slot = ath9k_htc_tx_get_slot(priv); + if (tx_slot != 0) { + ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); + dev_kfree_skb_any(skb); + goto next; + } + + ret = ath9k_htc_tx_start(priv, skb, tx_slot, true); if (ret != 0) { - ath_dbg(common, ATH_DBG_FATAL, - "Failed to send CAB frame\n"); + ath9k_htc_tx_clear_slot(priv, tx_slot); dev_kfree_skb_any(skb); + + ath_dbg(common, ATH_DBG_XMIT, + "Failed to send CAB frame\n"); } else { spin_lock_bh(&priv->tx.tx_lock); priv->tx.queued_cnt++; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 690113673d25..c7e056b40e1d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -834,7 +834,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct ieee80211_hdr *hdr; struct ath9k_htc_priv *priv = hw->priv; struct ath_common *common = ath9k_hw_common(priv->ah); - int padpos, padsize, ret; + int padpos, padsize, ret, slot; hdr = (struct ieee80211_hdr *) skb->data; @@ -850,16 +850,24 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) memmove(skb->data, skb->data + padsize, padpos); } - ret = ath9k_htc_tx_start(priv, skb, false); + slot = ath9k_htc_tx_get_slot(priv); + if (slot < 0) { + ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n"); + goto fail_tx; + } + + ret = ath9k_htc_tx_start(priv, skb, slot, false); if (ret != 0) { ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); - goto fail_tx; + goto clear_slot; } ath9k_htc_check_stop_queues(priv); return; +clear_slot: + ath9k_htc_tx_clear_slot(priv, slot); fail_tx: dev_kfree_skb_any(skb); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 7b218dad55d9..ee5b3e281cd3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -76,6 +76,29 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv) spin_unlock_bh(&priv->tx.tx_lock); } +int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv) +{ + int slot; + + spin_lock_bh(&priv->tx.tx_lock); + slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM); + if (slot >= MAX_TX_BUF_NUM) { + spin_unlock_bh(&priv->tx.tx_lock); + return -ENOBUFS; + } + __set_bit(slot, priv->tx.tx_slot); + spin_unlock_bh(&priv->tx.tx_lock); + + return slot; +} + +void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) +{ + spin_lock_bh(&priv->tx.tx_lock); + __clear_bit(slot, priv->tx.tx_slot); + spin_unlock_bh(&priv->tx.tx_lock); +} + static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, u16 qnum) { @@ -104,28 +127,38 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, return epid; } +/* + * Removes the driver header and returns the TX slot number + */ static inline int strip_drv_header(struct ath9k_htc_priv *priv, struct sk_buff *skb) { struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_tx_ctl *tx_ctl; + int slot; tx_ctl = HTC_SKB_CB(skb); if (tx_ctl->epid == priv->mgmt_ep) { + struct tx_mgmt_hdr *tx_mhdr = + (struct tx_mgmt_hdr *)skb->data; + slot = tx_mhdr->cookie; skb_pull(skb, sizeof(struct tx_mgmt_hdr)); } else if ((tx_ctl->epid == priv->data_bk_ep) || (tx_ctl->epid == priv->data_be_ep) || (tx_ctl->epid == priv->data_vi_ep) || (tx_ctl->epid == priv->data_vo_ep) || (tx_ctl->epid == priv->cab_ep)) { + struct tx_frame_hdr *tx_fhdr = + (struct tx_frame_hdr *)skb->data; + slot = tx_fhdr->cookie; skb_pull(skb, sizeof(struct tx_frame_hdr)); } else { ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid); - return -EINVAL; + slot = -EINVAL; } - return 0; + return slot; } int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, @@ -155,7 +188,8 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, } int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, - struct sk_buff *skb, bool is_cab) + struct sk_buff *skb, + u8 slot, bool is_cab) { struct ieee80211_hdr *hdr; struct ieee80211_mgmt *mgmt; @@ -212,6 +246,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_hdr.node_idx = sta_idx; tx_hdr.vif_idx = vif_idx; + tx_hdr.cookie = slot; if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_ctl->type = ATH9K_HTC_AMPDU; @@ -274,6 +309,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, mgmt_hdr.vif_idx = vif_idx; mgmt_hdr.tidno = 0; mgmt_hdr.flags = 0; + mgmt_hdr.cookie = slot; mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) @@ -313,10 +349,12 @@ void ath9k_tx_tasklet(unsigned long data) struct sk_buff *skb = NULL; __le16 fc; bool txok; + int slot; while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { - if (strip_drv_header(priv, skb) < 0) { + slot = strip_drv_header(priv, skb); + if (slot < 0) { dev_kfree_skb_any(skb); continue; } @@ -347,8 +385,7 @@ void ath9k_tx_tasklet(unsigned long data) sta = ieee80211_find_sta(vif, hdr->addr1); if (!sta) { rcu_read_unlock(); - ieee80211_tx_status(priv->hw, skb); - continue; + goto send_mac80211; } /* Check if we need to start aggregation */ @@ -380,6 +417,8 @@ void ath9k_tx_tasklet(unsigned long data) priv->tx.queued_cnt = 0; spin_unlock_bh(&priv->tx.tx_lock); + ath9k_htc_tx_clear_slot(priv, slot); + /* Send status to mac80211 */ ieee80211_tx_status(priv->hw, skb); } -- GitLab From f2820f4583b233827f10d91adea70225e196d852 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:54 +0530 Subject: [PATCH 0858/5560] ath9k_htc: Use helper functions for TX processing Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 137 ++++++++++-------- 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index ee5b3e281cd3..944440c84c49 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -325,8 +325,8 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, return htc_send(priv->htc, skb); } -static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, - struct ath9k_htc_sta *ista, u8 tid) +static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, + struct ath9k_htc_sta *ista, u8 tid) { bool ret = false; @@ -338,89 +338,98 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, return ret; } -void ath9k_tx_tasklet(unsigned long data) +static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct sk_buff *skb) { - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - struct ath9k_htc_tx_ctl *tx_ctl; - struct ieee80211_vif *vif; struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *tx_info; - struct sk_buff *skb = NULL; __le16 fc; - bool txok; - int slot; - while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + hdr = (struct ieee80211_hdr *) skb->data; + fc = hdr->frame_control; - slot = strip_drv_header(priv, skb); - if (slot < 0) { - dev_kfree_skb_any(skb); - continue; - } + rcu_read_lock(); - tx_ctl = HTC_SKB_CB(skb); - hdr = (struct ieee80211_hdr *) skb->data; - fc = hdr->frame_control; - tx_info = IEEE80211_SKB_CB(skb); - vif = tx_info->control.vif; - txok = tx_ctl->txok; + sta = ieee80211_find_sta(vif, hdr->addr1); + if (!sta) { + rcu_read_unlock(); + return; + } - memset(&tx_info->status, 0, sizeof(tx_info->status)); + if (sta && conf_is_ht(&priv->hw->conf) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + if (ieee80211_is_data_qos(fc)) { + u8 *qc, tid; + struct ath9k_htc_sta *ista; - /* - * URB submission failed for this frame, it never reached - * the target. - */ - if (!txok) - goto send_mac80211; + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + ista = (struct ath9k_htc_sta *)sta->drv_priv; + if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) { + ieee80211_start_tx_ba_session(sta, tid, 0); + spin_lock_bh(&priv->tx.tx_lock); + ista->tid_state[tid] = AGGR_PROGRESS; + spin_unlock_bh(&priv->tx.tx_lock); + } + } + } - tx_info->flags |= IEEE80211_TX_STAT_ACK; + rcu_read_unlock(); +} - if (!vif) - goto send_mac80211; +static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, + struct sk_buff *skb) +{ + struct ieee80211_vif *vif; + struct ath9k_htc_tx_ctl *tx_ctl; + struct ieee80211_tx_info *tx_info; + bool txok; + int slot; - rcu_read_lock(); + slot = strip_drv_header(priv, skb); + if (slot < 0) { + dev_kfree_skb_any(skb); + return; + } - sta = ieee80211_find_sta(vif, hdr->addr1); - if (!sta) { - rcu_read_unlock(); - goto send_mac80211; - } + tx_ctl = HTC_SKB_CB(skb); + txok = tx_ctl->txok; + tx_info = IEEE80211_SKB_CB(skb); + vif = tx_info->control.vif; - /* Check if we need to start aggregation */ + memset(&tx_info->status, 0, sizeof(tx_info->status)); - if (sta && conf_is_ht(&priv->hw->conf) && - !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { - if (ieee80211_is_data_qos(fc)) { - u8 *qc, tid; - struct ath9k_htc_sta *ista; + /* + * URB submission failed for this frame, it never reached + * the target. + */ + if (!txok || !vif) + goto send_mac80211; - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - ista = (struct ath9k_htc_sta *)sta->drv_priv; + tx_info->flags |= IEEE80211_TX_STAT_ACK; - if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { - ieee80211_start_tx_ba_session(sta, tid, 0); - spin_lock_bh(&priv->tx.tx_lock); - ista->tid_state[tid] = AGGR_PROGRESS; - spin_unlock_bh(&priv->tx.tx_lock); - } - } - } + ath9k_htc_check_tx_aggr(priv, vif, skb); - rcu_read_unlock(); +send_mac80211: + spin_lock_bh(&priv->tx.tx_lock); + if (WARN_ON(--priv->tx.queued_cnt < 0)) + priv->tx.queued_cnt = 0; + spin_unlock_bh(&priv->tx.tx_lock); - send_mac80211: - spin_lock_bh(&priv->tx.tx_lock); - if (WARN_ON(--priv->tx.queued_cnt < 0)) - priv->tx.queued_cnt = 0; - spin_unlock_bh(&priv->tx.tx_lock); + ath9k_htc_tx_clear_slot(priv, slot); + + /* Send status to mac80211 */ + ieee80211_tx_status(priv->hw, skb); +} - ath9k_htc_tx_clear_slot(priv, slot); +void ath9k_tx_tasklet(unsigned long data) +{ + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + struct sk_buff *skb = NULL; - /* Send status to mac80211 */ - ieee80211_tx_status(priv->hw, skb); + while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + ath9k_htc_tx_process(priv, skb); } /* Wake TX queues if needed */ -- GitLab From b587fc81a80b9656f64e89fe0a106ffa4b35abca Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:25:59 +0530 Subject: [PATCH 0859/5560] ath9k_htc: Drain pending TX frames properly When doing a channel set or a reset operation the pending frames queued up for transmission have to be flushed and sent to mac80211. Fixing this has to be done in two separate steps: * Flush queued frames and kill the URB TX completion handler. * Complete all the frames that in the TX pending queue. This patch adds proper support for draining and all the callsites namely, channel change/reset/idle/stop are fixed. A separate queue is used for handling failed frames. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 55 +++++++------------ drivers/net/wireless/ath/ath9k/htc.h | 6 +- .../net/wireless/ath/ath9k/htc_drv_debug.c | 8 +-- drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 15 +++-- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 31 ++++++++++- 6 files changed, 69 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 0b63a48462c7..db07e7b93204 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -131,7 +131,19 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, while ((skb = __skb_dequeue(list)) != NULL) { dev_kfree_skb_any(skb); - TX_STAT_INC(skb_dropped); + } +} + +static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, + struct sk_buff_head *queue, + bool txok) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(queue)) != NULL) { + ath9k_htc_txcompletion_cb(hif_dev->htc_handle, + skb, txok); + (txok) ? TX_STAT_INC(skb_success) : TX_STAT_INC(skb_failed); } } @@ -139,7 +151,7 @@ static void hif_usb_tx_cb(struct urb *urb) { struct tx_buf *tx_buf = (struct tx_buf *) urb->context; struct hif_device_usb *hif_dev; - struct sk_buff *skb; + bool txok = true; if (!tx_buf || !tx_buf->hif_dev) return; @@ -153,10 +165,7 @@ static void hif_usb_tx_cb(struct urb *urb) case -ECONNRESET: case -ENODEV: case -ESHUTDOWN: - /* - * The URB has been killed, free the SKBs. - */ - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); + txok = false; /* * If the URBs are being flushed, no need to add this @@ -165,41 +174,19 @@ static void hif_usb_tx_cb(struct urb *urb) spin_lock(&hif_dev->tx.tx_lock); if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { spin_unlock(&hif_dev->tx.tx_lock); + ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); 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; + break; default: + txok = false; break; } - /* - * 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); - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); - goto add_free; - } - spin_unlock(&hif_dev->tx.tx_lock); - - /* Complete the queued SKBs. */ - while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { - ath9k_htc_txcompletion_cb(hif_dev->htc_handle, - skb, 1); - TX_STAT_INC(skb_completed); - } + ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok); -add_free: /* Re-initialize the SKB queue */ tx_buf->len = tx_buf->offset = 0; __skb_queue_head_init(&tx_buf->skb_queue); @@ -272,7 +259,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); if (ret) { tx_buf->len = tx_buf->offset = 0; - ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); + ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false); __skb_queue_head_init(&tx_buf->skb_queue); list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); hif_dev->tx.tx_buf_cnt++; @@ -342,7 +329,7 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) unsigned long flags; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); - ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); + ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false); hif_dev->tx.tx_skb_cnt = 0; hif_dev->tx.flags |= HIF_USB_TX_STOP; spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 45cf75579438..0d2e2b10358d 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -271,6 +271,7 @@ struct ath9k_htc_tx { u8 flags; int queued_cnt; struct sk_buff_head tx_queue; + struct sk_buff_head tx_failed; DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); spinlock_t tx_lock; }; @@ -305,8 +306,8 @@ struct ath_tx_stats { u32 buf_queued; u32 buf_completed; u32 skb_queued; - u32 skb_completed; - u32 skb_dropped; + u32 skb_success; + u32 skb_failed; u32 cab_queued; u32 queue_stats[WME_NUM_AC]; }; @@ -544,6 +545,7 @@ void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv); void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); +void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 6fc6cb749362..91a486cca32a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -88,11 +88,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, "%20s : %10u\n", "SKBs queued", priv->debug.tx_stats.skb_queued); len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.tx_stats.skb_completed); + "%20s : %10u\n", "SKBs success", + priv->debug.tx_stats.skb_success); len += snprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs dropped", - priv->debug.tx_stats.skb_dropped); + "%20s : %10u\n", "SKBs failed", + priv->debug.tx_stats.skb_failed); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "CAB queued", priv->debug.tx_stats.cab_queued); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 92e4b312a98b..dc0b33d01210 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -429,9 +429,8 @@ void ath9k_htc_radio_disable(struct ieee80211_hw *hw) /* Stop TX */ ieee80211_stop_queues(hw); - htc_stop(priv->htc); + ath9k_htc_tx_drain(priv); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); - skb_queue_purge(&priv->tx.tx_queue); /* Stop RX */ WMI_CMD(WMI_STOP_RECV_CMDID); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index c7e056b40e1d..fb9ff1188a0a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -193,7 +193,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ath9k_htc_stop_ani(priv); ieee80211_stop_queues(priv->hw); - htc_stop(priv->htc); + + ath9k_htc_tx_drain(priv); + WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); @@ -248,7 +250,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); ath9k_htc_ps_wakeup(priv); - htc_stop(priv->htc); + + ath9k_htc_tx_drain(priv); + WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); @@ -263,6 +267,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, if (!fastcc) caldata = &priv->caldata; + ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (ret) { ath_err(common, @@ -960,16 +965,14 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) } ath9k_htc_ps_wakeup(priv); - htc_stop(priv->htc); + WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); tasklet_kill(&priv->rx_tasklet); - tasklet_kill(&priv->tx_tasklet); - - skb_queue_purge(&priv->tx.tx_queue); + ath9k_htc_tx_drain(priv); ath9k_wmi_event_drain(priv); mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 944440c84c49..9e0c34b0a794 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -423,6 +423,26 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, ieee80211_tx_status(priv->hw, skb); } +void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) +{ + struct sk_buff *skb = NULL; + + /* + * Ensure that all pending TX frames are flushed, + * and that the TX completion tasklet is killed. + */ + htc_stop(priv->htc); + tasklet_kill(&priv->tx_tasklet); + + while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { + ath9k_htc_tx_process(priv, skb); + } + + while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { + ath9k_htc_tx_process(priv, skb); + } +} + void ath9k_tx_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; @@ -432,6 +452,10 @@ void ath9k_tx_tasklet(unsigned long data) ath9k_htc_tx_process(priv, skb); } + while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { + ath9k_htc_tx_process(priv, skb); + } + /* Wake TX queues if needed */ ath9k_htc_check_wake_queues(priv); } @@ -445,13 +469,18 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, tx_ctl = HTC_SKB_CB(skb); tx_ctl->txok = txok; - skb_queue_tail(&priv->tx.tx_queue, skb); + if (txok) + skb_queue_tail(&priv->tx.tx_queue, skb); + else + skb_queue_tail(&priv->tx.tx_failed, skb); + tasklet_schedule(&priv->tx_tasklet); } int ath9k_tx_init(struct ath9k_htc_priv *priv) { skb_queue_head_init(&priv->tx.tx_queue); + skb_queue_head_init(&priv->tx.tx_failed); return 0; } -- GitLab From e1fe7c38d39f8f6ebdffc3a55e2ec6e2ec0d1872 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:06 +0530 Subject: [PATCH 0860/5560] ath9k_htc: Optimize HTC start/stop API There is no point in looping over all the endpoints, since the HIF layer uses the start/stop APIs only for the TX pipe. Simplify the API accordingly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++-- drivers/net/wireless/ath/ath9k/htc_hst.c | 19 ++----------------- drivers/net/wireless/ath/ath9k/htc_hst.h | 4 ++-- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index db07e7b93204..b3f23c2be738 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -310,7 +310,7 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) return 0; } -static void hif_usb_start(void *hif_handle, u8 pipe_id) +static void hif_usb_start(void *hif_handle) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; unsigned long flags; @@ -322,7 +322,7 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); } -static void hif_usb_stop(void *hif_handle, u8 pipe_id) +static void hif_usb_stop(void *hif_handle) { struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index be87f4757bf5..7ced8ab1ae4c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -302,27 +302,12 @@ int htc_send_epid(struct htc_target *target, struct sk_buff *skb, void htc_stop(struct htc_target *target) { - enum htc_endpoint_id epid; - struct htc_endpoint *endpoint; - - for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { - endpoint = &target->endpoint[epid]; - if (endpoint->service_id != 0) - target->hif->stop(target->hif_dev, endpoint->ul_pipeid); - } + target->hif->stop(target->hif_dev); } void htc_start(struct htc_target *target) { - enum htc_endpoint_id epid; - struct htc_endpoint *endpoint; - - for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { - endpoint = &target->endpoint[epid]; - if (endpoint->service_id != 0) - target->hif->start(target->hif_dev, - endpoint->ul_pipeid); - } + target->hif->start(target->hif_dev); } void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 064a324b5228..191e3c0837a6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -33,8 +33,8 @@ struct ath9k_htc_hif { u8 control_dl_pipe; u8 control_ul_pipe; - void (*start) (void *hif_handle, u8 pipe); - void (*stop) (void *hif_handle, u8 pipe); + void (*start) (void *hif_handle); + void (*stop) (void *hif_handle); int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); }; -- GitLab From 84c9e164468bd707e52b440e1c34bc3c85299332 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:11 +0530 Subject: [PATCH 0861/5560] ath9k_htc: Drain packets on station removal When a station entry is removed, there could still be pending packets destined for that station in the HIF layer. Sending these to the target is not necessary, so drain them in the driver itself. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 35 +++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_main.c | 3 ++ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 +++++ drivers/net/wireless/ath/ath9k/htc_hst.c | 5 +++ drivers/net/wireless/ath/ath9k/htc_hst.h | 2 ++ 6 files changed, 54 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index b3f23c2be738..7fae79d16665 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -363,6 +363,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) return ret; } +static inline bool check_index(struct sk_buff *skb, u8 idx) +{ + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + + if ((tx_ctl->type == ATH9K_HTC_AMPDU) && + (tx_ctl->sta_idx == idx)) + return true; + + return false; +} + +static void hif_usb_sta_drain(void *hif_handle, u8 idx) +{ + struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; + struct sk_buff *skb, *tmp; + unsigned long flags; + + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + + skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) { + if (check_index(skb, idx)) { + __skb_unlink(skb, &hif_dev->tx.tx_skb_queue); + ath9k_htc_txcompletion_cb(hif_dev->htc_handle, + skb, false); + hif_dev->tx.tx_skb_cnt--; + TX_STAT_INC(skb_failed); + } + } + + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); +} + static struct ath9k_htc_hif hif_usb = { .transport = ATH9K_HIF_USB, .name = "ath9k_hif_usb", @@ -372,6 +406,7 @@ static struct ath9k_htc_hif hif_usb = { .start = hif_usb_start, .stop = hif_usb_stop, + .sta_drain = hif_usb_sta_drain, .send = hif_usb_send, }; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0d2e2b10358d..41823fd6d9ad 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -280,6 +280,7 @@ struct ath9k_htc_tx_ctl { u8 type; /* ATH9K_HTC_* */ u8 epid; u8 txok; + u8 sta_idx; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index fb9ff1188a0a..ae85cc4373f0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1303,10 +1303,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { struct ath9k_htc_priv *priv = hw->priv; + struct ath9k_htc_sta *ista; int ret; mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); + ista = (struct ath9k_htc_sta *) sta->drv_priv; + htc_sta_drain(priv->htc, ista->index); ret = ath9k_htc_remove_station(priv, vif, sta); ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 9e0c34b0a794..0790070a7f63 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -248,6 +248,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, tx_hdr.vif_idx = vif_idx; tx_hdr.cookie = slot; + /* + * This is a bit redundant but it helps to get + * the per-packet index quickly when draining the + * TX queue in the HIF layer. Otherwise we would + * have to parse the packet contents ... + */ + tx_ctl->sta_idx = sta_idx; + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_ctl->type = ATH9K_HTC_AMPDU; tx_hdr.data_type = ATH9K_HTC_AMPDU; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 7ced8ab1ae4c..5c76352b1319 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -310,6 +310,11 @@ void htc_start(struct htc_target *target) target->hif->start(target->hif_dev); } +void htc_sta_drain(struct htc_target *target, u8 idx) +{ + target->hif->sta_drain(target->hif_dev, idx); +} + void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, struct sk_buff *skb, bool txok) { diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index 191e3c0837a6..cb9174ade53e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -35,6 +35,7 @@ struct ath9k_htc_hif { void (*start) (void *hif_handle); void (*stop) (void *hif_handle); + void (*sta_drain) (void *hif_handle, u8 idx); int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf); }; @@ -209,6 +210,7 @@ int htc_send_epid(struct htc_target *target, struct sk_buff *skb, enum htc_endpoint_id epid); void htc_stop(struct htc_target *target); void htc_start(struct htc_target *target); +void htc_sta_drain(struct htc_target *target, u8 idx); void ath9k_htc_rx_msg(struct htc_target *htc_handle, struct sk_buff *skb, u32 len, u8 pipe_id); -- GitLab From 27876a29de221186c9d5883e5fe5f6da18ef9a45 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:18 +0530 Subject: [PATCH 0862/5560] ath9k_htc: Add support for TX completion Now that the infrastructure is in place, process WMI TX status events and complete packets. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 14 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 208 +++++++++++++++--- drivers/net/wireless/ath/ath9k/wmi.c | 10 + drivers/net/wireless/ath/ath9k/wmi.h | 4 +- 5 files changed, 207 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 41823fd6d9ad..6c103edf890a 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -266,11 +266,17 @@ struct ath9k_htc_rx { #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) +#define ATH9K_HTC_OP_TX_DRAIN BIT(1) struct ath9k_htc_tx { u8 flags; int queued_cnt; - struct sk_buff_head tx_queue; + struct sk_buff_head mgmt_ep_queue; + struct sk_buff_head cab_ep_queue; + struct sk_buff_head data_be_queue; + struct sk_buff_head data_bk_queue; + struct sk_buff_head data_vi_queue; + struct sk_buff_head data_vo_queue; struct sk_buff_head tx_failed; DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); spinlock_t tx_lock; @@ -465,8 +471,8 @@ struct ath9k_htc_priv { struct tasklet_struct swba_tasklet; struct tasklet_struct rx_tasklet; - struct tasklet_struct tx_tasklet; struct delayed_work ani_work; + struct tasklet_struct tx_failed_tasklet; struct work_struct ps_work; struct work_struct fatal_work; @@ -533,7 +539,6 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); -void ath9k_tx_tasklet(unsigned long data); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb, u8 slot, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); @@ -547,6 +552,9 @@ void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv); int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv); void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot); void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); +void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); +void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); +void ath9k_tx_failed_tasklet(unsigned long data); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index c270da7be10f..afceeaa6b916 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, mutex_init(&priv->htc_pm_lock); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, (unsigned long)priv); - tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, + tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet, (unsigned long)priv); INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 0790070a7f63..a9b6bb1ef287 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -99,8 +99,8 @@ void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot) spin_unlock_bh(&priv->tx.tx_lock); } -static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, - u16 qnum) +static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, + u16 qnum) { enum htc_endpoint_id epid; @@ -127,6 +127,30 @@ static enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, return epid; } +static inline struct sk_buff_head* +get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct sk_buff_head *epid_queue = NULL; + + if (epid == priv->mgmt_ep) + epid_queue = &priv->tx.mgmt_ep_queue; + else if (epid == priv->cab_ep) + epid_queue = &priv->tx.cab_ep_queue; + else if (epid == priv->data_be_ep) + epid_queue = &priv->tx.data_be_queue; + else if (epid == priv->data_bk_ep) + epid_queue = &priv->tx.data_bk_queue; + else if (epid == priv->data_vi_ep) + epid_queue = &priv->tx.data_vi_queue; + else if (epid == priv->data_vo_ep) + epid_queue = &priv->tx.data_vo_queue; + else + ath_err(common, "Invalid EPID: %d\n", epid); + + return epid_queue; +} + /* * Removes the driver header and returns the TX slot number */ @@ -387,11 +411,15 @@ static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, } static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, - struct sk_buff *skb) + struct sk_buff *skb, + struct __wmi_event_txstatus *txs) { struct ieee80211_vif *vif; struct ath9k_htc_tx_ctl *tx_ctl; struct ieee80211_tx_info *tx_info; + struct ieee80211_tx_rate *rate; + struct ieee80211_conf *cur_conf = &priv->hw->conf; + struct ieee80211_supported_band *sband; bool txok; int slot; @@ -405,6 +433,8 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, txok = tx_ctl->txok; tx_info = IEEE80211_SKB_CB(skb); vif = tx_info->control.vif; + rate = &tx_info->status.rates[0]; + sband = priv->hw->wiphy->bands[cur_conf->channel->band]; memset(&tx_info->status, 0, sizeof(tx_info->status)); @@ -412,10 +442,32 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, * URB submission failed for this frame, it never reached * the target. */ - if (!txok || !vif) + if (!txok || !vif || !txs) goto send_mac80211; - tx_info->flags |= IEEE80211_TX_STAT_ACK; + if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT) + tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS) + rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; + + rate->count = 1; + rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE); + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) { + rate->flags |= IEEE80211_TX_RC_MCS; + + if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; + } else { + if (cur_conf->channel->band == IEEE80211_BAND_5GHZ) + rate->idx += 4; /* No CCK rates */ + } ath9k_htc_check_tx_aggr(priv, vif, skb); @@ -431,37 +483,130 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, ieee80211_tx_status(priv->hw, skb); } +static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, + struct sk_buff_head *queue) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(queue)) != NULL) { + ath9k_htc_tx_process(priv, skb, NULL); + } +} + void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) { - struct sk_buff *skb = NULL; + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; + spin_unlock_bh(&priv->tx.tx_lock); /* * Ensure that all pending TX frames are flushed, - * and that the TX completion tasklet is killed. + * and that the TX completion/failed tasklets is killed. */ htc_stop(priv->htc); - tasklet_kill(&priv->tx_tasklet); + tasklet_kill(&priv->wmi->wmi_event_tasklet); + tasklet_kill(&priv->tx_failed_tasklet); - while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { - ath9k_htc_tx_process(priv, skb); - } + ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); + ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); - while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { - ath9k_htc_tx_process(priv, skb); - } + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; + spin_unlock_bh(&priv->tx.tx_lock); } -void ath9k_tx_tasklet(unsigned long data) +void ath9k_tx_failed_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - struct sk_buff *skb = NULL; - while ((skb = skb_dequeue(&priv->tx.tx_queue)) != NULL) { - ath9k_htc_tx_process(priv, skb); + spin_lock_bh(&priv->tx.tx_lock); + if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { + spin_unlock_bh(&priv->tx.tx_lock); + return; } + spin_unlock_bh(&priv->tx.tx_lock); - while ((skb = skb_dequeue(&priv->tx.tx_failed)) != NULL) { - ath9k_htc_tx_process(priv, skb); + ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); +} + +static inline bool check_cookie(struct ath9k_htc_priv *priv, + struct sk_buff *skb, + u8 cookie, u8 epid) +{ + u8 fcookie = 0; + + if (epid == priv->mgmt_ep) { + struct tx_mgmt_hdr *hdr; + hdr = (struct tx_mgmt_hdr *) skb->data; + fcookie = hdr->cookie; + } else if ((epid == priv->data_bk_ep) || + (epid == priv->data_be_ep) || + (epid == priv->data_vi_ep) || + (epid == priv->data_vo_ep) || + (epid == priv->cab_ep)) { + struct tx_frame_hdr *hdr; + hdr = (struct tx_frame_hdr *) skb->data; + fcookie = hdr->cookie; + } + + if (fcookie == cookie) + return true; + + return false; +} + +static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv, + struct __wmi_event_txstatus *txs) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct sk_buff_head *epid_queue; + struct sk_buff *skb, *tmp; + unsigned long flags; + u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID); + + epid_queue = get_htc_epid_queue(priv, epid); + if (!epid_queue) + return NULL; + + spin_lock_irqsave(&epid_queue->lock, flags); + skb_queue_walk_safe(epid_queue, skb, tmp) { + if (check_cookie(priv, skb, txs->cookie, epid)) { + __skb_unlink(skb, epid_queue); + spin_unlock_irqrestore(&epid_queue->lock, flags); + return skb; + } + } + spin_unlock_irqrestore(&epid_queue->lock, flags); + + ath_dbg(common, ATH_DBG_XMIT, + "No matching packet for cookie: %d, epid: %d\n", + txs->cookie, epid); + + return NULL; +} + +void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) +{ + struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; + struct __wmi_event_txstatus *__txs; + struct sk_buff *skb; + int i; + + for (i = 0; i < txs->cnt; i++) { + WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); + + __txs = &txs->txstatus[i]; + + skb = ath9k_htc_tx_get_packet(priv, __txs); + if (!skb) + continue; + + ath9k_htc_tx_process(priv, skb, __txs); } /* Wake TX queues if needed */ @@ -473,21 +618,34 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; struct ath9k_htc_tx_ctl *tx_ctl; + struct sk_buff_head *epid_queue; tx_ctl = HTC_SKB_CB(skb); tx_ctl->txok = txok; - if (txok) - skb_queue_tail(&priv->tx.tx_queue, skb); - else + if (!txok) { skb_queue_tail(&priv->tx.tx_failed, skb); + tasklet_schedule(&priv->tx_failed_tasklet); + return; + } + + epid_queue = get_htc_epid_queue(priv, ep_id); + if (!epid_queue) { + dev_kfree_skb_any(skb); + return; + } - tasklet_schedule(&priv->tx_tasklet); + skb_queue_tail(epid_queue, skb); } int ath9k_tx_init(struct ath9k_htc_priv *priv) { - skb_queue_head_init(&priv->tx.tx_queue); + skb_queue_head_init(&priv->tx.mgmt_ep_queue); + skb_queue_head_init(&priv->tx.cab_ep_queue); + skb_queue_head_init(&priv->tx.data_be_queue); + skb_queue_head_init(&priv->tx.data_bk_queue); + skb_queue_head_init(&priv->tx.data_vi_queue); + skb_queue_head_init(&priv->tx.data_vo_queue); skb_queue_head_init(&priv->tx.tx_failed); return 0; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index e66f6c333028..3f5a4d1fe077 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -163,6 +163,16 @@ void ath9k_wmi_event_tasklet(unsigned long data) wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); #endif break; + case WMI_TXSTATUS_EVENTID: + spin_lock_bh(&priv->tx.tx_lock); + if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { + spin_unlock_bh(&priv->tx.tx_lock); + break; + } + spin_unlock_bh(&priv->tx.tx_lock); + + ath9k_htc_txstatus(priv, wmi_event); + break; default: break; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 8c877dc2e2e0..44b17385374f 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -45,9 +45,9 @@ struct wmi_event_swba { /* * 64 - HTC header - WMI header - 1 / txstatus * And some other hdr. space is also accounted for. - * 13 seems to be the magic number. + * 12 seems to be the magic number. */ -#define HTC_MAX_TX_STATUS 13 +#define HTC_MAX_TX_STATUS 12 #define ATH9K_HTC_TXSTAT_ACK BIT(0) #define ATH9K_HTC_TXSTAT_FILT BIT(1) -- GitLab From 01f684de7cc0641a9ee968f2d2c45c3a67241252 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:26 +0530 Subject: [PATCH 0863/5560] ath9k_htc: Add a debugfs file to dump TX slot information Location: ath9k_htc/phy#/slot Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + .../net/wireless/ath/ath9k/htc_drv_debug.c | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 6c103edf890a..b9c7bec9dd45 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -338,6 +338,7 @@ struct ath9k_debug { struct dentry *debugfs_tgt_stats; struct dentry *debugfs_xmit; struct dentry *debugfs_recv; + struct dentry *debugfs_slot; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; u32 txrate; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 91a486cca32a..119cc544cea0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -244,6 +244,41 @@ static const struct file_operations fops_recv = { .llseek = default_llseek, }; +static ssize_t read_file_slot(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + spin_lock_bh(&priv->tx.tx_lock); + + len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); + + len += bitmap_scnprintf(buf + len, sizeof(buf) - len, + priv->tx.tx_slot, MAX_TX_BUF_NUM); + + len += snprintf(buf + len, sizeof(buf) - len, "\n"); + + len += snprintf(buf + len, sizeof(buf) - len, + "Used slots : %d\n", + bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); + + spin_unlock_bh(&priv->tx.tx_lock); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_slot = { + .read = read_file_slot, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath9k_htc_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -276,6 +311,12 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_recv) goto err; + priv->debug.debugfs_slot = debugfs_create_file("slot", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_slot); + if (!priv->debug.debugfs_slot) + goto err; + return 0; err: @@ -288,6 +329,7 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + debugfs_remove(priv->debug.debugfs_slot); debugfs_remove(priv->debug.debugfs_recv); debugfs_remove(priv->debug.debugfs_xmit); debugfs_remove(priv->debug.debugfs_tgt_stats); -- GitLab From c4d04186c7023d54445b695da226b3e98e0a55f9 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:31 +0530 Subject: [PATCH 0864/5560] ath9k_htc: Add a debugfs file showing endpoint status Location: ath9k_htc/phy#/queue Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + .../net/wireless/ath/ath9k/htc_drv_debug.c | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b9c7bec9dd45..b40753ca6706 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -339,6 +339,7 @@ struct ath9k_debug { struct dentry *debugfs_xmit; struct dentry *debugfs_recv; struct dentry *debugfs_slot; + struct dentry *debugfs_queue; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; u32 txrate; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 119cc544cea0..961bec20d140 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -279,6 +279,53 @@ static const struct file_operations fops_slot = { .llseek = default_llseek, }; +static ssize_t read_file_queue(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); + + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Failed queue", skb_queue_len(&priv->tx.tx_failed)); + + spin_lock_bh(&priv->tx.tx_lock); + len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + "Queued count", priv->tx.queued_cnt); + spin_unlock_bh(&priv->tx.tx_lock); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); + +} + +static const struct file_operations fops_queue = { + .read = read_file_queue, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int ath9k_htc_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -317,6 +364,12 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_slot) goto err; + priv->debug.debugfs_queue = debugfs_create_file("queue", S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_queue); + if (!priv->debug.debugfs_queue) + goto err; + return 0; err: @@ -329,6 +382,7 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + debugfs_remove(priv->debug.debugfs_queue); debugfs_remove(priv->debug.debugfs_slot); debugfs_remove(priv->debug.debugfs_recv); debugfs_remove(priv->debug.debugfs_xmit); -- GitLab From 859c3ca1e4608615788dc6cbc199210fe4b5efa2 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:39 +0530 Subject: [PATCH 0865/5560] ath9k_htc: Add a timer to cleanup WMI events Occasionally, a WMI event would arrive ahead of the TX URB completion handler. Discarding these events would exhaust the available TX slots, so handle them by running a timer cleaning up such events. Also, timeout packets for which TX completion events have not arrived. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 8 +- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 12 ++ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 127 +++++++++++++++++- drivers/net/wireless/ath/ath9k/wmi.c | 3 + drivers/net/wireless/ath/ath9k/wmi.h | 9 ++ 6 files changed, 159 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b40753ca6706..b413b46119b0 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -262,7 +262,10 @@ struct ath9k_htc_rx { spinlock_t rxbuflock; }; -#define ATH9K_HTC_TX_RESERVE 10 +#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ +#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ +#define ATH9K_HTC_TX_RESERVE 10 +#define ATH9K_HTC_TX_TIMEOUT_COUNT 20 #define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) #define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) @@ -279,6 +282,7 @@ struct ath9k_htc_tx { struct sk_buff_head data_vo_queue; struct sk_buff_head tx_failed; DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); + struct timer_list cleanup_timer; spinlock_t tx_lock; }; @@ -287,6 +291,7 @@ struct ath9k_htc_tx_ctl { u8 epid; u8 txok; u8 sta_idx; + unsigned long timestamp; }; static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb) @@ -557,6 +562,7 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv); void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event); void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv); void ath9k_tx_failed_tasklet(unsigned long data); +void ath9k_htc_tx_cleanup_timer(unsigned long data); int ath9k_rx_init(struct ath9k_htc_priv *priv); void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index afceeaa6b916..0aec25920c0a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -671,7 +671,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, common->priv = priv; common->debug_mask = ath9k_debug; - spin_lock_init(&priv->wmi->wmi_lock); spin_lock_init(&priv->beacon_lock); spin_lock_init(&priv->tx.tx_lock); mutex_init(&priv->mutex); @@ -683,6 +682,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); INIT_WORK(&priv->fatal_work, ath9k_fatal_work); + setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer, + (unsigned long)priv); /* * 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 ae85cc4373f0..4de38643cb53 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -194,6 +194,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ath9k_htc_stop_ani(priv); ieee80211_stop_queues(priv->hw); + del_timer_sync(&priv->tx.cleanup_timer); ath9k_htc_tx_drain(priv); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -225,6 +226,9 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) ath9k_htc_vif_reconfig(priv); ieee80211_wake_queues(priv->hw); + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -251,6 +255,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, ath9k_htc_ps_wakeup(priv); + del_timer_sync(&priv->tx.cleanup_timer); ath9k_htc_tx_drain(priv); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -301,6 +306,9 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) ath9k_htc_vif_reconfig(priv); + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + err: ath9k_htc_ps_restore(priv); return ret; @@ -937,6 +945,9 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, AR_STOMP_LOW_WLAN_WGHT); @@ -972,6 +983,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) tasklet_kill(&priv->rx_tasklet); + del_timer_sync(&priv->tx.cleanup_timer); ath9k_htc_tx_drain(priv); ath9k_wmi_event_drain(priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index a9b6bb1ef287..86f5ce9b6e0e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -495,6 +495,8 @@ static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv, void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) { + struct ath9k_htc_tx_event *event, *tmp; + spin_lock_bh(&priv->tx.tx_lock); priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN; spin_unlock_bh(&priv->tx.tx_lock); @@ -515,6 +517,16 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv) ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue); ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); + /* + * The TX cleanup timer has already been killed. + */ + spin_lock_bh(&priv->wmi->event_lock); + list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { + list_del(&event->list); + kfree(event); + } + spin_unlock_bh(&priv->wmi->event_lock); + spin_lock_bh(&priv->tx.tx_lock); priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN; spin_unlock_bh(&priv->tx.tx_lock); @@ -595,6 +607,7 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event; struct __wmi_event_txstatus *__txs; struct sk_buff *skb; + struct ath9k_htc_tx_event *tx_pend; int i; for (i = 0; i < txs->cnt; i++) { @@ -603,8 +616,26 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) __txs = &txs->txstatus[i]; skb = ath9k_htc_tx_get_packet(priv, __txs); - if (!skb) + if (!skb) { + /* + * Store this event, so that the TX cleanup + * routine can check later for the needed packet. + */ + tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event), + GFP_ATOMIC); + if (!tx_pend) + continue; + + memcpy(&tx_pend->txs, __txs, + sizeof(struct __wmi_event_txstatus)); + + spin_lock(&priv->wmi->event_lock); + list_add_tail(&tx_pend->list, + &priv->wmi->pending_tx_events); + spin_unlock(&priv->wmi->event_lock); + continue; + } ath9k_htc_tx_process(priv, skb, __txs); } @@ -622,6 +653,7 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, tx_ctl = HTC_SKB_CB(skb); tx_ctl->txok = txok; + tx_ctl->timestamp = jiffies; if (!txok) { skb_queue_tail(&priv->tx.tx_failed, skb); @@ -638,6 +670,99 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, skb_queue_tail(epid_queue, skb); } +static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_tx_ctl *tx_ctl; + + tx_ctl = HTC_SKB_CB(skb); + + if (time_after(jiffies, + tx_ctl->timestamp + + msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { + ath_dbg(common, ATH_DBG_XMIT, + "Dropping a packet due to TX timeout\n"); + return true; + } + + return false; +} + +static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv, + struct sk_buff_head *epid_queue) +{ + bool process = false; + unsigned long flags; + struct sk_buff *skb, *tmp; + struct sk_buff_head queue; + + skb_queue_head_init(&queue); + + spin_lock_irqsave(&epid_queue->lock, flags); + skb_queue_walk_safe(epid_queue, skb, tmp) { + if (check_packet(priv, skb)) { + __skb_unlink(skb, epid_queue); + __skb_queue_tail(&queue, skb); + process = true; + } + } + spin_unlock_irqrestore(&epid_queue->lock, flags); + + if (process) { + skb_queue_walk_safe(&queue, skb, tmp) { + __skb_unlink(skb, &queue); + ath9k_htc_tx_process(priv, skb, NULL); + } + } +} + +void ath9k_htc_tx_cleanup_timer(unsigned long data) +{ + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data; + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_tx_event *event, *tmp; + struct sk_buff *skb; + + spin_lock(&priv->wmi->event_lock); + list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) { + + skb = ath9k_htc_tx_get_packet(priv, &event->txs); + if (skb) { + ath_dbg(common, ATH_DBG_XMIT, + "Found packet for cookie: %d, epid: %d\n", + event->txs.cookie, + MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); + + ath9k_htc_tx_process(priv, skb, &event->txs); + list_del(&event->list); + kfree(event); + continue; + } + + if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) { + list_del(&event->list); + kfree(event); + } + } + spin_unlock(&priv->wmi->event_lock); + + /* + * Check if status-pending packets have to be cleaned up. + */ + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue); + ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue); + + /* Wake TX queues if needed */ + ath9k_htc_check_wake_queues(priv); + + mod_timer(&priv->tx.cleanup_timer, + jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); +} + int ath9k_tx_init(struct ath9k_htc_priv *priv) { skb_queue_head_init(&priv->tx.mgmt_ep_queue); diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 3f5a4d1fe077..697e5af842c1 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -91,9 +91,12 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) wmi->drv_priv = priv; wmi->stopped = false; skb_queue_head_init(&wmi->wmi_event_queue); + spin_lock_init(&wmi->wmi_lock); + spin_lock_init(&wmi->event_lock); mutex_init(&wmi->op_mutex); mutex_init(&wmi->multi_write_mutex); init_completion(&wmi->cmd_wait); + INIT_LIST_HEAD(&wmi->pending_tx_events); tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, (unsigned long)wmi); diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 44b17385374f..310d94eaed19 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -130,6 +130,12 @@ struct register_write { __be32 val; }; +struct ath9k_htc_tx_event { + int count; + struct __wmi_event_txstatus txs; + struct list_head list; +}; + struct wmi { struct ath9k_htc_priv *drv_priv; struct htc_target *htc; @@ -144,6 +150,9 @@ struct wmi { u32 cmd_rsp_len; bool stopped; + struct list_head pending_tx_events; + spinlock_t event_lock; + spinlock_t wmi_lock; atomic_t mwrite_cnt; -- GitLab From 2f80194c90caea3668d0e3739518bf100449a813 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:46 +0530 Subject: [PATCH 0866/5560] ath9k_htc: Use separate URB pool for management frames Beacon transmission needs to involve as little latency as possible after receiving a SWBA event from the target. Since packets are buffered to use TX stream mode, beacon frames sometimes gets queued up and are not sent out immediately. Fix this by decoupling management frame transmission from the normal data path and send them out immediately. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 116 +++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/hif_usb.h | 1 + 2 files changed, 108 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 7fae79d16665..3b0efab65131 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -78,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb) if (cmd) { ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, - cmd->skb, 1); + cmd->skb, true); kfree(cmd); } @@ -124,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, return ret; } +static void hif_usb_mgmt_cb(struct urb *urb) +{ + struct cmd_buf *cmd = (struct cmd_buf *)urb->context; + struct hif_device_usb *hif_dev = cmd->hif_dev; + bool txok = true; + + if (!cmd || !cmd->skb || !cmd->hif_dev) + return; + + switch (urb->status) { + case 0: + break; + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + txok = false; + + /* + * If the URBs are being flushed, no need to complete + * this packet. + */ + spin_lock(&hif_dev->tx.tx_lock); + if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { + spin_unlock(&hif_dev->tx.tx_lock); + dev_kfree_skb_any(cmd->skb); + kfree(cmd); + return; + } + spin_unlock(&hif_dev->tx.tx_lock); + + break; + default: + txok = false; + break; + } + + skb_pull(cmd->skb, 4); + ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, + cmd->skb, txok); + kfree(cmd); +} + +static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, + struct sk_buff *skb) +{ + struct urb *urb; + struct cmd_buf *cmd; + int ret = 0; + __le16 *hdr; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (urb == NULL) + return -ENOMEM; + + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + if (cmd == NULL) { + usb_free_urb(urb); + return -ENOMEM; + } + + cmd->skb = skb; + cmd->hif_dev = hif_dev; + + hdr = (__le16 *) skb_push(skb, 4); + *hdr++ = cpu_to_le16(skb->len - 4); + *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); + + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), + skb->data, skb->len, + hif_usb_mgmt_cb, cmd); + + usb_anchor_urb(urb, &hif_dev->mgmt_submitted); + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) { + usb_unanchor_urb(urb); + kfree(cmd); + } + usb_free_urb(urb); + + return ret; +} + static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, struct sk_buff_head *list) { @@ -275,6 +359,7 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) { struct ath9k_htc_tx_ctl *tx_ctl; unsigned long flags; + int ret = 0; spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); @@ -289,25 +374,33 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) return -ENOMEM; } - __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); - hif_dev->tx.tx_skb_cnt++; + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); tx_ctl = HTC_SKB_CB(skb); - /* Send normal/mgmt/beacon frames immediately */ - if (tx_ctl->type != ATH9K_HTC_AMPDU) - __hif_usb_tx(hif_dev); + /* Mgmt/Beacon frames don't use the TX buffer pool */ + if ((tx_ctl->type == ATH9K_HTC_MGMT) || + (tx_ctl->type == ATH9K_HTC_BEACON)) { + ret = hif_usb_send_mgmt(hif_dev, skb); + } + + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); + + if ((tx_ctl->type == ATH9K_HTC_NORMAL) || + (tx_ctl->type == ATH9K_HTC_AMPDU)) { + __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); + hif_dev->tx.tx_skb_cnt++; + } /* Check if AMPDUs have to be sent immediately */ - if ((tx_ctl->type == ATH9K_HTC_AMPDU) && - (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && + if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && (hif_dev->tx.tx_skb_cnt < 2)) { __hif_usb_tx(hif_dev); } spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); - return 0; + return ret; } static void hif_usb_start(void *hif_handle) @@ -339,6 +432,8 @@ static void hif_usb_stop(void *hif_handle) &hif_dev->tx.tx_pending, list) { usb_kill_urb(tx_buf->urb); } + + usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); } static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) @@ -657,6 +752,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) kfree(tx_buf->buf); kfree(tx_buf); } + + usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); } static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) @@ -668,6 +765,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) INIT_LIST_HEAD(&hif_dev->tx.tx_pending); spin_lock_init(&hif_dev->tx.tx_lock); __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); + init_usb_anchor(&hif_dev->mgmt_submitted); for (i = 0; i < MAX_TX_URB_NUM; i++) { tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 8b98d646e91a..f59df48a86e2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -93,6 +93,7 @@ struct hif_device_usb { struct usb_anchor regout_submitted; struct usb_anchor rx_submitted; struct usb_anchor reg_in_submitted; + struct usb_anchor mgmt_submitted; struct sk_buff *remain_skb; const char *fw_name; int rx_remain_len; -- GitLab From 821f9414c0546fbc99a999e9dc613d1756e1de8a Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:52 +0530 Subject: [PATCH 0867/5560] ath9k_htc: Use helper routines for transmission Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 227 ++++++++++-------- 1 file changed, 127 insertions(+), 100 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 86f5ce9b6e0e..723a3a9c5cd9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -211,28 +211,140 @@ int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, return error; } +static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv, + struct ath9k_htc_vif *avp, + struct sk_buff *skb, + u8 sta_idx, u8 vif_idx, u8 slot) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_mgmt *mgmt; + struct ieee80211_hdr *hdr; + struct tx_mgmt_hdr mgmt_hdr; + struct ath9k_htc_tx_ctl *tx_ctl; + u8 *tx_fhdr; + + tx_ctl = HTC_SKB_CB(skb); + hdr = (struct ieee80211_hdr *) skb->data; + + memset(tx_ctl, 0, sizeof(*tx_ctl)); + memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); + + /* + * Set the TSF adjust value for probe response + * frame also. + */ + if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) { + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.probe_resp.timestamp = avp->tsfadjust; + } + + tx_ctl->type = ATH9K_HTC_MGMT; + + mgmt_hdr.node_idx = sta_idx; + mgmt_hdr.vif_idx = vif_idx; + mgmt_hdr.tidno = 0; + mgmt_hdr.flags = 0; + mgmt_hdr.cookie = slot; + + mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); + if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) + mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; + else + mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; + + tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); + memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); + tx_ctl->epid = priv->mgmt_ep; +} + +static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct sk_buff *skb, + u8 sta_idx, u8 vif_idx, u8 slot, + bool is_cab) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr; + struct ath9k_htc_tx_ctl *tx_ctl; + struct tx_frame_hdr tx_hdr; + u32 flags = 0; + u8 *qc, *tx_fhdr; + u16 qnum; + + tx_ctl = HTC_SKB_CB(skb); + hdr = (struct ieee80211_hdr *) skb->data; + + memset(tx_ctl, 0, sizeof(*tx_ctl)); + memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); + + tx_hdr.node_idx = sta_idx; + tx_hdr.vif_idx = vif_idx; + tx_hdr.cookie = slot; + + /* + * This is a bit redundant but it helps to get + * the per-packet index quickly when draining the + * TX queue in the HIF layer. Otherwise we would + * have to parse the packet contents ... + */ + tx_ctl->sta_idx = sta_idx; + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + tx_ctl->type = ATH9K_HTC_AMPDU; + tx_hdr.data_type = ATH9K_HTC_AMPDU; + } else { + tx_ctl->type = ATH9K_HTC_NORMAL; + tx_hdr.data_type = ATH9K_HTC_NORMAL; + } + + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl(hdr); + tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + } + + /* Check for RTS protection */ + if (priv->hw->wiphy->rts_threshold != (u32) -1) + if (skb->len > priv->hw->wiphy->rts_threshold) + flags |= ATH9K_HTC_TX_RTSCTS; + + /* CTS-to-self */ + if (!(flags & ATH9K_HTC_TX_RTSCTS) && + (vif && vif->bss_conf.use_cts_prot)) + flags |= ATH9K_HTC_TX_CTSONLY; + + tx_hdr.flags = cpu_to_be32(flags); + tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); + if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) + tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; + else + tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; + + tx_fhdr = skb_push(skb, sizeof(tx_hdr)); + memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); + + if (is_cab) { + CAB_STAT_INC; + tx_ctl->epid = priv->cab_ep; + return; + } + + qnum = skb_get_queue_mapping(skb); + tx_ctl->epid = get_htc_epid(priv, qnum); +} + int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb, u8 slot, bool is_cab) { struct ieee80211_hdr *hdr; - struct ieee80211_mgmt *mgmt; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; - struct ath9k_htc_tx_ctl *tx_ctl; - u16 qnum; - __le16 fc; - u8 *tx_fhdr; u8 sta_idx, vif_idx; - tx_ctl = HTC_SKB_CB(skb); - memset(tx_ctl, 0, sizeof(*tx_ctl)); - hdr = (struct ieee80211_hdr *) skb->data; - fc = hdr->frame_control; /* * Find out on which interface this packet has to be @@ -261,99 +373,14 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, sta_idx = priv->vif_sta_pos[vif_idx]; } - if (ieee80211_is_data(fc)) { - struct tx_frame_hdr tx_hdr; - u32 flags = 0; - u8 *qc; - - memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); - - tx_hdr.node_idx = sta_idx; - tx_hdr.vif_idx = vif_idx; - tx_hdr.cookie = slot; - - /* - * This is a bit redundant but it helps to get - * the per-packet index quickly when draining the - * TX queue in the HIF layer. Otherwise we would - * have to parse the packet contents ... - */ - tx_ctl->sta_idx = sta_idx; - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - tx_ctl->type = ATH9K_HTC_AMPDU; - tx_hdr.data_type = ATH9K_HTC_AMPDU; - } else { - tx_ctl->type = ATH9K_HTC_NORMAL; - tx_hdr.data_type = ATH9K_HTC_NORMAL; - } - - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); - tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - } - - /* Check for RTS protection */ - if (priv->hw->wiphy->rts_threshold != (u32) -1) - if (skb->len > priv->hw->wiphy->rts_threshold) - flags |= ATH9K_HTC_TX_RTSCTS; - - /* CTS-to-self */ - if (!(flags & ATH9K_HTC_TX_RTSCTS) && - (vif && vif->bss_conf.use_cts_prot)) - flags |= ATH9K_HTC_TX_CTSONLY; - - tx_hdr.flags = cpu_to_be32(flags); - tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); - if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) - tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; - else - tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; - - tx_fhdr = skb_push(skb, sizeof(tx_hdr)); - memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); - - if (is_cab) { - CAB_STAT_INC; - tx_ctl->epid = priv->cab_ep; - goto send; - } - - qnum = skb_get_queue_mapping(skb); - tx_ctl->epid = get_htc_epid(priv, qnum); - } else { - struct tx_mgmt_hdr mgmt_hdr; - - memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); - - /* - * Set the TSF adjust value for probe response - * frame also. - */ - if (avp && unlikely(ieee80211_is_probe_resp(fc))) { - mgmt = (struct ieee80211_mgmt *)skb->data; - mgmt->u.probe_resp.timestamp = avp->tsfadjust; - } - - tx_ctl->type = ATH9K_HTC_MGMT; - - mgmt_hdr.node_idx = sta_idx; - mgmt_hdr.vif_idx = vif_idx; - mgmt_hdr.tidno = 0; - mgmt_hdr.flags = 0; - mgmt_hdr.cookie = slot; + if (ieee80211_is_data(hdr->frame_control)) + ath9k_htc_tx_data(priv, vif, skb, + sta_idx, vif_idx, slot, is_cab); + else + ath9k_htc_tx_mgmt(priv, avp, skb, + sta_idx, vif_idx, slot); - mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); - if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) - mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; - else - mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; - tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); - memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); - tx_ctl->epid = priv->mgmt_ep; - } -send: return htc_send(priv->htc, skb); } -- GitLab From fbc29d6c3da58bc51416f65a50bdb419d4ea85b8 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:26:58 +0530 Subject: [PATCH 0868/5560] ath9k_htc: Add detailed firmware statistics New debugfs files: /ath9k_htc//tgt_int_stats /ath9k_htc//tgt_tx_stats /ath9k_htc//tgt_rx_stats Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 36 +++- .../net/wireless/ath/ath9k/htc_drv_debug.c | 185 +++++++++++++++--- drivers/net/wireless/ath/ath9k/wmi.c | 19 +- drivers/net/wireless/ath/ath9k/wmi.h | 7 +- 4 files changed, 195 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b413b46119b0..cc5d0a4b9da2 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -175,12 +175,31 @@ struct ath9k_htc_target_rate { struct ath9k_htc_rate rates; }; -struct ath9k_htc_target_stats { - __be32 tx_shortretry; - __be32 tx_longretry; - __be32 tx_xretries; - __be32 ht_txunaggr_xretry; - __be32 ht_tx_xretries; +struct ath9k_htc_target_int_stats { + __be32 rx; + __be32 rxorn; + __be32 rxeol; + __be32 txurn; + __be32 txto; + __be32 cst; +} __packed; + +struct ath9k_htc_target_tx_stats { + __be32 xretries; + __be32 fifoerr; + __be32 filtered; + __be32 timer_exp; + __be32 shortretries; + __be32 longretries; + __be32 qnull; + __be32 encap_fail; + __be32 nobuf; +} __packed; + +struct ath9k_htc_target_rx_stats { + __be32 nobuf; + __be32 host_send; + __be32 host_done; } __packed; #define ATH9K_HTC_MAX_VIF 2 @@ -340,14 +359,15 @@ struct ath_rx_stats { struct ath9k_debug { struct dentry *debugfs_phy; - struct dentry *debugfs_tgt_stats; + struct dentry *debugfs_tgt_int_stats; + struct dentry *debugfs_tgt_tx_stats; + struct dentry *debugfs_tgt_rx_stats; struct dentry *debugfs_xmit; struct dentry *debugfs_recv; struct dentry *debugfs_slot; struct dentry *debugfs_queue; struct ath_tx_stats tx_stats; struct ath_rx_stats rx_stats; - u32 txrate; }; #else diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 961bec20d140..8d0de60e0c27 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -24,39 +24,108 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) return 0; } -static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) { struct ath9k_htc_priv *priv = file->private_data; - struct ath9k_htc_target_stats cmd_rsp; + struct ath9k_htc_target_int_stats cmd_rsp; char buf[512]; unsigned int len = 0; int ret = 0; memset(&cmd_rsp, 0, sizeof(cmd_rsp)); - WMI_CMD(WMI_TGT_STATS_CMDID); + WMI_CMD(WMI_INT_STATS_CMDID); if (ret) return -EINVAL; + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RX", + be32_to_cpu(cmd_rsp.rx)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RXORN", + be32_to_cpu(cmd_rsp.rxorn)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RXEOL", + be32_to_cpu(cmd_rsp.rxeol)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TXURN", + be32_to_cpu(cmd_rsp.txurn)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TXTO", + be32_to_cpu(cmd_rsp.txto)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CST", + be32_to_cpu(cmd_rsp.cst)); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_tgt_int_stats = { + .read = read_file_tgt_int_stats, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_target_tx_stats cmd_rsp; + char buf[512]; + unsigned int len = 0; + int ret = 0; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_TX_STATS_CMDID); + if (ret) + return -EINVAL; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Xretries", + be32_to_cpu(cmd_rsp.xretries)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "FifoErr", + be32_to_cpu(cmd_rsp.fifoerr)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Filtered", + be32_to_cpu(cmd_rsp.filtered)); len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Short Retries", - be32_to_cpu(cmd_rsp.tx_shortretry)); + "%20s : %10u\n", "TimerExp", + be32_to_cpu(cmd_rsp.timer_exp)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Long Retries", - be32_to_cpu(cmd_rsp.tx_longretry)); + "%20s : %10u\n", "ShortRetries", + be32_to_cpu(cmd_rsp.shortretries)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries", - be32_to_cpu(cmd_rsp.tx_xretries)); + "%20s : %10u\n", "LongRetries", + be32_to_cpu(cmd_rsp.longretries)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Unaggr. Xretries", - be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); + "%20s : %10u\n", "QueueNull", + be32_to_cpu(cmd_rsp.qnull)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Xretries (HT)", - be32_to_cpu(cmd_rsp.ht_tx_xretries)); + "%20s : %10u\n", "EncapFail", + be32_to_cpu(cmd_rsp.encap_fail)); + len += snprintf(buf + len, sizeof(buf) - len, - "%19s : %10u\n", "TX Rate", priv->debug.txrate); + "%20s : %10u\n", "NoBuf", + be32_to_cpu(cmd_rsp.nobuf)); if (len > sizeof(buf)) len = sizeof(buf); @@ -64,8 +133,48 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, len); } -static const struct file_operations fops_tgt_stats = { - .read = read_file_tgt_stats, +static const struct file_operations fops_tgt_tx_stats = { + .read = read_file_tgt_tx_stats, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath9k_htc_priv *priv = file->private_data; + struct ath9k_htc_target_rx_stats cmd_rsp; + char buf[512]; + unsigned int len = 0; + int ret = 0; + + memset(&cmd_rsp, 0, sizeof(cmd_rsp)); + + WMI_CMD(WMI_RX_STATS_CMDID); + if (ret) + return -EINVAL; + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "NoBuf", + be32_to_cpu(cmd_rsp.nobuf)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "HostSend", + be32_to_cpu(cmd_rsp.host_send)); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "HostDone", + be32_to_cpu(cmd_rsp.host_done)); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_tgt_rx_stats = { + .read = read_file_tgt_rx_stats, .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -286,29 +395,29 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, char buf[512]; unsigned int len = 0; - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Failed queue", skb_queue_len(&priv->tx.tx_failed)); spin_lock_bh(&priv->tx.tx_lock); - len += snprintf(buf + len, sizeof(buf) - len, "%16s : %3d\n", + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "Queued count", priv->tx.queued_cnt); spin_unlock_bh(&priv->tx.tx_lock); @@ -339,12 +448,26 @@ int ath9k_htc_init_debug(struct ath_hw *ah) if (!priv->debug.debugfs_phy) goto err; - priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, - priv->debug.debugfs_phy, - priv, &fops_tgt_stats); - if (!priv->debug.debugfs_tgt_stats) + priv->debug.debugfs_tgt_int_stats = debugfs_create_file("tgt_int_stats", + S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_int_stats); + if (!priv->debug.debugfs_tgt_int_stats) goto err; + priv->debug.debugfs_tgt_tx_stats = debugfs_create_file("tgt_tx_stats", + S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_tx_stats); + if (!priv->debug.debugfs_tgt_tx_stats) + goto err; + + priv->debug.debugfs_tgt_rx_stats = debugfs_create_file("tgt_rx_stats", + S_IRUSR, + priv->debug.debugfs_phy, + priv, &fops_tgt_rx_stats); + if (!priv->debug.debugfs_tgt_rx_stats) + goto err; priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, @@ -386,7 +509,9 @@ void ath9k_htc_exit_debug(struct ath_hw *ah) debugfs_remove(priv->debug.debugfs_slot); debugfs_remove(priv->debug.debugfs_recv); debugfs_remove(priv->debug.debugfs_xmit); - debugfs_remove(priv->debug.debugfs_tgt_stats); + debugfs_remove(priv->debug.debugfs_tgt_int_stats); + debugfs_remove(priv->debug.debugfs_tgt_tx_stats); + debugfs_remove(priv->debug.debugfs_tgt_rx_stats); debugfs_remove(priv->debug.debugfs_phy); } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 697e5af842c1..8f095ad0a3db 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -67,12 +67,18 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_RC_RATE_UPDATE_CMDID"; case WMI_TARGET_IC_UPDATE_CMDID: return "WMI_TARGET_IC_UPDATE_CMDID"; - case WMI_TGT_STATS_CMDID: - return "WMI_TGT_STATS_CMDID"; case WMI_TX_AGGR_ENABLE_CMDID: return "WMI_TX_AGGR_ENABLE_CMDID"; case WMI_TGT_DETACH_CMDID: return "WMI_TGT_DETACH_CMDID"; + case WMI_NODE_UPDATE_CMDID: + return "WMI_NODE_UPDATE_CMDID"; + case WMI_INT_STATS_CMDID: + return "WMI_INT_STATS_CMDID"; + case WMI_TX_STATS_CMDID: + return "WMI_TX_STATS_CMDID"; + case WMI_RX_STATS_CMDID: + return "WMI_RX_STATS_CMDID"; case WMI_AGGR_LIMIT_CMD: return "WMI_AGGR_LIMIT_CMD"; } @@ -134,9 +140,6 @@ void ath9k_wmi_event_tasklet(unsigned long data) struct sk_buff *skb = NULL; unsigned long flags; u16 cmd_id; -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - __be32 txrate; -#endif do { spin_lock_irqsave(&wmi->wmi_lock, flags); @@ -160,12 +163,6 @@ void ath9k_wmi_event_tasklet(unsigned long data) ieee80211_queue_work(wmi->drv_priv->hw, &wmi->drv_priv->fatal_work); break; - case WMI_TXRATE_EVENTID: -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; - wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); -#endif - break; case WMI_TXSTATUS_EVENTID: spin_lock_bh(&priv->tx.tx_lock); if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 310d94eaed19..02ecb9f06db0 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -17,7 +17,6 @@ #ifndef WMI_H #define WMI_H - struct wmi_event_txrate { __be32 txrate; struct { @@ -106,9 +105,12 @@ enum wmi_cmd_id { WMI_RC_STATE_CHANGE_CMDID, WMI_RC_RATE_UPDATE_CMDID, WMI_TARGET_IC_UPDATE_CMDID, - WMI_TGT_STATS_CMDID, WMI_TX_AGGR_ENABLE_CMDID, WMI_TGT_DETACH_CMDID, + WMI_NODE_UPDATE_CMDID, + WMI_INT_STATS_CMDID, + WMI_TX_STATS_CMDID, + WMI_RX_STATS_CMDID, WMI_AGGR_LIMIT_CMD = 0x0026, }; @@ -119,7 +121,6 @@ enum wmi_event_id { WMI_TXTO_EVENTID, WMI_BMISS_EVENTID, WMI_DELBA_EVENTID, - WMI_TXRATE_EVENTID, WMI_TXSTATUS_EVENTID, }; -- GitLab From 09d5b94d2cbc6c3ebb70a9a318f6390d0b4cf010 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 13 Apr 2011 11:27:06 +0530 Subject: [PATCH 0869/5560] ath9k_htc: Enable AP and P2P modes Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 0aec25920c0a..22736eb901cf 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -752,7 +752,10 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT); hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; -- GitLab From a3e6b12c0232748658a602eda39f12fddb254ba8 Mon Sep 17 00:00:00 2001 From: cozybit Inc Date: Wed, 13 Apr 2011 11:10:28 -0700 Subject: [PATCH 0870/5560] mac80211: Allocate new mesh path and portal tables before taking locks It is unnecessary to hold the path table resize lock while allocating a new table. Allocate first and take lock later. This resolves a soft-lockup: [ 293.385799] BUG: soft lockup - CPU#0 stuck for 61s! [kworker/u:3:744] (...) [ 293.386049] Call Trace: [ 293.386049] [] do_raw_read_lock+0x26/0x29 [ 293.386049] [] _raw_read_lock+0x8/0xa [ 293.386049] [] mesh_path_add+0xb7/0x24e [ 293.386049] [] ? mesh_path_lookup+0x1b/0xa6 [ 293.386049] [] hwmp_route_info_get+0x276/0x2fd [ 293.386049] [] mesh_rx_path_sel_frame+0x5a/0x5d9 [ 293.386049] [] ? update_curr+0x1cf/0x1d7 [ 293.386049] [] ieee80211_mesh_rx_queued_mgmt+0x60/0x67 [ 293.386049] [] ieee80211_iface_work+0x1f0/0x258 (...) Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 49 +++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 8d65b47d9837..7776ae5a8f15 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -65,42 +65,37 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) __mesh_table_free(tbl); } -static struct mesh_table *mesh_table_grow(struct mesh_table *tbl) +static int mesh_table_grow(struct mesh_table *oldtbl, + struct mesh_table *newtbl) { - struct mesh_table *newtbl; struct hlist_head *oldhash; struct hlist_node *p, *q; int i; - if (atomic_read(&tbl->entries) - < tbl->mean_chain_len * (tbl->hash_mask + 1)) - goto endgrow; + if (atomic_read(&oldtbl->entries) + < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) + return -EAGAIN; - newtbl = mesh_table_alloc(tbl->size_order + 1); - if (!newtbl) - goto endgrow; - newtbl->free_node = tbl->free_node; - newtbl->mean_chain_len = tbl->mean_chain_len; - newtbl->copy_node = tbl->copy_node; - atomic_set(&newtbl->entries, atomic_read(&tbl->entries)); + newtbl->free_node = oldtbl->free_node; + newtbl->mean_chain_len = oldtbl->mean_chain_len; + newtbl->copy_node = oldtbl->copy_node; + atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries)); - oldhash = tbl->hash_buckets; - for (i = 0; i <= tbl->hash_mask; i++) + oldhash = oldtbl->hash_buckets; + for (i = 0; i <= oldtbl->hash_mask; i++) hlist_for_each(p, &oldhash[i]) - if (tbl->copy_node(p, newtbl) < 0) + if (oldtbl->copy_node(p, newtbl) < 0) goto errcopy; - return newtbl; + return 0; errcopy: for (i = 0; i <= newtbl->hash_mask; i++) { hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) - tbl->free_node(p, 0); + oldtbl->free_node(p, 0); } - __mesh_table_free(newtbl); -endgrow: - return NULL; + return -ENOMEM; } @@ -334,10 +329,13 @@ void mesh_mpath_table_grow(void) { struct mesh_table *oldtbl, *newtbl; + newtbl = mesh_table_alloc(mesh_paths->size_order + 1); + if (!newtbl) + return; write_lock(&pathtbl_resize_lock); oldtbl = mesh_paths; - newtbl = mesh_table_grow(mesh_paths); - if (!newtbl) { + if (mesh_table_grow(mesh_paths, newtbl) < 0) { + __mesh_table_free(newtbl); write_unlock(&pathtbl_resize_lock); return; } @@ -352,10 +350,13 @@ void mesh_mpp_table_grow(void) { struct mesh_table *oldtbl, *newtbl; + newtbl = mesh_table_alloc(mpp_paths->size_order + 1); + if (!newtbl) + return; write_lock(&pathtbl_resize_lock); oldtbl = mpp_paths; - newtbl = mesh_table_grow(mpp_paths); - if (!newtbl) { + if (mesh_table_grow(mpp_paths, newtbl) < 0) { + __mesh_table_free(newtbl); write_unlock(&pathtbl_resize_lock); return; } -- GitLab From 4d42d417be75d750b82798922b6e775915e11bce Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 13 Apr 2011 14:48:55 -0700 Subject: [PATCH 0871/5560] rndis_host: Poll status before control channel where necessary Some RNDIS devices don't respond on the control channel until polled on the status channel. In particular, this was reported to be the case for the 2Wire HomePortal 1000SW and for some Windows Mobile devices. This is roughly based on a patch by John Carr which is currently applied by Mandriva. Reported-by: Mark Glassberg Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/usb/rndis_host.c | 39 ++++++++++++++++++++++++++++------ include/linux/usb/rndis_host.h | 2 ++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 5994a25c56ac..6d6c1da68a36 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -104,8 +104,10 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg, int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) { struct cdc_state *info = (void *) &dev->data; + struct usb_cdc_notification notification; int master_ifnum; int retval; + int partial; unsigned count; __le32 rsp; u32 xid = 0, msg_len, request_id; @@ -133,13 +135,20 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) if (unlikely(retval < 0 || xid == 0)) return retval; - // FIXME Seems like some devices discard responses when - // we time out and cancel our "get response" requests... - // so, this is fragile. Probably need to poll for status. + /* Some devices don't respond on the control channel until + * polled on the status channel, so do that first. */ + if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) { + retval = usb_interrupt_msg( + dev->udev, + usb_rcvintpipe(dev->udev, + dev->status->desc.bEndpointAddress), + ¬ification, sizeof(notification), &partial, + RNDIS_CONTROL_TIMEOUT_MS); + if (unlikely(retval < 0)) + return retval; + } - /* ignore status endpoint, just poll the control channel; - * the request probably completed immediately - */ + /* Poll the control channel; the request probably completed immediately */ rsp = buf->msg_type | RNDIS_MSG_COMPLETION; for (count = 0; count < 10; count++) { memset(buf, 0, CONTROL_BUFFER_SIZE); @@ -581,17 +590,33 @@ static const struct driver_info rndis_info = { .tx_fixup = rndis_tx_fixup, }; +static const struct driver_info rndis_poll_status_info = { + .description = "RNDIS device (poll status before control)", + .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, + .data = RNDIS_DRIVER_DATA_POLL_STATUS, + .bind = rndis_bind, + .unbind = rndis_unbind, + .status = rndis_status, + .rx_fixup = rndis_rx_fixup, + .tx_fixup = rndis_tx_fixup, +}; + /*-------------------------------------------------------------------------*/ static const struct usb_device_id products [] = { { + /* 2Wire HomePortal 1000SW */ + USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042, + USB_CLASS_COMM, 2 /* ACM */, 0x0ff), + .driver_info = (unsigned long) &rndis_poll_status_info, +}, { /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), .driver_info = (unsigned long) &rndis_info, }, { /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), - .driver_info = (unsigned long) &rndis_info, + .driver_info = (unsigned long) &rndis_poll_status_info, }, { /* RNDIS for tethering */ USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h index 05ef52861988..88fceb718c77 100644 --- a/include/linux/usb/rndis_host.h +++ b/include/linux/usb/rndis_host.h @@ -256,6 +256,8 @@ struct rndis_keepalive_c { /* IN (optionally OUT) */ #define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001 #define FLAG_RNDIS_PHYM_WIRELESS 0x0002 +/* Flags for driver_info::data */ +#define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */ extern void rndis_status(struct usbnet *dev, struct urb *urb); extern int -- GitLab From 280f294f7bd0c14d9f802a551c95dc930e31d723 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 13 Apr 2011 19:01:22 -0300 Subject: [PATCH 0872/5560] Bluetooth: Don't lock sock inside l2cap_get_sock_by_scid() Fix an locking issue with the new l2cap_att_channel(). l2cap_att_channel() was trying to lock a locked socket. Reported-by: Anderson Lizardo Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c9c1f9257a91..d5db5a38df6a 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -594,7 +594,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) */ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) { - struct sock *s, *sk = NULL, *sk1 = NULL; + struct sock *sk = NULL, *sk1 = NULL; struct hlist_node *node; read_lock(&l2cap_sk_list.lock); @@ -613,12 +613,10 @@ static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) sk1 = sk; } } - s = node ? sk : sk1; - if (s) - bh_lock_sock(s); + read_unlock(&l2cap_sk_list.lock); - return s; + return node ? sk : sk1; } static void l2cap_le_conn_ready(struct l2cap_conn *conn) -- GitLab From f1407d5c66240b33d11a7f1a41d55ccf6a9d7647 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 4 Apr 2011 13:44:59 +0900 Subject: [PATCH 0873/5560] usb: renesas_usbhs: Add Renesas USBHS common code Renesas SuperH has USBHS IP which can switch Host / Function. This driver is designed so that Host / Function may dynamically change. This patch add usb/renesas_usbhs and common code for SuperH USBHS. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/Makefile | 1 + drivers/usb/Kconfig | 2 + drivers/usb/renesas_usbhs/Kconfig | 15 + drivers/usb/renesas_usbhs/Makefile | 7 + drivers/usb/renesas_usbhs/common.c | 394 +++++++++++++ drivers/usb/renesas_usbhs/common.h | 225 ++++++++ drivers/usb/renesas_usbhs/mod.c | 261 +++++++++ drivers/usb/renesas_usbhs/mod.h | 106 ++++ drivers/usb/renesas_usbhs/pipe.c | 880 +++++++++++++++++++++++++++++ drivers/usb/renesas_usbhs/pipe.h | 105 ++++ include/linux/usb/renesas_usbhs.h | 149 +++++ 11 files changed, 2145 insertions(+) create mode 100644 drivers/usb/renesas_usbhs/Kconfig create mode 100644 drivers/usb/renesas_usbhs/Makefile create mode 100644 drivers/usb/renesas_usbhs/common.c create mode 100644 drivers/usb/renesas_usbhs/common.h create mode 100644 drivers/usb/renesas_usbhs/mod.c create mode 100644 drivers/usb/renesas_usbhs/mod.h create mode 100644 drivers/usb/renesas_usbhs/pipe.c create mode 100644 drivers/usb/renesas_usbhs/pipe.h create mode 100644 include/linux/usb/renesas_usbhs.h diff --git a/drivers/Makefile b/drivers/Makefile index 3f135b6fb014..ad67b7d4c271 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_UWB) += uwb/ obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/ +obj-$(CONFIG_USB_RENESAS_USBHS) += usb/renesas_usbhs/ obj-$(CONFIG_PCI) += usb/ obj-$(CONFIG_USB_GADGET) += usb/gadget/ obj-$(CONFIG_SERIO) += input/serio/ diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 41b6e51188e4..d299906e4f00 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -115,6 +115,8 @@ source "drivers/usb/host/Kconfig" source "drivers/usb/musb/Kconfig" +source "drivers/usb/renesas_usbhs/Kconfig" + source "drivers/usb/class/Kconfig" source "drivers/usb/storage/Kconfig" diff --git a/drivers/usb/renesas_usbhs/Kconfig b/drivers/usb/renesas_usbhs/Kconfig new file mode 100644 index 000000000000..481490e5500a --- /dev/null +++ b/drivers/usb/renesas_usbhs/Kconfig @@ -0,0 +1,15 @@ +# +# Renesas USB Controller Drivers +# + +config USB_RENESAS_USBHS + tristate 'Renesas USBHS controller' + default n + help + Renesas USBHS is a discrete USB host and peripheral controller chip + that supports both full and high speed USB 2.0 data transfers. + It has nine or more configurable endpoints, and endpoint zero. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "renesas_usbhs" and force all + gadget drivers to also be dynamically linked. diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile new file mode 100644 index 000000000000..d76f3dd3b9d1 --- /dev/null +++ b/drivers/usb/renesas_usbhs/Makefile @@ -0,0 +1,7 @@ +# +# for Renesas USB +# + +obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o + +renesas_usbhs-y := common.o mod.o pipe.o diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c new file mode 100644 index 000000000000..d9ad60d1c156 --- /dev/null +++ b/drivers/usb/renesas_usbhs/common.c @@ -0,0 +1,394 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 "./common.h" + +/* + * platform call back + * + * renesas usb support platform callback function. + * Below macro call it. + * if platform doesn't have callback, it return 0 (no error) + */ +#define usbhs_platform_call(priv, func, args...)\ + (!(priv) ? -ENODEV : \ + !((priv)->pfunc->func) ? 0 : \ + (priv)->pfunc->func(args)) + +/* + * common functions + */ +u16 usbhs_read(struct usbhs_priv *priv, u32 reg) +{ + return ioread16(priv->base + reg); +} + +void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data) +{ + iowrite16(data, priv->base + reg); +} + +void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data) +{ + u16 val = usbhs_read(priv, reg); + + val &= ~mask; + val |= data & mask; + + usbhs_write(priv, reg, val); +} + +/* + * syscfg functions + */ +void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0); +} + +void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, HSE, enable ? HSE : 0); +} + +void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, USBE, enable ? USBE : 0); +} + +void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) +{ + u16 mask = DCFM | DRPD | DPRPU; + u16 val = DCFM | DRPD; + + /* + * if enable + * + * - select Host mode + * - D+ Line/D- Line Pull-down + */ + usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); +} + +void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) +{ + u16 mask = DCFM | DRPD | DPRPU; + u16 val = DPRPU; + + /* + * if enable + * + * - select Function mode + * - D+ Line Pull-up + */ + usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); +} + +/* + * frame functions + */ +int usbhs_frame_get_num(struct usbhs_priv *priv) +{ + return usbhs_read(priv, FRMNUM) & FRNM_MASK; +} + +/* + * local functions + */ +static struct usbhs_priv *usbhsc_pdev_to_priv(struct platform_device *pdev) +{ + return dev_get_drvdata(&pdev->dev); +} + +static void usbhsc_bus_ctrl(struct usbhs_priv *priv, int enable) +{ + int wait = usbhs_get_dparam(priv, buswait_bwait); + u16 data = 0; + + if (enable) { + /* set bus wait if platform have */ + if (wait) + usbhs_bset(priv, BUSWAIT, 0x000F, wait); + } + usbhs_write(priv, DVSTCTR, data); +} + +/* + * platform default param + */ +static u32 usbhsc_default_pipe_type[] = { + USB_ENDPOINT_XFER_CONTROL, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_ISOC, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_BULK, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, + USB_ENDPOINT_XFER_INT, +}; + +/* + * driver callback functions + */ +static void usbhsc_notify_hotplug(struct work_struct *work) +{ + struct usbhs_priv *priv = container_of(work, + struct usbhs_priv, + notify_hotplug_work); + struct platform_device *pdev = usbhs_priv_to_pdev(priv); + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + int id; + int enable; + int ret; + + /* + * get vbus status from platform + */ + enable = usbhs_platform_call(priv, get_vbus, pdev); + + /* + * get id from platform + */ + id = usbhs_platform_call(priv, get_id, pdev); + + if (enable && !mod) { + ret = usbhs_mod_change(priv, id); + if (ret < 0) + return; + + dev_dbg(&pdev->dev, "%s enable\n", __func__); + + /* enable PM */ + pm_runtime_get_sync(&pdev->dev); + + /* USB on */ + usbhs_sys_clock_ctrl(priv, enable); + usbhsc_bus_ctrl(priv, enable); + + /* module start */ + usbhs_mod_call(priv, start, priv); + + } else if (!enable && mod) { + dev_dbg(&pdev->dev, "%s disable\n", __func__); + + /* module stop */ + usbhs_mod_call(priv, stop, priv); + + /* USB off */ + usbhsc_bus_ctrl(priv, enable); + usbhs_sys_clock_ctrl(priv, enable); + + /* disable PM */ + pm_runtime_put_sync(&pdev->dev); + + usbhs_mod_change(priv, -1); + + /* reset phy for next connection */ + usbhs_platform_call(priv, phy_reset, pdev); + } +} + +static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) +{ + struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev); + + /* + * This functions will be called in interrupt. + * To make sure safety context, + * use workqueue for usbhs_notify_hotplug + */ + schedule_work(&priv->notify_hotplug_work); + return 0; +} + +/* + * platform functions + */ +static int __devinit usbhs_probe(struct platform_device *pdev) +{ + struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; + struct renesas_usbhs_driver_callback *dfunc; + struct usbhs_priv *priv; + struct resource *res; + unsigned int irq; + int ret; + + /* check platform information */ + if (!info || + !info->platform_callback.get_id || + !info->platform_callback.get_vbus) { + dev_err(&pdev->dev, "no platform information\n"); + return -EINVAL; + } + + /* platform data */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || (int)irq <= 0) { + dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); + return -ENODEV; + } + + /* usb private data */ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "Could not allocate priv\n"); + return -ENOMEM; + } + + priv->base = ioremap_nocache(res->start, resource_size(res)); + if (!priv->base) { + dev_err(&pdev->dev, "ioremap error.\n"); + ret = -ENOMEM; + goto probe_end_kfree; + } + + /* + * care platform info + */ + priv->pfunc = &info->platform_callback; + priv->dparam = &info->driver_param; + + /* set driver callback functions for platform */ + dfunc = &info->driver_callback; + dfunc->notify_hotplug = usbhsc_drvcllbck_notify_hotplug; + + /* set default param if platform doesn't have */ + if (!priv->dparam->pipe_type) { + priv->dparam->pipe_type = usbhsc_default_pipe_type; + priv->dparam->pipe_size = ARRAY_SIZE(usbhsc_default_pipe_type); + } + + /* + * priv settings + */ + priv->irq = irq; + priv->pdev = pdev; + INIT_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); + spin_lock_init(usbhs_priv_to_lock(priv)); + + /* call pipe and module init */ + ret = usbhs_pipe_probe(priv); + if (ret < 0) + goto probe_end_mod_exit; + + ret = usbhs_mod_probe(priv); + if (ret < 0) + goto probe_end_iounmap; + + /* dev_set_drvdata should be called after usbhs_mod_init */ + dev_set_drvdata(&pdev->dev, priv); + + /* + * deviece reset here because + * USB device might be used in boot loader. + */ + usbhs_sys_clock_ctrl(priv, 0); + + /* + * platform call + * + * USB phy setup might depend on CPU/Board. + * If platform has its callback functions, + * call it here. + */ + ret = usbhs_platform_call(priv, hardware_init, pdev); + if (ret < 0) { + dev_err(&pdev->dev, "platform prove failed.\n"); + goto probe_end_pipe_exit; + } + + /* reset phy for connection */ + usbhs_platform_call(priv, phy_reset, pdev); + + /* + * manual call notify_hotplug for cold plug + */ + pm_runtime_enable(&pdev->dev); + ret = usbhsc_drvcllbck_notify_hotplug(pdev); + if (ret < 0) + goto probe_end_call_remove; + + dev_info(&pdev->dev, "probed\n"); + + return ret; + +probe_end_call_remove: + usbhs_platform_call(priv, hardware_exit, pdev); +probe_end_pipe_exit: + usbhs_pipe_remove(priv); +probe_end_mod_exit: + usbhs_mod_remove(priv); +probe_end_iounmap: + iounmap(priv->base); +probe_end_kfree: + kfree(priv); + + dev_info(&pdev->dev, "probe failed\n"); + + return ret; +} + +static int __devexit usbhs_remove(struct platform_device *pdev) +{ + struct usbhs_priv *priv = usbhsc_pdev_to_priv(pdev); + + dev_dbg(&pdev->dev, "usb remove\n"); + + pm_runtime_disable(&pdev->dev); + + usbhsc_bus_ctrl(priv, 0); + + usbhs_platform_call(priv, hardware_exit, pdev); + usbhs_pipe_remove(priv); + usbhs_mod_remove(priv); + iounmap(priv->base); + kfree(priv); + + return 0; +} + +static struct platform_driver renesas_usbhs_driver = { + .driver = { + .name = "renesas_usbhs", + }, + .probe = usbhs_probe, + .remove = __devexit_p(usbhs_remove), +}; + +static int __init usbhs_init(void) +{ + return platform_driver_register(&renesas_usbhs_driver); +} + +static void __exit usbhs_exit(void) +{ + platform_driver_unregister(&renesas_usbhs_driver); +} + +module_init(usbhs_init); +module_exit(usbhs_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Renesas USB driver"); +MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h new file mode 100644 index 000000000000..f1a2b62f93f9 --- /dev/null +++ b/drivers/usb/renesas_usbhs/common.h @@ -0,0 +1,225 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 RENESAS_USB_DRIVER_H +#define RENESAS_USB_DRIVER_H + +#include +#include + +struct usbhs_priv; + +#include "./mod.h" +#include "./pipe.h" + +/* + * + * register define + * + */ +#define SYSCFG 0x0000 +#define BUSWAIT 0x0002 +#define DVSTCTR 0x0008 +#define CFIFO 0x0014 +#define CFIFOSEL 0x0020 +#define CFIFOCTR 0x0022 +#define INTENB0 0x0030 +#define INTENB1 0x0032 +#define BRDYENB 0x0036 +#define NRDYENB 0x0038 +#define BEMPENB 0x003A +#define INTSTS0 0x0040 +#define INTSTS1 0x0042 +#define BRDYSTS 0x0046 +#define NRDYSTS 0x0048 +#define BEMPSTS 0x004A +#define FRMNUM 0x004C +#define USBREQ 0x0054 /* USB request type register */ +#define USBVAL 0x0056 /* USB request value register */ +#define USBINDX 0x0058 /* USB request index register */ +#define USBLENG 0x005A /* USB request length register */ +#define DCPCFG 0x005C +#define DCPMAXP 0x005E +#define DCPCTR 0x0060 +#define PIPESEL 0x0064 +#define PIPECFG 0x0068 +#define PIPEBUF 0x006A +#define PIPEMAXP 0x006C +#define PIPEPERI 0x006E +#define PIPEnCTR 0x0070 + +/* SYSCFG */ +#define SCKE (1 << 10) /* USB Module Clock Enable */ +#define HSE (1 << 7) /* High-Speed Operation Enable */ +#define DCFM (1 << 6) /* Controller Function Select */ +#define DRPD (1 << 5) /* D+ Line/D- Line Resistance Control */ +#define DPRPU (1 << 4) /* D+ Line Resistance Control */ +#define USBE (1 << 0) /* USB Module Operation Enable */ + +/* DVSTCTR */ +#define EXTLP (1 << 10) /* Controls the EXTLP pin output state */ +#define PWEN (1 << 9) /* Controls the PWEN pin output state */ +#define RHST (0x7) /* Reset Handshake */ +#define RHST_LOW_SPEED 1 /* Low-speed connection */ +#define RHST_FULL_SPEED 2 /* Full-speed connection */ +#define RHST_HIGH_SPEED 3 /* High-speed connection */ + +/* CFIFOSEL */ +#define MBW_32 (0x2 << 10) /* CFIFO Port Access Bit Width */ + +/* CFIFOCTR */ +#define BVAL (1 << 15) /* Buffer Memory Enable Flag */ +#define BCLR (1 << 14) /* CPU buffer clear */ +#define FRDY (1 << 13) /* FIFO Port Ready */ +#define DTLN_MASK (0x0FFF) /* Receive Data Length */ + +/* INTENB0 */ +#define VBSE (1 << 15) /* Enable IRQ VBUS_0 and VBUSIN_0 */ +#define RSME (1 << 14) /* Enable IRQ Resume */ +#define SOFE (1 << 13) /* Enable IRQ Frame Number Update */ +#define DVSE (1 << 12) /* Enable IRQ Device State Transition */ +#define CTRE (1 << 11) /* Enable IRQ Control Stage Transition */ +#define BEMPE (1 << 10) /* Enable IRQ Buffer Empty */ +#define NRDYE (1 << 9) /* Enable IRQ Buffer Not Ready Response */ +#define BRDYE (1 << 8) /* Enable IRQ Buffer Ready */ + +/* INTENB1 */ +#define BCHGE (1 << 14) /* USB Bus Change Interrupt Enable */ +#define DTCHE (1 << 12) /* Disconnection Detect Interrupt Enable */ +#define ATTCHE (1 << 11) /* Connection Detect Interrupt Enable */ +#define EOFERRE (1 << 6) /* EOF Error Detect Interrupt Enable */ +#define SIGNE (1 << 5) /* Setup Transaction Error Interrupt Enable */ +#define SACKE (1 << 4) /* Setup Transaction ACK Interrupt Enable */ + +/* INTSTS0 */ +#define DVST (1 << 12) /* Device State Transition Interrupt Status */ +#define CTRT (1 << 11) /* Control Stage Interrupt Status */ +#define BEMP (1 << 10) /* Buffer Empty Interrupt Status */ +#define BRDY (1 << 8) /* Buffer Ready Interrupt Status */ +#define VBSTS (1 << 7) /* VBUS_0 and VBUSIN_0 Input Status */ +#define VALID (1 << 3) /* USB Request Receive */ + +#define DVSQ_MASK (0x3 << 4) /* Device State */ +#define POWER_STATE (0 << 4) +#define DEFAULT_STATE (1 << 4) +#define ADDRESS_STATE (2 << 4) +#define CONFIGURATION_STATE (3 << 4) + +#define CTSQ_MASK (0x7) /* Control Transfer Stage */ +#define IDLE_SETUP_STAGE 0 /* Idle stage or setup stage */ +#define READ_DATA_STAGE 1 /* Control read data stage */ +#define READ_STATUS_STAGE 2 /* Control read status stage */ +#define WRITE_DATA_STAGE 3 /* Control write data stage */ +#define WRITE_STATUS_STAGE 4 /* Control write status stage */ +#define NODATA_STATUS_STAGE 5 /* Control write NoData status stage */ +#define SEQUENCE_ERROR 6 /* Control transfer sequence error */ + +/* PIPECFG */ +/* DCPCFG */ +#define TYPE_NONE (0 << 14) /* Transfer Type */ +#define TYPE_BULK (1 << 14) +#define TYPE_INT (2 << 14) +#define TYPE_ISO (3 << 14) +#define DBLB (1 << 9) /* Double Buffer Mode */ +#define SHTNAK (1 << 7) /* Pipe Disable in Transfer End */ +#define DIR_OUT (1 << 4) /* Transfer Direction */ + +/* PIPEMAXP */ +/* DCPMAXP */ +#define DEVSEL_MASK (0xF << 12) /* Device Select */ +#define DCP_MAXP_MASK (0x7F) +#define PIPE_MAXP_MASK (0x7FF) + +/* PIPEBUF */ +#define BUFSIZE_SHIFT 10 +#define BUFSIZE_MASK (0x1F << BUFSIZE_SHIFT) +#define BUFNMB_MASK (0xFF) + +/* PIPEnCTR */ +/* DCPCTR */ +#define BSTS (1 << 15) /* Buffer Status */ +#define CSSTS (1 << 12) /* CSSTS Status */ +#define SQCLR (1 << 8) /* Toggle Bit Clear */ +#define ACLRM (1 << 9) /* Buffer Auto-Clear Mode */ +#define PBUSY (1 << 5) /* Pipe Busy */ +#define PID_MASK (0x3) /* Response PID */ +#define PID_NAK 0 +#define PID_BUF 1 +#define PID_STALL10 2 +#define PID_STALL11 3 + +#define CCPL (1 << 2) /* Control Transfer End Enable */ + +/* FRMNUM */ +#define FRNM_MASK (0x7FF) + +/* + * struct + */ +struct usbhs_priv { + + void __iomem *base; + unsigned int irq; + + struct renesas_usbhs_platform_callback *pfunc; + struct renesas_usbhs_driver_param *dparam; + + struct work_struct notify_hotplug_work; + struct platform_device *pdev; + + spinlock_t lock; + + /* + * module control + */ + struct usbhs_mod_info mod_info; + + /* + * pipe control + */ + struct usbhs_pipe_info pipe_info; +}; + +/* + * common + */ +u16 usbhs_read(struct usbhs_priv *priv, u32 reg); +void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); +void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); + +/* + * sysconfig + */ +void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); + +/* + * frame + */ +int usbhs_frame_get_num(struct usbhs_priv *priv); + +/* + * data + */ +#define usbhs_get_dparam(priv, param) (priv->dparam->param) +#define usbhs_priv_to_pdev(priv) (priv->pdev) +#define usbhs_priv_to_dev(priv) (&priv->pdev->dev) +#define usbhs_priv_to_lock(priv) (&priv->lock) + +#endif /* RENESAS_USB_DRIVER_H */ diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c new file mode 100644 index 000000000000..4a3398484cd7 --- /dev/null +++ b/drivers/usb/renesas_usbhs/mod.c @@ -0,0 +1,261 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 "./common.h" +#include "./mod.h" + +#define usbhs_priv_to_modinfo(priv) (&priv->mod_info) + +/* + * host / gadget functions + * + * renesas_usbhs host/gadget can register itself by below functions. + * these functions are called when probe + * + */ +void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *mod, int id) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + + info->mod[id] = mod; + mod->priv = priv; +} + +struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + struct usbhs_mod *ret = NULL; + + switch (id) { + case USBHS_HOST: + case USBHS_GADGET: + ret = info->mod[id]; + break; + } + + return ret; +} + +int usbhs_mod_is_host(struct usbhs_priv *priv, struct usbhs_mod *mod) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + + if (!mod) + return -EINVAL; + + return info->mod[USBHS_HOST] == mod; +} + +struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + + return info->curt; +} + +int usbhs_mod_change(struct usbhs_priv *priv, int id) +{ + struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); + struct usbhs_mod *mod = NULL; + int ret = 0; + + /* id < 0 mean no current */ + switch (id) { + case USBHS_HOST: + case USBHS_GADGET: + mod = info->mod[id]; + break; + default: + ret = -EINVAL; + } + info->curt = mod; + + return ret; +} + +static irqreturn_t usbhs_interrupt(int irq, void *data); +int usbhs_mod_probe(struct usbhs_priv *priv) +{ + struct device *dev = usbhs_priv_to_dev(priv); + int ret; + + /* irq settings */ + ret = request_irq(priv->irq, usbhs_interrupt, + IRQF_DISABLED, dev_name(dev), priv); + if (ret) + dev_err(dev, "irq request err\n"); + + return ret; +} + +void usbhs_mod_remove(struct usbhs_priv *priv) +{ + free_irq(priv->irq, priv); +} + +/* + * status functions + */ +int usbhs_status_get_usb_speed(struct usbhs_irq_state *irq_state) +{ + switch (irq_state->dvstctr & RHST) { + case RHST_LOW_SPEED: + return USB_SPEED_LOW; + case RHST_FULL_SPEED: + return USB_SPEED_FULL; + case RHST_HIGH_SPEED: + return USB_SPEED_HIGH; + } + + return USB_SPEED_UNKNOWN; +} + +int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state) +{ + int state = irq_state->intsts0 & DVSQ_MASK; + + switch (state) { + case POWER_STATE: + case DEFAULT_STATE: + case ADDRESS_STATE: + case CONFIGURATION_STATE: + return state; + } + + return -EIO; +} + +int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state) +{ + /* + * return value + * + * IDLE_SETUP_STAGE + * READ_DATA_STAGE + * READ_STATUS_STAGE + * WRITE_DATA_STAGE + * WRITE_STATUS_STAGE + * NODATA_STATUS_STAGE + * SEQUENCE_ERROR + */ + return (int)irq_state->intsts0 & CTSQ_MASK; +} + +static void usbhs_status_get_each_irq(struct usbhs_priv *priv, + struct usbhs_irq_state *state) +{ + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + + state->intsts0 = usbhs_read(priv, INTSTS0); + state->intsts1 = usbhs_read(priv, INTSTS1); + + state->brdysts = usbhs_read(priv, BRDYSTS); + state->nrdysts = usbhs_read(priv, NRDYSTS); + state->bempsts = usbhs_read(priv, BEMPSTS); + + state->dvstctr = usbhs_read(priv, DVSTCTR); + + /* mask */ + state->bempsts &= mod->irq_bempsts; + state->brdysts &= mod->irq_brdysts; +} + +/* + * interrupt + */ +#define INTSTS0_MAGIC 0xF800 /* acknowledge magical interrupt sources */ +#define INTSTS1_MAGIC 0xA870 /* acknowledge magical interrupt sources */ +static irqreturn_t usbhs_interrupt(int irq, void *data) +{ + struct usbhs_priv *priv = data; + struct usbhs_irq_state irq_state; + + usbhs_status_get_each_irq(priv, &irq_state); + + /* + * clear interrupt + * + * The hardware is _very_ picky to clear interrupt bit. + * Especially INTSTS0_MAGIC, INTSTS1_MAGIC value. + * + * see + * "Operation" + * - "Control Transfer (DCP)" + * - Function :: VALID bit should 0 + */ + usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); + usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); + + usbhs_write(priv, BRDYSTS, 0); + usbhs_write(priv, NRDYSTS, 0); + usbhs_write(priv, BEMPSTS, 0); + + /* + * call irq callback functions + * see also + * usbhs_irq_setting_update + */ + if (irq_state.intsts0 & DVST) + usbhs_mod_call(priv, irq_dev_state, priv, &irq_state); + + if (irq_state.intsts0 & CTRT) + usbhs_mod_call(priv, irq_ctrl_stage, priv, &irq_state); + + if (irq_state.intsts0 & BEMP) + usbhs_mod_call(priv, irq_empty, priv, &irq_state); + + if (irq_state.intsts0 & BRDY) + usbhs_mod_call(priv, irq_ready, priv, &irq_state); + + return IRQ_HANDLED; +} + +void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) +{ + u16 intenb0 = 0; + + usbhs_write(priv, INTENB0, 0); + + usbhs_write(priv, BEMPENB, 0); + usbhs_write(priv, BRDYENB, 0); + + /* + * see also + * usbhs_interrupt + */ + + /* + * it don't enable DVSE (intenb0) here + * but "mod->irq_dev_state" will be called. + */ + + if (mod->irq_ctrl_stage) + intenb0 |= CTRE; + + if (mod->irq_empty && mod->irq_bempsts) { + usbhs_write(priv, BEMPENB, mod->irq_bempsts); + intenb0 |= BEMPE; + } + + if (mod->irq_ready && mod->irq_brdysts) { + usbhs_write(priv, BRDYENB, mod->irq_brdysts); + intenb0 |= BRDYE; + } + + usbhs_write(priv, INTENB0, intenb0); +} diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h new file mode 100644 index 000000000000..bd873d5b432a --- /dev/null +++ b/drivers/usb/renesas_usbhs/mod.h @@ -0,0 +1,106 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 RENESAS_USB_MOD_H +#define RENESAS_USB_MOD_H + +#include +#include +#include "./common.h" + +/* + * struct + */ +struct usbhs_irq_state { + u16 intsts0; + u16 intsts1; + u16 brdysts; + u16 nrdysts; + u16 bempsts; + u16 dvstctr; +}; + +struct usbhs_mod { + char *name; + + /* + * entry point from common.c + */ + int (*start)(struct usbhs_priv *priv); + int (*stop)(struct usbhs_priv *priv); + + /* INTSTS0 :: DVST (DVSQ) */ + int (*irq_dev_state)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + + /* INTSTS0 :: CTRT (CTSQ) */ + int (*irq_ctrl_stage)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + + /* INTSTS0 :: BEMP */ + /* BEMPSTS */ + int (*irq_empty)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + u16 irq_bempsts; + + /* INTSTS0 :: BRDY */ + /* BRDYSTS */ + int (*irq_ready)(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state); + u16 irq_brdysts; + + struct usbhs_priv *priv; +}; + +struct usbhs_mod_info { + struct usbhs_mod *mod[USBHS_MAX]; + struct usbhs_mod *curt; /* current mod */ +}; + +/* + * for host/gadget module + */ +struct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id); +struct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv); +void usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *usb, int id); +int usbhs_mod_is_host(struct usbhs_priv *priv, struct usbhs_mod *mod); +int usbhs_mod_change(struct usbhs_priv *priv, int id); +int usbhs_mod_probe(struct usbhs_priv *priv); +void usbhs_mod_remove(struct usbhs_priv *priv); + +/* + * status functions + */ +int usbhs_status_get_usb_speed(struct usbhs_irq_state *irq_state); +int usbhs_status_get_device_state(struct usbhs_irq_state *irq_state); +int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state); + +/* + * callback functions + */ +void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); + + +#define usbhs_mod_call(priv, func, param...) \ + ({ \ + struct usbhs_mod *mod; \ + mod = usbhs_mod_get_current(priv); \ + !mod ? -ENODEV : \ + !mod->func ? 0 : \ + mod->func(param); \ + }) + +#endif /* RENESAS_USB_MOD_H */ diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c new file mode 100644 index 000000000000..b7a9137f599b --- /dev/null +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -0,0 +1,880 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 "./common.h" +#include "./pipe.h" + +/* + * macros + */ +#define usbhsp_priv_to_pipeinfo(pr) (&(pr)->pipe_info) +#define usbhsp_pipe_to_priv(p) ((p)->priv) + +#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2) + +#define usbhsp_is_dcp(p) ((p)->priv->pipe_info.pipe == (p)) + +#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f) +#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f) +#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f) +#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0) + +#define usbhsp_type(p) ((p)->pipe_type) +#define usbhsp_type_is(p, t) ((p)->pipe_type == t) + +/* + * for debug + */ +static char *usbhsp_pipe_name[] = { + [USB_ENDPOINT_XFER_CONTROL] = "DCP", + [USB_ENDPOINT_XFER_BULK] = "BULK", + [USB_ENDPOINT_XFER_INT] = "INT", + [USB_ENDPOINT_XFER_ISOC] = "ISO", +}; + +/* + * usb request functions + */ +void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) +{ + u16 val; + + val = usbhs_read(priv, USBREQ); + req->bRequest = (val >> 8) & 0xFF; + req->bRequestType = (val >> 0) & 0xFF; + + req->wValue = usbhs_read(priv, USBVAL); + req->wIndex = usbhs_read(priv, USBINDX); + req->wLength = usbhs_read(priv, USBLENG); +} + +void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) +{ + usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType); + usbhs_write(priv, USBVAL, req->wValue); + usbhs_write(priv, USBINDX, req->wIndex); + usbhs_write(priv, USBLENG, req->wLength); +} + +/* + * DCPCTR/PIPEnCTR functions + */ +static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + int offset = usbhsp_addr_offset(pipe); + + if (usbhsp_is_dcp(pipe)) + usbhs_bset(priv, DCPCTR, mask, val); + else + usbhs_bset(priv, PIPEnCTR + offset, mask, val); +} + +static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + int offset = usbhsp_addr_offset(pipe); + + if (usbhsp_is_dcp(pipe)) + return usbhs_read(priv, DCPCTR); + else + return usbhs_read(priv, PIPEnCTR + offset); +} + +/* + * DCP/PIPE functions + */ +static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe, + u16 dcp_reg, u16 pipe_reg, + u16 mask, u16 val) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + if (usbhsp_is_dcp(pipe)) + usbhs_bset(priv, dcp_reg, mask, val); + else + usbhs_bset(priv, pipe_reg, mask, val); +} + +static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe, + u16 dcp_reg, u16 pipe_reg) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + if (usbhsp_is_dcp(pipe)) + return usbhs_read(priv, dcp_reg); + else + return usbhs_read(priv, pipe_reg); +} + +/* + * DCPCFG/PIPECFG functions + */ +static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val); +} + +/* + * PIPEBUF + */ +static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + if (usbhsp_is_dcp(pipe)) + return; + + __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val); +} + +/* + * DCPMAXP/PIPEMAXP + */ +static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val); +} + +static u16 usbhsp_pipe_maxp_get(struct usbhs_pipe *pipe) +{ + return __usbhsp_pipe_xxx_get(pipe, DCPMAXP, PIPEMAXP); +} + +/* + * pipe control functions + */ +static void usbhsp_pipe_select(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + /* + * On pipe, this is necessary before + * accesses to below registers. + * + * PIPESEL : usbhsp_pipe_select + * PIPECFG : usbhsp_pipe_cfg_xxx + * PIPEBUF : usbhsp_pipe_buf_xxx + * PIPEMAXP : usbhsp_pipe_maxp_xxx + * PIPEPERI + */ + + /* + * if pipe is dcp, no pipe is selected. + * it is no problem, because dcp have its register + */ + usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe)); +} + +static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + struct device *dev = usbhs_priv_to_dev(priv); + int timeout = 1024; + u16 val; + + /* + * make sure.... + * + * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is + * specified by the CURPIPE bits. + * When changing the setting of this bit after changing + * the PID bits for the selected pipe from BUF to NAK, + * check that CSSTS = 0 and PBUSY = 0. + */ + + /* + * CURPIPE bit = 0 + * + * see also + * "Operation" + * - "Pipe Control" + * - "Pipe Control Registers Switching Procedure" + */ + usbhs_write(priv, CFIFOSEL, 0); + + do { + val = usbhsp_pipectrl_get(pipe); + val &= CSSTS | PID_MASK; + if (!val) + return 0; + + udelay(10); + + } while (timeout--); + + /* + * force NAK + */ + timeout = 1024; + usbhs_fifo_disable(pipe); + do { + val = usbhsp_pipectrl_get(pipe); + val &= PBUSY; + if (!val) + return 0; + + } while (timeout--); + + dev_err(dev, "pipe barrier failed\n"); + + return -EBUSY; +} + +static int usbhsp_pipe_is_accessible(struct usbhs_pipe *pipe) +{ + u16 val; + + val = usbhsp_pipectrl_get(pipe); + if (val & BSTS) + return 0; + + return -EBUSY; +} + +/* + * PID ctrl + */ +static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe) +{ + u16 pid = usbhsp_pipectrl_get(pipe); + + pid &= PID_MASK; + + /* + * see + * "Pipe n Control Register" - "PID" + */ + switch (pid) { + case PID_STALL11: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10); + /* fall-through */ + case PID_STALL10: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK); + } +} + +void usbhs_fifo_disable(struct usbhs_pipe *pipe) +{ + /* see "Pipe n Control Register" - "PID" */ + __usbhsp_pid_try_nak_if_stall(pipe); + + usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK); +} + +void usbhs_fifo_enable(struct usbhs_pipe *pipe) +{ + /* see "Pipe n Control Register" - "PID" */ + __usbhsp_pid_try_nak_if_stall(pipe); + + usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF); +} + +void usbhs_fifo_stall(struct usbhs_pipe *pipe) +{ + u16 pid = usbhsp_pipectrl_get(pipe); + + pid &= PID_MASK; + + /* + * see + * "Pipe n Control Register" - "PID" + */ + switch (pid) { + case PID_NAK: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10); + break; + case PID_BUF: + usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11); + break; + } +} + +/* + * CFIFO ctrl + */ +void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + usbhs_bset(priv, CFIFOCTR, BVAL, BVAL); +} + +static void usbhsp_fifo_clear(struct usbhs_pipe *pipe) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + + usbhs_write(priv, CFIFOCTR, BCLR); +} + +static int usbhsp_fifo_barrier(struct usbhs_priv *priv) +{ + int timeout = 1024; + + do { + /* The FIFO port is accessible */ + if (usbhs_read(priv, CFIFOCTR) & FRDY) + return 0; + + udelay(10); + } while (timeout--); + + return -EBUSY; +} + +static int usbhsp_fifo_rcv_len(struct usbhs_priv *priv) +{ + return usbhs_read(priv, CFIFOCTR) & DTLN_MASK; +} + +static int usbhsp_fifo_select(struct usbhs_pipe *pipe, int write) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + struct device *dev = usbhs_priv_to_dev(priv); + int timeout = 1024; + u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */ + u16 base = usbhs_pipe_number(pipe); /* CURPIPE */ + + if (usbhsp_is_dcp(pipe)) + base |= (1 == write) << 5; /* ISEL */ + + /* "base" will be used below */ + usbhs_write(priv, CFIFOSEL, base | MBW_32); + + /* check ISEL and CURPIPE value */ + while (timeout--) { + if (base == (mask & usbhs_read(priv, CFIFOSEL))) + return 0; + udelay(10); + } + + dev_err(dev, "fifo select error\n"); + + return -EIO; +} + +int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe) +{ + int ret; + + ret = usbhsp_fifo_select(pipe, 1); + if (ret < 0) + return ret; + + usbhsp_fifo_clear(pipe); + + return ret; +} + +int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + void __iomem *addr = priv->base + CFIFO; + int maxp = usbhs_pipe_get_maxpacket(pipe); + int total_len; + int i, ret; + + ret = usbhsp_pipe_is_accessible(pipe); + if (ret < 0) + return ret; + + ret = usbhs_fifo_prepare_write(pipe); + if (ret < 0) + return ret; + + ret = usbhsp_fifo_barrier(priv); + if (ret < 0) + return ret; + + len = min(len, maxp); + total_len = len; + + /* + * FIXME + * + * 32-bit access only + */ + if (len >= 4 && + !((unsigned long)buf & 0x03)) { + iowrite32_rep(addr, buf, len / 4); + len %= 4; + buf += total_len - len; + } + + /* the rest operation */ + for (i = 0; i < len; i++) + iowrite8(buf[i], addr + (0x03 - (i & 0x03))); + + if (total_len < maxp) + usbhs_fifo_send_terminator(pipe); + + return total_len; +} + +int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe) +{ + int ret; + + /* + * select pipe and enable it to prepare packet receive + */ + ret = usbhsp_fifo_select(pipe, 0); + if (ret < 0) + return ret; + + usbhs_fifo_enable(pipe); + + return ret; +} + +int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + void __iomem *addr = priv->base + CFIFO; + int rcv_len; + int i, ret; + int total_len; + u32 data = 0; + + ret = usbhsp_fifo_select(pipe, 0); + if (ret < 0) + return ret; + + ret = usbhsp_fifo_barrier(priv); + if (ret < 0) + return ret; + + rcv_len = usbhsp_fifo_rcv_len(priv); + + /* + * Buffer clear if Zero-Length packet + * + * see + * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" + */ + if (0 == rcv_len) { + usbhsp_fifo_clear(pipe); + return 0; + } + + len = min(rcv_len, len); + total_len = len; + + /* + * FIXME + * + * 32-bit access only + */ + if (len >= 4 && + !((unsigned long)buf & 0x03)) { + ioread32_rep(addr, buf, len / 4); + len %= 4; + buf += rcv_len - len; + } + + /* the rest operation */ + for (i = 0; i < len; i++) { + if (!(i & 0x03)) + data = ioread32(addr); + + buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; + } + + return total_len; +} + +/* + * pipe setup + */ +static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe) +{ + /* + * only ISO / BULK pipe can use double buffer + */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) || + usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC)) + return 1; + + return 0; +} + +static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, + const struct usb_endpoint_descriptor *desc, + int is_host) +{ + u16 type = 0; + u16 bfre = 0; + u16 dblb = 0; + u16 cntmd = 0; + u16 dir = 0; + u16 epnum = 0; + u16 shtnak = 0; + u16 type_array[] = { + [USB_ENDPOINT_XFER_BULK] = TYPE_BULK, + [USB_ENDPOINT_XFER_INT] = TYPE_INT, + [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO, + }; + int is_double = usbhsp_possible_double_buffer(pipe); + + if (usbhsp_is_dcp(pipe)) + return -EINVAL; + + /* + * PIPECFG + * + * see + * - "Register Descriptions" - "PIPECFG" register + * - "Features" - "Pipe configuration" + * - "Operation" - "Pipe Control" + */ + + /* TYPE */ + type = type_array[usbhsp_type(pipe)]; + + /* BFRE */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || + usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + bfre = 0; /* FIXME */ + + /* DBLB */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_ISOC) || + usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + dblb = (is_double) ? DBLB : 0; + + /* CNTMD */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + cntmd = 0; /* FIXME */ + + /* DIR */ + if (usb_endpoint_dir_in(desc)) + usbhsp_flags_set(pipe, IS_DIR_IN); + + if ((is_host && usb_endpoint_dir_out(desc)) || + (!is_host && usb_endpoint_dir_in(desc))) + dir |= DIR_OUT; + + /* SHTNAK */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_BULK) && + !dir) + shtnak = SHTNAK; + + /* EPNUM */ + epnum = 0xF & usb_endpoint_num(desc); + + return type | + bfre | + dblb | + cntmd | + dir | + shtnak | + epnum; +} + +static u16 usbhsp_setup_pipemaxp(struct usbhs_pipe *pipe, + const struct usb_endpoint_descriptor *desc, + int is_host) +{ + /* host should set DEVSEL */ + + /* reutn MXPS */ + return PIPE_MAXP_MASK & le16_to_cpu(desc->wMaxPacketSize); +} + +static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe, + const struct usb_endpoint_descriptor *desc, + int is_host) +{ + struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + struct device *dev = usbhs_priv_to_dev(priv); + int pipe_num = usbhs_pipe_number(pipe); + int is_double = usbhsp_possible_double_buffer(pipe); + u16 buff_size; + u16 bufnmb; + u16 bufnmb_cnt; + + /* + * PIPEBUF + * + * see + * - "Register Descriptions" - "PIPEBUF" register + * - "Features" - "Pipe configuration" + * - "Operation" - "FIFO Buffer Memory" + * - "Operation" - "Pipe Control" + * + * ex) if pipe6 - pipe9 are USB_ENDPOINT_XFER_INT (SH7724) + * + * BUFNMB: PIPE + * 0: pipe0 (DCP 256byte) + * 1: - + * 2: - + * 3: - + * 4: pipe6 (INT 64byte) + * 5: pipe7 (INT 64byte) + * 6: pipe8 (INT 64byte) + * 7: pipe9 (INT 64byte) + * 8 - xx: free (for BULK, ISOC) + */ + + /* + * FIXME + * + * it doesn't have good buffer allocator + * + * DCP : 256 byte + * BULK: 512 byte + * INT : 64 byte + * ISOC: 512 byte + */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_CONTROL)) + buff_size = 256; + else if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) + buff_size = 64; + else + buff_size = 512; + + /* change buff_size to register value */ + bufnmb_cnt = (buff_size / 64) - 1; + + /* BUFNMB has been reserved for INT pipe + * see above */ + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) { + bufnmb = pipe_num - 2; + } else { + bufnmb = info->bufnmb_last; + info->bufnmb_last += bufnmb_cnt + 1; + + /* + * double buffer + */ + if (is_double) + info->bufnmb_last += bufnmb_cnt + 1; + } + + dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n", + pipe_num, buff_size, bufnmb); + + return (0x1f & bufnmb_cnt) << 10 | + (0xff & bufnmb) << 0; +} + +/* + * pipe control + */ +int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe) +{ + u16 mask = usbhsp_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK; + + usbhsp_pipe_select(pipe); + + return (int)(usbhsp_pipe_maxp_get(pipe) & mask); +} + +int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe) +{ + return usbhsp_flags_has(pipe, IS_DIR_IN); +} + +void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe) +{ + usbhsp_pipectrl_set(pipe, SQCLR, SQCLR); +} + +static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type) +{ + struct usbhs_pipe *pos, *pipe; + int i; + + /* + * find target pipe + */ + pipe = NULL; + usbhs_for_each_pipe_with_dcp(pos, priv, i) { + if (!usbhsp_type_is(pos, type)) + continue; + if (usbhsp_flags_has(pos, IS_USED)) + continue; + + pipe = pos; + break; + } + + if (!pipe) + return NULL; + + /* + * initialize pipe flags + */ + usbhsp_flags_init(pipe); + usbhsp_flags_set(pipe, IS_USED); + + return pipe; +} + +void usbhs_pipe_init(struct usbhs_priv *priv) +{ + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + struct usbhs_pipe *pipe; + int i; + + /* + * FIXME + * + * driver needs good allocator. + * + * find first free buffer area (BULK, ISOC) + * (DCP, INT area is fixed) + * + * buffer number 0 - 3 have been reserved for DCP + * see + * usbhsp_to_bufnmb + */ + info->bufnmb_last = 4; + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { + if (usbhsp_type_is(pipe, USB_ENDPOINT_XFER_INT)) + info->bufnmb_last++; + + usbhsp_flags_init(pipe); + pipe->mod_private = NULL; + } +} + +struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, + const struct usb_endpoint_descriptor *desc) +{ + struct device *dev = usbhs_priv_to_dev(priv); + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + struct usbhs_pipe *pipe; + int is_host = usbhs_mod_is_host(priv, mod); + int ret; + u16 pipecfg, pipebuf, pipemaxp; + + pipe = usbhsp_get_pipe(priv, usb_endpoint_type(desc)); + if (!pipe) + return NULL; + + usbhs_fifo_disable(pipe); + + /* make sure pipe is not busy */ + ret = usbhsp_pipe_barrier(pipe); + if (ret < 0) { + dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe)); + return NULL; + } + + pipecfg = usbhsp_setup_pipecfg(pipe, desc, is_host); + pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host); + pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host); + + /* buffer clear + * see PIPECFG :: BFRE */ + usbhsp_pipectrl_set(pipe, ACLRM, ACLRM); + usbhsp_pipectrl_set(pipe, ACLRM, 0); + + usbhsp_pipe_select(pipe); + usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); + usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); + usbhsp_pipe_maxp_set(pipe, 0xFFFF, pipemaxp); + + usbhs_pipe_clear_sequence(pipe); + + dev_dbg(dev, "enable pipe %d : %s (%s)\n", + usbhs_pipe_number(pipe), + usbhsp_pipe_name[usb_endpoint_type(desc)], + usbhs_pipe_is_dir_in(pipe) ? "in" : "out"); + + return pipe; +} + +/* + * dcp control + */ +struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv) +{ + struct usbhs_pipe *pipe; + + pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL); + if (!pipe) + return NULL; + + /* + * dcpcfg : default + * dcpmaxp : default + * pipebuf : nothing to do + */ + + usbhsp_pipe_select(pipe); + usbhs_pipe_clear_sequence(pipe); + + return pipe; +} + +void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe) +{ + WARN_ON(!usbhsp_is_dcp(pipe)); + + usbhs_fifo_enable(pipe); + usbhsp_pipectrl_set(pipe, CCPL, CCPL); +} + + +/* + * pipe module function + */ +int usbhs_pipe_probe(struct usbhs_priv *priv) +{ + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + struct usbhs_pipe *pipe; + struct device *dev = usbhs_priv_to_dev(priv); + u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); + int pipe_size = usbhs_get_dparam(priv, pipe_size); + int i; + + /* This driver expects 1st pipe is DCP */ + if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) { + dev_err(dev, "1st PIPE is not DCP\n"); + return -EINVAL; + } + + info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL); + if (!info->pipe) { + dev_err(dev, "Could not allocate pipe\n"); + return -ENOMEM; + } + + info->size = pipe_size; + + /* + * init pipe + */ + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { + pipe->priv = priv; + usbhsp_type(pipe) = pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK; + + dev_dbg(dev, "pipe %x\t: %s\n", + i, usbhsp_pipe_name[pipe_type[i]]); + } + + return 0; +} + +void usbhs_pipe_remove(struct usbhs_priv *priv) +{ + struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); + + kfree(info->pipe); +} diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h new file mode 100644 index 000000000000..4a60dcef9676 --- /dev/null +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -0,0 +1,105 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 RENESAS_USB_PIPE_H +#define RENESAS_USB_PIPE_H + +#include "./common.h" + +/* + * struct + */ +struct usbhs_pipe { + u32 pipe_type; /* USB_ENDPOINT_XFER_xxx */ + + struct usbhs_priv *priv; + + u32 flags; +#define USBHS_PIPE_FLAGS_IS_USED (1 << 0) +#define USBHS_PIPE_FLAGS_IS_DIR_IN (1 << 1) + + void *mod_private; +}; + +struct usbhs_pipe_info { + struct usbhs_pipe *pipe; + int size; /* array size of "pipe" */ + int bufnmb_last; /* FIXME : driver needs good allocator */ +}; + +/* + * pipe list + */ +#define __usbhs_for_each_pipe(start, pos, info, i) \ + for (i = start, pos = (info)->pipe; \ + i < (info)->size; \ + i++, pos = (info)->pipe + i) + +#define usbhs_for_each_pipe(pos, priv, i) \ + __usbhs_for_each_pipe(1, pos, &((priv)->pipe_info), i) + +#define usbhs_for_each_pipe_with_dcp(pos, priv, i) \ + __usbhs_for_each_pipe(0, pos, &((priv)->pipe_info), i) + +/* + * pipe module probe / remove + */ +int usbhs_pipe_probe(struct usbhs_priv *priv); +void usbhs_pipe_remove(struct usbhs_priv *priv); + +/* + * cfifo + */ +int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len); +int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len); +int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe); +int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe); + +void usbhs_fifo_enable(struct usbhs_pipe *pipe); +void usbhs_fifo_disable(struct usbhs_pipe *pipe); +void usbhs_fifo_stall(struct usbhs_pipe *pipe); + +void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe); + + +/* + * usb request + */ +void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req); +void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req); + +/* + * pipe control + */ +struct usbhs_pipe +*usbhs_pipe_malloc(struct usbhs_priv *priv, + const struct usb_endpoint_descriptor *desc); + +int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); +void usbhs_pipe_init(struct usbhs_priv *priv); +int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); +void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); + +#define usbhs_pipe_number(p) (((u32)(p) - (u32)(p)->priv->pipe_info.pipe) / \ + sizeof(struct usbhs_pipe)) + +/* + * dcp control + */ +struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv); +void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe); + +#endif /* RENESAS_USB_PIPE_H */ diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h new file mode 100644 index 000000000000..565bca3aa440 --- /dev/null +++ b/include/linux/usb/renesas_usbhs.h @@ -0,0 +1,149 @@ +/* + * Renesas USB + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 RENESAS_USB_H +#define RENESAS_USB_H +#include +#include + +/* + * module type + * + * it will be return value from get_id + */ +enum { + USBHS_HOST = 0, + USBHS_GADGET, + USBHS_MAX, +}; + +/* + * callback functions table for driver + * + * These functions are called from platform for driver. + * Callback function's pointer will be set before + * renesas_usbhs_platform_callback :: hardware_init was called + */ +struct renesas_usbhs_driver_callback { + int (*notify_hotplug)(struct platform_device *pdev); +}; + +/* + * callback functions for platform + * + * These functions are called from driver for platform + */ +struct renesas_usbhs_platform_callback { + + /* + * option: + * + * Hardware init function for platform. + * it is called when driver was probed. + */ + int (*hardware_init)(struct platform_device *pdev); + + /* + * option: + * + * Hardware exit function for platform. + * it is called when driver was removed + */ + void (*hardware_exit)(struct platform_device *pdev); + + /* + * option: + * + * Phy reset for platform + */ + void (*phy_reset)(struct platform_device *pdev); + + /* + * get USB ID function + * - USBHS_HOST + * - USBHS_GADGET + */ + int (*get_id)(struct platform_device *pdev); + + /* + * get VBUS status function. + */ + int (*get_vbus)(struct platform_device *pdev); +}; + +/* + * parameters for renesas usbhs + * + * some register needs USB chip specific parameters. + * This struct show it to driver + */ +struct renesas_usbhs_driver_param { + /* + * pipe settings + */ + u32 *pipe_type; /* array of USB_ENDPOINT_XFER_xxx (from ep0) */ + int pipe_size; /* pipe_type array size */ + + /* + * option: + * + * for BUSWAIT :: BWAIT + * */ + int buswait_bwait; +}; + +/* + * option: + * + * platform information for renesas_usbhs driver. + */ +struct renesas_usbhs_platform_info { + /* + * option: + * + * platform set these functions before + * call platform_add_devices if needed + */ + struct renesas_usbhs_platform_callback platform_callback; + + /* + * driver set these callback functions pointer. + * platform can use it on callback functions + */ + struct renesas_usbhs_driver_callback driver_callback; + + /* + * option: + * + * driver use these param for some register + */ + struct renesas_usbhs_driver_param driver_param; +}; + +/* + * macro for platform + */ +#define renesas_usbhs_get_info(pdev)\ + ((struct renesas_usbhs_platform_info *)(pdev)->dev.platform_data) + +#define renesas_usbhs_call_notify_hotplug(pdev) \ + ({ \ + struct renesas_usbhs_driver_callback *dc; \ + dc = &(renesas_usbhs_get_info(pdev)->driver_callback); \ + if (dc) \ + dc->notify_hotplug(pdev); \ + }) +#endif /* RENESAS_USB_H */ -- GitLab From 2f98382dcdfe1f0048b447da35f34507ffb514dc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 5 Apr 2011 11:40:54 +0900 Subject: [PATCH 0874/5560] usb: renesas_usbhs: Add Renesas USBHS Gadget This patch add usb gadget code to SuperH USBHS. Signed-off-by: Kuninori Morimoto Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 18 + drivers/usb/gadget/gadget_chips.h | 9 + drivers/usb/renesas_usbhs/Makefile | 2 + drivers/usb/renesas_usbhs/mod.c | 17 +- drivers/usb/renesas_usbhs/mod.h | 16 + drivers/usb/renesas_usbhs/mod_gadget.c | 1341 ++++++++++++++++++++++++ 6 files changed, 1402 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/renesas_usbhs/mod_gadget.c diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bc5123cf41c2..4c02b9f1597e 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -260,6 +260,24 @@ config USB_R8A66597 default USB_GADGET select USB_GADGET_SELECTED +config USB_GADGET_RENESAS_USBHS + boolean "Renesas USBHS" + depends on USB_RENESAS_USBHS + select USB_GADGET_DUALSPEED + help + Renesas USBHS is a discrete USB host and peripheral controller + chip that supports both full and high speed USB 2.0 data transfers. + platform is able to configure endpoint (pipe) style + + Say "y" to enable the gadget specific portion of the USBHS driver. + + +config USB_RENESAS_USBHS_UDC + tristate + depends on USB_GADGET_RENESAS_USBHS + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_PXA27X boolean "PXA 27x" depends on ARCH_PXA && (PXA27x || PXA3xx) diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index e896f6359dfe..ec3fd979c71d 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -148,6 +148,12 @@ #define gadget_is_ci13xxx_msm(g) 0 #endif +#ifdef CONFIG_USB_GADGET_RENESAS_USBHS +#define gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name)) +#else +#define gadget_is_renesas_usbhs(g) 0 +#endif + /** * usb_gadget_controller_number - support bcdDevice id convention * @gadget: the controller being driven @@ -207,6 +213,9 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x27; else if (gadget_is_ci13xxx_msm(gadget)) return 0x28; + else if (gadget_is_renesas_usbhs(gadget)) + return 0x29; + return -ENOENT; } diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile index d76f3dd3b9d1..b8798ad16278 100644 --- a/drivers/usb/renesas_usbhs/Makefile +++ b/drivers/usb/renesas_usbhs/Makefile @@ -5,3 +5,5 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o renesas_usbhs-y := common.o mod.o pipe.o + +renesas_usbhs-$(CONFIG_USB_RENESAS_USBHS_UDC) += mod_gadget.o diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 4a3398484cd7..73604a1d6843 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -94,17 +94,32 @@ int usbhs_mod_probe(struct usbhs_priv *priv) struct device *dev = usbhs_priv_to_dev(priv); int ret; + /* + * install host/gadget driver + */ + ret = usbhs_mod_gadget_probe(priv); + if (ret < 0) + return ret; + /* irq settings */ ret = request_irq(priv->irq, usbhs_interrupt, IRQF_DISABLED, dev_name(dev), priv); - if (ret) + if (ret) { dev_err(dev, "irq request err\n"); + goto mod_init_gadget_err; + } + + return ret; + +mod_init_gadget_err: + usbhs_mod_gadget_remove(priv); return ret; } void usbhs_mod_remove(struct usbhs_priv *priv) { + usbhs_mod_gadget_remove(priv); free_irq(priv->irq, priv); } diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h index bd873d5b432a..8644191e164f 100644 --- a/drivers/usb/renesas_usbhs/mod.h +++ b/drivers/usb/renesas_usbhs/mod.h @@ -103,4 +103,20 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); mod->func(param); \ }) +/* + * gadget control + */ +#ifdef CONFIG_USB_RENESAS_USBHS_UDC +extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv); +extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv); +#else +static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) +{ + return 0; +} +static inline void usbhs_mod_gadget_remove(struct usbhs_priv *priv) +{ +} +#endif + #endif /* RENESAS_USB_MOD_H */ diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c new file mode 100644 index 000000000000..9a5ac02077b9 --- /dev/null +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -0,0 +1,1341 @@ +/* + * Renesas USB driver + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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 "common.h" + +/* + * struct + */ +struct usbhsg_request { + struct usb_request req; + struct list_head node; +}; + +#define EP_NAME_SIZE 8 +struct usbhsg_gpriv; +struct usbhsg_pipe_handle; +struct usbhsg_uep { + struct usb_ep ep; + struct usbhs_pipe *pipe; + struct list_head list; + + char ep_name[EP_NAME_SIZE]; + + struct usbhsg_gpriv *gpriv; + struct usbhsg_pipe_handle *handler; +}; + +struct usbhsg_gpriv { + struct usb_gadget gadget; + struct usbhs_mod mod; + + struct usbhsg_uep *uep; + int uep_size; + + struct usb_gadget_driver *driver; + + u32 status; +#define USBHSG_STATUS_STARTED (1 << 0) +#define USBHSG_STATUS_REGISTERD (1 << 1) +#define USBHSG_STATUS_WEDGE (1 << 2) +}; + +struct usbhsg_pipe_handle { + int (*prepare)(struct usbhsg_uep *uep, struct usbhsg_request *ureq); + int (*try_run)(struct usbhsg_uep *uep, struct usbhsg_request *ureq); + void (*irq_mask)(struct usbhsg_uep *uep, int enable); +}; + +struct usbhsg_recip_handle { + char *name; + int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, + struct usb_ctrlrequest *ctrl); + int (*interface)(struct usbhs_priv *priv, struct usbhsg_uep *uep, + struct usb_ctrlrequest *ctrl); + int (*endpoint)(struct usbhs_priv *priv, struct usbhsg_uep *uep, + struct usb_ctrlrequest *ctrl); +}; + +/* + * macro + */ +#define usbhsg_priv_to_gpriv(priv) \ + container_of( \ + usbhs_mod_get(priv, USBHS_GADGET), \ + struct usbhsg_gpriv, mod) + +#define __usbhsg_for_each_uep(start, pos, g, i) \ + for (i = start, pos = (g)->uep; \ + i < (g)->uep_size; \ + i++, pos = (g)->uep + i) + +#define usbhsg_for_each_uep(pos, gpriv, i) \ + __usbhsg_for_each_uep(1, pos, gpriv, i) + +#define usbhsg_for_each_uep_with_dcp(pos, gpriv, i) \ + __usbhsg_for_each_uep(0, pos, gpriv, i) + +#define usbhsg_gadget_to_gpriv(g)\ + container_of(g, struct usbhsg_gpriv, gadget) + +#define usbhsg_req_to_ureq(r)\ + container_of(r, struct usbhsg_request, req) + +#define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) +#define usbhsg_gpriv_to_lock(gp) usbhs_priv_to_lock((gp)->mod.priv) +#define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) +#define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) +#define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) +#define usbhsg_gpriv_to_nth_uep(gp, i) ((gp)->uep + i) +#define usbhsg_uep_to_gpriv(u) ((u)->gpriv) +#define usbhsg_uep_to_pipe(u) ((u)->pipe) +#define usbhsg_pipe_to_uep(p) ((p)->mod_private) +#define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) + +#define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) + +/* status */ +#define usbhsg_status_init(gp) do {(gp)->status = 0; } while (0) +#define usbhsg_status_set(gp, b) (gp->status |= b) +#define usbhsg_status_clr(gp, b) (gp->status &= ~b) +#define usbhsg_status_has(gp, b) (gp->status & b) + +/* + * list push/pop + */ +static void usbhsg_queue_push(struct usbhsg_uep *uep, + struct usbhsg_request *ureq) +{ + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + + /* + ********* assume under spin lock ********* + */ + list_del_init(&ureq->node); + list_add_tail(&ureq->node, &uep->list); + ureq->req.actual = 0; + ureq->req.status = -EINPROGRESS; + + dev_dbg(dev, "pipe %d : queue push (%d)\n", + usbhs_pipe_number(pipe), + ureq->req.length); +} + +static struct usbhsg_request *usbhsg_queue_get(struct usbhsg_uep *uep) +{ + /* + ********* assume under spin lock ********* + */ + if (list_empty(&uep->list)) + return NULL; + + return list_entry(uep->list.next, struct usbhsg_request, node); +} + +#define usbhsg_queue_prepare(uep) __usbhsg_queue_handler(uep, 1); +#define usbhsg_queue_handle(uep) __usbhsg_queue_handler(uep, 0); +static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) +{ + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + struct usbhsg_request *ureq; + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + int is_locked; + int ret = 0; + + if (!uep->handler) { + dev_err(dev, "no handler function\n"); + return -EIO; + } + + /* + * CAUTION [*queue handler*] + * + * This function will be called for start/restart queue operation. + * OTOH the most much worry for USB driver is spinlock nest. + * Specially it are + * - usb_ep_ops :: queue + * - usb_request :: complete + * + * But the caller of this function need not care about spinlock. + * This function is using spin_trylock_irqsave for it. + * if "is_locked" is 1, this mean this function lock it. + * but if it is 0, this mean it is already under spin lock. + * see also + * CAUTION [*endpoint queue*] + * CAUTION [*request complete*] + */ + + /****************** spin try lock *******************/ + is_locked = spin_trylock_irqsave(lock, flags); + ureq = usbhsg_queue_get(uep); + if (ureq) { + if (prepare) + ret = uep->handler->prepare(uep, ureq); + else + ret = uep->handler->try_run(uep, ureq); + } + if (is_locked) + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ******************/ + + return ret; +} + +static void usbhsg_queue_pop(struct usbhsg_uep *uep, + struct usbhsg_request *ureq, + int status) +{ + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + + /* + ********* assume under spin lock ********* + */ + + /* + * CAUTION [*request complete*] + * + * There is a possibility not to be called in correct order + * if "complete" is called without spinlock. + * + * So, this function assume it is under spinlock, + * and call usb_request :: complete. + * + * But this "complete" will push next usb_request. + * It mean "usb_ep_ops :: queue" which is using spinlock is called + * under spinlock. + * + * To avoid dead-lock, this driver is using spin_trylock. + * CAUTION [*endpoint queue*] + * CAUTION [*queue handler*] + */ + + dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); + + list_del_init(&ureq->node); + + ureq->req.status = status; + ureq->req.complete(&uep->ep, &ureq->req); + + /* more request ? */ + if (0 == status) + usbhsg_queue_prepare(uep); +} + +/* + * irq enable/disable function + */ +#define usbhsg_irq_callback_ctrl(uep, status, enable) \ + ({ \ + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); \ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); \ + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); \ + struct usbhs_mod *mod = usbhs_mod_get_current(priv); \ + if (!mod) \ + return; \ + if (enable) \ + mod->irq_##status |= (1 << usbhs_pipe_number(pipe)); \ + else \ + mod->irq_##status &= ~(1 << usbhs_pipe_number(pipe)); \ + usbhs_irq_callback_update(priv, mod); \ + }) + +static void usbhsg_irq_empty_ctrl(struct usbhsg_uep *uep, int enable) +{ + usbhsg_irq_callback_ctrl(uep, bempsts, enable); +} + +static void usbhsg_irq_ready_ctrl(struct usbhsg_uep *uep, int enable) +{ + usbhsg_irq_callback_ctrl(uep, brdysts, enable); +} + +/* + * handler function + */ +static int usbhsg_try_run_ctrl_stage_end(struct usbhsg_uep *uep, + struct usbhsg_request *ureq) +{ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + + /* + ********* assume under spin lock ********* + */ + + usbhs_dcp_control_transfer_done(pipe); + usbhsg_queue_pop(uep, ureq, 0); + + return 0; +} + +static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep, + struct usbhsg_request *ureq) +{ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + struct usb_request *req = &ureq->req; + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + void *buf; + int remainder, send; + int is_done = 0; + int enable; + int maxp; + + /* + ********* assume under spin lock ********* + */ + + maxp = usbhs_pipe_get_maxpacket(pipe); + buf = req->buf + req->actual; + remainder = req->length - req->actual; + + send = usbhs_fifo_write(pipe, buf, remainder); + + /* + * send < 0 : pipe busy + * send = 0 : send zero packet + * send > 0 : send data + * + * send <= max_packet + */ + if (send > 0) + req->actual += send; + + /* send all packet ? */ + if (send < remainder) + is_done = 0; /* there are remainder data */ + else if (send < maxp) + is_done = 1; /* short packet */ + else + is_done = !req->zero; /* send zero packet ? */ + + dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", + usbhs_pipe_number(pipe), + remainder, send, is_done, req->zero); + + /* + * enable interrupt and send again in irq handler + * if it still have remainder data which should be sent. + */ + enable = !is_done; + uep->handler->irq_mask(uep, enable); + + /* + * usbhs_fifo_enable execute + * - after callback_update, + * - before queue_pop / stage_end + */ + usbhs_fifo_enable(pipe); + + /* + * all data were sent ? + */ + if (is_done) { + /* it care below call in + "function mode" */ + if (usbhsg_is_dcp(uep)) + usbhs_dcp_control_transfer_done(pipe); + + usbhsg_queue_pop(uep, ureq, 0); + } + + return 0; +} + +static int usbhsg_prepare_send_packet(struct usbhsg_uep *uep, + struct usbhsg_request *ureq) +{ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + + /* + ********* assume under spin lock ********* + */ + + usbhs_fifo_prepare_write(pipe); + usbhsg_try_run_send_packet(uep, ureq); + + return 0; +} + +static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep, + struct usbhsg_request *ureq) +{ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + struct usb_request *req = &ureq->req; + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + void *buf; + int maxp; + int remainder, recv; + int is_done = 0; + + /* + ********* assume under spin lock ********* + */ + + maxp = usbhs_pipe_get_maxpacket(pipe); + buf = req->buf + req->actual; + remainder = req->length - req->actual; + + recv = usbhs_fifo_read(pipe, buf, remainder); + /* + * recv < 0 : pipe busy + * recv >= 0 : receive data + * + * recv <= max_packet + */ + if (recv < 0) + return -EBUSY; + + /* update parameters */ + req->actual += recv; + + if ((recv == remainder) || /* receive all data */ + (recv < maxp)) /* short packet */ + is_done = 1; + + dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n", + usbhs_pipe_number(pipe), + remainder, recv, is_done, req->zero); + + /* read all data ? */ + if (is_done) { + int disable = 0; + + uep->handler->irq_mask(uep, disable); + usbhs_fifo_disable(pipe); + usbhsg_queue_pop(uep, ureq, 0); + } + + return 0; +} + +static int usbhsg_prepare_receive_packet(struct usbhsg_uep *uep, + struct usbhsg_request *ureq) +{ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + int enable = 1; + int ret; + + /* + ********* assume under spin lock ********* + */ + + ret = usbhs_fifo_prepare_read(pipe); + if (ret < 0) + return ret; + + /* + * data will be read in interrupt handler + */ + uep->handler->irq_mask(uep, enable); + + return ret; +} + +static struct usbhsg_pipe_handle usbhsg_handler_send_by_empty = { + .prepare = usbhsg_prepare_send_packet, + .try_run = usbhsg_try_run_send_packet, + .irq_mask = usbhsg_irq_empty_ctrl, +}; + +static struct usbhsg_pipe_handle usbhsg_handler_send_by_ready = { + .prepare = usbhsg_prepare_send_packet, + .try_run = usbhsg_try_run_send_packet, + .irq_mask = usbhsg_irq_ready_ctrl, +}; + +static struct usbhsg_pipe_handle usbhsg_handler_recv_by_ready = { + .prepare = usbhsg_prepare_receive_packet, + .try_run = usbhsg_try_run_receive_packet, + .irq_mask = usbhsg_irq_ready_ctrl, +}; + +static struct usbhsg_pipe_handle usbhsg_handler_ctrl_stage_end = { + .prepare = usbhsg_try_run_ctrl_stage_end, + .try_run = usbhsg_try_run_ctrl_stage_end, +}; + +/* + * DCP pipe can NOT use "ready interrupt" for "send" + * it should use "empty" interrupt. + * see + * "Operation" - "Interrupt Function" - "BRDY Interrupt" + * + * on the other hand, normal pipe can use "ready interrupt" for "send" + * even though it is single/double buffer + */ +#define usbhsg_handler_send_ctrl usbhsg_handler_send_by_empty +#define usbhsg_handler_recv_ctrl usbhsg_handler_recv_by_ready + +#define usbhsg_handler_send_packet usbhsg_handler_send_by_ready +#define usbhsg_handler_recv_packet usbhsg_handler_recv_by_ready + +/* + * USB_TYPE_STANDARD / clear feature functions + */ +static int usbhsg_recip_handler_std_control_done(struct usbhs_priv *priv, + struct usbhsg_uep *uep, + struct usb_ctrlrequest *ctrl) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); + + usbhs_dcp_control_transfer_done(pipe); + + return 0; +} + +static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, + struct usbhsg_uep *uep, + struct usb_ctrlrequest *ctrl) +{ + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + + if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { + usbhs_fifo_disable(pipe); + usbhs_pipe_clear_sequence(pipe); + usbhs_fifo_enable(pipe); + } + + usbhsg_recip_handler_std_control_done(priv, uep, ctrl); + + usbhsg_queue_prepare(uep); + + return 0; +} + +struct usbhsg_recip_handle req_clear_feature = { + .name = "clear feature", + .device = usbhsg_recip_handler_std_control_done, + .interface = usbhsg_recip_handler_std_control_done, + .endpoint = usbhsg_recip_handler_std_clear_endpoint, +}; + +/* + * USB_TYPE handler + */ +static int usbhsg_recip_run_handle(struct usbhs_priv *priv, + struct usbhsg_recip_handle *handler, + struct usb_ctrlrequest *ctrl) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + struct usbhsg_uep *uep; + int recip = ctrl->bRequestType & USB_RECIP_MASK; + int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; + int ret; + int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, + struct usb_ctrlrequest *ctrl); + char *msg; + + uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); + + switch (recip) { + case USB_RECIP_DEVICE: + msg = "DEVICE"; + func = handler->device; + break; + case USB_RECIP_INTERFACE: + msg = "INTERFACE"; + func = handler->interface; + break; + case USB_RECIP_ENDPOINT: + msg = "ENDPOINT"; + func = handler->endpoint; + break; + default: + dev_warn(dev, "unsupported RECIP(%d)\n", recip); + func = NULL; + ret = -EINVAL; + } + + if (func) { + dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); + ret = func(priv, uep, ctrl); + } + + return ret; +} + +/* + * irq functions + * + * it will be called from usbhs_interrupt + */ +static int usbhsg_irq_dev_state(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + + gpriv->gadget.speed = usbhs_status_get_usb_speed(irq_state); + + dev_dbg(dev, "state = %x : speed : %d\n", + usbhs_status_get_device_state(irq_state), + gpriv->gadget.speed); + + return 0; +} + +static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + struct usb_ctrlrequest ctrl; + struct usbhsg_recip_handle *recip_handler = NULL; + int stage = usbhs_status_get_ctrl_stage(irq_state); + int ret = 0; + + dev_dbg(dev, "stage = %d\n", stage); + + /* + * see Manual + * + * "Operation" + * - "Interrupt Function" + * - "Control Transfer Stage Transition Interrupt" + * - Fig. "Control Transfer Stage Transitions" + */ + + switch (stage) { + case READ_DATA_STAGE: + dcp->handler = &usbhsg_handler_send_ctrl; + break; + case WRITE_DATA_STAGE: + dcp->handler = &usbhsg_handler_recv_ctrl; + break; + case NODATA_STATUS_STAGE: + dcp->handler = &usbhsg_handler_ctrl_stage_end; + break; + default: + return ret; + } + + /* + * get usb request + */ + usbhs_usbreq_get_val(priv, &ctrl); + + switch (ctrl.bRequestType & USB_TYPE_MASK) { + case USB_TYPE_STANDARD: + switch (ctrl.bRequest) { + case USB_REQ_CLEAR_FEATURE: + recip_handler = &req_clear_feature; + break; + } + } + + /* + * setup stage / run recip + */ + if (recip_handler) + ret = usbhsg_recip_run_handle(priv, recip_handler, &ctrl); + else + ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); + + if (ret < 0) + usbhs_fifo_stall(pipe); + + return ret; +} + +static int usbhsg_irq_empty(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct usbhsg_uep *uep; + struct usbhs_pipe *pipe; + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + int i, ret; + + if (!irq_state->bempsts) { + dev_err(dev, "debug %s !!\n", __func__); + return -EIO; + } + + dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts); + + /* + * search interrupted "pipe" + * not "uep". + */ + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { + if (!(irq_state->bempsts & (1 << i))) + continue; + + uep = usbhsg_pipe_to_uep(pipe); + ret = usbhsg_queue_handle(uep); + if (ret < 0) + dev_err(dev, "send error %d : %d\n", i, ret); + } + + return 0; +} + +static int usbhsg_irq_ready(struct usbhs_priv *priv, + struct usbhs_irq_state *irq_state) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct usbhsg_uep *uep; + struct usbhs_pipe *pipe; + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + int i, ret; + + if (!irq_state->brdysts) { + dev_err(dev, "debug %s !!\n", __func__); + return -EIO; + } + + dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts); + + /* + * search interrupted "pipe" + * not "uep". + */ + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { + if (!(irq_state->brdysts & (1 << i))) + continue; + + uep = usbhsg_pipe_to_uep(pipe); + ret = usbhsg_queue_handle(uep); + if (ret < 0) + dev_err(dev, "receive error %d : %d\n", i, ret); + } + + return 0; +} + +/* + * + * usb_dcp_ops + * + */ +static int usbhsg_dcp_enable(struct usbhsg_uep *uep) +{ + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); + struct usbhs_pipe *pipe; + + /* + ********* assume under spin lock ********* + */ + + pipe = usbhs_dcp_malloc(priv); + if (!pipe) + return -EIO; + + uep->pipe = pipe; + uep->pipe->mod_private = uep; + INIT_LIST_HEAD(&uep->list); + + return 0; +} + +#define usbhsg_dcp_disable usbhsg_pipe_disable +static int usbhsg_pipe_disable(struct usbhsg_uep *uep) +{ + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + struct usbhsg_request *ureq; + int disable = 0; + + /* + ********* assume under spin lock ********* + */ + + usbhs_fifo_disable(pipe); + + /* + * disable pipe irq + */ + usbhsg_irq_empty_ctrl(uep, disable); + usbhsg_irq_ready_ctrl(uep, disable); + + while (1) { + ureq = usbhsg_queue_get(uep); + if (!ureq) + break; + + usbhsg_queue_pop(uep, ureq, -ECONNRESET); + } + + uep->pipe->mod_private = NULL; + uep->pipe = NULL; + + return 0; +} + +/* + * + * usb_ep_ops + * + */ +static int usbhsg_ep_enable(struct usb_ep *ep, + const struct usb_endpoint_descriptor *desc) +{ + struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); + struct usbhs_pipe *pipe; + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + int ret = -EIO; + + /******************** spin lock ********************/ + spin_lock_irqsave(lock, flags); + + pipe = usbhs_pipe_malloc(priv, desc); + if (pipe) { + uep->pipe = pipe; + pipe->mod_private = uep; + INIT_LIST_HEAD(&uep->list); + + if (usb_endpoint_dir_in(desc)) + uep->handler = &usbhsg_handler_send_packet; + else + uep->handler = &usbhsg_handler_recv_packet; + + ret = 0; + } + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ******************/ + + return ret; +} + +static int usbhsg_ep_disable(struct usb_ep *ep) +{ + struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + int ret; + + /******************** spin lock ********************/ + spin_lock_irqsave(lock, flags); + ret = usbhsg_pipe_disable(uep); + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ******************/ + + return ret; +} + +static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, + gfp_t gfp_flags) +{ + struct usbhsg_request *ureq; + + ureq = kzalloc(sizeof *ureq, gfp_flags); + if (!ureq) + return NULL; + + INIT_LIST_HEAD(&ureq->node); + return &ureq->req; +} + +static void usbhsg_ep_free_request(struct usb_ep *ep, + struct usb_request *req) +{ + struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); + + WARN_ON(!list_empty(&ureq->node)); + kfree(ureq); +} + +static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, + gfp_t gfp_flags) +{ + struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + int ret = 0; + int is_locked; + + /* + * CAUTION [*endpoint queue*] + * + * This function will be called from usb_request :: complete + * or usb driver timing. + * If this function is called from usb_request :: complete, + * it is already under spinlock on this driver. + * but it is called frm usb driver, this function should call spinlock. + * + * This function is using spin_trylock_irqsave to solve this issue. + * if "is_locked" is 1, this mean this function lock it. + * but if it is 0, this mean it is already under spin lock. + * see also + * CAUTION [*queue handler*] + * CAUTION [*request complete*] + */ + + /******************** spin lock ********************/ + is_locked = spin_trylock_irqsave(lock, flags); + + /* param check */ + if (usbhsg_is_not_connected(gpriv) || + unlikely(!gpriv->driver) || + unlikely(!pipe)) + ret = -ESHUTDOWN; + else + usbhsg_queue_push(uep, ureq); + + if (is_locked) + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ******************/ + + usbhsg_queue_prepare(uep); + + return ret; +} + +static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) +{ + struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); + struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + int is_locked; + + /* + * see + * CAUTION [*queue handler*] + * CAUTION [*endpoint queue*] + * CAUTION [*request complete*] + */ + + /******************** spin lock ********************/ + is_locked = spin_trylock_irqsave(lock, flags); + + usbhsg_queue_pop(uep, ureq, -ECONNRESET); + + if (is_locked) + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ******************/ + + return 0; +} + +static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) +{ + struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); + struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); + struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + int ret = -EAGAIN; + int is_locked; + + /* + * see + * CAUTION [*queue handler*] + * CAUTION [*endpoint queue*] + * CAUTION [*request complete*] + */ + + /******************** spin lock ********************/ + is_locked = spin_trylock_irqsave(lock, flags); + if (!usbhsg_queue_get(uep)) { + + dev_dbg(dev, "set halt %d (pipe %d)\n", + halt, usbhs_pipe_number(pipe)); + + if (halt) + usbhs_fifo_stall(pipe); + else + usbhs_fifo_disable(pipe); + + if (halt && wedge) + usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); + else + usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); + + ret = 0; + } + + if (is_locked) + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ******************/ + + return ret; +} + +static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) +{ + return __usbhsg_ep_set_halt_wedge(ep, value, 0); +} + +static int usbhsg_ep_set_wedge(struct usb_ep *ep) +{ + return __usbhsg_ep_set_halt_wedge(ep, 1, 1); +} + +static struct usb_ep_ops usbhsg_ep_ops = { + .enable = usbhsg_ep_enable, + .disable = usbhsg_ep_disable, + + .alloc_request = usbhsg_ep_alloc_request, + .free_request = usbhsg_ep_free_request, + + .queue = usbhsg_ep_queue, + .dequeue = usbhsg_ep_dequeue, + + .set_halt = usbhsg_ep_set_halt, + .set_wedge = usbhsg_ep_set_wedge, +}; + +/* + * usb module start/end + */ +static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + struct device *dev = usbhs_priv_to_dev(priv); + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + + /******************** spin lock ********************/ + spin_lock_irqsave(lock, flags); + + /* + * enable interrupt and systems if ready + */ + usbhsg_status_set(gpriv, status); + if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && + usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) + goto usbhsg_try_start_unlock; + + dev_dbg(dev, "start gadget\n"); + + /* + * pipe initialize and enable DCP + */ + usbhs_pipe_init(priv); + usbhsg_dcp_enable(dcp); + + /* + * system config enble + * - HI speed + * - function + * - usb module + */ + usbhs_sys_hispeed_ctrl(priv, 1); + usbhs_sys_function_ctrl(priv, 1); + usbhs_sys_usb_ctrl(priv, 1); + + /* + * enable irq callback + */ + mod->irq_dev_state = usbhsg_irq_dev_state; + mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; + mod->irq_empty = usbhsg_irq_empty; + mod->irq_ready = usbhsg_irq_ready; + mod->irq_bempsts = 0; + mod->irq_brdysts = 0; + usbhs_irq_callback_update(priv, mod); + +usbhsg_try_start_unlock: + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ********************/ + + return 0; +} + +static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + struct usbhs_mod *mod = usbhs_mod_get_current(priv); + struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); + struct device *dev = usbhs_priv_to_dev(priv); + spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); + unsigned long flags; + + /******************** spin lock ********************/ + spin_lock_irqsave(lock, flags); + + /* + * disable interrupt and systems if 1st try + */ + usbhsg_status_clr(gpriv, status); + if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && + !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) + goto usbhsg_try_stop_unlock; + + /* disable all irq */ + mod->irq_dev_state = NULL; + mod->irq_ctrl_stage = NULL; + mod->irq_empty = NULL; + mod->irq_ready = NULL; + mod->irq_bempsts = 0; + mod->irq_brdysts = 0; + usbhs_irq_callback_update(priv, mod); + + usbhsg_dcp_disable(dcp); + + gpriv->gadget.speed = USB_SPEED_UNKNOWN; + + /* disable sys */ + usbhs_sys_hispeed_ctrl(priv, 0); + usbhs_sys_function_ctrl(priv, 0); + usbhs_sys_usb_ctrl(priv, 0); + + spin_unlock_irqrestore(lock, flags); + /******************** spin unlock ********************/ + + if (gpriv->driver && + gpriv->driver->disconnect) + gpriv->driver->disconnect(&gpriv->gadget); + + dev_dbg(dev, "stop gadget\n"); + + return 0; + +usbhsg_try_stop_unlock: + spin_unlock_irqrestore(lock, flags); + + return 0; +} + +/* + * + * linux usb function + * + */ +struct usbhsg_gpriv *the_controller; +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) +{ + struct usbhsg_gpriv *gpriv = the_controller; + struct usbhs_priv *priv; + struct device *dev; + int ret; + + if (!bind || + !driver || + !driver->setup || + driver->speed != USB_SPEED_HIGH) + return -EINVAL; + if (!gpriv) + return -ENODEV; + if (gpriv->driver) + return -EBUSY; + + dev = usbhsg_gpriv_to_dev(gpriv); + priv = usbhsg_gpriv_to_priv(gpriv); + + /* first hook up the driver ... */ + gpriv->driver = driver; + gpriv->gadget.dev.driver = &driver->driver; + + ret = device_add(&gpriv->gadget.dev); + if (ret) { + dev_err(dev, "device_add error %d\n", ret); + goto add_fail; + } + + ret = bind(&gpriv->gadget); + if (ret) { + dev_err(dev, "bind to driver %s error %d\n", + driver->driver.name, ret); + goto bind_fail; + } + + dev_dbg(dev, "bind %s\n", driver->driver.name); + + return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); + +bind_fail: + device_del(&gpriv->gadget.dev); +add_fail: + gpriv->driver = NULL; + gpriv->gadget.dev.driver = NULL; + + return ret; +} +EXPORT_SYMBOL(usb_gadget_probe_driver); + +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + struct usbhsg_gpriv *gpriv = the_controller; + struct usbhs_priv *priv; + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + + if (!gpriv) + return -ENODEV; + + if (!driver || + !driver->unbind || + driver != gpriv->driver) + return -EINVAL; + + dev = usbhsg_gpriv_to_dev(gpriv); + priv = usbhsg_gpriv_to_priv(gpriv); + + usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); + device_del(&gpriv->gadget.dev); + gpriv->driver = NULL; + + if (driver->disconnect) + driver->disconnect(&gpriv->gadget); + + driver->unbind(&gpriv->gadget); + dev_dbg(dev, "unbind %s\n", driver->driver.name); + + return 0; +} +EXPORT_SYMBOL(usb_gadget_unregister_driver); + +/* + * usb gadget ops + */ +static int usbhsg_get_frame(struct usb_gadget *gadget) +{ + struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); + + return usbhs_frame_get_num(priv); +} + +static struct usb_gadget_ops usbhsg_gadget_ops = { + .get_frame = usbhsg_get_frame, +}; + +static int usbhsg_start(struct usbhs_priv *priv) +{ + return usbhsg_try_start(priv, USBHSG_STATUS_STARTED); +} + +static int usbhsg_stop(struct usbhs_priv *priv) +{ + return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); +} + +int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) +{ + struct usbhsg_gpriv *gpriv; + struct usbhsg_uep *uep; + struct device *dev = usbhs_priv_to_dev(priv); + int pipe_size = usbhs_get_dparam(priv, pipe_size); + int i; + + gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); + if (!gpriv) { + dev_err(dev, "Could not allocate gadget priv\n"); + return -ENOMEM; + } + + uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); + if (!uep) { + dev_err(dev, "Could not allocate ep\n"); + goto usbhs_mod_gadget_probe_err_gpriv; + } + + /* + * CAUTION + * + * There is no guarantee that it is possible to access usb module here. + * Don't accesses to it. + * The accesse will be enable after "usbhsg_start" + */ + + /* + * register itself + */ + usbhs_mod_register(priv, &gpriv->mod, USBHS_GADGET); + + /* init gpriv */ + gpriv->mod.name = "gadget"; + gpriv->mod.start = usbhsg_start; + gpriv->mod.stop = usbhsg_stop; + gpriv->uep = uep; + gpriv->uep_size = pipe_size; + usbhsg_status_init(gpriv); + + /* + * init gadget + */ + device_initialize(&gpriv->gadget.dev); + dev_set_name(&gpriv->gadget.dev, "gadget"); + gpriv->gadget.dev.parent = dev; + gpriv->gadget.name = "renesas_usbhs_udc"; + gpriv->gadget.ops = &usbhsg_gadget_ops; + gpriv->gadget.is_dualspeed = 1; + + INIT_LIST_HEAD(&gpriv->gadget.ep_list); + + /* + * init usb_ep + */ + usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { + uep->gpriv = gpriv; + snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i); + + uep->ep.name = uep->ep_name; + uep->ep.ops = &usbhsg_ep_ops; + INIT_LIST_HEAD(&uep->ep.ep_list); + INIT_LIST_HEAD(&uep->list); + + /* init DCP */ + if (usbhsg_is_dcp(uep)) { + gpriv->gadget.ep0 = &uep->ep; + uep->ep.maxpacket = 64; + } + /* init normal pipe */ + else { + uep->ep.maxpacket = 512; + list_add_tail(&uep->ep.ep_list, &gpriv->gadget.ep_list); + } + } + + the_controller = gpriv; + + dev_info(dev, "gadget probed\n"); + + return 0; + +usbhs_mod_gadget_probe_err_gpriv: + kfree(gpriv); + + return -ENOMEM; +} + +void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) +{ + struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); + + kfree(gpriv); +} -- GitLab From bce1a702ed9bd9aa3549352b3134e110bf076586 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 20 Mar 2011 02:02:39 -0700 Subject: [PATCH 0875/5560] USB: change the way we initialize format strings Changing initialization from static const char *string = "blah"; to static const char string[] = "blah"; saves us one pointer per each string. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devices.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index a3d2e2399655..d382291d1b15 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -64,49 +64,49 @@ /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ #define ALLOW_SERIAL_NUMBER -static const char *format_topo = +static const char format_topo[] = /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */ "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n"; -static const char *format_string_manufacturer = +static const char format_string_manufacturer[] = /* S: Manufacturer=xxxx */ "S: Manufacturer=%.100s\n"; -static const char *format_string_product = +static const char format_string_product[] = /* S: Product=xxxx */ "S: Product=%.100s\n"; #ifdef ALLOW_SERIAL_NUMBER -static const char *format_string_serialnumber = +static const char format_string_serialnumber[] = /* S: SerialNumber=xxxx */ "S: SerialNumber=%.100s\n"; #endif -static const char *format_bandwidth = +static const char format_bandwidth[] = /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; -static const char *format_device1 = +static const char format_device1[] = /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; -static const char *format_device2 = +static const char format_device2[] = /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; -static const char *format_config = +static const char format_config[] = /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; -static const char *format_iad = +static const char format_iad[] = /* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */ "A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; -static const char *format_iface = +static const char format_iface[] = /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; -static const char *format_endpt = +static const char format_endpt[] = /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; -- GitLab From 59d7fec7c6908604862658a3679ac44c2c3eea44 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:12 +0100 Subject: [PATCH 0876/5560] USB: cdc-acm: add missing newlines to dev_dbg and dev_err Add missing newline to two dev_dbg and dev_err messages. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e057e5381465..849aa04e6093 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -341,7 +341,7 @@ static void acm_ctrl_irq(struct urb *urb) retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with " - "result %d", __func__, retval); + "result %d\n", __func__, retval); } /* data interface returns incoming bytes, or we got unthrottled */ @@ -355,7 +355,7 @@ static void acm_read_bulk(struct urb *urb) dbg("Entering acm_read_bulk with status %d", status); if (!ACM_READY(acm)) { - dev_dbg(&acm->data->dev, "Aborting, acm not ready"); + dev_dbg(&acm->data->dev, "Aborting, acm not ready\n"); return; } usb_mark_last_busy(acm->dev); @@ -1224,7 +1224,7 @@ static int acm_probe(struct usb_interface *intf, snd->urb = usb_alloc_urb(0, GFP_KERNEL); if (snd->urb == NULL) { dev_dbg(&intf->dev, - "out of memory (write urbs usb_alloc_urb)"); + "out of memory (write urbs usb_alloc_urb)\n"); goto alloc_fail8; } -- GitLab From 255ab56c5ae30165d506b837f6576944a02ecdf0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:13 +0100 Subject: [PATCH 0877/5560] USB: cdc-acm: use dev_err to report failed allocations Upgrade out-of-memory dev_dbg to dev_err. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 849aa04e6093..c9f8a837c5fa 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1143,7 +1143,7 @@ static int acm_probe(struct usb_interface *intf, acm = kzalloc(sizeof(struct acm), GFP_KERNEL); if (acm == NULL) { - dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); + dev_err(&intf->dev, "out of memory (acm kzalloc)\n"); goto alloc_fail; } @@ -1179,19 +1179,19 @@ static int acm_probe(struct usb_interface *intf, buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); if (!buf) { - dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); + dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); goto alloc_fail2; } acm->ctrl_buffer = buf; if (acm_write_buffers_alloc(acm) < 0) { - dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); + dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); goto alloc_fail4; } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) { - dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); + dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { @@ -1199,7 +1199,7 @@ static int acm_probe(struct usb_interface *intf, rcv->urb = usb_alloc_urb(0, GFP_KERNEL); if (rcv->urb == NULL) { - dev_dbg(&intf->dev, + dev_err(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); goto alloc_fail6; } @@ -1213,7 +1213,7 @@ static int acm_probe(struct usb_interface *intf, rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, &rb->dma); if (!rb->base) { - dev_dbg(&intf->dev, + dev_err(&intf->dev, "out of memory (read bufs usb_alloc_coherent)\n"); goto alloc_fail7; } @@ -1223,7 +1223,7 @@ static int acm_probe(struct usb_interface *intf, snd->urb = usb_alloc_urb(0, GFP_KERNEL); if (snd->urb == NULL) { - dev_dbg(&intf->dev, + dev_err(&intf->dev, "out of memory (write urbs usb_alloc_urb)\n"); goto alloc_fail8; } -- GitLab From 1d9846e505febb71255b098910ace741433312b7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:14 +0100 Subject: [PATCH 0878/5560] USB: cdc-acm: clean up dev_err and dev_dbg Clean up some dev_err and dev_dbg messages and make sure that the appropriate interface device is used for reporting consistently throughout. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index c9f8a837c5fa..612b9ff0fcf2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -340,8 +340,8 @@ static void acm_ctrl_irq(struct urb *urb) exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) - dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with " - "result %d\n", __func__, retval); + dev_err(&acm->control->dev, "%s - usb_submit_urb failed: %d\n", + __func__, retval); } /* data interface returns incoming bytes, or we got unthrottled */ @@ -355,13 +355,14 @@ static void acm_read_bulk(struct urb *urb) dbg("Entering acm_read_bulk with status %d", status); if (!ACM_READY(acm)) { - dev_dbg(&acm->data->dev, "Aborting, acm not ready\n"); + dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); return; } usb_mark_last_busy(acm->dev); if (status) - dev_dbg(&acm->data->dev, "bulk rx status %d\n", status); + dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", + __func__, status); buf = rcv->buffer; buf->size = urb->actual_length; @@ -511,7 +512,8 @@ static void acm_write_bulk(struct urb *urb) if (verbose || urb->status || (urb->actual_length != urb->transfer_buffer_length)) - dev_dbg(&acm->data->dev, "tx %d/%d bytes -- > %d\n", + dev_dbg(&acm->data->dev, "%s - len %d/%d, status %d\n", + __func__, urb->actual_length, urb->transfer_buffer_length, urb->status); @@ -530,7 +532,8 @@ static void acm_softint(struct work_struct *work) struct acm *acm = container_of(work, struct acm, work); struct tty_struct *tty; - dev_vdbg(&acm->data->dev, "tx work\n"); + dev_vdbg(&acm->data->dev, "%s\n", __func__); + if (!ACM_READY(acm)) return; tty = tty_port_tty_get(&acm->port); -- GitLab From a5cc7ef92f69a88a1984cc3e09f6c19656efeb2e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:15 +0100 Subject: [PATCH 0879/5560] USB: cdc-acm: replace dbg macros with dev_dbg Replace all remaining instances of dbg with dev_dbg. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 80 ++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 612b9ff0fcf2..fee7d8b94fe2 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -111,8 +111,9 @@ static int acm_ctrl_msg(struct acm *acm, int request, int value, request, USB_RT_ACM, value, acm->control->altsetting[0].desc.bInterfaceNumber, buf, len, 5000); - dbg("acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d", - request, value, len, retval); + dev_dbg(&acm->control->dev, + "%s - rq 0x%02x, val %#x, len %#x, result %d\n", + __func__, request, value, len, retval); return retval < 0 ? retval : 0; } @@ -192,7 +193,9 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) rc = usb_submit_urb(wb->urb, GFP_ATOMIC); if (rc < 0) { - dbg("usb_submit_urb(write bulk) failed: %d", rc); + dev_err(&acm->data->dev, + "%s - usb_submit_urb(write bulk) failed: %d\n", + __func__, rc); acm_write_done(acm, wb); } return rc; @@ -211,7 +214,8 @@ static int acm_write_start(struct acm *acm, int wbn) return -ENODEV; } - dbg("%s susp_count: %d", __func__, acm->susp_count); + dev_dbg(&acm->data->dev, "%s - susp_count %d\n", __func__, + acm->susp_count); usb_autopm_get_interface_async(acm->control); if (acm->susp_count) { if (!acm->delayed_wb) @@ -287,10 +291,14 @@ static void acm_ctrl_irq(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __func__, status); + dev_dbg(&acm->control->dev, + "%s - urb shutting down with status: %d\n", + __func__, status); return; default: - dbg("%s - nonzero urb status received: %d", __func__, status); + dev_dbg(&acm->control->dev, + "%s - nonzero urb status received: %d\n", + __func__, status); goto exit; } @@ -302,8 +310,8 @@ static void acm_ctrl_irq(struct urb *urb) data = (unsigned char *)(dr + 1); switch (dr->bNotificationType) { case USB_CDC_NOTIFY_NETWORK_CONNECTION: - dbg("%s network", dr->wValue ? - "connected to" : "disconnected from"); + dev_dbg(&acm->control->dev, "%s - network connection: %d\n", + __func__, dr->wValue); break; case USB_CDC_NOTIFY_SERIAL_STATE: @@ -313,7 +321,8 @@ static void acm_ctrl_irq(struct urb *urb) if (tty) { if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { - dbg("calling hangup"); + dev_dbg(&acm->control->dev, + "%s - calling hangup\n", __func__); tty_hangup(tty); } tty_kref_put(tty); @@ -321,7 +330,10 @@ static void acm_ctrl_irq(struct urb *urb) acm->ctrlin = newctrl; - dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c", + dev_dbg(&acm->control->dev, + "%s - input control lines: dcd%c dsr%c break%c " + "ring%c framing%c parity%c overrun%c\n", + __func__, acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-', acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', @@ -332,7 +344,10 @@ static void acm_ctrl_irq(struct urb *urb) break; default: - dbg("unknown notification %d received: index %d len %d data0 %d data1 %d", + dev_dbg(&acm->control->dev, + "%s - unknown notification %d received: index %d " + "len %d data0 %d data1 %d\n", + __func__, dr->bNotificationType, dr->wIndex, dr->wLength, data[0], data[1]); break; @@ -352,7 +367,7 @@ static void acm_read_bulk(struct urb *urb) struct acm *acm = rcv->instance; int status = urb->status; - dbg("Entering acm_read_bulk with status %d", status); + dev_dbg(&acm->data->dev, "%s - status %d\n", __func__, status); if (!ACM_READY(acm)) { dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); @@ -395,10 +410,10 @@ static void acm_rx_tasklet(unsigned long _acm) unsigned long flags; unsigned char throttled; - dbg("Entering acm_rx_tasklet"); + dev_dbg(&acm->data->dev, "%s\n", __func__); if (!ACM_READY(acm)) { - dbg("acm_rx_tasklet: ACM not ready"); + dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); return; } @@ -406,7 +421,7 @@ static void acm_rx_tasklet(unsigned long _acm) throttled = acm->throttle; spin_unlock_irqrestore(&acm->throttle_lock, flags); if (throttled) { - dbg("acm_rx_tasklet: throttled"); + dev_dbg(&acm->data->dev, "%s - throttled\n", __func__); return; } @@ -423,8 +438,8 @@ static void acm_rx_tasklet(unsigned long _acm) list_del(&buf->list); spin_unlock_irqrestore(&acm->read_lock, flags); - dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); - + dev_dbg(&acm->data->dev, "%s - processing buf 0x%p, size = %d\n", + __func__, buf, buf->size); if (tty) { spin_lock_irqsave(&acm->throttle_lock, flags); throttled = acm->throttle; @@ -434,7 +449,8 @@ static void acm_rx_tasklet(unsigned long _acm) tty_flip_buffer_push(tty); } else { tty_kref_put(tty); - dbg("Throttling noticed"); + dev_dbg(&acm->data->dev, "%s - throttling noticed\n", + __func__); spin_lock_irqsave(&acm->read_lock, flags); list_add(&buf->list, &acm->filled_read_bufs); spin_unlock_irqrestore(&acm->read_lock, flags); @@ -495,7 +511,9 @@ static void acm_rx_tasklet(unsigned long _acm) return; } else { spin_unlock_irqrestore(&acm->read_lock, flags); - dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf); + dev_dbg(&acm->data->dev, + "%s - sending urb 0x%p, rcv 0x%p, buf 0x%p\n", + __func__, rcv->urb, rcv, buf); } } spin_lock_irqsave(&acm->read_lock, flags); @@ -552,7 +570,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) struct acm *acm; int rv = -ENODEV; int i; - dbg("Entering acm_tty_open."); mutex_lock(&open_mutex); @@ -562,6 +579,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) else rv = 0; + dev_dbg(&acm->control->dev, "%s\n", __func__); + set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); tty->driver_data = acm; @@ -581,7 +600,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) acm->ctrlurb->dev = acm->dev; if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { - dbg("usb_submit_urb(ctrl irq) failed"); + dev_err(&acm->control->dev, + "%s - usb_submit_urb(ctrl irq) failed\n", __func__); goto bail_out; } @@ -701,13 +721,13 @@ static int acm_tty_write(struct tty_struct *tty, int wbn; struct acm_wb *wb; - dbg("Entering acm_tty_write to write %d bytes,", count); - if (!ACM_READY(acm)) return -EINVAL; if (!count) return 0; + dev_dbg(&acm->data->dev, "%s - count %d\n", __func__, count); + spin_lock_irqsave(&acm->write_lock, flags); wbn = acm_wb_alloc(acm); if (wbn < 0) { @@ -717,7 +737,7 @@ static int acm_tty_write(struct tty_struct *tty, wb = &acm->wb[wbn]; count = (count > acm->writesize) ? acm->writesize : count; - dbg("Get %d bytes...", count); + dev_dbg(&acm->data->dev, "%s - write %d\n", __func__, count); memcpy(wb->buf, buf, count); wb->len = count; spin_unlock_irqrestore(&acm->write_lock, flags); @@ -780,7 +800,8 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) return -EINVAL; retval = acm_send_break(acm, state ? 0xffff : 0); if (retval < 0) - dbg("send break failed"); + dev_dbg(&acm->control->dev, "%s - send break failed\n", + __func__); return retval; } @@ -875,7 +896,9 @@ static void acm_tty_set_termios(struct tty_struct *tty, if (memcmp(&acm->line, &newline, sizeof newline)) { memcpy(&acm->line, &newline, sizeof newline); - dbg("set line: %d %d %d %d", le32_to_cpu(newline.dwDTERate), + dev_dbg(&acm->control->dev, "%s - set line: %d %d %d %d\n", + __func__, + le32_to_cpu(newline.dwDTERate), newline.bCharFormat, newline.bParityType, newline.bDataBits); acm_set_line(acm, &acm->line); @@ -1136,7 +1159,7 @@ static int acm_probe(struct usb_interface *intf, epwrite = t; } made_compressed_probe: - dbg("interfaces are valid"); + dev_dbg(&intf->dev, "interfaces are valid\n"); for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); if (minor == ACM_TTY_MINORS) { @@ -1321,7 +1344,8 @@ static int acm_probe(struct usb_interface *intf, static void stop_data_traffic(struct acm *acm) { int i; - dbg("Entering stop_data_traffic"); + + dev_dbg(&acm->control->dev, "%s\n", __func__); tasklet_disable(&acm->urb_task); -- GitLab From 4fa4626cd43679dc62a73ee3e347665e761abc9c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:16 +0100 Subject: [PATCH 0880/5560] USB: cdc-acm: clean up verbose debug Clean up use of verbose debug. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index fee7d8b94fe2..44a5291c5699 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -94,12 +94,6 @@ static DEFINE_MUTEX(open_mutex); static const struct tty_port_operations acm_port_ops = { }; -#ifdef VERBOSE_DEBUG -#define verbose 1 -#else -#define verbose 0 -#endif - /* * Functions for ACM control messages. */ @@ -528,9 +522,8 @@ static void acm_write_bulk(struct urb *urb) struct acm *acm = wb->instance; unsigned long flags; - if (verbose || urb->status - || (urb->actual_length != urb->transfer_buffer_length)) - dev_dbg(&acm->data->dev, "%s - len %d/%d, status %d\n", + if (urb->status || (urb->actual_length != urb->transfer_buffer_length)) + dev_vdbg(&acm->data->dev, "%s - len %d/%d, status %d\n", __func__, urb->actual_length, urb->transfer_buffer_length, -- GitLab From 5e9e75f8bd97864d552ec2b8d1a00e2b3012a6b3 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:17 +0100 Subject: [PATCH 0881/5560] USB: cdc-acm: use dev_vdbg in read/write paths Replace dev_dbg with verbose dev_vdbg in read/write paths where appropriate. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 44a5291c5699..3c0d4b913a89 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -208,7 +208,7 @@ static int acm_write_start(struct acm *acm, int wbn) return -ENODEV; } - dev_dbg(&acm->data->dev, "%s - susp_count %d\n", __func__, + dev_vdbg(&acm->data->dev, "%s - susp_count %d\n", __func__, acm->susp_count); usb_autopm_get_interface_async(acm->control); if (acm->susp_count) { @@ -361,7 +361,7 @@ static void acm_read_bulk(struct urb *urb) struct acm *acm = rcv->instance; int status = urb->status; - dev_dbg(&acm->data->dev, "%s - status %d\n", __func__, status); + dev_vdbg(&acm->data->dev, "%s - status %d\n", __func__, status); if (!ACM_READY(acm)) { dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); @@ -404,7 +404,7 @@ static void acm_rx_tasklet(unsigned long _acm) unsigned long flags; unsigned char throttled; - dev_dbg(&acm->data->dev, "%s\n", __func__); + dev_vdbg(&acm->data->dev, "%s\n", __func__); if (!ACM_READY(acm)) { dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); @@ -432,7 +432,7 @@ static void acm_rx_tasklet(unsigned long _acm) list_del(&buf->list); spin_unlock_irqrestore(&acm->read_lock, flags); - dev_dbg(&acm->data->dev, "%s - processing buf 0x%p, size = %d\n", + dev_vdbg(&acm->data->dev, "%s - processing buf 0x%p, size = %d\n", __func__, buf, buf->size); if (tty) { spin_lock_irqsave(&acm->throttle_lock, flags); @@ -505,7 +505,7 @@ static void acm_rx_tasklet(unsigned long _acm) return; } else { spin_unlock_irqrestore(&acm->read_lock, flags); - dev_dbg(&acm->data->dev, + dev_vdbg(&acm->data->dev, "%s - sending urb 0x%p, rcv 0x%p, buf 0x%p\n", __func__, rcv->urb, rcv, buf); } @@ -719,7 +719,7 @@ static int acm_tty_write(struct tty_struct *tty, if (!count) return 0; - dev_dbg(&acm->data->dev, "%s - count %d\n", __func__, count); + dev_vdbg(&acm->data->dev, "%s - count %d\n", __func__, count); spin_lock_irqsave(&acm->write_lock, flags); wbn = acm_wb_alloc(acm); @@ -730,7 +730,7 @@ static int acm_tty_write(struct tty_struct *tty, wb = &acm->wb[wbn]; count = (count > acm->writesize) ? acm->writesize : count; - dev_dbg(&acm->data->dev, "%s - write %d\n", __func__, count); + dev_vdbg(&acm->data->dev, "%s - write %d\n", __func__, count); memcpy(wb->buf, buf, count); wb->len = count; spin_unlock_irqrestore(&acm->write_lock, flags); -- GitLab From a2c7b9353e8f782590852052fe2948692020147e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:18 +0100 Subject: [PATCH 0882/5560] USB: cdc-acm: remove version information and changelog Remove driver version and changelog which can be retrieved from git history. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 3c0d4b913a89..a693381ed3cc 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -12,30 +12,6 @@ * * Sponsored by SuSE * - * ChangeLog: - * v0.9 - thorough cleaning, URBification, almost a rewrite - * v0.10 - some more cleanups - * v0.11 - fixed flow control, read error doesn't stop reads - * v0.12 - added TIOCM ioctls, added break handling, made struct acm - * kmalloced - * v0.13 - added termios, added hangup - * v0.14 - sized down struct acm - * v0.15 - fixed flow control again - characters could be lost - * v0.16 - added code for modems with swapped data and control interfaces - * v0.17 - added new style probing - * v0.18 - fixed new style probing for devices with more configurations - * v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan) - * v0.20 - switched to probing on interface (rather than device) class - * v0.21 - revert to probing on device for devices with multiple configs - * v0.22 - probe only the control interface. if usbcore doesn't choose the - * config we want, sysadmin changes bConfigurationValue in sysfs. - * v0.23 - use softirq for rx processing, as needed by tty layer - * v0.24 - change probe method to evaluate CDC union descriptor - * v0.25 - downstream tasks paralelized to maximize throughput - * v0.26 - multiple write urbs, writesize increased - */ - -/* * 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 @@ -76,10 +52,7 @@ #define ACM_CLOSE_TIMEOUT 15 /* seconds to let writes drain */ -/* - * Version Information - */ -#define DRIVER_VERSION "v0.26" + #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" @@ -1736,8 +1709,7 @@ static int __init acm_init(void) return retval; } - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); return 0; } -- GitLab From 3a42610812c55e8a60e2660e01c6cb6eb01d4171 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:19 +0100 Subject: [PATCH 0883/5560] USB: cdc-acm: remove superfluous prototype Remove unnecessary acm_tty_chars_in_buffer prototype. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index a693381ed3cc..b84ccec8fc7b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -626,8 +626,6 @@ static void acm_tty_unregister(struct acm *acm) kfree(acm); } -static int acm_tty_chars_in_buffer(struct tty_struct *tty); - static void acm_port_down(struct acm *acm) { int i, nr = acm->rx_buflimit; -- GitLab From 6fb6b8846458afb7b5689f86cf35705c40eb70e5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:20 +0100 Subject: [PATCH 0884/5560] USB: cdc-acm: remove unused drain-delay code The drain-delay code is no longer used, so remove it. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 6 ------ drivers/usb/class/cdc-acm.h | 1 - 2 files changed, 7 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index b84ccec8fc7b..e0f9febee7e6 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -50,9 +50,6 @@ #include "cdc-acm.h" -#define ACM_CLOSE_TIMEOUT 15 /* seconds to let writes drain */ - - #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" @@ -507,8 +504,6 @@ static void acm_write_bulk(struct urb *urb) spin_unlock_irqrestore(&acm->write_lock, flags); if (ACM_READY(acm)) schedule_work(&acm->work); - else - wake_up_interruptible(&acm->drain_wait); } static void acm_softint(struct work_struct *work) @@ -1155,7 +1150,6 @@ static int acm_probe(struct usb_interface *intf, acm->urb_task.func = acm_rx_tasklet; acm->urb_task.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint); - init_waitqueue_head(&acm->drain_wait); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index b4ea54dbf323..7282d1f4912b 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -112,7 +112,6 @@ struct acm { struct mutex mutex; struct usb_cdc_line_coding line; /* bits, stop, parity */ struct work_struct work; /* work queue entry for line discipline waking up */ - wait_queue_head_t drain_wait; /* close processing */ struct tasklet_struct urb_task; /* rx processing */ spinlock_t throttle_lock; /* synchronize throtteling and read callback */ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ -- GitLab From dab54c9f1e26f47a3313300bc1f4dc0eecb47375 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:21 +0100 Subject: [PATCH 0885/5560] USB: cdc-acm: clean up rx_buflimit references Clean up references to rx_buflimit. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e0f9febee7e6..2d8d6b838235 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -606,16 +606,15 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) static void acm_tty_unregister(struct acm *acm) { - int i, nr; + int i; - nr = acm->rx_buflimit; tty_unregister_device(acm_tty_driver, acm->minor); usb_put_intf(acm->control); acm_table[acm->minor] = NULL; usb_free_urb(acm->ctrlurb); for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); - for (i = 0; i < nr; i++) + for (i = 0; i < acm->rx_buflimit; i++) usb_free_urb(acm->ru[i].urb); kfree(acm->country_codes); kfree(acm); @@ -623,7 +622,8 @@ static void acm_tty_unregister(struct acm *acm) static void acm_port_down(struct acm *acm) { - int i, nr = acm->rx_buflimit; + int i; + mutex_lock(&open_mutex); if (acm->dev) { usb_autopm_get_interface(acm->control); @@ -632,7 +632,7 @@ static void acm_port_down(struct acm *acm) for (i = 0; i < ACM_NW; i++) usb_kill_urb(acm->wb[i].urb); tasklet_disable(&acm->urb_task); - for (i = 0; i < nr; i++) + for (i = 0; i < acm->rx_buflimit; i++) usb_kill_urb(acm->ru[i].urb); tasklet_enable(&acm->urb_task); acm->control->needs_remote_wakeup = 0; @@ -882,9 +882,9 @@ static void acm_write_buffers_free(struct acm *acm) static void acm_read_buffers_free(struct acm *acm) { struct usb_device *usb_dev = interface_to_usbdev(acm->control); - int i, n = acm->rx_buflimit; + int i; - for (i = 0; i < n; i++) + for (i = 0; i < acm->rx_buflimit; i++) usb_free_coherent(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); } -- GitLab From 94d4c8919de3ae9e2e029ed121adfed43803bb5d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:22 +0100 Subject: [PATCH 0886/5560] USB: cdc-acm: clean up open error handling No need to kill ctrl urb on errors as this is done later during close. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 2d8d6b838235..f239e3bd6423 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -568,7 +568,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && (acm->ctrl_caps & USB_CDC_CAP_LINE)) - goto full_bailout; + goto bail_out; usb_autopm_put_interface(acm->control); @@ -592,8 +592,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) mutex_unlock(&open_mutex); return rv; -full_bailout: - usb_kill_urb(acm->ctrlurb); bail_out: acm->port.count--; mutex_unlock(&acm->mutex); -- GitLab From 74f5e1babde76149c2bb35ca5dbf4d0b9b38f161 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Mar 2011 11:12:23 +0100 Subject: [PATCH 0887/5560] USB: cdc-acm: clean up read urb allocation Allocate read urbs and read buffers in the same loop during probe. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f239e3bd6423..519c7b933508 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1177,8 +1177,17 @@ static int acm_probe(struct usb_interface *intf, goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { + struct acm_rb *rb = &(acm->rb[i]); struct acm_ru *rcv = &(acm->ru[i]); + rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, + &rb->dma); + if (!rb->base) { + dev_err(&intf->dev, "out of memory " + "(read bufs usb_alloc_coherent)\n"); + goto alloc_fail6; + } + rcv->urb = usb_alloc_urb(0, GFP_KERNEL); if (rcv->urb == NULL) { dev_err(&intf->dev, @@ -1189,17 +1198,6 @@ static int acm_probe(struct usb_interface *intf, rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; rcv->instance = acm; } - for (i = 0; i < num_rx_buf; i++) { - struct acm_rb *rb = &(acm->rb[i]); - - rb->base = usb_alloc_coherent(acm->dev, readsize, - GFP_KERNEL, &rb->dma); - if (!rb->base) { - dev_err(&intf->dev, - "out of memory (read bufs usb_alloc_coherent)\n"); - goto alloc_fail7; - } - } for (i = 0; i < ACM_NW; i++) { struct acm_wb *snd = &(acm->wb[i]); @@ -1207,7 +1205,7 @@ static int acm_probe(struct usb_interface *intf, if (snd->urb == NULL) { dev_err(&intf->dev, "out of memory (write urbs usb_alloc_urb)\n"); - goto alloc_fail8; + goto alloc_fail7; } if (usb_endpoint_xfer_int(epwrite)) @@ -1226,7 +1224,7 @@ static int acm_probe(struct usb_interface *intf, i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); if (i < 0) - goto alloc_fail8; + goto alloc_fail7; if (cfd) { /* export the country data */ acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); @@ -1278,14 +1276,13 @@ static int acm_probe(struct usb_interface *intf, acm_table[minor] = acm; return 0; -alloc_fail8: +alloc_fail7: for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); -alloc_fail7: - acm_read_buffers_free(acm); alloc_fail6: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->ru[i].urb); + acm_read_buffers_free(acm); usb_free_urb(acm->ctrlurb); alloc_fail5: acm_write_buffers_free(acm); -- GitLab From 088c64f812847b3623b03d167ed329f90f3e38a4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 25 Mar 2011 11:06:02 +0100 Subject: [PATCH 0888/5560] USB: cdc-acm: re-write read processing Kill rx tasklet, which is no longer needed, and re-write read processing. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 295 ++++++++++++++---------------------- drivers/usb/class/cdc-acm.h | 22 +-- 2 files changed, 120 insertions(+), 197 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 519c7b933508..58754b508a0f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -7,6 +7,7 @@ * Copyright (c) 2000 Vojtech Pavlik * Copyright (c) 2004 Oliver Neukum * Copyright (c) 2005 David Kubicek + * Copyright (c) 2011 Johan Hovold * * USB Abstract Control Model driver for USB modems and ISDN adapters * @@ -50,7 +51,7 @@ #include "cdc-acm.h" -#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" +#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek, Johan Hovold" #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" static struct usb_driver acm_driver; @@ -323,166 +324,92 @@ static void acm_ctrl_irq(struct urb *urb) __func__, retval); } -/* data interface returns incoming bytes, or we got unthrottled */ -static void acm_read_bulk(struct urb *urb) +static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags) { - struct acm_rb *buf; - struct acm_ru *rcv = urb->context; - struct acm *acm = rcv->instance; - int status = urb->status; + int res; - dev_vdbg(&acm->data->dev, "%s - status %d\n", __func__, status); + if (!test_and_clear_bit(index, &acm->read_urbs_free)) + return 0; - if (!ACM_READY(acm)) { - dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); - return; + dev_vdbg(&acm->data->dev, "%s - urb %d\n", __func__, index); + + res = usb_submit_urb(acm->read_urbs[index], mem_flags); + if (res) { + if (res != -EPERM) { + dev_err(&acm->data->dev, + "%s - usb_submit_urb failed: %d\n", + __func__, res); + } + set_bit(index, &acm->read_urbs_free); + return res; } - usb_mark_last_busy(acm->dev); - if (status) - dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", - __func__, status); + return 0; +} - buf = rcv->buffer; - buf->size = urb->actual_length; +static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) +{ + int res; + int i; - if (likely(status == 0)) { - spin_lock(&acm->read_lock); - acm->processing++; - list_add_tail(&rcv->list, &acm->spare_read_urbs); - list_add_tail(&buf->list, &acm->filled_read_bufs); - spin_unlock(&acm->read_lock); - } else { - /* we drop the buffer due to an error */ - spin_lock(&acm->read_lock); - list_add_tail(&rcv->list, &acm->spare_read_urbs); - list_add(&buf->list, &acm->spare_read_bufs); - spin_unlock(&acm->read_lock); - /* nevertheless the tasklet must be kicked unconditionally - so the queue cannot dry up */ + for (i = 0; i < acm->rx_buflimit; ++i) { + res = acm_submit_read_urb(acm, i, mem_flags); + if (res) + return res; } - if (likely(!acm->susp_count)) - tasklet_schedule(&acm->urb_task); + + return 0; } -static void acm_rx_tasklet(unsigned long _acm) +static void acm_process_read_urb(struct acm *acm, struct urb *urb) { - struct acm *acm = (void *)_acm; - struct acm_rb *buf; struct tty_struct *tty; - struct acm_ru *rcv; - unsigned long flags; - unsigned char throttled; - - dev_vdbg(&acm->data->dev, "%s\n", __func__); - if (!ACM_READY(acm)) { - dev_dbg(&acm->data->dev, "%s - acm not ready\n", __func__); + if (!urb->actual_length) return; - } - - spin_lock_irqsave(&acm->throttle_lock, flags); - throttled = acm->throttle; - spin_unlock_irqrestore(&acm->throttle_lock, flags); - if (throttled) { - dev_dbg(&acm->data->dev, "%s - throttled\n", __func__); - return; - } tty = tty_port_tty_get(&acm->port); + if (!tty) + return; -next_buffer: - spin_lock_irqsave(&acm->read_lock, flags); - if (list_empty(&acm->filled_read_bufs)) { - spin_unlock_irqrestore(&acm->read_lock, flags); - goto urbs; - } - buf = list_entry(acm->filled_read_bufs.next, - struct acm_rb, list); - list_del(&buf->list); - spin_unlock_irqrestore(&acm->read_lock, flags); - - dev_vdbg(&acm->data->dev, "%s - processing buf 0x%p, size = %d\n", - __func__, buf, buf->size); - if (tty) { - spin_lock_irqsave(&acm->throttle_lock, flags); - throttled = acm->throttle; - spin_unlock_irqrestore(&acm->throttle_lock, flags); - if (!throttled) { - tty_insert_flip_string(tty, buf->base, buf->size); - tty_flip_buffer_push(tty); - } else { - tty_kref_put(tty); - dev_dbg(&acm->data->dev, "%s - throttling noticed\n", - __func__); - spin_lock_irqsave(&acm->read_lock, flags); - list_add(&buf->list, &acm->filled_read_bufs); - spin_unlock_irqrestore(&acm->read_lock, flags); - return; - } - } - - spin_lock_irqsave(&acm->read_lock, flags); - list_add(&buf->list, &acm->spare_read_bufs); - spin_unlock_irqrestore(&acm->read_lock, flags); - goto next_buffer; + tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); + tty_flip_buffer_push(tty); -urbs: tty_kref_put(tty); +} - while (!list_empty(&acm->spare_read_bufs)) { - spin_lock_irqsave(&acm->read_lock, flags); - if (list_empty(&acm->spare_read_urbs)) { - acm->processing = 0; - spin_unlock_irqrestore(&acm->read_lock, flags); - return; - } - rcv = list_entry(acm->spare_read_urbs.next, - struct acm_ru, list); - list_del(&rcv->list); - spin_unlock_irqrestore(&acm->read_lock, flags); +static void acm_read_bulk_callback(struct urb *urb) +{ + struct acm_rb *rb = urb->context; + struct acm *acm = rb->instance; + unsigned long flags; - buf = list_entry(acm->spare_read_bufs.next, - struct acm_rb, list); - list_del(&buf->list); + dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__, + rb->index, urb->actual_length); + set_bit(rb->index, &acm->read_urbs_free); - rcv->buffer = buf; + if (!acm->dev) { + dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__); + return; + } + usb_mark_last_busy(acm->dev); - if (acm->is_int_ep) - usb_fill_int_urb(rcv->urb, acm->dev, - acm->rx_endpoint, - buf->base, - acm->readsize, - acm_read_bulk, rcv, acm->bInterval); - else - usb_fill_bulk_urb(rcv->urb, acm->dev, - acm->rx_endpoint, - buf->base, - acm->readsize, - acm_read_bulk, rcv); - rcv->urb->transfer_dma = buf->dma; - rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - /* This shouldn't kill the driver as unsuccessful URBs are - returned to the free-urbs-pool and resubmited ASAP */ - spin_lock_irqsave(&acm->read_lock, flags); - if (acm->susp_count || - usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { - list_add(&buf->list, &acm->spare_read_bufs); - list_add(&rcv->list, &acm->spare_read_urbs); - acm->processing = 0; - spin_unlock_irqrestore(&acm->read_lock, flags); - return; - } else { - spin_unlock_irqrestore(&acm->read_lock, flags); - dev_vdbg(&acm->data->dev, - "%s - sending urb 0x%p, rcv 0x%p, buf 0x%p\n", - __func__, rcv->urb, rcv, buf); - } + if (urb->status) { + dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n", + __func__, urb->status); + return; } + acm_process_read_urb(acm, urb); + + /* throttle device if requested by tty */ spin_lock_irqsave(&acm->read_lock, flags); - acm->processing = 0; - spin_unlock_irqrestore(&acm->read_lock, flags); + acm->throttled = acm->throttle_req; + if (!acm->throttled && !acm->susp_count) { + spin_unlock_irqrestore(&acm->read_lock, flags); + acm_submit_read_urb(acm, rb->index, GFP_ATOMIC); + } else { + spin_unlock_irqrestore(&acm->read_lock, flags); + } } /* data interface wrote those outgoing bytes */ @@ -530,7 +457,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) { struct acm *acm; int rv = -ENODEV; - int i; mutex_lock(&open_mutex); @@ -572,20 +498,11 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) usb_autopm_put_interface(acm->control); - INIT_LIST_HEAD(&acm->spare_read_urbs); - INIT_LIST_HEAD(&acm->spare_read_bufs); - INIT_LIST_HEAD(&acm->filled_read_bufs); - - for (i = 0; i < acm->rx_buflimit; i++) - list_add(&(acm->ru[i].list), &acm->spare_read_urbs); - for (i = 0; i < acm->rx_buflimit; i++) - list_add(&(acm->rb[i].list), &acm->spare_read_bufs); - - acm->throttle = 0; + if (acm_submit_read_urbs(acm, GFP_KERNEL)) + goto bail_out; set_bit(ASYNCB_INITIALIZED, &acm->port.flags); rv = tty_port_block_til_ready(&acm->port, tty, filp); - tasklet_schedule(&acm->urb_task); mutex_unlock(&acm->mutex); out: @@ -613,7 +530,7 @@ static void acm_tty_unregister(struct acm *acm) for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); for (i = 0; i < acm->rx_buflimit; i++) - usb_free_urb(acm->ru[i].urb); + usb_free_urb(acm->read_urbs[i]); kfree(acm->country_codes); kfree(acm); } @@ -629,10 +546,8 @@ static void acm_port_down(struct acm *acm) usb_kill_urb(acm->ctrlurb); for (i = 0; i < ACM_NW; i++) usb_kill_urb(acm->wb[i].urb); - tasklet_disable(&acm->urb_task); for (i = 0; i < acm->rx_buflimit; i++) - usb_kill_urb(acm->ru[i].urb); - tasklet_enable(&acm->urb_task); + usb_kill_urb(acm->read_urbs[i]); acm->control->needs_remote_wakeup = 0; usb_autopm_put_interface(acm->control); } @@ -731,22 +646,31 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) static void acm_tty_throttle(struct tty_struct *tty) { struct acm *acm = tty->driver_data; + if (!ACM_READY(acm)) return; - spin_lock_bh(&acm->throttle_lock); - acm->throttle = 1; - spin_unlock_bh(&acm->throttle_lock); + + spin_lock_irq(&acm->read_lock); + acm->throttle_req = 1; + spin_unlock_irq(&acm->read_lock); } static void acm_tty_unthrottle(struct tty_struct *tty) { struct acm *acm = tty->driver_data; + unsigned int was_throttled; + if (!ACM_READY(acm)) return; - spin_lock_bh(&acm->throttle_lock); - acm->throttle = 0; - spin_unlock_bh(&acm->throttle_lock); - tasklet_schedule(&acm->urb_task); + + spin_lock_irq(&acm->read_lock); + was_throttled = acm->throttled; + acm->throttled = 0; + acm->throttle_req = 0; + spin_unlock_irq(&acm->read_lock); + + if (was_throttled) + acm_submit_read_urbs(acm, GFP_KERNEL); } static int acm_tty_break_ctl(struct tty_struct *tty, int state) @@ -884,7 +808,7 @@ static void acm_read_buffers_free(struct acm *acm) for (i = 0; i < acm->rx_buflimit; i++) usb_free_coherent(usb_dev, acm->readsize, - acm->rb[i].base, acm->rb[i].dma); + acm->read_buffers[i].base, acm->read_buffers[i].dma); } /* Little helper: write buffers allocate */ @@ -1145,10 +1069,7 @@ static int acm_probe(struct usb_interface *intf, acm->ctrlsize = ctrlsize; acm->readsize = readsize; acm->rx_buflimit = num_rx_buf; - acm->urb_task.func = acm_rx_tasklet; - acm->urb_task.data = (unsigned long) acm; INIT_WORK(&acm->work, acm_softint); - spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); @@ -1177,8 +1098,8 @@ static int acm_probe(struct usb_interface *intf, goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { - struct acm_rb *rb = &(acm->rb[i]); - struct acm_ru *rcv = &(acm->ru[i]); + struct acm_rb *rb = &(acm->read_buffers[i]); + struct urb *urb; rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, &rb->dma); @@ -1187,16 +1108,34 @@ static int acm_probe(struct usb_interface *intf, "(read bufs usb_alloc_coherent)\n"); goto alloc_fail6; } + rb->index = i; + rb->instance = acm; - rcv->urb = usb_alloc_urb(0, GFP_KERNEL); - if (rcv->urb == NULL) { + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { dev_err(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); goto alloc_fail6; } + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + urb->transfer_dma = rb->dma; + if (acm->is_int_ep) { + usb_fill_int_urb(urb, acm->dev, + acm->rx_endpoint, + rb->base, + acm->readsize, + acm_read_bulk_callback, rb, + acm->bInterval); + } else { + usb_fill_bulk_urb(urb, acm->dev, + acm->rx_endpoint, + rb->base, + acm->readsize, + acm_read_bulk_callback, rb); + } - rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - rcv->instance = acm; + acm->read_urbs[i] = urb; + __set_bit(i, &acm->read_urbs_free); } for (i = 0; i < ACM_NW; i++) { struct acm_wb *snd = &(acm->wb[i]); @@ -1281,7 +1220,7 @@ static int acm_probe(struct usb_interface *intf, usb_free_urb(acm->wb[i].urb); alloc_fail6: for (i = 0; i < num_rx_buf; i++) - usb_free_urb(acm->ru[i].urb); + usb_free_urb(acm->read_urbs[i]); acm_read_buffers_free(acm); usb_free_urb(acm->ctrlurb); alloc_fail5: @@ -1300,15 +1239,11 @@ static void stop_data_traffic(struct acm *acm) dev_dbg(&acm->control->dev, "%s\n", __func__); - tasklet_disable(&acm->urb_task); - usb_kill_urb(acm->ctrlurb); for (i = 0; i < ACM_NW; i++) usb_kill_urb(acm->wb[i].urb); for (i = 0; i < acm->rx_buflimit; i++) - usb_kill_urb(acm->ru[i].urb); - - tasklet_enable(&acm->urb_task); + usb_kill_urb(acm->read_urbs[i]); cancel_work_sync(&acm->work); } @@ -1369,11 +1304,9 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message) if (message.event & PM_EVENT_AUTO) { int b; - spin_lock_irq(&acm->read_lock); - spin_lock(&acm->write_lock); - b = acm->processing + acm->transmitting; - spin_unlock(&acm->write_lock); - spin_unlock_irq(&acm->read_lock); + spin_lock_irq(&acm->write_lock); + b = acm->transmitting; + spin_unlock_irq(&acm->write_lock); if (b) return -EBUSY; } @@ -1435,7 +1368,7 @@ static int acm_resume(struct usb_interface *intf) if (rv < 0) goto err_out; - tasklet_schedule(&acm->urb_task); + rv = acm_submit_read_urbs(acm, GFP_NOIO); } err_out: diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 7282d1f4912b..7b5c0bd07f80 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -72,16 +72,10 @@ struct acm_wb { }; struct acm_rb { - struct list_head list; int size; unsigned char *base; dma_addr_t dma; -}; - -struct acm_ru { - struct list_head list; - struct acm_rb *buffer; - struct urb *urb; + int index; struct acm *instance; }; @@ -97,34 +91,30 @@ struct acm { unsigned int country_code_size; /* size of this buffer */ unsigned int country_rel_date; /* release date of version */ struct acm_wb wb[ACM_NW]; - struct acm_ru ru[ACM_NR]; - struct acm_rb rb[ACM_NR]; + unsigned long read_urbs_free; + struct urb *read_urbs[ACM_NR]; + struct acm_rb read_buffers[ACM_NR]; int rx_buflimit; int rx_endpoint; spinlock_t read_lock; - struct list_head spare_read_urbs; - struct list_head spare_read_bufs; - struct list_head filled_read_bufs; int write_used; /* number of non-empty write buffers */ - int processing; int transmitting; spinlock_t write_lock; struct mutex mutex; struct usb_cdc_line_coding line; /* bits, stop, parity */ struct work_struct work; /* work queue entry for line discipline waking up */ - struct tasklet_struct urb_task; /* rx processing */ - spinlock_t throttle_lock; /* synchronize throtteling and read callback */ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ unsigned int ctrlout; /* output control lines (DTR, RTS) */ unsigned int writesize; /* max packet size for the output bulk endpoint */ unsigned int readsize,ctrlsize; /* buffer sizes for freeing */ unsigned int minor; /* acm minor number */ - unsigned char throttle; /* throttled by tty layer */ unsigned char clocal; /* termios CLOCAL */ unsigned int ctrl_caps; /* control capabilities from the class specific header */ unsigned int susp_count; /* number of suspended interfaces */ unsigned int combined_interfaces:1; /* control and data collapsed */ unsigned int is_int_ep:1; /* interrupt endpoints contrary to spec used */ + unsigned int throttled:1; /* actually throttled */ + unsigned int throttle_req:1; /* throttle requested */ u8 bInterval; struct acm_wb *delayed_wb; /* write queued for a device about to be woken */ }; -- GitLab From 806e8f8fcc27e1753947bd9f059ba2316cf8f92a Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Thu, 24 Mar 2011 12:20:13 +0100 Subject: [PATCH 0889/5560] usb: usb_storage: do not align length of request for CBW to maxp size Mass-storage and file-storage gadgets align the length to maximum-packet-size when preparing the request to receive CBW. This is unnecessary and prevents the controller driver from knowing that a short-packet is expected. It is incorrect to set short_not_ok when preparing the request to receive CBW. CBW will be a short-packet so short_not_ok must not be set. This makes bh->bulk_out_intended_length unnecessary so it is also removed. Signed-off-by: Mian Yousaf Kaukab Acked-by: Michal Nazarewicz Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 24 ++++-------------------- drivers/usb/gadget/file_storage.c | 28 ++++++---------------------- drivers/usb/gadget/storage_common.c | 7 ------- 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6d8e533949eb..125587ac5d0b 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -474,20 +474,6 @@ static int exception_in_progress(struct fsg_common *common) return common->state > FSG_STATE_IDLE; } -/* Make bulk-out requests be divisible by the maxpacket size */ -static void set_bulk_out_req_length(struct fsg_common *common, - struct fsg_buffhd *bh, unsigned int length) -{ - unsigned int rem; - - bh->bulk_out_intended_length = length; - rem = length % common->bulk_out_maxpacket; - if (rem > 0) - length += common->bulk_out_maxpacket - rem; - bh->outreq->length = length; -} - - /*-------------------------------------------------------------------------*/ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) @@ -586,9 +572,9 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) struct fsg_buffhd *bh = req->context; dump_msg(common, "bulk-out", req->buf, req->actual); - if (req->status || req->actual != bh->bulk_out_intended_length) + if (req->status || req->actual != req->length) DBG(common, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, bh->bulk_out_intended_length); + req->status, req->actual, req->length); if (req->status == -ECONNRESET) /* Request was cancelled */ usb_ep_fifo_flush(ep); @@ -975,7 +961,6 @@ static int do_write(struct fsg_common *common) * the bulk-out maxpacket size */ bh->outreq->length = amount; - bh->bulk_out_intended_length = amount; bh->outreq->short_not_ok = 1; if (!start_out_transfer(common, bh)) /* Dunno what to do if common->fsg is NULL */ @@ -1652,7 +1637,6 @@ static int throw_away_data(struct fsg_common *common) * the bulk-out maxpacket size. */ bh->outreq->length = amount; - bh->bulk_out_intended_length = amount; bh->outreq->short_not_ok = 1; if (!start_out_transfer(common, bh)) /* Dunno what to do if common->fsg is NULL */ @@ -2322,8 +2306,8 @@ static int get_next_command(struct fsg_common *common) } /* Queue a request to read a Bulk-only CBW */ - set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); - bh->outreq->short_not_ok = 1; + bh->outreq->length = USB_BULK_CB_WRAP_LEN; + bh->outreq->short_not_ok = 0; if (!start_out_transfer(common, bh)) /* Don't know what to do if common->fsg is NULL */ return -EIO; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a6eacb59571b..d04e0e6b019d 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -497,19 +497,6 @@ static int exception_in_progress(struct fsg_dev *fsg) return (fsg->state > FSG_STATE_IDLE); } -/* Make bulk-out requests be divisible by the maxpacket size */ -static void set_bulk_out_req_length(struct fsg_dev *fsg, - struct fsg_buffhd *bh, unsigned int length) -{ - unsigned int rem; - - bh->bulk_out_intended_length = length; - rem = length % fsg->bulk_out_maxpacket; - if (rem > 0) - length += fsg->bulk_out_maxpacket - rem; - bh->outreq->length = length; -} - static struct fsg_dev *the_fsg; static struct usb_gadget_driver fsg_driver; @@ -730,10 +717,9 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) struct fsg_buffhd *bh = req->context; dump_msg(fsg, "bulk-out", req->buf, req->actual); - if (req->status || req->actual != bh->bulk_out_intended_length) + if (req->status || req->actual != req->length) DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, - bh->bulk_out_intended_length); + req->status, req->actual, req->length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1349,8 +1335,7 @@ static int do_write(struct fsg_dev *fsg) /* amount is always divisible by 512, hence by * the bulk-out maxpacket size */ - bh->outreq->length = bh->bulk_out_intended_length = - amount; + bh->outreq->length = amount; bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); @@ -2010,8 +1995,7 @@ static int throw_away_data(struct fsg_dev *fsg) /* amount is always divisible by 512, hence by * the bulk-out maxpacket size */ - bh->outreq->length = bh->bulk_out_intended_length = - amount; + bh->outreq->length = amount; bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); @@ -2688,8 +2672,8 @@ static int get_next_command(struct fsg_dev *fsg) } /* Queue a request to read a Bulk-only CBW */ - set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); - bh->outreq->short_not_ok = 1; + bh->outreq->length = USB_BULK_CB_WRAP_LEN; + bh->outreq->short_not_ok = 0; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index b015561fd602..3179b8bb6ced 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -286,13 +286,6 @@ struct fsg_buffhd { enum fsg_buffer_state state; struct fsg_buffhd *next; - /* - * The NetChip 2280 is faster, and handles some protocol faults - * better, if we don't submit any short bulk-out read requests. - * So we will record the intended request length here. - */ - unsigned int bulk_out_intended_length; - struct usb_request *inreq; int inreq_busy; struct usb_request *outreq; -- GitLab From edf847decc4159128041d2a81f8d93e6eb567ecb Mon Sep 17 00:00:00 2001 From: Libor Pechacek Date: Fri, 25 Mar 2011 09:36:49 +0100 Subject: [PATCH 0890/5560] USB: remove dead code from usb_deregister_dev() The `name' variable is unused in usb_deregister_dev() since commit d6e5bcf (devfs: Remove the mode field from usb_class_driver as it's no longer needed). Signed-off-by: Libor Pechacek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/file.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index cf6a5423de09..99458c843d60 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -236,13 +236,6 @@ EXPORT_SYMBOL_GPL(usb_register_dev); void usb_deregister_dev(struct usb_interface *intf, struct usb_class_driver *class_driver) { - int minor_base = class_driver->minor_base; - char name[20]; - -#ifdef CONFIG_USB_DYNAMIC_MINORS - minor_base = 0; -#endif - if (intf->minor == -1) return; @@ -252,7 +245,6 @@ void usb_deregister_dev(struct usb_interface *intf, usb_minors[intf->minor] = NULL; up_write(&minor_rwsem); - snprintf(name, sizeof(name), class_driver->name, intf->minor - minor_base); device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); intf->usb_dev = NULL; intf->minor = -1; -- GitLab From ee81b3e086c907a3347b15ef219a24fc8bf900f6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 25 Mar 2011 11:46:27 -0400 Subject: [PATCH 0891/5560] USB: g_file_storage: don't send padding when stall=n This patch (as1455) removes the extra padding sent by g_file_storage and g_mass_storage when the gadget wants to send less data than requested by the host and isn't allowed to halt the bulk-IN endpoint. Although the Bulk-Only Transport specification requires the padding to be present, it isn't truly needed since the transfer will be terminated by a short packet anyway. Furthermore, many existing devices don't bother to send any padding. Signed-off-by: Alan Stern Acked-By: Michal Nazarewicz CC: Roger Quadros Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 54 ++++++----------------------- drivers/usb/gadget/file_storage.c | 53 +++++++--------------------- 2 files changed, 23 insertions(+), 84 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 125587ac5d0b..98d6b39061d2 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -1569,37 +1569,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) return rc; } -static int pad_with_zeros(struct fsg_dev *fsg) -{ - struct fsg_buffhd *bh = fsg->common->next_buffhd_to_fill; - u32 nkeep = bh->inreq->length; - u32 nsend; - int rc; - - bh->state = BUF_STATE_EMPTY; /* For the first iteration */ - fsg->common->usb_amount_left = nkeep + fsg->common->residue; - while (fsg->common->usb_amount_left > 0) { - - /* Wait for the next buffer to be free */ - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(fsg->common); - if (rc) - return rc; - } - - nsend = min(fsg->common->usb_amount_left, FSG_BUFLEN); - memset(bh->buf + nkeep, 0, nsend - nkeep); - bh->inreq->length = nsend; - bh->inreq->zero = 0; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - bh = fsg->common->next_buffhd_to_fill = bh->next; - fsg->common->usb_amount_left -= nsend; - nkeep = 0; - } - return 0; -} - static int throw_away_data(struct fsg_common *common) { struct fsg_buffhd *bh; @@ -1686,6 +1655,10 @@ static int finish_reply(struct fsg_common *common) if (common->data_size == 0) { /* Nothing to send */ + /* Don't know what to do if common->fsg is NULL */ + } else if (!fsg_is_set(common)) { + rc = -EIO; + /* If there's no residue, simply send the last buffer */ } else if (common->residue == 0) { bh->inreq->zero = 0; @@ -1694,24 +1667,19 @@ static int finish_reply(struct fsg_common *common) common->next_buffhd_to_fill = bh->next; /* - * For Bulk-only, if we're allowed to stall then send the - * short packet and halt the bulk-in endpoint. If we can't - * stall, pad out the remaining data with 0's. + * For Bulk-only, mark the end of the data with a short + * packet. If we are allowed to stall, halt the bulk-in + * endpoint. (Note: This violates the Bulk-Only Transport + * specification, which requires us to pad the data if we + * don't halt the endpoint. Presumably nobody will mind.) */ - } else if (common->can_stall) { + } else { bh->inreq->zero = 1; if (!start_in_transfer(common, bh)) - /* Don't know what to do if - * common->fsg is NULL */ rc = -EIO; common->next_buffhd_to_fill = bh->next; - if (common->fsg) + if (common->can_stall) rc = halt_bulk_in_endpoint(common->fsg); - } else if (fsg_is_set(common)) { - rc = pad_with_zeros(common->fsg); - } else { - /* Don't know what to do if common->fsg is NULL */ - rc = -EIO; } break; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index d04e0e6b019d..aebfb81f3ba4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1932,37 +1932,6 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) return rc; } -static int pad_with_zeros(struct fsg_dev *fsg) -{ - struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; - u32 nkeep = bh->inreq->length; - u32 nsend; - int rc; - - bh->state = BUF_STATE_EMPTY; // For the first iteration - fsg->usb_amount_left = nkeep + fsg->residue; - while (fsg->usb_amount_left > 0) { - - /* Wait for the next buffer to be free */ - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - - nsend = min(fsg->usb_amount_left, (u32) mod_data.buflen); - memset(bh->buf + nkeep, 0, nsend - nkeep); - bh->inreq->length = nsend; - bh->inreq->zero = 0; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - bh = fsg->next_buffhd_to_fill = bh->next; - fsg->usb_amount_left -= nsend; - nkeep = 0; - } - return 0; -} - static int throw_away_data(struct fsg_dev *fsg) { struct fsg_buffhd *bh; @@ -2066,18 +2035,20 @@ static int finish_reply(struct fsg_dev *fsg) } } - /* For Bulk-only, if we're allowed to stall then send the - * short packet and halt the bulk-in endpoint. If we can't - * stall, pad out the remaining data with 0's. */ + /* + * For Bulk-only, mark the end of the data with a short + * packet. If we are allowed to stall, halt the bulk-in + * endpoint. (Note: This violates the Bulk-Only Transport + * specification, which requires us to pad the data if we + * don't halt the endpoint. Presumably nobody will mind.) + */ else { - if (mod_data.can_stall) { - bh->inreq->zero = 1; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; + bh->inreq->zero = 1; + start_transfer(fsg, fsg->bulk_in, bh->inreq, + &bh->inreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; + if (mod_data.can_stall) rc = halt_bulk_in_endpoint(fsg); - } else - rc = pad_with_zeros(fsg); } break; -- GitLab From ad7c56f07e24c758d78e797ceeb9cf049dec66aa Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 22 Mar 2011 15:35:39 -0400 Subject: [PATCH 0892/5560] USB: sl811: add Kconfig option for ISOCHRONOUS mode Some bluetooth dongles want ISO mode, and the limited support that the sl811 offers today is sufficient. So add a Kconfig option for people to optionally get access to the partial functionality. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 10 ++++++++++ drivers/usb/host/sl811-hcd.c | 8 +------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index e0e0787b724b..5f518ded1955 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -444,6 +444,16 @@ config USB_SL811_HCD To compile this driver as a module, choose M here: the module will be called sl811-hcd. +config USB_SL811_HCD_ISO + bool "partial ISO support" + depends on USB_SL811_HCD + help + The driver doesn't support iso_frame_desc (yet), but for some simple + devices that just queue one ISO frame per URB, then ISO transfers + "should" work using the normal urb status fields. + + If unsure, say N. + config USB_SL811_CS tristate "CF/PCMCIA support for SL811HS HCD" depends on USB_SL811_HCD && PCMCIA diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 18b7099a8125..5adcba016fcf 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -71,12 +71,6 @@ MODULE_ALIAS("platform:sl811-hcd"); /* for now, use only one transfer register bank */ #undef USE_B -/* this doesn't understand urb->iso_frame_desc[], but if you had a driver - * that just queued one ISO frame per URB then iso transfers "should" work - * using the normal urb status fields. - */ -#define DISABLE_ISO - // #define QUIRK2 #define QUIRK3 @@ -807,7 +801,7 @@ static int sl811h_urb_enqueue( int retval; struct usb_host_endpoint *hep = urb->ep; -#ifdef DISABLE_ISO +#ifndef CONFIG_USB_SL811_HCD_ISO if (type == PIPE_ISOCHRONOUS) return -ENOSPC; #endif -- GitLab From 3ab810f19d71f4083be44b41770bcd784ff82e51 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 1 Apr 2011 11:24:30 -0700 Subject: [PATCH 0893/5560] usb gadget: fix all Section mismatch warnings Fix 41 occurrences of this type of Section mismatch warning in g_mass_storage, g_serial, g_cdc, g_multi, g_nokia, g_ether, g_ffs: (the 75 number reported earlier contained some duplicates.) WARNING: drivers/usb/gadget/g_mass_storage.o(.text+0x687a): Section mismatch in reference from the function fsg_bind() to the function .devinit.text:usb_ep_autoconfig() The function fsg_bind() references the function __devinit usb_ep_autoconfig(). This is often because fsg_bind lacks a __devinit annotation or the annotation of usb_ep_autoconfig is wrong. Also remove __devinit from usb_ep_autoconfig_reset() to prevent possible section mismatch problems with it. Signed-off-by: Randy Dunlap Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/gadget.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index e538172c0f64..dd1571db55e7 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -890,8 +890,8 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v) /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, - struct usb_endpoint_descriptor *) __devinit; + struct usb_endpoint_descriptor *); -extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit; +extern void usb_ep_autoconfig_reset(struct usb_gadget *); #endif /* __LINUX_USB_GADGET_H */ -- GitLab From 4661ffc91befc8c5ee080720120da1d53851060a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 7 Apr 2011 10:59:34 +0300 Subject: [PATCH 0894/5560] usb: don't enter usb subdirectories directly Instead, make we enter usb/ directory on all needed cases and enter the subdirectories from drivers/usb/Makefile. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/Makefile | 6 ++---- drivers/usb/Makefile | 5 +++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index ad67b7d4c271..0cf73a90fca8 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -64,12 +64,10 @@ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_UWB) += uwb/ -obj-$(CONFIG_USB_OTG_UTILS) += usb/otg/ +obj-$(CONFIG_USB_OTG_UTILS) += usb/ obj-$(CONFIG_USB) += usb/ -obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/ -obj-$(CONFIG_USB_RENESAS_USBHS) += usb/renesas_usbhs/ obj-$(CONFIG_PCI) += usb/ -obj-$(CONFIG_USB_GADGET) += usb/gadget/ +obj-$(CONFIG_USB_GADGET) += usb/ obj-$(CONFIG_SERIO) += input/serio/ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 239f050efa35..9bc8aeb3c96f 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -45,3 +45,8 @@ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ + +obj-$(CONFIG_USB_MUSB_HDRC) += musb/ +obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ +obj-$(CONFIG_USB_OTG_UTILS) += otg/ +obj-$(CONFIG_USB_GADGET) += gadget/ -- GitLab From 7d670a2ed770a3405a7edb1159e3fa9b3f43fe46 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 5 Apr 2011 13:36:04 -0400 Subject: [PATCH 0895/5560] USB: UHCI: remove uses of hcd->state This patch (as1456) removes all uses of hcd->state from the uhci-hcd driver, as part of the overall strategy to eliminate hcd->state completely. Now when a controller dies we call usb_hc_died() directly, instead of relying on the core interrupt handler to see that hcd->state has changed to HC_STATE_HALT and make the call for us. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 4f65b14e5e08..73db5569f57b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -139,7 +139,6 @@ static void finish_reset(struct uhci_hcd *uhci) uhci->port_c_suspend = uhci->resuming_ports = 0; uhci->rh_state = UHCI_RH_RESET; uhci->is_stopped = UHCI_IS_STOPPED; - uhci_to_hcd(uhci)->state = HC_STATE_HALT; clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); uhci->dead = 0; /* Full reset resurrects the controller */ @@ -188,10 +187,6 @@ static void configure_hc(struct uhci_hcd *uhci) outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER, uhci->io_addr + USBFRNUM); - /* Mark controller as not halted before we enable interrupts */ - uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; - mb(); - /* Enable PIRQ */ pci_write_config_word(pdev, USBLEGSUP, USBLEGSUP_DEFAULT); @@ -360,7 +355,6 @@ __acquires(uhci->lock) static void start_rh(struct uhci_hcd *uhci) { - uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; uhci->is_stopped = 0; /* Mark it configured and running with a 64-byte max packet. @@ -449,6 +443,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) lprintk(errbuf); } uhci_hc_died(uhci); + usb_hc_died(hcd); /* Force a callback in case there are * pending unlinks */ -- GitLab From 99083f16f04e050eab0059167b4980cd67e7aa5a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 5 Apr 2011 13:35:53 -0400 Subject: [PATCH 0896/5560] USB: UHCI: don't try to revive a dead controller This patch (as1457) abandons the curious strategy of declaring a controller dead following hibernation merely in order to reset and then revive it. The core no longer allow dead controllers to spring back to life when the system resumes, so there's no reason to declare a working controller temporarily dead. Instead we do an explicit reset. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 73db5569f57b..83344d688ff0 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -140,8 +140,6 @@ static void finish_reset(struct uhci_hcd *uhci) uhci->rh_state = UHCI_RH_RESET; uhci->is_stopped = UHCI_IS_STOPPED; clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); - - uhci->dead = 0; /* Full reset resurrects the controller */ } /* @@ -837,16 +835,17 @@ static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated) spin_lock_irq(&uhci->lock); /* Make sure resume from hibernation re-enumerates everything */ - if (hibernated) - uhci_hc_died(uhci); + if (hibernated) { + uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); + finish_reset(uhci); + } - /* The firmware or a boot kernel may have changed the controller - * settings during a system wakeup. Check it and reconfigure - * to avoid problems. + /* The firmware may have changed the controller settings during + * a system wakeup. Check it and reconfigure to avoid problems. */ - check_and_reset_hc(uhci); - - /* If the controller was dead before, it's back alive now */ + else { + check_and_reset_hc(uhci); + } configure_hc(uhci); /* Tell the core if the controller had to be reset */ -- GitLab From 3482f00d018fb5e476beb867272c1d82f4f5c7d6 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 5 Apr 2011 16:59:12 +0200 Subject: [PATCH 0897/5560] usb: ftdi-elan: Drop __TIME__ usage The kernel already prints its build timestamp during boot, no need to repeat it in random drivers and produce different object files each time. Cc: Tony Olech Cc: linux-usb@vger.kernel.org Signed-off-by: Michal Marek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 7839c98fa742..b16bd3ce3915 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -2889,8 +2889,7 @@ static struct usb_driver ftdi_elan_driver = { static int __init ftdi_elan_init(void) { int result; - printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, - __TIME__, __DATE__); + printk(KERN_INFO "driver %s\n", ftdi_elan_driver.name); mutex_init(&ftdi_module_lock); INIT_LIST_HEAD(&ftdi_static_list); status_queue = create_singlethread_workqueue("ftdi-status-control"); -- GitLab From 654d121ad8c84e3442efee20b2a0703edb18c212 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 5 Apr 2011 16:59:11 +0200 Subject: [PATCH 0898/5560] usb: u132-hcd: Drop __TIME__ usage The kernel already prints its build timestamp during boot, no need to repeat it in random drivers and produce different object files each time. Cc: Tony Olech Cc: linux-usb@vger.kernel.org Signed-off-by: Michal Marek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/u132-hcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index b4785934e091..533d12cca371 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3230,8 +3230,7 @@ static int __init u132_hcd_init(void) mutex_init(&u132_module_lock); if (usb_disabled()) return -ENODEV; - printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, - __DATE__); + printk(KERN_INFO "driver %s\n", hcd_name); workqueue = create_singlethread_workqueue("u132"); retval = platform_driver_register(&u132_platform_driver); return retval; -- GitLab From 73ee4da994e7b97bd8241e39099cf3dd94675d79 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 5 Apr 2011 18:36:38 +0300 Subject: [PATCH 0899/5560] usb: gadget: f_mass_storage: Fix Bulk-only RESET handling The ep0 request tag was not recorded thus resulting in phase problems while sending status/response in handle_execption() handler. This was resulting in MSC compliance test failures with USBCV tool. With this patch, the Bulk-Only Mass storage RESET request is handled correctly and the MSC compliance tests pass. Signed-off-by: Roger Quadros Acked-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 98d6b39061d2..e9de33d1c9a0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -599,6 +599,11 @@ static int fsg_setup(struct usb_function *f, if (!fsg_is_set(fsg->common)) return -EOPNOTSUPP; + ++fsg->common->ep0_req_tag; /* Record arrival of a new request */ + req->context = NULL; + req->length = 0; + dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); + switch (ctrl->bRequest) { case USB_BULK_RESET_REQUEST: -- GitLab From 3c624d4962a583516acadcbf60a8ca2a48421f5c Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 5 Apr 2011 18:36:39 +0300 Subject: [PATCH 0900/5560] usb: gadget: f_mass_storage: If 'ro'/'cdrom' specified, open file as read-only If we don't need Write access then attempt to open backing file in Read Only mode instead of bailing out too soon. Signed-off-by: Roger Quadros Acked-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index e9de33d1c9a0..7d95a2cf58a3 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2757,6 +2757,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) { curlun->cdrom = !!lcfg->cdrom; curlun->ro = lcfg->cdrom || lcfg->ro; + curlun->initially_ro = curlun->ro; curlun->removable = lcfg->removable; curlun->dev.release = fsg_lun_release; curlun->dev.parent = &gadget->dev; -- GitLab From 84f6c3fb7e8eef51f994e959015e18bb927127e0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Apr 2011 10:11:44 -0700 Subject: [PATCH 0901/5560] usb/otg: fix twl6030 macro Fix warning caused by stray semi-colon at end of macro: drivers/usb/otg/twl6030-usb.c:183: warning: ISO C90 forbids mixed declarations and code Signed-off-by: Randy Dunlap Cc: Hema HK Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/twl6030-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 8a91b4b832a1..6e920de64ef6 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -101,7 +101,7 @@ struct twl6030_usb { bool irq_enabled; }; -#define xceiv_to_twl(x) container_of((x), struct twl6030_usb, otg); +#define xceiv_to_twl(x) container_of((x), struct twl6030_usb, otg) /*-------------------------------------------------------------------------*/ -- GitLab From 74d1dc8d8d13fef55c33b49f06ab84eeebf967c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Weiping=20Pan=28=E6=BD=98=E5=8D=AB=E5=B9=B3=29?= Date: Mon, 11 Apr 2011 18:16:15 +0800 Subject: [PATCH 0902/5560] usb: fix a typo in a comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit replace tranmitted with transmitted. Signed-off-by: Weiping Pan(潘卫平) Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_qe_udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index e35e24fd64bb..1da5fb03d218 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -207,7 +207,7 @@ struct qe_frame{ /* Frame status field */ /* Receive side */ -#define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */ +#define FRAME_OK 0x00000000 /* Frame transmitted or received OK */ #define FRAME_ERROR 0x80000000 /* Error occurred on frame */ #define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */ #define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */ -- GitLab From 0b0cd6c81defc4e4fccb9e9103666547fefdb9c0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 12 Apr 2011 09:31:54 -0300 Subject: [PATCH 0903/5560] USB: Mark ehci_adjust_port_wakeup_flags as __maybe_unused Mark ehci_adjust_port_wakeup_flags as __maybe_unused to avoid the following warning when building the ehci-mxc driver: CC drivers/usb/host/ehci-hcd.o drivers/usb/host/ehci-hub.c:130: warning: 'ehci_adjust_port_wakeup_flags' defined but not used Current ehci-mxc driver implementation does not support suspend/resume. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index d05ea03cfb4d..1a21799195af 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -127,7 +127,7 @@ static int ehci_port_change(struct ehci_hcd *ehci) return 0; } -static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, +static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, bool suspending, bool do_wakeup) { int port; -- GitLab From a87103a6d4a91cbb9be49d3bbd2f35dcf5510da1 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Fri, 1 Apr 2011 23:02:07 +0200 Subject: [PATCH 0904/5560] USB: twl4030-usb: Report correct vbus value for accessory charger adapters1 The twl4030-usb driver exports the status of VBUS as sysfs attribute. In case an accessory charger adapter (ACA) is connected to the OTG transceiver the attribute is always 'off', even when the charger provides VBUS. Added a variable to keep track of the status of VBUS and report it correctly Signed-off-by: Matthias Kaehlcke Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/twl4030-usb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index e01b073cc489..efeb4d1517ff 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -160,6 +160,7 @@ struct twl4030_usb { int irq; u8 linkstat; + bool vbus_supplied; u8 asleep; bool irq_enabled; }; @@ -250,6 +251,8 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) int status; int linkstat = USB_EVENT_NONE; + twl->vbus_supplied = false; + /* * For ID/VBUS sensing, see manual section 15.4.8 ... * except when using only battery backup power, two @@ -265,6 +268,9 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) if (status < 0) dev_err(twl->dev, "USB link status err %d\n", status); else if (status & (BIT(7) | BIT(2))) { + if (status & (BIT(7))) + twl->vbus_supplied = true; + if (status & BIT(2)) linkstat = USB_EVENT_ID; else @@ -484,7 +490,7 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev, spin_lock_irqsave(&twl->lock, flags); ret = sprintf(buf, "%s\n", - (twl->linkstat == USB_EVENT_VBUS) ? "on" : "off"); + twl->vbus_supplied ? "on" : "off"); spin_unlock_irqrestore(&twl->lock, flags); return ret; @@ -608,6 +614,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) twl->otg.set_peripheral = twl4030_set_peripheral; twl->otg.set_suspend = twl4030_set_suspend; twl->usb_mode = pdata->usb_mode; + twl->vbus_supplied = false; twl->asleep = 1; /* init spinlock for workqueue */ -- GitLab From b750106bafbf9e8cb888a2b3681f444d8183a296 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 4 Apr 2011 11:38:07 +0200 Subject: [PATCH 0905/5560] Revert "USB: sam-ba: add driver for Atmel SAM Boot Assistant (SAM-BA)" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 90593899de83a6e6fdea563d058acd2f4334e3f9. SAM-BA devices identify themselves CDC-ACM devices and should be using the cdc-acm driver. Since commit 5b239f0aebd4dd6f85b13decf5e18e86e35d57f0 (USB: cdc-acm: Add pseudo modem without AT command capabilities) cdc-acm also binds to them. Note that the Atmel SAM-BA tools expect to use a USB-serial driver and thus require a symlink from /dev/ttyACMn to some /dev/ttyUSBm (with m < 30) to be able to select the device. This is simply a UI-issue that should be fixed by Atmel. Tested with the SAM-BA 2.10 tools and an Atmel at91sam9260-ek. Signed-off-by: Johan Hovold Cc: Sven Köhler Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 9 -- drivers/usb/serial/Makefile | 1 - drivers/usb/serial/sam-ba.c | 206 ------------------------------------ 3 files changed, 216 deletions(-) delete mode 100644 drivers/usb/serial/sam-ba.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c2b29761fa98..b71e309116a3 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -527,15 +527,6 @@ config USB_SERIAL_SAFE_PADDED bool "USB Secure Encapsulated Driver - Padded" depends on USB_SERIAL_SAFE -config USB_SERIAL_SAMBA - tristate "USB Atmel SAM Boot Assistant (SAM-BA) driver" - help - Say Y here if you want to access the SAM-BA boot application of an - Atmel AT91SAM device. - - To compile this driver as a module, choose M here: the - module will be called sam-ba. - config USB_SERIAL_SIEMENS_MPI tristate "USB Siemens MPI driver" help diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 9a2117f2b06e..9e536eefb32c 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -48,7 +48,6 @@ obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o obj-$(CONFIG_USB_SERIAL_QCAUX) += qcaux.o obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o -obj-$(CONFIG_USB_SERIAL_SAMBA) += sam-ba.o obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o diff --git a/drivers/usb/serial/sam-ba.c b/drivers/usb/serial/sam-ba.c deleted file mode 100644 index e3bba64afc57..000000000000 --- a/drivers/usb/serial/sam-ba.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Atmel SAM Boot Assistant (SAM-BA) driver - * - * Copyright (C) 2010 Johan Hovold - * - * 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 - - -#define DRIVER_VERSION "v1.0" -#define DRIVER_AUTHOR "Johan Hovold " -#define DRIVER_DESC "Atmel SAM Boot Assistant (SAM-BA) driver" - -#define SAMBA_VENDOR_ID 0x3eb -#define SAMBA_PRODUCT_ID 0x6124 - - -static int debug; - -static const struct usb_device_id id_table[] = { - /* - * NOTE: Only match the CDC Data interface. - */ - { USB_DEVICE_AND_INTERFACE_INFO(SAMBA_VENDOR_ID, SAMBA_PRODUCT_ID, - USB_CLASS_CDC_DATA, 0, 0) }, - { } -}; -MODULE_DEVICE_TABLE(usb, id_table); - -static struct usb_driver samba_driver = { - .name = "sam-ba", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .no_dynamic_id = 1, -}; - - -/* - * NOTE: The SAM-BA firmware cannot handle merged write requests so we cannot - * use the generic write implementation (which uses the port write fifo). - */ -static int samba_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct urb *urb; - unsigned long flags; - int result; - int i; - - if (!count) - return 0; - - count = min_t(int, count, port->bulk_out_size); - - spin_lock_irqsave(&port->lock, flags); - if (!port->write_urbs_free) { - spin_unlock_irqrestore(&port->lock, flags); - return 0; - } - i = find_first_bit(&port->write_urbs_free, - ARRAY_SIZE(port->write_urbs)); - __clear_bit(i, &port->write_urbs_free); - port->tx_bytes += count; - spin_unlock_irqrestore(&port->lock, flags); - - urb = port->write_urbs[i]; - memcpy(urb->transfer_buffer, buf, count); - urb->transfer_buffer_length = count; - usb_serial_debug_data(debug, &port->dev, __func__, count, - urb->transfer_buffer); - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err(&port->dev, "%s - error submitting urb: %d\n", - __func__, result); - spin_lock_irqsave(&port->lock, flags); - __set_bit(i, &port->write_urbs_free); - port->tx_bytes -= count; - spin_unlock_irqrestore(&port->lock, flags); - - return result; - } - - return count; -} - -static int samba_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned long flags; - unsigned long free; - int count; - int room; - - spin_lock_irqsave(&port->lock, flags); - free = port->write_urbs_free; - spin_unlock_irqrestore(&port->lock, flags); - - count = hweight_long(free); - room = count * port->bulk_out_size; - - dbg("%s - returns %d", __func__, room); - - return room; -} - -static int samba_chars_in_buffer(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned long flags; - int chars; - - spin_lock_irqsave(&port->lock, flags); - chars = port->tx_bytes; - spin_unlock_irqrestore(&port->lock, flags); - - dbg("%s - returns %d", __func__, chars); - - return chars; -} - -static void samba_write_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - unsigned long flags; - int i; - - dbg("%s - port %d", __func__, port->number); - - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { - if (port->write_urbs[i] == urb) - break; - } - spin_lock_irqsave(&port->lock, flags); - __set_bit(i, &port->write_urbs_free); - port->tx_bytes -= urb->transfer_buffer_length; - spin_unlock_irqrestore(&port->lock, flags); - - if (urb->status) - dbg("%s - non-zero urb status: %d", __func__, urb->status); - - usb_serial_port_softint(port); -} - -static struct usb_serial_driver samba_device = { - .driver = { - .owner = THIS_MODULE, - .name = "sam-ba", - }, - .usb_driver = &samba_driver, - .id_table = id_table, - .num_ports = 1, - .bulk_in_size = 512, - .bulk_out_size = 2048, - .write = samba_write, - .write_room = samba_write_room, - .chars_in_buffer = samba_chars_in_buffer, - .write_bulk_callback = samba_write_bulk_callback, - .throttle = usb_serial_generic_throttle, - .unthrottle = usb_serial_generic_unthrottle, -}; - -static int __init samba_init(void) -{ - int retval; - - retval = usb_serial_register(&samba_device); - if (retval) - return retval; - - retval = usb_register(&samba_driver); - if (retval) { - usb_serial_deregister(&samba_device); - return retval; - } - - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ": " - DRIVER_DESC "\n"); - return 0; -} - -static void __exit samba_exit(void) -{ - usb_deregister(&samba_driver); - usb_serial_deregister(&samba_device); -} - -module_init(samba_init); -module_exit(samba_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Enable verbose debugging messages"); -- GitLab From 3e112662129b48bf8571ee5f7c49a4dbb3b70f04 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 8 Apr 2011 13:22:09 +0900 Subject: [PATCH 0906/5560] ARM: S5P: Add usb ehci device This patch adds usb ehci device definition for samsung s5p cpus. Signed-off-by: Joonyoung Shim Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-exynos4/include/mach/map.h | 3 ++ arch/arm/plat-s5p/Kconfig | 5 +++ arch/arm/plat-s5p/Makefile | 1 + arch/arm/plat-s5p/dev-ehci.c | 50 +++++++++++++++++++++++ arch/arm/plat-s5p/include/plat/ehci.h | 21 ++++++++++ arch/arm/plat-samsung/include/plat/devs.h | 2 + 6 files changed, 82 insertions(+) create mode 100644 arch/arm/plat-s5p/dev-ehci.c create mode 100644 arch/arm/plat-s5p/include/plat/ehci.h diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index 6330b73b9ea7..213c2a27d7ca 100644 --- a/arch/arm/mach-exynos4/include/mach/map.h +++ b/arch/arm/mach-exynos4/include/mach/map.h @@ -101,6 +101,8 @@ #define EXYNOS4_PA_SROMC 0x12570000 +#define EXYNOS4_PA_EHCI 0x12580000 + #define EXYNOS4_PA_UART 0x13800000 #define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000)) @@ -143,6 +145,7 @@ #define S5P_PA_SROMC EXYNOS4_PA_SROMC #define S5P_PA_SYSCON EXYNOS4_PA_SYSCON #define S5P_PA_TIMER EXYNOS4_PA_TIMER +#define S5P_PA_EHCI EXYNOS4_PA_EHCI #define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 849229716586..6751bcf7b888 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -85,6 +85,11 @@ config S5P_DEV_CSIS1 help Compile in platform device definitions for MIPI-CSIS channel 1 +config S5P_DEV_USB_EHCI + bool + help + Compile in platform device definition for USB EHCI + config S5P_SETUP_MIPIPHY bool help diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 42afff7f60be..e234cc4d49a0 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -33,4 +33,5 @@ obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o +obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c new file mode 100644 index 000000000000..a610e5c60964 --- /dev/null +++ b/arch/arm/plat-s5p/dev-ehci.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +/* USB EHCI Host Controller registration */ +static struct resource s5p_ehci_resource[] = { + [0] = { + .start = S5P_PA_EHCI, + .end = S5P_PA_EHCI + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB_HOST, + .end = IRQ_USB_HOST, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 s5p_device_ehci_dmamask = 0xffffffffUL; + +struct platform_device s5p_device_ehci = { + .name = "s5p-ehci", + .id = -1, + .num_resources = ARRAY_SIZE(s5p_ehci_resource), + .resource = s5p_ehci_resource, + .dev = { + .dma_mask = &s5p_device_ehci_dmamask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd) +{ + s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata), + &s5p_device_ehci); +} diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-s5p/include/plat/ehci.h new file mode 100644 index 000000000000..6ae6810c7569 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/ehci.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * 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. + */ + +#ifndef __PLAT_S5P_EHCI_H +#define __PLAT_S5P_EHCI_H + +struct s5p_ehci_platdata { + int (*phy_init)(struct platform_device *pdev, int type); + int (*phy_exit)(struct platform_device *pdev, int type); +}; + +extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd); + +#endif /* __PLAT_S5P_EHCI_H */ diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index f0da6b70fba4..3f38debbb108 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -142,6 +142,8 @@ extern struct platform_device s5p_device_fimc3; extern struct platform_device s5p_device_mipi_csis0; extern struct platform_device s5p_device_mipi_csis1; +extern struct platform_device s5p_device_ehci; + extern struct platform_device exynos4_device_sysmmu; /* s3c2440 specific devices */ -- GitLab From 8f1d169f999fea892c3fcbf5a79ae8525a477572 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 8 Apr 2011 13:22:10 +0900 Subject: [PATCH 0907/5560] ARM: EXYNOS4: Add usb host phy control EXYNOS4 has 2 phys for usb host and usb device. This patch supports to control usb host phy of EXYNOS4. Signed-off-by: Joonyoung Shim Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-exynos4/Makefile | 2 + arch/arm/mach-exynos4/cpu.c | 7 +- arch/arm/mach-exynos4/include/mach/map.h | 1 + arch/arm/mach-exynos4/include/mach/regs-pmu.h | 3 + .../mach-exynos4/include/mach/regs-usb-phy.h | 64 +++++++++ arch/arm/mach-exynos4/usb-phy.c | 136 ++++++++++++++++++ arch/arm/plat-s5p/dev-ehci.c | 9 +- arch/arm/plat-s5p/include/plat/map-s5p.h | 2 +- arch/arm/plat-s5p/include/plat/usb-phy.h | 22 +++ 9 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-exynos4/include/mach/regs-usb-phy.h create mode 100644 arch/arm/mach-exynos4/usb-phy.c create mode 100644 arch/arm/plat-s5p/include/plat/usb-phy.h diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile index 9be104f63c0b..777897551e42 100644 --- a/arch/arm/mach-exynos4/Makefile +++ b/arch/arm/mach-exynos4/Makefile @@ -54,3 +54,5 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o + +obj-$(CONFIG_USB_SUPPORT) += usb-phy.o diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 793011391943..08813a6f66b1 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c @@ -97,7 +97,12 @@ static struct map_desc exynos4_iodesc[] __initdata = { .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), .length = SZ_4K, .type = MT_DEVICE, - }, + }, { + .virtual = (unsigned long)S5P_VA_USB_HSPHY, + .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY), + .length = SZ_4K, + .type = MT_DEVICE, + } }; static void exynos4_idle(void) diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h index 213c2a27d7ca..0009e77a05fc 100644 --- a/arch/arm/mach-exynos4/include/mach/map.h +++ b/arch/arm/mach-exynos4/include/mach/map.h @@ -102,6 +102,7 @@ #define EXYNOS4_PA_SROMC 0x12570000 #define EXYNOS4_PA_EHCI 0x12580000 +#define EXYNOS4_PA_HSPHY 0x125B0000 #define EXYNOS4_PA_UART 0x13800000 diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h index 62b0014d05e0..a9643371f8e7 100644 --- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h @@ -33,6 +33,9 @@ #define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) #define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) +#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) +#define S5P_USBHOST_PHY_ENABLE (1 << 0) + #define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4) #define S5P_MIPI_DPHY_ENABLE (1 << 0) #define S5P_MIPI_DPHY_SRESETN (1 << 1) diff --git a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h new file mode 100644 index 000000000000..703118d5173c --- /dev/null +++ b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * 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. + */ + +#ifndef __PLAT_S5P_REGS_USB_PHY_H +#define __PLAT_S5P_REGS_USB_PHY_H + +#define EXYNOS4_HSOTG_PHYREG(x) ((x) + S5P_VA_USB_HSPHY) + +#define EXYNOS4_PHYPWR EXYNOS4_HSOTG_PHYREG(0x00) +#define PHY1_HSIC_NORMAL_MASK (0xf << 9) +#define PHY1_HSIC1_SLEEP (1 << 12) +#define PHY1_HSIC1_FORCE_SUSPEND (1 << 11) +#define PHY1_HSIC0_SLEEP (1 << 10) +#define PHY1_HSIC0_FORCE_SUSPEND (1 << 9) + +#define PHY1_STD_NORMAL_MASK (0x7 << 6) +#define PHY1_STD_SLEEP (1 << 8) +#define PHY1_STD_ANALOG_POWERDOWN (1 << 7) +#define PHY1_STD_FORCE_SUSPEND (1 << 6) + +#define PHY0_NORMAL_MASK (0x39 << 0) +#define PHY0_SLEEP (1 << 5) +#define PHY0_OTG_DISABLE (1 << 4) +#define PHY0_ANALOG_POWERDOWN (1 << 3) +#define PHY0_FORCE_SUSPEND (1 << 0) + +#define EXYNOS4_PHYCLK EXYNOS4_HSOTG_PHYREG(0x04) +#define PHY1_COMMON_ON_N (1 << 7) +#define PHY0_COMMON_ON_N (1 << 4) +#define PHY0_ID_PULLUP (1 << 2) +#define CLKSEL_MASK (0x3 << 0) +#define CLKSEL_SHIFT (0) +#define CLKSEL_48M (0x0 << 0) +#define CLKSEL_12M (0x2 << 0) +#define CLKSEL_24M (0x3 << 0) + +#define EXYNOS4_RSTCON EXYNOS4_HSOTG_PHYREG(0x08) +#define HOST_LINK_PORT_SWRST_MASK (0xf << 6) +#define HOST_LINK_PORT2_SWRST (1 << 9) +#define HOST_LINK_PORT1_SWRST (1 << 8) +#define HOST_LINK_PORT0_SWRST (1 << 7) +#define HOST_LINK_ALL_SWRST (1 << 6) + +#define PHY1_SWRST_MASK (0x7 << 3) +#define PHY1_HSIC_SWRST (1 << 5) +#define PHY1_STD_SWRST (1 << 4) +#define PHY1_ALL_SWRST (1 << 3) + +#define PHY0_SWRST_MASK (0x7 << 0) +#define PHY0_PHYLINK_SWRST (1 << 2) +#define PHY0_HLINK_SWRST (1 << 1) +#define PHY0_SWRST (1 << 0) + +#define EXYNOS4_PHY1CON EXYNOS4_HSOTG_PHYREG(0x34) +#define FPENABLEN (1 << 0) + +#endif /* __PLAT_S5P_REGS_USB_PHY_H */ diff --git a/arch/arm/mach-exynos4/usb-phy.c b/arch/arm/mach-exynos4/usb-phy.c new file mode 100644 index 000000000000..0883c1b824b9 --- /dev/null +++ b/arch/arm/mach-exynos4/usb-phy.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int exynos4_usb_phy1_init(struct platform_device *pdev) +{ + struct clk *otg_clk; + struct clk *xusbxti_clk; + u32 phyclk; + u32 rstcon; + int err; + + otg_clk = clk_get(&pdev->dev, "otg"); + if (IS_ERR(otg_clk)) { + dev_err(&pdev->dev, "Failed to get otg clock\n"); + return PTR_ERR(otg_clk); + } + + err = clk_enable(otg_clk); + if (err) { + clk_put(otg_clk); + return err; + } + + writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, + S5P_USBHOST_PHY_CONTROL); + + /* set clock frequency for PLL */ + phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK; + + xusbxti_clk = clk_get(&pdev->dev, "xusbxti"); + if (xusbxti_clk && !IS_ERR(xusbxti_clk)) { + switch (clk_get_rate(xusbxti_clk)) { + case 12 * MHZ: + phyclk |= CLKSEL_12M; + break; + case 24 * MHZ: + phyclk |= CLKSEL_24M; + break; + default: + case 48 * MHZ: + /* default reference clock */ + break; + } + clk_put(xusbxti_clk); + } + + writel(phyclk, EXYNOS4_PHYCLK); + + /* floating prevention logic: disable */ + writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON); + + /* set to normal HSIC 0 and 1 of PHY1 */ + writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK), + EXYNOS4_PHYPWR); + + /* set to normal standard USB of PHY1 */ + writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR); + + /* reset all ports of both PHY and Link */ + rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK | + PHY1_SWRST_MASK; + writel(rstcon, EXYNOS4_RSTCON); + udelay(10); + + rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK); + writel(rstcon, EXYNOS4_RSTCON); + udelay(50); + + clk_disable(otg_clk); + clk_put(otg_clk); + + return 0; +} + +static int exynos4_usb_phy1_exit(struct platform_device *pdev) +{ + struct clk *otg_clk; + int err; + + otg_clk = clk_get(&pdev->dev, "otg"); + if (IS_ERR(otg_clk)) { + dev_err(&pdev->dev, "Failed to get otg clock\n"); + return PTR_ERR(otg_clk); + } + + err = clk_enable(otg_clk); + if (err) { + clk_put(otg_clk); + return err; + } + + writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN), + EXYNOS4_PHYPWR); + + writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE, + S5P_USBHOST_PHY_CONTROL); + + clk_disable(otg_clk); + clk_put(otg_clk); + + return 0; +} + +int s5p_usb_phy_init(struct platform_device *pdev, int type) +{ + if (type == S5P_USB_PHY_HOST) + return exynos4_usb_phy1_init(pdev); + + return -EINVAL; +} + +int s5p_usb_phy_exit(struct platform_device *pdev, int type) +{ + if (type == S5P_USB_PHY_HOST) + return exynos4_usb_phy1_exit(pdev); + + return -EINVAL; +} diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c index a610e5c60964..94080fff9e9b 100644 --- a/arch/arm/plat-s5p/dev-ehci.c +++ b/arch/arm/plat-s5p/dev-ehci.c @@ -45,6 +45,13 @@ struct platform_device s5p_device_ehci = { void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd) { - s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata), + struct s5p_ehci_platdata *npd; + + npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata), &s5p_device_ehci); + + if (!npd->phy_init) + npd->phy_init = s5p_usb_phy_init; + if (!npd->phy_exit) + npd->phy_exit = s5p_usb_phy_exit; } diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index d973d39666a3..a6c3d327ce72 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -39,7 +39,7 @@ #define S5P_VA_TWD S5P_VA_COREPERI(0x600) #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) -#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000) +#define S5P_VA_USB_HSPHY S3C_ADDR(0x02900000) #define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) #define VA_VIC0 VA_VIC(0) diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-s5p/include/plat/usb-phy.h new file mode 100644 index 000000000000..6dd6bcfca3ce --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/usb-phy.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Joonyoung Shim + * + * 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. + */ + +#ifndef __PLAT_S5P_USB_PHY_H +#define __PLAT_S5P_USB_PHY_H + +enum s5p_usb_phy_type { + S5P_USB_PHY_DEVICE, + S5P_USB_PHY_HOST, +}; + +extern int s5p_usb_phy_init(struct platform_device *pdev, int type); +extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); + +#endif /* __PLAT_S5P_REGS_USB_PHY_H */ -- GitLab From 1bcc5aa87f043d34522d783154d08173b435fb46 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 8 Apr 2011 14:08:50 +0900 Subject: [PATCH 0908/5560] USB: Add initial S5P EHCI driver This patch adds host USB high speed driver for samsung S5P series. This is initial driver and we need additional implementation to support some functions like power management. Signed-off-by: Jingoo Han Signed-off-by: Joonyoung Shim Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 1 + drivers/usb/host/Kconfig | 6 ++ drivers/usb/host/ehci-hcd.c | 5 + drivers/usb/host/ehci-s5p.c | 201 ++++++++++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 drivers/usb/host/ehci-s5p.c diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index d299906e4f00..cf7614d29f03 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -65,6 +65,7 @@ config USB_ARCH_HAS_EHCI default y if ARCH_CNS3XXX default y if ARCH_VT8500 default y if PLAT_SPEAR + default y if PLAT_S5P default y if ARCH_MSM default PCI diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5f518ded1955..ade009081feb 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -188,6 +188,12 @@ config USB_EHCI_SH Enables support for the on-chip EHCI controller on the SuperH. If you use the PCI EHCI controller, this option is not necessary. +config USB_EHCI_S5P + boolean "S5P EHCI support" + depends on USB_EHCI_HCD && PLAT_S5P + help + Enable support for the S5P SOC's on-chip EHCI controller. + config USB_W90X900_EHCI bool "W90X900(W90P910) EHCI support" depends on USB_EHCI_HCD && ARCH_W90X900 diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 78561d112c04..6b20b3b12d65 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1265,6 +1265,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER tegra_ehci_driver #endif +#ifdef CONFIG_USB_EHCI_S5P +#include "ehci-s5p.c" +#define PLATFORM_DRIVER s5p_ehci_driver +#endif + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c new file mode 100644 index 000000000000..0c18f280bf4c --- /dev/null +++ b/drivers/usb/host/ehci-s5p.c @@ -0,0 +1,201 @@ +/* + * SAMSUNG S5P USB HOST EHCI Controller + * + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Jingoo Han + * Author: Joonyoung Shim + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +struct s5p_ehci_hcd { + struct device *dev; + struct usb_hcd *hcd; + struct clk *clk; +}; + +static const struct hc_driver s5p_ehci_hc_driver = { + .description = hcd_name, + .product_desc = "S5P EHCI Host Controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, + + .reset = ehci_init, + .start = ehci_run, + .stop = ehci_stop, + .shutdown = ehci_shutdown, + + .get_frame_number = ehci_get_frame, + + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .bus_suspend = ehci_bus_suspend, + .bus_resume = ehci_bus_resume, + + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +}; + +static int s5p_ehci_probe(struct platform_device *pdev) +{ + struct s5p_ehci_platdata *pdata; + struct s5p_ehci_hcd *s5p_ehci; + struct usb_hcd *hcd; + struct ehci_hcd *ehci; + struct resource *res; + int irq; + int err; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "No platform data defined\n"); + return -EINVAL; + } + + s5p_ehci = kzalloc(sizeof(struct s5p_ehci_hcd), GFP_KERNEL); + if (!s5p_ehci) + return -ENOMEM; + + s5p_ehci->dev = &pdev->dev; + + hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) { + dev_err(&pdev->dev, "Unable to create HCD\n"); + err = -ENOMEM; + goto fail_hcd; + } + + s5p_ehci->clk = clk_get(&pdev->dev, "usbhost"); + + if (IS_ERR(s5p_ehci->clk)) { + dev_err(&pdev->dev, "Failed to get usbhost clock\n"); + err = PTR_ERR(s5p_ehci->clk); + goto fail_clk; + } + + err = clk_enable(s5p_ehci->clk); + if (err) + goto fail_clken; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get I/O memory\n"); + err = -ENXIO; + goto fail_io; + } + + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + hcd->regs = ioremap(res->start, resource_size(res)); + if (!hcd->regs) { + dev_err(&pdev->dev, "Failed to remap I/O memory\n"); + err = -ENOMEM; + goto fail_io; + } + + irq = platform_get_irq(pdev, 0); + if (!irq) { + dev_err(&pdev->dev, "Failed to get IRQ\n"); + err = -ENODEV; + goto fail; + } + + if (pdata->phy_init) + pdata->phy_init(pdev, S5P_USB_PHY_HOST); + + ehci = hcd_to_ehci(hcd); + ehci->caps = hcd->regs; + ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); + + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); + + /* cache this readonly data; minimize chip reads */ + ehci->hcs_params = readl(&ehci->caps->hcs_params); + + err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + if (err) { + dev_err(&pdev->dev, "Failed to add USB HCD\n"); + goto fail; + } + + platform_set_drvdata(pdev, s5p_ehci); + + return 0; + +fail: + iounmap(hcd->regs); +fail_io: + clk_disable(s5p_ehci->clk); +fail_clken: + clk_put(s5p_ehci->clk); +fail_clk: + usb_put_hcd(hcd); +fail_hcd: + kfree(s5p_ehci); + return err; +} + +static int s5p_ehci_remove(struct platform_device *pdev) +{ + struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; + struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); + struct usb_hcd *hcd = s5p_ehci->hcd; + + usb_remove_hcd(hcd); + + if (pdata && pdata->phy_exit) + pdata->phy_exit(pdev, S5P_USB_PHY_HOST); + + iounmap(hcd->regs); + + clk_disable(s5p_ehci->clk); + clk_put(s5p_ehci->clk); + + usb_put_hcd(hcd); + kfree(s5p_ehci); + + return 0; +} + +static void s5p_ehci_shutdown(struct platform_device *pdev) +{ + struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); + struct usb_hcd *hcd = s5p_ehci->hcd; + + if (hcd->driver->shutdown) + hcd->driver->shutdown(hcd); +} + +static struct platform_driver s5p_ehci_driver = { + .probe = s5p_ehci_probe, + .remove = s5p_ehci_remove, + .shutdown = s5p_ehci_shutdown, + .driver = { + .name = "s5p-ehci", + .owner = THIS_MODULE, + } +}; + +MODULE_ALIAS("platform:s5p-ehci"); -- GitLab From 01da92f7f6436c6c29c11490c7fcdb20fb6c46b8 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 8 Apr 2011 13:22:11 +0900 Subject: [PATCH 0909/5560] ARM: EXYNOS4: Add usb ehci device to the NURI board This patch is to support usb ehci device to the NURI board. Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-exynos4/Kconfig | 1 + arch/arm/mach-exynos4/mach-nuri.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index e849f67be47d..805196207ce8 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -170,6 +170,7 @@ config MACH_NURI select S3C_DEV_HSMMC3 select S3C_DEV_I2C1 select S3C_DEV_I2C5 + select S5P_DEV_USB_EHCI select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_I2C5 select EXYNOS4_SETUP_SDHCI diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c index b79ad010d194..bb5d12f43af8 100644 --- a/arch/arm/mach-exynos4/mach-nuri.c +++ b/arch/arm/mach-exynos4/mach-nuri.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include @@ -262,6 +264,16 @@ static struct i2c_board_info i2c5_devs[] __initdata = { /* max8997, To be updated */ }; +/* USB EHCI */ +static struct s5p_ehci_platdata nuri_ehci_pdata; + +static void __init nuri_ehci_init(void) +{ + struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata; + + s5p_ehci_set_platdata(pdata); +} + static struct platform_device *nuri_devices[] __initdata = { /* Samsung Platform Devices */ &emmc_fixed_voltage, @@ -270,6 +282,7 @@ static struct platform_device *nuri_devices[] __initdata = { &s3c_device_hsmmc3, &s3c_device_wdt, &s3c_device_timer[0], + &s5p_device_ehci, /* NURI Devices */ &nuri_gpio_keys, @@ -291,6 +304,9 @@ static void __init nuri_machine_init(void) i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); + nuri_ehci_init(); + clk_xusbxti.rate = 24000000; + /* Last */ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); } -- GitLab From 502fa84195f47a79d7220470ebaa85a773659755 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 13 Apr 2011 10:54:22 +0200 Subject: [PATCH 0910/5560] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR91XX SoCs The Atheros AR71XX/AR91XX SoCs have a built-in EHCI controller. This patch adds the necessary glue code to make the generic EHCI driver usable for them. Signed-off-by: Gabor Juhos Signed-off-by: Imre Kaloz Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/ath79/Kconfig | 3 + drivers/usb/host/Kconfig | 9 ++ drivers/usb/host/ehci-ath79.c | 200 ++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci-hcd.c | 5 + 4 files changed, 217 insertions(+) create mode 100644 drivers/usb/host/ehci-ath79.c diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index b05828260f7f..649a2a3bde78 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -26,12 +26,15 @@ config ATH79_MACH_PB44 endmenu config SOC_AR71XX + select USB_ARCH_HAS_EHCI def_bool n config SOC_AR724X + select USB_ARCH_HAS_EHCI def_bool n config SOC_AR913X + select USB_ARCH_HAS_EHCI def_bool n config ATH79_DEV_AR913X_WMAC diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index ade009081feb..da3757cec7ac 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -208,6 +208,15 @@ config USB_CNS3XXX_EHCI It is needed for high-speed (480Mbit/sec) USB 2.0 device support. +config USB_EHCI_ATH79 + bool "EHCI support for AR7XXX/AR9XXX SoCs" + depends on USB_EHCI_HCD && (SOC_AR71XX || SOC_AR724X || SOC_AR913X) + select USB_EHCI_ROOT_HUB_TT + default y + ---help--- + Enables support for the built-in EHCI controller present + on the Atheros AR7XXX/AR9XXX SoCs. + config USB_OXU210HP_HCD tristate "OXU210HP HCD support" depends on USB diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c new file mode 100644 index 000000000000..74325b87bd77 --- /dev/null +++ b/drivers/usb/host/ehci-ath79.c @@ -0,0 +1,200 @@ +/* + * Bus Glue for Atheros AR7XXX/AR9XXX built-in EHCI controller. + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros' 2.6.15 BSP + * Copyright (C) 2007 Atheros Communications, Inc. + * + * 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 + +enum { + EHCI_ATH79_IP_V1 = 0, + EHCI_ATH79_IP_V2, +}; + +static const struct platform_device_id ehci_ath79_id_table[] = { + { + .name = "ar71xx-ehci", + .driver_data = EHCI_ATH79_IP_V1, + }, + { + .name = "ar724x-ehci", + .driver_data = EHCI_ATH79_IP_V2, + }, + { + .name = "ar913x-ehci", + .driver_data = EHCI_ATH79_IP_V2, + }, + { + /* terminating entry */ + }, +}; + +MODULE_DEVICE_TABLE(platform, ehci_ath79_id_table); + +static int ehci_ath79_init(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct platform_device *pdev = to_platform_device(hcd->self.controller); + const struct platform_device_id *id; + int ret; + + id = platform_get_device_id(pdev); + if (!id) { + dev_err(hcd->self.controller, "missing device id\n"); + return -EINVAL; + } + + switch (id->driver_data) { + case EHCI_ATH79_IP_V1: + ehci->caps = hcd->regs; + ehci->regs = hcd->regs + + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + break; + + case EHCI_ATH79_IP_V2: + hcd->has_tt = 1; + + ehci->caps = hcd->regs + 0x100; + ehci->regs = hcd->regs + 0x100 + + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + break; + + default: + BUG(); + } + + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + ehci->sbrn = 0x20; + + ehci_reset(ehci); + + ret = ehci_init(hcd); + if (ret) + return ret; + + ehci_port_power(ehci, 0); + + return 0; +} + +static const struct hc_driver ehci_ath79_hc_driver = { + .description = hcd_name, + .product_desc = "Atheros built-in EHCI controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, + + .reset = ehci_ath79_init, + .start = ehci_run, + .stop = ehci_stop, + .shutdown = ehci_shutdown, + + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + + .get_frame_number = ehci_get_frame, + + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +}; + +static int ehci_ath79_probe(struct platform_device *pdev) +{ + struct usb_hcd *hcd; + struct resource *res; + int irq; + int ret; + + if (usb_disabled()) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_dbg(&pdev->dev, "no IRQ specified\n"); + return -ENODEV; + } + irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_dbg(&pdev->dev, "no base address specified\n"); + return -ENODEV; + } + + hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) + return -ENOMEM; + + hcd->rsrc_start = res->start; + hcd->rsrc_len = res->end - res->start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + dev_dbg(&pdev->dev, "controller already in use\n"); + ret = -EBUSY; + goto err_put_hcd; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { + dev_dbg(&pdev->dev, "error mapping memory\n"); + ret = -EFAULT; + goto err_release_region; + } + + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + if (ret) + goto err_iounmap; + + return 0; + +err_iounmap: + iounmap(hcd->regs); + +err_release_region: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err_put_hcd: + usb_put_hcd(hcd); + return ret; +} + +static int ehci_ath79_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_remove_hcd(hcd); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + + return 0; +} + +static struct platform_driver ehci_ath79_driver = { + .probe = ehci_ath79_probe, + .remove = ehci_ath79_remove, + .id_table = ehci_ath79_id_table, + .driver = { + .owner = THIS_MODULE, + .name = "ath79-ehci", + } +}; + +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ehci"); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6b20b3b12d65..83b7d5f02a15 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1270,6 +1270,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER s5p_ehci_driver #endif +#ifdef CONFIG_USB_EHCI_ATH79 +#include "ehci-ath79.c" +#define PLATFORM_DRIVER ehci_ath79_driver +#endif + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) -- GitLab From 2f7ac6c199978d0a0e407a12534201aa675a6482 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 13 Apr 2011 10:54:23 +0200 Subject: [PATCH 0911/5560] USB: ehci: add workaround for Synopsys HC bug A Synopsys USB core used in various SoCs has a bug which might cause that the host controller not issuing ping. When software uses the Doorbell mechanism to remove queue heads, the host controller still has references to the removed queue head even after indicating an Interrupt on Async Advance. This happens if the last executed queue head's Next Link queue head is removed. Consequences of the defect: The Host controller fetches the removed queue head, using memory that would otherwise be deallocated.This results in incorrect transactions on both the USB and system memory. This may result in undefined behavior. Workarounds: 1) If no queue head is active (no Status field's Active bit is set) after removing the queue heads, the software can write one of the valid queue head addresses to the ASYNCLISTADDR register and deallocate the removed queue head's memory after 2 microframes. If one or more of the queue heads is active (the Active bit is set in the Status field) after removing the queue heads, the software can delay memory deallocation after time X, where X is the time required for the Host Controller to go through all the queue heads once. X varies with the number of queue heads and the time required to process periodic transactions: if more periodic transactions must be performed, the Host Controller has less time to process asynchronous transaction processing. 2) Do not use the Doorbell mechanism to remove the queue heads. Disable the Asynchronous Schedule Enable bit instead. The bug has been discussed on the linux-usb-devel mailing-list four years ago, the original thread can be found here: http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg45345.html This patch implements the first workaround as suggested by David Brownell. The built-in USB host controller of the Atheros AR7130/AR7141/AR7161 SoCs requires this to work properly. Signed-off-by: Gabor Juhos Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-ath79.c | 2 ++ drivers/usb/host/ehci-q.c | 4 ++++ drivers/usb/host/ehci.h | 1 + 3 files changed, 7 insertions(+) diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c index 74325b87bd77..7ea23b50f5d8 100644 --- a/drivers/usb/host/ehci-ath79.c +++ b/drivers/usb/host/ehci-ath79.c @@ -54,6 +54,8 @@ static int ehci_ath79_init(struct usb_hcd *hcd) switch (id->driver_data) { case EHCI_ATH79_IP_V1: + ehci->has_synopsys_hc_bug = 1; + ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 98ded66e8d3f..6582aeab6237 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1183,6 +1183,10 @@ static void end_unlink_async (struct ehci_hcd *ehci) ehci->reclaim = NULL; start_unlink_async (ehci, next); } + + if (ehci->has_synopsys_hc_bug) + ehci_writel(ehci, (u32) ehci->async->qh_dma, + &ehci->regs->async_next); } /* makes sure the async qh will become idle */ diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 333ddc156919..168f1a88c4d0 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -134,6 +134,7 @@ struct ehci_hcd { /* one per controller */ unsigned amd_pll_fix:1; unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ + unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) -- GitLab From 90e6ca5cda8a38b7bb53660e67eff0845c0abe3f Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 13 Apr 2011 10:54:24 +0200 Subject: [PATCH 0912/5560] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs The Atheros AR71XX/AR7240 SoCs have a built-in OHCI controller. This patch adds the necessary glue code to make the generic OHCI driver usable for them. Signed-off-by: Gabor Juhos Signed-off-by: Imre Kaloz Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/ath79/Kconfig | 2 + drivers/usb/host/Kconfig | 8 ++ drivers/usb/host/ohci-ath79.c | 151 ++++++++++++++++++++++++++++++++++ drivers/usb/host/ohci-hcd.c | 5 ++ 4 files changed, 166 insertions(+) create mode 100644 drivers/usb/host/ohci-ath79.c diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 649a2a3bde78..47707410582c 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -27,10 +27,12 @@ endmenu config SOC_AR71XX select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_OHCI def_bool n config SOC_AR724X select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_OHCI def_bool n config SOC_AR913X diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index da3757cec7ac..fe4beca00009 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -302,6 +302,14 @@ config USB_OHCI_HCD_OMAP3 Enables support for the on-chip OHCI controller on OMAP3 and later chips. +config USB_OHCI_ATH79 + bool "USB OHCI support for the Atheros AR71XX/AR7240 SoCs" + depends on USB_OHCI_HCD && (SOC_AR71XX || SOC_AR724X) + default y + help + Enables support for the built-in OHCI controller present on the + Atheros AR71XX/AR7240 SoCs. + config USB_OHCI_HCD_PPC_SOC bool "OHCI support for on-chip PPC USB controller" depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c new file mode 100644 index 000000000000..ffea3e7cb0a8 --- /dev/null +++ b/drivers/usb/host/ohci-ath79.c @@ -0,0 +1,151 @@ +/* + * OHCI HCD (Host Controller Driver) for USB. + * + * Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller. + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros' 2.6.15 BSP + * Copyright (C) 2007 Atheros Communications, Inc. + * + * 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 + +static int __devinit ohci_ath79_start(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int ret; + + ret = ohci_init(ohci); + if (ret < 0) + return ret; + + ret = ohci_run(ohci); + if (ret < 0) + goto err; + + return 0; + +err: + ohci_stop(hcd); + return ret; +} + +static const struct hc_driver ohci_ath79_hc_driver = { + .description = hcd_name, + .product_desc = "Atheros built-in OHCI controller", + .hcd_priv_size = sizeof(struct ohci_hcd), + + .irq = ohci_irq, + .flags = HCD_USB11 | HCD_MEMORY, + + .start = ohci_ath79_start, + .stop = ohci_stop, + .shutdown = ohci_shutdown, + + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .endpoint_disable = ohci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ohci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ohci_hub_status_data, + .hub_control = ohci_hub_control, + .start_port_reset = ohci_start_port_reset, +}; + +static int ohci_ath79_probe(struct platform_device *pdev) +{ + struct usb_hcd *hcd; + struct resource *res; + int irq; + int ret; + + if (usb_disabled()) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_dbg(&pdev->dev, "no IRQ specified\n"); + return -ENODEV; + } + irq = res->start; + + hcd = usb_create_hcd(&ohci_ath79_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_dbg(&pdev->dev, "no base address specified\n"); + ret = -ENODEV; + goto err_put_hcd; + } + hcd->rsrc_start = res->start; + hcd->rsrc_len = res->end - res->start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + dev_dbg(&pdev->dev, "controller already in use\n"); + ret = -EBUSY; + goto err_put_hcd; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { + dev_dbg(&pdev->dev, "error mapping memory\n"); + ret = -EFAULT; + goto err_release_region; + } + + ohci_hcd_init(hcd_to_ohci(hcd)); + + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); + if (ret) + goto err_stop_hcd; + + return 0; + +err_stop_hcd: + iounmap(hcd->regs); +err_release_region: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err_put_hcd: + usb_put_hcd(hcd); + return ret; +} + +static int ohci_ath79_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_remove_hcd(hcd); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + + return 0; +} + +static struct platform_driver ohci_hcd_ath79_driver = { + .probe = ohci_ath79_probe, + .remove = ohci_ath79_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "ath79-ohci", + .owner = THIS_MODULE, + }, +}; + +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ohci"); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d55723514860..8c8dc6559ac7 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1105,6 +1105,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver #endif +#ifdef CONFIG_USB_OHCI_ATH79 +#include "ohci-ath79.c" +#define PLATFORM_DRIVER ohci_hcd_ath79_driver +#endif + #if !defined(PCI_DRIVER) && \ !defined(PLATFORM_DRIVER) && \ !defined(OMAP1_PLATFORM_DRIVER) && \ -- GitLab From db8fa2852ed5b46c05148db87be135300f17b8ce Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Thu, 14 Apr 2011 00:37:00 +0200 Subject: [PATCH 0913/5560] usb: gadget: storage_common: use kstrto*() This commit replaces the usage of strict_strtoul() (which became deprecated after commit 33ee3b2e) with kstrtouint(). Signed-off-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/storage_common.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 3179b8bb6ced..86fcebd89abe 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -704,10 +704,11 @@ static ssize_t fsg_store_ro(struct device *dev, struct device_attribute *attr, ssize_t rc = count; struct fsg_lun *curlun = fsg_lun_from_dev(dev); struct rw_semaphore *filesem = dev_get_drvdata(dev); - unsigned long ro; + unsigned ro; - if (strict_strtoul(buf, 2, &ro)) - return -EINVAL; + rc = kstrtouint(buf, 2, &ro); + if (rc) + return rc; /* * Allow the write-enable status to change only while the @@ -731,10 +732,12 @@ static ssize_t fsg_store_nofua(struct device *dev, const char *buf, size_t count) { struct fsg_lun *curlun = fsg_lun_from_dev(dev); - unsigned long nofua; + unsigned nofua; + int ret; - if (strict_strtoul(buf, 2, &nofua)) - return -EINVAL; + ret = kstrtouint(buf, 2, &nofua); + if (ret) + return ret; /* Sync data when switching from async mode to sync */ if (!nofua && curlun->nofua) -- GitLab From 97bd8e491d1786f0020372a5a470bb8b3184856f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Apr 2011 11:05:04 +0000 Subject: [PATCH 0914/5560] tg3: Provide full regdump on tx timeout The current amount of information provided in the output of a tx timeout is insufficient to determine a root cause. This patch replaces the terse, four-register status output with a more complete body of information. For PCIe devices, the full register space is dumped. For other devices, select registers are dumped instead. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 189 +++++++++++++++++++++++++++++----------------- drivers/net/tg3.h | 2 + 2 files changed, 123 insertions(+), 68 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 9d7defc2628d..72744353b1cb 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4459,6 +4459,123 @@ static inline int tg3_irq_sync(struct tg3 *tp) return tp->irq_sync; } +static inline void tg3_rd32_loop(struct tg3 *tp, u32 *dst, u32 off, u32 len) +{ + int i; + + dst = (u32 *)((u8 *)dst + off); + for (i = 0; i < len; i += sizeof(u32)) + *dst++ = tr32(off + i); +} + +static void tg3_dump_legacy_regs(struct tg3 *tp, u32 *regs) +{ + tg3_rd32_loop(tp, regs, TG3PCI_VENDOR, 0xb0); + tg3_rd32_loop(tp, regs, MAILBOX_INTERRUPT_0, 0x200); + tg3_rd32_loop(tp, regs, MAC_MODE, 0x4f0); + tg3_rd32_loop(tp, regs, SNDDATAI_MODE, 0xe0); + tg3_rd32_loop(tp, regs, SNDDATAC_MODE, 0x04); + tg3_rd32_loop(tp, regs, SNDBDS_MODE, 0x80); + tg3_rd32_loop(tp, regs, SNDBDI_MODE, 0x48); + tg3_rd32_loop(tp, regs, SNDBDC_MODE, 0x04); + tg3_rd32_loop(tp, regs, RCVLPC_MODE, 0x20); + tg3_rd32_loop(tp, regs, RCVLPC_SELLST_BASE, 0x15c); + tg3_rd32_loop(tp, regs, RCVDBDI_MODE, 0x0c); + tg3_rd32_loop(tp, regs, RCVDBDI_JUMBO_BD, 0x3c); + tg3_rd32_loop(tp, regs, RCVDBDI_BD_PROD_IDX_0, 0x44); + tg3_rd32_loop(tp, regs, RCVDCC_MODE, 0x04); + tg3_rd32_loop(tp, regs, RCVBDI_MODE, 0x20); + tg3_rd32_loop(tp, regs, RCVCC_MODE, 0x14); + tg3_rd32_loop(tp, regs, RCVLSC_MODE, 0x08); + tg3_rd32_loop(tp, regs, MBFREE_MODE, 0x08); + tg3_rd32_loop(tp, regs, HOSTCC_MODE, 0x100); + + if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) + tg3_rd32_loop(tp, regs, HOSTCC_RXCOL_TICKS_VEC1, 0x180); + + tg3_rd32_loop(tp, regs, MEMARB_MODE, 0x10); + tg3_rd32_loop(tp, regs, BUFMGR_MODE, 0x58); + tg3_rd32_loop(tp, regs, RDMAC_MODE, 0x08); + tg3_rd32_loop(tp, regs, WDMAC_MODE, 0x08); + tg3_rd32_loop(tp, regs, RX_CPU_MODE, 0x04); + tg3_rd32_loop(tp, regs, RX_CPU_STATE, 0x04); + tg3_rd32_loop(tp, regs, RX_CPU_PGMCTR, 0x04); + tg3_rd32_loop(tp, regs, RX_CPU_HWBKPT, 0x04); + + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { + tg3_rd32_loop(tp, regs, TX_CPU_MODE, 0x04); + tg3_rd32_loop(tp, regs, TX_CPU_STATE, 0x04); + tg3_rd32_loop(tp, regs, TX_CPU_PGMCTR, 0x04); + } + + tg3_rd32_loop(tp, regs, GRCMBOX_INTERRUPT_0, 0x110); + tg3_rd32_loop(tp, regs, FTQ_RESET, 0x120); + tg3_rd32_loop(tp, regs, MSGINT_MODE, 0x0c); + tg3_rd32_loop(tp, regs, DMAC_MODE, 0x04); + tg3_rd32_loop(tp, regs, GRC_MODE, 0x4c); + + if (tp->tg3_flags & TG3_FLAG_NVRAM) + tg3_rd32_loop(tp, regs, NVRAM_CMD, 0x24); +} + +static void tg3_dump_state(struct tg3 *tp) +{ + int i; + u32 *regs; + + regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC); + if (!regs) { + netdev_err(tp->dev, "Failed allocating register dump buffer\n"); + return; + } + + if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { + /* Read up to but not including private PCI registers */ + for (i = 0; i < TG3_PCIE_TLDLPL_PORT; i += sizeof(u32)) + regs[i / sizeof(u32)] = tr32(i); + } else + tg3_dump_legacy_regs(tp, regs); + + for (i = 0; i < TG3_REG_BLK_SIZE / sizeof(u32); i += 4) { + if (!regs[i + 0] && !regs[i + 1] && + !regs[i + 2] && !regs[i + 3]) + continue; + + netdev_err(tp->dev, "0x%08x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + i * 4, + regs[i + 0], regs[i + 1], regs[i + 2], regs[i + 3]); + } + + kfree(regs); + + for (i = 0; i < tp->irq_cnt; i++) { + struct tg3_napi *tnapi = &tp->napi[i]; + + /* SW status block */ + netdev_err(tp->dev, + "%d: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n", + i, + tnapi->hw_status->status, + tnapi->hw_status->status_tag, + tnapi->hw_status->rx_jumbo_consumer, + tnapi->hw_status->rx_consumer, + tnapi->hw_status->rx_mini_consumer, + tnapi->hw_status->idx[0].rx_producer, + tnapi->hw_status->idx[0].tx_consumer); + + netdev_err(tp->dev, + "%d: NAPI info [%08x:%08x:(%04x:%04x:%04x):%04x:(%04x:%04x:%04x:%04x)]\n", + i, + tnapi->last_tag, tnapi->last_irq_tag, + tnapi->tx_prod, tnapi->tx_cons, tnapi->tx_pending, + tnapi->rx_rcb_ptr, + tnapi->prodring.rx_std_prod_idx, + tnapi->prodring.rx_std_cons_idx, + tnapi->prodring.rx_jmb_prod_idx, + tnapi->prodring.rx_jmb_cons_idx); + } +} + /* This is called whenever we suspect that the system chipset is re- * ordering the sequence of MMIO to the tx send mailbox. The symptom * is bogus tx completions. We try to recover by setting the @@ -5516,21 +5633,13 @@ static void tg3_reset_task(struct work_struct *work) tg3_phy_start(tp); } -static void tg3_dump_short_state(struct tg3 *tp) -{ - netdev_err(tp->dev, "DEBUG: MAC_TX_STATUS[%08x] MAC_RX_STATUS[%08x]\n", - tr32(MAC_TX_STATUS), tr32(MAC_RX_STATUS)); - netdev_err(tp->dev, "DEBUG: RDMAC_STATUS[%08x] WDMAC_STATUS[%08x]\n", - tr32(RDMAC_STATUS), tr32(WDMAC_STATUS)); -} - static void tg3_tx_timeout(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); if (netif_msg_tx_err(tp)) { netdev_err(dev, "transmit timed out, resetting\n"); - tg3_dump_short_state(tp); + tg3_dump_state(tp); } schedule_work(&tp->reset_task); @@ -9624,82 +9733,26 @@ static void tg3_set_rx_mode(struct net_device *dev) tg3_full_unlock(tp); } -#define TG3_REGDUMP_LEN (32 * 1024) - static int tg3_get_regs_len(struct net_device *dev) { - return TG3_REGDUMP_LEN; + return TG3_REG_BLK_SIZE; } static void tg3_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) { - u32 *p = _p; struct tg3 *tp = netdev_priv(dev); - u8 *orig_p = _p; - int i; regs->version = 0; - memset(p, 0, TG3_REGDUMP_LEN); + memset(_p, 0, TG3_REG_BLK_SIZE); if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) return; tg3_full_lock(tp, 0); -#define __GET_REG32(reg) (*(p)++ = tr32(reg)) -#define GET_REG32_LOOP(base, len) \ -do { p = (u32 *)(orig_p + (base)); \ - for (i = 0; i < len; i += 4) \ - __GET_REG32((base) + i); \ -} while (0) -#define GET_REG32_1(reg) \ -do { p = (u32 *)(orig_p + (reg)); \ - __GET_REG32((reg)); \ -} while (0) - - GET_REG32_LOOP(TG3PCI_VENDOR, 0xb0); - GET_REG32_LOOP(MAILBOX_INTERRUPT_0, 0x200); - GET_REG32_LOOP(MAC_MODE, 0x4f0); - GET_REG32_LOOP(SNDDATAI_MODE, 0xe0); - GET_REG32_1(SNDDATAC_MODE); - GET_REG32_LOOP(SNDBDS_MODE, 0x80); - GET_REG32_LOOP(SNDBDI_MODE, 0x48); - GET_REG32_1(SNDBDC_MODE); - GET_REG32_LOOP(RCVLPC_MODE, 0x20); - GET_REG32_LOOP(RCVLPC_SELLST_BASE, 0x15c); - GET_REG32_LOOP(RCVDBDI_MODE, 0x0c); - GET_REG32_LOOP(RCVDBDI_JUMBO_BD, 0x3c); - GET_REG32_LOOP(RCVDBDI_BD_PROD_IDX_0, 0x44); - GET_REG32_1(RCVDCC_MODE); - GET_REG32_LOOP(RCVBDI_MODE, 0x20); - GET_REG32_LOOP(RCVCC_MODE, 0x14); - GET_REG32_LOOP(RCVLSC_MODE, 0x08); - GET_REG32_1(MBFREE_MODE); - GET_REG32_LOOP(HOSTCC_MODE, 0x100); - GET_REG32_LOOP(MEMARB_MODE, 0x10); - GET_REG32_LOOP(BUFMGR_MODE, 0x58); - GET_REG32_LOOP(RDMAC_MODE, 0x08); - GET_REG32_LOOP(WDMAC_MODE, 0x08); - GET_REG32_1(RX_CPU_MODE); - GET_REG32_1(RX_CPU_STATE); - GET_REG32_1(RX_CPU_PGMCTR); - GET_REG32_1(RX_CPU_HWBKPT); - GET_REG32_1(TX_CPU_MODE); - GET_REG32_1(TX_CPU_STATE); - GET_REG32_1(TX_CPU_PGMCTR); - GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110); - GET_REG32_LOOP(FTQ_RESET, 0x120); - GET_REG32_LOOP(MSGINT_MODE, 0x0c); - GET_REG32_1(DMAC_MODE); - GET_REG32_LOOP(GRC_MODE, 0x4c); - if (tp->tg3_flags & TG3_FLAG_NVRAM) - GET_REG32_LOOP(NVRAM_CMD, 0x24); - -#undef __GET_REG32 -#undef GET_REG32_LOOP -#undef GET_REG32_1 + tg3_dump_legacy_regs(tp, (u32 *)_p); tg3_full_unlock(tp); } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 829a84ad80f2..99120100bf6a 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1954,6 +1954,8 @@ #define TG3_PCIE_PL_LO_PHYCTL5 0x00000014 #define TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ 0x80000000 +#define TG3_REG_BLK_SIZE 0x00008000 + /* OTP bit definitions */ #define TG3_OTP_AGCTGT_MASK 0x000000e0 #define TG3_OTP_AGCTGT_SHIFT 1 -- GitLab From e64de4e6c660dae6d6370b3acb59d5d5cc9ecf20 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Apr 2011 11:05:05 +0000 Subject: [PATCH 0915/5560] tg3: Dump registers when status block shows errors This patch monitors the error bit of the status word within the status block. If it is set, the driver will dump the driver state after validating the error and then reset the chip. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 40 +++++++++++++++++++++++++++++++++++++++- drivers/net/tg3.h | 3 +++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 72744353b1cb..b61b52f0a9fb 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5259,6 +5259,40 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget) return work_done; } +static void tg3_process_error(struct tg3 *tp) +{ + u32 val; + bool real_error = false; + + if (tp->tg3_flags & TG3_FLAG_ERROR_PROCESSED) + return; + + /* Check Flow Attention register */ + val = tr32(HOSTCC_FLOW_ATTN); + if (val & ~HOSTCC_FLOW_ATTN_MBUF_LWM) { + netdev_err(tp->dev, "FLOW Attention error. Resetting chip.\n"); + real_error = true; + } + + if (tr32(MSGINT_STATUS) & ~MSGINT_STATUS_MSI_REQ) { + netdev_err(tp->dev, "MSI Status error. Resetting chip.\n"); + real_error = true; + } + + if (tr32(RDMAC_STATUS) || tr32(WDMAC_STATUS)) { + netdev_err(tp->dev, "DMA Status error. Resetting chip.\n"); + real_error = true; + } + + if (!real_error) + return; + + tg3_dump_state(tp); + + tp->tg3_flags |= TG3_FLAG_ERROR_PROCESSED; + schedule_work(&tp->reset_task); +} + static int tg3_poll(struct napi_struct *napi, int budget) { struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi); @@ -5267,6 +5301,9 @@ static int tg3_poll(struct napi_struct *napi, int budget) struct tg3_hw_status *sblk = tnapi->hw_status; while (1) { + if (sblk->status & SD_STATUS_ERROR) + tg3_process_error(tp); + tg3_poll_link(tp); work_done = tg3_poll_work(tnapi, work_done, budget); @@ -7316,7 +7353,8 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_restore_pci_state(tp); - tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING; + tp->tg3_flags &= ~(TG3_FLAG_CHIP_RESETTING | + TG3_FLAG_ERROR_PROCESSED); val = 0; if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 99120100bf6a..b3ccfcc9ffea 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1201,6 +1201,7 @@ #define HOSTCC_STATS_BLK_NIC_ADDR 0x00003c40 #define HOSTCC_STATUS_BLK_NIC_ADDR 0x00003c44 #define HOSTCC_FLOW_ATTN 0x00003c48 +#define HOSTCC_FLOW_ATTN_MBUF_LWM 0x00000040 /* 0x3c4c --> 0x3c50 unused */ #define HOSTCC_JUMBO_CON_IDX 0x00003c50 #define HOSTCC_STD_CON_IDX 0x00003c54 @@ -1611,6 +1612,7 @@ #define MSGINT_MODE_ONE_SHOT_DISABLE 0x00000020 #define MSGINT_MODE_MULTIVEC_EN 0x00000080 #define MSGINT_STATUS 0x00006004 +#define MSGINT_STATUS_MSI_REQ 0x00000001 #define MSGINT_FIFO 0x00006008 /* 0x600c --> 0x6400 unused */ @@ -2886,6 +2888,7 @@ struct tg3 { #define TG3_FLAG_TAGGED_STATUS 0x00000001 #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 +#define TG3_FLAG_ERROR_PROCESSED 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 #define TG3_FLAG_ASPM_WORKAROUND 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 -- GitLab From 48fa55a0a5e20b9e2a28a72c66c7027678cae6bb Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Apr 2011 11:05:06 +0000 Subject: [PATCH 0916/5560] tg3: Automatically size stat/test string arrays This patch reimplements the size preprocessor constants of the stats and ethtool test string arrays. The size is calculated at compile time rather than using static constants. Signed-off-by: Matt Carlson Signed-off-by: Benjamin Li Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b61b52f0a9fb..9975cdb38831 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -165,11 +165,6 @@ #define TG3_RAW_IP_ALIGN 2 -/* number of ETHTOOL_GSTATS u64's */ -#define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) - -#define TG3_NUM_TEST 6 - #define TG3_FW_UPDATE_TIMEOUT_SEC 5 #define FIRMWARE_TG3 "tigon/tg3.bin" @@ -279,7 +274,7 @@ MODULE_DEVICE_TABLE(pci, tg3_pci_tbl); static const struct { const char string[ETH_GSTRING_LEN]; -} ethtool_stats_keys[TG3_NUM_STATS] = { +} ethtool_stats_keys[] = { { "rx_octets" }, { "rx_fragments" }, { "rx_ucast_packets" }, @@ -358,9 +353,12 @@ static const struct { { "nic_tx_threshold_hit" } }; +#define TG3_NUM_STATS ARRAY_SIZE(ethtool_stats_keys) + + static const struct { const char string[ETH_GSTRING_LEN]; -} ethtool_test_keys[TG3_NUM_TEST] = { +} ethtool_test_keys[] = { { "nvram test (online) " }, { "link test (online) " }, { "register test (offline)" }, @@ -369,6 +367,9 @@ static const struct { { "interrupt test (offline)" }, }; +#define TG3_NUM_TEST ARRAY_SIZE(ethtool_test_keys) + + static void tg3_write32(struct tg3 *tp, u32 off, u32 val) { writel(val, tp->regs + off); -- GitLab From 4852a8614f63999e38539ad16615054dcd20a05d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Apr 2011 11:05:07 +0000 Subject: [PATCH 0917/5560] tg3: Add jumbo frame loopback tests to selftest This patch adds jumbo frame loopback test support to the ethtool selftest. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 9975cdb38831..52dd516ba786 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10935,7 +10935,7 @@ static int tg3_test_memory(struct tg3 *tp) #define TG3_MAC_LOOPBACK 0 #define TG3_PHY_LOOPBACK 1 -static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) +static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode) { u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key; u32 desc_idx, coal_now; @@ -11033,7 +11033,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) err = -EIO; - tx_len = 1514; + tx_len = pktsz; skb = netdev_alloc_skb(tp->dev, tx_len); if (!skb) return -ENOMEM; @@ -11042,7 +11042,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) memcpy(tx_data, tp->dev->dev_addr, 6); memset(tx_data + 6, 0x0, 8); - tw32(MAC_RX_MTU_SIZE, tx_len + 4); + tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN); for (i = 14; i < tx_len; i++) tx_data[i] = (u8) (i & 0xff); @@ -11098,8 +11098,6 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) desc = &rnapi->rx_rcb[rx_start_idx]; desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; - if (opaque_key != RXD_OPAQUE_RING_STD) - goto out; if ((desc->err_vlan & RXD_ERR_MASK) != 0 && (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) @@ -11109,9 +11107,20 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) if (rx_len != tx_len) goto out; - rx_skb = tpr->rx_std_buffers[desc_idx].skb; + if (pktsz <= TG3_RX_STD_DMA_SZ - ETH_FCS_LEN) { + if (opaque_key != RXD_OPAQUE_RING_STD) + goto out; + + rx_skb = tpr->rx_std_buffers[desc_idx].skb; + map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], mapping); + } else { + if (opaque_key != RXD_OPAQUE_RING_JUMBO) + goto out; + + rx_skb = tpr->rx_jmb_buffers[desc_idx].skb; + map = dma_unmap_addr(&tpr->rx_jmb_buffers[desc_idx], mapping); + } - map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], mapping); pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE); for (i = 14; i < tx_len; i++) { @@ -11177,9 +11186,13 @@ static int tg3_test_loopback(struct tg3 *tp) CPMU_CTRL_LINK_AWARE_MODE)); } - if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) + if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_MAC_LOOPBACK)) err |= TG3_MAC_LOOPBACK_FAILED; + if ((tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) && + tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_MAC_LOOPBACK)) + err |= (TG3_MAC_LOOPBACK_FAILED << 2); + if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) { tw32(TG3_CPMU_CTRL, cpmuctrl); @@ -11189,8 +11202,11 @@ static int tg3_test_loopback(struct tg3 *tp) if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) && !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) { - if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK)) + if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_PHY_LOOPBACK)) err |= TG3_PHY_LOOPBACK_FAILED; + if ((tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) && + tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_PHY_LOOPBACK)) + err |= (TG3_PHY_LOOPBACK_FAILED << 2); } /* Re-enable gphy autopowerdown. */ -- GitLab From c3e945006ab2295e9a3f4327aa74a502ad123fe6 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 13 Apr 2011 11:05:08 +0000 Subject: [PATCH 0918/5560] tg3: Add support for extended VPD blocks In some devices, the VPD block is relocated to a different area in NVRAM. The original location can still contain old, but still valid VPD data. This patch changes the code to look for an extended VPD block in NVRAM. If one is found, that block is used for all VPD operations instead. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Reviewed-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/tg3.c | 125 ++++++++++++++++++++++++++++++---------------- drivers/net/tg3.h | 2 + 2 files changed, 83 insertions(+), 44 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 52dd516ba786..10fa476fede3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10416,6 +10416,81 @@ static void tg3_get_ethtool_stats(struct net_device *dev, memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); } +static __be32 * tg3_vpd_readblock(struct tg3 *tp) +{ + int i; + __be32 *buf; + u32 offset = 0, len = 0; + u32 magic, val; + + if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || + tg3_nvram_read(tp, 0, &magic)) + return NULL; + + if (magic == TG3_EEPROM_MAGIC) { + for (offset = TG3_NVM_DIR_START; + offset < TG3_NVM_DIR_END; + offset += TG3_NVM_DIRENT_SIZE) { + if (tg3_nvram_read(tp, offset, &val)) + return NULL; + + if ((val >> TG3_NVM_DIRTYPE_SHIFT) == + TG3_NVM_DIRTYPE_EXTVPD) + break; + } + + if (offset != TG3_NVM_DIR_END) { + len = (val & TG3_NVM_DIRTYPE_LENMSK) * 4; + if (tg3_nvram_read(tp, offset + 4, &offset)) + return NULL; + + offset = tg3_nvram_logical_addr(tp, offset); + } + } + + if (!offset || !len) { + offset = TG3_NVM_VPD_OFF; + len = TG3_NVM_VPD_LEN; + } + + buf = kmalloc(len, GFP_KERNEL); + if (buf == NULL) + return NULL; + + if (magic == TG3_EEPROM_MAGIC) { + for (i = 0; i < len; i += 4) { + /* The data is in little-endian format in NVRAM. + * Use the big-endian read routines to preserve + * the byte order as it exists in NVRAM. + */ + if (tg3_nvram_read_be32(tp, offset + i, &buf[i/4])) + goto error; + } + } else { + u8 *ptr; + ssize_t cnt; + unsigned int pos = 0; + + ptr = (u8 *)&buf[0]; + for (i = 0; pos < len && i < 3; i++, pos += cnt, ptr += cnt) { + cnt = pci_read_vpd(tp->pdev, pos, + len - pos, ptr); + if (cnt == -ETIMEDOUT || cnt == -EINTR) + cnt = 0; + else if (cnt < 0) + goto error; + } + if (pos != len) + goto error; + } + + return buf; + +error: + kfree(buf); + return NULL; +} + #define NVRAM_TEST_SIZE 0x100 #define NVRAM_SELFBOOT_FORMAT1_0_SIZE 0x14 #define NVRAM_SELFBOOT_FORMAT1_2_SIZE 0x18 @@ -10555,14 +10630,11 @@ static int tg3_test_nvram(struct tg3 *tp) if (csum != le32_to_cpu(buf[0xfc/4])) goto out; - for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) { - /* The data is in little-endian format in NVRAM. - * Use the big-endian read routines to preserve - * the byte order as it exists in NVRAM. - */ - if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &buf[i/4])) - goto out; - } + kfree(buf); + + buf = tg3_vpd_readblock(tp); + if (!buf) + return -ENOMEM; i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN, PCI_VPD_LRDT_RO_DATA); @@ -12905,46 +12977,11 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) u8 *vpd_data; unsigned int block_end, rosize, len; int j, i = 0; - u32 magic; - - if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || - tg3_nvram_read(tp, 0x0, &magic)) - goto out_no_vpd; - vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL); + vpd_data = (u8 *)tg3_vpd_readblock(tp); if (!vpd_data) goto out_no_vpd; - if (magic == TG3_EEPROM_MAGIC) { - for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) { - u32 tmp; - - /* The data is in little-endian format in NVRAM. - * Use the big-endian read routines to preserve - * the byte order as it exists in NVRAM. - */ - if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &tmp)) - goto out_not_found; - - memcpy(&vpd_data[i], &tmp, sizeof(tmp)); - } - } else { - ssize_t cnt; - unsigned int pos = 0; - - for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) { - cnt = pci_read_vpd(tp->pdev, pos, - TG3_NVM_VPD_LEN - pos, - &vpd_data[pos]); - if (cnt == -ETIMEDOUT || cnt == -EINTR) - cnt = 0; - else if (cnt < 0) - goto out_not_found; - } - if (pos != TG3_NVM_VPD_LEN) - goto out_not_found; - } - i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN, PCI_VPD_LRDT_RO_DATA); if (i < 0) diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index b3ccfcc9ffea..224c3e0ec695 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2009,7 +2009,9 @@ #define TG3_NVM_DIR_END 0x78 #define TG3_NVM_DIRENT_SIZE 0xc #define TG3_NVM_DIRTYPE_SHIFT 24 +#define TG3_NVM_DIRTYPE_LENMSK 0x003fffff #define TG3_NVM_DIRTYPE_ASFINI 1 +#define TG3_NVM_DIRTYPE_EXTVPD 20 #define TG3_NVM_PTREV_BCVER 0x94 #define TG3_NVM_BCVER_MAJMSK 0x0000ff00 #define TG3_NVM_BCVER_MAJSFT 8 -- GitLab From c326de88b8ac7ed1cd1027017ba6079dbe91be49 Mon Sep 17 00:00:00 2001 From: "Mathieu J. Poirier" Date: Wed, 13 Apr 2011 17:13:00 -0700 Subject: [PATCH 0919/5560] net: allow shifted access in smsc911x V2 This is a revised patch that permits a shifted access to the LAN9221 registers. More specifically: It adds a shift parameter in the platform_data. It introduces an ops in smsc911x_data. A choice of access function to use at run-time. Four new shifted access function. Signed-off-by: Mathieu Poirier Signed-off-by: Alessandro Rubini Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 156 +++++++++++++++++++++++++++++++++++++-- include/linux/smsc911x.h | 1 + 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index b8faab7780da..c6d47d10590c 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -71,6 +71,17 @@ static int debug = 3; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); +struct smsc911x_data; + +struct smsc911x_ops { + u32 (*reg_read)(struct smsc911x_data *pdata, u32 reg); + void (*reg_write)(struct smsc911x_data *pdata, u32 reg, u32 val); + void (*rx_readfifo)(struct smsc911x_data *pdata, + unsigned int *buf, unsigned int wordcount); + void (*tx_writefifo)(struct smsc911x_data *pdata, + unsigned int *buf, unsigned int wordcount); +}; + struct smsc911x_data { void __iomem *ioaddr; @@ -118,8 +129,14 @@ struct smsc911x_data { unsigned int clear_bits_mask; unsigned int hashhi; unsigned int hashlo; + + /* register access functions */ + const struct smsc911x_ops *ops; }; +/* Easy access to information */ +#define __smsc_shift(pdata, reg) ((reg) << ((pdata)->config.shift)) + static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) { if (pdata->config.flags & SMSC911X_USE_32BIT) @@ -133,13 +150,29 @@ static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) return 0; } +static inline u32 +__smsc911x_reg_read_shift(struct smsc911x_data *pdata, u32 reg) +{ + if (pdata->config.flags & SMSC911X_USE_32BIT) + return readl(pdata->ioaddr + __smsc_shift(pdata, reg)); + + if (pdata->config.flags & SMSC911X_USE_16BIT) + return (readw(pdata->ioaddr + + __smsc_shift(pdata, reg)) & 0xFFFF) | + ((readw(pdata->ioaddr + + __smsc_shift(pdata, reg + 2)) & 0xFFFF) << 16); + + BUG(); + return 0; +} + static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) { u32 data; unsigned long flags; spin_lock_irqsave(&pdata->dev_lock, flags); - data = __smsc911x_reg_read(pdata, reg); + data = pdata->ops->reg_read(pdata, reg); spin_unlock_irqrestore(&pdata->dev_lock, flags); return data; @@ -162,13 +195,32 @@ static inline void __smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, BUG(); } +static inline void +__smsc911x_reg_write_shift(struct smsc911x_data *pdata, u32 reg, u32 val) +{ + if (pdata->config.flags & SMSC911X_USE_32BIT) { + writel(val, pdata->ioaddr + __smsc_shift(pdata, reg)); + return; + } + + if (pdata->config.flags & SMSC911X_USE_16BIT) { + writew(val & 0xFFFF, + pdata->ioaddr + __smsc_shift(pdata, reg)); + writew((val >> 16) & 0xFFFF, + pdata->ioaddr + __smsc_shift(pdata, reg + 2)); + return; + } + + BUG(); +} + static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg, u32 val) { unsigned long flags; spin_lock_irqsave(&pdata->dev_lock, flags); - __smsc911x_reg_write(pdata, reg, val); + pdata->ops->reg_write(pdata, reg, val); spin_unlock_irqrestore(&pdata->dev_lock, flags); } @@ -204,6 +256,40 @@ smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf, spin_unlock_irqrestore(&pdata->dev_lock, flags); } +/* Writes a packet to the TX_DATA_FIFO - shifted version */ +static inline void +smsc911x_tx_writefifo_shift(struct smsc911x_data *pdata, unsigned int *buf, + unsigned int wordcount) +{ + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + __smsc911x_reg_write_shift(pdata, TX_DATA_FIFO, + swab32(*buf++)); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_32BIT) { + writesl(pdata->ioaddr + __smsc_shift(pdata, + TX_DATA_FIFO), buf, wordcount); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_16BIT) { + while (wordcount--) + __smsc911x_reg_write_shift(pdata, + TX_DATA_FIFO, *buf++); + goto out; + } + + BUG(); +out: + spin_unlock_irqrestore(&pdata->dev_lock, flags); +} + /* Reads a packet out of the RX_DATA_FIFO */ static inline void smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, @@ -236,6 +322,40 @@ smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, spin_unlock_irqrestore(&pdata->dev_lock, flags); } +/* Reads a packet out of the RX_DATA_FIFO - shifted version */ +static inline void +smsc911x_rx_readfifo_shift(struct smsc911x_data *pdata, unsigned int *buf, + unsigned int wordcount) +{ + unsigned long flags; + + spin_lock_irqsave(&pdata->dev_lock, flags); + + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + *buf++ = swab32(__smsc911x_reg_read_shift(pdata, + RX_DATA_FIFO)); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_32BIT) { + readsl(pdata->ioaddr + __smsc_shift(pdata, + RX_DATA_FIFO), buf, wordcount); + goto out; + } + + if (pdata->config.flags & SMSC911X_USE_16BIT) { + while (wordcount--) + *buf++ = __smsc911x_reg_read_shift(pdata, + RX_DATA_FIFO); + goto out; + } + + BUG(); +out: + spin_unlock_irqrestore(&pdata->dev_lock, flags); +} + /* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read * and smsc911x_mac_write, so assumes mac_lock is held */ static int smsc911x_mac_complete(struct smsc911x_data *pdata) @@ -500,7 +620,7 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) wrsz += (u32)((ulong)pdata->loopback_tx_pkt & 0x3); wrsz >>= 2; - smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); + pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz); /* Wait till transmit is done */ i = 60; @@ -544,7 +664,7 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) rdsz += (u32)((ulong)pdata->loopback_rx_pkt & 0x3); rdsz >>= 2; - smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz); + pdata->ops->rx_readfifo(pdata, (unsigned int *)bufp, rdsz); if (pktlength != (MIN_PACKET_SIZE + 4)) { SMSC_WARN(pdata, hw, "Unexpected packet size " @@ -1046,8 +1166,8 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) /* Align IP on 16B boundary */ skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pktlength - 4); - smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head, - pktwords); + pdata->ops->rx_readfifo(pdata, + (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); skb_checksum_none_assert(skb); netif_receive_skb(skb); @@ -1351,7 +1471,7 @@ static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) wrsz += (u32)((ulong)skb->data & 0x3); wrsz >>= 2; - smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); + pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz); freespace -= (skb->len + 32); dev_kfree_skb(skb); @@ -1957,6 +2077,22 @@ static int __devexit smsc911x_drv_remove(struct platform_device *pdev) return 0; } +/* standard register acces */ +static const struct smsc911x_ops standard_smsc911x_ops = { + .reg_read = __smsc911x_reg_read, + .reg_write = __smsc911x_reg_write, + .rx_readfifo = smsc911x_rx_readfifo, + .tx_writefifo = smsc911x_tx_writefifo, +}; + +/* shifted register access */ +static const struct smsc911x_ops shifted_smsc911x_ops = { + .reg_read = __smsc911x_reg_read_shift, + .reg_write = __smsc911x_reg_write_shift, + .rx_readfifo = smsc911x_rx_readfifo_shift, + .tx_writefifo = smsc911x_tx_writefifo_shift, +}; + static int __devinit smsc911x_drv_probe(struct platform_device *pdev) { struct net_device *dev; @@ -2026,6 +2162,12 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) goto out_free_netdev_2; } + /* assume standard, non-shifted, access to HW registers */ + pdata->ops = &standard_smsc911x_ops; + /* apply the right access if shifting is needed */ + if (config->shift) + pdata->ops = &shifted_smsc911x_ops; + retval = smsc911x_init(dev); if (retval < 0) goto out_unmap_io_3; diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h index 7144e8aa1e41..4dde70e74822 100644 --- a/include/linux/smsc911x.h +++ b/include/linux/smsc911x.h @@ -29,6 +29,7 @@ struct smsc911x_platform_config { unsigned int irq_polarity; unsigned int irq_type; unsigned int flags; + unsigned int shift; phy_interface_t phy_interface; unsigned char mac[6]; }; -- GitLab From 7c158399c21e4eabb33965a5fc689ebbd2ded4f6 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Sat, 12 Mar 2011 11:56:02 +0000 Subject: [PATCH 0920/5560] igb: Add anti-spoofing feature documentation Add the documentation for the anti-spoofing feature in the HW. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- Documentation/networking/igb.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/networking/igb.txt b/Documentation/networking/igb.txt index 98953c0d5342..9a2a037194a5 100644 --- a/Documentation/networking/igb.txt +++ b/Documentation/networking/igb.txt @@ -93,6 +93,19 @@ 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. + 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. + Support ======= -- GitLab From 34a0326e3aaf1d67fe3de55e77e92961c6a9a847 Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Tue, 5 Apr 2011 04:27:05 +0000 Subject: [PATCH 0921/5560] igb: fix typo in igb_validate_nvm_checksum_82580 Comment spelling fix. Signed-off-by: Stefan Assmann Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 6b256c275e10..0cd41c49bc17 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -1877,7 +1877,7 @@ static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw) } if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) { - /* if chekcsums compatibility bit is set validate checksums + /* if checksums compatibility bit is set validate checksums * for all 4 ports. */ eeprom_regions_count = 4; } @@ -1988,6 +1988,7 @@ static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw) out: return ret_val; } + /** * igb_set_eee_i350 - Enable/disable EEE support * @hw: pointer to the HW structure -- GitLab From 563988dcfe706457ec7049d59e18d6147179bb0a Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Tue, 5 Apr 2011 04:27:15 +0000 Subject: [PATCH 0922/5560] igb: introduce igb_thermal_sensor_event for sensor checking The code for thermal sensor checking should be wrapped into a function. Signed-off-by: Stefan Assmann Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 67 +++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0dfd1b93829e..cdfd57271051 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3532,6 +3532,25 @@ bool igb_has_link(struct igb_adapter *adapter) return link_active; } +static bool igb_thermal_sensor_event(struct e1000_hw *hw, u32 event) +{ + bool ret = false; + u32 ctrl_ext, thstat; + + /* check for thermal sensor event on i350, copper only */ + if (hw->mac.type == e1000_i350) { + thstat = rd32(E1000_THSTAT); + ctrl_ext = rd32(E1000_CTRL_EXT); + + if ((hw->phy.media_type == e1000_media_type_copper) && + !(ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII)) { + ret = !!(thstat & event); + } + } + + return ret; +} + /** * igb_watchdog - Timer Call-back * @data: pointer to adapter cast into an unsigned long @@ -3550,7 +3569,7 @@ static void igb_watchdog_task(struct work_struct *work) watchdog_task); struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; - u32 link, ctrl_ext, thstat; + u32 link; int i; link = igb_has_link(adapter); @@ -3574,25 +3593,14 @@ static void igb_watchdog_task(struct work_struct *work) ((ctrl & E1000_CTRL_RFCE) ? "RX" : ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None"))); - /* check for thermal sensor event on i350, - * copper only */ - if (hw->mac.type == e1000_i350) { - thstat = rd32(E1000_THSTAT); - ctrl_ext = rd32(E1000_CTRL_EXT); - if ((hw->phy.media_type == - e1000_media_type_copper) && !(ctrl_ext & - E1000_CTRL_EXT_LINK_MODE_SGMII)) { - if (thstat & - E1000_THSTAT_LINK_THROTTLE) { - printk(KERN_INFO "igb: %s The " - "network adapter link " - "speed was downshifted " - "because it " - "overheated.\n", - netdev->name); - } - } + /* check for thermal sensor event */ + if (igb_thermal_sensor_event(hw, E1000_THSTAT_LINK_THROTTLE)) { + printk(KERN_INFO "igb: %s The network adapter " + "link speed was downshifted " + "because it overheated.\n", + netdev->name); } + /* adjust timeout factor according to speed/duplex */ adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { @@ -3618,22 +3626,15 @@ static void igb_watchdog_task(struct work_struct *work) if (netif_carrier_ok(netdev)) { adapter->link_speed = 0; adapter->link_duplex = 0; - /* check for thermal sensor event on i350 - * copper only*/ - if (hw->mac.type == e1000_i350) { - thstat = rd32(E1000_THSTAT); - ctrl_ext = rd32(E1000_CTRL_EXT); - if ((hw->phy.media_type == - e1000_media_type_copper) && !(ctrl_ext & - E1000_CTRL_EXT_LINK_MODE_SGMII)) { - if (thstat & E1000_THSTAT_PWR_DOWN) { - printk(KERN_ERR "igb: %s The " - "network adapter was stopped " - "because it overheated.\n", + + /* check for thermal sensor event */ + if (igb_thermal_sensor_event(hw, E1000_THSTAT_PWR_DOWN)) { + printk(KERN_ERR "igb: %s The network adapter " + "was stopped because it " + "overheated.\n", netdev->name); - } - } } + /* Links status message must follow this format */ printk(KERN_INFO "igb: %s NIC Link is Down\n", netdev->name); -- GitLab From 1bba4386ab4f67a53c9649268dd9c83bc6110a9b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 19 Mar 2011 00:27:20 +0000 Subject: [PATCH 0923/5560] e1000e: convert short duration msleep() to usleep_range() With durations less than 20ms, the jiffies or legacy timer backed msleep() may sleep ~20ms which might not be what the caller expects. Instead, it is recommended to use the hrtimers backed usleep_range(). For more, see Documentation/timers/timers-howto.txt. Issues reported by checkpatch. In addition, remove unnecessary sleep in e1000e_write_nvm_spi(). Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 10 +++++----- drivers/net/e1000e/es2lan.c | 4 ++-- drivers/net/e1000e/ethtool.c | 20 ++++++++++---------- drivers/net/e1000e/ich8lan.c | 12 ++++++------ drivers/net/e1000e/lib.c | 10 ++++------ drivers/net/e1000e/netdev.c | 8 ++++---- drivers/net/e1000e/phy.c | 4 ++-- 7 files changed, 33 insertions(+), 35 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 89a69035e538..9fedbca66dfd 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -594,7 +594,7 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - msleep(2); + usleep_range(2000, 4000); i++; } while (i < MDIO_OWNERSHIP_TIMEOUT); @@ -816,7 +816,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) /* Check for pending operations. */ for (i = 0; i < E1000_FLASH_UPDATES; i++) { - msleep(1); + usleep_range(1000, 2000); if ((er32(EECD) & E1000_EECD_FLUPD) == 0) break; } @@ -840,7 +840,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) ew32(EECD, eecd); for (i = 0; i < E1000_FLASH_UPDATES; i++) { - msleep(1); + usleep_range(1000, 2000); if ((er32(EECD) & E1000_EECD_FLUPD) == 0) break; } @@ -930,7 +930,7 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) if (er32(EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0) break; - msleep(1); + usleep_range(1000, 2000); timeout--; } if (!timeout) { @@ -1037,7 +1037,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ew32(TCTL, E1000_TCTL_PSP); e1e_flush(); - msleep(10); + usleep_range(10000, 20000); /* * Must acquire the MDIO ownership before MAC reset. diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 2fefa820302b..0279695b6942 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -612,7 +612,7 @@ static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) while (timeout) { if (er32(EEMNGCTL) & mask) break; - msleep(1); + usleep_range(1000, 2000); timeout--; } if (!timeout) { @@ -802,7 +802,7 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) ew32(TCTL, E1000_TCTL_PSP); e1e_flush(); - msleep(10); + usleep_range(10000, 20000); ctrl = er32(CTRL); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 07f09e96e453..5b4cf9076bac 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -253,7 +253,7 @@ static int e1000_set_settings(struct net_device *netdev, } while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (ecmd->autoneg == AUTONEG_ENABLE) { hw->mac.autoneg = 1; @@ -317,7 +317,7 @@ static int e1000_set_pauseparam(struct net_device *netdev, adapter->fc_autoneg = pause->autoneg; while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (adapter->fc_autoneg == AUTONEG_ENABLE) { hw->fc.requested_mode = e1000_fc_default; @@ -673,7 +673,7 @@ static int e1000_set_ringparam(struct net_device *netdev, return -EINVAL; while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (netif_running(adapter->netdev)) e1000e_down(adapter); @@ -952,7 +952,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); - msleep(10); + usleep_range(10000, 20000); /* Test each interrupt */ for (i = 0; i < 10; i++) { @@ -984,7 +984,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMC, mask); ew32(ICS, mask); - msleep(10); + usleep_range(10000, 20000); if (adapter->test_icr & mask) { *data = 3; @@ -1002,7 +1002,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMS, mask); ew32(ICS, mask); - msleep(10); + usleep_range(10000, 20000); if (!(adapter->test_icr & mask)) { *data = 4; @@ -1020,7 +1020,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMC, ~mask & 0x00007FFF); ew32(ICS, ~mask & 0x00007FFF); - msleep(10); + usleep_range(10000, 20000); if (adapter->test_icr) { *data = 5; @@ -1031,7 +1031,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); - msleep(10); + usleep_range(10000, 20000); /* Unhook test interrupt handler */ free_irq(irq, netdev); @@ -1406,7 +1406,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) */ #define E1000_SERDES_LB_ON 0x410 ew32(SCTL, E1000_SERDES_LB_ON); - msleep(10); + usleep_range(10000, 20000); return 0; } @@ -1501,7 +1501,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter) hw->phy.media_type == e1000_media_type_internal_serdes) { #define E1000_SERDES_LB_OFF 0x400 ew32(SCTL, E1000_SERDES_LB_OFF); - msleep(10); + usleep_range(10000, 20000); break; } /* Fall Through */ diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index ce1dbfdca112..06ff884bc2c7 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -338,7 +338,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) /* Ungate automatic PHY configuration on non-managed 82579 */ if ((hw->mac.type == e1000_pch2lan) && !(fwsm & E1000_ICH_FWSM_FW_VALID)) { - msleep(10); + usleep_range(10000, 20000); e1000_gate_hw_phy_config_ich8lan(hw, false); } @@ -427,7 +427,7 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) phy->id = 0; while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) && (i++ < 100)) { - msleep(1); + usleep_range(1000, 2000); ret_val = e1000e_get_phy_id(hw); if (ret_val) return ret_val; @@ -1704,7 +1704,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) goto out; /* Allow time for h/w to get to quiescent state after reset */ - msleep(10); + usleep_range(10000, 20000); /* Perform any necessary post-reset workarounds */ switch (hw->mac.type) { @@ -1737,7 +1737,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) if (hw->mac.type == e1000_pch2lan) { /* Ungate automatic PHY configuration on non-managed 82579 */ if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { - msleep(10); + usleep_range(10000, 20000); e1000_gate_hw_phy_config_ich8lan(hw, false); } @@ -2532,7 +2532,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) */ if (!ret_val) { e1000e_reload_nvm(hw); - msleep(10); + usleep_range(10000, 20000); } out: @@ -3009,7 +3009,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ew32(TCTL, E1000_TCTL_PSP); e1e_flush(); - msleep(10); + usleep_range(10000, 20000); /* Workaround for ICH8 bit corruption issue in FIFO memory */ if (hw->mac.type == e1000_ich8lan) { diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 96921de5df2e..30ef8fa4968c 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -868,7 +868,7 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) * milliseconds even if the other end is doing it in SW). */ for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { - msleep(10); + usleep_range(10000, 20000); status = er32(STATUS); if (status & E1000_STATUS_LU) break; @@ -930,7 +930,7 @@ s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw) ew32(CTRL, ctrl); e1e_flush(); - msleep(1); + usleep_range(1000, 2000); /* * For these adapters, the SW definable pin 1 is set when the optics @@ -1385,7 +1385,7 @@ s32 e1000e_get_auto_rd_done(struct e1000_hw *hw) while (i < AUTO_READ_DONE_TIMEOUT) { if (er32(EECD) & E1000_EECD_AUTO_RD) break; - msleep(1); + usleep_range(1000, 2000); i++; } @@ -2087,8 +2087,6 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) if (ret_val) return ret_val; - msleep(10); - while (widx < words) { u8 write_opcode = NVM_WRITE_OPCODE_SPI; @@ -2132,7 +2130,7 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) } } - msleep(10); + usleep_range(10000, 20000); nvm->ops.release(hw); return 0; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 506a0a0043b3..909c8de58c15 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2902,7 +2902,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e1e_flush(); - msleep(10); + usleep_range(10000, 20000); if (adapter->flags2 & FLAG2_DMA_BURST) { /* @@ -3383,7 +3383,7 @@ void e1000e_down(struct e1000_adapter *adapter) ew32(TCTL, tctl); /* flush both disables and wait for them to finish */ e1e_flush(); - msleep(10); + usleep_range(10000, 20000); napi_disable(&adapter->napi); e1000_irq_disable(adapter); @@ -3418,7 +3418,7 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter) { might_sleep(); while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); e1000e_down(adapter); e1000e_up(adapter); clear_bit(__E1000_RESETTING, &adapter->state); @@ -5028,7 +5028,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) } while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ adapter->max_frame_size = max_frame; e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 6ae31fcfb629..484774c13c21 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -2372,7 +2372,7 @@ s32 e1000e_determine_phy_address(struct e1000_hw *hw) ret_val = 0; goto out; } - msleep(1); + usleep_range(1000, 2000); i++; } while (i < 10); } @@ -2740,7 +2740,7 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw) e1e_rphy(hw, PHY_CONTROL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; e1e_wphy(hw, PHY_CONTROL, mii_reg); - msleep(1); + usleep_range(1000, 2000); } /** -- GitLab From a5cc764206a3d01dce8ebc17b4e1534afb53c495 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 19 Mar 2011 00:31:23 +0000 Subject: [PATCH 0924/5560] e1000e: PCIe link speed in GT/s, not GB/s Correct the log message when driver loads. Signed-off-by: Bruce Allan Tested-by: Aaron Brown 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 909c8de58c15..99c8c7c0b1fb 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5714,7 +5714,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) u8 pba_str[E1000_PBANUM_LENGTH]; /* print bus type/speed/width info */ - e_info("(PCI Express:2.5GB/s:%s) %pM\n", + e_info("(PCI Express:2.5GT/s:%s) %pM\n", /* bus width */ ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : "Width x1"), -- GitLab From 86d70e532c352bd309dab5f1d18d113f441cb3ae Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 25 Mar 2011 16:01:01 +0000 Subject: [PATCH 0925/5560] e1000e: convert to new VLAN model This switches the e1000e driver to use the new VLAN interfaces. CC: Jesse Gross Signed-off-by: Jeff Kirsher Tested-by: Jeff Pieper --- drivers/net/e1000e/e1000.h | 4 +- drivers/net/e1000e/ethtool.c | 26 ++++++ drivers/net/e1000e/netdev.c | 170 ++++++++++++++++++----------------- 3 files changed, 119 insertions(+), 81 deletions(-) diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 00bf595ebd67..500896e42206 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -31,6 +31,7 @@ #ifndef _E1000_H_ #define _E1000_H_ +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include #include "hw.h" @@ -280,7 +282,7 @@ struct e1000_adapter { const struct e1000_info *ei; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u32 bd_number; u32 rx_buffer_len; u16 mng_vlan_id; diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 5b4cf9076bac..a31d280ffb6d 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -2020,6 +2020,31 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, } } +static int e1000e_set_flags(struct net_device *netdev, u32 data) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + bool need_reset = false; + int rc; + + need_reset = (data & ETH_FLAG_RXVLAN) != + (netdev->features & NETIF_F_HW_VLAN_RX); + + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN); + + if (rc) + return rc; + + if (need_reset) { + if (netif_running(netdev)) + e1000e_reinit_locked(adapter); + else + e1000e_reset(adapter); + } + + return 0; +} + static const struct ethtool_ops e1000_ethtool_ops = { .get_settings = e1000_get_settings, .set_settings = e1000_set_settings, @@ -2055,6 +2080,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { .get_coalesce = e1000_get_coalesce, .set_coalesce = e1000_set_coalesce, .get_flags = ethtool_op_get_flags, + .set_flags = e1000e_set_flags, }; void e1000e_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 99c8c7c0b1fb..8812eb28e099 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -459,13 +459,13 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, struct net_device *netdev, struct sk_buff *skb, u8 status, __le16 vlan) { + u16 tag = le16_to_cpu(vlan); skb->protocol = eth_type_trans(skb, netdev); - if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) - vlan_gro_receive(&adapter->napi, adapter->vlgrp, - le16_to_cpu(vlan), skb); - else - napi_gro_receive(&adapter->napi, skb); + if (status & E1000_RXD_STAT_VP) + __vlan_hwaccel_put_tag(skb, tag); + + napi_gro_receive(&adapter->napi, skb); } /** @@ -2433,6 +2433,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid) vfta |= (1 << (vid & 0x1F)); hw->mac.ops.write_vfta(hw, index, vfta); } + + set_bit(vid, adapter->active_vlans); } static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -2441,13 +2443,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct e1000_hw *hw = &adapter->hw; u32 vfta, index; - if (!test_bit(__E1000_DOWN, &adapter->state)) - e1000_irq_disable(adapter); - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__E1000_DOWN, &adapter->state)) - e1000_irq_enable(adapter); - if ((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && (vid == adapter->mng_vlan_id)) { @@ -2463,93 +2458,105 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) vfta &= ~(1 << (vid & 0x1F)); hw->mac.ops.write_vfta(hw, index, vfta); } + + clear_bit(vid, adapter->active_vlans); } -static void e1000_update_mng_vlan(struct e1000_adapter *adapter) +/** + * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering + * @adapter: board private structure to initialize + **/ +static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - u16 vid = adapter->hw.mng_cookie.vlan_id; - u16 old_vid = adapter->mng_vlan_id; - - if (!adapter->vlgrp) - return; + struct e1000_hw *hw = &adapter->hw; + u32 rctl; - if (!vlan_group_get_device(adapter->vlgrp, vid)) { - adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - if (adapter->hw.mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { - e1000_vlan_rx_add_vid(netdev, vid); - adapter->mng_vlan_id = vid; + if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { + /* disable VLAN receive filtering */ + rctl = er32(RCTL); + rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN); + ew32(RCTL, rctl); + + if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) { + e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); + adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; } - - if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && - (vid != old_vid) && - !vlan_group_get_device(adapter->vlgrp, old_vid)) - e1000_vlan_rx_kill_vid(netdev, old_vid); - } else { - adapter->mng_vlan_id = vid; } } +/** + * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering + * @adapter: board private structure to initialize + **/ +static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 rctl; + + if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { + /* enable VLAN receive filtering */ + rctl = er32(RCTL); + rctl |= E1000_RCTL_VFE; + rctl &= ~E1000_RCTL_CFIEN; + ew32(RCTL, rctl); + } +} -static void e1000_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) +/** + * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping + * @adapter: board private structure to initialize + **/ +static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter) { - struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 ctrl, rctl; + u32 ctrl; - if (!test_bit(__E1000_DOWN, &adapter->state)) - e1000_irq_disable(adapter); - adapter->vlgrp = grp; + /* disable VLAN tag insert/strip */ + ctrl = er32(CTRL); + ctrl &= ~E1000_CTRL_VME; + ew32(CTRL, ctrl); +} - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_VME; - ew32(CTRL, ctrl); +/** + * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping + * @adapter: board private structure to initialize + **/ +static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 ctrl; - if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { - /* enable VLAN receive filtering */ - rctl = er32(RCTL); - rctl &= ~E1000_RCTL_CFIEN; - ew32(RCTL, rctl); - e1000_update_mng_vlan(adapter); - } - } else { - /* disable VLAN tag insert/strip */ - ctrl = er32(CTRL); - ctrl &= ~E1000_CTRL_VME; - ew32(CTRL, ctrl); + /* enable VLAN tag insert/strip */ + ctrl = er32(CTRL); + ctrl |= E1000_CTRL_VME; + ew32(CTRL, ctrl); +} - if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { - if (adapter->mng_vlan_id != - (u16)E1000_MNG_VLAN_NONE) { - e1000_vlan_rx_kill_vid(netdev, - adapter->mng_vlan_id); - adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; - } - } +static void e1000_update_mng_vlan(struct e1000_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + u16 vid = adapter->hw.mng_cookie.vlan_id; + u16 old_vid = adapter->mng_vlan_id; + + if (adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { + e1000_vlan_rx_add_vid(netdev, vid); + adapter->mng_vlan_id = vid; } - if (!test_bit(__E1000_DOWN, &adapter->state)) - e1000_irq_enable(adapter); + if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid)) + e1000_vlan_rx_kill_vid(netdev, old_vid); } static void e1000_restore_vlan(struct e1000_adapter *adapter) { u16 vid; - e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp); - - if (!adapter->vlgrp) - return; + e1000_vlan_rx_add_vid(adapter->netdev, 0); - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) e1000_vlan_rx_add_vid(adapter->netdev, vid); - } } static void e1000_init_manageability_pt(struct e1000_adapter *adapter) @@ -3039,6 +3046,8 @@ static void e1000_set_multi(struct net_device *netdev) if (netdev->flags & IFF_PROMISC) { rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); rctl &= ~E1000_RCTL_VFE; + /* Do not hardware filter VLANs in promisc mode */ + e1000e_vlan_filter_disable(adapter); } else { if (netdev->flags & IFF_ALLMULTI) { rctl |= E1000_RCTL_MPE; @@ -3046,8 +3055,7 @@ static void e1000_set_multi(struct net_device *netdev) } else { rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); } - if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) - rctl |= E1000_RCTL_VFE; + e1000e_vlan_filter_enable(adapter); } ew32(RCTL, rctl); @@ -3072,6 +3080,11 @@ static void e1000_set_multi(struct net_device *netdev) */ e1000_update_mc_addr_list(hw, NULL, 0); } + + if (netdev->features & NETIF_F_HW_VLAN_RX) + e1000e_vlan_strip_enable(adapter); + else + e1000e_vlan_strip_disable(adapter); } /** @@ -3721,10 +3734,8 @@ static int e1000_close(struct net_device *netdev) * kill manageability vlan ID if supported, but not if a vlan with * the same ID is registered on the host OS (let 8021q kill it) */ - if ((adapter->hw.mng_cookie.status & - E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && - !(adapter->vlgrp && - vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) + if (adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN) e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); /* @@ -5759,7 +5770,6 @@ static const struct net_device_ops e1000e_netdev_ops = { .ndo_tx_timeout = e1000_tx_timeout, .ndo_validate_addr = eth_validate_addr, - .ndo_vlan_rx_register = e1000_vlan_rx_register, .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER -- GitLab From 2084b114e3fb0d84e5882f5ee6c7039be52da715 Mon Sep 17 00:00:00 2001 From: Flavio Leitner Date: Tue, 5 Apr 2011 04:27:43 +0000 Subject: [PATCH 0926/5560] e1000e: fix stats locking in e1000_watchdog_task Just move the unlock down a bit because it unlocks too early leaving a chance for get_stats64() run in parallel while it is still accessing the stats. Signed-off-by: Flavio Leitner Acked-by: Bruce Allan Tested-by: Aaron Brown 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 8812eb28e099..8a3145e9aa3e 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4339,7 +4339,6 @@ static void e1000_watchdog_task(struct work_struct *work) link_up: spin_lock(&adapter->stats64_lock); e1000e_update_stats(adapter); - spin_unlock(&adapter->stats64_lock); mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; adapter->tpt_old = adapter->stats.tpt; @@ -4350,6 +4349,7 @@ static void e1000_watchdog_task(struct work_struct *work) adapter->gorc_old = adapter->stats.gorc; adapter->gotc = adapter->stats.gotc - adapter->gotc_old; adapter->gotc_old = adapter->stats.gotc; + spin_unlock(&adapter->stats64_lock); e1000e_update_adaptive(&adapter->hw); -- GitLab From 78cd29d5a92ae5067377ad42089f2c8781312f4a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 24 Mar 2011 03:09:03 +0000 Subject: [PATCH 0927/5560] e1000e: If ASPM L0s needs to be disabled, do it prior to enabling device Based on a patch from Naga Chumbalkar : If ASPM L0s needs to be disabled due to HW errata, do it prior to "enabling" the device. This way if the kernel ever defaults its aspm_policy to POLICY_POWERSAVE, then the e1000e driver will get a chance to disable ASPM on the misbehaving device *prior* to calling pci_enable_device_mem(). This will be useful in situations where the BIOS indicates ASPM support on the server by clearing the ACPI FADT "ASPM Controls" bit. Note: The kernel (2.6.38) currently uses the BIOS "default" as its aspm_policy. However, Linux distros can diverge from that and set the default to "powersave". v2: o cleanup namespace pollution of e1000e_disable_aspm(), o fix type and initialization of the new aspm_disable_flag in a few functions, and o redefine FLAG2_DISABLE_ASPM_L0S to the first unused bit in adapter->flags2. Signed-off-by: Bruce Allan Cc: Naga Chumbalkar Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/82571.c | 10 +++++----- drivers/net/e1000e/e1000.h | 2 +- drivers/net/e1000e/netdev.c | 29 ++++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 9fedbca66dfd..ae07d37903ba 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -431,9 +431,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) case e1000_82573: case e1000_82574: case e1000_82583: - /* Disable ASPM L0s due to hardware errata */ - e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S); - if (pdev->device == E1000_DEV_ID_82573L) { adapter->flags |= FLAG_HAS_JUMBO_FRAMES; adapter->max_hw_frame_size = DEFAULT_JUMBO; @@ -2066,7 +2063,8 @@ struct e1000_info e1000_82573_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_SWSM_ON_LOAD, - .flags2 = FLAG2_DISABLE_ASPM_L1, + .flags2 = FLAG2_DISABLE_ASPM_L1 + | FLAG2_DISABLE_ASPM_L0S, .pba = 20, .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, @@ -2086,7 +2084,8 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, - .flags2 = FLAG2_CHECK_PHY_HANG, + .flags2 = FLAG2_CHECK_PHY_HANG + | FLAG2_DISABLE_ASPM_L0S, .pba = 32, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, @@ -2104,6 +2103,7 @@ struct e1000_info e1000_82583_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, + .flags2 = FLAG2_DISABLE_ASPM_L0S, .pba = 32, .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 500896e42206..3be5478dfdf1 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -458,6 +458,7 @@ struct e1000_info { #define FLAG2_HAS_PHY_STATS (1 << 4) #define FLAG2_HAS_EEE (1 << 5) #define FLAG2_DMA_BURST (1 << 6) +#define FLAG2_DISABLE_ASPM_L0S (1 << 7) #define FLAG2_DISABLE_AIM (1 << 8) #define FLAG2_CHECK_PHY_HANG (1 << 9) @@ -504,7 +505,6 @@ extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_get_hw_control(struct e1000_adapter *adapter); extern void e1000e_release_hw_control(struct e1000_adapter *adapter); -extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); extern unsigned int copybreak; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 8a3145e9aa3e..4deb67d98e36 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -58,6 +58,8 @@ char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; +static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); + static const struct e1000_info *e1000_info_tbl[] = { [board_82571] = &e1000_82571_info, [board_82572] = &e1000_82572_info, @@ -5384,7 +5386,7 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); } #endif -void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) +static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) { dev_info(&pdev->dev, "Disabling ASPM %s %s\n", (state & PCIE_LINK_STATE_L0S) ? "L0s" : "", @@ -5404,13 +5406,19 @@ static int __e1000_resume(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + u16 aspm_disable_flag = 0; u32 err; + if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S) + aspm_disable_flag = PCIE_LINK_STATE_L0S; + if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) + aspm_disable_flag |= PCIE_LINK_STATE_L1; + if (aspm_disable_flag) + e1000e_disable_aspm(pdev, aspm_disable_flag); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); pci_save_state(pdev); - if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) - e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); e1000e_set_interrupt_capability(adapter); if (netif_running(netdev)) { @@ -5654,11 +5662,17 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + u16 aspm_disable_flag = 0; int err; pci_ers_result_t result; + if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S) + aspm_disable_flag = PCIE_LINK_STATE_L0S; if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1) - e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); + aspm_disable_flag |= PCIE_LINK_STATE_L1; + if (aspm_disable_flag) + e1000e_disable_aspm(pdev, aspm_disable_flag); + err = pci_enable_device_mem(pdev); if (err) { dev_err(&pdev->dev, @@ -5799,12 +5813,17 @@ static int __devinit e1000_probe(struct pci_dev *pdev, resource_size_t flash_start, flash_len; static int cards_found; + u16 aspm_disable_flag = 0; int i, err, pci_using_dac; u16 eeprom_data = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; + if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S) + aspm_disable_flag = PCIE_LINK_STATE_L0S; if (ei->flags2 & FLAG2_DISABLE_ASPM_L1) - e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1); + aspm_disable_flag |= PCIE_LINK_STATE_L1; + if (aspm_disable_flag) + e1000e_disable_aspm(pdev, aspm_disable_flag); err = pci_enable_device_mem(pdev); if (err) -- GitLab From c8ca76ebc6e50752c5311b92bb9aef7edb324577 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 12 Mar 2011 03:50:53 +0000 Subject: [PATCH 0928/5560] ixgbe: DCB, further cleanups to app configuration With the app data on the kernel dcb_app list we no longer need to specifically handle them in ixgbe for the CEE case. So now we can remove app handling logic and check when the hw is configured if the app data matches the hardware configuration in set_hw_all(). If it does not match then we can reconfigure. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 107 +++++++------------------------ 1 file changed, 24 insertions(+), 83 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 327c8614198c..7b59f64a13d4 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -347,18 +347,28 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct dcb_app app = { + .selector = DCB_APP_IDTYPE_ETHTYPE, + .protocol = ETH_P_FCOE, + }; + u8 up = dcb_getapp(netdev, &app); int ret; - if (!adapter->dcb_set_bitmap || - !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) - return DCB_NO_HW_CHG; - ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, MAX_TRAFFIC_CLASS); - if (ret) return DCB_NO_HW_CHG; + /* In IEEE mode app data must be parsed into DCBX format for + * hardware routines. + */ + if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) + up = (1 << up); + +#ifdef IXGBE_FCOE + if (up && (up != (1 << adapter->fcoe.up))) + adapter->dcb_set_bitmap |= BIT_APP_UPCHG; + /* * Only take down the adapter if an app change occurred. FCoE * may shuffle tx rings in this case and this can not be done @@ -368,10 +378,13 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); + ixgbe_fcoe_setapp(adapter, up); + if (netif_running(netdev)) netdev->netdev_ops->ndo_stop(netdev); ixgbe_clear_interrupt_scheme(adapter); } +#endif if (adapter->dcb_cfg.pfc_mode_enable) { switch (adapter->hw.mac.type) { @@ -399,12 +412,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } } +#ifdef IXGBE_FCOE if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); ret = DCB_HW_CHG_RST; } +#endif if (adapter->dcb_set_bitmap & BIT_PFC) { u8 pfc_en; @@ -558,68 +573,6 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) return dcb_getapp(netdev, &app); } -/** - * ixgbe_dcbnl_setapp - set the DCBX application user priority - * @netdev : the corresponding netdev - * @idtype : identifies the id as ether type or TCP/UDP port number - * @id: id is either ether type or TCP/UDP port number - * @up: the 802.1p user priority bitmap - * - * Returns : 0 on success or 1 on error - */ -static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, - u8 idtype, u16 id, u8 up) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - u8 rval = 1; - struct dcb_app app = { - .selector = idtype, - .protocol = id, - .priority = up - }; - - if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) - return rval; - - rval = dcb_setapp(netdev, &app); - - switch (idtype) { - case DCB_APP_IDTYPE_ETHTYPE: -#ifdef IXGBE_FCOE - if (id == ETH_P_FCOE) { - u8 old_tc; - - /* Get current programmed tc */ - old_tc = adapter->fcoe.tc; - rval = ixgbe_fcoe_setapp(adapter, up); - - if (rval || - !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || - !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) - break; - - /* The FCoE application priority may be changed multiple - * times in quick succession with switches that build up - * TLVs. To avoid creating uneeded device resets this - * checks the actual HW configuration and clears - * BIT_APP_UPCHG if a HW configuration change is not - * need - */ - if (old_tc == adapter->fcoe.tc) - adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG; - else - adapter->dcb_set_bitmap |= BIT_APP_UPCHG; - } -#endif - break; - case DCB_APP_IDTYPE_PORTNUM: - break; - default: - break; - } - return rval; -} - static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets) { @@ -745,25 +698,14 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL; -#ifdef IXGBE_FCOE - if (app->selector == 1 && app->protocol == ETH_P_FCOE) { - if (adapter->fcoe.tc == app->priority) - goto setapp; - /* In IEEE mode map up to tc 1:1 */ - adapter->fcoe.tc = app->priority; - adapter->fcoe.up = app->priority; + dcb_setapp(dev, app); - /* Force hardware reset required to push FCoE - * setup on {tx|rx}_rings - */ - adapter->dcb_set_bitmap |= BIT_APP_UPCHG; +#ifdef IXGBE_FCOE + if (app->selector == 1 && app->protocol == ETH_P_FCOE && + adapter->fcoe.tc == app->priority) ixgbe_dcbnl_set_all(dev); - } - -setapp: #endif - dcb_setapp(dev, app); return 0; } @@ -838,7 +780,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = { .getpfcstate = ixgbe_dcbnl_getpfcstate, .setpfcstate = ixgbe_dcbnl_setpfcstate, .getapp = ixgbe_dcbnl_getapp, - .setapp = ixgbe_dcbnl_setapp, .getdcbx = ixgbe_dcbnl_getdcbx, .setdcbx = ixgbe_dcbnl_setdcbx, }; -- GitLab From 2ea5ea5fc4f4f1daa74708c2a14e364d8474812d Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 12 Mar 2011 08:56:38 +0000 Subject: [PATCH 0929/5560] ixgbe: fix return value checks The value of status was incorrectly tested. Also whitespace cleanup. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_x540.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index d9323c08f5c7..7ce3f45cad71 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -452,7 +452,7 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); status = ixgbe_poll_flash_update_done_X540(hw); - if (status) + if (status == 0) hw_dbg(hw, "Flash update complete\n"); else hw_dbg(hw, "Flash update time out\n"); @@ -466,11 +466,10 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) } status = ixgbe_poll_flash_update_done_X540(hw); - if (status) + if (status == 0) hw_dbg(hw, "Flash update complete\n"); else hw_dbg(hw, "Flash update time out\n"); - } out: return status; -- GitLab From c9130180a8dc48943f2a072acec4a53616a1f0ab Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 16 Mar 2011 01:55:55 +0000 Subject: [PATCH 0930/5560] ixgbe: correct function number for some 82598 parts Some 82598 parts have LAN0 disabled and LAN1 enabled and the LAN ID bits in Device Status register report the NIC as having only LAN1 as enabled. This causes ixgbe_set_lan_id_multi_port_pcie() to set bus->func = 1 which is incorrect. Force bus->func to 0 when LAN0 is disabled in the EEPROM. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 34 ++++++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_type.h | 5 +++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 845c679c8b87..c9b6574cdd72 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1188,6 +1188,38 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) return physical_layer; } +/** + * ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple + * port devices. + * @hw: pointer to the HW structure + * + * Calls common function and corrects issue with some single port devices + * that enable LAN1 but not LAN0. + **/ +static void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw) +{ + struct ixgbe_bus_info *bus = &hw->bus; + u16 pci_gen = 0; + u16 pci_ctrl2 = 0; + + ixgbe_set_lan_id_multi_port_pcie(hw); + + /* check if LAN0 is disabled */ + hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen); + if ((pci_gen != 0) && (pci_gen != 0xFFFF)) { + + hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2); + + /* if LAN0 is completely disabled force function to 0 */ + if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) && + !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) && + !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) { + + bus->func = 0; + } + } +} + static struct ixgbe_mac_operations mac_ops_82598 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82598, @@ -1199,7 +1231,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .get_mac_addr = &ixgbe_get_mac_addr_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, + .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie_82598, .read_analog_reg8 = &ixgbe_read_analog_reg8_82598, .write_analog_reg8 = &ixgbe_write_analog_reg8_82598, .setup_link = &ixgbe_setup_mac_link_82598, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 25c1fb7eda06..cd1c2b62ec49 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1616,6 +1616,11 @@ #define IXGBE_FLUDONE_ATTEMPTS 20000 #endif +#define IXGBE_PCIE_CTRL2 0x5 /* PCIe Control 2 Offset */ +#define IXGBE_PCIE_CTRL2_DUMMY_ENABLE 0x8 /* Dummy Function Enable */ +#define IXGBE_PCIE_CTRL2_LAN_DISABLE 0x2 /* LAN PCI Disable */ +#define IXGBE_PCIE_CTRL2_DISABLE_SELECT 0x1 /* LAN Disable Select */ + #define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET 0x0 #define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 #define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 -- GitLab From d6cd8e0e75b66896bd4e14c8883d62322831cb8f Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 16 Mar 2011 01:58:20 +0000 Subject: [PATCH 0931/5560] ixgbe: fix namespacecheck issue Set ixgbe_identify_82599() as static Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 00aeba385a2f..32ad4119ff77 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1775,7 +1775,7 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) * If PHY already detected, maintains current PHY type in hw struct, * otherwise executes the PHY detection routine. **/ -s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) +static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; -- GitLab From 75e3d3c6812ef2387f8dcfd86437cff00f64b68b Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 17 Mar 2011 18:11:38 +0000 Subject: [PATCH 0932/5560] ixgbe: update version string for Dell CEM use Signed-off-by: Jeff Kirsher Acked-by: Don Skidmore Tested-by: Stephen Ko --- drivers/net/ixgbe/ixgbe_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 6f8adc7f5d7c..3dbe6896b2c3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -51,8 +51,12 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; - -#define DRV_VERSION "3.2.9-k2" +#define MAJ 3 +#define MIN 2 +#define BUILD 9 +#define KFIX 2 +#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ + __stringify(BUILD) "-k" __stringify(KFIX) const char ixgbe_driver_version[] = DRV_VERSION; static const char ixgbe_copyright[] = "Copyright (c) 1999-2011 Intel Corporation."; -- GitLab From 7184b7cf555f5bc08e34994147c341abb07d1dbb Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 18 Mar 2011 08:18:22 +0000 Subject: [PATCH 0933/5560] ixgbe: refactor common start_hw code for 82599 and x540 Factored out the common start_hw code into a new function ixgbe_start_hw_gen2() so that it can be used by x540 and 82599. Signed-off-by: Emil Tantilov Acked-by: Don Skidmore Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 22 ++++++++++------------ drivers/net/ixgbe/ixgbe_common.c | 24 ++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_common.h | 1 + drivers/net/ixgbe/ixgbe_x540.c | 24 +++++++++++++++++++++++- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 32ad4119ff77..09934a82eb30 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1740,30 +1740,28 @@ static s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val) * ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx * @hw: pointer to hardware structure * - * Starts the hardware using the generic start_hw function. - * Then performs device-specific: - * Clears the rate limiter registers. + * Starts the hardware using the generic start_hw function + * and the generation start_hw function. + * Then performs revision-specific operations, if any. **/ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) { - u32 q_num; - s32 ret_val; + s32 ret_val = 0; ret_val = ixgbe_start_hw_generic(hw); + if (ret_val != 0) + goto out; - /* Clear the rate limiters */ - for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) { - IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num); - IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0); - } - IXGBE_WRITE_FLUSH(hw); + ret_val = ixgbe_start_hw_gen2(hw); + if (ret_val != 0) + goto out; /* We need to run link autotry after the driver loads */ hw->mac.autotry_restart = true; if (ret_val == 0) ret_val = ixgbe_verify_fw_version_82599(hw); - +out: return ret_val; } diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index bcd952916eb2..c66fd957578c 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -95,6 +95,30 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) return 0; } +/** + * ixgbe_start_hw_gen2 - Init sequence for common device family + * @hw: pointer to hw structure + * + * Performs the init sequence common to the second generation + * of 10 GbE devices. + * Devices in the second generation: + * 82599 + * X540 + **/ +s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) +{ + u32 i; + + /* Clear the rate limiters */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i); + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0); + } + IXGBE_WRITE_FLUSH(hw); + + return 0; +} + /** * ixgbe_init_hw_generic - Generic hardware initialization * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 508f635fc2ca..2585bf38391d 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -35,6 +35,7 @@ u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw); 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_start_hw_gen2(struct ixgbe_hw *hw); s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw); s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num, u32 pba_num_size); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 7ce3f45cad71..295c17003d6d 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -225,6 +225,28 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) return status; } +/** + * ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware using the generic start_hw function + * and the generation start_hw function. + * Then performs revision-specific operations, if any. + **/ +static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) +{ + s32 ret_val = 0; + + ret_val = ixgbe_start_hw_generic(hw); + if (ret_val != 0) + goto out; + + ret_val = ixgbe_start_hw_gen2(hw); + +out: + return ret_val; +} + /** * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type * @hw: pointer to hardware structure @@ -660,7 +682,7 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *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, + .start_hw = &ixgbe_start_hw_X540, .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, .get_media_type = &ixgbe_get_media_type_X540, .get_supported_physical_layer = -- GitLab From 3d5c520727ce3dbf418eec38e431856708f946f8 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 19 Mar 2011 01:32:46 +0000 Subject: [PATCH 0934/5560] ixgbe: move disabling of relaxed ordering in start_hw() Relaxed ordering can lead to issues with some chipsets. This patch makes sure that it is disabled by default and not only when DCA is on. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 21 ++++++++++++++++++++- drivers/net/ixgbe/ixgbe_common.c | 15 +++++++++++++++ drivers/net/ixgbe/ixgbe_main.c | 4 ---- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index c9b6574cdd72..a93275fd260f 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -197,14 +197,33 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) * @hw: pointer to hardware structure * * Starts the hardware using the generic start_hw function. - * Then set pcie completion timeout + * Disables relaxed ordering Then set pcie completion timeout + * **/ static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) { + u32 regval; + u32 i; s32 ret_val = 0; ret_val = ixgbe_start_hw_generic(hw); + /* Disable relaxed ordering */ + for (i = 0; ((i < hw->mac.max_tx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); + regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); + } + + for (i = 0; ((i < hw->mac.max_rx_queues) && + (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + /* set the completion timeout for interface */ if (ret_val == 0) ixgbe_set_pcie_completion_timeout(hw); diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index c66fd957578c..1b8b3cd1664f 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -108,6 +108,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) { u32 i; + u32 regval; /* Clear the rate limiters */ for (i = 0; i < hw->mac.max_tx_queues; i++) { @@ -116,6 +117,20 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) } IXGBE_WRITE_FLUSH(hw); + /* Disable relaxed ordering */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); + regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); + } + + for (i = 0; i < hw->mac.max_rx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + return 0; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3dbe6896b2c3..3148e2182e92 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -947,8 +947,6 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, 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); } @@ -966,7 +964,6 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, 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: @@ -976,7 +973,6 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, 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: -- GitLab From 0fa6d83258252695203d24c8818092644df10fd7 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 18 Mar 2011 08:18:32 +0000 Subject: [PATCH 0935/5560] ixgbe: fix 82599 KR downshift coexistence with LESM FW module Disable KR to KX4/KX downshift on 82599 backplane devices when LESM (Link Establishment State Machine) is enabled in FW. Those features cannot co-exist as they both manipulate the same registers. Signed-off-by: Emil Tantilov Acked-by: Don Skidmore Tested-by: Phillip Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 46 ++++++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_type.h | 3 +++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 09934a82eb30..d195278c62e3 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -61,6 +61,7 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, bool autoneg, bool autoneg_wait_to_complete); static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); +static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { @@ -86,7 +87,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) if ((mac->ops.get_media_type(hw) == ixgbe_media_type_backplane) && (hw->phy.smart_speed == ixgbe_smart_speed_auto || - hw->phy.smart_speed == ixgbe_smart_speed_on)) + hw->phy.smart_speed == ixgbe_smart_speed_on) && + !ixgbe_verify_lesm_fw_enabled_82599(hw)) mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed; else mac->ops.setup_link = &ixgbe_setup_mac_link_82599; @@ -2028,6 +2030,48 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) return status; } +/** + * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state. + * @hw: pointer to hardware structure + * + * Returns true if the LESM FW module is present and enabled. Otherwise + * returns false. Smart Speed must be disabled if LESM FW module is enabled. + **/ +static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) +{ + bool lesm_enabled = false; + u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; + s32 status; + + /* get the offset to the Firmware Module block */ + status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset); + + if ((status != 0) || + (fw_offset == 0) || (fw_offset == 0xFFFF)) + goto out; + + /* get the offset to the LESM Parameters block */ + status = hw->eeprom.ops.read(hw, (fw_offset + + IXGBE_FW_LESM_PARAMETERS_PTR), + &fw_lesm_param_offset); + + if ((status != 0) || + (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF)) + goto out; + + /* get the lesm state word */ + status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset + + IXGBE_FW_LESM_STATE_1), + &fw_lesm_state); + + if ((status == 0) && + (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED)) + lesm_enabled = true; + +out: + return lesm_enabled; +} + static struct ixgbe_mac_operations mac_ops_82599 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82599, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index cd1c2b62ec49..e00356a25ee1 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1625,6 +1625,9 @@ #define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 #define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 +#define IXGBE_FW_LESM_PARAMETERS_PTR 0x2 +#define IXGBE_FW_LESM_STATE_1 0x1 +#define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */ #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 #define IXGBE_FW_PATCH_VERSION_4 0x7 -- GitLab From 032b4325b61b03f87f0346d0e92e39f785e24105 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 18 Mar 2011 09:32:53 +0000 Subject: [PATCH 0936/5560] ixgbe: cleanup short msleep's (<20ms) to use usleep_range Since msleep might not sleep for the desired amount when less than 20ms use usleep_range. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 2 +- drivers/net/ixgbe/ixgbe_82599.c | 14 +++++++++----- drivers/net/ixgbe/ixgbe_common.c | 14 +++++++++----- drivers/net/ixgbe/ixgbe_dcb_nl.c | 2 +- drivers/net/ixgbe/ixgbe_ethtool.c | 14 +++++++------- drivers/net/ixgbe/ixgbe_main.c | 8 ++++---- drivers/net/ixgbe/ixgbe_phy.c | 4 ++-- drivers/net/ixgbe/ixgbe_x540.c | 6 +++--- 8 files changed, 36 insertions(+), 28 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index a93275fd260f..af4054a1a133 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1083,7 +1083,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) break; - msleep(10); + usleep_range(10000, 20000); } if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index d195278c62e3..e39380ca996c 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -130,8 +130,12 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) /* 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); + /* + * Delay obtaining semaphore again to allow FW access, + * semaphore_delay is in ms usleep_range needs us. + */ + usleep_range(hw->eeprom.semaphore_delay * 1000, + hw->eeprom.semaphore_delay * 2000); /* Now restart DSP by setting Restart_AN and clearing LMS */ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw, @@ -140,7 +144,7 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) /* Wait for AN to leave state 0 */ for (i = 0; i < 10; i++) { - msleep(4); + usleep_range(4000, 8000); reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1); if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK) break; @@ -1178,7 +1182,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & IXGBE_FDIRCTRL_INIT_DONE) break; - msleep(1); + usleep_range(1000, 2000); } if (i >= IXGBE_FDIR_INIT_DONE_POLL) hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); @@ -1273,7 +1277,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & IXGBE_FDIRCTRL_INIT_DONE) break; - msleep(1); + usleep_range(1000, 2000); } if (i >= IXGBE_FDIR_INIT_DONE_POLL) hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n"); diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 1b8b3cd1664f..a67cba5149d1 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -503,7 +503,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) reg_val &= ~(IXGBE_RXCTRL_RXEN); IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val); IXGBE_WRITE_FLUSH(hw); - msleep(2); + usleep_range(2000, 4000); /* Clear interrupt mask to stop from interrupts being generated */ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); @@ -1151,8 +1151,12 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); - /* Delay before attempt to obtain semaphore again to allow FW access */ - msleep(hw->eeprom.semaphore_delay); + /* + * Delay before attempt to obtain semaphore again to allow FW + * access. semaphore_delay is in ms we need us for usleep_range + */ + usleep_range(hw->eeprom.semaphore_delay * 1000, + hw->eeprom.semaphore_delay * 2000); } /** @@ -2228,7 +2232,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) * thread currently using resource (swmask) */ ixgbe_release_eeprom_semaphore(hw); - msleep(5); + usleep_range(5000, 10000); timeout--; } @@ -2302,7 +2306,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - msleep(10); + usleep_range(10000, 20000); } led_reg &= ~IXGBE_LED_MODE_MASK(index); diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 7b59f64a13d4..5e7ed225851a 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -376,7 +376,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) */ if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); ixgbe_fcoe_setapp(adapter, up); diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 76380a2b35aa..5005a36f8593 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -931,7 +931,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, } while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); if (!netif_running(adapter->netdev)) { for (i = 0; i < adapter->num_tx_queues; i++) @@ -1417,7 +1417,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) /* Disable all the interrupts */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); - msleep(10); + usleep_range(10000, 20000); /* Test each interrupt */ for (; i < 10; i++) { @@ -1437,7 +1437,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) ~mask & 0x00007FFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, ~mask & 0x00007FFF); - msleep(10); + usleep_range(10000, 20000); if (adapter->test_icr & mask) { *data = 3; @@ -1454,7 +1454,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) adapter->test_icr = 0; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - msleep(10); + usleep_range(10000, 20000); if (!(adapter->test_icr &mask)) { *data = 4; @@ -1474,7 +1474,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) ~mask & 0x00007FFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, ~mask & 0x00007FFF); - msleep(10); + usleep_range(10000, 20000); if (adapter->test_icr) { *data = 5; @@ -1485,7 +1485,7 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) /* Disable all the interrupts */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); - msleep(10); + usleep_range(10000, 20000); /* Unhook test interrupt handler */ free_irq(irq, netdev); @@ -1613,7 +1613,7 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data); IXGBE_WRITE_FLUSH(&adapter->hw); - msleep(10); + usleep_range(10000, 20000); /* Disable Atlas Tx lanes; re-enabled in reset path */ if (hw->mac.type == ixgbe_mac_82598EB) { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3148e2182e92..5cd2cd3dd353 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2731,7 +2731,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, /* poll to verify queue is enabled */ do { - msleep(1); + usleep_range(1000, 2000); txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); if (!wait_loop) @@ -3023,7 +3023,7 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, return; do { - msleep(1); + usleep_range(1000, 2000); rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE)); @@ -3945,7 +3945,7 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) { WARN_ON(in_interrupt()); while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) - msleep(1); + usleep_range(1000, 2000); ixgbe_down(adapter); /* * If SR-IOV enabled then wait a bit before bringing the adapter @@ -4150,7 +4150,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* this call also flushes the previous write */ ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]); - msleep(10); + usleep_range(10000, 20000); netif_tx_stop_all_queues(netdev); diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index df5b8aa4795d..31cc29ed137c 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -753,7 +753,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) &phy_data); if ((phy_data & MDIO_CTRL1_RESET) == 0) break; - msleep(10); + usleep_range(10000, 20000); } if ((phy_data & MDIO_CTRL1_RESET) != 0) { @@ -782,7 +782,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) case IXGBE_DELAY_NL: data_offset++; hw_dbg(hw, "DELAY: %d MS\n", edata); - msleep(edata); + usleep_range(edata * 1000, edata * 2000); break; case IXGBE_DATA_NL: hw_dbg(hw, "DATA:\n"); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 295c17003d6d..8aa1dc1155a9 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -563,7 +563,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) * resource (swmask) */ ixgbe_release_swfw_sync_semaphore(hw); - msleep(5); + usleep_range(5000, 10000); } } @@ -585,7 +585,7 @@ static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) } } - msleep(5); + usleep_range(5000, 10000); return 0; } @@ -609,7 +609,7 @@ static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); ixgbe_release_swfw_sync_semaphore(hw); - msleep(5); + usleep_range(5000, 10000); } /** -- GitLab From eb9c3e3ea2981e56c71e8f5477c51783856090b1 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 24 Mar 2011 00:57:50 +0000 Subject: [PATCH 0937/5560] ixgbe: fix semaphores in eeprom routines for x540 HW can upload EEPROM content from flash while in a middle of checksum calculation. Take NVM ownership for the whole process of checksum update. Call ixgbe_read_eerd_generic() and ixgbe_write_eewr_generic() directly to avoid double take of semaphores which leads to long loading times. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 44 ++++++++- drivers/net/ixgbe/ixgbe_common.h | 2 +- drivers/net/ixgbe/ixgbe_x540.c | 154 ++++++++++++++++++++++--------- 3 files changed, 153 insertions(+), 47 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index a67cba5149d1..fc31e0256c18 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -54,6 +54,7 @@ static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); 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 @@ -777,6 +778,47 @@ s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) return status; } +/** + * ixgbe_write_eewr_generic - 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_generic(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; + + 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; + } + +out: + return status; +} + /** * ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status * @hw: pointer to hardware structure @@ -785,7 +827,7 @@ s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) * Polls the status bit (bit 1) of the EERD or EEWR to determine when the * read or write is done respectively. **/ -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) { u32 i; u32 reg; diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 2585bf38391d..e18dc136ad34 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -50,13 +50,13 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); 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_write_eewr_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); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 8aa1dc1155a9..5433f15c1e1b 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -322,55 +322,33 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) } /** - * 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 + * 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. + * Write a 16 bit word to the EEPROM using the EEWR register. **/ static 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 (hw->mac.ops.acquire_swfw_sync(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"); - goto out; - } - - IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr); + s32 status = 0; - 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 { + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) + status = ixgbe_write_eewr_generic(hw, offset, data); + else status = IXGBE_ERR_SWFW_SYNC; - } -out: - ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); return status; } /** - * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum - * @hw: pointer to hardware structure + * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum + * + * This function does not use synchronization for EERD and EEWR. It can + * be used internally by function which utilize ixgbe_acquire_swfw_sync_X540. + * + * @hw: pointer to hardware structure **/ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) { @@ -381,9 +359,15 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) u16 pointer = 0; u16 word = 0; + /* + * Do not use hw->eeprom.ops.read because we do not want to take + * the synchronization semaphores here. Instead use + * ixgbe_read_eerd_generic + */ + /* Include 0x0-0x3F in the checksum */ for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { - if (hw->eeprom.ops.read(hw, i, &word) != 0) { + if (ixgbe_read_eerd_generic(hw, i, &word) != 0) { hw_dbg(hw, "EEPROM read failed\n"); break; } @@ -398,7 +382,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) continue; - if (hw->eeprom.ops.read(hw, i, &pointer) != 0) { + if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) { hw_dbg(hw, "EEPROM read failed\n"); break; } @@ -408,7 +392,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) pointer >= hw->eeprom.word_size) continue; - if (hw->eeprom.ops.read(hw, pointer, &length) != 0) { + if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) { hw_dbg(hw, "EEPROM read failed\n"); break; } @@ -419,7 +403,7 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) continue; for (j = pointer+1; j <= pointer+length; j++) { - if (hw->eeprom.ops.read(hw, j, &word) != 0) { + if (ixgbe_read_eerd_generic(hw, j, &word) != 0) { hw_dbg(hw, "EEPROM read failed\n"); break; } @@ -432,6 +416,62 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) return checksum; } +/** + * ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum + * @hw: pointer to hardware structure + * @checksum_val: calculated checksum + * + * Performs checksum calculation and validates the EEPROM checksum. If the + * caller does not need checksum_val, the value can be NULL. + **/ +static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, + u16 *checksum_val) +{ + s32 status; + u16 checksum; + u16 read_checksum = 0; + + /* + * Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + + if (status != 0) { + hw_dbg(hw, "EEPROM read failed\n"); + goto out; + } + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { + checksum = hw->eeprom.ops.calc_checksum(hw); + + /* + * Do not use hw->eeprom.ops.read because we do not want to take + * the synchronization semaphores twice here. + */ + ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM, + &read_checksum); + + /* + * Verify read checksum from EEPROM is the same as + * calculated checksum + */ + if (read_checksum != checksum) + status = IXGBE_ERR_EEPROM_CHECKSUM; + + /* If the user cares, return the calculated checksum */ + if (checksum_val) + *checksum_val = checksum; + } else { + status = IXGBE_ERR_SWFW_SYNC; + } + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); +out: + return status; +} + /** * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash * @hw: pointer to hardware structure @@ -443,11 +483,35 @@ static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) { s32 status; + u16 checksum; - status = ixgbe_update_eeprom_checksum_generic(hw); + /* + * Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + + if (status != 0) + hw_dbg(hw, "EEPROM read failed\n"); + + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { + checksum = hw->eeprom.ops.calc_checksum(hw); - if (status) + /* + * Do not use hw->eeprom.ops.write because we do not want to + * take the synchronization semaphores twice here. + */ + status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, + checksum); + + if (status == 0) status = ixgbe_update_flash_X540(hw); + else + status = IXGBE_ERR_SWFW_SYNC; + } + + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); return status; } @@ -728,7 +792,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_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, + .validate_checksum = &ixgbe_validate_eeprom_checksum_X540, .update_checksum = &ixgbe_update_eeprom_checksum_X540, }; -- GitLab From 4c40ef0291acebf32435e5a4921178ee53bd8933 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 24 Mar 2011 07:06:02 +0000 Subject: [PATCH 0938/5560] ixgbe: add support for new HW Add new device ID supported by ixgbe. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 1 + drivers/net/ixgbe/ixgbe_main.c | 2 ++ drivers/net/ixgbe/ixgbe_type.h | 1 + 3 files changed, 4 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index e39380ca996c..63b4da6b5b77 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -359,6 +359,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_SFP_FCOE: case IXGBE_DEV_ID_82599_SFP_EM: + case IXGBE_DEV_ID_82599_SFP_SF2: media_type = ixgbe_media_type_fiber; break; case IXGBE_DEV_ID_82599_CX4: diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5cd2cd3dd353..200ae7e60ba0 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -124,6 +124,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), board_X540 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2), + board_82599 }, /* required last entry */ {0, } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index e00356a25ee1..15580d687aee 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -58,6 +58,7 @@ #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_SFP_SF2 0x154D #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 -- GitLab From a59e8a1a72806057084adc2d321fc2a7cbce9579 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 31 Mar 2011 09:36:12 +0000 Subject: [PATCH 0939/5560] ixgbe: explicitly disable 100H for x540 100H is not supported on this HW, but the bit is set on the PHY. This can result in link at 100F when advertising only 1000F. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_phy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 31cc29ed137c..fd381ea17e99 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -449,7 +449,8 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) MDIO_MMD_AN, &autoneg_reg); - autoneg_reg &= ~ADVERTISE_100FULL; + autoneg_reg &= ~(ADVERTISE_100FULL | + ADVERTISE_100HALF); if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) autoneg_reg |= ADVERTISE_100FULL; -- GitLab From b776d1043510c60f59220eb5e58b524f5a7f0e52 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 31 Mar 2011 09:36:18 +0000 Subject: [PATCH 0940/5560] ixgbe: make device_caps() generic x540 has the same device capability word in the EEPROM as 82599. This patch renames ixgbe_get_device_caps_82599 to ixgbe_get_device_caps_generic, moves it to ixgbe_common.h and sets up the function pointer for x540. Signed-off-by: Emil Tantilov Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 17 +---------------- drivers/net/ixgbe/ixgbe_common.c | 15 +++++++++++++++ drivers/net/ixgbe/ixgbe_common.h | 1 + drivers/net/ixgbe/ixgbe_x540.c | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 63b4da6b5b77..e4323055347b 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1972,21 +1972,6 @@ static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) return 0; } -/** - * ixgbe_get_device_caps_82599 - Get additional device capabilities - * @hw: pointer to hardware structure - * @device_caps: the EEPROM word with the extra device capabilities - * - * This function will read the EEPROM location for the device capabilities, - * and return the word through device_caps. - **/ -static s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps) -{ - hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); - - return 0; -} - /** * ixgbe_verify_fw_version_82599 - verify fw version for 82599 * @hw: pointer to hardware structure @@ -2087,7 +2072,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .enable_rx_dma = &ixgbe_enable_rx_dma_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_device_caps = &ixgbe_get_device_caps_generic, .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, .stop_adapter = &ixgbe_stop_adapter_generic, .get_bus_info = &ixgbe_get_bus_info_generic, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index fc31e0256c18..cb2e8e18dd39 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2968,3 +2968,18 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) pfvfspoof &= ~(1 << vf_target_shift); IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); } + +/** + * ixgbe_get_device_caps_generic - Get additional device capabilities + * @hw: pointer to hardware structure + * @device_caps: the EEPROM word with the extra device capabilities + * + * This function will read the EEPROM location for the device capabilities, + * and return the word through device_caps. + **/ +s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps) +{ + hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); + + return 0; +} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index e18dc136ad34..e850adbb32a1 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -90,6 +90,7 @@ 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); +s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 5433f15c1e1b..05f8e9cddef4 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -754,7 +754,7 @@ static struct ixgbe_mac_operations mac_ops_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_device_caps = &ixgbe_get_device_caps_generic, .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, .stop_adapter = &ixgbe_stop_adapter_generic, .get_bus_info = &ixgbe_get_bus_info_generic, -- GitLab From e09ad236fc85b1d6e010138f59aba76f6c9a295b Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Mon, 4 Apr 2011 04:29:41 +0000 Subject: [PATCH 0941/5560] ixgbe: DCB, misallocated packet buffer size with X540 device The X540 device has a smaller packet buffer but the DCB configuration never took this into account. Under stress this can result in the DMA engine hanging and TX Unit hang occurring to reset the device. This patch reworks the packet buffer allocation routine used for DCB on 82599 and X540 devices to account for RX packet buffer sizes. This fixes the immediate hang. We should consolidate the various hardware specific routines for configuring features into a single routine. This will make it much harder to miss feature cases like this. Signed-off-by: John Fastabend Tested-by: Ross Brattain Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 3 ++ drivers/net/ixgbe/ixgbe_82599.c | 2 + drivers/net/ixgbe/ixgbe_dcb_82599.c | 68 ++++++++++++++++++----------- drivers/net/ixgbe/ixgbe_dcb_82599.h | 2 + drivers/net/ixgbe/ixgbe_type.h | 1 + drivers/net/ixgbe/ixgbe_x540.c | 3 +- 6 files changed, 52 insertions(+), 27 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index af4054a1a133..7a64f50435cf 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -37,6 +37,7 @@ #define IXGBE_82598_RAR_ENTRIES 16 #define IXGBE_82598_MC_TBL_SIZE 128 #define IXGBE_82598_VFT_TBL_SIZE 128 +#define IXGBE_82598_RX_PB_SIZE 512 static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, @@ -224,6 +225,8 @@ static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); } + hw->mac.rx_pb_size = IXGBE_82598_RX_PB_SIZE; + /* set the completion timeout for interface */ if (ret_val == 0) ixgbe_set_pcie_completion_timeout(hw); diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index e4323055347b..b341ed8ef84f 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -38,6 +38,7 @@ #define IXGBE_82599_RAR_ENTRIES 128 #define IXGBE_82599_MC_TBL_SIZE 128 #define IXGBE_82599_VFT_TBL_SIZE 128 +#define IXGBE_82599_RX_PB_SIZE 512 static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); @@ -1765,6 +1766,7 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) /* We need to run link autotry after the driver loads */ hw->mac.autotry_restart = true; + hw->mac.rx_pb_size = IXGBE_82599_RX_PB_SIZE; if (ret_val == 0) ret_val = ixgbe_verify_fw_version_82599(hw); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 025af8c53ddb..865ddd82b268 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -39,36 +39,52 @@ */ static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba) { - s32 ret_val = 0; - u32 value = IXGBE_RXPBSIZE_64KB; + int num_tcs = IXGBE_MAX_PACKET_BUFFERS; + u32 rx_pb_size = hw->mac.rx_pb_size << IXGBE_RXPBSIZE_SHIFT; + u32 rxpktsize; + u32 txpktsize; + u32 txpbthresh; u8 i = 0; - /* Setup Rx packet buffer sizes */ - switch (rx_pba) { - case pba_80_48: - /* Setup the first four at 80KB */ - value = IXGBE_RXPBSIZE_80KB; - for (; i < 4; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value); - /* Setup the last four at 48KB...don't re-init i */ - value = IXGBE_RXPBSIZE_48KB; - /* Fall Through */ - case pba_equal: - default: - for (; i < IXGBE_MAX_PACKET_BUFFERS; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value); - - /* Setup Tx packet buffer sizes */ - for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) { - IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), - IXGBE_TXPBSIZE_20KB); - IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), - IXGBE_TXPBTHRESH_DCB); - } - break; + /* + * This really means configure the first half of the TCs + * (Traffic Classes) to use 5/8 of the Rx packet buffer + * space. To determine the size of the buffer for each TC, + * we are multiplying the average size by 5/4 and applying + * it to half of the traffic classes. + */ + if (rx_pba == pba_80_48) { + rxpktsize = (rx_pb_size * 5) / (num_tcs * 4); + rx_pb_size -= rxpktsize * (num_tcs / 2); + for (; i < (num_tcs / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + } + + /* Divide the remaining Rx packet buffer evenly among the TCs */ + rxpktsize = rx_pb_size / (num_tcs - i); + for (; i < num_tcs; i++) + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize); + + /* + * Setup Tx packet buffer and threshold equally for all TCs + * TXPBTHRESH register is set in K so divide by 1024 and subtract + * 10 since the largest packet we support is just over 9K. + */ + txpktsize = IXGBE_TXPBSIZE_MAX / num_tcs; + txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX; + for (i = 0; i < num_tcs; i++) { + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize); + IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh); } - return ret_val; + /* Clear unused TCs, if any, to zero buffer size*/ + for (; i < MAX_TRAFFIC_CLASS; i++) { + IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0); + } + + return 0; } /** diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 148fd8b477a9..2de71a503153 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -92,8 +92,10 @@ #define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */ #define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */ #define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */ +#define IXGBE_TXPBSIZE_MAX 0x00028000 /* 160KB Packet Buffer*/ #define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */ +#define IXGBE_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */ /* SECTXMINIFG DCB */ #define IXGBE_SECTX_DCB 0x00001F00 /* DCB TX Buffer IFG */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 15580d687aee..7d0b37d2ab7b 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2606,6 +2606,7 @@ struct ixgbe_mac_info { u32 vft_size; u32 num_rar_entries; u32 rar_highwater; + u32 rx_pb_size; u32 max_tx_queues; u32 max_rx_queues; u32 max_msix_vectors; diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 05f8e9cddef4..932394fce439 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -37,6 +37,7 @@ #define IXGBE_X540_RAR_ENTRIES 128 #define IXGBE_X540_MC_TBL_SIZE 128 #define IXGBE_X540_VFT_TBL_SIZE 128 +#define IXGBE_X540_RX_PB_SIZE 384 static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); @@ -242,7 +243,7 @@ static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw) goto out; ret_val = ixgbe_start_hw_gen2(hw); - + hw->mac.rx_pb_size = IXGBE_X540_RX_PB_SIZE; out: return ret_val; } -- GitLab From 45a5f720fe37d21059da3c333c373c845ccbd82b Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Mon, 4 Apr 2011 04:29:46 +0000 Subject: [PATCH 0942/5560] ixgbe: DCB, X540 devices do not respond to pause frames DCB enabled X540 devices are not responding to pause frames due to a missing register set that was added for these devices that did not exist in other devices. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_82599.c | 9 +++++++-- drivers/net/ixgbe/ixgbe_type.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 865ddd82b268..d50cf78c234d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -301,12 +301,17 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en) IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg); /* * Enable Receive PFC - * We will always honor XOFF frames we receive when - * we are in PFC mode. + * 82599 will always honor XOFF frames we receive when + * we are in PFC mode however X540 only honors enabled + * traffic classes. */ reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); reg &= ~IXGBE_MFLCN_RFCE; reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF; + + if (hw->mac.type == ixgbe_mac_X540) + reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); } else { diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 7d0b37d2ab7b..f5bec9754c00 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1728,6 +1728,8 @@ #define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */ #define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */ +#define IXGBE_MFLCN_RPFCE_SHIFT 4 + /* Multiple Receive Queue Control */ #define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */ #define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */ -- GitLab From 8849b720e9632acef139a349f9ec62e63ce7e497 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 14 Apr 2011 00:20:07 -0700 Subject: [PATCH 0943/5560] NET: AX.25, NETROM, ROSE: Remove SOCK_DEBUG calls Nobody alive seems to recall when they last were useful. Signed-off-by: Ralf Baechle Signed-off-by: David S. Miller --- net/ax25/af_ax25.c | 16 +--------------- net/netrom/af_netrom.c | 12 +----------- net/rose/af_rose.c | 16 ++-------------- 3 files changed, 4 insertions(+), 40 deletions(-) diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 6da5daeebab7..e7c69f4619ec 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1538,8 +1538,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, } /* Build a packet */ - SOCK_DEBUG(sk, "AX.25: sendto: Addresses built. Building packet.\n"); - /* Assume the worst case */ size = len + ax25->ax25_dev->dev->hard_header_len; @@ -1549,8 +1547,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reserve(skb, size - len); - SOCK_DEBUG(sk, "AX.25: Appending user data\n"); - /* User data follows immediately after the AX.25 data */ if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { err = -EFAULT; @@ -1564,8 +1560,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, if (!ax25->pidincl) *skb_push(skb, 1) = sk->sk_protocol; - SOCK_DEBUG(sk, "AX.25: Transmitting buffer\n"); - if (sk->sk_type == SOCK_SEQPACKET) { /* Connected mode sockets go via the LAPB machine */ if (sk->sk_state != TCP_ESTABLISHED) { @@ -1583,22 +1577,14 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, skb_push(skb, 1 + ax25_addr_size(dp)); - SOCK_DEBUG(sk, "Building AX.25 Header (dp=%p).\n", dp); - - if (dp != NULL) - SOCK_DEBUG(sk, "Num digipeaters=%d\n", dp->ndigi); + /* Building AX.25 Header */ /* Build an AX.25 header */ lv = ax25_addr_build(skb->data, &ax25->source_addr, &sax.sax25_call, dp, AX25_COMMAND, AX25_MODULUS); - SOCK_DEBUG(sk, "Built header (%d bytes)\n",lv); - skb_set_transport_header(skb, lv); - SOCK_DEBUG(sk, "base=%p pos=%p\n", - skb->data, skb_transport_header(skb)); - *skb_transport_header(skb) = AX25_UI; /* Datagram frames go straight out of the door as UI */ diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 06cb02796a0e..732152f718e0 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -591,7 +591,6 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) return -EINVAL; } if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) { - SOCK_DEBUG(sk, "NET/ROM: bind failed: invalid node callsign\n"); release_sock(sk); return -EADDRNOTAVAIL; } @@ -632,7 +631,7 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) sock_reset_flag(sk, SOCK_ZAPPED); dev_put(dev); release_sock(sk); - SOCK_DEBUG(sk, "NET/ROM: socket is bound\n"); + return 0; } @@ -1082,8 +1081,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, sax.sax25_call = nr->dest_addr; } - SOCK_DEBUG(sk, "NET/ROM: sendto: Addresses built.\n"); - /* Build a packet - the conventional user limit is 236 bytes. We can do ludicrously large NetROM frames but must not overflow */ if (len > 65536) { @@ -1091,7 +1088,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, goto out; } - SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n"); size = len + NR_NETWORK_LEN + NR_TRANSPORT_LEN; if ((skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL) @@ -1105,7 +1101,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, */ asmptr = skb_push(skb, NR_TRANSPORT_LEN); - SOCK_DEBUG(sk, "Building NET/ROM Header.\n"); /* Build a NET/ROM Transport header */ @@ -1114,15 +1109,12 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, *asmptr++ = 0; /* To be filled in later */ *asmptr++ = 0; /* Ditto */ *asmptr++ = NR_INFO; - SOCK_DEBUG(sk, "Built header.\n"); /* * Put the data on the end */ skb_put(skb, len); - SOCK_DEBUG(sk, "NET/ROM: Appending user data\n"); - /* User data follows immediately after the NET/ROM transport header */ if (memcpy_fromiovec(skb_transport_header(skb), msg->msg_iov, len)) { kfree_skb(skb); @@ -1130,8 +1122,6 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock, goto out; } - SOCK_DEBUG(sk, "NET/ROM: Transmitting buffer\n"); - if (sk->sk_state != TCP_ESTABLISHED) { kfree_skb(skb); err = -ENOTCONN; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index a80aef6e3d1f..f9ea925ad9cb 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -682,10 +682,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) return -EINVAL; - if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { - SOCK_DEBUG(sk, "ROSE: bind failed: invalid address\n"); + if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) return -EADDRNOTAVAIL; - } source = &addr->srose_call; @@ -716,7 +714,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) rose_insert_socket(sk); sock_reset_flag(sk, SOCK_ZAPPED); - SOCK_DEBUG(sk, "ROSE: socket is bound\n"); + return 0; } @@ -1109,10 +1107,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, srose.srose_digis[n] = rose->dest_digis[n]; } - SOCK_DEBUG(sk, "ROSE: sendto: Addresses built.\n"); - /* Build a packet */ - SOCK_DEBUG(sk, "ROSE: sendto: building packet.\n"); /* Sanity check the packet size */ if (len > 65535) return -EMSGSIZE; @@ -1127,7 +1122,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, /* * Put the data on the end */ - SOCK_DEBUG(sk, "ROSE: Appending user data\n"); skb_reset_transport_header(skb); skb_put(skb, len); @@ -1152,8 +1146,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, */ asmptr = skb_push(skb, ROSE_MIN_LEN); - SOCK_DEBUG(sk, "ROSE: Building Network Header.\n"); - /* Build a ROSE Network header */ asmptr[0] = ((rose->lci >> 8) & 0x0F) | ROSE_GFI; asmptr[1] = (rose->lci >> 0) & 0xFF; @@ -1162,10 +1154,6 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock, if (qbit) asmptr[0] |= ROSE_Q_BIT; - SOCK_DEBUG(sk, "ROSE: Built header.\n"); - - SOCK_DEBUG(sk, "ROSE: Transmitting buffer\n"); - if (sk->sk_state != TCP_ESTABLISHED) { kfree_skb(skb); return -ENOTCONN; -- GitLab From e10b376e98332edcc2530aaed384a7e248477052 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 21 Mar 2011 16:50:18 +0200 Subject: [PATCH 0944/5560] UBI: make the control character device non-seekable This patch makes the UBI control device (/dev/ubi_ctrl) non-seekable. The seek operation does is not applicable to this file, so it is cleaner to explicitly return error (which the added 'no_llseek()') does than trying to change the position (which the removed 'default_llseek()' does). This is an API break, but the only known user of this interface is mtd-utils which does not need the seeking functionality. And any app which relies on this is broken, but I'm not aware of such apps. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index af9fb0ff8210..9a1703286411 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1100,5 +1100,5 @@ const struct file_operations ubi_ctrl_cdev_operations = { .owner = THIS_MODULE, .unlocked_ioctl = ctrl_cdev_ioctl, .compat_ioctl = ctrl_cdev_compat_ioctl, - .llseek = noop_llseek, + .llseek = no_llseek, }; -- GitLab From 6748482f4153fc0e095aa3dc831d5edac5656a80 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 15 Mar 2011 16:25:38 +0200 Subject: [PATCH 0945/5560] UBI: re-name set volume properties ioctl Rename the ioctl which sets volume properties from 'UBI_IOCSETPROP' to 'UBI_IOCSETVOLPROP' to reflect the fact that this ioctl is about volume properties, not device properties. This is also consistent with the other volume ioctl name - 'UBI_IOCVOLUP'. The main motivation for the re-name, however, is that we are going to introduce the per-UBI device "set properties" ioctl, so we need good and logical naming. At the same time, re-name the "set volume properties request" data structure from 'struct ubi_set_prop_req' to 'struct ubi_set_vol_prop_req'. And re-name 'UBI_PROP_DIRECT_WRITE' to 'UBI_VOL_PROP_DIRECT_WRITE'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 8 ++++---- include/mtd/ubi-user.h | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 9a1703286411..4119cb857c97 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -561,18 +561,18 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, } /* Set volume property command */ - case UBI_IOCSETPROP: + case UBI_IOCSETVOLPROP: { - struct ubi_set_prop_req req; + struct ubi_set_vol_prop_req req; err = copy_from_user(&req, argp, - sizeof(struct ubi_set_prop_req)); + sizeof(struct ubi_set_vol_prop_req)); if (err) { err = -EFAULT; break; } switch (req.property) { - case UBI_PROP_DIRECT_WRITE: + case UBI_VOL_PROP_DIRECT_WRITE: mutex_lock(&ubi->device_mutex); desc->vol->direct_writes = !!req.value; mutex_unlock(&ubi->device_mutex); diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index c0d47ad4b103..8d8484b1ed46 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -131,7 +131,7 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~ * * To set an UBI volume property the %UBI_IOCSETPROP ioctl command should be - * used. A pointer to a &struct ubi_set_prop_req object is expected to be + * used. A pointer to a &struct ubi_set_vol_prop_req object is expected to be * passed. The object describes which property should be set, and to which value * it should be set. */ @@ -186,7 +186,8 @@ /* Check if LEB is mapped command */ #define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, __s32) /* Set an UBI volume property */ -#define UBI_IOCSETPROP _IOW(UBI_VOL_IOC_MAGIC, 6, struct ubi_set_prop_req) +#define UBI_IOCSETVOLPROP _IOW(UBI_VOL_IOC_MAGIC, 6, \ + struct ubi_set_vol_prop_req) /* Maximum MTD device name length supported by UBI */ #define MAX_UBI_MTD_NAME_LEN 127 @@ -225,11 +226,11 @@ enum { /* * UBI set property ioctl constants * - * @UBI_PROP_DIRECT_WRITE: allow / disallow user to directly write and - * erase individual eraseblocks on dynamic volumes + * @UBI_VOL_PROP_DIRECT_WRITE: allow / disallow user to directly write and + * erase individual eraseblocks on dynamic volumes */ enum { - UBI_PROP_DIRECT_WRITE = 1, + UBI_VOL_PROP_DIRECT_WRITE = 1, }; /** @@ -397,13 +398,13 @@ struct ubi_map_req { /** - * struct ubi_set_prop_req - a data structure used to set an ubi volume - * property. - * @property: property to set (%UBI_PROP_DIRECT_WRITE) + * struct ubi_set_vol_prop_req - a data structure used to set an ubi volume + * property. + * @property: property to set (%UBI_VOL_PROP_DIRECT_WRITE) * @padding: reserved for future, not used, has to be zeroed * @value: value to set */ -struct ubi_set_prop_req { +struct ubi_set_vol_prop_req { __u8 property; __u8 padding[7]; __u64 value; -- GitLab From e8e088de305d7cc00b2c8b2a857ceb62d5fa68d3 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 15 Mar 2011 16:37:57 +0200 Subject: [PATCH 0946/5560] UBI: cleanup comments around volume properties Cleanup and improve commentaries around the "set volume properties" ioctl, make a simple indentation fix as well. Signed-off-by: Artem Bityutskiy --- include/mtd/ubi-user.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 8d8484b1ed46..e70bd347dbbb 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -224,13 +224,14 @@ enum { }; /* - * UBI set property ioctl constants + * UBI set volume property ioctl constants. * - * @UBI_VOL_PROP_DIRECT_WRITE: allow / disallow user to directly write and - * erase individual eraseblocks on dynamic volumes + * @UBI_VOL_PROP_DIRECT_WRITE: allow (any non-zero value) or disallow (value 0) + * user to directly write and erase individual + * eraseblocks on dynamic volumes */ enum { - UBI_VOL_PROP_DIRECT_WRITE = 1, + UBI_VOL_PROP_DIRECT_WRITE = 1, }; /** @@ -398,7 +399,7 @@ struct ubi_map_req { /** - * struct ubi_set_vol_prop_req - a data structure used to set an ubi volume + * struct ubi_set_vol_prop_req - a data structure used to set an UBI volume * property. * @property: property to set (%UBI_VOL_PROP_DIRECT_WRITE) * @padding: reserved for future, not used, has to be zeroed -- GitLab From 3627924acf70a9a26587712e4888ee7144489678 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 28 Mar 2011 10:04:09 +0300 Subject: [PATCH 0947/5560] UBI: use __packed instead of __attribute__((packed)) There was an attempt to standartize various "__attribute__" and other macros in order to have potentially portable and more consistent code, see commit 82ddcb040570411fc2d421d96b3e69711c670328. Note, that commit refers Rober Love's blog post, but the URL is broken, the valid URL is: http://blog.rlove.org/2005/10/with-little-help-from-your-compiler.html Moreover, nowadays checkpatch.pl warns about using __attribute__((packed)): "WARNING: __packed is preferred over __attribute__((packed))" It is not a big deal for UBI to use __packed, so let's do it. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi-media.h | 6 +++--- include/mtd/ubi-user.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 503ea9b27309..6fb8ec2174a5 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h @@ -164,7 +164,7 @@ struct ubi_ec_hdr { __be32 image_seq; __u8 padding2[32]; __be32 hdr_crc; -} __attribute__ ((packed)); +} __packed; /** * struct ubi_vid_hdr - on-flash UBI volume identifier header. @@ -292,7 +292,7 @@ struct ubi_vid_hdr { __be64 sqnum; __u8 padding3[12]; __be32 hdr_crc; -} __attribute__ ((packed)); +} __packed; /* Internal UBI volumes count */ #define UBI_INT_VOL_COUNT 1 @@ -373,6 +373,6 @@ struct ubi_vtbl_record { __u8 flags; __u8 padding[23]; __be32 crc; -} __attribute__ ((packed)); +} __packed; #endif /* !__UBI_MEDIA_H__ */ diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index e70bd347dbbb..a3903423c005 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -310,7 +310,7 @@ struct ubi_mkvol_req { __s16 name_len; __s8 padding2[4]; char name[UBI_MAX_VOLUME_NAME + 1]; -} __attribute__ ((packed)); +} __packed; /** * struct ubi_rsvol_req - a data structure used in volume re-size requests. @@ -326,7 +326,7 @@ struct ubi_mkvol_req { struct ubi_rsvol_req { __s64 bytes; __s32 vol_id; -} __attribute__ ((packed)); +} __packed; /** * struct ubi_rnvol_req - volumes re-name request. @@ -368,7 +368,7 @@ struct ubi_rnvol_req { __s8 padding2[2]; char name[UBI_MAX_VOLUME_NAME + 1]; } ents[UBI_MAX_RNVOL]; -} __attribute__ ((packed)); +} __packed; /** * struct ubi_leb_change_req - a data structure used in atomic LEB change @@ -383,7 +383,7 @@ struct ubi_leb_change_req { __s32 bytes; __s8 dtype; __s8 padding[7]; -} __attribute__ ((packed)); +} __packed; /** * struct ubi_map_req - a data structure used in map LEB requests. @@ -395,7 +395,7 @@ struct ubi_map_req { __s32 lnum; __s8 dtype; __s8 padding[3]; -} __attribute__ ((packed)); +} __packed; /** @@ -409,6 +409,6 @@ struct ubi_set_vol_prop_req { __u8 property; __u8 padding[7]; __u64 value; -} __attribute__ ((packed)); +} __packed; #endif /* __UBI_USER_H__ */ -- GitLab From feddbb34ebd75e9b6bf573b852079e327a88c07a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 28 Mar 2011 10:12:25 +0300 Subject: [PATCH 0948/5560] UBI: fix minor stylistic issues Fix checkpatch.pl errors and warnings: * space before tab * line over 80 characters * include linux/ioctl.h instead of asm/ioctl.h Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 4 ++-- drivers/mtd/ubi/debug.c | 18 +++++++++--------- drivers/mtd/ubi/io.c | 4 ++-- drivers/mtd/ubi/scan.c | 2 +- drivers/mtd/ubi/ubi.h | 4 ++-- drivers/mtd/ubi/wl.c | 3 ++- include/linux/mtd/ubi.h | 4 ++-- include/mtd/ubi-user.h | 6 +++--- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 4119cb857c97..191f3bb3c41a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -115,7 +115,7 @@ static int vol_cdev_open(struct inode *inode, struct file *file) mode = UBI_READONLY; dbg_gen("open device %d, volume %d, mode %d", - ubi_num, vol_id, mode); + ubi_num, vol_id, mode); desc = ubi_open_volume(ubi_num, vol_id, mode); if (IS_ERR(desc)) @@ -158,7 +158,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) loff_t new_offset; if (vol->updating) { - /* Update is in progress, seeking is prohibited */ + /* Update is in progress, seeking is prohibited */ dbg_err("updating"); return -EBUSY; } diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index d4d07e5f138f..0cd5beabe9c9 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -75,15 +75,15 @@ void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { printk(KERN_DEBUG "Volume identifier header dump:\n"); printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); - printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version); - printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type); - printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag); - printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat); - printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); - printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); - printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); - printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); - printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); + printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version); + printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type); + printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag); + printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat); + printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); + printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); + printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); + printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); + printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); printk(KERN_DEBUG "\tsqnum %llu\n", (unsigned long long)be64_to_cpu(vid_hdr->sqnum)); printk(KERN_DEBUG "\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc)); diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index e347cc4388ed..d58ceb1ca8fd 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -189,8 +189,8 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, } if (retries++ < UBI_IO_RETRIES) { - dbg_io("error %d%s while reading %d bytes from PEB %d:%d," - " read only %zd bytes, retry", + dbg_io("error %d%s while reading %d bytes from PEB " + "%d:%d, read only %zd bytes, retry", err, errstr, len, pnum, offset, read); yield(); goto retry; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index d2d12ab7def4..2135a53732ff 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1103,7 +1103,7 @@ static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si) * otherwise, only print a warning. */ if (si->corr_peb_count >= max_corr) { - ubi_err("too many corrupted PEBs, refusing this device"); + ubi_err("too many corrupted PEBs, refusing"); return -EINVAL; } } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index f1be8b79663c..c6c22295898e 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -341,8 +341,8 @@ struct ubi_wl_entry; * protected from the wear-leveling worker) * @pq_head: protection queue head * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from, - * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, - * @erroneous, and @erroneous_peb_count fields + * @move_to, @move_to_put @erase_pending, @wl_scheduled, @works, + * @erroneous, and @erroneous_peb_count fields * @move_mutex: serializes eraseblock moves * @work_sem: synchronizes the WL worker with use tasks * @wl_scheduled: non-zero if the wear-leveling was scheduled diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b4cf57db2556..ff2c4956eeff 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1570,7 +1570,8 @@ void ubi_wl_close(struct ubi_device *ubi) * @ec: the erase counter to check * * This function returns zero if the erase counter of physical eraseblock @pnum - * is equivalent to @ec, and a negative error code if not or if an error occurred. + * is equivalent to @ec, and a negative error code if not or if an error + * occurred. */ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) { diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h index 84854edf4436..15da0e99f48a 100644 --- a/include/linux/mtd/ubi.h +++ b/include/linux/mtd/ubi.h @@ -21,7 +21,7 @@ #ifndef __LINUX_UBI_H__ #define __LINUX_UBI_H__ -#include +#include #include #include @@ -87,7 +87,7 @@ enum { * physical eraseblock size and on how much bytes UBI headers consume. But * because of the volume alignment (@alignment), the usable size of logical * eraseblocks if a volume may be less. The following equation is true: - * @usable_leb_size = LEB size - (LEB size mod @alignment), + * @usable_leb_size = LEB size - (LEB size mod @alignment), * where LEB size is the logical eraseblock size defined by the UBI device. * * The alignment is multiple to the minimal flash input/output unit size or %1 diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index a3903423c005..3c4109777aff 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -406,9 +406,9 @@ struct ubi_map_req { * @value: value to set */ struct ubi_set_vol_prop_req { - __u8 property; - __u8 padding[7]; - __u64 value; + __u8 property; + __u8 padding[7]; + __u64 value; } __packed; #endif /* __UBI_USER_H__ */ -- GitLab From 9cdc352936311eea55624cbabafda296b99ff137 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 11 Apr 2011 17:56:32 +0200 Subject: [PATCH 0949/5560] ALSA: usb-audio: Add quirks for Audio Kontrol 6 This new device by Native Instruments is also compliant to the USB standard v2.0, but hides this detail at when connected. It needs the same boot quirks than other models, and also has two non-class-compliant mixer controls. Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 17 +++++++++++++++++ sound/usb/quirks-table.h | 6 ++++++ sound/usb/quirks.c | 1 + 3 files changed, 24 insertions(+) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 73dcc8256bc0..4a7ad7ed62f7 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -398,6 +398,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, return 0; } +static struct snd_kcontrol_new snd_nativeinstruments_ak6_mixers[] = { + { + .name = "Direct Monitor Channel 1+2", + .private_value = _MAKE_NI_CONTROL(0x03, 0x03), + }, + { + .name = "Direct Monitor Channel 3+4", + .private_value = _MAKE_NI_CONTROL(0x03, 0x05), + }, +}; + static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = { { .name = "Direct Thru Channel A", @@ -526,6 +537,12 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) err = snd_xonar_u1_controls_create(mixer); break; + case USB_ID(0x17cc, 0x1001): /* Audio Kontrol 6 */ + err = snd_nativeinstruments_create_mixer(mixer, + snd_nativeinstruments_ak6_mixers, + ARRAY_SIZE(snd_nativeinstruments_ak6_mixers)); + break; + case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */ err = snd_nativeinstruments_create_mixer(mixer, snd_nativeinstruments_ta6_mixers, diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c66d3f64dcf8..54e18c181a12 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -2331,6 +2331,12 @@ YAMAHA_DEVICE(0x7010, "UB99"), }, /* Native Instruments MK2 series */ +{ + /* Audio Kontrol 6 */ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x17cc, + .idProduct = 0x1000, +}, { /* Traktor Audio 6 */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 355759bad581..2452edd2f141 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -539,6 +539,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, /* Access Music VirusTI Desktop */ return snd_usb_accessmusic_boot_quirk(dev); + case USB_ID(0x17cc, 0x1000): /* Audio Kontrol 6 */ case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ return snd_usb_nativeinstruments_boot_quirk(dev); -- GitLab From 1426414431a8d37a6e631e0b5e2ad6186b81876a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 14 Apr 2011 11:36:31 +0300 Subject: [PATCH 0950/5560] UBI: fix typo in a message When a PEB passes the torture test, UBI prints "do not mark it a bad", but should print "do not mark it as bad". This patch corrects the typo. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index d58ceb1ca8fd..8c1b1c7bc4a7 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -465,7 +465,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum) } err = patt_count; - ubi_msg("PEB %d passed torture test, do not mark it a bad", pnum); + ubi_msg("PEB %d passed torture test, do not mark it as bad", pnum); out: mutex_unlock(&ubi->buf_mutex); -- GitLab From dfa8fc69d92f8418e1296d762f3b1624df59f0ac Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 14 Apr 2011 10:38:22 -0400 Subject: [PATCH 0951/5560] ath9k: avoid using trinary operator w/ TX_STAT_INC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise, you get this: CC [M] drivers/net/wireless/ath/ath9k/hif_usb.o drivers/net/wireless/ath/ath9k/hif_usb.c: In function ‘ath9k_skb_queue_complete’: drivers/net/wireless/ath/ath9k/hif_usb.c:230:12: error: expected expression before ‘do’ make[2]: *** [drivers/net/wireless/ath/ath9k/hif_usb.o] Error 1 make[1]: *** [drivers/net/wireless/ath/ath9k] Error 2 make: *** [drivers/net/wireless/ath/] Error 2 The TX_STAT_INC macro should probably be changed to accomodate such usage, although using a trinary operator in place of an if-else seems questionable to me anyway. Signed-off-by: John W. Linville Acked-by: Sujith Manoharan --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 3b0efab65131..48bcc1a21076 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -227,7 +227,10 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, while ((skb = __skb_dequeue(queue)) != NULL) { ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, txok); - (txok) ? TX_STAT_INC(skb_success) : TX_STAT_INC(skb_failed); + if (txok) + TX_STAT_INC(skb_success); + else + TX_STAT_INC(skb_failed); } } -- GitLab From 10add41f2b7a7bc1a74ba7bb535a6745cac318a2 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 12 Apr 2011 17:29:29 +0530 Subject: [PATCH 0952/5560] ath9k: Fix improper beacon slot selection in IBSS Request a re-configuration of Beacon related timers on the receipt of the first Beacon frame has to be set only for station mode. Setting beacon sync for IBSS is causing wrong beacon slot selection on beacon generation. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b56f69e7677b..9193a385ceb2 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -744,7 +744,6 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) cur_conf->dtim_period = 1; ath_set_beacon(sc); - sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; } void ath_set_beacon(struct ath_softc *sc) @@ -762,6 +761,12 @@ void ath_set_beacon(struct ath_softc *sc) break; case NL80211_IFTYPE_STATION: ath_beacon_config_sta(sc, cur_conf); + /* + * Request a re-configuration of Beacon related timers + * on the receipt of the first Beacon frame (i.e., + * after time sync with the AP). + */ + sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; break; default: ath_dbg(common, ATH_DBG_CONFIG, -- GitLab From 7f94f05b24b47f6b70f2322b26876d0636329dfe Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:42 +0200 Subject: [PATCH 0953/5560] ath5k: disable 5 GHz support if a 2.4 GHz radio is detected On a dual-radio dual-band AR5312 device, the calibration data is shared between the 5 GHz and the 2.4 GHz radio/MAC. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/caps.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index f77e8a703c5c..7dd88e1c3ff8 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -94,6 +94,9 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) } } + if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112) + __clear_bit(AR5K_MODE_11A, caps->cap_mode); + /* Set number of supported TX queues */ if (ah->ah_version == AR5K_AR5210) caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; -- GitLab From 0cb9e06b6359bfa82f46c38a0b43e72d90b84081 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:43 +0200 Subject: [PATCH 0954/5560] ath: unshare struct ath_bus_ops between ath5k and ath9k This struct is not used in any common code, and moving it out of the ath header makes it easier to add more driver specific ops. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 9 +-------- drivers/net/wireless/ath/ath5k/ath5k.h | 6 ++++++ drivers/net/wireless/ath/ath9k/hw.h | 8 ++++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 6d7105b7e8f1..7cf4317a2a84 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -123,14 +123,7 @@ struct ath_ops { }; struct ath_common; - -struct ath_bus_ops { - enum ath_bus_type ath_bus_type; - 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_bus_ops; struct ath_common { void *ah; diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e303db7ee6f6..266e548acf78 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1155,6 +1155,12 @@ struct ath5k_hw { struct ath5k_rx_status *); }; +struct ath_bus_ops { + enum ath_bus_type ath_bus_type; + void (*read_cachesize)(struct ath_common *common, int *csz); + bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); +}; + /* * Prototypes */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a778b66f4438..073bc9e1c792 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -846,6 +846,14 @@ struct ath_hw { u32 ent_mode; }; +struct ath_bus_ops { + enum ath_bus_type ath_bus_type; + 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); +}; + static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) { return &ah->common; -- GitLab From fa9bfd61e03e8dbcf110a93b373234d17a732233 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:44 +0200 Subject: [PATCH 0955/5560] ath5k: add a new bus op for reading the mac address On AHB, the calibration data usually does not contain a valid MAC address, the correct MAC address is stored in the board config. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 18 ++++++++++++++ drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/base.c | 2 +- drivers/net/wireless/ath/ath5k/eeprom.c | 29 ---------------------- drivers/net/wireless/ath/ath5k/pci.c | 32 +++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 82324e98efef..1374e647f4e6 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -18,6 +18,7 @@ #include #include +#include #include #include "ath5k.h" #include "debug.h" @@ -62,10 +63,27 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) return 0; } +static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +{ + 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; + u8 *cfg_mac; + + if (to_platform_device(sc->dev)->id == 0) + cfg_mac = bcfg->config->wlan0_mac; + else + cfg_mac = bcfg->config->wlan1_mac; + + memcpy(mac, cfg_mac, ETH_ALEN); + 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, + .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, }; /*Initialization*/ diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 266e548acf78..bb50700436fe 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1159,6 +1159,7 @@ struct ath_bus_ops { enum ath_bus_type ath_bus_type; void (*read_cachesize)(struct ath_common *common, int *csz); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); + int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac); }; /* @@ -1244,7 +1245,6 @@ int ath5k_hw_dma_stop(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 */ diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c7da00454397..7583841fc29a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2880,7 +2880,7 @@ ath5k_init(struct ieee80211_hw *hw) INIT_WORK(&sc->reset_work, ath5k_reset_work); INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); - ret = ath5k_eeprom_read_mac(ah, mac); + ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); if (ret) { ATH5K_ERR(sc, "unable to read address from EEPROM\n"); goto err_queues; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index fb12027e0346..e9263e4c7f3e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1732,35 +1732,6 @@ 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; - - AR5K_EEPROM_READ(0x20, data); - - for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - AR5K_EEPROM_READ(offset, data); - - 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 * diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 66598a0d1df0..5cc4a2fe47b6 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "../ath.h" #include "ath5k.h" #include "debug.h" @@ -108,11 +109,42 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) return 0; } +/* + * Read the MAC address from eeprom or platform_data + */ +static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +{ + u8 mac_d[ETH_ALEN] = {}; + u32 total, offset; + u16 data; + int octet; + + AR5K_EEPROM_READ(0x20, data); + + for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { + AR5K_EEPROM_READ(offset, data); + + 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; +} + + /* 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, + .eeprom_read_mac = ath5k_pci_eeprom_read_mac, }; /********************\ -- GitLab From 32377b6cf75247cbdd0640efb43bef992efe3b68 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:45 +0200 Subject: [PATCH 0956/5560] ath5k: fix the EEPROM check for hw AES crypto support EEPROM version 5.0 adds a new field for disabling AES support, having an older version means that AES is present. This patch fixes hw AES crypto support on AR5312 boards, which have an older EEPROM version. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index bc8240560488..326d7c84c912 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -318,7 +318,7 @@ int ath5k_hw_init(struct ath5k_softc *sc) AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); if (srev >= AR5K_SREV_AR5212_V4 && - (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && + (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; -- GitLab From 3a9dddea89eb2132ba919fe04cb3b44a3b1e6db7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 13 Apr 2011 21:56:46 +0200 Subject: [PATCH 0957/5560] ath5k: disable 5 GHz support for the dualband PHY chip on dual-radio AR5312 There are two variants of AR5312 dual-band devices, one single-radio and the other one dual-radio. On the dual-radio board, the first MAC only supports 5 GHz, even though it has a dual-band PHY. The 2.4 GHz part of this phy is used in pass-through mode, connecting the second MAC with the second PHY. Disable 2.4 GHz for the first MAC on an AR5312, but only if the board configuration indicates a dual-radio device. Signed-off-by: Felix Fietkau Tested-by: Sedat Dilek Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 10 ++++++++++ drivers/net/wireless/ath/ath5k/attach.c | 5 +++++ drivers/net/wireless/ath/ath5k/base.h | 3 ++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 1374e647f4e6..ea9982781559 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -160,6 +160,16 @@ static int ath_ahb_probe(struct platform_device *pdev) else reg |= AR5K_AR5312_ENABLE_WLAN1; __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); + + /* + * On a dual-band AR5312, the multiband radio is only + * used as pass-through. Disable 2 GHz support in the + * driver for it + */ + if (to_platform_device(sc->dev)->id == 0 && + (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) == + (BD_WLAN1|BD_WLAN0)) + __set_bit(ATH_STAT_2G_DISABLED, sc->status); } ret = ath5k_init_softc(sc, &ath_ahb_bus_ops); diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 326d7c84c912..1588401de3c4 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -313,6 +313,11 @@ int ath5k_hw_init(struct ath5k_softc *sc) goto err; } + if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) { + __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode); + __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode); + } + /* Crypto settings */ common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 4c4e36064a3b..b294f3305011 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -193,12 +193,13 @@ struct ath5k_softc { dma_addr_t desc_daddr; /* DMA (physical) address */ size_t desc_len; /* size of TX/RX descriptors */ - DECLARE_BITMAP(status, 5); + DECLARE_BITMAP(status, 6); #define ATH_STAT_INVALID 0 /* disable hardware accesses */ #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ #define ATH_STAT_PROMISC 2 #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ +#define ATH_STAT_2G_DISABLED 5 /* multiband radio without 2G */ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ struct ieee80211_channel *curchan; /* current h/w channel */ -- GitLab From 600f5d909a54a8dccf8c8c23898fc2e91bc0953e Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 13 Apr 2011 17:27:06 -0700 Subject: [PATCH 0958/5560] mwifiex: cleanup ioctl wait queue and abstraction layer 1) remove mwifiex_alloc_fill_wait_queue() and mwifiex_request_ioctl() 2) avoid dynamic allocation of wait queue 3) remove unnecessary mwifiex_error_code macros that were used mainly by the wait queue status code 4) remove some abstraction functions 5) split mwifiex_prepare_cmd() to mwifiex_send_cmd_async() and mwifiex_send_sync() to handle asynchronous and synchronous commands respectively Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 13 +- drivers/net/wireless/mwifiex/11n_rxreorder.c | 2 +- drivers/net/wireless/mwifiex/README | 2 +- drivers/net/wireless/mwifiex/cfg80211.c | 113 +- drivers/net/wireless/mwifiex/cmdevt.c | 179 ++-- drivers/net/wireless/mwifiex/debugfs.c | 4 +- drivers/net/wireless/mwifiex/decl.h | 24 +- drivers/net/wireless/mwifiex/init.c | 3 +- drivers/net/wireless/mwifiex/join.c | 90 +- drivers/net/wireless/mwifiex/main.c | 71 +- drivers/net/wireless/mwifiex/main.h | 123 +-- drivers/net/wireless/mwifiex/scan.c | 126 +-- drivers/net/wireless/mwifiex/sdio.c | 11 +- drivers/net/wireless/mwifiex/sta_cmd.c | 60 +- drivers/net/wireless/mwifiex/sta_cmdresp.c | 29 +- drivers/net/wireless/mwifiex/sta_event.c | 25 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 1008 +++--------------- drivers/net/wireless/mwifiex/sta_tx.c | 2 +- drivers/net/wireless/mwifiex/util.c | 51 +- 19 files changed, 502 insertions(+), 1434 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 73a6e62f5680..edf4c274fa9b 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -541,9 +541,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; if (curr_tx_buf_size != tx_buf) - mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, - HostCmd_ACT_GEN_SET, 0, - NULL, &tx_buf); + mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, &tx_buf); return; } @@ -694,8 +693,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); /* We don't wait for the response of this command */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, - 0, 0, NULL, &add_ba_req); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ, + 0, 0, &add_ba_req); return ret; } @@ -722,8 +721,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); /* We don't wait for the response of this command */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, - HostCmd_ACT_GEN_SET, 0, NULL, &delba); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, + HostCmd_ACT_GEN_SET, 0, &delba); return ret; } diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 8e94e620e6f4..ef46d0a8a6d0 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -609,7 +609,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, delba.del_ba_param_set |= cpu_to_le16( (u16) event->origninator << DELBA_INITIATOR_POS); delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); - mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); + mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); return; } diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README index 338377f7093b..b55badef4660 100644 --- a/drivers/net/wireless/mwifiex/README +++ b/drivers/net/wireless/mwifiex/README @@ -157,7 +157,7 @@ info mp_wr_bitmap = cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> event_received = <0/1, no event to process/event received and yet to process> - ioctl_pending = + cmd_pending = tx_pending = rx_pending = diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ec0895f4e8d3..a1ff490da836 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -139,8 +139,16 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_power_cfg power_cfg; - ret = mwifiex_set_tx_power(priv, type, dbm); + if (type == NL80211_TX_POWER_FIXED) { + power_cfg.is_power_auto = 0; + power_cfg.power_level = dbm; + } else { + power_cfg.is_power_auto = 1; + } + + ret = mwifiex_set_tx_power(priv, &power_cfg); return ret; } @@ -157,13 +165,15 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + u32 ps_mode; if (timeout) wiphy_dbg(wiphy, "info: ignoring the timeout value" " for IEEE power save\n"); - ret = mwifiex_drv_set_power(priv, enabled); + ps_mode = enabled; + ret = mwifiex_drv_set_power(priv, &ps_mode); return ret; } @@ -291,8 +301,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) domain_info->no_of_triplet = no_of_triplet; /* Send cmd to FW to set domain info */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, - HostCmd_ACT_GEN_SET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) wiphy_err(wiphy, "11D: setting domain info in FW\n"); @@ -347,7 +357,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, { struct mwifiex_chan_freq_power cfp; int ret = 0; - int status = 0; struct mwifiex_ds_band_cfg band_cfg; u32 config_bands = 0; struct wiphy *wiphy = priv->wdev->wiphy; @@ -370,10 +379,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, band_cfg.sec_chan_offset = mwifiex_cfg80211_channel_type_to_mwifiex_channels (channel_type); - status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, - &band_cfg); + ret = mwifiex_set_radio_band_cfg(priv, &band_cfg); - if (status) + if (ret) return -EFAULT; mwifiex_send_domain_info_cmd_fw(wiphy); } @@ -389,8 +397,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, /* Convert frequency to channel */ cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); - status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); - if (status) + ret = mwifiex_bss_set_channel(priv, &cfp); + if (ret) return -EFAULT; ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); @@ -422,66 +430,45 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, /* * This function sets the fragmentation threshold. * - * This function creates an IOCTL request, populates it accordingly - * and issues an IOCTL. - * - * The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE + * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE * and MWIFIEX_FRAG_MAX_VALUE. */ static int mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; - u8 wait_option = MWIFIEX_IOCTL_WAIT; if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || frag_thr > MWIFIEX_FRAG_MAX_VALUE) return -EINVAL; - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, FRAG_THRESH_I, + &frag_thr); - status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I, - HostCmd_ACT_GEN_SET, &frag_thr); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) - ret = -EFAULT; - - kfree(wait); return ret; } /* * This function sets the RTS threshold. - * - * This function creates an IOCTL request, populates it accordingly - * and issues an IOCTL. + + * The rts value must lie between MWIFIEX_RTS_MIN_VALUE + * and MWIFIEX_RTS_MAX_VALUE. */ static int mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) { int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - u8 wait_option = MWIFIEX_IOCTL_WAIT; if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) rts_thr = MWIFIEX_RTS_MAX_VALUE; - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I, - HostCmd_ACT_GEN_SET, &rts_thr); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) - ret = -EFAULT; + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, RTS_THRESH_I, + &rts_thr); - kfree(wait); return ret; } @@ -518,7 +505,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, { int ret = 0; struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - struct mwifiex_wait_queue *wait = NULL; if (priv->bss_mode == type) { wiphy_warn(wiphy, "already set to required type\n"); @@ -545,24 +531,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, return -EINVAL; } - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - - mwifiex_deauthenticate(priv, wait, NULL); + mwifiex_deauthenticate(priv, NULL); priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, - HostCmd_ACT_GEN_SET, 0, wait, NULL); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE, + HostCmd_ACT_GEN_SET, 0, NULL); - ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT); - if (ret) - ret = -EFAULT; - - kfree(wait); return ret; } @@ -592,7 +567,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, /* Get signal information from the firmware */ memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); - if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { + if (mwifiex_get_signal_info(priv, &signal)) { dev_err(priv->adapter->dev, "getting signal information\n"); ret = -EFAULT; } @@ -750,7 +725,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, return -EBUSY; priv->disconnect = 1; - if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) + if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" @@ -838,8 +813,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, u8 element_id, element_len; memset(&scan_resp, 0, sizeof(scan_resp)); - if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) - return -EFAULT; + scan_resp.scan_table = (u8 *) priv->adapter->scan_table; + scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table; #define MAX_IE_BUF 2048 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); @@ -986,7 +961,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } /* disconnect before try to associate */ - mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); + mwifiex_deauthenticate(priv, NULL); if (channel) ret = mwifiex_set_rf_channel(priv, channel, @@ -1046,7 +1021,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } done: /* Do specific SSID scanning */ - if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { + if (mwifiex_request_scan(priv, &req_ssid)) { dev_err(priv->adapter->dev, "scan error\n"); return -EFAULT; } @@ -1055,8 +1030,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); if (mode != NL80211_IFTYPE_ADHOC) { - if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, - &ssid_bssid)) + if (mwifiex_find_best_bss(priv, &ssid_bssid)) return -EFAULT; /* Inform the BSS information to kernel, otherwise * kernel will give a panic after successful assoc */ @@ -1072,7 +1046,10 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, /* Connect to BSS by ESSID */ memset(&ssid_bssid.bssid, 0, ETH_ALEN); - if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); + + if (mwifiex_bss_start(priv, &ssid_bssid)) return -EFAULT; if (mode == NL80211_IFTYPE_ADHOC) { @@ -1176,7 +1153,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", priv->cfg_bssid); - if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) + if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; queue_work(priv->workqueue, &priv->cfg_workqueue); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8676480ead94..bb6fecd77619 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -36,11 +36,12 @@ static void mwifiex_init_cmd_node(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node, - u32 cmd_oid, void *wait_queue, void *data_buf) + u32 cmd_oid, void *data_buf) { cmd_node->priv = priv; cmd_node->cmd_oid = cmd_oid; - cmd_node->wq_buf = wait_queue; + cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required; + priv->adapter->cmd_wait_q_required = false; cmd_node->data_buf = data_buf; cmd_node->cmd_skb = cmd_node->skb; } @@ -86,8 +87,8 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, { cmd_node->cmd_oid = 0; cmd_node->cmd_flag = 0; - cmd_node->wq_buf = NULL; cmd_node->data_buf = NULL; + cmd_node->wait_q_enabled = false; if (cmd_node->resp_skb) { mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); @@ -97,30 +98,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, return; } -/* - * This function returns a command node from the pending queue which - * matches the given IOCTL request. - */ -static struct cmd_ctrl_node * -mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue) -{ - unsigned long flags; - struct cmd_ctrl_node *cmd_node; - - spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); - list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { - if (cmd_node->wq_buf == wait_queue) { - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, - flags); - return cmd_node; - } - } - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); - - return NULL; -} - /* * This function sends a host command to the firmware. * @@ -155,7 +132,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; struct host_cmd_ds_command *host_cmd; - struct mwifiex_wait_queue *wait_queue = NULL; uint16_t cmd_code; uint16_t cmd_size; struct timeval tstamp; @@ -165,15 +141,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, return -1; host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); - if (cmd_node->wq_buf) - wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; /* Sanity test */ if (host_cmd == NULL || host_cmd->size == 0) { dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" " or cmd size is 0, not sending\n"); - if (wait_queue) - wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -1; mwifiex_insert_cmd_to_free_q(adapter, cmd_node); return -1; } @@ -210,8 +184,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, if (ret == -1) { dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); - if (wait_queue) - wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -1; mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); @@ -437,7 +411,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) } /* - * This function prepares a command before sending it to the firmware. + * This function is used to send synchronous command to the firmware. + * + * it allocates a wait queue for the command and wait for the command + * response. + */ +int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf) +{ + int ret = 0; + struct mwifiex_adapter *adapter = priv->adapter; + + adapter->cmd_wait_q_required = true; + adapter->cmd_wait_q.condition = false; + + ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, + data_buf); + if (!ret) + ret = mwifiex_wait_queue_complete(adapter); + + return ret; +} + + +/* + * This function prepares a command and asynchronously send it to the firmware. * * Preparation includes - * - Sanity tests to make sure the card is still present or the FW @@ -447,9 +445,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) * - Fill up the non-default parameters and buffer pointers * - Add the command to pending queue */ -int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, - u16 cmd_action, u32 cmd_oid, - void *wait_queue, void *data_buf) +int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -487,7 +484,7 @@ int mwifiex_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, } /* Initialize the command node */ - mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, wait_queue, data_buf); + mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf); if (!cmd_node->cmd_skb) { dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n"); @@ -537,18 +534,13 @@ void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node) { - struct mwifiex_wait_queue *wait_queue = NULL; unsigned long flags; if (cmd_node == NULL) return; - if (cmd_node->wq_buf) { - wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; - if (wait_queue->status != MWIFIEX_ERROR_NO_ERROR) - mwifiex_ioctl_complete(adapter, wait_queue, -1); - else - mwifiex_ioctl_complete(adapter, wait_queue, 0); - } + + if (cmd_node->wait_q_enabled) + mwifiex_complete_cmd(adapter); /* Clean the node */ mwifiex_clean_cmd_node(adapter, cmd_node); @@ -694,7 +686,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) uint16_t orig_cmdresp_no; uint16_t cmdresp_no; uint16_t cmdresp_result; - struct mwifiex_wait_queue *wait_queue = NULL; struct timeval tstamp; unsigned long flags; @@ -708,10 +699,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) return -1; } - if (adapter->curr_cmd->wq_buf) - wait_queue = (struct mwifiex_wait_queue *) - adapter->curr_cmd->wq_buf; - adapter->num_cmd_timeout = 0; resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; @@ -766,8 +753,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (!(orig_cmdresp_no & HostCmd_RET_BIT)) { dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n"); - if (wait_queue) - wait_queue->status = MWIFIEX_ERROR_FW_CMDRESP; + if (adapter->curr_cmd->wait_q_enabled) + adapter->cmd_wait_q.status = -1; mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); @@ -783,8 +770,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) ret = mwifiex_ret_802_11_hs_cfg(priv, resp); } else { /* handle response */ - ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp, - wait_queue); + ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp); } /* Check init command response */ @@ -799,10 +785,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) } if (adapter->curr_cmd) { - if (wait_queue && (!ret)) - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; - else if (wait_queue && (ret == -1)) - wait_queue->status = MWIFIEX_ERROR_CMD_RESP_FAIL; + if (adapter->curr_cmd->wait_q_enabled && (!ret)) + adapter->cmd_wait_q.status = 0; + else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) + adapter->cmd_wait_q.status = -1; /* Clean up and put current command back to cmd_free_q */ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); @@ -826,7 +812,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) struct mwifiex_adapter *adapter = (struct mwifiex_adapter *) function_context; struct cmd_ctrl_node *cmd_node = NULL; - struct mwifiex_wait_queue *wait_queue = NULL; struct timeval tstamp; adapter->num_cmd_timeout++; @@ -836,10 +821,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; - if (cmd_node->wq_buf) { - wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf; - wait_queue->status = MWIFIEX_ERROR_CMD_TIMEOUT; - } + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -ETIMEDOUT; if (cmd_node) { adapter->dbg.timeout_cmd_id = @@ -903,18 +886,15 @@ void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; - struct mwifiex_wait_queue *wait_queue = NULL; unsigned long flags; /* Cancel current cmd */ - if ((adapter->curr_cmd) && (adapter->curr_cmd->wq_buf)) { - wait_queue = - (struct mwifiex_wait_queue *) adapter->curr_cmd->wq_buf; + if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); - adapter->curr_cmd->wq_buf = NULL; + adapter->curr_cmd->wait_q_enabled = false; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; - mwifiex_ioctl_complete(adapter, wait_queue, -1); + adapter->cmd_wait_q.status = -1; + mwifiex_complete_cmd(adapter); } /* Cancel all pending command */ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); @@ -923,12 +903,10 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); - if (cmd_node->wq_buf) { - wait_queue = - (struct mwifiex_wait_queue *) cmd_node->wq_buf; - wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; - mwifiex_ioctl_complete(adapter, wait_queue, -1); - cmd_node->wq_buf = NULL; + if (cmd_node->wait_q_enabled) { + adapter->cmd_wait_q.status = -1; + mwifiex_complete_cmd(adapter); + cmd_node->wait_q_enabled = false; } mwifiex_insert_cmd_to_free_q(adapter, cmd_node); spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags); @@ -942,7 +920,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - cmd_node->wq_buf = NULL; + cmd_node->wait_q_enabled = false; mwifiex_insert_cmd_to_free_q(adapter, cmd_node); spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); } @@ -964,8 +942,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) * are cancelled. */ void -mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue) +mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; unsigned long cmd_flags; @@ -974,45 +951,33 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, uint16_t cancel_scan_cmd = false; if ((adapter->curr_cmd) && - (adapter->curr_cmd->wq_buf == wait_queue)) { + (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); cmd_node = adapter->curr_cmd; - cmd_node->wq_buf = NULL; + cmd_node->wait_q_enabled = false; cmd_node->cmd_flag |= CMD_F_CANCELED; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); - } - - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); - while (1) { - cmd_node = mwifiex_get_pending_ioctl_cmd(adapter, wait_queue); - if (!cmd_node) - break; - spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, cmd_pending_q_flags); - - cmd_node->wq_buf = NULL; mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + /* Cancel all pending scan command */ spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_pending_q_flags); list_for_each_entry_safe(cmd_node, tmp_node, &adapter->scan_pending_q, list) { - if (cmd_node->wq_buf == wait_queue) { - list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - scan_pending_q_flags); - cmd_node->wq_buf = NULL; - mwifiex_insert_cmd_to_free_q(adapter, cmd_node); - spin_lock_irqsave(&adapter->scan_pending_q_lock, - scan_pending_q_flags); - cancel_scan_cmd = true; - } + list_del(&cmd_node->list); + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + cmd_node->wait_q_enabled = false; + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + spin_lock_irqsave(&adapter->scan_pending_q_lock, + scan_pending_q_flags); + cancel_scan_cmd = true; } spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_pending_q_flags); @@ -1022,8 +987,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, adapter->scan_processing = false; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } - wait_queue->status = MWIFIEX_ERROR_CMD_CANCEL; - mwifiex_ioctl_complete(adapter, wait_queue, -1); + adapter->cmd_wait_q.status = -1; + mwifiex_complete_cmd(adapter); return; } diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 63b09692f27d..77d7c777ea66 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -129,8 +129,8 @@ static struct mwifiex_debug_data items[] = { item_addr(event_received), 1}, /* variables defined in struct mwifiex_adapter */ - {"ioctl_pending", adapter_item_size(ioctl_pending), - adapter_item_addr(ioctl_pending), 1}, + {"cmd_pending", adapter_item_size(cmd_pending), + adapter_item_addr(cmd_pending), 1}, {"tx_pending", adapter_item_size(tx_pending), adapter_item_addr(tx_pending), 1}, {"rx_pending", adapter_item_size(rx_pending), diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index c3c15f9e757e..8364b62c3298 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -61,23 +61,6 @@ #define MWIFIEX_BUF_FLAG_REQUEUED_PKT BIT(0) -enum mwifiex_error_code { - MWIFIEX_ERROR_NO_ERROR = 0, - MWIFIEX_ERROR_FW_NOT_READY = 0x00000001, - MWIFIEX_ERROR_FW_BUSY, - MWIFIEX_ERROR_FW_CMDRESP, - MWIFIEX_ERROR_PKT_SIZE_INVALID = 0x80000001, - MWIFIEX_ERROR_PKT_TIMEOUT, - MWIFIEX_ERROR_CMD_INVALID, - MWIFIEX_ERROR_CMD_TIMEOUT, - MWIFIEX_ERROR_CMD_DNLD_FAIL, - MWIFIEX_ERROR_CMD_CANCEL, - MWIFIEX_ERROR_CMD_RESP_FAIL, - MWIFIEX_ERROR_ASSOC_FAIL, - MWIFIEX_ERROR_EVENT_UNKNOWN, - MWIFIEX_ERROR_INVALID_PARAMETER, -}; - enum mwifiex_bss_type { MWIFIEX_BSS_TYPE_STA = 0, MWIFIEX_BSS_TYPE_UAP = 1, @@ -112,12 +95,9 @@ struct mwifiex_802_11_ssid { }; struct mwifiex_wait_queue { - u32 bss_index; - wait_queue_head_t *wait; - u16 *condition; - u32 start_time; + wait_queue_head_t wait; + u16 condition; int status; - u32 enabled; }; struct mwifiex_rxinfo { diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 8189862da1f9..26931d5f950f 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -35,7 +35,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bss_prio; - int status = 0; unsigned long flags; bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); @@ -59,7 +58,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] .bss_prio_lock, flags); - return status; + return 0; } /* diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 7a9e0b5962ed..60d25c690c07 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -590,11 +590,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, * an association success (0) or failure (non-zero). */ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, void *wq_buf) + struct host_cmd_ds_command *resp) { + struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; - struct mwifiex_wait_queue *wait_queue = - (struct mwifiex_wait_queue *) wq_buf; struct ieee_types_assoc_rsp *assoc_rsp; struct mwifiex_bssdescriptor *bss_desc; u8 enable_data = true; @@ -718,16 +717,11 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, done: /* Need to indicate IOCTL complete */ - if (wait_queue) { - if (ret) { - if (assoc_rsp->status_code) - wait_queue->status = - le16_to_cpu(assoc_rsp->status_code); - else - wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; - } else { - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; - } + if (adapter->curr_cmd->wait_q_enabled) { + if (ret) + adapter->cmd_wait_q.status = -1; + else + adapter->cmd_wait_q.status = 0; } return ret; @@ -885,9 +879,9 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); if ((adapter->adhoc_start_band & BAND_G) && (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, - 0, NULL, &priv->curr_pkt_filter); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter); if (ret) { dev_err(adapter->dev, @@ -1066,9 +1060,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, priv-> curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, NULL, - &curr_pkt_filter); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &curr_pkt_filter); if (ret) { dev_err(priv->adapter->dev, "ADHOC_J_CMD: G Protection config failed\n"); @@ -1192,11 +1186,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, * saves the beacon buffer. */ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, void *wq_buf) + struct host_cmd_ds_command *resp) { int ret = 0; - struct mwifiex_wait_queue *wait_queue = - (struct mwifiex_wait_queue *) wq_buf; + struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; struct mwifiex_bssdescriptor *bss_desc; u16 command = le16_to_cpu(resp->command); @@ -1264,11 +1257,11 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, done: /* Need to indicate IOCTL complete */ - if (wait_queue) { + if (adapter->curr_cmd->wait_q_enabled) { if (ret) - wait_queue->status = MWIFIEX_ERROR_ASSOC_FAIL; + adapter->cmd_wait_q.status = -1; else - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; + adapter->cmd_wait_q.status = 0; } @@ -1283,7 +1276,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, * command to firmware. */ int mwifiex_associate(struct mwifiex_private *priv, - void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) + struct mwifiex_bssdescriptor *bss_desc) { int ret = 0; u8 current_bssid[ETH_ALEN]; @@ -1301,9 +1294,8 @@ int mwifiex_associate(struct mwifiex_private *priv, retrieval */ priv->assoc_rsp_size = 0; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE, - HostCmd_ACT_GEN_SET, 0, wait_queue, - bss_desc); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE, + HostCmd_ACT_GEN_SET, 0, bss_desc); return ret; } @@ -1315,7 +1307,7 @@ int mwifiex_associate(struct mwifiex_private *priv, */ int mwifiex_adhoc_start(struct mwifiex_private *priv, - void *wait_queue, struct mwifiex_802_11_ssid *adhoc_ssid) + struct mwifiex_802_11_ssid *adhoc_ssid) { int ret = 0; @@ -1326,9 +1318,8 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", priv->curr_bss_params.band); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START, - HostCmd_ACT_GEN_SET, 0, wait_queue, - adhoc_ssid); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, + HostCmd_ACT_GEN_SET, 0, adhoc_ssid); return ret; } @@ -1340,7 +1331,7 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, * if already not connected to the requested SSID. */ int mwifiex_adhoc_join(struct mwifiex_private *priv, - void *wait_queue, struct mwifiex_bssdescriptor *bss_desc) + struct mwifiex_bssdescriptor *bss_desc) { int ret = 0; @@ -1369,9 +1360,8 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", priv->curr_bss_params.band); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, - HostCmd_ACT_GEN_SET, 0, wait_queue, - bss_desc); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, + HostCmd_ACT_GEN_SET, 0, bss_desc); return ret; } @@ -1380,9 +1370,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, * This function deauthenticates/disconnects from infra network by sending * deauthentication request. */ -static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u8 *mac) +static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) { u8 mac_address[ETH_ALEN]; int ret = 0; @@ -1400,11 +1388,8 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, bss_descriptor.mac_address, ETH_ALEN); } - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, - HostCmd_ACT_GEN_SET, 0, wait, &mac_address); - - if (!ret && wait) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, + HostCmd_ACT_GEN_SET, 0, &mac_address); return ret; } @@ -1415,26 +1400,23 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, * In case of infra made, it sends deauthentication request, and * in case of ad-hoc mode, a stop network request is sent to the firmware. */ -int mwifiex_deauthenticate(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, u8 *mac) +int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac) { int ret = 0; if (priv->media_connected) { if (priv->bss_mode == NL80211_IFTYPE_STATION) { - ret = mwifiex_deauthenticate_infra(priv, wait, mac); + ret = mwifiex_deauthenticate_infra(priv, mac); } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_AD_HOC_STOP, - HostCmd_ACT_GEN_SET, 0, wait, NULL); - - if (!ret && wait) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_AD_HOC_STOP, + HostCmd_ACT_GEN_SET, 0, NULL); } } return ret; } +EXPORT_SYMBOL_GPL(mwifiex_deauthenticate); /* * This function converts band to radio type used in channel TLV. diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index ed89ca41a902..df665db8c433 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -597,16 +597,23 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct sockaddr *hw_addr = (struct sockaddr *) addr; + int ret = 0; memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); - if (mwifiex_request_set_mac_address(priv)) { - dev_err(priv->adapter->dev, "set MAC address failed\n"); - return -EFAULT; - } + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS, + HostCmd_ACT_GEN_SET, 0, NULL); + + if (!ret) + memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); + else + dev_err(priv->adapter->dev, "set mac address failed: ret=%d" + "\n", ret); + memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); - return 0; + return ret; } /* @@ -615,7 +622,20 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) static void mwifiex_set_multicast_list(struct net_device *dev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - mwifiex_request_set_multicast_list(priv, dev); + struct mwifiex_multicast_list mcast_list; + + if (dev->flags & IFF_PROMISC) { + mcast_list.mode = MWIFIEX_PROMISC_MODE; + } else if (dev->flags & IFF_ALLMULTI || + netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { + mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; + } else { + mcast_list.mode = MWIFIEX_MULTICAST_MODE; + if (netdev_mc_count(dev)) + mcast_list.num_multicast_addr = + mwifiex_copy_mcast_addr(&mcast_list, dev); + } + mwifiex_request_set_multicast_list(priv, &mcast_list); } /* @@ -677,9 +697,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) { dev->netdev_ops = &mwifiex_netdev_ops; /* Initialize private structure */ - init_waitqueue_head(&priv->ioctl_wait_q); - init_waitqueue_head(&priv->cmd_wait_q); - init_waitqueue_head(&priv->w_stats_wait_q); priv->current_key_index = 0; priv->media_connected = false; memset(&priv->nick_name, 0, sizeof(priv->nick_name)); @@ -807,32 +824,6 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) return; } -/* - * Sends IOCTL request to shutdown firmware. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_shutdown_fw(struct mwifiex_private *priv, u8 wait_option) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - - /* Allocate an IOCTL request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_misc_ioctl_init_shutdown(priv->adapter, wait, - MWIFIEX_FUNC_SHUTDOWN); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - kfree(wait); - return status; -} -EXPORT_SYMBOL_GPL(mwifiex_shutdown_fw); - /* * This function check if command is pending. */ @@ -927,6 +918,10 @@ mwifiex_add_card(void *card, struct semaphore *sem, adapter->is_suspended = false; adapter->hs_activated = false; init_waitqueue_head(&adapter->hs_activate_wait_q); + adapter->cmd_wait_q_required = false; + init_waitqueue_head(&adapter->cmd_wait_q.wait); + adapter->cmd_wait_q.condition = false; + adapter->cmd_wait_q.status = 0; /* Create workqueue */ adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); @@ -1038,12 +1033,12 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n"); if (atomic_read(&adapter->rx_pending) || atomic_read(&adapter->tx_pending) || - atomic_read(&adapter->ioctl_pending)) { + atomic_read(&adapter->cmd_pending)) { dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, " - "ioctl_pending=%d\n", + "cmd_pending=%d\n", atomic_read(&adapter->rx_pending), atomic_read(&adapter->tx_pending), - atomic_read(&adapter->ioctl_pending)); + atomic_read(&adapter->cmd_pending)); } /* Remove interface */ diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 43ff149de9db..7ead15e1967e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -42,11 +42,8 @@ extern const char driver_version[]; extern struct mwifiex_adapter *g_adapter; enum { - MWIFIEX_NO_WAIT, - MWIFIEX_IOCTL_WAIT, - MWIFIEX_CMD_WAIT, - MWIFIEX_PROC_WAIT, - MWIFIEX_WSTATS_WAIT + MWIFIEX_ASYNC_CMD, + MWIFIEX_SYNC_CMD }; #define DRV_MODE_STA 0x1 @@ -468,10 +465,6 @@ struct mwifiex_private { u32 curr_bcn_size; /* spin lock for beacon buffer */ spinlock_t curr_bcn_buf_lock; - u16 ioctl_wait_q_woken; - wait_queue_head_t ioctl_wait_q; - u16 cmd_wait_q_woken; - wait_queue_head_t cmd_wait_q; struct wireless_dev *wdev; struct mwifiex_chan_freq_power cfp; char version_str[128]; @@ -480,8 +473,6 @@ struct mwifiex_private { #endif u8 nick_name[16]; struct iw_statistics w_stats; - u16 w_stats_wait_q_woken; - wait_queue_head_t w_stats_wait_q; u16 current_key_index; struct semaphore async_sem; u8 scan_pending_on_block; @@ -552,7 +543,7 @@ struct cmd_ctrl_node { struct sk_buff *cmd_skb; struct sk_buff *resp_skb; void *data_buf; - void *wq_buf; + u32 wait_q_enabled; struct sk_buff *skb; }; @@ -590,7 +581,7 @@ struct mwifiex_adapter { struct mwifiex_if_ops if_ops; atomic_t rx_pending; atomic_t tx_pending; - atomic_t ioctl_pending; + atomic_t cmd_pending; struct workqueue_struct *workqueue; struct work_struct main_work; struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; @@ -684,6 +675,8 @@ struct mwifiex_adapter { struct mwifiex_dbg dbg; u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; u32 arp_filter_size; + u16 cmd_wait_q_required; + struct mwifiex_wait_queue cmd_wait_q; }; int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); @@ -707,29 +700,23 @@ int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); int mwifiex_process_event(struct mwifiex_adapter *adapter); -int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *ioctl_wq, - int status); +int mwifiex_complete_cmd(struct mwifiex_adapter *adapter); -int mwifiex_prepare_cmd(struct mwifiex_private *priv, - uint16_t cmd_no, - u16 cmd_action, - u32 cmd_oid, - void *wait_queue, void *data_buf); +int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf); + +int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, + u16 cmd_action, u32 cmd_oid, void *data_buf); void mwifiex_cmd_timeout_func(unsigned long function_context); -int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue, - u32 func_init_shutdown); int mwifiex_get_debug_info(struct mwifiex_private *, struct mwifiex_debug_info *); int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter); int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); -void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *ioctl_wq); +void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node); @@ -772,24 +759,21 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, void *data_buf, void *cmd_buf); int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, - void *cmd_buf, void *ioctl); + void *cmd_buf); int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, struct sk_buff *skb); int mwifiex_process_sta_event(struct mwifiex_private *); void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); -int mwifiex_scan_networks(struct mwifiex_private *priv, void *wait_queue, - u16 action, - const struct mwifiex_user_scan_cfg - *user_scan_in, struct mwifiex_scan_resp *); +int mwifiex_scan_networks(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in); int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *wait_queue); + struct host_cmd_ds_command *resp); s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *ssid, u8 *bssid, u32 mode); @@ -799,23 +783,20 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, struct mwifiex_ssid_bssid *req_ssid_bssid); s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, struct mwifiex_802_11_ssid *ssid2); -int mwifiex_associate(struct mwifiex_private *priv, void *wait_queue, +int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *wait_queue); + struct host_cmd_ds_command *resp); void mwifiex_reset_connect_state(struct mwifiex_private *priv); void mwifiex_2040_coex_event(struct mwifiex_private *priv); u8 mwifiex_band_to_radio_type(u8 band); -int mwifiex_deauthenticate(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait_queue, - u8 *mac); -int mwifiex_adhoc_start(struct mwifiex_private *priv, void *wait_queue, +int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); +int mwifiex_adhoc_start(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *adhoc_ssid); -int mwifiex_adhoc_join(struct mwifiex_private *priv, void *wait_queue, +int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, @@ -824,8 +805,7 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *wait_queue); + struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); @@ -943,52 +923,34 @@ mwifiex_netdev_get_priv(struct net_device *dev) return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); } -struct mwifiex_wait_queue *mwifiex_alloc_fill_wait_queue( - struct mwifiex_private *, - u8 wait_option); struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index); -int mwifiex_shutdown_fw(struct mwifiex_private *, u8); - +int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, + u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *); int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *); void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version, int maxlen); -int mwifiex_request_set_mac_address(struct mwifiex_private *priv); -void mwifiex_request_set_multicast_list(struct mwifiex_private *priv, - struct net_device *dev); -int mwifiex_request_ioctl(struct mwifiex_private *priv, - struct mwifiex_wait_queue *req, - int, u8 wait_option); -int mwifiex_disconnect(struct mwifiex_private *, u8, u8 *); +int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + struct mwifiex_multicast_list *mcast_list); +int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, + struct net_device *dev); +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); int mwifiex_bss_start(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid); int mwifiex_set_hs_params(struct mwifiex_private *priv, - u16 action, u8 wait_option, + u16 action, int cmd_type, struct mwifiex_ds_hs_cfg *hscfg); -int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option); +int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); -void mwifiex_process_ioctl_resp(struct mwifiex_private *priv, - struct mwifiex_wait_queue *req); -u32 mwifiex_get_mode(struct mwifiex_private *priv, u8 wait_option); int mwifiex_get_signal_info(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_ds_get_signal *signal); int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate); -int mwifiex_get_channel_list(struct mwifiex_private *priv, - u8 wait_option, - struct mwifiex_chan_list *chanlist); -int mwifiex_get_scan_table(struct mwifiex_private *priv, - u8 wait_option, - struct mwifiex_scan_resp *scanresp); -int mwifiex_enable_wep_key(struct mwifiex_private *priv, u8 wait_option); -int mwifiex_find_best_bss(struct mwifiex_private *priv, u8 wait_option, +int mwifiex_find_best_bss(struct mwifiex_private *priv, struct mwifiex_ssid_bssid *ssid_bssid); int mwifiex_request_scan(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_802_11_ssid *req_ssid); int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req); @@ -1024,27 +986,22 @@ int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index); int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index); -int mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on); +int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode); int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, int max_len); -int mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm); +int mwifiex_set_tx_power(struct mwifiex_private *priv, + struct mwifiex_power_cfg *power_cfg); int mwifiex_main_process(struct mwifiex_adapter *); -int mwifiex_bss_ioctl_channel(struct mwifiex_private *, - u16 action, - struct mwifiex_chan_freq_power *cfp); +int mwifiex_bss_set_channel(struct mwifiex_private *, + struct mwifiex_chan_freq_power *cfp); int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *, - struct mwifiex_wait_queue *, struct mwifiex_ssid_bssid *); -int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *, - u16 action, - struct mwifiex_ds_band_cfg *); -int mwifiex_snmp_mib_ioctl(struct mwifiex_private *, - struct mwifiex_wait_queue *, - u32 cmd_oid, u16 action, u32 *value); +int mwifiex_set_radio_band_cfg(struct mwifiex_private *, + struct mwifiex_ds_band_cfg *); int mwifiex_get_bss_info(struct mwifiex_private *, struct mwifiex_bss_info *); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6bb52d0e6cfa..12fe021536d1 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -178,9 +178,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, * with requisite parameters and calls the IOCTL handler. */ int mwifiex_find_best_bss(struct mwifiex_private *priv, - u8 wait_option, struct mwifiex_ssid_bssid *ssid_bssid) + struct mwifiex_ssid_bssid *ssid_bssid) { - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ssid_bssid tmp_ssid_bssid; int ret = 0; u8 *mac = NULL; @@ -188,14 +187,9 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, if (!ssid_bssid) return -1; - /* Allocate wait request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - memcpy(&tmp_ssid_bssid, ssid_bssid, sizeof(struct mwifiex_ssid_bssid)); - ret = mwifiex_bss_ioctl_find_bss(priv, wait, &tmp_ssid_bssid); + ret = mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid); if (!ret) { memcpy(ssid_bssid, &tmp_ssid_bssid, @@ -205,7 +199,6 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, " %pM\n", ssid_bssid->ssid.ssid, mac); } - kfree(wait); return ret; } @@ -221,22 +214,14 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv, int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req) { - struct mwifiex_wait_queue *wait = NULL; int status = 0; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate an IOCTL request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, - scan_req, NULL); + priv->adapter->cmd_wait_q.condition = false; - status = mwifiex_request_ioctl(priv, wait, status, wait_option); + status = mwifiex_scan_networks(priv, scan_req); + if (!status) + status = mwifiex_wait_queue_complete(priv->adapter); - if (wait && (status != -EINPROGRESS)) - kfree(wait); return status; } @@ -674,7 +659,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, * along with the other TLVs, to the firmware. */ static int -mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, +mwifiex_scan_channel_list(struct mwifiex_private *priv, u32 max_chan_per_scan, u8 filtered_scan, struct mwifiex_scan_cmd_config *scan_cfg_out, struct mwifiex_ie_types_chan_list_param_set @@ -808,9 +793,9 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, void *wait_buf, /* Send the scan command to the firmware with the specified cfg */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SCAN, - HostCmd_ACT_GEN_SET, - 0, wait_buf, scan_cfg_out); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN, + HostCmd_ACT_GEN_SET, 0, + scan_cfg_out); if (ret) break; } @@ -2271,9 +2256,7 @@ mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv, * update the internal driver scan table. */ int mwifiex_scan_networks(struct mwifiex_private *priv, - void *wait_buf, u16 action, - const struct mwifiex_user_scan_cfg *user_scan_in, - struct mwifiex_scan_resp *scan_resp) + const struct mwifiex_user_scan_cfg *user_scan_in) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -2288,18 +2271,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, u8 max_chan_per_scan; unsigned long flags; - if (action == HostCmd_ACT_GEN_GET) { - if (scan_resp) { - scan_resp->scan_table = (u8 *) adapter->scan_table; - scan_resp->num_in_scan_table = - adapter->num_in_scan_table; - } else { - ret = -1; - } - return ret; - } - - if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { + if (adapter->scan_processing) { dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); return ret; } @@ -2308,7 +2280,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->scan_processing = true; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { + if (priv->scan_block) { dev_dbg(adapter->dev, "cmd: Scan is blocked during association...\n"); return ret; @@ -2348,9 +2320,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->bcn_buf_end = adapter->bcn_buf; } - ret = mwifiex_scan_channel_list(priv, wait_buf, max_chan_per_scan, - filtered_scan, &scan_cfg_out->config, - chan_list_out, scan_chan_list); + ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, + &scan_cfg_out->config, chan_list_out, + scan_chan_list); /* Get scan command from scan_pending_q and put to cmd_pending_q */ if (!ret) { @@ -2367,7 +2339,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); } - ret = -EINPROGRESS; } else { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->scan_processing = true; @@ -2437,11 +2408,10 @@ int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, * .-------------------------------------------------------------. */ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, void *wq_buf) + struct host_cmd_ds_command *resp) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; - struct mwifiex_wait_queue *wait_queue = NULL; struct cmd_ctrl_node *cmd_node = NULL; struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; struct mwifiex_bssdescriptor *bss_new_entry = NULL; @@ -2653,13 +2623,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, mwifiex_process_scan_results(priv); /* Need to indicate IOCTL complete */ - wait_queue = (struct mwifiex_wait_queue *) wq_buf; - if (wait_queue) { - wait_queue->status = MWIFIEX_ERROR_NO_ERROR; - - /* Indicate ioctl complete */ - mwifiex_ioctl_complete(adapter, - (struct mwifiex_wait_queue *) wait_queue, 0); + if (adapter->curr_cmd->wait_q_enabled) { + adapter->cmd_wait_q.status = 0; + mwifiex_complete_cmd(adapter); } if (priv->report_scan_result) priv->report_scan_result = false; @@ -2853,6 +2819,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; unsigned long flags; + cmd_node->wait_q_enabled = true; spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); list_add_tail(&cmd_node->list, &adapter->scan_pending_q); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -2899,9 +2866,7 @@ int mwifiex_find_best_network(struct mwifiex_private *priv, * firmware, filtered on a specific SSID. */ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, - void *wait_buf, u16 action, - struct mwifiex_802_11_ssid *req_ssid, - struct mwifiex_scan_resp *scan_resp) + struct mwifiex_802_11_ssid *req_ssid) { struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; @@ -2910,24 +2875,12 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, if (!req_ssid) return -1; - if (action == HostCmd_ACT_GEN_GET) { - if (scan_resp) { - scan_resp->scan_table = - (u8 *) &priv->curr_bss_params.bss_descriptor; - scan_resp->num_in_scan_table = - adapter->num_in_scan_table; - } else { - ret = -1; - } - return ret; - } - - if (adapter->scan_processing && action == HostCmd_ACT_GEN_SET) { + if (adapter->scan_processing) { dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); return ret; } - if (priv->scan_block && action == HostCmd_ACT_GEN_SET) { + if (priv->scan_block) { dev_dbg(adapter->dev, "cmd: Scan is blocked during association...\n"); return ret; @@ -2945,7 +2898,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, req_ssid->ssid_len); scan_cfg->keep_previous_scan = true; - ret = mwifiex_scan_networks(priv, wait_buf, action, scan_cfg, NULL); + ret = mwifiex_scan_networks(priv, scan_cfg); kfree(scan_cfg); return ret; @@ -2960,12 +2913,10 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, * Scan command can be issued for both normal scan and specific SSID * scan, depending upon whether an SSID is provided or not. */ -int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, +int mwifiex_request_scan(struct mwifiex_private *priv, struct mwifiex_802_11_ssid *req_ssid) { int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; if (down_interruptible(&priv->async_sem)) { dev_err(priv->adapter->dev, "%s: acquire semaphore\n", @@ -2974,32 +2925,23 @@ int mwifiex_request_scan(struct mwifiex_private *priv, u8 wait_option, } priv->scan_pending_on_block = true; - /* Allocate wait request buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) { - ret = -1; - goto done; - } + priv->adapter->cmd_wait_q.condition = false; if (req_ssid && req_ssid->ssid_len != 0) /* Specific SSID scan */ - status = mwifiex_scan_specific_ssid(priv, wait, - HostCmd_ACT_GEN_SET, - req_ssid, NULL); + ret = mwifiex_scan_specific_ssid(priv, req_ssid); else /* Normal scan */ - status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_SET, - NULL, NULL); - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (status == -1) - ret = -1; -done: - if ((wait) && (status != -EINPROGRESS)) - kfree(wait); + ret = mwifiex_scan_networks(priv, NULL); + + if (!ret) + ret = mwifiex_wait_queue_complete(priv->adapter); + if (ret == -1) { priv->scan_pending_on_block = false; up(&priv->async_sem); } + return ret; } diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index f21e5cd19839..f207756cbb79 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -208,7 +208,7 @@ static int mwifiex_sdio_resume(struct device *dev) /* Disable Host Sleep */ mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - MWIFIEX_NO_WAIT); + MWIFIEX_ASYNC_CMD); return 0; } @@ -1745,13 +1745,12 @@ mwifiex_sdio_cleanup_module(void) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && adapter->priv[i]->media_connected) - mwifiex_disconnect(adapter->priv[i], MWIFIEX_CMD_WAIT, - NULL); + mwifiex_deauthenticate(adapter->priv[i], NULL); if (!adapter->surprise_removed) - mwifiex_shutdown_fw(mwifiex_get_priv - (adapter, MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_CMD_WAIT); + mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY), + MWIFIEX_FUNC_SHUTDOWN); exit: up(&add_remove_card_sem); diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 19de6524d428..dec496369b95 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -1135,65 +1135,66 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (first_sta) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, - HostCmd_ACT_GEN_SET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return -1; /* Read MAC address from HW */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC, + HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; /* Reconfigure tx buf size */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, - HostCmd_ACT_GEN_SET, 0, NULL, - &priv->adapter->tx_buf_size); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_RECONFIGURE_TX_BUFF, + HostCmd_ACT_GEN_SET, 0, + &priv->adapter->tx_buf_size); if (ret) return -1; /* Enable IEEE PS by default */ priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, - EN_AUTO_PS, BITMAP_STA_PS, NULL, - NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_STA_PS, NULL); if (ret) return -1; } /* get tx rate */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG, + HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; priv->data_rate = 0; /* get tx power */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG, + HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; /* set ibss coalescing_status */ - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, - HostCmd_ACT_GEN_SET, 0, NULL, &enable); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, + HostCmd_ACT_GEN_SET, 0, &enable); if (ret) return -1; memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); amsdu_aggr_ctrl.enable = true; /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, - HostCmd_ACT_GEN_SET, 0, NULL, - (void *) &amsdu_aggr_ctrl); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, + HostCmd_ACT_GEN_SET, 0, + (void *) &amsdu_aggr_ctrl); if (ret) return -1; /* MAC Control must be the last command in init_fw */ /* set MAC Control */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, NULL, - &priv->curr_pkt_filter); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter); if (ret) return -1; @@ -1201,19 +1202,18 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) /* Enable auto deep sleep */ auto_ds.auto_ds = DEEP_SLEEP_ON; auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, - EN_AUTO_PS, BITMAP_AUTO_DS, NULL, - &auto_ds); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, + EN_AUTO_PS, BITMAP_AUTO_DS, + &auto_ds); if (ret) return -1; } /* Send cmd to FW to enable/disable 11D function */ state_11d = ENABLE_11D; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, - HostCmd_ACT_GEN_SET, DOT11D_I, - NULL, &state_11d); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d); if (ret) dev_err(priv->adapter->dev, "11D: failed to enable 11D\n"); diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 648df690f5d1..8743c116bee5 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -41,8 +41,7 @@ */ static void mwifiex_process_cmdresp_error(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - struct mwifiex_wait_queue *wq_buf) + struct host_cmd_ds_command *resp) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; struct mwifiex_adapter *adapter = priv->adapter; @@ -51,8 +50,9 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", resp->command, resp->result); - if (wq_buf) - wq_buf->status = MWIFIEX_ERROR_FW_CMDRESP; + + if (adapter->curr_cmd->wait_q_enabled) + adapter->cmd_wait_q.status = -1; switch (le16_to_cpu(resp->command)) { case HostCmd_CMD_802_11_PS_MODE_ENH: @@ -328,9 +328,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, if (priv->is_data_rate_auto) priv->data_rate = 0; else - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + HostCmd_ACT_GEN_GET, 0, NULL); if (data_buf) { ds_rate = (struct mwifiex_rate_cfg *) data_buf; @@ -833,19 +833,17 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, * response handlers based on the command ID. */ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, - u16 cmdresp_no, void *cmd_buf, void *wq_buf) + u16 cmdresp_no, void *cmd_buf) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_command *resp = (struct host_cmd_ds_command *) cmd_buf; - struct mwifiex_wait_queue *wait_queue = - (struct mwifiex_wait_queue *) wq_buf; void *data_buf = adapter->curr_cmd->data_buf; /* If the command is not successful, cleanup and return failure */ if (resp->result != HostCmd_RESULT_OK) { - mwifiex_process_cmdresp_error(priv, resp, wait_queue); + mwifiex_process_cmdresp_error(priv, resp); return -1; } /* Command successful, handle response */ @@ -865,12 +863,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); break; case HostCmd_CMD_802_11_SCAN: - ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); - wait_queue = NULL; - adapter->curr_cmd->wq_buf = NULL; + ret = mwifiex_ret_802_11_scan(priv, resp); + adapter->curr_cmd->wait_q_enabled = false; break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: - ret = mwifiex_ret_802_11_scan(priv, resp, wait_queue); + ret = mwifiex_ret_802_11_scan(priv, resp); dev_dbg(adapter->dev, "info: CMD_RESP: BG_SCAN result is ready!\n"); break; @@ -884,14 +881,14 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, ret = mwifiex_ret_802_11_hs_cfg(priv, resp); break; case HostCmd_CMD_802_11_ASSOCIATE: - ret = mwifiex_ret_802_11_associate(priv, resp, wait_queue); + ret = mwifiex_ret_802_11_associate(priv, resp); break; case HostCmd_CMD_802_11_DEAUTHENTICATE: ret = mwifiex_ret_802_11_deauthenticate(priv, resp); break; case HostCmd_CMD_802_11_AD_HOC_START: case HostCmd_CMD_802_11_AD_HOC_JOIN: - ret = mwifiex_ret_802_11_ad_hoc(priv, resp, wait_queue); + ret = mwifiex_ret_802_11_ad_hoc(priv, resp); break; case HostCmd_CMD_802_11_AD_HOC_STOP: ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp); diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 936d7c175e75..fc265cab0907 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -271,8 +271,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_HS_ACT_REQ: dev_dbg(adapter->dev, "event: HS_ACT_REQ\n"); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_HS_CFG_ENH, - 0, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + 0, 0, NULL); break; case EVENT_MIC_ERR_UNICAST: @@ -303,9 +304,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP); adapter->num_in_scan_table = 0; adapter->bcn_buf_end = adapter->bcn_buf; - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_BG_SCAN_QUERY, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_BG_SCAN_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL); break; case EVENT_PORT_RELEASE: @@ -314,8 +315,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_WMM_STATUS_CHANGE: dev_dbg(adapter->dev, "event: WMM status changed\n"); - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, - 0, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS, + 0, 0, NULL); break; case EVENT_RSSI_LOW: @@ -353,15 +354,15 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_IBSS_COALESCED: dev_dbg(adapter->dev, "event: IBSS_COALESCED\n"); - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, - HostCmd_ACT_GEN_GET, 0, NULL, NULL); + HostCmd_ACT_GEN_GET, 0, NULL); break; case EVENT_ADDBA: dev_dbg(adapter->dev, "event: ADDBA Request\n"); - mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_RSP, - HostCmd_ACT_GEN_SET, 0, NULL, - adapter->event_body); + mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP, + HostCmd_ACT_GEN_SET, 0, + adapter->event_body); break; case EVENT_DELBA: dev_dbg(adapter->dev, "event: DELBA Request\n"); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 2fcdbc224e08..5f2ce9459d26 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -33,9 +33,8 @@ * size, and the calling function must ensure enough memory is * available. */ -static int -mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, - struct net_device *dev) +int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, + struct net_device *dev) { int i = 0; struct netdev_hw_addr *ha; @@ -46,217 +45,52 @@ mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, return i; } -/* - * Allocate and fills a wait queue with proper parameters. - * - * This function needs to be called before an IOCTL request can be made. - * It can handle the following wait options: - * MWIFIEX_NO_WAIT - Waiting is disabled - * MWIFIEX_IOCTL_WAIT - Waiting is done on IOCTL wait queue - * MWIFIEX_CMD_WAIT - Waiting is done on command wait queue - * MWIFIEX_WSTATS_WAIT - Waiting is done on stats wait queue - */ -struct mwifiex_wait_queue * -mwifiex_alloc_fill_wait_queue(struct mwifiex_private *priv, - u8 wait_option) -{ - struct mwifiex_wait_queue *wait = NULL; - - wait = (struct mwifiex_wait_queue *) - kzalloc(sizeof(struct mwifiex_wait_queue), GFP_ATOMIC); - if (!wait) { - dev_err(priv->adapter->dev, "%s: fail to alloc buffer\n", - __func__); - return wait; - } - - wait->bss_index = priv->bss_index; - - switch (wait_option) { - case MWIFIEX_NO_WAIT: - wait->enabled = 0; - break; - case MWIFIEX_IOCTL_WAIT: - priv->ioctl_wait_q_woken = false; - wait->start_time = jiffies; - wait->wait = &priv->ioctl_wait_q; - wait->condition = &priv->ioctl_wait_q_woken; - wait->enabled = 1; - break; - case MWIFIEX_CMD_WAIT: - priv->cmd_wait_q_woken = false; - wait->start_time = jiffies; - wait->wait = &priv->cmd_wait_q; - wait->condition = &priv->cmd_wait_q_woken; - wait->enabled = 1; - break; - case MWIFIEX_WSTATS_WAIT: - priv->w_stats_wait_q_woken = false; - wait->start_time = jiffies; - wait->wait = &priv->w_stats_wait_q; - wait->condition = &priv->w_stats_wait_q_woken; - wait->enabled = 1; - break; - } - - return wait; -} - /* * Wait queue completion handler. * - * This function waits on a particular wait queue. - * For NO_WAIT option, it returns immediately. It also cancels the - * pending IOCTL request after waking up, in case of errors. + * This function waits on a cmd wait queue. It also cancels the pending + * request after waking up, in case of errors. */ -static void -mwifiex_wait_ioctl_complete(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u8 wait_option) +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) { bool cancel_flag = false; + int status = adapter->cmd_wait_q.status; - switch (wait_option) { - case MWIFIEX_NO_WAIT: - break; - case MWIFIEX_IOCTL_WAIT: - wait_event_interruptible(priv->ioctl_wait_q, - priv->ioctl_wait_q_woken); - if (!priv->ioctl_wait_q_woken) - cancel_flag = true; - break; - case MWIFIEX_CMD_WAIT: - wait_event_interruptible(priv->cmd_wait_q, - priv->cmd_wait_q_woken); - if (!priv->cmd_wait_q_woken) - cancel_flag = true; - break; - case MWIFIEX_WSTATS_WAIT: - wait_event_interruptible(priv->w_stats_wait_q, - priv->w_stats_wait_q_woken); - if (!priv->w_stats_wait_q_woken) - cancel_flag = true; - break; - } - if (cancel_flag) { - mwifiex_cancel_pending_ioctl(priv->adapter, wait); - dev_dbg(priv->adapter->dev, "cmd: IOCTL cancel: wait=%p, wait_option=%d\n", - wait, wait_option); - } + dev_dbg(adapter->dev, "cmd pending\n"); + atomic_inc(&adapter->cmd_pending); - return; -} + /* Status pending, wake up main process */ + queue_work(adapter->workqueue, &adapter->main_work); -/* - * The function waits for the request to complete and issues the - * completion handler, if required. - */ -int mwifiex_request_ioctl(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - int status, u8 wait_option) -{ - switch (status) { - case -EINPROGRESS: - dev_dbg(priv->adapter->dev, "cmd: IOCTL pending: wait=%p, wait_option=%d\n", - wait, wait_option); - atomic_inc(&priv->adapter->ioctl_pending); - /* Status pending, wake up main process */ - queue_work(priv->adapter->workqueue, &priv->adapter->main_work); - - /* Wait for completion */ - if (wait_option) { - mwifiex_wait_ioctl_complete(priv, wait, wait_option); - status = wait->status; - } - break; - case 0: - case -1: - case -EBUSY: - default: - break; - } - return status; -} -EXPORT_SYMBOL_GPL(mwifiex_request_ioctl); + /* Wait for completion */ + wait_event_interruptible(adapter->cmd_wait_q.wait, + adapter->cmd_wait_q.condition); + if (!adapter->cmd_wait_q.condition) + cancel_flag = true; -/* - * IOCTL request handler to set/get MAC address. - * - * This function prepares the correct firmware command and - * issues it to get the extended version information. - */ -static int mwifiex_bss_ioctl_mac_address(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u8 action, u8 *mac) -{ - int ret = 0; - - if ((action == HostCmd_ACT_GEN_GET) && mac) { - memcpy(mac, priv->curr_addr, ETH_ALEN); - return 0; + if (cancel_flag) { + mwifiex_cancel_pending_ioctl(adapter); + dev_dbg(adapter->dev, "cmd cancel\n"); } + adapter->cmd_wait_q.status = 0; - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS, - action, 0, wait, mac); - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * Sends IOCTL request to set MAC address. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_request_set_mac_address(struct mwifiex_private *priv) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - u8 wait_option = MWIFIEX_CMD_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_bss_ioctl_mac_address(priv, wait, HostCmd_ACT_GEN_SET, - NULL); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (!status) - memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); - else - dev_err(priv->adapter->dev, "set mac address failed: status=%d" - " error_code=%#x\n", status, wait->status); - - kfree(wait); return status; } /* - * IOCTL request handler to set multicast list. - * * This function prepares the correct firmware command and * issues it to set the multicast list. * * This function can be used to enable promiscuous mode, or enable all * multicast packets, or to enable selective multicast. */ -static int -mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u16 action, - struct mwifiex_multicast_list *mcast_list) +int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, + struct mwifiex_multicast_list *mcast_list) { int ret = 0; u16 old_pkt_filter; old_pkt_filter = priv->curr_pkt_filter; - if (action == HostCmd_ACT_GEN_GET) - return -1; if (mcast_list->mode == MWIFIEX_PROMISC_MODE) { dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n"); @@ -281,16 +115,15 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, /* Set multicast addresses to firmware */ if (old_pkt_filter == priv->curr_pkt_filter) { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_MULTICAST_ADR, - action, 0, wait, mcast_list); - if (!ret) - ret = -EINPROGRESS; + HostCmd_ACT_GEN_SET, 0, + mcast_list); } else { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_MULTICAST_ADR, - action, 0, NULL, + HostCmd_ACT_GEN_SET, 0, mcast_list); } } @@ -300,101 +133,21 @@ mwifiex_bss_ioctl_multicast_list(struct mwifiex_private *priv, "info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n", old_pkt_filter, priv->curr_pkt_filter); if (old_pkt_filter != priv->curr_pkt_filter) { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, action, - 0, wait, &priv->curr_pkt_filter); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, + 0, &priv->curr_pkt_filter); } return ret; } /* - * Sends IOCTL request to set multicast list. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -void -mwifiex_request_set_multicast_list(struct mwifiex_private *priv, - struct net_device *dev) -{ - struct mwifiex_wait_queue *wait = NULL; - struct mwifiex_multicast_list mcast_list; - u8 wait_option = MWIFIEX_NO_WAIT; - int status = 0; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return; - - if (dev->flags & IFF_PROMISC) { - mcast_list.mode = MWIFIEX_PROMISC_MODE; - } else if (dev->flags & IFF_ALLMULTI || - netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) { - mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; - } else { - mcast_list.mode = MWIFIEX_MULTICAST_MODE; - if (netdev_mc_count(dev)) - mcast_list.num_multicast_addr = - mwifiex_copy_mcast_addr(&mcast_list, dev); - } - status = mwifiex_bss_ioctl_multicast_list(priv, wait, - HostCmd_ACT_GEN_SET, - &mcast_list); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (wait && status != -EINPROGRESS) - kfree(wait); - - return; -} - -/* - * IOCTL request handler to disconnect from a BSS/IBSS. - */ -static int mwifiex_bss_ioctl_stop(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, u8 *mac) -{ - return mwifiex_deauthenticate(priv, wait, mac); -} - -/* - * Sends IOCTL request to disconnect from a BSS. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_disconnect(struct mwifiex_private *priv, u8 wait_option, u8 *mac) -{ - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_bss_ioctl_stop(priv, wait, mac); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - kfree(wait); - return status; -} -EXPORT_SYMBOL_GPL(mwifiex_disconnect); - -/* - * IOCTL request handler to join a BSS/IBSS. - * * In Ad-Hoc mode, the IBSS is created if not found in scan list. * In both Ad-Hoc and infra mode, an deauthentication is performed * first. */ -static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ssid_bssid *ssid_bssid) +int mwifiex_bss_start(struct mwifiex_private *priv, + struct mwifiex_ssid_bssid *ssid_bssid) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -406,7 +159,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, if (priv->bss_mode == NL80211_IFTYPE_STATION) { /* Infra mode */ - ret = mwifiex_deauthenticate(priv, NULL, NULL); + ret = mwifiex_deauthenticate(priv, NULL); if (ret) return ret; @@ -427,7 +180,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, /* Clear any past association response stored for * application retrieval */ priv->assoc_rsp_size = 0; - ret = mwifiex_associate(priv, wait, &adapter->scan_table[i]); + ret = mwifiex_associate(priv, &adapter->scan_table[i]); if (ret) return ret; } else { @@ -441,7 +194,7 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, /* Exit Adhoc mode first */ dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n"); - ret = mwifiex_deauthenticate(priv, NULL, NULL); + ret = mwifiex_deauthenticate(priv, NULL); if (ret) return ret; @@ -460,75 +213,39 @@ static int mwifiex_bss_ioctl_start(struct mwifiex_private *priv, if (i >= 0) { dev_dbg(adapter->dev, "info: network found in scan" " list. Joining...\n"); - ret = mwifiex_adhoc_join(priv, wait, - &adapter->scan_table[i]); + ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]); if (ret) return ret; } else { /* i >= 0 */ dev_dbg(adapter->dev, "info: Network not found in " "the list, creating adhoc with ssid = %s\n", ssid_bssid->ssid.ssid); - ret = mwifiex_adhoc_start(priv, wait, - &ssid_bssid->ssid); + ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid); if (ret) return ret; } } - if (!ret) - ret = -EINPROGRESS; - return ret; } -/* - * Sends IOCTL request to connect with a BSS. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_bss_start(struct mwifiex_private *priv, u8 wait_option, - struct mwifiex_ssid_bssid *ssid_bssid) -{ - struct mwifiex_wait_queue *wait = NULL; - struct mwifiex_ssid_bssid tmp_ssid_bssid; - int status = 0; - - /* Stop the O.S. TX queue if needed */ - if (!netif_queue_stopped(priv->netdev)) - netif_stop_queue(priv->netdev); - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - if (ssid_bssid) - memcpy(&tmp_ssid_bssid, ssid_bssid, - sizeof(struct mwifiex_ssid_bssid)); - status = mwifiex_bss_ioctl_start(priv, wait, &tmp_ssid_bssid); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - - kfree(wait); - return status; -} - /* * IOCTL request handler to set host sleep configuration. * * This function prepares the correct firmware command and * issues it. */ -static int -mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u16 action, struct mwifiex_ds_hs_cfg *hs_cfg) +int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, + int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) + { struct mwifiex_adapter *adapter = priv->adapter; int status = 0; u32 prev_cond = 0; + if (!hs_cfg) + return -ENOMEM; + switch (action) { case HostCmd_ACT_GEN_SET: if (adapter->pps_uapsd_mode) { @@ -561,12 +278,16 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, status = -1; break; } - status = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_HS_CFG_ENH, - HostCmd_ACT_GEN_SET, - 0, wait, &adapter->hs_cfg); - if (!status) - status = -EINPROGRESS; + if (cmd_type == MWIFIEX_SYNC_CMD) + status = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + HostCmd_ACT_GEN_SET, 0, + &adapter->hs_cfg); + else + status = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_HS_CFG_ENH, + HostCmd_ACT_GEN_SET, 0, + &adapter->hs_cfg); if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) /* Restore previous condition */ adapter->hs_cfg.conditions = @@ -591,43 +312,13 @@ mwifiex_pm_ioctl_hs_cfg(struct mwifiex_private *priv, return status; } -/* - * Sends IOCTL request to set Host Sleep parameters. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, - u8 wait_option, - struct mwifiex_ds_hs_cfg *hscfg) -{ - int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - - if (!hscfg) - return -ENOMEM; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - ret = mwifiex_pm_ioctl_hs_cfg(priv, wait, action, hscfg); - - ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); - - if (wait && (ret != -EINPROGRESS)) - kfree(wait); - return ret; -} - /* * Sends IOCTL request to cancel the existing Host Sleep configuration. * * This function allocates the IOCTL request buffer, fills it * with requisite parameters and calls the IOCTL handler. */ -int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) +int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type) { int ret = 0; struct mwifiex_ds_hs_cfg hscfg; @@ -636,7 +327,7 @@ int mwifiex_cancel_hs(struct mwifiex_private *priv, u8 wait_option) hscfg.conditions = HOST_SLEEP_CFG_CANCEL; hscfg.is_invoke_hostcmd = true; ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, - wait_option, &hscfg); + cmd_type, &hscfg); return ret; } @@ -665,8 +356,8 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - HostCmd_ACT_GEN_SET, - MWIFIEX_IOCTL_WAIT, &hscfg)) { + HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, + &hscfg)) { dev_err(adapter->dev, "IOCTL request HS enable failed\n"); return false; } @@ -678,69 +369,6 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } EXPORT_SYMBOL_GPL(mwifiex_enable_hs); -/* - * IOCTL request handler to get signal information. - * - * This function prepares the correct firmware command and - * issues it to get the signal (RSSI) information. - * - * This only works in the connected mode. - */ -static int mwifiex_get_info_signal(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ds_get_signal *signal) -{ - int ret = 0; - - if (!wait) { - dev_err(priv->adapter->dev, "WAIT information is not present\n"); - return -1; - } - - /* Signal info can be obtained only if connected */ - if (!priv->media_connected) { - dev_dbg(priv->adapter->dev, - "info: Can not get signal in disconnected state\n"); - return -1; - } - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_RSSI_INFO, - HostCmd_ACT_GEN_GET, 0, wait, signal); - - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * IOCTL request handler to get statistics. - * - * This function prepares the correct firmware command and - * issues it to get the statistics (RSSI) information. - */ -static int mwifiex_get_info_stats(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ds_get_stats *log) -{ - int ret = 0; - - if (!wait) { - dev_err(priv->adapter->dev, "MWIFIEX IOCTL information is not present\n"); - return -1; - } - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_GET_LOG, - HostCmd_ACT_GEN_GET, 0, wait, log); - - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - /* * IOCTL request handler to get BSS information. * @@ -813,90 +441,20 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, } /* - * IOCTL request handler to get extended version information. - * - * This function prepares the correct firmware command and - * issues it to get the extended version information. - */ -static int mwifiex_get_info_ver_ext(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ver_ext *ver_ext) -{ - int ret = 0; - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_VERSION_EXT, - HostCmd_ACT_GEN_GET, 0, wait, ver_ext); - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * IOCTL request handler to set/get SNMP MIB parameters. - * - * This function prepares the correct firmware command and - * issues it. + * The function sets band configurations. * - * Currently the following parameters are supported - - * Set/get RTS Threshold - * Set/get fragmentation threshold - * Set/get retry count - */ -int mwifiex_snmp_mib_ioctl(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u32 cmd_oid, u16 action, u32 *value) -{ - int ret = 0; - - if (!value) - return -1; - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, - action, cmd_oid, wait, value); - - if (!ret) - ret = -EINPROGRESS; - - return ret; -} - -/* - * IOCTL request handler to set/get band configurations. - * - * For SET operation, it performs extra checks to make sure the Ad-Hoc + * it performs extra checks to make sure the Ad-Hoc * band and channel are compatible. Otherwise it returns an error. * - * For GET operation, this function retrieves the following information - - * - Infra bands - * - Ad-hoc band - * - Ad-hoc channel - * - Secondary channel offset */ -int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, - u16 action, - struct mwifiex_ds_band_cfg *radio_cfg) +int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv, + struct mwifiex_ds_band_cfg *radio_cfg) { struct mwifiex_adapter *adapter = priv->adapter; u8 infra_band = 0; u8 adhoc_band = 0; u32 adhoc_channel = 0; - if (action == HostCmd_ACT_GEN_GET) { - /* Infra Bands */ - radio_cfg->config_bands = adapter->config_bands; - /* Adhoc Band */ - radio_cfg->adhoc_start_band = adapter->adhoc_start_band; - /* Adhoc channel */ - radio_cfg->adhoc_channel = priv->adhoc_channel; - /* Secondary channel offset */ - radio_cfg->sec_chan_offset = adapter->chan_offset; - return 0; - } - - /* For action = SET */ infra_band = (u8) radio_cfg->config_bands; adhoc_band = (u8) radio_cfg->adhoc_start_band; adhoc_channel = radio_cfg->adhoc_channel; @@ -950,8 +508,8 @@ int mwifiex_radio_ioctl_band_cfg(struct mwifiex_private *priv, * This function performs validity checking on channel/frequency * compatibility and returns failure if not valid. */ -int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, - struct mwifiex_chan_freq_power *chan) +int mwifiex_bss_set_channel(struct mwifiex_private *priv, + struct mwifiex_chan_freq_power *chan) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_chan_freq_power *cfp = NULL; @@ -959,16 +517,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, if (!chan) return -1; - if (action == HostCmd_ACT_GEN_GET) { - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - priv->curr_bss_params.band, - (u16) priv->curr_bss_params.bss_descriptor. - channel); - chan->channel = cfp->channel; - chan->freq = cfp->freq; - - return 0; - } if (!chan->channel && !chan->freq) return -1; if (adapter->adhoc_start_band & BAND_AN) @@ -1024,7 +572,6 @@ int mwifiex_bss_ioctl_channel(struct mwifiex_private *priv, u16 action, * issues it to set or get the ad-hoc channel. */ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, u16 action, u16 *channel) { int ret = 0; @@ -1039,10 +586,8 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_RF_CHANNEL, - action, 0, wait, channel); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, + action, 0, channel); return ret; } @@ -1054,7 +599,6 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, * these are provided, just the best BSS (best RSSI) is returned. */ int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_ssid_bssid *ssid_bssid) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1114,10 +658,7 @@ int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) { int ret = 0; - int status = 0; struct mwifiex_bss_info bss_info; - struct mwifiex_wait_queue *wait = NULL; - u8 wait_option = MWIFIEX_IOCTL_WAIT; struct mwifiex_ssid_bssid ssid_bssid; u16 curr_chan = 0; @@ -1127,19 +668,10 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) if (mwifiex_get_bss_info(priv, &bss_info)) return -1; - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - /* Get current channel */ - status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_GET, - &curr_chan); + ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET, + &curr_chan); - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { - ret = -1; - goto done; - } if (curr_chan == channel) { ret = 0; goto done; @@ -1154,23 +686,13 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) /* Do disonnect */ memset(&ssid_bssid, 0, ETH_ALEN); - status = mwifiex_bss_ioctl_stop(priv, wait, ssid_bssid.bssid); + ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { - ret = -1; - goto done; - } - - status = mwifiex_bss_ioctl_ibss_channel(priv, wait, HostCmd_ACT_GEN_SET, - (u16 *) &channel); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) { - ret = -1; - goto done; - } + ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, + (u16 *) &channel); /* Do specific SSID scanning */ - if (mwifiex_request_scan(priv, wait_option, &bss_info.ssid)) { + if (mwifiex_request_scan(priv, &bss_info.ssid)) { ret = -1; goto done; } @@ -1179,13 +701,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) memcpy(&ssid_bssid.ssid, &bss_info.ssid, sizeof(struct mwifiex_802_11_ssid)); - status = mwifiex_bss_ioctl_start(priv, wait, &ssid_bssid); - - if (mwifiex_request_ioctl(priv, wait, status, wait_option)) - ret = -1; - + ret = mwifiex_bss_start(priv, &ssid_bssid); done: - kfree(wait); return ret; } @@ -1198,7 +715,6 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) * for the band. */ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_rate_cfg *rate_cfg) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1242,11 +758,9 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, } } else { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_TX_RATE_QUERY, - HostCmd_ACT_GEN_GET, 0, wait, NULL); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_TX_RATE_QUERY, + HostCmd_ACT_GEN_GET, 0, NULL); } return ret; @@ -1261,7 +775,6 @@ static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, * The function also performs validation checking on the supplied value. */ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_rate_cfg *rate_cfg) { u8 rates[MWIFIEX_SUPPORTED_RATES]; @@ -1316,10 +829,8 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TX_RATE_CFG, - HostCmd_ACT_GEN_SET, 0, wait, bitmap_rates); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, + HostCmd_ACT_GEN_SET, 0, bitmap_rates); return ret; } @@ -1331,7 +842,6 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, * rate index. */ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_rate_cfg *rate_cfg) { int status = 0; @@ -1340,11 +850,9 @@ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, return -1; if (rate_cfg->action == HostCmd_ACT_GEN_GET) - status = mwifiex_rate_ioctl_get_rate_value( - priv, wait, rate_cfg); + status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg); else - status = mwifiex_rate_ioctl_set_rate_value( - priv, wait, rate_cfg); + status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg); return status; } @@ -1359,19 +867,11 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate) { int ret = 0; - struct mwifiex_wait_queue *wait = NULL; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); rate->action = HostCmd_ACT_GEN_GET; - ret = mwifiex_rate_ioctl_cfg(priv, wait, rate); + ret = mwifiex_rate_ioctl_cfg(priv, rate); - ret = mwifiex_request_ioctl(priv, wait, ret, wait_option); if (!ret) { if (rate && rate->is_rate_auto) rate->rate = mwifiex_index_to_data_rate(priv->adapter, @@ -1382,7 +882,6 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, ret = -1; } - kfree(wait); return ret; } @@ -1398,9 +897,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, * - Modulation class HTBW20 * - Modulation class HTBW40 */ -static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_power_cfg *power_cfg) +int mwifiex_set_tx_power(struct mwifiex_private *priv, + struct mwifiex_power_cfg *power_cfg) { int ret = 0; struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; @@ -1473,12 +971,10 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, pg->ht_bandwidth = HT_BW_40; } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_TXPWR_CFG, - HostCmd_ACT_GEN_SET, 0, wait, buf); - if (!ret) - ret = -EINPROGRESS; - kfree(buf); + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG, + HostCmd_ACT_GEN_SET, 0, buf); + kfree(buf); return ret; } @@ -1488,33 +984,23 @@ static int mwifiex_power_ioctl_set_power(struct mwifiex_private *priv, * This function prepares the correct firmware command and * issues it. */ -static int mwifiex_pm_ioctl_ps_mode(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - u32 *ps_mode, u16 action) +int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; u16 sub_cmd; - if (action == HostCmd_ACT_GEN_SET) { - if (*ps_mode) - adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; - else - adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; - sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, - sub_cmd, BITMAP_STA_PS, wait, NULL); - if ((!ret) && (sub_cmd == DIS_AUTO_PS)) - ret = mwifiex_prepare_cmd(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, - 0, NULL, NULL); - } else { - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, - GET_PS, 0, wait, NULL); - } - - if (!ret) - ret = -EINPROGRESS; + if (*ps_mode) + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; + else + adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; + sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH, + sub_cmd, BITMAP_STA_PS, NULL); + if ((!ret) && (sub_cmd == DIS_AUTO_PS)) + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, + 0, NULL); return ret; } @@ -1600,18 +1086,14 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, * This function prepares the correct firmware command and * issues it. */ -static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, +static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { int ret = 0; - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - wait, encrypt_key); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); return ret; } @@ -1622,12 +1104,10 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_adapter *adapter, * This function prepares the correct firmware command and * issues it, after validation checks. */ -static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, +static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { int ret = 0; - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; struct mwifiex_wep_key *wep_key = NULL; int index; @@ -1641,7 +1121,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, /* Copy the required key as the current key */ wep_key = &priv->wep_key[index]; if (!wep_key->key_length) { - dev_err(adapter->dev, + dev_err(priv->adapter->dev, "key not set, so cannot enable it\n"); return -1; } @@ -1661,8 +1141,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, } if (wep_key->key_length) { /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, 0, NULL, NULL); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return ret; } @@ -1672,11 +1153,9 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, wait, - &priv->curr_pkt_filter); - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter); return ret; } @@ -1691,18 +1170,16 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_adapter *adapter, * * This function can also be used to disable a currently set key. */ -static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, +static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, struct mwifiex_ds_encrypt_key *encrypt_key) { int ret = 0; - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; u8 remove_key = false; struct host_cmd_ds_802_11_key_material *ibss_key; /* Current driver only supports key length of up to 32 bytes */ if (encrypt_key->key_len > MWIFIEX_MAX_KEY_LENGTH) { - dev_err(adapter->dev, "key length too long\n"); + dev_err(priv->adapter->dev, "key length too long\n"); return -1; } @@ -1713,9 +1190,10 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, */ /* Send the key as PTK to firmware */ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - NULL, encrypt_key); + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); if (ret) return ret; @@ -1740,18 +1218,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, if (remove_key) /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, - !(KEY_INFO_ENABLED), - wait, encrypt_key); + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), + encrypt_key); else /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - wait, encrypt_key); - - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); return ret; } @@ -1764,21 +1240,16 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_adapter *adapter, */ static int mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_ds_encrypt_key *encrypt_key) { int status = 0; - struct mwifiex_adapter *adapter = priv->adapter; if (encrypt_key->is_wapi_key) - status = mwifiex_sec_ioctl_set_wapi_key(adapter, wait, - encrypt_key); + status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key); else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104) - status = mwifiex_sec_ioctl_set_wpa_key(adapter, wait, - encrypt_key); + status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key); else - status = mwifiex_sec_ioctl_set_wep_key(adapter, wait, - encrypt_key); + status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key); return status; } @@ -1805,95 +1276,32 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, return 0; } -/* - * Sends IOCTL request to set Tx power. It can be set to either auto - * or a fixed value. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int -mwifiex_set_tx_power(struct mwifiex_private *priv, int type, int dbm) -{ - struct mwifiex_power_cfg power_cfg; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; - int ret = 0; - - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - - if (type == NL80211_TX_POWER_FIXED) { - power_cfg.is_power_auto = 0; - power_cfg.power_level = dbm; - } else { - power_cfg.is_power_auto = 1; - } - status = mwifiex_power_ioctl_set_power(priv, wait, &power_cfg); - - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - - kfree(wait); - return ret; -} - -/* - * Sends IOCTL request to get scan table. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int mwifiex_get_scan_table(struct mwifiex_private *priv, u8 wait_option, - struct mwifiex_scan_resp *scan_resp) -{ - struct mwifiex_wait_queue *wait = NULL; - struct mwifiex_scan_resp scan; - int status = 0; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - - status = mwifiex_scan_networks(priv, wait, HostCmd_ACT_GEN_GET, - NULL, &scan); - - status = mwifiex_request_ioctl(priv, wait, status, wait_option); - if (!status) { - if (scan_resp) - memcpy(scan_resp, &scan, - sizeof(struct mwifiex_scan_resp)); - } - - if (wait && (status != -EINPROGRESS)) - kfree(wait); - return status; -} - /* * Sends IOCTL request to get signal information. * * This function allocates the IOCTL request buffer, fills it * with requisite parameters and calls the IOCTL handler. */ -int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, +int mwifiex_get_signal_info(struct mwifiex_private *priv, struct mwifiex_ds_get_signal *signal) { struct mwifiex_ds_get_signal info; - struct mwifiex_wait_queue *wait = NULL; int status = 0; - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; - + memset(&info, 0, sizeof(struct mwifiex_ds_get_signal)); info.selector = ALL_RSSI_INFO_MASK; - status = mwifiex_get_info_signal(priv, wait, &info); + /* Signal info can be obtained only if connected */ + if (!priv->media_connected) { + dev_dbg(priv->adapter->dev, + "info: Can not get signal in disconnected state\n"); + return -1; + } + + /* Send request to firmware */ + status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO, + HostCmd_ACT_GEN_GET, 0, signal); - status = mwifiex_request_ioctl(priv, wait, status, wait_option); if (!status) { if (signal) memcpy(signal, &info, @@ -1904,8 +1312,6 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, priv->w_stats.qual.noise = info.bcn_nf_avg; } - if (wait && (status != -EINPROGRESS)) - kfree(wait); return status; } @@ -1918,15 +1324,9 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, u8 wait_option, int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int key_len, u8 key_index, int disable) { - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_encrypt_key encrypt_key; - int status = 0; int ret = 0; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key)); encrypt_key.key_len = key_len; if (!disable) { @@ -1937,40 +1337,8 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, encrypt_key.key_disable = true; } - status = mwifiex_sec_ioctl_encrypt_key(priv, wait, &encrypt_key); - - if (mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT)) - ret = -EFAULT; - - kfree(wait); - return ret; -} - -/* - * Sends IOCTL request to set power management parameters. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - */ -int -mwifiex_drv_set_power(struct mwifiex_private *priv, bool power_on) -{ - int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; - u32 ps_mode; - - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - - ps_mode = power_on; - status = mwifiex_pm_ioctl_ps_mode(priv, wait, &ps_mode, - HostCmd_ACT_GEN_SET); + ret = mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - - kfree(wait); return ret; } @@ -1984,26 +1352,17 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv) { struct mwifiex_ver_ext ver_ext; - struct mwifiex_wait_queue *wait = NULL; - int status = 0; int ret = 0; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; /* get fw version */ memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); - status = mwifiex_get_info_ver_ext(priv, wait, &ver_ext); - - ret = mwifiex_request_ioctl(priv, wait, status, wait_option); + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, + HostCmd_ACT_GEN_GET, 0, &ver_ext); if (ret) ret = -1; - kfree(wait); return ret; } @@ -2018,21 +1377,13 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *log) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_get_stats get_log; - u8 wait_option = MWIFIEX_IOCTL_WAIT; - - /* Allocate wait buffer */ - wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); - if (!wait) - return -ENOMEM; memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats)); - status = mwifiex_get_info_stats(priv, wait, &get_log); + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, + HostCmd_ACT_GEN_GET, 0, &get_log); - /* Send IOCTL request to MWIFIEX */ - ret = mwifiex_request_ioctl(priv, wait, status, wait_option); if (!ret) { if (log) memcpy(log, &get_log, sizeof(struct @@ -2042,7 +1393,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, priv->w_stats.discard.misc = get_log.ack_failure; } - kfree(wait); return ret; } @@ -2060,7 +1410,6 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, * - CAU */ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, struct mwifiex_ds_reg_rw *reg_rw, u16 action) { @@ -2088,10 +1437,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, } /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, cmd_no, action, 0, wait, reg_rw); - - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw); return ret; } @@ -2107,23 +1453,13 @@ mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, u32 reg_offset, u32 reg_value) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_reg_rw reg_rw; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - reg_rw.type = cpu_to_le32(reg_type); reg_rw.offset = cpu_to_le32(reg_offset); reg_rw.value = cpu_to_le32(reg_value); - status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, - HostCmd_ACT_GEN_SET); + ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - - kfree(wait); return ret; } @@ -2138,50 +1474,18 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, u32 reg_offset, u32 *value) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_reg_rw reg_rw; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - reg_rw.type = cpu_to_le32(reg_type); reg_rw.offset = cpu_to_le32(reg_offset); - status = mwifiex_reg_mem_ioctl_reg_rw(priv, wait, ®_rw, - HostCmd_ACT_GEN_GET); + ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); if (ret) goto done; *value = le32_to_cpu(reg_rw.value); done: - kfree(wait); - return ret; -} - -/* - * IOCTL request handler to read EEPROM. - * - * This function prepares the correct firmware command and - * issues it. - */ -static int -mwifiex_reg_mem_ioctl_read_eeprom(struct mwifiex_private *priv, - struct mwifiex_wait_queue *wait, - struct mwifiex_ds_read_eeprom *rd_eeprom) -{ - int ret = 0; - - /* Send request to firmware */ - ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, - HostCmd_ACT_GEN_GET, 0, wait, rd_eeprom); - - if (!ret) - ret = -EINPROGRESS; - return ret; } @@ -2196,25 +1500,17 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, u8 *value) { int ret = 0; - int status = 0; - struct mwifiex_wait_queue *wait = NULL; struct mwifiex_ds_read_eeprom rd_eeprom; - wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); - if (!wait) - return -ENOMEM; - rd_eeprom.offset = cpu_to_le16((u16) offset); rd_eeprom.byte_count = cpu_to_le16((u16) bytes); - status = mwifiex_reg_mem_ioctl_read_eeprom(priv, wait, &rd_eeprom); - ret = mwifiex_request_ioctl(priv, wait, status, MWIFIEX_IOCTL_WAIT); - if (ret) - goto done; + /* Send request to firmware */ + ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, + HostCmd_ACT_GEN_GET, 0, &rd_eeprom); - memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); -done: - kfree(wait); + if (!ret) + memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); return ret; } diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index e8db6bd021c6..b261d812c4d3 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -51,7 +51,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, if (!skb->len) { dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); - tx_info->status_code = MWIFIEX_ERROR_PKT_SIZE_INVALID; + tx_info->status_code = -1; return skb->data; } diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 205022aa52f5..9f65587622fd 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -55,17 +55,12 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) } /* - * IOCTL request handler to send function init/shutdown command + * This function sends init/shutdown command * to firmware. - * - * This function prepares the correct firmware command and - * issues it. */ -int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait, - u32 func_init_shutdown) +int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, + u32 func_init_shutdown) { - struct mwifiex_private *priv = adapter->priv[wait->bss_index]; int ret; u16 cmd; @@ -74,19 +69,16 @@ int mwifiex_misc_ioctl_init_shutdown(struct mwifiex_adapter *adapter, } else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) { cmd = HostCmd_CMD_FUNC_SHUTDOWN; } else { - dev_err(adapter->dev, "unsupported parameter\n"); + dev_err(priv->adapter->dev, "unsupported parameter\n"); return -1; } /* Send command to firmware */ - ret = mwifiex_prepare_cmd(priv, cmd, HostCmd_ACT_GEN_SET, - 0, wait, NULL); - - if (!ret) - ret = -EINPROGRESS; + ret = mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL); return ret; } +EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw); /* * IOCTL request handler to set/get debug information. @@ -222,31 +214,18 @@ int mwifiex_recv_complete(struct mwifiex_adapter *adapter, * corresponding waiting function. Otherwise, it processes the * IOCTL response and frees the response buffer. */ -int mwifiex_ioctl_complete(struct mwifiex_adapter *adapter, - struct mwifiex_wait_queue *wait_queue, - int status) +int mwifiex_complete_cmd(struct mwifiex_adapter *adapter) { - enum mwifiex_error_code status_code = - (enum mwifiex_error_code) wait_queue->status; - - atomic_dec(&adapter->ioctl_pending); + atomic_dec(&adapter->cmd_pending); + dev_dbg(adapter->dev, "cmd completed: status=%d\n", + adapter->cmd_wait_q.status); - dev_dbg(adapter->dev, "cmd: IOCTL completed: status=%d," - " status_code=%#x\n", status, status_code); + adapter->cmd_wait_q.condition = true; - if (wait_queue->enabled) { - *wait_queue->condition = true; - wait_queue->status = status; - if (status && (status_code == MWIFIEX_ERROR_CMD_TIMEOUT)) - dev_err(adapter->dev, "cmd timeout\n"); - else - wake_up_interruptible(wait_queue->wait); - } else { - if (status) - dev_err(adapter->dev, "cmd failed: status_code=%#x\n", - status_code); - kfree(wait_queue); - } + if (adapter->cmd_wait_q.status == -ETIMEDOUT) + dev_err(adapter->dev, "cmd timeout\n"); + else + wake_up_interruptible(&adapter->cmd_wait_q.wait); return 0; } -- GitLab From 19a898601ad192d8c59c3a8f1a4501919f53b94d Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 13 Apr 2011 17:27:07 -0700 Subject: [PATCH 0959/5560] mwifiex: remove redundant "return" at end of void function The return statement at the last line of a void function is not necessary. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 6 ------ drivers/net/wireless/mwifiex/11n_rxreorder.c | 4 ---- drivers/net/wireless/mwifiex/cfg80211.c | 2 -- drivers/net/wireless/mwifiex/cmdevt.c | 13 +------------ drivers/net/wireless/mwifiex/debugfs.c | 3 --- drivers/net/wireless/mwifiex/init.c | 6 ------ drivers/net/wireless/mwifiex/main.c | 3 --- drivers/net/wireless/mwifiex/sdio.c | 4 ---- drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 -- drivers/net/wireless/mwifiex/wmm.c | 2 -- 10 files changed, 1 insertion(+), 44 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index edf4c274fa9b..c57107a860d1 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -543,8 +543,6 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, if (curr_tx_buf_size != tx_buf) mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, HostCmd_ACT_GEN_SET, 0, &tx_buf); - - return; } /* @@ -582,8 +580,6 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, list_del(&tx_ba_tsr_tbl->list); kfree(tx_ba_tsr_tbl); - - return; } /* @@ -662,8 +658,6 @@ void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr); spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); } - - return; } /* diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index ef46d0a8a6d0..6736fc604844 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -309,8 +309,6 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - - return; } /* @@ -610,8 +608,6 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, (u16) event->origninator << DELBA_INITIATOR_POS); delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a1ff490da836..74b6cf20da04 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1428,6 +1428,4 @@ mwifiex_cfg80211_results(struct work_struct *work) memset(priv->cfg_bssid, 0, ETH_ALEN); priv->disconnect = 0; } - - return; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index bb6fecd77619..776146a104ec 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -94,8 +94,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); cmd_node->resp_skb = NULL; } - - return; } /* @@ -536,7 +534,7 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, { unsigned long flags; - if (cmd_node == NULL) + if (!cmd_node) return; if (cmd_node->wait_q_enabled) @@ -548,8 +546,6 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter, spin_lock_irqsave(&adapter->cmd_free_q_lock, flags); list_add_tail(&cmd_node->list, &adapter->cmd_free_q); spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); - - return; } /* @@ -594,8 +590,6 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command); - - return; } /* @@ -871,8 +865,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); - - return; } /* @@ -989,8 +981,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) } adapter->cmd_wait_q.status = -1; mwifiex_complete_cmd(adapter); - - return; } /* @@ -1094,7 +1084,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->is_hs_configured = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY), false); - return; } /* diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index 77d7c777ea66..7ddcb062f103 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c @@ -735,8 +735,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv) MWIFIEX_DFS_ADD_FILE(getlog); MWIFIEX_DFS_ADD_FILE(regrdwr); MWIFIEX_DFS_ADD_FILE(rdeeprom); - - return; } /* @@ -749,7 +747,6 @@ mwifiex_dev_debugfs_remove(struct mwifiex_private *priv) return; debugfs_remove_recursive(priv->dfs_dev_dir); - return; } /* diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 26931d5f950f..1b79a5ac9214 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -299,8 +299,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->adhoc_awake_period = 0; memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; - - return; } /* @@ -339,8 +337,6 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter) adapter->if_ops.cleanup_if(adapter); dev_kfree_skb_any(adapter->sleep_cfm); - - return; } /* @@ -428,8 +424,6 @@ void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) list_del(&priv->rx_reorder_tbl_ptr); } } - - return; } /* diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index df665db8c433..77abfc3d6c32 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -505,7 +505,6 @@ mwifiex_fill_buffer(struct sk_buff *skb) */ do_gettimeofday(&tv); skb->tstamp = timeval_to_ktime(tv); - return; } /* @@ -820,8 +819,6 @@ mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) wiphy_unregister(priv->wdev->wiphy); wiphy_free(priv->wdev->wiphy); kfree(priv->wdev); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index f207756cbb79..fa46df509757 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -859,8 +859,6 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) adapter->int_status |= sdio_ireg; spin_unlock_irqrestore(&adapter->int_lock, flags); } - - return; } /* @@ -891,8 +889,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func) mwifiex_interrupt_status(adapter); queue_work(adapter->workqueue, &adapter->main_work); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 8743c116bee5..20ce8cb39186 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -103,8 +103,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = NULL; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - - return; } /* diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 1cfbc6bed692..6ce6f94e222b 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1232,6 +1232,4 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) if (mwifiex_dequeue_tx_packet(adapter)) break; } while (true); - - return; } -- GitLab From 572e8f3ead47ad223fb428a4f1db986317e8e0ec Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 13 Apr 2011 17:27:08 -0700 Subject: [PATCH 0960/5560] mwifiex: remove unused function parameters Some function parameters become useless after previous cleanup changes. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.c | 13 ++--- drivers/net/wireless/mwifiex/11n.h | 50 +++++++------------- drivers/net/wireless/mwifiex/11n_aggr.c | 5 +- drivers/net/wireless/mwifiex/11n_rxreorder.c | 6 +-- drivers/net/wireless/mwifiex/11n_rxreorder.h | 6 +-- drivers/net/wireless/mwifiex/cfp.c | 9 ++-- drivers/net/wireless/mwifiex/main.h | 17 ++----- drivers/net/wireless/mwifiex/scan.c | 7 +-- drivers/net/wireless/mwifiex/sdio.c | 18 ++++--- drivers/net/wireless/mwifiex/sta_cmd.c | 40 +++++++--------- drivers/net/wireless/mwifiex/sta_cmdresp.c | 13 ++--- drivers/net/wireless/mwifiex/sta_ioctl.c | 7 ++- drivers/net/wireless/mwifiex/wmm.c | 17 ++++--- drivers/net/wireless/mwifiex/wmm.h | 8 ++-- 14 files changed, 80 insertions(+), 136 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index c57107a860d1..d64065ff235c 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -242,9 +242,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, * * Handling includes changing the header fields into CPU format. */ -int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, - void *data_buf) +int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) { struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; @@ -298,8 +296,7 @@ int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, * - Setting AMSDU control parameters (for SET only) * - Ensuring correct endian-ness */ -int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, int cmd_action, void *data_buf) { struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = @@ -331,8 +328,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, * * Handling includes changing the header fields into CPU format. */ -int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, +int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, void *data_buf) { struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; @@ -357,8 +353,7 @@ int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, * - Setting HT Tx capability and HT Tx information fields * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg; diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 71a853e61b61..9128d2c9638b 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -28,15 +28,9 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_ret_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp, +int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf); -int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf); - -int mwifiex_cmd_11n_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf); int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, @@ -67,24 +61,19 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv, struct mwifiex_ds_rx_reorder_tbl *buf); int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, struct mwifiex_ds_tx_ba_stream_tbl *buf); -int mwifiex_ret_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command - *resp, +int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, void *data_buf); int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, int cmd_action, void *data_buf); -int mwifiex_cmd_amsdu_aggr_ctrl(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - int cmd_action, - void *data_buf); +int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd, + int cmd_action, void *data_buf); /* * This function checks whether AMPDU is allowed or not for a particular TID. */ static inline u8 -mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) +mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) { return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED) ? true : false); @@ -94,8 +83,7 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, * This function checks whether AMSDU is allowed or not for a particular TID. */ static inline u8 -mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) +mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) { return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && ((priv->is_data_rate_auto) @@ -106,21 +94,18 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, /* * This function checks whether a BA stream is available or not. */ -static inline u8 -mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) +static inline u8 mwifiex_is_ba_stream_avail(struct mwifiex_adapter *adapter) { - struct mwifiex_private *pmpriv = NULL; - u8 i = 0; + struct mwifiex_private *priv; + u8 i; u32 ba_stream_num = 0; - for (i = 0; i < priv->adapter->priv_num; i++) { - pmpriv = priv->adapter->priv[i]; - if (pmpriv) - ba_stream_num += - mwifiex_wmm_list_len(priv->adapter, - (struct list_head - *) &pmpriv-> - tx_ba_stream_tbl_ptr); + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (priv) + ba_stream_num += mwifiex_wmm_list_len( + (struct list_head *) + &priv->tx_ba_stream_tbl_ptr); } return ((ba_stream_num < @@ -133,8 +118,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv) * Upon successfully locating, both the TID and the RA are returned. */ static inline u8 -mwifiex_find_stream_to_delete(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int ptr_tid, +mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, int *ptid, u8 *ra) { int tid; diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index c2abced66957..c9fb0627de43 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -44,8 +44,7 @@ * MSDU => |DA|SA|Length|SNAP|...... ..| */ static int -mwifiex_11n_form_amsdu_pkt(struct mwifiex_adapter *adapter, - struct sk_buff *skb_aggr, +mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, struct sk_buff *skb_src, int *pad) { @@ -324,7 +323,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_11n_form_amsdu_pkt(adapter, skb_aggr, skb_src, &pad); + mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); mwifiex_write_data_complete(adapter, skb_src, 0); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 6736fc604844..755e5d533c03 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -319,8 +319,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, * - Setting add BA request buffer * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) { struct host_cmd_ds_11n_addba_req *add_ba_req = (struct host_cmd_ds_11n_addba_req *) @@ -391,8 +390,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, * - Setting del BA request buffer * - Ensuring correct endian-ness */ -int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) { struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) &cmd->params.del_ba; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 42f569035745..f3ca8c8c18f9 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -49,14 +49,12 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_cmd_11n_delba(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf); int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, void *data_buf); -int mwifiex_cmd_11n_addba_req(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv); struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 07187a405fee..bb73cfe14aeb 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -75,8 +75,7 @@ u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 }; * This function maps an index in supported rates table into * the corresponding data rate. */ -u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, - u8 ht_info) +u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info) { u16 mcs_rate[4][8] = { {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e} @@ -126,7 +125,7 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, * This function maps a data rate value into corresponding index in supported * rates table. */ -u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate) +u8 mwifiex_data_rate_to_index(u32 rate) { u16 *ptr; @@ -265,9 +264,7 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv) /* * This function converts rate bitmap into rate index. */ -int -mwifiex_get_rate_index(struct mwifiex_adapter *adapter, u16 *rate_bitmap, - int size) +int mwifiex_get_rate_index(u16 *rate_bitmap, int size) { int i; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 7ead15e1967e..2d296dcc210e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -767,8 +767,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); int mwifiex_scan_networks(struct mwifiex_private *priv, const struct mwifiex_user_scan_cfg *user_scan_in); -int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf); void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); @@ -806,9 +805,7 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, void *data_buf); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - void *data_buf); +int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); struct mwifiex_chan_freq_power * mwifiex_get_cfp_by_band_and_channel_from_cfg80211( struct mwifiex_private *priv, @@ -816,20 +813,16 @@ struct mwifiex_chan_freq_power * struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( struct mwifiex_private *priv, u8 band, u32 freq); -u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, - u8 ht_info); +u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info); u32 mwifiex_find_freq_from_band_chan(u8, u8); int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, u8 **buffer); -u32 mwifiex_index_to_data_rate(struct mwifiex_adapter *adapter, u8 index, - u8 ht_info); u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates); u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); -u8 mwifiex_data_rate_to_index(struct mwifiex_adapter *adapter, u32 rate); +u8 mwifiex_data_rate_to_index(u32 rate); u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); -int mwifiex_get_rate_index(struct mwifiex_adapter *adapter, - u16 *rateBitmap, int size); +int mwifiex_get_rate_index(u16 *rateBitmap, int size); extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; void mwifiex_save_curr_bcn(struct mwifiex_private *priv); void mwifiex_free_curr_bcn(struct mwifiex_private *priv); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 12fe021536d1..84742715893f 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2364,8 +2364,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, * - Setting command ID, and proper size * - Ensuring correct endian-ness */ -int mwifiex_cmd_802_11_scan(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, void *data_buf) +int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf) { struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan; struct mwifiex_scan_cmd_config *scan_cfg; @@ -2658,9 +2657,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, * - Setting background scan flush parameter * - Ensuring correct endian-ness */ -int mwifiex_cmd_802_11_bg_scan_query(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - void *data_buf) +int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd) { struct host_cmd_ds_802_11_bg_scan_query *bg_query = &cmd->params.bg_scan_query; diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fa46df509757..41c087d3f0f5 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -282,7 +282,7 @@ mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) */ static int mwifiex_write_data_sync(struct mwifiex_adapter *adapter, - u8 *buffer, u32 pkt_len, u32 port, u32 timeout) + u8 *buffer, u32 pkt_len, u32 port) { struct sdio_mmc_card *card = adapter->card; int ret = -1; @@ -314,9 +314,8 @@ mwifiex_write_data_sync(struct mwifiex_adapter *adapter, /* * This function reads multiple data from SDIO card memory. */ -static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, - u8 *buffer, u32 len, - u32 port, u32 timeout, u8 claim) +static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, + u32 len, u32 port, u8 claim) { struct sdio_mmc_card *card = adapter->card; int ret = -1; @@ -430,8 +429,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, int ret = 0; do { - ret = mwifiex_write_data_sync(adapter, payload, pkt_len, - port, 0); + ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port); if (ret) { i++; dev_err(adapter->dev, "host_to_card, write iomem" @@ -630,7 +628,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, return -1; } - ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 0, 1); + ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1); if (ret) { dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, @@ -769,7 +767,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks * MWIFIEX_SDIO_BLOCK_SIZE, - adapter->ioport, 0); + adapter->ioport); if (ret) { dev_err(adapter->dev, "FW download, write iomem (%d)" " failed @ %d\n", i, offset); @@ -842,7 +840,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) unsigned long flags; if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, - REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0, + REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) { dev_err(adapter->dev, "read mp_regs failed\n"); return; @@ -1050,7 +1048,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, card->mpa_rx.buf_len, (adapter->ioport | 0x1000 | (card->mpa_rx.ports << 4)) + - card->mpa_rx.start_port, 0, 1)) + card->mpa_rx.start_port, 1)) return -1; curr_ptr = card->mpa_rx.buf; diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index dec496369b95..33c8ba1f5e33 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -190,8 +190,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, * - Ensuring correct endian-ness */ static int -mwifiex_cmd_802_11_get_log(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd) +mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd) { cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) + @@ -272,8 +271,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, * (as required) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_tx_power_cfg(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct mwifiex_types_power_group *pg_tlv = NULL; @@ -407,8 +405,7 @@ static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv, * - Setting MAC multicast address * - Ensuring correct endian-ness */ -static int mwifiex_cmd_mac_multicast_adr(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct mwifiex_multicast_list *mcast_list = @@ -463,8 +460,7 @@ static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv, * - Setting command ID and proper size * - Ensuring correct endian-ness */ -static int mwifiex_cmd_802_11_ad_hoc_stop(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd) +static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd) { cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP); cmd->size = cpu_to_le16(S_DS_GEN); @@ -777,8 +773,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, * - Setting status to enable or disable (for SET only) * - Ensuring correct endian-ness */ -static int mwifiex_cmd_ibss_coalescing_status(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, +static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd, u16 cmd_action, void *data_buf) { struct host_cmd_ds_802_11_ibss_status *ibss_coal = @@ -946,7 +941,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, cmd_action); break; case HostCmd_CMD_MAC_MULTICAST_ADR: - ret = mwifiex_cmd_mac_multicast_adr(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_TX_RATE_CFG: @@ -954,7 +949,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_TXPWR_CFG: - ret = mwifiex_cmd_tx_power_cfg(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_802_11_PS_MODE_ENH: @@ -966,11 +961,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, (struct mwifiex_hs_config_param *) data_buf); break; case HostCmd_CMD_802_11_SCAN: - ret = mwifiex_cmd_802_11_scan(priv, cmd_ptr, data_buf); + ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); break; case HostCmd_CMD_802_11_BG_SCAN_QUERY: - ret = mwifiex_cmd_802_11_bg_scan_query(priv, cmd_ptr, - data_buf); + ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr); break; case HostCmd_CMD_802_11_ASSOCIATE: ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf); @@ -984,14 +978,14 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_802_11_GET_LOG: - ret = mwifiex_cmd_802_11_get_log(priv, cmd_ptr); + ret = mwifiex_cmd_802_11_get_log(cmd_ptr); break; case HostCmd_CMD_802_11_AD_HOC_JOIN: ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr, data_buf); break; case HostCmd_CMD_802_11_AD_HOC_STOP: - ret = mwifiex_cmd_802_11_ad_hoc_stop(priv, cmd_ptr); + ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr); break; case HostCmd_CMD_RSSI_INFO: ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action); @@ -1036,10 +1030,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, cmd_ptr->size = cpu_to_le16(S_DS_GEN); break; case HostCmd_CMD_11N_ADDBA_REQ: - ret = mwifiex_cmd_11n_addba_req(priv, cmd_ptr, data_buf); + ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf); break; case HostCmd_CMD_11N_DELBA: - ret = mwifiex_cmd_11n_delba(priv, cmd_ptr, data_buf); + ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf); break; case HostCmd_CMD_11N_ADDBA_RSP: ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf); @@ -1058,11 +1052,11 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: - ret = mwifiex_cmd_amsdu_aggr_ctrl(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_cmd_11n_cfg(priv, cmd_ptr, cmd_action, + ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: @@ -1075,8 +1069,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = 0; break; case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: - ret = mwifiex_cmd_ibss_coalescing_status(priv, cmd_ptr, - cmd_action, data_buf); + ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, + data_buf); break; case HostCmd_CMD_MAC_REG_ACCESS: case HostCmd_CMD_BBP_REG_ACCESS: diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 20ce8cb39186..7f4f10b752fb 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -280,7 +280,6 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *resp, void *data_buf) { - struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_rate_cfg *ds_rate = NULL; struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; @@ -336,9 +335,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, if (priv->is_data_rate_auto) { ds_rate->is_rate_auto = 1; } else { - ds_rate->rate = - mwifiex_get_rate_index(adapter, - priv-> + ds_rate->rate = mwifiex_get_rate_index(priv-> bitmap_rates, sizeof(priv-> bitmap_rates)); @@ -514,13 +511,11 @@ static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv, static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - struct mwifiex_adapter *adapter = priv->adapter; - priv->tx_rate = resp->params.tx_rate.tx_rate; priv->tx_htinfo = resp->params.tx_rate.ht_info; if (!priv->is_data_rate_auto) priv->data_rate = - mwifiex_index_to_data_rate(adapter, priv->tx_rate, + mwifiex_index_to_data_rate(priv->tx_rate, priv->tx_htinfo); return 0; @@ -946,7 +941,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, mp_end_port)); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: - ret = mwifiex_ret_amsdu_aggr_ctrl(priv, resp, data_buf); + ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: ret = mwifiex_ret_wmm_get_status(priv, resp); @@ -965,7 +960,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, case HostCmd_CMD_SET_BSS_MODE: break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_ret_11n_cfg(priv, resp, data_buf); + ret = mwifiex_ret_11n_cfg(resp, data_buf); break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 5f2ce9459d26..6489f264ef5f 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -812,8 +812,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, } memset(bitmap_rates, 0, sizeof(bitmap_rates)); - rate_index = - mwifiex_data_rate_to_index(adapter, rate_cfg->rate); + rate_index = mwifiex_data_rate_to_index(rate_cfg->rate); /* Only allow b/g rates to be set */ if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && @@ -874,8 +873,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, if (!ret) { if (rate && rate->is_rate_auto) - rate->rate = mwifiex_index_to_data_rate(priv->adapter, - priv->tx_rate, priv->tx_htinfo); + rate->rate = mwifiex_index_to_data_rate(priv->tx_rate, + priv->tx_htinfo); else if (rate) rate->rate = priv->data_rate; } else { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 6ce6f94e222b..57b98c59235d 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -177,8 +177,7 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv) * This function map ACs to TIDs. */ static void -mwifiex_wmm_queue_priorities_tid(struct mwifiex_private *priv, - u8 queue_priority[]) +mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) { int i; @@ -247,7 +246,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, } } - mwifiex_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority); + mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); } /* @@ -416,7 +415,7 @@ mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) priv = adapter->priv[j]; if (priv) { for (i = 0; i < MAX_NUM_TID; i++) - if (!mwifiex_wmm_is_ra_list_empty(adapter, + if (!mwifiex_wmm_is_ra_list_empty( &priv->wmm.tid_tbl_ptr[i].ra_list)) return false; } @@ -1161,7 +1160,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr) return -1; - tid = mwifiex_get_tid(priv->adapter, ptr); + tid = mwifiex_get_tid(ptr); dev_dbg(adapter->dev, "data: tid=%d\n", tid); @@ -1186,14 +1185,14 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) /* ra_list_spinlock has been freed in mwifiex_send_single_packet() */ } else { - if (mwifiex_is_ampdu_allowed(priv, ptr, tid)) { - if (mwifiex_is_ba_stream_avail(priv)) { + if (mwifiex_is_ampdu_allowed(priv, tid)) { + if (mwifiex_is_ba_stream_avail(adapter)) { mwifiex_11n_create_tx_ba_stream_tbl(priv, ptr->ra, tid, BA_STREAM_SETUP_INPROGRESS); mwifiex_send_addba(priv, tid, ptr->ra); } else if (mwifiex_find_stream_to_delete - (priv, ptr, tid, &tid_del, ra)) { + (priv, tid, &tid_del, ra)) { mwifiex_11n_create_tx_ba_stream_tbl(priv, ptr->ra, tid, BA_STREAM_SETUP_INPROGRESS); @@ -1202,7 +1201,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) } /* Minimum number of AMSDU */ #define MIN_NUM_AMSDU 2 - if (mwifiex_is_amsdu_allowed(priv, ptr, tid) && + if (mwifiex_is_amsdu_allowed(priv, tid) && (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= MIN_NUM_AMSDU)) mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index 241f1b0b77f9..fcea1f68792f 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -35,8 +35,7 @@ enum ieee_types_wmm_ecw_bitmasks { * This function retrieves the TID of the given RA list. */ static inline int -mwifiex_get_tid(struct mwifiex_adapter *adapter, - struct mwifiex_ra_list_tbl *ptr) +mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr) { struct sk_buff *skb; @@ -52,7 +51,7 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter, * This function gets the length of a list. */ static inline int -mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) +mwifiex_wmm_list_len(struct list_head *head) { struct list_head *pos; int count = 0; @@ -67,8 +66,7 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter, struct list_head *head) * This function checks if a RA list is empty or not. */ static inline u8 -mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter, - struct list_head *ra_list_hhead) +mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) { struct mwifiex_ra_list_tbl *ra_list; int is_list_empty; -- GitLab From 53d7938e6a2ac6569476fc59b404e70c0537b42b Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 13 Apr 2011 17:27:09 -0700 Subject: [PATCH 0961/5560] mwifiex: rename function mwifiex_is_ba_stream_avail The old function name sounds like checking for existing BA stream. The function actually checks if we have room for creating new BA stream or not. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n.h | 5 +++-- drivers/net/wireless/mwifiex/wmm.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 9128d2c9638b..02602ff30cbf 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -92,9 +92,10 @@ mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) } /* - * This function checks whether a BA stream is available or not. + * This function checks whether a space is available for new BA stream or not. */ -static inline u8 mwifiex_is_ba_stream_avail(struct mwifiex_adapter *adapter) +static inline u8 mwifiex_space_avail_for_new_ba_stream( + struct mwifiex_adapter *adapter) { struct mwifiex_private *priv; u8 i; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 57b98c59235d..99e8431c1e93 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -1186,7 +1186,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) mwifiex_send_single_packet() */ } else { if (mwifiex_is_ampdu_allowed(priv, tid)) { - if (mwifiex_is_ba_stream_avail(adapter)) { + if (mwifiex_space_avail_for_new_ba_stream(adapter)) { mwifiex_11n_create_tx_ba_stream_tbl(priv, ptr->ra, tid, BA_STREAM_SETUP_INPROGRESS); -- GitLab From 9f219bd248d417c2144eedafdf2c683ba8baee84 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 13 Apr 2011 21:00:02 -0500 Subject: [PATCH 0962/5560] rtlwifi: Fix unitialized variable warnings In http://lkml.indiana.edu/hypermail/linux/kernel/1104.1/01955.html, Geerti Uytterhoeven reports the following warnings for the rtlwifi drivers. src/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c: warning: 'cck_index' may be used uninitialized in this function: => 637 src/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c: warning: 'cck_index_old' may be used uninitialized in this function: => 637 src/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c: warning: 'box_extreg' may be used uninitialized in this function: => 303 src/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c: warning: 'box_reg' may be used uninitialized in this function: => 303 src/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c: warning: 'chnlgroup' may be used uninitialized in this function: => 205 src/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c: warning: 'u4_regvalue' may be used uninitialized in this function: => 450 src/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c: warning: 'hq_sele' may be used uninitialized in this function: => 924 Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bb023274414c..c228b9ee3711 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -634,7 +634,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_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; + u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0; int i; bool is2t = IS_92C_SERIAL(rtlhal->version); u8 txpwr_level[2] = {0, 0}; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index f107660f545d..bc9d24134ac4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -293,7 +293,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 boxnum; - u16 box_reg, box_extreg; + u16 box_reg = 0, box_extreg = 0; u8 u1b_tmp; bool isfw_read = false; bool bwrite_sucess = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 669b1168dbec..e301b12e281a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -202,7 +202,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(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)); - u8 i, chnlgroup, pwr_diff_limit[4]; + u8 i, chnlgroup = 0, pwr_diff_limit[4]; u32 writeVal, customer_limit, rf; for (rf = 0; rf < 2; rf++) { @@ -447,7 +447,7 @@ 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; + u32 u4_regvalue = 0; u8 rfpath; bool rtstatus; struct bb_reg_def *pphyreg; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 9444e76838cf..e43be2547827 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -921,7 +921,7 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, u8 out_ep_num, u8 queue_sel) { - u8 hq_sele; + u8 hq_sele = 0; struct rtl_priv *rtlpriv = rtl_priv(hw); switch (out_ep_num) { -- GitLab From 34a0a2025c8bddc6505b56a58ef2e7333a4e4165 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Thu, 14 Apr 2011 16:41:30 +0530 Subject: [PATCH 0963/5560] ath: Add a missing world regulatory domain 0x6C Some customers use 0x6C world regulatory domain and this patch adds the support. Cc: Luis R. Rodriguez Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 7 ++++--- drivers/net/wireless/ath/regd_common.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index f828f294ba89..7e3b29015dda 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -97,8 +97,8 @@ static const struct ieee80211_regdomain ath_world_regdom_66_69 = { } }; -/* Can be used by 0x67, 0x6A and 0x68 */ -static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { +/* Can be used by 0x67, 0x68, 0x6A and 0x6C */ +static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { .n_reg_rules = 4, .alpha2 = "99", .reg_rules = { @@ -151,7 +151,8 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) case 0x67: case 0x68: case 0x6A: - return &ath_world_regdom_67_68_6A; + case 0x6C: + return &ath_world_regdom_67_68_6A_6C; default: WARN_ON(1); return ath_default_world_regdomain(); diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h index 5c2cfe694152..24b53839fc3a 100644 --- a/drivers/net/wireless/ath/regd_common.h +++ b/drivers/net/wireless/ath/regd_common.h @@ -86,6 +86,7 @@ enum EnumRd { WOR9_WORLD = 0x69, WORA_WORLD = 0x6A, WORB_WORLD = 0x6B, + WORC_WORLD = 0x6C, MKK3_MKKB = 0x80, MKK3_MKKA2 = 0x81, @@ -282,6 +283,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = { {WOR9_WORLD, NO_CTL, NO_CTL}, {WORA_WORLD, NO_CTL, NO_CTL}, {WORB_WORLD, NO_CTL, NO_CTL}, + {WORC_WORLD, NO_CTL, NO_CTL}, }; static struct country_code_to_enum_rd allCountries[] = { -- GitLab From 98346f7db014614a4814eb60639f651f8bbc591d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Apr 2011 13:42:46 -0700 Subject: [PATCH 0964/5560] Revert "usb: usb_storage: do not align length of request for CBW to maxp size" This reverts commit 806e8f8fcc27e1753947bd9f059ba2316cf8f92a. To quote Alan Stern: The necessity for this patch has been under discussion. It turns out the UDC that Mian has been working on and Felipe's UDC have contradictory requirements. Mian's UDC driver wants a bulk-OUT transfer length to be shorter than the maxpacket size if a short packet is expected, whereas Felipe's UDC hardware always needs bulk-OUT transfer lengths to be evenly divisible by the maxpacket size. Mian has agreed to go back over the driver to resolve this conflict. This means we probably will not want this patch after all. (In fact, we may ultimately decide to change the gadget framework to require that bulk-OUT transfer lengths _always_ be divisible by the maxpacket size -- only the g_file_storage and g_mass_storage gadgets would need to be changed.) Cc: Mian Yousaf Kaukab Cc: Michal Nazarewicz Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 24 ++++++++++++++++++++---- drivers/usb/gadget/file_storage.c | 28 ++++++++++++++++++++++------ drivers/usb/gadget/storage_common.c | 7 +++++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 7d95a2cf58a3..01ae27b60d4c 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -474,6 +474,20 @@ static int exception_in_progress(struct fsg_common *common) return common->state > FSG_STATE_IDLE; } +/* Make bulk-out requests be divisible by the maxpacket size */ +static void set_bulk_out_req_length(struct fsg_common *common, + struct fsg_buffhd *bh, unsigned int length) +{ + unsigned int rem; + + bh->bulk_out_intended_length = length; + rem = length % common->bulk_out_maxpacket; + if (rem > 0) + length += common->bulk_out_maxpacket - rem; + bh->outreq->length = length; +} + + /*-------------------------------------------------------------------------*/ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) @@ -572,9 +586,9 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) struct fsg_buffhd *bh = req->context; dump_msg(common, "bulk-out", req->buf, req->actual); - if (req->status || req->actual != req->length) + if (req->status || req->actual != bh->bulk_out_intended_length) DBG(common, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); + req->status, req->actual, bh->bulk_out_intended_length); if (req->status == -ECONNRESET) /* Request was cancelled */ usb_ep_fifo_flush(ep); @@ -966,6 +980,7 @@ static int do_write(struct fsg_common *common) * the bulk-out maxpacket size */ bh->outreq->length = amount; + bh->bulk_out_intended_length = amount; bh->outreq->short_not_ok = 1; if (!start_out_transfer(common, bh)) /* Dunno what to do if common->fsg is NULL */ @@ -1611,6 +1626,7 @@ static int throw_away_data(struct fsg_common *common) * the bulk-out maxpacket size. */ bh->outreq->length = amount; + bh->bulk_out_intended_length = amount; bh->outreq->short_not_ok = 1; if (!start_out_transfer(common, bh)) /* Dunno what to do if common->fsg is NULL */ @@ -2279,8 +2295,8 @@ static int get_next_command(struct fsg_common *common) } /* Queue a request to read a Bulk-only CBW */ - bh->outreq->length = USB_BULK_CB_WRAP_LEN; - bh->outreq->short_not_ok = 0; + set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); + bh->outreq->short_not_ok = 1; if (!start_out_transfer(common, bh)) /* Don't know what to do if common->fsg is NULL */ return -EIO; diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index aebfb81f3ba4..fcfc77c7ad70 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -497,6 +497,19 @@ static int exception_in_progress(struct fsg_dev *fsg) return (fsg->state > FSG_STATE_IDLE); } +/* Make bulk-out requests be divisible by the maxpacket size */ +static void set_bulk_out_req_length(struct fsg_dev *fsg, + struct fsg_buffhd *bh, unsigned int length) +{ + unsigned int rem; + + bh->bulk_out_intended_length = length; + rem = length % fsg->bulk_out_maxpacket; + if (rem > 0) + length += fsg->bulk_out_maxpacket - rem; + bh->outreq->length = length; +} + static struct fsg_dev *the_fsg; static struct usb_gadget_driver fsg_driver; @@ -717,9 +730,10 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) struct fsg_buffhd *bh = req->context; dump_msg(fsg, "bulk-out", req->buf, req->actual); - if (req->status || req->actual != req->length) + if (req->status || req->actual != bh->bulk_out_intended_length) DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); + req->status, req->actual, + bh->bulk_out_intended_length); if (req->status == -ECONNRESET) // Request was cancelled usb_ep_fifo_flush(ep); @@ -1335,7 +1349,8 @@ static int do_write(struct fsg_dev *fsg) /* amount is always divisible by 512, hence by * the bulk-out maxpacket size */ - bh->outreq->length = amount; + bh->outreq->length = bh->bulk_out_intended_length = + amount; bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); @@ -1964,7 +1979,8 @@ static int throw_away_data(struct fsg_dev *fsg) /* amount is always divisible by 512, hence by * the bulk-out maxpacket size */ - bh->outreq->length = amount; + bh->outreq->length = bh->bulk_out_intended_length = + amount; bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); @@ -2643,8 +2659,8 @@ static int get_next_command(struct fsg_dev *fsg) } /* Queue a request to read a Bulk-only CBW */ - bh->outreq->length = USB_BULK_CB_WRAP_LEN; - bh->outreq->short_not_ok = 0; + set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); + bh->outreq->short_not_ok = 1; start_transfer(fsg, fsg->bulk_out, bh->outreq, &bh->outreq_busy, &bh->state); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 86fcebd89abe..109635a84888 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -286,6 +286,13 @@ struct fsg_buffhd { enum fsg_buffer_state state; struct fsg_buffhd *next; + /* + * The NetChip 2280 is faster, and handles some protocol faults + * better, if we don't submit any short bulk-out read requests. + * So we will record the intended request length here. + */ + unsigned int bulk_out_intended_length; + struct usb_request *inreq; int inreq_busy; struct usb_request *outreq; -- GitLab From 62f3a2cfb1891c070631e496eeea852e949ea8bb Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 14 Apr 2011 18:34:34 -0300 Subject: [PATCH 0965/5560] Bluetooth: Fix another locking unbalance l2cap_get_sock_by_scid was changed to not lock the socket anymore, but I forgot to change all the users of this function. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d5db5a38df6a..bc84ed1b3320 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -632,6 +632,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) if (!parent) return; + bh_lock_sock(parent); + /* Check for backlog size */ if (sk_acceptq_is_full(parent)) { BT_DBG("backlog full %d", parent->sk_ack_backlog); -- GitLab From 26954c7f26068b6ced108806fdd39aee5cd54e6f Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 14 Apr 2011 17:57:26 -0300 Subject: [PATCH 0966/5560] Bluetooth: Fix lockdep warning in L2CAP Fix a regression from the L2CAP "rewrite" patches. Purge the tx_q already happens on l2cap_chan_del() so we don't need it at l2cap_disconnect_req(). Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index bc84ed1b3320..d47de2b04b2e 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -477,8 +477,6 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, in sk = chan->sk; - skb_queue_purge(&chan->tx_q); - if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) { del_timer(&chan->retrans_timer); del_timer(&chan->monitor_timer); -- GitLab From 21d8c49e01a0c1c6eb6c750cd04110db4a539284 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 14 Apr 2011 14:49:37 -0700 Subject: [PATCH 0967/5560] ipv4: Call fib_select_default() only when actually necessary. fib_select_default() is a complete NOP, and completely pointless to invoke, when we have no more than 1 default route installed. And this is far and away the common case. So remember how many prefixlen==0 routes we have in the routing table, and elide the call when we have no more than one of those. This cuts output route creation time by 157 cycles on Niagara2+. In order to add the new int to fib_table, we have to correct the type of ->tb_data[] to unsigned long, otherwise the private area will be unaligned on 64-bit systems. Signed-off-by: David S. Miller Reviewed-by: Eric Dumazet --- include/net/ip_fib.h | 3 ++- net/ipv4/fib_trie.c | 7 +++++++ net/ipv4/route.c | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 514627f56339..10422ef14e28 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -160,7 +160,8 @@ struct fib_table { struct hlist_node tb_hlist; u32 tb_id; int tb_default; - unsigned char tb_data[0]; + int tb_num_default; + unsigned long tb_data[0]; }; extern int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index bde80c450b52..9ac481a10d37 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1332,6 +1332,9 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) } } + if (!plen) + tb->tb_num_default++; + list_add_tail_rcu(&new_fa->fa_list, (fa ? &fa->fa_list : fa_head)); @@ -1697,6 +1700,9 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) list_del_rcu(&fa->fa_list); + if (!plen) + tb->tb_num_default--; + if (list_empty(fa_head)) { hlist_del_rcu(&li->hlist); free_leaf_info(li); @@ -1987,6 +1993,7 @@ struct fib_table *fib_trie_table(u32 id) tb->tb_id = id; tb->tb_default = -1; + tb->tb_num_default = 0; t = (struct trie *) tb->tb_data; memset(t, 0, sizeof(*t)); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 0e7430c327a7..e9aee81de3e3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2615,7 +2615,9 @@ static struct rtable *ip_route_output_slow(struct net *net, fib_select_multipath(&res); else #endif - if (!res.prefixlen && res.type == RTN_UNICAST && !fl4.flowi4_oif) + if (!res.prefixlen && + res.table->tb_num_default > 1 && + res.type == RTN_UNICAST && !fl4.flowi4_oif) fib_select_default(&res); if (!fl4.saddr) -- GitLab From 4d05a28db56225bbab5e1321d818f318e92a4657 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 18:25:47 -0400 Subject: [PATCH 0968/5560] xen: add blkback support Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Konrad Rzeszutek Wilk Conflicts: drivers/xen/Makefile --- drivers/xen/Kconfig | 8 + drivers/xen/Makefile | 1 + drivers/xen/blkback/Makefile | 3 + drivers/xen/blkback/blkback.c | 656 ++++++++++++++++++++++++++++++++ drivers/xen/blkback/common.h | 139 +++++++ drivers/xen/blkback/interface.c | 181 +++++++++ drivers/xen/blkback/vbd.c | 118 ++++++ drivers/xen/blkback/xenbus.c | 541 ++++++++++++++++++++++++++ include/xen/blkif.h | 123 ++++++ 9 files changed, 1770 insertions(+) create mode 100644 drivers/xen/blkback/Makefile create mode 100644 drivers/xen/blkback/blkback.c create mode 100644 drivers/xen/blkback/common.h create mode 100644 drivers/xen/blkback/interface.c create mode 100644 drivers/xen/blkback/vbd.c create mode 100644 drivers/xen/blkback/xenbus.c create mode 100644 include/xen/blkif.h diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index a59638b37c1a..fb1af628cbfc 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -37,6 +37,14 @@ config XEN_BACKEND Support for backend device drivers that provide I/O services to other virtual machines. +config XEN_BLKDEV_BACKEND + tristate "Block-device backend driver" + depends on XEN_BACKEND && BLOCK + help + The block-device backend driver allows the kernel to export its + block devices to other guests via a high-performance shared-memory + interface. + config XENFS tristate "Xen filesystem" default y diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index f420f1ff7f13..29c0a416f082 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_XEN_BALLOON) += xen-balloon.o obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o obj-$(CONFIG_XEN_GNTDEV) += xen-gntdev.o obj-$(CONFIG_XEN_GRANT_DEV_ALLOC) += xen-gntalloc.o +obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/ obj-$(CONFIG_XENFS) += xenfs/ obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o obj-$(CONFIG_XEN_PLATFORM_PCI) += xen-platform-pci.o diff --git a/drivers/xen/blkback/Makefile b/drivers/xen/blkback/Makefile new file mode 100644 index 000000000000..8bab63da3b3e --- /dev/null +++ b/drivers/xen/blkback/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o + +blkbk-y := blkback.o xenbus.o interface.o vbd.o diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c new file mode 100644 index 000000000000..5b8d50e344b4 --- /dev/null +++ b/drivers/xen/blkback/blkback.c @@ -0,0 +1,656 @@ +/****************************************************************************** + * arch/xen/drivers/blkif/backend/main.c + * + * Back-end of the driver for virtual block devices. This portion of the + * driver exports a 'unified' block-device interface that can be accessed + * by any operating system that implements a compatible front end. A + * reference front-end implementation can be found in: + * arch/xen/drivers/blkif/frontend + * + * Copyright (c) 2003-2004, Keir Fraser & Steve Hand + * Copyright (c) 2005, Christopher Clark + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" + +/* + * These are rather arbitrary. They are fairly large because adjacent requests + * pulled from a communication ring are quite likely to end up being part of + * the same scatter/gather request at the disc. + * + * ** TRY INCREASING 'blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW ** + * + * This will increase the chances of being able to write whole tracks. + * 64 should be enough to keep us competitive with Linux. + */ +static int blkif_reqs = 64; +module_param_named(reqs, blkif_reqs, int, 0); +MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); + +/* Run-time switchable: /sys/module/blkback/parameters/ */ +static unsigned int log_stats = 0; +static unsigned int debug_lvl = 0; +module_param(log_stats, int, 0644); +module_param(debug_lvl, int, 0644); + +/* + * Each outstanding request that we've passed to the lower device layers has a + * 'pending_req' allocated to it. Each buffer_head that completes decrements + * the pendcnt towards zero. When it hits zero, the specified domain has a + * response queued for it, with the saved 'id' passed back. + */ +typedef struct { + blkif_t *blkif; + u64 id; + int nr_pages; + atomic_t pendcnt; + unsigned short operation; + int status; + struct list_head free_list; +} pending_req_t; + +static pending_req_t *pending_reqs; +static struct list_head pending_free; +static DEFINE_SPINLOCK(pending_free_lock); +static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq); + +#define BLKBACK_INVALID_HANDLE (~0) + +static struct page **pending_pages; +static grant_handle_t *pending_grant_handles; + +static inline int vaddr_pagenr(pending_req_t *req, int seg) +{ + return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; +} + +static inline unsigned long vaddr(pending_req_t *req, int seg) +{ + unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]); + return (unsigned long)pfn_to_kaddr(pfn); +} + +#define pending_handle(_req, _seg) \ + (pending_grant_handles[vaddr_pagenr(_req, _seg)]) + + +static int do_block_io_op(blkif_t *blkif); +static void dispatch_rw_block_io(blkif_t *blkif, + blkif_request_t *req, + pending_req_t *pending_req); +static void make_response(blkif_t *blkif, u64 id, + unsigned short op, int st); + +/****************************************************************** + * misc small helpers + */ +static pending_req_t* alloc_req(void) +{ + pending_req_t *req = NULL; + unsigned long flags; + + spin_lock_irqsave(&pending_free_lock, flags); + if (!list_empty(&pending_free)) { + req = list_entry(pending_free.next, pending_req_t, free_list); + list_del(&req->free_list); + } + spin_unlock_irqrestore(&pending_free_lock, flags); + return req; +} + +static void free_req(pending_req_t *req) +{ + unsigned long flags; + int was_empty; + + spin_lock_irqsave(&pending_free_lock, flags); + was_empty = list_empty(&pending_free); + list_add(&req->free_list, &pending_free); + spin_unlock_irqrestore(&pending_free_lock, flags); + if (was_empty) + wake_up(&pending_free_wq); +} + +static void unplug_queue(blkif_t *blkif) +{ + if (blkif->plug == NULL) + return; + if (blkif->plug->unplug_fn) + blkif->plug->unplug_fn(blkif->plug); + blk_put_queue(blkif->plug); + blkif->plug = NULL; +} + +static void plug_queue(blkif_t *blkif, struct block_device *bdev) +{ + request_queue_t *q = bdev_get_queue(bdev); + + if (q == blkif->plug) + return; + unplug_queue(blkif); + blk_get_queue(q); + blkif->plug = q; +} + +static void fast_flush_area(pending_req_t *req) +{ + struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + unsigned int i, invcount = 0; + grant_handle_t handle; + int ret; + + for (i = 0; i < req->nr_pages; i++) { + handle = pending_handle(req, i); + if (handle == BLKBACK_INVALID_HANDLE) + continue; + gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), + GNTMAP_host_map, handle); + pending_handle(req, i) = BLKBACK_INVALID_HANDLE; + invcount++; + } + + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); + BUG_ON(ret); +} + +/****************************************************************** + * SCHEDULER FUNCTIONS + */ + +static void print_stats(blkif_t *blkif) +{ + printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | br %4d\n", + current->comm, blkif->st_oo_req, + blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req); + blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); + blkif->st_rd_req = 0; + blkif->st_wr_req = 0; + blkif->st_oo_req = 0; +} + +int blkif_schedule(void *arg) +{ + blkif_t *blkif = arg; + + blkif_get(blkif); + + if (debug_lvl) + printk(KERN_DEBUG "%s: started\n", current->comm); + + while (!kthread_should_stop()) { + if (try_to_freeze()) + continue; + + wait_event_interruptible( + blkif->wq, + blkif->waiting_reqs || kthread_should_stop()); + wait_event_interruptible( + pending_free_wq, + !list_empty(&pending_free) || kthread_should_stop()); + + blkif->waiting_reqs = 0; + smp_mb(); /* clear flag *before* checking for work */ + + if (do_block_io_op(blkif)) + blkif->waiting_reqs = 1; + unplug_queue(blkif); + + if (log_stats && time_after(jiffies, blkif->st_print)) + print_stats(blkif); + } + + if (log_stats) + print_stats(blkif); + if (debug_lvl) + printk(KERN_DEBUG "%s: exiting\n", current->comm); + + blkif->xenblkd = NULL; + blkif_put(blkif); + + return 0; +} + +/****************************************************************** + * COMPLETION CALLBACK -- Called as bh->b_end_io() + */ + +static void __end_block_io_op(pending_req_t *pending_req, int error) +{ + /* An error fails the entire request. */ + if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) && + (error == -EOPNOTSUPP)) { + DPRINTK("blkback: write barrier op failed, not supported\n"); + blkback_barrier(XBT_NIL, pending_req->blkif->be, 0); + pending_req->status = BLKIF_RSP_EOPNOTSUPP; + } else if (error) { + DPRINTK("Buffer not up-to-date at end of operation, " + "error=%d\n", error); + pending_req->status = BLKIF_RSP_ERROR; + } + + if (atomic_dec_and_test(&pending_req->pendcnt)) { + fast_flush_area(pending_req); + make_response(pending_req->blkif, pending_req->id, + pending_req->operation, pending_req->status); + blkif_put(pending_req->blkif); + free_req(pending_req); + } +} + +static int end_block_io_op(struct bio *bio, unsigned int done, int error) +{ + if (bio->bi_size != 0) + return 1; + __end_block_io_op(bio->bi_private, error); + bio_put(bio); + return error; +} + + +/****************************************************************************** + * NOTIFICATION FROM GUEST OS. + */ + +static void blkif_notify_work(blkif_t *blkif) +{ + blkif->waiting_reqs = 1; + wake_up(&blkif->wq); +} + +irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs) +{ + blkif_notify_work(dev_id); + return IRQ_HANDLED; +} + + + +/****************************************************************** + * DOWNWARD CALLS -- These interface with the block-device layer proper. + */ + +static int do_block_io_op(blkif_t *blkif) +{ + blkif_back_rings_t *blk_rings = &blkif->blk_rings; + blkif_request_t req; + pending_req_t *pending_req; + RING_IDX rc, rp; + int more_to_do = 0; + + rc = blk_rings->common.req_cons; + rp = blk_rings->common.sring->req_prod; + rmb(); /* Ensure we see queued requests up to 'rp'. */ + + while (rc != rp) { + + if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) + break; + + pending_req = alloc_req(); + if (NULL == pending_req) { + blkif->st_oo_req++; + more_to_do = 1; + break; + } + + if (kthread_should_stop()) { + more_to_do = 1; + break; + } + + switch (blkif->blk_protocol) { + case BLKIF_PROTOCOL_NATIVE: + memcpy(&req, RING_GET_REQUEST(&blk_rings->native, rc), sizeof(req)); + break; + case BLKIF_PROTOCOL_X86_32: + blkif_get_x86_32_req(&req, RING_GET_REQUEST(&blk_rings->x86_32, rc)); + break; + case BLKIF_PROTOCOL_X86_64: + blkif_get_x86_64_req(&req, RING_GET_REQUEST(&blk_rings->x86_64, rc)); + break; + default: + BUG(); + } + blk_rings->common.req_cons = ++rc; /* before make_response() */ + + /* Apply all sanity checks to /private copy/ of request. */ + barrier(); + + switch (req.operation) { + case BLKIF_OP_READ: + blkif->st_rd_req++; + dispatch_rw_block_io(blkif, &req, pending_req); + break; + case BLKIF_OP_WRITE_BARRIER: + blkif->st_br_req++; + /* fall through */ + case BLKIF_OP_WRITE: + blkif->st_wr_req++; + dispatch_rw_block_io(blkif, &req, pending_req); + break; + default: + /* A good sign something is wrong: sleep for a while to + * avoid excessive CPU consumption by a bad guest. */ + msleep(1); + DPRINTK("error: unknown block io operation [%d]\n", + req.operation); + make_response(blkif, req.id, req.operation, + BLKIF_RSP_ERROR); + free_req(pending_req); + break; + } + + /* Yield point for this unbounded loop. */ + cond_resched(); + } + + return more_to_do; +} + +static void dispatch_rw_block_io(blkif_t *blkif, + blkif_request_t *req, + pending_req_t *pending_req) +{ + extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); + struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct phys_req preq; + struct { + unsigned long buf; unsigned int nsec; + } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + unsigned int nseg; + struct bio *bio = NULL; + int ret, i; + int operation; + + switch (req->operation) { + case BLKIF_OP_READ: + operation = READ; + break; + case BLKIF_OP_WRITE: + operation = WRITE; + break; + case BLKIF_OP_WRITE_BARRIER: + operation = WRITE_BARRIER; + break; + default: + operation = 0; /* make gcc happy */ + BUG(); + } + + /* Check that number of segments is sane. */ + nseg = req->nr_segments; + if (unlikely(nseg == 0 && operation != WRITE_BARRIER) || + unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { + DPRINTK("Bad number of segments in request (%d)\n", nseg); + goto fail_response; + } + + preq.dev = req->handle; + preq.sector_number = req->sector_number; + preq.nr_sects = 0; + + pending_req->blkif = blkif; + pending_req->id = req->id; + pending_req->operation = req->operation; + pending_req->status = BLKIF_RSP_OKAY; + pending_req->nr_pages = nseg; + + for (i = 0; i < nseg; i++) { + uint32_t flags; + + seg[i].nsec = req->seg[i].last_sect - + req->seg[i].first_sect + 1; + + if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) || + (req->seg[i].last_sect < req->seg[i].first_sect)) + goto fail_response; + preq.nr_sects += seg[i].nsec; + + flags = GNTMAP_host_map; + if (operation != READ) + flags |= GNTMAP_readonly; + gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, + req->seg[i].gref, blkif->domid); + } + + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); + BUG_ON(ret); + + for (i = 0; i < nseg; i++) { + if (unlikely(map[i].status != 0)) { + DPRINTK("invalid buffer -- could not remap it\n"); + map[i].handle = BLKBACK_INVALID_HANDLE; + ret |= 1; + } + + pending_handle(pending_req, i) = map[i].handle; + + if (ret) + continue; + + set_phys_to_machine(__pa(vaddr( + pending_req, i)) >> PAGE_SHIFT, + FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); + seg[i].buf = map[i].dev_bus_addr | + (req->seg[i].first_sect << 9); + } + + if (ret) + goto fail_flush; + + if (vbd_translate(&preq, blkif, operation) != 0) { + DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", + operation == READ ? "read" : "write", + preq.sector_number, + preq.sector_number + preq.nr_sects, preq.dev); + goto fail_flush; + } + + plug_queue(blkif, preq.bdev); + atomic_set(&pending_req->pendcnt, 1); + blkif_get(blkif); + + for (i = 0; i < nseg; i++) { + if (((int)preq.sector_number|(int)seg[i].nsec) & + ((bdev_hardsect_size(preq.bdev) >> 9) - 1)) { + DPRINTK("Misaligned I/O request from domain %d", + blkif->domid); + goto fail_put_bio; + } + + while ((bio == NULL) || + (bio_add_page(bio, + virt_to_page(vaddr(pending_req, i)), + seg[i].nsec << 9, + seg[i].buf & ~PAGE_MASK) == 0)) { + if (bio) { + atomic_inc(&pending_req->pendcnt); + submit_bio(operation, bio); + } + + bio = bio_alloc(GFP_KERNEL, nseg-i); + if (unlikely(bio == NULL)) + goto fail_put_bio; + + bio->bi_bdev = preq.bdev; + bio->bi_private = pending_req; + bio->bi_end_io = end_block_io_op; + bio->bi_sector = preq.sector_number; + } + + preq.sector_number += seg[i].nsec; + } + + if (!bio) { + BUG_ON(operation != WRITE_BARRIER); + bio = bio_alloc(GFP_KERNEL, 0); + if (unlikely(bio == NULL)) + goto fail_put_bio; + + bio->bi_bdev = preq.bdev; + bio->bi_private = pending_req; + bio->bi_end_io = end_block_io_op; + bio->bi_sector = -1; + } + + submit_bio(operation, bio); + + if (operation == READ) + blkif->st_rd_sect += preq.nr_sects; + else if (operation == WRITE || operation == WRITE_BARRIER) + blkif->st_wr_sect += preq.nr_sects; + + return; + + fail_flush: + fast_flush_area(pending_req); + fail_response: + make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); + free_req(pending_req); + msleep(1); /* back off a bit */ + return; + + fail_put_bio: + __end_block_io_op(pending_req, -EINVAL); + if (bio) + bio_put(bio); + unplug_queue(blkif); + msleep(1); /* back off a bit */ + return; +} + + + +/****************************************************************** + * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING + */ + + +static void make_response(blkif_t *blkif, u64 id, + unsigned short op, int st) +{ + blkif_response_t resp; + unsigned long flags; + blkif_back_rings_t *blk_rings = &blkif->blk_rings; + int more_to_do = 0; + int notify; + + resp.id = id; + resp.operation = op; + resp.status = st; + + spin_lock_irqsave(&blkif->blk_ring_lock, flags); + /* Place on the response ring for the relevant domain. */ + switch (blkif->blk_protocol) { + case BLKIF_PROTOCOL_NATIVE: + memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt), + &resp, sizeof(resp)); + break; + case BLKIF_PROTOCOL_X86_32: + memcpy(RING_GET_RESPONSE(&blk_rings->x86_32, blk_rings->x86_32.rsp_prod_pvt), + &resp, sizeof(resp)); + break; + case BLKIF_PROTOCOL_X86_64: + memcpy(RING_GET_RESPONSE(&blk_rings->x86_64, blk_rings->x86_64.rsp_prod_pvt), + &resp, sizeof(resp)); + break; + default: + BUG(); + } + blk_rings->common.rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify); + if (blk_rings->common.rsp_prod_pvt == blk_rings->common.req_cons) { + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(&blk_rings->common, more_to_do); + + } else if (RING_HAS_UNCONSUMED_REQUESTS(&blk_rings->common)) { + more_to_do = 1; + } + + spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); + + if (more_to_do) + blkif_notify_work(blkif); + if (notify) + notify_remote_via_irq(blkif->irq); +} + +static int __init blkif_init(void) +{ + int i, mmap_pages; + + if (!is_running_on_xen()) + return -ENODEV; + + mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; + + pending_reqs = kmalloc(sizeof(pending_reqs[0]) * + blkif_reqs, GFP_KERNEL); + pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * + mmap_pages, GFP_KERNEL); + pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); + + if (!pending_reqs || !pending_grant_handles || !pending_pages) + goto out_of_memory; + + for (i = 0; i < mmap_pages; i++) + pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; + + blkif_interface_init(); + + memset(pending_reqs, 0, sizeof(pending_reqs)); + INIT_LIST_HEAD(&pending_free); + + for (i = 0; i < blkif_reqs; i++) + list_add_tail(&pending_reqs[i].free_list, &pending_free); + + blkif_xenbus_init(); + + return 0; + + out_of_memory: + kfree(pending_reqs); + kfree(pending_grant_handles); + free_empty_pages_and_pagevec(pending_pages, mmap_pages); + printk("%s: out of memory\n", __FUNCTION__); + return -ENOMEM; +} + +module_init(blkif_init); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h new file mode 100644 index 000000000000..422e935528be --- /dev/null +++ b/drivers/xen/blkback/common.h @@ -0,0 +1,139 @@ +/* + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __BLKIF__BACKEND__COMMON_H__ +#define __BLKIF__BACKEND__COMMON_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPRINTK(_f, _a...) \ + pr_debug("(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) + +struct vbd { + blkif_vdev_t handle; /* what the domain refers to this vbd as */ + unsigned char readonly; /* Non-zero -> read-only */ + unsigned char type; /* VDISK_xxx */ + u32 pdevice; /* phys device that this vbd maps to */ + struct block_device *bdev; +}; + +struct backend_info; + +typedef struct blkif_st { + /* Unique identifier for this interface. */ + domid_t domid; + unsigned int handle; + /* Physical parameters of the comms window. */ + unsigned int irq; + /* Comms information. */ + enum blkif_protocol blk_protocol; + blkif_back_rings_t blk_rings; + struct vm_struct *blk_ring_area; + /* The VBD attached to this interface. */ + struct vbd vbd; + /* Back pointer to the backend_info. */ + struct backend_info *be; + /* Private fields. */ + spinlock_t blk_ring_lock; + atomic_t refcnt; + + wait_queue_head_t wq; + struct task_struct *xenblkd; + unsigned int waiting_reqs; + request_queue_t *plug; + + /* statistics */ + unsigned long st_print; + int st_rd_req; + int st_wr_req; + int st_oo_req; + int st_br_req; + int st_rd_sect; + int st_wr_sect; + + wait_queue_head_t waiting_to_free; + + grant_handle_t shmem_handle; + grant_ref_t shmem_ref; +} blkif_t; + +blkif_t *blkif_alloc(domid_t domid); +void blkif_disconnect(blkif_t *blkif); +void blkif_free(blkif_t *blkif); +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); + +#define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) +#define blkif_put(_b) \ + do { \ + if (atomic_dec_and_test(&(_b)->refcnt)) \ + wake_up(&(_b)->waiting_to_free);\ + } while (0) + +/* Create a vbd. */ +int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major, + unsigned minor, int readonly, int cdrom); +void vbd_free(struct vbd *vbd); + +unsigned long long vbd_size(struct vbd *vbd); +unsigned int vbd_info(struct vbd *vbd); +unsigned long vbd_secsize(struct vbd *vbd); + +struct phys_req { + unsigned short dev; + unsigned short nr_sects; + struct block_device *bdev; + blkif_sector_t sector_number; +}; + +int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); + +void blkif_interface_init(void); + +void blkif_xenbus_init(void); + +irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs); +int blkif_schedule(void *arg); + +int blkback_barrier(struct xenbus_transaction xbt, + struct backend_info *be, int state); + +#endif /* __BLKIF__BACKEND__COMMON_H__ */ diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c new file mode 100644 index 000000000000..81821bdc7ef1 --- /dev/null +++ b/drivers/xen/blkback/interface.c @@ -0,0 +1,181 @@ +/****************************************************************************** + * arch/xen/drivers/blkif/backend/interface.c + * + * Block-device interface management. + * + * Copyright (c) 2004, Keir Fraser + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "common.h" +#include +#include + +static kmem_cache_t *blkif_cachep; + +blkif_t *blkif_alloc(domid_t domid) +{ + blkif_t *blkif; + + blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL); + if (!blkif) + return ERR_PTR(-ENOMEM); + + memset(blkif, 0, sizeof(*blkif)); + blkif->domid = domid; + spin_lock_init(&blkif->blk_ring_lock); + atomic_set(&blkif->refcnt, 1); + init_waitqueue_head(&blkif->wq); + blkif->st_print = jiffies; + init_waitqueue_head(&blkif->waiting_to_free); + + return blkif; +} + +static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) +{ + struct gnttab_map_grant_ref op; + + gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr, + GNTMAP_host_map, shared_page, blkif->domid); + + if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) + BUG(); + + if (op.status) { + DPRINTK(" Grant table operation failure !\n"); + return op.status; + } + + blkif->shmem_ref = shared_page; + blkif->shmem_handle = op.handle; + + return 0; +} + +static void unmap_frontend_page(blkif_t *blkif) +{ + struct gnttab_unmap_grant_ref op; + + gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr, + GNTMAP_host_map, blkif->shmem_handle); + + if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) + BUG(); +} + +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) +{ + int err; + + /* Already connected through? */ + if (blkif->irq) + return 0; + + if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL ) + return -ENOMEM; + + err = map_frontend_page(blkif, shared_page); + if (err) { + free_vm_area(blkif->blk_ring_area); + return err; + } + + switch (blkif->blk_protocol) { + case BLKIF_PROTOCOL_NATIVE: + { + blkif_sring_t *sring; + sring = (blkif_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_rings.native, sring, PAGE_SIZE); + break; + } + case BLKIF_PROTOCOL_X86_32: + { + blkif_x86_32_sring_t *sring_x86_32; + sring_x86_32 = (blkif_x86_32_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32, PAGE_SIZE); + break; + } + case BLKIF_PROTOCOL_X86_64: + { + blkif_x86_64_sring_t *sring_x86_64; + sring_x86_64 = (blkif_x86_64_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE); + break; + } + default: + BUG(); + } + + err = bind_interdomain_evtchn_to_irqhandler( + blkif->domid, evtchn, blkif_be_int, 0, "blkif-backend", blkif); + if (err < 0) + { + unmap_frontend_page(blkif); + free_vm_area(blkif->blk_ring_area); + blkif->blk_rings.common.sring = NULL; + return err; + } + blkif->irq = err; + + return 0; +} + +void blkif_disconnect(blkif_t *blkif) +{ + if (blkif->xenblkd) { + kthread_stop(blkif->xenblkd); + blkif->xenblkd = NULL; + } + + atomic_dec(&blkif->refcnt); + wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0); + atomic_inc(&blkif->refcnt); + + if (blkif->irq) { + unbind_from_irqhandler(blkif->irq, blkif); + blkif->irq = 0; + } + + if (blkif->blk_rings.common.sring) { + unmap_frontend_page(blkif); + free_vm_area(blkif->blk_ring_area); + blkif->blk_rings.common.sring = NULL; + } +} + +void blkif_free(blkif_t *blkif) +{ + if (!atomic_dec_and_test(&blkif->refcnt)) + BUG(); + kmem_cache_free(blkif_cachep, blkif); +} + +void __init blkif_interface_init(void) +{ + blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), + 0, 0, NULL, NULL); +} diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c new file mode 100644 index 000000000000..1fb31d0236b4 --- /dev/null +++ b/drivers/xen/blkback/vbd.c @@ -0,0 +1,118 @@ +/****************************************************************************** + * blkback/vbd.c + * + * Routines for managing virtual block devices (VBDs). + * + * Copyright (c) 2003-2005, Keir Fraser & Steve Hand + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "common.h" + +#define vbd_sz(_v) ((_v)->bdev->bd_part ? \ + (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity) + +unsigned long long vbd_size(struct vbd *vbd) +{ + return vbd_sz(vbd); +} + +unsigned int vbd_info(struct vbd *vbd) +{ + return vbd->type | (vbd->readonly?VDISK_READONLY:0); +} + +unsigned long vbd_secsize(struct vbd *vbd) +{ + return bdev_hardsect_size(vbd->bdev); +} + +int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, + unsigned minor, int readonly, int cdrom) +{ + struct vbd *vbd; + struct block_device *bdev; + + vbd = &blkif->vbd; + vbd->handle = handle; + vbd->readonly = readonly; + vbd->type = 0; + + vbd->pdevice = MKDEV(major, minor); + + bdev = open_by_devnum(vbd->pdevice, + vbd->readonly ? FMODE_READ : FMODE_WRITE); + + if (IS_ERR(bdev)) { + DPRINTK("vbd_creat: device %08x could not be opened.\n", + vbd->pdevice); + return -ENOENT; + } + + vbd->bdev = bdev; + + if (vbd->bdev->bd_disk == NULL) { + DPRINTK("vbd_creat: device %08x doesn't exist.\n", + vbd->pdevice); + vbd_free(vbd); + return -ENOENT; + } + + if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom) + vbd->type |= VDISK_CDROM; + if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) + vbd->type |= VDISK_REMOVABLE; + + DPRINTK("Successful creation of handle=%04x (dom=%u)\n", + handle, blkif->domid); + return 0; +} + +void vbd_free(struct vbd *vbd) +{ + if (vbd->bdev) + blkdev_put(vbd->bdev); + vbd->bdev = NULL; +} + +int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) +{ + struct vbd *vbd = &blkif->vbd; + int rc = -EACCES; + + if ((operation != READ) && vbd->readonly) + goto out; + + if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd))) + goto out; + + req->dev = vbd->pdevice; + req->bdev = vbd->bdev; + rc = 0; + + out: + return rc; +} diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c new file mode 100644 index 000000000000..80d9aa6e6ba3 --- /dev/null +++ b/drivers/xen/blkback/xenbus.c @@ -0,0 +1,541 @@ +/* Xenbus code for blkif backend + Copyright (C) 2005 Rusty Russell + Copyright (C) 2005 XenSource 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 + 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 +*/ + +#include +#include +#include +#include "common.h" + +#undef DPRINTK +#define DPRINTK(fmt, args...) \ + pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \ + __FUNCTION__, __LINE__, ##args) + +struct backend_info +{ + struct xenbus_device *dev; + blkif_t *blkif; + struct xenbus_watch backend_watch; + unsigned major; + unsigned minor; + char *mode; +}; + +static void connect(struct backend_info *); +static int connect_ring(struct backend_info *); +static void backend_changed(struct xenbus_watch *, const char **, + unsigned int); + +static int blkback_name(blkif_t *blkif, char *buf) +{ + char *devpath, *devname; + struct xenbus_device *dev = blkif->be->dev; + + devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL); + if (IS_ERR(devpath)) + return PTR_ERR(devpath); + + if ((devname = strstr(devpath, "/dev/")) != NULL) + devname += strlen("/dev/"); + else + devname = devpath; + + snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname); + kfree(devpath); + + return 0; +} + +static void update_blkif_status(blkif_t *blkif) +{ + int err; + char name[TASK_COMM_LEN]; + + /* Not ready to connect? */ + if (!blkif->irq || !blkif->vbd.bdev) + return; + + /* Already connected? */ + if (blkif->be->dev->state == XenbusStateConnected) + return; + + /* Attempt to connect: exit if we fail to. */ + connect(blkif->be); + if (blkif->be->dev->state != XenbusStateConnected) + return; + + err = blkback_name(blkif, name); + if (err) { + xenbus_dev_error(blkif->be->dev, err, "get blkback dev name"); + return; + } + + blkif->xenblkd = kthread_run(blkif_schedule, blkif, name); + if (IS_ERR(blkif->xenblkd)) { + err = PTR_ERR(blkif->xenblkd); + blkif->xenblkd = NULL; + xenbus_dev_error(blkif->be->dev, err, "start xenblkd"); + } +} + + +/**************************************************************** + * sysfs interface for VBD I/O requests + */ + +#define VBD_SHOW(name, format, args...) \ + static ssize_t show_##name(struct device *_dev, \ + struct device_attribute *attr, \ + char *buf) \ + { \ + struct xenbus_device *dev = to_xenbus_device(_dev); \ + struct backend_info *be = dev->dev.driver_data; \ + \ + return sprintf(buf, format, ##args); \ + } \ + static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) + +VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req); +VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req); +VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req); +VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req); +VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect); +VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect); + +static struct attribute *vbdstat_attrs[] = { + &dev_attr_oo_req.attr, + &dev_attr_rd_req.attr, + &dev_attr_wr_req.attr, + &dev_attr_br_req.attr, + &dev_attr_rd_sect.attr, + &dev_attr_wr_sect.attr, + NULL +}; + +static struct attribute_group vbdstat_group = { + .name = "statistics", + .attrs = vbdstat_attrs, +}; + +VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); +VBD_SHOW(mode, "%s\n", be->mode); + +int xenvbd_sysfs_addif(struct xenbus_device *dev) +{ + int error; + + error = device_create_file(&dev->dev, &dev_attr_physical_device); + if (error) + goto fail1; + + error = device_create_file(&dev->dev, &dev_attr_mode); + if (error) + goto fail2; + + error = sysfs_create_group(&dev->dev.kobj, &vbdstat_group); + if (error) + goto fail3; + + return 0; + +fail3: sysfs_remove_group(&dev->dev.kobj, &vbdstat_group); +fail2: device_remove_file(&dev->dev, &dev_attr_mode); +fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); + return error; +} + +void xenvbd_sysfs_delif(struct xenbus_device *dev) +{ + sysfs_remove_group(&dev->dev.kobj, &vbdstat_group); + device_remove_file(&dev->dev, &dev_attr_mode); + device_remove_file(&dev->dev, &dev_attr_physical_device); +} + +static int blkback_remove(struct xenbus_device *dev) +{ + struct backend_info *be = dev->dev.driver_data; + + DPRINTK(""); + + if (be->major || be->minor) + xenvbd_sysfs_delif(dev); + + if (be->backend_watch.node) { + unregister_xenbus_watch(&be->backend_watch); + kfree(be->backend_watch.node); + be->backend_watch.node = NULL; + } + + if (be->blkif) { + blkif_disconnect(be->blkif); + vbd_free(&be->blkif->vbd); + blkif_free(be->blkif); + be->blkif = NULL; + } + + kfree(be); + dev->dev.driver_data = NULL; + return 0; +} + +int blkback_barrier(struct xenbus_transaction xbt, + struct backend_info *be, int state) +{ + struct xenbus_device *dev = be->dev; + int err; + + err = xenbus_printf(xbt, dev->nodename, "feature-barrier", + "%d", state); + if (err) + xenbus_dev_fatal(dev, err, "writing feature-barrier"); + + return err; +} + +/** + * Entry point to this code when a new device is created. Allocate the basic + * structures, and watch the store waiting for the hotplug scripts to tell us + * the device's physical major and minor numbers. Switch to InitWait. + */ +static int blkback_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + int err; + struct backend_info *be = kzalloc(sizeof(struct backend_info), + GFP_KERNEL); + if (!be) { + xenbus_dev_fatal(dev, -ENOMEM, + "allocating backend structure"); + return -ENOMEM; + } + be->dev = dev; + dev->dev.driver_data = be; + + be->blkif = blkif_alloc(dev->otherend_id); + if (IS_ERR(be->blkif)) { + err = PTR_ERR(be->blkif); + be->blkif = NULL; + xenbus_dev_fatal(dev, err, "creating block interface"); + goto fail; + } + + /* setup back pointer */ + be->blkif->be = be; + + err = xenbus_watch_path2(dev, dev->nodename, "physical-device", + &be->backend_watch, backend_changed); + if (err) + goto fail; + + err = xenbus_switch_state(dev, XenbusStateInitWait); + if (err) + goto fail; + + return 0; + +fail: + DPRINTK("failed"); + blkback_remove(dev); + return err; +} + + +/** + * Callback received when the hotplug scripts have placed the physical-device + * node. Read it and the mode node, and create a vbd. If the frontend is + * ready, connect. + */ +static void backend_changed(struct xenbus_watch *watch, + const char **vec, unsigned int len) +{ + int err; + unsigned major; + unsigned minor; + struct backend_info *be + = container_of(watch, struct backend_info, backend_watch); + struct xenbus_device *dev = be->dev; + int cdrom = 0; + char *device_type; + + DPRINTK(""); + + err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x", + &major, &minor); + if (XENBUS_EXIST_ERR(err)) { + /* Since this watch will fire once immediately after it is + registered, we expect this. Ignore it, and wait for the + hotplug scripts. */ + return; + } + if (err != 2) { + xenbus_dev_fatal(dev, err, "reading physical-device"); + return; + } + + if ((be->major || be->minor) && + ((be->major != major) || (be->minor != minor))) { + printk(KERN_WARNING + "blkback: changing physical device (from %x:%x to " + "%x:%x) not supported.\n", be->major, be->minor, + major, minor); + return; + } + + be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL); + if (IS_ERR(be->mode)) { + err = PTR_ERR(be->mode); + be->mode = NULL; + xenbus_dev_fatal(dev, err, "reading mode"); + return; + } + + device_type = xenbus_read(XBT_NIL, dev->otherend, "device-type", NULL); + if (!IS_ERR(device_type)) { + cdrom = strcmp(device_type, "cdrom") == 0; + kfree(device_type); + } + + if (be->major == 0 && be->minor == 0) { + /* Front end dir is a number, which is used as the handle. */ + + char *p = strrchr(dev->otherend, '/') + 1; + long handle = simple_strtoul(p, NULL, 0); + + be->major = major; + be->minor = minor; + + err = vbd_create(be->blkif, handle, major, minor, + (NULL == strchr(be->mode, 'w')), cdrom); + if (err) { + be->major = be->minor = 0; + xenbus_dev_fatal(dev, err, "creating vbd structure"); + return; + } + + err = xenvbd_sysfs_addif(dev); + if (err) { + vbd_free(&be->blkif->vbd); + be->major = be->minor = 0; + xenbus_dev_fatal(dev, err, "creating sysfs entries"); + return; + } + + /* We're potentially connected now */ + update_blkif_status(be->blkif); + } +} + + +/** + * Callback received when the frontend's state changes. + */ +static void frontend_changed(struct xenbus_device *dev, + enum xenbus_state frontend_state) +{ + struct backend_info *be = dev->dev.driver_data; + int err; + + DPRINTK("%s", xenbus_strstate(frontend_state)); + + switch (frontend_state) { + case XenbusStateInitialising: + if (dev->state == XenbusStateClosed) { + printk(KERN_INFO "%s: %s: prepare for reconnect\n", + __FUNCTION__, dev->nodename); + xenbus_switch_state(dev, XenbusStateInitWait); + } + break; + + case XenbusStateInitialised: + case XenbusStateConnected: + /* Ensure we connect even when two watches fire in + close successsion and we miss the intermediate value + of frontend_state. */ + if (dev->state == XenbusStateConnected) + break; + + err = connect_ring(be); + if (err) + break; + update_blkif_status(be->blkif); + break; + + case XenbusStateClosing: + blkif_disconnect(be->blkif); + xenbus_switch_state(dev, XenbusStateClosing); + break; + + case XenbusStateClosed: + xenbus_switch_state(dev, XenbusStateClosed); + if (xenbus_dev_is_online(dev)) + break; + /* fall through if not online */ + case XenbusStateUnknown: + device_unregister(&dev->dev); + break; + + default: + xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend", + frontend_state); + break; + } +} + + +/* ** Connection ** */ + + +/** + * Write the physical details regarding the block device to the store, and + * switch to Connected state. + */ +static void connect(struct backend_info *be) +{ + struct xenbus_transaction xbt; + int err; + struct xenbus_device *dev = be->dev; + + DPRINTK("%s", dev->otherend); + + /* Supply the information about the device the frontend needs */ +again: + err = xenbus_transaction_start(&xbt); + if (err) { + xenbus_dev_fatal(dev, err, "starting transaction"); + return; + } + + err = blkback_barrier(xbt, be, 1); + if (err) + goto abort; + + err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", + vbd_size(&be->blkif->vbd)); + if (err) { + xenbus_dev_fatal(dev, err, "writing %s/sectors", + dev->nodename); + goto abort; + } + + /* FIXME: use a typename instead */ + err = xenbus_printf(xbt, dev->nodename, "info", "%u", + vbd_info(&be->blkif->vbd)); + if (err) { + xenbus_dev_fatal(dev, err, "writing %s/info", + dev->nodename); + goto abort; + } + err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu", + vbd_secsize(&be->blkif->vbd)); + if (err) { + xenbus_dev_fatal(dev, err, "writing %s/sector-size", + dev->nodename); + goto abort; + } + + err = xenbus_transaction_end(xbt, 0); + if (err == -EAGAIN) + goto again; + if (err) + xenbus_dev_fatal(dev, err, "ending transaction"); + + err = xenbus_switch_state(dev, XenbusStateConnected); + if (err) + xenbus_dev_fatal(dev, err, "switching to Connected state", + dev->nodename); + + return; + abort: + xenbus_transaction_end(xbt, 1); +} + + +static int connect_ring(struct backend_info *be) +{ + struct xenbus_device *dev = be->dev; + unsigned long ring_ref; + unsigned int evtchn; + char protocol[64] = ""; + int err; + + DPRINTK("%s", dev->otherend); + + err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref, + "event-channel", "%u", &evtchn, NULL); + if (err) { + xenbus_dev_fatal(dev, err, + "reading %s/ring-ref and event-channel", + dev->otherend); + return err; + } + + be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; + err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", + "%63s", protocol, NULL); + if (err) + strcpy(protocol, "unspecified, assuming native"); + else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) + be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; + else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) + be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32; + else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64)) + be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64; + else { + xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol); + return -1; + } + printk(KERN_INFO + "blkback: ring-ref %ld, event-channel %d, protocol %d (%s)\n", + ring_ref, evtchn, be->blkif->blk_protocol, protocol); + + /* Map the shared frame, irq etc. */ + err = blkif_map(be->blkif, ring_ref, evtchn); + if (err) { + xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u", + ring_ref, evtchn); + return err; + } + + return 0; +} + + +/* ** Driver Registration ** */ + + +static const struct xenbus_device_id blkback_ids[] = { + { "vbd" }, + { "" } +}; + + +static struct xenbus_driver blkback = { + .name = "vbd", + .owner = THIS_MODULE, + .ids = blkback_ids, + .probe = blkback_probe, + .remove = blkback_remove, + .otherend_changed = frontend_changed +}; + + +void blkif_xenbus_init(void) +{ + xenbus_register_backend(&blkback); +} diff --git a/include/xen/blkif.h b/include/xen/blkif.h new file mode 100644 index 000000000000..3d56b75de909 --- /dev/null +++ b/include/xen/blkif.h @@ -0,0 +1,123 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __XEN_BLKIF_H__ +#define __XEN_BLKIF_H__ + +#include +#include +#include + +/* Not a real protocol. Used to generate ring structs which contain + * the elements common to all protocols only. This way we get a + * compiler-checkable way to use common struct elements, so we can + * avoid using switch(protocol) in a number of places. */ +struct blkif_common_request { + char dummy; +}; +struct blkif_common_response { + char dummy; +}; + +/* i386 protocol version */ +#pragma pack(push, 4) +struct blkif_x86_32_request { + uint8_t operation; /* BLKIF_OP_??? */ + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ + uint64_t id; /* private guest value, echoed in resp */ + blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ + struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; +}; +struct blkif_x86_32_response { + uint64_t id; /* copied from request */ + uint8_t operation; /* copied from request */ + int16_t status; /* BLKIF_RSP_??? */ +}; +typedef struct blkif_x86_32_request blkif_x86_32_request_t; +typedef struct blkif_x86_32_response blkif_x86_32_response_t; +#pragma pack(pop) + +/* x86_64 protocol version */ +struct blkif_x86_64_request { + uint8_t operation; /* BLKIF_OP_??? */ + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ + uint64_t __attribute__((__aligned__(8))) id; + blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ + struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; +}; +struct blkif_x86_64_response { + uint64_t __attribute__((__aligned__(8))) id; + uint8_t operation; /* copied from request */ + int16_t status; /* BLKIF_RSP_??? */ +}; +typedef struct blkif_x86_64_request blkif_x86_64_request_t; +typedef struct blkif_x86_64_response blkif_x86_64_response_t; + +DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, struct blkif_common_response); +DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, struct blkif_x86_32_response); +DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, struct blkif_x86_64_response); + +union blkif_back_rings { + blkif_back_ring_t native; + blkif_common_back_ring_t common; + blkif_x86_32_back_ring_t x86_32; + blkif_x86_64_back_ring_t x86_64; +}; +typedef union blkif_back_rings blkif_back_rings_t; + +enum blkif_protocol { + BLKIF_PROTOCOL_NATIVE = 1, + BLKIF_PROTOCOL_X86_32 = 2, + BLKIF_PROTOCOL_X86_64 = 3, +}; + +static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src) +{ + int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; + dst->operation = src->operation; + dst->nr_segments = src->nr_segments; + dst->handle = src->handle; + dst->id = src->id; + dst->sector_number = src->sector_number; + barrier(); + if (n > dst->nr_segments) + n = dst->nr_segments; + for (i = 0; i < n; i++) + dst->seg[i] = src->seg[i]; +} + +static void inline blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src) +{ + int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; + dst->operation = src->operation; + dst->nr_segments = src->nr_segments; + dst->handle = src->handle; + dst->id = src->id; + dst->sector_number = src->sector_number; + barrier(); + if (n > dst->nr_segments) + n = dst->nr_segments; + for (i = 0; i < n; i++) + dst->seg[i] = src->seg[i]; +} + +#endif /* __XEN_BLKIF_H__ */ -- GitLab From 8812293323a79134e06c3bf82eba1e217d23382e Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 9 Feb 2009 12:05:51 -0800 Subject: [PATCH 0969/5560] xen-blkback-porting --- drivers/xen/blkback/blkback.c | 30 ++++++++++++++++-------------- drivers/xen/blkback/common.h | 9 ++++----- drivers/xen/blkback/interface.c | 19 ++++++++++--------- drivers/xen/blkback/vbd.c | 4 ++-- drivers/xen/blkback/xenbus.c | 7 ++++--- include/xen/blkif.h | 13 ++++++------- 6 files changed, 42 insertions(+), 40 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 5b8d50e344b4..43fd07091d4d 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -39,8 +39,12 @@ #include #include #include +#include #include -#include +#include +#include +#include +#include #include "common.h" /* @@ -106,7 +110,7 @@ static inline unsigned long vaddr(pending_req_t *req, int seg) static int do_block_io_op(blkif_t *blkif); static void dispatch_rw_block_io(blkif_t *blkif, - blkif_request_t *req, + struct blkif_request *req, pending_req_t *pending_req); static void make_response(blkif_t *blkif, u64 id, unsigned short op, int st); @@ -153,7 +157,7 @@ static void unplug_queue(blkif_t *blkif) static void plug_queue(blkif_t *blkif, struct block_device *bdev) { - request_queue_t *q = bdev_get_queue(bdev); + struct request_queue *q = bdev_get_queue(bdev); if (q == blkif->plug) return; @@ -268,13 +272,10 @@ static void __end_block_io_op(pending_req_t *pending_req, int error) } } -static int end_block_io_op(struct bio *bio, unsigned int done, int error) +static void end_block_io_op(struct bio *bio, int error) { - if (bio->bi_size != 0) - return 1; __end_block_io_op(bio->bi_private, error); bio_put(bio); - return error; } @@ -288,7 +289,7 @@ static void blkif_notify_work(blkif_t *blkif) wake_up(&blkif->wq); } -irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t blkif_be_int(int irq, void *dev_id) { blkif_notify_work(dev_id); return IRQ_HANDLED; @@ -302,8 +303,8 @@ irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs) static int do_block_io_op(blkif_t *blkif) { - blkif_back_rings_t *blk_rings = &blkif->blk_rings; - blkif_request_t req; + union blkif_back_rings *blk_rings = &blkif->blk_rings; + struct blkif_request req; pending_req_t *pending_req; RING_IDX rc, rp; int more_to_do = 0; @@ -379,7 +380,7 @@ static int do_block_io_op(blkif_t *blkif) } static void dispatch_rw_block_io(blkif_t *blkif, - blkif_request_t *req, + struct blkif_request *req, pending_req_t *pending_req) { extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); @@ -560,9 +561,9 @@ static void dispatch_rw_block_io(blkif_t *blkif, static void make_response(blkif_t *blkif, u64 id, unsigned short op, int st) { - blkif_response_t resp; + struct blkif_response resp; unsigned long flags; - blkif_back_rings_t *blk_rings = &blkif->blk_rings; + union blkif_back_rings *blk_rings = &blkif->blk_rings; int more_to_do = 0; int notify; @@ -614,7 +615,8 @@ static int __init blkif_init(void) { int i, mmap_pages; - if (!is_running_on_xen()) + printk(KERN_CRIT "***blkif_init\n"); + if (!xen_pv_domain()) return -ENODEV; mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index 422e935528be..1c422b00974e 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -40,8 +40,7 @@ #include #include #include -#include -#include +#include #include #define DPRINTK(_f, _a...) \ @@ -66,7 +65,7 @@ typedef struct blkif_st { unsigned int irq; /* Comms information. */ enum blkif_protocol blk_protocol; - blkif_back_rings_t blk_rings; + union blkif_back_rings blk_rings; struct vm_struct *blk_ring_area; /* The VBD attached to this interface. */ struct vbd vbd; @@ -79,7 +78,7 @@ typedef struct blkif_st { wait_queue_head_t wq; struct task_struct *xenblkd; unsigned int waiting_reqs; - request_queue_t *plug; + struct request_queue *plug; /* statistics */ unsigned long st_print; @@ -130,7 +129,7 @@ void blkif_interface_init(void); void blkif_xenbus_init(void); -irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs); +irqreturn_t blkif_be_int(int irq, void *dev_id); int blkif_schedule(void *arg); int blkback_barrier(struct xenbus_transaction xbt, diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c index 81821bdc7ef1..c6c3e14776b9 100644 --- a/drivers/xen/blkback/interface.c +++ b/drivers/xen/blkback/interface.c @@ -31,10 +31,11 @@ */ #include "common.h" -#include +#include +#include #include -static kmem_cache_t *blkif_cachep; +static struct kmem_cache *blkif_cachep; blkif_t *blkif_alloc(domid_t domid) { @@ -107,22 +108,22 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) switch (blkif->blk_protocol) { case BLKIF_PROTOCOL_NATIVE: { - blkif_sring_t *sring; - sring = (blkif_sring_t *)blkif->blk_ring_area->addr; + struct blkif_sring *sring; + sring = (struct blkif_sring *)blkif->blk_ring_area->addr; BACK_RING_INIT(&blkif->blk_rings.native, sring, PAGE_SIZE); break; } case BLKIF_PROTOCOL_X86_32: { - blkif_x86_32_sring_t *sring_x86_32; - sring_x86_32 = (blkif_x86_32_sring_t *)blkif->blk_ring_area->addr; + struct blkif_x86_32_sring *sring_x86_32; + sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring_area->addr; BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32, PAGE_SIZE); break; } case BLKIF_PROTOCOL_X86_64: { - blkif_x86_64_sring_t *sring_x86_64; - sring_x86_64 = (blkif_x86_64_sring_t *)blkif->blk_ring_area->addr; + struct blkif_x86_64_sring *sring_x86_64; + sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring_area->addr; BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE); break; } @@ -177,5 +178,5 @@ void blkif_free(blkif_t *blkif) void __init blkif_interface_init(void) { blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), - 0, 0, NULL, NULL); + 0, 0, NULL); } diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 1fb31d0236b4..7e9a1cd35ade 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -33,7 +33,7 @@ #include "common.h" #define vbd_sz(_v) ((_v)->bdev->bd_part ? \ - (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity) + (_v)->bdev->bd_part->nr_sects : get_capacity((_v)->bdev->bd_disk)) unsigned long long vbd_size(struct vbd *vbd) { @@ -94,7 +94,7 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, void vbd_free(struct vbd *vbd) { if (vbd->bdev) - blkdev_put(vbd->bdev); + blkdev_put(vbd->bdev, vbd->readonly ? FMODE_READ : FMODE_WRITE); vbd->bdev = NULL; } diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 80d9aa6e6ba3..650f4b3e9b3c 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -238,8 +238,8 @@ static int blkback_probe(struct xenbus_device *dev, /* setup back pointer */ be->blkif->be = be; - err = xenbus_watch_path2(dev, dev->nodename, "physical-device", - &be->backend_watch, backend_changed); + err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed, + "%s/%s", dev->nodename, "physical-device"); if (err) goto fail; @@ -537,5 +537,6 @@ static struct xenbus_driver blkback = { void blkif_xenbus_init(void) { - xenbus_register_backend(&blkback); + /* XXX must_check */ + (void)xenbus_register_backend(&blkback); } diff --git a/include/xen/blkif.h b/include/xen/blkif.h index 3d56b75de909..d27428046918 100644 --- a/include/xen/blkif.h +++ b/include/xen/blkif.h @@ -77,12 +77,11 @@ DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, struct blkif_x86_32 DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, struct blkif_x86_64_response); union blkif_back_rings { - blkif_back_ring_t native; - blkif_common_back_ring_t common; - blkif_x86_32_back_ring_t x86_32; - blkif_x86_64_back_ring_t x86_64; + struct blkif_back_ring native; + struct blkif_common_back_ring common; + struct blkif_x86_32_back_ring x86_32; + struct blkif_x86_64_back_ring x86_64; }; -typedef union blkif_back_rings blkif_back_rings_t; enum blkif_protocol { BLKIF_PROTOCOL_NATIVE = 1, @@ -90,7 +89,7 @@ enum blkif_protocol { BLKIF_PROTOCOL_X86_64 = 3, }; -static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src) +static void inline blkif_get_x86_32_req(struct blkif_request *dst, struct blkif_x86_32_request *src) { int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; dst->operation = src->operation; @@ -105,7 +104,7 @@ static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque dst->seg[i] = src->seg[i]; } -static void inline blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src) +static void inline blkif_get_x86_64_req(struct blkif_request *dst, struct blkif_x86_64_request *src) { int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST; dst->operation = src->operation; -- GitLab From dd3672424caa7b302433635831afbb6787476b96 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 9 Feb 2009 16:39:58 -0800 Subject: [PATCH 0970/5560] xen/blkback: don't include xen/evtchn.h It's a user-mode header for users of /dev/evtchn Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index 1c422b00974e..57b78250cfb7 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include -- GitLab From 8270b45bc8a45eef4a224bd256bd0997d4fd857e Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 6 Mar 2009 08:29:15 +0000 Subject: [PATCH 0971/5560] blkback: Fix potential resource leak. --- drivers/xen/blkback/blkback.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 43fd07091d4d..8d988f4513aa 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -318,14 +318,14 @@ static int do_block_io_op(blkif_t *blkif) if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) break; - pending_req = alloc_req(); - if (NULL == pending_req) { - blkif->st_oo_req++; + if (kthread_should_stop()) { more_to_do = 1; break; } - if (kthread_should_stop()) { + pending_req = alloc_req(); + if (NULL == pending_req) { + blkif->st_oo_req++; more_to_do = 1; break; } -- GitLab From 690f1b63b2db88330834d8482f3b125990c8e609 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sat, 21 Mar 2009 23:34:19 -0700 Subject: [PATCH 0972/5560] block: export blk_get/put_queue for blkback Impact: build fix I'm not sure if blkback should be using these functions, but in the meantime export them to allow blkback to be a module. Signed-off-by: Jeremy Fitzhardinge --- block/blk-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/blk-core.c b/block/blk-core.c index 90f22cc30799..9b60e69a5400 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -351,6 +351,7 @@ void blk_put_queue(struct request_queue *q) { kobject_put(&q->kobj); } +EXPORT_SYMBOL_GPL(blk_put_queue); /* * Note: If a driver supplied the queue lock, it should not zap that lock @@ -572,6 +573,7 @@ int blk_get_queue(struct request_queue *q) return 1; } +EXPORT_SYMBOL_GPL(blk_get_queue); static inline void blk_free_request(struct request_queue *q, struct request *rq) { -- GitLab From 05d43865ddc00bdb33d12c8e9d9f176ed5d3797b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 29 Jun 2009 14:58:45 -0700 Subject: [PATCH 0973/5560] xen/blkback: deal with hardsect_size to logical_block_size rename Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/blkback.c | 2 +- drivers/xen/blkback/vbd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 8d988f4513aa..ac5af91c393f 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -484,7 +484,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, for (i = 0; i < nseg; i++) { if (((int)preq.sector_number|(int)seg[i].nsec) & - ((bdev_hardsect_size(preq.bdev) >> 9) - 1)) { + ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) { DPRINTK("Misaligned I/O request from domain %d", blkif->domid); goto fail_put_bio; diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 7e9a1cd35ade..410c2eac5ad7 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -47,7 +47,7 @@ unsigned int vbd_info(struct vbd *vbd) unsigned long vbd_secsize(struct vbd *vbd) { - return bdev_hardsect_size(vbd->bdev); + return bdev_logical_block_size(vbd->bdev); } int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, -- GitLab From 0660c7dbf228a06345392a64ebb43734875a3b91 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 9 Sep 2009 15:15:16 -0700 Subject: [PATCH 0974/5560] xen/blkback: remove spurious debug output noise Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/blkback.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index ac5af91c393f..31458bd07252 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -615,7 +615,6 @@ static int __init blkif_init(void) { int i, mmap_pages; - printk(KERN_CRIT "***blkif_init\n"); if (!xen_pv_domain()) return -ENODEV; -- GitLab From afd91d07ff72919071e37086c0664384b3875688 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 15 Sep 2009 14:12:37 -0700 Subject: [PATCH 0975/5560] xen/blkback: little cleanups Remove unused local prototype; group headers. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/blkback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 31458bd07252..e9e3de119a73 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -40,6 +40,7 @@ #include #include #include + #include #include #include @@ -383,7 +384,6 @@ static void dispatch_rw_block_io(blkif_t *blkif, struct blkif_request *req, pending_req_t *pending_req) { - extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct phys_req preq; struct { -- GitLab From 8770b2683f9f98d4c1d6caf2e28f625592bba4f3 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 8 Oct 2009 13:23:09 -0400 Subject: [PATCH 0976/5560] Fix compile warnings: ignoring return value of 'xenbus_register_backend' .. We neglect to check the return value of xenbus_register_backend and take actions when that fails. This patch fixes that and adds code to deal with those type of failures. Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/blkback.c | 18 +++++++++++++----- drivers/xen/blkback/common.h | 4 ++-- drivers/xen/blkback/interface.c | 6 +++++- drivers/xen/blkback/xenbus.c | 5 ++--- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index e9e3de119a73..a2ac7189cc0a 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -614,6 +614,7 @@ static void make_response(blkif_t *blkif, u64 id, static int __init blkif_init(void) { int i, mmap_pages; + int rc = 0; if (!xen_pv_domain()) return -ENODEV; @@ -626,13 +627,17 @@ static int __init blkif_init(void) mmap_pages, GFP_KERNEL); pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); - if (!pending_reqs || !pending_grant_handles || !pending_pages) + if (!pending_reqs || !pending_grant_handles || !pending_pages) { + rc = -ENOMEM; goto out_of_memory; + } for (i = 0; i < mmap_pages; i++) pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; - blkif_interface_init(); + rc = blkif_interface_init(); + if (rc) + goto failed_init; memset(pending_reqs, 0, sizeof(pending_reqs)); INIT_LIST_HEAD(&pending_free); @@ -640,16 +645,19 @@ static int __init blkif_init(void) for (i = 0; i < blkif_reqs; i++) list_add_tail(&pending_reqs[i].free_list, &pending_free); - blkif_xenbus_init(); + rc = blkif_xenbus_init(); + if (rc) + goto failed_init; return 0; out_of_memory: + printk(KERN_ERR "%s: out of memory\n", __func__); + failed_init: kfree(pending_reqs); kfree(pending_grant_handles); free_empty_pages_and_pagevec(pending_pages, mmap_pages); - printk("%s: out of memory\n", __FUNCTION__); - return -ENOMEM; + return rc; } module_init(blkif_init); diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index 57b78250cfb7..aaf36485bc01 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -124,9 +124,9 @@ struct phys_req { int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); -void blkif_interface_init(void); +int blkif_interface_init(void); -void blkif_xenbus_init(void); +int blkif_xenbus_init(void); irqreturn_t blkif_be_int(int irq, void *dev_id); int blkif_schedule(void *arg); diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c index c6c3e14776b9..e397a4134f1b 100644 --- a/drivers/xen/blkback/interface.c +++ b/drivers/xen/blkback/interface.c @@ -175,8 +175,12 @@ void blkif_free(blkif_t *blkif) kmem_cache_free(blkif_cachep, blkif); } -void __init blkif_interface_init(void) +int __init blkif_interface_init(void) { blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 0, 0, NULL); + if (!blkif_cachep) + return -ENOMEM; + + return 0; } diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 650f4b3e9b3c..04c0a12aff36 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -535,8 +535,7 @@ static struct xenbus_driver blkback = { }; -void blkif_xenbus_init(void) +int blkif_xenbus_init(void) { - /* XXX must_check */ - (void)xenbus_register_backend(&blkback); + return xenbus_register_backend(&blkback); } -- GitLab From e7579a99b598f8e4a2b4df4854fbda2cc961bb02 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 3 Dec 2009 21:56:18 +0000 Subject: [PATCH 0977/5560] xen: rename blkbk module xen-blkback. blkbk is rather generic for a modular distro style kernel. Signed-off-by: Ian Campbell Cc: Jeremy Fitzhardinge Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/blkback/Makefile b/drivers/xen/blkback/Makefile index 8bab63da3b3e..f1ae1ff07a4d 100644 --- a/drivers/xen/blkback/Makefile +++ b/drivers/xen/blkback/Makefile @@ -1,3 +1,3 @@ -obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o +obj-$(CONFIG_XEN_BLKDEV_BACKEND) := xen-blkback.o -blkbk-y := blkback.o xenbus.o interface.o vbd.o +xen-blkback-y := blkback.o xenbus.o interface.o vbd.o -- GitLab From 5cf6e4f6f6d5549904db6ecb3ffd5b8f71f41250 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 11 Feb 2010 16:07:31 -0800 Subject: [PATCH 0978/5560] xen/blkback: use drv_get/set_drvdata rather than directly accessing driver_data. Direct driver_data access is obsolete and will disappear. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/xenbus.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 04c0a12aff36..34f8e4046578 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -105,7 +105,7 @@ static void update_blkif_status(blkif_t *blkif) char *buf) \ { \ struct xenbus_device *dev = to_xenbus_device(_dev); \ - struct backend_info *be = dev->dev.driver_data; \ + struct backend_info *be = dev_get_drvdata(&dev->dev); \ \ return sprintf(buf, format, ##args); \ } \ @@ -169,7 +169,7 @@ void xenvbd_sysfs_delif(struct xenbus_device *dev) static int blkback_remove(struct xenbus_device *dev) { - struct backend_info *be = dev->dev.driver_data; + struct backend_info *be = dev_get_drvdata(&dev->dev); DPRINTK(""); @@ -190,7 +190,7 @@ static int blkback_remove(struct xenbus_device *dev) } kfree(be); - dev->dev.driver_data = NULL; + dev_set_drvdata(&dev->dev, NULL); return 0; } @@ -225,7 +225,7 @@ static int blkback_probe(struct xenbus_device *dev, return -ENOMEM; } be->dev = dev; - dev->dev.driver_data = be; + dev_set_drvdata(&dev->dev, be); be->blkif = blkif_alloc(dev->otherend_id); if (IS_ERR(be->blkif)) { @@ -348,7 +348,7 @@ static void backend_changed(struct xenbus_watch *watch, static void frontend_changed(struct xenbus_device *dev, enum xenbus_state frontend_state) { - struct backend_info *be = dev->dev.driver_data; + struct backend_info *be = dev_get_drvdata(&dev->dev); int err; DPRINTK("%s", xenbus_strstate(frontend_state)); -- GitLab From 2ccbfe26c106a1a93a402567b7853c1484c4a0b0 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 11 Mar 2010 13:39:50 -0800 Subject: [PATCH 0979/5560] xen/blkback: Propagate changed size of VBDs Support dynamic resizing of virtual block devices. This patch supports both file backed block devices as well as physical devices that can be dynamically resized on the host side. Signed-off-by: K. Y. Srinivasan Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/blkback.c | 3 +++ drivers/xen/blkback/common.h | 2 ++ drivers/xen/blkback/vbd.c | 43 +++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index a2ac7189cc0a..6d897664802d 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -207,6 +207,7 @@ static void print_stats(blkif_t *blkif) int blkif_schedule(void *arg) { blkif_t *blkif = arg; + struct vbd *vbd = &blkif->vbd; blkif_get(blkif); @@ -216,6 +217,8 @@ int blkif_schedule(void *arg) while (!kthread_should_stop()) { if (try_to_freeze()) continue; + if (unlikely(vbd->size != vbd_size(vbd))) + vbd_resize(blkif); wait_event_interruptible( blkif->wq, diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index aaf36485bc01..cebcc2b7e9f6 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -52,6 +52,7 @@ struct vbd { unsigned char type; /* VDISK_xxx */ u32 pdevice; /* phys device that this vbd maps to */ struct block_device *bdev; + sector_t size; /* Cached size parameter */ }; struct backend_info; @@ -98,6 +99,7 @@ blkif_t *blkif_alloc(domid_t domid); void blkif_disconnect(blkif_t *blkif); void blkif_free(blkif_t *blkif); int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); +void vbd_resize(blkif_t *blkif); #define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) #define blkif_put(_b) \ diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 410c2eac5ad7..0635c54079f8 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -73,6 +73,7 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, } vbd->bdev = bdev; + vbd->size = vbd_size(vbd); if (vbd->bdev->bd_disk == NULL) { DPRINTK("vbd_creat: device %08x doesn't exist.\n", @@ -116,3 +117,45 @@ int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) out: return rc; } + +void vbd_resize(blkif_t *blkif) +{ + struct vbd *vbd = &blkif->vbd; + struct xenbus_transaction xbt; + int err; + struct xenbus_device *dev = blkif->be->dev; + unsigned long long new_size = vbd_size(vbd); + + printk(KERN_INFO "VBD Resize: new size %Lu\n", new_size); + vbd->size = new_size; +again: + err = xenbus_transaction_start(&xbt); + if (err) { + printk(KERN_WARNING "Error starting transaction"); + return; + } + err = xenbus_printf(xbt, dev->nodename, "sectors", "%Lu", + vbd_size(vbd)); + if (err) { + printk(KERN_WARNING "Error writing new size"); + goto abort; + } + /* + * Write the current state; we will use this to synchronize + * the front-end. If the current state is "connected" the + * front-end will get the new size information online. + */ + err = xenbus_printf(xbt, dev->nodename, "state", "%d", dev->state); + if (err) { + printk(KERN_WARNING "Error writing the state"); + goto abort; + } + + err = xenbus_transaction_end(xbt, 0); + if (err == -EAGAIN) + goto again; + if (err) + printk(KERN_WARNING "Error ending transaction"); +abort: + xenbus_transaction_end(xbt, 1); +} -- GitLab From 98e036a356747cfaa225478b1e4875e190257b09 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 18 Mar 2010 15:35:05 -0700 Subject: [PATCH 0980/5560] xen/blkback: add accessor for xenbus backend device Since backend_info is hidden away now. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/common.h | 2 ++ drivers/xen/blkback/vbd.c | 2 +- drivers/xen/blkback/xenbus.c | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index cebcc2b7e9f6..0f91830f18c8 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -136,4 +136,6 @@ int blkif_schedule(void *arg); int blkback_barrier(struct xenbus_transaction xbt, struct backend_info *be, int state); +struct xenbus_device *blkback_xenbus(struct backend_info *be); + #endif /* __BLKIF__BACKEND__COMMON_H__ */ diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 0635c54079f8..943ec2313522 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -123,7 +123,7 @@ void vbd_resize(blkif_t *blkif) struct vbd *vbd = &blkif->vbd; struct xenbus_transaction xbt; int err; - struct xenbus_device *dev = blkif->be->dev; + struct xenbus_device *dev = blkback_xenbus(blkif->be); unsigned long long new_size = vbd_size(vbd); printk(KERN_INFO "VBD Resize: new size %Lu\n", new_size); diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 34f8e4046578..c31e5c40b45c 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -42,6 +42,11 @@ static int connect_ring(struct backend_info *); static void backend_changed(struct xenbus_watch *, const char **, unsigned int); +struct xenbus_device *blkback_xenbus(struct backend_info *be) +{ + return be->dev; +} + static int blkback_name(blkif_t *blkif, char *buf) { char *devpath, *devname; -- GitLab From cbf462908c8080f47c2a3300072877589dd1275f Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Wed, 21 Jul 2010 12:41:45 -0700 Subject: [PATCH 0981/5560] xen/blkback: Flush blkback data when connecting. First cut at flushing blkback data when first connecting blkback. This should avoid the pygrub issues we are experiencing in (RedHat bugzilla) 466681. [ 2.6.18-xen.hg commit 63b4d7f56688 ] Signed-off-by: Chris Lalancette Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/xenbus.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index c31e5c40b45c..a0534fc6a428 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -91,6 +91,13 @@ static void update_blkif_status(blkif_t *blkif) return; } + err = filemap_write_and_wait(blkif->vbd.bdev->bd_inode->i_mapping); + if (err) { + xenbus_dev_error(blkif->be->dev, err, "block flush"); + return; + } + invalidate_inode_pages2(blkif->vbd.bdev->bd_inode->i_mapping); + blkif->xenblkd = kthread_run(blkif_schedule, blkif, name); if (IS_ERR(blkif->xenblkd)) { err = PTR_ERR(blkif->xenblkd); -- GitLab From a81135d90bf176e6139c352c7b96c03d00131836 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 16 Aug 2010 13:43:06 -0700 Subject: [PATCH 0982/5560] xen/blkback: Print additional information when a vbd is resized. Signed-off-by: K. Y. Srinivasan Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/vbd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 943ec2313522..dc2572338567 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -126,6 +126,8 @@ void vbd_resize(blkif_t *blkif) struct xenbus_device *dev = blkback_xenbus(blkif->be); unsigned long long new_size = vbd_size(vbd); + printk(KERN_INFO "VBD Resize: Domid: %d, Device: (%d, %d)\n", + blkif->domid, MAJOR(vbd->pdevice), MINOR(vbd->pdevice)); printk(KERN_INFO "VBD Resize: new size %Lu\n", new_size); vbd->size = new_size; again: -- GitLab From 313d7b003ceceb797e8c0d18ab085ed0638b4aff Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 24 Nov 2010 22:08:20 -0800 Subject: [PATCH 0983/5560] blkback: Fix CVE-2010-3699 A guest can cause the backend driver to leak a kernel thread. Such leaked threads hold references to the device, whichmakes the device impossible to tear down. If shut down, the guest remains a zombie domain, the xenwatch process hangs, and most xm commands will stop working. This patch tries to do the following for blkback: - identify/extract idempotent teardown operations, - add/move the invocation of said teardown operation right before we're about to allocate new resources in the Connected states. [ linux-2.6.18-xen.hg 59f097ef181b ] Signed-off-by: Laszlo Ersek Signed-off-by: Keir Fraser Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/blkback/xenbus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index a0534fc6a428..031bc3d7eec3 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -382,6 +382,11 @@ static void frontend_changed(struct xenbus_device *dev, if (dev->state == XenbusStateConnected) break; + /* Enforce precondition before potential leak point. + * blkif_disconnect() is idempotent. + */ + blkif_disconnect(be->blkif); + err = connect_ring(be); if (err) break; @@ -399,6 +404,7 @@ static void frontend_changed(struct xenbus_device *dev, break; /* fall through if not online */ case XenbusStateUnknown: + /* implies blkif_disconnect() via blkback_remove() */ device_unregister(&dev->dev); break; -- GitLab From 248e9f7539f8351cd857d12a74bd52133a3a900f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 24 Feb 2011 17:22:41 -0500 Subject: [PATCH 0984/5560] xen/blkback: Replace WRITE_BARRIER with (REQ_FLUSH | REQ_FUA) TODO: Double check xen-blkfront.c --- drivers/xen/blkback/blkback.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 6d897664802d..cb844f734d91 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -405,7 +405,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, operation = WRITE; break; case BLKIF_OP_WRITE_BARRIER: - operation = WRITE_BARRIER; + operation = REQ_FLUSH | REQ_FUA; break; default: operation = 0; /* make gcc happy */ @@ -414,7 +414,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, /* Check that number of segments is sane. */ nseg = req->nr_segments; - if (unlikely(nseg == 0 && operation != WRITE_BARRIER) || + if (unlikely(nseg == 0 && operation != (REQ_FLUSH | REQ_FUA)) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { DPRINTK("Bad number of segments in request (%d)\n", nseg); goto fail_response; @@ -517,7 +517,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, } if (!bio) { - BUG_ON(operation != WRITE_BARRIER); + BUG_ON(operation != (REQ_FLUSH | REQ_FUA)); bio = bio_alloc(GFP_KERNEL, 0); if (unlikely(bio == NULL)) goto fail_put_bio; @@ -532,7 +532,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, if (operation == READ) blkif->st_rd_sect += preq.nr_sects; - else if (operation == WRITE || operation == WRITE_BARRIER) + else if (operation == WRITE || operation == (REQ_FLUSH | REQ_FUA)) blkif->st_wr_sect += preq.nr_sects; return; -- GitLab From bc0c081b0e7a4afc4d2c7bc0666f5cd169e96814 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 25 Feb 2011 10:02:39 -0500 Subject: [PATCH 0985/5560] xen/blkback: Update to use blkdev_get_by_dev instead of open_by_devnum. The API for opening a block device has changed since 2.6.32. The correct function to open a device is blkdev_get_by_dev. --- drivers/xen/blkback/vbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index dc2572338567..8c91a2fb0019 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -63,8 +63,8 @@ int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, vbd->pdevice = MKDEV(major, minor); - bdev = open_by_devnum(vbd->pdevice, - vbd->readonly ? FMODE_READ : FMODE_WRITE); + bdev = blkdev_get_by_dev(vbd->pdevice, vbd->readonly ? + FMODE_READ : FMODE_WRITE, NULL); if (IS_ERR(bdev)) { DPRINTK("vbd_creat: device %08x could not be opened.\n", -- GitLab From efe08a3eecf15ab022afba48c691d02c7de2fbbb Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 5 Feb 2010 14:19:33 -0500 Subject: [PATCH 0986/5560] xen/blkback: simplify address translations Cherry-pick and modified from 69d64727c42eecd47fdf82c15a54474d21a4012a ("blkback/blktap2: simplify address translations"): "There are quite a number of places where e.g. page->va->page translations happen. Besides yielding smaller code (source and binary), a second goal is to make it easier to determine where virtual addresses of pages allocated through alloc_empty_pages_and_pagevec() are really used (in turn in order to determine whether using highmem pages would be possible there)." The second goal is not the purpose of this patch - it is just to make it easier to read the code. linux-2.6-pvops: * Stripped drivers/xen/gntdev/* * Stripped drivers/xen/netback/* [v2: Stripped blktap off] Signed-off-by: Jan Beulich Signed-off-by: Daniel Stodden Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index cb844f734d91..7c9421cc5991 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -99,9 +99,11 @@ static inline int vaddr_pagenr(pending_req_t *req, int seg) return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; } +#define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)] + static inline unsigned long vaddr(pending_req_t *req, int seg) { - unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]); + unsigned long pfn = page_to_pfn(pending_page(req, seg)); return (unsigned long)pfn_to_kaddr(pfn); } @@ -463,8 +465,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, if (ret) continue; - set_phys_to_machine(__pa(vaddr( - pending_req, i)) >> PAGE_SHIFT, + set_phys_to_machine( + page_to_pfn(pending_page(pending_req, i)), FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); seg[i].buf = map[i].dev_bus_addr | (req->seg[i].first_sect << 9); @@ -495,7 +497,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, while ((bio == NULL) || (bio_add_page(bio, - virt_to_page(vaddr(pending_req, i)), + pending_page(pending_req, i), seg[i].nsec << 9, seg[i].buf & ~PAGE_MASK) == 0)) { if (bio) { -- GitLab From e8e28871edf0d0adb0bd7e597c044cbaf7a7f137 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 25 Feb 2011 10:51:29 -0500 Subject: [PATCH 0987/5560] xen/blkback: Move global/static variables into struct xen_blkbk. Bundle the lot of discrete variables into a single structure. This is based on what was done in the xen-netback driver: xen: netback: Move global/static variables into struct xen_netbk. (094944631cc5a9d6e623302c987f78117c0bf7ac) Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 82 ++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 7c9421cc5991..c08875b0ad64 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -84,31 +84,34 @@ typedef struct { struct list_head free_list; } pending_req_t; -static pending_req_t *pending_reqs; -static struct list_head pending_free; -static DEFINE_SPINLOCK(pending_free_lock); -static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq); - #define BLKBACK_INVALID_HANDLE (~0) -static struct page **pending_pages; -static grant_handle_t *pending_grant_handles; +struct xen_blkbk { + pending_req_t *pending_reqs; + struct list_head pending_free; + spinlock_t pending_free_lock; + wait_queue_head_t pending_free_wq; + struct page **pending_pages; + grant_handle_t *pending_grant_handles; +}; + +static struct xen_blkbk *blkbk; static inline int vaddr_pagenr(pending_req_t *req, int seg) { - return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; + return (req - blkbk->pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; } #define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)] static inline unsigned long vaddr(pending_req_t *req, int seg) { - unsigned long pfn = page_to_pfn(pending_page(req, seg)); + unsigned long pfn = page_to_pfn(blkbk->pending_page(req, seg)); return (unsigned long)pfn_to_kaddr(pfn); } #define pending_handle(_req, _seg) \ - (pending_grant_handles[vaddr_pagenr(_req, _seg)]) + (blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)]) static int do_block_io_op(blkif_t *blkif); @@ -126,12 +129,12 @@ static pending_req_t* alloc_req(void) pending_req_t *req = NULL; unsigned long flags; - spin_lock_irqsave(&pending_free_lock, flags); - if (!list_empty(&pending_free)) { - req = list_entry(pending_free.next, pending_req_t, free_list); + spin_lock_irqsave(&blkbk->pending_free_lock, flags); + if (!list_empty(&blkbk->pending_free)) { + req = list_entry(blkbk->pending_free.next, pending_req_t, free_list); list_del(&req->free_list); } - spin_unlock_irqrestore(&pending_free_lock, flags); + spin_unlock_irqrestore(&blkbk->pending_free_lock, flags); return req; } @@ -140,12 +143,12 @@ static void free_req(pending_req_t *req) unsigned long flags; int was_empty; - spin_lock_irqsave(&pending_free_lock, flags); - was_empty = list_empty(&pending_free); - list_add(&req->free_list, &pending_free); - spin_unlock_irqrestore(&pending_free_lock, flags); + spin_lock_irqsave(&blkbk->pending_free_lock, flags); + was_empty = list_empty(&blkbk->pending_free); + list_add(&req->free_list, &blkbk->pending_free); + spin_unlock_irqrestore(&blkbk->pending_free_lock, flags); if (was_empty) - wake_up(&pending_free_wq); + wake_up(&blkbk->pending_free_wq); } static void unplug_queue(blkif_t *blkif) @@ -226,8 +229,8 @@ int blkif_schedule(void *arg) blkif->wq, blkif->waiting_reqs || kthread_should_stop()); wait_event_interruptible( - pending_free_wq, - !list_empty(&pending_free) || kthread_should_stop()); + blkbk->pending_free_wq, + !list_empty(&blkbk->pending_free) || kthread_should_stop()); blkif->waiting_reqs = 0; smp_mb(); /* clear flag *before* checking for work */ @@ -466,7 +469,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, continue; set_phys_to_machine( - page_to_pfn(pending_page(pending_req, i)), + page_to_pfn(blkbk->pending_page(pending_req, i)), FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); seg[i].buf = map[i].dev_bus_addr | (req->seg[i].first_sect << 9); @@ -497,7 +500,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, while ((bio == NULL) || (bio_add_page(bio, - pending_page(pending_req, i), + blkbk->pending_page(pending_req, i), seg[i].nsec << 9, seg[i].buf & ~PAGE_MASK) == 0)) { if (bio) { @@ -624,31 +627,40 @@ static int __init blkif_init(void) if (!xen_pv_domain()) return -ENODEV; + blkbk = (struct xen_blkbk *)vmalloc(sizeof(struct xen_blkbk)); + if (!blkbk) { + printk(KERN_ALERT "%s: out of memory!\n", __func__); + return -ENOMEM; + } + mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; - pending_reqs = kmalloc(sizeof(pending_reqs[0]) * + blkbk->pending_reqs = kmalloc(sizeof(blkbk->pending_reqs[0]) * blkif_reqs, GFP_KERNEL); - pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * + blkbk->pending_grant_handles = kmalloc(sizeof(blkbk->pending_grant_handles[0]) * mmap_pages, GFP_KERNEL); - pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); + blkbk->pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); - if (!pending_reqs || !pending_grant_handles || !pending_pages) { + if (!blkbk->pending_reqs || !blkbk->pending_grant_handles || !blkbk->pending_pages) { rc = -ENOMEM; goto out_of_memory; } for (i = 0; i < mmap_pages; i++) - pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; + blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; rc = blkif_interface_init(); if (rc) goto failed_init; - memset(pending_reqs, 0, sizeof(pending_reqs)); - INIT_LIST_HEAD(&pending_free); + memset(blkbk->pending_reqs, 0, sizeof(blkbk->pending_reqs)); + + INIT_LIST_HEAD(&blkbk->pending_free); + spin_lock_init(&blkbk->pending_free_lock); + init_waitqueue_head(&blkbk->pending_free_wq); for (i = 0; i < blkif_reqs; i++) - list_add_tail(&pending_reqs[i].free_list, &pending_free); + list_add_tail(&blkbk->pending_reqs[i].free_list, &blkbk->pending_free); rc = blkif_xenbus_init(); if (rc) @@ -659,9 +671,11 @@ static int __init blkif_init(void) out_of_memory: printk(KERN_ERR "%s: out of memory\n", __func__); failed_init: - kfree(pending_reqs); - kfree(pending_grant_handles); - free_empty_pages_and_pagevec(pending_pages, mmap_pages); + kfree(blkbk->pending_reqs); + kfree(blkbk->pending_grant_handles); + free_empty_pages_and_pagevec(blkbk->pending_pages, mmap_pages); + vfree(blkbk); + blkbk = NULL; return rc; } -- GitLab From c35950bfa9abaaf16548a287a8d5d782a361414f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 1 Mar 2011 16:22:28 -0500 Subject: [PATCH 0988/5560] xen/blkback: Union the blkif_request request specific fields Following in the steps of patch: "xen: Union the blkif_request request specific fields" this patch changes the blkback. Per the original patch: "Prepare for extending the block device ring to allow request specific fields, by moving the request specific fields for reads, writes and barrier requests to a union member." Cc: Owen Smith Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 14 +++++++------- include/xen/blkif.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index c08875b0ad64..eda50646775d 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -426,7 +426,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, } preq.dev = req->handle; - preq.sector_number = req->sector_number; + preq.sector_number = req->u.rw.sector_number; preq.nr_sects = 0; pending_req->blkif = blkif; @@ -438,11 +438,11 @@ static void dispatch_rw_block_io(blkif_t *blkif, for (i = 0; i < nseg; i++) { uint32_t flags; - seg[i].nsec = req->seg[i].last_sect - - req->seg[i].first_sect + 1; + seg[i].nsec = req->u.rw.seg[i].last_sect - + req->u.rw.seg[i].first_sect + 1; - if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) || - (req->seg[i].last_sect < req->seg[i].first_sect)) + if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) || + (req->u.rw.seg[i].last_sect < req->u.rw.seg[i].first_sect)) goto fail_response; preq.nr_sects += seg[i].nsec; @@ -450,7 +450,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, if (operation != READ) flags |= GNTMAP_readonly; gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, - req->seg[i].gref, blkif->domid); + req->u.rw.seg[i].gref, blkif->domid); } ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); @@ -472,7 +472,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, page_to_pfn(blkbk->pending_page(pending_req, i)), FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); seg[i].buf = map[i].dev_bus_addr | - (req->seg[i].first_sect << 9); + (req->u.rw.seg[i].first_sect << 9); } if (ret) diff --git a/include/xen/blkif.h b/include/xen/blkif.h index d27428046918..ab794269fc53 100644 --- a/include/xen/blkif.h +++ b/include/xen/blkif.h @@ -96,12 +96,12 @@ static void inline blkif_get_x86_32_req(struct blkif_request *dst, struct blkif_ dst->nr_segments = src->nr_segments; dst->handle = src->handle; dst->id = src->id; - dst->sector_number = src->sector_number; + dst->u.rw.sector_number = src->sector_number; barrier(); if (n > dst->nr_segments) n = dst->nr_segments; for (i = 0; i < n; i++) - dst->seg[i] = src->seg[i]; + dst->u.rw.seg[i] = src->seg[i]; } static void inline blkif_get_x86_64_req(struct blkif_request *dst, struct blkif_x86_64_request *src) @@ -111,12 +111,12 @@ static void inline blkif_get_x86_64_req(struct blkif_request *dst, struct blkif_ dst->nr_segments = src->nr_segments; dst->handle = src->handle; dst->id = src->id; - dst->sector_number = src->sector_number; + dst->u.rw.sector_number = src->sector_number; barrier(); if (n > dst->nr_segments) n = dst->nr_segments; for (i = 0; i < n; i++) - dst->seg[i] = src->seg[i]; + dst->u.rw.seg[i] = src->seg[i]; } #endif /* __XEN_BLKIF_H__ */ -- GitLab From 464fb419e17083a18b636c9f4714fc49ef6857d2 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 1 Mar 2011 16:26:10 -0500 Subject: [PATCH 0989/5560] xen/blkback: Use 'vzalloc' for page arrays and pre-allocate pages. Previously we would allocate the array for page using 'kmalloc' which we can as easily do with 'vzalloc'. The pre-allocation of pages was done a bit differently in the past - it used to be that the balloon driver would export "alloc_empty_pages_and_pagevec" which would have in one function created an array, allocated the pages, balloned the pages out (so the memory behind those pages would be non-present), and provide us those pages. This was OK as those pages were shared between other guest and the only thing we needed was to "swizzel" the MFN of those pages to point to the other guest MFN. We can still "swizzel" the MFNs using the M2P (and P2M) override API calls, but for the sake of simplicity we are dropping the balloon API calls. We can return to those later on. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index eda50646775d..d32198d1be04 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -637,18 +637,23 @@ static int __init blkif_init(void) blkbk->pending_reqs = kmalloc(sizeof(blkbk->pending_reqs[0]) * blkif_reqs, GFP_KERNEL); - blkbk->pending_grant_handles = kmalloc(sizeof(blkbk->pending_grant_handles[0]) * - mmap_pages, GFP_KERNEL); - blkbk->pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); + blkbk->pending_grant_handles = vzalloc(sizeof(blkbk->pending_grant_handles[0]) * + mmap_pages); + blkbk->pending_pages = vzalloc(sizeof(blkbk->pending_pages[0]) * mmap_pages); if (!blkbk->pending_reqs || !blkbk->pending_grant_handles || !blkbk->pending_pages) { rc = -ENOMEM; goto out_of_memory; } - for (i = 0; i < mmap_pages; i++) + for (i = 0; i < mmap_pages; i++) { blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; - + blkbk->pending_pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + if (blkbk->pending_pages[i] == NULL) { + rc = -ENOMEM; + goto out_of_memory; + } + } rc = blkif_interface_init(); if (rc) goto failed_init; @@ -672,8 +677,12 @@ static int __init blkif_init(void) printk(KERN_ERR "%s: out of memory\n", __func__); failed_init: kfree(blkbk->pending_reqs); - kfree(blkbk->pending_grant_handles); - free_empty_pages_and_pagevec(blkbk->pending_pages, mmap_pages); + vfree(blkbk->pending_grant_handles); + for (i = 0; i < mmap_pages; i++) { + if (blkbk->pending_pages[i]) + __free_page(blkbk->pending_pages[i]); + } + vfree(blkbk->pending_pages); vfree(blkbk); blkbk = NULL; return rc; -- GitLab From 5dc03639cc903f887931831d69895facb5260f4b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 1 Mar 2011 16:46:45 -0500 Subject: [PATCH 0990/5560] xen/blkback: Utilize the M2P override mechanism for GNTMAP_host_map Instead of doing copy grants lets do mapping grants using the M2P(and P2M) override mechanism. Signed-off-by: Konrad Rzeszutek Wilk Conflicts: drivers/xen/blkback/blkback.c --- drivers/xen/blkback/blkback.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index d32198d1be04..15790ae96f33 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include @@ -192,6 +191,17 @@ static void fast_flush_area(pending_req_t *req) ret = HYPERVISOR_grant_table_op( GNTTABOP_unmap_grant_ref, unmap, invcount); BUG_ON(ret); + /* Note, we use invcount, so nr->pages, so we can't index + * using vaddr(req, i). */ + for (i = 0; i < invcount; i++) { + ret = m2p_remove_override( + virt_to_page(unmap[i].host_addr), false); + if (ret) { + printk(KERN_ALERT "Failed to remove M2P override for " \ + "%lx\n", (unsigned long)unmap[i].host_addr); + continue; + } + } } /****************************************************************** @@ -467,10 +477,15 @@ static void dispatch_rw_block_io(blkif_t *blkif, if (ret) continue; + + ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), + blkbk->pending_page(pending_req, i), false); + if (ret) { + printk(KERN_ALERT "Failed to install M2P override for"\ + " %lx (ret: %d)\n", (unsigned long)map[i].dev_bus_addr, ret); + continue; + } - set_phys_to_machine( - page_to_pfn(blkbk->pending_page(pending_req, i)), - FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); seg[i].buf = map[i].dev_bus_addr | (req->u.rw.seg[i].first_sect << 9); } -- GitLab From a742b02c75e6e76bd0833f9b6e702f1be7d7e008 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 14 Mar 2011 12:41:26 -0400 Subject: [PATCH 0991/5560] xen/blkback: Use kzalloc's, and GFP_KERNEL for data structures. The patch titled:"xen/blkback: Use 'vzalloc' for page arrays and pre-allocate pages." allocates the structures and its member variables using the 'vzalloc'. Daniel Stodden pointed out that vzalloc is good when we use big number of pages - while these are at the max two pages. We can do this using kzalloc. Also the GFP_HIGHMEM does not work properly with Xen, so take that out. We will have to revisit this when a "get_empty_pages_and_pagevec" type API shows up to leverage that. BugLink: http://mid.gmane.org/1299898639.11681.227.camel@agari.van.xensource.com CC: Daniel Stodden Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 15790ae96f33..a6f8f1338118 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -642,7 +642,7 @@ static int __init blkif_init(void) if (!xen_pv_domain()) return -ENODEV; - blkbk = (struct xen_blkbk *)vmalloc(sizeof(struct xen_blkbk)); + blkbk = (struct xen_blkbk *)kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL); if (!blkbk) { printk(KERN_ALERT "%s: out of memory!\n", __func__); return -ENOMEM; @@ -652,9 +652,10 @@ static int __init blkif_init(void) blkbk->pending_reqs = kmalloc(sizeof(blkbk->pending_reqs[0]) * blkif_reqs, GFP_KERNEL); - blkbk->pending_grant_handles = vzalloc(sizeof(blkbk->pending_grant_handles[0]) * - mmap_pages); - blkbk->pending_pages = vzalloc(sizeof(blkbk->pending_pages[0]) * mmap_pages); + blkbk->pending_grant_handles = kzalloc(sizeof(blkbk->pending_grant_handles[0]) * + mmap_pages, GFP_KERNEL); + blkbk->pending_pages = kzalloc(sizeof(blkbk->pending_pages[0]) * + mmap_pages, GFP_KERNEL); if (!blkbk->pending_reqs || !blkbk->pending_grant_handles || !blkbk->pending_pages) { rc = -ENOMEM; @@ -663,7 +664,7 @@ static int __init blkif_init(void) for (i = 0; i < mmap_pages; i++) { blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; - blkbk->pending_pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + blkbk->pending_pages[i] = alloc_page(GFP_KERNEL); if (blkbk->pending_pages[i] == NULL) { rc = -ENOMEM; goto out_of_memory; @@ -692,13 +693,13 @@ static int __init blkif_init(void) printk(KERN_ERR "%s: out of memory\n", __func__); failed_init: kfree(blkbk->pending_reqs); - vfree(blkbk->pending_grant_handles); + kfree(blkbk->pending_grant_handles); for (i = 0; i < mmap_pages; i++) { if (blkbk->pending_pages[i]) __free_page(blkbk->pending_pages[i]); } - vfree(blkbk->pending_pages); - vfree(blkbk); + kfree(blkbk->pending_pages); + kfree(blkbk); blkbk = NULL; return rc; } -- GitLab From 314146e515710f8a7d7eaf7a58b7ed590c9c14c3 Mon Sep 17 00:00:00 2001 From: Tom Goetz Date: Thu, 17 Mar 2011 12:14:29 -0400 Subject: [PATCH 0992/5560] xen/blkback: Fix the WRITE_BARRIER The WRITE_BARRIER was missing the REQ_WRITE option. This was causing the blktap to die. Signed-off-by: Tom Goetz Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index a6f8f1338118..4cd5b49de0c1 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -47,6 +47,8 @@ #include #include "common.h" +#define WRITE_BARRIER (REQ_WRITE | REQ_FLUSH | REQ_FUA) + /* * These are rather arbitrary. They are fairly large because adjacent requests * pulled from a communication ring are quite likely to end up being part of @@ -420,7 +422,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, operation = WRITE; break; case BLKIF_OP_WRITE_BARRIER: - operation = REQ_FLUSH | REQ_FUA; + operation = WRITE_BARRIER; break; default: operation = 0; /* make gcc happy */ @@ -429,7 +431,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, /* Check that number of segments is sane. */ nseg = req->nr_segments; - if (unlikely(nseg == 0 && operation != (REQ_FLUSH | REQ_FUA)) || + if (unlikely(nseg == 0 && operation != WRITE_BARRIER) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { DPRINTK("Bad number of segments in request (%d)\n", nseg); goto fail_response; @@ -537,7 +539,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, } if (!bio) { - BUG_ON(operation != (REQ_FLUSH | REQ_FUA)); + BUG_ON(operation != WRITE_BARRIER); bio = bio_alloc(GFP_KERNEL, 0); if (unlikely(bio == NULL)) goto fail_put_bio; @@ -552,7 +554,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, if (operation == READ) blkif->st_rd_sect += preq.nr_sects; - else if (operation == WRITE || operation == (REQ_FLUSH | REQ_FUA)) + else if (operation == WRITE || operation == WRITE_BARRIER) blkif->st_wr_sect += preq.nr_sects; return; -- GitLab From a1397fa3090c25c6c51c04b4101f2786d16b615f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:05:23 -0400 Subject: [PATCH 0993/5560] xen/blkback: Add some comments. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 88 ++++++++++++++++++++++++++------- drivers/xen/blkback/common.h | 1 + drivers/xen/blkback/interface.c | 2 - drivers/xen/blkback/vbd.c | 2 - drivers/xen/blkback/xenbus.c | 2 +- 5 files changed, 71 insertions(+), 24 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 4cd5b49de0c1..8a4b1e8eeb62 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -1,11 +1,10 @@ /****************************************************************************** - * arch/xen/drivers/blkif/backend/main.c * * Back-end of the driver for virtual block devices. This portion of the * driver exports a 'unified' block-device interface that can be accessed * by any operating system that implements a compatible front end. A * reference front-end implementation can be found in: - * arch/xen/drivers/blkif/frontend + * drivers/block/xen-blkfront.c * * Copyright (c) 2003-2004, Keir Fraser & Steve Hand * Copyright (c) 2005, Christopher Clark @@ -88,16 +87,25 @@ typedef struct { #define BLKBACK_INVALID_HANDLE (~0) struct xen_blkbk { - pending_req_t *pending_reqs; + pending_req_t *pending_reqs; + /* List of all 'pending_req' available */ struct list_head pending_free; + /* And its spinlock. */ spinlock_t pending_free_lock; wait_queue_head_t pending_free_wq; + /* The list of all pages that are available. */ struct page **pending_pages; + /* And the grant handles that are available. */ grant_handle_t *pending_grant_handles; }; static struct xen_blkbk *blkbk; +/* + * Little helpful macro to figure out the index and virtual address of the + * pending_pages[..]. For each 'pending_req' we have have up to + * BLKIF_MAX_SEGMENTS_PER_REQUEST (11) pages. The seg would be from 0 through + * 10 and would index in the pending_pages[..]. */ static inline int vaddr_pagenr(pending_req_t *req, int seg) { return (req - blkbk->pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; @@ -122,8 +130,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, static void make_response(blkif_t *blkif, u64 id, unsigned short op, int st); -/****************************************************************** - * misc small helpers +/* + * Retrieve from the 'pending_reqs' a free pending_req structure to be used. */ static pending_req_t* alloc_req(void) { @@ -139,6 +147,10 @@ static pending_req_t* alloc_req(void) return req; } +/* + * Return the 'pending_req' structure back to the freepool. We also + * wake up the thread if it was waiting for a free page. + */ static void free_req(pending_req_t *req) { unsigned long flags; @@ -152,6 +164,11 @@ static void free_req(pending_req_t *req) wake_up(&blkbk->pending_free_wq); } +/* + * Give back a reference count on the underlaying storage. + * It is OK to make multiple calls in this function as it + * resets the plug to NULL when it is done on the first call. + */ static void unplug_queue(blkif_t *blkif) { if (blkif->plug == NULL) @@ -162,6 +179,12 @@ static void unplug_queue(blkif_t *blkif) blkif->plug = NULL; } +/* + * Take a reference count on the underlaying storage. + * It is OK to call this multiple times as we check to make sure + * not to double reference. We also give back a reference count + * if it corresponds to another queue. + */ static void plug_queue(blkif_t *blkif, struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); @@ -173,6 +196,10 @@ static void plug_queue(blkif_t *blkif, struct block_device *bdev) blkif->plug = q; } +/* + * Unmap the grant references, and also remove the M2P over-rides + * used in the 'pending_req'. +*/ static void fast_flush_area(pending_req_t *req) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; @@ -266,8 +293,8 @@ int blkif_schedule(void *arg) return 0; } -/****************************************************************** - * COMPLETION CALLBACK -- Called as bh->b_end_io() +/* + * Completion callback on the bio's. Called as bh->b_end_io() */ static void __end_block_io_op(pending_req_t *pending_req, int error) @@ -284,6 +311,9 @@ static void __end_block_io_op(pending_req_t *pending_req, int error) pending_req->status = BLKIF_RSP_ERROR; } + /* If all of the bio's have completed it is time to unmap + * the grant references associated with 'request' and provide + * the proper response on the ring. */ if (atomic_dec_and_test(&pending_req->pendcnt)) { fast_flush_area(pending_req); make_response(pending_req->blkif, pending_req->id, @@ -293,6 +323,9 @@ static void __end_block_io_op(pending_req_t *pending_req, int error) } } +/* + * bio callback. + */ static void end_block_io_op(struct bio *bio, int error) { __end_block_io_op(bio->bi_private, error); @@ -300,8 +333,8 @@ static void end_block_io_op(struct bio *bio, int error) } -/****************************************************************************** - * NOTIFICATION FROM GUEST OS. +/* + * Notification from the guest OS. */ static void blkif_notify_work(blkif_t *blkif) @@ -318,10 +351,11 @@ irqreturn_t blkif_be_int(int irq, void *dev_id) -/****************************************************************** - * DOWNWARD CALLS -- These interface with the block-device layer proper. +/* + * Function to copy the from the ring buffer the 'struct blkif_request' + * (which has the sectors we want, number of them, grant references, etc), + * and transmute it to the block API to hand it over to the proper block disk. */ - static int do_block_io_op(blkif_t *blkif) { union blkif_back_rings *blk_rings = &blkif->blk_rings; @@ -400,6 +434,10 @@ static int do_block_io_op(blkif_t *blkif) return more_to_do; } +/* + * Transumation of the 'struct blkif_request' to a proper 'struct bio' + * and call the 'submit_bio' to pass it to the underlaying storage. + */ static void dispatch_rw_block_io(blkif_t *blkif, struct blkif_request *req, pending_req_t *pending_req) @@ -429,7 +467,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, BUG(); } - /* Check that number of segments is sane. */ + /* Check that the number of segments is sane. */ nseg = req->nr_segments; if (unlikely(nseg == 0 && operation != WRITE_BARRIER) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { @@ -447,12 +485,14 @@ static void dispatch_rw_block_io(blkif_t *blkif, pending_req->status = BLKIF_RSP_OKAY; pending_req->nr_pages = nseg; + /* Fill out preq.nr_sects with proper amount of sectors, and setup + * assign map[..] with the PFN of the page in our domain with the + * corresponding grant reference for each page.*/ for (i = 0; i < nseg; i++) { uint32_t flags; seg[i].nsec = req->u.rw.seg[i].last_sect - req->u.rw.seg[i].first_sect + 1; - if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) || (req->u.rw.seg[i].last_sect < req->u.rw.seg[i].first_sect)) goto fail_response; @@ -468,6 +508,9 @@ static void dispatch_rw_block_io(blkif_t *blkif, ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); BUG_ON(ret); + /* Now swizzel the MFN in our domain with the MFN from the other domain + * so that when we access vaddr(pending_req,i) it has the contents of the + * page from the other domain. */ for (i = 0; i < nseg; i++) { if (unlikely(map[i].status != 0)) { DPRINTK("invalid buffer -- could not remap it\n"); @@ -485,6 +528,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, if (ret) { printk(KERN_ALERT "Failed to install M2P override for"\ " %lx (ret: %d)\n", (unsigned long)map[i].dev_bus_addr, ret); + /* We could switch over to GNTTABOP_copy */ continue; } @@ -492,6 +536,9 @@ static void dispatch_rw_block_io(blkif_t *blkif, (req->u.rw.seg[i].first_sect << 9); } + /* If we have failed at this point, we need to undo the M2P override, set + * gnttab_set_unmap_op on all of the grant references and perform the + * hypercall to unmap the grants - that is all done in fast_flush_area. */ if (ret) goto fail_flush; @@ -503,7 +550,11 @@ static void dispatch_rw_block_io(blkif_t *blkif, goto fail_flush; } + /* Get a reference count for the disk queue and start sending I/O */ plug_queue(blkif, preq.bdev); + + /* We set it one so that the last submit_bio does not have to call + * atomic_inc. */ atomic_set(&pending_req->pendcnt, 1); blkif_get(blkif); @@ -524,7 +575,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, atomic_inc(&pending_req->pendcnt); submit_bio(operation, bio); } - + bio = bio_alloc(GFP_KERNEL, nseg-i); if (unlikely(bio == NULL)) goto fail_put_bio; @@ -538,6 +589,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, preq.sector_number += seg[i].nsec; } + /* This will be hit if the operation was a barrier. */ if (!bio) { BUG_ON(operation != WRITE_BARRIER); bio = bio_alloc(GFP_KERNEL, 0); @@ -578,11 +630,9 @@ static void dispatch_rw_block_io(blkif_t *blkif, -/****************************************************************** - * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING +/* + * Put a response on the ring on how the operation fared. */ - - static void make_response(blkif_t *blkif, u64 id, unsigned short op, int st) { diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index 0f91830f18c8..4c140c8e75bd 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -76,6 +76,7 @@ typedef struct blkif_st { atomic_t refcnt; wait_queue_head_t wq; + /* One thread per one blkif. */ struct task_struct *xenblkd; unsigned int waiting_reqs; struct request_queue *plug; diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c index e397a4134f1b..a4a15350737f 100644 --- a/drivers/xen/blkback/interface.c +++ b/drivers/xen/blkback/interface.c @@ -1,6 +1,4 @@ /****************************************************************************** - * arch/xen/drivers/blkif/backend/interface.c - * * Block-device interface management. * * Copyright (c) 2004, Keir Fraser diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 8c91a2fb0019..95156c95ab2f 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -1,6 +1,4 @@ /****************************************************************************** - * blkback/vbd.c - * * Routines for managing virtual block devices (VBDs). * * Copyright (c) 2003-2005, Keir Fraser & Steve Hand diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 031bc3d7eec3..e9c4f80ef1c8 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -107,7 +107,7 @@ static void update_blkif_status(blkif_t *blkif) } -/**************************************************************** +/* * sysfs interface for VBD I/O requests */ -- GitLab From 5489377ce40d52fb722dcd811617114cebad7bba Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:21:50 -0400 Subject: [PATCH 0994/5560] xen/blkback: blkif->struct blkif_st checkpatch.pl suggested that we don't use the typdef in common.h and this triggered this avalanche of patches. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 24 ++++++++++++------------ drivers/xen/blkback/common.h | 23 ++++++++++++----------- drivers/xen/blkback/interface.c | 16 ++++++++-------- drivers/xen/blkback/vbd.c | 6 +++--- drivers/xen/blkback/xenbus.c | 6 +++--- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 8a4b1e8eeb62..d07ad5318a85 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -75,7 +75,7 @@ module_param(debug_lvl, int, 0644); * response queued for it, with the saved 'id' passed back. */ typedef struct { - blkif_t *blkif; + struct blkif_st *blkif; u64 id; int nr_pages; atomic_t pendcnt; @@ -123,11 +123,11 @@ static inline unsigned long vaddr(pending_req_t *req, int seg) (blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)]) -static int do_block_io_op(blkif_t *blkif); -static void dispatch_rw_block_io(blkif_t *blkif, +static int do_block_io_op(struct blkif_st *blkif); +static void dispatch_rw_block_io(struct blkif_st *blkif, struct blkif_request *req, pending_req_t *pending_req); -static void make_response(blkif_t *blkif, u64 id, +static void make_response(struct blkif_st *blkif, u64 id, unsigned short op, int st); /* @@ -169,7 +169,7 @@ static void free_req(pending_req_t *req) * It is OK to make multiple calls in this function as it * resets the plug to NULL when it is done on the first call. */ -static void unplug_queue(blkif_t *blkif) +static void unplug_queue(struct blkif_st *blkif) { if (blkif->plug == NULL) return; @@ -185,7 +185,7 @@ static void unplug_queue(blkif_t *blkif) * not to double reference. We also give back a reference count * if it corresponds to another queue. */ -static void plug_queue(blkif_t *blkif, struct block_device *bdev) +static void plug_queue(struct blkif_st *blkif, struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); @@ -237,7 +237,7 @@ static void fast_flush_area(pending_req_t *req) * SCHEDULER FUNCTIONS */ -static void print_stats(blkif_t *blkif) +static void print_stats(struct blkif_st *blkif) { printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | br %4d\n", current->comm, blkif->st_oo_req, @@ -250,7 +250,7 @@ static void print_stats(blkif_t *blkif) int blkif_schedule(void *arg) { - blkif_t *blkif = arg; + struct blkif_st *blkif = arg; struct vbd *vbd = &blkif->vbd; blkif_get(blkif); @@ -337,7 +337,7 @@ static void end_block_io_op(struct bio *bio, int error) * Notification from the guest OS. */ -static void blkif_notify_work(blkif_t *blkif) +static void blkif_notify_work(struct blkif_st *blkif) { blkif->waiting_reqs = 1; wake_up(&blkif->wq); @@ -356,7 +356,7 @@ irqreturn_t blkif_be_int(int irq, void *dev_id) * (which has the sectors we want, number of them, grant references, etc), * and transmute it to the block API to hand it over to the proper block disk. */ -static int do_block_io_op(blkif_t *blkif) +static int do_block_io_op(struct blkif_st *blkif) { union blkif_back_rings *blk_rings = &blkif->blk_rings; struct blkif_request req; @@ -438,7 +438,7 @@ static int do_block_io_op(blkif_t *blkif) * Transumation of the 'struct blkif_request' to a proper 'struct bio' * and call the 'submit_bio' to pass it to the underlaying storage. */ -static void dispatch_rw_block_io(blkif_t *blkif, +static void dispatch_rw_block_io(struct blkif_st *blkif, struct blkif_request *req, pending_req_t *pending_req) { @@ -633,7 +633,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, /* * Put a response on the ring on how the operation fared. */ -static void make_response(blkif_t *blkif, u64 id, +static void make_response(struct blkif_st *blkif, u64 id, unsigned short op, int st) { struct blkif_response resp; diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index 4c140c8e75bd..be3fc93d8a31 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -44,7 +44,7 @@ #define DPRINTK(_f, _a...) \ pr_debug("(file=%s, line=%d) " _f, \ - __FILE__ , __LINE__ , ## _a ) + __FILE__ , __LINE__ , ## _a) struct vbd { blkif_vdev_t handle; /* what the domain refers to this vbd as */ @@ -57,7 +57,7 @@ struct vbd { struct backend_info; -typedef struct blkif_st { +struct blkif_st { /* Unique identifier for this interface. */ domid_t domid; unsigned int handle; @@ -94,13 +94,14 @@ typedef struct blkif_st { grant_handle_t shmem_handle; grant_ref_t shmem_ref; -} blkif_t; +}; -blkif_t *blkif_alloc(domid_t domid); -void blkif_disconnect(blkif_t *blkif); -void blkif_free(blkif_t *blkif); -int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); -void vbd_resize(blkif_t *blkif); +struct blkif_st *blkif_alloc(domid_t domid); +void blkif_disconnect(struct blkif_st *blkif); +void blkif_free(struct blkif_st *blkif); +int blkif_map(struct blkif_st *blkif, unsigned long shared_page, + unsigned int evtchn); +void vbd_resize(struct blkif_st *blkif); #define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) #define blkif_put(_b) \ @@ -110,7 +111,7 @@ void vbd_resize(blkif_t *blkif); } while (0) /* Create a vbd. */ -int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major, +int vbd_create(struct blkif_st *blkif, blkif_vdev_t vdevice, unsigned major, unsigned minor, int readonly, int cdrom); void vbd_free(struct vbd *vbd); @@ -125,7 +126,7 @@ struct phys_req { blkif_sector_t sector_number; }; -int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); +int vbd_translate(struct phys_req *req, struct blkif_st *blkif, int operation); int blkif_interface_init(void); diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c index a4a15350737f..7d59f13115cf 100644 --- a/drivers/xen/blkback/interface.c +++ b/drivers/xen/blkback/interface.c @@ -35,9 +35,9 @@ static struct kmem_cache *blkif_cachep; -blkif_t *blkif_alloc(domid_t domid) +struct blkif_st *blkif_alloc(domid_t domid) { - blkif_t *blkif; + struct blkif_st *blkif; blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL); if (!blkif) @@ -54,7 +54,7 @@ blkif_t *blkif_alloc(domid_t domid) return blkif; } -static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) +static int map_frontend_page(struct blkif_st *blkif, unsigned long shared_page) { struct gnttab_map_grant_ref op; @@ -75,7 +75,7 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) return 0; } -static void unmap_frontend_page(blkif_t *blkif) +static void unmap_frontend_page(struct blkif_st *blkif) { struct gnttab_unmap_grant_ref op; @@ -86,7 +86,7 @@ static void unmap_frontend_page(blkif_t *blkif) BUG(); } -int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) +int blkif_map(struct blkif_st *blkif, unsigned long shared_page, unsigned int evtchn) { int err; @@ -143,7 +143,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) return 0; } -void blkif_disconnect(blkif_t *blkif) +void blkif_disconnect(struct blkif_st *blkif) { if (blkif->xenblkd) { kthread_stop(blkif->xenblkd); @@ -166,7 +166,7 @@ void blkif_disconnect(blkif_t *blkif) } } -void blkif_free(blkif_t *blkif) +void blkif_free(struct blkif_st *blkif) { if (!atomic_dec_and_test(&blkif->refcnt)) BUG(); @@ -175,7 +175,7 @@ void blkif_free(blkif_t *blkif) int __init blkif_interface_init(void) { - blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), + blkif_cachep = kmem_cache_create("blkif_cache", sizeof(struct blkif_st), 0, 0, NULL); if (!blkif_cachep) return -ENOMEM; diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 95156c95ab2f..26a37df8173a 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -48,7 +48,7 @@ unsigned long vbd_secsize(struct vbd *vbd) return bdev_logical_block_size(vbd->bdev); } -int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, +int vbd_create(struct blkif_st *blkif, blkif_vdev_t handle, unsigned major, unsigned minor, int readonly, int cdrom) { struct vbd *vbd; @@ -97,7 +97,7 @@ void vbd_free(struct vbd *vbd) vbd->bdev = NULL; } -int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) +int vbd_translate(struct phys_req *req, struct blkif_st *blkif, int operation) { struct vbd *vbd = &blkif->vbd; int rc = -EACCES; @@ -116,7 +116,7 @@ int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) return rc; } -void vbd_resize(blkif_t *blkif) +void vbd_resize(struct blkif_st *blkif) { struct vbd *vbd = &blkif->vbd; struct xenbus_transaction xbt; diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index e9c4f80ef1c8..67462c4e9ab4 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -30,7 +30,7 @@ struct backend_info { struct xenbus_device *dev; - blkif_t *blkif; + struct blkif_st *blkif; struct xenbus_watch backend_watch; unsigned major; unsigned minor; @@ -47,7 +47,7 @@ struct xenbus_device *blkback_xenbus(struct backend_info *be) return be->dev; } -static int blkback_name(blkif_t *blkif, char *buf) +static int blkback_name(struct blkif_st *blkif, char *buf) { char *devpath, *devname; struct xenbus_device *dev = blkif->be->dev; @@ -67,7 +67,7 @@ static int blkback_name(blkif_t *blkif, char *buf) return 0; } -static void update_blkif_status(blkif_t *blkif) +static void update_blkif_status(struct blkif_st *blkif) { int err; char name[TASK_COMM_LEN]; -- GitLab From 3c64b58cd614c976dcb19e16fa59ab620b3fe130 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:24:45 -0400 Subject: [PATCH 0995/5560] xen/blkback: Fix checkpatch warnings in vbd.c Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/vbd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index 26a37df8173a..d0ff4cf91a34 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -30,8 +30,9 @@ #include "common.h" -#define vbd_sz(_v) ((_v)->bdev->bd_part ? \ - (_v)->bdev->bd_part->nr_sects : get_capacity((_v)->bdev->bd_disk)) +#define vbd_sz(_v) ((_v)->bdev->bd_part ? \ + (_v)->bdev->bd_part->nr_sects : \ + get_capacity((_v)->bdev->bd_disk)) unsigned long long vbd_size(struct vbd *vbd) { @@ -40,7 +41,7 @@ unsigned long long vbd_size(struct vbd *vbd) unsigned int vbd_info(struct vbd *vbd) { - return vbd->type | (vbd->readonly?VDISK_READONLY:0); + return vbd->type | (vbd->readonly ? VDISK_READONLY : 0); } unsigned long vbd_secsize(struct vbd *vbd) @@ -126,7 +127,7 @@ void vbd_resize(struct blkif_st *blkif) printk(KERN_INFO "VBD Resize: Domid: %d, Device: (%d, %d)\n", blkif->domid, MAJOR(vbd->pdevice), MINOR(vbd->pdevice)); - printk(KERN_INFO "VBD Resize: new size %Lu\n", new_size); + printk(KERN_INFO "VBD Resize: new size %llu\n", new_size); vbd->size = new_size; again: err = xenbus_transaction_start(&xbt); @@ -134,7 +135,7 @@ void vbd_resize(struct blkif_st *blkif) printk(KERN_WARNING "Error starting transaction"); return; } - err = xenbus_printf(xbt, dev->nodename, "sectors", "%Lu", + err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", vbd_size(vbd)); if (err) { printk(KERN_WARNING "Error writing new size"); -- GitLab From e5f4b3c498623fc3d83f6d92e00a2b2dbf500cd0 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:27:29 -0400 Subject: [PATCH 0996/5560] xen/blkback: Fix interface.c checkpatch warnings .. except + sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring_area->addr; WARNING: line over 80 characters + BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE); as breaking them up really does not help that much. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/interface.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c index 7d59f13115cf..163aed41e825 100644 --- a/drivers/xen/blkback/interface.c +++ b/drivers/xen/blkback/interface.c @@ -86,7 +86,8 @@ static void unmap_frontend_page(struct blkif_st *blkif) BUG(); } -int blkif_map(struct blkif_st *blkif, unsigned long shared_page, unsigned int evtchn) +int blkif_map(struct blkif_st *blkif, unsigned long shared_page, + unsigned int evtchn) { int err; @@ -94,7 +95,8 @@ int blkif_map(struct blkif_st *blkif, unsigned long shared_page, unsigned int ev if (blkif->irq) return 0; - if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL ) + blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE); + if (!blkif->blk_ring_area) return -ENOMEM; err = map_frontend_page(blkif, shared_page); @@ -131,8 +133,7 @@ int blkif_map(struct blkif_st *blkif, unsigned long shared_page, unsigned int ev err = bind_interdomain_evtchn_to_irqhandler( blkif->domid, evtchn, blkif_be_int, 0, "blkif-backend", blkif); - if (err < 0) - { + if (err < 0) { unmap_frontend_page(blkif); free_vm_area(blkif->blk_ring_area); blkif->blk_rings.common.sring = NULL; -- GitLab From d6091b217dd4fdabc4a8cd6fa61775f1e3eb6efe Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:33:30 -0400 Subject: [PATCH 0997/5560] xen/blkback: Fix checkpatch warnings of xenbus.c Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/xenbus.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 67462c4e9ab4..b41ed65db2d3 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -25,10 +25,9 @@ #undef DPRINTK #define DPRINTK(fmt, args...) \ pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \ - __FUNCTION__, __LINE__, ##args) + __func__, __LINE__, ##args) -struct backend_info -{ +struct backend_info { struct xenbus_device *dev; struct blkif_st *blkif; struct xenbus_watch backend_watch; @@ -56,7 +55,8 @@ static int blkback_name(struct blkif_st *blkif, char *buf) if (IS_ERR(devpath)) return PTR_ERR(devpath); - if ((devname = strstr(devpath, "/dev/")) != NULL) + devname = strstr(devpath, "/dev/"); + if (devname != NULL) devname += strlen("/dev/"); else devname = devpath; @@ -153,7 +153,7 @@ int xenvbd_sysfs_addif(struct xenbus_device *dev) int error; error = device_create_file(&dev->dev, &dev_attr_physical_device); - if (error) + if (error) goto fail1; error = device_create_file(&dev->dev, &dev_attr_mode); @@ -327,7 +327,10 @@ static void backend_changed(struct xenbus_watch *watch, /* Front end dir is a number, which is used as the handle. */ char *p = strrchr(dev->otherend, '/') + 1; - long handle = simple_strtoul(p, NULL, 0); + long handle; + err = strict_strtoul(p, 0, &handle); + if (err) + return; be->major = major; be->minor = minor; @@ -369,7 +372,7 @@ static void frontend_changed(struct xenbus_device *dev, case XenbusStateInitialising: if (dev->state == XenbusStateClosed) { printk(KERN_INFO "%s: %s: prepare for reconnect\n", - __FUNCTION__, dev->nodename); + __func__, dev->nodename); xenbus_switch_state(dev, XenbusStateInitWait); } break; @@ -494,8 +497,8 @@ static int connect_ring(struct backend_info *be) DPRINTK("%s", dev->otherend); - err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref, - "event-channel", "%u", &evtchn, NULL); + err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", + &ring_ref, "event-channel", "%u", &evtchn, NULL); if (err) { xenbus_dev_fatal(dev, err, "reading %s/ring-ref and event-channel", -- GitLab From 2e9977c21f7679d5f616132ae1f7857e932ccd19 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:42:07 -0400 Subject: [PATCH 0998/5560] xen/blkback: Fix checkpatch warnings in blkback.c Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 81 ++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index d07ad5318a85..2d413930f235 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -63,8 +63,8 @@ module_param_named(reqs, blkif_reqs, int, 0); MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); /* Run-time switchable: /sys/module/blkback/parameters/ */ -static unsigned int log_stats = 0; -static unsigned int debug_lvl = 0; +static unsigned int log_stats; +static unsigned int debug_lvl; module_param(log_stats, int, 0644); module_param(debug_lvl, int, 0644); @@ -74,7 +74,7 @@ module_param(debug_lvl, int, 0644); * the pendcnt towards zero. When it hits zero, the specified domain has a * response queued for it, with the saved 'id' passed back. */ -typedef struct { +struct pending_req { struct blkif_st *blkif; u64 id; int nr_pages; @@ -82,12 +82,12 @@ typedef struct { unsigned short operation; int status; struct list_head free_list; -} pending_req_t; +}; #define BLKBACK_INVALID_HANDLE (~0) struct xen_blkbk { - pending_req_t *pending_reqs; + struct pending_req *pending_reqs; /* List of all 'pending_req' available */ struct list_head pending_free; /* And its spinlock. */ @@ -106,14 +106,15 @@ static struct xen_blkbk *blkbk; * pending_pages[..]. For each 'pending_req' we have have up to * BLKIF_MAX_SEGMENTS_PER_REQUEST (11) pages. The seg would be from 0 through * 10 and would index in the pending_pages[..]. */ -static inline int vaddr_pagenr(pending_req_t *req, int seg) +static inline int vaddr_pagenr(struct pending_req *req, int seg) { - return (req - blkbk->pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; + return (req - blkbk->pending_reqs) * + BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; } #define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)] -static inline unsigned long vaddr(pending_req_t *req, int seg) +static inline unsigned long vaddr(struct pending_req *req, int seg) { unsigned long pfn = page_to_pfn(blkbk->pending_page(req, seg)); return (unsigned long)pfn_to_kaddr(pfn); @@ -126,21 +127,22 @@ static inline unsigned long vaddr(pending_req_t *req, int seg) static int do_block_io_op(struct blkif_st *blkif); static void dispatch_rw_block_io(struct blkif_st *blkif, struct blkif_request *req, - pending_req_t *pending_req); + struct pending_req *pending_req); static void make_response(struct blkif_st *blkif, u64 id, unsigned short op, int st); /* * Retrieve from the 'pending_reqs' a free pending_req structure to be used. */ -static pending_req_t* alloc_req(void) +static struct pending_req *alloc_req(void) { - pending_req_t *req = NULL; + struct pending_req *req = NULL; unsigned long flags; spin_lock_irqsave(&blkbk->pending_free_lock, flags); if (!list_empty(&blkbk->pending_free)) { - req = list_entry(blkbk->pending_free.next, pending_req_t, free_list); + req = list_entry(blkbk->pending_free.next, struct pending_req, + free_list); list_del(&req->free_list); } spin_unlock_irqrestore(&blkbk->pending_free_lock, flags); @@ -151,7 +153,7 @@ static pending_req_t* alloc_req(void) * Return the 'pending_req' structure back to the freepool. We also * wake up the thread if it was waiting for a free page. */ -static void free_req(pending_req_t *req) +static void free_req(struct pending_req *req) { unsigned long flags; int was_empty; @@ -200,7 +202,7 @@ static void plug_queue(struct blkif_st *blkif, struct block_device *bdev) * Unmap the grant references, and also remove the M2P over-rides * used in the 'pending_req'. */ -static void fast_flush_area(pending_req_t *req) +static void fast_flush_area(struct pending_req *req) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; @@ -221,7 +223,8 @@ static void fast_flush_area(pending_req_t *req) GNTTABOP_unmap_grant_ref, unmap, invcount); BUG_ON(ret); /* Note, we use invcount, so nr->pages, so we can't index - * using vaddr(req, i). */ + * using vaddr(req, i). + */ for (i = 0; i < invcount; i++) { ret = m2p_remove_override( virt_to_page(unmap[i].host_addr), false); @@ -233,7 +236,7 @@ static void fast_flush_area(pending_req_t *req) } } -/****************************************************************** +/* * SCHEDULER FUNCTIONS */ @@ -269,7 +272,8 @@ int blkif_schedule(void *arg) blkif->waiting_reqs || kthread_should_stop()); wait_event_interruptible( blkbk->pending_free_wq, - !list_empty(&blkbk->pending_free) || kthread_should_stop()); + !list_empty(&blkbk->pending_free) || + kthread_should_stop()); blkif->waiting_reqs = 0; smp_mb(); /* clear flag *before* checking for work */ @@ -297,7 +301,7 @@ int blkif_schedule(void *arg) * Completion callback on the bio's. Called as bh->b_end_io() */ -static void __end_block_io_op(pending_req_t *pending_req, int error) +static void __end_block_io_op(struct pending_req *pending_req, int error) { /* An error fails the entire request. */ if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) && @@ -313,7 +317,8 @@ static void __end_block_io_op(pending_req_t *pending_req, int error) /* If all of the bio's have completed it is time to unmap * the grant references associated with 'request' and provide - * the proper response on the ring. */ + * the proper response on the ring. + */ if (atomic_dec_and_test(&pending_req->pendcnt)) { fast_flush_area(pending_req); make_response(pending_req->blkif, pending_req->id, @@ -360,7 +365,7 @@ static int do_block_io_op(struct blkif_st *blkif) { union blkif_back_rings *blk_rings = &blkif->blk_rings; struct blkif_request req; - pending_req_t *pending_req; + struct pending_req *pending_req; RING_IDX rc, rp; int more_to_do = 0; @@ -440,7 +445,7 @@ static int do_block_io_op(struct blkif_st *blkif) */ static void dispatch_rw_block_io(struct blkif_st *blkif, struct blkif_request *req, - pending_req_t *pending_req) + struct pending_req *pending_req) { struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct phys_req preq; @@ -487,7 +492,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, /* Fill out preq.nr_sects with proper amount of sectors, and setup * assign map[..] with the PFN of the page in our domain with the - * corresponding grant reference for each page.*/ + * corresponding grant reference for each page. + */ for (i = 0; i < nseg; i++) { uint32_t flags; @@ -509,8 +515,9 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, BUG_ON(ret); /* Now swizzel the MFN in our domain with the MFN from the other domain - * so that when we access vaddr(pending_req,i) it has the contents of the - * page from the other domain. */ + * so that when we access vaddr(pending_req,i) it has the contents of + * the page from the other domain. + */ for (i = 0; i < nseg; i++) { if (unlikely(map[i].status != 0)) { DPRINTK("invalid buffer -- could not remap it\n"); @@ -522,12 +529,13 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, if (ret) continue; - + ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), blkbk->pending_page(pending_req, i), false); if (ret) { printk(KERN_ALERT "Failed to install M2P override for"\ - " %lx (ret: %d)\n", (unsigned long)map[i].dev_bus_addr, ret); + " %lx (ret: %d)\n", (unsigned long) + map[i].dev_bus_addr, ret); /* We could switch over to GNTTABOP_copy */ continue; } @@ -536,9 +544,11 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, (req->u.rw.seg[i].first_sect << 9); } - /* If we have failed at this point, we need to undo the M2P override, set - * gnttab_set_unmap_op on all of the grant references and perform the - * hypercall to unmap the grants - that is all done in fast_flush_area. */ + /* If we have failed at this point, we need to undo the M2P override, + * set gnttab_set_unmap_op on all of the grant references and perform + * the hypercall to unmap the grants - that is all done in + * fast_flush_area. + */ if (ret) goto fail_flush; @@ -554,7 +564,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, plug_queue(blkif, preq.bdev); /* We set it one so that the last submit_bio does not have to call - * atomic_inc. */ + * atomic_inc. + */ atomic_set(&pending_req->pendcnt, 1); blkif_get(blkif); @@ -575,7 +586,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, atomic_inc(&pending_req->pendcnt); submit_bio(operation, bio); } - + bio = bio_alloc(GFP_KERNEL, nseg-i); if (unlikely(bio == NULL)) goto fail_put_bio; @@ -694,7 +705,7 @@ static int __init blkif_init(void) if (!xen_pv_domain()) return -ENODEV; - blkbk = (struct xen_blkbk *)kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL); + blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL); if (!blkbk) { printk(KERN_ALERT "%s: out of memory!\n", __func__); return -ENOMEM; @@ -709,7 +720,8 @@ static int __init blkif_init(void) blkbk->pending_pages = kzalloc(sizeof(blkbk->pending_pages[0]) * mmap_pages, GFP_KERNEL); - if (!blkbk->pending_reqs || !blkbk->pending_grant_handles || !blkbk->pending_pages) { + if (!blkbk->pending_reqs || !blkbk->pending_grant_handles || + !blkbk->pending_pages) { rc = -ENOMEM; goto out_of_memory; } @@ -733,7 +745,8 @@ static int __init blkif_init(void) init_waitqueue_head(&blkbk->pending_free_wq); for (i = 0; i < blkif_reqs; i++) - list_add_tail(&blkbk->pending_reqs[i].free_list, &blkbk->pending_free); + list_add_tail(&blkbk->pending_reqs[i].free_list, + &blkbk->pending_free); rc = blkif_xenbus_init(); if (rc) -- GitLab From 0faa8cca883bbc6a0919e3c89128672659b75820 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 14 Apr 2011 17:58:19 -0400 Subject: [PATCH 0999/5560] xen/blkback: remove per-queue plugging commit 7eaceaccab5f40bbfda044629a6298616aeaed50 ("block: remove per-queue plugging") added two new interfaces to plug and unplug: blk_start_plug and blk_finish_plug. Lets use those. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 44 +++++++---------------------------- drivers/xen/blkback/common.h | 1 - 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 2d413930f235..464f2e0b5a61 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -166,38 +166,6 @@ static void free_req(struct pending_req *req) wake_up(&blkbk->pending_free_wq); } -/* - * Give back a reference count on the underlaying storage. - * It is OK to make multiple calls in this function as it - * resets the plug to NULL when it is done on the first call. - */ -static void unplug_queue(struct blkif_st *blkif) -{ - if (blkif->plug == NULL) - return; - if (blkif->plug->unplug_fn) - blkif->plug->unplug_fn(blkif->plug); - blk_put_queue(blkif->plug); - blkif->plug = NULL; -} - -/* - * Take a reference count on the underlaying storage. - * It is OK to call this multiple times as we check to make sure - * not to double reference. We also give back a reference count - * if it corresponds to another queue. - */ -static void plug_queue(struct blkif_st *blkif, struct block_device *bdev) -{ - struct request_queue *q = bdev_get_queue(bdev); - - if (q == blkif->plug) - return; - unplug_queue(blkif); - blk_get_queue(q); - blkif->plug = q; -} - /* * Unmap the grant references, and also remove the M2P over-rides * used in the 'pending_req'. @@ -280,7 +248,6 @@ int blkif_schedule(void *arg) if (do_block_io_op(blkif)) blkif->waiting_reqs = 1; - unplug_queue(blkif); if (log_stats && time_after(jiffies, blkif->st_print)) print_stats(blkif); @@ -456,6 +423,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, struct bio *bio = NULL; int ret, i; int operation; + struct blk_plug plug; + struct request_queue *q; switch (req->operation) { case BLKIF_OP_READ: @@ -561,7 +530,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, } /* Get a reference count for the disk queue and start sending I/O */ - plug_queue(blkif, preq.bdev); + blk_get_queue(q); + blk_start_plug(&plug); /* We set it one so that the last submit_bio does not have to call * atomic_inc. @@ -620,11 +590,14 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, else if (operation == WRITE || operation == WRITE_BARRIER) blkif->st_wr_sect += preq.nr_sects; + blk_finish_plug(&plug); + blk_put_queue(q); return; fail_flush: fast_flush_area(pending_req); fail_response: + /* Haven't submitted any bio's yet. */ make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); free_req(pending_req); msleep(1); /* back off a bit */ @@ -634,7 +607,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, __end_block_io_op(pending_req, -EINVAL); if (bio) bio_put(bio); - unplug_queue(blkif); + blk_finish_plug(&plug); + blk_put_queue(q); msleep(1); /* back off a bit */ return; } diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index be3fc93d8a31..6257c1106591 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -79,7 +79,6 @@ struct blkif_st { /* One thread per one blkif. */ struct task_struct *xenblkd; unsigned int waiting_reqs; - struct request_queue *plug; /* statistics */ unsigned long st_print; -- GitLab From fce55922f5299a04c0a56b170a141fab34f13465 Mon Sep 17 00:00:00 2001 From: "Allan, Bruce W" Date: Wed, 13 Apr 2011 13:09:10 +0000 Subject: [PATCH 1000/5560] ethtool: allow custom interval for physical identification When physical identification of an adapter is done by toggling the mechanism on and off through software utilizing the set_phys_id operation, it is done with a fixed duration for both on and off states. Some drivers may want to set a custom duration for the on/off intervals. This patch changes the API so the return code from the driver's entry point when it is called with ETHTOOL_ID_ACTIVE can specify the frequency at which to cycle the on/off states, and updates the drivers that have already been converted to use the new set_phys_id and use the synchronous method for identifying an adapter. The physical identification frequency set in the updated drivers is based on how it was done prior to the introduction of set_phys_id. Compile tested only. Also fixes a compiler warning in sfc. v2: drivers do not return -EINVAL for ETHOOL_ID_ACTIVE v3: fold patchset into single patch and cleanup per Ben's feedback Signed-off-by: Bruce Allan Cc: Ben Hutchings Cc: Sathya Perla Cc: Subbu Seetharaman Cc: Ajit Khaparde Cc: Michael Chan Cc: Eilon Greenstein Cc: Divy Le Ray Cc: Don Fry Cc: Jon Mason Cc: Solarflare linux maintainers Cc: Steve Hodgson Cc: Stephen Hemminger Cc: Matt Carlson Acked-by: Jon Mason Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 2 +- drivers/net/bnx2.c | 2 +- drivers/net/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/cxgb3/cxgb3_main.c | 2 +- drivers/net/ewrk3.c | 2 +- drivers/net/niu.c | 2 +- drivers/net/pcnet32.c | 2 +- drivers/net/s2io.c | 2 +- drivers/net/sfc/ethtool.c | 6 +++--- drivers/net/skge.c | 2 +- drivers/net/sky2.c | 2 +- drivers/net/tg3.c | 2 +- include/linux/ethtool.h | 6 ++++-- net/core/ethtool.c | 31 ++++++++++++++++--------------- 14 files changed, 34 insertions(+), 31 deletions(-) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 96f5502e0ef7..80226e4801f3 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -516,7 +516,7 @@ be_set_phys_id(struct net_device *netdev, case ETHTOOL_ID_ACTIVE: be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &adapter->beacon_state); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0a52079bafef..bf729ee6acbd 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7473,7 +7473,7 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) bp->leds_save = REG_RD(bp, BNX2_MISC_CFG); REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ad7d91e499f4..0a5e88d6ba2c 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -2025,7 +2025,7 @@ static int bnx2x_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: bnx2x_set_led(&bp->link_params, &bp->link_vars, diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 802c7a7c3b25..a087e0691dce 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1757,7 +1757,7 @@ static int set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_OFF: t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0); diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index c7ce4438e923..17b6027d8be8 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -1618,7 +1618,7 @@ static int ewrk3_set_phys_id(struct net_device *dev, /* Prevent ISR from twiddling the LED */ lp->led_mask = 0; spin_unlock_irq(&lp->hw_lock); - return -EINVAL; + return 2; /* cycle on/off twice per second */ case ETHTOOL_ID_ON: cr = inb(EWRK3_CR); diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 3fa1e9cdb4a8..ea2272f0f37e 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7896,7 +7896,7 @@ static int niu_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: np->orig_led_state = niu_led_state_save(np); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: niu_force_led(np, 1); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index e89afb929740..0a1efbae1bc0 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1038,7 +1038,7 @@ static int pcnet32_set_phys_id(struct net_device *dev, for (i = 4; i < 8; i++) lp->save_regs[i - 4] = a->read_bcr(ioaddr, i); spin_unlock_irqrestore(&lp->lock, flags); - return -EINVAL; + return 2; /* cycle on/off twice per second */ case ETHTOOL_ID_ON: case ETHTOOL_ID_OFF: diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2d5cc6142c04..2302d9743744 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5541,7 +5541,7 @@ static int s2io_ethtool_set_led(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: sp->adapt_ctrl_org = readq(&bar0->gpio_control); - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: s2io_set_led(sp, true); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 644f7c1d6e7b..5d8468fc5804 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -182,7 +182,7 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, enum ethtool_phys_id_state state) { struct efx_nic *efx = netdev_priv(net_dev); - enum efx_led_mode mode; + enum efx_led_mode mode = EFX_LED_DEFAULT; switch (state) { case ETHTOOL_ID_ON: @@ -194,8 +194,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, case ETHTOOL_ID_INACTIVE: mode = EFX_LED_DEFAULT; break; - default: - return -EINVAL; + case ETHTOOL_ID_ACTIVE: + return 1; /* cycle on/off once per second */ } efx->type->set_id_led(efx, mode); diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 310dcbce2519..176d784cbb54 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -753,7 +753,7 @@ static int skge_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 2; /* cycle on/off twice per second */ case ETHTOOL_ID_ON: skge_led(skge, LED_MODE_TST); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a4b8fe564eb0..c8d045114c66 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3813,7 +3813,7 @@ static int sky2_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_INACTIVE: sky2_led(sky2, MO_LED_NORM); break; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 10fa476fede3..9915734ac3e9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10384,7 +10384,7 @@ static int tg3_set_phys_id(struct net_device *dev, switch (state) { case ETHTOOL_ID_ACTIVE: - return -EINVAL; + return 1; /* cycle on/off once per second */ case ETHTOOL_ID_ON: tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ad22a68c2e5d..9de31274341d 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -798,8 +798,10 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); * attached to it. The implementation may update the indicator * asynchronously or synchronously, but in either case it must return * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE, - * and must either activate asynchronous updates or return -%EINVAL. - * If it returns -%EINVAL then it will be called again at intervals with + * and must either activate asynchronous updates and return zero, return + * a negative error or return a positive frequency for synchronous + * indication (e.g. 1 for one on/off cycle per second). If it returns + * a frequency then it will be called again at intervals with the * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of * the indicator accordingly. Finally, it is called with the argument * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 41dee2de13ad..13d79f5a86e5 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1669,7 +1669,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) return dev->ethtool_ops->phys_id(dev, id.data); rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE); - if (rc && rc != -EINVAL) + if (rc < 0) return rc; /* Drop the RTNL lock while waiting, but prevent reentry or @@ -1684,21 +1684,22 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) schedule_timeout_interruptible( id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT); } else { - /* Driver expects to be called periodically */ + /* Driver expects to be called at twice the frequency in rc */ + int n = rc * 2, i, interval = HZ / n; + + /* Count down seconds */ do { - rtnl_lock(); - rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ON); - rtnl_unlock(); - if (rc) - break; - schedule_timeout_interruptible(HZ / 2); - - rtnl_lock(); - rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_OFF); - rtnl_unlock(); - if (rc) - break; - schedule_timeout_interruptible(HZ / 2); + /* Count down iterations per second */ + i = n; + do { + rtnl_lock(); + rc = dev->ethtool_ops->set_phys_id(dev, + (i & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON); + rtnl_unlock(); + if (rc) + break; + schedule_timeout_interruptible(interval); + } while (!signal_pending(current) && --i != 0); } while (!signal_pending(current) && (id.data == 0 || --id.data != 0)); } -- GitLab From 44f4d5a27ee63ec80d498e0d0673605d5ce1427d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Tue, 12 Apr 2011 23:27:36 +0000 Subject: [PATCH 1001/5560] Phonet: convert bound sockets hash list to RCU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This gets rid of the last spinlock in the Phonet stack proper. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- net/phonet/socket.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index b1adafab377c..8c5bfcef92cb 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -52,7 +52,7 @@ static int pn_socket_release(struct socket *sock) static struct { struct hlist_head hlist[PN_HASHSIZE]; - spinlock_t lock; + struct mutex lock; } pnsocks; void __init pn_sock_init(void) @@ -61,7 +61,7 @@ void __init pn_sock_init(void) for (i = 0; i < PN_HASHSIZE; i++) INIT_HLIST_HEAD(pnsocks.hlist + i); - spin_lock_init(&pnsocks.lock); + mutex_init(&pnsocks.lock); } static struct hlist_head *pn_hash_list(u16 obj) @@ -82,9 +82,8 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn) u8 res = spn->spn_resource; struct hlist_head *hlist = pn_hash_list(obj); - spin_lock_bh(&pnsocks.lock); - - sk_for_each(sknode, node, hlist) { + rcu_read_lock(); + sk_for_each_rcu(sknode, node, hlist) { struct pn_sock *pn = pn_sk(sknode); BUG_ON(!pn->sobject); /* unbound socket */ @@ -107,8 +106,7 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn) sock_hold(sknode); break; } - - spin_unlock_bh(&pnsocks.lock); + rcu_read_unlock(); return rval; } @@ -119,7 +117,7 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb) struct hlist_head *hlist = pnsocks.hlist; unsigned h; - spin_lock(&pnsocks.lock); + rcu_read_lock(); for (h = 0; h < PN_HASHSIZE; h++) { struct hlist_node *node; struct sock *sknode; @@ -140,25 +138,26 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb) } hlist++; } - spin_unlock(&pnsocks.lock); + rcu_read_unlock(); } void pn_sock_hash(struct sock *sk) { struct hlist_head *hlist = pn_hash_list(pn_sk(sk)->sobject); - spin_lock_bh(&pnsocks.lock); - sk_add_node(sk, hlist); - spin_unlock_bh(&pnsocks.lock); + mutex_lock(&pnsocks.lock); + sk_add_node_rcu(sk, hlist); + mutex_unlock(&pnsocks.lock); } EXPORT_SYMBOL(pn_sock_hash); void pn_sock_unhash(struct sock *sk) { - spin_lock_bh(&pnsocks.lock); - sk_del_node_init(sk); - spin_unlock_bh(&pnsocks.lock); + mutex_lock(&pnsocks.lock); + sk_del_node_init_rcu(sk); + mutex_unlock(&pnsocks.lock); pn_sock_unbind_all_res(sk); + synchronize_rcu(); } EXPORT_SYMBOL(pn_sock_unhash); @@ -548,7 +547,7 @@ static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos) unsigned h; for (h = 0; h < PN_HASHSIZE; h++) { - sk_for_each(sknode, node, hlist) { + sk_for_each_rcu(sknode, node, hlist) { if (!net_eq(net, sock_net(sknode))) continue; if (!pos) @@ -572,9 +571,9 @@ static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk) } static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(pnsocks.lock) + __acquires(rcu) { - spin_lock_bh(&pnsocks.lock); + rcu_read_lock(); return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } @@ -591,9 +590,9 @@ static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void pn_sock_seq_stop(struct seq_file *seq, void *v) - __releases(pnsocks.lock) + __releases(rcu) { - spin_unlock_bh(&pnsocks.lock); + rcu_read_unlock(); } static int pn_sock_seq_show(struct seq_file *seq, void *v) @@ -721,13 +720,11 @@ void pn_sock_unbind_all_res(struct sock *sk) } mutex_unlock(&resource_mutex); - if (match == 0) - return; - synchronize_rcu(); while (match > 0) { - sock_put(sk); + __sock_put(sk); match--; } + /* Caller is responsible for RCU sync before final sock_put() */ } #ifdef CONFIG_PROC_FS -- GitLab From 6c8c2513c86c589a819c161c9abbdea2a3d56f5e Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 14 Apr 2011 05:50:12 +0000 Subject: [PATCH 1002/5560] sfc: make function tables const The phy, mac, and board information structures should be const. Since tables contain function pointer this improves security (at least theoretically). Compile tested only. Signed-off-by: Stephen Hemminger Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 6 +++--- drivers/net/sfc/falcon.c | 4 ++-- drivers/net/sfc/falcon_xmac.c | 2 +- drivers/net/sfc/mac.h | 4 ++-- drivers/net/sfc/mcdi_mac.c | 2 +- drivers/net/sfc/mcdi_phy.c | 2 +- drivers/net/sfc/net_driver.h | 6 +++--- drivers/net/sfc/nic.h | 6 +++--- drivers/net/sfc/phy.h | 8 ++++---- drivers/net/sfc/qt202x_phy.c | 2 +- drivers/net/sfc/siena.c | 2 +- drivers/net/sfc/tenxpress.c | 2 +- drivers/net/sfc/txc43128_phy.c | 2 +- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index db72a6e054e1..c8871b2db38c 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -2245,7 +2245,7 @@ static bool efx_port_dummy_op_poll(struct efx_nic *efx) return false; } -static struct efx_phy_operations efx_dummy_phy_operations = { +static const struct efx_phy_operations efx_dummy_phy_operations = { .init = efx_port_dummy_op_int, .reconfigure = efx_port_dummy_op_int, .poll = efx_port_dummy_op_poll, @@ -2261,7 +2261,7 @@ static struct efx_phy_operations efx_dummy_phy_operations = { /* This zeroes out and then fills in the invariants in a struct * efx_nic (including all sub-structures). */ -static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, +static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type, struct pci_dev *pci_dev, struct net_device *net_dev) { int i; @@ -2451,7 +2451,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) static int __devinit efx_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *entry) { - struct efx_nic_type *type = (struct efx_nic_type *) entry->driver_data; + const struct efx_nic_type *type = (const struct efx_nic_type *) entry->driver_data; struct net_device *net_dev; struct efx_nic *efx; int i, rc; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d96b23769bd1..60176e873d62 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1703,7 +1703,7 @@ static int falcon_set_wol(struct efx_nic *efx, u32 type) ************************************************************************** */ -struct efx_nic_type falcon_a1_nic_type = { +const struct efx_nic_type falcon_a1_nic_type = { .probe = falcon_probe_nic, .remove = falcon_remove_nic, .init = falcon_init_nic, @@ -1744,7 +1744,7 @@ struct efx_nic_type falcon_a1_nic_type = { .reset_world_flags = ETH_RESET_IRQ, }; -struct efx_nic_type falcon_b0_nic_type = { +const struct efx_nic_type falcon_b0_nic_type = { .probe = falcon_probe_nic, .remove = falcon_remove_nic, .init = falcon_init_nic, diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 2c9ee5db3bf7..9516452c079c 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -362,7 +362,7 @@ void falcon_poll_xmac(struct efx_nic *efx) falcon_ack_status_intr(efx); } -struct efx_mac_operations falcon_xmac_operations = { +const struct efx_mac_operations falcon_xmac_operations = { .reconfigure = falcon_reconfigure_xmac, .update_stats = falcon_update_stats_xmac, .check_fault = falcon_xmac_check_fault, diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h index 6886cdf87c12..d6a255d0856b 100644 --- a/drivers/net/sfc/mac.h +++ b/drivers/net/sfc/mac.h @@ -13,8 +13,8 @@ #include "net_driver.h" -extern struct efx_mac_operations falcon_xmac_operations; -extern struct efx_mac_operations efx_mcdi_mac_operations; +extern const struct efx_mac_operations falcon_xmac_operations; +extern const struct efx_mac_operations efx_mcdi_mac_operations; extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, u32 dma_len, int enable, int clear); diff --git a/drivers/net/sfc/mcdi_mac.c b/drivers/net/sfc/mcdi_mac.c index 33f7294edb47..50c20777a564 100644 --- a/drivers/net/sfc/mcdi_mac.c +++ b/drivers/net/sfc/mcdi_mac.c @@ -138,7 +138,7 @@ static bool efx_mcdi_mac_check_fault(struct efx_nic *efx) } -struct efx_mac_operations efx_mcdi_mac_operations = { +const struct efx_mac_operations efx_mcdi_mac_operations = { .reconfigure = efx_mcdi_mac_reconfigure, .update_stats = efx_port_dummy_op_void, .check_fault = efx_mcdi_mac_check_fault, diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 7e3c65b0c99f..1fcda2d82399 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -739,7 +739,7 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, return NULL; } -struct efx_phy_operations efx_mcdi_phy_ops = { +const struct efx_phy_operations efx_mcdi_phy_ops = { .probe = efx_mcdi_phy_probe, .init = efx_port_dummy_op_int, .reconfigure = efx_mcdi_phy_reconfigure, diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 92a9067e8e77..ab4d05b84eb7 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -773,10 +773,10 @@ struct efx_nic { struct efx_buffer stats_buffer; - struct efx_mac_operations *mac_op; + const struct efx_mac_operations *mac_op; unsigned int phy_type; - struct efx_phy_operations *phy_op; + const struct efx_phy_operations *phy_op; void *phy_data; struct mdio_if_info mdio; unsigned int mdio_bus; @@ -897,7 +897,7 @@ struct efx_nic_type { void (*resume_wol)(struct efx_nic *efx); int (*test_registers)(struct efx_nic *efx); int (*test_nvram)(struct efx_nic *efx); - struct efx_mac_operations *default_mac_ops; + const struct efx_mac_operations *default_mac_ops; int revision; unsigned int mem_map_size; diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index d9de1b647d41..f7ec03cc002d 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -150,9 +150,9 @@ struct siena_nic_data { int wol_filter_id; }; -extern struct efx_nic_type falcon_a1_nic_type; -extern struct efx_nic_type falcon_b0_nic_type; -extern struct efx_nic_type siena_a0_nic_type; +extern const struct efx_nic_type falcon_a1_nic_type; +extern const struct efx_nic_type falcon_b0_nic_type; +extern const struct efx_nic_type siena_a0_nic_type; /************************************************************************** * diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index b3b79472421e..11d148cd8441 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h @@ -13,14 +13,14 @@ /**************************************************************************** * 10Xpress (SFX7101) PHY */ -extern struct efx_phy_operations falcon_sfx7101_phy_ops; +extern const struct efx_phy_operations falcon_sfx7101_phy_ops; extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); /**************************************************************************** * AMCC/Quake QT202x PHYs */ -extern struct efx_phy_operations falcon_qt202x_phy_ops; +extern const struct efx_phy_operations falcon_qt202x_phy_ops; /* These PHYs provide various H/W control states for LEDs */ #define QUAKE_LED_LINK_INVAL (0) @@ -39,7 +39,7 @@ extern void falcon_qt202x_set_led(struct efx_nic *p, int led, int state); /**************************************************************************** * Transwitch CX4 retimer */ -extern struct efx_phy_operations falcon_txc_phy_ops; +extern const struct efx_phy_operations falcon_txc_phy_ops; #define TXC_GPIO_DIR_INPUT 0 #define TXC_GPIO_DIR_OUTPUT 1 @@ -50,7 +50,7 @@ extern void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int val); /**************************************************************************** * Siena managed PHYs */ -extern struct efx_phy_operations efx_mcdi_phy_ops; +extern const struct efx_phy_operations efx_mcdi_phy_ops; extern int efx_mcdi_mdio_read(struct efx_nic *efx, unsigned int bus, unsigned int prtad, unsigned int devad, diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 55f90924247e..7ad97e397406 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -449,7 +449,7 @@ static void qt202x_phy_remove(struct efx_nic *efx) efx->phy_data = NULL; } -struct efx_phy_operations falcon_qt202x_phy_ops = { +const struct efx_phy_operations falcon_qt202x_phy_ops = { .probe = qt202x_phy_probe, .init = qt202x_phy_init, .reconfigure = qt202x_phy_reconfigure, diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index e4dd8986b1fe..ceac1c9907f0 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -581,7 +581,7 @@ static void siena_init_wol(struct efx_nic *efx) ************************************************************************** */ -struct efx_nic_type siena_a0_nic_type = { +const struct efx_nic_type siena_a0_nic_type = { .probe = siena_probe_nic, .remove = siena_remove_nic, .init = siena_init_nic, diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index efdceb35aaae..204ecdaac9ab 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -478,7 +478,7 @@ static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) advertising & ADVERTISED_10000baseT_Full); } -struct efx_phy_operations falcon_sfx7101_phy_ops = { +const struct efx_phy_operations falcon_sfx7101_phy_ops = { .probe = tenxpress_phy_probe, .init = tenxpress_phy_init, .reconfigure = tenxpress_phy_reconfigure, diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c index d9886addcc99..7c21b334a75b 100644 --- a/drivers/net/sfc/txc43128_phy.c +++ b/drivers/net/sfc/txc43128_phy.c @@ -545,7 +545,7 @@ static void txc43128_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) mdio45_ethtool_gset(&efx->mdio, ecmd); } -struct efx_phy_operations falcon_txc_phy_ops = { +const struct efx_phy_operations falcon_txc_phy_ops = { .probe = txc43128_phy_probe, .init = txc43128_phy_init, .reconfigure = txc43128_phy_reconfigure, -- GitLab From ef9c7ab4a97d53d9cb4912d13e142f52a30ecd54 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 14 Apr 2011 05:51:52 +0000 Subject: [PATCH 1003/5560] qlge: make nic_operations struct const The struct nic_operations is just function pointers and should be declared const for added security. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 2 +- drivers/net/qlge/qlge_main.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 4757c59a07a2..d32850715f5c 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -2134,7 +2134,7 @@ struct ql_adapter { struct delayed_work mpi_idc_work; struct delayed_work mpi_core_to_log; struct completion ide_completion; - struct nic_operations *nic_ops; + const struct nic_operations *nic_ops; u16 device_id; struct timer_list timer; atomic_t lb_count; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 5bb311945436..f61e717adac4 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -4412,12 +4412,12 @@ static void ql_asic_reset_work(struct work_struct *work) rtnl_unlock(); } -static struct nic_operations qla8012_nic_ops = { +static const struct nic_operations qla8012_nic_ops = { .get_flash = ql_get_8012_flash_params, .port_initialize = ql_8012_port_initialize, }; -static struct nic_operations qla8000_nic_ops = { +static const struct nic_operations qla8000_nic_ops = { .get_flash = ql_get_8000_flash_params, .port_initialize = ql_8000_port_initialize, }; -- GitLab From d30ee670f25ea8f265a2804e2a0a53804cac5185 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 13 Apr 2011 15:22:29 +0000 Subject: [PATCH 1004/5560] net-bonding: Fix minor sparse complaints This gets rid of minor sparse complaints: drivers/net/bonding/bond_main.c:4361:4: warning: do-while statement is not a compound statement drivers/net/bonding/bond_main.c:243:12: warning: symbol 'bond_mode_name' was not declared. Should it be static? Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/bonding/bond_procfs.c | 2 -- drivers/net/bonding/bonding.h | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b51e021354b5..94a371c12d70 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4357,9 +4357,9 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; if (unlikely(txq >= dev->real_num_tx_queues)) { - do + do { txq -= dev->real_num_tx_queues; - while (txq >= dev->real_num_tx_queues); + } while (txq >= dev->real_num_tx_queues); } return txq; } diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index c32ff55a34c1..c97307ddd1c9 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -4,8 +4,6 @@ #include "bonding.h" -extern const char *bond_mode_name(int mode); - static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) __acquires(RCU) __acquires(&bond->lock) diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 90736cb4d975..3ca503e50718 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -416,6 +416,7 @@ 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); +const char *bond_mode_name(int mode); struct bond_net { struct net * net; /* Associated network namespace */ -- GitLab From 65cce19c07756c2b2b51595c967dda93b0727027 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 13 Apr 2011 15:22:30 +0000 Subject: [PATCH 1005/5560] net-bonding: Fix minor/cosmetic type inconsistencies The __get_link_speed() function returns a u16 value which was stored in a u32 local variable. This patch uses the return value directly, thus fixing that minor type consistency. The 'duplex' field in struct slave being encoded on 8 bits, to be more consistent we use a u8 integer (instead of u16) whenever we copy it to local variables. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 4 +--- drivers/net/bonding/bond_main.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 494bf960442d..123dd602261f 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -716,11 +716,9 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) static u32 __get_agg_bandwidth(struct aggregator *aggregator) { u32 bandwidth = 0; - u32 basic_speed; if (aggregator->num_of_ports) { - basic_speed = __get_link_speed(aggregator->lag_ports); - switch (basic_speed) { + switch (__get_link_speed(aggregator->lag_ports)) { case AD_LINK_SPEED_BITMASK_1MBPS: bandwidth = aggregator->num_of_ports; break; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 94a371c12d70..4df674bc6f12 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3340,7 +3340,7 @@ static int bond_slave_netdev_event(unsigned long event, slave = bond_get_slave_by_dev(bond, slave_dev); if (slave) { u16 old_speed = slave->speed; - u16 old_duplex = slave->duplex; + u8 old_duplex = slave->duplex; bond_update_speed_duplex(slave); -- GitLab From 5d30530efbb811f875786d788ae1c5d79547c3a4 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 13 Apr 2011 15:22:31 +0000 Subject: [PATCH 1006/5560] net-bonding: Adding support for throughputs larger than 65536 Mbps This updates the bonding driver to support v2.6.27-rc3 enhancements (b11f8d8c aka. "ethtool: Expand ethtool_cmd.speed to 32 bits") which allow to encode the Mbps link speed on 32-bits (Max 4 Pbps) instead of 16 (Max 65536 Mbps). This patch also attempts to compact struct slave by reordering its fields. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 12 +++++++----- drivers/net/bonding/bonding.h | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4df674bc6f12..ca902ae3f2e5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -631,7 +631,8 @@ static int bond_set_carrier(struct bonding *bond) static int bond_update_speed_duplex(struct slave *slave) { struct net_device *slave_dev = slave->dev; - struct ethtool_cmd etool; + struct ethtool_cmd etool = { .cmd = ETHTOOL_GSET }; + u32 slave_speed; int res; /* Fake speed and duplex */ @@ -645,7 +646,8 @@ static int bond_update_speed_duplex(struct slave *slave) if (res < 0) return -1; - switch (etool.speed) { + slave_speed = ethtool_cmd_speed(&etool); + switch (slave_speed) { case SPEED_10: case SPEED_100: case SPEED_1000: @@ -663,7 +665,7 @@ static int bond_update_speed_duplex(struct slave *slave) return -1; } - slave->speed = etool.speed; + slave->speed = slave_speed; slave->duplex = etool.duplex; return 0; @@ -2493,7 +2495,7 @@ static void bond_miimon_commit(struct bonding *bond) bond_update_speed_duplex(slave); - pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n", + pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", bond->dev->name, slave->dev->name, slave->speed, slave->duplex ? "full" : "half"); @@ -3339,7 +3341,7 @@ static int bond_slave_netdev_event(unsigned long event, slave = bond_get_slave_by_dev(bond, slave_dev); if (slave) { - u16 old_speed = slave->speed; + u32 old_speed = slave->speed; u8 old_duplex = slave->duplex; bond_update_speed_duplex(slave); diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 3ca503e50718..553c764f7407 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -196,12 +196,12 @@ struct slave { u8 backup:1, /* indicates backup slave. Value corresponds with BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ inactive:1; /* indicates inactive slave */ + u8 duplex; u32 original_mtu; u32 link_failure_count; - u8 perm_hwaddr[ETH_ALEN]; - u16 speed; - u8 duplex; + u32 speed; u16 queue_id; + u8 perm_hwaddr[ETH_ALEN]; struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ struct tlb_slave_info tlb_info; #ifdef CONFIG_NET_POLL_CONTROLLER -- GitLab From eb8aa72d4e8756bde74d5f22bdd968ee6131069a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 14 Apr 2011 23:23:45 -0700 Subject: [PATCH 1007/5560] rndis_host: Quirky devices are still 'point-to-point' My changes in commit 4d42d417be75d750b82798922b6e775915e11bce were written some time before the introduction of FLAG_POINTTOPOINT, so didn't include that flag in the new driver_info. Change the new driver_info to be consistent. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/usb/rndis_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 6d6c1da68a36..255d6a424a6b 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -592,7 +592,7 @@ static const struct driver_info rndis_info = { static const struct driver_info rndis_poll_status_info = { .description = "RNDIS device (poll status before control)", - .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT, .data = RNDIS_DRIVER_DATA_POLL_STATUS, .bind = rndis_bind, .unbind = rndis_unbind, -- GitLab From 5b17b077eb069365ac9508dd0be6e09e0b604bd2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 14 Apr 2011 15:06:13 -0700 Subject: [PATCH 1008/5560] ALSA: hda - sound/pci/hda/hda_codec.c: fix warning sound/pci/hda/hda_codec.c: In function 'snd_hda_get_connections': sound/pci/hda/hda_codec.c:332: warning: unused variable 'j' Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 11ead159abd9..2b6019390489 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -329,7 +329,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns) { struct snd_array *array = &codec->conn_lists; - int i, j, len, old_used; + int i, len, old_used; hda_nid_t list[HDA_MAX_CONNECTIONS]; /* look up the cached results */ -- GitLab From ae038af12c2bc0859279a1a62b5f8cb0ef00f5f8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 7 Apr 2011 15:28:47 +0300 Subject: [PATCH 1009/5560] OMAP: DSS2: DSI: fix use_sys_clk & highfreq use_sys_clk and highfreq fields in dsi.current_cinfo were never set. Luckily they weren't used anywhere so it didn't cause any problems. This patch fixes those fields and they are now set at the same time as the rest of the fields. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 0a7f1a47f8e3..86041535f34a 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1276,6 +1276,9 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) DSSDBGF(); + dsi.current_cinfo.use_sys_clk = cinfo->use_sys_clk; + dsi.current_cinfo.highfreq = cinfo->highfreq; + dsi.current_cinfo.fint = cinfo->fint; dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk = -- GitLab From 4eb68edb7d21aff81765a065680270693c23fbfc Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 4 Apr 2011 10:02:53 +0300 Subject: [PATCH 1010/5560] OMAP: DSS2: DSI: fix dsi_dump_clocks() On OMAP4, reading DSI_PLL_CONFIGURATION2 register requires the L3 clock (CIO_CLK_ICG) to PLL. Currently dsi_dump_clocks() tries to read that register without enabling the L3 clock, leading to crash if DSI is not in use. The status of the bit being read from DSI_PLL_CONFIGURATION2 is available from dsi_clock_info->use_sys_clk, so we can avoid the whole problem by just using that. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 86041535f34a..1464ac4f6f58 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1491,7 +1491,6 @@ void dsi_pll_uninit(void) void dsi_dump_clocks(struct seq_file *s) { - int clksel; struct dsi_clock_info *cinfo = &dsi.current_cinfo; enum dss_clk_source dispc_clk_src, dsi_clk_src; @@ -1500,13 +1499,10 @@ void dsi_dump_clocks(struct seq_file *s) enable_clocks(1); - clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11); - seq_printf(s, "- DSI PLL -\n"); seq_printf(s, "dsi pll source = %s\n", - clksel == 0 ? - "dss_sys_clk" : "pclkfree"); + cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree"); seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); -- GitLab From 6553b2105c8871dae8dfff244440e793f3a6bdb9 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 31 Mar 2011 13:23:35 +0530 Subject: [PATCH 1011/5560] OMAP: DSS2: Fix: Return correct lcd clock source for OMAP2/3 dss.lcd_clk_source is set to the default value DSS_CLK_SRC_FCK at dss_init. For OMAP2 and OMAP3, the dss.lcd_clk_source should always be the same as dss.dispc_clk_source. The function dss_get_lcd_clk_source() always returns the default value DSS_CLK_SRC_FCK for OMAP2/3. This leads to wrong clock dumps when dispc_clk_source is not DSS_CLK_SRC_FCK. Correct this function to always return dss.dispc_clk_source for OMAP2/3. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 3f1fee63c678..c3b48a0fcf35 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -385,8 +385,14 @@ enum dss_clk_source dss_get_dsi_clk_source(void) enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) { - int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; - return dss.lcd_clk_source[ix]; + if (dss_has_feature(FEAT_LCD_CLK_SRC)) { + int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; + return dss.lcd_clk_source[ix]; + } else { + /* LCD_CLK source is the same as DISPC_FCLK source for + * OMAP2 and OMAP3 */ + return dss.dispc_clk_source; + } } /* calculate clock rates using dividers in cinfo */ -- GitLab From 0b41136c0d2f544b9b771643f849f82ed86f765e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 15 Apr 2011 10:42:59 +0300 Subject: [PATCH 1012/5560] OMAP: DSS2: DSI: Fix DSI PLL power bug OMAP3630 has a HW bug causing DSI PLL power command POWER_ON_DIV (0x3) to not work properly. The bug prevents us from enabling DSI PLL power only to HS divider block. This patch adds a dss feature for the bug and converts POWER_ON_DIV requests to POWER_ON_ALL (0x2). Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 5 +++++ drivers/video/omap2/dss/dss_features.c | 2 +- drivers/video/omap2/dss/dss_features.h | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 1464ac4f6f58..cbd9ca48d6ec 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1059,6 +1059,11 @@ static int dsi_pll_power(enum dsi_pll_power_state state) { int t = 0; + /* DSI-PLL power command 0x3 is not working */ + if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) && + state == DSI_PLL_POWER_ON_DIV) + state = DSI_PLL_POWER_ON_ALL; + REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ /* PLL_PWR_STATUS */ diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index aa1622241d0d..8c50e18bc0b0 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -271,7 +271,7 @@ static struct omap_dss_features omap3630_dss_features = { FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | - FEAT_RESIZECONF, + FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG, .num_mgrs = 2, .num_ovls = 3, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 12e9c4ef0dec..37922ce6b8b1 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -40,6 +40,8 @@ enum dss_feat_id { /* Independent core clk divider */ FEAT_CORE_CLK_DIV = 1 << 11, FEAT_LCD_CLK_SRC = 1 << 12, + /* DSI-PLL power command 0x3 is not working */ + FEAT_DSI_PLL_PWR_BUG = 1 << 13, }; /* DSS register field id */ -- GitLab From 0fd08060f1bb9d7d0d712f39257dc3574a632271 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Apr 2011 09:30:27 +0300 Subject: [PATCH 1013/5560] OMAP: DSS2: fix panel Kconfig dependencies All DPI panels were missing dependency to OMAP2_DSS_DPI. Add the dependency. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index d18ad6b2372a..609a28073178 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -3,6 +3,7 @@ menu "OMAP2/3 Display Device Drivers" config PANEL_GENERIC_DPI tristate "Generic DPI Panel" + depends on OMAP2_DSS_DPI help Generic DPI panel driver. Supports DVI output for Beagle and OMAP3 SDP. @@ -11,20 +12,20 @@ config PANEL_GENERIC_DPI config PANEL_LGPHILIPS_LB035Q02 tristate "LG.Philips LB035Q02 LCD Panel" - depends on OMAP2_DSS && SPI + depends on OMAP2_DSS_DPI && SPI help LCD Panel used on the Gumstix Overo Palo35 config PANEL_SHARP_LS037V7DW01 tristate "Sharp LS037V7DW01 LCD Panel" - depends on OMAP2_DSS + depends on OMAP2_DSS_DPI select BACKLIGHT_CLASS_DEVICE help LCD Panel used in TI's SDP3430 and EVM boards config PANEL_NEC_NL8048HL11_01B tristate "NEC NL8048HL11-01B Panel" - depends on OMAP2_DSS + depends on OMAP2_DSS_DPI help This NEC NL8048HL11-01B panel is TFT LCD used in the Zoom2/3/3630 sdp boards. @@ -37,7 +38,7 @@ config PANEL_TAAL config PANEL_TPO_TD043MTEA1 tristate "TPO TD043MTEA1 LCD Panel" - depends on OMAP2_DSS && SPI + depends on OMAP2_DSS_DPI && SPI help LCD Panel used in OMAP3 Pandora -- GitLab From f094f8a1b2737a4f3ca46742ff9aaf460d39285e Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Thu, 24 Feb 2011 19:36:42 +0100 Subject: [PATCH 1014/5560] kconfig: allow multiple inclusion of the same file Allow 'source'ing the same file from multiple places (eg. from different files, and/or under different conditions). To avoid circular inclusion, scan the source-ancestry of the current file, and abort if already sourced in this branch. Regenerate the pre-parsed lex.zconf.c_shipped file. Signed-off-by: "Yann E. MORIN" Signed-off-by: Michal Marek --- scripts/kconfig/lex.zconf.c_shipped | 29 +++++++++++++++++++---------- scripts/kconfig/zconf.l | 29 +++++++++++++++++++---------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped index 6eb039718259..f4b3b1a15e21 100644 --- a/scripts/kconfig/lex.zconf.c_shipped +++ b/scripts/kconfig/lex.zconf.c_shipped @@ -2368,6 +2368,7 @@ void zconf_initscan(const char *name) void zconf_nextfile(const char *name) { + struct file *iter; struct file *file = file_lookup(name); struct buffer *buf = malloc(sizeof(*buf)); memset(buf, 0, sizeof(*buf)); @@ -2383,16 +2384,24 @@ void zconf_nextfile(const char *name) buf->parent = current_buf; current_buf = buf; - if (file->flags & FILE_BUSY) { - printf("%s:%d: do not source '%s' from itself\n", - zconf_curname(), zconf_lineno(), name); - exit(1); - } - if (file->flags & FILE_SCANNED) { - printf("%s:%d: file '%s' is already sourced from '%s'\n", - zconf_curname(), zconf_lineno(), name, - file->parent->name); - exit(1); + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } } file->flags |= FILE_BUSY; file->lineno = 1; diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index 3dbaec185cc4..f23e3affa9b5 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -299,6 +299,7 @@ void zconf_initscan(const char *name) void zconf_nextfile(const char *name) { + struct file *iter; struct file *file = file_lookup(name); struct buffer *buf = malloc(sizeof(*buf)); memset(buf, 0, sizeof(*buf)); @@ -314,16 +315,24 @@ void zconf_nextfile(const char *name) buf->parent = current_buf; current_buf = buf; - if (file->flags & FILE_BUSY) { - printf("%s:%d: do not source '%s' from itself\n", - zconf_curname(), zconf_lineno(), name); - exit(1); - } - if (file->flags & FILE_SCANNED) { - printf("%s:%d: file '%s' is already sourced from '%s'\n", - zconf_curname(), zconf_lineno(), name, - file->parent->name); - exit(1); + for (iter = current_file->parent; iter; iter = iter->parent ) { + if (!strcmp(current_file->name,iter->name) ) { + printf("%s:%d: recursive inclusion detected. " + "Inclusion path:\n current file : '%s'\n", + zconf_curname(), zconf_lineno(), + zconf_curname()); + iter = current_file->parent; + while (iter && \ + strcmp(iter->name,current_file->name)) { + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno-1); + iter = iter->parent; + } + if (iter) + printf(" included from: '%s:%d'\n", + iter->name, iter->lineno+1); + exit(1); + } } file->flags |= FILE_BUSY; file->lineno = 1; -- GitLab From 2b2112f617e8ca600ec24271c93bbd49aa2acce4 Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Thu, 24 Feb 2011 19:36:43 +0100 Subject: [PATCH 1015/5560] kconfig: get rid of unused flags Now that we detect recusrion of sourced files, get rid of now unused flags. Regenerate lex.zconf.c_shipped file. Signed-off-by: "Yann E. MORIN" Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 4 ---- scripts/kconfig/lex.zconf.c_shipped | 4 ---- scripts/kconfig/zconf.l | 4 ---- 3 files changed, 12 deletions(-) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 3d238db49764..16bfae2d3217 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -20,12 +20,8 @@ struct file { struct file *parent; const char *name; int lineno; - int flags; }; -#define FILE_BUSY 0x0001 -#define FILE_SCANNED 0x0002 - typedef enum tristate { no, mod, yes } tristate; diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped index f4b3b1a15e21..d9182916f724 100644 --- a/scripts/kconfig/lex.zconf.c_shipped +++ b/scripts/kconfig/lex.zconf.c_shipped @@ -2363,7 +2363,6 @@ void zconf_initscan(const char *name) current_file = file_lookup(name); current_file->lineno = 1; - current_file->flags = FILE_BUSY; } void zconf_nextfile(const char *name) @@ -2403,7 +2402,6 @@ void zconf_nextfile(const char *name) exit(1); } } - file->flags |= FILE_BUSY; file->lineno = 1; file->parent = current_file; current_file = file; @@ -2413,8 +2411,6 @@ static void zconf_endfile(void) { struct buffer *parent; - current_file->flags |= FILE_SCANNED; - current_file->flags &= ~FILE_BUSY; current_file = current_file->parent; parent = current_buf->parent; diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l index f23e3affa9b5..b22f884f9022 100644 --- a/scripts/kconfig/zconf.l +++ b/scripts/kconfig/zconf.l @@ -294,7 +294,6 @@ void zconf_initscan(const char *name) current_file = file_lookup(name); current_file->lineno = 1; - current_file->flags = FILE_BUSY; } void zconf_nextfile(const char *name) @@ -334,7 +333,6 @@ void zconf_nextfile(const char *name) exit(1); } } - file->flags |= FILE_BUSY; file->lineno = 1; file->parent = current_file; current_file = file; @@ -344,8 +342,6 @@ static void zconf_endfile(void) { struct buffer *parent; - current_file->flags |= FILE_SCANNED; - current_file->flags &= ~FILE_BUSY; current_file = current_file->parent; parent = current_buf->parent; -- GitLab From 71a83ec7da8910f374a1c82e96d2704aa45d9238 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 5 Apr 2011 13:24:57 +0300 Subject: [PATCH 1016/5560] Kconfig: improve KALLSYMS_ALL documentation Dumb users like myself are not able to grasp from the existing KALLSYMS_ALL documentation that this option is not what they need. Improve the help message and make it clearer that KALLSYMS is enough in the majority of use cases, and KALLSYMS_ALL should really be used very rarely. Signed-off-by: Artem Bityutskiy Signed-off-by: Michal Marek --- init/Kconfig | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index 56240e724d9a..563065df29a5 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -968,12 +968,18 @@ config KALLSYMS_ALL bool "Include all symbols in kallsyms" depends on DEBUG_KERNEL && KALLSYMS help - Normally kallsyms only contains the symbols of functions, for nicer - OOPS messages. Some debuggers can use kallsyms for other - symbols too: say Y here to include all symbols, if you need them - and you don't care about adding 300k to the size of your kernel. - - Say N. + Normally kallsyms only contains the symbols of functions for nicer + OOPS messages and backtraces (i.e., symbols from the text and inittext + sections). This is sufficient for most cases. And only in very rare + cases (e.g., when a debugger is used) all symbols are required (e.g., + names of variables from the data sections, etc). + + This option makes sure that all symbols are loaded into the kernel + image (i.e., symbols from all sections) in cost of increased kernel + size (depending on the kernel configuration, it may be 300KiB or + something like this). + + Say N unless you really need all symbols. config KALLSYMS_EXTRA_PASS bool "Do an extra kallsyms pass" -- GitLab From 1e2795a1191bb5ff05e80d77feffd51ac875c06d Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 5 Apr 2011 13:24:58 +0300 Subject: [PATCH 1017/5560] kbuild: move KALLSYMS_EXTRA_PASS from Kconfig to Makefile At the moment we have the CONFIG_KALLSYMS_EXTRA_PASS Kconfig switch, which users can enable or disable while configuring the kernel. This option is then used by 'make' to determine whether an extra kallsyms pass is needed or not. However, this approach is not nice and confusing, and this patch moves CONFIG_KALLSYMS_EXTRA_PASS from Kconfig to Makefile instead. The rationale is below. 1. CONFIG_KALLSYMS_EXTRA_PASS is really about the build time, not run-time. There is no real need for it to be in Kconfig. It is just an additional work-around which should be used only in rare cases, when someone breaks kallsyms, so Kbuild/Makefile is much better place for this option. 2. Grepping CONFIG_KALLSYMS_EXTRA_PASS shows that many defconfigs have it enabled, probably not because they try to work-around a kallsyms bug, but just because the Kconfig help text is confusing and does not really make it clear that this option should not be used unless except when kallsyms is broken. 3. And since many people have CONFIG_KALLSYMS_EXTRA_PASS enabled in their Kconfig, we do might fail to notice kallsyms bugs in time. E.g., many testers use "make allyesconfig" to test builds, which will enable CONFIG_KALLSYMS_EXTRA_PASS and kallsyms breakage will not be noticed. To address that, this patch: 1. Kills CONFIG_KALLSYMS_EXTRA_PASS 2. Changes Makefile so that people can use "make KALLSYMS_EXTRA_PASS=1" to enable the extra pass if needed. Additionally, they may define KALLSYMS_EXTRA_PASS as an environment variable. 3. By default KALLSYMS_EXTRA_PASS is disabled and if kallsyms has issues, "make" should print a warning and suggest using KALLSYMS_EXTRA_PASS Signed-off-by: Artem Bityutskiy [mmarek: Removed make help text, is not necessary] Signed-off-by: Michal Marek --- Makefile | 13 ++++++++----- init/Kconfig | 12 ------------ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index ba7a55ccd890..c3bd316b16f4 100644 --- a/Makefile +++ b/Makefile @@ -797,15 +797,17 @@ ifdef CONFIG_KALLSYMS # o The correct .tmp_kallsyms2.o is linked into the final vmlinux. # o Verify that the System.map from vmlinux matches the map from # .tmp_vmlinux2, just in case we did not generate kallsyms correctly. -# o If CONFIG_KALLSYMS_EXTRA_PASS is set, do an extra pass using +# o If 'make KALLSYMS_EXTRA_PASS=1" was used, do an extra pass using # .tmp_vmlinux3 and .tmp_kallsyms3.o. This is only meant as a # temporary bypass to allow the kernel to be built while the # maintainers work out what went wrong with kallsyms. -ifdef CONFIG_KALLSYMS_EXTRA_PASS -last_kallsyms := 3 -else last_kallsyms := 2 + +ifdef KALLSYMS_EXTRA_PASS +ifneq ($(KALLSYMS_EXTRA_PASS),0) +last_kallsyms := 3 +endif endif kallsyms.o := .tmp_kallsyms$(last_kallsyms).o @@ -816,7 +818,8 @@ define verify_kallsyms $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map $(Q)cmp -s System.map .tmp_System.map || \ (echo Inconsistent kallsyms data; \ - echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \ + echo This is a bug - please report about it; \ + echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround; \ rm .tmp_kallsyms* ; /bin/false ) endef diff --git a/init/Kconfig b/init/Kconfig index 563065df29a5..0edda616640f 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -981,18 +981,6 @@ config KALLSYMS_ALL Say N unless you really need all symbols. -config KALLSYMS_EXTRA_PASS - bool "Do an extra kallsyms pass" - depends on KALLSYMS - help - If kallsyms is not working correctly, the build will fail with - inconsistent kallsyms data. If that occurs, log a bug report and - turn on KALLSYMS_EXTRA_PASS which should result in a stable build. - Always say N here unless you find a bug in kallsyms, which must be - reported. KALLSYMS_EXTRA_PASS is only a temporary workaround while - you wait for kallsyms to be fixed. - - config HOTPLUG bool "Support for hot-pluggable devices" if EXPERT default y -- GitLab From 7708992616487c00d5ca8ed7612111180d8e1b68 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 15 Apr 2011 10:51:27 -0400 Subject: [PATCH 1018/5560] xen/blkback: Seperate the bio allocation and the bio submission. We seperate the bio allocation (bio_alloc) from the bio submission so that the error paths are much easier, and also so that the bio submission can be done in one tight loop. It also makes the plug/unplug calls much much easier. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 45 ++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 464f2e0b5a61..3c10499d61a7 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -421,7 +421,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int nseg; struct bio *bio = NULL; - int ret, i; + struct bio *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + int ret, i, nbio = 0; int operation; struct blk_plug plug; struct request_queue *q; @@ -529,14 +530,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, goto fail_flush; } - /* Get a reference count for the disk queue and start sending I/O */ - blk_get_queue(q); - blk_start_plug(&plug); - - /* We set it one so that the last submit_bio does not have to call - * atomic_inc. - */ - atomic_set(&pending_req->pendcnt, 1); + /* This corresponding blkif_put is done in __end_block_io_op */ blkif_get(blkif); for (i = 0; i < nseg; i++) { @@ -552,12 +546,8 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, blkbk->pending_page(pending_req, i), seg[i].nsec << 9, seg[i].buf & ~PAGE_MASK) == 0)) { - if (bio) { - atomic_inc(&pending_req->pendcnt); - submit_bio(operation, bio); - } - bio = bio_alloc(GFP_KERNEL, nseg-i); + bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i); if (unlikely(bio == NULL)) goto fail_put_bio; @@ -573,7 +563,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, /* This will be hit if the operation was a barrier. */ if (!bio) { BUG_ON(operation != WRITE_BARRIER); - bio = bio_alloc(GFP_KERNEL, 0); + bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, 0); if (unlikely(bio == NULL)) goto fail_put_bio; @@ -583,15 +573,28 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, bio->bi_sector = -1; } - submit_bio(operation, bio); + + /* We set it one so that the last submit_bio does not have to call + * atomic_inc. + */ + atomic_set(&pending_req->pendcnt, nbio); + + /* Get a reference count for the disk queue and start sending I/O */ + blk_get_queue(q); + blk_start_plug(&plug); + + for (i = 0; i < nbio; i++) + submit_bio(operation, biolist[i]); + + blk_finish_plug(&plug); + /* Let the I/Os go.. */ + blk_put_queue(q); if (operation == READ) blkif->st_rd_sect += preq.nr_sects; else if (operation == WRITE || operation == WRITE_BARRIER) blkif->st_wr_sect += preq.nr_sects; - blk_finish_plug(&plug); - blk_put_queue(q); return; fail_flush: @@ -604,11 +607,9 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, return; fail_put_bio: + for (i = 0; i < (nbio-1); i++) + bio_put(biolist[i]); __end_block_io_op(pending_req, -EINVAL); - if (bio) - bio_put(bio); - blk_finish_plug(&plug); - blk_put_queue(q); msleep(1); /* back off a bit */ return; } -- GitLab From b0aef17924a06646403cae8eecf6c73219a63c19 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 15 Apr 2011 10:58:05 -0400 Subject: [PATCH 1019/5560] xen/blkback: Cleanup move the code a bit around. Moving it so that the code that 'fast_flush_area' code is close to the code that deals with it so that the reader won't lose focus. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 97 +++++++++++++++++------------------ 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 3c10499d61a7..f282463d7b5c 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -167,41 +167,18 @@ static void free_req(struct pending_req *req) } /* - * Unmap the grant references, and also remove the M2P over-rides - * used in the 'pending_req'. -*/ -static void fast_flush_area(struct pending_req *req) + * Notification from the guest OS. + */ +static void blkif_notify_work(struct blkif_st *blkif) { - struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - unsigned int i, invcount = 0; - grant_handle_t handle; - int ret; - - for (i = 0; i < req->nr_pages; i++) { - handle = pending_handle(req, i); - if (handle == BLKBACK_INVALID_HANDLE) - continue; - gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), - GNTMAP_host_map, handle); - pending_handle(req, i) = BLKBACK_INVALID_HANDLE; - invcount++; - } + blkif->waiting_reqs = 1; + wake_up(&blkif->wq); +} - ret = HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, unmap, invcount); - BUG_ON(ret); - /* Note, we use invcount, so nr->pages, so we can't index - * using vaddr(req, i). - */ - for (i = 0; i < invcount; i++) { - ret = m2p_remove_override( - virt_to_page(unmap[i].host_addr), false); - if (ret) { - printk(KERN_ALERT "Failed to remove M2P override for " \ - "%lx\n", (unsigned long)unmap[i].host_addr); - continue; - } - } +irqreturn_t blkif_be_int(int irq, void *dev_id) +{ + blkif_notify_work(dev_id); + return IRQ_HANDLED; } /* @@ -264,6 +241,43 @@ int blkif_schedule(void *arg) return 0; } +/* + * Unmap the grant references, and also remove the M2P over-rides + * used in the 'pending_req'. +*/ +static void fast_flush_area(struct pending_req *req) +{ + struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + unsigned int i, invcount = 0; + grant_handle_t handle; + int ret; + + for (i = 0; i < req->nr_pages; i++) { + handle = pending_handle(req, i); + if (handle == BLKBACK_INVALID_HANDLE) + continue; + gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), + GNTMAP_host_map, handle); + pending_handle(req, i) = BLKBACK_INVALID_HANDLE; + invcount++; + } + + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); + BUG_ON(ret); + /* Note, we use invcount, so nr->pages, so we can't index + * using vaddr(req, i). + */ + for (i = 0; i < invcount; i++) { + ret = m2p_remove_override( + virt_to_page(unmap[i].host_addr), false); + if (ret) { + printk(KERN_ALERT "Failed to remove M2P override for " \ + "%lx\n", (unsigned long)unmap[i].host_addr); + continue; + } + } +} /* * Completion callback on the bio's. Called as bh->b_end_io() */ @@ -305,23 +319,6 @@ static void end_block_io_op(struct bio *bio, int error) } -/* - * Notification from the guest OS. - */ - -static void blkif_notify_work(struct blkif_st *blkif) -{ - blkif->waiting_reqs = 1; - wake_up(&blkif->wq); -} - -irqreturn_t blkif_be_int(int irq, void *dev_id) -{ - blkif_notify_work(dev_id); - return IRQ_HANDLED; -} - - /* * Function to copy the from the ring buffer the 'struct blkif_request' -- GitLab From 1a95fe6e42cefc52c62c471ad87d7fe8643231df Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 15 Apr 2011 11:35:13 -0400 Subject: [PATCH 1020/5560] xen/blkback: Shuffle code around (vbd_translate moved higher). We take out the chunk of code dealing with mapping to the guest of pages into the xen_blk_map_buf code. And we also move the vbd_translate to be done much earlier. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 129 ++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index f282463d7b5c..211b2005f963 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -241,6 +241,10 @@ int blkif_schedule(void *arg) return 0; } +struct seg_buf { + unsigned long buf; + unsigned int nsec; +}; /* * Unmap the grant references, and also remove the M2P over-rides * used in the 'pending_req'. @@ -278,6 +282,62 @@ static void fast_flush_area(struct pending_req *req) } } } +static int xen_blk_map_buf(struct blkif_request *req, struct pending_req *pending_req, + struct seg_buf seg[]) +{ + struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + int i; + int nseg = req->nr_segments; + int ret = 0; + /* Fill out preq.nr_sects with proper amount of sectors, and setup + * assign map[..] with the PFN of the page in our domain with the + * corresponding grant reference for each page. + */ + for (i = 0; i < nseg; i++) { + uint32_t flags; + + flags = GNTMAP_host_map; + if (pending_req->operation != BLKIF_OP_READ) + flags |= GNTMAP_readonly; + gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, + req->u.rw.seg[i].gref, pending_req->blkif->domid); + } + + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); + BUG_ON(ret); + + /* Now swizzel the MFN in our domain with the MFN from the other domain + * so that when we access vaddr(pending_req,i) it has the contents of + * the page from the other domain. + */ + for (i = 0; i < nseg; i++) { + if (unlikely(map[i].status != 0)) { + DPRINTK("invalid buffer -- could not remap it\n"); + map[i].handle = BLKBACK_INVALID_HANDLE; + ret |= 1; + } + + pending_handle(pending_req, i) = map[i].handle; + + if (ret) + continue; + + ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), + blkbk->pending_page(pending_req, i), false); + if (ret) { + printk(KERN_ALERT "Failed to install M2P override for"\ + " %lx (ret: %d)\n", (unsigned long) + map[i].dev_bus_addr, ret); + /* We could switch over to GNTTABOP_copy */ + continue; + } + + seg[i].buf = map[i].dev_bus_addr | + (req->u.rw.seg[i].first_sect << 9); + } + return ret; +} + /* * Completion callback on the bio's. Called as bh->b_end_io() */ @@ -411,15 +471,12 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, struct blkif_request *req, struct pending_req *pending_req) { - struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct phys_req preq; - struct { - unsigned long buf; unsigned int nsec; - } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct seg_buf seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int nseg; struct bio *bio = NULL; struct bio *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - int ret, i, nbio = 0; + int i, nbio = 0; int operation; struct blk_plug plug; struct request_queue *q; @@ -444,6 +501,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, if (unlikely(nseg == 0 && operation != WRITE_BARRIER) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { DPRINTK("Bad number of segments in request (%d)\n", nseg); + /* Haven't submitted any bio's yet. */ goto fail_response; } @@ -456,77 +514,30 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, pending_req->operation = req->operation; pending_req->status = BLKIF_RSP_OKAY; pending_req->nr_pages = nseg; - - /* Fill out preq.nr_sects with proper amount of sectors, and setup - * assign map[..] with the PFN of the page in our domain with the - * corresponding grant reference for each page. - */ for (i = 0; i < nseg; i++) { - uint32_t flags; - seg[i].nsec = req->u.rw.seg[i].last_sect - req->u.rw.seg[i].first_sect + 1; if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) || (req->u.rw.seg[i].last_sect < req->u.rw.seg[i].first_sect)) goto fail_response; preq.nr_sects += seg[i].nsec; - - flags = GNTMAP_host_map; - if (operation != READ) - flags |= GNTMAP_readonly; - gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, - req->u.rw.seg[i].gref, blkif->domid); } - ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); - BUG_ON(ret); - - /* Now swizzel the MFN in our domain with the MFN from the other domain - * so that when we access vaddr(pending_req,i) it has the contents of - * the page from the other domain. - */ - for (i = 0; i < nseg; i++) { - if (unlikely(map[i].status != 0)) { - DPRINTK("invalid buffer -- could not remap it\n"); - map[i].handle = BLKBACK_INVALID_HANDLE; - ret |= 1; - } - - pending_handle(pending_req, i) = map[i].handle; - - if (ret) - continue; - - ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), - blkbk->pending_page(pending_req, i), false); - if (ret) { - printk(KERN_ALERT "Failed to install M2P override for"\ - " %lx (ret: %d)\n", (unsigned long) - map[i].dev_bus_addr, ret); - /* We could switch over to GNTTABOP_copy */ - continue; - } - - seg[i].buf = map[i].dev_bus_addr | - (req->u.rw.seg[i].first_sect << 9); + if (vbd_translate(&preq, blkif, operation) != 0) { + DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", + operation == READ ? "read" : "write", + preq.sector_number, + preq.sector_number + preq.nr_sects, preq.dev); + goto fail_response; } - /* If we have failed at this point, we need to undo the M2P override, * set gnttab_set_unmap_op on all of the grant references and perform * the hypercall to unmap the grants - that is all done in * fast_flush_area. */ - if (ret) + if (xen_blk_map_buf(req, pending_req, seg)) goto fail_flush; - if (vbd_translate(&preq, blkif, operation) != 0) { - DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", - operation == READ ? "read" : "write", - preq.sector_number, - preq.sector_number + preq.nr_sects, preq.dev); - goto fail_flush; - } - /* This corresponding blkif_put is done in __end_block_io_op */ blkif_get(blkif); -- GitLab From 976222e05ea5a9959ccf880d7a24efbf79b3c6cf Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 15 Apr 2011 11:38:29 -0400 Subject: [PATCH 1021/5560] xen/blkback: Move the check for misaligned I/O higher. We move it up higher to be in same loop that actually computes the sector number. This way, all of the code that deals with verifying that the request is correct is all done before we do any of the page mapping, I/O submission, etc. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 211b2005f963..9598e0fd0f9e 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -521,6 +521,13 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, (req->u.rw.seg[i].last_sect < req->u.rw.seg[i].first_sect)) goto fail_response; preq.nr_sects += seg[i].nsec; + + if (((int)preq.sector_number|(int)seg[i].nsec) & + ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) { + DPRINTK("Misaligned I/O request from domain %d", + blkif->domid); + goto fail_response; + } } if (vbd_translate(&preq, blkif, operation) != 0) { @@ -542,13 +549,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, blkif_get(blkif); for (i = 0; i < nseg; i++) { - if (((int)preq.sector_number|(int)seg[i].nsec) & - ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) { - DPRINTK("Misaligned I/O request from domain %d", - blkif->domid); - goto fail_put_bio; - } - while ((bio == NULL) || (bio_add_page(bio, blkbk->pending_page(pending_req, i), -- GitLab From 9f3aedf573dd034d59e7eb6c4ee97648d5be8fc6 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 15 Apr 2011 11:50:34 -0400 Subject: [PATCH 1022/5560] xen/blkback: Change fast_flush_area to xen_blkbk_unmap, and tweak xen_blk_map_seg. The previous name ('fast_flush_area') had nothing to do with what it does right now. Changing the names so that the code dealing with mapping pages in and out of the guest is called xen_blkbk_[map|unmap]. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 9598e0fd0f9e..c645c83f900b 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -249,7 +249,7 @@ struct seg_buf { * Unmap the grant references, and also remove the M2P over-rides * used in the 'pending_req'. */ -static void fast_flush_area(struct pending_req *req) +static void xen_blkbk_unmap(struct pending_req *req) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; @@ -282,8 +282,8 @@ static void fast_flush_area(struct pending_req *req) } } } -static int xen_blk_map_buf(struct blkif_request *req, struct pending_req *pending_req, - struct seg_buf seg[]) +static int xen_blkbk_map(struct blkif_request *req, struct pending_req *pending_req, + struct seg_buf seg[]) { struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int i; @@ -361,7 +361,7 @@ static void __end_block_io_op(struct pending_req *pending_req, int error) * the proper response on the ring. */ if (atomic_dec_and_test(&pending_req->pendcnt)) { - fast_flush_area(pending_req); + xen_blkbk_unmap(pending_req); make_response(pending_req->blkif, pending_req->id, pending_req->operation, pending_req->status); blkif_put(pending_req->blkif); @@ -540,9 +540,9 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, /* If we have failed at this point, we need to undo the M2P override, * set gnttab_set_unmap_op on all of the grant references and perform * the hypercall to unmap the grants - that is all done in - * fast_flush_area. + * xen_blkbk_unmap. */ - if (xen_blk_map_buf(req, pending_req, seg)) + if (xen_blkbk_map(req, pending_req, seg)) goto fail_flush; /* This corresponding blkif_put is done in __end_block_io_op */ @@ -606,7 +606,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, return; fail_flush: - fast_flush_area(pending_req); + xen_blkbk_unmap(pending_req); fail_response: /* Haven't submitted any bio's yet. */ make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); -- GitLab From b54cd0d5053633373cd3c374aa203024cbf125a0 Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Mon, 21 Mar 2011 22:47:15 +0200 Subject: [PATCH 1023/5560] [PARISC] fix pacache .size with new binutils Fix style of flush_user_dcache_range_asm procedure declaration in arch/parisc/kernel/pacache.s to be consistent with other assembly procedures. Signed-off-by: Meelis Roos Signed-off-by: James Bottomley --- arch/parisc/kernel/pacache.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index a85823668cba..93ff3d90edd1 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -817,10 +817,7 @@ ENTRY(purge_kernel_dcache_page) .procend ENDPROC(purge_kernel_dcache_page) - - .export flush_user_dcache_range_asm - -flush_user_dcache_range_asm: +ENTRY(flush_user_dcache_range_asm) .proc .callinfo NO_CALLS .entry @@ -839,6 +836,7 @@ flush_user_dcache_range_asm: .exit .procend +ENDPROC(flush_user_dcache_range_asm) ENTRY(flush_kernel_dcache_range_asm) .proc -- GitLab From d7dd2ff11b7fcd425aca5a875983c862d19a67ae Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 14 Apr 2011 18:25:21 -0500 Subject: [PATCH 1024/5560] [PARISC] only make executable areas executable Currently parisc has the whole kernel marked as RWX, meaning any kernel page at all is eligible to be executed. This can cause a theoretical problem on systems with combined I/D TLB because the act of referencing a page causes a TLB insertion with an executable bit. This TLB entry may be used by the CPU as the basis for speculating the page into the I-Cache. If this speculated page is subsequently used for a user process, there is the possibility we will get a stale I-cache line picked up as the binary executes. As a point of good practise, only mark actual kernel text pages as executable. The same has to be done for init_text pages, but they're converted to data pages (and the I-Cache flushed) when the init memory is released. Signed-off-by: James Bottomley --- arch/parisc/include/asm/pgtable.h | 9 +- arch/parisc/kernel/entry.S | 3 + arch/parisc/kernel/head.S | 5 +- arch/parisc/kernel/module.c | 10 +- arch/parisc/kernel/vmlinux.lds.S | 1 + arch/parisc/mm/init.c | 260 ++++++++++++++++-------------- 6 files changed, 166 insertions(+), 122 deletions(-) diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 5d7b8ce9fdf3..22dadeb58695 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -177,7 +177,10 @@ struct vm_area_struct; #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _PAGE_KERNEL (_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) +#define _PAGE_KERNEL_RO (_PAGE_PRESENT | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED) +#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXEC) +#define _PAGE_KERNEL_RWX (_PAGE_KERNEL_EXEC | _PAGE_WRITE) +#define _PAGE_KERNEL (_PAGE_KERNEL_RO | _PAGE_WRITE) /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds * are page-aligned, we don't care about the PAGE_OFFSET bits, except @@ -208,7 +211,9 @@ struct vm_area_struct; #define PAGE_COPY PAGE_EXECREAD #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) -#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) +#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RWX __pgprot(_PAGE_KERNEL_RWX) +#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO) #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) #define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index ead8d2a1034c..6f0594439143 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -692,6 +692,9 @@ ENTRY(fault_vector_11) END(fault_vector_11) #endif + /* Fault vector is separately protected and *must* be on its own page */ + .align PAGE_SIZE +ENTRY(end_fault_vector) .import handle_interruption,code .import do_cpu_irq_mask,code diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 145c5e4caaa0..37aabd772fbb 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -106,8 +106,9 @@ $bss_loop: #endif - /* Now initialize the PTEs themselves */ - ldo 0+_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */ + /* Now initialize the PTEs themselves. We use RWX for + * everything ... it will get remapped correctly later */ + ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */ ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ load32 PA(pg0),%r1 diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 6e81bb596e5b..cedbbb8b18d9 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -61,8 +61,10 @@ #include #include #include +#include #include +#include #include #if 0 @@ -214,7 +216,13 @@ void *module_alloc(unsigned long size) { if (size == 0) return NULL; - return vmalloc(size); + /* using RWX means less protection for modules, but it's + * easier than trying to map the text, data, init_text and + * init_data correctly */ + return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, + GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_RWX, -1, + __builtin_return_address(0)); } #ifndef CONFIG_64BIT diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 8f1e4efd143e..bf6a43a322ec 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -134,6 +134,7 @@ SECTIONS . = ALIGN(16384); __init_begin = .; INIT_TEXT_SECTION(16384) + . = ALIGN(PAGE_SIZE); INIT_DATA_SECTION(16) /* we have to discard exit text and such at runtime, not link time */ .exit.text : diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index b7ed8d7a9b33..7e6b4656f3d7 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -369,24 +369,158 @@ static void __init setup_bootmem(void) request_resource(&sysram_resources[0], &pdcdata_resource); } +static void __init map_pages(unsigned long start_vaddr, + unsigned long start_paddr, unsigned long size, + pgprot_t pgprot, int force) +{ + pgd_t *pg_dir; + pmd_t *pmd; + pte_t *pg_table; + unsigned long end_paddr; + unsigned long start_pmd; + unsigned long start_pte; + unsigned long tmp1; + unsigned long tmp2; + unsigned long address; + unsigned long vaddr; + unsigned long ro_start; + unsigned long ro_end; + unsigned long fv_addr; + unsigned long gw_addr; + extern const unsigned long fault_vector_20; + extern void * const linux_gateway_page; + + ro_start = __pa((unsigned long)_text); + ro_end = __pa((unsigned long)&data_start); + fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK; + gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK; + + end_paddr = start_paddr + size; + + pg_dir = pgd_offset_k(start_vaddr); + +#if PTRS_PER_PMD == 1 + start_pmd = 0; +#else + start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); +#endif + start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); + + address = start_paddr; + vaddr = start_vaddr; + while (address < end_paddr) { +#if PTRS_PER_PMD == 1 + pmd = (pmd_t *)__pa(pg_dir); +#else + pmd = (pmd_t *)pgd_address(*pg_dir); + + /* + * pmd is physical at this point + */ + + if (!pmd) { + pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE << PMD_ORDER); + pmd = (pmd_t *) __pa(pmd); + } + + pgd_populate(NULL, pg_dir, __va(pmd)); +#endif + pg_dir++; + + /* now change pmd to kernel virtual addresses */ + + pmd = (pmd_t *)__va(pmd) + start_pmd; + for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++, pmd++) { + + /* + * pg_table is physical at this point + */ + + pg_table = (pte_t *)pmd_address(*pmd); + if (!pg_table) { + pg_table = (pte_t *) + alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE); + pg_table = (pte_t *) __pa(pg_table); + } + + pmd_populate_kernel(NULL, pmd, __va(pg_table)); + + /* now change pg_table to kernel virtual addresses */ + + pg_table = (pte_t *) __va(pg_table) + start_pte; + for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) { + pte_t pte; + + /* + * Map the fault vector writable so we can + * write the HPMC checksum. + */ + if (force) + pte = __mk_pte(address, pgprot); + else if (core_kernel_text(vaddr) && + address != fv_addr) + pte = __mk_pte(address, PAGE_KERNEL_EXEC); + else +#if defined(CONFIG_PARISC_PAGE_SIZE_4KB) + if (address >= ro_start && address < ro_end + && address != fv_addr + && address != gw_addr) + pte = __mk_pte(address, PAGE_KERNEL_RO); + else +#endif + pte = __mk_pte(address, pgprot); + + if (address >= end_paddr) { + if (force) + break; + else + pte_val(pte) = 0; + } + + set_pte(pg_table, pte); + + address += PAGE_SIZE; + vaddr += PAGE_SIZE; + } + start_pte = 0; + + if (address >= end_paddr) + break; + } + start_pmd = 0; + } +} + void free_initmem(void) { unsigned long addr; unsigned long init_begin = (unsigned long)__init_begin; unsigned long init_end = (unsigned long)__init_end; -#ifdef CONFIG_DEBUG_KERNEL + /* The init text pages are marked R-X. We have to + * flush the icache and mark them RW- + * + * This is tricky, because map_pages is in the init section. + * Do a dummy remap of the data section first (the data + * section is already PAGE_KERNEL) to pull in the TLB entries + * for map_kernel */ + map_pages(init_begin, __pa(init_begin), init_end - init_begin, + PAGE_KERNEL_RWX, 1); + /* now remap at PAGE_KERNEL since the TLB is pre-primed to execute + * map_pages */ + map_pages(init_begin, __pa(init_begin), init_end - init_begin, + PAGE_KERNEL, 1); + + /* force the kernel to see the new TLB entries */ + __flush_tlb_range(0, init_begin, init_end); /* Attempt to catch anyone trying to execute code here * by filling the page with BRK insns. */ memset((void *)init_begin, 0x00, init_end - init_begin); + /* finally dump all the instructions which were cached, since the + * pages are no-longer executable */ flush_icache_range(init_begin, init_end); -#endif - /* align __init_begin and __init_end to page size, - ignoring linker script where we might have tried to save RAM */ - init_begin = PAGE_ALIGN(init_begin); - init_end = PAGE_ALIGN(init_end); for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); @@ -616,114 +750,6 @@ void show_mem(unsigned int filter) #endif } - -static void __init map_pages(unsigned long start_vaddr, unsigned long start_paddr, unsigned long size, pgprot_t pgprot) -{ - pgd_t *pg_dir; - pmd_t *pmd; - pte_t *pg_table; - unsigned long end_paddr; - unsigned long start_pmd; - unsigned long start_pte; - unsigned long tmp1; - unsigned long tmp2; - unsigned long address; - unsigned long ro_start; - unsigned long ro_end; - unsigned long fv_addr; - unsigned long gw_addr; - extern const unsigned long fault_vector_20; - extern void * const linux_gateway_page; - - ro_start = __pa((unsigned long)_text); - ro_end = __pa((unsigned long)&data_start); - fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK; - gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK; - - end_paddr = start_paddr + size; - - pg_dir = pgd_offset_k(start_vaddr); - -#if PTRS_PER_PMD == 1 - start_pmd = 0; -#else - start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); -#endif - start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); - - address = start_paddr; - while (address < end_paddr) { -#if PTRS_PER_PMD == 1 - pmd = (pmd_t *)__pa(pg_dir); -#else - pmd = (pmd_t *)pgd_address(*pg_dir); - - /* - * pmd is physical at this point - */ - - if (!pmd) { - pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE << PMD_ORDER); - pmd = (pmd_t *) __pa(pmd); - } - - pgd_populate(NULL, pg_dir, __va(pmd)); -#endif - pg_dir++; - - /* now change pmd to kernel virtual addresses */ - - pmd = (pmd_t *)__va(pmd) + start_pmd; - for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++,pmd++) { - - /* - * pg_table is physical at this point - */ - - pg_table = (pte_t *)pmd_address(*pmd); - if (!pg_table) { - pg_table = (pte_t *) - alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE); - pg_table = (pte_t *) __pa(pg_table); - } - - pmd_populate_kernel(NULL, pmd, __va(pg_table)); - - /* now change pg_table to kernel virtual addresses */ - - pg_table = (pte_t *) __va(pg_table) + start_pte; - for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++,pg_table++) { - pte_t pte; - - /* - * Map the fault vector writable so we can - * write the HPMC checksum. - */ -#if defined(CONFIG_PARISC_PAGE_SIZE_4KB) - if (address >= ro_start && address < ro_end - && address != fv_addr - && address != gw_addr) - pte = __mk_pte(address, PAGE_KERNEL_RO); - else -#endif - pte = __mk_pte(address, pgprot); - - if (address >= end_paddr) - pte_val(pte) = 0; - - set_pte(pg_table, pte); - - address += PAGE_SIZE; - } - start_pte = 0; - - if (address >= end_paddr) - break; - } - start_pmd = 0; - } -} - /* * pagetable_init() sets up the page tables * @@ -748,14 +774,14 @@ static void __init pagetable_init(void) size = pmem_ranges[range].pages << PAGE_SHIFT; map_pages((unsigned long)__va(start_paddr), start_paddr, - size, PAGE_KERNEL); + size, PAGE_KERNEL, 0); } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_end && initrd_end > mem_limit) { printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end); map_pages(initrd_start, __pa(initrd_start), - initrd_end - initrd_start, PAGE_KERNEL); + initrd_end - initrd_start, PAGE_KERNEL, 0); } #endif @@ -780,7 +806,7 @@ static void __init gateway_init(void) */ map_pages(linux_gateway_page_addr, __pa(&linux_gateway_page), - PAGE_SIZE, PAGE_GATEWAY); + PAGE_SIZE, PAGE_GATEWAY, 1); } #ifdef CONFIG_HPUX -- GitLab From b7d45818444a31948cfc7849136013a0ea54b2fb Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Apr 2011 12:37:22 -0500 Subject: [PATCH 1025/5560] [PARISC] prevent speculative re-read on cache flush According to Appendix F, the TLB is the primary arbiter of speculation. Thus, if a page has a TLB entry, it may be speculatively read into the cache. On linux, this can cause us incoherencies because if we're about to do a disk read, we call get_user_pages() to do the flush/invalidate in user space, but we still potentially have the user TLB entries, and the cache could speculate the lines back into userspace (thus causing stale data to be used). This is fixed by purging the TLB entries before we flush through the tmpalias space. Now, the only way the line could be re-speculated is if the user actually tries to touch it (which is not allowed). Signed-off-by: James Bottomley --- arch/parisc/include/asm/cacheflush.h | 5 ++++- arch/parisc/kernel/cache.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index d18328b3f938..da601dd34c05 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h @@ -3,6 +3,7 @@ #include #include +#include /* The usual comment is "Caches aren't brain-dead on the ". * Unfortunately, that doesn't apply to PA-RISC. */ @@ -112,8 +113,10 @@ void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) { - if (PageAnon(page)) + if (PageAnon(page)) { + flush_tlb_page(vma, vmaddr); flush_dcache_page_asm(page_to_phys(page), vmaddr); + } } #ifdef CONFIG_DEBUG_RODATA diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 3f11331c2775..83335f3da5fc 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -304,10 +304,20 @@ void flush_dcache_page(struct page *page) offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; addr = mpnt->vm_start + offset; + /* The TLB is the engine of coherence on parisc: The + * CPU is entitled to speculate any page with a TLB + * mapping, so here we kill the mapping then flush the + * page along a special flush only alias mapping. + * This guarantees that the page is no-longer in the + * cache for any process and nor may it be + * speculatively read in (until the user or kernel + * specifically accesses it, of course) */ + + flush_tlb_page(mpnt, addr); if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) { __flush_cache_page(mpnt, addr, page_to_phys(page)); if (old_addr) - printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)"); + printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)"); old_addr = addr; } } @@ -499,6 +509,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long { BUG_ON(!vma->vm_mm->context); + flush_tlb_page(vma, vmaddr); __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn))); } -- GitLab From 1824074b07ee66fa0f714e08579ad85075132d7b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Apr 2011 08:55:44 -0700 Subject: [PATCH 1026/5560] [PARISC] wire up fanotify syscalls Cc: stable@kernel.org Signed-off-by: James Bottomley --- arch/parisc/include/asm/unistd.h | 4 +++- arch/parisc/kernel/sys_parisc32.c | 8 ++++++++ arch/parisc/kernel/syscall_table.S | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 3eb82c2a5ec3..09f62a6eb069 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -814,8 +814,10 @@ #define __NR_recvmmsg (__NR_Linux + 319) #define __NR_accept4 (__NR_Linux + 320) #define __NR_prlimit64 (__NR_Linux + 321) +#define __NR_fanotify_init (__NR_Linux + 322) +#define __NR_fanotify_mark (__NR_Linux + 323) -#define __NR_Linux_syscalls (__NR_prlimit64 + 1) +#define __NR_Linux_syscalls (__NR_fanotify_mark + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 88a0ad14a9c9..dc9a62462323 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -228,3 +228,11 @@ asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, ((loff_t)lenhi << 32) | lenlo); } + +asmlinkage long compat_sys_fanotify_mark(int fan_fd, int flags, u32 mask_hi, + u32 mask_lo, int fd, + const char __user *pathname) +{ + return sys_fanotify_mark(fan_fd, flags, ((u64)mask_hi << 32) | mask_lo, + fd, pathname); +} diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 4be85ee10b85..c5b01e80981a 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -420,6 +420,8 @@ ENTRY_COMP(recvmmsg) ENTRY_SAME(accept4) /* 320 */ ENTRY_SAME(prlimit64) + ENTRY_SAME(fanotify_init) + ENTRY_COMP(fanotify_mark) /* Nothing yet */ -- GitLab From c3f957a22eca106bd28136943305b390b4337ebf Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Apr 2011 08:55:45 -0700 Subject: [PATCH 1027/5560] [PARISC] wire up clock_adjtime syscall Cc: stable@kernel.org Signed-off-by: James Bottomley --- arch/parisc/include/asm/unistd.h | 3 ++- arch/parisc/kernel/syscall_table.S | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 09f62a6eb069..9af5fab2befc 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -816,8 +816,9 @@ #define __NR_prlimit64 (__NR_Linux + 321) #define __NR_fanotify_init (__NR_Linux + 322) #define __NR_fanotify_mark (__NR_Linux + 323) +#define __NR_clock_adjtime (__NR_Linux + 324) -#define __NR_Linux_syscalls (__NR_fanotify_mark + 1) +#define __NR_Linux_syscalls (__NR_clock_adjtime + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index c5b01e80981a..473bf41f2682 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -422,6 +422,7 @@ ENTRY_SAME(prlimit64) ENTRY_SAME(fanotify_init) ENTRY_COMP(fanotify_mark) + ENTRY_COMP(clock_adjtime) /* Nothing yet */ -- GitLab From a71aae4cec120ee85cf32608fca40a4605461214 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Apr 2011 08:55:46 -0700 Subject: [PATCH 1028/5560] [PARISC] wire up the fhandle syscalls Cc: stable@kernel.org Signed-off-by: James Bottomley --- arch/parisc/include/asm/unistd.h | 4 +++- arch/parisc/kernel/syscall_table.S | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 9af5fab2befc..4266e44a8503 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -817,8 +817,10 @@ #define __NR_fanotify_init (__NR_Linux + 322) #define __NR_fanotify_mark (__NR_Linux + 323) #define __NR_clock_adjtime (__NR_Linux + 324) +#define __NR_name_to_handle_at (__NR_Linux + 325) +#define __NR_open_by_handle_at (__NR_Linux + 326) -#define __NR_Linux_syscalls (__NR_clock_adjtime + 1) +#define __NR_Linux_syscalls (__NR_open_by_handle_at + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 473bf41f2682..b5d298209ecf 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -423,6 +423,8 @@ ENTRY_SAME(fanotify_init) ENTRY_COMP(fanotify_mark) ENTRY_COMP(clock_adjtime) + ENTRY_SAME(name_to_handle_at) /* 325 */ + ENTRY_COMP(open_by_handle_at) /* Nothing yet */ -- GitLab From 2e7bad5f34b5beed47542490c760ed26574e38ba Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 15 Apr 2011 08:55:47 -0700 Subject: [PATCH 1029/5560] [PARISC] wire up syncfs syscall Cc: stable@kernel.org Signed-off-by: James Bottomley --- arch/parisc/include/asm/unistd.h | 3 ++- arch/parisc/kernel/syscall_table.S | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 4266e44a8503..9cbc2c3bf630 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -819,8 +819,9 @@ #define __NR_clock_adjtime (__NR_Linux + 324) #define __NR_name_to_handle_at (__NR_Linux + 325) #define __NR_open_by_handle_at (__NR_Linux + 326) +#define __NR_syncfs (__NR_Linux + 327) -#define __NR_Linux_syscalls (__NR_open_by_handle_at + 1) +#define __NR_Linux_syscalls (__NR_syncfs + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index b5d298209ecf..a5b02ce4d41e 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -425,6 +425,7 @@ ENTRY_COMP(clock_adjtime) ENTRY_SAME(name_to_handle_at) /* 325 */ ENTRY_COMP(open_by_handle_at) + ENTRY_SAME(syncfs) /* Nothing yet */ -- GitLab From deb1cb63d220fc6f24baef39a0ebb48e598f617b Mon Sep 17 00:00:00 2001 From: Shyam Iyer Date: Sat, 26 Feb 2011 01:59:44 -0500 Subject: [PATCH 1030/5560] [SCSI] Log thin provisioning threshold event At least log the message that we received a THIN PROVISIONING SOFT THRESHOLD REACHED Unit Attention. Also added it to unit attention decodes. Signed-off-by: Shyam Iyer Signed-off-by: James Bottomley --- drivers/scsi/constants.c | 1 + drivers/scsi/scsi_error.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index d0c82340f0e2..60d2ef291646 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -772,6 +772,7 @@ static const struct error_info additional[] = {0x3802, "Esn - power management class event"}, {0x3804, "Esn - media class event"}, {0x3806, "Esn - device busy class event"}, + {0x3807, "Thin Provisioning soft threshold reached"}, {0x3900, "Saving parameters not supported"}, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 633c2395a92a..abea2cf05c2e 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -321,6 +321,12 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) "changed. The Linux SCSI layer does not " "automatically adjust these parameters.\n"); + if (sshdr.asc == 0x38 && sshdr.ascq == 0x07) + scmd_printk(KERN_WARNING, scmd, + "Warning! Received an indication that the " + "LUN reached a thin provisioning soft " + "threshold.\n"); + /* * Pass the UA upwards for a determination in the completion * functions. -- GitLab From b4ce6a285b65be4fb858728b3bbe9011242b769f Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 15 Apr 2011 21:35:25 +0000 Subject: [PATCH 1031/5560] viafb: fix OLPC DCON refresh rate This patch fixes a regression introduced by fd3cc69848b7e1873e5f12bbcdd572b20277ecf3a "viafb: remove duplicated clock storage" caused by an incosistent mode which pretended to have a higher refresh rate than it actually had. The wrong refresh rate resulted in a calculated higher pixclock which the OLPC DCON could not handle. By reducing the refresh rate to 50Hz we get close to the old pixclock which makes the OLPC display usable again. Minor other adjustments are needed as 60Hz is assumed to be a safe value which is not true for OLPC DCON. This is no problem as we only support 1200x900 on the OLPC. Signed-off-by: Florian Tobias Schandinat Reported-by: Daniel Drake --- drivers/video/via/hw.c | 8 ++++++-- drivers/video/via/viamode.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index dc4c778877ce..980e263f1875 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2598,8 +2598,12 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh) best = &vmode->crtc[i]; } - if (abs(best->refresh_rate - long_refresh) > 3) - return 60; + if (abs(best->refresh_rate - long_refresh) > 3) { + if (hres == 1200 && vres == 900) + return 50; /* OLPC DCON only supports 50 Hz */ + else + return 60; + } return best->refresh_rate; } diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 8c5bc41ff6a4..260d339b236c 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c @@ -606,7 +606,7 @@ static struct crt_mode_table CRTM1200x720[] = { /* 1200x900 (DCON) */ static struct crt_mode_table DCON1200x900[] = { /* r_rate, hsp, vsp */ - {REFRESH_60, M1200X900_R60_HSP, M1200X900_R60_VSP, + {REFRESH_50, M1200X900_R60_HSP, M1200X900_R60_VSP, /* The correct htotal is 1240, but this doesn't raster on VX855. */ /* Via suggested changing to a multiple of 16, hence 1264. */ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ -- GitLab From 255fa9a3cce3e344ff245cf3b4fbb738bd7e3f48 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Fri, 25 Mar 2011 14:23:57 -0700 Subject: [PATCH 1032/5560] [SCSI] be2iscsi: change in copyright notice - Modifying copyright year to 2011 - Replacing Serverengines with Emulex as Serverengines Corp has been acquired by Emulex Corp Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley --- drivers/scsi/be2iscsi/be.h | 10 +++++----- drivers/scsi/be2iscsi/be_cmds.c | 10 +++++----- drivers/scsi/be2iscsi/be_cmds.h | 10 +++++----- drivers/scsi/be2iscsi/be_iscsi.c | 13 ++++++------- drivers/scsi/be2iscsi/be_iscsi.h | 13 ++++++------- drivers/scsi/be2iscsi/be_main.c | 14 +++++++------- drivers/scsi/be2iscsi/be_main.h | 13 ++++++------- drivers/scsi/be2iscsi/be_mgmt.c | 13 ++++++------- drivers/scsi/be2iscsi/be_mgmt.h | 13 ++++++------- 9 files changed, 52 insertions(+), 57 deletions(-) diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 1cb8a5e85c7f..1d7b976c850f 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #ifndef BEISCSI_H diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index ad246369d373..4ffcbf751695 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #include "be.h" diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index fbd1dc2c15f7..497eb29e5c9e 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #ifndef BEISCSI_CMDS_H diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 868cc5590145..3cad10605023 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,15 +7,14 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohank@serverengines.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) * * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * linux-drivers@emulex.com * + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #include diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index 9c532797c29e..ff60b7fd92d6 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,15 +7,14 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohank@serverengines.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) * * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * linux-drivers@emulex.com * + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #ifndef _BE_ISCSI_ diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 24e20ba9633c..7fe38a49bbb7 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,16 +7,16 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohank@serverengines.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) * * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * linux-drivers@emulex.com * + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ + #include #include #include diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 90eb74f6bcab..1f7c495f4135 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,15 +7,14 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohank@serverengines.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) * * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * linux-drivers@emulex.com * + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #ifndef _BEISCSI_MAIN_ diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 877324fc594c..65a402b60e71 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,15 +7,14 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohank@serverengines.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) * * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * linux-drivers@emulex.com * + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #include "be_mgmt.h" diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index b9acedf78653..08428824ace2 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -7,15 +7,14 @@ * as published by the Free Software Foundation. The full GNU General * Public License is included in this distribution in the file called COPYING. * - * Written by: Jayamohan Kallickal (jayamohank@serverengines.com) + * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com) * * Contact Information: - * linux-drivers@serverengines.com - * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * linux-drivers@emulex.com * + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #ifndef _BEISCSI_MGMT_ -- GitLab From 0ca43cc01ed6778ce7a870573dbbd1c6b44bbab2 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Fri, 25 Mar 2011 14:23:58 -0700 Subject: [PATCH 1033/5560] [SCSI] be2iscsi: Modifying Maintainer's emailid - Modifying Maintainer's emailid to emulex as Emulex has acquired Serverengines Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index ec3600306289..4f68fa787fff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5596,9 +5596,9 @@ F: include/linux/ata.h F: include/linux/libata.h SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER -M: Jayamohan Kallickal +M: Jayamohan Kallickal L: linux-scsi@vger.kernel.org -W: http://www.serverengines.com +W: http://www.emulex.com S: Supported F: drivers/scsi/be2iscsi/ -- GitLab From 91eefa894add1617200c70d3886773e608de7a03 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Fri, 25 Mar 2011 14:23:59 -0700 Subject: [PATCH 1034/5560] [SCSI] be2iscsi: Set a timeout to FW Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley --- drivers/scsi/be2iscsi/be_cmds.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 4ffcbf751695..b8a82f2c62c8 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -458,6 +458,7 @@ void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, req_hdr->opcode = opcode; req_hdr->subsystem = subsystem; req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); + req_hdr->timeout = 120; } static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, -- GitLab From 0b1d3cbf51f75eaaabdb904f02362368487e2aa7 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Fri, 25 Mar 2011 14:24:00 -0700 Subject: [PATCH 1035/5560] [SCSI] be2iscsi: check boot_kset is created before destroying it Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley --- drivers/scsi/be2iscsi/be_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 7fe38a49bbb7..91b354daf94b 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -420,7 +420,8 @@ static int beiscsi_setup_boot_info(struct beiscsi_hba *phba) return 0; free_kset: - iscsi_boot_destroy_kset(phba->boot_kset); + if (phba->boot_kset) + iscsi_boot_destroy_kset(phba->boot_kset); return -ENOMEM; } @@ -4144,10 +4145,11 @@ static void beiscsi_remove(struct pci_dev *pcidev) phba->ctrl.mbox_mem_alloced.size, phba->ctrl.mbox_mem_alloced.va, phba->ctrl.mbox_mem_alloced.dma); + if (phba->boot_kset) + iscsi_boot_destroy_kset(phba->boot_kset); iscsi_host_remove(phba->shost); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); - iscsi_boot_destroy_kset(phba->boot_kset); } static void beiscsi_msix_enable(struct beiscsi_hba *phba) -- GitLab From 1390b01b26300d42662e436d8f1d307c4e0903c7 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Fri, 25 Mar 2011 14:24:01 -0700 Subject: [PATCH 1036/5560] [SCSI] be2iscsi: Fix for proper setting of FW There was a bug in setting up type and dmsg for FW Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley --- drivers/scsi/be2iscsi/be_main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 91b354daf94b..d83413658a9d 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4020,12 +4020,17 @@ static int beiscsi_mtask(struct iscsi_task *task) hwi_write_buffer(pwrb, task); break; case ISCSI_OP_NOOP_OUT: - AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, - INI_RD_CMD); - if (task->hdr->ttt == ISCSI_RESERVED_TAG) + if (task->hdr->ttt != ISCSI_RESERVED_TAG) { + AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, + TGT_DM_CMD); + AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, + pwrb, 0); AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); - else + } else { + AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, + INI_RD_CMD); AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); + } hwi_write_buffer(pwrb, task); break; case ISCSI_OP_TEXT: -- GitLab From bd015928bb1713691068c4d0d159afccbaf0f8c0 Mon Sep 17 00:00:00 2001 From: Daniel Walter Date: Wed, 13 Apr 2011 21:09:25 +0000 Subject: [PATCH 1037/5560] ipv6: ignore looped-back NA while dad is running [ipv6] Ignore looped-back NAs while in Duplicate Address Detection If we send an unsolicited NA shortly after bringing up an IPv6 address, the duplicate address detection algorithm fails and the ip stays in tentative mode forever. This is due a missing check if the NA is looped-back to us. Signed-off-by: Daniel Walter Signed-off-by: David S. Miller --- net/ipv6/ndisc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 92f952d093db..f057ff312840 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -945,9 +945,10 @@ static void ndisc_recv_na(struct sk_buff *skb) } ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1); if (ifp) { - if (ifp->flags & IFA_F_TENTATIVE) { - addrconf_dad_failure(ifp); - return; + if (skb->pkt_type != PACKET_LOOPBACK + && (ifp->flags & IFA_F_TENTATIVE)) { + addrconf_dad_failure(ifp); + return; } /* What should we make now? The advertisement is invalid, but ndisc specs say nothing -- GitLab From c3968a857a6b6c3d2ef4ead35776b055fb664d74 Mon Sep 17 00:00:00 2001 From: Daniel Walter Date: Wed, 13 Apr 2011 21:10:57 +0000 Subject: [PATCH 1038/5560] ipv6: RTA_PREFSRC support for ipv6 route source address selection [ipv6] Add support for RTA_PREFSRC This patch allows a user to select the preferred source address for a specific IPv6-Route. It can be set via a netlink message setting RTA_PREFSRC to a valid IPv6 address which must be up on the device the route will be bound to. Signed-off-by: Daniel Walter Signed-off-by: David S. Miller --- include/net/ip6_fib.h | 2 ++ include/net/ip6_route.h | 7 ++++ net/ipv6/addrconf.c | 2 ++ net/ipv6/ip6_output.c | 8 ++--- net/ipv6/route.c | 72 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 84 insertions(+), 7 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index bc3cde0a810c..98348d53b2b6 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -42,6 +42,7 @@ struct fib6_config { struct in6_addr fc_dst; struct in6_addr fc_src; + struct in6_addr fc_prefsrc; struct in6_addr fc_gateway; unsigned long fc_expires; @@ -107,6 +108,7 @@ struct rt6_info { struct rt6key rt6i_dst ____cacheline_aligned_in_smp; u32 rt6i_flags; struct rt6key rt6i_src; + struct rt6key rt6i_prefsrc; u32 rt6i_metric; u32 rt6i_peer_genid; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index c850e5fb967c..86b1cb486903 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -84,6 +84,12 @@ extern int ip6_route_add(struct fib6_config *cfg); extern int ip6_ins_rt(struct rt6_info *); extern int ip6_del_rt(struct rt6_info *); +extern int ip6_route_get_saddr(struct net *net, + struct rt6_info *rt, + struct in6_addr *daddr, + unsigned int prefs, + struct in6_addr *saddr); + extern struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, const struct in6_addr *saddr, @@ -141,6 +147,7 @@ struct rt6_rtnl_dump_arg { extern int rt6_dump_route(struct rt6_info *rt, void *p_arg); extern void rt6_ifdown(struct net *net, struct net_device *dev); extern void rt6_mtu_change(struct net_device *dev, unsigned mtu); +extern void rt6_remove_prefsrc(struct inet6_ifaddr *ifp); /* diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1493534116df..129d7e1f311c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -825,6 +825,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) dst_release(&rt->dst); } + /* clean up prefsrc entries */ + rt6_remove_prefsrc(ifp); out: in6_ifa_put(ifp); } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 46cf7bea6769..c614d02bf429 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -930,10 +930,10 @@ static int ip6_dst_lookup_tail(struct sock *sk, goto out_err_release; if (ipv6_addr_any(&fl6->saddr)) { - err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, - &fl6->daddr, - sk ? inet6_sk(sk)->srcprefs : 0, - &fl6->saddr); + struct rt6_info *rt = (struct rt6_info *) *dst; + err = ip6_route_get_saddr(net, rt, &fl6->daddr, + sk ? inet6_sk(sk)->srcprefs : 0, + &fl6->saddr); if (err) goto out_err_release; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 843406f14d7b..af26cc1073cb 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1325,6 +1325,16 @@ int ip6_route_add(struct fib6_config *cfg) if (dev == NULL) goto out; + if (!ipv6_addr_any(&cfg->fc_prefsrc)) { + if (!ipv6_chk_addr(net, &cfg->fc_prefsrc, dev, 0)) { + err = -EINVAL; + goto out; + } + ipv6_addr_copy(&rt->rt6i_prefsrc.addr, &cfg->fc_prefsrc); + rt->rt6i_prefsrc.plen = 128; + } else + rt->rt6i_prefsrc.plen = 0; + if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) { rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); if (IS_ERR(rt->rt6i_nexthop)) { @@ -2037,6 +2047,55 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, return rt; } +int ip6_route_get_saddr(struct net *net, + struct rt6_info *rt, + struct in6_addr *daddr, + unsigned int prefs, + struct in6_addr *saddr) +{ + struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt); + int err = 0; + if (rt->rt6i_prefsrc.plen) + ipv6_addr_copy(saddr, &rt->rt6i_prefsrc.addr); + else + err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, + daddr, prefs, saddr); + return err; +} + +/* remove deleted ip from prefsrc entries */ +struct arg_dev_net_ip { + struct net_device *dev; + struct net *net; + struct in6_addr *addr; +}; + +static int fib6_remove_prefsrc(struct rt6_info *rt, void *arg) +{ + struct net_device *dev = ((struct arg_dev_net_ip *)arg)->dev; + struct net *net = ((struct arg_dev_net_ip *)arg)->net; + struct in6_addr *addr = ((struct arg_dev_net_ip *)arg)->addr; + + if (((void *)rt->rt6i_dev == dev || dev == NULL) && + rt != net->ipv6.ip6_null_entry && + ipv6_addr_equal(addr, &rt->rt6i_prefsrc.addr)) { + /* remove prefsrc entry */ + rt->rt6i_prefsrc.plen = 0; + } + return 0; +} + +void rt6_remove_prefsrc(struct inet6_ifaddr *ifp) +{ + struct net *net = dev_net(ifp->idev->dev); + struct arg_dev_net_ip adni = { + .dev = ifp->idev->dev, + .net = net, + .addr = &ifp->addr, + }; + fib6_clean_all(net, fib6_remove_prefsrc, 0, &adni); +} + struct arg_dev_net { struct net_device *dev; struct net *net; @@ -2183,6 +2242,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen); } + if (tb[RTA_PREFSRC]) + nla_memcpy(&cfg->fc_prefsrc, tb[RTA_PREFSRC], 16); + if (tb[RTA_OIF]) cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]); @@ -2325,13 +2387,17 @@ static int rt6_fill_node(struct net *net, #endif NLA_PUT_U32(skb, RTA_IIF, iif); } else if (dst) { - struct inet6_dev *idev = ip6_dst_idev(&rt->dst); struct in6_addr saddr_buf; - if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, - dst, 0, &saddr_buf) == 0) + if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0) NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); } + if (rt->rt6i_prefsrc.plen) { + struct in6_addr saddr_buf; + ipv6_addr_copy(&saddr_buf, &rt->rt6i_prefsrc.addr); + NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); + } + if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) goto nla_put_failure; -- GitLab From 911cb193f3eb0370f20fbba712211e55ffede4de Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Fri, 15 Apr 2011 02:26:25 +0000 Subject: [PATCH 1039/5560] net: minor cleanup to net_namespace.c. Inline a small static function that's only ever called from one place. Signed-off-by: Rob Landley Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller --- net/core/net_namespace.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 3f860261c5ee..1abb50841046 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -216,11 +216,14 @@ static void net_free(struct net *net) kmem_cache_free(net_cachep, net); } -static struct net *net_create(void) +struct net *copy_net_ns(unsigned long flags, struct net *old_net) { struct net *net; int rv; + if (!(flags & CLONE_NEWNET)) + return get_net(old_net); + net = net_alloc(); if (!net) return ERR_PTR(-ENOMEM); @@ -239,13 +242,6 @@ static struct net *net_create(void) return net; } -struct net *copy_net_ns(unsigned long flags, struct net *old_net) -{ - if (!(flags & CLONE_NEWNET)) - return get_net(old_net); - return net_create(); -} - static DEFINE_SPINLOCK(cleanup_list_lock); static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */ -- GitLab From 6de240b7f714d63ca2a53d52c7eefb37e7eb3f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:49 +0000 Subject: [PATCH 1040/5560] net: spider_net: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/spider_net.c | 15 +++++++-------- drivers/net/spider_net.h | 7 ------- drivers/net/spider_net_ethtool.c | 21 --------------------- 3 files changed, 7 insertions(+), 36 deletions(-) diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index cb6bcca9d541..949f124e1278 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -994,15 +994,13 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, skb->protocol = eth_type_trans(skb, netdev); /* checksum offload */ - if (card->options.rx_csum) { + skb_checksum_none_assert(skb); + if (netdev->features & NETIF_F_RXCSUM) { if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) == SPIDER_NET_DATA_STATUS_CKSUM_MASK) && !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb_checksum_none_assert(skb); - } else - skb_checksum_none_assert(skb); + } if (data_status & SPIDER_NET_VLAN_PACKET) { /* further enhancements: HW-accel VLAN @@ -2322,14 +2320,15 @@ spider_net_setup_netdev(struct spider_net_card *card) card->aneg_timer.function = spider_net_link_phy; card->aneg_timer.data = (unsigned long) card; - card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; - netif_napi_add(netdev, &card->napi, spider_net_poll, SPIDER_NET_NAPI_WEIGHT); spider_net_setup_netdev_ops(netdev); - netdev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX; + netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM; + if (SPIDER_NET_RX_CSUM_DEFAULT) + netdev->features |= NETIF_F_RXCSUM; + netdev->features |= NETIF_F_IP_CSUM | NETIF_F_LLTX; /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | * NETIF_F_HW_VLAN_FILTER */ diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 05f74cbdd617..020f64a8fcf7 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -429,12 +429,6 @@ struct spider_net_descr_chain { * 701b8000 would be correct, but every packets gets that flag */ #define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000 -/* this will be bigger some time */ -struct spider_net_options { - int rx_csum; /* for rx: if 0 ip_summed=NONE, - if 1 and hw has verified, ip_summed=UNNECESSARY */ -}; - #define SPIDER_NET_DEFAULT_MSG ( NETIF_MSG_DRV | \ NETIF_MSG_PROBE | \ NETIF_MSG_LINK | \ @@ -487,7 +481,6 @@ struct spider_net_card { /* for ethtool */ int msg_enable; struct spider_net_extra_stats spider_stats; - struct spider_net_options options; /* Must be last item in struct */ struct spider_net_descr darray[0]; diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c index 5bae728c3820..d723fca872ce 100644 --- a/drivers/net/spider_net_ethtool.c +++ b/drivers/net/spider_net_ethtool.c @@ -115,24 +115,6 @@ spider_net_ethtool_nway_reset(struct net_device *netdev) return 0; } -static u32 -spider_net_ethtool_get_rx_csum(struct net_device *netdev) -{ - struct spider_net_card *card = netdev_priv(netdev); - - return card->options.rx_csum; -} - -static int -spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n) -{ - struct spider_net_card *card = netdev_priv(netdev); - - card->options.rx_csum = n; - return 0; -} - - static void spider_net_ethtool_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ering) @@ -189,9 +171,6 @@ const struct ethtool_ops spider_net_ethtool_ops = { .set_msglevel = spider_net_ethtool_set_msglevel, .get_link = ethtool_op_get_link, .nway_reset = spider_net_ethtool_nway_reset, - .get_rx_csum = spider_net_ethtool_get_rx_csum, - .set_rx_csum = spider_net_ethtool_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, .get_ringparam = spider_net_ethtool_get_ringparam, .get_strings = spider_net_get_strings, .get_sset_count = spider_net_get_sset_count, -- GitLab From c88fcb3d8265cf473c73bc147a2aa21ae03abf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:49 +0000 Subject: [PATCH 1041/5560] net: dm9000: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 57 ++++++++++---------------------------------- 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index b7af5bab9937..f7bdebbcb908 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -131,8 +131,6 @@ typedef struct board_info { u32 msg_enable; u32 wake_state; - int rx_csum; - int can_csum; int ip_summed; } board_info_t; @@ -470,47 +468,20 @@ static int dm9000_nway_reset(struct net_device *dev) return mii_nway_restart(&dm->mii); } -static uint32_t dm9000_get_rx_csum(struct net_device *dev) +static int dm9000_set_features(struct net_device *dev, u32 features) { board_info_t *dm = to_dm9000_board(dev); - return dm->rx_csum; -} - -static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data) -{ - board_info_t *dm = to_dm9000_board(dev); - - if (dm->can_csum) { - dm->rx_csum = data; - iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0); + u32 changed = dev->features ^ features; + unsigned long flags; + if (!(changed & NETIF_F_RXCSUM)) return 0; - } - - return -EOPNOTSUPP; -} - -static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data) -{ - board_info_t *dm = to_dm9000_board(dev); - unsigned long flags; - int ret; spin_lock_irqsave(&dm->lock, flags); - ret = dm9000_set_rx_csum_unlocked(dev, data); + iow(dm, DM9000_RCSR, (features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0); spin_unlock_irqrestore(&dm->lock, flags); - return ret; -} - -static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data) -{ - board_info_t *dm = to_dm9000_board(dev); - int ret = -EOPNOTSUPP; - - if (dm->can_csum) - ret = ethtool_op_set_tx_csum(dev, data); - return ret; + return 0; } static u32 dm9000_get_link(struct net_device *dev) @@ -643,10 +614,6 @@ static const struct ethtool_ops dm9000_ethtool_ops = { .get_eeprom_len = dm9000_get_eeprom_len, .get_eeprom = dm9000_get_eeprom, .set_eeprom = dm9000_set_eeprom, - .get_rx_csum = dm9000_get_rx_csum, - .set_rx_csum = dm9000_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = dm9000_set_tx_csum, }; static void dm9000_show_carrier(board_info_t *db, @@ -800,7 +767,9 @@ dm9000_init_dm9000(struct net_device *dev) db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ /* Checksum mode */ - dm9000_set_rx_csum_unlocked(dev, db->rx_csum); + if (dev->hw_features & NETIF_F_RXCSUM) + iow(dm, DM9000_RCSR, + (dev->features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0); iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ @@ -1049,7 +1018,7 @@ dm9000_rx(struct net_device *dev) /* Pass to upper layer */ skb->protocol = eth_type_trans(skb, dev); - if (db->rx_csum) { + if (dev->features & NETIF_F_RXCSUM) { if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0) skb->ip_summed = CHECKSUM_UNNECESSARY; else @@ -1358,6 +1327,7 @@ static const struct net_device_ops dm9000_netdev_ops = { .ndo_set_multicast_list = dm9000_hash_table, .ndo_do_ioctl = dm9000_ioctl, .ndo_change_mtu = eth_change_mtu, + .ndo_set_features = dm9000_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1551,9 +1521,8 @@ dm9000_probe(struct platform_device *pdev) /* dm9000a/b are capable of hardware checksum offload */ if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) { - db->can_csum = 1; - db->rx_csum = 1; - ndev->features |= NETIF_F_IP_CSUM; + ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM; + ndev->features |= ndev->hw_features; } /* from this point we assume that we have found a DM9000 */ -- GitLab From 569e146396cb3b378d2957b94671bf30cd777c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:49 +0000 Subject: [PATCH 1042/5560] net: forcedeth: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also fixes a race around np->txrxctl_bits while changing RXCSUM offload. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 78 ++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d5ab4dad5051..ec9a32d01e61 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -774,7 +774,6 @@ struct fe_priv { u32 driver_data; u32 device_id; u32 register_size; - int rx_csum; u32 mac_in_use; int mgmt_version; int mgmt_sema; @@ -4480,58 +4479,36 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* return 0; } -static u32 nv_get_rx_csum(struct net_device *dev) +static u32 nv_fix_features(struct net_device *dev, u32 features) { - struct fe_priv *np = netdev_priv(dev); - return np->rx_csum != 0; + /* vlan is dependent on rx checksum offload */ + if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) + features |= NETIF_F_RXCSUM; + + return features; } -static int nv_set_rx_csum(struct net_device *dev, u32 data) +static int nv_set_features(struct net_device *dev, u32 features) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - int retcode = 0; + u32 changed = dev->features ^ features; - if (np->driver_data & DEV_HAS_CHECKSUM) { - if (data) { - np->rx_csum = 1; - np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; - } else { - np->rx_csum = 0; - /* vlan is dependent on rx checksum offload */ - if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) - np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; - } - if (netif_running(dev)) { - spin_lock_irq(&np->lock); - writel(np->txrxctl_bits, base + NvRegTxRxControl); - spin_unlock_irq(&np->lock); - } - } else { - return -EINVAL; - } - - return retcode; -} + if (changed & NETIF_F_RXCSUM) { + spin_lock_irq(&np->lock); -static int nv_set_tx_csum(struct net_device *dev, u32 data) -{ - struct fe_priv *np = netdev_priv(dev); + if (features & NETIF_F_RXCSUM) + np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; + else + np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; - if (np->driver_data & DEV_HAS_CHECKSUM) - return ethtool_op_set_tx_csum(dev, data); - else - return -EOPNOTSUPP; -} + if (netif_running(dev)) + writel(np->txrxctl_bits, base + NvRegTxRxControl); -static int nv_set_sg(struct net_device *dev, u32 data) -{ - struct fe_priv *np = netdev_priv(dev); + spin_unlock_irq(&np->lock); + } - if (np->driver_data & DEV_HAS_CHECKSUM) - return ethtool_op_set_sg(dev, data); - else - return -EOPNOTSUPP; + return 0; } static int nv_get_sset_count(struct net_device *dev, int sset) @@ -4896,15 +4873,10 @@ static const struct ethtool_ops ops = { .get_regs_len = nv_get_regs_len, .get_regs = nv_get_regs, .nway_reset = nv_nway_reset, - .set_tso = nv_set_tso, .get_ringparam = nv_get_ringparam, .set_ringparam = nv_set_ringparam, .get_pauseparam = nv_get_pauseparam, .set_pauseparam = nv_set_pauseparam, - .get_rx_csum = nv_get_rx_csum, - .set_rx_csum = nv_set_rx_csum, - .set_tx_csum = nv_set_tx_csum, - .set_sg = nv_set_sg, .get_strings = nv_get_strings, .get_ethtool_stats = nv_get_ethtool_stats, .get_sset_count = nv_get_sset_count, @@ -5235,6 +5207,8 @@ static const struct net_device_ops nv_netdev_ops = { .ndo_start_xmit = nv_start_xmit, .ndo_tx_timeout = nv_tx_timeout, .ndo_change_mtu = nv_change_mtu, + .ndo_fix_features = nv_fix_features, + .ndo_set_features = nv_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, @@ -5251,6 +5225,8 @@ static const struct net_device_ops nv_netdev_ops_optimized = { .ndo_start_xmit = nv_start_xmit_optimized, .ndo_tx_timeout = nv_tx_timeout, .ndo_change_mtu = nv_change_mtu, + .ndo_fix_features = nv_fix_features, + .ndo_set_features = nv_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, @@ -5364,11 +5340,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->pkt_limit = NV_PKTLIMIT_2; if (id->driver_data & DEV_HAS_CHECKSUM) { - np->rx_csum = 1; np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; - dev->features |= NETIF_F_TSO; - dev->features |= NETIF_F_GRO; + dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_RXCSUM; + dev->features |= dev->hw_features; } np->vlanctl_bits = 0; @@ -5384,7 +5359,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ; } - err = -ENOMEM; np->base = ioremap(addr, np->register_size); if (!np->base) -- GitLab From c8c64cff2c88b17fdd7402dd06288d7415896430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:49 +0000 Subject: [PATCH 1043/5560] net: mlx4: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/mlx4/en_ethtool.c | 42 ----------------------------------- drivers/net/mlx4/en_netdev.c | 26 +++++++++------------- drivers/net/mlx4/en_rx.c | 2 +- drivers/net/mlx4/mlx4_en.h | 1 - 4 files changed, 11 insertions(+), 60 deletions(-) diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index d54b7abf0225..da1b64d68607 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -57,37 +57,6 @@ mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) drvinfo->eedump_len = 0; } -static u32 mlx4_en_get_tso(struct net_device *dev) -{ - return (dev->features & NETIF_F_TSO) != 0; -} - -static int mlx4_en_set_tso(struct net_device *dev, u32 data) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - - if (data) { - if (!priv->mdev->LSO_support) - return -EPERM; - dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); - } else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - return 0; -} - -static u32 mlx4_en_get_rx_csum(struct net_device *dev) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - return priv->rx_csum; -} - -static int mlx4_en_set_rx_csum(struct net_device *dev, u32 data) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - priv->rx_csum = (data != 0); - return 0; -} - static const char main_strings[][ETH_GSTRING_LEN] = { "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", @@ -483,17 +452,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_drvinfo = mlx4_en_get_drvinfo, .get_settings = mlx4_en_get_settings, .set_settings = mlx4_en_set_settings, -#ifdef NETIF_F_TSO - .get_tso = mlx4_en_get_tso, - .set_tso = mlx4_en_set_tso, -#endif - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, - .get_rx_csum = mlx4_en_get_rx_csum, - .set_rx_csum = mlx4_en_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_ipv6_csum, .get_strings = mlx4_en_get_strings, .get_sset_count = mlx4_en_get_sset_count, .get_ethtool_stats = mlx4_en_get_ethtool_stats, @@ -508,7 +467,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .set_pauseparam = mlx4_en_set_pauseparam, .get_ringparam = mlx4_en_get_ringparam, .set_ringparam = mlx4_en_set_ringparam, - .get_flags = ethtool_op_get_flags, }; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 77063f91c564..61850adae6f7 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -1083,7 +1083,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->prof = prof; priv->port = port; priv->port_up = false; - priv->rx_csum = 1; priv->flags = prof->flags; priv->tx_ring_num = prof->tx_ring_num; priv->rx_ring_num = prof->rx_ring_num; @@ -1141,21 +1140,16 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, /* * Set driver features */ - dev->features |= NETIF_F_SG; - dev->vlan_features |= NETIF_F_SG; - dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - dev->features |= NETIF_F_HIGHDMA; - dev->features |= NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; - dev->features |= NETIF_F_GRO; - if (mdev->LSO_support) { - dev->features |= NETIF_F_TSO; - dev->features |= NETIF_F_TSO6; - dev->vlan_features |= NETIF_F_TSO; - dev->vlan_features |= NETIF_F_TSO6; - } + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + if (mdev->LSO_support) + dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; + + dev->vlan_features = dev->hw_features; + + dev->hw_features |= NETIF_F_RXCSUM; + dev->features = dev->hw_features | NETIF_F_HIGHDMA | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; mdev->pndev[port] = dev; diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 62dd21b06df4..277215fb9d72 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -584,7 +584,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud ring->bytes += length; ring->packets++; - if (likely(priv->rx_csum)) { + if (likely(dev->features & NETIF_F_RXCSUM)) { if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) && (cqe->checksum == cpu_to_be16(0xffff))) { priv->port_stats.rx_chksum_good++; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index e30f6099c0de..0b5150df0585 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -451,7 +451,6 @@ struct mlx4_en_priv { int registered; int allocated; int stride; - int rx_csum; u64 mac; int mac_index; unsigned max_mtu; -- GitLab From 8b3afe95e363dbd32bd9ddc6c2d562944f5350c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:50 +0000 Subject: [PATCH 1044/5560] net: gianfar: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: I bet that gfar_set_features() don't really need a full reset. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 16 +++++----- drivers/net/gianfar.h | 3 +- drivers/net/gianfar_ethtool.c | 58 +++-------------------------------- 3 files changed, 16 insertions(+), 61 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 2a0ad9a501bb..ff60b23a5b74 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -365,7 +365,7 @@ static void gfar_init_mac(struct net_device *ndev) gfar_write(®s->rir0, DEFAULT_RIR0); } - if (priv->rx_csum_enable) + if (ndev->features & NETIF_F_RXCSUM) rctrl |= RCTRL_CHECKSUMMING; if (priv->extended_hash) { @@ -463,6 +463,7 @@ static const struct net_device_ops gfar_netdev_ops = { .ndo_start_xmit = gfar_start_xmit, .ndo_stop = gfar_close, .ndo_change_mtu = gfar_change_mtu, + .ndo_set_features = gfar_set_features, .ndo_set_multicast_list = gfar_set_multi, .ndo_tx_timeout = gfar_timeout, .ndo_do_ioctl = gfar_ioctl, @@ -513,7 +514,7 @@ void unlock_tx_qs(struct gfar_private *priv) /* Returns 1 if incoming frames use an FCB */ static inline int gfar_uses_fcb(struct gfar_private *priv) { - return priv->vlgrp || priv->rx_csum_enable || + return priv->vlgrp || (priv->ndev->features & NETIF_F_RXCSUM) || (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); } @@ -1030,10 +1031,11 @@ static int gfar_probe(struct platform_device *ofdev) netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, GFAR_DEV_WEIGHT); if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { - priv->rx_csum_enable = 1; - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA; - } else - priv->rx_csum_enable = 0; + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_RXCSUM; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_RXCSUM | NETIF_F_HIGHDMA; + } priv->vlgrp = NULL; @@ -2697,7 +2699,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, if (priv->padding) skb_pull(skb, priv->padding); - if (priv->rx_csum_enable) + if (dev->features & NETIF_F_RXCSUM) gfar_rx_checksum(skb, fcb); /* Tell the skb what kind of packet this is */ diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 0438d3551d5c..fc86f5195445 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -1083,7 +1083,7 @@ struct gfar_private { struct device_node *phy_node; struct device_node *tbi_node; u32 device_flags; - unsigned char rx_csum_enable:1, + unsigned char extended_hash:1, bd_stash_en:1, rx_filer_enable:1, @@ -1153,6 +1153,7 @@ extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, extern void gfar_configure_coalescing(struct gfar_private *priv, unsigned long tx_mask, unsigned long rx_mask); void gfar_init_sysfs(struct net_device *dev); +int gfar_set_features(struct net_device *dev, u32 features); extern const struct ethtool_ops gfar_ethtool_ops; diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 0840590958dd..493d743839d9 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -517,15 +517,15 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva return err; } -static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) +int gfar_set_features(struct net_device *dev, u32 features) { struct gfar_private *priv = netdev_priv(dev); unsigned long flags; int err = 0, i = 0; + u32 changed = dev->features ^ features; - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) - return -EOPNOTSUPP; - + if (!(changed & NETIF_F_RXCSUM)) + return 0; if (dev->flags & IFF_UP) { /* Halt TX and RX, and process the frames which @@ -546,58 +546,15 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) /* Now we take down the rings to rebuild them */ stop_gfar(dev); - } - spin_lock_irqsave(&priv->bflock, flags); - priv->rx_csum_enable = data; - spin_unlock_irqrestore(&priv->bflock, flags); + dev->features = features; - if (dev->flags & IFF_UP) { err = startup_gfar(dev); netif_tx_wake_all_queues(dev); } return err; } -static uint32_t gfar_get_rx_csum(struct net_device *dev) -{ - struct gfar_private *priv = netdev_priv(dev); - - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) - return 0; - - return priv->rx_csum_enable; -} - -static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) -{ - struct gfar_private *priv = netdev_priv(dev); - - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) - return -EOPNOTSUPP; - - netif_tx_lock_bh(dev); - - if (data) - dev->features |= NETIF_F_IP_CSUM; - else - dev->features &= ~NETIF_F_IP_CSUM; - - netif_tx_unlock_bh(dev); - - return 0; -} - -static uint32_t gfar_get_tx_csum(struct net_device *dev) -{ - struct gfar_private *priv = netdev_priv(dev); - - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) - return 0; - - return (dev->features & NETIF_F_IP_CSUM) != 0; -} - static uint32_t gfar_get_msglevel(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); @@ -844,11 +801,6 @@ const struct ethtool_ops gfar_ethtool_ops = { .get_strings = gfar_gstrings, .get_sset_count = gfar_sset_count, .get_ethtool_stats = gfar_fill_stats, - .get_rx_csum = gfar_get_rx_csum, - .get_tx_csum = gfar_get_tx_csum, - .set_rx_csum = gfar_set_rx_csum, - .set_tx_csum = gfar_set_tx_csum, - .set_sg = ethtool_op_set_sg, .get_msglevel = gfar_get_msglevel, .set_msglevel = gfar_set_msglevel, #ifdef CONFIG_PM -- GitLab From a35d4e58737116fd4126c240a1faeb735839435e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 7 Apr 2011 19:50:10 +0100 Subject: [PATCH 1045/5560] ARM: 6871/1: Use asm-generic/sizes.h Commit d232b12 (asm-generic headers: add sizes.h, 2011-01-15) introduced a generic sizes.h. Use that instead of the ARM specific version. Cc: Arnd Bergmann Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/include/asm/sizes.h | 42 ++---------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h index 316bb2b2be3d..154b89b81d3e 100644 --- a/arch/arm/include/asm/sizes.h +++ b/arch/arm/include/asm/sizes.h @@ -16,44 +16,6 @@ /* Size definitions * Copyright (C) ARM Limited 1998. All rights reserved. */ +#include -#ifndef __sizes_h -#define __sizes_h 1 - -/* handy sizes */ -#define SZ_16 0x00000010 -#define SZ_32 0x00000020 -#define SZ_64 0x00000040 -#define SZ_128 0x00000080 -#define SZ_256 0x00000100 -#define SZ_512 0x00000200 - -#define SZ_1K 0x00000400 -#define SZ_2K 0x00000800 -#define SZ_4K 0x00001000 -#define SZ_8K 0x00002000 -#define SZ_16K 0x00004000 -#define SZ_32K 0x00008000 -#define SZ_64K 0x00010000 -#define SZ_128K 0x00020000 -#define SZ_256K 0x00040000 -#define SZ_512K 0x00080000 - -#define SZ_1M 0x00100000 -#define SZ_2M 0x00200000 -#define SZ_4M 0x00400000 -#define SZ_8M 0x00800000 -#define SZ_16M 0x01000000 -#define SZ_32M 0x02000000 -#define SZ_48M 0x03000000 -#define SZ_64M 0x04000000 -#define SZ_128M 0x08000000 -#define SZ_256M 0x10000000 -#define SZ_512M 0x20000000 - -#define SZ_1G 0x40000000 -#define SZ_2G 0x80000000 - -#endif - -/* END */ +#define SZ_48M (SZ_32M + SZ_16M) -- GitLab From dd182574d86e22faaaed37db79e3d54e773f29f7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:03:38 -0700 Subject: [PATCH 1046/5560] atm: eni: Kill set-but-unused variables. The variable eni_dev is initialized but never subsequently used in these two functions. Signed-off-by: David S. Miller --- drivers/atm/eni.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index c495fae74200..3230ea0df83c 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -1469,10 +1469,7 @@ if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost); static void bug_int(struct atm_dev *dev,unsigned long reason) { - struct eni_dev *eni_dev; - DPRINTK(">bug_int\n"); - eni_dev = ENI_DEV(dev); if (reason & MID_DMA_ERR_ACK) printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA " "error\n",dev->number); @@ -1900,7 +1897,6 @@ static void eni_close(struct atm_vcc *vcc) static int eni_open(struct atm_vcc *vcc) { - struct eni_dev *eni_dev; struct eni_vcc *eni_vcc; int error; short vpi = vcc->vpi; @@ -1910,7 +1906,6 @@ static int eni_open(struct atm_vcc *vcc) EVENT("eni_open\n",0,0); if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) vcc->dev_data = NULL; - eni_dev = ENI_DEV(vcc->dev); if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC) set_bit(ATM_VF_ADDR,&vcc->flags); if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5) -- GitLab From e60c5e14fbfcaa54f430aad80b38763a403b2158 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:07:55 -0700 Subject: [PATCH 1047/5560] atm: he: Fix undefined sequence points. GCC complains in these queue index operations because we perform operations of the form: x = some_operation(++x); which is undefined. Replace with: x = some_operation(x + 1); which is well defined and provides the intended operation. Signed-off-by: David S. Miller --- drivers/atm/he.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 6cf59bf281dc..9a51df4f5b74 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -1801,7 +1801,7 @@ he_service_rbrq(struct he_dev *he_dev, int group) next_rbrq_entry: he_dev->rbrq_head = (struct he_rbrq *) ((unsigned long) he_dev->rbrq_base | - RBRQ_MASK(++he_dev->rbrq_head)); + RBRQ_MASK(he_dev->rbrq_head + 1)); } read_unlock(&vcc_sklist_lock); @@ -1884,7 +1884,7 @@ he_service_tbrq(struct he_dev *he_dev, int group) pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); he_dev->tbrq_head = (struct he_tbrq *) ((unsigned long) he_dev->tbrq_base | - TBRQ_MASK(++he_dev->tbrq_head)); + TBRQ_MASK(he_dev->tbrq_head + 1)); } if (updated) { -- GitLab From edb4dcb717d71f63c5147d7bef3014f96d192842 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:10:17 -0700 Subject: [PATCH 1048/5560] atm: idt77252: Fix set-but-unused variables. Two cases here: 1) idt77252_rx_raw() really does not make any use of the extracted PTI field of the atm header. 2) idt77252_collect_stat() only uses the register values in code which has been compiled out by a "NOTDEF" cpp test for more than 10 years. Just kill this NOTDEF code entirely, but keep the register reads in case they have side effects. Signed-off-by: David S. Miller --- drivers/atm/idt77252.c | 52 ++++-------------------------------------- 1 file changed, 4 insertions(+), 48 deletions(-) diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 048f99fe6f83..1f8d724a18bf 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -1261,14 +1261,13 @@ idt77252_rx_raw(struct idt77252_dev *card) PCI_DMA_FROMDEVICE); while (head != tail) { - unsigned int vpi, vci, pti; + unsigned int vpi, vci; u32 header; header = le32_to_cpu(*(u32 *) &queue->data[0]); vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT; vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT; - pti = (header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT; #ifdef CONFIG_ATM_IDT77252_DEBUG if (debug & DBG_RAW_CELL) { @@ -2709,53 +2708,10 @@ idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page) static void idt77252_collect_stat(struct idt77252_dev *card) { - u32 cdc, vpec, icc; + (void) readl(SAR_REG_CDC); + (void) readl(SAR_REG_VPEC); + (void) readl(SAR_REG_ICC); - cdc = readl(SAR_REG_CDC); - vpec = readl(SAR_REG_VPEC); - icc = readl(SAR_REG_ICC); - -#ifdef NOTDEF - printk("%s:", card->name); - - if (cdc & 0x7f0000) { - char *s = ""; - - printk(" ["); - if (cdc & (1 << 22)) { - printk("%sRM ID", s); - s = " | "; - } - if (cdc & (1 << 21)) { - printk("%sCON TAB", s); - s = " | "; - } - if (cdc & (1 << 20)) { - printk("%sNO FB", s); - s = " | "; - } - if (cdc & (1 << 19)) { - printk("%sOAM CRC", s); - s = " | "; - } - if (cdc & (1 << 18)) { - printk("%sRM CRC", s); - s = " | "; - } - if (cdc & (1 << 17)) { - printk("%sRM FIFO", s); - s = " | "; - } - if (cdc & (1 << 16)) { - printk("%sRX FIFO", s); - s = " | "; - } - printk("]"); - } - - printk(" CDC %04x, VPEC %04x, ICC: %04x\n", - cdc & 0xffff, vpec & 0xffff, icc & 0xffff); -#endif } static irqreturn_t -- GitLab From 06091ed6b8ec726e6cbc7e40ee6b5aa2332cf381 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:11:25 -0700 Subject: [PATCH 1049/5560] atm: solos-pci: Fix set-but-unused variable. This is just a readback to entire completion of a register write, keep the readback but kill the unused variable. Signed-off-by: David S. Miller --- drivers/atm/solos-pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index cd0ff66469b2..5d1d07645132 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -527,7 +527,6 @@ static int flash_upgrade(struct solos_card *card, int chip) { const struct firmware *fw; const char *fw_name; - uint32_t data32 = 0; int blocksize = 0; int numblocks = 0; int offset; @@ -576,7 +575,7 @@ static int flash_upgrade(struct solos_card *card, int chip) dev_info(&card->dev->dev, "Changing FPGA to Update mode\n"); iowrite32(1, card->config_regs + FPGA_MODE); - data32 = ioread32(card->config_regs + FPGA_MODE); + (void) ioread32(card->config_regs + FPGA_MODE); /* Set mode to Chip Erase */ if(chip == 0 || chip == 2) -- GitLab From 21f825e61878db94c7093c8407602fc89fc38ad9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:13:16 -0700 Subject: [PATCH 1050/5560] pktgen: Fix set-but-unused variable. "iph" in pktgen_output_ipsec() is set but never actually used. Kill it off. Signed-off-by: David S. Miller --- net/core/pktgen.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index aeeece72b72f..2fa6fee1b46f 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2514,7 +2514,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev) { struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x; int err = 0; - struct iphdr *iph; if (!x) return 0; @@ -2524,7 +2523,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev) return 0; spin_lock(&x->lock); - iph = ip_hdr(skb); err = x->outer_mode->output(x, skb); if (err) -- GitLab From 9bf9055eb716f85372c41b3fbc51f90bc7653740 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:14:09 -0700 Subject: [PATCH 1051/5560] decnet: Fix set-but-unused variable. "next" in dn_rebuild_zone() is set but not actually used, kill it off. Signed-off-by: David S. Miller --- net/decnet/dn_table.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 99d8d3a40998..d8ea583076cf 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -124,11 +124,10 @@ static inline void dn_rebuild_zone(struct dn_zone *dz, int old_divisor) { int i; - struct dn_fib_node *f, **fp, *next; + struct dn_fib_node *f, **fp; for(i = 0; i < old_divisor; i++) { for(f = old_ht[i]; f; f = f->fn_next) { - next = f->fn_next; for(fp = dn_chain_p(f->fn_key, dz); *fp && dn_key_leq((*fp)->fn_key, f->fn_key); fp = &(*fp)->fn_next) -- GitLab From b3b8dc51c16cdaca0d191a340022093fb5c9f003 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:15:22 -0700 Subject: [PATCH 1052/5560] econet: Fix set-but-unused variable. #if 0'd out code for IP handling in aun_data_available() has been commented out since the beginning, which makes the variable "ip" set but not used. Kill it off as well as the stub code. Signed-off-by: David S. Miller --- net/econet/af_econet.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 116d3fd3d669..a1d9f3787dd5 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -935,7 +935,6 @@ static void aun_data_available(struct sock *sk, int slen) struct sk_buff *skb; unsigned char *data; struct aunhdr *ah; - struct iphdr *ip; size_t len; while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) { @@ -949,7 +948,6 @@ static void aun_data_available(struct sock *sk, int slen) data = skb_transport_header(skb) + sizeof(struct udphdr); ah = (struct aunhdr *)data; len = skb->len - sizeof(struct udphdr); - ip = ip_hdr(skb); switch (ah->code) { @@ -962,12 +960,6 @@ static void aun_data_available(struct sock *sk, int slen) case 4: aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING); break; -#if 0 - /* This isn't quite right yet. */ - case 5: - aun_send_response(ip->saddr, ah->handle, 6, ah->cb); - break; -#endif default: printk(KERN_DEBUG "unknown AUN packet (type %d)\n", data[0]); } -- GitLab From d8f969e603b85931f25a1d50f3a7a01e2712c17a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:46:45 -0700 Subject: [PATCH 1053/5560] ax25: Fix set-but-unused variable. The variable 's' is set but unused in ax25_protocol_release(). Just kill it off. Signed-off-by: David S. Miller --- net/ax25/ax25_iface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index 5a0dda8df492..60b545e2822a 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c @@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(ax25_register_pid); void ax25_protocol_release(unsigned int pid) { - struct ax25_protocol *s, *protocol; + struct ax25_protocol *protocol; write_lock_bh(&protocol_list_lock); protocol = protocol_list; @@ -72,7 +72,6 @@ void ax25_protocol_release(unsigned int pid) while (protocol != NULL && protocol->next != NULL) { if (protocol->next->pid == pid) { - s = protocol->next; protocol->next = protocol->next->next; goto out; } -- GitLab From 9e5ebaf852b96aaf4d7f63b920d8016b6784f088 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:48:01 -0700 Subject: [PATCH 1054/5560] atm: lec: Fix set-but-unused variables. The variable 'eth' is set but unused in lec_handle_bridge(). Also, the variable 'priv' is set but unused in lane_module_cleanup(). Just kill them off. Signed-off-by: David S. Miller --- net/atm/lec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/atm/lec.c b/net/atm/lec.c index 38754fdb88ba..25073b6ef474 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -129,7 +129,6 @@ static struct net_device *dev_lec[MAX_LEC_ITF]; #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) { - struct ethhdr *eth; char *buff; struct lec_priv *priv; @@ -138,7 +137,6 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) * LE_TOPOLOGY_REQUEST with the same value of Topology Change bit * as the Config BPDU has */ - eth = (struct ethhdr *)skb->data; buff = skb->data + skb->dev->hard_header_len; if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) { struct sock *sk; @@ -1180,7 +1178,6 @@ static int __init lane_module_init(void) static void __exit lane_module_cleanup(void) { int i; - struct lec_priv *priv; remove_proc_entry("lec", atm_proc_root); @@ -1188,7 +1185,6 @@ static void __exit lane_module_cleanup(void) for (i = 0; i < MAX_LEC_ITF; i++) { if (dev_lec[i] != NULL) { - priv = netdev_priv(dev_lec[i]); unregister_netdev(dev_lec[i]); free_netdev(dev_lec[i]); dev_lec[i] = NULL; -- GitLab From 7d038eb6dc0e256dbcac88d52972c4ac55a78fc5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:50:58 -0700 Subject: [PATCH 1055/5560] bonding: Fix set-but-unused variable. The variable 'vlan_dev' is set but unused in bond_send_gratuitous_arp(). Just kill it off. Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ca902ae3f2e5..fdf9215ada7d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2763,7 +2763,6 @@ static void bond_send_gratuitous_arp(struct bonding *bond) { struct slave *slave = bond->curr_active_slave; struct vlan_entry *vlan; - struct net_device *vlan_dev; pr_debug("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name, slave ? slave->dev->name : "NULL"); @@ -2783,7 +2782,6 @@ static void bond_send_gratuitous_arp(struct bonding *bond) return; list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); if (vlan->vlan_ip) { bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip, vlan->vlan_ip, vlan->vlan_id); -- GitLab From f8dfc4528b93ba9c9a191151f8888b4da1d1a45b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:51:40 -0700 Subject: [PATCH 1056/5560] atlx: Fix set-but-unused variable. The variable 'tpc' is set but unused in atl1_intr_tx(). Just kill it off. Signed-off-by: David S. Miller --- drivers/net/atlx/atl1.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 98334a1f0c5c..dffa6919a419 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2074,9 +2074,6 @@ static void atl1_intr_tx(struct atl1_adapter *adapter) cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx); while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { - struct tx_packet_desc *tpd; - - tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean); buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; if (buffer_info->dma) { pci_unmap_page(adapter->pdev, buffer_info->dma, -- GitLab From c96922c7beeb6246f36b89a1e8b61d99a435a780 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:54:51 -0700 Subject: [PATCH 1057/5560] atl1e: Fix set-but-unused variable. The variable 'tx_ring' is set but unused in atl1e_init_ring_resources(). Just kill it off. Signed-off-by: David S. Miller --- drivers/net/atl1e/atl1e_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 9900ca1d8eda..86a912283134 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -691,10 +691,8 @@ static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size) static void atl1e_init_ring_resources(struct atl1e_adapter *adapter) { - struct atl1e_tx_ring *tx_ring = NULL; struct atl1e_rx_ring *rx_ring = NULL; - tx_ring = &adapter->tx_ring; rx_ring = &adapter->rx_ring; rx_ring->real_page_size = adapter->rx_ring.page_size -- GitLab From 0c78641d7f677c8f420f1c302b4848135b207eb8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 00:55:20 -0700 Subject: [PATCH 1058/5560] atl1c: Fix set-but-unused variable. The variable 'extra_size' is set but unused in atl1c_configure_tx(). Just kill it off. Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 894d485bf5bc..5c64a5d91544 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1095,10 +1095,8 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter) u32 max_pay_load; u16 tx_offload_thresh; u32 txq_ctrl_data; - u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ u32 max_pay_load_data; - extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH, (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK); -- GitLab From 33de04ec4cb80b6bd0782e88a64954e60bc15dc1 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 15 Apr 2011 14:48:12 -0500 Subject: [PATCH 1059/5560] slub: Use NUMA_NO_NODE in get_partial A -1 was leftover during the conversion. Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index 129f10cdfc59..5284fb779670 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1487,7 +1487,7 @@ static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node) int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node; page = get_partial_node(get_node(s, searchnode)); - if (page || node != -1) + if (page || node != NUMA_NO_NODE) return page; return get_any_partial(s, flags); -- GitLab From 5f80b13ae45df7da6646d1881da186318e70b6b6 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 15 Apr 2011 14:48:13 -0500 Subject: [PATCH 1060/5560] slub: get_map() function to establish map of free objects in a slab The bit map of free objects in a slab page is determined in various functions if debugging is enabled. Provide a common function for that purpose. Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- mm/slub.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 5284fb779670..837f932671a1 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -271,10 +271,6 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) for (__p = (__addr); __p < (__addr) + (__objects) * (__s)->size;\ __p += (__s)->size) -/* Scan freelist */ -#define for_each_free_object(__p, __s, __free) \ - for (__p = (__free); __p; __p = get_freepointer((__s), __p)) - /* Determine object index from a given position */ static inline int slab_index(void *p, struct kmem_cache *s, void *addr) { @@ -330,6 +326,21 @@ static inline int oo_objects(struct kmem_cache_order_objects x) return x.x & OO_MASK; } +/* + * Determine a map of object in use on a page. + * + * Slab lock or node listlock must be held to guarantee that the page does + * not vanish from under us. + */ +static void get_map(struct kmem_cache *s, struct page *page, unsigned long *map) +{ + void *p; + void *addr = page_address(page); + + for (p = page->freelist; p; p = get_freepointer(s, p)) + set_bit(slab_index(p, s, addr), map); +} + #ifdef CONFIG_SLUB_DEBUG /* * Debug settings: @@ -2673,9 +2684,8 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, return; slab_err(s, page, "%s", text); slab_lock(page); - for_each_free_object(p, s, page->freelist) - set_bit(slab_index(p, s, addr), map); + get_map(s, page, map); for_each_object(p, s, addr, page->objects) { if (!test_bit(slab_index(p, s, addr), map)) { @@ -3610,10 +3620,11 @@ static int validate_slab(struct kmem_cache *s, struct page *page, /* Now we know that a valid freelist exists */ bitmap_zero(map, page->objects); - for_each_free_object(p, s, page->freelist) { - set_bit(slab_index(p, s, addr), map); - if (!check_object(s, page, p, SLUB_RED_INACTIVE)) - return 0; + get_map(s, page, map); + for_each_object(p, s, addr, page->objects) { + if (test_bit(slab_index(p, s, addr), map)) + if (!check_object(s, page, p, SLUB_RED_INACTIVE)) + return 0; } for_each_object(p, s, addr, page->objects) @@ -3821,8 +3832,7 @@ static void process_slab(struct loc_track *t, struct kmem_cache *s, void *p; bitmap_zero(map, page->objects); - for_each_free_object(p, s, page->freelist) - set_bit(slab_index(p, s, addr), map); + get_map(s, page, map); for_each_object(p, s, addr, page->objects) if (!test_bit(slab_index(p, s, addr), map)) -- GitLab From 01ad8a7bc226ddbbf90e4c15167d9e31a8d02930 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 15 Apr 2011 14:48:14 -0500 Subject: [PATCH 1061/5560] slub: Eliminate repeated use of c->page through a new page variable __slab_alloc is full of "c->page" repeats. Lets just use one local variable named "page" for this. Also avoids the need to a have another variable called "new". Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- mm/slub.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 837f932671a1..ab44368ed692 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1790,7 +1790,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, unsigned long addr, struct kmem_cache_cpu *c) { void **object; - struct page *new; + struct page *page; #ifdef CONFIG_CMPXCHG_LOCAL unsigned long flags; @@ -1808,28 +1808,30 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, /* We handle __GFP_ZERO in the caller */ gfpflags &= ~__GFP_ZERO; - if (!c->page) + page = c->page; + if (!page) goto new_slab; - slab_lock(c->page); + slab_lock(page); if (unlikely(!node_match(c, node))) goto another_slab; stat(s, ALLOC_REFILL); load_freelist: - object = c->page->freelist; + object = page->freelist; if (unlikely(!object)) goto another_slab; if (kmem_cache_debug(s)) goto debug; c->freelist = get_freepointer(s, object); - c->page->inuse = c->page->objects; - c->page->freelist = NULL; - c->node = page_to_nid(c->page); + page->inuse = page->objects; + page->freelist = NULL; + c->node = page_to_nid(page); + unlock_out: - slab_unlock(c->page); + slab_unlock(page); #ifdef CONFIG_CMPXCHG_LOCAL c->tid = next_tid(c->tid); local_irq_restore(flags); @@ -1841,9 +1843,9 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, deactivate_slab(s, c); new_slab: - new = get_partial(s, gfpflags, node); - if (new) { - c->page = new; + page = get_partial(s, gfpflags, node); + if (page) { + c->page = page; stat(s, ALLOC_FROM_PARTIAL); goto load_freelist; } @@ -1852,19 +1854,20 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, if (gfpflags & __GFP_WAIT) local_irq_enable(); - new = new_slab(s, gfpflags, node); + page = new_slab(s, gfpflags, node); if (gfpflags & __GFP_WAIT) local_irq_disable(); - if (new) { + if (page) { c = __this_cpu_ptr(s->cpu_slab); stat(s, ALLOC_SLAB); if (c->page) flush_slab(s, c); - slab_lock(new); - __SetPageSlubFrozen(new); - c->page = new; + + slab_lock(page); + __SetPageSlubFrozen(page); + c->page = page; goto load_freelist; } if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit()) @@ -1874,11 +1877,11 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, #endif return NULL; debug: - if (!alloc_debug_processing(s, c->page, object, addr)) + if (!alloc_debug_processing(s, page, object, addr)) goto another_slab; - c->page->inuse++; - c->page->freelist = get_freepointer(s, object); + page->inuse++; + page->freelist = get_freepointer(s, object); c->node = NUMA_NO_NODE; goto unlock_out; } -- GitLab From dc1fb7f43636754a4d06f7bdb8ea3269a7d71d6d Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 15 Apr 2011 14:48:15 -0500 Subject: [PATCH 1062/5560] slub: Move node determination out of hotpath If the node does not change then there is no need to recalculate the node from the page struct. So move the node determination into the places where we acquire a new slab page. Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- mm/slub.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index ab44368ed692..301360bc00c6 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1828,7 +1828,6 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, c->freelist = get_freepointer(s, object); page->inuse = page->objects; page->freelist = NULL; - c->node = page_to_nid(page); unlock_out: slab_unlock(page); @@ -1845,8 +1844,10 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, new_slab: page = get_partial(s, gfpflags, node); if (page) { - c->page = page; stat(s, ALLOC_FROM_PARTIAL); +load_from_page: + c->node = page_to_nid(page); + c->page = page; goto load_freelist; } @@ -1867,8 +1868,8 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, slab_lock(page); __SetPageSlubFrozen(page); - c->page = page; - goto load_freelist; + + goto load_from_page; } if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit()) slab_out_of_memory(s, gfpflags, node); -- GitLab From 8dc16c6c04b1a82d00a8464ccc08e1fe17d0ff82 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 15 Apr 2011 14:48:16 -0500 Subject: [PATCH 1063/5560] slub: Move debug handlign in __slab_free Its easier to read if its with the check for debugging flags. Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- mm/slub.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 301360bc00c6..c952fac112e8 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2057,10 +2057,9 @@ static void __slab_free(struct kmem_cache *s, struct page *page, slab_lock(page); stat(s, FREE_SLOWPATH); - if (kmem_cache_debug(s)) - goto debug; + if (kmem_cache_debug(s) && !free_debug_processing(s, page, x, addr)) + goto out_unlock; -checks_ok: prior = page->freelist; set_freepointer(s, object, prior); page->freelist = object; @@ -2104,12 +2103,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page, #endif stat(s, FREE_SLAB); discard_slab(s, page); - return; - -debug: - if (!free_debug_processing(s, page, x, addr)) - goto out_unlock; - goto checks_ok; } /* -- GitLab From 551586292b39da6e4fbfbb5b96b57b68decfdab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Mon, 14 Mar 2011 22:43:27 +0000 Subject: [PATCH 1064/5560] batman-adv: Move bonding / iface alternating router search to own functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This decreases the size of find_router() by outsourcing the router search for the bonding and interface alternating modes to their own sub functions. This shall make it easier to keep track of the correct refcounting later. Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/routing.c | 180 +++++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 75 deletions(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index c172f5d0e05a..f212abe745bc 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1092,6 +1092,106 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) return ret; } +/* In the bonding case, send the packets in a round + * robin fashion over the remaining interfaces. + * + * This method rotates the bonding list and increases the + * returned router's refcount. */ +static struct neigh_node *find_bond_router(struct orig_node *primary_orig, + struct hard_iface *recv_if) +{ + struct neigh_node *tmp_neigh_node; + struct neigh_node *router = NULL, *first_candidate = NULL; + + rcu_read_lock(); + list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list, + bonding_list) { + if (!first_candidate) + first_candidate = tmp_neigh_node; + + /* recv_if == NULL on the first node. */ + if (tmp_neigh_node->if_incoming == recv_if) + continue; + + if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) + continue; + + router = tmp_neigh_node; + break; + } + + /* use the first candidate if nothing was found. */ + if (!router && first_candidate && + atomic_inc_not_zero(&first_candidate->refcount)) + router = first_candidate; + + if (!router) + goto out; + + /* selected should point to the next element + * after the current router */ + spin_lock_bh(&primary_orig->neigh_list_lock); + /* this is a list_move(), which unfortunately + * does not exist as rcu version */ + list_del_rcu(&primary_orig->bond_list); + list_add_rcu(&primary_orig->bond_list, + &router->bonding_list); + spin_unlock_bh(&primary_orig->neigh_list_lock); + +out: + rcu_read_unlock(); + return router; +} + +/* Interface Alternating: Use the best of the + * remaining candidates which are not using + * this interface. + * + * Increases the returned router's refcount */ +static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, + struct hard_iface *recv_if) +{ + struct neigh_node *tmp_neigh_node; + struct neigh_node *router = NULL, *first_candidate = NULL; + + rcu_read_lock(); + list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list, + bonding_list) { + if (!first_candidate) + first_candidate = tmp_neigh_node; + + /* recv_if == NULL on the first node. */ + if (tmp_neigh_node->if_incoming == recv_if) + continue; + + if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) + continue; + + /* if we don't have a router yet + * or this one is better, choose it. */ + if ((!router) || + (tmp_neigh_node->tq_avg > router->tq_avg)) { + /* decrement refcount of + * previously selected router */ + if (router) + neigh_node_free_ref(router); + + router = tmp_neigh_node; + atomic_inc_not_zero(&router->refcount); + } + + neigh_node_free_ref(tmp_neigh_node); + } + + /* use the first candidate if nothing was found. */ + if (!router && first_candidate && + atomic_inc_not_zero(&first_candidate->refcount)) + router = first_candidate; + + rcu_read_unlock(); + return router; +} + /* find a suitable router for this originator, and use * bonding if possible. increases the found neighbors * refcount.*/ @@ -1101,7 +1201,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, { struct orig_node *primary_orig_node; struct orig_node *router_orig; - struct neigh_node *router, *first_candidate, *tmp_neigh_node; + struct neigh_node *router; static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; int bonding_enabled; @@ -1157,82 +1257,12 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, * in. */ neigh_node_free_ref(router); - first_candidate = NULL; - router = NULL; - - if (bonding_enabled) { - /* in the bonding case, send the packets in a round - * robin fashion over the remaining interfaces. */ - - list_for_each_entry_rcu(tmp_neigh_node, - &primary_orig_node->bond_list, bonding_list) { - if (!first_candidate) - first_candidate = tmp_neigh_node; - /* recv_if == NULL on the first node. */ - if (tmp_neigh_node->if_incoming != recv_if && - atomic_inc_not_zero(&tmp_neigh_node->refcount)) { - router = tmp_neigh_node; - break; - } - } - - /* use the first candidate if nothing was found. */ - if (!router && first_candidate && - atomic_inc_not_zero(&first_candidate->refcount)) - router = first_candidate; - if (!router) { - rcu_read_unlock(); - return NULL; - } - - /* selected should point to the next element - * after the current router */ - spin_lock_bh(&primary_orig_node->neigh_list_lock); - /* this is a list_move(), which unfortunately - * does not exist as rcu version */ - list_del_rcu(&primary_orig_node->bond_list); - list_add_rcu(&primary_orig_node->bond_list, - &router->bonding_list); - spin_unlock_bh(&primary_orig_node->neigh_list_lock); - - } else { - /* if bonding is disabled, use the best of the - * remaining candidates which are not using - * this interface. */ - list_for_each_entry_rcu(tmp_neigh_node, - &primary_orig_node->bond_list, bonding_list) { - if (!first_candidate) - first_candidate = tmp_neigh_node; - - /* recv_if == NULL on the first node. */ - if (tmp_neigh_node->if_incoming == recv_if) - continue; - - if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) - continue; - - /* if we don't have a router yet - * or this one is better, choose it. */ - if ((!router) || - (tmp_neigh_node->tq_avg > router->tq_avg)) { - /* decrement refcount of - * previously selected router */ - if (router) - neigh_node_free_ref(router); - - router = tmp_neigh_node; - atomic_inc_not_zero(&router->refcount); - } - - neigh_node_free_ref(tmp_neigh_node); - } + if (bonding_enabled) + router = find_bond_router(primary_orig_node, recv_if); + else + router = find_ifalter_router(primary_orig_node, recv_if); - /* use the first candidate if nothing was found. */ - if (!router && first_candidate && - atomic_inc_not_zero(&first_candidate->refcount)) - router = first_candidate; - } return_router: rcu_read_unlock(); return router; -- GitLab From 4c804850572f70a2350e4d1e79d6659392b07733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Mon, 14 Mar 2011 22:43:30 +0000 Subject: [PATCH 1065/5560] batman-adv: Make gateway_get_selected type safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the return value explicit instead of (void *). Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_client.c | 2 +- net/batman-adv/gateway_client.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 3cc43558cf9c..27b87add044b 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -42,7 +42,7 @@ static void gw_node_free_ref(struct gw_node *gw_node) call_rcu(&gw_node->rcu, gw_node_free_rcu); } -void *gw_get_selected(struct bat_priv *bat_priv) +struct orig_node *gw_get_selected(struct bat_priv *bat_priv) { struct gw_node *curr_gateway_tmp; struct orig_node *orig_node = NULL; diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h index 2aa439124ee3..97c31d178163 100644 --- a/net/batman-adv/gateway_client.h +++ b/net/batman-adv/gateway_client.h @@ -24,7 +24,7 @@ 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); +struct orig_node *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); -- GitLab From 57f0c07c4d0da8bcc23e21c330fe9c7c5cf776b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Mon, 14 Mar 2011 22:43:33 +0000 Subject: [PATCH 1066/5560] batman-adv: Simplify gw_check_election(), use gw_get_selected() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gw_get_selected() can get us the desired orig_node directly, therefore reusing that function in gw_check_election(). Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_client.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 27b87add044b..879ac1594869 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -23,6 +23,7 @@ #include "gateway_client.h" #include "gateway_common.h" #include "hard-interface.h" +#include "originator.h" #include #include #include @@ -203,28 +204,25 @@ void gw_election(struct bat_priv *bat_priv) void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) { - struct gw_node *curr_gateway_tmp; + struct orig_node *curr_gw_orig; uint8_t gw_tq_avg, orig_tq_avg; - rcu_read_lock(); - curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw); - if (!curr_gateway_tmp) - goto out_rcu; + curr_gw_orig = gw_get_selected(bat_priv); + if (!curr_gw_orig) + goto deselect; - if (!curr_gateway_tmp->orig_node) - goto deselect_rcu; - - if (!curr_gateway_tmp->orig_node->router) + rcu_read_lock(); + if (!curr_gw_orig->router) goto deselect_rcu; /* this node already is the gateway */ - if (curr_gateway_tmp->orig_node == orig_node) + if (curr_gw_orig == orig_node) goto out_rcu; if (!orig_node->router) goto out_rcu; - gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg; + gw_tq_avg = curr_gw_orig->router->tq_avg; rcu_read_unlock(); orig_tq_avg = orig_node->router->tq_avg; @@ -255,6 +253,9 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) deselect: gw_deselect(bat_priv); out: + if (curr_gw_orig) + orig_node_free_ref(curr_gw_orig); + return; } -- GitLab From e1a5382f978b67b5cc36eec65e6046730ce07714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Mon, 14 Mar 2011 22:43:37 +0000 Subject: [PATCH 1067/5560] batman-adv: Make orig_node->router an rcu protected pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rcu protected macros rcu_dereference() and rcu_assign_pointer() for the orig_node->router need to be used, as well as spin/rcu locking. Otherwise we might end up using a router pointer pointing to already freed memory. Therefore this commit introduces the safe getter method orig_node_get_router(). Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_client.c | 80 +++++++------ net/batman-adv/icmp_socket.c | 18 +-- net/batman-adv/originator.c | 37 ++++-- net/batman-adv/originator.h | 1 + net/batman-adv/routing.c | 194 +++++++++++++++----------------- net/batman-adv/send.c | 19 ++-- net/batman-adv/types.h | 4 +- net/batman-adv/vis.c | 91 ++++++++------- 8 files changed, 232 insertions(+), 212 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 879ac1594869..42a8a7ba06e6 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -98,6 +98,7 @@ void gw_election(struct bat_priv *bat_priv) { struct hlist_node *node; struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL; + struct neigh_node *router; uint8_t max_tq = 0; uint32_t max_gw_factor = 0, tmp_gw_factor = 0; int down, up; @@ -133,10 +134,11 @@ void gw_election(struct bat_priv *bat_priv) } hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { - if (!gw_node->orig_node->router) + if (gw_node->deleted) continue; - if (gw_node->deleted) + router = orig_node_get_router(gw_node->orig_node); + if (!router) continue; switch (atomic_read(&bat_priv->gw_sel_class)) { @@ -144,15 +146,14 @@ void gw_election(struct bat_priv *bat_priv) 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 * + tmp_gw_factor = (router->tq_avg * 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))) + (router->tq_avg > max_tq))) curr_gw_tmp = gw_node; break; @@ -164,19 +165,25 @@ void gw_election(struct bat_priv *bat_priv) * soon as a better gateway appears which has * $routing_class more tq points) **/ - if (gw_node->orig_node->router->tq_avg > max_tq) + if (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 (router->tq_avg > max_tq) + max_tq = router->tq_avg; if (tmp_gw_factor > max_gw_factor) max_gw_factor = tmp_gw_factor; + + neigh_node_free_ref(router); } if (curr_gw != curr_gw_tmp) { + router = orig_node_get_router(curr_gw_tmp->orig_node); + if (!router) + goto out; + if ((curr_gw) && (!curr_gw_tmp)) bat_dbg(DBG_BATMAN, bat_priv, "Removing selected gateway - " @@ -187,45 +194,47 @@ void gw_election(struct bat_priv *bat_priv) "(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); + 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); + router->tq_avg); + neigh_node_free_ref(router); gw_select(bat_priv, curr_gw_tmp); } +out: rcu_read_unlock(); } void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) { struct orig_node *curr_gw_orig; + struct neigh_node *router_gw = NULL, *router_orig = NULL; uint8_t gw_tq_avg, orig_tq_avg; curr_gw_orig = gw_get_selected(bat_priv); if (!curr_gw_orig) goto deselect; - rcu_read_lock(); - if (!curr_gw_orig->router) - goto deselect_rcu; + router_gw = orig_node_get_router(curr_gw_orig); + if (!router_gw) + goto deselect; /* this node already is the gateway */ if (curr_gw_orig == orig_node) - goto out_rcu; - - if (!orig_node->router) - goto out_rcu; + goto out; - gw_tq_avg = curr_gw_orig->router->tq_avg; - rcu_read_unlock(); + router_orig = orig_node_get_router(orig_node); + if (!router_orig) + goto out; - orig_tq_avg = orig_node->router->tq_avg; + gw_tq_avg = router_gw->tq_avg; + orig_tq_avg = router_orig->tq_avg; /* the TQ value has to be better */ if (orig_tq_avg < gw_tq_avg) @@ -243,18 +252,16 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) "Restarting gateway selection: better gateway found (tq curr: " "%i, tq new: %i)\n", gw_tq_avg, orig_tq_avg); - goto deselect; -out_rcu: - rcu_read_unlock(); - goto out; -deselect_rcu: - rcu_read_unlock(); deselect: gw_deselect(bat_priv); out: if (curr_gw_orig) orig_node_free_ref(curr_gw_orig); + if (router_gw) + neigh_node_free_ref(router_gw); + if (router_orig) + neigh_node_free_ref(router_orig); return; } @@ -362,23 +369,30 @@ void gw_node_purge(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->gw_list_lock); } +/** + * fails if orig_node has no router + */ static int _write_buffer_text(struct bat_priv *bat_priv, struct seq_file *seq, struct gw_node *gw_node) { struct gw_node *curr_gw; - int down, up, ret; + struct neigh_node *router; + int down, up, ret = -1; gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); + router = orig_node_get_router(gw_node->orig_node); + if (!router) + goto out; + rcu_read_lock(); curr_gw = rcu_dereference(bat_priv->curr_gw); ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", (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, + router->tq_avg, router->addr, + router->if_incoming->net_dev->name, gw_node->orig_node->gw_flags, (down > 2048 ? down / 1024 : down), (down > 2048 ? "MBit" : "KBit"), @@ -386,6 +400,8 @@ static int _write_buffer_text(struct bat_priv *bat_priv, (up > 2048 ? "MBit" : "KBit")); rcu_read_unlock(); + neigh_node_free_ref(router); +out: return ret; } @@ -423,10 +439,10 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset) if (gw_node->deleted) continue; - if (!gw_node->orig_node->router) + /* fails if orig_node has no router */ + if (_write_buffer_text(bat_priv, seq, gw_node) < 0) continue; - _write_buffer_text(bat_priv, seq, gw_node); gw_count++; } rcu_read_unlock(); diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index 34ce56c358e5..49079c254476 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -218,23 +218,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) goto dst_unreach; - rcu_read_lock(); orig_node = orig_hash_find(bat_priv, icmp_packet->dst); - if (!orig_node) - goto unlock; - - neigh_node = orig_node->router; + goto dst_unreach; + neigh_node = orig_node_get_router(orig_node); if (!neigh_node) - goto unlock; - - if (!atomic_inc_not_zero(&neigh_node->refcount)) { - neigh_node = NULL; - goto unlock; - } - - rcu_read_unlock(); + goto dst_unreach; if (!neigh_node->if_incoming) goto dst_unreach; @@ -252,8 +242,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); goto out; -unlock: - rcu_read_unlock(); dst_unreach: icmp_packet->msg_type = DESTINATION_UNREACHABLE; bat_socket_add_packet(socket_client, icmp_packet, packet_len); diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 0b9133022d2d..b4cfe3686155 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -70,6 +70,21 @@ void neigh_node_free_ref(struct neigh_node *neigh_node) call_rcu(&neigh_node->rcu, neigh_node_free_rcu); } +/* increases the refcounter of a found router */ +struct neigh_node *orig_node_get_router(struct orig_node *orig_node) +{ + struct neigh_node *router; + + rcu_read_lock(); + router = rcu_dereference(orig_node->router); + + if (router && !atomic_inc_not_zero(&router->refcount)) + router = NULL; + + rcu_read_unlock(); + return router; +} + struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, @@ -390,7 +405,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) struct hlist_node *node, *node_tmp; struct hlist_head *head; struct orig_node *orig_node; - struct neigh_node *neigh_node; + struct neigh_node *neigh_node, *neigh_node_tmp; int batman_count = 0; int last_seen_secs; int last_seen_msecs; @@ -421,37 +436,41 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - if (!orig_node->router) + neigh_node = orig_node_get_router(orig_node); + if (!neigh_node) continue; - if (orig_node->router->tq_avg == 0) - continue; + if (neigh_node->tq_avg == 0) + goto next; 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); - hlist_for_each_entry_rcu(neigh_node, node_tmp, + hlist_for_each_entry_rcu(neigh_node_tmp, node_tmp, &orig_node->neigh_list, list) { - seq_printf(seq, " %pM (%3i)", neigh_node->addr, - neigh_node->tq_avg); + seq_printf(seq, " %pM (%3i)", + neigh_node_tmp->addr, + neigh_node_tmp->tq_avg); } seq_printf(seq, "\n"); batman_count++; + +next: + neigh_node_free_ref(neigh_node); } rcu_read_unlock(); } - if ((batman_count == 0)) + if (batman_count == 0) seq_printf(seq, "No batman nodes in range ...\n"); return 0; diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 5cc011057da1..e1d641f27aa9 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -34,6 +34,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node, uint8_t *neigh, struct hard_iface *if_incoming); void neigh_node_free_ref(struct neigh_node *neigh_node); +struct neigh_node *orig_node_get_router(struct orig_node *orig_node); int orig_seq_print_text(struct seq_file *seq, void *offset); int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num); int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index f212abe745bc..b7d43caaa9c8 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -87,18 +87,20 @@ static void update_route(struct bat_priv *bat_priv, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len) { - struct neigh_node *neigh_node_tmp; + struct neigh_node *curr_router; + + curr_router = orig_node_get_router(orig_node); /* route deleted */ - if ((orig_node->router) && (!neigh_node)) { + if ((curr_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)) { + /* route added */ + } else if ((!curr_router) && (neigh_node)) { bat_dbg(DBG_ROUTES, bat_priv, "Adding route towards: %pM (via %pM)\n", @@ -106,21 +108,29 @@ static void update_route(struct bat_priv *bat_priv, hna_global_add_orig(bat_priv, orig_node, hna_buff, hna_buff_len); - /* route changed */ + /* 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); + curr_router->addr); } + if (curr_router) + neigh_node_free_ref(curr_router); + + /* increase refcount of new best neighbor */ if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount)) neigh_node = NULL; - neigh_node_tmp = orig_node->router; - orig_node->router = neigh_node; - if (neigh_node_tmp) - neigh_node_free_ref(neigh_node_tmp); + + spin_lock_bh(&orig_node->neigh_list_lock); + rcu_assign_pointer(orig_node->router, neigh_node); + spin_unlock_bh(&orig_node->neigh_list_lock); + + /* decrease refcount of previous best neighbor */ + if (curr_router) + neigh_node_free_ref(curr_router); } @@ -128,16 +138,23 @@ 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) { + struct neigh_node *router = NULL; if (!orig_node) - return; + goto out; + + router = orig_node_get_router(orig_node); - if (orig_node->router != neigh_node) + if (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); + +out: + if (router) + neigh_node_free_ref(router); } static int is_bidirectional_neigh(struct orig_node *orig_node, @@ -288,8 +305,8 @@ static void bonding_candidate_add(struct orig_node *orig_node, struct neigh_node *neigh_node) { struct hlist_node *node; - struct neigh_node *tmp_neigh_node; - uint8_t best_tq, interference_candidate = 0; + struct neigh_node *tmp_neigh_node, *router = NULL; + uint8_t interference_candidate = 0; spin_lock_bh(&orig_node->neigh_list_lock); @@ -298,13 +315,12 @@ static void bonding_candidate_add(struct orig_node *orig_node, neigh_node->orig_node->primary_addr)) goto candidate_del; - if (!orig_node->router) + router = orig_node_get_router(orig_node); + if (!router) goto candidate_del; - best_tq = orig_node->router->tq_avg; - /* ... and is good enough to be considered */ - if (neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD) + if (neigh_node->tq_avg < router->tq_avg - BONDING_TQ_THRESHOLD) goto candidate_del; /** @@ -350,7 +366,9 @@ static void bonding_candidate_add(struct orig_node *orig_node, out: spin_unlock_bh(&orig_node->neigh_list_lock); - return; + + if (router) + neigh_node_free_ref(router); } /* copy primary address for bonding */ @@ -373,6 +391,7 @@ static void update_orig(struct bat_priv *bat_priv, char is_duplicate) { struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; + struct neigh_node *router = NULL; struct orig_node *orig_node_tmp; struct hlist_node *node; int tmp_hna_buff_len; @@ -441,19 +460,18 @@ static void update_orig(struct bat_priv *bat_priv, /* if this neighbor already is our next hop there is nothing * to change */ - if (orig_node->router == neigh_node) + router = orig_node_get_router(orig_node); + if (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)) + if (router && (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_tmp = orig_node->router->orig_node; + if (router && (neigh_node->tq_avg == router->tq_avg)) { + orig_node_tmp = router->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); bcast_own_sum_orig = orig_node_tmp->bcast_own_sum[if_incoming->if_num]; @@ -474,7 +492,7 @@ static void update_orig(struct bat_priv *bat_priv, goto update_gw; update_hna: - update_routes(bat_priv, orig_node, orig_node->router, + update_routes(bat_priv, orig_node, router, hna_buff, tmp_hna_buff_len); update_gw: @@ -496,6 +514,8 @@ static void update_orig(struct bat_priv *bat_priv, out: if (neigh_node) neigh_node_free_ref(neigh_node); + if (router) + neigh_node_free_ref(router); } /* checks whether the host restarted and is in the protection time. @@ -603,6 +623,8 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct hard_iface *hard_iface; struct orig_node *orig_neigh_node, *orig_node; + struct neigh_node *router = NULL, *router_router = NULL; + struct neigh_node *orig_neigh_router = NULL; 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; @@ -747,14 +769,15 @@ void receive_bat_packet(struct ethhdr *ethhdr, goto out; } + router = orig_node_get_router(orig_node); + if (router) + router_router = orig_node_get_router(router->orig_node); + /* avoid temporary routing loops */ - if ((orig_node->router) && - (orig_node->router->orig_node->router) && - (compare_eth(orig_node->router->addr, - batman_packet->prev_sender)) && + if (router && router_router && + (compare_eth(router->addr, batman_packet->prev_sender)) && !(compare_eth(batman_packet->orig, batman_packet->prev_sender)) && - (compare_eth(orig_node->router->addr, - orig_node->router->orig_node->router->addr))) { + (compare_eth(router->addr, router_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); @@ -769,9 +792,11 @@ void receive_bat_packet(struct ethhdr *ethhdr, if (!orig_neigh_node) goto out; + orig_neigh_router = orig_node_get_router(orig_neigh_node); + /* 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)) { + if (!is_single_hop_neigh && (!orig_neigh_router)) { bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: OGM via unknown neighbor!\n"); goto out_neigh; @@ -825,6 +850,13 @@ void receive_bat_packet(struct ethhdr *ethhdr, if ((orig_neigh_node) && (!is_single_hop_neigh)) orig_node_free_ref(orig_neigh_node); out: + if (router) + neigh_node_free_ref(router); + if (router_router) + neigh_node_free_ref(router_router); + if (orig_neigh_router) + neigh_node_free_ref(orig_neigh_router); + orig_node_free_ref(orig_node); } @@ -869,7 +901,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, struct sk_buff *skb, size_t icmp_len) { struct orig_node *orig_node = NULL; - struct neigh_node *neigh_node = NULL; + struct neigh_node *router = NULL; struct icmp_packet_rr *icmp_packet; int ret = NET_RX_DROP; @@ -886,23 +918,13 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, /* answer echo request (ping) */ /* get routing information */ - rcu_read_lock(); orig_node = orig_hash_find(bat_priv, icmp_packet->orig); - if (!orig_node) - goto unlock; - - neigh_node = orig_node->router; - - if (!neigh_node) - goto unlock; - - if (!atomic_inc_not_zero(&neigh_node->refcount)) { - neigh_node = NULL; - goto unlock; - } + goto out; - rcu_read_unlock(); + router = orig_node_get_router(orig_node); + if (!router) + goto out; /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -916,15 +938,12 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, icmp_packet->msg_type = ECHO_REPLY; icmp_packet->ttl = TTL; - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; - goto out; -unlock: - rcu_read_unlock(); out: - if (neigh_node) - neigh_node_free_ref(neigh_node); + if (router) + neigh_node_free_ref(router); if (orig_node) orig_node_free_ref(orig_node); return ret; @@ -934,7 +953,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, struct sk_buff *skb) { struct orig_node *orig_node = NULL; - struct neigh_node *neigh_node = NULL; + struct neigh_node *router = NULL; struct icmp_packet *icmp_packet; int ret = NET_RX_DROP; @@ -952,23 +971,13 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, goto out; /* get routing information */ - rcu_read_lock(); orig_node = orig_hash_find(bat_priv, icmp_packet->orig); - if (!orig_node) - goto unlock; - - neigh_node = orig_node->router; - - if (!neigh_node) - goto unlock; - - if (!atomic_inc_not_zero(&neigh_node->refcount)) { - neigh_node = NULL; - goto unlock; - } + goto out; - rcu_read_unlock(); + router = orig_node_get_router(orig_node); + if (!router) + goto out; /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -982,15 +991,12 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, icmp_packet->msg_type = TTL_EXCEEDED; icmp_packet->ttl = TTL; - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; - goto out; -unlock: - rcu_read_unlock(); out: - if (neigh_node) - neigh_node_free_ref(neigh_node); + if (router) + neigh_node_free_ref(router); if (orig_node) orig_node_free_ref(orig_node); return ret; @@ -1003,7 +1009,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) struct icmp_packet_rr *icmp_packet; struct ethhdr *ethhdr; struct orig_node *orig_node = NULL; - struct neigh_node *neigh_node = NULL; + struct neigh_node *router = NULL; int hdr_size = sizeof(struct icmp_packet); int ret = NET_RX_DROP; @@ -1050,23 +1056,13 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) return recv_icmp_ttl_exceeded(bat_priv, skb); /* get routing information */ - rcu_read_lock(); orig_node = orig_hash_find(bat_priv, icmp_packet->dst); - if (!orig_node) - goto unlock; - - neigh_node = orig_node->router; - - if (!neigh_node) - goto unlock; - - if (!atomic_inc_not_zero(&neigh_node->refcount)) { - neigh_node = NULL; - goto unlock; - } + goto out; - rcu_read_unlock(); + router = orig_node_get_router(orig_node); + if (!router) + goto out; /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -1078,15 +1074,12 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if) icmp_packet->ttl--; /* route it */ - send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); + send_skb_packet(skb, router->if_incoming, router->addr); ret = NET_RX_SUCCESS; - goto out; -unlock: - rcu_read_unlock(); out: - if (neigh_node) - neigh_node_free_ref(neigh_node); + if (router) + neigh_node_free_ref(router); if (orig_node) orig_node_free_ref(orig_node); return ret; @@ -1208,7 +1201,8 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, if (!orig_node) return NULL; - if (!orig_node->router) + router = orig_node_get_router(orig_node); + if (!router) return NULL; /* without bonding, the first node should @@ -1217,9 +1211,8 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, rcu_read_lock(); /* select default router to output */ - router = orig_node->router; - router_orig = orig_node->router->orig_node; - if (!router_orig || !atomic_inc_not_zero(&router->refcount)) { + router_orig = router->orig_node; + if (!router_orig) { rcu_read_unlock(); return NULL; } @@ -1251,7 +1244,6 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, if (atomic_read(&primary_orig_node->bond_candidates) < 2) goto return_router; - /* all nodes between should choose a candidate which * is is not on the interface where the packet came * in. */ diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index d49e54d932af..e78670c3c4b7 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -308,6 +308,7 @@ void schedule_forward_packet(struct orig_node *orig_node, struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); + struct neigh_node *router; unsigned char in_tq, in_ttl, tq_avg = 0; unsigned long send_time; @@ -316,6 +317,8 @@ void schedule_forward_packet(struct orig_node *orig_node, return; } + router = orig_node_get_router(orig_node); + in_tq = batman_packet->tq; in_ttl = batman_packet->ttl; @@ -324,20 +327,22 @@ void schedule_forward_packet(struct orig_node *orig_node, /* 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)) { + if (router && router->tq_avg != 0) { /* rebroadcast ogm of best ranking neighbor as is */ - if (!compare_eth(orig_node->router->addr, ethhdr->h_source)) { - batman_packet->tq = orig_node->router->tq_avg; + if (!compare_eth(router->addr, ethhdr->h_source)) { + batman_packet->tq = router->tq_avg; - if (orig_node->router->last_ttl) - batman_packet->ttl = orig_node->router->last_ttl - - 1; + if (router->last_ttl) + batman_packet->ttl = router->last_ttl - 1; } - tq_avg = orig_node->router->tq_avg; + tq_avg = router->tq_avg; } + if (router) + neigh_node_free_ref(router); + /* apply hop penalty */ batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 83445cf0cc9f..1854cbb4c1b6 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -67,7 +67,7 @@ struct hard_iface { struct orig_node { uint8_t orig[ETH_ALEN]; uint8_t primary_addr[ETH_ALEN]; - struct neigh_node *router; + struct neigh_node __rcu *router; /* rcu protected pointer */ unsigned long *bcast_own; uint8_t *bcast_own_sum; unsigned long last_valid; @@ -83,7 +83,7 @@ struct orig_node { uint32_t last_bcast_seqno; struct hlist_head neigh_list; struct list_head frag_list; - spinlock_t neigh_list_lock; /* protects neighbor list */ + spinlock_t neigh_list_lock; /* protects neigh_list and router */ atomic_t refcount; struct rcu_head rcu; struct hlist_node hash_entry; diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index f90212f42082..d4cc4f5399f4 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c @@ -558,6 +558,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv, struct vis_info *info) { struct hashtable_t *hash = bat_priv->orig_hash; + struct neigh_node *router; struct hlist_node *node; struct hlist_head *head; struct orig_node *orig_node; @@ -571,13 +572,17 @@ static int find_best_vis_server(struct bat_priv *bat_priv, rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - 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; + router = orig_node_get_router(orig_node); + if (!router) + continue; + + if ((orig_node->flags & VIS_SERVER) && + (router->tq_avg > best_tq)) { + best_tq = router->tq_avg; memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); } + neigh_node_free_ref(router); } rcu_read_unlock(); } @@ -605,7 +610,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) struct hlist_node *node; struct hlist_head *head; struct orig_node *orig_node; - struct neigh_node *neigh_node; + struct neigh_node *router; 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; @@ -633,30 +638,32 @@ static int generate_vis_packet(struct bat_priv *bat_priv) rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { - neigh_node = orig_node->router; - - if (!neigh_node) + router = orig_node_get_router(orig_node); + if (!router) continue; - if (!compare_eth(neigh_node->addr, orig_node->orig)) - continue; + if (!compare_eth(router->addr, orig_node->orig)) + goto next; - if (neigh_node->if_incoming->if_status != IF_ACTIVE) - continue; + if (router->if_incoming->if_status != IF_ACTIVE) + goto next; - if (neigh_node->tq_avg < 1) - continue; + if (router->tq_avg < 1) + goto next; /* 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, + router->if_incoming->net_dev->dev_addr, ETH_ALEN); memcpy(entry->dest, orig_node->orig, ETH_ALEN); - entry->quality = neigh_node->tq_avg; + entry->quality = router->tq_avg; packet->entries++; +next: + neigh_node_free_ref(router); + if (vis_packet_full(info)) goto unlock; } @@ -725,6 +732,7 @@ static void purge_vis_packets(struct bat_priv *bat_priv) static void broadcast_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) { + struct neigh_node *router; struct hashtable_t *hash = bat_priv->orig_hash; struct hlist_node *node; struct hlist_head *head; @@ -745,19 +753,26 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { /* if it's a vis server and reachable, send it. */ - if ((!orig_node) || (!orig_node->router)) - continue; if (!(orig_node->flags & VIS_SERVER)) continue; + + router = orig_node_get_router(orig_node); + if (!router) + continue; + /* don't send it if we already received the packet from - * this node. */ + * this node. */ if (recv_list_is_in(bat_priv, &info->recv_list, - orig_node->orig)) + orig_node->orig)) { + neigh_node_free_ref(router); continue; + } memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); - hard_iface = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + hard_iface = router->if_incoming; + memcpy(dstaddr, router->addr, ETH_ALEN); + + neigh_node_free_ref(router); skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) @@ -772,45 +787,29 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) { struct orig_node *orig_node; - struct neigh_node *neigh_node = NULL; + struct neigh_node *router = NULL; struct sk_buff *skb; struct vis_packet *packet; packet = (struct vis_packet *)info->skb_packet->data; - rcu_read_lock(); orig_node = orig_hash_find(bat_priv, packet->target_orig); - if (!orig_node) - goto unlock; + goto out; - neigh_node = orig_node->router; - - if (!neigh_node) - goto unlock; - - if (!atomic_inc_not_zero(&neigh_node->refcount)) { - neigh_node = NULL; - goto unlock; - } - - rcu_read_unlock(); + router = orig_node_get_router(orig_node); + if (!router) + goto out; skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) - send_skb_packet(skb, neigh_node->if_incoming, - neigh_node->addr); - - goto out; + send_skb_packet(skb, router->if_incoming, router->addr); -unlock: - rcu_read_unlock(); out: - if (neigh_node) - neigh_node_free_ref(neigh_node); + if (router) + neigh_node_free_ref(router); if (orig_node) orig_node_free_ref(orig_node); - return; } /* only send one vis packet. called from send_vis_packets() */ -- GitLab From 68003903e4eeec5288f074ff0751a381750ceb34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Mon, 14 Mar 2011 22:43:40 +0000 Subject: [PATCH 1068/5560] batman-adv: Protect global TQ window with a spinlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/originator.c | 1 + net/batman-adv/routing.c | 4 ++++ net/batman-adv/types.h | 1 + 3 files changed, 6 insertions(+) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index b4cfe3686155..5b8fe32043da 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -102,6 +102,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node, INIT_HLIST_NODE(&neigh_node->list); INIT_LIST_HEAD(&neigh_node->bonding_list); + spin_lock_init(&neigh_node->tq_lock); memcpy(neigh_node->addr, neigh, ETH_ALEN); neigh_node->orig_node = orig_neigh_node; diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index b7d43caaa9c8..f6c642246972 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -415,10 +415,12 @@ static void update_orig(struct bat_priv *bat_priv, if (is_duplicate) continue; + spin_lock_bh(&tmp_neigh_node->tq_lock); 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); + spin_unlock_bh(&tmp_neigh_node->tq_lock); } if (!neigh_node) { @@ -443,10 +445,12 @@ static void update_orig(struct bat_priv *bat_priv, orig_node->flags = batman_packet->flags; neigh_node->last_valid = jiffies; + spin_lock_bh(&neigh_node->tq_lock); 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); + spin_unlock_bh(&neigh_node->tq_lock); if (!is_duplicate) { orig_node->last_ttl = batman_packet->ttl; diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 1854cbb4c1b6..091476df4f0e 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -125,6 +125,7 @@ struct neigh_node { struct rcu_head rcu; struct orig_node *orig_node; struct hard_iface *if_incoming; + spinlock_t tq_lock; /* protects: tq_recv, tq_index */ }; -- GitLab From c4aac1ab9b973798163b34939b522f01e4d28ac9 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Wed, 23 Mar 2011 11:24:34 +0100 Subject: [PATCH 1069/5560] batman-adv: concentrate all curr_gw related rcu operations in select/deselect functions Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/gateway_client.c | 170 ++++++++++++++++++-------------- net/batman-adv/gateway_client.h | 2 +- net/batman-adv/unicast.c | 2 +- 3 files changed, 100 insertions(+), 74 deletions(-) diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 42a8a7ba06e6..2acd7a666bda 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -43,61 +43,75 @@ static void gw_node_free_ref(struct gw_node *gw_node) call_rcu(&gw_node->rcu, gw_node_free_rcu); } -struct orig_node *gw_get_selected(struct bat_priv *bat_priv) +static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv) { - struct gw_node *curr_gateway_tmp; - struct orig_node *orig_node = NULL; + struct gw_node *gw_node; rcu_read_lock(); - curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw); - if (!curr_gateway_tmp) - goto out; - - orig_node = curr_gateway_tmp->orig_node; - if (!orig_node) + gw_node = rcu_dereference(bat_priv->curr_gw); + if (!gw_node) goto out; - if (!atomic_inc_not_zero(&orig_node->refcount)) - orig_node = NULL; + if (!atomic_inc_not_zero(&gw_node->refcount)) + gw_node = NULL; out: rcu_read_unlock(); - return orig_node; + return gw_node; } -void gw_deselect(struct bat_priv *bat_priv) +struct orig_node *gw_get_selected_orig(struct bat_priv *bat_priv) { struct gw_node *gw_node; + struct orig_node *orig_node = NULL; - spin_lock_bh(&bat_priv->gw_list_lock); - gw_node = rcu_dereference(bat_priv->curr_gw); - rcu_assign_pointer(bat_priv->curr_gw, NULL); - spin_unlock_bh(&bat_priv->gw_list_lock); + gw_node = gw_get_selected_gw_node(bat_priv); + if (!gw_node) + goto out; + + rcu_read_lock(); + orig_node = gw_node->orig_node; + if (!orig_node) + goto unlock; + + if (!atomic_inc_not_zero(&orig_node->refcount)) + orig_node = NULL; +unlock: + rcu_read_unlock(); +out: if (gw_node) gw_node_free_ref(gw_node); + return orig_node; } static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node) { struct gw_node *curr_gw_node; + spin_lock_bh(&bat_priv->gw_list_lock); + if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount)) new_gw_node = NULL; - spin_lock_bh(&bat_priv->gw_list_lock); - curr_gw_node = rcu_dereference(bat_priv->curr_gw); + curr_gw_node = bat_priv->curr_gw; rcu_assign_pointer(bat_priv->curr_gw, new_gw_node); - spin_unlock_bh(&bat_priv->gw_list_lock); if (curr_gw_node) gw_node_free_ref(curr_gw_node); + + spin_unlock_bh(&bat_priv->gw_list_lock); +} + +void gw_deselect(struct bat_priv *bat_priv) +{ + gw_select(bat_priv, NULL); } void gw_election(struct bat_priv *bat_priv) { struct hlist_node *node; - struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL; + struct gw_node *gw_node, *curr_gw = NULL, *curr_gw_tmp = NULL; struct neigh_node *router; uint8_t max_tq = 0; uint32_t max_gw_factor = 0, tmp_gw_factor = 0; @@ -112,25 +126,17 @@ void gw_election(struct bat_priv *bat_priv) if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) return; - rcu_read_lock(); - curr_gw = rcu_dereference(bat_priv->curr_gw); - if (curr_gw) { - rcu_read_unlock(); - return; - } + curr_gw = gw_get_selected_gw_node(bat_priv); + if (!curr_gw) + goto out; + rcu_read_lock(); if (hlist_empty(&bat_priv->gw_list)) { - - if (curr_gw) { - rcu_read_unlock(); - bat_dbg(DBG_BATMAN, bat_priv, - "Removing selected gateway - " - "no gateway in range\n"); - gw_deselect(bat_priv); - } else - rcu_read_unlock(); - - return; + bat_dbg(DBG_BATMAN, bat_priv, + "Removing selected gateway - " + "no gateway in range\n"); + gw_deselect(bat_priv); + goto unlock; } hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { @@ -182,7 +188,7 @@ void gw_election(struct bat_priv *bat_priv) if (curr_gw != curr_gw_tmp) { router = orig_node_get_router(curr_gw_tmp->orig_node); if (!router) - goto out; + goto unlock; if ((curr_gw) && (!curr_gw_tmp)) bat_dbg(DBG_BATMAN, bat_priv, @@ -207,8 +213,11 @@ void gw_election(struct bat_priv *bat_priv) gw_select(bat_priv, curr_gw_tmp); } -out: +unlock: rcu_read_unlock(); +out: + if (curr_gw) + gw_node_free_ref(curr_gw); } void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) @@ -217,7 +226,7 @@ void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) struct neigh_node *router_gw = NULL, *router_orig = NULL; uint8_t gw_tq_avg, orig_tq_avg; - curr_gw_orig = gw_get_selected(bat_priv); + curr_gw_orig = gw_get_selected_orig(bat_priv); if (!curr_gw_orig) goto deselect; @@ -299,7 +308,11 @@ 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; + struct gw_node *gw_node, *curr_gw; + + curr_gw = gw_get_selected_gw_node(bat_priv); + if (!curr_gw) + goto out; rcu_read_lock(); hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { @@ -320,22 +333,26 @@ void gw_node_update(struct bat_priv *bat_priv, "Gateway %pM removed from gateway list\n", orig_node->orig); - if (gw_node == rcu_dereference(bat_priv->curr_gw)) { - rcu_read_unlock(); - gw_deselect(bat_priv); - return; - } + if (gw_node == curr_gw) + goto deselect; } - rcu_read_unlock(); - return; + goto unlock; } - rcu_read_unlock(); if (new_gwflags == 0) - return; + goto unlock; gw_node_add(bat_priv, orig_node, new_gwflags); + goto unlock; + +deselect: + gw_deselect(bat_priv); +unlock: + rcu_read_unlock(); +out: + if (curr_gw) + gw_node_free_ref(curr_gw); } void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) @@ -345,9 +362,12 @@ void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) void gw_node_purge(struct bat_priv *bat_priv) { - struct gw_node *gw_node; + struct gw_node *gw_node, *curr_gw; struct hlist_node *node, *node_tmp; unsigned long timeout = 2 * PURGE_TIMEOUT * HZ; + char do_deselect = 0; + + curr_gw = gw_get_selected_gw_node(bat_priv); spin_lock_bh(&bat_priv->gw_list_lock); @@ -358,15 +378,21 @@ void gw_node_purge(struct bat_priv *bat_priv) atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) continue; - if (rcu_dereference(bat_priv->curr_gw) == gw_node) - gw_deselect(bat_priv); + if (curr_gw == gw_node) + do_deselect = 1; hlist_del_rcu(&gw_node->list); gw_node_free_ref(gw_node); } - spin_unlock_bh(&bat_priv->gw_list_lock); + + /* gw_deselect() needs to acquire the gw_list_lock */ + if (do_deselect) + gw_deselect(bat_priv); + + if (curr_gw) + gw_node_free_ref(curr_gw); } /** @@ -385,22 +411,22 @@ static int _write_buffer_text(struct bat_priv *bat_priv, if (!router) goto out; - rcu_read_lock(); - curr_gw = rcu_dereference(bat_priv->curr_gw); + curr_gw = gw_get_selected_gw_node(bat_priv); ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", - (curr_gw == gw_node ? "=>" : " "), - gw_node->orig_node->orig, - router->tq_avg, router->addr, - 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")); + (curr_gw == gw_node ? "=>" : " "), + gw_node->orig_node->orig, + router->tq_avg, router->addr, + 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")); - rcu_read_unlock(); neigh_node_free_ref(router); + if (curr_gw) + gw_node_free_ref(curr_gw); out: return ret; } @@ -459,6 +485,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) struct iphdr *iphdr; struct ipv6hdr *ipv6hdr; struct udphdr *udphdr; + struct gw_node *curr_gw; unsigned int header_len = 0; if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) @@ -523,12 +550,11 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) return -1; - rcu_read_lock(); - if (!rcu_dereference(bat_priv->curr_gw)) { - rcu_read_unlock(); + curr_gw = gw_get_selected_gw_node(bat_priv); + if (!curr_gw) return 0; - } - rcu_read_unlock(); + if (curr_gw) + gw_node_free_ref(curr_gw); return 1; } diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h index 97c31d178163..1ce8c6066da1 100644 --- a/net/batman-adv/gateway_client.h +++ b/net/batman-adv/gateway_client.h @@ -24,7 +24,7 @@ void gw_deselect(struct bat_priv *bat_priv); void gw_election(struct bat_priv *bat_priv); -struct orig_node *gw_get_selected(struct bat_priv *bat_priv); +struct orig_node *gw_get_selected_orig(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); diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index 19f84bd443af..d46acc815138 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c @@ -289,7 +289,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* get routing information */ if (is_multicast_ether_addr(ethhdr->h_dest)) { - orig_node = (struct orig_node *)gw_get_selected(bat_priv); + orig_node = (struct orig_node *)gw_get_selected_orig(bat_priv); if (orig_node) goto find_router; } -- GitLab From ba85fac28005a59e6e03fdb13918fc6f6e69a3ca Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Sun, 17 Apr 2011 20:34:27 +0200 Subject: [PATCH 1070/5560] batman-adv: protect softif_neigh by rcu Add get/set wrapper functions for softif_neigh and use rcu functions to manipulate the pointers. Signed-off-by: Simon Wunderlich Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/soft-interface.c | 114 ++++++++++++++++++++++++-------- net/batman-adv/types.h | 2 +- 2 files changed, 88 insertions(+), 28 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 9ed26140a269..ad6da4c7ddb5 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -90,10 +90,51 @@ static void softif_neigh_free_ref(struct softif_neigh *softif_neigh) call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); } +static struct softif_neigh *softif_neigh_get_selected(struct bat_priv *bat_priv) +{ + struct softif_neigh *neigh; + + rcu_read_lock(); + neigh = rcu_dereference(bat_priv->softif_neigh); + + if (neigh && !atomic_inc_not_zero(&neigh->refcount)) + neigh = NULL; + + rcu_read_unlock(); + return neigh; +} + +static void softif_neigh_select(struct bat_priv *bat_priv, + struct softif_neigh *new_neigh) +{ + struct softif_neigh *curr_neigh; + + spin_lock_bh(&bat_priv->softif_neigh_lock); + + if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount)) + new_neigh = NULL; + + curr_neigh = bat_priv->softif_neigh; + rcu_assign_pointer(bat_priv->softif_neigh, new_neigh); + + if (curr_neigh) + softif_neigh_free_ref(curr_neigh); + + spin_unlock_bh(&bat_priv->softif_neigh_lock); +} + +static void softif_neigh_deselect(struct bat_priv *bat_priv) +{ + softif_neigh_select(bat_priv, NULL); +} + void softif_neigh_purge(struct bat_priv *bat_priv) { - struct softif_neigh *softif_neigh, *softif_neigh_tmp; + struct softif_neigh *softif_neigh, *curr_softif_neigh; struct hlist_node *node, *node_tmp; + char do_deselect = 0; + + curr_softif_neigh = softif_neigh_get_selected(bat_priv); spin_lock_bh(&bat_priv->softif_neigh_lock); @@ -105,22 +146,26 @@ void softif_neigh_purge(struct bat_priv *bat_priv) (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) continue; - hlist_del_rcu(&softif_neigh->list); - - if (bat_priv->softif_neigh == softif_neigh) { + if (curr_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; - softif_neigh_free_ref(softif_neigh_tmp); + do_deselect = 1; } + hlist_del_rcu(&softif_neigh->list); softif_neigh_free_ref(softif_neigh); } spin_unlock_bh(&bat_priv->softif_neigh_lock); + + /* soft_neigh_deselect() needs to acquire the softif_neigh_lock */ + if (do_deselect) + softif_neigh_deselect(bat_priv); + + if (curr_softif_neigh) + softif_neigh_free_ref(curr_softif_neigh); } static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, @@ -171,6 +216,7 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) struct bat_priv *bat_priv = netdev_priv(net_dev); struct softif_neigh *softif_neigh; struct hlist_node *node; + struct softif_neigh *curr_softif_neigh; if (!bat_priv->primary_if) { return seq_printf(seq, "BATMAN mesh %s disabled - " @@ -180,14 +226,17 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); + curr_softif_neigh = softif_neigh_get_selected(bat_priv); rcu_read_lock(); hlist_for_each_entry_rcu(softif_neigh, node, &bat_priv->softif_neigh_list, list) seq_printf(seq, "%s %pM (vid: %d)\n", - bat_priv->softif_neigh == softif_neigh + curr_softif_neigh == softif_neigh ? "=>" : " ", softif_neigh->addr, softif_neigh->vid); rcu_read_unlock(); + if (curr_softif_neigh) + softif_neigh_free_ref(curr_softif_neigh); return 0; } @@ -198,7 +247,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, 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; + struct softif_neigh *softif_neigh; + struct softif_neigh *curr_softif_neigh = NULL; if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) batman_packet = (struct batman_packet *) @@ -223,7 +273,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, if (!softif_neigh) goto err; - if (bat_priv->softif_neigh == softif_neigh) + curr_softif_neigh = softif_neigh_get_selected(bat_priv); + if (curr_softif_neigh == softif_neigh) goto out; /* we got a neighbor but its mac is 'bigger' than ours */ @@ -232,38 +283,39 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, goto out; /* switch to new 'smallest neighbor' */ - if ((bat_priv->softif_neigh) && - (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr, + if ((curr_softif_neigh) && + (memcmp(softif_neigh->addr, curr_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, + curr_softif_neigh->addr, + curr_softif_neigh->vid, softif_neigh->addr, softif_neigh->vid); - softif_neigh_tmp = bat_priv->softif_neigh; - bat_priv->softif_neigh = softif_neigh; - softif_neigh_free_ref(softif_neigh_tmp); - /* we need to hold the additional reference */ - goto err; + + softif_neigh_select(bat_priv, softif_neigh); + goto out; } /* close own batX device and use softif_neigh as exit node */ - if ((!bat_priv->softif_neigh) && + if ((!curr_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; + + softif_neigh_select(bat_priv, softif_neigh); + goto out; } out: softif_neigh_free_ref(softif_neigh); err: kfree_skb(skb); + if (curr_softif_neigh) + softif_neigh_free_ref(curr_softif_neigh); + return; } @@ -321,6 +373,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) struct bat_priv *bat_priv = netdev_priv(soft_iface); struct bcast_packet *bcast_packet; struct vlan_ethhdr *vhdr; + struct softif_neigh *curr_softif_neigh = NULL; int data_len = skb->len, ret; short vid = -1; bool do_bcast = false; @@ -348,7 +401,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) * 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)) + curr_softif_neigh = softif_neigh_get_selected(bat_priv); + if ((curr_softif_neigh) && (curr_softif_neigh->vid == vid)) goto dropped; /* TODO: check this for locks */ @@ -410,6 +464,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) dropped_freed: bat_priv->stats.tx_dropped++; end: + if (curr_softif_neigh) + softif_neigh_free_ref(curr_softif_neigh); return NETDEV_TX_OK; } @@ -421,6 +477,7 @@ void interface_rx(struct net_device *soft_iface, struct unicast_packet *unicast_packet; struct ethhdr *ethhdr; struct vlan_ethhdr *vhdr; + struct softif_neigh *curr_softif_neigh = NULL; short vid = -1; int ret; @@ -450,7 +507,8 @@ void interface_rx(struct net_device *soft_iface, * 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)) { + curr_softif_neigh = softif_neigh_get_selected(bat_priv); + if (curr_softif_neigh && (curr_softif_neigh->vid == vid)) { skb_push(skb, hdr_size); unicast_packet = (struct unicast_packet *)skb->data; @@ -461,7 +519,7 @@ void interface_rx(struct net_device *soft_iface, skb_reset_mac_header(skb); memcpy(unicast_packet->dest, - bat_priv->softif_neigh->addr, ETH_ALEN); + curr_softif_neigh->addr, ETH_ALEN); ret = route_unicast_packet(skb, recv_if); if (ret == NET_RX_DROP) goto dropped; @@ -486,11 +544,13 @@ void interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; netif_rx(skb); - return; + goto out; dropped: kfree_skb(skb); out: + if (curr_softif_neigh) + softif_neigh_free_ref(curr_softif_neigh); return; } diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 091476df4f0e..75123b1ae0de 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -147,7 +147,7 @@ struct bat_priv { atomic_t batman_queue_left; char num_ifaces; struct hlist_head softif_neigh_list; - struct softif_neigh *softif_neigh; + struct softif_neigh __rcu *softif_neigh; struct debug_log *debug_log; struct hard_iface *primary_if; struct kobject *mesh_obj; -- GitLab From af20b710479ae662829cf739b521390daa7fcbcb Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 17 Apr 2011 20:39:07 +0200 Subject: [PATCH 1071/5560] batman-adv: Set the txqueuelen to zero when creating soft interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like other virtual interfaces, e.g. br0, we don't need a transmit queue. Packets should only be queued on real interfaces which are underneath. In practice this patch makes little difference since the virtual interfaces can accept packets as fast as they come, but the patch will avoid bufferbloat questions to the mailling lists in the future. Signed-off-by: Andrew Lunn Tested-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann --- net/batman-adv/soft-interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index ad6da4c7ddb5..58ce4400d581 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -584,6 +584,7 @@ static void interface_setup(struct net_device *dev) dev->hard_start_xmit = interface_tx; #endif dev->destructor = free_netdev; + dev->tx_queue_len = 0; /** * can't call min_mtu, because the needed variables -- GitLab From a713c3bbb5a6736e673940eb97d9bf2c27aec4c5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:22:33 -0700 Subject: [PATCH 1072/5560] isdn: gigaset: Fix set-but-unused variable. The variable 'offset' is set but unused in write_iso_tasklet(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/gigaset/bas-gigaset.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 8a3c5cfc4fea..3913f47ef86d 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -1157,7 +1157,6 @@ static void write_iso_tasklet(unsigned long data) struct urb *urb; int status; struct usb_iso_packet_descriptor *ifd; - int offset; unsigned long flags; int i; struct sk_buff *skb; @@ -1225,7 +1224,6 @@ static void write_iso_tasklet(unsigned long data) * successfully sent * - all following frames are not sent at all */ - offset = done->limit; /* default (no error) */ for (i = 0; i < BAS_NUMFRAMES; i++) { ifd = &urb->iso_frame_desc[i]; if (ifd->status || @@ -1235,9 +1233,6 @@ static void write_iso_tasklet(unsigned long data) i, ifd->actual_length, ifd->length, get_usb_statmsg(ifd->status)); - offset = (ifd->offset + - ifd->actual_length) - % BAS_OUTBUFSIZE; break; } } -- GitLab From 2d09d567127e85dddd027d049196093640025c36 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:23:22 -0700 Subject: [PATCH 1073/5560] isdn: eicon: Fix set-but-unused variables. The variable 'best_id' is set but unused in diva_mnt_add_xdi_adapter(). Just kill it off. Similarly for the variable 'CIP' in connect_req(), 'Number' in sig_ind(), 'Info' in dtmf_confirmation() mixer_command() fax_connect_ack_command() fax_edata_ack_command() rtp_connect_b3_res_command() and rtp_connect_b3_res_command(), and 'a' in mixer_indication_coefs_set(), Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/debug.c | 3 +-- drivers/isdn/hardware/eicon/message.c | 23 ++--------------------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 362640120886..7a9894cb4557 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c @@ -861,7 +861,7 @@ static int diva_get_idi_adapter_info (IDI_CALL request, dword* serial, dword* lo void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { diva_os_spin_lock_magic_t old_irql, old_irql1; dword sec, usec, logical, serial, org_mask; - int id, best_id = 0, free_id = -1; + int id, free_id = -1; char tmp[128]; diva_dbg_entry_head_t* pmsg = NULL; int len; @@ -906,7 +906,6 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { and slot is still free - reuse it */ free_id = id; - best_id = 1; break; } } diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index 8c5c563c4f12..a3395986df3d 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -1198,7 +1198,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, word ch; word i; word Info; - word CIP; byte LinkLayer; API_PARSE * ai; API_PARSE * bp; @@ -1340,7 +1339,6 @@ static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, add_s(plci,BC,&parms[6]); add_s(plci,LLC,&parms[7]); add_s(plci,HLC,&parms[8]); - CIP = GET_WORD(parms[0].info); if (a->Info_Mask[appl->Id-1] & 0x200) { /* early B3 connect (CIP mask bit 9) no release after a disc */ @@ -4830,7 +4828,6 @@ static void sig_ind(PLCI *plci) dword x_Id; dword Id; dword rId; - word Number = 0; word i; word cip; dword cip_mask; @@ -5106,7 +5103,7 @@ static void sig_ind(PLCI *plci) } } - if(plci->appl) Number = plci->appl->Number++; + if(plci->appl) plci->appl->Number++; switch(plci->Sig.Ind) { /* Response to Get_Supported_Services request */ @@ -5894,7 +5891,6 @@ static void sig_ind(PLCI *plci) break; case TEL_CTRL: - Number = 0; ie = multi_fac_parms[0]; /* inspect the facility hook indications */ if(plci->State==ADVANCED_VOICE_SIG && ie[0]){ switch (ie[1]&0x91) { @@ -10119,14 +10115,12 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI static void dtmf_confirmation (dword Id, PLCI *plci) { - word Info; word i; byte result[4]; dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation", UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = GOOD; result[0] = 2; PUT_WORD (&result[1], DTMF_SUCCESS); if (plci->dtmf_send_requests != 0) @@ -11520,13 +11514,12 @@ static word mixer_restore_config (dword Id, PLCI *plci, byte Rc) static void mixer_command (dword Id, PLCI *plci, byte Rc) { DIVA_CAPI_ADAPTER *a; - word i, internal_command, Info; + word i, internal_command; dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x", UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, plci->li_cmd)); - Info = GOOD; a = plci->adapter; internal_command = plci->internal_command; plci->internal_command = 0; @@ -11550,7 +11543,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc) { dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed", UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; break; } if (plci->internal_command) @@ -11592,7 +11584,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc) } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)); } - Info = _FACILITY_NOT_SUPPORTED; break; } if (plci->internal_command) @@ -11610,7 +11601,6 @@ static void mixer_command (dword Id, PLCI *plci, byte Rc) { dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed", UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; break; } if (plci->internal_command) @@ -12448,13 +12438,11 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI static void mixer_indication_coefs_set (dword Id, PLCI *plci) { dword d; - DIVA_CAPI_ADAPTER *a; byte result[12]; dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set", UnMapId (Id), (char *)(FILE_), __LINE__)); - a = plci->adapter; if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos) { do @@ -14111,13 +14099,11 @@ static void select_b_command (dword Id, PLCI *plci, byte Rc) static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc) { - word Info; word internal_command; dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x", UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - Info = GOOD; internal_command = plci->internal_command; plci->internal_command = 0; switch (internal_command) @@ -14160,13 +14146,11 @@ static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc) static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc) { - word Info; word internal_command; dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x", UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - Info = GOOD; internal_command = plci->internal_command; plci->internal_command = 0; switch (internal_command) @@ -14395,13 +14379,11 @@ static void rtp_connect_b3_req_command (dword Id, PLCI *plci, byte Rc) static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc) { - word Info; word internal_command; dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x", UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - Info = GOOD; internal_command = plci->internal_command; plci->internal_command = 0; switch (internal_command) @@ -14423,7 +14405,6 @@ static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc) { dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x", UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; break; } if (plci_nl_busy (plci)) -- GitLab From a719e0a81f8ab1e96301aada203be1c43788aec7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:34:50 -0700 Subject: [PATCH 1074/5560] isdn: hfcpci: Fix set-but-unused variables. The variable 'total' is set but unused in hfcpci_empty_bfifo(). Just kill it off. Similarly for the variable 'val' in ph_state_nt(). Signed-off-by: David S. Miller --- drivers/isdn/hardware/mISDN/hfcpci.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 4343abac0b13..b01a7be1300f 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -405,7 +405,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz, u_char *bdata, int count) { u_char *ptr, *ptr1, new_f2; - int total, maxlen, new_z2; + int maxlen, new_z2; struct zt *zp; if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) @@ -431,7 +431,6 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz, printk(KERN_WARNING "HFCPCI: receive out of memory\n"); return; } - total = count; count -= 3; ptr = skb_put(bch->rx_skb, count); @@ -968,7 +967,6 @@ static void ph_state_nt(struct dchannel *dch) { struct hfc_pci *hc = dch->hw; - u_char val; if (dch->debug) printk(KERN_DEBUG "%s: NT newstate %x\n", @@ -982,7 +980,7 @@ ph_state_nt(struct dchannel *dch) hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); /* Clear already pending ints */ - val = Read_hfc(hc, HFCPCI_INT_S1); + (void) Read_hfc(hc, HFCPCI_INT_S1); Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); udelay(10); Write_hfc(hc, HFCPCI_STATES, 4); -- GitLab From 3c76c58fca03c1162ab8592f71c996e933af3a9e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:35:27 -0700 Subject: [PATCH 1075/5560] isdn: hfcsusb: Fix set-but-unused variables. The variable 'buf' is set but unused in ctrl_complete(). Just kill it off. Similarly for the variable 'err' in setup_hfcsusb(). Signed-off-by: David S. Miller --- drivers/isdn/hardware/mISDN/hfcsusb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index 8700474747e8..3ccbff13eaf2 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -118,14 +118,12 @@ static void ctrl_complete(struct urb *urb) { struct hfcsusb *hw = (struct hfcsusb *) urb->context; - struct ctrl_buf *buf; if (debug & DBG_HFC_CALL_TRACE) printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); urb->dev = hw->dev; if (hw->ctrl_cnt) { - buf = &hw->ctrl_buff[hw->ctrl_out_idx]; hw->ctrl_cnt--; /* decrement actual count */ if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hw->ctrl_out_idx = 0; /* pointer wrap */ @@ -1726,7 +1724,6 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel) static int setup_hfcsusb(struct hfcsusb *hw) { - int err; u_char b; if (debug & DBG_HFC_CALL_TRACE) @@ -1745,7 +1742,7 @@ setup_hfcsusb(struct hfcsusb *hw) } /* first set the needed config, interface and alternate */ - err = usb_set_interface(hw->dev, hw->if_used, hw->alt_used); + (void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used); hw->led_state = 0; -- GitLab From 011bc1ef447dd6aa969d9c83a90fe3df360b5d6e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:36:28 -0700 Subject: [PATCH 1076/5560] isdn: arcofi: Fix set-but-unused variables. The variable 'val' is set but unused in send_arcofi(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/arcofi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/isdn/hisax/arcofi.c b/drivers/isdn/hisax/arcofi.c index 85a8fd8dd0b7..21cbbe1d5563 100644 --- a/drivers/isdn/hisax/arcofi.c +++ b/drivers/isdn/hisax/arcofi.c @@ -30,8 +30,6 @@ add_arcofi_timer(struct IsdnCardState *cs) { static void send_arcofi(struct IsdnCardState *cs) { - u_char val; - add_arcofi_timer(cs); cs->dc.isac.mon_txp = 0; cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len; @@ -45,7 +43,7 @@ send_arcofi(struct IsdnCardState *cs) { cs->dc.isac.mocr &= 0x0f; cs->dc.isac.mocr |= 0xa0; cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); - val = cs->readisac(cs, ISAC_MOSR); + (void) cs->readisac(cs, ISAC_MOSR); cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); cs->dc.isac.mocr |= 0x10; cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); -- GitLab From 94dbe1ae44df1d22a391980eb6bd502f937b1af8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:37:11 -0700 Subject: [PATCH 1077/5560] isdn: elsa_cs: Fix set-but-unused variables. The variable 'dev' is set but unused in elsa_cs_config(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/elsa_cs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 496d477af0f8..9e5e87be756b 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -129,12 +129,10 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) static int __devinit elsa_cs_config(struct pcmcia_device *link) { - local_info_t *dev; int i; IsdnCard_t icard; dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); - dev = link->priv; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; -- GitLab From db47367451cbee4e8a3fd9389cc341f4acc43b1e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:38:33 -0700 Subject: [PATCH 1078/5560] isdn: elsa_ser: Fix set-but-unused variables. The variable 'bits' is set but unused in change_speed(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/elsa_ser.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index cbda3790a10d..3fa9f6171095 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c @@ -109,11 +109,10 @@ static void change_speed(struct IsdnCardState *cs, int baud) { int quot = 0, baud_base; unsigned cval, fcr = 0; - int bits; /* byte size and parity */ - cval = 0x03; bits = 10; + cval = 0x03; /* Determine divisor based on baud rate */ baud_base = BASE_BAUD; quot = baud_base / baud; -- GitLab From a1e6216d1b5035db1d4c018cf841d3267f949281 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:39:18 -0700 Subject: [PATCH 1079/5560] isdn: hfc_usb: Fix set-but-unused variables. The variable 'buf' is set but unused in ctrl_complete(). Just kill it off. Similarly for 'err' in hfc_usb_init(). Signed-off-by: David S. Miller --- drivers/isdn/hisax/hfc_usb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index ed9527aa5f2c..f407de0e006d 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -258,11 +258,9 @@ static void ctrl_complete(struct urb *urb) { hfcusb_data *hfc = (hfcusb_data *) urb->context; - ctrl_buft *buf; urb->dev = hfc->dev; if (hfc->ctrl_cnt) { - buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; hfc->ctrl_cnt--; /* decrement actual count */ if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_out_idx = 0; /* pointer wrap */ @@ -1097,7 +1095,7 @@ static int hfc_usb_init(hfcusb_data * hfc) { usb_fifo *fifo; - int i, err; + int i; u_char b; struct hisax_b_if *p_b_if[2]; @@ -1112,7 +1110,7 @@ hfc_usb_init(hfcusb_data * hfc) } /* first set the needed config, interface and alternate */ - err = usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used); + usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used); /* do Chip reset */ write_usb(hfc, HFCUSB_CIRM, 8); -- GitLab From d462003ddbb28926109396b9038299fc740c2efc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:40:30 -0700 Subject: [PATCH 1080/5560] isdn: ipacx: Fix set-but-unused variables. The variable 'cda2_cr' is set but unused in ctrl_complete(). Just kill it off. Keep the cs->readisac() call just in case the register read has side effects. Signed-off-by: David S. Miller --- drivers/isdn/hisax/ipacx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index 332104103e18..690840444184 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c @@ -96,7 +96,7 @@ dch_l2l1(struct PStack *st, int pr, void *arg) { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; - u_char cda1_cr, cda2_cr; + u_char cda1_cr; switch (pr) { case (PH_DATA |REQUEST): @@ -163,7 +163,7 @@ dch_l2l1(struct PStack *st, int pr, void *arg) cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1 cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1 cda1_cr = cs->readisac(cs, IPACX_CDA1_CR); - cda2_cr = cs->readisac(cs, IPACX_CDA2_CR); + (void) cs->readisac(cs, IPACX_CDA2_CR); if ((long)arg &1) { // loop B1 cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a); } -- GitLab From f6f0e4a7a343f85dd773f6f18e553933c4367e96 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:41:29 -0700 Subject: [PATCH 1081/5560] isdn: jade: Fix set-but-unused variables. The variable 'i' is set but unused in JadeVersion(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/jade.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index ea8f840871d0..a06cea09158b 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c @@ -23,10 +23,9 @@ int JadeVersion(struct IsdnCardState *cs, char *s) { - int ver,i; + int ver; int to = 50; cs->BC_Write_Reg(cs, -1, 0x50, 0x19); - i=0; while (to) { udelay(1); ver = cs->BC_Read_Reg(cs, -1, 0x60); -- GitLab From cf117eafa0dc17c6f973d078d4e0bf2069f45ce7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:42:15 -0700 Subject: [PATCH 1082/5560] isdn: l3dss1: Fix set-but-unused variables. The variable 'cause' is set but unused in dss1up(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/l3dss1.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index 8e2fd02ecce0..b0d9ab1f21c0 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c @@ -2943,7 +2943,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb) static void dss1up(struct PStack *st, int pr, void *arg) { - int i, mt, cr, cause, callState; + int i, mt, cr, callState; char *ptr; u_char *p; struct sk_buff *skb = arg; @@ -3034,12 +3034,10 @@ dss1up(struct PStack *st, int pr, void *arg) return; } } else if (mt == MT_STATUS) { - cause = 0; if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) { ptr++; if (*ptr++ == 2) ptr++; - cause = *ptr & 0x7f; } callState = 0; if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) { -- GitLab From 1397c5df2547f3296ad37a0c77daff3b124b98c8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:43:20 -0700 Subject: [PATCH 1083/5560] isdn: l3ni1: Fix set-but-unused variables. The variable 'cause' is set but unused in ni1up(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/l3ni1.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 7b229c0ce115..092dcbb39d94 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -2883,7 +2883,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb) static void ni1up(struct PStack *st, int pr, void *arg) { - int i, mt, cr, cause, callState; + int i, mt, cr, callState; char *ptr; u_char *p; struct sk_buff *skb = arg; @@ -2986,12 +2986,10 @@ ni1up(struct PStack *st, int pr, void *arg) return; } } else if (mt == MT_STATUS) { - cause = 0; if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) { ptr++; if (*ptr++ == 2) ptr++; - cause = *ptr & 0x7f; } callState = 0; if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) { -- GitLab From 8c85290d84eaa7b3ba605090987d2136a3302ca9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:44:12 -0700 Subject: [PATCH 1084/5560] isdn: teles_cs: Fix set-but-unused variables. The variable 'dev' is set but unused in teles_cs_config(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/hisax/teles_cs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index aa25e183bf79..360f9ec7c802 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -111,12 +111,10 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) static int __devinit teles_cs_config(struct pcmcia_device *link) { - local_info_t *dev; int i; IsdnCard_t icard; dev_dbg(&link->dev, "teles_config(0x%p)\n", link); - dev = link->priv; i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); if (i != 0) -- GitLab From 50a7c114c2673f3fcbb0ba5d659049156e1ccd50 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:45:51 -0700 Subject: [PATCH 1085/5560] isdn: i4l: isdn_common: Fix set-but-unused variables. The variable 'ch' is set but unused in isdn_capi_rec_hl_msg(). Just kill it off. Similarly for 'chidx' in isdn_ioctl() and 'di' in isdn_capi_rec_hl_msg(). Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_common.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 15632bd2f643..6ed82add6ffa 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -399,13 +399,8 @@ isdn_all_eaz(int di, int ch) #include static int -isdn_capi_rec_hl_msg(capi_msg *cm) { - - int di; - int ch; - - di = (cm->adr.Controller & 0x7f) -1; - ch = isdn_dc2minor(di, (cm->adr.Controller>>8)& 0x7f); +isdn_capi_rec_hl_msg(capi_msg *cm) +{ switch(cm->Command) { case CAPI_FACILITY: /* in the moment only handled in tty */ @@ -1278,7 +1273,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) uint minor = iminor(file->f_path.dentry->d_inode); isdn_ctrl c; int drvidx; - int chidx; int ret; int i; char __user *p; @@ -1340,7 +1334,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) drvidx = isdn_minor2drv(minor); if (drvidx < 0) return -ENODEV; - chidx = isdn_minor2chan(minor); if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) return -ENODEV; return 0; -- GitLab From 07f46f80f4ca4ddb700ff40a19876ba1b3242917 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:46:50 -0700 Subject: [PATCH 1086/5560] isdn: i4l: isdn_net: Fix set-but-unused variables. The variable 'unused' is set but unused in isdn_net_ciscohdlck_slarp_in(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_net.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 2a7d17c19489..97988111e45a 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -1678,7 +1678,6 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb) u32 your_seq; __be32 local; __be32 *addr, *mask; - u16 unused; if (skb->len < 14) return; @@ -1722,7 +1721,6 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb) lp->cisco_last_slarp_in = jiffies; my_seq = be32_to_cpup((__be32 *)(p + 0)); your_seq = be32_to_cpup((__be32 *)(p + 4)); - unused = be16_to_cpup((__be16 *)(p + 8)); p += 10; lp->cisco_yourseq = my_seq; lp->cisco_mineseen = your_seq; -- GitLab From 81b424d9e2ef815b2035d4c2be0bc41dddbebc06 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:48:53 -0700 Subject: [PATCH 1087/5560] isdn: mISDN: socket: Fix set-but-unused variables. The variable 'len' is set but unused in data_sock_getsockopt(). The code should use 'len' to validate that the user's socket option is indeed the right size. Signed-off-by: David S. Miller --- drivers/isdn/mISDN/socket.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index 7446d8b4282d..8e325227b4c0 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -457,6 +457,9 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname, if (get_user(len, optlen)) return -EFAULT; + if (len != sizeof(char)) + return -EINVAL; + switch (optname) { case MISDN_TIME_STAMP: if (_pms(sk)->cmask & MISDN_TIME_STAMP) -- GitLab From 585985429080a449e0ecf66dd485899a8765c26c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:51:36 -0700 Subject: [PATCH 1088/5560] bna: Fix set-but-unused variables. The variable 'pgoff' is set but unused in bfa_nw_ioc_fwver_get() and bfa_ioc_download_fw(). Similarly for 'cmd_h' in bna_mbox_flush_q and the entirety of bna_rit_mod_uninit() is unused since variables are purely set but no action is made using them. Same for 'bna' in bna_rit_create() and 'ret' in bna_rx_create(). Just kill them off. Signed-off-by: David S. Miller --- drivers/net/bna/bfa_ioc.c | 6 ++---- drivers/net/bna/bna_ctrl.c | 21 --------------------- drivers/net/bna/bna_txrx.c | 7 ++----- 3 files changed, 4 insertions(+), 30 deletions(-) diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c index e3de0b8625cd..c1c9e70eec2f 100644 --- a/drivers/net/bna/bfa_ioc.c +++ b/drivers/net/bna/bfa_ioc.c @@ -1272,13 +1272,12 @@ bfa_ioc_lpu_stop(struct bfa_ioc *ioc) void bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) { - u32 pgnum, pgoff; + u32 pgnum; u32 loff = 0; int i; u32 *fwsig = (u32 *) fwhdr; pgnum = bfa_ioc_smem_pgnum(ioc, loff); - pgoff = bfa_ioc_smem_pgoff(ioc, loff); writel(pgnum, ioc->ioc_regs.host_page_num_fn); for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); @@ -1509,7 +1508,7 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) { u32 *fwimg; - u32 pgnum, pgoff; + u32 pgnum; u32 loff = 0; u32 chunkno = 0; u32 i; @@ -1522,7 +1521,6 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); pgnum = bfa_ioc_smem_pgnum(ioc, loff); - pgoff = bfa_ioc_smem_pgoff(ioc, loff); writel(pgnum, ioc->ioc_regs.host_page_num_fn); diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c index e1527472b961..53b14169e363 100644 --- a/drivers/net/bna/bna_ctrl.c +++ b/drivers/net/bna/bna_ctrl.c @@ -246,7 +246,6 @@ static void bna_mbox_flush_q(struct bna *bna, struct list_head *q) { struct bna_mbox_qe *mb_qe = NULL; - struct bfi_mhdr *cmd_h; struct list_head *mb_q; void (*cbfn)(void *arg, int status); void *cbarg; @@ -260,7 +259,6 @@ bna_mbox_flush_q(struct bna *bna, struct list_head *q) bfa_q_qe_init(mb_qe); bna->mbox_mod.msg_pending--; - cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]); if (cbfn) cbfn(cbarg, BNA_CB_NOT_EXEC); } @@ -2774,23 +2772,6 @@ bna_rit_mod_init(struct bna_rit_mod *rit_mod, } } -static void -bna_rit_mod_uninit(struct bna_rit_mod *rit_mod) -{ - struct bna_rit_segment *rit_segment; - struct list_head *qe; - int i; - int j; - - for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { - j = 0; - list_for_each(qe, &rit_mod->rit_seg_pool[i]) { - rit_segment = (struct bna_rit_segment *)qe; - j++; - } - } -} - /* * Public functions */ @@ -2977,8 +2958,6 @@ bna_uninit(struct bna *bna) bna_ucam_mod_uninit(&bna->ucam_mod); - bna_rit_mod_uninit(&bna->rit_mod); - bna_ib_mod_uninit(&bna->ib_mod); bna_rx_mod_uninit(&bna->rx_mod); diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c index 58c7664040dc..380085cc3088 100644 --- a/drivers/net/bna/bna_txrx.c +++ b/drivers/net/bna/bna_txrx.c @@ -2229,14 +2229,11 @@ void bna_rit_create(struct bna_rx *rx) { struct list_head *qe_rxp; - struct bna *bna; struct bna_rxp *rxp; struct bna_rxq *q0 = NULL; struct bna_rxq *q1 = NULL; int offset; - bna = rx->bna; - offset = 0; list_for_each(qe_rxp, &rx->rxp_q) { rxp = (struct bna_rxp *)qe_rxp; @@ -2830,7 +2827,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad, struct bna_mem_descr *dsqpt_mem; /* s/w qpt for data */ struct bna_mem_descr *hpage_mem; /* hdr page mem */ struct bna_mem_descr *dpage_mem; /* data page mem */ - int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret; + int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0; int dpage_count, hpage_count, rcb_idx; struct bna_ib_config ibcfg; /* Fail if we don't have enough RXPs, RXQs */ @@ -2924,7 +2921,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad, ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO; ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE; - ret = bna_ib_config(rxp->cq.ib, &ibcfg); + bna_ib_config(rxp->cq.ib, &ibcfg); /* Link rxqs to rxp */ _rxp_add_rxqs(rxp, q0, q1); -- GitLab From b8ee8328bac0d8420d2b9ef4838d0df25df100ab Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:56:12 -0700 Subject: [PATCH 1089/5560] bnx2x: Fix set-but-unused variables. The variable 'rc' is set but unused in bnx2x_timer(). Similarly for 'hc_index_p' in bnx2x_init_sb(), and 'port' in bnx2x_get_hwinfo(). Just kill them off. Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 696e84afdc53..bfd7ac98248b 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -3904,10 +3904,9 @@ static void bnx2x_timer(unsigned long data) if (poll) { struct bnx2x_fastpath *fp = &bp->fp[0]; - int rc; bnx2x_tx_int(fp); - rc = bnx2x_rx_int(fp, 1000); + bnx2x_rx_int(fp, 1000); } if (!BP_NOMCP(bp)) { @@ -4062,7 +4061,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, struct hc_status_block_data_e2 sb_data_e2; struct hc_status_block_data_e1x sb_data_e1x; struct hc_status_block_sm *hc_sm_p; - struct hc_index_data *hc_index_p; int data_size; u32 *sb_data_p; @@ -4083,7 +4081,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping); sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping); hc_sm_p = sb_data_e2.common.state_machine; - hc_index_p = sb_data_e2.index_data; sb_data_p = (u32 *)&sb_data_e2; data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); } else { @@ -4097,7 +4094,6 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); hc_sm_p = sb_data_e1x.common.state_machine; - hc_index_p = sb_data_e1x.index_data; sb_data_p = (u32 *)&sb_data_e1x; data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); } @@ -8635,7 +8631,7 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) { int /*abs*/func = BP_ABS_FUNC(bp); - int vn, port; + int vn; u32 val = 0; int rc = 0; @@ -8670,7 +8666,6 @@ 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, -- GitLab From 056693a38e56c520e208409d221cbc077282c19d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:57:55 -0700 Subject: [PATCH 1090/5560] caif: Fix set-but-unused variables. The variable 'caifdef' is set but unused in modemcmd(). Similarly for 'net' in receive(), and 'res' in caif_device_notify() and caif_exit_net(). Just kill them off. Signed-off-by: David S. Miller --- net/caif/caif_dev.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index a518fdd4da0a..75e00d59eb49 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -133,9 +133,7 @@ static int transmit(struct cflayer *layer, struct cfpkt *pkt) static int modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) { struct caif_device_entry *caifd; - struct caif_dev_common *caifdev; caifd = container_of(layr, struct caif_device_entry, layer); - caifdev = netdev_priv(caifd->netdev); if (ctrl == _CAIF_MODEMCMD_PHYIF_USEFULL) { atomic_set(&caifd->in_use, 1); wake_up_interruptible(&caifd->event); @@ -154,10 +152,8 @@ static int modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) static int receive(struct sk_buff *skb, struct net_device *dev, struct packet_type *pkttype, struct net_device *orig_dev) { - struct net *net; struct cfpkt *pkt; struct caif_device_entry *caifd; - net = dev_net(dev); pkt = cfpkt_fromnative(CAIF_DIR_IN, skb); caifd = caif_get(dev); if (!caifd || !caifd->layer.up || !caifd->layer.up->receive) @@ -195,7 +191,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, struct caif_device_entry *caifd = NULL; struct caif_dev_common *caifdev; enum cfcnfg_phy_preference pref; - int res = -EINVAL; enum cfcnfg_phy_type phy_type; if (dev->type != ARPHRD_CAIF) @@ -210,7 +205,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifdev = netdev_priv(dev); caifdev->flowctrl = dev_flowctrl; atomic_set(&caifd->state, what); - res = 0; break; case NETDEV_UP: @@ -274,7 +268,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, _CAIF_CTRLCMD_PHYIF_DOWN_IND, caifd->layer.id); might_sleep(); - res = wait_event_interruptible_timeout(caifd->event, + wait_event_interruptible_timeout(caifd->event, atomic_read(&caifd->in_use) == 0, TIMEOUT); break; @@ -344,12 +338,11 @@ static int caif_init_net(struct net *net) static void caif_exit_net(struct net *net) { struct net_device *dev; - int res; rtnl_lock(); for_each_netdev(net, dev) { if (dev->type != ARPHRD_CAIF) continue; - res = dev_close(dev); + dev_close(dev); caif_device_destroy(dev); } rtnl_unlock(); -- GitLab From 1627ea35cb10af2f71d38a82de6f6dfb910771ed Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:59:09 -0700 Subject: [PATCH 1091/5560] irda: irlap_event: Fix set-but-unused variables. The variable 'ret' is set but unused in irlap_state_sclose(). Just kill it off. Signed-off-by: David S. Miller --- net/irda/irlap_event.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index bb47021c9a55..ccd214f9d196 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -2227,8 +2227,6 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event, struct sk_buff *skb, struct irlap_info *info) { - int ret = 0; - IRDA_DEBUG(1, "%s()\n", __func__); IRDA_ASSERT(self != NULL, return -ENODEV;); @@ -2289,7 +2287,6 @@ static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event, IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __func__, event, irlap_event[event]); - ret = -EINVAL; break; } -- GitLab From 6385969b3297287e6259a012671be09c78c20620 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 16:59:50 -0700 Subject: [PATCH 1092/5560] irda: irproc: Fix set-but-unused variables. The variable 'd' is set but unused in irda_proc_register(). Just kill it off. Signed-off-by: David S. Miller --- net/irda/irproc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/irda/irproc.c b/net/irda/irproc.c index 318766e5dbdf..b9ac598e2116 100644 --- a/net/irda/irproc.c +++ b/net/irda/irproc.c @@ -65,15 +65,14 @@ static const struct irda_entry irda_dirs[] = { void __init irda_proc_register(void) { int i; - struct proc_dir_entry *d; proc_irda = proc_mkdir("irda", init_net.proc_net); if (proc_irda == NULL) return; for (i = 0; i < ARRAY_SIZE(irda_dirs); i++) - d = proc_create(irda_dirs[i].name, 0, proc_irda, - irda_dirs[i].fops); + (void) proc_create(irda_dirs[i].name, 0, proc_irda, + irda_dirs[i].fops); } /* -- GitLab From 8cb490144708ef295421d0601b0866623651a37e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:01:05 -0700 Subject: [PATCH 1093/5560] l2tp: Fix set-but-unused variables. The variable 'ret' is set but unused in l2tp_nl_register_ops(). This was obviously meant to maintain error codes which are returned to the caller, make it so. Signed-off-by: David S. Miller --- net/l2tp/l2tp_netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 4c1e540732d7..93a41a09458b 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -795,11 +795,12 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops goto out; l2tp_nl_cmd_ops[pw_type] = ops; + ret = 0; out: genl_unlock(); err: - return 0; + return ret; } EXPORT_SYMBOL_GPL(l2tp_nl_register_ops); -- GitLab From dab51d0e0718e7beef26075a9353f09ea2652a4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:01:49 -0700 Subject: [PATCH 1094/5560] netlabel: Fix set-but-unused variables. The variable 'type_str' is set but unused in netlbl_cipsov4_add(). Just kill it off. Signed-off-by: David S. Miller --- net/netlabel/netlabel_cipso_v4.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 5f14c8462e30..bae5756b1626 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -422,7 +422,6 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info) { int ret_val = -EINVAL; - const char *type_str = "(unknown)"; struct netlbl_audit audit_info; if (!info->attrs[NLBL_CIPSOV4_A_DOI] || @@ -432,15 +431,12 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info) netlbl_netlink_auditinfo(skb, &audit_info); switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) { case CIPSO_V4_MAP_TRANS: - type_str = "trans"; ret_val = netlbl_cipsov4_add_std(info, &audit_info); break; case CIPSO_V4_MAP_PASS: - type_str = "pass"; ret_val = netlbl_cipsov4_add_pass(info, &audit_info); break; case CIPSO_V4_MAP_LOCAL: - type_str = "local"; ret_val = netlbl_cipsov4_add_local(info, &audit_info); break; } -- GitLab From d87d7fb381c153f71b7cdfd37f3513edc6d0eb8f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:02:29 -0700 Subject: [PATCH 1095/5560] netfilter: nfnetlink_log: Fix set-but-unused variables. The variable 'tmp_uint' is set but unused in __build_packet_message(). Just kill it off. Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 985e9b76c916..e0ee010935e7 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -381,7 +381,6 @@ __build_packet_message(struct nfulnl_instance *inst, struct nfulnl_msg_packet_hdr pmsg; struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; - __be32 tmp_uint; sk_buff_data_t old_tail = inst->skb->tail; nlh = NLMSG_PUT(inst->skb, 0, 0, @@ -428,7 +427,6 @@ __build_packet_message(struct nfulnl_instance *inst, } if (outdev) { - tmp_uint = htonl(outdev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, htonl(outdev->ifindex)); -- GitLab From d88d7de09875e643e225a5d0883d18152ce5a89b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:03:33 -0700 Subject: [PATCH 1096/5560] netfilter: nf_conntrack_standalone: Fix set-but-unused variables. The variable 'ret' is set but unused in ct_seq_show(). This was obviously meant to be used to propagate error codes to the caller, so make it so. Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_standalone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 0ae142825881..05e9feb101c3 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -245,7 +245,7 @@ static int ct_seq_show(struct seq_file *s, void *v) ret = 0; release: nf_ct_put(ct); - return 0; + return ret; } static const struct seq_operations ct_seq_ops = { -- GitLab From f3c85dd560f26ceae1351e6f83e83f1322761ead Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:04:48 -0700 Subject: [PATCH 1097/5560] netfilter: ip6_tables: Fix set-but-unused variables. The variable 'target' is set but unused in compat_copy_entry_from_user(). Just kill it off. Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6_tables.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 5a1c6f27ffaf..4c1492ff473c 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1578,7 +1578,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, struct xt_table_info *newinfo, unsigned char *base) { struct xt_entry_target *t; - struct xt_target *target; struct ip6t_entry *de; unsigned int origsize; int ret, h; @@ -1600,7 +1599,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, } de->target_offset = e->target_offset - (origsize - *size); t = compat_ip6t_get_target(e); - target = t->u.kernel.target; xt_compat_target_from_user(t, dstptr, size); de->next_offset = e->next_offset - (origsize - *size); -- GitLab From b169f6db40605d0907458d1ff78ceac2b194a44f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:06:15 -0700 Subject: [PATCH 1098/5560] netfilter: ip6table_mangle: Fix set-but-unused variables. The variable 'flowlabel' is set but unused in ip6t_mangle_out(). The intention here was to compare this key to the header value after mangling, and trigger a route lookup on mismatch. Make it so. Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6table_mangle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 679a0a3b7b3c..00d19173db7e 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c @@ -64,7 +64,8 @@ ip6t_mangle_out(struct sk_buff *skb, const struct net_device *out) (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || skb->mark != mark || - ipv6_hdr(skb)->hop_limit != hop_limit)) + ipv6_hdr(skb)->hop_limit != hop_limit || + flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP; return ret; -- GitLab From 9365f11a5321bcff5579799a071a70c5cacb5e65 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:07:57 -0700 Subject: [PATCH 1099/5560] isdn: i4l: isdn_tty: Fix unused-but-set variables. The variable 'fcr' is set but not used in isdn_tty_change_speed(). Just kill it off. Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_tty.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 607d846ae063..d8504279e502 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -998,7 +998,6 @@ isdn_tty_change_speed(modem_info * info) { uint cflag, cval, - fcr, quot; int i; @@ -1037,7 +1036,6 @@ isdn_tty_change_speed(modem_info * info) cval |= UART_LCR_PARITY; if (!(cflag & PARODD)) cval |= UART_LCR_EPAR; - fcr = 0; /* CTS flow control flag and modem status interrupts */ if (cflag & CRTSCTS) { -- GitLab From 03746b0a02d25866a29cd8d7306d221c238d6397 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 17:08:41 -0700 Subject: [PATCH 1100/5560] be2net: Fix unused-but-set variables. The variables 'tx_min' and 'tx_max' are set but not used in be_set_coalesce(). Similarly for 'region' in be_do_flash(). Just kill them off. Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 80226e4801f3..0f645a92bebe 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -205,9 +205,9 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) struct be_rx_obj *rxo; struct be_eq_obj *rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; - u32 tx_max, tx_min, tx_cur; u32 rx_max, rx_min, rx_cur; int status = 0, i; + u32 tx_cur; if (coalesce->use_adaptive_tx_coalesce == 1) return -EINVAL; @@ -246,8 +246,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) } } - tx_max = coalesce->tx_coalesce_usecs_high; - tx_min = coalesce->tx_coalesce_usecs_low; tx_cur = coalesce->tx_coalesce_usecs; if (tx_cur > BE_MAX_EQD) @@ -664,11 +662,9 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) { struct be_adapter *adapter = netdev_priv(netdev); char file_name[ETHTOOL_FLASH_MAX_FILENAME]; - u32 region; file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0; strcpy(file_name, efl->data); - region = efl->region; return be_load_fw(adapter, file_name); } -- GitLab From 391876466670988196786150fc9d9da2f3c7cecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:46 +0000 Subject: [PATCH 1101/5560] net: macvlan: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not much of a conversion anyway - macvlan has no way to change the offload settings independently to its base device. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 78e34e9e4f00..3ad5425b82dd 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -415,7 +415,7 @@ static struct lock_class_key macvlan_netdev_addr_lock_key; #define MACVLAN_FEATURES \ (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ - NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO) + NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM) #define MACVLAN_STATE_MASK \ ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) @@ -517,12 +517,6 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev, snprintf(drvinfo->version, 32, "0.1"); } -static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev) -{ - const struct macvlan_dev *vlan = netdev_priv(dev); - return dev_ethtool_get_rx_csum(vlan->lowerdev); -} - static int macvlan_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -530,18 +524,10 @@ static int macvlan_ethtool_get_settings(struct net_device *dev, return dev_ethtool_get_settings(vlan->lowerdev, cmd); } -static u32 macvlan_ethtool_get_flags(struct net_device *dev) -{ - const struct macvlan_dev *vlan = netdev_priv(dev); - return dev_ethtool_get_flags(vlan->lowerdev); -} - static const struct ethtool_ops macvlan_ethtool_ops = { .get_link = ethtool_op_get_link, .get_settings = macvlan_ethtool_get_settings, - .get_rx_csum = macvlan_ethtool_get_rx_csum, .get_drvinfo = macvlan_ethtool_get_drvinfo, - .get_flags = macvlan_ethtool_get_flags, }; static const struct net_device_ops macvlan_netdev_ops = { -- GitLab From d2fe2755342b30bc1ee7797b9975f8626d65e485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:46 +0000 Subject: [PATCH 1102/5560] net: cxgb3: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes some of the remnants of LRO -> GRO conversion. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/cxgb3/adapter.h | 7 --- drivers/net/cxgb3/common.h | 1 - drivers/net/cxgb3/cxgb3_main.c | 78 ++++++---------------------------- drivers/net/cxgb3/sge.c | 7 +-- 4 files changed, 17 insertions(+), 76 deletions(-) diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index ef67be59680f..7300de5a1426 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -50,11 +50,6 @@ struct adapter; struct sge_qset; struct port_info; -enum { /* rx_offload flags */ - T3_RX_CSUM = 1 << 0, - T3_LRO = 1 << 1, -}; - enum mac_idx_types { LAN_MAC_IDX = 0, SAN_MAC_IDX, @@ -74,7 +69,6 @@ struct port_info { struct vlan_group *vlan_grp; struct sge_qset *qs; u8 port_id; - u8 rx_offload; u8 nqsets; u8 first_qset; struct cphy phy; @@ -212,7 +206,6 @@ struct sge_qset { /* an SGE queue set */ struct sge_fl fl[SGE_RXQ_PER_SET]; struct sge_txq txq[SGE_TXQ_PER_SET]; int nomem; - int lro_enabled; void *lro_va; struct net_device *netdev; struct netdev_queue *tx_q; /* associated netdev TX queue */ diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index 5ccb77d078aa..056ee8c831f1 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -317,7 +317,6 @@ struct tp_params { struct qset_params { /* SGE queue set parameters */ unsigned int polling; /* polling/interrupt service for rspq */ - unsigned int lro; /* large receive offload */ unsigned int coalesce_usecs; /* irq coalescing timer */ unsigned int rspq_size; /* # of entries in response queue */ unsigned int fl_size; /* # of entries in regular free list */ diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index a087e0691dce..040491804efb 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -643,26 +643,6 @@ static void enable_all_napi(struct adapter *adap) napi_enable(&adap->sge.qs[i].napi); } -/** - * set_qset_lro - Turn a queue set's LRO capability on and off - * @dev: the device the qset is attached to - * @qset_idx: the queue set index - * @val: the LRO switch - * - * Sets LRO on or off for a particular queue set. - * the device's features flag is updated to reflect the LRO - * capability when all queues belonging to the device are - * in the same state. - */ -static void set_qset_lro(struct net_device *dev, int qset_idx, int val) -{ - struct port_info *pi = netdev_priv(dev); - struct adapter *adapter = pi->adapter; - - adapter->params.sge.qset[qset_idx].lro = !!val; - adapter->sge.qs[qset_idx].lro_enabled = !!val; -} - /** * setup_sge_qsets - configure SGE Tx/Rx/response queues * @adap: the adapter @@ -685,7 +665,6 @@ static int setup_sge_qsets(struct adapter *adap) pi->qs = &adap->sge.qs[pi->first_qset]; for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { - set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO); err = t3_sge_alloc_qset(adap, qset_idx, 1, (adap->flags & USING_MSIX) ? qset_idx + 1 : irq_idx, @@ -1910,29 +1889,6 @@ static int set_pauseparam(struct net_device *dev, return 0; } -static u32 get_rx_csum(struct net_device *dev) -{ - struct port_info *p = netdev_priv(dev); - - return p->rx_offload & T3_RX_CSUM; -} - -static int set_rx_csum(struct net_device *dev, u32 data) -{ - struct port_info *p = netdev_priv(dev); - - if (data) { - p->rx_offload |= T3_RX_CSUM; - } else { - int i; - - p->rx_offload &= ~(T3_RX_CSUM | T3_LRO); - for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) - set_qset_lro(dev, i, 0); - } - return 0; -} - static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) { struct port_info *pi = netdev_priv(dev); @@ -2104,10 +2060,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = { .set_eeprom = set_eeprom, .get_pauseparam = get_pauseparam, .set_pauseparam = set_pauseparam, - .get_rx_csum = get_rx_csum, - .set_rx_csum = set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = get_strings, .set_phys_id = set_phys_id, @@ -2117,7 +2069,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = { .get_regs_len = get_regs_len, .get_regs = get_regs, .get_wol = get_wol, - .set_tso = ethtool_op_set_tso, }; static int in_range(int val, int lo, int hi) @@ -2165,15 +2116,6 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) MAX_RSPQ_ENTRIES)) return -EINVAL; - if ((adapter->flags & FULL_INIT_DONE) && t.lro > 0) - for_each_port(adapter, i) { - pi = adap2pinfo(adapter, i); - if (t.qset_idx >= pi->first_qset && - t.qset_idx < pi->first_qset + pi->nqsets && - !(pi->rx_offload & T3_RX_CSUM)) - return -EINVAL; - } - if ((adapter->flags & FULL_INIT_DONE) && (t.rspq_size >= 0 || t.fl_size[0] >= 0 || t.fl_size[1] >= 0 || t.txq_size[0] >= 0 || @@ -2234,8 +2176,14 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) } } } - if (t.lro >= 0) - set_qset_lro(dev, t.qset_idx, t.lro); + + if (t.lro >= 0) { + if (t.lro) + dev->wanted_features |= NETIF_F_GRO; + else + dev->wanted_features &= ~NETIF_F_GRO; + netdev_update_features(dev); + } break; } @@ -2269,7 +2217,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) t.fl_size[0] = q->fl_size; t.fl_size[1] = q->jumbo_size; t.polling = q->polling; - t.lro = q->lro; + t.lro = !!(dev->features & NETIF_F_GRO); t.intr_lat = q->coalesce_usecs; t.cong_thres = q->cong_thres; t.qnum = q1; @@ -3307,18 +3255,18 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->port[i] = netdev; pi = netdev_priv(netdev); pi->adapter = adapter; - pi->rx_offload = T3_RX_CSUM | T3_LRO; pi->port_id = i; netif_carrier_off(netdev); netdev->irq = pdev->irq; netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; - netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; - netdev->features |= NETIF_F_GRO; + netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_TSO | NETIF_F_RXCSUM; + netdev->features |= netdev->hw_features | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; netdev->netdev_ops = &cxgb_netdev_ops; SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops); } diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index bfa2d56af1ee..cba1401377ab 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2019,7 +2019,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, skb_pull(skb, sizeof(*p) + pad); skb->protocol = eth_type_trans(skb, adap->port[p->iff]); pi = netdev_priv(skb->dev); - if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid && + if ((skb->dev->features & NETIF_F_RXCSUM) && p->csum_valid && p->csum == htons(0xffff) && !p->fragment) { qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2120,7 +2120,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, offset = 2 + sizeof(struct cpl_rx_pkt); cpl = qs->lro_va = sd->pg_chunk.va + 2; - if ((pi->rx_offload & T3_RX_CSUM) && + if ((qs->netdev->features & NETIF_F_RXCSUM) && cpl->csum_valid && cpl->csum == htons(0xffff)) { skb->ip_summed = CHECKSUM_UNNECESSARY; qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; @@ -2285,7 +2285,8 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs, q->next_holdoff = q->holdoff_tmr; while (likely(budget_left && is_new_response(r, q))) { - int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled; + int packet_complete, eth, ethpad = 2; + int lro = !!(qs->netdev->features & NETIF_F_GRO); struct sk_buff *skb = NULL; u32 len, flags; __be32 rss_hi, rss_lo; -- GitLab From eea3250b43fd0b4fe565409bbf2fb06514213386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:46 +0000 Subject: [PATCH 1103/5560] net: tehuti: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a side effect, make TX offloads changeable. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/tehuti.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 8564ec5cfb7f..8be71de725e5 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -2017,9 +2017,11 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ndev->irq = pdev->irq; ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER + NETIF_F_HW_VLAN_FILTER | NETIF_F_RXCSUM /*| NETIF_F_FRAGLIST */ ; + ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_HW_VLAN_TX; if (pci_using_dac) ndev->features |= NETIF_F_HIGHDMA; @@ -2187,24 +2189,6 @@ bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) drvinfo->eedump_len = 0; } -/* - * bdx_get_rx_csum - report whether receive checksums are turned on or off - * @netdev - */ -static u32 bdx_get_rx_csum(struct net_device *netdev) -{ - return 1; /* always on */ -} - -/* - * bdx_get_tx_csum - report whether transmit checksums are turned on or off - * @netdev - */ -static u32 bdx_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_IP_CSUM) != 0; -} - /* * bdx_get_coalesce - get interrupt coalescing parameters * @netdev @@ -2424,10 +2408,6 @@ static void bdx_set_ethtool_ops(struct net_device *netdev) .set_coalesce = bdx_set_coalesce, .get_ringparam = bdx_get_ringparam, .set_ringparam = bdx_set_ringparam, - .get_rx_csum = bdx_get_rx_csum, - .get_tx_csum = bdx_get_tx_csum, - .get_sg = ethtool_op_get_sg, - .get_tso = ethtool_op_get_tso, .get_strings = bdx_get_strings, .get_sset_count = bdx_get_sset_count, .get_ethtool_stats = bdx_get_ethtool_stats, -- GitLab From aad59c431b77be5cbfa01f2066a036b95981fed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:46 +0000 Subject: [PATCH 1104/5560] net: mv643xx: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Side effect: don't reenable RXCSUM on every ifdown/ifup. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 34425b94452f..29605a34d4c1 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1575,18 +1575,12 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er) return 0; } -static u32 -mv643xx_eth_get_rx_csum(struct net_device *dev) -{ - struct mv643xx_eth_private *mp = netdev_priv(dev); - - return !!(rdlp(mp, PORT_CONFIG) & 0x02000000); -} static int -mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum) +mv643xx_eth_set_features(struct net_device *dev, u32 features) { struct mv643xx_eth_private *mp = netdev_priv(dev); + u32 rx_csum = features & NETIF_F_RXCSUM; wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000); @@ -1634,11 +1628,6 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev, } } -static int mv643xx_eth_set_flags(struct net_device *dev, u32 data) -{ - return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO); -} - static int mv643xx_eth_get_sset_count(struct net_device *dev, int sset) { if (sset == ETH_SS_STATS) @@ -1657,14 +1646,8 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = { .set_coalesce = mv643xx_eth_set_coalesce, .get_ringparam = mv643xx_eth_get_ringparam, .set_ringparam = mv643xx_eth_set_ringparam, - .get_rx_csum = mv643xx_eth_get_rx_csum, - .set_rx_csum = mv643xx_eth_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, .get_strings = mv643xx_eth_get_strings, .get_ethtool_stats = mv643xx_eth_get_ethtool_stats, - .get_flags = ethtool_op_get_flags, - .set_flags = mv643xx_eth_set_flags, .get_sset_count = mv643xx_eth_get_sset_count, }; @@ -2264,7 +2247,7 @@ static void port_start(struct mv643xx_eth_private *mp) * frames to RX queue #0, and include the pseudo-header when * calculating receive checksums. */ - wrlp(mp, PORT_CONFIG, 0x02000000); + mv643xx_eth_set_features(dev, dev->features); /* * Treat BPDUs as normal multicasts, and disable partition mode. @@ -2848,6 +2831,7 @@ static const struct net_device_ops mv643xx_eth_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = mv643xx_eth_ioctl, .ndo_change_mtu = mv643xx_eth_change_mtu, + .ndo_set_features = mv643xx_eth_set_features, .ndo_tx_timeout = mv643xx_eth_tx_timeout, .ndo_get_stats = mv643xx_eth_get_stats, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -2930,7 +2914,9 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->watchdog_timeo = 2 * HZ; dev->base_addr = 0; - dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_RXCSUM | NETIF_F_LRO; + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM; dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM; SET_NETDEV_DEV(dev, &pdev->dev); -- GitLab From 86688a8f132a7630f8610c13a349c711fe683b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:47 +0000 Subject: [PATCH 1105/5560] net: typhoon: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/typhoon.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 82653cb07857..119c394f71ce 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1144,28 +1144,6 @@ typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) return 0; } -static u32 -typhoon_get_rx_csum(struct net_device *dev) -{ - /* For now, we don't allow turning off RX checksums. - */ - return 1; -} - -static int -typhoon_set_flags(struct net_device *dev, u32 data) -{ - /* There's no way to turn off the RX VLAN offloading and stripping - * on the current 3XP firmware -- it does not respect the offload - * settings -- so we only allow the user to toggle the TX processing. - */ - if (!(data & ETH_FLAG_RXVLAN)) - return -EINVAL; - - return ethtool_op_set_flags(dev, data, - ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); -} - static void typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { @@ -1187,13 +1165,7 @@ static const struct ethtool_ops typhoon_ethtool_ops = { .get_wol = typhoon_get_wol, .set_wol = typhoon_set_wol, .get_link = ethtool_op_get_link, - .get_rx_csum = typhoon_get_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = ethtool_op_set_tso, .get_ringparam = typhoon_get_ringparam, - .set_flags = typhoon_set_flags, - .get_flags = ethtool_op_get_flags, }; static int @@ -2482,10 +2454,15 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* We can handle scatter gather, up to 16 entries, and * we can do IP checksumming (only version 4, doh...) + * + * There's no way to turn off the RX VLAN offloading and stripping + * on the current 3XP firmware -- it does not respect the offload + * settings -- so we only allow the user to toggle the TX processing. */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->features |= NETIF_F_TSO; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HW_VLAN_TX; + dev->features = dev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM; if(register_netdev(dev) < 0) { err_msg = "unable to register netdev"; -- GitLab From 66a1c5413260a8c302b4024555c489cc6731b463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:47 +0000 Subject: [PATCH 1106/5560] net: benet: convert to hw_features - fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove be_set_flags() as it's already covered by hw_features. Signed-off-by: Michał Mirosław Acked-by: Ajit Khaparde ajit.khaparde@emulex.com Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 0f645a92bebe..28716a6061bc 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -712,18 +712,6 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, return status; } -static int be_set_flags(struct net_device *netdev, u32 data) -{ - struct be_adapter *adapter = netdev_priv(netdev); - int rc = -1; - - if (be_multi_rxq(adapter)) - rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXHASH | - ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); - - return rc; -} - const struct ethtool_ops be_ethtool_ops = { .get_settings = be_get_settings, .get_drvinfo = be_get_drvinfo, @@ -745,5 +733,4 @@ const struct ethtool_ops be_ethtool_ops = { .get_regs = be_get_regs, .flash_device = be_do_flash, .self_test = be_self_test, - .set_flags = be_set_flags, }; -- GitLab From f4786a96252b97f6f05cd42ea7fe6e967048bfa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:47 +0000 Subject: [PATCH 1107/5560] net: ehea: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_ethtool.c | 23 ----------------------- drivers/net/ehea/ehea_main.c | 4 +++- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 3e2e734fecb7..5f13491cf2a9 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -162,11 +162,6 @@ static void ehea_set_msglevel(struct net_device *dev, u32 value) port->msg_enable = value; } -static u32 ehea_get_rx_csum(struct net_device *dev) -{ - return 1; -} - static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = { {"sig_comp_iv"}, {"swqe_refill_th"}, @@ -263,34 +258,16 @@ static void ehea_get_ethtool_stats(struct net_device *dev, } -static int ehea_set_flags(struct net_device *dev, u32 data) -{ - /* Avoid changing the VLAN flags */ - if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) != - (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN | - ETH_FLAG_TXVLAN))){ - return -EINVAL; - } - - return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO - | ETH_FLAG_TXVLAN - | ETH_FLAG_RXVLAN); -} - const struct ethtool_ops ehea_ethtool_ops = { .get_settings = ehea_get_settings, .get_drvinfo = ehea_get_drvinfo, .get_msglevel = ehea_get_msglevel, .set_msglevel = ehea_set_msglevel, .get_link = ethtool_op_get_link, - .set_tso = ethtool_op_set_tso, .get_strings = ehea_get_strings, .get_sset_count = ehea_get_sset_count, .get_ethtool_stats = ehea_get_ethtool_stats, - .get_rx_csum = ehea_get_rx_csum, .set_settings = ehea_set_settings, - .get_flags = ethtool_op_get_flags, - .set_flags = ehea_set_flags, .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ }; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index f75d3144b8a5..ce2f0ca61d9a 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3262,10 +3262,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev->netdev_ops = &ehea_netdev_ops; ehea_set_ethtool_ops(dev); + dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO + | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER - | NETIF_F_LLTX; + | NETIF_F_LLTX | NETIF_F_RXCSUM; dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; if (use_lro) -- GitLab From 3cd8ef4b6071834fd432bbccbec0611591908643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:47 +0000 Subject: [PATCH 1108/5560] net: niu: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Side effect: allow toggling of TX offloads. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/niu.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/net/niu.c b/drivers/net/niu.c index ea2272f0f37e..a7072174ffa7 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -7913,11 +7913,6 @@ static int niu_set_phys_id(struct net_device *dev, return 0; } -static int niu_set_flags(struct net_device *dev, u32 data) -{ - return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH); -} - static const struct ethtool_ops niu_ethtool_ops = { .get_drvinfo = niu_get_drvinfo, .get_link = ethtool_op_get_link, @@ -7934,8 +7929,6 @@ static const struct ethtool_ops niu_ethtool_ops = { .set_phys_id = niu_set_phys_id, .get_rxnfc = niu_get_nfc, .set_rxnfc = niu_set_nfc, - .set_flags = niu_set_flags, - .get_flags = ethtool_op_get_flags, }; static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent, @@ -9764,8 +9757,8 @@ static void __devinit niu_device_announce(struct niu *np) static void __devinit niu_set_basic_features(struct net_device *dev) { - dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | - NETIF_F_GRO | NETIF_F_RXHASH); + dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXHASH; + dev->features |= dev->hw_features | NETIF_F_RXCSUM; } static int __devinit niu_pci_init_one(struct pci_dev *pdev, -- GitLab From 131ae329702755d897c6072c7839086b0702fb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:47 +0000 Subject: [PATCH 1109/5560] net: greth: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: Driver modifies its struct net_device_ops. This will break if used for multiple devices that are not all the same (if that HW config is possible). Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/greth.c | 46 ++++----------------------------------------- drivers/net/greth.h | 4 ---- 2 files changed, 4 insertions(+), 46 deletions(-) diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 396ff7d785d1..f181304a7ab6 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -901,7 +901,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit) skb_put(skb, pkt_len); - if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status)) + if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb_checksum_none_assert(skb); @@ -1142,41 +1142,6 @@ static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, vo buff[i] = greth_read_bd(&greth_regs[i]); } -static u32 greth_get_rx_csum(struct net_device *dev) -{ - struct greth_private *greth = netdev_priv(dev); - return (greth->flags & GRETH_FLAG_RX_CSUM) != 0; -} - -static int greth_set_rx_csum(struct net_device *dev, u32 data) -{ - struct greth_private *greth = netdev_priv(dev); - - spin_lock_bh(&greth->devlock); - - if (data) - greth->flags |= GRETH_FLAG_RX_CSUM; - else - greth->flags &= ~GRETH_FLAG_RX_CSUM; - - spin_unlock_bh(&greth->devlock); - - return 0; -} - -static u32 greth_get_tx_csum(struct net_device *dev) -{ - return (dev->features & NETIF_F_IP_CSUM) != 0; -} - -static int greth_set_tx_csum(struct net_device *dev, u32 data) -{ - netif_tx_lock_bh(dev); - ethtool_op_set_tx_csum(dev, data); - netif_tx_unlock_bh(dev); - return 0; -} - static const struct ethtool_ops greth_ethtool_ops = { .get_msglevel = greth_get_msglevel, .set_msglevel = greth_set_msglevel, @@ -1185,10 +1150,6 @@ static const struct ethtool_ops greth_ethtool_ops = { .get_drvinfo = greth_get_drvinfo, .get_regs_len = greth_get_regs_len, .get_regs = greth_get_regs, - .get_rx_csum = greth_get_rx_csum, - .set_rx_csum = greth_set_rx_csum, - .get_tx_csum = greth_get_tx_csum, - .set_tx_csum = greth_set_tx_csum, .get_link = ethtool_op_get_link, }; @@ -1570,9 +1531,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev) GRETH_REGSAVE(regs->status, 0xFF); if (greth->gbit_mac) { - dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HIGHDMA; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_RXCSUM; + dev->features = dev->hw_features | NETIF_F_HIGHDMA; greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit; - greth->flags = GRETH_FLAG_RX_CSUM; } if (greth->multicast) { diff --git a/drivers/net/greth.h b/drivers/net/greth.h index be0f2062bd14..9a0040dee4da 100644 --- a/drivers/net/greth.h +++ b/drivers/net/greth.h @@ -77,9 +77,6 @@ */ #define MAX_FRAME_SIZE 1520 -/* Flags */ -#define GRETH_FLAG_RX_CSUM 0x1 - /* GRETH APB registers */ struct greth_regs { u32 control; @@ -133,7 +130,6 @@ struct greth_private { unsigned int duplex; u32 msg_enable; - u32 flags; u8 phyaddr; u8 multicast; -- GitLab From 5e4011e2b8032cd132d9482f016558f1b27569cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sun, 17 Apr 2011 00:15:47 +0000 Subject: [PATCH 1110/5560] net: ibm_newemac: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Side effect: allow toggling of TX offloads. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/ibm_newemac/core.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 3bb990b6651a..079450fe5e96 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2053,13 +2053,6 @@ static void emac_ethtool_get_pauseparam(struct net_device *ndev, mutex_unlock(&dev->link_lock); } -static u32 emac_ethtool_get_rx_csum(struct net_device *ndev) -{ - struct emac_instance *dev = netdev_priv(ndev); - - return dev->tah_dev != NULL; -} - static int emac_get_regs_len(struct emac_instance *dev) { if (emac_has_feature(dev, EMAC_FTR_EMAC4)) @@ -2203,15 +2196,11 @@ static const struct ethtool_ops emac_ethtool_ops = { .get_ringparam = emac_ethtool_get_ringparam, .get_pauseparam = emac_ethtool_get_pauseparam, - .get_rx_csum = emac_ethtool_get_rx_csum, - .get_strings = emac_ethtool_get_strings, .get_sset_count = emac_ethtool_get_sset_count, .get_ethtool_stats = emac_ethtool_get_ethtool_stats, .get_link = ethtool_op_get_link, - .get_tx_csum = ethtool_op_get_tx_csum, - .get_sg = ethtool_op_get_sg, }; static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) @@ -2859,8 +2848,10 @@ static int __devinit emac_probe(struct platform_device *ofdev) if (err != 0) goto err_detach_tah; - if (dev->tah_dev) - ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; + if (dev->tah_dev) { + ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG; + ndev->features |= ndev->hw_features | NETIF_F_RXCSUM; + } ndev->watchdog_timeo = 5 * HZ; if (emac_phy_supports_gige(dev->phy_mode)) { ndev->netdev_ops = &emac_gige_netdev_ops; -- GitLab From c582a950b1d7488750831cb4499de071781c7f45 Mon Sep 17 00:00:00 2001 From: Thiago Farina Date: Sun, 17 Apr 2011 17:49:21 -0700 Subject: [PATCH 1111/5560] drivers/net/usb/usbnet.c: Use FIELD_SIZEOF macro in usbnet_init() function. Signed-off-by: Thiago Farina Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 069c1cf0fdf7..7bc9852bd57c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1529,9 +1529,9 @@ EXPORT_SYMBOL_GPL(usbnet_resume); static int __init usbnet_init(void) { - /* compiler should optimize this out */ - BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb) - < sizeof (struct skb_data)); + /* Compiler should optimize this out. */ + BUILD_BUG_ON( + FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data)); random_ether_addr(node_id); return 0; -- GitLab From 2ed28baa7076083b56c1e70ccd927b7870117c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Sat, 16 Apr 2011 13:05:08 +0000 Subject: [PATCH 1112/5560] net: cxgb4{,vf}: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Acked-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/cxgb4.h | 6 --- drivers/net/cxgb4/cxgb4_main.c | 72 +++++++----------------------- drivers/net/cxgb4/sge.c | 4 +- drivers/net/cxgb4vf/adapter.h | 6 --- drivers/net/cxgb4vf/cxgb4vf_main.c | 57 ++++------------------- drivers/net/cxgb4vf/sge.c | 4 +- 6 files changed, 28 insertions(+), 121 deletions(-) diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 01d49eaa44d2..bc9982a4c1f4 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -290,7 +290,6 @@ struct port_info { u8 port_id; u8 tx_chan; u8 lport; /* associated offload logical port */ - u8 rx_offload; /* CSO, etc */ u8 nqsets; /* # of qsets */ u8 first_qset; /* index of first qset */ u8 rss_mode; @@ -298,11 +297,6 @@ struct port_info { u16 *rss; }; -/* port_info.rx_offload flags */ -enum { - RX_CSO = 1 << 0, -}; - struct dentry; struct work_struct; diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 0af9c9f0ca78..bdc868ca47ec 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -1531,24 +1531,6 @@ static int set_pauseparam(struct net_device *dev, return 0; } -static u32 get_rx_csum(struct net_device *dev) -{ - struct port_info *p = netdev_priv(dev); - - return p->rx_offload & RX_CSO; -} - -static int set_rx_csum(struct net_device *dev, u32 data) -{ - struct port_info *p = netdev_priv(dev); - - if (data) - p->rx_offload |= RX_CSO; - else - p->rx_offload &= ~RX_CSO; - return 0; -} - static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) { const struct port_info *pi = netdev_priv(dev); @@ -1870,36 +1852,20 @@ static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) return err; } -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) - -static int set_tso(struct net_device *dev, u32 value) -{ - if (value) - dev->features |= TSO_FLAGS; - else - dev->features &= ~TSO_FLAGS; - return 0; -} - -static int set_flags(struct net_device *dev, u32 flags) +static int cxgb_set_features(struct net_device *dev, u32 features) { + const struct port_info *pi = netdev_priv(dev); + u32 changed = dev->features ^ features; int err; - unsigned long old_feat = dev->features; - - err = ethtool_op_set_flags(dev, flags, ETH_FLAG_RXHASH | - ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); - if (err) - return err; - if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) { - const struct port_info *pi = netdev_priv(dev); + if (!(changed & NETIF_F_HW_VLAN_RX)) + return 0; - err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1, - -1, -1, -1, !!(flags & ETH_FLAG_RXVLAN), - true); - if (err) - dev->features = old_feat; - } + err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1, + -1, -1, -1, + !!(features & NETIF_F_HW_VLAN_RX), true); + if (unlikely(err)) + dev->features = features ^ NETIF_F_HW_VLAN_RX; return err; } @@ -2010,10 +1976,6 @@ static struct ethtool_ops cxgb_ethtool_ops = { .set_eeprom = set_eeprom, .get_pauseparam = get_pauseparam, .set_pauseparam = set_pauseparam, - .get_rx_csum = get_rx_csum, - .set_rx_csum = set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_ipv6_csum, - .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = get_strings, .set_phys_id = identify_port, @@ -2024,8 +1986,6 @@ static struct ethtool_ops cxgb_ethtool_ops = { .get_regs = get_regs, .get_wol = get_wol, .set_wol = set_wol, - .set_tso = set_tso, - .set_flags = set_flags, .get_rxnfc = get_rxnfc, .get_rxfh_indir = get_rss_table, .set_rxfh_indir = set_rss_table, @@ -2882,6 +2842,7 @@ static const struct net_device_ops cxgb4_netdev_ops = { .ndo_get_stats64 = cxgb_get_stats, .ndo_set_rx_mode = cxgb_set_rxmode, .ndo_set_mac_address = cxgb_set_mac_addr, + .ndo_set_features = cxgb_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = cxgb_ioctl, .ndo_change_mtu = cxgb_change_mtu, @@ -3564,6 +3525,7 @@ static void free_some_resources(struct adapter *adapter) t4_fw_bye(adapter, adapter->fn); } +#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) @@ -3665,14 +3627,14 @@ static int __devinit init_one(struct pci_dev *pdev, pi = netdev_priv(netdev); pi->adapter = adapter; pi->xact_addr_filt = -1; - pi->rx_offload = RX_CSO; pi->port_id = i; netdev->irq = pdev->irq; - netdev->features |= NETIF_F_SG | TSO_FLAGS; - netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma; - netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + netdev->hw_features = NETIF_F_SG | TSO_FLAGS | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM | NETIF_F_RXHASH | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + netdev->features |= netdev->hw_features | highdma; netdev->vlan_features = netdev->features & VLAN_FEAT; netdev->netdev_ops = &cxgb4_netdev_ops; diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index 311471b439a8..75a4b0fa19ee 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -1556,7 +1556,6 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, { bool csum_ok; struct sk_buff *skb; - struct port_info *pi; const struct cpl_rx_pkt *pkt; struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); @@ -1584,10 +1583,9 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, if (skb->dev->features & NETIF_F_RXHASH) skb->rxhash = (__force u32)pkt->rsshdr.hash_val; - pi = netdev_priv(skb->dev); rxq->stats.pkts++; - if (csum_ok && (pi->rx_offload & RX_CSO) && + if (csum_ok && (q->netdev->features & NETIF_F_RXCSUM) && (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) { if (!pkt->ip_frag) { skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h index 4766b4116b41..4fd821aadc8a 100644 --- a/drivers/net/cxgb4vf/adapter.h +++ b/drivers/net/cxgb4vf/adapter.h @@ -97,17 +97,11 @@ struct port_info { u16 rss_size; /* size of VI's RSS table slice */ u8 pidx; /* index into adapter port[] */ u8 port_id; /* physical port ID */ - u8 rx_offload; /* CSO, etc. */ u8 nqsets; /* # of "Queue Sets" */ u8 first_qset; /* index of first "Queue Set" */ struct link_config link_cfg; /* physical port configuration */ }; -/* port_info.rx_offload flags */ -enum { - RX_CSO = 1 << 0, -}; - /* * Scatter Gather Engine resources for the "adapter". Our ingress and egress * queues are organized into "Queue Sets" with one ingress and one egress diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index c662679de4fa..8cf9890cafaf 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -1325,30 +1325,6 @@ static void cxgb4vf_get_pauseparam(struct net_device *dev, pauseparam->tx_pause = (pi->link_cfg.fc & PAUSE_TX) != 0; } -/* - * Return whether RX Checksum Offloading is currently enabled for the device. - */ -static u32 cxgb4vf_get_rx_csum(struct net_device *dev) -{ - struct port_info *pi = netdev_priv(dev); - - return (pi->rx_offload & RX_CSO) != 0; -} - -/* - * Turn RX Checksum Offloading on or off for the device. - */ -static int cxgb4vf_set_rx_csum(struct net_device *dev, u32 csum) -{ - struct port_info *pi = netdev_priv(dev); - - if (csum) - pi->rx_offload |= RX_CSO; - else - pi->rx_offload &= ~RX_CSO; - return 0; -} - /* * Identify the port by blinking the port's LED. */ @@ -1569,18 +1545,6 @@ static void cxgb4vf_get_wol(struct net_device *dev, */ #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 |= TSO_FLAGS; - else - dev->features &= ~TSO_FLAGS; - return 0; -} - static struct ethtool_ops cxgb4vf_ethtool_ops = { .get_settings = cxgb4vf_get_settings, .get_drvinfo = cxgb4vf_get_drvinfo, @@ -1591,10 +1555,6 @@ static struct ethtool_ops cxgb4vf_ethtool_ops = { .get_coalesce = cxgb4vf_get_coalesce, .set_coalesce = cxgb4vf_set_coalesce, .get_pauseparam = cxgb4vf_get_pauseparam, - .get_rx_csum = cxgb4vf_get_rx_csum, - .set_rx_csum = cxgb4vf_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_ipv6_csum, - .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = cxgb4vf_get_strings, .set_phys_id = cxgb4vf_phys_id, @@ -1603,7 +1563,6 @@ static struct ethtool_ops cxgb4vf_ethtool_ops = { .get_regs_len = cxgb4vf_get_regs_len, .get_regs = cxgb4vf_get_regs, .get_wol = cxgb4vf_get_wol, - .set_tso = cxgb4vf_set_tso, }; /* @@ -2638,19 +2597,19 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, * it. */ pi->xact_addr_filt = -1; - pi->rx_offload = RX_CSO; netif_carrier_off(netdev); netdev->irq = pdev->irq; - 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); + netdev->hw_features = NETIF_F_SG | TSO_FLAGS | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; + netdev->vlan_features = NETIF_F_SG | TSO_FLAGS | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_HIGHDMA; + netdev->features = netdev->hw_features | + NETIF_F_HW_VLAN_RX; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - netdev->vlan_features = - (netdev->features & - ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)); #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops = &cxgb4vf_netdev_ops; diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index bb65121f581c..5182960e29fd 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1555,8 +1555,8 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, pi = netdev_priv(skb->dev); rxq->stats.pkts++; - if (csum_ok && (pi->rx_offload & RX_CSO) && !pkt->err_vec && - (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) { + if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) && + !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) { if (!pkt->ip_frag) skb->ip_summed = CHECKSUM_UNNECESSARY; else { -- GitLab From 28674b97cfb907b0b3de7b7fea89efda1e65f34e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 17 Apr 2011 17:52:51 -0700 Subject: [PATCH 1113/5560] bridge: fix accidental creation of sysfs directory Commit bb900b27a2f49b37bc38c08e656ea13048fee13b ("bridge: allow creating bridge devices with netlink") introduced a bug in net-next because of a typo in notifier. Every device would have the sysfs bridge directory (and files). Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_notify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 7a03bb975375..606b323e8a0c 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c @@ -37,7 +37,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v int err; /* register of bridge completed, add sysfs entries */ - if ((dev->priv_flags && IFF_EBRIDGE) && event == NETDEV_REGISTER) { + if ((dev->priv_flags & IFF_EBRIDGE) && event == NETDEV_REGISTER) { br_sysfs_addbr(dev); return NOTIFY_DONE; } -- GitLab From df4511feb76173db872c8845b63179dd15f2b7da Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 16 Apr 2011 14:15:25 +0000 Subject: [PATCH 1114/5560] via_rhine: Use netdev_ and pr_ Use the more current logging styles. Add #define DEBUG to make netdev_dbg always active. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/via-rhine.c | 230 +++++++++++++++++++--------------------- 1 file changed, 108 insertions(+), 122 deletions(-) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 0422a79acfd7..40f394ce113b 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -29,6 +29,8 @@ */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "via-rhine" #define DRV_VERSION "1.5.0" #define DRV_RELDATE "2010-10-09" @@ -37,6 +39,7 @@ /* A few user-configurable values. These may be modified when a driver module is loaded. */ +#define DEBUG static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ static int max_interrupt_work = 20; @@ -111,8 +114,7 @@ static const int multicast_filter_limit = 32; /* These identify the driver base version and may not be removed. */ static const char version[] __devinitconst = - KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE - " Written by Donald Becker\n"; + "v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker"; /* This driver was written to use PCI memory space. Some early versions of the Rhine may only work correctly with I/O space accesses. */ @@ -495,14 +497,15 @@ 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; \ - while (!(condition) && --i) \ - ; \ - if (debug > 1 && i < 512) \ - printk(KERN_INFO "%s: %4d cycles used @ %s:%d\n", \ - DRV_NAME, 1024-i, __func__, __LINE__); \ -} while(0) +#define RHINE_WAIT_FOR(condition) \ +do { \ + int i = 1024; \ + while (!(condition) && --i) \ + ; \ + if (debug > 1 && i < 512) \ + pr_info("%4d cycles used @ %s:%d\n", \ + 1024 - i, __func__, __LINE__); \ +} while (0) static inline u32 get_intr_status(struct net_device *dev) { @@ -571,8 +574,8 @@ static void rhine_power_init(struct net_device *dev) default: reason = "Unknown"; } - printk(KERN_INFO "%s: Woke system up. Reason: %s.\n", - DRV_NAME, reason); + netdev_info(dev, "Woke system up. Reason: %s\n", + reason); } } } @@ -586,8 +589,7 @@ static void rhine_chip_reset(struct net_device *dev) IOSYNC; if (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) { - printk(KERN_INFO "%s: Reset not complete yet. " - "Trying harder.\n", DRV_NAME); + netdev_info(dev, "Reset not complete yet. Trying harder.\n"); /* Force reset */ if (rp->quirks & rqForceReset) @@ -598,9 +600,9 @@ static void rhine_chip_reset(struct net_device *dev) } if (debug > 1) - printk(KERN_INFO "%s: Reset %s.\n", dev->name, - (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ? - "failed" : "succeeded"); + netdev_info(dev, "Reset %s\n", + (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ? + "failed" : "succeeded"); } #ifdef USE_MMIO @@ -728,9 +730,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, /* when built into the kernel, we only print version if device is found */ #ifndef MODULE - static int printed_version; - if (!printed_version++) - printk(version); + pr_info_once("%s\n", version); #endif io_size = 256; @@ -765,8 +765,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, /* this should always be supported */ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc) { - printk(KERN_ERR "32-bit PCI DMA addresses not supported by " - "the card!?\n"); + dev_err(&pdev->dev, + "32-bit PCI DMA addresses not supported by the card!?\n"); goto err_out; } @@ -774,7 +774,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if ((pci_resource_len(pdev, 0) < io_size) || (pci_resource_len(pdev, 1) < io_size)) { rc = -EIO; - printk(KERN_ERR "Insufficient PCI resources, aborting\n"); + dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n"); goto err_out; } @@ -786,7 +786,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct rhine_private)); if (!dev) { rc = -ENOMEM; - printk(KERN_ERR "alloc_etherdev failed\n"); + dev_err(&pdev->dev, "alloc_etherdev failed\n"); goto err_out; } SET_NETDEV_DEV(dev, &pdev->dev); @@ -804,8 +804,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, ioaddr = pci_iomap(pdev, bar, io_size); if (!ioaddr) { rc = -EIO; - printk(KERN_ERR "ioremap failed for device %s, region 0x%X " - "@ 0x%lX\n", pci_name(pdev), io_size, memaddr); + dev_err(&pdev->dev, + "ioremap failed for device %s, region 0x%X @ 0x%lX\n", + pci_name(pdev), io_size, memaddr); goto err_out_free_res; } @@ -820,8 +821,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, unsigned char b = readb(ioaddr+reg); if (a != b) { rc = -EIO; - printk(KERN_ERR "MMIO do not match PIO [%02x] " - "(%02x != %02x)\n", reg, a, b); + dev_err(&pdev->dev, + "MMIO do not match PIO [%02x] (%02x != %02x)\n", + reg, a, b); goto err_out_unmap; } } @@ -840,7 +842,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if (!is_valid_ether_addr(dev->perm_addr)) { rc = -EIO; - printk(KERN_ERR "Invalid MAC address\n"); + dev_err(&pdev->dev, "Invalid MAC address\n"); goto err_out_unmap; } @@ -878,14 +880,14 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if (rc) goto err_out_unmap; - printk(KERN_INFO "%s: VIA %s at 0x%lx, %pM, IRQ %d.\n", - dev->name, name, + netdev_info(dev, "VIA %s at 0x%lx, %pM, IRQ %d\n", + name, #ifdef USE_MMIO - memaddr, + memaddr, #else - (long)ioaddr, + (long)ioaddr, #endif - dev->dev_addr, pdev->irq); + dev->dev_addr, pdev->irq); pci_set_drvdata(pdev, dev); @@ -896,11 +898,11 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, mdio_write(dev, phy_id, MII_BMCR, mii_cmd); if (mii_status != 0xffff && mii_status != 0x0000) { rp->mii_if.advertising = mdio_read(dev, phy_id, 4); - printk(KERN_INFO "%s: MII PHY found at address " - "%d, status 0x%4.4x advertising %4.4x " - "Link %4.4x.\n", dev->name, phy_id, - mii_status, rp->mii_if.advertising, - mdio_read(dev, phy_id, 5)); + netdev_info(dev, + "MII PHY found at address %d, status 0x%04x advertising %04x Link %04x\n", + phy_id, + mii_status, rp->mii_if.advertising, + mdio_read(dev, phy_id, 5)); /* set IFF_RUNNING */ if (mii_status & BMSR_LSTATUS) @@ -912,8 +914,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, } rp->mii_if.phy_id = phy_id; if (debug > 1 && avoid_D3) - printk(KERN_INFO "%s: No D3 power state at shutdown.\n", - dev->name); + netdev_info(dev, "No D3 power state at shutdown\n"); return 0; @@ -938,7 +939,7 @@ static int alloc_ring(struct net_device* dev) TX_RING_SIZE * sizeof(struct tx_desc), &ring_dma); if (!ring) { - printk(KERN_ERR "Could not allocate DMA memory.\n"); + netdev_err(dev, "Could not allocate DMA memory\n"); return -ENOMEM; } if (rp->quirks & rqRhineI) { @@ -1098,8 +1099,8 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media) iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex, ioaddr + ChipCmd1); if (debug > 1) - printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name, - rp->mii_if.force_media, netif_carrier_ok(dev)); + netdev_info(dev, "force_media %d, carrier %d\n", + rp->mii_if.force_media, netif_carrier_ok(dev)); } /* Called after status of force_media possibly changed */ @@ -1113,9 +1114,8 @@ static void rhine_set_carrier(struct mii_if_info *mii) else /* Let MMI library update carrier status */ rhine_check_media(mii->dev, 0); if (debug > 1) - printk(KERN_INFO "%s: force_media %d, carrier %d\n", - mii->dev->name, mii->force_media, - netif_carrier_ok(mii->dev)); + netdev_info(mii->dev, "force_media %d, carrier %d\n", + mii->force_media, netif_carrier_ok(mii->dev)); } /** @@ -1402,8 +1402,7 @@ static int rhine_open(struct net_device *dev) return rc; if (debug > 1) - printk(KERN_DEBUG "%s: rhine_open() irq %d.\n", - dev->name, rp->pdev->irq); + netdev_dbg(dev, "%s() irq %d\n", __func__, rp->pdev->irq); rc = alloc_ring(dev); if (rc) { @@ -1415,10 +1414,9 @@ static int rhine_open(struct net_device *dev) rhine_chip_reset(dev); init_registers(dev); if (debug > 2) - printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x " - "MII status: %4.4x.\n", - dev->name, ioread16(ioaddr + ChipCmd), - mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); + netdev_dbg(dev, "%s() Done - status %04x MII status: %04x\n", + __func__, ioread16(ioaddr + ChipCmd), + mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); netif_start_queue(dev); @@ -1461,10 +1459,9 @@ static void rhine_tx_timeout(struct net_device *dev) struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; - printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " - "%4.4x, resetting...\n", - dev->name, ioread16(ioaddr + IntrStatus), - mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); + netdev_warn(dev, "Transmit timed out, status %04x, PHY status %04x, resetting...\n", + ioread16(ioaddr + IntrStatus), + mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); schedule_work(&rp->reset_task); } @@ -1551,8 +1548,8 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, spin_unlock_irqrestore(&rp->lock, flags); if (debug > 4) { - printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n", - dev->name, rp->cur_tx-1, entry); + netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n", + rp->cur_tx-1, entry); } return NETDEV_TX_OK; } @@ -1578,8 +1575,8 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance) IOSYNC; if (debug > 4) - printk(KERN_DEBUG "%s: Interrupt, status %8.8x.\n", - dev->name, intr_status); + netdev_dbg(dev, "Interrupt, status %08x\n", + intr_status); if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped | IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) { @@ -1597,9 +1594,9 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance) RHINE_WAIT_FOR(!(ioread8(ioaddr+ChipCmd) & CmdTxOn)); if (debug > 2 && ioread8(ioaddr+ChipCmd) & CmdTxOn) - printk(KERN_WARNING "%s: " - "rhine_interrupt() Tx engine " - "still on.\n", dev->name); + netdev_warn(dev, + "%s: Tx engine still on\n", + __func__); } rhine_tx(dev); } @@ -1611,16 +1608,15 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance) rhine_error(dev, intr_status); if (--boguscnt < 0) { - printk(KERN_WARNING "%s: Too much work at interrupt, " - "status=%#8.8x.\n", - dev->name, intr_status); + netdev_warn(dev, "Too much work at interrupt, status=%#08x\n", + intr_status); break; } } if (debug > 3) - printk(KERN_DEBUG "%s: exiting interrupt, status=%8.8x.\n", - dev->name, ioread16(ioaddr + IntrStatus)); + netdev_dbg(dev, "exiting interrupt, status=%08x\n", + ioread16(ioaddr + IntrStatus)); return IRQ_RETVAL(handled); } @@ -1637,15 +1633,14 @@ static void rhine_tx(struct net_device *dev) while (rp->dirty_tx != rp->cur_tx) { txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status); if (debug > 6) - printk(KERN_DEBUG "Tx scavenge %d status %8.8x.\n", - entry, txstatus); + netdev_dbg(dev, "Tx scavenge %d status %08x\n", + entry, txstatus); if (txstatus & DescOwn) break; if (txstatus & 0x8000) { if (debug > 1) - printk(KERN_DEBUG "%s: Transmit error, " - "Tx status %8.8x.\n", - dev->name, txstatus); + netdev_dbg(dev, "Transmit error, Tx status %08x\n", + txstatus); dev->stats.tx_errors++; if (txstatus & 0x0400) dev->stats.tx_carrier_errors++; @@ -1668,9 +1663,9 @@ static void rhine_tx(struct net_device *dev) else dev->stats.collisions += txstatus & 0x0F; if (debug > 6) - printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n", - (txstatus >> 3) & 0xF, - txstatus & 0xF); + netdev_dbg(dev, "collisions: %1.1x:%1.1x\n", + (txstatus >> 3) & 0xF, + txstatus & 0xF); dev->stats.tx_bytes += rp->tx_skbuff[entry]->len; dev->stats.tx_packets++; } @@ -1714,9 +1709,9 @@ static int rhine_rx(struct net_device *dev, int limit) int entry = rp->cur_rx % RX_RING_SIZE; if (debug > 4) { - printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n", - dev->name, entry, - le32_to_cpu(rp->rx_head_desc->rx_status)); + netdev_dbg(dev, "%s(), entry %d status %08x\n", + __func__, entry, + le32_to_cpu(rp->rx_head_desc->rx_status)); } /* If EOP is set on the next entry, it's a new packet. Send it up. */ @@ -1730,26 +1725,26 @@ static int rhine_rx(struct net_device *dev, int limit) break; if (debug > 4) - printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n", - desc_status); + netdev_dbg(dev, "%s() status is %08x\n", + __func__, desc_status); if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) { if ((desc_status & RxWholePkt) != RxWholePkt) { - printk(KERN_WARNING "%s: Oversized Ethernet " - "frame spanned multiple buffers, entry " - "%#x length %d status %8.8x!\n", - dev->name, entry, data_size, - desc_status); - printk(KERN_WARNING "%s: Oversized Ethernet " - "frame %p vs %p.\n", dev->name, - rp->rx_head_desc, &rp->rx_ring[entry]); + netdev_warn(dev, + "Oversized Ethernet frame spanned multiple buffers, " + "entry %#x length %d status %08x!\n", + entry, data_size, + desc_status); + netdev_warn(dev, + "Oversized Ethernet frame %p vs %p\n", + rp->rx_head_desc, + &rp->rx_ring[entry]); dev->stats.rx_length_errors++; } else if (desc_status & RxErr) { /* There was a error. */ if (debug > 2) - printk(KERN_DEBUG "rhine_rx() Rx " - "error was %8.8x.\n", - desc_status); + netdev_dbg(dev, "%s() Rx error was %08x\n", + __func__, desc_status); dev->stats.rx_errors++; if (desc_status & 0x0030) dev->stats.rx_length_errors++; @@ -1791,9 +1786,7 @@ static int rhine_rx(struct net_device *dev, int limit) } else { skb = rp->rx_skbuff[entry]; if (skb == NULL) { - printk(KERN_ERR "%s: Inconsistent Rx " - "descriptor chain.\n", - dev->name); + netdev_err(dev, "Inconsistent Rx descriptor chain\n"); break; } rp->rx_skbuff[entry] = NULL; @@ -1886,9 +1879,8 @@ static void rhine_restart_tx(struct net_device *dev) { else { /* This should never happen */ if (debug > 1) - printk(KERN_WARNING "%s: rhine_restart_tx() " - "Another error occurred %8.8x.\n", - dev->name, intr_status); + netdev_warn(dev, "%s() Another error occurred %08x\n", + __func__, intr_status); } } @@ -1909,21 +1901,19 @@ static void rhine_error(struct net_device *dev, int intr_status) } if (intr_status & IntrTxAborted) { if (debug > 1) - printk(KERN_INFO "%s: Abort %8.8x, frame dropped.\n", - dev->name, intr_status); + netdev_info(dev, "Abort %08x, frame dropped\n", + intr_status); } if (intr_status & IntrTxUnderrun) { if (rp->tx_thresh < 0xE0) 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", - dev->name, rp->tx_thresh); + netdev_info(dev, "Transmitter underrun, Tx threshold now %02x\n", + rp->tx_thresh); } if (intr_status & IntrTxDescRace) { if (debug > 2) - printk(KERN_INFO "%s: Tx descriptor write-back race.\n", - dev->name); + netdev_info(dev, "Tx descriptor write-back race\n"); } if ((intr_status & IntrTxError) && (intr_status & (IntrTxAborted | @@ -1932,9 +1922,8 @@ static void rhine_error(struct net_device *dev, int intr_status) BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig); } if (debug > 1) - printk(KERN_INFO "%s: Unspecified error. Tx " - "threshold now %2.2x.\n", - dev->name, rp->tx_thresh); + netdev_info(dev, "Unspecified error. Tx threshold now %02x\n", + rp->tx_thresh); } if (intr_status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace | IntrTxError)) @@ -1944,8 +1933,8 @@ static void rhine_error(struct net_device *dev, int intr_status) IntrTxError | IntrTxAborted | IntrNormalSummary | IntrTxDescRace)) { if (debug > 1) - printk(KERN_ERR "%s: Something Wicked happened! " - "%8.8x.\n", dev->name, intr_status); + netdev_err(dev, "Something Wicked happened! %08x\n", + intr_status); } spin_unlock(&rp->lock); @@ -2145,9 +2134,8 @@ static int rhine_close(struct net_device *dev) spin_lock_irq(&rp->lock); if (debug > 1) - printk(KERN_DEBUG "%s: Shutting down ethercard, " - "status was %4.4x.\n", - dev->name, ioread16(ioaddr + ChipCmd)); + netdev_dbg(dev, "Shutting down ethercard, status was %04x\n", + ioread16(ioaddr + ChipCmd)); /* Switch to loopback mode to avoid hardware races. */ iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig); @@ -2265,12 +2253,12 @@ static int rhine_resume(struct pci_dev *pdev) return 0; if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev)) - printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name); + netdev_err(dev, "request_irq failed\n"); ret = pci_set_power_state(pdev, PCI_D0); if (debug > 1) - printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n", - dev->name, ret ? "failed" : "succeeded", ret); + netdev_info(dev, "Entering power state D0 %s (%d)\n", + ret ? "failed" : "succeeded", ret); pci_restore_state(pdev); @@ -2326,17 +2314,15 @@ static int __init rhine_init(void) { /* when a module, this is printed whether or not devices are found in probe */ #ifdef MODULE - printk(version); + pr_info("%s\n", version); #endif if (dmi_check_system(rhine_dmi_table)) { /* these BIOSes fail at PXE boot if chip is in D3 */ avoid_D3 = 1; - printk(KERN_WARNING "%s: Broken BIOS detected, avoid_D3 " - "enabled.\n", - DRV_NAME); + pr_warn("Broken BIOS detected, avoid_D3 enabled\n"); } else if (avoid_D3) - printk(KERN_INFO "%s: avoid_D3 set.\n", DRV_NAME); + pr_info("avoid_D3 set\n"); return pci_register_driver(&rhine_driver); } -- GitLab From 482e3febc2e7df78411005dcdd7621c16b98b088 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 16 Apr 2011 14:15:26 +0000 Subject: [PATCH 1115/5560] via-rhine: Assign random MAC address if necessary Roger Luethi has had several reports of Rhine NICs providing an invalid MAC address. If so, assign a random MAC address so the hardware can still be used. Tested as a standalone interface, as carrier for ppp, and as a bonding slave. Original-patch-by: Alexandru Gagniuc Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/via-rhine.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 40f394ce113b..7f23ab913fd9 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -838,13 +838,15 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, for (i = 0; i < 6; i++) dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - if (!is_valid_ether_addr(dev->perm_addr)) { - rc = -EIO; - dev_err(&pdev->dev, "Invalid MAC address\n"); - goto err_out_unmap; + if (!is_valid_ether_addr(dev->dev_addr)) { + /* Report it and use a random ethernet address instead */ + netdev_err(dev, "Invalid MAC address: %pM\n", dev->dev_addr); + random_ether_addr(dev->dev_addr); + netdev_info(dev, "Using random MAC address: %pM\n", + dev->dev_addr); } + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); /* For Rhine-I/II, phy_id is loaded from EEPROM */ if (!phy_id) -- GitLab From a01c1335a308ee660518e33db03fb5f5e1dfc166 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 17 Apr 2011 20:47:07 -0700 Subject: [PATCH 1116/5560] decnet: Don't leak entries when rebuilding zone. As noticed by Ben Hutchings, when we move entries from one table to another we leak all except the first entry. Put back the "next" variable removed by commit 9bf9055eb716f85372c41b3fbc51f90bc7653740 ("decnet: Fix set-but-unused variable.") and use it properly. Reported-by: Ben Hutchings Signed-off-by: David S. Miller --- net/decnet/dn_table.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index d8ea583076cf..bd0a52dd1d40 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -123,11 +123,12 @@ static inline void dn_rebuild_zone(struct dn_zone *dz, struct dn_fib_node **old_ht, int old_divisor) { + struct dn_fib_node *f, **fp, *next; int i; - struct dn_fib_node *f, **fp; for(i = 0; i < old_divisor; i++) { - for(f = old_ht[i]; f; f = f->fn_next) { + for(f = old_ht[i]; f; f = next) { + next = f->fn_next; for(fp = dn_chain_p(f->fn_key, dz); *fp && dn_key_leq((*fp)->fn_key, f->fn_key); fp = &(*fp)->fn_next) -- GitLab From b3337e4cea15beb167e8d3a70ca1023e39abb4e5 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Thu, 14 Apr 2011 16:11:34 +0000 Subject: [PATCH 1117/5560] bnx2x: cosmetics: Using ethtool_cmd_speed() API This updates bnx2x to use the ethtool_cmd_speed() family of functions (see b11f8d8c in 2.6.27-rc3 aka. "ethtool: Expand ethtool_cmd.speed to 32 bits") to get and set the link speed via ethtool. This allows to avoid manually accessing ethtool_cmd's speed_hi field. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 0a5e88d6ba2c..e711a2292446 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -167,6 +167,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); int cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Dual Media boards present all available port types */ cmd->supported = bp->port.supported[cfg_idx] | (bp->port.supported[cfg_idx ^ 1] & @@ -176,16 +177,16 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if ((bp->state == BNX2X_STATE_OPEN) && !(bp->flags & MF_FUNC_DIS) && (bp->link_vars.link_up)) { - cmd->speed = bp->link_vars.line_speed; + ethtool_cmd_speed_set(cmd, bp->link_vars.line_speed); cmd->duplex = bp->link_vars.duplex; } else { - - cmd->speed = bp->link_params.req_line_speed[cfg_idx]; + ethtool_cmd_speed_set( + cmd, bp->link_params.req_line_speed[cfg_idx]); cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } if (IS_MF(bp)) - cmd->speed = bnx2x_get_mf_speed(bp); + ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp)); if (bp->port.supported[cfg_idx] & SUPPORTED_TP) cmd->port = PORT_TP; @@ -206,10 +207,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->maxrxpkt = 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" - DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" + DP_LEVEL " supported 0x%x advertising 0x%x speed %u\n" DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", - cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->cmd, cmd->supported, cmd->advertising, + ethtool_cmd_speed(cmd), cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); @@ -226,16 +228,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" - " supported 0x%x advertising 0x%x speed %d speed_hi %d\n" + " supported 0x%x advertising 0x%x speed %u\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->cmd, cmd->supported, cmd->advertising, + ethtool_cmd_speed(cmd), cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); - speed = cmd->speed; - speed |= (cmd->speed_hi << 16); + speed = ethtool_cmd_speed(cmd); if (IS_MF_SI(bp)) { u32 part; @@ -439,7 +440,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; default: - DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed); + DP(NETIF_MSG_LINK, "Unsupported speed %u\n", speed); return -EINVAL; } -- GitLab From f47b94646f30529624c82ab0f9cd5bd3f25ef9d2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 15 Apr 2011 13:46:02 +0000 Subject: [PATCH 1118/5560] ipv6: Send unsolicited neighbour advertismements when notified The NETDEV_NOTIFY_PEERS notifier is a request to send such advertisements following migration to a different physical link, e.g. virtual machine migration. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/ipv6/ndisc.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f057ff312840..62cbd15b4cde 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -611,6 +611,29 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); } +static void ndisc_send_unsol_na(struct net_device *dev) +{ + struct inet6_dev *idev; + struct inet6_ifaddr *ifa; + struct in6_addr mcaddr; + + idev = in6_dev_get(dev); + if (!idev) + return; + + read_lock_bh(&idev->lock); + list_for_each_entry(ifa, &idev->addr_list, if_list) { + addrconf_addr_solict_mult(&ifa->addr, &mcaddr); + ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, + /*router=*/ !!idev->cnf.forwarding, + /*solicited=*/ false, /*override=*/ true, + /*inc_opt=*/ true); + } + read_unlock_bh(&idev->lock); + + in6_dev_put(idev); +} + void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, const struct in6_addr *solicit, const struct in6_addr *daddr, const struct in6_addr *saddr) @@ -1723,6 +1746,9 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, neigh_ifdown(&nd_tbl, dev); fib6_run_gc(~0UL, net); break; + case NETDEV_NOTIFY_PEERS: + ndisc_send_unsol_na(dev); + break; default: break; } -- GitLab From 99606477a5888b0ead0284fecb13417b1da8e3af Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 15 Apr 2011 13:46:49 +0000 Subject: [PATCH 1119/5560] vlan: Propagate NETDEV_NOTIFY_PEERS notifier The NETDEV_NOTIFY_PEERS notifier indicates that a device moved to a different physical link; this also applies to any VLAN devices on top of it. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- net/8021q/vlan.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 14ef5efbc653..b2ff70fcf8ea 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -499,6 +499,17 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_PRE_TYPE_CHANGE: /* Forbid underlaying device to change its type. */ return NOTIFY_BAD; + + case NETDEV_NOTIFY_PEERS: + /* Propagate to vlan devices */ + for (i = 0; i < VLAN_N_VID; i++) { + vlandev = vlan_group_get_device(grp, i); + if (!vlandev) + continue; + + call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, vlandev); + } + break; } out: -- GitLab From 7c89943236750537d26421d9bbb6f6575e2d1e1b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 15 Apr 2011 13:47:51 +0000 Subject: [PATCH 1120/5560] bonding, ipv4, ipv6, vlan: Handle NETDEV_BONDING_FAILOVER like NETDEV_NOTIFY_PEERS It is undesirable for the bonding driver to be poking into higher level protocols, and notifiers provide a way to avoid that. This does mean removing the ability to configure reptitition of gratuitous ARPs and unsolicited NAs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/bonding/Makefile | 3 - drivers/net/bonding/bond_main.c | 94 -------------------------------- drivers/net/bonding/bond_sysfs.c | 80 --------------------------- drivers/net/bonding/bonding.h | 29 ---------- net/8021q/vlan.c | 3 +- net/ipv4/devinet.c | 1 + net/ipv6/ndisc.c | 1 + 7 files changed, 4 insertions(+), 207 deletions(-) diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index 3c5c014e82b2..4c21bf6b8b2f 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile @@ -9,6 +9,3 @@ bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o proc-$(CONFIG_PROC_FS) += bond_procfs.o bonding-objs += $(proc-y) -ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o -bonding-objs += $(ipv6-y) - diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index fdf9215ada7d..4ce14bdf96dd 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -89,8 +89,6 @@ static int max_bonds = BOND_DEFAULT_MAX_BONDS; static int tx_queues = BOND_DEFAULT_TX_QUEUES; -static int num_grat_arp = 1; -static int num_unsol_na = 1; static int miimon = BOND_LINK_MON_INTERV; static int updelay; static int downdelay; @@ -113,10 +111,6 @@ module_param(max_bonds, int, 0); MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); module_param(tx_queues, int, 0); MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)"); -module_param(num_grat_arp, int, 0644); -MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); -module_param(num_unsol_na, int, 0644); -MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event"); module_param(miimon, int, 0); MODULE_PARM_DESC(miimon, "Link check interval in milliseconds"); module_param(updelay, int, 0); @@ -234,7 +228,6 @@ struct bond_parm_tbl ad_select_tbl[] = { /*-------------------------- Forward declarations ---------------------------*/ -static void bond_send_gratuitous_arp(struct bonding *bond); static int bond_init(struct net_device *bond_dev); static void bond_uninit(struct net_device *bond_dev); @@ -1162,14 +1155,6 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) bond_do_fail_over_mac(bond, new_active, old_active); - if (netif_running(bond->dev)) { - bond->send_grat_arp = bond->params.num_grat_arp; - bond_send_gratuitous_arp(bond); - - bond->send_unsol_na = bond->params.num_unsol_na; - bond_send_unsolicited_na(bond); - } - write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); @@ -2580,18 +2565,6 @@ void bond_mii_monitor(struct work_struct *work) if (bond->slave_cnt == 0) goto re_arm; - if (bond->send_grat_arp) { - read_lock(&bond->curr_slave_lock); - bond_send_gratuitous_arp(bond); - read_unlock(&bond->curr_slave_lock); - } - - if (bond->send_unsol_na) { - read_lock(&bond->curr_slave_lock); - bond_send_unsolicited_na(bond); - read_unlock(&bond->curr_slave_lock); - } - if (bond_miimon_inspect(bond)) { read_unlock(&bond->lock); rtnl_lock(); @@ -2753,42 +2726,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) } } -/* - * Kick out a gratuitous ARP for an IP on the bonding master plus one - * for each VLAN above us. - * - * Caller must hold curr_slave_lock for read or better - */ -static void bond_send_gratuitous_arp(struct bonding *bond) -{ - struct slave *slave = bond->curr_active_slave; - struct vlan_entry *vlan; - - pr_debug("bond_send_grat_arp: bond %s slave %s\n", - bond->dev->name, slave ? slave->dev->name : "NULL"); - - if (!slave || !bond->send_grat_arp || - test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) - return; - - bond->send_grat_arp--; - - if (bond->master_ip) { - bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, - bond->master_ip, 0); - } - - if (!bond->vlgrp) - return; - - list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - if (vlan->vlan_ip) { - bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip, - vlan->vlan_ip, vlan->vlan_id); - } - } -} - static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip) { int i; @@ -3255,18 +3192,6 @@ void bond_activebackup_arp_mon(struct work_struct *work) if (bond->slave_cnt == 0) goto re_arm; - if (bond->send_grat_arp) { - read_lock(&bond->curr_slave_lock); - bond_send_gratuitous_arp(bond); - read_unlock(&bond->curr_slave_lock); - } - - if (bond->send_unsol_na) { - read_lock(&bond->curr_slave_lock); - bond_send_unsolicited_na(bond); - read_unlock(&bond->curr_slave_lock); - } - if (bond_ab_arp_inspect(bond, delta_in_ticks)) { read_unlock(&bond->lock); rtnl_lock(); @@ -3645,9 +3570,6 @@ static int bond_close(struct net_device *bond_dev) write_lock_bh(&bond->lock); - bond->send_grat_arp = 0; - bond->send_unsol_na = 0; - /* signal timers not to re-arm */ bond->kill_timers = 1; @@ -4724,18 +4646,6 @@ static int bond_check_params(struct bond_params *params) use_carrier = 1; } - if (num_grat_arp < 0 || num_grat_arp > 255) { - pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1\n", - num_grat_arp); - num_grat_arp = 1; - } - - if (num_unsol_na < 0 || num_unsol_na > 255) { - pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1\n", - num_unsol_na); - num_unsol_na = 1; - } - /* reset values for 802.3ad */ if (bond_mode == BOND_MODE_8023AD) { if (!miimon) { @@ -4925,8 +4835,6 @@ static int bond_check_params(struct bond_params *params) params->mode = bond_mode; params->xmit_policy = xmit_hashtype; params->miimon = miimon; - params->num_grat_arp = num_grat_arp; - params->num_unsol_na = num_unsol_na; params->arp_interval = arp_interval; params->arp_validate = arp_validate_value; params->updelay = updelay; @@ -5121,7 +5029,6 @@ static int __init bonding_init(void) register_netdevice_notifier(&bond_netdev_notifier); register_inetaddr_notifier(&bond_inetaddr_notifier); - bond_register_ipv6_notifier(); out: return res; err: @@ -5136,7 +5043,6 @@ static void __exit bonding_exit(void) { unregister_netdevice_notifier(&bond_netdev_notifier); unregister_inetaddr_notifier(&bond_inetaddr_notifier); - bond_unregister_ipv6_notifier(); bond_destroy_sysfs(); bond_destroy_debugfs(); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index de87aea6d01a..259ff32cd573 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -873,84 +873,6 @@ static ssize_t bonding_store_ad_select(struct device *d, static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR, bonding_show_ad_select, bonding_store_ad_select); -/* - * Show and set the number of grat ARP to send after a failover event. - */ -static ssize_t bonding_show_n_grat_arp(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct bonding *bond = to_bond(d); - - return sprintf(buf, "%d\n", bond->params.num_grat_arp); -} - -static ssize_t bonding_store_n_grat_arp(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int new_value, ret = count; - struct bonding *bond = to_bond(d); - - if (sscanf(buf, "%d", &new_value) != 1) { - pr_err("%s: no num_grat_arp value specified.\n", - bond->dev->name); - ret = -EINVAL; - goto out; - } - if (new_value < 0 || new_value > 255) { - pr_err("%s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n", - bond->dev->name, new_value); - ret = -EINVAL; - goto out; - } else { - bond->params.num_grat_arp = new_value; - } -out: - return ret; -} -static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, - bonding_show_n_grat_arp, bonding_store_n_grat_arp); - -/* - * Show and set the number of unsolicited NA's to send after a failover event. - */ -static ssize_t bonding_show_n_unsol_na(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct bonding *bond = to_bond(d); - - return sprintf(buf, "%d\n", bond->params.num_unsol_na); -} - -static ssize_t bonding_store_n_unsol_na(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int new_value, ret = count; - struct bonding *bond = to_bond(d); - - if (sscanf(buf, "%d", &new_value) != 1) { - pr_err("%s: no num_unsol_na value specified.\n", - bond->dev->name); - ret = -EINVAL; - goto out; - } - - if (new_value < 0 || new_value > 255) { - pr_err("%s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n", - bond->dev->name, new_value); - ret = -EINVAL; - goto out; - } else - bond->params.num_unsol_na = new_value; -out: - return ret; -} -static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR, - bonding_show_n_unsol_na, bonding_store_n_unsol_na); - /* * Show and set the MII monitor interval. There are two tricky bits * here. First, if MII monitoring is activated, then we must disable @@ -1650,8 +1572,6 @@ static struct attribute *per_bond_attrs[] = { &dev_attr_lacp_rate.attr, &dev_attr_ad_select.attr, &dev_attr_xmit_hash_policy.attr, - &dev_attr_num_grat_arp.attr, - &dev_attr_num_unsol_na.attr, &dev_attr_miimon.attr, &dev_attr_primary.attr, &dev_attr_primary_reselect.attr, diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 553c764f7407..6126c6a13a74 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -149,8 +149,6 @@ struct bond_params { int mode; int xmit_policy; int miimon; - int num_grat_arp; - int num_unsol_na; int arp_interval; int arp_validate; int use_carrier; @@ -178,9 +176,6 @@ struct vlan_entry { struct list_head vlan_list; __be32 vlan_ip; unsigned short vlan_id; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - struct in6_addr vlan_ipv6; -#endif }; struct slave { @@ -234,8 +229,6 @@ struct bonding { rwlock_t lock; rwlock_t curr_slave_lock; s8 kill_timers; - s8 send_grat_arp; - s8 send_unsol_na; s8 setup_by_slave; s8 igmp_retrans; #ifdef CONFIG_PROC_FS @@ -260,9 +253,6 @@ struct bonding { struct delayed_work alb_work; struct delayed_work ad_work; struct delayed_work mcast_work; -#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; @@ -460,23 +450,4 @@ extern const struct bond_parm_tbl fail_over_mac_tbl[]; extern const struct bond_parm_tbl pri_reselect_tbl[]; extern struct bond_parm_tbl ad_select_tbl[]; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -void bond_send_unsolicited_na(struct bonding *bond); -void bond_register_ipv6_notifier(void); -void bond_unregister_ipv6_notifier(void); -#else -static inline void bond_send_unsolicited_na(struct bonding *bond) -{ - return; -} -static inline void bond_register_ipv6_notifier(void) -{ - return; -} -static inline void bond_unregister_ipv6_notifier(void) -{ - return; -} -#endif - #endif /* _LINUX_BONDING_H */ diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index b2ff70fcf8ea..969e7004cf86 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -501,13 +501,14 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, return NOTIFY_BAD; case NETDEV_NOTIFY_PEERS: + case NETDEV_BONDING_FAILOVER: /* Propagate to vlan devices */ for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, vlandev); + call_netdevice_notifiers(event, vlandev); } break; } diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 5345b0bee6df..acf553f95b5b 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1203,6 +1203,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, break; /* fall through */ case NETDEV_NOTIFY_PEERS: + case NETDEV_BONDING_FAILOVER: /* Send gratuitous ARP to notify of link change */ inetdev_send_gratuitous_arp(dev, in_dev); break; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 62cbd15b4cde..01a0ffc7b402 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1747,6 +1747,7 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, fib6_run_gc(~0UL, net); break; case NETDEV_NOTIFY_PEERS: + case NETDEV_BONDING_FAILOVER: ndisc_send_unsol_na(dev); break; default: -- GitLab From 52c10ad22b7e317960b4d411c9a9ddeaf3d5ae39 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 14 Apr 2011 17:13:53 +0900 Subject: [PATCH 1121/5560] sh: clkfwk: fixup clk_rate_table_build parameter in div6 clock div6 clock should not use arch_flags for clk_rate_table_build, because SH_CLK_DIV6_EXT doesn't care .arch_flags. clk->freq_table[] will be all CPUFREQ_ENTRY_INVALID without this patch. Signed-off-by: Kuninori Morimoto Cc: stable@kernel.org Signed-off-by: Paul Mundt --- drivers/sh/clk/cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 6172335ae323..82dd6fb17838 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -105,7 +105,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) /* Rebuild the frequency table */ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, &clk->arch_flags); + table, NULL); return 0; } -- GitLab From a7f800131f35925299860a95259453c9bc0c272f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 14 Apr 2011 17:13:22 +0900 Subject: [PATCH 1122/5560] ARM: mach-shmobile: clock-sh7372: remove status check from fsidiv_recalc clock status check is not needed in recalc function. clk->rate will be 0 in clk_set_rate without this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/clock-sh7372.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index e9731b5a73ed..6c79b4019667 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -421,9 +421,6 @@ static unsigned long fsidiv_recalc(struct clk *clk) value = __raw_readl(clk->mapping->base); - if ((value & 0x3) != 0x3) - return 0; - value >>= 16; if (value < 2) return 0; -- GitLab From 5744c88111f076c98f389eae28ec2ff206ba2e14 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 15 Apr 2011 20:03:17 +0200 Subject: [PATCH 1123/5560] sh: fix SD / MMC configuration dependencies on ecovec Update CONFIG_MMC_TMIO to the new CONFIG_MMC_SDHI symbol and fix MMCIF to also function in modular builds for ecovec. Signed-off-by: Guennadi Liakhovetski Acked-by: Simon Horman Cc: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 86a0d565aded..bb13d0e1b964 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -482,7 +482,7 @@ static struct i2c_board_info ts_i2c_clients = { .irq = IRQ0, }; -#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE) +#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) /* SDHI0 */ static void sdhi0_set_pwr(struct platform_device *pdev, int state) { @@ -522,7 +522,7 @@ static struct platform_device sdhi0_device = { }, }; -#if !defined(CONFIG_MMC_SH_MMCIF) +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* SDHI1 */ static void sdhi1_set_pwr(struct platform_device *pdev, int state) { @@ -836,7 +836,7 @@ static struct platform_device vou_device = { }, }; -#if defined(CONFIG_MMC_SH_MMCIF) +#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) /* SH_MMCIF */ static void mmcif_set_pwr(struct platform_device *pdev, int state) { @@ -898,9 +898,9 @@ static struct platform_device *ecovec_devices[] __initdata = { &ceu0_device, &ceu1_device, &keysc_device, -#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE) +#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) &sdhi0_device, -#if !defined(CONFIG_MMC_SH_MMCIF) +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) &sdhi1_device, #endif #else @@ -912,7 +912,7 @@ static struct platform_device *ecovec_devices[] __initdata = { &fsi_device, &irda_device, &vou_device, -#if defined(CONFIG_MMC_SH_MMCIF) +#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) &sh_mmcif_device, #endif }; @@ -1180,7 +1180,7 @@ static int __init arch_setup(void) gpio_direction_input(GPIO_PTR5); gpio_direction_input(GPIO_PTR6); -#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE) +#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ gpio_request(GPIO_FN_SDHI0CD, NULL); gpio_request(GPIO_FN_SDHI0WP, NULL); @@ -1193,7 +1193,7 @@ static int __init arch_setup(void) gpio_request(GPIO_PTB6, NULL); gpio_direction_output(GPIO_PTB6, 0); -#if !defined(CONFIG_MMC_SH_MMCIF) +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ gpio_request(GPIO_FN_SDHI1CD, NULL); gpio_request(GPIO_FN_SDHI1WP, NULL); @@ -1284,7 +1284,7 @@ static int __init arch_setup(void) gpio_request(GPIO_PTU5, NULL); gpio_direction_output(GPIO_PTU5, 0); -#if defined(CONFIG_MMC_SH_MMCIF) +#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) /* enable MMCIF (needs DS2.6,7 set to OFF,ON) */ gpio_request(GPIO_FN_MMC_D7, NULL); gpio_request(GPIO_FN_MMC_D6, NULL); -- GitLab From 013b19e3aa843e206a47098063258d5cc5c3482e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 15 Apr 2011 20:04:12 +0200 Subject: [PATCH 1124/5560] sh: update SDHI configuration symbols in defconfigs Signed-off-by: Guennadi Liakhovetski Acked-by: Simon Horman Cc: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/configs/ecovec24_defconfig | 2 +- arch/sh/configs/sh7757lcr_defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 8d13e8a5a750..911e30c9abfd 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -115,7 +115,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_FILE_STORAGE=m CONFIG_MMC=y CONFIG_MMC_SPI=y -CONFIG_MMC_TMIO=y +CONFIG_MMC_SDHI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RS5C372=y CONFIG_UIO=y diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig index fa0ecf87034c..33ddb130a7c8 100644 --- a/arch/sh/configs/sh7757lcr_defconfig +++ b/arch/sh/configs/sh7757lcr_defconfig @@ -70,7 +70,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_MMC=y -CONFIG_MMC_TMIO=y +CONFIG_MMC_SDHI=y CONFIG_MMC_SH_MMCIF=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y -- GitLab From c40eb1e9e53dbd1e5601650565e2ed8bf14866ba Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 15 Apr 2011 20:17:34 +0200 Subject: [PATCH 1125/5560] ALSA: add a module alias to the FSI driver This patch enables FSI driver autoloading on sh-mobile systems. Signed-off-by: Guennadi Liakhovetski Reviewed-by: Simon Horman Acked-by: Liam Girdwood Signed-off-by: Paul Mundt --- sound/soc/sh/fsi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 0c9997e2d8c0..88b669c9af75 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1321,3 +1321,4 @@ module_exit(fsi_mobile_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SuperH onchip FSI audio driver"); MODULE_AUTHOR("Kuninori Morimoto "); +MODULE_ALIAS("platform:fsi-pcm-audio"); -- GitLab From 7ef0c12a280c059f4624d311bb1a7d946cbac7b7 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 15 Apr 2011 20:18:57 +0200 Subject: [PATCH 1126/5560] i2c: add a module alias to the sh-mobile driver This patch enables I2C driver autoloading on sh-mobile systems. Signed-off-by: Guennadi Liakhovetski Reviewed-by: Simon Horman Cc: Magnus Damm Signed-off-by: Paul Mundt --- drivers/i2c/busses/i2c-sh_mobile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 2707f5e17158..81ccd7875627 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -729,3 +729,4 @@ module_exit(sh_mobile_i2c_adap_exit); MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); MODULE_AUTHOR("Magnus Damm"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:i2c-sh_mobile"); -- GitLab From a375b15164dd9264f724ad941825e52c90145151 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 15 Apr 2011 16:44:27 +0900 Subject: [PATCH 1127/5560] sh: fixup fpu.o compile order arch_ptrace() was modified to reference init_fpu() to fix up xstate initialization, which overlooked the fact that there are configurations that don't enable any of hard FPU support or emulation, resulting in build errors on DSP parts. Given that init_fpu() simply sets up the xstate slab cache and is side-stepped entirely for the DSP case, we can simply always build in the helper and fix up the references. Reported-by: Nobuhiro Iwamatsu Signed-off-by: Kuninori Morimoto Cc: stable@kernel.org Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index d49c2135fd48..ae95935d93cd 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -17,7 +17,5 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ obj-$(CONFIG_SH_ADC) += adc.o obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o -obj-$(CONFIG_SH_FPU) += fpu.o -obj-$(CONFIG_SH_FPU_EMU) += fpu.o -obj-y += irq/ init.o clock.o hwblk.o proc.o +obj-y += irq/ init.o clock.o fpu.o hwblk.o proc.o -- GitLab From c33724a43875786719f51916311308f2752d846e Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 28 Apr 2009 15:05:20 +0200 Subject: [PATCH 1128/5560] kconfig: Do not record timestamp in auto.conf and autoconf.h Timestamps in file data are useless and there is already one in .config Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 61c35bf2d9cb..834eecb010ba 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -784,7 +784,6 @@ int conf_write_autoconf(void) const char *str; const char *name; FILE *out, *tristate, *out_h; - time_t now; int i; sym_clear_all_valid(); @@ -811,22 +810,19 @@ int conf_write_autoconf(void) return 1; } - time(&now); fprintf(out, "#\n" "# Automatically generated make config: don't edit\n" "# %s\n" - "# %s" "#\n", - rootmenu.prompt->text, ctime(&now)); + rootmenu.prompt->text); fprintf(tristate, "#\n" "# Automatically generated - do not edit\n" "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" " * %s\n" - " * %s" " */\n", - rootmenu.prompt->text, ctime(&now)); + rootmenu.prompt->text); for_all_symbols(i, sym) { sym_calc_value(sym); -- GitLab From 6ae9ecb86188cc8419024cdb299f18d4ae4f5713 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 31 Mar 2011 15:47:55 +0200 Subject: [PATCH 1129/5560] kbuild: Call gzip with -n The timestamps recorded in the .gz files add no value. Signed-off-by: Michal Marek --- scripts/Makefile.lib | 2 +- scripts/gen_initramfs_list.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 1c702ca8aac8..93b2b5938a2e 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -197,7 +197,7 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ # --------------------------------------------------------------------------- quiet_cmd_gzip = GZIP $@ -cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ +cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ (rm -f $@ ; false) # DTC diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 55caecdad995..4a43fe12d179 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -226,7 +226,7 @@ cpio_list= output="/dev/stdout" output_file="" is_cpio_compressed= -compr="gzip -9 -f" +compr="gzip -n -9 -f" arg="$1" case "$arg" in @@ -240,7 +240,7 @@ case "$arg" in output_file="$1" cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)" output=${cpio_list} - echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f" + echo "$output_file" | grep -q "\.gz$" && compr="gzip -n -9 -f" echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f" echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f" echo "$output_file" | grep -q "\.xz$" && \ -- GitLab From 09ff9fecc039d60fff6c11d47522af61e89fff56 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 31 Mar 2011 16:09:47 +0200 Subject: [PATCH 1130/5560] kbuild: Use the deterministic mode of ar Signed-off-by: Michal Marek --- scripts/Makefile.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d5f925abe4d2..5f87d3709f9f 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -345,7 +345,7 @@ quiet_cmd_link_o_target = LD $@ cmd_link_o_target = $(if $(strip $(obj-y)),\ $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \ $(cmd_secanalysis),\ - rm -f $@; $(AR) rcs $@) + rm -f $@; $(AR) rcsD $@) $(builtin-target): $(obj-y) FORCE $(call if_changed,link_o_target) @@ -371,7 +371,7 @@ $(modorder-target): $(subdir-ym) FORCE # ifdef lib-target quiet_cmd_link_l_target = AR $@ -cmd_link_l_target = rm -f $@; $(AR) rcs $@ $(lib-y) +cmd_link_l_target = rm -f $@; $(AR) rcsD $@ $(lib-y) $(lib-target): $(lib-y) FORCE $(call if_changed,link_l_target) -- GitLab From 061296dc2c14f852604fc6849669fe0b78bb1eda Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 31 Mar 2011 17:13:55 +0200 Subject: [PATCH 1131/5560] kbuild: Drop unused LINUX_COMPILE_TIME and LINUX_COMPILE_DOMAIN macros Signed-off-by: Michal Marek --- scripts/mkcompile_h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 50ad317a4bf9..82416a81df5e 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -63,21 +63,9 @@ UTS_TRUNCATE="cut -b -$UTS_LEN" echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\" - echo \#define LINUX_COMPILE_TIME \"`date +%T`\" echo \#define LINUX_COMPILE_BY \"`whoami`\" echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" - domain=`dnsdomainname 2> /dev/null` - if [ -z "$domain" ]; then - domain=`domainname 2> /dev/null` - fi - - if [ -n "$domain" ]; then - echo \#define LINUX_COMPILE_DOMAIN \"`echo $domain | $UTS_TRUNCATE`\" - else - echo \#define LINUX_COMPILE_DOMAIN - fi - echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\" ) > .tmpcompile @@ -91,8 +79,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN" # first line. if [ -r $TARGET ] && \ - grep -v 'UTS_VERSION\|LINUX_COMPILE_TIME' $TARGET > .tmpver.1 && \ - grep -v 'UTS_VERSION\|LINUX_COMPILE_TIME' .tmpcompile > .tmpver.2 && \ + grep -v 'UTS_VERSION' $TARGET > .tmpver.1 && \ + grep -v 'UTS_VERSION' .tmpcompile > .tmpver.2 && \ cmp -s .tmpver.1 .tmpver.2; then rm -f .tmpcompile else -- GitLab From 53e6892c0411006848882eacfcfea9e93681b55d Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Tue, 5 Apr 2011 14:32:30 +0200 Subject: [PATCH 1132/5560] kbuild: Allow to override LINUX_COMPILE_BY and LINUX_COMPILE_HOST macros Make it possible to override the user@host string displayed during boot and in /proc/version by the environment variables KBUILD_BUILD_USER and KBUILD_BUILD_HOST. Several distributions patch scripts/mkcompile_h to achieve this, so let's provide an official way. Also, document the KBUILD_BUILD_TIMESTAMP variable while at it. Signed-off-by: Michal Marek --- Documentation/kbuild/kbuild.txt | 12 ++++++++++++ scripts/mkcompile_h | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index f1431d099fce..f11ebb33e4a6 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -201,3 +201,15 @@ KBUILD_ENABLE_EXTRA_GCC_CHECKS -------------------------------------------------- If enabled over the make command line with "W=1", it turns on additional gcc -W... options for more extensive build-time checking. + +KBUILD_BUILD_TIMESTAMP +-------------------------------------------------- +Setting this to a date string overrides the timestamp used in the +UTS_VERSION definition (uname -v in the running kernel). The default value +is the output of the date command at one point during build. + +KBUILD_BUILD_USER, KBUILD_BUILD_HOST +-------------------------------------------------- +These two variables allow to override the user@host string displayed during +boot and in /proc/version. The default value is the output of the commands +whoami and host, respectively. diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 82416a81df5e..7ad6bf7a09ff 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -42,6 +42,16 @@ if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then else TIMESTAMP=$KBUILD_BUILD_TIMESTAMP fi +if test -z "$KBUILD_BUILD_USER"; then + LINUX_COMPILE_BY=`whoami` +else + LINUX_COMPILE_BY=$KBUILD_BUILD_USER +fi +if test -z "$KBUILD_BUILD_HOST"; then + LINUX_COMPILE_HOST=`hostname` +else + LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST +fi UTS_VERSION="#$VERSION" CONFIG_FLAGS="" @@ -63,8 +73,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN" echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\" - echo \#define LINUX_COMPILE_BY \"`whoami`\" - echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" + echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\" + echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\" echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\" ) > .tmpcompile -- GitLab From a8b8017c34fefcb763d8b06c294b58d1c480b2e4 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Thu, 31 Mar 2011 23:16:42 +0200 Subject: [PATCH 1133/5560] initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries gen_init_cpio gets the current time and uses it for each symlink, special file, and directory. Grab the current time once and make it possible to override it with the KBUILD_BUILD_TIMESTAMP variable for reproducible builds. Signed-off-by: Michal Marek --- Documentation/kbuild/kbuild.txt | 3 +- scripts/gen_initramfs_list.sh | 9 +++++- usr/gen_init_cpio.c | 53 +++++++++++++++++++++++++-------- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index f11ebb33e4a6..646e2c114fff 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -205,7 +205,8 @@ gcc -W... options for more extensive build-time checking. KBUILD_BUILD_TIMESTAMP -------------------------------------------------- Setting this to a date string overrides the timestamp used in the -UTS_VERSION definition (uname -v in the running kernel). The default value +UTS_VERSION definition (uname -v in the running kernel). The value has to +be a string that can be passed to date -d. The default value is the output of the date command at one point during build. KBUILD_BUILD_USER, KBUILD_BUILD_HOST diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 4a43fe12d179..d44cf675bc22 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -287,8 +287,15 @@ done # we are carefull to delete tmp files if [ ! -z ${output_file} ]; then if [ -z ${cpio_file} ]; then + timestamp= + if test -n "$KBUILD_BUILD_TIMESTAMP"; then + timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)" + if test -n "$timestamp"; then + timestamp="-t $timestamp" + fi + fi cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)" - usr/gen_init_cpio ${cpio_list} > ${cpio_tfile} + usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile} else cpio_tfile=${cpio_file} fi diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 7f06884ecd41..af0f22fb1ef7 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -22,6 +22,7 @@ static unsigned int offset; static unsigned int ino = 721; +static time_t default_mtime; struct file_handler { const char *type; @@ -102,7 +103,6 @@ static int cpio_mkslink(const char *name, const char *target, unsigned int mode, uid_t uid, gid_t gid) { char s[256]; - time_t mtime = time(NULL); if (name[0] == '/') name++; @@ -114,7 +114,7 @@ static int cpio_mkslink(const char *name, const char *target, (long) uid, /* uid */ (long) gid, /* gid */ 1, /* nlink */ - (long) mtime, /* mtime */ + (long) default_mtime, /* mtime */ (unsigned)strlen(target)+1, /* filesize */ 3, /* major */ 1, /* minor */ @@ -152,7 +152,6 @@ static int cpio_mkgeneric(const char *name, unsigned int mode, uid_t uid, gid_t gid) { char s[256]; - time_t mtime = time(NULL); if (name[0] == '/') name++; @@ -164,7 +163,7 @@ static int cpio_mkgeneric(const char *name, unsigned int mode, (long) uid, /* uid */ (long) gid, /* gid */ 2, /* nlink */ - (long) mtime, /* mtime */ + (long) default_mtime, /* mtime */ 0, /* filesize */ 3, /* major */ 1, /* minor */ @@ -242,7 +241,6 @@ static int cpio_mknod(const char *name, unsigned int mode, unsigned int maj, unsigned int min) { char s[256]; - time_t mtime = time(NULL); if (dev_type == 'b') mode |= S_IFBLK; @@ -259,7 +257,7 @@ static int cpio_mknod(const char *name, unsigned int mode, (long) uid, /* uid */ (long) gid, /* gid */ 1, /* nlink */ - (long) mtime, /* mtime */ + (long) default_mtime, /* mtime */ 0, /* filesize */ 3, /* major */ 1, /* minor */ @@ -460,7 +458,7 @@ static int cpio_mkfile_line(const char *line) static void usage(const char *prog) { fprintf(stderr, "Usage:\n" - "\t%s \n" + "\t%s [-t ] \n" "\n" " is a file containing newline separated entries that\n" "describe the files to be included in the initramfs archive:\n" @@ -491,7 +489,11 @@ static void usage(const char *prog) "nod /dev/console 0600 0 0 c 5 1\n" "dir /root 0700 0 0\n" "dir /sbin 0755 0 0\n" - "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n", + "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n" + "\n" + " is time in seconds since Epoch that will be used\n" + "as mtime for symlinks, special files and directories. The default\n" + "is to use the current time for these entries.\n", prog); } @@ -529,17 +531,42 @@ int main (int argc, char *argv[]) char *args, *type; int ec = 0; int line_nr = 0; + const char *filename; + + default_mtime = time(NULL); + while (1) { + int opt = getopt(argc, argv, "t:h"); + char *invalid; - if (2 != argc) { + if (opt == -1) + break; + switch (opt) { + case 't': + default_mtime = strtol(optarg, &invalid, 10); + if (!*optarg || *invalid) { + fprintf(stderr, "Invalid timestamp: %s\n", + optarg); + usage(argv[0]); + exit(1); + } + break; + case 'h': + case '?': + usage(argv[0]); + exit(opt == 'h' ? 0 : 1); + } + } + + if (argc - optind != 1) { usage(argv[0]); exit(1); } - - if (!strcmp(argv[1], "-")) + filename = argv[optind]; + if (!strcmp(filename, "-")) cpio_list = stdin; - else if (! (cpio_list = fopen(argv[1], "r"))) { + else if (!(cpio_list = fopen(filename, "r"))) { fprintf(stderr, "ERROR: unable to open '%s': %s\n\n", - argv[1], strerror(errno)); + filename, strerror(errno)); usage(argv[0]); exit(1); } -- GitLab From e93504933ee6982bdc005fa5c24e1ea330faaf8b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 18 Apr 2011 11:34:55 -0400 Subject: [PATCH 1134/5560] xen/blkback: Move the check for misaligned I/O once more. The commit 976222e05ea5a9959ccf880d7a24efbf79b3c6cf xen/blkback: Move the check for misaligned I/O higher. moved it a bit to high. The preq->vbdev was not set, so the check for misaligned I/O would cause a NULL pointer derefence. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index c645c83f900b..a0d3227955c9 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -514,6 +514,7 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, pending_req->operation = req->operation; pending_req->status = BLKIF_RSP_OKAY; pending_req->nr_pages = nseg; + for (i = 0; i < nseg; i++) { seg[i].nsec = req->u.rw.seg[i].last_sect - req->u.rw.seg[i].first_sect + 1; @@ -522,12 +523,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, goto fail_response; preq.nr_sects += seg[i].nsec; - if (((int)preq.sector_number|(int)seg[i].nsec) & - ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) { - DPRINTK("Misaligned I/O request from domain %d", - blkif->domid); - goto fail_response; - } } if (vbd_translate(&preq, blkif, operation) != 0) { @@ -537,6 +532,16 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, preq.sector_number + preq.nr_sects, preq.dev); goto fail_response; } + /* This check _MUST_ be done after vbd_translate as the preq.bdev + * is set there. */ + for (i = 0; i < nseg; i++) { + if (((int)preq.sector_number|(int)seg[i].nsec) & + ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) { + DPRINTK("Misaligned I/O request from domain %d", + blkif->domid); + goto fail_response; + } + } /* If we have failed at this point, we need to undo the M2P override, * set gnttab_set_unmap_op on all of the grant references and perform * the hypercall to unmap the grants - that is all done in -- GitLab From e79b1ca75bb48111e8d93fc576f50e24671f5f9d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 5 Apr 2011 08:30:43 -0700 Subject: [PATCH 1135/5560] iwlagn: use direct call for led functions After driver split, no need to call led functions through callback Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 - drivers/net/wireless/iwlwifi/iwl-2000.c | 5 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 3 - drivers/net/wireless/iwlwifi/iwl-6000.c | 5 -- drivers/net/wireless/iwlwifi/iwl-agn-led.c | 73 ---------------------- drivers/net/wireless/iwlwifi/iwl-agn-led.h | 33 ---------- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 - drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-led.c | 26 +++++++- drivers/net/wireless/iwlwifi/iwl-led.h | 1 + 11 files changed, 27 insertions(+), 125 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 3652931753e0..bb6a737de61f 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,6 +1,6 @@ # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o -iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o +iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index d1d7852f0ee4..809117d74196 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -45,7 +45,6 @@ #include "iwl-agn.h" #include "iwl-helpers.h" #include "iwl-agn-hw.h" -#include "iwl-agn-led.h" #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ @@ -226,7 +225,6 @@ static const struct iwl_ops iwl1000_ops = { .lib = &iwl1000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index a31314fdb053..0a330d16ce7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -46,7 +46,6 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-6000-hw.h" -#include "iwl-agn-led.h" #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ @@ -310,7 +309,6 @@ static const struct iwl_ops iwl2000_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -318,7 +316,6 @@ static const struct iwl_ops iwl2030_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -326,7 +323,6 @@ static const struct iwl_ops iwl200_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -334,7 +330,6 @@ static const struct iwl_ops iwl230_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 7c286662d26a..79dd45c3aefc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -45,7 +45,6 @@ #include "iwl-sta.h" #include "iwl-helpers.h" #include "iwl-agn.h" -#include "iwl-agn-led.h" #include "iwl-agn-hw.h" #include "iwl-5000-hw.h" #include "iwl-agn-debugfs.h" @@ -447,7 +446,6 @@ static const struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -455,7 +453,6 @@ static const struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 064981345c84..a35338e20b10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -46,7 +46,6 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-6000-hw.h" -#include "iwl-agn-led.h" #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ @@ -397,7 +396,6 @@ static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -405,7 +403,6 @@ static const struct iwl_ops iwl6050_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .nic = &iwl6050_nic_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -414,7 +411,6 @@ static const struct iwl_ops iwl6150_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .nic = &iwl6150_nic_ops, .ieee80211_ops = &iwlagn_hw_ops, }; @@ -423,7 +419,6 @@ static const struct iwl_ops iwl6030_ops = { .lib = &iwl6030_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .led = &iwlagn_led_ops, .ieee80211_ops = &iwlagn_hw_ops, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c deleted file mode 100644 index 4bb877e600c7..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2011 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-commands.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-io.h" -#include "iwl-agn-led.h" - -/* Send led command */ -static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_LEDS_CMD, - .len = sizeof(struct iwl_led_cmd), - .data = led_cmd, - .flags = CMD_ASYNC, - .callback = NULL, - }; - u32 reg; - - reg = iwl_read32(priv, CSR_LED_REG); - if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) - iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); - - return iwl_send_cmd(priv, &cmd); -} - -/* Set led register off */ -void iwlagn_led_enable(struct iwl_priv *priv) -{ - iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); -} - -const struct iwl_led_ops iwlagn_led_ops = { - .cmd = iwl_send_led_cmd, -}; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h deleted file mode 100644 index c0b7611b72c3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2011 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 - * - *****************************************************************************/ - -#ifndef __iwl_agn_led_h__ -#define __iwl_agn_led_h__ - -extern const struct iwl_led_ops iwlagn_led_ops; -void iwlagn_led_enable(struct iwl_priv *priv); - -#endif /* __iwl_agn_led_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 47a4cda9eb72..b4f7510f51ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -59,7 +59,6 @@ #include "iwl-sta.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" -#include "iwl-agn-led.h" /****************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6988335328e8..240abdf4347c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -217,7 +217,6 @@ 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; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 0d90004e8b1b..d798c2a152d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -61,6 +61,12 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { { .throughput = 300 * 1024 - 1, .blink_time = 50 }, }; +/* Set led register off */ +void iwlagn_led_enable(struct iwl_priv *priv) +{ + iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); +} + /* * Adjust led blink rate to compensate on a MAC Clock difference on every HW * Led blink rate analysis showed an average deviation of 20% on 5000 series @@ -84,6 +90,24 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv, return (u8)((time * compensation) >> 6); } +static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_LEDS_CMD, + .len = sizeof(struct iwl_led_cmd), + .data = led_cmd, + .flags = CMD_ASYNC, + .callback = NULL, + }; + u32 reg; + + reg = iwl_read32(priv, CSR_LED_REG); + if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) + iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); + + return iwl_send_cmd(priv, &cmd); +} + /* Set led pattern command */ static int iwl_led_cmd(struct iwl_priv *priv, unsigned long on, @@ -108,7 +132,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, led_cmd.off = iwl_blink_compensation(priv, off, priv->cfg->base_params->led_compensation); - ret = priv->cfg->ops->led->cmd(priv, &led_cmd); + ret = iwl_send_led_cmd(priv, &led_cmd); if (!ret) { priv->blink_on = on; priv->blink_off = off; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 05b8e8f7dd4a..1c93dfef6933 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -50,6 +50,7 @@ enum iwl_led_mode { IWL_LED_BLINK, }; +void iwlagn_led_enable(struct iwl_priv *priv); void iwl_leds_init(struct iwl_priv *priv); void iwl_leds_exit(struct iwl_priv *priv); -- GitLab From 6fd17b5643bf05c29fc226a5aee96328056fca10 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 18 Apr 2011 12:04:17 -0400 Subject: [PATCH 1136/5560] xen/blkback: Get the 'requeust_queue' properly. After the commit 0faa8cca883bbc6a0919e3c89128672659b75820 (" xen/blkback: remove per-queue plugging") we forgot to retrieve the 'struct request_queue' from the block device. This puts the functionality back in and fixes a NULL pointer bug. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/blkback/blkback.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index a0d3227955c9..3751325bfc32 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -542,6 +542,9 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, goto fail_response; } } + q = bdev_get_queue(preq.bdev); + if (!q) + goto fail_response; /* If we have failed at this point, we need to undo the M2P override, * set gnttab_set_unmap_op on all of the grant references and perform * the hypercall to unmap the grants - that is all done in -- GitLab From 3e41ace5deef7af16dd277d9d17f9d36dca0a10e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Apr 2011 09:12:37 -0700 Subject: [PATCH 1137/5560] iwlagn: remove most BUG_ON instances There are a number of things in the driver that may result in a BUG(), which is suboptimal since it's hard to get debugging information out of the driver in that case and the user experience is also not good :-) Almost all BUG_ON instances can be converted to WARN_ON with a few lines of appropriate error handling, so do that instead. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 ++++++-- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-eeprom.h | 1 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 12 +++++++---- drivers/net/wireless/iwlwifi/iwl-power.c | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-sta.c | 9 +++++--- drivers/net/wireless/iwlwifi/iwl-tx.c | 25 +++++++++++++++-------- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b4f7510f51ec..0daededb0ff2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -394,7 +394,9 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, return -EINVAL; } - BUG_ON(addr & ~DMA_BIT_MASK(36)); + if (WARN_ON(addr & ~DMA_BIT_MASK(36))) + return -EINVAL; + if (unlikely(addr & ~IWL_TX_DMA_MASK)) IWL_ERR(priv, "Unaligned address = %llx\n", (unsigned long long)addr); @@ -718,7 +720,10 @@ static void iwl_rx_handle(struct iwl_priv *priv) /* If an RXB doesn't have a Rx queue slot associated with it, * then a bug has been introduced in the queue refilling * routines -- catch it here */ - BUG_ON(rxb == NULL); + if (WARN_ON(rxb == NULL)) { + i = (i + 1) & RX_QUEUE_MASK; + continue; + } rxq->queue[i] = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 859b94a12297..402733638f50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -215,12 +215,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) return nvm_type; } -const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) -{ - BUG_ON(offset >= priv->cfg->base_params->eeprom_size); - return &priv->eeprom[offset]; -} - static int iwl_init_otp_access(struct iwl_priv *priv) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 0e9d9703636a..9ce052573c6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -309,7 +309,6 @@ 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); -const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); int iwl_init_channel_map(struct iwl_priv *priv); void iwl_free_channel_map(struct iwl_priv *priv); const struct iwl_channel_info *iwl_get_channel_info( diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 9177b553fe57..8f0beb992ccf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -143,10 +143,12 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { int ret; - BUG_ON(!(cmd->flags & CMD_ASYNC)); + if (WARN_ON(!(cmd->flags & CMD_ASYNC))) + return -EINVAL; /* An asynchronous command can not expect an SKB to be set. */ - BUG_ON(cmd->flags & CMD_WANT_SKB); + if (WARN_ON(cmd->flags & CMD_WANT_SKB)) + return -EINVAL; /* Assign a generic callback if one is not provided */ if (!cmd->callback) @@ -169,10 +171,12 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int cmd_idx; int ret; - lockdep_assert_held(&priv->mutex); + if (WARN_ON(cmd->flags & CMD_ASYNC)) + return -EINVAL; /* A synchronous command can not have a callback set. */ - BUG_ON((cmd->flags & CMD_ASYNC) || cmd->callback); + if (WARN_ON(cmd->callback)) + return -EINVAL; IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index ae176d8da9e8..b7cd95820ff8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -188,9 +188,10 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, table = range_0; } - BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM); - - *cmd = table[lvl].cmd; + if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM)) + memset(cmd, 0, sizeof(*cmd)); + else + *cmd = table[lvl].cmd; if (period == 0) { skip = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c21515640077..3c8cebde16cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -494,7 +494,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, priv->num_stations--; - BUG_ON(priv->num_stations < 0); + if (WARN_ON(priv->num_stations < 0)) + priv->num_stations = 0; spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -679,7 +680,8 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; priv->num_stations--; - BUG_ON(priv->num_stations < 0); + if (WARN_ON(priv->num_stations < 0)) + priv->num_stations = 0; kfree(priv->stations[i].lq); priv->stations[i].lq = NULL; } @@ -775,7 +777,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, spin_unlock_irqrestore(&priv->sta_lock, flags_spin); iwl_dump_lq_cmd(priv, lq); - BUG_ON(init && (cmd.flags & CMD_ASYNC)); + if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) + return -EINVAL; if (is_lq_table_valid(priv, ctx, lq)) ret = iwl_send_cmd(priv, &cmd); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 3732380c4ffe..e7faba57b6e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -263,11 +263,13 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, /* count must be power-of-two size, otherwise iwl_queue_inc_wrap * and iwl_queue_dec_wrap are broken. */ - BUG_ON(!is_power_of_2(count)); + if (WARN_ON(!is_power_of_2(count))) + return -EINVAL; /* slots_num must be power-of-two size, otherwise * get_cmd_index is broken. */ - BUG_ON(!is_power_of_2(slots_num)); + if (WARN_ON(!is_power_of_2(slots_num))) + return -EINVAL; q->low_mark = q->n_window / 4; if (q->low_mark < 4) @@ -384,7 +386,9 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); /* Initialize queue's high/low-water marks, and head/tail indexes */ - iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + if (ret) + return ret; /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); @@ -446,14 +450,19 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); - /* If any of the command structures end up being larger than + /* + * If any of the command structures end up being larger than * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then * we will need to increase the size of the TFD entries * Also, check to see if command buffer should not exceed the size - * of device_cmd and max_cmd_size. */ - BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && - !(cmd->flags & CMD_SIZE_HUGE)); - BUG_ON(fix_size > IWL_MAX_CMD_SIZE); + * of device_cmd and max_cmd_size. + */ + if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && + !(cmd->flags & CMD_SIZE_HUGE))) + return -EINVAL; + + if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE)) + return -EINVAL; if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { IWL_WARN(priv, "Not sending command - %s KILL\n", -- GitLab From 7b21f00ee6073909c01adeba317af3d78c3b9d0a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 18 Apr 2011 09:22:10 -0700 Subject: [PATCH 1138/5560] iwlagn: verify that huge commands are synchronous Since huge commands all share a single buffer, there can only be a single one in flight at a time since otherwise they'd overwrite each other. This is true in the driver now, but it seems like a possible source of bugs, so add a test to verify that huge commands are always sent synchronously. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-tx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e7faba57b6e3..1b69507db5fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -470,6 +470,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + /* + * As we only have a single huge buffer, check that the command + * is synchronous (otherwise buffers could end up being reused). + */ + + if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE))) + return -EINVAL; + spin_lock_irqsave(&priv->hcmd_lock, flags); if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { -- GitLab From b4ebd28f23e3ae00af886aff1c00f800dee3b080 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Apr 2011 12:28:56 -0700 Subject: [PATCH 1139/5560] iwlagn: use huge command for beacon When testing some new P2P code, Angie found that the driver might crash because the beacon command ended up being bigger than a regular command. This is quite obvious -- a normal command is limited to roughly 360 bytes but a beacon may be much larger of course. To fix this, use the huge command buffer. Reported-by: Angie Chinchilla Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0daededb0ff2..3cfd7ebb3448 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -253,6 +253,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) struct iwl_frame *frame; unsigned int frame_size; int rc; + struct iwl_host_cmd cmd = { + .id = REPLY_TX_BEACON, + .flags = CMD_SIZE_HUGE, + }; frame = iwl_get_free_frame(priv); if (!frame) { @@ -268,8 +272,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) return -EINVAL; } - rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, - &frame->u.cmd[0]); + cmd.len = frame_size; + cmd.data = &frame->u.cmd[0]; + + rc = iwl_send_cmd_sync(priv, &cmd); iwl_free_frame(priv, frame); -- GitLab From b7af6a99690503a48c63ce5e587b4e4555f31cdb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Apr 2011 15:55:25 -0700 Subject: [PATCH 1140/5560] iwlagn: always support uCode trace All _agn devices support continuous uCode trace, remove checking Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 +-- 6 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 809117d74196..e7844565ef55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -242,7 +242,6 @@ static struct iwl_base_params iwl1000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 128, - .ucode_tracing = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0a330d16ce7e..dcd660818d21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -348,7 +348,6 @@ static struct iwl_base_params iwl2000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; @@ -368,7 +367,6 @@ static struct iwl_base_params iwl2030_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79dd45c3aefc..14b75f1de186 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -467,7 +467,6 @@ static struct iwl_base_params iwl5000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a35338e20b10..81881aad8751 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -437,7 +437,6 @@ static struct iwl_base_params iwl6000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; @@ -456,7 +455,6 @@ static struct iwl_base_params iwl6050_base_params = { .chain_noise_scale = 1500, .wd_timeout = IWL_DEF_WD_TIMEOUT, .max_event_log_size = 1024, - .ucode_tracing = true, .shadow_reg_enable = true, }; static struct iwl_base_params iwl6000_g2_base_params = { @@ -474,7 +472,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .ucode_tracing = true, .shadow_reg_enable = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 240abdf4347c..2e8c936e556d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -249,7 +249,6 @@ struct iwl_mod_params { * @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 - * @ucode_tracing: support ucode continuous tracing * @shadow_reg_enable: HW shadhow register bit */ struct iwl_base_params { @@ -271,7 +270,6 @@ struct iwl_base_params { unsigned int wd_timeout; bool temperature_kelvin; u32 max_event_log_size; - const bool ucode_tracing; const bool shadow_reg_enable; }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 897efacb96eb..c272204fccff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1749,8 +1749,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); - if (priv->cfg->base_params->ucode_tracing) - DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); -- GitLab From f42e7662815647c1a6f73e160abcdf812d3057d2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 18 Apr 2011 09:30:09 -0700 Subject: [PATCH 1141/5560] iwlagn: temperature should be measure for all _agn devices Thermal throttling functions are available for all _agn devices, call the functions directly. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-2000.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-5000.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-6000.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-core.h | 9 --------- drivers/net/wireless/iwlwifi/iwl-power.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-tx.c | 5 +---- 7 files changed, 3 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e7844565ef55..946c7dca440a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -214,11 +214,6 @@ static struct iwl_lib_ops iwl1000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index dcd660818d21..c8bb4a4930df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -298,11 +298,6 @@ static struct iwl_lib_ops iwl2000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static const struct iwl_ops iwl2000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 14b75f1de186..ced89f662bd1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -383,11 +383,6 @@ static struct iwl_lib_ops iwl5000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static struct iwl_lib_ops iwl5150_lib = { @@ -435,11 +430,6 @@ static struct iwl_lib_ops iwl5150_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static const struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 81881aad8751..ed6a0ed0f501 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -323,11 +323,6 @@ static struct iwl_lib_ops iwl6000_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static struct iwl_lib_ops iwl6030_lib = { @@ -377,11 +372,6 @@ static struct iwl_lib_ops iwl6030_lib = { }, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, - .tt_ops = { - .lower_power_detection = iwl_tt_is_low_power_state, - .tt_power_mode = iwl_tt_current_power_mode, - .ct_kill_check = iwl_check_for_ct_kill, - } }; static struct iwl_nic_ops iwl6050_nic_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2e8c936e556d..abee5074d30e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -139,12 +139,6 @@ struct iwl_temp_ops { void (*temperature)(struct iwl_priv *priv); }; -struct iwl_tt_ops { - bool (*lower_power_detection)(struct iwl_priv *priv); - u8 (*tt_power_mode)(struct iwl_priv *priv); - bool (*ct_kill_check)(struct iwl_priv *priv); -}; - struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); @@ -190,9 +184,6 @@ struct iwl_lib_ops { void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); struct iwl_debugfs_ops debugfs_ops; - - /* thermal throttling */ - struct iwl_tt_ops tt_ops; }; struct iwl_led_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index b7cd95820ff8..595c930b28ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -357,12 +357,10 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) 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)) { + else if (iwl_tt_is_low_power_state(priv)) { /* in thermal throttling low power state */ iwl_static_sleep_cmd(priv, cmd, - priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); + iwl_tt_current_power_mode(priv), dtimper); } else if (!enabled) iwl_power_sleep_cam_cmd(priv, cmd); else if (priv->power_data.debug_sleep_level_override >= 0) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1b69507db5fc..80c3565a66ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -484,10 +484,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) spin_unlock_irqrestore(&priv->hcmd_lock, flags); IWL_ERR(priv, "No space in command queue\n"); - if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { - is_ct_kill = - priv->cfg->ops->lib->tt_ops.ct_kill_check(priv); - } + is_ct_kill = iwl_check_for_ct_kill(priv); if (!is_ct_kill) { IWL_ERR(priv, "Restarting adapter due to queue full\n"); iwlagn_fw_error(priv, false); -- GitLab From 5cab35e7f4feda1a0bfd4f48b7686391004be9de Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 6 Apr 2011 15:55:27 -0700 Subject: [PATCH 1142/5560] iwlagn: no 5.2GHz/HT40 support for bgn devices For bgn devices, there were no HT40 channels value in EEPROM Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 946c7dca440a..a01871801e53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -195,7 +195,7 @@ static struct iwl_lib_ops iwl1000_lib = { EEPROM_REG_BAND_4_CHANNELS, EEPROM_REG_BAND_5_CHANNELS, EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS + EEPROM_REGULATORY_BAND_NO_HT40, }, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index c8bb4a4930df..0bd9b146bb94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -278,7 +278,7 @@ static struct iwl_lib_ops iwl2000_lib = { EEPROM_REG_BAND_4_CHANNELS, EEPROM_REG_BAND_5_CHANNELS, EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS + EEPROM_REGULATORY_BAND_NO_HT40, }, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, -- GitLab From 119ea186cad7643ea82b7290374ebb8e780c35b6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 18 Apr 2011 09:34:06 -0700 Subject: [PATCH 1143/5560] iwlagn: remove un-necessary ieee80211_ops After driver split, no need to use ieee80211_ops, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-agn.c | 22 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.c | 24 ------------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 2 -- 7 files changed, 22 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index a01871801e53..baf80111efaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -220,7 +220,6 @@ static const struct iwl_ops iwl1000_ops = { .lib = &iwl1000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl1000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0bd9b146bb94..e76e02c28928 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -304,28 +304,24 @@ static const struct iwl_ops iwl2000_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl2030_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl200_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl230_ops = { .lib = &iwl2000_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static struct iwl_base_params iwl2000_base_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ced89f662bd1..655afc19f68f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -436,14 +436,12 @@ static const struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .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 ed6a0ed0f501..905eb57f7cab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -386,7 +386,6 @@ static const struct iwl_ops iwl6000_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6050_ops = { @@ -394,7 +393,6 @@ static const struct iwl_ops iwl6050_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .nic = &iwl6050_nic_ops, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6150_ops = { @@ -402,14 +400,12 @@ static const struct iwl_ops iwl6150_ops = { .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .nic = &iwl6150_nic_ops, - .ieee80211_ops = &iwlagn_hw_ops, }; static const struct iwl_ops iwl6030_ops = { .lib = &iwl6030_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, - .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 3cfd7ebb3448..cdeb09eee739 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3728,6 +3728,28 @@ static const u8 iwlagn_pan_ac_to_queue[] = { 7, 6, 5, 4, }; +/* This function both allocates and initializes hw and priv. */ +static 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; + + hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); + if (hw == NULL) { + pr_err("%s: Can not allocate network device\n", + cfg->name); + goto out; + } + + priv = hw->priv; + priv->hw = hw; + +out: + return hw; +} + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0, i; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0e98a8703e55..885167f8168d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -67,30 +67,6 @@ u32 iwl_debug_level; const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - -/* This function both allocates and initializes hw and priv. */ -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; - - 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); - goto out; - } - - priv = hw->priv; - priv->hw = hw; - -out: - return hw; -} - #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, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index abee5074d30e..0049790eab7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -210,7 +210,6 @@ struct iwl_ops { const struct iwl_hcmd_utils_ops *utils; const struct iwl_nic_ops *nic; const struct iwl_legacy_ops *legacy; - const struct ieee80211_ops *ieee80211_ops; }; struct iwl_mod_params { @@ -364,7 +363,6 @@ struct iwl_cfg { * L i b * ***************************/ -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); -- GitLab From e339807d97bcb4e214c9137bb5bbb2f685054624 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 8 Apr 2011 10:21:52 -0700 Subject: [PATCH 1144/5560] iwlagn: remove legacy ops No longer used by _agn devices, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 0049790eab7f..99a91bddd9ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -195,21 +195,11 @@ 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_nic_ops *nic; - const struct iwl_legacy_ops *legacy; }; struct iwl_mod_params { -- GitLab From f212b43c4e4a8f6378c50ce18f3d271983b575a7 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 18 Apr 2011 09:36:30 -0700 Subject: [PATCH 1145/5560] iwlagn: remove led_ops No longer use, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 99a91bddd9ee..32a990ff09ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -186,10 +186,6 @@ struct iwl_lib_ops { struct iwl_debugfs_ops debugfs_ops; }; -struct iwl_led_ops { - int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); -}; - /* NIC specific ops */ struct iwl_nic_ops { void (*additional_nic_config)(struct iwl_priv *priv); -- GitLab From 4651d5566840e911b14a5052f18ed39558677937 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:28:59 -0600 Subject: [PATCH 1146/5560] ARM: Tegra: Rename harmony_audio.h -> tegra_wm8903_pdata.h The audio driver will soon support more than just the Tegra Harmony board. Rename the platform data header file and data type to reflect this. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- arch/arm/mach-tegra/board-harmony.c | 4 ++-- .../mach/{harmony_audio.h => tegra_wm8903_pdata.h} | 4 ++-- sound/soc/tegra/harmony.c | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) rename arch/arm/mach-tegra/include/mach/{harmony_audio.h => tegra_wm8903_pdata.h} (86%) diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 75c918a86a31..3c6bba25a1e4 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include #include @@ -67,7 +67,7 @@ static struct platform_device debug_uart = { }, }; -static struct harmony_audio_platform_data harmony_audio_pdata = { +static struct tegra_wm8903_platform_data harmony_audio_pdata = { .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, .gpio_hp_det = TEGRA_GPIO_HP_DET, .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN, diff --git a/arch/arm/mach-tegra/include/mach/harmony_audio.h b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h similarity index 86% rename from arch/arm/mach-tegra/include/mach/harmony_audio.h rename to arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h index af086500ab7d..c34bd5eb204e 100644 --- a/arch/arm/mach-tegra/include/mach/harmony_audio.h +++ b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h @@ -1,5 +1,5 @@ /* - * arch/arm/mach-tegra/include/mach/harmony_audio.h + * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h * * Copyright 2011 NVIDIA, Inc. * @@ -14,7 +14,7 @@ * */ -struct harmony_audio_platform_data { +struct tegra_wm8903_platform_data { int gpio_spkr_en; int gpio_hp_det; int gpio_int_mic_en; diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c index 8585957477eb..c3096c3b9e2b 100644 --- a/sound/soc/tegra/harmony.c +++ b/sound/soc/tegra/harmony.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include @@ -58,7 +58,7 @@ struct tegra_harmony { struct tegra_asoc_utils_data util_data; - struct harmony_audio_platform_data *pdata; + struct tegra_wm8903_platform_data *pdata; int gpio_requested; }; @@ -163,7 +163,7 @@ static int harmony_event_int_spk(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; struct snd_soc_card *card = codec->card; struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); - struct harmony_audio_platform_data *pdata = harmony->pdata; + struct tegra_wm8903_platform_data *pdata = harmony->pdata; gpio_set_value_cansleep(pdata->gpio_spkr_en, SND_SOC_DAPM_EVENT_ON(event)); @@ -198,7 +198,7 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); - struct harmony_audio_platform_data *pdata = harmony->pdata; + struct tegra_wm8903_platform_data *pdata = harmony->pdata; int ret; ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); @@ -291,7 +291,7 @@ static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_harmony; struct tegra_harmony *harmony; - struct harmony_audio_platform_data *pdata; + struct tegra_wm8903_platform_data *pdata; int ret; if (!machine_is_harmony()) { @@ -344,7 +344,7 @@ static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); - struct harmony_audio_platform_data *pdata = harmony->pdata; + struct tegra_wm8903_platform_data *pdata = harmony->pdata; snd_soc_unregister_card(card); -- GitLab From 7b33af252fbbf3beb694448da3ba6687022fd602 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:29:00 -0600 Subject: [PATCH 1147/5560] ASoC: Tegra: Rename pdev tegra-snd-harmony to tegra-snd-wm8903 Soon, this machine driver will be updated to handle a number of Tegra boards using the WM8903 codec. Rename the platform device in advance to reflect this. Signed-off-by: Stephen Warren Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-tegra/board-harmony.c | 2 +- sound/soc/tegra/harmony.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 3c6bba25a1e4..987c5e46d581 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -75,7 +75,7 @@ static struct tegra_wm8903_platform_data harmony_audio_pdata = { }; static struct platform_device harmony_audio_device = { - .name = "tegra-snd-harmony", + .name = "tegra-snd-wm8903", .id = 0, .dev = { .platform_data = &harmony_audio_pdata, diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/harmony.c index c3096c3b9e2b..ae168f2446a6 100644 --- a/sound/soc/tegra/harmony.c +++ b/sound/soc/tegra/harmony.c @@ -50,7 +50,7 @@ #include "tegra_pcm.h" #include "tegra_asoc_utils.h" -#define DRV_NAME "tegra-snd-harmony" +#define DRV_NAME "tegra-snd-wm8903" #define GPIO_SPKR_EN BIT(0) #define GPIO_INT_MIC_EN BIT(1) -- GitLab From 61a6d0764be43e014d265128c2af1b41e0fc96b0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:29:01 -0600 Subject: [PATCH 1148/5560] ARM: Tegra: Add to tegra_wm8903_platform_data Seaboard derivate Kaen has a GPIO to mute the headphone output. Add a field to tegra_wm8903_platform_data so the board files can pass the GPIO number for that to the ASoC machine driver. Also, initialize this new field to a "not present" value for Harmony. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- arch/arm/mach-tegra/board-harmony.c | 1 + arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 987c5e46d581..30e18bc60647 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -70,6 +70,7 @@ static struct platform_device debug_uart = { static struct tegra_wm8903_platform_data harmony_audio_pdata = { .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, .gpio_hp_det = TEGRA_GPIO_HP_DET, + .gpio_hp_mute = -1, .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN, .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN, }; diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h index c34bd5eb204e..9d293344a7ff 100644 --- a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h +++ b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h @@ -17,6 +17,7 @@ struct tegra_wm8903_platform_data { int gpio_spkr_en; int gpio_hp_det; + int gpio_hp_mute; int gpio_int_mic_en; int gpio_ext_mic_en; }; -- GitLab From d2436eda2e81f1993bfe6349f17f52503bffeff5 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 18 Apr 2011 14:17:49 -0400 Subject: [PATCH 1149/5560] block, xen/blkback: remove blk_[get|put]_queue calls. They were used to check if the queue does not have QUEUE_FLAG_DEAD set. That is not necessary anymore as the 'submit_io' call ends up doing that for us. Signed-off-by: Konrad Rzeszutek Wilk --- block/blk-core.c | 2 -- drivers/xen/blkback/blkback.c | 6 ------ 2 files changed, 8 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 9b60e69a5400..90f22cc30799 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -351,7 +351,6 @@ void blk_put_queue(struct request_queue *q) { kobject_put(&q->kobj); } -EXPORT_SYMBOL_GPL(blk_put_queue); /* * Note: If a driver supplied the queue lock, it should not zap that lock @@ -573,7 +572,6 @@ int blk_get_queue(struct request_queue *q) return 1; } -EXPORT_SYMBOL_GPL(blk_get_queue); static inline void blk_free_request(struct request_queue *q, struct request *rq) { diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 3751325bfc32..59a2bae0f35e 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -479,7 +479,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, int i, nbio = 0; int operation; struct blk_plug plug; - struct request_queue *q; switch (req->operation) { case BLKIF_OP_READ: @@ -542,9 +541,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, goto fail_response; } } - q = bdev_get_queue(preq.bdev); - if (!q) - goto fail_response; /* If we have failed at this point, we need to undo the M2P override, * set gnttab_set_unmap_op on all of the grant references and perform * the hypercall to unmap the grants - that is all done in @@ -596,7 +592,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, atomic_set(&pending_req->pendcnt, nbio); /* Get a reference count for the disk queue and start sending I/O */ - blk_get_queue(q); blk_start_plug(&plug); for (i = 0; i < nbio; i++) @@ -604,7 +599,6 @@ static void dispatch_rw_block_io(struct blkif_st *blkif, blk_finish_plug(&plug); /* Let the I/Os go.. */ - blk_put_queue(q); if (operation == READ) blkif->st_rd_sect += preq.nr_sects; -- GitLab From dfc07b13dcacefda6ebdea14584ed8724dc980ef Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 18 Apr 2011 14:24:23 -0400 Subject: [PATCH 1150/5560] xen/blkback: Move it from drivers/xen to drivers/block .. and modify the Makefile and Kconfig files appropriately. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/Kconfig | 8 ++++++++ drivers/block/Makefile | 1 + drivers/{xen/blkback => block/xen-blkback}/Makefile | 0 drivers/{xen/blkback => block/xen-blkback}/blkback.c | 0 drivers/{xen/blkback => block/xen-blkback}/common.h | 0 drivers/{xen/blkback => block/xen-blkback}/interface.c | 0 drivers/{xen/blkback => block/xen-blkback}/vbd.c | 0 drivers/{xen/blkback => block/xen-blkback}/xenbus.c | 0 drivers/xen/Kconfig | 8 -------- drivers/xen/Makefile | 1 - 10 files changed, 9 insertions(+), 9 deletions(-) rename drivers/{xen/blkback => block/xen-blkback}/Makefile (100%) rename drivers/{xen/blkback => block/xen-blkback}/blkback.c (100%) rename drivers/{xen/blkback => block/xen-blkback}/common.h (100%) rename drivers/{xen/blkback => block/xen-blkback}/interface.c (100%) rename drivers/{xen/blkback => block/xen-blkback}/vbd.c (100%) rename drivers/{xen/blkback => block/xen-blkback}/xenbus.c (100%) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 83c32cb72582..9abb64689712 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -470,6 +470,14 @@ config XEN_BLKDEV_FRONTEND block device driver. It communicates with a back-end driver in another domain which drives the actual block device. +config XEN_BLKDEV_BACKEND + tristate "Block-device backend driver" + depends on XEN_BACKEND + help + The block-device backend driver allows the kernel to export its + block devices to other guests via a high-performance shared-memory + interface. + config VIRTIO_BLK tristate "Virtio block driver (EXPERIMENTAL)" depends on EXPERIMENTAL && VIRTIO diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 40528ba56d1b..76646e9a1c91 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_BLK_DEV_UB) += ub.o obj-$(CONFIG_BLK_DEV_HD) += hd.o obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o +obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/ obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ obj-$(CONFIG_BLK_DEV_RBD) += rbd.o diff --git a/drivers/xen/blkback/Makefile b/drivers/block/xen-blkback/Makefile similarity index 100% rename from drivers/xen/blkback/Makefile rename to drivers/block/xen-blkback/Makefile diff --git a/drivers/xen/blkback/blkback.c b/drivers/block/xen-blkback/blkback.c similarity index 100% rename from drivers/xen/blkback/blkback.c rename to drivers/block/xen-blkback/blkback.c diff --git a/drivers/xen/blkback/common.h b/drivers/block/xen-blkback/common.h similarity index 100% rename from drivers/xen/blkback/common.h rename to drivers/block/xen-blkback/common.h diff --git a/drivers/xen/blkback/interface.c b/drivers/block/xen-blkback/interface.c similarity index 100% rename from drivers/xen/blkback/interface.c rename to drivers/block/xen-blkback/interface.c diff --git a/drivers/xen/blkback/vbd.c b/drivers/block/xen-blkback/vbd.c similarity index 100% rename from drivers/xen/blkback/vbd.c rename to drivers/block/xen-blkback/vbd.c diff --git a/drivers/xen/blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c similarity index 100% rename from drivers/xen/blkback/xenbus.c rename to drivers/block/xen-blkback/xenbus.c diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index fb1af628cbfc..a59638b37c1a 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -37,14 +37,6 @@ config XEN_BACKEND Support for backend device drivers that provide I/O services to other virtual machines. -config XEN_BLKDEV_BACKEND - tristate "Block-device backend driver" - depends on XEN_BACKEND && BLOCK - help - The block-device backend driver allows the kernel to export its - block devices to other guests via a high-performance shared-memory - interface. - config XENFS tristate "Xen filesystem" default y diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 29c0a416f082..f420f1ff7f13 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_XEN_BALLOON) += xen-balloon.o obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o obj-$(CONFIG_XEN_GNTDEV) += xen-gntdev.o obj-$(CONFIG_XEN_GRANT_DEV_ALLOC) += xen-gntalloc.o -obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/ obj-$(CONFIG_XENFS) += xenfs/ obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o obj-$(CONFIG_XEN_PLATFORM_PCI) += xen-platform-pci.o -- GitLab From dc0a50afa67c3dbd51211881b7568917dbbc6861 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:40:36 -0600 Subject: [PATCH 1151/5560] ASoC: Tegra: Rename harmony.c to tegra_wm8903.c Soon, this machine driver will be updated to handle a number of Tegra boards using the WM8903 codec. Rename the file in advance to reflect this. Fix the content of tegra_wm8903.c to match the rename; replace references to Harmony board with something more generic. * s/struct tegra_harmony/struct tegra_wm8903/ * s/harmony/machine/ # variable name * Similar rename for some functions * Similar comment fix * Similar MODULE_DESCRIPTION fix Signed-off-by: Stephen Warren Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/tegra/Kconfig | 9 +- sound/soc/tegra/Makefile | 4 +- sound/soc/tegra/{harmony.c => tegra_wm8903.c} | 157 +++++++++--------- 3 files changed, 86 insertions(+), 84 deletions(-) rename sound/soc/tegra/{harmony.c => tegra_wm8903.c} (63%) diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 66b504f06c23..9e53fec52d60 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -14,13 +14,14 @@ config SND_TEGRA_SOC_I2S Tegra I2S interface. You will also need to select the individual machine drivers to support below. -config SND_TEGRA_SOC_HARMONY - tristate "SoC Audio support for Tegra Harmony reference board" +config SND_TEGRA_SOC_WM8903 + tristate "SoC Audio support for Tegra boards using a WM8903 codec" depends on SND_TEGRA_SOC && MACH_HARMONY && I2C default m select SND_TEGRA_SOC_I2S select SND_SOC_WM8903 help - Say Y or M here if you want to add support for SoC audio on the - Tegra Harmony reference board. + Say Y or M here if you want to add support for SoC audio on Tegra + boards using the WM8093 codec. Currently, the only supported board + is Harmony. diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index fd183d3ab4f1..c9f7ea430376 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -10,6 +10,6 @@ obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o # Tegra machine Support -snd-soc-tegra-harmony-objs := harmony.o +snd-soc-tegra-wm8903-objs := tegra_wm8903.o -obj-$(CONFIG_SND_TEGRA_SOC_HARMONY) += snd-soc-tegra-harmony.o +obj-$(CONFIG_SND_TEGRA_SOC_WM8903) += snd-soc-tegra-wm8903.o diff --git a/sound/soc/tegra/harmony.c b/sound/soc/tegra/tegra_wm8903.c similarity index 63% rename from sound/soc/tegra/harmony.c rename to sound/soc/tegra/tegra_wm8903.c index 6bd1e42d5381..0e31925b9d56 100644 --- a/sound/soc/tegra/harmony.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -1,5 +1,5 @@ /* - * harmony.c - Harmony machine ASoC driver + * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec. * * Author: Stephen Warren * Copyright (C) 2010-2011 - NVIDIA, Inc. @@ -56,13 +56,13 @@ #define GPIO_INT_MIC_EN BIT(1) #define GPIO_EXT_MIC_EN BIT(2) -struct tegra_harmony { +struct tegra_wm8903 { struct tegra_asoc_utils_data util_data; struct tegra_wm8903_platform_data *pdata; int gpio_requested; }; -static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, +static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -70,7 +70,7 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; - struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, mclk_change; int err; @@ -89,7 +89,7 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, while (mclk < 6000000) mclk *= 2; - err = tegra_asoc_utils_set_rate(&harmony->util_data, srate, mclk, + err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk, &mclk_change); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); @@ -126,20 +126,20 @@ static int harmony_asoc_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops harmony_asoc_ops = { - .hw_params = harmony_asoc_hw_params, +static struct snd_soc_ops tegra_wm8903_ops = { + .hw_params = tegra_wm8903_hw_params, }; -static struct snd_soc_jack harmony_hp_jack; +static struct snd_soc_jack tegra_wm8903_hp_jack; -static struct snd_soc_jack_pin harmony_hp_jack_pins[] = { +static struct snd_soc_jack_pin tegra_wm8903_hp_jack_pins[] = { { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE, }, }; -static struct snd_soc_jack_gpio harmony_hp_jack_gpios[] = { +static struct snd_soc_jack_gpio tegra_wm8903_hp_jack_gpios[] = { { .name = "headphone detect", .report = SND_JACK_HEADPHONE, @@ -148,22 +148,22 @@ static struct snd_soc_jack_gpio harmony_hp_jack_gpios[] = { } }; -static struct snd_soc_jack harmony_mic_jack; +static struct snd_soc_jack tegra_wm8903_mic_jack; -static struct snd_soc_jack_pin harmony_mic_jack_pins[] = { +static struct snd_soc_jack_pin tegra_wm8903_mic_jack_pins[] = { { .pin = "Mic Jack", .mask = SND_JACK_MICROPHONE, }, }; -static int harmony_event_int_spk(struct snd_soc_dapm_widget *w, +static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { struct snd_soc_codec *codec = w->codec; struct snd_soc_card *card = codec->card; - struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = harmony->pdata; + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); + struct tegra_wm8903_platform_data *pdata = machine->pdata; gpio_set_value_cansleep(pdata->gpio_spkr_en, SND_SOC_DAPM_EVENT_ON(event)); @@ -171,8 +171,8 @@ static int harmony_event_int_spk(struct snd_soc_dapm_widget *w, return 0; } -static const struct snd_soc_dapm_widget harmony_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Int Spk", harmony_event_int_spk), +static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Int Spk", tegra_wm8903_event_int_spk), SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Mic Jack", NULL), }; @@ -188,17 +188,17 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = { {"IN1L", NULL, "Mic Bias"}, }; -static const struct snd_kcontrol_new harmony_controls[] = { +static const struct snd_kcontrol_new tegra_wm8903_controls[] = { SOC_DAPM_PIN_SWITCH("Int Spk"), }; -static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) +static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; - struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = harmony->pdata; + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); + struct tegra_wm8903_platform_data *pdata = machine->pdata; int ret; ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); @@ -206,7 +206,7 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } - harmony->gpio_requested |= GPIO_SPKR_EN; + machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); @@ -215,7 +215,7 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } - harmony->gpio_requested |= GPIO_INT_MIC_EN; + machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); @@ -225,38 +225,39 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } - harmony->gpio_requested |= GPIO_EXT_MIC_EN; + machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); - ret = snd_soc_add_controls(codec, harmony_controls, - ARRAY_SIZE(harmony_controls)); + ret = snd_soc_add_controls(codec, tegra_wm8903_controls, + ARRAY_SIZE(tegra_wm8903_controls)); if (ret < 0) return ret; - snd_soc_dapm_new_controls(dapm, harmony_dapm_widgets, - ARRAY_SIZE(harmony_dapm_widgets)); + snd_soc_dapm_new_controls(dapm, tegra_wm8903_dapm_widgets, + ARRAY_SIZE(tegra_wm8903_dapm_widgets)); snd_soc_dapm_add_routes(dapm, harmony_audio_map, ARRAY_SIZE(harmony_audio_map)); - harmony_hp_jack_gpios[0].gpio = pdata->gpio_hp_det; + tegra_wm8903_hp_jack_gpios[0].gpio = pdata->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &harmony_hp_jack); - snd_soc_jack_add_pins(&harmony_hp_jack, - ARRAY_SIZE(harmony_hp_jack_pins), - harmony_hp_jack_pins); - snd_soc_jack_add_gpios(&harmony_hp_jack, - ARRAY_SIZE(harmony_hp_jack_gpios), - harmony_hp_jack_gpios); + &tegra_wm8903_hp_jack); + snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, + ARRAY_SIZE(tegra_wm8903_hp_jack_pins), + tegra_wm8903_hp_jack_pins); + snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, + ARRAY_SIZE(tegra_wm8903_hp_jack_gpios), + tegra_wm8903_hp_jack_gpios); snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, - &harmony_mic_jack); - snd_soc_jack_add_pins(&harmony_mic_jack, - ARRAY_SIZE(harmony_mic_jack_pins), - harmony_mic_jack_pins); - wm8903_mic_detect(codec, &harmony_mic_jack, SND_JACK_MICROPHONE, 0); + &tegra_wm8903_mic_jack); + snd_soc_jack_add_pins(&tegra_wm8903_mic_jack, + ARRAY_SIZE(tegra_wm8903_mic_jack_pins), + tegra_wm8903_mic_jack_pins); + wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, + 0); snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); @@ -270,27 +271,27 @@ static int harmony_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_dai_link harmony_wm8903_dai = { +static struct snd_soc_dai_link tegra_wm8903_dai = { .name = "WM8903", .stream_name = "WM8903 PCM", .codec_name = "wm8903.0-001a", .platform_name = "tegra-pcm-audio", .cpu_dai_name = "tegra-i2s.0", .codec_dai_name = "wm8903-hifi", - .init = harmony_asoc_init, - .ops = &harmony_asoc_ops, + .init = tegra_wm8903_init, + .ops = &tegra_wm8903_ops, }; -static struct snd_soc_card snd_soc_harmony = { - .name = "tegra-harmony", - .dai_link = &harmony_wm8903_dai, +static struct snd_soc_card snd_soc_tegra_wm8903 = { + .name = "tegra-wm8903", + .dai_link = &tegra_wm8903_dai, .num_links = 1, }; -static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev) +static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) { - struct snd_soc_card *card = &snd_soc_harmony; - struct tegra_harmony *harmony; + struct snd_soc_card *card = &snd_soc_tegra_wm8903; + struct tegra_wm8903 *machine; struct tegra_wm8903_platform_data *pdata; int ret; @@ -305,21 +306,21 @@ static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev) return -EINVAL; } - harmony = kzalloc(sizeof(struct tegra_harmony), GFP_KERNEL); - if (!harmony) { - dev_err(&pdev->dev, "Can't allocate tegra_harmony\n"); + machine = kzalloc(sizeof(struct tegra_wm8903), GFP_KERNEL); + if (!machine) { + dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); return -ENOMEM; } - harmony->pdata = pdata; + machine->pdata = pdata; - ret = tegra_asoc_utils_init(&harmony->util_data, &pdev->dev); + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) - goto err_free_harmony; + goto err_free_machine; card->dev = &pdev->dev; platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, harmony); + snd_soc_card_set_drvdata(card, machine); ret = snd_soc_register_card(card); if (ret) { @@ -334,17 +335,17 @@ static __devinit int tegra_snd_harmony_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(card, NULL); platform_set_drvdata(pdev, NULL); card->dev = NULL; - tegra_asoc_utils_fini(&harmony->util_data); -err_free_harmony: - kfree(harmony); + tegra_asoc_utils_fini(&machine->util_data); +err_free_machine: + kfree(machine); return ret; } -static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev) +static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct tegra_harmony *harmony = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = harmony->pdata; + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); + struct tegra_wm8903_platform_data *pdata = machine->pdata; snd_soc_unregister_card(card); @@ -352,43 +353,43 @@ static int __devexit tegra_snd_harmony_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); card->dev = NULL; - tegra_asoc_utils_fini(&harmony->util_data); + tegra_asoc_utils_fini(&machine->util_data); - if (harmony->gpio_requested & GPIO_EXT_MIC_EN) + if (machine->gpio_requested & GPIO_EXT_MIC_EN) gpio_free(pdata->gpio_ext_mic_en); - if (harmony->gpio_requested & GPIO_INT_MIC_EN) + if (machine->gpio_requested & GPIO_INT_MIC_EN) gpio_free(pdata->gpio_int_mic_en); - if (harmony->gpio_requested & GPIO_SPKR_EN) + if (machine->gpio_requested & GPIO_SPKR_EN) gpio_free(pdata->gpio_spkr_en); - kfree(harmony); + kfree(machine); return 0; } -static struct platform_driver tegra_snd_harmony_driver = { +static struct platform_driver tegra_wm8903_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, - .probe = tegra_snd_harmony_probe, - .remove = __devexit_p(tegra_snd_harmony_remove), + .probe = tegra_wm8903_driver_probe, + .remove = __devexit_p(tegra_wm8903_driver_remove), }; -static int __init snd_tegra_harmony_init(void) +static int __init tegra_wm8903_modinit(void) { - return platform_driver_register(&tegra_snd_harmony_driver); + return platform_driver_register(&tegra_wm8903_driver); } -module_init(snd_tegra_harmony_init); +module_init(tegra_wm8903_modinit); -static void __exit snd_tegra_harmony_exit(void) +static void __exit tegra_wm8903_modexit(void) { - platform_driver_unregister(&tegra_snd_harmony_driver); + platform_driver_unregister(&tegra_wm8903_driver); } -module_exit(snd_tegra_harmony_exit); +module_exit(tegra_wm8903_modexit); MODULE_AUTHOR("Stephen Warren "); -MODULE_DESCRIPTION("Harmony machine ASoC driver"); +MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); -- GitLab From 2ba9471b34f48eab9f6e097ef305746b33e12f85 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:40:37 -0600 Subject: [PATCH 1152/5560] ASoC: Tegra: Rename Kconfig SND_TEGRA_SOC_* to SND_SOC_TEGRA_* The previous commit renames SND_TEGRA_SOC_HARMONY to SND_TEGRA_SOC_WM8903. While we're breaking people's .config files, rename all Tegra/SOC-related Kconfig variables to be more consistent with at least the core codec variables. Note that there exist machines that name their variables both ways. Signed-off-by: Stephen Warren Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/tegra/Kconfig | 12 ++++++------ sound/soc/tegra/Makefile | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 9e53fec52d60..21125b302630 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -1,24 +1,24 @@ -config SND_TEGRA_SOC +config SND_SOC_TEGRA tristate "SoC Audio for the Tegra System-on-Chip" depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA default m help Say Y or M here if you want support for SoC audio on Tegra. -config SND_TEGRA_SOC_I2S +config SND_SOC_TEGRA_I2S tristate - depends on SND_TEGRA_SOC + depends on SND_SOC_TEGRA default m help Say Y or M if you want to add support for codecs attached to the Tegra I2S interface. You will also need to select the individual machine drivers to support below. -config SND_TEGRA_SOC_WM8903 +config SND_SOC_TEGRA_WM8903 tristate "SoC Audio support for Tegra boards using a WM8903 codec" - depends on SND_TEGRA_SOC && MACH_HARMONY && I2C + depends on SND_SOC_TEGRA && MACH_HARMONY && I2C default m - select SND_TEGRA_SOC_I2S + select SND_SOC_TEGRA_I2S select SND_SOC_WM8903 help Say Y or M here if you want to add support for SoC audio on Tegra diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index c9f7ea430376..13bef8d572c9 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -4,12 +4,12 @@ snd-soc-tegra-pcm-objs := tegra_pcm.o snd-soc-tegra-i2s-objs := tegra_i2s.o snd-soc-tegra-utils-objs += tegra_asoc_utils.o -obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-utils.o -obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-das.o -obj-$(CONFIG_SND_TEGRA_SOC) += snd-soc-tegra-pcm.o -obj-$(CONFIG_SND_TEGRA_SOC_I2S) += snd-soc-tegra-i2s.o +obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o +obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o +obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o +obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o # Tegra machine Support snd-soc-tegra-wm8903-objs := tegra_wm8903.o -obj-$(CONFIG_SND_TEGRA_SOC_WM8903) += snd-soc-tegra-wm8903.o +obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o -- GitLab From 3eb25f998d3aede5f0011ba236e7586351e450bf Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:40:38 -0600 Subject: [PATCH 1153/5560] ASoC: Tegra: Don't store snd_soc_jack_gpio in an array Storing the struct in an array makes the assignments to the GPIO member a little non-obvious, and is pointless when there's only a single GPIO. (I thought I fixed this during the review cycle when first submitting this driver, but I guess I overlooked that) Signed-off-by: Stephen Warren Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0e31925b9d56..2b3844322c40 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -139,13 +139,11 @@ static struct snd_soc_jack_pin tegra_wm8903_hp_jack_pins[] = { }, }; -static struct snd_soc_jack_gpio tegra_wm8903_hp_jack_gpios[] = { - { - .name = "headphone detect", - .report = SND_JACK_HEADPHONE, - .debounce_time = 150, - .invert = 1, - } +static struct snd_soc_jack_gpio tegra_wm8903_hp_jack_gpio = { + .name = "headphone detect", + .report = SND_JACK_HEADPHONE, + .debounce_time = 150, + .invert = 1, }; static struct snd_soc_jack tegra_wm8903_mic_jack; @@ -241,15 +239,15 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_add_routes(dapm, harmony_audio_map, ARRAY_SIZE(harmony_audio_map)); - tegra_wm8903_hp_jack_gpios[0].gpio = pdata->gpio_hp_det; + tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack); snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, ARRAY_SIZE(tegra_wm8903_hp_jack_pins), tegra_wm8903_hp_jack_pins); snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, - ARRAY_SIZE(tegra_wm8903_hp_jack_gpios), - tegra_wm8903_hp_jack_gpios); + 1, + &tegra_wm8903_hp_jack_gpio); snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, &tegra_wm8903_mic_jack); -- GitLab From 773b1d3d31bbf7257c48f6257b4ab06bcf4f5dfa Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 12 Apr 2011 11:40:39 -0600 Subject: [PATCH 1154/5560] ASoC: Tegra: Support more boards * Ventana is identical to Harmony. * Seaboard, Kaen, and Aebl are all pretty similar, mainly with slightly different sets of GPIOs, and slightly different WM8903 pin connectivity. Signed-off-by: Stephen Warren Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/tegra/Kconfig | 7 +- sound/soc/tegra/tegra_wm8903.c | 180 ++++++++++++++++++++++++++------- 2 files changed, 145 insertions(+), 42 deletions(-) diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 21125b302630..14f711977ae3 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -16,12 +16,13 @@ config SND_SOC_TEGRA_I2S config SND_SOC_TEGRA_WM8903 tristate "SoC Audio support for Tegra boards using a WM8903 codec" - depends on SND_SOC_TEGRA && MACH_HARMONY && I2C + depends on SND_SOC_TEGRA && I2C + depends on MACH_HARMONY || MACH_VENTANA || MACH_SEABOARD || MACH_KAEN || MACH_AEBL default m select SND_SOC_TEGRA_I2S select SND_SOC_WM8903 help Say Y or M here if you want to add support for SoC audio on Tegra - boards using the WM8093 codec. Currently, the only supported board - is Harmony. + boards using the WM8093 codec. Currently, the supported boards are + Harmony, Ventana, Seaboard, Kaen, and Aebl. diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 2b3844322c40..37f6010a9109 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -53,8 +53,9 @@ #define DRV_NAME "tegra-snd-wm8903" #define GPIO_SPKR_EN BIT(0) -#define GPIO_INT_MIC_EN BIT(1) -#define GPIO_EXT_MIC_EN BIT(2) +#define GPIO_HP_MUTE BIT(1) +#define GPIO_INT_MIC_EN BIT(2) +#define GPIO_EXT_MIC_EN BIT(3) struct tegra_wm8903 { struct tegra_asoc_utils_data util_data; @@ -163,15 +164,35 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = machine->pdata; + if (!(machine->gpio_requested & GPIO_SPKR_EN)) + return 0; + gpio_set_value_cansleep(pdata->gpio_spkr_en, SND_SOC_DAPM_EVENT_ON(event)); return 0; } +static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct snd_soc_card *card = codec->card; + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); + struct tegra_wm8903_platform_data *pdata = machine->pdata; + + if (!(machine->gpio_requested & GPIO_HP_MUTE)) + return 0; + + gpio_set_value_cansleep(pdata->gpio_hp_mute, + !SND_SOC_DAPM_EVENT_ON(event)); + + return 0; +} + static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { SND_SOC_DAPM_SPK("Int Spk", tegra_wm8903_event_int_spk), - SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_HP("Headphone Jack", tegra_wm8903_event_hp), SND_SOC_DAPM_MIC("Mic Jack", NULL), }; @@ -186,6 +207,37 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = { {"IN1L", NULL, "Mic Bias"}, }; +static const struct snd_soc_dapm_route seaboard_audio_map[] = { + {"Headphone Jack", NULL, "HPOUTR"}, + {"Headphone Jack", NULL, "HPOUTL"}, + {"Int Spk", NULL, "ROP"}, + {"Int Spk", NULL, "RON"}, + {"Int Spk", NULL, "LOP"}, + {"Int Spk", NULL, "LON"}, + {"Mic Bias", NULL, "Mic Jack"}, + {"IN1R", NULL, "Mic Bias"}, +}; + +static const struct snd_soc_dapm_route kaen_audio_map[] = { + {"Headphone Jack", NULL, "HPOUTR"}, + {"Headphone Jack", NULL, "HPOUTL"}, + {"Int Spk", NULL, "ROP"}, + {"Int Spk", NULL, "RON"}, + {"Int Spk", NULL, "LOP"}, + {"Int Spk", NULL, "LON"}, + {"Mic Bias", NULL, "Mic Jack"}, + {"IN2R", NULL, "Mic Bias"}, +}; + +static const struct snd_soc_dapm_route aebl_audio_map[] = { + {"Headphone Jack", NULL, "HPOUTR"}, + {"Headphone Jack", NULL, "HPOUTL"}, + {"Int Spk", NULL, "LINEOUTR"}, + {"Int Spk", NULL, "LINEOUTL"}, + {"Mic Bias", NULL, "Mic Jack"}, + {"IN1R", NULL, "Mic Bias"}, +}; + static const struct snd_kcontrol_new tegra_wm8903_controls[] = { SOC_DAPM_PIN_SWITCH("Int Spk"), }; @@ -199,34 +251,51 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) struct tegra_wm8903_platform_data *pdata = machine->pdata; int ret; - ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); - if (ret) { - dev_err(card->dev, "cannot get spkr_en gpio\n"); - return ret; + if (gpio_is_valid(pdata->gpio_spkr_en)) { + ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); + if (ret) { + dev_err(card->dev, "cannot get spkr_en gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_SPKR_EN; + + gpio_direction_output(pdata->gpio_spkr_en, 0); } - machine->gpio_requested |= GPIO_SPKR_EN; - gpio_direction_output(pdata->gpio_spkr_en, 0); + if (gpio_is_valid(pdata->gpio_hp_mute)) { + ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); + if (ret) { + dev_err(card->dev, "cannot get hp_mute gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_HP_MUTE; - ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); - if (ret) { - dev_err(card->dev, "cannot get int_mic_en gpio\n"); - return ret; + gpio_direction_output(pdata->gpio_hp_mute, 0); } - machine->gpio_requested |= GPIO_INT_MIC_EN; - /* Disable int mic; enable signal is active-high */ - gpio_direction_output(pdata->gpio_int_mic_en, 0); + if (gpio_is_valid(pdata->gpio_int_mic_en)) { + ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); + if (ret) { + dev_err(card->dev, "cannot get int_mic_en gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_INT_MIC_EN; - ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); - if (ret) { - dev_err(card->dev, "cannot get ext_mic_en gpio\n"); - return ret; + /* Disable int mic; enable signal is active-high */ + gpio_direction_output(pdata->gpio_int_mic_en, 0); } - machine->gpio_requested |= GPIO_EXT_MIC_EN; - /* Enable ext mic; enable signal is active-low */ - gpio_direction_output(pdata->gpio_ext_mic_en, 0); + if (gpio_is_valid(pdata->gpio_ext_mic_en)) { + ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); + if (ret) { + dev_err(card->dev, "cannot get ext_mic_en gpio\n"); + return ret; + } + machine->gpio_requested |= GPIO_EXT_MIC_EN; + + /* Enable ext mic; enable signal is active-low */ + gpio_direction_output(pdata->gpio_ext_mic_en, 0); + } ret = snd_soc_add_controls(codec, tegra_wm8903_controls, ARRAY_SIZE(tegra_wm8903_controls)); @@ -236,18 +305,31 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_new_controls(dapm, tegra_wm8903_dapm_widgets, ARRAY_SIZE(tegra_wm8903_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, harmony_audio_map, - ARRAY_SIZE(harmony_audio_map)); + if (machine_is_harmony() || machine_is_ventana()) { + snd_soc_dapm_add_routes(dapm, harmony_audio_map, + ARRAY_SIZE(harmony_audio_map)); + } else if (machine_is_seaboard()) { + snd_soc_dapm_add_routes(dapm, seaboard_audio_map, + ARRAY_SIZE(seaboard_audio_map)); + } else if (machine_is_kaen()) { + snd_soc_dapm_add_routes(dapm, kaen_audio_map, + ARRAY_SIZE(kaen_audio_map)); + } else { + snd_soc_dapm_add_routes(dapm, aebl_audio_map, + ARRAY_SIZE(aebl_audio_map)); + } - tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &tegra_wm8903_hp_jack); - snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, - ARRAY_SIZE(tegra_wm8903_hp_jack_pins), - tegra_wm8903_hp_jack_pins); - snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, - 1, - &tegra_wm8903_hp_jack_gpio); + if (gpio_is_valid(pdata->gpio_hp_det)) { + tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, + &tegra_wm8903_hp_jack); + snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, + ARRAY_SIZE(tegra_wm8903_hp_jack_pins), + tegra_wm8903_hp_jack_pins); + snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, + 1, + &tegra_wm8903_hp_jack_gpio); + } snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, &tegra_wm8903_mic_jack); @@ -259,10 +341,26 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); + /* FIXME: Calculate automatically based on DAPM routes? */ + if (!machine_is_harmony() && !machine_is_ventana()) + snd_soc_dapm_nc_pin(dapm, "IN1L"); + if (!machine_is_seaboard() && !machine_is_aebl()) + snd_soc_dapm_nc_pin(dapm, "IN1R"); + snd_soc_dapm_nc_pin(dapm, "IN2L"); + if (!machine_is_kaen()) + snd_soc_dapm_nc_pin(dapm, "IN2R"); snd_soc_dapm_nc_pin(dapm, "IN3L"); snd_soc_dapm_nc_pin(dapm, "IN3R"); - snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); - snd_soc_dapm_nc_pin(dapm, "LINEOUTR"); + + if (machine_is_aebl()) { + snd_soc_dapm_nc_pin(dapm, "LON"); + snd_soc_dapm_nc_pin(dapm, "RON"); + snd_soc_dapm_nc_pin(dapm, "ROP"); + snd_soc_dapm_nc_pin(dapm, "LOP"); + } else { + snd_soc_dapm_nc_pin(dapm, "LINEOUTR"); + snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); + } snd_soc_dapm_sync(dapm); @@ -293,14 +391,16 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) struct tegra_wm8903_platform_data *pdata; int ret; - if (!machine_is_harmony()) { - dev_err(&pdev->dev, "Not running on Tegra Harmony!\n"); + if (!machine_is_harmony() && !machine_is_ventana() && + !machine_is_seaboard() && !machine_is_kaen() && + !machine_is_aebl()) { + dev_err(&pdev->dev, "Not running on a supported board!\n"); return -ENODEV; } pdata = pdev->dev.platform_data; if (!pdata) { - dev_err(&pdev->dev, "no platform data supplied\n"); + dev_err(&pdev->dev, "No platform data supplied\n"); return -EINVAL; } @@ -357,6 +457,8 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) gpio_free(pdata->gpio_ext_mic_en); if (machine->gpio_requested & GPIO_INT_MIC_EN) gpio_free(pdata->gpio_int_mic_en); + if (machine->gpio_requested & GPIO_HP_MUTE) + gpio_free(pdata->gpio_hp_mute); if (machine->gpio_requested & GPIO_SPKR_EN) gpio_free(pdata->gpio_spkr_en); -- GitLab From 56d37f17165084e10f425e66f0bd964f06e8bd23 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 18 Apr 2011 01:04:37 +0000 Subject: [PATCH 1155/5560] net: dm9000: Fix build Commit c88fcb (net: dm9000: convert to hw_features) broke the build of the dm9000 driver since it merged functions which use different names for the board info structure used for I/O operations without updating all the references to use the same name. Fix that. Signed-off-by: Mark Brown Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index f7bdebbcb908..fbaff3584bd4 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -768,7 +768,7 @@ dm9000_init_dm9000(struct net_device *dev) /* Checksum mode */ if (dev->hw_features & NETIF_F_RXCSUM) - iow(dm, DM9000_RCSR, + iow(db, DM9000_RCSR, (dev->features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0); iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ -- GitLab From 2a086e5d3a23570735f75b784d29b93068070833 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 3 Apr 2011 00:09:26 +0900 Subject: [PATCH 1156/5560] TOMOYO: Fix race on updating profile's comment line. In tomoyo_write_profile() since 2.6.34, a lock was by error missing when replacing profile's comment line. If multiple threads attempted echo '0-COMMENT=comment' > /sys/kernel/security/tomoyo/profile in parallel, garbage collector will fail to kfree() the old value. Protect the replacement using a lock. Also, keep the old value rather than replace with empty string when out of memory error has occurred. Signed-off-by: Xiaochen Wang Signed-off-by: Tetsuo Handa Signed-off-by: James Morris --- security/tomoyo/common.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 7556315c1978..2b7b1a123600 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -459,8 +459,16 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head) if (profile == &tomoyo_default_profile) return -EINVAL; if (!strcmp(data, "COMMENT")) { - const struct tomoyo_path_info *old_comment = profile->comment; - profile->comment = tomoyo_get_name(cp); + static DEFINE_SPINLOCK(lock); + const struct tomoyo_path_info *new_comment + = tomoyo_get_name(cp); + const struct tomoyo_path_info *old_comment; + if (!new_comment) + return -ENOMEM; + spin_lock(&lock); + old_comment = profile->comment; + profile->comment = new_comment; + spin_unlock(&lock); tomoyo_put_name(old_comment); return 0; } -- GitLab From e4f5f26d8336318a5aa0858223c81cf29fcf5f68 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 3 Apr 2011 00:11:50 +0900 Subject: [PATCH 1157/5560] TOMOYO: Don't add / for allow_unmount permission check. "mount --bind /path/to/file1 /path/to/file2" is legal. Therefore, "umount /path/to/file2" is also legal. Do not automatically append trailing '/' if pathname to be unmounted does not end with '/'. Signed-off-by: Tetsuo Handa Signed-off-by: James Morris --- security/tomoyo/file.c | 1 - 1 file changed, 1 deletion(-) diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index cb09f1fce910..d64e8ecb6fb3 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c @@ -1011,7 +1011,6 @@ int tomoyo_path_perm(const u8 operation, struct path *path) break; case TOMOYO_TYPE_RMDIR: case TOMOYO_TYPE_CHROOT: - case TOMOYO_TYPE_UMOUNT: tomoyo_add_slash(&buf); break; } -- GitLab From c0fa797ae6cd02ff87c0bfe0d509368a3b45640e Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 3 Apr 2011 00:12:54 +0900 Subject: [PATCH 1158/5560] TOMOYO: Fix infinite loop bug when reading /sys/kernel/security/tomoyo/audit In tomoyo_flush(), head->r.w[0] holds pointer to string data to be printed. But head->r.w[0] was updated only when the string data was partially printed (because head->r.w[0] will be updated by head->r.w[1] later if completely printed). However, regarding /sys/kernel/security/tomoyo/query , an additional '\0' is printed after the string data was completely printed. But if free space for read buffer became 0 before printing the additional '\0', tomoyo_flush() was returning without updating head->r.w[0]. As a result, tomoyo_flush() forever reprints already printed string data. Signed-off-by: Tetsuo Handa Signed-off-by: James Morris --- security/tomoyo/common.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 2b7b1a123600..a0d09e56874b 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -108,10 +108,9 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head) head->read_user_buf += len; w += len; } - if (*w) { - head->r.w[0] = w; + head->r.w[0] = w; + if (*w) return false; - } /* Add '\0' for query. */ if (head->poll) { if (!head->read_user_buf_avail || -- GitLab From 47c2cdf5513e86e43c799da8d5406cc9a2bf3626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:50 +0000 Subject: [PATCH 1159/5560] net: myri10ge: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Mirosław Acked-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 66 ++++++--------------------------- 1 file changed, 12 insertions(+), 54 deletions(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 1446de59ae53..e7f801643c12 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -205,7 +205,6 @@ struct myri10ge_priv { int tx_boundary; /* boundary transmits cannot cross */ int num_slices; int running; /* running? */ - int csum_flag; /* rx_csums? */ int small_bytes; int big_bytes; int max_intr_slots; @@ -1386,7 +1385,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, ss - &mgp->ss[0]); - if (mgp->csum_flag) { + if (dev->features & NETIF_F_RXCSUM) { if ((skb->protocol == htons(ETH_P_IP)) || (skb->protocol == htons(ETH_P_IPV6))) { skb->csum = csum; @@ -1757,43 +1756,6 @@ myri10ge_get_ringparam(struct net_device *netdev, ring->tx_pending = ring->tx_max_pending; } -static u32 myri10ge_get_rx_csum(struct net_device *netdev) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - - if (mgp->csum_flag) - return 1; - else - return 0; -} - -static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - int err = 0; - - if (csum_enabled) - mgp->csum_flag = MXGEFW_FLAGS_CKSUM; - else { - netdev->features &= ~NETIF_F_LRO; - mgp->csum_flag = 0; - - } - return err; -} - -static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - u32 flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO); - - if (tso_enabled) - netdev->features |= flags; - else - netdev->features &= ~flags; - return 0; -} - static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", @@ -1944,11 +1906,6 @@ static u32 myri10ge_get_msglevel(struct net_device *netdev) return mgp->msg_enable; } -static int myri10ge_set_flags(struct net_device *netdev, u32 value) -{ - return ethtool_op_set_flags(netdev, value, ETH_FLAG_LRO); -} - static const struct ethtool_ops myri10ge_ethtool_ops = { .get_settings = myri10ge_get_settings, .get_drvinfo = myri10ge_get_drvinfo, @@ -1957,19 +1914,12 @@ static const struct ethtool_ops myri10ge_ethtool_ops = { .get_pauseparam = myri10ge_get_pauseparam, .set_pauseparam = myri10ge_set_pauseparam, .get_ringparam = myri10ge_get_ringparam, - .get_rx_csum = myri10ge_get_rx_csum, - .set_rx_csum = myri10ge_set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .set_sg = ethtool_op_set_sg, - .set_tso = myri10ge_set_tso, .get_link = ethtool_op_get_link, .get_strings = myri10ge_get_strings, .get_sset_count = myri10ge_get_sset_count, .get_ethtool_stats = myri10ge_get_ethtool_stats, .set_msglevel = myri10ge_set_msglevel, .get_msglevel = myri10ge_get_msglevel, - .get_flags = ethtool_op_get_flags, - .set_flags = myri10ge_set_flags }; static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss) @@ -3136,6 +3086,14 @@ static int myri10ge_set_mac_address(struct net_device *dev, void *addr) return 0; } +static u32 myri10ge_fix_features(struct net_device *dev, u32 features) +{ + if (!(features & NETIF_F_RXCSUM)) + features &= ~NETIF_F_LRO; + + return features; +} + static int myri10ge_change_mtu(struct net_device *dev, int new_mtu) { struct myri10ge_priv *mgp = netdev_priv(dev); @@ -3834,6 +3792,7 @@ static const struct net_device_ops myri10ge_netdev_ops = { .ndo_get_stats = myri10ge_get_stats, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = myri10ge_change_mtu, + .ndo_fix_features = myri10ge_fix_features, .ndo_set_multicast_list = myri10ge_set_multicast_list, .ndo_set_mac_address = myri10ge_set_mac_address, }; @@ -3860,7 +3819,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mgp = netdev_priv(netdev); mgp->dev = netdev; mgp->pdev = pdev; - mgp->csum_flag = MXGEFW_FLAGS_CKSUM; mgp->pause = myri10ge_flow_control; mgp->intr_coal_delay = myri10ge_intr_coal_delay; mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT); @@ -3976,11 +3934,11 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->netdev_ops = &myri10ge_netdev_ops; netdev->mtu = myri10ge_initial_mtu; netdev->base_addr = mgp->iomem_base; - netdev->features = mgp->features; + netdev->hw_features = mgp->features | NETIF_F_LRO | NETIF_F_RXCSUM; + netdev->features = netdev->hw_features; if (dac_enabled) netdev->features |= NETIF_F_HIGHDMA; - netdev->features |= NETIF_F_LRO; netdev->vlan_features |= mgp->features; if (mgp->fw_ver_tiny < 37) -- GitLab From 2b7b431858c284b62c18baaf2cea571be2797d5a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 18 Apr 2011 22:53:24 -0700 Subject: [PATCH 1160/5560] r8169: TSO fixes. - the MSS value is actually contained in a 11 bits wide (0x7ff) field. The extra bit in the former MSSMask did encompass the TSO command bit ("LargeSend") as well (0xfff). Oops. - the Tx descriptor layout is not the same through the whole chipset family. The 8169 documentation, the 8168c documentation and Realtek's drivers (8.020.00, 1.019.00, 6.014.00) highlight two layouts: 1. 8169, 8168 up to 8168b (included) and 8101 2. {8102e, 8168c} and beyond - notwithstanding the "first descriptor" and "last descriptor" bits, the same Tx descriptor content is enforced when a packet consists of several descriptors. The chipsets are documented to require it. Credits go to David Dillow for the original patch. Signed-off-by: Francois Romieu Cc: Realtek Signed-off-by: David S. Miller --- drivers/net/r8169.c | 209 +++++++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 72 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 058524f3eb49..fb03e6ff3716 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -134,47 +134,52 @@ enum mac_version { RTL_GIGA_MAC_VER_33 = 0x21, // 8168E }; -#define _R(NAME,MAC,MASK) \ - { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } +enum rtl_tx_desc_version { + RTL_TD_0 = 0, + RTL_TD_1 = 1, +}; + +#define _R(NAME,MAC,TD) \ + { .name = NAME, .mac_version = MAC, .txd_version = TD } static const struct { const char *name; u8 mac_version; - u32 RxConfigMask; /* Clears the bits supported by this chip */ + enum rtl_tx_desc_version txd_version; } rtl_chip_info[] = { - _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169 - _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S - _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S - _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB - _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd - _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe - _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E - _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E - _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E - _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E - _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E - _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E - _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 - _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 - _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139 - _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E - _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E - _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E - _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E - _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E - _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_28, 0xff7e1880), // PCI-E - _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E - _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880), // PCI-E - _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, 0xff7e1880), // PCI-E - _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_32, 0xff7e1880), // PCI-E - _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_33, 0xff7e1880) // PCI-E + _R("RTL8169", RTL_GIGA_MAC_VER_01, RTL_TD_0), // 8169 + _R("RTL8169s", RTL_GIGA_MAC_VER_02, RTL_TD_0), // 8169S + _R("RTL8110s", RTL_GIGA_MAC_VER_03, RTL_TD_0), // 8110S + _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, RTL_TD_0), // 8169SB + _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, RTL_TD_0), // 8110SCd + _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, RTL_TD_0), // 8110SCe + _R("RTL8102e", RTL_GIGA_MAC_VER_07, RTL_TD_1), // PCI-E + _R("RTL8102e", RTL_GIGA_MAC_VER_08, RTL_TD_1), // PCI-E + _R("RTL8102e", RTL_GIGA_MAC_VER_09, RTL_TD_1), // PCI-E + _R("RTL8101e", RTL_GIGA_MAC_VER_10, RTL_TD_0), // PCI-E + _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, RTL_TD_0), // PCI-E + _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, RTL_TD_0), // PCI-E + _R("RTL8101e", RTL_GIGA_MAC_VER_13, RTL_TD_0), // PCI-E 8139 + _R("RTL8100e", RTL_GIGA_MAC_VER_14, RTL_TD_0), // PCI-E 8139 + _R("RTL8100e", RTL_GIGA_MAC_VER_15, RTL_TD_0), // PCI-E 8139 + _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, RTL_TD_0), // PCI-E + _R("RTL8101e", RTL_GIGA_MAC_VER_16, RTL_TD_0), // PCI-E + _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, RTL_TD_1), // PCI-E + _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, RTL_TD_1), // PCI-E + _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, RTL_TD_1), // PCI-E + _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, RTL_TD_1), // PCI-E + _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, RTL_TD_1), // PCI-E + _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, RTL_TD_1), // PCI-E + _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, RTL_TD_1), // PCI-E + _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, RTL_TD_1), // PCI-E + _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, RTL_TD_1), // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, RTL_TD_1), // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, RTL_TD_1), // PCI-E + _R("RTL8105e", RTL_GIGA_MAC_VER_29, RTL_TD_1), // PCI-E + _R("RTL8105e", RTL_GIGA_MAC_VER_30, RTL_TD_1), // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_31, RTL_TD_1), // PCI-E + _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_32, RTL_TD_1), // PCI-E + _R("RTL8168e/8111e", RTL_GIGA_MAC_VER_33, RTL_TD_1) // PCI-E }; #undef _R @@ -230,6 +235,9 @@ enum rtl_registers { IntrStatus = 0x3e, TxConfig = 0x40, RxConfig = 0x44, + +#define RTL_RX_CONFIG_MASK 0xff7e1880u + RxMissed = 0x4c, Cfg9346 = 0x50, Config0 = 0x51, @@ -452,21 +460,69 @@ enum rtl_register_content { CounterDump = 0x8, }; -enum desc_status_bit { +enum rtl_desc_bit { + /* First doubleword. */ DescOwn = (1 << 31), /* Descriptor is owned by NIC */ RingEnd = (1 << 30), /* End of descriptor ring */ FirstFrag = (1 << 29), /* First segment of a packet */ LastFrag = (1 << 28), /* Final segment of a packet */ +}; + +/* Generic case. */ +enum rtl_tx_desc_bit { + /* First doubleword. */ + TD_LSO = (1 << 27), /* Large Send Offload */ +#define TD_MSS_MAX 0x07ffu /* MSS value */ - /* Tx private */ - LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ - MSSShift = 16, /* MSS value position */ - MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */ - IPCS = (1 << 18), /* Calculate IP checksum */ - UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ - TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ - TxVlanTag = (1 << 17), /* Add VLAN tag */ + /* Second doubleword. */ + TxVlanTag = (1 << 17), /* Add VLAN tag */ +}; + +/* 8169, 8168b and 810x except 8102e. */ +enum rtl_tx_desc_bit_0 { + /* First doubleword. */ +#define TD0_MSS_SHIFT 16 /* MSS position (11 bits) */ + TD0_TCP_CS = (1 << 16), /* Calculate TCP/IP checksum */ + TD0_UDP_CS = (1 << 17), /* Calculate UDP/IP checksum */ + TD0_IP_CS = (1 << 18), /* Calculate IP checksum */ +}; + +/* 8102e, 8168c and beyond. */ +enum rtl_tx_desc_bit_1 { + /* Second doubleword. */ +#define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */ + TD1_IP_CS = (1 << 29), /* Calculate IP checksum */ + TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */ + TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ +}; +static const struct rtl_tx_desc_info { + struct { + u32 udp; + u32 tcp; + } checksum; + u16 mss_shift; + u16 opts_offset; +} tx_desc_info [] = { + [RTL_TD_0] = { + .checksum = { + .udp = TD0_IP_CS | TD0_UDP_CS, + .tcp = TD0_IP_CS | TD0_TCP_CS + }, + .mss_shift = TD0_MSS_SHIFT, + .opts_offset = 0 + }, + [RTL_TD_1] = { + .checksum = { + .udp = TD1_IP_CS | TD1_UDP_CS, + .tcp = TD1_IP_CS | TD1_TCP_CS + }, + .mss_shift = TD1_MSS_SHIFT, + .opts_offset = 1 + } +}; + +enum rtl_rx_desc_bit { /* Rx private */ PID1 = (1 << 18), /* Protocol ID bit 1/2 */ PID0 = (1 << 17), /* Protocol ID bit 2/2 */ @@ -531,8 +587,8 @@ struct rtl8169_private { struct napi_struct napi; spinlock_t lock; /* spin lock flag */ u32 msg_enable; - int chipset; - int mac_version; + u16 txd_version; + u16 mac_version; u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ u32 dirty_rx; @@ -1288,7 +1344,7 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) static u32 rtl8169_fix_features(struct net_device *dev, u32 features) { - if (dev->mtu > MSSMask) + if (dev->mtu > TD_MSS_MAX) features &= ~NETIF_F_ALL_TSO; return features; @@ -3194,7 +3250,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct mii_if_info *mii; struct net_device *dev; void __iomem *ioaddr; - unsigned int i; + int chipset, i; int rc; if (netif_msg_drv(&debug)) { @@ -3336,7 +3392,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) "driver bug, MAC version not found in rtl_chip_info\n"); goto err_out_msi_4; } - tp->chipset = i; + chipset = i; + tp->txd_version = rtl_chip_info[chipset].txd_version; RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(Config1, RTL_R8(Config1) | PMEnable); @@ -3413,8 +3470,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); netif_info(tp, probe, dev, "%s at 0x%lx, %pM, XID %08x IRQ %d\n", - rtl_chip_info[tp->chipset].name, - dev->base_addr, dev->dev_addr, + rtl_chip_info[chipset].name, dev->base_addr, dev->dev_addr, (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || @@ -3572,7 +3628,7 @@ static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; u32 cfg = rtl8169_rx_config; - cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); + cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK); RTL_W32(RxConfig, cfg); /* Set DMA burst size and Interframe Gap Time */ @@ -4564,7 +4620,7 @@ static void rtl8169_tx_timeout(struct net_device *dev) } static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, - u32 opts1) + u32 *opts) { struct skb_shared_info *info = skb_shinfo(skb); unsigned int cur_frag, entry; @@ -4592,9 +4648,11 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, } /* anti gcc 2.95.3 bugware (sic) */ - status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); + status = opts[0] | len | + (RingEnd * !((entry + 1) % NUM_TX_DESC)); txd->opts1 = cpu_to_le32(status); + txd->opts2 = cpu_to_le32(opts[1]); txd->addr = cpu_to_le64(mapping); tp->tx_skb[entry].len = len; @@ -4612,23 +4670,26 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, return -EIO; } -static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) +static inline void rtl8169_tso_csum(struct rtl8169_private *tp, + struct sk_buff *skb, u32 *opts) { + const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; u32 mss = skb_shinfo(skb)->gso_size; + int offset = info->opts_offset; - if (mss) - return LargeSend | ((mss & MSSMask) << MSSShift); - - if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (mss) { + opts[0] |= TD_LSO; + opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift; + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = ip_hdr(skb); if (ip->protocol == IPPROTO_TCP) - return IPCS | TCPCS; + opts[offset] |= info->checksum.tcp; else if (ip->protocol == IPPROTO_UDP) - return IPCS | UDPCS; - WARN_ON(1); /* we need a WARN() */ + opts[offset] |= info->checksum.udp; + else + WARN_ON_ONCE(1); } - return 0; } static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, @@ -4641,7 +4702,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, struct device *d = &tp->pci_dev->dev; dma_addr_t mapping; u32 status, len; - u32 opts1; + u32 opts[2]; int frags; if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { @@ -4662,24 +4723,28 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); - txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); - opts1 = DescOwn | rtl8169_tso_csum(skb, dev); + opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); + opts[0] = DescOwn; - frags = rtl8169_xmit_frags(tp, skb, opts1); + rtl8169_tso_csum(tp, skb, opts); + + frags = rtl8169_xmit_frags(tp, skb, opts); if (frags < 0) goto err_dma_1; else if (frags) - opts1 |= FirstFrag; + opts[0] |= FirstFrag; else { - opts1 |= FirstFrag | LastFrag; + opts[0] |= FirstFrag | LastFrag; tp->tx_skb[entry].skb = skb; } + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); /* anti gcc 2.95.3 bugware (sic) */ - status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); + status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); txd->opts1 = cpu_to_le32(status); tp->cur_tx += frags + 1; @@ -5167,7 +5232,7 @@ static void rtl_set_rx_mode(struct net_device *dev) spin_lock_irqsave(&tp->lock, flags); tmp = rtl8169_rx_config | rx_mode | - (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); + (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK); if (tp->mac_version > RTL_GIGA_MAC_VER_06) { u32 data = mc_filter[0]; -- GitLab From e5cb966c0838e4da43a3b0751bdcac7fe719f7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 18 Apr 2011 13:31:20 +0000 Subject: [PATCH 1161/5560] net: fix section mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix build warnings like the following: WARNING: drivers/net/built-in.o(.data+0x12434): Section mismatch in reference from the variable madgemc_driver to the variable .init.data:madgemc_adapter_ids And add some consts to EISA device ID tables along the way. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/3c509.c | 14 +++++------ drivers/net/3c59x.c | 4 +-- drivers/net/depca.c | 35 +++++++++++++------------- drivers/net/hp100.c | 12 ++++----- drivers/net/ibmlana.c | 4 +-- drivers/net/irda/smsc-ircc2.c | 44 ++++++++++++++++----------------- drivers/net/ne3210.c | 15 ++++++----- drivers/net/smc-mca.c | 6 ++--- drivers/net/tokenring/madgemc.c | 2 +- drivers/net/tulip/de4x5.c | 4 +-- 10 files changed, 72 insertions(+), 68 deletions(-) diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 91abb965fb44..cb39dedf46bd 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -185,7 +185,7 @@ static int max_interrupt_work = 10; static int nopnp; #endif -static int __devinit el3_common_init(struct net_device *dev); +static int el3_common_init(struct net_device *dev); static void el3_common_remove(struct net_device *dev); static ushort id_read_eeprom(int index); static ushort read_eeprom(int ioaddr, int index); @@ -395,7 +395,7 @@ static struct isa_driver el3_isa_driver = { static int isa_registered; #ifdef CONFIG_PNP -static struct pnp_device_id el3_pnp_ids[] = { +static const struct pnp_device_id el3_pnp_ids[] __devinitconst = { { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */ { .id = "TCM5091" }, /* 3Com Etherlink III */ { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */ @@ -478,7 +478,7 @@ static int pnp_registered; #endif /* CONFIG_PNP */ #ifdef CONFIG_EISA -static struct eisa_device_id el3_eisa_ids[] = { +static const struct eisa_device_id el3_eisa_ids[] __devinitconst = { { "TCM5090" }, { "TCM5091" }, { "TCM5092" }, @@ -508,7 +508,7 @@ static int eisa_registered; #ifdef CONFIG_MCA static int el3_mca_probe(struct device *dev); -static short el3_mca_adapter_ids[] __initdata = { +static const short el3_mca_adapter_ids[] __devinitconst = { 0x627c, 0x627d, 0x62db, @@ -517,7 +517,7 @@ static short el3_mca_adapter_ids[] __initdata = { 0x0000 }; -static char *el3_mca_adapter_names[] __initdata = { +static const char *const el3_mca_adapter_names[] __devinitconst = { "3Com 3c529 EtherLink III (10base2)", "3Com 3c529 EtherLink III (10baseT)", "3Com 3c529 EtherLink III (test mode)", @@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev) } #ifdef CONFIG_MCA -static int __init el3_mca_probe(struct device *device) +static int __devinit el3_mca_probe(struct device *device) { /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, * heavily modified by Chris Beauregard @@ -671,7 +671,7 @@ static int __init el3_mca_probe(struct device *device) #endif /* CONFIG_MCA */ #ifdef CONFIG_EISA -static int __init el3_eisa_probe (struct device *device) +static int __devinit el3_eisa_probe (struct device *device) { short i; int ioaddr, irq, if_port; diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 8cc22568ebd3..99f43d275442 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = { #endif /* !CONFIG_PM */ #ifdef CONFIG_EISA -static struct eisa_device_id vortex_eisa_ids[] = { +static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = { { "TCM5920", CH_3C592 }, { "TCM5970", CH_3C597 }, { "" } }; MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids); -static int __init vortex_eisa_probe(struct device *device) +static int __devinit vortex_eisa_probe(struct device *device) { void __iomem *ioaddr; struct eisa_device *edev; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 8b0084d17c8c..17654059922d 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -331,18 +331,18 @@ static struct { "DE422",\ ""} -static char* __initdata depca_signature[] = DEPCA_SIGNATURE; +static const char* const depca_signature[] __devinitconst = DEPCA_SIGNATURE; enum depca_type { DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown }; -static char depca_string[] = "depca"; +static const char depca_string[] = "depca"; static int depca_device_remove (struct device *device); #ifdef CONFIG_EISA -static struct eisa_device_id depca_eisa_ids[] = { +static const struct eisa_device_id depca_eisa_ids[] __devinitconst = { { "DEC4220", de422 }, { "" } }; @@ -367,19 +367,19 @@ static struct eisa_driver depca_eisa_driver = { #define DE210_ID 0x628d #define DE212_ID 0x6def -static short depca_mca_adapter_ids[] = { +static const short depca_mca_adapter_ids[] __devinitconst = { DE210_ID, DE212_ID, 0x0000 }; -static char *depca_mca_adapter_name[] = { +static const char *depca_mca_adapter_name[] = { "DEC EtherWORKS MC Adapter (DE210)", "DEC EtherWORKS MC Adapter (DE212)", NULL }; -static enum depca_type depca_mca_adapter_type[] = { +static const enum depca_type depca_mca_adapter_type[] = { de210, de212, 0 @@ -541,10 +541,9 @@ static void SetMulticastFilter(struct net_device *dev); static int load_packet(struct net_device *dev, struct sk_buff *skb); static void depca_dbg_open(struct net_device *dev); -static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 }; -static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 }; -static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 }; -static u_char *depca_irq; +static const u_char de1xx_irq[] __devinitconst = { 2, 3, 4, 5, 7, 9, 0 }; +static const u_char de2xx_irq[] __devinitconst = { 5, 9, 10, 11, 15, 0 }; +static const u_char de422_irq[] __devinitconst = { 5, 9, 10, 11, 0 }; static int irq; static int io; @@ -580,7 +579,7 @@ static const struct net_device_ops depca_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; -static int __init depca_hw_init (struct net_device *dev, struct device *device) +static int __devinit depca_hw_init (struct net_device *dev, struct device *device) { struct depca_private *lp; int i, j, offset, netRAM, mem_len, status = 0; @@ -748,6 +747,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) if (dev->irq < 2) { unsigned char irqnum; unsigned long irq_mask, delay; + const u_char *depca_irq; irq_mask = probe_irq_on(); @@ -770,6 +770,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) break; default: + depca_irq = NULL; break; /* Not reached */ } @@ -1302,7 +1303,7 @@ static void SetMulticastFilter(struct net_device *dev) } } -static int __init depca_common_init (u_long ioaddr, struct net_device **devp) +static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp) { int status = 0; @@ -1333,7 +1334,7 @@ static int __init depca_common_init (u_long ioaddr, struct net_device **devp) /* ** Microchannel bus I/O device probe */ -static int __init depca_mca_probe(struct device *device) +static int __devinit depca_mca_probe(struct device *device) { unsigned char pos[2]; unsigned char where; @@ -1457,7 +1458,7 @@ static int __init depca_mca_probe(struct device *device) ** ISA bus I/O device probe */ -static void __init depca_platform_probe (void) +static void __devinit depca_platform_probe (void) { int i; struct platform_device *pldev; @@ -1497,7 +1498,7 @@ static void __init depca_platform_probe (void) } } -static enum depca_type __init depca_shmem_probe (ulong *mem_start) +static enum depca_type __devinit depca_shmem_probe (ulong *mem_start) { u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES; enum depca_type adapter = unknown; @@ -1558,7 +1559,7 @@ static int __devinit depca_isa_probe (struct platform_device *device) */ #ifdef CONFIG_EISA -static int __init depca_eisa_probe (struct device *device) +static int __devinit depca_eisa_probe (struct device *device) { enum depca_type adapter = unknown; struct eisa_device *edev; @@ -1629,7 +1630,7 @@ static int __devexit depca_device_remove (struct device *device) ** and Boot (readb) ROM. This will also give us a clue to the network RAM ** base address. */ -static int __init DepcaSignature(char *name, u_long base_addr) +static int __devinit DepcaSignature(char *name, u_long base_addr) { u_int i, j, k; void __iomem *ptr; diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 8e10d2f6a5ad..c52a1df5d922 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -188,14 +188,14 @@ struct hp100_private { * variables */ #ifdef CONFIG_ISA -static const char *hp100_isa_tbl[] = { +static const char *const hp100_isa_tbl[] __devinitconst = { "HWPF150", /* HP J2573 rev A */ "HWP1950", /* HP J2573 */ }; #endif #ifdef CONFIG_EISA -static struct eisa_device_id hp100_eisa_tbl[] = { +static const struct eisa_device_id hp100_eisa_tbl[] __devinitconst = { { "HWPF180" }, /* HP J2577 rev A */ { "HWP1920" }, /* HP 27248B */ { "HWP1940" }, /* HP J2577 */ @@ -336,7 +336,7 @@ static __devinit const char *hp100_read_id(int ioaddr) } #ifdef CONFIG_ISA -static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr) +static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr) { const char *sig; int i; @@ -372,7 +372,7 @@ static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr) * EISA and PCI are handled by device infrastructure. */ -static int __init hp100_isa_probe(struct net_device *dev, int addr) +static int __devinit hp100_isa_probe(struct net_device *dev, int addr) { int err = -ENODEV; @@ -396,7 +396,7 @@ static int __init hp100_isa_probe(struct net_device *dev, int addr) #endif /* CONFIG_ISA */ #if !defined(MODULE) && defined(CONFIG_ISA) -struct net_device * __init hp100_probe(int unit) +struct net_device * __devinit hp100_probe(int unit) { struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); int err; @@ -2843,7 +2843,7 @@ static void cleanup_dev(struct net_device *d) } #ifdef CONFIG_EISA -static int __init hp100_eisa_probe (struct device *gendev) +static int __devinit hp100_eisa_probe (struct device *gendev) { struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); struct eisa_device *edev = to_eisa_device(gendev); diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index a7d6cad32953..136d7544cc33 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -895,12 +895,12 @@ static int ibmlana_irq; static int ibmlana_io; static int startslot; /* counts through slots when probing multiple devices */ -static short ibmlana_adapter_ids[] __initdata = { +static const short ibmlana_adapter_ids[] __devinitconst = { IBM_LANA_ID, 0x0000 }; -static char *ibmlana_adapter_names[] __devinitdata = { +static const char *const ibmlana_adapter_names[] __devinitconst = { "IBM LAN Adapter/A", NULL }; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 8800e1fe4129..69b5707db369 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -222,19 +222,19 @@ static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 s static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self); /* Probing */ -static int __init smsc_ircc_look_for_chips(void); -static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type); -static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type); -static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); -static int __init smsc_superio_fdc(unsigned short cfg_base); -static int __init smsc_superio_lpc(unsigned short cfg_base); +static int smsc_ircc_look_for_chips(void); +static const struct smsc_chip * smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type); +static int smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type); +static int smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); +static int smsc_superio_fdc(unsigned short cfg_base); +static int smsc_superio_lpc(unsigned short cfg_base); #ifdef CONFIG_PCI -static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); -static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); -static void __init preconfigure_ali_port(struct pci_dev *dev, +static int preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); +static int preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); +static void preconfigure_ali_port(struct pci_dev *dev, unsigned short port); -static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); -static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, +static int preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); +static int smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, unsigned short ircc_fir, unsigned short ircc_sir, unsigned char ircc_dma, @@ -366,7 +366,7 @@ static inline void register_bank(int iobase, int bank) } /* PNP hotplug support */ -static const struct pnp_device_id smsc_ircc_pnp_table[] = { +static const struct pnp_device_id smsc_ircc_pnp_table[] __devinitconst = { { .id = "SMCf010", .driver_data = 0 }, /* and presumably others */ { } @@ -515,7 +515,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = { * Try to open driver instance * */ -static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) +static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) { struct smsc_ircc_cb *self; struct net_device *dev; @@ -2273,7 +2273,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho } -static int __init smsc_access(unsigned short cfg_base, unsigned char reg) +static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg) { IRDA_DEBUG(1, "%s\n", __func__); @@ -2281,7 +2281,7 @@ static int __init smsc_access(unsigned short cfg_base, unsigned char reg) return inb(cfg_base) != reg ? -1 : 0; } -static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type) +static const struct smsc_chip * __devinit smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type) { u8 devid, xdevid, rev; @@ -2406,7 +2406,7 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) #ifdef CONFIG_PCI #define PCIID_VENDOR_INTEL 0x8086 #define PCIID_VENDOR_ALI 0x10b9 -static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = { +static const struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitconst = { /* * Subsystems needing entries: * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family @@ -2532,7 +2532,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini * (FIR port, SIR port, FIR DMA, FIR IRQ) * through the chip configuration port. */ -static int __init preconfigure_smsc_chip(struct +static int __devinit preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf) { @@ -2633,7 +2633,7 @@ static int __init preconfigure_smsc_chip(struct * or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. * They all work the same way! */ -static int __init preconfigure_through_82801(struct pci_dev *dev, +static int __devinit preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf) @@ -2786,7 +2786,7 @@ static int __init preconfigure_through_82801(struct pci_dev *dev, * This is based on reverse-engineering since ALi does not * provide any data sheet for the 1533 chip. */ -static void __init preconfigure_ali_port(struct pci_dev *dev, +static void __devinit preconfigure_ali_port(struct pci_dev *dev, unsigned short port) { unsigned char reg; @@ -2824,7 +2824,7 @@ static void __init preconfigure_ali_port(struct pci_dev *dev, IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); } -static int __init preconfigure_through_ali(struct pci_dev *dev, +static int __devinit preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf) @@ -2837,7 +2837,7 @@ static int __init preconfigure_through_ali(struct pci_dev *dev, return preconfigure_smsc_chip(conf); } -static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, +static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, unsigned short ircc_fir, unsigned short ircc_sir, unsigned char ircc_dma, @@ -2849,7 +2849,7 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, int ret = 0; for_each_pci_dev(dev) { - struct smsc_ircc_subsystem_configuration *conf; + const struct smsc_ircc_subsystem_configuration *conf; /* * Cache the subsystem vendor/device: diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index 243ed2aee88e..e8984b0ca521 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c @@ -80,17 +80,20 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne #define NE3210_DEBUG 0x0 -static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; -static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0}; -static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"}; -static int ifmap_val[] __initdata = { +static const unsigned char irq_map[] __devinitconst = + { 15, 12, 11, 10, 9, 7, 5, 3 }; +static const unsigned int shmem_map[] __devinitconst = + { 0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0 }; +static const char *const ifmap[] __devinitconst = + { "UTP", "?", "BNC", "AUI" }; +static const int ifmap_val[] __devinitconst = { IF_PORT_10BASET, IF_PORT_UNKNOWN, IF_PORT_10BASE2, IF_PORT_AUI, }; -static int __init ne3210_eisa_probe (struct device *device) +static int __devinit ne3210_eisa_probe (struct device *device) { unsigned long ioaddr, phys_mem; int i, retval, port_index; @@ -313,7 +316,7 @@ static void ne3210_block_output(struct net_device *dev, int count, memcpy_toio(shmem, buf, count); } -static struct eisa_device_id ne3210_ids[] = { +static const struct eisa_device_id ne3210_ids[] __devinitconst = { { "EGL0101" }, { "NVL1801" }, { "" }, diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index d07c39cb4daf..0f29f261fcfe 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -156,7 +156,7 @@ static const struct { { 14, 15 } }; -static short smc_mca_adapter_ids[] __initdata = { +static const short smc_mca_adapter_ids[] __devinitconst = { 0x61c8, 0x61c9, 0x6fc0, @@ -168,7 +168,7 @@ static short smc_mca_adapter_ids[] __initdata = { 0x0000 }; -static char *smc_mca_adapter_names[] __initdata = { +static const char *const smc_mca_adapter_names[] __devinitconst = { "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)", "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)", "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)", @@ -199,7 +199,7 @@ static const struct net_device_ops ultramca_netdev_ops = { #endif }; -static int __init ultramca_probe(struct device *gen_dev) +static int __devinit ultramca_probe(struct device *gen_dev) { unsigned short ioaddr; struct net_device *dev; diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 2bedc0ace812..1313aa1315f0 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -727,7 +727,7 @@ static int __devexit madgemc_remove(struct device *device) return 0; } -static short madgemc_adapter_ids[] __initdata = { +static const short madgemc_adapter_ids[] __devinitconst = { 0x002d, 0x0000 }; diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index efaa1d69b720..45144d5bd11b 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1995,7 +1995,7 @@ SetMulticastFilter(struct net_device *dev) static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; -static int __init de4x5_eisa_probe (struct device *gendev) +static int __devinit de4x5_eisa_probe (struct device *gendev) { struct eisa_device *edev; u_long iobase; @@ -2097,7 +2097,7 @@ static int __devexit de4x5_eisa_remove (struct device *device) return 0; } -static struct eisa_device_id de4x5_eisa_ids[] = { +static const struct eisa_device_id de4x5_eisa_ids[] __devinitconst = { { "DEC4250", 0 }, /* 0 is the board name index... */ { "" } }; -- GitLab From b437a8cc7de4c9d8d0bdb37e7621c119f7640967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 18 Apr 2011 13:31:20 +0000 Subject: [PATCH 1162/5560] net: s2io: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes advertising HW_CSUM as driver does not support it. Note: driver advertises TSO6 but not IPV6_CSUM - bug maybe? Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/s2io.c | 100 +++++++++------------------------------------ 1 file changed, 20 insertions(+), 80 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2302d9743744..58b78f46e54f 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -6618,25 +6618,6 @@ static int s2io_ethtool_get_regs_len(struct net_device *dev) } -static u32 s2io_ethtool_get_rx_csum(struct net_device *dev) -{ - struct s2io_nic *sp = netdev_priv(dev); - - return sp->rx_csum; -} - -static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) -{ - struct s2io_nic *sp = netdev_priv(dev); - - if (data) - sp->rx_csum = 1; - else - sp->rx_csum = 0; - - return 0; -} - static int s2io_get_eeprom_len(struct net_device *dev) { return XENA_EEPROM_SPACE; @@ -6688,61 +6669,27 @@ static void s2io_ethtool_get_strings(struct net_device *dev, } } -static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) -{ - if (data) - dev->features |= NETIF_F_IP_CSUM; - else - dev->features &= ~NETIF_F_IP_CSUM; - - return 0; -} - -static u32 s2io_ethtool_op_get_tso(struct net_device *dev) -{ - return (dev->features & NETIF_F_TSO) != 0; -} - -static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) -{ - if (data) - dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); - else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} - -static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) +static int s2io_set_features(struct net_device *dev, u32 features) { struct s2io_nic *sp = netdev_priv(dev); - int rc = 0; - int changed = 0; - - if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO)) - return -EINVAL; - - if (data & ETH_FLAG_LRO) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - changed = 1; - } - } else if (dev->features & NETIF_F_LRO) { - dev->features &= ~NETIF_F_LRO; - changed = 1; - } + u32 changed = (features ^ dev->features) & NETIF_F_LRO; if (changed && netif_running(dev)) { + int rc; + s2io_stop_all_tx_queue(sp); s2io_card_down(sp); + dev->features = features; rc = s2io_card_up(sp); if (rc) s2io_reset(sp); else s2io_start_all_tx_queue(sp); + + return rc ? rc : 1; } - return rc; + return 0; } static const struct ethtool_ops netdev_ethtool_ops = { @@ -6758,15 +6705,6 @@ static const struct ethtool_ops netdev_ethtool_ops = { .get_ringparam = s2io_ethtool_gringparam, .get_pauseparam = s2io_ethtool_getpause_data, .set_pauseparam = s2io_ethtool_setpause_data, - .get_rx_csum = s2io_ethtool_get_rx_csum, - .set_rx_csum = s2io_ethtool_set_rx_csum, - .set_tx_csum = s2io_ethtool_op_set_tx_csum, - .set_flags = s2io_ethtool_set_flags, - .get_flags = ethtool_op_get_flags, - .set_sg = ethtool_op_set_sg, - .get_tso = s2io_ethtool_op_get_tso, - .set_tso = s2io_ethtool_op_set_tso, - .set_ufo = ethtool_op_set_ufo, .self_test = s2io_ethtool_test, .get_strings = s2io_ethtool_get_strings, .set_phys_id = s2io_ethtool_set_led, @@ -7538,7 +7476,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!ring_data->lro) || (ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) && - (sp->rx_csum)) { + (dev->features & NETIF_F_RXCSUM)) { l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1); if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) { @@ -7799,6 +7737,7 @@ static const struct net_device_ops s2io_netdev_ops = { .ndo_do_ioctl = s2io_ioctl, .ndo_set_mac_address = s2io_set_mac_addr, .ndo_change_mtu = s2io_change_mtu, + .ndo_set_features = s2io_set_features, .ndo_vlan_rx_register = s2io_vlan_rx_register, .ndo_vlan_rx_kill_vid = s2io_vlan_rx_kill_vid, .ndo_tx_timeout = s2io_tx_watchdog, @@ -8040,17 +7979,18 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Driver entry points */ dev->netdev_ops = &s2io_netdev_ops; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->features |= NETIF_F_LRO; - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_RXCSUM | NETIF_F_LRO; + dev->features |= dev->hw_features | + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + if (sp->device_type & XFRAME_II_DEVICE) { + dev->hw_features |= NETIF_F_UFO; + if (ufo) + dev->features |= NETIF_F_UFO; + } if (sp->high_dma_flag == true) dev->features |= NETIF_F_HIGHDMA; - dev->features |= NETIF_F_TSO; - dev->features |= NETIF_F_TSO6; - if ((sp->device_type & XFRAME_II_DEVICE) && (ufo)) { - dev->features |= NETIF_F_UFO; - dev->features |= NETIF_F_HW_CSUM; - } dev->watchdog_timeo = WATCH_DOG_TIMEOUT; INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); INIT_WORK(&sp->set_link_task, s2io_set_link); -- GitLab From 30f554f925335abad89aaa38eec6828242b27527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 18 Apr 2011 13:31:20 +0000 Subject: [PATCH 1163/5560] net: chelsio: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also remove flags that were not used or are now redundant to hw_features bits. No device had UDP_CSUM_CAPABLE set. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/chelsio/common.h | 5 ---- drivers/net/chelsio/cxgb2.c | 48 ++++++------------------------------ drivers/net/chelsio/sge.c | 13 +++++----- drivers/net/chelsio/tp.c | 5 ---- drivers/net/chelsio/tp.h | 1 - 5 files changed, 14 insertions(+), 58 deletions(-) diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index 092f31a126e6..c26d863e1697 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -264,11 +264,6 @@ struct adapter { enum { /* adapter flags */ FULL_INIT_DONE = 1 << 0, - TSO_CAPABLE = 1 << 2, - TCP_CSUM_CAPABLE = 1 << 3, - UDP_CSUM_CAPABLE = 1 << 4, - VLAN_ACCEL_CAPABLE = 1 << 5, - RX_CSUM_ENABLED = 1 << 6, }; struct mdio_ops; diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 0f71304e0542..5f82c9c34978 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -192,10 +192,8 @@ static void link_start(struct port_info *p) static void enable_hw_csum(struct adapter *adapter) { - if (adapter->flags & TSO_CAPABLE) + if (adapter->port[0].dev->hw_features & NETIF_F_TSO) t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */ - if (adapter->flags & UDP_CSUM_CAPABLE) - t1_tp_set_udp_checksum_offload(adapter->tp, 1); t1_tp_set_tcp_checksum_offload(adapter->tp, 1); } @@ -705,33 +703,6 @@ static int set_pauseparam(struct net_device *dev, return 0; } -static u32 get_rx_csum(struct net_device *dev) -{ - struct adapter *adapter = dev->ml_priv; - - return (adapter->flags & RX_CSUM_ENABLED) != 0; -} - -static int set_rx_csum(struct net_device *dev, u32 data) -{ - struct adapter *adapter = dev->ml_priv; - - if (data) - adapter->flags |= RX_CSUM_ENABLED; - else - adapter->flags &= ~RX_CSUM_ENABLED; - return 0; -} - -static int set_tso(struct net_device *dev, u32 value) -{ - struct adapter *adapter = dev->ml_priv; - - if (!(adapter->flags & TSO_CAPABLE)) - return value ? -EOPNOTSUPP : 0; - return ethtool_op_set_tso(dev, value); -} - static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) { struct adapter *adapter = dev->ml_priv; @@ -831,17 +802,12 @@ static const struct ethtool_ops t1_ethtool_ops = { .get_eeprom = get_eeprom, .get_pauseparam = get_pauseparam, .set_pauseparam = set_pauseparam, - .get_rx_csum = get_rx_csum, - .set_rx_csum = set_rx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .set_sg = ethtool_op_set_sg, .get_link = ethtool_op_get_link, .get_strings = get_strings, .get_sset_count = get_sset_count, .get_ethtool_stats = get_stats, .get_regs_len = get_regs_len, .get_regs = get_regs, - .set_tso = set_tso, }; static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) @@ -1105,28 +1071,28 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->ml_priv = adapter; - netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - netdev->features |= NETIF_F_LLTX; + netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_RXCSUM; + netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_RXCSUM | NETIF_F_LLTX; - adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; if (vlan_tso_capable(adapter)) { #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - adapter->flags |= VLAN_ACCEL_CAPABLE; netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; #endif /* T204: disable TSO */ if (!(is_T2(adapter)) || bi->port_number != 4) { - adapter->flags |= TSO_CAPABLE; + netdev->hw_features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO; } } netdev->netdev_ops = &cxgb_netdev_ops; - netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? + netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ? sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt); netif_napi_add(netdev, &adapter->napi, t1_poll, 64); diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 8754d4473042..b948ea737550 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -929,7 +929,7 @@ void t1_sge_intr_enable(struct sge *sge) u32 en = SGE_INT_ENABLE; u32 val = readl(sge->adapter->regs + A_PL_ENABLE); - if (sge->adapter->flags & TSO_CAPABLE) + if (sge->adapter->port[0].dev->hw_features & NETIF_F_TSO) en &= ~F_PACKET_TOO_BIG; writel(en, sge->adapter->regs + A_SG_INT_ENABLE); writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE); @@ -952,7 +952,7 @@ int t1_sge_intr_error_handler(struct sge *sge) struct adapter *adapter = sge->adapter; u32 cause = readl(adapter->regs + A_SG_INT_CAUSE); - if (adapter->flags & TSO_CAPABLE) + if (adapter->port[0].dev->hw_features & NETIF_F_TSO) cause &= ~F_PACKET_TOO_BIG; if (cause & F_RESPQ_EXHAUSTED) sge->stats.respQ_empty++; @@ -1369,6 +1369,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) const struct cpl_rx_pkt *p; struct adapter *adapter = sge->adapter; struct sge_port_stats *st; + struct net_device *dev; skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad); if (unlikely(!skb)) { @@ -1384,9 +1385,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) __skb_pull(skb, sizeof(*p)); st = this_cpu_ptr(sge->port_stats[p->iff]); + dev = adapter->port[p->iff].dev; - skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev); - if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff && + skb->protocol = eth_type_trans(skb, dev); + if ((dev->features & NETIF_F_RXCSUM) && p->csum == 0xffff && skb->protocol == htons(ETH_P_IP) && (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) { ++st->rx_cso_good; @@ -1838,8 +1840,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - if (!(adapter->flags & UDP_CSUM_CAPABLE) && - skb->ip_summed == CHECKSUM_PARTIAL && + if (skb->ip_summed == CHECKSUM_PARTIAL && ip_hdr(skb)->protocol == IPPROTO_UDP) { if (unlikely(skb_checksum_help(skb))) { pr_debug("%s: unable to do udp checksum\n", dev->name); diff --git a/drivers/net/chelsio/tp.c b/drivers/net/chelsio/tp.c index 6222d585e447..8bed4a59e65f 100644 --- a/drivers/net/chelsio/tp.c +++ b/drivers/net/chelsio/tp.c @@ -152,11 +152,6 @@ void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable) set_csum_offload(tp, F_IP_CSUM, enable); } -void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable) -{ - set_csum_offload(tp, F_UDP_CSUM, enable); -} - void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable) { set_csum_offload(tp, F_TCP_CSUM, enable); diff --git a/drivers/net/chelsio/tp.h b/drivers/net/chelsio/tp.h index 32fc71e58913..dfd8ce25106a 100644 --- a/drivers/net/chelsio/tp.h +++ b/drivers/net/chelsio/tp.h @@ -65,7 +65,6 @@ void t1_tp_intr_clear(struct petp *tp); int t1_tp_intr_handler(struct petp *tp); void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps); -void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable); void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable); void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable); int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size); -- GitLab From feb990d467f76abe90ae68437eb1db351e67c674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 18 Apr 2011 13:31:21 +0000 Subject: [PATCH 1164/5560] net: vxge: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Side effect: ->gro_enable is removed as napi_gro_receive() does the fallback itself. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-ethtool.c | 72 ----------------------- drivers/net/vxge/vxge-main.c | 100 ++++++++++++++++++-------------- drivers/net/vxge/vxge-main.h | 14 ++--- 3 files changed, 59 insertions(+), 127 deletions(-) diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index 43c458323f83..5aef6c893aee 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -1071,35 +1071,6 @@ static int vxge_ethtool_get_regs_len(struct net_device *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 = netdev_priv(dev); - - return vdev->rx_csum; -} - -static int vxge_set_rx_csum(struct net_device *dev, u32 data) -{ - struct vxgedev *vdev = netdev_priv(dev); - - if (data) - vdev->rx_csum = 1; - else - vdev->rx_csum = 0; - - return 0; -} - -static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data) -{ - if (data) - dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); - else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} - static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset) { struct vxgedev *vdev = netdev_priv(dev); @@ -1119,40 +1090,6 @@ 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 = netdev_priv(dev); - enum vxge_hw_status status; - - if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH)) - return -EINVAL; - - 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 int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms) { struct vxgedev *vdev = netdev_priv(dev); @@ -1181,19 +1118,10 @@ static const struct ethtool_ops vxge_ethtool_ops = { .get_link = ethtool_op_get_link, .get_pauseparam = vxge_ethtool_getpause_data, .set_pauseparam = vxge_ethtool_setpause_data, - .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_ipv6_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = vxge_ethtool_op_set_tso, .get_strings = vxge_ethtool_get_strings, .set_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, .flash_device = vxge_fw_flash, }; diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index d192dad8ff21..fc837cf6bd4d 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -304,22 +304,14 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan, "%s: %s:%d skb protocol = %d", ring->ndev->name, __func__, __LINE__, skb->protocol); - if (ring->gro_enable) { - if (ring->vlgrp && ext_info->vlan && - (ring->vlan_tag_strip == - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE)) - vlan_gro_receive(ring->napi_p, ring->vlgrp, - ext_info->vlan, skb); - else - napi_gro_receive(ring->napi_p, skb); - } else { - if (ring->vlgrp && vlan && - (ring->vlan_tag_strip == - VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE)) - vlan_hwaccel_receive_skb(skb, ring->vlgrp, vlan); - else - netif_receive_skb(skb); - } + if (ring->vlgrp && ext_info->vlan && + (ring->vlan_tag_strip == + VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE)) + vlan_gro_receive(ring->napi_p, ring->vlgrp, + ext_info->vlan, skb); + else + napi_gro_receive(ring->napi_p, skb); + vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__); } @@ -490,7 +482,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, if ((ext_info.proto & VXGE_HW_FRAME_PROTO_TCP_OR_UDP) && !(ext_info.proto & VXGE_HW_FRAME_PROTO_IP_FRAG) && - ring->rx_csum && /* Offload Rx side CSUM */ + (dev->features & NETIF_F_RXCSUM) && /* Offload Rx side CSUM */ ext_info.l3_cksum == VXGE_HW_L3_CKSUM_OK && ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2094,11 +2086,9 @@ static int vxge_open_vpaths(struct vxgedev *vdev) vdev->config.fifo_indicate_max_pkts; vpath->fifo.tx_vector_no = 0; 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; vpath->ring.vlan_tag_strip = vdev->vlan_tag_strip; vdev->stats.vpaths_open++; } else { @@ -2670,6 +2660,40 @@ static void vxge_poll_vp_lockup(unsigned long data) mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000); } +static u32 vxge_fix_features(struct net_device *dev, u32 features) +{ + u32 changed = dev->features ^ features; + + /* 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. + */ + if ((changed & NETIF_F_RXHASH) && netif_running(dev)) + features ^= NETIF_F_RXHASH; + + return features; +} + +static int vxge_set_features(struct net_device *dev, u32 features) +{ + struct vxgedev *vdev = netdev_priv(dev); + u32 changed = dev->features ^ features; + + if (!(changed & NETIF_F_RXHASH)) + return 0; + + /* !netif_running() ensured by vxge_fix_features() */ + + vdev->devh->config.rth_en = !!(features & NETIF_F_RXHASH); + if (vxge_reset_all_vpaths(vdev) != VXGE_HW_OK) { + dev->features = features ^ NETIF_F_RXHASH; + vdev->devh->config.rth_en = !!(dev->features & NETIF_F_RXHASH); + return -EIO; + } + + return 0; +} + /** * vxge_open * @dev: pointer to the device structure. @@ -3369,6 +3393,8 @@ static const struct net_device_ops vxge_netdev_ops = { .ndo_do_ioctl = vxge_ioctl, .ndo_set_mac_address = vxge_set_mac_addr, .ndo_change_mtu = vxge_change_mtu, + .ndo_fix_features = vxge_fix_features, + .ndo_set_features = vxge_set_features, .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, @@ -3415,14 +3441,21 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vdev->devh = 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; vdev->titan1 = (vdev->pdev->revision == VXGE_HW_TITAN1_PCI_REVISION); SET_NETDEV_DEV(ndev, &vdev->pdev->dev); - ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; + ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_HW_VLAN_TX; + if (vdev->config.rth_steering != NO_STEERING) + ndev->hw_features |= NETIF_F_RXHASH; + + ndev->features |= ndev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; + /* Driver entry points */ ndev->irq = vdev->pdev->irq; ndev->base_addr = (unsigned long) hldev->bar0; @@ -3434,11 +3467,6 @@ 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); @@ -3450,9 +3478,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, goto _out1; } - ndev->features |= NETIF_F_SG; - - ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; vxge_debug_init(vxge_hw_device_trace_level_get(hldev), "%s : checksuming enabled", __func__); @@ -3462,11 +3487,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, "%s : using High DMA", __func__); } - ndev->features |= NETIF_F_TSO | NETIF_F_TSO6; - - if (vdev->config.gro_enable) - ndev->features |= NETIF_F_GRO; - ret = register_netdev(ndev); if (ret) { vxge_debug_init(vxge_hw_device_trace_level_get(hldev), @@ -3996,15 +4016,6 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask) vdev->config.tx_steering_type = 0; } - if (vdev->config.gro_enable) { - vxge_debug_init(VXGE_ERR, - "%s: Generic receive offload enabled", - vdev->ndev->name); - } else - vxge_debug_init(VXGE_TRACE, - "%s: Generic receive offload disabled", - vdev->ndev->name); - if (vdev->config.addr_learn_en) vxge_debug_init(VXGE_TRACE, "%s: MAC Address learning enabled", vdev->ndev->name); @@ -4589,7 +4600,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) /* set private device info */ pci_set_drvdata(pdev, hldev); - ll_config->gro_enable = VXGE_GRO_ALWAYS_AGGREGATE; 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; diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 40474f0da576..ed120aba443d 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -168,9 +168,6 @@ struct vxge_config { #define NEW_NAPI_WEIGHT 64 int napi_weight; -#define VXGE_GRO_DONOT_AGGREGATE 0 -#define VXGE_GRO_ALWAYS_AGGREGATE 1 - int gro_enable; int intr_type; #define INTA 0 #define MSI 1 @@ -290,13 +287,11 @@ struct vxge_ring { unsigned long interrupt_count; unsigned long jiffies; - /* copy of the flag indicating whether rx_csum is to be used */ - u32 rx_csum:1, - rx_hwts:1; + /* copy of the flag indicating whether rx_hwts is to be used */ + u32 rx_hwts:1; int pkts_processed; int budget; - int gro_enable; struct napi_struct napi; struct napi_struct *napi_p; @@ -369,9 +364,8 @@ struct vxgedev { */ u16 all_multi_flg; - /* A flag indicating whether rx_csum is to be used or not. */ - u32 rx_csum:1, - rx_hwts:1, + /* A flag indicating whether rx_hwts is to be used or not. */ + u32 rx_hwts:1, titan1:1; struct vxge_msix_entry *vxge_entries; -- GitLab From a0d2730c9571aeba793cb5d3009094ee1d8fda35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 18 Apr 2011 13:31:21 +0000 Subject: [PATCH 1165/5560] net: vmxnet3: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also removes private feature flags that were always set to true. You may want to move vmxnet3_set_features() to vmxnet3_drv.c as a following cleanup. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 40 ++++++---------- drivers/net/vmxnet3/vmxnet3_ethtool.c | 67 +++++---------------------- drivers/net/vmxnet3/vmxnet3_int.h | 7 ++- 3 files changed, 28 insertions(+), 86 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 0d47c3a05307..7a494f79c88f 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1082,7 +1082,7 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter, struct sk_buff *skb, union Vmxnet3_GenericDesc *gdesc) { - if (!gdesc->rcd.cnc && adapter->rxcsum) { + if (!gdesc->rcd.cnc && adapter->netdev->features & NETIF_F_RXCSUM) { /* typical case: TCP/UDP over IP and both csums are correct */ if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) { @@ -2081,10 +2081,10 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) devRead->misc.ddLen = cpu_to_le32(sizeof(struct vmxnet3_adapter)); /* set up feature flags */ - if (adapter->rxcsum) + if (adapter->netdev->features & NETIF_F_RXCSUM) devRead->misc.uptFeatures |= UPT1_F_RXCSUM; - if (adapter->lro) { + if (adapter->netdev->features & NETIF_F_LRO) { devRead->misc.uptFeatures |= UPT1_F_LRO; devRead->misc.maxNumRxSG = cpu_to_le16(1 + MAX_SKB_FRAGS); } @@ -2593,9 +2593,6 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu) if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU) return -EINVAL; - if (new_mtu > 1500 && !adapter->jumbo_frame) - return -EINVAL; - netdev->mtu = new_mtu; /* @@ -2641,28 +2638,18 @@ vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64) { struct net_device *netdev = adapter->netdev; - netdev->features = NETIF_F_SG | - NETIF_F_HW_CSUM | - NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER | - NETIF_F_TSO | - NETIF_F_TSO6 | - NETIF_F_LRO; - - printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro"); - - adapter->rxcsum = true; - adapter->jumbo_frame = true; - adapter->lro = true; - - if (dma64) { + netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | + NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX | + NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO; + if (dma64) netdev->features |= NETIF_F_HIGHDMA; - printk(" highDMA"); - } + netdev->vlan_features = netdev->hw_features & ~NETIF_F_HW_VLAN_TX; + netdev->features = netdev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - netdev->vlan_features = netdev->features; - printk("\n"); + netdev_info(adapter->netdev, + "features: sg csum vlan jf tso tsoIPv6 lro%s\n", + dma64 ? " highDMA" : ""); } @@ -2874,6 +2861,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, .ndo_start_xmit = vmxnet3_xmit_frame, .ndo_set_mac_address = vmxnet3_set_mac_addr, .ndo_change_mtu = vmxnet3_change_mtu, + .ndo_set_features = vmxnet3_set_features, .ndo_get_stats = vmxnet3_get_stats, .ndo_tx_timeout = vmxnet3_tx_timeout, .ndo_set_multicast_list = vmxnet3_set_mc, diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 51f2ef142a5b..70c1ab96ed27 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -33,40 +33,6 @@ struct vmxnet3_stat_desc { }; -static u32 -vmxnet3_get_rx_csum(struct net_device *netdev) -{ - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - return adapter->rxcsum; -} - - -static int -vmxnet3_set_rx_csum(struct net_device *netdev, u32 val) -{ - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - - if (adapter->rxcsum != val) { - adapter->rxcsum = val; - if (netif_running(netdev)) { - if (val) - adapter->shared->devRead.misc.uptFeatures |= - UPT1_F_RXCSUM; - else - adapter->shared->devRead.misc.uptFeatures &= - ~UPT1_F_RXCSUM; - - spin_lock_irqsave(&adapter->cmd_lock, flags); - VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, - VMXNET3_CMD_UPDATE_FEATURE); - spin_unlock_irqrestore(&adapter->cmd_lock, flags); - } - } - return 0; -} - - /* per tq stats maintained by the device */ static const struct vmxnet3_stat_desc vmxnet3_tq_dev_stats[] = { @@ -296,28 +262,27 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf) } } -static int -vmxnet3_set_flags(struct net_device *netdev, u32 data) +int vmxnet3_set_features(struct net_device *netdev, u32 features) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); - u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1; - u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1; unsigned long flags; + u32 changed = features ^ netdev->features; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) - return -EINVAL; - - if (lro_requested ^ lro_present) { - /* toggle the LRO feature*/ - netdev->features ^= NETIF_F_LRO; + if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) { + if (features & NETIF_F_RXCSUM) + adapter->shared->devRead.misc.uptFeatures |= + UPT1_F_RXCSUM; + else + adapter->shared->devRead.misc.uptFeatures &= + ~UPT1_F_RXCSUM; - /* update harware LRO capability accordingly */ - if (lro_requested) + if (features & NETIF_F_LRO) adapter->shared->devRead.misc.uptFeatures |= UPT1_F_LRO; else adapter->shared->devRead.misc.uptFeatures &= ~UPT1_F_LRO; + spin_lock_irqsave(&adapter->cmd_lock, flags); VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_UPDATE_FEATURE); @@ -654,17 +619,7 @@ static struct ethtool_ops vmxnet3_ethtool_ops = { .get_wol = vmxnet3_get_wol, .set_wol = vmxnet3_set_wol, .get_link = ethtool_op_get_link, - .get_rx_csum = vmxnet3_get_rx_csum, - .set_rx_csum = vmxnet3_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, .get_strings = vmxnet3_get_strings, - .get_flags = ethtool_op_get_flags, - .set_flags = vmxnet3_set_flags, .get_sset_count = vmxnet3_get_sset_count, .get_ethtool_stats = vmxnet3_get_ethtool_stats, .get_ringparam = vmxnet3_get_ringparam, diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index fb5d245ac878..8ba7b5f67de2 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -329,10 +329,6 @@ struct vmxnet3_adapter { u8 __iomem *hw_addr0; /* for BAR 0 */ u8 __iomem *hw_addr1; /* for BAR 1 */ - /* feature control */ - bool rxcsum; - bool lro; - bool jumbo_frame; #ifdef VMXNET3_RSS struct UPT1_RSSConf *rss_conf; bool rss; @@ -403,6 +399,9 @@ vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter); void vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter); +int +vmxnet3_set_features(struct net_device *netdev, u32 features); + int vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size); -- GitLab From 88230fd586b4ccc5ffe6d6c2df8cdc495e89ad83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 18 Apr 2011 13:31:21 +0000 Subject: [PATCH 1166/5560] net: qlge: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another simple conversion. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_ethtool.c | 34 --------------------------------- drivers/net/qlge/qlge_main.c | 21 ++++++++------------ 2 files changed, 8 insertions(+), 47 deletions(-) diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 687754da2a9f..78dc40c18c60 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -655,32 +655,6 @@ static int ql_set_pauseparam(struct net_device *netdev, return status; } -static u32 ql_get_rx_csum(struct net_device *netdev) -{ - struct ql_adapter *qdev = netdev_priv(netdev); - return qdev->rx_csum; -} - -static int ql_set_rx_csum(struct net_device *netdev, uint32_t data) -{ - struct ql_adapter *qdev = netdev_priv(netdev); - qdev->rx_csum = data; - return 0; -} - -static int ql_set_tso(struct net_device *ndev, uint32_t data) -{ - - if (data) { - ndev->features |= NETIF_F_TSO; - ndev->features |= NETIF_F_TSO6; - } else { - ndev->features &= ~NETIF_F_TSO; - ndev->features &= ~NETIF_F_TSO6; - } - return 0; -} - static u32 ql_get_msglevel(struct net_device *ndev) { struct ql_adapter *qdev = netdev_priv(ndev); @@ -707,14 +681,6 @@ const struct ethtool_ops qlge_ethtool_ops = { .self_test = ql_self_test, .get_pauseparam = ql_get_pauseparam, .set_pauseparam = ql_set_pauseparam, - .get_rx_csum = ql_get_rx_csum, - .set_rx_csum = ql_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = ql_set_tso, .get_coalesce = ql_get_coalesce, .set_coalesce = ql_set_coalesce, .get_sset_count = ql_get_sset_count, diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index f61e717adac4..6c9d124cfc76 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1571,7 +1571,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, skb->protocol = eth_type_trans(skb, ndev); skb_checksum_none_assert(skb); - if (qdev->rx_csum && + if ((ndev->features & NETIF_F_RXCSUM) && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { /* TCP frame. */ if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { @@ -1684,7 +1684,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, /* If rx checksum is on, and there are no * csum or frame errors. */ - if (qdev->rx_csum && + if ((ndev->features & NETIF_F_RXCSUM) && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { /* TCP frame. */ if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { @@ -2004,7 +2004,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, /* If rx checksum is on, and there are no * csum or frame errors. */ - if (qdev->rx_csum && + if ((ndev->features & NETIF_F_RXCSUM) && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { /* TCP frame. */ if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { @@ -4621,7 +4621,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev, /* * Set up the operating parameters. */ - qdev->rx_csum = 1; qdev->workqueue = create_singlethread_workqueue(ndev->name); INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work); INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work); @@ -4695,15 +4694,11 @@ static int __devinit qlge_probe(struct pci_dev *pdev, qdev = netdev_priv(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); - ndev->features = (0 - | NETIF_F_IP_CSUM - | NETIF_F_SG - | NETIF_F_TSO - | NETIF_F_TSO6 - | NETIF_F_TSO_ECN - | NETIF_F_HW_VLAN_TX - | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER); - ndev->features |= NETIF_F_GRO; + ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | + NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM; + ndev->features = ndev->hw_features | + NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; if (test_bit(QL_DMA64, &qdev->flags)) ndev->features |= NETIF_F_HIGHDMA; -- GitLab From 86c0f043a737dadf034a4e6f29aefb074f4a1146 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 18 Apr 2011 10:14:57 +0000 Subject: [PATCH 1167/5560] s3fb: add DDC support Add I2C support for the DDC bus and also default mode initialization by reading monitor EDID to the s3fb driver. Tested on Trio64V+ (2 cards), Trio64V2/DX, Virge (3 cards), Virge/DX (3 cards), Virge/GX2, Trio3D/2X (4 cards), Trio3D. Will probably not work on Trio32 - my 2 cards have DDC support in BIOS that looks different from the other cards but the DDC pins on the VGA connector are not connected. Signed-off-by: Ondrej Zary Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 8 ++ drivers/video/s3fb.c | 206 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 209 insertions(+), 5 deletions(-) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e6a8d8c0101d..e2126b5af1de 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1463,6 +1463,14 @@ config FB_S3 ---help--- Driver for graphics boards with S3 Trio / S3 Virge chip. +config FB_S3_DDC + bool "DDC for S3 support" + depends on FB_S3 + select FB_DDC + default y + help + Say Y here if you want DDC support for your S3 graphics card. + config FB_SAVAGE tristate "S3 Savage support" depends on FB && PCI && EXPERIMENTAL diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index c4482f2e5799..9a345209535b 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c @@ -25,6 +25,9 @@ #include /* Why should fb driver call console functions? because console_lock() */ #include